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.
This commit is contained in:
PeachyPeach 2022-05-14 23:28:25 +02:00 committed by GitHub
parent 8200b17560
commit 27db236b5d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
20 changed files with 263 additions and 19 deletions

View file

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

View file

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

View file

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

View file

@ -764,7 +764,7 @@ void DynOS_Pack_AddTex(PackData* aPackData, DataNode<TexData>* 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);

View file

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

View file

@ -1,4 +1,5 @@
#include <map>
#include <algorithm>
#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) {

View file

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

View file

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

View file

@ -2378,6 +2378,78 @@
<br />
## [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:](#)
<br />
## [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:](#)
<br />
## [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:](#)
<br />
## [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:](#)
<br />
## [play_course_clear](#play_course_clear)
### Lua Example

View file

@ -5389,6 +5389,24 @@
<br />
## [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:](#)
<br />
## [movtexqc_register](#movtexqc_register)
### Lua Example

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -34,7 +34,7 @@ enum LuaHookedEventType {
HOOK_MAX,
};
static char* LuaHookedEventTypeName[] = {
static const char* LuaHookedEventTypeName[] = {
"HOOK_UPDATE",
"HOOK_MARIO_UPDATE",
"HOOK_BEFORE_MARIO_UPDATE",

View file

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

View file

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

View file

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