JD2022-TU1/main/extern/Camcam/LIBS/Mixer/SCENE_LUA.cpp

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;
}