add "ability to move camera" (aka freelook). it requires use of a lua script to actually control the matrix switcheroo
re: #130
This commit is contained in:
parent
d6babce9b7
commit
43fcaf68f1
|
@ -348,6 +348,9 @@ static u16 dsDiffuse, dsAmbient, dsSpecular, dsEmission;
|
|||
//used for indexing the shininess table during parameters to shininess command
|
||||
static u8 shininessInd = 0;
|
||||
|
||||
// "Freelook" related things
|
||||
int freelookMode = 0;
|
||||
s32 freelookMatrix[16];
|
||||
|
||||
//-----------cached things:
|
||||
//these dont need to go into the savestate. they can be regenerated from HW registers
|
||||
|
@ -743,8 +746,27 @@ static void SetVertex()
|
|||
if(polylist->count >= POLYLIST_SIZE)
|
||||
return;
|
||||
|
||||
GEM_TransformVertex(mtxCurrent[MATRIXMODE_POSITION], coordTransformed); //modelview
|
||||
GEM_TransformVertex(mtxCurrent[MATRIXMODE_PROJECTION], coordTransformed); //projection
|
||||
if(freelookMode == 2)
|
||||
{
|
||||
//adjust projection
|
||||
s32 tmp[16];
|
||||
MatrixCopy(tmp,mtxCurrent[MATRIXMODE_PROJECTION]);
|
||||
MatrixMultiply(tmp, freelookMatrix);
|
||||
GEM_TransformVertex(mtxCurrent[MATRIXMODE_POSITION], coordTransformed); //modelview
|
||||
GEM_TransformVertex(tmp, coordTransformed); //projection
|
||||
}
|
||||
else if(freelookMode == 3)
|
||||
{
|
||||
//use provided projection
|
||||
GEM_TransformVertex(mtxCurrent[MATRIXMODE_POSITION], coordTransformed); //modelview
|
||||
GEM_TransformVertex(freelookMatrix, coordTransformed); //projection
|
||||
}
|
||||
else
|
||||
{
|
||||
//no freelook
|
||||
GEM_TransformVertex(mtxCurrent[MATRIXMODE_POSITION], coordTransformed); //modelview
|
||||
GEM_TransformVertex(mtxCurrent[MATRIXMODE_PROJECTION], coordTransformed); //projection
|
||||
}
|
||||
|
||||
//TODO - culling should be done here.
|
||||
//TODO - viewport transform?
|
||||
|
@ -904,6 +926,15 @@ static void SetVertex()
|
|||
}
|
||||
}
|
||||
|
||||
static void UpdateProjection()
|
||||
{
|
||||
if(freelookMode == 0) return;
|
||||
float floatproj[16];
|
||||
for(int i=0;i<16;i++)
|
||||
floatproj[i] = mtxCurrent[MATRIXMODE_PROJECTION][i]/((float)(1<<12));
|
||||
CallRegistered3dEvent(0,floatproj);
|
||||
}
|
||||
|
||||
static void gfx3d_glPolygonAttrib_cache()
|
||||
{
|
||||
// Light enable/disable
|
||||
|
@ -984,6 +1015,8 @@ static void gfx3d_glPushMatrix()
|
|||
if (index == 1) MMU_new.gxstat.se = 1;
|
||||
index += 1;
|
||||
index &= 1;
|
||||
|
||||
UpdateProjection();
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1031,6 +1064,8 @@ static void gfx3d_glPopMatrix(u32 v)
|
|||
index ^= 1;
|
||||
if (index == 1) MMU_new.gxstat.se = 1;
|
||||
MatrixCopy(mtxCurrent[mode], mtxStackProjection.matrix[0]);
|
||||
|
||||
UpdateProjection();
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1070,6 +1105,7 @@ static void gfx3d_glStoreMatrix(u32 v)
|
|||
if (mode == MATRIXMODE_PROJECTION)
|
||||
{
|
||||
MatrixCopy(mtxStackProjection.matrix[0], mtxCurrent[MATRIXMODE_PROJECTION]);
|
||||
UpdateProjection();
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1102,6 +1138,7 @@ static void gfx3d_glRestoreMatrix(u32 v)
|
|||
if (mode == MATRIXMODE_PROJECTION)
|
||||
{
|
||||
MatrixCopy(mtxCurrent[MATRIXMODE_PROJECTION], mtxStackProjection.matrix[0]);
|
||||
UpdateProjection();
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -3830,6 +3830,38 @@ DEFINE_LUA_FUNCTION(emu_registermenustart, "func")
|
|||
return 1;
|
||||
}
|
||||
|
||||
DEFINE_LUA_FUNCTION(emu_set3dtransform, "mode, matrix")
|
||||
{
|
||||
extern int freelookMode;
|
||||
extern s32 freelookMatrix[16];
|
||||
|
||||
int mode = luaL_checkinteger(L,1);
|
||||
freelookMode = mode;
|
||||
if(mode == 2 || mode == 3)
|
||||
{
|
||||
for(int i=0;i<16;i++)
|
||||
{
|
||||
lua_rawgeti(L, 2, i+1);
|
||||
freelookMatrix[i] = (s32)(lua_tonumber(L,-1)*(1<<12));
|
||||
lua_pop(L,1);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
DEFINE_LUA_FUNCTION(emu_register3devent, "func")
|
||||
{
|
||||
if (!lua_isnil(L,1))
|
||||
luaL_checktype(L, 1, LUA_TFUNCTION);
|
||||
lua_settop(L,1);
|
||||
lua_getfield(L, LUA_REGISTRYINDEX, luaCallIDStrings[LUACALL_REGISTER3DEVENT]);
|
||||
lua_insert(L,1);
|
||||
lua_setfield(L, LUA_REGISTRYINDEX, luaCallIDStrings[LUACALL_REGISTER3DEVENT]);
|
||||
StopScriptIfFinished(luaStateToUIDMap[L->l_G->mainthread]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
// TODO
|
||||
/*
|
||||
DEFINE_LUA_FUNCTION(emu_loadrom, "filename")
|
||||
|
@ -4674,6 +4706,8 @@ static const struct luaL_reg emulib [] =
|
|||
{"addmenu", emu_addmenu},
|
||||
{"setmenuiteminfo", emu_setmenuiteminfo},
|
||||
{"registermenustart", emu_registermenustart},
|
||||
{"register3devent", emu_register3devent},
|
||||
{"set3dtransform", emu_set3dtransform},
|
||||
// alternative names
|
||||
// {"openrom", emu_loadrom},
|
||||
{NULL, NULL}
|
||||
|
@ -5683,7 +5717,7 @@ bool AnyLuaActive()
|
|||
return false;
|
||||
}
|
||||
|
||||
void CallRegisteredLuaFunctions(LuaCallID calltype)
|
||||
void _CallRegisteredLuaFunctions(LuaCallID calltype, int (*beforeCallback)(lua_State*, void*), void* beforeCallbackArg)
|
||||
{
|
||||
assert((unsigned int)calltype < (unsigned int)LUACALL_COUNT);
|
||||
const char* idstring = luaCallIDStrings[calltype];
|
||||
|
@ -5720,7 +5754,9 @@ void CallRegisteredLuaFunctions(LuaCallID calltype)
|
|||
bool wasRunning = info.running;
|
||||
info.running = true;
|
||||
RefreshScriptSpeedStatus();
|
||||
int errorcode = lua_pcall(L, 0, 0, 0);
|
||||
int nargs = 0;
|
||||
if(beforeCallback) nargs = beforeCallback(L,beforeCallbackArg);
|
||||
int errorcode = lua_pcall(L, nargs, 0, 0);
|
||||
info.running = wasRunning;
|
||||
RefreshScriptSpeedStatus();
|
||||
if (errorcode)
|
||||
|
@ -5744,6 +5780,45 @@ void CallRegisteredLuaFunctions(LuaCallID calltype)
|
|||
}
|
||||
}
|
||||
|
||||
void CallRegisteredLuaFunctions(LuaCallID calltype)
|
||||
{
|
||||
_CallRegisteredLuaFunctions(calltype, NULL, NULL);
|
||||
}
|
||||
|
||||
static struct {
|
||||
int which;
|
||||
void* arg;
|
||||
} todo3devent;
|
||||
|
||||
int CallRegistered3dEvent_callback(lua_State* L, void* userarg)
|
||||
{
|
||||
if(todo3devent.which == 0)
|
||||
{
|
||||
float* mat = (float*)todo3devent.arg;
|
||||
lua_newtable(L);
|
||||
for(int i=0;i<16;i++)
|
||||
{
|
||||
lua_pushnumber(L,mat[i]);
|
||||
lua_rawseti(L,-2,i+1);
|
||||
}
|
||||
lua_setfield(L,LUA_GLOBALSINDEX,"registered3devent_arg");
|
||||
|
||||
lua_pushnumber(L,todo3devent.which);
|
||||
lua_setfield(L,LUA_GLOBALSINDEX,"registered3devent_which");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void CallRegistered3dEvent(int which, void* arg)
|
||||
{
|
||||
todo3devent.which = which;
|
||||
todo3devent.arg = arg;
|
||||
_CallRegisteredLuaFunctions(LUACALL_REGISTER3DEVENT, &CallRegistered3dEvent_callback, NULL);
|
||||
}
|
||||
|
||||
void CallRegisteredLuaSaveFunctions(int savestateNumber, LuaSaveData& saveData)
|
||||
{
|
||||
const char* idstring = luaCallIDStrings[LUACALL_BEFORESAVE];
|
||||
|
|
|
@ -37,6 +37,7 @@ enum LuaCallID
|
|||
LUACALL_AFTERLOAD,
|
||||
LUACALL_ONSTART,
|
||||
LUACALL_ONINITMENU,
|
||||
LUACALL_REGISTER3DEVENT,
|
||||
|
||||
LUACALL_SCRIPT_HOTKEY_1,
|
||||
LUACALL_SCRIPT_HOTKEY_2,
|
||||
|
@ -58,6 +59,7 @@ enum LuaCallID
|
|||
LUACALL_COUNT
|
||||
};
|
||||
void CallRegisteredLuaFunctions(LuaCallID calltype);
|
||||
void CallRegistered3dEvent(int which, void* arg);
|
||||
|
||||
enum LuaMemHookType
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue