mirror of
https://github.com/coop-deluxe/sm64coopdx.git
synced 2024-11-25 05:25:14 +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…
Reference in a new issue