4306 lines
105 KiB
C++
4306 lines
105 KiB
C++
#include "Scene.h"
|
|
#ifndef SKIMMED_NET
|
|
#include "lsluasocket.h"
|
|
#endif
|
|
#ifdef ONLINE_MODE
|
|
#include "account.h"
|
|
#include "json-c/json.h"
|
|
#endif
|
|
#include <string>
|
|
|
|
bool debuggingLua = false;
|
|
bool updateEvent = false;
|
|
int UpdateEvents(lua_State *L);
|
|
|
|
extern WORLD *TheScene;
|
|
|
|
#ifdef ONLINE_MODE
|
|
extern CCamCamAccount Account;
|
|
#include <map>
|
|
std::map<int, CHttpClient> HttpClientChannels;
|
|
#endif
|
|
|
|
void FillScriptInfo(lua_State *L, int paramNum, int isError);
|
|
void SaveDBGInfo(char *text);
|
|
#ifndef USER_MODE
|
|
void MyDebug(lua_State *L, int i = 0);
|
|
static void MyDebug(lua_State *L, int i) {
|
|
FillScriptInfo(L, 0, 0);
|
|
return;
|
|
}
|
|
#else
|
|
#define MyDebug(L, i)
|
|
#define MyDebug(L)
|
|
#endif
|
|
|
|
typedef struct MouseInfo_
|
|
{
|
|
int x;
|
|
int y;
|
|
u32 keys;
|
|
int value;
|
|
} MouseInfo;
|
|
|
|
|
|
void getStack(lua_State *L, int index)
|
|
{
|
|
char * luatype = NULL, *luaval = NULL;
|
|
|
|
luatype = (char *)lua_typename(L, lua_type(L, index));
|
|
if (luatype)
|
|
luaval = (char *)lua_tostring(L, index);
|
|
|
|
return;
|
|
}
|
|
|
|
void SetStrFieldFloat(lua_State *L, const char *index, float value);
|
|
void SetStrFieldString(lua_State *L, const char *index, char * value);
|
|
|
|
int PopColor(lua_State *L, u32 *colorPtr, int luaParam = 0);
|
|
int PopPoint(lua_State *L, POINT *vectorPtr, int luaParam = 0);
|
|
|
|
|
|
void PushBool(lua_State *L, BOOL value);
|
|
void PushInt(lua_State *L, int value);
|
|
void PushFloat(lua_State *L, float value);
|
|
void PushString(lua_State *L, char *string);
|
|
void PushColor(lua_State *L, DWORD color);
|
|
void PushRectangle(lua_State *L, RECT *rectPtr);
|
|
void PushTableInt(lua_State *L, int *tabList, int nbElmts);
|
|
void PushTableFloat(lua_State *L, float *tabList, int nbElmts);
|
|
void PushPoint(lua_State *L, POINT *pointPtr);
|
|
void PushPoint(lua_State *L, int x, int y);
|
|
void PushMouseInfo(lua_State *L, int x, int y, u32 code);
|
|
void PushMatrix(lua_State *L, MATRIX *matrixPtr);
|
|
void PushIntEvent(lua_State *L, int value, float time);
|
|
void PushFloatEvent(lua_State *L, float value, float time);
|
|
void PushStringEvent(lua_State *L, char * value, float time);
|
|
|
|
|
|
Vector *PopVectorPtr(lua_State *L, int luaParam = 0);
|
|
int PopVector(lua_State *L, Vector *vectorPtr, int luaParam = 0);
|
|
void PushVector(lua_State *L, Vector *vectorPtr);
|
|
void PushVectorPtr(lua_State *L, Vector *vectorPtr);
|
|
|
|
int Vector_Clone(lua_State *L);
|
|
int Vector_Add(lua_State *L);
|
|
int Vector_Sub(lua_State *L);
|
|
int Vector_Mul(lua_State *L);
|
|
int Vector_Pow(lua_State *L);
|
|
int Vector_SqrNorm(lua_State *L);
|
|
int Vector_Norm(lua_State *L);
|
|
int Vector_Normalize(lua_State *L);
|
|
void Vector_Register(lua_State *L);
|
|
void VectorPtr_Register(lua_State *L);
|
|
|
|
|
|
Quat *PopQuatPtr(lua_State *L, int luaParam = 0);
|
|
int PopQuat(lua_State *L, Quat *quatPtr, int luaParam = 0);
|
|
void PushQuat(lua_State *L, Vector *vectorPtr);
|
|
|
|
int Quat_Clone(lua_State *L);
|
|
int Quat_Add(lua_State *L);
|
|
int Quat_Sub(lua_State *L);
|
|
int Quat_Mul(lua_State *L);
|
|
int Quat_Pow(lua_State *L);
|
|
int Quat_Normalize(lua_State *L);
|
|
int Quat_NormalizeW(lua_State *L);
|
|
void Quat_Register(lua_State *L);
|
|
|
|
|
|
int PopMatrix(lua_State *L, MATRIX *matrixPtr, int luaParam = 0);
|
|
MATRIX *PopMatrixPtr(lua_State *L, int luaParam = 0);
|
|
|
|
int Matrix_Clone(lua_State *L);
|
|
int Matrix_Mul(lua_State *L);
|
|
void Matrix_Register(lua_State *L);
|
|
|
|
|
|
inline void ComputeReturn(lua_State *L, int returnDone)
|
|
{
|
|
if (returnDone <= 1) return;
|
|
if (returnDone == 2)
|
|
{
|
|
lua_newtable(L);
|
|
lua_pushinteger(L, 1);
|
|
lua_pushvalue(L, -4);
|
|
lua_settable(L, -3);
|
|
lua_pushinteger(L, 2);
|
|
lua_pushvalue(L, -3);
|
|
lua_settable(L, -3);
|
|
lua_remove(L, -2);
|
|
lua_remove(L, -2);
|
|
return;
|
|
}
|
|
lua_pushinteger(L, returnDone);
|
|
lua_pushvalue(L, -2);
|
|
lua_remove(L, -3);
|
|
lua_settable(L, -3);
|
|
}
|
|
|
|
|
|
/*********************** POP FUNCTIONS ***********************/
|
|
|
|
int PopFloatInTable(lua_State *L, char *name, float *val)
|
|
{
|
|
int returnVal = 0;
|
|
lua_pushstring(L, name);
|
|
lua_gettable(L, -2);
|
|
if (lua_isnumber(L, -1))
|
|
{
|
|
*val = (float)lua_tonumber(L, -1);
|
|
returnVal = 1;
|
|
}
|
|
lua_pop(L,1);
|
|
return returnVal;
|
|
}
|
|
|
|
int PopIntInTable(lua_State *L, char *name, int *val)
|
|
{
|
|
int returnVal = 0;
|
|
lua_pushstring(L, name);
|
|
lua_gettable(L, -2);
|
|
if (lua_isnumber(L, -1))
|
|
{
|
|
*val = (int)lua_tonumber(L, -1);
|
|
returnVal = 1;
|
|
}
|
|
lua_pop(L,1);
|
|
return returnVal;
|
|
}
|
|
|
|
int PopColor(lua_State *L, u32 *colorPtr, int luaParam)
|
|
{
|
|
int result = 1;
|
|
if (luaParam > 0)
|
|
lua_pushvalue(L, luaParam);
|
|
*colorPtr = 0;
|
|
|
|
if (lua_type(L, -1) == LUA_TSTRING)
|
|
{
|
|
char *color = (char *)lua_tostring(L, -1);
|
|
int colorLen = strlen(color);
|
|
int colorIdx = 0;
|
|
|
|
for (; colorIdx < colorLen &&
|
|
(('0' <= color[colorIdx] && color[colorIdx] <= '9') ||
|
|
('A' <= color[colorIdx] && color[colorIdx] <= 'F') ||
|
|
('a' <= color[colorIdx] && color[colorIdx] <= 'f')); colorIdx++);
|
|
|
|
if (colorIdx == colorLen)
|
|
{
|
|
if (colorLen == 8)
|
|
*colorPtr = (u32)((((IsHex(*(color + 0))-1)*16 + (IsHex(*(color + 1))-1)) << 24) +
|
|
((( IsHex(*(color + 2))-1)*16 + (IsHex(*(color + 3))-1)) << 16) +
|
|
((( IsHex(*(color + 4))-1)*16 + (IsHex(*(color + 5))-1)) << 8) +
|
|
((( IsHex(*(color + 6))-1)*16 + (IsHex(*(color + 7))-1)) ));
|
|
else if (colorLen == 6)
|
|
*colorPtr = (u32)(( 255 << 24) +
|
|
((( IsHex(*(color + 0))-1)*16 + (IsHex(*(color + 1))-1)) << 16) +
|
|
((( IsHex(*(color + 2))-1)*16 + (IsHex(*(color + 3))-1)) << 8) +
|
|
((( IsHex(*(color + 4))-1)*16 + (IsHex(*(color + 5))-1)) ));
|
|
else
|
|
result = 0;
|
|
} else
|
|
result = 0;
|
|
} else if (lua_istable(L, -1))
|
|
{
|
|
int R,G,B,A;
|
|
if (!result || !PopIntInTable(L, "R", &R)) result = 0;
|
|
if (!result || !PopIntInTable(L, "G", &G)) result = 0;
|
|
if (!result || !PopIntInTable(L, "B", &B)) result = 0;
|
|
if (!result || !PopIntInTable(L, "A", &A)) A = 255;
|
|
if (result)
|
|
*colorPtr = (A << 24) + (R << 16) + (G << 8) + B;
|
|
} else if (luaParam > 0)
|
|
{
|
|
int RGBA[4];
|
|
int curParam = luaParam;
|
|
RGBA[3] = 255;
|
|
|
|
for (int c=0; result && c<4; c++, curParam++)
|
|
{
|
|
if (lua_type(L, curParam) == LUA_TNUMBER)
|
|
{
|
|
lua_pop(L,1);
|
|
lua_pushvalue(L, curParam);
|
|
RGBA[c] = lua_tonumber(L, -1);
|
|
if (c) result++;
|
|
} else if (c < 3) result = 0;
|
|
}
|
|
if (result)
|
|
*colorPtr = (RGBA[3] << 24) + (RGBA[0] << 16) + (RGBA[1] << 8) + RGBA[2];
|
|
}
|
|
|
|
if (luaParam > 0)
|
|
lua_pop(L,1);
|
|
return result;
|
|
}
|
|
|
|
int PopPoint(lua_State *L, POINT *pointPtr, int luaParam)
|
|
{
|
|
BOOL result = 1;
|
|
if (luaParam > 0)
|
|
{
|
|
lua_pushvalue(L, luaParam);
|
|
luaL_checktype(L, luaParam, LUA_TTABLE);
|
|
} else
|
|
luaL_checktype(L, -1, LUA_TTABLE);
|
|
|
|
int pointParam;
|
|
if (!result || !PopIntInTable(L, "x", &pointParam)) result = 0;
|
|
pointPtr->x = pointParam;
|
|
if (!result || !PopIntInTable(L, "y", &pointParam)) result = 0;
|
|
pointPtr->y = pointParam;
|
|
if (luaParam > 0)
|
|
lua_pop(L,1);
|
|
return result;
|
|
}
|
|
|
|
/*** USER MATRIX POP ***/
|
|
|
|
|
|
int PopListInt(lua_State *L, int *resultList, int *nbElmts, int luaParam)
|
|
{
|
|
luaL_checktype(L, luaParam, LUA_TTABLE);
|
|
lua_pushvalue(L, luaParam);
|
|
|
|
*nbElmts = lua_objlen(L, -1);
|
|
for (int i=0; i<*nbElmts; i++)
|
|
{
|
|
lua_pushnumber(L, i+1);
|
|
lua_gettable(L, -2);
|
|
if (lua_isnumber(L, -1))
|
|
{
|
|
resultList[i] = (int)lua_tonumber(L, -1);
|
|
}
|
|
lua_pop(L,1);
|
|
}
|
|
lua_pop(L,1);
|
|
return *nbElmts;
|
|
}
|
|
|
|
int PopListFloat(lua_State *L, float *resultList, int *nbElmts, int luaParam)
|
|
{
|
|
luaL_checktype(L, luaParam, LUA_TTABLE);
|
|
lua_pushvalue(L, luaParam);
|
|
|
|
*nbElmts = lua_objlen(L, -1);
|
|
for (int i=0; i<*nbElmts; i++)
|
|
{
|
|
lua_pushnumber(L, i+1);
|
|
lua_gettable(L, -2);
|
|
if (lua_isnumber(L, -1))
|
|
{
|
|
resultList[i] = (float)lua_tonumber(L, -1);
|
|
}
|
|
lua_pop(L,1);
|
|
}
|
|
lua_pop(L,1);
|
|
return *nbElmts;
|
|
}
|
|
|
|
int PopListPoint(lua_State *L, POINT *resultList, int *nbElmts, int luaParam)
|
|
{
|
|
luaL_checktype(L, luaParam, LUA_TTABLE);
|
|
lua_pushvalue(L, luaParam);
|
|
|
|
*nbElmts = lua_objlen(L, -1);
|
|
for (int i=0; i<*nbElmts; i++)
|
|
{
|
|
lua_pushnumber(L, i+1);
|
|
lua_gettable(L, -2);
|
|
PopPoint(L, &resultList[i]);
|
|
lua_pop(L,1);
|
|
}
|
|
lua_pop(L,1);
|
|
return *nbElmts;
|
|
}
|
|
int PopListVector(lua_State *L, Vector *resultList, int *nbElmts, int luaParam)
|
|
{
|
|
luaL_checktype(L, luaParam, LUA_TTABLE);
|
|
lua_pushvalue(L, luaParam);
|
|
|
|
*nbElmts = lua_objlen(L, -1);
|
|
for (int i=0; i<*nbElmts; i++)
|
|
{
|
|
lua_pushnumber(L, i+1);
|
|
lua_gettable(L, -2);
|
|
PopVector(L, &resultList[i],-1);
|
|
lua_pop(L,1);
|
|
}
|
|
lua_pop(L,1);
|
|
return *nbElmts;
|
|
}
|
|
|
|
int PopListColor(lua_State *L, u32 *resultList, int *nbElmts, int luaParam)
|
|
{
|
|
luaL_checktype(L, luaParam, LUA_TTABLE);
|
|
lua_pushvalue(L, luaParam);
|
|
|
|
*nbElmts = lua_objlen(L, -1);
|
|
for (int i=0; i<*nbElmts; i++)
|
|
{
|
|
lua_pushnumber(L, i+1);
|
|
lua_gettable(L, -2);
|
|
PopColor(L, &resultList[i],-1);
|
|
lua_pop(L,1);
|
|
}
|
|
lua_pop(L,1);
|
|
return *nbElmts;
|
|
}
|
|
|
|
/*********************** POP FUNCTIONS ***********************/
|
|
|
|
/*********************** PUSH FUNCTIONS ***********************/
|
|
|
|
void SetStrFieldFloat(lua_State *L, const char *index, float value) {
|
|
lua_pushstring(L, index);
|
|
lua_pushnumber(L, (double)value);
|
|
//lua_settable(L, -3);
|
|
lua_rawset(L, -3);
|
|
}
|
|
|
|
void SetStrFieldInteger(lua_State *L, const char *index, int value) {
|
|
lua_pushstring(L, index);
|
|
lua_pushinteger(L, value);
|
|
//lua_settable(L, -3);
|
|
lua_rawset(L, -3);
|
|
}
|
|
|
|
void SetStrFieldString(lua_State *L, const char *index, char * value) {
|
|
lua_pushstring(L, index);
|
|
lua_pushstring(L, value);
|
|
//lua_settable(L, -3);
|
|
lua_rawset(L, -3);
|
|
}
|
|
|
|
void SetStrFieldFunction(lua_State *L, const char *index, lua_CFunction function) {
|
|
lua_pushstring(L, index);
|
|
lua_pushcfunction(L, function);
|
|
//lua_settable(L, -3);
|
|
lua_rawset(L, -3);
|
|
}
|
|
|
|
void SetStrFieldBoolean(lua_State *L, const char *index, bool value) {
|
|
lua_pushstring(L, index);
|
|
lua_pushboolean(L, value);
|
|
//lua_settable(L, -3);
|
|
lua_rawset(L, -3);
|
|
}
|
|
|
|
|
|
void PushBool(lua_State *L, BOOL value)
|
|
{
|
|
lua_pushboolean(L, value);
|
|
}
|
|
void PushInt(lua_State *L, int value)
|
|
{
|
|
lua_pushinteger(L, (double)value);
|
|
}
|
|
void PushFloat(lua_State *L, float value)
|
|
{
|
|
lua_pushnumber(L, (double)value);
|
|
}
|
|
void PushString(lua_State *L, char *string)
|
|
{
|
|
lua_pushstring(L, string);
|
|
}
|
|
void PushColor(lua_State *L, DWORD color)
|
|
{
|
|
//lua_newtable(L);
|
|
lua_createtable(L,0,4);
|
|
SetStrFieldFloat(L, "A", (float)((color & 0xFF000000) >> 24));
|
|
SetStrFieldFloat(L, "R", (float)((color & 0x00FF0000) >> 16));
|
|
SetStrFieldFloat(L, "G", (float)((color & 0x0000FF00) >> 8 ));
|
|
SetStrFieldFloat(L, "B", (float)((color & 0x000000FF) ));
|
|
}
|
|
void PushRectangle(lua_State *L, RECT *rectPtr)
|
|
{
|
|
//lua_newtable(L);
|
|
lua_createtable(L,0,4);
|
|
SetStrFieldFloat(L, "x", (float)rectPtr->left);
|
|
SetStrFieldFloat(L, "y", (float)rectPtr->top);
|
|
SetStrFieldFloat(L, "sx", (float)(rectPtr->right - rectPtr->left));
|
|
SetStrFieldFloat(L, "sy", (float)(rectPtr->bottom - rectPtr->top));
|
|
}
|
|
void PushTableInt(lua_State *L, int *tabList, int nbElmts)
|
|
{
|
|
//lua_newtable(L);
|
|
lua_createtable(L, nbElmts, 0);
|
|
for (int i=0; i<nbElmts; i++)
|
|
{
|
|
//lua_pushnumber(L, i+1);
|
|
//lua_pushnumber(L, (double)tabList[i]);
|
|
//lua_settable(L, -3);
|
|
lua_pushnumber(L, (double)tabList[i]);
|
|
lua_rawseti(L, -2, i+1);
|
|
}
|
|
}
|
|
|
|
void PushTableFloat(lua_State *L, float *tabList, int nbElmts)
|
|
{
|
|
//lua_newtable(L);
|
|
lua_createtable(L, nbElmts, 0);
|
|
for (int i=0; i<nbElmts; i++)
|
|
{
|
|
//lua_pushnumber(L, i+1);
|
|
//lua_pushnumber(L, (double)tabList[i]);
|
|
//lua_settable(L, -3);
|
|
lua_pushnumber(L, (double)tabList[i]);
|
|
lua_rawseti(L, -2, i+1);
|
|
}
|
|
}
|
|
|
|
void PushPoint(lua_State *L, POINT *pointPtr)
|
|
{
|
|
PushPoint(L, pointPtr->x, pointPtr->y);
|
|
}
|
|
void PushPoint(lua_State *L, float x, float y)
|
|
{
|
|
//lua_newtable(L);
|
|
lua_createtable(L, 0, 2);
|
|
SetStrFieldFloat(L, "x", x);
|
|
SetStrFieldFloat(L, "y", y);
|
|
}
|
|
|
|
void PushPoint(lua_State *L, int x, int y)
|
|
{
|
|
PushPoint(L, (float)x, (float)y);
|
|
}
|
|
|
|
void PushMouseInfo(lua_State *L, MouseInfo *mouseInfo)
|
|
{
|
|
//lua_newtable(L);
|
|
lua_createtable(L, 0, 4);
|
|
SetStrFieldFloat(L, "x", mouseInfo->x);
|
|
SetStrFieldFloat(L, "y", mouseInfo->y);
|
|
|
|
lua_pushstring(L, "keys");
|
|
lua_newtable(L);
|
|
|
|
if (mouseInfo->keys & MK_CONTROL)
|
|
SetStrFieldFloat(L, "control", 1);
|
|
if (mouseInfo->keys & MK_LBUTTON)
|
|
SetStrFieldFloat(L, "lbutton", 1);
|
|
if (mouseInfo->keys & MK_MBUTTON)
|
|
SetStrFieldFloat(L, "mbutton", 1);
|
|
if (mouseInfo->keys & MK_RBUTTON)
|
|
SetStrFieldFloat(L, "rbutton", 1);
|
|
if (mouseInfo->keys & MK_SHIFT)
|
|
SetStrFieldFloat(L, "shift", 1);
|
|
|
|
lua_settable(L, -3);
|
|
|
|
SetStrFieldFloat(L, "value", mouseInfo->value);
|
|
}
|
|
|
|
|
|
void PushIntEvent(lua_State *L, int value, float time)
|
|
{
|
|
//lua_newtable(L);
|
|
lua_createtable(L, 0, 2);
|
|
SetStrFieldFloat(L, "data", value);
|
|
SetStrFieldFloat(L, "time", time);
|
|
}
|
|
|
|
void PushFloatEvent(lua_State *L, float value, float time)
|
|
{
|
|
//lua_newtable(L);
|
|
lua_createtable(L, 0, 2);
|
|
SetStrFieldFloat(L, "data", value);
|
|
SetStrFieldFloat(L, "time", time);
|
|
}
|
|
|
|
void PushStringEvent(lua_State *L, char * value, float time)
|
|
{
|
|
//lua_newtable(L);
|
|
lua_createtable(L, 0, 2);
|
|
SetStrFieldString(L, "data", value);
|
|
SetStrFieldFloat(L, "time", time);
|
|
}
|
|
|
|
/*********************** PUSH FUNCTIONS ***********************/
|
|
|
|
|
|
/*********************** CLASS DEFINITIONS ***********************/
|
|
|
|
/*********************** VECTOR ***********************/
|
|
|
|
Vector *PopVectorPtr(lua_State *L, int luaParam)
|
|
{
|
|
int top = lua_gettop(L);
|
|
void *p = lua_touserdata(L, luaParam);
|
|
Vector *vPtr = NULL;
|
|
|
|
if (p == NULL) return NULL;
|
|
if (!lua_getmetatable(L, luaParam)) return NULL;
|
|
|
|
lua_getfield(L, LUA_REGISTRYINDEX, "VECTOR");
|
|
if (lua_rawequal(L, -1, -2))
|
|
vPtr = (Vector *)p;
|
|
else
|
|
{
|
|
lua_pop(L, 1);
|
|
lua_getfield(L, LUA_REGISTRYINDEX, "VECTOR_PTR");
|
|
if (lua_rawequal(L, -1, -2))
|
|
vPtr = *((Vector **)p);
|
|
}
|
|
lua_pop(L, 2);
|
|
return vPtr;
|
|
}
|
|
|
|
int PopVector(lua_State *L, Vector *vectorPtr, int luaParam)
|
|
{
|
|
Vector *vPtr = PopVectorPtr(L, luaParam);
|
|
if (vPtr == NULL) return 0;
|
|
memcpy(vectorPtr, vPtr, sizeof(Vector)); return 1;
|
|
}
|
|
|
|
void PushVector(lua_State *L, Vector *vectorPtr)
|
|
{
|
|
void *VectorUser = lua_newuserdata(L, sizeof(Vector));
|
|
if (!VectorUser) return;
|
|
|
|
memcpy(VectorUser, vectorPtr, sizeof(Vector));
|
|
luaL_getmetatable(L, "VECTOR");
|
|
lua_setmetatable (L, -2);
|
|
}
|
|
|
|
void PushVector(lua_State *L, char *vectorString)
|
|
{
|
|
Vector *vectorPtr = (Vector*)ZeroAlloc(sizeof(Vector));
|
|
if(sscanf(vectorString,"{x=%f,y=%f,z=%f}", &vectorPtr->x, &vectorPtr->y, &vectorPtr->z)==3)
|
|
PushVector(L,vectorPtr);
|
|
}
|
|
|
|
void PushVectorPtr(lua_State *L, Vector *vectorPtr)
|
|
{
|
|
void *VectorUserPtr = lua_newuserdata(L, sizeof(Vector *));
|
|
if (!VectorUserPtr) return;
|
|
|
|
*((Vector **)VectorUserPtr) = vectorPtr;
|
|
luaL_getmetatable(L, "VECTOR_PTR");
|
|
lua_setmetatable (L, -2);
|
|
}
|
|
|
|
int Vector_Index(lua_State *L)
|
|
{
|
|
Vector *vPtr;
|
|
if (!(vPtr = PopVectorPtr(L, 1)))
|
|
return 0;
|
|
const char *tableStr = luaL_checkstring(L, 2);
|
|
if (tableStr[1] == 0)
|
|
{
|
|
switch (*tableStr)
|
|
{
|
|
case 'x': lua_pushnumber(L, vPtr->x); return 1;
|
|
case 'y': lua_pushnumber(L, vPtr->y); return 1;
|
|
case 'z': lua_pushnumber(L, vPtr->z); return 1;
|
|
}
|
|
return 0;
|
|
}
|
|
if (!strcmp(tableStr, "Norm"))
|
|
{
|
|
lua_pushcfunction(L, Vector_Norm);
|
|
return 1;
|
|
}
|
|
if (!strcmp(tableStr, "SqrNorm"))
|
|
{
|
|
lua_pushcfunction(L, Vector_SqrNorm);
|
|
return 1;
|
|
}
|
|
if (!strcmp(tableStr, "Normalize"))
|
|
{
|
|
lua_pushcfunction(L, Vector_Normalize);
|
|
return 1;
|
|
}
|
|
if (!strcmp(tableStr, "Clone"))
|
|
{
|
|
lua_pushcfunction(L, Vector_Clone);
|
|
return 1;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
int Vector_NewIndex(lua_State *L)
|
|
{
|
|
Vector *vPtr;
|
|
if (!(vPtr = PopVectorPtr(L, 1)))
|
|
return 0;
|
|
const char *tableStr = luaL_checkstring(L, 2);
|
|
float number = luaL_checknumber(L, 3);
|
|
if (tableStr[1] != 0) return 0;
|
|
|
|
switch (*tableStr)
|
|
{
|
|
case 'x': vPtr->x = number; return 1;
|
|
case 'y': vPtr->y = number; return 1;
|
|
case 'z': vPtr->z = number; return 1;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
|
|
int Vector_Clone(lua_State *L)
|
|
{
|
|
Vector *vPtr;
|
|
if (!(vPtr = PopVectorPtr(L, 1))) return 0;
|
|
PushVector(L, vPtr);
|
|
return 1;
|
|
}
|
|
|
|
int Vector_ToString(lua_State *L)
|
|
{
|
|
Vector *vPtr;
|
|
char vStr[256];
|
|
|
|
if (!(vPtr = PopVectorPtr(L, 1))) return 0;
|
|
|
|
sprintf(vStr, "{x=%.2f,y=%.2f,z=%.2f}",
|
|
vPtr->x, vPtr->y, vPtr->z);
|
|
lua_pushstring(L, vStr); return 1;
|
|
}
|
|
|
|
int Vector_Add(lua_State *L)
|
|
{
|
|
Vector v1, *v2Ptr = NULL;
|
|
if (!PopVector(L, &v1, 1)) return 0;
|
|
|
|
if (lua_isnumber(L, 2))
|
|
{
|
|
v1 += lua_tonumber(L, -1);
|
|
PushVector(L, &v1); return 1;
|
|
}
|
|
if ((v2Ptr = PopVectorPtr(L, 2)) != NULL)
|
|
{
|
|
v1 = v1+*v2Ptr;
|
|
PushVector(L, &v1); return 1;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
int Vector_Sub(lua_State *L)
|
|
{
|
|
Vector v1, *v2Ptr = NULL;
|
|
if (!PopVector(L, &v1, 1)) return 0;
|
|
|
|
if (lua_isnumber(L, 2))
|
|
{
|
|
v1 += -lua_tonumber(L, -1);
|
|
PushVector(L, &v1); return 1;
|
|
} else if ((v2Ptr = PopVectorPtr(L, 2)) != NULL)
|
|
{
|
|
v1 = v1-*v2Ptr;
|
|
PushVector(L, &v1); return 1;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
int Vector_Mul(lua_State *L)
|
|
{
|
|
Vector v1, *v2Ptr = NULL;
|
|
if (!PopVector(L, &v1, 1)) return 0;
|
|
|
|
if (lua_isnumber(L, 2))
|
|
{
|
|
v1 = v1*lua_tonumber(L, -1);
|
|
PushVector(L, &v1); return 1;
|
|
} else if ((v2Ptr = PopVectorPtr(L, 2)) != NULL)
|
|
{
|
|
lua_pushnumber(L, v1**v2Ptr); return 1;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
|
|
int Vector_Pow(lua_State *L)
|
|
{
|
|
Vector v1, *v2Ptr = NULL;
|
|
if (!PopVector(L, &v1, 1) ||
|
|
!(v2Ptr = PopVectorPtr(L, 2))) return 0;
|
|
|
|
v1 = v1^(*v2Ptr);
|
|
PushVector(L, &v1); return 1;
|
|
}
|
|
|
|
int Vector_SqrNorm(lua_State *L)
|
|
{
|
|
Vector *v1Ptr;
|
|
if (!(v1Ptr = PopVectorPtr(L, 1))) return 0;
|
|
lua_pushnumber(L, v1Ptr->SqrNorm());
|
|
return 1;
|
|
}
|
|
|
|
int Vector_Norm(lua_State *L)
|
|
{
|
|
Vector *v1Ptr;
|
|
if (!(v1Ptr = PopVectorPtr(L, 1))) return 0;
|
|
lua_pushnumber(L, v1Ptr->Norm()); return 1;
|
|
}
|
|
|
|
int Vector_Normalize(lua_State *L)
|
|
{
|
|
Vector *v1Ptr = NULL;
|
|
if (!(v1Ptr = PopVectorPtr(L, 1))) return 0;
|
|
if (lua_gettop(L) > 1 && lua_toboolean(L, 2))
|
|
{
|
|
Vector v2 = *v1Ptr;
|
|
v2.Normalize();
|
|
PushVector(L, &v2);
|
|
} else
|
|
{
|
|
v1Ptr->Normalize();
|
|
PushVectorPtr(L, v1Ptr);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
static const luaL_reg Vector_meta[] = {
|
|
{"__index", Vector_Index},
|
|
{"__newindex", Vector_NewIndex},
|
|
{"__tostring", Vector_ToString},
|
|
{"__add", Vector_Add},
|
|
{"__sub", Vector_Sub},
|
|
{"__mul", Vector_Mul},
|
|
{"__pow", Vector_Pow},
|
|
{0, 0}
|
|
};
|
|
|
|
|
|
void Vector_Register(lua_State *L)
|
|
{
|
|
luaL_newmetatable(L, "VECTOR"); /* create metatable for Foo,
|
|
and add it to the Lua registry */
|
|
luaL_openlib(L, 0, Vector_meta, 0); /* fill metatable */
|
|
lua_pushliteral(L, "__metatable");
|
|
lua_pushvalue(L, -3); /* dup methods table*/
|
|
lua_rawset(L, -3); /* hide metatable:
|
|
metatable.__metatable = methods */
|
|
lua_pop(L, 1); /* drop metatable */
|
|
}
|
|
|
|
void VectorPtr_Register(lua_State *L)
|
|
{
|
|
luaL_newmetatable(L, "VECTOR_PTR"); /* create metatable for Foo,
|
|
and add it to the Lua registry */
|
|
luaL_openlib(L, 0, Vector_meta, 0); /* fill metatable */
|
|
lua_pushliteral(L, "__metatable");
|
|
lua_pushvalue(L, -3); /* dup methods table*/
|
|
lua_rawset(L, -3); /* hide metatable:
|
|
metatable.__metatable = methods */
|
|
lua_pop(L, 1); /* drop metatable */
|
|
}
|
|
|
|
|
|
/*********************** QUAT ***********************/
|
|
|
|
Quat *PopQuatPtr(lua_State *L, int luaParam)
|
|
{
|
|
int top = lua_gettop(L);
|
|
Quat *qPtr = NULL;
|
|
|
|
if (luaParam > 0)
|
|
{
|
|
lua_pushvalue(L, luaParam);
|
|
luaL_checktype(L, luaParam, LUA_TUSERDATA);
|
|
qPtr = (Quat *)luaL_checkudata(L, luaParam, "QUAT");
|
|
} else
|
|
{
|
|
luaL_checktype(L, -1, LUA_TUSERDATA);
|
|
qPtr = (Quat *)luaL_checkudata(L, luaParam, "QUAT");
|
|
}
|
|
if (qPtr == NULL) luaL_typerror(L, luaParam, "QUAT");
|
|
return qPtr;
|
|
}
|
|
|
|
int PopQuat(lua_State *L, Quat *quatPtr, int luaParam)
|
|
{
|
|
Quat *qPtr = PopQuatPtr(L, luaParam);
|
|
if (qPtr == NULL) return 0;
|
|
memcpy(quatPtr, qPtr, sizeof(Quat));
|
|
return 1;
|
|
}
|
|
|
|
void PushQuat(lua_State *L, Quat *quatPtr)
|
|
{
|
|
void *QuatUser = lua_newuserdata(L, sizeof(Quat));
|
|
if (!QuatUser) return;
|
|
|
|
memcpy(QuatUser, quatPtr, sizeof(Quat));
|
|
luaL_getmetatable(L, "QUAT");
|
|
lua_setmetatable (L, -2);
|
|
}
|
|
|
|
void PushQuat(lua_State *L, char *qStr)
|
|
{
|
|
Quat *qPtr = (Quat*)ZeroAlloc(sizeof(Quat));
|
|
if(4==sscanf(qStr, "{x=%f,y=%f,z=%f,w=%f}",
|
|
&qPtr->x, &qPtr->y, &qPtr->z, &qPtr->w))
|
|
{
|
|
PushQuat(L, qPtr);
|
|
}
|
|
}
|
|
|
|
int Quat_Clone(lua_State *L)
|
|
{
|
|
Quat *qPtr;
|
|
if (!(qPtr = PopQuatPtr(L, 1))) return 0;
|
|
PushQuat(L, qPtr);
|
|
return 1;
|
|
}
|
|
|
|
|
|
int Quat_Index(lua_State *L)
|
|
{
|
|
Quat *qPtr;
|
|
if (!(qPtr = PopQuatPtr(L, 1)))
|
|
return 0;
|
|
const char *tableStr = luaL_checkstring(L, 2);
|
|
if (tableStr[1] == 0)
|
|
{
|
|
switch (*tableStr)
|
|
{
|
|
case 'x': lua_pushnumber(L, qPtr->x); return 1;
|
|
case 'y': lua_pushnumber(L, qPtr->y); return 1;
|
|
case 'z': lua_pushnumber(L, qPtr->z); return 1;
|
|
case 'w': lua_pushnumber(L, qPtr->w); return 1;
|
|
}
|
|
return 0;
|
|
}
|
|
if (!strcmp(tableStr, "Normalize"))
|
|
{
|
|
lua_pushcfunction(L, Quat_Normalize);
|
|
return 1;
|
|
}
|
|
if (!strcmp(tableStr, "NormalizeW"))
|
|
{
|
|
lua_pushcfunction(L, Quat_NormalizeW);
|
|
return 1;
|
|
}
|
|
if (!strcmp(tableStr, "Clone"))
|
|
{
|
|
lua_pushcfunction(L, Quat_Clone);
|
|
return 1;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
int Quat_NewIndex(lua_State *L)
|
|
{
|
|
Quat *qPtr;
|
|
if (!(qPtr = PopQuatPtr(L, 1)))
|
|
return 0;
|
|
const char *tableStr = luaL_checkstring(L, 2);
|
|
float number = luaL_checknumber(L, 3);
|
|
|
|
if (tableStr[1] != 0) return 0;
|
|
switch (*tableStr)
|
|
{
|
|
case 'x': qPtr->x = number; return 1;
|
|
case 'y': qPtr->y = number; return 1;
|
|
case 'z': qPtr->z = number; return 1;
|
|
case 'w': qPtr->w = number; return 1;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
|
|
int Quat_ToString(lua_State *L)
|
|
{
|
|
Quat *qPtr;
|
|
char qStr[256];
|
|
|
|
if (!(qPtr = PopQuatPtr(L, 1))) return 0;
|
|
|
|
sprintf(qStr, "{x=%.2f,y=%.2f,z=%.2f,w=%.2f}",
|
|
qPtr->x, qPtr->y, qPtr->z, qPtr->w);
|
|
lua_pushstring(L, qStr); return 1;
|
|
}
|
|
|
|
int Quat_Add(lua_State *L)
|
|
{
|
|
Quat q1, *q2Ptr = NULL;
|
|
if (!PopQuat(L, &q1, 1) ||
|
|
!(q2Ptr = PopQuatPtr(L, 2))) return 0;
|
|
|
|
q1 = q1+*q2Ptr;
|
|
PushQuat(L, &q1);
|
|
return 1;
|
|
}
|
|
|
|
int Quat_Mul(lua_State *L)
|
|
{
|
|
Quat q1, *q2Ptr = NULL;
|
|
if (!PopQuat(L, &q1, 1)) return 0;
|
|
|
|
if (lua_isnumber(L, 2))
|
|
{
|
|
q1 = q1*lua_tonumber(L, 2);
|
|
PushQuat(L, &q1); return 1;
|
|
} else if ((q2Ptr = PopQuatPtr(L, 2)) != NULL)
|
|
{
|
|
q1 *= *q2Ptr;
|
|
PushQuat(L, &q1); return 1;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
|
|
int Quat_Normalize(lua_State *L)
|
|
{
|
|
Quat *q1Ptr = NULL;
|
|
if (!(q1Ptr = PopQuatPtr(L, 1))) return 0;
|
|
q1Ptr->Normalize();
|
|
PushQuat(L, q1Ptr); return 1;
|
|
}
|
|
|
|
int Quat_NormalizeW(lua_State *L)
|
|
{
|
|
Quat *q1Ptr = NULL;
|
|
if (!(q1Ptr = PopQuatPtr(L, 1))) return 0;
|
|
q1Ptr->NormalizeW();
|
|
PushQuat(L, q1Ptr); return 1;
|
|
}
|
|
|
|
|
|
static const luaL_reg Quat_meta[] = {
|
|
{"__index", Quat_Index},
|
|
{"__newindex", Quat_NewIndex},
|
|
{"__tostring", Quat_ToString},
|
|
{"__add", Quat_Add},
|
|
{"__mul", Quat_Mul},
|
|
{0, 0}
|
|
};
|
|
|
|
|
|
void Quat_Register(lua_State *L)
|
|
{
|
|
luaL_newmetatable(L, "QUAT"); /* create metatable for Foo,
|
|
and add it to the Lua registry */
|
|
luaL_openlib(L, 0, Quat_meta, 0); /* fill metatable */
|
|
lua_pushliteral(L, "__metatable");
|
|
lua_pushvalue(L, -3); /* dup methods table*/
|
|
lua_rawset(L, -3); /* hide metatable:
|
|
metatable.__metatable = methods */
|
|
lua_pop(L, 1); /* drop metatable */
|
|
}
|
|
|
|
|
|
/*********************** MATRIX **************************/
|
|
|
|
|
|
MATRIX *PopMatrixPtr(lua_State *L, int luaParam)
|
|
{
|
|
int top = lua_gettop(L);
|
|
MATRIX *mPtr = NULL;
|
|
|
|
if (luaParam > 0)
|
|
{
|
|
lua_pushvalue(L, luaParam);
|
|
luaL_checktype(L, luaParam, LUA_TUSERDATA);
|
|
mPtr = (MATRIX *)luaL_checkudata(L, luaParam, "MATRIX");
|
|
} else
|
|
{
|
|
luaL_checktype(L, -1, LUA_TUSERDATA);
|
|
mPtr = (MATRIX *)luaL_checkudata(L, luaParam, "MATRIX");
|
|
}
|
|
if (mPtr == NULL) luaL_typerror(L, luaParam, "MATRIX");
|
|
return mPtr;
|
|
}
|
|
|
|
int PopMatrix(lua_State *L, MATRIX *matrixPtr, int luaParam)
|
|
{
|
|
MATRIX *mPtr = PopMatrixPtr(L, luaParam);
|
|
if (mPtr == NULL)
|
|
return 0;
|
|
memcpy(matrixPtr, mPtr, sizeof(MATRIX));
|
|
return 1;
|
|
}
|
|
|
|
void PushMatrix(lua_State *L, MATRIX *matrixPtr)
|
|
{
|
|
void *MatrixUser = lua_newuserdata(L, sizeof(MATRIX));
|
|
if (!MatrixUser) return;
|
|
|
|
memcpy(MatrixUser, matrixPtr, sizeof(MATRIX));
|
|
luaL_getmetatable(L, "MATRIX");
|
|
//lua_getglobal(L, "MATRIX");
|
|
lua_setmetatable (L, -2);
|
|
}
|
|
|
|
void PushMatrix(lua_State *L, char *matrixString)
|
|
{
|
|
MATRIX *mPtr = (MATRIX*)ZeroAlloc(sizeof(MATRIX));
|
|
if(12==sscanf(matrixString, "{I={x=%f,y=%f,z=%f},J={x=%f,y=%f,z=%f},K={x=%f,y=%f,z=%f},T={x=%f,y=%f,z=%f}}",
|
|
&mPtr->I.x, &mPtr->I.y, &mPtr->I.z,
|
|
&mPtr->J.x, &mPtr->J.y, &mPtr->J.z,
|
|
&mPtr->K.x, &mPtr->K.y, &mPtr->K.z,
|
|
&mPtr->T.x, &mPtr->T.y, &mPtr->T.z))
|
|
{
|
|
PushMatrix(L, mPtr);
|
|
}
|
|
}
|
|
|
|
int Matrix_Clone(lua_State *L)
|
|
{
|
|
MATRIX *mPtr;
|
|
if (!(mPtr = PopMatrixPtr(L, 1))) return 0;
|
|
PushMatrix(L, mPtr);
|
|
return 1;
|
|
}
|
|
|
|
#define MATRIX_FLOAT_SETGET(Vct,Wct) \
|
|
int Matrix_Set##Vct##Wct(lua_State *L) \
|
|
{ \
|
|
MATRIX *mPtr = NULL; \
|
|
float number= 0; \
|
|
if (!(mPtr = PopMatrixPtr(L, 1))) return 0; \
|
|
number = luaL_checknumber(L, 2); \
|
|
mPtr->Vct.Wct = number; return 1; \
|
|
} \
|
|
int Matrix_Get##Vct##Wct(lua_State *L) \
|
|
{ \
|
|
MATRIX *mPtr = NULL; \
|
|
if (!(mPtr = PopMatrixPtr(L, 1))) return 0; \
|
|
lua_pushnumber(L, mPtr->Vct.Wct); return 1; \
|
|
}
|
|
|
|
#define PUSH_SETGET(Vct, Wct) \
|
|
if (tableStr[0] == 'S' && tableStr[3] == *#Vct && tableStr[4] == *#Wct) \
|
|
{ lua_pushcfunction(L, Matrix_Set##Vct##Wct); return 1; } \
|
|
if (tableStr[0] == 'G' && tableStr[3] == *#Vct && tableStr[4] == *#Wct) \
|
|
{ lua_pushcfunction(L, Matrix_Get##Vct##Wct); return 1; }
|
|
|
|
MATRIX_FLOAT_SETGET(I,x)
|
|
MATRIX_FLOAT_SETGET(I,y)
|
|
MATRIX_FLOAT_SETGET(I,z)
|
|
MATRIX_FLOAT_SETGET(J,x)
|
|
MATRIX_FLOAT_SETGET(J,y)
|
|
MATRIX_FLOAT_SETGET(J,z)
|
|
MATRIX_FLOAT_SETGET(K,x)
|
|
MATRIX_FLOAT_SETGET(K,y)
|
|
MATRIX_FLOAT_SETGET(K,z)
|
|
MATRIX_FLOAT_SETGET(T,x)
|
|
MATRIX_FLOAT_SETGET(T,y)
|
|
MATRIX_FLOAT_SETGET(T,z)
|
|
|
|
int Matrix_Index(lua_State *L)
|
|
{
|
|
MATRIX *mPtr;
|
|
if (!(mPtr = PopMatrixPtr(L, 1)))
|
|
return 0;
|
|
const char *tableStr = luaL_checkstring(L, 2);
|
|
if (tableStr[1] == 0)
|
|
{
|
|
switch (*tableStr)
|
|
{
|
|
case 'I': PushVectorPtr(L, &mPtr->I); return 1;
|
|
case 'J': PushVectorPtr(L, &mPtr->J); return 1;
|
|
case 'K': PushVectorPtr(L, &mPtr->K); return 1;
|
|
case 'T': PushVectorPtr(L, &mPtr->T); return 1;
|
|
}
|
|
return 0;
|
|
}
|
|
if (!strcmp(tableStr, "Clone"))
|
|
{
|
|
lua_pushcfunction(L, Matrix_Clone);
|
|
return 1;
|
|
}
|
|
if (strlen(tableStr) == 5)
|
|
{
|
|
PUSH_SETGET(I,x)
|
|
PUSH_SETGET(I,y)
|
|
PUSH_SETGET(I,z)
|
|
PUSH_SETGET(J,x)
|
|
PUSH_SETGET(J,y)
|
|
PUSH_SETGET(J,z)
|
|
PUSH_SETGET(K,x)
|
|
PUSH_SETGET(K,y)
|
|
PUSH_SETGET(K,z)
|
|
PUSH_SETGET(T,x)
|
|
PUSH_SETGET(T,y)
|
|
PUSH_SETGET(T,z)
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
int Matrix_NewIndex(lua_State *L)
|
|
{
|
|
MATRIX *mPtr = PopMatrixPtr(L, 1);
|
|
if (!mPtr) return 0;
|
|
const char *tableStr = luaL_checkstring(L, 2);
|
|
if (tableStr[1] != 0) return 0;
|
|
Vector *vPtr = PopVectorPtr(L, 3);
|
|
if (!vPtr) return 0;
|
|
|
|
switch (*tableStr)
|
|
{
|
|
case 'I': mPtr->I = *vPtr; return 1;
|
|
case 'J': mPtr->J = *vPtr; return 1;
|
|
case 'K': mPtr->K = *vPtr; return 1;
|
|
case 'T': mPtr->T = *vPtr; return 1;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
|
|
int Matrix_ToString(lua_State *L)
|
|
{
|
|
MATRIX *mPtr;
|
|
char mStr[512];
|
|
|
|
if (!(mPtr = PopMatrixPtr(L, 1))) return 0;
|
|
|
|
sprintf(mStr, "{I={x=%.2f,y=%.2f,z=%.2f},J={x=%.2f,y=%.2f,z=%.2f},K={x=%.2f,y=%.2f,z=%.2f},T={x=%.2f,y=%.2f,z=%.2f}}",
|
|
mPtr->I.x, mPtr->I.y, mPtr->I.z, mPtr->J.x, mPtr->J.y, mPtr->J.z, mPtr->K.x, mPtr->K.y, mPtr->K.z, mPtr->T.x, mPtr->T.y, mPtr->T.z);
|
|
|
|
lua_pushstring(L, mStr); return 1;
|
|
}
|
|
|
|
int Matrix_Mul(lua_State *L)
|
|
{
|
|
MATRIX m1, *m2Ptr;
|
|
Vector v1;
|
|
if (!PopMatrix(L, &m1, 1)) return 0;
|
|
if (PopVector(L, &v1, 2))
|
|
{
|
|
v1 = m1*v1;
|
|
PushVector(L, &v1);
|
|
return 1;
|
|
}
|
|
if ((m2Ptr = PopMatrixPtr(L, 2)) != NULL)
|
|
{
|
|
m1 *= *m2Ptr;
|
|
PushMatrix(L, &m1);
|
|
return 1;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
|
|
#define MATRIX_VECTOR_SETGET(Vct) \
|
|
int Matrix_Set##Vct(lua_State *L) \
|
|
{ \
|
|
MATRIX * mPtr = NULL; \
|
|
Vector * vPtr = NULL; \
|
|
if (!(mPtr = PopMatrixPtr(L, 1)) || !(vPtr = PopVectorPtr(L, 2))) return 0; \
|
|
mPtr->Vct = *vPtr; return 1; \
|
|
} \
|
|
int Matrix_Get##Vct(lua_State *L) \
|
|
{ \
|
|
MATRIX * mPtr = NULL; \
|
|
if (!(mPtr = PopMatrixPtr(L, 1))) return 0; \
|
|
PushVector(L, &mPtr->Vct); return 1; \
|
|
} \
|
|
int Matrix_GetPtr##Vct(lua_State *L) \
|
|
{ \
|
|
MATRIX * mPtr = NULL; \
|
|
if (!(mPtr = PopMatrixPtr(L, 1))) return 0; \
|
|
PushVectorPtr(L, &mPtr->Vct); return 1; \
|
|
}
|
|
|
|
|
|
#define MATRIX_VECTOR_DECLARE(Vct) \
|
|
{"Set"#Vct, Matrix_Set##Vct}, \
|
|
{"Get"#Vct, Matrix_Get##Vct}, \
|
|
{"GetPtr"#Vct, Matrix_GetPtr##Vct},
|
|
|
|
#define MATRIX_FLOAT_DECLARE(Vct,Wct) \
|
|
{"Set"#Vct#Wct, Matrix_Set##Vct##Wct}, \
|
|
{"Get"#Vct#Wct, Matrix_Get##Vct##Wct},
|
|
|
|
static const luaL_reg Matrix_meta[] = {
|
|
{"__mul", Matrix_Mul},
|
|
{"__index", Matrix_Index},
|
|
{"__newindex", Matrix_NewIndex},
|
|
{"__tostring", Matrix_ToString},
|
|
{0, 0}
|
|
};
|
|
|
|
|
|
void Matrix_Register(lua_State *L)
|
|
{
|
|
luaL_newmetatable(L, "MATRIX");
|
|
luaL_openlib(L, 0, Matrix_meta, 0); /* fill metatable */
|
|
lua_pushliteral(L, "__metatable");
|
|
lua_pushvalue(L, -3); /* dup methods table*/
|
|
lua_rawset(L, -3); /* hide metatable:
|
|
metatable.__metatable = methods */
|
|
lua_pop(L, 1); /* drop metatable */
|
|
}
|
|
|
|
/*********************** CLASS DEFINITIONS ***********************/
|
|
|
|
/*********************** CONVERSTION FUNCTIONS ***********************/
|
|
|
|
BOOL IsTableBase(lua_State *L)
|
|
{
|
|
BOOL isBase = true;
|
|
int index = 1;
|
|
|
|
lua_pushnil(L); /* first key */
|
|
while (isBase && lua_next(L, -2) != 0)
|
|
{
|
|
isBase = lua_isnumber(L, -2) && lua_tonumber(L, -2) == index;
|
|
index++;
|
|
lua_pop(L, 1);
|
|
}
|
|
if (!isBase)
|
|
lua_pop(L, 1);
|
|
|
|
return isBase;
|
|
}
|
|
|
|
static int curLevel;
|
|
static int maxLevel = 512;
|
|
static void **levelsPtr = NULL;
|
|
//#define EVENT_CONFLICT
|
|
#ifdef EVENT_CONFLICT
|
|
static char **levelsCharsPtr = NULL;
|
|
#endif
|
|
|
|
|
|
char *TableToStringRec(lua_State *L, char *bufferPtr, bool isTableBase, int precision, int *remaningLen)
|
|
{
|
|
BOOL isFirst = true;
|
|
BOOL isNumber;
|
|
char *tmpBufferPtr;
|
|
static char tmpBuffer[2048];
|
|
static void *tmpLevels[512];
|
|
|
|
if (curLevel >= 512)
|
|
return bufferPtr;
|
|
tmpLevels[curLevel] = (void *)lua_topointer(L, -1);
|
|
for (int lvlIdx=0; lvlIdx<curLevel; lvlIdx++)
|
|
{
|
|
if (tmpLevels[lvlIdx] == tmpLevels[curLevel])
|
|
{
|
|
tmpLevels[curLevel] = NULL;
|
|
break;
|
|
}
|
|
}
|
|
if (tmpLevels[curLevel] == NULL)
|
|
{
|
|
if ((*remaningLen) > strlen("rec_val"))
|
|
{
|
|
(*remaningLen) -= strlen("rec_val");
|
|
strcpy(bufferPtr, "rec_val");
|
|
bufferPtr += strlen(bufferPtr);
|
|
} else *remaningLen = 0;
|
|
lua_pop(L, 1);
|
|
return bufferPtr;
|
|
} else
|
|
{
|
|
curLevel++;
|
|
}
|
|
|
|
lua_pushnil(L); /* first key */
|
|
while (lua_next(L, -2) != 0 && *remaningLen > 0 ) {
|
|
/* uses 'key' (at index -2) and 'value' (at index -1) */
|
|
if (lua_isfunction(L, -1))
|
|
{
|
|
lua_pop(L, 1);
|
|
continue;
|
|
}
|
|
|
|
if (isFirst) isFirst = false;
|
|
else {
|
|
if (*remaningLen > strlen(","))
|
|
{
|
|
strcpy(bufferPtr, ","); (*remaningLen)-= strlen(","); bufferPtr += strlen(bufferPtr);
|
|
} else *remaningLen = 0;
|
|
}
|
|
|
|
if (!isTableBase)
|
|
{
|
|
lua_pushvalue(L, -2);
|
|
if ((*remaningLen) > strlen(lua_tostring(L, -1)))
|
|
{
|
|
(*remaningLen) -= strlen(lua_tostring(L, -1)) + 1;
|
|
sprintf(bufferPtr, "%s=", lua_tostring(L, -1));
|
|
bufferPtr += strlen(bufferPtr);
|
|
} else *remaningLen = 0;
|
|
lua_pop(L, 1);
|
|
}
|
|
|
|
if (lua_istable(L, -1))
|
|
{
|
|
if (*remaningLen > strlen("{"))
|
|
{
|
|
strcpy(bufferPtr, "{"); *remaningLen -= strlen(bufferPtr); bufferPtr += strlen(bufferPtr);
|
|
} else *remaningLen = 0;
|
|
bufferPtr = TableToStringRec(L, bufferPtr, IsTableBase(L), precision, remaningLen);
|
|
|
|
if (*remaningLen > strlen("}"))
|
|
{
|
|
strcpy(bufferPtr, "}"); *remaningLen -= strlen(bufferPtr); bufferPtr += strlen(bufferPtr);
|
|
} else *remaningLen = 0;
|
|
} else
|
|
{
|
|
float number = 0;
|
|
tmpBufferPtr = tmpBuffer;
|
|
if (precision >= 0 && lua_isnumber(L, -1))
|
|
{
|
|
number = lua_tonumber(L, -1);
|
|
if (number == (float)((int)number))
|
|
number = 0;
|
|
}
|
|
if (number)
|
|
{
|
|
char precisionStr[64];
|
|
sprintf(precisionStr, "%%.%if", precision);
|
|
sprintf(tmpBuffer, precisionStr, number);
|
|
} else
|
|
{
|
|
if (luaL_callmeta(L, -1, "__tostring"))
|
|
{
|
|
strcpy(tmpBuffer, lua_tostring(L, -1));
|
|
lua_pop(L, 1);
|
|
} else {
|
|
switch (lua_type(L, -1)) {
|
|
case LUA_TNUMBER:
|
|
strcpy(tmpBuffer, lua_tostring(L, -1));
|
|
break;
|
|
case LUA_TSTRING:
|
|
strcpy(tmpBuffer, lua_tostring(L, -1));
|
|
break;
|
|
case LUA_TBOOLEAN:
|
|
strcpy(tmpBuffer, (lua_toboolean(L, -1) ? "true" : "false"));
|
|
break;
|
|
case LUA_TNIL:
|
|
strcpy(tmpBuffer, "nil");
|
|
break;
|
|
default:
|
|
sprintf(tmpBuffer, "%s: %p", luaL_typename(L, -1), lua_topointer(L, -1));
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
if (*remaningLen > strlen(tmpBufferPtr))
|
|
{
|
|
strcpy(bufferPtr, tmpBufferPtr);
|
|
*remaningLen -= strlen(tmpBufferPtr);
|
|
bufferPtr += strlen(bufferPtr);
|
|
} else *remaningLen = 0;
|
|
lua_pop(L, 1);
|
|
}
|
|
}
|
|
lua_pop(L, 1);
|
|
return bufferPtr;
|
|
}
|
|
|
|
int TableToString(lua_State *L, int tableIndex)
|
|
{
|
|
static char buffer[4096];
|
|
int remaningLen = 1920;
|
|
char *bufferPtr = buffer;
|
|
int precision = -1;
|
|
|
|
if (!lua_istable(L, tableIndex))
|
|
{
|
|
if (luaL_callmeta(L, tableIndex, "__tostring"))
|
|
return 1;
|
|
switch (lua_type(L, tableIndex)) {
|
|
case LUA_TNUMBER:
|
|
lua_pushstring(L, lua_tostring(L, tableIndex));
|
|
break;
|
|
case LUA_TSTRING:
|
|
lua_pushvalue(L, tableIndex);
|
|
break;
|
|
case LUA_TBOOLEAN:
|
|
lua_pushstring(L, (lua_toboolean(L, tableIndex) ? "true" : "false"));
|
|
break;
|
|
case LUA_TNIL:
|
|
lua_pushliteral(L, "nil");
|
|
break;
|
|
default:
|
|
lua_pushfstring(L, "%s: %p", luaL_typename(L, tableIndex), lua_topointer(L, 1));
|
|
break;
|
|
}
|
|
return 1;
|
|
}
|
|
if (tableIndex == -2 || lua_gettop(L) == 2)
|
|
{
|
|
precision = luaL_checknumber(L, -1);
|
|
lua_pop(L, 1);
|
|
}
|
|
|
|
strcpy(bufferPtr, "{"); bufferPtr += strlen(bufferPtr);
|
|
curLevel = 0;
|
|
bufferPtr = TableToStringRec(L, bufferPtr, IsTableBase(L), precision, &remaningLen);
|
|
if (remaningLen <= 0)
|
|
{
|
|
strcpy(bufferPtr, "...");
|
|
precision = strlen(buffer);
|
|
}
|
|
else
|
|
strcpy(bufferPtr, "}");
|
|
lua_pushstring(L, buffer);
|
|
return 1;
|
|
}
|
|
|
|
int TableToString(lua_State *L)
|
|
{
|
|
return TableToString(L, 1);
|
|
}
|
|
|
|
/**********************************************************************************************/
|
|
/***** FILE SEARCH ****************************************************************************/
|
|
/**********************************************************************************************/
|
|
int PushSystemTime(lua_State *L, SYSTEMTIME sysTime);
|
|
|
|
int PushFileTime(lua_State *L, FILETIME time)
|
|
{
|
|
SYSTEMTIME sysTime;
|
|
FileTimeToSystemTime(&time, &sysTime);
|
|
|
|
return PushSystemTime(L, sysTime);
|
|
}
|
|
|
|
int PushSystemTime(lua_State *L, SYSTEMTIME sysTime)
|
|
{
|
|
lua_newtable(L);
|
|
lua_pushstring(L, "year");
|
|
lua_pushnumber(L, sysTime.wYear);
|
|
lua_settable(L, -3);
|
|
|
|
lua_pushstring(L, "month");
|
|
lua_pushnumber(L, sysTime.wMonth);
|
|
lua_settable(L, -3);
|
|
|
|
lua_pushstring(L, "day");
|
|
lua_pushnumber(L, sysTime.wDay);
|
|
lua_settable(L, -3);
|
|
|
|
lua_pushstring(L, "hour");
|
|
lua_pushnumber(L, sysTime.wHour);
|
|
lua_settable(L, -3);
|
|
|
|
lua_pushstring(L, "minute");
|
|
lua_pushnumber(L, sysTime.wMinute);
|
|
lua_settable(L, -3);
|
|
|
|
lua_pushstring(L, "second");
|
|
lua_pushnumber(L, sysTime.wSecond);
|
|
lua_settable(L, -3);
|
|
|
|
lua_pushstring(L, "milliseconds");
|
|
lua_pushnumber(L, sysTime.wMilliseconds);
|
|
lua_settable(L, -3);
|
|
|
|
return 1;
|
|
}
|
|
|
|
|
|
bool CheckFocus()
|
|
{
|
|
#ifdef ONLINE_MODE
|
|
// return ((GetFocus() == TheScene->OwnerHwnd) || Account.logInPageHasFocus() || Account.shopHasFocus() || Account.youupPugPageHasFocus() /*|| Account.uploadBrowserHasFocus()*/);
|
|
|
|
bool focusTestOld = (GetFocus() == TheScene->OwnerHwnd) || Account.logInPageHasFocus() || Account.shopHasFocus() || Account.youupPugPageHasFocus() /*|| Account.uploadBrowserHasFocus()*/;
|
|
bool focusTestNew = GetForegroundWindow() == TheScene->OwnerHwnd;
|
|
if (focusTestNew && !focusTestOld)
|
|
SetFocus(TheScene->OwnerHwnd);
|
|
return focusTestNew;
|
|
#else
|
|
return (GetFocus() == TheScene->OwnerHwnd);
|
|
#endif
|
|
}
|
|
|
|
|
|
int EnumFilesRec(lua_State *L, char *dirname, char *ext, BOOL recursiv, BOOL fullInfo)
|
|
{
|
|
char dirSearch[1024];
|
|
char fileExt[64];
|
|
HANDLE fileFind;
|
|
WIN32_FIND_DATA fileData;
|
|
|
|
sprintf(dirSearch, "%s\\*.*", dirname);
|
|
fileFind = FindFirstFile(dirSearch, &fileData);
|
|
|
|
if (fileFind == INVALID_HANDLE_VALUE) return 0;
|
|
|
|
int index = 1;
|
|
do {
|
|
if (fileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
|
|
{
|
|
if (recursiv && strcmp(".", fileData.cFileName) && strcmp("..", fileData.cFileName))
|
|
{
|
|
char dirNameIn[1024];
|
|
sprintf(dirNameIn, "%s\\%s", dirname, fileData.cFileName);
|
|
lua_pushstring(L, fileData.cFileName);
|
|
lua_newtable(L);
|
|
EnumFilesRec(L, dirNameIn, ext, recursiv, fullInfo);
|
|
lua_settable(L, -3);
|
|
}
|
|
} else
|
|
{
|
|
if (ext)
|
|
{
|
|
strcpy(fileExt, fileData.cFileName + strlen(fileData.cFileName) - strlen(ext));
|
|
strlwr(fileExt);
|
|
if (strcmp(fileExt, ext))
|
|
continue;
|
|
}
|
|
lua_pushinteger(L, index++);
|
|
|
|
if (fullInfo)
|
|
{
|
|
lua_newtable(L);
|
|
lua_pushfstring(L, "name");
|
|
lua_pushfstring(L, fileData.cFileName);
|
|
lua_settable(L, -3);
|
|
|
|
lua_pushfstring(L, "creationTime");
|
|
PushFileTime(L, fileData.ftCreationTime);
|
|
lua_settable(L, -3);
|
|
|
|
lua_pushfstring(L, "writeTime");
|
|
PushFileTime(L, fileData.ftLastWriteTime);
|
|
lua_settable(L, -3);
|
|
|
|
lua_pushfstring(L, "size");
|
|
lua_pushnumber(L, fileData.nFileSizeLow);
|
|
lua_settable(L, -3);
|
|
} else
|
|
{
|
|
lua_pushfstring(L, fileData.cFileName);
|
|
}
|
|
lua_settable(L, -3);
|
|
}
|
|
} while (FindNextFile(fileFind, &fileData));
|
|
return 1;
|
|
}
|
|
|
|
|
|
int EnumFiles(lua_State *L)
|
|
{
|
|
if (lua_gettop(L) < 1 || !lua_tostring(L, 1))
|
|
return 0;
|
|
|
|
char *dirname = (char *)lua_tostring(L, 1);
|
|
char extData[128];
|
|
char *ext = NULL;
|
|
int recursiv = 0;
|
|
int fullInfo = 0;
|
|
|
|
if (lua_gettop(L) > 1)
|
|
recursiv = (int)lua_tonumber(L, 2);
|
|
if (lua_gettop(L) > 2 && lua_tostring(L, 3) && *lua_tostring(L, 3))
|
|
{
|
|
strcpy(extData, lua_tostring(L, 3));
|
|
strlwr(extData);
|
|
ext = extData;
|
|
}
|
|
if (lua_gettop(L) > 3)
|
|
fullInfo = lua_tonumber(L, 4);
|
|
|
|
lua_newtable(L);
|
|
EnumFilesRec(L, dirname, ext, recursiv, fullInfo);
|
|
return 1;
|
|
}
|
|
|
|
|
|
|
|
/**********************************************************************************************/
|
|
/***** INI VALUE ******************************************************************************/
|
|
/**********************************************************************************************/
|
|
extern char CamcamCCM[];
|
|
|
|
int IniLoad(lua_State *L)
|
|
{
|
|
int nbArgs = lua_gettop(L);
|
|
int saveRet;
|
|
switch (nbArgs)
|
|
{
|
|
case 0 :
|
|
saveRet = TheScene->LoadIniFile(CamcamCCM);
|
|
lua_pushboolean(L, saveRet >= 0);
|
|
return 1;
|
|
break;
|
|
default :
|
|
if(lua_isstring(L,1))
|
|
{
|
|
char destFile[2048] = "";
|
|
strcpy(destFile, lua_tostring(L, 1));
|
|
destFile[strlen(lua_tostring(L, 1))] = 0;
|
|
if(strlen(destFile)<4 || strcmp(".ccm", strlwr(destFile+strlen(destFile)-4))!=0)
|
|
{
|
|
strcpy(destFile, lua_tostring(L, 1));
|
|
destFile[strlen(lua_tostring(L, 1))] = 0;
|
|
strcat(destFile, ".ccm");
|
|
destFile[4+strlen(lua_tostring(L, 1))] = 0;
|
|
}
|
|
else
|
|
{
|
|
strcpy(destFile, lua_tostring(L, 1));
|
|
destFile[strlen(lua_tostring(L, 1))] = 0;
|
|
}
|
|
saveRet = TheScene->LoadIniFile(destFile);
|
|
lua_pushboolean(L, saveRet >= 0);
|
|
return 1;
|
|
}
|
|
else
|
|
{
|
|
lua_pushboolean(L, false);
|
|
return 1;
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
|
|
|
|
int IniSave(lua_State *L)
|
|
{
|
|
int nbArgs = lua_gettop(L);
|
|
int saveRet;
|
|
switch (nbArgs)
|
|
{
|
|
case 0 :
|
|
saveRet = TheScene->SaveIniFile(CamcamCCM);
|
|
lua_pushboolean(L, saveRet >= 0);
|
|
return 1;
|
|
break;
|
|
default :
|
|
if(lua_isstring(L,1))
|
|
{
|
|
char destFile[2048] = "";
|
|
strcpy(destFile, lua_tostring(L, 1));
|
|
destFile[strlen(lua_tostring(L, 1))] = 0;
|
|
if(strlen(destFile)<4 || strcmp(".ccm", strlwr(destFile+strlen(destFile)-4))!=0)
|
|
{
|
|
strcpy(destFile, lua_tostring(L, 1));
|
|
destFile[strlen(lua_tostring(L, 1))] = 0;
|
|
strcat(destFile, ".ccm");
|
|
destFile[4+strlen(lua_tostring(L, 1))] = 0;
|
|
}
|
|
else
|
|
{
|
|
strcpy(destFile, lua_tostring(L, 1));
|
|
destFile[strlen(lua_tostring(L, 1))] = 0;
|
|
}
|
|
saveRet = TheScene->SaveIniFile(destFile);
|
|
lua_pushboolean(L, saveRet >= 0);
|
|
return 1;
|
|
}
|
|
else
|
|
{
|
|
lua_pushboolean(L, false);
|
|
return 1;
|
|
}
|
|
break;
|
|
}
|
|
|
|
}
|
|
|
|
int IniDestroy(lua_State *L)
|
|
{
|
|
int nbArgs = lua_gettop(L);
|
|
int saveRet;
|
|
switch (nbArgs)
|
|
{
|
|
case 0 :
|
|
saveRet = TheScene->DestroyIniFile(CamcamCCM);
|
|
lua_pushboolean(L, saveRet >= 0);
|
|
return 1;
|
|
default :
|
|
saveRet = TheScene->DestroyIniFile((char *)luaL_checkstring(L,1));
|
|
lua_pushboolean(L, saveRet >= 0);
|
|
return 1;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
int IniValueDel(lua_State *L)
|
|
{
|
|
char iniFile[2048];
|
|
strcpy(iniFile, CamcamCCM);
|
|
|
|
if(lua_gettop(L)==0 || (lua_gettop(L)>0 && !lua_isstring(L,1))) return false;
|
|
|
|
char completedVarname[2048] = ".";
|
|
if(lua_tostring(L,1)[0]!='.')
|
|
{
|
|
strcat(completedVarname, lua_tostring(L,1));
|
|
completedVarname[strlen(lua_tostring(L,1))+1] = 0;
|
|
}
|
|
else
|
|
{
|
|
strcpy(completedVarname, lua_tostring(L,1));
|
|
}
|
|
|
|
if(lua_gettop(L)==2)
|
|
{
|
|
if(!lua_isstring(L,2)) return false;
|
|
|
|
strcpy(iniFile, lua_tostring(L, 2));
|
|
iniFile[strlen(lua_tostring(L, 2))] = 0;
|
|
if(strlen(iniFile)<4 || strcmp(".ccm", strlwr(iniFile+strlen(iniFile)-4))!=0)
|
|
{
|
|
strcpy(iniFile, lua_tostring(L, 2));
|
|
iniFile[strlen(lua_tostring(L, 2))] = 0;
|
|
strcat(iniFile, ".ccm");
|
|
iniFile[4+strlen(lua_tostring(L, 2))] = 0;
|
|
}
|
|
else
|
|
{
|
|
strcpy(iniFile, lua_tostring(L, 2));
|
|
iniFile[strlen(lua_tostring(L, 2))] = 0;
|
|
}
|
|
}
|
|
|
|
if (TheScene->IniFileDico.IsExist(iniFile) == -1 && TheScene->LoadIniFile(iniFile) == -1)
|
|
return false;
|
|
|
|
u32 ID;
|
|
UnicID mUID;
|
|
TheScene->IniFileDico.GetUnic(&mUID,iniFile);
|
|
ID = TheScene->IniFileDico.mpst_Dico[mUID].AssociatedValue;
|
|
INIFILE* inifile = &(TheScene->IniFiles[ID]);
|
|
|
|
if(inifile->variableDico.IsExist(completedVarname)!=-1)
|
|
{
|
|
inifile->delVariable(completedVarname);
|
|
return true;
|
|
}
|
|
if(strcmp(completedVarname,".")==0)
|
|
{
|
|
u32 currentChild = inifile->root;
|
|
u32 nextChild = -1;
|
|
while(currentChild!=-1)
|
|
{
|
|
nextChild = inifile->variables[currentChild].next;
|
|
inifile->delVariable(inifile->variables[currentChild].name);
|
|
currentChild = nextChild;
|
|
}
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
int IniValueDelOld(lua_State *L)
|
|
{
|
|
char iniFile[2048] = "Camcam.ini";
|
|
|
|
if(lua_gettop(L)==0 || (lua_gettop(L)>0 && !lua_isstring(L,1))) return false;
|
|
|
|
char completedVarname[2048] = ".";
|
|
if(lua_tostring(L,1)[0]!='.')
|
|
{
|
|
strcat(completedVarname, lua_tostring(L,1));
|
|
completedVarname[strlen(lua_tostring(L,1))+1] = 0;
|
|
}
|
|
else
|
|
{
|
|
strcpy(completedVarname, lua_tostring(L,1));
|
|
}
|
|
|
|
if(lua_gettop(L)==2)
|
|
{
|
|
if(!lua_isstring(L,2)) return false;
|
|
|
|
strcpy(iniFile, lua_tostring(L, 2));
|
|
iniFile[strlen(lua_tostring(L, 2))] = 0;
|
|
if(strlen(iniFile)<4 || strcmp(".ini", strlwr(iniFile+strlen(iniFile)-4))!=0)
|
|
{
|
|
strcpy(iniFile, lua_tostring(L, 2));
|
|
iniFile[strlen(lua_tostring(L, 2))] = 0;
|
|
strcat(iniFile, ".ini");
|
|
iniFile[4+strlen(lua_tostring(L, 2))] = 0;
|
|
}
|
|
else
|
|
{
|
|
strcpy(iniFile, lua_tostring(L, 2));
|
|
iniFile[strlen(lua_tostring(L, 2))] = 0;
|
|
}
|
|
}
|
|
|
|
if (TheScene->IniFileDico.IsExist(iniFile) == -1 && TheScene->LoadIniFile(iniFile) == -1)
|
|
return false;
|
|
|
|
u32 ID;
|
|
UnicID mUID;
|
|
TheScene->IniFileDico.GetUnic(&mUID,iniFile);
|
|
ID = TheScene->IniFileDico.mpst_Dico[mUID].AssociatedValue;
|
|
INIFILE* inifile = &(TheScene->IniFiles[ID]);
|
|
|
|
if(inifile->variableDico.IsExist(completedVarname)!=-1)
|
|
{
|
|
inifile->delVariable(completedVarname);
|
|
return true;
|
|
}
|
|
if(strcmp(completedVarname,".")==0)
|
|
{
|
|
u32 currentChild = inifile->root;
|
|
while(currentChild!=-1)
|
|
{
|
|
inifile->delVariable(inifile->variables[currentChild].name);
|
|
currentChild = inifile->variables[currentChild].next;
|
|
}
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
void IniValueGetRec(lua_State *L, INI_VARIABLE* variables, u32 ID)
|
|
{
|
|
if(variables[ID].child==-1)
|
|
{
|
|
bool knownFound = false;
|
|
if(strlen(variables[ID].value)>=3)
|
|
{
|
|
if(strcmp(" #s", variables[ID].value+strlen(variables[ID].value)-3)==0)
|
|
{
|
|
char value[2048];
|
|
strcpy(value, variables[ID].value);
|
|
value[strlen(variables[ID].value)-3] = 0;
|
|
PushString(L, value);
|
|
knownFound = true;
|
|
}
|
|
if(strcmp(" #b", variables[ID].value+strlen(variables[ID].value)-3)==0)
|
|
{
|
|
if(strcmp("true #b", variables[ID].value)==0)
|
|
{
|
|
PushBool(L, true);
|
|
}
|
|
else
|
|
{
|
|
PushBool(L, false);
|
|
}
|
|
knownFound = true;
|
|
}
|
|
if(strcmp(" #n", variables[ID].value+strlen(variables[ID].value)-3)==0)
|
|
{
|
|
char value[2048];
|
|
strcpy(value, variables[ID].value);
|
|
value[strlen(variables[ID].value)-3] = 0;
|
|
lua_pushnumber(L, (double)atof(value));
|
|
knownFound = true;
|
|
}
|
|
if(strcmp(" #v", variables[ID].value+strlen(variables[ID].value)-3)==0)
|
|
{
|
|
char value[2048];
|
|
strcpy(value, variables[ID].value);
|
|
value[strlen(variables[ID].value)-3] = 0;
|
|
PushVector(L, value);
|
|
knownFound = true;
|
|
}
|
|
if(strcmp(" #m", variables[ID].value+strlen(variables[ID].value)-3)==0)
|
|
{
|
|
char value[2048];
|
|
strcpy(value, variables[ID].value);
|
|
value[strlen(variables[ID].value)-3] = 0;
|
|
PushMatrix(L, value);
|
|
knownFound = true;
|
|
}
|
|
if(strcmp(" #q", variables[ID].value+strlen(variables[ID].value)-3)==0)
|
|
{
|
|
char value[2048];
|
|
strcpy(value, variables[ID].value);
|
|
value[strlen(variables[ID].value)-3] = 0;
|
|
PushQuat(L, value);
|
|
knownFound = true;
|
|
}
|
|
if(strcmp("nil #0", variables[ID].value)==0)
|
|
{
|
|
lua_pushnil(L);
|
|
knownFound = true;
|
|
}
|
|
if(strcmp("{} #0", variables[ID].value)==0)
|
|
{
|
|
lua_newtable(L);
|
|
knownFound = true;
|
|
}
|
|
}
|
|
if(!knownFound)
|
|
{
|
|
char value[2048];
|
|
strcpy(value, variables[ID].value);
|
|
PushString(L, value);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
lua_newtable(L);
|
|
u32 currentChild = variables[ID].child;
|
|
do
|
|
{
|
|
char key[2048] = "";
|
|
strcpy(key, strrchr(variables[currentChild].name, '.')+1);
|
|
if(key[strlen(key)-1]=='#')
|
|
{
|
|
key[strlen(key)-1] = 0;
|
|
lua_pushnumber(L, atoi(key));
|
|
}
|
|
else
|
|
{
|
|
PushString(L, key);
|
|
}
|
|
IniValueGetRec(L, variables, currentChild);
|
|
lua_settable(L,-3);
|
|
currentChild = variables[currentChild].next;
|
|
}
|
|
while(currentChild!=-1);
|
|
}
|
|
}
|
|
|
|
int DoIniValueGet(lua_State *L/*, bool fromServer*/)
|
|
{
|
|
char iniFile[2048];
|
|
strcpy(iniFile, CamcamCCM);
|
|
|
|
if(lua_gettop(L)==0 || (lua_gettop(L)>0 && !lua_isstring(L,1))) return false;
|
|
|
|
char completedVarname[2048] = ".";
|
|
if(lua_tostring(L,1)[0]!='.')
|
|
{
|
|
strcat(completedVarname, lua_tostring(L,1));
|
|
completedVarname[strlen(lua_tostring(L,1))+1] = 0;
|
|
}
|
|
else
|
|
{
|
|
strcpy(completedVarname, lua_tostring(L,1));
|
|
}
|
|
|
|
if(lua_gettop(L)==3)
|
|
{
|
|
if(!lua_isstring(L,3)) return false;
|
|
|
|
strcpy(iniFile, lua_tostring(L, 3));
|
|
iniFile[strlen(lua_tostring(L, 3))] = 0;
|
|
if(strlen(iniFile)<4 || strcmp(".ccm", strlwr(iniFile+strlen(iniFile)-4))!=0)
|
|
{
|
|
strcpy(iniFile, lua_tostring(L, 3));
|
|
iniFile[strlen(lua_tostring(L, 3))] = 0;
|
|
strcat(iniFile, ".ccm");
|
|
iniFile[4+strlen(lua_tostring(L, 3))] = 0;
|
|
}
|
|
else
|
|
{
|
|
strcpy(iniFile, lua_tostring(L, 3));
|
|
iniFile[strlen(lua_tostring(L, 3))] = 0;
|
|
}
|
|
}
|
|
|
|
if (TheScene->IniFileDico.IsExist(iniFile) == -1 && TheScene->LoadIniFile(iniFile) == -1)
|
|
{
|
|
if(lua_gettop(L)==1) lua_pushnil(L);
|
|
else lua_pushvalue(L, 2);
|
|
return true;
|
|
}
|
|
|
|
u32 ID;
|
|
UnicID mUID;
|
|
TheScene->IniFileDico.GetUnic(&mUID,iniFile);
|
|
ID = TheScene->IniFileDico.mpst_Dico[mUID].AssociatedValue;
|
|
INIFILE* inifile = &(TheScene->IniFiles[ID]);
|
|
|
|
if(inifile->variableDico.IsExist(completedVarname)!=-1)
|
|
{
|
|
inifile->variableDico.GetUnic(&mUID,completedVarname);
|
|
ID = inifile->variableDico.mpst_Dico[mUID].AssociatedValue;
|
|
IniValueGetRec(L, inifile->variables, ID);
|
|
return true;
|
|
}
|
|
if (strcmp(completedVarname,".")==0)
|
|
{
|
|
lua_newtable(L);
|
|
u32 currentChild = inifile->root;
|
|
while(currentChild!=-1)
|
|
{
|
|
char key[2048] = "";
|
|
strcpy(key, strrchr(inifile->variables[currentChild].name, '.')+1);
|
|
if(key[strlen(key)-1]=='#')
|
|
{
|
|
key[strlen(key)-1] = 0;
|
|
lua_pushnumber(L, atoi(key));
|
|
}
|
|
else
|
|
{
|
|
PushString(L, key);
|
|
}
|
|
IniValueGetRec(L, inifile->variables, currentChild);
|
|
lua_settable(L,-3);
|
|
currentChild = inifile->variables[currentChild].next;
|
|
}
|
|
return true;
|
|
}
|
|
if(lua_gettop(L)==1) lua_pushnil(L);
|
|
else lua_pushvalue(L, 2);
|
|
|
|
return true;
|
|
}
|
|
|
|
int IniValueGet(lua_State *L)
|
|
{
|
|
return DoIniValueGet(L/*, false*/);
|
|
}
|
|
|
|
//int IniValueGetFromServer(lua_State *L)
|
|
//{
|
|
// return DoIniValueGet(L, true);
|
|
//}
|
|
|
|
|
|
int IniValueGetOld(lua_State *L)
|
|
{
|
|
char iniFile[2048] = "Camcam.ini";
|
|
|
|
if(lua_gettop(L)==0 || (lua_gettop(L)>0 && !lua_isstring(L,1))) return false;
|
|
|
|
char completedVarname[2048] = ".";
|
|
if(lua_tostring(L,1)[0]!='.')
|
|
{
|
|
strcat(completedVarname, lua_tostring(L,1));
|
|
completedVarname[strlen(lua_tostring(L,1))+1] = 0;
|
|
}
|
|
else
|
|
{
|
|
strcpy(completedVarname, lua_tostring(L,1));
|
|
}
|
|
|
|
if(lua_gettop(L)==3)
|
|
{
|
|
if(!lua_isstring(L,3)) return false;
|
|
|
|
strcpy(iniFile, lua_tostring(L, 3));
|
|
iniFile[strlen(lua_tostring(L, 3))] = 0;
|
|
if(strlen(iniFile)<4 || strcmp(".ini", strlwr(iniFile+strlen(iniFile)-4))!=0)
|
|
{
|
|
strcpy(iniFile, lua_tostring(L, 3));
|
|
iniFile[strlen(lua_tostring(L, 3))] = 0;
|
|
strcat(iniFile, ".ini");
|
|
iniFile[4+strlen(lua_tostring(L, 3))] = 0;
|
|
}
|
|
else
|
|
{
|
|
strcpy(iniFile, lua_tostring(L, 3));
|
|
iniFile[strlen(lua_tostring(L, 3))] = 0;
|
|
}
|
|
}
|
|
|
|
if (TheScene->IniFileDico.IsExist(iniFile) == -1 && TheScene->LoadIniFile(iniFile) == -1)
|
|
return false;
|
|
|
|
u32 ID;
|
|
UnicID mUID;
|
|
TheScene->IniFileDico.GetUnic(&mUID,iniFile);
|
|
ID = TheScene->IniFileDico.mpst_Dico[mUID].AssociatedValue;
|
|
INIFILE* inifile = &(TheScene->IniFiles[ID]);
|
|
|
|
if(inifile->variableDico.IsExist(completedVarname)!=-1)
|
|
{
|
|
inifile->variableDico.GetUnic(&mUID,completedVarname);
|
|
ID = inifile->variableDico.mpst_Dico[mUID].AssociatedValue;
|
|
IniValueGetRec(L, inifile->variables, ID);
|
|
return true;
|
|
}
|
|
if(lua_gettop(L)==1) lua_pushnil(L);
|
|
else lua_pushvalue(L, 2);
|
|
|
|
return true;
|
|
}
|
|
|
|
void IniValueSetRec(lua_State *L, char* parentName, char* inifile)
|
|
{
|
|
if(!lua_istable(L,-1))
|
|
{
|
|
char* iniVarname = (char*)ZeroAlloc(strlen(parentName)+1+1);
|
|
strcpy(iniVarname,parentName);
|
|
strcat(iniVarname, ".");
|
|
if(lua_type(L, -2)==LUA_TSTRING)
|
|
{
|
|
iniVarname = (char*)CC_realloc(iniVarname, 1+strlen(parentName)+1+strlen(lua_tostring(L,-2)));
|
|
strcat(iniVarname, lua_tostring(L,-2));
|
|
iniVarname[strlen(parentName)+1+strlen(lua_tostring(L,-2))] = 0;
|
|
}
|
|
else
|
|
{
|
|
lua_pushvalue(L,-2);
|
|
iniVarname = (char*)CC_realloc(iniVarname, 1+1+strlen(parentName)+1+strlen(lua_tostring(L,-1)));
|
|
strcat(iniVarname, lua_tostring(L,-1));
|
|
strcat(iniVarname, "#");
|
|
iniVarname[1+strlen(parentName)+1+strlen(lua_tostring(L,-1))] = 0;
|
|
lua_pop(L,1);
|
|
}
|
|
|
|
char* value = 0;
|
|
switch (lua_type(L,-1))
|
|
{
|
|
case LUA_TNUMBER:
|
|
{
|
|
value = (char*)ZeroAlloc(3+strlen(lua_tostring(L,-1))+1);
|
|
lua_pushvalue(L,-1);
|
|
strcpy(value, lua_tostring(L,-1));
|
|
strcat(value, " #n");
|
|
value[3+strlen(lua_tostring(L,-1))] = 0;
|
|
lua_pop(L,1);
|
|
TheScene->SetIniValue(inifile, iniVarname, value);
|
|
}
|
|
break;
|
|
case LUA_TSTRING:
|
|
{
|
|
value = (char*)ZeroAlloc(3+strlen(lua_tostring(L,-1))+1);
|
|
strcpy(value, lua_tostring(L,-1));
|
|
//strcat(value, " #s");
|
|
value[3+strlen(lua_tostring(L,-1))] = 0;
|
|
TheScene->SetIniValue(inifile, iniVarname, value);
|
|
}
|
|
break;
|
|
case LUA_TBOOLEAN:
|
|
{
|
|
value = (char*)ZeroAlloc(3+strlen((lua_toboolean(L, -1) ? "true" : "false"))+1);
|
|
strcpy(value, (lua_toboolean(L, -1) ? "true" : "false"));
|
|
strcat(value, " #b");
|
|
value[3+strlen((lua_toboolean(L, -1) ? "true" : "false"))] = 0;
|
|
TheScene->SetIniValue(inifile, iniVarname, value);
|
|
}
|
|
break;
|
|
case LUA_TNIL:
|
|
{
|
|
value = (char*)ZeroAlloc(strlen("nil #0")+1);
|
|
strcpy(value, "nil #0");
|
|
value[6] = 0;
|
|
TheScene->SetIniValue(inifile, iniVarname, value);
|
|
}
|
|
break;
|
|
default:
|
|
{
|
|
void *p = lua_touserdata(L, -1);
|
|
if (p != NULL)
|
|
{
|
|
if (lua_getmetatable(L, -1))
|
|
{
|
|
lua_getfield(L, LUA_REGISTRYINDEX, "VECTOR");
|
|
if (lua_rawequal(L, -1, -2))
|
|
{
|
|
lua_pop(L, 2);
|
|
luaL_callmeta(L, -1, "__tostring");
|
|
value = (char*)ZeroAlloc(strlen(lua_tostring(L, -1))+3+1);
|
|
strcpy(value, lua_tostring(L, -1));
|
|
strcat(value, " #v\0");
|
|
TheScene->SetIniValue(inifile, iniVarname, value);
|
|
lua_pop(L,1);
|
|
}
|
|
else
|
|
{
|
|
lua_pop(L, 2);
|
|
}
|
|
}
|
|
if (lua_getmetatable(L, -1))
|
|
{
|
|
lua_getfield(L, LUA_REGISTRYINDEX, "MATRIX");
|
|
if (lua_rawequal(L, -1, -2))
|
|
{
|
|
lua_pop(L, 2);
|
|
luaL_callmeta(L, -1, "__tostring");
|
|
value = (char*)ZeroAlloc(strlen(lua_tostring(L, -1))+3+1);
|
|
strcpy(value, lua_tostring(L, -1));
|
|
strcat(value, " #m\0");
|
|
TheScene->SetIniValue(inifile, iniVarname, value);
|
|
lua_pop(L,1);
|
|
}
|
|
else
|
|
{
|
|
lua_pop(L, 2);
|
|
}
|
|
}
|
|
if (lua_getmetatable(L, -1))
|
|
{
|
|
lua_getfield(L, LUA_REGISTRYINDEX, "QUAT");
|
|
if (lua_rawequal(L, -1, -2))
|
|
{
|
|
lua_pop(L, 2);
|
|
luaL_callmeta(L, -1, "__tostring");
|
|
value = (char*)ZeroAlloc(strlen(lua_tostring(L, -1))+3+1);
|
|
strcpy(value, lua_tostring(L, -1));
|
|
strcat(value, " #q\0");
|
|
TheScene->SetIniValue(inifile, iniVarname, value);
|
|
lua_pop(L,1);
|
|
}
|
|
else
|
|
{
|
|
lua_pop(L, 2);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
if (value) CC_free(value);
|
|
if (iniVarname) CC_free(iniVarname);
|
|
}
|
|
else
|
|
{
|
|
char* iniVarname = (char*)ZeroAlloc(1+strlen(parentName)+1);
|
|
strcpy(iniVarname,parentName);
|
|
strcat(iniVarname, ".");
|
|
lua_pushvalue(L,-2);
|
|
if(lua_type(L, -1)==LUA_TSTRING)
|
|
{
|
|
iniVarname = (char*)CC_realloc(iniVarname, 1+strlen(parentName)+1+strlen(lua_tostring(L,-1))+1);
|
|
strcat(iniVarname, lua_tostring(L,-1));
|
|
iniVarname[strlen(parentName)+1+strlen(lua_tostring(L,-1))] = 0;
|
|
}
|
|
else
|
|
{
|
|
iniVarname = (char*)CC_realloc(iniVarname, 1+strlen(parentName)+1+strlen(lua_tostring(L,-1))+1);
|
|
strcat(iniVarname, lua_tostring(L,-1));
|
|
strcat(iniVarname, "#");
|
|
iniVarname[1+strlen(parentName)+1+strlen(lua_tostring(L,-1))] = 0;
|
|
}
|
|
lua_pop(L,1);
|
|
|
|
TheScene->SetIniValue(inifile, iniVarname, ""); //iniVarname = prochain parent
|
|
lua_pushnil(L);
|
|
bool atLeastOne = false;
|
|
while (lua_next(L, -2) != 0)
|
|
{
|
|
atLeastOne = true;
|
|
IniValueSetRec(L, iniVarname, inifile);
|
|
}
|
|
if(!atLeastOne) TheScene->SetIniValue(inifile, iniVarname, "{} #0");
|
|
CC_free(iniVarname);
|
|
}
|
|
lua_pop(L,1);
|
|
}
|
|
|
|
int IniValueSet(lua_State *L)
|
|
{
|
|
char iniFile[1024];
|
|
strcpy(iniFile, CamcamCCM);
|
|
|
|
int s = lua_gettop(L);
|
|
|
|
if(lua_gettop(L)==0 || (lua_gettop(L)>0 && !lua_isstring(L,1))) return false;
|
|
|
|
char* completedVarname = (char*)ZeroAlloc(2048);
|
|
strcpy(completedVarname, ".");
|
|
if(lua_tostring(L,1)[0]!='.')
|
|
{
|
|
if (strlen(lua_tostring(L,1))+strlen(completedVarname)+1 > 2048)
|
|
{
|
|
completedVarname = (char*)CC_realloc(completedVarname, strlen(lua_tostring(L,1))+strlen(completedVarname))+1;
|
|
}
|
|
strcat(completedVarname, lua_tostring(L,1));
|
|
completedVarname[strlen(lua_tostring(L,1))+1] = 0;
|
|
}
|
|
else
|
|
{
|
|
if (strlen(lua_tostring(L,1))+1 > 2048)
|
|
{
|
|
completedVarname = (char*)CC_realloc(completedVarname, strlen(lua_tostring(L,1))+1);
|
|
}
|
|
strcpy(completedVarname, lua_tostring(L,1));
|
|
}
|
|
char* posPtr = strrchr(completedVarname, '.');
|
|
int pos = posPtr-completedVarname;
|
|
char* parent = (char*)ZeroAlloc(pos+1);
|
|
strncpy(parent, completedVarname, pos);
|
|
parent[pos] = 0;
|
|
|
|
char* varName = (char*)ZeroAlloc(strlen(completedVarname)-pos+1);
|
|
strncpy(varName, completedVarname+pos+1, strlen(completedVarname)-pos);
|
|
|
|
if(lua_gettop(L)==3)
|
|
{
|
|
if(!lua_isstring(L,3)) return false;
|
|
|
|
strcpy(iniFile, lua_tostring(L, 3));
|
|
if(strlen(iniFile)<4 || strcmp(".ccm", strlwr(iniFile+strlen(iniFile)-4))!=0)
|
|
{
|
|
strcpy(iniFile, lua_tostring(L, 3));
|
|
iniFile[strlen(lua_tostring(L, 3))] = 0;
|
|
strcat(iniFile, ".ccm");
|
|
iniFile[4+strlen(lua_tostring(L, 3))] = 0;
|
|
}
|
|
}
|
|
|
|
if (*varName)
|
|
{
|
|
if(lua_gettop(L)==1)
|
|
{
|
|
lua_pushstring(L, varName);
|
|
lua_pushstring(L, "1");
|
|
}
|
|
else
|
|
{
|
|
lua_pushstring(L, varName);
|
|
lua_pushvalue(L, 2);
|
|
}
|
|
IniValueSetRec(L, parent, iniFile);
|
|
|
|
CC_free(completedVarname);
|
|
CC_free(parent);
|
|
CC_free(varName);
|
|
|
|
return false;
|
|
}
|
|
else
|
|
{
|
|
if(lua_gettop(L)!=1 && (lua_istable(L,2)))
|
|
{
|
|
lua_pushnil(L);
|
|
while (lua_next(L, 2) != 0)
|
|
{
|
|
IniValueSetRec(L, parent, iniFile);
|
|
}
|
|
|
|
CC_free(completedVarname);
|
|
CC_free(parent);
|
|
CC_free(varName);
|
|
|
|
return false;
|
|
}
|
|
else
|
|
{
|
|
CC_free(completedVarname);
|
|
CC_free(parent);
|
|
CC_free(varName);
|
|
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
|
|
int IniValueSetOld(lua_State *L)
|
|
{
|
|
char iniFile[2048] = "Camcam.ini";
|
|
|
|
if(lua_gettop(L)==0 || (lua_gettop(L)>0 && !lua_isstring(L,1))) return false;
|
|
|
|
char completedVarname[2048] = ".";
|
|
if(lua_tostring(L,1)[0]!='.')
|
|
{
|
|
strcat(completedVarname, lua_tostring(L,1));
|
|
completedVarname[strlen(lua_tostring(L,1))+1] = 0;
|
|
}
|
|
else
|
|
{
|
|
strcpy(completedVarname, lua_tostring(L,1));
|
|
}
|
|
char* posPtr = strrchr(completedVarname, '.');
|
|
int pos = posPtr-completedVarname;
|
|
char parent[2048] = "";
|
|
strncpy(parent, completedVarname, pos);
|
|
parent[pos] = 0;
|
|
|
|
char varName[2048] = "";
|
|
strncpy(varName, completedVarname+pos+1, strlen(completedVarname)-pos);
|
|
|
|
if(lua_gettop(L)==3)
|
|
{
|
|
if(!lua_isstring(L,3)) return false;
|
|
|
|
strcpy(iniFile, lua_tostring(L, 3));
|
|
iniFile[strlen(lua_tostring(L, 3))] = 0;
|
|
if(strlen(iniFile)<4 || strcmp(".ini", strlwr(iniFile+strlen(iniFile)-4))!=0)
|
|
{
|
|
strcpy(iniFile, lua_tostring(L, 3));
|
|
iniFile[strlen(lua_tostring(L, 3))] = 0;
|
|
strcat(iniFile, ".ini");
|
|
iniFile[4+strlen(lua_tostring(L, 3))] = 0;
|
|
}
|
|
else
|
|
{
|
|
strcpy(iniFile, lua_tostring(L, 3));
|
|
iniFile[strlen(lua_tostring(L, 3))] = 0;
|
|
}
|
|
}
|
|
|
|
if(lua_gettop(L)==1)
|
|
{
|
|
lua_pushstring(L, varName);
|
|
lua_pushstring(L, "1");
|
|
}
|
|
else
|
|
{
|
|
lua_pushstring(L, varName);
|
|
lua_pushvalue(L, 2);
|
|
}
|
|
|
|
char value[2048];
|
|
strcpy(value, lua_tostring(L,-1));
|
|
TheScene->SetIniValue(iniFile, varName, value);
|
|
TheScene->SaveIniFile(iniFile);
|
|
return false;
|
|
}
|
|
|
|
/****************************************************/
|
|
// Note: returns an empty string in case of error; max len of string : 2047.
|
|
std::string GetRegistryValueStr(HKEY rootKey, const char *subKey, const char *name)
|
|
{
|
|
HKEY key;
|
|
if (RegOpenKeyEx(rootKey, subKey, 0, KEY_READ, &key) != ERROR_SUCCESS)
|
|
return std::string();
|
|
char str[2048] = "";
|
|
DWORD strType = NULL;
|
|
DWORD strLen = 2048;
|
|
DWORD error = RegQueryValueEx(key, name, 0, &strType, (BYTE *)str, &strLen);
|
|
|
|
/************************ DEBUG BEGINS HERE *************************/
|
|
/*
|
|
char info[2048] = "";
|
|
sprintf(info, "error=%u", error);
|
|
MessageBox(NULL, info, "Info", MB_OK);
|
|
//*/
|
|
/*
|
|
if (error!=ERROR_SUCCESS)
|
|
{
|
|
char info[2048] = "";
|
|
wchar_t Winfo[2048];
|
|
DWORD err = error; //GetLastError();
|
|
FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, err,
|
|
LANG_NEUTRAL, info, sizeof(Winfo)/sizeof(wchar_t), NULL);
|
|
wcstombs(info,Winfo,2048-1);
|
|
strcat(info, " : ");
|
|
strcat(info, str);
|
|
MessageBox(NULL, info, "Info", MB_OK);
|
|
}
|
|
//*/
|
|
/************************* DEBUG ENDS HERE **************************/
|
|
|
|
RegCloseKey(key);
|
|
return std::string(str);
|
|
}
|
|
|
|
/****************************************************/
|
|
bool GetDemoBranchFlagFromRegistry()
|
|
{
|
|
/*static volatile*/ short int DemoState = -1; // no cache
|
|
//if (DemoState == -1)
|
|
DemoState = (GetRegistryValueStr(HKEY_LOCAL_MACHINE, (std::string(CAMCAM_REG_KEY)+std::string(GAME_UPDATE_SUBKEY)).c_str(),
|
|
"branch") == "demo") ? 1 : 0;
|
|
return (DemoState == 1);
|
|
}
|
|
|
|
static const char *OC_KEY_CAMCAM = "OnceConnected";
|
|
|
|
/****************************************************/
|
|
bool GetFirstRunFlag()
|
|
{
|
|
return (GetRegistryValueStr(HKEY_CURRENT_USER, CAMCAM_REG_KEY, OC_KEY_CAMCAM) != "1");
|
|
}
|
|
|
|
/****************************************************/
|
|
bool SetFirstRunFlag()
|
|
{
|
|
HKEY newKey;
|
|
if (RegCreateKey(HKEY_CURRENT_USER, CAMCAM_REG_KEY, &newKey) != ERROR_SUCCESS)
|
|
return false;
|
|
const char *frvalue = "1";
|
|
bool ret = (RegSetValueEx(newKey, OC_KEY_CAMCAM, 0, REG_EXPAND_SZ, (BYTE *)frvalue, strlen(frvalue)+1) == ERROR_SUCCESS);
|
|
RegCloseKey(newKey);
|
|
return ret;
|
|
}
|
|
|
|
/****************************************************/
|
|
// dst: max 2047 chars
|
|
/*void GetCamCamValueFromRegistry(char *dst, char *item, bool fromHKCU)
|
|
{
|
|
std::string value;
|
|
if (fromHKCU)
|
|
value = GetRegistryValueStr(HKEY_CURRENT_USER, CAMCAM_REG_KEY, item);
|
|
else
|
|
value = GetRegistryValueStr(HKEY_LOCAL_MACHINE, (std::string(CAMCAM_REG_KEY)+std::string(GAME_UPDATE_SUBKEY).c_str(), item);
|
|
strncpy(dst, value, 2047);
|
|
}*/
|
|
|
|
/****************************************************/
|
|
// dst: max 2 chars
|
|
void GetInstalledLanguageCode(char *dst)
|
|
{
|
|
strncpy(dst, GetRegistryValueStr(HKEY_LOCAL_MACHINE, (std::string(CAMCAM_REG_KEY)+std::string(GAME_UPDATE_SUBKEY)).c_str(),
|
|
"language").c_str(), 2);
|
|
}
|
|
|
|
///****************************************************/
|
|
//bool SetRegistryValueStr(HKEY rootKey, const char *key, const char *name, const char *value)
|
|
//{
|
|
// HKEY hkey;
|
|
// if (RegOpenKeyEx(rootKey, key, 0, KEY_ALL_ACCESS, &hkey) != ERROR_SUCCESS)
|
|
// return false;
|
|
// bool ret = RegSetValueEx(hkey, name, 0, REG_EXPAND_SZ, (BYTE *)value, strlen(value)+1);
|
|
// RegCloseKey(hkey);
|
|
// return ret;
|
|
//}
|
|
//
|
|
///****************************************************/
|
|
//bool SetBranch(const char *branch, const char *newGameId)
|
|
//{
|
|
// const char *BRANCH_KEY_CAMCAM = "branch";
|
|
// const char *GAMEID_KEY_CAMCAM = "info";
|
|
// bool res = SetRegistryValueStr(HKEY_LOCAL_MACHINE, CAMCAM_REG_KEY, BRANCH_KEY_CAMCAM, branch);
|
|
// if (!res)
|
|
// return false;
|
|
// return SetRegistryValueStr(HKEY_LOCAL_MACHINE, CAMCAM_REG_KEY, GAMEID_KEY_CAMCAM, newGameId);
|
|
//}
|
|
//
|
|
///****************************************************/
|
|
//bool SwitchToBetaBranch()
|
|
//{
|
|
//#ifdef ONLINE_MODE
|
|
// if (Account.sameCurrentDemoAndBeta())
|
|
// return SetBranch("beta", Account.getBetaGameId().c_str());
|
|
// else
|
|
// return false; // user must download a new beta installer
|
|
//#endif
|
|
// return false;
|
|
//}
|
|
|
|
|
|
/****************************************************/
|
|
int GetAccountInfo(lua_State *L)
|
|
{
|
|
lua_newtable(L);
|
|
lua_pushstring(L, "v");
|
|
#ifdef ONLINE_MODE
|
|
lua_pushnumber(L, Account.getProtocolNum());
|
|
#else
|
|
lua_pushnumber(L, 0);
|
|
#endif
|
|
lua_settable(L, -3);
|
|
lua_pushstring(L, "ia");
|
|
#ifdef ONLINE_MODE
|
|
lua_pushnumber(L, Account.getIdAccount());
|
|
#else
|
|
lua_pushnumber(L, 0);
|
|
#endif
|
|
lua_settable(L, -3);
|
|
return true;
|
|
}
|
|
|
|
|
|
#ifdef ONLINE_MODE
|
|
/****************************************************/
|
|
int lua_push_json_object(lua_State *L, json_object *jo, bool freeJO=false)
|
|
{
|
|
if (!jo)
|
|
return 0;
|
|
switch(json_object_get_type(jo))
|
|
{
|
|
case json_type_boolean:
|
|
lua_pushboolean(L, json_object_get_boolean(jo));
|
|
break;
|
|
case json_type_double:
|
|
lua_pushnumber(L, json_object_get_double(jo));
|
|
break;
|
|
case json_type_int:
|
|
lua_pushnumber(L, (double)json_object_get_int(jo));
|
|
break;
|
|
case json_type_object:
|
|
lua_newtable(L);
|
|
json_object_object_foreach(jo, key, val)
|
|
{
|
|
lua_pushstring(L, key);
|
|
lua_push_json_object(L, val);
|
|
lua_settable(L, -3);
|
|
}
|
|
break;
|
|
case json_type_array:
|
|
{
|
|
lua_newtable(L);
|
|
int len = json_object_array_length(jo);
|
|
for (int i=0; i!=len; ++i)
|
|
{
|
|
lua_pushnumber(L, i+1); // wants index starting at 1
|
|
lua_push_json_object(L, json_object_array_get_idx(jo, i));
|
|
lua_settable(L, -3);
|
|
}
|
|
}
|
|
break;
|
|
case json_type_string:
|
|
lua_pushstring(L, json_object_get_string(jo));
|
|
break;
|
|
default:
|
|
lua_pushboolean(L, false); // avoid corrupting the table in case something went really wrong
|
|
return 0;
|
|
}
|
|
if (freeJO)
|
|
json_object_put(jo);
|
|
return 1;
|
|
}
|
|
#endif
|
|
|
|
/****************************************************/
|
|
int JSONToTable(lua_State *L)
|
|
{
|
|
if(lua_gettop(L)<1) return false;
|
|
|
|
#ifdef ONLINE_MODE
|
|
json_object *jo = json_tokener_parse(const_cast<char*>(lua_tostring(L, 1)));
|
|
if (is_error(jo))
|
|
lua_newtable(L);
|
|
else
|
|
lua_push_json_object(L, jo, true);
|
|
#else
|
|
lua_newtable(L);
|
|
#endif
|
|
return true;
|
|
}
|
|
|
|
/****************************************************/
|
|
int AddCredits(lua_State *L)
|
|
{
|
|
if(lua_gettop(L)<1) return false;
|
|
|
|
#ifdef ONLINE_MODE
|
|
//lua_pushboolean(L, Account.addCredits(lua_tonumber(L, 1)));
|
|
MessageBox(NULL, "Deprecated", "AddCredits", MB_ICONWARNING);
|
|
lua_pushboolean(L, true);
|
|
#else
|
|
lua_pushboolean(L, true);
|
|
#endif
|
|
return true;
|
|
}
|
|
|
|
extern HWND hWnd;
|
|
|
|
/****************************************************/
|
|
int OpenExternalBrowser(lua_State *L)
|
|
{
|
|
if(lua_gettop(L)<1) return false;
|
|
|
|
// Prevent from spawning an exe...
|
|
char url[2048];
|
|
strncpy(url, lua_tostring(L, 1), 2047);
|
|
#ifdef ONLINE_MODE
|
|
if (!*url)
|
|
{
|
|
// If first arg is empty, auto-log-in to web page, using arg 2 index
|
|
CCamCamAccount::WebPage page = CCamCamAccount::Profile;
|
|
if (lua_gettop(L)>1)
|
|
{
|
|
if (lua_tointeger(L, 2) >= CCamCamAccount::NbWebPages)
|
|
{
|
|
lua_pushboolean(L, false);
|
|
return true;
|
|
}
|
|
|
|
page = (CCamCamAccount::WebPage)lua_tointeger(L, 2);
|
|
}
|
|
|
|
if(CCamCamAccount::CNT_NORMAL != Account.getConnectionMode())
|
|
{
|
|
// If account is not a normal connection, we cant auto-log-in
|
|
lua_pushboolean(L, Account.callGuestPage(Account.getPage(page)));
|
|
return true;
|
|
}
|
|
|
|
strncpy(url, Account.getLoggedProfileURL(page).c_str(), 2047);
|
|
}
|
|
|
|
// Launch
|
|
lua_pushboolean(L, Account.openExternalWebBrowser(url));
|
|
#else
|
|
if ((strncmp(url, "http://", 7) == 0) || (strncmp(url, "https://", 8) == 0))
|
|
{
|
|
HINSTANCE r = ShellExecute(NULL, "open", url, NULL, NULL, SW_SHOWNORMAL);
|
|
lua_pushboolean(L, ((int)r)>32);
|
|
}
|
|
else
|
|
lua_pushboolean(L, false);
|
|
#endif
|
|
|
|
return true;
|
|
}
|
|
|
|
|
|
std::string getNextToken(char const**ppSrc, char delimiter)
|
|
{
|
|
const char *pStart = *ppSrc;
|
|
const char *pEnd = strchr(pStart, delimiter);
|
|
if (pEnd != NULL)
|
|
{
|
|
*ppSrc = pEnd+1;
|
|
return std::string(pStart, pEnd-pStart);
|
|
}
|
|
else
|
|
{
|
|
*ppSrc = NULL;
|
|
return std::string(pStart);
|
|
}
|
|
}
|
|
|
|
#ifdef ONLINE_MODE
|
|
/****************************************************/
|
|
void releaseLuaHTTPClients()
|
|
{
|
|
for (std::map<int,CHttpClient>::iterator it=HttpClientChannels.begin(); it!=HttpClientChannels.end(); ++it)
|
|
{
|
|
it->second.release();
|
|
}
|
|
HttpClientChannels.clear();
|
|
}
|
|
#endif
|
|
|
|
/****************************************************/
|
|
//int GetHTTPProxy(lua_State *L)
|
|
//{
|
|
//#ifdef ONLINE_MODE
|
|
// const char *proxy = Account.getHttpClient().getProxy();
|
|
// if (proxy)
|
|
// lua_pushstring(L, proxy);
|
|
// else
|
|
// lua_pushnil(L);
|
|
//#else
|
|
// lua_pushnil(L);
|
|
//#endif
|
|
// return true;
|
|
//}
|
|
//
|
|
///****************************************************/
|
|
//int SetRecommendedHTTPProxy(lua_State *L)
|
|
//{
|
|
// if (lua_gettop(L) < 1) return false;
|
|
//#ifdef ONLINE_MODE
|
|
// Account.setProxy(lua_tostring(L, 1));
|
|
//#endif
|
|
// return true;
|
|
//}
|
|
|
|
/****************************************************/
|
|
|
|
#ifdef ONLINE_MODE
|
|
bool hasChannelClient(int channel)
|
|
{
|
|
if (channel == -1)
|
|
return true;
|
|
return (HttpClientChannels.find(channel) != HttpClientChannels.end());
|
|
}
|
|
CHttpClient *getChannelClient(int channel)
|
|
{
|
|
if (channel < 0)
|
|
{
|
|
if (channel == -1)
|
|
return &Account._HttpClient;
|
|
else
|
|
return &HttpClientChannels[channel]; // TODO
|
|
}
|
|
else
|
|
return &HttpClientChannels[channel];
|
|
}
|
|
#endif
|
|
|
|
/****************************************************/
|
|
int HTTPRequest(lua_State *L, int channel, bool isPostRequest, bool isMultipart=false)
|
|
{
|
|
// Get URL
|
|
if(lua_gettop(L)<1) return false;
|
|
const char *url = lua_tostring(L,1);
|
|
const char *urlParams;
|
|
if (isPostRequest)
|
|
{
|
|
urlParams = lua_tostring(L,2);
|
|
}
|
|
else
|
|
{
|
|
urlParams = strchr(url, '?');
|
|
char blankParams [1] = "";
|
|
char pageURL [1024];
|
|
strncpy(pageURL, url, min(1024, urlParams ? (urlParams-url) : 1024));
|
|
pageURL[min(1023, urlParams ? (urlParams-url) : 1023)] = 0;
|
|
strncpy(pageURL, url, min(1024, urlParams ? (urlParams-url) : 1024));
|
|
url = pageURL;
|
|
urlParams = urlParams ? urlParams+1 : blankParams; // skip separator
|
|
}
|
|
int paramDelta = (isPostRequest ? 1 : 0);
|
|
|
|
// Get optional destination file
|
|
const char *destFile = (lua_gettop(L)>1+paramDelta) ? lua_tostring(L,2+paramDelta) : NULL;
|
|
|
|
// Get optional verbose param
|
|
bool verbose = ((lua_gettop(L)>2+paramDelta) && lua_toboolean(L,2+paramDelta));
|
|
|
|
#ifdef ONLINE_MODE
|
|
|
|
// Quick config
|
|
bool isNewClient = !hasChannelClient(channel);
|
|
CHttpClient *httpClient = getChannelClient(channel);
|
|
if (isNewClient && channel >= 0)
|
|
{
|
|
httpClient->init();
|
|
httpClient->setCurrentPacMethod(CHttpClient::PacmManual);
|
|
httpClient->setProxy(Account.getHttpClient().getProxy());
|
|
}
|
|
|
|
bool res;
|
|
bool canTryOtherProxy = false;
|
|
if (isPostRequest && isMultipart)
|
|
{
|
|
const char *bufPos = urlParams;
|
|
while (bufPos)
|
|
{
|
|
std::string field = getNextToken(&bufPos, '=');
|
|
std::string value = (bufPos ? getNextToken(&bufPos, '&') : "");
|
|
if (value[0] == '@')
|
|
httpClient->addMultipartParam(field.c_str(), CHttpClient::MultipartParam(value.substr(1).c_str(), CHttpClient::ParamLoadFile));
|
|
else
|
|
httpClient->addMultipartParam(field.c_str(), value.c_str());
|
|
}
|
|
do
|
|
{
|
|
// Do request, and reconfigure proxy if needed
|
|
res = httpClient->sendMultipartRequest(url, false, verbose);
|
|
if (!res && httpClient->mayRetryAfterProxyAutoConfig())
|
|
canTryOtherProxy = httpClient->nextTryAutoConfigureProxy(url); // needs XP SP1 or newer
|
|
}
|
|
while (!res && canTryOtherProxy);
|
|
}
|
|
else
|
|
{
|
|
if (channel == -1)
|
|
{
|
|
if (!Account.isLoggedIn())
|
|
res = false;
|
|
else
|
|
res = Account.doRequest(url, urlParams, FAILED_SCRIPT_REQUEST, __FUNCTION__, "", true);
|
|
}
|
|
else
|
|
{
|
|
do
|
|
{
|
|
// Do request, and reconfigure proxy if needed
|
|
res = httpClient->sendRequest(url, urlParams, isPostRequest, false, verbose);
|
|
if (!res && httpClient->mayRetryAfterProxyAutoConfig())
|
|
canTryOtherProxy = httpClient->nextTryAutoConfigureProxy(url); // needs XP SP1 or newer
|
|
}
|
|
while (!res && canTryOtherProxy);
|
|
}
|
|
}
|
|
if (destFile && *destFile)
|
|
{
|
|
if (!res)
|
|
lua_pushboolean(L, false);
|
|
else
|
|
{
|
|
if (fileExists(const_cast<char*>(destFile)))
|
|
{
|
|
lua_pushboolean(L, false);
|
|
return true;
|
|
}
|
|
FILE *f = CC_fopen(destFile, "wb");
|
|
if (f)
|
|
{
|
|
fwrite(httpClient->getResponsePage().data(), 1, httpClient->getResponsePage().size(), f);
|
|
CC_fclose(f);
|
|
lua_pushboolean(L, true);
|
|
}
|
|
else
|
|
lua_pushboolean(L, false);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
lua_pushstring(L, httpClient->getResponsePage().c_str());
|
|
}
|
|
#else
|
|
lua_pushstring(L, "");
|
|
#endif // ONLINE_MODE
|
|
|
|
return true;
|
|
}
|
|
|
|
|
|
/****************************************************/
|
|
int HTTPGet(lua_State *L)
|
|
{
|
|
int channel = (lua_gettop(L)>=4) ? lua_tonumber(L, 4) : 0;
|
|
return HTTPRequest(L, channel, false);
|
|
}
|
|
|
|
/****************************************************/
|
|
int HTTPPost(lua_State *L)
|
|
{
|
|
int channel = (lua_gettop(L)>=5) ? lua_tonumber(L, 5) : 0;
|
|
return HTTPRequest(L, channel, true, false);
|
|
}
|
|
|
|
/****************************************************/
|
|
int HTTPPostMultipart(lua_State *L)
|
|
{
|
|
int channel = (lua_gettop(L)>=5) ? lua_tonumber(L, 5) : 0;
|
|
return HTTPRequest(L, channel, true, true);
|
|
}
|
|
|
|
/*********************** Get Object List *****************************/
|
|
int GetObjectList(lua_State *L)
|
|
{
|
|
if (lua_gettop(L) == 0 ||
|
|
(lua_gettop(L)>0 && !lua_isstring(L,1))) return 0;
|
|
|
|
char *sceneName = (char *)lua_tostring(L,1);
|
|
SmallScene *SmSc = TheScene->SmallNameToScene(sceneName);
|
|
_3D_Object **pObj;
|
|
int onlyMesh = 0;
|
|
if (lua_gettop(L) > 1 && lua_isnumber(L, 2))
|
|
onlyMesh = lua_tonumber(L, 2);
|
|
|
|
if (!SmSc) return 0;
|
|
|
|
pObj = SmSc->ObjectsPtrs;
|
|
|
|
lua_newtable(L);
|
|
int nbInTable = 0;
|
|
for (int counter = 0; counter < SmSc->ulNumberOfObjects; counter++,pObj++)
|
|
{
|
|
if (onlyMesh && (*pObj)->MeshIndex == -1) continue;
|
|
lua_pushnumber(L, ++nbInTable);
|
|
lua_newtable(L);
|
|
lua_pushstring(L, "name");
|
|
lua_pushstring(L, (char *)(*pObj)->pObjectName);
|
|
lua_settable(L, -3);
|
|
lua_pushstring(L, "father");
|
|
lua_pushnumber(L, (*pObj)->FatherIndex + 1);
|
|
lua_settable(L, -3);
|
|
lua_settable(L, -3);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
|
|
/*********************** Get Material List *****************************/
|
|
static int matEnumIndex;
|
|
void MatEnumProcess(char *String,void *UserParam)
|
|
{
|
|
int len;
|
|
lua_State *L = (lua_State *)UserParam;
|
|
lua_pushnumber(L, ++matEnumIndex);
|
|
lua_pushstring(L, (char *)String);
|
|
lua_settable(L, -3);
|
|
}
|
|
|
|
int GetMatList(lua_State *L)
|
|
{
|
|
if (lua_gettop(L) == 0 ||
|
|
(lua_gettop(L)>0 && !lua_isstring(L,1))) return 0;
|
|
|
|
char *sceneName = (char *)lua_tostring(L,1);
|
|
SmallScene *SmSc = TheScene->SmallNameToScene(sceneName);
|
|
if (!SmSc) return 0;
|
|
|
|
lua_newtable(L);
|
|
matEnumIndex = 0;
|
|
SmSc->MaterialNameDico.EnumWords(MatEnumProcess,L);
|
|
return 1;
|
|
}
|
|
|
|
|
|
/*********************** Get Material List *****************************/
|
|
|
|
int GetMediaList(lua_State *L)
|
|
{
|
|
if (lua_gettop(L) == 0 ||
|
|
(lua_gettop(L)>0 && !lua_isstring(L,1))) return 0;
|
|
|
|
char *sceneName = (char *)lua_tostring(L,1);
|
|
SmallScene *SmSc = TheScene->SmallNameToScene(sceneName);
|
|
int mediaEnumIndex = 0;
|
|
if (!SmSc) return 0;
|
|
|
|
lua_newtable(L);
|
|
for (int i=0; i<SmSc->ulNumberOfMaterials; i++)
|
|
{
|
|
for (int j=0; j<SmSc->MaterialsPtrs[i]->NumberOfLayers; j++)
|
|
{
|
|
u32 textureIndex = SmSc->MaterialsPtrs[i]->Layers[j].TextureMediaIndex;
|
|
if (textureIndex != -1)
|
|
textureIndex = TheScene->MediaDico.mpst_Dico[textureIndex].AssociatedValue;
|
|
if (textureIndex != -1 && TheScene->ID_MEDIA[textureIndex])
|
|
{
|
|
lua_pushnumber(L, ++mediaEnumIndex);
|
|
lua_pushstring(L, (char *)TheScene->ID_MEDIA[textureIndex]->MediaName);
|
|
lua_settable(L, -3);
|
|
}
|
|
}
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
/*********************** CONVERSTION FUNCTIONS ***********************/
|
|
|
|
int ProcessTableRec(lua_State *L, char *strPtr, int nbElmts)
|
|
{
|
|
// Set Variable
|
|
char inBuffer[256];
|
|
char *inBufferPtr;
|
|
int keyIndex = 1;
|
|
|
|
lua_newtable(L);
|
|
while (nbElmts > 0)
|
|
{
|
|
memset(inBuffer, 0, sizeof(inBuffer));
|
|
|
|
for (;nbElmts > 0 && *strPtr <= 32; strPtr++, nbElmts--);
|
|
for (inBufferPtr=inBuffer;nbElmts > 0 && *strPtr != '=' && *strPtr != '{'; strPtr++, inBufferPtr++, nbElmts--)
|
|
*inBufferPtr = *strPtr;
|
|
|
|
if (*inBuffer)
|
|
{
|
|
lua_pushstring(L, inBuffer);
|
|
strPtr++; nbElmts--;
|
|
} else
|
|
{
|
|
lua_pushnumber(L, keyIndex++);
|
|
}
|
|
for (;nbElmts > 0 && *strPtr <= 32; strPtr++, nbElmts--);
|
|
if (*strPtr == '{')
|
|
{
|
|
int level = 1;
|
|
int nbElmtsIn = 0;
|
|
|
|
strPtr++; nbElmts--;
|
|
while (level != 0 && nbElmts > 0)
|
|
{
|
|
if (*strPtr == '{') level++;
|
|
if (*strPtr == '}') level--;
|
|
strPtr++; nbElmts--;
|
|
nbElmtsIn++;
|
|
}
|
|
ProcessTableRec(L, strPtr-nbElmtsIn, nbElmtsIn-1);
|
|
} else
|
|
{
|
|
BOOL isNumber = true;
|
|
|
|
memset(inBuffer, 0, sizeof(inBuffer));
|
|
inBufferPtr = inBuffer;
|
|
|
|
for (inBufferPtr = inBuffer; nbElmts > 0 && *strPtr != ','; strPtr++, inBufferPtr++, nbElmts--)
|
|
{
|
|
if (*strPtr <= 32) continue;
|
|
if ((*strPtr < '0' || *strPtr > '9') &&
|
|
*strPtr != '+' && *strPtr != '-' && *strPtr != '.' ) isNumber = false;
|
|
*inBufferPtr = *strPtr;
|
|
}
|
|
*inBufferPtr = 0;
|
|
|
|
if (isNumber)
|
|
lua_pushnumber(L, (double)atof(inBuffer));
|
|
else
|
|
lua_pushstring(L, inBuffer);
|
|
}
|
|
for (;*strPtr <= 32 && nbElmts > 0; strPtr++, nbElmts--);
|
|
if (nbElmts > 0 && *strPtr == ',' )
|
|
{ strPtr++; nbElmts--; }
|
|
lua_settable(L, -3);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int StringToTable(lua_State *L)
|
|
{
|
|
char *strPtr = (char *)lua_tostring(L, -1);
|
|
int strLen = strlen(strPtr);
|
|
|
|
if (*strPtr != '{' && strPtr[strLen-1] != '}') return 0;
|
|
strPtr++;
|
|
ProcessTableRec(L, strPtr, strLen-2);
|
|
return 1;
|
|
}
|
|
|
|
|
|
/*********************** EVENT FUNCTIONS ***********************/
|
|
|
|
typedef struct {
|
|
char name[512];
|
|
DWORD mode;
|
|
|
|
int nbObject;
|
|
int maxObject;
|
|
ObjectEventInfo *object;
|
|
} EventInfo;
|
|
|
|
#define BASE_MAX_OBJECT 8
|
|
static BOOL IsEventListGlobal = 1;
|
|
static BOOL IsEventListEmpty[MAX_SCRIPTS];
|
|
static EventInfo EventList[MAX_SCRIPTS][MAX_EVENT];
|
|
|
|
#define MAX_EVENT_EXEC 1024
|
|
|
|
static int nbEventsExec = 0;
|
|
static int currentEvent = 0;
|
|
static ObjectEventDatas EventsExec[MAX_EVENT_EXEC];
|
|
static UNIC_Dico objEventDico;
|
|
|
|
void LuaEventAdd(EventInfo *EventListPtr, int eventNum, char* eventName, DWORD mode)
|
|
{
|
|
strcpy(EventListPtr[eventNum].name, eventName);
|
|
EventListPtr[eventNum].mode = mode;
|
|
|
|
EventListPtr[eventNum].nbObject = 0;
|
|
EventListPtr[eventNum].maxObject = BASE_MAX_OBJECT;
|
|
EventListPtr[eventNum].object = (ObjectEventInfo *)CC_malloc(EventListPtr[eventNum].maxObject*sizeof(ObjectEventInfo));
|
|
memset(EventListPtr[eventNum].object, 0, EventListPtr[eventNum].maxObject*sizeof(ObjectEventInfo));
|
|
}
|
|
|
|
void LuaAddAllEvents(lua_State *L, EventInfo *EventListPtr)
|
|
{
|
|
#define LUA_EVENT_SET(a,m) LuaEventAdd(EventListPtr, EVT_##a, #a, m);
|
|
#include "LuaEvents.h"
|
|
}
|
|
|
|
|
|
inline void LuaEventAddObject(EventInfo *EventListPtr, int eventNum, char *function, int *levels, int nbLevels)
|
|
{
|
|
if (!function) return;
|
|
|
|
EventInfo *eventPtr = EventListPtr + eventNum;
|
|
ObjectEventInfo *objectPtr;
|
|
int functionLen;
|
|
|
|
if (eventPtr->nbObject >= eventPtr->maxObject)
|
|
{
|
|
while (eventPtr->maxObject <= eventPtr->nbObject)
|
|
eventPtr->maxObject *= 2;
|
|
eventPtr->object = (ObjectEventInfo *)CC_realloc(eventPtr->object,
|
|
eventPtr->maxObject*sizeof(ObjectEventInfo));
|
|
memset(eventPtr->object + eventPtr->nbObject, 0, (eventPtr->maxObject-eventPtr->nbObject)*sizeof(ObjectEventInfo));
|
|
}
|
|
objectPtr = eventPtr->object + eventPtr->nbObject++;
|
|
objectPtr->nbLevels = nbLevels;
|
|
|
|
UnicID id;
|
|
for (int i=0; i<=nbLevels; i++)
|
|
{
|
|
id = objEventDico.IsExist(function + levels[i]);
|
|
if (id == -1)
|
|
objEventDico.GetUnic(&id, function + levels[i]);
|
|
objectPtr->objID[i] = id;
|
|
}
|
|
memcpy(objectPtr->levels, levels, (nbLevels+1)*sizeof(int));
|
|
memcpy(objectPtr->luaFunction, function, objectPtr->levels[objectPtr->nbLevels]);
|
|
}
|
|
|
|
void adressToString(u32 adress, char *buffer)
|
|
{
|
|
buffer[0] = ((adress >> 28) & 0xf) + 'A';
|
|
buffer[1] = ((adress >> 24) & 0xf) + 'A';
|
|
buffer[2] = ((adress >> 20) & 0xf) + 'A';
|
|
buffer[3] = ((adress >> 16) & 0xf) + 'A';
|
|
buffer[4] = ((adress >> 12) & 0xf) + 'A';
|
|
buffer[5] = ((adress >> 8) & 0xf) + 'A';
|
|
buffer[6] = ((adress >> 4) & 0xf) + 'A';
|
|
buffer[7] = ((adress >> 0) & 0xf) + 'A';
|
|
buffer[8] = 0;
|
|
}
|
|
|
|
|
|
void LuaPreProcessEvent(lua_State *L, EventInfo *EventListPtr, int nbLevels, int *levels, char *functionName, int len, char *name)
|
|
{
|
|
if (!L) return;
|
|
static UNIC_Dico levelsDico;
|
|
char adressStr[16];
|
|
if (nbLevels < 0)
|
|
{
|
|
char nameBuffer[1024];
|
|
*functionName = 0;
|
|
if (name == NULL)
|
|
strcpy(nameBuffer, "UI");
|
|
else
|
|
strcpy(nameBuffer, name);
|
|
lua_getglobal(L, nameBuffer);
|
|
curLevel = 0;
|
|
levelsDico.Init();
|
|
levelsDico.IsCaseSensitive = 1;
|
|
LuaPreProcessEvent(L, EventListPtr, 0, levels, functionName, 0, nameBuffer);
|
|
levelsDico.Destroy();
|
|
lua_pop(L, 1);
|
|
return;
|
|
}
|
|
if (!lua_istable(L,-1)) return;
|
|
adressToString((u32)lua_topointer(L, -1), adressStr);
|
|
if (levelsDico.IsExist(adressStr) != -1)
|
|
return;
|
|
levelsDico.AddWord(adressStr);
|
|
/*
|
|
// Verify if event already done
|
|
if (curLevel >= maxLevel)
|
|
{
|
|
maxLevel *= 2;
|
|
levelsPtr = (void **)CC_realloc(levelsPtr, maxLevel*sizeof(void *));
|
|
#ifdef EVENT_CONFLICT
|
|
levelsCharsPtr = (char **)CC_realloc(levelsCharsPtr, maxLevel*sizeof(char *));
|
|
#endif
|
|
}
|
|
levelsPtr[curLevel] = (void *)lua_topointer(L, -1);
|
|
#ifdef EVENT_CONFLICT
|
|
char buffer[1024];
|
|
memset(buffer, 0, sizeof(buffer));
|
|
memcpy(buffer, functionName, len);
|
|
for (int i=0; i<len; i++)
|
|
if (buffer[i] == 0) buffer[i] = '.';
|
|
strcat(buffer, name);
|
|
#endif
|
|
|
|
for (int lvlIdx=0; lvlIdx<curLevel; lvlIdx++)
|
|
{
|
|
if (levelsPtr[lvlIdx] == levelsPtr[curLevel])
|
|
{
|
|
levelsPtr[curLevel] = NULL;
|
|
#ifdef EVENT_CONFLICT
|
|
char log[2048];
|
|
sprintf(log, "Same ptr %s <> %s", levelsCharsPtr[lvlIdx], buffer);
|
|
SaveDBGInfo(log);
|
|
#endif
|
|
break;
|
|
}
|
|
}
|
|
if (levelsPtr[curLevel] == NULL)
|
|
return;
|
|
else
|
|
curLevel++;
|
|
|
|
#ifdef EVENT_CONFLICT
|
|
levelsCharsPtr[curLevel-1] = strdup(buffer);
|
|
#endif
|
|
*/
|
|
levels[nbLevels] = len;
|
|
strcpy(functionName + len, name);
|
|
len += strlen(functionName + len) + 1;
|
|
|
|
nbLevels++;
|
|
lua_pushnil(L); /* first key */
|
|
while (lua_next(L, -2) != 0) {
|
|
/* uses 'key' (at index -2) and 'value' (at index -1) */
|
|
if (lua_isnumber(L, -2))
|
|
{
|
|
lua_pop(L, 1);
|
|
continue;
|
|
}
|
|
lua_pushvalue(L, -2);
|
|
strcpy(name, (char *)lua_tostring(L,-1));
|
|
lua_pop(L, 1);
|
|
LuaPreProcessEvent(L, EventListPtr, nbLevels, levels, functionName, len, name);
|
|
lua_pop(L, 1);
|
|
}
|
|
|
|
for (int eventIdx=0; eventIdx<MAX_EVENT; eventIdx++)
|
|
{
|
|
lua_pushstring(L, EventListPtr[eventIdx].name);
|
|
lua_gettable(L, -2);
|
|
|
|
if (lua_isfunction(L, -1))
|
|
{
|
|
int lastLevel = nbLevels;
|
|
levels[lastLevel++] = len;
|
|
strcpy(functionName + len, EventListPtr[eventIdx].name);
|
|
levels[lastLevel] = len + strlen(functionName + len) + 1;
|
|
LuaEventAddObject(EventListPtr, eventIdx, functionName, levels, lastLevel);
|
|
}
|
|
lua_pop(L, 1);
|
|
}
|
|
}
|
|
|
|
|
|
inline void AddEventExec(ObjectEventDatas *datas)
|
|
{
|
|
if (nbEventsExec >= MAX_EVENT_EXEC)
|
|
return;
|
|
EventsExec[nbEventsExec++] = *datas;
|
|
}
|
|
|
|
inline BOOL PushLuaParents(lua_State *L, ObjectEventInfo *event)
|
|
{
|
|
int nbPtsIn = 0;
|
|
|
|
lua_getglobal(L, event->luaFunction);
|
|
if (lua_isnil(L, -1))
|
|
return false;
|
|
for (int lev=1; lev<event->nbLevels; lev++)
|
|
{
|
|
lua_pushstring(L, event->luaFunction+event->levels[lev]);
|
|
lua_gettable(L, -2);
|
|
if (lua_isnil(L, -1))
|
|
return false;
|
|
}
|
|
nbPtsIn = event->nbLevels;
|
|
while (nbPtsIn > 1)
|
|
{
|
|
lua_insert (L, -nbPtsIn--);
|
|
}
|
|
return true;
|
|
}
|
|
|
|
|
|
void WORLD::LuaEventsExec()
|
|
{
|
|
ObjectEventInfo *lastObject = NULL;
|
|
ObjectEventInfo *objPtr;
|
|
BOOL result = false;
|
|
lua_State *luaScriptPtr = luaScriptTable[currentScript];
|
|
|
|
if (!luaScriptPtr)
|
|
{
|
|
nbEventsExec = 0;
|
|
return;
|
|
}
|
|
|
|
START_RASTER(LUA_CALLS);
|
|
|
|
if (WAIT_OBJECT_0 == WaitForSingleObject(ScriptAccesMutex, INFINITE))
|
|
{
|
|
LUA_DEBUG_RASTER_STOP();
|
|
for (currentEvent=0; currentEvent<nbEventsExec; currentEvent++)
|
|
{
|
|
objPtr = EventsExec[currentEvent].infoPtr;
|
|
if (objPtr->nbLevels == 0) continue;
|
|
|
|
if (result &&
|
|
strcmp( lastObject->luaFunction + lastObject->levels[lastObject->nbLevels-1],
|
|
objPtr->luaFunction + objPtr->levels[objPtr->nbLevels-1]))
|
|
result = 0;
|
|
|
|
if (result &&
|
|
(lastObject->levels[lastObject->nbLevels-1] > objPtr->levels[objPtr->nbLevels-1]) &&
|
|
!memcmp(lastObject->luaFunction, objPtr->luaFunction, objPtr->levels[objPtr->nbLevels-1]))
|
|
continue;
|
|
|
|
if (!PushLuaParents(luaScriptPtr, objPtr))
|
|
continue;
|
|
|
|
#ifndef USER_MODE
|
|
extern int mainThread;
|
|
if (mainThread != GetCurrentThreadId()) MessageBox(NULL, "Bad Threard Access 6!", "YouUp", MB_OK | MB_ICONERROR);
|
|
#endif
|
|
if(debuggingLua)
|
|
{
|
|
lua_call(luaScriptPtr,objPtr->nbLevels-1,1);
|
|
}
|
|
else
|
|
{
|
|
if (lua_pcall(luaScriptPtr,objPtr->nbLevels-1,1,0) != 0)
|
|
{
|
|
char * luaRes = (char *)lua_tostring(luaScriptPtr, -1);
|
|
if (luaRes) strcpy(LuaErrors, luaRes);
|
|
else strcpy(LuaErrors, "LUA Unknown error (set debuggingLua to 1 in camcam.ccm !!)");
|
|
lua_pop(luaScriptPtr, 1);
|
|
|
|
SaveDBGInfo(LuaErrors);
|
|
STOP_RASTER(LUA_CALLS)
|
|
ReleaseMutex(ScriptAccesMutex);
|
|
nbEventsExec = 0;
|
|
return;
|
|
}
|
|
}
|
|
if (lua_isboolean(luaScriptPtr, -1))
|
|
{
|
|
result = lua_toboolean(luaScriptPtr, -1);
|
|
if (result)
|
|
lastObject = objPtr;
|
|
} else
|
|
result = false;
|
|
lua_pop(luaScriptPtr, 1);
|
|
}
|
|
LUA_DEBUG_RASTER_STOP();
|
|
STOP_RASTER(LUA_CALLS);
|
|
ReleaseMutex(ScriptAccesMutex);
|
|
nbEventsExec = 0;
|
|
}
|
|
if (updateEvent)
|
|
{
|
|
UpdateEvents(NULL);
|
|
updateEvent = false;
|
|
}
|
|
}
|
|
|
|
static char inScriptError[2048];
|
|
|
|
void FillScriptInfo(lua_State *L, int paramNum, int isError)
|
|
{
|
|
lua_Debug ar[64];
|
|
int nbLevels = 1;
|
|
char *inScriptErrorPtr = inScriptError;
|
|
lua_getstack(L, 0, &ar[0]);
|
|
lua_getinfo(L, "n", &ar[0]);
|
|
for (; nbLevels < 64 && lua_getstack(L, nbLevels, &ar[nbLevels]); nbLevels++)
|
|
lua_getinfo(L, "lS", &ar[nbLevels]);
|
|
for (nbLevels--; nbLevels > 1; nbLevels--)
|
|
{
|
|
sprintf(inScriptErrorPtr, "%s:%i\n", ar[nbLevels].short_src, ar[nbLevels].currentline);
|
|
inScriptErrorPtr += strlen(inScriptErrorPtr);
|
|
}
|
|
|
|
if (isError)
|
|
sprintf(inScriptErrorPtr, "%s:%i: bad argument #%i to '%s\'", ar[1].short_src, ar[1].currentline, paramNum, ar[0].name);
|
|
else
|
|
sprintf(inScriptErrorPtr, "%s:%i: function '%s\'", ar[1].short_src, ar[1].currentline, ar[0].name);
|
|
}
|
|
|
|
void HandleError(lua_State *L, int paramNum)
|
|
{
|
|
FillScriptInfo(L, paramNum, 1);
|
|
lua_pushstring(L, inScriptError);
|
|
lua_error(L);
|
|
}
|
|
|
|
|
|
bool PopBoolean(lua_State *L, int narg)
|
|
{
|
|
if (!lua_isboolean(L, narg))
|
|
HandleError(L, narg);
|
|
return lua_toboolean(L, narg);
|
|
}
|
|
|
|
int PopInteger(lua_State *L, int narg)
|
|
{
|
|
lua_Integer d = lua_tointeger(L, narg);
|
|
if (d == 0 && !lua_isnumber(L, narg)) /* avoid extra test when d is not 0 */
|
|
HandleError(L, narg);
|
|
return d;
|
|
}
|
|
|
|
double PopNumber(lua_State *L, int narg)
|
|
{
|
|
lua_Number d = lua_tonumber(L, narg);
|
|
if (d == 0 && !lua_isnumber(L, narg)) /* avoid extra test when d is not 0 */
|
|
HandleError(L, narg);
|
|
return d;
|
|
}
|
|
|
|
const char *PopString(lua_State *L, int narg)
|
|
{
|
|
const char *s = lua_tolstring(L, narg, NULL);
|
|
if (!s) HandleError(L, narg);
|
|
return s;
|
|
}
|
|
|
|
//FillScriptInfo(L, 0, 0); \
|
|
|
|
/*
|
|
#define DEFINE_SCRIPT_SPECIAL(scriptName, functionName, parameters, helpString)
|
|
#define DEFINE_SCRIPT(a,params,Help,b) \
|
|
int WORLD::WSCRIPT_##a(lua_State *L) {int ParamsOk=1; int luaParam=1; int returnDone = 0; int luaArgs = lua_gettop(L); params; \
|
|
if (!ParamsOk) { HandleError(L, luaParam); return 0; } \
|
|
b; \
|
|
if (!returnDone) lua_pushnil(L); \
|
|
else if (returnDone > 1) \
|
|
{ lua_newtable(L); for (int idx=0; idx<returnDone; idx++) \
|
|
{lua_pushinteger(L,idx+1); lua_pushvalue(L, idx-returnDone-2); lua_settable(L, -3); lua_remove(L,idx-returnDone-1); \
|
|
} } return 1; } \
|
|
int SCRIPT_##a(lua_State *L) { return TheScene->WSCRIPT_##a(L); }
|
|
#define DEFINE_SCRIPT_REN(n,a,params,Help,b) \
|
|
DEFINE_SCRIPT(n,params,Help,b)
|
|
#include "Script_Commands.h"
|
|
*/
|
|
|
|
|
|
#define DEFINE_SCRIPT_SPECIAL(scriptName, functionName, parameters, helpString)
|
|
#define DEFINE_SCRIPT(a,params,Help,b) \
|
|
int WORLD::WSCRIPT_##a(lua_State *L) {START_RASTER(LUA_SUB_CALLS); int ParamsOk=1; int luaParam=1; int returnDone = 0; int luaArgs = lua_gettop(L); params; \
|
|
if (!ParamsOk) { HandleError(L, luaParam); STOP_RASTER(LUA_SUB_CALLS); return 0; } \
|
|
b; \
|
|
if (!returnDone) lua_pushnil(L); STOP_RASTER(LUA_SUB_CALLS);\
|
|
return 1; } \
|
|
int SCRIPT_##a(lua_State *L) { return TheScene->WSCRIPT_##a(L); }
|
|
#define DEFINE_SCRIPT_REN(n,a,params,Help,b) \
|
|
DEFINE_SCRIPT(n,params,Help,b)
|
|
#ifdef ONLINE_MODE
|
|
#define DEFINE_SCRIPT_ONLINE(a,params,Help,b,c) \
|
|
DEFINE_SCRIPT(a,params,Help,b)
|
|
#else
|
|
#define DEFINE_SCRIPT_ONLINE(a,params,Help,b,c) \
|
|
DEFINE_SCRIPT(a,params,Help,c)
|
|
#endif
|
|
#include "Script_Commands.h"
|
|
|
|
int SCRIPT_SmallSceneNewMultiMaterial(lua_State *L)
|
|
{
|
|
return TheScene->SmallSceneNewMultiMaterial(L);
|
|
}
|
|
|
|
|
|
|
|
/************************ LUA SPECIFUC GENERIC ***********************************/
|
|
|
|
int SCRIPT_Xml2Lua(lua_State *L)
|
|
{
|
|
return TheScene->Xml2Lua(L, (char *)lua_tostring(L, 1));
|
|
}
|
|
|
|
int SCRIPT_XmlFile2Lua(lua_State *L)
|
|
{
|
|
int result = 0;
|
|
FILE * file = fopen(lua_tostring(L, 1), "rt");
|
|
if (file)
|
|
{
|
|
fseek(file, 0, SEEK_END);
|
|
int size = ftell(file);
|
|
fseek(file, 0, SEEK_SET);
|
|
|
|
char *buffer = (char *)CC_malloc(size+1);
|
|
if (buffer)
|
|
{
|
|
fread(buffer, size, 1, file);
|
|
buffer[size] = 0;
|
|
result = TheScene->Xml2Lua(L, buffer);
|
|
CC_free(buffer);
|
|
}
|
|
fclose(file);
|
|
}
|
|
return result;
|
|
}
|
|
|
|
|
|
#ifndef SKIMMED_NET
|
|
int SCRIPT_SendFlash(lua_State *L)
|
|
{
|
|
if (!lua_isstring(L, -1))
|
|
return 0;
|
|
|
|
TheScene->FlashCom_Send((char *)lua_tostring(L, -1));
|
|
|
|
return 1;
|
|
}
|
|
#endif
|
|
|
|
int SCRIPT_DoFile(lua_State *L)
|
|
{
|
|
char *filename = (char *)lua_tostring(L, -1);
|
|
|
|
#ifdef USER_MODE
|
|
char filenameX[1024];
|
|
sprintf(filenameX, "%sx", filename);
|
|
filename = filenameX;
|
|
|
|
BOOL IsFileAllowed(char *filename, bool fromLua);
|
|
void displayIntegrityError(int num);
|
|
|
|
/*// Check integrity of caller, if it is a registered file
|
|
lua_Debug ar;
|
|
lua_getstack(L, 1, &ar);
|
|
lua_getinfo(L, "lS", &ar);
|
|
if (!IsFileAllowed((char *)ar.source, 1))
|
|
{
|
|
displayIntegrityError(2);
|
|
lua_pushboolean(L, false);
|
|
return 1;
|
|
}*/
|
|
|
|
// New: check integrity of called file, if it is a registered file
|
|
if (!IsFileAllowed(filename, 1))
|
|
{
|
|
displayIntegrityError(3);
|
|
lua_pushboolean(L, false);
|
|
return 1;
|
|
}
|
|
#endif //USER_MODE
|
|
|
|
FILE *fileF = CC_fopen(filename, "r");
|
|
|
|
UnicID ID;
|
|
if (fileF)
|
|
{
|
|
CC_fclose(fileF);
|
|
TheScene->luaLoaddedFilesDICO.GetUnic(&ID,(char *)lua_tostring(L, -1));
|
|
|
|
if (luaL_loadfile(L, (char *)lua_tostring(L, -1)) != 0)
|
|
lua_error(L);
|
|
lua_call(L, 0, LUA_MULTRET);
|
|
lua_pushboolean(L, true);
|
|
} else
|
|
{
|
|
lua_pushboolean(L, false);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
void FreeEvents(int scriptIndex)
|
|
{
|
|
if (IsEventListGlobal)
|
|
{
|
|
for (int evIdx=0; evIdx<MAX_SCRIPTS; evIdx++)
|
|
IsEventListEmpty[evIdx] = 1;
|
|
IsEventListGlobal = 0;
|
|
}
|
|
if (!IsEventListEmpty[scriptIndex])
|
|
{
|
|
for (int eventIdx = 0; eventIdx<MAX_EVENT; eventIdx++)
|
|
{
|
|
if (EventList[scriptIndex][eventIdx].object)
|
|
CC_free(EventList[scriptIndex][eventIdx].object);
|
|
}
|
|
IsEventListEmpty[scriptIndex] = 1;
|
|
}
|
|
memset(EventList[scriptIndex], 0, sizeof(EventList[scriptIndex]));
|
|
}
|
|
|
|
int UpdateEvents(lua_State *L)
|
|
{
|
|
char luaFunction[512];
|
|
int levels[32];
|
|
|
|
if (L != NULL)
|
|
{
|
|
updateEvent = true;
|
|
return 1;
|
|
}
|
|
FreeEvents(TheScene->currentScript);
|
|
LuaAddAllEvents(TheScene->luaScriptTable[TheScene->currentScript], EventList[TheScene->currentScript]);
|
|
IsEventListEmpty[TheScene->currentScript] = 0;
|
|
|
|
levelsPtr = (void **)CC_malloc(maxLevel*sizeof(void *));
|
|
#ifdef EVENT_CONFLICT
|
|
levelsCharsPtr = (char **)CC_malloc(maxLevel*sizeof(char *));
|
|
#endif
|
|
objEventDico.Init();
|
|
LuaPreProcessEvent( TheScene->luaScriptTable[TheScene->currentScript],
|
|
EventList[TheScene->currentScript],
|
|
-1, levels, luaFunction, 0, NULL);
|
|
CC_free(levelsPtr);
|
|
#ifdef EVENT_CONFLICT
|
|
for (int i=0; i<curLevel; i++)
|
|
free(levelsCharsPtr[i]);
|
|
CC_free(levelsCharsPtr);
|
|
#endif
|
|
levelsPtr = NULL;
|
|
return 1;
|
|
}
|
|
|
|
|
|
int AddToEvents(lua_State *L)
|
|
{
|
|
char *eventName = (char *)lua_tostring(L, 1);
|
|
char *UIName = (char *)lua_tostring(L, 2);
|
|
char eventNameLocal[2048];
|
|
char UINameLocal[1024];
|
|
char *eventFunction = eventName;
|
|
int eventLevelsTab[128];
|
|
int eventLevels = 0;
|
|
|
|
if (!eventName)
|
|
return 0;
|
|
|
|
//while (strchr(eventFunction, '.'))
|
|
// eventFunction = strchr(eventFunction, '.') + 1;
|
|
|
|
if (UIName == NULL)
|
|
strcpy(UINameLocal, "UI");
|
|
else
|
|
strcpy(UINameLocal, UIName);
|
|
memset(eventNameLocal, 0, sizeof(eventNameLocal));
|
|
sprintf(eventNameLocal, "%s.%s", UINameLocal, eventName);
|
|
|
|
lua_getglobal(L, UINameLocal);
|
|
eventFunction = eventNameLocal;
|
|
eventLevelsTab[eventLevels++] = 0;
|
|
while (strchr(eventFunction, '.'))
|
|
{
|
|
eventLevelsTab[eventLevels++] = (strchr(eventFunction, '.') - eventNameLocal)+1;
|
|
*strchr(eventFunction, '.') = 0;
|
|
if (eventFunction != eventNameLocal)
|
|
{
|
|
lua_pushstring(L, eventFunction);
|
|
lua_gettable(L, -2);
|
|
if (lua_isnil(L, -1))
|
|
{
|
|
HandleError(L, 0);
|
|
return 0;
|
|
}
|
|
}
|
|
eventFunction = eventFunction + strlen(eventFunction) + 1;
|
|
}
|
|
eventLevelsTab[eventLevels] = (eventFunction - eventNameLocal)+strlen(eventFunction)+1;
|
|
lua_pushstring(L, eventFunction);
|
|
lua_gettable(L, -2);
|
|
if (lua_isfunction(L, -1))
|
|
{
|
|
int eventIndex = -1;
|
|
if (!*EventList[TheScene->currentScript][0].name)
|
|
LuaAddAllEvents(L, EventList[TheScene->currentScript]);
|
|
for (int Idx = 0; Idx<MAX_EVENT; Idx++)
|
|
{
|
|
if (!strcmp(EventList[TheScene->currentScript][Idx].name, eventFunction))
|
|
{
|
|
eventIndex = Idx;
|
|
break;
|
|
}
|
|
}
|
|
if (eventIndex == -1)
|
|
{
|
|
HandleError(L, 0);
|
|
return 0;
|
|
}
|
|
LuaEventAddObject(EventList[TheScene->currentScript], eventIndex, eventNameLocal, eventLevelsTab, eventLevels);
|
|
}
|
|
lua_pop(L, 1);
|
|
return 1;
|
|
}
|
|
|
|
int GetEventsData(lua_State *L)
|
|
{
|
|
if (currentEvent < nbEventsExec)
|
|
{
|
|
switch (EventsExec[currentEvent].type)
|
|
{
|
|
case EVENT_TYPE_MOUSE:
|
|
PushMouseInfo(L, (MouseInfo *)EventsExec[currentEvent].data);
|
|
break;
|
|
case EVENT_TYPE_KEY:
|
|
PushInt(L, *((int *)EventsExec[currentEvent].data));
|
|
break;
|
|
case EVENT_TYPE_STRING:
|
|
PushString(L, EventsExec[currentEvent].data);
|
|
break;
|
|
case EVENT_TYPE_SIZE:
|
|
PushPoint(L, (POINT *)EventsExec[currentEvent].data);
|
|
break;
|
|
}
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
|
|
BOOL WORLD::LuaSetLevel(int changeLevel)
|
|
{
|
|
nbEventsExec = 0;
|
|
if (changeLevel < 0)
|
|
{
|
|
int newLevel = currentScript + changeLevel;
|
|
if (newLevel >= 0)
|
|
{
|
|
for (int luaIdx = currentScript; luaIdx>newLevel; luaIdx--)
|
|
{
|
|
if (luaScriptTable[luaIdx])
|
|
{
|
|
lua_State *luaScriptPtr = luaScriptTable[luaIdx];
|
|
luaScriptTable[luaIdx] = NULL;
|
|
FreeEvents(luaIdx);
|
|
lua_close(luaScriptPtr);
|
|
}
|
|
}
|
|
currentScript = newLevel;
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
if (changeLevel == 0)
|
|
{
|
|
for (int luaIdx=MAX_SCRIPTS-1; luaIdx >= 0; luaIdx--)
|
|
{
|
|
if (luaScriptTable[luaIdx])
|
|
{
|
|
lua_State *luaScriptPtr = luaScriptTable[luaIdx];
|
|
luaScriptTable[luaIdx] = NULL;
|
|
FreeEvents(luaIdx);
|
|
lua_close(luaScriptPtr);
|
|
}
|
|
}
|
|
currentScript = 0;
|
|
return true;
|
|
}
|
|
if (changeLevel == 1)
|
|
{
|
|
if ((currentScript+1) < MAX_SCRIPTS)
|
|
{
|
|
currentScript++;
|
|
if (luaScriptTable[currentScript])
|
|
{
|
|
lua_State *luaScriptPtr = luaScriptTable[currentScript];
|
|
luaScriptTable[currentScript] = NULL;
|
|
FreeEvents(currentScript);
|
|
lua_close(luaScriptPtr);
|
|
}
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
int WORLD::LoadLua(char *filename, BOOL clearParams)
|
|
{
|
|
LUA_DEBUG_CLEAN();
|
|
if (WAIT_OBJECT_0 == WaitForSingleObject(ScriptAccesMutex, INFINITE))
|
|
{
|
|
lua_State * lua_L;
|
|
|
|
luaLoaddedFilesDICO.Destroy();
|
|
luaLoaddedFilesDICO.Init();
|
|
|
|
memset(LuaErrors, 0, sizeof(LuaErrors));
|
|
SceneScript_DESTROY(&SceneScript_Loop);
|
|
|
|
if (clearParams == 1 || (currentScript == 0 && clearParams != 2))
|
|
{
|
|
#ifdef ONLINE_MODE
|
|
Account.logOut();
|
|
#endif
|
|
LuaSetLevel(0);
|
|
DestroyAllSMSC();
|
|
DestroyAllPGenerator();
|
|
DestroyAllMedia();
|
|
DestroyAllAnim();
|
|
DestroyTrackeur();
|
|
if (WSPC) WSPC_Destroy(WSPC);
|
|
WSPC = NULL;
|
|
|
|
u32 Counter = MAX_INIFILES;
|
|
while (Counter--)
|
|
IniFiles[Counter].Destroy();
|
|
IniFileDico.Destroy();
|
|
|
|
ulFullRefresh = true;
|
|
} else if (luaScriptTable[currentScript] != NULL)
|
|
{
|
|
lua_close(luaScriptTable[currentScript]);
|
|
luaScriptTable[currentScript] = NULL;
|
|
}
|
|
if (currentScript == 0)
|
|
VirtuallyDestroyAllMedia();
|
|
|
|
|
|
nbEventsExec = 0;
|
|
|
|
lua_L = lua_open();
|
|
luaL_openlibs(lua_L);
|
|
|
|
#ifndef SKIMMED_NET
|
|
luaopen_socket_core(lua_L); // socket register
|
|
#endif
|
|
|
|
Vector_Register(lua_L);
|
|
VectorPtr_Register(lua_L);
|
|
Quat_Register(lua_L);
|
|
Matrix_Register(lua_L);
|
|
|
|
#define DEFINE_SCRIPT_SPECIAL(scriptName, functionName, parameters, helpString) \
|
|
lua_register(lua_L,#scriptName,functionName);
|
|
#define DEFINE_SCRIPT(a,params,Help,b) \
|
|
lua_register(lua_L,#a,SCRIPT_##a);
|
|
#define DEFINE_SCRIPT_REN(n,a,params,Help,b) \
|
|
lua_register(lua_L,#a,SCRIPT_##n); \
|
|
lua_register(lua_L,#n,SCRIPT_##n);
|
|
#define DEFINE_SCRIPT_ONLINE(a,params,Help,b,c) \
|
|
lua_register(lua_L,#a,SCRIPT_##a);
|
|
#include "Script_Commands.h"
|
|
|
|
#ifndef USER_MODE
|
|
extern int mainThread;
|
|
if (mainThread != GetCurrentThreadId()) MessageBox(NULL, "Bad Threard Access 7!", "YouUp", MB_OK | MB_ICONERROR);
|
|
#endif
|
|
if(debuggingLua)
|
|
{
|
|
luaScriptTable[currentScript] = lua_L;
|
|
if(!luaL_loadfile(lua_L, filename))
|
|
lua_call(lua_L, 0, LUA_MULTRET);
|
|
}
|
|
else
|
|
{
|
|
luaScriptTable[currentScript] = lua_L;
|
|
if(luaL_loadfile(lua_L, filename) || lua_pcall(lua_L, 0, LUA_MULTRET, 0))
|
|
{
|
|
if (lua_tostring(lua_L, -1) != NULL)
|
|
strcpy(LuaErrors, (char *)lua_tostring(lua_L, -1));
|
|
else
|
|
strcpy(LuaErrors, "Error Openning LUA File");
|
|
SaveDBGInfo(LuaErrors);
|
|
lua_close(lua_L);
|
|
ReleaseMutex(ScriptAccesMutex);
|
|
luaScriptTable[currentScript] = NULL;
|
|
return 0;
|
|
}
|
|
}
|
|
luaScriptTable[currentScript] = lua_L;
|
|
|
|
UpdateEvents(NULL);
|
|
ReleaseMutex(ScriptAccesMutex);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int WORLD::LuaHandle(UINT message, WPARAM wParam, LPARAM lParam)
|
|
{
|
|
BOOL result = 0;
|
|
ObjectEventDatas datas;
|
|
|
|
if (luaScriptTable[currentScript] == NULL) return 0;
|
|
if (bManualBoot && !oldManualBoot) return 0;
|
|
|
|
switch (message)
|
|
{
|
|
case WM_MOUSEMOVE:
|
|
case WM_LBUTTONDOWN:
|
|
case WM_LBUTTONUP:
|
|
case WM_LBUTTONDBLCLK:
|
|
case 0x020A:
|
|
datas.type = EVENT_TYPE_MOUSE;
|
|
((MouseInfo *)datas.data)->x = (INT16)LOWORD(lParam);
|
|
((MouseInfo *)datas.data)->y = (INT16)HIWORD(lParam);
|
|
((MouseInfo *)datas.data)->keys = (INT16)LOWORD(wParam);
|
|
((MouseInfo *)datas.data)->value = (INT16)HIWORD(wParam);
|
|
break;
|
|
case WM_KEYUP:
|
|
case WM_KEYDOWN:
|
|
datas.type = EVENT_TYPE_KEY;
|
|
*((int *)datas.data) = (int) wParam;
|
|
break;
|
|
case WM_DROPFILES:
|
|
{
|
|
HDROP hDropFiles = (HDROP)wParam;
|
|
int nChar = 1 + DragQueryFile(hDropFiles,0,NULL,0);
|
|
datas.type = EVENT_TYPE_STRING;
|
|
if (nChar < 256)
|
|
DragQueryFile(hDropFiles,0,datas.data,nChar);
|
|
else
|
|
*datas.data = 0;
|
|
//DragFinish(hDropFiles);
|
|
}
|
|
break;
|
|
case WM_SIZE:
|
|
datas.type = EVENT_TYPE_SIZE;
|
|
((POINT *)datas.data)->x = (INT16)LOWORD(lParam);
|
|
((POINT *)datas.data)->y = (INT16)HIWORD(lParam);
|
|
break;
|
|
case WM_SIZING:
|
|
datas.type = EVENT_TYPE_SIZE;
|
|
((POINT *)datas.data)->x = ((RECT *)lParam)->right - ((RECT *)lParam)->left;
|
|
((POINT *)datas.data)->y = ((RECT *)lParam)->bottom - ((RECT *)lParam)->top;
|
|
break;
|
|
}
|
|
|
|
switch (message)
|
|
{
|
|
case WM_MOUSEMOVE:
|
|
result = LuaProcessEventDatas(EVT_onMouseMove, &datas);
|
|
break;
|
|
case WM_LBUTTONDOWN:
|
|
result = LuaProcessEventDatas(EVT_onPressOut, &datas) ||
|
|
LuaProcessEventDatas(EVT_onPress, &datas);
|
|
PickReportClick = PickReportFinal;
|
|
break;
|
|
case WM_LBUTTONUP:
|
|
result = LuaProcessEventDatas(EVT_onReleaseIn, &datas) ||
|
|
LuaProcessEventDatas(EVT_onReleaseOut, &datas) ||
|
|
LuaProcessEventDatas(EVT_onRelease, &datas);
|
|
memset(&PickReportClick, 0, sizeof(PickReportClick));
|
|
break;
|
|
case WM_RBUTTONDOWN:
|
|
case WM_RBUTTONUP:
|
|
memset(&PickReportClick, 0, sizeof(PickReportClick));
|
|
break;
|
|
case WM_LBUTTONDBLCLK:
|
|
LuaProcessEventDatas(EVT_onDoubleClick, &datas);
|
|
result = 1;
|
|
break;
|
|
case 0x020A:
|
|
if ((int) wParam < 0)
|
|
result = LuaProcessEventDatas(EVT_onMouseWheelDown, &datas);
|
|
else
|
|
result = LuaProcessEventDatas(EVT_onMouseWheelUp, &datas);
|
|
result = result || LuaProcessEventDatas(EVT_onMouseWheel, &datas);
|
|
break;
|
|
case WM_KEYDOWN:
|
|
result = LuaProcessEventDatas(EVT_onKeyDown, &datas);
|
|
break;
|
|
case WM_KEYUP:
|
|
result = LuaProcessEventDatas(EVT_onKeyUp, &datas);
|
|
break;
|
|
case WM_DROPFILES:
|
|
result = LuaProcessEventDatas(EVT_onDropFiles, &datas);
|
|
break;
|
|
case WM_SIZE:
|
|
case WM_SIZING:
|
|
result = LuaProcessEventDatas(EVT_onWndSize, &datas);
|
|
break;
|
|
case WM_CLOSE:
|
|
case WM_DESTROY:
|
|
result = LuaProcessEventDatas(EVT_onExit, &datas);
|
|
break;
|
|
}
|
|
return result;
|
|
}
|
|
|
|
inline int PickingClass(char *str, char *pickingStr, DWORD currentMask)
|
|
{
|
|
char *pickPtr;
|
|
int maskPos = 0;
|
|
int strLen = strlen(str);
|
|
while ((pickPtr = strchr(pickingStr, '.')) != NULL)
|
|
{
|
|
if (!(currentMask & (1<<maskPos)) &&
|
|
(pickPtr - pickingStr == strLen) &&
|
|
!strncmp(str, pickingStr, strLen))
|
|
return maskPos;
|
|
maskPos++;
|
|
pickingStr = pickPtr + 1;
|
|
}
|
|
if (!(currentMask & (1<<maskPos)) &&
|
|
!(strcmp(str, pickingStr)))
|
|
return maskPos;
|
|
return -1;
|
|
}
|
|
|
|
inline BOOL IsFunctionOnPick(ObjectEventInfo *event, PickingReport *report, INPUT_IO *mediaPtr)
|
|
{
|
|
DWORD mask[6];
|
|
int maskIndex;
|
|
BOOL objFound;
|
|
char *currentStr;
|
|
|
|
memset(mask, 0, sizeof(mask));
|
|
//1<<0 PickingClass
|
|
//1<<1 CollidedSmallSceneName
|
|
//1<<2 CollidedSmallSceneGameObjectName
|
|
//1<<3 CollidedSmallMaterialName
|
|
//1<<4 CollidedMediaName
|
|
//1<<5 CollidedMediaNickname
|
|
|
|
for (int lev=1; lev<event->nbLevels-1; lev++)
|
|
{
|
|
currentStr = event->luaFunction + event->levels[lev];
|
|
if ((maskIndex = PickingClass(currentStr, report->PickingClass, mask[0])) != -1)
|
|
{ mask[0] |= (1<<maskIndex); continue; }
|
|
if ((maskIndex = PickingClass(currentStr, report->CollidedSmallSceneName, mask[1])) != -1)
|
|
{ mask[1] |= (1<<maskIndex); continue; }
|
|
if ((maskIndex = PickingClass(currentStr, report->CollidedSmallSceneGameObjectName, mask[2])) != -1)
|
|
{ mask[2] |= (1<<maskIndex); continue; }
|
|
if ((maskIndex = PickingClass(currentStr, report->CollidedSmallMaterialName, mask[3])) != -1)
|
|
{ mask[3] |= (1<<maskIndex); continue; }
|
|
if (mediaPtr != NULL && (maskIndex = PickingClass(currentStr, (char *)mediaPtr->MediaName, mask[4])) != -1)
|
|
{ mask[4] |= (1<<maskIndex); continue; }
|
|
if (mediaPtr != NULL && (maskIndex = PickingClass(currentStr, (char *)mediaPtr->Nickname, mask[5])) != -1)
|
|
{ mask[5] |= (1<<maskIndex); continue; }
|
|
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
int WORLD::LuaProcessEvent(int eventNum)
|
|
{
|
|
ObjectEventDatas datas;
|
|
|
|
datas.type = EVENT_DATA_NONE;
|
|
*datas.data = 0;
|
|
|
|
return LuaProcessEventDatas(eventNum, &datas);
|
|
}
|
|
|
|
typedef struct PickingReportUId_
|
|
{
|
|
int PickingClassNb;
|
|
UnicID PickingClassId[32];
|
|
int CollidedSmallSceneNameNb;
|
|
UnicID CollidedSmallSceneNameId[32];
|
|
int CollidedSmallSceneGameObjectNameNb;
|
|
UnicID CollidedSmallSceneGameObjectNameId[32];
|
|
int CollidedSmallMaterialNameNb;
|
|
UnicID CollidedSmallMaterialNameId[32];
|
|
int MediaNameNb;
|
|
UnicID MediaNameId[32];
|
|
int NicknameNb;
|
|
UnicID NicknameId[32];
|
|
} PickingReportUId;
|
|
|
|
|
|
int FillUIDString(char *str, UnicID *idList)
|
|
{
|
|
char word[512];
|
|
char *posPtr;
|
|
int posLen;
|
|
UnicID id;
|
|
int curPos = 0;
|
|
|
|
while (posPtr = strchr(str, '.'))
|
|
{
|
|
posLen = posPtr - str;
|
|
strncpy(word, str, posLen);
|
|
word[posLen] = 0;
|
|
id = objEventDico.IsExist(word);
|
|
if (id == -1)
|
|
return curPos;
|
|
idList[curPos++] = id;
|
|
str = posPtr + 1;
|
|
}
|
|
id = objEventDico.IsExist(str);
|
|
if (id == -1)
|
|
return curPos;
|
|
idList[curPos++] = id;
|
|
return curPos;
|
|
}
|
|
|
|
void FillPickReportID(PickingReport *PR, PickingReportUId *PRID, INPUT_IO *mediaPtr)
|
|
{
|
|
PRID->PickingClassNb = FillUIDString(PR->PickingClass, PRID->PickingClassId);
|
|
PRID->CollidedSmallSceneNameNb = FillUIDString(PR->CollidedSmallSceneName, PRID->CollidedSmallSceneNameId);
|
|
PRID->CollidedSmallSceneGameObjectNameNb= FillUIDString(PR->CollidedSmallSceneGameObjectName, PRID->CollidedSmallSceneGameObjectNameId);
|
|
PRID->CollidedSmallMaterialNameNb = FillUIDString(PR->CollidedSmallMaterialName, PRID->CollidedSmallMaterialNameId);
|
|
if (mediaPtr)
|
|
{
|
|
PRID->MediaNameNb = FillUIDString((char *)mediaPtr->MediaName, PRID->MediaNameId);
|
|
PRID->NicknameNb = FillUIDString((char *)mediaPtr->Nickname, PRID->NicknameId);
|
|
} else
|
|
{
|
|
PRID->MediaNameNb = -1;
|
|
PRID->NicknameNb = -1;
|
|
}
|
|
}
|
|
|
|
inline BOOL IsFunctionOnPickID(ObjectEventInfo *event, PickingReportUId *PRID)
|
|
{
|
|
UnicID *objID = event->objID+1;
|
|
int testLvl = event->nbLevels - 2;
|
|
int compSize= testLvl*sizeof(UnicID);
|
|
if (PRID->PickingClassNb >= testLvl && !memcmp(PRID->PickingClassId, objID, compSize)) return true;
|
|
if (PRID->CollidedSmallSceneNameNb >= testLvl && !memcmp(PRID->CollidedSmallSceneNameId, objID, compSize)) return true;
|
|
if (PRID->CollidedSmallSceneGameObjectNameNb >= testLvl && !memcmp(PRID->CollidedSmallSceneGameObjectNameId, objID, compSize)) return true;
|
|
if (PRID->CollidedSmallMaterialNameNb >= testLvl && !memcmp(PRID->CollidedSmallMaterialNameId, objID, compSize)) return true;
|
|
if (PRID->MediaNameNb >= testLvl && !memcmp(PRID->MediaNameId, objID, compSize)) return true;
|
|
if (PRID->NicknameNb >= testLvl && !memcmp(PRID->PickingClassId, objID, compSize)) return true;
|
|
return false;
|
|
}
|
|
|
|
|
|
|
|
int WORLD::LuaProcessEventDatas(int eventNum, ObjectEventDatas *dataPtr)
|
|
{
|
|
DWORD mode = EventList[currentScript][eventNum].mode;
|
|
BOOL verifyEqual = (mode >> LUA_MODE_DEC) & 1;
|
|
BOOL mainTest = !((mode >> LUA_MAIN_TEST_DEC) & 1);
|
|
BOOL process;
|
|
ObjectEventInfo *objPtr;
|
|
PickingReport *mainReport;
|
|
PickingReportUId mainReportID;
|
|
PickingReport *compReport;
|
|
PickingReportUId compReportID;
|
|
|
|
START_RASTER(Events);
|
|
objPtr = EventList[currentScript][eventNum].object;
|
|
|
|
switch(mode & 255)
|
|
{
|
|
case LUA_RESULT_PICK: mainReport = &PickReportResult; break;
|
|
case LUA_FINAL_PICK: mainReport = &PickReportFinal; break;
|
|
case LUA_PRESSED_PICK: mainReport = &PickReportClick; break;
|
|
case LUA_TOWATCH_PICK: mainReport = &PickReportToWatch; break;
|
|
default: mainReport = NULL;
|
|
}
|
|
|
|
switch((mode>>LUA_SRC_DEC) & 255)
|
|
{
|
|
case LUA_RESULT_PICK: compReport = &PickReportResult; break;
|
|
case LUA_FINAL_PICK: compReport = &PickReportFinal; break;
|
|
case LUA_PRESSED_PICK: compReport = &PickReportClick; break;
|
|
case LUA_TOWATCH_PICK: compReport = &PickReportToWatch; break;
|
|
default: compReport = NULL;
|
|
}
|
|
|
|
if (mainReport)
|
|
FillPickReportID(mainReport, &mainReportID, GetMediaFromImage(mainReport->CollidedMap));
|
|
if (compReport)
|
|
FillPickReportID(compReport, &compReportID, GetMediaFromImage(compReport->CollidedMap));
|
|
|
|
for (int objIdx=0; objIdx<EventList[currentScript][eventNum].nbObject; objIdx++, objPtr++)
|
|
{
|
|
process = !mode || (objPtr->nbLevels <= 2);
|
|
if (!process)
|
|
{
|
|
//for (int idx=0; idx<objPtr->nbLevels; idx++)
|
|
//{
|
|
// if (!strcmp(objPtr->luaFunction+objPtr->levels[idx], "item3"))
|
|
// {
|
|
// int BreackPoint = 0;
|
|
// }
|
|
//}
|
|
if (!mainReport) continue;
|
|
|
|
//if (mainTest == IsFunctionOnPick(objPtr, mainReport, GetMediaFromImage(mainReport->CollidedMap)))
|
|
if (mainTest == IsFunctionOnPickID(objPtr, &mainReportID))
|
|
{
|
|
if (compReport)
|
|
{
|
|
//process = IsFunctionOnPick(objPtr, compReport, GetMediaFromImage(compReport->CollidedMap)) == verifyEqual;
|
|
process = IsFunctionOnPickID(objPtr, &compReportID) == verifyEqual;
|
|
} else process = 1;
|
|
}
|
|
}
|
|
if (!process) continue;
|
|
|
|
dataPtr->infoPtr = objPtr;
|
|
AddEventExec(dataPtr);
|
|
}
|
|
STOP_RASTER(Events);
|
|
return 0;
|
|
}
|
|
|
|
/***************************** XML LUA Parse **************************************/
|
|
#include "tinyxml.h"
|
|
|
|
void XmlElmtCreate(lua_State *L, TiXmlElement *xmlElmt)
|
|
{
|
|
TiXmlAttribute *xmlAttr;
|
|
TiXmlNode *xmlChildNode;
|
|
int curIndex;
|
|
|
|
lua_newtable(L); // xml node
|
|
|
|
if (xmlElmt == NULL)
|
|
return;
|
|
|
|
lua_pushstring(L, "tag");// elmt name
|
|
lua_pushstring(L, xmlElmt->Value());
|
|
lua_settable(L, -3);
|
|
|
|
lua_pushstring(L, "attr");// elmt attr
|
|
lua_newtable(L);
|
|
|
|
for (xmlAttr = xmlElmt->FirstAttribute(), curIndex = 1;
|
|
xmlAttr; xmlAttr = xmlAttr->Next())
|
|
{
|
|
lua_pushnumber(L, curIndex++);
|
|
lua_pushstring(L, xmlAttr->Name());
|
|
lua_settable(L, -3);
|
|
|
|
lua_pushstring(L, xmlAttr->Name());
|
|
lua_pushstring(L, xmlAttr->Value());
|
|
lua_settable(L, -3);
|
|
}
|
|
lua_settable(L, -3);
|
|
|
|
|
|
for (xmlChildNode = xmlElmt->FirstChild(), curIndex = 1;
|
|
xmlChildNode; xmlChildNode = xmlChildNode->NextSibling())
|
|
{
|
|
if (xmlChildNode->Type() == TiXmlNode::TEXT)
|
|
{
|
|
lua_pushnumber(L, curIndex++);
|
|
lua_pushstring(L, xmlChildNode->Value());
|
|
lua_settable(L, -3);
|
|
} else if (xmlChildNode->Type() == TiXmlNode::ELEMENT)
|
|
{
|
|
lua_pushnumber(L, curIndex++);
|
|
XmlElmtCreate(L, (TiXmlElement *)xmlChildNode);
|
|
lua_settable(L, -3);
|
|
}
|
|
}
|
|
}
|
|
|
|
BOOL XmlCreate(lua_State *L, char *xmlStr)
|
|
{
|
|
TiXmlDocument xmlDoc;
|
|
TiXmlElement *xmlElmt;
|
|
|
|
if (!xmlStr) return 0;
|
|
|
|
xmlDoc.Parse(xmlStr);
|
|
xmlElmt = xmlDoc.RootElement();
|
|
if (xmlElmt == NULL)
|
|
return 0;
|
|
|
|
XmlElmtCreate(L, xmlElmt);
|
|
return 1;
|
|
}
|
|
|
|
BOOL WORLD::Xml2Lua(lua_State *L, char *buffer)
|
|
{
|
|
if (L && buffer)
|
|
{
|
|
char *xmlStr = (char *)buffer;
|
|
if (XmlCreate(L, xmlStr))
|
|
return 1;
|
|
}
|
|
lua_pushnil(L);
|
|
return 0;
|
|
}
|
|
|