diff --git a/autogen/convert_constants.py b/autogen/convert_constants.py index 020e0312..3993363c 100644 --- a/autogen/convert_constants.py +++ b/autogen/convert_constants.py @@ -166,7 +166,7 @@ def process_define(filename, line): continue p = re.sub(r'0x[a-fA-F0-9]+', '', p) if re.search('[a-z]', p) != None and 'VERSION_TEXT' not in line: - if 'gCurrentObject' not in line: + if 'gCurrentObject' not in line and 'gNetworkType' not in line: print('UNRECOGNIZED DEFINE: ' + line) return None diff --git a/autogen/convert_functions.py b/autogen/convert_functions.py index 73fc9370..5065228d 100644 --- a/autogen/convert_functions.py +++ b/autogen/convert_functions.py @@ -102,12 +102,14 @@ override_disallowed_functions = { "src/game/obj_behaviors.c": [ "debug_" ], "src/game/obj_behaviors_2.c": [ "wiggler_jumped_on_attack_handler", "huge_goomba_weakly_attacked" ], "src/game/spawn_sound.c": [ "spawner" ], + "src/game/level_info.h": [ "_name_table" ], "src/pc/lua/utils/smlua_obj_utils.h": [ "spawn_object_remember_field", "set_exclamation_box_new_contents", "get_exclamation_box_new_contents_pointer", "get_exclamation_box_new_contents_size" ], "src/game/camera.h": [ "update_camera", "init_camera", "stub_camera", "^reset_camera", "move_point_along_spline" ], "src/game/behavior_actions.h": [ "bhv_dust_smoke_loop", "bhv_init_room" ], "src/pc/lua/utils/smlua_audio_utils.h": [ "smlua_audio_utils_override", "audio_custom_shutdown"], "src/pc/djui/djui_hud_utils.h": [ "djui_hud_render_texture", "djui_hud_render_texture_raw", "djui_hud_render_texture_tile", "djui_hud_render_texture_tile_raw" ], "src/pc/lua/utils/smlua_level_utils.h": [ "smlua_level_util_reset" ], + "src/pc/lua/utils/smlua_text_utils.h": [ "smlua_text_utils_reset_all" ], "src/pc/lua/utils/smlua_anim_utils.h": [ "smlua_anim_util_reset", "smlua_anim_util_register_animation" ], "src/pc/network/lag_compensation.h": [ "lag_compensation_clear", "lag_compensation_store" ] } diff --git a/autogen/convert_structs.py b/autogen/convert_structs.py index 65343d78..b3b7045f 100644 --- a/autogen/convert_structs.py +++ b/autogen/convert_structs.py @@ -79,7 +79,7 @@ override_field_mutable = { override_field_invisible = { "Mod": [ "files" ], "MarioState": [ "visibleToEnemies" ], - "NetworkPlayer": [ "gag"], + "NetworkPlayer": [ "gag", "moderator"], "GraphNode": [ "_guard1", "_guard2" ], } @@ -371,11 +371,11 @@ def build_struct(struct): if sid in override_field_invisible: if fid in override_field_invisible[sid]: continue - + version = None row = [] - + startStr = '' endStr = ' },' if fid in override_field_version_excludes: diff --git a/autogen/lua_definitions/functions.lua b/autogen/lua_definitions/functions.lua index dfa50e0b..7e9f255a 100644 --- a/autogen/lua_definitions/functions.lua +++ b/autogen/lua_definitions/functions.lua @@ -8190,6 +8190,22 @@ function smlua_audio_utils_reset_all() -- ... end +--- @param x number +--- @param y number +--- @param z number +--- @return Surface +function collision_find_ceil(x, y, z) + -- ... +end + +--- @param x number +--- @param y number +--- @param z number +--- @return Surface +function collision_find_floor(x, y, z) + -- ... +end + --- @param startX number --- @param startY number --- @param startZ number @@ -8254,6 +8270,12 @@ function smlua_level_util_get_info(levelNum) -- ... end +--- @param courseNum integer +--- @return CustomLevelInfo +function smlua_level_util_get_info_from_course_num(courseNum) + -- ... +end + --- @param shortName string --- @return CustomLevelInfo function smlua_level_util_get_info_from_short_name(shortName) @@ -9096,6 +9118,35 @@ function spawn_sync_object(behaviorId, modelId, x, y, z, objSetupFunction) -- ... end +--- @param courseNum integer +--- @param actNum integer +--- @return string +function smlua_text_utils_act_name_get(courseNum, actNum) + -- ... +end + +--- @param courseNum integer +--- @param actNum integer +--- @return boolean +function smlua_text_utils_act_name_is_modified(courseNum, actNum) + -- ... +end + +--- @param courseNum integer +--- @param actNum integer +--- @param name string +--- @return nil +function smlua_text_utils_act_name_replace(courseNum, actNum, name) + -- ... +end + +--- @param courseNum integer +--- @param actNum integer +--- @return nil +function smlua_text_utils_act_name_reset(courseNum, actNum) + -- ... +end + --- @param name string --- @return nil function smlua_text_utils_castle_secret_stars_replace(name) @@ -9115,6 +9166,31 @@ function smlua_text_utils_course_acts_replace(courseNum, courseName, act1, act2, -- ... end +--- @param courseNum integer +--- @return string +function smlua_text_utils_course_name_get(courseNum) + -- ... +end + +--- @param courseNum integer +--- @return integer +function smlua_text_utils_course_name_mod_index(courseNum) + -- ... +end + +--- @param courseNum integer +--- @param name string +--- @return nil +function smlua_text_utils_course_name_replace(courseNum, name) + -- ... +end + +--- @param courseNum integer +--- @return nil +function smlua_text_utils_course_name_reset(courseNum) + -- ... +end + --- @param dialogId DialogId --- @param unused integer --- @param linesPerBox integer @@ -9138,11 +9214,6 @@ function smlua_text_utils_get_language() -- ... end ---- @return nil -function smlua_text_utils_reset_all() - -- ... -end - --- @param courseNum integer --- @param courseName string --- @return nil diff --git a/data/dynos.c.h b/data/dynos.c.h index e63c1cd6..a632cbc1 100644 --- a/data/dynos.c.h +++ b/data/dynos.c.h @@ -12,7 +12,6 @@ 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_gfx_swap_animations(void *ptr); @@ -59,7 +58,7 @@ const char* dynos_level_get_token(u32 index); Trajectory* dynos_level_get_trajectory(const char* name); void dynos_level_load_background(void *ptr); u64 dynos_level_cmd_get(void *cmd, u64 offset); -void dynos_level_cmd_next(void *cmd, u64 cmdsize); +void dynos_level_cmd_next(void *cmd); void dynos_level_parse_script(const void *script, s32 (*aPreprocessFunction)(u8, void *)); void* dynos_level_get_script(s32 level); s32 dynos_level_get_mod_index(s32 level); diff --git a/data/dynos.cpp.h b/data/dynos.cpp.h index b07ea6b5..aff4a2c6 100644 --- a/data/dynos.cpp.h +++ b/data/dynos.cpp.h @@ -656,6 +656,11 @@ struct BuiltinTexInfo { s32 bitSize; }; +struct LvlCmd { + u8 mType; + u8 mSize; +}; + // // Utils // @@ -783,23 +788,6 @@ void DynOS_Mod_Update(); void DynOS_Mod_Shutdown(); void DynOS_ReturnToMainMenu(); -// -// Opt -// - -s32 DynOS_Opt_GetValue(const String &aName); -void DynOS_Opt_SetValue(const String &aName, s32 aValue); -void DynOS_Opt_AddAction(const String &aFuncName, bool (*aFuncPtr)(const char *), bool aOverwrite); -void DynOS_Opt_Init(); -void DynOS_Opt_InitVanilla(DynosOption *&aOptionsMenu); -void DynOS_Opt_Update(OSContPad *aPad); -bool DynOS_Opt_ControllerUpdate(DynosOption *aOpt, void *aData); -s32 DynOS_Opt_ControllerGetKeyPressed(); -void DynOS_Opt_LoadConfig(DynosOption *aMenu); -void DynOS_Opt_SaveConfig(DynosOption *aMenu); -void DynOS_Opt_DrawMenu(DynosOption *aCurrentOption, DynosOption *aCurrentMenu, DynosOption *aOptionsMenu, DynosOption *aDynosMenu); -void DynOS_Opt_DrawPrompt(DynosOption *aCurrentMenu, DynosOption *aOptionsMenu, DynosOption *aDynosMenu); - // // Gfx // @@ -826,22 +814,18 @@ s32 DynOS_String_Width(const u8 *aStr64); // Levels // -s32 DynOS_Level_GetCount(); -const s32 *DynOS_Level_GetList(); -s32 DynOS_Level_GetCourse(s32 aLevel); +void DynOS_Level_Init(); +s8 DynOS_Level_GetCourse(s32 aLevel); void DynOS_Level_Override(void* originalScript, void* newScript, s32 modIndex); void DynOS_Level_Unoverride(); const void *DynOS_Level_GetScript(s32 aLevel); s32 DynOS_Level_GetModIndex(s32 aLevel); bool DynOS_Level_IsVanillaLevel(s32 aLevel); -const u8 *DynOS_Level_GetName(s32 aLevel, bool aDecaps, bool aAddCourseNumber); -const u8 *DynOS_Level_GetActName(s32 aLevel, s32 aAct, bool aDecaps, bool aAddStarNumber); -const u8 *DynOS_Level_GetAreaName(s32 aLevel, s32 aArea, bool aDecaps); s16 *DynOS_Level_GetWarp(s32 aLevel, s32 aArea, u8 aWarpId); s16 *DynOS_Level_GetWarpEntry(s32 aLevel, s32 aArea); s16 *DynOS_Level_GetWarpDeath(s32 aLevel, s32 aArea); u64 DynOS_Level_CmdGet(void *aCmd, u64 aOffset); -void *DynOS_Level_CmdNext(void *aCmd, u64 aCmdSize); +LvlCmd *DynOS_Level_CmdNext(LvlCmd *aCmd); void DynOS_Level_ParseScript(const void *aScript, s32 (*aPreprocessFunction)(u8, void *)); // @@ -854,8 +838,6 @@ bool DynOS_Warp_ToLevel(s32 aLevel, s32 aArea, s32 aAct); bool DynOS_Warp_RestartLevel(); bool DynOS_Warp_ExitLevel(s32 aDelay); bool DynOS_Warp_ToCastle(s32 aLevel); -void DynOS_Warp_SetParam(s32 aLevel, s32 aIndex); -const char *DynOS_Warp_GetParamName(s32 aLevel, s32 aIndex); // // Builtin @@ -988,7 +970,6 @@ u32 DynOS_Model_GetIdFromAsset(void* asset); u32 DynOS_Model_GetIdFromGraphNode(struct GraphNode* aNode); void DynOS_Model_OverwriteSlot(u32 srcSlot, u32 dstSlot); void DynOS_Model_ClearPool(enum ModelPool aModelPool); -void DynOS_Model_Update(); // // Bin diff --git a/data/dynos_bin_vtx.cpp b/data/dynos_bin_vtx.cpp index d1cdc406..a42767f2 100644 --- a/data/dynos_bin_vtx.cpp +++ b/data/dynos_bin_vtx.cpp @@ -10,7 +10,7 @@ extern "C" { static inline bool ShouldUseF32Vtx(DataNode* aNode) { for (u32 i = 0; i != aNode->mSize; ++i) { for (u32 j = 0; j != 3; ++j) { - if (aNode->mData[i].n.ob[j] < -0x7FFF || + if (aNode->mData[i].n.ob[j] < -0x7FFF || aNode->mData[i].n.ob[j] > +0x7FFF) { return true; } diff --git a/data/dynos_c.cpp b/data/dynos_c.cpp index 3d3da3f2..ff1d9a0d 100644 --- a/data/dynos_c.cpp +++ b/data/dynos_c.cpp @@ -14,14 +14,9 @@ void *dynos_update_cmd(void *cmd) { } void dynos_update_gfx() { - DynOS_Model_Update(); return DynOS_UpdateGfx(); } -void dynos_update_opt(void *pad) { - return DynOS_UpdateOpt(pad); -} - s32 dynos_tex_import(void **output, void *ptr, s32 tile, void *grapi, void **hashmap, void *pool, s32 *poolpos, s32 poolsize) { return DynOS_Tex_Import(output, ptr, tile, grapi, hashmap, pool, (u32 *) poolpos, (u32) poolsize); } @@ -185,8 +180,8 @@ u64 dynos_level_cmd_get(void *cmd, u64 offset) { return DynOS_Level_CmdGet(cmd, offset); } -void dynos_level_cmd_next(void *cmd, u64 cmdsize) { - DynOS_Level_CmdNext(cmd, cmdsize); +void dynos_level_cmd_next(void *cmd) { + DynOS_Level_CmdNext((LvlCmd*) cmd); } void dynos_level_parse_script(const void *script, s32 (*aPreprocessFunction)(u8, void *)) { diff --git a/data/dynos_level.cpp b/data/dynos_level.cpp index 983f80ff..181a02ef 100644 --- a/data/dynos_level.cpp +++ b/data/dynos_level.cpp @@ -5,10 +5,6 @@ extern "C" { #include "levels/scripts.h" #include "pc/lua/utils/smlua_level_utils.h" -#ifdef VERSION_EU -#include "eu_translation.h" -#endif - } // @@ -20,20 +16,6 @@ extern const BehaviorScript *sWarpBhvSpawnTable[]; #include "engine/level_script.h" } -#define DYNOS_LEVEL_TEXT_EMPTY "" -#define DYNOS_LEVEL_TEXT_CASTLE "CASTLE" -#define DYNOS_LEVEL_TEXT_BOWSER_1 "BOWSER 1" -#define DYNOS_LEVEL_TEXT_BOWSER_2 "BOWSER 2" -#define DYNOS_LEVEL_TEXT_BOWSER_3 "BOWSER 3" -#define DYNOS_LEVEL_TEXT_100_COINS_STAR "100 COINS STAR" -#define DYNOS_LEVEL_TEXT_RED_COINS_STAR "RED COINS STAR" -#define DYNOS_LEVEL_TEXT_ONE_SECRET_STAR "ONE OF THE CASTLE'S SECRET STARS!" - -static void SetConvertedTextToBuffer(u8 *aBuffer, const char *aText) { - u8 *_ConvertedText = DynOS_String_Convert(aText, false); - memcpy(aBuffer, _ConvertedText, DynOS_String_Length(_ConvertedText) + 1); -} - // // Data // @@ -59,18 +41,18 @@ struct DynosLevelScript { #define DYNOS_LEVEL_MOD_INDEX_VANILLA (-1) static DynosLevelScript sDynosLevelScripts[LEVEL_COUNT] = { { NULL, DYNOS_LEVEL_MOD_INDEX_VANILLA } }; -static void *sDynosLevelScriptsOriginal[LEVEL_COUNT] = { NULL }; +extern void *gDynosLevelScriptsOriginal[LEVEL_COUNT]; static Array sDynosLevelWarps[LEVEL_COUNT] = { Array() }; -static Array sDynosLevelList = Array(); // Ordered by Course Id, COURSE_NONE excluded u64 DynOS_Level_CmdGet(void *aCmd, u64 aOffset) { u64 _Offset = (((aOffset) & 3llu) | (((aOffset) & ~3llu) << (sizeof(void *) >> 3llu))); return *((u64 *) (u64(aCmd) + _Offset)); } -void *DynOS_Level_CmdNext(void *aCmd, u64 aCmdSize) { +LvlCmd *DynOS_Level_CmdNext(LvlCmd *aCmd) { + u64 aCmdSize = aCmd->mSize; u64 _Offset = (((aCmdSize) & 3llu) | (((aCmdSize) & ~3llu) << (sizeof(void *) >> 3llu))); - return (void *) (u64(aCmd) + _Offset); + return (LvlCmd*) (u64(aCmd) + _Offset); } void DynOS_Level_ParseScript(const void *aScript, s32 (*aPreprocessFunction)(u8, void *)); @@ -83,15 +65,7 @@ static s32 DynOS_Level_PreprocessMasterScript(u8 aType, void *aCmd) { static bool sDynosScriptExecLevelTable = false; static s32 sDynosLevelNum = -1; - if (!sDynosScriptExecLevelTable) { - - // JUMP_LINK - if (aType == 0x06) { - sDynosScriptExecLevelTable = true; - return 0; - } - - } else { + if (sDynosScriptExecLevelTable) { // JUMP_IF if (aType == 0x0C) { @@ -105,21 +79,19 @@ static s32 DynOS_Level_PreprocessMasterScript(u8 aType, void *aCmd) { if (sDynosLevelNum >= 0 && sDynosLevelNum < LEVEL_COUNT && !sDynosLevelScripts[sDynosLevelNum].mLevelScript) { sDynosLevelScripts[sDynosLevelNum].mLevelScript = _Script; sDynosLevelScripts[sDynosLevelNum].mModIndex = DYNOS_LEVEL_MOD_INDEX_VANILLA; - sDynosLevelScriptsOriginal[sDynosLevelNum] = _Script; + gDynosLevelScriptsOriginal[sDynosLevelNum] = _Script; } sDynosLevelNum = -1; return 2; } - // EXIT - if (aType == 0x02) { - return 3; - } - - // SLEEP - if (aType == 0x03) { + // EXIT or SLEEP + if (aType == 0x02 || aType == 0x03) { return 3; } + } else if (aType == 0x06) { // JUMP_LINK + sDynosScriptExecLevelTable = true; + return 0; } return 0; } @@ -184,8 +156,7 @@ static s32 DynOS_Level_PreprocessScript(u8 aType, void *aCmd) { } } - // SLEEP - // SLEEP_BEFORE_EXIT + // SLEEP or SLEEP_BEFORE_EXIT else if (aType == 0x03 || aType == 0x04) { return 3; } @@ -194,30 +165,19 @@ static s32 DynOS_Level_PreprocessScript(u8 aType, void *aCmd) { } // Runs only once -static void DynOS_Level_Init() { +void DynOS_Level_Init() { static bool sInited = false; if (!sInited) { - // Level scripts - DynOS_Level_ParseScript(level_main_scripts_entry, DynOS_Level_PreprocessMasterScript); - // Level warps for (sDynosCurrentLevelNum = 0; sDynosCurrentLevelNum != LEVEL_COUNT; ++sDynosCurrentLevelNum) { + sDynosLevelScripts[sDynosCurrentLevelNum].mLevelScript = gDynosLevelScriptsOriginal[sDynosCurrentLevelNum]; + sDynosLevelScripts[sDynosCurrentLevelNum].mModIndex = DYNOS_LEVEL_MOD_INDEX_VANILLA; if (sDynosLevelScripts[sDynosCurrentLevelNum].mLevelScript) { DynOS_Level_ParseScript(sDynosLevelScripts[sDynosCurrentLevelNum].mLevelScript, DynOS_Level_PreprocessScript); } } - // Level list ordered by course id - for (s32 i = COURSE_MIN; i <= COURSE_MAX; ++i) { - if (i == COURSE_CAKE_END) continue; - for (s32 j = 1; j != LEVEL_COUNT; ++j) { - if (get_level_course_num(j - 1) == i) { - sDynosLevelList.Add(j); - } - } - } - // Done sInited = true; } @@ -227,20 +187,8 @@ static void DynOS_Level_Init() { // Common // -s32 DynOS_Level_GetCount() { - DynOS_Level_Init(); - return sDynosLevelList.Count(); -} - -const s32 *DynOS_Level_GetList() { - DynOS_Level_Init(); - return sDynosLevelList.begin(); -} - -s32 DynOS_Level_GetCourse(s32 aLevel) { - u32 index = aLevel - 1; - if (index >= LEVEL_COUNT) { return COURSE_NONE; } - return (s32) gLevelToCourseNumTable[index]; +s8 DynOS_Level_GetCourse(s32 aLevel) { + return get_level_course_num(aLevel); } void DynOS_Level_Override(void* originalScript, void* newScript, s32 modIndex) { @@ -260,7 +208,7 @@ void DynOS_Level_Unoverride() { for (s32 i = 0; i < LEVEL_COUNT; i++) { sDynosCurrentLevelNum = i; sDynosLevelWarps[i].Clear(); - sDynosLevelScripts[i].mLevelScript = sDynosLevelScriptsOriginal[i]; + sDynosLevelScripts[i].mLevelScript = gDynosLevelScriptsOriginal[i]; sDynosLevelScripts[i].mModIndex = DYNOS_LEVEL_MOD_INDEX_VANILLA; DynOS_Level_ParseScript(sDynosLevelScripts[i].mLevelScript, DynOS_Level_PreprocessScript); } @@ -289,205 +237,21 @@ s32 DynOS_Level_GetModIndex(s32 aLevel) { } bool DynOS_Level_IsVanillaLevel(s32 aLevel) { - if (aLevel >= 0 && aLevel < LEVEL_COUNT) { - return sDynosLevelScripts[aLevel].mLevelScript == sDynosLevelScriptsOriginal[aLevel]; + DynOS_Level_Init(); + + if (aLevel >= LEVEL_MIN && aLevel < LEVEL_COUNT) { + return sDynosLevelScripts[aLevel].mLevelScript == gDynosLevelScriptsOriginal[aLevel]; } return false; } -// -// Course name -// - -const u8 *DynOS_Level_GetName(s32 aLevel, bool aDecaps, bool aAddCourseNumber) { - DynOS_Level_Init(); - static u8 sBuffer[256]; - memset(sBuffer, 0xFF, 256); - s32 _Course = DynOS_Level_GetCourse(aLevel); - - // Level name - if (aLevel == LEVEL_BOWSER_1) { - SetConvertedTextToBuffer(sBuffer, DYNOS_LEVEL_TEXT_BOWSER_1); - } else if (aLevel == LEVEL_BOWSER_2) { - SetConvertedTextToBuffer(sBuffer, DYNOS_LEVEL_TEXT_BOWSER_2); - } else if (aLevel == LEVEL_BOWSER_3) { - SetConvertedTextToBuffer(sBuffer, DYNOS_LEVEL_TEXT_BOWSER_3); - } else if (_Course < COURSE_BOB) { - SetConvertedTextToBuffer(sBuffer, DYNOS_LEVEL_TEXT_CASTLE); - } else if (_Course >= COURSE_CAKE_END) { - SetConvertedTextToBuffer(sBuffer, DYNOS_LEVEL_TEXT_CASTLE); - } else { -#ifdef VERSION_EU - const u8 *_CourseName = ((const u8 **) course_name_table_eu_en)[_Course - COURSE_BOB] + 3; -#else - const u8 *_CourseName = ((const u8 **) seg2_course_name_table)[_Course - COURSE_BOB] + 3; -#endif - memcpy(sBuffer, _CourseName, DynOS_String_Length(_CourseName)); - } - - // Decaps - if (aDecaps) { - DynOS_String_Decapitalize(sBuffer); - } - - // Course number - if (aAddCourseNumber && (_Course >= COURSE_BOB) && (_Course <= COURSE_STAGES_MAX)) { - memmove(sBuffer + 5, sBuffer, DynOS_String_Length(sBuffer)); - sBuffer[0] = ((_Course / 10) == 0 ? 158 : (_Course / 10)); - sBuffer[1] = (_Course % 10); - sBuffer[2] = 158; - sBuffer[3] = 159; - sBuffer[4] = 158; - } - - return sBuffer; -} - -// -// Act/Star name -// - -const u8 *DynOS_Level_GetActName(s32 aLevel, s32 aAct, bool aDecaps, bool aAddStarNumber) { - DynOS_Level_Init(); - static u8 sBuffer[256]; - memset(sBuffer, 0xFF, 256); - s32 _Course = DynOS_Level_GetCourse(aLevel); - - // Star name - if (_Course < COURSE_BOB) { - SetConvertedTextToBuffer(sBuffer, DYNOS_LEVEL_TEXT_ONE_SECRET_STAR); - } else if (aLevel == LEVEL_BITDW) { - SetConvertedTextToBuffer(sBuffer, DYNOS_LEVEL_TEXT_RED_COINS_STAR); - } else if (aLevel == LEVEL_BITFS) { - SetConvertedTextToBuffer(sBuffer, DYNOS_LEVEL_TEXT_RED_COINS_STAR); - } else if (aLevel == LEVEL_BITS) { - SetConvertedTextToBuffer(sBuffer, DYNOS_LEVEL_TEXT_RED_COINS_STAR); - } else if (_Course > COURSE_STAGES_MAX) { - SetConvertedTextToBuffer(sBuffer, DYNOS_LEVEL_TEXT_EMPTY); - } else if (aAct >= 7) { - SetConvertedTextToBuffer(sBuffer, DYNOS_LEVEL_TEXT_100_COINS_STAR); - } else { -#ifdef VERSION_EU - const u8 *_ActName = ((const u8 **) act_name_table_eu_en)[(_Course - COURSE_BOB) * 6 + (aAct - 1)]; -#else - const u8 *_ActName = ((const u8 **) seg2_act_name_table)[(_Course - COURSE_BOB) * 6 + (aAct - 1)]; -#endif - memcpy(sBuffer, _ActName, DynOS_String_Length(_ActName)); - } - - // Decaps - if (aDecaps) { - DynOS_String_Decapitalize(sBuffer); - } - - // Star number - if (aAddStarNumber && (_Course >= COURSE_BOB) && (_Course <= COURSE_STAGES_MAX)) { - memmove(sBuffer + 5, sBuffer, DynOS_String_Length(sBuffer)); - sBuffer[0] = ((aAct / 10) == 0 ? 158 : (aAct / 10)); - sBuffer[1] = (aAct % 10); - sBuffer[2] = 158; - sBuffer[3] = 159; - sBuffer[4] = 158; - } - - return sBuffer; -} - -const u8 *DynOS_Level_GetAreaName(s32 aLevel, s32 aArea, bool aDecaps) { - DynOS_Level_Init(); - static const char *sAreaNamesPerLevel[][4] = { - { "", "", "", "" }, - { "MAIN AREA", "NOT AVAILABLE", "NOT AVAILABLE", "NOT AVAILABLE" }, /* BoB */ - { "MAIN AREA", "NOT AVAILABLE", "NOT AVAILABLE", "NOT AVAILABLE" }, /* WF */ - { "MAIN AREA", "SUNKEN SHIP", "NOT AVAILABLE", "NOT AVAILABLE" }, /* JRB */ - { "MAIN AREA", "COTTAGE SLIDE", "NOT AVAILABLE", "NOT AVAILABLE" }, /* CCM */ - { "MAIN AREA", "NOT AVAILABLE", "NOT AVAILABLE", "NOT AVAILABLE" }, /* BBH */ - { "MAIN AREA", "NOT AVAILABLE", "NOT AVAILABLE", "NOT AVAILABLE" }, /* HMC */ - { "MAIN AREA", "VOLCANO", "NOT AVAILABLE", "NOT AVAILABLE" }, /* LLL */ - { "MAIN AREA", "PYRAMID", "EYEROCK'S ROOM", "NOT AVAILABLE" }, /* SSL */ - { "MAIN AREA", "DOCKS", "NOT AVAILABLE", "NOT AVAILABLE" }, /* DDD */ - { "MAIN AREA", "IGLOO", "NOT AVAILABLE", "NOT AVAILABLE" }, /* SL */ - { "MAIN AREA", "DOWNTOWN", "NOT AVAILABLE", "NOT AVAILABLE" }, /* WDW */ - { "MAIN AREA", "SECRET SLIDE", "NOT AVAILABLE", "NOT AVAILABLE" }, /* TTM */ - { "HUGE ISLAND", "TINY ISLAND", "WIGGLER'S ROOM", "NOT AVAILABLE" }, /* THI */ - { "MAIN AREA", "NOT AVAILABLE", "NOT AVAILABLE", "NOT AVAILABLE" }, /* TTC */ - { "MAIN AREA", "NOT AVAILABLE", "NOT AVAILABLE", "NOT AVAILABLE" }, /* RR */ - { "MAIN AREA", "NOT AVAILABLE", "NOT AVAILABLE", "NOT AVAILABLE" }, /* BITDW */ - { "BOWSER BATTLE", "NOT AVAILABLE", "NOT AVAILABLE", "NOT AVAILABLE" }, /* Bowser 1 */ - { "MAIN AREA", "NOT AVAILABLE", "NOT AVAILABLE", "NOT AVAILABLE" }, /* BITFS */ - { "BOWSER BATTLE", "NOT AVAILABLE", "NOT AVAILABLE", "NOT AVAILABLE" }, /* Bowser 2 */ - { "MAIN AREA", "NOT AVAILABLE", "NOT AVAILABLE", "NOT AVAILABLE" }, /* BITS */ - { "BOWSER BATTLE", "NOT AVAILABLE", "NOT AVAILABLE", "NOT AVAILABLE" }, /* Bowser 3 */ - { "MAIN AREA", "NOT AVAILABLE", "NOT AVAILABLE", "NOT AVAILABLE" }, /* PSS */ - { "MAIN AREA", "NOT AVAILABLE", "NOT AVAILABLE", "NOT AVAILABLE" }, /* TOTWC */ - { "MAIN AREA", "NOT AVAILABLE", "NOT AVAILABLE", "NOT AVAILABLE" }, /* COTMC */ - { "MAIN AREA", "NOT AVAILABLE", "NOT AVAILABLE", "NOT AVAILABLE" }, /* VCUTM */ - { "MAIN AREA", "NOT AVAILABLE", "NOT AVAILABLE", "NOT AVAILABLE" }, /* WMOTR */ - { "MAIN AREA", "NOT AVAILABLE", "NOT AVAILABLE", "NOT AVAILABLE" }, /* SA */ - { "MAIN AREA", "NOT AVAILABLE", "NOT AVAILABLE", "NOT AVAILABLE" }, /* Castle grounds */ - { "FIRST FLOOR", "SECOND FLOOR", "BASEMENT", "NOT AVAILABLE" }, /* Castle inside */ - { "MAIN AREA", "NOT AVAILABLE", "NOT AVAILABLE", "NOT AVAILABLE" }, /* Castle courtyard */ - { "ENDING", "NOT AVAILABLE", "NOT AVAILABLE", "NOT AVAILABLE" }, /* Ending */ - }; - static u8 sBuffer[256]; - memset(sBuffer, 0xFF, 256); - - // Area name - switch (aLevel) { - case LEVEL_BOB: SetConvertedTextToBuffer(sBuffer, sAreaNamesPerLevel[1][MIN(MAX(aArea - 1, 0), 3)]); break; - case LEVEL_WF: SetConvertedTextToBuffer(sBuffer, sAreaNamesPerLevel[2][MIN(MAX(aArea - 1, 0), 3)]); break; - case LEVEL_JRB: SetConvertedTextToBuffer(sBuffer, sAreaNamesPerLevel[3][MIN(MAX(aArea - 1, 0), 3)]); break; - case LEVEL_CCM: SetConvertedTextToBuffer(sBuffer, sAreaNamesPerLevel[4][MIN(MAX(aArea - 1, 0), 3)]); break; - case LEVEL_BBH: SetConvertedTextToBuffer(sBuffer, sAreaNamesPerLevel[5][MIN(MAX(aArea - 1, 0), 3)]); break; - case LEVEL_HMC: SetConvertedTextToBuffer(sBuffer, sAreaNamesPerLevel[6][MIN(MAX(aArea - 1, 0), 3)]); break; - case LEVEL_LLL: SetConvertedTextToBuffer(sBuffer, sAreaNamesPerLevel[7][MIN(MAX(aArea - 1, 0), 3)]); break; - case LEVEL_SSL: SetConvertedTextToBuffer(sBuffer, sAreaNamesPerLevel[8][MIN(MAX(aArea - 1, 0), 3)]); break; - case LEVEL_DDD: SetConvertedTextToBuffer(sBuffer, sAreaNamesPerLevel[9][MIN(MAX(aArea - 1, 0), 3)]); break; - case LEVEL_SL: SetConvertedTextToBuffer(sBuffer, sAreaNamesPerLevel[10][MIN(MAX(aArea - 1, 0), 3)]); break; - case LEVEL_WDW: SetConvertedTextToBuffer(sBuffer, sAreaNamesPerLevel[11][MIN(MAX(aArea - 1, 0), 3)]); break; - case LEVEL_TTM: SetConvertedTextToBuffer(sBuffer, sAreaNamesPerLevel[12][MIN(MAX(aArea - 1, 0), 3)]); break; - case LEVEL_THI: SetConvertedTextToBuffer(sBuffer, sAreaNamesPerLevel[13][MIN(MAX(aArea - 1, 0), 3)]); break; - case LEVEL_TTC: SetConvertedTextToBuffer(sBuffer, sAreaNamesPerLevel[14][MIN(MAX(aArea - 1, 0), 3)]); break; - case LEVEL_RR: SetConvertedTextToBuffer(sBuffer, sAreaNamesPerLevel[15][MIN(MAX(aArea - 1, 0), 3)]); break; - case LEVEL_BITDW: SetConvertedTextToBuffer(sBuffer, sAreaNamesPerLevel[16][MIN(MAX(aArea - 1, 0), 3)]); break; - case LEVEL_BOWSER_1: SetConvertedTextToBuffer(sBuffer, sAreaNamesPerLevel[17][MIN(MAX(aArea - 1, 0), 3)]); break; - case LEVEL_BITFS: SetConvertedTextToBuffer(sBuffer, sAreaNamesPerLevel[18][MIN(MAX(aArea - 1, 0), 3)]); break; - case LEVEL_BOWSER_2: SetConvertedTextToBuffer(sBuffer, sAreaNamesPerLevel[19][MIN(MAX(aArea - 1, 0), 3)]); break; - case LEVEL_BITS: SetConvertedTextToBuffer(sBuffer, sAreaNamesPerLevel[20][MIN(MAX(aArea - 1, 0), 3)]); break; - case LEVEL_BOWSER_3: SetConvertedTextToBuffer(sBuffer, sAreaNamesPerLevel[21][MIN(MAX(aArea - 1, 0), 3)]); break; - case LEVEL_PSS: SetConvertedTextToBuffer(sBuffer, sAreaNamesPerLevel[22][MIN(MAX(aArea - 1, 0), 3)]); break; - case LEVEL_TOTWC: SetConvertedTextToBuffer(sBuffer, sAreaNamesPerLevel[23][MIN(MAX(aArea - 1, 0), 3)]); break; - case LEVEL_COTMC: SetConvertedTextToBuffer(sBuffer, sAreaNamesPerLevel[24][MIN(MAX(aArea - 1, 0), 3)]); break; - case LEVEL_VCUTM: SetConvertedTextToBuffer(sBuffer, sAreaNamesPerLevel[25][MIN(MAX(aArea - 1, 0), 3)]); break; - case LEVEL_WMOTR: SetConvertedTextToBuffer(sBuffer, sAreaNamesPerLevel[26][MIN(MAX(aArea - 1, 0), 3)]); break; - case LEVEL_SA: SetConvertedTextToBuffer(sBuffer, sAreaNamesPerLevel[27][MIN(MAX(aArea - 1, 0), 3)]); break; - case LEVEL_CASTLE_GROUNDS: SetConvertedTextToBuffer(sBuffer, sAreaNamesPerLevel[28][MIN(MAX(aArea - 1, 0), 3)]); break; - case LEVEL_CASTLE: SetConvertedTextToBuffer(sBuffer, sAreaNamesPerLevel[29][MIN(MAX(aArea - 1, 0), 3)]); break; - case LEVEL_CASTLE_COURTYARD: SetConvertedTextToBuffer(sBuffer, sAreaNamesPerLevel[30][MIN(MAX(aArea - 1, 0), 3)]); break; - case LEVEL_ENDING: SetConvertedTextToBuffer(sBuffer, sAreaNamesPerLevel[31][MIN(MAX(aArea - 1, 0), 3)]); break; - default: SetConvertedTextToBuffer(sBuffer, sAreaNamesPerLevel[0][MIN(MAX(aArea - 1, 0), 3)]); break; - } - - // Decaps - if (aDecaps) { - DynOS_String_Decapitalize(sBuffer); - } - return sBuffer; -} - // // Level Script Preprocessing -// By default, // - Ifs are always true // - Skips are always false // - Loops break after the first loop // -struct LvlCmd { - u8 mType; - u8 mSize; -}; - struct Stack { u64 mData[32]; s32 mBaseIndex; @@ -512,7 +276,7 @@ static T StackPop(Stack& aStack) { } static LvlCmd *DynOS_Level_CmdExecute(Stack &aStack, LvlCmd *aCmd) { - StackPush(aStack, DynOS_Level_CmdNext(aCmd, aCmd->mSize)); + StackPush(aStack, DynOS_Level_CmdNext(aCmd)); StackPush(aStack, aStack.mBaseIndex); aStack.mBaseIndex = aStack.mTopIndex; return (LvlCmd *) DynOS_Level_CmdGet(aCmd, 12); @@ -529,20 +293,12 @@ static LvlCmd *DynOS_Level_CmdExit(Stack &aStack, LvlCmd *aCmd) { return StackPop(aStack); } -static LvlCmd *DynOS_Level_CmdSleep(Stack &aStack, LvlCmd *aCmd) { - return (LvlCmd *) DynOS_Level_CmdNext(aCmd, aCmd->mSize); -} - -static LvlCmd *DynOS_Level_CmdSleepBeforeExit(Stack &aStack, LvlCmd *aCmd) { - return (LvlCmd *) DynOS_Level_CmdNext(aCmd, aCmd->mSize); -} - static LvlCmd *DynOS_Level_CmdJump(Stack &aStack, LvlCmd *aCmd) { return (LvlCmd *) DynOS_Level_CmdGet(aCmd, 4); } static LvlCmd *DynOS_Level_CmdJumpLink(Stack &aStack, LvlCmd *aCmd) { - StackPush(aStack, DynOS_Level_CmdNext(aCmd, aCmd->mSize)); + StackPush(aStack, DynOS_Level_CmdNext(aCmd)); return (LvlCmd *) DynOS_Level_CmdGet(aCmd, 4); } @@ -551,248 +307,40 @@ static LvlCmd *DynOS_Level_CmdReturn(Stack &aStack, UNUSED LvlCmd *aCmd) { } static LvlCmd *DynOS_Level_CmdJumpLinkPushArg(Stack &aStack, LvlCmd *aCmd) { - StackPush(aStack, DynOS_Level_CmdNext(aCmd, aCmd->mSize)); + StackPush(aStack, DynOS_Level_CmdNext(aCmd)); StackPush(aStack, DynOS_Level_CmdGet(aCmd, 2)); - return (LvlCmd *) DynOS_Level_CmdNext(aCmd, aCmd->mSize); + return DynOS_Level_CmdNext(aCmd); } static LvlCmd *DynOS_Level_CmdJumpRepeat(Stack &aStack, LvlCmd *aCmd) { aStack.mTopIndex -= 2; - return (LvlCmd *) DynOS_Level_CmdNext(aCmd, aCmd->mSize); + return DynOS_Level_CmdNext(aCmd); } static LvlCmd *DynOS_Level_CmdLoopBegin(Stack &aStack, LvlCmd *aCmd) { - StackPush(aStack, DynOS_Level_CmdNext(aCmd, aCmd->mSize)); + StackPush(aStack, DynOS_Level_CmdNext(aCmd)); StackPush(aStack, 0); - return (LvlCmd *) DynOS_Level_CmdNext(aCmd, aCmd->mSize); + return DynOS_Level_CmdNext(aCmd); } static LvlCmd *DynOS_Level_CmdLoopUntil(Stack &aStack, LvlCmd *aCmd) { aStack.mTopIndex -= 2; - return (LvlCmd *) DynOS_Level_CmdNext(aCmd, aCmd->mSize); + return DynOS_Level_CmdNext(aCmd); } static LvlCmd *DynOS_Level_CmdJumpIf(Stack &aStack, LvlCmd *aCmd) { - StackPush(aStack, DynOS_Level_CmdNext(aCmd, aCmd->mSize)); /* Not an error, that's intentional */ + StackPush(aStack, DynOS_Level_CmdNext(aCmd)); /* Not an error, that's intentional */ return (LvlCmd *) DynOS_Level_CmdGet(aCmd, 8); } static LvlCmd *DynOS_Level_CmdJumpLinkIf(Stack &aStack, LvlCmd *aCmd) { - StackPush(aStack, DynOS_Level_CmdNext(aCmd, aCmd->mSize)); + StackPush(aStack, DynOS_Level_CmdNext(aCmd)); return (LvlCmd *) DynOS_Level_CmdGet(aCmd, 8); } -static LvlCmd *DynOS_Level_CmdSkipIf(Stack &aStack, LvlCmd *aCmd) { - return (LvlCmd *) DynOS_Level_CmdNext(aCmd, aCmd->mSize); -} - -static LvlCmd *DynOS_Level_CmdSkip(Stack &aStack, LvlCmd *aCmd) { - return (LvlCmd *) DynOS_Level_CmdNext(aCmd, aCmd->mSize); -} - -static LvlCmd *DynOS_Level_CmdSkipNop(Stack &aStack, LvlCmd *aCmd) { - return (LvlCmd *) DynOS_Level_CmdNext(aCmd, aCmd->mSize); -} - -static LvlCmd *DynOS_Level_CmdCall(Stack &aStack, LvlCmd *aCmd) { - return (LvlCmd *) DynOS_Level_CmdNext(aCmd, aCmd->mSize); -} - -static LvlCmd *DynOS_Level_CmdCallLoop(Stack &aStack, LvlCmd *aCmd) { - return (LvlCmd *) DynOS_Level_CmdNext(aCmd, aCmd->mSize); -} - -static LvlCmd *DynOS_Level_CmdSetRegister(Stack &aStack, LvlCmd *aCmd) { - return (LvlCmd *) DynOS_Level_CmdNext(aCmd, aCmd->mSize); -} - -static LvlCmd *DynOS_Level_CmdPushPool(Stack &aStack, LvlCmd *aCmd) { - return (LvlCmd *) DynOS_Level_CmdNext(aCmd, aCmd->mSize); -} - -static LvlCmd *DynOS_Level_CmdPopPool(Stack &aStack, LvlCmd *aCmd) { - return (LvlCmd *) DynOS_Level_CmdNext(aCmd, aCmd->mSize); -} - -static LvlCmd *DynOS_Level_CmdLoadFixed(Stack &aStack, LvlCmd *aCmd) { - return (LvlCmd *) DynOS_Level_CmdNext(aCmd, aCmd->mSize); -} - -static LvlCmd *DynOS_Level_CmdLoadRaw(Stack &aStack, LvlCmd *aCmd) { - return (LvlCmd *) DynOS_Level_CmdNext(aCmd, aCmd->mSize); -} - -static LvlCmd *DynOS_Level_CmdLoadMIO0(Stack &aStack, LvlCmd *aCmd) { - return (LvlCmd *) DynOS_Level_CmdNext(aCmd, aCmd->mSize); -} - -static LvlCmd *DynOS_Level_CmdLoadMarioHead(Stack &aStack, LvlCmd *aCmd) { - return (LvlCmd *) DynOS_Level_CmdNext(aCmd, aCmd->mSize); -} - -static LvlCmd *DynOS_Level_CmdLoadMIO0Texture(Stack &aStack, LvlCmd *aCmd) { - return (LvlCmd *) DynOS_Level_CmdNext(aCmd, aCmd->mSize); -} - -static LvlCmd *DynOS_Level_CmdInitLevel(Stack &aStack, LvlCmd *aCmd) { - return (LvlCmd *) DynOS_Level_CmdNext(aCmd, aCmd->mSize); -} - -static LvlCmd *DynOS_Level_CmdClearLevel(Stack &aStack, LvlCmd *aCmd) { - return (LvlCmd *) DynOS_Level_CmdNext(aCmd, aCmd->mSize); -} - -static LvlCmd *DynOS_Level_CmdAllocLevelPool(Stack &aStack, LvlCmd *aCmd) { - return (LvlCmd *) DynOS_Level_CmdNext(aCmd, aCmd->mSize); -} - -static LvlCmd *DynOS_Level_CmdFreeLevelPool(Stack &aStack, LvlCmd *aCmd) { - return (LvlCmd *) DynOS_Level_CmdNext(aCmd, aCmd->mSize); -} - -static LvlCmd *DynOS_Level_CmdBeginArea(Stack &aStack, LvlCmd *aCmd) { - return (LvlCmd *) DynOS_Level_CmdNext(aCmd, aCmd->mSize); -} - -static LvlCmd *DynOS_Level_CmdEndArea(Stack &aStack, LvlCmd *aCmd) { - return (LvlCmd *) DynOS_Level_CmdNext(aCmd, aCmd->mSize); -} - -static LvlCmd *DynOS_Level_CmdLoadModelFromDL(Stack &aStack, LvlCmd *aCmd) { - return (LvlCmd *) DynOS_Level_CmdNext(aCmd, aCmd->mSize); -} - -static LvlCmd *DynOS_Level_CmdLoadModelFromGeo(Stack &aStack, LvlCmd *aCmd) { - return (LvlCmd *) DynOS_Level_CmdNext(aCmd, aCmd->mSize); -} - -static LvlCmd *DynOS_Level_Cmd23(Stack &aStack, LvlCmd *aCmd) { - return (LvlCmd *) DynOS_Level_CmdNext(aCmd, aCmd->mSize); -} - -static LvlCmd *DynOS_Level_CmdMario(Stack &aStack, LvlCmd *aCmd) { - return (LvlCmd *) DynOS_Level_CmdNext(aCmd, aCmd->mSize); -} - -static LvlCmd *DynOS_Level_CmdObject(Stack &aStack, LvlCmd *aCmd) { - return (LvlCmd *) DynOS_Level_CmdNext(aCmd, aCmd->mSize); -} - -static LvlCmd *DynOS_Level_CmdWarpNode(Stack &aStack, LvlCmd *aCmd) { - return (LvlCmd *) DynOS_Level_CmdNext(aCmd, aCmd->mSize); -} - -static LvlCmd *DynOS_Level_CmdInstantWarp(Stack &aStack, LvlCmd *aCmd) { - return (LvlCmd *) DynOS_Level_CmdNext(aCmd, aCmd->mSize); -} - -static LvlCmd *DynOS_Level_CmdSetTerrainType(Stack &aStack, LvlCmd *aCmd) { - return (LvlCmd *) DynOS_Level_CmdNext(aCmd, aCmd->mSize); -} - -static LvlCmd *DynOS_Level_CmdPaintingWarpNode(Stack &aStack, LvlCmd *aCmd) { - return (LvlCmd *) DynOS_Level_CmdNext(aCmd, aCmd->mSize); -} - -static LvlCmd *DynOS_Level_Cmd3A(Stack &aStack, LvlCmd *aCmd) { - return (LvlCmd *) DynOS_Level_CmdNext(aCmd, aCmd->mSize); -} - -static LvlCmd *DynOS_Level_CmdSetWhirlpool(Stack &aStack, LvlCmd *aCmd) { - return (LvlCmd *) DynOS_Level_CmdNext(aCmd, aCmd->mSize); -} - -static LvlCmd *DynOS_Level_CmdSetBlackout(Stack &aStack, LvlCmd *aCmd) { - return (LvlCmd *) DynOS_Level_CmdNext(aCmd, aCmd->mSize); -} - -static LvlCmd *DynOS_Level_CmdSetGamma(Stack &aStack, LvlCmd *aCmd) { - return (LvlCmd *) DynOS_Level_CmdNext(aCmd, aCmd->mSize); -} - -static LvlCmd *DynOS_Level_CmdSetTerrain(Stack &aStack, LvlCmd *aCmd) { - return (LvlCmd *) DynOS_Level_CmdNext(aCmd, aCmd->mSize); -} - -static LvlCmd *DynOS_Level_CmdSetRooms(Stack &aStack, LvlCmd *aCmd) { - return (LvlCmd *) DynOS_Level_CmdNext(aCmd, aCmd->mSize); -} - -static LvlCmd *DynOS_Level_CmdMacroObjects(Stack &aStack, LvlCmd *aCmd) { - return (LvlCmd *) DynOS_Level_CmdNext(aCmd, aCmd->mSize); -} - -static LvlCmd *DynOS_Level_CmdLoadArea(Stack &aStack, LvlCmd *aCmd) { - return (LvlCmd *) DynOS_Level_CmdNext(aCmd, aCmd->mSize); -} - -static LvlCmd *DynOS_Level_CmdUnloadArea(Stack &aStack, LvlCmd *aCmd) { - return (LvlCmd *) DynOS_Level_CmdNext(aCmd, aCmd->mSize); -} - -static LvlCmd *DynOS_Level_CmdSetMarioStartPos(Stack &aStack, LvlCmd *aCmd) { - return (LvlCmd *) DynOS_Level_CmdNext(aCmd, aCmd->mSize); -} - -static LvlCmd *DynOS_Level_Cmd2C(Stack &aStack, LvlCmd *aCmd) { - return (LvlCmd *) DynOS_Level_CmdNext(aCmd, aCmd->mSize); -} - -static LvlCmd *DynOS_Level_Cmd2D(Stack &aStack, LvlCmd *aCmd) { - return (LvlCmd *) DynOS_Level_CmdNext(aCmd, aCmd->mSize); -} - -static LvlCmd *DynOS_Level_CmdSetTransition(Stack &aStack, LvlCmd *aCmd) { - return (LvlCmd *) DynOS_Level_CmdNext(aCmd, aCmd->mSize); -} - -static LvlCmd *DynOS_Level_CmdNop(Stack &aStack, LvlCmd *aCmd) { - return (LvlCmd *) DynOS_Level_CmdNext(aCmd, aCmd->mSize); -} - -static LvlCmd *DynOS_Level_CmdShowDialog(Stack &aStack, LvlCmd *aCmd) { - return (LvlCmd *) DynOS_Level_CmdNext(aCmd, aCmd->mSize); -} - -static LvlCmd *DynOS_Level_CmdSetBackgroundMusic(Stack &aStack, LvlCmd *aCmd) { - return (LvlCmd *) DynOS_Level_CmdNext(aCmd, aCmd->mSize); -} - -static LvlCmd *DynOS_Level_CmdSetMenuMusic(Stack &aStack, LvlCmd *aCmd) { - return (LvlCmd *) DynOS_Level_CmdNext(aCmd, aCmd->mSize); -} - -static LvlCmd *DynOS_Level_CmdStopMusic(Stack &aStack, LvlCmd *aCmd) { - return (LvlCmd *) DynOS_Level_CmdNext(aCmd, aCmd->mSize); -} - -static LvlCmd *DynOS_Level_CmdGetOrSet(Stack &aStack, LvlCmd *aCmd) { - return (LvlCmd *) DynOS_Level_CmdNext(aCmd, aCmd->mSize); -} - -static LvlCmd *DynOS_Level_CmdAdvanceDemo(Stack &aStack, LvlCmd *aCmd) { - return (LvlCmd *) DynOS_Level_CmdNext(aCmd, aCmd->mSize); -} - -static LvlCmd *DynOS_Level_CmdClearDemoPointer(Stack &aStack, LvlCmd *aCmd) { - return (LvlCmd *) DynOS_Level_CmdNext(aCmd, aCmd->mSize); -} - -static LvlCmd *DynOS_Level_CmdPlaceObjectExt(Stack &aStack, LvlCmd *aCmd) { - return (LvlCmd *) DynOS_Level_CmdNext(aCmd, aCmd->mSize); -} - -static LvlCmd *DynOS_Level_CmdPlaceObjectExt2(Stack &aStack, LvlCmd *aCmd) { - return (LvlCmd *) DynOS_Level_CmdNext(aCmd, aCmd->mSize); -} - -static LvlCmd *DynOS_Level_CmdLoadModelFromGeoExt(Stack &aStack, LvlCmd *aCmd) { - return (LvlCmd *) DynOS_Level_CmdNext(aCmd, aCmd->mSize); -} - static LvlCmd *DynOS_Level_CmdJumpArea(Stack &aStack, LvlCmd *aCmd, s32 (*aPreprocessFunction)(u8, void *)) { DynOS_Level_ParseScript((const void *) DynOS_Level_CmdGet(aCmd, 8), aPreprocessFunction); - return (LvlCmd *) DynOS_Level_CmdNext(aCmd, aCmd->mSize); + return DynOS_Level_CmdNext(aCmd); } void DynOS_Level_ParseScript(const void *aScript, s32 (*aPreprocessFunction)(u8, void *)) { @@ -808,8 +356,6 @@ void DynOS_Level_ParseScript(const void *aScript, s32 (*aPreprocessFunction)(u8, case 0x00: _Cmd = DynOS_Level_CmdExecute(_Stack, _Cmd); break; case 0x01: _Cmd = DynOS_Level_CmdExitAndExecute(_Stack, _Cmd); break; case 0x02: _Cmd = DynOS_Level_CmdExit(_Stack, _Cmd); break; - case 0x03: _Cmd = DynOS_Level_CmdSleep(_Stack, _Cmd); break; - case 0x04: _Cmd = DynOS_Level_CmdSleepBeforeExit(_Stack, _Cmd); break; case 0x05: _Cmd = DynOS_Level_CmdJump(_Stack, _Cmd); break; case 0x06: _Cmd = DynOS_Level_CmdJumpLink(_Stack, _Cmd); break; case 0x07: _Cmd = DynOS_Level_CmdReturn(_Stack, _Cmd); break; @@ -819,64 +365,15 @@ void DynOS_Level_ParseScript(const void *aScript, s32 (*aPreprocessFunction)(u8, case 0x0B: _Cmd = DynOS_Level_CmdLoopUntil(_Stack, _Cmd); break; case 0x0C: _Cmd = DynOS_Level_CmdJumpIf(_Stack, _Cmd); break; case 0x0D: _Cmd = DynOS_Level_CmdJumpLinkIf(_Stack, _Cmd); break; - case 0x0E: _Cmd = DynOS_Level_CmdSkipIf(_Stack, _Cmd); break; - case 0x0F: _Cmd = DynOS_Level_CmdSkip(_Stack, _Cmd); break; - case 0x10: _Cmd = DynOS_Level_CmdSkipNop(_Stack, _Cmd); break; - case 0x11: _Cmd = DynOS_Level_CmdCall(_Stack, _Cmd); break; - case 0x12: _Cmd = DynOS_Level_CmdCallLoop(_Stack, _Cmd); break; - case 0x13: _Cmd = DynOS_Level_CmdSetRegister(_Stack, _Cmd); break; - case 0x14: _Cmd = DynOS_Level_CmdPushPool(_Stack, _Cmd); break; - case 0x15: _Cmd = DynOS_Level_CmdPopPool(_Stack, _Cmd); break; - case 0x16: _Cmd = DynOS_Level_CmdLoadFixed(_Stack, _Cmd); break; - case 0x17: _Cmd = DynOS_Level_CmdLoadRaw(_Stack, _Cmd); break; - case 0x18: _Cmd = DynOS_Level_CmdLoadMIO0(_Stack, _Cmd); break; - case 0x19: _Cmd = DynOS_Level_CmdLoadMarioHead(_Stack, _Cmd); break; - case 0x1A: _Cmd = DynOS_Level_CmdLoadMIO0Texture(_Stack, _Cmd); break; - case 0x1B: _Cmd = DynOS_Level_CmdInitLevel(_Stack, _Cmd); break; - case 0x1C: _Cmd = DynOS_Level_CmdClearLevel(_Stack, _Cmd); break; - case 0x1D: _Cmd = DynOS_Level_CmdAllocLevelPool(_Stack, _Cmd); break; - case 0x1E: _Cmd = DynOS_Level_CmdFreeLevelPool(_Stack, _Cmd); break; - case 0x1F: _Cmd = DynOS_Level_CmdBeginArea(_Stack, _Cmd); break; - case 0x20: _Cmd = DynOS_Level_CmdEndArea(_Stack, _Cmd); break; - case 0x21: _Cmd = DynOS_Level_CmdLoadModelFromDL(_Stack, _Cmd); break; - case 0x22: _Cmd = DynOS_Level_CmdLoadModelFromGeo(_Stack, _Cmd); break; - case 0x23: _Cmd = DynOS_Level_Cmd23(_Stack, _Cmd); break; - case 0x24: _Cmd = DynOS_Level_CmdObject(_Stack, _Cmd); break; - case 0x25: _Cmd = DynOS_Level_CmdMario(_Stack, _Cmd); break; - case 0x26: _Cmd = DynOS_Level_CmdWarpNode(_Stack, _Cmd); break; - case 0x27: _Cmd = DynOS_Level_CmdPaintingWarpNode(_Stack, _Cmd); break; - case 0x28: _Cmd = DynOS_Level_CmdInstantWarp(_Stack, _Cmd); break; - case 0x29: _Cmd = DynOS_Level_CmdLoadArea(_Stack, _Cmd); break; - case 0x2A: _Cmd = DynOS_Level_CmdUnloadArea(_Stack, _Cmd); break; - case 0x2B: _Cmd = DynOS_Level_CmdSetMarioStartPos(_Stack, _Cmd); break; - case 0x2C: _Cmd = DynOS_Level_Cmd2C(_Stack, _Cmd); break; - case 0x2D: _Cmd = DynOS_Level_Cmd2D(_Stack, _Cmd); break; - case 0x2E: _Cmd = DynOS_Level_CmdSetTerrain(_Stack, _Cmd); break; - case 0x2F: _Cmd = DynOS_Level_CmdSetRooms(_Stack, _Cmd); break; - case 0x30: _Cmd = DynOS_Level_CmdShowDialog(_Stack, _Cmd); break; - case 0x31: _Cmd = DynOS_Level_CmdSetTerrainType(_Stack, _Cmd); break; - case 0x32: _Cmd = DynOS_Level_CmdNop(_Stack, _Cmd); break; - case 0x33: _Cmd = DynOS_Level_CmdSetTransition(_Stack, _Cmd); break; - case 0x34: _Cmd = DynOS_Level_CmdSetBlackout(_Stack, _Cmd); break; - case 0x35: _Cmd = DynOS_Level_CmdSetGamma(_Stack, _Cmd); break; - case 0x36: _Cmd = DynOS_Level_CmdSetBackgroundMusic(_Stack, _Cmd); break; - case 0x37: _Cmd = DynOS_Level_CmdSetMenuMusic(_Stack, _Cmd); break; - case 0x38: _Cmd = DynOS_Level_CmdStopMusic(_Stack, _Cmd); break; - case 0x39: _Cmd = DynOS_Level_CmdMacroObjects(_Stack, _Cmd); break; - case 0x3A: _Cmd = DynOS_Level_Cmd3A(_Stack, _Cmd); break; - case 0x3B: _Cmd = DynOS_Level_CmdSetWhirlpool(_Stack, _Cmd); break; - case 0x3C: _Cmd = DynOS_Level_CmdGetOrSet(_Stack, _Cmd); break; - case 0x3D: _Cmd = DynOS_Level_CmdAdvanceDemo(_Stack, _Cmd); break; - case 0x3E: _Cmd = DynOS_Level_CmdClearDemoPointer(_Stack, _Cmd); break; + // coop - case 0x3F: _Cmd = DynOS_Level_CmdPlaceObjectExt(_Stack, _Cmd); break; - case 0x40: _Cmd = DynOS_Level_CmdPlaceObjectExt2(_Stack, _Cmd); break; - case 0x41: _Cmd = DynOS_Level_CmdLoadModelFromGeoExt(_Stack, _Cmd); break; case 0x42: _Cmd = DynOS_Level_CmdJumpArea(_Stack, _Cmd, aPreprocessFunction); break; + + default: _Cmd = DynOS_Level_CmdNext(_Cmd); break; } break; case 1: - _Cmd = (LvlCmd *) DynOS_Level_CmdNext(_Cmd, _Cmd->mSize); + _Cmd = DynOS_Level_CmdNext(_Cmd); break; case 2: @@ -900,10 +397,8 @@ s16 *DynOS_Level_GetWarp(s32 aLevel, s32 aArea, u8 aWarpId) { sDynosCurrentLevelNum = 1; DynOS_Level_ParseScript(info->script, DynOS_Level_PreprocessScript); for (const auto &_Warp : sDynosLevelWarps[1]) { - if (_Warp.mArea == aArea) { - if (_Warp.mId == aWarpId) { - return (s16 *) &_Warp; - } + if (_Warp.mArea == aArea && _Warp.mId == aWarpId) { + return (s16 *) &_Warp; } } return NULL; @@ -912,10 +407,8 @@ s16 *DynOS_Level_GetWarp(s32 aLevel, s32 aArea, u8 aWarpId) { DynOS_Level_Init(); if (aLevel >= 0 && aLevel < LEVEL_COUNT) { for (const auto &_Warp : sDynosLevelWarps[aLevel]) { - if (_Warp.mArea == aArea) { - if (_Warp.mId == aWarpId) { - return (s16 *) &_Warp; - } + if (_Warp.mArea == aArea && _Warp.mId == aWarpId) { + return (s16 *) &_Warp; } } } @@ -924,7 +417,6 @@ s16 *DynOS_Level_GetWarp(s32 aLevel, s32 aArea, u8 aWarpId) { s16 *DynOS_Level_GetWarpEntry(s32 aLevel, s32 aArea) { DynOS_Level_Init(); - if (aLevel == LEVEL_TTM && aArea > 2) return NULL; // override vanilla castle warps if (DynOS_Level_GetCourse(aLevel) == COURSE_NONE && aLevel >= 0 && aLevel < LEVEL_COUNT) { diff --git a/data/dynos_main.cpp b/data/dynos_main.cpp index 4470530a..a2b107e6 100644 --- a/data/dynos_main.cpp +++ b/data/dynos_main.cpp @@ -3,7 +3,6 @@ extern "C" { #include "sm64.h" #include "level_commands.h" #include "game/level_update.h" -#include "game/options_menu.h" #include "game/object_list_processor.h" extern s16 gMenuMode; extern s8 gDialogBoxState; @@ -17,38 +16,17 @@ extern void omm_opt_init(); // void DynOS_ReturnToMainMenu() { - optmenu_toggle(); level_set_transition(0, NULL); gDialogBoxState = 0; gMenuMode = -1; fade_into_special_warp(-2, 0); } -// -// Init -// - -DYNOS_AT_STARTUP void DynOS_Init() { -#ifdef OMM_DEFINES_H - omm_opt_init(); -#endif - DynOS_Opt_Init(); -} - // // Update // static bool sDynosIsLevelEntry = false; -void DynOS_UpdateOpt(void *aPad) { - if (sDynosIsLevelEntry) { - DynOS_Warp_SetParam(gCurrLevelNum, -1); - sDynosIsLevelEntry = false; - } - DynOS_Opt_Update((OSContPad *) aPad); - gPrevFrameObjectCount = 0; -} - void *DynOS_SwapCmd(void *aCmd) { return DynOS_Lvl_Override(aCmd); } diff --git a/data/dynos_mgr_anim.cpp b/data/dynos_mgr_anim.cpp index 02b74f7b..472ffdc0 100644 --- a/data/dynos_mgr_anim.cpp +++ b/data/dynos_mgr_anim.cpp @@ -43,7 +43,7 @@ void DynOS_Anim_Swap(void *aPtr) { static Animation *pDefaultAnimation = NULL; static Animation sGfxDataAnimation; - // Does the object has a model? + // Does the object have a model? struct Object *_Object = (struct Object *) aPtr; if (!_Object->header.gfx.sharedChild) { return; diff --git a/data/dynos_mgr_builtin.cpp b/data/dynos_mgr_builtin.cpp index 928881b9..96e0b20d 100644 --- a/data/dynos_mgr_builtin.cpp +++ b/data/dynos_mgr_builtin.cpp @@ -100,7 +100,7 @@ extern "C" { } \ } \ return NULL; - + #define MGR_FIND_DATA_FROM_TABLES(_DataTable, _DataTable2, _Cast) \ size_t _count = sizeof(_DataTable) / (2 * sizeof(_DataTable[0])); \ for (u32 _i = 0; _i < _count; _i++) { \ @@ -183,6 +183,48 @@ static const void* sDynosBuiltinScriptPtrs[] = { define_builtin(level_main_menu_entry_1), }; +#define define_level_original(lvl, script) (void*) script + +void* gDynosLevelScriptsOriginal[LEVEL_COUNT] = { + define_level_original(0, NULL), + define_level_original(LEVEL_UNKNOWN_1, NULL), + define_level_original(LEVEL_UNKNOWN_2, NULL), + define_level_original(LEVEL_UNKNOWN_3, NULL), + define_level_original(LEVEL_BBH, level_bbh_entry), + define_level_original(LEVEL_CCM, level_ccm_entry), + define_level_original(LEVEL_CASTLE, level_castle_inside_entry), + define_level_original(LEVEL_HMC, level_hmc_entry), + define_level_original(LEVEL_SSL, level_ssl_entry), + define_level_original(LEVEL_BOB, level_bob_entry), + define_level_original(LEVEL_SL, level_sl_entry), + define_level_original(LEVEL_WDW, level_wdw_entry), + define_level_original(LEVEL_JRB, level_jrb_entry), + define_level_original(LEVEL_THI, level_thi_entry), + define_level_original(LEVEL_TTC, level_ttc_entry), + define_level_original(LEVEL_RR, level_rr_entry), + define_level_original(LEVEL_CASTLE_GROUNDS, level_castle_grounds_entry), + define_level_original(LEVEL_BITDW, level_bitdw_entry), + define_level_original(LEVEL_VCUTM, level_vcutm_entry), + define_level_original(LEVEL_BITFS, level_bitfs_entry), + define_level_original(LEVEL_SA, level_sa_entry), + define_level_original(LEVEL_BITS, level_bits_entry), + define_level_original(LEVEL_LLL, level_lll_entry), + define_level_original(LEVEL_DDD, level_ddd_entry), + define_level_original(LEVEL_WF, level_wf_entry), + define_level_original(LEVEL_ENDING, level_ending_entry), + define_level_original(LEVEL_CASTLE_COURTYARD, level_castle_courtyard_entry), + define_level_original(LEVEL_PSS, level_pss_entry), + define_level_original(LEVEL_COTMC, level_cotmc_entry), + define_level_original(LEVEL_TOTWC, level_totwc_entry), + define_level_original(LEVEL_BOWSER_1, level_bowser_1_entry), + define_level_original(LEVEL_WMOTR, level_wmotr_entry), + define_level_original(LEVEL_UNKNOWN_32, NULL), + define_level_original(LEVEL_BOWSER_2, level_bowser_2_entry), + define_level_original(LEVEL_BOWSER_3, level_bowser_3_entry), + define_level_original(LEVEL_UNKNOWN_35, NULL), + define_level_original(LEVEL_TTM, level_ttm_entry), +}; + const void* DynOS_Builtin_ScriptPtr_GetFromName(const char* aDataName) { MGR_FIND_DATA(sDynosBuiltinScriptPtrs, (const void*)); } @@ -1089,7 +1131,7 @@ static const void* sDynosBuiltinCols[] = { define_builtin(wf_seg7_collision_trapezoid), define_builtin(wf_seg7_collision_tumbling_bridge), define_builtin(wmotr_seg7_collision), - + // Actor Collisions define_builtin(bbh_seg7_collision_coffin), define_builtin(bbh_seg7_collision_haunted_bookshelf), @@ -1356,7 +1398,7 @@ static const void* sDynosBuiltinFuncs[] = { define_builtin(geo_movtex_draw_water_regions_ext), define_builtin(lvl_init_or_update), define_builtin(geo_choose_area_ext), - + // Behaviors define_builtin(bhv_cap_switch_loop), define_builtin(bhv_tiny_star_particles_init), @@ -1909,13 +1951,13 @@ static const void* sDynosBuiltinFuncs[] = { define_builtin(bhv_dust_smoke_loop), define_builtin(bhv_yoshi_loop), define_builtin(bhv_volcano_trap_loop), - + // mario_misc.h define_builtin(bhv_toad_message_init), define_builtin(bhv_toad_message_loop), define_builtin(bhv_unlock_door_star_init), define_builtin(bhv_unlock_door_star_loop), - + // Other define_builtin(load_object_collision_model), define_builtin(obj_set_secondary_camera_focus), diff --git a/data/dynos_mgr_lvl.cpp b/data/dynos_mgr_lvl.cpp index c9a11113..44ef9bd8 100644 --- a/data/dynos_mgr_lvl.cpp +++ b/data/dynos_mgr_lvl.cpp @@ -56,7 +56,7 @@ void DynOS_Lvl_Activate(s32 modIndex, const SysPath &aFilename, const char *aLev auto& _OverrideLevelScripts = DynosOverrideLevelScripts(); // make sure vanilla levels were parsed - DynOS_Level_GetCount(); + DynOS_Level_Init(); // check for duplicates for (s32 i = 0; i < _CustomLevelScripts.Count(); ++i) { @@ -121,7 +121,7 @@ const char* DynOS_Lvl_GetToken(u32 index) { if (index >= gfxData->mLuaTokenList.Count()) { return NULL; } - + return gfxData->mLuaTokenList[index].begin(); } diff --git a/data/dynos_mgr_models.cpp b/data/dynos_mgr_models.cpp index 64d42393..0901be39 100644 --- a/data/dynos_mgr_models.cpp +++ b/data/dynos_mgr_models.cpp @@ -234,7 +234,3 @@ void DynOS_Model_ClearPool(enum ModelPool aModelPool) { assetMap.clear(); } - -void DynOS_Model_Update() { - -} \ No newline at end of file diff --git a/data/dynos_opt.cpp b/data/dynos_opt.cpp deleted file mode 100644 index a0aab992..00000000 --- a/data/dynos_opt.cpp +++ /dev/null @@ -1,749 +0,0 @@ -#include "dynos.cpp.h" -extern "C" { -#include "pc/configfile.h" -#include "audio/external.h" -#include "game/game_init.h" -#include "pc/controller/controller_keyboard.h" -#ifdef BETTERCAMERA -#include "game/bettercamera.h" -#endif -} - -// -// Data -// - -static DynosOption *sPrevOpt = NULL; -static DynosOption *sDynosMenu = NULL; -static DynosOption *sOptionsMenu = NULL; -static DynosOption *sCurrentMenu = NULL; -static DynosOption *sCurrentOpt = NULL; -extern s32 sBindingState; - -// -// Action list -// - -typedef bool (*DynosActionFunction)(const char *); -struct DynosAction : NoCopy { - String mFuncName; - DynosActionFunction mAction; -}; - -STATIC_STORAGE(Array, DynosActions); -#define sDynosActions __DynosActions() - -static DynosActionFunction DynOS_Opt_GetAction(const String& aFuncName) { - for (auto &_DynosAction : sDynosActions) { - if (_DynosAction->mFuncName == aFuncName) { - return _DynosAction->mAction; - } - } - return NULL; -} - -void DynOS_Opt_AddAction(const String& aFuncName, bool (*aFuncPtr)(const char *), bool aOverwrite) { - for (auto &_DynosAction : sDynosActions) { - if (_DynosAction->mFuncName == aFuncName) { - if (aOverwrite) { - _DynosAction->mAction = aFuncPtr; - } - return; - } - } - DynosAction *_DynosAction = New(); - _DynosAction->mFuncName = aFuncName; - _DynosAction->mAction = aFuncPtr; - sDynosActions.Add(_DynosAction); -} - -// -// Constructors -// - -static DynosOption *DynOS_Opt_GetExistingOption(DynosOption *aOpt, const String &aName) { - while (aOpt) { - if (aOpt->mName == aName) { - return aOpt; - } - if (aOpt->mType == DOPT_SUBMENU) { - DynosOption *_Opt = DynOS_Opt_GetExistingOption(aOpt->mSubMenu.mChild, aName); - if (_Opt) { - return _Opt; - } - } - aOpt = aOpt->mNext; - } - return NULL; -} - -static DynosOption *DynOS_Opt_NewOption(const String &aName, const String &aConfigName, const String &aLabel, const String &aTitle) { - - // Check if the option already exists - static DynosOption sDummyOpt; - if (DynOS_Opt_GetExistingOption(sDynosMenu, aName)) { - return &sDummyOpt; - } - - // Create a new option - DynosOption *_Opt = New(); - _Opt->mName = aName; - _Opt->mConfigName = aConfigName; - _Opt->mLabel = { aLabel, NULL }; - _Opt->mTitle = { aTitle, NULL }; - _Opt->mDynos = true; - if (sPrevOpt == NULL) { // The very first option - _Opt->mPrev = NULL; - _Opt->mNext = NULL; - _Opt->mParent = NULL; - sDynosMenu = _Opt; - } else { - if (sPrevOpt->mType == DOPT_SUBMENU && sPrevOpt->mSubMenu.mEmpty) { // First option of a sub-menu - _Opt->mPrev = NULL; - _Opt->mNext = NULL; - _Opt->mParent = sPrevOpt; - sPrevOpt->mSubMenu.mChild = _Opt; - sPrevOpt->mSubMenu.mEmpty = false; - } else { - _Opt->mPrev = sPrevOpt; - _Opt->mNext = NULL; - _Opt->mParent = sPrevOpt->mParent; - sPrevOpt->mNext = _Opt; - } - } - sPrevOpt = _Opt; - return _Opt; -} - -static void DynOS_Opt_EndSubMenu() { - if (sPrevOpt && sPrevOpt->mParent) { - if (sPrevOpt->mType == DOPT_SUBMENU && sPrevOpt->mSubMenu.mEmpty) { // ENDMENU command following a SUBMENU command - sPrevOpt->mSubMenu.mEmpty = false; - } else { - sPrevOpt = sPrevOpt->mParent; - } - } -} - -static void DynOS_Opt_CreateSubMenu(const String &aName, const String &aLabel, const String &aTitle) { - DynosOption *_Opt = DynOS_Opt_NewOption(aName, "", aLabel, aTitle); - _Opt->mType = DOPT_SUBMENU; - _Opt->mSubMenu.mChild = NULL; - _Opt->mSubMenu.mEmpty = true; -} - -static void DynOS_Opt_CreateToggle(const String &aName, const String &aConfigName, const String &aLabel, s32 aValue) { - DynosOption *_Opt = DynOS_Opt_NewOption(aName, aConfigName, aLabel, aLabel); - _Opt->mType = DOPT_TOGGLE; - _Opt->mToggle.mTog = New(); - *_Opt->mToggle.mTog = (bool) aValue; -} - -static void DynOS_Opt_CreateScroll(const String &aName, const String &aConfigName, const String &aLabel, s32 aMin, s32 aMax, s32 aStep, s32 aValue) { - DynosOption *_Opt = DynOS_Opt_NewOption(aName, aConfigName, aLabel, aLabel); - _Opt->mType = DOPT_SCROLL; - _Opt->mScroll.mMin = aMin; - _Opt->mScroll.mMax = aMax; - _Opt->mScroll.mStep = aStep; - _Opt->mScroll.mValue = New(); - *_Opt->mScroll.mValue = aValue; -} - -static void DynOS_Opt_CreateChoice(const String &aName, const String &aConfigName, const String &aLabel, const Array& aChoices, s32 aValue) { - DynosOption *_Opt = DynOS_Opt_NewOption(aName, aConfigName, aLabel, aLabel); - _Opt->mType = DOPT_CHOICE; - _Opt->mChoice.mIndex = New(); - *_Opt->mChoice.mIndex = aValue; - for (const auto &_Choice : aChoices) { - _Opt->mChoice.mChoices.Add({ _Choice, NULL }); - } -} - -static void DynOS_Opt_CreateButton(const String &aName, const String &aLabel, const String& aFuncName) { - DynosOption *_Opt = DynOS_Opt_NewOption(aName, "", aLabel, aLabel); - _Opt->mType = DOPT_BUTTON; - _Opt->mButton.mFuncName = aFuncName; -} - -static void DynOS_Opt_CreateBind(const String &aName, const String &aConfigName, const String &aLabel, u32 aMask, u32 aBind0, u32 aBind1, u32 aBind2) { - DynosOption *_Opt = DynOS_Opt_NewOption(aName, aConfigName, aLabel, aLabel); - _Opt->mType = DOPT_BIND; - _Opt->mBind.mMask = aMask; - _Opt->mBind.mBinds = New(3); - _Opt->mBind.mBinds[0] = aBind0; - _Opt->mBind.mBinds[1] = aBind1; - _Opt->mBind.mBinds[2] = aBind2; - _Opt->mBind.mIndex = 0; -} - -// -// Loop through DynosOptions -// - -DynosOption *DynOS_Opt_Loop(DynosOption *aOpt, DynosLoopFunc aFunc, void *aData) { - while (aOpt) { - if (aFunc(aOpt, aData)) { - return aOpt; - } else if (aOpt->mType == DOPT_SUBMENU) { - DynosOption *_Opt = DynOS_Opt_Loop(aOpt->mSubMenu.mChild, aFunc, aData); - if (_Opt) { - return _Opt; - } - } - aOpt = aOpt->mNext; - } - return NULL; -} - -// -// Get/Set values -// - -static bool DynOS_Opt_Get(DynosOption *aOpt, void *aData) { - return aOpt->mName == (const char *) aData; -} - -s32 DynOS_Opt_GetValue(const String &aName) { - DynosOption *_Opt = DynOS_Opt_Loop(sDynosMenu, DynOS_Opt_Get, (void *) aName.begin()); - if (_Opt) { - switch (_Opt->mType) { - case DOPT_TOGGLE: return *_Opt->mToggle.mTog; - case DOPT_CHOICE: return *_Opt->mChoice.mIndex; - case DOPT_CHOICELEVEL: return *_Opt->mChoice.mIndex; - case DOPT_CHOICEAREA: return *_Opt->mChoice.mIndex; - case DOPT_CHOICESTAR: return *_Opt->mChoice.mIndex; - case DOPT_CHOICEPARAM: return *_Opt->mChoice.mIndex; - case DOPT_SCROLL: return *_Opt->mScroll.mValue; - default: break; - } - } - return 0; -} - -void DynOS_Opt_SetValue(const String &aName, s32 aValue) { - DynosOption *_Opt = DynOS_Opt_Loop(sDynosMenu, DynOS_Opt_Get, (void *) aName.begin()); - if (_Opt) { - switch (_Opt->mType) { - case DOPT_TOGGLE: *_Opt->mToggle.mTog = aValue; break; - case DOPT_CHOICE: *_Opt->mChoice.mIndex = aValue; break; - case DOPT_CHOICELEVEL: *_Opt->mChoice.mIndex = aValue; break; - case DOPT_CHOICEAREA: *_Opt->mChoice.mIndex = aValue; break; - case DOPT_CHOICESTAR: *_Opt->mChoice.mIndex = aValue; break; - case DOPT_CHOICEPARAM: *_Opt->mChoice.mIndex = aValue; break; - case DOPT_SCROLL: *_Opt->mScroll.mValue = aValue; break; - default: break; - } - } -} - -// -// Processing -// - -#define SOUND_DYNOS_SAVED (SOUND_MENU_MARIO_CASTLE_WARP2 | (0xFF << 8)) -#define SOUND_DYNOS_SELECT (SOUND_MENU_CHANGE_SELECT | (0xF8 << 8)) -#define SOUND_DYNOS_OK (SOUND_MENU_CHANGE_SELECT | (0xF8 << 8)) -#define SOUND_DYNOS_CANCEL (SOUND_MENU_CAMERA_BUZZ | (0xFC << 8)) - -enum { - INPUT_LEFT, - INPUT_RIGHT, - INPUT_A, - INPUT_Z -}; - -enum { - RESULT_NONE, - RESULT_OK, - RESULT_CANCEL -}; - -static s32 DynOS_Opt_ProcessInput(DynosOption *aOpt, s32 input) { - switch (aOpt->mType) { - case DOPT_TOGGLE: - if (input == INPUT_LEFT) { - *aOpt->mToggle.mTog = false; - return RESULT_OK; - } - if (input == INPUT_RIGHT) { - *aOpt->mToggle.mTog = true; - return RESULT_OK; - } - if (input == INPUT_A) { - *aOpt->mToggle.mTog = !(*aOpt->mToggle.mTog); - return RESULT_OK; - } - break; - - case DOPT_CHOICE: - if (input == INPUT_LEFT) { - *aOpt->mChoice.mIndex = (*aOpt->mChoice.mIndex + aOpt->mChoice.mChoices.Count() - 1) % (aOpt->mChoice.mChoices.Count()); - return RESULT_OK; - } - if (input == INPUT_RIGHT || input == INPUT_A) { - *aOpt->mChoice.mIndex = (*aOpt->mChoice.mIndex + 1) % (aOpt->mChoice.mChoices.Count()); - return RESULT_OK; - } - break; - - case DOPT_CHOICELEVEL: - if (input == INPUT_LEFT) { - *aOpt->mChoice.mIndex = (*aOpt->mChoice.mIndex + DynOS_Level_GetCount() - 1) % (DynOS_Level_GetCount()); - return RESULT_OK; - } - if (input == INPUT_RIGHT || input == INPUT_A) { - *aOpt->mChoice.mIndex = (*aOpt->mChoice.mIndex + 1) % (DynOS_Level_GetCount()); - return RESULT_OK; - } - break; - - case DOPT_CHOICEAREA: - if (input == INPUT_LEFT) { - *aOpt->mChoice.mIndex = (*aOpt->mChoice.mIndex + 3) % (4); - return RESULT_OK; - } - if (input == INPUT_RIGHT || input == INPUT_A) { - *aOpt->mChoice.mIndex = (*aOpt->mChoice.mIndex + 1) % (4); - return RESULT_OK; - } - break; - - case DOPT_CHOICESTAR: - if (input == INPUT_LEFT) { - *aOpt->mChoice.mIndex = (*aOpt->mChoice.mIndex + 5) % (6); - return RESULT_OK; - } - if (input == INPUT_RIGHT || input == INPUT_A) { - *aOpt->mChoice.mIndex = (*aOpt->mChoice.mIndex + 1) % (6); - return RESULT_OK; - } - break; - - case DOPT_CHOICEPARAM: - if (input == INPUT_LEFT) { - *aOpt->mChoice.mIndex = (*aOpt->mChoice.mIndex + 4) % (5); - return RESULT_OK; - } - if (input == INPUT_RIGHT || input == INPUT_A) { - *aOpt->mChoice.mIndex = (*aOpt->mChoice.mIndex + 1) % (5); - return RESULT_OK; - } - break; - - case DOPT_SCROLL: - if (input == INPUT_LEFT) { - *aOpt->mScroll.mValue = MAX(aOpt->mScroll.mMin, *aOpt->mScroll.mValue - aOpt->mScroll.mStep * (gPlayer1Controller->buttonDown & A_BUTTON ? 5 : 1)); - return RESULT_OK; - } - if (input == INPUT_RIGHT) { - *aOpt->mScroll.mValue = MIN(aOpt->mScroll.mMax, *aOpt->mScroll.mValue + aOpt->mScroll.mStep * (gPlayer1Controller->buttonDown & A_BUTTON ? 5 : 1)); - return RESULT_OK; - } - break; - - case DOPT_BIND: - if (input == INPUT_LEFT) { - aOpt->mBind.mIndex = MAX(0, aOpt->mBind.mIndex - 1); - return RESULT_OK; - } - if (input == INPUT_RIGHT) { - aOpt->mBind.mIndex = MIN(2, aOpt->mBind.mIndex + 1); - return RESULT_OK; - } - if (input == INPUT_Z) { - aOpt->mBind.mBinds[aOpt->mBind.mIndex] = VK_INVALID; - return RESULT_OK; - } - if (input == INPUT_A) { - aOpt->mBind.mBinds[aOpt->mBind.mIndex] = VK_INVALID; - sBindingState = 1; - controller_get_raw_key(); - return RESULT_OK; - } - break; - - case DOPT_BUTTON: - if (input == INPUT_A) { - DynosActionFunction _Action = DynOS_Opt_GetAction(aOpt->mButton.mFuncName); - if (_Action != NULL && _Action(aOpt->mName.begin())) { - return RESULT_OK; - } - return RESULT_CANCEL; - } - break; - - case DOPT_SUBMENU: - if (input == INPUT_A) { - if (aOpt->mSubMenu.mChild != NULL) { - sCurrentOpt = aOpt->mSubMenu.mChild; - return RESULT_OK; - } - return RESULT_CANCEL; - } - break; - } - return RESULT_NONE; -} - -static void DynOS_Opt_Open(DynosOption *aMenu) { - play_sound(SOUND_DYNOS_SELECT, gGlobalSoundSource); - sCurrentMenu = aMenu; - sCurrentOpt = aMenu; -} - -static void DynOS_Opt_Close(bool aPlaySavedSfx) { - if (sCurrentMenu != NULL) { - if (aPlaySavedSfx) { - play_sound(SOUND_DYNOS_SAVED, gGlobalSoundSource); - } -#ifdef BETTERCAMERA - newcam_init_settings(); -#endif - controller_reconfigure(); - configfile_save(configfile_name()); - DynOS_Opt_SaveConfig(sDynosMenu); - sCurrentMenu = NULL; - } -} - -static void DynOS_Opt_ProcessInputs() { - static s32 sStickTimer = 0; - static bool sPrevStick = 0; - - // Stick values - f32 _StickX = gPlayer1Controller->stickX; - f32 _StickY = gPlayer1Controller->stickY; - if (absx(_StickX) > 60 || absx(_StickY) > 60) { - if (sStickTimer == 0) { - sStickTimer = (sPrevStick ? 2 : 9); - } else { - _StickX = 0; - _StickY = 0; - sStickTimer--; - } - sPrevStick = true; - } else { - sStickTimer = 0; - sPrevStick = false; - } - - // Key binding - if (sBindingState != 0) { - u32 _Key = (sCurrentOpt->mDynos ? (u32) DynOS_Opt_ControllerGetKeyPressed() : controller_get_raw_key()); - if (_Key != VK_INVALID) { - play_sound(SOUND_DYNOS_SELECT, gGlobalSoundSource); - sCurrentOpt->mBind.mBinds[sCurrentOpt->mBind.mIndex] = _Key; - sBindingState = false; - } - return; - } - - if (sCurrentMenu != NULL) { - - // Up - if (_StickY > +60) { - if (sCurrentOpt->mPrev != NULL) { - sCurrentOpt = sCurrentOpt->mPrev; - } else { - while (sCurrentOpt->mNext) sCurrentOpt = sCurrentOpt->mNext; - } - play_sound(SOUND_DYNOS_SELECT, gGlobalSoundSource); - return; - } - - // Down - if (_StickY < -60) { - if (sCurrentOpt->mNext != NULL) { - sCurrentOpt = sCurrentOpt->mNext; - } else { - while (sCurrentOpt->mPrev) sCurrentOpt = sCurrentOpt->mPrev; - } - play_sound(SOUND_DYNOS_SELECT, gGlobalSoundSource); - return; - } - - // Left - if (_StickX < -60) { - switch (DynOS_Opt_ProcessInput(sCurrentOpt, INPUT_LEFT)) { - case RESULT_OK: play_sound(SOUND_DYNOS_OK, gGlobalSoundSource); break; - case RESULT_CANCEL: play_sound(SOUND_DYNOS_CANCEL, gGlobalSoundSource); break; - case RESULT_NONE: break; - } - return; - } - - // Right - if (_StickX > +60) { - switch (DynOS_Opt_ProcessInput(sCurrentOpt, INPUT_RIGHT)) { - case RESULT_OK: play_sound(SOUND_DYNOS_OK, gGlobalSoundSource); break; - case RESULT_CANCEL: play_sound(SOUND_DYNOS_CANCEL, gGlobalSoundSource); break; - case RESULT_NONE: break; - } - return; - } - - // A - if (gPlayer1Controller->buttonPressed & A_BUTTON) { - switch (DynOS_Opt_ProcessInput(sCurrentOpt, INPUT_A)) { - case RESULT_OK: play_sound(SOUND_DYNOS_OK, gGlobalSoundSource); break; - case RESULT_CANCEL: play_sound(SOUND_DYNOS_CANCEL, gGlobalSoundSource); break; - case RESULT_NONE: break; - } - return; - } - - // B - if (gPlayer1Controller->buttonPressed & B_BUTTON) { - if (sCurrentOpt->mParent != NULL) { - sCurrentOpt = sCurrentOpt->mParent; - play_sound(SOUND_DYNOS_SELECT, gGlobalSoundSource); - } else { - DynOS_Opt_Close(true); - } - return; - } - - // Z - if (gPlayer1Controller->buttonPressed & Z_TRIG) { - switch (DynOS_Opt_ProcessInput(sCurrentOpt, INPUT_Z)) { - case RESULT_OK: play_sound(SOUND_DYNOS_OK, gGlobalSoundSource); break; - case RESULT_CANCEL: play_sound(SOUND_DYNOS_CANCEL, gGlobalSoundSource); break; - case RESULT_NONE: - if (sCurrentMenu == sDynosMenu) { - DynOS_Opt_Close(true); - } else { - DynOS_Opt_Open(sDynosMenu); - } break; - } - return; - } - - // R - if (gPlayer1Controller->buttonPressed & R_TRIG) { - if (sCurrentMenu == sOptionsMenu) { - DynOS_Opt_Close(true); - } else { - DynOS_Opt_Open(sOptionsMenu); - } - return; - } - - // Start - if (gPlayer1Controller->buttonPressed & START_BUTTON) { - DynOS_Opt_Close(true); - return; - } - } else if (gPlayer1Controller->buttonPressed & R_TRIG) { - DynOS_Opt_Open(sOptionsMenu); - } else if (gPlayer1Controller->buttonPressed & Z_TRIG) { - DynOS_Opt_Open(sDynosMenu); - } -} - -// -// Init -// - -static void DynOS_Opt_CreateWarpToLevelSubMenu() { - DynOS_Opt_CreateSubMenu("dynos_warp_to_level_submenu", "Warp to Level", "WARP TO LEUEL"); - - // Level select - { - DynosOption *aOpt = DynOS_Opt_NewOption("dynos_warp_level", "", "Level Select", ""); - aOpt->mType = DOPT_CHOICELEVEL; - aOpt->mChoice.mIndex = New(); - *aOpt->mChoice.mIndex = 0; - } - - // Area select - { - DynosOption *aOpt = DynOS_Opt_NewOption("dynos_warp_area", "", "Area Select", ""); - aOpt->mType = DOPT_CHOICEAREA; - aOpt->mChoice.mIndex = New(); - *aOpt->mChoice.mIndex = 0; - } - - // Star select - { - DynosOption *aOpt = DynOS_Opt_NewOption("dynos_warp_act", "", "Star Select", ""); - aOpt->mType = DOPT_CHOICESTAR; - aOpt->mChoice.mIndex = New(); - *aOpt->mChoice.mIndex = 0; - } - - // Param select - { - DynosOption *aOpt = DynOS_Opt_NewOption("dynos_warp_param", "", "Param Select", ""); - aOpt->mType = DOPT_CHOICEPARAM; - aOpt->mChoice.mIndex = New(); - *aOpt->mChoice.mIndex = 0; - } - - DynOS_Opt_CreateButton("dynos_warp_to_level", "Warp", "DynOS_Opt_WarpToLevel"); - DynOS_Opt_EndSubMenu(); -} - -static void DynOS_Opt_CreateWarpToCastleSubMenu() { - DynOS_Opt_CreateSubMenu("dynos_warp_to_castle_submenu", "Warp to Castle", "WARP TO CASTLE"); - - // Level select - { - DynosOption *aOpt = DynOS_Opt_NewOption("dynos_warp_castle", "", "Level Exit", ""); - aOpt->mType = DOPT_CHOICELEVEL; - aOpt->mChoice.mIndex = New(); - *aOpt->mChoice.mIndex = 0; - } - - DynOS_Opt_CreateButton("dynos_warp_to_castle", "Warp", "DynOS_Opt_WarpToCastle"); - DynOS_Opt_EndSubMenu(); -} - -static u32 DynOS_Opt_GetHash(const String& aStr) { - u32 _Hash = 5381u; - for (char c : aStr) { _Hash += c + (_Hash << 5); } - return _Hash; -} - -static void DynOS_Opt_CreateModelPacksSubMenu() { - /*Array _Packs = DynOS_Gfx_Init(); - if (_Packs.Count() == 0) { - return; - } - - DynOS_Opt_CreateSubMenu("dynos_model_loader_submenu", "Model Packs", "MODEL PACKS"); - for (s32 i = 0; i != _Packs.Count(); ++i) { - DynOS_Opt_CreateToggle(String("dynos_pack_%d", i), String("dynos_pack_%08X", DynOS_Opt_GetHash(_Packs[i])), _Packs[i], false); - } - DynOS_Opt_CreateButton("dynos_packs_disable_all", "Disable all packs", "DynOS_Opt_DisableAllPacks"); - DynOS_Opt_EndSubMenu();*/ -} - -void DynOS_Opt_Init() { - -#ifdef COOP -#else - // Convert options menu - DynOS_Opt_InitVanilla(sOptionsMenu); - - // Warp to level - DynOS_Opt_CreateWarpToLevelSubMenu(); - - // Warp to castle - DynOS_Opt_CreateWarpToCastleSubMenu(); - - // Restart level - DynOS_Opt_CreateButton("dynos_restart_level", "Restart Level", "DynOS_Opt_RestartLevel"); - - // Exit level - DynOS_Opt_CreateButton("dynos_exit_level", "Exit Level", "DynOS_Opt_ExitLevel"); - - // Return to main menu - DynOS_Opt_CreateButton("dynos_return_to_main_menu", "Return to Main Menu", "DynOS_Opt_ReturnToMainMenu"); - - // Model loader - DynOS_Opt_CreateModelPacksSubMenu(); - - // Init config - DynOS_Opt_LoadConfig(sDynosMenu); -#endif -} - -// -// Update -// - -void DynOS_Opt_Update(OSContPad *aPad) { - DynOS_Opt_Loop(sDynosMenu, DynOS_Opt_ControllerUpdate, (void *) aPad); -#ifndef COOP - if (DynOS_IsTransitionActive()) { - aPad->button = 0; - aPad->stick_x = 0; - aPad->stick_y = 0; - aPad->ext_stick_x = 0; - aPad->ext_stick_y = 0; - } -#endif -} - -// -// Hijack -// This is C code -// - -extern "C" { - -u8 optmenu_open = 0; - -void optmenu_toggle(void) { - DynOS_Opt_Close(false); - optmenu_open = 0; -} - -void optmenu_draw(void) { - DynOS_Opt_DrawMenu(sCurrentOpt, sCurrentMenu, sOptionsMenu, sDynosMenu); -} - -void optmenu_draw_prompt(void) { - DynOS_Opt_DrawPrompt(sCurrentMenu, sOptionsMenu, sDynosMenu); - DynOS_Opt_ProcessInputs(); - optmenu_open = (sCurrentMenu != NULL); -} - -void optmenu_check_buttons(void) { -} - -} - -// -// Built-in options -// - -#define DYNOS_DEFINE_ACTION(func) \ -DYNOS_AT_STARTUP static void DynOS_Opt_AddAction_##func() { \ - DynOS_Opt_AddAction(#func, func, false); \ -} - -#ifndef COOP - -static bool DynOS_Opt_ReturnToMainMenu(UNUSED const char *optName) { - DynOS_ReturnToMainMenu(); - return true; -} -DYNOS_DEFINE_ACTION(DynOS_Opt_ReturnToMainMenu); - -static bool DynOS_Opt_WarpToLevel(UNUSED const char *optName) { - s32 _Level = DynOS_Level_GetList()[DynOS_Opt_GetValue("dynos_warp_level")]; - s32 _Area = DynOS_Opt_GetValue("dynos_warp_area") + 1; - s32 _Act = DynOS_Opt_GetValue("dynos_warp_act") + 1; - return DynOS_Warp_ToLevel(_Level, _Area, _Act); -} -DYNOS_DEFINE_ACTION(DynOS_Opt_WarpToLevel); - -static bool DynOS_Opt_WarpToCastle(UNUSED const char *optName) { - s32 _Level = DynOS_Level_GetList()[DynOS_Opt_GetValue("dynos_warp_castle")]; - return DynOS_Warp_ToCastle(_Level); -} -DYNOS_DEFINE_ACTION(DynOS_Opt_WarpToCastle); - -static bool DynOS_Opt_RestartLevel(UNUSED const char *optName) { - return DynOS_Warp_RestartLevel(); -} -DYNOS_DEFINE_ACTION(DynOS_Opt_RestartLevel); - -static bool DynOS_Opt_ExitLevel(UNUSED const char *optName) { - return DynOS_Warp_ExitLevel(30); -} -DYNOS_DEFINE_ACTION(DynOS_Opt_ExitLevel); - -static bool DynOS_Opt_DisableAllPacks(UNUSED const char *optName) { - const Array &pDynosPacks = DynOS_Gfx_GetPacks(); - for (s32 i = 0; i != pDynosPacks.Count(); ++i) { - DynOS_Opt_SetValue(String("dynos_pack_%d", i), false); - } - return true; -} -DYNOS_DEFINE_ACTION(DynOS_Opt_DisableAllPacks); - -#endif - -#undef DYNOS_DEFINE_ACTION diff --git a/data/dynos_opt_config.cpp b/data/dynos_opt_config.cpp deleted file mode 100644 index c6d48a2a..00000000 --- a/data/dynos_opt_config.cpp +++ /dev/null @@ -1,67 +0,0 @@ -#include "dynos.cpp.h" - -extern DynosOption *DynOS_Opt_Loop(DynosOption *aOpt, DynosLoopFunc aFunc, void *aData); - -static bool DynOS_Opt_ReadConfig(DynosOption *aOpt, void *aData) { - return (aOpt->mConfigName == (const char *) aData); -} - -void DynOS_Opt_LoadConfig(DynosOption *aMenu) { - SysPath _Filename = fstring("%s/%s", DYNOS_USER_FOLDER, DYNOS_CONFIG_FILENAME); - FILE *_File = fopen(_Filename.c_str(), "r"); - if (_File) { - char _Buffer[1024]; - while (fgets(_Buffer, 1024, _File)) { - - // Option strings - char *_NameBegin = _Buffer; - char *_DataBegin = strchr(_NameBegin, '='); - if (_NameBegin && _DataBegin) { - *(_DataBegin++) = 0; - - // Option name - String _OptName = String(_NameBegin); - DynosOption *_Opt = DynOS_Opt_Loop(aMenu, DynOS_Opt_ReadConfig, (void *) _OptName.begin()); - if (_Opt) { - - // Option values - switch (_Opt->mType) { - case DOPT_TOGGLE: { - unsigned char boolValue = 0; - sscanf(_DataBegin, "%hhu\n", &boolValue); - _Opt->mToggle.mTog[0] = boolValue; - break; - } - case DOPT_CHOICE: sscanf(_DataBegin, "%d\n", &_Opt->mChoice.mIndex[0]); break; - case DOPT_SCROLL: sscanf(_DataBegin, "%d\n", &_Opt->mScroll.mValue[0]); break; - case DOPT_BIND: sscanf(_DataBegin, "%04X;%04X;%04X\n", &_Opt->mBind.mBinds[0], &_Opt->mBind.mBinds[1], &_Opt->mBind.mBinds[2]); break; - } - } - } - } - fclose(_File); - } -} - -static bool DynOS_Opt_WriteConfig(DynosOption *aOpt, void *aData) { - if (aOpt->mConfigName.Length() != 0 && - aOpt->mConfigName != "null" && - aOpt->mConfigName != "NULL") { - switch (aOpt->mType) { - case DOPT_TOGGLE: fprintf((FILE *) aData, "%s=%hhu\n", aOpt->mConfigName.begin(), aOpt->mToggle.mTog[0]); break; - case DOPT_CHOICE: fprintf((FILE *) aData, "%s=%d\n", aOpt->mConfigName.begin(), aOpt->mChoice.mIndex[0]); break; - case DOPT_SCROLL: fprintf((FILE *) aData, "%s=%d\n", aOpt->mConfigName.begin(), aOpt->mScroll.mValue[0]); break; - case DOPT_BIND: fprintf((FILE *) aData, "%s=%04X;%04X;%04X\n", aOpt->mConfigName.begin(), aOpt->mBind.mBinds[0], aOpt->mBind.mBinds[1], aOpt->mBind.mBinds[2]); break; - } - } - return false; -} - -void DynOS_Opt_SaveConfig(DynosOption *aMenu) { - SysPath _Filename = fstring("%s/%s", DYNOS_USER_FOLDER, DYNOS_CONFIG_FILENAME); - FILE *_File = fopen(_Filename.c_str(), "w"); - if (_File) { - DynOS_Opt_Loop(aMenu, DynOS_Opt_WriteConfig, (void *) _File); - fclose(_File); - } -} diff --git a/data/dynos_opt_cont.cpp b/data/dynos_opt_cont.cpp deleted file mode 100644 index e50dd977..00000000 --- a/data/dynos_opt_cont.cpp +++ /dev/null @@ -1,75 +0,0 @@ -#include "dynos.cpp.h" -extern "C" { -#include "pc/controller/controller_api.h" -} - -static bool DynOS_Opt_ControllerIsKeyDown(s32 aCont, s32 aKey) { -#ifdef HAVE_SDL2 - // Keyboard - if (aCont == 0 && aKey >= 0 && aKey < SDL_NUM_SCANCODES) { - return SDL_GetKeyboardState(NULL)[aKey]; - } - - // Game Controller - else if (aKey >= 0x1000) { - - // Button - s32 _Button = (aKey - 0x1000); - if (_Button < SDL_CONTROLLER_BUTTON_MAX) { - return SDL_GameControllerGetButton(SDL_GameControllerOpen(aCont - 1), SDL_GameControllerButton(_Button)); - } - - // Axis - s32 _Axis = (aKey - 0x1000 - SDL_CONTROLLER_BUTTON_MAX); - if (_Axis < SDL_CONTROLLER_AXIS_MAX * 2) { - s32 _AxisValue = SDL_GameControllerGetAxis(SDL_GameControllerOpen(aCont - 1), SDL_GameControllerAxis(_Axis / 2)); - if (_Axis & 1) return (_AxisValue < (SHRT_MIN / 2)); - else return (_AxisValue > (SHRT_MAX / 2)); - } - } - // Invalid -#endif - return false; -} - -#define MAX_CONTS 8 -bool DynOS_Opt_ControllerUpdate(DynosOption *aOpt, void *aData) { -#ifdef HAVE_SDL2 - if (aOpt->mType == DOPT_BIND) { - OSContPad *pad = (OSContPad *) aData; - for (s32 _Cont = 0; _Cont < MAX_CONTS; ++_Cont) - for (s32 _Bind = 0; _Bind < 3; ++_Bind) { - pad->button |= aOpt->mBind.mMask * DynOS_Opt_ControllerIsKeyDown(_Cont, aOpt->mBind.mBinds[_Bind]); - } - } -#endif - return false; -} - -#define MAX_GKEYS (SDL_CONTROLLER_BUTTON_MAX + SDL_CONTROLLER_AXIS_MAX * 2) -s32 sBindingState = 0; // 0 = No bind, 1 = Wait for all keys released, 2 = Return first pressed key -s32 DynOS_Opt_ControllerGetKeyPressed() { -#ifdef HAVE_SDL2 - - // Keyboard - for (s32 _Key = 0; _Key < SDL_NUM_SCANCODES; ++_Key) { - if (DynOS_Opt_ControllerIsKeyDown(0, _Key)) { - if (sBindingState == 1) return VK_INVALID; - return _Key; - } - } - - // Game Controller - for (s32 _Cont = 1; _Cont < MAX_CONTS; ++_Cont) - for (s32 _Key = 0; _Key < MAX_GKEYS; ++_Key) { - if (DynOS_Opt_ControllerIsKeyDown(_Cont, _Key + 0x1000)) { - if (sBindingState == 1) return VK_INVALID; - return _Key + 0x1000; - } - } - - // No key - sBindingState = 2; -#endif - return VK_INVALID; -} diff --git a/data/dynos_opt_render.cpp b/data/dynos_opt_render.cpp deleted file mode 100644 index d644a51a..00000000 --- a/data/dynos_opt_render.cpp +++ /dev/null @@ -1,309 +0,0 @@ -#include "dynos.cpp.h" -extern "C" { -#include "course_table.h" -#include "game/game_init.h" -#include "game/ingame_menu.h" -#include "game/segment2.h" -#include "pc/controller/controller_api.h" -#include "gfx_dimensions.h" -} - -extern s32 sBindingState; - -#define DYNOS_TEXT_DYNOS_MENU { "DYNOS MENU", NULL } -#define DYNOS_TEXT_A { "([A]) >", NULL } -#define DYNOS_TEXT_OPEN_LEFT { "[Z] DynOS", NULL } -#define DYNOS_TEXT_CLOSE_LEFT { "[Z] Return", NULL } -#define DYNOS_TEXT_OPTIONS_MENU { "OPTIONS", NULL } -#define DYNOS_TEXT_DISABLED { "Disabled", NULL } -#define DYNOS_TEXT_ENABLED { "Enabled", NULL } -#define DYNOS_TEXT_NONE { "NONE", NULL } -#define DYNOS_TEXT_DOT_DOT_DOT { "...", NULL } -#define DYNOS_TEXT_OPEN_RIGHT { "[R] Options", NULL } -#define DYNOS_TEXT_CLOSE_RIGHT { "[R] Return", NULL } - -static void RenderString(const u8 *aStr64, s32 aX, s32 aY) { - create_dl_translation_matrix(MENU_MTX_PUSH, aX, aY, 0); - for (; *aStr64 != DIALOG_CHAR_TERMINATOR; ++aStr64) { - if (*aStr64 != DIALOG_CHAR_SPACE) { - void **fontLUT = (void **) segmented_to_virtual(main_font_lut); - void *packedTexture = segmented_to_virtual(fontLUT[*aStr64]); - gDPPipeSync(gDisplayListHead++); - gDPSetTextureImage(gDisplayListHead++, G_IM_FMT_IA, G_IM_SIZ_16b, 1, VIRTUAL_TO_PHYSICAL(packedTexture)); - gSPDisplayList(gDisplayListHead++, dl_ia_text_tex_settings); - } - create_dl_translation_matrix(MENU_MTX_NOPUSH, DynOS_String_WidthChar64(*aStr64), 0, 0); - } - gSPPopMatrix(gDisplayListHead++, G_MTX_MODELVIEW); -} - -static void PrintString(const Label& aLabel, s32 aX, s32 aY, u32 aFrontColorRGBA, u32 aBackColorRGBA, bool aAlignLeft) { - const u8 *_Str64 = (aLabel.second ? aLabel.second : DynOS_String_Convert(aLabel.first.begin(), false)); - - gSPDisplayList(gDisplayListHead++, dl_ia_text_begin); - if ((aBackColorRGBA & 0xFF) != 0) { - gDPSetEnvColor(gDisplayListHead++, ((aBackColorRGBA >> 24) & 0xFF), ((aBackColorRGBA >> 16) & 0xFF), ((aBackColorRGBA >> 8) & 0xFF), ((aBackColorRGBA >> 0) & 0xFF)); - if (aAlignLeft) { - RenderString(_Str64, GFX_DIMENSIONS_FROM_LEFT_EDGE(aX) + 1, aY - 1); - } else { - RenderString(_Str64, GFX_DIMENSIONS_FROM_RIGHT_EDGE(aX + DynOS_String_Width(_Str64) - 1), aY - 1); - } - } - if ((aFrontColorRGBA & 0xFF) != 0) { - gDPSetEnvColor(gDisplayListHead++, ((aFrontColorRGBA >> 24) & 0xFF), ((aFrontColorRGBA >> 16) & 0xFF), ((aFrontColorRGBA >> 8) & 0xFF), ((aFrontColorRGBA >> 0) & 0xFF)); - if (aAlignLeft) { - RenderString(_Str64, GFX_DIMENSIONS_FROM_LEFT_EDGE(aX), aY); - } else { - RenderString(_Str64, GFX_DIMENSIONS_FROM_RIGHT_EDGE(aX + DynOS_String_Width(_Str64)), aY); - } - } - gSPDisplayList(gDisplayListHead++, dl_ia_text_end); - gDPSetEnvColor(gDisplayListHead++, 255, 255, 255, 255); -} - -static void PrintBox(s32 aX, s32 aY, s32 aWidth, s32 aHeight, u32 aColorRGBA, bool aAlignLeft) { - if ((aColorRGBA & 0xFF) != 0) { - Mtx *_Matrix = (Mtx *) alloc_display_list(sizeof(Mtx)); - if (!_Matrix) return; - if (aAlignLeft) { - create_dl_translation_matrix(MENU_MTX_PUSH, GFX_DIMENSIONS_FROM_LEFT_EDGE(aX), aY + aHeight, 0); - } else { - create_dl_translation_matrix(MENU_MTX_PUSH, GFX_DIMENSIONS_FROM_RIGHT_EDGE(aX + aWidth), aY + aHeight, 0); - } - guScale(_Matrix, (f32) aWidth / 130.f, (f32) aHeight / 80.f, 1.f); - gSPMatrix(gDisplayListHead++, VIRTUAL_TO_PHYSICAL(_Matrix), G_MTX_MODELVIEW | G_MTX_MUL | G_MTX_NOPUSH); - gDPSetEnvColor(gDisplayListHead++, ((aColorRGBA >> 24) & 0xFF), ((aColorRGBA >> 16) & 0xFF), ((aColorRGBA >> 8) & 0xFF), ((aColorRGBA >> 0) & 0xFF)); - gSPDisplayList(gDisplayListHead++, dl_draw_text_bg_box); - gSPPopMatrix(gDisplayListHead++, G_MTX_MODELVIEW); - gDPSetEnvColor(gDisplayListHead++, 255, 255, 255, 255); - } -} - -static const char *IntToString(const char *fmt, s32 x) { - static char sBuffer[16]; - snprintf(sBuffer, 16, fmt, x); - return sBuffer; -} - -#define get_label(opt) (opt->mLabel) -#define get_title(opt) (opt->mTitle) -#define get_choice(opt) (opt->mChoice.mChoices[*opt->mChoice.mIndex]) -#define get_dec_number(n) { "", DynOS_String_Convert(IntToString("%d", n), false) } -#define get_hex_number(n) { "", DynOS_String_Convert(IntToString("%04X", n), false) } -#define get_level(opt) { "", DynOS_Level_GetName(DynOS_Level_GetList()[*opt->mChoice.mIndex], true, true) } -#define get_star(opt) { "", DynOS_Level_GetActName(DynOS_Level_GetList()[DynOS_Opt_GetValue("dynos_warp_level")], *opt->mChoice.mIndex + 1, true, true) } -#define get_param(opt) { DynOS_Warp_GetParamName(DynOS_Level_GetList()[DynOS_Opt_GetValue("dynos_warp_level")], *opt->mChoice.mIndex), NULL } - -static s32 GetCurrentOptionCount(DynosOption *aCurrentOpt) { - s32 _Count = 0; - while (aCurrentOpt->mPrev) { aCurrentOpt = aCurrentOpt->mPrev; } - while (aCurrentOpt) { aCurrentOpt = aCurrentOpt->mNext; _Count++; } - return _Count; -} - -static s32 GetCurrentOptionIndex(DynosOption *aCurrentOpt) { - s32 _Index = 0; - while (aCurrentOpt->mPrev) { aCurrentOpt = aCurrentOpt->mPrev; _Index++; } - return _Index; -} - -#define PREV(opt) (opt == NULL ? NULL : opt->mPrev) -#define NEXT(opt) (opt == NULL ? NULL : opt->mNext) -static DynosOption **GetCurrentOptions(DynosOption *aCurrentOpt) { - static DynosOption *sOptionList[13]; - - sOptionList[6] = aCurrentOpt; - sOptionList[5] = PREV(sOptionList[6]); - sOptionList[4] = PREV(sOptionList[5]); - sOptionList[3] = PREV(sOptionList[4]); - sOptionList[2] = PREV(sOptionList[3]); - sOptionList[1] = PREV(sOptionList[2]); - sOptionList[0] = PREV(sOptionList[1]); - sOptionList[7] = NEXT(sOptionList[6]); - sOptionList[8] = NEXT(sOptionList[7]); - sOptionList[9] = NEXT(sOptionList[8]); - sOptionList[10] = NEXT(sOptionList[9]); - sOptionList[11] = NEXT(sOptionList[10]); - sOptionList[12] = NEXT(sOptionList[11]); - - s32 _StartIndex = 12, _EndIndex = 0; - for (s32 i = 0; i != 13; ++i) { - if (sOptionList[i] != NULL) { - _StartIndex = MIN(_StartIndex, i); - _EndIndex = MAX(_EndIndex, i); - } - } - - if (_EndIndex - _StartIndex < 7) { - return &sOptionList[_StartIndex]; - } - if (_EndIndex <= 9) { - return &sOptionList[_EndIndex - 6]; - } - if (_StartIndex >= 3) { - return &sOptionList[_StartIndex]; - } - return &sOptionList[3]; -} -#undef PREV -#undef NEXT - -#define COLOR_WHITE 0xFFFFFFFF -#define COLOR_BLACK 0x000000FF -#define COLOR_GRAY 0xA0A0A0FF -#define COLOR_DARK_GRAY 0x808080FF -#define COLOR_SELECT 0x80E0FFFF -#define COLOR_SELECT_BOX 0x00FFFF20 -#define COLOR_ENABLED 0x20E020FF -#define COLOR_DISABLED 0xFF2020FF -#define OFFSET_FROM_LEFT_EDGE (20.f * sqr(GFX_DIMENSIONS_ASPECT_RATIO)) -#define OFFSET_FROM_RIGHT_EDGE (20.f * sqr(GFX_DIMENSIONS_ASPECT_RATIO)) -#define SCROLL_BAR_SIZE ((s32) (45.f * GFX_DIMENSIONS_ASPECT_RATIO)) - -static void DynOS_Opt_DrawOption(DynosOption *aOpt, DynosOption *aCurrentOpt, s32 aY) { - if (aOpt == NULL) { - return; - } - - // Selected box - if (aOpt == aCurrentOpt) { - u8 _Alpha = (u8) ((coss(gGlobalTimer * 0x800) + 1.f) * 0x20); - PrintBox(OFFSET_FROM_LEFT_EDGE - 4, aY - 2, GFX_DIMENSIONS_FROM_RIGHT_EDGE(OFFSET_FROM_RIGHT_EDGE) - GFX_DIMENSIONS_FROM_LEFT_EDGE(OFFSET_FROM_LEFT_EDGE) + 8, 20, COLOR_SELECT_BOX + _Alpha, 1); - } - - // Label - if (aOpt == aCurrentOpt) { - PrintString(get_label(aOpt), OFFSET_FROM_LEFT_EDGE, aY, COLOR_SELECT, COLOR_BLACK, 1); - } else { - PrintString(get_label(aOpt), OFFSET_FROM_LEFT_EDGE, aY, COLOR_WHITE, COLOR_BLACK, 1); - } - - // Values - switch (aOpt->mType) { - case DOPT_TOGGLE: { - if (*aOpt->mToggle.mTog) { - PrintString(DYNOS_TEXT_ENABLED, OFFSET_FROM_RIGHT_EDGE, aY, COLOR_ENABLED, COLOR_BLACK, 0); - } else { - PrintString(DYNOS_TEXT_DISABLED, OFFSET_FROM_RIGHT_EDGE, aY, COLOR_DISABLED, COLOR_BLACK, 0); - } - } break; - - case DOPT_CHOICE: { - PrintString(get_choice(aOpt), OFFSET_FROM_RIGHT_EDGE, aY, aOpt == aCurrentOpt ? COLOR_SELECT : COLOR_WHITE, COLOR_BLACK, 0); - } break; - - case DOPT_CHOICELEVEL: { - PrintString(get_level(aOpt), OFFSET_FROM_RIGHT_EDGE, aY, aOpt == aCurrentOpt ? COLOR_SELECT : COLOR_WHITE, COLOR_BLACK, 0); - } break; - - case DOPT_CHOICEAREA: { - s32 _Level = DynOS_Level_GetList()[DynOS_Opt_GetValue("dynos_warp_level")]; - s32 _Area = *aOpt->mChoice.mIndex + 1; - const u8 *_Name = DynOS_Level_GetAreaName(_Level, _Area, true); - if (DynOS_Level_GetWarpEntry(_Level, _Area)) { - PrintString({ "", _Name }, OFFSET_FROM_RIGHT_EDGE, aY, aOpt == aCurrentOpt ? COLOR_SELECT : COLOR_WHITE, COLOR_BLACK, 0); - } else { - PrintString({ "", _Name }, OFFSET_FROM_RIGHT_EDGE, aY, COLOR_GRAY, COLOR_BLACK, 0); - } - } break; - - case DOPT_CHOICESTAR: { - s32 _Course = DynOS_Level_GetCourse(DynOS_Level_GetList()[DynOS_Opt_GetValue("dynos_warp_level")]); - if (_Course >= COURSE_MIN && _Course <= COURSE_STAGES_MAX) { - PrintString(get_star(aOpt), OFFSET_FROM_RIGHT_EDGE, aY, aOpt == aCurrentOpt ? COLOR_SELECT : COLOR_WHITE, COLOR_BLACK, 0); - } - } break; - - case DOPT_CHOICEPARAM: { - PrintString(get_param(aOpt), OFFSET_FROM_RIGHT_EDGE, aY, aOpt == aCurrentOpt ? COLOR_SELECT : COLOR_WHITE, COLOR_BLACK, 0); - } break; - - case DOPT_SCROLL: { - s32 _Width = (s32) (SCROLL_BAR_SIZE * (f32) (*aOpt->mScroll.mValue - aOpt->mScroll.mMin) / (f32) (aOpt->mScroll.mMax - aOpt->mScroll.mMin)); - PrintString(get_dec_number(*aOpt->mScroll.mValue), OFFSET_FROM_RIGHT_EDGE, aY, aOpt == aCurrentOpt ? COLOR_SELECT : COLOR_WHITE, COLOR_BLACK, 0); - PrintBox(OFFSET_FROM_RIGHT_EDGE + 28, aY + 4, SCROLL_BAR_SIZE + 2, 8, COLOR_DARK_GRAY, 0); - PrintBox(OFFSET_FROM_RIGHT_EDGE + 29 + SCROLL_BAR_SIZE - _Width, aY + 5, _Width, 6, aOpt == aCurrentOpt ? COLOR_SELECT : COLOR_WHITE, 0); - } break; - - case DOPT_BIND: { - for (s32 i = 0; i != 3; ++i) { - u32 _Bind = aOpt->mBind.mBinds[i]; - if (aOpt == aCurrentOpt && i == aOpt->mBind.mIndex) { - if (sBindingState != 0) { - PrintString(DYNOS_TEXT_DOT_DOT_DOT, OFFSET_FROM_RIGHT_EDGE + (2 - i) * 36, aY, COLOR_SELECT, COLOR_BLACK, 0); - } else if (_Bind == VK_INVALID) { - PrintString(DYNOS_TEXT_NONE, OFFSET_FROM_RIGHT_EDGE + (2 - i) * 36, aY, COLOR_SELECT, COLOR_BLACK, 0); - } else { - PrintString(get_hex_number(_Bind), OFFSET_FROM_RIGHT_EDGE + (2 - i) * 36, aY, COLOR_SELECT, COLOR_BLACK, 0); - } - } else { - if (_Bind == VK_INVALID) { - PrintString(DYNOS_TEXT_NONE, OFFSET_FROM_RIGHT_EDGE + (2 - i) * 36, aY, COLOR_GRAY, COLOR_BLACK, 0); - } else { - PrintString(get_hex_number(_Bind), OFFSET_FROM_RIGHT_EDGE + (2 - i) * 36, aY, COLOR_WHITE, COLOR_BLACK, 0); - } - } - } - } break; - - case DOPT_BUTTON: { - } break; - - case DOPT_SUBMENU: { - if (aOpt == aCurrentOpt) { - PrintString(DYNOS_TEXT_A, OFFSET_FROM_RIGHT_EDGE, aY, COLOR_SELECT, COLOR_BLACK, 0); - } - } break; - } -} - -void DynOS_Opt_DrawMenu(DynosOption *aCurrentOption, DynosOption *aCurrentMenu, DynosOption *aOptionsMenu, DynosOption *aDynosMenu) { - if (aCurrentMenu == NULL) { - return; - } - - // Colorful label - Label _Title; - if (aCurrentOption->mParent) { - _Title = get_title(aCurrentOption->mParent); - } else if (aCurrentMenu == aDynosMenu) { - _Title = DYNOS_TEXT_DYNOS_MENU; - } else if (aCurrentMenu == aOptionsMenu) { - _Title = DYNOS_TEXT_OPTIONS_MENU; - } - gSPDisplayList(gDisplayListHead++, dl_rgba16_text_begin); - gDPSetEnvColor(gDisplayListHead++, 255, 255, 255, 255); - if (!_Title.second) _Title.second = DynOS_String_Convert(_Title.first.begin(), false); - print_hud_lut_string(HUD_LUT_GLOBAL, (SCREEN_WIDTH / 2 - DynOS_String_Length(_Title.second) * 6), 40, _Title.second); - gSPDisplayList(gDisplayListHead++, dl_rgba16_text_end); - - // Display options - DynosOption **_Options = GetCurrentOptions(aCurrentOption); - for (s32 i = 0; i != 7; ++i) { - DynOS_Opt_DrawOption(_Options[i], aCurrentOption, 156 - 20 * i); - } - - // Scroll bar - s32 _OptCount = GetCurrentOptionCount(aCurrentOption); - s32 _OptIndex = GetCurrentOptionIndex(aCurrentOption); - if (_OptCount > 7) { - s32 _Height = (s32) (134.f * sqrtf(1.f / (_OptCount - 6))); - s32 _Y = 37 + (134 - _Height) * (1.f - MAX(0.f, MIN(1.f, (f32)(_OptIndex - 3) / (f32)(_OptCount - 6)))); - PrintBox(OFFSET_FROM_RIGHT_EDGE - 16, 36, 8, 136, COLOR_DARK_GRAY, 0); - PrintBox(OFFSET_FROM_RIGHT_EDGE - 15, _Y, 6, _Height, COLOR_WHITE, 0); - } -} - -#define PROMPT_OFFSET (56.25f * GFX_DIMENSIONS_ASPECT_RATIO) -void DynOS_Opt_DrawPrompt(DynosOption *aCurrentMenu, DynosOption *aOptionsMenu, DynosOption *aDynosMenu) { - if (aCurrentMenu == aOptionsMenu) { - PrintString(DYNOS_TEXT_OPEN_LEFT, PROMPT_OFFSET, 212, COLOR_WHITE, COLOR_BLACK, 1); - PrintString(DYNOS_TEXT_CLOSE_RIGHT, PROMPT_OFFSET, 212, COLOR_WHITE, COLOR_BLACK, 0); - } else if (aCurrentMenu == aDynosMenu) { - PrintString(DYNOS_TEXT_CLOSE_LEFT, PROMPT_OFFSET, 212, COLOR_WHITE, COLOR_BLACK, 1); - PrintString(DYNOS_TEXT_OPEN_RIGHT, PROMPT_OFFSET, 212, COLOR_WHITE, COLOR_BLACK, 0); - } else { - PrintString(DYNOS_TEXT_OPEN_LEFT, PROMPT_OFFSET, 212, COLOR_WHITE, COLOR_BLACK, 1); - PrintString(DYNOS_TEXT_OPEN_RIGHT, PROMPT_OFFSET, 212, COLOR_WHITE, COLOR_BLACK, 0); - } -} diff --git a/data/dynos_opt_vanilla.cpp b/data/dynos_opt_vanilla.cpp deleted file mode 100644 index 2e17c136..00000000 --- a/data/dynos_opt_vanilla.cpp +++ /dev/null @@ -1,159 +0,0 @@ -#include "dynos.cpp.h" - -static DynosOption *sPrevOpt = NULL; -static DynosOption *sOptionsMenu = NULL; - -// -// Vanilla actions -// - -typedef void (*VanillaActionFunction)(struct Option *, s32); -typedef struct VanillaAction { - String mFuncName; - VanillaActionFunction mAction; -} VanillaAction; - -STATIC_STORAGE(Array, VanillaActions); -#define sVanillaActions __VanillaActions() - -static VanillaActionFunction DynOS_Opt_GetVanillaAction(const String& aFuncName) { - for (auto &_DynosAction : sVanillaActions) { - if (_DynosAction->mFuncName == aFuncName) { - return _DynosAction->mAction; - } - } - return NULL; -} - -static void DynOS_Opt_AddVanillaAction(const String& aFuncName, void (*aFuncPtr)(struct Option *, s32)) { - for (auto &_DynosAction : sVanillaActions) { - if (_DynosAction->mFuncName == aFuncName) { - return; - } - } - VanillaAction *_DynosAction = New(); - _DynosAction->mFuncName = aFuncName; - _DynosAction->mAction = aFuncPtr; - sVanillaActions.Add(_DynosAction); -} - -static bool DynOS_Opt_CallVanillaAction(const char *aOptName) { - VanillaActionFunction _Func = DynOS_Opt_GetVanillaAction(aOptName); - if (_Func) { - _Func(NULL, 0); - return true; - } - return false; -} - -// -// Convert classic options menu into DynOS menu -// - -static DynosOption *DynOS_Opt_ConvertOption(const u8 *aLabel, const u8 *aTitle) { - static u32 sOptIdx = 0; - DynosOption *_Opt = New(); - _Opt->mName = String("vanilla_opt_%08X", sOptIdx++); - _Opt->mConfigName = ""; - _Opt->mLabel = { "", aLabel }; - _Opt->mTitle = { "", aTitle }; - _Opt->mDynos = false; - if (sPrevOpt == NULL) { // The very first option - _Opt->mPrev = NULL; - _Opt->mNext = NULL; - _Opt->mParent = NULL; - sOptionsMenu = _Opt; - } else { - if (sPrevOpt->mType == DOPT_SUBMENU && sPrevOpt->mSubMenu.mEmpty) { // First option of a sub-menu - _Opt->mPrev = NULL; - _Opt->mNext = NULL; - _Opt->mParent = sPrevOpt; - sPrevOpt->mSubMenu.mChild = _Opt; - sPrevOpt->mSubMenu.mEmpty = false; - } else { - _Opt->mPrev = sPrevOpt; - _Opt->mNext = NULL; - _Opt->mParent = sPrevOpt->mParent; - sPrevOpt->mNext = _Opt; - } - } - sPrevOpt = _Opt; - return _Opt; -} - -static void DynOS_Opt_EndSubMenu() { - if (sPrevOpt) { - if (sPrevOpt->mType == DOPT_SUBMENU && sPrevOpt->mSubMenu.mEmpty) { // ENDMENU command following a SUBMENU command - sPrevOpt->mSubMenu.mEmpty = false; - } else { - sPrevOpt = sPrevOpt->mParent; - } - } -} - -static void DynOS_Opt_ConvertSubMenu(const u8 *aLabel, const u8 *aTitle) { - DynosOption *_Opt = DynOS_Opt_ConvertOption(aLabel, aTitle); - _Opt->mType = DOPT_SUBMENU; - _Opt->mSubMenu.mChild = NULL; - _Opt->mSubMenu.mEmpty = true; -} - -static void DynOS_Opt_ConvertToggle(const u8 *aLabel, bool *pValue) { - DynosOption *_Opt = DynOS_Opt_ConvertOption(aLabel, aLabel); - _Opt->mType = DOPT_TOGGLE; - _Opt->mToggle.mTog = (bool *) pValue; -} - -static void DynOS_Opt_ConvertScroll(const u8 *aLabel, s32 aMin, s32 aMax, s32 aStep, u32 *pValue) { - DynosOption *_Opt = DynOS_Opt_ConvertOption(aLabel, aLabel); - _Opt->mType = DOPT_SCROLL; - _Opt->mScroll.mMin = aMin; - _Opt->mScroll.mMax = aMax; - _Opt->mScroll.mStep = aStep; - _Opt->mScroll.mValue = (s32 *) pValue; -} - -static void DynOS_Opt_ConvertChoice(const u8 *aLabel, const u8 **aChoices, s32 aCount, u32 *pValue) { - DynosOption *_Opt = DynOS_Opt_ConvertOption(aLabel, aLabel); - _Opt->mType = DOPT_CHOICE; - _Opt->mChoice.mIndex = (s32 *) pValue; - for (s32 i = 0; i != aCount; ++i) { - _Opt->mChoice.mChoices.Add({ "", aChoices[i] }); - } -} - -static void DynOS_Opt_ConvertButton(const u8 *aLabel, VanillaActionFunction aAction) { - DynosOption *_Opt = DynOS_Opt_ConvertOption(aLabel, aLabel); - _Opt->mType = DOPT_BUTTON; - _Opt->mButton.mFuncName = "DynOS_Opt_CallVanillaAction"; - DynOS_Opt_AddVanillaAction(_Opt->mName, aAction); -} - -static void DynOS_Opt_ConvertBind(const u8 *aLabel, u32 *pBinds) { - DynosOption *_Opt = DynOS_Opt_ConvertOption(aLabel, aLabel); - _Opt->mType = DOPT_BIND; - _Opt->mBind.mMask = 0; - _Opt->mBind.mBinds = pBinds; - _Opt->mBind.mIndex = 0; -} - -#ifndef COOP -extern "C" { -extern void dynos_opt_convert_vanilla_main_menu(); -void dynos_opt_end_submenu() { return DynOS_Opt_EndSubMenu(); } -void dynos_opt_convert_submenu(const u8 *label, const u8 *title) { return DynOS_Opt_ConvertSubMenu(label, title); } -void dynos_opt_convert_toggle(const u8 *label, bool *bval) { return DynOS_Opt_ConvertToggle(label, bval); } -void dynos_opt_convert_scroll(const u8 *label, s32 min, s32 max, s32 step, u32 *uval) { return DynOS_Opt_ConvertScroll(label, min, max, step, uval); } -void dynos_opt_convert_choice(const u8 *label, const u8 **choices, s32 numChoices, u32 *uval) { return DynOS_Opt_ConvertChoice(label, choices, numChoices, uval); } -void dynos_opt_convert_button(const u8 *label, void *action) { return DynOS_Opt_ConvertButton(label, (VanillaActionFunction) action); } -void dynos_opt_convert_bind(const u8 *label, u32 *uval) { return DynOS_Opt_ConvertBind(label, uval); } -} -#endif -void DynOS_Opt_InitVanilla(DynosOption *&aOptionsMenu) { - sPrevOpt = NULL; -#ifndef COOP - dynos_opt_convert_vanilla_main_menu(); -#endif - DynOS_Opt_AddAction("DynOS_Opt_CallVanillaAction", DynOS_Opt_CallVanillaAction, true); - aOptionsMenu = sOptionsMenu; -} diff --git a/data/dynos_opt_vanilla_c.c b/data/dynos_opt_vanilla_c.c deleted file mode 100644 index d9cb3796..00000000 --- a/data/dynos_opt_vanilla_c.c +++ /dev/null @@ -1,72 +0,0 @@ - -#ifndef COOP -// Not my problem -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wsizeof-pointer-div" -#pragma GCC diagnostic ignored "-Wdiscarded-qualifiers" -#pragma GCC diagnostic ignored "-Wpointer-sign" -#pragma GCC diagnostic ignored "-Wsign-compare" -#define optmenu_toggle optmenu_toggle_unused -#define optmenu_draw optmenu_draw_unused -#define optmenu_draw_prompt optmenu_draw_prompt_unused -#define optmenu_check_buttons optmenu_check_buttons_unused -#define optmenu_open optmenu_open_unused -#define DYNOS_INL -#include "game/options_menu.c" -#undef DYNOS_INL -#undef optmenu_toggle -#undef optmenu_draw -#undef optmenu_draw_prompt -#undef optmenu_check_buttons -#undef optmenu_open -#pragma GCC diagnostic pop -// Now, that's my problem - -extern void dynos_opt_end_submenu(); -extern void dynos_opt_convert_submenu(const u8 *label, const u8 *title); -extern void dynos_opt_convert_toggle(const u8 *label, bool *bval); -extern void dynos_opt_convert_scroll(const u8 *label, s32 min, s32 max, s32 step, u32 *uval); -extern void dynos_opt_convert_choice(const u8 *label, const u8 **choices, s32 numChoices, u32 *uval); -extern void dynos_opt_convert_button(const u8 *label, void *action); -extern void dynos_opt_convert_bind(const u8 *label, u32 *uval); - -static void dynos_opt_convert_menu(struct SubMenu *submenu) { - for (s32 i = 0; i != submenu->numOpts; ++i) { - struct Option *opt = &submenu->opts[i]; - switch (opt->type) { - case OPT_TOGGLE: - dynos_opt_convert_toggle(opt->label, opt->bval); - break; - - case OPT_CHOICE: - dynos_opt_convert_choice(opt->label, opt->choices, opt->numChoices, opt->uval); - break; - - case OPT_SCROLL: - dynos_opt_convert_scroll(opt->label, opt->scrMin, opt->scrMax, opt->scrStep, opt->uval); - break; - - case OPT_SUBMENU: - dynos_opt_convert_submenu(opt->label, opt->nextMenu->label); - dynos_opt_convert_menu(opt->nextMenu); - dynos_opt_end_submenu(); - break; - - case OPT_BIND: - dynos_opt_convert_bind(opt->label, opt->uval); - break; - - case OPT_BUTTON: - dynos_opt_convert_button(opt->label, opt->actionFn); - break; - - default: - break; - } - } -} - -void dynos_opt_convert_vanilla_main_menu() { - dynos_opt_convert_menu(&menuMain); -} -#endif \ No newline at end of file diff --git a/data/dynos_warps.cpp b/data/dynos_warps.cpp index 9a2a95c0..1900604f 100644 --- a/data/dynos_warps.cpp +++ b/data/dynos_warps.cpp @@ -10,7 +10,6 @@ extern "C" { #include "game/level_update.h" #include "game/sound_init.h" #include "game/object_list_processor.h" -#include "game/options_menu.h" #include "pc/network/packets/packet.h" #include "pc/lua/smlua_hooks.h" extern s8 gDialogBoxState; @@ -82,19 +81,18 @@ bool DynOS_Warp_RestartLevel() { // bool DynOS_Warp_ExitLevel(s32 aDelay) { - if (DynOS_Level_GetCourse(gCurrLevelNum) == COURSE_NONE) { + if (DynOS_Level_GetCourse(gCurrLevelNum) == COURSE_NONE || !DynOS_Level_GetWarpDeath(gCurrLevelNum, gCurrAreaIndex)) { return false; } // Close the pause menu if it was open - optmenu_toggle(); level_set_transition(0, NULL); gDialogBoxState = 0; gMenuMode = -1; // Cancel out every music/sound/sequence for (u16 seqid = 0; seqid != SEQ_COUNT; ++seqid) { - stop_background_music(seqid); + stop_background_music(seqid); } play_shell_music(); stop_shell_music(); @@ -106,7 +104,7 @@ bool DynOS_Warp_ExitLevel(s32 aDelay) { // Play Mario head transition, and change play mode to avoid getting stuck on the pause menu aDelay = MAX(1, aDelay); gMarioState->invincTimer = -1; - play_transition(WARP_TRANSITION_FADE_INTO_MARIO, aDelay, 0x00, 0x00, 0x00); + play_transition(WARP_TRANSITION_FADE_INTO_COLOR, aDelay, 0x00, 0x00, 0x00); set_play_mode(0); sDynosExitLevelNum = gCurrLevelNum; sDynosExitAreaNum = gCurrAreaIndex; @@ -114,19 +112,18 @@ bool DynOS_Warp_ExitLevel(s32 aDelay) { } bool DynOS_Warp_ToCastle(s32 aLevel) { - if (DynOS_Level_GetCourse(aLevel) == COURSE_NONE) { + if (DynOS_Level_GetCourse(aLevel) == COURSE_NONE || !DynOS_Level_GetWarpDeath(aLevel, 1)) { return false; } // Close the pause menu if it was open - optmenu_toggle(); level_set_transition(0, NULL); gDialogBoxState = 0; gMenuMode = -1; // Cancel out every music/sound/sequence for (u16 seqid = 0; seqid != SEQ_COUNT; ++seqid) { - stop_background_music(seqid); + stop_background_music(seqid); } play_shell_music(); stop_shell_music(); @@ -142,79 +139,6 @@ bool DynOS_Warp_ToCastle(s32 aLevel) { return true; } -// -// Params -// - -const char *DynOS_Warp_GetParamName(s32 aLevel, s32 aIndex) { - static const char *sLevelParams[][5] = { - { "", "", "", "", "" }, - { "None", "No Submarine, No Poles", "Submarine Only", "Poles Only", "Submarine And Poles" }, - { "None", "Water Level: Lowest", "Water Level: Low", "Water Level: High", "Water Level: Highest" }, - { "None", "Top Flooded", "Top Drained", "Top Flooded", "Top Drained" }, - { "None", "Clock Speed: Stopped", "Clock Speed: Slow", "Clock Speed: Fast", "Clock Speed: Random" }, - }; - switch (aLevel) { - case LEVEL_DDD: return sLevelParams[1][MIN(4, aIndex)]; - case LEVEL_WDW: return sLevelParams[2][MIN(4, aIndex)]; - case LEVEL_THI: return sLevelParams[3][MIN(4, aIndex)]; - case LEVEL_TTC: return sLevelParams[4][MIN(4, aIndex)]; - } - return sLevelParams[0][MIN(4, aIndex)]; -} - -// Called thrice -// Pass -1 to use the previous value (only once) -void DynOS_Warp_SetParam(s32 aLevel, s32 aIndex) { - static s32 sDynosWarpPrevParamIndex = -1; - if (aIndex == -1) { - aIndex = sDynosWarpPrevParamIndex; - sDynosWarpPrevParamIndex = -1; - } else { - sDynosWarpPrevParamIndex = aIndex; - } - - switch (aLevel) { - case LEVEL_DDD: - switch (aIndex) { - case 1: gDDDBowsersSub = 0; gDDDPoles = 0; break; - case 2: gDDDBowsersSub = 1; gDDDPoles = 0; break; - case 3: gDDDBowsersSub = 0; gDDDPoles = 1; break; - case 4: gDDDBowsersSub = 1; gDDDPoles = 1; break; - } - break; - - case LEVEL_WDW: - if (gEnvironmentRegions && gEnvironmentRegionsLength > 6) { - switch (aIndex) { - case 1: gEnvironmentRegions[6] = *gEnvironmentLevels = 31; gWdwWaterLevelSet = 1; break; - case 2: gEnvironmentRegions[6] = *gEnvironmentLevels = 1024; gWdwWaterLevelSet = 1; break; - case 3: gEnvironmentRegions[6] = *gEnvironmentLevels = 1792; gWdwWaterLevelSet = 1; break; - case 4: gEnvironmentRegions[6] = *gEnvironmentLevels = 2816; gWdwWaterLevelSet = 1; break; - } - } - break; - - case LEVEL_THI: - switch (aIndex) { - case 1: gTHIWaterDrained = 0; break; - case 2: gTHIWaterDrained = 1; break; - case 3: gTHIWaterDrained = 0; break; - case 4: gTHIWaterDrained = 1; break; - } - break; - - case LEVEL_TTC: - switch (aIndex) { - case 1: gTTCSpeedSetting = TTC_SPEED_STOPPED; break; - case 2: gTTCSpeedSetting = TTC_SPEED_SLOW; break; - case 3: gTTCSpeedSetting = TTC_SPEED_FAST; break; - case 4: gTTCSpeedSetting = TTC_SPEED_RANDOM; break; - } - break; - } -} - // // Update // @@ -226,14 +150,13 @@ static void *DynOS_Warp_UpdateWarp(void *aCmd, bool aIsLevelInitDone) { if (sDynosWarpTargetArea == -1) { // Close the pause menu if it was open - optmenu_toggle(); level_set_transition(0, NULL); gDialogBoxState = 0; gMenuMode = -1; // Cancel out every music/sound/sequence for (u16 seqid = 0; seqid != SEQ_COUNT; ++seqid) { - stop_background_music(seqid); + stop_background_music(seqid); } play_shell_music(); stop_shell_music(); @@ -259,13 +182,10 @@ static void *DynOS_Warp_UpdateWarp(void *aCmd, bool aIsLevelInitDone) { gCurrLevelNum = sDynosWarpLevelNum; gCurrCourseNum = DynOS_Level_GetCourse(gCurrLevelNum); gSavedCourseNum = gCurrCourseNum; - gCurrActNum = MAX(1, sDynosWarpActNum * (gCurrCourseNum <= COURSE_STAGES_MAX)); + gCurrActNum = MAX(0, sDynosWarpActNum * (gCurrCourseNum <= COURSE_STAGES_MAX)); gDialogCourseActNum = gCurrActNum; gCurrAreaIndex = sDynosWarpAreaNum; gCurrActStarNum = sDynosWarpActNum; -#ifndef COOP - DynOS_Warp_SetParam(gCurrLevelNum, DynOS_Opt_GetValue("dynos_warp_param")); -#endif sDynosWarpTargetArea = gCurrAreaIndex; // Set up new level script @@ -285,7 +205,7 @@ static void *DynOS_Warp_UpdateWarp(void *aCmd, bool aIsLevelInitDone) { } // Phase 3 - End level initialization - if (aIsLevelInitDone) { + if (aIsLevelInitDone && gMarioObjects[0]) { // Get Warp s16 *_Warp; @@ -306,9 +226,6 @@ static void *DynOS_Warp_UpdateWarp(void *aCmd, bool aIsLevelInitDone) { gMarioSpawnInfo->areaIndex = gCurrAreaIndex; init_mario(); set_mario_initial_action(gMarioState, sDynosWarpSpawnType, 0); -#ifndef COOP - DynOS_Warp_SetParam(gCurrLevelNum, DynOS_Opt_GetValue("dynos_warp_param")); -#endif // Init transition if (gCurrentArea != NULL) { @@ -447,7 +364,7 @@ static void *DynOS_Warp_UpdateExit(void *aCmd, bool aIsLevelInitDone) { } // Phase 3 - End level initialization - if (sDynosExitTargetWarp && aIsLevelInitDone) { + if (sDynosExitTargetWarp && aIsLevelInitDone && gMarioObjects[0]) { // Find target position // Because of course, every hack has its own warp distances and orientations... @@ -471,14 +388,18 @@ static void *DynOS_Warp_UpdateExit(void *aCmd, bool aIsLevelInitDone) { set_mario_initial_action(gMarioState, MARIO_SPAWN_UNKNOWN_02, 0); // Init transition - reset_camera(gCurrentArea->camera); - init_camera(gCurrentArea->camera); + if (gCurrentArea != NULL) { + reset_camera(gCurrentArea->camera); + init_camera(gCurrentArea->camera); + } sDelayedWarpOp = WARP_OP_NONE; play_transition(WARP_TRANSITION_FADE_FROM_STAR, 15, 0x00, 0x00, 0x00); play_sound(SOUND_MENU_MARIO_CASTLE_WARP, gGlobalSoundSource); // Set music - set_background_music(gCurrentArea->musicParam, gCurrentArea->musicParam2, 0); + if (gCurrentArea != NULL) { + set_background_music(gCurrentArea->musicParam, gCurrentArea->musicParam2, 0); + } sDynosExitTargetWarp = NULL; // lua hooks diff --git a/docs/lua/functions-4.md b/docs/lua/functions-4.md index 06aca719..15194a50 100644 --- a/docs/lua/functions-4.md +++ b/docs/lua/functions-4.md @@ -7384,6 +7384,50 @@
+## [collision_find_ceil](#collision_find_ceil) + +### Lua Example +`local SurfaceValue = collision_find_ceil(x, y, z)` + +### Parameters +| Field | Type | +| ----- | ---- | +| x | `number` | +| y | `number` | +| z | `number` | + +### Returns +[Surface](structs.md#Surface) + +### C Prototype +`struct Surface* collision_find_ceil(f32 x, f32 y, f32 z);` + +[:arrow_up_small:](#) + +
+ +## [collision_find_floor](#collision_find_floor) + +### Lua Example +`local SurfaceValue = collision_find_floor(x, y, z)` + +### Parameters +| Field | Type | +| ----- | ---- | +| x | `number` | +| y | `number` | +| z | `number` | + +### Returns +[Surface](structs.md#Surface) + +### C Prototype +`struct Surface* collision_find_floor(f32 x, f32 y, f32 z);` + +[:arrow_up_small:](#) + +
+ ## [collision_find_surface_on_ray](#collision_find_surface_on_ray) ### Lua Example @@ -7564,6 +7608,26 @@
+## [smlua_level_util_get_info_from_course_num](#smlua_level_util_get_info_from_course_num) + +### Lua Example +`local CustomLevelInfoValue = smlua_level_util_get_info_from_course_num(courseNum)` + +### Parameters +| Field | Type | +| ----- | ---- | +| courseNum | `integer` | + +### Returns +[CustomLevelInfo](structs.md#CustomLevelInfo) + +### C Prototype +`struct CustomLevelInfo* smlua_level_util_get_info_from_course_num(u8 courseNum);` + +[:arrow_up_small:](#) + +
+ ## [smlua_level_util_get_info_from_short_name](#smlua_level_util_get_info_from_short_name) ### Lua Example diff --git a/docs/lua/functions-5.md b/docs/lua/functions-5.md index bcb5f24d..4a76c5a4 100644 --- a/docs/lua/functions-5.md +++ b/docs/lua/functions-5.md @@ -2384,6 +2384,91 @@
+## [smlua_text_utils_act_name_get](#smlua_text_utils_act_name_get) + +### Lua Example +`local stringValue = smlua_text_utils_act_name_get(courseNum, actNum)` + +### Parameters +| Field | Type | +| ----- | ---- | +| courseNum | `integer` | +| actNum | `integer` | + +### Returns +- `string` + +### C Prototype +`const char* smlua_text_utils_act_name_get(s16 courseNum, u8 actNum);` + +[:arrow_up_small:](#) + +
+ +## [smlua_text_utils_act_name_is_modified](#smlua_text_utils_act_name_is_modified) + +### Lua Example +`local booleanValue = smlua_text_utils_act_name_is_modified(courseNum, actNum)` + +### Parameters +| Field | Type | +| ----- | ---- | +| courseNum | `integer` | +| actNum | `integer` | + +### Returns +- `boolean` + +### C Prototype +`bool smlua_text_utils_act_name_is_modified(s16 courseNum, u8 actNum);` + +[:arrow_up_small:](#) + +
+ +## [smlua_text_utils_act_name_replace](#smlua_text_utils_act_name_replace) + +### Lua Example +`smlua_text_utils_act_name_replace(courseNum, actNum, name)` + +### Parameters +| Field | Type | +| ----- | ---- | +| courseNum | `integer` | +| actNum | `integer` | +| name | `string` | + +### Returns +- None + +### C Prototype +`void smlua_text_utils_act_name_replace(s16 courseNum, u8 actNum, const char* name);` + +[:arrow_up_small:](#) + +
+ +## [smlua_text_utils_act_name_reset](#smlua_text_utils_act_name_reset) + +### Lua Example +`smlua_text_utils_act_name_reset(courseNum, actNum)` + +### Parameters +| Field | Type | +| ----- | ---- | +| courseNum | `integer` | +| actNum | `integer` | + +### Returns +- None + +### C Prototype +`void smlua_text_utils_act_name_reset(s16 courseNum, u8 actNum);` + +[:arrow_up_small:](#) + +
+ ## [smlua_text_utils_castle_secret_stars_replace](#smlua_text_utils_castle_secret_stars_replace) ### Lua Example @@ -2431,6 +2516,87 @@
+## [smlua_text_utils_course_name_get](#smlua_text_utils_course_name_get) + +### Lua Example +`local stringValue = smlua_text_utils_course_name_get(courseNum)` + +### Parameters +| Field | Type | +| ----- | ---- | +| courseNum | `integer` | + +### Returns +- `string` + +### C Prototype +`const char* smlua_text_utils_course_name_get(s16 courseNum);` + +[:arrow_up_small:](#) + +
+ +## [smlua_text_utils_course_name_mod_index](#smlua_text_utils_course_name_mod_index) + +### Lua Example +`local integerValue = smlua_text_utils_course_name_mod_index(courseNum)` + +### Parameters +| Field | Type | +| ----- | ---- | +| courseNum | `integer` | + +### Returns +- `integer` + +### C Prototype +`s32 smlua_text_utils_course_name_mod_index(s16 courseNum);` + +[:arrow_up_small:](#) + +
+ +## [smlua_text_utils_course_name_replace](#smlua_text_utils_course_name_replace) + +### Lua Example +`smlua_text_utils_course_name_replace(courseNum, name)` + +### Parameters +| Field | Type | +| ----- | ---- | +| courseNum | `integer` | +| name | `string` | + +### Returns +- None + +### C Prototype +`void smlua_text_utils_course_name_replace(s16 courseNum, const char* name);` + +[:arrow_up_small:](#) + +
+ +## [smlua_text_utils_course_name_reset](#smlua_text_utils_course_name_reset) + +### Lua Example +`smlua_text_utils_course_name_reset(courseNum)` + +### Parameters +| Field | Type | +| ----- | ---- | +| courseNum | `integer` | + +### Returns +- None + +### C Prototype +`void smlua_text_utils_course_name_reset(s16 courseNum);` + +[:arrow_up_small:](#) + +
+ ## [smlua_text_utils_dialog_replace](#smlua_text_utils_dialog_replace) ### Lua Example @@ -2495,24 +2661,6 @@
-## [smlua_text_utils_reset_all](#smlua_text_utils_reset_all) - -### Lua Example -`smlua_text_utils_reset_all()` - -### Parameters -- None - -### Returns -- None - -### C Prototype -`void smlua_text_utils_reset_all(void);` - -[:arrow_up_small:](#) - -
- ## [smlua_text_utils_secret_star_replace](#smlua_text_utils_secret_star_replace) ### Lua Example diff --git a/docs/lua/functions.md b/docs/lua/functions.md index f4cddf94..ff947990 100644 --- a/docs/lua/functions.md +++ b/docs/lua/functions.md @@ -1521,6 +1521,8 @@
- smlua_collision_utils.h + - [collision_find_ceil](functions-4.md#collision_find_ceil) + - [collision_find_floor](functions-4.md#collision_find_floor) - [collision_find_surface_on_ray](functions-4.md#collision_find_surface_on_ray) - [collision_get_temp_wall_collision_data](functions-4.md#collision_get_temp_wall_collision_data) - [get_water_surface_pseudo_floor](functions-4.md#get_water_surface_pseudo_floor) @@ -1537,6 +1539,7 @@ - [level_register](functions-4.md#level_register) - [smlua_level_util_change_area](functions-4.md#smlua_level_util_change_area) - [smlua_level_util_get_info](functions-4.md#smlua_level_util_get_info) + - [smlua_level_util_get_info_from_course_num](functions-4.md#smlua_level_util_get_info_from_course_num) - [smlua_level_util_get_info_from_short_name](functions-4.md#smlua_level_util_get_info_from_short_name) - [warp_exit_level](functions-4.md#warp_exit_level) - [warp_restart_level](functions-4.md#warp_restart_level) @@ -1690,12 +1693,19 @@
- smlua_text_utils.h + - [smlua_text_utils_act_name_get](functions-5.md#smlua_text_utils_act_name_get) + - [smlua_text_utils_act_name_is_modified](functions-5.md#smlua_text_utils_act_name_is_modified) + - [smlua_text_utils_act_name_replace](functions-5.md#smlua_text_utils_act_name_replace) + - [smlua_text_utils_act_name_reset](functions-5.md#smlua_text_utils_act_name_reset) - [smlua_text_utils_castle_secret_stars_replace](functions-5.md#smlua_text_utils_castle_secret_stars_replace) - [smlua_text_utils_course_acts_replace](functions-5.md#smlua_text_utils_course_acts_replace) + - [smlua_text_utils_course_name_get](functions-5.md#smlua_text_utils_course_name_get) + - [smlua_text_utils_course_name_mod_index](functions-5.md#smlua_text_utils_course_name_mod_index) + - [smlua_text_utils_course_name_replace](functions-5.md#smlua_text_utils_course_name_replace) + - [smlua_text_utils_course_name_reset](functions-5.md#smlua_text_utils_course_name_reset) - [smlua_text_utils_dialog_replace](functions-5.md#smlua_text_utils_dialog_replace) - [smlua_text_utils_extra_text_replace](functions-5.md#smlua_text_utils_extra_text_replace) - [smlua_text_utils_get_language](functions-5.md#smlua_text_utils_get_language) - - [smlua_text_utils_reset_all](functions-5.md#smlua_text_utils_reset_all) - [smlua_text_utils_secret_star_replace](functions-5.md#smlua_text_utils_secret_star_replace)
diff --git a/src/engine/surface_load.c b/src/engine/surface_load.c index 2422a548..188078c0 100644 --- a/src/engine/surface_load.c +++ b/src/engine/surface_load.c @@ -154,32 +154,14 @@ static void add_surface_to_cell(s16 dynamic, s16 cellX, s16 cellZ, struct Surfac /** * Returns the lowest of three values. */ -static s16 min_3(s16 a0, s16 a1, s16 a2) { - if (a1 < a0) { - a0 = a1; - } - if (a2 < a0) { - a0 = a2; - } - - return a0; -} +#define min_3(a0, a1, a2) MIN(MIN(a0, a1), a2) /** * Returns the highest of three values. */ -static s16 max_3(s16 a0, s16 a1, s16 a2) { - if (a1 > a0) { - a0 = a1; - } - if (a2 > a0) { - a0 = a2; - } - - return a0; -} +#define max_3(a0, a1, a2) MAX(MAX(a0, a1), a2) /** * Every level is split into 16 * 16 cells of surfaces (to limit computing @@ -378,48 +360,25 @@ static struct Surface *read_surface_data(s16 *vertexData, s16 **vertexIndices) { * Returns whether a surface has exertion/moves Mario * based on the surface type. */ -static s32 surface_has_force(s16 surfaceType) { - s32 hasForce = FALSE; - - switch (surfaceType) { - case SURFACE_0004: // Unused - case SURFACE_FLOWING_WATER: - case SURFACE_DEEP_MOVING_QUICKSAND: - case SURFACE_SHALLOW_MOVING_QUICKSAND: - case SURFACE_MOVING_QUICKSAND: - case SURFACE_HORIZONTAL_WIND: - case SURFACE_INSTANT_MOVING_QUICKSAND: - hasForce = TRUE; - break; - - default: - break; - } - return hasForce; +static bool surface_has_force(s16 surfaceType) { + return surfaceType == SURFACE_0004 || + surfaceType == SURFACE_FLOWING_WATER || + surfaceType == SURFACE_HORIZONTAL_WIND || + surfaceType == SURFACE_MOVING_QUICKSAND || + surfaceType == SURFACE_DEEP_MOVING_QUICKSAND || + surfaceType == SURFACE_SHALLOW_MOVING_QUICKSAND || + surfaceType == SURFACE_INSTANT_MOVING_QUICKSAND; } /** * Returns whether a surface should have the * SURFACE_FLAG_NO_CAM_COLLISION flag. */ -static s32 surf_has_no_cam_collision(s16 surfaceType) { - s32 flags = 0; - - switch (surfaceType) { - case SURFACE_RAYCAST: - case SURFACE_NO_CAM_COLLISION: - case SURFACE_NO_CAM_COLLISION_77: // Unused - case SURFACE_NO_CAM_COL_VERY_SLIPPERY: - case SURFACE_VANISH_CAP_WALLS: - case SURFACE_SWITCH: - flags = SURFACE_FLAG_NO_CAM_COLLISION; - break; - - default: - break; - } - - return flags; +static bool surf_has_no_cam_collision(s16 surfaceType) { + return surfaceType == SURFACE_SWITCH || + surfaceType == SURFACE_NO_CAM_COLLISION || + surfaceType == SURFACE_NO_CAM_COLLISION_77 || + surfaceType == SURFACE_NO_CAM_COL_VERY_SLIPPERY; } /** @@ -427,17 +386,16 @@ static s32 surf_has_no_cam_collision(s16 surfaceType) { * exertion, and room. */ static void load_static_surfaces(s16 **data, s16 *vertexData, s16 surfaceType, s8 **surfaceRooms) { - s32 i; s32 numSurfaces; struct Surface *surface; s8 room = 0; - s16 hasForce = surface_has_force(surfaceType); - s16 flags = surf_has_no_cam_collision(surfaceType); + bool hasForce = surface_has_force(surfaceType); + bool flags = surf_has_no_cam_collision(surfaceType); numSurfaces = *(*data); *data += 1; - for (i = 0; i < numSurfaces; i++) { + for (s32 i = 0; i < numSurfaces; i++) { if (*surfaceRooms != NULL) { room = *(*surfaceRooms); *surfaceRooms += 1; @@ -486,7 +444,6 @@ static s16 *read_vertex_data(s16 **data) { */ static void load_environmental_regions(s16 **data) { s32 numRegions; - s32 i; gEnvironmentRegionsLength = 0; gEnvironmentRegions = *data; @@ -497,7 +454,7 @@ static void load_environmental_regions(s16 **data) { numRegions = 20; } - for (i = 0; i < numRegions; i++) { + for (s32 i = 0; i < numRegions; i++) { UNUSED s16 val, loX, loZ, hiX, hiZ; s16 height; diff --git a/src/game/behaviors/camera_lakitu.inc.c b/src/game/behaviors/camera_lakitu.inc.c index eec0059b..51eea749 100644 --- a/src/game/behaviors/camera_lakitu.inc.c +++ b/src/game/behaviors/camera_lakitu.inc.c @@ -30,7 +30,7 @@ static void bhv_camera_lakitu_on_received_post(u8 localIndex) { void bhv_camera_lakitu_init(void) { if (o->oBehParams2ndByte != CAMERA_LAKITU_BP_FOLLOW_CAMERA) { // Despawn unless this is the very beginning of the game - if (gNeverEnteredCastle != TRUE) { + if (!gNeverEnteredCastle) { obj_mark_for_deletion(o); return; } @@ -38,7 +38,7 @@ void bhv_camera_lakitu_init(void) { spawn_object_relative_with_scale(CLOUD_BP_LAKITU_CLOUD, 0, 0, 0, 2.0f, o, MODEL_MIST, bhvCloud); } lakituTargetLocalIndex = UNKNOWN_LOCAL_INDEX; - + if (!sync_object_is_initialized(o->oSyncID)) { struct SyncObject *so = sync_object_init(o, 4000.0f); if (so) { diff --git a/src/game/behaviors/snowman.inc.c b/src/game/behaviors/snowman.inc.c index 86d0e7ad..65ea5def 100644 --- a/src/game/behaviors/snowman.inc.c +++ b/src/game/behaviors/snowman.inc.c @@ -131,23 +131,20 @@ static u8 bhv_snowmans_bottom_loop_continue_dialog(void) { } void bhv_snowmans_bottom_loop(void) { - s16 sp1E; - struct MarioState* marioState = nearest_mario_state_to_object(o); switch (o->oAction) { case 0: if (marioState + && marioState->playerIndex == 0 && should_start_or_continue_dialog(marioState, o) && (is_point_within_radius_of_mario(o->oPosX, o->oPosY, o->oPosZ, 400) == 1) - && set_mario_npc_dialog(&gMarioStates[0], 1, bhv_snowmans_bottom_loop_continue_dialog) == 2) { - sp1E = cutscene_object_with_dialog(CUTSCENE_DIALOG, o, gBehaviorValues.dialogs.SnowmanHeadBodyDialog); - if (sp1E) { - o->oForwardVel = 10.0f; - o->oAction = 1; - set_mario_npc_dialog(&gMarioStates[0], 0, NULL); - network_send_object(o); - } + && set_mario_npc_dialog(&gMarioStates[0], 1, bhv_snowmans_bottom_loop_continue_dialog) + && cutscene_object_with_dialog(CUTSCENE_DIALOG, o, gBehaviorValues.dialogs.SnowmanHeadBodyDialog)) { + o->oForwardVel = 10.0f; + o->oAction = 1; + set_mario_npc_dialog(&gMarioStates[0], 0, NULL); + network_send_object(o); } break; diff --git a/src/game/behaviors/spawn_star.inc.c b/src/game/behaviors/spawn_star.inc.c index 0ddcbb1e..195549a6 100644 --- a/src/game/behaviors/spawn_star.inc.c +++ b/src/game/behaviors/spawn_star.inc.c @@ -59,10 +59,10 @@ static struct ObjectHitbox sCollectStarHitbox = { }; void bhv_collect_star_init(void) { - s8 starId; + s16 starId; u8 currentLevelStarFlags; - starId = (o->oBehParams >> 24) & 0xFF; + starId = o->oBehParams >> 24; currentLevelStarFlags = save_file_get_star_flags(gCurrSaveFileNum - 1, gCurrCourseNum - 1); if (currentLevelStarFlags & (1 << starId)) { cur_obj_set_model(MODEL_TRANSPARENT_STAR); @@ -256,7 +256,7 @@ struct Object *spawn_no_exit_star(f32 x, f32 y, f32 z) { /** * A special star spawning routine just for a networked stars. * These stars require the global index for a network player for proper - * cutscene functionality. + * cutscene functionality. */ struct Object *spawn_networked_default_star(f32 x, f32 y, f32 z, u8 networkPlayerIndex) { if (sCurrPlayMode != PLAY_MODE_NORMAL && sCurrPlayMode != PLAY_MODE_PAUSED) { return NULL; } @@ -298,7 +298,7 @@ void bhv_hidden_red_coin_star_init(void) { if (gCurrentArea) { o->oHiddenStarTriggerCounter = gCurrentArea->numRedCoins - redCoins; } - + // We haven't interacted with a player yet. // We also don't sync this as not only is it not required // but it also is only set for an interaction. @@ -306,7 +306,7 @@ void bhv_hidden_red_coin_star_init(void) { // and if it wasn't. You couldn't of possibly been the one // who last interacted to begin with. o->oHiddenStarLastInteractedObject = NULL; - + if (!sync_object_is_initialized(o->oSyncID)) { struct SyncObject *so = sync_object_init(o, SYNC_DISTANCE_ONLY_EVENTS); if (so) { diff --git a/src/game/camera.c b/src/game/camera.c index b96fb212..29829310 100644 --- a/src/game/camera.c +++ b/src/game/camera.c @@ -3112,10 +3112,12 @@ void update_lakitu(struct Camera *c) { gLakituState.defMode = c->defMode; } +extern bool gIsDemoActive; static void update_romhack_camera_override(struct Camera *c) { if (gOverrideRomhackCamera == RCO_NONE) { return; } if (c->mode == CAMERA_MODE_ROM_HACK) { return; } if (dynos_level_is_vanilla_level(gCurrLevelNum)) { return; } + if (gIsDemoActive) { return; } if (gOverrideRomhackCamera == RCO_ALL_EXCEPT_BOWSER) { if (gCurrLevelNum == LEVEL_BOWSER_1 || gCurrLevelNum == LEVEL_BOWSER_2 || gCurrLevelNum == LEVEL_BOWSER_3) { @@ -3516,7 +3518,7 @@ void init_camera(struct Camera *c) { // Make sure Bowser is in a state that we'd start speaking to him in. obj = find_object_with_behavior(bhvBowser); if (obj != NULL && obj->oAction != 5) { break; } - + start_cutscene(c, CUTSCENE_ENTER_BOWSER_ARENA); } else if (gSecondCameraFocus != NULL) { gSecondCameraFocus->oBowserUnk88 = 2; @@ -3525,7 +3527,7 @@ void init_camera(struct Camera *c) { // Make sure Bowser is in a state that we'd start speaking to him in. obj = find_object_with_behavior(bhvBowser); if (obj != NULL && obj->oAction != 5) { break; } - + start_cutscene(c, CUTSCENE_ENTER_BOWSER_ARENA); #endif break; @@ -3533,14 +3535,14 @@ void init_camera(struct Camera *c) { // Make sure Bowser is in a state that we'd start speaking to him in. obj = find_object_with_behavior(bhvBowser); if (obj != NULL && obj->oAction != 5) { break; } - + start_cutscene(c, CUTSCENE_ENTER_BOWSER_ARENA); break; case LEVEL_BOWSER_3: // Make sure Bowser is in a state that we'd start speaking to him in. obj = find_object_with_behavior(bhvBowser); if (obj != NULL && obj->oAction != 5) { break; } - + start_cutscene(c, CUTSCENE_ENTER_BOWSER_ARENA); break; @@ -9605,7 +9607,7 @@ BAD_RETURN(s32) cutscene_non_painting_set_cam_pos(struct Camera *c) { BAD_RETURN(s32) cutscene_non_painting_set_cam_focus(struct Camera *c) { if (!c) { return; } offset_rotated(c->focus, sCutsceneVars[7].point, sCutsceneVars[6].point, sCutsceneVars[7].angle); - + if (dynos_level_is_vanilla_level(gCurrLevelNum) && ((gPrevLevel == LEVEL_COTMC) || (gPrevLevel == LEVEL_HMC) || (gPrevLevel == LEVEL_RR) || (gPrevLevel == LEVEL_WMOTR))) { c->focus[0] = c->pos[0] + (sMarioCamState->pos[0] - c->pos[0]) * 0.7f; c->focus[1] = c->pos[1] + (sMarioCamState->pos[1] - c->pos[1]) * 0.4f; diff --git a/src/game/game_init.c b/src/game/game_init.c index c4c36e0d..f8f1ad3c 100644 --- a/src/game/game_init.c +++ b/src/game/game_init.c @@ -468,7 +468,6 @@ void read_controller_inputs(void) { if (gControllerBits) { osRecvMesg(&gSIEventMesgQueue, &D_80339BEC, OS_MESG_BLOCK); osContGetReadData(gInteractableOverridePad ? &gInteractablePad : &gControllerPads[0]); - dynos_update_opt((void *) &gControllerPads[0]); } run_demo_inputs(); diff --git a/src/game/hardcoded.c b/src/game/hardcoded.c index 7ada52d2..c66b73c1 100644 --- a/src/game/hardcoded.c +++ b/src/game/hardcoded.c @@ -34,6 +34,8 @@ #include "levels/wf/header.h" #include "levels/wmotr/header.h" +#include "src/pc/pc_main.h" + extern Trajectory sThiHugeMetalBallTraj[]; extern Trajectory sThiTinyMetalBallTraj[]; @@ -308,8 +310,7 @@ struct PaintingValues gPaintingValues = { 0 }; // functions // /////////////// -__attribute__((constructor)) -void hardcoded_reset_default_values(void) { +AT_STARTUP void hardcoded_reset_default_values(void) { gLevelValues = gDefaultLevelValues; gBehaviorValues = gDefaultBehaviorValues; diff --git a/src/game/ingame_menu.c b/src/game/ingame_menu.c index 8287a60b..182d1e0a 100644 --- a/src/game/ingame_menu.c +++ b/src/game/ingame_menu.c @@ -39,6 +39,7 @@ #ifdef BETTERCAMERA #include "bettercamera.h" #endif +#include "level_info.h" u16 gDialogColorFadeTimer; s8 gLastDialogLineNum; @@ -2515,38 +2516,13 @@ void render_pause_my_score_coins(void) { u8 textUnfilledStar[] = { TEXT_UNFILLED_STAR }; u8 strCourseNum[4]; - void **courseNameTbl; - u8 *courseName; - void **actNameTbl; - u8 *actName = NULL; - u8 courseIndex; + u8 courseIndex = gCurrCourseNum - 1; + u8 *courseName = (u8*) get_level_name_sm64(gCurrCourseNum, gCurrLevelNum, gCurrAreaIndex, 1); + u8 *actName = (u8*) get_star_name_sm64(gCurrCourseNum, gDialogCourseActNum, 1); u8 starFlags; -#ifndef VERSION_EU - courseNameTbl = segmented_to_virtual(seg2_course_name_table); - actNameTbl = segmented_to_virtual(seg2_act_name_table); -#endif - - courseIndex = gCurrCourseNum - 1; starFlags = save_file_get_star_flags(gCurrSaveFileNum - 1, gCurrCourseNum - 1); -#ifdef VERSION_EU - switch (gInGameLanguage) { - case LANGUAGE_ENGLISH: - actNameTbl = segmented_to_virtual(act_name_table_eu_en); - courseNameTbl = segmented_to_virtual(course_name_table_eu_en); - break; - case LANGUAGE_FRENCH: - actNameTbl = segmented_to_virtual(act_name_table_eu_fr); - courseNameTbl = segmented_to_virtual(course_name_table_eu_fr); - break; - case LANGUAGE_GERMAN: - actNameTbl = segmented_to_virtual(act_name_table_eu_de); - courseNameTbl = segmented_to_virtual(course_name_table_eu_de); - break; - } -#endif - gSPDisplayList(gDisplayListHead++, dl_rgba16_text_begin); gDPSetEnvColor(gDisplayListHead++, 255, 255, 255, gDialogTextAlpha); @@ -2564,8 +2540,6 @@ void render_pause_my_score_coins(void) { print_generic_string(MYSCORE_X, 121, textMyScore); } - courseName = segmented_to_virtual(courseNameTbl[courseIndex]); - if (courseIndex < COURSE_STAGES_COUNT) { #ifdef VERSION_EU print_generic_string(48, 157, gTextCourseArr[gInGameLanguage]); @@ -2579,10 +2553,6 @@ void render_pause_my_score_coins(void) { print_generic_string(CRS_NUM_X1, 157, strCourseNum); #endif - if (gDialogCourseActNum >= 1 && gDialogCourseActNum <= 6) { - actName = segmented_to_virtual(actNameTbl[(gCurrCourseNum - 1) * 6 + gDialogCourseActNum - 1]); - } - if (starFlags & (1 << (gDialogCourseActNum - 1))) { print_generic_string(TXT_STAR_X, 140, textStar); } else { @@ -2838,11 +2808,7 @@ void render_pause_castle_course_stars(s16 x, s16 y, s16 fileNum, s16 courseNum) } void render_pause_castle_main_strings(s16 x, s16 y) { -#ifdef VERSION_EU - void **courseNameTbl; -#else - void **courseNameTbl = segmented_to_virtual(seg2_course_name_table); -#endif + void **courseNameTbl = get_course_name_table(); #ifdef VERSION_EU u8 textCoin[] = { TEXT_COIN }; @@ -2856,20 +2822,6 @@ void render_pause_castle_main_strings(s16 x, s16 y) { u8 strVal[8]; s16 starNum = gDialogLineNum; -#ifdef VERSION_EU - switch (gInGameLanguage) { - case LANGUAGE_ENGLISH: - courseNameTbl = segmented_to_virtual(course_name_table_eu_en); - break; - case LANGUAGE_FRENCH: - courseNameTbl = segmented_to_virtual(course_name_table_eu_fr); - break; - case LANGUAGE_GERMAN: - courseNameTbl = segmented_to_virtual(course_name_table_eu_de); - break; - } -#endif - handle_menu_scrolling(MENU_SCROLL_VERTICAL, &gDialogLineNum, -1, COURSE_STAGES_COUNT + 1); if (gDialogLineNum == COURSE_STAGES_COUNT + 1) { @@ -2936,7 +2888,7 @@ void render_pause_castle_main_strings(s16 x, s16 y) { static u32 pause_castle_get_stars(s32 index) { // Main courses (0-14), Secret courses (15-24) - if (index >= 0 && index < INDEX_CASTLE_STARS) { + if (COURSE_IS_VALID_COURSE(index)) { return save_file_get_star_flags(gCurrSaveFileNum - 1, index); } @@ -3061,24 +3013,8 @@ void render_pause_castle_main_strings_extended(s16 x, s16 y) { gSPDisplayList(gDisplayListHead++, dl_ia_text_begin); gDPSetEnvColor(gDisplayListHead++, 255, 255, 255, gDialogTextAlpha); - - void **courseNameTbl = NULL; - -#ifdef VERSION_EU - switch (gInGameLanguage) { - case LANGUAGE_ENGLISH: - courseNameTbl = segmented_to_virtual(course_name_table_eu_en); - break; - case LANGUAGE_FRENCH: - courseNameTbl = segmented_to_virtual(course_name_table_eu_fr); - break; - case LANGUAGE_GERMAN: - courseNameTbl = segmented_to_virtual(course_name_table_eu_de); - break; - } -#else - courseNameTbl = segmented_to_virtual(seg2_course_name_table); -#endif + + void **courseNameTbl = get_course_name_table(); // Main courses (0-14) if (gDialogLineNum < COURSE_STAGES_COUNT) { @@ -3098,7 +3034,7 @@ void render_pause_castle_main_strings_extended(s16 x, s16 y) { render_pause_castle_course_name(courseName + 3, 160, y + 30); render_pause_castle_course_stars_extended(x + 20, y); } - + // Castle stars (25) else if (gDialogLineNum == INDEX_CASTLE_STARS) { const u8 *courseName = courseNameTbl[COURSE_MAX]; @@ -3150,7 +3086,7 @@ s16 render_pause_courses_and_castle(void) { play_sound(SOUND_MENU_PAUSE_HIGHPRIO, gGlobalSoundSource); #endif - if (gCurrCourseNum >= COURSE_MIN && gCurrCourseNum <= COURSE_MAX) { + if (COURSE_IS_VALID_COURSE(gCurrCourseNum)) { change_dialog_camera_angle(); gDialogBoxState = DIALOG_STATE_VERTICAL; } else { @@ -3227,14 +3163,9 @@ s16 render_pause_courses_and_castle(void) { } if (gDjuiPanelPauseCreated) { shade_screen(); } - if (gPlayer1Controller->buttonPressed & R_TRIG) + if (gPlayer1Controller->buttonPressed & R_TRIG) { djui_panel_pause_create(NULL); - -#ifndef COOP - // call into DynOS's menu system - optmenu_draw(); - optmenu_draw_prompt(); -#endif + } return 0; } @@ -3384,33 +3315,12 @@ void render_course_complete_lvl_info_and_hud_str(void) { u8 textSymStar[] = { GLYPH_STAR, GLYPH_SPACE }; #endif - void **actNameTbl; - void **courseNameTbl; + void **actNameTbl = get_act_name_table(); + void **courseNameTbl = get_course_name_table(); u8 *name; u8 strCourseNum[4]; -#ifdef VERSION_EU - s16 centerX; - switch (gInGameLanguage) { - case LANGUAGE_ENGLISH: - actNameTbl = segmented_to_virtual(act_name_table_eu_en); - courseNameTbl = segmented_to_virtual(course_name_table_eu_en); - break; - case LANGUAGE_FRENCH: - actNameTbl = segmented_to_virtual(act_name_table_eu_fr); - courseNameTbl = segmented_to_virtual(course_name_table_eu_fr); - break; - case LANGUAGE_GERMAN: - actNameTbl = segmented_to_virtual(act_name_table_eu_de); - courseNameTbl = segmented_to_virtual(course_name_table_eu_de); - break; - } -#else - actNameTbl = segmented_to_virtual(seg2_act_name_table); - courseNameTbl = segmented_to_virtual(seg2_course_name_table); -#endif - if (gLastCompletedCourseNum <= COURSE_STAGES_MAX) { print_hud_course_complete_coins(118, 103); play_star_fanfare_and_flash_hud(1, 1 << (gLastCompletedStarNum - 1)); @@ -3435,7 +3345,7 @@ void render_course_complete_lvl_info_and_hud_str(void) { gSPDisplayList(gDisplayListHead++, dl_ia_text_begin); gDPSetEnvColor(gDisplayListHead++, 0, 0, 0, gDialogTextAlpha); #ifdef VERSION_EU - centerX = get_str_x_pos_from_center(153, name, 12.0f); + s16 centerX = get_str_x_pos_from_center(153, name, 12.0f); #endif print_generic_string(TXT_NAME_X1, 130, name); #ifndef VERSION_EU diff --git a/src/game/interaction.c b/src/game/interaction.c index 9a70c06b..956c8bb7 100644 --- a/src/game/interaction.c +++ b/src/game/interaction.c @@ -923,12 +923,7 @@ u32 interact_star_or_key(struct MarioState *m, UNUSED u32 interactType, struct O u8 stayInLevelCommon = !(gCurrLevelNum == LEVEL_BOWSER_1 || gCurrLevelNum == LEVEL_BOWSER_2 || gCurrLevelNum == LEVEL_BOWSER_3); if (stayInLevelCommon && gServerSettings.stayInLevelAfterStar) { noExit = TRUE; } - - if (o->behavior == bhvBowserKey) { - gLastCollectedStarOrKey = 1; - } else { - gLastCollectedStarOrKey = 0; - } + gLastCollectedStarOrKey = o->behavior == bhvBowserKey; if (m->health >= 0x100) { @@ -981,7 +976,7 @@ u32 interact_star_or_key(struct MarioState *m, UNUSED u32 interactType, struct O m->interactObj = o; m->usedObj = o; - starIndex = (o->oBehParams >> 24) & 0x1F; + starIndex = o->oBehParams >> 24; if (m == &gMarioStates[0]) { // sync the star collection diff --git a/src/game/level_info.c b/src/game/level_info.c index 7af399d9..547420cc 100644 --- a/src/game/level_info.c +++ b/src/game/level_info.c @@ -9,6 +9,7 @@ #include "save_file.h" #include "types.h" #include "pc/lua/utils/smlua_level_utils.h" +#include "pc/lua/utils/smlua_text_utils.h" #ifdef VERSION_EU extern s32 gInGameLanguage; @@ -39,7 +40,7 @@ static const struct { const char *str; u8 c; } sSm64CharMap[] = { { "p", 0x33 }, { "q", 0x34 }, { "r", 0x35 }, { "s", 0x36 }, { "t", 0x37 }, { "u", 0x38 }, { "v", 0x39 }, { "w", 0x3A }, { "x", 0x3B }, { "y", 0x3C }, { "z", 0x3D }, - + // Punctuation { "...", 0xE6 }, // ellipsis { ")(", 0xE2 }, // close-open parentheses @@ -57,7 +58,7 @@ static const struct { const char *str; u8 c; } sSm64CharMap[] = { { "%", 0xF3 }, // percent { "?", 0xF4 }, // question mark { "~", 0xF7 }, // tilde - + // Symbols { "[A]", 0x54 }, // bold A { "[B]", 0x55 }, // bold B @@ -107,7 +108,7 @@ static void convert_string_ascii_to_sm64(u8 *str64, const char *strAscii) { *str64 = 0xFF; } -static void convert_string_sm64_to_ascii(char *strAscii, const u8 *str64) { +void convert_string_sm64_to_ascii(char *strAscii, const u8 *str64) { for (; *str64 != 0xFF; str64++) { strAscii = sm64_to_ascii_char(strAscii, str64); } @@ -158,12 +159,40 @@ static void decapitalize_string_sm64(u8 *str64) { } } +void *get_course_name_table() { + void **courseNameTbl = segmented_to_virtual(seg2_course_name_table); + +#ifdef VERSION_EU + switch (gInGameLanguage) { + case LANGUAGE_ENGLISH: courseNameTbl = segmented_to_virtual(course_name_table_eu_en); break; + case LANGUAGE_FRENCH: courseNameTbl = segmented_to_virtual(course_name_table_eu_fr); break; + case LANGUAGE_GERMAN: courseNameTbl = segmented_to_virtual(course_name_table_eu_de); break; + } +#endif + + return courseNameTbl; +} + +void *get_act_name_table() { + void **actNameTbl = segmented_to_virtual(seg2_act_name_table); + +#ifdef VERSION_EU + switch (gInGameLanguage) { + case LANGUAGE_ENGLISH: actNameTbl = segmented_to_virtual(act_name_table_eu_en); break; + case LANGUAGE_FRENCH: actNameTbl = segmented_to_virtual(act_name_table_eu_fr); break; + case LANGUAGE_GERMAN: actNameTbl = segmented_to_virtual(act_name_table_eu_de); break; + } +#endif + + return actNameTbl; +} + +extern struct CourseName *gReplacedActNameTable[]; + const char *get_level_name_ascii(s16 courseNum, s16 levelNum, s16 areaIndex, s16 charCase) { static char output[256]; - // Valid course: BOB to RR, Bowser stages and Secret courses - // There is no course name for Cake Ending, make it defaults to "Peach's Castle" - + // Custom course bool hasCustomName = false; if (levelNum >= CUSTOM_LEVEL_NUM_START) { struct CustomLevelInfo* info = smlua_level_util_get_info(levelNum); @@ -173,41 +202,39 @@ const char *get_level_name_ascii(s16 courseNum, s16 levelNum, s16 areaIndex, s16 } } - if (!hasCustomName && courseNum >= COURSE_MIN && courseNum < COURSE_MAX) { - void **courseNameTbl = NULL; -#ifdef VERSION_EU - switch (gInGameLanguage) { - case LANGUAGE_ENGLISH: courseNameTbl = segmented_to_virtual(course_name_table_eu_en); break; - case LANGUAGE_FRENCH: courseNameTbl = segmented_to_virtual(course_name_table_eu_fr); break; - case LANGUAGE_GERMAN: courseNameTbl = segmented_to_virtual(course_name_table_eu_de); break; - } -#else - courseNameTbl = segmented_to_virtual(seg2_course_name_table); -#endif - const u8 *courseName = segmented_to_virtual(courseNameTbl[courseNum - COURSE_BOB]); - convert_string_sm64_to_ascii(output, courseName + 3); + if (gReplacedActNameTable[courseNum]->modIndex != -1) { + snprintf(output, 256, "%s", gReplacedActNameTable[courseNum]->name); } - - // Castle level - else if (!hasCustomName && courseNum == COURSE_NONE) { - switch (levelNum) { - case LEVEL_CASTLE: { - switch (areaIndex) { - case 1: snprintf(output, 256, "Castle Main Floor"); break; - case 2: snprintf(output, 256, "Castle Upper Floor"); break; - case 3: snprintf(output, 256, "Castle Basement"); break; - default: snprintf(output, 256, "Castle Purgatory"); break; - } - } break; - case LEVEL_CASTLE_GROUNDS: snprintf(output, 256, "Castle Grounds"); break; - case LEVEL_CASTLE_COURTYARD: snprintf(output, 256, "Castle Courtyard"); break; - default: snprintf(output, 256, "Peach's Castle"); - } - } - - // Default + else if (!hasCustomName) { - snprintf(output, 256, "Peach's Castle"); + if (COURSE_IS_VALID_COURSE(courseNum)) { + void **courseNameTbl = get_course_name_table(); + const u8 *courseName = segmented_to_virtual(courseNameTbl[courseNum - COURSE_BOB]); + convert_string_sm64_to_ascii(output, courseName + 3); + charCase = MIN(charCase, 0); // Don't need to capitalize vanilla course names + } + + // Castle level + else if (courseNum == COURSE_NONE) { + switch (levelNum) { + case LEVEL_CASTLE: { + switch (areaIndex) { + case 1: snprintf(output, 256, "Castle Main Floor"); break; + case 2: snprintf(output, 256, "Castle Upper Floor"); break; + case 3: snprintf(output, 256, "Castle Basement"); break; + default: snprintf(output, 256, "Castle Purgatory"); break; + } + } break; + case LEVEL_CASTLE_GROUNDS: snprintf(output, 256, "Castle Grounds"); break; + case LEVEL_CASTLE_COURTYARD: snprintf(output, 256, "Castle Courtyard"); break; + default: snprintf(output, 256, "Peach's Castle"); + } + } + + // Default + else { + snprintf(output, 256, "Peach's Castle"); + } } // Capitalize or decapitalize text @@ -221,7 +248,8 @@ const char *get_level_name_ascii(s16 courseNum, s16 levelNum, s16 areaIndex, s16 const u8 *get_level_name_sm64(s16 courseNum, s16 levelNum, s16 areaIndex, s16 charCase) { static u8 output[256]; - const char *levelName = get_level_name_ascii(courseNum, levelNum, areaIndex, charCase); + char levelName[256]; + snprintf(levelName, 256, " %d %s", courseNum, (char*) get_level_name_ascii(courseNum, levelNum, areaIndex, charCase)); convert_string_ascii_to_sm64(output, levelName); return output; } @@ -233,28 +261,24 @@ const char *get_level_name(s16 courseNum, s16 levelNum, s16 areaIndex) { const char *get_star_name_ascii(s16 courseNum, s16 starNum, s16 charCase) { static char output[256]; + if (gReplacedActNameTable[courseNum]->actName && gReplacedActNameTable[courseNum]->actName[starNum - 1].isModified) { + snprintf(output, 256, "%s", gReplacedActNameTable[courseNum]->actName[starNum - 1].name); + } + // Main courses: BOB to RR - if (COURSE_IS_MAIN_COURSE(courseNum)) { + else if (COURSE_IS_MAIN_COURSE(courseNum)) { if (starNum >= 1 && starNum <= 6) { - void **actNameTable = NULL; -#ifdef VERSION_EU - switch (gInGameLanguage) { - case LANGUAGE_ENGLISH: actNameTable = segmented_to_virtual(act_name_table_eu_en); break; - case LANGUAGE_FRENCH: actNameTable = segmented_to_virtual(act_name_table_eu_fr); break; - case LANGUAGE_GERMAN: actNameTable = segmented_to_virtual(act_name_table_eu_de); break; - } -#else - actNameTable = segmented_to_virtual(seg2_act_name_table); -#endif + void **actNameTable = get_act_name_table(); const u8 *starName = segmented_to_virtual(actNameTable[(courseNum - COURSE_BOB) * 6 + (starNum - 1)]); convert_string_sm64_to_ascii(output, starName); + charCase = MIN(charCase, 0); // Don't need to capitalize vanilla act names } else if (starNum == 7) { - snprintf(output, 256, "%d Coins Star", (s32) gLevelValues.coinsRequiredForCoinStar); + snprintf(output, 256, "%d Coins Star", gLevelValues.coinsRequiredForCoinStar); } else { snprintf(output, 256, "A Secret Star!"); } } - + // Castle stars: Toads' and Mips' else if (courseNum == COURSE_NONE) { switch (starNum) { @@ -271,7 +295,7 @@ const char *get_star_name_ascii(s16 courseNum, s16 starNum, s16 charCase) { else if (courseNum <= COURSE_MAX) { snprintf(output, 256, "Star %d", starNum); } - + // Default else { snprintf(output, 256, "A Secret Star!"); diff --git a/src/game/level_info.h b/src/game/level_info.h index b0c81722..372921d2 100644 --- a/src/game/level_info.h +++ b/src/game/level_info.h @@ -3,6 +3,8 @@ #include +void *get_course_name_table(); +void *get_act_name_table(); const char *get_level_name_ascii(s16 courseNum, s16 levelNum, s16 areaIndex, s16 charCase); const u8 *get_level_name_sm64(s16 courseNum, s16 levelNum, s16 areaIndex, s16 charCase); const char *get_level_name(s16 courseNum, s16 levelNum, s16 areaIndex); diff --git a/src/game/level_update.c b/src/game/level_update.c index 53de7810..b409522a 100644 --- a/src/game/level_update.c +++ b/src/game/level_update.c @@ -69,7 +69,7 @@ s16 gChangeLevelTransition = -1; s16 gChangeActNum = -1; static bool sFirstCastleGroundsMenu = true; -static bool sIsDemoActive = false; +bool gIsDemoActive = false; bool gInPlayerMenu = false; static u16 gDemoCountdown = 0; static int sDemoNumber = -1; @@ -201,7 +201,7 @@ s32 sDelayedWarpArg; s16 unusedEULevelUpdateBss1; #endif s8 sTimerRunning; -s8 gNeverEnteredCastle; +bool gNeverEnteredCastle; struct MarioState *gMarioState = &gMarioStates[0]; u8 unused1[4] = { 0 }; @@ -1158,10 +1158,10 @@ bool find_demo_number(void) { } static void start_demo(void) { - if (sIsDemoActive) { - sIsDemoActive = false; + if (gIsDemoActive) { + gIsDemoActive = false; } else { - sIsDemoActive = true; + gIsDemoActive = true; if (find_demo_number()) { gChangeLevel = gCurrLevelNum; @@ -1173,14 +1173,14 @@ static void start_demo(void) { load_patchable_table(&gDemo, sDemoNumber); gCurrDemoInput = ((struct DemoInput *) gDemo.targetAnim); } else { - sIsDemoActive = false; + gIsDemoActive = false; } } } void stop_demo(UNUSED struct DjuiBase* caller) { - if (sIsDemoActive) { - sIsDemoActive = false; + if (gIsDemoActive) { + gIsDemoActive = false; gCurrDemoInput = NULL; gChangeLevel = gCurrLevelNum; gDemoCountdown = 0; @@ -1197,22 +1197,26 @@ s32 play_mode_normal(void) { if (gCurrDemoInput != NULL) { print_intro_text(); if (gPlayer1Controller->buttonPressed & END_DEMO) { - level_trigger_warp(gMarioState, - gCurrLevelNum == LEVEL_PSS ? WARP_OP_DEMO_END : WARP_OP_DEMO_NEXT); - } else if (!gWarpTransition.isActive && sDelayedWarpOp == WARP_OP_NONE - && (gPlayer1Controller->buttonPressed & START_BUTTON)) { + level_trigger_warp(gMarioState, gCurrLevelNum == LEVEL_PSS ? WARP_OP_DEMO_END : WARP_OP_DEMO_NEXT); + } else if (!gWarpTransition.isActive && sDelayedWarpOp == WARP_OP_NONE && (gPlayer1Controller->buttonPressed & START_BUTTON)) { gPressedStart = 1; level_trigger_warp(gMarioState, WARP_OP_DEMO_NEXT); } } } else { - if (gDjuiInMainMenu && gCurrDemoInput == NULL && configMenuDemos && !gInPlayerMenu) { - if ((++gDemoCountdown) == PRESS_START_DEMO_TIMER && (find_demo_number() && (sDemoNumber <= 6 && sDemoNumber > -1))) { - start_demo(); - } + if (gDjuiInMainMenu && + gCurrDemoInput == NULL && + configMenuDemos && + !gInPlayerMenu && + (++gDemoCountdown) == PRESS_START_DEMO_TIMER && + (find_demo_number() && (sDemoNumber <= 6 && sDemoNumber > -1)) && + gNetworkType == NT_NONE) { + start_demo(); } - if (((gCurrDemoInput != NULL) && (gPlayer1Controller->buttonPressed & END_DEMO || !sIsDemoActive || !gDjuiInMainMenu || gNetworkType != NT_NONE || gInPlayerMenu)) || (gCurrDemoInput == NULL && sIsDemoActive)) { + if (((gCurrDemoInput != NULL) && + (gPlayer1Controller->buttonPressed & END_DEMO || !gIsDemoActive || !gDjuiInMainMenu || gNetworkType != NT_NONE || gInPlayerMenu)) || + (gCurrDemoInput == NULL && gIsDemoActive)) { gPlayer1Controller->buttonPressed &= ~END_DEMO; stop_demo(NULL); } @@ -1442,7 +1446,7 @@ void update_menu_level(void) { // warp to level, this feels buggy if (gCurrLevelNum != curLevel) { - if (sIsDemoActive) { + if (gIsDemoActive) { stop_demo(NULL); } @@ -1450,7 +1454,7 @@ void update_menu_level(void) { gChangeActNum = 6; gDemoCountdown = 0; } - if (sIsDemoActive) { + if (gIsDemoActive) { return; } @@ -1462,7 +1466,7 @@ void update_menu_level(void) { // set sFirstCastleGroundsMenu to false to prevent wall hugging bug if (curLevel != LEVEL_CASTLE_GROUNDS) { - sFirstCastleGroundsMenu = false; + sFirstCastleGroundsMenu = false; } struct Object *o; @@ -1837,7 +1841,7 @@ s32 lvl_set_current_level(UNUSED s16 arg0, s32 levelNum) { sWarpCheckpointActive = FALSE; gCurrLevelNum = levelNum; - gCurrCourseNum = get_level_course_num(levelNum - 1); + gCurrCourseNum = get_level_course_num(levelNum); bool foundHook = false; bool hookUseActSelect = false; diff --git a/src/game/level_update.h b/src/game/level_update.h index dbc72957..336b6a7b 100644 --- a/src/game/level_update.h +++ b/src/game/level_update.h @@ -124,7 +124,7 @@ struct HudDisplay { }; extern struct HudDisplay gHudDisplay; -extern s8 gNeverEnteredCastle; +extern bool gNeverEnteredCastle; extern u32 gControlTimerStartNat; extern u32 gControlTimerStopNat; diff --git a/src/game/mario.c b/src/game/mario.c index f06407f0..272c3040 100644 --- a/src/game/mario.c +++ b/src/game/mario.c @@ -1577,6 +1577,7 @@ copyPlayerGoto:; if (m == m2) { continue; } find_floor(m2->pos[0], m2->pos[1], m2->pos[2], &floor2); if (floor2 == NULL) { continue; } + LOG_INFO("OOB! teleporting to player with local index %d", i); vec3f_copy(m->pos, m2->pos); copiedPlayer = TRUE; goto copyPlayerGoto; diff --git a/src/game/mario_actions_cutscene.c b/src/game/mario_actions_cutscene.c index 66e409be..64a75618 100644 --- a/src/game/mario_actions_cutscene.c +++ b/src/game/mario_actions_cutscene.c @@ -349,6 +349,7 @@ void cutscene_put_cap_on(struct MarioState *m) { m->flags &= ~MARIO_CAP_IN_HAND; m->flags |= MARIO_CAP_ON_HEAD; play_sound(SOUND_ACTION_UNKNOWN43E, m->marioObj->header.gfx.cameraToObject); + m->cap = 0; } /** @@ -524,10 +525,10 @@ s32 act_disappeared(struct MarioState *m) { s32 act_reading_automatic_dialog(struct MarioState *m) { if (m == NULL) { return TRUE; } - + // Increment our action state to continue our 'cutscene'. m->actionState++; - + if (m->actionState == 2) { enable_time_stop_if_alone(); } @@ -556,7 +557,7 @@ s32 act_reading_automatic_dialog(struct MarioState *m) { } else if (m->actionState == 25) { // finished action disable_time_stop(); if (gNeverEnteredCastle) { - gNeverEnteredCastle = FALSE; + gNeverEnteredCastle = false; play_cutscene_music(SEQUENCE_ARGS(0, SEQ_LEVEL_INSIDE_CASTLE)); } if (m->prevAction == ACT_STAR_DANCE_WATER) { @@ -567,7 +568,7 @@ s32 act_reading_automatic_dialog(struct MarioState *m) { } } } - + // apply head turn vec3s_set(m->marioBodyState->headAngle, m->actionTimer, 0, 0); return FALSE; @@ -575,9 +576,9 @@ s32 act_reading_automatic_dialog(struct MarioState *m) { s32 act_reading_sign(struct MarioState *m) { if (m == NULL) { return TRUE; } - + struct Object *marioObj = m->marioObj; - + // If anybody but us is reading a sign, // Don't handle their action state. if (m->playerIndex != 0) { @@ -628,11 +629,11 @@ s32 act_reading_sign(struct MarioState *m) { s32 act_debug_free_move(struct MarioState *m) { if (m == NULL) { return TRUE; } - + u32 action = ACT_IDLE; #ifndef DEVELOPMENT - if (gNetworkType == NT_SERVER && gServerSettings.enableCheats == 0 && m->action == ACT_DEBUG_FREE_MOVE) { + if (gServerSettings.enableCheats == 0) { if (m->pos[1] <= m->waterLevel - 100) { action = ACT_WATER_IDLE; } else { @@ -690,7 +691,7 @@ s32 act_debug_free_move(struct MarioState *m) { void general_star_dance_handler(struct MarioState *m, s32 isInWater) { if (m == NULL) { return; } - + if (m->actionState == 0) { switch (++m->actionTimer) { case 1: @@ -1149,7 +1150,7 @@ s32 act_warp_door_spawn(struct MarioState *m) { } } else if (m->usedObj == NULL || (m->usedObj->oAction == 0 || m->usedObj->oAction == 100)) { if (m->playerIndex == 0) { - if (gNeverEnteredCastle == TRUE && gCurrLevelNum == LEVEL_CASTLE) { + if (gNeverEnteredCastle && gCurrLevelNum == LEVEL_CASTLE) { set_mario_action(m, ACT_READING_AUTOMATIC_DIALOG, gBehaviorValues.dialogs.CastleEnterDialog); } else { set_mario_action(m, ACT_IDLE, 0); @@ -1722,7 +1723,7 @@ s32 act_shocked(struct MarioState *m) { s32 act_squished(struct MarioState *m) { if (m == NULL) { return TRUE; } - + f32 spaceUnderCeil; s16 surfAngle; s32 underSteepSurf = FALSE; // seems to be responsible for setting velocity? @@ -2534,7 +2535,7 @@ static void end_peach_cutscene_dialog_1(struct MarioState *m) { #endif sEndPeachAnimation = 6; break; - + #ifdef VERSION_SH case 111: #else @@ -2638,7 +2639,7 @@ static void end_peach_cutscene_dialog_2(struct MarioState *m) { #ifdef VERSION_SH case 65: -#else +#else case 45: #endif D_8032CBE8 = 1; diff --git a/src/game/options_menu.h b/src/game/options_menu.h deleted file mode 100644 index 9a174351..00000000 --- a/src/game/options_menu.h +++ /dev/null @@ -1,8 +0,0 @@ -#ifndef OPTIONS_MENU_H -#define OPTIONS_MENU_H - -void optmenu_draw(void); -void optmenu_draw_prompt(void); -void optmenu_toggle(void); - -#endif \ No newline at end of file diff --git a/src/game/paintings.c b/src/game/paintings.c index 5a32782d..a08b00ee 100644 --- a/src/game/paintings.c +++ b/src/game/paintings.c @@ -309,7 +309,7 @@ void patch_paintings_interpolated(f32 delta) { if (currPItem == NULL || currPItem == &paintingZero) { break; } - + } } @@ -916,7 +916,7 @@ void painting_update_floors(struct Painting *painting) { if (!consider) { continue; } - // floorEntered is true iff currFloor is true and lastFloor is false + // floorEntered is true if currFloor is true and lastFloor is false // (Mario just entered the floor on this frame) s8 entered = (painting->ripples.lastFloors[i] ^ painting->ripples.currFloors[i]) & painting->ripples.currFloors[i]; if (entered) { @@ -1023,7 +1023,7 @@ s16 calculate_ripple_at_point(struct Painting *painting, f32 posX, f32 posY) { // For calculating the highest ripple, ans needs to start extremely low otherwise ripples under 0 won't be counted s16 ans = multiRippleMode == HIGHEST_RIPPLE ? -32000 : 0; bool flat = true; - + if (multiRippleMode != SINGLE_RIPPLE) { // If multi ripple mode for (s32 i = 0; i < MAX_PLAYERS + 1; i++) { @@ -1791,7 +1791,7 @@ Gfx *geo_painting_update(s32 callContext, UNUSED struct GraphNode *node, UNUSED } else { gLastPaintingUpdateCounter = gPaintingUpdateCounter; gPaintingUpdateCounter = gAreaUpdateCounter; - + // Store Mario's floor and position if (gMarioObject) { find_floor(gMarioObject->oPosX, gMarioObject->oPosY, gMarioObject->oPosZ, &surface); diff --git a/src/game/save_file.c b/src/game/save_file.c index 5b013770..b981b4fb 100644 --- a/src/game/save_file.c +++ b/src/game/save_file.c @@ -63,6 +63,8 @@ s8 get_level_course_num(s16 levelNum) { return (info ? info->courseNum : COURSE_NONE); } + levelNum = levelNum - 1; + if (INVALID_LEVEL_NUM(levelNum)) { return COURSE_NONE; } @@ -392,7 +394,7 @@ void save_file_do_save(s32 fileIndex, s8 forceSave) { // Write to EEPROM write_eeprom_savefile(fileIndex, 0, 2); - + gSaveFileModified = FALSE; } save_main_menu_data(); @@ -412,7 +414,7 @@ void save_file_erase(s32 fileIndex) { void save_file_reload(u8 load_all) { gSaveFileModified = TRUE; update_all_mario_stars(); - + if (load_all == TRUE) { save_file_load_all(TRUE); save_file_do_save(gCurrSaveFileNum-1, TRUE); @@ -818,7 +820,7 @@ void check_if_should_set_warp_checkpoint(struct WarpNode *warpNode) { */ s32 check_warp_checkpoint(struct WarpNode *warpNode) { s16 warpCheckpointActive = FALSE; - s16 currCourseNum = get_level_course_num((warpNode->destLevel & 0x7F) - 1); + s16 currCourseNum = get_level_course_num(warpNode->destLevel & 0x7F); // gSavedCourseNum is only used in this function. if (gWarpCheckpoint.courseNum != COURSE_NONE && gSavedCourseNum == currCourseNum diff --git a/src/menu/star_select.c b/src/menu/star_select.c index d1d993ca..d0aaafec 100644 --- a/src/menu/star_select.c +++ b/src/menu/star_select.c @@ -25,6 +25,7 @@ #include "pc/network/network.h" #include "engine/math_util.h" #include "game/print.h" +#include "game/level_info.h" /** * @file star_select.c @@ -278,15 +279,9 @@ void print_act_selector_strings(void) { #endif unsigned char starNumbers[] = { TEXT_ZERO }; -#ifdef VERSION_EU - u8 **levelNameTbl; - u8 *currLevelName; - u8 **actNameTbl; -#else - u8 **levelNameTbl = segmented_to_virtual(seg2_course_name_table); + u8 **levelNameTbl = get_course_name_table(); u8 *currLevelName = segmented_to_virtual(levelNameTbl[gCurrCourseNum - 1]); - u8 **actNameTbl = segmented_to_virtual(seg2_act_name_table); -#endif + u8 **actNameTbl = get_act_name_table(); u8 *selectedActName; #ifndef VERSION_EU s16 lvlNameX; @@ -299,24 +294,6 @@ void print_act_selector_strings(void) { create_dl_ortho_matrix(); -#ifdef VERSION_EU - switch (language) { - case LANGUAGE_ENGLISH: - actNameTbl = segmented_to_virtual(act_name_table_eu_en); - levelNameTbl = segmented_to_virtual(course_name_table_eu_en); - break; - case LANGUAGE_FRENCH: - actNameTbl = segmented_to_virtual(act_name_table_eu_fr); - levelNameTbl = segmented_to_virtual(course_name_table_eu_fr); - break; - case LANGUAGE_GERMAN: - actNameTbl = segmented_to_virtual(act_name_table_eu_de); - levelNameTbl = segmented_to_virtual(course_name_table_eu_de); - break; - } - currLevelName = segmented_to_virtual(levelNameTbl[gCurrCourseNum - 1]); -#endif - // Print the coin highscore. gSPDisplayList(gDisplayListHead++, dl_rgba16_text_begin); gDPSetEnvColor(gDisplayListHead++, 255, 255, 255, 255); diff --git a/src/pc/chat_commands.c b/src/pc/chat_commands.c index a1039547..989c7ef6 100644 --- a/src/pc/chat_commands.c +++ b/src/pc/chat_commands.c @@ -13,7 +13,6 @@ #include "dev/chat.h" #endif -extern bool gIsModerator; static enum ChatConfirmCommand sConfirming = CCC_NONE; static u8 sConfirmPlayerIndex = 0; @@ -55,14 +54,15 @@ static void chat_construct_player_message(struct NetworkPlayer* np, char* msg) { } bool exec_chat_command(char* command) { + struct NetworkPlayer* npl = &gNetworkPlayers[0]; enum ChatConfirmCommand ccc = sConfirming; sConfirming = CCC_NONE; if (ccc != CCC_NONE && strcmp("/confirm", command) == 0) { - if (gNetworkType == NT_SERVER || gIsModerator) { + struct NetworkPlayer* np = &gNetworkPlayers[sConfirmPlayerIndex]; + if (!np->connected) return true; + if (gNetworkType == NT_SERVER || npl->moderator) { if (ccc == CCC_KICK) { - struct NetworkPlayer* np = &gNetworkPlayers[sConfirmPlayerIndex]; - if (!np->connected) { return true; } chat_construct_player_message(np, DLANG(CHAT, KICKING)); if (gNetworkType == NT_SERVER) { network_send_kick(np->localIndex, EKT_KICKED); @@ -73,10 +73,8 @@ bool exec_chat_command(char* command) { return true; } } - if (gNetworkType == NT_SERVER || gIsModerator) { + if (gNetworkType == NT_SERVER || npl->moderator) { if (ccc == CCC_BAN) { - struct NetworkPlayer* np = &gNetworkPlayers[sConfirmPlayerIndex]; - if (!np->connected) { return true; } chat_construct_player_message(np, DLANG(CHAT, BANNING)); if (gNetworkType == NT_SERVER) { network_send_kick(np->localIndex, EKT_BANNED); @@ -89,8 +87,6 @@ bool exec_chat_command(char* command) { } } if (gNetworkType == NT_SERVER && ccc == CCC_PERMBAN) { - struct NetworkPlayer* np = &gNetworkPlayers[sConfirmPlayerIndex]; - if (!np->connected) { return true; } chat_construct_player_message(np, DLANG(CHAT, PERM_BANNING)); network_send_kick(np->localIndex, EKT_BANNED); ban_list_add(gNetworkSystem->get_id_str(np->localIndex), true); @@ -98,9 +94,8 @@ bool exec_chat_command(char* command) { return true; } if (gNetworkType == NT_SERVER && ccc == CCC_MODERATOR) { - struct NetworkPlayer* np = &gNetworkPlayers[sConfirmPlayerIndex]; - if (!np->connected) { return true; } chat_construct_player_message(np, DLANG(CHAT, ADD_MODERATOR)); + np->moderator = true; network_send_moderator(np->localIndex); moderator_list_add(gNetworkSystem->get_id_str(np->localIndex), true); return true; @@ -125,7 +120,7 @@ bool exec_chat_command(char* command) { } if (str_starts_with("/kick ", command)) { - if (gNetworkType != NT_SERVER && !gIsModerator) { + if (gNetworkType != NT_SERVER && !npl->moderator) { djui_chat_message_create(DLANG(CHAT, NO_PERMS)); return true; } @@ -148,7 +143,7 @@ bool exec_chat_command(char* command) { } if (str_starts_with("/ban ", command)) { - if (gNetworkType != NT_SERVER && !gIsModerator) { + if (gNetworkType != NT_SERVER && !npl->moderator) { djui_chat_message_create(DLANG(CHAT, NO_PERMS)); return true; } @@ -171,7 +166,7 @@ bool exec_chat_command(char* command) { } if (str_starts_with("/permban ", command)) { - if (gNetworkType != NT_SERVER && !gIsModerator) { + if (gNetworkType != NT_SERVER && !npl->moderator) { djui_chat_message_create(DLANG(CHAT, NO_PERMS)); return true; } @@ -226,15 +221,18 @@ bool exec_chat_command(char* command) { void display_chat_commands(void) { djui_chat_message_create(DLANG(CHAT, PLAYERS_DESC)); - if (gNetworkType == NT_SERVER || gIsModerator) { + if (gNetworkType == NT_SERVER || gNetworkPlayers[0].moderator) { djui_chat_message_create(DLANG(CHAT, KICK_DESC)); djui_chat_message_create(DLANG(CHAT, BAN_DESC)); - djui_chat_message_create(DLANG(CHAT, PERM_BAN_DESC)); - djui_chat_message_create(DLANG(CHAT, MOD_DESC)); + + if (gNetworkType == NT_SERVER) { + djui_chat_message_create(DLANG(CHAT, PERM_BAN_DESC)); + djui_chat_message_create(DLANG(CHAT, MOD_DESC)); + } } #if defined(DEVELOPMENT) dev_display_chat_commands(); #endif if (sConfirming != CCC_NONE) { djui_chat_message_create("/confirm"); } smlua_display_chat_commands(); -} \ No newline at end of file +} diff --git a/src/pc/cliopts.c b/src/pc/cliopts.c index 3b8fec98..04cf0cd7 100644 --- a/src/pc/cliopts.c +++ b/src/pc/cliopts.c @@ -43,7 +43,7 @@ static inline int arg_uint(UNUSED const char *name, const char *value, unsigned return 1; } -void parse_cli_opts(int argc, char* argv[]) { +inline void parse_cli_opts(int argc, char* argv[]) { // Initialize options with false values. memset(&gCLIOpts, 0, sizeof(gCLIOpts)); diff --git a/src/pc/configfile.c b/src/pc/configfile.c index 25169cca..9c9cef4b 100644 --- a/src/pc/configfile.c +++ b/src/pc/configfile.c @@ -113,8 +113,8 @@ unsigned int configCameraPan = 0; unsigned int configCameraDegrade = 50; // 0 - 100% bool configCameraInvertX = false; bool configCameraInvertY = true; -bool configEnableCamera = true; -bool configCameraAnalog = true; +bool configEnableCamera = false; +bool configCameraAnalog = false; bool configCameraMouse = false; #endif bool configSkipIntro = 0; diff --git a/src/pc/crash_handler.c b/src/pc/crash_handler.c index 5e431c06..d5e5b59e 100644 --- a/src/pc/crash_handler.c +++ b/src/pc/crash_handler.c @@ -27,6 +27,7 @@ char gLastRemoteBhv[256] = ""; #include "pc/gfx/gfx_rendering_api.h" #include "pc/mods/mods.h" #include "pc/debuglog.h" +#include "pc/pc_main.h" typedef struct { s32 x, y; @@ -659,16 +660,12 @@ static void crash_handler(const int signalNum, siginfo_t *info, ucontext_t *cont // Main loop while (true) { -#if defined(WAPI_SDL1) || defined(WAPI_SDL2) - gfx_sdl.main_loop(crash_handler_produce_one_frame); -#elif defined(WAPI_DXGI) - gfx_dxgi.main_loop(crash_handler_produce_one_frame); -#endif + WAPI.main_loop(crash_handler_produce_one_frame); } exit(0); } -__attribute__((constructor)) static void init_crash_handler() { +AT_STARTUP static void init_crash_handler() { #ifdef _WIN32 // Windows SetUnhandledExceptionFilter(crash_handler); diff --git a/src/pc/discord/discord_activity.c b/src/pc/discord/discord_activity.c index bcac8025..f1bc9bdc 100644 --- a/src/pc/discord/discord_activity.c +++ b/src/pc/discord/discord_activity.c @@ -136,18 +136,18 @@ void discord_activity_update(void) { } void discord_activity_update_check(void) { +#ifdef COOPNET if (sQueuedLobby > 0) { if (--sQueuedLobby == 0) { -#ifdef COOPNET gCoopNetDesiredLobby = sQueuedLobbyId; snprintf(gCoopNetPassword, 64, "%s", sQueuedLobbyPassword); network_reset_reconnect_and_rehost(); network_set_system(NS_COOPNET); network_init(NT_CLIENT, false); djui_panel_join_message_create(NULL); -#endif } } +#endif if (gNetworkType == NT_NONE) { return; } bool shouldUpdate = false; diff --git a/src/pc/djui/djui_panel.h b/src/pc/djui/djui_panel.h index ec184f70..fa5c22c6 100644 --- a/src/pc/djui/djui_panel.h +++ b/src/pc/djui/djui_panel.h @@ -3,11 +3,13 @@ #define DJUI_DEFAULT_PANEL_WIDTH (500.0f + (16 * 2.0f)) #define DJUI_PANEL_HEADER_OFFSET (-16) +#define DJUI_PANEL_MOVE_MAX 1.0f struct DjuiPanel { struct DjuiBase* base; struct DjuiPanel* parent; struct DjuiBase* defaultElementBase; + bool temporary; void (*on_panel_destroy)(struct DjuiBase*); }; diff --git a/src/pc/lua/smlua_functions_autogen.c b/src/pc/lua/smlua_functions_autogen.c index 728315e8..643bfe04 100644 --- a/src/pc/lua/smlua_functions_autogen.c +++ b/src/pc/lua/smlua_functions_autogen.c @@ -27294,6 +27294,48 @@ int smlua_func_smlua_audio_utils_reset_all(UNUSED lua_State* L) { // smlua_collision_utils.h // ///////////////////////////// +int smlua_func_collision_find_ceil(lua_State* L) { + if (L == NULL) { return 0; } + + int top = lua_gettop(L); + if (top != 3) { + LOG_LUA_LINE("Improper param count for '%s': Expected %u, Received %u", "collision_find_ceil", 3, top); + return 0; + } + + f32 x = smlua_to_number(L, 1); + if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 1, "collision_find_ceil"); return 0; } + f32 y = smlua_to_number(L, 2); + if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 2, "collision_find_ceil"); return 0; } + f32 z = smlua_to_number(L, 3); + if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 3, "collision_find_ceil"); return 0; } + + smlua_push_object(L, LOT_SURFACE, collision_find_ceil(x, y, z)); + + return 1; +} + +int smlua_func_collision_find_floor(lua_State* L) { + if (L == NULL) { return 0; } + + int top = lua_gettop(L); + if (top != 3) { + LOG_LUA_LINE("Improper param count for '%s': Expected %u, Received %u", "collision_find_floor", 3, top); + return 0; + } + + f32 x = smlua_to_number(L, 1); + if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 1, "collision_find_floor"); return 0; } + f32 y = smlua_to_number(L, 2); + if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 2, "collision_find_floor"); return 0; } + f32 z = smlua_to_number(L, 3); + if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 3, "collision_find_floor"); return 0; } + + smlua_push_object(L, LOT_SURFACE, collision_find_floor(x, y, z)); + + return 1; +} + int smlua_func_collision_find_surface_on_ray(lua_State* L) { if (L == NULL) { return 0; } @@ -27475,6 +27517,23 @@ int smlua_func_smlua_level_util_get_info(lua_State* L) { return 1; } +int smlua_func_smlua_level_util_get_info_from_course_num(lua_State* L) { + if (L == NULL) { return 0; } + + int top = lua_gettop(L); + if (top != 1) { + LOG_LUA_LINE("Improper param count for '%s': Expected %u, Received %u", "smlua_level_util_get_info_from_course_num", 1, top); + return 0; + } + + u8 courseNum = smlua_to_integer(L, 1); + if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 1, "smlua_level_util_get_info_from_course_num"); return 0; } + + smlua_push_object(L, LOT_CUSTOMLEVELINFO, smlua_level_util_get_info_from_course_num(courseNum)); + + return 1; +} + int smlua_func_smlua_level_util_get_info_from_short_name(lua_State* L) { if (L == NULL) { return 0; } @@ -29844,6 +29903,84 @@ int smlua_func_spawn_sync_object(lua_State* L) { // smlua_text_utils.h // //////////////////////// +int smlua_func_smlua_text_utils_act_name_get(lua_State* L) { + if (L == NULL) { return 0; } + + int top = lua_gettop(L); + if (top != 2) { + LOG_LUA_LINE("Improper param count for '%s': Expected %u, Received %u", "smlua_text_utils_act_name_get", 2, top); + return 0; + } + + s16 courseNum = smlua_to_integer(L, 1); + if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 1, "smlua_text_utils_act_name_get"); return 0; } + u8 actNum = smlua_to_integer(L, 2); + if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 2, "smlua_text_utils_act_name_get"); return 0; } + + lua_pushstring(L, smlua_text_utils_act_name_get(courseNum, actNum)); + + return 1; +} + +int smlua_func_smlua_text_utils_act_name_is_modified(lua_State* L) { + if (L == NULL) { return 0; } + + int top = lua_gettop(L); + if (top != 2) { + LOG_LUA_LINE("Improper param count for '%s': Expected %u, Received %u", "smlua_text_utils_act_name_is_modified", 2, top); + return 0; + } + + s16 courseNum = smlua_to_integer(L, 1); + if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 1, "smlua_text_utils_act_name_is_modified"); return 0; } + u8 actNum = smlua_to_integer(L, 2); + if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 2, "smlua_text_utils_act_name_is_modified"); return 0; } + + lua_pushboolean(L, smlua_text_utils_act_name_is_modified(courseNum, actNum)); + + return 1; +} + +int smlua_func_smlua_text_utils_act_name_replace(lua_State* L) { + if (L == NULL) { return 0; } + + int top = lua_gettop(L); + if (top != 3) { + LOG_LUA_LINE("Improper param count for '%s': Expected %u, Received %u", "smlua_text_utils_act_name_replace", 3, top); + return 0; + } + + s16 courseNum = smlua_to_integer(L, 1); + if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 1, "smlua_text_utils_act_name_replace"); return 0; } + u8 actNum = smlua_to_integer(L, 2); + if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 2, "smlua_text_utils_act_name_replace"); return 0; } + const char* name = smlua_to_string(L, 3); + if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 3, "smlua_text_utils_act_name_replace"); return 0; } + + smlua_text_utils_act_name_replace(courseNum, actNum, name); + + return 1; +} + +int smlua_func_smlua_text_utils_act_name_reset(lua_State* L) { + if (L == NULL) { return 0; } + + int top = lua_gettop(L); + if (top != 2) { + LOG_LUA_LINE("Improper param count for '%s': Expected %u, Received %u", "smlua_text_utils_act_name_reset", 2, top); + return 0; + } + + s16 courseNum = smlua_to_integer(L, 1); + if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 1, "smlua_text_utils_act_name_reset"); return 0; } + u8 actNum = smlua_to_integer(L, 2); + if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 2, "smlua_text_utils_act_name_reset"); return 0; } + + smlua_text_utils_act_name_reset(courseNum, actNum); + + return 1; +} + int smlua_func_smlua_text_utils_castle_secret_stars_replace(lua_State* L) { if (L == NULL) { return 0; } @@ -29892,6 +30029,76 @@ int smlua_func_smlua_text_utils_course_acts_replace(lua_State* L) { return 1; } +int smlua_func_smlua_text_utils_course_name_get(lua_State* L) { + if (L == NULL) { return 0; } + + int top = lua_gettop(L); + if (top != 1) { + LOG_LUA_LINE("Improper param count for '%s': Expected %u, Received %u", "smlua_text_utils_course_name_get", 1, top); + return 0; + } + + s16 courseNum = smlua_to_integer(L, 1); + if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 1, "smlua_text_utils_course_name_get"); return 0; } + + lua_pushstring(L, smlua_text_utils_course_name_get(courseNum)); + + return 1; +} + +int smlua_func_smlua_text_utils_course_name_mod_index(lua_State* L) { + if (L == NULL) { return 0; } + + int top = lua_gettop(L); + if (top != 1) { + LOG_LUA_LINE("Improper param count for '%s': Expected %u, Received %u", "smlua_text_utils_course_name_mod_index", 1, top); + return 0; + } + + s16 courseNum = smlua_to_integer(L, 1); + if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 1, "smlua_text_utils_course_name_mod_index"); return 0; } + + lua_pushinteger(L, smlua_text_utils_course_name_mod_index(courseNum)); + + return 1; +} + +int smlua_func_smlua_text_utils_course_name_replace(lua_State* L) { + if (L == NULL) { return 0; } + + int top = lua_gettop(L); + if (top != 2) { + LOG_LUA_LINE("Improper param count for '%s': Expected %u, Received %u", "smlua_text_utils_course_name_replace", 2, top); + return 0; + } + + s16 courseNum = smlua_to_integer(L, 1); + if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 1, "smlua_text_utils_course_name_replace"); return 0; } + const char* name = smlua_to_string(L, 2); + if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 2, "smlua_text_utils_course_name_replace"); return 0; } + + smlua_text_utils_course_name_replace(courseNum, name); + + return 1; +} + +int smlua_func_smlua_text_utils_course_name_reset(lua_State* L) { + if (L == NULL) { return 0; } + + int top = lua_gettop(L); + if (top != 1) { + LOG_LUA_LINE("Improper param count for '%s': Expected %u, Received %u", "smlua_text_utils_course_name_reset", 1, top); + return 0; + } + + s16 courseNum = smlua_to_integer(L, 1); + if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 1, "smlua_text_utils_course_name_reset"); return 0; } + + smlua_text_utils_course_name_reset(courseNum); + + return 1; +} + int smlua_func_smlua_text_utils_dialog_replace(lua_State* L) { if (L == NULL) { return 0; } @@ -29953,21 +30160,6 @@ int smlua_func_smlua_text_utils_get_language(UNUSED lua_State* L) { return 1; } -int smlua_func_smlua_text_utils_reset_all(UNUSED lua_State* L) { - if (L == NULL) { return 0; } - - int top = lua_gettop(L); - if (top != 0) { - LOG_LUA_LINE("Improper param count for '%s': Expected %u, Received %u", "smlua_text_utils_reset_all", 0, top); - return 0; - } - - - smlua_text_utils_reset_all(); - - return 1; -} - int smlua_func_smlua_text_utils_secret_star_replace(lua_State* L) { if (L == NULL) { return 0; } @@ -32135,6 +32327,8 @@ void smlua_bind_functions_autogen(void) { smlua_bind_function(L, "smlua_audio_utils_reset_all", smlua_func_smlua_audio_utils_reset_all); // smlua_collision_utils.h + smlua_bind_function(L, "collision_find_ceil", smlua_func_collision_find_ceil); + smlua_bind_function(L, "collision_find_floor", smlua_func_collision_find_floor); smlua_bind_function(L, "collision_find_surface_on_ray", smlua_func_collision_find_surface_on_ray); smlua_bind_function(L, "collision_get_temp_wall_collision_data", smlua_func_collision_get_temp_wall_collision_data); smlua_bind_function(L, "get_water_surface_pseudo_floor", smlua_func_get_water_surface_pseudo_floor); @@ -32148,6 +32342,7 @@ void smlua_bind_functions_autogen(void) { smlua_bind_function(L, "level_register", smlua_func_level_register); smlua_bind_function(L, "smlua_level_util_change_area", smlua_func_smlua_level_util_change_area); smlua_bind_function(L, "smlua_level_util_get_info", smlua_func_smlua_level_util_get_info); + smlua_bind_function(L, "smlua_level_util_get_info_from_course_num", smlua_func_smlua_level_util_get_info_from_course_num); smlua_bind_function(L, "smlua_level_util_get_info_from_short_name", smlua_func_smlua_level_util_get_info_from_short_name); smlua_bind_function(L, "warp_exit_level", smlua_func_warp_exit_level); smlua_bind_function(L, "warp_restart_level", smlua_func_warp_restart_level); @@ -32291,12 +32486,19 @@ void smlua_bind_functions_autogen(void) { smlua_bind_function(L, "spawn_sync_object", smlua_func_spawn_sync_object); // smlua_text_utils.h + smlua_bind_function(L, "smlua_text_utils_act_name_get", smlua_func_smlua_text_utils_act_name_get); + smlua_bind_function(L, "smlua_text_utils_act_name_is_modified", smlua_func_smlua_text_utils_act_name_is_modified); + smlua_bind_function(L, "smlua_text_utils_act_name_replace", smlua_func_smlua_text_utils_act_name_replace); + smlua_bind_function(L, "smlua_text_utils_act_name_reset", smlua_func_smlua_text_utils_act_name_reset); smlua_bind_function(L, "smlua_text_utils_castle_secret_stars_replace", smlua_func_smlua_text_utils_castle_secret_stars_replace); smlua_bind_function(L, "smlua_text_utils_course_acts_replace", smlua_func_smlua_text_utils_course_acts_replace); + smlua_bind_function(L, "smlua_text_utils_course_name_get", smlua_func_smlua_text_utils_course_name_get); + smlua_bind_function(L, "smlua_text_utils_course_name_mod_index", smlua_func_smlua_text_utils_course_name_mod_index); + smlua_bind_function(L, "smlua_text_utils_course_name_replace", smlua_func_smlua_text_utils_course_name_replace); + smlua_bind_function(L, "smlua_text_utils_course_name_reset", smlua_func_smlua_text_utils_course_name_reset); smlua_bind_function(L, "smlua_text_utils_dialog_replace", smlua_func_smlua_text_utils_dialog_replace); smlua_bind_function(L, "smlua_text_utils_extra_text_replace", smlua_func_smlua_text_utils_extra_text_replace); smlua_bind_function(L, "smlua_text_utils_get_language", smlua_func_smlua_text_utils_get_language); - smlua_bind_function(L, "smlua_text_utils_reset_all", smlua_func_smlua_text_utils_reset_all); smlua_bind_function(L, "smlua_text_utils_secret_star_replace", smlua_func_smlua_text_utils_secret_star_replace); // sound_init.h diff --git a/src/pc/lua/smlua_utils.c b/src/pc/lua/smlua_utils.c index f4bf9cd3..52346d84 100644 --- a/src/pc/lua/smlua_utils.c +++ b/src/pc/lua/smlua_utils.c @@ -417,13 +417,15 @@ void smlua_push_object(lua_State* L, u16 lot, void* p) { lua_pushnil(L); return; } + u64 pointer = (uintptr_t) p; + // add to allowlist - smlua_cobject_allowlist_add(lot, (u64)(intptr_t)p); + smlua_cobject_allowlist_add(lot, pointer); // get a cobject from a function lua_getglobal(L, "_NewCObject"); // Get the function by its global name lua_pushinteger(L, lot); - lua_pushinteger(L, (u64)(intptr_t)p); + lua_pushinteger(L, pointer); if (lua_pcall(L, 2, 1, 0) != LUA_OK) { LOG_ERROR("Error calling Lua function: %s\n", lua_tostring(L, -1)); @@ -436,12 +438,13 @@ void smlua_push_pointer(lua_State* L, u16 lvt, void* p) { return; } - smlua_cpointer_allowlist_add(lvt, (u64)(intptr_t)p); + u64 pointer = (uintptr_t) p; + smlua_cpointer_allowlist_add(lvt, pointer); // get a cpointer from a function lua_getglobal(L, "_NewCPointer"); // Get the function by its global name lua_pushinteger(L, lvt); - lua_pushinteger(L, (u64)(intptr_t)p); + lua_pushinteger(L, pointer); if (lua_pcall(L, 2, 1, 0) != LUA_OK) { LOG_ERROR("Error calling Lua function: %s\n", lua_tostring(L, -1)); } @@ -550,7 +553,7 @@ s64 smlua_get_integer_mod_variable(u16 modIndex, const char* variable) { LOG_ERROR("Could not find mod list entry for modIndex: %u", modIndex); return 0; } - + u8 prevSuppress = gSmLuaSuppressErrors; int prevTop = lua_gettop(L); @@ -601,7 +604,7 @@ LuaFunction smlua_get_function_mod_variable(u16 modIndex, const char *variable) LOG_ERROR("Could not find mod list entry for modIndex: %u", modIndex); return 0; } - + u8 prevSuppress = gSmLuaSuppressErrors; int prevTop = lua_gettop(L); diff --git a/src/pc/lua/utils/smlua_collision_utils.c b/src/pc/lua/utils/smlua_collision_utils.c index 7b4ca407..7a643928 100644 --- a/src/pc/lua/utils/smlua_collision_utils.c +++ b/src/pc/lua/utils/smlua_collision_utils.c @@ -1,6 +1,7 @@ #include "types.h" #include "src/engine/surface_collision.h" +#include "include/surface_terrains.h" #include "game/mario_step.h" #include "pc/lua/smlua.h" @@ -164,6 +165,18 @@ struct RayIntersectionInfo* collision_find_surface_on_ray(f32 startX, f32 startY return &info; } +struct Surface* collision_find_floor(f32 x, f32 y, f32 z) { + static struct Surface *surface; + find_floor(x, y, z, &surface); + return surface; +} + +struct Surface* collision_find_ceil(f32 x, f32 y, f32 z) { + static struct Surface *surface; + find_ceil(x, y, z, &surface); + return surface; +} + struct Surface* get_water_surface_pseudo_floor(void) { return &gWaterSurfacePseudoFloor; } diff --git a/src/pc/lua/utils/smlua_collision_utils.h b/src/pc/lua/utils/smlua_collision_utils.h index 47827a30..432c7548 100644 --- a/src/pc/lua/utils/smlua_collision_utils.h +++ b/src/pc/lua/utils/smlua_collision_utils.h @@ -116,6 +116,10 @@ extern struct GlobalObjectCollisionData gGlobalObjectCollisionData; struct RayIntersectionInfo* collision_find_surface_on_ray(f32 startX, f32 startY, f32 startZ, f32 dirX, f32 dirY, f32 dirZ); +struct Surface* collision_find_floor(f32 x, f32 y, f32 z); + +struct Surface* collision_find_ceil(f32 x, f32 y, f32 z); + struct Surface* get_water_surface_pseudo_floor(void); Collision* smlua_collision_util_get(const char* name); diff --git a/src/pc/lua/utils/smlua_level_utils.c b/src/pc/lua/utils/smlua_level_utils.c index 49ce6d65..fcd06ab7 100644 --- a/src/pc/lua/utils/smlua_level_utils.c +++ b/src/pc/lua/utils/smlua_level_utils.c @@ -73,6 +73,17 @@ static struct CustomLevelInfo* smlua_level_util_get_info_from_script(char* scrip return NULL; } +struct CustomLevelInfo* smlua_level_util_get_info_from_course_num(u8 courseNum) { + struct CustomLevelInfo* node = sCustomLevelHead; + while (node != NULL) { + if (node->courseNum == courseNum) { + return node; + } + node = node->next; + } + return NULL; +} + s16 level_register(const char* scriptEntryName, s16 courseNum, const char* fullName, const char* shortName, u32 acousticReach, u32 echoLevel1, u32 echoLevel2, u32 echoLevel3) { // validate params if (scriptEntryName == NULL) { diff --git a/src/pc/lua/utils/smlua_level_utils.h b/src/pc/lua/utils/smlua_level_utils.h index 4bfa5a72..4d43b984 100644 --- a/src/pc/lua/utils/smlua_level_utils.h +++ b/src/pc/lua/utils/smlua_level_utils.h @@ -21,7 +21,8 @@ struct CustomLevelInfo { void smlua_level_util_reset(void); void smlua_level_util_change_area(s32 areaIndex); struct CustomLevelInfo* smlua_level_util_get_info(s16 levelNum); -struct CustomLevelInfo* smlua_level_util_get_info_from_short_name(const char* shortName); +struct CustomLevelInfo* smlua_level_util_get_info_from_short_name(char* shortName); +struct CustomLevelInfo* smlua_level_util_get_info_from_course_num(u8 courseNum); s16 level_register(const char* scriptEntryName, s16 courseNum, const char* fullName, const char* shortName, u32 acousticReach, u32 echoLevel1, u32 echoLevel2, u32 echoLevel3); bool level_is_vanilla_level(s16 levelNum); bool warp_to_warpnode(s32 aLevel, s32 aArea, s32 aAct, s32 aWarpId); diff --git a/src/pc/lua/utils/smlua_text_utils.c b/src/pc/lua/utils/smlua_text_utils.c index b8f8407c..f4563604 100644 --- a/src/pc/lua/utils/smlua_text_utils.c +++ b/src/pc/lua/utils/smlua_text_utils.c @@ -5,6 +5,11 @@ #include "game/ingame_menu.h" #include "game/save_file.h" #include "game/segment2.h" +#include "game/level_info.h" +#include "pc/pc_main.h" +#include "../smlua.h" +#include "smlua_level_utils.h" +#include "smlua_text_utils.h" #ifdef VERSION_EU extern s32 gInGameLanguage; @@ -15,6 +20,42 @@ static bool sReplacedDialog[DIALOG_COUNT] = { 0 }; static bool sReplacedCourseName[COURSE_COUNT+2] = { 0 }; static bool sReplacedActName[(COURSE_RR+2)*6] = { 0 }; +#define INVALID_COURSE_NUM(courseNum) (smlua_level_util_get_info_from_course_num(courseNum) == NULL && !COURSE_IS_VALID_COURSE(courseNum)) + +void convert_string_sm64_to_ascii(char *strAscii, const u8 *str64); + +struct CourseName *gReplacedActNameTable[COURSE_COUNT]; + +// Save all vanilla act names and course names +AT_STARTUP static void smlua_text_utils_init() { + void **actNameTbl = get_act_name_table(); + void **courseNameTbl = get_course_name_table(); + char courseBuffer[50]; + char actBuffer[50]; + + for (s16 courseNum = 0; courseNum < COURSE_COUNT; courseNum++) { + const u8 *courseName = segmented_to_virtual(courseNameTbl[courseNum]); + convert_string_sm64_to_ascii(courseBuffer, courseName); + gReplacedActNameTable[courseNum] = malloc(sizeof(struct CourseName)); + struct CourseName* courseActNames = gReplacedActNameTable[courseNum]; + snprintf(courseActNames->name, 50, "%s", courseBuffer); + snprintf(courseActNames->orig, 50, "%s", courseBuffer); + courseActNames->modIndex = -1; + + // Individual acts + if (COURSE_IS_MAIN_COURSE(courseNum)) { + courseActNames->actName = calloc(6, sizeof(struct ActName)); + for (s16 actNum = 0; actNum < 6; actNum++) { + const u8 *starName = segmented_to_virtual(actNameTbl[courseNum * 6 + actNum]); + convert_string_sm64_to_ascii(actBuffer, starName); + snprintf(courseActNames->actName[actNum].name, 50, "%s", actBuffer); + snprintf(courseActNames->actName[actNum].orig, 50, "%s", actBuffer); + courseActNames->actName[actNum].isModified = false; + } + } + } +} + static u8* smlua_text_utils_convert(const char* str) { s32 len = strlen(str); u8* dialogStr = calloc(len + 2, sizeof(u8)); @@ -29,7 +70,7 @@ void smlua_text_utils_reset_all(void) { void **dialogTableOrg = NULL; void **actNameTblOrg = NULL; void **courseNameTblOrg = NULL; - + #ifdef VERSION_EU switch (gInGameLanguage) { case LANGUAGE_ENGLISH: @@ -87,13 +128,27 @@ void smlua_text_utils_reset_all(void) { actNameTbl[i] = segmented_to_virtual(actNameTblOrg[i]); sReplacedActName[i] = false; } + + for (s32 courseNum = 0; courseNum < COURSE_COUNT; courseNum++) { + struct CourseName* courseActNames = gReplacedActNameTable[courseNum]; + snprintf(courseActNames->name, 50, "%s", courseActNames->orig); + courseActNames->modIndex = -1; + + // Individual acts + if (COURSE_IS_MAIN_COURSE(courseNum)) { + for (s16 actNum = 0; actNum < 6; actNum++) { + snprintf(courseActNames->actName[actNum].name, 50, "%s", courseActNames->actName[actNum].orig); + courseActNames->actName[actNum].isModified = false; + } + } + } } void smlua_text_utils_dialog_replace(enum DialogId dialogId, UNUSED u32 unused, s8 linesPerBox, s16 leftOffset, s16 width, const char* str) { if (dialogId >= DIALOG_COUNT) { return; } - + void **dialogTable = NULL; - + #ifdef VERSION_EU switch (gInGameLanguage) { case LANGUAGE_ENGLISH: @@ -124,75 +179,88 @@ void smlua_text_utils_dialog_replace(enum DialogId dialogId, UNUSED u32 unused, sReplacedDialog[dialogId] = true; } +#define REPLACE_ACT_NAME(i) \ + snprintf(courseActNames->actName[i-1].name, 256, "%s", act##i); \ + courseActNames->actName[i-1].isModified = true; \ + void smlua_text_utils_course_acts_replace(s16 courseNum, const char* courseName, const char* act1, const char* act2, const char* act3, const char* act4, const char* act5, const char* act6) { if (courseNum <= 0 || courseNum > COURSE_RR) { return; } - s16 courseOffset = courseNum - 1; - - void **actNameTbl = NULL; - void **courseNameTbl = NULL; - -#ifdef VERSION_EU - switch (gInGameLanguage) { - case LANGUAGE_ENGLISH: - actNameTbl = segmented_to_virtual(act_name_table_eu_en); - courseNameTbl = segmented_to_virtual(course_name_table_eu_en); - break; - case LANGUAGE_FRENCH: - actNameTbl = segmented_to_virtual(act_name_table_eu_fr); - courseNameTbl = segmented_to_virtual(course_name_table_eu_fr); - break; - case LANGUAGE_GERMAN: - actNameTbl = segmented_to_virtual(act_name_table_eu_de); - courseNameTbl = segmented_to_virtual(course_name_table_eu_de); - break; - } -#else - actNameTbl = segmented_to_virtual(seg2_act_name_table); - courseNameTbl = segmented_to_virtual(seg2_course_name_table); -#endif + struct CourseName* courseActNames = gReplacedActNameTable[courseNum]; + snprintf(courseActNames->name, 256, "%s", courseName + 3); + courseActNames->modIndex = gLuaActiveMod->index; - // replace course name - if (sReplacedCourseName[courseOffset]) { - free(courseNameTbl[courseOffset]); - } - courseNameTbl[courseOffset] = smlua_text_utils_convert(courseName); - sReplacedCourseName[courseOffset] = true; + REPLACE_ACT_NAME(1); + REPLACE_ACT_NAME(2); + REPLACE_ACT_NAME(3); + REPLACE_ACT_NAME(4); + REPLACE_ACT_NAME(5); + REPLACE_ACT_NAME(6); - // replace act names - const char* newActs[] = { act1, act2, act3, act4, act5, act6 }; - for (s32 i = 0; i < 6; i++) { - s32 index = (courseOffset * 6 + i); + LOG_INFO("%d (%s) replacing act names 1-6 of course %d, (%s), act 1: %s", courseActNames->modIndex, gLuaActiveMod->name, courseNum, courseName, act1); +} - if (sReplacedActName[index]) { - free(actNameTbl[index]); - } +void smlua_text_utils_course_name_replace(s16 courseNum, const char* name) { + if (INVALID_COURSE_NUM(courseNum)) { return; } - actNameTbl[index] = smlua_text_utils_convert(newActs[i]); - sReplacedActName[index] = true; - } + struct CourseName* courseActNames = gReplacedActNameTable[courseNum]; + snprintf(courseActNames->name, 256, "%s", name); + courseActNames->modIndex = gLuaActiveMod->index; +} + +const char* smlua_text_utils_course_name_get(s16 courseNum) { + if (INVALID_COURSE_NUM(courseNum)) { return NULL; } + + return gReplacedActNameTable[courseNum]->name; +} + +s32 smlua_text_utils_course_name_mod_index(s16 courseNum) { + if (INVALID_COURSE_NUM(courseNum)) { return -1; } + + return gReplacedActNameTable[courseNum]->modIndex; +} + +void smlua_text_utils_course_name_reset(s16 courseNum) { + if (INVALID_COURSE_NUM(courseNum)) { return; } + + struct CourseName* courseActNames = gReplacedActNameTable[courseNum]; + snprintf(courseActNames->name, 50, "%s", courseActNames->orig); + courseActNames->modIndex = -1; +} + +void smlua_text_utils_act_name_replace(s16 courseNum, u8 actNum, const char* name) { + if (INVALID_COURSE_NUM(courseNum) || actNum > 7) { return; } + + struct CourseName* courseActNames = gReplacedActNameTable[courseNum]; + + snprintf(courseActNames->actName[actNum].name, 256, "%s", name); + courseActNames->actName[actNum].isModified = true; +} + +const char* smlua_text_utils_act_name_get(s16 courseNum, u8 actNum) { + if (INVALID_COURSE_NUM(courseNum) || actNum > 7) { return NULL; } + + return gReplacedActNameTable[courseNum]->actName[actNum].name; +} + +bool smlua_text_utils_act_name_is_modified(s16 courseNum, u8 actNum) { + if (INVALID_COURSE_NUM(courseNum) || actNum > 7) { return false; } + + return gReplacedActNameTable[courseNum]->actName[actNum].isModified; +} + +void smlua_text_utils_act_name_reset(s16 courseNum, u8 actNum) { + if (INVALID_COURSE_NUM(courseNum) || actNum > 7) { return; } + + struct CourseName* courseActNames = gReplacedActNameTable[courseNum]; + snprintf(courseActNames->actName[actNum].name, 50, "%s", courseActNames->actName[actNum].orig); + courseActNames->actName[actNum].isModified = false; } void smlua_text_utils_secret_star_replace(s16 courseNum, const char* courseName) { if (courseNum <= COURSE_RR || courseNum > COURSE_COUNT) { return; } s16 courseOffset = courseNum - 1; - - void **courseNameTbl = NULL; - -#ifdef VERSION_EU - switch (gInGameLanguage) { - case LANGUAGE_ENGLISH: - courseNameTbl = segmented_to_virtual(course_name_table_eu_en); - break; - case LANGUAGE_FRENCH: - courseNameTbl = segmented_to_virtual(course_name_table_eu_fr); - break; - case LANGUAGE_GERMAN: - courseNameTbl = segmented_to_virtual(course_name_table_eu_de); - break; - } -#else - courseNameTbl = segmented_to_virtual(seg2_course_name_table); -#endif + + void **courseNameTbl = get_course_name_table(); if (sReplacedCourseName[courseOffset]) { free(courseNameTbl[courseOffset]); @@ -204,24 +272,8 @@ void smlua_text_utils_secret_star_replace(s16 courseNum, const char* courseName) void smlua_text_utils_castle_secret_stars_replace(const char* name) { s16 courseOffset = COURSE_COUNT; - - void **courseNameTbl = NULL; - -#ifdef VERSION_EU - switch (gInGameLanguage) { - case LANGUAGE_ENGLISH: - courseNameTbl = segmented_to_virtual(course_name_table_eu_en); - break; - case LANGUAGE_FRENCH: - courseNameTbl = segmented_to_virtual(course_name_table_eu_fr); - break; - case LANGUAGE_GERMAN: - courseNameTbl = segmented_to_virtual(course_name_table_eu_de); - break; - } -#else - courseNameTbl = segmented_to_virtual(seg2_course_name_table); -#endif + + void **courseNameTbl = get_course_name_table(); if (sReplacedCourseName[courseOffset]) { free(courseNameTbl[courseOffset]); @@ -234,24 +286,8 @@ void smlua_text_utils_castle_secret_stars_replace(const char* name) { void smlua_text_utils_extra_text_replace(s16 index, const char* text) { if (index < 0 || index > 6) { return; } index = (COURSE_RR * 6 + index); - - void **actNameTbl = NULL; - -#ifdef VERSION_EU - switch (gInGameLanguage) { - case LANGUAGE_ENGLISH: - actNameTbl = segmented_to_virtual(act_name_table_eu_en); - break; - case LANGUAGE_FRENCH: - actNameTbl = segmented_to_virtual(act_name_table_eu_fr); - break; - case LANGUAGE_GERMAN: - actNameTbl = segmented_to_virtual(act_name_table_eu_de); - break; - } -#else - actNameTbl = segmented_to_virtual(seg2_act_name_table); -#endif + + void **actNameTbl = get_act_name_table(); if (sReplacedActName[index]) { free(actNameTbl[index]); @@ -263,4 +299,4 @@ void smlua_text_utils_extra_text_replace(s16 index, const char* text) { const char* smlua_text_utils_get_language(void) { return configLanguage; -} \ No newline at end of file +} diff --git a/src/pc/lua/utils/smlua_text_utils.h b/src/pc/lua/utils/smlua_text_utils.h index 52d9d692..52486e84 100644 --- a/src/pc/lua/utils/smlua_text_utils.h +++ b/src/pc/lua/utils/smlua_text_utils.h @@ -4,10 +4,31 @@ #include "types.h" #include "dialog_ids.h" +struct ActName { + char name[256]; + char orig[256]; + bool isModified; +}; + +struct CourseName { + struct ActName *actName; + char name[256]; + char orig[256]; + s32 modIndex; +}; + void smlua_text_utils_reset_all(void); void smlua_text_utils_dialog_replace(enum DialogId dialogId, u32 unused, s8 linesPerBox, s16 leftOffset, s16 width, const char* str); void smlua_text_utils_course_acts_replace(s16 courseNum, const char* courseName, const char* act1, const char* act2, const char* act3, const char* act4, const char* act5, const char* act6); void smlua_text_utils_secret_star_replace(s16 courseNum, const char* courseName); +void smlua_text_utils_course_name_replace(s16 courseNum, const char* name); +const char* smlua_text_utils_course_name_get(s16 courseNum); +s32 smlua_text_utils_course_name_mod_index(s16 courseNum); +void smlua_text_utils_course_name_reset(s16 courseNum); +void smlua_text_utils_act_name_replace(s16 courseNum, u8 actNum, const char* name); +const char* smlua_text_utils_act_name_get(s16 courseNum, u8 actNum); +bool smlua_text_utils_act_name_is_modified(s16 courseNum, u8 actNum); +void smlua_text_utils_act_name_reset(s16 courseNum, u8 actNum); void smlua_text_utils_castle_secret_stars_replace(const char* name); void smlua_text_utils_extra_text_replace(s16 index, const char* text); const char* smlua_text_utils_get_language(void); diff --git a/src/pc/mods/mods.c b/src/pc/mods/mods.c index c3611c43..b03fe146 100644 --- a/src/pc/mods/mods.c +++ b/src/pc/mods/mods.c @@ -4,6 +4,7 @@ #include "mod_cache.h" #include "data/dynos.c.h" #include "pc/debuglog.h" +#include "pc/pc_main.h" #define MAX_SESSION_CHARS 7 diff --git a/src/pc/network/moderator_list.c b/src/pc/network/moderator_list.c index f9891dd2..87cbf85f 100644 --- a/src/pc/network/moderator_list.c +++ b/src/pc/network/moderator_list.c @@ -32,9 +32,7 @@ void moderator_list_add(char* address, bool perm) { gModerator = malloc(sizeof(bool) * gModeratorCount); } else { gModeratorAddresses = realloc(gModeratorAddresses, sizeof(char*) * gModeratorCount); - assert(gModeratorAddresses != NULL); gModerator = realloc(gModerator, sizeof(bool) * gModeratorCount); - assert(gModerator != NULL); } if (gModeratorAddresses == NULL) { LOG_ERROR("Failed to allocate gModeratorAddresses"); diff --git a/src/pc/network/network.c b/src/pc/network/network.c index e1d9689a..ea1df1dd 100644 --- a/src/pc/network/network.c +++ b/src/pc/network/network.c @@ -373,6 +373,7 @@ void network_send(struct Packet* p) { } void network_receive(u8 localIndex, void* addr, u8* data, u16 dataLength) { + // receive packet struct Packet p = { .localIndex = localIndex, @@ -681,9 +682,6 @@ void network_shutdown(bool sendLeaving, bool exiting, bool popup, bool reconnect extern s16 gMenuMode; gMenuMode = -1; - extern bool gIsModerator; - gIsModerator = false; - djui_panel_shutdown(); extern bool gDjuiInMainMenu; if (!gDjuiInMainMenu) { diff --git a/src/pc/network/network_player.h b/src/pc/network/network_player.h index 92589f1c..ef3b1e75 100644 --- a/src/pc/network/network_player.h +++ b/src/pc/network/network_player.h @@ -25,6 +25,7 @@ struct NetworkPlayer { u8 type; u8 localIndex; u8 globalIndex; + bool moderator; f32 lastReceived; f32 lastSent; f32 lastPingSent; diff --git a/src/pc/network/network_utils.c b/src/pc/network/network_utils.c index a1e0dcda..aafe2b64 100644 --- a/src/pc/network/network_utils.c +++ b/src/pc/network/network_utils.c @@ -27,8 +27,7 @@ bool network_is_server(void) { } bool network_is_moderator(void) { - extern bool gIsModerator; - return gIsModerator; + return gNetworkPlayers[0].moderator; } u8* network_get_player_text_color(u8 localIndex) { diff --git a/src/pc/network/packets/packet_chat.c b/src/pc/network/packets/packet_chat.c index 59ee2de2..fc6e9742 100644 --- a/src/pc/network/packets/packet_chat.c +++ b/src/pc/network/packets/packet_chat.c @@ -100,7 +100,7 @@ void network_receive_chat(struct Packet* p) { // add the message djui_chat_message_create_from(globalIndex, remoteMessage); - if (gNetworkSystem && gNetworkSystem->get_id_str && np) { + if (gNetworkSystem && gNetworkSystem->get_id_str && np->connected && strlen(np->name) > 0) { LOG_CONSOLE("[%s] %s: %s", gNetworkSystem->get_id_str(np->localIndex), np->name, remoteMessage); LOG_INFO("[%s] %s: %s", gNetworkSystem->get_id_str(np->localIndex), np->name, remoteMessage); } else { diff --git a/src/pc/network/packets/packet_command_mod.c b/src/pc/network/packets/packet_command_mod.c index 76b735d2..ce3fa0ba 100644 --- a/src/pc/network/packets/packet_command_mod.c +++ b/src/pc/network/packets/packet_command_mod.c @@ -4,53 +4,55 @@ #include "pc/djui/djui_chat_message.h" #include "pc/network/ban_list.h" #include "pc/network/moderator_list.h" - -bool gIsModerator = false; +#include "pc/debuglog.h" void network_send_chat_command(u8 globalIndex, enum ChatConfirmCommand ccc) { - if (gIsModerator) { - u8 cccType = ccc; - struct Packet p = { 0 }; - packet_init(&p, PACKET_COMMAND, false, PLMT_NONE); - packet_write(&p, &globalIndex, sizeof(u8)); - packet_write(&p, &cccType, sizeof(u8)); - network_send_to(gNetworkPlayerServer->localIndex, &p); - } + if (!gNetworkPlayers[0].moderator) return; + + u8 cccType = ccc; struct Packet p = { 0 }; + LOG_INFO("sending chat command to host with type: %d", cccType); + packet_init(&p, PACKET_COMMAND, false, PLMT_NONE); + packet_write(&p, &globalIndex, sizeof(u8)); + packet_write(&p, &cccType, sizeof(u8)); + network_send_to(gNetworkPlayerServer->localIndex, &p); } void network_receive_chat_command(struct Packet *p) { - if (!moderator_list_contains(gNetworkSystem->get_id_str(p->localIndex))) { + if (gNetworkType != NT_SERVER) { + LOG_ERROR("recieved chat command as non server"); return; } - enum ChatConfirmCommand CCC; - u8 player; + + if (!moderator_list_contains(gNetworkSystem->get_id_str(p->localIndex))) { + LOG_ERROR("recieved moderator command from non moderator"); + return; + } + u8 CCC; u8 player; packet_read(p, &player, sizeof(u8)); packet_read(p, &CCC, sizeof(u8)); - if (gNetworkType == NT_SERVER && CCC == CCC_KICK) { - struct NetworkPlayer *np = &gNetworkPlayers[player]; - if (!np->connected) { - return; - } - network_send_kick(np->localIndex, EKT_KICKED); - network_player_disconnected(np->localIndex); - char message[256] = { 0 }; - snprintf(message, 256, "\\#fff982\\Kicked '%s%s\\#fff982\\'!", - network_get_player_text_color_string(np->localIndex), np->name); - djui_chat_message_create(message); + + if (CCC != CCC_KICK && CCC != CCC_BAN) { + LOG_ERROR("recieved an invalid chat command: %d", CCC); + return; } - if (gNetworkType == NT_SERVER && CCC == CCC_BAN) { - struct NetworkPlayer *np = &gNetworkPlayers[player]; - if (!np->connected) { - return; - } + + struct NetworkPlayer *np = &gNetworkPlayers[player]; + if (!np->connected) { + LOG_ERROR("recieved player that isn't connected"); + return; + } + char message[256] = { 0 }; + if (CCC == CCC_KICK) { + network_send_kick(np->localIndex, EKT_KICKED); + snprintf(message, 256, "\\#fff982\\Kicked '%s%s\\#fff982\\'!", network_get_player_text_color_string(np->localIndex), np->name); + } + if (CCC == CCC_BAN) { network_send_kick(np->localIndex, EKT_BANNED); ban_list_add(gNetworkSystem->get_id_str(np->localIndex), false); - network_player_disconnected(np->localIndex); - char message[256] = { 0 }; - snprintf(message, 256, "\\#fff982\\Banned '%s%s\\#fff982\\'!", - network_get_player_text_color_string(np->localIndex), np->name); - djui_chat_message_create(message); + snprintf(message, 256, "\\#fff982\\Banned '%s%s\\#fff982\\'!", network_get_player_text_color_string(np->localIndex), np->name); } + network_player_disconnected(np->localIndex); + djui_chat_message_create(message); } void network_send_moderator(u8 localIndex) { @@ -60,10 +62,7 @@ void network_send_moderator(u8 localIndex) { } void network_receive_moderator(struct Packet *p) { - if ((gIsModerator) || (network_player_any_connected() && gNetworkPlayers[p->localIndex].type != NPT_SERVER)) { - return; - } - - gIsModerator = true; + if (gNetworkPlayers[0].moderator || (network_player_any_connected() && gNetworkPlayers[p->localIndex].type != NPT_SERVER)) return; + gNetworkPlayers[0].moderator = true; djui_chat_message_create(DLANG(CHAT, MOD_GRANTED)); -} \ No newline at end of file +} diff --git a/src/pc/network/packets/packet_object.c b/src/pc/network/packets/packet_object.c index 8f8ead86..5d21637b 100644 --- a/src/pc/network/packets/packet_object.c +++ b/src/pc/network/packets/packet_object.c @@ -468,7 +468,9 @@ void network_update_objects(void) { // check for stale sync object if (so->o->oSyncID != so->id) { - LOG_ERROR("sync id mismatch: %d vs %d (behavior %d)", so->o->oSyncID, so->id, get_id_from_behavior(so->o->behavior)); + enum BehaviorId bhvId = get_id_from_behavior(so->o->behavior); + const char* bhvName = get_behavior_name_from_id(bhvId); + LOG_ERROR("sync id mismatch: %d vs %d (behavior %s, %d)", so->o->oSyncID, so->id, bhvName != NULL ? bhvName : "NULL", bhvId); sync_object_forget(so->id); continue; } diff --git a/src/pc/pc_main.c b/src/pc/pc_main.c index da57d227..b60c1a57 100644 --- a/src/pc/pc_main.c +++ b/src/pc/pc_main.c @@ -12,16 +12,6 @@ #include "network/network.h" #include "lua/smlua.h" -#include "gfx/gfx_pc.h" - -#include "gfx/gfx_opengl.h" -#include "gfx/gfx_direct3d11.h" -#include "gfx/gfx_direct3d12.h" - -#include "gfx/gfx_dxgi.h" -#include "gfx/gfx_sdl.h" -#include "gfx/gfx_dummy.h" - #include "audio/audio_api.h" #include "audio/audio_sdl.h" #include "audio/audio_null.h" @@ -87,25 +77,22 @@ static f64 sLastFrameTimeStart; static f32 sAvgFrames = 1; static f32 sAvgFps = 0; +bool gGameInited = false; +bool gGfxInited = false; + static struct AudioAPI *audio_api; -struct GfxWindowManagerAPI *wm_api; -static struct GfxRenderingAPI *rendering_api; +struct GfxWindowManagerAPI *wm_api = &WAPI; extern void gfx_run(Gfx *commands); extern void thread5_game_loop(void *arg); extern void create_next_audio_buffer(s16 *samples, u32 num_samples); void game_loop_one_iteration(void); -void dispatch_audio_sptask(UNUSED struct SPTask *spTask) { -} - -void set_vblank_handler(UNUSED s32 index, UNUSED struct VblankHandler *handler, UNUSED OSMesgQueue *queue, UNUSED OSMesg *msg) { -} - -static bool inited = false; +void dispatch_audio_sptask(UNUSED struct SPTask *spTask) {} +void set_vblank_handler(UNUSED s32 index, UNUSED struct VblankHandler *handler, UNUSED OSMesgQueue *queue, UNUSED OSMesg *msg) {} void send_display_list(struct SPTask *spTask) { - if (!inited) return; + if (!gGameInited) { return; } gfx_run((Gfx *)spTask->task.t.data_ptr); } @@ -117,17 +104,29 @@ void send_display_list(struct SPTask *spTask) { #define SAMPLES_LOW 528 #endif +extern void patch_mtx_before(void); +extern void patch_screen_transition_before(void); +extern void patch_title_screen_before(void); +extern void patch_dialog_before(void); +extern void patch_hud_before(void); +extern void patch_paintings_before(void); +extern void patch_bubble_particles_before(void); +extern void patch_snow_particles_before(void); +extern void patch_djui_before(void); +extern void patch_djui_hud_before(void); + +extern void patch_mtx_interpolated(f32 delta); +extern void patch_screen_transition_interpolated(f32 delta); +extern void patch_title_screen_interpolated(f32 delta); +extern void patch_dialog_interpolated(f32 delta); +extern void patch_hud_interpolated(f32 delta); +extern void patch_paintings_interpolated(f32 delta); +extern void patch_bubble_particles_interpolated(f32 delta); +extern void patch_snow_particles_interpolated(f32 delta); +extern void patch_djui_interpolated(f32 delta); +extern void patch_djui_hud(f32 delta); + static void patch_interpolations_before(void) { - extern void patch_mtx_before(void); - extern void patch_screen_transition_before(void); - extern void patch_title_screen_before(void); - extern void patch_dialog_before(void); - extern void patch_hud_before(void); - extern void patch_paintings_before(void); - extern void patch_bubble_particles_before(void); - extern void patch_snow_particles_before(void); - extern void patch_djui_before(void); - extern void patch_djui_hud_before(void); patch_mtx_before(); patch_screen_transition_before(); patch_title_screen_before(); @@ -141,16 +140,6 @@ static void patch_interpolations_before(void) { } static inline void patch_interpolations(f32 delta) { - extern void patch_mtx_interpolated(f32 delta); - extern void patch_screen_transition_interpolated(f32 delta); - extern void patch_title_screen_interpolated(f32 delta); - extern void patch_dialog_interpolated(f32 delta); - extern void patch_hud_interpolated(f32 delta); - extern void patch_paintings_interpolated(f32 delta); - extern void patch_bubble_particles_interpolated(f32 delta); - extern void patch_snow_particles_interpolated(f32 delta); - extern void patch_djui_interpolated(f32 delta); - extern void patch_djui_hud(f32 delta); patch_mtx_interpolated(delta); patch_screen_transition_interpolated(delta); patch_title_screen_interpolated(delta); @@ -163,19 +152,17 @@ static inline void patch_interpolations(f32 delta) { patch_djui_hud(delta); } - void produce_interpolation_frames_and_delay(void) { + u64 frames = 0; + f64 curTime = clock_elapsed_f64(); + gRenderingInterpolated = true; // sanity check target time to deal with hangs and such - f64 curTime = clock_elapsed_f64(); - if (fabs(sFrameTargetTime - curTime) > 1) { - sFrameTargetTime = curTime - 0.01f; - } + if (fabs(sFrameTargetTime - curTime) > 1) { sFrameTargetTime = curTime - 0.01f; } - u64 frames = 0; + // interpolate and render while ((curTime = clock_elapsed_f64()) < sFrameTargetTime) { - // interpolate and render gfx_start_frame(); f32 delta = MIN((curTime - sFrameTimeStart) / (sFrameTargetTime - sFrameTimeStart), 1); gRenderingDelta = delta; @@ -185,12 +172,12 @@ void produce_interpolation_frames_and_delay(void) { // delay if (!configUncappedFramerate) { - f64 targetDelta = 1.0 / (f64)configFrameLimit; + f64 targetDelta = 1.0 / (f64) configFrameLimit; f64 now = clock_elapsed_f64(); f64 actualDelta = now - curTime; if (actualDelta < targetDelta) { f64 delay = ((targetDelta - actualDelta) * 1000.0); - wm_api->delay((u32)delay); + WAPI.delay((u32) delay); } } @@ -207,50 +194,35 @@ void produce_interpolation_frames_and_delay(void) { //printf(">>> fpt: %llu, fps: %f :: %f\n", frames, sAvgFps, fps); } -void produce_one_frame(void) { - CTX_BEGIN(CTX_NETWORK); - network_update(); - CTX_END(CTX_NETWORK); +inline static void buffer_audio(void) { + int samples_left = audio_api->buffered(); + u32 num_audio_samples = samples_left < audio_api->get_desired_buffered() ? SAMPLES_HIGH : SAMPLES_LOW; + s16 audio_buffer[SAMPLES_HIGH * 2 * 2]; + for (s32 i = 0; i < 2; i++) { + create_next_audio_buffer(audio_buffer + i * (num_audio_samples * 2), num_audio_samples); + } + audio_api->play((u8 *)audio_buffer, 2 * num_audio_samples * 4); +} - CTX_BEGIN(CTX_INTERP); - patch_interpolations_before(); - CTX_END(CTX_INTERP); +void produce_one_frame(void) { + CTX_EXTENT(CTX_NETWORK, network_update); + + CTX_EXTENT(CTX_INTERP, patch_interpolations_before); const f32 master_mod = (f32)configMasterVolume / 127.0f; set_sequence_player_volume(SEQ_PLAYER_LEVEL, (f32)configMusicVolume / 127.0f * master_mod); set_sequence_player_volume(SEQ_PLAYER_SFX, (f32)configSfxVolume / 127.0f * master_mod); set_sequence_player_volume(SEQ_PLAYER_ENV, (f32)configEnvVolume / 127.0f * master_mod); - CTX_BEGIN(CTX_GAME_LOOP); - game_loop_one_iteration(); - CTX_END(CTX_GAME_LOOP); + CTX_EXTENT(CTX_GAME_LOOP, game_loop_one_iteration); - CTX_BEGIN(CTX_SMLUA); - smlua_update(); - CTX_END(CTX_SMLUA); + CTX_EXTENT(CTX_SMLUA, smlua_update); thread6_rumble_loop(NULL); - CTX_BEGIN(CTX_AUDIO); - int samples_left = audio_api->buffered(); - u32 num_audio_samples = samples_left < audio_api->get_desired_buffered() ? SAMPLES_HIGH : SAMPLES_LOW; - //printf("Audio samples: %d %u\n", samples_left, num_audio_samples); - s16 audio_buffer[SAMPLES_HIGH * 2 * 2]; - for (s32 i = 0; i < 2; i++) { - /*if (audio_cnt-- == 0) { - audio_cnt = 2; - } - u32 num_audio_samples = audio_cnt < 2 ? 528 : 544;*/ - create_next_audio_buffer(audio_buffer + i * (num_audio_samples * 2), num_audio_samples); - } - //printf("Audio samples before submitting: %d\n", audio_api->buffered()); + CTX_EXTENT(CTX_AUDIO, buffer_audio); - audio_api->play((u8 *)audio_buffer, 2 * num_audio_samples * 4); - CTX_END(CTX_AUDIO); - - CTX_BEGIN(CTX_RENDER); - produce_interpolation_frames_and_delay(); - CTX_END(CTX_RENDER); + CTX_EXTENT(CTX_RENDER, produce_interpolation_frames_and_delay); } void audio_shutdown(void) { @@ -270,7 +242,7 @@ void game_deinit(void) { network_shutdown(true, true, false, false); smlua_shutdown(); mods_shutdown(); - inited = false; + gGameInited = false; } void game_exit(void) { @@ -279,10 +251,6 @@ void game_exit(void) { exit(0); } -void inthand(UNUSED int signum) { - game_exit(); -} - void main_func(void) { const char *gamedir = gCLIOpts.GameDir[0] ? gCLIOpts.GameDir : FS_BASEDIR; const char *userpath = gCLIOpts.SavePath[0] ? gCLIOpts.SavePath : sys_user_path(); @@ -315,62 +283,30 @@ void main_func(void) { if (configPlayerModel >= CT_MAX) { configPlayerModel = 0; } - if (gCLIOpts.FullScreen == 1) - configWindow.fullscreen = true; - else if (gCLIOpts.FullScreen == 2) - configWindow.fullscreen = false; + if (gCLIOpts.FullScreen == 1) { configWindow.fullscreen = true; } + else if (gCLIOpts.FullScreen == 2) { configWindow.fullscreen = false; } - #if defined(WAPI_SDL1) || defined(WAPI_SDL2) - wm_api = &gfx_sdl; - #elif defined(WAPI_DXGI) - wm_api = &gfx_dxgi; - #elif defined(WAPI_DUMMY) - wm_api = &gfx_dummy_wm_api; - #else - #error No window API! - #endif - - #if defined(RAPI_D3D11) - rendering_api = &gfx_direct3d11_api; - # define RAPI_NAME "DirectX 11" - #elif defined(RAPI_D3D12) - rendering_api = &gfx_direct3d12_api; - # define RAPI_NAME "DirectX 12" - #elif defined(RAPI_GL) || defined(RAPI_GL_LEGACY) - rendering_api = &gfx_opengl_api; - # ifdef USE_GLES - # define RAPI_NAME "OpenGL ES" - # else - # define RAPI_NAME "OpenGL" - # endif - #elif defined(RAPI_DUMMY) - rendering_api = &gfx_dummy_renderer_api; - #else - #error No rendering API! - #endif - - const char* version = get_version_local(); - char window_title[96] = { 0 }; -#ifdef GIT_HASH - snprintf(window_title, 96, "sm64ex-coop: %s [%s]", version, GIT_HASH); -#else - snprintf(window_title, 96, "sm64ex-coop: %s", version); -#endif - - gfx_init(wm_api, rendering_api, window_title); - wm_api->set_keyboard_callbacks(keyboard_on_key_down, keyboard_on_key_up, keyboard_on_all_keys_up, keyboard_on_text_input); - - #if defined(AAPI_SDL1) || defined(AAPI_SDL2) - if (audio_api == NULL && audio_sdl.init()) - audio_api = &audio_sdl; - #endif - - if (audio_api == NULL) { - audio_api = &audio_null; + // incase the loading screen failed, or is disabled + if (!gGfxInited) { + gfx_init(&WAPI, &RAPI, TITLE); + WAPI.set_keyboard_callbacks(keyboard_on_key_down, keyboard_on_key_up, keyboard_on_all_keys_up, keyboard_on_text_input); } +#if defined(AAPI_SDL1) || defined(AAPI_SDL2) + if (audio_api == NULL && audio_sdl.init()) { audio_api = &audio_sdl; } +#endif + if (audio_api == NULL) { audio_api = &audio_null; } + + audio_init(); + sound_init(); + bassh_init(); + network_player_init(); + + thread5_game_loop(NULL); + djui_init_late(); + // init network if (gCLIOpts.Network == NT_CLIENT) { network_set_system(NS_SOCKET); snprintf(gGetHostName, MAX_CONFIG_STRING, "%s", gCLIOpts.JoinIp); @@ -387,15 +323,6 @@ void main_func(void) { network_init(NT_NONE, false); } - audio_init(); - sound_init(); - bassh_init(); - network_player_init(); - - thread5_game_loop(NULL); - - inited = true; - #ifdef EXTERNAL_DATA // precache data if needed if (configPrecacheRes) { @@ -405,10 +332,12 @@ void main_func(void) { } #endif + gGameInited = true; + while (true) { debug_context_reset(); CTX_BEGIN(CTX_FRAME); - wm_api->main_loop(produce_one_frame); + WAPI.main_loop(produce_one_frame); #ifdef DISCORD_SDK discord_update(); #endif diff --git a/src/pc/pc_main.h b/src/pc/pc_main.h index 7f6e1624..f6d00894 100644 --- a/src/pc/pc_main.h +++ b/src/pc/pc_main.h @@ -5,6 +5,66 @@ extern "C" { #endif +#include "gfx/gfx_pc.h" + +#include "gfx/gfx_opengl.h" +#include "gfx/gfx_direct3d11.h" +#include "gfx/gfx_direct3d12.h" + +#include "gfx/gfx_dxgi.h" +#include "gfx/gfx_sdl.h" +#include "gfx/gfx_dummy.h" + +#if defined(WAPI_SDL1) || defined(WAPI_SDL2) +# define WAPI gfx_sdl +#elif defined(WAPI_DXGI) +# define WAPI gfx_dxgi +#elif defined(WAPI_DUMMY) +# define WAPI gfx_dummy_wm_api +#else +# error No window API! +#endif + +#if defined(RAPI_D3D11) +# define RAPI gfx_direct3d11_api +# define RAPI_NAME "DirectX 11" +#elif defined(RAPI_D3D12) +# define RAPI gfx_direct3d12_api +# define RAPI_NAME "DirectX 12" +#elif defined(RAPI_GL) || defined(RAPI_GL_LEGACY) +# define RAPI gfx_opengl_api +# ifdef USE_GLES +# define RAPI_NAME "OpenGL ES" +# else +# define RAPI_NAME "OpenGL" +# endif +#elif defined(RAPI_DUMMY) +# define RAPI gfx_dummy_renderer_api +#else +# error No rendering API! +#endif + +// For IDEs with syntax highlighting +#ifndef WAPI +#define WAPI gfx_dummy_wm_api +#endif +#ifndef RAPI +#define RAPI gfx_dummy_renderer_api +#endif + +#ifdef GIT_HASH +#define TITLE ({ char title[96] = ""; snprintf(title, 96, "sm64ex-coop: %s [%s]", get_version_local(), GIT_HASH); title; }) +#else +#define TITLE ({ char title[96] = ""; snprintf(title, 96, "sm64ex-coop: %s", get_version_local()); title; }) +#endif + +#define LOAD_STEPS 6 + +#define AT_STARTUP __attribute__((constructor)) + +extern bool gGameInited; +extern bool gGfxInited; + extern struct GfxWindowManagerAPI* wm_api; void game_deinit(void); void game_exit(void); diff --git a/src/pc/utils/misc.c b/src/pc/utils/misc.c index 1f29afbc..ac7fd21d 100644 --- a/src/pc/utils/misc.c +++ b/src/pc/utils/misc.c @@ -168,17 +168,6 @@ void delta_interpolate_rgba(u8* res, u8* a, u8* b, f32 delta) { res[3] = ((a[3] * antiDelta) + (b[3] * delta)); } -/* -void delta_interpolate_mtx(Mtx* out, Mtx* a, Mtx* b, f32 delta) { - f32 antiDelta = 1.0f - delta; - for (s32 i = 0; i < 4; i++) { - for (s32 j = 0; j < 4; j++) { - out->m[i][j] = (a->m[i][j] * antiDelta) + (b->m[i][j] * delta); - } - } -} -*/ - static f32 get_quat_compo_abs(f32 xPiece, f32 yPiece, f32 zPiece) { return sqrt((1.0f + xPiece + yPiece + zPiece) * 0.25f); } @@ -308,7 +297,7 @@ static void rot_quat_slerp(Vec4f out, Vec4f a, Vec4f b, f32 t) { } // removes scaling from the shear value -static f32 unmat_unscale_shear(f32 shear, f32 scale) { +inline static f32 unmat_unscale_shear(f32 shear, f32 scale) { if (scale == 0.0f) { // assume no shear return 0.0f; @@ -325,14 +314,14 @@ static f32 unmat_unscale_shear(f32 shear, f32 scale) { // // matrix perspective is not used in SM64, so those indices are stripped from the output parameter // return value was related to if matrix was non-singular, which was necessary for perspective -// since perspective is not used, the return value is also strippped +// since perspective is not used, the return value is also stripped // // additionally, rotation is not converted to euler angles // instead, it is converted to a quaternion to avoid gimbal lock // // tranfs is returned as follows: // scale(x, y, z), shear(xy, xz, zy), rotation(a, b, c, d), translation(x, y, z) -static void unmatrix(Mtx * mat, f32 tranfs[13]) { +OPTIMIZE_O3 static void unmatrix(Mtx * mat, f32 tranfs[13]) { int i = 0; Vec3f axisVecs[3] = { 0 }; Vec3f yzCross = { 0 }; @@ -433,7 +422,7 @@ static void unmatrix(Mtx * mat, f32 tranfs[13]) { // builds a transformation matrix from a decomposed sequence from unmatrix // see unmatrix for what tranfs means -static void rematrix(Mtx * mat, f32 tranfs[13]) { +OPTIMIZE_O3 static void rematrix(Mtx * mat, f32 tranfs[13]) { int i; Vec3f rotAxes[3] = { 0 }; Mat4 rotMat = { 0 }; @@ -479,7 +468,7 @@ static void rematrix(Mtx * mat, f32 tranfs[13]) { } } -void delta_interpolate_mtx_accurate(Mtx* out, Mtx* a, Mtx* b, f32 delta) { +OPTIMIZE_O3 inline static void delta_interpolate_mtx_accurate(Mtx* out, Mtx* a, Mtx* b, f32 delta) { int i = 0; f32 matTranfsA[13] = { 0 }; f32 matTranfsB[13] = { 0 }; @@ -502,7 +491,7 @@ void delta_interpolate_mtx_accurate(Mtx* out, Mtx* a, Mtx* b, f32 delta) { rematrix(out, matTranfsB); } -void delta_interpolate_mtx(Mtx* out, Mtx* a, Mtx* b, f32 delta) { +OPTIMIZE_O3 void delta_interpolate_mtx(Mtx* out, Mtx* a, Mtx* b, f32 delta) { // HACK: Limit accurate interpolation to 64-bit builds if (sizeof(void*) > 4) { if (configInterpolationMode) {