Fixed token corruption in DynOS, added support for runtime LOAD_MODEL_FROM_GEO
This commit is contained in:
parent
3731ab31af
commit
4956f0dd95
|
@ -37,6 +37,7 @@ Collision* dynos_collision_get(const char* collisionName);
|
|||
// -- levels -- //
|
||||
void dynos_add_level(s32 modIndex, const char *modPath, const char* levelName);
|
||||
LevelScript* dynos_level_get(const char* levelName);
|
||||
const char* dynos_level_get_token(u32 index);
|
||||
struct MovtexQuadCollection *dynos_level_movtexqc_getfromindex(s32 index);
|
||||
void dynos_level_load_background(void *ptr);
|
||||
|
||||
|
|
|
@ -717,6 +717,7 @@ s16 *DynOS_Level_GetWarpDeath(s32 aLevel, s32 aArea);
|
|||
void DynOS_Lvl_Add(s32 modIndex, const SysPath &aPackFolder, const char *aLevelName);
|
||||
LevelScript* DynOS_Lvl_Get(const char* levelName);
|
||||
s32 DynOS_Lvl_GetModIndex(void* levelScript);
|
||||
const char* DynOS_Lvl_Get_Token(u32 index);
|
||||
DataNode<TexData> *DynOS_Lvl_Texture_Get(void *aPtr);
|
||||
DataNode<MovtexQC> *DynOS_Lvl_MovtexQuadCollection_GetFromIndex(s32 index);
|
||||
void DynOS_Lvl_Load_Background(void *aPtr);
|
||||
|
|
|
@ -1665,7 +1665,6 @@ static void ParseLevelScriptSymbol(GfxData* aGfxData, DataNode<LevelScript>* aNo
|
|||
|
||||
// models
|
||||
lvl_symbol_3(LOAD_MODEL_FROM_DL, 1, 0, 0);
|
||||
lvl_symbol_2(LOAD_MODEL_FROM_GEO, 1, 0);
|
||||
lvl_symbol_3(CMD23, 1, 0, 0);
|
||||
|
||||
// objects
|
||||
|
@ -1779,6 +1778,26 @@ static void ParseLevelScriptSymbol(GfxData* aGfxData, DataNode<LevelScript>* aNo
|
|||
return;
|
||||
}
|
||||
|
||||
// LOAD_MODEL_FROM_GEO
|
||||
if (_Symbol == "LOAD_MODEL_FROM_GEO") {
|
||||
u64 topTokenIndex = aTokenIndex;
|
||||
bool foundGeo = true;
|
||||
LevelScript model = ParseLevelScriptSymbolArg(aGfxData, aNode, aTokenIndex);
|
||||
LevelScript geo = ParseLevelScriptSymbolArgInternal(aGfxData, aNode, aTokenIndex, &foundGeo);
|
||||
if (foundGeo) {
|
||||
aGfxData->mPointerList.Add(aHead + 1);
|
||||
LevelScript _Ls[] = { LOAD_MODEL_FROM_GEO(model, geo) };
|
||||
memcpy(aHead, _Ls, sizeof(_Ls));
|
||||
aHead += (sizeof(_Ls) / sizeof(_Ls[0]));
|
||||
} else {
|
||||
u32 geoIndex = DynOS_Lua_RememberVariable(aGfxData, aHead + 1, aNode->mTokens[topTokenIndex + 1]);
|
||||
LevelScript _Ls[] = { LOAD_MODEL_FROM_GEO_EXT(model, geo) };
|
||||
memcpy(aHead, _Ls, sizeof(_Ls));
|
||||
aHead += (sizeof(_Ls) / sizeof(_Ls[0]));
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// Unknown
|
||||
PrintError(" ERROR: Unknown lvl symbol: %s", _Symbol.begin());
|
||||
}
|
||||
|
|
|
@ -393,9 +393,14 @@ void *DynOS_Pointer_Load(FILE *aFile, GfxData *aGfxData, u32 aValue, bool isLvl)
|
|||
// LUAV
|
||||
if (aValue == LUA_VAR_CODE) {
|
||||
String token; token.Read(aFile);
|
||||
for (s32 i = 0; i < aGfxData->mLuaTokenList.Count(); i++) {
|
||||
if (token == aGfxData->mLuaTokenList[i]) {
|
||||
return (void*)(uintptr_t)(i+1);
|
||||
}
|
||||
}
|
||||
u32 index = aGfxData->mLuaTokenList.Count();
|
||||
aGfxData->mLuaTokenList.Add(token);
|
||||
return aGfxData->mLuaTokenList[index].begin();
|
||||
return (void*)(uintptr_t)(index+1);
|
||||
}
|
||||
|
||||
// FUNC
|
||||
|
|
|
@ -108,6 +108,10 @@ LevelScript* dynos_level_get(const char* levelName) {
|
|||
return DynOS_Lvl_Get(levelName);
|
||||
}
|
||||
|
||||
const char* dynos_level_get_token(u32 index) {
|
||||
return DynOS_Lvl_Get_Token(index);
|
||||
}
|
||||
|
||||
struct MovtexQuadCollection *dynos_level_movtexqc_getfromindex(s32 index) {
|
||||
DataNode<MovtexQC> *node = DynOS_Lvl_MovtexQuadCollection_GetFromIndex(index);
|
||||
if (node == NULL) { return NULL; }
|
||||
|
|
|
@ -404,6 +404,8 @@ const void *DynOS_Geo_GetActorLayout(s32 aIndex) {
|
|||
}
|
||||
|
||||
const void *DynOS_Geo_GetActorLayoutFromName(const char *aActorName) {
|
||||
if (aActorName == NULL) { return NULL; }
|
||||
|
||||
// check levels
|
||||
for (auto& lvl : sDynosCustomLevelScripts) {
|
||||
for (auto& geo : lvl.second->mGeoLayouts) {
|
||||
|
@ -698,19 +700,47 @@ DataNode<TexData> *DynOS_Lvl_Texture_Get(void *aPtr) {
|
|||
return NULL;
|
||||
}
|
||||
|
||||
static GfxData* DynOS_Lvl_Get_Active_Gfx(void) {
|
||||
for (s32 i = 0; i < sDynosCustomLevelScripts.Count(); ++i) {
|
||||
auto& gfxData = sDynosCustomLevelScripts[i].second;
|
||||
auto& scripts = gfxData->mLevelScripts;
|
||||
if (gLevelScriptActive == scripts[scripts.Count() - 1]->mData) {
|
||||
return gfxData;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const char* DynOS_Lvl_Get_Token(u32 index) {
|
||||
GfxData* gfxData = DynOS_Lvl_Get_Active_Gfx();
|
||||
if (gfxData == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// have to 1-index due to to pointer read code
|
||||
index = index - 1;
|
||||
|
||||
if (index >= gfxData->mLuaTokenList.Count()) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return gfxData->mLuaTokenList[index].begin();
|
||||
}
|
||||
|
||||
DataNode<MovtexQC> *DynOS_Lvl_MovtexQuadCollection_GetFromIndex(s32 index) {
|
||||
s32 modIndex = gLevelScriptModIndex - 1;
|
||||
// Sanity check our currently loaded mod.
|
||||
if (modIndex < 0 || modIndex >= sDynosCustomLevelScripts.Count()) { return NULL; }
|
||||
|
||||
auto &mMovtexQCs = sDynosCustomLevelScripts[modIndex].second->mMovtexQCs;
|
||||
GfxData* gfxData = DynOS_Lvl_Get_Active_Gfx();
|
||||
if (gfxData == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
auto &mMovtexQCs = gfxData->mMovtexQCs;
|
||||
|
||||
// Sanity check the index we passed.
|
||||
if (index < 0 || index >= mMovtexQCs.Count()) { return NULL; }
|
||||
if (index < 0 || index >= mMovtexQCs.Count()) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
auto &movetexQC = mMovtexQCs[index];
|
||||
|
||||
return movetexQC;
|
||||
return mMovtexQCs[index];
|
||||
}
|
||||
|
||||
void DynOS_Lvl_Load_Background(void *aPtr) {
|
||||
|
|
|
@ -251,6 +251,7 @@ static void *DynOS_Warp_UpdateWarp(void *aCmd, bool aIsLevelInitDone) {
|
|||
sWarpDest.arg = 0;
|
||||
void* levelScript = (void *) DynOS_Level_GetScript(gCurrLevelNum);
|
||||
gLevelScriptModIndex = DynOS_Lvl_GetModIndex(levelScript);
|
||||
gLevelScriptActive = (LevelScript*)levelScript;
|
||||
return levelScript;
|
||||
|
||||
} else {
|
||||
|
|
|
@ -303,4 +303,8 @@
|
|||
#define OBJECT_EXT2(model, posX, posY, posZ, angleX, angleY, angleZ, behParam, beh) \
|
||||
OBJECT_WITH_ACTS_EXT2(model, posX, posY, posZ, angleX, angleY, angleZ, behParam, beh, 0x1F)
|
||||
|
||||
#define LOAD_MODEL_FROM_GEO_EXT(model, geo) \
|
||||
CMD_BBH(0x41, 0x08, model), \
|
||||
CMD_PTR(geo)
|
||||
|
||||
#endif // LEVEL_COMMANDS_H
|
||||
|
|
|
@ -41,6 +41,7 @@ struct LevelCommand {
|
|||
enum ScriptStatus { SCRIPT_RUNNING = 1, SCRIPT_PAUSED = 0, SCRIPT_PAUSED2 = -1 };
|
||||
|
||||
s32 gLevelScriptModIndex = -1;
|
||||
LevelScript* gLevelScriptActive = NULL;
|
||||
|
||||
static uintptr_t sStack[32];
|
||||
|
||||
|
@ -829,7 +830,7 @@ static void level_cmd_place_object_ext(void) {
|
|||
struct SpawnInfo *spawnInfo;
|
||||
|
||||
u16 modIndex = gLevelScriptModIndex;
|
||||
char* behStr = CMD_GET(char*, 20);
|
||||
const char* behStr = dynos_level_get_token(CMD_GET(u32, 20));
|
||||
|
||||
gSmLuaConvertSuccess = true;
|
||||
enum BehaviorId behId = smlua_get_mod_variable(modIndex, behStr);
|
||||
|
@ -872,8 +873,8 @@ static void level_cmd_place_object_ext2(void) {
|
|||
struct SpawnInfo *spawnInfo;
|
||||
|
||||
u16 modIndex = gLevelScriptModIndex;
|
||||
char* modelStr = CMD_GET(char*, 20);
|
||||
char* behStr = CMD_GET(char*, 24);
|
||||
const char* modelStr = dynos_level_get_token(CMD_GET(u32, 20));
|
||||
const char* behStr = dynos_level_get_token(CMD_GET(u32, 24));
|
||||
|
||||
gSmLuaConvertSuccess = true;
|
||||
enum ModelExtendedId modelId = smlua_get_mod_variable(modIndex, modelStr);
|
||||
|
@ -911,6 +912,19 @@ static void level_cmd_place_object_ext2(void) {
|
|||
sCurrentCmd = CMD_NEXT;
|
||||
}
|
||||
|
||||
static void level_cmd_load_model_from_geo_ext(void) {
|
||||
s16 modelSlot = CMD_GET(s16, 2);
|
||||
|
||||
const char* geoName = dynos_level_get_token(CMD_GET(u32, 4));
|
||||
u32 modelId = smlua_model_util_get_id(geoName);
|
||||
|
||||
if (modelSlot < 256) {
|
||||
smlua_model_util_load_with_pool_and_cache_id(modelId, sLevelPool, modelSlot);
|
||||
}
|
||||
|
||||
sCurrentCmd = CMD_NEXT;
|
||||
}
|
||||
|
||||
static void (*LevelScriptJumpTable[])(void) = {
|
||||
/*00*/ level_cmd_load_and_execute,
|
||||
/*01*/ level_cmd_exit_and_execute,
|
||||
|
@ -979,6 +993,7 @@ static void (*LevelScriptJumpTable[])(void) = {
|
|||
// coop
|
||||
/*3F*/ level_cmd_place_object_ext,
|
||||
/*40*/ level_cmd_place_object_ext2,
|
||||
/*41*/ level_cmd_load_model_from_geo_ext,
|
||||
};
|
||||
|
||||
struct LevelCommand *level_script_execute(struct LevelCommand *cmd) {
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
struct LevelCommand;
|
||||
|
||||
extern s32 gLevelScriptModIndex;
|
||||
extern LevelScript* gLevelScriptActive;
|
||||
|
||||
extern u8 level_script_entry[];
|
||||
|
||||
|
|
|
@ -798,26 +798,34 @@ void cur_obj_scale(f32 scale) {
|
|||
|
||||
void cur_obj_init_animation(s32 animIndex) {
|
||||
struct Animation **anims = o->oAnimations;
|
||||
geo_obj_init_animation(&o->header.gfx, &anims[animIndex]);
|
||||
if (anims != NULL) {
|
||||
geo_obj_init_animation(&o->header.gfx, &anims[animIndex]);
|
||||
}
|
||||
}
|
||||
|
||||
void cur_obj_init_animation_with_sound(s32 animIndex) {
|
||||
struct Animation **anims = o->oAnimations;
|
||||
geo_obj_init_animation(&o->header.gfx, &anims[animIndex]);
|
||||
if (anims != NULL) {
|
||||
geo_obj_init_animation(&o->header.gfx, &anims[animIndex]);
|
||||
}
|
||||
o->oSoundStateID = animIndex;
|
||||
}
|
||||
|
||||
void cur_obj_init_animation_with_accel_and_sound(s32 animIndex, f32 accel) {
|
||||
struct Animation **anims = o->oAnimations;
|
||||
s32 animAccel = (s32)(accel * 65536.0f);
|
||||
geo_obj_init_animation_accel(&o->header.gfx, &anims[animIndex], animAccel);
|
||||
if (anims != NULL) {
|
||||
s32 animAccel = (s32)(accel * 65536.0f);
|
||||
geo_obj_init_animation_accel(&o->header.gfx, &anims[animIndex], animAccel);
|
||||
}
|
||||
o->oSoundStateID = animIndex;
|
||||
}
|
||||
|
||||
void obj_init_animation_with_sound(struct Object *obj, const struct Animation * const* animations, s32 animIndex) {
|
||||
struct Animation **anims = (struct Animation **)animations;
|
||||
obj->oAnimations = (struct Animation **)animations;
|
||||
geo_obj_init_animation(&obj->header.gfx, &anims[animIndex]);
|
||||
if (anims != NULL) {
|
||||
geo_obj_init_animation(&obj->header.gfx, &anims[animIndex]);
|
||||
}
|
||||
obj->oSoundStateID = animIndex;
|
||||
}
|
||||
|
||||
|
|
|
@ -372,7 +372,7 @@ lua_Number smlua_get_number_field(int index, char* name) {
|
|||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
s64 smlua_get_mod_variable(u16 modIndex, char* variable) {
|
||||
s64 smlua_get_mod_variable(u16 modIndex, const char* variable) {
|
||||
lua_State* L = gLuaState;
|
||||
|
||||
// figure out entry
|
||||
|
@ -385,7 +385,7 @@ s64 smlua_get_mod_variable(u16 modIndex, char* variable) {
|
|||
int prevTop = lua_gettop(L);
|
||||
lua_getglobal(L, "_G"); // get global table
|
||||
lua_getfield(L, LUA_REGISTRYINDEX, mod->relativePath); // get the file's "global" table
|
||||
s64 value = smlua_get_integer_field(-1, variable);
|
||||
s64 value = smlua_get_integer_field(-1, (char*)variable);
|
||||
lua_settop(L, prevTop);
|
||||
|
||||
// return variable
|
||||
|
|
|
@ -34,7 +34,7 @@ lua_Number smlua_get_number_field(int index, char* name);
|
|||
|
||||
char* smlua_lnt_to_str(struct LSTNetworkType* lnt);
|
||||
|
||||
s64 smlua_get_mod_variable(u16 modIndex, char* variable) ;
|
||||
s64 smlua_get_mod_variable(u16 modIndex, const char* variable) ;
|
||||
|
||||
void smlua_logline(void);
|
||||
void smlua_dump_stack(void);
|
||||
|
|
|
@ -480,7 +480,7 @@ void smlua_model_util_clear(void) {
|
|||
}
|
||||
}
|
||||
|
||||
u8 smlua_model_util_load_with_pool(enum ModelExtendedId id, struct AllocOnlyPool* pool) {
|
||||
u8 smlua_model_util_load_with_pool_and_cache_id(enum ModelExtendedId id, struct AllocOnlyPool* pool, u8 cacheId) {
|
||||
if (id == E_MODEL_NONE) { return MODEL_NONE; }
|
||||
if (id == E_MODEL_MAX) { LOG_ERROR("id invalid"); return MODEL_NONE; }
|
||||
if (id > E_MODEL_MAX + sCustomModelsCount) { LOG_ERROR("id invalid"); return MODEL_NONE; }
|
||||
|
@ -496,21 +496,25 @@ u8 smlua_model_util_load_with_pool(enum ModelExtendedId id, struct AllocOnlyPool
|
|||
}
|
||||
|
||||
// find cached asset
|
||||
bool foundEmptyCacheId = false;
|
||||
u8 emptyCacheId = 0;
|
||||
for (int i = 0; i < 255; i++) {
|
||||
if (sCachedAssets[i].asset == info->asset) {
|
||||
//LOG_INFO("Found in cached assets");
|
||||
return sCachedAssets[i].id;
|
||||
if (cacheId == 0) {
|
||||
bool foundEmptyCacheId = false;
|
||||
for (int i = 0; i < 255; i++) {
|
||||
if (sCachedAssets[i].asset == info->asset) {
|
||||
//LOG_INFO("Found in cached assets");
|
||||
return sCachedAssets[i].id;
|
||||
}
|
||||
if (sCachedAssets[i].asset == NULL) {
|
||||
foundEmptyCacheId = true;
|
||||
emptyCacheId = i;
|
||||
}
|
||||
}
|
||||
if (sCachedAssets[i].asset == NULL) {
|
||||
foundEmptyCacheId = true;
|
||||
emptyCacheId = i;
|
||||
if (!foundEmptyCacheId) {
|
||||
LOG_ERROR("No empty cache");
|
||||
return 0xFF;
|
||||
}
|
||||
}
|
||||
if (!foundEmptyCacheId) {
|
||||
LOG_ERROR("No empty cache");
|
||||
return 0xFF;
|
||||
} else {
|
||||
emptyCacheId = cacheId;
|
||||
}
|
||||
|
||||
// load
|
||||
|
@ -537,6 +541,10 @@ u8 smlua_model_util_load_with_pool(enum ModelExtendedId id, struct AllocOnlyPool
|
|||
return emptyCacheId;
|
||||
}
|
||||
|
||||
u8 smlua_model_util_load_with_pool(enum ModelExtendedId id, struct AllocOnlyPool* pool) {
|
||||
return smlua_model_util_load_with_pool_and_cache_id(id, pool, 0);
|
||||
}
|
||||
|
||||
u8 smlua_model_util_load(enum ModelExtendedId id) {
|
||||
return smlua_model_util_load_with_pool(id, NULL);
|
||||
}
|
||||
|
|
|
@ -392,6 +392,7 @@ enum ModelExtendedId {
|
|||
|
||||
void smlua_model_util_remember(u8 modelId, u8 layer, const void* asset, u8 isDisplayList);
|
||||
void smlua_model_util_clear(void);
|
||||
u8 smlua_model_util_load_with_pool_and_cache_id(enum ModelExtendedId id, struct AllocOnlyPool* pool, u8 cacheId);
|
||||
u8 smlua_model_util_load_with_pool(enum ModelExtendedId id, struct AllocOnlyPool* pool);
|
||||
u8 smlua_model_util_load(enum ModelExtendedId id);
|
||||
u32 smlua_model_util_get_id(const char* name);
|
||||
|
|
Loading…
Reference in New Issue