mirror of
https://github.com/ZDoom/raze-gles.git
synced 2024-12-25 11:10:47 +00:00
Lunatic: actors
git-svn-id: https://svn.eduke32.com/eduke32@2747 1a8010ca-5511-0410-912e-c29ae57300e0
This commit is contained in:
parent
90b169d8c8
commit
59df76f0b6
5 changed files with 112 additions and 32 deletions
|
@ -5082,6 +5082,10 @@ void A_Execute(int32_t iActor,int32_t iPlayer,int32_t lDist)
|
||||||
vm.g_t[3] = 0;
|
vm.g_t[3] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef LUNATIC
|
||||||
|
if (El_IsInitialized(&g_ElState) && El_HaveActor(vm.g_sp->picnum))
|
||||||
|
El_CallActor(&g_ElState, vm.g_sp->picnum, iActor, iPlayer, lDist);
|
||||||
|
#endif
|
||||||
VM_Execute(1);
|
VM_Execute(1);
|
||||||
insptr = NULL;
|
insptr = NULL;
|
||||||
|
|
||||||
|
|
|
@ -431,7 +431,8 @@ string.dump = nil
|
||||||
|
|
||||||
--- non-default data and functions
|
--- non-default data and functions
|
||||||
G_._EDUKE32_LUNATIC = _EDUKE32_LUNATIC
|
G_._EDUKE32_LUNATIC = _EDUKE32_LUNATIC
|
||||||
G_.setevent = setevent -- included in lunatic.c
|
G_.gameevent = gameevent -- included in lunatic.c
|
||||||
|
G_.gameactor = gameactor -- included in lunatic.c
|
||||||
|
|
||||||
|
|
||||||
---=== Lunatic interpreter setup ===---
|
---=== Lunatic interpreter setup ===---
|
||||||
|
|
|
@ -17,9 +17,13 @@
|
||||||
// the values as booleans and the addresses as keys to the Lua registry
|
// the values as booleans and the addresses as keys to the Lua registry
|
||||||
uint8_t g_elEvents[MAXEVENTS];
|
uint8_t g_elEvents[MAXEVENTS];
|
||||||
|
|
||||||
|
// same thing for actors:
|
||||||
|
uint8_t g_elActors[MAXTILES];
|
||||||
|
|
||||||
|
|
||||||
// forward-decls...
|
// forward-decls...
|
||||||
static int32_t SetEvent_luacf(lua_State *L);
|
static int32_t SetEvent_luacf(lua_State *L);
|
||||||
|
static int32_t SetActor_luacf(lua_State *L);
|
||||||
|
|
||||||
// in lpeg.o
|
// in lpeg.o
|
||||||
extern int luaopen_lpeg(lua_State *L);
|
extern int luaopen_lpeg(lua_State *L);
|
||||||
|
@ -41,12 +45,14 @@ int32_t El_CreateState(El_State *estate, const char *name)
|
||||||
return -2;
|
return -2;
|
||||||
}
|
}
|
||||||
|
|
||||||
luaL_openlibs(estate->L); // XXX: only for internal use and testing, obviously
|
luaL_openlibs(estate->L); // NOTE: we set up the sandbox in defs.ilua
|
||||||
luaopen_lpeg(estate->L);
|
luaopen_lpeg(estate->L);
|
||||||
|
|
||||||
// create misc. global functions in the Lua state
|
// create misc. global functions in the Lua state
|
||||||
lua_pushcfunction(estate->L, SetEvent_luacf);
|
lua_pushcfunction(estate->L, SetEvent_luacf);
|
||||||
lua_setglobal(estate->L, "setevent");
|
lua_setglobal(estate->L, "gameevent");
|
||||||
|
lua_pushcfunction(estate->L, SetActor_luacf);
|
||||||
|
lua_setglobal(estate->L, "gameactor");
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -74,6 +80,8 @@ int32_t El_RunOnce(El_State *estate, const char *fn)
|
||||||
int32_t fid, flen, i;
|
int32_t fid, flen, i;
|
||||||
char *buf;
|
char *buf;
|
||||||
|
|
||||||
|
lua_State *const L = estate->L;
|
||||||
|
|
||||||
fid = kopen4load(fn, 0);
|
fid = kopen4load(fn, 0);
|
||||||
|
|
||||||
if (fid < 0)
|
if (fid < 0)
|
||||||
|
@ -103,7 +111,7 @@ int32_t El_RunOnce(El_State *estate, const char *fn)
|
||||||
|
|
||||||
// -- lua --
|
// -- lua --
|
||||||
|
|
||||||
i = luaL_loadstring(estate->L, buf);
|
i = luaL_loadstring(L, buf);
|
||||||
Bfree(buf);
|
Bfree(buf);
|
||||||
|
|
||||||
if (i == LUA_ERRMEM)
|
if (i == LUA_ERRMEM)
|
||||||
|
@ -111,55 +119,76 @@ int32_t El_RunOnce(El_State *estate, const char *fn)
|
||||||
|
|
||||||
if (i == LUA_ERRSYNTAX)
|
if (i == LUA_ERRSYNTAX)
|
||||||
{
|
{
|
||||||
OSD_Printf("state \"%s\" syntax error: %s\n", estate->name, lua_tostring(estate->L, -1)); // get err msg
|
OSD_Printf("state \"%s\" syntax error: %s\n", estate->name,
|
||||||
lua_pop(estate->L, 1);
|
lua_tostring(L, -1)); // get err msg
|
||||||
|
lua_pop(L, 1);
|
||||||
return 3;
|
return 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
// -- call the lua chunk! --
|
// -- call the lua chunk! --
|
||||||
|
|
||||||
i = lua_pcall(estate->L, 0, 0, 0);
|
i = lua_pcall(L, 0, 0, 0);
|
||||||
if (i == LUA_ERRMEM) // XXX: should be more sophisticated. Clean up stack? Do GC?
|
if (i == LUA_ERRMEM) // XXX: should be more sophisticated. Clean up stack? Do GC?
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
if (i == LUA_ERRRUN)
|
if (i == LUA_ERRRUN)
|
||||||
{
|
{
|
||||||
Bassert(lua_type(estate->L, -1)==LUA_TSTRING);
|
Bassert(lua_type(L, -1)==LUA_TSTRING);
|
||||||
OSD_Printf("state \"%s\" runtime error: %s\n", estate->name, lua_tostring(estate->L, -1)); // get err msg
|
OSD_Printf("state \"%s\" runtime error: %s\n", estate->name,
|
||||||
lua_pop(estate->L, 1);
|
lua_tostring(L, -1)); // get err msg
|
||||||
|
lua_pop(L, 1);
|
||||||
return 4;
|
return 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// setupevent(EVENT_..., lua_function)
|
|
||||||
|
static void check_and_register_function(lua_State *L, void *keyaddr)
|
||||||
|
{
|
||||||
|
luaL_checktype(L, 2, LUA_TFUNCTION);
|
||||||
|
|
||||||
|
lua_pushlightuserdata(L, keyaddr); // 3, push address
|
||||||
|
lua_pushvalue(L, 2); // 4, push copy of lua function
|
||||||
|
|
||||||
|
lua_settable(L, LUA_REGISTRYINDEX); // "registry[keyaddr] = <lua function>"
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
////////// Lua_CFunctions //////////
|
||||||
|
|
||||||
|
// gameevent(EVENT_..., lua_function)
|
||||||
static int32_t SetEvent_luacf(lua_State *L)
|
static int32_t SetEvent_luacf(lua_State *L)
|
||||||
{
|
{
|
||||||
int32_t eventidx = luaL_checkint(L, 1);
|
int32_t eventidx = luaL_checkint(L, 1);
|
||||||
|
|
||||||
luaL_argcheck(L, (unsigned)eventidx < MAXEVENTS, 1, "must be an event number (0 .. MAXEVENTS-1)");
|
luaL_argcheck(L, (unsigned)eventidx < MAXEVENTS, 1, "must be an event number (0 .. MAXEVENTS-1)");
|
||||||
luaL_checktype(L, 2, LUA_TFUNCTION);
|
check_and_register_function(L, &g_elEvents[eventidx]);
|
||||||
|
|
||||||
lua_pushlightuserdata(L, &g_elEvents[eventidx]); // 3, push address
|
|
||||||
lua_pushvalue(L, 2); // 4, push copy of lua function
|
|
||||||
|
|
||||||
lua_settable(L, LUA_REGISTRYINDEX); // "registry[&g_elEvents[eventidx]] = <lua function>"
|
|
||||||
g_elEvents[eventidx] = 1;
|
g_elEvents[eventidx] = 1;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t El_CallEvent(El_State *estate, int32_t eventidx, int32_t iActor, int32_t iPlayer, int32_t lDist)
|
// gameactor(<actortile>, lua_function)
|
||||||
|
static int32_t SetActor_luacf(lua_State *L)
|
||||||
{
|
{
|
||||||
// XXX: estate must be the one where the events were registered...
|
int32_t actortile = luaL_checkint(L, 1);
|
||||||
// make a global?
|
|
||||||
|
|
||||||
|
luaL_argcheck(L, (unsigned)actortile < MAXTILES, 1, "must be an tile number (0 .. MAXTILES-1)");
|
||||||
|
check_and_register_function(L, &g_elActors[actortile]);
|
||||||
|
g_elActors[actortile] = 1;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
//////////////////////////////
|
||||||
|
|
||||||
|
static int32_t call_registered_function3(lua_State *L, void *keyaddr,
|
||||||
|
int32_t iActor, int32_t iPlayer, int32_t lDist)
|
||||||
|
{
|
||||||
int32_t i;
|
int32_t i;
|
||||||
|
|
||||||
lua_State *const L = estate->L;
|
lua_pushlightuserdata(L, keyaddr); // push address
|
||||||
|
|
||||||
lua_pushlightuserdata(L, &g_elEvents[eventidx]); // push address
|
|
||||||
lua_gettable(L, LUA_REGISTRYINDEX); // get lua function
|
lua_gettable(L, LUA_REGISTRYINDEX); // get lua function
|
||||||
|
|
||||||
lua_pushinteger(L, iActor);
|
lua_pushinteger(L, iActor);
|
||||||
|
@ -169,13 +198,44 @@ int32_t El_CallEvent(El_State *estate, int32_t eventidx, int32_t iActor, int32_t
|
||||||
// -- call it! --
|
// -- call it! --
|
||||||
|
|
||||||
i = lua_pcall(L, 3, 0, 0);
|
i = lua_pcall(L, 3, 0, 0);
|
||||||
if (i == LUA_ERRMEM) // XXX: should be more sophisticated. Clean up stack? Do GC?
|
if (i == LUA_ERRMEM)
|
||||||
return -1;
|
{
|
||||||
|
// XXX: should be more sophisticated. Clean up stack? Do GC?
|
||||||
|
}
|
||||||
|
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t El_CallEvent(El_State *estate, int32_t eventidx, int32_t iActor, int32_t iPlayer, int32_t lDist)
|
||||||
|
{
|
||||||
|
// XXX: estate must be the one where the events were registered...
|
||||||
|
// make a global?
|
||||||
|
|
||||||
|
lua_State *const L = estate->L;
|
||||||
|
|
||||||
|
int32_t i = call_registered_function3(L, &g_elEvents[eventidx], iActor, iPlayer, lDist);
|
||||||
|
|
||||||
if (i == LUA_ERRRUN)
|
if (i == LUA_ERRRUN)
|
||||||
{
|
{
|
||||||
OSD_Printf("event \"%s\" (state \"%s\") runtime error: %s\n", EventNames[eventidx].text,
|
OSD_Printf("event \"%s\" (state \"%s\") runtime error: %s\n", EventNames[eventidx].text,
|
||||||
estate->name, lua_tostring(L, 1)); // get err msg
|
estate->name, lua_tostring(L, -1)); // get err msg
|
||||||
|
lua_pop(L, 1);
|
||||||
|
return 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t El_CallActor(El_State *estate, int32_t actortile, int32_t iActor, int32_t iPlayer, int32_t lDist)
|
||||||
|
{
|
||||||
|
lua_State *const L = estate->L;
|
||||||
|
|
||||||
|
int32_t i = call_registered_function3(L, &g_elActors[actortile], iActor, iPlayer, lDist);
|
||||||
|
|
||||||
|
if (i == LUA_ERRRUN)
|
||||||
|
{
|
||||||
|
OSD_Printf("actor %d (sprite %d, state \"%s\") runtime error: %s\n", actortile, iActor,
|
||||||
|
estate->name, lua_tostring(L, -1)); // get err msg
|
||||||
lua_pop(L, 1);
|
lua_pop(L, 1);
|
||||||
return 4;
|
return 4;
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,13 +15,17 @@ typedef struct
|
||||||
} El_State;
|
} El_State;
|
||||||
|
|
||||||
extern uint8_t g_elEvents[MAXEVENTS]; // shouldn't be used directly
|
extern uint8_t g_elEvents[MAXEVENTS]; // shouldn't be used directly
|
||||||
|
extern uint8_t g_elActors[MAXTILES]; // shouldn't be used directly
|
||||||
|
|
||||||
// -- functions --
|
// -- functions --
|
||||||
int32_t El_CreateState(El_State *estate, const char *name);
|
int32_t El_CreateState(El_State *estate, const char *name);
|
||||||
void El_DestroyState(El_State *estate);
|
void El_DestroyState(El_State *estate);
|
||||||
static inline int32_t El_IsInitialized(const El_State *estate) { return (estate->L != NULL); }
|
|
||||||
static inline int32_t El_HaveEvent(int32_t eventidx) { return g_elEvents[eventidx]!=0; }
|
|
||||||
int32_t El_RunOnce(El_State *estate, const char *fn);
|
int32_t El_RunOnce(El_State *estate, const char *fn);
|
||||||
int32_t El_CallEvent(El_State *estate, int32_t eventidx, int32_t iActor, int32_t iPlayer, int32_t lDist);
|
int32_t El_CallEvent(El_State *estate, int32_t eventidx, int32_t iActor, int32_t iPlayer, int32_t lDist);
|
||||||
|
int32_t El_CallActor(El_State *estate, int32_t actortile, int32_t iActor, int32_t iPlayer, int32_t lDist);
|
||||||
|
|
||||||
|
static inline int32_t El_IsInitialized(const El_State *estate) { return (estate->L != NULL); }
|
||||||
|
static inline int32_t El_HaveEvent(int32_t eventidx) { return g_elEvents[eventidx]!=0; }
|
||||||
|
static inline int32_t El_HaveActor(int32_t actortile) { return g_elActors[actortile]!=0; }
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -104,16 +104,27 @@ checkfail("require('os')") -- 'require' has been thrown away to be replaced by
|
||||||
-- something more restricted later
|
-- something more restricted later
|
||||||
checkfail("new_global = 345") -- we should declare globals
|
checkfail("new_global = 345") -- we should declare globals
|
||||||
checkfail('gv.CEILING = 3') -- can't redefine constants in 'gv'
|
checkfail('gv.CEILING = 3') -- can't redefine constants in 'gv'
|
||||||
checkfail('string.dump(setevent)') -- string.dump is unavailable
|
checkfail('string.dump(gameevent)') -- string.dump is unavailable
|
||||||
|
|
||||||
-- This is problematic, even though pretty much every access will yield a
|
-- This is problematic, even though pretty much every access will yield a
|
||||||
-- "missing declaration" error.
|
-- "missing declaration" error.
|
||||||
-- See http://luajit.org/ext_ffi_api.html#ffi_C about what stuff ffi.C contains.
|
-- See http://luajit.org/ext_ffi_api.html#ffi_C about what stuff ffi.C contains.
|
||||||
checkfail('gv.luaJIT_setmode(nil, 0, 0)')
|
checkfail('gv.luaJIT_setmode(nil, 0, 0)')
|
||||||
|
|
||||||
setevent(gv.EVENT_JUMP, function(actori, playeri, dist)
|
gameevent(gv.EVENT_JUMP,
|
||||||
|
function(actori, playeri, dist)
|
||||||
printf("jump i=%d p=%d d=%d", actori, playeri, dist)
|
printf("jump i=%d p=%d d=%d", actori, playeri, dist)
|
||||||
end)
|
end
|
||||||
|
)
|
||||||
|
|
||||||
|
gameactor(1680, -- LIZTROOP
|
||||||
|
function(i, playeri, dist)
|
||||||
|
sprite[i].pal = math.random(32)
|
||||||
|
-- sprite[i].ang = bit.band(sprite[i].ang-20, 2047)
|
||||||
|
end
|
||||||
|
)
|
||||||
|
|
||||||
|
checkfail('gameactor(1680, 0)') -- lua function expected, number passed
|
||||||
|
|
||||||
|
|
||||||
print('---=== END TEST SCRIPT ===---')
|
print('---=== END TEST SCRIPT ===---')
|
||||||
|
|
Loading…
Reference in a new issue