From 40176c77cbe05034d32ae769cb284122a56ba235 Mon Sep 17 00:00:00 2001 From: kiwi515 <49212064+kiwi515@users.noreply.github.com> Date: Sat, 13 Dec 2025 15:49:02 -0500 Subject: [PATCH 1/3] RPSysKokeshiManager + save data classes --- config/RSPE01_01/splits.txt | 3 +- config/RSPE01_01/symbols.txt | 270 ++-- configure.py | 10 +- include/Pack/RPGraphics/RPGrpModel.h | 11 + include/Pack/RPGraphics/RPGrpModelManager.h | 2 +- include/Pack/RPGraphics/RPGrpModelMaterial.h | 75 +- include/Pack/RPGraphics/RPGrpModelRfl.h | 19 +- include/Pack/RPGraphics/RPGrpTexture.h | 12 +- include/Pack/RPKernel/RPSysAvatar.h | 9 +- include/Pack/RPKernel/RPSysFrameCtrl.h | 2 +- include/Pack/RPKernel/RPSysKokeshi.h | 6 +- include/Pack/RPKernel/RPSysKokeshiCtrlMgr.h | 6 +- include/Pack/RPKernel/RPSysKokeshiGenInfo.h | 12 +- include/Pack/RPKernel/RPSysKokeshiIterater.h | 3 +- include/Pack/RPKernel/RPSysKokeshiManager.h | 315 ++++- include/Pack/RPKernel/RPSysLayout.h | 2 +- include/Pack/RPKernel/RPSysLytAnmObj.h | 2 +- include/Pack/RPSystem.h | 8 +- include/Pack/RPSystem/RPPartyPlayerData.h | 136 ++ include/Pack/RPSystem/RPPartySystemData.h | 93 ++ include/Pack/RPSystem/RPSportsPlayerData.h | 781 +++++++++++ include/Pack/RPSystem/RPSportsSystemData.h | 169 +++ include/Pack/RPSystem/RPSysPlayer.h | 35 + include/Pack/RPSystem/RPSysPlayerMgr.h | 33 + include/Pack/RPSystem/RPSysResourceManager.h | 2 +- include/Pack/RPSystem/RPSysSaveData.h | 165 +++ include/Pack/RPSystem/RPSysSceneCreator.h | 4 +- include/Pack/RPSystem/RPSysSceneMgr.h | 2 +- include/Pack/common_message.h | 155 +++ include/Pack/sports_message.h | 1222 ++++++++++++++++++ include/RVLFaceLib/RFL_Types.h | 10 + include/nw4r/g3d/g3d_scnrfl.h | 4 + include/revolution/WPAD/WPAD.h | 2 + include/revolution/WUD/WUD.h | 1 + src/Pack/RPGraphics/RPGrpModelRfl.cpp | 2 +- src/Pack/RPKernel/RPSysFile.cpp | 4 + src/Pack/RPKernel/RPSysKokeshi.cpp | 10 +- src/Pack/RPKernel/RPSysKokeshiGenInfo.cpp | 4 +- src/Pack/RPKernel/RPSysKokeshiManager.cpp | 734 +++++++++++ src/Pack/RPKernel/RPSysStringUtility.cpp | 4 + src/Pack/RPSystem/RPPartyPlayerData.cpp | 85 ++ src/Pack/RPSystem/RPPartySystemData.cpp | 10 + src/Pack/RPSystem/RPSportsPlayerData.cpp | 990 ++++++++++++++ src/Pack/RPSystem/RPSportsSystemData.cpp | 200 +++ src/Pack/RPSystem/RPSysProjectLocal.cpp | 2 +- src/Pack/RPSystem/RPSysSaveData.cpp | 227 ++++ 46 files changed, 5625 insertions(+), 228 deletions(-) create mode 100644 include/Pack/RPSystem/RPPartyPlayerData.h create mode 100644 include/Pack/RPSystem/RPPartySystemData.h create mode 100644 include/Pack/RPSystem/RPSportsPlayerData.h create mode 100644 include/Pack/RPSystem/RPSportsSystemData.h create mode 100644 include/Pack/RPSystem/RPSysPlayer.h create mode 100644 include/Pack/RPSystem/RPSysPlayerMgr.h create mode 100644 include/Pack/RPSystem/RPSysSaveData.h create mode 100644 include/Pack/common_message.h create mode 100644 include/Pack/sports_message.h create mode 100644 src/Pack/RPKernel/RPSysKokeshiManager.cpp create mode 100644 src/Pack/RPSystem/RPPartyPlayerData.cpp create mode 100644 src/Pack/RPSystem/RPPartySystemData.cpp create mode 100644 src/Pack/RPSystem/RPSportsPlayerData.cpp create mode 100644 src/Pack/RPSystem/RPSportsSystemData.cpp create mode 100644 src/Pack/RPSystem/RPSysSaveData.cpp diff --git a/config/RSPE01_01/splits.txt b/config/RSPE01_01/splits.txt index 6a4e79cb..25186a4f 100644 --- a/config/RSPE01_01/splits.txt +++ b/config/RSPE01_01/splits.txt @@ -2783,13 +2783,14 @@ Pack/RPSystem/RPSysDvdStatus.cpp: Pack/RPSystem/RPSysSaveDataMgr.cpp: .text start:0x80188368 end:0x8018A90C - .rodata start:0x803829E0 end:0x80382A50 + .rodata start:0x803829E0 end:0x80382A30 .data start:0x803B9938 end:0x803B994C .sdata start:0x804BDB88 end:0x804BDB98 .sbss start:0x804BF508 end:0x804BF510 Pack/RPSystem/RPSportsSystemData.cpp: .text start:0x8018A90C end:0x8018AD70 + .rodata start:0x80382A30 end:0x80382A50 Pack/RPSystem/RPSportsPlayerData.cpp: .text start:0x8018AD70 end:0x8018BCDC diff --git a/config/RSPE01_01/symbols.txt b/config/RSPE01_01/symbols.txt index bec68251..2b4633fd 100644 --- a/config/RSPE01_01/symbols.txt +++ b/config/RSPE01_01/symbols.txt @@ -7081,115 +7081,115 @@ fn_8018A39C = .text:0x8018A39C; // type:function size:0x508 fn_8018A8A4 = .text:0x8018A8A4; // type:function size:0x60 ListenPropertyEvent__18IRPSysHostIOSocketFv = .text:0x8018A904; // type:function size:0x4 GenMessage__18IRPSysHostIOSocketFv = .text:0x8018A908; // type:function size:0x4 -fn_8018A90C = .text:0x8018A90C; // type:function size:0xC4 -fn_8018A9D0 = .text:0x8018A9D0; // type:function size:0xC0 -fn_8018AA90 = .text:0x8018AA90; // type:function size:0x28 -fn_8018AAB8 = .text:0x8018AAB8; // type:function size:0x38 -fn_8018AAF0 = .text:0x8018AAF0; // type:function size:0x20 -fn_8018AB10 = .text:0x8018AB10; // type:function size:0x30 -fn_8018AB40 = .text:0x8018AB40; // type:function size:0x8 -fn_8018AB48 = .text:0x8018AB48; // type:function size:0x8 -fn_8018AB50 = .text:0x8018AB50; // type:function size:0x8 -fn_8018AB58 = .text:0x8018AB58; // type:function size:0x8 -fn_8018AB60 = .text:0x8018AB60; // type:function size:0x80 -fn_8018ABE0 = .text:0x8018ABE0; // type:function size:0x84 -fn_8018AC64 = .text:0x8018AC64; // type:function size:0xD0 -fn_8018AD34 = .text:0x8018AD34; // type:function size:0x3C -fn_8018AD70 = .text:0x8018AD70; // type:function size:0x374 -fn_8018B0E4 = .text:0x8018B0E4; // type:function size:0x368 -fn_8018B44C = .text:0x8018B44C; // type:function size:0x8 -fn_8018B454 = .text:0x8018B454; // type:function size:0x8 -fn_8018B45C = .text:0x8018B45C; // type:function size:0x44 -fn_8018B4A0 = .text:0x8018B4A0; // type:function size:0x44 -fn_8018B4E4 = .text:0x8018B4E4; // type:function size:0x28 -fn_8018B50C = .text:0x8018B50C; // type:function size:0xC -fn_8018B518 = .text:0x8018B518; // type:function size:0x8 -fn_8018B520 = .text:0x8018B520; // type:function size:0x8 -fn_8018B528 = .text:0x8018B528; // type:function size:0x10 -fn_8018B538 = .text:0x8018B538; // type:function size:0x10 -fn_8018B548 = .text:0x8018B548; // type:function size:0x10 -fn_8018B558 = .text:0x8018B558; // type:function size:0x10 -fn_8018B568 = .text:0x8018B568; // type:function size:0x8 -fn_8018B570 = .text:0x8018B570; // type:function size:0x8 -fn_8018B578 = .text:0x8018B578; // type:function size:0x18 -fn_8018B590 = .text:0x8018B590; // type:function size:0x18 -fn_8018B5A8 = .text:0x8018B5A8; // type:function size:0xC -fn_8018B5B4 = .text:0x8018B5B4; // type:function size:0xC -fn_8018B5C0 = .text:0x8018B5C0; // type:function size:0x10 -fn_8018B5D0 = .text:0x8018B5D0; // type:function size:0x10 -fn_8018B5E0 = .text:0x8018B5E0; // type:function size:0x8 -fn_8018B5E8 = .text:0x8018B5E8; // type:function size:0x8 -fn_8018B5F0 = .text:0x8018B5F0; // type:function size:0x8 -fn_8018B5F8 = .text:0x8018B5F8; // type:function size:0x8 -fn_8018B600 = .text:0x8018B600; // type:function size:0x10 -fn_8018B610 = .text:0x8018B610; // type:function size:0x10 -fn_8018B620 = .text:0x8018B620; // type:function size:0x10 -fn_8018B630 = .text:0x8018B630; // type:function size:0x10 -fn_8018B640 = .text:0x8018B640; // type:function size:0x8 -fn_8018B648 = .text:0x8018B648; // type:function size:0x8 -fn_8018B650 = .text:0x8018B650; // type:function size:0xC -fn_8018B65C = .text:0x8018B65C; // type:function size:0x10 -fn_8018B66C = .text:0x8018B66C; // type:function size:0x10 -fn_8018B67C = .text:0x8018B67C; // type:function size:0x10 -fn_8018B68C = .text:0x8018B68C; // type:function size:0x8 -fn_8018B694 = .text:0x8018B694; // type:function size:0x8 -fn_8018B69C = .text:0x8018B69C; // type:function size:0x8 -fn_8018B6A4 = .text:0x8018B6A4; // type:function size:0x8 -fn_8018B6AC = .text:0x8018B6AC; // type:function size:0x8 -fn_8018B6B4 = .text:0x8018B6B4; // type:function size:0x8 -fn_8018B6BC = .text:0x8018B6BC; // type:function size:0x8 -fn_8018B6C4 = .text:0x8018B6C4; // type:function size:0x8 -fn_8018B6CC = .text:0x8018B6CC; // type:function size:0x8 -fn_8018B6D4 = .text:0x8018B6D4; // type:function size:0x8 -fn_8018B6DC = .text:0x8018B6DC; // type:function size:0x8 -fn_8018B6E4 = .text:0x8018B6E4; // type:function size:0x8 -fn_8018B6EC = .text:0x8018B6EC; // type:function size:0xC -fn_8018B6F8 = .text:0x8018B6F8; // type:function size:0xC -fn_8018B704 = .text:0x8018B704; // type:function size:0x8 -fn_8018B70C = .text:0x8018B70C; // type:function size:0x8 -fn_8018B714 = .text:0x8018B714; // type:function size:0x8 -fn_8018B71C = .text:0x8018B71C; // type:function size:0x8 -fn_8018B724 = .text:0x8018B724; // type:function size:0x20 -fn_8018B744 = .text:0x8018B744; // type:function size:0x28 -fn_8018B76C = .text:0x8018B76C; // type:function size:0x10 -fn_8018B77C = .text:0x8018B77C; // type:function size:0xC -fn_8018B788 = .text:0x8018B788; // type:function size:0x18 -fn_8018B7A0 = .text:0x8018B7A0; // type:function size:0x18 -fn_8018B7B8 = .text:0x8018B7B8; // type:function size:0x18 -fn_8018B7D0 = .text:0x8018B7D0; // type:function size:0x18 -fn_8018B7E8 = .text:0x8018B7E8; // type:function size:0x10 -fn_8018B7F8 = .text:0x8018B7F8; // type:function size:0x10 -fn_8018B808 = .text:0x8018B808; // type:function size:0x18 -fn_8018B820 = .text:0x8018B820; // type:function size:0x18 -fn_8018B838 = .text:0x8018B838; // type:function size:0x10 -fn_8018B848 = .text:0x8018B848; // type:function size:0x10 -fn_8018B858 = .text:0x8018B858; // type:function size:0x18 -fn_8018B870 = .text:0x8018B870; // type:function size:0x18 -fn_8018B888 = .text:0x8018B888; // type:function size:0x10 -fn_8018B898 = .text:0x8018B898; // type:function size:0x10 -fn_8018B8A8 = .text:0x8018B8A8; // type:function size:0x50 -fn_8018B8F8 = .text:0x8018B8F8; // type:function size:0x48 -fn_8018B940 = .text:0x8018B940; // type:function size:0x2C -fn_8018B96C = .text:0x8018B96C; // type:function size:0x28 -fn_8018B994 = .text:0x8018B994; // type:function size:0x30C -fn_8018BCA0 = .text:0x8018BCA0; // type:function size:0x3C +write__18RPSportsSystemDataFRQ23EGG9RamStream = .text:0x8018A90C; // type:function size:0xC4 +read__18RPSportsSystemDataFRQ23EGG9RamStream = .text:0x8018A9D0; // type:function size:0xC0 +isGameOpen__18RPSportsSystemDataCFUc = .text:0x8018AA90; // type:function size:0x28 +setGameOpen__18RPSportsSystemDataFUcb = .text:0x8018AAB8; // type:function size:0x38 +isGameOpenDemo__18RPSportsSystemDataCFUc = .text:0x8018AAF0; // type:function size:0x20 +setGameOpenDemo__18RPSportsSystemDataFUcb = .text:0x8018AB10; // type:function size:0x30 +getPhysicalEndLastDate__18RPSportsSystemDataCFv = .text:0x8018AB40; // type:function size:0x8 +setPhysicalEndLastDate__18RPSportsSystemDataFUs = .text:0x8018AB48; // type:function size:0x8 +getPhysicalEndCount__18RPSportsSystemDataCFv = .text:0x8018AB50; // type:function size:0x8 +setPhysicalEndCount__18RPSportsSystemDataFUc = .text:0x8018AB58; // type:function size:0x8 +setOldData__18RPSportsSystemDataFScPCUcll = .text:0x8018AB60; // type:function size:0x80 +getOldData__18RPSportsSystemDataCFPScPUcll = .text:0x8018ABE0; // type:function size:0x84 +reset__18RPSportsSystemDataFv = .text:0x8018AC64; // type:function size:0xD0 +__ct__18RPSportsSystemDataFv = .text:0x8018AD34; // type:function size:0x3C +write__18RPSportsPlayerDataFRQ23EGG9RamStream = .text:0x8018AD70; // type:function size:0x374 +read__18RPSportsPlayerDataFRQ23EGG9RamStream = .text:0x8018B0E4; // type:function size:0x368 +setDebutTime__18RPSportsPlayerDataFUl = .text:0x8018B44C; // type:function size:0x8 +getDebutTime__18RPSportsPlayerDataCFv = .text:0x8018B454; // type:function size:0x8 +setCreateID__18RPSportsPlayerDataFPC11RFLCreateID = .text:0x8018B45C; // type:function size:0x44 +getCreateID__18RPSportsPlayerDataCFP11RFLCreateID = .text:0x8018B4A0; // type:function size:0x44 +setRegistered__18RPSportsPlayerDataFb = .text:0x8018B4E4; // type:function size:0x28 +isRegistered__18RPSportsPlayerDataCFv = .text:0x8018B50C; // type:function size:0xC +setPhysicalBeginLastDate__18RPSportsPlayerDataFUs = .text:0x8018B518; // type:function size:0x8 +getPhysicalBeginLastDate__18RPSportsPlayerDataCFv = .text:0x8018B520; // type:function size:0x8 +setPhysicalDateHistory__18RPSportsPlayerDataFUsUl = .text:0x8018B528; // type:function size:0x10 +getPhysicalDateHistory__18RPSportsPlayerDataCFUl = .text:0x8018B538; // type:function size:0x10 +setPhysicalStatSumHistory__18RPSportsPlayerDataFUsUl = .text:0x8018B548; // type:function size:0x10 +getPhysicalStatSumHistory__18RPSportsPlayerDataCFUl = .text:0x8018B558; // type:function size:0x10 +setPhysicalEndLastDate__18RPSportsPlayerDataFUs = .text:0x8018B568; // type:function size:0x8 +getPhysicalEndLastDate__18RPSportsPlayerDataCFv = .text:0x8018B570; // type:function size:0x8 +setPhysicalStatSumBest__18RPSportsPlayerDataFUsQ218RPSportsPlayerData6ESportQ218RPSportsPlayerData5EGame = .text:0x8018B578; // type:function size:0x18 +getPhysicalStatSumBest__18RPSportsPlayerDataCFQ218RPSportsPlayerData6ESportQ218RPSportsPlayerData5EGame = .text:0x8018B590; // type:function size:0x18 +setPhysicalEvent__18RPSportsPlayerDataFUcUl = .text:0x8018B5A8; // type:function size:0xC +getPhysicalEvent__18RPSportsPlayerDataCFUl = .text:0x8018B5B4; // type:function size:0xC +setPhysicalStat__18RPSportsPlayerDataFUsQ218RPSportsPlayerData5EStat = .text:0x8018B5C0; // type:function size:0x10 +getPhysicalStat__18RPSportsPlayerDataCFQ218RPSportsPlayerData5EStat = .text:0x8018B5D0; // type:function size:0x10 +setPhysicalEndCount__18RPSportsPlayerDataFUs = .text:0x8018B5E0; // type:function size:0x8 +getPhysicalEndCount__18RPSportsPlayerDataCFv = .text:0x8018B5E8; // type:function size:0x8 +setPhysicalEndFirstDate__18RPSportsPlayerDataFUs = .text:0x8018B5F0; // type:function size:0x8 +getPhysicalEndFirstDate__18RPSportsPlayerDataCFv = .text:0x8018B5F8; // type:function size:0x8 +setBoxTrainingBest__18RPSportsPlayerDataFUsQ218RPSportsPlayerData5EGame = .text:0x8018B600; // type:function size:0x10 +getBoxTrainingBest__18RPSportsPlayerDataCFQ218RPSportsPlayerData5EGame = .text:0x8018B610; // type:function size:0x10 +setGolTrainingBest__18RPSportsPlayerDataFUsQ218RPSportsPlayerData5EGame = .text:0x8018B620; // type:function size:0x10 +getGolTrainingBest__18RPSportsPlayerDataCFQ218RPSportsPlayerData5EGame = .text:0x8018B630; // type:function size:0x10 +setGolAceCount__18RPSportsPlayerDataFUc = .text:0x8018B640; // type:function size:0x8 +getGolAceCount__18RPSportsPlayerDataCFv = .text:0x8018B648; // type:function size:0x8 +setGolStandardBest__18RPSportsPlayerDataFScQ218RPSportsPlayerData7ECourse = .text:0x8018B650; // type:function size:0xC +getGolStandardBest__18RPSportsPlayerDataCFQ218RPSportsPlayerData7ECourse = .text:0x8018B65C; // type:function size:0x10 +setBowTrainingBest__18RPSportsPlayerDataFUsQ218RPSportsPlayerData5EGame = .text:0x8018B66C; // type:function size:0x10 +getBowTrainingBest__18RPSportsPlayerDataCFQ218RPSportsPlayerData5EGame = .text:0x8018B67C; // type:function size:0x10 +setBowPerfectCount__18RPSportsPlayerDataFUc = .text:0x8018B68C; // type:function size:0x8 +getBowPerfectCount__18RPSportsPlayerDataCFv = .text:0x8018B694; // type:function size:0x8 +setBowStandardBest__18RPSportsPlayerDataFUs = .text:0x8018B69C; // type:function size:0x8 +getBowStandardBest__18RPSportsPlayerDataCFv = .text:0x8018B6A4; // type:function size:0x8 +setBsbRenzokuBest__18RPSportsPlayerDataFUc = .text:0x8018B6AC; // type:function size:0x8 +getBsbRenzokuBest__18RPSportsPlayerDataCFv = .text:0x8018B6B4; // type:function size:0x8 +setBsbUchiwakeBest__18RPSportsPlayerDataFUc = .text:0x8018B6BC; // type:function size:0x8 +getBsbUchiwakeBest__18RPSportsPlayerDataCFv = .text:0x8018B6C4; // type:function size:0x8 +setBsbHomerunDistBest__18RPSportsPlayerDataFUs = .text:0x8018B6CC; // type:function size:0x8 +getBsbHomerunDistBest__18RPSportsPlayerDataCFv = .text:0x8018B6D4; // type:function size:0x8 +setBsbHomerunRunsBest__18RPSportsPlayerDataFUc = .text:0x8018B6DC; // type:function size:0x8 +getBsbHomerunRunsBest__18RPSportsPlayerDataCFv = .text:0x8018B6E4; // type:function size:0x8 +setTnsTrainingBest__18RPSportsPlayerDataFUcQ218RPSportsPlayerData5EGame = .text:0x8018B6EC; // type:function size:0xC +getTnsTrainingBest__18RPSportsPlayerDataCFQ218RPSportsPlayerData5EGame = .text:0x8018B6F8; // type:function size:0xC +setTnsSuccess__18RPSportsPlayerDataFf = .text:0x8018B704; // type:function size:0x8 +getTnsSuccess__18RPSportsPlayerDataCFv = .text:0x8018B70C; // type:function size:0x8 +setTnsDifficulty__18RPSportsPlayerDataFf = .text:0x8018B714; // type:function size:0x8 +getTnsDifficulty__18RPSportsPlayerDataCFv = .text:0x8018B71C; // type:function size:0x8 +setDefeatChampion__18RPSportsPlayerDataFQ218RPSportsPlayerData6ESport = .text:0x8018B724; // type:function size:0x20 +isDefeatChampion__18RPSportsPlayerDataCFQ218RPSportsPlayerData6ESport = .text:0x8018B744; // type:function size:0x28 +setFirstPlay__18RPSportsPlayerDataFv = .text:0x8018B76C; // type:function size:0x10 +isFirstPlay__18RPSportsPlayerDataCFv = .text:0x8018B77C; // type:function size:0xC +setTrainingMedal__18RPSportsPlayerDataFUcQ218RPSportsPlayerData6ESportQ218RPSportsPlayerData5EGame = .text:0x8018B788; // type:function size:0x18 +getTrainingMedal__18RPSportsPlayerDataCFQ218RPSportsPlayerData6ESportQ218RPSportsPlayerData5EGame = .text:0x8018B7A0; // type:function size:0x18 +setTrainingPlayCount__18RPSportsPlayerDataFUsQ218RPSportsPlayerData6ESportQ218RPSportsPlayerData5EGame = .text:0x8018B7B8; // type:function size:0x18 +getTrainingPlayCount__18RPSportsPlayerDataCFQ218RPSportsPlayerData6ESportQ218RPSportsPlayerData5EGame = .text:0x8018B7D0; // type:function size:0x18 +setStandardPlayCount__18RPSportsPlayerDataFUsQ218RPSportsPlayerData6ESport = .text:0x8018B7E8; // type:function size:0x10 +getStandardPlayCount__18RPSportsPlayerDataCFQ218RPSportsPlayerData6ESport = .text:0x8018B7F8; // type:function size:0x10 +setTrainingFirstDate__18RPSportsPlayerDataFUsQ218RPSportsPlayerData6ESportQ218RPSportsPlayerData5EGame = .text:0x8018B808; // type:function size:0x18 +getTrainingFirstDate__18RPSportsPlayerDataCFQ218RPSportsPlayerData6ESportQ218RPSportsPlayerData5EGame = .text:0x8018B820; // type:function size:0x18 +setStandardFirstDate__18RPSportsPlayerDataFUsQ218RPSportsPlayerData6ESport = .text:0x8018B838; // type:function size:0x10 +getStandardFirstDate__18RPSportsPlayerDataCFQ218RPSportsPlayerData6ESport = .text:0x8018B848; // type:function size:0x10 +setSkillGraphPoint__18RPSportsPlayerDataFsQ218RPSportsPlayerData6ESportUl = .text:0x8018B858; // type:function size:0x18 +getSkillGraphPoint__18RPSportsPlayerDataCFQ218RPSportsPlayerData6ESportUl = .text:0x8018B870; // type:function size:0x18 +setSkillLevel__18RPSportsPlayerDataFQ218RPSportsPlayerData6ESportf = .text:0x8018B888; // type:function size:0x10 +getSkillLevel__18RPSportsPlayerDataCFQ218RPSportsPlayerData6ESport = .text:0x8018B898; // type:function size:0x10 +setHandSecondary__18RPSportsPlayerDataFQ218RPSportsPlayerData5EHandQ218RPSportsPlayerData6ESport = .text:0x8018B8A8; // type:function size:0x50 +setHandPrimary__18RPSportsPlayerDataFQ218RPSportsPlayerData5EHandQ218RPSportsPlayerData6ESport = .text:0x8018B8F8; // type:function size:0x48 +getHandSecondary__18RPSportsPlayerDataCFQ218RPSportsPlayerData6ESport = .text:0x8018B940; // type:function size:0x2C +getHandPrimary__18RPSportsPlayerDataCFQ218RPSportsPlayerData6ESport = .text:0x8018B96C; // type:function size:0x28 +reset__18RPSportsPlayerDataFv = .text:0x8018B994; // type:function size:0x30C +__ct__18RPSportsPlayerDataFv = .text:0x8018BCA0; // type:function size:0x3C GetResFontData__16RPSysFontManagerCFPCc = .text:0x8018BCDC; // type:function size:0x88 fn_8018BD64 = .text:0x8018BD64; // type:function size:0xAC fn_8018BE10 = .text:0x8018BE10; // type:function size:0x54 fn_8018BE64 = .text:0x8018BE64; // type:function size:0x40 fn_8018BEA4 = .text:0x8018BEA4; // type:function size:0xB0 -fn_8018BF54 = .text:0x8018BF54; // type:function size:0x8 -fn_8018BF5C = .text:0x8018BF5C; // type:function size:0x184 -fn_8018C0E0 = .text:0x8018C0E0; // type:function size:0x24C -fn_8018C32C = .text:0x8018C32C; // type:function size:0x8 -fn_8018C334 = .text:0x8018C334; // type:function size:0xD8 -fn_8018C40C = .text:0x8018C40C; // type:function size:0x10 -fn_8018C41C = .text:0x8018C41C; // type:function size:0x268 -fn_8018C684 = .text:0x8018C684; // type:function size:0x8 -fn_8018C68C = .text:0x8018C68C; // type:function size:0x4E0 -fn_8018CB6C = .text:0x8018CB6C; // type:function size:0x10 -fn_8018CB7C = .text:0x8018CB7C; // type:function size:0x14 -fn_8018CB90 = .text:0x8018CB90; // type:function size:0xDC +getSaveFileSize__13RPSysSaveDataFv = .text:0x8018BF54; // type:function size:0x8 +write__13RPSysSaveDataCFRQ23EGG9RamStreamPCv = .text:0x8018BF5C; // type:function size:0x184 +read__13RPSysSaveDataFRQ23EGG9RamStreamPCv = .text:0x8018C0E0; // type:function size:0x24C +getPartySystemData__13RPSysSaveDataCFv = .text:0x8018C32C; // type:function size:0x8 +setPartyPlayerData__13RPSysSaveDataFPC17RPPartyPlayerDataUl = .text:0x8018C334; // type:function size:0xD8 +getPartyPlayerData__13RPSysSaveDataCFUl = .text:0x8018C40C; // type:function size:0x10 +setSportsSystemData__13RPSysSaveDataFPC18RPSportsSystemData = .text:0x8018C41C; // type:function size:0x268 +getSportsSystemData__13RPSysSaveDataCFv = .text:0x8018C684; // type:function size:0x8 +setSportsPlayerData__13RPSysSaveDataFPC18RPSportsPlayerDataUl = .text:0x8018C68C; // type:function size:0x4E0 +getSportsPlayerData__13RPSysSaveDataCFUl = .text:0x8018CB6C; // type:function size:0x10 +isErrorOccured__13RPSysSaveDataCFv = .text:0x8018CB7C; // type:function size:0x14 +__ct__13RPSysSaveDataFv = .text:0x8018CB90; // type:function size:0xDC fn_8018CC6C = .text:0x8018CC6C; // type:function size:0x68 fn_8018CCD4 = .text:0x8018CCD4; // type:function size:0x254 fn_8018CF28 = .text:0x8018CF28; // type:function size:0xF4 @@ -7198,14 +7198,14 @@ fn_8018D034 = .text:0x8018D034; // type:function size:0x1EC fn_8018D220 = .text:0x8018D220; // type:function size:0x1F8 fn_8018D418 = .text:0x8018D418; // type:function size:0x8 fn_8018D420 = .text:0x8018D420; // type:function size:0x28C -fn_8018D6AC = .text:0x8018D6AC; // type:function size:0x24 -fn_8018D6D0 = .text:0x8018D6D0; // type:function size:0x8 -fn_8018D6D8 = .text:0x8018D6D8; // type:function size:0x8 -fn_8018D6E0 = .text:0x8018D6E0; // type:function size:0x44 -fn_8018D724 = .text:0x8018D724; // type:function size:0x44 -fn_8018D768 = .text:0x8018D768; // type:function size:0x28 -fn_8018D790 = .text:0x8018D790; // type:function size:0xC -fn_8018D79C = .text:0x8018D79C; // type:function size:0xB0 +isGameOpen__17RPPartySystemDataCFl = .text:0x8018D6AC; // type:function size:0x24 +setDebutTime__17RPPartyPlayerDataFUl = .text:0x8018D6D0; // type:function size:0x8 +getDebutTime__17RPPartyPlayerDataCFv = .text:0x8018D6D8; // type:function size:0x8 +setCreateID__17RPPartyPlayerDataFPC11RFLCreateID = .text:0x8018D6E0; // type:function size:0x44 +getCreateID__17RPPartyPlayerDataCFP11RFLCreateID = .text:0x8018D724; // type:function size:0x44 +setRegistered__17RPPartyPlayerDataFb = .text:0x8018D768; // type:function size:0x28 +isRegistered__17RPPartyPlayerDataCFv = .text:0x8018D790; // type:function size:0xC +reset__17RPPartyPlayerDataFv = .text:0x8018D79C; // type:function size:0xB0 fn_8018D84C = .text:0x8018D84C; // type:function size:0x40 fn_8018D88C = .text:0x8018D88C; // type:function size:0x1C0 fn_8018DA4C = .text:0x8018DA4C; // type:function size:0x34 @@ -7265,34 +7265,34 @@ ApplyLightTexture__12RPSysKokeshiFUc = .text:0x80190FAC; // type:function size:0 LoadResource__12RPSysKokeshiFPC24RPSysKokeshiOverloadInfo = .text:0x80191088; // type:function size:0x39C __dt__12RPSysKokeshiFv = .text:0x80191424; // type:function size:0x58 __ct__12RPSysKokeshiFPC19RPSysKokeshiGenInfo = .text:0x8019147C; // type:function size:0x44 -fn_801914C0 = .text:0x801914C0; // type:function size:0x14 +UpdateCtrlMgr__19RPSysKokeshiManagerFv = .text:0x801914C0; // type:function size:0x14 ClearCtrlMgr__19RPSysKokeshiManagerFv = .text:0x801914D4; // type:function size:0xC SetCtrlMgr__19RPSysKokeshiManagerFP19RPSysKokeshiCtrlMgr = .text:0x801914E0; // type:function size:0x8 RegistLocation__19RPSysKokeshiManagerFRC20RPSysKokeshiLocation = .text:0x801914E8; // type:function size:0x24 GetLocationFriend__19RPSysKokeshiManagerF13RFLDataSourceP13RPSysMiddleDBP20RPSysKokeshiLocation = .text:0x8019150C; // type:function size:0x450 GetLocationPlayer__19RPSysKokeshiManagerFUcP20RPSysKokeshiLocation = .text:0x8019195C; // type:function size:0xD4 -fn_80191A30 = .text:0x80191A30; // type:function size:0x10 -fn_80191A40 = .text:0x80191A40; // type:function size:0xE8 +GetHandFileName__19RPSysKokeshiManagerFUl = .text:0x80191A30; // type:function size:0x10 +GetModelBaseScaleInvalidatedMtx__19RPSysKokeshiManagerFPQ34nw4r4math5MTX34P10RPGrpModelPCQ34nw4r4math5MTX34 = .text:0x80191A40; // type:function size:0xE8 GetAdditionalInfo__19RPSysKokeshiManagerFRC20RPSysKokeshiLocationP17RFLAdditionalInfo = .text:0x80191B28; // type:function size:0x78 -fn_80191BA0 = .text:0x80191BA0; // type:function size:0x78 -fn_80191C18 = .text:0x80191C18; // type:function size:0xD0 -fn_80191CE8 = .text:0x80191CE8; // type:function size:0x74 -fn_80191D5C = .text:0x80191D5C; // type:function size:0x8 -fn_80191D64 = .text:0x80191D64; // type:function size:0x13C -CreateNigaoeModel__19RPSysKokeshiManagerFRC20RPSysKokeshiLocation13RFLResolution13RFLExpressionUc = .text:0x80191EA0; // type:function size:0xFC -fn_80191F9C = .text:0x80191F9C; // type:function size:0x150 -fn_801920EC = .text:0x801920EC; // type:function size:0x198 -fn_80192284 = .text:0x80192284; // type:function size:0x70 -fn_801922F4 = .text:0x801922F4; // type:function size:0x54 -fn_80192348 = .text:0x80192348; // type:function size:0x38 -fn_80192380 = .text:0x80192380; // type:function size:0x10 -fn_80192390 = .text:0x80192390; // type:function size:0xC -fn_8019239C = .text:0x8019239C; // type:function size:0x70 -fn_8019240C = .text:0x8019240C; // type:function size:0x84 -fn_80192490 = .text:0x80192490; // type:function size:0x68 -fn_801924F8 = .text:0x801924F8; // type:function size:0x58 -fn_80192550 = .text:0x80192550; // type:function size:0x12C -fn_8019267C = .text:0x8019267C; // type:function size:0x34 +SetMatTevColorEffect__19RPSysKokeshiManagerFP10RPGrpModelUcUcUcUc = .text:0x80191BA0; // type:function size:0x78 +SetMatColor__19RPSysKokeshiManagerFP10RPGrpModel8_GXColor8_GXColor = .text:0x80191C18; // type:function size:0xD0 +ChangeTexture__19RPSysKokeshiManagerFP10RPGrpModelP12RPGrpTextureP12RPGrpTexture = .text:0x80191CE8; // type:function size:0x74 +CreateTexture__19RPSysKokeshiManagerFPv = .text:0x80191D5C; // type:function size:0x8 +CreateTexture__19RPSysKokeshiManagerFPvPCc = .text:0x80191D64; // type:function size:0x13C +CreateNigaoeModel__19RPSysKokeshiManagerFRC20RPSysKokeshiLocation13RFLResolutionUlUc = .text:0x80191EA0; // type:function size:0xFC +CreateModel__19RPSysKokeshiManagerFPvUsUcUlUl = .text:0x80191F9C; // type:function size:0x150 +LoadStaticResource__19RPSysKokeshiManagerFv = .text:0x801920EC; // type:function size:0x198 +SetBrightnessColor__19RPSysKokeshiManagerFP10RPGrpModel8_GXColor = .text:0x80192284; // type:function size:0x70 +SetMaterialType__19RPSysKokeshiManagerFP10RPGrpModelQ213RPGrpModelRfl12MaterialType = .text:0x801922F4; // type:function size:0x54 +Reset__19RPSysKokeshiManagerFv = .text:0x80192348; // type:function size:0x38 +GetOfficialDBIndexFromCreateID__19RPSysKokeshiManagerFPC11RFLCreateID = .text:0x80192380; // type:function size:0x10 +GetOfficialDBValidNum__19RPSysKokeshiManagerFv = .text:0x80192390; // type:function size:0xC +GetExpression__19RPSysKokeshiManagerFP10RPGrpModel = .text:0x8019239C; // type:function size:0x70 +ChangeExpression__19RPSysKokeshiManagerFP10RPGrpModel13RFLExpression = .text:0x8019240C; // type:function size:0x84 +CreateLightTexture__19RPSysKokeshiManagerFUc = .text:0x80192490; // type:function size:0x68 +__dt__19RPSysKokeshiManagerFv = .text:0x801924F8; // type:function size:0x58 +__ct__19RPSysKokeshiManagerFv = .text:0x80192550; // type:function size:0x12C +CreateInstance__19RPSysKokeshiManagerFv = .text:0x8019267C; // type:function size:0x34 __dt__15RP_DEBUG_STUB_1Fv = .text:0x801926B0; // type:function size:0x40 __ct__15RP_DEBUG_STUB_1Fv = .text:0x801926F0; // type:function size:0x10 fn_80192700 = .text:0x80192700; // type:function size:0xCC @@ -18541,7 +18541,7 @@ __vt__24RPSysHostIOSocketManager = .data:0x803B99B0; // type:object size:0xC __vt__15RPSysTextWriter = .data:0x803B99C0; // type:object size:0xC __vt__12RPSysMessage = .data:0x803B99D0; // type:object size:0xC __vt__12RPSysKokeshi = .data:0x803B99E0; // type:object size:0x18 -lbl_803B99F8 = .data:0x803B99F8; // type:object size:0x18 +__vt__19RPSysKokeshiManager = .data:0x803B99F8; // type:object size:0x18 __vt__15RP_DEBUG_STUB_1 = .data:0x803B9A10; // type:object size:0xC lbl_803B9A20 = .data:0x803B9A20; // type:object size:0x18 lbl_803B9A38 = .data:0x803B9A38; // type:object size:0x68 diff --git a/configure.py b/configure.py index 0ea514cb..5ddf83cf 100755 --- a/configure.py +++ b/configure.py @@ -1164,13 +1164,13 @@ def MatchingFor(*versions): Object(NonMatching, "Pack/RPSystem/RPSysCommonObject.cpp"), Object(NonMatching, "Pack/RPSystem/RPSysDvdStatus.cpp"), Object(NonMatching, "Pack/RPSystem/RPSysSaveDataMgr.cpp"), - Object(NonMatching, "Pack/RPSystem/RPSportsSystemData.cpp"), - Object(NonMatching, "Pack/RPSystem/RPSportsPlayerData.cpp"), + Object(Matching, "Pack/RPSystem/RPSportsSystemData.cpp"), + Object(Matching, "Pack/RPSystem/RPSportsPlayerData.cpp"), Object(NonMatching, "Pack/RPSystem/RPSysFontManager.cpp"), - Object(NonMatching, "Pack/RPSystem/RPSysSaveData.cpp"), + Object(Matching, "Pack/RPSystem/RPSysSaveData.cpp"), Object(NonMatching, "Pack/RPSystem/RPSysPauseMgr.cpp"), - Object(NonMatching, "Pack/RPSystem/RPPartySystemData.cpp"), - Object(NonMatching, "Pack/RPSystem/RPPartyPlayerData.cpp"), + Object(Matching, "Pack/RPSystem/RPPartySystemData.cpp"), + Object(Matching, "Pack/RPSystem/RPPartyPlayerData.cpp"), Object(NonMatching, "Pack/RPSystem/RPSysPlayerMgr.cpp"), Object(NonMatching, "Pack/RPSystem/RPSysPlayer.cpp"), ], diff --git a/include/Pack/RPGraphics/RPGrpModel.h b/include/Pack/RPGraphics/RPGrpModel.h index 40310760..ec6bed6c 100644 --- a/include/Pack/RPGraphics/RPGrpModel.h +++ b/include/Pack/RPGraphics/RPGrpModel.h @@ -210,6 +210,17 @@ class RPGrpModel { return mpModelEx->getScnRfl(); } + const nw4r::math::VEC3& GetScale() const { + return mScale; + } + + RPGrpModelMaterial* GetMaterial(const char* pName) const { + return mppMaterials[GetMaterialIndex(pName)]; + } + RPGrpModelMaterial* GetMaterial(u16 idx) const { + return mppMaterials[idx]; + } + bool IsVisible() const { return (mFlags & EFlag_Visible) ? true : false; } diff --git a/include/Pack/RPGraphics/RPGrpModelManager.h b/include/Pack/RPGraphics/RPGrpModelManager.h index d657da95..92e4e254 100644 --- a/include/Pack/RPGraphics/RPGrpModelManager.h +++ b/include/Pack/RPGraphics/RPGrpModelManager.h @@ -20,7 +20,7 @@ class RPGrpModelManager { return spCurrent; } - RPGrpDrawPathManager* GetDrawPathManager(); + RPGrpDrawPathManager* GetDrawPathManager(u8 drawScene) const; private: //! Allocator used for model-related allocations diff --git a/include/Pack/RPGraphics/RPGrpModelMaterial.h b/include/Pack/RPGraphics/RPGrpModelMaterial.h index 93e895f6..fe822393 100644 --- a/include/Pack/RPGraphics/RPGrpModelMaterial.h +++ b/include/Pack/RPGraphics/RPGrpModelMaterial.h @@ -19,16 +19,50 @@ class RPGrpModelMaterial { public: enum ESyncFlag { ESyncFlag_ResGenMode = 1 << 0, + ESyncFlag_ResMatTev = 1 << 4, + }; + + enum ETevColor { + ETevColor_Reg0, + ETevColor_Reg1, + ETevColor_Reg2, + + ETevColor_Max + }; + + enum ETevKColor { + ETevKColor_Reg0, + ETevKColor_Reg1, + ETevKColor_Reg2, + ETevKColor_Reg3, + + ETevKColor_Max + }; + + struct ChanCtrl { + u8 enable; // at 0x0 + u8 lightMask; // at 0x1 + u8 ambSrc; // at 0x2 + u8 matSrc; // at 0x3 + u8 diffuseFn; // at 0x4 + u8 attnFn; // at 0x5 }; private: u32 mSyncFlags; // at 0x0 - char unkB[0xB - 0x4]; - u8 mCullMode; // at 0xB - char _0C[0x20 - 0xC]; - GXColor mTevKColors[GX_MAX_KCOLOR]; // at 0x20 - GXColorS10 mTevColors[GX_MAX_TEVREG - GX_TEVREG0]; // at 0x30 - char unk48[0xD0 - 0x48]; + u16 unk4; + u8 unk6; + u8 mNumChans; // at 0x7 + u8 mNumTexGens; // at 0x8 + u8 mNumTevStages; // at 0x9 + u8 mNumIndStages; // at 0xA + u8 mCullMode; // at 0xB + char unkC[4]; + ChanCtrl* mpChanCtrls[GX_ALPHA1 - GX_COLOR0 + 1]; // at 0x10 + GXColor mTevKColors[ETevKColor_Max]; // at 0x20 + GXColorS10 mTevColors[ETevColor_Max]; // at 0x30 + char unk48[0x9C - 0x48]; + nw4r::g3d::ScnMdl::CopiedMatAccess mCopiedMatAccess; // at 0x9C public: RPGrpModelMaterial(RPGrpModel* pModel, u16 idx); @@ -47,11 +81,32 @@ class RPGrpModelMaterial { mCullMode = cullMode; } - void SetTevKColor(GXTevKColorID id, GXColor color) { - mTevKColors[id] = color; + void SetTevKColor(ETevKColor idx, GXColor color) { + mTevKColors[idx] = color; + } + void SetTevKColor(ETevKColor idx, u8 r, u8 g, u8 b) { + mTevKColors[idx].r = r; + mTevKColors[idx].g = g; + mTevKColors[idx].b = b; + } + + void SetTevColor(ETevColor idx, GXColorS10 color) { + mTevColors[idx] = color; + } + void SetTevColor(ETevColor idx, const GXColor& color) { + mTevColors[idx].r = color.r; + mTevColors[idx].g = color.g; + mTevColors[idx].b = color.b; + mTevColors[idx].a = color.a; + } + void SetTevColor(ETevColor idx, u8 r, u8 g, u8 b, u8 a) { + mTevColors[idx].r = r; + mTevColors[idx].g = g; + mTevColors[idx].b = b; + mTevColors[idx].a = a; } - void SetTevColor(GXTevRegID id, GXColorS10 color) { - mTevColors[id - GX_TEVREG0] = color; + void SetTevColorAlpha(ETevColor idx, u8 alpha) { + mTevColors[idx].a = alpha; } }; diff --git a/include/Pack/RPGraphics/RPGrpModelRfl.h b/include/Pack/RPGraphics/RPGrpModelRfl.h index 28f4377d..cc15f674 100644 --- a/include/Pack/RPGraphics/RPGrpModelRfl.h +++ b/include/Pack/RPGraphics/RPGrpModelRfl.h @@ -30,7 +30,7 @@ class RPGrpModelRfl : public RPGrpModel, public nw4r::g3d::IScnObjCallback { static RPGrpModelRfl* Construct(RFLDataSource src, u16 index, RFLMiddleDB* pMiddleDB, RFLResolution resolution, u32 exprFlags, - u8 viewNo); + u8 viewNo, u32 arg6 = 0); RPGrpModelRfl(RFLResolution resolution, u32 exprFlags, u8 viewNo); @@ -137,10 +137,26 @@ class RPGrpModelRfl : public RPGrpModel, public nw4r::g3d::IScnObjCallback { virtual UNKTYPE VF_0x10(UNKTYPE) override {} // at 0x10 virtual UNKTYPE VF_0xC(UNKTYPE) override {} // at 0xC + void SetBrightnessColor(const GXColor& rColor) { + mBrightnessColor = rColor; + } + void SetOutputAlpha(u8 alpha) { mOutputAlpha = alpha; } + void SetMaterialType(MaterialType type) { + mMaterialType = type; + } + + static void SetBaseScale(f32 scale) { + sBaseScale = scale; + } + + static void SetMtx(const nw4r::math::MTX34& rMtx) { + nw4r::math::MTX34Copy(&lbl_804A4608, &rMtx); + } + private: enum { EFlag_ReverseCulling = 1 << 4, @@ -171,6 +187,7 @@ class RPGrpModelRfl : public RPGrpModel, public nw4r::g3d::IScnObjCallback { static f32 sBaseScale; static nw4r::math::MTX34 lbl_804A4608; +private: GXTexObj mLightTexObj0; // at 0x4C GXTexObj mLightTexObj1; // at 0x6C GXColor mBrightnessColor; // at 0x8C diff --git a/include/Pack/RPGraphics/RPGrpTexture.h b/include/Pack/RPGraphics/RPGrpTexture.h index 3aace568..860b0d7e 100644 --- a/include/Pack/RPGraphics/RPGrpTexture.h +++ b/include/Pack/RPGraphics/RPGrpTexture.h @@ -2,6 +2,8 @@ #define RP_GRAPHICS_MODEL_TEXTURE_H #include +#include + #include //! @addtogroup rp_graphics @@ -11,13 +13,17 @@ * @brief Texture utility */ class RPGrpTexture { +private: + GXTexObj mGXTexObj; // at 0x0 + public: + RPGrpTexture(); + RPGrpTexture(RPGrpHandle handle, const char* pName); + virtual ~RPGrpTexture(); + const GXTexObj& GetTexObj() const { return mGXTexObj; } - -private: - GXTexObj mGXTexObj; // at 0x0 }; //! @} diff --git a/include/Pack/RPKernel/RPSysAvatar.h b/include/Pack/RPKernel/RPSysAvatar.h index 7d0c6bdf..dba159fe 100644 --- a/include/Pack/RPKernel/RPSysAvatar.h +++ b/include/Pack/RPKernel/RPSysAvatar.h @@ -37,17 +37,20 @@ class RPSysAvatar : public RP_DEBUG_STUB_1 { const RPSysKokeshiOverloadInfo* pOverloadInfo = NULL); // at 0xC /** - * @brief Applies a generated light texture to this avatar + * @brief Applies all lightmap textures to this avatar * - * @param idx Lightmap texture index + * @param drawScene Draw scene index */ - virtual void ApplyLightTexture(u8 idx) = 0; // at 0x10 + virtual void ApplyLightTexture(u8 drawScene) = 0; // at 0x10 /** * @brief Gets the RFL favorite color of this avatar */ GXColor GetFavoriteColor() const; + /** + * @brief Accesses the Mii generation parameters + */ const RPSysKokeshiGenInfo& GetGenInfo() const { return mGenInfo; } diff --git a/include/Pack/RPKernel/RPSysFrameCtrl.h b/include/Pack/RPKernel/RPSysFrameCtrl.h index 2aed0439..a63c0503 100644 --- a/include/Pack/RPKernel/RPSysFrameCtrl.h +++ b/include/Pack/RPKernel/RPSysFrameCtrl.h @@ -116,7 +116,7 @@ class RPSysFrameCtrl { /** * @brief Animation result flags */ - enum EFlag { + enum { EFlag_Finished = 1 << 0, //!< Non-looping animation has finished EFlag_Looped = 1 << 1, //!< Animation has looped at least once }; diff --git a/include/Pack/RPKernel/RPSysKokeshi.h b/include/Pack/RPKernel/RPSysKokeshi.h index 3f24aedf..a483fb4b 100644 --- a/include/Pack/RPKernel/RPSysKokeshi.h +++ b/include/Pack/RPKernel/RPSysKokeshi.h @@ -36,11 +36,11 @@ class RPSysKokeshi : public RPSysAvatar { NULL) override; // at 0xC /** - * @brief Applies a generated light texture to this avatar + * @brief Applies all lightmap textures to this avatar * - * @param idx Lightmap texture index + * @param drawScene Draw scene index */ - virtual void ApplyLightTexture(u8 idx) override; // at 0x10 + virtual void ApplyLightTexture(u8 drawScene) override; // at 0x10 /** * @brief Gets the transformation matrix of the head joint/node diff --git a/include/Pack/RPKernel/RPSysKokeshiCtrlMgr.h b/include/Pack/RPKernel/RPSysKokeshiCtrlMgr.h index f1c8a555..9982344e 100644 --- a/include/Pack/RPKernel/RPSysKokeshiCtrlMgr.h +++ b/include/Pack/RPKernel/RPSysKokeshiCtrlMgr.h @@ -24,18 +24,18 @@ class RPSysKokeshiCtrlMgr { /** * @brief Lifetime manager */ - class Disposer : public EGG::Disposer { + class T__Disposer : public EGG::Disposer { public: /** * @brief Destructor */ - virtual ~Disposer() override { // at 0x8 + virtual ~T__Disposer() override { // at 0x8 RP_GET_INSTANCE(RPSysKokeshiManager)->ClearCtrlMgr(); } }; //! Disposer for this manager - Disposer mDisposer; // at 0x0 + T__Disposer mDisposer; // at 0x0 private: void* unk10; // at 0x10 diff --git a/include/Pack/RPKernel/RPSysKokeshiGenInfo.h b/include/Pack/RPKernel/RPSysKokeshiGenInfo.h index e0508e2b..98b35762 100644 --- a/include/Pack/RPKernel/RPSysKokeshiGenInfo.h +++ b/include/Pack/RPKernel/RPSysKokeshiGenInfo.h @@ -39,8 +39,8 @@ class RPSysKokeshiGenInfo { //! Resolution of models and textures RFLResolution mResolution; // at 0x30 - //! Facial expression to use - RFLExpression mExpression; // at 0x34 + //! Facial expressions to support + u32 mExprFlag; // at 0x34 // Use mipmapping to downscale the icon texture BOOL mMipMap; @@ -125,11 +125,11 @@ class RPSysKokeshiGenInfo { mResolution = resolution; } - RFLExpression GetExpression() const { - return mExpression; + u32 GetExpressionFlag() const { + return mExprFlag; } - void SetExpression(RFLExpression expression) { - mExpression = expression; + void SetExpressionFlag(u32 exprFlag) { + mExprFlag = exprFlag; } const RPSysKokeshiLocation& GetLocation() const { diff --git a/include/Pack/RPKernel/RPSysKokeshiIterater.h b/include/Pack/RPKernel/RPSysKokeshiIterater.h index dcbb5191..2e07bd4b 100644 --- a/include/Pack/RPKernel/RPSysKokeshiIterater.h +++ b/include/Pack/RPKernel/RPSysKokeshiIterater.h @@ -9,8 +9,9 @@ /** * @brief Mii data source iterator + * @typo */ -class RPSysKokeshiIterater { // @typo +class RPSysKokeshiIterater { private: //! Whether this iterator has been initialized BOOL mIsInitialized; // at 0x0 diff --git a/include/Pack/RPKernel/RPSysKokeshiManager.h b/include/Pack/RPKernel/RPSysKokeshiManager.h index 68898913..926ad547 100644 --- a/include/Pack/RPKernel/RPSysKokeshiManager.h +++ b/include/Pack/RPKernel/RPSysKokeshiManager.h @@ -3,6 +3,7 @@ #include #include +#include #include #include @@ -17,12 +18,14 @@ class IRPSysKokeshiBodyManager; class RPSysKokeshiCtrlDataLoader; class RPSysKokeshiCtrlMgr; class RPSysKokeshiLocation; +class RPSysMessage; class RPSysMiddleDB; +class RPSysOfficialDB; /** * @brief Mii manager */ -class RPSysKokeshiManager { +class RPSysKokeshiManager : public IRPSysHostIOSocket { RP_SINGLETON_DECL(RPSysKokeshiManager); public: @@ -61,68 +64,252 @@ class RPSysKokeshiManager { * @brief Official DB Mii state */ enum OfficialDBState { - OfficialDBState_Unused, //!< Database index is unused - OfficialDBState_Valid, //!< Database index holds a valid Mii - OfficialDBState_Favorite, //!< Database index holds a favorite Mii + OfficialDBState_Unused, //!< Database index is unused + OfficialDBState_Valid, //!< Database index holds a valid Mii + OfficialDBState_Registered, //!< A location has been registered here }; /** * @brief Light map texture index */ enum LightMap { - LightMap_lm_0, - LightMap_lm_1, + LightMap_lm_0, //!< "lm_0" texture + LightMap_lm_1, //!< "lm_1" texture LightMap_Max }; + /** + * @brief Clothing texture index + */ + enum ClothingTexture { + ClothingTexture_A, //!< "dummy_tex_a" texture + ClothingTexture_B, //!< "dummy_tex_b" texture + + ClothingTexture_Max + }; + + /** + * @brief Hand model type + */ + enum HandType { + HandType_Human, //!< Model with fingers + HandType_Sphere, //!< Spherical model + + HandType_Max + }; + public: /** - * @brief Sets the active controller manager + * @brief Creates all lightmap textures * - * @param pCtrlMgr Controller manager + * @param drawScene Draw scene index */ - void SetCtrlMgr(RPSysKokeshiCtrlMgr* pCtrlMgr); + static void CreateLightTexture(u8 drawScene); /** - * @brief Clears the active controller manager + * @brief Applies the specified expression to the Mii model + * + * @param pModel Mii model + * @param expr New expression */ - void ClearCtrlMgr(); + static void ChangeExpression(RPGrpModel* pModel, RFLExpression expr); - void GetAdditionalInfo(const RPSysKokeshiLocation& rLocation, - RFLAdditionalInfo* pInfo); + /** + * @brief Gets the current expression of the Mii model + * + * @param pModel Mii model + */ + static RFLExpression GetExpression(RPGrpModel* pModel); - void RegistLocation(const RPSysKokeshiLocation& rLocation); + /** + * @brief Gets the number of valid Miis in the official database + */ + static u16 GetOfficialDBValidNum(); - void GetLocationPlayer(u8 playerNo, RPSysKokeshiLocation* pLocation); + /** + * @brief Finds the official database index holding the Mii with the + * specified create ID + * + * @param pCreateID Mii create ID + * @return Official database index, or -1 if not found + */ + static s16 GetOfficialDBIndexFromCreateID(const RFLCreateID* pCreateID); - void GetLocationFriend(RFLDataSource src, RPSysMiddleDB* pMiddleDB, - RPSysKokeshiLocation* pLocation); + /** + * @brief Resets the manager state + */ + void Reset(); - RPGrpModel* CreateNigaoeModel(const RPSysKokeshiLocation& rLocation, - RFLResolution res, RFLExpression expr, - u8 viewNo); + /** + * @brief Sets the material type of the Mii model + * + * @param pModel Mii model + * @param type New material type + */ + void SetMaterialType(RPGrpModel* pModel, RPGrpModelRfl::MaterialType type); + + /** + * @brief Sets the brightness color of the Mii model + * + * @param pModel Mii model + * @param color New brightness color + */ + void SetBrightnessColor(RPGrpModel* pModel, GXColor color); - RPGrpModel* CreateModel(void* pFile, u16 index, const char* pName, - u8 viewNo, u32 flags, u32 bufferOption); + /** + * @brief Loads all static lifetime resources required by this manager + */ + void LoadStaticResource(); - RPGrpModel* CreateModel(void* pFile, u16 index, u8 viewNo, u32 flags, + /** + * @brief Creates a Kokeshi-related model + * + * @param pFile Resource file + * @param index Model index + * @param viewNo Renderer view ID + * @param typeOption Model type option + * @param bufferOption nw4r::g3d replacement buffer option + */ + RPGrpModel* CreateModel(void* pFile, u16 index, u8 viewNo, u32 typeOption, u32 bufferOption); + /** + * @brief Creates a Kokeshi face model + * + * @param rLocation Mii location + * @param resolution Texture resolution + * @param exprFlag Facial expression flags + * @param viewNo Renderer view ID + */ + RPGrpModel* CreateNigaoeModel(const RPSysKokeshiLocation& rLocation, + RFLResolution resolution, u32 exprFlag, + u8 viewNo); + + /** + * @brief Creates a Kokeshi-related texture + * + * @param pFile Resource file + * @param pName Texture name + */ RPGrpTexture* CreateTexture(void* pFile, const char* pName); - const char* GetHandFileName(u32 handType) const; + /** + * @brief Creates a Kokeshi-related texture + * + * @param pTexData Texture data + */ + RPGrpTexture* CreateTexture(void* pTexData); + + /** + * @brief Changes the clothing textures of the specified Mii model + * + * @param pModel Mii model + * @param pTextureA Clothing texture A + * @param pTextureB Clothing texture B + */ + void ChangeTexture(RPGrpModel* pModel, RPGrpTexture* pTextureA, + RPGrpTexture* pTextureB); + + /** + * @brief Sets the material colors of the specified Mii model + * + * @param pModel Mii model + * @param body Body color + * @param skin Skin color + */ + void SetMatColor(RPGrpModel* pModel, GXColor body, GXColor skin); + + /** + * @brief Configures the TEV color effect of the specified Mii model + * + * @param pModel Mii model + * @param alpha Effect alpha + * @param r Red component + * @param g Green component + * @param b Blue component + */ + void SetMatTevColorEffect(RPGrpModel* pModel, u8 alpha, u8 r, u8 g, u8 b); + + /** + * @brief Gets the additional info about the specified Mii + * + * @param rLocation Mii location + * @param[out] pInfo Additional info + */ + void GetAdditionalInfo(const RPSysKokeshiLocation& rLocation, + RFLAdditionalInfo* pInfo); + + /** + * @brief Removes the model's scaling from the transformation matrix + * + * @param[out] pOut Transformation matrix with scaling removed + * @param pModel Model whose scale should be used + * @param pIn Initial transformation matrix + */ + void GetModelBaseScaleInvalidatedMtx(nw4r::math::MTX34* pOut, + RPGrpModel* pModel, + const nw4r::math::MTX34* pIn); + + /** + * @brief Gets the archive filename for the specified hand type + * + * @param type Hand model type + */ + const char* GetHandFileName(u32 type); + + /** + * @brief Gets the Mii location for the specified player slot + * @details If the specified index is invalid, this function provides a + * random guest Mii location. + * + * @param idx Player index + * @param[out] pLocation Mii location + */ + void GetLocationPlayer(u8 idx, RPSysKokeshiLocation* pLocation) + DECOMP_DONT_INLINE; + + /** + * @brief Gets the Mii location of a "friend" Mii + * + * @param src Mii data source + * @param pMiddleDB Middle database (for RFLDataSource_Middle) + * @param[out] pLocation Mii location + */ + void GetLocationFriend(RFLDataSource src, RPSysMiddleDB* pMiddleDB, + RPSysKokeshiLocation* pLocation); + + /** + * @brief Registers the specified Mii location with the in-memory official + * database + * + * @param rLocation Mii location + */ + void RegistLocation(const RPSysKokeshiLocation& rLocation); + + /** + * @brief Sets the active controller manager + * + * @param pCtrlMgr Controller manager + */ + void SetCtrlMgr(RPSysKokeshiCtrlMgr* pCtrlMgr); - void ChangeTexture(RPGrpModel*, RPGrpTexture*, RPGrpTexture*); + /** + * @brief Clears the active controller manager + */ + void ClearCtrlMgr(); - void SetMatColor(RPGrpModel* pModel, GXColor, GXColor); + /** + * @brief Updates the active controller manager's state + */ + void UpdateCtrlMgr(); /** * @brief Accesses the specified guest Mii's name * * @param index Default database index */ - const wchar_t* GetGuestName(u16 index) { + const wchar_t* GetGuestName(u16 index) const { return mpGuestNames[index]; } @@ -140,13 +327,13 @@ class RPSysKokeshiManager { } /** - * @brief Gets the body manager used for kokeshi models + * @brief Gets the body manager used for model assets */ - IRPSysKokeshiBodyManager* GetBodyManager() { + IRPSysKokeshiBodyManager* GetBodyManager() const { return mpBodyManager; } /** - * @brief Sets the body manager used for kokeshi models + * @brief Sets the body manager used for model assets * * @param pBodyManager New body manager */ @@ -154,31 +341,81 @@ class RPSysKokeshiManager { mpBodyManager = pBodyManager; } - static const char* GetLightTextureName(int i) { + /** + * @brief Gets the name of the specified lightmap texture + * + * @param i Lightmap texture index + */ + static const char* GetLightTextureName(u32 i) { return LIGHT_TEXTURE_NAMES[i]; } private: + /** + * @brief Resource loading error + */ + enum LoadError { + LoadError_Success, //!< Load successful + LoadError_Fail, //!< Load failed + LoadError_Busy, //!< Processor is busy + }; + +private: + /** + * @brief Gets the index of the controller resource heap that is the current + * global heap + * + * @return Controller channel, or -1 if not applicable + */ + s32 GetCurrentCtrlHeap() const; + +private: + //! Default value for output alpha + static const u8 DEFAULT_OUTPUT_ALPHA; + + //! Clothing texture filenames + static const char* CLOTHING_TEXTURE_NAMES[ClothingTexture_Max]; + //! Lightmap texture names static const char* LIGHT_TEXTURE_NAMES[LightMap_Max]; + //! Main material name + static const char* MAIN_MATERIAL_NAME; + //! Face library resource filename + static const char* RFL_RES_NAME; + //! Common message filename + static const char* COMMON_MESSAGE_NAME; + //! Hand model filenames + static const char* HAND_FILE_NAMES[HandType_Max]; //! Face library work buffer - void* mpNglBuffer; // at 0x4 - + u8* mpNglBuffer; // at 0x4 //! Names for default database ("Guest") Miis const wchar_t* mpGuestNames[RFL_DEFAULT_CHAR_MAX]; // at 0x8 + //! Number of attempts before giving up on picking a random friend Mii + u16 mFriendRandomNum; // at 0x30 + //! Mii model base scale + f32 mBaseScale; // at 0x34 - char unk20[0x34 - 0x20]; + f32 unk28; + f32 unk2C; + f32 unk30; + + //! Light effect output alpha? u8 mOutputAlpha; // at 0x34 + //! Common message file + RPSysMessage* mpCommonMessage; // at 0x38 + //! Official database + RPSysOfficialDB* mpOfficialDB; // at 0x3C - char unk35[0x44 - 0x35]; + //! Last resource load error + LoadError mLoadError; // at 0x40 - //! Data loaders for every controller + //! Mii data loaders per controller RPSysKokeshiCtrlDataLoader* mppCtrlDataLoaders[WPAD_MAX_CONTROLLERS]; // at 0x44 + //! Controller Mii manager + RPSysKokeshiCtrlMgr* mpCtrlMgr; // at 0x48 - char unk54[4]; - - //! App body manager + //! Application body manager IRPSysKokeshiBodyManager* mpBodyManager; // at 0x58 }; diff --git a/include/Pack/RPKernel/RPSysLayout.h b/include/Pack/RPKernel/RPSysLayout.h index 4d8a6afc..ed9fbd11 100644 --- a/include/Pack/RPKernel/RPSysLayout.h +++ b/include/Pack/RPKernel/RPSysLayout.h @@ -350,7 +350,7 @@ class RPSysLayout { /** * @brief State flags */ - enum EFlag { + enum { EFlag_Visible = 1 << 0, }; diff --git a/include/Pack/RPKernel/RPSysLytAnmObj.h b/include/Pack/RPKernel/RPSysLytAnmObj.h index 58299a73..49a406c4 100644 --- a/include/Pack/RPKernel/RPSysLytAnmObj.h +++ b/include/Pack/RPKernel/RPSysLytAnmObj.h @@ -105,7 +105,7 @@ class RPSysLytAnmObj { /** * @brief Animation result flags */ - enum EFlag { + enum { EFlag_Finished = 1 << 0, //!< Non-looping animation has finished EFlag_Looped = 1 << 1, //!< Animation has looped at least once }; diff --git a/include/Pack/RPSystem.h b/include/Pack/RPSystem.h index 2bb787fa..6d4f436a 100644 --- a/include/Pack/RPSystem.h +++ b/include/Pack/RPSystem.h @@ -1,14 +1,20 @@ #ifndef RP_PUBLIC_SYSTEM_H #define RP_PUBLIC_SYSTEM_H +#include +#include +#include +#include #include #include +#include +#include #include #include +#include #include #include #include #include - #endif diff --git a/include/Pack/RPSystem/RPPartyPlayerData.h b/include/Pack/RPSystem/RPPartyPlayerData.h new file mode 100644 index 00000000..cc7fc290 --- /dev/null +++ b/include/Pack/RPSystem/RPPartyPlayerData.h @@ -0,0 +1,136 @@ +#ifndef RP_SYSTEM_PARTY_PLAYER_DATA_H +#define RP_SYSTEM_PARTY_PLAYER_DATA_H +#include + +#include + +#include + +//! @addtogroup rp_system +//! @{ + +/** + * @brief Party Pack save file player data + */ +class RPPartyPlayerData { +public: + /** + * @brief Minigame ID + */ + enum EGame { + EGame_Duc, //!< Shooting Range + EGame_Wly, //!< Find Mii + EGame_Pnp, //!< Table Tennis + EGame_Bom, //!< Pose Mii + EGame_Hky, //!< Laser Hockey + EGame_Bil, //!< Billiards + EGame_Fsh, //!< Fishing + EGame_Cow, //!< Charge! + EGame_Tnk, //!< Tanks! + + EGame_Max, + }; + + /** + * @brief Medal type + */ + enum EMedal { + EMedal_None, + EMedal_Bronze, + EMedal_Silver, + EMedal_Gold, + EMedal_Platinum, + }; + + /** + * @brief Medal cutscene ID + */ + enum EMedalDemo { + EMedalDemo_0, + EMedalDemo_BronzeComplete, //!< All bronze medals earned + EMedalDemo_SilverComplete, //!< All silver medals earned + EMedalDemo_GoldComplete, //!< All gold medals earned + EMedalDemo_PlatinumComplete //!< All platinum medals earned + }; + + //! Number of sports in the My Records leaderboard + static const int MY_RECORDS_LENGTH = 5; + +public: + /** + * @brief Constructor + */ + RPPartyPlayerData(); + + /** + * @brief Resets the data to a default save state + */ + void reset(); + + /** + * @name Player list + */ + /**@{*/ + /** + * @brief Tests whether this player has been registered with the player list + */ + bool isRegistered() const; + /** + * @brief Sets whether this player has been registered with the player list + * + * @param registered Registration status + */ + void setRegistered(bool registered); + + /** + * @brief Gets this player's Mii create ID + * + * @param[out] pCreateID Mii create ID + */ + void getCreateID(RFLCreateID* pCreateID) const; + /** + * @brief Set this player's Mii create ID + * + * @param pCreateID Mii create ID + */ + void setCreateID(const RFLCreateID* pCreateID); + + /** + * @brief Gets the time this player was registered with the player list + */ + RPTime32 getDebutTime() const; + /** + * @brief Sets the time this player was registered with the player list + * + * @param time Debut time + */ + void setDebutTime(RPTime32 time); + /**@}*/ + +private: + /** + * @brief Player data flags + */ + enum { + EFlag_Registered = 1, //!< Registered with the player list + }; + +private: + //! Player data flags + EGG::TBitFlag mPlayerFlags; // at 0x0 + //! Mii create/unique ID + RFLCreateID mCreateID; // at 0x4 + //! Time the player was registered + RPTime32 mDebutTime; // at 0xC + + //! My Record leaderboard for each game + s32 mMyRecords[EGame_Max][MY_RECORDS_LENGTH]; // at 0x10 + //! Medal earned in each game + u8 mMedals[EGame_Max]; // at 0xC4 + //! Medal cutscene flags + EGG::TBitFlag mMedalDemoFlags; // at 0xCD +}; + +//! @} + +#endif diff --git a/include/Pack/RPSystem/RPPartySystemData.h b/include/Pack/RPSystem/RPPartySystemData.h new file mode 100644 index 00000000..31a4621c --- /dev/null +++ b/include/Pack/RPSystem/RPPartySystemData.h @@ -0,0 +1,93 @@ +#ifndef RP_SYSTEM_PARTY_SYSTEM_DATA_H +#define RP_SYSTEM_PARTY_SYSTEM_DATA_H +#include + +#include + +#include + +//! @addtogroup rp_system +//! @{ + +/** + * @brief Party Pack save file system data + */ +class RPPartySystemData { +public: + /** + * @brief Minigame ID + */ + enum EGame { + EGame_Duc, //!< Shooting Range + EGame_Wly, //!< Find Mii + EGame_Pnp, //!< Table Tennis + EGame_Bom, //!< Pose Mii + EGame_Hky, //!< Laser Hockey + EGame_Bil, //!< Billiards + EGame_Fsh, //!< Fishing + EGame_Cow, //!< Charge! + EGame_Tnk, //!< Tanks! + + EGame_Max, + }; + + /** + * @brief Message ID + */ + enum EMsg { + EMsg_Welcome, //!< Play for the first time + EMsg_StageTwo, //!< Unlock stage two + EMsg_StageThree, //!< Unlock stage three + EMsg_StageFour, //!< Unlock stage four + EMsg_StageFive, //!< Unlock stage five + EMsg_StageSix, //!< Unlock stage six + EMsg_StageSeven, //!< Unlock stage seven + EMsg_StageEight, //!< Unlock stage eight + EMsg_StageFinal, //!< Unlock the final stage + EMsg_Master, //!< Completed all stages + + EMsg_Max + }; + +public: + /** + * @brief Constructor + */ + RPPartySystemData(); + + /** + * @brief Tests whether the specified minigame is available + * + * @param idx Minigame index + */ + bool isGameOpen(s32 idx) const; + +private: + //! Old data exists for each player count + static const int OLD_DATA_LEN = 1 + 2; + +private: + /** + * @name Previous Mii data + */ + /**@{*/ + //! Official database index + s8 mOldIndex[OLD_DATA_LEN]; // at 0x0 + //! Remote Blutetooth address + u8 mOldAddress[OLD_DATA_LEN][WPAD_ADDR_LEN]; // at 0x3 + /**@}*/ + + //! Number of new players registered today + u8 mRegistTodayCount; // at 0x15 + //! Last fitness test completed + RPTime16 mRegistLastDate; // at 0x16 + + //! Game unlock flags + EGG::TBitFlag mGameFlags; // at 0x18 + //! Message seen flags + EGG::TBitFlag mMsgFlags; // at 0x1C +}; + +//! @} + +#endif diff --git a/include/Pack/RPSystem/RPSportsPlayerData.h b/include/Pack/RPSystem/RPSportsPlayerData.h new file mode 100644 index 00000000..5ae6c5dd --- /dev/null +++ b/include/Pack/RPSystem/RPSportsPlayerData.h @@ -0,0 +1,781 @@ +#ifndef RP_SYSTEM_SPORTS_PLAYER_DATA_H +#define RP_SYSTEM_SPORTS_PLAYER_DATA_H +#include + +#include + +#include + +//! @addtogroup rp_system +//! @{ + +/** + * @brief Sports Pack save file player data + */ +class RPSportsPlayerData { +public: + /** + * @brief Sport ID + */ + enum ESport { + ESport_Bsb, //!< Baseball + ESport_Tns, //!< Tennis + ESport_Gol, //!< Golf + ESport_Bow, //!< Bowling + ESport_Box, //!< Boxing + + ESport_Max + }; + + /** + * @brief Training game ID + */ + enum EGame { + EGame_1st, //!< First of the three training games + EGame_2nd, //!< Second of the three training games + EGame_3rd, //!< Last of the three training games + + EGame_Max + }; + + /** + * @brief Training game medal type + */ + enum EMedal { + EMedal_None, + EMedal_Bronze, + EMedal_Silver, + EMedal_Gold, + EMedal_Platinum, + }; + + /** + * @brief Golf course ID + */ + enum ECourse { + ECourse_NineHole, //!< Nine-hole + ECourse_Beginner, //!< Beginner (H1-H3) + ECourse_Intermediate, //!< Intermediate (H4-H6) + ECourse_Expert, //!< Expert (H7-H9) + + ECourse_Max + }; + + /** + * @brief Fitness test statistic + */ + enum EStat { + EStat_Stamina, + EStat_Speed, + EStat_Balance, + + EStat_Max + }; + + /** + * @brief Handedness type + */ + enum EHand { + EHand_Right, //!< Right-handed + EHand_Left, //!< Left-handed + }; + +public: + /** + * @brief Constructor + */ + RPSportsPlayerData(); + + /** + * @brief Resets the data to a default save state + */ + void reset(); + + /** + * @name Common + */ + /**@{*/ + /** + * @brief Gets the hand type used for the specified sport's primary control + * + * @param sport Sport ID + */ + EHand getHandPrimary(ESport sport) const; + /** + * @brief Gets the hand type used for the specified sport's secondary + * control + * + * @param sport Sport ID + */ + EHand getHandSecondary(ESport sport) const; + + /** + * @brief Sets the hand type used for the specified sport's primary control + * + * @param hand Hand type + * @param sport Sport ID + */ + void setHandPrimary(EHand hand, ESport sport); + /** + * @brief Sets the hand type used for the specified sport's secondary + * control + * + * @param hand Hand type + * @param sport Sport ID + */ + void setHandSecondary(EHand hand, ESport sport); + + /** + * @brief Gets the skill level in the specified sport + * + * @param sport Sport ID + */ + f32 getSkillLevel(ESport sport) const; + /** + * @brief Sets the skill level in the specified sport + * + * @param sport Sport ID + * @param skill Skill level + */ + void setSkillLevel(ESport sport, f32 skill); + + /** + * @brief Gets a point from the specified sport's skill graph + * + * @param sport Sport ID + * @param idx Graph point index + */ + s16 getSkillGraphPoint(ESport sport, u32 idx) const; + /** + * @brief Sets a point in the specified sport's skill graph + * + * @param value Point value (delta) + * @param sport Sport ID + * @param idx Graph point index + */ + void setSkillGraphPoint(s16 value, ESport sport, u32 idx); + + /** + * @brief Gets the first date when the standard mode of the specified sport + * was played + * + * @param sport Sport ID + */ + RPTime16 getStandardFirstDate(ESport sport) const; + /** + * @brief Sets the first date when the standard mode of the specified sport + * was played + * + * @param date First play date + * @param sport Sport ID + */ + void setStandardFirstDate(RPTime16 date, ESport sport); + + /** + * @brief Gets the first date when the specified training game was played + * + * @param sport Sport ID + * @param game Training game ID + */ + RPTime16 getTrainingFirstDate(ESport sport, EGame game) const; + /** + * @brief Sets the first date when the specified training game was played + * + * @param date First play date + * @param sport Sport ID + * @param game Training game ID + */ + void setTrainingFirstDate(RPTime16 date, ESport sport, EGame game); + + /** + * @brief Gets the play count for the standard mode of the specified sport + * + * @param sport Sport ID + */ + u16 getStandardPlayCount(ESport sport) const; + /** + * @brief Sets the play count for the standard mode of the specified sport + * + * @param count Play count + * @param sport Sport ID + */ + void setStandardPlayCount(u16 count, ESport sport); + + /** + * @brief Gets the play count for the specified training game + * + * @param sport Sport ID + * @param game Training game ID + */ + u16 getTrainingPlayCount(ESport sport, EGame game) const; + /** + * @brief Sets the play count for the specified training game + * + * @param count Play count + * @param sport Sport ID + * @param game Training game ID + */ + void setTrainingPlayCount(u16 count, ESport sport, EGame game); + + /** + * @brief Gets the medal type earned in the specified training game + * + * @param sport Sport ID + * @param game Training game ID + */ + u8 getTrainingMedal(ESport sport, EGame game) const; + /** + * @brief Sets the medal type earned in the specified training game + * + * @param medal Medal type + * @param sport Sport ID + * @param game Training game ID + */ + void setTrainingMedal(u8 medal, ESport sport, EGame game); + + /** + * @brief Tests whether this player has completed a round of any sport + */ + bool isFirstPlay() const; + /** + * @brief Marks that this player has completed a round of any sport + */ + void setFirstPlay(); + + /** + * @brief Tests whether this player has defeated the specified sport's + * champion + * + * @param sport Sport ID + */ + bool isDefeatChampion(ESport sport) const; + /** + * @brief Marks that this player has defeated the specified sport's champion + * + * @param sport Sport ID + */ + void setDefeatChampion(ESport sport); + /**@}*/ + + /** + * @name Tennis + */ + /**@{*/ + /** + * @brief Gets the difficulty of the Tennis CPU players + */ + f32 getTnsDifficulty() const; + /** + * @brief Sets the difficulty of the Tennis CPU players + * + * @param difficulty New CPU difficulty + */ + void setTnsDifficulty(f32 difficulty); + + /** + * @brief Gets the Tennis player success factor + */ + f32 getTnsSuccess() const; + /** + * @brief Sets the Tennis player success factor + * + * @param success New player success factor + */ + void setTnsSuccess(f32 success); + + /** + * @brief Gets the best score in the specified Tennis training game + * + * @param game Training game ID + */ + u8 getTnsTrainingBest(EGame game) const; + /** + * @brief Sets the best score in the specified Tennis training game + * + * @param score Best score + * @param game Training game ID + */ + void setTnsTrainingBest(u8 score, EGame game); + /**@}*/ + + /** + * @name Baseball + */ + /**@{*/ + /** + * @brief Gets the best home run count record in Hitting Home Runs + */ + u8 getBsbHomerunRunsBest() const; + /** + * @brief Sets the best home run count record in Hitting Home Runs + * + * @param runs Best home run count + */ + void setBsbHomerunRunsBest(u8 runs); + + /** + * @brief Gets the best total distance record in Hitting Home Runs + */ + u16 getBsbHomerunDistBest() const; + /** + * @brief Sets the best total distance record in Hitting Home Runs + * + * @param dist Best total distance + */ + void setBsbHomerunDistBest(u16 dist); + + /** + * @brief Gets the best score in Swing Control + */ + u8 getBsbUchiwakeBest() const; + /** + * @brief Sets the best score in Swing Control + * + * @param score Best score + */ + void setBsbUchiwakeBest(u8 score); + + /** + * @brief Gets the best score in Batting Practice + */ + u8 getBsbRenzokuBest() const; + /** + * @brief Sets the best score in Batting Practice + * + * @param score Best score + */ + void setBsbRenzokuBest(u8 score); + /**@}*/ + + /** + * @name Bowling + */ + /**@{*/ + /** + * @brief Gets the best score in Bowling + */ + u16 getBowStandardBest() const; + /** + * @brief Sets the best score in Bowling + * + * @param score Best score + */ + void setBowStandardBest(u16 score); + + /** + * @brief Gets the number of perfect games bowled + */ + u8 getBowPerfectCount() const; + /** + * @brief Sets the number of perfect games bowled + * + * @param count Perfect game count + */ + void setBowPerfectCount(u8 count); + + /** + * @brief Gets the best score in the specified Bowling training game + * + * @param game Training game ID + */ + u16 getBowTrainingBest(EGame game) const; + /** + * @brief Sets the best score in the specified Bowling training game + * + * @param score Best score + * @param game Training game ID + */ + void setBowTrainingBest(u16 score, EGame game); + /**@}*/ + + /** + * @name Golf + */ + /**@{*/ + /** + * @brief Gets the best Golf score on the specified course + * + * @param course Golf course ID + */ + s8 getGolStandardBest(ECourse course) const; + /** + * @brief Sets the best Golf score on the specified course + * + * @param score Best score + * @param course Golf course ID + */ + void setGolStandardBest(s8 score, ECourse course); + + /** + * @brief Gets the amount of hole-in-ones hit + */ + u8 getGolAceCount() const; + /** + * @brief Sets the amount of hole-in-ones hit + * + * @param count Hole-in-one count + */ + void setGolAceCount(u8 count); + + /** + * @brief Gets the best score in the specified Golf training game + * + * @param game Training game ID + */ + u16 getGolTrainingBest(EGame game) const; + /** + * @brief Set the best score in the specified Golf training game + * + * @param score Best score + * @param game Training game ID + */ + void setGolTrainingBest(u16 score, EGame game); + /**@}*/ + + /** + * @name Boxing + */ + /**@{*/ + /** + * @brief Gets the best score in the specified Boxing training game + * + * @param game Training game ID + */ + u16 getBoxTrainingBest(EGame game) const; + /** + * @brief Set the best score in the specified Boxing training game + * + * @param score Best score + * @param game Training game ID + */ + void setBoxTrainingBest(u16 score, EGame game); + /**@}*/ + + /** + * @name Wii Fitness + */ + /**@{*/ + /** + * @brief Gets the date of the first completed fitness test + */ + RPTime16 getPhysicalEndFirstDate() const; + /** + * @brief Sets the date of the first completed fitness test + * + * @param date Date of first test completion + */ + void setPhysicalEndFirstDate(RPTime16 date); + + /** + * @brief Gets the number of completed fitness tests + */ + u16 getPhysicalEndCount() const; + /** + * @brief Sets the number of completed fitness tests + * + * @param count Number of completed fitness tests + */ + void setPhysicalEndCount(u16 count); + + /** + * @brief Gets the most recent value of the specified fitness test stat + * + * @param stat Fitness test stat ID + */ + u16 getPhysicalStat(EStat stat) const; + /** + * @brief Sets the most recent value of the specified fitness test stat + * + * @param value Stat value + * @param stat Fitness test stat ID + */ + void setPhysicalStat(u16 value, EStat stat); + + /** + * @brief Gets the specified event from the most recent fitness test + * + * @param idx Event index + * @return Packed event ID + */ + u8 getPhysicalEvent(u32 idx) const; + /** + * @brief Sets the specified event of the most recent fitness test + * + * @param event Packed event index + * @param idx Event index + */ + void setPhysicalEvent(u8 event, u32 idx); + + /** + * @brief Gets the fitness stat sum record in the specified training game + * + * @param sport Sport ID + * @param game Training game ID + */ + u16 getPhysicalStatSumBest(ESport sport, EGame game) const; + /** + * @brief Sets the fitness stat sum record in the specified training game + * + * @param sum Fitness stat sum + * @param sport Sport ID + * @param game Training game ID + */ + void setPhysicalStatSumBest(u16 sum, ESport sport, EGame game); + + /** + * @brief Gets the date of the most recently completed fitness test + */ + RPTime16 getPhysicalEndLastDate() const; + /** + * @brief Sets the date of the most recently completed fitness test + * + * @param date Date of last test completion + */ + void setPhysicalEndLastDate(RPTime16 date); + + /** + * @brief Gets the specified fitness stat sum from the test history + * + * @param idx Fitness test history index + */ + u16 getPhysicalStatSumHistory(u32 idx) const; + /** + * @brief Sets the specified fitness stat sum in the test history + * + * @param sum Fitness stat sum + * @param idx Fitness test history index + */ + void setPhysicalStatSumHistory(u16 sum, u32 idx); + + /** + * @brief Gets the specified fitness test completion date from the test + * history + * + * @param idx Fitness test history index + */ + RPTime16 getPhysicalDateHistory(u32 idx) const; + /** + * @brief Sets the specified fitness test completion date in the test + * history + * + * @param date Date of test completion + * @param idx Fitness test history index + */ + void setPhysicalDateHistory(RPTime16 date, u32 idx); + + /** + * @brief Gets the date of the most recently started fitness test + */ + RPTime16 getPhysicalBeginLastDate() const; + /** + * @brief Sets the date of the most recently started fitness test + * + * @param date Start date of the last test + */ + void setPhysicalBeginLastDate(RPTime16 date); + /**@}*/ + + /** + * @name Player list + */ + /**@{*/ + /** + * @brief Tests whether this player has been registered with the player list + */ + bool isRegistered() const; + /** + * @brief Sets whether this player has been registered with the player list + * + * @param registered Registration status + */ + void setRegistered(bool registered); + + /** + * @brief Gets this player's Mii create ID + * + * @param[out] pCreateID Mii create ID + */ + void getCreateID(RFLCreateID* pCreateID) const; + /** + * @brief Set this player's Mii create ID + * + * @param pCreateID Mii create ID + */ + void setCreateID(const RFLCreateID* pCreateID); + + /** + * @brief Gets the time this player was registered with the player list + */ + RPTime32 getDebutTime() const; + /** + * @brief Sets the time this player was registered with the player list + * + * @param time Debut time + */ + void setDebutTime(RPTime32 time); + /**@}*/ + + /** + * @brief Deserializes this object from the specified stream + * + * @param rStrm Memory stream + */ + void read(EGG::RamStream& rStrm); + /** + * @brief Serializes this object to the specified stream + * + * @param rStrm Memory stream + */ + void write(EGG::RamStream& rStrm); + +private: + /** + * @brief Player data flags + */ + enum { + EFlag_Registered = 1, //!< Registered with the player list + EFlag_FirstPlay = 2, //!< Completed first round of any sport + EFlag_Champion = 27 /* 27-31 */, //!< Defeated the sport champion + }; + +private: + //! Length of the skill graph history (previous 49) + static const int SKILL_HISTORY_LENGTH = 50 - 1; + + //! Number of events in a fitness test + static const int PHYSICAL_EVENT_NUM = 3; + //! Length of the fitness results history (previous 90) + static const int PHYSICAL_HISTORY_LENGTH = 90 + 1; + +private: + /** + * @name Common data + */ + /**@{*/ + //! Player data flags + EGG::TBitFlag mPlayerFlags; // at 0x0 + //! Mii create/unique ID + RFLCreateID mCreateID; // at 0x4 + //! Time the player was registered + RPTime32 mDebutTime; // at 0xC + + //! Handedness flags (primary, secondary) + EGG::TBitFlag mHandFlags; // at 0x10 + + //! Player skill levels + f32 mSkillLevels[ESport_Max]; // at 0x14 + //! Skill graph history (displacement) + s16 mSkillGraphDelta[ESport_Max][SKILL_HISTORY_LENGTH]; // at 0x28 + + //! First date playing each sport's standard mode + RPTime16 mStandardFirstDates[ESport_Max]; // at 0x212 + //! First date playing each training game + RPTime16 mTrainingFirstDates[ESport_Max][EGame_Max]; // at 0x21C + + //! Play count of each sport (measured in holes for Golf) + u16 mPlayCounts[ESport_Max]; // at 0x23A + //! Play count of each training game + u16 mTrainingPlayCounts[ESport_Max][EGame_Max]; // at 0x244 + + //! Medal earned in each training game + u8 mTrainingMedals[ESport_Max][EGame_Max]; // at 0x262 + /**@}*/ + + /** + * @name Tennis data + */ + /**@{*/ + u16 unk272; + + //! CPU difficulty + f32 mTnsDifficulty; // at 0x274 + //! Player success coefficient (accelerates the increase in difficulty) + f32 mTnsSuccess; // at 0x278 + + //! Tennis training best scores + u8 mTnsTrainingBests[EGame_Max]; // at 0x27C + /**@}*/ + + /** + * @name Baseball data + */ + /**@{*/ + //! Best home run count in Hitting Home Runs + u8 mBsbHomerunRunsBest; // at 0x27F + //! Best total distance in Hitting Home Runs + u16 mBsbHomerunDistBest; // at 0x280 + + //! Swing Control best score + u8 mBsbUchiwakeBest; // at 0x282 + //! Batting Practice best score + u8 mBsbRenzokuBest; // at 0x283 + /**@}*/ + + /** + * @name Bowling data + */ + /**@{*/ + u16 unk284; + + //! Bowling best score + u16 mBowStandardBest; // at 0x286 + //! Number of perfect games bowled + u8 mBowPerfectCount; // at 0x288 + //! Best scores in Bowling training games + u16 mBowTrainingBests[EGame_Max]; // at 0x28A + /**@}*/ + + /** + * @name Golf data + */ + /**@{*/ + //! Best scores on each difficulty + s8 mGolStandardBests[ECourse_Max]; // at 0x290 + //! Number of aces hit + u8 mGolAceCount; // at 0x294 + //! Best scores in Golf training games + u16 mGolTrainingBests[EGame_Max]; // at 0x296 + /**@}*/ + + /** + * @name Boxing data + */ + /**@{*/ + //! Best scores in Boxing training games + u16 mBoxTrainingBests[EGame_Max]; // at 0x29C + /**@}*/ + + /** + * @name Wii Fitness data + */ + /**@{*/ + //! Date of the first completed fitness test + RPTime16 mPhysicalEndFirstDate; // at 0x2A2 + //! Number of completed fitness tests + u16 mPhysicalEndCount; // at 0x2A4 + + //! Previous fitness test stat ratings + u16 mPhysicalLastStats[EStat_Max]; // at 0x2A6 + //! Previous fitness test event IDs + u8 mPhysicalLastEvents[PHYSICAL_EVENT_NUM]; // at 0x2AC + + //! Best fitness stat sum in all training games + u16 mPhysicalStatSumBests[ESport_Max][EGame_Max]; // at 0x2B0 + + //! Date of the last completed fitness test + RPTime16 mPhysicalEndLastDate; // at 0x2CE + //! Fitness stat sums of the most recent fitness test, and the previous 90 + u16 mPhysicalStatSumHistory[PHYSICAL_HISTORY_LENGTH]; // at 0x2D0 + //! Dates of the most recent fitness test, and the previous 90 + RPTime16 mPhysicalDateHistory[PHYSICAL_HISTORY_LENGTH]; // at 0x386 + + //! Date of the last started fitness test + RPTime16 mPhysicalBeginLastDate; // at 0x43C + + u16 unk43E[15]; + /**@}*/ +}; + +//! @} + +#endif diff --git a/include/Pack/RPSystem/RPSportsSystemData.h b/include/Pack/RPSystem/RPSportsSystemData.h new file mode 100644 index 00000000..8df493f0 --- /dev/null +++ b/include/Pack/RPSystem/RPSportsSystemData.h @@ -0,0 +1,169 @@ +#ifndef RP_SYSTEM_SPORTS_SYSTEM_DATA_H +#define RP_SYSTEM_SPORTS_SYSTEM_DATA_H +#include + +#include + +#include + +//! @addtogroup rp_system +//! @{ + +/** + * @brief Sports Pack save file system data + */ +class RPSportsSystemData { +public: + /** + * @brief Training game ID + */ + enum EGame { + EGame_Box_Mituchi, //!< Throwing Punches + EGame_Box_Tamayoke, //!< Dodging + EGame_Box_Sandbag, //!< Working the Bag + + EGame_Gol_Target, //!< Target Practice + EGame_Gol_Nearpin, //!< Hitting the Green + EGame_Gol_Onepat, //!< Putting + + EGame_Bow_Gatetoshi, //!< Spin Control + EGame_Bow_Nagitaoshi, //!< Power Throws + EGame_Bow_Spareget, //!< Picking Up Spares + + EGame_Bsb_Renzoku, //!< Batting Practice + EGame_Bsb_Uchiwake, //!< Swing Control + EGame_Bsb_Homerun, //!< Hitting Home Runs + + EGame_Tns_Kabeuchi, //!< Target Practice + EGame_Tns_Nerauchii, //!< Timing Your Swing + EGame_Tns_Renzoku, //!< Returning Balls + + EGame_Max, + }; + +public: + /** + * @brief Constructor + */ + RPSportsSystemData(); + + /** + * @brief Resets the data to a default save state + */ + void reset(); + + /** + * @brief Gets the old data for the specified player count and player index + * + * @param[out] pIndex Official database index + * @param[out] pAddr Remote Bluetooth address + * @param playerNum Player count + * @param playerNo Player index + */ + void getOldData(s8* pIndex, u8* pAddr, s32 playerNum, s32 playerNo) const; + /** + * @brief Sets the old data for the specified player count and player index + * + * @param[out] pIndex Official database index + * @param[out] pAddr Remote Bluetooth address + * @param playerNum Player count + * @param playerNo Player index + */ + void setOldData(s8 index, const u8* pAddr, s32 playerNum, s32 playerNo); + + /** + * @brief Sets the total number of fitness tests completed + * + * @param count Number of fitness tests completed + */ + void setPhysicalEndCount(u8 count); + /** + * @brief Gets the total number of fitness tests completed + */ + u8 getPhysicalEndCount() const; + + /** + * @brief Sets the last date on which a fitness test was completed + * + * @param date Last completion date + */ + void setPhysicalEndLastDate(RPTime16 date); + /** + * @brief Gets the last date on which a fitness test was completed + */ + RPTime16 getPhysicalEndLastDate() const; + + /** + * @brief Sets whether the specified training game's unlock cutscene has + * played + * + * @param idx Training game index + * @param open Whether the unlock cutscene has played + */ + void setGameOpenDemo(u8 idx, bool open); + /** + * @brief Tests whether the specified training game's unlock cutscene has + * played + * + * @param idx Training game index + */ + bool isGameOpenDemo(u8 idx) const; + + /** + * @brief Sets whether the specified training game is available + * + * @param idx Training game index + * @param open Whether the game is available + */ + void setGameOpen(u8 idx, bool open); + /** + * @brief Tests whether the specified training game is available + * + * @param idx Training game index + */ + bool isGameOpen(u8 idx) const; + + /** + * @brief Deserializes this object from the specified stream + * + * @param rStrm Memory stream + */ + void read(EGG::RamStream& rStrm); + /** + * @brief Serializes this object to the specified stream + * + * @param rStrm Memory stream + */ + void write(EGG::RamStream& rStrm); + +private: + //! Old data exists for each player count + static const int OLD_DATA_LEN = 1 + 2 + 3 + 4; + +private: + /** + * @name Previous Mii data + */ + /**@{*/ + //! Official database index + s8 mOldIndex[OLD_DATA_LEN]; // at 0x0 + //! Remote Blutetooth address + u8 mOldAddress[OLD_DATA_LEN][WPAD_ADDR_LEN]; // at 0xA + /**@}*/ + + //! Total number of fitness tests completed + u8 mPhysicalCount; // at 0x46 + //! Last fitness test completed + RPTime16 mPhysicalEndLastDate; // at 0x48 + + u16 unk4A; + u8 unk4C; + + //! Game/demo bitflags + EGG::TBitFlag mFlags; // at 0x50 + EGG::TBitFlag unk54; +}; + +//! @} + +#endif diff --git a/include/Pack/RPSystem/RPSysPlayer.h b/include/Pack/RPSystem/RPSysPlayer.h new file mode 100644 index 00000000..f7c1077d --- /dev/null +++ b/include/Pack/RPSystem/RPSysPlayer.h @@ -0,0 +1,35 @@ +#ifndef RP_SYSTEM_PLAYER_H +#define RP_SYSTEM_PLAYER_H +#include + +#include + +#include + +//! @addtogroup rp_system +//! @{ + +/** + * @brief Player object + */ +class RPSysPlayer { +public: + s8 getDataSource() const { + return mDataSource; + } + + u16 getIndex() const { + return mIndex; + } + +private: + u8 mChannel; // at 0x0 + s8 mDataSource; // at 0x1 + u16 mIndex; // at 0x2 + RFLCreateID mCreateID; // at 0x4 + // . . . +}; + +//! @} + +#endif diff --git a/include/Pack/RPSystem/RPSysPlayerMgr.h b/include/Pack/RPSystem/RPSysPlayerMgr.h new file mode 100644 index 00000000..46b47506 --- /dev/null +++ b/include/Pack/RPSystem/RPSysPlayerMgr.h @@ -0,0 +1,33 @@ +#ifndef RP_SYSTEM_PLAYER_MGR_H +#define RP_SYSTEM_PLAYER_MGR_H +#include + +#include +#include + +#include + +//! @addtogroup rp_system +//! @{ + +/** + * @brief Player manager + */ +class RPSysPlayerMgr { + RP_SINGLETON_DECL_EX(RPSysPlayerMgr); + +public: + s32 getPlayerNum() const { + return mPlayerNum; + } + + const RPSysPlayer& getPlayer(s32 idx) const; + +private: + s32 mPlayerNum; // at 0x0 + s32 mRemoteNum; // at 0x4 +}; + +//! @} + +#endif diff --git a/include/Pack/RPSystem/RPSysResourceManager.h b/include/Pack/RPSystem/RPSysResourceManager.h index e9880c3e..74bfd8bb 100644 --- a/include/Pack/RPSystem/RPSysResourceManager.h +++ b/include/Pack/RPSystem/RPSysResourceManager.h @@ -194,7 +194,7 @@ class RPSysResourceManager { #if defined(PACK_SPORTS) //! Sports Pack Mii manager RPSportsAppMiiManager* mpAppMiiManager; // at 0x38 -#elif defined(PACK_PLAY) +#elif defined(PACK_PARTY) //! Party Pack Mii manager RPPartyAppMiiManager* mpAppMiiManager; // at 0x38 #endif diff --git a/include/Pack/RPSystem/RPSysSaveData.h b/include/Pack/RPSystem/RPSysSaveData.h new file mode 100644 index 00000000..b5a9bf92 --- /dev/null +++ b/include/Pack/RPSystem/RPSysSaveData.h @@ -0,0 +1,165 @@ +#ifndef RP_SYSTEM_SAVE_DATA_H +#define RP_SYSTEM_SAVE_DATA_H +#include + +#include + +//! @addtogroup rp_system +//! @{ + +// Forward declarations +class RPPartyPlayerData; +class RPPartySystemData; +class RPSportsPlayerData; +class RPSportsSystemData; + +/** + * @brief Pack Project save data + */ +class RPSysSaveData { +public: + //! Length of the player list + static const int PLAYER_LIST_SIZE = 100; + +public: + /** + * @brief Constructor + */ + RPSysSaveData(); + + /** + * @brief Resets the save data state + */ + void reset(); + + /** + * @brief Tests whether an error occurred while reading the save file + * @typo + */ + bool isErrorOccured() const; + + /** + * @brief Gets the Sports Pack player data at the specified player list + * index + * + * @param idx Player list index + */ + RPSportsPlayerData* getSportsPlayerData(u32 idx) const; + /** + * @brief Sets the Sports Pack player data at the specified player list + * index + * + * @param pPlayerData Player data + * @param idx Player list index + */ + void setSportsPlayerData(const RPSportsPlayerData* pPlayerData, u32 idx); + + /** + * @brief Gets the Sports Pack system data + */ + RPSportsSystemData* getSportsSystemData() const; + /** + * @brief Sets the Sports Pack system data + * + * @param pSystemData System data + */ + void setSportsSystemData(const RPSportsSystemData* pSystemData); + + /** + * @brief Gets the Party Pack player data at the specified player list + * index + * + * @param idx Player list index + */ + RPPartyPlayerData* getPartyPlayerData(u32 idx) const; + /** + * @brief Sets the Party Pack player data at the specified player list + * index + * + * @param pPlayerData Player data + * @param idx Player list index + */ + void setPartyPlayerData(const RPPartyPlayerData* pPlayerData, u32 idx); + + /** + * @brief Gets the Party Pack system data + */ + RPPartySystemData* getPartySystemData() const; + /** + * @brief Sets the Party Pack system data + * + * @param pSystemData System data + */ + void setPartySystemData(const RPPartySystemData* pSystemData); + + /** + * @brief Deserializes this object from the specified stream + * + * @param rStrm Memory stream + * @param pRawSave Raw save data + */ + void read(EGG::RamStream& rStrm, const void* pRawSave); + /** + * @brief Serializes this object to the specified stream + * + * @param rStrm Memory stream + * @param pRawSave Raw save data + */ + void write(EGG::RamStream& rStrm, const void* pRawSave) const; + + /** + * @brief Gets the size of the current pack's save file, in bytes + */ + static u32 getSaveFileSize(); + +private: + enum { + EFlag_BadPack, //!< The save file is not for this pack + EFlag_BadVersion, //!< The save file is not for this version + EFlag_BadCrc, //!< The save file checksum is invalid + }; + + //! Name of the Pack Project game this save file is intended for +#if defined(PACK_SPORTS) + static const u32 SIGNATURE_PACK = FOURCC('R', 'P', 'S', 'P'); +#elif defined(PACK_PARTY) + static const u32 SIGNATURE_PACK = FOURCC('R', 'P', 'P', 'T'); +#endif + + //! Version of this save file + static const u32 SIGNATURE_VERSION = FOURCC('0', '0', '0', '0'); + +private: + /** + * @brief Calculates a checksum of the specified data + * + * @param pData Data buffer + * @param size Buffer size + * @return 32-bit checksum + */ + static u32 calcCrc(const void* pData, u32 size); + +private: + //! Data error flags + EGG::TBitFlag mFlags; // at 0x0 + + //! Sports Pack system data + RPSportsSystemData* mpSportsSystemData; // at 0x4 + //! Sports Pack player save data list + RPSportsPlayerData* mpSportsPlayerList; // at 0x8 + + //! Party Pack system save data + RPPartySystemData* mpPartySystemData; // at 0xC + //! Party Pack player save data list + RPPartyPlayerData* mpPartyPlayerList; // at 0x10 + + u32 unk14; + u32 unk18; + u32 unk1C; + u32 unk20; + u32 unk24; +}; + +//! @} + +#endif diff --git a/include/Pack/RPSystem/RPSysSceneCreator.h b/include/Pack/RPSystem/RPSysSceneCreator.h index 48a54689..124af2a3 100644 --- a/include/Pack/RPSystem/RPSysSceneCreator.h +++ b/include/Pack/RPSystem/RPSysSceneCreator.h @@ -58,7 +58,7 @@ class RPSysSceneCreator : public EGG::SceneCreator { ESceneID_RPPartyMiiLoadScene, //!< Mii/GameMgr Setup ESceneID_RPPartyMenuScene, //!< Main Menu -#if defined(PACK_PLAY) +#if defined(PACK_PARTY) ESceneID_Max, #endif @@ -193,7 +193,7 @@ class RPSysSceneCreator : public EGG::SceneCreator { * @param id Scene ID */ EGG::Scene* createSportsScene(s32 id); -#elif defined(PACK_PLAY) +#elif defined(PACK_PARTY) /** * @brief Creates a Party Pack scene by ID * diff --git a/include/Pack/RPSystem/RPSysSceneMgr.h b/include/Pack/RPSystem/RPSysSceneMgr.h index 9d0ccc9f..6bfd0334 100644 --- a/include/Pack/RPSystem/RPSysSceneMgr.h +++ b/include/Pack/RPSystem/RPSysSceneMgr.h @@ -6,7 +6,7 @@ #include -//! @addtogroup rp_kernel +//! @addtogroup rp_system //! @{ /** diff --git a/include/Pack/common_message.h b/include/Pack/common_message.h new file mode 100644 index 00000000..23b7f376 --- /dev/null +++ b/include/Pack/common_message.h @@ -0,0 +1,155 @@ +#ifndef RP_COMMON_MESSAGE_H +#define RP_COMMON_MESSAGE_H +#include + +#define MSG_GROUP(X) (((X) & 0xFFFFFF00) >> 8) +#define MSG_INDEX(X) ((X) & 0xFF) +#define MSG_UNPACK(X) MSG_GROUP(X), MSG_INDEX(X) + +struct bmg_message { + u32 group; + u32 index; +}; + +/** + * @brief common_message.bmg message IDs + */ +enum common_message { + // clang-format off + MSG_000_000 = 0x00000000, //!< Yes + MSG_001_000 = 0x00000010, //!< No + MSG_002_000 = 0x00000020, //!< Back + MSG_003_000 = 0x00000030, //!< Wii Menu + MSG_010_000 = 0x00000100, //!< + MSG_011_000 = 0x00000110, //!< + MSG_012_000 = 0x00000120, //!< + MSG_013_000 = 0x00000130, //!< + MSG_014_000 = 0x00000140, //!< + MSG_015_000 = 0x00000150, //!< + MSG_020_000 = 0x00000200, //!< Wii Sports + MSG_021_000 = 0x00000210, //!< Wii Play + MSG_040_000 = 0x00000400, //!< An error has occurred.\nPress the Eject Button,\nremove the Game Disc,\nand turn the power off.\nPlease read the\nWii Operations Manual\nfor help troubleshooting. + MSG_041_000 = 0x00000410, //!< The Game Disc could not be read.\nPlease read the Wii operations\nmanual for more information. + MSG_042_000 = 0x00000420, //!< Please insert the {000000}\nGame Disc. + MSG_043_000 = 0x00000430, //!< Press a button on the Wii Remote\nif you want to continue playing. + MSG_050_000 = 0x00000500, //!< + MSG_051_000 = 0x00000510, //!< + MSG_052_000 = 0x00000520, //!< The game could not be saved.\nContinue without saving?{020001 01 00} + MSG_053_000 = 0x00000530, //!< The Wii System Memory is\ncorrupted. Please refer to the\nWii Operations Manual for help\ntroubleshooting. Continue without\nsaving?{020001 01 00} + MSG_100_000 = 0x00001000, //!< This game's save data is\ncorrupted and must be formatted.\nFormat the data now?{020001 01 00} + MSG_101_000 = 0x00001010, //!< Continue without saving?{020001 01 00} + MSG_102_000 = 0x00001020, //!< + MSG_103_000 = 0x00001030, //!< + MSG_104_000 = 0x00001040, //!< The Wii System Memory does not\nhave enough free space. Either\nmove files to an SD Card or erase\nfiles to save. This game requires\n{000000} empty blocks.\nOpen the Data Management\nscreen now?{020001 01 00} + MSG_105_000 = 0x00001050, //!< Create a save file for {000000}?{020001 00 00} + MSG_106_000 = 0x00001060, //!< + MSG_107_000 = 0x00001070, //!< A save file has been created. + MSG_108_000 = 0x00001080, //!< + MSG_110_000 = 0x00001100, //!< The Wii System Memory does not\nhave enough empty files. Either\nmove files to an SD Card or erase\nfiles to save. Open the Data\nManagement screen now?{020001 01 00} + MSG_150_000 = 0x00001500, //!< The batteries in the Wii Remote\nare running low. Please check the\nbattery level on the HOME Menu. + MSG_160_000 = 0x00001600, //!< Unable to load Mii Channel data.\nPlease access the Mii Channel\nand check Mii Channel data. + MSG_161_000 = 0x00001610, //!< Unable to load Mii data stored\nin the Wii Remote. + MSG_170_000 = 0x00001700, //!< Unable to load saved data.\nPlease try again later.\nIf this problem continues, see\nthe Wii Operations Manual for\nhelp troubleshooting. + MSG_171_000 = 0x00001710, //!< Unable to save. + MSG_200_000 = 0x00002000, //!< To play with this many players,\nyou need {000000} Wii Remotes.\nPlease connect more Wii Remotes.{020000 00 3C} + MSG_210_000 = 0x00002100, //!< Use {000000} Wii Remote with {000000} players. + MSG_211_000 = 0x00002110, //!< Use {000000} Wii Remotes with {000000} players. + MSG_250_000 = 0x00002500, //!< You can't select this until you've\ncreated a Mii in the Mii Channel.{020002 00 00}{020001 00 00} + MSG_250_001 = 0x00002501, //!< Back + MSG_250_002 = 0x00002502, //!< To Wii Menu + MSG_251_000 = 0x00002510, //!< There are no Miis stored on this\nWii Remote. Please add a Mii in\nthe Mii Channel. + MSG_260_000 = 0x00002600, //!< You can't save your records\nwith this Mii. Continue?{020002 01 00}{020001 01 00} + MSG_261_000 = 0x00002610, //!< You can't save My Record data\nwith this Mii. Continue?{020001 01 00}{020002 01 00} + MSG_270_000 = 0x00002700, //!< You can't select this Mii today\nbecause it has taken the Wii\nFitness test. Try again tomorrow. + MSG_271_000 = 0x00002710, //!< The connection between the\nWii Remote and Wii console has\nbeen lost. Press \uE047 and \uE048\nsimultaneously to reconnect... + MSG_280_000 = 0x00002800, //!< Added {000001} to\nthe player list. If you erase\nthis Mii from the Mii Channel, it\nwill be deleted from your player\nlist, so be careful!{020000 00 B4} + MSG_281_000 = 0x00002810, //!< Added {000001} to\nthe player list. If you erase\nthis Mii from the Mii Channel, it\nwill be deleted from your player\nlist, so be careful!{020000 00 B4} + MSG_290_000 = 0x00002900, //!< One or more Miis have been\nerased from the Mii Channel\nand will be removed from your\nplayer list.{020000 00 B4} + MSG_291_000 = 0x00002910, //!< One or more Miis have been\nerased from the Mii Channel\nand will be removed from your\nplayer list.{020000 00 B4} + MSG_300_000 = 0x00003000, //!< Which hand do you want to use? + MSG_301_000 = 0x00003010, //!< Tennis + MSG_302_000 = 0x00003020, //!< Baseball + MSG_303_000 = 0x00003030, //!< Bowling + MSG_304_000 = 0x00003040, //!< Golf + MSG_305_000 = 0x00003050, //!< Boxing + MSG_310_000 = 0x00003100, //!< Swing + MSG_311_000 = 0x00003110, //!< Pitch + MSG_312_000 = 0x00003120, //!< Bat + MSG_313_000 = 0x00003130, //!< Bowl + MSG_314_000 = 0x00003140, //!< Swing + MSG_315_000 = 0x00003150, //!< Stance + MSG_320_000 = 0x00003200, //!< L + MSG_321_000 = 0x00003210, //!< R + MSG_330_000 = 0x00003300, //!< OK + MSG_400_000 = 0x00004000, //!< Select Mii + MSG_401_000 = 0x00004010, //!< Select Players + MSG_402_000 = 0x00004020, //!< Tennis + MSG_403_000 = 0x00004030, //!< Baseball + MSG_404_000 = 0x00004040, //!< Bowling + MSG_405_000 = 0x00004050, //!< Golf + MSG_406_000 = 0x00004060, //!< Boxing + MSG_407_000 = 0x00004070, //!< Training + MSG_408_000 = 0x00004080, //!< Wii Fitness + MSG_409_000 = 0x00004090, //!< Main Menu + MSG_450_000 = 0x00004500, //!< Back + MSG_450_001 = 0x00004501, //!< Main Menu + MSG_451_000 = 0x00004510, //!< P1 + MSG_452_000 = 0x00004520, //!< P2 + MSG_453_000 = 0x00004530, //!< P3 + MSG_454_000 = 0x00004540, //!< P4 + MSG_455_000 = 0x00004550, //!< {000001} + MSG_470_000 = 0x00004700, //!< + MSG_500_000 = 0x00005000, //!< Select the number of players. + MSG_510_000 = 0x00005100, //!< 1 + MSG_511_000 = 0x00005110, //!< 2 + MSG_520_000 = 0x00005200, //!< 1 + MSG_521_000 = 0x00005210, //!< 2 + MSG_522_000 = 0x00005220, //!< 3 + MSG_523_000 = 0x00005230, //!< 4 + MSG_530_000 = 0x00005300, //!< More + MSG_531_000 = 0x00005310, //!< OK + MSG_540_000 = 0x00005400, //!< Wii Remotes + MSG_541_000 = 0x00005410, //!< Press \uE047 and \uE048 at the same time on\neach Wii Remote you want to add. + MSG_600_000 = 0x00006000, //!< Select a Mii for Player {000000}. + MSG_600_001 = 0x00006001, //!< Select a Mii. + MSG_610_000 = 0x00006100, //!< Wii Console + MSG_611_000 = 0x00006110, //!< Guest + MSG_612_000 = 0x00006120, //!< Wii Remote + MSG_613_000 = 0x00006130, //!< Reading Mii data...\nDo not unplug the extension controller. + MSG_620_000 = 0x00006200, //!< Play with this Mii. + MSG_620_001 = 0x00006201, //!< Play with these Miis. + MSG_630_000 = 0x00006300, //!< P1 + MSG_631_000 = 0x00006310, //!< P2 + MSG_632_000 = 0x00006320, //!< + MSG_633_000 = 0x00006330, //!< + MSG_640_000 = 0x00006400, //!< {000001} + MSG_650_000 = 0x00006500, //!< Change + MSG_651_000 = 0x00006510, //!< OK + MSG_660_000 = 0x00006600, //!< Guest A + MSG_661_000 = 0x00006610, //!< Guest B + MSG_662_000 = 0x00006620, //!< Guest C + MSG_663_000 = 0x00006630, //!< Guest D + MSG_664_000 = 0x00006640, //!< Guest E + MSG_665_000 = 0x00006650, //!< Guest F + MSG_700_000 = 0x00007000, //!< Yes + MSG_700_001 = 0x00007001, //!< Back + MSG_701_000 = 0x00007010, //!< No + MSG_701_001 = 0x00007011, //!< Wii Menu + MSG_702_000 = 0x00007020, //!< + MSG_750_000 = 0x00007500, //!< Continue + MSG_751_000 = 0x00007510, //!< Start over + MSG_752_000 = 0x00007520, //!< Quit + MSG_800_000 = 0x00008000, //!< Attach the Wii Remote wrist strap. + MSG_850_000 = 0x00008500, //!< Slip the Wii Remote strap\nthrough the connector\nhook of the Nunchuk plug,\nthen connect the Nunchuk. + MSG_851_000 = 0x00008510, //!< Unplug the extension controller\nconnected to this Wii Remote. + MSG_860_000 = 0x00008600, //!< Put the Wii Remote strap through\nthe Nunchuk's connector hook. + MSG_870_000 = 0x00008700, //!< {000001} + MSG_871_000 = 0x00008710, //!< OK! + MSG_880_000 = 0x00008800, //!< Starting the game...\n\nHold the Wii Remote\nsecurely in your hand and\npress \uE042 and \uE043. + MSG_900_000 = 0x00009000, //!< Are you using your Wii Remote\nJacket? Make sure there are\nno people or objects around\nthat you might bump into! + MSG_901_000 = 0x00009010, //!< Why not take a break?\nYou can pause the game\nby pressing \uE045. + MSG_999_000 = 0x00009990, //!< + // clang-format on +}; + +#endif diff --git a/include/Pack/sports_message.h b/include/Pack/sports_message.h new file mode 100644 index 00000000..6ac98d21 --- /dev/null +++ b/include/Pack/sports_message.h @@ -0,0 +1,1222 @@ +#ifndef RP_SPORTS_MESSAGE_H +#define RP_SPORTS_MESSAGE_H +#include + +#define MSG_GROUP(X) (((X) & 0xFFFFFF00) >> 8) +#define MSG_INDEX(X) ((X) & 0xFF) +#define MSG_UNPACK(X) MSG_GROUP(X), MSG_INDEX(X) + +struct bmg_message { + u32 group; + u32 index; +}; + +/** + * @brief sports_message.bmg message IDs + */ +enum sports_message { + // clang-format off + MSG_00000_000 = 0x00000000, //!< + MSG_00001_000 = 0x00000010, //!< + MSG_00999_000 = 0x00009990, //!< + MSG_01000_000 = 0x00010000, //!< + MSG_01110_000 = 0x00011100, //!< + MSG_01300_000 = 0x00013000, //!< Returning Balls + MSG_01301_000 = 0x00013010, //!< Return the ball inside\nthe court. Just relax\nand focus on hitting\nthe ball. + MSG_01310_000 = 0x00013100, //!< Timing Your Swing + MSG_01311_000 = 0x00013110, //!< Return the ball into\nthe orange bar. Watch\nyour timing, and aim\neach shot carefully. + MSG_01320_000 = 0x00013200, //!< Target Practice + MSG_01321_000 = 0x00013210, //!< Volley the ball off\nthe wall and hit the\ntargets. Controlling\nyour swing speed and\nstrength is essential\nin aiming your shots. + MSG_02000_000 = 0x00020000, //!< + MSG_02100_000 = 0x00021000, //!< + MSG_02101_000 = 0x00021010, //!< + MSG_02101_001 = 0x00021011, //!< + MSG_02101_002 = 0x00021012, //!< + MSG_02101_003 = 0x00021013, //!< + MSG_02102_000 = 0x00021020, //!< + MSG_02300_000 = 0x00023000, //!< Hitting Home Runs + MSG_02301_000 = 0x00023010, //!< Watch the ball, and\ntry to hit it out of\nthe park. Timing is\neverything! + MSG_02310_000 = 0x00023100, //!< Swing Control + MSG_02311_000 = 0x00023110, //!< Hit into the target\nzones on the field.\nMaster this, and you'll\nbe a pro in no time! + MSG_02320_000 = 0x00023200, //!< Batting Practice + MSG_02321_000 = 0x00023210, //!< The pitcher will keep\nthrowing those balls,\nso focus on making\nfast, compact swings! + MSG_03000_000 = 0x00030000, //!< + MSG_03001_000 = 0x00030010, //!< + MSG_03002_000 = 0x00030020, //!< + MSG_03002_001 = 0x00030021, //!< + MSG_03003_000 = 0x00030030, //!< + MSG_03100_000 = 0x00031000, //!< + MSG_03101_000 = 0x00031010, //!< + MSG_03200_000 = 0x00032000, //!< + MSG_03201_000 = 0x00032010, //!< + MSG_03300_000 = 0x00033000, //!< Putting + MSG_03301_000 = 0x00033010, //!< Drop it in the cup with\na single putt. Check\nthe lay of the green\nby pressing \uE047. + MSG_03310_000 = 0x00033100, //!< Hitting the Green + MSG_03311_000 = 0x00033110, //!< Land the ball as close\nto the pin as possible.\nPractice your stroke\nto check the power of\nyour swing. Hold \uE042\nto approach the ball. + MSG_03320_000 = 0x00033200, //!< Target Practice + MSG_03321_000 = 0x00033210, //!< Hit the target with\nthe ball. Before you\ntake your swing, be\nsure to read the\nwind direction. + MSG_04000_000 = 0x00040000, //!< + MSG_04001_000 = 0x00040010, //!< + MSG_04100_000 = 0x00041000, //!< + MSG_04101_000 = 0x00041010, //!< + MSG_05000_000 = 0x00050000, //!< Boxing + MSG_05300_000 = 0x00053000, //!< Throwing Punches + MSG_05301_000 = 0x00053010, //!< Watch your trainer's\nmitts, and try to hit\nthem. You lose points\nif you hit your trainer. + MSG_05310_000 = 0x00053100, //!< Dodging + MSG_05311_000 = 0x00053110, //!< Your trainer throws\nball after ball at you.\nMove left and right\nto avoid getting hit. + MSG_05320_000 = 0x00053200, //!< Working the Bag + MSG_05321_000 = 0x00053210, //!< Throw punches at\nthe punching bags\nuntil you knock them\noff their chains.\nWell-aimed combo\npunches are key. + MSG_06000_000 = 0x00060000, //!< + MSG_06300_000 = 0x00063000, //!< Picking Up Spares + MSG_06301_000 = 0x00063010, //!< Knock down the pins\nwith a single throw.\nTwist your wrist to\ncurve the ball. + MSG_06310_000 = 0x00063100, //!< Spin Control + MSG_06311_000 = 0x00063110, //!< Avoid the barriers in\nthe lane and knock\ndown the pin. You'll\nhave to balance speed\nand spin. + MSG_06320_000 = 0x00063200, //!< Power Throws + MSG_06321_000 = 0x00063210, //!< Knock down as many\npins as you can. A\nnew row will be added\nafter each set. Strikes\ndouble your score! + MSG_07000_000 = 0x00070000, //!< Today's fitness test uses\nthe Nunchuk. Are you able to use\nthe Nunchuk?{020001 00 00} + MSG_07001_000 = 0x00070010, //!< Quit the Wii Fitness test?\n\nIf you quit, you can't do another\nWii Fitness test until tomorrow.{020001 01 00}{020002 01 00} + MSG_07002_000 = 0x00070020, //!< Quitting today's fitness test. + MSG_07003_000 = 0x00070030, //!< + MSG_07004_000 = 0x00070040, //!< + MSG_07005_000 = 0x00070050, //!< + MSG_07006_000 = 0x00070060, //!< Selecting events that do\nnot use the Nunchuk. + MSG_07010_000 = 0x00070100, //!< You can take only one Wii Fitness\ntest each day. You've already\ntaken the test today, so please\ntry again tomorrow. + MSG_07020_000 = 0x00070200, //!< + MSG_07030_000 = 0x00070300, //!< Wii Fitness\n\nTest your speed, stamina, and\nstrength to determine your Wii\nFitness Age. Train every day to\nlower your Wii Fitness Age. + MSG_08000_000 = 0x00080000, //!< {000001}\ndebuted in Wii Sports on\n{000000} at {000000}. + MSG_08010_000 = 0x00080100, //!< You're a tennis pro! + MSG_08011_000 = 0x00080110, //!< You're a baseball pro! + MSG_08012_000 = 0x00080120, //!< You're a pro bowler! + MSG_08013_000 = 0x00080130, //!< You're a pro golfer! + MSG_08014_000 = 0x00080140, //!< You're a pro boxer! + MSG_08020_000 = 0x00080200, //!< You've lost your\ntennis pro status! + MSG_08021_000 = 0x00080210, //!< You've lost your\nbaseball pro status! + MSG_08022_000 = 0x00080220, //!< You've lost your\nbowling pro status! + MSG_08023_000 = 0x00080230, //!< You've lost your\ngolf pro status! + MSG_08024_000 = 0x00080240, //!< You've lost your\nboxing pro status! + MSG_08030_000 = 0x00080300, //!< New personal best!\nGolf: Stroke play + MSG_08030_001 = 0x00080301, //!< Score: {000000} + MSG_08030_002 = 0x00080302, //!< {000000} + MSG_08031_000 = 0x00080310, //!< New personal best!\nBowling: Score play + MSG_08031_001 = 0x00080311, //!< Score: {000000} + MSG_08031_002 = 0x00080312, //!< {000000} + MSG_08040_000 = 0x00080400, //!< New personal best!\n{000000}: {000000} + MSG_08040_001 = 0x00080401, //!< Score: {000000} + MSG_08040_002 = 0x00080402, //!< {000000} pt + MSG_08040_003 = 0x00080403, //!< {000000} pts + MSG_08041_000 = 0x00080410, //!< Home runs: {000000} + MSG_08041_001 = 0x00080411, //!< {000000} homer + MSG_08041_002 = 0x00080412, //!< Total distance: {000000} + MSG_08041_003 = 0x00080413, //!< {000000} foot + MSG_08041_004 = 0x00080414, //!< {000000} feet + MSG_08041_005 = 0x00080415, //!< {000000} homers + MSG_08042_000 = 0x00080420, //!< Hits: {000000} + MSG_08042_001 = 0x00080421, //!< {000000} hit + MSG_08042_002 = 0x00080422, //!< {000000} hits + MSG_08043_000 = 0x00080430, //!< Successful hits: {000000} + MSG_08043_001 = 0x00080431, //!< {000000} hit + MSG_08043_002 = 0x00080432, //!< {000000} hits + MSG_08044_000 = 0x00080440, //!< Pins knocked down: {000000} + MSG_08044_001 = 0x00080441, //!< {000000} pin + MSG_08044_002 = 0x00080442, //!< {000000} pins + MSG_08045_000 = 0x00080450, //!< Cup-in: {000000} + MSG_08045_001 = 0x00080451, //!< {000000} pt + MSG_08045_002 = 0x00080452, //!< {000000} pts + MSG_08046_000 = 0x00080460, //!< Total remaining: {000000} + MSG_08046_001 = 0x00080461, //!< {000000} yard + MSG_08046_002 = 0x00080462, //!< {000000} yards + MSG_08050_000 = 0x00080500, //!< You got a {000000} medal in\n{000000}: {000000}! + MSG_08060_000 = 0x00080600, //!< Wii Fitness Results + MSG_08060_001 = 0x00080601, //!< {000000} years old!\nYou've taken off {000000} year! + MSG_08060_002 = 0x00080602, //!< {000000} years old!\nYou've taken off {000000} years! + MSG_08070_000 = 0x00080700, //!< Impressive! You hit a hole\nin one on hole {000000} in a\nnine-hole game of golf! + MSG_08070_001 = 0x00080701, //!< Impressive! You hit a hole\nin one on hole {000000} in a\nthree-hole game of golf! + MSG_08100_000 = 0x00081000, //!< Wii Sports Debut + MSG_08110_000 = 0x00081100, //!< Pro Status Earned + MSG_08111_000 = 0x00081110, //!< Pro Status Lost + MSG_08112_000 = 0x00081120, //!< New Personal Best Set + MSG_08113_000 = 0x00081130, //!< A New Champion! + MSG_08114_020 = 0x00811420, //!< Impressive! + MSG_08114_030 = 0x00811430, //!< Impressive! + MSG_08120_000 = 0x00081200, //!< New Personal Best Set + MSG_08121_000 = 0x00081210, //!< Platinum Medal Earned! + MSG_08121_001 = 0x00081211, //!< Gold Medal Earned! + MSG_08121_002 = 0x00081212, //!< Silver Medal Earned! + MSG_08121_003 = 0x00081213, //!< Bronzed Medal Earned! + MSG_08122_000 = 0x00081220, //!< All Gold Medals Earned! + MSG_08123_000 = 0x00081230, //!< All Platinum Medals Earned! + MSG_08130_000 = 0x00081300, //!< Wii Fitness Results + MSG_08200_000 = 0x00082000, //!< Wii Sports Debut + MSG_08210_000 = 0x00082100, //!< Tennis Pro Status Reached! + MSG_08210_010 = 0x00821010, //!< Baseball Pro Status Reached! + MSG_08210_020 = 0x00821020, //!< Bowling Pro Status Reached! + MSG_08210_030 = 0x00821030, //!< Golf Pro Status Reached! + MSG_08210_040 = 0x00821040, //!< Boxing Pro Status Reached! + MSG_08211_000 = 0x00082110, //!< Tennis Pro Status Lost! + MSG_08211_010 = 0x00821110, //!< Baseball Pro Status Lost! + MSG_08211_020 = 0x00821120, //!< Bowling Pro Status Lost! + MSG_08211_030 = 0x00821130, //!< Golf Pro Status Lost! + MSG_08211_040 = 0x00821140, //!< Boxing Pro Status Lost! + MSG_08212_020 = 0x00821220, //!< Bowling\n New Personal Best! + MSG_08212_030 = 0x00821230, //!< Golf\n New Personal Best! + MSG_08213_000 = 0x00082130, //!< Tennis\n Beat the tennis champ! + MSG_08213_010 = 0x00821310, //!< Baseball\n Beat the baseball champ! + MSG_08213_040 = 0x00821340, //!< Boxing\n Beat the boxing champ! + MSG_08220_000 = 0x00082200, //!< Tennis: Target Practice\n New Personal Best! + MSG_08220_001 = 0x00082201, //!< Tennis: Timing Your Swing\n New Personal Best! + MSG_08220_002 = 0x00082202, //!< Tennis: Returning Balls\n New Personal Best! + MSG_08220_010 = 0x00822010, //!< Baseball: Hitting Home Runs\n New Personal Best! + MSG_08220_011 = 0x00822011, //!< Baseball: Swing Control\n New Personal Best! + MSG_08220_012 = 0x00822012, //!< Baseball: Batting Practice\n New Personal Best! + MSG_08220_020 = 0x00822020, //!< Bowling: Picking Up Spares\n New Personal Best! + MSG_08220_021 = 0x00822021, //!< Bowling: Power Throws\n New Personal Best! + MSG_08220_022 = 0x00822022, //!< Bowling: Spin Control\n New Personal Best! + MSG_08220_030 = 0x00822030, //!< Golf: Putting\n New Personal Best! + MSG_08220_031 = 0x00822031, //!< Golf: Hitting the Green\n New Personal Best! + MSG_08220_032 = 0x00822032, //!< Golf: Target Practice\n New Personal Best! + MSG_08220_040 = 0x00822040, //!< Boxing: Working the Bag\n New Personal Best! + MSG_08220_041 = 0x00822041, //!< Boxing: Dodging\n New Personal Best! + MSG_08220_042 = 0x00822042, //!< Boxing: Throwing Punches\n New Personal Best! + MSG_08221_000 = 0x00082210, //!< Tennis: Target Practice\n Earned a platinum medal! + MSG_08221_001 = 0x00082211, //!< Tennis: Target Practice\n Earned a gold medal! + MSG_08221_002 = 0x00082212, //!< Tennis: Target Practice\n Earned a silver medal! + MSG_08221_003 = 0x00082213, //!< Tennis: Target Practice\n Earned a bronze medal! + MSG_08221_004 = 0x00082214, //!< Tennis: Timing Your Swing\n Earned a platinum medal! + MSG_08221_005 = 0x00082215, //!< Tennis: Timing Your Swing\n Earned a gold medal! + MSG_08221_006 = 0x00082216, //!< Tennis: Timing Your Swing\n Earned a silver medal! + MSG_08221_007 = 0x00082217, //!< Tennis: Timing Your Swing\n Earned a bronze medal! + MSG_08221_008 = 0x00082218, //!< Tennis: Returning Balls\n Earned a platinum medal! + MSG_08221_009 = 0x00082219, //!< Tennis: Returning Balls\n Earned a gold medal! + MSG_08221_010 = 0x00822110, //!< Tennis: Returning Balls\n Earned a silver medal! + MSG_08221_011 = 0x00822111, //!< Tennis: Returning Balls\n Earned a bronze medal! + MSG_08221_020 = 0x00822120, //!< Baseball: Hitting Home Runs\n Earned a platinum medal! + MSG_08221_021 = 0x00822121, //!< Baseball: Hitting Home Runs\n Earned a gold medal! + MSG_08221_022 = 0x00822122, //!< Baseball: Hitting Home Runs\n Earned a silver medal! + MSG_08221_023 = 0x00822123, //!< Baseball: Hitting Home Runs\n Earned a bronze medal! + MSG_08221_024 = 0x00822124, //!< Baseball: Swing Control\n Earned a platinum medal! + MSG_08221_025 = 0x00822125, //!< Baseball: Swing Control\n Earned a gold medal! + MSG_08221_026 = 0x00822126, //!< Baseball: Swing Control\n Earned a silver medal! + MSG_08221_027 = 0x00822127, //!< Baseball: Swing Control\n Earned a bronze medal! + MSG_08221_028 = 0x00822128, //!< Baseball: Batting Practice\n Earned a platinum medal! + MSG_08221_029 = 0x00822129, //!< Baseball: Batting Practice\n Earned a gold medal! + MSG_08221_030 = 0x00822130, //!< Baseball: Batting Practice\n Earned a silver medal! + MSG_08221_031 = 0x00822131, //!< Baseball: Batting Practice\n Earned a bronze medal! + MSG_08221_040 = 0x00822140, //!< Bowling: Picking Up Spares\n Earned a platinum medal! + MSG_08221_041 = 0x00822141, //!< Bowling: Picking Up Spares\n Earned a gold medal! + MSG_08221_042 = 0x00822142, //!< Bowling: Picking Up Spares\n Earned a silver medal! + MSG_08221_043 = 0x00822143, //!< Bowling: Picking Up Spares\n Earned a bronze medal! + MSG_08221_044 = 0x00822144, //!< Bowling: Power Throws\n Earned a platinum medal! + MSG_08221_045 = 0x00822145, //!< Bowling: Power Throws\n Earned a gold medal! + MSG_08221_046 = 0x00822146, //!< Bowling: Power Throws\n Earned a silver medal! + MSG_08221_047 = 0x00822147, //!< Bowling: Power Throws\n Earned a bronze medal! + MSG_08221_048 = 0x00822148, //!< Bowling: Spin Control\n Earned a platinum medal! + MSG_08221_049 = 0x00822149, //!< Bowling: Spin Control\n Earned a gold medal! + MSG_08221_050 = 0x00822150, //!< Bowling: Spin Control\n Earned a silver medal! + MSG_08221_051 = 0x00822151, //!< Bowling: Spin Control\n Earned a bronze medal! + MSG_08221_060 = 0x00822160, //!< Golf: Putting \n Earned a platinum medal! + MSG_08221_061 = 0x00822161, //!< Golf: Putting \n Earned a gold medal! + MSG_08221_062 = 0x00822162, //!< Golf: Putting \n Earned a silver medal! + MSG_08221_063 = 0x00822163, //!< Golf: Putting \n Earned a bronze medal! + MSG_08221_064 = 0x00822164, //!< Golf: Hitting the Green\n Earned a platinum medal! + MSG_08221_065 = 0x00822165, //!< Golf: Hitting the Green\n Earned a gold medal! + MSG_08221_066 = 0x00822166, //!< Golf: Hitting the Green\n Earned a silver medal! + MSG_08221_067 = 0x00822167, //!< Golf: Hitting the Green\n Earned a bronze medal! + MSG_08221_068 = 0x00822168, //!< Golf: Target Practice\n Earned a platinum medal! + MSG_08221_069 = 0x00822169, //!< Golf: Target Practice\n Earned a gold medal! + MSG_08221_070 = 0x00822170, //!< Golf: Target Practice\n Earned a silver medal! + MSG_08221_071 = 0x00822171, //!< Golf: Target Practice\n Earned a bronze medal! + MSG_08221_080 = 0x00822180, //!< Boxing: Working the Bag\n Earned a platinum medal! + MSG_08221_081 = 0x00822181, //!< Boxing: Working the Bag\n Earned a gold medal! + MSG_08221_082 = 0x00822182, //!< Boxing: Working the Bag\n Earned a silver medal! + MSG_08221_083 = 0x00822183, //!< Boxing: Working the Bag\n Earned a bronze medal! + MSG_08221_084 = 0x00822184, //!< Boxing: Dodging\n Earned a platinum medal! + MSG_08221_085 = 0x00822185, //!< Boxing: Dodging\n Earned a gold medal! + MSG_08221_086 = 0x00822186, //!< Boxing: Dodging\n Earned a silver medal! + MSG_08221_087 = 0x00822187, //!< Boxing: Dodging\n Earned a bronze medal! + MSG_08221_088 = 0x00822188, //!< Boxing: Throwing Punches\n Earned a platinum medal! + MSG_08221_089 = 0x00822189, //!< Boxing: Throwing Punches\n Earned a gold medal! + MSG_08221_090 = 0x00822190, //!< Boxing: Throwing Punches\n Earned a silver medal! + MSG_08221_091 = 0x00822191, //!< Boxing: Throwing Punches\n Earned a bronze medal! + MSG_08300_000 = 0x00083000, //!< The following player has been\nadded to the player list:\n{000001}{000000}\n\nIf you erase this Mii from the\nMii Channel, it will be deleted\nfrom your player list, so be\ncareful. + MSG_08310_000 = 0x00083100, //!< The following player has become\na tennis pro:\n{000001}{000000} + MSG_08310_010 = 0x00831010, //!< The following player has become\na baseball pro:\n{000001}{000000} + MSG_08310_020 = 0x00831020, //!< The following player has become\na bowling pro:\n{000001}{000000} + MSG_08310_030 = 0x00831030, //!< The following player has become\na golf pro:\n{000001}{000000} + MSG_08310_040 = 0x00831040, //!< The following player has become\na boxing pro:\n{000001}{000000} + MSG_08311_000 = 0x00083110, //!< The following player has lost\nthe title of tennis pro:\n{000001}{000000} + MSG_08311_010 = 0x00831110, //!< The following player has lost\nthe title of baseball pro:\n{000001}{000000} + MSG_08311_020 = 0x00831120, //!< The following player has lost\nthe title of bowling pro:\n{000001}{000000} + MSG_08311_030 = 0x00831130, //!< The following player has lost\nthe title of golf pro:\n{000001}{000000} + MSG_08311_040 = 0x00831140, //!< The following player has lost\nthe title of boxing pro:\n{000001}{000000} + MSG_08312_020 = 0x00831220, //!< The following player has set a\nnew personal best in bowling:\n{000001}{000000} + MSG_08312_030 = 0x00831230, //!< The following player has set a\nnew personal best in three-hole\ngolf at the beginner level:\n{000001}{000000} + MSG_08312_031 = 0x00831231, //!< The following player has set a\nnew personal best in three-hole\ngolf at the intermediate level:\n{000001}{000000} + MSG_08312_032 = 0x00831232, //!< The following player has set a\nnew personal best in three-hole\ngolf at the expert level:\n{000001}{000000} + MSG_08312_033 = 0x00831233, //!< The following player has set a\nnew personal best in nine-hole\ngolf:\n{000001}{000000} + MSG_08313_000 = 0x00083130, //!< {000001}{000000} beat\ntennis pro {000000}. + MSG_08313_010 = 0x00831310, //!< {000001}{000000} beat\nbaseball pro {000000}. + MSG_08313_040 = 0x00831340, //!< {000001}{000000} beat\nboxing pro {000000}. + MSG_08314_030 = 0x00831430, //!< The following player hit a hole\nin one on the first hole in golf:\n{000001}{000000} + MSG_08314_031 = 0x00831431, //!< The following player hit a hole\nin one on the second hole in\ngolf:\n{000001}{000000} + MSG_08314_032 = 0x00831432, //!< The following player hit a hole\nin one on the third hole in\ngolf:\n{000001}{000000} + MSG_08314_033 = 0x00831433, //!< The following player hit a hole\nin one on the fourth hole in\ngolf:\n{000001}{000000} + MSG_08314_034 = 0x00831434, //!< The following player hit a hole\nin one on the fifth hole in\ngolf:\n{000001}{000000} + MSG_08314_035 = 0x00831435, //!< The following player hit a hole\nin one on the sixth hole in\ngolf:\n{000001}{000000} + MSG_08314_036 = 0x00831436, //!< The following player hit a hole\nin one on the seventh hole in\ngolf:\n{000001}{000000} + MSG_08314_037 = 0x00831437, //!< The following player hit a hole\nin one on the eighth hole in\ngolf:\n{000001}{000000} + MSG_08314_038 = 0x00831438, //!< The following player hit a hole\nin one on the nine hole in golf:\n{000001}{000000} + MSG_08314_050 = 0x00831450, //!< {000001}{000000} bowled\na perfect game. + MSG_08319_000 = 0x00083190, //!< Score: {000000} ⇒ {000000} + MSG_08320_000 = 0x00083200, //!< The following player has set a\nnew personal best in Tennis:\nTarget Practice:\n{000001}{000000} + MSG_08320_001 = 0x00083201, //!< The following player has set a\nnew personal best in Tennis:\nTiming Your Swing:\n{000001}{000000} + MSG_08320_002 = 0x00083202, //!< The following player has set a\nnew personal best in Tennis:\nReturning Balls:\n{000001}{000000} + MSG_08320_010 = 0x00832010, //!< The following player has set a\nnew personal best in Baseball:\nHitting Home Runs:\n{000001}{000000} + MSG_08320_011 = 0x00832011, //!< The following player has set a\nnew personal best in Baseball:\nSwing Control:\n{000001}{000000} + MSG_08320_012 = 0x00832012, //!< The following player has set a\nnew personal best in Baseball:\nBatting Practice:\n{000001}{000000} + MSG_08320_020 = 0x00832020, //!< The following player has set a\nnew personal best in Bowling:\nPicking Up Spares:\n{000001}{000000} + MSG_08320_021 = 0x00832021, //!< The following player has set a\nnew personal best in Bowling:\nPower Throws:\n{000001}{000000} + MSG_08320_022 = 0x00832022, //!< The following player has set a\nnew personal best in Bowling:\nSpin Control:\n{000001}{000000} + MSG_08320_030 = 0x00832030, //!< The following player has set a\nnew personal best in Golf:\nPutting:\n{000001}{000000} + MSG_08320_031 = 0x00832031, //!< The following player has set a\nnew personal best in Golf:\nHitting the Green:\n{000001}{000000} + MSG_08320_032 = 0x00832032, //!< The following player has set a\nnew personal best in Golf:\nTarget Practice:\n{000001}{000000} + MSG_08320_040 = 0x00832040, //!< The following player has set a\nnew personal best in Boxing:\nWorking the Bag:\n{000001}{000000} + MSG_08320_041 = 0x00832041, //!< The following player has set a\nnew personal best in Boxing:\nDodging:\n{000001}{000000} + MSG_08320_042 = 0x00832042, //!< The following player has set a\nnew personal best in Boxing:\nThrowing Punches:\n{000001}{000000} + MSG_08321_000 = 0x00083210, //!< The following player has earned\na platinum medal in Tennis:\nTarget Practice:\n{000001}{000000} + MSG_08321_001 = 0x00083211, //!< The following player has earned\na gold medal in Tennis:\nTarget Practice:\n{000001}{000000} + MSG_08321_002 = 0x00083212, //!< The following player has earned\na silver medal in Tennis:\nTarget Practice:\n{000001}{000000} + MSG_08321_003 = 0x00083213, //!< The following player has earned\na bronze medal in Tennis:\nTarget Practice:\n{000001}{000000} + MSG_08321_004 = 0x00083214, //!< The following player has earned\na platinum medal in Tennis:\nTiming Your Swing:\n{000001}{000000} + MSG_08321_005 = 0x00083215, //!< The following player has earned\na gold medal in Tennis:\nTiming Your Swing:\n{000001}{000000} + MSG_08321_006 = 0x00083216, //!< The following player has earned\na silver medal in Tennis:\nTiming Your Swing:\n{000001}{000000} + MSG_08321_007 = 0x00083217, //!< The following player has earned\na bronze medal in Tennis:\nTiming Your Swing:\n{000001}{000000} + MSG_08321_008 = 0x00083218, //!< The following player has earned\na platinum medal in Tennis:\nReturning Balls:\n{000001}{000000} + MSG_08321_009 = 0x00083219, //!< The following player has earned\na gold medal in Tennis:\nReturning Balls:\n{000001}{000000} + MSG_08321_010 = 0x00832110, //!< The following player has earned\na silver medal in Tennis:\nReturning Balls:\n{000001}{000000} + MSG_08321_011 = 0x00832111, //!< The following player has earned\na bronze medal in Tennis:\nReturning Balls:\n{000001}{000000} + MSG_08321_020 = 0x00832120, //!< The following player has earned\na platinum medal in Baseball:\nHitting Home Runs:\n{000001}{000000} + MSG_08321_021 = 0x00832121, //!< The following player has earned\na gold medal in Baseball:\nHitting Home Runs:\n{000001}{000000} + MSG_08321_022 = 0x00832122, //!< The following player has earned\na silver medal in Baseball:\nHitting Home Runs:\n{000001}{000000} + MSG_08321_023 = 0x00832123, //!< The following player has earned\na bronze medal in Baseball:\nHitting Home Runs:\n{000001}{000000} + MSG_08321_024 = 0x00832124, //!< The following player has earned\na platinum medal in Baseball:\nSwing Control:\n{000001}{000000} + MSG_08321_025 = 0x00832125, //!< The following player has earned\na gold medal in Baseball:\nSwing Control:\n{000001}{000000} + MSG_08321_026 = 0x00832126, //!< The following player has earned\na silver medal in Baseball:\nSwing Control:\n{000001}{000000} + MSG_08321_027 = 0x00832127, //!< The following player has earned\na bronze medal in Baseball:\nSwing Control:\n{000001}{000000} + MSG_08321_028 = 0x00832128, //!< The following player has earned\na platinum medal in Baseball:\nBatting Practice:\n{000001}{000000} + MSG_08321_029 = 0x00832129, //!< The following player has earned\na gold medal in Baseball:\nBatting Practice:\n{000001}{000000} + MSG_08321_030 = 0x00832130, //!< The following player has earned\na silver medal in Baseball:\nBatting Practice:\n{000001}{000000} + MSG_08321_031 = 0x00832131, //!< The following player has earned\na bronze medal in Baseball:\nBatting Practice:\n{000001}{000000} + MSG_08321_040 = 0x00832140, //!< The following player has earned\na platinum medal in Bowling:\nPicking Up Spares:\n{000001}{000000} + MSG_08321_041 = 0x00832141, //!< The following player has earned\na gold medal in Bowling:\nPicking Up Spares:\n{000001}{000000} + MSG_08321_042 = 0x00832142, //!< The following player has earned\na silver medal in Bowling:\nPicking Up Spares:\n{000001}{000000} + MSG_08321_043 = 0x00832143, //!< The following player has earned\na bronze medal in Bowling:\nPicking Up Spares:\n{000001}{000000} + MSG_08321_044 = 0x00832144, //!< The following player has earned\na platinum medal in Bowling:\nPower Throws:\n{000001}{000000} + MSG_08321_045 = 0x00832145, //!< The following player has earned\na gold medal in Bowling:\nPower Throws:\n{000001}{000000} + MSG_08321_046 = 0x00832146, //!< The following player has earned\na silver medal in Bowling:\nPower Throws:\n{000001}{000000} + MSG_08321_047 = 0x00832147, //!< The following player has earned\na bronze medal in Bowling:\nPower Throws:\n{000001}{000000} + MSG_08321_048 = 0x00832148, //!< The following player has earned\na platinum medal in Bowling:\nSpin Control:\n{000001}{000000} + MSG_08321_049 = 0x00832149, //!< The following player has earned\na gold medal in Bowling:\nSpin Control:\n{000001}{000000} + MSG_08321_050 = 0x00832150, //!< The following player has earned\na silver medal in Bowling:\nSpin Control:\n{000001}{000000} + MSG_08321_051 = 0x00832151, //!< The following player has earned\na bronze medal in Bowling:\nSpin Control:\n{000001}{000000} + MSG_08321_060 = 0x00832160, //!< The following player has earned\na platinum medal in Golf:\nPutting:\n{000001}{000000} + MSG_08321_061 = 0x00832161, //!< The following player has earned\na gold medal in Golf:\nPutting:\n{000001}{000000} + MSG_08321_062 = 0x00832162, //!< The following player has earned\na silver medal in Golf:\nPutting:\n{000001}{000000} + MSG_08321_063 = 0x00832163, //!< The following player has earned\na bronze medal in Golf:\nPutting:\n{000001}{000000} + MSG_08321_064 = 0x00832164, //!< The following player has earned\na platinum medal in Golf:\nHitting the Green:\n{000001}{000000} + MSG_08321_065 = 0x00832165, //!< The following player has earned\na gold medal in Golf:\nHitting the Green:\n{000001}{000000} + MSG_08321_066 = 0x00832166, //!< The following player has earned\na silver medal in Golf:\nHitting the Green:\n{000001}{000000} + MSG_08321_067 = 0x00832167, //!< The following player has earned\na bronze medal in Golf:\nHitting the Green:\n{000001}{000000} + MSG_08321_068 = 0x00832168, //!< The following player has earned\na platinum medal in Golf:\nTarget Practice:\n{000001}{000000} + MSG_08321_069 = 0x00832169, //!< The following player has earned\na gold medal in Golf:\nTarget Practice:\n{000001}{000000} + MSG_08321_070 = 0x00832170, //!< The following player has earned\na silver medal in Golf:\nTarget Practice:\n{000001}{000000} + MSG_08321_071 = 0x00832171, //!< The following player has earned\na bronze medal in Golf:\nTarget Practice:\n{000001}{000000} + MSG_08321_080 = 0x00832180, //!< The following player has earned\na platinum medal in Boxing:\nWorking the Bag:\n{000001}{000000} + MSG_08321_081 = 0x00832181, //!< The following player has earned\na gold medal in Boxing:\nWorking the Bag:\n{000001}{000000} + MSG_08321_082 = 0x00832182, //!< The following player has earned\na silver medal in Boxing:\nWorking the Bag:\n{000001}{000000} + MSG_08321_083 = 0x00832183, //!< The following player has earned\na bronze medal in Boxing:\nWorking the Bag:\n{000001}{000000} + MSG_08321_084 = 0x00832184, //!< The following player has earned\na platinum medal in Boxing:\nDodging:\n{000001}{000000} + MSG_08321_085 = 0x00832185, //!< The following player has earned\na gold medal in Boxing:\nDodging:\n{000001}{000000} + MSG_08321_086 = 0x00832186, //!< The following player has earned\na silver medal in Boxing:\nDodging:\n{000001}{000000} + MSG_08321_087 = 0x00832187, //!< The following player has earned\na bronze medal in Boxing:\nDodging:\n{000001}{000000} + MSG_08321_088 = 0x00832188, //!< The following player has earned\na platinum medal in Boxing:\nThrowing Punches:\n{000001}{000000} + MSG_08321_089 = 0x00832189, //!< The following player has earned\na gold medal in Boxing:\nThrowing Punches:\n{000001}{000000} + MSG_08321_090 = 0x00832190, //!< The following player has earned\na silver medal in Boxing:\nThrowing Punches:\n{000001}{000000} + MSG_08321_091 = 0x00832191, //!< The following player has earned\na bronze medal in Boxing:\nThrowing Punches:\n{000001}{000000} + MSG_08329_000 = 0x00083290, //!< Score: {000000} ⇒ {000000} + MSG_08329_001 = 0x00083291, //!< Score:\n{000000} {000000} ({000000} {000000})\n⇒ {000000} {000000} ({000000} {000000}) + MSG_08329_002 = 0x00083292, //!< Score: {000000} ft ⇒ {000000} ft + MSG_08330_000 = 0x00083300, //!< The following player has earned\ngold medals in all training\ngames:\n{000001}{000000} + MSG_08331_000 = 0x00083310, //!< The following player has earned\nplatinum medals in all training\ngames:\n{000001}{000000} + MSG_08340_000 = 0x00083400, //!< Today's Wii Fitness results for\n{000001}{000000}: + MSG_08341_000 = 0x00083410, //!<        {000000} + MSG_08342_000 = 0x00083420, //!< Wow! You've taken off {000000} {000000}! + MSG_08342_001 = 0x00083421, //!< Wow! You've taken off {000000} {000000}! + MSG_08342_002 = 0x00083422, //!< Oh, no! You've added {000000} {000000}! + MSG_08342_003 = 0x00083423, //!< Oh, no! You've added {000000} {000000}! + MSG_08510_000 = 0x00085100, //!< Tennis Info + MSG_08510_005 = 0x00085105, //!< Skill level\n {000000} + MSG_08510_006 = 0x00085106, //!< Debuted on\n {000000} + MSG_08510_007 = 0x00085107, //!< Games played\n {000000} {000000} + MSG_08510_010 = 0x00851010, //!< Baseball Info + MSG_08510_015 = 0x00851015, //!< Skill level\n {000000} + MSG_08510_016 = 0x00851016, //!< Debuted on\n {000000} + MSG_08510_017 = 0x00851017, //!< Games played\n {000000} + MSG_08510_020 = 0x00851020, //!< Bowling Info + MSG_08510_025 = 0x00851025, //!< Skill level\n {000000} + MSG_08510_026 = 0x00851026, //!< Debuted on\n {000000} + MSG_08510_027 = 0x00851027, //!< Games played\n {000000} + MSG_08510_030 = 0x00851030, //!< Golf Info + MSG_08510_035 = 0x00851035, //!< Skill level\n {000000} + MSG_08510_036 = 0x00851036, //!< Debuted on\n {000000} + MSG_08510_037 = 0x00851037, //!< Games played\n {000000} {000000} + MSG_08510_040 = 0x00851040, //!< Boxing Info + MSG_08510_045 = 0x00851045, //!< Skill level\n {000000} + MSG_08510_046 = 0x00851046, //!< Debuted on\n {000000} + MSG_08510_047 = 0x00851047, //!< Matches fought\n {000000} + MSG_08511_000 = 0x00085110, //!< Tennis Info + MSG_08511_005 = 0x00085115, //!< Skill level\n {000000} + MSG_08511_006 = 0x00085116, //!< Debuted on\n {000000} + MSG_08511_007 = 0x00085117, //!< Games played\n {000000} {000000} + MSG_08511_010 = 0x00851110, //!< Baseball Info + MSG_08511_015 = 0x00851115, //!< Skill level\n {000000} + MSG_08511_016 = 0x00851116, //!< Debuted on\n {000000} + MSG_08511_017 = 0x00851117, //!< Games played\n {000000} + MSG_08511_020 = 0x00851120, //!< Bowling Info + MSG_08511_025 = 0x00851125, //!< Skill level\n {000000} + MSG_08511_026 = 0x00851126, //!< Debuted on\n {000000} + MSG_08511_027 = 0x00851127, //!< Games played\n {000000} + MSG_08511_030 = 0x00851130, //!< Golf Info + MSG_08511_035 = 0x00851135, //!< Skill level\n {000000} + MSG_08511_036 = 0x00851136, //!< Debuted on\n {000000} + MSG_08511_037 = 0x00851137, //!< Games played\n {000000} {000000} + MSG_08511_040 = 0x00851140, //!< Boxing Info + MSG_08511_045 = 0x00851145, //!< Skill level\n {000000} + MSG_08511_046 = 0x00851146, //!< Debuted on\n {000000} + MSG_08511_047 = 0x00851147, //!< Matches fought\n {000000} + MSG_08512_020 = 0x00851220, //!< Bowling Info + MSG_08512_025 = 0x00851225, //!< Skill level\n {000000} + MSG_08512_026 = 0x00851226, //!< Debuted on\n {000000} + MSG_08512_027 = 0x00851227, //!< Games played\n {000000} + MSG_08512_030 = 0x00851230, //!< Golf Info + MSG_08512_035 = 0x00851235, //!< Skill level\n {000000} + MSG_08512_036 = 0x00851236, //!< Debuted on\n {000000} + MSG_08512_037 = 0x00851237, //!< Games played\n {000000} {000000} + MSG_08513_000 = 0x00085130, //!< Tennis Info + MSG_08513_005 = 0x00085135, //!< Skill level\n {000000} + MSG_08513_006 = 0x00085136, //!< Debuted on\n {000000} + MSG_08513_007 = 0x00085137, //!< Matches played\n {000000} + MSG_08513_010 = 0x00851310, //!< Baseball Info + MSG_08513_040 = 0x00851340, //!< Boxing Info + MSG_08514_000 = 0x00085140, //!< Holes in one: {000000} + MSG_08514_001 = 0x00085141, //!< Perfect games: {000000} + MSG_08520_000 = 0x00085200, //!< Training Info + MSG_08520_001 = 0x00085201, //!< Medal earned\n Platinum + MSG_08520_002 = 0x00085202, //!< Medal earned\n Gold + MSG_08520_003 = 0x00085203, //!< Medal earned\n Silver + MSG_08520_004 = 0x00085204, //!< Medal earned\n Bronze + MSG_08520_005 = 0x00085205, //!< Began training on\n {000000} + MSG_08520_006 = 0x00085206, //!< Total training sessions\n {000000} + MSG_08521_000 = 0x00085210, //!< Training Info + MSG_08521_001 = 0x00085211, //!< Personal best\n {000000} + MSG_08521_002 = 0x00085212, //!< Personal best\n {000000} {000000} ({000000} {000000}) + MSG_08521_003 = 0x00085213, //!< Personal best\n {000000} ft + MSG_08521_005 = 0x00085215, //!< Began training on\n {000000} + MSG_08521_006 = 0x00085216, //!< Total training sessions\n {000000} + MSG_08530_000 = 0x00085300, //!< Wii Fitness Info + MSG_08530_001 = 0x00085301, //!< Date of this Wii Fitness test:\n {000000} + MSG_08530_002 = 0x00085302, //!< Date of first Wii Fitness test:\n {000000} + MSG_08530_003 = 0x00085303, //!< Total tests completed:\n {000000} + MSG_08530_004 = 0x00085304, //!< Wii Fitness\n\nMeasure your skill in Wii\nSports. Your test results appear\nas a Wii Fitness Age, with 20\nbeing the best possible age.\n\nBecause these tests are designed\nfor adults, children may not\nget accurate test results. + MSG_08900_000 = 0x00089000, //!< Wii Sports News\n + MSG_08901_000 = 0x00089010, //!< {000000} + MSG_08902_000 = 0x00089020, //!< + MSG_08903_000 = 0x00089030, //!< 【PRO】 + MSG_08910_000 = 0x00089100, //!< + MSG_08910_001 = 0x00089101, //!< + MSG_08911_000 = 0x00089110, //!< set + MSG_08911_001 = 0x00089111, //!< sets + MSG_08912_000 = 0x00089120, //!< hole + MSG_08912_001 = 0x00089121, //!< holes + MSG_08913_000 = 0x00089130, //!< homer + MSG_08913_001 = 0x00089131, //!< homers + MSG_08914_000 = 0x00089140, //!< ft + MSG_08915_000 = 0x00089150, //!< + MSG_08916_000 = 0x00089160, //!< years + MSG_08916_001 = 0x00089161, //!< year + MSG_09999_000 = 0x00099990, //!< + MSG_19000_000 = 0x00190000, //!< Saburo + MSG_19000_001 = 0x00190001, //!< Hiroshi + MSG_19000_002 = 0x00190002, //!< Daisuke + MSG_19000_003 = 0x00190003, //!< Shinnosuke + MSG_19000_004 = 0x00190004, //!< Akira + MSG_19000_005 = 0x00190005, //!< Tatsuaki + MSG_19000_006 = 0x00190006, //!< Shouta + MSG_19000_007 = 0x00190007, //!< Ren + MSG_19000_008 = 0x00190008, //!< Kentaro + MSG_19000_009 = 0x00190009, //!< Takumi + MSG_19000_010 = 0x01900010, //!< Haru + MSG_19000_011 = 0x01900011, //!< Yoshi + MSG_19000_012 = 0x01900012, //!< Fumiko + MSG_19000_013 = 0x01900013, //!< Keiko + MSG_19000_014 = 0x01900014, //!< Yoko + MSG_19000_015 = 0x01900015, //!< Miyu + MSG_19000_016 = 0x01900016, //!< Ai + MSG_19000_017 = 0x01900017, //!< Misaki + MSG_19000_018 = 0x01900018, //!< Rin + MSG_19000_019 = 0x01900019, //!< Sakura + MSG_19000_020 = 0x01900020, //!< Andy + MSG_19000_021 = 0x01900021, //!< Chris + MSG_19000_022 = 0x01900022, //!< Ryan + MSG_19000_023 = 0x01900023, //!< Jake + MSG_19000_024 = 0x01900024, //!< Matt + MSG_19000_025 = 0x01900025, //!< Mike + MSG_19000_026 = 0x01900026, //!< Nick + MSG_19000_027 = 0x01900027, //!< Oscar + MSG_19000_028 = 0x01900028, //!< Theo + MSG_19000_029 = 0x01900029, //!< Tyrone + MSG_19000_030 = 0x01900030, //!< Abby + MSG_19000_031 = 0x01900031, //!< Ashley + MSG_19000_032 = 0x01900032, //!< Emily + MSG_19000_033 = 0x01900033, //!< Hayley + MSG_19000_034 = 0x01900034, //!< Jackie + MSG_19000_035 = 0x01900035, //!< Jessie + MSG_19000_036 = 0x01900036, //!< Maria + MSG_19000_037 = 0x01900037, //!< Naomi + MSG_19000_038 = 0x01900038, //!< Rachel + MSG_19000_039 = 0x01900039, //!< Steph + MSG_19000_040 = 0x01900040, //!< James + MSG_19000_041 = 0x01900041, //!< Steve + MSG_19000_042 = 0x01900042, //!< Michael + MSG_19000_043 = 0x01900043, //!< Martin + MSG_19000_044 = 0x01900044, //!< Pierre + MSG_19000_045 = 0x01900045, //!< Alex + MSG_19000_046 = 0x01900046, //!< Luca + MSG_19000_047 = 0x01900047, //!< Marco + MSG_19000_048 = 0x01900048, //!< David + MSG_19000_049 = 0x01900049, //!< Víctor + MSG_19000_050 = 0x01900050, //!< Sarah + MSG_19000_051 = 0x01900051, //!< Helen + MSG_19000_052 = 0x01900052, //!< Kathrin + MSG_19000_053 = 0x01900053, //!< Silke + MSG_19000_054 = 0x01900054, //!< Emma + MSG_19000_055 = 0x01900055, //!< Julie + MSG_19000_056 = 0x01900056, //!< Anna + MSG_19000_057 = 0x01900057, //!< Elisa + MSG_19000_058 = 0x01900058, //!< Eva + MSG_19000_059 = 0x01900059, //!< Lucía + MSG_20000_000 = 0x00200000, //!< + MSG_20000_001 = 0x00200001, //!< + MSG_20000_002 = 0x00200002, //!< + MSG_20001_000 = 0x00200010, //!< + MSG_20001_001 = 0x00200011, //!< + MSG_20001_002 = 0x00200012, //!< + MSG_20001_003 = 0x00200013, //!< + MSG_20002_000 = 0x00200020, //!< + MSG_20010_000 = 0x00200100, //!< + MSG_20010_001 = 0x00200101, //!< + MSG_20020_000 = 0x00200200, //!< + MSG_20020_001 = 0x00200201, //!< + MSG_20020_002 = 0x00200202, //!< + MSG_20020_003 = 0x00200203, //!< + MSG_20020_004 = 0x00200204, //!< + MSG_20020_005 = 0x00200205, //!< + MSG_20020_006 = 0x00200206, //!< + MSG_20021_000 = 0x00200210, //!< + MSG_20021_001 = 0x00200211, //!< + MSG_20021_002 = 0x00200212, //!< + MSG_20021_003 = 0x00200213, //!< + MSG_20021_004 = 0x00200214, //!< + MSG_20021_005 = 0x00200215, //!< + MSG_20021_006 = 0x00200216, //!< + MSG_20021_007 = 0x00200217, //!< + MSG_20021_008 = 0x00200218, //!< + MSG_20021_009 = 0x00200219, //!< + MSG_20021_010 = 0x02002110, //!< + MSG_20021_011 = 0x02002111, //!< + MSG_20022_000 = 0x00200220, //!< + MSG_20022_001 = 0x00200221, //!< + MSG_20022_002 = 0x00200222, //!< + MSG_20022_003 = 0x00200223, //!< + MSG_20030_000 = 0x00200300, //!< + MSG_20030_001 = 0x00200301, //!< + MSG_20030_002 = 0x00200302, //!< + MSG_20030_003 = 0x00200303, //!< + MSG_20030_004 = 0x00200304, //!< + MSG_20030_005 = 0x00200305, //!< + MSG_20030_006 = 0x00200306, //!< + MSG_20030_007 = 0x00200307, //!< + MSG_20031_000 = 0x00200310, //!< + MSG_20031_001 = 0x00200311, //!< + MSG_20031_002 = 0x00200312, //!< + MSG_20031_003 = 0x00200313, //!< + MSG_20031_004 = 0x00200314, //!< + MSG_20040_000 = 0x00200400, //!< + MSG_20050_000 = 0x00200500, //!< + MSG_20051_000 = 0x00200510, //!< + MSG_20060_000 = 0x00200600, //!< + MSG_20061_000 = 0x00200610, //!< + MSG_20061_001 = 0x00200611, //!< + MSG_20061_002 = 0x00200612, //!< + MSG_20062_000 = 0x00200620, //!< + MSG_20063_000 = 0x00200630, //!< + MSG_20063_001 = 0x00200631, //!< + MSG_20063_002 = 0x00200632, //!< + MSG_20063_003 = 0x00200633, //!< + MSG_20063_004 = 0x00200634, //!< + MSG_20064_000 = 0x00200640, //!< + MSG_20070_000 = 0x00200700, //!< + MSG_20071_000 = 0x00200710, //!< + MSG_20072_000 = 0x00200720, //!< + MSG_20080_000 = 0x00200800, //!< + MSG_20080_001 = 0x00200801, //!< + MSG_21000_000 = 0x00210000, //!< + MSG_21010_000 = 0x00210100, //!< + MSG_21010_001 = 0x00210101, //!< + MSG_21010_002 = 0x00210102, //!< + MSG_21010_003 = 0x00210103, //!< + MSG_21010_004 = 0x00210104, //!< + MSG_21011_000 = 0x00210110, //!< + MSG_21011_001 = 0x00210111, //!< + MSG_21020_000 = 0x00210200, //!< + MSG_21020_001 = 0x00210201, //!< + MSG_21020_002 = 0x00210202, //!< + MSG_21030_000 = 0x00210300, //!< + MSG_21100_000 = 0x00211000, //!< Server + MSG_21110_000 = 0x00211100, //!< Miss + MSG_21120_000 = 0x00211200, //!< Let + MSG_21120_001 = 0x00211201, //!< Out + MSG_21120_002 = 0x00211202, //!< Miss + MSG_21120_003 = 0x00211203, //!< 2nd Bounce + MSG_21130_000 = 0x00211300, //!< 00 + MSG_21130_001 = 0x00211301, //!< 15 + MSG_21130_002 = 0x00211302, //!< 30 + MSG_21130_003 = 0x00211303, //!< 40 + MSG_21130_004 = 0x00211304, //!< Adv. + MSG_21131_000 = 0x00211310, //!< - + MSG_21132_000 = 0x00211320, //!< Deuce + MSG_21132_001 = 0x00211321, //!< Game + MSG_21140_000 = 0x00211400, //!< Advantage + MSG_21141_000 = 0x00211410, //!< Deuce + MSG_21141_001 = 0x00211411, //!< Game Point + MSG_21141_002 = 0x00211412, //!< Break Point + MSG_21141_003 = 0x00211413, //!< Match Point + MSG_21150_000 = 0x00211500, //!< {000001} + MSG_21200_000 = 0x00212000, //!< Choose positions and press \uE042. + MSG_21210_000 = 0x00212100, //!< Single Game + MSG_21211_000 = 0x00212110, //!< Best of 3 + MSG_21212_000 = 0x00212120, //!< Best of 5 + MSG_21220_000 = 0x00212200, //!< Start + MSG_21230_000 = 0x00212300, //!< {000001}{000000}\nSkill Level: {000000} + MSG_21240_000 = 0x00212400, //!< ? + MSG_21300_000 = 0x00213000, //!< {000000} + MSG_21310_000 = 0x00213100, //!< pt + MSG_21310_001 = 0x00213101, //!< pts + MSG_21500_000 = 0x00215000, //!< {000000} + MSG_21510_000 = 0x00215100, //!< Targets left + MSG_21520_000 = 0x00215200, //!< Balls left + MSG_22000_000 = 0x00220000, //!< + MSG_22000_001 = 0x00220001, //!< + MSG_22001_000 = 0x00220010, //!< + MSG_22001_001 = 0x00220011, //!< + MSG_22001_002 = 0x00220012, //!< + MSG_22001_003 = 0x00220013, //!< + MSG_22010_000 = 0x00220100, //!< + MSG_22010_001 = 0x00220101, //!< + MSG_22010_002 = 0x00220102, //!< + MSG_22010_003 = 0x00220103, //!< + MSG_22010_004 = 0x00220104, //!< + MSG_22010_005 = 0x00220105, //!< + MSG_22010_006 = 0x00220106, //!< + MSG_22010_007 = 0x00220107, //!< + MSG_22010_008 = 0x00220108, //!< + MSG_22011_000 = 0x00220110, //!< + MSG_22011_001 = 0x00220111, //!< + MSG_22011_002 = 0x00220112, //!< + MSG_22100_000 = 0x00221000, //!< Play Ball! + MSG_22101_000 = 0x00221010, //!< Mercy Rule + MSG_22110_000 = 0x00221100, //!< Strike + MSG_22110_001 = 0x00221101, //!< Ball + MSG_22110_002 = 0x00221102, //!< Ball Four + MSG_22110_003 = 0x00221103, //!< Strikeout + MSG_22120_000 = 0x00221200, //!< Foul Ball + MSG_22120_001 = 0x00221201, //!< Single + MSG_22120_002 = 0x00221202, //!< Double + MSG_22120_003 = 0x00221203, //!< Triple + MSG_22120_004 = 0x00221204, //!< Home Run + MSG_22120_005 = 0x00221205, //!< Out of the Park + MSG_22130_000 = 0x00221300, //!< Out + MSG_22130_001 = 0x00221301, //!< Double Play + MSG_22130_002 = 0x00221302, //!< Error + MSG_22130_003 = 0x00221303, //!< Change + MSG_22130_004 = 0x00221304, //!< Mercy Rule + MSG_22140_000 = 0x00221400, //!< Fastball + MSG_22140_001 = 0x00221401, //!< Curveball + MSG_22140_002 = 0x00221402, //!< Screwball + MSG_22140_003 = 0x00221403, //!< Splitter + MSG_22150_000 = 0x00221500, //!< mph + MSG_22151_000 = 0x00221510, //!< ft + MSG_22151_001 = 0x00221511, //!< ft + MSG_22160_000 = 0x00221600, //!< 1ST + MSG_22160_001 = 0x00221601, //!< 2ND + MSG_22160_002 = 0x00221602, //!< 3RD + MSG_22170_000 = 0x00221700, //!< + MSG_22180_000 = 0x00221800, //!< + MSG_22180_001 = 0x00221801, //!< + MSG_22180_002 = 0x00221802, //!< + MSG_22190_000 = 0x00221900, //!< Vs. + MSG_22191_000 = 0x00221910, //!< 1 + MSG_22191_001 = 0x00221911, //!< 2 + MSG_22191_002 = 0x00221912, //!< 3 + MSG_22191_003 = 0x00221913, //!< R + MSG_22192_000 = 0x00221920, //!< B + MSG_22192_001 = 0x00221921, //!< S + MSG_22193_002 = 0x00221932, //!< O + MSG_22200_000 = 0x00222000, //!< {000001} + MSG_22201_000 = 0x00222010, //!< + MSG_22210_000 = 0x00222100, //!< Strikeout + MSG_22210_001 = 0x00222101, //!< Ball Four + MSG_22210_002 = 0x00222102, //!< Out + MSG_22210_003 = 0x00222103, //!< Single + MSG_22210_004 = 0x00222104, //!< Double + MSG_22210_005 = 0x00222105, //!< Triple + MSG_22210_006 = 0x00222106, //!< Home Run + MSG_22210_007 = 0x00222107, //!< Out of the Park + MSG_22210_008 = 0x00222108, //!< + MSG_22220_000 = 0x00222200, //!< + MSG_22220_001 = 0x00222201, //!< + MSG_22220_002 = 0x00222202, //!< + MSG_22230_000 = 0x00222300, //!< That's the Game! + MSG_22240_000 = 0x00222400, //!< R + MSG_22250_000 = 0x00222500, //!< Play again + MSG_22251_000 = 0x00222510, //!< Quit + MSG_22252_000 = 0x00222520, //!< Next + MSG_22300_000 = 0x00223000, //!< + MSG_22301_000 = 0x00223010, //!< + MSG_22350_000 = 0x00223500, //!< + MSG_22400_000 = 0x00224000, //!< 10 balls + MSG_22400_001 = 0x00224001, //!< 30 balls + MSG_22410_000 = 0x00224100, //!< You swung too early! + MSG_22410_001 = 0x00224101, //!< You're a tad early! + MSG_22410_002 = 0x00224102, //!< You swung too late! + MSG_22410_003 = 0x00224103, //!< You're a tad late! + MSG_22420_000 = 0x00224200, //!< Home run + MSG_22420_001 = 0x00224201, //!< Out of the park + MSG_22450_000 = 0x00224500, //!< + MSG_22451_000 = 0x00224510, //!< + MSG_22500_000 = 0x00225000, //!< 10 pitches + MSG_22510_000 = 0x00225100, //!< {000000} runs + MSG_22520_000 = 0x00225200, //!< + MSG_22600_000 = 0x00226000, //!< Left + MSG_22601_000 = 0x00226010, //!< + MSG_22610_000 = 0x00226100, //!< Hits + MSG_22611_000 = 0x00226110, //!< + MSG_22611_001 = 0x00226111, //!< + MSG_22612_000 = 0x00226120, //!< Hit! + MSG_22620_000 = 0x00226200, //!< + MSG_22621_000 = 0x00226210, //!< + MSG_22650_000 = 0x00226500, //!< + MSG_22651_000 = 0x00226510, //!< + MSG_22700_000 = 0x00227000, //!< Vs. + MSG_22710_000 = 0x00227100, //!< {000001}{000000} + MSG_22711_000 = 0x00227110, //!< Skill Level: {000000} + MSG_22720_000 = 0x00227200, //!< {000001}{000000} + MSG_22721_000 = 0x00227210, //!< Skill Level: {000000} + MSG_22800_000 = 0x00228000, //!< Batting + MSG_22801_000 = 0x00228010, //!< + MSG_22810_000 = 0x00228100, //!< How to Hold + MSG_22811_000 = 0x00228110, //!< Hold the Wii Remote so that the side\nwith the buttons is facing you. + MSG_22820_000 = 0x00228200, //!< Batting + MSG_22821_000 = 0x00228210, //!< Hold the Wii Remote like a bat. Swing at\npitches at the right time to hit them. + MSG_22830_000 = 0x00228300, //!< Pitching + MSG_22831_000 = 0x00228310, //!< + MSG_22840_000 = 0x00228400, //!< Pitching + MSG_22841_000 = 0x00228410, //!< Swing the Wii Remote overhand to pitch.\nAim your pitch with \uE041. + MSG_22850_000 = 0x00228500, //!< Breaking Balls + MSG_22851_000 = 0x00228510, //!< Pitch while pressing \uE042 for a screwball,\n\uE043 for a curveball, and \uE042+\uE043 for a splitter. + MSG_22851_001 = 0x00228511, //!< Pitch while pressing \uE042 for a curveball,\n\uE043 for a screwball, and \uE042+\uE043 for a splitter. + MSG_22860_000 = 0x00228600, //!< Swing to pitch. + MSG_23000_000 = 0x00230000, //!< + MSG_23001_000 = 0x00230010, //!< + MSG_23010_000 = 0x00230100, //!< + MSG_23011_000 = 0x00230110, //!< + MSG_23011_001 = 0x00230111, //!< + MSG_23012_000 = 0x00230120, //!< + MSG_23012_001 = 0x00230121, //!< + MSG_23012_002 = 0x00230122, //!< + MSG_23012_003 = 0x00230123, //!< + MSG_23012_004 = 0x00230124, //!< + MSG_23020_000 = 0x00230200, //!< + MSG_23020_001 = 0x00230201, //!< + MSG_23020_002 = 0x00230202, //!< + MSG_23020_003 = 0x00230203, //!< + MSG_23020_004 = 0x00230204, //!< + MSG_23030_000 = 0x00230300, //!< + MSG_23030_001 = 0x00230301, //!< + MSG_23100_000 = 0x00231000, //!< Select a course + MSG_23101_000 = 0x00231010, //!< 9-Hole Game + MSG_23102_000 = 0x00231020, //!< 3-Hole Game + MSG_23103_000 = 0x00231030, //!< Beginner + MSG_23103_001 = 0x00231031, //!< Holes 1 to 3 + MSG_23104_000 = 0x00231040, //!< Intermediate + MSG_23104_001 = 0x00231041, //!< Holes 4 to 5 + MSG_23105_000 = 0x00231050, //!< Expert + MSG_23105_001 = 0x00231051, //!< Holes 6 to 9 + MSG_23106_000 = 0x00231060, //!< Main menu + MSG_23110_000 = 0x00231100, //!< Hole {000000}: Par {000000} + MSG_23111_000 = 0x00231110, //!< {000001} + MSG_23112_000 = 0x00231120, //!< Best + MSG_23113_000 = 0x00231130, //!< + MSG_23114_000 = 0x00231140, //!< Skill Level + MSG_23115_000 = 0x00231150, //!< + MSG_23116_000 = 0x00231160, //!< Score + MSG_23117_000 = 0x00231170, //!< + MSG_23120_000 = 0x00231200, //!< Stroke {000000} + MSG_23121_000 = 0x00231210, //!< {000001}{000000} + MSG_23130_000 = 0x00231300, //!< Hole {000000}: Par {000000} + MSG_23131_000 = 0x00231310, //!< {000000} yd left + MSG_23131_001 = 0x00231311, //!< {000000} yds left + MSG_23131_002 = 0x00231312, //!< {000000} ft left + MSG_23131_003 = 0x00231313, //!< {000000} ft left + MSG_23132_000 = 0x00231320, //!< {000000} mph + MSG_23132_001 = 0x00231321, //!< Wind + MSG_23132_002 = 0x00231322, //!< mph + MSG_23133_000 = 0x00231330, //!< Driver + MSG_23133_001 = 0x00231331, //!< Iron + MSG_23133_002 = 0x00231332, //!< Wedge + MSG_23133_003 = 0x00231333, //!< Putter + MSG_23134_000 = 0x00231340, //!< To hit the ball, hold down \uE042 and swing.\n㌍\uE041㍗: Aim, ㌦\uE041㌣: Change clubs + MSG_23135_000 = 0x00231350, //!< To hit the ball, hold down \uE042 and swing.\n㌍\uE041㍗: Aim, \uE047: Read green\n\uE048: Change camera + MSG_23136_000 = 0x00231360, //!< + MSG_23140_000 = 0x00231400, //!< Green + MSG_23140_001 = 0x00231401, //!< Edge of Green + MSG_23140_002 = 0x00231402, //!< Fairway + MSG_23140_003 = 0x00231403, //!< Rough + MSG_23140_004 = 0x00231404, //!< Bunker + MSG_23140_005 = 0x00231405, //!< Out of Bounds + MSG_23140_006 = 0x00231406, //!< Water Hazard + MSG_23140_007 = 0x00231407, //!< Off the Green + MSG_23141_000 = 0x00231410, //!< {000000} yard to go + MSG_23141_001 = 0x00231411, //!< {000000} yards to go + MSG_23142_000 = 0x00231420, //!< {000000} foot to go + MSG_23142_001 = 0x00231421, //!< {000000} feet to go + MSG_23150_000 = 0x00231500, //!< Hole in One + MSG_23150_001 = 0x00231501, //!< Double Eagle + MSG_23150_002 = 0x00231502, //!< Eagle + MSG_23150_003 = 0x00231503, //!< Birdie + MSG_23150_004 = 0x00231504, //!< Par + MSG_23150_005 = 0x00231505, //!< Bogey + MSG_23150_006 = 0x00231506, //!< Double Bogey + MSG_23150_007 = 0x00231507, //!< Triple Bogey + MSG_23150_008 = 0x00231508, //!< {000000} + MSG_23160_000 = 0x00231600, //!< Give up + MSG_23161_000 = 0x00231610, //!< {000000} + MSG_23170_000 = 0x00231700, //!< Scorecard + MSG_23180_000 = 0x00231800, //!< New personal best! + MSG_23181_000 = 0x00231810, //!< Next + MSG_23182_000 = 0x00231820, //!< Hole + MSG_23183_000 = 0x00231830, //!< Total + MSG_23184_000 = 0x00231840, //!< Par + MSG_23185_000 = 0x00231850, //!< {000001} + MSG_23200_000 = 0x00232000, //!< Round {000000} + MSG_23210_000 = 0x00232100, //!< Distance left: {000000} ft + MSG_23210_001 = 0x00232101, //!< Distance left: {000000} ft + MSG_23220_000 = 0x00232200, //!< Try again + MSG_23300_000 = 0x00233000, //!< Total: {000000} ft + MSG_23300_001 = 0x00233001, //!< Total: {000000} ft + MSG_23310_000 = 0x00233100, //!< + MSG_23311_000 = 0x00233110, //!< + MSG_23311_001 = 0x00233111, //!< Score: {000000} ft + MSG_23400_000 = 0x00234000, //!< Total: {000000} pt + MSG_23400_001 = 0x00234001, //!< Total: {000000} pts + MSG_23401_000 = 0x00234010, //!< Miss + MSG_23401_001 = 0x00234011, //!< +10 + MSG_23401_002 = 0x00234012, //!< +25 + MSG_23401_003 = 0x00234013, //!< +50 + MSG_23401_004 = 0x00234014, //!< +100 + MSG_23401_005 = 0x00234015, //!< +75 + MSG_23500_000 = 0x00235000, //!< High + MSG_23501_000 = 0x00235010, //!< Low + MSG_23600_000 = 0x00236000, //!< Hold the Wii Remote down, like a club.\nSwing as though you are hitting the\nball with the side of the Wii Remote. + MSG_23601_000 = 0x00236010, //!< Check the strength of your swing\nwith the power gauge. + MSG_23602_000 = 0x00236020, //!< If you swing too hard and max out the\ngauge, your shot will slice or hook. + MSG_23603_000 = 0x00236030, //!< Try some practice swings before you\nstep up to hit the ball. + MSG_23604_000 = 0x00236040, //!< Let's take a swing at the ball.\nAim the Wii Remote down and hold\ndown \uE042 to swing. + MSG_24000_000 = 0x00240000, //!< + MSG_24001_000 = 0x00240010, //!< + MSG_24002_000 = 0x00240020, //!< + MSG_24002_001 = 0x00240021, //!< + MSG_25000_000 = 0x00250000, //!< + MSG_25001_000 = 0x00250010, //!< + MSG_25002_000 = 0x00250020, //!< + MSG_25003_000 = 0x00250030, //!< + MSG_25010_000 = 0x00250100, //!< Decision + MSG_25011_000 = 0x00250110, //!< Decision + MSG_25020_000 = 0x00250200, //!< + MSG_25021_000 = 0x00250210, //!< + MSG_25030_000 = 0x00250300, //!< R1 + MSG_25030_001 = 0x00250301, //!< R2 + MSG_25030_002 = 0x00250302, //!< R3 + MSG_25040_000 = 0x00250400, //!< pt + MSG_25040_001 = 0x00250401, //!< pts + MSG_25100_000 = 0x00251000, //!< + MSG_25101_000 = 0x00251010, //!< + MSG_25200_000 = 0x00252000, //!< + MSG_25201_000 = 0x00252010, //!< + MSG_25300_000 = 0x00253000, //!< + MSG_25301_000 = 0x00253010, //!< + MSG_25400_000 = 0x00254000, //!< Guard your face! + MSG_25401_000 = 0x00254010, //!< Hold the Wii Remote and Nunchuk\nup in front of your face. + MSG_25410_000 = 0x00254100, //!< Punch the face! + MSG_25411_000 = 0x00254110, //!< Jab with the Wii Remote to punch\nyour opponent's head. + MSG_25420_000 = 0x00254200, //!< Guard your body! + MSG_25421_000 = 0x00254210, //!< Hold the Wii Remote and Nunchuk in front\nof your torso and tilt them inward. + MSG_25430_000 = 0x00254300, //!< Punch the Body + MSG_25431_000 = 0x00254310, //!< Jab with the Wii Remote to punch\nyour opponent's body. + MSG_25440_000 = 0x00254400, //!< Dodge Punches + MSG_25441_000 = 0x00254410, //!< Hold the Wii Remote and Nunchuk and tilt\nyour body forward, back, left, or right. + MSG_25550_000 = 0x00255500, //!< Fighting Stance + MSG_25551_000 = 0x00255510, //!< Hold the Wii Remote in your dominant\nhand and the Nunchuk in the other hand. + MSG_26000_000 = 0x00260000, //!< Raise the Wii Remote and hold \uE043. + MSG_26001_000 = 0x00260010, //!< Take a swing while\nholding \uE043. Release \uE043\nas you roll the ball. + MSG_26002_000 = 0x00260020, //!< Swing your arm while\nholding down \uE043, and\nrelease it to roll the ball. + MSG_26010_000 = 0x00260100, //!< Strike + MSG_26010_001 = 0x00260101, //!< Spare + MSG_26010_002 = 0x00260102, //!< {000000} pin + MSG_26010_003 = 0x00260103, //!< {000000} pins + MSG_26011_000 = 0x00260110, //!< Double + MSG_26011_001 = 0x00260111, //!< Turkey + MSG_26011_002 = 0x00260112, //!< Fourth + MSG_26011_003 = 0x00260113, //!< Fifth + MSG_26011_004 = 0x00260114, //!< Six-pack + MSG_26011_005 = 0x00260115, //!< Seven-pack + MSG_26011_006 = 0x00260116, //!< Eight in a row + MSG_26011_007 = 0x00260117, //!< Nine in a row + MSG_26011_008 = 0x00260118, //!< Ten in a row + MSG_26011_009 = 0x00260119, //!< Eleven in a row + MSG_26011_010 = 0x02601110, //!< Perfect + MSG_26012_000 = 0x00260120, //!< Missed + MSG_26020_000 = 0x00260200, //!< Scorecard + MSG_26021_000 = 0x00260210, //!< Record! + MSG_26022_000 = 0x00260220, //!< - + MSG_26023_000 = 0x00260230, //!< ①②③④⑤⑥⑦⑧ + MSG_26030_000 = 0x00260300, //!< Next + MSG_26040_000 = 0x00260400, //!< Move + MSG_26040_001 = 0x00260401, //!< Turn + MSG_26041_000 = 0x00260410, //!< Switch + MSG_26042_000 = 0x00260420, //!< Back + MSG_26050_000 = 0x00260500, //!< Game Finished + MSG_26060_000 = 0x00260600, //!< Replay + MSG_26100_000 = 0x00261000, //!< Stage {000000} + MSG_26101_000 = 0x00261010, //!< {000000} pins + MSG_26102_000 = 0x00261020, //!< Stage {000000} + MSG_26110_000 = 0x00261100, //!< Missed + MSG_26120_000 = 0x00261200, //!< Challenge cleared + MSG_26200_000 = 0x00262000, //!< + MSG_26300_000 = 0x00263000, //!< + MSG_26400_000 = 0x00264000, //!< {000000} pin + MSG_26400_001 = 0x00264001, //!< {000000} pins + MSG_26401_000 = 0x00264010, //!< × + MSG_26500_000 = 0x00265000, //!< Perfect! + MSG_27000_000 = 0x00270000, //!< {000001} + MSG_27001_000 = 0x00270010, //!< Wii Fitness + MSG_27010_000 = 0x00270100, //!< Wii Fitness Age: + MSG_27011_000 = 0x00270110, //!< + MSG_27020_000 = 0x00270200, //!< {000000} + MSG_27021_000 = 0x00270210, //!< Sun + MSG_27021_001 = 0x00270211, //!< Mon + MSG_27021_002 = 0x00270212, //!< Tues + MSG_27021_003 = 0x00270213, //!< Wed + MSG_27021_004 = 0x00270214, //!< Thurs + MSG_27021_005 = 0x00270215, //!< Fri + MSG_27021_006 = 0x00270216, //!< Sat + MSG_27030_000 = 0x00270300, //!< Start + MSG_27031_000 = 0x00270310, //!< Done + MSG_27100_000 = 0x00271000, //!< Speed + MSG_27101_000 = 0x00271010, //!< Balance + MSG_27102_000 = 0x00271020, //!< Stamina + MSG_27200_000 = 0x00272000, //!< Results + MSG_27210_000 = 0x00272100, //!< {000001} + MSG_27210_001 = 0x00272101, //!< + MSG_27210_002 = 0x00272102, //!< + MSG_27220_000 = 0x00272200, //!< + MSG_27230_000 = 0x00272300, //!< + MSG_27250_000 = 0x00272500, //!< Wow! It's like you're {000000} years younger! + MSG_27251_000 = 0x00272510, //!< It's like you're a whole year younger! + MSG_27251_001 = 0x00272511, //!< It's like you're {000000} years younger! + MSG_27252_000 = 0x00272520, //!< No change + MSG_27253_000 = 0x00272530, //!< A bit lower than before + MSG_27254_000 = 0x00272540, //!< A big decline + MSG_27255_000 = 0x00272550, //!< Good job! + MSG_27400_000 = 0x00274000, //!< JAN + MSG_27400_001 = 0x00274001, //!< FEB + MSG_27400_002 = 0x00274002, //!< MAR + MSG_27400_003 = 0x00274003, //!< APR + MSG_27400_004 = 0x00274004, //!< MAY + MSG_27400_005 = 0x00274005, //!< JUN + MSG_27400_006 = 0x00274006, //!< JUL + MSG_27400_007 = 0x00274007, //!< AUG + MSG_27400_008 = 0x00274008, //!< SEP + MSG_27400_009 = 0x00274009, //!< OCT + MSG_27400_010 = 0x02740010, //!< NOV + MSG_27400_011 = 0x02740011, //!< DEC + MSG_27500_000 = 0x00275000, //!< {000000} + MSG_27600_000 = 0x00276000, //!< Testing... + MSG_27601_000 = 0x00276010, //!< Wii Fitness Age + MSG_28000_000 = 0x00280000, //!< + MSG_29000_000 = 0x00290000, //!< + MSG_29000_001 = 0x00290001, //!< + MSG_29000_002 = 0x00290002, //!< + MSG_29000_003 = 0x00290003, //!< + MSG_29000_004 = 0x00290004, //!< + MSG_29000_005 = 0x00290005, //!< + MSG_29000_006 = 0x00290006, //!< + MSG_29000_007 = 0x00290007, //!< + MSG_29000_008 = 0x00290008, //!< + MSG_29000_009 = 0x00290009, //!< + MSG_29000_010 = 0x02900010, //!< + MSG_29000_011 = 0x02900011, //!< + MSG_29000_012 = 0x02900012, //!< + MSG_29000_013 = 0x02900013, //!< + MSG_29000_014 = 0x02900014, //!< + MSG_29010_000 = 0x00290100, //!< Start + MSG_29010_001 = 0x00290101, //!< Finished + MSG_29100_000 = 0x00291000, //!< + MSG_29111_000 = 0x00291110, //!< + MSG_29112_000 = 0x00291120, //!< + MSG_29113_000 = 0x00291130, //!< + MSG_29114_000 = 0x00291140, //!< + MSG_29115_000 = 0x00291150, //!< + MSG_29120_000 = 0x00291200, //!< + MSG_29121_000 = 0x00291210, //!< + MSG_29122_000 = 0x00291220, //!< + MSG_29123_000 = 0x00291230, //!< + MSG_29124_000 = 0x00291240, //!< + MSG_29125_000 = 0x00291250, //!< + MSG_29130_000 = 0x00291300, //!< + MSG_29131_000 = 0x00291310, //!< + MSG_29140_000 = 0x00291400, //!< + MSG_29200_000 = 0x00292000, //!< Training + MSG_29201_000 = 0x00292010, //!< Main menu + MSG_29202_000 = 0x00292020, //!< Wii Fitness + MSG_29210_000 = 0x00292100, //!< Tennis + MSG_29211_000 = 0x00292110, //!< Baseball + MSG_29212_000 = 0x00292120, //!< Bowling + MSG_29213_000 = 0x00292130, //!< Golf + MSG_29214_000 = 0x00292140, //!< Boxing + MSG_29230_000 = 0x00292300, //!< Returning Balls + MSG_29231_000 = 0x00292310, //!< Timing Your Swing + MSG_29232_000 = 0x00292320, //!< Target Practice + MSG_29233_000 = 0x00292330, //!< Hitting Home Runs + MSG_29234_000 = 0x00292340, //!< Batting Practice + MSG_29235_000 = 0x00292350, //!< Swing Control + MSG_29236_000 = 0x00292360, //!< Picking Up Spares + MSG_29237_000 = 0x00292370, //!< Spin Control + MSG_29238_000 = 0x00292380, //!< Power Throws + MSG_29239_000 = 0x00292390, //!< Putting + MSG_29240_000 = 0x00292400, //!< Hitting the Green + MSG_29241_000 = 0x00292410, //!< Target Practice + MSG_29242_000 = 0x00292420, //!< Throwing Punches + MSG_29243_000 = 0x00292430, //!< Dodging + MSG_29244_000 = 0x00292440, //!< Working the Bag + MSG_29300_000 = 0x00293000, //!< \uE042: Start + MSG_29310_000 = 0x00293100, //!< ??? + MSG_29400_000 = 0x00294000, //!< First event + MSG_29400_001 = 0x00294001, //!< Second event + MSG_29400_002 = 0x00294002, //!< Third event + MSG_29500_000 = 0x00295000, //!< Skill Level + MSG_29501_000 = 0x00295010, //!< PRO + MSG_29502_000 = 0x00295020, //!< Play again + MSG_29503_000 = 0x00295030, //!< Quit + MSG_29510_000 = 0x00295100, //!< {000001}{000000} + MSG_29511_000 = 0x00295110, //!< {000000} + MSG_29600_000 = 0x00296000, //!< {000001}{000000} + MSG_29601_000 = 0x00296010, //!< Pause + MSG_29610_000 = 0x00296100, //!< Record: {000000} pt + MSG_29610_001 = 0x00296101, //!< Record: {000000} pts + MSG_29611_000 = 0x00296110, //!< Record: {000000} pt + MSG_29611_001 = 0x00296111, //!< Record: {000000} pts + MSG_29612_000 = 0x00296120, //!< Record: {000000} pt + MSG_29612_001 = 0x00296121, //!< Record: {000000} pts + MSG_29620_000 = 0x00296200, //!< Record: {000000} homer ({000000} ft) + MSG_29620_001 = 0x00296201, //!< Record: {000000} homers ({000000} ft) + MSG_29621_000 = 0x00296210, //!< Record: {000000} pt + MSG_29621_001 = 0x00296211, //!< Record: {000000} pts + MSG_29622_000 = 0x00296220, //!< Record: {000000} hit + MSG_29622_001 = 0x00296221, //!< Record: {000000} hits + MSG_29630_000 = 0x00296300, //!< Record: {000000} pt + MSG_29630_001 = 0x00296301, //!< Record: {000000} pts + MSG_29631_000 = 0x00296310, //!< Record: {000000} ft + MSG_29631_001 = 0x00296311, //!< Record: {000000} ft + MSG_29632_000 = 0x00296320, //!< Record: {000000} pt + MSG_29632_001 = 0x00296321, //!< Record: {000000} pts + MSG_29640_000 = 0x00296400, //!< Record: {000000} pt + MSG_29640_001 = 0x00296401, //!< Record: {000000} pts + MSG_29641_000 = 0x00296410, //!< Record: {000000} pt + MSG_29641_001 = 0x00296411, //!< Record: {000000} pts + MSG_29642_000 = 0x00296420, //!< Record: {000000} pt + MSG_29642_001 = 0x00296421, //!< Record: {000000} pts + MSG_29650_000 = 0x00296500, //!< Record: {000000} lane + MSG_29650_001 = 0x00296501, //!< Record: {000000} lanes + MSG_29651_000 = 0x00296510, //!< Record: {000000} lane + MSG_29651_001 = 0x00296511, //!< Record: {000000} lanes + MSG_29652_000 = 0x00296520, //!< Record: {000000} pin + MSG_29652_001 = 0x00296521, //!< Record: {000000} pins + MSG_29700_000 = 0x00297000, //!< {000001}{000000} + MSG_29701_000 = 0x00297010, //!< Record! + MSG_29702_000 = 0x00297020, //!< Try again + MSG_29703_000 = 0x00297030, //!< Quit + MSG_29710_000 = 0x00297100, //!< Returning Balls + MSG_29710_001 = 0x00297101, //!< Score: + MSG_29710_002 = 0x00297102, //!< pt + MSG_29710_003 = 0x00297103, //!< pts + MSG_29711_000 = 0x00297110, //!< Timing Your Swing + MSG_29711_001 = 0x00297111, //!< Score: + MSG_29711_002 = 0x00297112, //!< pt + MSG_29711_003 = 0x00297113, //!< pts + MSG_29712_000 = 0x00297120, //!< Target Practice + MSG_29712_001 = 0x00297121, //!< Score: + MSG_29712_002 = 0x00297122, //!< pt + MSG_29712_003 = 0x00297123, //!< pts + MSG_29720_000 = 0x00297200, //!< Hitting Home Runs + MSG_29720_001 = 0x00297201, //!< Home runs: + MSG_29720_002 = 0x00297202, //!< run + MSG_29720_003 = 0x00297203, //!< runs + MSG_29720_004 = 0x00297204, //!< Total distance: + MSG_29720_005 = 0x00297205, //!< ft + MSG_29720_006 = 0x00297206, //!< ft + MSG_29721_000 = 0x00297210, //!< Swing Control + MSG_29721_001 = 0x00297211, //!< Score: + MSG_29721_002 = 0x00297212, //!< pt + MSG_29721_003 = 0x00297213, //!< pts + MSG_29722_000 = 0x00297220, //!< Batting Practice + MSG_29722_001 = 0x00297221, //!< Score: + MSG_29722_002 = 0x00297222, //!< hit + MSG_29722_003 = 0x00297223, //!< hits + MSG_29730_000 = 0x00297300, //!< Putting + MSG_29730_001 = 0x00297301, //!< Cup-in: + MSG_29730_002 = 0x00297302, //!< pt + MSG_29730_003 = 0x00297303, //!< pts + MSG_29731_000 = 0x00297310, //!< Hitting the Green + MSG_29731_001 = 0x00297311, //!< Total left: + MSG_29731_002 = 0x00297312, //!< ft + MSG_29731_003 = 0x00297313, //!< ft + MSG_29732_000 = 0x00297320, //!< Target Practice + MSG_29732_001 = 0x00297321, //!< Score: + MSG_29732_002 = 0x00297322, //!< pt + MSG_29732_003 = 0x00297323, //!< pts + MSG_29740_000 = 0x00297400, //!< Throwing Punches + MSG_29740_001 = 0x00297401, //!< Score: + MSG_29740_002 = 0x00297402, //!< pt + MSG_29740_003 = 0x00297403, //!< pts + MSG_29740_004 = 0x00297404, //!< Hit score: + MSG_29740_005 = 0x00297405, //!< pt + MSG_29740_006 = 0x00297406, //!< pts + MSG_29740_007 = 0x00297407, //!< Trainer penalty: + MSG_29740_008 = 0x00297408, //!< pt + MSG_29740_009 = 0x00297409, //!< pts + MSG_29741_000 = 0x00297410, //!< Dodging + MSG_29741_001 = 0x00297411, //!< Score: + MSG_29741_002 = 0x00297412, //!< pt + MSG_29741_003 = 0x00297413, //!< pts + MSG_29741_004 = 0x00297414, //!< Balls dodged: + MSG_29741_005 = 0x00297415, //!< pt + MSG_29741_006 = 0x00297416, //!< pts + MSG_29741_007 = 0x00297417, //!< Balls hit: + MSG_29741_008 = 0x00297418, //!< pt + MSG_29741_009 = 0x00297419, //!< pts + MSG_29742_000 = 0x00297420, //!< Working the Bag + MSG_29742_001 = 0x00297421, //!< Score: + MSG_29742_002 = 0x00297422, //!< pt + MSG_29742_003 = 0x00297423, //!< pts + MSG_29742_004 = 0x00297424, //!< + MSG_29742_005 = 0x00297425, //!< + MSG_29742_006 = 0x00297426, //!< + MSG_29742_007 = 0x00297427, //!< + MSG_29742_008 = 0x00297428, //!< + MSG_29742_009 = 0x00297429, //!< + MSG_29750_000 = 0x00297500, //!< Picking Up Spares + MSG_29750_001 = 0x00297501, //!< Cleared: + MSG_29750_002 = 0x00297502, //!< lane + MSG_29750_003 = 0x00297503, //!< lanes + MSG_29751_000 = 0x00297510, //!< Spin Control + MSG_29751_001 = 0x00297511, //!< Cleared: + MSG_29751_002 = 0x00297512, //!< lane + MSG_29751_003 = 0x00297513, //!< lanes + MSG_29752_000 = 0x00297520, //!< Power Throws + MSG_29752_001 = 0x00297521, //!< Score: + MSG_29752_002 = 0x00297522, //!< pin + MSG_29752_003 = 0x00297523, //!< pins + MSG_29800_000 = 0x00298000, //!< + MSG_29801_000 = 0x00298010, //!< 1 + MSG_29802_000 = 0x00298020, //!< 2 + MSG_29803_000 = 0x00298030, //!< 3 + MSG_29804_000 = 0x00298040, //!< 4 + MSG_29805_000 = 0x00298050, //!< {000001} + MSG_29810_000 = 0x00298100, //!< {000000} pt + MSG_29810_001 = 0x00298101, //!< {000000} pts + MSG_29811_000 = 0x00298110, //!< {000000} pt + MSG_29811_001 = 0x00298111, //!< {000000} pts + MSG_29812_000 = 0x00298120, //!< {000000} pt + MSG_29812_001 = 0x00298121, //!< {000000} pts + MSG_29820_000 = 0x00298200, //!< {000000} homer {FF0001 00 3C}({000000} ft) + MSG_29820_001 = 0x00298201, //!< {000000} homers {FF0001 00 3C}({000000} ft) + MSG_29820_002 = 0x00298202, //!< + MSG_29820_003 = 0x00298203, //!< + MSG_29821_000 = 0x00298210, //!< {000000} pt + MSG_29821_001 = 0x00298211, //!< {000000} pts + MSG_29822_000 = 0x00298220, //!< {000000} hit + MSG_29822_001 = 0x00298221, //!< {000000} hits + MSG_29830_000 = 0x00298300, //!< {000000} pt + MSG_29830_001 = 0x00298301, //!< {000000} pts + MSG_29831_000 = 0x00298310, //!< {000000} ft + MSG_29831_001 = 0x00298311, //!< {000000} ft + MSG_29832_000 = 0x00298320, //!< {000000} pt + MSG_29832_001 = 0x00298321, //!< {000000} pts + MSG_29840_000 = 0x00298400, //!< {000000} pt + MSG_29840_001 = 0x00298401, //!< {000000} pts + MSG_29841_000 = 0x00298410, //!< {000000} pt + MSG_29841_001 = 0x00298411, //!< {000000} pts + MSG_29842_000 = 0x00298420, //!< {000000} pt + MSG_29842_001 = 0x00298421, //!< {000000} pts + MSG_29850_000 = 0x00298500, //!< {000000} lane + MSG_29850_001 = 0x00298501, //!< {000000} lanes + MSG_29851_000 = 0x00298510, //!< {000000} lane + MSG_29851_001 = 0x00298511, //!< {000000} lanes + MSG_29852_000 = 0x00298520, //!< {000000} pin + MSG_29852_001 = 0x00298521, //!< {000000} pins + MSG_29860_000 = 0x00298600, //!< Returning Balls + MSG_29861_000 = 0x00298610, //!< Timing Your Swing + MSG_29862_000 = 0x00298620, //!< Target Practice + MSG_29863_000 = 0x00298630, //!< Hitting Home Runs + MSG_29864_000 = 0x00298640, //!< Batting Practice + MSG_29865_000 = 0x00298650, //!< Swing Control + MSG_29866_000 = 0x00298660, //!< Picking Up Spares + MSG_29867_000 = 0x00298670, //!< Spin Control + MSG_29868_000 = 0x00298680, //!< Power Throws + MSG_29869_000 = 0x00298690, //!< Putting + MSG_29870_000 = 0x00298700, //!< Hitting the Green + MSG_29871_000 = 0x00298710, //!< Target Practice + MSG_29872_000 = 0x00298720, //!< Throwing Punches + MSG_29873_000 = 0x00298730, //!< Dodging + MSG_29874_000 = 0x00298740, //!< Working the Bag + MSG_29880_000 = 0x00298800, //!< Again + MSG_29881_000 = 0x00298810, //!< Quit + MSG_29890_000 = 0x00298900, //!< Platinum + MSG_29891_000 = 0x00298910, //!< Gold + MSG_29892_000 = 0x00298920, //!< Silver + MSG_29893_000 = 0x00298930, //!< Bronze + MSG_29900_000 = 0x00299000, //!< Tennis + MSG_29901_000 = 0x00299010, //!< Baseball + MSG_29902_000 = 0x00299020, //!< Bowling + MSG_29903_000 = 0x00299030, //!< Golf + MSG_29904_000 = 0x00299040, //!< Boxing + MSG_29910_000 = 0x00299100, //!< Training + MSG_29911_000 = 0x00299110, //!< Wii Fitness + MSG_29920_000 = 0x00299200, //!< ㌃㌶㍑ + MSG_29930_000 = 0x00299300, //!< Please press \uE042 and \uE043. + MSG_29940_000 = 0x00299400, //!< Wii Sports + MSG_29941_000 = 0x00299410, //!< Play like a pro! + // clang-format on +}; + +#endif diff --git a/include/RVLFaceLib/RFL_Types.h b/include/RVLFaceLib/RFL_Types.h index 07e7ebde..0a666333 100644 --- a/include/RVLFaceLib/RFL_Types.h +++ b/include/RVLFaceLib/RFL_Types.h @@ -81,6 +81,16 @@ typedef enum { RFLExp_Max } RFLExpression; +typedef enum { + RFLExpFlag_Normal = 1 << RFLExp_Normal, + RFLExpFlag_Smile = 1 << RFLExp_Smile, + RFLExpFlag_Anger = 1 << RFLExp_Anger, + RFLExpFlag_Sorrow = 1 << RFLExp_Sorrow, + RFLExpFlag_Surprise = 1 << RFLExp_Surprise, + RFLExpFlag_Blink = 1 << RFLExp_Blink, + RFLExpFlag_OpenMouth = 1 << RFLExp_OpenMouth, +} RFLExpressionFlag; + typedef enum { RFLFavoriteColor_Red, RFLFavoriteColor_Orange, diff --git a/include/nw4r/g3d/g3d_scnrfl.h b/include/nw4r/g3d/g3d_scnrfl.h index 8208af0e..f4ccc29e 100644 --- a/include/nw4r/g3d/g3d_scnrfl.h +++ b/include/nw4r/g3d/g3d_scnrfl.h @@ -35,6 +35,10 @@ class ScnRfl : public ScnLeaf { bool SetExpression(RFLExpression expression); bool GetExpression(RFLExpression* pExpression); + u32 GetExpressionFlag() const { + return mExpressionFlag; + } + void SetLightSetIdx(int idx); s8 GetLightSetIdx() const { return mIdxLightSet; diff --git a/include/revolution/WPAD/WPAD.h b/include/revolution/WPAD/WPAD.h index b93a86c6..d5d18adf 100644 --- a/include/revolution/WPAD/WPAD.h +++ b/include/revolution/WPAD/WPAD.h @@ -18,6 +18,8 @@ extern "C" { #define WPAD_MAX_SPEAKER_VOLUME 127 +#define WPAD_ADDR_LEN WUD_ADDR_LEN + extern u8 _scFlush; typedef WUDAllocFunc WPADAllocFunc; diff --git a/include/revolution/WUD/WUD.h b/include/revolution/WUD/WUD.h index 8629ae46..e4c907fa 100644 --- a/include/revolution/WUD/WUD.h +++ b/include/revolution/WUD/WUD.h @@ -12,6 +12,7 @@ extern "C" { #define WUD_MAX_DEV_ENTRY_FOR_SMP SC_MAX_DEV_ENTRY_FOR_SMP #define WUD_MAX_DEV_ENTRY SC_MAX_DEV_ENTRY #define WUD_DEV_HANDLE_INVALID (-1) +#define WUD_ADDR_LEN BD_ADDR_LEN // Forward declarations typedef struct WUDDevInfo WUDDevInfo; diff --git a/src/Pack/RPGraphics/RPGrpModelRfl.cpp b/src/Pack/RPGraphics/RPGrpModelRfl.cpp index 573aa5e7..95905762 100644 --- a/src/Pack/RPGraphics/RPGrpModelRfl.cpp +++ b/src/Pack/RPGraphics/RPGrpModelRfl.cpp @@ -24,7 +24,7 @@ nw4r::math::MTX34 RPGrpModelRfl::lbl_804A4608( RPGrpModelRfl* RPGrpModelRfl::Construct(RFLDataSource src, u16 index, RFLMiddleDB* pMiddleDB, RFLResolution resolution, u32 exprFlags, - u8 viewNo) { + u8 viewNo, u32 /* arg6 */) { RPGrpModelRfl* p = new RPGrpModelRfl(resolution, exprFlags, viewNo); diff --git a/src/Pack/RPKernel/RPSysFile.cpp b/src/Pack/RPKernel/RPSysFile.cpp index 3e0484d5..1095f10d 100644 --- a/src/Pack/RPKernel/RPSysFile.cpp +++ b/src/Pack/RPKernel/RPSysFile.cpp @@ -14,7 +14,11 @@ RPSysFile::RPSysFile(const char* pPath, s32 size, const void* pData) : mSize(size) { // @bug Can easily overflow the fixed-size buffer +#if defined(BUG_FIX) + std::strncpy(mPath, pPath, ARRAY_SIZE(mPath)); +#else std::strcpy(mPath, pPath); +#endif mpData = static_cast(pData); } diff --git a/src/Pack/RPKernel/RPSysKokeshi.cpp b/src/Pack/RPKernel/RPSysKokeshi.cpp index fff7b0f4..4ec307c0 100644 --- a/src/Pack/RPKernel/RPSysKokeshi.cpp +++ b/src/Pack/RPKernel/RPSysKokeshi.cpp @@ -136,13 +136,13 @@ void RPSysKokeshi::LoadResource(const RPSysKokeshiOverloadInfo* pOverloadInfo) { } /** - * @brief Applies a generated light texture to this avatar + * @brief Applies all lightmap textures to this avatar * - * @param idx Lightmap texture index + * @param drawScene Draw scene index */ -void RPSysKokeshi::ApplyLightTexture(u8 /* idx */) { +void RPSysKokeshi::ApplyLightTexture(u8 drawScene) { RPGrpDrawPathLightMap* pLightMap = RPGrpModelManager::GetCurrent() - ->GetDrawPathManager() + ->GetDrawPathManager(drawScene) ->GetDrawPathLightMap(); for (u32 i = 0; i < RPSysKokeshiManager::LightMap_Max; i++) { @@ -238,7 +238,7 @@ void RPSysKokeshi::Construct() { } mpNigaoeModel = pKokeshiManager->CreateNigaoeModel( - location, mGenInfo.GetResolution(), mGenInfo.GetExpression(), + location, mGenInfo.GetResolution(), mGenInfo.GetExpressionFlag(), mGenInfo.GetViewNo()); RPSysAvatar::Setup(); diff --git a/src/Pack/RPKernel/RPSysKokeshiGenInfo.cpp b/src/Pack/RPKernel/RPSysKokeshiGenInfo.cpp index 4139f61e..1308f8db 100644 --- a/src/Pack/RPKernel/RPSysKokeshiGenInfo.cpp +++ b/src/Pack/RPKernel/RPSysKokeshiGenInfo.cpp @@ -9,14 +9,14 @@ RPSysKokeshiGenInfo::RPSysKokeshiGenInfo() { mGenType = RPSysKokeshiManager::GenType_None; mPlayerNo = 0; mBodyType = 0; - mHandType = 1; + mHandType = RPSysKokeshiManager::HandType_Sphere; mViewNo = 1; mModelFlags = 0; mBufferOption = 0; mTexWidth = 128; mTexHeight = 128; mResolution = RFLResolution_128; - mExpression = RFLExp_Smile; + mExprFlag = RFLExpFlag_Normal; mMipMap = false; mUseFavoriteColor = false; mClearColor.r = mClearColor.g = mClearColor.b = mClearColor.a = 0; diff --git a/src/Pack/RPKernel/RPSysKokeshiManager.cpp b/src/Pack/RPKernel/RPSysKokeshiManager.cpp new file mode 100644 index 00000000..dc6bc0a1 --- /dev/null +++ b/src/Pack/RPKernel/RPSysKokeshiManager.cpp @@ -0,0 +1,734 @@ +#include +#include +#include +#include +#include + +#include + +#include + +RP_SINGLETON_IMPL(RPSysKokeshiManager); + +/** + * @brief Default value for output alpha + */ +const u8 RPSysKokeshiManager::DEFAULT_OUTPUT_ALPHA = 128; + +/** + * @brief Clothing texture filenames + */ +const char* RPSysKokeshiManager::CLOTHING_TEXTURE_NAMES[ClothingTexture_Max] = { + "dummy_tex_a", + "dummy_tex_b", +}; + +/** + * @brief Lightmap texture names + */ +const char* RPSysKokeshiManager::LIGHT_TEXTURE_NAMES[LightMap_Max] = { + "lm_0", + "lm_1", +}; + +/** + * @brief Main material name + */ +const char* RPSysKokeshiManager::MAIN_MATERIAL_NAME = "mt_main"; + +/** + * @brief Face library resource filename + */ +const char* RPSysKokeshiManager::RFL_RES_NAME = "RFL_Res.dat"; + +/** + * @brief Common message filename + */ +const char* RPSysKokeshiManager::COMMON_MESSAGE_NAME = "common_message.bmg"; + +/** + * @brief Hand model filenames + */ +const char* RPSysKokeshiManager::HAND_FILE_NAMES[HandType_Max] = { + "G3D/ava_handA.brres", + "G3D/ava_handB.brres", +}; + +/** + * @brief Constructor + */ +RPSysKokeshiManager::RPSysKokeshiManager() + : IRPSysHostIOSocket("Kokeshi Manager") { + + mpNglBuffer = new (32) u8[RFLGetWorkSize(false)]; + mFriendRandomNum = RFL_DB_CHAR_MAX; + unk28 = unk2C = unk30 = 0.0f; + mOutputAlpha = DEFAULT_OUTPUT_ALPHA; + mLoadError = LoadError_Success; + + mBaseScale = 0.08f; + RPGrpModelRfl::SetBaseScale(mBaseScale); + + nw4r::math::MTX34 mtx; + nw4r::math::MTX34Identity(&mtx); + RPGrpModelRfl::SetMtx(mtx); + + mpOfficialDB = new RPSysOfficialDB(); + + for (int i = 0; i < WPAD_MAX_CONTROLLERS; i++) { + mppCtrlDataLoaders[i] = new RPSysKokeshiCtrlDataLoader(i); + } + + mpCtrlMgr = NULL; + mpBodyManager = NULL; + + RPSysHostIOSocketManager::AddHostIOSocket(this); +} + +/** + * @brief Destructor + */ +RPSysKokeshiManager::~RPSysKokeshiManager() {} + +/** + * @brief Creates all lightmap textures + * + * @param drawScene Draw scene index + */ +void RPSysKokeshiManager::CreateLightTexture(u8 drawScene) { + RPGrpDrawPathLightMap* pLightMap = RPGrpModelManager::GetCurrent() + ->GetDrawPathManager(drawScene) + ->GetDrawPathLightMap(); + + for (u8 i = 0; i < LightMap_Max; i++) { + pLightMap->GetLightTextureManager()->createTexture( + LIGHT_TEXTURE_NAMES[i]); + } +} + +/** + * @brief Applies the specified expression to the Mii model + * + * @param pModel Mii model + * @param expr New expression + */ +void RPSysKokeshiManager::ChangeExpression(RPGrpModel* pModel, + RFLExpression expr) { + if (pModel->GetKind() != RPGrpModel::Kind_RFL) { + return; + } + + nw4r::g3d::ScnRfl* pScnRfl = pModel->GetScnRfl(); + + if (pScnRfl->GetExpressionFlag() & (1 << expr)) { + pScnRfl->SetExpression(expr); + } +} + +/** + * @brief Gets the current expression of the Mii model + * + * @param pModel Mii model + */ +RFLExpression RPSysKokeshiManager::GetExpression(RPGrpModel* pModel) { + if (pModel->GetKind() != RPGrpModel::Kind_RFL) { + return RFLExp_Normal; + } + + nw4r::g3d::ScnRfl* pScnRfl = pModel->GetScnRfl(); + + RFLExpression expr; + pScnRfl->GetExpression(&expr); + return expr; +} + +/** + * @brief Gets the number of valid Miis in the official database + */ +u16 RPSysKokeshiManager::GetOfficialDBValidNum() { + return RP_GET_INSTANCE(RPSysKokeshiManager)->mpOfficialDB->GetValidNum(); +} + +/** + * @brief Finds the official database index holding the Mii with the + * specified create ID + * + * @param pCreateID Mii create ID + * @return Official database index, or -1 if not found + */ +s16 RPSysKokeshiManager::GetOfficialDBIndexFromCreateID( + const RFLCreateID* pCreateID) { + + return RP_GET_INSTANCE(RPSysKokeshiManager) + ->mpOfficialDB->GetIndexFromCreateID(pCreateID); +} + +/** + * @brief Resets the manager state + */ +void RPSysKokeshiManager::Reset() { + mpOfficialDB->Reset(); + mOutputAlpha = DEFAULT_OUTPUT_ALPHA; +} + +/** + * @brief Sets the material type of the Mii model + * + * @param pModel Mii model + * @param type New material type + */ +void RPSysKokeshiManager::SetMaterialType(RPGrpModel* pModel, + RPGrpModelRfl::MaterialType type) { + if (pModel->GetKind() != RPGrpModel::Kind_RFL) { + return; + } + + static_cast(pModel)->SetMaterialType(type); +} + +/** + * @brief Sets the brightness color of the Mii model + * + * @param pModel Mii model + * @param color New brightness color + */ +void RPSysKokeshiManager::SetBrightnessColor(RPGrpModel* pModel, + GXColor color) { + if (pModel->GetKind() != RPGrpModel::Kind_RFL) { + return; + } + + static_cast(pModel)->SetBrightnessColor(color); +} + +/** + * @brief Loads all static lifetime resources required by this manager + */ +void RPSysKokeshiManager::LoadStaticResource() { + RPSysSystem* pSystem = RP_GET_INSTANCE(RPSysSystem); + EGG::Heap* pResHeap = pSystem->getResourceHeap(); + + RPSysResourceManager* pResourceManager = + RP_GET_INSTANCE(RPSysResourceManager); + + pResourceManager->LoadKokeshiArchive(); + EGG::Archive* pKokeshiArchive = pResourceManager->GetKokeshiArchive(); + + u32 nglSize = 0; + void* pNglRes = RPSysResourceManager::GetFileFromArchive( + pKokeshiArchive, RFL_RES_NAME, &nglSize); + + pSystem->startLoadCount(); + + RFLErrcode err = RFLErrcode_NANDCommandfail; + s32 reason = NAND_RESULT_BUSY; + + while (err == RFLErrcode_NANDCommandfail && reason == NAND_RESULT_BUSY) { + err = RFLInitRes(mpNglBuffer, pNglRes, nglSize, false); + + if (err == RFLErrcode_NANDCommandfail) { + reason = RFLGetLastReason(); + } + + // Time out eventually + if (pSystem->isLoadCountEnd()) { + break; + } + } + + switch (err) { + case RFLErrcode_Success: { + mLoadError = LoadError_Success; + break; + } + + case RFLErrcode_NANDCommandfail: { + if (RFLGetLastReason() == NAND_RESULT_BUSY) { + mLoadError = LoadError_Busy; + } else { + mLoadError = LoadError_Fail; + } + break; + } + + case RFLErrcode_Loadfail: + case RFLErrcode_Fatal: { + mLoadError = LoadError_Fail; + break; + } + + case RFLErrcode_NotAvailable: + default: { + mLoadError = LoadError_Fail; + break; + } + } + + void* pCommonRes = + RPSysResourceManager::GetMessageResource(COMMON_MESSAGE_NAME); + + mpCommonMessage = new (pResHeap) RPSysMessage(pCommonRes, pResHeap); + + static const bmg_message GUEST_NAME_MSGS[RFL_DEFAULT_CHAR_MAX] = { + MSG_UNPACK(MSG_660_000), MSG_UNPACK(MSG_661_000), + MSG_UNPACK(MSG_662_000), MSG_UNPACK(MSG_663_000), + MSG_UNPACK(MSG_664_000), MSG_UNPACK(MSG_665_000), + }; + + for (u16 i = 0; i < RFL_DEFAULT_CHAR_MAX; i++) { + mpGuestNames[i] = mpCommonMessage->GetMsg(GUEST_NAME_MSGS[i].group, + GUEST_NAME_MSGS[i].index); + } +} + +/** + * @brief Creates a Kokeshi-related model + * + * @param pFile Resource file + * @param index Model index + * @param viewNo Renderer view ID + * @param typeOption Model type option + * @param bufferOption nw4r::g3d replacement buffer option + */ +RPGrpModel* RPSysKokeshiManager::CreateModel(void* pFile, u16 index, u8 viewNo, + u32 typeOption, u32 bufferOption) { + RPGrpModelResManager* pResManager = RPGrpModelResManager::GetCurrent(); + + s32 chan = -1; + bool ctrlFile = false; + + if (mpCtrlMgr != NULL) { + chan = GetCurrentCtrlHeap(); + + if (chan != -1 && pResManager->SearchData(pFile) == -1) { + ctrlFile = true; + } + } + + RPGrpHandle fileHandle = + pResManager->CreateData(RPGrpModelResManager::Type_ResFile, pFile); + + void* pMdlRes = pResManager->GetPtr(RPGrpModelResManager::Type_ResMdl, + fileHandle, index); + RPGrpHandle mdlHandle = + pResManager->CreateData(RPGrpModelResManager::Type_ResMdl, pMdlRes); + + RPGrpModel* pModel = RPGrpModel::Construct( + mdlHandle, viewNo, typeOption, + bufferOption | nw4r::g3d::ScnMdl::BUFFER_RESTEXOBJ | + nw4r::g3d::ScnMdl::BUFFER_RESGENMODE | + nw4r::g3d::ScnMdl::BUFFER_RESTEVCOLOR); + + if (mpCtrlMgr != NULL && chan != -1) { + if (ctrlFile) { + mpCtrlMgr->appendFile(chan, fileHandle); + mpCtrlMgr->appendFile(chan, mdlHandle); + } + + mpCtrlMgr->appendModel(chan, pModel); + } + + return pModel; +} + +/** + * @brief Creates a Kokeshi face model + * + * @param rLocation Mii location + * @param resolution Texture resolution + * @param exprFlag Facial expression flags + * @param viewNo Renderer view ID + */ +RPGrpModel* +RPSysKokeshiManager::CreateNigaoeModel(const RPSysKokeshiLocation& rLocation, + RFLResolution resolution, u32 exprFlags, + u8 viewNo) { + s32 chan = -1; + + if (mpCtrlMgr != NULL) { + chan = GetCurrentCtrlHeap(); + } + + RFLSetCoordinate(RFLCoordinateType_X, RFLCoordinateType_Y); + + u16 index = rLocation.GetIndex(); + RFLMiddleDB* pMiddleDB = NULL; + + if (rLocation.GetDataSource() == RFLDataSource_Middle) { + rLocation.GetMiddleDB()->GetRFLMiddleDB(index, &pMiddleDB, &index); + } + + RPGrpModelRfl* pNigaoeModel = RPGrpModelRfl::Construct( + rLocation.GetDataSource(), index, pMiddleDB, resolution, + exprFlags | RFLExpFlag_Normal, viewNo); + + if (mpCtrlMgr != NULL && chan != -1) { + mpCtrlMgr->appendModel(chan, pNigaoeModel); + } + + return pNigaoeModel; +} + +/** + * @brief Creates a Kokeshi-related texture + * + * @param pFile Resource file + * @param pName Texture name + */ +RPGrpTexture* RPSysKokeshiManager::CreateTexture(void* pFile, + const char* pName) { + RPGrpModelResManager* pResManager = RPGrpModelResManager::GetCurrent(); + + s32 chan = -1; + bool ctrlFile = false; + + if (mpCtrlMgr != NULL) { + chan = GetCurrentCtrlHeap(); + + if (chan != -1 && pResManager->SearchData(pFile) == -1) { + ctrlFile = true; + } + } + + RPGrpHandle fileHandle = + pResManager->CreateData(RPGrpModelResManager::Type_ResFile, pFile); + + void* pTexRes = pResManager->GetPtr(RPGrpModelResManager::Type_ResTex, + fileHandle, pName); + RPGrpHandle texHandle = + pResManager->CreateData(RPGrpModelResManager::Type_ResTex, pTexRes); + + RPGrpTexture* pTexture = new RPGrpTexture(fileHandle, pName); + + if (mpCtrlMgr != NULL && chan != -1) { + if (ctrlFile) { + mpCtrlMgr->appendFile(chan, fileHandle); + mpCtrlMgr->appendFile(chan, texHandle); + } + } + + return pTexture; +} + +/** + * @brief Creates a Kokeshi-related texture + * + * @param pTexData Texture data + */ +RPGrpTexture* RPSysKokeshiManager::CreateTexture(void* pTexData) { + // TODO(kiwi) I think ResTIMG and GXTexObj have the same layout, but this + // cast still isn't safe because RPGrpTexture has a vtable! + return static_cast(pTexData); +} + +/** + * @brief Changes the clothing textures of the specified Mii model + * + * @param pModel Mii model + * @param pTextureA Clothing texture A + * @param pTextureB Clothing texture B + */ +void RPSysKokeshiManager::ChangeTexture(RPGrpModel* pModel, + RPGrpTexture* pTextureA, + RPGrpTexture* pTextureB) { + pModel->ReplaceTexture(CLOTHING_TEXTURE_NAMES[ClothingTexture_A], + *pTextureA, true); + + pModel->ReplaceTexture(CLOTHING_TEXTURE_NAMES[ClothingTexture_B], + *pTextureB, true); +} + +/** + * @brief Sets the material colors of the specified Mii model + * + * @param pModel Mii model + * @param body Body color + * @param skin Skin color + */ +void RPSysKokeshiManager::SetMatColor(RPGrpModel* pModel, GXColor body, + GXColor skin) { + RPGrpModelMaterial* pMaterial = pModel->GetMaterial(MAIN_MATERIAL_NAME); + + static const RPGrpModelMaterial::ETevColor TEV_REGS[] = { + RPGrpModelMaterial::ETevColor_Reg0, // body color + RPGrpModelMaterial::ETevColor_Reg1 // skin color + }; + + pMaterial->SetTevColor(TEV_REGS[0], body); + pMaterial->SetTevColor(TEV_REGS[1], skin); + + pMaterial->SetSyncFlags(RPGrpModelMaterial::ESyncFlag_ResMatTev); +} + +/** + * @brief Configures the TEV color effect of the specified Mii model + * + * @param pModel Mii model + * @param alpha Effect alpha + * @param r Red component + * @param g Green component + * @param b Blue component + */ +void RPSysKokeshiManager::SetMatTevColorEffect(RPGrpModel* pModel, u8 alpha, + u8 r, u8 g, u8 b) { + RPGrpModelMaterial* pMaterial = pModel->GetMaterial(MAIN_MATERIAL_NAME); + + pMaterial->SetTevColorAlpha(RPGrpModelMaterial::ETevColor_Reg2, alpha); + pMaterial->SetTevKColor(RPGrpModelMaterial::ETevKColor_Reg0, r, g, b); + + pMaterial->SetSyncFlags(RPGrpModelMaterial::ESyncFlag_ResMatTev); +} + +/** + * @brief Gets the additional info about the specified Mii + * + * @param rLocation Mii location + * @param[out] pInfo Additional info + */ +void RPSysKokeshiManager::GetAdditionalInfo( + const RPSysKokeshiLocation& rLocation, RFLAdditionalInfo* pInfo) { + + u16 index = rLocation.GetIndex(); + RFLMiddleDB* pMiddleDB = NULL; + + if (rLocation.GetDataSource() == RFLDataSource_Middle) { + rLocation.GetMiddleDB()->GetRFLMiddleDB(rLocation.GetIndex(), + &pMiddleDB, &index); + } + + RFLGetAdditionalInfo(pInfo, rLocation.GetDataSource(), pMiddleDB, index); +} + +/** + * @brief Removes the model's scaling from the transformation matrix + * + * @param[out] pOut Transformation matrix with scaling removed + * @param pModel Model whose scale should be used + * @param pIn Initial transformation matrix + */ +void RPSysKokeshiManager::GetModelBaseScaleInvalidatedMtx( + nw4r::math::MTX34* pOut, RPGrpModel* pModel, const nw4r::math::MTX34* pIn) { + + nw4r::math::VEC3 scale = pModel->GetScale(); + nw4r::math::VEC3 scaleInv(1.0f / scale.x, 1.0f / scale.y, 1.0f / scale.z); + + nw4r::math::MTX34Copy(pOut, pIn); + + pOut->_00 *= scaleInv.x; + pOut->_01 *= scaleInv.y; + pOut->_02 *= scaleInv.z; + + pOut->_10 *= scaleInv.x; + pOut->_11 *= scaleInv.y; + pOut->_12 *= scaleInv.z; + + pOut->_20 *= scaleInv.x; + pOut->_21 *= scaleInv.y; + pOut->_22 *= scaleInv.z; +} + +/** + * @brief Gets the archive filename for the specified hand type + * + * @param type Hand model type + */ +const char* RPSysKokeshiManager::GetHandFileName(u32 type) { + return HAND_FILE_NAMES[type]; +} + +/** + * @brief Gets the Mii location for the specified player slot + * @details If the specified index is invalid, this function provides a + * random guest Mii location. + * + * @param idx Player index + * @param[out] pLocation Mii location + */ +void RPSysKokeshiManager::GetLocationPlayer(u8 idx, + RPSysKokeshiLocation* pLocation) { + if (RP_GET_INSTANCE(RPSysPlayerMgr)->getPlayerNum() > idx) { + const RPSysPlayer& rPlayer = + RP_GET_INSTANCE(RPSysPlayerMgr)->getPlayer(idx); + + RFLDataSource src = static_cast(rPlayer.getDataSource()); + + pLocation->SetDataSource(src); + pLocation->SetIndex(rPlayer.getIndex()); + pLocation->SetMiddleDB(NULL); + } else { + // Pick a random guest Mii + u16 index = RPUtlRandom::getU32(RFL_DEFAULT_CHAR_MAX); + + pLocation->SetDataSource(RFLDataSource_Default); + pLocation->SetIndex(index); + pLocation->SetMiddleDB(NULL); + } +} + +/** + * @brief Gets the Mii location of a "friend" Mii + * + * @param src Mii data source + * @param pMiddleDB Middle database (for RFLDataSource_Middle) + * @param[out] pLocation Mii location + */ +void RPSysKokeshiManager::GetLocationFriend(RFLDataSource src, + RPSysMiddleDB* pMiddleDB, + RPSysKokeshiLocation* pLocation) { + switch (src) { + case RFLDataSource_Official: { + u16 index = 0; + bool valid = false; + + // Try picking a random Mii from the official database + for (u16 i = 0; i < mFriendRandomNum; i++) { + index = RPUtlRandom::getU32(RFL_DB_CHAR_MAX); + + if (mpOfficialDB->GetState(index) == OfficialDBState_Valid) { + valid = true; + pLocation->SetDataSource(RFLDataSource_Official); + break; + } + } + + // Linear search for the first valid Mii + if (!valid) { + for (u16 i = 0; i < RFL_DB_CHAR_MAX; i++) { + index = i; + + if (mpOfficialDB->GetState(i) == OfficialDBState_Valid) { + valid = true; + pLocation->SetDataSource(RFLDataSource_Official); + break; + } + } + } + + // No valid official Miis, select a random guest + if (!valid) { + index = RPUtlRandom::getU32(RFL_DEFAULT_CHAR_MAX); + pLocation->SetDataSource(RFLDataSource_Default); + } + + pLocation->SetIndex(index); + pLocation->SetMiddleDB(NULL); + + break; + } + + case RFLDataSource_Middle: { + pLocation->SetMiddleDB(pMiddleDB); + pLocation->SetDataSource(RFLDataSource_Middle); + + u16 index = 0; + bool valid = false; + RPSysKokeshiLocation player; + + // Find the next non-player Mii from the middle database + while (!valid) { + pLocation->SetIndex(pMiddleDB->GetCurrentIndex()); + valid = true; + + if (pMiddleDB->GetStoredNum() > pMiddleDB->GetCurrentIndex()) { + RFLAdditionalInfo middleInfo; + GetAdditionalInfo(*pLocation, &middleInfo); + + // Make sure this Mii was not chosen by any player + for (u32 i = 0; i < WPAD_MAX_CONTROLLERS; i++) { + GetLocationPlayer(i, &player); + + RFLAdditionalInfo playerInfo; + GetAdditionalInfo(player, &playerInfo); + + bool isPlayer = true; + + for (u32 i = 0; i < RFL_CREATEID_LEN; i++) { + if (playerInfo.createID.data[i] != + middleInfo.createID.data[i]) { + + isPlayer = false; + break; + } + } + + if (isPlayer) { + valid = false; + break; + } + } + } + + pMiddleDB->IncrementCurrentIndex(); + + if (valid || ++index >= WPAD_MAX_CONTROLLERS) { + break; + } + } + + break; + } + + default: { + break; + } + } +} + +/** + * @brief Registers the specified Mii location with the in-memory official + * database + * + * @param rLocation Mii location + */ +void RPSysKokeshiManager::RegistLocation( + const RPSysKokeshiLocation& rLocation) { + + if (rLocation.GetDataSource() != RFLDataSource_Official) { + return; + } + + mpOfficialDB->SetState(rLocation.GetIndex(), OfficialDBState_Registered); +} + +/** + * @brief Sets the active controller manager + * + * @param pCtrlMgr Controller manager + */ +void RPSysKokeshiManager::SetCtrlMgr(RPSysKokeshiCtrlMgr* pCtrlMgr) { + mpCtrlMgr = pCtrlMgr; +} + +/** + * @brief Clears the active controller manager + */ +void RPSysKokeshiManager::ClearCtrlMgr() { + mpCtrlMgr = NULL; +} + +/** + * @brief Updates the active controller manager's state + */ +void RPSysKokeshiManager::UpdateCtrlMgr() { + if (mpCtrlMgr != NULL) { + mpCtrlMgr->calc(); + } +} + +/** + * @brief Gets the index of the controller resource heap that is the current + * global heap + * + * @return Controller channel, or -1 if not applicable + */ +s32 RPSysKokeshiManager::GetCurrentCtrlHeap() const { + EGG::Heap* pCurrentHeap = EGG::Heap::getCurrentHeap(); + + for (int i = 0; i < WPAD_MAX_CONTROLLERS; i++) { + if (mpCtrlMgr->getResourceHeap(i) == pCurrentHeap) { + return i; + } + } + + return -1; +} diff --git a/src/Pack/RPKernel/RPSysStringUtility.cpp b/src/Pack/RPKernel/RPSysStringUtility.cpp index 5ee38213..f7324d77 100644 --- a/src/Pack/RPKernel/RPSysStringUtility.cpp +++ b/src/Pack/RPKernel/RPSysStringUtility.cpp @@ -392,7 +392,11 @@ void RPSysStringUtility::ChangePointHalfFull(wchar_t* pStr) { case L',': { // @bug Should be a full-width character +#if defined(BUG_FIX) + pStr[i] = L','; /* full-width comma */ +#else pStr[i] = L','; +#endif break; } diff --git a/src/Pack/RPSystem/RPPartyPlayerData.cpp b/src/Pack/RPSystem/RPPartyPlayerData.cpp new file mode 100644 index 00000000..95c9946d --- /dev/null +++ b/src/Pack/RPSystem/RPPartyPlayerData.cpp @@ -0,0 +1,85 @@ +#include + +/** + * @brief Constructor + */ +RPPartyPlayerData::RPPartyPlayerData() { + reset(); +} + +/** + * @brief Resets the data to a default save state + */ +void RPPartyPlayerData::reset() { + mPlayerFlags.makeAllZero(); + + for (int i = 0; i < RFL_CREATEID_LEN; i++) { + mCreateID.data[i] = 0; + } + + mDebutTime = 0; + + for (int i = 0; i < EGame_Max; i++) { + for (int j = 0; j < MY_RECORDS_LENGTH; j++) { + mMyRecords[i][j] = 0; + } + + mMedals[i] = EMedal_None; + } + + mMedalDemoFlags.makeAllZero(); +} + +/** + * @brief Tests whether this player has been registered with the player list + */ +bool RPPartyPlayerData::isRegistered() const { + return mPlayerFlags.onBit(EFlag_Registered); +} + +/** + * @brief Sets whether this player has been registered with the player list + * + * @param registered Registration status + */ +void RPPartyPlayerData::setRegistered(bool registered) { + mPlayerFlags.changeBit(EFlag_Registered, registered); +} + +/** + * @brief Gets this player's Mii create ID + * + * @param[out] pCreateID Mii create ID + */ +void RPPartyPlayerData::getCreateID(RFLCreateID* pCreateID) const { + for (int i = 0; i < RFL_CREATEID_LEN; i++) { + pCreateID->data[i] = mCreateID.data[i]; + } +} + +/** + * @brief Set this player's Mii create ID + * + * @param pCreateID Mii create ID + */ +void RPPartyPlayerData::setCreateID(const RFLCreateID* pCreateID) { + for (int i = 0; i < RFL_CREATEID_LEN; i++) { + mCreateID.data[i] = pCreateID->data[i]; + } +} + +/** + * @brief Gets the time this player was registered with the player list + */ +RPTime32 RPPartyPlayerData::getDebutTime() const { + return mDebutTime; +} + +/** + * @brief Sets the time this player was registered with the player list + * + * @param time Debut time + */ +void RPPartyPlayerData::setDebutTime(RPTime32 time) { + mDebutTime = time; +} diff --git a/src/Pack/RPSystem/RPPartySystemData.cpp b/src/Pack/RPSystem/RPPartySystemData.cpp new file mode 100644 index 00000000..fe3113cf --- /dev/null +++ b/src/Pack/RPSystem/RPPartySystemData.cpp @@ -0,0 +1,10 @@ +#include + +/** + * @brief Tests whether the specified minigame is available + * + * @param idx Minigame index + */ +bool RPPartySystemData::isGameOpen(s32 idx) const { + return mGameFlags.onBit(idx); +} diff --git a/src/Pack/RPSystem/RPSportsPlayerData.cpp b/src/Pack/RPSystem/RPSportsPlayerData.cpp new file mode 100644 index 00000000..3d451654 --- /dev/null +++ b/src/Pack/RPSystem/RPSportsPlayerData.cpp @@ -0,0 +1,990 @@ +#include + +/** + * @brief Constructor + */ +RPSportsPlayerData::RPSportsPlayerData() { + reset(); +} + +/** + * @brief Resets the data to a default save state + */ +void RPSportsPlayerData::reset() { + mPlayerFlags.makeAllZero(); + + for (int i = 0; i < RFL_CREATEID_LEN; i++) { + mCreateID.data[i] = 0; + } + + mDebutTime = 0; + mHandFlags.makeAllZero(); + + for (int i = 0; i < ESport_Max; i++) { + mSkillLevels[i] = 0.0f; + + for (int j = 0; j < SKILL_HISTORY_LENGTH; j++) { + mSkillGraphDelta[i][j] = 0; + } + + mStandardFirstDates[i] = 0; + + for (int j = 0; j < EGame_Max; j++) { + mTrainingFirstDates[i][j] = 0; + } + + mPlayCounts[i] = 0; + + for (int j = 0; j < EGame_Max; j++) { + mTrainingPlayCounts[i][j] = 0; + mTrainingMedals[i][j] = EMedal_None; + } + } + + unk272 = 0; + mTnsDifficulty = 0.1f; + mTnsSuccess = 0.1f; + for (int i = 0; i < EGame_Max; i++) { + mTnsTrainingBests[i] = 0; + } + + mBsbHomerunRunsBest = 0; + mBsbHomerunDistBest = 0; + mBsbUchiwakeBest = 0; + mBsbRenzokuBest = 0; + + unk284 = 0; + mBowStandardBest = 0; + mBowPerfectCount = 0; + for (int i = 0; i < EGame_Max; i++) { + mBowTrainingBests[i] = 0; + } + + for (int i = 0; i < ECourse_Max; i++) { + mGolStandardBests[i] = +99; + } + mGolAceCount = 0; + mGolTrainingBests[EGame_1st] = 0; + mGolTrainingBests[EGame_3rd] = 0; + // Hitting the Green - 300.0 meters + mGolTrainingBests[EGame_2nd] = 30000; + + for (int i = 0; i < EGame_Max; i++) { + mBoxTrainingBests[i] = 0; + } + + mPhysicalEndFirstDate = 0; + mPhysicalEndCount = 0; + for (int i = 0; i < EStat_Max; i++) { + mPhysicalLastStats[i] = 0; + mPhysicalLastEvents[i] = 0; + } + for (int i = 0; i < ESport_Max; i++) { + for (int j = 0; j < EGame_Max; j++) { + mPhysicalStatSumBests[i][j] = 0; + } + } + mPhysicalEndLastDate = 0; + for (int i = 0; i < PHYSICAL_HISTORY_LENGTH; i++) { + mPhysicalStatSumHistory[i] = 0xFFFF; + mPhysicalDateHistory[i] = 0; + } + mPhysicalBeginLastDate = 0; + for (int i = 0; i < static_cast(ARRAY_SIZE(unk43E)); i++) { + unk43E[i] = 0; + } +} + +/** + * @brief Gets the hand type used for the specified sport's primary control + * + * @param sport Sport ID + */ +RPSportsPlayerData::EHand +RPSportsPlayerData::getHandPrimary(ESport sport) const { + return mHandFlags.onBit(sport) ? EHand_Left : EHand_Right; +} + +/** + * @brief Gets the hand type used for the specified sport's secondary + * control + * + * @param sport Sport ID + */ +RPSportsPlayerData::EHand +RPSportsPlayerData::getHandSecondary(ESport sport) const { + // First set of bits are for the primary control + return mHandFlags.onBit(ESport_Max + sport) ? EHand_Left : EHand_Right; +} + +/** + * @brief Sets the hand type used for the specified sport's primary control + * + * @param hand Hand type + * @param sport Sport ID + */ +void RPSportsPlayerData::setHandPrimary(EHand hand, ESport sport) { + if (hand != EHand_Right) { + mHandFlags.setBit(sport); + } else { + mHandFlags.resetBit(sport); + } +} + +/** + * @brief Sets the hand type used for the specified sport's secondary + * control + * + * @param hand Hand type + * @param sport Sport ID + */ +void RPSportsPlayerData::setHandSecondary(EHand hand, ESport sport) { + // First set of bits are for the primary control + if (hand != EHand_Right) { + mHandFlags.setBit(ESport_Max + sport); + } else { + mHandFlags.resetBit(ESport_Max + sport); + } +} + +/** + * @brief Gets the skill level in the specified sport + * + * @param sport Sport ID + */ +f32 RPSportsPlayerData::getSkillLevel(ESport sport) const { + return mSkillLevels[sport]; +} + +/** + * @brief Sets the skill level in the specified sport + * + * @param sport Sport ID + * @param skill Skill level + */ +void RPSportsPlayerData::setSkillLevel(ESport sport, f32 skill) { + mSkillLevels[sport] = skill; +} + +/** + * @brief Gets a point from the specified sport's skill graph + * + * @param sport Sport ID + * @param idx Graph point index + */ +s16 RPSportsPlayerData::getSkillGraphPoint(ESport sport, u32 idx) const { + return mSkillGraphDelta[sport][idx]; +} + +/** + * @brief Sets a point in the specified sport's skill graph + * + * @param value Point value (delta) + * @param sport Sport ID + * @param idx Graph point index + */ +void RPSportsPlayerData::setSkillGraphPoint(s16 value, ESport sport, u32 idx) { + mSkillGraphDelta[sport][idx] = value; +} + +/** + * @brief Gets the first date when the standard mode of the specified sport + * was played + * + * @param sport Sport ID + */ +RPTime16 RPSportsPlayerData::getStandardFirstDate(ESport sport) const { + return mStandardFirstDates[sport]; +} + +/** + * @brief Sets the first date when the standard mode of the specified sport + * was played + * + * @param date First play date + * @param sport Sport ID + */ +void RPSportsPlayerData::setStandardFirstDate(RPTime16 date, ESport sport) { + mStandardFirstDates[sport] = date; +} + +/** + * @brief Gets the first date when the specified training game was played + * + * @param sport Sport ID + * @param game Training game ID + */ +RPTime16 RPSportsPlayerData::getTrainingFirstDate(ESport sport, + EGame game) const { + return mTrainingFirstDates[sport][game]; +} + +/** + * @brief Sets the first date when the specified training game was played + * + * @param date First play date + * @param sport Sport ID + * @param game Training game ID + */ +void RPSportsPlayerData::setTrainingFirstDate(RPTime16 date, ESport sport, + EGame game) { + mTrainingFirstDates[sport][game] = date; +} + +/** + * @brief Gets the play count for the standard mode of the specified sport + * + * @param sport Sport ID + */ +u16 RPSportsPlayerData::getStandardPlayCount(ESport sport) const { + return mPlayCounts[sport]; +} + +/** + * @brief Sets the play count for the standard mode of the specified sport + * + * @param count Play count + * @param sport Sport ID + */ +void RPSportsPlayerData::setStandardPlayCount(u16 count, ESport sport) { + mPlayCounts[sport] = count; +} + +/** + * @brief Gets the play count for the specified training game + * + * @param sport Sport ID + * @param game Training game + */ +u16 RPSportsPlayerData::getTrainingPlayCount(ESport sport, EGame game) const { + return mTrainingPlayCounts[sport][game]; +} + +/** + * @brief Sets the play count for the specified training game + * + * @param count Play count + * @param sport Sport ID + * @param game Training game + */ +void RPSportsPlayerData::setTrainingPlayCount(u16 count, ESport sport, + EGame game) { + mTrainingPlayCounts[sport][game] = count; +} + +/** + * @brief Gets the medal type earned in the specified training game + * + * @param sport Sport ID + * @param game Training game ID + */ +u8 RPSportsPlayerData::getTrainingMedal(ESport sport, EGame game) const { + return mTrainingMedals[sport][game]; +} + +/** + * @brief Sets the medal type earned in the specified training game + * + * @param medal Medal type + * @param sport Sport ID + * @param game Training game ID + */ +void RPSportsPlayerData::setTrainingMedal(u8 medal, ESport sport, EGame game) { + mTrainingMedals[sport][game] = medal; +} + +/** + * @brief Tests whether this player has completed a round of any sport + */ +bool RPSportsPlayerData::isFirstPlay() const { + return mPlayerFlags.onBit(EFlag_FirstPlay); +} +/** + * @brief Marks that this player has completed a round of any sport + */ +void RPSportsPlayerData::setFirstPlay() { + mPlayerFlags.setBit(EFlag_FirstPlay); +} + +/** + * @brief Tests whether this player has defeated the specified sport's + * champion + * + * @param sport Sport ID + */ +bool RPSportsPlayerData::isDefeatChampion(ESport sport) const { + return mPlayerFlags.onBit(EFlag_Champion + sport); +} + +/** + * @brief Marks that this player has defeated the specified sport's champion + * + * @param sport Sport ID + */ +void RPSportsPlayerData::setDefeatChampion(ESport sport) { + mPlayerFlags.setBit(EFlag_Champion + sport); +} + +/** + * @brief Gets the difficulty of the Tennis CPU players + */ +f32 RPSportsPlayerData::getTnsDifficulty() const { + return mTnsDifficulty; +} + +/** + * @brief Sets the difficulty of the Tennis CPU players + * + * @param difficulty New CPU difficulty + */ +void RPSportsPlayerData::setTnsDifficulty(f32 difficulty) { + mTnsDifficulty = difficulty; +} + +/** + * @brief Gets the Tennis player success factor + */ +f32 RPSportsPlayerData::getTnsSuccess() const { + return mTnsSuccess; +} + +/** + * @brief Sets the Tennis player success factor + * + * @param success New player success factor + */ +void RPSportsPlayerData::setTnsSuccess(f32 success) { + mTnsSuccess = success; +} + +/** + * @brief Gets the best score in the specified Tennis training game + * + * @param game Training game ID + */ +u8 RPSportsPlayerData::getTnsTrainingBest(EGame game) const { + return mTnsTrainingBests[game]; +} + +/** + * @brief Sets the best score in the specified Tennis training game + * + * @param score Best score + * @param game Training game ID + */ +void RPSportsPlayerData::setTnsTrainingBest(u8 score, EGame game) { + // @bug This can somewhat easily overflow with a high score. + // It will reflect on the UI, but not save correctly. + mTnsTrainingBests[game] = score; +} + +/** + * @brief Gets the best home run count record in Hitting Home Runs + */ +u8 RPSportsPlayerData::getBsbHomerunRunsBest() const { + return mBsbHomerunRunsBest; +} + +/** + * @brief Sets the best home run count record in Hitting Home Runs + * + * @param runs Best home run count + */ +void RPSportsPlayerData::setBsbHomerunRunsBest(u8 runs) { + mBsbHomerunRunsBest = runs; +} + +/** + * @brief Gets the best total distance record in Hitting Home Runs + */ +u16 RPSportsPlayerData::getBsbHomerunDistBest() const { + return mBsbHomerunDistBest; +} + +/** + * @brief Sets the best total distance record in Hitting Home Runs + * + * @param dist Best total distance + */ +void RPSportsPlayerData::setBsbHomerunDistBest(u16 dist) { + mBsbHomerunDistBest = dist; +} + +/** + * @brief Gets the best score in Swing Control + */ +u8 RPSportsPlayerData::getBsbUchiwakeBest() const { + return mBsbUchiwakeBest; +} + +/** + * @brief Sets the best score in Swing Control + * + * @param score Best score + */ +void RPSportsPlayerData::setBsbUchiwakeBest(u8 score) { + mBsbUchiwakeBest = score; +} + +/** + * @brief Gets the best score in Batting Practice + */ +u8 RPSportsPlayerData::getBsbRenzokuBest() const { + return mBsbRenzokuBest; +} + +/** + * @brief Sets the best score in Batting Practice + * + * @param score Best score + */ +void RPSportsPlayerData::setBsbRenzokuBest(u8 score) { + mBsbRenzokuBest = score; +} + +/** + * @brief Gets the best score in Bowling + */ +u16 RPSportsPlayerData::getBowStandardBest() const { + return mBowStandardBest; +} + +/** + * @brief Sets the best score in Bowling + * + * @param score Best score + */ +void RPSportsPlayerData::setBowStandardBest(u16 score) { + mBowStandardBest = score; +} + +/** + * @brief Gets the number of perfect games bowled + */ +u8 RPSportsPlayerData::getBowPerfectCount() const { + return mBowPerfectCount; +} + +/** + * @brief Sets the number of perfect games bowled + * + * @param count Perfect game count + */ +void RPSportsPlayerData::setBowPerfectCount(u8 count) { + mBowPerfectCount = count; +} + +/** + * @brief Gets the best score in the specified Bowling training game + * + * @param game Training game ID + */ +u16 RPSportsPlayerData::getBowTrainingBest(EGame game) const { + return mBowTrainingBests[game]; +} + +/** + * @brief Sets the best score in the specified Bowling training game + * + * @param score Best score + * @param game Training game ID + */ +void RPSportsPlayerData::setBowTrainingBest(u16 score, EGame game) { + mBowTrainingBests[game] = score; +} + +/** + * @brief Gets the best Golf score on the specified course + * + * @param course Golf course ID + */ +s8 RPSportsPlayerData::getGolStandardBest(ECourse course) const { + return mGolStandardBests[course]; +} + +/** + * @brief Sets the best Golf score on the specified course + * + * @param score Best score + * @param course Golf course ID + */ +void RPSportsPlayerData::setGolStandardBest(s8 score, ECourse course) { + mGolStandardBests[course] = score; +} + +/** + * @brief Gets the amount of hole-in-ones hit + */ +u8 RPSportsPlayerData::getGolAceCount() const { + return mGolAceCount; +} + +/** + * @brief Sets the amount of hole-in-ones hit + * + * @param count Hole-in-one count + */ +void RPSportsPlayerData::setGolAceCount(u8 count) { + mGolAceCount = count; +} + +/** + * @brief Gets the best score in the specified Golf training game + * + * @param game Training game ID + */ +u16 RPSportsPlayerData::getGolTrainingBest(EGame game) const { + return mGolTrainingBests[game]; +} + +/** + * @brief Set the best score in the specified Golf training game + * + * @param score Best score + * @param game Training game ID + */ +void RPSportsPlayerData::setGolTrainingBest(u16 score, EGame game) { + mGolTrainingBests[game] = score; +} + +/** + * @brief Gets the best score in the specified Boxing training game + * + * @param game Training game ID + */ +u16 RPSportsPlayerData::getBoxTrainingBest(EGame game) const { + return mBoxTrainingBests[game]; +} + +/** + * @brief Set the best score in the specified Boxing training game + * + * @param score Best score + * @param game Training game ID + */ +void RPSportsPlayerData::setBoxTrainingBest(u16 score, EGame game) { + mBoxTrainingBests[game] = score; +} + +/** + * @brief Gets the date of the first completed fitness test + */ +RPTime16 RPSportsPlayerData::getPhysicalEndFirstDate() const { + return mPhysicalEndFirstDate; +} + +/** + * @brief Sets the date of the first completed fitness test + * + * @param date Date of first test completion + */ +void RPSportsPlayerData::setPhysicalEndFirstDate(RPTime16 date) { + mPhysicalEndFirstDate = date; +} + +/** + * @brief Gets the number of completed fitness tests + */ +u16 RPSportsPlayerData::getPhysicalEndCount() const { + return mPhysicalEndCount; +} + +/** + * @brief Sets the number of completed fitness tests + * + * @param count Number of completed fitness tests + */ +void RPSportsPlayerData::setPhysicalEndCount(u16 count) { + mPhysicalEndCount = count; +} + +/** + * @brief Gets the most recent value of the specified fitness test stat + * + * @param stat Fitness test stat ID + */ +u16 RPSportsPlayerData::getPhysicalStat(EStat stat) const { + return mPhysicalLastStats[stat]; +} + +/** + * @brief Sets the most recent value of the specified fitness test stat + * + * @param value Stat value + * @param stat Fitness test stat ID + */ +void RPSportsPlayerData::setPhysicalStat(u16 value, EStat stat) { + mPhysicalLastStats[stat] = value; +} + +/** + * @brief Gets the specified event from the most recent fitness test + * + * @param idx Event index + * @return Packed event ID + */ +u8 RPSportsPlayerData::getPhysicalEvent(u32 idx) const { + return mPhysicalLastEvents[idx]; +} + +/** + * @brief Sets the specified event of the most recent fitness test + * + * @param event Packed event index + * @param idx Event index + */ +void RPSportsPlayerData::setPhysicalEvent(u8 event, u32 idx) { + mPhysicalLastEvents[idx] = event; +} + +/** + * @brief Gets the fitness stat sum record in the specified training game + * + * @param sport Sport ID + * @param game Training game ID + */ +u16 RPSportsPlayerData::getPhysicalStatSumBest(ESport sport, EGame game) const { + return mPhysicalStatSumBests[sport][game]; +} + +/** + * @brief Sets the fitness stat sum record in the specified training game + * + * @param sum Fitness stat sum + * @param sport Sport ID + * @param game Training game ID + */ +void RPSportsPlayerData::setPhysicalStatSumBest(u16 sum, ESport sport, + EGame game) { + mPhysicalStatSumBests[sport][game] = sum; +} + +/** + * @brief Gets the date of the most recently completed fitness test + */ +RPTime16 RPSportsPlayerData::getPhysicalEndLastDate() const { + return mPhysicalEndLastDate; +} + +/** + * @brief Sets the date of the most recently completed fitness test + * + * @param date Date of last test completion + */ +void RPSportsPlayerData::setPhysicalEndLastDate(RPTime16 date) { + mPhysicalEndLastDate = date; +} + +/** + * @brief Gets the specified fitness stat sum from the test history + * + * @param idx Fitness test history index + */ +u16 RPSportsPlayerData::getPhysicalStatSumHistory(u32 idx) const { + return mPhysicalStatSumHistory[idx]; +} + +/** + * @brief Sets the specified fitness stat sum in the test history + * + * @param sum Fitness stat sum + * @param idx Fitness test history index + */ +void RPSportsPlayerData::setPhysicalStatSumHistory(u16 sum, u32 idx) { + mPhysicalStatSumHistory[idx] = sum; +} + +/** + * @brief Gets the specified fitness test completion date from the test + * history + * + * @param idx Fitness test history index + */ +RPTime16 RPSportsPlayerData::getPhysicalDateHistory(u32 idx) const { + return mPhysicalDateHistory[idx]; +} + +/** + * @brief Sets the specified fitness test completion date in the test + * history + * + * @param date Date of test completion + * @param idx Fitness test history index + */ +void RPSportsPlayerData::setPhysicalDateHistory(RPTime16 date, u32 idx) { + mPhysicalDateHistory[idx] = date; +} + +/** + * @brief Gets the date of the most recently started fitness test + */ +RPTime16 RPSportsPlayerData::getPhysicalBeginLastDate() const { + return mPhysicalBeginLastDate; +} + +/** + * @brief Sets the date of the most recently started fitness test + * + * @param date Start date of the last test + */ +void RPSportsPlayerData::setPhysicalBeginLastDate(RPTime16 date) { + mPhysicalBeginLastDate = date; +} + +/** + * @brief Tests whether this player has been registered with the player list + */ +bool RPSportsPlayerData::isRegistered() const { + return mPlayerFlags.onBit(EFlag_Registered); +} + +/** + * @brief Sets whether this player has been registered with the player list + * + * @param registered Registration status + */ +void RPSportsPlayerData::setRegistered(bool registered) { + mPlayerFlags.changeBit(EFlag_Registered, registered); +} + +/** + * @brief Gets this player's Mii create ID + * + * @param[out] pCreateID Mii create ID + */ +void RPSportsPlayerData::getCreateID(RFLCreateID* pCreateID) const { + for (int i = 0; i < RFL_CREATEID_LEN; i++) { + pCreateID->data[i] = mCreateID.data[i]; + } +} + +/** + * @brief Set this player's Mii create ID + * + * @param pCreateID Mii create ID + */ +void RPSportsPlayerData::setCreateID(const RFLCreateID* pCreateID) { + for (int i = 0; i < RFL_CREATEID_LEN; i++) { + mCreateID.data[i] = pCreateID->data[i]; + } +} + +/** + * @brief Gets the time this player was registered with the player list + */ +RPTime32 RPSportsPlayerData::getDebutTime() const { + return mDebutTime; +} + +/** + * @brief Sets the time this player was registered with the player list + * + * @param time Debut time + */ +void RPSportsPlayerData::setDebutTime(RPTime32 time) { + mDebutTime = time; +} + +/** + * @brief Deserializes this object from the specified stream + * + * @param rStrm Memory stream + */ +void RPSportsPlayerData::read(EGG::RamStream& rStrm) { + mPlayerFlags = rStrm.read_u32(); + + for (int i = 0; i < RFL_CREATEID_LEN; i++) { + mCreateID.data[i] = rStrm.read_u8(); + } + + mDebutTime = rStrm.read_u32(); + mHandFlags = rStrm.read_u8(); + + for (int i = 0; i < ESport_Max; i++) { + mSkillLevels[i] = rStrm.read_f32(); + + for (int j = 0; j < SKILL_HISTORY_LENGTH; j++) { + mSkillGraphDelta[i][j] = rStrm.read_s16(); + } + + mStandardFirstDates[i] = rStrm.read_u16(); + + for (int j = 0; j < EGame_Max; j++) { + mTrainingFirstDates[i][j] = rStrm.read_u16(); + } + + mPlayCounts[i] = rStrm.read_u16(); + + for (int j = 0; j < EGame_Max; j++) { + mTrainingPlayCounts[i][j] = rStrm.read_u16(); + mTrainingMedals[i][j] = rStrm.read_u8(); + } + } + + unk272 = rStrm.read_u16(); + mTnsDifficulty = rStrm.read_f32(); + mTnsSuccess = rStrm.read_f32(); + for (int i = 0; i < EGame_Max; i++) { + mTnsTrainingBests[i] = rStrm.read_u8(); + } + + mBsbHomerunRunsBest = rStrm.read_u8(); + mBsbHomerunDistBest = rStrm.read_u16(); + mBsbUchiwakeBest = rStrm.read_u8(); + mBsbRenzokuBest = rStrm.read_u8(); + + unk284 = rStrm.read_u16(); + mBowStandardBest = rStrm.read_u16(); + mBowPerfectCount = rStrm.read_u8(); + for (int i = 0; i < EGame_Max; i++) { + mBowTrainingBests[i] = rStrm.read_u16(); + } + + for (int i = 0; i < ECourse_Max; i++) { + mGolStandardBests[i] = rStrm.read_s8(); + } + mGolAceCount = rStrm.read_u8(); + for (int i = 0; i < EGame_Max; i++) { + mGolTrainingBests[i] = rStrm.read_u16(); + } + + for (int i = 0; i < EGame_Max; i++) { + mBoxTrainingBests[i] = rStrm.read_u16(); + } + + mPhysicalEndFirstDate = rStrm.read_u16(); + mPhysicalEndCount = rStrm.read_u16(); + + // @bug These arrays are only the same length by chance +#if defined(BUG_FIX) + for (int i = 0; i < EStat_Max; i++) { + mPhysicalLastStats[i] = rStrm.read_u16(); + } + + for (int i = 0; i < PHYSICAL_EVENT_NUM; i++) { + mPhysicalLastEvents[i] = rStrm.read_u8(); + } +#else + for (int i = 0; i < EStat_Max; i++) { + mPhysicalLastStats[i] = rStrm.read_u16(); + mPhysicalLastEvents[i] = rStrm.read_u8(); + } +#endif + + for (int i = 0; i < ESport_Max; i++) { + for (int j = 0; j < EGame_Max; j++) { + mPhysicalStatSumBests[i][j] = rStrm.read_u16(); + } + } + mPhysicalEndLastDate = rStrm.read_u16(); + for (int i = 0; i < PHYSICAL_HISTORY_LENGTH; i++) { + mPhysicalStatSumHistory[i] = rStrm.read_u16(); + mPhysicalDateHistory[i] = rStrm.read_u16(); + } + mPhysicalBeginLastDate = rStrm.read_u16(); + for (int i = 0; i < static_cast(ARRAY_SIZE(unk43E)); i++) { + unk43E[i] = rStrm.read_u16(); + } +} + +/** + * @brief Serializes this object to the specified stream + * + * @param rStrm Memory stream + */ +void RPSportsPlayerData::write(EGG::RamStream& rStrm) { + rStrm.write_u32(mPlayerFlags); + + for (int i = 0; i < RFL_CREATEID_LEN; i++) { + rStrm.write_u8(mCreateID.data[i]); + } + + rStrm.write_u32(mDebutTime); + rStrm.write_u8(mHandFlags); + + for (int i = 0; i < ESport_Max; i++) { + rStrm.write_f32(mSkillLevels[i]); + + for (int j = 0; j < SKILL_HISTORY_LENGTH; j++) { + rStrm.write_s16(mSkillGraphDelta[i][j]); + } + + rStrm.write_u16(mStandardFirstDates[i]); + + for (int j = 0; j < EGame_Max; j++) { + rStrm.write_u16(mTrainingFirstDates[i][j]); + } + + rStrm.write_u16(mPlayCounts[i]); + + for (int j = 0; j < EGame_Max; j++) { + rStrm.write_u16(mTrainingPlayCounts[i][j]); + rStrm.write_u8(mTrainingMedals[i][j]); + } + } + + rStrm.write_u16(unk272); + rStrm.write_f32(mTnsDifficulty); + rStrm.write_f32(mTnsSuccess); + for (int i = 0; i < EGame_Max; i++) { + rStrm.write_u8(mTnsTrainingBests[i]); + } + + rStrm.write_u8(mBsbHomerunRunsBest); + rStrm.write_u16(mBsbHomerunDistBest); + rStrm.write_u8(mBsbUchiwakeBest); + rStrm.write_u8(mBsbRenzokuBest); + + rStrm.write_u16(unk284); + rStrm.write_u16(mBowStandardBest); + rStrm.write_u8(mBowPerfectCount); + for (int i = 0; i < EGame_Max; i++) { + rStrm.write_u16(mBowTrainingBests[i]); + } + + for (int i = 0; i < ECourse_Max; i++) { + rStrm.write_s8(mGolStandardBests[i]); + } + rStrm.write_u8(mGolAceCount); + for (int i = 0; i < EGame_Max; i++) { + rStrm.write_u16(mGolTrainingBests[i]); + } + + for (int i = 0; i < EGame_Max; i++) { + rStrm.write_u16(mBoxTrainingBests[i]); + } + + rStrm.write_u16(mPhysicalEndFirstDate); + rStrm.write_u16(mPhysicalEndCount); + + // @bug These arrays are only the same length by chance +#if defined(BUG_FIX) + for (int i = 0; i < EStat_Max; i++) { + rStrm.write_u16(mPhysicalLastStats[i]); + } + + for (int i = 0; i < PHYSICAL_EVENT_NUM; i++) { + rStrm.write_u8(mPhysicalLastEvents[i]); + } +#else + for (int i = 0; i < EStat_Max; i++) { + rStrm.write_u16(mPhysicalLastStats[i]); + rStrm.write_u8(mPhysicalLastEvents[i]); + } +#endif + + for (int i = 0; i < ESport_Max; i++) { + for (int j = 0; j < EGame_Max; j++) { + rStrm.write_u16(mPhysicalStatSumBests[i][j]); + } + } + rStrm.write_u16(mPhysicalEndLastDate); + for (int i = 0; i < PHYSICAL_HISTORY_LENGTH; i++) { + rStrm.write_u16(mPhysicalStatSumHistory[i]); + rStrm.write_u16(mPhysicalDateHistory[i]); + } + rStrm.write_u16(mPhysicalBeginLastDate); + for (int i = 0; i < static_cast(ARRAY_SIZE(unk43E)); i++) { + rStrm.write_u16(unk43E[i]); + } +} diff --git a/src/Pack/RPSystem/RPSportsSystemData.cpp b/src/Pack/RPSystem/RPSportsSystemData.cpp new file mode 100644 index 00000000..e13f35ac --- /dev/null +++ b/src/Pack/RPSystem/RPSportsSystemData.cpp @@ -0,0 +1,200 @@ +#include + +/** + * @brief Constructor + */ +RPSportsSystemData::RPSportsSystemData() { + reset(); +} + +/** + * @brief Resets the data to a default save state + */ +void RPSportsSystemData::reset() { + for (int i = 0; i < OLD_DATA_LEN; i++) { + mOldIndex[i] = -1; + + for (int j = 0; j < WPAD_ADDR_LEN; j++) { + mOldAddress[i][j] = 0; + } + } + + mPhysicalCount = 0; + mPhysicalEndLastDate = 0; + + unk4A = 0; + unk4C = 0; + + mFlags.makeAllZero(); + unk54.makeAllZero(); +} + +/** + * @brief Gets the old data for the specified player count and player index + * + * @param[out] pIndex Official database index + * @param[out] pAddr Remote Bluetooth address + * @param playerNum Player count + * @param playerNo Player index + */ +void RPSportsSystemData::getOldData(s8* pIndex, u8* pAddr, s32 playerNum, + s32 playerNo) const { + u32 rel2Abs[WPAD_MAX_CONTROLLERS] = { + 0, // 1 player + 0 + 1, // 2 players + 0 + 1 + 2, // 3 players + 0 + 1 + 2 + 3, // 4 players + }; + + u32 absIdx = rel2Abs[--playerNum] + playerNo; + + *pIndex = mOldIndex[absIdx]; + + for (int i = 0; i < WPAD_ADDR_LEN; i++) { + pAddr[i] = mOldAddress[absIdx][i]; + } +} + +/** + * @brief Sets the old data for the specified player count and player index + * + * @param[out] pIndex Official database index + * @param[out] pAddr Remote Bluetooth address + * @param playerNum Player count + * @param playerNo Player index + */ +void RPSportsSystemData::setOldData(s8 index, const u8* pAddr, s32 playerNum, + s32 playerNo) { + u32 rel2Abs[WPAD_MAX_CONTROLLERS] = { + 0, // 1 player + 0 + 1, // 2 players + 0 + 1 + 2, // 3 players + 0 + 1 + 2 + 3, // 4 players + }; + + u32 absIdx = rel2Abs[--playerNum] + playerNo; + + mOldIndex[absIdx] = index; + + for (int i = 0; i < WPAD_ADDR_LEN; i++) { + mOldAddress[absIdx][i] = pAddr[i]; + } +} + +/** + * @brief Sets the total number of fitness tests completed + * + * @param count Number of fitness tests completed + */ +void RPSportsSystemData::setPhysicalEndCount(u8 count) { + mPhysicalCount = count; +} + +/** + * @brief Gets the total number of fitness tests completed + */ +u8 RPSportsSystemData::getPhysicalEndCount() const { + return mPhysicalCount; +} + +/** + * @brief Sets the last date on which a fitness test was completed + * + * @param date Last completion date + */ +void RPSportsSystemData::setPhysicalEndLastDate(RPTime16 date) { + mPhysicalEndLastDate = date; +} + +/** + * @brief Gets the last date on which a fitness test was completed + */ +RPTime16 RPSportsSystemData::getPhysicalEndLastDate() const { + return mPhysicalEndLastDate; +} + +/** + * @brief Sets whether the specified training game's unlock cutscene has + * played + * + * @param idx Training game index + * @param open Whether the unlock cutscene has played + */ +void RPSportsSystemData::setGameOpenDemo(u8 idx, bool open) { + return mFlags.changeBit(idx, open); +} + +/** + * @brief Tests whether the specified training game's unlock cutscene has + * played + * + * @param idx Training game index + */ +bool RPSportsSystemData::isGameOpenDemo(u8 idx) const { + return mFlags.onBit(idx); +} + +/** + * @brief Sets whether the specified training game is available + * + * @param idx Training game index + * @param open Whether the game is available + */ +void RPSportsSystemData::setGameOpen(u8 idx, bool open) { + // First set of EGame bits is for demo + return mFlags.changeBit(EGame_Max + idx, open); +} + +/** + * @brief Tests whether the specified training game is available + * + * @param idx Training game index + */ +bool RPSportsSystemData::isGameOpen(u8 idx) const { + // First set of EGame bits is for demo + return mFlags.onBit(EGame_Max + idx); +} + +/** + * @brief Deserializes this object from the specified stream + * + * @param rStrm Memory stream + */ +void RPSportsSystemData::read(EGG::RamStream& rStrm) { + for (int i = 0; i < OLD_DATA_LEN; i++) { + mOldIndex[i] = rStrm.read_s8(); + + for (int j = 0; j < WPAD_ADDR_LEN; j++) { + mOldAddress[i][j] = rStrm.read_u8(); + } + } + + mPhysicalCount = rStrm.read_u8(); + mPhysicalEndLastDate = rStrm.read_u16(); + unk4A = rStrm.read_u16(); + unk4C = rStrm.read_u8(); + mFlags = rStrm.read_u32(); + unk54 = rStrm.read_u32(); +} + +/** + * @brief Serializes this object to the specified stream + * + * @param rStrm Memory stream + */ +void RPSportsSystemData::write(EGG::RamStream& rStrm) { + for (int i = 0; i < OLD_DATA_LEN; i++) { + rStrm.write_s8(mOldIndex[i]); + + for (int j = 0; j < WPAD_ADDR_LEN; j++) { + rStrm.write_u8(mOldAddress[i][j]); + } + } + + rStrm.write_u8(mPhysicalCount); + rStrm.write_u16(mPhysicalEndLastDate); + rStrm.write_u16(unk4A); + rStrm.write_u8(unk4C); + rStrm.write_u32(mFlags); + rStrm.write_u32(unk54); +} diff --git a/src/Pack/RPSystem/RPSysProjectLocal.cpp b/src/Pack/RPSystem/RPSysProjectLocal.cpp index 3ab52d30..0dd3e86c 100644 --- a/src/Pack/RPSystem/RPSysProjectLocal.cpp +++ b/src/Pack/RPSystem/RPSysProjectLocal.cpp @@ -22,7 +22,7 @@ RPSysProjectLocal::RPSysProjectLocal(EGG::Heap* pHeap) #if defined(PACK_SPORTS) mPack(RPSysSceneCreator::EPackID_SportsPack) -#elif defined(PACK_PLAY) +#elif defined(PACK_PARTY) mPack(RPSysSceneCreator::EPackID_PartyPack) #endif { diff --git a/src/Pack/RPSystem/RPSysSaveData.cpp b/src/Pack/RPSystem/RPSysSaveData.cpp new file mode 100644 index 00000000..6e8d82d4 --- /dev/null +++ b/src/Pack/RPSystem/RPSysSaveData.cpp @@ -0,0 +1,227 @@ +#include + +#include + +/** + * @brief Constructor + */ +RPSysSaveData::RPSysSaveData() + : mpSportsSystemData(NULL), + mpSportsPlayerList(NULL), + mpPartySystemData(NULL), + mpPartyPlayerList(NULL), + unk14(0), + unk18(0), + unk1C(0), + unk20(0), + unk24(0) { + +#if defined(PACK_SPORTS) + mpSportsSystemData = new RPSportsSystemData(); + mpSportsPlayerList = new RPSportsPlayerData[PLAYER_LIST_SIZE]; +#elif defined(PACK_PARTY) + mpPartySystemData = new RPPartySystemData(); + mpPartyPlayerList = new RPPartyPlayerData[PLAYER_LIST_SIZE]; +#endif + + mFlags.makeAllZero(); + reset(); +} + +/** + * @brief Resets the save data state + */ +void RPSysSaveData::reset() { +#if defined(PACK_SPORTS) + mpSportsSystemData->reset(); +#elif defined(PACK_PARTY) + mpPartySystemData->reset(); +#endif + + for (int i = 0; i < PLAYER_LIST_SIZE; i++) { +#if defined(PACK_SPORTS) + mpSportsPlayerList[i].reset(); +#elif defined(PACK_PARTY) + mpPartyPlayerList[i].reset(); +#endif + } +} + +/** + * @brief Tests whether an error occurred while reading the save file + * @typo + */ +bool RPSysSaveData::isErrorOccured() const { + return !mFlags.isZero(); +} + +/** + * @brief Gets the Sports Pack player data at the specified player list + * index + * + * @param idx Player list index + */ +RPSportsPlayerData* RPSysSaveData::getSportsPlayerData(u32 idx) const { + return &mpSportsPlayerList[idx]; +} + +/** + * @brief Sets the Sports Pack player data at the specified player list + * index + * + * @param pPlayerData Player data + * @param idx Player list index + */ +void RPSysSaveData::setSportsPlayerData(const RPSportsPlayerData* pPlayerData, + u32 idx) { + mpSportsPlayerList[idx] = *pPlayerData; +} + +/** + * @brief Gets the Sports Pack system data + */ +RPSportsSystemData* RPSysSaveData::getSportsSystemData() const { + return mpSportsSystemData; +} + +/** + * @brief Sets the Sports Pack system data + * + * @param pSystemData System data + */ +void RPSysSaveData::setSportsSystemData(const RPSportsSystemData* pSystemData) { + *mpSportsSystemData = *pSystemData; +} + +/** + * @brief Gets the Party Pack player data at the specified player list + * index + * + * @param idx Player list index + */ +RPPartyPlayerData* RPSysSaveData::getPartyPlayerData(u32 idx) const { + return &mpPartyPlayerList[idx]; +} + +/** + * @brief Sets the Party Pack player data at the specified player list + * index + * + * @param pPlayerData Player data + * @param idx Player list index + */ +void RPSysSaveData::setPartyPlayerData(const RPPartyPlayerData* pPlayerData, + u32 idx) { + mpPartyPlayerList[idx] = *pPlayerData; +} + +/** + * @brief Gets the Party Pack system data + */ +RPPartySystemData* RPSysSaveData::getPartySystemData() const { + return mpPartySystemData; +} + +/** + * @brief Sets the Party Pack system data + * + * @param pSystemData System data + */ +void RPSysSaveData::setPartySystemData(const RPPartySystemData* pSystemData) { + *mpPartySystemData = *pSystemData; +} + +/** + * @brief Deserializes this object from the specified stream + * + * @param rStrm Memory stream + * @param pRawSave Raw save data + */ +void RPSysSaveData::read(EGG::RamStream& rStrm, const void* pRawSave) { + mFlags.makeAllZero(); + + if (rStrm.read_u32() != SIGNATURE_PACK) { + mFlags.setBit(EFlag_BadPack); + + reset(); + return; + } + + if (rStrm.read_u32() != SIGNATURE_VERSION) { + mFlags.setBit(EFlag_BadVersion); + + reset(); + return; + } + +#if defined(PACK_SPORTS) + mpSportsSystemData->read(rStrm); +#elif defined(PACK_PLAY) + mpPartySystemData->read(rStrm); +#endif + + for (int i = 0; i < PLAYER_LIST_SIZE; i++) { +#if defined(PACK_SPORTS) + mpSportsPlayerList[i].read(rStrm); +#elif defined(PACK_PARTY) + mpPartyPlayerList[i].read(rStrm); +#endif + } + + if (calcCrc(pRawSave, rStrm.getPosition()) != rStrm.read_u32()) { + mFlags.setBit(EFlag_BadCrc); + + reset(); + return; + } +} + +/** + * @brief Serializes this object to the specified stream + * + * @param rStrm Memory stream + * @param pRawSave Raw save data + */ +void RPSysSaveData::write(EGG::RamStream& rStrm, const void* pRawSave) const { + rStrm.write_u32(SIGNATURE_PACK); + rStrm.write_u32(SIGNATURE_VERSION); + + mpSportsSystemData->write(rStrm); + + for (int i = 0; i < PLAYER_LIST_SIZE; i++) { + mpSportsPlayerList[i].write(rStrm); + } + + rStrm.write_u32(calcCrc(pRawSave, rStrm.getPosition())); +} + +/** + * @brief Gets the size of the current pack's save file, in bytes + */ +u32 RPSysSaveData::getSaveFileSize() { +#if defined(PACK_SPORTS) + return OS_MEM_KB_TO_B(128); +#elif defined(PACK_PARTY) + return OS_MEM_KB_TO_B(32); +#endif +} + +/** + * @brief Calculates a checksum of the specified data + * + * @param pData Data buffer + * @param size Buffer size + * @return 32-bit checksum + */ +u32 RPSysSaveData::calcCrc(const void* pData, u32 size) { + u16 sum = 0; + u16 isum = 0; + const u16* p = static_cast(pData); + + for (int i = 0; i < size / sizeof(u16); i++, p++) { + sum += *p; + isum += ~*p; + } + + return sum << 16 | isum; +} From d8a0135a7bc7cb4575a384df9c6ae7ab022b154e Mon Sep 17 00:00:00 2001 From: kiwi515 <49212064+kiwi515@users.noreply.github.com> Date: Sat, 13 Dec 2025 15:58:07 -0500 Subject: [PATCH 2/3] Fix RPGrpModelRfl symbol --- config/RSPE01_01/symbols.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/RSPE01_01/symbols.txt b/config/RSPE01_01/symbols.txt index 2b4633fd..12ea0197 100644 --- a/config/RSPE01_01/symbols.txt +++ b/config/RSPE01_01/symbols.txt @@ -8084,7 +8084,7 @@ InternalCalc__13RPGrpModelRflFv = .text:0x801B5B40; // type:function size:0x1A4 ReplaceTexture__13RPGrpModelRflFPCcRC12RPGrpTextureb = .text:0x801B5CE4; // type:function size:0x124 CreateAnm__13RPGrpModelRflFv = .text:0x801B5E08; // type:function size:0x4 Configure__13RPGrpModelRflFv = .text:0x801B5E0C; // type:function size:0x14C -Construct__13RPGrpModelRflF13RFLDataSourceUsP11RFLMiddleDB13RFLResolutionUlUc = .text:0x801B5F58; // type:function size:0x1E8 +Construct__13RPGrpModelRflF13RFLDataSourceUsP11RFLMiddleDB13RFLResolutionUlUcUl = .text:0x801B5F58; // type:function size:0x1E8 GetKind__13RPGrpModelRflFv = .text:0x801B6140; // type:function size:0x8 SetCallbackJointIndex__13RPGrpModelRflFUs = .text:0x801B6148; // type:function size:0x4 GetCallbackJointIndex__13RPGrpModelRflCFv = .text:0x801B614C; // type:function size:0x8 From 227baa41f01c349c88f20a589f79d98beaa4a326 Mon Sep 17 00:00:00 2001 From: kiwi515 <49212064+kiwi515@users.noreply.github.com> Date: Sat, 13 Dec 2025 15:58:40 -0500 Subject: [PATCH 3/3] Apply symbols from ELF --- config/RSPE01_01/symbols.txt | 529 +++++++++++++++++++---------------- 1 file changed, 295 insertions(+), 234 deletions(-) diff --git a/config/RSPE01_01/symbols.txt b/config/RSPE01_01/symbols.txt index 12ea0197..14a7b700 100644 --- a/config/RSPE01_01/symbols.txt +++ b/config/RSPE01_01/symbols.txt @@ -6713,10 +6713,10 @@ HBMStartBlackOut = .text:0x80177818; // type:function size:0xC scope:global HBMSetBlackOutColor = .text:0x80177824; // type:function size:0x18 scope:global __ct__Q210homebutton10HomeButtonFPC11HBMDataInfo = .text:0x8017783C; // type:function size:0x114 scope:global create__Q210homebutton10HomeButtonFv = .text:0x80177950; // type:function size:0x908 scope:global -__dt__Q310homebutton3gui9InterfaceFv = .text:0x80178258; // type:function size:0x40 scope:global -setManager__Q310homebutton3gui12EventHandlerFPQ310homebutton3gui7Manager = .text:0x80178298; // type:function size:0x8 scope:global -setTriggerTarget__Q310homebutton3gui9ComponentFb = .text:0x801782A0; // type:function size:0x8 scope:global -setDrawInfo__Q310homebutton3gui11PaneManagerFPCQ34nw4r3lyt8DrawInfo = .text:0x801782A8; // type:function size:0x8 scope:global +__dt__Q310homebutton3gui9InterfaceFv = .text:0x80178258; // type:function size:0x40 scope:weak +setManager__Q310homebutton3gui12EventHandlerFPQ310homebutton3gui7Manager = .text:0x80178298; // type:function size:0x8 scope:weak +setTriggerTarget__Q310homebutton3gui9ComponentFb = .text:0x801782A0; // type:function size:0x8 scope:weak +setDrawInfo__Q310homebutton3gui11PaneManagerFPCQ34nw4r3lyt8DrawInfo = .text:0x801782A8; // type:function size:0x8 scope:weak set_config__Q210homebutton10HomeButtonFv = .text:0x801782B0; // type:function size:0x168 scope:global set_text__Q210homebutton10HomeButtonFv = .text:0x80178418; // type:function size:0x84 scope:global init__Q210homebutton10HomeButtonFv = .text:0x8017849C; // type:function size:0x39C scope:global @@ -6725,10 +6725,10 @@ init_sound__Q210homebutton10HomeButtonFv = .text:0x80178A38; // type:function si init_battery__Q210homebutton10HomeButtonFPC17HBMControllerData = .text:0x80178B5C; // type:function size:0x268 scope:global calc__Q210homebutton10HomeButtonFPC17HBMControllerData = .text:0x80178DC4; // type:function size:0x1D60 scope:global calc_battery__Q210homebutton10HomeButtonFi = .text:0x8017AB24; // type:function size:0x200 scope:global -SpeakerCallback__10homebuttonFP7OSAlarmP9OSContext = .text:0x8017AD24; // type:function size:0xE8 scope:global -MotorCallback__10homebuttonFP7OSAlarmP9OSContext = .text:0x8017AE0C; // type:function size:0x24 scope:global -RetrySimpleSyncCallback__10homebuttonFP7OSAlarmP9OSContext = .text:0x8017AE30; // type:function size:0xCC scope:global -SimpleSyncCallback__10homebuttonFll = .text:0x8017AEFC; // type:function size:0x38 scope:global +SpeakerCallback__10homebuttonFP7OSAlarmP9OSContext = .text:0x8017AD24; // type:function size:0xE8 scope:local +MotorCallback__10homebuttonFP7OSAlarmP9OSContext = .text:0x8017AE0C; // type:function size:0x24 scope:local +RetrySimpleSyncCallback__10homebuttonFP7OSAlarmP9OSContext = .text:0x8017AE30; // type:function size:0xCC scope:local +SimpleSyncCallback__10homebuttonFll = .text:0x8017AEFC; // type:function size:0x38 scope:local update__Q210homebutton10HomeButtonFPC17HBMControllerData = .text:0x8017AF34; // type:function size:0x988 scope:global update_controller__Q210homebutton10HomeButtonFi = .text:0x8017B8BC; // type:function size:0xB3C scope:global updateTrigPane__Q210homebutton10HomeButtonFv = .text:0x8017C3F8; // type:function size:0x2C8 scope:global @@ -6739,15 +6739,15 @@ reset_btn__Q210homebutton10HomeButtonFv = .text:0x8017FB04; // type:function siz getPaneNo__Q210homebutton10HomeButtonFPCc = .text:0x8017FD64; // type:function size:0xB0 scope:global setAdjustFlag__Q210homebutton10HomeButtonFi = .text:0x8017FE14; // type:function size:0x13C scope:global onEvent__Q210homebutton22HomeButtonEventHandlerFUlUlPv = .text:0x8017FF50; // type:function size:0xC8 scope:global -getPane__Q310homebutton3gui13PaneComponentFv = .text:0x80180018; // type:function size:0x8 scope:global +getPane__Q310homebutton3gui13PaneComponentFv = .text:0x80180018; // type:function size:0x8 scope:weak startBlackOut__Q210homebutton10HomeButtonFv = .text:0x80180020; // type:function size:0x1F8 scope:global -initgx__10homebuttonFv = .text:0x80180218; // type:function size:0x1B8 scope:global -onEvent__Q310homebutton3gui12EventHandlerFUlUlPv = .text:0x801803D0; // type:function size:0x4 scope:global -draw__Q310homebutton3gui9InterfaceFRA3_A4_f = .text:0x801803D4; // type:function size:0x4 scope:global -draw__Q310homebutton3gui9InterfaceFv = .text:0x801803D8; // type:function size:0x4 scope:global -calc__Q310homebutton3gui9InterfaceFv = .text:0x801803DC; // type:function size:0x4 scope:global -init__Q310homebutton3gui9InterfaceFv = .text:0x801803E0; // type:function size:0x4 scope:global -create__Q310homebutton3gui9InterfaceFv = .text:0x801803E4; // type:function size:0x4 scope:global +initgx__10homebuttonFv = .text:0x80180218; // type:function size:0x1B8 scope:local +onEvent__Q310homebutton3gui12EventHandlerFUlUlPv = .text:0x801803D0; // type:function size:0x4 scope:weak +draw__Q310homebutton3gui9InterfaceFRA3_A4_f = .text:0x801803D4; // type:function size:0x4 scope:weak +draw__Q310homebutton3gui9InterfaceFv = .text:0x801803D8; // type:function size:0x4 scope:weak +calc__Q310homebutton3gui9InterfaceFv = .text:0x801803DC; // type:function size:0x4 scope:weak +init__Q310homebutton3gui9InterfaceFv = .text:0x801803E0; // type:function size:0x4 scope:weak +create__Q310homebutton3gui9InterfaceFv = .text:0x801803E4; // type:function size:0x4 scope:weak __ct__Q210homebutton18GroupAnmControllerFv = .text:0x801803E8; // type:function size:0x1C scope:global __dt__Q210homebutton18GroupAnmControllerFv = .text:0x80180404; // type:function size:0x40 scope:global do_calc__Q210homebutton18GroupAnmControllerFv = .text:0x80180444; // type:function size:0xB0 scope:global @@ -6756,46 +6756,46 @@ initFrame__Q210homebutton15FrameControllerFv = .text:0x8018052C; // type:functio calc__Q210homebutton15FrameControllerFv = .text:0x8018054C; // type:function size:0x150 drawLine___Q210homebutton3guiFfffffUcR8_GXColor = .text:0x8018069C; // type:function size:0x1C4 scope:global update__Q310homebutton3gui9ComponentFiffUlUlUlPv = .text:0x80180860; // type:function size:0x208 scope:global -isVisible__Q310homebutton3gui9ComponentFv = .text:0x80180A68; // type:function size:0x8 scope:global -isPointed__Q310homebutton3gui9ComponentFi = .text:0x80180A70; // type:function size:0xC scope:global -onMove__Q310homebutton3gui9ComponentFff = .text:0x80180A7C; // type:function size:0x4 scope:global -onEvent__Q310homebutton3gui7ManagerFUlUlPv = .text:0x80180A80; // type:function size:0x20 scope:global -getID__Q310homebutton3gui9ComponentFv = .text:0x80180AA0; // type:function size:0x8 scope:global -setPointed__Q310homebutton3gui9ComponentFib = .text:0x80180AA8; // type:function size:0xC scope:global -onPoint__Q310homebutton3gui9ComponentFv = .text:0x80180AB4; // type:function size:0x4 scope:global -offPoint__Q310homebutton3gui9ComponentFv = .text:0x80180AB8; // type:function size:0x4 scope:global +isVisible__Q310homebutton3gui9ComponentFv = .text:0x80180A68; // type:function size:0x8 scope:weak +isPointed__Q310homebutton3gui9ComponentFi = .text:0x80180A70; // type:function size:0xC scope:weak +onMove__Q310homebutton3gui9ComponentFff = .text:0x80180A7C; // type:function size:0x4 scope:weak +onEvent__Q310homebutton3gui7ManagerFUlUlPv = .text:0x80180A80; // type:function size:0x20 scope:weak +getID__Q310homebutton3gui9ComponentFv = .text:0x80180AA0; // type:function size:0x8 scope:weak +setPointed__Q310homebutton3gui9ComponentFib = .text:0x80180AA8; // type:function size:0xC scope:weak +onPoint__Q310homebutton3gui9ComponentFv = .text:0x80180AB4; // type:function size:0x4 scope:weak +offPoint__Q310homebutton3gui9ComponentFv = .text:0x80180AB8; // type:function size:0x4 scope:weak __dt__Q310homebutton3gui7ManagerFv = .text:0x80180ABC; // type:function size:0xBC scope:global init__Q310homebutton3gui7ManagerFv = .text:0x80180B78; // type:function size:0x68 scope:global -init__Q310homebutton3gui9ComponentFv = .text:0x80180BE0; // type:function size:0x2C scope:global +init__Q310homebutton3gui9ComponentFv = .text:0x80180BE0; // type:function size:0x2C scope:weak addComponent__Q310homebutton3gui7ManagerFPQ310homebutton3gui9Component = .text:0x80180C0C; // type:function size:0xC4 scope:global -setManager__Q310homebutton3gui9ComponentFPQ310homebutton3gui7Manager = .text:0x80180CD0; // type:function size:0x8 scope:global +setManager__Q310homebutton3gui9ComponentFPQ310homebutton3gui7Manager = .text:0x80180CD0; // type:function size:0x8 scope:weak getComponent__Q310homebutton3gui7ManagerFUl = .text:0x80180CD8; // type:function size:0x2C scope:global update__Q310homebutton3gui7ManagerFiffUlUlUlPv = .text:0x80180D04; // type:function size:0x1A4 scope:global -isTriggerTarger__Q310homebutton3gui9ComponentFv = .text:0x80180EA8; // type:function size:0x8 scope:global -onTrig__Q310homebutton3gui9ComponentFUlR3Vec = .text:0x80180EB0; // type:function size:0x30 scope:global +isTriggerTarger__Q310homebutton3gui9ComponentFv = .text:0x80180EA8; // type:function size:0x8 scope:weak +onTrig__Q310homebutton3gui9ComponentFUlR3Vec = .text:0x80180EB0; // type:function size:0x30 scope:weak calc__Q310homebutton3gui7ManagerFv = .text:0x80180EE0; // type:function size:0x68 scope:global draw__Q310homebutton3gui7ManagerFv = .text:0x80180F48; // type:function size:0x68 scope:global setAllComponentTriggerTarget__Q310homebutton3gui7ManagerFb = .text:0x80180FB0; // type:function size:0x78 scope:global __dt__Q310homebutton3gui11PaneManagerFv = .text:0x80181028; // type:function size:0x154 scope:global -__dt__Q310homebutton3gui13PaneComponentFv = .text:0x8018117C; // type:function size:0x40 scope:global -__dt__Q310homebutton3gui9ComponentFv = .text:0x801811BC; // type:function size:0x40 scope:global +__dt__Q310homebutton3gui13PaneComponentFv = .text:0x8018117C; // type:function size:0x40 scope:weak +__dt__Q310homebutton3gui9ComponentFv = .text:0x801811BC; // type:function size:0x40 scope:weak createLayoutScene__Q310homebutton3gui11PaneManagerFRCQ34nw4r3lyt6Layout = .text:0x801811FC; // type:function size:0x24 scope:global walkInChildren__Q310homebutton3gui11PaneManagerFRQ34nw4r2ut28LinkList = .text:0x80181220; // type:function size:0x290 scope:global -setPane__Q310homebutton3gui13PaneComponentFPQ34nw4r3lyt4Pane = .text:0x801814B0; // type:function size:0x8 scope:global +setPane__Q310homebutton3gui13PaneComponentFPQ34nw4r3lyt4Pane = .text:0x801814B0; // type:function size:0x8 scope:weak getPaneComponentByPane__Q310homebutton3gui11PaneManagerFPQ34nw4r3lyt4Pane = .text:0x801814B8; // type:function size:0x78 scope:global setAllBoundingBoxComponentTriggerTarget__Q310homebutton3gui11PaneManagerFb = .text:0x80181530; // type:function size:0xD0 scope:global contain__Q310homebutton3gui13PaneComponentFff = .text:0x80181600; // type:function size:0x12C scope:global -getDrawInfo__Q310homebutton3gui11PaneManagerFv = .text:0x8018172C; // type:function size:0x8 scope:global +getDrawInfo__Q310homebutton3gui11PaneManagerFv = .text:0x8018172C; // type:function size:0x8 scope:weak draw__Q310homebutton3gui13PaneComponentFv = .text:0x80181734; // type:function size:0x1A0 scope:global -is_visible__Q210homebutton3guiFPQ34nw4r3lyt4Pane = .text:0x801818D4; // type:function size:0x100 scope:global -IsVisible__Q34nw4r3lyt4PaneCFv = .text:0x801819D4; // type:function size:0xC scope:global -GetParent__Q34nw4r3lyt4PaneCFv = .text:0x801819E0; // type:function size:0x8 scope:global +is_visible__Q210homebutton3guiFPQ34nw4r3lyt4Pane = .text:0x801818D4; // type:function size:0x100 scope:local +IsVisible__Q34nw4r3lyt4PaneCFv = .text:0x801819D4; // type:function size:0xC scope:weak +GetParent__Q34nw4r3lyt4PaneCFv = .text:0x801819E0; // type:function size:0x8 scope:weak isVisible__Q310homebutton3gui13PaneComponentFv = .text:0x801819E8; // type:function size:0xD4 scope:global -update__Q310homebutton3gui9ComponentFiPC10KPADStatusffPv = .text:0x80181ABC; // type:function size:0x8 scope:global -setDraggingButton__Q310homebutton3gui9ComponentFUl = .text:0x80181AC4; // type:function size:0x8 scope:global -onDrag__Q310homebutton3gui9ComponentFff = .text:0x80181ACC; // type:function size:0x4 scope:global -setEventHandler__Q310homebutton3gui7ManagerFPQ310homebutton3gui12EventHandler = .text:0x80181AD0; // type:function size:0x2C scope:global -update__Q310homebutton3gui7ManagerFiPC10KPADStatusffPv = .text:0x80181AFC; // type:function size:0x8 scope:global +update__Q310homebutton3gui9ComponentFiPC10KPADStatusffPv = .text:0x80181ABC; // type:function size:0x8 scope:weak +setDraggingButton__Q310homebutton3gui9ComponentFUl = .text:0x80181AC4; // type:function size:0x8 scope:weak +onDrag__Q310homebutton3gui9ComponentFff = .text:0x80181ACC; // type:function size:0x4 scope:weak +setEventHandler__Q310homebutton3gui7ManagerFPQ310homebutton3gui12EventHandler = .text:0x80181AD0; // type:function size:0x2C scope:weak +update__Q310homebutton3gui7ManagerFiPC10KPADStatusffPv = .text:0x80181AFC; // type:function size:0x8 scope:weak wpadConnectCallback__Q210homebutton10ControllerFll = .text:0x80181B04; // type:function size:0x114 scope:global wpadExtensionCallback__Q210homebutton10ControllerFll = .text:0x80181C18; // type:function size:0x110 scope:global soundOnCallback__Q210homebutton10ControllerFP7OSAlarmP9OSContext = .text:0x80181D28; // type:function size:0x6C scope:global @@ -7702,7 +7702,7 @@ resetResource__19RPSysKokeshiCtrlMgrFl = .text:0x801A61B0; // type:function size notifyReleaseResource__19RPSysKokeshiCtrlMgrFl = .text:0x801A61C0; // type:function size:0x10 __dt__19RPSysKokeshiCtrlMgrFv = .text:0x801A61D0; // type:function size:0x74 __ct__19RPSysKokeshiCtrlMgrFP29IRPSysKokeshiCtrlDataCallbackPQ23EGG4HeapUl = .text:0x801A6244; // type:function size:0xAC -__dt__Q219RPSysKokeshiCtrlMgr8DisposerFv = .text:0x801A62F0; // type:function size:0x70 scope:weak +__dt__Q219RPSysKokeshiCtrlMgr11T__DisposerFv = .text:0x801A62F0; // type:function size:0x70 scope:weak __dt__18RPSysAppMiiManagerFv = .text:0x801A6360; // type:function size:0x40 __ct__18RPSysAppMiiManagerFUsPQ23EGG4Heap = .text:0x801A63A0; // type:function size:0x84 calc__22RPSysControllerSyncMgrFv = .text:0x801A6424; // type:function size:0xB0 @@ -14972,18 +14972,59 @@ hairColorTable$3256 = .rodata:0x80381A84; // type:object size:0xB4 scope:local a eyeColorTable$3261 = .rodata:0x80381B38; // type:object size:0x1E scope:local align:4 scDefaultData = .rodata:0x80381B58; // type:object size:0x1BC scope:local align:4 scDayMax$3234 = .rodata:0x80381D18; // type:object size:0xD scope:local align:4 -lbl_80381D28 = .rodata:0x80381D28; // type:object size:0x4 -lbl_80381D2C = .rodata:0x80381D2C; // type:object size:0x4 align:4 data:float -lbl_80381D30 = .rodata:0x80381D30; // type:object size:0x8 align:4 data:float -lbl_80381D38 = .rodata:0x80381D38; // type:object size:0x60 data:4byte -lbl_80381D98 = .rodata:0x80381D98; // type:object size:0x27C data:4byte -lbl_80382014 = .rodata:0x80382014; // type:object size:0x2C align:4 data:float -lbl_80382040 = .rodata:0x80382040; // type:object size:0x50 align:8 data:double -lbl_80382090 = .rodata:0x80382090; // type:object size:0x8 align:4 data:float -lbl_80382098 = .rodata:0x80382098; // type:object size:0x10 align:4 data:float -lbl_803820A8 = .rodata:0x803820A8; // type:object size:0x4 align:4 data:float -lbl_803820AC = .rodata:0x803820AC; // type:object size:0x4 align:4 data:float -lbl_803820B0 = .rodata:0x803820B0; // type:object size:0x8 align:4 data:float +@17070 = .rodata:0x80381D28; // type:object size:0x4 scope:local +...rodata.0 = .rodata:0x80381D28; // type:label scope:local +@17140 = .rodata:0x80381D2C; // type:object size:0x4 scope:local align:4 data:float +@17141 = .rodata:0x80381D30; // type:object size:0x4 scope:local align:4 data:float +scAnmTable__10homebutton = .rodata:0x80381D38; // type:object size:0x60 scope:local data:4byte +scGroupAnmTable__10homebutton = .rodata:0x80381D98; // type:object size:0x250 scope:local data:4byte +scReConnectTime__Q210homebutton10HomeButton = .rodata:0x80381FE8; // type:object size:0x4 scope:global +scReConnectTime2__Q210homebutton10HomeButton = .rodata:0x80381FEC; // type:object size:0x4 scope:global +scPadDrawWaitTime__Q210homebutton10HomeButton = .rodata:0x80381FF0; // type:object size:0x4 scope:global +scGetPadInfoTime__Q210homebutton10HomeButton = .rodata:0x80381FF4; // type:object size:0x4 scope:global +scForcusSEWaitTime__Q210homebutton10HomeButton = .rodata:0x80381FF8; // type:object size:0x4 scope:global +scOnPaneVibTime__Q210homebutton10HomeButton = .rodata:0x80381FFC; // type:object size:0x4 scope:global +scOnPaneVibWaitTime__Q210homebutton10HomeButton = .rodata:0x80382000; // type:object size:0x4 scope:global +scWaitStopMotorTime__Q210homebutton10HomeButton = .rodata:0x80382004; // type:object size:0x4 scope:global +scWaitDisConnectTime__Q210homebutton10HomeButton = .rodata:0x80382008; // type:object size:0x4 scope:global +@17629 = .rodata:0x8038200C; // type:object size:0x4 scope:local +@17630 = .rodata:0x80382010; // type:object size:0x4 scope:local +@17631 = .rodata:0x80382014; // type:object size:0x4 scope:local align:4 data:float +@17634 = .rodata:0x80382018; // type:object size:0x8 scope:local +@17787 = .rodata:0x80382020; // type:object size:0x4 scope:local +@17788 = .rodata:0x80382024; // type:object size:0x4 scope:local data:string +@17789 = .rodata:0x80382028; // type:object size:0x4 scope:local +@17790 = .rodata:0x8038202C; // type:object size:0x4 scope:local +@17873 = .rodata:0x80382030; // type:object size:0x4 scope:local data:string +@17874 = .rodata:0x80382034; // type:object size:0x4 scope:local +@17875 = .rodata:0x80382038; // type:object size:0x4 scope:local +@17879 = .rodata:0x80382040; // type:object size:0x8 scope:local align:8 data:double +@17925 = .rodata:0x80382048; // type:object size:0x4 scope:local +@17926 = .rodata:0x8038204C; // type:object size:0x4 scope:local +@18580 = .rodata:0x80382050; // type:object size:0x4 scope:local +@18583 = .rodata:0x80382054; // type:object size:0x4 scope:local +@18584 = .rodata:0x80382058; // type:object size:0x4 scope:local +@18585 = .rodata:0x8038205C; // type:object size:0x4 scope:local data:string +@18936 = .rodata:0x80382060; // type:object size:0x4 scope:local +@18937 = .rodata:0x80382064; // type:object size:0x4 scope:local +@18938 = .rodata:0x80382068; // type:object size:0x4 scope:local +@19152 = .rodata:0x8038206C; // type:object size:0x4 scope:local +@19153 = .rodata:0x80382070; // type:object size:0x4 scope:local +@19154 = .rodata:0x80382074; // type:object size:0x4 scope:local +@19576 = .rodata:0x80382078; // type:object size:0x4 scope:local +scSoundHeapSize_but2__Q210homebutton10HomeButton = .rodata:0x8038207C; // type:object size:0x4 scope:global +scSoundHeapSize_but3__Q210homebutton10HomeButton = .rodata:0x80382080; // type:object size:0x4 scope:global +scSoundThreadPrio__Q210homebutton10HomeButton = .rodata:0x80382084; // type:object size:0x4 scope:global +scDvdThreadPrio__Q210homebutton10HomeButton = .rodata:0x80382088; // type:object size:0x4 scope:global +@10600 = .rodata:0x80382090; // type:object size:0x4 scope:local align:4 data:float +@11421 = .rodata:0x80382098; // type:object size:0x4 scope:local align:4 data:float +...rodata.0 = .rodata:0x80382098; // type:label scope:local +@10889 = .rodata:0x8038209C; // type:object size:0x4 scope:local +@11805 = .rodata:0x803820A0; // type:object size:0x4 scope:local +cubeScale$10537 = .rodata:0x803820A4; // type:object size:0x4 scope:local +@10898 = .rodata:0x803820A8; // type:object size:0x4 scope:local align:4 data:float +@10950 = .rodata:0x803820AC; // type:object size:0x4 scope:local align:4 data:float +@10977 = .rodata:0x803820B0; // type:object size:0x4 scope:local align:4 data:float lbl_803820B8 = .rodata:0x803820B8; // type:object size:0x10 lbl_803820C8 = .rodata:0x803820C8; // type:object size:0x30 lbl_803820F8 = .rodata:0x803820F8; // type:object size:0x1E0 data:4byte @@ -15043,8 +15084,8 @@ lbl_80382993 = .rodata:0x80382993; // type:object size:0x4D lbl_803829E0 = .rodata:0x803829E0; // type:object size:0xB data:string lbl_803829EB = .rodata:0x803829EB; // type:object size:0x10 data:string lbl_803829FB = .rodata:0x803829FB; // type:object size:0x35 -lbl_80382A30 = .rodata:0x80382A30; // type:object size:0x10 data:4byte -lbl_80382A40 = .rodata:0x80382A40; // type:object size:0x10 data:4byte +@7451 = .rodata:0x80382A30; // type:object size:0x10 scope:local data:4byte +@7468 = .rodata:0x80382A40; // type:object size:0x10 scope:local data:4byte lbl_80382A50 = .rodata:0x80382A50; // type:object size:0x1C lbl_80382A6C = .rodata:0x80382A6C; // type:object size:0x17 data:string lbl_80382A83 = .rodata:0x80382A83; // type:object size:0x18 data:string @@ -18339,172 +18380,190 @@ coordinateData = .data:0x803B80E0; // type:object size:0x10 scope:global align:8 @3187 = .data:0x803B8560; // type:object size:0x12 scope:local align:4 data:byte @3196 = .data:0x803B8578; // type:object size:0x1B0 scope:local align:8 data:byte @3198 = .data:0x803B8728; // type:object size:0x12 scope:local align:4 data:byte -lbl_803B8740 = .data:0x803B8740; // type:object size:0x48 data:string -lbl_803B8788 = .data:0x803B8788; // type:object size:0x4 data:4byte -lbl_803B878C = .data:0x803B878C; // type:object size:0x4 data:4byte -lbl_803B8790 = .data:0x803B8790; // type:object size:0xD data:string -lbl_803B87A0 = .data:0x803B87A0; // type:object size:0xD data:string -lbl_803B87B0 = .data:0x803B87B0; // type:object size:0xD data:string -lbl_803B87C0 = .data:0x803B87C0; // type:object size:0x20 -lbl_803B87E0 = .data:0x803B87E0; // type:object size:0x8 data:string -lbl_803B87E8 = .data:0x803B87E8; // type:object size:0x4 data:4byte -lbl_803B87EC = .data:0x803B87EC; // type:object size:0xC -lbl_803B87F8 = .data:0x803B87F8; // type:object size:0xC -lbl_803B8804 = .data:0x803B8804; // type:object size:0xA data:string -lbl_803B8810 = .data:0x803B8810; // type:object size:0xA data:string -lbl_803B881C = .data:0x803B881C; // type:object size:0xA data:string -lbl_803B8828 = .data:0x803B8828; // type:object size:0xA data:string -lbl_803B8838 = .data:0x803B8838; // type:object size:0x10 data:4byte -lbl_803B8848 = .data:0x803B8848; // type:object size:0xA data:string -lbl_803B8854 = .data:0x803B8854; // type:object size:0xA data:string -lbl_803B8860 = .data:0x803B8860; // type:object size:0xA data:string -lbl_803B886C = .data:0x803B886C; // type:object size:0x1C -lbl_803B8888 = .data:0x803B8888; // type:object size:0xE data:string -lbl_803B8898 = .data:0x803B8898; // type:object size:0xE data:string -lbl_803B88A8 = .data:0x803B88A8; // type:object size:0xE data:string -lbl_803B88B8 = .data:0x803B88B8; // type:object size:0xE data:string -lbl_803B88C8 = .data:0x803B88C8; // type:object size:0xC data:string -lbl_803B88D4 = .data:0x803B88D4; // type:object size:0xC data:string -lbl_803B88E0 = .data:0x803B88E0; // type:object size:0xC data:string -lbl_803B88EC = .data:0x803B88EC; // type:object size:0x2C -lbl_803B8918 = .data:0x803B8918; // type:object size:0x11 data:string -lbl_803B892C = .data:0x803B892C; // type:object size:0x12 data:string -lbl_803B8940 = .data:0x803B8940; // type:object size:0x20 -lbl_803B8960 = .data:0x803B8960; // type:object size:0x11 data:string -lbl_803B8974 = .data:0x803B8974; // type:object size:0x14 data:string -lbl_803B8988 = .data:0x803B8988; // type:object size:0x15 data:string -lbl_803B89A0 = .data:0x803B89A0; // type:object size:0x15 data:string -lbl_803B89B8 = .data:0x803B89B8; // type:object size:0x16 data:string -lbl_803B89D0 = .data:0x803B89D0; // type:object size:0x13 data:string -lbl_803B89E4 = .data:0x803B89E4; // type:object size:0x14 data:string -lbl_803B89F8 = .data:0x803B89F8; // type:object size:0x12 data:string -lbl_803B8A0C = .data:0x803B8A0C; // type:object size:0x13 data:string -lbl_803B8A20 = .data:0x803B8A20; // type:object size:0x10 data:string -lbl_803B8A30 = .data:0x803B8A30; // type:object size:0x16 data:string -lbl_803B8A48 = .data:0x803B8A48; // type:object size:0x11 data:string -lbl_803B8A5C = .data:0x803B8A5C; // type:object size:0x16 data:string -lbl_803B8A74 = .data:0x803B8A74; // type:object size:0x14 data:string -lbl_803B8A88 = .data:0x803B8A88; // type:object size:0x4C -lbl_803B8AD4 = .data:0x803B8AD4; // type:object size:0xA data:string -lbl_803B8AE0 = .data:0x803B8AE0; // type:object size:0xD data:string -lbl_803B8AF0 = .data:0x803B8AF0; // type:object size:0xE data:string -lbl_803B8B00 = .data:0x803B8B00; // type:object size:0xE data:string -lbl_803B8B10 = .data:0x803B8B10; // type:object size:0xF data:string -lbl_803B8B20 = .data:0x803B8B20; // type:object size:0xC data:string -lbl_803B8B2C = .data:0x803B8B2C; // type:object size:0xD data:string -lbl_803B8B3C = .data:0x803B8B3C; // type:object size:0xB data:string -lbl_803B8B48 = .data:0x803B8B48; // type:object size:0xC data:string -lbl_803B8B54 = .data:0x803B8B54; // type:object size:0x9 data:string -lbl_803B8B60 = .data:0x803B8B60; // type:object size:0xF data:string -lbl_803B8B70 = .data:0x803B8B70; // type:object size:0xA data:string -lbl_803B8B7C = .data:0x803B8B7C; // type:object size:0xF data:string -lbl_803B8B8C = .data:0x803B8B8C; // type:object size:0xD data:string -lbl_803B8B9C = .data:0x803B8B9C; // type:object size:0x48 -lbl_803B8BE4 = .data:0x803B8BE4; // type:object size:0x13 data:string -lbl_803B8BF8 = .data:0x803B8BF8; // type:object size:0x13 data:string -lbl_803B8C0C = .data:0x803B8C0C; // type:object size:0x13 data:string -lbl_803B8C20 = .data:0x803B8C20; // type:object size:0x14 data:string -lbl_803B8C34 = .data:0x803B8C34; // type:object size:0x13 data:string -lbl_803B8C48 = .data:0x803B8C48; // type:object size:0x14 data:string -lbl_803B8C5C = .data:0x803B8C5C; // type:object size:0x16 data:string -lbl_803B8C74 = .data:0x803B8C74; // type:object size:0x14 data:string -lbl_803B8C88 = .data:0x803B8C88; // type:object size:0x16 data:string -lbl_803B8CA0 = .data:0x803B8CA0; // type:object size:0x11 data:string -lbl_803B8CB4 = .data:0x803B8CB4; // type:object size:0x11 data:string -lbl_803B8CC8 = .data:0x803B8CC8; // type:object size:0x16 data:string -lbl_803B8CE0 = .data:0x803B8CE0; // type:object size:0x17 data:string -lbl_803B8CF8 = .data:0x803B8CF8; // type:object size:0x17 data:string -lbl_803B8D10 = .data:0x803B8D10; // type:object size:0x16 data:string -lbl_803B8D28 = .data:0x803B8D28; // type:object size:0x11 data:string -lbl_803B8D40 = .data:0x803B8D40; // type:object size:0x10 data:string -lbl_803B8D50 = .data:0x803B8D50; // type:object size:0x10 data:string -lbl_803B8D60 = .data:0x803B8D60; // type:object size:0x15 data:string -lbl_803B8D78 = .data:0x803B8D78; // type:object size:0x14 data:string -lbl_803B8D8C = .data:0x803B8D8C; // type:object size:0x15 data:string -lbl_803B8DA8 = .data:0x803B8DA8; // type:object size:0x68 -lbl_803B8E10 = .data:0x803B8E10; // type:object size:0xC data:string -lbl_803B8E1C = .data:0x803B8E1C; // type:object size:0xC data:string -lbl_803B8E28 = .data:0x803B8E28; // type:object size:0xF data:string -lbl_803B8E38 = .data:0x803B8E38; // type:object size:0xF data:string -lbl_803B8E48 = .data:0x803B8E48; // type:object size:0xC data:string -lbl_803B8E54 = .data:0x803B8E54; // type:object size:0xD data:string -lbl_803B8E64 = .data:0x803B8E64; // type:object size:0x11 data:string -lbl_803B8E78 = .data:0x803B8E78; // type:object size:0x11 data:string -lbl_803B8E8C = .data:0x803B8E8C; // type:object size:0x11 data:string -lbl_803B8EA0 = .data:0x803B8EA0; // type:object size:0x11 data:string -lbl_803B8EB4 = .data:0x803B8EB4; // type:object size:0x11 data:string -lbl_803B8EC8 = .data:0x803B8EC8; // type:object size:0xF data:string -lbl_803B8ED8 = .data:0x803B8ED8; // type:object size:0xF data:string -lbl_803B8EE8 = .data:0x803B8EE8; // type:object size:0xF data:string -lbl_803B8EF8 = .data:0x803B8EF8; // type:object size:0xF data:string -lbl_803B8F08 = .data:0x803B8F08; // type:object size:0xF data:string -lbl_803B8F18 = .data:0x803B8F18; // type:object size:0x11 data:string -lbl_803B8F30 = .data:0x803B8F30; // type:object size:0x10 data:string -lbl_803B8F40 = .data:0x803B8F40; // type:object size:0x10 data:string -lbl_803B8F50 = .data:0x803B8F50; // type:object size:0xE data:string -lbl_803B8F60 = .data:0x803B8F60; // type:object size:0xE data:string -lbl_803B8F70 = .data:0x803B8F70; // type:object size:0x7 data:string -lbl_803B8F78 = .data:0x803B8F78; // type:object size:0x7 data:string -lbl_803B8F80 = .data:0x803B8F80; // type:object size:0x7 data:string -lbl_803B8F88 = .data:0x803B8F88; // type:object size:0x7 data:string -lbl_803B8F90 = .data:0x803B8F90; // type:object size:0x7 data:string -lbl_803B8F98 = .data:0x803B8F98; // type:object size:0x7 data:string -lbl_803B8FA0 = .data:0x803B8FA0; // type:object size:0x7 data:string -lbl_803B8FA8 = .data:0x803B8FA8; // type:object size:0x7 data:string -lbl_803B8FB0 = .data:0x803B8FB0; // type:object size:0x7 data:string -lbl_803B8FB8 = .data:0x803B8FB8; // type:object size:0x7 data:string -lbl_803B8FC0 = .data:0x803B8FC0; // type:object size:0x8 data:string -lbl_803B8FC8 = .data:0x803B8FC8; // type:object size:0x8 data:string -lbl_803B8FD0 = .data:0x803B8FD0; // type:object size:0x8 data:string -lbl_803B8FD8 = .data:0x803B8FD8; // type:object size:0x94 -lbl_803B906C = .data:0x803B906C; // type:object size:0xB data:string -lbl_803B9078 = .data:0x803B9078; // type:object size:0xA data:string -lbl_803B9084 = .data:0x803B9084; // type:object size:0xA data:string -lbl_803B9090 = .data:0x803B9090; // type:object size:0xA data:string -lbl_803B909C = .data:0x803B909C; // type:object size:0x20 -lbl_803B90BC = .data:0x803B90BC; // type:object size:0x9 data:string -lbl_803B90C8 = .data:0x803B90C8; // type:object size:0x9 data:string -lbl_803B90D4 = .data:0x803B90D4; // type:object size:0xD data:string -lbl_803B90E4 = .data:0x803B90E4; // type:object size:0xD data:string -lbl_803B90F4 = .data:0x803B90F4; // type:object size:0xD data:string -lbl_803B9104 = .data:0x803B9104; // type:object size:0xD data:string -lbl_803B9114 = .data:0x803B9114; // type:object size:0xD data:string -lbl_803B9124 = .data:0x803B9124; // type:object size:0x7 data:string -lbl_803B912C = .data:0x803B912C; // type:object size:0x7 data:string -lbl_803B9134 = .data:0x803B9134; // type:object size:0x9 data:string -lbl_803B9140 = .data:0x803B9140; // type:object size:0x28 data:4byte -lbl_803B9168 = .data:0x803B9168; // type:object size:0x9 data:string -lbl_803B9174 = .data:0x803B9174; // type:object size:0x9 data:string -lbl_803B9180 = .data:0x803B9180; // type:object size:0x9 data:string -lbl_803B918C = .data:0x803B918C; // type:object size:0xC data:4byte -lbl_803B9198 = .data:0x803B9198; // type:object size:0xD data:string -lbl_803B91A8 = .data:0x803B91A8; // type:object size:0xD data:string -lbl_803B91B8 = .data:0x803B91B8; // type:object size:0xD data:string -lbl_803B91C8 = .data:0x803B91C8; // type:object size:0xD data:string -lbl_803B91D8 = .data:0x803B91D8; // type:object size:0xD data:string -lbl_803B91E8 = .data:0x803B91E8; // type:object size:0xD data:string -lbl_803B91F8 = .data:0x803B91F8; // type:object size:0xD data:string -lbl_803B9208 = .data:0x803B9208; // type:object size:0xD data:string -lbl_803B9218 = .data:0x803B9218; // type:object size:0xD data:string -lbl_803B9228 = .data:0x803B9228; // type:object size:0xD data:string -lbl_803B9238 = .data:0x803B9238; // type:object size:0xD data:string -lbl_803B9248 = .data:0x803B9248; // type:object size:0xD data:string -lbl_803B9258 = .data:0x803B9258; // type:object size:0xD data:string -lbl_803B9268 = .data:0x803B9268; // type:object size:0xD data:string -lbl_803B9278 = .data:0x803B9278; // type:object size:0xD data:string -lbl_803B9288 = .data:0x803B9288; // type:object size:0xD data:string -lbl_803B9298 = .data:0x803B9298; // type:object size:0x60 data:4byte -jumptable_803B92F8 = .data:0x803B92F8; // type:object size:0x50 scope:local -jumptable_803B9348 = .data:0x803B9348; // type:object size:0x28 scope:local -jumptable_803B9370 = .data:0x803B9370; // type:object size:0x28 scope:local -jumptable_803B9398 = .data:0x803B9398; // type:object size:0x28 scope:local -lbl_803B93C0 = .data:0x803B93C0; // type:object size:0x40 -lbl_803B9400 = .data:0x803B9400; // type:object size:0x10 +@10545 = .data:0x803B8740; // type:object size:0x48 scope:local data:string +...data.0 = .data:0x803B8740; // type:label scope:local +__HBMVersion = .data:0x803B8788; // type:object size:0x4 data:4byte +spAllocator = .data:0x803B878C; // type:object size:0x4 scope:local data:4byte +@10610 = .data:0x803B8790; // type:object size:0xD scope:local data:string +@10611 = .data:0x803B87A0; // type:object size:0xD scope:local data:string +@10612 = .data:0x803B87B0; // type:object size:0xD scope:local data:string +@10613 = .data:0x803B87C0; // type:object size:0xD scope:local data:string +scCursorLytName__Q210homebutton10HomeButton = .data:0x803B87D0; // type:object size:0x10 scope:global +@10614 = .data:0x803B87E0; // type:object size:0x8 scope:local data:string +scCursorPaneName__Q210homebutton10HomeButton = .data:0x803B87E8; // type:object size:0x4 data:4byte +@10615 = .data:0x803B87EC; // type:object size:0x6 scope:local data:string +scCursorRotPaneName__Q210homebutton10HomeButton = .data:0x803B87F4; // type:object size:0x4 scope:global +@10616 = .data:0x803B87F8; // type:object size:0x7 scope:local data:string +scCursorSRotPaneName__Q210homebutton10HomeButton = .data:0x803B8800; // type:object size:0x4 scope:global +@10617 = .data:0x803B8804; // type:object size:0xA scope:local data:string +@10618 = .data:0x803B8810; // type:object size:0xA scope:local data:string +@10619 = .data:0x803B881C; // type:object size:0xA scope:local data:string +@10620 = .data:0x803B8828; // type:object size:0xA scope:local data:string +scBtnName__Q210homebutton10HomeButton = .data:0x803B8838; // type:object size:0x10 data:4byte +@10621 = .data:0x803B8848; // type:object size:0xA scope:local data:string +@10622 = .data:0x803B8854; // type:object size:0xA scope:local data:string +@10623 = .data:0x803B8860; // type:object size:0xA scope:local data:string +@10624 = .data:0x803B886C; // type:object size:0xA scope:local data:string +scTxtName__Q210homebutton10HomeButton = .data:0x803B8878; // type:object size:0x10 scope:global +@10625 = .data:0x803B8888; // type:object size:0xE scope:local data:string +@10626 = .data:0x803B8898; // type:object size:0xE scope:local data:string +@10627 = .data:0x803B88A8; // type:object size:0xE scope:local data:string +@10628 = .data:0x803B88B8; // type:object size:0xE scope:local data:string +@10629 = .data:0x803B88C8; // type:object size:0xC scope:local data:string +@10630 = .data:0x803B88D4; // type:object size:0xC scope:local data:string +@10631 = .data:0x803B88E0; // type:object size:0xC scope:local data:string +@10632 = .data:0x803B88EC; // type:object size:0xC scope:local data:string +scGrName__Q210homebutton10HomeButton = .data:0x803B88F8; // type:object size:0x20 scope:global +@10633 = .data:0x803B8918; // type:object size:0x11 scope:local data:string +@10634 = .data:0x803B892C; // type:object size:0x12 scope:local data:string +@10635 = .data:0x803B8940; // type:object size:0x12 scope:local data:string +scAnimName__Q210homebutton10HomeButton = .data:0x803B8954; // type:object size:0xC scope:global +@10636 = .data:0x803B8960; // type:object size:0x11 scope:local data:string +@10637 = .data:0x803B8974; // type:object size:0x14 scope:local data:string +@10638 = .data:0x803B8988; // type:object size:0x15 scope:local data:string +@10639 = .data:0x803B89A0; // type:object size:0x15 scope:local data:string +@10640 = .data:0x803B89B8; // type:object size:0x16 scope:local data:string +@10641 = .data:0x803B89D0; // type:object size:0x13 scope:local data:string +@10642 = .data:0x803B89E4; // type:object size:0x14 scope:local data:string +@10643 = .data:0x803B89F8; // type:object size:0x12 scope:local data:string +@10644 = .data:0x803B8A0C; // type:object size:0x13 scope:local data:string +@10645 = .data:0x803B8A20; // type:object size:0x10 scope:local data:string +@10646 = .data:0x803B8A30; // type:object size:0x16 scope:local data:string +@10647 = .data:0x803B8A48; // type:object size:0x11 scope:local data:string +@10648 = .data:0x803B8A5C; // type:object size:0x16 scope:local data:string +@10649 = .data:0x803B8A74; // type:object size:0x14 scope:local data:string +@10650 = .data:0x803B8A88; // type:object size:0x10 scope:local data:string +scPairGroupAnimName__Q210homebutton10HomeButton = .data:0x803B8A98; // type:object size:0x3C scope:global +@10651 = .data:0x803B8AD4; // type:object size:0xA scope:local data:string +@10652 = .data:0x803B8AE0; // type:object size:0xD scope:local data:string +@10653 = .data:0x803B8AF0; // type:object size:0xE scope:local data:string +@10654 = .data:0x803B8B00; // type:object size:0xE scope:local data:string +@10655 = .data:0x803B8B10; // type:object size:0xF scope:local data:string +@10656 = .data:0x803B8B20; // type:object size:0xC scope:local data:string +@10657 = .data:0x803B8B2C; // type:object size:0xD scope:local data:string +@10658 = .data:0x803B8B3C; // type:object size:0xB scope:local data:string +@10659 = .data:0x803B8B48; // type:object size:0xC scope:local data:string +@10660 = .data:0x803B8B54; // type:object size:0x9 scope:local data:string +@10661 = .data:0x803B8B60; // type:object size:0xF scope:local data:string +@10662 = .data:0x803B8B70; // type:object size:0xA scope:local data:string +@10663 = .data:0x803B8B7C; // type:object size:0xF scope:local data:string +@10664 = .data:0x803B8B8C; // type:object size:0xD scope:local data:string +@10665 = .data:0x803B8B9C; // type:object size:0x9 scope:local data:string +scPairGroupName__Q210homebutton10HomeButton = .data:0x803B8BA8; // type:object size:0x3C scope:global +@10666 = .data:0x803B8BE4; // type:object size:0x13 scope:local data:string +@10667 = .data:0x803B8BF8; // type:object size:0x13 scope:local data:string +@10668 = .data:0x803B8C0C; // type:object size:0x13 scope:local data:string +@10669 = .data:0x803B8C20; // type:object size:0x14 scope:local data:string +@10670 = .data:0x803B8C34; // type:object size:0x13 scope:local data:string +@10671 = .data:0x803B8C48; // type:object size:0x14 scope:local data:string +@10672 = .data:0x803B8C5C; // type:object size:0x16 scope:local data:string +@10673 = .data:0x803B8C74; // type:object size:0x14 scope:local data:string +@10674 = .data:0x803B8C88; // type:object size:0x16 scope:local data:string +@10675 = .data:0x803B8CA0; // type:object size:0x11 scope:local data:string +@10676 = .data:0x803B8CB4; // type:object size:0x11 scope:local data:string +@10677 = .data:0x803B8CC8; // type:object size:0x16 scope:local data:string +@10678 = .data:0x803B8CE0; // type:object size:0x17 scope:local data:string +@10679 = .data:0x803B8CF8; // type:object size:0x17 scope:local data:string +@10680 = .data:0x803B8D10; // type:object size:0x16 scope:local data:string +@10681 = .data:0x803B8D28; // type:object size:0x11 scope:local data:string +@10682 = .data:0x803B8D40; // type:object size:0x10 scope:local data:string +@10683 = .data:0x803B8D50; // type:object size:0x10 scope:local data:string +@10684 = .data:0x803B8D60; // type:object size:0x15 scope:local data:string +@10685 = .data:0x803B8D78; // type:object size:0x14 scope:local data:string +@10686 = .data:0x803B8D8C; // type:object size:0x15 scope:local data:string +@10687 = .data:0x803B8DA8; // type:object size:0x10 scope:local data:string +scGroupAnimName__Q210homebutton10HomeButton = .data:0x803B8DB8; // type:object size:0x58 scope:global +@10688 = .data:0x803B8E10; // type:object size:0xC scope:local data:string +@10689 = .data:0x803B8E1C; // type:object size:0xC scope:local data:string +@10690 = .data:0x803B8E28; // type:object size:0xF scope:local data:string +@10691 = .data:0x803B8E38; // type:object size:0xF scope:local data:string +@10692 = .data:0x803B8E48; // type:object size:0xC scope:local data:string +@10693 = .data:0x803B8E54; // type:object size:0xD scope:local data:string +@10694 = .data:0x803B8E64; // type:object size:0x11 scope:local data:string +@10695 = .data:0x803B8E78; // type:object size:0x11 scope:local data:string +@10696 = .data:0x803B8E8C; // type:object size:0x11 scope:local data:string +@10697 = .data:0x803B8EA0; // type:object size:0x11 scope:local data:string +@10698 = .data:0x803B8EB4; // type:object size:0x11 scope:local data:string +@10699 = .data:0x803B8EC8; // type:object size:0xF scope:local data:string +@10700 = .data:0x803B8ED8; // type:object size:0xF scope:local data:string +@10701 = .data:0x803B8EE8; // type:object size:0xF scope:local data:string +@10702 = .data:0x803B8EF8; // type:object size:0xF scope:local data:string +@10703 = .data:0x803B8F08; // type:object size:0xF scope:local data:string +@10704 = .data:0x803B8F18; // type:object size:0x11 scope:local data:string +@10705 = .data:0x803B8F30; // type:object size:0x10 scope:local data:string +@10706 = .data:0x803B8F40; // type:object size:0x10 scope:local data:string +@10707 = .data:0x803B8F50; // type:object size:0xE scope:local data:string +@10708 = .data:0x803B8F60; // type:object size:0xE scope:local data:string +@10709 = .data:0x803B8F70; // type:object size:0x7 scope:local data:string +@10710 = .data:0x803B8F78; // type:object size:0x7 scope:local data:string +@10711 = .data:0x803B8F80; // type:object size:0x7 scope:local data:string +@10712 = .data:0x803B8F88; // type:object size:0x7 scope:local data:string +@10713 = .data:0x803B8F90; // type:object size:0x7 scope:local data:string +@10714 = .data:0x803B8F98; // type:object size:0x7 scope:local data:string +@10715 = .data:0x803B8FA0; // type:object size:0x7 scope:local data:string +@10716 = .data:0x803B8FA8; // type:object size:0x7 scope:local data:string +@10717 = .data:0x803B8FB0; // type:object size:0x7 scope:local data:string +@10718 = .data:0x803B8FB8; // type:object size:0x7 scope:local data:string +@10719 = .data:0x803B8FC0; // type:object size:0x8 scope:local data:string +@10720 = .data:0x803B8FC8; // type:object size:0x8 scope:local data:string +@10721 = .data:0x803B8FD0; // type:object size:0x8 scope:local data:string +@10722 = .data:0x803B8FD8; // type:object size:0x8 scope:local data:string +scGroupName__Q210homebutton10HomeButton = .data:0x803B8FE0; // type:object size:0x8C scope:global +@10723 = .data:0x803B906C; // type:object size:0xB scope:local data:string +@10724 = .data:0x803B9078; // type:object size:0xA scope:local data:string +@10725 = .data:0x803B9084; // type:object size:0xA scope:local data:string +@10726 = .data:0x803B9090; // type:object size:0xA scope:local data:string +@10727 = .data:0x803B909C; // type:object size:0xA scope:local data:string +scFuncPaneName__Q210homebutton10HomeButton = .data:0x803B90A8; // type:object size:0x14 scope:global +@10728 = .data:0x803B90BC; // type:object size:0x9 scope:local data:string +@10729 = .data:0x803B90C8; // type:object size:0x9 scope:local data:string +@10730 = .data:0x803B90D4; // type:object size:0xD scope:local data:string +@10731 = .data:0x803B90E4; // type:object size:0xD scope:local data:string +@10732 = .data:0x803B90F4; // type:object size:0xD scope:local data:string +@10733 = .data:0x803B9104; // type:object size:0xD scope:local data:string +@10734 = .data:0x803B9114; // type:object size:0xD scope:local data:string +@10735 = .data:0x803B9124; // type:object size:0x7 scope:local data:string +@10736 = .data:0x803B912C; // type:object size:0x7 scope:local data:string +@10737 = .data:0x803B9134; // type:object size:0x9 scope:local data:string +scFuncTouchPaneName__Q210homebutton10HomeButton = .data:0x803B9140; // type:object size:0x28 data:4byte +@10738 = .data:0x803B9168; // type:object size:0x9 scope:local data:string +@10739 = .data:0x803B9174; // type:object size:0x9 scope:local data:string +@10740 = .data:0x803B9180; // type:object size:0x9 scope:local data:string +scFuncTextPaneName__Q210homebutton10HomeButton = .data:0x803B918C; // type:object size:0xC data:4byte +@10741 = .data:0x803B9198; // type:object size:0xD scope:local data:string +@10742 = .data:0x803B91A8; // type:object size:0xD scope:local data:string +@10743 = .data:0x803B91B8; // type:object size:0xD scope:local data:string +@10744 = .data:0x803B91C8; // type:object size:0xD scope:local data:string +@10745 = .data:0x803B91D8; // type:object size:0xD scope:local data:string +@10746 = .data:0x803B91E8; // type:object size:0xD scope:local data:string +@10747 = .data:0x803B91F8; // type:object size:0xD scope:local data:string +@10748 = .data:0x803B9208; // type:object size:0xD scope:local data:string +@10749 = .data:0x803B9218; // type:object size:0xD scope:local data:string +@10750 = .data:0x803B9228; // type:object size:0xD scope:local data:string +@10751 = .data:0x803B9238; // type:object size:0xD scope:local data:string +@10752 = .data:0x803B9248; // type:object size:0xD scope:local data:string +@10753 = .data:0x803B9258; // type:object size:0xD scope:local data:string +@10754 = .data:0x803B9268; // type:object size:0xD scope:local data:string +@10755 = .data:0x803B9278; // type:object size:0xD scope:local data:string +@10756 = .data:0x803B9288; // type:object size:0xD scope:local data:string +scBatteryPaneName__Q210homebutton10HomeButton = .data:0x803B9298; // type:object size:0x40 data:4byte +@17627 = .data:0x803B92D8; // type:object size:0x4 scope:local data:string +@17628 = .data:0x803B92E0; // type:object size:0x8 scope:local data:string +@18581 = .data:0x803B92E8; // type:object size:0x8 scope:local data:string +@18582 = .data:0x803B92F0; // type:object size:0x8 scope:local data:string +@18590 = .data:0x803B92F8; // type:object size:0x50 scope:local +@19580 = .data:0x803B9348; // type:object size:0x28 scope:local +@19778 = .data:0x803B9370; // type:object size:0x28 scope:local +@20295 = .data:0x803B9398; // type:object size:0x28 scope:local +__vt__Q210homebutton22HomeButtonEventHandler = .data:0x803B93C0; // type:object size:0x10 +__vt__Q310homebutton3gui12EventHandler = .data:0x803B93D0; // type:object size:0x10 scope:weak +__vt__Q310homebutton3gui9Interface = .data:0x803B93E0; // type:object size:0x20 scope:weak +__vt__Q210homebutton18GroupAnmController = .data:0x803B9400; // type:object size:0x10 __vt__Q310homebutton3gui13PaneComponent = .data:0x803B9410; // type:object size:0x68 __vt__Q310homebutton3gui11PaneManager = .data:0x803B9478; // type:object size:0x54 __vt__Q310homebutton3gui7Manager = .data:0x803B94CC; // type:object size:0x3C __vt__Q310homebutton3gui9Component = .data:0x803B9508; // type:object size:0x60 -lbl_803B9568 = .data:0x803B9568; // type:object size:0x10 +__vt__Q210homebutton9RemoteSpk = .data:0x803B9568; // type:object size:0xC __vt__11RPSysSystem = .data:0x803B9578; // type:object size:0xC scope:global __vt__15RPSysConfigData = .data:0x803B9584; // type:object size:0x34 scope:global jumptable_803B95B8 = .data:0x803B95B8; // type:object size:0x30 scope:local @@ -18569,7 +18628,7 @@ __vt__17RPSysLytAllocator = .data:0x803B9D10; // type:object size:0x14 @17563 = .data:0x803B9D28; // type:object size:0x1C scope:local __vt__20RPSysKokeshiIterater = .data:0x803B9D44; // type:object size:0xC lbl_803B9D50 = .data:0x803B9D50; // type:object size:0x18 -lbl_803B9D68 = .data:0x803B9D68; // type:object size:0x18 +@wstringBase0 = .data:0x803B9D68; // type:object size:0x18 scope:local @17530 = .data:0x803B9D80; // type:object size:0x30 scope:local __vt__26RPSysKokeshiCtrlDataLoader = .data:0x803B9DB0; // type:object size:0xC lbl_803B9DC0 = .data:0x803B9DC0; // type:object size:0x40 @@ -18581,7 +18640,7 @@ lbl_803B9E48 = .data:0x803B9E48; // type:object size:0x10 __vt__15RPSysOfficialDB = .data:0x803B9E58; // type:object size:0xC __vt__23RPSysKokeshiCtrlDataMgr = .data:0x803B9E68; // type:object size:0xC __vt__19RPSysKokeshiCtrlMgr = .data:0x803B9E78; // type:object size:0xC -__vt__Q219RPSysKokeshiCtrlMgr8Disposer = .data:0x803B9E84; // type:object size:0xC scope:weak +__vt__Q219RPSysKokeshiCtrlMgr11T__Disposer = .data:0x803B9E84; // type:object size:0xC scope:weak lbl_803B9E90 = .data:0x803B9E90; // type:object size:0x10 lbl_803B9EA0 = .data:0x803B9EA0; // type:object size:0x10 @19267 = .data:0x803B9EB0; // type:object size:0x9C scope:local @@ -19799,14 +19858,16 @@ lbl_804A3590 = .bss:0x804A3590; // type:object size:0x10 data:2byte lbl_804A35A0 = .bss:0x804A35A0; // type:object size:0x230 data:byte l_driveInfo = .bss:0x804A37D0; // type:object size:0x208 scope:global data:4byte lbl_804A39D8 = .bss:0x804A39D8; // type:object size:0x1A0 -lbl_804A3B78 = .bss:0x804A3B78; // type:object size:0x10 -lbl_804A3B88 = .bss:0x804A3B88; // type:object size:0x8 data:4byte -lbl_804A3B90 = .bss:0x804A3B90; // type:object size:0x18 -lbl_804A3BA8 = .bss:0x804A3BA8; // type:object size:0x8 data:4byte -lbl_804A3BB0 = .bss:0x804A3BB0; // type:object size:0xC8 -lbl_804A3C78 = .bss:0x804A3C78; // type:object size:0xC0 -lbl_804A3D38 = .bss:0x804A3D38; // type:object size:0x10 -lbl_804A3D48 = .bss:0x804A3D48; // type:object size:0x8 data:4byte +sAllocator = .bss:0x804A3B78; // type:object size:0x10 scope:local +spHomeButtonObj__Q210homebutton10HomeButton = .bss:0x804A3B88; // type:object size:0x4 data:4byte +sMutex__Q210homebutton10HomeButton = .bss:0x804A3B90; // type:object size:0x18 +suIDCounter__Q310homebutton3gui11PaneManager = .bss:0x804A3BA8; // type:object size:0x4 data:4byte +sBatteryFlag__Q210homebutton10Controller = .bss:0x804A3BB0; // type:object size:0x4 +...bss.0 = .bss:0x804A3BB0; // type:label scope:local +sAlarm__Q210homebutton10Controller = .bss:0x804A3BB8; // type:object size:0xC0 scope:global +sAlarmSoundOff__Q210homebutton10Controller = .bss:0x804A3C78; // type:object size:0xC0 +sThis__Q210homebutton10Controller = .bss:0x804A3D38; // type:object size:0x10 +spInstance__Q210homebutton9RemoteSpk = .bss:0x804A3D48; // type:object size:0x4 data:4byte lbl_804A3D50 = .bss:0x804A3D50; // type:object size:0x50 data:4byte lbl_804A3DA0 = .bss:0x804A3DA0; // type:object size:0x10 lbl_804A3DB0 = .bss:0x804A3DB0; // type:object size:0x30 @@ -23423,8 +23484,8 @@ lbl_804C1558 = .sdata2:0x804C1558; // type:object size:0x4 align:4 data:float lbl_804C155C = .sdata2:0x804C155C; // type:object size:0x4 align:4 data:float lbl_804C1560 = .sdata2:0x804C1560; // type:object size:0x4 align:4 data:float lbl_804C1564 = .sdata2:0x804C1564; // type:object size:0x4 align:4 data:float -lbl_804C1568 = .sdata2:0x804C1568; // type:object size:0x4 align:4 data:float -lbl_804C156C = .sdata2:0x804C156C; // type:object size:0x4 align:4 data:float +@8740 = .sdata2:0x804C1568; // type:object size:0x4 scope:local align:4 data:float +@8741 = .sdata2:0x804C156C; // type:object size:0x4 scope:local align:4 data:float lbl_804C1570 = .sdata2:0x804C1570; // type:object size:0x4 align:4 data:float lbl_804C1574 = .sdata2:0x804C1574; // type:object size:0x4 align:4 data:float lbl_804C1578 = .sdata2:0x804C1578; // type:object size:0x1 data:byte @@ -23546,11 +23607,11 @@ lbl_804C1788 = .sdata2:0x804C1788; // type:object size:0x4 align:4 data:float lbl_804C178C = .sdata2:0x804C178C; // type:object size:0x4 align:4 data:float lbl_804C1790 = .sdata2:0x804C1790; // type:object size:0x4 align:4 data:float lbl_804C1794 = .sdata2:0x804C1794; // type:object size:0x4 align:4 data:float -lbl_804C1798 = .sdata2:0x804C1798; // type:object size:0x4 align:4 data:float -lbl_804C179C = .sdata2:0x804C179C; // type:object size:0x4 align:4 data:float -lbl_804C17A0 = .sdata2:0x804C17A0; // type:object size:0x4 align:4 data:float -lbl_804C17A4 = .sdata2:0x804C17A4; // type:object size:0x4 align:4 data:float -lbl_804C17A8 = .sdata2:0x804C17A8; // type:object size:0x4 align:4 data:float +@20967 = .sdata2:0x804C1798; // type:object size:0x4 scope:local align:4 data:float +@21005 = .sdata2:0x804C179C; // type:object size:0x4 scope:local align:4 data:float +@21006 = .sdata2:0x804C17A0; // type:object size:0x4 scope:local align:4 data:float +@21007 = .sdata2:0x804C17A4; // type:object size:0x4 scope:local align:4 data:float +@21008 = .sdata2:0x804C17A8; // type:object size:0x4 scope:local align:4 data:float gap_12_804C17AC_sdata2 = .sdata2:0x804C17AC; // type:object size:0x4 scope:global lbl_804C17B0 = .sdata2:0x804C17B0; // type:object size:0x8 align:8 data:double lbl_804C17B8 = .sdata2:0x804C17B8; // type:object size:0x4 align:4 data:float