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:
parent
8200b17560
commit
27db236b5d
|
@ -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" ],
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
*/
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -34,7 +34,7 @@ enum LuaHookedEventType {
|
|||
HOOK_MAX,
|
||||
};
|
||||
|
||||
static char* LuaHookedEventTypeName[] = {
|
||||
static const char* LuaHookedEventTypeName[] = {
|
||||
"HOOK_UPDATE",
|
||||
"HOOK_MARIO_UPDATE",
|
||||
"HOOK_BEFORE_MARIO_UPDATE",
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue