mirror of
				https://github.com/coop-deluxe/sm64coopdx.git
				synced 2025-10-30 08:01:01 +00:00 
			
		
		
		
	Added ability for mods to load custom geos
This commit is contained in:
		
							parent
							
								
									1e96340b1d
								
							
						
					
					
						commit
						edf06bede0
					
				
					 16 changed files with 210 additions and 22 deletions
				
			
		| 
						 | 
				
			
			@ -39,6 +39,7 @@ in_files = [
 | 
			
		|||
    "src/pc/lua/utils/smlua_obj_utils.h",
 | 
			
		||||
    "src/pc/lua/utils/smlua_misc_utils.h",
 | 
			
		||||
    'src/pc/lua/utils/smlua_collision_utils.h',
 | 
			
		||||
    'src/pc/lua/utils/smlua_model_utils.h',
 | 
			
		||||
    "src/game/object_helpers.c",
 | 
			
		||||
    "src/game/obj_behaviors.c",
 | 
			
		||||
    "src/game/obj_behaviors_2.c",
 | 
			
		||||
| 
						 | 
				
			
			@ -47,11 +48,12 @@ in_files = [
 | 
			
		|||
]
 | 
			
		||||
 | 
			
		||||
override_allowed_functions = {
 | 
			
		||||
    "src/audio/external.h":           [ " play_", "fade" ],
 | 
			
		||||
    "src/game/camera.h":              [ "set_.*camera_.*shake", "set_camera_mode" ],
 | 
			
		||||
    "src/game/rumble_init.c":         [ "queue_rumble_"],
 | 
			
		||||
    "src/pc/djui/djui_popup.h" :      [ "create" ],
 | 
			
		||||
    "src/game/save_file.h":           [ "save_file_get_" ],
 | 
			
		||||
    "src/audio/external.h":                 [ " play_", "fade" ],
 | 
			
		||||
    "src/game/camera.h":                    [ "set_.*camera_.*shake", "set_camera_mode" ],
 | 
			
		||||
    "src/game/rumble_init.c":               [ "queue_rumble_"],
 | 
			
		||||
    "src/pc/djui/djui_popup.h" :            [ "create" ],
 | 
			
		||||
    "src/game/save_file.h":                 [ "save_file_get_" ],
 | 
			
		||||
    "src/pc/lua/utils/smlua_model_utils.h": [ "smlua_model_util_get_id" ],
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
override_disallowed_functions = {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -259,5 +259,6 @@ end
 | 
			
		|||
--- @param flags2 number
 | 
			
		||||
--- @return number
 | 
			
		||||
function SOUND_ARG_LOAD(bank, playFlags, soundID, priority, flags2)
 | 
			
		||||
    if flags2 == nil then flags2 = 0 end
 | 
			
		||||
    return ((bank << 28) | (playFlags << 24) | (soundID << 16) | (priority << 8) | (flags2 << 4) | 1)
 | 
			
		||||
end
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -261,6 +261,7 @@ end
 | 
			
		|||
--- @param flags2 number
 | 
			
		||||
--- @return number
 | 
			
		||||
function SOUND_ARG_LOAD(bank, playFlags, soundID, priority, flags2)
 | 
			
		||||
    if flags2 == nil then flags2 = 0 end
 | 
			
		||||
    return ((bank << 28) | (playFlags << 24) | (soundID << 16) | (priority << 8) | (flags2 << 4) | 1)
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -2347,7 +2348,7 @@ SHAKE_SHOCK = 10
 | 
			
		|||
SHAKE_SMALL_DAMAGE = 3
 | 
			
		||||
 | 
			
		||||
--- @type integer
 | 
			
		||||
PALETTE_MAX = 24
 | 
			
		||||
PALETTE_MAX = 30
 | 
			
		||||
 | 
			
		||||
--- @class CharacterSound
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -3516,6 +3516,12 @@ function warp_to_level(aLevel, aArea, aAct)
 | 
			
		|||
    -- ...
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
--- @param name string
 | 
			
		||||
--- @return integer
 | 
			
		||||
function smlua_model_util_get_id(name)
 | 
			
		||||
    -- ...
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
--- @return ObjectHitbox
 | 
			
		||||
function get_temp_object_hitbox()
 | 
			
		||||
    -- ...
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -662,6 +662,11 @@ s32 DynOS_String_Width(const u8 *aStr64);
 | 
			
		|||
// Geo
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
#ifdef COOP
 | 
			
		||||
void DynOS_Geo_AddActorCustom(const SysPath &aPackFolder, const char *aActorName);
 | 
			
		||||
const void *DynOS_Geo_GetActorLayoutFromName(const char *aActorName);
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
s32 DynOS_Geo_GetActorCount();
 | 
			
		||||
const char *DynOS_Geo_GetActorName(s32 aIndex);
 | 
			
		||||
const void *DynOS_Geo_GetActorLayout(s32 aIndex);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -13,6 +13,8 @@ const char* dynos_packs_get(s32 index);
 | 
			
		|||
bool dynos_packs_get_enabled(s32 index);
 | 
			
		||||
void dynos_packs_set_enabled(s32 index, bool value);
 | 
			
		||||
 | 
			
		||||
const void* dynos_geolayout_get(const char *name);
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
#endif
 | 
			
		||||
#endif
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -53,5 +53,9 @@ void dynos_packs_set_enabled(s32 index, bool value) {
 | 
			
		|||
    DynOS_Gfx_GetPacksEnabled()[index] = value;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const void* dynos_geolayout_get(const char *name) {
 | 
			
		||||
    return DynOS_Geo_GetActorLayoutFromName(name);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1826,6 +1826,9 @@ void DynOS_Gfx_GeneratePack(const SysPath &aPackFolder) {
 | 
			
		|||
            // If there is an existing binary file for this layout, skip and go to the next actor
 | 
			
		||||
            SysPath _BinFilename = fstring("%s/%s.bin", aPackFolder.c_str(), _GeoRootName.begin());
 | 
			
		||||
            if (fs_sys_file_exists(_BinFilename.c_str())) {
 | 
			
		||||
#ifdef COOP
 | 
			
		||||
                DynOS_Geo_AddActorCustom(aPackFolder, _GeoRootName.begin());
 | 
			
		||||
#endif
 | 
			
		||||
                continue;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1881,7 +1884,10 @@ void DynOS_Gfx_GeneratePack(const SysPath &aPackFolder) {
 | 
			
		|||
            } else {
 | 
			
		||||
                Print("  %u error(s): Unable to parse data", _GfxData->mErrorCount);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
#ifdef COOP
 | 
			
		||||
            // Add to custom actors
 | 
			
		||||
            DynOS_Geo_AddActorCustom(aPackFolder, _GeoRootName.begin());
 | 
			
		||||
#endif
 | 
			
		||||
            // Clear data pointers
 | 
			
		||||
            ClearGfxDataNodes(_GfxData->mLights);
 | 
			
		||||
            ClearGfxDataNodes(_GfxData->mTextures);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -336,6 +336,76 @@ define_actor(warios_winged_metal_cap_geo),
 | 
			
		|||
#endif
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#ifdef COOP
 | 
			
		||||
static Array<Pair<const char*, void *>> sDynosCustomActors;
 | 
			
		||||
 | 
			
		||||
void DynOS_Geo_AddActorCustom(const SysPath &aPackFolder, const char *aActorName) {
 | 
			
		||||
    // check for duplicates
 | 
			
		||||
    for (s32 i = 0; i < DynOS_Geo_GetActorCount(); ++i) {
 | 
			
		||||
        if (!strcmp(DynOS_Geo_GetActorName(i), aActorName)) {
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    GfxData *_GfxData = DynOS_Gfx_LoadFromBinary(aPackFolder, aActorName);
 | 
			
		||||
    if (!_GfxData) {
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void* geoLayout = (*(_GfxData->mGeoLayouts.end() - 1))->mData;
 | 
			
		||||
    if (!geoLayout) {
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Add to custom actors
 | 
			
		||||
    s32 index = DynOS_Geo_GetActorCount();
 | 
			
		||||
    sDynosCustomActors.Add({ strdup(aActorName), geoLayout });
 | 
			
		||||
 | 
			
		||||
    // Alloc and init the actors gfx list
 | 
			
		||||
    Array<ActorGfx> &pActorGfxList = DynOS_Gfx_GetActorList();
 | 
			
		||||
    pActorGfxList.Resize(DynOS_Geo_GetActorCount());
 | 
			
		||||
    pActorGfxList[index].mPackIndex = -1;
 | 
			
		||||
    pActorGfxList[index].mGfxData   = NULL; // maybe _GfxData?
 | 
			
		||||
    pActorGfxList[index].mGraphNode = (GraphNode *) DynOS_Geo_GetGraphNode(DynOS_Geo_GetActorLayout(index), true);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
s32 DynOS_Geo_GetActorCount() {
 | 
			
		||||
    s32 arrayCount = (s32) (sizeof(sDynosActors) / (2 * sizeof(sDynosActors[0])));
 | 
			
		||||
    return (s32) arrayCount + sDynosCustomActors.Count();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const char *DynOS_Geo_GetActorName(s32 aIndex) {
 | 
			
		||||
    s32 arrayCount = (s32) (sizeof(sDynosActors) / (2 * sizeof(sDynosActors[0])));
 | 
			
		||||
    if (aIndex < arrayCount) { return (const char *) sDynosActors[2 * aIndex]; }
 | 
			
		||||
    return sDynosCustomActors[aIndex - arrayCount].first;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const void *DynOS_Geo_GetActorLayout(s32 aIndex) {
 | 
			
		||||
    s32 arrayCount = (s32) (sizeof(sDynosActors) / (2 * sizeof(sDynosActors[0])));
 | 
			
		||||
    if (aIndex < arrayCount) { return (const void *) sDynosActors[2 * aIndex + 1]; }
 | 
			
		||||
    return sDynosCustomActors[aIndex - arrayCount].second;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const void *DynOS_Geo_GetActorLayoutFromName(const char *aActorName) {
 | 
			
		||||
    for (s32 i = 0; i < DynOS_Geo_GetActorCount(); ++i) {
 | 
			
		||||
        if (!strcmp(DynOS_Geo_GetActorName(i), aActorName)) {
 | 
			
		||||
            return DynOS_Geo_GetActorLayout(i);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    return NULL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
s32 DynOS_Geo_GetActorIndex(const void *aGeoLayout) {
 | 
			
		||||
    for (s32 i = 0; i < DynOS_Geo_GetActorCount(); ++i) {
 | 
			
		||||
        if (DynOS_Geo_GetActorLayout(i) == aGeoLayout) {
 | 
			
		||||
            return i;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    return -1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#else // NORMAL DYNOS
 | 
			
		||||
 | 
			
		||||
s32 DynOS_Geo_GetActorCount() {
 | 
			
		||||
    return (s32) (sizeof(sDynosActors) / (2 * sizeof(sDynosActors[0])));
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -357,6 +427,8 @@ s32 DynOS_Geo_GetActorIndex(const void *aGeoLayout) {
 | 
			
		|||
    return -1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif // NORMAL DYNOS END
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
// Geo Functions
 | 
			
		||||
//
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -644,6 +644,11 @@
 | 
			
		|||
 | 
			
		||||
<br />
 | 
			
		||||
 | 
			
		||||
- smlua_model_utils.h
 | 
			
		||||
   - [smlua_model_util_get_id](#smlua_model_util_get_id)
 | 
			
		||||
 | 
			
		||||
<br />
 | 
			
		||||
 | 
			
		||||
- smlua_obj_utils.h
 | 
			
		||||
   - [get_temp_object_hitbox](#get_temp_object_hitbox)
 | 
			
		||||
   - [obj_get_first](#obj_get_first)
 | 
			
		||||
| 
						 | 
				
			
			@ -11743,6 +11748,32 @@ The `reliable` field will ensure that the packet arrives, but should be used spa
 | 
			
		|||
 | 
			
		||||
<br />
 | 
			
		||||
 | 
			
		||||
---
 | 
			
		||||
# functions from smlua_model_utils.h
 | 
			
		||||
 | 
			
		||||
<br />
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
## [smlua_model_util_get_id](#smlua_model_util_get_id)
 | 
			
		||||
 | 
			
		||||
### Lua Example
 | 
			
		||||
`local integerValue = smlua_model_util_get_id(name)`
 | 
			
		||||
 | 
			
		||||
### Parameters
 | 
			
		||||
| Field | Type |
 | 
			
		||||
| ----- | ---- |
 | 
			
		||||
| name | `string` |
 | 
			
		||||
 | 
			
		||||
### Returns
 | 
			
		||||
- `integer`
 | 
			
		||||
 | 
			
		||||
### C Prototype
 | 
			
		||||
`u32 smlua_model_util_get_id(const char* name);`
 | 
			
		||||
 | 
			
		||||
[:arrow_up_small:](#)
 | 
			
		||||
 | 
			
		||||
<br />
 | 
			
		||||
 | 
			
		||||
---
 | 
			
		||||
# functions from smlua_obj_utils.h
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,6 +1,6 @@
 | 
			
		|||
#include <PR/ultratypes.h>
 | 
			
		||||
 | 
			
		||||
#ifdef DEVELOPMENT
 | 
			
		||||
#if defined(AUDIO_DEVELOPMENT) || defined(DEVELOPMENT)
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include <assert.h>
 | 
			
		||||
#endif
 | 
			
		||||
| 
						 | 
				
			
			@ -280,7 +280,7 @@ void sequence_player_init_channels_extended(struct SequencePlayer* seqPlayer, u3
 | 
			
		|||
    struct SequenceChannel* seqChannel;
 | 
			
		||||
    s32 i;
 | 
			
		||||
 | 
			
		||||
#ifdef DEVELOPMENT
 | 
			
		||||
#ifdef AUDIO_DEVELOPMENT
 | 
			
		||||
    printf("debug: Enabling channels (extended) with corresponding bits %X\n", channelBits);
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -305,12 +305,12 @@ void sequence_player_init_channels_extended(struct SequencePlayer* seqPlayer, u3
 | 
			
		|||
                seqChannel->noteAllocPolicy = seqPlayer->noteAllocPolicy;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
#ifdef DEVELOPMENT
 | 
			
		||||
#ifdef AUDIO_DEVELOPMENT
 | 
			
		||||
            printf("debug: Tried to enable channel (extended) %i with result of validity %u.\n", i, IS_SEQUENCE_CHANNEL_VALID(seqChannel));
 | 
			
		||||
#endif
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
#ifdef DEVELOPMENT
 | 
			
		||||
#ifdef AUDIO_DEVELOPMENT
 | 
			
		||||
        printf("debug: Checked channel (extended) %i for enable with bit %u.\n", i, channelBits & 1);
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -326,7 +326,7 @@ void sequence_player_disable_channels_extended(struct SequencePlayer* seqPlayer,
 | 
			
		|||
    struct SequenceChannel* seqChannel;
 | 
			
		||||
    s32 i;
 | 
			
		||||
 | 
			
		||||
#ifdef DEVELOPMENT
 | 
			
		||||
#ifdef AUDIO_DEVELOPMENT
 | 
			
		||||
    printf("debug: Disabling channels (extended) with corresponding bits %X\n", channelBits);
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -2161,9 +2161,6 @@ static void init_single_mario(struct MarioState* m) {
 | 
			
		|||
    if (nearbyPlayers > 1) {
 | 
			
		||||
        m->pos[0] -= spawnMag * sins(spawnAngle);
 | 
			
		||||
        m->pos[2] -= spawnMag * coss(spawnAngle);
 | 
			
		||||
        LOG_INFO("spawn offset!, %u", nearbyPlayers);
 | 
			
		||||
    } else {
 | 
			
		||||
        LOG_INFO("no spawn offset!, %u", nearbyPlayers);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    m->floorHeight = find_floor(m->pos[0], m->pos[1], m->pos[2], &m->floor);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -236,6 +236,7 @@ char gSmluaConstants[] = ""
 | 
			
		|||
"--- @param flags2 number\n"
 | 
			
		||||
"--- @return number\n"
 | 
			
		||||
"function SOUND_ARG_LOAD(bank, playFlags, soundID, priority, flags2)\n"
 | 
			
		||||
"    if flags2 == nil then flags2 = 0 end\n"
 | 
			
		||||
"    return ((bank << 28) | (playFlags << 24) | (soundID << 16) | (priority << 8) | (flags2 << 4) | 1)\n"
 | 
			
		||||
"end\n"
 | 
			
		||||
"id_bhvStarDoor = 0\n"
 | 
			
		||||
| 
						 | 
				
			
			@ -931,7 +932,7 @@ char gSmluaConstants[] = ""
 | 
			
		|||
"CAM_EVENT_START_ENDING = 11\n"
 | 
			
		||||
"CAM_EVENT_START_END_WAVING = 12\n"
 | 
			
		||||
"CAM_EVENT_START_CREDITS = 13\n"
 | 
			
		||||
"PALETTE_MAX = 24\n"
 | 
			
		||||
"PALETTE_MAX = 30\n"
 | 
			
		||||
"CT_MARIO = 0\n"
 | 
			
		||||
"CT_LUIGI = 1\n"
 | 
			
		||||
"CT_TOAD = 2\n"
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -22,6 +22,7 @@
 | 
			
		|||
#include "src/pc/lua/utils/smlua_obj_utils.h"
 | 
			
		||||
#include "src/pc/lua/utils/smlua_misc_utils.h"
 | 
			
		||||
#include "src/pc/lua/utils/smlua_collision_utils.h"
 | 
			
		||||
#include "src/pc/lua/utils/smlua_model_utils.h"
 | 
			
		||||
#include "src/engine/surface_load.h"
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -7472,6 +7473,21 @@ int smlua_func_warp_to_level(lua_State* L) {
 | 
			
		|||
    return 1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
  /////////////////////////
 | 
			
		||||
 // smlua_model_utils.h //
 | 
			
		||||
/////////////////////////
 | 
			
		||||
 | 
			
		||||
int smlua_func_smlua_model_util_get_id(lua_State* L) {
 | 
			
		||||
    if(!smlua_functions_valid_param_count(L, 1)) { return 0; }
 | 
			
		||||
 | 
			
		||||
    const char* name = smlua_to_string(L, 1);
 | 
			
		||||
    if (!gSmLuaConvertSuccess) { return 0; }
 | 
			
		||||
 | 
			
		||||
    lua_pushinteger(L, smlua_model_util_get_id(name));
 | 
			
		||||
 | 
			
		||||
    return 1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
  ///////////////////////
 | 
			
		||||
 // smlua_obj_utils.h //
 | 
			
		||||
///////////////////////
 | 
			
		||||
| 
						 | 
				
			
			@ -8761,6 +8777,9 @@ void smlua_bind_functions_autogen(void) {
 | 
			
		|||
    smlua_bind_function(L, "warp_to_castle", smlua_func_warp_to_castle);
 | 
			
		||||
    smlua_bind_function(L, "warp_to_level", smlua_func_warp_to_level);
 | 
			
		||||
 | 
			
		||||
    // smlua_model_utils.h
 | 
			
		||||
    smlua_bind_function(L, "smlua_model_util_get_id", smlua_func_smlua_model_util_get_id);
 | 
			
		||||
 | 
			
		||||
    // smlua_obj_utils.h
 | 
			
		||||
    smlua_bind_function(L, "get_temp_object_hitbox", smlua_func_get_temp_object_hitbox);
 | 
			
		||||
    smlua_bind_function(L, "obj_get_first", smlua_func_obj_get_first);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -65,7 +65,7 @@ struct ModelUtilsInfo {
 | 
			
		|||
#define MODEL_UTIL_GEO(x, y) [x] = { .id = x, .asset = y, .layer = LAYER_OPAQUE, .isDisplayList = false, .cacheId = 0xFF }
 | 
			
		||||
#define MODEL_UTIL_DL(x, y, z) [x] = { .id = x, .asset = y, .layer = z, .isDisplayList = true, .cacheId = 0xFF }
 | 
			
		||||
 | 
			
		||||
struct ModelUtilsInfo sModels[] = {
 | 
			
		||||
struct ModelUtilsInfo sModels[E_MODEL_MAX] = {
 | 
			
		||||
    MODEL_UTIL_GEO(E_MODEL_NONE,                    NULL),
 | 
			
		||||
 | 
			
		||||
    // actors
 | 
			
		||||
| 
						 | 
				
			
			@ -449,6 +449,9 @@ struct ModelUtilsInfo sModels[] = {
 | 
			
		|||
    MODEL_UTIL_GEO(E_MODEL_WARIOS_WINGED_METAL_CAP,   warios_winged_metal_cap_geo),
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct ModelUtilsInfo* sCustomModels = NULL;
 | 
			
		||||
u32 sCustomModelsCount = 0;
 | 
			
		||||
 | 
			
		||||
struct ModelUtilsInfo sCachedAssets[256] = { 0 };
 | 
			
		||||
 | 
			
		||||
void smlua_model_util_remember(u8 modelId, u8 layer, const void* asset, u8 isDisplayList) {
 | 
			
		||||
| 
						 | 
				
			
			@ -467,16 +470,23 @@ void smlua_model_util_clear(void) {
 | 
			
		|||
        }
 | 
			
		||||
        sModels[i].cacheId = 0xFF;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    for (u32 i = 0; i < sCustomModelsCount; i++) {
 | 
			
		||||
        if (sCustomModels[i].cacheId != 0xFF) {
 | 
			
		||||
            gLoadedGraphNodes[sCustomModels[i].cacheId] = NULL;
 | 
			
		||||
        }
 | 
			
		||||
        sCustomModels[i].cacheId = 0xFF;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
u8 smlua_model_util_load(enum ModelExtendedId id) {
 | 
			
		||||
    if (id == E_MODEL_NONE) { return MODEL_NONE; }
 | 
			
		||||
    if (id >= E_MODEL_MAX) {
 | 
			
		||||
        LOG_ERROR("id invalid");
 | 
			
		||||
        return 0xFF;
 | 
			
		||||
    }
 | 
			
		||||
    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; }
 | 
			
		||||
 | 
			
		||||
    struct ModelUtilsInfo* info = &sModels[id];
 | 
			
		||||
    struct ModelUtilsInfo* info = (id >= E_MODEL_MAX)
 | 
			
		||||
                                ? &sCustomModels[id - E_MODEL_MAX - 1]
 | 
			
		||||
                                : &sModels[id];
 | 
			
		||||
 | 
			
		||||
    // check cache
 | 
			
		||||
    if (info->cacheId != 0xFF) {
 | 
			
		||||
| 
						 | 
				
			
			@ -518,3 +528,33 @@ u8 smlua_model_util_load(enum ModelExtendedId id) {
 | 
			
		|||
 | 
			
		||||
    return emptyCacheId;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
u32 smlua_model_util_get_id(const char* name) {
 | 
			
		||||
    // find geolayout
 | 
			
		||||
    const void* layout = dynos_geolayout_get(name);
 | 
			
		||||
    if (layout == NULL) { return E_MODEL_NONE; }
 | 
			
		||||
 | 
			
		||||
    // find existing model
 | 
			
		||||
    for (u32 i = 0; i < E_MODEL_MAX; i++) {
 | 
			
		||||
        if (sModels[i].asset == layout) {
 | 
			
		||||
            return i;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    for (u32 i = 0; i < sCustomModelsCount; i++) {
 | 
			
		||||
        if (sCustomModels[i].asset == layout) {
 | 
			
		||||
            return E_MODEL_MAX + i + 1;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // allocate custom model
 | 
			
		||||
    u32 customIndex = sCustomModelsCount++;
 | 
			
		||||
    sCustomModels = realloc(sCustomModels, sizeof(struct ModelUtilsInfo) * sCustomModelsCount);
 | 
			
		||||
    struct ModelUtilsInfo* info = &sCustomModels[customIndex];
 | 
			
		||||
    info->asset = layout;
 | 
			
		||||
    info->cacheId = 0xFF;
 | 
			
		||||
    info->id = E_MODEL_MAX + sCustomModelsCount;
 | 
			
		||||
    info->isDisplayList = false;
 | 
			
		||||
    info->layer = LAYER_OPAQUE;
 | 
			
		||||
 | 
			
		||||
    return info->id;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -390,5 +390,6 @@ 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(enum ModelExtendedId id);
 | 
			
		||||
u32 smlua_model_util_get_id(const char* name);
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		
		Reference in a new issue