diff --git a/include/game/bases/d_WarningManager.hpp b/include/game/bases/d_WarningManager.hpp index ebc9cc57..2e2193c1 100644 --- a/include/game/bases/d_WarningManager.hpp +++ b/include/game/bases/d_WarningManager.hpp @@ -1,6 +1,27 @@ #pragma once +#include + class dWarningManager_c { public: + void AllWarningEnd(bool); + void setError(int errorID) { m_b8f = true; mErrorID = errorID; } + static void CreateWarningManager(); + static void addWarningForbid() NOINLINE { m_WarningForbid++; } + static void subWarningForbid() NOINLINE { if (m_WarningForbid > 0) m_WarningForbid--; } + static bool isError() { return m_Created && m_WarningCheck; } + + u8 mPad1[0xb00]; + int m_b00; + u8 mPad2[0x5]; + bool m_b09; + u8 mPad3[0x46]; + int mErrorID; + u8 mPad4[0x3b]; + bool m_b8f; + + static bool m_Created; + static bool m_WarningCheck; static int m_WarningForbid; + static dWarningManager_c *m_instance; }; diff --git a/include/game/bases/d_WiiStrapScreen.hpp b/include/game/bases/d_WiiStrapScreen.hpp new file mode 100644 index 00000000..cbda6f86 --- /dev/null +++ b/include/game/bases/d_WiiStrapScreen.hpp @@ -0,0 +1,41 @@ +#pragma once + +#include +#include + +/// @brief Displays the Wii Strap safety warning screen. +/// @details Loops between the two images that show the safety warning and how to put on the strap. +/// @note The button press to advance from this screen is handled by dScBoot_c. +/// @ingroup bases +class dWiiStrapScreen_c : public dBase_c { +public: + /// @brief The animation names used in the layout. + /// @unofficial + enum ANIM_NAME_e { + roop, + ANIM_NAME_COUNT + }; + + /// @brief The animations used for the layout. + /// @unofficial + enum ANIM_e { + ANIM_STRAP, + ANIM_COUNT + }; + + dWiiStrapScreen_c(); + virtual ~dWiiStrapScreen_c(); + + virtual int create(); + virtual int preExecute(); + virtual int execute(); + virtual int draw(); + virtual int doDelete(); + + bool createLayout(); + + LytBase_c mLayout; ///< The layout for the screen. + + bool mHasLoadedLayout; ///< Whether the layout has been loaded. + bool mVisible; ///< Whether the screen is currently visible. +}; diff --git a/include/game/bases/d_game_com.hpp b/include/game/bases/d_game_com.hpp index 7f0a9294..ddb4aba6 100644 --- a/include/game/bases/d_game_com.hpp +++ b/include/game/bases/d_game_com.hpp @@ -38,6 +38,12 @@ namespace dGameCom { void clearGameStop(); ///< Resets the game stop state. void setGameStop(); + ////////////////// + // Language API // + ////////////////// + + u8 GetLanguageHBM(); + //////////////////////// // Model Lighting API // //////////////////////// diff --git a/include/game/bases/d_lytbase.hpp b/include/game/bases/d_lytbase.hpp index 5bc5c24f..46e33ab6 100644 --- a/include/game/bases/d_lytbase.hpp +++ b/include/game/bases/d_lytbase.hpp @@ -17,7 +17,7 @@ class LytBase_c : public d2d::Multi_c { bool ReadResourceEx(const char *, int, bool); bool ReadResource(const char *, bool); bool ReadResource2(const char *, int); - bool ReadResource3(const char *, int); ///< @unofficial Not in Shield version. + bool ReadResource3(const char *, int); ///< @unofficial [Not in Shield version.] void NPaneRegister(const char **, nw4r::lyt::Pane **, int); void WPaneRegister(const char **, nw4r::lyt::Window **, int); diff --git a/include/game/bases/d_s_boot.hpp b/include/game/bases/d_s_boot.hpp index a1404ad7..0688a768 100644 --- a/include/game/bases/d_s_boot.hpp +++ b/include/game/bases/d_s_boot.hpp @@ -1,7 +1,7 @@ #pragma once #include -#include +#include #include #include #include diff --git a/include/game/bases/d_warning_manager.hpp b/include/game/bases/d_warning_manager.hpp deleted file mode 100644 index 2e2193c1..00000000 --- a/include/game/bases/d_warning_manager.hpp +++ /dev/null @@ -1,27 +0,0 @@ -#pragma once - -#include - -class dWarningManager_c { -public: - void AllWarningEnd(bool); - void setError(int errorID) { m_b8f = true; mErrorID = errorID; } - static void CreateWarningManager(); - static void addWarningForbid() NOINLINE { m_WarningForbid++; } - static void subWarningForbid() NOINLINE { if (m_WarningForbid > 0) m_WarningForbid--; } - static bool isError() { return m_Created && m_WarningCheck; } - - u8 mPad1[0xb00]; - int m_b00; - u8 mPad2[0x5]; - bool m_b09; - u8 mPad3[0x46]; - int mErrorID; - u8 mPad4[0x3b]; - bool m_b8f; - - static bool m_Created; - static bool m_WarningCheck; - static int m_WarningForbid; - static dWarningManager_c *m_instance; -}; diff --git a/include/game/bases/d_wii_strap_screen.hpp b/include/game/bases/d_wii_strap_screen.hpp deleted file mode 100644 index 30cc4777..00000000 --- a/include/game/bases/d_wii_strap_screen.hpp +++ /dev/null @@ -1,12 +0,0 @@ -#pragma once - -#include -#include - -class dWiiStrapScreen_c : public dBase_c { -public: - - LytBase_c mLayout; - bool mHasLoadedLayout; - bool mVisible; -}; diff --git a/include/types.h b/include/types.h index a596d92e..ece753da 100644 --- a/include/types.h +++ b/include/types.h @@ -49,6 +49,7 @@ typedef int BOOL; // Macros #define ARRAY_SIZE(a) (sizeof(a) / sizeof(a[0])) +#define ARRAY_MAX_STRLEN(a) (ARRAY_SIZE(a) - 1) #define ARRAY_LAST(a) (a[ARRAY_SIZE(a) - 1]) #define BIT_FLAG(bit) ((bit) < 0 ? 0 : 1 << (bit)) #define ROUND_UP(x, align) (((x) + (align) - 1) & (-(align))) diff --git a/prepare_objdiff.py b/prepare_objdiff.py index 05c08d93..a1d14713 100644 --- a/prepare_objdiff.py +++ b/prepare_objdiff.py @@ -43,7 +43,8 @@ def text_to_syms(syms_text: str) -> dict[tuple[str, int], tuple[str, dict[str, s if re.match(r'^\@\d+$', sym): # All @ symbols are local comment_dict['scope'] = 'local' - orig_syms[(sec, addr)] = (sym, comment_dict) + if not re.match(r'\.\.\..+', sym): + orig_syms[(sec, addr)] = (sym, comment_dict) # Symbols that appear multiple times must also be local for _, (sym, comment_dict) in orig_syms.items(): @@ -226,7 +227,7 @@ def get_dtk(tag: str) -> str: o_sym, o_attrs = dol_syms[(sec, addr)] n_sym, n_attrs = new_syms[(sec, addr)] if 'size' in o_attrs and o_attrs['size'] != 0: - if 'size' not in n_attrs or n_attrs['size'] != o_attrs['size']: + if 'size' not in n_attrs or n_attrs['size'] < o_attrs['size']: n_attrs['size'] = o_attrs['size'] if re.match(r'\.\.\..+', n_sym) and n_sym != o_sym: new_syms[(sec, addr)] = (o_sym, o_attrs) diff --git a/slices/wiimj2d.json b/slices/wiimj2d.json index 1870dc6c..59fa5585 100644 --- a/slices/wiimj2d.json +++ b/slices/wiimj2d.json @@ -466,6 +466,15 @@ ".sdata2": "0x2290-0x22d0" } }, + { + "source": "dol/bases/d_WiiStrapScreen.cpp", + "memoryRanges": { + ".text": "0x108900-0x108db0", + ".data": "0x24940-0x24ac8", + ".sdata": "0x1bc0-0x1bf0", + ".sbss2": "0x20-0x28" + } + }, { "source": "dol/bases/d_a_iceball.cpp", "memoryRanges": { diff --git a/source/dol/bases/d_WiiStrapScreen.cpp b/source/dol/bases/d_WiiStrapScreen.cpp new file mode 100644 index 00000000..d5889d21 --- /dev/null +++ b/source/dol/bases/d_WiiStrapScreen.cpp @@ -0,0 +1,121 @@ +#include +#include +#include +#include +#include +#include + +BASE_PROFILE(WII_STRAP, dWiiStrapScreen_c); + +dWiiStrapScreen_c::dWiiStrapScreen_c() : mHasLoadedLayout(false) {} + +dWiiStrapScreen_c::~dWiiStrapScreen_c() {} + +int dWiiStrapScreen_c::create() { + if (mHasLoadedLayout) { + return SUCCEEDED; + } + if (!createLayout()) { + return NOT_READY; + } + mHasLoadedLayout = true; + mVisible = true; + return SUCCEEDED; +} + +bool dWiiStrapScreen_c::createLayout() { + static const char *AnmNameTblEng[ANIM_NAME_COUNT] = { "wiiStrap_EngEU_00_roop.brlan" }; + static const char *AnmNameTblFra[ANIM_NAME_COUNT] = { "wiiStrap_FraEU_00_roop.brlan" }; + static const char *AnmNameTblGer[ANIM_NAME_COUNT] = { "wiiStrap_GerEU_00_roop.brlan" }; + static const char *AnmNameTblIta[ANIM_NAME_COUNT] = { "wiiStrap_ItaEU_00_roop.brlan" }; + static const char *AnmNameTblSpa[ANIM_NAME_COUNT] = { "wiiStrap_SpaEU_00_roop.brlan" }; + static const char *AnmNameTblNed[ANIM_NAME_COUNT] = { "wiiStrap_NedEU_00_roop.brlan" }; + + static const char *GROUP_NAME_DT[ANIM_COUNT] = { "A00_Strap" }; + + static const int ANIME_INDEX_TBL[ANIM_COUNT] = { roop }; + + if (mHasLoadedLayout) { + return true; + } + + switch (dGameCom::GetLanguageHBM()) { + case SC_LANG_NL: + if (!mLayout.ReadResource3("WiiStrap/WiiStrap.arc", 2)) { + return false; + } + break; + default: + if (!mLayout.ReadResourceEx("WiiStrap/WiiStrap.arc", 2, true)) { + return false; + } + break; + } + + + char filename[100]; + memset(filename, 0, ARRAY_SIZE(filename)); + strncat(filename, "wiiStrap_", ARRAY_MAX_STRLEN(filename)); + switch (dGameCom::GetLanguageHBM()) { + default: + strncat(filename, "EngEU_00", ARRAY_MAX_STRLEN(filename)); break; + case SC_LANG_FR: + strncat(filename, "FraEU_00", ARRAY_MAX_STRLEN(filename)); break; + case SC_LANG_DE: + strncat(filename, "GerEU_00", ARRAY_MAX_STRLEN(filename)); break; + case SC_LANG_IT: + strncat(filename, "ItaEU_00", ARRAY_MAX_STRLEN(filename)); break; + case SC_LANG_SP: + strncat(filename, "SpaEU_00", ARRAY_MAX_STRLEN(filename)); break; + case SC_LANG_NL: + strncat(filename, "NedEU_00", ARRAY_MAX_STRLEN(filename)); break; + } + strncat(filename, ".brlyt", ARRAY_MAX_STRLEN(filename)); + + mLayout.build(filename, nullptr); + + switch (dGameCom::GetLanguageHBM()) { + default: + mLayout.AnimeResRegister(AnmNameTblEng, ANIM_NAME_COUNT); break; + case SC_LANG_FR: + mLayout.AnimeResRegister(AnmNameTblFra, ANIM_NAME_COUNT); break; + case SC_LANG_DE: + mLayout.AnimeResRegister(AnmNameTblGer, ANIM_NAME_COUNT); break; + case SC_LANG_IT: + mLayout.AnimeResRegister(AnmNameTblIta, ANIM_NAME_COUNT); break; + case SC_LANG_SP: + mLayout.AnimeResRegister(AnmNameTblSpa, ANIM_NAME_COUNT); break; + case SC_LANG_NL: + mLayout.AnimeResRegister(AnmNameTblNed, ANIM_NAME_COUNT); break; + } + mLayout.GroupRegister(GROUP_NAME_DT, ANIME_INDEX_TBL, ANIM_COUNT); + mLayout.LoopAnimeStartSetup(ANIM_STRAP); + + return true; +} + +int dWiiStrapScreen_c::preExecute() { + if (dBase_c::preExecute() == NOT_READY) { + return NOT_READY; + } + return mFader_c::mFader->getStatus() == mFaderBase_c::HIDDEN; +} + +int dWiiStrapScreen_c::execute() { + if (mHasLoadedLayout && mVisible) { + mLayout.AnimePlay(); + mLayout.calc(); + } + return SUCCEEDED; +} + +int dWiiStrapScreen_c::draw() { + if (mHasLoadedLayout && mVisible) { + mLayout.entry(); + } + return SUCCEEDED; +} + +int dWiiStrapScreen_c::doDelete() { + return mLayout.doDelete(); +} diff --git a/source/dol/bases/d_s_boot.cpp b/source/dol/bases/d_s_boot.cpp index e89acaa8..0548a7e4 100644 --- a/source/dol/bases/d_s_boot.cpp +++ b/source/dol/bases/d_s_boot.cpp @@ -18,7 +18,7 @@ #include #include #include -#include +#include #include #include diff --git a/syms.txt b/syms.txt index e3af0653..5f358620 100644 --- a/syms.txt +++ b/syms.txt @@ -140,6 +140,7 @@ SetSoftLight_Boss__8dGameComFRQ23m3d6bmdl_ci=0x800B4050 SetSoftLight_Enemy__8dGameComFRQ23m3d6bmdl_ci=0x800B4170 SetSoftLight_MapObj__8dGameComFRQ23m3d6bmdl_ci=0x800B42B0 SelectCursorSetup__8dGameComFPQ34nw4r3lyt4Paneib=0x800B44D0 +GetLanguageHBM__8dGameComFv=0x800B4630 PlayerEnterCheck__8dGameComFi=0x800B4760 Player1upColor__8dGameComFP12LytTextBox_ci=0x800B4780 isNowCourseClear__8dGameComFv=0x800B4E30 @@ -162,7 +163,9 @@ FUN_800bbc40__7dInfo_cFiii=0x800BBC40 GetMapEnemyInfo__7dInfo_cFiiRQ27dInfo_c7enemy_s=0x800BBC60 __ct__9LytBase_cFv=0x800C89A0 __dt__9LytBase_cFv=0x800C89F0 +ReadResourceEx__9LytBase_cFPCcib=0x800C8C00 ReadResource__9LytBase_cFPCcb=0x800C8D00 +ReadResource3__9LytBase_cFPCci=0x800C8DB0 NPaneRegister__9LytBase_cFPPCcPPQ34nw4r3lyt4Panei=0x800C8E50 WPaneRegister__9LytBase_cFPPCcPPQ34nw4r3lyt6Windowi=0x800C8EC0 PPaneRegister__9LytBase_cFPPCcPPQ34nw4r3lyt7Picturei=0x800C8F30 @@ -578,6 +581,7 @@ snprintf=0x802E19D8 sprintf=0x802E1ACC strcpy=0x802E1C28 strncpy=0x802E1CE8 +strncat=0x802E1D58 strcmp=0x802E1DA4 strrchr=0x802E1F30 fmod=0x802E8904