From 27db236b5d1811553804ebd11ed4cc181874a86c Mon Sep 17 00:00:00 2001 From: PeachyPeach <72323920+PeachyPeachSM64@users.noreply.github.com> Date: Sat, 14 May 2022 23:28:25 +0200 Subject: [PATCH] Various bug fixes + Added is_game_paused() and more background music functions to lua (#93) Bug: DynOS models with animations cannot swap animations if they are loaded via lua (smlua_model_util_get_id and obj_set_model_extended). Fix: DynOS_Actor_GetActorGfx takes a graph node instead of a georef, and checks for DynosValidActors graph nodes if georef is NULL. Bug: The game can crash when calling obj_set_model_extended inside a HOOK_ON_OBJECT_RENDER hook. Fix: The crash happens in smlua_model_util_load_with_pool_and_cache_id due to pool being NULL. If the game can't allocate an AllocOnlyPool object, use DynOS to generate the graph node. Bug: warp_to_level and similar functions don't trigger HOOK_ON_WARP. Fix: Call HOOK_ON_WARP hooks in DynOS_Warp_UpdateWarp and DynOS_Warp_UpdateExit after level and mario initialization. Bug: The game sometimes calls HOOK_ON_OBJECT_RENDER hooks for unintended objects. Fix: Initialize hookRender field to 0 when creating an object. Bug: Actions can't apply gfx offsets to characters that have an anim offset (Waluigi, Wario) Fix: Add m->curAnimOffset to gfx.pos[1] instead of setting it to m->pos[1] + m->curAnimOffset, except during the jumbo star cutscene. --- autogen/convert_functions.py | 2 +- autogen/lua_definitions/functions.lua | 25 ++++++++++ data/dynos.c.h | 9 ++-- data/dynos.cpp.h | 2 +- data/dynos_c.cpp | 4 ++ data/dynos_mgr_actor.cpp | 26 ++++++++-- data/dynos_mgr_anim.cpp | 2 +- data/dynos_warps.cpp | 7 +++ docs/lua/functions-3.md | 72 +++++++++++++++++++++++++++ docs/lua/functions-4.md | 18 +++++++ docs/lua/functions.md | 5 ++ src/audio/external.c | 12 +++++ src/audio/external.h | 3 ++ src/game/characters.c | 6 ++- src/game/spawn_object.c | 1 + src/pc/lua/smlua_functions_autogen.c | 50 +++++++++++++++++++ src/pc/lua/smlua_hooks.h | 2 +- src/pc/lua/utils/smlua_misc_utils.c | 7 +++ src/pc/lua/utils/smlua_misc_utils.h | 2 + src/pc/lua/utils/smlua_model_utils.c | 27 +++++++--- 20 files changed, 263 insertions(+), 19 deletions(-) diff --git a/autogen/convert_functions.py b/autogen/convert_functions.py index bf0386c1..8ab1615b 100644 --- a/autogen/convert_functions.py +++ b/autogen/convert_functions.py @@ -53,7 +53,7 @@ in_files = [ ] override_allowed_functions = { - "src/audio/external.h": [ " play_", "fade" ], + "src/audio/external.h": [ " play_", "fade", "current_background" ], "src/game/rumble_init.c": [ "queue_rumble_", "reset_rumble_timers" ], "src/pc/djui/djui_popup.h" : [ "create" ], "src/game/save_file.h": [ "save_file_get_", "save_file_set_flags", "save_file_clear_flags" ], diff --git a/autogen/lua_definitions/functions.lua b/autogen/lua_definitions/functions.lua index aeebeb84..8c283bb6 100644 --- a/autogen/lua_definitions/functions.lua +++ b/autogen/lua_definitions/functions.lua @@ -3688,6 +3688,26 @@ function fadeout_background_music(arg0, fadeOut) -- ... end +--- @return integer +function get_current_background_music() + -- ... +end + +--- @return integer +function get_current_background_music_max_target_volume() + -- ... +end + +--- @return integer +function get_current_background_music_target_volume() + -- ... +end + +--- @return integer +function is_current_background_music_volume_lowered() + -- ... +end + --- @return nil function play_course_clear() -- ... @@ -7376,6 +7396,11 @@ function hud_show() -- ... end +--- @return boolean +function is_game_paused() + -- ... +end + --- @param name string --- @param level integer --- @param area integer diff --git a/data/dynos.c.h b/data/dynos.c.h index 98b47353..491c7c0e 100644 --- a/data/dynos.c.h +++ b/data/dynos.c.h @@ -9,10 +9,10 @@ void *dynos_swap_cmd(void *cmd); // -- built in -- // -void *dynos_update_cmd (void *cmd); -void dynos_update_gfx (); -void dynos_update_opt (void *pad); -s32 dynos_tex_import (void **output, void *ptr, s32 tile, void *grapi, void **hashmap, void *pool, s32 *poolpos, s32 poolsize); +void *dynos_update_cmd(void *cmd); +void dynos_update_gfx(); +void dynos_update_opt(void *pad); +s32 dynos_tex_import(void **output, void *ptr, s32 tile, void *grapi, void **hashmap, void *pool, s32 *poolpos, s32 poolsize); void dynos_gfx_swap_animations(void *ptr); // -- warps -- // @@ -33,6 +33,7 @@ void dynos_generate_packs(const char* directory); void dynos_actor_override(void** aSharedChild); void dynos_add_actor_custom(const char *filePath, const char* geoName); const void* dynos_geolayout_get(const char *name); +void *dynos_geolayout_to_graphnode(const void *geoLayout, bool keepInMemory); // -- collisions -- // void dynos_add_collision(const char *filePath, const char* collisionName); diff --git a/data/dynos.cpp.h b/data/dynos.cpp.h index a38e15a9..05355e9f 100644 --- a/data/dynos.cpp.h +++ b/data/dynos.cpp.h @@ -764,7 +764,7 @@ void DynOS_Pack_AddTex(PackData* aPackData, DataNode* aTexData); void DynOS_Actor_AddCustom(const SysPath &aFilename, const char *aActorName); const void *DynOS_Actor_GetLayoutFromName(const char *aActorName); -ActorGfx* DynOS_Actor_GetActorGfx(const void* aGeoref); +ActorGfx* DynOS_Actor_GetActorGfx(const GraphNode* aGraphNode); void DynOS_Actor_Valid(const void* aGeoref, ActorGfx& aActorGfx); void DynOS_Actor_Invalid(const void* aGeoref, s32 aPackIndex); void DynOS_Actor_Override(void** aSharedChild); diff --git a/data/dynos_c.cpp b/data/dynos_c.cpp index 42196c13..154013dc 100644 --- a/data/dynos_c.cpp +++ b/data/dynos_c.cpp @@ -97,6 +97,10 @@ const void* dynos_geolayout_get(const char *name) { return DynOS_Actor_GetLayoutFromName(name); } +void *dynos_geolayout_to_graphnode(const void *geoLayout, bool keepInMemory) { + return DynOS_Geo_GetGraphNode(geoLayout, keepInMemory); +} + // -- collisions -- // void dynos_add_collision(const char *filePath, const char* collisionName) { diff --git a/data/dynos_mgr_actor.cpp b/data/dynos_mgr_actor.cpp index b4b44ac8..c1ce9988 100644 --- a/data/dynos_mgr_actor.cpp +++ b/data/dynos_mgr_actor.cpp @@ -1,4 +1,5 @@ #include +#include #include "dynos.cpp.h" extern "C" { @@ -101,11 +102,28 @@ const void *DynOS_Actor_GetLayoutFromName(const char *aActorName) { return NULL; } -ActorGfx* DynOS_Actor_GetActorGfx(const void* aGeoref) { - if (aGeoref == NULL) { return NULL; } +ActorGfx* DynOS_Actor_GetActorGfx(const GraphNode* aGraphNode) { + if (aGraphNode == NULL) { return NULL; } auto& _ValidActors = DynosValidActors(); - if (_ValidActors.count(aGeoref) == 0) { return NULL; } - return &_ValidActors[aGeoref]; + + // If georef is not NULL, check georef + if (aGraphNode->georef != NULL) { + if (_ValidActors.count(aGraphNode->georef) != 0) { + return &_ValidActors[aGraphNode->georef]; + } + return NULL; + } + + // Check graph node + auto it = std::find_if(_ValidActors.begin(), _ValidActors.end(), + [&aGraphNode](const auto& _Actor) { return _Actor.second.mGraphNode == aGraphNode; } + ); + if (it != _ValidActors.end()) { + return &it->second; + } + + // No actor found + return NULL; } void DynOS_Actor_Valid(const void* aGeoref, ActorGfx& aActorGfx) { diff --git a/data/dynos_mgr_anim.cpp b/data/dynos_mgr_anim.cpp index b65f769c..19b42f46 100644 --- a/data/dynos_mgr_anim.cpp +++ b/data/dynos_mgr_anim.cpp @@ -52,7 +52,7 @@ void DynOS_Anim_Swap(void *aPtr) { pDefaultAnimation = _Object->header.gfx.animInfo.curAnim; // ActorGfx data - ActorGfx* _ActorGfx = DynOS_Actor_GetActorGfx(_Object->header.gfx.sharedChild->georef); + ActorGfx* _ActorGfx = DynOS_Actor_GetActorGfx(_Object->header.gfx.sharedChild); if (!_ActorGfx) { return; } diff --git a/data/dynos_warps.cpp b/data/dynos_warps.cpp index be14ee2b..6413cacd 100644 --- a/data/dynos_warps.cpp +++ b/data/dynos_warps.cpp @@ -11,6 +11,7 @@ extern "C" { #include "game/sound_init.h" #include "game/object_list_processor.h" #include "game/options_menu.h" +#include "pc/lua/smlua_hooks.h" extern s8 gDialogBoxState; extern s16 gMenuMode; extern s32 gWdwWaterLevelSet; @@ -305,6 +306,9 @@ static void *DynOS_Warp_UpdateWarp(void *aCmd, bool aIsLevelInitDone) { sound_banks_enable(0, 0xFFFF); // Bowser levels sound fix } + // lua hooks + smlua_call_event_hooks(HOOK_ON_WARP); + // Reset values sDynosWarpTargetArea = -1; sDynosWarpLevelNum = -1; @@ -441,6 +445,9 @@ static void *DynOS_Warp_UpdateExit(void *aCmd, bool aIsLevelInitDone) { // Set music set_background_music(gCurrentArea->musicParam, gCurrentArea->musicParam2, 0); sDynosExitTargetWarp = NULL; + + // lua hooks + smlua_call_event_hooks(HOOK_ON_WARP); } // Phase 4 - Unlock Mario as soon as the second transition is ended diff --git a/docs/lua/functions-3.md b/docs/lua/functions-3.md index ee9e7787..b1dc3709 100644 --- a/docs/lua/functions-3.md +++ b/docs/lua/functions-3.md @@ -2378,6 +2378,78 @@
+## [get_current_background_music](#get_current_background_music) + +### Lua Example +`local integerValue = get_current_background_music()` + +### Parameters +- None + +### Returns +- `integer` + +### C Prototype +`u16 get_current_background_music(void);` + +[:arrow_up_small:](#) + +
+ +## [get_current_background_music_max_target_volume](#get_current_background_music_max_target_volume) + +### Lua Example +`local integerValue = get_current_background_music_max_target_volume()` + +### Parameters +- None + +### Returns +- `integer` + +### C Prototype +`u8 get_current_background_music_max_target_volume(void);` + +[:arrow_up_small:](#) + +
+ +## [get_current_background_music_target_volume](#get_current_background_music_target_volume) + +### Lua Example +`local integerValue = get_current_background_music_target_volume()` + +### Parameters +- None + +### Returns +- `integer` + +### C Prototype +`u8 get_current_background_music_target_volume(void);` + +[:arrow_up_small:](#) + +
+ +## [is_current_background_music_volume_lowered](#is_current_background_music_volume_lowered) + +### Lua Example +`local integerValue = is_current_background_music_volume_lowered()` + +### Parameters +- None + +### Returns +- `integer` + +### C Prototype +`u8 is_current_background_music_volume_lowered(void);` + +[:arrow_up_small:](#) + +
+ ## [play_course_clear](#play_course_clear) ### Lua Example diff --git a/docs/lua/functions-4.md b/docs/lua/functions-4.md index a3a907d1..b83d7d86 100644 --- a/docs/lua/functions-4.md +++ b/docs/lua/functions-4.md @@ -5389,6 +5389,24 @@
+## [is_game_paused](#is_game_paused) + +### Lua Example +`local booleanValue = is_game_paused()` + +### Parameters +- None + +### Returns +- `boolean` + +### C Prototype +`bool is_game_paused(void);` + +[:arrow_up_small:](#) + +
+ ## [movtexqc_register](#movtexqc_register) ### Lua Example diff --git a/docs/lua/functions.md b/docs/lua/functions.md index 586339b3..40dd7770 100644 --- a/docs/lua/functions.md +++ b/docs/lua/functions.md @@ -728,6 +728,10 @@ - external.h - [fade_volume_scale](functions-3.md#fade_volume_scale) - [fadeout_background_music](functions-3.md#fadeout_background_music) + - [get_current_background_music](functions-3.md#get_current_background_music) + - [get_current_background_music_max_target_volume](functions-3.md#get_current_background_music_max_target_volume) + - [get_current_background_music_target_volume](functions-3.md#get_current_background_music_target_volume) + - [is_current_background_music_volume_lowered](functions-3.md#is_current_background_music_volume_lowered) - [play_course_clear](functions-3.md#play_course_clear) - [play_dialog_sound](functions-3.md#play_dialog_sound) - [play_music](functions-3.md#play_music) @@ -1376,6 +1380,7 @@ - [hud_render_power_meter](functions-4.md#hud_render_power_meter) - [hud_set_value](functions-4.md#hud_set_value) - [hud_show](functions-4.md#hud_show) + - [is_game_paused](functions-4.md#is_game_paused) - [movtexqc_register](functions-4.md#movtexqc_register) - [play_transition](functions-4.md#play_transition) - [save_file_set_using_backup_slot](functions-4.md#save_file_set_using_backup_slot) diff --git a/src/audio/external.c b/src/audio/external.c index 1303e994..d6f69053 100644 --- a/src/audio/external.c +++ b/src/audio/external.c @@ -2509,6 +2509,18 @@ u16 get_current_background_music(void) { return -1; } +u8 get_current_background_music_target_volume(void) { + return sBackgroundMusicTargetVolume; +} + +u8 get_current_background_music_max_target_volume(void) { + return sBackgroundMusicMaxTargetVolume; +} + +u8 is_current_background_music_volume_lowered(void) { + return sLowerBackgroundMusicVolume; +} + /** * Called from threads: thread4_sound, thread5_game_loop (EU only) */ diff --git a/src/audio/external.h b/src/audio/external.h index add25d27..3d3c3fbe 100644 --- a/src/audio/external.h +++ b/src/audio/external.h @@ -53,6 +53,9 @@ void stop_background_music(u16 seqId); void fadeout_background_music(u16 arg0, u16 fadeOut); void drop_queued_background_music(void); u16 get_current_background_music(void); +u8 get_current_background_music_target_volume(void); +u8 get_current_background_music_max_target_volume(void); +u8 is_current_background_music_volume_lowered(void); void play_secondary_music(u8 seqId, u8 bgMusicVolume, u8 volume, u16 fadeTimer); void func_80321080(u16 fadeTimer); void func_803210D4(u16 fadeOutTime); diff --git a/src/game/characters.c b/src/game/characters.c index cad9a562..7405e2ad 100644 --- a/src/game/characters.c +++ b/src/game/characters.c @@ -515,6 +515,10 @@ void update_character_anim_offset(struct MarioState* m) { if (m->curAnimOffset > 40) { m->curAnimOffset = 40; } if (m->curAnimOffset < -40) { m->curAnimOffset = -40; } - marioObj->header.gfx.pos[1] = m->pos[1] + m->curAnimOffset; + if (m->action == ACT_JUMBO_STAR_CUTSCENE) { + marioObj->header.gfx.pos[1] = m->pos[1] + m->curAnimOffset; + } else { + marioObj->header.gfx.pos[1] += m->curAnimOffset; + } marioObj->header.gfx.node.flags |= GRAPH_RENDER_PLAYER; } \ No newline at end of file diff --git a/src/game/spawn_object.c b/src/game/spawn_object.c index 2a86dbd1..60bce1ee 100644 --- a/src/game/spawn_object.c +++ b/src/game/spawn_object.c @@ -313,6 +313,7 @@ struct Object *allocate_object(struct ObjectNode *objList) { obj->header.gfx.throwMatrix = NULL; obj->coopFlags = 0; + obj->hookRender = 0; obj->areaTimerType = AREA_TIMER_TYPE_NONE; obj->areaTimer = 0; diff --git a/src/pc/lua/smlua_functions_autogen.c b/src/pc/lua/smlua_functions_autogen.c index 9ece0bd5..34881729 100644 --- a/src/pc/lua/smlua_functions_autogen.c +++ b/src/pc/lua/smlua_functions_autogen.c @@ -7438,6 +7438,42 @@ int smlua_func_fadeout_background_music(lua_State* L) { return 1; } +int smlua_func_get_current_background_music(UNUSED lua_State* L) { + if(!smlua_functions_valid_param_count(L, 0)) { return 0; } + + + lua_pushinteger(L, get_current_background_music()); + + return 1; +} + +int smlua_func_get_current_background_music_max_target_volume(UNUSED lua_State* L) { + if(!smlua_functions_valid_param_count(L, 0)) { return 0; } + + + lua_pushinteger(L, get_current_background_music_max_target_volume()); + + return 1; +} + +int smlua_func_get_current_background_music_target_volume(UNUSED lua_State* L) { + if(!smlua_functions_valid_param_count(L, 0)) { return 0; } + + + lua_pushinteger(L, get_current_background_music_target_volume()); + + return 1; +} + +int smlua_func_is_current_background_music_volume_lowered(UNUSED lua_State* L) { + if(!smlua_functions_valid_param_count(L, 0)) { return 0; } + + + lua_pushinteger(L, is_current_background_music_volume_lowered()); + + return 1; +} + int smlua_func_play_course_clear(UNUSED lua_State* L) { if(!smlua_functions_valid_param_count(L, 0)) { return 0; } @@ -15171,6 +15207,15 @@ int smlua_func_hud_show(UNUSED lua_State* L) { return 1; } +int smlua_func_is_game_paused(UNUSED lua_State* L) { + if(!smlua_functions_valid_param_count(L, 0)) { return 0; } + + + lua_pushboolean(L, is_game_paused()); + + return 1; +} + int smlua_func_movtexqc_register(lua_State* L) { if(!smlua_functions_valid_param_count(L, 4)) { return 0; } @@ -16905,6 +16950,10 @@ void smlua_bind_functions_autogen(void) { // external.h smlua_bind_function(L, "fade_volume_scale", smlua_func_fade_volume_scale); smlua_bind_function(L, "fadeout_background_music", smlua_func_fadeout_background_music); + smlua_bind_function(L, "get_current_background_music", smlua_func_get_current_background_music); + smlua_bind_function(L, "get_current_background_music_max_target_volume", smlua_func_get_current_background_music_max_target_volume); + smlua_bind_function(L, "get_current_background_music_target_volume", smlua_func_get_current_background_music_target_volume); + smlua_bind_function(L, "is_current_background_music_volume_lowered", smlua_func_is_current_background_music_volume_lowered); smlua_bind_function(L, "play_course_clear", smlua_func_play_course_clear); smlua_bind_function(L, "play_dialog_sound", smlua_func_play_dialog_sound); smlua_bind_function(L, "play_music", smlua_func_play_music); @@ -17524,6 +17573,7 @@ void smlua_bind_functions_autogen(void) { smlua_bind_function(L, "hud_render_power_meter", smlua_func_hud_render_power_meter); smlua_bind_function(L, "hud_set_value", smlua_func_hud_set_value); smlua_bind_function(L, "hud_show", smlua_func_hud_show); + smlua_bind_function(L, "is_game_paused", smlua_func_is_game_paused); smlua_bind_function(L, "movtexqc_register", smlua_func_movtexqc_register); smlua_bind_function(L, "play_transition", smlua_func_play_transition); smlua_bind_function(L, "save_file_set_using_backup_slot", smlua_func_save_file_set_using_backup_slot); diff --git a/src/pc/lua/smlua_hooks.h b/src/pc/lua/smlua_hooks.h index cbc2a4ba..4ae109de 100644 --- a/src/pc/lua/smlua_hooks.h +++ b/src/pc/lua/smlua_hooks.h @@ -34,7 +34,7 @@ enum LuaHookedEventType { HOOK_MAX, }; -static char* LuaHookedEventTypeName[] = { +static const char* LuaHookedEventTypeName[] = { "HOOK_UPDATE", "HOOK_MARIO_UPDATE", "HOOK_BEFORE_MARIO_UPDATE", diff --git a/src/pc/lua/utils/smlua_misc_utils.c b/src/pc/lua/utils/smlua_misc_utils.c index dc26b643..79073093 100644 --- a/src/pc/lua/utils/smlua_misc_utils.c +++ b/src/pc/lua/utils/smlua_misc_utils.c @@ -114,6 +114,13 @@ void camera_unfreeze(void) { /// +extern s16 gMenuMode; +bool is_game_paused(void) { + return gMenuMode != -1; +} + +/// + bool warp_to_level(s32 aLevel, s32 aArea, s32 aAct) { return dynos_warp_to_level(aLevel, aArea, aAct); } diff --git a/src/pc/lua/utils/smlua_misc_utils.h b/src/pc/lua/utils/smlua_misc_utils.h index 84390c93..326541ab 100644 --- a/src/pc/lua/utils/smlua_misc_utils.h +++ b/src/pc/lua/utils/smlua_misc_utils.h @@ -39,6 +39,8 @@ void hud_render_power_meter(s32 health, f32 x, f32 y, f32 width, f32 height); void camera_freeze(void); void camera_unfreeze(void); +bool is_game_paused(void); + bool warp_to_level(s32 aLevel, s32 aArea, s32 aAct); bool warp_restart_level(void); bool warp_exit_level(s32 aDelay); diff --git a/src/pc/lua/utils/smlua_model_utils.c b/src/pc/lua/utils/smlua_model_utils.c index 6faf28d6..be44ef1b 100644 --- a/src/pc/lua/utils/smlua_model_utils.c +++ b/src/pc/lua/utils/smlua_model_utils.c @@ -1,5 +1,6 @@ #include "sm64.h" #include "types.h" +#include "geo_commands.h" #include "src/game/area.h" #include "src/engine/graph_node.h" @@ -566,14 +567,28 @@ u8 smlua_model_util_load_with_pool_and_cache_id(enum ModelExtendedId extId, stru resizePool = true; } - if (info->isDisplayList) { - gLoadedGraphNodes[pickLoadedId] = (struct GraphNode *) init_graph_node_display_list(pool, NULL, info->layer, (void*)info->asset); - } else { - gLoadedGraphNodes[pickLoadedId] = process_geo_layout(pool, (void*)info->asset); + if (pool != NULL) { + if (info->isDisplayList) { + gLoadedGraphNodes[pickLoadedId] = (struct GraphNode *) init_graph_node_display_list(pool, NULL, info->layer, (void*)info->asset); + } else { + gLoadedGraphNodes[pickLoadedId] = process_geo_layout(pool, (void*)info->asset); + } + + if (resizePool) { + alloc_only_pool_resize(pool, pool->usedSpace); + } } - if (resizePool) { - alloc_only_pool_resize(pool, pool->usedSpace); + // If no pool is available, use DynOS to generate the graph node + else { + + // Turn the display list into a geo layout + if (info->isDisplayList) { + const GeoLayout displayListToGeoLayout[] = { GEO_NODE_START(), GEO_DISPLAY_LIST(info->layer, info->asset), GEO_END() }; + info->asset = memcpy(calloc(1, sizeof(displayListToGeoLayout)), displayListToGeoLayout, sizeof(displayListToGeoLayout)); + info->isDisplayList = false; + } + gLoadedGraphNodes[pickLoadedId] = dynos_geolayout_to_graphnode(info->asset, true); } // remember