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:
zeromus 2018-10-03 03:18:16 -04:00
parent d6babce9b7
commit 43fcaf68f1
3 changed files with 118 additions and 4 deletions

View File

@ -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
{

View File

@ -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];

View File

@ -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
{