a5ec8db5f7
build / build (push) Failing after 5s
dependency (SDL2, SDL2_mixer, fluidsynth-lite, a MIDI soundfont) prebuilt, so compiling the engine needs no network access - just the image and the engine source. Add res/assets/extract_assets.sh to pull the game's data files out of a purchased GOG installer, and a Makefile that assembles a runnable dist/ from the two. Also add `make package`, which builds a redistributable tarball that omits the proprietary game assets (shipping res/GET_ASSETS.txt instead) plus license information for both the MIT tooling and the GPLv3 engine, and a Gitea Actions workflow that builds and publishes it to dl.ladkau.de on every push.
249 lines
6.6 KiB
C
249 lines
6.6 KiB
C
/*
|
|
|
|
Copyright (C) 2015-2018 Night Dive Studios, LLC.
|
|
|
|
This program is free software: you can redistribute it and/or modify
|
|
it under the terms of the GNU General Public License as published by
|
|
the Free Software Foundation, either version 3 of the License, or
|
|
(at your option) any later version.
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
*/
|
|
/*
|
|
* FrOslew.c
|
|
*
|
|
* $Source: n:/project/cit/src/RCS/froslew.c $
|
|
* $Revision: 1.8 $
|
|
* $Author: dc $
|
|
* $Date: 1994/04/10 05:34:29 $
|
|
*
|
|
* Citadel Renderer
|
|
* object slew system controllers/prototypes/vars
|
|
*
|
|
* $Log: froslew.c $
|
|
* Revision 1.8 1994/04/10 05:34:29 dc
|
|
* hack return codes to avoid move_to teleport and physics vector reset...
|
|
*
|
|
* Revision 1.7 1994/04/10 05:15:41 dc
|
|
* support for cyberman, vfx1, other 6d control structure, inc. HEAD_H
|
|
*
|
|
* Revision 1.6 1994/01/02 17:12:02 dc
|
|
* Initial revision
|
|
*
|
|
* Revision 1.5 1993/12/05 05:43:57 mahk
|
|
* Fixed player height thing for slew mode.
|
|
*
|
|
* Revision 1.4 1993/11/04 16:09:50 dc
|
|
* fix flat floor slewing
|
|
*
|
|
* Revision 1.3 1993/09/14 05:41:49 dc
|
|
* new fr/camera regieme
|
|
*
|
|
* Revision 1.2 1993/09/05 20:54:16 dc
|
|
* new regieme for real, or at least more so
|
|
*
|
|
* Revision 1.1 1993/09/05 20:21:41 dc
|
|
* Initial revision
|
|
*
|
|
*/
|
|
|
|
#include "fauxrint.h"
|
|
#include "froslew.h"
|
|
#ifndef __RENDTEST__
|
|
#include "objsim.h"
|
|
#endif
|
|
#include "map.h"
|
|
#include "tilename.h"
|
|
#include "mapflags.h"
|
|
|
|
int32_t eye_mods[3] = {0, 0, 0};
|
|
|
|
// prototype
|
|
int32_t *fr_objslew_obj_to_list(int32_t *flist, Obj *cobj, int count);
|
|
Obj *fr_objslew_list_to_obj(int32_t *flist, Obj *cobj, int count);
|
|
|
|
int32_t *fr_objslew_obj_to_list(int32_t *flist, Obj *cobj, int count) {
|
|
switch (count - 1) {
|
|
case 5:
|
|
flist[5] = (cobj->loc.b << 8);
|
|
case 4:
|
|
flist[4] = (cobj->loc.p << 8);
|
|
case 3:
|
|
flist[3] = (cobj->loc.h << 8);
|
|
case 2:
|
|
flist[2] = (cobj->loc.z << SLOPE_SHIFT_D);
|
|
default:
|
|
case 1:
|
|
flist[1] = cobj->loc.y;
|
|
case 0:
|
|
flist[0] = cobj->loc.x;
|
|
break;
|
|
}
|
|
return flist;
|
|
}
|
|
|
|
Obj *fr_objslew_list_to_obj(int32_t *flist, Obj *cobj, int count) {
|
|
switch (count - 1) {
|
|
case 5:
|
|
cobj->loc.b = (flist[5] >> 8);
|
|
case 4:
|
|
cobj->loc.p = (flist[4] >> 8);
|
|
case 3:
|
|
cobj->loc.h = (flist[3] >> 8);
|
|
case 2:
|
|
cobj->loc.z = (flist[2] >> SLOPE_SHIFT_D);
|
|
default:
|
|
case 1:
|
|
cobj->loc.y = flist[1];
|
|
case 0:
|
|
cobj->loc.x = flist[0];
|
|
break;
|
|
}
|
|
return cobj;
|
|
}
|
|
|
|
// returns whether the camera moved or not
|
|
uchar fr_objslew_go_real_height(Obj *cobj, int32_t *eye) {
|
|
int32_t leye[3];
|
|
int x, y, z;
|
|
MapElem *o_t;
|
|
|
|
if (cobj != NULL) {
|
|
eye = leye;
|
|
fr_objslew_obj_to_list(eye, cobj, 3);
|
|
}
|
|
x = eye[0] >> MAP_SH;
|
|
y = eye[1] >> MAP_SH;
|
|
o_t = MAP_GET_XY(x, y);
|
|
z = me_height_flr(o_t);
|
|
z *= MAP_SC >> SLOPE_SHIFT;
|
|
// someday should teach this about other tile types....
|
|
if (me_bits_mirror(o_t) != MAP_FFLAT)
|
|
if ((me_tiletype(o_t) >= TILE_SLOPEUP_N) && (me_tiletype(o_t) <= TILE_SLOPEUP_W)) {
|
|
int diff;
|
|
switch (me_tiletype(o_t)) {
|
|
case TILE_SLOPEUP_N:
|
|
diff = eye[1] & MAP_MK;
|
|
break;
|
|
case TILE_SLOPEUP_E:
|
|
diff = eye[0] & MAP_MK;
|
|
break;
|
|
case TILE_SLOPEUP_S:
|
|
diff = MAP_MK - (eye[1] & MAP_MK);
|
|
break;
|
|
case TILE_SLOPEUP_W:
|
|
diff = MAP_MK - (eye[0] & MAP_MK);
|
|
break;
|
|
}
|
|
z += (diff * me_param(o_t)) >> SLOPE_SHIFT;
|
|
}
|
|
// now add height of current posture...
|
|
eye[2] = z + PLAYER_HEIGHT / 2; /* this should probably be fixed */
|
|
if (cobj != NULL)
|
|
fr_objslew_list_to_obj(eye, cobj, 3);
|
|
return TRUE;
|
|
}
|
|
|
|
uchar fr_objslew_allowed(Obj *cobj, int32_t *eye) {
|
|
int x, y; // z
|
|
MapElem *o_t;
|
|
|
|
if (cobj != NULL)
|
|
fr_objslew_obj_to_list(eye, cobj, 3);
|
|
x = eye[0] >> MAP_SH;
|
|
y = eye[1] >> MAP_SH;
|
|
if ((x < 0) || (x >= MAP_XSIZE) || (y < 0) || (y >= MAP_YSIZE))
|
|
return FALSE;
|
|
o_t = MAP_GET_XY(x, y);
|
|
if (me_tiletype(o_t) == TILE_SOLID)
|
|
return FALSE;
|
|
if (cobj != NULL)
|
|
fr_objslew_list_to_obj(eye, cobj, 3);
|
|
return TRUE;
|
|
}
|
|
|
|
// to physics teleport or not
|
|
// should teach it not to slam all velocities!
|
|
uchar fr_objslew_moveone(Obj *cobj, ObjID objnum, int which, int how, uchar conform) {
|
|
int32_t eye[4];
|
|
uchar valid_pos = TRUE;
|
|
|
|
if (cobj == NULL)
|
|
cobj = &objs[objnum];
|
|
fr_objslew_obj_to_list(eye, cobj, 4);
|
|
switch (which) {
|
|
case EYE_HEADH:
|
|
eye_mods[0] += how * cam_slew_scale[which];
|
|
return valid_pos; // break;
|
|
case EYE_H:
|
|
cobj->loc.h += (how * cam_slew_scale[which]) >> 8;
|
|
break;
|
|
case EYE_RESET:
|
|
eye_mods[0] = eye_mods[1] = eye_mods[2] = 0;
|
|
return valid_pos; // break;
|
|
case EYE_B:
|
|
case EYE_P:
|
|
eye_mods[which - 3] += how * cam_slew_scale[which];
|
|
return valid_pos; // break;
|
|
case EYE_Z:
|
|
eye[2] += how << SLOPE_SHIFT_D;
|
|
break;
|
|
case EYE_Y:
|
|
case EYE_X: {
|
|
fix v[2], tot;
|
|
tot = how * cam_slew_scale[which];
|
|
fix_sincos((fixang)(eye[3] + (which == EYE_X ? 0x4000 : 0)), v + 0, v + 1);
|
|
eye[0] += fix_int(fix_mul(v[0], tot));
|
|
eye[1] += fix_int(fix_mul(v[1], tot));
|
|
if (conform)
|
|
if ((valid_pos = fr_objslew_allowed(NULL, eye)) == TRUE)
|
|
fr_objslew_go_real_height(NULL, eye);
|
|
break;
|
|
}
|
|
}
|
|
fr_objslew_list_to_obj(eye, cobj, 3);
|
|
obj_move_to(cobj - objs, &cobj->loc, TRUE);
|
|
return valid_pos;
|
|
}
|
|
|
|
// to physics teleport or not
|
|
//#pragma disable_message(202)
|
|
uchar fr_objslew_setone(int which, int l_new) {
|
|
switch (which) {
|
|
case EYE_HEADH:
|
|
eye_mods[0] = l_new;
|
|
return TRUE;
|
|
case EYE_H:
|
|
break;
|
|
case EYE_RESET:
|
|
eye_mods[0] = eye_mods[1] = eye_mods[2] = 0;
|
|
return TRUE;
|
|
case EYE_P:
|
|
eye_mods[1] = l_new;
|
|
return TRUE;
|
|
case EYE_B:
|
|
eye_mods[2] = l_new;
|
|
return TRUE;
|
|
case EYE_Z:
|
|
case EYE_Y:
|
|
case EYE_X:
|
|
break;
|
|
}
|
|
return TRUE;
|
|
}
|
|
//#pragma enable_message(202)
|
|
|
|
/* KLC - not used
|
|
uchar fr_objslew_tele_to(Obj *, int , int )
|
|
{
|
|
return TRUE;
|
|
}
|
|
*/
|