From c1e33f5e708b42c6dae02cc9735178a1dfb4b7e9 Mon Sep 17 00:00:00 2001 From: MysterD Date: Mon, 24 Apr 2023 01:01:50 -0700 Subject: [PATCH] Doubled extended model id size, avoided using vanilla object slots --- src/engine/level_script.c | 24 +++++++----- src/game/area.h | 4 +- src/game/object_helpers.c | 3 ++ src/game/object_helpers.h | 2 +- src/pc/lua/utils/smlua_model_utils.c | 37 +++++++++---------- src/pc/lua/utils/smlua_model_utils.h | 8 ++-- src/pc/lua/utils/smlua_obj_utils.c | 12 +++--- src/pc/network/packets/packet_spawn_objects.c | 4 +- 8 files changed, 52 insertions(+), 42 deletions(-) diff --git a/src/engine/level_script.c b/src/engine/level_script.c index 2020406c9..ddc5943cb 100644 --- a/src/engine/level_script.c +++ b/src/engine/level_script.c @@ -452,9 +452,8 @@ static void level_cmd_load_model_from_dl(void) { s16 val2 = ((u16)CMD_GET(s16, 2)) >> 12; void *val3 = CMD_GET(void *, 4); - if (val1 < 256) { - gLoadedGraphNodes[val1] = - (struct GraphNode *) init_graph_node_display_list(sLevelPool, 0, val2, val3); + if (val1 < MAX_LOADED_GRAPH_NODES) { + gLoadedGraphNodes[val1] = (struct GraphNode *) init_graph_node_display_list(sLevelPool, 0, val2, val3); sLevelOwnedGraphNodes[val1] = true; smlua_model_util_remember(val1, val2, val3, 1); } @@ -466,7 +465,7 @@ static void level_cmd_load_model_from_geo(void) { s16 arg0 = CMD_GET(s16, 2); void *arg1 = CMD_GET(void *, 4); - if (arg0 < 256) { + if (arg0 < MAX_LOADED_GRAPH_NODES) { gLoadedGraphNodes[arg0] = process_geo_layout(sLevelPool, arg1); sLevelOwnedGraphNodes[arg0] = true; smlua_model_util_remember(arg0, LAYER_OPAQUE, arg1, 0); @@ -487,11 +486,10 @@ static void level_cmd_23(void) { // load an f32, but using an integer load instruction for some reason (hence the union) arg2.i = CMD_GET(s32, 8); - if (model < 256) { + if (model < MAX_LOADED_GRAPH_NODES) { // GraphNodeScale has a GraphNode at the top. This // is being stored to the array, so cast the pointer. - gLoadedGraphNodes[model] = - (struct GraphNode *) init_graph_node_scale(sLevelPool, 0, arg0H, arg1, arg2.f); + gLoadedGraphNodes[model] = (struct GraphNode *) init_graph_node_scale(sLevelPool, 0, arg0H, arg1, arg2.f); sLevelOwnedGraphNodes[model] = true; smlua_model_util_remember(model, arg0H, arg1, 1); } @@ -503,7 +501,9 @@ static void level_cmd_init_mario(void) { u32 behaviorArg = CMD_GET(u32, 4); behaviorArg = behaviorArg; void* behaviorScript = CMD_GET(void*, 8); - struct GraphNode* unk18 = gLoadedGraphNodes[CMD_GET(u8, 3)]; + u16 slot = CMD_GET(u8, 3); + if (slot >= MAX_LOADED_GRAPH_NODES) { slot = MODEL_NONE; } + struct GraphNode* unk18 = gLoadedGraphNodes[slot]; struct SpawnInfo* lastSpawnInfo = NULL; for (s32 i = 0; i < MAX_PLAYERS; i++) { @@ -535,6 +535,7 @@ static void level_cmd_place_object(void) { if (sCurrAreaIndex != -1 && (gLevelValues.disableActs || (CMD_GET(u8, 2) & val7) || CMD_GET(u8, 2) == 0x1F)) { model = CMD_GET(u8, 3); + if (model >= MAX_LOADED_GRAPH_NODES) { model = MODEL_NONE; } spawnInfo = alloc_only_pool_alloc(sLevelPool, sizeof(struct SpawnInfo)); spawnInfo->startPos[0] = CMD_GET(s16, 4); @@ -933,6 +934,7 @@ static void level_cmd_place_object_ext(void) { if (sCurrAreaIndex != -1 && ((CMD_GET(u8, 2) & val7) || CMD_GET(u8, 2) == 0x1F)) { u16 model = CMD_GET(u8, 3); + if (model >= MAX_LOADED_GRAPH_NODES) { model = MODEL_NONE; } spawnInfo = alloc_only_pool_alloc(sLevelPool, sizeof(struct SpawnInfo)); spawnInfo->startPos[0] = CMD_GET(s16, 4); @@ -1019,7 +1021,9 @@ static void level_cmd_place_object_ext2(void) { spawnInfo->behaviorArg = CMD_GET(u32, 16); spawnInfo->behaviorScript = (BehaviorScript*)get_behavior_from_id(behId); - spawnInfo->unk18 = gLoadedGraphNodes[smlua_model_util_load_with_pool(modelId, sLevelPool)]; + u16 slot = smlua_model_util_load_with_pool(modelId, sLevelPool); + if (slot >= MAX_LOADED_GRAPH_NODES) { slot = MODEL_NONE; } + spawnInfo->unk18 = gLoadedGraphNodes[slot]; spawnInfo->next = gAreas[sCurrAreaIndex].objectSpawnInfos; spawnInfo->syncID = spawnInfo->next @@ -1039,7 +1043,7 @@ static void level_cmd_load_model_from_geo_ext(void) { const char* geoName = dynos_level_get_token(CMD_GET(u32, 4)); u32 modelId = smlua_model_util_get_id(geoName); - if (modelSlot < 256) { + if (modelSlot < MAX_LOADED_GRAPH_NODES) { smlua_model_util_load_with_pool_and_cache_id(modelId, sLevelPool, modelSlot); } diff --git a/src/game/area.h b/src/game/area.h index d3e819754..19f0b5afb 100644 --- a/src/game/area.h +++ b/src/game/area.h @@ -7,7 +7,9 @@ #include "camera.h" #include "engine/graph_node.h" -#define MAX_LOADED_GRAPH_NODES 0x100 +#define LOADED_GRAPH_NODES_VANILLA 256 +#define LOADED_GRAPH_NODES_EXTENDED 512 +#define MAX_LOADED_GRAPH_NODES (LOADED_GRAPH_NODES_VANILLA + LOADED_GRAPH_NODES_EXTENDED) struct WarpNode { diff --git a/src/game/object_helpers.c b/src/game/object_helpers.c index b5290f3c4..f969304e3 100644 --- a/src/game/object_helpers.c +++ b/src/game/object_helpers.c @@ -675,6 +675,7 @@ struct Object *spawn_object_at_origin(struct Object *parent, UNUSED s32 unusedAr obj->header.gfx.activeAreaIndex = parent->header.gfx.areaIndex; obj->globalPlayerIndex = 0; + if (model >= MAX_LOADED_GRAPH_NODES) { model = MODEL_NONE; } geo_obj_init((struct GraphNodeObject *) &obj->header.gfx, gLoadedGraphNodes[model], gVec3fZero, gVec3sZero); smlua_call_event_hooks_object_model_param(HOOK_OBJECT_SET_MODEL, obj, model); @@ -1373,6 +1374,7 @@ void cur_obj_set_model(s32 modelID) { } void obj_set_model(struct Object* obj, s32 modelID) { + if (modelID >= MAX_LOADED_GRAPH_NODES) { modelID = MODEL_NONE; } obj->header.gfx.sharedChild = gLoadedGraphNodes[modelID]; dynos_actor_override((void*)&obj->header.gfx.sharedChild); smlua_call_event_hooks_object_model_param(HOOK_OBJECT_SET_MODEL, obj, modelID); @@ -3115,6 +3117,7 @@ s32 cur_obj_update_dialog_with_cutscene(struct MarioState* m, s32 actionArg, s32 } s32 cur_obj_has_model(u16 modelID) { + if (modelID >= MAX_LOADED_GRAPH_NODES) { return FALSE; } if (o->header.gfx.sharedChild == gLoadedGraphNodes[modelID]) { return TRUE; } else if (o->header.gfx.sharedChild && gLoadedGraphNodes[modelID] && o->header.gfx.sharedChild->georef == gLoadedGraphNodes[modelID]->georef) { diff --git a/src/game/object_helpers.h b/src/game/object_helpers.h index 1ff092cdc..570477e6f 100644 --- a/src/game/object_helpers.h +++ b/src/game/object_helpers.h @@ -55,7 +55,7 @@ struct SpawnParticlesInfo { /*0x00*/ s8 behParam; /*0x01*/ s8 count; - /*0x02*/ u8 model; + /*0x02*/ u16 model; /*0x03*/ s8 offsetY; /*0x04*/ s8 forwardVelBase; /*0x05*/ s8 forwardVelRange; diff --git a/src/pc/lua/utils/smlua_model_utils.c b/src/pc/lua/utils/smlua_model_utils.c index 9a20557a8..705169d27 100644 --- a/src/pc/lua/utils/smlua_model_utils.c +++ b/src/pc/lua/utils/smlua_model_utils.c @@ -58,14 +58,14 @@ struct ModelUtilsInfo { enum ModelExtendedId extId; u8 layer; - u8 loadedId; + u16 loadedId; bool permanent; bool isDisplayList; const void* asset; u8 shouldFreeAsset; }; -#define UNLOADED_ID 0xFF +#define UNLOADED_ID 0xFFFF #define MODEL_UTIL_GEO(x, y) [x] = { .extId = x, .asset = y, .layer = LAYER_OPAQUE, .isDisplayList = false, .loadedId = UNLOADED_ID, .permanent = false } #define MODEL_UTIL_DL(x, y, z) [x] = { .extId = x, .asset = y, .layer = z, .isDisplayList = true, .loadedId = UNLOADED_ID, .permanent = false } @@ -468,11 +468,10 @@ struct ModelUtilsInfo sModels[E_MODEL_MAX] = { struct ModelUtilsInfo sCustomModels[MAX_CUSTOM_MODELS] = { 0 }; static u16 sCustomModelsCount = 0; -#define MAX_CACHED_ASSETS 256 -struct ModelUtilsInfo* sCachedAssets[MAX_CACHED_ASSETS] = { 0 }; -bool sCachedAssetTaken[MAX_CACHED_ASSETS] = { 0 }; +struct ModelUtilsInfo* sCachedAssets[MAX_LOADED_GRAPH_NODES] = { 0 }; +bool sCachedAssetTaken[MAX_LOADED_GRAPH_NODES] = { 0 }; -void smlua_model_util_remember(u8 loadedId, UNUSED u8 layer, const void* asset, UNUSED u8 isDisplayList) { +void smlua_model_util_remember(u16 loadedId, UNUSED u8 layer, const void* asset, UNUSED u8 isDisplayList) { struct ModelUtilsInfo* found = NULL; // find in sModels @@ -502,10 +501,10 @@ void smlua_model_util_remember(u8 loadedId, UNUSED u8 layer, const void* asset, // remember if (sCachedAssetTaken[loadedId] && sCachedAssets[loadedId] != found) { if (sCachedAssets[loadedId]->permanent) { - // TODO: we need to restore the permanent model afterward - LOG_ERROR("OVERRIDING PERMANENT MODEL: %u -> %u", sCachedAssets[loadedId]->loadedId, loadedId); + LOG_ERROR("Tried to override permanent model: %u -> %u", sCachedAssets[loadedId]->loadedId, loadedId); + return; } else { - LOG_INFO("Overriding model: loadedId %u was extId %u, now extId %u", loadedId, sCachedAssets[loadedId]->extId, found->extId); + //LOG_INFO("Overriding model: loadedId %u was extId %u, now extId %u", loadedId, sCachedAssets[loadedId]->extId, found->extId); } sCachedAssets[loadedId]->loadedId = UNLOADED_ID; } @@ -530,10 +529,9 @@ void smlua_model_util_reset(void) { } void smlua_model_util_clear(void) { - // TODO: we need to restore replaced permanent models - for (int i = 0; i < MAX_CACHED_ASSETS; i++) { + for (int i = 0; i < MAX_LOADED_GRAPH_NODES; i++) { struct ModelUtilsInfo* m = sCachedAssets[i]; - if (m == NULL || m->permanent) { continue; } + if (m == NULL) { continue; } //LOG_INFO("Forget: %u -> %u", m->extId, m->loadedId); m->loadedId = UNLOADED_ID; if (m->asset && m->shouldFreeAsset) { @@ -545,10 +543,10 @@ void smlua_model_util_clear(void) { sCachedAssetTaken[i] = false; } - //LOG_INFO("Cleared runtime model cache."); + LOG_INFO("Cleared runtime model cache."); } -u8 smlua_model_util_load_with_pool_and_cache_id(enum ModelExtendedId extId, struct AllocOnlyPool* pool, u8 loadedId) { +u16 smlua_model_util_load_with_pool_and_cache_id(enum ModelExtendedId extId, struct AllocOnlyPool* pool, u16 loadedId) { if (extId == E_MODEL_NONE) { return MODEL_NONE; } if (extId >= (u16)(E_MODEL_MAX + sCustomModelsCount)) { LOG_ERROR("Tried to load invalid extId: %u >= %u (%u)", extId, (E_MODEL_MAX + sCustomModelsCount), sCustomModelsCount); @@ -566,15 +564,15 @@ u8 smlua_model_util_load_with_pool_and_cache_id(enum ModelExtendedId extId, stru } // find cached asset - u8 pickLoadedId = loadedId; + u16 pickLoadedId = loadedId; if (loadedId == UNLOADED_ID) { - for (s32 i = 0; i < (MAX_CACHED_ASSETS-1); i++) { + for (s32 i = 0; i < (MAX_LOADED_GRAPH_NODES-1); i++) { struct ModelUtilsInfo* m = sCachedAssets[i]; if (m == info) { //LOG_INFO("Found in cache (but late, confused?) - %u -> %u", extId, i); info->loadedId = m->loadedId; return info->loadedId; - } else if (!sCachedAssetTaken[i]) { + } else if (i >= LOADED_GRAPH_NODES_VANILLA && !sCachedAssetTaken[i]) { pickLoadedId = i; } } @@ -616,6 +614,7 @@ u8 smlua_model_util_load_with_pool_and_cache_id(enum ModelExtendedId extId, stru info->isDisplayList = false; } gLoadedGraphNodes[pickLoadedId] = dynos_geolayout_to_graphnode(info->asset, true); + LOG_ERROR("XXXXXXXXXXXXXXXXXXXXXXXXXX"); } // remember @@ -625,11 +624,11 @@ u8 smlua_model_util_load_with_pool_and_cache_id(enum ModelExtendedId extId, stru return pickLoadedId; } -u8 smlua_model_util_load_with_pool(enum ModelExtendedId extId, struct AllocOnlyPool* pool) { +u16 smlua_model_util_load_with_pool(enum ModelExtendedId extId, struct AllocOnlyPool* pool) { return smlua_model_util_load_with_pool_and_cache_id(extId, pool, UNLOADED_ID); } -u8 smlua_model_util_load(enum ModelExtendedId extId) { +u16 smlua_model_util_load(enum ModelExtendedId extId) { return smlua_model_util_load_with_pool(extId, NULL); } diff --git a/src/pc/lua/utils/smlua_model_utils.h b/src/pc/lua/utils/smlua_model_utils.h index 1edf1bb29..730b3cc8c 100644 --- a/src/pc/lua/utils/smlua_model_utils.h +++ b/src/pc/lua/utils/smlua_model_utils.h @@ -395,12 +395,12 @@ enum ModelExtendedId { E_MODEL_MAX }; -void smlua_model_util_remember(u8 loadedId, u8 layer, const void* asset, u8 isDisplayList); +void smlua_model_util_remember(u16 loadedId, u8 layer, const void* asset, u8 isDisplayList); void smlua_model_util_reset(void); void smlua_model_util_clear(void); -u8 smlua_model_util_load_with_pool_and_cache_id(enum ModelExtendedId extId, struct AllocOnlyPool* pool, u8 loadedId); -u8 smlua_model_util_load_with_pool(enum ModelExtendedId extId, struct AllocOnlyPool* pool); -u8 smlua_model_util_load(enum ModelExtendedId extId); +u16 smlua_model_util_load_with_pool_and_cache_id(enum ModelExtendedId extId, struct AllocOnlyPool* pool, u16 loadedId); +u16 smlua_model_util_load_with_pool(enum ModelExtendedId extId, struct AllocOnlyPool* pool); +u16 smlua_model_util_load(enum ModelExtendedId extId); u32 smlua_model_util_get_id(const char* name); #endif diff --git a/src/pc/lua/utils/smlua_obj_utils.c b/src/pc/lua/utils/smlua_obj_utils.c index 9b86ab0f8..1ac6956eb 100644 --- a/src/pc/lua/utils/smlua_obj_utils.c +++ b/src/pc/lua/utils/smlua_obj_utils.c @@ -22,8 +22,8 @@ static struct Object* spawn_object_internal(enum BehaviorId behaviorId, enum Mod return NULL; } - u8 loadedModelId = smlua_model_util_load(modelId); - if (loadedModelId == 0xFF) { + u16 loadedModelId = smlua_model_util_load(modelId); + if (loadedModelId >= MAX_LOADED_GRAPH_NODES) { LOG_ERROR("failed to load model %u", modelId); return NULL; } @@ -92,7 +92,9 @@ s32 obj_has_behavior_id(struct Object *o, enum BehaviorId behaviorId) { } s32 obj_has_model_extended(struct Object *o, enum ModelExtendedId modelId) { - struct GraphNode *model = gLoadedGraphNodes[smlua_model_util_load(modelId)]; + u16 slot = smlua_model_util_load(modelId); + if (slot >= MAX_LOADED_GRAPH_NODES) { return false; } + struct GraphNode *model = gLoadedGraphNodes[slot]; return o->header.gfx.sharedChild == model; } @@ -246,8 +248,8 @@ struct SpawnParticlesInfo* obj_get_temp_spawn_particles_info(enum ModelExtendedI static struct SpawnParticlesInfo sTmpSpi = { 0 }; memset(&sTmpSpi, 0, sizeof(struct SpawnParticlesInfo)); - u8 loadedModelId = smlua_model_util_load(modelId); - if (loadedModelId == 0xFF) { + u16 loadedModelId = smlua_model_util_load(modelId); + if (loadedModelId >= MAX_LOADED_GRAPH_NODES) { LOG_ERROR("failed to load model %u", modelId); return NULL; } diff --git a/src/pc/network/packets/packet_spawn_objects.c b/src/pc/network/packets/packet_spawn_objects.c index 6bca15873..189f4146c 100644 --- a/src/pc/network/packets/packet_spawn_objects.c +++ b/src/pc/network/packets/packet_spawn_objects.c @@ -177,8 +177,8 @@ void network_receive_spawn_objects(struct Packet* p) { // load extended model if (data.extendedModelId != 0xFFFF) { - u8 loadedModelId = smlua_model_util_load(data.extendedModelId); - if (loadedModelId != 0xFF) { + u16 loadedModelId = smlua_model_util_load(data.extendedModelId); + if (loadedModelId < MAX_LOADED_GRAPH_NODES) { data.model = loadedModelId; } }