diff --git a/.clang-format b/.clang-format index fe3619d35..f7bfc994e 100644 --- a/.clang-format +++ b/.clang-format @@ -5,10 +5,11 @@ Standard: Cpp03 AccessModifierOffset: -4 AllowShortFunctionsOnASingleLine: Empty -AttributeMacros: [DECOMP_INLINE, DECOMP_DONT_INLINE] +AttributeMacros: + [DECOMP_INLINE, DECOMP_DONT_INLINE, NW4R_EF_MEMORY_MANAGER_MEMBER_ACCESS] ConstructorInitializerAllOnOneLineOrOnePerLine: true FixNamespaceComments: true -ForEachMacros: [EGG_NW4R_LIST_FOREACH] +ForEachMacros: [EGG_NW4R_LIST_FOREACH, RP_NW4R_LIST_FOREACH] IncludeBlocks: Regroup IndentWidth: 4 InsertNewlineAtEOF: true @@ -36,6 +37,7 @@ WhitespaceSensitiveMacros: NW4R_UT_LINKLIST_FOREACH_SAFE, NW4R_UT_LIST_FOREACH_SAFE, NW4R_UT_LIST_FOREACH, + RP_NW4R_LIST_FOREACH, ] IncludeCategories: diff --git a/.clangd b/.clangd new file mode 100644 index 000000000..3ac0da921 --- /dev/null +++ b/.clangd @@ -0,0 +1,2 @@ +CompileFlags: + Add: -ferror-limit=100 diff --git a/.vscode/settings.json b/.vscode/settings.json index 10b4bb311..46c5e397c 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -10,7 +10,12 @@ "[python]": { "editor.defaultFormatter": "ms-python.black-formatter" }, - "C_Cpp.default.defines": ["IEEE_LIBM", "REVOLUTION", "PACK_SPORTS"], + "C_Cpp.default.defines": [ + "IEEE_LIBM", + "REVOLUTION", + "PACK_SPORTS", + "NW4R_EF_MEMORY_MANAGER_CONFIGURED" + ], // "editor.tabSize": 4, // "files.autoSave": "onFocusChange", "files.insertFinalNewline": true, diff --git a/README.md b/README.md index f4f87bcf8..3e4cb04f4 100644 --- a/README.md +++ b/README.md @@ -67,11 +67,6 @@ ensure consistency across the codebase and its documentation. > - Source code leaked online, pertaining to any software libraries linked > within this game > - Source code acquired through means only intended for licensed developers, such as a software development kit (SDK) distribution -> -> Due to concerns of leaked material in training sets, decompilation created by or with the assistance of large language models (LLMs) will not be accepted. -> -> As such, reviewers reserve the right to make the final call on whether to accept contributions. -> > [!IMPORTANT] > "Leaked material" does **NOT** include debugging information **left behind in retail games**, such as: @@ -80,3 +75,11 @@ ensure consistency across the codebase and its documentation. > - Debug builds of the executable > - Binary object files (`*.o`), and static libraries (`*.a`) that may contain them + +## AI/LLM Policy + +Due to concerns of leaked material in training sets, decompilation of SDK code created by or with the assistance of large language models (LLMs) **will not be accepted**. The use of such tools is permitted for game code (Pack Project engine) only, with some restrictions. + +The main goal of this repo is to produce sensible, maintainable source code. Pull requests containing heavy use of raw pointer arithmetic and other non-portable expressions may still be rejected when the future effort required for refactoring is deemed to be too much. + +**As such, project leads reserve the right to make the final call on whether to accept these types of contributions.** diff --git a/config/RSPE01_01/splits.txt b/config/RSPE01_01/splits.txt index 9d551c0d2..980e5afd3 100644 --- a/config/RSPE01_01/splits.txt +++ b/config/RSPE01_01/splits.txt @@ -3431,15 +3431,92 @@ Pack/RPUtility/RPUtlDohMath.cpp: .sbss start:0x804BF660 end:0x804BF668 .sdata2 start:0x804C19A0 end:0x804C19B0 +Pack/RPUtility/RPUtlRigid.cpp: + .text start:0x801B9EC0 end:0x801BAF60 + .data start:0x803C1720 end:0x803C1748 + .sdata2 start:0x804C19B0 end:0x804C19D0 + +Pack/RPUtility/RPUtlAccAnalyzer.cpp: + .text start:0x801BAF60 end:0x801BB9B8 + .ctors start:0x80355140 end:0x80355144 + .data start:0x803C1748 end:0x803C17C8 + .bss start:0x804A4750 end:0x804A4770 + .sdata start:0x804BDC18 end:0x804BDC20 + .sdata2 start:0x804C19D0 end:0x804C19F0 + +Pack/RPUtility/RPUtlCollisionModel.cpp: + .text start:0x801BB9B8 end:0x801BC384 + .sdata2 start:0x804C19F0 end:0x804C19F8 + +Pack/RPUtility/RP_DEBUG_STUB_2.cpp: + .text start:0x801BC384 end:0x801BC418 + .data start:0x803C17C8 end:0x803C17D8 + +Pack/RPUtility/RPUtlCollisionChecker.cpp: + .text start:0x801BC418 end:0x801BD51C + .sdata2 start:0x804C19F8 end:0x804C1A08 + +Pack/RPUtility/RPUtlSimpleShadow.cpp: + .text start:0x801BD51C end:0x801BD648 + .sdata2 start:0x804C1A08 end:0x804C1A20 + +Pack/RPUtility/RPUtlGameResourceMgr.cpp: + .text start:0x801BD648 end:0x801BD7E0 + .data start:0x803C17D8 end:0x803C17E8 + .sbss start:0x804BF668 end:0x804BF670 + +Pack/RPUtility/RPUtlDirMath.cpp: + .text start:0x801BD7E0 end:0x801BE340 + .ctors start:0x80355144 end:0x80355148 + .bss start:0x804A4770 end:0x804A4800 + .sbss start:0x804BF670 end:0x804BF678 + .sdata2 start:0x804C1A20 end:0x804C1A38 + +Pack/RPUtility/RPUtlRand.cpp: + .sbss start:0x804BF678 end:0x804BF680 + +Pack/RPUtility/RPUtlModel.cpp: + .text start:0x801BE340 end:0x801BE574 + .data start:0x803C17E8 end:0x803C17F8 + .sbss start:0x804BF680 end:0x804BF688 + +Pack/RPUtility/RPUtlViewClipper.cpp: + .text start:0x801BE574 end:0x801BEA28 + .sdata2 start:0x804C1A38 end:0x804C1A50 + +Pack/RPUtility/RPUtlRandom.cpp: + .text start:0x801BEA28 end:0x801BEA7C + .sbss start:0x804BF688 end:0x804BF690 + .sdata2 start:0x804C1A50 end:0x804C1A60 + +Pack/RPUtility/RPUtlMath.cpp: + .text start:0x801BEA7C end:0x801BF564 + .sdata2 start:0x804C1A60 end:0x804C1A90 + +Pack/RPUtility/RPUtlMapData.cpp: + .text start:0x801BF564 end:0x801BF9D0 + +Pack/RPUtility/RPUtlShadowDrawer.cpp: + .text start:0x801BF9D0 end:0x801BFAE4 + .ctors start:0x80355148 end:0x8035514C + .bss start:0x804A4800 end:0x804A4830 + +Pack/RPUtility/RPUtlObject.cpp: + .text start:0x801BFAE4 end:0x801BFEA8 + .ctors start:0x8035514C end:0x80355150 + .data start:0x803C17F8 end:0x803C1820 + .bss start:0x804A4830 end:0x804A4848 + .sbss start:0x804BF690 end:0x804BF698 + Pack/RPUtility_unsplit.o: - .text start:0x801B9EC0 end:0x801CCB70 - .ctors start:0x80355140 end:0x80355160 + .text start:0x801BFEA8 end:0x801CCB70 + .ctors start:0x80355150 end:0x80355160 .rodata start:0x803837E8 end:0x80383990 - .data start:0x803C1720 end:0x803C1BF0 - .bss start:0x804A4750 end:0x804A48A0 - .sdata start:0x804BDC18 end:0x804BDC38 - .sbss start:0x804BF668 end:0x804BF6F0 - .sdata2 start:0x804C19B0 end:0x804C1A20 + .data start:0x803C1820 end:0x803C1BF0 + .bss start:0x804A4848 end:0x804A48A0 + .sdata start:0x804BDC20 end:0x804BDC38 + .sbss start:0x804BF698 end:0x804BF6F0 + .sdata2 start:0x804C1A90 end:0x804C1C98 Pack/RPSports/RPSportsCommon/RPSportsCommon_unsplit.o: .text start:0x801CCB70 end:0x80214480 @@ -3449,7 +3526,7 @@ Pack/RPSports/RPSportsCommon/RPSportsCommon_unsplit.o: .bss start:0x804A48A0 end:0x804A6000 .sdata start:0x804BDC38 end:0x804BDDD0 .sbss start:0x804BF6F0 end:0x804BF768 - .sdata2 start:0x804C1A20 end:0x804C2338 + .sdata2 start:0x804C1C98 end:0x804C2338 Pack/RPSports/RPTnsScene/RPTnsScene_unsplit.o: .text start:0x80214480 end:0x8024E334 @@ -3471,15 +3548,169 @@ Pack/RPSports/RPBsbScene/RPBsbScene_unsplit.o: .sbss start:0x804BF778 end:0x804BF850 .sdata2 start:0x804C32A8 end:0x804C3E80 +Pack/RPSports/RPGolScene/RPGolScene.cpp: + .text start:0x8028DF74 end:0x8028E098 + .data start:0x803C7718 end:0x803C7798 + +Pack/RPSports/RPGolScene/RPGolMain.cpp: + .text start:0x8028E098 end:0x8028E900 + .rodata start:0x8038E250 end:0x8038E2B0 + .data start:0x803C7798 end:0x803C77C0 + .sbss start:0x804BF850 end:0x804BF858 + .sdata2 start:0x804C3E80 end:0x804C3EA8 + +Pack/RPSports/RPGolScene/RPGolResourceManager.cpp: + .text start:0x8028E900 end:0x8028EAE0 + .data start:0x803C77C0 end:0x803C77D0 + .sbss start:0x804BF858 end:0x804BF860 + +Pack/RPSports/RPGolScene/RPGolCameraManager.cpp: + .text start:0x8028EAE0 end:0x8028F9FC + .data start:0x803C77D0 end:0x803C77E8 + .sbss start:0x804BF860 end:0x804BF868 + .sdata2 start:0x804C3EA8 end:0x804C3ED0 + +Pack/RPSports/RPGolScene/RPGolMapObjBase.cpp: + .text start:0x8028F9FC end:0x80290B44 + .ctors start:0x803551F4 end:0x803551F8 + .data start:0x803C77E8 end:0x803C77F8 + .sdata2 start:0x804C3ED0 end:0x804C3ED8 + +Pack/RPSports/RPGolScene/RPGolFieldManager.cpp: + .text start:0x80290B44 end:0x80294184 + .ctors start:0x803551F8 end:0x803551FC + .rodata start:0x8038E2B0 end:0x8038E4A0 + .data start:0x803C77F8 end:0x803C78E8 + .sdata start:0x804BE818 end:0x804BE830 + .sbss start:0x804BF868 end:0x804BF870 + .sdata2 start:0x804C3ED8 end:0x804C3F70 + +Pack/RPSports/RPGolScene/RPGolDrawManager.cpp: + .text start:0x80294184 end:0x8029528C + .data start:0x803C78E8 end:0x803C78F8 + .sbss start:0x804BF870 end:0x804BF878 + .sdata2 start:0x804C3F70 end:0x804C3FA8 + +Pack/RPSports/RPGolScene/RPGolUtlMtx.cpp: + .text start:0x8029528C end:0x80295CB0 + .ctors start:0x803551FC end:0x80355200 + .bss start:0x804A8900 end:0x804A8960 + .sdata2 start:0x804C3FA8 end:0x804C3FC0 + +Pack/RPSports/RPGolScene/RPGolUtlVec.cpp: + .text start:0x80295CB0 end:0x80296238 + .ctors start:0x80355200 end:0x80355204 + .bss start:0x804A8960 end:0x804A8AC0 + .sdata2 start:0x804C3FC0 end:0x804C3FE0 + +Pack/RPSports/RPGolScene/RPGolMapObjTree.cpp: + .text start:0x80296238 end:0x80296EA8 + .rodata start:0x8038E4A0 end:0x8038E4E8 + .data start:0x803C78F8 end:0x803C7908 + .sdata2 start:0x804C3FE0 end:0x804C4030 + +Pack/RPSports/RPGolScene/RPGolMapObjTreeWater.cpp: + .text start:0x80296EA8 end:0x80296F50 + .rodata start:0x8038E4E8 end:0x8038E510 + +Pack/RPSports/RPGolScene/RPGolMapObjTee.cpp: + .text start:0x80296F50 end:0x80296FD8 + .data start:0x803C7908 end:0x803C7918 + +Pack/RPSports/RPGolScene/RPGolMapObjBall.cpp: + .text start:0x80296FD8 end:0x8029B240 + .rodata start:0x8038E510 end:0x8038E610 + .data start:0x803C7918 end:0x803C7A50 + .bss start:0x804A8AC0 end:0x804A8B48 + .sdata start:0x804BE830 end:0x804BE848 + .sbss start:0x804BF878 end:0x804BF890 + .sdata2 start:0x804C4030 end:0x804C4108 + +Pack/RPSports/RPGolScene/RPGolSimulateManager.cpp: + .text start:0x8029B240 end:0x8029BBB4 + .data start:0x803C7A50 end:0x803C7A60 + .sbss start:0x804BF890 end:0x804BF898 + .sdata2 start:0x804C4108 end:0x804C4110 + +Pack/RPSports/RPGolScene/RPGolCamera.cpp: + .text start:0x8029BBB4 end:0x8029C2F8 + .data start:0x803C7A60 end:0x803C7A80 + .sbss start:0x804BF898 end:0x804BF8B8 + .sdata2 start:0x804C4110 end:0x804C4140 + +Pack/RPSports/RPGolScene/RPGolCameraStatic.cpp: + .text start:0x8029C2F8 end:0x8029CA4C + .ctors start:0x80355204 end:0x80355208 + .data start:0x803C7A80 end:0x803C7AA0 + .sbss start:0x804BF8B8 end:0x804BF8C0 + .sdata2 start:0x804C4140 end:0x804C41A0 + +Pack/RPSports/RPGolScene/RPGolConfig.cpp: + .text start:0x8029CA4C end:0x8029E62C + .ctors start:0x80355208 end:0x8035520C + .rodata start:0x8038E610 end:0x8038E658 + .data start:0x803C7AA0 end:0x803C7CC8 + .bss start:0x804A8B48 end:0x804A8BA0 + .sdata start:0x804BE848 end:0x804BE858 + .sbss start:0x804BF8C0 end:0x804BF8C8 + .sdata2 start:0x804C41A0 end:0x804C4228 + +Pack/RPSports/RPGolScene/RPGolPlayer.cpp: + .text start:0x8029E62C end:0x802A2210 + .ctors start:0x8035520C end:0x80355210 + .data start:0x803C7CC8 end:0x803C7DD0 + .sbss start:0x804BF8C8 end:0x804BF8D0 + .sdata2 start:0x804C4228 end:0x804C42B8 + +Pack/RPSports/RPGolScene/RPGolPlayerManager.cpp: + .text start:0x802A2210 end:0x802A3560 + .rodata start:0x8038E658 end:0x8038E698 + .data start:0x803C7DD0 end:0x803C7DE0 + .sbss start:0x804BF8D0 end:0x804BF8D8 + .sdata2 start:0x804C42B8 end:0x804C42E0 + +Pack/RPSports/RPGolScene/RPGolMath.cpp: + .text start:0x802A3560 end:0x802A3A6C + .ctors start:0x80355210 end:0x80355214 + .bss start:0x804A8BA0 end:0x804A8BB8 + .sbss start:0x804BF8D8 end:0x804BF8E8 + .sdata2 start:0x804C42E0 end:0x804C42F8 + +Pack/RPSports/RPGolScene/RPGol_802a3a6c.cpp: + .text start:0x802A3A6C end:0x802A3B84 + .ctors start:0x80355214 end:0x80355218 + .bss start:0x804A8BB8 end:0x804A8CD0 + .sbss start:0x804BF8E8 end:0x804BF8F0 + .sdata2 start:0x804C42F8 end:0x804C4300 + +Pack/RPSports/RPGolScene/RPGolMathTrig.cpp: + .text start:0x802A3B84 end:0x802A3DE4 + .sdata2 start:0x804C4300 end:0x804C4318 + +Pack/RPSports/RPGolScene/RPGolKCol.cpp: + .text start:0x802A3DE4 end:0x802A7444 + .ctors start:0x80355218 end:0x8035521C + .data start:0x803C7DE0 end:0x803C7DF0 + .bss start:0x804A8CD0 end:0x804A8D68 + .sbss start:0x804BF8F0 end:0x804BF8F8 + .sdata2 start:0x804C4318 end:0x804C4338 + +Pack/RPSports/RPGolScene/RPGolCameraTilt.cpp: + .text start:0x802A7444 end:0x802A79F8 + .ctors start:0x8035521C end:0x80355220 + .data start:0x803C7DF0 end:0x803C7E10 + .sbss start:0x804BF8F8 end:0x804BF900 + .sdata2 start:0x804C4338 end:0x804C4388 + Pack/RPSports/RPGolScene/RPGolScene_unsplit.o: - .text start:0x8028DF74 end:0x802C7924 - .ctors start:0x803551F4 end:0x8035522C - .rodata start:0x8038E250 end:0x8038FB10 - .data start:0x803C7718 end:0x803C8958 - .bss start:0x804A8900 end:0x804A92D0 - .sdata start:0x804BE818 end:0x804BE8D0 - .sbss start:0x804BF850 end:0x804BF958 - .sdata2 start:0x804C3E80 end:0x804C4CB8 + .text start:0x802A79F8 end:0x802C7924 + .ctors start:0x80355220 end:0x8035522C + .rodata start:0x8038E698 end:0x8038FB10 + .data start:0x803C7E10 end:0x803C8958 + .bss start:0x804A8D68 end:0x804A92D0 + .sdata start:0x804BE858 end:0x804BE8D0 + .sbss start:0x804BF900 end:0x804BF958 + .sdata2 start:0x804C4388 end:0x804C4CB8 Pack/RPSports/RPBoxScene/RPBoxScene_unsplit.o: .text start:0x802C7924 end:0x80313028 @@ -3491,12 +3722,262 @@ Pack/RPSports/RPBoxScene/RPBoxScene_unsplit.o: .sbss start:0x804BF958 end:0x804BF998 .sdata2 start:0x804C4CB8 end:0x804C5AC0 -Pack/RPSports/RPBowScene/RPBowScene_unsplit.o: - .text start:0x80313028 end:0x8035507C - .ctors start:0x8035524C end:0x8035525C - .rodata start:0x80392190 end:0x80393A70 - .data start:0x803CA1B8 end:0x803CAF00 - .bss start:0x804A9DE8 end:0x804BD36C - .sdata start:0x804BE968 end:0x804BE9D0 +Pack/RPSports/RPBowScene/RPBow_80313028.cpp: + .text start:0x80313028 end:0x80315998 + .rodata start:0x80392190 end:0x803924A0 + .data start:0x803CA1B8 end:0x803CA940 .sbss start:0x804BF998 end:0x804BFA10 - .sdata2 start:0x804C5AC0 end:0x804C69D0 + .sdata2 start:0x804C5AC0 end:0x804C5B00 + +Pack/RPSports/RPBowScene/RPBow_80315998.cpp: + .text start:0x80315998 end:0x8031641C + .sdata2 start:0x804C5B00 end:0x804C5B48 + +Pack/RPSports/RPBowScene/RPBow_8031641C.cpp: + .text start:0x8031641C end:0x80319C98 + .rodata start:0x803924A0 end:0x803929C8 + .data start:0x803CA940 end:0x803CAF00 + .sdata2 start:0x804C5B48 end:0x804C5B80 + +Pack/RPSports/RPBowScene/RPBow_80319C98.cpp: + .text start:0x80319C98 end:0x8031C388 + .sdata2 start:0x804C5B80 end:0x804C5CB8 + +Pack/RPSports/RPBowScene/RPBowSwing.cpp: + .text start:0x8031C388 end:0x8031ECB4 + .sdata2 start:0x804C5CB8 end:0x804C5D28 + +Pack/RPSports/RPBowScene/RPBow_8031C388.cpp: + .text start:0x8031ECB4 end:0x8031EFE4 + .rodata start:0x803929C8 end:0x803929E0 + .sdata2 start:0x804C5D28 end:0x804C5D30 + +Pack/RPSports/RPBowScene/RPBow_8031EFE4.cpp: + .text start:0x8031EFE4 end:0x80320EFC + .sdata2 start:0x804C5D30 end:0x804C5DC8 + +Pack/RPSports/RPBowScene/RPBow_80320EFC.cpp: + .text start:0x80320EFC end:0x80323790 + .rodata start:0x803929E0 end:0x80392A80 + .sdata2 start:0x804C5DC8 end:0x804C5EF8 + +Pack/RPSports/RPBowScene/RPBow_80323790.cpp: + .text start:0x80323790 end:0x80327F0C + .ctors start:0x8035524C end:0x80355250 + .rodata start:0x80392A80 end:0x80392B20 + .bss start:0x804A9DE8 end:0x804BC218 + .sdata2 start:0x804C5EF8 end:0x804C6078 + +Pack/RPSports/RPBowScene/RPBow_80327F0C.cpp: + .text start:0x80327F0C end:0x80329350 + .sdata2 start:0x804C6078 end:0x804C6098 + +Pack/RPSports/RPBowScene/RPBow_80329350.cpp: + .text start:0x80329350 end:0x80329658 + +Pack/RPSports/RPBowScene/RPBow_80329658.cpp: + .text start:0x80329658 end:0x8032A9E8 + .rodata start:0x80392B20 end:0x80392B30 + .sdata2 start:0x804C6098 end:0x804C60E0 + +Pack/RPSports/RPBowScene/RPBowActiveBall.cpp: + .text start:0x8032A9E8 end:0x8032ADD8 + .sdata2 start:0x804C60E0 end:0x804C6100 + +Pack/RPSports/RPBowScene/RPBow_8032ADD8.cpp: + .text start:0x8032ADD8 end:0x8032EA58 + .rodata start:0x80392B30 end:0x80392B58 + .sdata2 start:0x804C6100 end:0x804C6158 + +Pack/RPSports/RPBowScene/RPBow_8032EA58.cpp: + .text start:0x8032EA58 end:0x80330830 + .rodata start:0x80392B58 end:0x80392C08 + .bss start:0x804BC218 end:0x804BD2E8 + .sdata2 start:0x804C6158 end:0x804C6178 + +Pack/RPSports/RPBowScene/RPBowGlobalLaneManager.cpp: + .text start:0x80330830 end:0x80330EBC + .sdata2 start:0x804C6178 end:0x804C6180 + +Pack/RPSports/RPBowScene/RPBow_80330EBC.cpp: + .text start:0x80330EBC end:0x80330FE8 + .sdata2 start:0x804C6180 end:0x804C6188 + +Pack/RPSports/RPBowScene/RPBow_80330FE8.cpp: + .text start:0x80330FE8 end:0x80331654 + .sdata2 start:0x804C6188 end:0x804C61B8 + +Pack/RPSports/RPBowScene/RPBowNpcManager.cpp: + .text start:0x80331654 end:0x803327FC + .sdata2 start:0x804C61B8 end:0x804C61C8 + +Pack/RPSports/RPBowScene/RPBowManagerContext.cpp: + .text start:0x803327FC end:0x80332C24 + .rodata start:0x80392C08 end:0x80392CC0 + .bss start:0x804BD2E8 end:0x804BD328 + .sdata2 start:0x804C61C8 end:0x804C61D8 + +Pack/RPSports/RPBowScene/RPBow_80332C24.cpp: + .text start:0x80332C24 end:0x80332D14 + +Pack/RPSports/RPBowScene/RPBow_80332D14.cpp: + .text start:0x80332D14 end:0x803345F0 + .sdata2 start:0x804C61D8 end:0x804C6260 + +Pack/RPSports/RPBowScene/RPBowPinSetter.cpp: + .text start:0x803345F0 end:0x803349E0 + .sdata2 start:0x804C6260 end:0x804C6288 + +Pack/RPSports/RPBowScene/RPBow_803349E0.cpp: + .text start:0x803349E0 end:0x803363D0 + .rodata start:0x80392CC0 end:0x80392D28 + .sdata2 start:0x804C6288 end:0x804C62A0 + +Pack/RPSports/RPBowScene/RPBow_803363D0.cpp: + .text start:0x803363D0 end:0x803381DC + .sdata2 start:0x804C62A0 end:0x804C62B8 + +Pack/RPSports/RPBowScene/RPBow_803381DC.cpp: + .text start:0x803381DC end:0x8033A558 + .sdata2 start:0x804C62B8 end:0x804C6320 + +Pack/RPSports/RPBowScene/RPBow_8033A558.cpp: + .text start:0x8033A558 end:0x8033B690 + .rodata start:0x80392D28 end:0x80392EE8 + .sdata2 start:0x804C6320 end:0x804C6390 + +Pack/RPSports/RPBowScene/RPBow_8033B690.cpp: + .text start:0x8033B690 end:0x8033FD0C + .rodata start:0x80392EE8 end:0x80392EF8 + .sdata2 start:0x804C6390 end:0x804C6440 + +Pack/RPSports/RPBowScene/RPBow_8033FD0C.cpp: + .text start:0x8033FD0C end:0x80340308 + .sdata2 start:0x804C6440 end:0x804C6450 + +Pack/RPSports/RPBowScene/RPBowObstacleManager.cpp: + .text start:0x80340308 end:0x80340C34 + .rodata start:0x80392EF8 end:0x803930D0 + .sdata2 start:0x804C6450 end:0x804C6478 + +Pack/RPSports/RPBowScene/RPBow_80340C34.cpp: + .text start:0x80340C34 end:0x803433E4 + .rodata start:0x803930D0 end:0x803930E8 + .sdata2 start:0x804C6478 end:0x804C64D8 + +Pack/RPSports/RPBowScene/RPBow_803433E4.cpp: + .text start:0x803433E4 end:0x8034656C + .rodata start:0x803930E8 end:0x80393168 + .sdata2 start:0x804C64D8 end:0x804C6518 + +Pack/RPSports/RPBowScene/RPBow_8034656C.cpp: + .text start:0x8034656C end:0x80346E60 + .ctors start:0x80355250 end:0x80355254 + .rodata start:0x80393168 end:0x80393180 + .sdata2 start:0x804C6518 end:0x804C65C0 + +Pack/RPSports/RPBowScene/RPBowPlayerLaneNpc.cpp: + .text start:0x80346E60 end:0x80347574 + .sdata2 start:0x804C65C0 end:0x804C65EC + +Pack/RPSports/RPBowScene/RPBow_80347574.cpp: + .text start:0x80347574 end:0x80347D0C + .ctors start:0x80355254 end:0x80355258 + .rodata start:0x80393180 end:0x803931A0 + .sdata2 start:0x804C65EC end:0x804C6610 + +Pack/RPSports/RPBowScene/RPBow_80347D0C.cpp: + .text start:0x80347D0C end:0x80348158 + .rodata start:0x803931A0 end:0x803931C0 + .sdata2 start:0x804C6610 end:0x804C6628 + +Pack/RPSports/RPBowScene/RPBow_80348158.cpp: + .text start:0x80348158 end:0x80348858 + .rodata start:0x803931C0 end:0x80393350 + .sdata2 start:0x804C6628 end:0x804C6660 + +Pack/RPSports/RPBowScene/RPBow_80348858.cpp: + .text start:0x80348858 end:0x8034C1AC + .sdata2 start:0x804C6660 end:0x804C67C8 + +Pack/RPSports/RPBowScene/RPBow_8034C1AC.cpp: + .text start:0x8034C1AC end:0x8034C95C + .sdata2 start:0x804C67C8 end:0x804C67E0 + +Pack/RPSports/RPBowScene/RPBow_8034C95C.cpp: + .text start:0x8034C95C end:0x8034D128 + .sdata2 start:0x804C67E0 end:0x804C6838 + +Pack/RPSports/RPBowScene/RPBowMotionBlur.cpp: + .text start:0x8034D128 end:0x8034D4F4 + .sdata2 start:0x804C6838 end:0x804C6848 + +Pack/RPSports/RPBowScene/RPBowBallReturnRack.cpp: + .text start:0x8034D4F4 end:0x8034DD08 + .sdata2 start:0x804C6848 end:0x804C6898 + +Pack/RPSports/RPBowScene/RPBowBackgroundNpcManager.cpp: + .text start:0x8034DD08 end:0x8034E974 + .ctors start:0x80355258 end:0x8035525C + .bss start:0x804BD328 end:0x804BD36C + .sdata2 start:0x804C6898 end:0x804C68F8 + +Pack/RPSports/RPBowScene/RPBow_8034E974.cpp: + .text start:0x8034E974 end:0x8034F710 + .rodata start:0x80393350 end:0x80393360 + .sdata2 start:0x804C68F8 end:0x804C6930 + +Pack/RPSports/RPBowScene/RPBow_8034F710.cpp: + .text start:0x8034F710 end:0x803501D8 + .rodata start:0x80393360 end:0x80393398 + .sdata2 start:0x804C6930 end:0x804C6948 + +Pack/RPSports/RPBowScene/RPBow_803501D8.cpp: + .text start:0x803501D8 end:0x80350F78 + .sdata2 start:0x804C6948 end:0x804C6950 + +Pack/RPSports/RPBowScene/RPBow_80350F78.cpp: + .text start:0x80350F78 end:0x80351D58 + .rodata start:0x80393398 end:0x80393578 + .sdata start:0x804BE968 end:0x804BE9D0 + .sdata2 start:0x804C6950 end:0x804C6968 + +Pack/RPSports/RPBowScene/RPBow_80351D58.cpp: + .text start:0x80351D58 end:0x803520F0 + .sdata2 start:0x804C6968 end:0x804C6970 + +Pack/RPSports/RPBowScene/RPBow_803520F0.cpp: + .text start:0x803520F0 end:0x80353214 + .rodata start:0x80393578 end:0x803937C0 + .sdata2 start:0x804C6970 end:0x804C6978 + +Pack/RPSports/RPBowScene/RPBow_80353214.cpp: + .text start:0x80353214 end:0x803536C4 + .rodata start:0x803937C0 end:0x80393848 + .sdata2 start:0x804C6978 end:0x804C6980 + +Pack/RPSports/RPBowScene/RPBow_803536C4.cpp: + .text start:0x803536C4 end:0x80353C8C + .rodata start:0x80393848 end:0x803938C8 + .sdata2 start:0x804C6980 end:0x804C6988 + +Pack/RPSports/RPBowScene/RPBow_80353C8C.cpp: + .text start:0x80353C8C end:0x803543A8 + .rodata start:0x803938C8 end:0x803939F0 + .sdata2 start:0x804C6988 end:0x804C6998 + +Pack/RPSports/RPBowScene/RPBowTrajectoryGuide.cpp: + .text start:0x803543A8 end:0x803547A4 + .sdata2 start:0x804C6998 end:0x804C69C0 + +Pack/RPSports/RPBowScene/RPBow_803547A4.cpp: + .text start:0x803547A4 end:0x80354C78 + +Pack/RPSports/RPBowScene/RPBow_80354C78.cpp: + .text start:0x80354C78 end:0x80354CAC + .sdata2 start:0x804C69C0 end:0x804C69C8 + +Pack/RPSports/RPBowScene/RPBow_80354CAC.cpp: + .text start:0x80354CAC end:0x8035507C + .rodata start:0x803939F0 end:0x80393A70 + .sdata2 start:0x804C69C8 end:0x804C69D0 diff --git a/config/RSPE01_01/symbols.txt b/config/RSPE01_01/symbols.txt index 1c230d2e4..397a537ea 100644 --- a/config/RSPE01_01/symbols.txt +++ b/config/RSPE01_01/symbols.txt @@ -6834,41 +6834,41 @@ Play__Q210homebutton9RemoteSpkFliSc = .text:0x80182AAC; // type:function size:0x isPlaying__Q210homebutton9RemoteSpkCFl = .text:0x80182B44; // type:function size:0x1C scope:global isPlayingId__Q210homebutton9RemoteSpkCFli = .text:0x80182B60; // type:function size:0x30 scope:global isPlayReady__Q210homebutton9RemoteSpkCFl = .text:0x80182B90; // type:function size:0x1C -fn_80182BAC = .text:0x80182BAC; // type:function size:0xC -fn_80182BB8 = .text:0x80182BB8; // type:function size:0x70 -fn_80182C28 = .text:0x80182C28; // type:function size:0x34 +shutdownSystemCallBack__11RPSysSystemFv = .text:0x80182BAC; // type:function size:0xC +softResetCallBack__11RPSysSystemFv = .text:0x80182BB8; // type:function size:0x70 +setCallBack__11RPSysSystemFv = .text:0x80182C28; // type:function size:0x34 fn_80182C5C = .text:0x80182C5C; // type:function size:0xA0 -fn_80182CFC = .text:0x80182CFC; // type:function size:0xA8 +setupLocalSettings__11RPSysSystemFv = .text:0x80182CFC; // type:function size:0xA8 fn_80182DA4 = .text:0x80182DA4; // type:function size:0x148 fn_80182EEC = .text:0x80182EEC; // type:function size:0x1B0 fn_8018309C = .text:0x8018309C; // type:function size:0xDC fn_80183178 = .text:0x80183178; // type:function size:0x40 -fn_801831B8 = .text:0x801831B8; // type:function size:0x8 -fn_801831C0 = .text:0x801831C0; // type:function size:0x8 -fn_801831C8 = .text:0x801831C8; // type:function size:0x8 -fn_801831D0 = .text:0x801831D0; // type:function size:0x8 -fn_801831D8 = .text:0x801831D8; // type:function size:0x8 -fn_801831E0 = .text:0x801831E0; // type:function size:0x8 -fn_801831E8 = .text:0x801831E8; // type:function size:0x8 +getTimeStampString__11RPSysSystemFv = .text:0x801831B8; // type:function size:0x8 +getDvdEndMessage__11RPSysSystemCFv = .text:0x801831C0; // type:function size:0x8 +getNandEndMessage__11RPSysSystemCFv = .text:0x801831C8; // type:function size:0x8 +getWc24Thread__11RPSysSystemFv = .text:0x801831D0; // type:function size:0x8 +getDvdThread__11RPSysSystemFv = .text:0x801831D8; // type:function size:0x8 +getNandThread__11RPSysSystemFv = .text:0x801831E0; // type:function size:0x8 +setDimming__11RPSysSystemFi = .text:0x801831E8; // type:function size:0x8 systemShutDown__11RPSysSystemFv = .text:0x801831F0; // type:function size:0xD8 fn_801832C8 = .text:0x801832C8; // type:function size:0x28 fn_801832F0 = .text:0x801832F0; // type:function size:0x18 -fn_80183308 = .text:0x80183308; // type:function size:0xC -fn_80183314 = .text:0x80183314; // type:function size:0xA0 +startLoadCount__11RPSysSystemFv = .text:0x80183308; // type:function size:0xC +getCalendarTime__11RPSysSystemFPCUsRUlRUlRUl = .text:0x80183314; // type:function size:0xA0 fn_801833B4 = .text:0x801833B4; // type:function size:0xBC -fn_80183470 = .text:0x80183470; // type:function size:0x4C -fn_801834BC = .text:0x801834BC; // type:function size:0x5C -fn_80183518 = .text:0x80183518; // type:function size:0x14 -fn_8018352C = .text:0x8018352C; // type:function size:0x8 +getCalendarTime16__11RPSysSystemFv = .text:0x80183470; // type:function size:0x4C +getCalendarTime32__11RPSysSystemFv = .text:0x801834BC; // type:function size:0x5C +destroyHeap__11RPSysSystemFPQ23EGG4Heap = .text:0x80183518; // type:function size:0x14 +getBootScene__11RPSysSystemFv = .text:0x8018352C; // type:function size:0x8 fn_80183534 = .text:0x80183534; // type:function size:0x50 fn_80183584 = .text:0x80183584; // type:function size:0x24 -fn_801835A8 = .text:0x801835A8; // type:function size:0xC -fn_801835B4 = .text:0x801835B4; // type:function size:0xC +getFBHeight__11RPSysSystemCFv = .text:0x801835A8; // type:function size:0xC +getFBWidth__11RPSysSystemCFv = .text:0x801835B4; // type:function size:0xC fn_801835C0 = .text:0x801835C0; // type:function size:0x14 fn_801835D4 = .text:0x801835D4; // type:function size:0x8 -fn_801835DC = .text:0x801835DC; // type:function size:0x130 -fn_8018370C = .text:0x8018370C; // type:function size:0x6C -fn_80183778 = .text:0x80183778; // type:function size:0x180 +setupRenderMode__11RPSysSystemFv = .text:0x801835DC; // type:function size:0x130 +setupTVMode__11RPSysSystemFv = .text:0x8018370C; // type:function size:0x6C +loadFrameWork__11RPSysSystemFb = .text:0x80183778; // type:function size:0x180 mainLoop__11RPSysSystemFv = .text:0x801838F8; // type:function size:0x16C setup__11RPSysSystemFv = .text:0x80183A64; // type:function size:0x13C create__11RPSysSystemFv = .text:0x80183BA0; // type:function size:0x44 @@ -6883,91 +6883,92 @@ fn_80183ED4 = .text:0x80183ED4; // type:function size:0x8 fn_80183EDC = .text:0x80183EDC; // type:function size:0x8 main = .text:0x80183EE4; // type:function size:0x34 scope:global OSReport = .text:0x80183F18; // type:function size:0x50 scope:global -fn_80183F68 = .text:0x80183F68; // type:function size:0x40 -fn_80183FA8 = .text:0x80183FA8; // type:function size:0x58 -fn_80184000 = .text:0x80184000; // type:function size:0x460 -fn_80184460 = .text:0x80184460; // type:function size:0x5C -fn_801844BC = .text:0x801844BC; // type:function size:0x9C -fn_80184558 = .text:0x80184558; // type:function size:0x9C -fn_801845F4 = .text:0x801845F4; // type:function size:0x9C -fn_80184690 = .text:0x80184690; // type:function size:0x5C -fn_801846EC = .text:0x801846EC; // type:function size:0x6C -fn_80184758 = .text:0x80184758; // type:function size:0xAC -fn_80184804 = .text:0x80184804; // type:function size:0x34 -fn_80184838 = .text:0x80184838; // type:function size:0x360 -fn_80184B98 = .text:0x80184B98; // type:function size:0xC -fn_80184BA4 = .text:0x80184BA4; // type:function size:0x26C -fn_80184E10 = .text:0x80184E10; // type:function size:0x70 -fn_80184E80 = .text:0x80184E80; // type:function size:0x10 -fn_80184E90 = .text:0x80184E90; // type:function size:0x8 -fn_80184E98 = .text:0x80184E98; // type:function size:0x8 -fn_80184EA0 = .text:0x80184EA0; // type:function size:0xF0 -fn_80184F90 = .text:0x80184F90; // type:function size:0x74 -fn_80185004 = .text:0x80185004; // type:function size:0x4 -fn_80185008 = .text:0x80185008; // type:function size:0x40 -fn_80185048 = .text:0x80185048; // type:function size:0x4C -fn_80185094 = .text:0x80185094; // type:function size:0xD0 -fn_80185164 = .text:0x80185164; // type:function size:0x4 -fn_80185168 = .text:0x80185168; // type:function size:0xC0 -fn_80185228 = .text:0x80185228; // type:function size:0x4 -fn_8018522C = .text:0x8018522C; // type:function size:0xD8 -fn_80185304 = .text:0x80185304; // type:function size:0xFC -fn_80185400 = .text:0x80185400; // type:function size:0x4 -fn_80185404 = .text:0x80185404; // type:function size:0x68 -fn_8018546C = .text:0x8018546C; // type:function size:0x8 -fn_80185474 = .text:0x80185474; // type:function size:0x8 -fn_8018547C = .text:0x8018547C; // type:function size:0x8 -fn_80185484 = .text:0x80185484; // type:function size:0x48 -fn_801854CC = .text:0x801854CC; // type:function size:0x48 -fn_80185514 = .text:0x80185514; // type:function size:0x8 -fn_8018551C = .text:0x8018551C; // type:function size:0x8 -fn_80185524 = .text:0x80185524; // type:function size:0x50 -fn_80185574 = .text:0x80185574; // type:function size:0x8 -fn_8018557C = .text:0x8018557C; // type:function size:0x8 -fn_80185584 = .text:0x80185584; // type:function size:0x8 -fn_8018558C = .text:0x8018558C; // type:function size:0x8 -fn_80185594 = .text:0x80185594; // type:function size:0x4 -fn_80185598 = .text:0x80185598; // type:function size:0x4 -fn_8018559C = .text:0x8018559C; // type:function size:0x4 -fn_801855A0 = .text:0x801855A0; // type:function size:0x4 -fn_801855A4 = .text:0x801855A4; // type:function size:0x4 -fn_801855A8 = .text:0x801855A8; // type:function size:0xC -fn_801855B4 = .text:0x801855B4; // type:function size:0x8 -fn_801855BC = .text:0x801855BC; // type:function size:0xBC -fn_80185678 = .text:0x80185678; // type:function size:0x58 -fn_801856D0 = .text:0x801856D0; // type:function size:0x198 -fn_80185868 = .text:0x80185868; // type:function size:0x34 -fn_8018589C = .text:0x8018589C; // type:function size:0x14 -fn_801858B0 = .text:0x801858B0; // type:function size:0x14 -fn_801858C4 = .text:0x801858C4; // type:function size:0x14 -fn_801858D8 = .text:0x801858D8; // type:function size:0x90 -fn_80185968 = .text:0x80185968; // type:function size:0x74 -fn_801859DC = .text:0x801859DC; // type:function size:0x74 -fn_80185A50 = .text:0x80185A50; // type:function size:0x74 -fn_80185AC4 = .text:0x80185AC4; // type:function size:0x74 -fn_80185B38 = .text:0x80185B38; // type:function size:0x14 -fn_80185B4C = .text:0x80185B4C; // type:function size:0x14 -fn_80185B60 = .text:0x80185B60; // type:function size:0x4 -fn_80185B64 = .text:0x80185B64; // type:function size:0x14 -fn_80185B78 = .text:0x80185B78; // type:function size:0x14 -fn_80185B8C = .text:0x80185B8C; // type:function size:0x48 -fn_80185BD4 = .text:0x80185BD4; // type:function size:0x8C -fn_80185C60 = .text:0x80185C60; // type:function size:0x2C -fn_80185C8C = .text:0x80185C8C; // type:function size:0x54 -fn_80185CE0 = .text:0x80185CE0; // type:function size:0x48 -fn_80185D28 = .text:0x80185D28; // type:function size:0xC -fn_80185D34 = .text:0x80185D34; // type:function size:0x40 -fn_80185D74 = .text:0x80185D74; // type:function size:0x190 -isDvdErrorApplicationEnd__13RPSysSceneMgrCFv = .text:0x80185F04; // type:function size:0x14 -fn_80185F18 = .text:0x80185F18; // type:function size:0x20 -fn_80185F38 = .text:0x80185F38; // type:function size:0x18 -fn_80185F50 = .text:0x80185F50; // type:function size:0x14 -fn_80185F64 = .text:0x80185F64; // type:function size:0x10 -fn_80185F74 = .text:0x80185F74; // type:function size:0x70 -fn_80185FE4 = .text:0x80185FE4; // type:function size:0x70 -fn_80186054 = .text:0x80186054; // type:function size:0xAC -fn_80186100 = .text:0x80186100; // type:function size:0x8 -fn_80186108 = .text:0x80186108; // type:function size:0x12C +__dt__17RPSysSceneCreatorFv = .text:0x80183F68; // type:function size:0x40 +__dt__10RPSysSceneFv = .text:0x80183FA8; // type:function size:0x58 +createSportsScene__17RPSysSceneCreatorFl = .text:0x80184000; // type:function size:0x460 +__dt__17RPSportsBaseSceneFv = .text:0x80184460; // type:function size:0x5C +getAudioType__17RPSysSceneCreatorFl = .text:0x801844BC; // type:function size:0x9C +getExitType__17RPSysSceneCreatorFl = .text:0x80184558; // type:function size:0x9C +getCreateType__17RPSysSceneCreatorFl = .text:0x801845F4; // type:function size:0x9C +getSceneID__17RPSysSceneCreatorFQ217RPSysSceneCreator8ESportID = .text:0x80184690; // type:function size:0x5C +getSportID__17RPSysSceneCreatorFl = .text:0x801846EC; // type:function size:0x6C +getResDirName__17RPSysSceneCreatorFl = .text:0x80184758; // type:function size:0xAC +destroy__17RPSysSceneCreatorFl = .text:0x80184804; // type:function size:0x34 +create__17RPSysSceneCreatorFl = .text:0x80184838; // type:function size:0x360 +changeSoftReset__17RPSysSceneCreatorFv = .text:0x80184B98; // type:function size:0xC +changeSceneAfterFade__17RPSysSceneCreatorFlb = .text:0x80184BA4; // type:function size:0x26C +CreateInstance__17RPSysSceneCreatorFPQ23EGG4Heap = .text:0x80184E10; // type:function size:0x70 +setChildScene__10RPSysSceneFv = .text:0x80184E80; // type:function size:0x10 +getCreatorSceneID__10RPSysSceneCFv = .text:0x80184E90; // type:function size:0x8 +setCreatorSceneID__10RPSysSceneFl = .text:0x80184E98; // type:function size:0x8 +init__10RPSysSceneFv = .text:0x80184EA0; // type:function size:0xF0 +exit__10RPSysSceneFv = .text:0x80184F90; // type:function size:0x74 +Exit__10RPSysSceneFv = .text:0x80185004; // type:function size:0x4 scope:weak +outgoing_childCreate__10RPSysSceneFv = .text:0x80185008; // type:function size:0x40 +draw__10RPSysSceneFv = .text:0x80185048; // type:function size:0x4C +calc__10RPSysSceneFv = .text:0x80185094; // type:function size:0xD0 +Calculate__10RPSysSceneFv = .text:0x80185164; // type:function size:0x4 scope:weak +incoming_childDestroy__10RPSysSceneFv = .text:0x80185168; // type:function size:0xC0 +Reset__10RPSysSceneFv = .text:0x80185228; // type:function size:0x4 scope:weak +reinit__10RPSysSceneFv = .text:0x8018522C; // type:function size:0xD8 +enter__10RPSysSceneFv = .text:0x80185304; // type:function size:0xFC +Configure__10RPSysSceneFv = .text:0x80185400; // type:function size:0x4 scope:weak +__ct__10RPSysSceneFv = .text:0x80185404; // type:function size:0x68 +setDimming__10RPSysSceneFb = .text:0x8018546C; // type:function size:0x8 +startFadeOut__10RPSysSceneFv = .text:0x80185474; // type:function size:0x8 +startFadeIn__10RPSysSceneFv = .text:0x8018547C; // type:function size:0x8 +setSceneFadeColor__10RPSysSceneFQ34nw4r2ut5Color = .text:0x80185484; // type:function size:0x48 +setFadeColor__10RPSysSceneFQ34nw4r2ut5Color = .text:0x801854CC; // type:function size:0x48 +getFadeColor__10RPSysSceneCFv = .text:0x80185514; // type:function size:0x8 +setFadeFrame__10RPSysSceneFUs = .text:0x8018551C; // type:function size:0x8 +isNandAccessEnable__10RPSysSceneCFv = .text:0x80185524; // type:function size:0x50 +isSceneChangeEnable__10RPSysSceneCFv = .text:0x80185574; // type:function size:0x8 +isSceneBlank__10RPSysSceneCFv = .text:0x8018557C; // type:function size:0x8 +isSceneDisplay__10RPSysSceneCFv = .text:0x80185584; // type:function size:0x8 +VF_0x3C__10RPSysSceneFv = .text:0x8018558C; // type:function size:0x8 scope:weak +pauseCallBack__10RPSysSceneFb = .text:0x80185594; // type:function size:0x4 scope:weak +LoadResource__10RPSysSceneFv = .text:0x80185598; // type:function size:0x4 scope:weak +taskAsync__10RPSysSceneFv = .text:0x8018559C; // type:function size:0x4 scope:weak +UserDraw__16IRPGrpDrawObjectFv = .text:0x801855A0; // type:function size:0x4 scope:weak +DebugDraw__16IRPGrpDrawObjectFv = .text:0x801855A4; // type:function size:0x4 scope:weak +__sinit_\RPSysScene_cpp = .text:0x801855A8; // type:function size:0xC scope:local +@36@__dt__10RPSysSceneFv = .text:0x801855B4; // type:function size:0x8 scope:weak +adjust__15RPSysRenderModeFPUsPUsQ215RPSysRenderMode7EFormatb = .text:0x801855BC; // type:function size:0xBC +__dt__13RPSysSceneMgrFv = .text:0x80185678; // type:function size:0x58 +updateState__13RPSysSceneMgrFv = .text:0x801856D0; // type:function size:0x198 +calcCurrentScene__13RPSysSceneMgrFv = .text:0x80185868; // type:function size:0x34 +drawMgrFader__13RPSysSceneMgrFv = .text:0x8018589C; // type:function size:0x14 +drawSceneFader__13RPSysSceneMgrFv = .text:0x801858B0; // type:function size:0x14 +calcSceneFader__13RPSysSceneMgrFv = .text:0x801858C4; // type:function size:0x14 +isSceneChangeEnable__13RPSysSceneMgrFv = .text:0x801858D8; // type:function size:0x90 +isTaskFinished__13RPSysSceneMgrFv = .text:0x80185968; // type:function size:0x74 +isFadeOut__13RPSysSceneMgrFv = .text:0x801859DC; // type:function size:0x74 +isBlank__13RPSysSceneMgrFv = .text:0x80185A50; // type:function size:0x74 +isDisplay__13RPSysSceneMgrFv = .text:0x80185AC4; // type:function size:0x74 +startSceneFadeOut__13RPSysSceneMgrFv = .text:0x80185B38; // type:function size:0x14 +startSceneFadeIn__13RPSysSceneMgrFv = .text:0x80185B4C; // type:function size:0x14 +startMgrFadeIn__13RPSysSceneMgrFv = .text:0x80185B60; // type:function size:0x4 +setSceneStatus__13RPSysSceneMgrFQ33EGG5Fader7EStatus = .text:0x80185B64; // type:function size:0x14 +getSceneStatus__13RPSysSceneMgrFv = .text:0x80185B78; // type:function size:0x14 +setSceneFadeColor__13RPSysSceneMgrFQ34nw4r2ut5Color = .text:0x80185B8C; // type:function size:0x48 +setFadeColor__13RPSysSceneMgrFQ34nw4r2ut5Color = .text:0x80185BD4; // type:function size:0x8C +getFadeColor__13RPSysSceneMgrFv = .text:0x80185C60; // type:function size:0x8 +getColor__Q23EGG10ColorFaderCFv = .text:0x80185C68; // type:function size:0x24 scope:weak +resetFadeColor__13RPSysSceneMgrFv = .text:0x80185C8C; // type:function size:0x54 +setFadeFrame__13RPSysSceneMgrFUs = .text:0x80185CE0; // type:function size:0x48 +getFadeFrame__13RPSysSceneMgrFv = .text:0x80185D28; // type:function size:0xC +resetFadeFrame__13RPSysSceneMgrFv = .text:0x80185D34; // type:function size:0x40 +changeNextSceneAfterFade__13RPSysSceneMgrFlb = .text:0x80185D74; // type:function size:0x190 +isDvdErrorApplicationEnd__13RPSysSceneMgrFv = .text:0x80185F04; // type:function size:0x14 +isApplicationEndReserved__13RPSysSceneMgrFv = .text:0x80185F18; // type:function size:0x20 +resetGuard__13RPSysSceneMgrFv = .text:0x80185F38; // type:function size:0x18 +isShutDownReserved__13RPSysSceneMgrCFv = .text:0x80185F50; // type:function size:0x14 +isNormalState__13RPSysSceneMgrCFv = .text:0x80185F64; // type:function size:0x10 +shutdownSystem__13RPSysSceneMgrFb = .text:0x80185F74; // type:function size:0x70 +returnToMenu__13RPSysSceneMgrFb = .text:0x80185FE4; // type:function size:0x70 +softReset__13RPSysSceneMgrFb = .text:0x80186054; // type:function size:0xAC +getCurrentSceneRP__13RPSysSceneMgrCFv = .text:0x80186100; // type:function size:0x8 +CreateInstance__13RPSysSceneMgrFPQ23EGG4Heap = .text:0x80186108; // type:function size:0x12C setLanguage__17RPSysProjectLocalFQ217RPSysProjectLocal5EArea = .text:0x80186234; // type:function size:0x8 setLocale__17RPSysProjectLocalFQ217RPSysProjectLocal5EArea = .text:0x8018623C; // type:function size:0x8 appendLocalDirectory__17RPSysProjectLocalFPcPCc = .text:0x80186244; // type:function size:0x120 @@ -6988,18 +6989,18 @@ dump__19RPSysPrimTagParmFv = .text:0x801867F8; // type:function size:0x4 write__19RPSysPrimTagParmFRQ23EGG6Stream = .text:0x801867FC; // type:function size:0x10 read__19RPSysPrimTagParmFRQ23EGG6Stream = .text:0x8018680C; // type:function size:0x34 __ct__12RPSysTagParmFP18RPSysTagParametersPc = .text:0x80186840; // type:function size:0x38 -fn_80186878 = .text:0x80186878; // type:function size:0x10 -fn_80186888 = .text:0x80186888; // type:function size:0xD8 -fn_80186960 = .text:0x80186960; // type:function size:0xBC -fn_80186A1C = .text:0x80186A1C; // type:function size:0x8C -fn_80186AA8 = .text:0x80186AA8; // type:function size:0x78 -fn_80186B20 = .text:0x80186B20; // type:function size:0x114 -fn_80186C34 = .text:0x80186C34; // type:function size:0xB8 -fn_80186CEC = .text:0x80186CEC; // type:function size:0x10 -fn_80186CFC = .text:0x80186CFC; // type:function size:0x20 -fn_80186D1C = .text:0x80186D1C; // type:function size:0x10 -fn_80186D2C = .text:0x80186D2C; // type:function size:0x4 -fn_80186D30 = .text:0x80186D30; // type:function size:0x110 +taskAsyncFunc__10RPSysSceneFPv = .text:0x80186878; // type:function size:0x10 +loadResourceFunc__10RPSysSceneFPv = .text:0x80186888; // type:function size:0xD8 +updateNandEndMessage__10RPSysSceneFv = .text:0x80186960; // type:function size:0xBC +updateDvdEndMessage__10RPSysSceneFv = .text:0x80186A1C; // type:function size:0x8C +initTaskAsync__10RPSysSceneFv = .text:0x80186AA8; // type:function size:0x78 +loadMessage__10RPSysSceneFv = .text:0x80186B20; // type:function size:0x114 +load__10RPSysSceneFv = .text:0x80186C34; // type:function size:0xB8 +enableLoadMessage__10RPSysSceneFv = .text:0x80186CEC; // type:function size:0x10 +isTaskAsyncFinish__10RPSysSceneCFv = .text:0x80186CFC; // type:function size:0x20 +setTaskAsync__10RPSysSceneFv = .text:0x80186D1C; // type:function size:0x10 +loadUpdate__10RPSysSceneFv = .text:0x80186D2C; // type:function size:0x4 +drawTimeStamp__10RPSysSceneFQ34nw4r2ut5Color = .text:0x80186D30; // type:function size:0x110 fn_80186E40 = .text:0x80186E40; // type:function size:0x58 fn_80186E98 = .text:0x80186E98; // type:function size:0x1C LoadFromDVD__20RPSysResourceManagerFPCcPQ23EGG4HeapQ33EGG9DvdRipper15EAllocDirectionPl = .text:0x80186EB4; // type:function size:0xEC @@ -7025,10 +7026,10 @@ fn_80187B54 = .text:0x80187B54; // type:function size:0x40 fn_80187B94 = .text:0x80187B94; // type:function size:0xC fn_80187BA0 = .text:0x80187BA0; // type:function size:0x70 fn_80187C10 = .text:0x80187C10; // type:function size:0x7C -fn_80187C8C = .text:0x80187C8C; // type:function size:0x88 -fn_80187D14 = .text:0x80187D14; // type:function size:0x64 -fn_80187D78 = .text:0x80187D78; // type:function size:0x44 -fn_80187DBC = .text:0x80187DBC; // type:function size:0x128 +postUpdate__17RPSysCommonObjectFv = .text:0x80187C8C; // type:function size:0x88 +preUpdate__17RPSysCommonObjectFv = .text:0x80187D14; // type:function size:0x64 +init__17RPSysCommonObjectFv = .text:0x80187D78; // type:function size:0x44 +__ct__17RPSysCommonObjectFv = .text:0x80187DBC; // type:function size:0x128 __dt__11RPGrpScreenFv = .text:0x80187EE4; // type:function size:0x40 scope:weak fn_80187F24 = .text:0x80187F24; // type:function size:0x40 __dt__14RPSysDvdStatusFv = .text:0x80187F64; // type:function size:0x40 @@ -7193,7 +7194,7 @@ __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 -fn_8018D01C = .text:0x8018D01C; // type:function size:0x18 +draw__13RPSysPauseMgrFv = .text:0x8018D01C; // type:function size:0x18 fn_8018D034 = .text:0x8018D034; // type:function size:0x1EC fn_8018D220 = .text:0x8018D220; // type:function size:0x1F8 fn_8018D418 = .text:0x8018D418; // type:function size:0x8 @@ -7295,92 +7296,92 @@ __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 -fn_801927CC = .text:0x801927CC; // type:function size:0x224 -fn_801929F0 = .text:0x801929F0; // type:function size:0x430 -fn_80192E20 = .text:0x80192E20; // type:function size:0x40 -fn_80192E60 = .text:0x80192E60; // type:function size:0xA4 -fn_80192F04 = .text:0x80192F04; // type:function size:0xA4 -fn_80192FA8 = .text:0x80192FA8; // type:function size:0xA4 -fn_8019304C = .text:0x8019304C; // type:function size:0xA4 -fn_801930F0 = .text:0x801930F0; // type:function size:0x8 -fn_801930F8 = .text:0x801930F8; // type:function size:0x8 -fn_80193100 = .text:0x80193100; // type:function size:0x150 -fn_80193250 = .text:0x80193250; // type:function size:0x18 -fn_80193268 = .text:0x80193268; // type:function size:0x10 -fn_80193278 = .text:0x80193278; // type:function size:0x10 -fn_80193288 = .text:0x80193288; // type:function size:0x22C -fn_801934B4 = .text:0x801934B4; // type:function size:0xD0 -fn_80193584 = .text:0x80193584; // type:function size:0x7C -fn_80193600 = .text:0x80193600; // type:function size:0x9C -fn_8019369C = .text:0x8019369C; // type:function size:0x48 -fn_801936E4 = .text:0x801936E4; // type:function size:0x18 -fn_801936FC = .text:0x801936FC; // type:function size:0x9C -fn_80193798 = .text:0x80193798; // type:function size:0x10 -fn_801937A8 = .text:0x801937A8; // type:function size:0x10 -fn_801937B8 = .text:0x801937B8; // type:function size:0x10 -fn_801937C8 = .text:0x801937C8; // type:function size:0x10 -fn_801937D8 = .text:0x801937D8; // type:function size:0x40 -fn_80193818 = .text:0x80193818; // type:function size:0x27C -fn_80193A94 = .text:0x80193A94; // type:function size:0x94 -fn_80193B28 = .text:0x80193B28; // type:function size:0x50 -fn_80193B78 = .text:0x80193B78; // type:function size:0x24 -fn_80193B9C = .text:0x80193B9C; // type:function size:0x1C -fn_80193BB8 = .text:0x80193BB8; // type:function size:0x1C -fn_80193BD4 = .text:0x80193BD4; // type:function size:0x94 -fn_80193C68 = .text:0x80193C68; // type:function size:0x50 -fn_80193CB8 = .text:0x80193CB8; // type:function size:0x24 -fn_80193CDC = .text:0x80193CDC; // type:function size:0x1C -fn_80193CF8 = .text:0x80193CF8; // type:function size:0x1C -fn_80193D14 = .text:0x80193D14; // type:function size:0x94 -fn_80193DA8 = .text:0x80193DA8; // type:function size:0x50 -fn_80193DF8 = .text:0x80193DF8; // type:function size:0x24 -fn_80193E1C = .text:0x80193E1C; // type:function size:0x1C -fn_80193E38 = .text:0x80193E38; // type:function size:0x1C -fn_80193E54 = .text:0x80193E54; // type:function size:0x94 -fn_80193EE8 = .text:0x80193EE8; // type:function size:0x50 -fn_80193F38 = .text:0x80193F38; // type:function size:0x24 -fn_80193F5C = .text:0x80193F5C; // type:function size:0x1C -fn_80193F78 = .text:0x80193F78; // type:function size:0x1C -fn_80193F94 = .text:0x80193F94; // type:function size:0x1C4 -fn_80194158 = .text:0x80194158; // type:function size:0x64 -fn_801941BC = .text:0x801941BC; // type:function size:0xB4 -fn_80194270 = .text:0x80194270; // type:function size:0xE4 -fn_80194354 = .text:0x80194354; // type:function size:0x178 -fn_801944CC = .text:0x801944CC; // type:function size:0x1C0 -fn_8019468C = .text:0x8019468C; // type:function size:0x98 -fn_80194724 = .text:0x80194724; // type:function size:0x28 -fn_8019474C = .text:0x8019474C; // type:function size:0x28 -fn_80194774 = .text:0x80194774; // type:function size:0x1C -fn_80194790 = .text:0x80194790; // type:function size:0xFC -fn_8019488C = .text:0x8019488C; // type:function size:0xAC -fn_80194938 = .text:0x80194938; // type:function size:0x60 -fn_80194998 = .text:0x80194998; // type:function size:0xC0 -fn_80194A58 = .text:0x80194A58; // type:function size:0x60 -fn_80194AB8 = .text:0x80194AB8; // type:function size:0xC0 -fn_80194B78 = .text:0x80194B78; // type:function size:0x20 -fn_80194B98 = .text:0x80194B98; // type:function size:0x14 -fn_80194BAC = .text:0x80194BAC; // type:function size:0x90 -fn_80194C3C = .text:0x80194C3C; // type:function size:0x64 -fn_80194CA0 = .text:0x80194CA0; // type:function size:0x1B0 -fn_80194E50 = .text:0x80194E50; // type:function size:0xF8 -fn_80194F48 = .text:0x80194F48; // type:function size:0xB8 -fn_80195000 = .text:0x80195000; // type:function size:0x94 -fn_80195094 = .text:0x80195094; // type:function size:0x94 -fn_80195128 = .text:0x80195128; // type:function size:0x94 -fn_801951BC = .text:0x801951BC; // type:function size:0x94 -fn_80195250 = .text:0x80195250; // type:function size:0x94 -fn_801952E4 = .text:0x801952E4; // type:function size:0xC0 -fn_801953A4 = .text:0x801953A4; // type:function size:0x9C -fn_80195440 = .text:0x80195440; // type:function size:0x70 -fn_801954B0 = .text:0x801954B0; // type:function size:0x70 -fn_80195520 = .text:0x80195520; // type:function size:0x5C -fn_8019557C = .text:0x8019557C; // type:function size:0x44 -fn_801955C0 = .text:0x801955C0; // type:function size:0x50 -fn_80195610 = .text:0x80195610; // type:function size:0xD4 -fn_801956E4 = .text:0x801956E4; // type:function size:0x40 -fn_80195724 = .text:0x80195724; // type:function size:0x94 -fn_801957B8 = .text:0x801957B8; // type:function size:0x8 +__dt__14RPSysEffectMgrFv = .text:0x80192700; // type:function size:0xCC +LoadResource__14RPSysEffectMgrFv = .text:0x801927CC; // type:function size:0x224 +createMemoryManager__14RPSysEffectMgrFPQ214RPSysEffectMgr9EffectArg = .text:0x801929F0; // type:function size:0x430 +__dt__Q34nw4r2ef17MemoryManagerBaseFv = .text:0x80192E20; // type:function size:0x40 scope:weak +__ct__48RPSysEffectMemoryManagerTmpFiPQ34nw4r2ef8Particle = .text:0x80192E60; // type:function size:0xA4 scope:weak +__ct__51RPSysEffectMemoryManagerTmp<20RPSysParticleManager>FiP20RPSysParticleManager = .text:0x80192F04; // type:function size:0xA4 scope:weak +__ct__47RPSysEffectMemoryManagerTmpFiPQ34nw4r2ef7Emitter = .text:0x80192FA8; // type:function size:0xA4 scope:weak +__ct__46RPSysEffectMemoryManagerTmpFiPQ34nw4r2ef6Effect = .text:0x8019304C; // type:function size:0xA4 scope:weak +__nw__FUlPv = .text:0x801930F0; // type:function size:0x8 scope:weak +__nwa__FUlPv = .text:0x801930F8; // type:function size:0x8 scope:weak +AllocHeap__24RPSysEffectMemoryManagerFUl = .text:0x80193100; // type:function size:0x150 scope:weak +RoundUp
    __Q34nw4r2ut24@unnamed@SportsPack_pch@FUlUi_Ul = .text:0x80193250; // type:function size:0x18 scope:weak +__ct__Q34nw4r2ef17MemoryManagerBaseFv = .text:0x80193268; // type:function size:0x10 scope:weak +createEffect__14RPSysEffectMgrFPCcUlUl = .text:0x80193278; // type:function size:0x10 +draw__14RPSysEffectMgrFRCQ34nw4r2ef8DrawInfoUlUl = .text:0x80193288; // type:function size:0x22C +setCaptureEfb__14RPSysEffectMgrFPvRCQ214RPSysEffectMgr10EfbTexData = .text:0x801934B4; // type:function size:0xD0 +update__14RPSysEffectMgrFQ214RPSysEffectMgr12ECalcSetting = .text:0x80193584; // type:function size:0x7C +stopAllEffect__14RPSysEffectMgrFv = .text:0x80193600; // type:function size:0x9C +resetCreator__14RPSysEffectMgrFP18RPSysEffectCreator = .text:0x8019369C; // type:function size:0x48 +setCreator__14RPSysEffectMgrFP18RPSysEffectCreatorUl = .text:0x801936E4; // type:function size:0x18 +CreateInstance__14RPSysEffectMgrFPQ23EGG4Heap = .text:0x801936FC; // type:function size:0x9C +AssignObjectID__46RPSysEffectMemoryManagerTmpFPv = .text:0x80193798; // type:function size:0x10 scope:weak +AssignObjectID__47RPSysEffectMemoryManagerTmpFPv = .text:0x801937A8; // type:function size:0x10 scope:weak +AssignObjectID__51RPSysEffectMemoryManagerTmp<20RPSysParticleManager>FPv = .text:0x801937B8; // type:function size:0x10 scope:weak +AssignObjectID__48RPSysEffectMemoryManagerTmpFPv = .text:0x801937C8; // type:function size:0x10 scope:weak +__dt__24RPSysEffectMemoryManagerFv = .text:0x801937D8; // type:function size:0x40 scope:weak +GarbageCollection__24RPSysEffectMemoryManagerFv = .text:0x80193818; // type:function size:0x27C scope:weak +AllocEffect__24RPSysEffectMemoryManagerFv = .text:0x80193A94; // type:function size:0x94 scope:weak +FreeEffect__24RPSysEffectMemoryManagerFPv = .text:0x80193B28; // type:function size:0x50 scope:weak +GetNumAllocEffect__24RPSysEffectMemoryManagerCFv = .text:0x80193B78; // type:function size:0x24 scope:weak +GetNumActiveEffect__24RPSysEffectMemoryManagerCFv = .text:0x80193B9C; // type:function size:0x1C scope:weak +GetNumFreeEffect__24RPSysEffectMemoryManagerCFv = .text:0x80193BB8; // type:function size:0x1C scope:weak +AllocEmitter__24RPSysEffectMemoryManagerFv = .text:0x80193BD4; // type:function size:0x94 scope:weak +FreeEmitter__24RPSysEffectMemoryManagerFPv = .text:0x80193C68; // type:function size:0x50 scope:weak +GetNumAllocEmitter__24RPSysEffectMemoryManagerCFv = .text:0x80193CB8; // type:function size:0x24 scope:weak +GetNumActiveEmitter__24RPSysEffectMemoryManagerCFv = .text:0x80193CDC; // type:function size:0x1C scope:weak +GetNumFreeEmitter__24RPSysEffectMemoryManagerCFv = .text:0x80193CF8; // type:function size:0x1C scope:weak +AllocParticleManager__24RPSysEffectMemoryManagerFv = .text:0x80193D14; // type:function size:0x94 scope:weak +FreeParticleManager__24RPSysEffectMemoryManagerFPv = .text:0x80193DA8; // type:function size:0x50 scope:weak +GetNumAllocParticleManager__24RPSysEffectMemoryManagerCFv = .text:0x80193DF8; // type:function size:0x24 scope:weak +GetNumActiveParticleManager__24RPSysEffectMemoryManagerCFv = .text:0x80193E1C; // type:function size:0x1C scope:weak +GetNumFreeParticleManager__24RPSysEffectMemoryManagerCFv = .text:0x80193E38; // type:function size:0x1C scope:weak +AllocParticle__24RPSysEffectMemoryManagerFv = .text:0x80193E54; // type:function size:0x94 scope:weak +FreeParticle__24RPSysEffectMemoryManagerFPv = .text:0x80193EE8; // type:function size:0x50 scope:weak +GetNumAllocParticle__24RPSysEffectMemoryManagerCFv = .text:0x80193F38; // type:function size:0x24 scope:weak +GetNumActiveParticle__24RPSysEffectMemoryManagerCFv = .text:0x80193F5C; // type:function size:0x1C scope:weak +GetNumFreeParticle__24RPSysEffectMemoryManagerCFv = .text:0x80193F78; // type:function size:0x1C scope:weak +FreeHeap__24RPSysEffectMemoryManagerFPv = .text:0x80193F94; // type:function size:0x1C4 scope:weak +reset__11RPSysEffectFv = .text:0x80194158; // type:function size:0x64 +fn_801941BC__11RPSysEffectCFi = .text:0x801941BC; // type:function size:0xB4 +getUserFlag__11RPSysEffectCFi = .text:0x80194270; // type:function size:0xE4 +update__11RPSysEffectFv = .text:0x80194354; // type:function size:0x178 +setPtclAnim__11RPSysEffectFib = .text:0x801944CC; // type:function size:0x1C0 +setMtx__11RPSysEffectFRCQ34nw4r4math5MTX34 = .text:0x8019468C; // type:function size:0x98 +setPos__11RPSysEffectFRCQ34nw4r4math4VEC3 = .text:0x80194724; // type:function size:0x28 +setScale__11RPSysEffectFRCQ34nw4r4math4VEC3 = .text:0x8019474C; // type:function size:0x28 +setScale__11RPSysEffectFf = .text:0x80194774; // type:function size:0x1C +setDynamicsScale__11RPSysEffectFRCQ34nw4r4math4VEC3PCQ34nw4r4math4VEC2 = .text:0x80194790; // type:function size:0xFC +setLocalScale__11RPSysEffectFRCQ34nw4r4math4VEC3 = .text:0x8019488C; // type:function size:0xAC +setParticleRotate__11RPSysEffectFRCQ34nw4r4math4VEC3 = .text:0x80194938; // type:function size:0x60 +setDefaultParticleRotate__11RPSysEffectFRCQ34nw4r4math4VEC3 = .text:0x80194998; // type:function size:0xC0 +setParticleScale__11RPSysEffectFRQ34nw4r4math4VEC2 = .text:0x80194A58; // type:function size:0x60 +setDefaultParticleSize__11RPSysEffectFRCQ34nw4r4math4VEC2 = .text:0x80194AB8; // type:function size:0xC0 +setColor__11RPSysEffectFUc = .text:0x80194B78; // type:function size:0x20 +setColor__11RPSysEffectFUcUcUc = .text:0x80194B98; // type:function size:0x14 +setColor__11RPSysEffectFUcUcUcUc = .text:0x80194BAC; // type:function size:0x90 +setVelocity__11RPSysEffectFRCQ34nw4r4math4VEC3 = .text:0x80194C3C; // type:function size:0x64 +setSpecDirAdd__11RPSysEffectFRCQ34nw4r4math4VEC3 = .text:0x80194CA0; // type:function size:0x1B0 +setSpecDir__11RPSysEffectFRCQ34nw4r4math4VEC3 = .text:0x80194E50; // type:function size:0xF8 +setPowerSpecDirAdd__11RPSysEffectFf = .text:0x80194F48; // type:function size:0xB8 +setPowerSpecDir__11RPSysEffectFf = .text:0x80195000; // type:function size:0x94 +setPowerRadiationDir__11RPSysEffectFf = .text:0x80195094; // type:function size:0x94 +setEmitEmitDiv__11RPSysEffectFUs = .text:0x80195128; // type:function size:0x94 +setEmitInterval__11RPSysEffectFUs = .text:0x801951BC; // type:function size:0x94 +setEmitRatio__11RPSysEffectFf = .text:0x80195250; // type:function size:0x94 +setLife__11RPSysEffectFUs = .text:0x801952E4; // type:function size:0xC0 +setDisableCalcDraw__11RPSysEffectFb = .text:0x801953A4; // type:function size:0x9C +setDisableDraw__11RPSysEffectFb = .text:0x80195440; // type:function size:0x70 +setDisableCalc__11RPSysEffectFb = .text:0x801954B0; // type:function size:0x70 +forceKill__11RPSysEffectFv = .text:0x80195520; // type:function size:0x5C +followFade__11RPSysEffectFv = .text:0x8019557C; // type:function size:0x44 +fade__11RPSysEffectFv = .text:0x801955C0; // type:function size:0x50 +create__11RPSysEffectFv = .text:0x80195610; // type:function size:0xD4 +__dt__11RPSysEffectFv = .text:0x801956E4; // type:function size:0x40 +__ct__11RPSysEffectFPCcUlUl = .text:0x80195724; // type:function size:0x94 +__sinit_\RPSysEffectBase_cpp = .text:0x801957B8; // type:function size:0x8 scope:local getCpuColor__11RPSysLayoutFv = .text:0x801957C0; // type:function size:0x8 getPlayerColor__11RPSysLayoutFUl = .text:0x801957C8; // type:function size:0x14 isFinishedDynAnmOut__11RPSysLayoutFv = .text:0x801957DC; // type:function size:0x68 @@ -7447,19 +7448,19 @@ parseDynamicAnmLength__11RPSysLayoutFPCc = .text:0x801976B8; // type:function si initialize__11RPSysLayoutFv = .text:0x8019778C; // type:function size:0x4 update__14RPSysFrameCtrlFv = .text:0x80197790; // type:function size:0x268 init__14RPSysFrameCtrlFs = .text:0x801979F8; // type:function size:0x30 -fn_80197A28 = .text:0x80197A28; // type:function size:0x84 -fn_80197AAC = .text:0x80197AAC; // type:function size:0x698 -fn_80198144 = .text:0x80198144; // type:function size:0xD4 -fn_80198218 = .text:0x80198218; // type:function size:0xB4 -fn_801982CC = .text:0x801982CC; // type:function size:0x14 -fn_801982E0 = .text:0x801982E0; // type:function size:0x14 -fn_801982F4 = .text:0x801982F4; // type:function size:0x38 -fn_8019832C = .text:0x8019832C; // type:function size:0x444 -fn_80198770 = .text:0x80198770; // type:function size:0x4 -fn_80198774 = .text:0x80198774; // type:function size:0x4 -fn_80198778 = .text:0x80198778; // type:function size:0x8C -fn_80198804 = .text:0x80198804; // type:function size:0xD4 -fn_801988D8 = .text:0x801988D8; // type:function size:0x90 +draw__18RPSysEffectCreatorFRCQ34nw4r2ef8DrawInfoUlUl = .text:0x80197A28; // type:function size:0x84 +update__18RPSysEffectCreatorFv = .text:0x80197AAC; // type:function size:0x698 +createEffect__18RPSysEffectCreatorFPCcUl = .text:0x80198144; // type:function size:0xD4 +stopAllEffect__18RPSysEffectCreatorFv = .text:0x80198218; // type:function size:0xB4 +isSlowEffect__18RPSysEffectCreatorCFv = .text:0x801982CC; // type:function size:0x14 +isSlowSystem__18RPSysEffectCreatorCFv = .text:0x801982E0; // type:function size:0x14 +setFrameRate__18RPSysEffectCreatorFf = .text:0x801982F4; // type:function size:0x38 +createSlowSystem__18RPSysEffectCreatorFv = .text:0x8019832C; // type:function size:0x444 +__ct__Q34nw4r2ef17ParticleParameterFv = .text:0x80198770; // type:function size:0x4 scope:weak +__ct__Q34nw4r2ef16EmitterParameterFv = .text:0x80198774; // type:function size:0x4 scope:weak +setEffectResource__18RPSysEffectCreatorFPvPv = .text:0x80198778; // type:function size:0x8C +__dt__18RPSysEffectCreatorFv = .text:0x80198804; // type:function size:0xD4 +__ct__18RPSysEffectCreatorFUl = .text:0x801988D8; // type:function size:0x90 Initialize__19RPSysWideTextWriterFv = .text:0x80198968; // type:function size:0x28 getFrameMax__14RPSysLytAnmObjFv = .text:0x80198990; // type:function size:0x40 init__14RPSysLytAnmObjFssQ214RPSysFrameCtrl9EPlayMode = .text:0x801989D0; // type:function size:0x7C @@ -7634,7 +7635,7 @@ fn_801A0C20 = .text:0x801A0C20; // type:function size:0xC0 fn_801A0CE0 = .text:0x801A0CE0; // type:function size:0x150 fn_801A0E30 = .text:0x801A0E30; // type:function size:0x300 fn_801A1130 = .text:0x801A1130; // type:function size:0x53C -fn_801A166C = .text:0x801A166C; // type:function size:0x50 +draw__14RPSysPauseMenuFv = .text:0x801A166C; // type:function size:0x50 fn_801A16BC = .text:0x801A16BC; // type:function size:0x3A0 fn_801A1A5C = .text:0x801A1A5C; // type:function size:0x350 fn_801A1DAC = .text:0x801A1DAC; // type:function size:0x234 @@ -7659,20 +7660,20 @@ fn_801A3F08 = .text:0x801A3F08; // type:function size:0x10C fn_801A4014 = .text:0x801A4014; // type:function size:0xA8 fn_801A40BC = .text:0x801A40BC; // type:function size:0x814 fn_801A48D0 = .text:0x801A48D0; // type:function size:0x60 -fn_801A4930 = .text:0x801A4930; // type:function size:0x24 -fn_801A4954 = .text:0x801A4954; // type:function size:0x2C +drawBanIcon__16RPSysHomeMenuMgrFv = .text:0x801A4930; // type:function size:0x24 +draw__16RPSysHomeMenuMgrFv = .text:0x801A4954; // type:function size:0x2C update__16RPSysHomeMenuMgrFv = .text:0x801A4980; // type:function size:0x390 -fn_801A4D10 = .text:0x801A4D10; // type:function size:0x58 -fn_801A4D68 = .text:0x801A4D68; // type:function size:0x124 -fn_801A4E8C = .text:0x801A4E8C; // type:function size:0x12C -fn_801A4FB8 = .text:0x801A4FB8; // type:function size:0x224 -fn_801A51DC = .text:0x801A51DC; // type:function size:0x68 -fn_801A5244 = .text:0x801A5244; // type:function size:0x40 -fn_801A5284 = .text:0x801A5284; // type:function size:0x1AC -fn_801A5430 = .text:0x801A5430; // type:function size:0x54 -fn_801A5484 = .text:0x801A5484; // type:function size:0x158 -fn_801A55DC = .text:0x801A55DC; // type:function size:0x11C -fn_801A56F8 = .text:0x801A56F8; // type:function size:0x60 +softReset__16RPSysHomeMenuMgrFv = .text:0x801A4D10; // type:function size:0x58 +checkMenuEnd__16RPSysHomeMenuMgrFv = .text:0x801A4D68; // type:function size:0x124 +checkMenuStart__16RPSysHomeMenuMgrFv = .text:0x801A4E8C; // type:function size:0x12C +initHomeButtonInfo__16RPSysHomeMenuMgrFv = .text:0x801A4FB8; // type:function size:0x224 +init__16RPSysHomeMenuMgrFv = .text:0x801A51DC; // type:function size:0x68 +__dt__16RPSysHomeMenuMgrFv = .text:0x801A5244; // type:function size:0x40 +__ct__16RPSysHomeMenuMgrFPQ23EGG4Heap = .text:0x801A5284; // type:function size:0x1AC +soundCallback__16RPSysHomeMenuMgrFii = .text:0x801A5430; // type:function size:0x54 +draw__Q216RPSysHomeMenuMgr7BanIconFv = .text:0x801A5484; // type:function size:0x158 +calc__Q216RPSysHomeMenuMgr7BanIconFv = .text:0x801A55DC; // type:function size:0x11C +CreateInstance__16RPSysHomeMenuMgrFPQ23EGG4Heap = .text:0x801A56F8; // type:function size:0x60 GetValidNum__15RPSysOfficialDBFv = .text:0x801A5758; // type:function size:0xA8 Reset__15RPSysOfficialDBFv = .text:0x801A5800; // type:function size:0x7C GetIndexFromCreateID__15RPSysOfficialDBFPC11RFLCreateID = .text:0x801A587C; // type:function size:0x44 @@ -7943,22 +7944,22 @@ fn_801AF1D4 = .text:0x801AF1D4; // type:function size:0x4 fn_801AF1D8 = .text:0x801AF1D8; // type:function size:0x230 fn_801AF408 = .text:0x801AF408; // type:function size:0x4 fn_801AF40C = .text:0x801AF40C; // type:function size:0x24 -fn_801AF430 = .text:0x801AF430; // type:function size:0x24 +AppendDrawObject__13RPGrpRendererFP16IRPGrpDrawObject = .text:0x801AF430; // type:function size:0x24 fn_801AF454 = .text:0x801AF454; // type:function size:0x138 fn_801AF58C = .text:0x801AF58C; // type:function size:0x9C fn_801AF628 = .text:0x801AF628; // type:function size:0x98 fn_801AF6C0 = .text:0x801AF6C0; // type:function size:0x54 -fn_801AF714 = .text:0x801AF714; // type:function size:0x58 -fn_801AF76C = .text:0x801AF76C; // type:function size:0x84 -fn_801AF7F0 = .text:0x801AF7F0; // type:function size:0x8 -fn_801AF7F8 = .text:0x801AF7F8; // type:function size:0x4F0 +CalculateInPause__13RPGrpRendererFv = .text:0x801AF714; // type:function size:0x58 +PostCalculate__13RPGrpRendererFv = .text:0x801AF76C; // type:function size:0x84 +PreCalculate__13RPGrpRendererFv = .text:0x801AF7F0; // type:function size:0x8 +Rendering__13RPGrpRendererFv = .text:0x801AF7F8; // type:function size:0x4F0 fn_801AFCE8 = .text:0x801AFCE8; // type:function size:0x60 -fn_801AFD48 = .text:0x801AFD48; // type:function size:0x30 -fn_801AFD78 = .text:0x801AFD78; // type:function size:0x8 -fn_801AFD80 = .text:0x801AFD80; // type:function size:0x160 -fn_801AFEE0 = .text:0x801AFEE0; // type:function size:0xC -fn_801AFEEC = .text:0x801AFEEC; // type:function size:0x80 -fn_801AFF6C = .text:0x801AFF6C; // type:function size:0x98 +BecomeCurrent__13RPGrpRendererFv = .text:0x801AFD48; // type:function size:0x30 +Destruct__13RPGrpRendererFv = .text:0x801AFD78; // type:function size:0x8 +Construct__13RPGrpRendererFPQ23EGG9AllocatorUs = .text:0x801AFD80; // type:function size:0x160 +End__13RPGrpRendererFv = .text:0x801AFEE0; // type:function size:0xC +StartDebugDraw__13RPGrpRendererFv = .text:0x801AFEEC; // type:function size:0x80 +Begin__13RPGrpRendererFv = .text:0x801AFF6C; // type:function size:0x98 fn_801B0004 = .text:0x801B0004; // type:function size:0x48 fn_801B004C = .text:0x801B004C; // type:function size:0x16C fn_801B01B8 = .text:0x801B01B8; // type:function size:0x40 @@ -8195,9 +8196,9 @@ calc__14RPSndStaticMgrFv = .text:0x801B9690; // type:function size:0x16C setupArchive__14RPSndStaticMgrFv = .text:0x801B97FC; // type:function size:0x54 __dt__14RPSndStaticMgrFv = .text:0x801B9850; // type:function size:0x68 __ct__14RPSndStaticMgrFv = .text:0x801B98B8; // type:function size:0x58 -fn_801B9910 = .text:0x801B9910; // type:function size:0x1FC -fn_801B9B0C = .text:0x801B9B0C; // type:function size:0x298 -fn_801B9DA4 = .text:0x801B9DA4; // type:function size:0x11C +GetMidPoint__12RPUtlDohMathFPQ34nw4r4math4VEC3PfRCQ34nw4r4math4VEC3RCQ34nw4r4math4VEC3RCQ34nw4r4math4VEC3ff = .text:0x801B9910; // type:function size:0x1FC +MTX34Normalize__12RPUtlDohMathFPQ34nw4r4math5MTX34PCQ34nw4r4math5MTX34Q212RPUtlDohMath9AxisOrder = .text:0x801B9B0C; // type:function size:0x298 +__sinit_\RPUtlDohMath_cpp = .text:0x801B9DA4; // type:function size:0x11C fn_801B9EC0 = .text:0x801B9EC0; // type:function size:0x3C4 fn_801BA284 = .text:0x801BA284; // type:function size:0x198 fn_801BA41C = .text:0x801BA41C; // type:function size:0x218 @@ -14092,7 +14093,7 @@ fn_803165D8 = .text:0x803165D8; // type:function size:0x60 fn_80316638 = .text:0x80316638; // type:function size:0x4 fn_8031663C = .text:0x8031663C; // type:function size:0x408 fn_80316A44 = .text:0x80316A44; // type:function size:0x4 -fn_80316A48 = .text:0x80316A48; // type:function size:0x34 +fn_80316A48__7BowlingFPQ27Bowling15SomeUnkManager0Pvi = .text:0x80316A48; // type:function size:0x34 fn_80316A7C = .text:0x80316A7C; // type:function size:0x88 fn_80316B04 = .text:0x80316B04; // type:function size:0x4 fn_80316B08 = .text:0x80316B08; // type:function size:0xFC @@ -14179,17 +14180,17 @@ fn_803248E8 = .text:0x803248E8; // type:function size:0x8 fn_803248F0 = .text:0x803248F0; // type:function size:0x8 fn_803248F8 = .text:0x803248F8; // type:function size:0x94 fn_8032498C = .text:0x8032498C; // type:function size:0x8 -fn_80324994 = .text:0x80324994; // type:function size:0xC0 +fn_80324994__7BowlingFPQ27Bowling9PinStatusPQ27Bowling11LaneContext = .text:0x80324994; // type:function size:0xC0 fn_80324A54 = .text:0x80324A54; // type:function size:0x4C fn_80324AA0 = .text:0x80324AA0; // type:function size:0x8 fn_80324AA8 = .text:0x80324AA8; // type:function size:0x18 fn_80324AC0 = .text:0x80324AC0; // type:function size:0x34 fn_80324AF4 = .text:0x80324AF4; // type:function size:0x1C -fn_80324B10 = .text:0x80324B10; // type:function size:0x8 +fn_80324B10__7BowlingFPQ27Bowling11LaneContext = .text:0x80324B10; // type:function size:0x8 fn_80324B18 = .text:0x80324B18; // type:function size:0x38 fn_80324B50 = .text:0x80324B50; // type:function size:0x50 fn_80324BA0 = .text:0x80324BA0; // type:function size:0x230 -fn_80324DD0 = .text:0x80324DD0; // type:function size:0x2C8 +fn_80324DD0__7BowlingFPQ27Bowling11LaneContextPQ34nw4r4math4VEC3 = .text:0x80324DD0; // type:function size:0x2C8 fn_80325098 = .text:0x80325098; // type:function size:0x1C fn_803250B4 = .text:0x803250B4; // type:function size:0x8 fn_803250BC = .text:0x803250BC; // type:function size:0x1C @@ -14198,7 +14199,7 @@ fn_803250E8 = .text:0x803250E8; // type:function size:0x10 fn_803250F8 = .text:0x803250F8; // type:function size:0x10 fn_80325108 = .text:0x80325108; // type:function size:0x3C fn_80325144 = .text:0x80325144; // type:function size:0x10 -fn_80325154 = .text:0x80325154; // type:function size:0x1A8 +fn_80325154__7BowlingFPQ27Bowling11LaneContext = .text:0x80325154; // type:function size:0x1A8 fn_803252FC = .text:0x803252FC; // type:function size:0x2E8 fn_803255E4 = .text:0x803255E4; // type:function size:0x24 fn_80325608 = .text:0x80325608; // type:function size:0x30 @@ -14240,15 +14241,15 @@ fn_803271E4 = .text:0x803271E4; // type:function size:0x1C fn_80327200 = .text:0x80327200; // type:function size:0x8 fn_80327208 = .text:0x80327208; // type:function size:0x8 fn_80327210 = .text:0x80327210; // type:function size:0x8 -fn_80327218 = .text:0x80327218; // type:function size:0x44 +fn_80327218__7BowlingFPQ27Bowling11LaneContext = .text:0x80327218; // type:function size:0x44 fn_8032725C = .text:0x8032725C; // type:function size:0xD4 -fn_80327330 = .text:0x80327330; // type:function size:0x174 +fn_80327330__7BowlingFPQ27Bowling11LaneContextPQ27Bowling9PinStatus = .text:0x80327330; // type:function size:0x174 fn_803274A4 = .text:0x803274A4; // type:function size:0x2C fn_803274D0 = .text:0x803274D0; // type:function size:0x34 fn_80327504 = .text:0x80327504; // type:function size:0x54 fn_80327558 = .text:0x80327558; // type:function size:0x240 fn_80327798 = .text:0x80327798; // type:function size:0x1C -fn_803277B4 = .text:0x803277B4; // type:function size:0x68 +fn_803277B4__7BowlingFPQ27Bowling11LaneContext = .text:0x803277B4; // type:function size:0x68 fn_8032781C = .text:0x8032781C; // type:function size:0x3C fn_80327858 = .text:0x80327858; // type:function size:0x298 fn_80327AF0 = .text:0x80327AF0; // type:function size:0xA0 @@ -14280,7 +14281,7 @@ fn_80329184 = .text:0x80329184; // type:function size:0x1CC fn_80329350 = .text:0x80329350; // type:function size:0x4 fn_80329354 = .text:0x80329354; // type:function size:0x12C fn_80329480 = .text:0x80329480; // type:function size:0x150 -fn_803295D0 = .text:0x803295D0; // type:function size:0x88 +fn_803295D0__7BowlingFPQ27Bowling11LaneBvhDataPvPv = .text:0x803295D0; // type:function size:0x88 fn_80329658 = .text:0x80329658; // type:function size:0x7AC fn_80329E04 = .text:0x80329E04; // type:function size:0x114 fn_80329F18 = .text:0x80329F18; // type:function size:0x188 @@ -14292,8 +14293,8 @@ fn_8032A7E4 = .text:0x8032A7E4; // type:function size:0x38 fn_8032A81C = .text:0x8032A81C; // type:function size:0x1AC fn_8032A9C8 = .text:0x8032A9C8; // type:function size:0x1C fn_8032A9E4 = .text:0x8032A9E4; // type:function size:0x4 -fn_8032A9E8 = .text:0x8032A9E8; // type:function size:0x3A0 -fn_8032AD88 = .text:0x8032AD88; // type:function size:0x50 +RenderModelSet__Q27Bowling15ResetRenderStateActiveBallFv = .text:0x8032A9E8; // type:function size:0x3A0 +ResetRenderState__Q27Bowling15RPBowActiveBallFv = .text:0x8032AD88; // type:function size:0x50 fn_8032ADD8 = .text:0x8032ADD8; // type:function size:0x1C fn_8032ADF4 = .text:0x8032ADF4; // type:function size:0x4 fn_8032ADF8 = .text:0x8032ADF8; // type:function size:0x5C @@ -14325,48 +14326,48 @@ fn_8032F6F8 = .text:0x8032F6F8; // type:function size:0xEE0 fn_803305D8 = .text:0x803305D8; // type:function size:0x24C fn_80330824 = .text:0x80330824; // type:function size:0x8 fn_8033082C = .text:0x8033082C; // type:function size:0x4 -fn_80330830 = .text:0x80330830; // type:function size:0x130 -fn_80330960 = .text:0x80330960; // type:function size:0x1F8 -fn_80330B58 = .text:0x80330B58; // type:function size:0x4C -fn_80330BA4 = .text:0x80330BA4; // type:function size:0x8C -fn_80330C30 = .text:0x80330C30; // type:function size:0x3C -fn_80330C6C = .text:0x80330C6C; // type:function size:0x7C -fn_80330CE8 = .text:0x80330CE8; // type:function size:0x64 -fn_80330D4C = .text:0x80330D4C; // type:function size:0x4C -fn_80330D98 = .text:0x80330D98; // type:function size:0x124 +UpdateBallsMdl__Q27Bowling22RPBowGlobalLaneManagerFPQ27Bowling18SceneObjectManager = .text:0x80330830; // type:function size:0x130 +UpdateLaneItems__Q27Bowling22RPBowGlobalLaneManagerFiPvPQ27Bowling15SomeUnkManager0b = .text:0x80330960; // type:function size:0x1F8 +TickNpcLanes__Q27Bowling22RPBowGlobalLaneManagerFv = .text:0x80330B58; // type:function size:0x4C +UpdateBallsPhysics__Q27Bowling22RPBowGlobalLaneManagerFv = .text:0x80330BA4; // type:function size:0x8C +SetLaneUnknownState__Q27Bowling22RPBowGlobalLaneManagerFi = .text:0x80330C30; // type:function size:0x3C +ResetLanePinsAndAnimations__Q27Bowling22RPBowGlobalLaneManagerFv = .text:0x80330C6C; // type:function size:0x7C +SetupBallManagerLaneObjects__Q27Bowling22RPBowGlobalLaneManagerFPvPv = .text:0x80330CE8; // type:function size:0x64 +InitializeBallManagerLanes__Q27Bowling22RPBowGlobalLaneManagerFv = .text:0x80330D4C; // type:function size:0x4C +CheckBallLaneIntersection__7BowlingFPff = .text:0x80330D98; // type:function size:0x124 fn_80330EBC = .text:0x80330EBC; // type:function size:0x12C -fn_80330FE8 = .text:0x80330FE8; // type:function size:0x66C -fn_80331654 = .text:0x80331654; // type:function size:0xFC -fn_80331750 = .text:0x80331750; // type:function size:0xDF0 -fn_80332540 = .text:0x80332540; // type:function size:0x7C -fn_803325BC = .text:0x803325BC; // type:function size:0x8 -fn_803325C4 = .text:0x803325C4; // type:function size:0x10 -fn_803325D4 = .text:0x803325D4; // type:function size:0xA4 -fn_80332678 = .text:0x80332678; // type:function size:0x184 -fn_803327FC = .text:0x803327FC; // type:function size:0x58 -fn_80332854 = .text:0x80332854; // type:function size:0x1B8 -fn_80332A0C = .text:0x80332A0C; // type:function size:0x5C -fn_80332A68 = .text:0x80332A68; // type:function size:0xCC -fn_80332B34 = .text:0x80332B34; // type:function size:0x98 -fn_80332BCC = .text:0x80332BCC; // type:function size:0x58 +CalculateNpcThrowVelocity__7BowlingFPQ34nw4r4math4VEC3PCQ27Bowling15RPBowNpcManagerPCQ34nw4r4math4VEC3PCQ27Bowling9PinStatus = .text:0x80330FE8; // type:function size:0x66C +DebugPrintNpcState__Q27Bowling15RPBowNpcManagerFv = .text:0x80331654; // type:function size:0xFC +Update__Q27Bowling15RPBowNpcManagerFv = .text:0x80331750; // type:function size:0xDF0 +ActivateNpcTurn__Q27Bowling15RPBowNpcManagerFv = .text:0x80332540; // type:function size:0x7C +SetStateFlag__Q27Bowling15RPBowNpcManagerFUc = .text:0x803325BC; // type:function size:0x8 +IsLaneIdle__Q27Bowling15RPBowNpcManagerFv = .text:0x803325C4; // type:function size:0x10 +Setup__Q27Bowling15RPBowNpcManagerFPQ27Bowling11LaneContextPQ27Bowling10NpcContextPQ27Bowling10NpcContextPQ27Bowling10NpcContextiPQ27Bowling19RPBowBallReturnRackPv = .text:0x803325D4; // type:function size:0xA4 +InitAudioActors__Q27Bowling15RPBowNpcManagerFi = .text:0x80332678; // type:function size:0x184 +DebugPrintStates__Q27Bowling19RPBowManagerContextFv = .text:0x803327FC; // type:function size:0x58 +UpdateNpcs__Q27Bowling19RPBowManagerContextFv = .text:0x80332854; // type:function size:0x1B8 +SetNpcStateFlags__Q27Bowling19RPBowManagerContextFUc = .text:0x80332A0C; // type:function size:0x5C +LinkNpcLanes__Q27Bowling19RPBowManagerContextFPQ27Bowling22RPBowGlobalLaneManagerPQ27Bowling18SceneObjectManager = .text:0x80332A68; // type:function size:0xCC +Initialize__Q27Bowling19RPBowManagerContextFv = .text:0x80332B34; // type:function size:0x98 +__dt__Q27Bowling15RPBowNpcManagerFv = .text:0x80332BCC; // type:function size:0x58 fn_80332C24 = .text:0x80332C24; // type:function size:0x8 fn_80332C2C = .text:0x80332C2C; // type:function size:0x34 fn_80332C60 = .text:0x80332C60; // type:function size:0xB4 fn_80332D14 = .text:0x80332D14; // type:function size:0x1390 -fn_803340A4 = .text:0x803340A4; // type:function size:0x1CC -fn_80334270 = .text:0x80334270; // type:function size:0xEC +CalculateNpcBallTransform__7BowlingFPQ34nw4r4math5MTX34PCQ27Bowling10NpcContext = .text:0x803340A4; // type:function size:0x1CC +fn_80334270__7BowlingFPQ27Bowling10NpcContext = .text:0x80334270; // type:function size:0xEC fn_8033435C = .text:0x8033435C; // type:function size:0x48 fn_803343A4 = .text:0x803343A4; // type:function size:0xA0 -fn_80334444 = .text:0x80334444; // type:function size:0x8 -fn_8033444C = .text:0x8033444C; // type:function size:0x70 +UpdateNpcLane__7BowlingFPUcPCQ27Bowling10NpcContext = .text:0x80334444; // type:function size:0x8 +InitNpcContext__7BowlingFPQ27Bowling10NpcContextii = .text:0x8033444C; // type:function size:0x70 fn_803344BC = .text:0x803344BC; // type:function size:0x68 fn_80334524 = .text:0x80334524; // type:function size:0x58 fn_8033457C = .text:0x8033457C; // type:function size:0x74 -fn_803345F0 = .text:0x803345F0; // type:function size:0x4 -fn_803345F4 = .text:0x803345F4; // type:function size:0x24 -fn_80334618 = .text:0x80334618; // type:function size:0x344 -fn_8033495C = .text:0x8033495C; // type:function size:0x24 -fn_80334980 = .text:0x80334980; // type:function size:0x60 +fn_803345F0__7BowlingFPQ27Bowling11LaneContext = .text:0x803345F0; // type:function size:0x4 +IsPinSetterActive__7BowlingFPQ27Bowling11LaneContext = .text:0x803345F4; // type:function size:0x24 +UpdatePinSetter__7BowlingFPQ27Bowling11LaneContext = .text:0x80334618; // type:function size:0x344 +TriggerPinSetter__7BowlingFPQ27Bowling11LaneContexti = .text:0x8033495C; // type:function size:0x24 +ResetPinSetterState__7BowlingFPQ27Bowling11LaneContextUc = .text:0x80334980; // type:function size:0x60 fn_803349E0 = .text:0x803349E0; // type:function size:0x51C fn_80334EFC = .text:0x80334EFC; // type:function size:0x650 fn_8033554C = .text:0x8033554C; // type:function size:0x368 @@ -14507,40 +14508,40 @@ fn_8034C6B0 = .text:0x8034C6B0; // type:function size:0x224 fn_8034C8D4 = .text:0x8034C8D4; // type:function size:0x24 fn_8034C8F8 = .text:0x8034C8F8; // type:function size:0x5C fn_8034C954 = .text:0x8034C954; // type:function size:0x8 -fn_8034C95C = .text:0x8034C95C; // type:function size:0x668 -fn_8034CFC4 = .text:0x8034CFC4; // type:function size:0xD0 +fn_8034C95C__7BowlingFPQ27Bowling12NpcIdleState = .text:0x8034C95C; // type:function size:0x668 +fn_8034CFC4__7BowlingFPQ27Bowling12NpcIdleStateii = .text:0x8034CFC4; // type:function size:0xD0 fn_8034D094 = .text:0x8034D094; // type:function size:0x90 fn_8034D124 = .text:0x8034D124; // type:function size:0x4 -fn_8034D128 = .text:0x8034D128; // type:function size:0x1B0 -fn_8034D2D8 = .text:0x8034D2D8; // type:function size:0x194 -fn_8034D46C = .text:0x8034D46C; // type:function size:0xC -fn_8034D478 = .text:0x8034D478; // type:function size:0x1C -fn_8034D494 = .text:0x8034D494; // type:function size:0x5C +DrawBlur__Q27Bowling15RPBowMotionBlurFPv = .text:0x8034D128; // type:function size:0x1B0 +UpdateBlurTransform__Q27Bowling15RPBowMotionBlurFPCQ34nw4r4math5MTX34f = .text:0x8034D2D8; // type:function size:0x194 +DeactivateBlur__Q27Bowling15RPBowMotionBlurFv = .text:0x8034D46C; // type:function size:0xC +SetBlurModels__Q27Bowling15RPBowMotionBlurFP10RPGrpModelP10RPGrpModelP10RPGrpModelP10RPGrpModelP10RPGrpModelP10RPGrpModel = .text:0x8034D478; // type:function size:0x1C +__dt__Q27Bowling15RPBowMotionBlurFv = .text:0x8034D494; // type:function size:0x5C fn_8034D4F0 = .text:0x8034D4F0; // type:function size:0x4 -fn_8034D4F4 = .text:0x8034D4F4; // type:function size:0x3E8 -fn_8034D8DC = .text:0x8034D8DC; // type:function size:0x10 -fn_8034D8EC = .text:0x8034D8EC; // type:function size:0x14 -fn_8034D900 = .text:0x8034D900; // type:function size:0x28 -fn_8034D928 = .text:0x8034D928; // type:function size:0x10 -fn_8034D938 = .text:0x8034D938; // type:function size:0x14 -fn_8034D94C = .text:0x8034D94C; // type:function size:0x1C8 -fn_8034DB14 = .text:0x8034DB14; // type:function size:0xBC -fn_8034DBD0 = .text:0x8034DBD0; // type:function size:0x20 -fn_8034DBF0 = .text:0x8034DBF0; // type:function size:0xA8 +UpdateBallReturnRack__Q27Bowling19RPBowBallReturnRackFl = .text:0x8034D4F4; // type:function size:0x3E8 +GetBallSlotIndex__Q27Bowling19RPBowBallReturnRackFl = .text:0x8034D8DC; // type:function size:0x10 +ReleaseBallFromNPC__Q27Bowling19RPBowBallReturnRackFl = .text:0x8034D8EC; // type:function size:0x14 +SpawnBallOnRack__Q27Bowling19RPBowBallReturnRackFl = .text:0x8034D900; // type:function size:0x28 +IsBallOnRack__Q27Bowling19RPBowBallReturnRackFl = .text:0x8034D928; // type:function size:0x10 +RemoveBallFromRack__Q27Bowling19RPBowBallReturnRackFl = .text:0x8034D938; // type:function size:0x14 +SelectBallForNPC__Q27Bowling19RPBowBallReturnRackFv = .text:0x8034D94C; // type:function size:0x1C8 +ResetRackBallStates__Q27Bowling19RPBowBallReturnRackFv = .text:0x8034DB14; // type:function size:0xBC +InitBallSlotResources__Q27Bowling19RPBowBallReturnRackFlP10RPGrpModelP10RPGrpModell = .text:0x8034DBD0; // type:function size:0x20 +InitBallReturnRack__Q27Bowling19RPBowBallReturnRackFl = .text:0x8034DBF0; // type:function size:0xA8 fn_8034DC98 = .text:0x8034DC98; // type:function size:0x70 -fn_8034DD08 = .text:0x8034DD08; // type:function size:0x4 -fn_8034DD0C = .text:0x8034DD0C; // type:function size:0x8 -fn_8034DD14 = .text:0x8034DD14; // type:function size:0x4 -fn_8034DD18 = .text:0x8034DD18; // type:function size:0x3F0 -fn_8034E108 = .text:0x8034E108; // type:function size:0x638 -fn_8034E740 = .text:0x8034E740; // type:function size:0xFC -fn_8034E83C = .text:0x8034E83C; // type:function size:0x4 -fn_8034E840 = .text:0x8034E840; // type:function size:0x14 -fn_8034E854 = .text:0x8034E854; // type:function size:0x98 -fn_8034E8EC = .text:0x8034E8EC; // type:function size:0x80 -fn_8034E96C = .text:0x8034E96C; // type:function size:0x8 -fn_8034E974 = .text:0x8034E974; // type:function size:0x168 -fn_8034EADC = .text:0x8034EADC; // type:function size:0x594 +fn_8034DD08__Q27Bowling25RPBowBackgroundNpcManagerFv = .text:0x8034DD08; // type:function size:0x4 +fn_8034DD0C__Q27Bowling25RPBowBackgroundNpcManagerFv = .text:0x8034DD0C; // type:function size:0x8 +fn_8034DD14__Q27Bowling25RPBowBackgroundNpcManagerFv = .text:0x8034DD14; // type:function size:0x4 +Render__Q27Bowling25RPBowBackgroundNpcManagerFv = .text:0x8034DD18; // type:function size:0x3F0 +UpdateMovement__Q27Bowling25RPBowBackgroundNpcManagerFPQ34nw4r4math4VEC3Pb = .text:0x8034E108; // type:function size:0x638 +Reset__Q27Bowling25RPBowBackgroundNpcManagerFv = .text:0x8034E740; // type:function size:0xFC +fn_8034E83C__Q27Bowling25RPBowBackgroundNpcManagerFv = .text:0x8034E83C; // type:function size:0x4 +SetModelGroups__Q27Bowling25RPBowBackgroundNpcManagerFiPQ27Bowling13NpcModelGroupPQ27Bowling13NpcModelGroup = .text:0x8034E840; // type:function size:0x14 +InitializeConfig__Q27Bowling25RPBowBackgroundNpcManagerFi = .text:0x8034E854; // type:function size:0x98 +__dt__Q27Bowling25RPBowBackgroundNpcManagerFv = .text:0x8034E8EC; // type:function size:0x80 +fn_8034E96C__Q27Bowling25RPBowBackgroundNpcManagerFv = .text:0x8034E96C; // type:function size:0x8 +fn_8034E974__7BowlingFPvi = .text:0x8034E974; // type:function size:0x168 +fn_8034EADC__7BowlingFPviPQ34nw4r4math5MTX34PQ34nw4r4math5MTX34b = .text:0x8034EADC; // type:function size:0x594 fn_8034F070 = .text:0x8034F070; // type:function size:0xF4 fn_8034F164 = .text:0x8034F164; // type:function size:0x4 fn_8034F168 = .text:0x8034F168; // type:function size:0x2D8 @@ -14639,13 +14640,13 @@ fn_80354138 = .text:0x80354138; // type:function size:0x208 fn_80354340 = .text:0x80354340; // type:function size:0x5C fn_8035439C = .text:0x8035439C; // type:function size:0x8 fn_803543A4 = .text:0x803543A4; // type:function size:0x4 -fn_803543A8 = .text:0x803543A8; // type:function size:0x2F8 -fn_803546A0 = .text:0x803546A0; // type:function size:0x28 -fn_803546C8 = .text:0x803546C8; // type:function size:0x28 -fn_803546F0 = .text:0x803546F0; // type:function size:0x10 -fn_80354700 = .text:0x80354700; // type:function size:0xC -fn_8035470C = .text:0x8035470C; // type:function size:0x5C -fn_80354768 = .text:0x80354768; // type:function size:0x3C +Draw__Q27Bowling20RPBowTrajectoryGuideFv = .text:0x803543A8; // type:function size:0x2F8 +Reset__Q27Bowling20RPBowTrajectoryGuideFv = .text:0x803546A0; // type:function size:0x28 +Initialize__Q27Bowling20RPBowTrajectoryGuideFv = .text:0x803546C8; // type:function size:0x28 +SetDotModel__Q27Bowling20RPBowTrajectoryGuideFUlP10RPGrpModel = .text:0x803546F0; // type:function size:0x10 +SetMainModels__Q27Bowling20RPBowTrajectoryGuideFP10RPGrpModelP10RPGrpModel = .text:0x80354700; // type:function size:0xC +__dt__Q27Bowling20RPBowTrajectoryGuideFv = .text:0x8035470C; // type:function size:0x5C +UpdateControllerState__7BowlingFPUl = .text:0x80354768; // type:function size:0x3C fn_803547A4 = .text:0x803547A4; // type:function size:0x6C fn_80354810 = .text:0x80354810; // type:function size:0x98 fn_803548A8 = .text:0x803548A8; // type:function size:0x6C @@ -15028,7 +15029,7 @@ cubeScale$10537 = .rodata:0x803820A4; // type:object size:0x4 scope:local @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 +SCENE_ATTR_TABLE__17RPSysSceneCreator = .rodata:0x803820F8; // type:object size:0x1E0 data:4byte lbl_803822D8 = .rodata:0x803822D8; // type:object size:0xA data:string lbl_803822E2 = .rodata:0x803822E2; // type:object size:0x5 lbl_803822E7 = .rodata:0x803822E7; // type:object size:0x13 @@ -15054,7 +15055,7 @@ lbl_803823F6 = .rodata:0x803823F6; // type:object size:0x11 lbl_80382407 = .rodata:0x80382407; // type:object size:0xD lbl_80382414 = .rodata:0x80382414; // type:object size:0xD lbl_80382421 = .rodata:0x80382421; // type:object size:0x17 -lbl_80382438 = .rodata:0x80382438; // type:object size:0x18 +spRenderModeTable__15RPSysRenderMode = .rodata:0x80382438; // type:object size:0x14 @stringBase0 = .rodata:0x80382450; // type:object size:0x1C scope:local data:string_table @stringBase0 = .rodata:0x80382470; // type:object size:0xF2 scope:local data:string_table lbl_80382568 = .rodata:0x80382568; // type:object size:0x48 @@ -15096,13 +15097,8 @@ lbl_80382C0A = .rodata:0x80382C0A; // type:object size:0xC data:string lbl_80382C16 = .rodata:0x80382C16; // type:object size:0x13 data:string lbl_80382C29 = .rodata:0x80382C29; // type:object size:0x14 data:string lbl_80382C3D = .rodata:0x80382C3D; // type:object size:0x23 -lbl_80382C60 = .rodata:0x80382C60; // type:object size:0x20 data:4byte -lbl_80382C80 = .rodata:0x80382C80; // type:object size:0x14 data:string -lbl_80382C94 = .rodata:0x80382C94; // type:object size:0x14 data:string -lbl_80382CA8 = .rodata:0x80382CA8; // type:object size:0x13 data:string -lbl_80382CBB = .rodata:0x80382CBB; // type:object size:0x13 data:string -lbl_80382CCE = .rodata:0x80382CCE; // type:object size:0x13 data:string -lbl_80382CE1 = .rodata:0x80382CE1; // type:object size:0x7F +@26584 = .rodata:0x80382C60; // type:object size:0x20 scope:local data:4byte +@stringBase0 = .rodata:0x80382C80; // type:object size:0xDE scope:local data:string PLAYER_COLORS__11RPSysLayout = .rodata:0x80382D60; // type:object size:0x10 lbl_80382D70 = .rodata:0x80382D70; // type:object size:0x5 data:string @stringBase0 = .rodata:0x80382D78; // type:object size:0x1 scope:local data:string_table @@ -15150,7 +15146,7 @@ lbl_8038338C = .rodata:0x8038338C; // type:object size:0xE data:string lbl_8038339A = .rodata:0x8038339A; // type:object size:0xE data:string lbl_803833A8 = .rodata:0x803833A8; // type:object size:0xE data:string lbl_803833B6 = .rodata:0x803833B6; // type:object size:0x18A -lbl_80383540 = .rodata:0x80383540; // type:object size:0x130 +@stringBase0 = .rodata:0x80383540; // type:object size:0x130 data:string_table TYPE_NAME__Q34nw4r3g3d6ScnRfl = .rodata:0x80383670; // type:object size:0xC scope:global lbl_80383680 = .rodata:0x80383680; // type:object size:0x18 data:4byte GEOMETRY_MAGNIFY__10RPGrpModel = .rodata:0x80383698; // type:object size:0x18 @@ -16983,7 +16979,7 @@ lbl_80392C67 = .rodata:0x80392C67; // type:object size:0x4 data:string lbl_80392C6B = .rodata:0x80392C6B; // type:object size:0x4 data:string lbl_80392C6F = .rodata:0x80392C6F; // type:object size:0x29 lbl_80392C98 = .rodata:0x80392C98; // type:object size:0x18 data:4byte -lbl_80392CB0 = .rodata:0x80392CB0; // type:object size:0x10 data:byte +sTargetLaneWeights__7Bowling = .rodata:0x80392CB0; // type:object size:0x10 data:byte lbl_80392CC0 = .rodata:0x80392CC0; // type:object size:0x68 lbl_80392D28 = .rodata:0x80392D28; // type:object size:0x1B0 data:4byte lbl_80392ED8 = .rodata:0x80392ED8; // type:object size:0xF data:string @@ -18550,16 +18546,16 @@ __vt__Q310homebutton3gui7Manager = .data:0x803B94CC; // type:object size:0x3C __vt__Q310homebutton3gui9Component = .data:0x803B9508; // type:object size:0x60 __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 +lbl_803B9584 = .data:0x803B9584; // type:object size:0x34 scope:global jumptable_803B95B8 = .data:0x803B95B8; // type:object size:0x30 scope:local __vt__17RPSysSceneCreator = .data:0x803B95E8; // type:object size:0x18 scope:global -__vt__10RPSysScene = .data:0x803B9600; // type:object size:0x60 scope:global -lbl_803B9660 = .data:0x803B9660; // type:object size:0x3C -lbl_803B969C = .data:0x803B969C; // type:object size:0x3C -lbl_803B96D8 = .data:0x803B96D8; // type:object size:0x3C -lbl_803B9714 = .data:0x803B9714; // type:object size:0x3C -lbl_803B9750 = .data:0x803B9750; // type:object size:0x40 -jumptable_803B9790 = .data:0x803B9790; // type:object size:0x20 scope:local +__vt__10RPSysScene = .data:0x803B9600; // type:object size:0x5C scope:global +localNtsc640x456IntDf__29@unnamed@RPSysRenderMode_cpp@ = .data:0x803B9660; // type:object size:0x3C scope:local +localNtsc640x456Prog__29@unnamed@RPSysRenderMode_cpp@ = .data:0x803B969C; // type:object size:0x3C scope:local +localPal50_640x456IntDf__29@unnamed@RPSysRenderMode_cpp@ = .data:0x803B96D8; // type:object size:0x3C scope:local +localPal60_640x456IntDf__29@unnamed@RPSysRenderMode_cpp@ = .data:0x803B9714; // type:object size:0x3C scope:local +localPal60_640x456Prog__29@unnamed@RPSysRenderMode_cpp@ = .data:0x803B9750; // type:object size:0x3C scope:local +@27493 = .data:0x803B9790; // type:object size:0x20 scope:local __vt__13RPSysSceneMgr = .data:0x803B97B0; // type:object size:0x28 scope:global @7080 = .data:0x803B97D8; // type:object size:0x20 scope:local __vt__17RPSysProjectLocal = .data:0x803B97F8; // type:object size:0xC scope:global @@ -18593,15 +18589,15 @@ __vt__12RPSysMessage = .data:0x803B99D0; // type:object size:0xC __vt__12RPSysKokeshi = .data:0x803B99E0; // 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 -lbl_803B9AA0 = .data:0x803B9AA0; // type:object size:0xC -lbl_803B9AAC = .data:0x803B9AAC; // type:object size:0xC -lbl_803B9AB8 = .data:0x803B9AB8; // type:object size:0xC -lbl_803B9AC4 = .data:0x803B9AC4; // type:object size:0xC -lbl_803B9AD0 = .data:0x803B9AD0; // type:object size:0x68 -lbl_803B9B38 = .data:0x803B9B38; // type:object size:0x98 -lbl_803B9BD0 = .data:0x803B9BD0; // type:object size:0x10 +__vt__14RPSysEffectMgr = .data:0x803B9A20; // type:object size:0x14 +__vt__24RPSysEffectMemoryManager = .data:0x803B9A38; // type:object size:0x68 scope:weak +__vt__48RPSysEffectMemoryManagerTmp = .data:0x803B9AA0; // type:object size:0xC scope:weak +__vt__51RPSysEffectMemoryManagerTmp<20RPSysParticleManager> = .data:0x803B9AAC; // type:object size:0xC scope:weak +__vt__47RPSysEffectMemoryManagerTmp = .data:0x803B9AB8; // type:object size:0xC scope:weak +__vt__46RPSysEffectMemoryManagerTmp = .data:0x803B9AC4; // type:object size:0xC scope:weak +__vt__Q34nw4r2ef17MemoryManagerBase = .data:0x803B9AD0; // type:object size:0x68 scope:weak +__vt__11RPSysEffect = .data:0x803B9B38; // type:object size:0x98 +__vt__18RPSysEffectCreator = .data:0x803B9BD0; // type:object size:0xC __vt__Q219RPSysLytResAccessor16InternalAccessor = .data:0x803B9BE0; // type:object size:0x14 __vt__9RPSysFile = .data:0x803B9BF8; // type:object size:0xC __vt__11RPSysAvatar = .data:0x803B9C08; // type:object size:0x14 @@ -18627,7 +18623,7 @@ lbl_803B9E00 = .data:0x803B9E00; // type:object size:0xC lbl_803B9E0C = .data:0x803B9E0C; // type:object size:0xC @STRING@changeNameToIdRP__13RPSndAudioMgrFPCc@0 = .data:0x803B9E18; // type:object size:0x19 data:string @STRING@changeNameToIdRP__13RPSndAudioMgrFPCc = .data:0x803B9E38; // type:object size:0x10 data:string -lbl_803B9E48 = .data:0x803B9E48; // type:object size:0x10 +__vt__16RPSysHomeMenuMgr = .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 @@ -18772,8 +18768,8 @@ lbl_803C1D68 = .data:0x803C1D68; // type:object size:0x10 lbl_803C1D78 = .data:0x803C1D78; // type:object size:0x180 lbl_803C1EF8 = .data:0x803C1EF8; // type:object size:0x50 lbl_803C1F48 = .data:0x803C1F48; // type:object size:0x30 -lbl_803C1F78 = .data:0x803C1F78; // type:object size:0x60 -lbl_803C1FD8 = .data:0x803C1FD8; // type:object size:0x60 +__vt__14RPSysBootScene = .data:0x803C1F78; // type:object size:0x60 +__vt__22RPSysPlayerSelectScene = .data:0x803C1FD8; // type:object size:0x60 lbl_803C2038 = .data:0x803C2038; // type:object size:0xC lbl_803C2044 = .data:0x803C2044; // type:object size:0x22 data:string lbl_803C2068 = .data:0x803C2068; // type:object size:0x12 data:string @@ -18790,7 +18786,7 @@ jumptable_803C2278 = .data:0x803C2278; // type:object size:0x30 scope:local jumptable_803C22A8 = .data:0x803C22A8; // type:object size:0x30 scope:local jumptable_803C22D8 = .data:0x803C22D8; // type:object size:0x30 scope:local jumptable_803C2308 = .data:0x803C2308; // type:object size:0x30 scope:local -lbl_803C2338 = .data:0x803C2338; // type:object size:0xE0 +__vt__22RPSysNunchukCheckScene = .data:0x803C2338; // type:object size:0xE0 lbl_803C2418 = .data:0x803C2418; // type:object size:0x78 lbl_803C2490 = .data:0x803C2490; // type:object size:0xB8 data:4byte lbl_803C2548 = .data:0x803C2548; // type:object size:0x20 data:4byte @@ -18803,14 +18799,14 @@ lbl_803C2618 = .data:0x803C2618; // type:object size:0x20 lbl_803C2638 = .data:0x803C2638; // type:object size:0x18 lbl_803C2650 = .data:0x803C2650; // type:object size:0x10 lbl_803C2660 = .data:0x803C2660; // type:object size:0x20 -lbl_803C2680 = .data:0x803C2680; // type:object size:0xE8 +__vt__22RPSportsPackTitleScene = .data:0x803C2680; // type:object size:0xE8 jumptable_803C2768 = .data:0x803C2768; // type:object size:0x24 scope:local gap_08_803C278C_data = .data:0x803C278C; // type:object size:0x4 scope:global -lbl_803C2790 = .data:0x803C2790; // type:object size:0x60 -lbl_803C27F0 = .data:0x803C27F0; // type:object size:0x60 -lbl_803C2850 = .data:0x803C2850; // type:object size:0x60 -lbl_803C28B0 = .data:0x803C28B0; // type:object size:0x60 -lbl_803C2910 = .data:0x803C2910; // type:object size:0x80 +__vt__25RPSportsTrainingMenuScene = .data:0x803C2790; // type:object size:0x60 +__vt__25RPSportsPhysicalMenuScene = .data:0x803C27F0; // type:object size:0x60 +__vt__27RPSportsPhysicalResultScene = .data:0x803C2850; // type:object size:0x60 +__vt__28RPSportsPhysicalPreviewScene = .data:0x803C28B0; // type:object size:0x60 +__vt__17RPSportsBaseScene = .data:0x803C2910; // type:object size:0x80 lbl_803C2990 = .data:0x803C2990; // type:object size:0x10 lbl_803C29A0 = .data:0x803C29A0; // type:object size:0x10 lbl_803C29B0 = .data:0x803C29B0; // type:object size:0x24 data:4byte @@ -18833,7 +18829,7 @@ lbl_803C2C68 = .data:0x803C2C68; // type:object size:0x2C lbl_803C2C94 = .data:0x803C2C94; // type:object size:0x5C lbl_803C2CF0 = .data:0x803C2CF0; // type:object size:0x18 lbl_803C2D08 = .data:0x803C2D08; // type:object size:0xC0 -lbl_803C2DC8 = .data:0x803C2DC8; // type:object size:0x60 +__vt__17RPSportsMainScene = .data:0x803C2DC8; // type:object size:0x60 lbl_803C2E28 = .data:0x803C2E28; // type:object size:0x18 lbl_803C2E40 = .data:0x803C2E40; // type:object size:0x18 lbl_803C2E58 = .data:0x803C2E58; // type:object size:0x10 @@ -18880,7 +18876,7 @@ lbl_803C35E8 = .data:0x803C35E8; // type:object size:0x10 data:4byte lbl_803C35F8 = .data:0x803C35F8; // type:object size:0xD0 data:4byte lbl_803C36C8 = .data:0x803C36C8; // type:object size:0x50 lbl_803C3718 = .data:0x803C3718; // type:object size:0x18 -lbl_803C3730 = .data:0x803C3730; // type:object size:0x80 +__vt__10RPTnsScene = .data:0x803C3730; // type:object size:0x80 lbl_803C37B0 = .data:0x803C37B0; // type:object size:0x68 lbl_803C3818 = .data:0x803C3818; // type:object size:0x10 __vt__19RPSndAudioActorBase = .data:0x803C3828; // type:object size:0x28 @@ -19043,7 +19039,7 @@ lbl_803C4F48 = .data:0x803C4F48; // type:object size:0x10 lbl_803C4F58 = .data:0x803C4F58; // type:object size:0x28 lbl_803C4F80 = .data:0x803C4F80; // type:object size:0x48 lbl_803C4FC8 = .data:0x803C4FC8; // type:object size:0x10 -lbl_803C4FD8 = .data:0x803C4FD8; // type:object size:0x80 +__vt__10RPBsbScene = .data:0x803C4FD8; // type:object size:0x80 jumptable_803C5058 = .data:0x803C5058; // type:object size:0x7C scope:local jumptable_803C50D4 = .data:0x803C50D4; // type:object size:0x20 scope:local gap_08_803C50F4_data = .data:0x803C50F4; // type:object size:0xA8 scope:global @@ -19154,7 +19150,7 @@ lbl_803C7658 = .data:0x803C7658; // type:object size:0x50 jumptable_803C76A8 = .data:0x803C76A8; // type:object size:0x20 scope:local lbl_803C76C8 = .data:0x803C76C8; // type:object size:0x28 lbl_803C76F0 = .data:0x803C76F0; // type:object size:0x28 -lbl_803C7718 = .data:0x803C7718; // type:object size:0x80 +__vt__10RPGolScene = .data:0x803C7718; // type:object size:0x80 lbl_803C7798 = .data:0x803C7798; // type:object size:0x10 lbl_803C77A8 = .data:0x803C77A8; // type:object size:0xC lbl_803C77B4 = .data:0x803C77B4; // type:object size:0xC @@ -19213,7 +19209,7 @@ lbl_803C7F38 = .data:0x803C7F38; // type:object size:0xC lbl_803C7F44 = .data:0x803C7F44; // type:object size:0xC lbl_803C7F50 = .data:0x803C7F50; // type:object size:0xC lbl_803C7F5C = .data:0x803C7F5C; // type:object size:0x2C -lbl_803C7F88 = .data:0x803C7F88; // type:object size:0x60 +__vt__22RPGolCourseSelectScene = .data:0x803C7F88; // type:object size:0x60 lbl_803C7FE8 = .data:0x803C7FE8; // type:object size:0x40 lbl_803C8028 = .data:0x803C8028; // type:object size:0x40 lbl_803C8068 = .data:0x803C8068; // type:object size:0x30 @@ -19298,7 +19294,7 @@ lbl_803C8988 = .data:0x803C8988; // type:object size:0xC lbl_803C8994 = .data:0x803C8994; // type:object size:0xC jumptable_803C89A0 = .data:0x803C89A0; // type:object size:0x28 scope:local lbl_803C89C8 = .data:0x803C89C8; // type:object size:0x38 -lbl_803C8A00 = .data:0x803C8A00; // type:object size:0x80 +__vt__10RPBoxScene = .data:0x803C8A00; // type:object size:0x80 jumptable_803C8A80 = .data:0x803C8A80; // type:object size:0x28 scope:local jumptable_803C8AA8 = .data:0x803C8AA8; // type:object size:0x24 scope:local jumptable_803C8ACC = .data:0x803C8ACC; // type:object size:0x28 scope:local @@ -19473,7 +19469,7 @@ lbl_803CA274 = .data:0x803CA274; // type:object size:0x34 lbl_803CA2A8 = .data:0x803CA2A8; // type:object size:0x18 lbl_803CA2C0 = .data:0x803CA2C0; // type:object size:0x10 lbl_803CA2D0 = .data:0x803CA2D0; // type:object size:0x14 -lbl_803CA2E4 = .data:0x803CA2E4; // type:object size:0x94 +__vt__10RPBowScene = .data:0x803CA2E4; // type:object size:0x94 lbl_803CA378 = .data:0x803CA378; // type:object size:0x20 lbl_803CA398 = .data:0x803CA398; // type:object size:0x18 lbl_803CA3B0 = .data:0x803CA3B0; // type:object size:0x14 @@ -19489,8 +19485,8 @@ lbl_803CA640 = .data:0x803CA640; // type:object size:0x10 lbl_803CA650 = .data:0x803CA650; // type:object size:0x38 jumptable_803CA688 = .data:0x803CA688; // type:object size:0x28 scope:local lbl_803CA6B0 = .data:0x803CA6B0; // type:object size:0x18 -lbl_803CA6C8 = .data:0x803CA6C8; // type:object size:0x20 align:4 data:float -lbl_803CA6E8 = .data:0x803CA6E8; // type:object size:0x18 +gLaneXOffsets__7Bowling = .data:0x803CA6C8; // type:object size:0x20 align:4 data:float +__vt__Q27Bowling15RPBowNpcManager = .data:0x803CA6E8; // type:object size:0x18 lbl_803CA700 = .data:0x803CA700; // type:object size:0x14 lbl_803CA714 = .data:0x803CA714; // type:object size:0x24 jumptable_803CA738 = .data:0x803CA738; // type:object size:0x20 scope:local @@ -19880,15 +19876,16 @@ lbl_804A4638 = .bss:0x804A4638; // type:object size:0x28 data:byte smCommon3DManager__Q23EGG32AudioSoundActorBaseWithCamera<4> = .bss:0x804A4660; // type:object size:0x10 data:4byte sActorList__19RPSndAudioActorBase = .bss:0x804A4670; // type:object size:0xC sMoveParamList__17RPSndMoveParamMgr = .bss:0x804A4680; // type:object size:0x10 -lbl_804A4690 = .bss:0x804A4690; // type:object size:0xC align:4 data:float -lbl_804A469C = .bss:0x804A469C; // type:object size:0xC align:4 data:float -lbl_804A46A8 = .bss:0x804A46A8; // type:object size:0xC align:4 data:float -lbl_804A46B4 = .bss:0x804A46B4; // type:object size:0xC align:4 data:float -lbl_804A46C0 = .bss:0x804A46C0; // type:object size:0xC align:4 data:float -lbl_804A46CC = .bss:0x804A46CC; // type:object size:0xC align:4 data:float -lbl_804A46D8 = .bss:0x804A46D8; // type:object size:0x10 align:4 data:float -lbl_804A46E8 = .bss:0x804A46E8; // type:object size:0x58 align:4 data:float -lbl_804A4740 = .bss:0x804A4740; // type:object size:0x10 align:4 data:float +VEC3_ZERO__12RPUtlDohMath = .bss:0x804A4690; // type:object size:0xC align:4 data:float +AXIS_XP__12RPUtlDohMath = .bss:0x804A469C; // type:object size:0xC align:4 data:float +AXIS_XN__12RPUtlDohMath = .bss:0x804A46A8; // type:object size:0xC align:4 data:float +AXIS_YP__12RPUtlDohMath = .bss:0x804A46B4; // type:object size:0xC align:4 data:float +AXIS_YN__12RPUtlDohMath = .bss:0x804A46C0; // type:object size:0xC align:4 data:float +AXIS_ZP__12RPUtlDohMath = .bss:0x804A46CC; // type:object size:0xC align:4 data:float +AXIS_ZN__12RPUtlDohMath = .bss:0x804A46D8; // type:object size:0xC align:4 data:float +MTX34_IDENT__12RPUtlDohMath = .bss:0x804A46E8; // type:object size:0x30 align:4 data:float +MTX33_IDENT__12RPUtlDohMath = .bss:0x804A4718; // type:object size:0x24 align:4 data:float +QUAT_IDENT__12RPUtlDohMath = .bss:0x804A4740; // type:object size:0x10 align:4 data:float lbl_804A4750 = .bss:0x804A4750; // type:object size:0x10 data:4byte lbl_804A4760 = .bss:0x804A4760; // type:object size:0x10 data:byte lbl_804A4770 = .bss:0x804A4770; // type:object size:0xC align:4 data:float @@ -20080,7 +20077,7 @@ lbl_804A9D98 = .bss:0x804A9D98; // type:object size:0xC lbl_804A9DA4 = .bss:0x804A9DA4; // type:object size:0x1C align:4 data:float lbl_804A9DC0 = .bss:0x804A9DC0; // type:object size:0xC lbl_804A9DCC = .bss:0x804A9DCC; // type:object size:0x1C align:4 data:float -lbl_804A9DE8 = .bss:0x804A9DE8; // type:object size:0x2D0 data:byte +gBowlingPhysicsData__7Bowling = .bss:0x804A9DE8; // type:object size:0x2D0 data:byte lbl_804AA0B8 = .bss:0x804AA0B8; // type:object size:0x160 lbl_804AA218 = .bss:0x804AA218; // type:object size:0x12000 lbl_804BC218 = .bss:0x804BC218; // type:object size:0xC68 data:4byte @@ -20089,7 +20086,7 @@ lbl_804BD150 = .bss:0x804BD150; // type:object size:0xD8 align:4 data:float lbl_804BD228 = .bss:0x804BD228; // type:object size:0x48 align:4 data:float lbl_804BD270 = .bss:0x804BD270; // type:object size:0x30 align:4 data:float lbl_804BD2A0 = .bss:0x804BD2A0; // type:object size:0x48 data:4byte -lbl_804BD2E8 = .bss:0x804BD2E8; // type:object size:0x40 align:4 data:float +gBallReturnRackConstants__7Bowling = .bss:0x804BD2E8; // type:object size:0x40 align:4 data:float lbl_804BD328 = .bss:0x804BD328; // type:object size:0x44 align:4 data:float mFontEncode__Q34nw4r2ut7RomFont = .sdata:0x804BD380; // type:object size:0x2 scope:global align:2 data:2byte mFormatBufferSize__Q34nw4r2ut17TextWriterBase = .sdata:0x804BD388; // type:object size:0x4 scope:weak align:4 data:4byte @@ -20457,7 +20454,7 @@ lbl_804BDBD8 = .sdata:0x804BDBD8; // type:object size:0x8 lbl_804BDBE0 = .sdata:0x804BDBE0; // type:object size:0x8 lbl_804BDBE8 = .sdata:0x804BDBE8; // type:object size:0x8 lbl_804BDBF0 = .sdata:0x804BDBF0; // type:object size:0x8 -lbl_804BDBF8 = .sdata:0x804BDBF8; // type:object size:0x8 data:4byte +sSoundHeapSize__16RPSysHomeMenuMgr = .sdata:0x804BDBF8; // type:object size:0x4 data:4byte sSuccess__17RPSysNWC24Manager = .sdata:0x804BDC00; // type:object size:0x4 data:4byte lbl_804BDC08 = .sdata:0x804BDC08; // type:object size:0x4 data:4byte lbl_804BDC0C = .sdata:0x804BDC0C; // type:object size:0x4 data:4byte @@ -21857,10 +21854,10 @@ sRFLBrokenType = .sbss:0x804BF4B0; // type:object size:0x1 scope:local data:byte spInstance__11RPSysSystem = .sbss:0x804BF4B8; // type:object size:0x4 data:4byte lbl_804BF4BC = .sbss:0x804BF4BC; // type:object size:0x4 data:4byte lbl_804BF4C0 = .sbss:0x804BF4C0; // type:object size:0x4 data:4byte -lbl_804BF4C4 = .sbss:0x804BF4C4; // type:object size:0x4 data:4byte -lbl_804BF4C8 = .sbss:0x804BF4C8; // type:object size:0x8 data:4byte -lbl_804BF4D0 = .sbss:0x804BF4D0; // type:object size:0x8 data:4byte -spInstance__13RPSysSceneMgr = .sbss:0x804BF4D8; // type:object size:0x8 data:4byte +sRenderModeFormat__11RPSysSystem = .sbss:0x804BF4C4; // type:object size:0x4 data:4byte +spInstance__17RPSysSceneCreator = .sbss:0x804BF4C8; // type:object size:0x8 data:4byte +sUnkStruct__10RPSysScene = .sbss:0x804BF4D0; // type:object size:0x4 data:4byte +spInstance__13RPSysSceneMgr = .sbss:0x804BF4D8; // type:object size:0x4 data:4byte spInstance__17RPSysProjectLocal = .sbss:0x804BF4E0; // type:object size:0x4 data:4byte spInstance__15RPSysGameConfig = .sbss:0x804BF4E8; // type:object size:0x4 data:4byte spInstance__20RPSysResourceManager = .sbss:0x804BF4F0; // type:object size:0x8 data:4byte @@ -21868,14 +21865,14 @@ lbl_804BF4F8 = .sbss:0x804BF4F8; // type:object size:0x8 data:4byte spInstance__14RPSysDvdStatus = .sbss:0x804BF500; // type:object size:0x4 data:4byte spInstance__16RPSysSaveDataMgr = .sbss:0x804BF508; // type:object size:0x8 data:4byte spInstance__16RPSysFontManager = .sbss:0x804BF510; // type:object size:0x8 data:4byte -lbl_804BF518 = .sbss:0x804BF518; // type:object size:0x8 data:4byte -lbl_804BF520 = .sbss:0x804BF520; // type:object size:0x8 data:4byte +spInstance__13RPSysPauseMgr = .sbss:0x804BF518; // type:object size:0x8 data:4byte +spInstance__14RPSysPlayerMgr = .sbss:0x804BF520; // type:object size:0x8 data:4byte spInstance__24RPSysHostIOSocketManager = .sbss:0x804BF528; // type:object size:0x4 data:4byte spInstance__15RP_DEBUG_STUB_0 = .sbss:0x804BF530; // type:object size:0x4 data:4byte spInstance__15RPSysTextWriter = .sbss:0x804BF538; // type:object size:0x4 data:4byte spInstance__19RPSysKokeshiManager = .sbss:0x804BF540; // type:object size:0x8 data:4byte -lbl_804BF548 = .sbss:0x804BF548; // type:object size:0x8 data:4byte -lbl_804BF550 = .sbss:0x804BF550; // type:object size:0x8 +spInstance__14RPSysEffectMgr = .sbss:0x804BF548; // type:object size:0x4 data:4byte +INVALID_HANDLE__11RPSysEffect = .sbss:0x804BF550; // type:object size:0x8 spTextBuffer__19RPSysWideTextWriter = .sbss:0x804BF558; // type:object size:0x4 data:4byte lbl_804BF560 = .sbss:0x804BF560; // type:object size:0x8 data:4byte spInstance__17RPSysTagProcessor = .sbss:0x804BF568; // type:object size:0x8 data:4byte @@ -21889,7 +21886,7 @@ lbl_804BF590 = .sbss:0x804BF590; // type:object size:0x8 align:4 data:float lbl_804BF598 = .sbss:0x804BF598; // type:object size:0x8 data:4byte lbl_804BF5A0 = .sbss:0x804BF5A0; // type:object size:0x8 data:4byte spInstance__16RPSysHomeMenuMgr = .sbss:0x804BF5A8; // type:object size:0x4 data:4byte -lbl_804BF5AC = .sbss:0x804BF5AC; // type:object size:0x4 data:4byte +spHomeMenuArcMgr__16RPSysHomeMenuMgr = .sbss:0x804BF5AC; // type:object size:0x4 data:4byte sIsBusy__15RPSysPairingMgr = .sbss:0x804BF5B0; // type:object size:0x1 data:byte sConnectionFlag__22RPSysCoreControllerMgr = .sbss:0x804BF5B8; // type:object size:0x2 data:2byte sPrevConnectionFlag__22RPSysCoreControllerMgr = .sbss:0x804BF5BA; // type:object size:0x2 data:2byte @@ -21908,11 +21905,11 @@ lbl_804BF5F0 = .sbss:0x804BF5F0; // type:object size:0x8 data:byte lbl_804BF5F8 = .sbss:0x804BF5F8; // type:object size:0x8 data:4byte spCurrent__20RPGrpModelResManager = .sbss:0x804BF600; // type:object size:0x8 data:4byte lbl_804BF608 = .sbss:0x804BF608; // type:object size:0x8 data:4byte -lbl_804BF610 = .sbss:0x804BF610; // type:object size:0x4 data:4byte +spCurrent__13RPGrpRenderer = .sbss:0x804BF610; // type:object size:0x4 data:4byte lbl_804BF614 = .sbss:0x804BF614; // type:object size:0x1 data:byte lbl_804BF615 = .sbss:0x804BF615; // type:object size:0x1 data:byte gap_11_804BF616_sbss = .sbss:0x804BF616; // type:object size:0x2 scope:global -lbl_804BF618 = .sbss:0x804BF618; // type:object size:0x4 data:4byte +spCurrentView__13RPGrpRenderer = .sbss:0x804BF618; // type:object size:0x4 data:4byte spCurrentScreen__13RPGrpRenderer = .sbss:0x804BF61C; // type:object size:0x4 data:4byte lbl_804BF620 = .sbss:0x804BF620; // type:object size:0x8 data:4byte lbl_804BF628 = .sbss:0x804BF628; // type:object size:0x8 data:byte @@ -21923,7 +21920,7 @@ spInstance__13RPSndAudioMgr = .sbss:0x804BF644; // type:object size:0x4 data:4by DAT_804bf648 = .sbss:0x804BF648; // type:object size:0x8 data:4byte spInstance__15RPSndSpeakerMgr = .sbss:0x804BF650; // type:object size:0x4 data:4byte spSoundArchivePlayer__12RPSndUtility = .sbss:0x804BF658; // type:object size:0x4 data:4byte -lbl_804BF660 = .sbss:0x804BF660; // type:object size:0x8 align:4 data:float +VEC2_ZERO__12RPUtlDohMath = .sbss:0x804BF660; // type:object size:0x8 align:4 data:float lbl_804BF668 = .sbss:0x804BF668; // type:object size:0x8 data:4byte lbl_804BF670 = .sbss:0x804BF670; // type:object size:0x4 data:4byte lbl_804BF674 = .sbss:0x804BF674; // type:object size:0x4 data:4byte @@ -23445,9 +23442,9 @@ lbl_804C1510 = .sdata2:0x804C1510; // type:object size:0x8 align:8 data:double lbl_804C1518 = .sdata2:0x804C1518; // type:object size:0x4 align:4 data:float lbl_804C151C = .sdata2:0x804C151C; // type:object size:0x4 align:4 data:float lbl_804C1520 = .sdata2:0x804C1520; // type:object size:0x8 align:4 data:float -lbl_804C1528 = .sdata2:0x804C1528; // type:object size:0x4 align:4 data:float +@27568 = .sdata2:0x804C1528; // type:object size:0x4 scope:local align:4 data:float gap_12_804C152C_sdata2 = .sdata2:0x804C152C; // type:object size:0x4 scope:global -lbl_804C1530 = .sdata2:0x804C1530; // type:object size:0x8 align:8 data:double +@27572 = .sdata2:0x804C1530; // type:object size:0x8 scope:local align:8 data:double lbl_804C1538 = .sdata2:0x804C1538; // type:object size:0x4 align:4 data:float lbl_804C153C = .sdata2:0x804C153C; // type:object size:0x4 align:4 data:float lbl_804C1540 = .sdata2:0x804C1540; // type:object size:0x8 align:4 data:float @@ -23481,15 +23478,15 @@ lbl_804C15B0 = .sdata2:0x804C15B0; // type:object size:0x8 align:8 data:double lbl_804C15B8 = .sdata2:0x804C15B8; // type:object size:0x4 align:4 data:float lbl_804C15BC = .sdata2:0x804C15BC; // type:object size:0x4 align:4 data:float lbl_804C15C0 = .sdata2:0x804C15C0; // type:object size:0x8 align:4 data:float -lbl_804C15C8 = .sdata2:0x804C15C8; // type:object size:0x4 align:4 data:float -lbl_804C15CC = .sdata2:0x804C15CC; // type:object size:0x4 align:4 data:float -lbl_804C15D0 = .sdata2:0x804C15D0; // type:object size:0x8 align:8 data:double -lbl_804C15D8 = .sdata2:0x804C15D8; // type:object size:0x4 align:4 data:float -lbl_804C15DC = .sdata2:0x804C15DC; // type:object size:0x4 align:4 data:float -lbl_804C15E0 = .sdata2:0x804C15E0; // type:object size:0x4 align:4 data:float -lbl_804C15E4 = .sdata2:0x804C15E4; // type:object size:0x4 align:4 data:float -lbl_804C15E8 = .sdata2:0x804C15E8; // type:object size:0x4 align:4 data:float -lbl_804C15EC = .sdata2:0x804C15EC; // type:object size:0x4 align:4 data:float +@26865 = .sdata2:0x804C15C8; // type:object size:0x4 scope:local align:4 data:float +@26866 = .sdata2:0x804C15CC; // type:object size:0x4 scope:local align:4 data:float +@26867 = .sdata2:0x804C15D0; // type:object size:0x8 scope:local align:8 data:double +@26905 = .sdata2:0x804C15D8; // type:object size:0x4 scope:local align:4 data:float +@26906 = .sdata2:0x804C15DC; // type:object size:0x4 scope:local align:4 data:float +@26530 = .sdata2:0x804C15E0; // type:object size:0x4 scope:local align:4 data:float +@26531 = .sdata2:0x804C15E4; // type:object size:0x4 scope:local align:4 data:float +@26793 = .sdata2:0x804C15E8; // type:object size:0x4 scope:local align:4 data:float +@26952 = .sdata2:0x804C15EC; // type:object size:0x4 scope:local align:4 data:float CPU_COLOR__11RPSysLayout = .sdata2:0x804C15F0; // type:object size:0x4 lbl_804C15F4 = .sdata2:0x804C15F4; // type:object size:0x1 data:byte lbl_804C15F5 = .sdata2:0x804C15F5; // type:object size:0x1 data:byte @@ -23504,13 +23501,13 @@ lbl_804C1610 = .sdata2:0x804C1610; // type:object size:0x8 align:8 data:double @17539 = .sdata2:0x804C1618; // type:object size:0x8 scope:local align:8 data:double @17541 = .sdata2:0x804C1620; // type:object size:0x4 scope:local align:4 data:float @17542 = .sdata2:0x804C1624; // type:object size:0x4 scope:local align:4 data:float -lbl_804C1628 = .sdata2:0x804C1628; // type:object size:0x4 align:4 data:float +@26254 = .sdata2:0x804C1628; // type:object size:0x4 scope:local align:4 data:float gap_12_804C162C_sdata2 = .sdata2:0x804C162C; // type:object size:0x4 scope:global -lbl_804C1630 = .sdata2:0x804C1630; // type:object size:0x8 align:8 data:double -lbl_804C1638 = .sdata2:0x804C1638; // type:object size:0x8 align:8 data:double -lbl_804C1640 = .sdata2:0x804C1640; // type:object size:0x4 align:4 data:float -lbl_804C1644 = .sdata2:0x804C1644; // type:object size:0x4 align:4 data:float -lbl_804C1648 = .sdata2:0x804C1648; // type:object size:0x4 align:4 data:float +@26258 = .sdata2:0x804C1630; // type:object size:0x8 scope:local align:8 data:double +@26259 = .sdata2:0x804C1638; // type:object size:0x8 scope:local align:8 data:double +@26310 = .sdata2:0x804C1640; // type:object size:0x4 scope:local align:4 data:float +@26311 = .sdata2:0x804C1644; // type:object size:0x4 scope:local align:4 data:float +@26522 = .sdata2:0x804C1648; // type:object size:0x4 scope:local align:4 data:float gap_12_804C164C_sdata2 = .sdata2:0x804C164C; // type:object size:0x4 scope:global @17696 = .sdata2:0x804C1650; // type:object size:0x8 scope:local align:8 data:double @17700 = .sdata2:0x804C1658; // type:object size:0x8 scope:local align:8 data:double @@ -23710,7 +23707,7 @@ lbl_804C1988 = .sdata2:0x804C1988; // type:object size:0x8 align:4 data:float @10717 = .sdata2:0x804C1990; // type:object size:0x4 scope:local align:4 data:float gap_12_804C1994_sdata2 = .sdata2:0x804C1994; // type:object size:0x4 scope:global @10720 = .sdata2:0x804C1998; // type:object size:0x8 scope:local align:8 data:double -lbl_804C19A0 = .sdata2:0x804C19A0; // type:object size:0x4 align:4 data:float +FLOAT_EPSILON__12RPUtlDohMath = .sdata2:0x804C19A0; // type:object size:0x4 align:4 data:float lbl_804C19A4 = .sdata2:0x804C19A4; // type:object size:0x4 align:4 data:float lbl_804C19A8 = .sdata2:0x804C19A8; // type:object size:0x4 align:4 data:float lbl_804C19AC = .sdata2:0x804C19AC; // type:object size:0x4 align:4 data:float diff --git a/configure.py b/configure.py index 6a143faf1..6a9af3e1b 100755 --- a/configure.py +++ b/configure.py @@ -421,6 +421,12 @@ def find_directories(root_path: str, recursive: bool) -> list[str]: "-i include/Pack", ] +# RP flags (include precompiled header) +cflags_rp_pch = [ + *cflags_rp, + "-prefix SportsPack.mch" +] + config.linker_version = "GC/3.0a5.2" @@ -436,6 +442,13 @@ def MatchingFor(*versions): config.warn_missing_config = True config.warn_missing_source = False +config.precompiled_headers = [ + { + "source": "SportsPack.pch", + "mw_version": config.linker_version, + "cflags": ["-lang=c++", *cflags_rp], + }, +] config.libs = [ { "lib": "libnw4r_ut", @@ -1144,7 +1157,7 @@ def MatchingFor(*versions): { "lib": "RP", "mw_version": config.linker_version, - "cflags": cflags_rp, + "cflags": cflags_rp_pch, "progress_category": "kernel", # str | List[str] "objects": [ Object(Matching, "main.cpp"), @@ -1157,11 +1170,11 @@ def MatchingFor(*versions): Object(NonMatching, "Pack/RPKernel/RPSysKokeshi.cpp"), Object(NonMatching, "Pack/RPKernel/RPSysKokeshiManager.cpp"), Object(Matching, "Pack/RPKernel/RP_DEBUG_STUB_1.cpp"), - Object(NonMatching, "Pack/RPKernel/RPSysEffectMgr.cpp"), - Object(NonMatching, "Pack/RPKernel/RPSysEffectBase.cpp"), + Object(Matching, "Pack/RPKernel/RPSysEffectMgr.cpp"), + Object(Matching, "Pack/RPKernel/RPSysEffectBase.cpp"), Object(NonMatching, "Pack/RPKernel/RPSysLayout.cpp"), Object(Matching, "Pack/RPKernel/RPSysFrameCtrl.cpp"), - Object(NonMatching, "Pack/RPKernel/RPSysEffectCreator.cpp"), + Object(Matching, "Pack/RPKernel/RPSysEffectCreator.cpp"), Object(Matching, "Pack/RPKernel/RPSysWideTextWriter.cpp"), Object(Matching, "Pack/RPKernel/RPSysLytAnmObj.cpp"), Object(Matching, "Pack/RPKernel/RPSysLytResAccessor.cpp"), @@ -1180,7 +1193,7 @@ def MatchingFor(*versions): Object(Matching, "Pack/RPKernel/RPSysMiddleDBGenInfo.cpp"), Object(Matching, "Pack/RPKernel/RPSysMiddleDB.cpp"), Object(Matching, "Pack/RPKernel/RPSysLytAllocator.cpp"), - Object(NonMatching, "Pack/RPKernel/RPSysLytDynamicAnm.cpp"), + Object(Matching, "Pack/RPKernel/RPSysLytDynamicAnm.cpp"), Object(Matching, "Pack/RPKernel/RPSysKokeshiIterater.cpp"), Object(NonMatching, "Pack/RPKernel/RPSysCursorDrawMgr.cpp"), Object(Matching, "Pack/RPKernel/RPSysStringUtility.cpp"), @@ -1192,23 +1205,23 @@ def MatchingFor(*versions): Object(Matching, "Pack/RPKernel/RPSysLytWindow.cpp"), Object(Matching, "Pack/RPKernel/RPSysKokeshiCtrlDataMgr.cpp"), Object(Matching, "Pack/RPKernel/RPSysKokeshiCtrlMgr.cpp"), - Object(NonMatching, "Pack/RPKernel/RPSysAppMiiManager.cpp"), + Object(Matching, "Pack/RPKernel/RPSysAppMiiManager.cpp"), Object(Matching, "Pack/RPKernel/RPSysPairingMgr.cpp"), Object(NonMatching, "Pack/RPKernel/RPSysControllerMgr.cpp"), - Object(NonMatching, "Pack/RPKernel/RPSysNWC24Manager.cpp"), + Object(Matching, "Pack/RPKernel/RPSysNWC24Manager.cpp"), Object(NonMatching, "Pack/RPKernel/RPSysParticleManager.cpp"), ], }, { "lib": "RP", "mw_version": config.linker_version, - "cflags": cflags_rp, + "cflags": cflags_rp_pch, "progress_category": "system", # str | List[str] "objects": [ Object(NonMatching, "Pack/RPSystem/RPSysSceneCreator.cpp"), - Object(NonMatching, "Pack/RPSystem/RPSysScene.cpp"), - Object(NonMatching, "Pack/RPSystem/RPSysRenderMode.cpp"), - Object(NonMatching, "Pack/RPSystem/RPSysSceneMgr.cpp"), + Object(Matching, "Pack/RPSystem/RPSysScene.cpp"), + Object(Matching, "Pack/RPSystem/RPSysRenderMode.cpp"), + Object(Matching, "Pack/RPSystem/RPSysSceneMgr.cpp"), Object(Matching, "Pack/RPSystem/RPSysProjectLocal.cpp"), Object(Matching, "Pack/RPSystem/RPSysGameConfig.cpp"), Object(NonMatching, "Pack/RPSystem/RPSysTagParms.cpp"), @@ -1233,7 +1246,7 @@ def MatchingFor(*versions): { "lib": "RP", "mw_version": config.linker_version, - "cflags": cflags_rp, + "cflags": cflags_rp_pch, "progress_category": "graphics", # str | List[str] "objects": [ Object(Matching, "Pack/RPGraphics/RPGrpCamera.cpp"), @@ -1268,14 +1281,14 @@ def MatchingFor(*versions): { "lib": "RP", "mw_version": config.linker_version, - "cflags": cflags_rp, + "cflags": cflags_rp_pch, "progress_category": "audio", # str | List[str] "objects": [ Object(NonMatching, "Pack/RPAudio/RPSndAudioMgr.cpp"), Object(Matching, "Pack/RPAudio/RPSndSpeakerMgr.cpp"), Object(Matching, "Pack/RPAudio/RPSndObject.cpp"), Object(Matching, "Pack/RPAudio/RPSndUtility.cpp"), - Object(NonMatching, "Pack/RPAudio/RPSndMoveParam.cpp"), + Object(Matching, "Pack/RPAudio/RPSndMoveParam.cpp"), Object(Matching, "Pack/RPAudio/RPSndHomeMenuArcMgr.cpp"), Object(Matching, "Pack/RPAudio/RPSndStaticMgr.cpp"), ], @@ -1283,17 +1296,33 @@ def MatchingFor(*versions): { "lib": "RP", "mw_version": config.linker_version, - "cflags": cflags_rp, + "cflags": cflags_rp_pch, "progress_category": "utility", # str | List[str] "objects": [ - Object(NonMatching, "Pack/RPUtility/RPUtlDohMath.cpp"), + Object(Matching, "Pack/RPUtility/RPUtlDohMath.cpp"), + Object(NonMatching, "Pack/RPUtility/RPUtlRigid.cpp"), + Object(NonMatching, "Pack/RPUtility/RPUtlAccAnalyzer.cpp"), + Object(NonMatching, "Pack/RPUtility/RPUtlCollisionModel.cpp"), + Object(NonMatching, "Pack/RPUtility/RP_DEBUG_STUB_2.cpp"), + Object(NonMatching, "Pack/RPUtility/RPUtlCollisionChecker.cpp"), + Object(NonMatching, "Pack/RPUtility/RPUtlSimpleShadow.cpp"), + Object(NonMatching, "Pack/RPUtility/RPUtlGameResourceMgr.cpp"), + Object(NonMatching, "Pack/RPUtility/RPUtlDirMath.cpp"), + Object(NonMatching, "Pack/RPUtility/RPUtlRand.cpp"), + Object(NonMatching, "Pack/RPUtility/RPUtlModel.cpp"), + Object(NonMatching, "Pack/RPUtility/RPUtlViewClipper.cpp"), + Object(NonMatching, "Pack/RPUtility/RPUtlRandom.cpp"), + Object(NonMatching, "Pack/RPUtility/RPUtlMath.cpp"), + Object(NonMatching, "Pack/RPUtility/RPUtlMapData.cpp"), + Object(NonMatching, "Pack/RPUtility/RPUtlShadowDrawer.cpp"), + Object(NonMatching, "Pack/RPUtility/RPUtlObject.cpp"), Object(NonMatching, "Pack/RPUtility_unsplit.o"), ], }, { "lib": "RP", "mw_version": config.linker_version, - "cflags": cflags_rp, + "cflags": cflags_rp_pch, "progress_category": "sports", # str | List[str] "objects": [ Object(NonMatching, "Pack/RPSports/RPSportsCommon/RPSportsCommon_unsplit.o"), @@ -1302,7 +1331,7 @@ def MatchingFor(*versions): { "lib": "RP", "mw_version": config.linker_version, - "cflags": cflags_rp, + "cflags": cflags_rp_pch, "progress_category": "tennis", # str | List[str] "objects": [ Object(NonMatching, "Pack/RPSports/RPTnsScene/RPTnsScene_unsplit.o"), @@ -1311,7 +1340,7 @@ def MatchingFor(*versions): { "lib": "RP", "mw_version": config.linker_version, - "cflags": cflags_rp, + "cflags": cflags_rp_pch, "progress_category": "baseball", # str | List[str] "objects": [ Object(NonMatching, "Pack/RPSports/RPBsbScene/RPBsbScene_unsplit.o"), @@ -1320,16 +1349,40 @@ def MatchingFor(*versions): { "lib": "RP", "mw_version": config.linker_version, - "cflags": cflags_rp, + "cflags": cflags_rp_pch, "progress_category": "golf", # str | List[str] "objects": [ + Object(NonMatching, "Pack/RPSports/RPGolScene/RPGolScene.cpp"), + Object(NonMatching, "Pack/RPSports/RPGolScene/RPGolMain.cpp"), + Object(NonMatching, "Pack/RPSports/RPGolScene/RPGolResourceManager.cpp"), + Object(NonMatching, "Pack/RPSports/RPGolScene/RPGolCameraManager.cpp"), + Object(NonMatching, "Pack/RPSports/RPGolScene/RPGolMapObjBase.cpp"), + Object(NonMatching, "Pack/RPSports/RPGolScene/RPGolFieldManager.cpp"), + Object(NonMatching, "Pack/RPSports/RPGolScene/RPGolDrawManager.cpp"), + Object(NonMatching, "Pack/RPSports/RPGolScene/RPGolUtlMtx.cpp"), + Object(NonMatching, "Pack/RPSports/RPGolScene/RPGolUtlVec.cpp"), + Object(NonMatching, "Pack/RPSports/RPGolScene/RPGolMapObjTree.cpp"), + Object(NonMatching, "Pack/RPSports/RPGolScene/RPGolMapObjTreeWater.cpp"), + Object(NonMatching, "Pack/RPSports/RPGolScene/RPGolMapObjTee.cpp"), + Object(NonMatching, "Pack/RPSports/RPGolScene/RPGolMapObjBall.cpp"), + Object(NonMatching, "Pack/RPSports/RPGolScene/RPGolSimulateManager.cpp"), + Object(NonMatching, "Pack/RPSports/RPGolScene/RPGolCamera.cpp"), + Object(NonMatching, "Pack/RPSports/RPGolScene/RPGolCameraStatic.cpp"), + Object(NonMatching, "Pack/RPSports/RPGolScene/RPGolConfig.cpp"), + Object(NonMatching, "Pack/RPSports/RPGolScene/RPGolPlayer.cpp"), + Object(NonMatching, "Pack/RPSports/RPGolScene/RPGolPlayerManager.cpp"), + Object(NonMatching, "Pack/RPSports/RPGolScene/RPGolMath.cpp"), + Object(NonMatching, "Pack/RPSports/RPGolScene/RPGol_802a3a6c.cpp"), + Object(NonMatching, "Pack/RPSports/RPGolScene/RPGolMathTrig.cpp"), + Object(NonMatching, "Pack/RPSports/RPGolScene/RPGolKCol.cpp"), + Object(NonMatching, "Pack/RPSports/RPGolScene/RPGolCameraTilt.cpp"), Object(NonMatching, "Pack/RPSports/RPGolScene/RPGolScene_unsplit.o"), ], }, { "lib": "RP", "mw_version": config.linker_version, - "cflags": cflags_rp, + "cflags": cflags_rp_pch, "progress_category": "boxing", # str | List[str] "objects": [ Object(NonMatching, "Pack/RPSports/RPBoxScene/RPBoxScene_unsplit.o"), @@ -1338,10 +1391,65 @@ def MatchingFor(*versions): { "lib": "RP", "mw_version": config.linker_version, - "cflags": cflags_rp, + "cflags": cflags_rp_pch, "progress_category": "bowling", # str | List[str] "objects": [ - Object(NonMatching, "Pack/RPSports/RPBowScene/RPBowScene_unsplit.o"), + Object(NonMatching, "Pack/RPSports/RPBowScene/RPBow_80313028.cpp"), + Object(NonMatching, "Pack/RPSports/RPBowScene/RPBow_80315998.cpp"), + Object(NonMatching, "Pack/RPSports/RPBowScene/RPBow_8031641C.cpp"), + Object(NonMatching, "Pack/RPSports/RPBowScene/RPBow_80319C98.cpp"), + Object(NonMatching, "Pack/RPSports/RPBowScene/RPBowSwing.cpp"), + Object(NonMatching, "Pack/RPSports/RPBowScene/RPBow_8031C388.cpp"), + Object(NonMatching, "Pack/RPSports/RPBowScene/RPBow_8031EFE4.cpp"), + Object(NonMatching, "Pack/RPSports/RPBowScene/RPBow_80320EFC.cpp"), + Object(NonMatching, "Pack/RPSports/RPBowScene/RPBow_80323790.cpp"), + Object(NonMatching, "Pack/RPSports/RPBowScene/RPBow_80327F0C.cpp"), + Object(NonMatching, "Pack/RPSports/RPBowScene/RPBow_80329350.cpp"), + Object(NonMatching, "Pack/RPSports/RPBowScene/RPBow_80329658.cpp"), + Object(NonMatching, "Pack/RPSports/RPBowScene/RPBowActiveBall.cpp"), + Object(NonMatching, "Pack/RPSports/RPBowScene/RPBow_8032ADD8.cpp"), + Object(NonMatching, "Pack/RPSports/RPBowScene/RPBow_8032EA58.cpp"), + Object(NonMatching, "Pack/RPSports/RPBowScene/RPBowGlobalLaneManager.cpp"), + Object(NonMatching, "Pack/RPSports/RPBowScene/RPBow_80330EBC.cpp"), + Object(NonMatching, "Pack/RPSports/RPBowScene/RPBow_80330FE8.cpp"), + Object(NonMatching, "Pack/RPSports/RPBowScene/RPBowNpcManager.cpp"), + Object(NonMatching, "Pack/RPSports/RPBowScene/RPBowManagerContext.cpp"), + Object(NonMatching, "Pack/RPSports/RPBowScene/RPBow_80332C24.cpp"), + Object(NonMatching, "Pack/RPSports/RPBowScene/RPBow_80332D14.cpp"), + Object(NonMatching, "Pack/RPSports/RPBowScene/RPBowPinSetter.cpp"), + Object(NonMatching, "Pack/RPSports/RPBowScene/RPBow_803349E0.cpp"), + Object(NonMatching, "Pack/RPSports/RPBowScene/RPBow_803363D0.cpp"), + Object(NonMatching, "Pack/RPSports/RPBowScene/RPBow_803381DC.cpp"), + Object(NonMatching, "Pack/RPSports/RPBowScene/RPBow_8033A558.cpp"), + Object(NonMatching, "Pack/RPSports/RPBowScene/RPBow_8033B690.cpp"), + Object(NonMatching, "Pack/RPSports/RPBowScene/RPBow_8033FD0C.cpp"), + Object(NonMatching, "Pack/RPSports/RPBowScene/RPBowObstacleManager.cpp"), + Object(NonMatching, "Pack/RPSports/RPBowScene/RPBow_80340C34.cpp"), + Object(NonMatching, "Pack/RPSports/RPBowScene/RPBow_803433E4.cpp"), + Object(NonMatching, "Pack/RPSports/RPBowScene/RPBow_8034656C.cpp"), + Object(NonMatching, "Pack/RPSports/RPBowScene/RPBowPlayerLaneNpc.cpp"), + Object(NonMatching, "Pack/RPSports/RPBowScene/RPBow_80347574.cpp"), + Object(NonMatching, "Pack/RPSports/RPBowScene/RPBow_80347D0C.cpp"), + Object(NonMatching, "Pack/RPSports/RPBowScene/RPBow_80348158.cpp"), + Object(NonMatching, "Pack/RPSports/RPBowScene/RPBow_80348858.cpp"), + Object(NonMatching, "Pack/RPSports/RPBowScene/RPBow_8034C1AC.cpp"), + Object(NonMatching, "Pack/RPSports/RPBowScene/RPBow_8034C95C.cpp"), + Object(NonMatching, "Pack/RPSports/RPBowScene/RPBowMotionBlur.cpp"), + Object(NonMatching, "Pack/RPSports/RPBowScene/RPBowBallReturnRack.cpp"), + Object(NonMatching, "Pack/RPSports/RPBowScene/RPBowBackgroundNpcManager.cpp"), + Object(NonMatching, "Pack/RPSports/RPBowScene/RPBow_8034E974.cpp"), + Object(NonMatching, "Pack/RPSports/RPBowScene/RPBow_8034F710.cpp"), + Object(NonMatching, "Pack/RPSports/RPBowScene/RPBow_803501D8.cpp"), + Object(NonMatching, "Pack/RPSports/RPBowScene/RPBow_80350F78.cpp"), + Object(NonMatching, "Pack/RPSports/RPBowScene/RPBow_80351D58.cpp"), + Object(NonMatching, "Pack/RPSports/RPBowScene/RPBow_803520F0.cpp"), + Object(NonMatching, "Pack/RPSports/RPBowScene/RPBow_80353214.cpp"), + Object(NonMatching, "Pack/RPSports/RPBowScene/RPBow_803536C4.cpp"), + Object(NonMatching, "Pack/RPSports/RPBowScene/RPBow_80353C8C.cpp"), + Object(NonMatching, "Pack/RPSports/RPBowScene/RPBowTrajectoryGuide.cpp"), + Object(NonMatching, "Pack/RPSports/RPBowScene/RPBow_803547A4.cpp"), + Object(NonMatching, "Pack/RPSports/RPBowScene/RPBow_80354C78.cpp"), + Object(NonMatching, "Pack/RPSports/RPBowScene/RPBow_80354CAC.cpp") ], }, ] diff --git a/include/Pack/RPAudio/RPSndHomeMenuArcMgr.h b/include/Pack/RPAudio/RPSndHomeMenuArcMgr.h index c1620125f..e6365bf44 100644 --- a/include/Pack/RPAudio/RPSndHomeMenuArcMgr.h +++ b/include/Pack/RPAudio/RPSndHomeMenuArcMgr.h @@ -35,6 +35,16 @@ class RPSndHomeMenuArcMgr : public EGG::SoundHeapMgr, public EGG::ArcPlayer { */ bool setupArchive(const void* pBinary); + /** + * @brief Attempts to start the specified sound + * + * @param id Sound ID + * @return Success + */ + bool startSe(u32 id) { + return startSound(&mSoundHandle, id); + } + private: //! Active sound handle nw4r::snd::SoundHandle mSoundHandle; // at 0x6A4 diff --git a/include/Pack/RPAudio/RPSndMoveParam.h b/include/Pack/RPAudio/RPSndMoveParam.h index d935565bd..f138b3601 100644 --- a/include/Pack/RPAudio/RPSndMoveParam.h +++ b/include/Pack/RPAudio/RPSndMoveParam.h @@ -48,6 +48,15 @@ class RPSndMoveValueF32 { */ virtual bool update(); // at 0x8 + /** + * @brief Updates the interpolation state + * @note This is used to call update with an instance of the base class + * @return Whether interpolation is ongoing + */ + bool doUpdate() { + return update(); + } + /** * @brief Gets the number of remaining interpolation frames */ diff --git a/include/Pack/RPAudio/RPSndObject.h b/include/Pack/RPAudio/RPSndObject.h index 8350933f7..d4948313b 100644 --- a/include/Pack/RPAudio/RPSndObject.h +++ b/include/Pack/RPAudio/RPSndObject.h @@ -223,15 +223,9 @@ class RPSndObjMgr { * @brief Updates the state of all active sounds */ static void update() { - RPSndAudioActorBase* pIt = static_cast( - nw4r::ut::List_GetFirst(&RPSndAudioActorBase::sActorList)); - - for (; pIt != NULL; - pIt = static_cast(nw4r::ut::List_GetNext( - &RPSndAudioActorBase::sActorList, pIt))) { - - if (pIt->mVolume.getFrame() > 0) { - pIt->update(); + RP_NW4R_LIST_FOREACH(RPSndAudioActorBase, it, RPSndAudioActorBase::sActorList) { + if (it->mVolume.getFrame() > 0) { + it->update(); } } } diff --git a/include/Pack/RPGraphics.h b/include/Pack/RPGraphics.h index 3dc6abaa4..75160af7b 100644 --- a/include/Pack/RPGraphics.h +++ b/include/Pack/RPGraphics.h @@ -1,6 +1,7 @@ #ifndef RP_PUBLIC_GRAPHICS_H #define RP_PUBLIC_GRAPHICS_H +#include #include #include #include @@ -31,5 +32,6 @@ #include #include #include +#include #endif diff --git a/include/Pack/RPGraphics/IRPGrpDrawObject.h b/include/Pack/RPGraphics/IRPGrpDrawObject.h new file mode 100644 index 000000000..a20e87ae4 --- /dev/null +++ b/include/Pack/RPGraphics/IRPGrpDrawObject.h @@ -0,0 +1,40 @@ +#ifndef RP_GRAPHICS_I_DRAW_OBJECT_H +#define RP_GRAPHICS_I_DRAW_OBJECT_H +#include + +//! @addtogroup rp_graphics +//! @{ + +/** + * @brief Interface for renderable objects + */ +class IRPGrpDrawObject { +private: + //! Next renderable in the linked list + IRPGrpDrawObject* mpNext; // at 0x0 + +public: + /** + * @brief Constructor + */ + IRPGrpDrawObject() : mpNext(NULL) {} + + /** + * @brief Destructor + */ + virtual ~IRPGrpDrawObject() {} // at 0x8 + + /** + * @brief Standard draw pass + */ + virtual void UserDraw() {} // at 0xC + + /** + * @brief Additional draw pass for debugging + */ + virtual void DebugDraw() {} // at 0x10 +}; + +//! @} + +#endif diff --git a/include/Pack/RPGraphics/RPGrpRenderer.h b/include/Pack/RPGraphics/RPGrpRenderer.h index 984a707f4..28e40563b 100644 --- a/include/Pack/RPGraphics/RPGrpRenderer.h +++ b/include/Pack/RPGraphics/RPGrpRenderer.h @@ -2,11 +2,15 @@ #define RP_GRAPHICS_RENDERER_H #include +#include + //! @addtogroup rp_graphics //! @{ // Forward declarations +class IRPGrpDrawObject; class RPGrpScreen; +class RPGrpView; /** * @brief Rendering engine @@ -24,6 +28,13 @@ class RPGrpRenderer { return spCurrent; } + /** + * @brief Gets the view currently being rendered to + */ + static RPGrpView* GetCurrentView() { + return spCurrentView; + } + /** * @brief Gets the screen currently being rendered to */ @@ -31,10 +42,32 @@ class RPGrpRenderer { return spCurrentScreen; } + static void Begin(); + static void End(); + + static void StartDebugDraw(); + + static RPGrpRenderer* Construct(EGG::Allocator* pAllocator, u16 id); + + void Rendering(); + void Destruct(); + void BecomeCurrent(); + + void AppendDrawObject(IRPGrpDrawObject* pObject); + void AppendDrawObject(IRPGrpDrawObject& rObject) { + AppendDrawObject(&rObject); + } + + void PreCalculate(); + void PostCalculate(); + void CalculateInPause(); + private: //! Allocator used for model-related allocations static RPGrpRenderer* spCurrent; + //! View currently being rendered to + static RPGrpView* spCurrentView; //! Screen currently being rendered to static RPGrpScreen* spCurrentScreen; }; diff --git a/include/Pack/RPGraphics/RPGrpView.h b/include/Pack/RPGraphics/RPGrpView.h new file mode 100644 index 000000000..60f91dcb5 --- /dev/null +++ b/include/Pack/RPGraphics/RPGrpView.h @@ -0,0 +1,45 @@ +#ifndef RP_GRAPHICS_VIEW_H +#define RP_GRAPHICS_VIEW_H +#include + +//! @addtogroup rp_graphics +//! @{ + +// Forward declarations +class RPGrpCamera; + +class RPGrpView { +public: + enum EProjType { + EProjType_Persp, + EProjType_Ortho, + EProjType_Max, + }; + +protected: + u8 mViewNo; // at 0x0 + u8 mDrawScene; // at 0x1 + char _02[0x8 - 0x2]; + EProjType mProjType; // at 0x8 + char _0C[0x1C - 0xC]; + +public: + virtual ~RPGrpView(); // at 0x8 + virtual UNKTYPE VF_0xC(UNKTYPE) = 0; // at 0xC + virtual void AttachCamera(RPGrpCamera* pCamera) = 0; // at 0x10 + + void SetDrawScene(u8 scene) { + mDrawScene = scene; + } + + EProjType GetProjType() const { + return mProjType; + } + +private: + ; +}; + +//! @} + +#endif diff --git a/include/Pack/RPKernel.h b/include/Pack/RPKernel.h index 9912de53d..17f7c4122 100644 --- a/include/Pack/RPKernel.h +++ b/include/Pack/RPKernel.h @@ -8,6 +8,11 @@ #include #include #include +#include +#include +#include +#include +#include #include #include #include @@ -37,8 +42,10 @@ #include #include #include +#include #include #include +#include #include #include #include diff --git a/include/Pack/RPKernel/RPSysAppMiiManager.h b/include/Pack/RPKernel/RPSysAppMiiManager.h index 5faa7927b..9a0c7eed3 100644 --- a/include/Pack/RPKernel/RPSysAppMiiManager.h +++ b/include/Pack/RPKernel/RPSysAppMiiManager.h @@ -31,7 +31,7 @@ class RPSysAppMiiManager { /** * @brief Destructor */ - virtual ~RPSysAppMiiManager() {} // at 0x8 + virtual ~RPSysAppMiiManager(); // at 0x8 /** * @brief Loads the Mii data resources diff --git a/include/Pack/RPKernel/RPSysController.h b/include/Pack/RPKernel/RPSysController.h index 6d6d73deb..cfe506684 100644 --- a/include/Pack/RPKernel/RPSysController.h +++ b/include/Pack/RPKernel/RPSysController.h @@ -126,7 +126,7 @@ class RPSysCoreInfo : public WPADInfo { private: //! Information flags - u16 mFlags; // at 0x0 + u16 mFlags; // at 0x18 }; /****************************************************************************** @@ -307,9 +307,9 @@ class RPSysCoreController : public EGG::CoreController, /** * @brief Constructor * - * @param id Unique ID + * @param playerNo Player ID */ - RPSysCoreController(u32 id); + explicit RPSysCoreController(u32 playerNo); /** * @brief Destructor diff --git a/include/Pack/RPKernel/RPSysEffectBase.h b/include/Pack/RPKernel/RPSysEffectBase.h new file mode 100644 index 000000000..5a19ad9e7 --- /dev/null +++ b/include/Pack/RPKernel/RPSysEffectBase.h @@ -0,0 +1,330 @@ +#ifndef RP_KERNEL_EFFECT_BASE_H +#define RP_KERNEL_EFFECT_BASE_H +#include + +#include + +#include +#include + +//! @addtogroup rp_kernel +//! @{ + +/** + * @brief Effect wrapper + */ +class RPSysEffect { +public: + /** + * @brief Constructor + * + * @param pName Effect name + * @param drawGroup Effect draw group + * @param drawScene Effect draw scene + */ + RPSysEffect(const char* pName, u32 drawGroup, u32 drawScene); + + /** + * @brief Destructor + */ + virtual ~RPSysEffect(); // at 0x8 + + /** + * @brief Creates this effect if it does not yet exist + * + * @return Success + */ + virtual bool create(); // at 0xC + + /** + * @brief Fades away and destroys this effect + */ + virtual void fade(); // at 0x10 + + /** + * @brief Fades away this effect without destroying the handle + */ + virtual void followFade(); // at 0x14 + + /** + * @brief Destroys this effect and all of its particles + */ + virtual void forceKill(); // at 0x18 + + /** + * @brief Toggles whether this effect will update + * + * @param disable Whether to disable updating + */ + virtual void setDisableCalc(bool disable); // at 0x1C + + /** + * @brief Toggles whether this effect will draw + * + * @param disable Whether to disable drawing + */ + virtual void setDisableDraw(bool disable); // at 0x20 + + /** + * @brief Toggles whether this effect will update and draw + * + * @param disable Whether to disable both updating and drawing + */ + virtual void setDisableCalcDraw(bool disable); // at 0x24 + + /** + * @brief Sets the lifetime of all particles + * + * @param life Lifetime, in ticks + */ + virtual void setLife(u16 life); // at 0x28 + + /** + * @brief Sets the emission ratio of all emitters + * + * @param ratio Emission ratio + */ + virtual void setEmitRatio(f32 ratio); // at 0x2C + + /** + * @brief Sets the emission interval of all emitters + * + * @param interval Emission interval + */ + virtual void setEmitInterval(u16 interval); // at 0x30 + + /** + * @brief Sets the number of circular divisions of all emitters + * + * @param emitDiv Number of emitter divisions + */ + virtual void setEmitEmitDiv(u16 emitDiv); // at 0x34 + + /** + * @brief Sets the emission power in the radiation direction + * + * @param power Emission power + */ + virtual void setPowerRadiationDir(f32 power); // at 0x38 + + /** + * @brief Sets the emission power in the specified direction + * + * @param power Emission power + */ + virtual void setPowerSpecDir(f32 power); // at 0x3C + + /** + * @brief Adds emission power in the specified direction + * + * @param add Emission power addend + */ + virtual void setPowerSpecDirAdd(f32 add); // at 0x40 + + /** + * @brief Sets the specified direction of emission + * + * @param rDir Specified direction + */ + virtual void setSpecDir(const nw4r::math::VEC3& rDir); // at 0x44 + + /** + * @brief Adds to the specified direction of emission + * + * @param rDir Specified direction addend + */ + virtual void setSpecDirAdd(const nw4r::math::VEC3& rAdd); // at 0x48 + + /** + * @brief Sets this effect's velocity + * + * @param rVelocity Velocity + */ + virtual void setVelocity(const nw4r::math::VEC3& rVelocity); // at 0x4C + + /** + * @brief Sets the color of all particles + * + * @param r Color red component + * @param g Color green component + * @param b Color blue component + * @param a Color alpha component + */ + virtual void setColor(u8 r, u8 g, u8 b, u8 a); // at 0x50 + + /** + * @brief Sets the color of all particles + * @details This function assumes full alpha + * + * @param r Color red component + * @param g Color green component + * @param b Color blue component + */ + virtual void setColor(u8 r, u8 g, u8 b); // at 0x54 + + /** + * @brief Sets the color alpha component of all particles + * @details This function assumes a white color + * + * @param a Color alpha component + */ + virtual void setColor(u8 a); // at 0x58 + + /** + * @brief Sets the default size of all particles + * + * @param rSize Default particle size + */ + virtual void + setDefaultParticleSize(const nw4r::math::VEC2& rSize); // at 0x5C + + /** + * @brief Sets the scale of all particles + * + * @param rSize Particle scale + */ + virtual void setParticleScale(nw4r::math::VEC2& rScale); // at 0x60 + + /** + * @brief Sets the default rotation of all particles + * + * @param rRotate Default particle rotation + */ + virtual void + setDefaultParticleRotate(const nw4r::math::VEC3& rRotate); // at 0x64 + + /** + * @brief Sets the rotation of all particles + * + * @param rRotate Particle rotation + */ + virtual void setParticleRotate(const nw4r::math::VEC3& rRotate); // at 0x68 + + /** + * @brief Sets the scale of all emitters + * + * @param rScale Emitter scale + */ + virtual void setLocalScale(const nw4r::math::VEC3& rScale); // at 0x6C + + /** + * @brief Sets this effect's scale without also indirectly scaling particles + * + * @param rScale New effect scale + * @param pParticleScale Current particle scale (optional) + */ + virtual void + setDynamicsScale(const nw4r::math::VEC3& rScale, + const nw4r::math::VEC2* pParticleScale); // at 0x70 + + /** + * @brief Sets this effect's scale + * + * @param scale Effect scale (uniform) + */ + virtual void setScale(f32 scale); // at 0x74 + + /** + * @brief Sets this effect's scale + * + * @param rScale Effect scale + */ + virtual void setScale(const nw4r::math::VEC3& rScale); // at 0x78 + + /** + * @brief Sets this effect's position + * + * @param rPosition Effect position + */ + virtual void setPos(const nw4r::math::VEC3& rPosition); // at 0x7C + + /** + * @brief Sets this effect's transformation matrix + * + * @param rTransform Effect transformation matrix + */ + virtual void setMtx(const nw4r::math::MTX34& rTransform); // at 0x80 + + /** + * @brief Toggles whether a particle animation is enabled + * + * @param idx Particle animation index + * @param enable Whether to enable the animation + */ + virtual void setPtclAnim(int idx, bool enable); // at 0x84 + + /** + * @brief Flushes this effect's configuration + */ + virtual void update(); // at 0x88 + + /** + * @brief Tests whether the specified flag in emitter userdata is set + * + * @param idx Userdata bitflag index + */ + virtual bool getUserFlag(int idx) const; // at 0x8C + + virtual u8 fn_801941BC(int idx) const; // at 0x90 + + /** + * @brief Clears this effect's configuration + */ + virtual void reset(); // at 0x94 + + /** + * @brief Tests whether this effect is attached to an instance + */ + bool isValid() const { + return mHandle.IsValid(); + } + + /** + * @brief Tests whether this effect's instance is alive + */ + bool isAlive() const { + return mHandle.IsAlive(); + } + +private: + /** + * @brief Effect state flags + */ + enum { + EFlag_PositionDirty, //!< Effect position should be flushed + EFlag_TransformDirty, //!< Effect transform should be flushed + EFlag_ScaleDirty, //!< Effect scale should be flushed + }; + + //! Maximum effect name length + static const u32 NAME_LENGTH = 32; + +private: + //! Dummy effect handle + static const nw4r::ef::Handle INVALID_HANDLE; + + //! Effect name + char mName[NAME_LENGTH]; // at 0x4 + + //! Effect draw group + u32 mDrawGroup; // at 0x24 + //! Effect draw scene + u32 mDrawScene; // at 0x28 + + //! Effect state flags + EGG::TBitFlag mFlags; // at 0x2C + + //! Effect scale + nw4r::math::VEC3 mScale; // at 0x30 + //! Effect position + nw4r::math::VEC3 mPosition; // at 0x3C + //! Effect transformation matrix + nw4r::math::MTX34 mTransform; // at 0x48 + + //! Effect handle + nw4r::ef::Handle mHandle; // at 0x78 +}; + +//! @} + +#endif diff --git a/include/Pack/RPKernel/RPSysEffectCreator.h b/include/Pack/RPKernel/RPSysEffectCreator.h new file mode 100644 index 000000000..91ba2fc95 --- /dev/null +++ b/include/Pack/RPKernel/RPSysEffectCreator.h @@ -0,0 +1,160 @@ +#ifndef RP_KERNEL_EFFECT_CREATOR_H +#define RP_KERNEL_EFFECT_CREATOR_H +#include + +#include + +#include + +#include + +//! @addtogroup rp_kernel +//! @{ + +/** + * @brief Effect creator + */ +class RPSysEffectCreator : public EGG::Disposer { +public: + /** + * @brief Constructor + * + * @param drawScene Effect draw scene + */ + explicit RPSysEffectCreator(u32 drawScene); + + /** + * @brief Destructor + */ + virtual ~RPSysEffectCreator(); // at 0x8 + + /** + * @brief Attaches new effect resource files + * + * @param pEffectProject Binary effect data project (.BREFF) + * @param pTextureProject Binary effect texture project (.BREFT) + */ + void setEffectResource(void* pEffectProject, void* pTextureProject); + + /** + * @brief Releases the attached effect resource files + */ + void resetEffectResource(); + + /** + * @brief Creates the effect system for slow-motion effects + */ + void createSlowSystem(); + + /** + * @brief Sets the frame rate of the slow-motion system + * + * @param frameRate Frame rate (0, 1) + */ + void setFrameRate(f32 frameRate); + + /** + * @brief Tests whether the slow-motion effect system exists + */ + bool isSlowSystem() const; + + /** + * @brief Tests whether effects are currently updating in slow motion + */ + bool isSlowEffect() const; + + /** + * @brief Kills all effects owned by this creator + */ + void stopAllEffect(); + + /** + * @brief Creates an instance of the specified effect + * + * @param pName Effect name + * @param drawGroup Effect draw group + */ + nw4r::ef::Effect* createEffect(const char* pName, u32 drawGroup); + + /** + * @brief Updates all effects owned by this creator + */ + void update(); + + /** + * @brief Draws the specified set of effects + * + * @param rDrawInfo Graphics configuration + * @param drawGroup Effect draw group + * @param drawScene Effect draw scene + */ + void draw(const nw4r::ef::DrawInfo& rDrawInfo, u32 drawGroup, + u32 drawScene); + + /** + * @brief Tests whether this creator has resource files attached + */ + bool isActive() const { + return mpEffectProject != NULL && mpTextureProject != NULL; + } + + /** + * @brief Accesses the attached effect texture project + */ + nw4r::ef::TextureProject* getTextureProject() const { + return mpTextureProject; + } + +private: + /** + * @brief Save buffer index + */ + enum ESaveBuffer { + ESaveBuffer_1st, //!< First of the two alternating buffers + ESaveBuffer_2nd, //!< Second of the two alternating buffers + + ESaveBuffer_Max + }; + + //! Slow system effect object pool size + static const u16 SLOW_MAX_EFFECT = 50; + //! Slow system emitter object pool size + static const u16 SLOW_MAX_EMITTER = 100; + //! Slow system particle manager object pool size + static const u16 SLOW_MAX_PARTICLE_MANAGER = 100; + //! Slow system particle object pool size + static const u16 SLOW_MAX_PARTICLE = 500; + +private: + //! Group ID prefix inherited by child effects + u32 mBaseGroupID; // at 0x10 + + //! Effect data project (.BREFF) + nw4r::ef::EffectProject* mpEffectProject; // at 0x14 + //! Effect texture project (.BREFT) + nw4r::ef::TextureProject* mpTextureProject; // at 0x18 + + //! Parameter save buffer where slow system data will be saved + u32 mBackSaveBuffer; // at 0x1C + //! Whether slow-motion effects are about to be processed + BOOL mIsSlowEffect; // at 0x20 + + //! Current frame processing position + f32 mFrame; // at 0x24 + //! Frame processing rate + f32 mFrameRate; // at 0x28 + + //! Effect system for slow-motion effects + nw4r::ef::EffectSystem* mpSlowSystem; // at 0x2C + //! Effect memory manager + RPSysEffectMemoryManager* mpMemoryManager; // at 0x30 + + //! Emitter parameter save buffers + nw4r::ef::EmitterParameter* mEmitterParamSave[ESaveBuffer_Max]; // at 0x34 + //! Particle parameter save buffers + nw4r::ef::ParticleParameter* mParticleParamSave[ESaveBuffer_Max]; // at 0x3C +}; + +//! @} + +#endif diff --git a/include/Pack/RPKernel/RPSysEffectDefine.h b/include/Pack/RPKernel/RPSysEffectDefine.h new file mode 100644 index 000000000..923347e71 --- /dev/null +++ b/include/Pack/RPKernel/RPSysEffectDefine.h @@ -0,0 +1,40 @@ +#ifndef RP_KERNEL_EFFECT_DEFINE_H +#define RP_KERNEL_EFFECT_DEFINE_H +#include + +#include +#include + +//! @addtogroup rp_kernel +//! @{ + +namespace RPSysEffectDefine { + +/** + * @brief Effect userdata flags + */ +enum EUserFlag { + EUserFlag_0 = 1 << 0, + + //! Effect supports slow motion + EUserFlag_SlowSystem = 1 << 14, + + EUserFlag_15 = 1 << 15, +}; + +/** + * @brief Number of effect systems (standard + slow) + */ +static const u32 MAX_SYSTEM = 2; + +/** + * @brief Maximum effect system group ID + */ +static const u32 MAX_GROUP_ID = RPSysEffectMgr::EDrawGroup_Max * MAX_SYSTEM * + RPSysEffectMgr::EDrawScene_Max; + +} // namespace RPSysEffectDefine + +//! @} + +#endif diff --git a/include/Pack/RPKernel/RPSysEffectMemoryManager.h b/include/Pack/RPKernel/RPSysEffectMemoryManager.h new file mode 100644 index 000000000..931fe2362 --- /dev/null +++ b/include/Pack/RPKernel/RPSysEffectMemoryManager.h @@ -0,0 +1,16 @@ +#ifndef RP_KERNEL_EFFECT_MEMORY_MANAGER_H +#define RP_KERNEL_EFFECT_MEMORY_MANAGER_H +#include + +#include + +// nw4r::ef::MemoryManager configuration +#define NW4R_EF_MEMORY_MANAGER_CONFIGURED +#define NW4R_EF_MEMORY_MANAGER_TMP_CLASS RPSysEffectMemoryManagerTmp +#define NW4R_EF_MEMORY_MANAGER_CLASS RPSysEffectMemoryManager +#define NW4R_EF_MEMORY_MANAGER_TPARTICLEMANAGER RPSysParticleManager + +// Include with NW4R_EF_MEMORY_MANAGER_CONFIGURED to get ef_memorymanagerimpl.h +#include + +#endif diff --git a/include/Pack/RPKernel/RPSysEffectMgr.h b/include/Pack/RPKernel/RPSysEffectMgr.h new file mode 100644 index 000000000..bd5a85d03 --- /dev/null +++ b/include/Pack/RPKernel/RPSysEffectMgr.h @@ -0,0 +1,165 @@ +#ifndef RP_KERNEL_EFFECT_MGR_H +#define RP_KERNEL_EFFECT_MGR_H +#include + +#include +#include +#include + +#include + +//! @addtogroup rp_kernel +//! @{ + +// Forward declarations +class RPSysEffectCreator; + +/** + * @brief Effect manager + */ +class RPSysEffectMgr : public IRPSysHostIOSocket { + RP_SINGLETON_DECL_EX(RPSysEffectMgr); + +public: + /** + * @brief Effect draw scene ID + */ + enum EDrawScene { + EDrawScene_Scene, //!< Scene effects + EDrawScene_Cursor, //!< Cursor effects + EDrawScene_Static, //!< Static/common effects + + EDrawScene_Max + }; + + /** + * @brief Effect draw group ID + */ + enum EDrawGroup { + EDrawGroup_Layer0, + EDrawGroup_Layer1, + EDrawGroup_Layer2, + EDrawGroup_Layer3, + + EDrawGroup_Cursor = 15, + EDrawGroup_16 = 16, + + EDrawGroup_Max = 64, + }; + + /** + * @brief Effect update type + */ + enum ECalcSetting { + ECalcSetting_All, //!< Update all effects + ECalcSetting_Cursor, //!< Only update cursor effects + }; + + /** + * @brief Effect memory settings + */ + struct EffectArg { + //! Heap to use for allocations + EGG::Heap* pHeap; // at 0x0 + + //! Effect object pool size + int maxEffect; // at 0x4 + //! Emitter object pool size + int maxEmitter; // at 0x8 + //! Particle manager object pool size + int maxParticleManager; // at 0xC + //! Particle object pool size + int maxParticle; // at 0x10 + }; + + /** + * @brief Framebuffer texture information + */ + struct EfbTexData { + //! Texture format (GXTexFmt) + u8 format; // at 0x0 + //! Texture width + u16 width; // at 0x2 + //! Texture height + u16 height; // at 0x4 + }; + +public: + /** + * @brief Attaches a new effect creator to the specified scene + * + * @param pCreator Effect creator + * @param drawScene Effect draw scene + */ + void setCreator(RPSysEffectCreator* pCreator, u32 drawScene); + + /** + * @brief Releases the specified effect creator from its scene + * + * @param pCreator Effect creator + */ + void resetCreator(RPSysEffectCreator* pCreator); + + /** + * @brief Kills all effects and particles + */ + void stopAllEffect(); + + /** + * @brief Updates the state of effects + * + * @param setting Effect update type + */ + void update(ECalcSetting setting); + + /** + * @brief Applies a framebuffer capture texture to all effects + * + * @param pTexture Framebuffer texture + * @param rData Framebuffer texture information + */ + void setCaptureEfb(void* pTexture, const EfbTexData& rData); + + /** + * @brief Draws the specified set of effects + * + * @param rDrawInfo Graphics configuration + * @param drawGroup Effect draw group + * @param drawScene Effect draw scene + */ + void draw(const nw4r::ef::DrawInfo& rDrawInfo, u32 drawGroup, + u32 drawScene); + + /** + * @brief Creates an instance of the specified effect + * + * @param pName Effect name + * @param drawGroup Effect draw group + * @param drawScene Effect draw scene + */ + nw4r::ef::Effect* createEffect(const char* pName, u32 drawGroup, + u32 drawScene); + + /** + * @brief Creates a memory manager using the specified settings + * + * @param pArg Effect memory settings + * @return Effect work memory size + */ + u32 createMemoryManager(EffectArg* pArg); + + /** + * @brief Loads the assets required by system Effect draw scenes + */ + void LoadResource(); + +private: + //! Scene effect creators + RPSysEffectCreator* mpEffectCreators[EDrawScene_Max]; // at 0x8 + + void* unk14; +}; + +//! @} + +#endif diff --git a/include/Pack/RPKernel/RPSysHomeMenuMgr.h b/include/Pack/RPKernel/RPSysHomeMenuMgr.h index 133bbfc67..0c76e5051 100644 --- a/include/Pack/RPKernel/RPSysHomeMenuMgr.h +++ b/include/Pack/RPKernel/RPSysHomeMenuMgr.h @@ -1,20 +1,230 @@ -#ifndef RP_KERNEL_HOME_MENU_MANAGER_H -#define RP_KERNEL_HOME_MENU_MANAGER_H +#ifndef RP_KERNEL_HOME_MENU_MGR_H +#define RP_KERNEL_HOME_MENU_MGR_H #include +#include #include +#include + +#include //! @addtogroup rp_kernel //! @{ /** - * @brief HBM library manager + * @brief HOME Menu manager */ class RPSysHomeMenuMgr { RP_SINGLETON_DECL_EX(RPSysHomeMenuMgr); public: + /** + * @brief Icon when HOME Menu is disabled + */ + class BanIcon { + public: + /** + * @brief Constructor + */ + BanIcon(); + + /** + * @brief Updates this icon's state + */ + void calc(); + + /** + * @brief Renders this icon's state + */ + void draw(); + + /** + * @brief Resets this icon's state + */ + void clear() { + mState = EState_Hide; + mTimer = 0; + mAlpha = 0; + } + + /** + * @brief Enables this icon + */ + void switchOn() { + mState = EState_FadeIn; + mTimer = 0; + mAlpha = 0; + } + + /** + * @brief Tests whether this icon is visible + */ + bool isDisp() const { + return mState != EState_Hide; + } + + /** + * @brief Attaches a texture to this icon + * + * @param pTexture Icon texture + */ + void setTexture(const EGG::ResTIMG* pTexture) { + mpTexture = pTexture; + } + + private: + /** + * @brief State machine state + */ + enum EState { + EState_Hide, //!< Icon is not displaying + EState_FadeIn, //!< Icon is appearing + EState_Disp, //!< Icon is fully visible + EState_FadeOut, //!< Icon is disappearing + }; + + //! Time to fade in/out the icon, in frames + static const int FADE_LENGTH = 15; + //! Time to fully display the icon, in frames + static const int DISP_LENGTH = 60; + + private: + //! Ban icon texture + const EGG::ResTIMG* mpTexture; // at 0x0 + + //! State machine state + EState mState; // at 0x4 + //! Duration of the current state + s16 mTimer; // at 0x8 + + //! Calculated icon transparency + u16 mAlpha; // at 0xA + }; + + /** + * @brief HOME Menu state + */ + enum EMenuState { + EMenuState_End, //!< Menu is closing + EMenuState_Start, //!< Menu is opening + EMenuState_Open, //!< Menu is interactable + EMenuState_Reset, //!< Menu is performing a soft reset + }; + +public: + /** + * @brief Initializes this manager's state + */ + void init(); + + /** + * @brief Initializes the HBM library + */ + void initHomeButtonInfo(); + + /** + * @brief Performs a soft reset + * + * @return Whether HBM will perform the reset + */ + bool softReset(); + + /** + * @brief Updates this manager's state + */ void update(); + + /** + * @brief Renders the HOME Menu if it is visible + */ + void draw(); + + /** + * @brief Renders the ban icon if it is visible + */ + void drawBanIcon(); + + /** + * @brief Toggles whether the HOME Menu is disabled + * + * @param disable Whether to disable the menu + */ + void disable(bool disable) { + mIsDisabled = disable; + } + + /** + * @brief Tests whether the HOME Menu is currently active + */ + bool isActive() const { + return mIsActive; + } + +private: + //! HBM work memory size + static const u32 HBM_WORK_SIZE = OS_MEM_KB_TO_B(512); + //! Size of the HBM config.txt file + static const u32 HBM_CONFIG_SIZE = 0x23; + +private: + /** + * @brief HBM library sound callback + * + * @param event HBM event + * @param arg Event argument + * @return Whether this callback handled the playback for HBM + */ + static BOOL soundCallback(int event, int arg); + + /** + * @brief Checks whether the HOME Menu should be opened + */ + void checkMenuStart(); + + /** + * @brief Checks whether the HOME Menu should be closed + */ + void checkMenuEnd(); + +private: + //! HOME Menu sound archive manager + static RPSndHomeMenuArcMgr* spHomeMenuArcMgr; + //! Sound archive heap size + static u32 sSoundHeapSize; + + //! Whether the HBM resources have been initialized + bool mIsInitialized; // at 0x8 + + //! Whether the menu is disabled + bool mIsDisabled; // at 0x9 + //! Whether the menu is opening due to a button press + bool mIsStarting; // at 0xA + //! Whether the menu is interactable + bool mIsActive; // at 0xB + //! Whether the menu should be drawn + bool mIsVisible; // at 0xC + + //! Whether a soft reset is in progress + bool mIsSoftReset; // at 0xD + + //! Current state machine state + EMenuState mMenuState; // at 0x10 + //! Current state duration + s16 mStateTimer; // at 0x14 + + //! Runtime project localization + RPSysProjectLocal* mpProjectLocal; // at 0x18 + + //! Menu ban icon + BanIcon* mpBanIcon; // at 0x1C + + //! HBM library configuration + HBMDataInfo mHBMDataInfo; // at 0x20 + + //! HBM controller input state + HBMControllerData mHBMControllerData; // at 0x60 + //! Local controller input state + KPADStatus mKPADStatus[KPAD_MAX_CONTROLLERS]; // at 0xA0 }; //! @} diff --git a/include/Pack/RPKernel/RPSysKokeshiCtrlDataLoader.h b/include/Pack/RPKernel/RPSysKokeshiCtrlDataLoader.h index ff6f3ddd3..b4d94c53e 100644 --- a/include/Pack/RPKernel/RPSysKokeshiCtrlDataLoader.h +++ b/include/Pack/RPKernel/RPSysKokeshiCtrlDataLoader.h @@ -29,7 +29,7 @@ class RPSysKokeshiCtrlDataLoader { /** * @brief Constructor * - * @param chan WPAD channel to use + * @param chan Remote channel */ explicit RPSysKokeshiCtrlDataLoader(s32 chan); diff --git a/include/Pack/RPKernel/RPSysKokeshiCtrlDataMgr.h b/include/Pack/RPKernel/RPSysKokeshiCtrlDataMgr.h index d6eb816c9..94c072fd0 100644 --- a/include/Pack/RPKernel/RPSysKokeshiCtrlDataMgr.h +++ b/include/Pack/RPKernel/RPSysKokeshiCtrlDataMgr.h @@ -79,12 +79,12 @@ class RPSysKokeshiCtrlDataMgr { public: /** - * @brief Construct + * @brief Constructor * * @param pCallback Controller data callback * @param pParentHeap Heap to use as the parent of the controller data heap * @param heapSize Size of the controller data heap - * @param index WPAD channel to use + * @param chan Remote channel */ RPSysKokeshiCtrlDataMgr(IRPSysKokeshiCtrlDataCallback* pCallback, EGG::Heap* pParentHeap, u32 heapSize, s32 chan); diff --git a/include/Pack/RPKernel/RPSysNWC24Manager.h b/include/Pack/RPKernel/RPSysNWC24Manager.h index 1c6abc568..8f9917022 100644 --- a/include/Pack/RPKernel/RPSysNWC24Manager.h +++ b/include/Pack/RPKernel/RPSysNWC24Manager.h @@ -31,7 +31,7 @@ class RPSysNWC24Manager { * * @param pHeap Heap to use for allocations */ - RPSysNWC24Manager(EGG::Heap* pHeap); + explicit RPSysNWC24Manager(EGG::Heap* pHeap); /** * @brief Destructor diff --git a/include/Pack/RPKernel/RPSysPauseMenu.h b/include/Pack/RPKernel/RPSysPauseMenu.h new file mode 100644 index 000000000..8b0d0c6ef --- /dev/null +++ b/include/Pack/RPKernel/RPSysPauseMenu.h @@ -0,0 +1,60 @@ +#ifndef RP_KERNEL_PAUSE_MENU_H +#define RP_KERNEL_PAUSE_MENU_H + +#include +#include + +//! @addtogroup rp_kernel +//! @{ + +// Forward declarations +class RPSysLayout; +class RPSysLytBounding; +class RPSysLytAnmObj; +class RPSysLytTextBox; + +/** + * @brief Library that handles pause menu layout. + */ + +class RPSysPauseMenu { + virtual ~RPSysPauseMenu(); + +public: + void draw(); + +private: + RPSysLayout* mLayout; // at 0x4 + RPSysLytAnmObj* mAnmObj_0x04; + RPSysLytAnmObj* mAnmObj_0x08; + void* mUNK_0x10; + nw4r::lyt::Pane* mPane_0x14; + nw4r::lyt::Pane* mPane_0x18; + bool mUNK_0x1C; + bool mUNK_0x1D; + u8 mPAD_0x1E[2]; + nw4r::lyt::Pane* mPane_0x20; + RPSysLytBounding* mBounding; // at 0x24 + RPSysLytTextBox* mTextBox; // at 0x28 + bool mUNK_0x2C; + bool mUNK_0x2D; + u8 mPAD_0x2E[10]; + bool mUNK_0x38; + bool mUNK_0x39; + u8 mPAD_0x3A[26]; + bool mUNK_0x54; + bool mUNK_0x55; + u8 mPAD_0x56[26]; + void* mUtlCursor; //! At 0x70. RPUtlLytFrameCursor is not defined yet. + u8 mPAD_0x74[4]; + bool mUNK_0x78; + u8 mPAD_0x79[4]; + bool mUNK_0x7D; + bool mUNK_0x7E; + bool mUNK_0x7F; + u8 mPAD_0x80[8]; +}; + +//! @} + +#endif diff --git a/include/Pack/RPSystem/RPSysSystem.h b/include/Pack/RPKernel/RPSysSystem.h similarity index 84% rename from include/Pack/RPSystem/RPSysSystem.h rename to include/Pack/RPKernel/RPSysSystem.h index 9a0d35d2f..806a72f85 100644 --- a/include/Pack/RPSystem/RPSysSystem.h +++ b/include/Pack/RPKernel/RPSysSystem.h @@ -1,8 +1,10 @@ -#ifndef RP_SYSTEM_SYSTEM_H -#define RP_SYSTEM_SYSTEM_H +#ifndef RP_KERNEL_SYSTEM_H +#define RP_KERNEL_SYSTEM_H #include +#include #include +#include #include @@ -14,6 +16,63 @@ //! @addtogroup rp_system //! @{ +/** + * @brief Pack Project configuration data. Derives from EGG::ConfigurationData. + */ + +class RPSysConfigData { +public: + explicit RPSysConfigData(u32 systemHeapSize) + : mSystemHeapSize(systemHeapSize) {} + + virtual EGG::Video* GetVideo() { + return mVideo; + } + virtual EGG::Heap* GetSystemHeap() { + return mSystemHeap; + } + virtual EGG::Display* GetDisplay() { + return mDisplay; + } + virtual EGG::XfbManager* GetXfbMgr() { + return mXfbMgr; + } + virtual EGG::PerformanceView* GetPerfView() { + return mPerfView; + } + virtual EGG::SceneManager* GetSceneMgr() { + return mSceneMgr; + } + virtual EGG::IAudioMgr* GetAudioMgr() { + return mAudioMgr; + } + virtual void StubA() {} + virtual void StubB() {} + +private: + void* mMem1Start; + void* mMem1End; + void* mMem2Start; + void* mMem2End; + u32 mMemSize; + EGG::Heap* mRootHeapMem1; + EGG::Heap* mRootHeapMem2; + EGG::Heap* mRootHeapDebug; + +protected: + EGG::Heap* mSystemHeap; + EGG::Thread* mCreatorThread; + void* mCodeStart; + void* mCodeEnd; + u32 mSystemHeapSize; + EGG::Video* mVideo; + EGG::XfbManager* mXfbMgr; + EGG::Display* mDisplay; + EGG::PerformanceView* mPerfView; + EGG::SceneManager* mSceneMgr; + EGG::IAudioMgr* mAudioMgr; +}; + /** * @brief Pack Project engine system */ @@ -296,7 +355,7 @@ class RPSysSystem { //! Task-end thread message for asynchronous NAND operations u32 mNandEndMessage; // at 0x40 //! Task-end thread message for asynchronous disc operations - u32 mDvdEndMessage; // at 0x44 + OSMessage mDvdEndMessage; // at 0x44 //! Task-end thread message for asynchronous WiiConnect24 operations u32 mWc24EndMessage; // at 0x48 @@ -311,12 +370,12 @@ class RPSysSystem { char* mpTimeStampString; // at 0x58 //! Engine configuration - // static RPSysConfigData sConfigData; + static RPSysConfigData sConfigData; //! Active render mode static GXRenderModeObj* spRenderModeObj; - //! Render mode format @see RPSysRenderMode::EFormat - // static u32 sRenderModeFormat; + //! Render mode format + static RPSysRenderMode::EFormat sRenderModeFormat; //! @brief Time (in milliseconds) when the render mode was setup //! @remark This value is only non-zero when scan mode/TV format is changed //! and the system must wait. diff --git a/include/Pack/RPParty.h b/include/Pack/RPParty.h deleted file mode 100644 index 0147f07be..000000000 --- a/include/Pack/RPParty.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef RP_PUBLIC_PARTY_H -#define RP_PUBLIC_PARTY_H - -#include - -#endif diff --git a/include/Pack/RPParty/RPBilScene.h b/include/Pack/RPParty/RPBilScene.h new file mode 100644 index 000000000..5a022c078 --- /dev/null +++ b/include/Pack/RPParty/RPBilScene.h @@ -0,0 +1,6 @@ +#ifndef RP_PUBLIC_PARTY_BIL_H +#define RP_PUBLIC_PARTY_BIL_H + +#include + +#endif diff --git a/include/Pack/RPParty/RPBilScene/RPBilScene.h b/include/Pack/RPParty/RPBilScene/RPBilScene.h new file mode 100644 index 000000000..e5cfd578c --- /dev/null +++ b/include/Pack/RPParty/RPBilScene/RPBilScene.h @@ -0,0 +1,19 @@ +#ifndef RP_PARTY_BIL_SCENE_H +#define RP_PARTY_BIL_SCENE_H +#include + +#include + +//! @addtogroup rp_bil +//! @{ + +/** + * @brief Party Pack Billiards scene + */ +class RPBilScene : public RPSysScene { + char unk44[0x58 - 0x44]; +}; + +//! @} + +#endif diff --git a/include/Pack/RPParty/RPBomScene.h b/include/Pack/RPParty/RPBomScene.h new file mode 100644 index 000000000..c5aba73ba --- /dev/null +++ b/include/Pack/RPParty/RPBomScene.h @@ -0,0 +1,6 @@ +#ifndef RP_PUBLIC_PARTY_BOM_H +#define RP_PUBLIC_PARTY_BOM_H + +#include + +#endif diff --git a/include/Pack/RPParty/RPBomScene/RPBomScene.h b/include/Pack/RPParty/RPBomScene/RPBomScene.h new file mode 100644 index 000000000..527c6e884 --- /dev/null +++ b/include/Pack/RPParty/RPBomScene/RPBomScene.h @@ -0,0 +1,19 @@ +#ifndef RP_PARTY_BOM_SCENE_H +#define RP_PARTY_BOM_SCENE_H +#include + +#include + +//! @addtogroup rp_bom +//! @{ + +/** + * @brief Party Pack Pose Mii scene + */ +class RPBomScene : public RPSysScene { + char unk44[0x8C - 0x44]; +}; + +//! @} + +#endif diff --git a/include/Pack/RPParty/RPCowScene.h b/include/Pack/RPParty/RPCowScene.h new file mode 100644 index 000000000..34dd1b9ef --- /dev/null +++ b/include/Pack/RPParty/RPCowScene.h @@ -0,0 +1,6 @@ +#ifndef RP_PUBLIC_PARTY_COW_H +#define RP_PUBLIC_PARTY_COW_H + +#include + +#endif diff --git a/include/Pack/RPParty/RPCowScene/RPCowScene.h b/include/Pack/RPParty/RPCowScene/RPCowScene.h new file mode 100644 index 000000000..29dda4f6b --- /dev/null +++ b/include/Pack/RPParty/RPCowScene/RPCowScene.h @@ -0,0 +1,17 @@ +#ifndef RP_PARTY_COW_SCENE_H +#define RP_PARTY_COW_SCENE_H +#include + +#include + +//! @addtogroup rp_cow +//! @{ + +/** + * @brief Party Pack Charge! scene + */ +class RPCowScene : public RPPartySeqScene {}; + +//! @} + +#endif diff --git a/include/Pack/RPParty/RPDucScene.h b/include/Pack/RPParty/RPDucScene.h new file mode 100644 index 000000000..43774685f --- /dev/null +++ b/include/Pack/RPParty/RPDucScene.h @@ -0,0 +1,6 @@ +#ifndef RP_PUBLIC_PARTY_DUC_H +#define RP_PUBLIC_PARTY_DUC_H + +#include + +#endif diff --git a/include/Pack/RPParty/RPDucScene/RPDucScene.h b/include/Pack/RPParty/RPDucScene/RPDucScene.h new file mode 100644 index 000000000..7ca5e2333 --- /dev/null +++ b/include/Pack/RPParty/RPDucScene/RPDucScene.h @@ -0,0 +1,19 @@ +#ifndef RP_PARTY_DUC_SCENE_H +#define RP_PARTY_DUC_SCENE_H +#include + +#include + +//! @addtogroup rp_duc +//! @{ + +/** + * @brief Party Pack Shooting Range scene + */ +class RPDucScene : public RPSysScene { + char unk44[0x80 - 0x44]; +}; + +//! @} + +#endif diff --git a/include/Pack/RPParty/RPFshScene.h b/include/Pack/RPParty/RPFshScene.h new file mode 100644 index 000000000..e3854eecc --- /dev/null +++ b/include/Pack/RPParty/RPFshScene.h @@ -0,0 +1,6 @@ +#ifndef RP_PUBLIC_PARTY_FSH_H +#define RP_PUBLIC_PARTY_FSH_H + +#include + +#endif diff --git a/include/Pack/RPParty/RPFshScene/RPFshScene.h b/include/Pack/RPParty/RPFshScene/RPFshScene.h new file mode 100644 index 000000000..92c5fa692 --- /dev/null +++ b/include/Pack/RPParty/RPFshScene/RPFshScene.h @@ -0,0 +1,19 @@ +#ifndef RP_PARTY_FSH_SCENE_H +#define RP_PARTY_FSH_SCENE_H +#include + +#include + +//! @addtogroup rp_fsh +//! @{ + +/** + * @brief Party Pack Fishing scene + */ +class RPFshScene : public RPSysScene { + char unk44[0x48 - 0x44]; +}; + +//! @} + +#endif diff --git a/include/Pack/RPParty/RPHkyScene.h b/include/Pack/RPParty/RPHkyScene.h new file mode 100644 index 000000000..48f1a7e03 --- /dev/null +++ b/include/Pack/RPParty/RPHkyScene.h @@ -0,0 +1,6 @@ +#ifndef RP_PUBLIC_PARTY_HKY_H +#define RP_PUBLIC_PARTY_HKY_H + +#include + +#endif diff --git a/include/Pack/RPParty/RPHkyScene/RPHkyScene.h b/include/Pack/RPParty/RPHkyScene/RPHkyScene.h new file mode 100644 index 000000000..f8349df6c --- /dev/null +++ b/include/Pack/RPParty/RPHkyScene/RPHkyScene.h @@ -0,0 +1,19 @@ +#ifndef RP_PARTY_HKY_SCENE_H +#define RP_PARTY_HKY_SCENE_H +#include + +#include + +//! @addtogroup rp_hky +//! @{ + +/** + * @brief Party Pack Laser Hockey scene + */ +class RPHkyScene : public RPSysScene { + char unk44[0x4C - 0x44]; +}; + +//! @} + +#endif diff --git a/include/Pack/RPParty/RPPartyCommon.h b/include/Pack/RPParty/RPPartyCommon.h new file mode 100644 index 000000000..0eaf86d36 --- /dev/null +++ b/include/Pack/RPParty/RPPartyCommon.h @@ -0,0 +1,10 @@ +#ifndef RP_PUBLIC_PARTY_COMMON_H +#define RP_PUBLIC_PARTY_COMMON_H + +#include +#include +#include +#include +#include + +#endif diff --git a/include/Pack/RPParty/RPPartyBodyManager.h b/include/Pack/RPParty/RPPartyCommon/RPPartyBodyManager.h similarity index 94% rename from include/Pack/RPParty/RPPartyBodyManager.h rename to include/Pack/RPParty/RPPartyCommon/RPPartyBodyManager.h index 83a7d48aa..45fdaa662 100644 --- a/include/Pack/RPParty/RPPartyBodyManager.h +++ b/include/Pack/RPParty/RPPartyCommon/RPPartyBodyManager.h @@ -1,5 +1,5 @@ -#ifndef RP_PARTY_BODY_MANAGER_H -#define RP_PARTY_BODY_MANAGER_H +#ifndef RP_PARTY_COMMON_BODY_MANAGER_H +#define RP_PARTY_COMMON_BODY_MANAGER_H #include #include diff --git a/include/Pack/RPParty/RPPartyCommon/RPPartyMainScene/RPPartyMainScene.h b/include/Pack/RPParty/RPPartyCommon/RPPartyMainScene/RPPartyMainScene.h new file mode 100644 index 000000000..6279affec --- /dev/null +++ b/include/Pack/RPParty/RPPartyCommon/RPPartyMainScene/RPPartyMainScene.h @@ -0,0 +1,17 @@ +#ifndef RP_PARTY_COMMON_MAIN_SCENE_H +#define RP_PARTY_COMMON_MAIN_SCENE_H +#include + +#include + +//! @addtogroup rp_party +//! @{ + +/** + * @brief Party Pack main menu scene + */ +class RPPartyMainScene : public RPSysScene {}; + +//! @} + +#endif diff --git a/include/Pack/RPParty/RPPartyCommon/RPPartyPackTitleScene/RPPartyPackTitleScene.h b/include/Pack/RPParty/RPPartyCommon/RPPartyPackTitleScene/RPPartyPackTitleScene.h new file mode 100644 index 000000000..ed6c2e74c --- /dev/null +++ b/include/Pack/RPParty/RPPartyCommon/RPPartyPackTitleScene/RPPartyPackTitleScene.h @@ -0,0 +1,19 @@ +#ifndef RP_PARTY_COMMON_PACK_TITLE_SCENE_H +#define RP_PARTY_COMMON_PACK_TITLE_SCENE_H +#include + +#include + +//! @addtogroup rp_party +//! @{ + +/** + * @brief Party Pack title screen scene + */ +class RPPartyPackTitleScene : public RPUtlLoadSaveDataScene { + char unk44[0x68 - 0x44]; +}; + +//! @} + +#endif diff --git a/include/Pack/RPParty/RPPartyCommon/RPPartyRootScene/RPPartyRootScene.h b/include/Pack/RPParty/RPPartyCommon/RPPartyRootScene/RPPartyRootScene.h new file mode 100644 index 000000000..6a16b1ecb --- /dev/null +++ b/include/Pack/RPParty/RPPartyCommon/RPPartyRootScene/RPPartyRootScene.h @@ -0,0 +1,17 @@ +#ifndef RP_PARTY_COMMON_ROOT_SCENE_H +#define RP_PARTY_COMMON_ROOT_SCENE_H +#include + +#include + +//! @addtogroup rp_party +//! @{ + +/** + * @brief Party Pack root scene + */ +class RPPartyRootScene : public RPSysScene {}; + +//! @} + +#endif diff --git a/include/Pack/RPParty/RPPartyCommon/RPPartySeqScene.h b/include/Pack/RPParty/RPPartyCommon/RPPartySeqScene.h new file mode 100644 index 000000000..b4a7fe67a --- /dev/null +++ b/include/Pack/RPParty/RPPartyCommon/RPPartySeqScene.h @@ -0,0 +1,19 @@ +#ifndef RP_PARTY_COMMON_SEQ_SCENE_H +#define RP_PARTY_COMMON_SEQ_SCENE_H +#include + +#include + +//! @addtogroup rp_party +//! @{ + +/** + * @brief Base class for Party Pack scenes using sequence logic + */ +class RPPartySeqScene : public RPSysScene { +private: +}; + +//! @} + +#endif diff --git a/include/Pack/RPParty/RPPnpScene.h b/include/Pack/RPParty/RPPnpScene.h new file mode 100644 index 000000000..2534ca311 --- /dev/null +++ b/include/Pack/RPParty/RPPnpScene.h @@ -0,0 +1,6 @@ +#ifndef RP_PUBLIC_PARTY_PNP_H +#define RP_PUBLIC_PARTY_PNP_H + +#include + +#endif diff --git a/include/Pack/RPParty/RPPnpScene/RPPnpScene.h b/include/Pack/RPParty/RPPnpScene/RPPnpScene.h new file mode 100644 index 000000000..01402d44f --- /dev/null +++ b/include/Pack/RPParty/RPPnpScene/RPPnpScene.h @@ -0,0 +1,19 @@ +#ifndef RP_PARTY_PNP_SCENE_H +#define RP_PARTY_PNP_SCENE_H +#include + +#include + +//! @addtogroup rp_pnp +//! @{ + +/** + * @brief Party Pack Table Tennis scene + */ +class RPPnpScene : public RPSysScene { + char unk44[0x4C - 0x44]; +}; + +//! @} + +#endif diff --git a/include/Pack/RPParty/RPTnkScene.h b/include/Pack/RPParty/RPTnkScene.h new file mode 100644 index 000000000..9989682e9 --- /dev/null +++ b/include/Pack/RPParty/RPTnkScene.h @@ -0,0 +1,6 @@ +#ifndef RP_PUBLIC_PARTY_TNK_H +#define RP_PUBLIC_PARTY_TNK_H + +#include + +#endif diff --git a/include/Pack/RPParty/RPTnkScene/RPTnkScene.h b/include/Pack/RPParty/RPTnkScene/RPTnkScene.h new file mode 100644 index 000000000..e67f8e22b --- /dev/null +++ b/include/Pack/RPParty/RPTnkScene/RPTnkScene.h @@ -0,0 +1,19 @@ +#ifndef RP_PARTY_TNK_SCENE_H +#define RP_PARTY_TNK_SCENE_H +#include + +#include + +//! @addtogroup rp_tnk +//! @{ + +/** + * @brief Party Pack Tanks! scene + */ +class RPTnkScene : public RPSysScene { + char unk44[0x8C - 0x44]; +}; + +//! @} + +#endif diff --git a/include/Pack/RPParty/RPWlyScene.h b/include/Pack/RPParty/RPWlyScene.h new file mode 100644 index 000000000..9984101bf --- /dev/null +++ b/include/Pack/RPParty/RPWlyScene.h @@ -0,0 +1,6 @@ +#ifndef RP_PUBLIC_PARTY_WLY_H +#define RP_PUBLIC_PARTY_WLY_H + +#include + +#endif diff --git a/include/Pack/RPParty/RPWlyScene/RPWlyScene.h b/include/Pack/RPParty/RPWlyScene/RPWlyScene.h new file mode 100644 index 000000000..e9cbd50ff --- /dev/null +++ b/include/Pack/RPParty/RPWlyScene/RPWlyScene.h @@ -0,0 +1,19 @@ +#ifndef RP_PARTY_WLY_SCENE_H +#define RP_PARTY_WLY_SCENE_H +#include + +#include + +//! @addtogroup rp_wly +//! @{ + +/** + * @brief Party Pack Find Mii scene + */ +class RPWlyScene : public RPSysScene { + char unk44[0x4C - 0x44]; +}; + +//! @} + +#endif diff --git a/include/Pack/RPSports.h b/include/Pack/RPSports.h deleted file mode 100644 index 9568e059d..000000000 --- a/include/Pack/RPSports.h +++ /dev/null @@ -1,7 +0,0 @@ -#ifndef RP_PUBLIC_SPORTS_H -#define RP_PUBLIC_SPORTS_H - -#include -#include - -#endif diff --git a/include/Pack/RPSports/RPBowScene.h b/include/Pack/RPSports/RPBowScene.h new file mode 100644 index 000000000..e734eea71 --- /dev/null +++ b/include/Pack/RPSports/RPBowScene.h @@ -0,0 +1,6 @@ +#ifndef RP_PUBLIC_SPORTS_BOW_H +#define RP_PUBLIC_SPORTS_BOW_H + +#include + +#endif diff --git a/include/Pack/RPSports/RPBowScene/RPBowScene.h b/include/Pack/RPSports/RPBowScene/RPBowScene.h new file mode 100644 index 000000000..e0675908b --- /dev/null +++ b/include/Pack/RPSports/RPBowScene/RPBowScene.h @@ -0,0 +1,21 @@ +#ifndef RP_SPORTS_BOW_SCENE_H +#define RP_SPORTS_BOW_SCENE_H +#include + +#include +#include + +//! @addtogroup rp_bow +//! @{ + +/** + * @brief Sports Pack Bowling scene + */ +class RPBowScene : public RPSportsBaseScene, public IRPSysHostIOSocket { +private: + char unkA0[0x13C - 0xA0]; +}; + +//! @} + +#endif diff --git a/include/Pack/RPSports/RPBowScene/bowling.h b/include/Pack/RPSports/RPBowScene/bowling.h new file mode 100644 index 000000000..79cd4d576 --- /dev/null +++ b/include/Pack/RPSports/RPBowScene/bowling.h @@ -0,0 +1,859 @@ +#include +#include + +namespace Bowling { + +struct RPGrpModelPair { + // total size: 0x8 + RPGrpModel* pRealModel; // offset 0x0, size 0x4 + RPGrpModel* pReflectionModel; // offset 0x4, size 0x4 +}; + +class RPBowActiveBall { +public: + // total size: 0x88 + virtual ~RPBowActiveBall(); // offset 0x0, size 0x4 + + RPGrpModelPair models[8]; // offset 0x4, size 0x40 + nw4r::math::MTX34 mtx; // offset 0x44, size 0x30 + f32 field_0x74; // offset 0x74, size 0x4 + u32 index; // offset 0x78, size 0x4 + f32 alpha; // offset 0x7C, size 0x4 + RPGrpShadowTexture* pShadowTexture; // offset 0x80, size 0x4 + BOOL disableShadow; // offset 0x84, size 0x4 + + void ResetRenderState(); + void RenderModelSet(); +}; + +struct PhysicsBody { + // total size: 0xFC + + virtual void VF_0x00(); // vtable index 0 (offset 0x0) + virtual void VF_0x04(); // vtable index 1 (offset 0x4) + virtual void VF_0x08(); // vtable index 2 (offset 0x8) + virtual void VF_0x0C(); // vtable index 3 (offset 0xC) + + nw4r::math::VEC3 position; // offset 0x04, size 0x4 + nw4r::math::VEC3 linearVelocity; // offset 0x10, size 0x4 + nw4r::math::VEC3 previousPosition; // offset 0x1C, size 0x4 + + nw4r::math::VEC3 minPositionDelta; // offset 0x28, size 0x4 + nw4r::math::VEC3 maxPositionDelta; // offset 0x34, size 0x4 + + nw4r::math::VEC3 minVelocityDelta; // offset 0x40, size 0x4 + nw4r::math::VEC3 maxVelocityDelta; // offset 0x4C, size 0x4 + + f32 linearDamping; // offset 0x58, size 0x4 + + nw4r::math::VEC3 basisX; // offset 0x5C, size 0x4 + nw4r::math::VEC3 basisY; // offset 0x68, size 0x4 + nw4r::math::VEC3 basisZ; // offset 0x74, size 0x4 + + nw4r::math::VEC3 angularVelXY; // offset 0x80, size 0x4 + nw4r::math::VEC3 angularVelYZ; // offset 0x8C, size 0x4 + nw4r::math::VEC3 angularVelZX; // offset 0x98, size 0x4 + + nw4r::math::VEC3 minAngularDeltaXY; // offset 0xA4, size 0x4 + nw4r::math::VEC3 maxAngularDeltaXY; // offset 0xB0, size 0x4 + + nw4r::math::VEC3 minAngularDeltaYZ; // offset 0xBC, size 0x4 + nw4r::math::VEC3 maxAngularDeltaYZ; // offset 0xC8, size 0x4 + + nw4r::math::VEC3 minAngularDeltaZX; // offset 0xD4, size 0x4 + nw4r::math::VEC3 maxAngularDeltaZX; // offset 0xE0, size 0x4 + + f32 angularDamping; // offset 0xEC, size 0x4 + f32 angularResponseScale; // offset 0xF0, size 0x4 + f32 interactionRadius; // offset 0xF4, size 0x4 + + u8 flags; // offset 0xF8, size 0x1 + u8 pad_F9[0x3]; // offset 0xF9, size 0x3 +}; + +struct PinSubVecs { + // total size: 0x1C + nw4r::math::VEC3 vec1; // offset 0x0, size 0xC + nw4r::math::VEC3 vec2; // offset 0xC, size 0xC + float field_0x18; // offset 0x18, size 0x4 +}; + +struct PinPhysicsBody : public PhysicsBody { + // total size: 0x2C0 + // PhysicsBody // offset 0x0, size 0xFC + nw4r::math::VEC3 field_0xFC; // offset 0xFC, size 0xC + nw4r::math::VEC3 unkVec_0x108; // offset 0x108, size 0xC + nw4r::math::VEC3 unkVec_0x114; // offset 0x114, size 0xC + nw4r::math::VEC3 unkVec_0x120; // offset 0x120, size 0xC + nw4r::math::VEC3 unkVec_0x12C; // offset 0x12C, size 0xC + nw4r::math::VEC3 unkVec_0x138; // offset 0x138, size 0xC + nw4r::math::VEC3 unkVec_0x144; // offset 0x144, size 0xC + nw4r::math::VEC3 unkVec_0x150; // offset 0x150, size 0xC + nw4r::math::VEC3 unkVec_0x15C; // offset 0x15C, size 0xC + float field_0x168; // offset 0x168, size 0x4 + float field_0x16C; // offset 0x16C, size 0x4 + PinSubVecs pinVecs[8]; // offset 0x170, size 0xE0 + u8 unkFlag_0x250; // offset 0x250, size 0x1 + u8 isActive; // offset 0x251, size 0x1 + u8 pad_0x252[0x2]; // offset 0x252, size 0x2 + void* unkPtr_0x254; // offset 0x254, size 0x4 + void* unkPtr_0x258; // offset 0x258, size 0x4 + void* unkPtr_0x25C; // offset 0x25C, size 0x4 + void* unkPtr_0x260; // offset 0x260, size 0x4 + f32 field_0x264; // offset 0x264, size 0x4 + f32 field_0x268; // offset 0x268, size 0x4 + f32 field_0x26C; // offset 0x26C, size 0x4 + f32 field_0x270; // offset 0x270, size 0x4 + f32 field_0x274; // offset 0x274, size 0x4 + f32 field_0x278; // offset 0x278, size 0x4 + f32 field_0x27C; // offset 0x27C, size 0x4 + f32 field_0x280; // offset 0x280, size 0x4 + f32 field_0x284; // offset 0x284, size 0x4 + f32 field_0x288; // offset 0x288, size 0x4 + int mode_0x28C; // offset 0x28C, size 0x4 + u8 flag_0x290; // offset 0x290, size 0x1 + u8 pad_0x291[0x3]; // offset 0x291, size 0x3 + f32 field_0x294; // offset 0x294, size 0x4 + void* unkPtr_0x298; // offset 0x298, size 0x4 + u8 flag_0x29C; // offset 0x29C, size 0x1 + u8 pad_0x29D[0x3]; // offset 0x29D, size 0x3 + void* unkPtr_0x2A0; // offset 0x2A0, size 0x4 + int unkCounter_0x2A4; // offset 0x2A4, size 0x4 + void* field_0x2A8; // offset 0x2A8, size 0x4 + int unkCounter_0x2AC; // offset 0x2AC, size 0x4 + f32 field_0x2B0; // offset 0x2B0, size 0x4 + f32 field_0x2B4; // offset 0x2B4, size 0x4 + f32 field_0x2B8; // offset 0x2B8, size 0x4 + f32 field_0x2BC; // offset 0x2BC, size 0x4 +}; + +// Rack index order for PinManager's pPinBodies +// [6] [7] [8] [9] +// [3] [4] [5] +// [1] [2] +// [0] + +struct PinManager { + PinPhysicsBody* pPinBodies[10]; // offset 0x0, size 0x28 +}; + +struct BvhEntryHeader { + // total size: 0x40 + u32 pEntry; // offset 0x0, size 0x4 + u32 child[4]; // offset 0x4, size 0x10 + f32 field_14; // offset 0x14, size 0x4 + u32 field_18; // offset 0x18, size 0x4 + u32 field_1C; // offset 0x1C, size 0x4 + u32 field_20; // offset 0x20, size 0x4 + u32 field_24; // offset 0x24, size 0x4 + u32 field_28; // offset 0x28, size 0x4 + u32 field_2C; // offset 0x2C, size 0x4 + u32 field_30; // offset 0x30, size 0x4 + u32 field_34; // offset 0x34, size 0x4 + u32 field_38; // offset 0x38, size 0x4 + f32 field_3C; // offset 0x3C, size 0x4 + + BvhEntryHeader() { + pEntry = 0; + } +}; + +struct LaneBvhData { + // total size: 0x18 + float field_0x0; // offset 0x0, size 0x4 + float field_0x4; // offset 0x4, size 0x4 + float field_0x8; // offset 0x8, size 0x4 + float field_0xC; // offset 0xC, size 0x4 + float field_0x10; // offset 0x10, size 0x4 + float field_0x14; // offset 0x14, size 0x4 + BvhEntryHeader* pObj1; // offset 0x18, size 0x4 + BvhEntryHeader* pObj2; // offset 0x1C, size 0x4 +}; + +struct PinSetter { + // total size: 0x4C + void* vtable; // offset 0x0, size 0x4 + void* field_04; // offset 0x4, size 0x4 + void* field_08; // offset 0x8, size 0x4 + float field_0C; // offset 0xC, size 0x4 + u8 pad_10[0x8]; // offset 0x10, size 0x8 + float positionX; // offset 0x18, size 0x4 + u8 pad_1c[0x4]; // offset 0x1C, size 0x4 + float field_20; // offset 0x20, size 0x4 + u8 pad_24[0x10]; // offset 0x24, size 0x10 + float field_34; // offset 0x34, size 0x4 + float positionZ; // offset 0x38, size 0x4 + int primaryState; // offset 0x3C, size 0x4 + int sequencePhase; // offset 0x40, size 0x4 + float field_44; // offset 0x44, size 0x4 + float frameTimer; // offset 0x48, size 0x4 +}; + +struct ThrowContext { + // total size: 0x108 + int throwState; // offset 0x0, size 0x4 + nw4r::math::MTX34 ballMtx; // offset 0x4, size 0x30 + u8 pad_0x34[0x2C]; // offset 0x34, size 0x2C + float field_0x60; // offset 0x60, size 0x4 + u8 pad_0x64[0x18]; // offset 0x64, size 0x18 + float field_0x7C; // offset 0x7C, size 0x4 + void* unkPtr_0x80; // offset 0x80, size 0x4 + float field_0x84; // offset 0x84, size 0x4 + float field_0x88; // offset 0x88, size 0x4 + float field_0x8C; // offset 0x8C, size 0x4 + u8 pad_0x90[0x4]; // offset 0x90, size 0x4 + float field_0x94; // offset 0x94, size 0x4 + float field_0x98; // offset 0x98, size 0x4 + u8 pad_0x9C[0x4]; // offset 0x9C, size 0x4 + u8 flag_0xA0; // offset 0xA0, size 0x1 + u8 pad_0xA1[0x3]; // offset 0xA1, size 0x3 + float field_0xA4; // offset 0xA4, size 0x4 + u8 flag_0xA8; // offset 0xA8, size 0x1 + u8 flag_0xA9; // offset 0xA9, size 0x1 + u8 isGutterBall; // offset 0xAA, size 0x1 + u8 flag_0xAB; // offset 0xAB, size 0x1 + u8 pad_0xAC[0x14]; // offset 0xAC, size 0x14 + int animationMode; // offset 0xC0, size 0x4 + u8 pad_0xC4[0x40]; // offset 0xC4, size 0x40 + int field_0x104; // offset 0x104, size 0x4 +}; + +struct PinStatus { + // total size: 0x14 + u32 pinBits[4]; // 0x0, Bitmask where each bit represents a pin (0=down, 1=standing) + s32 pinCount; // 0x10 + + int GetStandingPinCount() const { + int count = 0; + for (int i = 0; i < pinCount; ++i) { + if (pinBits[i / 30] & (1 << (i % 30))) { + count++; + } + } + return count; + } +}; + +struct PinSetterAnimation { + // total size: 0x10 + int sequenceFrameCount; // offset 0x0, size 0x4 + float animOffsetZ; // offset 0x4, size 0x4 + float animRotationY; // offset 0x8, size 0x4 + u8 isNewRack; // offset 0xC, size 0x1 + u8 pad_2025; // offset 0xD, size 0x1 + u8 pad_2026; // offset 0xE, size 0x1 + u8 pad_2027; // offset 0xF, size 0x1 +}; + + +struct LaneContext { + // total size: 0x2080 + // void* vtable; // offset 0x0, size 0x4 + + virtual void VF_0x00(); // at 0x0 + virtual void VF_0x04(); // at 0x4 + virtual void VF_0x08(); // at 0x8 + virtual void VF_0x0C(); // at 0xC + virtual void VF_0x10(); // at 0x10 + virtual void VF_0x14(); // at 0x14 + + PinManager* pPinManager; // offset 0x4, size 0x4 + LaneBvhData* pLaneBvhData; // offset 0x8, size 0x4 + PinSetter* pPinSetter; // offset 0xC, size 0x4 + void* unkPtr_0x10; // offset 0x10, size 0x4 + int pinCount; // offset 0x14, size 0x4 + void* unkPtr_0x18; // offset 0x18, size 0x4 + void* unkPtr_0x1C; // offset 0x1C, size 0x4 + u8 pad_0x20[0x1EA0]; // offset 0x20, size 0x1EA0 + int field_1EC0; // offset 0x1EC0, size 0x4 + int field_1EC4; // offset 0x1EC4, size 0x4 + u8 pad_0x1EC8[0x18]; // offset 0x1EC8, size 0x18 + int field_1EE0; // offset 0x1EE0, size 0x4 + int field_1EE4; // offset 0x1EE4, size 0x4 + float field_0x1EE8; // offset 0x1EE8, size 0x4 + float field_0x1EEC; // offset 0x1EEC, size 0x4 + float field_0x1EF0; // offset 0x1EF0, size 0x4 + int field_1EF4; // offset 0x1EF4, size 0x4 + ThrowContext throwContext; // offset 0x1EF8, size 0x108 + PinStatus pinStatus; // offset 0x2000, size 0x4 + float laneXOffset; // offset 0x2014, size 0x4 + PinSetterAnimation setterAnm; // offset 0x2018, size 0x10 + u32 field_0x2028; // offset 0x2028, size 0x4 + void* unkPtr_0x202C; // offset 0x202C, size 0x4 + void* unkPtr_0x2030; // offset 0x2030, size 0x4 + void* unkPtr_0x2034; // offset 0x2034, size 0x4 + void* unkPtr_0x2038; // offset 0x2038, size 0x4 + void* unkPtr_0x203C; // offset 0x203C, size 0x4 + void* unkPtr_0x2040; // offset 0x2040, size 0x4 + void* unkPtr_0x2044; // offset 0x2044, size 0x4 + void* unkPtr_0x2048; // offset 0x2048, size 0x4 + void* unkPtr_0x204C; // offset 0x204C, size 0x4 + void* unkPtr_0x2050; // offset 0x2050, size 0x4 + void* unkPtr_0x2054; // offset 0x2054, size 0x4 + void* unkPtr_0x2058; // offset 0x2058, size 0x4 + void* unkPtr_0x205C; // offset 0x205C, size 0x4 + void* unkPtr_0x2060; // offset 0x2060, size 0x4 + void* unkPtr_0x2064; // offset 0x2064, size 0x4 + void* unkPtr_0x2068; // offset 0x2068, size 0x4 + void* unkPtr_0x206C; // offset 0x206C, size 0x4 + bool flag_0x2070; // offset 0x2070, size 0x1 + u8 pad_0x2071[0x3]; // offset 0x2071, size 0x3 + float field_0x2074; // offset 0x2074, size 0x4 + bool flag_0x2078; // offset 0x2078, size 0x1 + u8 pad_0x2079[0x3]; // offset 0x2079, size 0x3 + int laneStateTarget; // offset 0x207C, size 0x4 +}; + +struct SomeUnkManager0 { + // total size: 0x30 + void* vtable; // offset 0x0, size 0x4 + void* unkPtr_0x4; // offset 0x4, size 0x4 + void* unkPtr_0x8; // offset 0x8, size 0x4 + void* unkPtr_0xC; // offset 0xC, size 0x4 + void* unkPtr_0x10; // offset 0x10, size 0x4 + void* arr[7]; // offset 0x14, size 0x1C +}; + +struct SubNpcLaneData { + // total size: 0x5C + u32 field_0x0; // offset 0x0, size 0x4 + int counter_0x4; // offset 0x4, size 0x4 + float field_0x8; // offset 0x8, size 0x4 + u8 pad_0xC[0x4]; // offset 0xC, size 0x4 + float field_0x10; // offset 0x10, size 0x4 + float field_0x14; // offset 0x14, size 0x4 + float field_0x18; // offset 0x18, size 0x4 + float field_0x1C; // offset 0x1C, size 0x4 + float field_0x20; // offset 0x20, size 0x4 + float field_0x24; // offset 0x24, size 0x4 + float field_0x28; // offset 0x28, size 0x4 + u8 pad_0x2C[0x4]; // offset 0x2C, size 0x4 + u8 pad_0x30[0x4]; // offset 0x30, size 0x4 + float field_0x34; // offset 0x34, size 0x4 + u8 pad_0x38[0x4]; // offset 0x38, size 0x4 + u8 pad_0x3C[0x4]; // offset 0x3C, size 0x4 + float field_0x40; // offset 0x40, size 0x4 + u8 pad_0x44[0x4]; // offset 0x44, size 0x4 + float field_0x48; // offset 0x48, size 0x4 + u8 pad_0x4C[0x4]; // offset 0x4C, size 0x4 + u8 pad_0x50[0x4]; // offset 0x50, size 0x4 + u8 flag_0x54; // offset 0x54, size 0x1 + u8 flag_0x55; // offset 0x55, size 0x1 + u8 flag_0x56; // offset 0x56, size 0x1 + u8 flag_0x57; // offset 0x57, size 0x1 + int field_0x58; // offset 0x58, size 0x4 +}; + +struct NpcModelGroup { + // total size: 0xB4 + void* vtable; // offset 0x0, size 0x4 + u8 pad_00[0xA0]; // offset 0x4, size 0xA0 + RPGrpModel* mModelA4; // offset 0xA4, size 0x4 + RPGrpModel* mModelA8; // offset 0xA8, size 0x4 + RPGrpModel* mModelAC; // offset 0xAC, size 0x4 + RPGrpModel* mModelB0; // offset 0xB0, size 0x4 +}; + +struct ModelGroupPair { + // total size: 0x8 + NpcModelGroup* groupA; // offset 0x0, size 0x4 + NpcModelGroup* groupB; // offset 0x4, size 0x4 +}; + +struct NpcLaneDataHolder { + // total size: 0x130 + void* vtable; // offset 0x0, size 0x4 + void* unkPtr_0x04; // offset 0x4, size 0x4 + u32 field_0x08; // offset 0x8, size 0x4 + float field_0x0C; // offset 0xC, size 0x4 + float field_0x10; // offset 0x10, size 0x4 + float field_0x14; // offset 0x14, size 0x4 + float field_0x18; // offset 0x18, size 0x4 + float field_0x1C; // offset 0x1C, size 0x4 + float field_0x20; // offset 0x20, size 0x4 + float field_0x24; // offset 0x24, size 0x4 + float field_0x28; // offset 0x28, size 0x4 + float field_0x2C; // offset 0x2C, size 0x4 + SubNpcLaneData subData; // offset 0x30, size 0x5C + ModelGroupPair groups[4]; // offset 0x8C, size 0x20 + u16 field_0xAC; // offset 0xAC, size 0x2 + u16 field_0xAE; // offset 0xAE, size 0x2 + float field_0xB0; // offset 0xB0, size 0x4 + float field_0xB4; // offset 0xB4, size 0x4 + u16 field_0xB8; // offset 0xB8, size 0x2 + u16 field_0xBA; // offset 0xBA, size 0x2 + float field_0xBC; // offset 0xBC, size 0x4 + float field_0xC0; // offset 0xC0, size 0x4 + float field_0xC4; // offset 0xC4, size 0x4 + float field_0xC8; // offset 0xC8, size 0x4 + float field_0xCC; // offset 0xCC, size 0x4 + float field_0xD0; // offset 0xD0, size 0x4 + u16 field_0xD4; // offset 0xD4, size 0x2 + u16 field_0xD6; // offset 0xD6, size 0x2 + u16 field_0xD8; // offset 0xD8, size 0x2 + u8 pad_0xDA[0x2]; // offset 0xDA, size 0x2 + nw4r::math::VEC3 vec_0xDC; // offset 0xDC, size 0xC + float field_0xE8; // offset 0xE8, size 0x4 + float field_0xEC; // offset 0xEC, size 0x4 + u8 flags[0x4]; // offset 0xF0, size 0x4 + void* unkPtr_0xF4; // offset 0xF4, size 0x4 + float field_0xF8; // offset 0xF8, size 0x4 + float field_0xFC; // offset 0xFC, size 0x4 + float field_0x100; // offset 0x100, size 0x4 + float field_0x104; // offset 0x104, size 0x4 + float field_0x108; // offset 0x108, size 0x4 + float field_0x10C; // offset 0x10C, size 0x4 + float field_0x110; // offset 0x110, size 0x4 + float field_0x114; // offset 0x114, size 0x4 + RPGrpModel* unkModel_0x118; // offset 0x118, size 0x4 + float field_0x11C; // offset 0x11C, size 0x4 + void* field_0x120[0x4]; // offset 0x120, size 0x10 +}; + +class RPBowTrajectoryGuide : public RP_DEBUG_STUB_1 { +public: + // total size: 0x6C + virtual ~RPBowTrajectoryGuide(); // offset 0x0, size 0x4 + RPGrpModel* mpMainModel; // offset 0x4, size 0x4 + RPGrpModel* mpUnkModel; // offset 0x8, size 0x4 + RPGrpModel* mpDotModels[16]; // offset 0xC, size 0x40 + u32 mActiveModelIndex; // offset 0x4C, size 0x4 + u8 mIsVisible; // offset 0x50, size 0x1 + u8 pad51[3]; // offset 0x51, size 0x3 + f32 mStartX; // offset 0x54, size 0x4 + f32 mAngle; // offset 0x58, size 0x4 + f32 unk_0x5C; // offset 0x5C, size 0x4 + u32 unk_0x60; // offset 0x60, size 0x4 + f32 mLimitCenter; // offset 0x64, size 0x4 + f32 mLimitWidth; // offset 0x68, size 0x4 + + void SetMainModels(RPGrpModel* pMainModel, RPGrpModel* pUnkModel); + void SetDotModel(u32 index, RPGrpModel* pDotModel); + void Initialize(); + void Reset(); + void Draw(); +}; + +struct NpcIdleStateSub { + // total size: 0x3C + int idleState; // offset 0x0, size 0x4 + int frameCounter; // offset 0x4, size 0x4 + int unk_0x8; // offset 0x8, size 0x4 + float targetRotation; // offset 0xC, size 0x4 + float rotationSpeed; // offset 0x10, size 0x4 + nw4r::math::VEC3 pos; // offset 0x14, size 0xC + s32 bouncesRemaining; // offset 0x20, size 0x4 + float bounceVelocity; // offset 0x24, size 0x4 + s32 unk_countdown_0x28; // offset 0x28, size 0x4 + u8 field_0x2C; // offset 0x2C, size 0x1 + u8 pad_0x2D[3]; // offset 0x2D, size 0x3 + float field_0x30; // offset 0x30, size 0x4 + float field_0x34; // offset 0x34, size 0x4 + u8 field_0x38; // offset 0x38, size 0x1 + u8 pad_0x39[3]; // offset 0x39, size 0x3 +}; + +struct NpcIdleState { + // total size: 0x48 + void* vtable; // offset 0x0, size 0x4 + int unk_0x04; // offset 0x4, size 0x4 + int unk_0x08; // offset 0x8, size 0x4 + NpcIdleStateSub sub; // offset 0xC, size 0x3C +}; + +enum NpcStates { + NPC_STATE_IDLE = 0, // Idle state + NPC_STATE_WALK_TO_APPROACH_AREA = 1, // Walking to approach area + NPC_STATE_UNUSED_2 = 2, // Unused + NPC_STATE_BOWL = 3, // Bowling action + NPC_STATE_WALK_TO_BALL_RETURN = 4, // Walking to ball return + NPC_STATE_WALK_BACK_TO_SEAT = 5, // Walking back to seat +}; + +struct NpcMovementState { + // total size: 0x1C + void* vtable; // offset 0x0, size 0x4 + s32 laneIdx; // offset 0x4, size 0x4 + s32 npcIdx; // offset 0x8, size 0x4 + u8 isMovementComplete; // offset 0xC, size 0x1 + u8 pad0D[3]; // offset 0xD, size 0x3 + nw4r::math::VEC3 returnStartPos; // offset 0x10, size 0xC +}; + +struct NpcContext { + // total size: 0xA8 + void* vtable; // offset 0x0, size 0x4 + RPSysKokeshi* mpKokeshi; // offset 0x4, size 0x4 + void* field_0x8; // offset 0x8, size 0x4 + void* field_0xC; // offset 0xC, size 0x4 + nw4r::math::VEC3 pos_0x10; // offset 0x10, size 0xC + nw4r::math::VEC3 rot_0x1C; // offset 0x1C, size 0xC + float field_0x28; // offset 0x28, size 0x4 + u8 pad_0x2C[0x4]; // offset 0x2C, size 0x4 + NpcStates npcState; // offset 0x30, size 0x4 + int stateFrameCounter; // offset 0x34, size 0x4 + u8 triggerThrow; // offset 0x38, size 0x1 + u8 triggerTransition; // offset 0x39, size 0x1 + u8 pad_0x3A[0x2]; // offset 0x3A, size 0x2 + s32 field_0x3A; // offset 0x3C, size 0x4 + float targetZPos; // offset 0x40, size 0x4 + u8 field_0x44; // offset 0x44, size 0x1 + u8 pad_0x45[3]; // offset 0x45, size 0x3 + NpcMovementState* movementState; // offset 0x48, size 0x4 + int field_0x4C; // offset 0x4C, size 0x4, 0 = Walk to approach area, 1 = Idle at approach area, 2 = Bowl, 3 = Watch ball, 4 = Turn around, 5 = Walk to ball return or seat from approach area, 6 = Idle, 7 = Walk to ball return from seat + u8 isHoldingBall; // offset 0x50, size 0x1 + u8 flag_51; // offset 0x51, size 0x1 + u8 flag_52; // offset 0x52, size 0x1 + u8 flag_53; // offset 0x53, size 0x1 + int laneIdx; // offset 0x54, size 0x4 + int npcIdx; // offset 0x58, size 0x4 + NpcIdleState subStruct; // offset 0x5C, size 0x48 + u8 pad_0xA4[0x1]; // offset 0xA4, size 0x1 + u8 flag_A5; // offset 0xA5, size 0x1 + u8 pad_0xA6[0x2]; // offset 0xA6, size 0x2 +}; + +class RPBowPlayerLaneNpc : public RP_DEBUG_STUB_1 { +public: + // total size: 0x78 + virtual ~RPBowPlayerLaneNpc(); // offset 0x0, size 0x4 + void* unkPtr_0x4; // offset 0x4, size 0x4 + RPSysKokeshi* mKokeshis[2]; // offset 0x8, size 0x8 + u32 index; // offset 0x10, size 0x4 + nw4r::math::VEC3 pos; // offset 0x14, size 0xC + nw4r::math::VEC3 rot; // offset 0x20, size 0xC + u8 isVisible; // offset 0x2C, size 0x1 + u8 pad_0x2D[0x3]; // offset 0x2D, size 0x3 + NpcIdleState npcIdleState; // offset 0x30, size 0x48 + + void Init(RPSysKokeshi* kokeshi1, RPSysKokeshi* kokeshi2, int index); + void SetSeatPosition(); + void HideActiveBowler(); + void UpdateModels(); +}; + +struct BallReturnBall { + // total size: 0x28 + nw4r::math::VEC3 mPos; // offset 0x0, size 0xC + nw4r::math::VEC3 unkVec_0xC; // offset 0xC, size 0xC + float mSpeed; // offset 0x18, size 0x4 + float mAngle; // offset 0x1C, size 0x4 + float mRepulsionForce; // offset 0x20, size 0x4 + bool mClaimedByNPC; // offset 0x24, size 0x1 + bool mIsOnRack; // offset 0x25, size 0x1 + char pad_0x26[0x2]; // offset 0x26, size 0x2 +}; + +class RPBowBallReturnRack { +public: + // total size: 0xDC + RPGrpModelPair mModels[4]; // offset 0x0, size 0x20 + void* unkPtr_0x20; // offset 0x20, size 0x4 + void* unkPtr_0x24; // offset 0x24, size 0x4 + s32 mSlotIndices[4]; // offset 0x28, size 0x10 + int mRackIndex; // offset 0x38, size 0x4 + BallReturnBall mBalls[4]; // offset 0x3C, size 0xA0 (Order: Blue, Red, Green, Yellow) + + void InitBallReturnRack(s32 index); + void InitBallSlotResources(s32 index, RPGrpModel* realModel, RPGrpModel* reflectionModel, s32 slotIndex); + void ResetRackBallStates(); + int SelectBallForNPC(); + void RemoveBallFromRack(s32 index); + u8 IsBallOnRack(s32 index); + void SpawnBallOnRack(s32 index); + void ReleaseBallFromNPC(s32 index); + s32 GetBallSlotIndex(s32 index); + void UpdateBallReturnRack(s32 index); +}; + +struct BackgroundNpcMovement { + // total size: 0x30 + nw4r::math::VEC3 position; // offset 0x0, size 0xC + nw4r::math::VEC3 rotation; // offset 0xC, size 0xC + nw4r::math::VEC3 velocity; // offset 0x18, size 0xC + int behaviorState; // offset 0x24, size 0x4 + int stateTimer; // offset 0x28, size 0x4 + int animationState; // offset 0x2C, size 0x4 +}; + +class RPBowBackgroundNpcManager : public RP_DEBUG_STUB_1 { +public: + // total size: 0x9C + virtual ~RPBowBackgroundNpcManager(); // offset 0x0, size 0x4 + void* unkPtr_0x04; // offset 0x4, size 0x4 + BackgroundNpcMovement mMovement; // offset 0x8, size 0x30 + NpcModelGroup* mModelGroups[2][2]; // offset 0x38, size 0x10 + int mConfigIndex; // offset 0x48, size 0x4 + NpcIdleState mIdleState; // offset 0x4C, size 0x48 + bool unk_0x94; // offset 0x94, size 0x1 + u8 pad_0x95[3]; // offset 0x95, size 0x3 + s32 mModelGroupSet; // offset 0x98, size 0x4 + + void fn_8034E96C(); + void InitializeConfig(int index); + void SetModelGroups(int managerIndex, NpcModelGroup* modelGroup0, NpcModelGroup* modelGroup1); + void fn_8034E83C(); + void Reset(); + void UpdateMovement(nw4r::math::VEC3* outPosition, bool* outStateFlag); + void Render(); + void fn_8034DD14(); + void fn_8034DD0C(); + void fn_8034DD08(); +}; + +struct SceneEntities { + // total size: 0x1E0 + void* unkPtr_0x04; // offset 0x0, size 0x4 + NpcLaneDataHolder* npcLaneData; // offset 0x4, size 0x4 + RPBowTrajectoryGuide* trajectoryGuide; // offset 0x8, size 0x4 + void* unkPtr_0x10; // offset 0xC, size 0x4 + void* unkPtr_0x14; // offset 0x10, size 0x4 + void* unkPtr_0x18; // offset 0x14, size 0x4 + void* unkPtr_0x1C; // offset 0x18, size 0x4 + void* unkPtr_0x20; // offset 0x1C, size 0x4 + void* unkPtr_0x24; // offset 0x20, size 0x4 + void* unkPtr_0x28; // offset 0x24, size 0x4 + void* unkPtr_0x2C; // offset 0x28, size 0x4 + RPBowActiveBall* balls[7]; // offset 0x2C, size 0x1C + NpcContext* npcs[18]; // offset 0x48, size 0x48 + RPBowPlayerLaneNpc* playerLaneNpcs[4]; // offset 0x90, size 0x10 + PinSetter* setters[7]; // offset 0xA0, size 0x1C + void* unkPtrs2[64]; // offset 0xBC, size 0x100 + RPBowBallReturnRack* ballReturns[4]; // offset 0x1BC, size 0x10 + RPBowBackgroundNpcManager* BackgroundNpcs[4]; // offset 0x1CC, size 0x10 + void* unkPtr_0x1E0; // offset 0x1DC, size 0x4 +}; + +struct SceneObjectManager { + // total size: 0x218 + void* vtable; // offset 0x0, size 0x4 + SceneEntities entities; // offset 0x4, size 0x1E0 + u8 field_0x1E4; // offset 0x1E4, size 0x1 + u8 pad_0x1E5; // offset 0x1E5, size 0x1 + u8 field_0x1E6; // offset 0x1E6, size 0x1 + u8 field_0x1E7; // offset 0x1E7, size 0x1 + u8 field_0x1E8; // offset 0x1E8, size 0x1 + u8 field_0x1E9; // offset 0x1E9, size 0x1 + u8 field_0x1EA; // offset 0x1EA, size 0x1 + u8 field_0x1EB; // offset 0x1EB, size 0x1 + void* unkPtr_0x1EC; // offset 0x1EC, size 0x4 + u8 isComplete; // offset 0x1F0, size 0x1 + u8 field_0x1F1; // offset 0x1F1, size 0x1 + u8 field_0x1F2; // offset 0x1F2, size 0x1 + u8 field_0x1F3; // offset 0x1F3, size 0x1 + u8 field_0x1F4; // offset 0x1F4, size 0x1 + u8 pad_0x1F5[0x3]; // offset 0x1F5, size 0x3 + void* unkPtr_0x1F8; // offset 0x1F8, size 0x4 + void* unkPtr_0x1FC; // offset 0x1FC, size 0x4 + void* unkPtr_0x200; // offset 0x200, size 0x4 + u8 pad_0x204[0x4]; // offset 0x204, size 0x4 + void* obj208Data; // offset 0x208, size 0x4 + void* field_0x20C; // offset 0x20C, size 0x4 + float field_0x210; // offset 0x210, size 0x4 + float field_0x214; // offset 0x214, size 0x4 +}; + +class RPBowGlobalLaneManager { +public: + // total size: 0x24 + u8 pad_00[0x04]; // offset 0x0, size 0x4 + LaneContext* pLanes[7]; // offset 0x4, size 0x1C + u8 isInitialized; // offset 0x20, size 0x1 + u8 field_0x21; // offset 0x21, size 0x1 + u8 pad_22[0x2]; // offset 0x22, size 0x2 + + void InitializeBallManagerLanes(); + void SetupBallManagerLaneObjects(void* arg1, void* arg2); + void ResetLanePinsAndAnimations(); + void SetLaneUnknownState(int value); + void UpdateBallsPhysics(); + void TickNpcLanes(); + void UpdateLaneItems(int val, void* obj, SomeUnkManager0* someMgr, bool isPlayerTurn); + void UpdateBallsMdl(SceneObjectManager* vballmgr); +}; + +class RPBowNpcManager: public IRPSysHostIOSocket { +public: + // Total Size 0x58. See fn_80332B34 + // vtable // offset 0x0, size 0x4 + u32 pad_0x04; // offset 0x4, size 0x4 + int mStateId; // offset 0x8, size 0x4, 0 = Idle, 1 = Walk to approach area, 2 = Idle at approach area, 3 = Bowl, 4 = Watch ball, 5 = Walk to ball return or seat. + int mStateTimer; // offset 0xC, size 0x4 + bool mHasReleasedBall; // offset 0x10, size 0x1, Set to 1 the moment the first ball is thrown during a turn. + bool mIsSecondThrow; // offset 0x11, size 0x1, Set to 1 the moment the NPC walks up to the approach area on the second turn. + bool mShouldReturnToSeat; // offset 0x12, size 0x1, Set to 1 after the pins are knocked down and the NPC turns to walk back to their seat. + u8 field_0x13; // offset 0x13, size 0x1 + LaneContext* mpLaneContext; // offset 0x14, size 0x4 + NpcContext* mpNpcs[3]; // offset 0x18, size 0xC + NpcContext* mpCurrentNpc; // offset 0x24, size 0x4 + int mLaneIdx; // offset 0x28, size 0x4 + int mCurrentNpcIdx; // offset 0x2C, size 0x4 + PinStatus mPinStatus; // offset 0x30, size 0x14 + void* mpSoundAudioMgr; // offset 0x44, size 0x4 + bool mHasPlayedGutterSfx; // offset 0x48, size 0x1 + u8 mDisableResultSfx; // offset 0x49, size 0x1 + u8 field_0x4A; // offset 0x4A, size 0x1 + u8 field_0x4B; // offset 0x4B, size 0x1 + RPBowBallReturnRack* mpReturnRack; // offset 0x4C, size 0x4 + s32 mActiveSubObjIdx; // offset 0x50, size 0x4 + void* mpSomeAudioStruct; // offset 0x54, size 0x4 + + void InitAudioActors(int laneIdx); + void Setup(LaneContext* pLaneContext, NpcContext* pNpc0, NpcContext* pNpc1, NpcContext* pNpc2, int laneIdx, RPBowBallReturnRack* pReturnRack, void* pAudioStruct); + int IsLaneIdle(); + void SetStateFlag(u8 flag); + void ActivateNpcTurn(); + void Update(); + void DebugPrintNpcState(); + + inline RPBowNpcManager() { + mPinStatus.pinBits[3] = -1; + mPinStatus.pinBits[2] = -1; + mPinStatus.pinBits[1] = -1; + mPinStatus.pinBits[0] = -1; + mPinStatus.pinCount = 10; + } + + nw4r::math::MTX34 GetPinWorldMatrix(int pinIndex) const { + if (pinIndex >= mpLaneContext->pinCount) { + nw4r::math::MTX34 matrix; + nw4r::math::MTX34Identity(&matrix); + return matrix; + } else { + PinPhysicsBody* pinData = mpLaneContext->pPinManager->pPinBodies[pinIndex]; + return nw4r::math::MTX34( + pinData->basisX.x, pinData->basisY.x, pinData->basisZ.x, pinData->position.x, + pinData->basisX.y, pinData->basisY.y, pinData->basisZ.y, pinData->position.y, + pinData->basisX.z, pinData->basisY.z, pinData->basisZ.z, pinData->position.z + ); + } + } +}; + +class RPBowManagerContext { +public: + // total size: 0x34 + void* vtable; // offset 0x0, size 0x4 + RPBowNpcManager* mpManagers[6]; // offset 0x4, size 0x18 + int field_0x1C; // offset 0x1C, size 0x4 + u8 mIsEnabled; // offset 0x20, size 0x1 + u8 pad_0x24[7]; // offset 0x21, size 0x7 + int field_0x28; // offset 0x28, size 0x4 + void* field_0x2C; // offset 0x2C, size 0x4 + void* field_0x30; // offset 0x30, size 0x4 + + void Initialize(); + void LinkNpcLanes(RPBowGlobalLaneManager* laneManager, SceneObjectManager* sceneObjectManager); + void SetNpcStateFlags(u8 flag); + void UpdateNpcs(); + void DebugPrintStates(); +}; + +class RPBowMotionBlur : public RP_DEBUG_STUB_1 { +public: + // total size: 0xB4 + virtual ~RPBowMotionBlur(); // offset 0x0, size 0x4 + RPGrpModelPair models[3]; // offset 0x4, size 0x18 + nw4r::math::MTX34 blurMtxs[3]; // offset 0x1C, size 0x90 + bool isActive; // offset 0xAC, size 0x1 + u8 pad1[3]; // offset 0xAD, size 0x3 + f32 speed; // offset 0xB0, size 0x4 + + void SetBlurModels(RPGrpModel* pReal1, RPGrpModel* pReal2, RPGrpModel* pReal3, RPGrpModel* pRefl1, RPGrpModel* pRefl2, RPGrpModel* pRefl3); + void DeactivateBlur(); + void UpdateBlurTransform(const nw4r::math::MTX34* pBaseMtx, f32 speed); + void DrawBlur(void* pCullingCtx); +}; + +// Global Data: + +struct BallReturnRackConstants { + // total size: 0x3C + nw4r::math::VEC3 mPositionOffsets[4]; // offset 0x0, size 0x30 + float mHeightLimit; // offset 0x30, size 0x4 + float mRepulsionThreshold; // offset 0x34, size 0x4 + float mGravity; // offset 0x38, size 0x4 +}; + +struct BowlingPhysicsData { + // total size: 0x2D0 + u8 flag_00; // offset 0x0, size 0x1 + u8 flag_01; // offset 0x1, size 0x1 + u8 flag_02; // offset 0x2, size 0x1 + u8 flag_03; // offset 0x3, size 0x1 + u8 flag_04; // offset 0x4, size 0x1 + u8 flag_05; // offset 0x5, size 0x1 + u8 flag_06; // offset 0x6, size 0x1 + u8 flag_07; // offset 0x7, size 0x1 + f32 field_08; // offset 0x8, size 0x4 + f32 field_0C; // offset 0xC, size 0x4 + f32 field_10; // offset 0x10, size 0x4 + f32 field_14; // offset 0x14, size 0x4 + f32 field_18; // offset 0x18, size 0x4 + f32 field_1C; // offset 0x1C, size 0x4 + f32 field_20; // offset 0x20, size 0x4 + f32 field_24; // offset 0x24, size 0x4 + f32 field_28; // offset 0x28, size 0x4 + f32 field_2C; // offset 0x2C, size 0x4 + f32 field_30; // offset 0x30, size 0x4 + f32 field_34; // offset 0x34, size 0x4 + u8 pad_0x38[0x3C]; // offset 0x38, size 0x3C + f32 field_74; // offset 0x74, size 0x4 + f32 field_78; // offset 0x78, size 0x4 + f32 field_7C; // offset 0x7C, size 0x4 + f32 field_80; // offset 0x80, size 0x4 + u8 pad_0x84[0x8]; // offset 0x84, size 0x8 + f32 field_8C; // offset 0x8C, size 0x4 + f32 field_90; // offset 0x90, size 0x4 + f32 field_94; // offset 0x94, size 0x4 + u8 pad_0x98[0x70]; // offset 0x98, size 0x70 + f32 field_108; // offset 0x108, size 0x4 + f32 field_10C; // offset 0x10C, size 0x4 + f32 field_110; // offset 0x110, size 0x4 + f32 field_114; // offset 0x114, size 0x4 + f32 field_118; // offset 0x118, size 0x4 + f32 field_11C; // offset 0x11C, size 0x4 + u8 pad_0x120[0x8]; // offset 0x120, size 0x8 + f32 field_128; // offset 0x128, size 0x4 + u8 pad_0x12C[0x2C]; // offset 0x12C, size 0x2C + f32 field_158; // offset 0x158, size 0x4 + u8 pad_0x15C[0x28]; // offset 0x15C, size 0x28 + f32 field_184; // offset 0x184, size 0x4 + u8 pad_0x188[0x1C]; // offset 0x188, size 0x1C + f32 field_1A4; // offset 0x1A4, size 0x4 + u8 pad_0x1A8[0x1C]; // offset 0x1A8, size 0x1C + f32 field_1C4; // offset 0x1C4, size 0x4 + u8 pad_0x1C8[0x3C]; // offset 0x1C8, size 0x3C + f32 field_204; // offset 0x204, size 0x4 + f32 field_208; // offset 0x208, size 0x4 + u8 pad_0x20C[0x60]; // offset 0x20C, size 0x60 + f32 floats[20]; // offset 0x26C, size 0x50 + f32 field_2BC; // offset 0x2BC, size 0x4 + f32 field_2C0; // offset 0x2C0, size 0x4 + f32 field_2C4; // offset 0x2C4, size 0x4 + f32 field_2C8; // offset 0x2C8, size 0x4 + f32 field_2CC; // offset 0x2CC, size 0x4 +}; + +struct BackgroundNpcConfig { + // total size: 0x44 + float laneZPositions[4]; // offset 0x0, size 0x10 + float basePosY; // offset 0x10, size 0x4 + float seatedPosY; // offset 0x14, size 0x4 + float mirroredModelZOffset; // offset 0x18, size 0x4 + float patrolMinX; // offset 0x1C, size 0x4 + float patrolMaxX; // offset 0x20, size 0x4 + float minWalkSpeed; // offset 0x24, size 0x4 + float maxWalkSpeed; // offset 0x28, size 0x4 + u32 dormantToPatrolChanceDenom; // offset 0x2C, size 0x4 + u32 patrolToIdleChanceDenom; // offset 0x30, size 0x4 + u32 idleToPatrolChanceDenom; // offset 0x34, size 0x4 + float turnLerpRate; // offset 0x38, size 0x4 + float idleCenterZoneX; // offset 0x3C, size 0x4 + u32 minStateDuration; // offset 0x40, size 0x4 +}; + +extern BallReturnRackConstants gBallReturnRackConstants; +extern BowlingPhysicsData gBowlingPhysicsData; + +} // namespace Bowling diff --git a/include/Pack/RPSports/RPBoxScene.h b/include/Pack/RPSports/RPBoxScene.h new file mode 100644 index 000000000..313ddb18c --- /dev/null +++ b/include/Pack/RPSports/RPBoxScene.h @@ -0,0 +1,6 @@ +#ifndef RP_PUBLIC_SPORTS_BOX_H +#define RP_PUBLIC_SPORTS_BOX_H + +#include + +#endif diff --git a/include/Pack/RPSports/RPBoxScene/RPBoxScene.h b/include/Pack/RPSports/RPBoxScene/RPBoxScene.h new file mode 100644 index 000000000..8c6a4879f --- /dev/null +++ b/include/Pack/RPSports/RPBoxScene/RPBoxScene.h @@ -0,0 +1,20 @@ +#ifndef RP_SPORTS_BOX_SCENE_H +#define RP_SPORTS_BOX_SCENE_H +#include + +#include + +//! @addtogroup rp_box +//! @{ + +/** + * @brief Sports Pack Boxing scene + */ +class RPBoxScene : public RPSportsBaseScene { +private: + char unk9C[0x10C - 0x9C]; +}; + +//! @} + +#endif diff --git a/include/Pack/RPSports/RPBsbScene.h b/include/Pack/RPSports/RPBsbScene.h new file mode 100644 index 000000000..cb6cdfbc8 --- /dev/null +++ b/include/Pack/RPSports/RPBsbScene.h @@ -0,0 +1,6 @@ +#ifndef RP_PUBLIC_SPORTS_BSB_H +#define RP_PUBLIC_SPORTS_BSB_H + +#include + +#endif diff --git a/include/Pack/RPSports/RPBsbScene/RPBsbScene.h b/include/Pack/RPSports/RPBsbScene/RPBsbScene.h new file mode 100644 index 000000000..007a97e4a --- /dev/null +++ b/include/Pack/RPSports/RPBsbScene/RPBsbScene.h @@ -0,0 +1,20 @@ +#ifndef RP_SPORTS_BSB_SCENE_H +#define RP_SPORTS_BSB_SCENE_H +#include + +#include + +//! @addtogroup rp_bsb +//! @{ + +/** + * @brief Sports Pack Baseball scene + */ +class RPBsbScene : public RPSportsBaseScene { +private: + char unk9C[0xA8 - 0x9C]; +}; + +//! @} + +#endif diff --git a/include/Pack/RPSports/RPGolScene.h b/include/Pack/RPSports/RPGolScene.h new file mode 100644 index 000000000..fbcb80f80 --- /dev/null +++ b/include/Pack/RPSports/RPGolScene.h @@ -0,0 +1,7 @@ +#ifndef RP_PUBLIC_SPORTS_GOL_H +#define RP_PUBLIC_SPORTS_GOL_H + +#include +#include + +#endif diff --git a/include/Pack/RPSports/RPGolScene/RPGolScene.h b/include/Pack/RPSports/RPGolScene/RPGolScene.h new file mode 100644 index 000000000..9c48919cc --- /dev/null +++ b/include/Pack/RPSports/RPGolScene/RPGolScene.h @@ -0,0 +1,20 @@ +#ifndef RP_SPORTS_GOL_SCENE_H +#define RP_SPORTS_GOL_SCENE_H +#include + +#include + +//! @addtogroup rp_gol +//! @{ + +/** + * @brief Sports Pack Golf scene + */ +class RPGolScene : public RPSportsBaseScene { +private: + char unk9C[0xA0 - 0x9C]; +}; + +//! @} + +#endif diff --git a/include/Pack/RPSports/RPGolScene/RPGolSelectScene.h b/include/Pack/RPSports/RPGolScene/RPGolSelectScene.h new file mode 100644 index 000000000..ee792ee87 --- /dev/null +++ b/include/Pack/RPSports/RPGolScene/RPGolSelectScene.h @@ -0,0 +1,19 @@ +#ifndef RP_SPORTS_GOL_COURSE_SELECT_SCENE_H +#define RP_SPORTS_GOL_COURSE_SELECT_SCENE_H +#include + +#include + +//! @addtogroup rp_gol +//! @{ + +/** + * @brief Sports Pack golf course select scene + */ +class RPGolCourseSelectScene : public RPSysScene { + char unk44[0xE4 - 0x44]; +}; + +//! @} + +#endif diff --git a/include/Pack/RPSports/RPSportsCommon.h b/include/Pack/RPSports/RPSportsCommon.h new file mode 100644 index 000000000..f762160ec --- /dev/null +++ b/include/Pack/RPSports/RPSportsCommon.h @@ -0,0 +1,14 @@ +#ifndef RP_PUBLIC_SPORTS_COMMON_H +#define RP_PUBLIC_SPORTS_COMMON_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#endif diff --git a/include/Pack/RPSports/RPSportsAppMiiManager.h b/include/Pack/RPSports/RPSportsCommon/RPSportsAppMiiManager.h similarity index 85% rename from include/Pack/RPSports/RPSportsAppMiiManager.h rename to include/Pack/RPSports/RPSportsCommon/RPSportsAppMiiManager.h index 8102dada7..89e2084a5 100644 --- a/include/Pack/RPSports/RPSportsAppMiiManager.h +++ b/include/Pack/RPSports/RPSportsCommon/RPSportsAppMiiManager.h @@ -1,5 +1,5 @@ -#ifndef RP_SPORTS_APP_MII_MANAGER_H -#define RP_SPORTS_APP_MII_MANAGER_H +#ifndef RP_SPORTS_COMMON_APP_MII_MANAGER_H +#define RP_SPORTS_COMMON_APP_MII_MANAGER_H #include #include diff --git a/include/Pack/RPSports/RPSportsCommon/RPSportsBaseScene.h b/include/Pack/RPSports/RPSportsCommon/RPSportsBaseScene.h new file mode 100644 index 000000000..a85b9a0d2 --- /dev/null +++ b/include/Pack/RPSports/RPSportsCommon/RPSportsBaseScene.h @@ -0,0 +1,38 @@ +#ifndef RP_SPORTS_COMMON_BASE_SCENE_H +#define RP_SPORTS_COMMON_BASE_SCENE_H +#include + +#include + +//! @addtogroup rp_sports +//! @{ + +/** + * @brief Base class for Sports Pack scenes + */ +class RPSportsBaseScene : public RPSysScene { +public: + virtual void Configure() override; + virtual void LoadResource() override; + virtual void Reset() override; + virtual void Calculate() override; + virtual void Exit() override; + + virtual void OnConfigure(); + virtual void OnLoadResource(); + virtual void OnReset(); + virtual void OnCalculate(); + virtual void OnUserDraw(); + virtual void OnDebugDraw(); + virtual void OnExit(); + + virtual void UserDraw() override; + virtual void DebugDraw() override; + +private: + char unk44[0x9C - 0x44]; +}; + +//! @} + +#endif diff --git a/include/Pack/RPSports/RPSportsBodyManager.h b/include/Pack/RPSports/RPSportsCommon/RPSportsBodyManager.h similarity index 94% rename from include/Pack/RPSports/RPSportsBodyManager.h rename to include/Pack/RPSports/RPSportsCommon/RPSportsBodyManager.h index 6e3f7e149..f2919ebec 100644 --- a/include/Pack/RPSports/RPSportsBodyManager.h +++ b/include/Pack/RPSports/RPSportsCommon/RPSportsBodyManager.h @@ -1,5 +1,5 @@ -#ifndef RP_SPORTS_BODY_MANAGER_H -#define RP_SPORTS_BODY_MANAGER_H +#ifndef RP_SPORTS_COMMON_BODY_MANAGER_H +#define RP_SPORTS_COMMON_BODY_MANAGER_H #include #include diff --git a/include/Pack/RPSports/RPSportsCommon/RPSportsMainScene/RPSportsMainScene.h b/include/Pack/RPSports/RPSportsCommon/RPSportsMainScene/RPSportsMainScene.h new file mode 100644 index 000000000..97c60185e --- /dev/null +++ b/include/Pack/RPSports/RPSportsCommon/RPSportsMainScene/RPSportsMainScene.h @@ -0,0 +1,19 @@ +#ifndef RP_SPORTS_COMMON_MAIN_SCENE_H +#define RP_SPORTS_COMMON_MAIN_SCENE_H +#include + +#include + +//! @addtogroup rp_sports +//! @{ + +/** + * @brief Sports Pack main menu scene + */ +class RPSportsMainScene : public RPSysScene { + char unk44[0x58 - 0x44]; +}; + +//! @} + +#endif diff --git a/include/Pack/RPSports/RPSportsCommon/RPSportsPackTitleScene/RPSportsPackTitleScene.h b/include/Pack/RPSports/RPSportsCommon/RPSportsPackTitleScene/RPSportsPackTitleScene.h new file mode 100644 index 000000000..84a448939 --- /dev/null +++ b/include/Pack/RPSports/RPSportsCommon/RPSportsPackTitleScene/RPSportsPackTitleScene.h @@ -0,0 +1,31 @@ +#ifndef RP_SPORTS_COMMON_PACK_TITLE_SCENE_H +#define RP_SPORTS_COMMON_PACK_TITLE_SCENE_H +#include + +#include + +//! @addtogroup rp_sports +//! @{ + +/** + * @brief Sports Pack title screen scene + */ +class RPSportsPackTitleScene : public RPUtlLoadSaveDataScene { +private: + struct UnkStruct { + u32 unk0; + u32 unk4; + u32 unk8; + + UnkStruct() : unk0(0), unk4(0), unk8(0) {} + }; + +private: + char unk44[0x54 - 0x44]; + UnkStruct unk60[(0x84 - 0x54) / sizeof(UnkStruct)]; + char unk84[0xA0 - 0x84]; +}; + +//! @} + +#endif diff --git a/include/Pack/RPSports/RPSportsCommon/RPSportsPhysicalMenuScene/RPSportsPhysicalMenuScene.h b/include/Pack/RPSports/RPSportsCommon/RPSportsPhysicalMenuScene/RPSportsPhysicalMenuScene.h new file mode 100644 index 000000000..3f7f323da --- /dev/null +++ b/include/Pack/RPSports/RPSportsCommon/RPSportsPhysicalMenuScene/RPSportsPhysicalMenuScene.h @@ -0,0 +1,19 @@ +#ifndef RP_SPORTS_COMMON_PHYSICAL_MENU_SCENE_H +#define RP_SPORTS_COMMON_PHYSICAL_MENU_SCENE_H +#include + +#include + +//! @addtogroup rp_sports +//! @{ + +/** + * @brief Sports Pack Wii Fitness menu scene + */ +class RPSportsPhysicalMenuScene : public RPSysScene { + char unk44[0x5C - 0x44]; +}; + +//! @} + +#endif diff --git a/include/Pack/RPSports/RPSportsCommon/RPSportsPhysicalPreviewScene/RPSportsPhysicalPreviewScene.h b/include/Pack/RPSports/RPSportsCommon/RPSportsPhysicalPreviewScene/RPSportsPhysicalPreviewScene.h new file mode 100644 index 000000000..db58d2567 --- /dev/null +++ b/include/Pack/RPSports/RPSportsCommon/RPSportsPhysicalPreviewScene/RPSportsPhysicalPreviewScene.h @@ -0,0 +1,19 @@ +#ifndef RP_SPORTS_COMMON_PHYSICAL_PREVIEW_SCENE_H +#define RP_SPORTS_COMMON_PHYSICAL_PREVIEW_SCENE_H +#include + +#include + +//! @addtogroup rp_sports +//! @{ + +/** + * @brief Sports Pack Wii Fitness game preview scene + */ +class RPSportsPhysicalPreviewScene : public RPSysScene { + char unk44[0x60 - 0x44]; +}; + +//! @} + +#endif diff --git a/include/Pack/RPSports/RPSportsCommon/RPSportsPhysicalResultScene/RPSportsPhysicalResultScene.h b/include/Pack/RPSports/RPSportsCommon/RPSportsPhysicalResultScene/RPSportsPhysicalResultScene.h new file mode 100644 index 000000000..a01bf689e --- /dev/null +++ b/include/Pack/RPSports/RPSportsCommon/RPSportsPhysicalResultScene/RPSportsPhysicalResultScene.h @@ -0,0 +1,19 @@ +#ifndef RP_SPORTS_COMMON_PHYSICAL_RESULT_SCENE_H +#define RP_SPORTS_COMMON_PHYSICAL_RESULT_SCENE_H +#include + +#include + +//! @addtogroup rp_sports +//! @{ + +/** + * @brief Sports Pack Wii Fitness results scene + */ +class RPSportsPhysicalResultScene : public RPSysScene { + char unk44[0x58 - 0x44]; +}; + +//! @} + +#endif diff --git a/include/Pack/RPSports/RPSportsCommon/RPSportsTrainingMenuScene/RPSportsTrainingMenuScene.h b/include/Pack/RPSports/RPSportsCommon/RPSportsTrainingMenuScene/RPSportsTrainingMenuScene.h new file mode 100644 index 000000000..417170f58 --- /dev/null +++ b/include/Pack/RPSports/RPSportsCommon/RPSportsTrainingMenuScene/RPSportsTrainingMenuScene.h @@ -0,0 +1,19 @@ +#ifndef RP_SPORTS_COMMON_TRAINING_MENU_SCENE_H +#define RP_SPORTS_COMMON_TRAINING_MENU_SCENE_H +#include + +#include + +//! @addtogroup rp_sports +//! @{ + +/** + * @brief Sports Pack training menu scene + */ +class RPSportsTrainingMenuScene : public RPSysScene { + char unk44[0x78 - 0x44]; +}; + +//! @} + +#endif diff --git a/include/Pack/RPSports/RPTnsScene.h b/include/Pack/RPSports/RPTnsScene.h new file mode 100644 index 000000000..e162e1220 --- /dev/null +++ b/include/Pack/RPSports/RPTnsScene.h @@ -0,0 +1,6 @@ +#ifndef RP_PUBLIC_SPORTS_TNS_H +#define RP_PUBLIC_SPORTS_TNS_H + +#include + +#endif diff --git a/include/Pack/RPSports/RPTnsScene/RPTnsScene.h b/include/Pack/RPSports/RPTnsScene/RPTnsScene.h new file mode 100644 index 000000000..6c3e37fe8 --- /dev/null +++ b/include/Pack/RPSports/RPTnsScene/RPTnsScene.h @@ -0,0 +1,20 @@ +#ifndef RP_SPORTS_TNS_SCENE_H +#define RP_SPORTS_TNS_SCENE_H +#include + +#include + +//! @addtogroup rp_tns +//! @{ + +/** + * @brief Sports Pack Tennis scene + */ +class RPTnsScene : public RPSportsBaseScene { +private: + char unk9C[0xA0 - 0x9C]; +}; + +//! @} + +#endif diff --git a/include/Pack/RPSystem.h b/include/Pack/RPSystem.h index 65aece802..d46be6880 100644 --- a/include/Pack/RPSystem.h +++ b/include/Pack/RPSystem.h @@ -5,19 +5,24 @@ #include #include #include +#include +#include #include #include #include +#include +#include #include #include +#include #include +#include #include #include #include #include #include #include -#include #include #endif diff --git a/include/Pack/RPSystem/RPSysBootScene.h b/include/Pack/RPSystem/RPSysBootScene.h new file mode 100644 index 000000000..56d051232 --- /dev/null +++ b/include/Pack/RPSystem/RPSysBootScene.h @@ -0,0 +1,20 @@ +#ifndef RP_SYSTEM_BOOT_SCENE_H +#define RP_SYSTEM_BOOT_SCENE_H +#include + +#include + +//! @addtogroup rp_system +//! @{ + +/** + * @brief Pack Project bootup scene + */ +class RPSysBootScene : public RPSysScene { +private: + char unk44[0x58 - 0x44]; +}; + +//! @} + +#endif diff --git a/include/Pack/RPSystem/RPSysCommonObject.h b/include/Pack/RPSystem/RPSysCommonObject.h new file mode 100644 index 000000000..c81dc6244 --- /dev/null +++ b/include/Pack/RPSystem/RPSysCommonObject.h @@ -0,0 +1,43 @@ +#ifndef RP_SYSTEM_COMMON_OBJECT_H +#define RP_SYSTEM_COMMON_OBJECT_H +#include + +#include + +//! @addtogroup rp_system +//! @{ + +/** + * @brief Encapsulates common object behavior/rendering + */ +class RPSysCommonObject : public IRPGrpDrawObject { +public: + /** + * @brief Constructor + */ + RPSysCommonObject(); + + /** + * @brief Renders common objects' state + */ + virtual void UserDraw() override; // at 0xC + + /** + * @brief Initializes common objects' state + */ + void init(); + + /** + * @brief Updates common objects' state before the scene gets to update + */ + void preUpdate(); + + /** + * @brief Updates common objects' state after the scene gets to update + */ + void postUpdate(); +}; + +//! @} + +#endif diff --git a/include/Pack/RPSystem/RPSysDvdStatus.h b/include/Pack/RPSystem/RPSysDvdStatus.h index 56ff36e5c..515b5a1b3 100644 --- a/include/Pack/RPSystem/RPSysDvdStatus.h +++ b/include/Pack/RPSystem/RPSysDvdStatus.h @@ -28,6 +28,12 @@ class RPSysDvdStatus { */ void draw(); + /** + * @brief Tests whether a disc drive error has occurred + * @typo + */ + bool isErrorOccured() const; + private: /** * @brief Disc drive error type @@ -50,13 +56,6 @@ class RPSysDvdStatus { //! Size of the error message buffer static const int MESSAGE_BUFFER_SIZE = 256; -private: - /** - * @brief Tests whether a disc drive error has occurred - * @typo - */ - bool isErrorOccured() const; - private: //! Game disc name static const char* GAME_DISK_NAME; diff --git a/include/Pack/RPSystem/RPSysNunchukCheckScene.h b/include/Pack/RPSystem/RPSysNunchukCheckScene.h new file mode 100644 index 000000000..9f948e1d3 --- /dev/null +++ b/include/Pack/RPSystem/RPSysNunchukCheckScene.h @@ -0,0 +1,21 @@ +#ifndef RP_SYSTEM_NUNCHUK_CHECK_SCENE_H +#define RP_SYSTEM_NUNCHUK_CHECK_SCENE_H +#include + +#include +#include + +//! @addtogroup rp_system +//! @{ + +/** + * @brief Pack Project Nunchuk check scene + */ +class RPSysNunchukCheckScene : public RPSysScene, public IRPSysHostIOSocket { +private: + char unk48[0x98 - 0x48]; +}; + +//! @} + +#endif diff --git a/include/Pack/RPSystem/RPSysPauseMgr.h b/include/Pack/RPSystem/RPSysPauseMgr.h new file mode 100644 index 000000000..cdea6ea64 --- /dev/null +++ b/include/Pack/RPSystem/RPSysPauseMgr.h @@ -0,0 +1,33 @@ +#ifndef RP_SYSTEM_PAUSE_MGR_H +#define RP_SYSTEM_PAUSE_MGR_H +#include + +#include +#include + +//! @addtogroup rp_system +//! @{ + +/** + * @brief Pause menu manager + */ +class RPSysPauseMgr { + RP_SINGLETON_DECL_EX(RPSysPauseMgr); + +public: + void init(); + void draw(); + bool isPause() const { + return mPause & 1; + } + +private: + BOOL mPause; + u32 mUNK_0x0C; + f32 mFloats_0x10[120]; + RPSysPauseMenu *mPauseMenu; +}; + +//! @} + +#endif diff --git a/include/Pack/RPSystem/RPSysPlayerSelectScene.h b/include/Pack/RPSystem/RPSysPlayerSelectScene.h new file mode 100644 index 000000000..6d6f1dc1b --- /dev/null +++ b/include/Pack/RPSystem/RPSysPlayerSelectScene.h @@ -0,0 +1,20 @@ +#ifndef RP_SYSTEM_PLAYER_SELECT_SCENE_H +#define RP_SYSTEM_PLAYER_SELECT_SCENE_H +#include + +#include + +//! @addtogroup rp_system +//! @{ + +/** + * @brief Pack Project player select scene + */ +class RPSysPlayerSelectScene : public RPSysScene { +private: + char unk44[0x8C - 0x44]; +}; + +//! @} + +#endif diff --git a/include/Pack/RPSystem/RPSysProjectLocal.h b/include/Pack/RPSystem/RPSysProjectLocal.h index f2ad93880..0b77da7d6 100644 --- a/include/Pack/RPSystem/RPSysProjectLocal.h +++ b/include/Pack/RPSystem/RPSysProjectLocal.h @@ -41,6 +41,14 @@ class RPSysProjectLocal { EArea_USA }; + /** + * @brief Target framerate + */ + enum EFrameRate { + EFrameRate_60Hz, //!< NTSC/PAL60 (60Hz) + EFrameRate_50Hz, //!< PAL50 (50Hz) + }; + /** * @brief Storage device */ @@ -105,10 +113,10 @@ class RPSysProjectLocal { } /** - * @brief Tests whether the game is expected to run at 50Hz + * @brief Gets the target framerate */ - bool isPal50() const { - return mIsPal50; + EFrameRate getFrameRate() const { + return mFrameRate; } /** @@ -127,8 +135,8 @@ class RPSysProjectLocal { EArea mLocale; // at 0x10 //! Game language EArea mLanguage; // at 0x14 - //! Whether the display is 50Hz - BOOL mIsPal50; // at 0x18 + //! Target framerate + EFrameRate mFrameRate; // at 0x18 //! Sound archive storage device EStorage mSoundStorage; // at 0x1C }; diff --git a/include/Pack/RPSystem/RPSysRenderMode.h b/include/Pack/RPSystem/RPSysRenderMode.h new file mode 100644 index 000000000..fe2b0d34b --- /dev/null +++ b/include/Pack/RPSystem/RPSysRenderMode.h @@ -0,0 +1,56 @@ +#ifndef RP_SYSTEM_RENDER_MODE_H +#define RP_SYSTEM_RENDER_MODE_H +#include + +#include + +//! @addtogroup rp_system +//! @{ + +/** + * @brief Render mode utilities + */ +class RPSysRenderMode { +public: + /** + * @brief Render mode formats + */ + enum EFormat { + EFormat_Ntsc, //!< NTSC + EFormat_NtscProg, //!< NTSC, Progressive Mode + + EFormat_Pal50, //!< PAL, 50Hz ("EuRgb50") + EFormat_Pal60, //!< PAL, 60Hz ("EuRgb60") + EFormat_PalProg, //!< PAL, Progressive Mode + + EFormat_Max + }; + +public: + /** + * @brief Gets the render mode for the specified format + * + * @param format Render mode format + */ + static GXRenderModeObj* getRenderMode(EFormat format) { + return spRenderModeTable[format]; + } + + /** + * @brief Adjusts a render mode to account for widescreen/50Hz formats + * + * @param pOriginX Pointer to render mode viXOrigin + * @param pWidth Pointer to render mode viWidth + * @param format Render mode format + * @param wide Whether the display is widescreen + */ + static void adjust(u16* pOriginX, u16* pWidth, EFormat format, bool wide); + +private: + //! Render mode configurations + static GXRenderModeObj* const spRenderModeTable[EFormat_Max]; +}; + +//! @} + +#endif diff --git a/include/Pack/RPSystem/RPSysResourceManager.h b/include/Pack/RPSystem/RPSysResourceManager.h index 430fc1cf8..9b874b8e8 100644 --- a/include/Pack/RPSystem/RPSysResourceManager.h +++ b/include/Pack/RPSystem/RPSysResourceManager.h @@ -3,7 +3,7 @@ #include #include -#include +#include #include #include @@ -237,6 +237,13 @@ class RPSysResourceManager { return mpStaticLocalArchive; } + /** + * @brief Gets the archive containing static layout assets for this pack + */ + EGG::Archive* GetStaticLayoutArchive() const { + return mpStaticLayoutArchive; + } + /** * @brief Gets the extra handle for opening files outside the DVD */ diff --git a/include/Pack/RPSystem/RPSysScene.h b/include/Pack/RPSystem/RPSysScene.h index c2e47ce67..cc5573659 100644 --- a/include/Pack/RPSystem/RPSysScene.h +++ b/include/Pack/RPSystem/RPSysScene.h @@ -2,17 +2,320 @@ #define RP_SYSTEM_SCENE_H #include +#include +#include + #include //! @addtogroup rp_system //! @{ +// Forward declarations +class RPSysCommonObject; + /** * @brief Pack Project scene */ -class RPSysScene : public EGG::Scene { +class RPSysScene : public EGG::Scene, public IRPGrpDrawObject { + friend class RPSysSceneCreator; + public: + struct UnkStruct { + u32 unk0; + UnkStruct() : unk0(0) {} + }; + +public: + /** + * @brief Constructor + */ + RPSysScene(); + + /** + * @name Internal events + * @brief These functions are internal, and should not be overriden. + */ + /**@{*/ + /** + * @brief Updates the scene state + */ + virtual void calc() override; // at 0xC + + /** + * @brief Renders the scene state + */ + virtual void draw() override; // at 0x10 + + /** + * @brief Enters the scene + */ + virtual void enter() override; // at 0x14 + + /** + * @brief Exits the scene + */ + virtual void exit() override; // at 0x18 + + /** + * @brief Re-initializes the scene + */ + virtual void reinit() override; // at 0x1C + + /** + * @brief Prepares for destruction of (and transition from) a child scene + */ + virtual void incoming_childDestroy() override; // at 0x20 + + /** + * @brief Prepares for creation of (and transition to) a child scene + */ + virtual void outgoing_childCreate() override; // at 0x24 + /**@}*/ + + /** + * @name Lifecycle hooks + * @brief These functions are mostly empty stubs, and should be overridden + * to provide scene functionality. + */ + /**@{*/ + virtual UnkStruct& VF_0x3C() { + return sUnkStruct; + } // at 0x3C + + /** + * @brief Pause callback + * + * @param enter Whether the pause menu is being entered + */ + virtual void pauseCallBack(bool /* enter */) {} // at 0x40 + + /** + * @brief Initializes the scene's state for the first time + */ + virtual void Configure() {} // at 0x44 + + /** + * @brief Loads the scene's required assets + */ + virtual void LoadResource() {} // at 0x48 + + /** + * @brief Re-initializes the scene's state + */ + virtual void Reset() {} // at 0x4C + + /** + * @brief Updates the scene's state + */ + virtual void Calculate() {} // at 0x50 + + /** + * @brief Exits the scene + */ + virtual void Exit() {} // at 0x54 + + /** + * @brief Runs an asynchronous task on the DVD thread + */ + virtual void taskAsync() {} // at 0x58 + /**@}*/ + + /** + * @brief Tests whether the scene is fully visible + */ + bool isSceneDisplay() const; + + /** + * @brief Tests whether the scene is visibly obscured + */ + bool isSceneBlank() const; + + /** + * @brief Tests whether a scene change would be allowed + */ + bool isSceneChangeEnable() const; + + /** + * @brief Tests whether NAND access would be safe + */ bool isNandAccessEnable() const; + + /** + * @brief Sets the duration of all faders + * + * @param frame Fade duration, in frames + */ + void setFadeFrame(u16 frame); + + /** + * @brief Gets the color of the manager fader + */ + nw4r::ut::Color getFadeColor() const; + + /** + * @brief Sets the color of all faders + * + * @param color Fade color + */ + void setFadeColor(nw4r::ut::Color color); + + /** + * @brief Sets the color of the scene fader + * + * @param color Fade color + */ + void setSceneFadeColor(nw4r::ut::Color color); + + /** + * @brief Begins fading in the scene fader + * + * @return Success + */ + bool startFadeIn(); + + /** + * @brief Begins fading out the scene fader + * + * @return Success + */ + bool startFadeOut(); + + /** + * @brief Toggles screen dimming + * @note If "Screen Saver Mode" is disabled, dimming is always OFF. + * + * @param enable Whether to dim the screen + */ + void setDimming(bool enable); + + /** + * @brief Sets this scene's parent/creator ID + * + * @param id ID of this scene's parent/creator + */ + void setCreatorSceneID(s32 id); + + /** + * @brief Gets this scene's parent/creator ID + */ + s32 getCreatorSceneID() const; + + /** + * @brief Marks this scene as a child of the previous scene + */ + void setChildScene(); + + /** + * @brief Displays the game's build date timestamp + * + * @param color Text color + */ + void drawTimeStamp(nw4r::ut::Color color); + + /** + * @brief Marks that this scene requires an asynchronous task + */ + void setTaskAsync(); + + /** + * @brief Tests whether this scene's asynchronous task has finished + */ + bool isTaskAsyncFinish() const; + +private: + /** + * @brief Prepares this scene to be entered + */ + DECOMP_INLINE void incomingScene(); + + /** + * @brief Prepares this scene to be exited + */ + void outgoingScene(); + + /** + * @brief Finalizes this scene after being exited + */ + void exitScenePost(); + + /** + * @brief Initializes this scene's members + */ + void init(); + + void loadUpdate(); + + /** + * @brief Creates the asynchronous task thread if requested by the scene + */ + void initTaskAsync(); + + /** + * @brief Enables the "Now Loading" message display + */ + void enableLoadMessage(); + + /** + * @brief Loads this scene's resources asynchronously + */ + void load(); + + /** + * @brief Loads this scene's resources asynchronously, displaying a "Now + * Loading" message if the feature is enabled + */ + void loadMessage(); + + /** + * @brief Polls the status of the DVD task thread + */ + void updateDvdEndMessage(); + + /** + * @brief Polls the status of the NAND task thread + */ + void updateNandEndMessage(); + + /** + * @brief Thread function for the LoadResource phase + * + * @param pArg Thread function argument + */ + static void loadResourceFunc(void* pArg); + + /** + * @brief Thread function for the scene's task + * + * @param pArg Thread function argument + */ + static void taskAsyncFunc(void* pArg); + +private: + /** + * @brief Scene flags + */ + enum { + EFlag_LoadMessage, //!< Display "Now Loading" message + EFlag_TaskAsyncSet, //!< The scene requested an asynchronous task + EFlag_TaskAsyncRunning, //!< The asynchronous task is running + EFlag_IsChild, //!< This scene was created as a child + }; + +private: + static UnkStruct sUnkStruct; + + //! Scene renderer + RPGrpRenderer* mpRenderer; // at 0x2C + //! Common draw functionality + RPSysCommonObject* mpCommonObject; // at 0x30 + //! Scene effect creator + RPSysEffectCreator* mpEffectCreator; // at 0x34 + //! Scene heap + EGG::Heap* mpSceneHeap; // at 0x38 + //! Scene flags + EGG::TBitFlag mFlags; // at 0x3C + //! ID of the previous scene + s32 mCreatorSceneID; // at 0x40 }; //! @} diff --git a/include/Pack/RPSystem/RPSysSceneCreator.h b/include/Pack/RPSystem/RPSysSceneCreator.h index be7028d22..d2444a526 100644 --- a/include/Pack/RPSystem/RPSysSceneCreator.h +++ b/include/Pack/RPSystem/RPSysSceneCreator.h @@ -9,21 +9,24 @@ //! @addtogroup rp_system //! @{ +// Forward declarations +class RPSysScene; + /** - * @brief Scene factory + * @brief Pack Project scene factory */ class RPSysSceneCreator : public EGG::SceneCreator { RP_SINGLETON_DECL_EX(RPSysSceneCreator); public: /** - * @brief Game scene ID + * @brief Pack Project scene ID */ enum ESceneID { // RPSystem ESceneID_RPSysBootScene, //!< Logo ESceneID_RPSysPlayerSelectScene, //!< Player Select - ESceneID_RPSysNunchukScene, //!< Nunchuk Check + ESceneID_RPSysNunchukCheckScene, //!< Nunchuk Check // RPSports ESceneID_RPBsbScene, //!< Baseball @@ -31,13 +34,13 @@ class RPSysSceneCreator : public EGG::SceneCreator { ESceneID_RPGolScene, //!< Golf ESceneID_RPTnsScene, //!< Tennis ESceneID_RPBoxScene, //!< Boxing - ESceneID_RPSportsTitleScene, //!< Sports Pack - ESceneID_RPSportsMenuScene, //!< Main Menu + ESceneID_RPSportsPackTitleScene, //!< Sports Pack + ESceneID_RPSportsMainScene, //!< Main Menu ESceneID_RPSportsTrainingMenuScene, //!< Training Menu ESceneID_RPSportsPhysicalMenuScene, //!< Physical Test (Menu) ESceneID_RPSportsPhysicalPreviewScene, //!< Physical Test (Description) ESceneID_RPSportsPhysicalResultScene, //!< Physical Test (Result) - ESceneID_RPGolSelectScene, //!< Golf (Course Select) + ESceneID_RPGolCourseSelectScene, //!< Golf (Course Select) #if defined(PACK_SPORTS) ESceneID_Max, @@ -45,23 +48,26 @@ class RPSysSceneCreator : public EGG::SceneCreator { // RPParty ESceneID_Unknown09h, - ESceneID_RPFshScene, //!< Fishing - ESceneID_RPHkyScene, //!< Laser Hockey - ESceneID_RPDucScene, //!< Shooting Range - ESceneID_RPPnpScene, //!< Table Tennis - ESceneID_RPBilScene, //!< Billiards - ESceneID_RPCowScene, //!< Charge! - ESceneID_RPWlyScene, //!< Find Mii - ESceneID_RPTnkScene, //!< Tanks! - ESceneID_RPBomScene, //!< Pose Mii - ESceneID_RPPartyTitleScene, //!< Party Pack - ESceneID_RPPartyMiiLoadScene, //!< Mii/GameMgr Setup - ESceneID_RPPartyMenuScene, //!< Main Menu + ESceneID_RPFshScene, //!< Fishing + ESceneID_RPHkyScene, //!< Laser Hockey + ESceneID_RPDucScene, //!< Shooting Range + ESceneID_RPPnpScene, //!< Table Tennis + ESceneID_RPBilScene, //!< Billiards + ESceneID_RPCowScene, //!< Charge! + ESceneID_RPWlyScene, //!< Find Mii + ESceneID_RPTnkScene, //!< Tanks! + ESceneID_RPBomScene, //!< Pose Mii + ESceneID_RPPartyPackTitleScene, //!< Party Pack + ESceneID_RPPartyRootScene, //!< Mii/GameMgr Setup + ESceneID_RPPartyMainScene, //!< Main Menu #if defined(PACK_PARTY) ESceneID_Max, #endif + // During the development of Wii Sports and Wii Play, + // Wii Fit and Wii Music were very early in development. +#if defined(PACK_SPORTS) || defined(PACK_PARTY) // RPHealth ESceneID_RPHealthTitleScene, //!< Health Pack ESceneID_RPHealthCounselScene, //!< Counseling @@ -100,19 +106,7 @@ class RPSysSceneCreator : public EGG::SceneCreator { ESceneID_RPDrmDebugScene, //!< Drum Debug ESceneID_RPOchDebugScene, //!< Orchestra Debug ESceneID_RPOchSelectScene, //!< Orchestra Music Select - }; - - /** - * @brief Sport ID - */ - enum ESportID { - ESportID_Bsb, //!< Baseball - ESportID_Tns, //!< Tennis - ESportID_Gol, //!< Golf - ESportID_Box, //!< Boxing - ESportID_Bow, //!< Bowling - - ESportID_Max +#endif }; /** @@ -137,6 +131,14 @@ class RPSysSceneCreator : public EGG::SceneCreator { ECreateType_Child, //!< Become child of outgoing scene }; + /** + * @brief Scene load type + */ + enum ELoadType { + ELoadType_Blank, //!< No additional display + ELoadType_Message, //!< Display "Now Loading" message + }; + /** * @brief Scene exit type */ @@ -149,126 +151,194 @@ class RPSysSceneCreator : public EGG::SceneCreator { }; /** - * @brief Scene information + * @brief Scene audio type + */ + enum EAudioType { + EAudioType_Scene, //!< Use the scene's sound archive + EAudioType_Common, //!< Use the common sound archive + }; + + /** + * @brief Sport ID + */ + enum ESportID { + ESportID_Bsb, //!< Baseball + ESportID_Tns, //!< Tennis + ESportID_Gol, //!< Golf + ESportID_Box, //!< Boxing + ESportID_Bow, //!< Bowling + + ESportID_Max, + }; + + /** + * @brief Scene attributes */ - struct SceneEntry { + struct SceneAttr { //! Scene ID ESceneID scene; // at 0x0 //! Pack ID EPackID pack; // at 0x4 + //! How to create the scene ECreateType createType; // at 0x8 - //! Toggle "Now Loading" text (unused) - BOOL loadingText; // at 0xC + //! How to load the scene + ELoadType loadType; // at 0xC //! How to exit the scene EExitType exitType; // at 0x10 - //! Whether to use the RP common sound archive - BOOL commonSound; // at 0x14 - //! Scene resource directory + //! How to configure the scene audio + EAudioType audioType; // at 0x14 + + //! Root resource directory const char* pResDirName; // at 0x18 - //! Proper name + //! Readable name const char* pSceneName; // at 0x1C }; public: /** - * @brief Creates a scene by ID + * @brief Creates the specified scene * * @param id Scene ID */ virtual EGG::Scene* create(s32 id); // at 0x8 + /** - * @brief Destroys a scene - * @remark If the scene manager has requested a shutdown, this function will - * tell the system to shutdown. + * @brief Destroys the specified scene * - * @param id ID of the scene being destroyed + * @param id Scene ID */ virtual void destroy(s32 id); // at 0xC -#if defined(PACK_SPORTS) /** - * @brief Creates a Sports Pack scene by ID + * @brief Requests a scene change after fading out + * @details A scene id of -1 will select the current scene. + * + * @param id New scene ID + * @param reconfigure Whether to fully reconfigure the scene + * @return Success + */ + bool changeSceneAfterFade(s32 id, bool reconfigure = false) + DECOMP_DONT_INLINE; + + /** + * @brief Changes to the title scene + * + * @return Success + */ + bool changeSoftReset(); + + /** + * @brief Gets the specified scene's resource directory + * @details A scene id of -1 will select the current scene. * * @param id Scene ID */ - EGG::Scene* createSportsScene(s32 id); -#elif defined(PACK_PARTY) + const char* getResDirName(s32 id = -1); + /** - * @brief Creates a Party Pack scene by ID + * @brief Gets the specified scene's sport ID + * @details A scene id of -1 will select the current scene. + * @note If no sport corresponds to the scene, this function returns -1. * * @param id Scene ID */ - EGG::Scene* createPartyScene(s32 id); -#endif + s32 getSportID(s32 id = -1); /** - * @brief Fades out the current scene and changes to a new scene - * @note Supply an ID of -1 to use the ID of the current scene + * @brief Gets the specified sport's scene ID + * @note If no scene corresponds to the sport, this function returns -1. * - * @param id New scene ID (-1 for current scene) - * @param reload Whether to reload the current scene - * @return Success + * @param sport Sport ID */ - bool changeSceneAfterFade(s32 id, bool reload = false); + s32 getSceneID(ESportID sport); + /** - * @brief Changes to the boot scene (performs a soft reset) + * @brief Gets the specified scene's pack ID + * + * @param id Scene ID */ - void changeSoftReset(); + EPackID getPackID(s32 id); /** - * @brief Gets the scene's resource directory + * @brief Gets the specified scene's creation type * - * @param id Scene ID (-1 to use the current scene) + * @param id Scene ID */ - const char* getResDirName(s32 id = -1); + ECreateType getCreateType(s32 id); -#if defined(PACK_SPORTS) /** - * @brief Gets the sport corresponding to the scene ID - * @note If the specified scene has no entry, this function returns -1. + * @brief Gets the specified scene's load type * - * @param id Scene ID (-1 to use the current scene) + * @param id Scene ID */ - s32 getSportID(s32 id = -1); -#endif + ELoadType getLoadType(s32 id); /** - * @brief Gets the scene ID corresponding to the sport - * @note If the specified sport has no entry, this function returns -1. + * @brief Gets the specified scene's exit type * - * @param sport Sport ID + * @param id Scene ID */ - s32 getSceneID(ESportID sport); + EExitType getExitType(s32 id); /** - * @brief Gets the scene's create logic type + * @brief Gets the specified scene's audio type * - * @param id Scene ID (-1 to use the current scene) + * @param id Scene ID */ - s32 getCreateType(s32 id = -1); + EAudioType getAudioType(s32 id); +private: /** - * @brief Gets the scene's exit logic type + * @brief Gets the index of the specified scene's entry in the table * - * @param id Scene ID (-1 to use the current scene) + * @param id Scene ID + * @return Entry index, or -1 if not found */ - s32 getExitType(s32 id = -1); + s32 getEntryIndex(ESceneID id); +#if defined(PACK_SPORTS) /** - * @brief Tests whether the scene should use the pack's common sound - * archive. + * @brief Creates the specified Sports Pack scene * - * @param id Scene ID (-1 to use the current scene) + * @param id Scene ID + */ + RPSysScene* createSportsScene(s32 id) DECOMP_DONT_INLINE; +#endif + +#if defined(PACK_PARTY) + /** + * @brief Creates the specified Party Pack scene + * + * @param id Scene ID */ - bool isCommonSound(s32 id = -1); + RPSysScene* createPartyScene(s32 id) DECOMP_DONT_INLINE; +#endif + +#if defined(PACK_HEALTH) + /** + * @brief Creates the specified Health Pack scene + * + * @param id Scene ID + */ + RPSysScene* createHealthScene(s32 id) DECOMP_DONT_INLINE; +#endif + +#if defined(PACK_MUSIC) + /** + * @brief Creates the specified Music Pack scene + * + * @param id Scene ID + */ + RPSysScene* createMusicScene(s32 id) DECOMP_DONT_INLINE; +#endif private: - //! ID of the previous scene - s32 mLastSceneID; // at 0x8 + //! Information about every Pack Project scene + static const SceneAttr SCENE_ATTR_TABLE[]; - //! Entries for all Pack Project scenes - static SceneEntry sSceneEntryTable[]; + //! ID of the previous scene + s32 mPrevSceneID; // at 0x8 }; //! @} diff --git a/include/Pack/RPSystem/RPSysSceneMgr.h b/include/Pack/RPSystem/RPSysSceneMgr.h index 183e5c6e6..ce4c9f75b 100644 --- a/include/Pack/RPSystem/RPSysSceneMgr.h +++ b/include/Pack/RPSystem/RPSysSceneMgr.h @@ -7,22 +7,237 @@ #include +#include + //! @addtogroup rp_system //! @{ /** - * @brief Scene manager + * @brief Pack Project scene manager */ class RPSysSceneMgr : public EGG::SceneManager { - RP_SINGLETON_DECL(RPSysSceneMgr); + RP_SINGLETON_DECL_EX(RPSysSceneMgr); public: - bool isShutDownReserved() const; - bool isDvdErrorApplicationEnd() const; + /** + * @brief Updates the state of the current scene + */ + virtual void calcCurrentScene() override; // at 0x10 + /** + * @brief Gets the currently active scene as the Pack Project type + */ RPSysScene* getCurrentSceneRP() const; - void returnToMenu(bool); + /** + * @brief Performs a soft reset + * + * @param fromHBM Whether the request came from HBM + * @return Success + */ + bool softReset(bool fromHBM); + + /** + * @brief Returns to the IPL + * + * @param fromHBM Whether the request came from HBM + * @return Success + */ + bool returnToMenu(bool fromHBM); + + /** + * @brief Powers off the console + * + * @param fromHBM Whether the request came from HBM + * @return Success + */ + bool shutdownSystem(bool fromHBM); + + /** + * @brief Tests whether this manager is operating normally + */ + bool isNormalState() const; + + /** + * @brief Tests whether this manager is currently shutting down the system + */ + bool isShutDownReserved() const; + + /** + * @brief Tests whether this manager is currently returning to the IPL + */ + bool getReturnToMenu() const; + + /** + * @brief Disables the guard state and returns to normal operation + */ + void resetGuard(); + + /** + * @brief Tests whether this manager is currently exiting the program + */ + bool isApplicationEndReserved(); + + /** + * @brief Tests whether a DVD error should exit the program + */ + bool isDvdErrorApplicationEnd(); + + /** + * @brief Requests a scene change after fading out + * @details A scene id of -1 will select the current scene. + * + * @param id New scene ID + * @param reconfigure Whether to fully reconfigure the scene + * @return Success + */ + bool changeNextSceneAfterFade(s32 id, bool reconfigure = false); + + /** + * @brief Resets the duration of all faders + */ + void resetFadeFrame(); + + /** + * @brief Gets the duration of the scene fader + */ + u16 getFadeFrame(); + + /** + * @brief Sets the duration of all faders + * + * @param frame Fade duration, in frames + */ + void setFadeFrame(u16 frame); + + /** + * @brief Resets the color of all faders + * @details The default fader color is black. + */ + void resetFadeColor(); + + /** + * @brief Gets the color of the manager fader + */ + nw4r::ut::Color getFadeColor(); + + /** + * @brief Sets the color of all faders + * + * @param color Fade color + */ + void setFadeColor(nw4r::ut::Color color); + + /** + * @brief Sets the color of the scene fader + * + * @param color Fade color + */ + void setSceneFadeColor(nw4r::ut::Color color); + + /** + * @brief Gets the status of the scene fader + */ + EGG::Fader::EStatus getSceneStatus(); + + /** + * @brief Sets the status of the scene fader + * + * @param status Fade status + */ + void setSceneStatus(EGG::Fader::EStatus status); + + /** + * @brief Begins fading in the manager fader + * + * @return Success + */ + bool startMgrFadeIn(); + + /** + * @brief Begins fading in the scene fader + * + * @return Success + */ + bool startSceneFadeIn(); + + /** + * @brief Begins fading out the scene fader + * + * @return Success + */ + bool startSceneFadeOut(); + + /** + * @brief Tests whether the scene is fully visible + */ + bool isDisplay(); + + /** + * @brief Tests whether the scene is visibly obscured + */ + bool isBlank(); + + /** + * @brief Tests whether the scene is fading out + */ + bool isFadeOut(); + + /** + * @brief Tests whether all asynchronous tasks have finished + */ + bool isTaskFinished(); + + /** + * @brief Tests whether a scene change would be allowed + */ + bool isSceneChangeEnable(); + + /** + * @brief Updates the state of the scene fader + * + * @return Whether the fade has finished + */ + bool calcSceneFader(); + + /** + * @brief Displays the state of the scene fader + */ + void drawSceneFader(); + + /** + * @brief Displays the state of the manager fader + */ + void drawMgrFader(); + + /** + * @brief Updates the state of this manager + */ + void updateState(); + +private: + /** + * @brief Scene manager state + */ + enum EState { + EState_Normal, //!< Normal operation + EState_Guard, //!< Prevents operations during soft reset + EState_SoftReset, //!< Perform soft reset + EState_ReturnToMenu, //!< Return to system menu + EState_Shutdown //!< Shutdown the system + }; + + //! The default fade duration, in frames + static const int DEFAULT_FADE_FRAME = 20; + + //! The default fade color + static const u32 DEFAULT_FADE_COLOR = nw4r::ut::Color::BLACK; + +private: + //! Manager state + EState mState; // at 0x30 + //! Fader usable by the current scene + EGG::ColorFader* mpSceneFader; // at 0x34 }; //! @} diff --git a/include/Pack/RPUtility.h b/include/Pack/RPUtility.h index 2044045db..9ba493ab3 100644 --- a/include/Pack/RPUtility.h +++ b/include/Pack/RPUtility.h @@ -1,6 +1,8 @@ #ifndef RP_PUBLIC_UTILITY_H #define RP_PUBLIC_UTILITY_H +#include +#include #include #endif diff --git a/include/Pack/RPUtility/RPUtlDohMath.h b/include/Pack/RPUtility/RPUtlDohMath.h new file mode 100644 index 000000000..37d63cd74 --- /dev/null +++ b/include/Pack/RPUtility/RPUtlDohMath.h @@ -0,0 +1,106 @@ +#ifndef RP_UTILITY_DOH_MATH_H +#define RP_UTILITY_DOH_MATH_H +#include + +#include + +/** + * @brief Dohta's math utilities + */ +class RPUtlDohMath { +public: + /** + * @brief Axis priority order during orthonormalization + */ + enum AxisOrder { + AxisOrder_XY, //! X-axis is preserved, Y-axis is the reference + AxisOrder_XZ, //! X-axis is preserved, Z-axis is the reference + + AxisOrder_YZ, //! Y-axis is preserved, Z-axis is the reference + AxisOrder_YX, //! Y-axis is preserved, X-axis is the reference + + AxisOrder_ZX, //! Z-axis is preserved, X-axis is the reference + AxisOrder_ZY, //! Z-axis is preserved, Y-axis is the reference + }; + + /** + * @brief Matrix axis index + */ + enum AxisType { + AxisType_X, //! X-axis + AxisType_Y, //! Y-axis + AxisType_Z, //! Z-axis + }; + +public: + /** + * @brief Sets the specified local axis of the input matrix + * + * @param pMtx Matrix + * @param axis Axis index + * @param pBase Base vector + */ + static void MTX34SetBase(nw4r::math::MTX34* pMtx, AxisType axis, + const nw4r::math::VEC3* pBase); + + /** + * @brief Constructs a right-handed orthonormal basis from the local axes of + * the specified matrix + * + * @param[out] pOut Output matrix + * @param pIn Input matrix + * @param order Axis priority order + */ + static void MTX34Normalize(nw4r::math::MTX34* pOut, + const nw4r::math::MTX34* pIn, AxisOrder order); + + /** + * @brief Calculates a bend point between two endpoints + * + * @param[out] pMidPoint Bend point + * @param[out] pDistance Distance between the endpoints + * @param rBendDir Bend direction vector + * @param rPointA Endpoint A + * @param rPointB Endpoint B + * @param lengthA Length of the segment from A to the bend joint + * @param lengthB Length of the segment from the bend joint to B + */ + static void GetMidPoint(nw4r::math::VEC3* pMidPoint, f32* pDistance, + const nw4r::math::VEC3& rBendDir, + const nw4r::math::VEC3& rPointA, + const nw4r::math::VEC3& rPointB, f32 lengthA, + f32 lengthB); + +public: + //! Zero vector (3D) + static const nw4r::math::VEC3 VEC3_ZERO; + //! Zero vector (2D) + static const nw4r::math::VEC2 VEC2_ZERO; + + //! Positive X-axis unit vector + static const nw4r::math::VEC3 AXIS_XP; + //! Negative X-axis unit vector + static const nw4r::math::VEC3 AXIS_XN; + + //! Positive Y-axis unit vector + static const nw4r::math::VEC3 AXIS_YP; + //! Negative Y-axis unit vector + static const nw4r::math::VEC3 AXIS_YN; + + //! Positive Z-axis unit vector + static const nw4r::math::VEC3 AXIS_ZP; + //! Negative Z-axis unit vector + static const nw4r::math::VEC3 AXIS_ZN; + + //! 3x4 identity matrix + static const nw4r::math::MTX34 MTX34_IDENT; + //! 3x3 identity matrix + static const nw4r::math::MTX33 MTX33_IDENT; + //! Identity quaternion + static const nw4r::math::QUAT QUAT_IDENT; + + //! Float close to zero for tolerance checks + static const f32 FLOAT_EPSILON; +}; + +#endif diff --git a/include/Pack/RPUtility/RPUtlLoadSaveDataScene.h b/include/Pack/RPUtility/RPUtlLoadSaveDataScene.h new file mode 100644 index 000000000..10e1032b1 --- /dev/null +++ b/include/Pack/RPUtility/RPUtlLoadSaveDataScene.h @@ -0,0 +1,14 @@ +#ifndef RP_UTILITY_LOAD_SAVE_DATA_SCENE_H +#define RP_UTILITY_LOAD_SAVE_DATA_SCENE_H +#include + +#include + +/** + * @brief Base class for scenes which need to load the save file + */ +class RPUtlLoadSaveDataScene : public RPSysScene { +public: +}; + +#endif diff --git a/include/Pack/types_pack.h b/include/Pack/types_pack.h index 89a36115b..dcef502b9 100644 --- a/include/Pack/types_pack.h +++ b/include/Pack/types_pack.h @@ -37,6 +37,18 @@ typedef u32 RPTime32; #define RP_MAX_PLAYERS RP_MUSIC_MAX_PLAYERS #endif +/** + * List for-each macro. + * + * @param TYPE Element type + * @param NAME Element name + * @param LIST Reference to list + */ +#define RP_NW4R_LIST_FOREACH(TYPE, NAME, LIST) \ + for (TYPE* NAME = static_cast(nw4r::ut::List_GetFirst(&LIST)); \ + NAME != NULL; \ + NAME = static_cast(nw4r::ut::List_GetNext(&LIST, NAME))) + /** * @brief Generic BMG message holder */ diff --git a/include/PartyPack.pch b/include/PartyPack.pch new file mode 100644 index 000000000..01b1572ab --- /dev/null +++ b/include/PartyPack.pch @@ -0,0 +1,6 @@ +#ifndef RP_PARTY_PACK_PRECOMPILED_HEADER +#define RP_PARTY_PACK_PRECOMPILED_HEADER + +#include + +#endif diff --git a/include/SportsPack.pch b/include/SportsPack.pch new file mode 100644 index 000000000..f91f314e7 --- /dev/null +++ b/include/SportsPack.pch @@ -0,0 +1,6 @@ +#ifndef RP_SPORTS_PACK_PRECOMPILED_HEADER +#define RP_SPORTS_PACK_PRECOMPILED_HEADER + +#include + +#endif diff --git a/include/__doxygen.hpp b/include/decomp/__doxygen.hpp similarity index 100% rename from include/__doxygen.hpp rename to include/decomp/__doxygen.hpp diff --git a/include/compat.h b/include/decomp/compat.h similarity index 100% rename from include/compat.h rename to include/decomp/compat.h diff --git a/include/decomp.h b/include/decomp/decomp.h similarity index 100% rename from include/decomp.h rename to include/decomp/decomp.h diff --git a/include/lang.h b/include/decomp/lang.h similarity index 100% rename from include/lang.h rename to include/decomp/lang.h diff --git a/include/egg/core/eggColorFader.h b/include/egg/core/eggColorFader.h index 2cb917d5d..fc30d8eee 100644 --- a/include/egg/core/eggColorFader.h +++ b/include/egg/core/eggColorFader.h @@ -28,7 +28,14 @@ class ColorFader : public Fader { virtual bool calc(); // at 0x18 virtual void draw(); // at 0x1C + u16 getFrame() const { + return mFadeFrame; + } void setFrame(u16 frame); + + nw4r::ut::Color getColor() const { + return mColor; + } void setColor(nw4r::ut::Color color); private: diff --git a/include/egg/core/eggDisplay.h b/include/egg/core/eggDisplay.h index b5c6e325e..db73c67bf 100644 --- a/include/egg/core/eggDisplay.h +++ b/include/egg/core/eggDisplay.h @@ -58,7 +58,7 @@ class Display { u32 mRetraceCount; // at 0xC u32 mFrameCount; // at 0x10 nw4r::ut::Color mClearColor; // at 0x14 - u32 mClearZ; // at 0x20 + u32 mClearZ; // at 0x18 s32 mPrevFrameTick; // at 0x1C s32 mFrameCostTick; // at 0x20 f32 mFrequency; // at 0x24 diff --git a/include/egg/core/eggSceneManager.h b/include/egg/core/eggSceneManager.h index 888c372e8..4ff05835d 100644 --- a/include/egg/core/eggSceneManager.h +++ b/include/egg/core/eggSceneManager.h @@ -5,7 +5,7 @@ namespace EGG { // Forward declarations -class Fader; +class ColorFader; class Heap; class SceneCreator; @@ -106,7 +106,7 @@ class SceneManager { mAfterFadeType = AFTER_FADE_TYPE_NONE; } -private: +protected: SceneCreator* mSceneCreator; // at 0x4 char UNK_0x8[0xC - 0x8]; // at 0x8 Scene* mCurrentScene; // at 0xC @@ -115,7 +115,7 @@ class SceneManager { s32 mCurrentSceneID; // at 0x18 s32 mPreviousSceneID; // at 0x1C eAfterFadeType mAfterFadeType; // at 0x20 - Fader* mCurrentFader; // at 0x24 + ColorFader* mCurrentFader; // at 0x24 eRootHeapType mRootHeapType; // at 0x28 static u16 sHeapOptionFlg; diff --git a/include/egg/core/eggTaskThread.h b/include/egg/core/eggTaskThread.h index d64c8e7d0..2134dc5fa 100644 --- a/include/egg/core/eggTaskThread.h +++ b/include/egg/core/eggTaskThread.h @@ -54,9 +54,13 @@ class TaskThread : public Thread { return mCurrentJob != NULL; } + OSMessageQueue* getEndMessageQueue() const { + return mEndMesgQueue; + } void setEndMessageQueue(OSMessageQueue* pQueue) { mEndMesgQueue = pQueue; } + OSMessage waitTaskEndMessage(BOOL* pSuccess) { OSMessage msg; *pSuccess = OSReceiveMessage(mEndMesgQueue, &msg, 0); diff --git a/include/egg/math/eggMath.h b/include/egg/math/eggMath.h index 2f3adbefc..67c35c51d 100644 --- a/include/egg/math/eggMath.h +++ b/include/egg/math/eggMath.h @@ -16,6 +16,9 @@ template class Math { static T zero() { return static_cast(0); } + static T epsilon() { + return static_cast(FLT_EPSILON); + } static T pi() { return static_cast(M_PI); @@ -49,6 +52,9 @@ template class Math { } }; +typedef Math Mathi; +typedef Math Mathf; + } // namespace EGG #endif diff --git a/include/homebuttonMiniLib/HBMTypes.h b/include/homebuttonMiniLib/HBMTypes.h index 8ac2a0cf7..f0366c95e 100644 --- a/include/homebuttonMiniLib/HBMTypes.h +++ b/include/homebuttonMiniLib/HBMTypes.h @@ -78,7 +78,7 @@ typedef struct HBMDataInfo { BOOL backFlag; // at 0x18 int region; // at 0x1C BOOL cursor; // at 0x20 - BOOL messageFlag; // at 0x24 + int messageFlag; // at 0x24 u32 configBufSize; // at 0x28 u32 memSize; // at 0x2C f32 frameDelta; // at 0x30 diff --git a/include/nw4r/ef.h b/include/nw4r/ef.h index e0304172f..11d95a8ac 100644 --- a/include/nw4r/ef.h +++ b/include/nw4r/ef.h @@ -49,3 +49,21 @@ #include #endif + +/****************************************************************************** + * + * Customizable memory manager + * + ******************************************************************************/ +#if defined(NW4R_EF_MEMORY_MANAGER_CONFIGURED) + +#ifndef NW4R_PUBLIC_EF_MEMORY_MANAGER_H +#define NW4R_PUBLIC_EF_MEMORY_MANAGER_H + +#include +#include +#include + +#endif + +#endif diff --git a/include/nw4r/ef/ef_drawinfo.h b/include/nw4r/ef/ef_drawinfo.h index 9c5fb10f4..65fa88407 100644 --- a/include/nw4r/ef/ef_drawinfo.h +++ b/include/nw4r/ef/ef_drawinfo.h @@ -11,43 +11,32 @@ namespace ef { class DrawInfo { private: - math::MTX34 mViewMtx; // at 0x0 - math::MTX34 mProjMtx; // at 0x30 - bool mLightEnable; // at 0x60 - GXLightID mLightMask; // at 0x64 - bool mIsSpotLight; // at 0x68 - GXFogType mFogType; // at 0x6C - f32 mFogStartz; // at 0x70 - f32 mFogEndz; // at 0x74 - f32 mFogNearz; // at 0x78 - f32 mFogFarz; // at 0x7C - GXColor mFogColor; // at 0x80 - f32 mZOffset; // at 0x84 - math::VEC3 mZOffsetOrig; // at 0x88 - GXColor mChanMatColor; // at 0x94 - GXColor mChanAmbColor; // at 0x98 + math::MTX34 mViewMtx; // at 0x0 + math::MTX34 mProjMtx; // at 0x30 + bool mLightEnable; // at 0x60 + GXLightID mLightMask; // at 0x64 + bool mIsSpotLight; // at 0x68 + GXFogType mFogType; // at 0x6C + f32 mFogStartz; // at 0x70 + f32 mFogEndz; // at 0x74 + f32 mFogNearz; // at 0x78 + f32 mFogFarz; // at 0x7C + GXColor mFogColor; // at 0x80 public: - DrawInfo() - : mLightEnable(false), - mLightMask(GX_LIGHT_NULL), - mIsSpotLight(true), - mFogType(GX_FOG_NONE), - mFogStartz(0.0f), - mFogEndz(1.0f), - mFogNearz(0.0f), - mFogFarz(1.0f), - mZOffset(0.0f) { - - mZOffsetOrig.x = 0.0f; - mZOffsetOrig.y = 0.0f; - mZOffsetOrig.z = 0.0f; - - mChanMatColor.r = mChanMatColor.g = mChanMatColor.b = mChanMatColor.a = - 255; - - mChanAmbColor.r = mChanAmbColor.g = mChanAmbColor.b = 0; - mChanAmbColor.a = 255; + DrawInfo() { + math::MTX34Identity(&mViewMtx); + math::MTX34Identity(&mProjMtx); + + mLightEnable = false; + mLightMask = GX_LIGHT_NULL; + mIsSpotLight = true; + + mFogType = GX_FOG_NONE; + mFogStartz = 0.0f; + mFogEndz = 1.0f; + mFogNearz = 0.0f; + mFogFarz = 1.0f; } const math::MTX34* GetViewMtx() const { @@ -86,22 +75,6 @@ class DrawInfo { *pFarZ = mFogFarz; *pColor = mFogColor; } - - void GetZOffset(f32& rOffset, math::VEC3& rPos) const { - rOffset = mZOffset; - rPos = mZOffsetOrig; - } - void SetZOffset(f32 offset, const math::VEC3& rPos) { - mZOffset = offset; - mZOffsetOrig = rPos; - } - - const GXColor& GetChanMatColor() const { - return mChanMatColor; - } - const GXColor& GetChanAmbColor() const { - return mChanAmbColor; - } }; } // namespace ef diff --git a/include/nw4r/ef/ef_effect.h b/include/nw4r/ef/ef_effect.h index d30bad6f9..2c3709f66 100644 --- a/include/nw4r/ef/ef_effect.h +++ b/include/nw4r/ef/ef_effect.h @@ -8,7 +8,6 @@ #include #include #include - #include #include @@ -102,27 +101,28 @@ class Effect : public ReferencedObject { mDrawOrderFunc->Remove(this, pManager); } - void Modifier_SetSimpleLightType(u8 type, bool ignoreLifeStatus) { + void Modifier_SetSimpleLightType(u8 type, bool ignoreLifeStatus = false) { ForeachParticleManager( ParticleManager::ModifierTravFunc_SetSimpleLightType, static_cast(type), ignoreLifeStatus); } void Modifier_SetSimpleLightAmbient(const GXColor& rColor, - bool ignoreLifeStatus) { + bool ignoreLifeStatus = false) { ForeachParticleManager( ParticleManager::ModifierTravFunc_SetSimpleLightAmbient, reinterpret_cast(&rColor), ignoreLifeStatus); } // @bug Surely meant to be a const reference... - void Modifier_SetScale(math::VEC2& rScale, bool ignoreLifeStatus) { + void Modifier_SetScale(math::VEC2& rScale, bool ignoreLifeStatus = false) { ForeachParticleManager(ParticleManager::ModifierTravFunc_SetScale, reinterpret_cast(&rScale), ignoreLifeStatus); } - void Modifier_SetRotate(const math::VEC3& rRot, bool ignoreLifeStatus) { + void Modifier_SetRotate(const math::VEC3& rRot, + bool ignoreLifeStatus = false) { ForeachParticleManager(ParticleManager::ModifierTravFunc_SetRotate, reinterpret_cast(&rRot), ignoreLifeStatus); } @@ -169,6 +169,10 @@ class Effect : public ReferencedObject { const math::VEC3* GetVelocity() const { return &mVelocity; } + + void SetVelocity(const nw4r::math::VEC3& rVelocity) { + mVelocity = rVelocity; + } }; } // namespace ef diff --git a/include/nw4r/ef/ef_effectsystem.h b/include/nw4r/ef/ef_effectsystem.h index 2452ba7c7..7754ec38c 100644 --- a/include/nw4r/ef/ef_effectsystem.h +++ b/include/nw4r/ef/ef_effectsystem.h @@ -41,6 +41,9 @@ class EffectSystem { public: static EffectSystem* GetInstance(); + EffectSystem(); + ~EffectSystem(); + bool Initialize(u32 maxGroupID); bool Closing(Effect* pEffect); @@ -62,19 +65,12 @@ class EffectSystem { if (mMemoryManager != NULL) { Initialize(maxGroupID); - } else { - maxGroupID = 0; - mActivityList = NULL; } } void SetXFFlushSafe(bool safe) { mXFFlushSafe = safe; } - -private: - EffectSystem(); - ~EffectSystem(); }; } // namespace ef diff --git a/include/nw4r/ef/ef_handle.h b/include/nw4r/ef/ef_handle.h index 56cd619b1..ba38e8ee3 100644 --- a/include/nw4r/ef/ef_handle.h +++ b/include/nw4r/ef/ef_handle.h @@ -31,7 +31,8 @@ template class Handle : public HandleBase { Handle(T* pObject) : HandleBase(static_cast(pObject)) {} Handle& operator=(T* pObject) { - *this = static_cast(pObject); + static_cast(*this) = static_cast(pObject); + return *this; } bool IsAlive() const { diff --git a/include/nw4r/ef/ef_memorymanager.h b/include/nw4r/ef/ef_memorymanager.h index d1c5fc2e1..da5a255ec 100644 --- a/include/nw4r/ef/ef_memorymanager.h +++ b/include/nw4r/ef/ef_memorymanager.h @@ -43,6 +43,7 @@ class MemoryManagerBase { virtual u32 GetNumFreeParticle() const = 0; // at 0x5C virtual void* AllocHeap(u32 size) = 0; // at 0x60 + virtual void FreeHeap(void* pPtr) = 0; // at 0x64 }; } // namespace ef diff --git a/include/nw4r/ef/ef_memorymanagerconfig.h b/include/nw4r/ef/ef_memorymanagerconfig.h new file mode 100644 index 000000000..541854cd9 --- /dev/null +++ b/include/nw4r/ef/ef_memorymanagerconfig.h @@ -0,0 +1,105 @@ +#ifndef NW4R_EF_MEMORY_MANAGER_CONFIG_H +#define NW4R_EF_MEMORY_MANAGER_CONFIG_H +#include + +// clang-format off +// +// Effect memory management in nw4r::ef involves watching the lifetime of four object types: +// - Effects created by the system (nw4r::ef::Effect) +// - Emitters created by their effects (nw4r::ef::Emitter) +// - Particle managers (nw4r::ef::ParticleManager) +// - Particles created by their managers (nw4r::ef::Particle) +// +// NW4R provides the MemoryManagerBase interface to allow the implementation to be swapped out. +// Register a memory manager with the effect system, and it will be used for all memory allocations. +// +// The default concrete implementation is MemoryManager, which leverages MemoryManagerTmp for object pooling. +// However, MemoryManagerTmp requires explicit template specializations for its GarbageCollection method. +// +// Customizing the default MemoryManager becomes difficult for developers because they would need to +// dig into nw4r::ef internals to understand MemoryManagerTmp and implement GarbageCollection for their object types. +// +// As such, the only way to reasonably support derived object types in these two classes +// is to allow developers to configure the basic MemoryManager through the use of preprocessor macros. +// +// There exists some information we can gather that gives this theory some merit. +// +// nw4r::ef::MemoryManager contains very large functions defined in-header, despite inlining them being impossible. +// +// In New Super Mario Bros. Wii, debugging symbols reveal that a modified MemoryManager exists for EGG types. +// Additionally, the classes keep their original names (MemoryManager, MemoryManagerTmp) but are strangely in the global namespace. +// +// Stringitized expressions leftover in debug NW4R assertions reveal that MemoryManagerTmp accesses members +// of the nw4r::ef namespace using "::nw4r::ef::". +// +// clang-format on + +// Opening namespace declarations +#if !defined(NW4R_EF_MEMORY_MANAGER_NAMESPACE_OPEN) +#if defined(NW4R_EF_MEMORY_MANAGER_CONFIGURED) +#define NW4R_EF_MEMORY_MANAGER_NAMESPACE_OPEN +#else +#define NW4R_EF_MEMORY_MANAGER_NAMESPACE_OPEN \ + namespace nw4r { \ + namespace ef { +#endif +#endif + +// Closing namespace declarations +#if !defined(NW4R_EF_MEMORY_MANAGER_NAMESPACE_CLOSE) +#if defined(NW4R_EF_MEMORY_MANAGER_CONFIGURED) +#define NW4R_EF_MEMORY_MANAGER_NAMESPACE_CLOSE +#else +#define NW4R_EF_MEMORY_MANAGER_NAMESPACE_CLOSE \ + } \ + } +#endif +#endif + +// Memory manager class name +#if !defined(NW4R_EF_MEMORY_MANAGER_CLASS) +#define NW4R_EF_MEMORY_MANAGER_CLASS MemoryManager +#endif + +// Temp memory manager class name +#if !defined(NW4R_EF_MEMORY_MANAGER_TMP_CLASS) +#define NW4R_EF_MEMORY_MANAGER_TMP_CLASS MemoryManagerTmp +#endif + +// Effect object class type +#if !defined(NW4R_EF_MEMORY_MANAGER_TEFFECT) +#define NW4R_EF_MEMORY_MANAGER_TEFFECT ::nw4r::ef::Effect +#endif + +// Emitter object class type +#if !defined(NW4R_EF_MEMORY_MANAGER_TEMITTER) +#define NW4R_EF_MEMORY_MANAGER_TEMITTER ::nw4r::ef::Emitter +#endif + +// Particle manager object class type +#if !defined(NW4R_EF_MEMORY_MANAGER_TPARTICLEMANAGER) +#define NW4R_EF_MEMORY_MANAGER_TPARTICLEMANAGER ::nw4r::ef::ParticleManager +#endif + +// Particle object class type +#if !defined(NW4R_EF_MEMORY_MANAGER_TPARTICLE) +#define NW4R_EF_MEMORY_MANAGER_TPARTICLE ::nw4r::ef::Particle +#endif + +#if defined(NW4R_EF_MEMORY_MANAGER_CONFIGURED) +#define NW4R_EF_MEMORY_MANAGER_MEMBER_ACCESS public: +#else +#define NW4R_EF_MEMORY_MANAGER_MEMBER_ACCESS private: +#endif + +NW4R_EF_MEMORY_MANAGER_NAMESPACE_OPEN; + +// Expose user object types +typedef NW4R_EF_MEMORY_MANAGER_TEFFECT TEffect; +typedef NW4R_EF_MEMORY_MANAGER_TEMITTER TEmitter; +typedef NW4R_EF_MEMORY_MANAGER_TPARTICLEMANAGER TParticleManager; +typedef NW4R_EF_MEMORY_MANAGER_TPARTICLE TParticle; + +NW4R_EF_MEMORY_MANAGER_NAMESPACE_CLOSE; + +#endif diff --git a/include/nw4r/ef/ef_memorymanagerimpl.h b/include/nw4r/ef/ef_memorymanagerimpl.h new file mode 100644 index 000000000..286488f23 --- /dev/null +++ b/include/nw4r/ef/ef_memorymanagerimpl.h @@ -0,0 +1,524 @@ +#ifndef NW4R_EF_MEMORY_MANAGER_IMPL_H +#define NW4R_EF_MEMORY_MANAGER_IMPL_H +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +NW4R_EF_MEMORY_MANAGER_NAMESPACE_OPEN; + +class NW4R_EF_MEMORY_MANAGER_CLASS : public ::nw4r::ef::MemoryManagerBase { + NW4R_EF_MEMORY_MANAGER_MEMBER_ACCESS; + struct MemInfo { + MemInfo* prev; // at 0x0 + MemInfo* next; // at 0x4 + MemInfo* chainPrev; // at 0x8 + MemInfo* chainNext; // at 0xC + u32 size; // at 0x10 + bool active; // at 0x14 + u8 PADDING_0x15[3]; // at 0x15 + }; + + NW4R_EF_MEMORY_MANAGER_MEMBER_ACCESS; + int mLeastEffect; // at 0x4 + int mMaxEffect; // at 0x8 + TEffectOM* mEffectOM; // at 0xC + + int mLeastEmitter; // at 0x10 + int mMaxEmitter; // at 0x14 + TEmitterOM* mEmitterOM; // at 0x18 + + int mLeastParticleManager; // at 0x1C + int mMaxParticleManager; // at 0x20 + TParticleManagerOM* mParticleManagerOM; // at 0x24 + + int mLeastParticle; // at 0x28 + int mMaxParticle; // at 0x2C + TParticleOM* mParticleOM; // at 0x30 + + void* mHeapStartAddr; // at 0x34 + void* mHeapEndAddr; // at 0x38 + + MemInfo* mActiveMem; // at 0x3C + MemInfo* mFreeMem; // at 0x40 + MemInfo* mFreeMemTail; // at 0x44 + MemInfo* mAllChain; // at 0x48 + +public: + static u32 CalcMemorySize(u16 maxEffect, u16 maxEmitter, + u16 maxParticleManager, u16 maxParticle, + u32 maxGroupID) { + // clang-format off + return ROUND_UP(sizeof(MemInfo), 32) + ::nw4r::ut::RoundUp(maxEffect * sizeof(TEffect) + 32, 32) + + ROUND_UP(sizeof(MemInfo), 32) + ::nw4r::ut::RoundUp(maxEmitter * sizeof(TEmitter) + 32, 32) + + ROUND_UP(sizeof(MemInfo), 32) + ::nw4r::ut::RoundUp(maxParticleManager * sizeof(TParticleManager) + 32, 32) + + ROUND_UP(sizeof(MemInfo), 32) + ::nw4r::ut::RoundUp(maxParticle * sizeof(TParticle) + 32, 32) + + ROUND_UP(sizeof(MemInfo), 32) + ::nw4r::ut::RoundUp(maxGroupID * sizeof(::nw4r::ef::ActivityList) + 32, 32) + + ROUND_UP(sizeof(MemInfo), 32) + ROUND_UP(sizeof(TEffectOM), 32) + + ROUND_UP(sizeof(MemInfo), 32) + ROUND_UP(sizeof(TEmitterOM), 32) + + ROUND_UP(sizeof(MemInfo), 32) + ROUND_UP(sizeof(TParticleManagerOM), 32) + + ROUND_UP(sizeof(MemInfo), 32) + ROUND_UP(sizeof(TParticleOM), 32); + // clang-format on + } + + NW4R_EF_MEMORY_MANAGER_CLASS(void* pStartAddr, u32 size, int maxEffect, + int maxEmitter, int maxParticleManager, + int maxParticle) { + + u32 headerSize = ::nw4r::ut::RoundUp(sizeof(MemInfo), 32); + + mLeastEffect = 0; + mLeastEmitter = 0; + mLeastParticleManager = 0; + mLeastParticle = 0; + + mMaxEffect = 0; + mMaxEmitter = 0; + mMaxParticleManager = 0; + mMaxParticle = 0; + + mEffectOM = NULL; + mEmitterOM = NULL; + mParticleManagerOM = NULL; + mParticleOM = NULL; + + mActiveMem = NULL; + mFreeMem = NULL; + mFreeMemTail = NULL; + mAllChain = NULL; + + mHeapEndAddr = static_cast(pStartAddr) + size; + mHeapStartAddr = reinterpret_cast( + ::nw4r::ut::RoundUp(reinterpret_cast(pStartAddr), 32)); + + mLeastEffect = maxEffect; + mLeastEmitter = maxEmitter; + mLeastParticleManager = maxParticleManager; + mLeastParticle = maxParticle; + + mMaxEffect = mLeastEffect; + mMaxEmitter = mLeastEmitter; + mMaxParticleManager = mLeastParticleManager; + mMaxParticle = mLeastParticle; + + mFreeMem = static_cast(mHeapStartAddr); + mFreeMem->prev = NULL; + mFreeMem->next = NULL; + mFreeMem->chainPrev = NULL; + mFreeMem->chainNext = NULL; + mFreeMem->active = false; + mFreeMem->size = static_cast(mHeapEndAddr) - + static_cast(mHeapStartAddr) - headerSize; + + mAllChain = mFreeMem; + mActiveMem = NULL; + + // clang-format off + int numEffects = mLeastEffect; + TEffect* pEffects = NULL; + + if (numEffects > 0) { + pEffects = new (AllocHeap(sizeof(TEffect) * numEffects + 32)) TEffect[numEffects]; + } + + mEffectOM = new (AllocHeap(sizeof(TEffectOM))) + TEffectOM(mLeastEffect, pEffects); + + int numEmitters = mLeastEmitter; + TEmitter* pEmitters = NULL; + + if (numEmitters > 0) { + pEmitters = new (AllocHeap(sizeof(TEmitter) * numEmitters + 32)) TEmitter[numEmitters]; + } + + mEmitterOM = new (AllocHeap(sizeof(TEmitterOM))) + TEmitterOM(mLeastEmitter, pEmitters); + + int numParticleManagers = mLeastParticleManager; + TParticleManager* pParticleManagers = NULL; + + if (numParticleManagers > 0) { + pParticleManagers = new (AllocHeap(sizeof(TParticleManager) * numParticleManagers + 32)) TParticleManager[numParticleManagers]; + } + + mParticleManagerOM = new (AllocHeap(sizeof(TParticleManagerOM))) + TParticleManagerOM(mLeastParticleManager, pParticleManagers); + + int numParticles = mLeastParticle; + TParticle* pParticles = NULL; + + if (numParticles > 0) { + pParticles = new (AllocHeap(sizeof(TParticle) * numParticles + 32)) TParticle[numParticles]; + } + + mParticleOM = new (AllocHeap(sizeof(TParticleOM))) + TParticleOM(mLeastParticle, pParticles); + // clang-format on + } + + virtual ~NW4R_EF_MEMORY_MANAGER_CLASS() {} // at 0x8 + + virtual void GarbageCollection() { + void* pPtr = + ::nw4r::ut::List_GetFirst(&mParticleManagerOM->mLeasedList); + + while (pPtr != NULL) { + void* pNext = ::nw4r::ut::List_GetNext( + &mParticleManagerOM->mLeasedList, pPtr); + + TParticleManager* mMgr = static_cast(pPtr); + + TParticle* pPtcl; + TParticle* pNextPtcl; + + for (pPtcl = static_cast( + mMgr->mActivityList.mClosingList.headObject); + pPtcl != NULL; pPtcl = pNextPtcl) { + + // clang-format off + pNextPtcl = static_cast( + NW4R_UT_LIST_GET_LINK(mMgr->mActivityList.mClosingList, pPtcl)->nextObject); + // clang-format on + + pPtcl->mParticleManager->ParticleToFree(pPtcl); + ::nw4r::ut::List_Remove(&mParticleOM->mLeasedList, pPtcl); + ::nw4r::ut::List_Append(&mParticleOM->mFreeList, pPtcl); + } + + pPtr = static_cast(pNext); + } + + if (mParticleManagerOM != NULL) { + mParticleManagerOM->GarbageCollection(); + } + + if (mEmitterOM != NULL) { + mEmitterOM->GarbageCollection(); + } + + if (mEffectOM != NULL) { + mEffectOM->GarbageCollection(); + } + } // at 0xC + + virtual TEffect* AllocEffect() { + if (mEffectOM == NULL) { + return NULL; + } else { + return mEffectOM->Alloc(); + } + } // at 0x10 + + virtual void FreeEffect(void* pObj) { + if (mEffectOM != NULL) { + mEffectOM->Free(static_cast(pObj)); + } + } // at 0x14 + + virtual u32 GetNumAllocEffect() const { + if (mEffectOM == NULL) { + return 0; + } else { + return mEffectOM->GetNumAllocObject(); + } + } // at 0x18 + + virtual u32 GetNumActiveEffect() const { + if (mEffectOM == NULL) { + return 0; + } else { + return mEffectOM->GetNumActiveObject(); + } + } // at 0x1C + + virtual u32 GetNumFreeEffect() const { + if (mEffectOM == NULL) { + return 0; + } else { + return mEffectOM->GetNumFreeObject(); + } + } // at 0x20 + + virtual TEmitter* AllocEmitter() { + if (mEmitterOM == NULL) { + return NULL; + } else { + return mEmitterOM->Alloc(); + } + } // at 0x24 + + virtual void FreeEmitter(void* pObj) { + if (mEmitterOM != NULL) { + mEmitterOM->Free(static_cast(pObj)); + } + } // at 0x28 + + virtual u32 GetNumAllocEmitter() const { + if (mEmitterOM == NULL) { + return 0; + } else { + return mEmitterOM->GetNumAllocObject(); + } + } // at 0x2C + + virtual u32 GetNumActiveEmitter() const { + if (mEmitterOM == NULL) { + return 0; + } else { + return mEmitterOM->GetNumActiveObject(); + } + } // at 0x30 + + virtual u32 GetNumFreeEmitter() const { + if (mEmitterOM == NULL) { + return 0; + } else { + return mEmitterOM->GetNumFreeObject(); + } + } // at 0x34 + + virtual TParticleManager* AllocParticleManager() { + if (mParticleManagerOM == NULL) { + return NULL; + } else { + return mParticleManagerOM->Alloc(); + } + } // at 0x38 + + virtual void FreeParticleManager(void* pObj) { + if (mParticleManagerOM != NULL) { + mParticleManagerOM->Free(static_cast(pObj)); + } + } // at 0x3C + + virtual u32 GetNumAllocParticleManager() const { + if (mParticleManagerOM == NULL) { + return 0; + } else { + return mParticleManagerOM->GetNumAllocObject(); + } + } // at 0x40 + + virtual u32 GetNumActiveParticleManager() const { + if (mParticleManagerOM == NULL) { + return 0; + } else { + return mParticleManagerOM->GetNumActiveObject(); + } + } // at 0x44 + + virtual u32 GetNumFreeParticleManager() const { + if (mParticleManagerOM == NULL) { + return 0; + } else { + return mParticleManagerOM->GetNumFreeObject(); + } + } // at 0x48 + + virtual TParticle* AllocParticle() { + if (mParticleOM == NULL) { + return NULL; + } else { + return mParticleOM->Alloc(); + } + } // at 0x4C + + virtual void FreeParticle(void* pObj) { + if (mParticleOM != NULL) { + mParticleOM->Free(static_cast(pObj)); + } + } // at 0x50 + + virtual u32 GetNumAllocParticle() const { + if (mParticleOM == NULL) { + return 0; + } else { + return mParticleOM->GetNumAllocObject(); + } + } // at 0x54 + + virtual u32 GetNumActiveParticle() const { + if (mParticleOM == NULL) { + return 0; + } else { + return mParticleOM->GetNumActiveObject(); + } + } // at 0x58 + + virtual u32 GetNumFreeParticle() const { + if (mParticleOM == NULL) { + return 0; + } else { + return mParticleOM->GetNumFreeObject(); + } + } // at 0x5C + + virtual void* AllocHeap(u32 size) { + u32 headerSize = ::nw4r::ut::RoundUp(sizeof(MemInfo), 32); + size = ::nw4r::ut::RoundUp(size, 32); + + for (MemInfo* pIt = mFreeMem; pIt != NULL; pIt = pIt->next) { + if (pIt->size < size) { + continue; + } + + if (pIt->size < size + headerSize + 32) { + if (pIt->prev != NULL) { + pIt->prev->next = pIt->next; + } else { + mFreeMem = pIt->next; + } + + if (pIt->next != NULL) { + pIt->next->prev = pIt->prev; + } + + if (mActiveMem != NULL) { + mActiveMem->prev = pIt; + } + + pIt->next = mActiveMem; + pIt->prev = NULL; + pIt->active = true; + mActiveMem = pIt; + } else { + MemInfo* pNewFree = reinterpret_cast( + (reinterpret_cast(pIt) + headerSize + size)); + + pNewFree->prev = pIt->prev; + pNewFree->next = pIt->next; + pNewFree->size = pIt->size - size - headerSize; + pNewFree->active = false; + pNewFree->chainNext = pIt->chainNext; + + if (pIt->chainNext != NULL) { + pIt->chainNext->chainPrev = pNewFree; + } + + pNewFree->chainPrev = pIt; + pIt->chainNext = pNewFree; + + if (pIt->prev != NULL) { + pIt->prev->next = pNewFree; + } else { + mFreeMem = pNewFree; + } + + if (pIt->next != NULL) { + pNewFree->next->prev = pNewFree; + } + + if (mActiveMem != NULL) { + mActiveMem->prev = pIt; + } + + pIt->next = mActiveMem; + pIt->prev = NULL; + pIt->size = size; + pIt->active = true; + mActiveMem = pIt; + } + + return reinterpret_cast(pIt) + headerSize; + } + + return NULL; + } // at 0x60 + + virtual void FreeHeap(void* pPtr) { + u32 headerSize = ::nw4r::ut::RoundUp(sizeof(MemInfo), 32); + + MemInfo* pInfo = + reinterpret_cast(static_cast(pPtr) - headerSize); + + if (pInfo->prev != NULL) { + pInfo->prev->next = pInfo->next; + } else { + mActiveMem = pInfo->next; + } + + if (pInfo->next != NULL) { + pInfo->next->prev = pInfo->prev; + } + + MemInfo* pPrev = NULL; + if (pInfo->chainPrev != NULL && !pInfo->chainPrev->active) { + pPrev = pInfo->chainPrev; + } + + MemInfo* pNext = NULL; + if (pInfo->chainNext != NULL && !pInfo->chainNext->active) { + pNext = pInfo->chainNext; + } + + if (pPrev != NULL) { + if (pNext != NULL) { + if (pNext->prev != NULL) { + pNext->prev->next = pNext->next; + } else { + mFreeMem = pNext->next; + } + + if (pNext->next != NULL) { + pNext->next->prev = pNext->prev; + } + + pPrev->size += + pNext->size + pInfo->size + headerSize + headerSize; + + pPrev->chainNext = pNext->chainNext; + + if (pNext->chainNext != NULL) { + pNext->chainNext->chainPrev = pPrev; + } + } else { + pPrev->size += pInfo->size + headerSize; + pPrev->chainNext = pInfo->chainNext; + + if (pInfo->chainNext != NULL) { + pInfo->chainNext->chainPrev = pPrev; + } + } + } else if (pNext != NULL) { + if (pNext->prev != NULL) { + pNext->prev->next = pInfo; + } else { + mFreeMem = pInfo; + } + + if (pNext->next != NULL) { + pNext->next->prev = pInfo; + } + + pInfo->prev = pNext->prev; + pInfo->next = pNext->next; + pInfo->size += pNext->size + headerSize; + pInfo->active = false; + pInfo->chainNext = pNext->chainNext; + + if (pNext->chainNext != NULL) { + pNext->chainNext->chainPrev = pPrev; + } + } else { + if (mFreeMem != NULL) { + mFreeMem->prev = pInfo; + } + + pInfo->next = mFreeMem; + pInfo->prev = 0; + pInfo->active = false; + mFreeMem = pInfo; + } + } // at 0x64 +}; + +NW4R_EF_MEMORY_MANAGER_NAMESPACE_CLOSE; + +#endif diff --git a/include/nw4r/ef/ef_memorymanagertmp.h b/include/nw4r/ef/ef_memorymanagertmp.h index c595b45e5..09f8e05c1 100644 --- a/include/nw4r/ef/ef_memorymanagertmp.h +++ b/include/nw4r/ef/ef_memorymanagertmp.h @@ -3,96 +3,166 @@ #include #include +#include #include #include +#include #include #include - #include -namespace nw4r { -namespace ef { +NW4R_EF_MEMORY_MANAGER_NAMESPACE_OPEN; + +template class NW4R_EF_MEMORY_MANAGER_TMP_CLASS { + friend class NW4R_EF_MEMORY_MANAGER_CLASS; -template class MemoryManagerTmp { -private: - T* mHead; // at 0x0 - ut::List mFreeList; // at 0x4 - ut::List mLeasedList; // at 0x10 - int mStructSize; // at 0x1C + NW4R_EF_MEMORY_MANAGER_MEMBER_ACCESS; + T* mHead; // at 0x0 + ::nw4r::ut::List mFreeList; // at 0x4 + ::nw4r::ut::List mLeasedList; // at 0x10 + int mStructSize; // at 0x1C public: - virtual void AssignObjectID(void* pObject); + static const u32 OBJECT_ID_BASE = 0x10000; + +public: + NW4R_EF_MEMORY_MANAGER_TMP_CLASS(int aCount, T* aHeap) { + u16 offset = offsetof(T, mMemoryLink); + int structSize = sizeof(T); + + ::nw4r::ut::List_Init(&mFreeList, offset); + ::nw4r::ut::List_Init(&mLeasedList, offset); + + mStructSize = structSize; + mHead = aHeap; + + for (u32 i = 0; i < aCount; i++) { + aHeap[i].mObjectID = i; + ::nw4r::ut::List_Append(&mFreeList, &aHeap[i]); + } + } + + virtual void AssignObjectID(void* pObj) { + static_cast< ::nw4r::ef::LinkedObject*>(pObj)->mObjectID += + OBJECT_ID_BASE; + } // at 0x8 + + // Not implemented for Particle + void GarbageCollection(); + + T* Alloc() { + void* pPtr = ::nw4r::ut::List_GetFirst(&mFreeList); + if (pPtr == NULL) { + return NULL; + } + + AssignObjectID(pPtr); + ::nw4r::ut::List_Remove(&mFreeList, pPtr); + ::nw4r::ut::List_Append(&mLeasedList, pPtr); + + return static_cast(pPtr); + } + + void Free(T* pObj) { + ::nw4r::ut::List_Remove(&mLeasedList, pObj); + ::nw4r::ut::List_Append(&mFreeList, pObj); + } + + u32 GetNumAllocObject() const { + return GetNumActiveObject() + GetNumFreeObject(); + } + + u32 GetNumActiveObject() const { + return ::nw4r::ut::List_GetSize(&mLeasedList); + } + + u32 GetNumFreeObject() const { + return ::nw4r::ut::List_GetSize(&mFreeList); + } }; -class MemoryManager : public MemoryManagerBase { -private: - struct MemInfo { - MemInfo* prev; // at 0x0 - MemInfo* next; // at 0x4 - MemInfo* chainPrev; // at 0x8 - MemInfo* chainNext; // at 0xC - u32 size; // at 0x10 - bool active; // at 0x14 - u8 PADDING_0x15[3]; // at 0x15 - }; +// Shorthand for MemoryManagerTmp specializations (also used by MemoryManager) +typedef NW4R_EF_MEMORY_MANAGER_TMP_CLASS TEffectOM; +typedef NW4R_EF_MEMORY_MANAGER_TMP_CLASS TEmitterOM; +typedef NW4R_EF_MEMORY_MANAGER_TMP_CLASS TParticleManagerOM; +typedef NW4R_EF_MEMORY_MANAGER_TMP_CLASS TParticleOM; -private: - int mMaxEffect; // at 0x4 - MemoryManagerTmp* mEffectOM; // at 0x8 +template <> inline void TEffectOM::GarbageCollection() { + void* pPtr = ::nw4r::ut::List_GetFirst(&mLeasedList); - int mMaxEmitter; // at 0xC - MemoryManagerTmp* mEmitterOM; // at 0x10 + if (pPtr != NULL) { + void* pNext = ::nw4r::ut::List_GetNext(&mLeasedList, pPtr); - int mMaxParticleManager; // at 0x14 - MemoryManagerTmp* mParticleManagerOM; // at 0x18 + while (pPtr != NULL) { + TEffect* pObj = static_cast(pPtr); - int mMaxParticle; // at 0x1C - MemoryManagerTmp* mParticleOM; // at 0x20 + if (pObj->GetLifeStatus() == + ::nw4r::ef::ReferencedObject::NW4R_EF_LS_CLOSING && + pObj->GetRefCount() == 0) { - void* mHeapStartAddr; // at 0x24 - void* mHeapEndAddr; // at 0x28 + pObj->mManagerES->mActivityList[pObj->mGroupID].ToFree(pObj); + ::nw4r::ut::List_Remove(&mLeasedList, pObj); + ::nw4r::ut::List_Append(&mFreeList, pObj); + } - MemInfo* mActiveMem; // at 0x2C - MemInfo* mFreeMem; // at 0x30 - MemInfo* mFreeMemTail; // at 0x34 - MemInfo* mAllChain; // at 0x38 + pPtr = pNext; + pNext = ::nw4r::ut::List_GetNext(&mLeasedList, pPtr); + } + } +} -public: - // TODO(kiwi) Crazy big implementation... - - MemoryManager() {} - virtual ~MemoryManager() {} // at 0x8 - - virtual void GarbageCollection() = 0; // at 0xC - - virtual Effect* AllocEffect() = 0; // at 0x10 - virtual void FreeEffect(void* pObject) = 0; // at 0x14 - virtual u32 GetNumAllocEffect() const = 0; // at 0x18 - virtual u32 GetNumActiveEffect() const = 0; // at 0x1C - virtual u32 GetNumFreeEffect() const = 0; // at 0x20 - - virtual Emitter* AllocEmitter() = 0; // at 0x24 - virtual void FreeEmitter(void* pObject) = 0; // at 0x28 - virtual u32 GetNumAllocEmitter() const = 0; // at 0x2C - virtual u32 GetNumActiveEmitter() const = 0; // at 0x30 - virtual u32 GetNumFreeEmitter() const = 0; // at 0x34 - - virtual ParticleManager* AllocParticleManager() = 0; // at 0x38 - virtual void FreeParticleManager(void* pObject) = 0; // at 0x3C - virtual u32 GetNumAllocParticleManager() const = 0; // at 0x40 - virtual u32 GetNumActiveParticleManager() const = 0; // at 0x44 - virtual u32 GetNumFreeParticleManager() const = 0; // at 0x48 - - virtual Particle* AllocParticle() = 0; // at 0x4C - virtual void FreeParticle(void* pObject) = 0; // at 0x50 - virtual u32 GetNumAllocParticle() const = 0; // at 0x54 - virtual u32 GetNumActiveParticle() const = 0; // at 0x58 - virtual u32 GetNumFreeParticle() const = 0; // at 0x5C - - virtual void* AllocHeap(u32 size) = 0; // at 0x60 -}; +template <> inline void TEmitterOM::GarbageCollection() { + void* pPtr = ::nw4r::ut::List_GetFirst(&mLeasedList); + + if (pPtr != NULL) { + void* pNext = ::nw4r::ut::List_GetNext(&mLeasedList, pPtr); + + while (pPtr != NULL) { + TEmitter* pObj = static_cast(pPtr); + + if (pObj->GetLifeStatus() == + ::nw4r::ef::ReferencedObject::NW4R_EF_LS_CLOSING && + pObj->GetRefCount() == 0) { + + pObj->mManagerEF->mActivityList.ToFree(pObj); + ::nw4r::ut::List_Remove(&mLeasedList, pObj); + ::nw4r::ut::List_Append(&mFreeList, pObj); + } + + pPtr = pNext; + pNext = ::nw4r::ut::List_GetNext(&mLeasedList, pPtr); + } + } +} + +template <> inline void TParticleManagerOM::GarbageCollection() { + void* pPtr = ::nw4r::ut::List_GetFirst(&mLeasedList); + + if (pPtr != NULL) { + void* pNext = ::nw4r::ut::List_GetNext(&mLeasedList, pPtr); + + while (pPtr != NULL) { + TParticleManager* pObj = static_cast(pPtr); + + if (pObj->GetLifeStatus() == + ::nw4r::ef::ReferencedObject::NW4R_EF_LS_CLOSING && + pObj->GetRefCount() == 0) { + + pObj->mManagerEM->mActivityList.ToFree(pObj); + ::nw4r::ut::List_Remove(&mLeasedList, pObj); + ::nw4r::ut::List_Append(&mFreeList, pObj); + } + + pPtr = pNext; + pNext = ::nw4r::ut::List_GetNext(&mLeasedList, pPtr); + } + } +} + +#if !defined(NONMATCHING) +template <> inline void TParticleOM::GarbageCollection() {} +#endif -} // namespace ef -} // namespace nw4r +NW4R_EF_MEMORY_MANAGER_NAMESPACE_CLOSE; #endif diff --git a/include/nw4r/ef/ef_resource.h b/include/nw4r/ef/ef_resource.h index 0afc5d5a1..f6e68c521 100644 --- a/include/nw4r/ef/ef_resource.h +++ b/include/nw4r/ef/ef_resource.h @@ -4,9 +4,9 @@ #include #include - #include + namespace nw4r { namespace ef { @@ -46,6 +46,8 @@ class Resource { static Resource* GetInstance(); + void Initialize(); + EffectProject* Add(u8* pData); TextureProject* AddTexture(u8* pData); @@ -70,8 +72,6 @@ class Resource { private: Resource(); - void Initialize(); - u32 relocateCurveTexture(u8* pCmdList); u32 relocateCurveChild(u8* pCmdList); diff --git a/include/nw4r/math/math_types.h b/include/nw4r/math/math_types.h index 65967309f..6fed0b0dd 100644 --- a/include/nw4r/math/math_types.h +++ b/include/nw4r/math/math_types.h @@ -182,6 +182,16 @@ struct _MTX33 { struct MTX33 : _MTX33 { MTX33() {} + + // clang-format off + MTX33(f32 f00, f32 f01, f32 f02, + f32 f10, f32 f11, f32 f12, + f32 f20, f32 f21, f32 f22) { + _00 = f00; _01 = f01; _02 = f02; + _10 = f10; _11 = f11; _12 = f12; + _20 = f20; _21 = f21; _22 = f22; + } + // clang-format on }; /****************************************************************************** diff --git a/include/nw4r/snd/snd_SoundArchivePlayer.h b/include/nw4r/snd/snd_SoundArchivePlayer.h index 069f19b20..7e328f6b9 100644 --- a/include/nw4r/snd/snd_SoundArchivePlayer.h +++ b/include/nw4r/snd/snd_SoundArchivePlayer.h @@ -141,7 +141,7 @@ class SoundArchivePlayer : public detail::DisposeCallback, const detail::NoteOnInfo& rInfo); // at 0xC private: - const SoundArchivePlayer& mSoundArchivePlayer; // at 0x0 + const SoundArchivePlayer& mSoundArchivePlayer; // at 0x4 }; /****************************************************************************** @@ -160,7 +160,7 @@ class SoundArchivePlayer : public detail::DisposeCallback, u32 callbackArg) const; // at 0xC private: - const SoundArchivePlayer& mSoundArchivePlayer; // at 0x0 + const SoundArchivePlayer& mSoundArchivePlayer; // at 0x4 }; private: diff --git a/include/nw4r/snd/snd_SoundHeap.h b/include/nw4r/snd/snd_SoundHeap.h index ac67d7085..ab6d8304b 100644 --- a/include/nw4r/snd/snd_SoundHeap.h +++ b/include/nw4r/snd/snd_SoundHeap.h @@ -49,7 +49,7 @@ class SoundHeap : public SoundMemoryAllocatable { void* pCallbackArg); private: - mutable OSMutex mMutex; // at 0x0 + mutable OSMutex mMutex; // at 0x4 detail::FrameHeap mFrameHeap; // at 0x1C }; diff --git a/include/nw4r/ut/ut_list.h b/include/nw4r/ut/ut_list.h index ba7e6a808..27c750537 100644 --- a/include/nw4r/ut/ut_list.h +++ b/include/nw4r/ut/ut_list.h @@ -104,6 +104,7 @@ inline u16 List_GetSize(const List* pList) { __VA_ARGS__; \ } \ } + /** * List for-each macro (reverse order). * diff --git a/include/revolution/VI/vi.h b/include/revolution/VI/vi.h index 95696787d..8f7a44b6f 100644 --- a/include/revolution/VI/vi.h +++ b/include/revolution/VI/vi.h @@ -80,6 +80,8 @@ VITVFormat VIGetTvFormat(void); VIScanMode VIGetScanMode(void); u32 VIGetDTVStatus(void); +BOOL VIEnableDimming(BOOL enable); + #ifdef __cplusplus } #endif diff --git a/include/types.h b/include/types.h index 5c8d5151d..4d8053861 100644 --- a/include/types.h +++ b/include/types.h @@ -10,9 +10,10 @@ #include #endif -#include -#include -#include +#include +#include +#include + #include typedef unsigned long long u64; diff --git a/src/Pack/RPAudio/RPSndMoveParam.cpp b/src/Pack/RPAudio/RPSndMoveParam.cpp index 6115ed18b..f3e51d5e9 100644 --- a/src/Pack/RPAudio/RPSndMoveParam.cpp +++ b/src/Pack/RPAudio/RPSndMoveParam.cpp @@ -137,7 +137,7 @@ void RPSndMoveParamMgr::update() { RPSndMoveParamLink* pNext = NULL; for (; pIt != NULL; pIt = pNext) { - bool ongoing = static_cast(pIt)->update(); + bool ongoing = static_cast(pIt)->doUpdate(); pNext = static_cast( nw4r::ut::List_GetNext(&sMoveParamList, pIt)); @@ -147,3 +147,6 @@ void RPSndMoveParamMgr::update() { } } } + +DECOMP_FORCELITERAL(RPSndMoveParam_cpp, + 4503599627370496.0); diff --git a/src/Pack/RPAudio/RPSndObject.cpp b/src/Pack/RPAudio/RPSndObject.cpp index 55910eab1..d596dbc5f 100644 --- a/src/Pack/RPAudio/RPSndObject.cpp +++ b/src/Pack/RPAudio/RPSndObject.cpp @@ -25,13 +25,8 @@ nw4r::ut::List RPSndAudioActorBase::sActorList; * @param frames Fade out time */ void RPSndObjMgr::stopAllActorSound(int frames) { - RPSndAudioActorBase* pIt = static_cast( - nw4r::ut::List_GetFirst(&RPSndAudioActorBase::sActorList)); - - for (; pIt != NULL; - pIt = static_cast( - nw4r::ut::List_GetNext(&RPSndAudioActorBase::sActorList, pIt))) { - - pIt->stopAllSound(frames); + RP_NW4R_LIST_FOREACH (RPSndAudioActorBase, it, + RPSndAudioActorBase::sActorList) { + it->stopAllSound(frames); } } diff --git a/src/Pack/RPKernel/RPSysAppMiiManager.cpp b/src/Pack/RPKernel/RPSysAppMiiManager.cpp index 114551513..001353dfb 100644 --- a/src/Pack/RPKernel/RPSysAppMiiManager.cpp +++ b/src/Pack/RPKernel/RPSysAppMiiManager.cpp @@ -11,11 +11,15 @@ * @param num Mii buffer capacity * @param pHeap Heap to use for allocations */ -RPSysAppMiiManager::RPSysAppMiiManager(u16 num, EGG::Heap* pHeap) - : mNumData(num), mppStoreData(NULL), mppCharData(NULL) { +RPSysAppMiiManager::RPSysAppMiiManager(u16 num, EGG::Heap* pHeap) : mNumData(num) { + //! Private variables require out-of-declaration setting + //! because ProjectLocal is accessed here as well. + RPSysProjectLocal *local = RP_GET_INSTANCE(RPSysProjectLocal); + mppStoreData = NULL; + mppCharData = NULL; // Only Wii Sports uses character data (no checksum) - if (RP_GET_INSTANCE(RPSysProjectLocal)->getPack() == + if (local->getPack() == RPSysSceneCreator::EPackID_SportsPack) { mppCharData = new (pHeap) RFLCharData*[num]; @@ -23,3 +27,9 @@ RPSysAppMiiManager::RPSysAppMiiManager(u16 num, EGG::Heap* pHeap) mppStoreData = new (pHeap) RFLStoreData*[num]; } } + +/** + * @brief Destructor + */ + //! Should be defined here: wrong order otherwise +RPSysAppMiiManager::~RPSysAppMiiManager() {} diff --git a/src/Pack/RPKernel/RPSysEffectBase.cpp b/src/Pack/RPKernel/RPSysEffectBase.cpp new file mode 100644 index 000000000..e8464ca31 --- /dev/null +++ b/src/Pack/RPKernel/RPSysEffectBase.cpp @@ -0,0 +1,782 @@ +#include + +#include +#include + +#include +#include + +/** + * @brief Dummy effect handle + */ +const nw4r::ef::Handle RPSysEffect::INVALID_HANDLE; + +/** + * @brief Constructor + * + * @param pName Effect name + * @param drawGroup Effect draw group + * @param drawScene Effect draw scene + */ +RPSysEffect::RPSysEffect(const char* pName, u32 drawGroup, u32 drawScene) { + // @bug Unsafe string operations +#if defined(BUG_FIX) + std::strncpy(mName, pName, ARRAY_SIZE(mName)); +#else + std::strcpy(mName, pName); +#endif + + mDrawGroup = drawGroup; + mDrawScene = drawScene; + + reset(); +} + +/** + * @brief Destructor + */ +RPSysEffect::~RPSysEffect() {} + +/** + * @brief Creates this effect if it does not yet exist + * + * @return Success + */ +bool RPSysEffect::create() { + if (isValid() && !isAlive()) { + mHandle = INVALID_HANDLE; + } + + if (!isValid()) { + reset(); + + mHandle = RP_GET_INSTANCE(RPSysEffectMgr) + ->createEffect(mName, mDrawGroup, mDrawScene); + + return isValid(); + } + + return false; +} + +/** + * @brief Fades away and destroys this effect + */ +void RPSysEffect::fade() { + if (isValid()) { + mHandle.GetPtr()->RetireEmitterAll(); + mHandle = INVALID_HANDLE; + } +} + +/** + * @brief Fades away this effect without destroying the handle + */ +void RPSysEffect::followFade() { + if (isValid()) { + mHandle.GetPtr()->RetireEmitterAll(); + } +} + +/** + * @brief Destroys this effect and all of its particles + */ +void RPSysEffect::forceKill() { + if (isValid()) { + mHandle.GetPtr()->RetireEmitterAll(); + mHandle.GetPtr()->RetireParticleAll(); + mHandle = INVALID_HANDLE; + } +} + +/** + * @brief Toggles whether this effect will update + * + * @param disable Whether to disable updating + */ +void RPSysEffect::setDisableCalc(bool disable) { + if (isValid()) { + mHandle.GetPtr()->SetFlagDisableCalc(disable); + } +} + +/** + * @brief Toggles whether this effect will draw + * + * @param disable Whether to disable drawing + */ +void RPSysEffect::setDisableDraw(bool disable) { + if (isValid()) { + mHandle.GetPtr()->SetFlagDisableDraw(disable); + } +} + +/** + * @brief Toggles whether this effect will update and draw + * + * @param disable Whether to disable both updating and drawing + */ +void RPSysEffect::setDisableCalcDraw(bool disable) { + if (isValid()) { + mHandle.GetPtr()->SetFlagDisableCalc(disable); + mHandle.GetPtr()->SetFlagDisableDraw(disable); + } +} + +/** + * @brief Sets the lifetime of all particles + * + * @param life Lifetime, in ticks + */ +void RPSysEffect::setLife(u16 life) { + if (isValid()) { + int numEmitter = mHandle.GetPtr()->GetNumEmitter(); + + for (int i = 0; i < numEmitter; i++) { + nw4r::ef::Emitter* pEmitter = mHandle.GetPtr()->GetEmitter(i); + + if (pEmitter == NULL) { + continue; + } + + int numParticleManager = pEmitter->GetNumParticleManager(); + + for (int j = 0; j < numParticleManager; j++) { + // clang-format off + RPSysParticleManager* pParticleManager = + static_cast(pEmitter->GetParticleManager(j)); + // clang-format on + + if (pParticleManager == NULL) { + continue; + } + + pParticleManager->SetParticleLife(life); + } + } + } +} + +/** + * @brief Sets the emission ratio of all emitters + * + * @param ratio Emission ratio + */ +void RPSysEffect::setEmitRatio(f32 ratio) { + if (isValid()) { + int numEmitter = mHandle.GetPtr()->GetNumEmitter(); + + for (int i = 0; i < numEmitter; i++) { + nw4r::ef::Emitter* pEmitter = mHandle.GetPtr()->GetEmitter(i); + if (pEmitter == NULL) { + continue; + } + + pEmitter->mParameter.mEmitRatio = ratio; + } + } +} + +/** + * @brief Sets the emission interval of all emitters + * + * @param ratio Emission interval + */ +void RPSysEffect::setEmitInterval(u16 interval) { + if (isValid()) { + int numEmitter = mHandle.GetPtr()->GetNumEmitter(); + + for (int i = 0; i < numEmitter; i++) { + nw4r::ef::Emitter* pEmitter = mHandle.GetPtr()->GetEmitter(i); + if (pEmitter == NULL) { + continue; + } + + pEmitter->mParameter.mEmitInterval = interval; + } + } +} + +/** + * @brief Sets the number of circular divisions of all emitters + * + * @param emitDiv Number of emitter divisions + */ +void RPSysEffect::setEmitEmitDiv(u16 emitDiv) { + if (isValid()) { + int numEmitter = mHandle.GetPtr()->GetNumEmitter(); + + for (int i = 0; i < numEmitter; i++) { + nw4r::ef::Emitter* pEmitter = mHandle.GetPtr()->GetEmitter(i); + if (pEmitter == NULL) { + continue; + } + + pEmitter->mParameter.mEmitEmitDiv = emitDiv; + } + } +} + +/** + * @brief Sets the emission power in the radiation direction + * + * @param power Emission power + */ +void RPSysEffect::setPowerRadiationDir(f32 power) { + if (isValid()) { + int numEmitter = mHandle.GetPtr()->GetNumEmitter(); + + for (int i = 0; i < numEmitter; i++) { + nw4r::ef::Emitter* pEmitter = mHandle.GetPtr()->GetEmitter(i); + if (pEmitter == NULL) { + continue; + } + + pEmitter->mParameter.mVelPowerRadiationDir = power; + } + } +} + +/** + * @brief Sets the emission power in the specified direction + * + * @param power Emission power + */ +void RPSysEffect::setPowerSpecDir(f32 power) { + if (isValid()) { + int numEmitter = mHandle.GetPtr()->GetNumEmitter(); + + for (int i = 0; i < numEmitter; i++) { + nw4r::ef::Emitter* pEmitter = mHandle.GetPtr()->GetEmitter(i); + if (pEmitter == NULL) { + continue; + } + + pEmitter->mParameter.mVelPowerSpecDir = power; + } + } +} + +/** + * @brief Adds emission power in the specified direction + * + * @param add Emission power addend + */ +void RPSysEffect::setPowerSpecDirAdd(f32 add) { + if (isValid()) { + int numEmitter = mHandle.GetPtr()->GetNumEmitter(); + + for (int i = 0; i < numEmitter; i++) { + nw4r::ef::Emitter* pEmitter = mHandle.GetPtr()->GetEmitter(i); + if (pEmitter == NULL) { + continue; + } + + nw4r::ef::EmitterResource* pResource = pEmitter->mResource; + if (pResource == NULL) { + continue; + } + + nw4r::ef::EmitterDesc* pDesc = pResource->GetEmitterDesc(); + if (pDesc == NULL) { + continue; + } + + pEmitter->mParameter.mVelPowerSpecDir = + pDesc->velPowerSpecDir + add; + } + } +} + +/** + * @brief Sets the specified direction of emission + * + * @param rDir Specified direction + */ +void RPSysEffect::setSpecDir(const nw4r::math::VEC3& rDir) { + if (isValid()) { + int numEmitter = mHandle.GetPtr()->GetNumEmitter(); + + for (int i = 0; i < numEmitter; i++) { + nw4r::ef::Emitter* pEmitter = mHandle.GetPtr()->GetEmitter(i); + if (pEmitter == NULL) { + continue; + } + + nw4r::math::MTX34 localMtx; + nw4r::math::MTX34 globalMtx; + + pEmitter->CalcGlobalMtx(&globalMtx); + globalMtx._03 = 0.0f; + globalMtx._13 = 0.0f; + globalMtx._23 = 0.0f; + + if (!nw4r::math::MTX34Inv(&localMtx, &globalMtx)) { + continue; + } + + nw4r::math::VEC3 localDir; + nw4r::math::VEC3Transform(&localDir, &localMtx, &rDir); + + pEmitter->mParameter.mVelSpecDir.x = // + std::acosf(localDir.y); + + pEmitter->mParameter.mVelSpecDir.y = // + std::atan2f(localDir.x, localDir.z); + + pEmitter->mParameter.mVelSpecDir.z = 0.0f; + } + } +} + +/** + * @brief Adds to the specified direction of emission + * + * @param rDir Specified direction addend + */ +void RPSysEffect::setSpecDirAdd(const nw4r::math::VEC3& rAdd) { + if (isValid()) { + int numEmitter = mHandle.GetPtr()->GetNumEmitter(); + + for (int i = 0; i < numEmitter; i++) { + nw4r::ef::Emitter* pEmitter = mHandle.GetPtr()->GetEmitter(i); + if (pEmitter == NULL) { + continue; + } + + nw4r::ef::EmitterResource* pResource = pEmitter->mResource; + if (pResource == NULL) { + continue; + } + + nw4r::ef::EmitterDesc* pDesc = pResource->GetEmitterDesc(); + if (pDesc == NULL) { + continue; + } + + nw4r::math::MTX34 rot; + nw4r::math::VEC3 dir(0.0f, 1.0f, 0.0f); + nw4r::math::MTX34 localMtx; + nw4r::math::MTX34 globalMtx; + + pEmitter->CalcGlobalMtx(&globalMtx); + globalMtx._03 = 0.0f; + globalMtx._13 = 0.0f; + globalMtx._23 = 0.0f; + + nw4r::math::MTX34RotXYZRad(&rot, pDesc->velSpecDir.x, + pDesc->velSpecDir.y, + pDesc->velSpecDir.z); + + nw4r::math::VEC3Transform(&dir, &rot, &dir); + nw4r::math::VEC3Transform(&dir, &globalMtx, &dir); + + dir += rAdd; + nw4r::math::VEC3Normalize(&dir, &dir); + + if (!nw4r::math::MTX34Inv(&localMtx, &globalMtx)) { + continue; + } + + nw4r::math::VEC3 localDir; + nw4r::math::VEC3Transform(&localDir, &localMtx, &dir); + + pEmitter->mParameter.mVelSpecDir.x = // + std::acosf(localDir.y); + + pEmitter->mParameter.mVelSpecDir.y = // + std::atan2f(localDir.x, localDir.z); + + pEmitter->mParameter.mVelSpecDir.z = 0.0f; + } + } +} + +/** + * @brief Sets this effect's velocity + * + * @param rVelocity Velocity + */ +void RPSysEffect::setVelocity(const nw4r::math::VEC3& rVelocity) { + if (isValid()) { + mHandle.GetPtr()->SetVelocity(rVelocity); + } +} + +/** + * @brief Sets the color of all particles + * + * @param r Color red component + * @param g Color green component + * @param b Color blue component + * @param a Color alpha component + */ +void RPSysEffect::setColor(u8 r, u8 g, u8 b, u8 a) { + if (isValid()) { + GXColor color = {r, g, b, a}; + + mHandle.GetPtr()->Modifier_SetSimpleLightType( + nw4r::ef::ParticleManager::ParticleModifier::SIMPLELIGHT_AMBIENT); + + mHandle.GetPtr()->Modifier_SetSimpleLightAmbient(color); + } +} + +/** + * @brief Sets the color of all particles + * @details This function assumes full alpha + * + * @param r Color red component + * @param g Color green component + * @param b Color blue component + */ +void RPSysEffect::setColor(u8 r, u8 g, u8 b) { + setColor(r, g, b, 255); +} + +/** + * @brief Sets the color alpha component of all particles + * @details This function assumes a white color + * + * @param a Color alpha component + */ +void RPSysEffect::setColor(u8 a) { + setColor(255, 255, 255, a); +} + +/** + * @brief Sets the default size of all particles + * + * @param rSize Default particle size + */ +void RPSysEffect::setDefaultParticleSize(const nw4r::math::VEC2& rSize) { + if (isValid()) { + int numEmitter = mHandle.GetPtr()->GetNumEmitter(); + + for (int i = 0; i < numEmitter; i++) { + nw4r::ef::Emitter* pEmitter = mHandle.GetPtr()->GetEmitter(i); + + if (pEmitter == NULL) { + continue; + } + + int numParticleManager = pEmitter->GetNumParticleManager(); + + for (int j = 0; j < numParticleManager; j++) { + // clang-format off + RPSysParticleManager* pParticleManager = + static_cast(pEmitter->GetParticleManager(j)); + // clang-format on + + if (pParticleManager == NULL) { + continue; + } + + pParticleManager->SetParticleSize(rSize); + } + } + } +} + +/** + * @brief Sets the scale of all particles + * + * @param rSize Particle scale + */ +void RPSysEffect::setParticleScale(nw4r::math::VEC2& rScale) { + if (!isValid()) { + return; + } + + mHandle.GetPtr()->Modifier_SetScale(rScale); +} + +/** + * @brief Sets the default rotation of all particles + * + * @param rRotate Default particle rotation + */ +void RPSysEffect::setDefaultParticleRotate(const nw4r::math::VEC3& rRotate) { + if (isValid()) { + int numEmitter = mHandle.GetPtr()->GetNumEmitter(); + + for (int i = 0; i < numEmitter; i++) { + nw4r::ef::Emitter* pEmitter = mHandle.GetPtr()->GetEmitter(i); + + if (pEmitter == NULL) { + continue; + } + + int numParticleManager = pEmitter->GetNumParticleManager(); + + for (int j = 0; j < numParticleManager; j++) { + // clang-format off + RPSysParticleManager* pParticleManager = + static_cast(pEmitter->GetParticleManager(j)); + // clang-format on + + if (pParticleManager == NULL) { + continue; + } + + pParticleManager->SetParticleRotate(rRotate); + } + } + } +} + +/** + * @brief Sets the rotation of all particles + * + * @param rRotate Particle rotation + */ +void RPSysEffect::setParticleRotate(const nw4r::math::VEC3& rRotate) { + if (isValid()) { + mHandle.GetPtr()->Modifier_SetRotate(rRotate); + } +} + +/** + * @brief Sets the scale of all emitters + * + * @param rScale Emitter scale + */ +void RPSysEffect::setLocalScale(const nw4r::math::VEC3& rScale) { + if (isValid()) { + int numEmitter = mHandle.GetPtr()->GetNumEmitter(); + + for (int i = 0; i < numEmitter; i++) { + nw4r::ef::Emitter* pEmitter = mHandle.GetPtr()->GetEmitter(i); + if (pEmitter == NULL) { + continue; + } + + pEmitter->mParameter.mScale = rScale; + pEmitter->SetMtxDirty(); + } + } +} + +/** + * @brief Sets this effect's scale without also indirectly scaling particles + * + * @param rScale New effect scale + * @param pParticleScale Current particle scale (optional) + */ +void RPSysEffect::setDynamicsScale(const nw4r::math::VEC3& rScale, + const nw4r::math::VEC2* pParticleScale) { + nw4r::math::VEC2 particleScale(1.0f, 1.0f); + + if (pParticleScale != NULL) { + particleScale = *pParticleScale; + } else { + f32 sx = rScale.x > 0.0f ? rScale.x : -rScale.x; + if (sx < EGG::Mathf::epsilon()) { + particleScale.x = 0.0f; + } else { + particleScale.x /= rScale.x; + } + + f32 sy = rScale.y > 0.0f ? rScale.y : -rScale.y; + if (sy < EGG::Mathf::epsilon()) { + particleScale.y = 0.0f; + } else { + particleScale.y /= rScale.y; + } + } + + setScale(rScale); + setParticleScale(particleScale); +} + +/** + * @brief Sets this effect's scale + * + * @param scale Effect scale (uniform) + */ +void RPSysEffect::setScale(f32 scale) { + mFlags.setBit(EFlag_ScaleDirty); + mScale.x = scale; + mScale.y = scale; + mScale.z = scale; +} + +/** + * @brief Sets this effect's scale + * + * @param rScale Effect scale + */ +void RPSysEffect::setScale(const nw4r::math::VEC3& rScale) { + mFlags.setBit(EFlag_ScaleDirty); + mScale = rScale; +} + +/** + * @brief Sets this effect's position + * + * @param rPosition Effect position + */ +void RPSysEffect::setPos(const nw4r::math::VEC3& rPosition) { + mFlags.setBit(EFlag_PositionDirty); + mPosition = rPosition; +} + +/** + * @brief Sets this effect's transformation matrix + * + * @param rTransform Effect transformation matrix + */ +void RPSysEffect::setMtx(const nw4r::math::MTX34& rTransform) { + mFlags.setBit(EFlag_TransformDirty); + mTransform = rTransform; +} + +/** + * @brief Toggles whether a particle animation is enabled + * + * @param idx Particle animation index + * @param enable Whether to enable the animation + */ +void RPSysEffect::setPtclAnim(int idx, bool enable) { + bool stop = !enable; + + if (isValid()) { + if (mHandle.GetPtr()->GetNumEmitter() > 0) { + nw4r::ef::Emitter* pEmitter = mHandle.GetPtr()->GetEmitter(0); + + if (pEmitter != NULL && pEmitter->mResource != NULL) { + // clang-format off + if (idx < 0) { + for (int i = 0; i < pEmitter->mResource->NumPtclTrack(); i++) { + nw4r::ef::ResAnimCurve res(pEmitter->mResource->GetPtclTrack(i)); + res.SetStop(stop); + } + } else { + nw4r::ef::ResAnimCurve res(pEmitter->mResource->GetPtclTrack(idx)); + res.SetStop(stop); + } + // clang-format on + + return; + } + } + } + + nw4r::ef::ResEmitter res = + nw4r::ef::Resource::GetInstance()->FindEmitter(mName, NULL); + + if (idx < 0) { + for (int i = 0; i < res.ptr()->NumPtclTrack(); i++) { + res.GetPtclTrack(i).SetStop(stop); + } + } else { + res.GetPtclTrack(idx).SetStop(stop); + } +} + +/** + * @brief Flushes this effect's configuration + */ +void RPSysEffect::update() { + if (isValid()) { + nw4r::math::MTX34 mtx; + + if (isAlive()) { + if (mFlags.onBit(EFlag_TransformDirty)) { + nw4r::math::MTX34Copy(&mtx, &mTransform); + } else { + nw4r::math::MTX34Identity(&mtx); + } + + if (mFlags.onBit(EFlag_ScaleDirty)) { + mtx._00 *= mScale.x; + mtx._10 *= mScale.x; + mtx._20 *= mScale.x; + + mtx._01 *= mScale.y; + mtx._11 *= mScale.y; + mtx._21 *= mScale.y; + + mtx._02 *= mScale.z; + mtx._12 *= mScale.z; + mtx._22 *= mScale.z; + } + + if (mFlags.onBit(EFlag_PositionDirty)) { + mtx._03 = mPosition.x; + mtx._13 = mPosition.y; + mtx._23 = mPosition.z; + } + + mHandle.GetPtr()->SetRootMtx(mtx); + } else { + mHandle = INVALID_HANDLE; + } + } +} + +/** + * @brief Tests whether the specified flag in emitter userdata is set + * + * @param idx Userdata bitflag index + */ +bool RPSysEffect::getUserFlag(int idx) const { + if (isValid()) { + if (mHandle.GetPtr()->GetNumEmitter() > 0) { + nw4r::ef::Emitter* pEmitter = mHandle.GetPtr()->GetEmitter(0); + + if (pEmitter != NULL && pEmitter->mResource != NULL) { + // clang-format off + u16 flags = pEmitter->mResource->GetEmitterDesc()->userdata[2] << 8 | + pEmitter->mResource->GetEmitterDesc()->userdata[3]; + // clang-format on + + return 1 << idx & flags; + } + } + } + + nw4r::ef::ResEmitter res = + nw4r::ef::Resource::GetInstance()->FindEmitter(mName, NULL); + + u16 flags = res.ptr()->GetEmitterDesc()->userdata[2] << 8 | + res.ptr()->GetEmitterDesc()->userdata[3]; + + return 1 << idx & flags; +} + +u8 RPSysEffect::fn_801941BC(int idx) const { + if (isValid()) { + if (mHandle.GetPtr()->GetNumEmitter() > 0) { + nw4r::ef::Emitter* pEmitter = mHandle.GetPtr()->GetEmitter(0); + + if (pEmitter != NULL && pEmitter->mResource != NULL) { + return pEmitter->mResource->GetEmitterDesc()->userdata[idx ^ 1]; + } + } + } + + nw4r::ef::ResEmitter res = + nw4r::ef::Resource::GetInstance()->FindEmitter(mName, NULL); + + return res.ptr()->GetEmitterDesc()->userdata[idx ^ 1]; +} + +/** + * @brief Clears this effect's configuration + */ +void RPSysEffect::reset() { + mFlags.makeAllZero(); + + mScale.x = 1.0f; + mScale.y = 1.0f; + mScale.z = 1.0f; + + mPosition.x = 0.0f; + mPosition.y = 0.0f; + mPosition.z = 0.0f; + + nw4r::math::MTX34Identity(&mTransform); + + mHandle = INVALID_HANDLE; +} diff --git a/src/Pack/RPKernel/RPSysEffectCreator.cpp b/src/Pack/RPKernel/RPSysEffectCreator.cpp new file mode 100644 index 000000000..43225eb4f --- /dev/null +++ b/src/Pack/RPKernel/RPSysEffectCreator.cpp @@ -0,0 +1,377 @@ +#include + +#include + +#include +#include + +#include + +#define MY_EPSILON 0.0001f + +/** + * @brief Constructor + * + * @param drawScene Effect draw scene + */ +RPSysEffectCreator::RPSysEffectCreator(u32 drawScene) { + // 6 bits needed to represent [0, MAX_GROUP_ID] + mBaseGroupID = drawScene << 7; + + mpEffectProject = NULL; + mpTextureProject = NULL; + + mBackSaveBuffer = ESaveBuffer_2nd; + mIsSlowEffect = false; + + mFrame = 0.0f; + mFrameRate = 1.0f; + + mpSlowSystem = NULL; + mpMemoryManager = NULL; + + for (int i = 0; i < ESaveBuffer_Max; i++) { + mEmitterParamSave[i] = NULL; + mParticleParamSave[i] = NULL; + } +} + +/** + * @brief Destructor + */ +RPSysEffectCreator::~RPSysEffectCreator() { + resetEffectResource(); +} + +/** + * @brief Attaches new effect resource files + * + * @param pEffectProject Binary effect data project (.BREFF) + * @param pTextureProject Binary effect texture project (.BREFT) + */ +void RPSysEffectCreator::setEffectResource(void* pEffectProject, + void* pTextureProject) { + + if (mpEffectProject == NULL && mpTextureProject == NULL) { + nw4r::ef::Resource* pResource = nw4r::ef::Resource::GetInstance(); + + mpEffectProject = pResource->Add(static_cast(pEffectProject)); + mpTextureProject = + pResource->AddTexture(static_cast(pTextureProject)); + + pResource->RelocateCommand(); + } +} + +/** + * @brief Releases the attached effect resource files + */ +void RPSysEffectCreator::resetEffectResource() { + stopAllEffect(); + + bool relocate = false; + nw4r::ef::Resource* pResource = nw4r::ef::Resource::GetInstance(); + + if (mpEffectProject != NULL) { + pResource->RemoveEffectProject(mpEffectProject); + mpEffectProject = NULL; + relocate = true; + } + + if (mpTextureProject != NULL) { + pResource->RemoveTextureProject(mpTextureProject); + mpTextureProject = NULL; + relocate = true; + } + + if (relocate) { + pResource->RelocateCommand(); + } +} + +/** + * @brief Creates the effect system for slow-motion effects + */ +void RPSysEffectCreator::createSlowSystem() { + u32 workSize = RPSysEffectMemoryManager::CalcMemorySize( // + SLOW_MAX_EFFECT, // + SLOW_MAX_EMITTER, // + SLOW_MAX_PARTICLE_MANAGER, // + SLOW_MAX_PARTICLE, // + RPSysEffectDefine::MAX_GROUP_ID); + + void* pEffectWork = EGG::Heap::alloc(workSize + 32, 32, NULL); + pEffectWork = nw4r::ut::RoundUp(pEffectWork, 32); + + mpMemoryManager = new RPSysEffectMemoryManager( // + pEffectWork, // + workSize, // + SLOW_MAX_EFFECT, // + SLOW_MAX_EMITTER, // + SLOW_MAX_PARTICLE_MANAGER, // + SLOW_MAX_PARTICLE); + + mpSlowSystem = new nw4r::ef::EffectSystem(); + mpSlowSystem->SetMemoryManager(mpMemoryManager, + RPSysEffectDefine::MAX_GROUP_ID); + + for (int i = 0; i < ESaveBuffer_Max; i++) { + mEmitterParamSave[i] = // + new nw4r::ef::EmitterParameter[SLOW_MAX_EMITTER]; + mParticleParamSave[i] = // + new nw4r::ef::ParticleParameter[SLOW_MAX_PARTICLE]; + } +} + +/** + * @brief Sets the frame rate of the slow-motion system + * + * @param frameRate Frame rate (0, 1) + */ +void RPSysEffectCreator::setFrameRate(f32 frameRate) { + if (frameRate >= 1.0f - MY_EPSILON) { + mFrameRate = 1.0f - MY_EPSILON; + + } else if (frameRate <= MY_EPSILON) { + mFrameRate = MY_EPSILON; + + } else { + mFrameRate = frameRate; + } +} + +/** + * @brief Tests whether the slow-motion effect system exists + */ +bool RPSysEffectCreator::isSlowSystem() const { + return mpSlowSystem != NULL; +} + +/** + * @brief Tests whether effects are currently updating in slow motion + */ +bool RPSysEffectCreator::isSlowEffect() const { + return mIsSlowEffect; +} + +/** + * @brief Kills all effects owned by this creator + */ +void RPSysEffectCreator::stopAllEffect() { + nw4r::ef::EffectSystem* pSystem = nw4r::ef::EffectSystem::GetInstance(); + + for (int i = 0; i < RPSysEffectMgr::EDrawGroup_Max; i++) { + u32 groupID = mBaseGroupID | i; + pSystem->RetireEmitterAll(groupID); + pSystem->RetireParticleAll(groupID); + } + + if (mpSlowSystem != NULL) { + for (int i = 0; i < RPSysEffectMgr::EDrawGroup_Max; i++) { + u32 groupID = mBaseGroupID | i; + mpSlowSystem->RetireEmitterAll(groupID); + mpSlowSystem->RetireParticleAll(groupID); + } + } +} + +/** + * @brief Creates an instance of the specified effect + * + * @param pName Effect name + * @param drawGroup Effect draw group + */ +nw4r::ef::Effect* RPSysEffectCreator::createEffect(const char* pName, + u32 drawGroup) { + u32 groupID = mBaseGroupID | drawGroup; + + nw4r::ef::ResEmitter res = + nw4r::ef::Resource::GetInstance()->FindEmitter(pName, NULL); + + u16 flags = res.ptr()->GetEmitterDesc()->userdata[2] << 8 | + res.ptr()->GetEmitterDesc()->userdata[3]; + + // TODO(kiwi) These should be EDrawGroup values I think? + if (flags & RPSysEffectDefine::EUserFlag_15) { + if (flags & RPSysEffectDefine::EUserFlag_0) { + groupID |= 0x30; + } else { + groupID |= 0x20; + } + } else if (!(flags & RPSysEffectDefine::EUserFlag_0)) { + groupID |= 0x10; + } + + if (mpSlowSystem != NULL && + flags & RPSysEffectDefine::EUserFlag_SlowSystem) { + + return mpSlowSystem->CreateEffect(pName, groupID, 0); + } else { + return nw4r::ef::EffectSystem::GetInstance() // + ->CreateEffect(pName, groupID, 0); + } +} + +/** + * @brief Updates all effects owned by this creator + */ +void RPSysEffectCreator::update() { + nw4r::ef::EffectSystem* pSystem = nw4r::ef::EffectSystem::GetInstance(); + + for (int i = 0; i < RPSysEffectMgr::EDrawGroup_Max; i++) { + pSystem->Calc(mBaseGroupID | i, false); + } + + if (mpSlowSystem != NULL) { + const nw4r::ut::List *pListEmitter, *pListParticle; + + const nw4r::ef::EmitterParameter* pLoadEmitter = + mEmitterParamSave[mBackSaveBuffer == ESaveBuffer_1st + ? ESaveBuffer_2nd + : ESaveBuffer_1st]; + + const nw4r::ef::ParticleParameter* pLoadParticle = + mParticleParamSave[mBackSaveBuffer == ESaveBuffer_1st + ? ESaveBuffer_2nd + : ESaveBuffer_1st]; + + nw4r::ef::EmitterParameter* pSaveEmitter = + mEmitterParamSave[mBackSaveBuffer]; + + nw4r::ef::ParticleParameter* pSaveParticle = + mParticleParamSave[mBackSaveBuffer]; + + pListEmitter = &mpMemoryManager->mEmitterOM->mLeasedList; + pListParticle = &mpMemoryManager->mParticleOM->mLeasedList; + + if (mIsSlowEffect) { + for (int i = 0; i < RPSysEffectMgr::EDrawGroup_Max; i++) { + mpSlowSystem->Calc(mBaseGroupID | i, false); + } + + RP_NW4R_LIST_FOREACH (nw4r::ef::Emitter, it, *pListEmitter) { + std::memcpy(&pSaveEmitter[it->GetObjectIdx()], &it->mParameter, + sizeof(nw4r::ef::EmitterParameter)); + } + + RP_NW4R_LIST_FOREACH (nw4r::ef::Particle, it, *pListParticle) { + std::memcpy(&pSaveParticle[it->GetObjectIdx()], &it->mParameter, + sizeof(nw4r::ef::ParticleParameter)); + } + } + + RP_NW4R_LIST_FOREACH (nw4r::ef::Emitter, it, *pListEmitter) { + const nw4r::ef::EmitterParameter* pT0 = + &pLoadEmitter[it->GetObjectIdx()]; + + const nw4r::ef::EmitterParameter* pT1 = + &pSaveEmitter[it->GetObjectIdx()]; + + if (it->mTick <= ESaveBuffer_Max - 1) { + it->mParameter.mComFlags |= + nw4r::ef::EmitterDesc::CMN_FLAG_DISABLE_DRAW; + + continue; + } + + if (it->mTick == ESaveBuffer_Max) { + it->mParameter.mComFlags &= + ~nw4r::ef::EmitterDesc::CMN_FLAG_DISABLE_DRAW; + } + + // clang-format off + it->mParameter.mRotate.x = pT0->mRotate.x + (pT1->mRotate.x - pT0->mRotate.x) * mFrame; + it->mParameter.mRotate.y = pT0->mRotate.y + (pT1->mRotate.y - pT0->mRotate.y) * mFrame; + it->mParameter.mRotate.z = pT0->mRotate.z + (pT1->mRotate.z - pT0->mRotate.z) * mFrame; + + it->mParameter.mTranslate.x = pT0->mTranslate.x + (pT1->mTranslate.x - pT0->mTranslate.x) * mFrame; + it->mParameter.mTranslate.y = pT0->mTranslate.y + (pT1->mTranslate.y - pT0->mTranslate.y) * mFrame; + it->mParameter.mTranslate.z = pT0->mTranslate.z + (pT1->mTranslate.z - pT0->mTranslate.z) * mFrame; + + it->mParameter.mScale.x = pT0->mScale.x + (pT1->mScale.x - pT0->mScale.x) * mFrame; + it->mParameter.mScale.y = pT0->mScale.y + (pT1->mScale.y - pT0->mScale.y) * mFrame; + it->mParameter.mScale.z = pT0->mScale.z + (pT1->mScale.z - pT0->mScale.z) * mFrame; + // clang-format on + + it->SetMtxDirty(); + } + + RP_NW4R_LIST_FOREACH (nw4r::ef::Particle, it, *pListParticle) { + const nw4r::ef::ParticleParameter* pT0 = + &pLoadParticle[it->GetObjectIdx()]; + + const nw4r::ef::ParticleParameter* pT1 = + &pSaveParticle[it->GetObjectIdx()]; + + if (it->mTick <= 1) { + continue; + } + + // clang-format off + it->mParameter.mScale.x = pT0->mScale.x + (pT1->mScale.x - pT0->mScale.x) * mFrame; + it->mParameter.mScale.y = pT0->mScale.y + (pT1->mScale.y - pT0->mScale.y) * mFrame; + + it->mParameter.mRotate.x = pT0->mRotate.x + (pT1->mRotate.x - pT0->mRotate.x) * mFrame; + it->mParameter.mRotate.y = pT0->mRotate.y + (pT1->mRotate.y - pT0->mRotate.y) * mFrame; + it->mParameter.mRotate.z = pT0->mRotate.z + (pT1->mRotate.z - pT0->mRotate.z) * mFrame; + + for (int i = 0; i < nw4r::ef::TEX_LAYER_MAX; i++) { + it->mParameter.mTextureScale[i].x = pT0->mTextureScale[i].x + (pT1->mTextureScale[i].x - pT0->mTextureScale[i].x) * mFrame; + it->mParameter.mTextureScale[i].y = pT0->mTextureScale[i].y + (pT1->mTextureScale[i].y - pT0->mTextureScale[i].y) * mFrame; + + it->mParameter.mTextureRotate[i] = pT0->mTextureRotate[i] + (pT1->mTextureRotate[i] - pT0->mTextureRotate[i]) * mFrame; + + it->mParameter.mTextureTranslate[i].x = pT0->mTextureTranslate[i].x + (pT1->mTextureTranslate[i].x - pT0->mTextureTranslate[i].x) * mFrame; + it->mParameter.mTextureTranslate[i].y = pT0->mTextureTranslate[i].y + (pT1->mTextureTranslate[i].y - pT0->mTextureTranslate[i].y) * mFrame; + } + + it->mParameter.mVelocity.x = pT0->mVelocity.x + (pT1->mVelocity.x - pT0->mVelocity.x) * mFrame; + it->mParameter.mVelocity.y = pT0->mVelocity.y + (pT1->mVelocity.y - pT0->mVelocity.y) * mFrame; + it->mParameter.mVelocity.z = pT0->mVelocity.z + (pT1->mVelocity.z - pT0->mVelocity.z) * mFrame; + + it->mParameter.mPosition.x = pT0->mPosition.x + (pT1->mPosition.x - pT0->mPosition.x) * mFrame; + it->mParameter.mPosition.y = pT0->mPosition.y + (pT1->mPosition.y - pT0->mPosition.y) * mFrame; + it->mParameter.mPosition.z = pT0->mPosition.z + (pT1->mPosition.z - pT0->mPosition.z) * mFrame; + + for (int i = 0; i < nw4r::ef::COLOR_LAYER_MAX; i++) { + for (int j = 0; j < nw4r::ef::COLOR_IDX_MAX; j++) { + it->mParameter.mColor[i][j].r = pT0->mColor[i][j].r + (pT1->mColor[i][j].r - pT0->mColor[i][j].r) * mFrame; + it->mParameter.mColor[i][j].g = pT0->mColor[i][j].g + (pT1->mColor[i][j].g - pT0->mColor[i][j].g) * mFrame; + it->mParameter.mColor[i][j].b = pT0->mColor[i][j].b + (pT1->mColor[i][j].b - pT0->mColor[i][j].b) * mFrame; + it->mParameter.mColor[i][j].a = pT0->mColor[i][j].a + (pT1->mColor[i][j].a - pT0->mColor[i][j].a) * mFrame; + } + } + + it->mParameter.mMomentum = pT0->mMomentum + (pT1->mMomentum - pT0->mMomentum) * mFrame; + // clang-format on + } + + mFrame += mFrameRate; + + if (mFrame >= 1.0f) { + mIsSlowEffect = true; + mBackSaveBuffer ^= 1; + mFrame -= 1.0f; + } else { + mIsSlowEffect = false; + } + } +} + +/** + * @brief Draws the specified set of effects + * + * @param rDrawInfo Graphics configuration + * @param drawGroup Effect draw group + * @param drawScene Effect draw scene + */ +void RPSysEffectCreator::draw(const nw4r::ef::DrawInfo& rDrawInfo, + u32 drawGroup, u32 drawScene) { + + nw4r::ef::EffectSystem::GetInstance() // + ->Draw(rDrawInfo, mBaseGroupID | drawScene | drawGroup); + + if (mpSlowSystem != NULL) { + mpSlowSystem->Draw(rDrawInfo, mBaseGroupID | drawScene | drawGroup); + } +} diff --git a/src/Pack/RPKernel/RPSysEffectMgr.cpp b/src/Pack/RPKernel/RPSysEffectMgr.cpp new file mode 100644 index 000000000..b035ccf61 --- /dev/null +++ b/src/Pack/RPKernel/RPSysEffectMgr.cpp @@ -0,0 +1,356 @@ +#include +#include +#include + +#include + +#include + +#include + +RP_SINGLETON_IMPL_EX(RPSysEffectMgr); + +/** + * @brief Constructor + * + * @param pHeap Parent heap + */ +RPSysEffectMgr::RPSysEffectMgr(EGG::Heap* pHeap) : mpParentHeap(pHeap) { + for (int i = 0; i < EDrawScene_Max; i++) { + mpEffectCreators[i] = NULL; + } + + unk14 = NULL; + nw4r::ef::EffectSystem::GetInstance()->SetXFFlushSafe(true); +} + +/** + * @brief Attaches a new effect creator to the specified scene + * + * @param pCreator Effect creator + * @param drawScene Effect draw scene + */ +void RPSysEffectMgr::setCreator(RPSysEffectCreator* pCreator, u32 drawScene) { + if (pCreator == NULL) { + return; + } + + mpEffectCreators[drawScene] = pCreator; +} + +/** + * @brief Releases the specified effect creator from its scene + * + * @param pCreator Effect creator + */ +void RPSysEffectMgr::resetCreator(RPSysEffectCreator* pCreator) { + if (pCreator == NULL) { + return; + } + + for (int i = 0; i < EDrawScene_Max; i++) { + if (mpEffectCreators[i] == pCreator) { + mpEffectCreators[i] = NULL; + break; + } + } +} + +/** + * @brief Kills all effects and particles + */ +void RPSysEffectMgr::stopAllEffect() { + nw4r::ef::EffectSystem* pSystem = nw4r::ef::EffectSystem::GetInstance(); + + for (int i = 0; i < RPSysEffectDefine::MAX_GROUP_ID; i++) { + pSystem->RetireEmitterAll(i); + pSystem->RetireParticleAll(i); + } + + for (int i = 0; i < EDrawScene_Max; i++) { + if (mpEffectCreators[i] == NULL) { + continue; + } + + if (mpEffectCreators[i]->isSlowSystem()) { + mpEffectCreators[i]->stopAllEffect(); + } + } +} + +/** + * @brief Updates the state of effects + * + * @param setting Effect update type + */ +void RPSysEffectMgr::update(ECalcSetting setting) { + (void)nw4r::ef::EffectSystem::GetInstance(); + + for (int i = 0; i < EDrawScene_Max; i++) { + if (mpEffectCreators[i] == NULL) { + continue; + } + + if (i == EDrawScene_Cursor) { + mpEffectCreators[i]->update(); + } else if (setting == ECalcSetting_All) { + mpEffectCreators[i]->update(); + } + } +} + +/** + * @brief Applies a framebuffer capture texture to all effects + * + * @param pTexture Framebuffer texture + * @param rData Framebuffer texture information + */ +void RPSysEffectMgr::setCaptureEfb(void* pTexture, const EfbTexData& rData) { + nw4r::ef::Resource* pResource = nw4r::ef::Resource::GetInstance(); + + for (int i = 0; i < EDrawScene_Max; i++) { + if (mpEffectCreators[i] == NULL || !mpEffectCreators[i]->isActive()) { + continue; + } + + nw4r::ef::ResTexture res = pResource->FindTexture( + "dummy_tex", mpEffectCreators[i]->getTextureProject()); + + if (res.IsValid()) { + res.ptr()->format = rData.format; + res.ptr()->width = rData.width; + res.ptr()->height = rData.height; + res.ptr()->texture = static_cast(pTexture); + } + } +} + +/** + * @brief Draws the specified set of effects + * + * @param rDrawInfo Graphics configuration + * @param drawGroup Effect draw group + * @param drawScene Effect draw scene + */ +void RPSysEffectMgr::draw(const nw4r::ef::DrawInfo& rDrawInfo, u32 drawGroup, + u32 drawScene) { + + nw4r::ef::DrawInfo sceneDrawInfo; + sceneDrawInfo.SetViewMtx(*rDrawInfo.GetViewMtx()); + + RPGrpScreen* pScreen = RPGrpRenderer::GetCurrentScreen(); + RPGrpView* pView = RPGrpRenderer::GetCurrentView(); + + nw4r::math::MTX34 proj; + if (pView->GetProjType() == RPGrpView::EProjType_Persp) { + C_MTXLightPerspective(proj, pScreen->GetFovy(), pScreen->GetAspect(), + 0.5f, -0.5f, 0.5f, 0.5f); + } else { + f32 cx = pScreen->GetWidth() / 2.0f; + f32 cy = pScreen->GetHeight() / 2.0f; + C_MTXLightOrtho(proj, cy, -cy, -cx, cx, 0.5f, -0.5f, 0.5f, 0.5f); + } + + sceneDrawInfo.SetProjMtx(proj); + + if (drawGroup < EDrawGroup_16) { + for (int i = 0; i < EDrawScene_Max; i++) { + if (mpEffectCreators[i] == NULL) { + continue; + } + + mpEffectCreators[i]->draw(sceneDrawInfo, drawGroup, drawScene); + } + } +} + +DECOMP_FORCELITERAL(RPSysEffectMgr_cpp, + +0.5f, + -0.5f, + 4503599627370496.0); + +/** + * @brief Creates an instance of the specified effect + * + * @param pName Effect name + * @param drawGroup Effect draw group + * @param drawScene Effect draw scene + */ +nw4r::ef::Effect* RPSysEffectMgr::createEffect(const char* pName, u32 drawGroup, + u32 drawScene) { + // @bug Effect creator is not validated +#if defined(BUG_FIX) + if (mpEffectCreators[drawScene] == NULL || + !mpEffectCreators[drawScene]->isActive()) { + return NULL; + } +#endif + + return mpEffectCreators[drawScene]->createEffect(pName, drawGroup); +} + +/** + * @brief Creates a memory manager using the specified settings + * + * @param pArg Effect memory settings + * @return Effect work memory size + */ +u32 RPSysEffectMgr::createMemoryManager(EffectArg* pArg) { + u32 workSize = RPSysEffectMemoryManager::CalcMemorySize( // + pArg->maxEffect, // + pArg->maxEmitter, // + pArg->maxParticleManager, // + pArg->maxParticle, // + RPSysEffectDefine::MAX_GROUP_ID); + + void* pEffectWork = EGG::Heap::alloc(workSize + 32, 32, pArg->pHeap); + pEffectWork = nw4r::ut::RoundUp(pEffectWork, 32); + + RPSysEffectMemoryManager* pMemoryManager = + new (pArg->pHeap) RPSysEffectMemoryManager( // + pEffectWork, // + workSize, // + pArg->maxEffect, // + pArg->maxEmitter, // + pArg->maxParticleManager, // + pArg->maxParticle); + + nw4r::ef::EffectSystem::GetInstance()->SetMemoryManager( + pMemoryManager, RPSysEffectDefine::MAX_GROUP_ID); + + return workSize; +} + +/** + * @brief Loads the assets required by system effect scenes + */ +void RPSysEffectMgr::LoadResource() { + if (mpEffectCreators[EDrawScene_Cursor] != NULL && + !mpEffectCreators[EDrawScene_Cursor]->isActive()) { + + RPSysSceneCreator::EPackID pack = + RP_GET_INSTANCE(RPSysProjectLocal)->getPack(); + + EGG::Archive* pCursorArchive = NULL; + + switch (pack) { + case RPSysSceneCreator::EPackID_SportsPack: { + case RPSysSceneCreator::EPackID_PartyPack: { + pCursorArchive = + RP_GET_INSTANCE(RPSysResourceManager)->GetStaticCommonArchive(); + break; + } + + /* EPackID_HealthPack, EPackID_MusicPack */ + default: { + pCursorArchive = + RP_GET_INSTANCE(RPSysResourceManager)->GetStaticLayoutArchive(); + break; + } + } + } + + void* pCursorEffect = NULL; + void* pCursorTexture = NULL; + + switch (pack) { + case RPSysSceneCreator::EPackID_SportsPack: { + case RPSysSceneCreator::EPackID_PartyPack: { + pCursorEffect = RPSysResourceManager::GetFileFromArchive( + pCursorArchive, "nw4r_defcursor_pack.breff"); + + pCursorTexture = RPSysResourceManager::GetFileFromArchive( + pCursorArchive, "nw4r_defcursor_pack.breft"); + break; + } + + /* EPackID_HealthPack, EPackID_MusicPack */ + default: { + pCursorEffect = RPSysResourceManager::GetFileFromArchive( + pCursorArchive, "pack_cursor_fix.breff"); + + pCursorTexture = RPSysResourceManager::GetFileFromArchive( + pCursorArchive, "pack_cursor_fix.breft"); + break; + } + } + } + + mpEffectCreators[EDrawScene_Cursor]->setEffectResource(pCursorEffect, + pCursorTexture); + } + + if (mpEffectCreators[EDrawScene_Static] != NULL && + !mpEffectCreators[EDrawScene_Static]->isActive()) { + + EGG::Archive* pStaticArchive = NULL; + + RPSysSceneCreator::EPackID pack = + RP_GET_INSTANCE(RPSysProjectLocal)->getPack(); + + switch (pack) { + case RPSysSceneCreator::EPackID_SportsPack: { + case RPSysSceneCreator::EPackID_PartyPack: { + pStaticArchive = + RP_GET_INSTANCE(RPSysResourceManager)->GetStaticCommonArchive(); + break; + } + + /* EPackID_HealthPack, EPackID_MusicPack */ + default: { + pStaticArchive = + RP_GET_INSTANCE(RPSysResourceManager)->GetStaticLayoutArchive(); + break; + } + } + } + + void* pStaticEffect; + void* pStaticTexture; + + const char* pFileNames[][2] = { + // EPackID_SportsPack + "sports_common.breff", + "sports_common.breft", + + // EPackID_PartyPack + "basic_common.breff", + "basic_common.breft", + + // EPackID_HealthPack + NULL, // huh??? + NULL, + + // EPackID_MusicPack + "effect_music.breff", + "effect_music.breft", + }; + + if (pFileNames[pack][0] && pFileNames[pack][1] != NULL) { + pStaticEffect = RPSysResourceManager::GetFileFromArchive( + pStaticArchive, pFileNames[pack][0]); + + pStaticTexture = RPSysResourceManager::GetFileFromArchive( + pStaticArchive, pFileNames[pack][1]); + + mpEffectCreators[EDrawScene_Static]->setEffectResource( + pStaticEffect, pStaticTexture); + } + } +} + +/** + * @brief Destructor + */ +RPSysEffectMgr::~RPSysEffectMgr() { + stopAllEffect(); + + for (int i = 0; i < EDrawScene_Max; i++) { + if (mpEffectCreators[i] != NULL) { + delete mpEffectCreators[i]; + } + } + + nw4r::ef::Resource::GetInstance()->Initialize(); + EGG::Heap::free(unk14, NULL); +} diff --git a/src/Pack/RPKernel/RPSysHomeMenuMgr.cpp b/src/Pack/RPKernel/RPSysHomeMenuMgr.cpp new file mode 100644 index 000000000..753e11f37 --- /dev/null +++ b/src/Pack/RPKernel/RPSysHomeMenuMgr.cpp @@ -0,0 +1,595 @@ +#include +#include +#include +#include + +#include + +#include + +#include +#include + +#include + +RP_SINGLETON_IMPL_EX(RPSysHomeMenuMgr); + +/****************************************************************************** + * + * BanIcon + * + ******************************************************************************/ + +//! X-origin of the ban icon +#define BANICON_X 552.0f +//! Y-origin of the ban icon +#define BANICON_Y 388.0f + +//! Width of the ban icon +#define BANICON_SIZE 28.0f + +/** + * @brief Constructor + */ +RPSysHomeMenuMgr::BanIcon::BanIcon() + : mpTexture(NULL), mState(EState_Hide), mTimer(0), mAlpha(0) {} + +/** + * @brief Updates this icon's state + */ +void RPSysHomeMenuMgr::BanIcon::calc() { + switch (mState) { + case EState_Hide: { + break; + } + + case EState_FadeIn: { + if (++mTimer < FADE_LENGTH) { + mAlpha = mTimer * 255 / FADE_LENGTH; + } else { + mState = EState_Disp; + mTimer = 0; + mAlpha = 255; + } + break; + } + + case EState_Disp: { + if (++mTimer >= DISP_LENGTH) { + mState = EState_FadeOut; + mTimer = 0; + } + + mAlpha = 255; + break; + } + + case EState_FadeOut: { + if (++mTimer < FADE_LENGTH) { + mAlpha = 255 - mTimer * 255 / FADE_LENGTH; + } else { + clear(); + } + break; + } + } +} + +/** + * @brief Renders this icon's state + */ +void RPSysHomeMenuMgr::BanIcon::draw() { + GXColor color; + color.r = color.g = color.b = 255; + color.a = mAlpha; + + RPGrpScreen screen; + screen.SetCanvasMode(RPGrpScreen::CANVAS_CC); + screen.SetNearZ(-10000.0f); + screen.SetFarZ(10000.0f); + screen.SetProjectionType(RPGrpScreen::PROJ_ORTHO); + screen.SetProjectionGX(); + + f32 x = BANICON_X; + f32 y = BANICON_Y; + + f32 current = RPGrpScreen::GetSizeXMax(); + f32 standard = RPGrpScreen::GetSizeYMax(RPGrpScreen::TV_MODE_STD); + + nw4r::ut::Rect rect( // + x * (current / standard) * 0.5f - BANICON_SIZE, // + -y * 0.5f + BANICON_SIZE, // + x * (current / standard), // + y // + ); + + screen.BeginDrawQuadTexture(false); + + screen.DrawQuadTexture( // + rect.left - BANICON_SIZE, // + rect.top + BANICON_SIZE, // + rect.left + BANICON_SIZE, // + rect.top - BANICON_SIZE, // + mpTexture, // + color // + ); +} + +/****************************************************************************** + * + * RPSysHomeMenuMgr + * + ******************************************************************************/ + +/** + * @brief HOME Menu sound archive manager + */ +RPSndHomeMenuArcMgr* RPSysHomeMenuMgr::spHomeMenuArcMgr = NULL; + +/** + * @brief Sound archive heap size + */ +u32 RPSysHomeMenuMgr::sSoundHeapSize = 0x7D000; + +/** + * @brief HBM library sound callback + * + * @param event HBM event + * @param arg Event argument + * @return Whether this callback handled the playback for HBM + */ +BOOL RPSysHomeMenuMgr::soundCallback(int event, int arg) { + switch (event) { + case HBM_SOUND_PLAY: { + spHomeMenuArcMgr->startSe(static_cast(arg)); + return TRUE; + } + + default: { + return FALSE; + } + } +} + +/** + * @brief Constructor + * + * @param pHeap Parent heap + */ +RPSysHomeMenuMgr::RPSysHomeMenuMgr(EGG::Heap* pHeap) : mpParentHeap(pHeap) { + mIsInitialized = false; + mIsDisabled = false; + mIsStarting = false; + + mpBanIcon = new (pHeap) BanIcon(); + init(); + + std::memset(&mHBMDataInfo, 0, sizeof(mHBMDataInfo)); + std::memset(&mHBMControllerData, 0, sizeof(mHBMControllerData)); + + mpProjectLocal = RP_GET_INSTANCE(RPSysProjectLocal); + + mHBMDataInfo.layoutBuf = NULL; + mHBMDataInfo.spkSeBuf = NULL; + mHBMDataInfo.msgBuf = NULL; + mHBMDataInfo.configBuf = NULL; + mHBMDataInfo.mem = new (pHeap) u8[HBM_WORK_SIZE]; + mHBMDataInfo.sound_callback = soundCallback; + mHBMDataInfo.backFlag = FALSE; + mHBMDataInfo.region = SC_LANG_EN; + mHBMDataInfo.cursor = FALSE; + mHBMDataInfo.configBufSize = HBM_CONFIG_SIZE; + mHBMDataInfo.memSize = HBM_WORK_SIZE; + if (mpProjectLocal->getFrameRate() == RPSysProjectLocal::EFrameRate_50Hz) { + mHBMDataInfo.frameDelta = 60.0f / 50.0f; + } else { + mHBMDataInfo.frameDelta = 60.0f / 60.0f; + } + mHBMDataInfo.pAllocator = NULL; + mHBMDataInfo.adjust.x = 1.0f; + mHBMDataInfo.adjust.y = 1.0f; + + std::memset(mHBMDataInfo.mem, 0, HBM_WORK_SIZE); + + spHomeMenuArcMgr = new (pHeap) RPSndHomeMenuArcMgr(); + spHomeMenuArcMgr->createSoundHeap(pHeap, sSoundHeapSize); +} + +/** + * @brief Destructor + */ +RPSysHomeMenuMgr::~RPSysHomeMenuMgr() {} + +/** + * @brief Initializes this manager's state + */ +void RPSysHomeMenuMgr::init() { + mIsDisabled = false; + mIsActive = false; + mIsVisible = false; + mIsSoftReset = false; + + mMenuState = EMenuState_End; + mStateTimer = 0; + + VISetBlack(FALSE); + disable(false); + mpBanIcon->clear(); +} + +/** + * @brief Initializes the HBM library + */ +void RPSysHomeMenuMgr::initHomeButtonInfo() { + // TODO(kiwi) Inline? + HBMDataInfo* pHBMDataInfo = &mHBMDataInfo; + + EGG::Archive* pCommonArchive = + RP_GET_INSTANCE(RPSysResourceManager)->GetStaticCommonArchive(); + + EGG::Archive* pLocalArchive = + RP_GET_INSTANCE(RPSysResourceManager)->GetStaticLocalArchive(); + + void* pIconTexture = + RP_GET_INSTANCE(RPSysResourceManager) + ->GetFileFromArchive(pCommonArchive, "/HomeMenu/homeBtnIcon.bti"); + + mpBanIcon->setTexture(static_cast(pIconTexture)); + + switch (mpProjectLocal->getLanguage()) { + case RPSysProjectLocal::EArea_France: { + pHBMDataInfo->region = SC_LANG_FR; + + pHBMDataInfo->layoutBuf = + RP_GET_INSTANCE(RPSysResourceManager) + ->GetFileFromArchive(pLocalArchive, + "/HomeMenu/homeBtn_FRA.arc"); + break; + } + + case RPSysProjectLocal::EArea_Germany: { + pHBMDataInfo->region = SC_LANG_DE; + + pHBMDataInfo->layoutBuf = + RP_GET_INSTANCE(RPSysResourceManager) + ->GetFileFromArchive(pLocalArchive, + "/HomeMenu/homeBtn_GER.arc"); + break; + } + + case RPSysProjectLocal::EArea_Italy: { + pHBMDataInfo->region = SC_LANG_IT; + + pHBMDataInfo->layoutBuf = + RP_GET_INSTANCE(RPSysResourceManager) + ->GetFileFromArchive(pLocalArchive, + "/HomeMenu/homeBtn_ITA.arc"); + break; + } + + case RPSysProjectLocal::EArea_Spain: { + pHBMDataInfo->region = SC_LANG_SP; + + pHBMDataInfo->layoutBuf = + RP_GET_INSTANCE(RPSysResourceManager) + ->GetFileFromArchive(pLocalArchive, + "/HomeMenu/homeBtn_SPA.arc"); + break; + } + + case RPSysProjectLocal::EArea_Netherlands: { + pHBMDataInfo->region = SC_LANG_NL; + + pHBMDataInfo->layoutBuf = + RP_GET_INSTANCE(RPSysResourceManager) + ->GetFileFromArchive(pLocalArchive, + "/HomeMenu/homeBtn_NED.arc"); + break; + } + + case RPSysProjectLocal::EArea_Japan: { + pHBMDataInfo->region = SC_LANG_JP; + + pHBMDataInfo->layoutBuf = + RP_GET_INSTANCE(RPSysResourceManager) + ->GetFileFromArchive(pLocalArchive, "/HomeMenu/homeBtn.arc"); + break; + } + + default: { + pHBMDataInfo->region = SC_LANG_EN; + + pHBMDataInfo->layoutBuf = + RP_GET_INSTANCE(RPSysResourceManager) + ->GetFileFromArchive(pLocalArchive, + "/HomeMenu/homeBtn_ENG.arc"); + break; + } + } + + pHBMDataInfo->spkSeBuf = + RP_GET_INSTANCE(RPSysResourceManager) + ->GetFileFromArchive(pCommonArchive, "/HomeMenu/SpeakerSe.arc"); + + pHBMDataInfo->msgBuf = + RP_GET_INSTANCE(RPSysResourceManager) + ->GetFileFromArchive(pCommonArchive, "/HomeMenu/home_nosave.csv"); + + pHBMDataInfo->configBuf = + RP_GET_INSTANCE(RPSysResourceManager) + ->GetFileFromArchive(pCommonArchive, "/HomeMenu/config.txt"); + + HBMCreate(pHBMDataInfo); + HBMSetAdjustFlag(TRUE); + + void* pSoundArchive = + RP_GET_INSTANCE(RPSysResourceManager) + ->GetFileFromArchive(pCommonArchive, + "/HomeMenu/HomeButtonSe.brsar"); + + spHomeMenuArcMgr->setupArchive(pSoundArchive); + + if (mpProjectLocal->getPack() == RPSysSceneCreator::EPackID_HealthPack) { + HBMSetBlackOutColor(255, 255, 255); + } + + mIsInitialized = true; +} + +/** + * @brief Checks whether the HOME Menu should be opened + */ +void RPSysHomeMenuMgr::checkMenuStart() { + bool pressedBtn = false; + + for (int index = 0; index < RP_MAX_CONTROLLERS; index++) { + if (RP_GET_CORE_CTRL(index)->getCoreStatus()->getTrigger() & + EGG::cCORE_BUTTON_HOME) { + + pressedBtn = true; + break; + } + } + + if (!pressedBtn && !mIsStarting) { + return; + } + + if (RP_GET_INSTANCE(RPSysSceneMgr) + ->getCurrentSceneRP() + ->isSceneChangeEnable()) { + + if (!mIsDisabled && + !RP_GET_INSTANCE(RPSysDvdStatus)->isErrorOccured()) { + + mMenuState = EMenuState_Start; + mStateTimer = 0; + mIsActive = true; + mIsVisible = false; + + RP_GET_INSTANCE(RPSndAudioMgr)->enterMenu(); + + } else { + mpBanIcon->switchOn(); + } + + mIsStarting = false; + + } else if (RP_GET_INSTANCE(RPSysDvdStatus)->isErrorOccured()) { + mpBanIcon->switchOn(); + + } else { + mIsStarting = true; + } +} + +/** + * @brief Checks whether the HOME Menu should be closed + */ +void RPSysHomeMenuMgr::checkMenuEnd() { + mIsVisible = true; + + switch (HBMCalc(&mHBMControllerData)) { + case HBM_SELECT_BTN2: { + mMenuState = EMenuState_Reset; + RP_GET_INSTANCE(RPSysSceneMgr)->softReset(true); + RP_GET_INSTANCE(RPSndAudioMgr)->stopAllSoundOnPauseOff(); + break; + } + + case HBM_SELECT_BTN1: { + RP_GET_INSTANCE(RPSysSceneMgr)->returnToMenu(true); + + mMenuState = EMenuState_End; + mIsActive = false; + mIsVisible = false; + + RP_GET_INSTANCE(RPSndAudioMgr)->exitMenu(); + + RPSysCoreController::popDpdCtrlStackAll(); + RPSysCoreController::popKPADParamStackAll(); + + // Avoid firing pauseCallback if it would be untrue + if (!RP_GET_INSTANCE(RPSysPauseMgr)->isPause()) { + RP_GET_INSTANCE(RPSysSceneMgr) + ->getCurrentSceneRP() + ->pauseCallBack(false); + } + break; + } + + case HBM_SELECT_HOMEBTN: { + mMenuState = EMenuState_End; + mIsActive = false; + mIsVisible = false; + + RP_GET_INSTANCE(RPSndAudioMgr)->exitMenu(); + + RPSysCoreController::popDpdCtrlStackAll(); + RPSysCoreController::popKPADParamStackAll(); + + // Avoid firing pauseCallback if it would be untrue + if (!RP_GET_INSTANCE(RPSysPauseMgr)->isPause()) { + RP_GET_INSTANCE(RPSysSceneMgr) + ->getCurrentSceneRP() + ->pauseCallBack(false); + } + break; + } + + case HBM_SELECT_NULL: + default: { + break; + } + } +} + +/** + * @brief Performs a soft reset + * + * @return Whether HBM will perform the reset + */ +bool RPSysHomeMenuMgr::softReset() { + if (mIsActive && !mIsSoftReset) { + HBMStartBlackOut(); + mIsSoftReset = true; + } + + mIsStarting = false; + return mIsActive; +} + +/** + * @brief Updates this manager's state + */ +void RPSysHomeMenuMgr::update() { + f32 current = RPGrpScreen::GetSizeXMax(); + f32 standard = RPGrpScreen::GetSizeXMax(RPGrpScreen::TV_MODE_STD); + + mHBMDataInfo.adjust.x = current / standard; + mHBMDataInfo.adjust.y = 1.0f; + + if (mIsActive) { + for (s32 chan = 0; chan < KPAD_MAX_CONTROLLERS; chan++) { + RPSysCoreController* pController = + RP_GET_INSTANCE(RPSysCoreControllerMgr)->findController(chan); + + if (pController != NULL && pController->isCoreBaseDevice()) { + switch (mKPADStatus[chan].wpad_err) { + case WPAD_ERR_COMMUNICATION_ERROR: { + std::memset(&mKPADStatus[chan], 0, + sizeof(mKPADStatus[chan])); + + mKPADStatus[chan].horizon = + pController->getCoreStatus()->horizon; + break; + } + + default: { + mKPADStatus[chan] = *pController->getCoreStatus(); + break; + } + } + + mHBMControllerData.wiiCon[chan].kpad = &mKPADStatus[chan]; + mHBMControllerData.wiiCon[chan].pos = mKPADStatus[chan].pos; + + } else { + mHBMControllerData.wiiCon[chan].kpad = NULL; + mHBMControllerData.wiiCon[chan].pos.x = 10000.0f; + mHBMControllerData.wiiCon[chan].pos.y = 10000.0f; + } + } + } + + if (mIsInitialized) { + switch (mMenuState) { + case EMenuState_End: { + checkMenuStart(); + break; + } + + case EMenuState_Start: { + mStateTimer++; + + if (!RP_GET_INSTANCE(RPSndSpeakerMgr)->isDisconnectAllFinished()) { + break; + } + + mMenuState = EMenuState_Open; + mStateTimer = 0; + + HBMInit(); + + RPSysCoreController::stopMotorAll(); + RPSysCoreController::pushDpdCtrlStackAll(true); + RPSysCoreController::pushKPADParamStackAll(); + + // Avoid firing pauseCallback if it would be untrue + if (!RP_GET_INSTANCE(RPSysPauseMgr)->isPause()) { + RP_GET_INSTANCE(RPSysSceneMgr) + ->getCurrentSceneRP() + ->pauseCallBack(true); + } + break; + } + + case EMenuState_Open: { + checkMenuEnd(); + break; + } + + case EMenuState_Reset: { + mMenuState = EMenuState_End; + mIsActive = false; + mIsVisible = false; + + RP_GET_INSTANCE(RPSndAudioMgr)->exitMenu(); + + RPSysCoreController::popDpdCtrlStackAll(); + RPSysCoreController::popKPADParamStackAll(); + + // Avoid firing pauseCallback if it would be untrue + if (!RP_GET_INSTANCE(RPSysPauseMgr)->isPause()) { + RP_GET_INSTANCE(RPSysSceneMgr) + ->getCurrentSceneRP() + ->pauseCallBack(false); + } + break; + } + + default: { + break; + } + } + + mpBanIcon->calc(); + spHomeMenuArcMgr->calc(); + } +} + +/** + * @brief Renders the HOME Menu if it is visible + */ +void RPSysHomeMenuMgr::draw() { + if (!mIsInitialized) { + return; + } + + if (isActive() && mIsVisible) { + HBMDraw(); + } +} + +/** + * @brief Renders the ban icon if it is visible + */ +void RPSysHomeMenuMgr::drawBanIcon() { + if (!mIsInitialized) { + return; + } + + if (mpBanIcon->isDisp()) { + mpBanIcon->draw(); + } +} diff --git a/src/Pack/RPKernel/RPSysKokeshiCtrlDataLoader.cpp b/src/Pack/RPKernel/RPSysKokeshiCtrlDataLoader.cpp index aa22ea783..f1fd8a514 100644 --- a/src/Pack/RPKernel/RPSysKokeshiCtrlDataLoader.cpp +++ b/src/Pack/RPKernel/RPSysKokeshiCtrlDataLoader.cpp @@ -5,7 +5,7 @@ /** * @brief Constructor * - * @param chan WPAD channel to use + * @param chan Remote channel */ RPSysKokeshiCtrlDataLoader::RPSysKokeshiCtrlDataLoader(s32 chan) : mChannel(chan), mLoadState(ELoadState_Start) {} diff --git a/src/Pack/RPKernel/RPSysKokeshiCtrlDataMgr.cpp b/src/Pack/RPKernel/RPSysKokeshiCtrlDataMgr.cpp index 26012574e..2e7460959 100644 --- a/src/Pack/RPKernel/RPSysKokeshiCtrlDataMgr.cpp +++ b/src/Pack/RPKernel/RPSysKokeshiCtrlDataMgr.cpp @@ -13,7 +13,7 @@ * @param pCallback Controller data callback * @param pParentHeap Heap to use as the parent of the controller data heap * @param heapSize Size of the controller data heap - * @param chan WPAD channel to use + * @param chan Remote channel */ RPSysKokeshiCtrlDataMgr::RPSysKokeshiCtrlDataMgr( IRPSysKokeshiCtrlDataCallback* pCallback, EGG::Heap* pParentHeap, diff --git a/src/Pack/RPKernel/RPSysLytBounding.cpp b/src/Pack/RPKernel/RPSysLytBounding.cpp index 5308e934c..1a8ac88f2 100644 --- a/src/Pack/RPKernel/RPSysLytBounding.cpp +++ b/src/Pack/RPKernel/RPSysLytBounding.cpp @@ -23,7 +23,7 @@ bool RPSysLytBounding::isInsideBounding(const nw4r::lyt::DrawInfo& rInfo, f32 lx = bx.length(); f32 ly = by.length(); - if (lx < NW4R_MATH_FLT_EPSILON || ly < NW4R_MATH_FLT_EPSILON) { + if (lx < EGG::Mathf::epsilon() || ly < EGG::Mathf::epsilon()) { inside = false; } else { nw4r::ut::Rect rect; diff --git a/src/Pack/RPKernel/RPSysLytDynamicAnm.cpp b/src/Pack/RPKernel/RPSysLytDynamicAnm.cpp index e156f7d8a..0db5158f7 100644 --- a/src/Pack/RPKernel/RPSysLytDynamicAnm.cpp +++ b/src/Pack/RPKernel/RPSysLytDynamicAnm.cpp @@ -22,8 +22,13 @@ RPSysLytDynamicAnm::RPSysLytDynamicAnm(nw4r::lyt::Pane* pParent, mAlpha = mpParent->GetAlpha(); const nw4r::math::VEC3& rParentPos = mpParent->GetTranslate(); - mStartPos.set(rParentPos.x, rParentPos.y, rParentPos.z); - mNowPos.set(mStartPos.x, mStartPos.y, mStartPos.z); + mStartPos.x = rParentPos.x; + mStartPos.y = rParentPos.y; + mStartPos.z = rParentPos.z; + + mNowPos.x = mStartPos.x; + mNowPos.y = mStartPos.y; + mNowPos.z = mStartPos.z; mEndFrame = frameNum; mStartFrame = 0; @@ -220,8 +225,9 @@ void RPSysLytDynamicAnm::calc() { target = nw4r::math::SinRad(rad) * 0.5f + 0.5f; } - mpParent->SetTranslate(mNowPos * (1.0f - target) + - mStartPos * target); + EGG::Vector3f translate = + mNowPos * (1.0f - target) + mStartPos * target; + mpParent->SetTranslate(translate); mpParent->SetAlpha(mAlpha * amount); } else { @@ -248,8 +254,9 @@ void RPSysLytDynamicAnm::calc() { target = nw4r::math::SinRad(rad) * 0.5f + 0.5f; } - mpParent->SetTranslate(mNowPos * target + - mStartPos * (1.0f - target)); + EGG::Vector3f translate = + mNowPos * target + mStartPos * (1.0f - target); + mpParent->SetTranslate(translate); mpParent->SetAlpha(mAlpha * (1.0f - amount)); } else { diff --git a/src/Pack/RPKernel/RPSysNWC24Manager.cpp b/src/Pack/RPKernel/RPSysNWC24Manager.cpp index 8e97185d0..741c8235a 100644 --- a/src/Pack/RPKernel/RPSysNWC24Manager.cpp +++ b/src/Pack/RPKernel/RPSysNWC24Manager.cpp @@ -59,7 +59,6 @@ RPSysNWC24Manager::~RPSysNWC24Manager() {} /** * @brief Attempts to commit a message to the Wii Message Board * - * @param pWork Library work buffer * @param pAltName Mail letter alt name * @param pMsg Mail letter message (can be a format string) * @param date Mail letter send date @@ -219,21 +218,24 @@ bool RPSysNWC24Manager::commitMail(const wchar_t* pAltName, const wchar_t* pMsg, /** * @brief Attempts to open the WiiConnect24 library for use * - * @return Success + * @return True if the library is opened, false if not */ bool RPSysNWC24Manager::openLib() { NWC24Work* pNwc24Work = reinterpret_cast(mpNwc24Work); + bool finished; switch (NWC24OpenLib(pNwc24Work)) { case NWC24_ERR_LIB_OPENED: case NWC24_OK: { - return true; + finished = true; + break; } case NWC24_ERR_INPROGRESS: case NWC24_ERR_BUSY: case NWC24_ERR_MUTEX: { - return false; + finished = false; + break; } case NWC24_ERR_NAND_CORRUPT: @@ -245,14 +247,18 @@ bool RPSysNWC24Manager::openLib() { case NWC24_ERR_FILE_OPEN: case NWC24_ERR_BROKEN: case NWC24_ERR_FATAL: { + finished = false; sSuccess = false; - return false; + break; } default: { - return false; + finished = false; + break; } } + + return finished; } /** diff --git a/src/Pack/RPKernel/RPSysParticleManager.cpp b/src/Pack/RPKernel/RPSysParticleManager.cpp index 5d3f92646..22a8eb168 100644 --- a/src/Pack/RPKernel/RPSysParticleManager.cpp +++ b/src/Pack/RPKernel/RPSysParticleManager.cpp @@ -39,30 +39,25 @@ void RPSysParticleManager::Calc() { nw4r::ef::Particle* pPrev = NULL; - nw4r::ef::Particle* pIt = static_cast( - nw4r::ut::List_GetFirst(&GetParticleList()->mActiveList)); - - for (; pIt != NULL; - pIt = static_cast( - nw4r::ut::List_GetNext(&GetParticleList()->mActiveList, pIt))) { - - if (pIt->mTick != 1) { + RP_NW4R_LIST_FOREACH (nw4r::ef::Particle, it, + GetParticleList()->mActiveList) { + if (it->mTick != 1) { continue; } - if (pIt->GetLifeStatus() == + if (it->GetLifeStatus() == nw4r::ef::ReferencedObject::NW4R_EF_LS_WAIT || - pIt->GetLifeStatus() == + it->GetLifeStatus() == nw4r::ef::ReferencedObject::NW4R_EF_LS_CLOSING) { continue; } if (mModifyFlags & EFlag_ModifyLife) { - pIt->mLife = mModifyLife; + it->mLife = mModifyLife; } - nw4r::ef::ParticleParameter* pParameter = pIt->GetParticleParameter(); + nw4r::ef::ParticleParameter* pParameter = it->GetParticleParameter(); if (pParameter == NULL) { continue; } @@ -75,7 +70,7 @@ void RPSysParticleManager::Calc() { pParameter->mRotate = mModifyRotate; } - pPrev = pIt; + pPrev = it; } } diff --git a/src/Pack/RPKernel/RPSysPauseMenu.cpp b/src/Pack/RPKernel/RPSysPauseMenu.cpp new file mode 100644 index 000000000..fb2806f7b --- /dev/null +++ b/src/Pack/RPKernel/RPSysPauseMenu.cpp @@ -0,0 +1,11 @@ +#include + +void RPSysPauseMenu::draw() { + if (!mUNK_0x78) { + mLayout->draw(); + //! todo(texline): define RPUtlLytFrameCursor + // mUtlCursor->draw(); + } +} + +RPSysPauseMenu::~RPSysPauseMenu() {} diff --git a/src/Pack/RPKernel/RPSysSystem.cpp b/src/Pack/RPKernel/RPSysSystem.cpp new file mode 100644 index 000000000..88897729a --- /dev/null +++ b/src/Pack/RPKernel/RPSysSystem.cpp @@ -0,0 +1,90 @@ +#include +#include + +#include +#include + +#include +#include +#include + +void RPSysSystem::setupTVMode() { + int i; + + VIInit(); + for (i = 0; i < 60; i++) { + if (SCCheckStatus() == SC_STATUS_OK) { + break; + } + VIWaitForRetrace(); + } + if (SCGetAspectRatio() == SC_ASPECT_WIDE) { + EGG::Screen::SetTVMode(EGG::Screen::TV_MODE_WIDE); + } else { + EGG::Screen::SetTVMode(EGG::Screen::TV_MODE_STD); + } +} + +RPSysSceneCreator::ESceneID RPSysSystem::getBootScene() { + // this function is hardcoded (symbol name is official, weirdly enough) + return RPSysSceneCreator::ESceneID_RPSportsPackTitleScene; +} + +void RPSysSystem::startLoadCount() { + mLoadCount = 0; +} + +const char* RPSysSystem::getTimeStampString() { + return mpTimeStampString; +} + +void RPSysSystem::setupLocalSettings() { + u8 sysLanguage = SCGetLanguage(); + + if (sysLanguage == SC_LANG_EN) { + RP_GET_INSTANCE(RPSysProjectLocal) + ->setLocale(RPSysProjectLocal::EArea_USA); + RP_GET_INSTANCE(RPSysProjectLocal) + ->setLanguage(RPSysProjectLocal::EArea_USA); + } else if (sysLanguage == SC_LANG_FR) { + RP_GET_INSTANCE(RPSysProjectLocal) + ->setLocale(RPSysProjectLocal::EArea_USA); + RP_GET_INSTANCE(RPSysProjectLocal) + ->setLanguage(RPSysProjectLocal::EArea_France); + } else if (sysLanguage == SC_LANG_SP) { + RP_GET_INSTANCE(RPSysProjectLocal) + ->setLocale(RPSysProjectLocal::EArea_USA); + RP_GET_INSTANCE(RPSysProjectLocal) + ->setLanguage(RPSysProjectLocal::EArea_Spain); + } + //! Requires ifdef for non Americas versions + else { + RP_GET_INSTANCE(RPSysProjectLocal) + ->setLocale(RPSysProjectLocal::EArea_USA); + RP_GET_INSTANCE(RPSysProjectLocal) + ->setLanguage(RPSysProjectLocal::EArea_USA); + } +} + +/** + * @brief Controls whether the game restarts or returns to the Wii Menu upon a + * soft reset. + */ +void RPSysSystem::softResetCallBack() { + if (RP_GET_INSTANCE(RPSysDvdStatus)->isErrorOccured()) { + RP_GET_INSTANCE(RPSysSceneMgr)->returnToMenu(FALSE); + + } else { + VIEnableDimming(FALSE); + + if (RP_GET_INSTANCE(RPSysSceneMgr)->isNormalState() && + !RP_GET_INSTANCE(RPSysHomeMenuMgr)->softReset()) { + + RP_GET_INSTANCE(RPSysSceneMgr)->softReset(FALSE); + } + } +} + +void RPSysSystem::shutdownSystemCallBack() { + RP_GET_INSTANCE(RPSysSceneMgr)->shutdownSystem(FALSE); +} diff --git a/src/Pack/RPSports/RPBowScene/RPBowActiveBall.cpp b/src/Pack/RPSports/RPBowScene/RPBowActiveBall.cpp new file mode 100644 index 000000000..6fb3f4c2a --- /dev/null +++ b/src/Pack/RPSports/RPBowScene/RPBowActiveBall.cpp @@ -0,0 +1,110 @@ +#include + +// Returns a packed 32-bit color (RGBA) from the model +u32 fn_801C389C(RPGrpModel* pModel, int unk1, int unk2); + +// Applies the given color to the model +void fn_801C37EC(RPGrpModel* pModel, int unk1, int unk2, GXColor* pColor); + +namespace Bowling { + +/** + * @brief Initializes the render object to its default state + */ +void RPBowActiveBall::ResetRenderState() { + MTX34Identity(&mtx); + + field_0x74 = 0.0f; + index = 0; + + mtx._23 = 9999.0f; + alpha = 1.0f; +} + +/** + * @brief Renders the currently selected model set + * + * Updates the main model's transform and color, renders a mirrored version used + * for reflections, and optionally submits the model to the shadow texture renderer. + */ +void RPBowActiveBall::RenderModelSet() { + if (mtx._23 > 49.0f) { + return; + } + + nw4r::math::MTX34 worldMtx = mtx; + + f32 scale = 1.0f; + worldMtx._00 *= scale; + worldMtx._01 *= scale; + worldMtx._02 *= scale; + + worldMtx._10 *= scale; + worldMtx._11 *= scale; + worldMtx._12 *= scale; + + worldMtx._20 *= scale; + worldMtx._21 *= scale; + worldMtx._22 *= scale; + + u32 packedColor = fn_801C389C(models[index].pRealModel, 0, 0); + + GXColor color; + color.a = (s8) (255.0f * alpha); + color.r = GX_BITGET(packedColor, 16, 8); + color.g = GX_BITGET(packedColor, 8, 8); + color.b = GX_BITGET(packedColor, 0, 8); + + GXColor modelColor = color; + + fn_801C37EC(models[index].pRealModel, 0, 0, &modelColor); + + if (models[index].pRealModel->GetScnObj() != NULL) { + models[index].pRealModel->GetScnObj()->SetMtx(nw4r::g3d::ScnObj::MTX_LOCAL, &worldMtx); + } + + models[index].pRealModel->UpdateFrame(); + models[index].pRealModel->Calc(); + models[index].pRealModel->Entry(); + + nw4r::math::MTX34 reflectionMtx = worldMtx; + + reflectionMtx._10 *= -1.0f; + reflectionMtx._11 *= -1.0f; + reflectionMtx._12 *= -1.0f; + reflectionMtx._13 *= -1.0f; + + nw4r::math::VEC3 src(0.0f, 0.0f, 0.0f); + nw4r::math::VEC3 dst; + + f32 limit = 1.075f; + f32 thresholdZ = -192.0f + limit; + f32 thresholdY = -limit; + f32 offset = 0.0f; + + VEC3Transform(&dst, &reflectionMtx, &src); + + if (dst.y > thresholdY && dst.z > thresholdZ) { + f32 diff = thresholdY - dst.y; + + if (offset > diff) { + offset = diff; + } + } + + reflectionMtx._13 += offset; + + if (models[index].pReflectionModel->GetScnObj() != NULL) { + models[index].pReflectionModel->GetScnObj()->SetMtx(nw4r::g3d::ScnObj::MTX_LOCAL, &reflectionMtx); + } + + models[index].pReflectionModel->UpdateFrame(); + models[index].pReflectionModel->Calc(); + models[index].pReflectionModel->Entry(); + + if (!disableShadow) { + pShadowTexture->AddModel(models[index].pRealModel, 1.0f); + } +} + +} // namespace Bowling diff --git a/src/Pack/RPSports/RPBowScene/RPBowBackgroundNpcManager.cpp b/src/Pack/RPSports/RPBowScene/RPBowBackgroundNpcManager.cpp new file mode 100644 index 000000000..80eabbf13 --- /dev/null +++ b/src/Pack/RPSports/RPBowScene/RPBowBackgroundNpcManager.cpp @@ -0,0 +1,382 @@ +#include +#include + +#define nullptr 0 + +namespace Bowling { + +// Forward declarations +extern u8 lbl_804BF9F8; +extern u32 lbl_804BF9F4; + +void fn_8034CFC4(NpcIdleState* pIdleState, int param_2, int param_3); +NpcIdleStateSub* fn_8034C95C(NpcIdleState* pIdleState); + +BackgroundNpcConfig gBackgroundNpcParams; + +class RPGrpModelAccessor : public RPGrpModel { +public: + static RPGrpModelAnm* GetModelAnm(RPGrpModel* pModel) { + return pModel->*(&RPGrpModelAccessor::mpModelAnm); + } + + static void SetScale(RPGrpModel* pModel, const nw4r::math::VEC3& rScale) { + pModel->*(&RPGrpModelAccessor::mBaseScale) = rScale; + } +}; + +/** + * @brief Unknown stub + */ +void RPBowBackgroundNpcManager::fn_8034E96C() { + ; +} + +/** + * @brief Destructor + */ +RPBowBackgroundNpcManager::~RPBowBackgroundNpcManager() {} + +/** + * @brief Initializes the background NPC configuration + * + * @param index Lane index + */ +void RPBowBackgroundNpcManager::InitializeConfig(int index) { + mConfigIndex = index; + + gBackgroundNpcParams.laneZPositions[0] = 92.0f; + gBackgroundNpcParams.laneZPositions[1] = 99.0f; + gBackgroundNpcParams.laneZPositions[2] = 106.0f; + gBackgroundNpcParams.laneZPositions[3] = 113.0f; + + gBackgroundNpcParams.basePosY = 3.85f; + gBackgroundNpcParams.seatedPosY = 2.0f; + gBackgroundNpcParams.mirroredModelZOffset = 6.5f; + gBackgroundNpcParams.patrolMinX = -120.0f; + gBackgroundNpcParams.patrolMaxX = 120.0f; + gBackgroundNpcParams.minWalkSpeed = 0.07f; + gBackgroundNpcParams.maxWalkSpeed = 0.25f; + + gBackgroundNpcParams.dormantToPatrolChanceDenom = 200; + gBackgroundNpcParams.patrolToIdleChanceDenom = 400; + gBackgroundNpcParams.idleToPatrolChanceDenom = 300; + + gBackgroundNpcParams.turnLerpRate = 0.05f; + gBackgroundNpcParams.idleCenterZoneX = 70.0f; + + gBackgroundNpcParams.minStateDuration = 120; +} + +/** + * @brief Sets the model groups for the manager + * + * @param managerIndex Manager index + * @param pModelGroup0 First model group + * @param pModelGroup1 Second model group + */ +void RPBowBackgroundNpcManager::SetModelGroups(int managerIndex, NpcModelGroup* pModelGroup0, NpcModelGroup* pModelGroup1) { + mModelGroups[managerIndex][0] = pModelGroup0; + mModelGroups[managerIndex][1] = pModelGroup1; +} + +/** + * @brief Unknown stub + */ +void RPBowBackgroundNpcManager::fn_8034E83C() { + ; +} + +/** + * @brief Resets the manager state + */ +void RPBowBackgroundNpcManager::Reset() { + mModelGroupSet = 0; + *(volatile int*)&mMovement.animationState = -1; + *(volatile int*)&mMovement.animationState = 0; + + for (int i = 0; i < 2; i++) { + NpcModelGroup* pGroup = mModelGroups[mModelGroupSet][i]; + RPGrpModelAnm* pAnimation = RPGrpModelAccessor::GetModelAnm(pGroup->mModelA8); + pAnimation->StartBlend(RPGrpModelAnm::Anm_Chr, 0, 60.0f, 0.0f); + } + + memset(&mMovement, 0, 0x30); + + mMovement.behaviorState = 0; + mMovement.stateTimer = -1; + + fn_8034CFC4(&mIdleState, 999, 0); + unk_0x94 = 0; + + for (int j = 0; j < 600; j++) { + UpdateMovement(nullptr, nullptr); + } + + lbl_804BF9F8 = 0; +} + +/** + * @brief Updates the movement state and calculates position + * + * @param pOutPosition[out] Output position + * @param pOutStateFlag[out] Output state flag + */ +void RPBowBackgroundNpcManager::UpdateMovement(nw4r::math::VEC3* pOutPosition, bool* pOutStateFlag) { + bool stateFlag = true; + BackgroundNpcConfig* pConfig = &gBackgroundNpcParams; + + if (mMovement.stateTimer < 0) { + mMovement.stateTimer = 0; + } + + nw4r::math::VEC3 localVec(0.0f, 0.0f, 0.0f); + + switch (mMovement.behaviorState) { + case 0: + { + if (RPUtlRandom::getU32(pConfig->dormantToPatrolChanceDenom) == 0) { + mModelGroupSet = RPUtlRandom::getU32(2); + if (mModelGroupSet >= 2) { + mModelGroupSet = 1; + } + mMovement.animationState = -1; + mMovement.behaviorState = 1; + mMovement.stateTimer = -1; + } + stateFlag = false; + break; + } + + case 1: + { + if (mMovement.stateTimer == 0) { + f32 walkSpeed = pConfig->minWalkSpeed + RPUtlRandom::getF32() * (pConfig->maxWalkSpeed - pConfig->minWalkSpeed); + if (RPUtlRandom::getU32(2) == 0) { + walkSpeed *= -1.0f; + } + + mMovement.velocity.x = walkSpeed; + mMovement.velocity.y = 0.0f; + mMovement.velocity.z = 0.0f; + + if (walkSpeed < 0.0f) { + mMovement.position.x = pConfig->patrolMaxX; + } else { + mMovement.position.x = pConfig->patrolMinX; + } + + mMovement.position.y = pConfig->basePosY; + mMovement.position.z = pConfig->laneZPositions[mConfigIndex]; + } + + if (mMovement.animationState != 1) { + mMovement.animationState = 1; + for (int i = 0; i < 2; i++) { + NpcModelGroup* pGroup = mModelGroups[mModelGroupSet][i]; + RPGrpModelAnm* pAnimation = RPGrpModelAccessor::GetModelAnm(pGroup->mModelA8); + + pAnimation->StartBlend(RPGrpModelAnm::Anm_Chr, 1, 60.0f, 0.0f); + } + } + + if (std::fabs(mMovement.position.x) < pConfig->idleCenterZoneX && (int)pConfig->minStateDuration < mMovement.stateTimer) { + if (RPUtlRandom::getU32(pConfig->patrolToIdleChanceDenom) == 0) { + mMovement.behaviorState = 2; + mMovement.stateTimer = -1; + } + } + + f32 targetAngle; + if (mMovement.velocity.x < 0.0f) { + targetAngle = 270.0f; + } else { + targetAngle = 90.0f; + } + + mMovement.rotation.y += pConfig->turnLerpRate * (targetAngle - mMovement.rotation.y); + mMovement.position += mMovement.velocity; + + if (mMovement.position.x < pConfig->patrolMinX || mMovement.position.x > pConfig->patrolMaxX) { + mMovement.behaviorState = 0; + mMovement.stateTimer = -1; + } + break; + } + + case 2: + { + if (mMovement.stateTimer == 0) { + mIdleState.sub.field_0x2C = true; + mIdleState.sub.unk_0x8 = lbl_804BF9F4; + } + + if (mMovement.animationState != 0) { + mMovement.animationState = 0; + for (int i = 0; i < 2; i++) { + NpcModelGroup* pGroup = mModelGroups[mModelGroupSet][i]; + RPGrpModelAnm* pAnimation = RPGrpModelAccessor::GetModelAnm(pGroup->mModelA8); + + pAnimation->StartBlend(RPGrpModelAnm::Anm_Chr, 0, 60.0f, 0.0f); + } + } + + NpcIdleStateSub* pRet = fn_8034C95C(&mIdleState); + localVec = pRet->pos; + mMovement.rotation.y += pRet->rotationSpeed * (pRet->targetRotation - mMovement.rotation.y); + + if ((int)pConfig->minStateDuration < mMovement.stateTimer) { + if (RPUtlRandom::getU32(pConfig->idleToPatrolChanceDenom) == 0) { + mMovement.behaviorState = 1; + mMovement.stateTimer = 0; + + f32 walkSpeed = pConfig->minWalkSpeed + RPUtlRandom::getF32() * (pConfig->maxWalkSpeed - pConfig->minWalkSpeed); + if (RPUtlRandom::getU32(2) == 0) { + walkSpeed *= -1.0f; + } + mMovement.velocity.x = walkSpeed; + } + } + break; + } + } + + mMovement.stateTimer++; + + if (pOutPosition != nullptr) { + *pOutPosition = localVec; + } + if (pOutStateFlag != nullptr) { + *pOutStateFlag = stateFlag; + } +} + +//! Gets the face model +#define GET_FACE(pKokeshi) ((pKokeshi)->mModelA4) +//! Gets the body model +#define GET_BODY(pKokeshi) ((pKokeshi)->mModelA8) +//! Gets the left hand model +#define GET_LHAND(pKokeshi) ((pKokeshi)->mModelAC) +//! Gets the right hand model +#define GET_RHAND(pKokeshi) ((pKokeshi)->mModelB0) + +/** + * @brief Renders the background NPC + */ +void RPBowBackgroundNpcManager::Render() { + bool stateFlag = true; + nw4r::math::VEC3 position(0.0f, 0.0f, 0.0f); + BackgroundNpcConfig* pConfig = &gBackgroundNpcParams; + + UpdateMovement(&position, &stateFlag); + + if (!stateFlag || !unk_0x94) { + return; + } + + nw4r::math::MTX34 mtx; + nw4r::math::MTX34Identity(&mtx); + + position += mMovement.position; + if (lbl_804BF9F8 != 0) { + position.y += pConfig->seatedPosY - pConfig->basePosY; + } + + nw4r::math::MTX34Trans(&mtx, &position, &mtx); + + nw4r::math::MTX34 mtx2; + nw4r::math::MTX34RotXYZDeg(&mtx2, mMovement.rotation.x, mMovement.rotation.y, mMovement.rotation.z); + + nw4r::math::MTX34Mult(&mtx, &mtx, &mtx2); + + nw4r::math::VEC3 scale(0.7f, 0.7f, 0.7f); + nw4r::math::MTX34 mtx3 = mtx; + + mtx3._10 *= -1.0f; + mtx3._11 *= -1.0f; + mtx3._12 *= -1.0f; + mtx3._13 *= -1.0f; + mtx3._13 += pConfig->mirroredModelZOffset; + + for (int i = 0; i < 2; i++) { + NpcModelGroup* pGroup = mModelGroups[mModelGroupSet][i]; + + nw4r::math::MTX34 leftHandMtx; + nw4r::math::MTX34 rightHandMtx; + nw4r::math::MTX34 headMtx; + + if (GET_BODY(pGroup)->GetScnObj() != nullptr) { + GET_BODY(pGroup)->GetScnObj()->SetMtx(nw4r::g3d::ScnObj::MTX_LOCAL, i == 0 ? &mtx : &mtx3); + } + RPGrpModelAccessor::SetScale(GET_BODY(pGroup), scale); + GET_BODY(pGroup)->UpdateFrame(); + GET_BODY(pGroup)->Calc(); + + RPSysKokeshi* pKokeshi = reinterpret_cast(pGroup); + pKokeshi->GetHeadJointMtx(reinterpret_cast(&headMtx)); + pKokeshi->GetLeftHandJointMtx(reinterpret_cast(&leftHandMtx)); + pKokeshi->GetRightHandJointMtx(reinterpret_cast(&rightHandMtx)); + + if (i != 0) { + nw4r::math::MTX34 flipMtx( + -1.0f, 0.0f, 0.0f, 0.0f, + 0.0f, 1.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 1.0f, 0.0f + ); + nw4r::math::MTX34Mult(&headMtx, &headMtx, &flipMtx); + } + + if (GET_FACE(pGroup)->GetScnObj() != nullptr) { + GET_FACE(pGroup)->GetScnObj()->SetMtx(nw4r::g3d::ScnObj::MTX_LOCAL, &headMtx); + } + RPGrpModelAccessor::SetScale(GET_FACE(pGroup), scale); + GET_FACE(pGroup)->UpdateFrame(); + GET_FACE(pGroup)->Calc(); + + if (GET_LHAND(pGroup)->GetScnObj() != nullptr) { + GET_LHAND(pGroup)->GetScnObj()->SetMtx(nw4r::g3d::ScnObj::MTX_LOCAL, &leftHandMtx); + } + RPGrpModelAccessor::SetScale(GET_LHAND(pGroup), scale); + GET_LHAND(pGroup)->UpdateFrame(); + GET_LHAND(pGroup)->Calc(); + + if (GET_RHAND(pGroup)->GetScnObj() != nullptr) { + GET_RHAND(pGroup)->GetScnObj()->SetMtx(nw4r::g3d::ScnObj::MTX_LOCAL, &rightHandMtx); + } + RPGrpModelAccessor::SetScale(GET_RHAND(pGroup), scale); + GET_RHAND(pGroup)->UpdateFrame(); + GET_RHAND(pGroup)->Calc(); + + if (i == 1 && !lbl_804BF9F8) { + break; + } + + GET_BODY(pGroup)->Entry(); + GET_FACE(pGroup)->Entry(); + GET_LHAND(pGroup)->Entry(); + GET_RHAND(pGroup)->Entry(); + } +} + +/** + * @brief Unknown stub + */ +void RPBowBackgroundNpcManager::fn_8034DD14() { + ; +} + +/** + * @brief Unknown stub + */ +void RPBowBackgroundNpcManager::fn_8034DD0C() { + ; +} + +/** + * @brief Unknown stub + */ +void RPBowBackgroundNpcManager::fn_8034DD08() { + ; +} + +} // namespace Bowling diff --git a/src/Pack/RPSports/RPBowScene/RPBowBallReturnRack.cpp b/src/Pack/RPSports/RPBowScene/RPBowBallReturnRack.cpp new file mode 100644 index 000000000..2cb12a4a8 --- /dev/null +++ b/src/Pack/RPSports/RPBowScene/RPBowBallReturnRack.cpp @@ -0,0 +1,276 @@ +#include +#include + +namespace Bowling { + +// Extern Functions +int fn_801C3490(int arg0, float arg1, void* pArg2); +u32 fn_801C389C(RPGrpModel* pModel, int arg1, int arg2); +void fn_801C37EC(RPGrpModel* pModel, int arg1, int arg2, void* pColor); + +/** + * @brief Initializes physics constants + * + * @param index Rack index + */ +void RPBowBallReturnRack::InitBallReturnRack(s32 index) { + mRackIndex = index; + + gBallReturnRackConstants.mPositionOffsets[0] = nw4r::math::VEC3( -25.0f, 3.5f, 33.3f ); + gBallReturnRackConstants.mPositionOffsets[1] = nw4r::math::VEC3( 8.8f, 3.5f, 33.3f ); + gBallReturnRackConstants.mPositionOffsets[2] = nw4r::math::VEC3( -58.5f, 3.5f, 33.3f ); + gBallReturnRackConstants.mPositionOffsets[3] = nw4r::math::VEC3( 42.4f, 3.5f, 33.3f ); + + gBallReturnRackConstants.mHeightLimit = 11.700001f; + gBallReturnRackConstants.mRepulsionThreshold = 1.075f; + gBallReturnRackConstants.mGravity = 0.0012f; +} + +/** + * @brief Initializes the resources associated with a ball slot + * + * @param index Rack index + * @param pRealModel Graphical model of the ball + * @param pReflectionModel Reflection model of the ball + * @param slotIndex Ball slot index mapping + */ +void RPBowBallReturnRack::InitBallSlotResources(s32 index, RPGrpModel* pRealModel, RPGrpModel* pReflectionModel, s32 slotIndex) { + mModels[index + 1].pRealModel = pRealModel; + mModels[index + 1].pReflectionModel = pReflectionModel; + + mSlotIndices[index] = slotIndex; +} + +/** + * @brief Sets up the graphical models for all of the NPC balls + */ +void RPBowBallReturnRack::ResetRackBallStates() { + BallReturnBall* pBall; + BallReturnRackConstants* pConstants = &gBallReturnRackConstants; + + pBall = mBalls; + for (int i = 0; i < 4; i++, pBall++) { + memset(pBall, 0, sizeof(BallReturnBall)); + + pBall->mIsOnRack = true; + + pBall->mPos.z = pConstants->mHeightLimit - (2.0f * ((float)(i + 1) * pConstants->mRepulsionThreshold)); + } +} + +/** + * @brief Selects an available ball from the rack for an NPC to use on their turn + * + * @return The index of the selected ball, or -1 if no balls are available + */ +int RPBowBallReturnRack::SelectBallForNPC() { + int indices[4]; + indices[0] = 0; + indices[1] = 1; + indices[2] = 2; + indices[3] = 3; + + for (int i = 0; i < 3; i++) { + for (int j = i + 1; j < 4; j++) { + if (mBalls[indices[i]].mPos.z < mBalls[indices[j]].mPos.z) { + int temp = indices[i]; + indices[i] = indices[j]; + indices[j] = temp; + } + } + } + + u32 randVal = (u32)(RPUtlRandom::getF32() * 3.0f); + int result = indices[randVal]; + + if (mBalls[result].mClaimedByNPC != 0 || mBalls[result].mIsOnRack == 0) { + result = -1; + } + + int* pIndex = indices; + int i = 0; + + while (i < 4 && result == -1) { + if (mBalls[*pIndex].mClaimedByNPC == 0 && mBalls[*pIndex].mIsOnRack != 0) { + result = indices[i]; + break; + } + pIndex++; + i++; + } + + if (result != -1) { + mBalls[result].mClaimedByNPC = 1; + return result; + } + return -1; +} + +/** + * @brief Removes the ball from rack physics calculations and rendering + * + * @param index Ball index + */ +void RPBowBallReturnRack::RemoveBallFromRack(s32 index) { + mBalls[index].mIsOnRack = 0; +} + +/** + * @brief Tests whether a specific ball slot currently has a ball resting on the rack + * + * @param index Ball index + * @return Non-zero if the ball is resting on the rack, 0 otherwise + */ +u8 RPBowBallReturnRack::IsBallOnRack(s32 index) { + return mBalls[index].mIsOnRack; +} + +/** + * @brief Spawns or resets a ball at the beginning of the return rack track + * + * @param index Ball index + */ +void RPBowBallReturnRack::SpawnBallOnRack(s32 index) { + mBalls[index].mPos.z = 0.0f; + mBalls[index].mClaimedByNPC = 0; + mBalls[index].mIsOnRack = 1; + mBalls[index].mAngle = 0.0f; +} + +/** + * @brief Removes an NPC's reservation of a ball + * + * @param index Ball index + */ +void RPBowBallReturnRack::ReleaseBallFromNPC(s32 index) { + mBalls[index].mClaimedByNPC = 0; +} + +/** + * @brief Retrieves the default slot index mapping for the rack + * + * @param index Ball index + * @return Default slot index mapping + */ +s32 RPBowBallReturnRack::GetBallSlotIndex(s32 index) { + return mSlotIndices[index]; +} + +/** + * @brief Main update function for the bowling scene entities + * + * @param index Rack index + */ +void RPBowBallReturnRack::UpdateBallReturnRack(s32 index) { + BallReturnBall* pBall; + RPGrpModelPair* pModelPair; + BallReturnRackConstants* pConstants = &gBallReturnRackConstants; + + // Part 1: Calculate repulsive forces between entities + for (int i = 0; i < 4; i++) { + mBalls[i].mRepulsionForce = 0.0f; + } + + for (int i = 0; i < 3; i++) { + if (!mBalls[i].mIsOnRack) continue; + + for (int j = i + 1; j < 4; j++) { + if (!mBalls[j].mIsOnRack) continue; + + f32 distI = mBalls[i].mPos.z; + f32 distJ = mBalls[j].mPos.z; + f32 distDiff = __fabs(distI - distJ); + + if (distDiff < pConstants->mRepulsionThreshold * 2.0f) { + f32 force = (pConstants->mRepulsionThreshold * 2.0f) - distDiff; + if (distI < distJ) { + mBalls[i].mRepulsionForce += -force; + mBalls[i].mSpeed = 0.0f; + } else { + mBalls[j].mRepulsionForce += -force; + mBalls[j].mSpeed = 0.0f; + } + } + } + } + + // Part 2: Update physics and models for each entity + pModelPair = &mModels[0]; + pBall = mBalls; + + for (int i = 0; i < 4; i++, pModelPair++, pBall++) { + if (!pBall->mIsOnRack) continue; + + f32 oldZ = pBall->mPos.z; + pBall->mSpeed += pConstants->mGravity; + pBall->mPos.z += pBall->mSpeed + pBall->mRepulsionForce; + + if (pBall->mPos.z > pConstants->mHeightLimit) { + pBall->mPos.z = pConstants->mHeightLimit; + pBall->mSpeed = 0.0f; + } + + f32 limit = 6.28318f * pConstants->mRepulsionThreshold; + f32 diff = pBall->mPos.z - oldZ; + f32 delta = diff / limit; + + pBall->mAngle += 6.28318f * delta; + + nw4r::math::VEC3 worldPos = pBall->mPos + pConstants->mPositionOffsets[mRackIndex]; + + nw4r::math::MTX34 ballMtx, rotMtx; + MTX34Identity(&ballMtx); + MTX34Trans(&ballMtx, &worldPos, &ballMtx); + + nw4r::math::MTX34RotXYZFIdx(&rotMtx, 40.743664f * pBall->mAngle, 0.0f, 0.0f); + PSMTXConcat(ballMtx, rotMtx, ballMtx); + + nw4r::g3d::ScnObj* pRealScnObj = pModelPair[1].pRealModel->GetScnObj(); + if (pRealScnObj != NULL) { + pRealScnObj->SetMtx(nw4r::g3d::ScnObj::MTX_LOCAL, &ballMtx); + } + + pModelPair[1].pRealModel->UpdateFrame(); + pModelPair[1].pRealModel->Calc(); + + if (fn_801C3490(index, pConstants->mRepulsionThreshold, &worldPos) != 0) { + u32 colorVal = fn_801C389C(pModelPair[1].pRealModel, 0, 0); + + GXColor color; + GXColor temp; + temp.r = colorVal >> 24; + temp.g = colorVal >> 16; + temp.b = colorVal >> 8; + temp.a = 255; + color = temp; + + fn_801C37EC(pModelPair[1].pRealModel, 0, 0, &color); + pModelPair[1].pRealModel->Entry(); + } + + nw4r::math::MTX34 reflectionMtx = ballMtx; + reflectionMtx.m[1][0] *= -1.0f; + reflectionMtx.m[1][1] *= -1.0f; + reflectionMtx.m[1][2] *= -1.0f; + reflectionMtx.m[1][3] *= -1.0f; + + nw4r::g3d::ScnObj* pReflScnObj = pModelPair[1].pReflectionModel->GetScnObj(); + if (pReflScnObj != NULL) { + pReflScnObj->SetMtx(nw4r::g3d::ScnObj::MTX_LOCAL, &reflectionMtx); + } + + pModelPair[1].pReflectionModel->UpdateFrame(); + pModelPair[1].pReflectionModel->Calc(); + + nw4r::math::VEC3 reflPosFinal; + reflPosFinal.x = reflectionMtx.m[0][3]; + reflPosFinal.y = reflectionMtx.m[1][3]; + reflPosFinal.z = reflectionMtx.m[2][3]; + + if (fn_801C3490(index, pConstants->mRepulsionThreshold, &reflPosFinal) != 0) { + pModelPair[1].pReflectionModel->Entry(); + } + } +} + +} // namespace Bowling diff --git a/src/Pack/RPSports/RPBowScene/RPBowGlobalLaneManager.cpp b/src/Pack/RPSports/RPBowScene/RPBowGlobalLaneManager.cpp new file mode 100644 index 000000000..c54a92b12 --- /dev/null +++ b/src/Pack/RPSports/RPBowScene/RPBowGlobalLaneManager.cpp @@ -0,0 +1,227 @@ +#include + +namespace Bowling { + +/** + * @brief Pin target offsets + * @details Controls where the triangle of pins is set up. + */ +float gLaneXOffsets[8] = { + 0, + -16.1, + 17.6, + -33.75, + 33.6, + -49.85, + 51.15, + 0 +}; + +// Extern Functions +void ResetPinSetterState(LaneContext* pLane, u8 arg); +void fn_80327330(LaneContext* pLane, PinStatus* pStatus); +nw4r::math::MTX34* fn_80316A48(SomeUnkManager0* pSomeMgr, void* pObj, int val); +void fn_8034EADC(void* pArrEntry, int validCount, nw4r::math::MTX34* pResultMtx, nw4r::math::MTX34* pMtx, bool flag); +void fn_8034E974(void* pArrEntry, int validCount); +void fn_80327218(LaneContext* pLane); +void fn_803277B4(LaneContext* pLane); +void fn_803295D0(LaneBvhData* pBvhData, void* pArg1, void* pArg2); +void fn_80325154(LaneContext* pLane); + +/** + * @brief Tests whether the ball's X position falls inside the hit-box radius of any lane boundary + * + * @param pBallXPos Ball's X position + * @param radius Hit-box radius + * @return True if the ball intersects with a lane boundary, false otherwise + */ +bool CheckBallLaneIntersection(float* pBallXPos, float radius) { + for (int i = 0; i < 7; i++) { + if (*pBallXPos > gLaneXOffsets[i] - radius && *pBallXPos < radius + gLaneXOffsets[i]) { + return true; + } + } + return false; +} + +/** + * @brief Initializes the context state and logic for all 7 lanes + */ +void RPBowGlobalLaneManager::InitializeBallManagerLanes() { + for (int i = 0; i < 7; i++) { + fn_803277B4(pLanes[i]); + } +} + +/** + * @brief Submits parameters to setup secondary components attached to each lane and flags the manager as initialized + * + * @param pArg1 First setup parameter + * @param pArg2 Second setup parameter + */ +void RPBowGlobalLaneManager::SetupBallManagerLaneObjects(void* pArg1, void* pArg2) { + for (int i = 0; i < 7; i++) { + fn_803295D0(pLanes[i]->pLaneBvhData, pArg1, pArg2); + } + isInitialized = 1; +} + +/** + * @brief Resets the pin layout mask to a fresh set of 10 standing pins for all 7 lanes + */ +void RPBowGlobalLaneManager::ResetLanePinsAndAnimations() { + for (int i = 0; i < 7; i++) { + LaneContext* pLane = pLanes[i]; + PinStatus status; + status.pinBits[3] = -1; + status.pinBits[2] = -1; + status.pinBits[1] = -1; + status.pinBits[0] = -1; + status.pinCount = 10; + + fn_80327330(pLane, &status); + ResetPinSetterState(pLanes[i], 0); + } + field_0x21 = 0; +} + +/** + * @brief Pushes target state updates to all lanes + * + * @param value Target state value + */ +void RPBowGlobalLaneManager::SetLaneUnknownState(int value) { + for (int i = 0; i < 7; i++) { + pLanes[i]->laneStateTarget = value; + } +} + +/** + * @brief Ensures lane position offsets are correctly pushed to memory + * @details Computes ball physics on NPC lanes, and skips computing it on the player lane unless conditions dictate otherwise. + */ +void RPBowGlobalLaneManager::UpdateBallsPhysics() { + for (int i = 0; i < 7; i++) { + pLanes[i]->laneXOffset = gLaneXOffsets[i]; + if (i != 0 || field_0x21 == 0) { + fn_80327218(pLanes[i]); + } + } +} + +/** + * @brief Executes a sub-tick physics/state update on the player lane and all 6 NPC lanes + */ +void RPBowGlobalLaneManager::TickNpcLanes() { + for (int i = 0; i < 7; i++) { + fn_80325154(pLanes[i]); + } +} + +/** + * @brief Iterates the 7 lane item arrays to synthesize their 3D world space transforms and registers them back into the game engine's scene + * + * @param val Unknown integer value + * @param pObj Pointer to an object + * @param pSomeMgr Manager object + * @param isPlayerTurn Indicates if it is currently the player's turn + */ +void RPBowGlobalLaneManager::UpdateLaneItems(int val, void* pObj, SomeUnkManager0* pSomeMgr, bool isPlayerTurn) { + if (isInitialized == 0) return; + + nw4r::math::MTX34* pResultMtx = fn_80316A48(pSomeMgr, pObj, val); + + for (int i = 0; i < 7; i++) { + void* pArrEntry = pSomeMgr->arr[i]; + int validCount = 0; + + for (int j = 0; j < 10; j++) { + LaneContext* pLane = pLanes[i]; + int limit = pLane->pinCount; + u8 isValid; + + if (j >= limit) { + isValid = 0; + } else { + PinPhysicsBody* pBody = pLane->pPinManager->pPinBodies[j]; + isValid = pBody->isActive; + } + + if (isValid != 0) { + nw4r::math::MTX34 mtx; + nw4r::math::MTX34* pMtx; + + if (j >= limit) { + nw4r::math::MTX34 mtxTemp; + MTX34Identity(&mtxTemp); + mtx = mtxTemp; + pMtx = &mtx; + } else { + PinPhysicsBody* pBody = pLane->pPinManager->pPinBodies[j]; + pMtx = &mtx; + + f32 t23 = pBody->position.z; + f32 t22 = pBody->basisZ.z; + f32 t21 = pBody->basisZ.y; + f32 t20 = pBody->basisZ.x; + f32 t13 = pBody->position.y; + f32 t12 = pBody->basisY.z; + f32 t11 = pBody->basisY.y; + f32 t10 = pBody->basisY.x; + f32 t03 = pBody->position.x; + f32 t02 = pBody->basisX.z; + f32 t01 = pBody->basisX.y; + // f32 t00 = pBody->basisX.x; + + mtx._00 = pBody->basisX.x; + mtx._01 = t01; + mtx._02 = t02; + mtx._03 = t03; + mtx._10 = t10; + mtx._11 = t11; + mtx._12 = t12; + mtx._13 = t13; + mtx._20 = t20; + mtx._21 = t21; + mtx._22 = t22; + mtx._23 = t23; + } + + bool flag = false; + if (i == 0 && isPlayerTurn != 0) { + flag = true; + } + + pLanes[i]->VF_0x14(); + + fn_8034EADC(pArrEntry, validCount, pResultMtx, pMtx, flag); + validCount++; + } + } + fn_8034E974(pArrEntry, validCount); + } +} + +/** + * @brief Applies physics matrix translations onto the game's ball models + * @details Also artificially moves the ball out of view bounds (y = 9999.0f) if it falls completely below the floor bounds. + * + * @param pBallMgr Scene object manager for balls + */ +void RPBowGlobalLaneManager::UpdateBallsMdl(SceneObjectManager* pBallMgr) { + for (int i = 0; i < 7; i++) { + LaneContext* pLane = pLanes[i]; + RPBowActiveBall* pBall = pBallMgr->entities.balls[i]; + + nw4r::math::MTX34 mtx = pLane->throwContext.ballMtx; + if (mtx._23 < -210.0f) { + mtx._23 = 9999.0f; + } + + float field_110 = gBowlingPhysicsData.field_110; + pBall->mtx = mtx; + pBall->field_0x74 = field_110; + } +} + +} // namespace Bowling diff --git a/src/Pack/RPSports/RPBowScene/RPBowManagerContext.cpp b/src/Pack/RPSports/RPBowScene/RPBowManagerContext.cpp new file mode 100644 index 000000000..02bd481d7 --- /dev/null +++ b/src/Pack/RPSports/RPBowScene/RPBowManagerContext.cpp @@ -0,0 +1,107 @@ +#include +#include + +namespace Bowling { + +struct WeightedLanes { + u8 data[15]; +}; + +static const WeightedLanes sTargetLaneWeights = {{ + 0x00, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x01, 0x01, 0x01, 0x02, + 0x02, 0x03, 0x03, 0x04, 0x05 +}}; + +/** + * @brief Initializes the manager context and its sub-managers + */ +void RPBowManagerContext::Initialize() { + for (int i = 0; i < 6; i++) { + mpManagers[i] = new RPBowNpcManager(); + mpManagers[i]->InitAudioActors(i); + } + mIsEnabled = 0; +} + +/** + * @brief Links NPC lanes to ball returns and balls + * + * @param pLaneManager Global lane manager instance + * @param pSceneObjectManager Scene object manager instance + */ +void RPBowManagerContext::LinkNpcLanes(RPBowGlobalLaneManager* pLaneManager, SceneObjectManager* pSceneObjectManager) { + for (int i = 0; i < 6; i++) { + const int sBallReturnMapping[] = { 0, 1, 0, 3, 2, 3 }; + + mpManagers[i]->Setup( + pLaneManager->pLanes[i + 1], + pSceneObjectManager->entities.npcs[i * 3 + 0], + pSceneObjectManager->entities.npcs[i * 3 + 1], + pSceneObjectManager->entities.npcs[i * 3 + 2], + i, + pSceneObjectManager->entities.ballReturns[sBallReturnMapping[i]], + pSceneObjectManager->entities.balls[i + 1] + ); + } +} + +/** + * @brief Sets the state flag for all NPC managers + * + * @param flag Status value applied to each NPC manager + */ +void RPBowManagerContext::SetNpcStateFlags(u8 flag) { + for (int i = 0; i < 6; i++) { + mpManagers[i]->SetStateFlag(flag); + } +} + +/** + * @brief Updates the six NPC bowling lanes and starts a new NPC turn if permitted + * + * @details Lanes closer to the player are heavily preferred when a new NPC is activated. + * A maximum of 2 NPCs are allowed to be active at once. New NPCs have a 1-in-180 chance to start per frame. + */ +void RPBowManagerContext::UpdateNpcs() { + int activeCount = 0; + + for (int i = 0; i < 6; i++) { + mpManagers[i]->Update(); + + if (mpManagers[i]->IsLaneIdle() == 0) { + activeCount++; + } + } + + if (activeCount >= 2) { + return; + } + + int targetLane = -1; + + if ((RPUtlRandom::getU32() % 180) == 0) { + WeightedLanes weightedLanes = sTargetLaneWeights; + u32 idx = (u32)(RPUtlRandom::getF32() * 15.0f); + targetLane = weightedLanes.data[idx]; + } + + if (targetLane != -1) { + if (mpManagers[targetLane]->IsLaneIdle() != 0) { + mpManagers[targetLane]->ActivateNpcTurn(); + } + } +} + +/** + * @brief Prints debug information for all NPC managers + */ +void RPBowManagerContext::DebugPrintStates() { + if (mIsEnabled != 0) { + for (int i = 0; i < 6; i++) { + mpManagers[i]->DebugPrintNpcState(); + } + } +} + +} // namespace Bowling diff --git a/src/Pack/RPSports/RPBowScene/RPBowMotionBlur.cpp b/src/Pack/RPSports/RPBowScene/RPBowMotionBlur.cpp new file mode 100644 index 000000000..5337a8c93 --- /dev/null +++ b/src/Pack/RPSports/RPBowScene/RPBowMotionBlur.cpp @@ -0,0 +1,110 @@ +#include + +namespace Bowling { + +// Appears to check frustum culling +extern bool fn_801C3490(void* pCullingCtx, const nw4r::math::VEC3* pos, f32 radius); + +/** + * @brief Destructor + */ +RPBowMotionBlur::~RPBowMotionBlur() {} + +/** + * @brief Sets the models used for the motion blur effect + * + * @param pReal1 Real model 1 + * @param pReal2 Real model 2 + * @param pReal3 Real model 3 + * @param pRefl1 Reflection model 1 + * @param pRefl2 Reflection model 2 + * @param pRefl3 Reflection model 3 + */ +void RPBowMotionBlur::SetBlurModels(RPGrpModel* pReal1, RPGrpModel* pReal2, RPGrpModel* pReal3, RPGrpModel* pRefl1, RPGrpModel* pRefl2, RPGrpModel* pRefl3) { + models[0].pRealModel = pReal1; + models[0].pReflectionModel = pRefl1; + models[1].pRealModel = pReal2; + models[1].pReflectionModel = pRefl2; + models[2].pRealModel = pReal3; + models[2].pReflectionModel = pRefl3; +} + +/** + * @brief Deactivates the motion blur effect + */ +void RPBowMotionBlur::DeactivateBlur() { + isActive = false; +} + +/** + * @brief Updates the transform matrices for the motion blur + * + * @param pBaseMtx Base transform matrix + * @param blurSpeed Speed of the blur effect + */ +void RPBowMotionBlur::UpdateBlurTransform(const nw4r::math::MTX34* pBaseMtx, f32 blurSpeed) { + if (blurSpeed > 0.001f) { + isActive = true; + } else { + isActive = false; + return; + } + + f32 stretchFactor = (blurSpeed * 2.0f) / 5.267f; + + blurMtxs[2] = *pBaseMtx; + blurMtxs[1] = *pBaseMtx; + blurMtxs[0] = *pBaseMtx; + + blurMtxs[0]._03 -= pBaseMtx->_00 * blurSpeed; + blurMtxs[0]._13 -= pBaseMtx->_10 * blurSpeed; + blurMtxs[0]._23 -= pBaseMtx->_20 * blurSpeed; + + blurMtxs[2]._03 += pBaseMtx->_00 * blurSpeed; + blurMtxs[2]._13 += pBaseMtx->_10 * blurSpeed; + blurMtxs[2]._23 += pBaseMtx->_20 * blurSpeed; + + blurMtxs[1]._00 *= stretchFactor; + blurMtxs[1]._10 *= stretchFactor; + blurMtxs[1]._20 *= stretchFactor; + + speed = blurSpeed; +} + +/** + * @brief Renders the motion blur models + * + * @param pCullingCtx Frustum culling context + */ +void RPBowMotionBlur::DrawBlur(void* pCullingCtx) { + if (!isActive) { + return; + } + + nw4r::math::VEC3 pos(blurMtxs[1]._03, blurMtxs[1]._13, blurMtxs[1]._23); + if (!fn_801C3490(pCullingCtx, &pos, speed * 2.0f)) { + return; + } + + for (int i = 0; i < 3; i++) { + if (models[i].pRealModel->GetScnObj() != NULL) { + models[i].pRealModel->GetScnObj()->SetMtx(nw4r::g3d::ScnObj::MTX_LOCAL, &blurMtxs[i]); + } + models[i].pRealModel->Calc(); + models[i].pRealModel->Entry(); + + nw4r::math::MTX34 reflectionMtx = blurMtxs[i]; + reflectionMtx._10 *= -1.0f; + reflectionMtx._11 *= -1.0f; + reflectionMtx._12 *= -1.0f; + reflectionMtx._13 *= -1.0f; + + if (models[i].pReflectionModel->GetScnObj() != NULL) { + models[i].pReflectionModel->GetScnObj()->SetMtx(nw4r::g3d::ScnObj::MTX_LOCAL, &reflectionMtx); + } + models[i].pReflectionModel->Calc(); + models[i].pReflectionModel->Entry(); + } +} + +} // namespace Bowling diff --git a/src/Pack/RPSports/RPBowScene/RPBowNpcManager.cpp b/src/Pack/RPSports/RPBowScene/RPBowNpcManager.cpp new file mode 100644 index 000000000..417dbcb33 --- /dev/null +++ b/src/Pack/RPSports/RPBowScene/RPBowNpcManager.cpp @@ -0,0 +1,115 @@ +#include + +extern "C" int rand(); + +namespace Bowling { + +// Extern functions: +void fn_80334270(NpcContext* pContext); +void InitNpcContext(NpcContext* pContext, int laneIdx, int npcIdx); + +/** + * @brief Initializes audio-related structures for the manager + * @details Allocates memory for sound actors and configures 3D audio settings. + * + * @param laneIdx Index of the lane + */ +// void RPBowNpcManager::InitAudioActors(int laneIdx) { +// ; +// } + +/** + * @brief Configures internal pointers and prepares initial contexts + * + * @param pLaneContext Pointer to the lane physics and gameplay context + * @param pNpc0 Pointer to the first NPC object + * @param pNpc1 Pointer to the second NPC object + * @param pNpc2 Pointer to the third NPC object + * @param laneIdx Lane index + * @param pReturnRack Rack containing usable balls + * @param pAudioStruct Pointer to the audio structure + */ +void RPBowNpcManager::Setup(LaneContext* pLaneContext, NpcContext* pNpc0, NpcContext* pNpc1, NpcContext* pNpc2, int laneIdx, RPBowBallReturnRack* pReturnRack, void* pAudioStruct) { + mpNpcs[0] = pNpc0; + mpNpcs[1] = pNpc1; + mpNpcs[2] = pNpc2; + + mpLaneContext = pLaneContext; + mLaneIdx = laneIdx; + mpReturnRack = pReturnRack; + mpSomeAudioStruct = pAudioStruct; + + memset(&mStateId, 0, 12); + + for (int i = 0; i < 3; i++) { + fn_80334270(mpNpcs[i]); + InitNpcContext(mpNpcs[i], mLaneIdx, i); + } + + mpCurrentNpc = mpNpcs[0]; + mCurrentNpcIdx = 0; +} + +/** + * @brief Tests whether the lane is idle + * + * @return 1 if idle, 0 otherwise + */ +int RPBowNpcManager::IsLaneIdle() { + return mStateId == 0; +} + +/** + * @brief Sets the NPC state flag + * + * @param flag Status value applied + */ +void RPBowNpcManager::SetStateFlag(u8 flag) { + mDisableResultSfx = flag; +} + +/** + * @brief Activates a new NPC turn for the lane + * @details Cycles to the next NPC in the lane (0->1->2->0). + */ +void RPBowNpcManager::ActivateNpcTurn() { + memset(&mStateId, 0, 12); + mStateId = 1; + mStateTimer = -1; + mpLaneContext->throwContext.throwState = 0; + + mpCurrentNpc = mpNpcs[mCurrentNpcIdx]; + + int nextIdx = mCurrentNpcIdx; // TODO: remove? + mCurrentNpcIdx = mCurrentNpcIdx + 1; + if (mCurrentNpcIdx == 3) { + mCurrentNpcIdx = 0; + } +} + +// States for RPBowNpcManager::Update() +enum NpcBowlingStates { + NPC_BOWLING_STATE_IDLE = 0, // Inactive, ball hidden off-screen + NPC_BOWLING_STATE_WAIT_PREPARE_LINE = 1, // Walk to approach area, pick up ball + NPC_BOWLING_STATE_PREPARE = 2, // Idle at line, RNG delay before bowling + NPC_BOWLING_STATE_RUN = 3, // Swing and release ball + NPC_BOWLING_STATE_SEE = 4, // Watch ball roll, handle result SFX + NPC_BOWLING_STATE_BACK = 5, // Walk to ball return or back to seat +}; + +/** + * @brief Updates the manager's state machine + */ +// void RPBowNpcManager::Update() { +// ; +// } + +/** + * @brief Prints debug information for this NPC manager + * @details Example string formats: 'NPC[0(1st)] PREPARE phy:0' + */ +// void RPBowNpcManager::DebugPrintNpcState() { +// ; +// } + +} // namespace Bowling diff --git a/src/Pack/RPSports/RPBowScene/RPBowPinSetter.cpp b/src/Pack/RPSports/RPBowScene/RPBowPinSetter.cpp new file mode 100644 index 000000000..ed9fca219 --- /dev/null +++ b/src/Pack/RPSports/RPBowScene/RPBowPinSetter.cpp @@ -0,0 +1,166 @@ +#include + +namespace Bowling { + +#define SWEEPER_BALL_Z_TRIGGER -192.0f +#define SWEEPER_FRAME_LIFT_PINS 0x73 +#define SWEEPER_FRAME_START_SWEEP 0xAF +#define SWEEPER_FRAME_PLACE_PINS 0xF5 +#define SWEEPER_FRAME_END 0x1B8 + +/** + * @brief Resets the pin setter state + * + * @param pContext Lane context + * @param isNewRack Flag indicating if this is a new rack + */ +void ResetPinSetterState(LaneContext* pContext, u8 isNewRack) { + memset(&pContext->setterAnm, 0, 0x10); + pContext->setterAnm.isNewRack = isNewRack; + + PinSetter* pSetter = pContext->pPinSetter; + pSetter->sequencePhase = 0; + pSetter->primaryState = 0; + pSetter->frameTimer = 0.0f; +} + +/** + * @brief Triggers the pin setter animation sequence + * + * @param pContext Lane context + * @param spawnNewRack Flag indicating if a new rack should be spawned + */ +void TriggerPinSetter(LaneContext* pContext, int spawnNewRack) { + if (pContext->setterAnm.sequenceFrameCount == 0) { + pContext->setterAnm.sequenceFrameCount = 1; + if (spawnNewRack != 0) { + pContext->setterAnm.isNewRack = 1; + } + } +} + +/** + * @brief Updates the pin setter state and animations + * + * @param pContext Lane context + * @return 1 on success, otherwise 0 + */ +int UpdatePinSetter(LaneContext* pContext) { + int currentAnimMode = pContext->throwContext.animationMode; + pContext->setterAnm.animOffsetZ = 0.0f; + pContext->setterAnm.animRotationY = -180.5f; + + if (currentAnimMode == 2) { + return 1; + } + + int sequenceFrame = pContext->setterAnm.sequenceFrameCount; + if (sequenceFrame == 0) { + for (int i = 0; i < pContext->pinCount; i++) { + pContext->pPinManager->pPinBodies[i]->mode_0x28C = 0; + } + + float z = pContext->throwContext.ballMtx._23; + float y = pContext->throwContext.ballMtx._13; + float x = pContext->throwContext.ballMtx._03; + nw4r::math::VEC3 ballPos(x, y, z); + + if (ballPos.z < SWEEPER_BALL_Z_TRIGGER) { + pContext->pPinSetter->sequencePhase = 1; + } + return 1; + } + + if (currentAnimMode != 0) { + return 1; + } + + if (sequenceFrame == 1 && pContext->setterAnm.isNewRack == 0) { + pContext->pPinSetter->sequencePhase = 2; + } + + if (pContext->setterAnm.sequenceFrameCount == SWEEPER_FRAME_LIFT_PINS && pContext->setterAnm.isNewRack == 0) { + for (int i = 0; i < pContext->pinCount; i++) { + if (pContext->pPinManager->pPinBodies[i]->unkFlag_0x250 == 0) { + pContext->pPinManager->pPinBodies[i]->mode_0x28C = 1; + } + } + } + + if (pContext->setterAnm.sequenceFrameCount == SWEEPER_FRAME_START_SWEEP) { + pContext->pPinSetter->sequencePhase = 3; + } + + if (pContext->setterAnm.sequenceFrameCount > SWEEPER_FRAME_START_SWEEP) { + pContext->setterAnm.animOffsetZ = 0.28f * ((float)pContext->setterAnm.sequenceFrameCount - (float)SWEEPER_FRAME_START_SWEEP); + } + + if (pContext->setterAnm.sequenceFrameCount == SWEEPER_FRAME_PLACE_PINS && pContext->setterAnm.isNewRack == 0) { + for (int i = 0; i < pContext->pinCount; i++) { + if (pContext->pPinManager->pPinBodies[i]->unkFlag_0x250 == 0) { + pContext->pPinManager->pPinBodies[i]->mode_0x28C = 3; + } + } + } + + if (pContext->setterAnm.sequenceFrameCount == SWEEPER_FRAME_PLACE_PINS && pContext->setterAnm.isNewRack != 0) { + for (int i = 0; i < pContext->pinCount; i++) { + pContext->pPinManager->pPinBodies[i]->VF_0x0C(); + + nw4r::math::VEC3 basisZ; + nw4r::math::VEC3 basisY; + nw4r::math::VEC3 basisX; + + pContext->pPinManager->pPinBodies[i]->isActive = 1; + + PinPhysicsBody* pBody = pContext->pPinManager->pPinBodies[i]; + nw4r::math::VEC3 pos = pBody->field_0xFC; + pos.y = 8.0f; + + pBody->position = pos; + + basisX.x = 1.0f; + basisX.y = 0.0f; + basisX.z = 0.0f; + pBody->basisX = basisX; + + basisY.x = 0.0f; + basisY.y = 1.0f; + basisY.z = 0.0f; + pBody->basisY = basisY; + + basisZ.x = 0.0f; + basisZ.y = 0.0f; + basisZ.z = 1.0f; + pBody->basisZ = basisZ; + + pContext->pPinManager->pPinBodies[i]->mode_0x28C = 3; + } + } + + pContext->setterAnm.sequenceFrameCount++; + return 1; +} + +/** + * @brief Tests whether the pin setter is currently active + * + * @param pContext Lane context + * @return 1 if active, 0 otherwise + */ +int IsPinSetterActive(LaneContext* pContext) { + int frame = pContext->setterAnm.sequenceFrameCount; + if (frame != 0 && frame < SWEEPER_FRAME_END) { + return 1; + } + return 0; +} + +/** + * @brief Unknown function (stubbed) + */ +void fn_803345F0(LaneContext* /* unused */) { + ; +} + +} // namespace Bowling diff --git a/src/Pack/RPSports/RPBowScene/RPBowTrajectoryGuide.cpp b/src/Pack/RPSports/RPBowScene/RPBowTrajectoryGuide.cpp new file mode 100644 index 000000000..2c59b0850 --- /dev/null +++ b/src/Pack/RPSports/RPBowScene/RPBowTrajectoryGuide.cpp @@ -0,0 +1,134 @@ +#include + +namespace Bowling { + +/** + * @brief Updates the controller state bitmask + * + * @param pObj Unknown object data array + */ +void UpdateControllerState(u32* pObj) { + if (pObj[3] != 0) { + EGG::CoreController* pCtrl = EGG::CoreControllerMgr::instance()->getNthController(0); + + pObj[3] &= 0x100; + } +} + +/** + * @brief Destructor + */ +RPBowTrajectoryGuide::~RPBowTrajectoryGuide() {} + +/** + * @brief Sets the main directional indicator models for the trajectory guide + * + * @param pMainModel Primary guide model + * @param pUnkModel Secondary guide model + */ +void RPBowTrajectoryGuide::SetMainModels(RPGrpModel* pMainModel, RPGrpModel* pUnkModel) { + mpMainModel = pMainModel; + mpUnkModel = pUnkModel; +} + +/** + * @brief Assigns a dot model to a specific index in the guide path + * + * @param index Index of the dot model + * @param pDotModel Point model along the trajectory + */ +void RPBowTrajectoryGuide::SetDotModel(u32 index, RPGrpModel* pDotModel) { + mpDotModels[index] = pDotModel; +} + +/** + * @brief Initializes the trajectory guide state upon scene startup + */ +void RPBowTrajectoryGuide::Initialize() { + mActiveModelIndex = 0; + mIsVisible = 0; + mStartX = 0.0f; + mAngle = 0.0f; + unk_0x60 = 0; + mLimitWidth = 0.0f; + mLimitCenter = 0.0f; +} + +/** + * @brief Resets the trajectory guide state for a new shot + */ +void RPBowTrajectoryGuide::Reset() { + mActiveModelIndex = 0; + mIsVisible = 0; + mStartX = 0.0f; + mAngle = 0.0f; + unk_0x60 = 0; + mLimitWidth = 0.0f; + mLimitCenter = 0.0f; +} + +/** + * @brief Renders the trajectory guide + * @details Computes transforms and pushes both the main indicator (arrow) and + * the individual path dots to the renderer to visually represent the player's aim. + */ +void RPBowTrajectoryGuide::Draw() { + if (mIsVisible == 0) return; + + f32 cosAngle = std::cos(mAngle); + f32 nCosAngle = -cosAngle; + f32 sinAngle = std::sin(mAngle); + + nw4r::math::VEC3 vecB(sinAngle, 0.0f, nCosAngle); + nw4r::math::VEC3 vecA(0.0f, -1.0f, 0.0f); + nw4r::math::VEC3 vecCross; + nw4r::math::VEC3Cross(&vecCross, &vecB, &vecA); + + nw4r::math::MTX34 mtx( + 1.0f, 0.0f, 0.0f, mStartX, + 0.0f, 1.0f, 0.0f, vecB.y + 0.03f, + 0.0f, 0.0f, 1.0f, 20.0f + ); + + nw4r::math::VEC3 vecBase(mStartX, 0.0f, 20.0f); + + if (nw4r::g3d::ScnObj* pScnObj1 = (&mpMainModel)[mActiveModelIndex]->GetScnObj()) { + pScnObj1->SetMtx(nw4r::g3d::ScnObj::MTX_LOCAL, &mtx); + } + + (&mpMainModel)[mActiveModelIndex]->UpdateFrame(); + (&mpMainModel)[mActiveModelIndex]->Calc(); + (&mpMainModel)[mActiveModelIndex]->Entry(); + + nw4r::math::MTX34 mtx2( + vecCross.x, vecA.x, vecB.x, 0.0f, + vecCross.y, vecA.y, vecB.y, 0.0f, + vecCross.z, vecA.z, vecB.z, 0.0f + ); + + for (int i = 0; i < 16; i++) { + nw4r::math::VEC3 vecFinal = vecBase + ((vecB * 6.0f) * static_cast(i)); + + f32 diffX = vecFinal.x - mLimitCenter; + + if (diffX < -mLimitWidth || diffX > mLimitWidth) { + if (vecFinal.z < -6.0f) { + continue; + } + } + + mtx2._03 = vecFinal.x; + mtx2._13 = vecFinal.y + 0.03f; + mtx2._23 = vecFinal.z; + + if (nw4r::g3d::ScnObj* pScnObj2 = mpDotModels[i]->GetScnObj()) { + pScnObj2->SetMtx(nw4r::g3d::ScnObj::MTX_LOCAL, &mtx2); + } + + mpDotModels[i]->UpdateFrame(); + mpDotModels[i]->Calc(); + mpDotModels[i]->Entry(); + } +} + +} // namespace Bowling diff --git a/src/Pack/RPSystem/RPSysLoadScene.cpp b/src/Pack/RPSystem/RPSysLoadScene.cpp new file mode 100644 index 000000000..09271799f --- /dev/null +++ b/src/Pack/RPSystem/RPSysLoadScene.cpp @@ -0,0 +1,283 @@ +#include +#include + +#include + +#include + +#if defined(PACK_SPORTS) +#define RP_COMMON_SOUND_PATH "Sound/RPSportsCommon/rp_Common_Sports.brsar" +#elif defined(PACK_PARTY) +#define RP_COMMON_SOUND_PATH "Sound/RPPartyCommon/rp_Common_Party.brsar" +#endif + +/** + * @brief Displays the game's build date timestamp + * + * @param color Text color + */ +void RPSysScene::drawTimeStamp(nw4r::ut::Color color) { + enum { + YEARSIZE = sizeof("yyyy") - 1, + MONTHSIZE = sizeof("mm") - 1, + DAYSIZE = sizeof("dd") - 1, + TIMESIZE = sizeof("hh:mm") - 1, + BUFSIZE = 8 + }; + + RP_GET_INSTANCE(RPSysTextWriter)->Begin(); + { + RP_GET_INSTANCE(RPSysTextWriter)->SetDrawFlag(0); + RP_GET_INSTANCE(RPSysTextWriter)->SetScale(0.65f, 0.65f); + RP_GET_INSTANCE(RPSysTextWriter)->SetTextColor(color); + + const char* pTimeStamp = + RP_GET_INSTANCE(RPSysSystem)->getTimeStampString(); + + char year[BUFSIZE]; + std::strncpy( // + year, // + pTimeStamp, // + YEARSIZE); + + char month[BUFSIZE]; + std::strncpy( // + month, // + pTimeStamp + YEARSIZE + sizeof('/'), // + MONTHSIZE); + + char day[BUFSIZE]; + std::strncpy( // + day, // + pTimeStamp + YEARSIZE + sizeof('/') + MONTHSIZE + sizeof('/'), // + DAYSIZE); + + char time[BUFSIZE]; + std::strncpy( // + time, // + pTimeStamp + YEARSIZE + sizeof('/') + MONTHSIZE + sizeof('/') + + DAYSIZE + sizeof(" \r\n") - 1, + TIMESIZE); + + year[YEARSIZE] = 0; + month[MONTHSIZE] = 0; + day[DAYSIZE] = 0; + time[TIMESIZE] = 0; + + RP_GET_INSTANCE(RPSysTextWriter) + ->PrintfZeroCenter(-0.95f, -0.90f, "%s %s %s %s", // + month, day, year, time); + } + RP_GET_INSTANCE(RPSysTextWriter)->End(); +} + +void RPSysScene::loadUpdate() {} + +/** + * @brief Marks that this scene requires an asynchronous task + */ +void RPSysScene::setTaskAsync() { + mFlags.setBit(EFlag_TaskAsyncSet); + mFlags.setBit(EFlag_TaskAsyncRunning); +} + +/** + * @brief Tests whether this scene's asynchronous task has finished + */ +bool RPSysScene::isTaskAsyncFinish() const { + return mFlags.onBit(EFlag_TaskAsyncSet) && + mFlags.offBit(EFlag_TaskAsyncRunning); +} + +/** + * @brief Enables the "Now Loading" message display + */ +void RPSysScene::enableLoadMessage() { + mFlags.setBit(EFlag_LoadMessage); +} + +/** + * @brief Loads this scene's resources asynchronously + */ +void RPSysScene::load() { + if (mFlags.onBit(EFlag_LoadMessage)) { + // Need to use loadMessage() + return; + } + + BOOL success = FALSE; + OSMessage msg; + + RP_GET_INSTANCE(RPSysSystem) + ->getDvdThread() + ->request(loadResourceFunc, // + this, // + RP_GET_INSTANCE(RPSysSystem)->getDvdEndMessage()); + + do { + do { + RP_GET_INSTANCE(RPSysSystem)->loadFrameWork(true); + + EGG::TaskThread* pDvdThread = + RP_GET_INSTANCE(RPSysSystem)->getDvdThread(); + + msg = pDvdThread->waitQueueMessage( // + pDvdThread->getEndMessageQueue(), &success); + + } while (!success); + } while (msg != RP_GET_INSTANCE(RPSysSystem)->getDvdEndMessage()); +} + +/** + * @brief Loads this scene's resources asynchronously, displaying a "Now + * Loading" message if the feature is enabled + */ +void RPSysScene::loadMessage() { + if (mFlags.offBit(EFlag_LoadMessage)) { + // Need to use load() + return; + } + + bool finished = false; + + RP_GET_INSTANCE(RPSysSceneMgr) + ->setSceneStatus(EGG::Fader::STATUS_PREPARE_IN); + + RP_GET_INSTANCE(RPSysSceneMgr)->startSceneFadeIn(); + + RP_GET_INSTANCE(RPSysSystem) + ->getDvdThread() + ->request(loadResourceFunc, // + this, // + RP_GET_INSTANCE(RPSysSystem)->getDvdEndMessage()); + + while (true) { + BOOL success = FALSE; + + RP_GET_INSTANCE(RPSysSystem)->loadFrameWork(false); + + if (RP_GET_INSTANCE(RPSysSceneMgr)->calcSceneFader()) { + break; + } + + if (!finished) { + EGG::TaskThread* pDvdThread = + RP_GET_INSTANCE(RPSysSystem)->getDvdThread(); + + OSMessage msg = pDvdThread->waitQueueMessage( // + pDvdThread->getEndMessageQueue(), &success); + + if (success && + msg == RP_GET_INSTANCE(RPSysSystem)->getDvdEndMessage()) { + + finished = true; + } + + } else if (RP_GET_INSTANCE(RPSysSceneMgr)->getSceneStatus() == + EGG::Fader::STATUS_PREPARE_OUT) { + + RP_GET_INSTANCE(RPSysSceneMgr)->startSceneFadeOut(); + } + } +} + +/** + * @brief Creates the asynchronous task thread if requested by the scene + */ +void RPSysScene::initTaskAsync() { + if (mFlags.onBit(EFlag_TaskAsyncSet) && + mFlags.onBit(EFlag_TaskAsyncRunning)) { + + RP_GET_INSTANCE(RPSysSystem) + ->getDvdThread() + ->request(taskAsyncFunc, // + this, // + RP_GET_INSTANCE(RPSysSystem)->getDvdEndMessage()); + } +} + +/** + * @brief Polls the status of the DVD task thread + */ +void RPSysScene::updateDvdEndMessage() { + if (mFlags.onBit(EFlag_TaskAsyncSet) && + mFlags.onBit(EFlag_TaskAsyncRunning)) { + + BOOL success = FALSE; + + EGG::TaskThread* pDvdThread = + RP_GET_INSTANCE(RPSysSystem)->getDvdThread(); + + OSMessage msg = pDvdThread->waitQueueMessage( + pDvdThread->getEndMessageQueue(), &success); + + if (success && + msg == RP_GET_INSTANCE(RPSysSystem)->getDvdEndMessage()) { + + mFlags.resetBit(EFlag_TaskAsyncRunning); + } + } +} + +/** + * @brief Polls the status of the NAND task thread + */ +void RPSysScene::updateNandEndMessage() { + if (!RP_GET_INSTANCE(RPSysSaveDataMgr)->isNandAccessFinish()) { + BOOL success = FALSE; + + EGG::TaskThread* pNandThread = + RP_GET_INSTANCE(RPSysSystem)->getNandThread(); + + OSMessage msg = pNandThread->waitQueueMessage( + pNandThread->getEndMessageQueue(), &success); + + if (success && + msg == RP_GET_INSTANCE(RPSysSystem)->getNandEndMessage()) { + + RP_GET_INSTANCE(RPSysSaveDataMgr)->finishNandAccess(); + } + } + + if (!RP_GET_INSTANCE(RPSysHomeMenuMgr)->isActive() && + !RP_GET_INSTANCE(RPSysPauseMgr)->isPause()) { + + RP_GET_INSTANCE(RPSysSaveDataMgr)->update(isSceneDisplay()); + } +} + +/** + * @brief Thread function for the LoadResource phase + * + * @param pArg Thread function argument + */ +void RPSysScene::loadResourceFunc(void* pArg) { + RPSysScene* p = static_cast(pArg); + + if (RP_GET_INSTANCE(RPSysSceneCreator)->getAudioType(p->getSceneID()) == + RPSysSceneCreator::EAudioType_Common) { + + RP_GET_INSTANCE(RPSndAudioMgr) + ->openArchive(RP_COMMON_SOUND_PATH, NULL, + EGG::ArcPlayer::SARC_STORAGE_DVD, NULL); + + if (p->getSceneID() == RPSysSceneCreator::ESceneID_RPSysBootScene) { + RP_GET_INSTANCE(RPSndAudioMgr)->loadGroup("GROUP_LOGO"); + } else { + RP_GET_INSTANCE(RPSndAudioMgr)->loadGroup("GROUP_COMMON_01"); + } + } + + p->LoadResource(); +} + +/** + * @brief Thread function for the scene's task + * + * @param pArg Thread function argument + */ +void RPSysScene::taskAsyncFunc(void* pArg) { + RPSysScene* p = static_cast(pArg); + + p->taskAsync(); +} diff --git a/src/Pack/RPSystem/RPSysPauseMgr.cpp b/src/Pack/RPSystem/RPSysPauseMgr.cpp new file mode 100644 index 000000000..ee924204e --- /dev/null +++ b/src/Pack/RPSystem/RPSysPauseMgr.cpp @@ -0,0 +1,18 @@ +#include +#include +#include + +RP_SINGLETON_IMPL_EX(RPSysPauseMgr); + +void RPSysPauseMgr::draw() { + if (isPause()) { + mPauseMenu->draw(); + } +} + +/** + * @brief Destructor + */ +RPSysPauseMgr::~RPSysPauseMgr() { + //TODO(texline): delete mPauseMenu (it does not have a singleton) +} diff --git a/src/Pack/RPSystem/RPSysProjectLocal.cpp b/src/Pack/RPSystem/RPSysProjectLocal.cpp index 007aa415f..e6b331a29 100644 --- a/src/Pack/RPSystem/RPSysProjectLocal.cpp +++ b/src/Pack/RPSystem/RPSysProjectLocal.cpp @@ -16,7 +16,7 @@ RPSysProjectLocal::RPSysProjectLocal(EGG::Heap* pHeap) mRegion(ERegion_NTSC_U), mLocale(EArea_USA), mLanguage(EArea_USA), - mIsPal50(false), + mFrameRate(EFrameRate_60Hz), mSoundStorage(EStorage_DVDStream), #endif diff --git a/src/Pack/RPSystem/RPSysRenderMode.cpp b/src/Pack/RPSystem/RPSysRenderMode.cpp new file mode 100644 index 000000000..0b69136e9 --- /dev/null +++ b/src/Pack/RPSystem/RPSysRenderMode.cpp @@ -0,0 +1,225 @@ +#include + +#include +#include + +namespace { + +/** + * @brief Render mode configuration for NTSC (interlaced) + */ +GXRenderModeObj localNtsc640x456IntDf = { + VI_TVMODE_NTSC_INT, // tvInfo + 640, // fbWidth + 456, // efbHeight + 456, // xfbHeight + 25, // viXOrigin + 12, // viYOrigin + 670, // viWidth + 456, // viHeight + VI_XFBMODE_DF, // xfbMode + GX_FALSE, // field_rendering + GX_FALSE, // aa + { + {6, 6}, + {6, 6}, + {6, 6}, + {6, 6}, + {6, 6}, + {6, 6}, + {6, 6}, + {6, 6}, + {6, 6}, + {6, 6}, + {6, 6}, + {6, 6}, + }, // sample_pattern + {7, 7, 12, 12, 12, 7, 7} // vfilter +}; + +/** + * @brief Render mode configuration for NTSC (progressive) + */ +GXRenderModeObj localNtsc640x456Prog = { + VI_TVMODE_NTSC_PROG, // tvInfo + 640, // fbWidth + 456, // efbHeight + 456, // xfbHeight + 25, // viXOrigin + 12, // viYOrigin + 670, // viWidth + 456, // viHeight + VI_XFBMODE_SF, // xfbMode + GX_FALSE, // field_rendering + GX_FALSE, // aa + { + {6, 6}, + {6, 6}, + {6, 6}, + {6, 6}, + {6, 6}, + {6, 6}, + {6, 6}, + {6, 6}, + {6, 6}, + {6, 6}, + {6, 6}, + {6, 6}, + }, // sample_pattern + {0, 0, 21, 22, 21, 0, 0} // vfilter +}; + +/** + * @brief Render mode configuration for PAL50 (interlaced) + */ +GXRenderModeObj localPal50_640x456IntDf = { + VI_TVMODE_PAL_INT, // tvInfo + 640, // fbWidth + 456, // efbHeight + 542, // xfbHeight + 27, // viXOrigin + 16, // viYOrigin + 666, // viWidth + 542, // viHeight + VI_XFBMODE_DF, // xfbMode + GX_FALSE, // field_rendering + GX_FALSE, // aa + { + {6, 6}, + {6, 6}, + {6, 6}, + {6, 6}, + {6, 6}, + {6, 6}, + {6, 6}, + {6, 6}, + {6, 6}, + {6, 6}, + {6, 6}, + {6, 6}, + }, // sample_pattern + {7, 7, 12, 12, 12, 7, 7} // vfilter +}; + +/** + * @brief Render mode configuration for NTSC video + */ +GXRenderModeObj localPal60_640x456IntDf = { + VI_TVMODE_EURGB60_INT, // tvInfo + 640, // fbWidth + 456, // efbHeight + 456, // xfbHeight + 25, // viXOrigin + 12, // viYOrigin + 670, // viWidth + 456, // viHeight + VI_XFBMODE_DF, // xfbMode + GX_FALSE, // field_rendering + GX_FALSE, // aa + { + {6, 6}, + {6, 6}, + {6, 6}, + {6, 6}, + {6, 6}, + {6, 6}, + {6, 6}, + {6, 6}, + {6, 6}, + {6, 6}, + {6, 6}, + {6, 6}, + }, // sample_pattern + {7, 7, 12, 12, 12, 7, 7} // vfilter +}; + +/** + * @brief Render mode configuration for PAL (progressive) + */ +GXRenderModeObj localPal60_640x456Prog = { + VI_TVMODE_EURGB60_PROG, // tvInfo + 640, // fbWidth + 456, // efbHeight + 456, // xfbHeight + 25, // viXOrigin + 12, // viYOrigin + 670, // viWidth + 456, // viHeight + VI_XFBMODE_SF, // xfbMode + GX_FALSE, // field_rendering + GX_FALSE, // aa + { + {6, 6}, + {6, 6}, + {6, 6}, + {6, 6}, + {6, 6}, + {6, 6}, + {6, 6}, + {6, 6}, + {6, 6}, + {6, 6}, + {6, 6}, + {6, 6}, + }, // sample_pattern + {0, 0, 21, 22, 21, 0, 0} // vfilter +}; + +} // namespace + +/** + * @brief Render mode configurations + */ +GXRenderModeObj* const RPSysRenderMode::spRenderModeTable[EFormat_Max] = { + &localNtsc640x456IntDf, // EFormat_Ntsc + &localNtsc640x456Prog, // EFormat_NtscProg + &localPal50_640x456IntDf, // EFormat_Pal50 + &localPal60_640x456IntDf, // EFormat_Pal60 + &localPal60_640x456Prog, // EFormat_PalProg +}; + +/** + * @brief Adjusts a render mode to account for widescreen/50Hz formats + * + * @param pOriginX Pointer to render mode viXOrigin + * @param pWidth Pointer to render mode viWidth + * @param format Render mode format + * @param wide Whether the display is widescreen + */ +void RPSysRenderMode::adjust(u16* pOriginX, u16* pWidth, EFormat format, + bool wide) { + if (wide) { + if (format == EFormat_Pal50) { + *pWidth = 682; + } else { + *pWidth = 686; + } + } else if (format == EFormat_Pal50) { + *pWidth = 666; + } else { + *pWidth = 670; + } + + switch (format) { + case EFormat_Ntsc: + case EFormat_NtscProg: { + *pOriginX = (720 - *pWidth) / 2; + break; + } + + case EFormat_Pal50: { + *pOriginX = (720 - *pWidth) / 2; + break; + } + + case EFormat_Pal60: + case EFormat_PalProg: { + *pOriginX = (720 - *pWidth) / 2; + break; + } + + default: { + break; + } + } +} diff --git a/src/Pack/RPSystem/RPSysResourceManager.cpp b/src/Pack/RPSystem/RPSysResourceManager.cpp index 66819b29d..5630bd314 100644 --- a/src/Pack/RPSystem/RPSysResourceManager.cpp +++ b/src/Pack/RPSystem/RPSysResourceManager.cpp @@ -1,6 +1,6 @@ #include -#include -#include +#include +#include #include #include @@ -14,7 +14,7 @@ RP_SINGLETON_IMPL(RPSysResourceManager); */ const RPSysSceneCreator::ESceneID RPSysResourceManager::CACHED_SCENES[] = { RPSysSceneCreator::ESceneID_RPSysPlayerSelectScene, - RPSysSceneCreator::ESceneID_RPSysNunchukScene, + RPSysSceneCreator::ESceneID_RPSysNunchukCheckScene, #if defined(PACK_SPORTS) RPSysSceneCreator::ESceneID_RPBsbScene, @@ -22,13 +22,13 @@ const RPSysSceneCreator::ESceneID RPSysResourceManager::CACHED_SCENES[] = { RPSysSceneCreator::ESceneID_RPGolScene, RPSysSceneCreator::ESceneID_RPTnsScene, RPSysSceneCreator::ESceneID_RPBoxScene, - RPSysSceneCreator::ESceneID_RPSportsTitleScene, - RPSysSceneCreator::ESceneID_RPSportsMenuScene, + RPSysSceneCreator::ESceneID_RPSportsPackTitleScene, + RPSysSceneCreator::ESceneID_RPSportsMainScene, RPSysSceneCreator::ESceneID_RPSportsTrainingMenuScene, RPSysSceneCreator::ESceneID_RPSportsPhysicalMenuScene, RPSysSceneCreator::ESceneID_RPSportsPhysicalPreviewScene, RPSysSceneCreator::ESceneID_RPSportsPhysicalResultScene, - RPSysSceneCreator::ESceneID_RPGolSelectScene, + RPSysSceneCreator::ESceneID_RPGolCourseSelectScene, #elif defined(PACK_PARTY) RPSysSceneCreator::ESceneID_RPFshScene, RPSysSceneCreator::ESceneID_RPHkyScene, @@ -39,9 +39,9 @@ const RPSysSceneCreator::ESceneID RPSysResourceManager::CACHED_SCENES[] = { RPSysSceneCreator::ESceneID_RPWlyScene, RPSysSceneCreator::ESceneID_RPTnkScene, RPSysSceneCreator::ESceneID_RPBomScene, - RPSysSceneCreator::ESceneID_RPPartyTitleScene, - RPSysSceneCreator::ESceneID_RPPartyMiiLoadScene, - RPSysSceneCreator::ESceneID_RPPartyMenuScene, + RPSysSceneCreator::ESceneID_RPPartyPackTitleScene, + RPSysSceneCreator::ESceneID_RPPartyRootScene, + RPSysSceneCreator::ESceneID_RPPartyMainScene, #endif }; @@ -576,16 +576,10 @@ DECOMP_FORCEACTIVE(RPSysResourceManager_cpp_1, * @param list Resource list */ RPSysFile* RPSysResourceManager::FindFile(const char* pPath, EList list) const { - RPSysFile* pFile = - static_cast(nw4r::ut::List_GetFirst(&mResourceLists[list])); - - while (pFile != NULL) { - if (std::strcmp(pPath, pFile->GetPath()) == 0) { - return pFile; + RP_NW4R_LIST_FOREACH(RPSysFile, it, mResourceLists[list]) { + if (std::strcmp(pPath, it->GetPath()) == 0) { + return it; } - - pFile = static_cast( - nw4r::ut::List_GetNext(&mResourceLists[list], pFile)); } return NULL; diff --git a/src/Pack/RPSystem/RPSysSaveDataMgr.cpp b/src/Pack/RPSystem/RPSysSaveDataMgr.cpp index 1a0f6f2b2..d48c04c9a 100644 --- a/src/Pack/RPSystem/RPSysSaveDataMgr.cpp +++ b/src/Pack/RPSystem/RPSysSaveDataMgr.cpp @@ -810,10 +810,8 @@ void RPSysSaveDataMgr::loadSync() { // No early return? } - { - EGG::RamStream strm(mpSaveFile, mSaveFileSize); - mpSaveData->read(strm, mpSaveFile); - } + EGG::RamStream strm(mpSaveFile, mSaveFileSize); + mpSaveData->read(strm, mpSaveFile); } } diff --git a/src/Pack/RPSystem/RPSysScene.cpp b/src/Pack/RPSystem/RPSysScene.cpp new file mode 100644 index 000000000..4199ed1c7 --- /dev/null +++ b/src/Pack/RPSystem/RPSysScene.cpp @@ -0,0 +1,319 @@ +#include +#include +#include +#include + +#include + +#include + +RPSysScene::UnkStruct RPSysScene::sUnkStruct; + +/** + * @brief Tests whether the scene is fully visible + */ +bool RPSysScene::isSceneDisplay() const { + return RP_GET_INSTANCE(RPSysSceneMgr)->isDisplay(); +} + +/** + * @brief Tests whether the scene is visibly obscured + */ +bool RPSysScene::isSceneBlank() const { + return RP_GET_INSTANCE(RPSysSceneMgr)->isBlank(); +} + +/** + * @brief Tests whether a scene change would be allowed + */ +bool RPSysScene::isSceneChangeEnable() const { + return RP_GET_INSTANCE(RPSysSceneMgr)->isSceneChangeEnable(); +} + +/** + * @brief Tests whether NAND access would be safe + */ +bool RPSysScene::isNandAccessEnable() const { + return !RP_GET_INSTANCE(RPSysSceneMgr)->isFadeOut() && + RP_GET_INSTANCE(RPSysSceneMgr)->isTaskFinished(); +} + +/** + * @brief Sets the duration of all faders + * + * @param frame Fade duration, in frames + */ +void RPSysScene::setFadeFrame(u16 frame) { + RP_GET_INSTANCE(RPSysSceneMgr)->setFadeFrame(frame); +} + +/** + * @brief Gets the color of the manager fader + */ +nw4r::ut::Color RPSysScene::getFadeColor() const { + return RP_GET_INSTANCE(RPSysSceneMgr)->getFadeColor(); +} + +/** + * @brief Sets the color of all faders + * + * @param color Fade color + */ +void RPSysScene::setFadeColor(nw4r::ut::Color color) { + RP_GET_INSTANCE(RPSysSceneMgr)->setFadeColor(color); +} + +/** + * @brief Sets the color of the scene fader + * + * @param color Fade color + */ +void RPSysScene::setSceneFadeColor(nw4r::ut::Color color) { + RP_GET_INSTANCE(RPSysSceneMgr)->setSceneFadeColor(color); +} + +/** + * @brief Begins fading in the scene fader + * + * @return Success + */ +bool RPSysScene::startFadeIn() { + return RP_GET_INSTANCE(RPSysSceneMgr)->startSceneFadeIn(); +} + +/** + * @brief Begins fading out the scene fader + * + * @return Success + */ +bool RPSysScene::startFadeOut() { + return RP_GET_INSTANCE(RPSysSceneMgr)->startSceneFadeOut(); +} + +/** + * @brief Toggles screen dimming + * @note If "Screen Saver Mode" is disabled, dimming is always OFF. + * + * @param enable Whether to dim the screen + */ +void RPSysScene::setDimming(bool enable) { + RP_GET_INSTANCE(RPSysSystem)->setDimming(enable); +} + +/** + * @brief Constructor + */ +RPSysScene::RPSysScene() + : mpRenderer(NULL), + mpCommonObject(NULL), + mpEffectCreator(NULL), + mpSceneHeap(NULL), + mCreatorSceneID(-1) {} + +/** + * @brief Prepares this scene to be entered + */ +void RPSysScene::incomingScene() { + RPSysCoreController::initScene(); + + RP_GET_INSTANCE(RPSysTextWriter)->Reset(); + + if (!mFlags.onBit(EFlag_IsChild)) { + initTaskAsync(); + } + + mpRenderer->BecomeCurrent(); + mpCommonObject->init(); + + RP_GET_INSTANCE(RPSysSceneMgr)->resetFadeColor(); + RP_GET_INSTANCE(RPSysSceneMgr)->resetFadeFrame(); + RP_GET_INSTANCE(RPSysSceneMgr) + ->setSceneStatus(EGG::Fader::STATUS_PREPARE_OUT); + + RP_GET_INSTANCE(RPSysSceneMgr)->resetGuard(); + setDimming(true); + + RP_GET_INSTANCE(RPSysEffectMgr) + ->setCreator(mpEffectCreator, RPSysEffectMgr::EDrawScene_Scene); + + Reset(); + + if (!mFlags.onBit(EFlag_IsChild)) { + RP_GET_INSTANCE(RPSysSceneMgr)->startMgrFadeIn(); + } +} + +/** + * @brief Enters the scene + */ +void RPSysScene::enter() { + init(); + Configure(); + + if (!mFlags.onBit(EFlag_IsChild)) { + RP_GET_INSTANCE(RPSysSceneMgr)->drawMgrFader(); + + load(); + loadMessage(); + } + + incomingScene(); +} + +/** + * @brief Prepares this scene to be exited + */ +void RPSysScene::outgoingScene() { + RPSysCoreController::stopMotorAll(); + + RP_GET_INSTANCE(RPSysEffectMgr)->stopAllEffect(); + RP_GET_INSTANCE(RPSysEffectMgr)->resetCreator(mpEffectCreator); +} + +/** + * @brief Re-initializes the scene + */ +void RPSysScene::reinit() { + outgoingScene(); + incomingScene(); +} + +/** + * @brief Prepares for destruction of (and transition from) a child scene + */ +void RPSysScene::incoming_childDestroy() { + incomingScene(); +} + +/** + * @brief Updates the scene state + */ +void RPSysScene::calc() { + if (!RP_GET_INSTANCE(RPSysDvdStatus)->isErrorOccured()) { + mpCommonObject->preUpdate(); + + loadUpdate(); + + if (RP_GET_INSTANCE(RPSysSceneMgr)->isNormalState() && + !RP_GET_INSTANCE(RPSysHomeMenuMgr)->isActive() && + !RP_GET_INSTANCE(RPSysPauseMgr)->isPause()) { + + mpRenderer->PreCalculate(); + Calculate(); + mpRenderer->PostCalculate(); + } else { + mpRenderer->CalculateInPause(); + } + + RP_GET_INSTANCE(RP_DEBUG_STUB_0)->Calculate(); + RP_GET_INSTANCE(RPSysHostIOSocketManager)->Update(); + + mpCommonObject->postUpdate(); + } + + updateDvdEndMessage(); + updateNandEndMessage(); +} + +/** + * @brief Renders the scene state + */ +void RPSysScene::draw() { + RP_GET_INSTANCE(RPSysKokeshiManager)->UpdateCtrlMgr(); + + RPGrpRenderer::Begin(); + { + mpRenderer->Rendering(); + + RPGrpRenderer::StartDebugDraw(); + RP_GET_INSTANCE(RP_DEBUG_STUB_0)->DebugDraw(); + } + RPGrpRenderer::End(); +} + +/** + * @brief Prepares for creation of (and transition to) a child scene + */ +void RPSysScene::outgoing_childCreate() { + outgoingScene(); +} + +/** + * @brief Finalizes this scene after being exited + */ +void RPSysScene::exitScenePost() { + GXDrawDone(); + mpRenderer->Destruct(); + + if (mpSceneHeap != NULL) { + RP_GET_INSTANCE(RPSysSystem)->destroyHeap(mpSceneHeap); + } +} + +/** + * @brief Exits the scene + */ +void RPSysScene::exit() { + outgoingScene(); + Exit(); + exitScenePost(); +} + +/** + * @brief Initializes this scene's members + */ +void RPSysScene::init() { + EGG::Allocator* pAllocator = new EGG::Allocator(getHeap()); + mpRenderer = RPGrpRenderer::Construct(pAllocator, getSceneID()); + + mpRenderer->BecomeCurrent(); + RPGrpRenderer::GetCurrent()->AppendDrawObject(*this); + + mpCommonObject = new RPSysCommonObject(); + + mpEffectCreator = new RPSysEffectCreator(RPSysEffectMgr::EDrawScene_Scene); + + RP_GET_INSTANCE(RPSysKokeshiManager)->Reset(); + + RPSysSceneCreator::EAudioType audioType = + RP_GET_INSTANCE(RPSysSceneCreator)->getAudioType(getSceneID()); + + if (audioType == RPSysSceneCreator::EAudioType_Common) { + RP_GET_INSTANCE(RPSndAudioMgr)->configureTitle(); + } + + RPSysSceneCreator::EExitType exitType = + RP_GET_INSTANCE(RPSysSceneCreator)->getExitType(getSceneID()); + + if (exitType == RPSysSceneCreator::EExitType_Standard) { + RP_GET_INSTANCE(RPSysPlayerMgr)->loadAllData(); + + } else if (exitType == RPSysSceneCreator::EExitType_Sibling || + exitType == RPSysSceneCreator::EExitType_2) { + + RP_GET_INSTANCE(RPSysPlayerMgr)->reset(); + } +} + +/** + * @brief Sets this scene's parent/creator ID + * + * @param id ID of this scene's parent/creator + */ +void RPSysScene::setCreatorSceneID(s32 id) { + mCreatorSceneID = id; +} + +/** + * @brief Gets this scene's parent/creator ID + */ +s32 RPSysScene::getCreatorSceneID() const { + return mCreatorSceneID; +} + +/** + * @brief Marks this scene as a child of the previous scene + */ +void RPSysScene::setChildScene() { + mFlags.setBit(EFlag_IsChild); +} diff --git a/src/Pack/RPSystem/RPSysSceneCreator.cpp b/src/Pack/RPSystem/RPSysSceneCreator.cpp new file mode 100644 index 000000000..a34888f7c --- /dev/null +++ b/src/Pack/RPSystem/RPSysSceneCreator.cpp @@ -0,0 +1,564 @@ +#include +#include + +#if defined(PACK_SPORTS) +#include +#include +#include +#include +#include +#include +#elif defined(PACK_PARTY) +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#endif + +RP_SINGLETON_IMPL_EX(RPSysSceneCreator); + +#if defined(PACK_SPORTS) +#define RP_COMMON_DIR "RPCommon/" +#elif defined(PACK_PARTY) +#define RP_COMMON_DIR "RPPartyCommon/" +#endif + +/** + * @brief Information about every Pack Project scene + */ +const RPSysSceneCreator::SceneAttr RPSysSceneCreator::SCENE_ATTR_TABLE[] = { + // clang-format off + {ESceneID_RPSysBootScene, EPackID_AllPack, ECreateType_Standard, ELoadType_Blank, EExitType_Sibling, EAudioType_Common, RP_COMMON_DIR, /* Logo */ "ロゴ"}, + {ESceneID_RPSysPlayerSelectScene, EPackID_AllPack, ECreateType_Standard, ELoadType_Blank, EExitType_2, EAudioType_Common, RP_COMMON_DIR, /* Player Select */ "プレイヤーセレクト"}, + {ESceneID_RPSysNunchukCheckScene, EPackID_AllPack, ECreateType_Sibling, ELoadType_Blank, EExitType_3, EAudioType_Scene, RP_COMMON_DIR, /* Nunchuk Check */ "ヌンチャクチェック"}, + +#if defined(PACK_SPORTS) + {ESceneID_RPBsbScene, EPackID_SportsPack, ECreateType_Sibling, ELoadType_Blank, EExitType_Standard, EAudioType_Scene, "RPBsbScene/", /* Baseball */ "野球"}, + {ESceneID_RPBowScene, EPackID_SportsPack, ECreateType_Sibling, ELoadType_Blank, EExitType_Standard, EAudioType_Scene, "RPBowScene/", /* Bowling */ "ボウリング"}, + {ESceneID_RPGolScene, EPackID_SportsPack, ECreateType_Sibling, ELoadType_Blank, EExitType_Standard, EAudioType_Scene, "RPGolScene/", /* Golf */ "ゴルフ"}, + {ESceneID_RPTnsScene, EPackID_SportsPack, ECreateType_Sibling, ELoadType_Blank, EExitType_Standard, EAudioType_Scene, "RPTnsScene/", /* Tennis */ "テニス"}, + {ESceneID_RPBoxScene, EPackID_SportsPack, ECreateType_Sibling, ELoadType_Blank, EExitType_Standard, EAudioType_Scene, "RPBoxScene/", /* Boxing */ "ボクシング"}, + {ESceneID_RPSportsPackTitleScene, EPackID_SportsPack, ECreateType_Standard, ELoadType_Blank, EExitType_Sibling, EAudioType_Common, "RPSportsTitle/", /* Sports Pack */ "スポーツパック"}, + {ESceneID_RPSportsMainScene, EPackID_SportsPack, ECreateType_Standard, ELoadType_Blank, EExitType_2, EAudioType_Common, "RPSportsCommon/", /* Sports Menu Select */ "スポーツメニューセレクト"}, + {ESceneID_RPSportsTrainingMenuScene, EPackID_SportsPack, ECreateType_Sibling, ELoadType_Blank, EExitType_3, EAudioType_Common, "RPSportsTrainingMenu/", /* Training Menu */ "トレーニングメニュー"}, + {ESceneID_RPSportsPhysicalMenuScene, EPackID_SportsPack, ECreateType_Sibling, ELoadType_Blank, EExitType_3, EAudioType_Common, "RPSportsPhysical/", /* Physical Measure Menu */ "体力測定メニュー"}, + {ESceneID_RPSportsPhysicalPreviewScene, EPackID_SportsPack, ECreateType_Sibling, ELoadType_Blank, EExitType_3, EAudioType_Common, "RPSportsPhysical/", /* Physical Measure Explanation */ "体力測定説明"}, + {ESceneID_RPSportsPhysicalResultScene, EPackID_SportsPack, ECreateType_Sibling, ELoadType_Blank, EExitType_3, EAudioType_Common, "RPSportsPhysical/", /* Physical Measure Results */ "体力測定結果"}, + {ESceneID_RPGolCourseSelectScene, EPackID_SportsPack, ECreateType_Sibling, ELoadType_Blank, EExitType_Standard, EAudioType_Scene, "RPGolScene/", /* Golf Course Select */ "ゴルフコースセレクト"}, +#endif + +#if defined(PACK_PARTY) + {ESceneID_RPFshScene, EPackID_PartyPack, ECreateType_Sibling, ELoadType_Blank, EExitType_Standard, EAudioType_Scene, "RPFshScene/", /* Fishing */ "釣り"}, + {ESceneID_RPHkyScene, EPackID_PartyPack, ECreateType_Sibling, ELoadType_Blank, EExitType_Standard, EAudioType_Scene, "RPHkyScene/", /* Hockey */ "ホッケー"}, + {ESceneID_RPDucScene, EPackID_PartyPack, ECreateType_Sibling, ELoadType_Blank, EExitType_Standard, EAudioType_Scene, "RPDucScene/", /* Shooting */ "射撃"}, + {ESceneID_RPPnpScene, EPackID_PartyPack, ECreateType_Sibling, ELoadType_Blank, EExitType_Standard, EAudioType_Scene, "RPPnpScene/", /* Table Tennis */ "卓球"}, + {ESceneID_RPBilScene, EPackID_PartyPack, ECreateType_Sibling, ELoadType_Blank, EExitType_Standard, EAudioType_Scene, "RPBilScene/", /* Billiards */ "ビリヤード"}, + {ESceneID_RPCowScene, EPackID_PartyPack, ECreateType_Sibling, ELoadType_Blank, EExitType_Standard, EAudioType_Scene, "RPCowScene/", /* Cow Race */ "牛レース"}, + {ESceneID_RPWlyScene, EPackID_PartyPack, ECreateType_Sibling, ELoadType_Blank, EExitType_Standard, EAudioType_Scene, "RPWlyScene/", /* Wally */ "ウォーリー"}, + {ESceneID_RPTnkScene, EPackID_PartyPack, ECreateType_Sibling, ELoadType_Blank, EExitType_Standard, EAudioType_Scene, "RPTnkScene/", /* Tank */ "タンク"}, + {ESceneID_RPBomScene, EPackID_PartyPack, ECreateType_Sibling, ELoadType_Blank, EExitType_Standard, EAudioType_Scene, "RPBomScene/", /* Bomb */ "爆弾"}, + {ESceneID_RPPartyPackTitleScene, EPackID_PartyPack, ECreateType_Standard, ELoadType_Blank, EExitType_Sibling, EAudioType_Common, "RPPartyTitle/", /* Party Pack */ "パーティパック"}, + {ESceneID_RPPartyRootScene, EPackID_PartyPack, ECreateType_Standard, ELoadType_Blank, EExitType_Child, EAudioType_Common, "RPPartyCommon/", /* Tour Menu */ "ツアーメニュー"}, + {ESceneID_RPPartyMainScene, EPackID_PartyPack, ECreateType_Sibling, ELoadType_Blank, EExitType_3, EAudioType_Common, "RPPartyCommon/", /* Tour Menu */ "ツアーメニュー"}, +#endif + // clang-format on +}; + +/** + * @brief Constructor + * + * @param pHeap Parent heap + */ +RPSysSceneCreator::RPSysSceneCreator(EGG::Heap* pHeap) + : mpParentHeap(pHeap), mPrevSceneID(-1) {} + +/** + * @brief Gets the index of the specified scene's entry in the table + * + * @param id Scene ID + * @return Entry index, or -1 if not found + */ +s32 RPSysSceneCreator::getEntryIndex(ESceneID id) { + for (s32 i = 0; i < ARRAY_SIZE(SCENE_ATTR_TABLE); i++) { + if (SCENE_ATTR_TABLE[i].scene == id) { + return i; + } + } + + return -1; +} + +/** + * @brief Requests a scene change after fading out + * @details A scene id of -1 will select the current scene. + * + * @param id New scene ID + * @param reconfigure Whether to fully reconfigure the scene + * @return Success + */ +bool RPSysSceneCreator::changeSceneAfterFade(s32 id, bool reconfigure) { + bool success = false; + + if (RP_GET_INSTANCE(RPSysSceneMgr)->isTaskFinished()) { + int current = RP_GET_INSTANCE(RPSysSceneMgr)->getCurrentSceneID(); + + if (reconfigure) { + id = current; + } + + success = RP_GET_INSTANCE(RPSysSceneMgr) + ->changeNextSceneAfterFade(id, reconfigure); + + if (success && current >= 0) { + // Fade out audio before switching sound archives + if (getAudioType(current) != getAudioType(id)) { + u16 frames = RP_GET_INSTANCE(RPSysSceneMgr)->getFadeFrame(); + RP_GET_INSTANCE(RPSndAudioMgr)->fadeOutAllSound(frames); + } + + if (getExitType(id) != EExitType_Child) { + mPrevSceneID = current; + } + } + } + + return success; +} + +/** + * @brief Changes to the title scene + * + * @return Success + */ +bool RPSysSceneCreator::changeSoftReset() { +#if defined(PACK_SPORTS) + return changeSceneAfterFade(ESceneID_RPSportsPackTitleScene); +#elif defined(PACK_PARTY) + return changeSceneAfterFade(ESceneID_RPPartyPackTitleScene); +#endif +} + +/** + * @brief Creates the specified scene + * + * @param id Scene ID + */ +EGG::Scene* RPSysSceneCreator::create(s32 id) { + RPSysScene* pScene = NULL; + + switch (getPackID(id)) { + case EPackID_SportsPack: { +#if defined(PACK_SPORTS) + pScene = createSportsScene(id); +#else + pScene = NULL; +#endif + break; + } + + case EPackID_PartyPack: { +#if defined(PACK_PARTY) + pScene = createPartyScene(id); +#else + pScene = NULL; +#endif + break; + } + + case EPackID_HealthPack: { +#if defined(PACK_HEALTH) + pScene = createHealthScene(id); +#else + pScene = NULL; +#endif + break; + } + + case EPackID_MusicPack: { +#if defined(PACK_MUSIC) + pScene = createMusicScene(id); +#else + pScene = NULL; +#endif + break; + } + + case EPackID_AllPack: { + switch (id) { + case ESceneID_RPSysBootScene: { + pScene = new RPSysBootScene(); + break; + } + + case ESceneID_RPSysPlayerSelectScene: { + pScene = new RPSysPlayerSelectScene(); + break; + } + + case ESceneID_RPSysNunchukCheckScene: { + pScene = new RPSysNunchukCheckScene(); + break; + } + + default: { + pScene = NULL; + break; + } + } + + break; + } + + default: { + break; + } + } + + if (pScene != NULL) { + if (getLoadType(id) == ELoadType_Message) { + pScene->enableLoadMessage(); + } + + if (getExitType(id) == EExitType_Child) { + pScene->setChildScene(); + } + + pScene->setCreatorSceneID(mPrevSceneID); + } + + return pScene; +} + +/** + * @brief Destroys the specified scene + * + * @param id Scene ID + */ +void RPSysSceneCreator::destroy(s32 /* id */) { + if (RP_GET_INSTANCE(RPSysSceneMgr)->isApplicationEndReserved()) { + RP_GET_INSTANCE(RPSysSystem)->systemShutDown(); + } +} + +/** + * @brief Gets the specified scene's resource directory + * @details A scene id of -1 will select the current scene. + * + * @param id Scene ID + */ +const char* RPSysSceneCreator::getResDirName(s32 id) { + if (id < 0) { + id = RP_GET_INSTANCE(RPSysSceneMgr)->getCurrentSceneID(); + } + + s32 index = getEntryIndex(static_cast(id)); + +// @bug Table index is not validated +#if defined(BUG_FIX) + if (index < 0) { + return RP_COMMON_DIR; + } +#endif + + return SCENE_ATTR_TABLE[index].pResDirName; +} + +/** + * @brief Gets the specified scene's sport ID + * @details A scene id of -1 will select the current scene. + * @note If no sport corresponds to the scene, this function returns -1. + * + * @param id Scene ID + */ +s32 RPSysSceneCreator::getSportID(s32 id) { + if (id < 0) { + id = RP_GET_INSTANCE(RPSysSceneMgr)->getCurrentSceneID(); + } + + switch (id) { + case ESceneID_RPBsbScene: { + return ESportID_Bsb; + } + + case ESceneID_RPTnsScene: { + return ESportID_Tns; + } + + case ESceneID_RPGolScene: { + return ESportID_Gol; + } + + case ESceneID_RPBoxScene: { + return ESportID_Box; + } + + case ESceneID_RPBowScene: { + return ESportID_Bow; + } + + default: { + return -1; + } + } +} + +/** + * @brief Gets the specified sport's scene ID + * @note If no scene corresponds to the sport, this function returns -1. + * + * @param sport Sport ID + */ +s32 RPSysSceneCreator::getSceneID(ESportID sport) { + switch (sport) { + case ESportID_Bsb: { + return ESceneID_RPBsbScene; + } + + case ESportID_Tns: { + return ESceneID_RPTnsScene; + } + + case ESportID_Gol: { + return ESceneID_RPGolScene; + } + + case ESportID_Box: { + return ESceneID_RPBoxScene; + } + + case ESportID_Bow: { + return ESceneID_RPBowScene; + } + + default: { + return -1; + } + } +} + +/** + * @brief Gets the specified scene's pack ID + * + * @param id Scene ID + */ +RPSysSceneCreator::EPackID RPSysSceneCreator::getPackID(s32 id) { + s32 index = getEntryIndex(static_cast(id)); + +// @bug Table index is not validated +#if defined(BUG_FIX) + if (index < 0) { + return EPackID_AllPack; + } +#endif + + return SCENE_ATTR_TABLE[index].pack; +} + +/** + * @brief Gets the specified scene's creation type + * + * @param id Scene ID + */ +RPSysSceneCreator::ECreateType RPSysSceneCreator::getCreateType(s32 id) { + s32 index = getEntryIndex(static_cast(id)); + +// @bug Table index is not validated +#if defined(BUG_FIX) + if (index < 0) { + return ECreateType_Standard; + } +#endif + + return SCENE_ATTR_TABLE[index].createType; +} + +/** + * @brief Gets the specified scene's load type + * + * @param id Scene ID + */ +RPSysSceneCreator::ELoadType RPSysSceneCreator::getLoadType(s32 id) { + s32 index = getEntryIndex(static_cast(id)); + +// @bug Table index is not validated +#if defined(BUG_FIX) + if (index < 0) { + return ELoadType_Blank; + } +#endif + + return SCENE_ATTR_TABLE[index].loadType; +} + +/** + * @brief Gets the specified scene's exit type + * + * @param id Scene ID + */ +RPSysSceneCreator::EExitType RPSysSceneCreator::getExitType(s32 id) { + s32 index = getEntryIndex(static_cast(id)); + +// @bug Table index is not validated +#if defined(BUG_FIX) + if (index < 0) { + return EExitType_Standard; + } +#endif + + return SCENE_ATTR_TABLE[index].exitType; +} + +/** + * @brief Gets the specified scene's audio type + * + * @param id Scene ID + */ +RPSysSceneCreator::EAudioType RPSysSceneCreator::getAudioType(s32 id) { + s32 index = getEntryIndex(static_cast(id)); + +// @bug Table index is not validated +#if defined(BUG_FIX) + if (index < 0) { + return EAudioType_Scene; + } +#endif + + return SCENE_ATTR_TABLE[index].audioType; +} + +#if defined(PACK_SPORTS) +/** + * @brief Creates the specified Sports Pack scene + * + * @param id Scene ID + */ +RPSysScene* RPSysSceneCreator::createSportsScene(s32 id) { + switch (id) { + case ESceneID_RPBsbScene: { + return new RPBsbScene(); + } + + case ESceneID_RPBowScene: { + return new RPBowScene(); + } + + case ESceneID_RPGolScene: { + return new RPGolScene(); + } + + case ESceneID_RPTnsScene: { + return new RPTnsScene(); + } + + case ESceneID_RPBoxScene: { + return new RPBoxScene(); + } + + case ESceneID_RPSportsPackTitleScene: { + return new RPSportsPackTitleScene(); + } + + case ESceneID_RPSportsMainScene: { + return new RPSportsMainScene(); + } + + case ESceneID_RPSportsTrainingMenuScene: { + return new RPSportsTrainingMenuScene(); + } + + case ESceneID_RPSportsPhysicalMenuScene: { + return new RPSportsPhysicalMenuScene(); + } + + case ESceneID_RPSportsPhysicalPreviewScene: { + return new RPSportsPhysicalPreviewScene(); + } + + case ESceneID_RPSportsPhysicalResultScene: { + return new RPSportsPhysicalResultScene(); + } + + case ESceneID_RPGolCourseSelectScene: { + return new RPGolCourseSelectScene(); + } + + default: { + return NULL; + } + } +} +#endif + +#if defined(PACK_PARTY) +/** + * @brief Creates the specified Party Pack scene + * + * @param id Scene ID + */ +RPSysScene* RPSysSceneCreator::createPartyScene(s32 id) { + switch (id) { + case ESceneID_RPFshScene: { + return new RPFshScene(); + } + + case ESceneID_RPHkyScene: { + return new RPHkyScene(); + } + + case ESceneID_RPDucScene: { + return new RPDucScene(); + } + + case ESceneID_RPPnpScene: { + return new RPPnpScene(); + } + + case ESceneID_RPBilScene: { + return new RPBilScene(); + } + + case ESceneID_RPCowScene: { + return new RPCowScene(); + } + + case ESceneID_RPWlyScene: { + return new RPWlyScene(); + } + + case ESceneID_RPTnkScene: { + return new RPTnkScene(); + } + + case ESceneID_RPBomScene: { + return new RPBomScene(); + } + + case ESceneID_RPPartyPackTitleScene: { + return new RPPartyPackTitleScene(); + } + + case ESceneID_RPPartyRootScene: { + return new RPPartyRootScene(); + } + + case ESceneID_RPPartyMainScene: { + return new RPPartyMainScene(); + } + + default: { + return NULL; + } + } +} +#endif + +/** + * @brief Destructor + */ +RPSysSceneCreator::~RPSysSceneCreator() {} diff --git a/src/Pack/RPSystem/RPSysSceneMgr.cpp b/src/Pack/RPSystem/RPSysSceneMgr.cpp new file mode 100644 index 000000000..b15fb9d98 --- /dev/null +++ b/src/Pack/RPSystem/RPSysSceneMgr.cpp @@ -0,0 +1,501 @@ +#include +#include + +#include + +#include + +RP_SINGLETON_IMPL_EX(RPSysSceneMgr); + +/** + * @brief Constructor + * + * @param pHeap Parent heap + */ +RPSysSceneMgr::RPSysSceneMgr(EGG::Heap* pHeap) + : mpParentHeap(pHeap), mState(EState_Normal) { + + mpSceneFader = new EGG::ColorFader( // + 0.0f, 0.0f, // + RP_GET_INSTANCE(RPSysSystem)->getFBWidth(), // + RP_GET_INSTANCE(RPSysSystem)->getFBHeight() // + ); +} + +/** + * @brief Gets the currently active scene as the Pack Project type + */ +RPSysScene* RPSysSceneMgr::getCurrentSceneRP() const { + return static_cast(getCurrentScene()); +} + +/** + * @brief Performs a soft reset + * + * @param fromHBM Whether the request came from HBM + * @return Success + */ +bool RPSysSceneMgr::softReset(bool fromHBM) { + if (mState == EState_Normal) { + mState = EState_SoftReset; + + // HBM does its own fadeout + if (fromHBM) { + resetFadeFrame(); + resetFadeColor(); + setSceneStatus(EGG::Fader::STATUS_PREPARE_IN); + } + + return true; + } + + return false; +} + +/** + * @brief Returns to the IPL + * + * @param fromHBM Whether the request came from HBM + * @return Success + */ +bool RPSysSceneMgr::returnToMenu(bool fromHBM) { + if (mState == EState_Normal) { + RP_GET_INSTANCE(RPSysSaveDataMgr)->setSaveDisable(true); + mState = EState_ReturnToMenu; + + // HBM does its own fadeout + if (fromHBM) { + VISetBlack(TRUE); + } + + return true; + } + + return false; +} + +/** + * @brief Powers off the console + * + * @param fromHBM Whether the request came from HBM + * @return Success + */ +bool RPSysSceneMgr::shutdownSystem(bool fromHBM) { + if (mState == EState_Normal) { + RP_GET_INSTANCE(RPSysSaveDataMgr)->setSaveDisable(true); + mState = EState_Shutdown; + + // HBM does its own fadeout + if (fromHBM) { + VISetBlack(TRUE); + } + + return true; + } + + return false; +} + +/** + * @brief Tests whether this manager is operating normally + */ +bool RPSysSceneMgr::isNormalState() const { + return mState == EState_Normal; +} + +/** + * @brief Tests whether this manager is currently shutting down the system + */ +bool RPSysSceneMgr::isShutDownReserved() const { + return mState == EState_Shutdown; +} + +/** + * @brief Tests whether this manager is currently returning to the IPL + */ +bool RPSysSceneMgr::getReturnToMenu() const { + return mState == EState_ReturnToMenu; +} + +/** + * @brief Disables the guard state and returns to normal operation + */ +void RPSysSceneMgr::resetGuard() { + if (mState == EState_Guard) { + mState = EState_Normal; + } +} + +/** + * @brief Tests whether this manager is currently exiting the program + */ +bool RPSysSceneMgr::isApplicationEndReserved() { + return getReturnToMenu() || isShutDownReserved(); +} + +/** + * @brief Tests whether a DVD error should exit the program + */ +bool RPSysSceneMgr::isDvdErrorApplicationEnd() { + return mState != EState_Normal; +} + +/** + * @brief Requests a scene change after fading out + * @details A scene id of -1 will select the current scene. + * + * @param id New scene ID + * @param reconfigure Whether to fully reconfigure the scene + * @return Success + */ +bool RPSysSceneMgr::changeNextSceneAfterFade(s32 id, bool reconfigure) { + //! Scene change method + enum EMethod { + Default, + ChangeSiblingSceneAfterFadeOut, + CreateChildSceneAfterFadeOut, + ReInitCurrentSceneAfterFadeOut, + DestroyToSelectSceneIDAfterFadeOut, + ChangeSceneAfterFadeOut, + ChangeScene, // no fadeout + CreateChildScene, // no fadeout + }; + + EMethod method = Default; + + if (getCurrentSceneRP() != NULL) { + int current = getCurrentSceneRP()->getSceneID(); + + // Parent scene's exit type takes priority over the new create type + RPSysSceneCreator::EExitType exitType = + RP_GET_INSTANCE(RPSysSceneCreator)->getExitType(current); + + // Current scene requests that new scenes are children + if (exitType == RPSysSceneCreator::EExitType_Child) { + method = CreateChildScene; + + goto _do_change; + } + + // Current scene is being reloaded + if (current == id) { + // Usual behavior is re-init, which skips the Configure phase. + // The reconfigure parameter forces a full destroy -> create. + if (reconfigure || + exitType == RPSysSceneCreator::EExitType_Sibling) { + method = ChangeSiblingSceneAfterFadeOut; + } else { + method = ReInitCurrentSceneAfterFadeOut; + } + + goto _do_change; + } + + // Orphan scenes can be freely destroyed + if (findParentScene(id) != NULL) { + method = DestroyToSelectSceneIDAfterFadeOut; + + goto _do_change; + } + + // New scene's create type takes the lowest priority + switch (RP_GET_INSTANCE(RPSysSceneCreator)->getCreateType(id)) { + case RPSysSceneCreator::ECreateType_Standard: { + method = ChangeSceneAfterFadeOut; + break; + } + + case RPSysSceneCreator::ECreateType_Sibling: { + method = ChangeSiblingSceneAfterFadeOut; + break; + } + + case RPSysSceneCreator::ECreateType_Child: { + method = CreateChildSceneAfterFadeOut; + break; + } + } + + } else { + // No scene exists yet, nothing else needs to be done + method = ChangeScene; + } + +_do_change: + switch (method) { + case Default: + case ChangeSiblingSceneAfterFadeOut: { + return changeSiblingSceneAfterFadeOut(id); + } + + case CreateChildSceneAfterFadeOut: { + return createChildSceneAfterFadeOut(id, getCurrentSceneRP()); + } + + case CreateChildScene: { + createChildScene(id, getCurrentSceneRP()); + return true; + } + + case ReInitCurrentSceneAfterFadeOut: { + return reinitCurrentSceneAfterFadeOut(); + } + + case DestroyToSelectSceneIDAfterFadeOut: { + return destroyToSelectSceneIDAfterFadeOut(id); + } + + case ChangeSceneAfterFadeOut: { + return changeSceneAfterFadeOut(id); + } + + case ChangeScene: { + changeScene(id); + return true; + } + + default: { + return false; + } + } +} + +/** + * @brief Resets the duration of all faders + */ +void RPSysSceneMgr::resetFadeFrame() { + mpSceneFader->setFrame(DEFAULT_FADE_FRAME); + mCurrentFader->setFrame(DEFAULT_FADE_FRAME); +} + +/** + * @brief Gets the duration of the scene fader + */ +u16 RPSysSceneMgr::getFadeFrame() { + return mpSceneFader->getFrame(); +} + +/** + * @brief Sets the duration of all faders + * + * @param frame Fade duration, in frames + */ +void RPSysSceneMgr::setFadeFrame(u16 frame) { + mpSceneFader->setFrame(frame); + mCurrentFader->setFrame(frame); +} + +/** + * @brief Resets the color of all faders + * @details The default fader color is white. + */ +void RPSysSceneMgr::resetFadeColor() { + mpSceneFader->setColor(DEFAULT_FADE_COLOR); + mCurrentFader->setColor(DEFAULT_FADE_COLOR); +} + +/** + * @brief Gets the color of the manager fader + */ +nw4r::ut::Color RPSysSceneMgr::getFadeColor() { + return mCurrentFader->getColor(); +} + +/** + * @brief Sets the color of all faders + * + * @param color Fade color + */ +void RPSysSceneMgr::setFadeColor(nw4r::ut::Color color) { + mpSceneFader->setColor(color); + mCurrentFader->setColor(color); +} + +/** + * @brief Sets the color of the scene fader + * + * @param color Fade color + */ +void RPSysSceneMgr::setSceneFadeColor(nw4r::ut::Color color) { + mpSceneFader->setColor(color); +} + +/** + * @brief Gets the status of the scene fader + */ +EGG::Fader::EStatus RPSysSceneMgr::getSceneStatus() { + return mpSceneFader->getStatus(); +} + +/** + * @brief Sets the status of the scene fader + * + * @param status Fade status + */ +void RPSysSceneMgr::setSceneStatus(EGG::Fader::EStatus status) { + mpSceneFader->setStatus(status); +} + +/** + * @brief Begins fading in the manager fader + * + * @return Success + */ +bool RPSysSceneMgr::startMgrFadeIn() { + return fadeIn(); +} + +/** + * @brief Begins fading in the scene fader + * + * @return Success + */ +bool RPSysSceneMgr::startSceneFadeIn() { + return mpSceneFader->fadeIn(); +} + +/** + * @brief Begins fading out the scene fader + * + * @return Success + */ +bool RPSysSceneMgr::startSceneFadeOut() { + return mpSceneFader->fadeOut(); +} + +/** + * @brief Tests whether the scene is fully visible + */ +bool RPSysSceneMgr::isDisplay() { + return mCurrentFader->getStatus() == EGG::Fader::STATUS_PREPARE_OUT && + mpSceneFader->getStatus() == EGG::Fader::STATUS_PREPARE_OUT; +} + +/** + * @brief Tests whether the scene is visibly obscured + */ +bool RPSysSceneMgr::isBlank() { + return mCurrentFader->getStatus() == EGG::Fader::STATUS_PREPARE_IN || + mpSceneFader->getStatus() == EGG::Fader::STATUS_PREPARE_IN; +} + +/** + * @brief Tests whether the scene is fading out + */ +bool RPSysSceneMgr::isFadeOut() { + return mCurrentFader->getStatus() == EGG::Fader::STATUS_FADE_OUT || + mpSceneFader->getStatus() == EGG::Fader::STATUS_FADE_OUT; +} + +/** + * @brief Tests whether all asynchronous tasks have finished + */ +bool RPSysSceneMgr::isTaskFinished() { + if (RP_GET_INSTANCE(RPSysSaveDataMgr)->isNandAccessFinish() && + !RP_GET_INSTANCE(RPSysSystem)->getNandThread()->isTaskExist() && + !RP_GET_INSTANCE(RPSysSystem)->getDvdThread()->isTaskExist() && + !RP_GET_INSTANCE(RPSysSystem)->getWc24Thread()->isTaskExist()) { + + return true; + } + + return false; +} + +/** + * @brief Tests whether a scene change would be allowed + */ +bool RPSysSceneMgr::isSceneChangeEnable() { + if (mCurrentFader->getStatus() == EGG::Fader::STATUS_PREPARE_OUT && + RP_GET_INSTANCE(RPSysSaveDataMgr)->isNandAccessFinish() && + !RP_GET_INSTANCE(RPSysSystem)->getNandThread()->isTaskExist() && + !RP_GET_INSTANCE(RPSysSystem)->getDvdThread()->isTaskExist() && + !RP_GET_INSTANCE(RPSysSystem)->getWc24Thread()->isTaskExist()) { + + return true; + } + + return false; +} + +/** + * @brief Updates the state of the scene fader + * + * @return Whether the fade has finished + */ +bool RPSysSceneMgr::calcSceneFader() { + return mpSceneFader->calc(); +} + +/** + * @brief Displays the state of the scene fader + */ +void RPSysSceneMgr::drawSceneFader() { + mpSceneFader->draw(); +} + +/** + * @brief Displays the state of the manager fader + */ +void RPSysSceneMgr::drawMgrFader() { + mCurrentFader->draw(); +} + +/** + * @brief Updates the state of the current scene + */ +void RPSysSceneMgr::calcCurrentScene() { + updateState(); + EGG::SceneManager::calcCurrentScene(); +} + +/** + * @brief Updates the state of this manager + */ +void RPSysSceneMgr::updateState() { + if (mState == EState_Normal) { + RP_GET_INSTANCE(RPSysSystem)->setCallBack(); + return; + } + + if (isSceneChangeEnable()) { + bool success = false; + + if (mState == EState_SoftReset) { + success = RP_GET_INSTANCE(RPSysSceneCreator)->changeSoftReset(); + + } else if (mState == EState_ReturnToMenu || mState == EState_Shutdown) { + // Dummy scene change to allow RPSysSceneCreator::destroy() to exit + success = changeSceneAfterFadeOut( + RPSysSceneCreator::ESceneID_RPSysBootScene); + } + + if (success) { + resetFadeFrame(); + + if (mState == EState_SoftReset) { + if (getCurrentSceneID() != + RPSysSceneCreator::ESceneID_RPSysBootScene) { + + resetFadeColor(); + } + + RP_GET_INSTANCE(RPSndAudioMgr)->resetSystem(DEFAULT_FADE_FRAME); + mState = EState_Guard; + + } else if (mState == EState_ReturnToMenu || + mState == EState_Shutdown) { + + setFadeColor(DEFAULT_FADE_COLOR); + + RP_GET_INSTANCE(RPSndAudioMgr) + ->shutdownSystem(DEFAULT_FADE_FRAME); + } + } + } +} + +/** + * @brief Destructor + */ +RPSysSceneMgr::~RPSysSceneMgr() {} diff --git a/src/Pack/RPUtility/RPUtlDohMath.cpp b/src/Pack/RPUtility/RPUtlDohMath.cpp new file mode 100644 index 000000000..7601074ba --- /dev/null +++ b/src/Pack/RPUtility/RPUtlDohMath.cpp @@ -0,0 +1,251 @@ +#include + +#include + +/** + * @brief Sets the specified local axis of the input matrix + * + * @param pMtx Matrix + * @param axis Axis index + * @param pBase Base vector + */ +void RPUtlDohMath::MTX34SetBase(nw4r::math::MTX34* pMtx, AxisType axis, + const nw4r::math::VEC3* pBase) { + if (pBase != NULL) { + pMtx->m[0][axis] = pBase->x; + pMtx->m[1][axis] = pBase->y; + pMtx->m[2][axis] = pBase->z; + } +} + +/** + * @brief Constructs a right-handed orthonormal basis from the local axes of + * the specified matrix + * + * @param[out] pOut Output matrix + * @param pIn Input matrix + * @param order Axis priority order + */ +void RPUtlDohMath::MTX34Normalize(nw4r::math::MTX34* pOut, + const nw4r::math::MTX34* pIn, + AxisOrder order) { + + nw4r::math::VEC3 ax(pIn->_00, pIn->_10, pIn->_20); + nw4r::math::VEC3 ay(pIn->_01, pIn->_11, pIn->_21); + nw4r::math::VEC3 az(pIn->_02, pIn->_12, pIn->_22); + + switch (order) { + case AxisOrder_XY: { + nw4r::math::VEC3Normalize(&ax, &ax); + nw4r::math::VEC3Cross(&az, &ax, &ay); + + nw4r::math::VEC3Normalize(&az, &az); + nw4r::math::VEC3Cross(&ay, &az, &ax); + + nw4r::math::VEC3Normalize(&ay, &ay); + break; + } + + case AxisOrder_XZ: { + nw4r::math::VEC3Normalize(&ax, &ax); + nw4r::math::VEC3Cross(&ay, &az, &ax); + + nw4r::math::VEC3Normalize(&ay, &ay); + nw4r::math::VEC3Cross(&az, &ax, &ay); + + nw4r::math::VEC3Normalize(&az, &az); + break; + } + + case AxisOrder_YZ: { + nw4r::math::VEC3Normalize(&ay, &ay); + nw4r::math::VEC3Cross(&ax, &ay, &az); + + nw4r::math::VEC3Normalize(&ax, &ax); + nw4r::math::VEC3Cross(&az, &ax, &ay); + + nw4r::math::VEC3Normalize(&az, &az); + break; + } + + case AxisOrder_YX: { + nw4r::math::VEC3Normalize(&ay, &ay); + nw4r::math::VEC3Cross(&az, &ax, &ay); + + nw4r::math::VEC3Normalize(&az, &az); + nw4r::math::VEC3Cross(&ax, &ay, &az); + + nw4r::math::VEC3Normalize(&ax, &ax); + break; + } + + case AxisOrder_ZX: { + nw4r::math::VEC3Normalize(&az, &az); + nw4r::math::VEC3Cross(&ay, &az, &ax); + + nw4r::math::VEC3Normalize(&ay, &ay); + nw4r::math::VEC3Cross(&ax, &ay, &az); + + nw4r::math::VEC3Normalize(&ax, &ax); + break; + } + + case AxisOrder_ZY: { + nw4r::math::VEC3Normalize(&az, &az); + nw4r::math::VEC3Cross(&ax, &ay, &az); + + nw4r::math::VEC3Normalize(&ax, &ax); + nw4r::math::VEC3Cross(&ay, &az, &ax); + + nw4r::math::VEC3Normalize(&ay, &ay); + break; + } + + default: { + break; + } + } + + pOut->_00 = ax.x; + pOut->_10 = ax.y; + pOut->_20 = ax.z; + + pOut->_01 = ay.x; + pOut->_11 = ay.y; + pOut->_21 = ay.z; + + pOut->_02 = az.x; + pOut->_12 = az.y; + pOut->_22 = az.z; +} + +/** + * @brief Calculates a bend point between two endpoints + * + * @param[out] pMidPoint Bend point + * @param[out] pDistance Distance between the endpoints + * @param rBendDir Bend direction vector + * @param rPointA Endpoint A + * @param rPointB Endpoint B + * @param lengthA Length of the segment from A to the bend joint + * @param lengthB Length of the segment from the bend joint to B + */ +void RPUtlDohMath::GetMidPoint(nw4r::math::VEC3* pMidPoint, f32* pDistance, + const nw4r::math::VEC3& rBendDir, + const nw4r::math::VEC3& rPointA, + const nw4r::math::VEC3& rPointB, f32 lengthA, + f32 lengthB) { + nw4r::math::VEC3 bend; + + nw4r::math::VEC3 delta( // + rPointB.x - rPointA.x, // + rPointB.y - rPointA.y, // + rPointB.z - rPointA.z); + + // Create an orthonormal basis for the bend direction + nw4r::math::MTX34 mtx; + MTX34SetBase(&mtx, AxisType_Y, &delta); + MTX34SetBase(&mtx, AxisType_Z, &rBendDir); + MTX34Normalize(&mtx, &mtx, AxisOrder_YZ); + + bend.x = mtx._02; + bend.y = mtx._12; + bend.z = mtx._22; + + // Find the position of the joint along the segment AB + f32 total = lengthA + lengthB; + f32 ratio = lengthA / total; + + nw4r::math::VEC3 joint( // + ratio * rPointB.x + (1.0f - ratio) * rPointA.x, + ratio * rPointB.y + (1.0f - ratio) * rPointA.y, + ratio * rPointB.z + (1.0f - ratio) * rPointA.z); + + f32 distance = nw4r::math::VEC3Len(&delta); + + if (distance >= total) { + // Segment chain is fully extended, no bend + *pMidPoint = joint; + } else { + // Construct a right triangle, solving for the bend height + f32 along = distance * ratio; + f32 height = nw4r::math::FSqrt(lengthA * lengthA - along * along); + + pMidPoint->x = joint.x + bend.x * height; + pMidPoint->y = joint.y + bend.y * height; + pMidPoint->z = joint.z + bend.z * height; + } + + if (pDistance != NULL) { + *pDistance = distance; + } +} + +/** + * @brief Zero vector (3D) + */ +const nw4r::math::VEC3 RPUtlDohMath::VEC3_ZERO(0.0f, 0.0f, 0.0f); + +/** + * @brief Zero vector (2D) + */ +const nw4r::math::VEC2 RPUtlDohMath::VEC2_ZERO(0.0f, 0.0f); + +/** + * @brief Positive X-axis unit vector + */ +const nw4r::math::VEC3 RPUtlDohMath::AXIS_XP(1.0f, 0.0f, 0.0f); + +/** + * @brief Negative X-axis unit vector + */ +const nw4r::math::VEC3 RPUtlDohMath::AXIS_XN(-1.0f, 0.0f, 0.0f); + +/** + * @brief Positive Y-axis unit vector + */ +const nw4r::math::VEC3 RPUtlDohMath::AXIS_YP(0.0f, 1.0f, 0.0f); + +/** + * @brief Negative Y-axis unit vector + */ +const nw4r::math::VEC3 RPUtlDohMath::AXIS_YN(0.0f, -1.0f, 0.0f); + +/** + * @brief Positive Z-axis unit vector + */ +const nw4r::math::VEC3 RPUtlDohMath::AXIS_ZP(0.0f, 0.0f, 1.0f); + +/** + * @brief Negative Z-axis unit vector + */ +const nw4r::math::VEC3 RPUtlDohMath::AXIS_ZN(0.0f, 0.0f, -1.0f); + +/** + * @brief 3x4 identity matrix + */ +const nw4r::math::MTX34 RPUtlDohMath::MTX34_IDENT( // + 1.0f, 0.0f, 0.0f, 0.0f, // + 0.0f, 1.0f, 0.0f, 0.0f, // + 0.0f, 0.0f, 1.0f, 0.0f // +); + +/** + * @brief 3x3 identity matrix + */ +const nw4r::math::MTX33 RPUtlDohMath::MTX33_IDENT( // + 1.0f, 0.0f, 0.0f, // + 0.0f, 1.0f, 0.0f, // + 0.0f, 0.0f, 1.0f // +); + +/** + * @brief Identity quaternion + */ +const nw4r::math::QUAT RPUtlDohMath::QUAT_IDENT(0.0f, 0.0f, 0.0f, 1.0f); + +/** + * @brief Float close to zero for tolerance checks + * @note Same as JGeometry's epsilon + */ +const f32 RPUtlDohMath::FLOAT_EPSILON = 32.0f * FLT_EPSILON; diff --git a/src/nw4r/ef/ef_emitter.cpp b/src/nw4r/ef/ef_emitter.cpp index 898c70549..3daefb433 100644 --- a/src/nw4r/ef/ef_emitter.cpp +++ b/src/nw4r/ef/ef_emitter.cpp @@ -1120,7 +1120,7 @@ u32 Emitter::ForeachParticleManager(ForEachFunc pFunc, ForEachParam param, pFunc(it, param); calls++; - }) + }); // TODO(kiwi) I think this is doing the same for all sibling emitters? if (propogate) { diff --git a/src/revolution/VI/vi.c b/src/revolution/VI/vi.c new file mode 100644 index 000000000..052bdcb37 --- /dev/null +++ b/src/revolution/VI/vi.c @@ -0,0 +1,16 @@ +#include + +static VIRetraceCallback PreCB; +static void* CurrBufAddr; + +VIRetraceCallback VISetPreRetraceCallback(VIRetraceCallback callback) { + VIRetraceCallback currCB = PreCB; + BOOL enabled = OSDisableInterrupts(); + PreCB = callback; + OSRestoreInterrupts(enabled); + return currCB; +} + +void* VIGetCurrentFrameBuffer(void) { + return CurrBufAddr; +}