Added ability for mods to load custom geos

This commit is contained in:
MysterD 2022-03-14 00:11:36 -07:00
parent 1e96340b1d
commit edf06bede0
16 changed files with 210 additions and 22 deletions

View file

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

View file

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

View file

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

View file

@ -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()
-- ...

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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