mirror of
https://github.com/UberGames/RPG-X2.git
synced 2025-02-08 15:51:49 +00:00
Merge branch 'master' of git://github.com/UberGames/RPG-X2.git
This commit is contained in:
commit
0d3b6ad490
8 changed files with 467 additions and 1 deletions
|
@ -56,6 +56,7 @@ OBJ = \
|
|||
cg_drawtools.o \
|
||||
cg_draw.o \
|
||||
cg_consolecmds.o \
|
||||
cg_lua.o \
|
||||
lua_vector.o \
|
||||
lua_qmath.o \
|
||||
|
||||
|
@ -136,6 +137,7 @@ cg_servercmds.o : cg_servercmds.c; $(DO_CC)
|
|||
cg_snapshot.o : cg_snapshot.c; $(DO_CC)
|
||||
cg_view.o : cg_view.c; $(DO_CC)
|
||||
cg_weapons.o : cg_weapons.c; $(DO_CC)
|
||||
cg_lua.o : cg_lua.c; $(DO_CC)
|
||||
fx_compression.o : fx_compression.c; $(DO_CC)
|
||||
fx_grenade.o : fx_grenade.c; $(DO_CC)
|
||||
fx_item.o : fx_item.c; $(DO_CC)
|
||||
|
|
|
@ -1821,6 +1821,12 @@ extern vmCvar_t rpg_forceFieldSet;
|
|||
// grp cvars
|
||||
extern vmCvar_t grp_berp;
|
||||
|
||||
// lua
|
||||
#ifdef CG_LUA
|
||||
extern vmCvar_t cg_debugLua;
|
||||
extern vmCvar_t cg_logLua;
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
368
cgame/cg_lua.c
Normal file
368
cgame/cg_lua.c
Normal file
|
@ -0,0 +1,368 @@
|
|||
// g_lua.c
|
||||
|
||||
#include "cg_lua.h"
|
||||
|
||||
#ifdef G_LUA
|
||||
|
||||
lvm_t *lVM[NUM_VMS];
|
||||
fileHandle_t lualog;
|
||||
|
||||
void QDECL LUA_DEBUG(const char *fmt, ...)
|
||||
{
|
||||
va_list argptr;
|
||||
char text[1024];
|
||||
|
||||
if(cg_debugLua.integer >= 1)
|
||||
{
|
||||
va_start(argptr, fmt);
|
||||
Com_sprintf(text, sizeof(text), fmt, argptr);
|
||||
va_end(argptr);
|
||||
CG_Printf(S_COLOR_YELLOW "LUA DEBUG:" S_COLOR_WHITE " %s\n", text);
|
||||
}
|
||||
}
|
||||
|
||||
void QDECL LUA_LOG(const char *fmt, ...)
|
||||
{
|
||||
va_list argptr;
|
||||
char buff[1024], string[1024];
|
||||
int min, tens, sec;
|
||||
|
||||
va_start(argptr, fmt);
|
||||
Com_sprintf(buff, sizeof(buff), fmt, argptr);
|
||||
va_end(argptr);
|
||||
|
||||
if(cg_logLua.integer) {
|
||||
sec = cg.time / 1000;
|
||||
min = sec / 60;
|
||||
sec -= min * 60;
|
||||
tens = sec / 10;
|
||||
sec -= tens * 10;
|
||||
|
||||
Com_sprintf(string, sizeof(string), "%i:%i%i %s", min, tens, sec, buff);
|
||||
|
||||
trap_FS_Write(string, strlen(string), lualog);
|
||||
}
|
||||
}
|
||||
|
||||
qboolean LoadLuaFile(char *path, int num_vm)
|
||||
{
|
||||
int flen = 0;
|
||||
char *code;
|
||||
fileHandle_t f;
|
||||
lvm_t *vm;
|
||||
|
||||
flen = trap_FS_FOpenFile(path, &f, FS_READ);
|
||||
if(flen < 0)
|
||||
{
|
||||
LUA_LOG("Lua: can not open file %s\n", path);
|
||||
CG_Printf(S_COLOR_YELLOW "Lua: can not open file %s\n", path);
|
||||
trap_FS_FCloseFile(f);
|
||||
return qfalse;
|
||||
}
|
||||
else
|
||||
{
|
||||
code = (char *)malloc(flen + 1);
|
||||
if(!code) return qfalse;
|
||||
trap_FS_Read(code, flen, f);
|
||||
*(code + flen) = '\0';
|
||||
trap_FS_FCloseFile(f);
|
||||
|
||||
vm = (lvm_t *) malloc(sizeof(lvm_t));
|
||||
if(vm == NULL)
|
||||
{
|
||||
LUA_LOG("Lua: failed to allocate memory for lua VM\n");
|
||||
CG_Printf(S_COLOR_YELLOW "Lua: failed to allocate memory for lua VM\n");
|
||||
return qfalse;
|
||||
}
|
||||
memset(vm, 0, sizeof(lvm_t));
|
||||
vm->id = -1;
|
||||
Q_strncpyz(vm->filename, path, sizeof(vm->filename));
|
||||
vm->code = code;
|
||||
vm->code_size = flen;
|
||||
vm->error = 0;
|
||||
|
||||
if(CG_LuaStartVM(vm) == qfalse)
|
||||
{
|
||||
CG_LuaStopVM(vm);
|
||||
vm = NULL;
|
||||
return qfalse;
|
||||
}
|
||||
else
|
||||
{
|
||||
vm->id = num_vm;
|
||||
lVM[num_vm] = vm;
|
||||
return qtrue;
|
||||
}
|
||||
}
|
||||
//return qfalse;
|
||||
}
|
||||
|
||||
qboolean CG_LuaInit()
|
||||
{
|
||||
|
||||
CG_Printf("------- CG_LuaInit -------\n");
|
||||
|
||||
// not much to do for now
|
||||
if(cg_logLua.integer) {
|
||||
trap_FS_FOpenFile("./cg_lua.log", &lualog, FS_APPEND);
|
||||
}
|
||||
|
||||
CG_Printf("------- CG_LuaInit Finish -------\n");
|
||||
|
||||
return qtrue;
|
||||
}
|
||||
|
||||
qboolean CG_LuaResume(lvm_t *vm, lua_State *T, char *func, int nargs) {
|
||||
int res = lua_resume(T, nargs);
|
||||
|
||||
if(res == LUA_ERRRUN) {
|
||||
LUA_LOG("Lua: %s error running lua script: %s\n", func, lua_tostring(T, -1));
|
||||
CG_Printf(S_COLOR_YELLOW "Lua: %s error running lua script: %s\n", func, lua_tostring(T, -1));
|
||||
lua_pop(T, 1);
|
||||
vm->error++;
|
||||
return qfalse;
|
||||
} else if(res == LUA_ERRMEM) {
|
||||
LUA_LOG("Lua: memory allocation error #2 ( %s )\n", vm->filename);
|
||||
vm->error++;
|
||||
return qfalse;
|
||||
} else if(res == LUA_ERRERR) {
|
||||
LUA_LOG("Lua: traceback error ( %s )\n", vm->filename);
|
||||
CG_Printf(S_COLOR_YELLOW "Lua: traceback error ( %s )\n", vm->filename);
|
||||
vm->error++;
|
||||
return qfalse;
|
||||
}
|
||||
return qtrue;
|
||||
}
|
||||
|
||||
qboolean CG_LuaCall(lvm_t * vm, char *func, int nargs, int nresults)
|
||||
{
|
||||
int res = lua_pcall(vm->L, nargs, nresults, 0);
|
||||
|
||||
if(res == LUA_ERRRUN)
|
||||
{
|
||||
LUA_LOG("Lua: %s error running lua script: %s\n", func, lua_tostring(vm->L, -1));
|
||||
CG_Printf(S_COLOR_YELLOW "Lua: %s error running lua script: %s\n", func, lua_tostring(vm->L, -1));
|
||||
lua_pop(vm->L, 1);
|
||||
vm->error++;
|
||||
return qfalse;
|
||||
}
|
||||
else if(res == LUA_ERRMEM)
|
||||
{
|
||||
LUA_LOG("Lua: memory allocation error #2 ( %s )\n", vm->filename);
|
||||
vm->error++;
|
||||
return qfalse;
|
||||
}
|
||||
else if(res == LUA_ERRERR)
|
||||
{
|
||||
LUA_LOG("Lua: traceback error ( %s )\n", vm->filename);
|
||||
CG_Printf(S_COLOR_YELLOW "Lua: traceback error ( %s )\n", vm->filename);
|
||||
vm->error++;
|
||||
return qfalse;
|
||||
}
|
||||
return qtrue;
|
||||
}
|
||||
|
||||
#define SAY_ALL 0
|
||||
#define SAY_TEAM 1
|
||||
|
||||
qboolean CG_LuaGetFunctionT(lua_State *T, char *name)
|
||||
{
|
||||
if(T)
|
||||
{
|
||||
lua_getglobal(T, name);
|
||||
if(lua_isfunction(T, -1))
|
||||
{
|
||||
return qtrue;
|
||||
}
|
||||
else
|
||||
{
|
||||
lua_pop(T, 1);
|
||||
return qfalse;
|
||||
}
|
||||
}
|
||||
return qfalse;
|
||||
}
|
||||
|
||||
qboolean CG_LuaGetFunction(lvm_t * vm, char *name)
|
||||
{
|
||||
if(vm->L)
|
||||
{
|
||||
lua_getglobal(vm->L, name);
|
||||
if(lua_isfunction(vm->L, -1))
|
||||
{
|
||||
return qtrue;
|
||||
}
|
||||
else
|
||||
{
|
||||
lua_pop(vm->L, 1);
|
||||
return qfalse;
|
||||
}
|
||||
}
|
||||
return qfalse;
|
||||
}
|
||||
|
||||
qboolean CG_LuaStartVM(lvm_t * vm)
|
||||
{
|
||||
int res = 0;
|
||||
char homepath[MAX_QPATH], gamepath[MAX_QPATH];
|
||||
|
||||
vm->L = luaL_newstate();
|
||||
if(!vm->L)
|
||||
{
|
||||
LUA_LOG("Lua: Lua failed to initialise.\n");
|
||||
return qfalse;
|
||||
}
|
||||
|
||||
luaL_openlibs(vm->L);
|
||||
|
||||
trap_Cvar_VariableStringBuffer("fs_homepath", homepath, sizeof(homepath));
|
||||
trap_Cvar_VariableStringBuffer("fs_game", gamepath, sizeof(gamepath));
|
||||
|
||||
lua_getglobal(vm->L, LUA_LOADLIBNAME);
|
||||
if(lua_istable(vm->L, -1))
|
||||
{
|
||||
lua_pushstring(vm->L, va("%s%s%s%s?.lua;%s%s%s%slualib%slua%s?.lua",
|
||||
homepath, LUA_DIRSEP, gamepath, LUA_DIRSEP,
|
||||
homepath, LUA_DIRSEP, gamepath, LUA_DIRSEP, LUA_DIRSEP, LUA_DIRSEP));
|
||||
lua_setfield(vm->L, -2, "path");
|
||||
lua_pushstring(vm->L, va("%s%s%s%s?.%s;%s%s%s%slualib%sclibs%s?.%s",
|
||||
homepath, LUA_DIRSEP, gamepath, LUA_DIRSEP, EXTENSION,
|
||||
homepath, LUA_DIRSEP, gamepath, LUA_DIRSEP, LUA_DIRSEP, LUA_DIRSEP, EXTENSION));
|
||||
lua_setfield(vm->L, -2, "cpath");
|
||||
}
|
||||
lua_pop(vm->L, 1);
|
||||
|
||||
Lua_RegisterGlobal(vm->L, "LUA_PATH", va("%s%s%s%s?.lua;%s%s%s%slualib%slua%s?.lua",
|
||||
homepath, LUA_DIRSEP, gamepath, LUA_DIRSEP,
|
||||
homepath, LUA_DIRSEP, gamepath, LUA_DIRSEP, LUA_DIRSEP, LUA_DIRSEP));
|
||||
Lua_RegisterGlobal(vm->L, "LUA_CPATH", va("%s%s%s%s?.%s;%s%s%s%slualib%sclibs%s?.%s",
|
||||
homepath, LUA_DIRSEP, gamepath, LUA_DIRSEP, EXTENSION,
|
||||
homepath, LUA_DIRSEP, gamepath, LUA_DIRSEP, LUA_DIRSEP, LUA_DIRSEP, EXTENSION));
|
||||
Lua_RegisterGlobal(vm->L, "LUA_DIRSEP", LUA_DIRSEP);
|
||||
|
||||
lua_newtable(vm->L);
|
||||
Lua_RegConstInteger(vm->L, CS_PLAYERS);
|
||||
Lua_RegConstInteger(vm->L, EXEC_NOW);
|
||||
Lua_RegConstInteger(vm->L, EXEC_INSERT);
|
||||
Lua_RegConstInteger(vm->L, EXEC_APPEND);
|
||||
Lua_RegConstInteger(vm->L, FS_READ);
|
||||
Lua_RegConstInteger(vm->L, FS_WRITE);
|
||||
Lua_RegConstInteger(vm->L, FS_APPEND);
|
||||
Lua_RegConstInteger(vm->L, FS_APPEND_SYNC);
|
||||
Lua_RegConstInteger(vm->L, SAY_ALL);
|
||||
Lua_RegConstInteger(vm->L, SAY_TEAM);
|
||||
Lua_RegConstString(vm->L, HOSTARCH);
|
||||
|
||||
luaopen_base(vm->L);
|
||||
luaopen_string(vm->L);
|
||||
luaopen_coroutine(vm->L);
|
||||
Luaopen_Qmath(vm->L);
|
||||
Luaopen_Vector(vm->L);
|
||||
|
||||
res = luaL_loadbuffer(vm->L, vm->code, vm->code_size, vm->filename);
|
||||
if(res == LUA_ERRSYNTAX)
|
||||
{
|
||||
LUA_LOG("Lua: syntax error during pre-compilation: %s\n", (char *)lua_tostring(vm->L, -1));
|
||||
CG_Printf(S_COLOR_YELLOW "Lua: syntax error: %s\n", (char *)lua_tostring(vm->L, -1));
|
||||
lua_pop(vm->L, 1);
|
||||
vm->error++;
|
||||
return qfalse;
|
||||
}
|
||||
else if(res == LUA_ERRMEM)
|
||||
{
|
||||
LUA_LOG("Lua: memory allocation error #1 ( %s )\n", vm->filename);
|
||||
vm->error++;
|
||||
return qfalse;
|
||||
}
|
||||
|
||||
if(!CG_LuaCall(vm, "CG_LuaStartVM", 0, 0))
|
||||
return qfalse;
|
||||
|
||||
LUA_LOG("Lua: Loading %s\n", vm->filename);
|
||||
return qtrue;
|
||||
}
|
||||
|
||||
void CG_LuaStopVM(lvm_t * vm)
|
||||
{
|
||||
if(vm == NULL)
|
||||
return;
|
||||
if(vm->code != NULL)
|
||||
{
|
||||
free(vm->code);
|
||||
vm->code = NULL;
|
||||
}
|
||||
if(vm->id >= 0)
|
||||
{
|
||||
if(lVM[vm->id] == vm)
|
||||
lVM[vm->id] = NULL;
|
||||
if(!vm->error)
|
||||
{
|
||||
LUA_LOG("Lua: Lua module [%s] unloaded.\n", vm->filename);
|
||||
}
|
||||
}
|
||||
free(vm);
|
||||
}
|
||||
|
||||
void CG_LuaShutdown()
|
||||
{
|
||||
int i;
|
||||
lvm_t *vm;
|
||||
|
||||
for(i = 0; i < NUM_VMS; i++)
|
||||
{
|
||||
vm = lVM[i];
|
||||
if(vm)
|
||||
{
|
||||
CG_LuaStopVM(vm);
|
||||
}
|
||||
}
|
||||
|
||||
trap_FS_FCloseFile(lualog);
|
||||
}
|
||||
|
||||
void CG_LuaStatus(void)
|
||||
{
|
||||
int i, cnt = 0;
|
||||
|
||||
for(i = 0; i < NUM_VMS; i++)
|
||||
if(lVM[i])
|
||||
cnt++;
|
||||
|
||||
if(cnt == 0)
|
||||
{
|
||||
CG_Printf("Lua: no scripts loaded.\n");
|
||||
return;
|
||||
}
|
||||
else if(cnt == 1)
|
||||
{
|
||||
CG_Printf("Lua: showing lua information ( 1 module loaded )\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
CG_Printf("Lua: showing lua information ( %d modules loaded )\n", cnt);
|
||||
}
|
||||
CG_Printf("%-2s %-24s\n", "VM", "Filename");
|
||||
CG_Printf("-- ------------------------\n");
|
||||
for(i = 0; i < NUM_VMS; i++)
|
||||
{
|
||||
if(lVM[i])
|
||||
{
|
||||
CG_Printf("%2d %-24s\n", lVM[i]->id, lVM[i]->filename);
|
||||
}
|
||||
}
|
||||
CG_Printf("-- ------------------------\n");
|
||||
|
||||
}
|
||||
|
||||
lvm_t *CG_LuaGetVM(lua_State * L)
|
||||
{
|
||||
int i;
|
||||
|
||||
for(i = 0; i < NUM_VMS; i++)
|
||||
if(lVM[i] && lVM[i]->L == L)
|
||||
return lVM[i];
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
#endif
|
69
cgame/cg_lua.h
Normal file
69
cgame/cg_lua.h
Normal file
|
@ -0,0 +1,69 @@
|
|||
#ifndef _G_LUA_H
|
||||
#define _G_LUA_H
|
||||
|
||||
#include "cg_local.h"
|
||||
|
||||
#if (defined __linux__ || defined __WIN32__) // linux or mingw
|
||||
#include "../game/lua.h"
|
||||
#include "../game/lauxlib.h"
|
||||
#include "../game/lualib.h"
|
||||
#else
|
||||
#include "../game/lua.h"
|
||||
#include "../game/lauxlib.h"
|
||||
#include "../game/lualib.h"
|
||||
#endif
|
||||
|
||||
#define NUM_VMS 1
|
||||
|
||||
#if defined __linux__
|
||||
#define HOSTARCH "UNIX"
|
||||
#define EXTENSION "so"
|
||||
#elif defined WIN32
|
||||
#define HOSTARCH "WIN32"
|
||||
#define EXTENSION "dll"
|
||||
#elif defined __APPLE__
|
||||
#define HOSTARCH "UNIX"
|
||||
#define EXTENSION "dylib"
|
||||
#endif
|
||||
|
||||
#define Lua_RegisterGlobal(L, n, v) (lua_pushstring(L, v), lua_setglobal(L, n))
|
||||
#define Lua_RegConstInteger(L, n) (lua_pushstring(L, #n), lua_pushinteger(L, n), lua_settable(L, -3))
|
||||
#define Lua_RegConstString(L, n) (lua_pushstring(L, #n), lua_pushstring(L, n), lua_settable(L, -3))
|
||||
|
||||
typedef struct {
|
||||
int id;
|
||||
char filename[MAX_QPATH];
|
||||
char *code;
|
||||
int code_size;
|
||||
int error;
|
||||
lua_State *L;
|
||||
} lvm_t;
|
||||
|
||||
extern lvm_t *lVM[NUM_VMS];
|
||||
|
||||
void QDECL LUA_DEBUG(const char *fmt, ...);
|
||||
void QDECL LUA_LOG(const char *fmt, ...);
|
||||
qboolean CG_LuaInit(void);
|
||||
qboolean CG_LuaCall(lvm_t *vm, char *func, int nargs, int nresults);
|
||||
qboolean CG_LuaResume(lvm_t *vm, lua_State *T, char *func, int nargs);
|
||||
qboolean CG_LuaGetFunction(lvm_t *vm, char *name);
|
||||
qboolean CG_LuaGetFunctionT(lua_State *T, char *name);
|
||||
qboolean CG_LuaStartVM(lvm_t *vm);
|
||||
void CG_LuaStopVM(lvm_t *vm);
|
||||
void CG_LuaShutdown(void);
|
||||
void CG_LuaStatus(void);
|
||||
lvm_t *CG_LuaGetVM(lua_State *L);
|
||||
|
||||
// lua_cgame.c
|
||||
int Luaopen_CGame(lua_State *L);
|
||||
|
||||
// lua_qmath.c
|
||||
int Luaopen_Qmath(lua_State *L);
|
||||
|
||||
// lua_vector.c
|
||||
int Luaopen_Vector(lua_State *L);
|
||||
void Lua_PushVector(lua_State *L, vec3_t v);
|
||||
vec_t *Lua_GetVector(lua_State *L, int argNum);
|
||||
int Lua_IsVector(lua_State *L, int index);
|
||||
vec3_t *Lua_GetVectorMisc(lua_State *L, int *index);
|
||||
#endif
|
|
@ -195,6 +195,12 @@ vmCvar_t rpg_forceFieldSet;
|
|||
// grp cvars
|
||||
vmCvar_t grp_berp;
|
||||
|
||||
// lua
|
||||
#ifdef CG_LUA
|
||||
vmCvar_t cg_debugLua;
|
||||
vmCvar_t cg_logLua;
|
||||
#endif
|
||||
|
||||
|
||||
//RPG-X | Phenix | 05/02/2006
|
||||
//Ban System (and it's backup cvars)
|
||||
|
@ -342,7 +348,14 @@ static cvarTable_t cvarTable[] = {
|
|||
//{ &cg_playerID, "cg_playerID", "0", CVAR_ARCHIVE | CVAR_ROM | CVAR_NORESTART }
|
||||
|
||||
// grp cvars
|
||||
{ &grp_berp, "grp_berp", "0", CVAR_ARCHIVE | CVAR_LATCH }
|
||||
{ &grp_berp, "grp_berp", "0", CVAR_ARCHIVE | CVAR_LATCH },
|
||||
|
||||
// lua
|
||||
#ifdef CG_LUA
|
||||
{ &cg_debugLua, "cg_debuglua", "0", CVAR_ARCHIVE | CVAR_LATCH },
|
||||
{ &cg_logLua, "cg_loglua", "0", CVAR_ARCHIVE }
|
||||
#endif
|
||||
|
||||
};
|
||||
|
||||
static int cvarTableSize = sizeof( cvarTable ) / sizeof( cvarTable[0] );
|
||||
|
|
|
@ -269,6 +269,7 @@
|
|||
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">WIN32;NDEBUG;_WINDOWS</PreprocessorDefinitions>
|
||||
<BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</BrowseInformation>
|
||||
</ClCompile>
|
||||
<ClCompile Include="cg_lua.c" />
|
||||
<ClCompile Include="cg_main.c">
|
||||
<Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
|
||||
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">WIN32;_DEBUG;_WINDOWS</PreprocessorDefinitions>
|
||||
|
@ -461,6 +462,7 @@
|
|||
<ClInclude Include="..\game\bg_public.h" />
|
||||
<ClInclude Include="cg_anims.h" />
|
||||
<ClInclude Include="cg_local.h" />
|
||||
<ClInclude Include="cg_lua.h" />
|
||||
<ClInclude Include="cg_public.h" />
|
||||
<ClInclude Include="cg_screenfx.h" />
|
||||
<ClInclude Include="cg_text.h" />
|
||||
|
|
|
@ -128,6 +128,9 @@
|
|||
<ClCompile Include="fx_disruptor.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="cg_lua.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\game\bg_local.h">
|
||||
|
@ -163,6 +166,9 @@
|
|||
<ClInclude Include="tr_types.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="cg_lua.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="cgame.def">
|
||||
|
|
BIN
stefgame.suo
BIN
stefgame.suo
Binary file not shown.
Loading…
Reference in a new issue