Lunatic reorganization part 2: split into engine and editor/game parts.

On the engine side (functions starting with L_), there are now the basic
parts like state creation and running code from strings and files.
The game and editor can add to that by e.g. loading whatever they please
into the state. Their functions start with El_ and Em_, respectively.
The Lua scripts still reside in source/lunatic, even for the common ones.
This is because they will be embedded into the binaries as bytecode or
compressed source eventually, so their location on disk will be irrelevant.

git-svn-id: https://svn.eduke32.com/eduke32@3148 1a8010ca-5511-0410-912e-c29ae57300e0
This commit is contained in:
helixhorned 2012-11-10 20:59:00 +00:00
parent 550acb2b1a
commit 3bcdc5acb8
16 changed files with 321 additions and 167 deletions

View file

@ -2,15 +2,6 @@
# EDuke32 Makefile for GNU Make # EDuke32 Makefile for GNU Make
# #
# Lunatic development, do not touch!
LUNATIC=0
ifneq ($(LUNATIC),0)
# FIXME: Lunatic doesn't build with inlining because of wacky include
# chains!
override DISABLEINLINING=1
endif
include Makefile.common include Makefile.common
@ -170,28 +161,9 @@ MISCGAMEDEPS=
## Lunatic devel ## Lunatic devel
LUAJIT=luajit
# for LJ headers:
LUAJIT_WIN_SRC:= g:/mod/LuaJIT-2.0.0-beta8/src
ifneq (0,$(LUNATIC)) ifneq (0,$(LUNATIC))
ifeq ($(PLATFORM),WINDOWS)
OURCOMMONFLAGS+= -I$(LUAJIT_WIN_SRC)
else
OURCOMMONFLAGS+= -I/usr/local/include/luajit-2.0
endif
OURCOMMONFLAGS+= -I$(SRC)/lunatic -DLUNATIC
ifeq ($(PLATFORM),WINDOWS)
LIBS+= -LWindows/lib -lluajit
else
LIBS+= -lluajit-5.1
endif
EDITOROBJS+= $(OBJ)/lunatic_m32.$o EDITOROBJS+= $(OBJ)/lunatic_m32.$o
GAMEOBJS+= $(OBJ)/lunatic.$o GAMEOBJS+= $(OBJ)/lunatic_game.$o
GAMEOBJS+= $(OBJ)/../lpeg.$o # TEMP GAMEOBJS+= $(OBJ)/../lpeg.$o # TEMP
GAMEOBJS+= $(OBJ)/luaJIT_BC_con_lang.$o \ GAMEOBJS+= $(OBJ)/luaJIT_BC_con_lang.$o \
@ -219,7 +191,6 @@ ifneq (0,$(LUNATIC))
PRINTLDFLAGS+= $(SRC)/lunatic/eduke32.def PRINTLDFLAGS+= $(SRC)/lunatic/eduke32.def
endif endif
ifeq ($(PLATFORM),LINUX) ifeq ($(PLATFORM),LINUX)
# TODO: Windows, OS X
GAMELDFLAGS+= -Wl,--dynamic-list=$(SRC)/lunatic/dynsymlist GAMELDFLAGS+= -Wl,--dynamic-list=$(SRC)/lunatic/dynsymlist
EDITORLDFLAGS+= -Wl,--dynamic-list=$(SRC)/lunatic/dynsymlist_m32 EDITORLDFLAGS+= -Wl,--dynamic-list=$(SRC)/lunatic/dynsymlist_m32
endif endif

View file

@ -308,6 +308,35 @@ ifneq (0,$(CLANG))
BASECOMMONFLAGS+= -Wno-unused-value -Wno-parentheses BASECOMMONFLAGS+= -Wno-unused-value -Wno-parentheses
endif endif
#### Lunatic development, do not touch!
LUNATIC=0
LUAJIT=luajit
# for LJ headers:
LUAJIT_WIN_SRC:= g:/mod/LuaJIT-2.0.0-beta8/src
ifneq ($(LUNATIC),0)
# FIXME: Lunatic doesn't build with inlining because of wacky include
# chains!
override DISABLEINLINING=1
ifeq ($(PLATFORM),WINDOWS)
BASECOMMONFLAGS+= -I$(LUAJIT_WIN_SRC)
else
BASECOMMONFLAGS+= -I/usr/local/include/luajit-2.0
endif
BASECOMMONFLAGS+= -I$(SRC)/lunatic -DLUNATIC
ifeq ($(PLATFORM),WINDOWS)
LIBS+= -LWindows/lib -lluajit
else
LIBS+= -lluajit-5.1
endif
endif
####
ifneq (0,$(DISABLEINLINING)) ifneq (0,$(DISABLEINLINING))
BASECOMMONFLAGS+= -DDISABLE_INLINING BASECOMMONFLAGS+= -DDISABLE_INLINING
endif endif

View file

@ -58,8 +58,8 @@ $(OBJ)/osdcmds.$o: $(SRC)/osdcmds.c $(INC)/osdcmds.h $(EINC)/osd.h $(duke3d_h)
$(OBJ)/xdelta3.$o: $(SRC)/xdelta3/xdelta3.c $(SRC)/xdelta3/xdelta3.h $(OBJ)/xdelta3.$o: $(SRC)/xdelta3/xdelta3.c $(SRC)/xdelta3/xdelta3.h
$(OBJ)/animvpx.$o: $(SRC)/animvpx.c $(SRC)/animvpx.h $(duke3d_h) $(EINC)/glbuild.h $(OBJ)/animvpx.$o: $(SRC)/animvpx.c $(SRC)/animvpx.h $(duke3d_h) $(EINC)/glbuild.h
$(OBJ)/lunatic.$o: $(SRC)/lunatic/lunatic.c $(SRC)/lunatic/lunatic.h $(SRC)/lunatic/lunatic_priv.h $(EINC)/cache1d.h $(EINC)/osd.h $(OBJ)/lunatic_game.$o: $(EINC)/lunatic.h $(SRC)/lunatic/lunatic_game.c $(SRC)/lunatic/lunatic_game.h $(SRC)/gamedef.h $(SRC)/gameexec.h $(EINC)/cache1d.h $(EINC)/osd.h
$(OBJ)/lunatic_m32.$o: $(SRC)/lunatic/lunatic_m32.c $(SRC)/lunatic/lunatic_m32.h $(SRC)/lunatic/lunatic_priv.h $(EINC)/cache1d.h $(EINC)/osd.h $(OBJ)/lunatic_m32.$o: $(EINC)/lunatic.h $(SRC)/lunatic/lunatic_m32.c $(SRC)/lunatic/lunatic_m32.h $(EINC)/cache1d.h $(EINC)/osd.h
# editor objects # editor objects
m32_script_hs=$(EINC)/m32script.h $(SRC)/m32def.h m32_script_hs=$(EINC)/m32script.h $(SRC)/m32def.h

View file

@ -100,6 +100,10 @@ ifeq (1,$(POLYMER))
ENGINEOBJS+= $(OBJ)/polymer.$o ENGINEOBJS+= $(OBJ)/polymer.$o
endif endif
ifeq (1,$(LUNATIC))
ENGINEOBJS+= $(OBJ)/lunatic.$o
endif
EDITOROBJS=$(OBJ)/build.$o \ EDITOROBJS=$(OBJ)/build.$o \
$(OBJ)/config.$o $(OBJ)/config.$o

View file

@ -31,6 +31,8 @@ $(OBJ)/polymer.$o: $(SRC)/polymer.c $(INC)/polymer.h $(INC)/compat.h $(INC)/buil
$(OBJ)/mutex.$o: $(SRC)/mutex.c $(INC)/mutex.h $(OBJ)/mutex.$o: $(SRC)/mutex.c $(INC)/mutex.h
$(OBJ)/rawinput.$o: $(SRC)/rawinput.c $(INC)/rawinput.h $(OBJ)/rawinput.$o: $(SRC)/rawinput.c $(INC)/rawinput.h
$(OBJ)/lunatic.$o: $(SRC)/lunatic.c $(INC)/lunatic.h $(INC)/cache1d.h $(INC)/osd.h
$(OBJ)/buildres.$(res): $(SRC)/misc/buildres.rc $(INC)/startwin.editor.h $(OBJ)/buildres.$(res): $(SRC)/misc/buildres.rc $(INC)/startwin.editor.h
$(OBJ)/startwin.editor.$o: $(SRC)/startwin.editor.c $(INC)/build.h $(INC)/editor.h $(INC)/winlayer.h $(INC)/compat.h $(INC)/startwin.editor.h $(OBJ)/startwin.editor.$o: $(SRC)/startwin.editor.c $(INC)/build.h $(INC)/editor.h $(INC)/winlayer.h $(INC)/compat.h $(INC)/startwin.editor.h
$(OBJ)/startgtk.editor.$o: $(SRC)/startgtk.editor.c $(INC)/baselayer.h $(INC)/build.h $(INC)/editor.h $(INC)/compat.h $(OBJ)/startgtk.editor.$o: $(SRC)/startgtk.editor.c $(INC)/baselayer.h $(INC)/build.h $(INC)/editor.h $(INC)/compat.h

View file

@ -0,0 +1,29 @@
/* The Lunatic Interpreter, part of EDuke32. Common, engine-side stuff. */
#ifndef ENGINE_LUNATIC_H_
#define ENGINE_LUNATIC_H_
#include <lua.h>
typedef struct
{
char *name;
lua_State *L;
} L_State;
// -- functions --
// helpers taking the lua_State directly:
void L_SetupDebugTraceback(lua_State *L);
void L_CheckAndRegisterFunction(lua_State *L, void *regkeyaddr);
int L_CreateState(L_State *estate, const char *name, void (*StateSetupFunc)(lua_State *));
void L_DestroyState(L_State *estate);
int L_RunOnce(L_State *estate, const char *fn);
int L_RunString(L_State *estate, char *buf, int dofreebuf);
static inline int L_IsInitialized(const L_State *estate) { return (estate->L != NULL); }
#endif

View file

@ -0,0 +1,192 @@
/* The Lunatic Interpreter, part of EDuke32. Common, engine-side stuff. */
#include <lua.h>
#include <lualib.h>
#include <lauxlib.h>
#include "cache1d.h"
#include "osd.h"
#include "lunatic.h"
////////// HELPER FUNCTIONS //////////
// Lua-registry key for debug.traceback
static uint8_t debug_traceback_key;
void L_CheckAndRegisterFunction(lua_State *L, void *regkeyaddr)
{
luaL_checktype(L, -1, LUA_TFUNCTION);
lua_pushlightuserdata(L, regkeyaddr); // 3, push address
lua_pushvalue(L, -2); // 4, push copy of lua function
lua_settable(L, LUA_REGISTRYINDEX); // "registry[regkeyaddr] = <lua function>", pop 2
}
void L_SetupDebugTraceback(lua_State *L)
{
// get debug.traceback
lua_getglobal(L, "debug");
lua_getfield(L, -1, "traceback");
Bassert(lua_isfunction(L, -1));
L_CheckAndRegisterFunction(L, &debug_traceback_key);
lua_pop(L, 2);
}
static int32_t read_whole_file(const char *fn, char **retbufptr)
{
int32_t fid, flen, i;
char *buf;
*retbufptr = NULL;
fid = kopen4load(fn, 0); // TODO: g_loadFromGroupOnly, kopen4loadfrommod ?
if (fid < 0)
return 1;
flen = kfilelength(fid);
if (flen == 0)
return 5;
buf = Bmalloc(flen+1);
if (!buf)
{
kclose(fid);
return -1;
}
i = kread(fid, buf, flen);
kclose(fid);
if (i != flen)
{
Bfree(buf);
return 2;
}
buf[flen] = 0;
*retbufptr = buf;
return 0;
}
////////// EXTERNAL FUNCTIONS //////////
// 0: success, <0: failure
int L_CreateState(L_State *estate, const char *name, void (*StateSetupFunc)(lua_State *))
{
lua_State *L;
estate->name = Bstrdup(name);
if (!estate->name)
return -1;
L = estate->L = luaL_newstate();
if (!estate->L)
{
Bfree(estate->name);
estate->name = NULL;
return -2;
}
StateSetupFunc(L);
return 0;
}
void L_DestroyState(L_State *estate)
{
if (!estate->L)
return;
Bfree(estate->name);
estate->name = NULL;
lua_close(estate->L);
estate->L = NULL;
}
int L_RunString(L_State *estate, char *buf, int dofreebuf)
{
int32_t i;
lua_State *L = estate->L;
// -- lua --
Bassert(lua_gettop(L)==0);
// get debug.traceback
lua_pushlightuserdata(L, &debug_traceback_key);
lua_gettable(L, LUA_REGISTRYINDEX);
Bassert(lua_isfunction(L, -1));
i = luaL_loadstring(L, buf);
Bassert(lua_gettop(L)==2);
if (dofreebuf)
Bfree(buf);
if (i == LUA_ERRMEM)
{
lua_pop(L, 2);
return -1;
}
if (i == LUA_ERRSYNTAX)
{
OSD_Printf("state \"%s\" syntax error: %s\n", estate->name,
lua_tostring(L, -1)); // get err msg
lua_pop(L, 2); // pop errmsg and debug.traceback
return 3;
}
// -- call the lua chunk! --
i = lua_pcall(L, 0, 0, -2);
Bassert(lua_gettop(L) == 1+!!i);
Bassert(i != LUA_ERRERR); // we expect debug.traceback not to fail
if (i == LUA_ERRMEM) // XXX: should be more sophisticated. Clean up stack? Do GC?
{
lua_pop(L, 2);
return -1;
}
if (i == LUA_ERRRUN)
{
int32_t stringp = (lua_type(L, -1)==LUA_TSTRING);
// get error message if possible
OSD_Printf("state \"%s\" runtime error: %s\n", estate->name,
stringp ? lua_tostring(L, -1) : "??? (errmsg not a string)");
lua_pop(L, 2); // pop errmsg and debug.traceback
return 4;
}
lua_pop(L, 1);
return 0;
}
// -1: alloc failure
// 0: success
// 1: didn't find file
// 2: couldn't read whole file
// 3: syntax error in lua file
// 4: runtime error while executing lua file
// 5: empty file
int L_RunOnce(L_State *estate, const char *fn)
{
char *buf;
int32_t i = read_whole_file(fn, &buf);
if (i != 0)
return i;
return L_RunString(estate, buf, 1);
}

View file

@ -100,7 +100,7 @@ int32_t g_clipMapFilesNum = 0;
#endif #endif
#ifdef LUNATIC #ifdef LUNATIC
Em_State *g_EmState; static L_State g_EmState;
#endif #endif
#pragma pack(push,1) #pragma pack(push,1)
@ -9294,13 +9294,13 @@ static int32_t osdcmd_lua(const osdfuncparm_t *parm)
if (parm->numparms != 1) if (parm->numparms != 1)
return OSDCMD_SHOWHELP; return OSDCMD_SHOWHELP;
if (g_EmState == NULL) if (!L_IsInitialized(&g_EmState))
{ {
OSD_Printf("Lua state is not initialized.\n"); OSD_Printf("Lua state is not initialized.\n");
return OSDCMD_OK; return OSDCMD_OK;
} }
ret = Em_RunStringOnce(g_EmState, parm->parms[0]); ret = L_RunString(&g_EmState, (char *)parm->parms[0], 0);
if (ret != 0) if (ret != 0)
OSD_Printf("Error running the Lua code (error code %d)\n", ret); OSD_Printf("Error running the Lua code (error code %d)\n", ret);
else else
@ -10608,16 +10608,13 @@ int32_t ExtInit(void)
MultiPskyInit(); MultiPskyInit();
#ifdef LUNATIC #ifdef LUNATIC
g_EmState = Em_CreateState(); if (Em_CreateState(&g_EmState) == 0)
if (g_EmState)
{ {
i = Em_RunOnce(g_EmState, "defs_m32.ilua"); i = L_RunOnce(&g_EmState, "defs_m32.ilua");
if (i) if (i != 0)
{ {
initprintf("Lunatic: Error preparing global Lua state (code %d)\n", i); initprintf("Lunatic: Error preparing global Lua state (code %d)\n", i);
Em_DestroyState(g_EmState); Em_DestroyState(&g_EmState);
g_EmState = NULL;
} }
} }
#endif #endif

View file

@ -63,7 +63,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include "input.h" #include "input.h"
#ifdef LUNATIC #ifdef LUNATIC
# include "lunatic.h" # include "lunatic_game.h"
#endif #endif
#if KRANDDEBUG #if KRANDDEBUG
@ -139,10 +139,6 @@ char **g_clipMapFiles = NULL;
int32_t g_clipMapFilesNum = 0; int32_t g_clipMapFilesNum = 0;
#endif #endif
#ifdef LUNATIC
El_State g_ElState;
#endif
extern int32_t lastvisinc; extern int32_t lastvisinc;
int32_t g_Shareware = 0; int32_t g_Shareware = 0;
@ -10449,7 +10445,7 @@ int32_t app_main(int32_t argc, const char **argv)
} }
else else
{ {
i = El_RunOnce(&g_ElState, "defs.ilua"); i = L_RunOnce(&g_ElState, "defs.ilua");
if (i) if (i)
{ {
initprintf("Lunatic: Error preparing global ELua state (code %d)\n", i); initprintf("Lunatic: Error preparing global ELua state (code %d)\n", i);

View file

@ -23,6 +23,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#ifndef _gamedef_h_ #ifndef _gamedef_h_
#define _gamedef_h_ #define _gamedef_h_
#include "build.h" // hashtable_t
#include "common.h" // tokenlist #include "common.h" // tokenlist
#define MAXGAMEEVENTS 128 #define MAXGAMEEVENTS 128

View file

@ -35,8 +35,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include "menus.h" #include "menus.h"
#ifdef LUNATIC #ifdef LUNATIC
# include "lunatic.h" # include "lunatic_game.h"
extern El_State g_ElState; // this needs to go into a header sometime
#endif #endif
#if KRANDDEBUG #if KRANDDEBUG
@ -99,7 +98,7 @@ int32_t VM_OnEvent(int32_t iEventID, int32_t iActor, int32_t iPlayer, int32_t lD
#ifdef LUNATIC #ifdef LUNATIC
const double t = gethitickms(); const double t = gethitickms();
if (El_IsInitialized(&g_ElState) && El_HaveEvent(iEventID)) if (L_IsInitialized(&g_ElState) && El_HaveEvent(iEventID))
El_CallEvent(&g_ElState, iEventID, iActor, iPlayer, lDist); El_CallEvent(&g_ElState, iEventID, iActor, iPlayer, lDist);
#endif #endif
if (apScriptGameEvent[iEventID]) if (apScriptGameEvent[iEventID])
@ -5156,7 +5155,7 @@ void A_Execute(int32_t iActor,int32_t iPlayer,int32_t lDist)
#ifdef LUNATIC #ifdef LUNATIC
t = gethitickms(); t = gethitickms();
if (El_IsInitialized(&g_ElState) && El_HaveActor(vm.g_sp->picnum)) if (L_IsInitialized(&g_ElState) && El_HaveActor(vm.g_sp->picnum))
El_CallActor(&g_ElState, vm.g_sp->picnum, iActor, iPlayer, lDist); El_CallActor(&g_ElState, vm.g_sp->picnum, iActor, iPlayer, lDist);
#endif #endif

View file

@ -1,19 +1,18 @@
/* The Lunatic Interpreter, part of EDuke32 */ /* The Lunatic Interpreter, part of EDuke32. Game-side stuff. */
#include <stdint.h> #include <stdint.h>
#include <lua.h>
#include <lualib.h> #include <lualib.h>
#include <lauxlib.h> #include <lauxlib.h>
#include "cache1d.h" #include "lunatic_game.h"
#include "osd.h" #include "osd.h"
#include "gamedef.h" // EventNames[]
#include "gameexec.h"
#include "gamedef.h" // EventNames[], MAXEVENTS
#include "lunatic.h" L_State g_ElState;
#include "lunatic_priv.h"
// this serves two purposes: // this serves two purposes:
// 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
@ -22,9 +21,6 @@ uint8_t g_elEvents[MAXEVENTS];
// same thing for actors: // same thing for actors:
uint8_t g_elActors[MAXTILES]; uint8_t g_elActors[MAXTILES];
// Lua-registry key for debug.traceback
static uint8_t debug_traceback_key;
// for timing events and actors // for timing events and actors
uint32_t g_eventCalls[MAXEVENTS], g_actorCalls[MAXTILES]; uint32_t g_eventCalls[MAXEVENTS], g_actorCalls[MAXTILES];
double g_eventTotalMs[MAXEVENTS], g_actorTotalMs[MAXTILES]; double g_eventTotalMs[MAXEVENTS], g_actorTotalMs[MAXTILES];
@ -89,29 +85,15 @@ void El_PrintTimes(void)
} }
// 0: success, <0: failure ////////// STATE CREATION/DESTRUCTIION //////////
int32_t El_CreateState(El_State *estate, const char *name)
static void El_StateSetup(lua_State *L)
{ {
lua_State *L;
estate->name = Bstrdup(name);
if (!estate->name)
return -1;
L = estate->L = luaL_newstate();
if (!estate->L)
{
Bfree(estate->name);
estate->name = NULL;
return -2;
}
luaL_openlibs(L); // NOTE: we set up the sandbox in defs.ilua luaL_openlibs(L); // NOTE: we set up the sandbox in defs.ilua
luaopen_lpeg(L); luaopen_lpeg(L);
lua_pop(L, lua_gettop(L)); // pop off whatever lpeg leaves on the stack lua_pop(L, lua_gettop(L)); // pop off whatever lpeg leaves on the stack
setup_debug_traceback(L); L_SetupDebugTraceback(L);
// create misc. global functions in the Lua state // create misc. global functions in the Lua state
lua_pushcfunction(L, SetEvent_luacf); lua_pushcfunction(L, SetEvent_luacf);
@ -120,32 +102,17 @@ int32_t El_CreateState(El_State *estate, const char *name)
lua_setglobal(L, "gameactor"); lua_setglobal(L, "gameactor");
Bassert(lua_gettop(L)==0); Bassert(lua_gettop(L)==0);
return 0;
} }
void El_DestroyState(El_State *estate) // 0: success, <0: failure
int32_t El_CreateState(L_State *estate, const char *name)
{ {
if (!estate->L) return L_CreateState(estate, name, &El_StateSetup);
return;
Bfree(estate->name);
estate->name = NULL;
lua_close(estate->L);
estate->L = NULL;
} }
// -1: alloc failure void El_DestroyState(L_State *estate)
// 0: success
// 1: didn't find file
// 2: couldn't read whole file
// 3: syntax error in lua file
// 4: runtime error while executing lua file
// 5: empty file
int32_t El_RunOnce(El_State *estate, const char *fn)
{ {
return lunatic_run_once(estate->L, fn, estate->name); L_DestroyState(estate);
} }
@ -162,7 +129,7 @@ static int32_t SetEvent_luacf(lua_State *L)
eventidx = luaL_checkint(L, 1); 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)");
check_and_register_function(L, &g_elEvents[eventidx]); L_CheckAndRegisterFunction(L, &g_elEvents[eventidx]);
g_elEvents[eventidx] = 1; g_elEvents[eventidx] = 1;
return 0; return 0;
@ -179,7 +146,7 @@ static int32_t SetActor_luacf(lua_State *L)
actortile = luaL_checkint(L, 1); actortile = luaL_checkint(L, 1);
luaL_argcheck(L, (unsigned)actortile < MAXTILES, 1, "must be an tile number (0 .. MAXTILES-1)"); luaL_argcheck(L, (unsigned)actortile < MAXTILES, 1, "must be an tile number (0 .. MAXTILES-1)");
check_and_register_function(L, &g_elActors[actortile]); L_CheckAndRegisterFunction(L, &g_elActors[actortile]);
g_elActors[actortile] = 1; g_elActors[actortile] = 1;
return 0; return 0;
@ -187,8 +154,8 @@ static int32_t SetActor_luacf(lua_State *L)
////////////////////////////// //////////////////////////////
static int32_t call_registered_function3(lua_State *L, void *keyaddr, static int32_t call_regd_function3(lua_State *L, void *keyaddr,
int32_t iActor, int32_t iPlayer, int32_t lDist) int32_t iActor, int32_t iPlayer, int32_t lDist)
{ {
int32_t i; int32_t i;
@ -212,14 +179,14 @@ static int32_t call_registered_function3(lua_State *L, void *keyaddr,
return i; return i;
} }
int32_t El_CallEvent(El_State *estate, int32_t eventidx, int32_t iActor, int32_t iPlayer, int32_t lDist) int32_t El_CallEvent(L_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... // XXX: estate must be the one where the events were registered...
// make a global? // make a global?
lua_State *const L = estate->L; lua_State *const L = estate->L;
int32_t i = call_registered_function3(L, &g_elEvents[eventidx], iActor, iPlayer, lDist); int32_t i = call_regd_function3(L, &g_elEvents[eventidx], iActor, iPlayer, lDist);
if (i == LUA_ERRRUN) if (i == LUA_ERRRUN)
{ {
@ -232,11 +199,11 @@ int32_t El_CallEvent(El_State *estate, int32_t eventidx, int32_t iActor, int32_t
return 0; return 0;
} }
int32_t El_CallActor(El_State *estate, int32_t actortile, int32_t iActor, int32_t iPlayer, int32_t lDist) int32_t El_CallActor(L_State *estate, int32_t actortile, int32_t iActor, int32_t iPlayer, int32_t lDist)
{ {
lua_State *const L = estate->L; lua_State *const L = estate->L;
int32_t i = call_registered_function3(L, &g_elActors[actortile], iActor, iPlayer, lDist); int32_t i = call_regd_function3(L, &g_elActors[actortile], iActor, iPlayer, lDist);
if (i == LUA_ERRRUN) if (i == LUA_ERRRUN)
{ {

View file

@ -1,18 +1,14 @@
/* The Lunatic Interpreter, part of EDuke32 */ /* The Lunatic Interpreter, part of EDuke32. Game-side stuff. */
#ifndef EDUKE32_LUNATIC_H_ #ifndef EDUKE32_LUNATIC_H_
#define EDUKE32_LUNATIC_H_ #define EDUKE32_LUNATIC_H_
#include <lua.h> #include "lunatic.h"
#include "gameexec.h" // MAXEVENTS
#include "gamedef.h" // EventNames[], MAXEVENTS
typedef struct extern L_State g_ElState;
{
char *name;
lua_State *L;
} 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 extern uint8_t g_elActors[MAXTILES]; // shouldn't be used directly
@ -23,13 +19,12 @@ extern double g_eventTotalMs[MAXEVENTS], g_actorTotalMs[MAXTILES];
// -- functions -- // -- functions --
void El_PrintTimes(void); void El_PrintTimes(void);
int32_t El_CreateState(El_State *estate, const char *name); int32_t El_CreateState(L_State *estate, const char *name);
void El_DestroyState(El_State *estate); void El_DestroyState(L_State *estate);
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(L_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); int32_t El_CallActor(L_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_HaveEvent(int32_t eventidx) { return g_elEvents[eventidx]!=0; }
static inline int32_t El_HaveActor(int32_t actortile) { return g_elActors[actortile]!=0; } static inline int32_t El_HaveActor(int32_t actortile) { return g_elActors[actortile]!=0; }

View file

@ -1,41 +1,23 @@
/* The Lunatic Interpreter, part of EDuke32/Mapster32 */ /* The Lunatic Interpreter, part of EDuke32. Editor stuff. */
#include <stdint.h>
#include <lua.h>
#include <lualib.h> #include <lualib.h>
#include <lauxlib.h>
#include "lunatic_m32.h" #include "lunatic_m32.h"
#include "lunatic_priv.h"
Em_State *Em_CreateState(void) static void Em_StateSetup(lua_State *L)
{ {
lua_State *L = luaL_newstate();
if (L == NULL)
return NULL;
luaL_openlibs(L); luaL_openlibs(L);
setup_debug_traceback(L); L_SetupDebugTraceback(L);
return L;
} }
// -1: alloc failure
// 0: success int Em_CreateState(L_State *estate)
// 1: didn't find file
// 2: couldn't read whole file
// 3: syntax error in lua file
// 4: runtime error while executing lua file
// 5: empty file
int32_t Em_RunOnce(Em_State *L, const char *fn)
{ {
return lunatic_run_once(L, fn, "file"); return L_CreateState(estate, "m32", &Em_StateSetup);
} }
int32_t Em_RunStringOnce(Em_State *L, const char *str) void Em_DestroyState(L_State *estate)
{ {
return lunatic_run_string(L, (char *)str, 0, "string"); L_DestroyState(estate);
} }

View file

@ -1,20 +1,11 @@
/* The Lunatic Interpreter, part of EDuke32. Editor stuff. */
#ifndef EDUKE32_LUNATIC_M32_H_ #ifndef EDUKE32_LUNATIC_M32_H_
#define EDUKE32_LUNATIC_M32_H_ #define EDUKE32_LUNATIC_M32_H_
#include <lua.h> #include "lunatic.h"
int Em_CreateState(L_State *estate);
typedef lua_State Em_State; void Em_DestroyState(L_State *estate);
Em_State *Em_CreateState(void);
static inline void Em_DestroyState(Em_State *L)
{
lua_close(L);
}
int32_t Em_RunOnce(Em_State *L, const char *fn);
int32_t Em_RunStringOnce(Em_State *L, const char *str);
#endif #endif

View file

@ -37,8 +37,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#endif #endif
#ifdef LUNATIC #ifdef LUNATIC
# include "lunatic.h" # include "lunatic_game.h"
extern El_State g_ElState;
#endif #endif
static int32_t g_whichPalForPlayer = 9; static int32_t g_whichPalForPlayer = 9;
@ -1419,9 +1418,9 @@ static inline void prelevel(char g)
} }
#ifdef LUNATIC #ifdef LUNATIC
if (El_IsInitialized(&g_ElState)) if (L_IsInitialized(&g_ElState))
{ {
i = El_RunOnce(&g_ElState, "test.elua"); i = L_RunOnce(&g_ElState, "test.elua");
if (i) if (i)
OSD_Printf("Error running the test ELua script (code %d)\n", i); OSD_Printf("Error running the test ELua script (code %d)\n", i);
else else