From f3970f9ac725b90f165be233f22c511cdd35ae8f Mon Sep 17 00:00:00 2001 From: helixhorned Date: Mon, 6 Aug 2012 20:00:29 +0000 Subject: [PATCH] Lunatic: clean up handing of ac/mv internally, add control module. git-svn-id: https://svn.eduke32.com/eduke32@2864 1a8010ca-5511-0410-912e-c29ae57300e0 --- polymer/eduke32/Makefile | 3 +- polymer/eduke32/source/actors.c | 4 +- polymer/eduke32/source/actors.h | 96 ++++++++++++----------- polymer/eduke32/source/game.c | 64 ++++++--------- polymer/eduke32/source/gameexec.c | 30 +++---- polymer/eduke32/source/lunatic/con.lua | 54 +++++++++++++ polymer/eduke32/source/lunatic/defs.ilua | 82 ++++++++++++++++++- polymer/eduke32/source/lunatic/dynsymlist | 1 + polymer/eduke32/source/lunatic/test.elua | 9 +++ 9 files changed, 240 insertions(+), 103 deletions(-) create mode 100644 polymer/eduke32/source/lunatic/con.lua diff --git a/polymer/eduke32/Makefile b/polymer/eduke32/Makefile index 45ae1ee9c..60f62bdc2 100644 --- a/polymer/eduke32/Makefile +++ b/polymer/eduke32/Makefile @@ -171,7 +171,8 @@ ifneq (0,$(LUNATIC)) $(OBJ)/luaJIT_BC_geom.$o \ $(OBJ)/luaJIT_BC_randgen.$o \ $(OBJ)/luaJIT_BC_stat.$o \ - $(OBJ)/luaJIT_BC_bitar.$o + $(OBJ)/luaJIT_BC_bitar.$o \ + $(OBJ)/luaJIT_BC_con.$o # now, take care of having the necessary symbols (sector, wall, etc.) in the # executable no matter what the debugging level diff --git a/polymer/eduke32/source/actors.c b/polymer/eduke32/source/actors.c index d39355770..df7c6bcb4 100644 --- a/polymer/eduke32/source/actors.c +++ b/polymer/eduke32/source/actors.c @@ -708,8 +708,8 @@ static void A_MoveSector(int32_t i) # define LIGHTRAD_PICOFS (T5 ? *(script+T5) + (*(script+T5+2))*T4 : 0) #else // SACTION -// startframe + viewtype*??? -# define LIGHTRAD_PICOFS (ACTION_STARTFRAME(actor[i].t_data) + ACTION_VIEWTYPE(actor[i].t_data)*T4) +// startframe + viewtype*[cyclic counter] +# define LIGHTRAD_PICOFS (actor[i].ac.startframe + actor[i].ac.viewtype*T4) #endif // this is the same crap as in game.c's tspr manipulation. puke. diff --git a/polymer/eduke32/source/actors.h b/polymer/eduke32/source/actors.h index c7790f2d3..ac0a21246 100644 --- a/polymer/eduke32/source/actors.h +++ b/polymer/eduke32/source/actors.h @@ -45,45 +45,6 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #define STAT_DUMMYPLAYER 13 #define STAT_LIGHT 14 -#ifdef LUNATIC -// Ai, action, move getters from t_data[] (== tptr) -# define ACTION_STARTFRAME(tptr) ((tptr)[10]&0x0000ffff) -# define ACTION_NUMFRAMES(tptr) (((tptr)[10]>>16)&0x0000ffff) -# define ACTION_VIEWTYPE(tptr) ((tptr)[11]&0x0000ffff) -# define ACTION_INCVAL(tptr) ((tptr)[11]>>16) // arithmetic shr expected! -# define ACTION_DELAY(tptr) ((tptr)[12]&0x0000ffff) - -# define ACTION_SET_STARTFRAME(tptr, val) do { (tptr)[10] &= ~0x0000ffff; (tptr)[10] |= (val)&0x0000ffff; } while (0) -# define ACTION_SET_NUMFRAMES(tptr, val) do { (tptr)[10] &= ~0xffff0000; (tptr)[10] |= ((val)<<16); } while (0) -# define ACTION_SET_VIEWTYPE(tptr, val) do { (tptr)[11] &= ~0x0000ffff; (tptr)[11] |= (val)&0x0000ffff; } while (0) -# define ACTION_SET_INCVAL(tptr, val) do { (tptr)[11] &= ~0xffff0000; (tptr)[11] |= (val)<<16; } while (0) -# define ACTION_SET_DELAY(tptr, val) do { (tptr)[12] = (val)&0x0000ffff; } while (0) - -# define MOVE_H(tptr) ((int16_t)((tptr)[13])) -# define MOVE_V(tptr) ((int16_t)((tptr)[13]>>16)) - -# define MOVE_SET_H(tptr, val) do { (tptr)[13] &= ~0x0000ffff; (tptr)[13] |= (val)&0x0000ffff; } while (0) -# define MOVE_SET_V(tptr, val) do { (tptr)[13] &= ~0xffff0000; (tptr)[13] |= (val)<<16; } while (0) - -extern intptr_t *script; - -// tptr[4] expected to be set -static inline void set_action_members(int32_t *tptr) -{ - ACTION_SET_STARTFRAME(tptr, script[tptr[4]]); - ACTION_SET_NUMFRAMES(tptr, script[tptr[4]+1]); - ACTION_SET_VIEWTYPE(tptr, script[tptr[4]+2]); - ACTION_SET_INCVAL(tptr, script[tptr[4]+3]); - ACTION_SET_DELAY(tptr, script[tptr[4]+4]); -} - -// tptr[1] expected to be set -static inline void set_move_members(int32_t *tptr) -{ - MOVE_SET_H(tptr, script[tptr[1]]); - MOVE_SET_V(tptr, script[tptr[1]+1]); -} -#endif // Defines the motion characteristics of an actor enum amoveflags_t { @@ -109,6 +70,18 @@ enum uactortypes_t { }; #pragma pack(push,1) + +#ifdef LUNATIC +struct action { + int16_t startframe, numframes; + int16_t viewtype, incval, delay; +}; + +struct move { + int16_t hvel, vvel; +}; +#endif + typedef struct { int32_t workslike, cstat; // 8b int32_t hitradius, range, flashcolor; // 12b @@ -126,11 +99,13 @@ typedef struct { // (+ 40 8 6 16 16 4 8 6 4 20) typedef struct { -#ifndef LUNATIC int32_t t_data[10]; // 40b sometimes used to hold offsets to con code -#else - int32_t t_data[14]; // 56b + +#ifdef LUNATIC // TODO: rearrange for better packing when enabling Lunatic + struct move mv; + struct action ac; + const int16_t padding_; #endif int16_t picnum,ang,extra,owner; //8b @@ -172,10 +147,12 @@ typedef struct { // this struct needs to match the beginning of actor_t above typedef struct { -#ifndef LUNATIC int32_t t_data[10]; // 40b sometimes used to hold offsets to con code -#else - int32_t t_data[14]; // 56b + +#ifdef LUNATIC + struct move mv; + struct action ac; + const int16_t padding_; #endif int16_t picnum,ang,extra,owner; //8b @@ -241,6 +218,35 @@ extern projectile_t DefaultProjectileData[MAXTILES]; extern projectile_t ProjectileData[MAXTILES]; extern projectile_t SpriteProjectile[MAXSPRITES]; + +#ifdef LUNATIC +// Legacy action/move setters from the CON script + t_data pointer: +extern intptr_t *script; + +// tptr[4] expected to be set +static inline void set_action_members(int32_t i) +{ + actor_t *const aptr = &actor[i]; + int32_t acofs = aptr->t_data[4]; + + aptr->ac.startframe = script[acofs]; + aptr->ac.numframes = script[acofs+1]; + aptr->ac.viewtype = script[acofs+2]; + aptr->ac.incval = script[acofs+3]; + aptr->ac.delay = script[acofs+4]; +} + +// tptr[1] expected to be set +static inline void set_move_members(int32_t i) +{ + actor_t *const aptr = &actor[i]; + int32_t mvofs = aptr->t_data[1]; + + aptr->mv.hvel = script[mvofs]; + aptr->mv.vvel = script[mvofs+1]; +} +#endif + void A_AddToDeleteQueue(int32_t i); int32_t A_CheckEnemySprite(const spritetype *s); int32_t A_CheckEnemyTile(int32_t pn); diff --git a/polymer/eduke32/source/game.c b/polymer/eduke32/source/game.c index f887a9d42..01bb065f8 100644 --- a/polymer/eduke32/source/game.c +++ b/polymer/eduke32/source/game.c @@ -3919,8 +3919,8 @@ int32_t A_InsertSprite(int32_t whatsect,int32_t s_x,int32_t s_y,int32_t s_z,int3 T5 = *(actorscrptr[s_pn]+1); T2 = *(actorscrptr[s_pn]+2); #ifdef LUNATIC - set_action_members(actor[i].t_data); - set_move_members(actor[i].t_data); + set_action_members(i); + set_move_members(i); #endif s->hitag = *(actorscrptr[s_pn]+3); } @@ -4050,8 +4050,8 @@ int32_t A_Spawn(int32_t j, int32_t pn) T5 = *(actorscrptr[s]+1); T2 = *(actorscrptr[s]+2); #ifdef LUNATIC - set_action_members(actor[i].t_data); - set_move_members(actor[i].t_data); + set_action_members(i); + set_move_members(i); #endif if (*(actorscrptr[s]+3) && SHT == 0) SHT = *(actorscrptr[s]+3); @@ -6086,12 +6086,11 @@ void G_DoSpriteAnimations(int32_t x,int32_t y,int32_t a,int32_t smoothratio) for (j=spritesortcnt-1; j>=0; j--) //Between drawrooms() and drawmasks() { int32_t switchpic; + int32_t t_data3; #ifndef LUNATIC - int32_t t_data1,t_data3,t_data4; + int32_t t_data4; #else - int32_t t_data[14] = { 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0 }; - - Bassert(sizeof(t_data) == sizeof(actor[0].t_data)); + int32_t startframe, viewtype; #endif //is the perfect time to animate sprites t = &tsprite[j]; @@ -6190,19 +6189,15 @@ void G_DoSpriteAnimations(int32_t x,int32_t y,int32_t a,int32_t smoothratio) } sect = s->sectnum; -#ifndef LUNATIC - t_data1 = T2; + + Bassert(i >= 0); t_data3 = T4; +#ifndef LUNATIC t_data4 = T5; // SACTION #else - t_data[1] = T2; - t_data[3] = T4; - t_data[4] = T5; - - set_action_members(t_data); - set_move_members(t_data); + startframe = actor[i].ac.startframe; + viewtype = actor[i].ac.viewtype; #endif - switchpic = s->picnum; //some special cases because dynamictostatic system can't handle addition to constants if ((s->picnum >= SCRAP6)&&(s->picnum<=SCRAP6+7)) @@ -6338,11 +6333,9 @@ void G_DoSpriteAnimations(int32_t x,int32_t y,int32_t a,int32_t smoothratio) } else t->cstat &= ~4; -#ifndef LUNATIC - if (klabs(t_data3) > 64) k += 7; -#else - if (klabs(t_data[3]) > 64) k += 7; -#endif + if (klabs(t_data3) > 64) + k += 7; // tilted recon car + t->picnum = RECON+k; break; @@ -6474,18 +6467,15 @@ void G_DoSpriteAnimations(int32_t x,int32_t y,int32_t a,int32_t smoothratio) if (g_player[p].ps->newowner > -1) { + // Display APLAYER sprites with action PSTAND when viewed through + // a camera. Not implemented for Lunatic. #ifndef LUNATIC - t_data4 = *(actorscrptr[APLAYER]+1); - t_data3 = 0; - t_data1 = *(actorscrptr[APLAYER]+2); -#else - t_data[4] = *(actorscrptr[APLAYER]+1); // TODO: this must go! - set_action_members(t_data); + const intptr_t *aplayer_scr = actorscrptr[APLAYER]; + // [0]=strength, [1]=actionofs, [2]=moveofs - t_data[3] = 0; - t_data[1] = *(actorscrptr[APLAYER]+2); // TODO: this must go! - set_move_members(t_data); + t_data4 = aplayer_scr[1]; #endif + t_data3 = 0; } if (ud.camerasprite == -1 && g_player[p].ps->newowner == -1) @@ -6598,7 +6588,7 @@ PALONLY: l = script[t_data4 + 2]; #else - l = ACTION_VIEWTYPE(t_data); + l = viewtype; #endif #ifdef USE_OPENGL @@ -6656,9 +6646,9 @@ PALONLY: } #ifndef LUNATIC - t->picnum += k + *(script + t_data4) + l*t_data3; + t->picnum += k + script[t_data4] + l*t_data3; #else - t->picnum += k + ACTION_STARTFRAME(t_data) + l*t_data[3]; + t->picnum += k + startframe + l*t_data3; #endif if (l > 0) @@ -6820,11 +6810,7 @@ skip: break; case WATERSPLASH2__STATIC: -#ifndef LUNATIC - t->picnum = WATERSPLASH2+t_data1; -#else - t->picnum = WATERSPLASH2+t_data[1]; -#endif + t->picnum = WATERSPLASH2+T2; break; case SHELL__STATIC: t->picnum = s->picnum+(T1&1); diff --git a/polymer/eduke32/source/gameexec.c b/polymer/eduke32/source/gameexec.c index a3d91ee33..5e1a08553 100644 --- a/polymer/eduke32/source/gameexec.c +++ b/polymer/eduke32/source/gameexec.c @@ -451,11 +451,13 @@ GAMEEXEC_STATIC void VM_AlterAng(int32_t a) moveptr = script + vm.g_t[1]; // RESEARCH: what's with move 0 and >>> 1 <<xvel += (*moveptr-vm.g_sp->xvel)/5; - if (vm.g_sp->zvel < 648) vm.g_sp->zvel += ((*(moveptr+1)<<4)-vm.g_sp->zvel)/5; + vm.g_sp->xvel += (*moveptr - vm.g_sp->xvel)/5; + if (vm.g_sp->zvel < 648) + vm.g_sp->zvel += ((*(moveptr+1)<<4) - vm.g_sp->zvel)/5; #else - vm.g_sp->xvel += (MOVE_H(vm.g_t)-vm.g_sp->xvel)/5; - if (vm.g_sp->zvel < 648) vm.g_sp->zvel += ((MOVE_V(vm.g_t)<<4)-vm.g_sp->zvel)/5; + vm.g_sp->xvel += (actor[vm.g_i].mv.hvel - vm.g_sp->xvel)/5; + if (vm.g_sp->zvel < 648) + vm.g_sp->zvel += ((actor[vm.g_i].mv.vvel<<4) - vm.g_sp->zvel)/5; #endif if (A_CheckEnemySprite(vm.g_sp) && vm.g_sp->extra <= 0) // hack @@ -600,8 +602,8 @@ dead: if (a&geth) vm.g_sp->xvel += ((*moveptr)-vm.g_sp->xvel)>>1; if (a&getv) vm.g_sp->zvel += ((*(moveptr+1)<<4)-vm.g_sp->zvel)>>1; #else - if (a&geth) vm.g_sp->xvel += (MOVE_H(vm.g_t)-vm.g_sp->xvel)>>1; - if (a&getv) vm.g_sp->zvel += ((MOVE_V(vm.g_t)<<4)-vm.g_sp->zvel)>>1; + if (a&geth) vm.g_sp->xvel += (actor[vm.g_i].mv.hvel - vm.g_sp->xvel)>>1; + if (a&getv) vm.g_sp->zvel += (actor[vm.g_i].mv.vvel - vm.g_sp->zvel)>>1; #endif if (a&dodgebullet && !deadflag) @@ -942,13 +944,13 @@ skip_check: vm.g_t[4] = *(script + vm.g_t[5]); // Action #ifdef LUNATIC - set_action_members(vm.g_t); + set_action_members(vm.g_i); #endif if (vm.g_t[5]) { vm.g_t[1] = *(script + vm.g_t[5] + 1); // move #ifdef LUNATIC - set_move_members(vm.g_t); + set_move_members(vm.g_i); #endif } vm.g_sp->hitag = *(script + vm.g_t[5] + 2); // move flags @@ -964,7 +966,7 @@ skip_check: vm.g_t[2] = vm.g_t[3] = 0; vm.g_t[4] = *insptr++; #ifdef LUNATIC - set_action_members(vm.g_t); + set_action_members(vm.g_i); #endif continue; @@ -1286,7 +1288,7 @@ skip_check: #ifndef LUNATIC (unsigned)moveScriptOfs < (unsigned)g_scriptSize-1 && script[moveScriptOfs + 1] #else - MOVE_V(vm.g_t) != 0 + actor[vm.g_i].mv.vvel != 0 #endif )) { @@ -1486,7 +1488,7 @@ skip_check: vm.g_t[0]=0; vm.g_t[1] = *insptr++; #ifdef LUNATIC - set_move_members(vm.g_t); + set_move_members(vm.g_i); #endif vm.g_sp->hitag = *insptr++; if (A_CheckEnemySprite(vm.g_sp) && vm.g_sp->extra <= 0) // hack @@ -5057,9 +5059,9 @@ void A_Execute(int32_t iActor,int32_t iPlayer,int32_t lDist) const int32_t action_delay = *(script + vm.g_t[4] + 4); #else // SACTION - const int32_t action_frames = ACTION_NUMFRAMES(vm.g_t); - const int32_t action_incval = ACTION_INCVAL(vm.g_t); - const int32_t action_delay = ACTION_DELAY(vm.g_t); + const int32_t action_frames = actor[vm.g_i].ac.numframes; + 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; diff --git a/polymer/eduke32/source/lunatic/con.lua b/polymer/eduke32/source/lunatic/con.lua new file mode 100644 index 000000000..caf397e06 --- /dev/null +++ b/polymer/eduke32/source/lunatic/con.lua @@ -0,0 +1,54 @@ +-- Game control module for Lunatic. + +local ffi = require("ffi") + +local setmetatable = setmetatable + +local assert = assert +local error = error +local type = type + + +module(...) + + +local lastid = { action=0, move=0 } + +local function forbidden() error("newindex forbidden", 2) end +local ac, mv = {}, {} + +AC = setmetatable({}, { __index=ac, __newindex=forbidden }) +MV = setmetatable({}, { __index=mv, __newindex=forbidden }) + +local function action_or_move(what, numargs, tab, name, ...) + assert(lastid[what] > -(2^31)) + if (type(name)~="string" or #name > 63) then + error("bad argument #1 to "..what..": must be a string of length <= 63", 3) + end + + local args = {...} + assert(#args <= numargs) + + for i=1,#args do + local n = args[i] + assert(type(n)=="number" and (n >= -32768 and n <= 32767)) + end + -- missing fields are initialized to 0 by ffi.new + + -- Named actions or moves have negative ids so that non-negative ones + -- can be used as (different) placeholders for all-zero ones. + lastid[what] = lastid[what]-1 + + -- ffi.new takes either for initialization: varargs, a table with numeric + -- indices, or a table with key-value pairs + -- See http://luajit.org/ext_ffi_semantics.html#init_table + tab[name] = ffi.new("const con_"..what.."_t", lastid[what], args) +end + +function action(name, ...) + action_or_move("action", 5, ac, name, ...) +end + +function move(name, ...) + action_or_move("move", 2, mv, name, ...) +end diff --git a/polymer/eduke32/source/lunatic/defs.ilua b/polymer/eduke32/source/lunatic/defs.ilua index b34c33448..8253618c2 100644 --- a/polymer/eduke32/source/lunatic/defs.ilua +++ b/polymer/eduke32/source/lunatic/defs.ilua @@ -234,14 +234,31 @@ enum { ffi.cdef([[ #pragma pack(push,1) + +struct action { + int16_t startframe, numframes; + int16_t viewtype, incval, delay; +}; + +struct move { + int16_t hvel, vvel; +}; + +typedef struct { int32_t id; struct move mv; } con_move_t; +typedef struct { int32_t id; struct action ac; } con_action_t; + // TODO: still need to make some fields read-only // NOTE: must not expose arrays in structs!!! typedef struct { ]] -..repeat_n_elts("int32_t", "_t", 14).. +..repeat_n_elts("int32_t", "_t", 10).. [[ -// const int32_t t_data[14]; // 56b sometimes used to hold offsets to con code +// const int32_t t_data[10]; // 56b sometimes used to hold offsets to con code + struct move mv; + struct action ac; + const int16_t padding_; + int16_t picnum,ang,extra,owner; //8b int16_t movflag,tempang,timetosleep; //6b @@ -257,6 +274,26 @@ typedef struct // const int8_t _do_not_use[8]; } actor_t; +// The _u_t versions are unrestricted variants for internal use. +typedef struct +{ + int32_t t_data[10]; + struct move mv; + struct action ac; + const int16_t padding_; + + int16_t picnum,ang,extra,owner; + int16_t movflag,tempang,timetosleep; + + int32_t flags, bposx,bposy,bposz; + int32_t floorz,ceilingz,lastvx,lastvy; + int32_t lasttransport; + + int16_t lightId, lightcount, lightmaxrange, cgg; + int16_t actorstayput, dispicnum, shootzvel; + const int8_t _do_not_use[8]; +} actor_u_t; + typedef struct { vec3_t pos, opos, vel, npos; int32_t bobposx, bobposy; @@ -529,6 +566,45 @@ for i=0,6 do == ffiC.g_sizes_of[i]) end + +--== Custom operations for BUILD data structures ==-- +-- declares struct action and struct move, and their ID-wrapped types +-- con_action_t and con_move_t +local con = require("con") + +-- All-zero action and move +local nullac, nullmv = ffi.new("const struct action"), ffi.new("const struct move") + +local actor_mt = { + __index = { + set_action = function(a, act) + a = ffi.cast("actor_u_t *", a) + if (ffi.istype("con_action_t", act)) then + a.t_data[4] = act.id + a.ac = act.ac + else + assert(type(act)=="number" and act >= 0 and act <= 32767) + a.t_data[4] = act + a.ac = nullac + end + end, + + set_move = function(a, mv) + a = ffi.cast("actor_u_t *", a) + if (ffi.istype("con_move_t", mov)) then + a.t_data[4] = mov.id + a.mv = mov.mv + else + assert(type(mov)=="number" and mov >= 0 and mov <= 32767) + a.t_data[4] = mov + a.mv = nullmv + end + end, + }, +} +ffi.metatype("actor_t", actor_mt) + + --- default defines local con_lang = require("con_lang") @@ -559,6 +635,8 @@ local allowed_modules = { geom = require("geom"), stat = require("stat"), bitar = require("bitar"), + + con = con, } for modname, themodule in pairs(allowed_modules) do diff --git a/polymer/eduke32/source/lunatic/dynsymlist b/polymer/eduke32/source/lunatic/dynsymlist index eec417c68..fee92a145 100644 --- a/polymer/eduke32/source/lunatic/dynsymlist +++ b/polymer/eduke32/source/lunatic/dynsymlist @@ -44,6 +44,7 @@ luaJIT_BC_geom; luaJIT_BC_randgen; luaJIT_BC_stat; luaJIT_BC_bitar; +luaJIT_BC_con; rand_jkiss_u32; rand_jkiss_dbl; diff --git a/polymer/eduke32/source/lunatic/test.elua b/polymer/eduke32/source/lunatic/test.elua index d19be3434..289d62fa0 100644 --- a/polymer/eduke32/source/lunatic/test.elua +++ b/polymer/eduke32/source/lunatic/test.elua @@ -232,6 +232,10 @@ gameevent(gv.EVENT_ENTERLEVEL, local stat = require("stat") local hs = stat.new() +local con = require("con") +local AC = con.AC +con.action("TROOPFLINTCH", 50, 1, 1, 1, 6) + gameactor(1680, -- LIZTROOP function(i, playeri, dist) sprite[i].pal = math.random(32) @@ -249,6 +253,11 @@ gameactor(1680, -- LIZTROOP printf("hitscan: %s", tostring(hs:getstats())) hs = stat.new() end + + if (dist < 4096) then + -- Duke Vader / Anakin Nukewalker? + actor[i]:set_action(AC.TROOPFLINTCH) + end end )