diff --git a/polymer/eduke32/source/actors.h b/polymer/eduke32/source/actors.h index 5cb8c47d7..7e3589573 100644 --- a/polymer/eduke32/source/actors.h +++ b/polymer/eduke32/source/actors.h @@ -76,16 +76,16 @@ enum uactortypes_t { // These macros are there to give names to the t_data[]/T*/vm.g_t[] indices // when used with actors. Greppability of source code is certainly a virtue. -#define AC_COUNT(t) (t[0]) /* the actor's count */ +#define AC_COUNT(t) ((t)[0]) /* the actor's count */ /* The ID of the actor's current move. In C-CON, the bytecode offset to the * move composite: */ -#define AC_MOVE_ID(t) (t[1]) -#define AC_ACTION_COUNT(t) (t[2]) /* the actor's action count */ -#define AC_CURFRAME(t) (t[3]) /* the actor's current frame offset */ +#define AC_MOVE_ID(t) ((t)[1]) +#define AC_ACTION_COUNT(t) ((t)[2]) /* the actor's action count */ +#define AC_CURFRAME(t) ((t)[3]) /* the actor's current frame offset */ /* The ID of the actor's current action. In C-CON, the bytecode offset to the * action composite: */ -#define AC_ACTION_ID(t) (t[4]) -#define AC_AI_ID(t) (t[5]) /* the ID of the actor's current ai */ +#define AC_ACTION_ID(t) ((t)[4]) +#define AC_AI_ID(t) ((t)[5]) /* the ID of the actor's current ai */ #ifdef LUNATIC struct action { @@ -122,6 +122,18 @@ typedef struct { int32_t userdata; // 4b } projectile_t; +// Select an actor's actiontics and movflags locations depending on +// whether we compile the Lunatic build. +// : sprite pointer +// : actor_t pointer +#ifdef LUNATIC +# define AC_ACTIONTICS(spr, a) ((a)->actiontics) +# define AC_MOVFLAGS(spr, a) ((a)->movflags) +#else +# define AC_ACTIONTICS(spr, a) ((spr)->lotag) +# define AC_MOVFLAGS(spr, a) ((spr)->hitag) +#endif + #pragma pack(push,1) // (+ 40 16 16 4 8 6 8 6 4 20) typedef struct { @@ -131,7 +143,8 @@ typedef struct { // total: 16b struct move mv; struct action ac; - const int16_t padding_; + // Gets incremented by TICSPERFRAME on each A_Execute() call: + uint16_t actiontics; #endif int32_t flags; //4b @@ -142,10 +155,17 @@ typedef struct { int16_t picnum,ang,extra,owner; //8b int16_t movflag,tempang,timetosleep; //6b + int16_t actorstayput, dispicnum; +#if !defined LUNATIC // NOTE: shootzvel is not used any more. - int16_t actorstayput, dispicnum, shootzvel_, cgg; // 8b - int16_t lightId, lightcount, lightmaxrange; //6b + int16_t shootzvel_; +#else + // Movement flags, sprite[i].hitag in C-CON: + uint16_t movflags; +#endif + int16_t cgg; + int16_t lightId, lightcount, lightmaxrange; //6b #ifdef POLYMER _prlight *lightptr; //4b/8b #else @@ -180,7 +200,7 @@ typedef struct { #ifdef LUNATIC struct move mv; struct action ac; - const int16_t padding_; + uint16_t actiontics; #endif int32_t flags; //4b @@ -191,7 +211,13 @@ typedef struct { int16_t picnum,ang,extra,owner; //8b int16_t movflag,tempang,timetosleep; // 6b - int16_t actorstayput, dispicnum, shootzvel_, cgg; // 8b + int16_t actorstayput, dispicnum; +#if !defined LUNATIC + int16_t shootzvel_; +#else + uint16_t movflags; +#endif + int16_t cgg; spritetype sprite; int16_t netIndex; diff --git a/polymer/eduke32/source/game.c b/polymer/eduke32/source/game.c index 29d8edcd1..6ba79c68f 100644 --- a/polymer/eduke32/source/game.c +++ b/polymer/eduke32/source/game.c @@ -4807,7 +4807,7 @@ static int32_t G_InitActor(int32_t i, int32_t tilenum, int32_t set_movflag_uncon AC_ACTION_ID(actor[i].t_data) = *(g_tile[tilenum].execPtr+1); AC_MOVE_ID(actor[i].t_data) = *(g_tile[tilenum].execPtr+2); - if (set_movflag_uncond || SHT == 0) + if (set_movflag_uncond || SHT == 0) // AC_MOVFLAGS SHT = *(g_tile[tilenum].execPtr+3); return 1; @@ -4817,6 +4817,7 @@ static int32_t G_InitActor(int32_t i, int32_t tilenum, int32_t set_movflag_uncon { // ^^^ C-CON takes precedence for now. const el_actor_t *a = &g_elActors[tilenum]; + uint16_t *movflagsptr = &AC_MOVFLAGS(&sprite[i], &actor[i]); SH = a->strength; AC_ACTION_ID(actor[i].t_data) = a->act.id; @@ -4824,8 +4825,8 @@ static int32_t G_InitActor(int32_t i, int32_t tilenum, int32_t set_movflag_uncon Bmemcpy(&actor[i].ac, &a->act.ac, sizeof(struct action)); Bmemcpy(&actor[i].mv, &a->mov.mv, sizeof(struct move)); - if (set_movflag_uncond || SHT == 0) - SHT = a->movflags; + if (set_movflag_uncond || *movflagsptr == 0) + *movflagsptr = a->movflags; return 1; } @@ -5999,6 +6000,8 @@ int32_t A_Spawn(int32_t j, int32_t pn) } } + // If spawned from parent sprite (as opposed to 'from premap'), + // ignore skill. if (j >= 0) sp->lotag = 0; if ((sp->lotag > ud.player_skill) || ud.monsters_off == 1) diff --git a/polymer/eduke32/source/gameexec.c b/polymer/eduke32/source/gameexec.c index 8c0fa80db..062b540a6 100644 --- a/polymer/eduke32/source/gameexec.c +++ b/polymer/eduke32/source/gameexec.c @@ -594,7 +594,8 @@ GAMEEXEC_STATIC void VM_Move(void) #endif // NOTE: commented out condition is dead since r3159 (making hi/lotag unsigned). // XXX: Does it break anything? Where are movflags with all bits set created? - const int32_t movflags = /*(vm.g_sp->hitag==-1) ? 0 :*/ vm.g_sp->hitag; + const uint16_t *movflagsptr = &AC_MOVFLAGS(vm.g_sp, &actor[vm.g_i]); + const int32_t movflags = /*(*movflagsptr==-1) ? 0 :*/ *movflagsptr; const int32_t deadflag = (A_CheckEnemySprite(vm.g_sp) && vm.g_sp->extra <= 0); int32_t badguyp, angdif; @@ -2236,7 +2237,7 @@ nullquote: // offsets AC_ACTION_ID(a->t_data) = actorptr[1]; AC_MOVE_ID(a->t_data) = actorptr[2]; - sprite[i].hitag = actorptr[3]; // ai bits (movflags) + AC_MOVFLAGS(&sprite[i], &actor[i]) = actorptr[3]; // ai bits (movflags) } } @@ -5381,12 +5382,13 @@ void A_Execute(int32_t iActor,int32_t iPlayer,int32_t lDist) const int32_t action_incval = actor[vm.g_i].ac.incval; const int32_t action_delay = actor[vm.g_i].ac.delay; #endif - vm.g_sp->lotag += TICSPERFRAME; + uint16_t *actionticsptr = &AC_ACTIONTICS(vm.g_sp, &actor[vm.g_i]); + *actionticsptr += TICSPERFRAME; - if (vm.g_sp->lotag > action_delay) + if (*actionticsptr > action_delay) { AC_ACTION_COUNT(vm.g_t)++; - vm.g_sp->lotag = 0; + *actionticsptr = 0; AC_CURFRAME(vm.g_t) += action_incval; } diff --git a/polymer/eduke32/source/lunatic/defs.ilua b/polymer/eduke32/source/lunatic/defs.ilua index 8c70bee6d..06c7332d4 100644 --- a/polymer/eduke32/source/lunatic/defs.ilua +++ b/polymer/eduke32/source/lunatic/defs.ilua @@ -155,7 +155,7 @@ __attribute__((packed)) struct { const int32_t t_data[10]; const struct move mv; const struct action ac; - const int16_t _padding[1]; + const uint16_t actiontics; ]]..defs_c.bitint_member("SBit32", "flags")..[[ vec3_t bpos; //12b @@ -169,10 +169,15 @@ __attribute__((packed)) struct { int16_t stayputsect; const int16_t dispicnum; - int16_t shootzvel, cgg; + // Movement flags, sprite[i].hitag in C-CON. + // XXX: more research where it was used in EDuke32's C code? (also .lotag <-> actiontics) + // XXX: what if CON code knew of the above implementation detail? +]]..defs_c.bitint_member("UBit16", "movflags")..[[ + int16_t cgg; const int16_t lightId, lightcount, lightmaxrange; const union { intptr_t ptr; uint64_t dummy; } _light; +// XXX: 32-bit has filler } ]] @@ -1001,11 +1006,11 @@ local actor_mt = { end a.t_data[0] = 0 + a.movflags = movflags or 0 local spr = ffiC.sprite[get_actor_idx(a)] - spr.hitag = movflags or 0 if (not spr:isenemy() or spr.extra > 0) then - if (bit.band(spr.hitag, 8) ~= 0) then -- random_angle + if (bit.band(a.movflags, 8) ~= 0) then -- random_angle spr.ang = bit.band(ffiC.krand(), 2047) end end diff --git a/polymer/eduke32/source/lunatic/test.elua b/polymer/eduke32/source/lunatic/test.elua index 30f4e6405..7fd51d6a3 100644 --- a/polymer/eduke32/source/lunatic/test.elua +++ b/polymer/eduke32/source/lunatic/test.elua @@ -456,7 +456,7 @@ gameactor if (actr:has_action(CAC.ATROOPWALKING)) then if (actr:get_count() % 50 == 0) then - spr.hitag = bit.bxor(spr.hitag, actor.MOVFLAGS.spin) + actr.movflagsbits:flip(actor.MOVFLAGS.spin) end end end @@ -468,13 +468,14 @@ gameactor -- XXX: I want to write "{0, 4, delay=20}" action = con.action{0, 4, 1, 1, 20}, - move = con.move{}, -- so that the ID is nonzero + move = con.move{}, -- so that the ID is nonzero and it will move func = function(aci) + local a = actor[aci] local delay = math.sin(0.1 * 2*math.pi*gv.totalclock/120) - actor[aci]:set_action_delay(20 + 10*delay) - actor[aci]:set_hvel(50*delay) - sprite[aci].hitag = actor.MOVFLAGS.geth + a:set_action_delay(20 + 10*delay) + a:set_hvel(50*delay) + a.movflags = actor.MOVFLAGS.geth end, }