diff --git a/config/RSPE01_01/splits.txt b/config/RSPE01_01/splits.txt index df4085de5..39536b2cf 100644 --- a/config/RSPE01_01/splits.txt +++ b/config/RSPE01_01/splits.txt @@ -3990,13 +3990,13 @@ Pack/RPSports/RPBowScene/RPBow_80315998.cpp: .text start:0x80315998 end:0x8031641C .sdata2 start:0x804C5B00 end:0x804C5B48 -Pack/RPSports/RPBowScene/RPBow_8031641C.cpp: +Pack/RPSports/RPBowScene/RPBowSceneObjectManager.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: +Pack/RPSports/RPBowScene/RPBowCameraTransform.cpp: .text start:0x80319C98 end:0x8031C388 .sdata2 start:0x804C5B80 end:0x804C5CB8 @@ -4004,12 +4004,12 @@ Pack/RPSports/RPBowScene/RPBowSwing.cpp: .text start:0x8031C388 end:0x8031ECB4 .sdata2 start:0x804C5CB8 end:0x804C5D28 -Pack/RPSports/RPBowScene/RPBow_8031C388.cpp: +Pack/RPSports/RPBowScene/RPBowAlleyModelManager.cpp: .text start:0x8031ECB4 end:0x8031EFE4 .rodata start:0x803929C8 end:0x803929E0 .sdata2 start:0x804C5D28 end:0x804C5D30 -Pack/RPSports/RPBowScene/RPBow_8031EFE4.cpp: +Pack/RPSports/RPBowScene/RPBowLaneDataHolder.cpp: .text start:0x8031EFE4 end:0x80320EFC .sdata2 start:0x804C5D30 end:0x804C5DC8 @@ -4038,27 +4038,27 @@ Pack/RPSports/RPBowScene/RPBow_80329658.cpp: .sdata2 start:0x804C6098 end:0x804C60E0 Pack/RPSports/RPBowScene/RPBowActiveBall.cpp: - .text start:0x8032A9E8 end:0x8032ADD8 + .text start:0x8032A9E8 end:0x8032AE54 .sdata2 start:0x804C60E0 end:0x804C6100 -Pack/RPSports/RPBowScene/RPBow_8032ADD8.cpp: - .text start:0x8032ADD8 end:0x8032EA58 +Pack/RPSports/RPBowScene/RPBowScoreManager.cpp: + .text start:0x8032AE54 end:0x8032B3D8 .rodata start:0x80392B30 end:0x80392B58 - .sdata2 start:0x804C6100 end:0x804C6158 + .sdata2 start:0x804C6100 end:0x804C6128 -Pack/RPSports/RPBowScene/RPBow_8032EA58.cpp: - .text start:0x8032EA58 end:0x80330830 +Pack/RPSports/RPBowScene/RPBowGameManager.cpp: + .text start:0x8032B3D8 end:0x8032F514 + .sdata2 start:0x804C6128 end:0x804C6158 + +Pack/RPSports/RPBowScene/RPBowGameModeState.cpp: + .text start:0x8032F514 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 + .text start:0x80330830 end:0x80330FE8 + .sdata2 start:0x804C6178 end:0x804C6188 Pack/RPSports/RPBowScene/RPBow_80330FE8.cpp: .text start:0x80330FE8 end:0x80331654 @@ -4074,14 +4074,11 @@ Pack/RPSports/RPBowScene/RPBowManagerContext.cpp: .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 +Pack/RPSports/RPBowScene/RPBowNpcContext.cpp: + .text start:0x80332C24 end:0x803345F0 .sdata2 start:0x804C61D8 end:0x804C6260 -Pack/RPSports/RPBowScene/RPBowPinSetter.cpp: +Pack/RPSports/RPBowScene/RPBowPinSetterManager.cpp: .text start:0x803345F0 end:0x803349E0 .sdata2 start:0x804C6260 end:0x804C6288 @@ -4108,7 +4105,7 @@ Pack/RPSports/RPBowScene/RPBow_8033B690.cpp: .rodata start:0x80392EE8 end:0x80392EF8 .sdata2 start:0x804C6390 end:0x804C6440 -Pack/RPSports/RPBowScene/RPBow_8033FD0C.cpp: +Pack/RPSports/RPBowScene/RPBowPowerThrowsPinManager.cpp: .text start:0x8033FD0C end:0x80340308 .sdata2 start:0x804C6440 end:0x804C6450 @@ -4134,21 +4131,20 @@ Pack/RPSports/RPBowScene/RPBow_8034656C.cpp: .sdata2 start:0x804C6518 end:0x804C65C0 Pack/RPSports/RPBowScene/RPBowPlayerLaneNpc.cpp: - .text start:0x80346E60 end:0x80347574 - .sdata2 start:0x804C65C0 end:0x804C65EC + .text start:0x80346E60 end:0x803475E4 + .ctors start:0x80355254 end:0x80355258 + .sdata2 start:0x804C65C0 end:0x804C6610 Pack/RPSports/RPBowScene/RPBow_80347574.cpp: - .text start:0x80347574 end:0x80347D0C - .ctors start:0x80355254 end:0x80355258 + .text start:0x803475E4 end:0x80347D0C .rodata start:0x80393180 end:0x803931A0 - .sdata2 start:0x804C65EC end:0x804C6610 -Pack/RPSports/RPBowScene/RPBow_80347D0C.cpp: +Pack/RPSports/RPBowScene/RPBowPinSetterModel.cpp: .text start:0x80347D0C end:0x80348158 .rodata start:0x803931A0 end:0x803931C0 .sdata2 start:0x804C6610 end:0x804C6628 -Pack/RPSports/RPBowScene/RPBow_80348158.cpp: +Pack/RPSports/RPBowScene/RPBowCameraController.cpp: .text start:0x80348158 end:0x80348858 .rodata start:0x803931C0 end:0x80393350 .sdata2 start:0x804C6628 end:0x804C6660 @@ -4157,7 +4153,7 @@ Pack/RPSports/RPBowScene/RPBow_80348858.cpp: .text start:0x80348858 end:0x8034C1AC .sdata2 start:0x804C6660 end:0x804C67C8 -Pack/RPSports/RPBowScene/RPBow_8034C1AC.cpp: +Pack/RPSports/RPBowScene/RPBowSceneDirector.cpp: .text start:0x8034C1AC end:0x8034C95C .sdata2 start:0x804C67C8 end:0x804C67E0 @@ -4179,46 +4175,53 @@ Pack/RPSports/RPBowScene/RPBowBackgroundNpcManager.cpp: .bss start:0x804BD328 end:0x804BD36C .sdata2 start:0x804C6898 end:0x804C68F8 -Pack/RPSports/RPBowScene/RPBow_8034E974.cpp: - .text start:0x8034E974 end:0x8034F710 +Pack/RPSports/RPBowScene/RPBowRegularPinManager.cpp: + .text start:0x8034E974 end:0x8034F53C .rodata start:0x80393350 end:0x80393360 .sdata2 start:0x804C68F8 end:0x804C6930 Pack/RPSports/RPBowScene/RPBow_8034F710.cpp: - .text start:0x8034F710 end:0x803501D8 + .text start:0x8034F53C end:0x80350120 .rodata start:0x80393360 end:0x80393398 .sdata2 start:0x804C6930 end:0x804C6948 Pack/RPSports/RPBowScene/RPBow_803501D8.cpp: - .text start:0x803501D8 end:0x80350F78 + .text start:0x80350120 end:0x80350F78 + .rodata start:0x80393398 end:0x80393410 + .sdata start:0x804BE968 end:0x804BE9D0 .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/RPBowScoreLayout.cpp: + .text start:0x80350F78 end:0x8035142C + .rodata start:0x80393410 end:0x803934F8 + .sdata2 start:0x804C6950 end:0x804C6958 -Pack/RPSports/RPBowScene/RPBow_80351D58.cpp: - .text start:0x80351D58 end:0x803520F0 - .sdata2 start:0x804C6968 end:0x804C6970 +Pack/RPSports/RPBowScene/RPBowNormalPinLayout.cpp: + .text start:0x8035142C end:0x80351818 + .rodata start:0x803934F8 end:0x80393520 + .sdata2 start:0x804C6958 end:0x804C6960 -Pack/RPSports/RPBowScene/RPBow_803520F0.cpp: - .text start:0x803520F0 end:0x80353214 +Pack/RPSports/RPBowScene/RPBowPowerThrowsPinLayout.cpp: + .text start:0x80351818 end:0x80351D10 + .rodata start:0x80393520 end:0x80393578 + .sdata2 start:0x804C6960 end:0x804C6968 + +Pack/RPSports/RPBowScene/RPBowLayoutManager.cpp: + .text start:0x80351D10 end:0x803531FC .rodata start:0x80393578 end:0x803937C0 - .sdata2 start:0x804C6970 end:0x804C6978 + .sdata2 start:0x804C6968 end:0x804C6978 -Pack/RPSports/RPBowScene/RPBow_80353214.cpp: - .text start:0x80353214 end:0x803536C4 +Pack/RPSports/RPBowScene/RPBowTrainingLivesLayout.cpp: + .text start:0x803531FC end:0x803536CC .rodata start:0x803937C0 end:0x80393848 .sdata2 start:0x804C6978 end:0x804C6980 -Pack/RPSports/RPBowScene/RPBow_803536C4.cpp: - .text start:0x803536C4 end:0x80353C8C +Pack/RPSports/RPBowScene/RPBowPowerThrowsRoundsLayout.cpp: + .text start:0x803536CC end:0x80353C8C .rodata start:0x80393848 end:0x803938C8 .sdata2 start:0x804C6980 end:0x804C6988 -Pack/RPSports/RPBowScene/RPBow_80353C8C.cpp: +Pack/RPSports/RPBowScene/RPBowAimGuideLayout.cpp: .text start:0x80353C8C end:0x803543A8 .rodata start:0x803938C8 end:0x803939F0 .sdata2 start:0x804C6988 end:0x804C6998 @@ -4227,14 +4230,11 @@ 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 +Pack/RPSports/RPBowScene/RPBowBallHistoryEntry.cpp: + .text start:0x803547A4 end:0x80354CA4 .sdata2 start:0x804C69C0 end:0x804C69C8 -Pack/RPSports/RPBowScene/RPBow_80354CAC.cpp: - .text start:0x80354CAC end:0x8035507C +Pack/RPSports/RPBowScene/RPBowPerfectGameUI.cpp: + .text start:0x80354CA4 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 4ea2385f4..87eb42008 100644 --- a/config/RSPE01_01/symbols.txt +++ b/config/RSPE01_01/symbols.txt @@ -14041,12 +14041,12 @@ fn_803140B4 = .text:0x803140B4; // type:function size:0x50 fn_80314104 = .text:0x80314104; // type:function size:0x3DC fn_803144E0 = .text:0x803144E0; // type:function size:0xE14 fn_803152F4 = .text:0x803152F4; // type:function size:0x8C -fn_80315380 = .text:0x80315380; // type:function size:0x40 +__dt__15ThrowPosState_AFv = .text:0x80315380; // type:function size:0x40 fn_803153C0 = .text:0x803153C0; // type:function size:0x104 -fn_803154C4 = .text:0x803154C4; // type:function size:0x40 -fn_80315504 = .text:0x80315504; // type:function size:0x1C -fn_80315520 = .text:0x80315520; // type:function size:0x40 -fn_80315560 = .text:0x80315560; // type:function size:0x1C +__dt__20LaneContextSubClassBFv = .text:0x803154C4; // type:function size:0x40 +__ct__20LaneContextSubClassBFv = .text:0x80315504; // type:function size:0x1C +__dt__20LaneContextSubClassAFv = .text:0x80315520; // type:function size:0x40 +__ct__20LaneContextSubClassAFv = .text:0x80315560; // type:function size:0x1C fn_8031557C = .text:0x8031557C; // type:function size:0x58 fn_803155D4 = .text:0x803155D4; // type:function size:0x58 fn_8031562C = .text:0x8031562C; // type:function size:0x58 @@ -14093,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__7BowlingFPQ27Bowling15SomeUnkManager0Pvi = .text:0x80316A48; // type:function size:0x34 +ProcessCamera__23RPBowSceneObjectManagerFP16CameraProjectionP20RPBowCameraTransform = .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 @@ -14117,12 +14117,12 @@ fn_8031EB18 = .text:0x8031EB18; // type:function size:0x58 fn_8031EB70 = .text:0x8031EB70; // type:function size:0x58 fn_8031EBC8 = .text:0x8031EBC8; // type:function size:0xE8 fn_8031ECB0 = .text:0x8031ECB0; // type:function size:0x4 -fn_8031ECB4 = .text:0x8031ECB4; // type:function size:0x278 -fn_8031EF2C = .text:0x8031EF2C; // type:function size:0x1C -fn_8031EF48 = .text:0x8031EF48; // type:function size:0x14 -fn_8031EF5C = .text:0x8031EF5C; // type:function size:0x28 -fn_8031EF84 = .text:0x8031EF84; // type:function size:0x5C -fn_8031EFE0 = .text:0x8031EFE0; // type:function size:0x4 +UpdateModels__22RPBowAlleyModelManagerFv = .text:0x8031ECB4; // type:function size:0x278 +ResetSceneParams__22RPBowAlleyModelManagerFv = .text:0x8031EF2C; // type:function size:0x1C +SetModelSlot__22RPBowAlleyModelManagerFiP10RPGrpModelP10RPGrpModel = .text:0x8031EF48; // type:function size:0x14 +SetModels__22RPBowAlleyModelManagerFP10RPGrpModelP10RPGrpModelP10RPGrpModelP10RPGrpModelP10RPGrpModelP10RPGrpModelP10RPGrpModelP10RPGrpModel = .text:0x8031EF5C; // type:function size:0x28 +__dt__22RPBowAlleyModelManagerFv = .text:0x8031EF84; // type:function size:0x5C +fn_8031EFE0__22RPBowAlleyModelManagerFv = .text:0x8031EFE0; // type:function size:0x4 fn_8031EFE4 = .text:0x8031EFE4; // type:function size:0x130 fn_8031F114 = .text:0x8031F114; // type:function size:0x6C fn_8031F180 = .text:0x8031F180; // type:function size:0x10C @@ -14180,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__7BowlingFPQ27Bowling9PinStatusPQ27Bowling11LaneContext = .text:0x80324994; // type:function size:0xC0 +fn_80324994__FP9PinStatusP11LaneContext = .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__7BowlingFPQ27Bowling11LaneContext = .text:0x80324B10; // type:function size:0x8 +fn_80324B10__11LaneContextFv = .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__7BowlingFPQ27Bowling11LaneContextPQ34nw4r4math4VEC3 = .text:0x80324DD0; // type:function size:0x2C8 +fn_80324DD0__11LaneContextFPQ34nw4r4math4VEC3Uc = .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 @@ -14199,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__7BowlingFPQ27Bowling11LaneContext = .text:0x80325154; // type:function size:0x1A8 +fn_80325154__11LaneContextFv = .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 @@ -14241,17 +14241,17 @@ 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__7BowlingFPQ27Bowling11LaneContext = .text:0x80327218; // type:function size:0x44 +fn_80327218__11LaneContextFv = .text:0x80327218; // type:function size:0x44 fn_8032725C = .text:0x8032725C; // type:function size:0xD4 -fn_80327330__7BowlingFPQ27Bowling11LaneContextPQ27Bowling9PinStatus = .text:0x80327330; // type:function size:0x174 +fn_80327330__11LaneContextFP9PinStatus = .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__7BowlingFPQ27Bowling11LaneContext = .text:0x803277B4; // type:function size:0x68 +fn_803277B4__11LaneContextFv = .text:0x803277B4; // type:function size:0x68 fn_8032781C = .text:0x8032781C; // type:function size:0x3C -fn_80327858 = .text:0x80327858; // type:function size:0x298 +fn_80327858__11LaneContextFiifP19RPBowPinSetterModel = .text:0x80327858; // type:function size:0x298 fn_80327AF0 = .text:0x80327AF0; // type:function size:0xA0 fn_80327B90 = .text:0x80327B90; // type:function size:0x4C __ct__15TRPSndObject<4>FRQ34nw4r3snd18SoundArchivePlayerRQ34nw4r3snd14Sound3DManagerUl = .text:0x80327BDC; // type:function size:0x70 @@ -14276,12 +14276,12 @@ fn_80328918 = .text:0x80328918; // type:function size:0x7C fn_80328994 = .text:0x80328994; // type:function size:0x26C fn_80328C00 = .text:0x80328C00; // type:function size:0x198 fn_80328D98 = .text:0x80328D98; // type:function size:0x2F0 -fn_80329088 = .text:0x80329088; // type:function size:0xFC +fn_80329088__11PhysicsBodyFffff = .text:0x80329088; // type:function size:0xFC 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__7BowlingFPQ27Bowling11LaneBvhDataPvPv = .text:0x803295D0; // type:function size:0x88 +fn_803295D0__FP11LaneBvhDataPvPv = .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 @@ -14293,11 +14293,11 @@ 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 -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 +RenderModelSet__15RPBowActiveBallFv = .text:0x8032A9E8; // type:function size:0x3A0 +ResetRenderState__15RPBowActiveBallFv = .text:0x8032AD88; // type:function size:0x50 +SetModelSet__15RPBowActiveBallFUlP10RPGrpModelP10RPGrpModel = .text:0x8032ADD8; // type:function size:0x1C +fn_8032ADF4__15RPBowActiveBallFv = .text:0x8032ADF4; // type:function size:0x4 +__dt__15RPBowActiveBallFv = .text:0x8032ADF8; // type:function size:0x5C fn_8032AE54 = .text:0x8032AE54; // type:function size:0x48 fn_8032AE9C = .text:0x8032AE9C; // type:function size:0x148 fn_8032AFE4 = .text:0x8032AFE4; // type:function size:0x3C8 @@ -14326,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 -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 -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 +UpdateBallsMdl__22RPBowGlobalLaneManagerFP23RPBowSceneObjectManager = .text:0x80330830; // type:function size:0x130 +UpdateLaneItems__22RPBowGlobalLaneManagerFP20RPBowCameraTransformP16CameraProjectionP23RPBowSceneObjectManagerb = .text:0x80330960; // type:function size:0x1F8 +TickNpcLanes__22RPBowGlobalLaneManagerFv = .text:0x80330B58; // type:function size:0x4C +UpdateBallsPhysics__22RPBowGlobalLaneManagerFv = .text:0x80330BA4; // type:function size:0x8C +SetLaneUnknownState__22RPBowGlobalLaneManagerFi = .text:0x80330C30; // type:function size:0x3C +ResetLanePinsAndAnimations__22RPBowGlobalLaneManagerFv = .text:0x80330C6C; // type:function size:0x7C +SetupBallManagerLaneObjects__22RPBowGlobalLaneManagerFPvPv = .text:0x80330CE8; // type:function size:0x64 +InitializeBallManagerLanes__22RPBowGlobalLaneManagerFv = .text:0x80330D4C; // type:function size:0x4C +CheckBallLaneIntersection__FPff = .text:0x80330D98; // type:function size:0x124 +InitializeLaneContexts__22RPBowGlobalLaneManagerFP23RPBowSceneObjectManager = .text:0x80330EBC; // type:function size:0x12C +CalculateNpcThrowVelocity__FPQ34nw4r4math4VEC3PC15RPBowNpcManagerPCQ34nw4r4math4VEC3PC9PinStatus = .text:0x80330FE8; // type:function size:0x66C +DebugPrintNpcState__15RPBowNpcManagerFv = .text:0x80331654; // type:function size:0xFC +Update__15RPBowNpcManagerFv = .text:0x80331750; // type:function size:0xDF0 +ActivateNpcTurn__15RPBowNpcManagerFv = .text:0x80332540; // type:function size:0x7C +SetStateFlag__15RPBowNpcManagerFUc = .text:0x803325BC; // type:function size:0x8 +IsLaneIdle__15RPBowNpcManagerFv = .text:0x803325C4; // type:function size:0x10 +Setup__15RPBowNpcManagerFP11LaneContextP15RPBowNpcContextP15RPBowNpcContextP15RPBowNpcContextiP19RPBowBallReturnRackPv = .text:0x803325D4; // type:function size:0xA4 +InitAudioActors__15RPBowNpcManagerFi = .text:0x80332678; // type:function size:0x184 +DebugPrintStates__19RPBowManagerContextFv = .text:0x803327FC; // type:function size:0x58 +UpdateNpcs__19RPBowManagerContextFv = .text:0x80332854; // type:function size:0x1B8 +SetNpcStateFlags__19RPBowManagerContextFUc = .text:0x80332A0C; // type:function size:0x5C +LinkNpcLanes__19RPBowManagerContextFP22RPBowGlobalLaneManagerP23RPBowSceneObjectManager = .text:0x80332A68; // type:function size:0xCC +Initialize__19RPBowManagerContextFv = .text:0x80332B34; // type:function size:0x98 +__dt__15RPBowNpcManagerFv = .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 -CalculateNpcBallTransform__7BowlingFPQ34nw4r4math5MTX34PCQ27Bowling10NpcContext = .text:0x803340A4; // type:function size:0x1CC -fn_80334270__7BowlingFPQ27Bowling10NpcContext = .text:0x80334270; // type:function size:0xEC +CalculateNpcBallTransform__FPQ34nw4r4math5MTX34PC15RPBowNpcContext = .text:0x803340A4; // type:function size:0x1CC +fn_80334270__15RPBowNpcContextFv = .text:0x80334270; // type:function size:0xEC fn_8033435C = .text:0x8033435C; // type:function size:0x48 fn_803343A4 = .text:0x803343A4; // type:function size:0xA0 -UpdateNpcLane__7BowlingFPUcPCQ27Bowling10NpcContext = .text:0x80334444; // type:function size:0x8 -InitNpcContext__7BowlingFPQ27Bowling10NpcContextii = .text:0x8033444C; // type:function size:0x70 +UpdateNpcLane__FPUcPC15RPBowNpcContext = .text:0x80334444; // type:function size:0x8 +InitNpcContext__15RPBowNpcContextFii = .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__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_803345F0__11LaneContextFv = .text:0x803345F0; // type:function size:0x4 +IsPinSetterActive__11LaneContextFv = .text:0x803345F4; // type:function size:0x24 +UpdatePinSetter__11LaneContextFv = .text:0x80334618; // type:function size:0x344 +TriggerPinSetter__11LaneContextFi = .text:0x8033495C; // type:function size:0x24 +ResetPinSetterState__11LaneContextFUc = .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 @@ -14387,7 +14387,7 @@ fn_8033871C = .text:0x8033871C; // type:function size:0x4 fn_80338720 = .text:0x80338720; // type:function size:0x4 fn_80338724 = .text:0x80338724; // type:function size:0x3C fn_80338760 = .text:0x80338760; // type:function size:0xD5C -fn_803394BC = .text:0x803394BC; // type:function size:0x4 +__ct__15ThrowPosState_AFv = .text:0x803394BC; // type:function size:0x4 fn_803394C0 = .text:0x803394C0; // type:function size:0x124 fn_803395E4 = .text:0x803395E4; // type:function size:0x878 fn_80339E5C = .text:0x80339E5C; // type:function size:0x6FC @@ -14406,22 +14406,22 @@ fn_8033E69C = .text:0x8033E69C; // type:function size:0x2D4 fn_8033E970 = .text:0x8033E970; // type:function size:0x1BC fn_8033EB2C = .text:0x8033EB2C; // type:function size:0x5B0 fn_8033F0DC = .text:0x8033F0DC; // type:function size:0xC30 -fn_8033FD0C = .text:0x8033FD0C; // type:function size:0x150 -fn_8033FE5C = .text:0x8033FE5C; // type:function size:0x244 -fn_803400A0 = .text:0x803400A0; // type:function size:0xF4 -fn_80340194 = .text:0x80340194; // type:function size:0x4 -fn_80340198 = .text:0x80340198; // type:function size:0x84 -fn_8034021C = .text:0x8034021C; // type:function size:0x4 -fn_80340220 = .text:0x80340220; // type:function size:0x78 -fn_80340298 = .text:0x80340298; // type:function size:0x5C +ClearMatrices__26RPBowPowerThrowsPinManagerFi = .text:0x8033FD0C; // type:function size:0x150 +TransformMatrix__26RPBowPowerThrowsPinManagerFiPCQ34nw4r4math5MTX34f = .text:0x8033FE5C; // type:function size:0x244 +CopyMatrices__26RPBowPowerThrowsPinManagerFP10RPGrpModel = .text:0x803400A0; // type:function size:0xF4 +fn_80340194__26RPBowPowerThrowsPinManagerFv = .text:0x80340194; // type:function size:0x4 +UpdateModels__26RPBowPowerThrowsPinManagerFv = .text:0x80340198; // type:function size:0x84 +fn_8034021C__26RPBowPowerThrowsPinManagerFv = .text:0x8034021C; // type:function size:0x4 +SetModels__26RPBowPowerThrowsPinManagerFP10RPGrpModelP10RPGrpModel = .text:0x80340220; // type:function size:0x78 +__dt__26RPBowPowerThrowsPinManagerFv = .text:0x80340298; // type:function size:0x5C fn_803402F4 = .text:0x803402F4; // type:function size:0x8 fn_803402FC = .text:0x803402FC; // type:function size:0x8 -fn_80340304 = .text:0x80340304; // type:function size:0x4 -fn_80340308 = .text:0x80340308; // type:function size:0x328 -fn_80340630 = .text:0x80340630; // type:function size:0x1F8 -fn_80340828 = .text:0x80340828; // type:function size:0xF8 -fn_80340920 = .text:0x80340920; // type:function size:0x140 -fn_80340A60 = .text:0x80340A60; // type:function size:0x1D4 +fn_80340304__26RPBowPowerThrowsPinManagerFv = .text:0x80340304; // type:function size:0x4 +UpdateObstacleCollisionBounds__20RPBowObstacleManagerFv = .text:0x80340308; // type:function size:0x328 +ResetLaneObstacles__20RPBowObstacleManagerFUlUlf = .text:0x80340630; // type:function size:0x1F8 +CheckObstaclePassed__20RPBowObstacleManagerFUlPQ34nw4r4math4VEC3 = .text:0x80340828; // type:function size:0xF8 +CheckObstacleCollision__20RPBowObstacleManagerFUlPQ34nw4r4math4VEC3 = .text:0x80340920; // type:function size:0x140 +UpdatePinHitState__FP9PinStatusP20RPBowObstacleManagerUlUl = .text:0x80340A60; // type:function size:0x1D4 fn_80340C34 = .text:0x80340C34; // type:function size:0x14 fn_80340C48 = .text:0x80340C48; // type:function size:0x3A4 fn_80340FEC = .text:0x80340FEC; // type:function size:0x3A4 @@ -14488,11 +14488,11 @@ fn_80347BA8 = .text:0x80347BA8; // type:function size:0xF4 fn_80347C9C = .text:0x80347C9C; // type:function size:0x5C fn_80347CF8 = .text:0x80347CF8; // type:function size:0x10 fn_80347D08 = .text:0x80347D08; // type:function size:0x4 -fn_80347D0C = .text:0x80347D0C; // type:function size:0x2D0 -fn_80347FDC = .text:0x80347FDC; // type:function size:0x58 -fn_80348034 = .text:0x80348034; // type:function size:0xBC -fn_803480F0 = .text:0x803480F0; // type:function size:0xC -fn_803480FC = .text:0x803480FC; // type:function size:0x5C +Calc__19RPBowPinSetterModelFv = .text:0x80347D0C; // type:function size:0x2D0 +SetOffsetXZ__19RPBowPinSetterModelFff = .text:0x80347FDC; // type:function size:0x58 +Reset__19RPBowPinSetterModelFv = .text:0x80348034; // type:function size:0xBC +SetModels__19RPBowPinSetterModelFP10RPGrpModelP10RPGrpModel = .text:0x803480F0; // type:function size:0xC +__dt__19RPBowPinSetterModelFv = .text:0x803480FC; // type:function size:0x5C fn_80348158 = .text:0x80348158; // type:function size:0x120 fn_80348278 = .text:0x80348278; // type:function size:0x248 fn_803484C0 = .text:0x803484C0; // type:function size:0x1D4 @@ -14508,46 +14508,46 @@ 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__7BowlingFPQ27Bowling12NpcIdleState = .text:0x8034C95C; // type:function size:0x668 -fn_8034CFC4__7BowlingFPQ27Bowling12NpcIdleStateii = .text:0x8034CFC4; // type:function size:0xD0 +fn_8034C95C__FP12NpcIdleState = .text:0x8034C95C; // type:function size:0x668 +fn_8034CFC4__FP12NpcIdleStateii = .text:0x8034CFC4; // type:function size:0xD0 fn_8034D094 = .text:0x8034D094; // type:function size:0x90 fn_8034D124 = .text:0x8034D124; // type:function size:0x4 -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 -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 +DrawBlur__15RPBowMotionBlurFPv = .text:0x8034D128; // type:function size:0x1B0 +UpdateBlurTransform__15RPBowMotionBlurFPCQ34nw4r4math5MTX34f = .text:0x8034D2D8; // type:function size:0x194 +DeactivateBlur__15RPBowMotionBlurFv = .text:0x8034D46C; // type:function size:0xC +SetBlurModels__15RPBowMotionBlurFP10RPGrpModelP10RPGrpModelP10RPGrpModelP10RPGrpModelP10RPGrpModelP10RPGrpModel = .text:0x8034D478; // type:function size:0x1C +__dt__15RPBowMotionBlurFv = .text:0x8034D494; // type:function size:0x5C +fn_8034D4F0__15RPBowMotionBlurFv = .text:0x8034D4F0; // type:function size:0x4 +UpdateBallReturnRack__19RPBowBallReturnRackFl = .text:0x8034D4F4; // type:function size:0x3E8 +GetBallSlotIndex__19RPBowBallReturnRackFl = .text:0x8034D8DC; // type:function size:0x10 +ReleaseBallFromNPC__19RPBowBallReturnRackFl = .text:0x8034D8EC; // type:function size:0x14 +SpawnBallOnRack__19RPBowBallReturnRackFl = .text:0x8034D900; // type:function size:0x28 +IsBallOnRack__19RPBowBallReturnRackFl = .text:0x8034D928; // type:function size:0x10 +RemoveBallFromRack__19RPBowBallReturnRackFl = .text:0x8034D938; // type:function size:0x14 +SelectBallForNPC__19RPBowBallReturnRackFv = .text:0x8034D94C; // type:function size:0x1C8 +ResetRackBallStates__19RPBowBallReturnRackFv = .text:0x8034DB14; // type:function size:0xBC +InitBallSlotResources__19RPBowBallReturnRackFlP10RPGrpModelP10RPGrpModell = .text:0x8034DBD0; // type:function size:0x20 +InitBallReturnRack__19RPBowBallReturnRackFl = .text:0x8034DBF0; // type:function size:0xA8 fn_8034DC98 = .text:0x8034DC98; // type:function size:0x70 -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 -fn_8034F440 = .text:0x8034F440; // type:function size:0x4 -fn_8034F444 = .text:0x8034F444; // type:function size:0x8C -fn_8034F4D0 = .text:0x8034F4D0; // type:function size:0x5C +fn_8034DD08__25RPBowBackgroundNpcManagerFv = .text:0x8034DD08; // type:function size:0x4 +fn_8034DD0C__25RPBowBackgroundNpcManagerFv = .text:0x8034DD0C; // type:function size:0x8 +fn_8034DD14__25RPBowBackgroundNpcManagerFv = .text:0x8034DD14; // type:function size:0x4 +Render__25RPBowBackgroundNpcManagerFv = .text:0x8034DD18; // type:function size:0x3F0 +UpdateMovement__25RPBowBackgroundNpcManagerFPQ34nw4r4math4VEC3Pb = .text:0x8034E108; // type:function size:0x638 +Reset__25RPBowBackgroundNpcManagerFv = .text:0x8034E740; // type:function size:0xFC +fn_8034E83C__25RPBowBackgroundNpcManagerFv = .text:0x8034E83C; // type:function size:0x4 +SetModelGroups__25RPBowBackgroundNpcManagerFiP12RPSysKokeshiP12RPSysKokeshi = .text:0x8034E840; // type:function size:0x14 +InitializeConfig__25RPBowBackgroundNpcManagerFi = .text:0x8034E854; // type:function size:0x98 +__dt__25RPBowBackgroundNpcManagerFv = .text:0x8034E8EC; // type:function size:0x80 +fn_8034E96C = .text:0x8034E96C; // type:function size:0x8 +HideExcessPins__22RPBowRegularPinManagerFi = .text:0x8034E974; // type:function size:0x168 +CalculatePinTransforms__22RPBowRegularPinManagerFifPQ34nw4r4math5MTX34PQ34nw4r4math5MTX34PQ34nw4r4math5MTX34 = .text:0x8034EADC; // type:function size:0x594 +CopyMatricesToModel__22RPBowRegularPinManagerFP10RPGrpModel = .text:0x8034F070; // type:function size:0xF4 +fn_8034F164__22RPBowRegularPinManagerFv = .text:0x8034F164; // type:function size:0x4 +Calc__22RPBowRegularPinManagerFv = .text:0x8034F168; // type:function size:0x2D8 +fn_8034F440__22RPBowRegularPinManagerFv = .text:0x8034F440; // type:function size:0x4 +InitializeModels__22RPBowRegularPinManagerFP10RPGrpModelP10RPGrpModel = .text:0x8034F444; // type:function size:0x8C +__dt__22RPBowRegularPinManagerFv = .text:0x8034F4D0; // type:function size:0x5C fn_8034F52C = .text:0x8034F52C; // type:function size:0x8 fn_8034F534 = .text:0x8034F534; // type:function size:0x8 fn_8034F53C = .text:0x8034F53C; // type:function size:0x30 @@ -14566,101 +14566,101 @@ fn_80350120 = .text:0x80350120; // type:function size:0x10 fn_80350130 = .text:0x80350130; // type:function size:0xA8 fn_803501D8 = .text:0x803501D8; // type:function size:0xA0 fn_80350278 = .text:0x80350278; // type:function size:0xD00 -fn_80350F78 = .text:0x80350F78; // type:function size:0x7C -fn_80350FF4 = .text:0x80350FF4; // type:function size:0x304 -fn_803512F8 = .text:0x803512F8; // type:function size:0xD0 -fn_803513C8 = .text:0x803513C8; // type:function size:0x5C +Reset__16RPBowScoreLayoutFv = .text:0x80350F78; // type:function size:0x7C +Init__16RPBowScoreLayoutFP19RPSysLytResAccessorUl = .text:0x80350FF4; // type:function size:0x304 +InitIcons__16RPBowScoreLayoutFv = .text:0x803512F8; // type:function size:0xD0 +__dt__16RPBowScoreLayoutFv = .text:0x803513C8; // type:function size:0x5C fn_80351424 = .text:0x80351424; // type:function size:0x8 -fn_8035142C = .text:0x8035142C; // type:function size:0x10 -fn_8035143C = .text:0x8035143C; // type:function size:0x8 -fn_80351444 = .text:0x80351444; // type:function size:0x290 -fn_803516D4 = .text:0x803516D4; // type:function size:0x38 -fn_8035170C = .text:0x8035170C; // type:function size:0xA8 -fn_803517B4 = .text:0x803517B4; // type:function size:0x5C +IsFinished__20RPBowNormalPinLayoutCFv = .text:0x8035142C; // type:function size:0x10 +Draw__20RPBowNormalPinLayoutFv = .text:0x8035143C; // type:function size:0x8 +Update__20RPBowNormalPinLayoutFP12SceneContext = .text:0x80351444; // type:function size:0x290 +Reset__20RPBowNormalPinLayoutFv = .text:0x803516D4; // type:function size:0x38 +Init__20RPBowNormalPinLayoutFP19RPSysLytResAccessor = .text:0x8035170C; // type:function size:0xA8 +__dt__20RPBowNormalPinLayoutFv = .text:0x803517B4; // type:function size:0x5C fn_80351810 = .text:0x80351810; // type:function size:0x8 -fn_80351818 = .text:0x80351818; // type:function size:0x10 -fn_80351828 = .text:0x80351828; // type:function size:0x8 -fn_80351830 = .text:0x80351830; // type:function size:0x300 -fn_80351B30 = .text:0x80351B30; // type:function size:0x40 -fn_80351B70 = .text:0x80351B70; // type:function size:0x13C -fn_80351CAC = .text:0x80351CAC; // type:function size:0x5C +IsFinished__25RPBowPowerThrowsPinLayoutCFv = .text:0x80351818; // type:function size:0x10 +Draw__25RPBowPowerThrowsPinLayoutFv = .text:0x80351828; // type:function size:0x8 +Update__25RPBowPowerThrowsPinLayoutFP12SceneContext = .text:0x80351830; // type:function size:0x300 +Reset__25RPBowPowerThrowsPinLayoutFv = .text:0x80351B30; // type:function size:0x40 +Init__25RPBowPowerThrowsPinLayoutFP19RPSysLytResAccessor = .text:0x80351B70; // type:function size:0x13C +__dt__25RPBowPowerThrowsPinLayoutFv = .text:0x80351CAC; // type:function size:0x5C fn_80351D08 = .text:0x80351D08; // type:function size:0x8 -fn_80351D10 = .text:0x80351D10; // type:function size:0x10 -fn_80351D20 = .text:0x80351D20; // type:function size:0x38 -fn_80351D58 = .text:0x80351D58; // type:function size:0x228 -fn_80351F80 = .text:0x80351F80; // type:function size:0x48 -fn_80351FC8 = .text:0x80351FC8; // type:function size:0x110 -fn_803520D8 = .text:0x803520D8; // type:function size:0x10 -fn_803520E8 = .text:0x803520E8; // type:function size:0x8 -fn_803520F0 = .text:0x803520F0; // type:function size:0x11C -fn_8035220C = .text:0x8035220C; // type:function size:0x40 -fn_8035224C = .text:0x8035224C; // type:function size:0x94 -fn_803522E0 = .text:0x803522E0; // type:function size:0x10 -fn_803522F0 = .text:0x803522F0; // type:function size:0x8 -fn_803522F8 = .text:0x803522F8; // type:function size:0xC4 -fn_803523BC = .text:0x803523BC; // type:function size:0x40 -fn_803523FC = .text:0x803523FC; // type:function size:0xD4 -fn_803524D0 = .text:0x803524D0; // type:function size:0x10 -fn_803524E0 = .text:0x803524E0; // type:function size:0x8 -fn_803524E8 = .text:0x803524E8; // type:function size:0x298 -fn_80352780 = .text:0x80352780; // type:function size:0x40 -fn_803527C0 = .text:0x803527C0; // type:function size:0x90 -fn_80352850 = .text:0x80352850; // type:function size:0x10 -fn_80352860 = .text:0x80352860; // type:function size:0x8 -fn_80352868 = .text:0x80352868; // type:function size:0x140 -fn_803529A8 = .text:0x803529A8; // type:function size:0x40 -fn_803529E8 = .text:0x803529E8; // type:function size:0x70 -fn_80352A58 = .text:0x80352A58; // type:function size:0x10 -fn_80352A68 = .text:0x80352A68; // type:function size:0x8 -fn_80352A70 = .text:0x80352A70; // type:function size:0x2D8 -fn_80352D48 = .text:0x80352D48; // type:function size:0x4C -fn_80352D94 = .text:0x80352D94; // type:function size:0x12C -fn_80352EC0 = .text:0x80352EC0; // type:function size:0x10 -fn_80352ED0 = .text:0x80352ED0; // type:function size:0x8 +IsFinished__19RPBowTutorialLayoutCFv = .text:0x80351D10; // type:function size:0x10 +Draw__19RPBowTutorialLayoutFv = .text:0x80351D20; // type:function size:0x38 +Update__19RPBowTutorialLayoutFv = .text:0x80351D58; // type:function size:0x228 +Reset__19RPBowTutorialLayoutFv = .text:0x80351F80; // type:function size:0x48 +Init__19RPBowTutorialLayoutFP19RPSysLytResAccessorP12RPSysMessage = .text:0x80351FC8; // type:function size:0x110 +IsFinished__17RPBowStrikeLayoutCFv = .text:0x803520D8; // type:function size:0x10 +Draw__17RPBowStrikeLayoutFv = .text:0x803520E8; // type:function size:0x8 +Update__17RPBowStrikeLayoutFP12SceneContext = .text:0x803520F0; // type:function size:0x11C +Reset__17RPBowStrikeLayoutFv = .text:0x8035220C; // type:function size:0x40 +Init__17RPBowStrikeLayoutFP19RPSysLytResAccessorP12RPSysMessage = .text:0x8035224C; // type:function size:0x94 +IsFinished__19RPBowGameOverLayoutCFv = .text:0x803522E0; // type:function size:0x10 +Draw__19RPBowGameOverLayoutFv = .text:0x803522F0; // type:function size:0x8 +Update__19RPBowGameOverLayoutFv = .text:0x803522F8; // type:function size:0xC4 +Reset__19RPBowGameOverLayoutFv = .text:0x803523BC; // type:function size:0x40 +Init__19RPBowGameOverLayoutFP19RPSysLytResAccessorP12RPSysMessage = .text:0x803523FC; // type:function size:0xD4 +IsFinished__27RPBowPowerThrowsStageLayoutCFv = .text:0x803524D0; // type:function size:0x10 +Draw__27RPBowPowerThrowsStageLayoutFv = .text:0x803524E0; // type:function size:0x8 +Update__27RPBowPowerThrowsStageLayoutFP12SceneContext = .text:0x803524E8; // type:function size:0x298 +Reset__27RPBowPowerThrowsStageLayoutFv = .text:0x80352780; // type:function size:0x40 +Init__27RPBowPowerThrowsStageLayoutFP19RPSysLytResAccessorP12RPSysMessage = .text:0x803527C0; // type:function size:0x90 +IsFinished__24RPBowTrainingStageLayoutCFv = .text:0x80352850; // type:function size:0x10 +Draw__24RPBowTrainingStageLayoutFv = .text:0x80352860; // type:function size:0x8 +Update__24RPBowTrainingStageLayoutFP12SceneContext = .text:0x80352868; // type:function size:0x140 +Reset__24RPBowTrainingStageLayoutFv = .text:0x803529A8; // type:function size:0x40 +Init__24RPBowTrainingStageLayoutFP19RPSysLytResAccessorP12RPSysMessage = .text:0x803529E8; // type:function size:0x70 +IsFinished__20RPBowEventTextLayoutCFv = .text:0x80352A58; // type:function size:0x10 +Draw__20RPBowEventTextLayoutFv = .text:0x80352A68; // type:function size:0x8 +Update__20RPBowEventTextLayoutFP12SceneContext = .text:0x80352A70; // type:function size:0x2D8 +Reset__20RPBowEventTextLayoutFv = .text:0x80352D48; // type:function size:0x4C +Init__20RPBowEventTextLayoutFP19RPSysLytResAccessorP12RPSysMessage = .text:0x80352D94; // type:function size:0x12C +IsFinished__19RPBowGuidanceLayoutCFv = .text:0x80352EC0; // type:function size:0x10 +Draw__19RPBowGuidanceLayoutFv = .text:0x80352ED0; // type:function size:0x8 fn_80352ED8 = .text:0x80352ED8; // type:function size:0x230 -fn_80353108 = .text:0x80353108; // type:function size:0x48 -fn_80353150 = .text:0x80353150; // type:function size:0xAC -fn_803531FC = .text:0x803531FC; // type:function size:0x10 -fn_8035320C = .text:0x8035320C; // type:function size:0x8 -fn_80353214 = .text:0x80353214; // type:function size:0x2E0 -fn_803534F4 = .text:0x803534F4; // type:function size:0x6C -fn_80353560 = .text:0x80353560; // type:function size:0x108 -fn_80353668 = .text:0x80353668; // type:function size:0x5C +Reset__19RPBowGuidanceLayoutFv = .text:0x80353108; // type:function size:0x48 +Init__19RPBowGuidanceLayoutFP19RPSysLytResAccessorP12RPSysMessage = .text:0x80353150; // type:function size:0xAC +IsFinished__24RPBowTrainingLivesLayoutCFv = .text:0x803531FC; // type:function size:0x10 +Draw__24RPBowTrainingLivesLayoutFv = .text:0x8035320C; // type:function size:0x8 +Update__24RPBowTrainingLivesLayoutFP12SceneContext = .text:0x80353214; // type:function size:0x2E0 +Reset__24RPBowTrainingLivesLayoutFv = .text:0x803534F4; // type:function size:0x6C +Init__24RPBowTrainingLivesLayoutFP19RPSysLytResAccessor = .text:0x80353560; // type:function size:0x108 +__dt__24RPBowTrainingLivesLayoutFv = .text:0x80353668; // type:function size:0x5C fn_803536C4 = .text:0x803536C4; // type:function size:0x8 -fn_803536CC = .text:0x803536CC; // type:function size:0x10 -fn_803536DC = .text:0x803536DC; // type:function size:0x8 -fn_803536E4 = .text:0x803536E4; // type:function size:0x3F4 -fn_80353AD8 = .text:0x80353AD8; // type:function size:0x6C -fn_80353B44 = .text:0x80353B44; // type:function size:0x148 -fn_80353C8C = .text:0x80353C8C; // type:function size:0x10 -fn_80353C9C = .text:0x80353C9C; // type:function size:0x8 -fn_80353CA4 = .text:0x80353CA4; // type:function size:0x448 -fn_803540EC = .text:0x803540EC; // type:function size:0x4C -fn_80354138 = .text:0x80354138; // type:function size:0x208 -fn_80354340 = .text:0x80354340; // type:function size:0x5C +IsFinished__28RPBowPowerThrowsRoundsLayoutCFv = .text:0x803536CC; // type:function size:0x10 +Draw__28RPBowPowerThrowsRoundsLayoutFv = .text:0x803536DC; // type:function size:0x8 +Update__28RPBowPowerThrowsRoundsLayoutFP12SceneContext = .text:0x803536E4; // type:function size:0x3F4 +Reset__28RPBowPowerThrowsRoundsLayoutFv = .text:0x80353AD8; // type:function size:0x6C +Init__28RPBowPowerThrowsRoundsLayoutFP19RPSysLytResAccessorP12RPSysMessage = .text:0x80353B44; // type:function size:0x148 +IsFinished__19RPBowAimGuideLayoutCFv = .text:0x80353C8C; // type:function size:0x10 +Draw__19RPBowAimGuideLayoutFv = .text:0x80353C9C; // type:function size:0x8 +Calc__19RPBowAimGuideLayoutFP12SceneContext = .text:0x80353CA4; // type:function size:0x448 +Reset__19RPBowAimGuideLayoutFv = .text:0x803540EC; // type:function size:0x4C +Init__19RPBowAimGuideLayoutFPQ23EGG4HeapP12RPSysMessage = .text:0x80354138; // type:function size:0x208 +__dt__19RPBowAimGuideLayoutFv = .text:0x80354340; // type:function size:0x5C fn_8035439C = .text:0x8035439C; // type:function size:0x8 fn_803543A4 = .text:0x803543A4; // type:function size:0x4 -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 -fn_80354914 = .text:0x80354914; // type:function size:0x218 -fn_80354B2C = .text:0x80354B2C; // type:function size:0x18 -fn_80354B44 = .text:0x80354B44; // type:function size:0xF0 -fn_80354C34 = .text:0x80354C34; // type:function size:0x4 -fn_80354C38 = .text:0x80354C38; // type:function size:0x40 -fn_80354C78 = .text:0x80354C78; // type:function size:0x1C -fn_80354C94 = .text:0x80354C94; // type:function size:0x10 -fn_80354CA4 = .text:0x80354CA4; // type:function size:0x8 -fn_80354CAC = .text:0x80354CAC; // type:function size:0x2AC -fn_80354F58 = .text:0x80354F58; // type:function size:0xC -fn_80354F64 = .text:0x80354F64; // type:function size:0x118 +Draw__20RPBowTrajectoryGuideFv = .text:0x803543A8; // type:function size:0x2F8 +Reset__20RPBowTrajectoryGuideFv = .text:0x803546A0; // type:function size:0x28 +Initialize__20RPBowTrajectoryGuideFv = .text:0x803546C8; // type:function size:0x28 +SetDotModel__20RPBowTrajectoryGuideFUlP10RPGrpModel = .text:0x803546F0; // type:function size:0x10 +SetMainModels__20RPBowTrajectoryGuideFP10RPGrpModelP10RPGrpModel = .text:0x80354700; // type:function size:0xC +__dt__20RPBowTrajectoryGuideFv = .text:0x8035470C; // type:function size:0x5C +UpdateControllerState__FPUl = .text:0x80354768; // type:function size:0x3C +AddThrowPosStateB__23RPBowBallHistoryManagerFUcPQ34nw4r4math4VEC3PQ34nw4r4math4VEC3 = .text:0x803547A4; // type:function size:0x6C +AddThrowPosStateA__23RPBowBallHistoryManagerFP15ThrowPosState_Ai = .text:0x80354810; // type:function size:0x98 +SetVectors__23RPBowBallHistoryManagerFPQ34nw4r4math4VEC3PQ34nw4r4math4VEC3PQ34nw4r4math4VEC3 = .text:0x803548A8; // type:function size:0x6C +RecordState__23RPBowBallHistoryManagerFP16BallPhysicsState = .text:0x80354914; // type:function size:0x218 +Reset__23RPBowBallHistoryManagerFv = .text:0x80354B2C; // type:function size:0x18 +Allocate__23RPBowBallHistoryManagerFUl = .text:0x80354B44; // type:function size:0xF0 +__ct__15ThrowPosState_BFv = .text:0x80354C34; // type:function size:0x4 +__dt__21RPBowBallHistoryEntryFv = .text:0x80354C38; // type:function size:0x40 +__ct__21RPBowBallHistoryEntryFv = .text:0x80354C78; // type:function size:0x1C +IsActiveEntryNull__23RPBowBallHistoryManagerFv = .text:0x80354C94; // type:function size:0x10 +Draw__18RPBowPerfectGameUIFv = .text:0x80354CA4; // type:function size:0x8 +Calc__18RPBowPerfectGameUIFv = .text:0x80354CAC; // type:function size:0x2AC +Reset__18RPBowPerfectGameUIFv = .text:0x80354F58; // type:function size:0xC +Init__18RPBowPerfectGameUIFP19RPSysLytResAccessorP12RPSysMessage = .text:0x80354F64; // type:function size:0x118 _ctors = .ctors:0x80355080; // type:label scope:global data:4byte __init_cpp_exceptions_reference = .ctors:0x80355080; // type:object size:0x4 scope:global _dtors = .dtors:0x80355260; // type:label scope:global data:4byte @@ -16982,7 +16982,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 -sTargetLaneWeights__7Bowling = .rodata:0x80392CB0; // type:object size:0x10 data:byte +sTargetLaneWeights = .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 @@ -19487,13 +19487,13 @@ lbl_803CA458 = .data:0x803CA458; // type:object size:0xE0 lbl_803CA538 = .data:0x803CA538; // type:object size:0x38 lbl_803CA570 = .data:0x803CA570; // type:object size:0x18 lbl_803CA588 = .data:0x803CA588; // type:object size:0x68 -lbl_803CA5F0 = .data:0x803CA5F0; // type:object size:0x50 +__vt__11LaneContext = .data:0x803CA5F0; // type:object size:0x50 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 -gLaneXOffsets__7Bowling = .data:0x803CA6C8; // type:object size:0x20 align:4 data:float -__vt__Q27Bowling15RPBowNpcManager = .data:0x803CA6E8; // type:object size:0x18 +gLaneXOffsets = .data:0x803CA6C8; // type:object size:0x20 align:4 data:float +__vt__15RPBowNpcManager = .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 @@ -20085,7 +20085,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 -gBowlingPhysicsData__7Bowling = .bss:0x804A9DE8; // type:object size:0x2D0 data:byte +gBowlingPhysicsData = .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 @@ -20094,7 +20094,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 -gBallReturnRackConstants__7Bowling = .bss:0x804BD2E8; // type:object size:0x40 align:4 data:float +gBallReturnRackConstants = .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 @@ -22120,8 +22120,8 @@ lbl_804BF9D0 = .sbss:0x804BF9D0; // type:object size:0x8 data:byte lbl_804BF9D8 = .sbss:0x804BF9D8; // type:object size:0x1 data:byte lbl_804BF9D9 = .sbss:0x804BF9D9; // type:object size:0x7 data:byte lbl_804BF9E0 = .sbss:0x804BF9E0; // type:object size:0x8 data:byte -lbl_804BF9E8 = .sbss:0x804BF9E8; // type:object size:0x1 data:byte -lbl_804BF9E9 = .sbss:0x804BF9E9; // type:object size:0x7 data:byte +gGameStateFlag1_804BF9E8 = .sbss:0x804BF9E8; // type:object size:0x1 data:byte +gGameStateFlag2_804BF9E9 = .sbss:0x804BF9E9; // type:object size:0x7 data:byte lbl_804BF9F0 = .sbss:0x804BF9F0; // type:object size:0x4 data:4byte lbl_804BF9F4 = .sbss:0x804BF9F4; // type:object size:0x4 data:4byte lbl_804BF9F8 = .sbss:0x804BF9F8; // type:object size:0x8 data:byte diff --git a/configure.py b/configure.py index 4660adf5f..f6ee41cfa 100755 --- a/configure.py +++ b/configure.py @@ -1464,60 +1464,60 @@ def MatchingFor(*versions): "objects": [ 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/RPBowSceneObjectManager.cpp"), + Object(NonMatching, "Pack/RPSports/RPBowScene/RPBowCameraTransform.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/RPBowAlleyModelManager.cpp"), + Object(NonMatching, "Pack/RPSports/RPBowScene/RPBowLaneDataHolder.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/RPBowScoreManager.cpp"), + Object(NonMatching, "Pack/RPSports/RPBowScene/RPBowGameManager.cpp"), + Object(NonMatching, "Pack/RPSports/RPBowScene/RPBowGameModeState.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/RPBowNpcContext.cpp"), + Object(NonMatching, "Pack/RPSports/RPBowScene/RPBowPinSetterManager.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/RPBowPowerThrowsPinManager.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/RPBowPinSetterModel.cpp"), + Object(NonMatching, "Pack/RPSports/RPBowScene/RPBowCameraController.cpp"), Object(NonMatching, "Pack/RPSports/RPBowScene/RPBow_80348858.cpp"), - Object(NonMatching, "Pack/RPSports/RPBowScene/RPBow_8034C1AC.cpp"), + Object(NonMatching, "Pack/RPSports/RPBowScene/RPBowSceneDirector.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/RPBowRegularPinManager.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/RPBowScoreLayout.cpp"), + Object(NonMatching, "Pack/RPSports/RPBowScene/RPBowNormalPinLayout.cpp"), + Object(NonMatching, "Pack/RPSports/RPBowScene/RPBowPowerThrowsPinLayout.cpp"), + Object(NonMatching, "Pack/RPSports/RPBowScene/RPBowLayoutManager.cpp"), + Object(NonMatching, "Pack/RPSports/RPBowScene/RPBowTrainingLivesLayout.cpp"), + Object(NonMatching, "Pack/RPSports/RPBowScene/RPBowPowerThrowsRoundsLayout.cpp"), + Object(NonMatching, "Pack/RPSports/RPBowScene/RPBowAimGuideLayout.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") + Object(NonMatching, "Pack/RPSports/RPBowScene/RPBowBallHistoryEntry.cpp"), + Object(NonMatching, "Pack/RPSports/RPBowScene/RPBowPerfectGameUI.cpp") ], }, ] diff --git a/include/Pack/RPGraphics/RPGrpModel.h b/include/Pack/RPGraphics/RPGrpModel.h index 87bb930b5..4b0bc348c 100644 --- a/include/Pack/RPGraphics/RPGrpModel.h +++ b/include/Pack/RPGraphics/RPGrpModel.h @@ -232,6 +232,10 @@ class RPGrpModel { mBaseScale.x = mBaseScale.y = mBaseScale.z = scale; } + RPGrpModelAnm* GetModelAnm() const { + return mpModelAnm; + } + RPGrpModelMaterial* GetMaterial(const char* pName) const { return mppMaterials[GetMaterialIndex(pName)]; } diff --git a/include/Pack/RPKernel/RPSysFrameCtrl.h b/include/Pack/RPKernel/RPSysFrameCtrl.h index a63c0503c..7506cf1ba 100644 --- a/include/Pack/RPKernel/RPSysFrameCtrl.h +++ b/include/Pack/RPKernel/RPSysFrameCtrl.h @@ -79,6 +79,24 @@ class RPSysFrameCtrl { mPlayMode = playMode; } + /** + * @brief Sets the animation result flags + * + * @param flags New flags + */ + void setFlags(u8 flags) { + mFlags = flags; + } + + /** + * @brief Sets whether the animation is enabled + * + * @param enabled New enabled state + */ + void setEnabled(s16 enabled) { + mIsEnabled = enabled; + } + /** * @brief Sets the starting frame of this animation * @@ -88,6 +106,13 @@ class RPSysFrameCtrl { mStartFrame = frame; } + /** + * @brief Gets the starting frame of this animation + */ + s16 getStartFrame() { + return mStartFrame; + } + /** * @brief Sets the animation update rate * diff --git a/include/Pack/RPKernel/RPSysKokeshi.h b/include/Pack/RPKernel/RPSysKokeshi.h index a483fb4bf..4237a11d7 100644 --- a/include/Pack/RPKernel/RPSysKokeshi.h +++ b/include/Pack/RPKernel/RPSysKokeshi.h @@ -63,6 +63,42 @@ class RPSysKokeshi : public RPSysAvatar { */ void GetRightHandJointMtx(EGG::Matrix34f* pMtx); + /** + * @brief Gets the face model + * + * @return Face model + */ + RPGrpModel* GetNigaoeModel() { + return mpNigaoeModel; + } + + /** + * @brief Gets the avatar body model + * + * @return Avatar body model + */ + RPGrpModel* GetBodyModel() { + return mpBodyModel; + } + + /** + * @brief Gets the left-hand model + * + * @return Left-hand model + */ + RPGrpModel* GetLeftHandModel() { + return mpLeftHandModel; + } + + /** + * @brief Gets the right-hand model + * + * @return Right-hand model + */ + RPGrpModel* GetRightHandModel() { + return mpRightHandModel; + } + private: /** * @brief Handles post-constructor initialization diff --git a/include/Pack/RPKernel/RPSysLytAnmObj.h b/include/Pack/RPKernel/RPSysLytAnmObj.h index 49a406c4e..25b2584ea 100644 --- a/include/Pack/RPKernel/RPSysLytAnmObj.h +++ b/include/Pack/RPKernel/RPSysLytAnmObj.h @@ -83,6 +83,31 @@ class RPSysLytAnmObj { mFrameCtrl.setPlayMode(playMode); } + /** + * @brief Sets the animation result flags + * + * @param flags New flags + */ + void setFlags(u8 flags) { + mFrameCtrl.setFlags(flags); + } + + /** + * @brief Sets whether the animation is enabled + * + * @param enabled New enabled state + */ + void setEnabled(s16 enabled) { + mFrameCtrl.setEnabled(enabled); + } + + /** + * @brief Gets the starting frame of this animation + */ + s16 getStartFrame() { + return mFrameCtrl.getStartFrame(); + } + /** * @brief Sets the current animation position * diff --git a/include/Pack/RPSports/RPBowScene/bowling.h b/include/Pack/RPSports/RPBowScene/bowling.h index 79cd4d576..6fbf31161 100644 --- a/include/Pack/RPSports/RPBowScene/bowling.h +++ b/include/Pack/RPSports/RPBowScene/bowling.h @@ -1,15 +1,13 @@ #include #include -namespace Bowling { - struct RPGrpModelPair { // total size: 0x8 RPGrpModel* pRealModel; // offset 0x0, size 0x4 RPGrpModel* pReflectionModel; // offset 0x4, size 0x4 }; -class RPBowActiveBall { +class RPBowActiveBall : public RP_DEBUG_STUB_1 { public: // total size: 0x88 virtual ~RPBowActiveBall(); // offset 0x0, size 0x4 @@ -22,53 +20,65 @@ class RPBowActiveBall { RPGrpShadowTexture* pShadowTexture; // offset 0x80, size 0x4 BOOL disableShadow; // offset 0x84, size 0x4 + void fn_8032ADF4(void); + void SetModelSet(u32 index, RPGrpModel* modelA, RPGrpModel* modelB); void ResetRenderState(); void RenderModelSet(); }; -struct PhysicsBody { - // total size: 0xFC +struct PhysicsBodyState { + // total size: 0xF4 - 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 0x0, size 0xC + nw4r::math::VEC3 linearVelocity; // offset 0xC, size 0xC + nw4r::math::VEC3 previousPosition; // offset 0x18, size 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 0x24, size 0xC + nw4r::math::VEC3 maxPositionDelta; // offset 0x30, size 0xC - nw4r::math::VEC3 minPositionDelta; // offset 0x28, size 0x4 - nw4r::math::VEC3 maxPositionDelta; // offset 0x34, size 0x4 + nw4r::math::VEC3 minVelocityDelta; // offset 0x3C, size 0xC + nw4r::math::VEC3 maxVelocityDelta; // offset 0x48, size 0xC - nw4r::math::VEC3 minVelocityDelta; // offset 0x40, size 0x4 - nw4r::math::VEC3 maxVelocityDelta; // offset 0x4C, size 0x4 + f32 linearDamping; // offset 0x54, size 0x4 - f32 linearDamping; // offset 0x58, size 0x4 + nw4r::math::VEC3 basisX; // offset 0x58, size 0xC + nw4r::math::VEC3 basisY; // offset 0x64, size 0xC + nw4r::math::VEC3 basisZ; // offset 0x70, size 0xC - 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 0x7C, size 0xC + nw4r::math::VEC3 angularVelYZ; // offset 0x88, size 0xC + nw4r::math::VEC3 angularVelZX; // offset 0x94, size 0xC - 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 0xA0, size 0xC + nw4r::math::VEC3 maxAngularDeltaXY; // offset 0xAC, size 0xC - nw4r::math::VEC3 minAngularDeltaXY; // offset 0xA4, size 0x4 - nw4r::math::VEC3 maxAngularDeltaXY; // offset 0xB0, size 0x4 + nw4r::math::VEC3 minAngularDeltaYZ; // offset 0xB8, size 0xC + nw4r::math::VEC3 maxAngularDeltaYZ; // offset 0xC4, size 0xC - nw4r::math::VEC3 minAngularDeltaYZ; // offset 0xBC, size 0x4 - nw4r::math::VEC3 maxAngularDeltaYZ; // offset 0xC8, size 0x4 + nw4r::math::VEC3 minAngularDeltaZX; // offset 0xD0, size 0xC + nw4r::math::VEC3 maxAngularDeltaZX; // offset 0xDC, size 0xC - nw4r::math::VEC3 minAngularDeltaZX; // offset 0xD4, size 0x4 - nw4r::math::VEC3 maxAngularDeltaZX; // offset 0xE0, size 0x4 + f32 angularDamping; // offset 0xE8, size 0x4 + f32 angularResponseScale; // offset 0xEC, size 0x4 + f32 interactionRadius; // offset 0xF0, size 0x4 +}; + +struct PhysicsBody { + // total size: 0xFC - f32 angularDamping; // offset 0xEC, size 0x4 - f32 angularResponseScale; // offset 0xF0, size 0x4 - f32 interactionRadius; // offset 0xF4, size 0x4 + // first 0x8 bytes of vtable taken by rtti or something like that. + virtual void VF_0x08(); + virtual void VF_0x0C(); + virtual void VF_0x10(); + virtual void VF_0x14(); + virtual void VF_0x18(); - u8 flags; // offset 0xF8, size 0x1 - u8 pad_F9[0x3]; // offset 0xF9, size 0x3 + PhysicsBodyState state; // offset 0x4, size 0xF4 + u8 flags; // offset 0xF8, size 0x1 + u8 pad_F9[0x3]; // offset 0xF9, size 0x3 + + void fn_8032A81C(); + void fn_80329088(float, float, float, float); }; struct PinSubVecs { @@ -79,7 +89,7 @@ struct PinSubVecs { }; struct PinPhysicsBody : public PhysicsBody { - // total size: 0x2C0 + // total size: 0x2B4 // PhysicsBody // offset 0x0, size 0xFC nw4r::math::VEC3 field_0xFC; // offset 0xFC, size 0xC nw4r::math::VEC3 unkVec_0x108; // offset 0x108, size 0xC @@ -122,9 +132,8 @@ struct PinPhysicsBody : public PhysicsBody { 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 + + PinPhysicsBody(); }; // Rack index order for PinManager's pPinBodies @@ -170,41 +179,45 @@ struct LaneBvhData { BvhEntryHeader* pObj2; // offset 0x1C, size 0x4 }; -struct PinSetter { +class RPBowPinSetterModel : public RP_DEBUG_STUB_1 { +public: // 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 + virtual ~RPBowPinSetterModel(); + + RPGrpModel* mpModel[2]; // offset 0x4, size 0x8 + nw4r::math::MTX34 mMtx; // offset 0xC, size 0x30 + int mPrimaryState; // offset 0x3C, size 0x4 + int mSequencePhase; // offset 0x40, size 0x4 + float mAngle; // offset 0x44, size 0x4 + float mFrameTimer; // offset 0x48, size 0x4 + + void fn_80323790(); + + void SetModels(RPGrpModel* pModel0, RPGrpModel* pModel1); + void Reset(); + void SetOffsetXZ(f32 x, f32 z); + void Calc(); }; 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 + u8 pad_0x34[0x24]; // offset 0x34, size 0x24 + u8 field_0x58; // offset 0x58, size 0x1 + u8 pad_0x59[0x3]; // offset 0x59, size 0x3 + u8 pad_0x5C[0x4]; // offset 0x5C, size 0x4 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 + u32 field_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_0x90; // 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 + float field_0x9C; // 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 @@ -212,9 +225,16 @@ struct ThrowContext { 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 + u8 pad_0xAC[0x8]; // offset 0xAC, size 0x8 + u8 flag_0xB4; // offset 0xB4, size 0x1 + u8 pad_0xB5[0x3]; // offset 0xB5, size 0x3 + u8 pad_0xB8[0x8]; // offset 0xB8, size 0x8 int animationMode; // offset 0xC0, size 0x4 - u8 pad_0xC4[0x40]; // offset 0xC4, size 0x40 + u8 pad_0xC4[0x8]; // offset 0xC4, size 0x8 + int field_0xCC; // offset 0xCC, size 0x4 + u8 pad_0xD0[0x4]; // offset 0xD0, size 0x4 + nw4r::math::VEC3 vec_0xD4; // offset 0xD4, size 0xC + u8 pad_0xE0[0x24]; // offset 0xE0, size 0x24 int field_0x104; // offset 0x104, size 0x4 }; @@ -245,85 +265,467 @@ struct PinSetterAnimation { u8 pad_2027; // offset 0xF, size 0x1 }; +struct BallPhysicsState { + // total size: 0x118 + u8 pad_00[0x10]; // offset 0x0, size 0x10 + f32 previousState[19]; // offset 0x10, size 0x4C + f32 field_5C; // offset 0x5C, size 0x4 + u32 unk_60; // offset 0x60, size 0x4 + f32 currentState[38]; // offset 0x64, size 0x98 + u8 pad_FC[0x18]; // offset 0xFC, size 0x18 + u8 flag_114; // offset 0x114, size 0x1 + u8 pad_115[3]; // offset 0x115, size 0x3 +}; -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 RPBowBallHistoryEntry { + // total size: 0x118 + RPBowBallHistoryEntry(); + ~RPBowBallHistoryEntry(); + + u32 unk_0; // offset 0x0, size 0x4 + f32 currentState[38]; // offset 0x4, size 0x98 + f32 previousState[19]; // offset 0x9C, size 0x4C + u32 index20A; // offset 0xE8, size 0x4 + u32 throwCount; // offset 0xEC, size 0x4 + nw4r::math::VEC3 vec1; // offset 0xF0, size 0xC + nw4r::math::VEC3 vec2; // offset 0xFC, size 0xC + nw4r::math::VEC3 vec3; // offset 0x108, size 0xC + u8 flag_114; // offset 0x114, size 0x1 + u8 pad_115[3]; // offset 0x115, size 0x3 +}; + +struct ThrowPosState_A { + // total size: 0x20 + ThrowPosState_A(); + ~ThrowPosState_A(); + + u32 field_00; // offset 0x0, size 0x4 + f32 field_04; // offset 0x4, size 0x4 + 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 +}; + +struct ThrowPosState_B { + // total size: 0x20 + ThrowPosState_B(); + + u32 field_00; // offset 0x0, size 0x4 + u8 flag_04; // offset 0x4, size 0x1 + u8 pad_5[3]; // offset 0x5, size 0x3 + nw4r::math::VEC3 vec1; // offset 0x8, size 0xC + nw4r::math::VEC3 vec2; // offset 0x14, size 0xC +}; + +class RPBowBallHistoryManager { +public: + // total size: 0x2C + u32 unk00; // offset 0x0, size 0x4 + ThrowPosState_A* pArray20A; // offset 0x4, size 0x4 + u32 maxCount; // offset 0x8, size 0x4 + RPBowBallHistoryEntry* pEntries; // offset 0xC, size 0x4 + u32 currentIndex; // offset 0x10, size 0x4 + RPBowBallHistoryEntry* pActiveEntry; // offset 0x14, size 0x4 + u32 maxCount8; // offset 0x18, size 0x4 + u32 index20A; // offset 0x1C, size 0x4 + u32 limit20B; // offset 0x20, size 0x4 + u32 index20B; // offset 0x24, size 0x4 + ThrowPosState_B* pArray20B; // offset 0x28, size 0x4 + + bool IsActiveEntryNull(); + void Allocate(u32 count); + void Reset(); + void RecordState(BallPhysicsState* pSrc); + void SetVectors(nw4r::math::VEC3* pVec1, nw4r::math::VEC3* pVec2, nw4r::math::VEC3* pVec3); + void AddThrowPosStateA(ThrowPosState_A* pSrcArr, int count); + void AddThrowPosStateB(u8 val1, nw4r::math::VEC3* pVec1, nw4r::math::VEC3* pVec2); +}; + +// TODO: this is some kind of class defined in RPUtility, RPKernel or RPSportsCommon, not in Bowling. +struct UnknownField18 { + // first 0x8 bytes of vtable taken by rtti or something like that. + virtual void pad_0x8(); + virtual void pad_0xC(); + virtual void pad_0x10(); + virtual void pad_0x14(); + virtual void pad_0x18(); + virtual void pad_0x1C(); + virtual void pad_0x20(); + virtual void pad_0x24(); + virtual void pad_0x28(); + virtual void pad_0x2C(); + virtual void pad_0x30(); + virtual float* vfunc_0x34(); + virtual void vfunc_0x38(EGG::Vector3f*); + virtual void pad_0x3C(); + virtual void vfunc_0x40(EGG::Vector3f*); + virtual void pad_0x44(); + virtual void pad_0x48(); + virtual void pad_0x4C(); + virtual void vfunc_0x50(EGG::Vector3f*); + virtual void pad_0x54(); + virtual void vfunc_0x58(EGG::Vector3f*); + virtual void pad_0x5C(); + virtual void vfunc_0x60(EGG::Vector3f*); +}; + +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 + f32 field_38; // offset 0x38, size 0x4 + f32 field_3C; // offset 0x3C, size 0x4 + f32 field_40; // offset 0x40, size 0x4 + f32 field_44; // offset 0x44, size 0x4 + f32 field_48; // offset 0x48, size 0x4 + f32 field_4C; // offset 0x4C, size 0x4 + f32 field_50; // offset 0x50, size 0x4 + f32 field_54; // offset 0x54, size 0x4 + f32 field_58; // offset 0x58, size 0x4 + f32 field_5C; // offset 0x5C, size 0x4 + f32 field_60; // offset 0x60, size 0x4 + f32 field_64; // offset 0x64, size 0x4 + f32 field_68; // offset 0x68, size 0x4 + f32 field_6C; // offset 0x6C, size 0x4 + f32 field_70; // offset 0x70, size 0x4 + 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 + f32 field_84; // offset 0x84, size 0x4 + f32 field_88; // offset 0x88, size 0x4 + f32 field_8C; // offset 0x8C, size 0x4 + f32 field_90; // offset 0x90, size 0x4 + f32 field_94; // offset 0x94, size 0x4 + f32 field_98; // offset 0x98, size 0x4 + f32 field_9C; // offset 0x9C, size 0x4 + f32 field_A0; // offset 0xA0, size 0x4 + f32 field_A4; // offset 0xA4, size 0x4 + f32 field_A8; // offset 0xA8, size 0x4 + f32 field_AC; // offset 0xAC, size 0x4 + f32 field_B0; // offset 0xB0, size 0x4 + f32 field_B4; // offset 0xB4, size 0x4 + f32 field_B8; // offset 0xB8, size 0x4 + f32 field_BC; // offset 0xBC, size 0x4 + f32 field_C0; // offset 0xC0, size 0x4 + f32 field_C4; // offset 0xC4, size 0x4 + f32 field_C8; // offset 0xC8, size 0x4 + f32 field_CC; // offset 0xCC, size 0x4 + f32 field_D0; // offset 0xD0, size 0x4 + f32 field_D4; // offset 0xD4, size 0x4 + f32 field_D8; // offset 0xD8, size 0x4 + f32 field_DC; // offset 0xDC, size 0x4 + f32 field_E0; // offset 0xE0, size 0x4 + f32 field_E4; // offset 0xE4, size 0x4 + f32 field_E8; // offset 0xE8, size 0x4 + f32 field_EC; // offset 0xEC, size 0x4 + f32 field_F0; // offset 0xF0, size 0x4 + f32 field_F4; // offset 0xF4, size 0x4 + f32 field_F8; // offset 0xF8, size 0x4 + f32 field_FC; // offset 0xFC, size 0x4 + f32 field_100; // offset 0x100, size 0x4 + f32 field_104; // offset 0x104, size 0x4 + 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 + f32 field_120; // offset 0x120, size 0x4 + f32 field_124; // offset 0x124, size 0x4 + f32 field_128; // offset 0x128, size 0x4 + f32 field_12C; // offset 0x12C, size 0x4 + f32 field_130; // offset 0x130, size 0x4 + f32 field_134; // offset 0x134, size 0x4 + f32 field_138; // offset 0x138, size 0x4 + f32 field_13C; // offset 0x13C, size 0x4 + f32 field_140; // offset 0x140, size 0x4 + f32 field_144; // offset 0x144, size 0x4 + f32 field_148; // offset 0x148, size 0x4 + f32 field_14C; // offset 0x14C, size 0x4 + f32 field_150; // offset 0x150, size 0x4 + f32 field_154; // offset 0x154, size 0x4 + f32 field_158; // offset 0x158, size 0x4 + f32 field_15C; // offset 0x15C, size 0x4 + f32 field_160; // offset 0x160, size 0x4 + f32 field_164; // offset 0x164, size 0x4 + f32 field_168; // offset 0x168, size 0x4 + f32 field_16C; // offset 0x16C, size 0x4 + f32 field_170; // offset 0x170, size 0x4 + f32 field_174; // offset 0x174, size 0x4 + f32 field_178; // offset 0x178, size 0x4 + f32 field_17C; // offset 0x17C, size 0x4 + f32 field_180; // offset 0x180, size 0x4 + f32 field_184; // offset 0x184, size 0x4 + f32 field_188; // offset 0x188, size 0x4 + f32 field_18C; // offset 0x18C, size 0x4 + f32 field_190; // offset 0x190, size 0x4 + f32 field_194; // offset 0x194, size 0x4 + f32 field_198; // offset 0x198, size 0x4 + f32 field_19C; // offset 0x19C, size 0x4 + f32 field_1A0; // offset 0x1A0, size 0x4 + f32 field_1A4; // offset 0x1A4, size 0x4 + f32 field_1A8; // offset 0x1A8, size 0x4 + f32 field_1AC; // offset 0x1AC, size 0x4 + f32 field_1B0; // offset 0x1B0, size 0x4 + f32 field_1B4; // offset 0x1B4, size 0x4 + f32 field_1B8; // offset 0x1B8, size 0x4 + f32 field_1BC; // offset 0x1BC, size 0x4 + f32 field_1C0; // offset 0x1C0, size 0x4 + f32 field_1C4; // offset 0x1C4, size 0x4 + f32 field_1C8; // offset 0x1C8, size 0x4 + f32 field_1CC; // offset 0x1CC, size 0x4 + f32 field_1D0; // offset 0x1D0, size 0x4 + f32 field_1D4; // offset 0x1D4, size 0x4 + f32 field_1D8; // offset 0x1D8, size 0x4 + f32 field_1DC; // offset 0x1DC, size 0x4 + f32 field_1E0; // offset 0x1E0, size 0x4 + f32 field_1E4; // offset 0x1E4, size 0x4 + f32 field_1E8; // offset 0x1E8, size 0x4 + f32 field_1EC; // offset 0x1EC, size 0x4 + f32 field_1F0; // offset 0x1F0, size 0x4 + f32 field_1F4; // offset 0x1F4, size 0x4 + f32 field_1F8; // offset 0x1F8, size 0x4 + f32 field_1FC; // offset 0x1FC, size 0x4 + f32 field_200; // offset 0x200, size 0x4 + f32 field_204; // offset 0x204, size 0x4 + f32 field_208; // offset 0x208, size 0x4 + f32 field_20C; // offset 0x20C, size 0x4 + f32 field_210; // offset 0x210, size 0x4 + f32 field_214; // offset 0x214, size 0x4 + f32 field_218; // offset 0x218, size 0x4 + f32 field_21C; // offset 0x21C, size 0x4 + f32 field_220; // offset 0x220, size 0x4 + f32 field_224; // offset 0x224, size 0x4 + f32 field_228; // offset 0x228, size 0x4 + f32 field_22C; // offset 0x22C, size 0x4 + f32 field_230; // offset 0x230, size 0x4 + f32 field_234; // offset 0x234, size 0x4 + f32 field_238; // offset 0x238, size 0x4 + f32 field_23C; // offset 0x23C, size 0x4 + f32 field_240; // offset 0x240, size 0x4 + u8 field_244; // offset 0x244, size 0x1 + u8 field_245; // offset 0x245, size 0x1 + u8 field_246; // offset 0x246, size 0x1 + u8 field_247; // offset 0x247, size 0x1 + f32 field_248; // offset 0x248, size 0x4 + f32 field_24C; // offset 0x24C, size 0x4 + f32 field_250; // offset 0x250, size 0x4 + f32 field_254; // offset 0x254, size 0x4 + f32 field_258; // offset 0x258, size 0x4 + f32 field_25C; // offset 0x25C, size 0x4 + f32 field_260; // offset 0x260, size 0x4 + f32 field_264; // offset 0x264, size 0x4 + f32 field_268; // offset 0x268, size 0x4 + 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 UnknownLaneContextStruct5 { + // total size: 0x114 + u8 pad_0x00[0x14]; // offset 0x0, size 0x14 + float field_0x14; // offset 0x14, size 0x4 + u8 pad_0x18[0x74]; // offset 0x18, size 0x74 + float field_0x8C; // offset 0x8C, size 0x4 + float field_0x90; // offset 0x90, size 0x4 + u8 pad_0x94[0x7C]; // offset 0x94, size 0x7C + float field_0x110; // offset 0x110, size 0x4 +}; + +struct PinMatrixPair { + // total size: 0x60 + nw4r::math::MTX34 realMtx; // offset 0x0, size 0x30 + nw4r::math::MTX34 reflectionMtx; // offset 0x30, size 0x30 +}; + +class RPBowPowerThrowsPinManager : public RP_DEBUG_STUB_1, public IRPGrpModelCallback { +public: + virtual ~RPBowPowerThrowsPinManager(); + virtual void VF_0x0C(); // at 0xC + virtual void VF_0x10(); // at 0x10 + virtual void CopyMatrices(RPGrpModel* pOther); // at 0x14 + + RPGrpModel* mpModels[2]; // offset 0x8, size 0x8 + PinMatrixPair mMatrixPairs[91]; // offset 0x10, size 0x2220 + + RPBowPowerThrowsPinManager(); + void fn_80340304(); + void SetModels(RPGrpModel* pRealModel, RPGrpModel* pReflectionModel); + void fn_8034021C(); + void UpdateModels(); + void fn_80340194(); + void TransformMatrix(int pinIndex, const nw4r::math::MTX34* pMtx, f32 yOffset); + void ClearMatrices(int startIndex); +}; + +struct LaneContextSubClassA { + // total size: 0xE8 + f32 unkFloats[58]; // offset 0x0, size 0xE8 + + LaneContextSubClassA(); // fn_80315560 + ~LaneContextSubClassA(); // fn_80315520 +}; + +struct LaneContextSubClassB { + // total size: 0x108 + ThrowContext ThrowContext; // offset 0x0, size 0x108 + + LaneContextSubClassB(); // fn_80315504 + ~LaneContextSubClassB(); // fn_803154C4 +}; + +class LaneContext : public IRPSysHostIOSocket { +public: + // total size: 0x2080. confirmed by RPBowGlobalLaneManager::InitializeLaneContexts. + // first virtual functions are taken up by rtti and IRPSysHostIOSocket's virtual functions. + virtual float VF_0x14(); // at 0x14 + virtual void VF_0x18(); // at 0x18 + virtual void VF_0x1C(); // at 0x1C + + PinManager* pPinManager; // offset 0x4, size 0x4 + LaneBvhData* pLaneBvhData; // offset 0x8, size 0x4 + RPBowPinSetterModel* pPinSetter; // offset 0xC, size 0x4 + RPBowBallHistoryManager* ballHistory; // offset 0x10, size 0x4 + int pinCount; // offset 0x14, size 0x4 + UnknownField18* unkPtr_0x18; // offset 0x18, size 0x4 + void* unkPtr_0x1C; // offset 0x1C, size 0x4 + LaneContextSubClassA arrayA[15]; // offset 0x20, size 0xD98 + LaneContextSubClassB arrayB[15]; // offset 0xDB8, size 0xF78 + PinPhysicsBody* array_0x1D30[100]; // offset 0x1D30, size 0x190 + int field_1EC0; // offset 0x1EC0, size 0x4 + int field_1EC4; // offset 0x1EC4, size 0x4 + nw4r::math::VEC3 vec_0x1EC8; // offset 0x1EC8, size 0xC + nw4r::math::VEC3 vec_0x1ED4; // offset 0x1ED4, size 0xC + int field_1EE0; // offset 0x1EE0, size 0x4 + int field_1EE4; // offset 0x1EE4, size 0x4 + nw4r::math::VEC3 vec_0x1EE8; // offset 0x1EE8, size 0xC + int field_1EF4; // offset 0x1EF4, size 0x4 + ThrowContext throwContext; // offset 0x1EF8, size 0x108 + PinStatus pinStatus; // offset 0x2000, size 0x14 + float laneXOffset; // offset 0x2014, size 0x4 + PinSetterAnimation setterAnimation; // offset 0x2018, size 0x10 + u32 field_0x2028; // offset 0x2028, size 0x4 + void* unkPtr_0x202C; // offset 0x202C, size 0x4 + RPSysEffect* effects[16]; // offset 0x2030, size 0x40 + bool flag_0x2070; // offset 0x2070, size 0x1 + bool flag_0x2071; // offset 0x2071, size 0x1 + u8 pad_0x2071[0x2]; // offset 0x2072, size 0x2 + 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 + + void fn_80327858(int a, int b, float f_val, RPBowPinSetterModel* pinSetter); + void fn_80323F30(); + void fn_8032781C(); + void fn_803277B4(); + void fn_80327558(); + void fn_80327330(PinStatus* status); + void fn_80327218(); + void fn_80325154(); + nw4r::math::VEC3 fn_80325144(); + nw4r::math::VEC3 fn_803250F8(); + nw4r::math::VEC3 fn_803250E8(); + nw4r::math::VEC3 fn_803250D8(); + void fn_80324B50(const nw4r::math::VEC3* v1, const nw4r::math::VEC3* v2); + void fn_80324B18(const nw4r::math::VEC3* v); + int fn_80324B10(); + int fn_803248F8(); + void fn_803252FC(); + void fn_80324DD0(nw4r::math::VEC3* vec, u8 flag); + void fn_80323DD0(); + void fn_80323D0C(BowlingPhysicsData* bowlingPhysicsData, float* out1, float* out2, float val); + void fn_80323A60(BowlingPhysicsData* bowlingPhysicsData); + void fn_803256C4(BowlingPhysicsData* bowlingPhysicsData); + void fn_803381DC(); + void fn_80338724(PhysicsBody* body, PhysicsBodyState* state); + void fn_8033C3B0(PinPhysicsBody* r4, UnknownLaneContextStruct5* r5, ThrowContext* r6, void* r7, void* r8, void* r9, float f1); + void fn_803394C0(PinPhysicsBody* r4, UnknownLaneContextStruct5* r5, ThrowContext* r6, void* r7, void* r8, void* r9, float f1); + void fn_80338720(); + void fn_8033871C(); + + void ResetPinSetterState(u8 isNewRack); + void TriggerPinSetter(int spawnNewRack); + int UpdatePinSetter(); + int IsPinSetterActive(); + void fn_803345F0(); + + LaneContext() : IRPSysHostIOSocket() { + throwContext.field_0x90 = 1.1920929e-07f; + throwContext.field_0x94 = 1.1920929e-07f; + throwContext.field_0x98 = 0.0f; + throwContext.field_0x9C = 0.0f; + + pinStatus.pinBits[0] = pinStatus.pinBits[1] = pinStatus.pinBits[2] = pinStatus.pinBits[3] = -1; + pinStatus.pinCount = 10; + } +}; + +struct LaneContextExt : public LaneContext { + // LaneContext laneContext // offset 0x4, size 0x2080 + float field_0x2080; // offset 0x2080, size 0x4 + float field_0x2084; // offset 0x2084, size 0x4 + float field_0x2088; // offset 0x2088, size 0x4 + float field_0x208C; // offset 0x208C, size 0x4 + float field_0x2090; // offset 0x2090, size 0x4 + float field_0x2094; // offset 0x2094, size 0x4 + float field_0x2098; // offset 0x2098, size 0x4 + float field_0x209C; // offset 0x209C, size 0x4 + float field_0x20A0; // offset 0x20A0, size 0x4 + float field_0x20A4; // offset 0x20A4, size 0x4 + float field_0x20A8; // offset 0x20A8, size 0x4 + float field_0x20AC; // offset 0x20AC, size 0x4 + float field_0x20B0; // offset 0x20B0, size 0x4 + float field_0x20B4; // offset 0x20B4, size 0x4 + float field_0x20B8; // offset 0x20B8, size 0x4 + float field_0x20BC; // offset 0x20BC, size 0x4 + float field_0x20C0; // offset 0x20C0, size 0x4 + float field_0x20C4; // offset 0x20C4, size 0x4 + RPBowPowerThrowsPinManager* powerThrowsPinManager; // offset 0x20C8, size 0x4 + u8 pad_0x20CC[0x4]; // offset 0x20CC, size 0x4 + u8 flag_0x20D0; // offset 0x20D0, size 0x1 + u8 flag_0x20D1; // offset 0x20D1, size 0x1 + u8 flag_0x20D2; // offset 0x20D2, size 0x1 + u8 flag_0x20D3; // offset 0x20D3, size 0x1 + u8 pad_0x20D4[0x878]; // offset 0x20D4, size 0x878 + int field_0x294C; // offset 0x294C, size 0x4 }; struct SubNpcLaneData { // total size: 0x5C - u32 field_0x0; // offset 0x0, size 0x4 - int counter_0x4; // offset 0x4, size 0x4 + u32 mState; // offset 0x0, size 0x4 + int mTimer; // 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 mScale; // offset 0x10, size 0x4 + float mOffsetZ; // offset 0x14, size 0x4 + float mRotY; // offset 0x18, size 0x4 + float mOffsetX; // 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 @@ -344,70 +746,73 @@ struct SubNpcLaneData { 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 { +struct KokeshiGroupPair { // total size: 0x8 - NpcModelGroup* groupA; // offset 0x0, size 0x4 - NpcModelGroup* groupB; // offset 0x4, size 0x4 + RPSysKokeshi* realKokeshi; // offset 0x0, size 0x4 + RPSysKokeshi* reflectionKokeshi; // offset 0x4, size 0x4 }; -struct NpcLaneDataHolder { +class RPBowLaneDataHolder : public IRPSysHostIOSocket { +public: // 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 + virtual ~RPBowLaneDataHolder(); + virtual void VF_0x08(); // vtable index 2 (offset 0x8) + virtual void VF_0x0C(int); // vtable index 3 (offset 0xC) + + void* unkPtr_0x04; // offset 0x4, size 0x4 + u32 mCurrentGroup; // 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 mWaitTime; // offset 0x2C, size 0x4 + SubNpcLaneData mSubData; // offset 0x30, size 0x5C + KokeshiGroupPair mGroups[4]; // offset 0x8C, size 0x20 + u16 mAnimIdA; // offset 0xAC, size 0x2 + u16 mAnimIdB; // offset 0xAE, size 0x2 + float mAnimFrameA; // offset 0xB0, size 0x4 + float mAnimFrameB; // offset 0xB4, size 0x4 + u16 mPrevAnimIdA; // offset 0xB8, size 0x2 + u16 mPrevAnimIdB; // offset 0xBA, size 0x2 + float mPrevAnimFrameA; // offset 0xBC, size 0x4 + float mPrevAnimFrameB; // offset 0xC0, size 0x4 + float mAnimWeightA; // offset 0xC4, size 0x4 + float mAnimWeightB; // 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 mSpawnPos; // offset 0xDC, size 0xC + float field_0xE8; // offset 0xE8, size 0x4 + float field_0xEC; // offset 0xEC, size 0x4 + u8 mFlags[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* mpExtraModel; // offset 0x118, size 0x4 + float field_0x11C; // offset 0x11C, size 0x4 + void* mpModelDataArray[0x4]; // offset 0x120, size 0x10 + + void Initialize(); + void RegisterGroups(int index, RPSysKokeshi* realKokeshi, RPSysKokeshi* reflectionKokeshi); + void SetModelData(s16 arg1, s16 arg2, s16 arg3, RPGrpModel* model); + void SetAnimation(u16 indexA, u16 indexB); + void Reset(int arg1, int arg2); + void StartThrow(); + void SetVisibility(bool enable); + void SetDrawGroup(u8 drawGroup); }; class RPBowTrajectoryGuide : public RP_DEBUG_STUB_1 { @@ -470,47 +875,70 @@ enum NpcStates { NPC_STATE_WALK_BACK_TO_SEAT = 5, // Walking back to seat }; -struct NpcMovementState { +class RPBowNpcMovementState : public IRPSysHostIOSocket { +public: // total size: 0x1C - void* vtable; // offset 0x0, size 0x4 + virtual ~RPBowNpcMovementState(); + 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 + + void fn_80346E5C(); + nw4r::math::VEC3 CalculateLaneSeatCenter() const; + void InitNpcMovementState(int laneIdx, int npcIdx); + void SetNpcReturnStartPos(const nw4r::math::VEC3 *pCurrentPos); +}; + +struct NpcActionState { + // total size: 0x14 + NpcStates npcState; // offset 0x0, size 0x4 + int stateFrameCounter; // offset 0x4, size 0x4 + u8 triggerThrow; // offset 0x8, size 0x1 + u8 triggerTransition; // offset 0x9, size 0x1 + u8 pad_0x3A[0x2]; // offset 0xA, size 0x2 + s32 field_0x3A; // offset 0xC, size 0x4 + float targetZPos; // offset 0x10, size 0x4 }; -struct NpcContext { +class RPBowNpcContext : public IRPSysHostIOSocket { +public: // 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 + virtual ~RPBowNpcContext(); + + RPSysKokeshi* mpKokeshi[2]; // offset 0x4, size 0x8 + void* unkPtr_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 + NpcActionState actionState; // offset 0x30, size 0x14 + u8 field_0x44; // offset 0x44, size 0x1 + u8 pad_0x45[3]; // offset 0x45, size 0x3 + RPBowNpcMovementState* 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 + + void InitNpcInstance(RPSysKokeshi* realKokeshi, RPSysKokeshi* reflectionKokeshi); + void InitNpcContext(int laneIdx, int npcIdx); + void UpdateNpcLane(); + void InitNpcBoundingBoxes(void* unkPtr); + void ResetNpcState(); + void fn_80334270(); + void fn_80332C60(int val); + void fn_80332C2C(u8 val); + void fn_80332C24(); }; class RPBowPlayerLaneNpc : public RP_DEBUG_STUB_1 { @@ -526,7 +954,7 @@ class RPBowPlayerLaneNpc : public RP_DEBUG_STUB_1 { u8 pad_0x2D[0x3]; // offset 0x2D, size 0x3 NpcIdleState npcIdleState; // offset 0x30, size 0x48 - void Init(RPSysKokeshi* kokeshi1, RPSysKokeshi* kokeshi2, int index); + void Init(RPSysKokeshi* realKokeshi, RPSysKokeshi* reflectionKokeshi, int index); void SetSeatPosition(); void HideActiveBowler(); void UpdateModels(); @@ -582,16 +1010,16 @@ class RPBowBackgroundNpcManager : public RP_DEBUG_STUB_1 { 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 + RPSysKokeshi* 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 + bool isVisible; // 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 SetModelGroups(int managerIndex, RPSysKokeshi* realKokeshi, RPSysKokeshi* reflectionKokeshi); void fn_8034E83C(); void Reset(); void UpdateMovement(nw4r::math::VEC3* outPosition, bool* outStateFlag); @@ -601,75 +1029,15 @@ class RPBowBackgroundNpcManager : public RP_DEBUG_STUB_1 { 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); +struct CameraProjection { + // total size: 0x1C + int field_0x00; // offset 0x0, size 0x4 + int field_0x04; // offset 0x4, size 0x4 + float resWidth; // offset 0x8, size 0x4 - Camera resolution width: 832.0 + float resHeight; // offset 0xC, size 0x4 - Camera resolution height: 456.0 + float fov; // offset 0x10, size 0x4 + float tanFov; // offset 0x14, size 0x4 + float field_0x18; // offset 0x18, size 0x4 }; class RPBowNpcManager: public IRPSysHostIOSocket { @@ -684,8 +1052,8 @@ class RPBowNpcManager: public IRPSysHostIOSocket { 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 + RPBowNpcContext* mpNpcs[3]; // offset 0x18, size 0xC + RPBowNpcContext* mpCurrentNpc; // offset 0x24, size 0x4 int mLaneIdx; // offset 0x28, size 0x4 int mCurrentNpcIdx; // offset 0x2C, size 0x4 PinStatus mPinStatus; // offset 0x30, size 0x14 @@ -699,7 +1067,7 @@ class RPBowNpcManager: public IRPSysHostIOSocket { 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); + void Setup(LaneContext* pLaneContext, RPBowNpcContext* pNpc0, RPBowNpcContext* pNpc1, RPBowNpcContext* pNpc2, int laneIdx, RPBowBallReturnRack* pReturnRack, void* pAudioStruct); int IsLaneIdle(); void SetStateFlag(u8 flag); void ActivateNpcTurn(); @@ -722,14 +1090,392 @@ class RPBowNpcManager: public IRPSysHostIOSocket { } 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 + pinData->state.basisX.x, pinData->state.basisY.x, pinData->state.basisZ.x, pinData->state.position.x, + pinData->state.basisX.y, pinData->state.basisY.y, pinData->state.basisZ.y, pinData->state.position.y, + pinData->state.basisX.z, pinData->state.basisY.z, pinData->state.basisZ.z, pinData->state.position.z ); } } }; +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 fn_8034D4F0(); + 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); +}; + +struct CameraTransformSub { + // total size: 0xDC. Confirmed by fn_8031C078 in tu4. + nw4r::math::VEC3 vec0; // offset 0x0, size 0xC + nw4r::math::VEC3 target; // offset 0xC, size 0xC + u8 pad_0x18[0x10]; // offset 0x18, size 0x10 + float offsetX; // offset 0x28, size 0x4 + u8 pad_0x2C[0xC]; // offset 0x2C, size 0xC + float unk_0x38; // offset 0x38, size 0x4 + u8 pad_0x3C[0x5C]; // offset 0x3C, size 0x5C + float unk_0x98; // offset 0x98, size 0x4 + u8 pad_0x9C[0x1C]; // offset 0x9C, size 0x1C + int curveInterpolationFrame; // offset 0xB8, size 0x4 + u8 pad_0xBC[0x4]; // offset 0xBC, size 0x4 + float unk_0xC0; // offset 0xC0, size 0x4 + u8 pad_0xC4[0x10]; // offset 0xC4, size 0x10 + float unk_0xD4; // offset 0xD4, size 0x4 + bool unk_0xD8; // offset 0xD8, size 0x1 + u8 pad_0xD9[0x3]; // offset 0xD9, size 0x3 +}; + +enum BowlingCameraStates { + BOWLING_CAMERA_STATE_NULL = -1, // Null + BOWLING_CAMERA_STATE_NORMAL_INITIAL_DEMO = 0, // Initial camera demo at the start of the game + BOWLING_CAMERA_STATE_NORMAL_PLAYER_SCORES = 1, // Displaying player scores + BOWLING_CAMERA_STATE_TRAINING_RECORD = 2, // Displaying player's training mode record + BOWLING_CAMERA_STATE_ADJUSTING_SHOT = 3, // Active bowling gameplay - adjusting shot + BOWLING_CAMERA_STATE_THROWING = 4, // Active bowling gameplay - throwing + BOWLING_CAMERA_STATE_FAILED_TO_BOWL_ERROR = 5, // "Failed to bowl properly" error message + BOWLING_CAMERA_STATE_UNKNOWN_6 = 6, // Unknown + BOWLING_CAMERA_STATE_LANE_TRANSITION = 7, // Camera shot transitioning to the next lane + BOWLING_CAMERA_STATE_POWER_THROWS_PIN_TRANSITION = 8, // Camera shot showing how many pins need to be hit + BOWLING_CAMERA_STATE_NORMAL_FINAL_DEMO = 9, // Final camera demo at the end of the game + BOWLING_CAMERA_STATE_NORMAL_REPLAY = 10, // Replay + BOWLING_CAMERA_STATE_NORMAL_STRIKE_SPLIT_REPLAY_1 = 11, // Strike/Split Replay 1 + BOWLING_CAMERA_STATE_NORMAL_STRIKE_SPLIT_REPLAY_2 = 12, // Strike/Split Replay 2 + BOWLING_CAMERA_STATE_POWER_THROWS_REPLAY = 13, // Replay + BOWLING_CAMERA_STATE_POWER_THROWS_STRIKE_REPLAY_1 = 14, // Strike Replay 1 + BOWLING_CAMERA_STATE_POWER_THROWS_STRIKE_REPLAY_2 = 15, // Strike Replay 2 + BOWLING_CAMERA_STATE_SPIN_CONTROL_REPLAY = 16, // Replay + BOWLING_CAMERA_STATE_PICKING_UP_SPARES_REPLAY = 17 // Replay +}; + +struct CameraAnimNode { + // total size: 0x74 + u8 name[0x20]; // offset 0x0, size 0x20 + u32 animType; // offset 0x20, size 0x4 + nw4r::math::VEC3 startPos; // offset 0x24, size 0xC + nw4r::math::VEC3 endPos; // offset 0x30, size 0xC + f32 startPitch; // offset 0x3C, size 0x4 + f32 startYaw; // offset 0x40, size 0x4 + f32 endPitch; // offset 0x44, size 0x4 + f32 endYaw; // offset 0x48, size 0x4 + f32 easeStart; // offset 0x4C, size 0x4 + f32 easeEnd; // offset 0x50, size 0x4 + f32 durationFrames; // offset 0x54, size 0x4 + f32 fov; // offset 0x58, size 0x4 + nw4r::math::VEC3 posOffset; // offset 0x5C, size 0xC + u8 flags; // offset 0x68, size 0x1 + u8 pad_0x69[3]; // offset 0x69, size 0x3 + f32 normalizationFactor; // offset 0x6C, size 0x4 + u32 nextNodeIdx; // offset 0x70, size 0x4 +}; + +struct CameraState { + // total size: 0x2C + nw4r::math::VEC3 pos; // offset 0x0, size 0xC + nw4r::math::VEC3 target; // offset 0xC, size 0xC + nw4r::math::VEC3 up; // offset 0x18, size 0xC + f32 fov; // offset 0x24, size 0x4 + u32 projType; // offset 0x28, size 0x4 +}; + +struct CameraTimeState { + // total size: 0xC + f32 linearTime; // offset 0x0, size 0x4 + f32 easedTime; // offset 0x4, size 0x4 + u8 isPaused; // offset 0x8, size 0x1 + u8 pad_0x9[0x3]; // offset 0x9, size 0x3 +}; + +class RPBowCameraController { +public: + // total size: 0x17D0 + void* vtable; // offset 0x0, size 0x4 + CameraState state; // offset 0x4, size 0x2C + u32 currentNodeIdx; // offset 0x30, size 0x4 + CameraAnimNode nodes[52]; // offset 0x34, size 0x1790 + CameraTimeState timeState; // offset 0x17C4, size 0xC + + void ResetCameraController(); + void SetCameraAnimationNode(s32 nodeIndex); + void InitCameraAnimations(); + bool IsCameraAnimFinished(); + void UpdateCameraAnimation(); + void CalculateCameraPose(CameraState* state, CameraAnimNode* node, f32 easedProgress); + void DebugPrintCameraInfo(); + +}; + +/* +struct RPGrpCamera { + // total size: 0x174 + nw4r::math::MTX34 mViewMtx; // offset 0x0, size 0x30 + nw4r::math::MTX34 mWorldMtx; // offset 0x30, size 0x30 + nw4r::math::MTX34 mAnmViewMtx; // offset 0x60, size 0x30 + nw4r::math::MTX34 mDirectWorldMtx; // offset 0x90, size 0x30 + nw4r::math::VEC3 mPosition; // offset 0xC0, size 0xC + nw4r::math::VEC3 mTarget; // offset 0xCC, size 0xC + nw4r::math::VEC3 mRotation; // offset 0xD8, size 0xC + f32 mDistance; // offset 0xE4, size 0x4 + nw4r::math::VEC3 mRight; // offset 0xE8, size 0xC + nw4r::math::VEC3 mUp; // offset 0xF4, size 0xC + nw4r::math::VEC3 mForward; // offset 0x100, size 0xC + ECameraType mCameraType; // offset 0x10C, size 0x4 + u16 mFlags; // offset 0x110, size 0x2 + nw4r::math::MTX34 mWorldMtxOld; // offset 0x114, size 0x30 + nw4r::math::MTX34 mSavedViewMtx; // offset 0x144, size 0x30 +}; +*/ + +class RPBowCameraTransform : public RPGrpCamera { +public: + // total size: 0x348 + CameraProjection* projection; // offset 0x178, size 0x4 + CameraTransformSub ctSub; // offset 0x17C, size 0xDC + float unk_0x258; // offset 0x258, size 0x4 + float unk_0x25C; // offset 0x25C, size 0x4 + float unk_0x260; // offset 0x260, size 0x4 + float unk_0x264; // offset 0x264, size 0x4 + float unk_0x268; // offset 0x268, size 0x4 + float unk_0x26C; // offset 0x26C, size 0x4 + float unk_0x270; // offset 0x270, size 0x4 + float unk_0x274; // offset 0x274, size 0x4 + float unk_0x278; // offset 0x278, size 0x4 + float unk_0x27C; // offset 0x27C, size 0x4 + float unk_0x280; // offset 0x280, size 0x4 + float unk_0x284; // offset 0x284, size 0x4 + float unk_0x288; // offset 0x288, size 0x4 + float unk_0x28C; // offset 0x28C, size 0x4 + float unk_0x290; // offset 0x290, size 0x4 + float unk_0x294; // offset 0x294, size 0x4 + float unk_0x298; // offset 0x298, size 0x4 + float unk_0x29C; // offset 0x29C, size 0x4 + float unk_0x2A0; // offset 0x2A0, size 0x4 + float unk_0x2A4; // offset 0x2A4, size 0x4 + float unk_0x2A8; // offset 0x2A8, size 0x4 + float unk_0x2AC; // offset 0x2AC, size 0x4 + float unk_0x2B0; // offset 0x2B0, size 0x4 + float unk_0x2B4; // offset 0x2B4, size 0x4 + float unk_0x2B8; // offset 0x2B8, size 0x4 + float unk_0x2BC; // offset 0x2BC, size 0x4 + float unk_0x2C0; // offset 0x2C0, size 0x4 + float unk_0x2C4; // offset 0x2C4, size 0x4 + float unk_0x2C8; // offset 0x2C8, size 0x4 + float unk_0x2CC; // offset 0x2CC, size 0x4 + float unk_0x2D0; // offset 0x2D0, size 0x4 + float fovStart; // offset 0x2D4, size 0x4 + float unk_0x2D8; // offset 0x2D8, size 0x4 + float unk_0x2DC; // offset 0x2DC, size 0x4 + float unk_0x2E0; // offset 0x2E0, size 0x4 + float unk_0x2E4; // offset 0x2E4, size 0x4 + float unk_0x2E8; // offset 0x2E8, size 0x4 + float targetY; // offset 0x2EC, size 0x4 + float unk_0x2F0; // offset 0x2F0, size 0x4 + float unk_0x2F4; // offset 0x2F4, size 0x4 + float posY; // offset 0x2F8, size 0x4 + float unk_0x2FC; // offset 0x2FC, size 0x4 + float fovEnd; // offset 0x300, size 0x4 + float posZ; // offset 0x304, size 0x4 + float unk_0x308; // offset 0x308, size 0x4 + float unk_0x30C; // offset 0x30C, size 0x4 + float unk_0x310; // offset 0x310, size 0x4 + int unk_0x314; // offset 0x314, size 0x4 + float unk_0x318; // offset 0x318, size 0x4 + float unk_0x31C; // offset 0x31C, size 0x4 + float unk_0x320; // offset 0x320, size 0x4 + float unk_0x324; // offset 0x324, size 0x4 + BowlingCameraStates state; // offset 0x328, size 0x4 + int counter; // offset 0x32C, size 0x4 + RPBowCameraController* cameraController; // offset 0x330, size 0x4 + bool animFinished; // offset 0x334, size 0x1 + u8 pad_0x335[0x3]; // offset 0x335, size 0x3 + int powerThrowStage; // offset 0x338, size 0x4 + int trainingLaneIndex; // offset 0x33C, size 0x4 + bool transitionStyle; // offset 0x340, size 0x1 + u8 pad_0x341[0x3]; // offset 0x341, size 0x3 + int initialDemoType; // offset 0x344, size 0x4 + + void InitCameraTransformConstants(CameraProjection* proj, RPBowCameraController* ctrl); + void ResetCameraTransform(); + void ApplyCameraAnimation(); + void CameraProc(); + float fn_8031B3C0(); + float fn_8031B388(); + void UseCamera(int); + void UseSpinControlReplayCamera(); + void UseReplayCamera(int type); +}; + +class RPBowAlleyModelManager : public RP_DEBUG_STUB_1 { +public: +virtual ~RPBowAlleyModelManager(); + RPGrpModel* mSlotModels[4]; // offset 0x4, size 0x10 + RPGrpModel* mSlotAltModels[4]; // offset 0x14, size 0x10 + RPGrpModel* mModels[8]; // offset 0x24, size 0x20 + // mModels[0]: Regular alley Lanes model + // mModels[1]: Power Throws area model. This is the entire Power Throws room, no culling like with the normal alley. + // mModels[2]: Regular alley static pins model. Pins that are never interacted with and are outside of the 7 active lanes. + // mModels[3]: Regular alley lounge area model. + // mModels[4]: Left Power Throws bumper. + // mModels[6]: Left Power Throws bumper reflection. + // mModels[5]: Right Power Throws bumper. + // mModels[7]: Right Power Throws bumper reflection. + u32 mSceneFlags; // offset 0x44, size 0x4 + u32 mCurrentSlotIndex; // offset 0x48, size 0x4 + f32 mBumperPosition; // offset 0x4C, size 0x4 + + void fn_8031EFE0(); + void SetModels(RPGrpModel* laneModel, RPGrpModel* powerThrowsRoomModel, RPGrpModel* staticPinsModel, RPGrpModel* loungeModel, RPGrpModel* leftBumperModel, RPGrpModel* leftBumperReflModel, RPGrpModel* rightBumperModel, RPGrpModel* rightBumperReflModel); + void SetModelSlot(int index, RPGrpModel* model, RPGrpModel* altModel) ; + void ResetSceneParams(); + void UpdateModelsLoop1(nw4r::math::MTX34* mtx); + void UpdateModelsLoop2(nw4r::math::MTX34* mtx); + void UpdateModelsLoop3(nw4r::math::MTX34* mtx); + void UpdateModels(); +}; + +struct Obj208Data { + // total size: 0x84 + u8 pad_0x00[0x4]; // offset 0x0, size 0x4 + u8 pad_0x04[0x4]; // offset 0x4, size 0x4 + u8 pad_0x08[0x4]; // offset 0x8, size 0x4 + u8 pad_0x0C[0x4]; // offset 0xC, size 0x4 + void* unkPtr_0x10; // offset 0x10, size 0x4 + void* unkPtr_0x14; // offset 0x14, size 0x4 + u8 pad_0x18[0x4]; // offset 0x18, size 0x4 + u8 pad_0x1C[0x4]; // offset 0x1C, size 0x4 + u8 pad_0x20[0x4]; // offset 0x20, size 0x4 + u8 pad_0x24[0x4]; // offset 0x24, size 0x4 + u8 pad_0x28[0x4]; // offset 0x28, size 0x4 + u8 pad_0x2C[0x4]; // offset 0x2C, size 0x4 + u8 pad_0x30[0x4]; // offset 0x30, size 0x4 + u8 pad_0x34[0x4]; // offset 0x34, size 0x4 + u8 pad_0x38[0x4]; // offset 0x38, size 0x4 + void* unkPtr_0x3C; // offset 0x3C, size 0x4 + u8 pad_0x40[0x4]; // offset 0x40, size 0x4 + u8 pad_0x44[0x4]; // offset 0x44, size 0x4 + u8 pad_0x48[0x4]; // offset 0x48, size 0x4 + u8 pad_0x4C[0x4]; // offset 0x4C, size 0x4 + float field_0x50; // offset 0x50, size 0x4 + float field_0x54; // offset 0x54, size 0x4 + float field_0x58; // offset 0x58, size 0x4 + u8 pad_0x5C[0x4]; // offset 0x5C, size 0x4 + u8 pad_0x60[0x4]; // offset 0x60, size 0x4 + u8 pad_0x64[0x4]; // offset 0x64, size 0x4 + float field_0x68; // offset 0x68, size 0x4 + u8 pad_0x6C[0x4]; // offset 0x6C, size 0x4 + u8 pad_0x70[0x4]; // offset 0x70, size 0x4 + u8 pad_0x74[0x4]; // offset 0x74, size 0x4 + nw4r::math::VEC3 vec; // offset 0x78, size 0xC +}; + +class RPBowRegularPinManager : public RP_DEBUG_STUB_1, public IRPGrpModelCallback { +public: + // total size: 0x3D8 + virtual ~RPBowRegularPinManager(); + + RPGrpModel* mModels[2]; // offset 0x8, size 0x8 + nw4r::math::MTX34 mMatrices[10][2]; // offset 0x10, size 0x3C0 + RPGrpShadowTexture* mpShadowTexture; // offset 0x3D0, size 0x4 + u32 mUseShadows; // offset 0x3D4, size 0x4 + + void InitializeModels(RPGrpModel* realModel, RPGrpModel* reflectionModel); + void fn_8034F440(); + void Calc(); + void fn_8034F164(); + void CopyMatricesToModel(RPGrpModel* pModel); + void CalculatePinTransforms(int index, f32 yOffset, nw4r::math::MTX34* pMtxA, nw4r::math::MTX34* pMtxB, nw4r::math::MTX34* pMtxC); + void HideExcessPins(int count); +}; + +struct SceneEntities { + // total size: 0x1E0 + RPBowAlleyModelManager* alleyModels; // offset 0x0, size 0x4 + RPBowLaneDataHolder* laneData; // offset 0x4, size 0x4 + RPBowTrajectoryGuide* trajectoryGuide; // offset 0x8, size 0x4 + void* primaryProp; // offset 0xC, size 0x4 + RPBowRegularPinManager* pinManagers[7]; // offset 0x10, size 0x1C + RPBowActiveBall* balls[7]; // offset 0x2C, size 0x1C + RPBowNpcContext* npcs[18]; // offset 0x48, size 0x48 + RPBowPlayerLaneNpc* playerLaneNpcs[4]; // offset 0x90, size 0x10 + RPBowPinSetterModel* setters[7]; // offset 0xA0, size 0x1C + void* environmentProps[64]; // offset 0xBC, size 0x100 + RPBowBallReturnRack* ballReturns[4]; // offset 0x1BC, size 0x10 + RPBowBackgroundNpcManager* backgroundNpcs[4]; // offset 0x1CC, size 0x10 + void* unkPtr_0x1DC; // offset 0x1DC, size 0x4 +}; + +class RPBowSceneObjectManager { +public: + // total size: 0x218 + void* vtable; // offset 0x0, size 0x4 + SceneEntities entities; // offset 0x4, size 0x1E0 + u8 bDrawLane; // offset 0x1E4, size 0x1 + u8 pad_0x1E5; // offset 0x1E5, size 0x1 + u8 bDrawNpcs; // offset 0x1E6, size 0x1 + u8 bDrawBalls; // offset 0x1E7, size 0x1 + u8 bDrawProps; // offset 0x1E8, size 0x1 + u8 bDrawPinSetters; // offset 0x1E9, size 0x1 + u8 bDrawEnv; // offset 0x1EA, size 0x1 + u8 bDrawBallReturns; // offset 0x1EB, size 0x1 + nw4r::math::MTX34* renderMatrix; // offset 0x1EC, size 0x4 + u8 isAlternateMode; // offset 0x1F0, size 0x1 + u8 bDrawPropsActive; // offset 0x1F1, size 0x1 + u8 bDrawGroupA; // offset 0x1F2, size 0x1 + u8 bDrawGroupB; // offset 0x1F3, size 0x1 + u8 bDrawGroupC; // offset 0x1F4, size 0x1 + u8 pad_0x1F5[0x3]; // offset 0x1F5, size 0x3 + void* pRenderViewA; // offset 0x1F8, size 0x4 + void* pRenderViewB; // offset 0x1FC, size 0x4 + void* unkPtr_0x200; // offset 0x200, size 0x4 + u8 pad_0x204[0x4]; // offset 0x204, size 0x4 + Obj208Data* cameraData; // offset 0x208, size 0x4 + void* pPanController; // offset 0x20C, size 0x4 + float panBoundary; // offset 0x210, size 0x4 + float panScale; // offset 0x214, size 0x4 + + void SetAlternateMode(bool flag); + void SetLaneGroupVisibility(int laneIdx, u8 isVisible); + void fn_80316B04(); + void ResetAllEntities(); + nw4r::math::MTX34* ProcessCamera(CameraProjection* proj, RPBowCameraTransform* transform); + void fn_80316A44(); + void RenderEntities(CameraProjection* proj, RPBowCameraTransform* transform); + void fn_80316638(); + void UpdateAllEntities(); + void fn_803165D4(); + void fn_803165D0(); + void UpdateRenderModeAlpha(u32 mode, float fVal); +}; + +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 InitializeLaneContexts(RPBowSceneObjectManager* objectManager); + void InitializeBallManagerLanes(); + void SetupBallManagerLaneObjects(void* arg1, void* arg2); + void ResetLanePinsAndAnimations(); + void SetLaneUnknownState(int value); + void UpdateBallsPhysics(); + void TickNpcLanes(); + void UpdateLaneItems(RPBowCameraTransform* transform, CameraProjection* pObj, RPBowSceneObjectManager* pObjectManager, bool isPlayerTurn); + void UpdateBallsMdl(RPBowSceneObjectManager* pObjectManager); +}; + class RPBowManagerContext { public: // total size: 0x34 @@ -743,26 +1489,912 @@ class RPBowManagerContext { void* field_0x30; // offset 0x30, size 0x4 void Initialize(); - void LinkNpcLanes(RPBowGlobalLaneManager* laneManager, SceneObjectManager* sceneObjectManager); + void LinkNpcLanes(RPBowGlobalLaneManager* laneManager, RPBowSceneObjectManager* sceneObjectManager); void SetNpcStateFlags(u8 flag); void UpdateNpcs(); void DebugPrintStates(); }; -class RPBowMotionBlur : public RP_DEBUG_STUB_1 { +enum BowlingGameStates { + BOWLING_GAME_STATE_START_GAME_CAMERA_DEMO = 0, // Initial camera demo at the start of the game + BOWLING_GAME_STATE_PLAYER_SCORE_VIEW = 1, // Displaying player scores + BOWLING_GAME_STATE_MAIN_BOWLING_VIEW = 2, // Active bowling gameplay (adjusting shot, throwing) + BOWLING_GAME_STATE_FAILED_BOWL_MESSAGE = 3, // "Failed to bowl properly" error message + BOWLING_GAME_STATE_REPLAY = 4, // Ball rolling replay + BOWLING_GAME_STATE_END_GAME_CAMERA_DEMO = 5, // Final camera demo at the end of the game + BOWLING_GAME_STATE_UNUSED_6 = 6, // Unused + BOWLING_GAME_STATE_SKILL_LEVEL_SCREEN = 7, // Skill level screen + BOWLING_GAME_STATE_UNUSED_8 = 8, // Unused + BOWLING_GAME_STATE_GAME_FINISHED = 9, // Game finished screen +}; + +struct SwingHistoryBuffer { + // total size: 0x1B8. Confirmed by fn_8031EBC8 in tu5 + float unkFloats_0x0[96]; // offset 0x0, size 0x180 + int field_0x180; // offset 0x180, size 0x4 + int field_0x184; // offset 0x184, size 0x4 + int field_0x188; // offset 0x188, size 0x4 + int unkCounter_0x18C; // offset 0x18C, size 0x4 + int unkCounterLimit_0x190; // offset 0x190, size 0x4 + void* unkPtr_0x198; // offset 0x194, size 0x4 + int field_0x198; // offset 0x198, size 0x4 + int field_0x19C; // offset 0x19C, size 0x4 + int field_0x1A0; // offset 0x1A0, size 0x4 + float unkFloats_0x1A4[5]; // offset 0x1A4, size 0x14 + + SwingHistoryBuffer(int param); +}; + +struct BowlingSwing { + // total size: 0xDC + u8 field_0x0; // offset 0x0, size 0x1 + u8 field_0x1; // offset 0x1, size 0x1 + u8 field_0x2; // offset 0x2, size 0x1 + u8 field_0x3; // offset 0x3, size 0x1 + int field_0x4; // offset 0x4, size 0x4 + u8 pad_0x8[0x4]; // offset 0x8, size 0x4 + int field_0xC; // offset 0xC, size 0x4 + int counter_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 field_0x2C; // offset 0x2C, size 0x1 + u8 pad_0x2D[0x3]; // offset 0x2D, size 0x3 + float field_0x30; // offset 0x30, size 0x4 + u8 pad_0x34[0x4]; // offset 0x34, size 0x4 + int counter_0x38; // offset 0x38, size 0x4 + float field_0x3C; // offset 0x3C, size 0x4 + float field_0x40; // offset 0x40, size 0x4 + float field_0x44; // offset 0x44, size 0x4 + float field_0x48; // offset 0x48, size 0x4 + float field_0x4C; // offset 0x4C, size 0x4 + int int_0x50; // offset 0x50, size 0x4 + u8 isSwinging; // offset 0x54, size 0x1 + u8 pad_0x55[0x3]; // offset 0x55, size 0x3 + int field_0x58; // offset 0x58, size 0x4 + int field_0x5C; // offset 0x5C, size 0x4 + float field_0x60; // offset 0x60, size 0x4 + int field_0x64; // offset 0x64, size 0x4 + int field_0x68; // offset 0x68, size 0x4 + int field_0x6C; // offset 0x6C, size 0x4 + u8 pad_0x70[0x14]; // offset 0x70, size 0x14 + float field_0x84; // offset 0x84, size 0x4 + float field_0x88; // offset 0x88, size 0x4 + int counter_0x8C; // offset 0x8C, size 0x4 + float field_0x90; // offset 0x90, size 0x4 + float field_0x94; // offset 0x94, size 0x4 + float field_0x98; // offset 0x98, size 0x4 + float field_0x9C; // offset 0x9C, size 0x4 + float field_0xA0; // offset 0xA0, size 0x4 + int counter_0xA4; // offset 0xA4, size 0x4 + int counter_0xA4_Result; // offset 0xA8, size 0x4 + u8 pad_0xAC[0x4]; // offset 0xAC, size 0x4 + int counter_0xB0; // offset 0xB0, size 0x4 + float field_0xB4; // offset 0xB4, size 0x4 + float field_0xB8; // offset 0xB8, size 0x4 + 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 + u8 pad_0xCC[0x4]; // offset 0xCC, size 0x4 + float field_0xD0; // offset 0xD0, size 0x4 + float field_0xD4; // offset 0xD4, size 0x4 + float field_0xD8; // offset 0xD8, size 0x4 +}; + +struct BowlingSwingContext { + // total size: 0x14C + void* vtable; // offset 0x0, size 0x4 + void* unkPtr_0x4; // offset 0x4, size 0x4 + SwingHistoryBuffer* swingHistory; // offset 0x8, size 0x4 + u8 byte_0x0C; // offset 0xC, size 0x1 + u8 pad_0xD[0x03]; // offset 0xD, size 0x3 + BowlingSwing swing; // offset 0x10, size 0xDC + float field_0xEC; // offset 0xEC, size 0x4 + float field_0xF0; // offset 0xF0, size 0x4 + float field_0xF4; // offset 0xF4, size 0x4 + float field_0xF8; // offset 0xF8, size 0x4 + int field_0xFC; // offset 0xFC, size 0x4 + float field_0x100; // offset 0x100, size 0x4 + float field_0x104; // offset 0x104, size 0x4 + int field_0x108; // offset 0x108, size 0x4 + int field_0x10C; // offset 0x10C, size 0x4 + int field_0x110; // offset 0x110, size 0x4 + bool byte_0x114; // offset 0x114, size 0x1 + u8 pad_0x115[3]; // offset 0x115, size 0x3 + float field_0x118; // offset 0x118, size 0x4 + int int_0x11C; // offset 0x11C, size 0x4 + int int_0x120; // offset 0x120, size 0x4 + int pad_0x124; // offset 0x124, size 0x4 + int field_0x128; // offset 0x128, size 0x4 + float field_0x12C; // offset 0x12C, size 0x4 + int field_0x130; // offset 0x130, size 0x4 + float field_0x134; // offset 0x134, size 0x4 + float field_0x138; // offset 0x138, size 0x4 + int field_0x13C; // offset 0x13C, size 0x4 + float field_0x140; // offset 0x140, size 0x4 + float field_0x144; // offset 0x144, size 0x4 + int field_0x148; // offset 0x148, size 0x4 +}; + +struct ControllerWrapper { + // total size: 0x10 + u32 id; // offset 0x0, size 0x4 + int controllerIndex; // offset 0x4, size 0x4 + u8 isActive; // offset 0x8, size 0x1 + u8 flag_0x9; // offset 0x9, size 0x1 + u8 pad_0xA[0x2]; // offset 0xA, size 0x2 + int field_0x0C; // offset 0xC, size 0x4 +}; + +struct ControllerWrapperManager { + // total size: 0x10 + 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 + ControllerWrapper* controllerWrapper; // offset 0x8, size 0x4 + int field_0x0C; // offset 0xC, size 0x4 +}; + +struct BowlerState { + // total size: 0x2C + float field_0x0; // offset 0x0, size 0x4 + float playerLaneRotation; // offset 0x4, size 0x4 + float playerLanePosition; // offset 0x8, size 0x4 + int playInRotationMode; // offset 0xC, size 0x4 + u8 field_0x10; // offset 0x10, size 0x1 + u8 field_0x11; // offset 0x11, size 0x1 + u8 field_0x12; // offset 0x12, size 0x1 + u8 field_0x13; // offset 0x13, size 0x1 + u8 field_0x14; // offset 0x14, size 0x1 + u8 field_0x15; // offset 0x15, size 0x1 + u8 field_0x16; // offset 0x16, size 0x1 + u8 field_0x17; // offset 0x17, size 0x1 + float field_0x18; // offset 0x18, size 0x4 + int field_0x1C; // offset 0x1C, size 0x4 + int unkLaneSideToggle; // offset 0x20, size 0x4 - Determines whether the ball will have left or right spin based off playerLaneRotation and playerLanePosition. + u8 pad_0x24[0x4]; // offset 0x24, size 0x4 + int unkCounter_0x28; // offset 0x28, size 0x4 + u8 pad_0x2C[0x4]; // offset 0x2C, size 0x4 +}; + +struct BowlerContext { + // total size: 0x528 + void* vtable; // offset 0x0, size 0x4 + float field_0x04; // offset 0x4, size 0x4 + float field_0x08; // offset 0x8, size 0x4 + float field_0x0C; // offset 0xC, size 0x4 + u8 pad_0x10[0x488]; // offset 0x10, size 0x488 + u8 field_0x498; // offset 0x498, size 0x1 + u8 pad_0x499[0x13]; // offset 0x499, size 0x13 + int field_0x4AC; // offset 0x4AC, size 0x4 + u8 pad_0x4B0[0x4]; // offset 0x4B0, size 0x4 + float releaseAngleDeg_Neg_LerpMin; // offset 0x4B4, size 0x4 + float releaseAngleDeg_Neg_LerpMax; // offset 0x4B8, size 0x4 + float ballPowerFactor_Neg_Min; // offset 0x4BC, size 0x4 + float ballPowerFactor_Neg_Max; // offset 0x4C0, size 0x4 + float releaseAngleDeg_Pos_LerpMin; // offset 0x4C4, size 0x4 + float releaseAngleDeg_Pos_LerpMax; // offset 0x4C8, size 0x4 + float ballPowerFactor_Pos_Min; // offset 0x4CC, size 0x4 + float ballPowerFactor_Pos_Max; // offset 0x4D0, size 0x4 + u8 pad_0x4D4[0x14]; // offset 0x4D4, size 0x14 + BowlerState bowlerState; // offset 0x4E8, size 0x30 + BowlingSwingContext* swingCtx; // offset 0x518, size 0x4 + LaneContext* laneContext; // offset 0x51C, size 0x4 + RPBowLaneDataHolder* laneData; // offset 0x520, size 0x4 + ControllerWrapper* controller; // offset 0x524, size 0x4 +}; + +struct BowlingRoundData { + // total size: 0x4C + u8 throws[3]; // offset 0x0, size 0x3 + u8 pad_0x03[0x1]; // offset 0x3, size 0x1 + int roundScore; // offset 0x4, size 0x4 + u8 field_0x08; // offset 0x8, size 0x1 + u8 pad_0x9[0x3]; // offset 0x9, size 0x3 + u8 pad_0x0C[0x4]; // offset 0xC, size 0x4 + PinStatus bonuses[3]; // offset 0x10, size 0x3C +}; + +class RPBowScoreManager { 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 + // total size: 0xDC0 + + virtual int GetMaxIter(); // offset 0x8 vtable call + virtual int GetPlayerIndex(); // offset 0xC vtable call + + void* unkPtr_0x4; // offset 0x4, size 0x4 + int currentRound; // offset 0x8, size 0x4 + int currentRoundThrow; // offset 0xC, size 0x4 + int field_0x10; // offset 0x10, size 0x4 + int field_0x14; // offset 0x14, size 0x4 + int field_0x18; // offset 0x18, size 0x4 + u8 wasStrike; // offset 0x1C, size 0x1 + u8 wasSpare; // offset 0x1D, size 0x1 + u8 pad_0x1E[0x2]; // offset 0x1E, size 0x2 + int recentPinsKnocked; // offset 0x20, size 0x4 + u8 field_0x24; // offset 0x24, size 0x1 + u8 pad_0x25[0x3]; // offset 0x25, size 0x3 + ControllerWrapperManager* cwm; // offset 0x28, size 0x4 + u8 pad_0x2C[0x4]; // offset 0x2C, size 0x4 + int consecutiveStrikes; // offset 0x30, size 0x4 + int field_0x34; // offset 0x34, size 0x4 + PinStatus prevBonuses1[2]; // offset 0x38, size 0x28 + float unkFloat_0x60; // offset 0x60, size 0x4 + float unkFloat_0x64; // offset 0x64, size 0x4 + float unkFloat_0x68; // offset 0x68, size 0x4 + float unkFloat_0x6C; // offset 0x6C, size 0x4 + float unkFloat_0x70; // offset 0x70, size 0x4 + PinStatus prevBonuses2[3]; // offset 0x74, size 0x3C + BowlingRoundData playerFrames[4][11]; // offset 0xB0, size 0xD10 + + void fn_8032B3AC(); + float CalcNewSkill(u32 playerIdx, float currentSkill); + void fn_8032AE9C(); + float fn_8032AE54(); +}; - 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); +struct DebugOverlaySettings { + // total size: 0x34 + u8 pad_0x0[0x1]; // offset 0x0, size 0x1 + u8 showScore; // offset 0x1, size 0x1 + u8 pad_0x2[0x2]; // offset 0x2, size 0x2 + u8 field_0x4; // offset 0x4, size 0x1 + u8 field_0x5; // offset 0x5, size 0x1 + u8 pad_0x6[0x2]; // offset 0x6, size 0x2 + u8 field_0x8; // offset 0x8, size 0x1 + u8 pad_0x9[0x1]; // offset 0x9, size 0x1 + u8 field_0xA; // offset 0xA, size 0x1 + u8 field_0xB; // offset 0xB, size 0x1 + u8 pad_0xC[0x2]; // offset 0xC, size 0x2 + u8 showDebugA; // offset 0xE, size 0x1 + u8 pad_0xF[0x4]; // offset 0xF, size 0x4 + u8 showDebugB; // offset 0x13, size 0x1 + u8 pad_0x14[0x1]; // offset 0x14, size 0x1 + u8 showDebugC; // offset 0x15, size 0x1 + u8 pad_0x16[0x2]; // offset 0x16, size 0x2 + u8 showDebugD; // offset 0x18, size 0x1 + u8 field_0x19; // offset 0x19, size 0x1 + u8 pad_0x1A[0x8]; // offset 0x1A, size 0x8 + u8 field_0x22; // offset 0x22, size 0x1 + u8 field_0x23; // offset 0x23, size 0x1 + u8 pad_0x24[0x4]; // offset 0x24, size 0x4 + int field_0x28; // offset 0x28, size 0x4 + u8 pad_0x2C[0x4]; // offset 0x2C, size 0x4 + int counter; // offset 0x30, size 0x4 +}; + +struct UnkModeVal5 { + void* vtable; // offset 0x0, size 0x4 + void* unkPtr_0x4; // offset 0x4, size 0x4 + u8 pad_0x8[0x64]; // offset 0x8, size 0x64 + void* field_0x6C; // offset 0x6C, size 0x4 +}; + +struct RPBowGameModeState { + // total size: 0x84 + DebugOverlaySettings current; // offset 0x0, size 0x34 + DebugOverlaySettings previous; // offset 0x34, size 0x34 + + // Either a RPBowScoreManager or DebugOverlaySub2 can be stored here for some reason. + void* modeVal1; // offset 0x68, size 0x4 + void* modeVal2; // offset 0x6C, size 0x4 + void* modeVal3; // offset 0x70, size 0x4 + void* modeVal4; // offset 0x74, size 0x4 + + // Stores some unknown struct + UnkModeVal5* modeVal5; // offset 0x78, size 0x4 + + int field_0x7C; // offset 0x7C, size 0x4 + void* startupModePtr; // offset 0x80, size 0x4 +}; + +struct PinHitState { + // total size: 0x8 + f32 hitTimer; // offset 0x0, size 0x4 + f32 unk_04; // offset 0x4, size 0x4 +}; + +struct ObstacleDef { + // total size: 0x10 + f32 scale; // offset 0x0, size 0x4 + f32 unk_04; // offset 0x4, size 0x4 + f32 offsetX; // offset 0x8, size 0x4 + f32 offsetZ; // offset 0xC, size 0x4 +}; + +struct ObstacleSet { + // total size: 0x150 + ObstacleDef obstacles[16]; // offset 0x0, size 0x100 + PinHitState pins[10]; // offset 0x100, size 0x50 +}; + +struct CollisionTriangleState { + // total size: 0x58 + nw4r::math::VEC3 vec0; // offset 0x0, size 0xC + nw4r::math::VEC3 vec1; // offset 0xC, size 0xC + nw4r::math::VEC3 vec2; // offset 0x18, size 0xC + + nw4r::math::VEC3 cross0; // offset 0x24, size 0xC + nw4r::math::VEC3 cross1; // offset 0x30, size 0xC + nw4r::math::VEC3 cross2; // offset 0x3C, size 0xC + nw4r::math::VEC3 cross3; // offset 0x48, size 0xC + + f32 edgeBias; // offset 0x54, size 0x4 +}; + +struct ObstacleInstance { + // total size: 0x524 + u8 active; // offset 0x0, size 0x1 + u8 pad0[0x3]; // offset 0x1, size 0x3 + CollisionTriangleState triangles[12]; // offset 0x4, size 0x420 + PhysicsBody body; // offset 0x424, size 0xFC + f32 baseScale; // offset 0x520, size 0x4 +}; + +class RPBowObstacleManager { +public: + // total size: 0x14 + ObstacleInstance* obstacles; // offset 0x0, size 0x4 + void* unkPointers[2]; // offset 0x4, size 0x8 + void* unkPtr_0xC; // offset 0xC, size 0x8 + ObstacleSet* dataPtr; // offset 0x10, size 0x4 + + u32 CheckObstacleCollision(u32 obstacleSetIdx, nw4r::math::VEC3* ball); + u32 CheckObstaclePassed(u32 obstacleSetIdx, nw4r::math::VEC3* ball); + void ResetLaneObstacles(u32 obstacleSetIdx, u32 isRightSide, f32 spawnZ); + void UpdateObstacleCollisionBounds(); +}; + +struct unkFrameScore { + // total size: 0x4c + PinStatus firstThrowPins; // 0x00, size: 0x14 + PinStatus secondThrowPins; // 0x14, size: 0x14 + u8 padding[0x24]; // 0x28 -> 0x4c +}; + +struct unkPlayerScore { + // total size: 0x344 + unkFrameScore frames[11]; // 11 frames * 0x4c = 0x344 +}; + +struct unkGameState_8032E2C4 { + u8 pad00[0x8]; + s32 currentFrame; // 0x08 + s32 currentThrow; // 0x0C (0 = None, 1 = First, 2 = Second) + u32 currentPlayer; // 0x10 + u8 pad14[0x4]; + s32 targetFrame; // 0x18 + u8 pad1C[0x58]; // Padding to reach 0x74 + + unkPlayerScore players[4]; // 0x74, Array of players +}; + +struct RPBowGameManager { + // total size: 0x78 + void* vtable; // offset 0x0, size 0x4 + RPBowGameModeState* gameModeState; // offset 0x4, size 0x4 + RPBowSceneObjectManager* objectManager; // offset 0x8, size 0x4 + RPBowLaneDataHolder* laneData; // offset 0xC, size 0x4 + RPBowCameraTransform* cameraTransform; // offset 0x10, size 0x4 + RPBowScoreManager* bowlingScoreManager; // offset 0x14, size 0x4 + BowlerContext* bowlerContext; // offset 0x18, size 0x4 + RPBowGlobalLaneManager* globalLaneManager; // offset 0x1C, size 0x4 + BowlingSwingContext* swing; // offset 0x20, size 0x4 + + // ManagerContext is used in all modes except for Spin Control + union { + RPBowManagerContext* managerContext; // offset 0x24, size 0x4 + RPBowObstacleManager* obstacleData; // offset 0x24, size 0x4 + }; + ControllerWrapper* controllerWrapper; // offset 0x28, size 0x4 + UnkModeVal5* unkModeVal5; // offset 0x2C, size 0x4 + void* unkPtr_0x30; // offset 0x30, size 0x4 + void* unkPtr_0x34; // offset 0x34, size 0x4 + u8 pad_0x38[0x4]; // offset 0x38, size 0x4 + BowlingGameStates bowlingGameState; // offset 0x3C, size 0x4 + int sceneFrameCounter; // offset 0x40, size 0x4 + int field_0x44; // offset 0x44, size 0x4 + int replayFrameCounter; // offset 0x48, size 0x4 + u8 field_0x4C; // offset 0x4C, size 0x1 + u8 pad_0x4D[0x03]; // offset 0x4D, size 0x3 + ControllerWrapperManager* cwm; // offset 0x50, size 0x4 + u8 field_0x54; // offset 0x54, size 0x1 + u8 pad_0x55[0x03]; // offset 0x55, size 0x3 + float playerLanePosition; // offset 0x58, size 0x4 + float playerLaneRotation; // offset 0x5C, size 0x4 + int inputIdleTimer; // offset 0x60, size 0x4 + u8 pad_0x64[0x4]; // offset 0x64, size 0x4 + u8 pad_0x68[0x4]; // offset 0x68, size 0x4 + int field_0x6C; // offset 0x6C, size 0x4 + u8 field_0x70; // offset 0x70, size 0x1 + u8 field_0x71; // offset 0x71, size 0x1 + u8 isScoreViewHidden; // offset 0x72, size 0x1 + u8 pad_0x73; // offset 0x73, size 0x1 + int field_0x74; // offset 0x74, size 0x4 + + void InitializeBowlingGameCtx(int arg1, int arg2, ControllerWrapperManager* cwm, u8 arg4, int, int arg5); + void fn_8032EFF8(); + bool UpdateGameState(); + void ExecuteGameModeUpdateTick(u32 majorState, int minorState); + void StartGameCameraDemoProc(); + void PlayerScoreViewProc(); + int GetNumRemainingPins(PinStatus* param_1); + int GetNumDownedPins(PinStatus* param_1); + bool fn_8032E2C4(unkGameState_8032E2C4* ptr); + void MainBowlingViewProc(); + void FailedBowlMessageProc(); + void ReplayProc(); + void EndGameProc(); + void SetScoreViewAndCullNpcs(int isScoreViewHidden); + void UnusedState8Proc(); + +}; + +struct DebugOverlaySub1 { + // total size: 0x3E4 + u8 pad_00[0xD8]; // offset 0x0, size 0xD8 + u32 trackingValue1; // offset 0xD8, size 0x4 + u8 pad_DC[0x304]; // offset 0xDC, size 0x304 + float trackingValue2; // offset 0x3E0, size 0x4 +}; + +struct DebugOverlaySub2 { + // total size: 0xE4 + u8 pad_00[0x10]; // offset 0x0, size 0x10 + u32 validCount; // offset 0x10, size 0x4 + u8 isValidArray[0xCC]; // offset 0x14, size 0xCC + float trackingValue3; // offset 0xE0, size 0x4 +}; + +struct UnkBowlingObj1 { + // total size: 0x29DC + u8 pad_0x0[0x4]; // offset 0x0, size 0x4 + u32* unk_0x4; // offset 0x4, size 0x4 + nw4r::math::VEC3* vecArray1; // offset 0x8, size 0x4 + u8 pad_0xC[0x8]; // offset 0xC, size 0x8 + u32 someIndex; // offset 0x14, size 0x4 + u8 pad_0x18[0x1FFC]; // offset 0x18, size 0x1FFC + u32 i_2014; // offset 0x2014, size 0x4 + u8 pad_0x2018[0x68]; // offset 0x2018, size 0x68 + f32 f_2080; // offset 0x2080, size 0x4 + f32 f_2084; // offset 0x2084, size 0x4 + s32 i_2088; // offset 0x2088, size 0x4 + f32 f_208C; // offset 0x208C, size 0x4 + f32 f_2090; // offset 0x2090, size 0x4 + u8 pad_0x2094[0xC]; // offset 0x2094, size 0xC + f32 f_20A0; // offset 0x20A0, size 0x4 + f32 f_20A4; // offset 0x20A4, size 0x4 + u8 pad_0x20A8[0x34]; // offset 0x20A8, size 0x34 + int field_0x20DC; // offset 0x20DC, size 0x4 + int field_0x20E0; // offset 0x20E0, size 0x4 + u8 pad_0x20E4[0x868]; // offset 0x20E4, size 0x868 + s32 i_294C; // offset 0x294C, size 0x4 + u8 pad_0x2950[0x4]; // offset 0x2950, size 0x4 + nw4r::math::VEC3 vec_2954[11]; // offset 0x2954, size 0x84 + u8 flag_0x29D8; // offset 0x29D8, size 0x1 + u8 pad29DC[0x3]; // offset 0x29D9, size 0x3 +}; + +struct RPBowSceneDirector : public IRPSysHostIOSocket { + virtual ~RPBowSceneDirector(); + + void* unkPtr_0x4; // offset 0x4, size 0x4 + RPBowSceneObjectManager* objectManager; // offset 0x8, size 0x4 + RPBowCameraController* cameraController; // offset 0xC, size 0x4 + CameraProjection* cameraProjection; // offset 0x10, size 0x4 + RPBowCameraTransform* cameraTransform; // offset 0x14, size 0x4 + RPBowLaneDataHolder* laneData; // offset 0x18, size 0x4 + LaneContext* laneContext; // offset 0x1C, size 0x4 + int frame; // offset 0x20, size 0x4 + + void fn_8034C8D4(RPBowSceneObjectManager* objectManager, RPBowCameraController* camController, RPBowCameraTransform* cameraTransform, CameraProjection* cameraProjection, RPBowLaneDataHolder* laneData, LaneContext* laneContext); + void fn_8034C6B0(int param1, int param2, u8* param3, int param4, int frame); + void fn_8034C6AC(); + void fn_8034C230(); + void fn_8034C1AC(u32 state, int p3); +}; + +struct SceneContext { + // total size: 0xC64 + u8 pad_0x0[0x4]; // offset 0x0, size 0x4 + u32 mUnk4; // offset 0x4, size 0x4 + u8 pad_0x8[0x2C]; // offset 0x8, size 0x2C + u8 mUnk34; // offset 0x34, size 0x1 + u8 pad_0x35[0x3]; // offset 0x35, size 0x3 + u8 pad_0x38[0xBE4]; // offset 0x38, size 0xBE4 + u8 mUnkC1C; // offset 0xC1C, size 0x1 + u8 pad_0xC1D[0x3]; // offset 0xC1D, size 0x3 + PinStatus pinStatus; // offset 0xC20, size 0x14 + u8 mUnkC34; // offset 0xC34, size 0x1 + u8 pad_0xC35[0x3]; // offset 0xC35, size 0x3 + s32 field_0xC38; // offset 0xC38, size 0x4 + s32 field_0xC3C; // offset 0xC3C, size 0x4 + s32 field_0xC40; // offset 0xC40, size 0x4 + u8 mUnkC44; // offset 0xC44, size 0x1 + u8 unkC45[10]; // offset 0xC45, size 0xA + u8 pad_0xC4F[0x1]; // offset 0xC4F, size 0x1 + s32 unkC50; // offset 0xC50, size 0x4 + u8 mUnkC54; // offset 0xC54, size 0x1 + u8 mUnkC55; // offset 0xC55, size 0x1 + u8 pad_0xC56[0x2]; // offset 0xC56, size 0x2 + s32 field_0xC58; // offset 0xC58, size 0x4 + u8 pad_0xC5C[0x1]; // offset 0xC5C, size 0x1 + u8 mUnkC5D; // offset 0xC5D, size 0x1 + u8 pad_0xC5E[0x2]; // offset 0xC5E, size 0x2 + s32 unkC60; // offset 0xC60, size 0x4 +}; + +struct DummyLayoutBase { + // total size: 0xC + virtual void dummy(); + + u8 mUnk4; // offset 0x4, size 0x1 + u8 pad_0x5[0x3]; // offset 0x5, size 0x3 + u8 pad_0x8[0x4]; // offset 0x8, size 0x4 +}; + +struct PlayerFrame { + // total size: 0x40 + RPSysLayout* layout; // offset 0x0, size 0x4 + nw4r::lyt::Pane* scoreBG; // offset 0x4, size 0x4 + nw4r::lyt::Pane* rootPane; // offset 0x8, size 0x4 + f32 rootX; // offset 0xC, size 0x4 + f32 rootY; // offset 0x10, size 0x4 + nw4r::lyt::TextBox* throwT[3]; // offset 0x14, size 0xC + nw4r::lyt::TextBox* totalT; // offset 0x20, size 0x4 + nw4r::lyt::Pane* strikeP[3]; // offset 0x24, size 0xC + nw4r::lyt::Pane* spareP[3]; // offset 0x30, size 0xC + u8 alpha; // offset 0x3C, size 0x1 + u8 pad3D[3]; // offset 0x3D, size 0x3 +}; + +class RPBowScoreLayout : public DummyLayoutBase, public IRPSysHostIOSocket { +public: + // total size: 0xBD0 + virtual ~RPBowScoreLayout(); + + RPSysLayout* mpLayout; // offset 0x10, size 0x4 + PlayerFrame mFrames[4][11]; // offset 0x14, size 0xB00 + + nw4r::lyt::Pane* mpFrameBGP[11]; // offset 0xB14, size 0x2C + nw4r::lyt::TextBox* mpFrameT[11]; // offset 0xB40, size 0x2C + nw4r::lyt::Picture* mpPlayerBGP[4]; // offset 0xB6C, size 0x10 + + u32 unkB7C; // offset 0xB7C, size 0x4 + RPSysKokeshiIcon* mpIcons[4]; // offset 0xB80, size 0x10 + nw4r::lyt::Pane* mpPlayerIconP[4]; // offset 0xB90, size 0x10 + + u32 unkBA0; // offset 0xBA0, size 0x4 + u32 unkBA4; // offset 0xBA4, size 0x4 + u32 unkBA8; // offset 0xBA8, size 0x4 + + nw4r::math::VEC3 mScoreRoot; // offset 0xBAC, size 0xC + + nw4r::lyt::Pane* mpScoreRootP; // offset 0xBB8, size 0x4 + nw4r::lyt::Pane* mpRootPane; // offset 0xBBC, size 0x4 + + f32 unkBC0; // offset 0xBC0, size 0x4 + f32 unkBC4; // offset 0xBC4, size 0x4 + + u32 unkBC8; // offset 0xBC8, size 0x4 + u32 unkBCC; // offset 0xBCC, size 0x4 + + void Init(RPSysLytResAccessor* acc, u32 unk); + void InitIcons(); + void Reset(); +}; + +class RPBowNormalPinLayout : public DummyLayoutBase, public IRPSysHostIOSocket { +public: + virtual ~RPBowNormalPinLayout(); + + RPSysLayout* mpLayout; // offset 0x10, size 0x4 + s32 mAnimationState; // offset 0x14, size 0x4 + nw4r::lyt::Pane* mpRootPane; // offset 0x18, size 0x4 + nw4r::lyt::Pane* mpPinPanes[10]; // offset 0x1C, size 0x28 + + void Init(RPSysLytResAccessor* acc); + void Reset(); + void Update(SceneContext* pContext); + void Draw(); + bool IsFinished() const; +}; + +struct StagePane { + // total size: 0xC + nw4r::lyt::Pane* lineBG; // offset 0x0, size 0x4 + nw4r::lyt::Pane* line; // offset 0x4, size 0x4 + RPSysLytAnmObj* stageAnm; // offset 0x8, size 0x4 +}; + +class RPBowPowerThrowsPinLayout : public DummyLayoutBase, public IRPSysHostIOSocket { +public: + virtual ~RPBowPowerThrowsPinLayout(); + + RPSysLayout* mpLayout; // offset 0x10, size 0x4 + s32 mAnimationState; // offset 0x14, size 0x4 + nw4r::lyt::Pane* mpRootPane; // offset 0x18, size 0x4 + StagePane mStages[10]; // offset 0x1C, size 0x78 + nw4r::lyt::Pane* mpPins[91]; // offset 0x94, size 0x16C + + void Init(RPSysLytResAccessor* acc); + void Reset(); + void Update(SceneContext* pContext); + void Draw(); + bool IsFinished() const; +}; + +class RPBowGuidanceLayout { +public: + // total size: 0x24 + void* vtable; // offset 0x0, size 0x4 + bool unk04; // offset 0x4, size 0x1 + u8 pad_0x5[0x3]; // offset 0x5, size 0x3 + u8 pad_0x8[0x4]; // offset 0x8, size 0x4 + RPSysLayout* mpLayout; // offset 0xC, size 0x4 + s32 mAnimationState; // offset 0x10, size 0x4 + RPSysLytAnmObj* mpAnm1; // offset 0x14, size 0x4 + RPSysLytAnmObj* mpAnm2; // offset 0x18, size 0x4 + RPSysMessage* mpMessage; // offset 0x1C, size 0x4 + RPSysLytTextBox* mpTextBox1; // offset 0x20, size 0x4 + nw4r::lyt::Pane* mpPane1; // offset 0x24, size 0x4 + u8 mFlag28; // offset 0x28, size 0x1 + u8 pad_29[0x3]; // offset 0x29, size 0x3 + + void Init(RPSysLytResAccessor* acc, RPSysMessage* msg); + void Reset(); + void Draw(); + bool IsFinished() const; +}; + +class RPBowEventTextLayout { +public: + // total size: 0x24 + void* vtable; // offset 0x0, size 0x4 + bool unk04; // offset 0x4, size 0x1 + u8 pad_0x5[0x3]; // offset 0x5, size 0x3 + u8 pad_0x8[0x4]; // offset 0x8, size 0x4 + RPSysLayout* mpLayout; // offset 0xC, size 0x4 + RPSysLytTextBox* mpTextBoxes[2][2]; // offset 0x10, size 0x10 + RPSysMessage* mpMessage; // offset 0x20, size 0x4 + RPSysLytAnmObj* mpAnm1; // offset 0x24, size 0x4 + RPSysLytAnmObj* mpAnm2; // offset 0x28, size 0x4 + s32 mAnimationState; // offset 0x2C, size 0x4 + nw4r::lyt::Pane* mpPane1; // offset 0x30, size 0x4 + nw4r::lyt::Pane* mpPane2; // offset 0x34, size 0x4 + RPSysLytTextBox* mpTextBox5; // offset 0x38, size 0x4 + RPSysLytTextBox* mpTextBox6; // offset 0x3C, size 0x4 + RPSysLytAnmObj* mpAnm3; // offset 0x40, size 0x4 + nw4r::lyt::Pane* mpPane3; // offset 0x44, size 0x4 + s32 mField48; // offset 0x48, size 0x4 + + void Init(RPSysLytResAccessor* acc, RPSysMessage* msg); + void Reset(); + void Update(SceneContext* pContext); + void Draw(); + bool IsFinished() const; +}; + +class RPBowTrainingStageLayout { +public: + // total size: 0x24 + void* vtable; // offset 0x0, size 0x4 + bool unk04; // offset 0x4, size 0x1 + u8 pad_0x5[0x3]; // offset 0x5, size 0x3 + u8 pad_0x8[0x4]; // offset 0x8, size 0x4 + RPSysLayout* mpLayout; // offset 0xC, size 0x4 + s32 mAnimationState; // offset 0x10, size 0x4 + RPSysLytTextBox* mpTextBox1; // offset 0x14, size 0x4 + RPSysLytTextBox* mpTextBox2; // offset 0x18, size 0x4 + RPSysMessage* mpMessage; // offset 0x1C, size 0x4 + + void Init(RPSysLytResAccessor* acc, RPSysMessage* msg); + void Reset(); + void Update(SceneContext* pContext); + void Draw(); + bool IsFinished() const; +}; + +class RPBowPowerThrowsStageLayout { +public: + // total size: 0x24 + void* vtable; // offset 0x0, size 0x4 + bool unk04; // offset 0x4, size 0x1 + u8 pad_0x5[0x3]; // offset 0x5, size 0x3 + u8 pad_0x8[0x4]; // offset 0x8, size 0x4 + RPSysLayout* mpLayout; // offset 0xC, size 0x4 + s32 mAnimationState; // offset 0x10, size 0x4 + RPSysLytTextBox* mpTextBox1; // offset 0x14, size 0x4 + RPSysLytTextBox* mpTextBox2; // offset 0x18, size 0x4 + RPSysLytTextBox* mpTextBox3; // offset 0x1C, size 0x4 + RPSysLytTextBox* mpTextBox4; // offset 0x20, size 0x4 + RPSysMessage* mpMessage; // offset 0x24, size 0x4 + + void Init(RPSysLytResAccessor* acc, RPSysMessage* msg); + void Reset(); + void Update(SceneContext* pContext); + void Draw(); + bool IsFinished() const; +}; + +class RPBowGameOverLayout { +public: + // total size: 0x24 + void* vtable; // offset 0x0, size 0x4 + bool unk04; // offset 0x4, size 0x1 + u8 pad_0x5[0x3]; // offset 0x5, size 0x3 + u8 pad_0x8[0x4]; // offset 0x8, size 0x4 + RPSysLayout* mpLayout; // offset 0xC, size 0x4 + s32 mAnimationState; // offset 0x10, size 0x4 + RPSysLytAnmObj* mpUnkAnim; // offset 0x14, size 0x4 + RPSysLytTextBox* mpTextBox1; // offset 0x18, size 0x4 + RPSysLytTextBox* mpTextBox2; // offset 0x1C, size 0x4 + RPSysMessage* mpMessage; // offset 0x20, size 0x4 + + void Init(RPSysLytResAccessor* acc, RPSysMessage* msg); + void Reset(); + void Update(); + void Draw(); + bool IsFinished() const; +}; + +class RPBowStrikeLayout { +public: + // total size: 0x24 + void* vtable; // offset 0x0, size 0x4 + bool unk04; // offset 0x4, size 0x1 + u8 pad_0x5[0x3]; // offset 0x5, size 0x3 + u8 pad_0x8[0x4]; // offset 0x8, size 0x4 + RPSysLayout* mpLayout; // offset 0xC, size 0x4 + s32 mAnimationState; // offset 0x10, size 0x4 + RPSysLytAnmObj* mpStrikeAnim; // offset 0x14, size 0x4 + RPSysLytTextBox* mpTextBox1; // offset 0x18, size 0x4 + RPSysLytTextBox* mpTextBox2; // offset 0x1C, size 0x4 + RPSysMessage* mpMessage; // offset 0x20, size 0x4 + + void Init(RPSysLytResAccessor* pAccessor, RPSysMessage* msg); + void Reset(); + void Update(SceneContext* pContext); + void Draw(); + bool IsFinished() const; +}; + +class RPBowTutorialLayout { +public: + // total size: 0x30 + void* vtable; // offset 0x0, size 0x4 + bool unk04; // offset 0x4, size 0x1 + u8 pad_0x5[0x3]; // offset 0x5, size 0x3 + u8 pad_0x8[0x4]; // offset 0x8, size 0x4 + RPSysLayout* mpLayout; // offset 0xC, size 0x4 + s32 mAnimationState; // offset 0x10, size 0x4 + RPSysLytAnmObj* mpObj1; // offset 0x14, size 0x4 + RPSysLytAnmObj* mpObj2; // offset 0x18, size 0x4 + RPSysLytAnmObj* mpObj3; // offset 0x1C, size 0x4 + RPSysMessage* mpMessage; // offset 0x20, size 0x4 + nw4r::lyt::Pane* mpPane1; // offset 0x24, size 0x4 + void* mpTutorialHelper; // offset 0x28, size 0x4 + nw4r::lyt::Pane* mpPane2; // offset 0x2C, size 0x4 + + void Init(RPSysLytResAccessor* acc, RPSysMessage* msg); + void Reset(); + void Update(); + void Draw(); + bool IsFinished() const; +}; + +struct TrainingLifePane { + // total size: 0x28 + RPSysLytAnmObj* bigBallObj; // offset 0x0, size 0x4 + RPSysLytAnmObj* smallBallObj; // offset 0x4, size 0x4 + s32 activeIdx1; // offset 0x8, size 0x4 + RPSysLytAnmObj* colors[5]; // offset 0xC, size 0x14 + s32 activeIdx2; // offset 0x20, size 0x4 + nw4r::lyt::Pane* pane; // offset 0x24, size 0x4 +}; + +class RPBowTrainingLivesLayout : public DummyLayoutBase, public IRPSysHostIOSocket { +public: + virtual ~RPBowTrainingLivesLayout(); + + RPSysLayout* mpLayout; // offset 0x10, size 0x4 + s32 mAnimationState; // offset 0x14, size 0x4 + nw4r::lyt::Pane* mpRootPane; // offset 0x18, size 0x4 + TrainingLifePane mAnmPanes[5]; // offset 0x1C, size 0xC8 + + void Init(RPSysLytResAccessor* acc); + void Reset(); + void Update(SceneContext* pContext); + void Draw(); + bool IsFinished() const; +}; + +struct PowerThrowsRoundPane { + // total size: 0x1C + RPSysLytAnmObj* anmObjs[4]; // offset 0x0, size 0x10 + s32 activeIdx; // offset 0x10, size 0x4 + nw4r::lyt::Pane* pane1; // offset 0x14, size 0x4 + nw4r::lyt::Pane* pane2; // offset 0x18, size 0x4 +}; + +class RPBowPowerThrowsRoundsLayout { +public: + u8 pad_0[0x4]; // offset 0x0, size 0x4 + bool unk04; // offset 0x4, size 0x1 + u8 pad_5[0x7]; // offset 0x5, size 0x7 + RPSysLayout* mpLayout; // offset 0xC, size 0x4 + s32 mAnimationState; // offset 0x10, size 0x4 + nw4r::lyt::Pane* mpRootPane; // offset 0x14, size 0x4 + PowerThrowsRoundPane mAnmPanes[10]; // offset 0x18, size 0x118 + RPSysLytTextBox* mpTextBoxes[2][2]; // offset 0x130, size 0x10 + RPSysMessage* mpMessage; // offset 0x140, size 0x4 + + void Init(RPSysLytResAccessor* acc, RPSysMessage* msg); + void Reset(); + void Update(SceneContext* pContext); + void Draw(); + bool IsFinished() const; +}; + +class RPBowAimGuideLayout : public DummyLayoutBase, public IRPSysHostIOSocket { +public: + virtual ~RPBowAimGuideLayout(); + + RPSysLayout* mpLayout; // offset 0x10, size 0x4 + u32 mState; // offset 0x14, size 0x4 + nw4r::lyt::Pane* mpRootPane; // offset 0x18, size 0x4 + RPSysLytAnmObj* mpBlinkAnm; // offset 0x1C, size 0x4 + nw4r::lyt::Pane* mpPlusButton00; // offset 0x20, size 0x4 + RPSysLytTextBox* mpPlusText00; // offset 0x24, size 0x4 + RPSysLytTextBox* mpPlusText01; // offset 0x28, size 0x4 + RPSysLytTextBox* mpAText00; // offset 0x2C, size 0x4 + RPSysLytTextBox* mpAText01; // offset 0x30, size 0x4 + RPSysMessage* mpMessage; // offset 0x34, size 0x4 + u32 mUnk38; // offset 0x38, size 0x4 + s32 mUnk3C; // offset 0x3C, size 0x4 + u32 mUnk40; // offset 0x40, size 0x4 + u32 mUnk44; // offset 0x44, size 0x4 + RPSysLytAnmObj* mpChangeAnm[2]; // offset 0x48, size 0x8 + nw4r::lyt::Pane* mpChangePanes[2]; // offset 0x50, size 0x8 + RPSysLytAnmObj* mpOnAnm[2]; // offset 0x58, size 0x8 + RPSysLytAnmObj* mpOffAnm[2]; // offset 0x60, size 0x8 + nw4r::lyt::Pane* mpOnOffPanes[2]; // offset 0x68, size 0x8 + u32 mUnk70; // offset 0x70, size 0x4 + + void Init(EGG::Heap* pHeap, RPSysMessage* pMsg); + void Reset(); + void Calc(SceneContext* pContext); + void Draw(); + bool IsFinished() const; +}; + +class RPBowPerfectGameUI { +public: + // total size: 0x24 + u8 pad_0x00[0x4]; // offset 0x0, size 0x4 + u8 mIsVisible; // offset 0x4, size 0x1 + u8 pad_0x05[0x3]; // offset 0x5, size 0x3 + u32 mDrawGroup; // offset 0x8, size 0x4 + RPSysLayout* mpLayout; // offset 0xC, size 0x4 + RPSysEffect* mpHubukiEffect; // offset 0x10, size 0x4 + s32 mState; // offset 0x14, size 0x4 + RPSysLytAnmObj* mpAnmIn; // offset 0x18, size 0x4 + RPSysLytAnmObj* mpAnmOut; // offset 0x1C, size 0x4 + nw4r::lyt::Pane* mpRootPane; // offset 0x20, size 0x4 + + void Init(RPSysLytResAccessor* pAccessor, RPSysMessage* pMessage); + void Reset(); + void Calc(); + void Draw(); }; // Global Data: @@ -775,66 +2407,6 @@ struct BallReturnRackConstants { 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 @@ -855,5 +2427,3 @@ struct BackgroundNpcConfig { extern BallReturnRackConstants gBallReturnRackConstants; extern BowlingPhysicsData gBowlingPhysicsData; - -} // namespace Bowling diff --git a/include/egg/gfxe/eggScreen.h b/include/egg/gfxe/eggScreen.h index d3587f86d..eded627da 100644 --- a/include/egg/gfxe/eggScreen.h +++ b/include/egg/gfxe/eggScreen.h @@ -102,6 +102,10 @@ class Screen : public Frustum { return sTVModeHeights[tvMode]; } + static TVMode GetTVMode() { + return sTVMode; + } + private: enum { FLAG_ALIGN_EFB_POS = 1 << 1, diff --git a/src/Pack/RPSports/RPBowScene/RPBowActiveBall.cpp b/src/Pack/RPSports/RPBowScene/RPBowActiveBall.cpp index 6fb3f4c2a..3af6cc3bc 100644 --- a/src/Pack/RPSports/RPBowScene/RPBowActiveBall.cpp +++ b/src/Pack/RPSports/RPBowScene/RPBowActiveBall.cpp @@ -6,7 +6,27 @@ 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 Destructor + */ +RPBowActiveBall::~RPBowActiveBall() {} + +/** + * @brief Unknown stub + */ +void RPBowActiveBall::fn_8032ADF4(void) { + ; +} + +/** + * @brief Sets the real and reflection models for a model set + */ +void RPBowActiveBall::SetModelSet(u32 index, RPGrpModel* realModel, RPGrpModel* reflectionModel) { + models[index].pRealModel = realModel; + models[index].pReflectionModel = reflectionModel; + + realModel->CreateBoundingInfo(1); +} /** * @brief Initializes the render object to its default state @@ -106,5 +126,3 @@ void RPBowActiveBall::RenderModelSet() { pShadowTexture->AddModel(models[index].pRealModel, 1.0f); } } - -} // namespace Bowling diff --git a/src/Pack/RPSports/RPBowScene/RPBowAimGuideLayout.cpp b/src/Pack/RPSports/RPBowScene/RPBowAimGuideLayout.cpp new file mode 100644 index 000000000..3c3016648 --- /dev/null +++ b/src/Pack/RPSports/RPBowScene/RPBowAimGuideLayout.cpp @@ -0,0 +1,193 @@ +#include + +extern const nw4r::math::VEC2 lbl_803CAE40[2][16]; +extern const f32 lbl_804BFA08[2]; + +/** + * @brief Destructor + */ +RPBowAimGuideLayout::~RPBowAimGuideLayout() {} + +/** + * @brief Initializes the aim guide layout + * + * @param pHeap Memory heap + * @param pMsg System message configuration + */ +void RPBowAimGuideLayout::Init(EGG::Heap* pHeap, RPSysMessage* pMsg) { + mpMessage = pMsg; + mpLayout = RPSysLayout::create((EGG::Heap*)NULL, (RPSysLytResAccessor*)pHeap, "bwgMoveExp_00.brlyt"); + mpRootPane = mpLayout->findPane("RootPane"); + + mpBlinkAnm = mpLayout->createAnmObj((EGG::Heap*)NULL, (RPSysLytResAccessor*)pHeap, "bwgMoveExp_00_blink_00.brlan"); + mpPlusButton00 = mpLayout->findPane("N_plusButton_00"); + + mpPlusText00 = mpLayout->findTextBox("T_plusText_00"); + mpPlusText01 = mpLayout->findTextBox("T_plusText_01"); + mpAText00 = mpLayout->findTextBox("T_aText_00"); + mpAText01 = mpLayout->findTextBox("T_aText_01"); + + mpAText00->setMessage(mpMessage, 0x65B9, 0, 0); + mpAText01->setMessage(mpMessage, 0x65B9, 0, 0); + + mpChangeAnm[0] = mpLayout->createAnmObj((EGG::Heap*)NULL, (RPSysLytResAccessor*)pHeap, "bwgMoveExp_00_change_00.brlan"); + mpChangeAnm[1] = mpLayout->createAnmObj((EGG::Heap*)NULL, (RPSysLytResAccessor*)pHeap, "bwgMoveExp_00_change_00.brlan"); + + mpChangePanes[0] = mpLayout->findPane("N_aButton_00"); + mpChangePanes[1] = mpLayout->findPane("N_plusText_00"); + + for (int i = 0; i < 2; i++) { + mpOnAnm[i] = mpLayout->createAnmObj((EGG::Heap*)NULL, (RPSysLytResAccessor*)pHeap, "bwgMoveExp_00_on_00.brlan"); + mpOffAnm[i] = mpLayout->createAnmObj((EGG::Heap*)NULL, (RPSysLytResAccessor*)pHeap, "bwgMoveExp_00_off_00.brlan"); + } + + mpOnOffPanes[0] = mpLayout->findPane("N_plusButton_01"); + mpOnOffPanes[1] = mpLayout->findPane("N_plusText_01"); + + RPSysLytTextBox* pPlusText02 = mpLayout->findTextBox("T_plusText_02"); + pPlusText02->setMessage(pMsg, 0x65ba, 0, 0); + + RPSysLytTextBox* pPlusText03 = mpLayout->findTextBox("T_plusText_03"); + pPlusText03->setMessage(pMsg, 0x65ba, 0, 0); + + mState = 0; +} + +/** + * @brief Resets the layout and unbinds objects + */ +void RPBowAimGuideLayout::Reset() { + mpLayout->reset(); + mpLayout->unbindAllAnmObj(); + mState = 0; + mUnk44 = 0; + mUnk3C = 0; + mUnk40 = 0; +} + +/** + * @brief Calculates transformations and pane statuses based on current context + * + * @param pContext Bowling scene context + */ +void RPBowAimGuideLayout::Calc(SceneContext* pContext) { + if (pContext->mUnkC54 != 0) { + mUnk38 = 0; + } else { + mUnk38 = 1; + } + + s32 animSpeed = -pContext->mUnkC34; + + if (mState == 0 || mState == 3) { + if (mUnk4 != 0) { + mpLayout->unbindAllAnmObj(); + RPSysLayout::bindAnmObjToPane(mpBlinkAnm, mpPlusButton00, true); + + mpBlinkAnm->setFrame(mpBlinkAnm->getStartFrame()); + mpBlinkAnm->setFlags(0); + mpBlinkAnm->setEnabled(1); + + mUnk70 = 1; + + for (int i = 0; i < 2; i++) { + RPSysLayout::bindAnmObjToPane(mpOnAnm[i], mpOnOffPanes[i], true); + mpOnAnm[i]->play((s16)(mpOnAnm[i]->getFrameMax() - 1.0f)); + } + + mpLayout->startDynAnmIn(animSpeed); + mState = 1; + mUnk38 = 0; + mUnk44 = 99999; + mUnk3C = -1; + mUnk40 = 0; + } + } + + if (mState == 1 || mState == 2) { + if (mUnk4 == 0) { + mpLayout->startDynAnmOut(0); + mState = 3; + } + } + + if (mState == 1) { + if (mpLayout->isFinishedDynAnmIn()) { + mState = 2; + } + } + + if (mState == 3) { + if (mpLayout->isFinishedDynAnmOut()) { + mState = 0; + } + } + + if (mUnk40 != mUnk38) { + for (int i = 0; i < 2; i++) { + RPSysLayout::unbindAnmObjToPane(mpChangeAnm[i], mpChangePanes[i], true); + RPSysLayout::bindAnmObjToPane(mpChangeAnm[i], mpChangePanes[i], true); + + RPSysLytAnmObj* pTempAnm = mpChangeAnm[i]; + pTempAnm->setFrame(pTempAnm->getStartFrame()); + pTempAnm->setFlags(0); + pTempAnm->setEnabled(1); + } + mUnk40 = mUnk38; + } + + if (mUnk38 != mUnk3C) { + mUnk44++; + if (mUnk44 >= 4) { + mpPlusText00->setMessage(mpMessage, 0x65B8, 0, 0); + mpPlusText01->setMessage(mpMessage, 0x65B8, mUnk38, 0); + mUnk44 = 0; + mUnk3C = mUnk38; + } + } + + u32 cond = (pContext->mUnkC5D == 0) ? 1 : 0; + if (mUnk70 != cond) { + RPSysLayout::unbindAnmObjToPane(mpOnAnm[0], mpOnOffPanes[0], true); + RPSysLayout::unbindAnmObjToPane(mpOnAnm[1], mpOnOffPanes[1], true); + RPSysLayout::unbindAnmObjToPane(mpOffAnm[0], mpOnOffPanes[0], true); + RPSysLayout::unbindAnmObjToPane(mpOffAnm[1], mpOnOffPanes[1], true); + + for (int i = 0; i < 2; i++) { + RPSysLytAnmObj* pAnm = mpOnAnm[i]; + RPSysLayout::bindAnmObjToPane(pAnm, mpOnOffPanes[i], true); + + pAnm->setFrame(pAnm->getStartFrame()); + pAnm->setFlags(0); + pAnm->setEnabled(1); + } + + mUnk70 = cond; + } + + bool isTvMode = EGG::Screen::GetTVMode(); + nw4r::math::VEC2 pos( + lbl_803CAE40[isTvMode][pContext->mUnkC1C].x, + lbl_804BFA08[isTvMode] * (pContext->mUnk4 - 1) + lbl_803CAE40[isTvMode][pContext->mUnkC1C].y + ); + + mpRootPane->SetTranslate(nw4r::math::VEC3(pos.x, pos.y, 0.0f)); + + mpLayout->calc(); +} + +/** + * @brief Draws the layout + */ +void RPBowAimGuideLayout::Draw() { + mpLayout->draw(); +} + +/** + * @brief Tests whether the layout animation has finished + * + * @return True if state is 0, false otherwise + */ +bool RPBowAimGuideLayout::IsFinished() const { + return mState == 0; +} diff --git a/src/Pack/RPSports/RPBowScene/RPBowAlleyModelManager.cpp b/src/Pack/RPSports/RPBowScene/RPBowAlleyModelManager.cpp new file mode 100644 index 000000000..3cba0ae9c --- /dev/null +++ b/src/Pack/RPSports/RPBowScene/RPBowAlleyModelManager.cpp @@ -0,0 +1,166 @@ +#include + +// External table used by the priority loop (defined elsewhere) +extern const f32 gLaneXOffsets[]; + +/** + * @brief Stub + */ +void RPBowAlleyModelManager::fn_8031EFE0() { + ; +} + +/** + * @brief Destructor + */ +RPBowAlleyModelManager::~RPBowAlleyModelManager() {} + +/** + * @brief Sets the primary models for the alley scene + * + * @param pLaneModel Regular alley Lanes model + * @param pPowerThrowsRoomModel Power Throws area model (entire room, no culling) + * @param pStaticPinsModel Regular alley static pins model (outside of the 7 active lanes) + * @param pLoungeModel Regular alley lounge area model + * @param pLeftBumperModel Left Power Throws bumper + * @param pLeftBumperReflModel Left Power Throws bumper reflection + * @param pRightBumperModel Right Power Throws bumper + * @param pRightBumperReflModel Right Power Throws bumper reflection + */ +void RPBowAlleyModelManager::SetModels(RPGrpModel* pLaneModel, RPGrpModel* pPowerThrowsRoomModel, RPGrpModel* pStaticPinsModel, RPGrpModel* pLoungeModel, RPGrpModel* pLeftBumperModel, RPGrpModel* pLeftBumperReflModel, RPGrpModel* pRightBumperModel, RPGrpModel* pRightBumperReflModel) { + mModels[0] = pLaneModel; + mModels[1] = pPowerThrowsRoomModel; + mModels[2] = pStaticPinsModel; + mModels[3] = pLoungeModel; + mModels[4] = pLeftBumperModel; + mModels[6] = pLeftBumperReflModel; + mModels[5] = pRightBumperModel; + mModels[7] = pRightBumperReflModel; +} + +/** + * @brief Sets a specific model slot for rendering + * + * @param index Slot index + * @param pModel Main model + * @param pAltModel Alternate model + */ +void RPBowAlleyModelManager::SetModelSlot(int index, RPGrpModel* pModel, RPGrpModel* pAltModel) { + mSlotModels[index] = pModel; + mSlotAltModels[index] = pAltModel; +} + +/** + * @brief Resets scene variables to default + */ +void RPBowAlleyModelManager::ResetSceneParams() { + mSceneFlags = 1; + mCurrentSlotIndex = 0; + mBumperPosition = 0.0f; +} + +/** + * @brief Performs the first loop update on the scene models + * + * @param pMtx Transformation matrix + */ +inline void RPBowAlleyModelManager::UpdateModelsLoop1(nw4r::math::MTX34* pMtx) { + int i; + u32 bit = 1; + RPBowAlleyModelManager* pThis = this; + + for (i = 0; i < 4; i++) { + if (mSceneFlags & (bit << i)) { + nw4r::g3d::ScnObj* pScnObj = pThis->mModels[0]->GetScnObj(); + if (pScnObj != NULL) { + pScnObj->SetMtx(nw4r::g3d::ScnObj::MTX_LOCAL, pMtx); + } + pThis->mModels[0]->UpdateFrame(); + pThis->mModels[0]->Calc(); + pThis->mModels[0]->Entry(); + } + + pThis = (RPBowAlleyModelManager*)((u8*)pThis + 4); + } +} + +/** + * @brief Performs the second loop update on the scene models + * + * @param pMtx Transformation matrix + */ +inline void RPBowAlleyModelManager::UpdateModelsLoop2(nw4r::math::MTX34* pMtx) { + if (mSceneFlags & 1) { + const f32* pLaneXOffset = gLaneXOffsets; + + for (int i = 0; i < 4; i++) { + RPGrpModel* pCurrentModel = (i == mCurrentSlotIndex) ? mSlotAltModels[i] : mSlotModels[i]; + + pMtx->m[0][3] = *pLaneXOffset; + + nw4r::g3d::ScnObj* pScnObj = pCurrentModel->GetScnObj(); + if (pScnObj != NULL) { + pScnObj->SetMtx(nw4r::g3d::ScnObj::MTX_LOCAL, pMtx); + } + + pCurrentModel->UpdateFrame(); + pCurrentModel->Calc(); + pCurrentModel->Entry(); + + pLaneXOffset++; + } + } +} + +/** + * @brief Performs the third loop update on the scene models + * + * @param pMtx Transformation matrix + */ +inline void RPBowAlleyModelManager::UpdateModelsLoop3(nw4r::math::MTX34* pMtx) { + if (mSceneFlags & 2) { + int pass; + RPBowAlleyModelManager* pThis = this; + + for (pass = 0; pass < 2; pass++) { + f32 sign = (pass == 0) ? -mBumperPosition : mBumperPosition; + pMtx->m[0][3] = sign; + + nw4r::g3d::ScnObj* pScnObjA = pThis->mModels[4]->GetScnObj(); + if (pScnObjA != NULL) { + pScnObjA->SetMtx(nw4r::g3d::ScnObj::MTX_LOCAL, pMtx); + } + pThis->mModels[4]->UpdateFrame(); + pThis->mModels[4]->Calc(); + pThis->mModels[4]->Entry(); + + nw4r::math::MTX34 mirrorMtx = *pMtx; + mirrorMtx.m[1][0] *= -1.0f; + mirrorMtx.m[1][1] *= -1.0f; + mirrorMtx.m[1][2] *= -1.0f; + mirrorMtx.m[1][3] *= -1.0f; + + nw4r::g3d::ScnObj* pScnObjB = pThis->mModels[5]->GetScnObj(); + if (pScnObjB != NULL) { + pScnObjB->SetMtx(nw4r::g3d::ScnObj::MTX_LOCAL, &mirrorMtx); + } + pThis->mModels[5]->UpdateFrame(); + pThis->mModels[5]->Calc(); + pThis->mModels[5]->Entry(); + + pThis = (RPBowAlleyModelManager*)((u8*)pThis + 8); + } + } +} + +/** + * @brief Updates all models bound to the alley manager + */ +void RPBowAlleyModelManager::UpdateModels() { + nw4r::math::MTX34 mtx; + PSMTXIdentity(mtx.mtx); + + UpdateModelsLoop1(&mtx); + UpdateModelsLoop2(&mtx); + UpdateModelsLoop3(&mtx); +} diff --git a/src/Pack/RPSports/RPBowScene/RPBowBackgroundNpcManager.cpp b/src/Pack/RPSports/RPBowScene/RPBowBackgroundNpcManager.cpp index 80eabbf13..ecb4c9990 100644 --- a/src/Pack/RPSports/RPBowScene/RPBowBackgroundNpcManager.cpp +++ b/src/Pack/RPSports/RPBowScene/RPBowBackgroundNpcManager.cpp @@ -1,10 +1,6 @@ #include #include -#define nullptr 0 - -namespace Bowling { - // Forward declarations extern u8 lbl_804BF9F8; extern u32 lbl_804BF9F4; @@ -28,9 +24,9 @@ class RPGrpModelAccessor : public RPGrpModel { /** * @brief Unknown stub */ -void RPBowBackgroundNpcManager::fn_8034E96C() { - ; -} +// void RPBowBackgroundNpcManager::fn_8034E96C() { +// ; +// } /** * @brief Destructor @@ -72,12 +68,12 @@ void RPBowBackgroundNpcManager::InitializeConfig(int index) { * @brief Sets the model groups for the manager * * @param managerIndex Manager index - * @param pModelGroup0 First model group - * @param pModelGroup1 Second model group + * @param realKokeshi First model group + * @param reflectionKokeshi Second model group */ -void RPBowBackgroundNpcManager::SetModelGroups(int managerIndex, NpcModelGroup* pModelGroup0, NpcModelGroup* pModelGroup1) { - mModelGroups[managerIndex][0] = pModelGroup0; - mModelGroups[managerIndex][1] = pModelGroup1; +void RPBowBackgroundNpcManager::SetModelGroups(int managerIndex, RPSysKokeshi* realKokeshi, RPSysKokeshi* reflectionKokeshi) { + mModelGroups[managerIndex][0] = realKokeshi; + mModelGroups[managerIndex][1] = reflectionKokeshi; } /** @@ -96,8 +92,8 @@ void RPBowBackgroundNpcManager::Reset() { *(volatile int*)&mMovement.animationState = 0; for (int i = 0; i < 2; i++) { - NpcModelGroup* pGroup = mModelGroups[mModelGroupSet][i]; - RPGrpModelAnm* pAnimation = RPGrpModelAccessor::GetModelAnm(pGroup->mModelA8); + RPSysKokeshi* pGroup = mModelGroups[mModelGroupSet][i]; + RPGrpModelAnm* pAnimation = RPGrpModelAccessor::GetModelAnm(pGroup->GetBodyModel()); pAnimation->StartBlend(RPGrpModelAnm::Anm_Chr, 0, 60.0f, 0.0f); } @@ -107,10 +103,10 @@ void RPBowBackgroundNpcManager::Reset() { mMovement.stateTimer = -1; fn_8034CFC4(&mIdleState, 999, 0); - unk_0x94 = 0; + isVisible = 0; for (int j = 0; j < 600; j++) { - UpdateMovement(nullptr, nullptr); + UpdateMovement(NULL, NULL); } lbl_804BF9F8 = 0; @@ -173,8 +169,8 @@ void RPBowBackgroundNpcManager::UpdateMovement(nw4r::math::VEC3* pOutPosition, b 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); + RPSysKokeshi* pGroup = mModelGroups[mModelGroupSet][i]; + RPGrpModelAnm* pAnimation = RPGrpModelAccessor::GetModelAnm(pGroup->GetBodyModel()); pAnimation->StartBlend(RPGrpModelAnm::Anm_Chr, 1, 60.0f, 0.0f); } @@ -214,8 +210,8 @@ void RPBowBackgroundNpcManager::UpdateMovement(nw4r::math::VEC3* pOutPosition, b 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); + RPSysKokeshi* pGroup = mModelGroups[mModelGroupSet][i]; + RPGrpModelAnm* pAnimation = RPGrpModelAccessor::GetModelAnm(pGroup->GetBodyModel()); pAnimation->StartBlend(RPGrpModelAnm::Anm_Chr, 0, 60.0f, 0.0f); } @@ -243,23 +239,14 @@ void RPBowBackgroundNpcManager::UpdateMovement(nw4r::math::VEC3* pOutPosition, b mMovement.stateTimer++; - if (pOutPosition != nullptr) { + if (pOutPosition != NULL) { *pOutPosition = localVec; } - if (pOutStateFlag != nullptr) { + if (pOutStateFlag != NULL) { *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 */ @@ -270,7 +257,7 @@ void RPBowBackgroundNpcManager::Render() { UpdateMovement(&position, &stateFlag); - if (!stateFlag || !unk_0x94) { + if (!stateFlag || !isVisible) { return; } @@ -299,18 +286,18 @@ void RPBowBackgroundNpcManager::Render() { mtx3._13 += pConfig->mirroredModelZOffset; for (int i = 0; i < 2; i++) { - NpcModelGroup* pGroup = mModelGroups[mModelGroupSet][i]; + RPSysKokeshi* 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); + if (pGroup->GetBodyModel()->GetScnObj() != NULL) { + pGroup->GetBodyModel()->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(); + RPGrpModelAccessor::SetScale(pGroup->GetBodyModel(), scale); + pGroup->GetBodyModel()->UpdateFrame(); + pGroup->GetBodyModel()->Calc(); RPSysKokeshi* pKokeshi = reinterpret_cast(pGroup); pKokeshi->GetHeadJointMtx(reinterpret_cast(&headMtx)); @@ -326,35 +313,35 @@ void RPBowBackgroundNpcManager::Render() { nw4r::math::MTX34Mult(&headMtx, &headMtx, &flipMtx); } - if (GET_FACE(pGroup)->GetScnObj() != nullptr) { - GET_FACE(pGroup)->GetScnObj()->SetMtx(nw4r::g3d::ScnObj::MTX_LOCAL, &headMtx); + if (pGroup->GetNigaoeModel()->GetScnObj() != NULL) { + pGroup->GetNigaoeModel()->GetScnObj()->SetMtx(nw4r::g3d::ScnObj::MTX_LOCAL, &headMtx); } - RPGrpModelAccessor::SetScale(GET_FACE(pGroup), scale); - GET_FACE(pGroup)->UpdateFrame(); - GET_FACE(pGroup)->Calc(); + RPGrpModelAccessor::SetScale(pGroup->GetNigaoeModel(), scale); + pGroup->GetNigaoeModel()->UpdateFrame(); + pGroup->GetNigaoeModel()->Calc(); - if (GET_LHAND(pGroup)->GetScnObj() != nullptr) { - GET_LHAND(pGroup)->GetScnObj()->SetMtx(nw4r::g3d::ScnObj::MTX_LOCAL, &leftHandMtx); + if (pGroup->GetLeftHandModel()->GetScnObj() != NULL) { + pGroup->GetLeftHandModel()->GetScnObj()->SetMtx(nw4r::g3d::ScnObj::MTX_LOCAL, &leftHandMtx); } - RPGrpModelAccessor::SetScale(GET_LHAND(pGroup), scale); - GET_LHAND(pGroup)->UpdateFrame(); - GET_LHAND(pGroup)->Calc(); + RPGrpModelAccessor::SetScale(pGroup->GetLeftHandModel(), scale); + pGroup->GetLeftHandModel()->UpdateFrame(); + pGroup->GetLeftHandModel()->Calc(); - if (GET_RHAND(pGroup)->GetScnObj() != nullptr) { - GET_RHAND(pGroup)->GetScnObj()->SetMtx(nw4r::g3d::ScnObj::MTX_LOCAL, &rightHandMtx); + if (pGroup->GetRightHandModel()->GetScnObj() != NULL) { + pGroup->GetRightHandModel()->GetScnObj()->SetMtx(nw4r::g3d::ScnObj::MTX_LOCAL, &rightHandMtx); } - RPGrpModelAccessor::SetScale(GET_RHAND(pGroup), scale); - GET_RHAND(pGroup)->UpdateFrame(); - GET_RHAND(pGroup)->Calc(); + RPGrpModelAccessor::SetScale(pGroup->GetRightHandModel(), scale); + pGroup->GetRightHandModel()->UpdateFrame(); + pGroup->GetRightHandModel()->Calc(); if (i == 1 && !lbl_804BF9F8) { break; } - GET_BODY(pGroup)->Entry(); - GET_FACE(pGroup)->Entry(); - GET_LHAND(pGroup)->Entry(); - GET_RHAND(pGroup)->Entry(); + pGroup->GetBodyModel()->Entry(); + pGroup->GetNigaoeModel()->Entry(); + pGroup->GetLeftHandModel()->Entry(); + pGroup->GetRightHandModel()->Entry(); } } @@ -378,5 +365,3 @@ void RPBowBackgroundNpcManager::fn_8034DD0C() { void RPBowBackgroundNpcManager::fn_8034DD08() { ; } - -} // namespace Bowling diff --git a/src/Pack/RPSports/RPBowScene/RPBowBallHistoryEntry.cpp b/src/Pack/RPSports/RPBowScene/RPBowBallHistoryEntry.cpp new file mode 100644 index 000000000..9955b4b2f --- /dev/null +++ b/src/Pack/RPSports/RPBowScene/RPBowBallHistoryEntry.cpp @@ -0,0 +1,259 @@ +#include + +/** + * @brief Tests whether the active entry is null + * + * @return true if there is no active entry, false otherwise + */ +bool RPBowBallHistoryManager::IsActiveEntryNull() { + return pActiveEntry == NULL; +} + +/** + * @brief Constructor + */ +RPBowBallHistoryEntry::RPBowBallHistoryEntry() { + currentState[3] = 0.00000011920929f; + currentState[4] = 0.00000011920929f; + currentState[5] = 0.0f; + currentState[6] = 0.0f; +} + +/** + * @brief Destructor + */ +RPBowBallHistoryEntry::~RPBowBallHistoryEntry() {} + +/** + * @brief Constructor + */ +ThrowPosState_B::ThrowPosState_B() {} + +/** + * @brief Allocates the history arrays based on the requested count + * + * @param count Number of entries to allocate + */ +void RPBowBallHistoryManager::Allocate(u32 count) { + maxCount = count; + maxCount8 = count * 8; + + if (count != 0) { + limit20B = 100; + + pEntries = new RPBowBallHistoryEntry[count]; + pArray20A = new ThrowPosState_A[maxCount8]; + pArray20B = new ThrowPosState_B[limit20B]; + } else { + limit20B = 0; + pEntries = NULL; + pArray20A = NULL; + pArray20B = NULL; + } +} + +/** + * @brief Resets the manager indices and pointers + */ +void RPBowBallHistoryManager::Reset() { + currentIndex = 0; + pActiveEntry = NULL; + index20A = 0; + index20B = 0; +} + +/** + * @brief Records a new physics state into the history + * + * @param pSrc Source physics state + */ +void RPBowBallHistoryManager::RecordState(BallPhysicsState* pSrc) { + RPBowBallHistoryEntry *pDst; + BallPhysicsState **new_var; + u32 idx; + + if (pEntries == NULL) { + return; + } + + idx = currentIndex; + if (((s32)idx) >= ((s32)maxCount)) { + return; + } + currentIndex = idx + 1; + + pDst = &pEntries[idx]; + pActiveEntry = pDst; + + pDst->unk_0 = pSrc->unk_60; + + // this whole section just feels like one massive fakematch... + + pDst->currentState[0] = pSrc->currentState[0]; + pDst->currentState[1] = pSrc->currentState[1]; + pDst->currentState[2] = pSrc->currentState[2]; + pDst->currentState[3] = pSrc->currentState[3]; + pDst->currentState[4] = pSrc->currentState[4]; + pDst->currentState[5] = pSrc->currentState[5]; + pDst->currentState[6] = pSrc->currentState[6]; + pDst->currentState[7] = pSrc->currentState[7]; + pDst->currentState[8] = pSrc->currentState[8]; + pDst->currentState[9] = pSrc->currentState[9]; + pDst->currentState[10] = pSrc->currentState[10]; + pDst->currentState[11] = pSrc->currentState[11]; + pDst->currentState[12] = pSrc->currentState[12]; + pDst->currentState[13] = pSrc->currentState[13]; + pDst->currentState[14] = pSrc->currentState[14]; + pDst->currentState[15] = pSrc->currentState[15]; + pDst->currentState[16] = pSrc->currentState[16]; + pDst->currentState[17] = pSrc->currentState[17]; + pDst->currentState[18] = pSrc->currentState[18]; + pDst->currentState[19] = pSrc->currentState[19]; + pDst->currentState[20] = pSrc->currentState[20]; + pDst->currentState[21] = pSrc->currentState[21]; + pDst->currentState[22] = pSrc->currentState[22]; + pDst->currentState[23] = pSrc->currentState[23]; + pDst->currentState[24] = pSrc->currentState[24]; + pDst->currentState[25] = pSrc->currentState[25]; + pDst->currentState[26] = pSrc->currentState[26]; + pDst->currentState[27] = pSrc->currentState[27]; + pDst->currentState[28] = pSrc->currentState[28]; + pDst->currentState[29] = pSrc->currentState[29]; + pDst->currentState[30] = pSrc->currentState[30]; + pDst->currentState[31] = pSrc->currentState[31]; + pDst->currentState[32] = pSrc->currentState[32]; + pDst->currentState[33] = pSrc->currentState[33]; + pDst->currentState[34] = pSrc->currentState[34]; + pDst->currentState[35] = pSrc->currentState[35]; + pDst->currentState[36] = pSrc->currentState[36]; + pDst->currentState[37] = pSrc->currentState[37]; + + pDst->previousState[0] = pSrc->previousState[0]; + pDst->previousState[1] = pSrc->previousState[1]; + pDst->previousState[2] = pSrc->previousState[2]; + pDst->previousState[3] = pSrc->previousState[3]; + pDst->previousState[4] = pSrc->previousState[4]; + pDst->previousState[5] = pSrc->previousState[5]; + pDst->previousState[6] = pSrc->previousState[6]; + pDst->previousState[7] = pSrc->previousState[7]; + pDst->previousState[8] = pSrc->previousState[8]; + pDst->previousState[9] = pSrc->previousState[9]; + pDst->previousState[10] = pSrc->previousState[10]; + pDst->previousState[11] = pSrc->previousState[11]; + pDst->previousState[12] = pSrc->previousState[12]; + pDst->previousState[13] = pSrc->previousState[13]; + + // TODO: fakematch + pDst->previousState[14] = (*(new_var = &pSrc))->previousState[14]; + pDst->previousState[15] = (*new_var)->previousState[15]; + pDst->previousState[16] = (*new_var)->previousState[16]; + pDst->previousState[17] = (*new_var)->previousState[17]; + pDst->previousState[18] = (*new_var)->previousState[18]; + + pActiveEntry->throwCount = 0; + pActiveEntry->flag_114 = 0; +} + +/** + * @brief Sets rotational/positional vectors for the active entry + * + * @param pVec1 First vector + * @param pVec2 Second vector + * @param pVec3 Third vector + */ +void RPBowBallHistoryManager::SetVectors(nw4r::math::VEC3* pVec1, nw4r::math::VEC3* pVec2, nw4r::math::VEC3* pVec3) { + float f0, f1, f2; + if (!pActiveEntry) { + return; + } + + // TODO: fakematch + RPBowBallHistoryEntry* pTempEntry = pActiveEntry; + + f0 = pVec1->x; + f1 = pVec1->y; + pTempEntry->vec1.x = f0; + f0 = pVec1->z; + pTempEntry->vec1.y = f1; + f2 = pVec2->x; + pTempEntry->vec1.z = f0; + f1 = pVec2->y; + + pTempEntry = pActiveEntry; + + f0 = pVec2->z; + pTempEntry->vec2.x = f2; + f2 = pVec3->x; + pTempEntry->vec2.y = f1; + f1 = pVec3->y; + pTempEntry->vec2.z = f0; + f0 = pVec3->z; + + pTempEntry = pActiveEntry; + + pTempEntry->vec3.x = f2; + pTempEntry->vec3.y = f1; + pTempEntry->vec3.z = f0; + + pActiveEntry->flag_114 = 1; +} + +/** + * @brief Copies an array of position states into the manager's A array + * + * @param pSrcArr Source array + * @param count Number of elements to copy + */ +void RPBowBallHistoryManager::AddThrowPosStateA(ThrowPosState_A* pSrcArr, int count) { + if (!pActiveEntry) return; + + pActiveEntry->index20A = index20A; + pActiveEntry->throwCount = count; + + for (int i = 0; i < count; i++) { + if ((int)index20A < (int)maxCount8) { + pArray20A[index20A] = *pSrcArr; + index20A++; + } + pSrcArr++; + } +} + +/** + * @brief Appends a state into the manager's B array + * + * @param val1 Flag value + * @param pVec1 First vector + * @param pVec2 Second vector + */ +void RPBowBallHistoryManager::AddThrowPosStateB(u8 val1, nw4r::math::VEC3* pVec1, nw4r::math::VEC3* pVec2) { + float new_var; + if (pArray20B && (int)index20B < (int)limit20B) { + + ThrowPosState_B* pTarget = &pArray20B[index20B++]; + + f32 v1x = pVec1->x; + pTarget->flag_04 = val1; + + // TODO: fakematch + new_var = pVec1->y; + f32 v1y = new_var; + pTarget->vec1.x = v1x; + + f32 v1z = pVec1->z; + pTarget->vec1.y = v1y; + + f32 v2x = pVec2->x; + pTarget->vec1.z = v1z; + + f32 v2y = pVec2->y; + pTarget->vec2.x = v2x; + + f32 v2z = pVec2->z; + pTarget->vec2.y = v2y; + + pTarget->vec2.z = v2z; + + pTarget->field_00 = currentIndex; + } +} diff --git a/src/Pack/RPSports/RPBowScene/RPBowBallReturnRack.cpp b/src/Pack/RPSports/RPBowScene/RPBowBallReturnRack.cpp index 2cb12a4a8..56bd6dfeb 100644 --- a/src/Pack/RPSports/RPBowScene/RPBowBallReturnRack.cpp +++ b/src/Pack/RPSports/RPBowScene/RPBowBallReturnRack.cpp @@ -1,8 +1,6 @@ #include #include -namespace Bowling { - // Extern Functions int fn_801C3490(int arg0, float arg1, void* pArg2); u32 fn_801C389C(RPGrpModel* pModel, int arg1, int arg2); @@ -272,5 +270,3 @@ void RPBowBallReturnRack::UpdateBallReturnRack(s32 index) { } } } - -} // namespace Bowling diff --git a/src/Pack/RPSports/RPBowScene/RPBowGlobalLaneManager.cpp b/src/Pack/RPSports/RPBowScene/RPBowGlobalLaneManager.cpp index c54a92b12..d163b53fb 100644 --- a/src/Pack/RPSports/RPBowScene/RPBowGlobalLaneManager.cpp +++ b/src/Pack/RPSports/RPBowScene/RPBowGlobalLaneManager.cpp @@ -1,7 +1,5 @@ #include -namespace Bowling { - /** * @brief Pin target offsets * @details Controls where the triangle of pins is set up. @@ -17,16 +15,23 @@ float gLaneXOffsets[8] = { 0 }; +extern void* lbl_803CA5F0[]; + // 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 Creates and initializes the seven lane contexts + * + * @param objectManager Scene object manager + */ +void RPBowGlobalLaneManager::InitializeLaneContexts(RPBowSceneObjectManager* objectManager) { + for (int i = 0; i < 7; i++) { + LaneContext* ctx = new LaneContext(); + pLanes[i] = ctx; + ctx->fn_80327858(0, 10, gLaneXOffsets[i], objectManager->entities.setters[i]); + } +} /** * @brief Tests whether the ball's X position falls inside the hit-box radius of any lane boundary @@ -49,7 +54,7 @@ bool CheckBallLaneIntersection(float* pBallXPos, float radius) { */ void RPBowGlobalLaneManager::InitializeBallManagerLanes() { for (int i = 0; i < 7; i++) { - fn_803277B4(pLanes[i]); + pLanes[i]->fn_803277B4(); } } @@ -79,8 +84,8 @@ void RPBowGlobalLaneManager::ResetLanePinsAndAnimations() { status.pinBits[0] = -1; status.pinCount = 10; - fn_80327330(pLane, &status); - ResetPinSetterState(pLanes[i], 0); + pLane->fn_80327330(&status); + pLanes[i]->ResetPinSetterState(0); } field_0x21 = 0; } @@ -104,7 +109,7 @@ 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]); + pLanes[i]->fn_80327218(); } } } @@ -114,7 +119,7 @@ void RPBowGlobalLaneManager::UpdateBallsPhysics() { */ void RPBowGlobalLaneManager::TickNpcLanes() { for (int i = 0; i < 7; i++) { - fn_80325154(pLanes[i]); + pLanes[i]->fn_80325154(); } } @@ -123,16 +128,16 @@ void RPBowGlobalLaneManager::TickNpcLanes() { * * @param val Unknown integer value * @param pObj Pointer to an object - * @param pSomeMgr Manager object + * @param pObjectManager Manager object * @param isPlayerTurn Indicates if it is currently the player's turn */ -void RPBowGlobalLaneManager::UpdateLaneItems(int val, void* pObj, SomeUnkManager0* pSomeMgr, bool isPlayerTurn) { +void RPBowGlobalLaneManager::UpdateLaneItems(RPBowCameraTransform* transform, CameraProjection* pObj, RPBowSceneObjectManager* pObjectManager, bool isPlayerTurn) { if (isInitialized == 0) return; - nw4r::math::MTX34* pResultMtx = fn_80316A48(pSomeMgr, pObj, val); + nw4r::math::MTX34* pResultMtx = pObjectManager->ProcessCamera(pObj, transform); for (int i = 0; i < 7; i++) { - void* pArrEntry = pSomeMgr->arr[i]; + RPBowRegularPinManager* pinManager = pObjectManager->entities.pinManagers[i]; int validCount = 0; for (int j = 0; j < 10; j++) { @@ -160,20 +165,21 @@ void RPBowGlobalLaneManager::UpdateLaneItems(int val, void* pObj, SomeUnkManager 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; + // Same issue occurs in fn_8034C230 + f32 t23 = pBody->state.position.z; + f32 t22 = pBody->state.basisZ.z; + f32 t21 = pBody->state.basisZ.y; + f32 t20 = pBody->state.basisZ.x; + f32 t13 = pBody->state.position.y; + f32 t12 = pBody->state.basisY.z; + f32 t11 = pBody->state.basisY.y; + f32 t10 = pBody->state.basisY.x; + f32 t03 = pBody->state.position.x; + f32 t02 = pBody->state.basisX.z; + f32 t01 = pBody->state.basisX.y; + // f32 t00 = pBody->state.basisX.x; + + mtx._00 = pBody->state.basisX.x; mtx._01 = t01; mtx._02 = t02; mtx._03 = t03; @@ -187,18 +193,16 @@ void RPBowGlobalLaneManager::UpdateLaneItems(int val, void* pObj, SomeUnkManager mtx._23 = t23; } - bool flag = false; + u32 flag = 0; if (i == 0 && isPlayerTurn != 0) { - flag = true; + flag = 1; } - pLanes[i]->VF_0x14(); - - fn_8034EADC(pArrEntry, validCount, pResultMtx, pMtx, flag); + pinManager->CalculatePinTransforms(validCount, pLanes[i]->VF_0x14(), pResultMtx, pMtx, (nw4r::math::MTX34*)flag); validCount++; } } - fn_8034E974(pArrEntry, validCount); + pinManager->HideExcessPins(validCount); } } @@ -206,12 +210,12 @@ void RPBowGlobalLaneManager::UpdateLaneItems(int val, void* pObj, SomeUnkManager * @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 + * @param pObjectManager Scene object manager for balls */ -void RPBowGlobalLaneManager::UpdateBallsMdl(SceneObjectManager* pBallMgr) { +void RPBowGlobalLaneManager::UpdateBallsMdl(RPBowSceneObjectManager* pObjectManager) { for (int i = 0; i < 7; i++) { LaneContext* pLane = pLanes[i]; - RPBowActiveBall* pBall = pBallMgr->entities.balls[i]; + RPBowActiveBall* pBall = pObjectManager->entities.balls[i]; nw4r::math::MTX34 mtx = pLane->throwContext.ballMtx; if (mtx._23 < -210.0f) { @@ -223,5 +227,3 @@ void RPBowGlobalLaneManager::UpdateBallsMdl(SceneObjectManager* pBallMgr) { pBall->field_0x74 = field_110; } } - -} // namespace Bowling diff --git a/src/Pack/RPSports/RPBowScene/RPBowLayoutManager.cpp b/src/Pack/RPSports/RPBowScene/RPBowLayoutManager.cpp new file mode 100644 index 000000000..650792f88 --- /dev/null +++ b/src/Pack/RPSports/RPBowScene/RPBowLayoutManager.cpp @@ -0,0 +1,675 @@ +#include +#include + +// -------------------- + +/** + * @brief Initializes the guidance layout + * + * @param pAcc Layout resource accessor + * @param pMsg System message configuration + */ +void RPBowGuidanceLayout::Init(RPSysLytResAccessor* pAcc, RPSysMessage* pMsg) { + mpMessage = pMsg; + + mpLayout = RPSysLayout::create(NULL, pAcc, "bwgText_00.brlyt"); + + mpAnm1 = mpLayout->createAnmObj(NULL, pAcc, "bwgText_00_in_00.brlan"); + mpAnm2 = mpLayout->createAnmObj(NULL, pAcc, "bwgText_00_out_00.brlan"); + + mpPane1 = mpLayout->findPane("P_tutorial_01"); + mpTextBox1 = mpLayout->findTextBox("T_exp_00"); + + mAnimationState = 0; +} + +/** + * @brief Resets the layout and unbinds objects + */ +void RPBowGuidanceLayout::Reset() { + mpLayout->reset(); + mpLayout->unbindAllAnmObj(); + mAnimationState = 0; + mFlag28 = 1; +} + +// void fn_80352ED8() + +/** + * @brief Draws the layout + */ +void RPBowGuidanceLayout::Draw() { + mpLayout->draw(); +} + +/** + * @brief Tests whether the layout animation has finished + * + * @return True if animation state is 0, false otherwise + */ +bool RPBowGuidanceLayout::IsFinished() const { + return mAnimationState == 0; +} + +// -------------------- + +/** + * @brief Initializes the event text layout + * + * @param pAcc Layout resource accessor + * @param pMsg System message configuration + */ +void RPBowEventTextLayout::Init(RPSysLytResAccessor* pAcc, RPSysMessage* pMsg) { + mpMessage = pMsg; + + mpLayout = RPSysLayout::create(NULL, pAcc, "bwgText_01.brlyt"); + + mpTextBoxes[0][0] = mpLayout->findTextBox("T_text_00"); + mpTextBoxes[0][1] = mpLayout->findTextBox("T_text_01"); + mpTextBoxes[1][0] = mpLayout->findTextBox("T_textS_00"); + mpTextBoxes[1][1] = mpLayout->findTextBox("T_textS_01"); + + mpAnm1 = mpLayout->createAnmObj(NULL, pAcc, "bwgText_01_in_00.brlan"); + mpAnm2 = mpLayout->createAnmObj(NULL, pAcc, "bwgText_01_in_00.brlan"); + + mpPane1 = mpLayout->findPane("N_text_00"); + mpPane2 = mpLayout->findPane("N_textS_00"); + + mpTextBox5 = mpLayout->findTextBox("T_double_00"); + mpTextBox6 = mpLayout->findTextBox("T_double_01"); + + mpAnm3 = mpLayout->createAnmObj(NULL, pAcc, "bwgText_01_in_00.brlan"); + + mpPane3 = mpLayout->findPane("N_double_00"); +} + +/** + * @brief Resets the layout and unbinds objects + */ +void RPBowEventTextLayout::Reset() { + mpLayout->reset(); + mAnimationState = 0; + mpLayout->unbindAllAnmObj(); + mField48 = 0; +} + +/** + * @brief Updates the event text animation each frame + * + * @param pContext Bowling scene context + */ +void RPBowEventTextLayout::Update(SceneContext* pContext) { + if (mAnimationState == 0 || mAnimationState == 3) { + if (unk04) { + mpLayout->unbindAllAnmObj(); + mpLayout->bindAnmObjToPane(mpAnm1, mpPane1, true); + mpLayout->bindAnmObjToPane(mpAnm2, mpPane2, true); + + RPSysLytAnmObj* pTempAnm1 = mpAnm1; + bool isC55 = pContext->mUnkC55; + + pTempAnm1->setFrame(pTempAnm1->getStartFrame()); + pTempAnm1->setFlags(0); + pTempAnm1->setEnabled(1); + + RPSysLytAnmObj* pTempAnm2 = mpAnm2; + pTempAnm2->setFrame(pTempAnm2->getStartFrame()); + pTempAnm2->setFlags(0); + pTempAnm2->setEnabled(1); + + if (isC55) { + mpLayout->bindAnmObjToPane(mpAnm3, mpPane3, true); + + RPSysLytAnmObj* pTempAnm3 = mpAnm3; + pTempAnm3->setFrame(pTempAnm3->getStartFrame()); + pTempAnm3->setFlags(0); + pTempAnm3->setEnabled(1); + + mpPane3->SetVisible(true); + } else { + mpPane3->SetVisible(false); + } + + mAnimationState = 1; + mField48 = 0; + } + } + + if (mAnimationState == 1 || mAnimationState == 2) { + if (!unk04) { + mAnimationState = 0; + } + } + + if (mAnimationState == 1) { + if (mpAnm1->isFinished() && mpAnm2->isFinished()) { + mAnimationState = 2; + } + } + + s32 fieldC3C = pContext->field_0xC3C; + bool bActive; + + if (fieldC3C == -1) { + bActive = true; + mpTextBoxes[1][0]->setMessage(mpMessage, 0x659C, 0, 0); + mpTextBoxes[1][1]->setMessage(mpMessage, 0x659C, 0, 0); + } else { + bActive = true; + s32 pluralOffset = !RPSysStringUtility::IsSingular(fieldC3C) + 2; + + wchar_t buffer[32]; + RPSysStringUtility::GetStringHalfSizeNumber(fieldC3C, buffer, 32, false); + + mpTextBoxes[1][0]->setMessage(mpMessage, 0x659A, pluralOffset, 1, buffer); + mpTextBoxes[1][1]->setMessage(mpMessage, 0x659A, pluralOffset, 1, buffer); + } + + mpTextBoxes[bActive][0]->SetVisible(true); + mpTextBoxes[bActive][1]->SetVisible(true); + mpTextBoxes[!bActive][0]->SetVisible(false); + mpTextBoxes[!bActive][1]->SetVisible(false); + + mField48++; + mpLayout->calc(); +} + +/** + * @brief Draws the layout + */ +void RPBowEventTextLayout::Draw() { + mpLayout->draw(); +} + +/** + * @brief Tests whether the layout animation has finished + * + * @return True if animation state is 0, false otherwise + */ +bool RPBowEventTextLayout::IsFinished() const { + return mAnimationState == 0; +} + +// -------------------- + +/** + * @brief Initializes the training stage layout + * + * @param pAcc Layout resource accessor + * @param pMsg System message configuration + */ +void RPBowTrainingStageLayout::Init(RPSysLytResAccessor* pAcc, RPSysMessage* pMsg) { + mpMessage = pMsg; + + mpLayout = RPSysLayout::create(NULL, pAcc, "bwgText_02.brlyt"); + mAnimationState = 0; + + mpTextBox1 = mpLayout->findTextBox("T_stage_00"); + mpTextBox2 = mpLayout->findTextBox("T_stage_01"); +} + +/** + * @brief Resets the layout and unbinds objects + */ +void RPBowTrainingStageLayout::Reset() { + mpLayout->reset(); + mpLayout->unbindAllAnmObj(); + mAnimationState = 0; +} + +/** + * @brief Updates the training stage animation each frame + * + * @param pContext Bowling scene context + */ +void RPBowTrainingStageLayout::Update(SceneContext* pContext) { + if (mAnimationState == 0 || mAnimationState == 3) { + if (unk04) { + mpLayout->startDynAnmIn(0); + mAnimationState = 1; + } + } + + if (mAnimationState == 1 || mAnimationState == 2) { + if (!unk04) { + mpLayout->startDynAnmOut(0); + mAnimationState = 3; + } + } + + if (mAnimationState == 1) { + if (mpLayout->isFinishedDynAnmIn()) { + mAnimationState = 2; + } + } + + if (mAnimationState == 3) { + if (mpLayout->isFinishedDynAnmOut()) { + mAnimationState = 0; + } + } + + wchar_t buffer[32]; + RPSysStringUtility::GetStringHalfSizeNumber(pContext->field_0xC38 + 1, buffer, 32, false); + + mpTextBox1->setMessage(mpMessage, 0x65F4, 0, 1, buffer); + mpTextBox2->setMessage(mpMessage, 0x65F4, 0, 1, buffer); + + mpLayout->calc(); +} + +/** + * @brief Draws the layout + */ +void RPBowTrainingStageLayout::Draw() { + mpLayout->draw(); +} + +/** + * @brief Tests whether the layout animation has finished + * + * @return True if animation state is 0, false otherwise + */ +bool RPBowTrainingStageLayout::IsFinished() const { + return mAnimationState == 0; +} + +// -------------------- + +/** + * @brief Initializes the Power Throws stage layout + * + * @param pAcc Layout resource accessor + * @param pMsg System message configuration + */ +void RPBowPowerThrowsStageLayout::Init(RPSysLytResAccessor* pAcc, RPSysMessage* pMsg) { + mpMessage = pMsg; + + mpLayout = RPSysLayout::create(NULL, pAcc, "bwgText_03.brlyt"); + mAnimationState = 0; + + mpTextBox1 = mpLayout->findTextBox("T_stage_00"); + mpTextBox2 = mpLayout->findTextBox("T_stage_01"); + mpTextBox3 = mpLayout->findTextBox("T_pin_00"); + mpTextBox4 = mpLayout->findTextBox("T_pin_01"); +} + +/** + * @brief Resets the layout and unbinds objects + */ +void RPBowPowerThrowsStageLayout::Reset() { + mpLayout->reset(); + mpLayout->unbindAllAnmObj(); + mAnimationState = 0; +} + +/** + * @brief Updates the Power Throws stage animation each frame + * + * @param pContext Bowling scene context + */ +void RPBowPowerThrowsStageLayout::Update(SceneContext* pContext) { + if (mAnimationState == 0 || mAnimationState == 3) { + if (unk04) { + mpLayout->startDynAnmIn(0); + mAnimationState = 1; + } + } + + if (mAnimationState == 1 || mAnimationState == 2) { + if (!unk04) { + mpLayout->startDynAnmOut(0); + mAnimationState = 3; + } + } + + if (mAnimationState == 1) { + if (mpLayout->isFinishedDynAnmIn()) { + mAnimationState = 2; + } + } + + if (mAnimationState == 3) { + if (mpLayout->isFinishedDynAnmOut()) { + mAnimationState = 0; + } + } + + wchar_t buffer1[32]; + RPSysStringUtility::GetStringHalfSizeNumber(pContext->field_0xC38 + 1, buffer1, 32, false); + mpTextBox1->setMessage(mpMessage, 0x65F6, 0, 1, buffer1); + mpTextBox2->setMessage(mpMessage, 0x65F6, 0, 1, buffer1); + + s32 max = pContext->field_0xC38 + 4; + s32 sum = 0; + for (s32 i = 0; i <= max; i++) { + sum += i; + } + + wchar_t buffer2[32]; + RPSysStringUtility::GetStringHalfSizeNumber(sum, buffer2, 32, false); + mpTextBox3->setMessage(mpMessage, 0x65F5, 0, 1, buffer2); + mpTextBox4->setMessage(mpMessage, 0x65F5, 0, 1, buffer2); + + mpLayout->calc(); +} + +/** + * @brief Draws the layout + */ +void RPBowPowerThrowsStageLayout::Draw() { + mpLayout->draw(); +} + +/** + * @brief Tests whether the layout animation has finished + * + * @return True if animation state is 0, false otherwise + */ +bool RPBowPowerThrowsStageLayout::IsFinished() const { + return mAnimationState == 0; +} + +// ----------------- + +/** + * @brief Initializes the Game Over layout + * + * @param pAcc Layout resource accessor + * @param pMsg System message configuration + */ +void RPBowGameOverLayout::Init(RPSysLytResAccessor* pAcc, RPSysMessage* pMsg) { + mpLayout = RPSysLayout::create(NULL, pAcc, "bwgText_04.brlyt"); + mpUnkAnim = mpLayout->createAnmObj(NULL, pAcc, "bwgText_04_inOut_00.brlan"); + + RPSysLytTextBox* pTb1 = mpLayout->findTextBox("T_game_00"); + RPSysLytTextBox* pTb2 = mpLayout->findTextBox("T_game_01"); + + pTb1->setMessage(pMsg, 0x65C2, 0, 0); + pTb2->setMessage(pMsg, 0x65C2, 0, 0); + + mAnimationState = 0; +} + +/** + * @brief Resets the layout and unbinds objects + */ +void RPBowGameOverLayout::Reset() { + mpLayout->reset(); + mpLayout->unbindAllAnmObj(); + mAnimationState = 0; +} + +/** + * @brief Updates the Game Over layout animation each frame + */ +void RPBowGameOverLayout::Update() { + if (mAnimationState == 0) { + if (unk04) { + mpLayout->unbindAllAnmObj(); + mpLayout->bindAnmObj(mpUnkAnim); + + RPSysLytAnmObj* pTempObj = mpUnkAnim; + pTempObj->setFrame(pTempObj->getStartFrame()); + pTempObj->setFlags(0); + pTempObj->setEnabled(1); + + mAnimationState = 1; + } + } + + if (mAnimationState == 1) { + if (mpUnkAnim->isFinished()) { + mpLayout->unbindAllAnmObj(); + mAnimationState = 0; + } + } + + mpLayout->calc(); +} + +/** + * @brief Draws the layout + */ +void RPBowGameOverLayout::Draw() { + mpLayout->draw(); +} + +/** + * @brief Tests whether the layout animation has finished + * + * @return True if animation state is 0, false otherwise + */ +bool RPBowGameOverLayout::IsFinished() const { + return mAnimationState == 0; +} + +// ------------------------ + +/** + * @brief Initializes the strike text layout + * + * @param pAccessor Layout resource accessor + * @param pMsg System message configuration + */ +void RPBowStrikeLayout::Init(RPSysLytResAccessor* pAccessor, RPSysMessage* pMsg) { + mpMessage = pMsg; + + mpLayout = RPSysLayout::create(NULL, pAccessor, "bwgStrike_00.brlyt"); + + mpStrikeAnim = mpLayout->createAnmObj(NULL, pAccessor, "bwgStrike_00_inOut_00.brlan"); + + mpTextBox1 = mpLayout->findTextBox("T_strike_00"); + mpTextBox2 = mpLayout->findTextBox("T_strike_01"); + + mAnimationState = 0; +} + +/** + * @brief Resets the layout and unbinds objects + */ +void RPBowStrikeLayout::Reset() { + mpLayout->reset(); + mpLayout->unbindAllAnmObj(); + mAnimationState = 0; +} + +/** + * @brief Updates the strike layout animation each frame + * + * @param pContext Bowling scene context + */ +void RPBowStrikeLayout::Update(SceneContext* pContext) { + if (pContext->field_0xC58 >= 2) { + if (mAnimationState == 0) { + if (unk04) { + mpLayout->unbindAllAnmObj(); + mpLayout->bindAnmObj(mpStrikeAnim); + + RPSysLytAnmObj* pTempObj = mpStrikeAnim; + pTempObj->setFrame(pTempObj->getStartFrame()); + pTempObj->setFlags(0); + pTempObj->setEnabled(1); + + mAnimationState = 1; + } + } + + if (mAnimationState == 1) { + if (mpStrikeAnim->isFinished()) { + mpLayout->unbindAllAnmObj(); + mAnimationState = 0; + } + } + + s32 msgArg = pContext->field_0xC58 - 2; + + mpTextBox1->setMessage(mpMessage, 0x659B, msgArg, 0); + mpTextBox2->setMessage(mpMessage, 0x659B, msgArg, 0); + + mpLayout->calc(); + } +} + +/** + * @brief Draws the layout + */ +void RPBowStrikeLayout::Draw() { + mpLayout->draw(); +} + +/** + * @brief Tests whether the layout animation has finished + * + * @return True if animation state is 0, false otherwise + */ +bool RPBowStrikeLayout::IsFinished() const { + return mAnimationState == 0; +} + +// ------------------ + +// Sub-class instantiated in the manager +struct UnkTutorialHelper { + u8 data[0x24]; +}; + +extern "C" { + bool fn_801CFCD4(UnkTutorialHelper*); + bool fn_801CFCC4(UnkTutorialHelper*); + void fn_801CFFE8(UnkTutorialHelper*); + void fn_801CFCE8(UnkTutorialHelper*); + void fn_801CFD64(UnkTutorialHelper*, nw4r::lyt::Pane*, f32, f32); + void fn_801CFEA8(UnkTutorialHelper*); + void fn_801D0044(UnkTutorialHelper*, void*, int); + void fn_801CFE90(UnkTutorialHelper*); +} + +/** + * @brief Initializes the bowling tutorial layout and its components + * @details Creates the layout showing the "Swing your arm while holding down B, + * and release it to roll the ball." message and accompanying button animation. + * + * @param pAcc Layout resource accessor + * @param pMsg System message configuration + */ +void RPBowTutorialLayout::Init(RPSysLytResAccessor* pAcc, RPSysMessage* pMsg) { + mpMessage = pMsg; + + mpLayout = RPSysLayout::create(NULL, pAcc, "bwgTutorial_00.brlyt"); + mpObj1 = mpLayout->createAnmObj(NULL, pAcc, "bwgTutorial_00_in_00.brlan"); + mpObj2 = mpLayout->createAnmObj(NULL, pAcc, "bwgTutorial_00_out_00.brlan"); + mpObj3 = mpLayout->createAnmObj(NULL, pAcc, "bwgTutorial_00_loop_00.brlan"); + mpPane1 = mpLayout->findPane("N_AButton_00"); + mpPane2 = mpLayout->findPane("N_tutorial_01"); + + RPSysLytTextBox* pTb = mpLayout->findTextBox("T_tutorial_00"); + pTb->setMessage(pMsg, 0x6592, 0, 0); + + mAnimationState = 0; + mpTutorialHelper = new UnkTutorialHelper(); + + void* pField30 = *(void**)((u8*)RP_GET_INSTANCE(RPSysResourceManager) + 0x30); + fn_801D0044((UnkTutorialHelper*)mpTutorialHelper, pField30, 0); +} + +/** + * @brief Resets the tutorial layout to its initial state + */ +void RPBowTutorialLayout::Reset() { + mpLayout->reset(); + mpLayout->unbindAllAnmObj(); + mAnimationState = 0; + fn_801CFFE8((UnkTutorialHelper*)mpTutorialHelper); +} + +/** + * @brief Updates the tutorial animation each frame + */ +void RPBowTutorialLayout::Update() { + if (mAnimationState == 0 || mAnimationState == 3) { + if (unk04) { + mpLayout->reset(); + mpLayout->unbindAllAnmObj(); + mpLayout->bindAnmObj(mpObj1); + + RPSysLytAnmObj* pIn1 = mpObj1; + s16 len1 = pIn1->getStartFrame(); + pIn1->setFrame(len1); + pIn1->setFlags(0); + pIn1->setEnabled(1); + + mAnimationState = 1; + + mpLayout->bindAnmObjToPane(mpObj3, mpPane2, true); + + RPSysLytAnmObj* pIn3 = mpObj3; + s16 len3 = pIn3->getStartFrame(); + pIn3->setFrame(len3); + pIn3->setFlags(0); + pIn3->setEnabled(1); + + fn_801CFFE8((UnkTutorialHelper*)mpTutorialHelper); + fn_801CFD64((UnkTutorialHelper*)mpTutorialHelper, mpPane1, 0.0f, 0.0f); + } + } + + if (mAnimationState == 1 || mAnimationState == 2) { + if (!unk04) { + if (fn_801CFCD4((UnkTutorialHelper*)mpTutorialHelper)) { + mpLayout->unbindAllAnmObj(); + mpLayout->bindAnmObj(mpObj2); + + RPSysLytAnmObj* pIn2 = mpObj2; + s16 len2 = pIn2->getStartFrame(); + pIn2->setFrame(len2); + pIn2->setFlags(0); + pIn2->setEnabled(1); + + mAnimationState = 3; + fn_801CFCE8((UnkTutorialHelper*)mpTutorialHelper); + } + } + } + + if (mAnimationState == 1) { + if (mpObj1->isFinished()) { + mAnimationState = 2; + } + } + + if (mAnimationState == 3) { + if (mpObj2->isFinished()) { + if (fn_801CFCC4((UnkTutorialHelper*)mpTutorialHelper)) { + mAnimationState = 0; + } + } + } + + // Controls the speed of the tutorial animation. + if (mAnimationState == 2) { + mpObj3->setRate(1.0f); + } else { + mpObj3->setRate(0.0f); + } + + mpLayout->calc(); + fn_801CFEA8((UnkTutorialHelper*)mpTutorialHelper); +} + +/** + * @brief Draws the layout + */ +void RPBowTutorialLayout::Draw() { + mpLayout->draw(); + fn_801CFE90((UnkTutorialHelper*)mpTutorialHelper); +} + +/** + * @brief Tests whether the layout animation has finished + * + * @return True if animation state is 0, false otherwise + */ +bool RPBowTutorialLayout::IsFinished() const { + return mAnimationState == 0; +} diff --git a/src/Pack/RPSports/RPBowScene/RPBowManagerContext.cpp b/src/Pack/RPSports/RPBowScene/RPBowManagerContext.cpp index 02bd481d7..f276e24a7 100644 --- a/src/Pack/RPSports/RPBowScene/RPBowManagerContext.cpp +++ b/src/Pack/RPSports/RPBowScene/RPBowManagerContext.cpp @@ -1,8 +1,6 @@ #include #include -namespace Bowling { - struct WeightedLanes { u8 data[15]; }; @@ -30,7 +28,7 @@ void RPBowManagerContext::Initialize() { * @param pLaneManager Global lane manager instance * @param pSceneObjectManager Scene object manager instance */ -void RPBowManagerContext::LinkNpcLanes(RPBowGlobalLaneManager* pLaneManager, SceneObjectManager* pSceneObjectManager) { +void RPBowManagerContext::LinkNpcLanes(RPBowGlobalLaneManager* pLaneManager, RPBowSceneObjectManager* pSceneObjectManager) { for (int i = 0; i < 6; i++) { const int sBallReturnMapping[] = { 0, 1, 0, 3, 2, 3 }; @@ -103,5 +101,3 @@ void RPBowManagerContext::DebugPrintStates() { } } } - -} // namespace Bowling diff --git a/src/Pack/RPSports/RPBowScene/RPBowMotionBlur.cpp b/src/Pack/RPSports/RPBowScene/RPBowMotionBlur.cpp index 5337a8c93..e0d62d1c7 100644 --- a/src/Pack/RPSports/RPBowScene/RPBowMotionBlur.cpp +++ b/src/Pack/RPSports/RPBowScene/RPBowMotionBlur.cpp @@ -1,10 +1,15 @@ #include -namespace Bowling { - // Appears to check frustum culling extern bool fn_801C3490(void* pCullingCtx, const nw4r::math::VEC3* pos, f32 radius); +/** + * @brief Unknown stub + */ +void RPBowMotionBlur::fn_8034D4F0() { + ; +} + /** * @brief Destructor */ @@ -106,5 +111,3 @@ void RPBowMotionBlur::DrawBlur(void* pCullingCtx) { models[i].pReflectionModel->Entry(); } } - -} // namespace Bowling diff --git a/src/Pack/RPSports/RPBowScene/RPBowNormalPinLayout.cpp b/src/Pack/RPSports/RPBowScene/RPBowNormalPinLayout.cpp new file mode 100644 index 000000000..1532cf91c --- /dev/null +++ b/src/Pack/RPSports/RPBowScene/RPBowNormalPinLayout.cpp @@ -0,0 +1,121 @@ +#include + +extern nw4r::math::VEC2 lbl_803CAB88[2][2]; + +/** + * @brief Destructor + */ +RPBowNormalPinLayout::~RPBowNormalPinLayout() {} + +/** + * @brief Initializes the normal pin layout + * + * @param pAcc Layout resource accessor + */ +void RPBowNormalPinLayout::Init(RPSysLytResAccessor* pAcc) { + mpLayout = RPSysLayout::create(NULL, pAcc, "pin_00.brlyt"); + mpRootPane = mpLayout->findPane("RootPane"); + + char buf[64]; + + for (int i = 0; i < 10; i++) { + sprintf(buf, "N_pin%02d_00", i + 1); + mpPinPanes[i] = mpLayout->findPane(buf); + } + + mAnimationState = 0; +} + +/** + * @brief Resets the layout and animation state + */ +void RPBowNormalPinLayout::Reset() { + mpLayout->reset(); + mAnimationState = 0; +} + +/** + * @brief Updates the pin layout logic and animations for the current frame + * + * @param pContext Bowling scene context + */ +void RPBowNormalPinLayout::Update(SceneContext* pContext) { + int typeIdx = pContext->mUnkC1C; + + if (pContext->mUnkC44 != 0) { + typeIdx = 0; + } + + bool revAnm = false; + if (typeIdx != 0) { + if (pContext->mUnk34 != 0) { + revAnm = true; + } + } + + int playerIdx = -pContext->mUnkC34; + mpLayout->reverseAnmHDirection(revAnm); + + if (mAnimationState == 0 || mAnimationState == 3) { + if (mUnk4) { + mpLayout->startDynAnmIn((short)playerIdx); + mAnimationState = 1; + } + } + + if (mAnimationState == 1 || mAnimationState == 2) { + if (!mUnk4) { + mpLayout->startDynAnmOut((short)playerIdx); + mAnimationState = 3; + } + } + + if (mAnimationState == 1) { + if (mpLayout->isFinishedDynAnmIn()) { + mAnimationState = 2; + } + } + + if (mAnimationState == 3) { + if (mpLayout->isFinishedDynAnmOut()) { + mAnimationState = 0; + } + } + + u32* pPinBits = pContext->pinStatus.pinBits; + for (int i = 0; i < 10; i++) { + if (pPinBits[i / 30] & (1 << (i % 30))) { + mpPinPanes[i]->SetVisible(true); + } else { + mpPinPanes[i]->SetVisible(false); + } + } + + int tvIdx = (EGG::Screen::GetTVMode() != EGG::Screen::TV_MODE_STD); + f32* pFloats = (f32*)lbl_803CAB88[tvIdx]; + + f32 x = pFloats[typeIdx * 2]; + f32 y = pFloats[typeIdx * 2 + 1]; + + nw4r::math::VEC2 pos(x, y); + nw4r::math::VEC3 trans(pos.x, pos.y, 0.0f); + + mpRootPane->SetTranslate(trans); + mpLayout->calc(); +} + +/** + * @brief Draws the layout + */ +void RPBowNormalPinLayout::Draw() { + mpLayout->draw(); +} + +/** + * @brief Tests whether the layout animation has finished + * + * @return True if animation state is 0, false otherwise + */ +bool RPBowNormalPinLayout::IsFinished() const { + return mAnimationState == 0; +} diff --git a/src/Pack/RPSports/RPBowScene/RPBowNpcManager.cpp b/src/Pack/RPSports/RPBowScene/RPBowNpcManager.cpp index 417dbcb33..48b9d0052 100644 --- a/src/Pack/RPSports/RPBowScene/RPBowNpcManager.cpp +++ b/src/Pack/RPSports/RPBowScene/RPBowNpcManager.cpp @@ -2,11 +2,22 @@ extern "C" int rand(); -namespace Bowling { +// Extern symbols +extern u8 lbl_804BF998; +extern u32 lbl_80392C08[]; // Extern functions: -void fn_80334270(NpcContext* pContext); -void InitNpcContext(NpcContext* pContext, int laneIdx, int npcIdx); +void fn_80334270(RPBowNpcContext* pContext); +void InitNpcContext(RPBowNpcContext* pContext, int laneIdx, int npcIdx); +void fn_80324994(PinStatus* pPinStatus, LaneContext* pLaneContext); +void CalculateNpcBallTransform(nw4r::math::MTX34* pOutMtx, const RPBowNpcContext* pContext); +void CalculateNpcThrowVelocity(nw4r::math::VEC3* pOutVelocity, const RPBowNpcManager* pLane, const nw4r::math::VEC3* pBallPosition, const PinStatus* pPinStatus); +void UpdateNpcLane(u8* pUpdateData, const RPBowNpcContext* pContext); + +typedef void (*PlaySoundFunc)(void*, int, int); +typedef void (*UpdateSoundFunc)(void*, void*); + +#define PLAY_SOUND(id) ((PlaySoundFunc)(*(void***)((u8*)mpSoundAudioMgr + 0x78))[24])(mpSoundAudioMgr, id, 0) /** * @brief Initializes audio-related structures for the manager @@ -14,9 +25,10 @@ void InitNpcContext(NpcContext* pContext, int laneIdx, int npcIdx); * * @param laneIdx Index of the lane */ -// void RPBowNpcManager::InitAudioActors(int laneIdx) { -// ; -// } +void RPBowNpcManager::InitAudioActors(int laneIdx) { + // TODO: Stub + laneIdx = laneIdx; +} /** * @brief Configures internal pointers and prepares initial contexts @@ -29,7 +41,7 @@ void InitNpcContext(NpcContext* pContext, int laneIdx, int npcIdx); * @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) { +void RPBowNpcManager::Setup(LaneContext* pLaneContext, RPBowNpcContext* pNpc0, RPBowNpcContext* pNpc1, RPBowNpcContext* pNpc2, int laneIdx, RPBowBallReturnRack* pReturnRack, void* pAudioStruct) { mpNpcs[0] = pNpc0; mpNpcs[1] = pNpc1; mpNpcs[2] = pNpc2; @@ -42,8 +54,8 @@ void RPBowNpcManager::Setup(LaneContext* pLaneContext, NpcContext* pNpc0, NpcCon memset(&mStateId, 0, 12); for (int i = 0; i < 3; i++) { - fn_80334270(mpNpcs[i]); - InitNpcContext(mpNpcs[i], mLaneIdx, i); + mpNpcs[i]->fn_80334270(); + mpNpcs[i]->InitNpcContext(mLaneIdx, i); } mpCurrentNpc = mpNpcs[0]; @@ -100,16 +112,367 @@ enum NpcBowlingStates { /** * @brief Updates the manager's state machine */ -// void RPBowNpcManager::Update() { -// ; -// } +void RPBowNpcManager::Update() { + if (mStateTimer < 0) { + mStateTimer = 0; + } + + switch (mStateId) { + case NPC_BOWLING_STATE_IDLE: { // IDLE + nw4r::math::MTX34 mtx; + mtx.m[2][3] = 9999.0f; + mpLaneContext->throwContext.ballMtx = mtx; + mActiveSubObjIdx = -1; + break; + } + + case NPC_BOWLING_STATE_WAIT_PREPARE_LINE: { // WAIT_PREPARE_LINE + if (mActiveSubObjIdx < 0) { + mActiveSubObjIdx = mpReturnRack->SelectBallForNPC(); + } + + if (mActiveSubObjIdx >= 0) { + mpCurrentNpc->actionState.targetZPos = + mpReturnRack->mBalls[mActiveSubObjIdx].mPos.z + + gBallReturnRackConstants.mPositionOffsets[mpReturnRack->mRackIndex].z; + } else { + mpCurrentNpc->actionState.targetZPos = -999.0f; + } + + if (mStateTimer == 0) { + mpCurrentNpc->actionState.npcState = NPC_STATE_WALK_TO_APPROACH_AREA; + mpCurrentNpc->actionState.stateFrameCounter = -1; + mpCurrentNpc->actionState.triggerTransition = false; + } + + if (mpCurrentNpc->actionState.triggerTransition) { + mStateId = 2; + mStateTimer = -1; + } + + if (mpCurrentNpc->isHoldingBall != 0) { + mpLaneContext->throwContext.throwState = 0; + *(s32*)((u8*)mpSomeAudioStruct + 0x78) = mpReturnRack->GetBallSlotIndex(mActiveSubObjIdx); + + if (mpReturnRack->IsBallOnRack(mActiveSubObjIdx)) { + mpReturnRack->RemoveBallFromRack(mActiveSubObjIdx); + } + } + + mHasReleasedBall = false; + break; + } + + case NPC_BOWLING_STATE_PREPARE: { // PREPARE + if ((rand() % 100) != 0) break; + if (mStateTimer <= 80) break; + if (!mpLaneContext->IsPinSetterActive()) break; + + mStateId = 3; + mStateTimer = -1; + break; + } + + case NPC_BOWLING_STATE_RUN: { // RUN + if (mStateTimer == 0) { + mpCurrentNpc->actionState.npcState = NPC_STATE_BOWL; + mpCurrentNpc->actionState.stateFrameCounter = -1; + mpCurrentNpc->actionState.triggerTransition = false; + + mpLaneContext->ResetPinSetterState(mIsSecondThrow); + mHasPlayedGutterSfx = false; + + if (mIsSecondThrow) { + PinStatus tempStatus; + fn_80324994(&tempStatus, mpLaneContext); + mpLaneContext->fn_80327330(&tempStatus); + } else { + PinStatus tempArray; + tempArray.pinBits[0] = -1; + tempArray.pinBits[1] = -1; + tempArray.pinBits[2] = -1; + tempArray.pinBits[3] = -1; + tempArray.pinCount = 10; + mpLaneContext->fn_80327330(&tempArray); + } + } + + if (mpCurrentNpc->actionState.triggerThrow) { + mpCurrentNpc->actionState.triggerThrow = false; + + nw4r::math::MTX34 mtx3; + nw4r::math::MTX34 mtx2; + nw4r::math::MTX34 mtx1; + + CalculateNpcBallTransform(&mtx1, mpCurrentNpc); + f32 z = mtx1.m[2][3]; + + CalculateNpcBallTransform(&mtx2, mpCurrentNpc); + f32 y = mtx2.m[1][3]; + + CalculateNpcBallTransform(&mtx3, mpCurrentNpc); + f32 x = mtx3.m[0][3]; + + nw4r::math::VEC3 ballPosition; + ballPosition.x = x; + ballPosition.y = y; + ballPosition.z = z; + + nw4r::math::VEC3 velocity; + if (mIsSecondThrow) { + nw4r::math::VEC3 velocityCopy; + CalculateNpcThrowVelocity(&velocityCopy, 0, &ballPosition, &mPinStatus); + velocity = velocityCopy; + } else { + PinStatus tempPinStatus; + tempPinStatus.pinBits[0] = -1; + tempPinStatus.pinBits[1] = -1; + tempPinStatus.pinBits[2] = -1; + tempPinStatus.pinBits[3] = -1; + tempPinStatus.pinCount = 10; + + nw4r::math::VEC3 velocityCopy; + CalculateNpcThrowVelocity(&velocityCopy, 0, &ballPosition, &tempPinStatus); + velocity = velocityCopy; + } + + nw4r::math::VEC3 finalVelocity = velocity; + mpLaneContext->fn_80324DD0(&finalVelocity, 0); + mHasReleasedBall = true; + } + + if (mpCurrentNpc->actionState.triggerTransition) { + mStateId = 4; + mStateTimer = -1; + } + break; + } + + case NPC_BOWLING_STATE_SEE: { // SEE + u32 arr[11]; + PinStatus pinStatus; + PinStatus pinStatusCopy; + + if (!mHasPlayedGutterSfx && + mpLaneContext->throwContext.isGutterBall != 0 && + !mDisableResultSfx) { + + PLAY_SOUND(0x34); + mHasPlayedGutterSfx = true; + } + + if (!mpLaneContext->fn_80324B10()) break; + + mpReturnRack->SpawnBallOnRack(mActiveSubObjIdx); + mActiveSubObjIdx = -1; + mStateId = 5; + mStateTimer = -1; + + fn_80324994(&pinStatus, mpLaneContext); + + if (!mDisableResultSfx) { + if (!mIsSecondThrow) { + int count1 = pinStatus.GetStandingPinCount(); + if (count1 == 0) { + PLAY_SOUND(0x2F); + PLAY_SOUND(0x50); + } else { + int count2 = pinStatus.GetStandingPinCount(); + if (count2 <= 3) { + PLAY_SOUND(0x31); + } else { + int count3 = pinStatus.GetStandingPinCount(); + if (count3 <= 9) { + PLAY_SOUND(0x32); + } + } + } + } else { + int count1 = pinStatus.GetStandingPinCount(); + if (count1 == 0) { + int r0 = 0; + if (lbl_804BF998 != 0) { + r0 = 1; + } else if ((mPinStatus.pinBits[0] & 1) == 0) { + r0 = 0; + } else { + for (int i = 0; i < 11; i++) { + arr[i] = lbl_80392C08[i]; + } + + u32 mask = 0; + for (int i = 0; i < mPinStatus.pinCount; i++) { + if (mPinStatus.pinBits[i / 30] & (1 << (i % 30))) { + mask |= (1 << arr[i]); + } + } + + r0 = 0; + for (int i = 0; i < 5; i++) { + if ((mask & (1 << i)) != 0 && (mask & (1 << (i + 1))) == 0) { + for (int j = i + 2; j < 7; j++) { + if ((mask & (1 << j)) != 0) { + r0 = 1; + goto end_split_check; + } + } + } + } + end_split_check:; + } + + if (r0 != 0) { + PLAY_SOUND(0x33); + PLAY_SOUND(0x52); + } else { + PLAY_SOUND(0x30); + PLAY_SOUND(0x51); + } + } else { + int count2 = pinStatus.GetStandingPinCount(); + int count3 = pinStatus.GetStandingPinCount(); + + if (count2 == count3) { + PLAY_SOUND(0x36); + } else if (mHasPlayedGutterSfx) { + PLAY_SOUND(0x35); + } + } + } + } + + fn_80324994(&pinStatusCopy, mpLaneContext); + mPinStatus = pinStatusCopy; + break; + } + + case NPC_BOWLING_STATE_BACK: { // BACK + if (mStateTimer == 0) { + if (!mIsSecondThrow) { + PinStatus tempStatus; + fn_80324994(&tempStatus, mpLaneContext); + if (tempStatus.GetStandingPinCount() == 0) { + mShouldReturnToSeat = true; + } else { + mShouldReturnToSeat = false; + } + } else { + mShouldReturnToSeat = false; + } + } + + if (mStateTimer == 0) { + if (mShouldReturnToSeat) { + PinStatus tempStatus2; + fn_80324994(&tempStatus2, mpLaneContext); + if (tempStatus2.GetStandingPinCount() == 0) { + mpCurrentNpc->flag_A5 = 1; + } else { + mpCurrentNpc->flag_A5 = 0; + } + + mpCurrentNpc->actionState.npcState = NPC_STATE_WALK_BACK_TO_SEAT; + mpCurrentNpc->actionState.stateFrameCounter = -1; + mpCurrentNpc->actionState.triggerTransition = false; + } else { + mpCurrentNpc->actionState.npcState = NPC_STATE_WALK_TO_BALL_RETURN; + mpCurrentNpc->actionState.stateFrameCounter = -1; + mpCurrentNpc->actionState.triggerTransition = false; + } + } + + if (!mShouldReturnToSeat) { + if (mActiveSubObjIdx < 0) { + mActiveSubObjIdx = mpReturnRack->SelectBallForNPC(); + } + + if (mActiveSubObjIdx >= 0) { + mpCurrentNpc->actionState.targetZPos = + mpReturnRack->mBalls[mActiveSubObjIdx].mPos.z + + gBallReturnRackConstants.mPositionOffsets[mpReturnRack->mRackIndex].z; + } else { + mpCurrentNpc->actionState.targetZPos = -999.0f; + } + } + + if (!mShouldReturnToSeat && mpCurrentNpc->isHoldingBall != 0) { + mpLaneContext->throwContext.throwState = 0; + *(s32*)((u8*)mpSomeAudioStruct + 0x78) = mpReturnRack->GetBallSlotIndex(mActiveSubObjIdx); + + if (mpReturnRack->IsBallOnRack(mActiveSubObjIdx)) { + mpReturnRack->RemoveBallFromRack(mActiveSubObjIdx); + } + } + + if (mpCurrentNpc->actionState.triggerTransition) { + if (mShouldReturnToSeat) { + if (mActiveSubObjIdx >= 0) { + mpReturnRack->ReleaseBallFromNPC(mActiveSubObjIdx); + mActiveSubObjIdx = -1; + } + mStateId = 0; + mStateTimer = -1; + } else { + mIsSecondThrow = true; + mStateId = 2; + mStateTimer = -1; + } + mpLaneContext->throwContext.throwState = 0; + } + break; + } + } + + mStateTimer++; + + u8 updateStruct[0x4C]; + UpdateNpcLane(updateStruct, mpCurrentNpc); + // mpCurrentNpc->UpdateNpcLane(); + + ((UpdateSoundFunc)(*(void***)((u8*)mpSoundAudioMgr + 0x78))[18])(mpSoundAudioMgr, updateStruct); + + if (mpCurrentNpc->isHoldingBall != 0) { + nw4r::math::MTX34 mtx; + CalculateNpcBallTransform(&mtx, mpCurrentNpc); + mpLaneContext->throwContext.ballMtx = mtx; + } +} + +struct StateStrings { + const char* str[6]; +}; + +// const char* lbl_80392C30[] = { +// "IDLE", +// "WAIT_PREPARE_LINE", +// "PREPARE", +// "RUN", +// "SEE", +// "BACK NPC[%d(%s)] %s phy:%d\x00\x32\x6E\x64\x00\x31\x73\x74\x00\x00\x00\x00" +// }; + +extern StateStrings lbl_80392C30; +extern char lbl_80392C48[]; + +extern "C" void fn_801C38B8(char* pBuffer, int a, int b, float c, float d, float e); +extern float lbl_804C618C; /** * @brief Prints debug information for this NPC manager * @details Example string formats: 'NPC[0(1st)] PREPARE phy:0' */ -// void RPBowNpcManager::DebugPrintNpcState() { -// ; -// } +void RPBowNpcManager::DebugPrintNpcState() { + StateStrings localStrings = lbl_80392C30; + + int laneCalc = (mLaneIdx * 20) + 100; -} // namespace Bowling + char buffer[256]; + + const char* pStr2 = (mIsSecondThrow) ? &lbl_80392C48[0x43] : &lbl_80392C48[0x47]; + int throwState = mpLaneContext->throwContext.throwState; + + sprintf(buffer, &lbl_80392C48[0x2C], mLaneIdx, pStr2, localStrings.str[mStateId], throwState); + + int VAL_400 = 400; + fn_801C38B8(buffer, -1, 1, (float)VAL_400, (float)laneCalc, lbl_804C618C); +} diff --git a/src/Pack/RPSports/RPBowScene/RPBowObstacleManager.cpp b/src/Pack/RPSports/RPBowScene/RPBowObstacleManager.cpp new file mode 100644 index 000000000..1bad239f3 --- /dev/null +++ b/src/Pack/RPSports/RPBowScene/RPBowObstacleManager.cpp @@ -0,0 +1,204 @@ +#include + +/** + * @brief Resets pin hit states based on obstacle data and mapping + * + * @param pPinBitfield[out] Array of pin bitfields to update + * @param pMgr Obstacle manager instance + * @param obstacleSetIdx Index of the active obstacle set + * @param useDirectMapping Flag to bypass the mapping array and use direct indexing + */ +void UpdatePinHitState(PinStatus* pPinStatus, RPBowObstacleManager* pMgr, u32 obstacleSetIdx, u32 useDirectMapping) { + pPinStatus->pinBits[3] = 0; + pPinStatus->pinBits[2] = 0; + pPinStatus->pinBits[1] = 0; + pPinStatus->pinBits[0] = 0; + pPinStatus->pinCount = 10; + + const u32 pinMapping[10] = {0, 2, 1, 5, 4, 3, 9, 8, 7, 6}; + + for (int i = 0; i < 10; i++) { + u32 targetPin = useDirectMapping ? i : pinMapping[i]; + if (pMgr->dataPtr[obstacleSetIdx].pins[targetPin].hitTimer >= -1000.0f) { + if (pMgr->dataPtr[obstacleSetIdx].pins[targetPin].unk_04 >= -1000.0f) { + pPinStatus->pinBits[i / 30] |= (1 << (i % 30)); + } + } + } +} + +/** + * @brief Tests whether the ball has collided with any active obstacle + * + * @param obstacleSetIdx Index of the active obstacle set + * @param pBall Position vector of the ball + * @return 1 if a collision occurred, 0 otherwise + */ +u32 RPBowObstacleManager::CheckObstacleCollision(u32 obstacleSetIdx, nw4r::math::VEC3* pBall) { + for (int i = 0; i < 16; i++) { + if (dataPtr[obstacleSetIdx].obstacles[i].scale > 0.000001f) { + float threshold = dataPtr[obstacleSetIdx].obstacles[i].offsetZ; + if (-pBall->z > threshold - 13.0f && -pBall->z < threshold + 4.0f) { + return 1; + } + } + } + + return 0; +} + +/** + * @brief Tests whether the ball has passed all obstacles in the current lane + * + * @param obstacleSetIdx Index of the active obstacle set + * @param pBall Position vector of the ball + * @return 1 if all active obstacles have been passed, 0 otherwise + */ +u32 RPBowObstacleManager::CheckObstaclePassed(u32 obstacleSetIdx, nw4r::math::VEC3* pBall) { + for (int i = 0; i < 16; i++) { + if (dataPtr[obstacleSetIdx].obstacles[i].scale > 0.000001f) { + if (-dataPtr[obstacleSetIdx].obstacles[i].offsetZ < pBall->z) { + return 0; + } + } + } + + return 1; +} + +/** + * @brief Initializes obstacle positions and states for a lane + * + * @param obstacleSetIdx Index of the active obstacle set + * @param isRightSide Flag indicating if the lane is on the right side + * @param spawnZ Z-coordinate to spawn the obstacles + */ +void RPBowObstacleManager::ResetLaneObstacles(u32 obstacleSetIdx, u32 isRightSide, f32 spawnZ) { + for (int i = 0; i < 48; i++) { + obstacles[i].active = 0; + } + + for (int i = 0; i < 16; i++) { + ObstacleDef* pObstacleDef = &dataPtr[obstacleSetIdx].obstacles[i]; + ObstacleInstance* pState = &obstacles[i]; + + pState->active = 0; + + if (pObstacleDef->scale > 0.000001f) { + pState->body.fn_80329088(10.0f, 0.5f, 1.0f, 0.0f); + f32 posZ = -pObstacleDef->offsetZ; + f32 adj = (isRightSide != 0) ? (pObstacleDef->offsetX) : (-pObstacleDef->offsetX); + + pState->body.state.position = nw4r::math::VEC3(spawnZ + adj, 0.0f, posZ); + pState->baseScale = pObstacleDef->scale; + pState->active = 1; + } + } +} + +/** + * @brief Represents a single collision triangle + */ +struct CollisionTriangle { + // total size: 0x24 + nw4r::math::_VEC3 vertex[3]; // offset 0x0, size 0x24 +}; + +/** + * @brief Represents the geometric hull for an obstacle + */ +struct CollisionHull { + // total size: 0x1B0 + CollisionTriangle triangles[12]; // offset 0x0, size 0x1B0 +}; + +// Default geometric definitions for an obstacle hull +const CollisionHull sObstacleHullVertices = {{ + { { { -1.0f, -1.0f, 1.0f }, { 1.0f, -1.0f, 1.0f }, { 1.0f, 1.0f, 1.0f } } }, + { { { -1.0f, -1.0f, 1.0f }, { 1.0f, 1.0f, 1.0f }, { -1.0f, 1.0f, 1.0f } } }, + { { { -1.0f, 1.0f, 1.0f }, { 1.0f, 1.0f, 1.0f }, { 1.0f, 1.0f, -1.0f } } }, + { { { -1.0f, 1.0f, 1.0f }, { 1.0f, 1.0f, -1.0f }, { -1.0f, 1.0f, -1.0f } } }, + { { { -1.0f, 1.0f, -1.0f }, { 1.0f, 1.0f, -1.0f }, { 1.0f, -1.0f, -1.0f } } }, + { { { -1.0f, 1.0f, -1.0f }, { 1.0f, -1.0f, -1.0f }, { -1.0f, -1.0f, -1.0f } } }, + { { { -1.0f, -1.0f, -1.0f }, { 1.0f, -1.0f, -1.0f }, { 1.0f, -1.0f, 1.0f } } }, + { { { -1.0f, -1.0f, -1.0f }, { 1.0f, -1.0f, 1.0f }, { -1.0f, -1.0f, 1.0f } } }, + { { { 1.0f, -1.0f, 1.0f }, { 1.0f, -1.0f, -1.0f }, { 1.0f, 1.0f, -1.0f } } }, + { { { 1.0f, -1.0f, 1.0f }, { 1.0f, 1.0f, -1.0f }, { 1.0f, 1.0f, 1.0f } } }, + { { { -1.0f, -1.0f, -1.0f }, { -1.0f, -1.0f, 1.0f }, { -1.0f, 1.0f, 1.0f } } }, + { { { -1.0f, -1.0f, -1.0f }, { -1.0f, 1.0f, 1.0f }, { -1.0f, 1.0f, -1.0f } } } +}}; + +/** + * @brief Updates collision geometry for all active obstacles + */ +void RPBowObstacleManager::UpdateObstacleCollisionBounds() { + const CollisionHull* pShapeDataSrc = &sObstacleHullVertices; + + f32 scaleY = 2.329f; + f32 scaleZ = 0.408f; + + for (int i = 0; i < 48; i++) { + ObstacleInstance* pObstacle = &obstacles[i]; + + if (pObstacle->active != 0) { + nw4r::math::MTX34 mtx1( + pObstacle->body.state.basisX.x, pObstacle->body.state.basisY.x, pObstacle->body.state.basisZ.x, pObstacle->body.state.position.x, + pObstacle->body.state.basisX.y, pObstacle->body.state.basisY.y, pObstacle->body.state.basisZ.y, pObstacle->body.state.position.y, + pObstacle->body.state.basisX.z, pObstacle->body.state.basisY.z, pObstacle->body.state.basisZ.z, pObstacle->body.state.position.z + ); + + CollisionHull shapeData = *pShapeDataSrc; + + for (int j = 0; j < 12; j++) { + CollisionTriangleState* pPart = &pObstacle->triangles[j]; + f32 scaleX = pObstacle->baseScale; + + pPart->vec0 = nw4r::math::VEC3( + scaleX * shapeData.triangles[j].vertex[0].x, + scaleY * shapeData.triangles[j].vertex[0].y, + scaleZ * shapeData.triangles[j].vertex[0].z + ); + + pPart->vec1 = nw4r::math::VEC3( + scaleX * shapeData.triangles[j].vertex[1].x, + scaleY * shapeData.triangles[j].vertex[1].y, + scaleZ * shapeData.triangles[j].vertex[1].z + ); + + pPart->vec2 = nw4r::math::VEC3( + scaleX * shapeData.triangles[j].vertex[2].x, + scaleY * shapeData.triangles[j].vertex[2].y, + scaleZ * shapeData.triangles[j].vertex[2].z + ); + + // Transforms each vertex by the body matrix (in-place) + nw4r::math::VEC3Transform(&pPart->vec0, &mtx1, &pPart->vec0); + nw4r::math::VEC3Transform(&pPart->vec1, &mtx1, &pPart->vec1); + nw4r::math::VEC3Transform(&pPart->vec2, &mtx1, &pPart->vec2); + + // Computes all four differences before any cross product + nw4r::math::VEC3 diff10 = pPart->vec1 - pPart->vec0; + nw4r::math::VEC3 diff20 = pPart->vec2 - pPart->vec0; + nw4r::math::VEC3 diff21 = pPart->vec2 - pPart->vec1; + nw4r::math::VEC3 diff02 = pPart->vec0 - pPart->vec2; + + // Primary surface normal + nw4r::math::VEC3Cross(&pPart->cross0, &diff10, &diff20); + nw4r::math::VEC3Normalize(&pPart->cross0, &pPart->cross0); + + // Edge normals + nw4r::math::VEC3Cross(&pPart->cross1, &diff10, &pPart->cross0); + nw4r::math::VEC3Cross(&pPart->cross2, &diff21, &pPart->cross0); + nw4r::math::VEC3Cross(&pPart->cross3, &diff02, &pPart->cross0); + + nw4r::math::VEC3Normalize(&pPart->cross1, &pPart->cross1); + nw4r::math::VEC3Normalize(&pPart->cross2, &pPart->cross2); + nw4r::math::VEC3Normalize(&pPart->cross3, &pPart->cross3); + + // Compute plane/edge bias + nw4r::math::VEC3 diff01 = pPart->vec0 - pPart->vec1; + pPart->edgeBias = -nw4r::math::VEC3Dot(&diff01, &pPart->cross2); + } + } + } +} diff --git a/src/Pack/RPSports/RPBowScene/RPBowPerfectGameUI.cpp b/src/Pack/RPSports/RPBowScene/RPBowPerfectGameUI.cpp new file mode 100644 index 000000000..d8671da20 --- /dev/null +++ b/src/Pack/RPSports/RPBowScene/RPBowPerfectGameUI.cpp @@ -0,0 +1,109 @@ +#include + +/** + * @brief Initializes the perfect game UI + * + * @param pAccessor Layout resource accessor + * @param pMessage Message handler + */ +void RPBowPerfectGameUI::Init(RPSysLytResAccessor* pAccessor, RPSysMessage* pMessage) { + mpLayout = RPSysLayout::create(0, pAccessor, "bwgText_05.brlyt"); + mpAnmIn = mpLayout->createAnmObj(0, pAccessor, "bwgText_05_in_00.brlan"); + mpAnmOut = mpLayout->createAnmObj(0, pAccessor, "bwgText_05_out_00.brlan"); + + for (int i = 0; i < 5; i++) { + char buf[256]; + std::sprintf(buf, "T_perfect_%02d", i); + RPSysLytTextBox* pTextBox = mpLayout->findTextBox(buf); + pTextBox->setMessage(pMessage, 0x6784, 0, 0); + } + + mpHubukiEffect = new RPSysEffect("Bow_perfect_hubuki", mDrawGroup, 0); + + mpRootPane = mpLayout->findPane("N_perfect_00"); +} + +/** + * @brief Resets the UI state + */ +void RPBowPerfectGameUI::Reset() { + mState = 0; +} + +/** + * @brief Updates the UI state and animations + */ +void RPBowPerfectGameUI::Calc() { + bool flag = false; + + if (mState == 0) { + if (mIsVisible) { + mpLayout->unbindAllAnmObj(); + mpLayout->bindAnmObj(mpAnmIn); + + RPSysLytAnmObj* pIn = mpAnmIn; + s16 len = pIn->getStartFrame(); + pIn->setFrame(len); + pIn->setFlags(0); + pIn->setEnabled(1); + + mState = 2; + flag = true; + } + } + + if (mState == 1) { + if (!mIsVisible) { + mpLayout->unbindAllAnmObj(); + mpLayout->bindAnmObj(mpAnmOut); + + RPSysLytAnmObj* pOut = mpAnmOut; + s16 len = pOut->getStartFrame(); + pOut->setFrame(len); + pOut->setFlags(0); + pOut->setEnabled(1); + + mpHubukiEffect->fade(); + mState = 3; + } + } + + if (mState == 2) { + if (mpAnmIn->isFinished()) { + mState = 1; + } + } + + if (mState == 3) { + if (mpAnmOut->isFinished()) { + mState = 0; + } + } + + mpLayout->calc(); + + nw4r::math::MTX34 mtx = mpRootPane->GetGlobalMtx(); + + if (flag) { + RPSysEffect kiraEffect("Bow_perfect_kira", mDrawGroup, 0); + kiraEffect.create(); + + nw4r::math::VEC3 pos(mtx[0][3], mtx[1][3], mtx[2][3]); + kiraEffect.setPos(pos); + kiraEffect.update(); + + mpHubukiEffect->forceKill(); + mpHubukiEffect->create(); + } + + nw4r::math::VEC3 pos2(mtx[0][3], mtx[1][3], mtx[2][3]); + mpHubukiEffect->setPos(pos2); + mpHubukiEffect->update(); +} + +/** + * @brief Draws the UI layout + */ +void RPBowPerfectGameUI::Draw() { + mpLayout->draw(); +} diff --git a/src/Pack/RPSports/RPBowScene/RPBowPinSetter.cpp b/src/Pack/RPSports/RPBowScene/RPBowPinSetter.cpp deleted file mode 100644 index ed9fca219..000000000 --- a/src/Pack/RPSports/RPBowScene/RPBowPinSetter.cpp +++ /dev/null @@ -1,166 +0,0 @@ -#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/RPBowPinSetterManager.cpp b/src/Pack/RPSports/RPBowScene/RPBowPinSetterManager.cpp new file mode 100644 index 000000000..cc5cc3699 --- /dev/null +++ b/src/Pack/RPSports/RPBowScene/RPBowPinSetterManager.cpp @@ -0,0 +1,158 @@ +#include + +#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 isNewRack Flag indicating if this is a new rack + */ +void LaneContext::ResetPinSetterState(u8 isNewRack) { + memset(&setterAnimation, 0, 0x10); + setterAnimation.isNewRack = isNewRack; + + RPBowPinSetterModel* pSetter = pPinSetter; + pSetter->mSequencePhase = 0; + pSetter->mPrimaryState = 0; + pSetter->mFrameTimer = 0.0f; +} + +/** + * @brief Triggers the pin setter animation sequence + * + * @param spawnNewRack Flag indicating if a new rack should be spawned + */ +void LaneContext::TriggerPinSetter(int spawnNewRack) { + if (setterAnimation.sequenceFrameCount == 0) { + setterAnimation.sequenceFrameCount = 1; + if (spawnNewRack != 0) { + setterAnimation.isNewRack = 1; + } + } +} + +/** + * @brief Updates the pin setter state and animations + * + * @return 1 on success, otherwise 0 + */ +int LaneContext::UpdatePinSetter() { + int currentAnimMode = throwContext.animationMode; + setterAnimation.animOffsetZ = 0.0f; + setterAnimation.animRotationY = -180.5f; + + if (currentAnimMode == 2) { + return 1; + } + + int sequenceFrame = setterAnimation.sequenceFrameCount; + if (sequenceFrame == 0) { + for (int i = 0; i < pinCount; i++) { + pPinManager->pPinBodies[i]->mode_0x28C = 0; + } + + float z = throwContext.ballMtx._23; + float y = throwContext.ballMtx._13; + float x = throwContext.ballMtx._03; + nw4r::math::VEC3 ballPos(x, y, z); + + if (ballPos.z < SWEEPER_BALL_Z_TRIGGER) { + pPinSetter->mSequencePhase = 1; + } + return 1; + } + + if (currentAnimMode != 0) { + return 1; + } + + if (sequenceFrame == 1 && setterAnimation.isNewRack == 0) { + pPinSetter->mSequencePhase = 2; + } + + if (setterAnimation.sequenceFrameCount == SWEEPER_FRAME_LIFT_PINS && setterAnimation.isNewRack == 0) { + for (int i = 0; i < pinCount; i++) { + if (pPinManager->pPinBodies[i]->unkFlag_0x250 == 0) { + pPinManager->pPinBodies[i]->mode_0x28C = 1; + } + } + } + + if (setterAnimation.sequenceFrameCount == SWEEPER_FRAME_START_SWEEP) { + pPinSetter->mSequencePhase = 3; + } + + if (setterAnimation.sequenceFrameCount > SWEEPER_FRAME_START_SWEEP) { + setterAnimation.animOffsetZ = 0.28f * ((float)setterAnimation.sequenceFrameCount - (float)SWEEPER_FRAME_START_SWEEP); + } + + if (setterAnimation.sequenceFrameCount == SWEEPER_FRAME_PLACE_PINS && setterAnimation.isNewRack == 0) { + for (int i = 0; i < pinCount; i++) { + if (pPinManager->pPinBodies[i]->unkFlag_0x250 == 0) { + pPinManager->pPinBodies[i]->mode_0x28C = 3; + } + } + } + + if (setterAnimation.sequenceFrameCount == SWEEPER_FRAME_PLACE_PINS && setterAnimation.isNewRack != 0) { + for (int i = 0; i < pinCount; i++) { + pPinManager->pPinBodies[i]->VF_0x0C(); + + nw4r::math::VEC3 basisZ; + nw4r::math::VEC3 basisY; + nw4r::math::VEC3 basisX; + + pPinManager->pPinBodies[i]->isActive = 1; + + PinPhysicsBody* pBody = pPinManager->pPinBodies[i]; + nw4r::math::VEC3 pos = pBody->field_0xFC; + pos.y = 8.0f; + + pBody->state.position = pos; + + basisX.x = 1.0f; + basisX.y = 0.0f; + basisX.z = 0.0f; + pBody->state.basisX = basisX; + + basisY.x = 0.0f; + basisY.y = 1.0f; + basisY.z = 0.0f; + pBody->state.basisY = basisY; + + basisZ.x = 0.0f; + basisZ.y = 0.0f; + basisZ.z = 1.0f; + pBody->state.basisZ = basisZ; + + pPinManager->pPinBodies[i]->mode_0x28C = 3; + } + } + + setterAnimation.sequenceFrameCount++; + return 1; +} + +/** + * @brief Tests whether the pin setter is currently active + * + * @return 1 if active, 0 otherwise + */ +int LaneContext::IsPinSetterActive() { + int frame = setterAnimation.sequenceFrameCount; + if (frame != 0 && frame < SWEEPER_FRAME_END) { + return 1; + } + return 0; +} + +/** + * @brief Unknown function (stubbed) + */ +void LaneContext::fn_803345F0() { + ; +} diff --git a/src/Pack/RPSports/RPBowScene/RPBowPinSetterModel.cpp b/src/Pack/RPSports/RPBowScene/RPBowPinSetterModel.cpp new file mode 100644 index 000000000..8e63add0c --- /dev/null +++ b/src/Pack/RPSports/RPBowScene/RPBowPinSetterModel.cpp @@ -0,0 +1,131 @@ +#include + +extern bool gGameStateFlag1_804BF9E8; +extern bool gGameStateFlag2_804BF9E9; + +/** + * @brief Min and max frame boundaries for pinsetter animation stages + */ +struct StageRange { + f32 min; + f32 max; +}; + +const StageRange scStageRanges[4] = { + { 0.0f, 0.0f }, + { 0.0f, 51.0f }, + { 75.0f, 250.0f }, + { 250.0f, 505.0f }, +}; + +/** + * @brief Destructor + */ +RPBowPinSetterModel::~RPBowPinSetterModel() {} + +/** + * @brief Sets the visual models for the pinsetter + * + * @param pModel0 Main pinsetter model + * @param pModel1 Reflection pinsetter model + */ +void RPBowPinSetterModel::SetModels(RPGrpModel* pModel0, RPGrpModel* pModel1) { + mpModel[0] = pModel0; + mpModel[1] = pModel1; +} + +/** + * @brief Resets the pinsetter's animation and state tracking variables + */ +void RPBowPinSetterModel::Reset() { + for (int i = 0; i < 2; i++) { + mpModel[i]->GetModelAnm()->Start(RPGrpModelAnm::Anm_Chr, 0, 0.0f); + mpModel[i]->GetModelAnm()->SetUpdateRate(RPGrpModelAnm::Anm_Chr, 0, 0.0f); + } + + mPrimaryState = 0; + mSequencePhase = 0; + mAngle = -175.0f; + mFrameTimer = 0.0f; + + gGameStateFlag1_804BF9E8 = false; + gGameStateFlag2_804BF9E9 = false; +} + +/** + * @brief Sets the world position offset of the pinsetter + * + * @param x X-axis offset + * @param z Z-axis offset + */ +void RPBowPinSetterModel::SetOffsetXZ(f32 x, f32 z) { + nw4r::math::VEC3 trans(x, 0.0f, z); + MTX34Identity(&mMtx); + MTX34Trans(&mMtx, &trans, &mMtx); +} + +/** + * @brief Calculates animation progression and updates the model transformation matrices + */ +void RPBowPinSetterModel::Calc() { + struct StageRangeArray { + float data[8]; + }; + + StageRangeArray stageRanges; + + float* pMax = &stageRanges.data[1]; + + stageRanges = *(StageRangeArray*)scStageRanges; + + float maxVal = pMax[mPrimaryState * 2]; + + bool reachedTarget = false; + if (!(mFrameTimer < maxVal)) { + mFrameTimer = maxVal; + reachedTarget = true; + } else { + mFrameTimer += 1.0f; + } + + if (mPrimaryState != mSequencePhase && reachedTarget) { + mPrimaryState = mSequencePhase; + mFrameTimer = stageRanges.data[mSequencePhase * 2]; + } + + if (!gGameStateFlag1_804BF9E8) { + if (mFrameTimer < 0.1f || mFrameTimer > 504.0f) { + return; + } + } + + for (int i = 0; i < 2; ++i) { + mpModel[i]->GetModelAnm()->SetFrame(RPGrpModelAnm::Anm_Chr, 0, mFrameTimer); + } + + nw4r::math::MTX34 mtx0 = mMtx; + + if (mpModel[0]->GetScnObj() != NULL) { + mpModel[0]->GetScnObj()->SetMtx(nw4r::g3d::ScnObj::MTX_LOCAL, &mtx0); + } + mpModel[0]->UpdateFrame(); + mpModel[0]->Calc(); + + nw4r::math::MTX34 mtx1 = mtx0; + const f32 neg = -1.0f; + mtx1._10 *= neg; + mtx1._11 *= neg; + mtx1._12 *= neg; + mtx1._13 *= neg; + + if (mpModel[1]->GetScnObj() != NULL) { + mpModel[1]->GetScnObj()->SetMtx(nw4r::g3d::ScnObj::MTX_LOCAL, &mtx1); + } + mpModel[1]->UpdateFrame(); + mpModel[1]->Calc(); + mpModel[1]->Entry(); + + if (!(std::fabs(mMtx._03) < 0.1f && gGameStateFlag2_804BF9E9)) { + mpModel[0]->Entry(); + } +} diff --git a/src/Pack/RPSports/RPBowScene/RPBowPowerThrowsPinLayout.cpp b/src/Pack/RPSports/RPBowScene/RPBowPowerThrowsPinLayout.cpp new file mode 100644 index 000000000..74cea6ff8 --- /dev/null +++ b/src/Pack/RPSports/RPBowScene/RPBowPowerThrowsPinLayout.cpp @@ -0,0 +1,137 @@ +#include + +extern nw4r::math::VEC2 lbl_803CABF0[2][4]; + +/** + * @brief Destructor + */ +RPBowPowerThrowsPinLayout::~RPBowPowerThrowsPinLayout() {} + +/** + * @brief Initializes the Power Throws pin layout + * + * @param pAcc Layout resource accessor + */ +void RPBowPowerThrowsPinLayout::Init(RPSysLytResAccessor* pAcc) { + mpLayout = RPSysLayout::create(NULL, pAcc, "pin_01.brlyt"); + mpRootPane = mpLayout->findPane("RootPane"); + + char buf[256]; + + for (int i = 0; i < 10; i++) { + StagePane* pCurrentStage = &mStages[i]; + pCurrentStage->line = NULL; + pCurrentStage->lineBG = NULL; + + if (i != 0) { + sprintf(buf, "N_lineBG%02d_00", i + 4); + pCurrentStage->lineBG = mpLayout->findPane(buf); + + sprintf(buf, "N_line%02d_00", i + 4); + pCurrentStage->line = mpLayout->findPane(buf); + } + + sprintf(buf, "pin_01_stage_%02d.brlan", i); + pCurrentStage->stageAnm = mpLayout->createAnmObj(NULL, pAcc, buf); + } + + for (int i = 0; i < 91; i++) { + sprintf(buf, "P_pin_%02d", i); + mpPins[i] = mpLayout->findPane(buf); + } + + mAnimationState = 0; +} + +/** + * @brief Resets the layout and animation objects + */ +void RPBowPowerThrowsPinLayout::Reset() { + mpLayout->reset(); + mpLayout->unbindAllAnmObj(); + mAnimationState = 0; +} + +/** + * @brief Updates the pin layout logic for the Power Throws mode + * + * @param pContext Bowling scene context + */ +void RPBowPowerThrowsPinLayout::Update(SceneContext* pContext) { + if (mAnimationState == 0 || mAnimationState == 3) { + if (mUnk4) { + mpLayout->startDynAnmIn(0); + mAnimationState = 1; + mpLayout->unbindAllAnmObj(); + + mpLayout->bindAnmObj(mStages[pContext->field_0xC38].stageAnm); + + RPSysLytAnmObj* pTempAnm = mStages[pContext->field_0xC38].stageAnm; + s16 startFrame = pTempAnm->getStartFrame(); + pTempAnm->setFrame((float)startFrame); + pTempAnm->setFlags(0); + pTempAnm->setEnabled(1); + } + } + + if (mAnimationState == 1 || mAnimationState == 2) { + if (!mUnk4) { + mpLayout->startDynAnmOut(0); + mAnimationState = 3; + } + } + + if (mAnimationState == 1) { + if (mpLayout->isFinishedDynAnmIn()) { + mAnimationState = 2; + } + } + + if (mAnimationState == 3) { + if (mpLayout->isFinishedDynAnmOut()) { + mAnimationState = 0; + } + } + + for (int i = 0; i < 10; i++) { + if (mStages[i].lineBG != NULL) { + mStages[i].lineBG->SetVisible(i < pContext->field_0xC38); + } + if (mStages[i].line != NULL) { + mStages[i].line->SetVisible(i < pContext->field_0xC38); + } + } + + for (int i = 0; i < 91; i++) { + if (pContext->pinStatus.pinBits[i / 30] & (1 << (i % 30))) { + mpPins[i]->SetVisible(true); + } else { + mpPins[i]->SetVisible(false); + } + } + + int tvIdx = (EGG::Screen::GetTVMode() != EGG::Screen::TV_MODE_STD); + int typeIdx = pContext->mUnkC1C; + + f32* pFloats = (f32*)lbl_803CABF0[tvIdx]; + volatile f32 dummyX = pFloats[typeIdx * 2]; + volatile f32 dummyY = pFloats[typeIdx * 2 + 1]; + + mpLayout->calc(); +} + +/** + * @brief Draws the layout + */ +void RPBowPowerThrowsPinLayout::Draw() { + mpLayout->draw(); +} + +/** + * @brief Tests whether the layout animation has finished + * + * @return True if animation state is 0, false otherwise + */ +bool RPBowPowerThrowsPinLayout::IsFinished() const { + return mAnimationState == 0; +} diff --git a/src/Pack/RPSports/RPBowScene/RPBowPowerThrowsPinManager.cpp b/src/Pack/RPSports/RPBowScene/RPBowPowerThrowsPinManager.cpp new file mode 100644 index 000000000..9c5d41317 --- /dev/null +++ b/src/Pack/RPSports/RPBowScene/RPBowPowerThrowsPinManager.cpp @@ -0,0 +1,131 @@ +#include + +/** + * @brief Stub + */ +void RPBowPowerThrowsPinManager::fn_80340304() { + ; +} + +// Calls destructor +// fn_803402FC() + +// Calls RPBowPowerThrowsPinManager::CopyMatrices +// fn_803402F4() + +/** + * @brief Destructor + */ +RPBowPowerThrowsPinManager::~RPBowPowerThrowsPinManager() {} + +/** + * @brief Sets the real and reflection models + * + * @param pRealModel Real pin model + * @param pReflectionModel Reflection pin model + */ +void RPBowPowerThrowsPinManager::SetModels(RPGrpModel* pRealModel, RPGrpModel* pReflectionModel) { + mpModels[0] = pRealModel; + mpModels[1] = pReflectionModel; + + mpModels[0]->SetCallback(this); + mpModels[1]->SetCallback(this); +} + +/** + * @brief Stub + */ +void RPBowPowerThrowsPinManager::fn_8034021C() { + ; +} + +/** + * @brief Updates frames and matrices for the models + */ +void RPBowPowerThrowsPinManager::UpdateModels() { + nw4r::math::MTX34 identityMtx; + PSMTXIdentity(identityMtx); + + for (int i = 0; i < 2; i++) { + nw4r::g3d::ScnObj* pScnObj = mpModels[i]->GetScnObj(); + + if (pScnObj != NULL) { + pScnObj->SetMtx(nw4r::g3d::ScnObj::MTX_LOCAL, &identityMtx); + } + + mpModels[i]->UpdateFrame(); + mpModels[i]->Calc(); + mpModels[i]->Entry(); + } +} + +/** + * @brief Stub + */ +void RPBowPowerThrowsPinManager::fn_80340194() { + ; +} + +/** + * @brief Copies matrices to the specified model + * + * @param pOther Target model + */ +void RPBowPowerThrowsPinManager::CopyMatrices(RPGrpModel* pOther) { + for (int i = 0; i < 2; i++) { + if (pOther == mpModels[i]) { + for (u16 j = 0; j < 91; j++) { + nw4r::math::MTX34* pDst = pOther->ReferWorldMtx(j + 1); + const nw4r::math::MTX34* pSrc = &mMatrixPairs[j].realMtx; + *pDst = *pSrc; + } + } + } +} + +/** + * @brief Transforms the matrix for a given pin + * + * @param pinIndex Index of the pin + * @param pMtx Base matrix + * @param yOffset Y-axis translation offset + */ +void RPBowPowerThrowsPinManager::TransformMatrix(int pinIndex, const nw4r::math::MTX34* pMtx, f32 yOffset) { + nw4r::math::MTX34 workMtx4; + workMtx4._00 = 1.0f; workMtx4._01 = 0.0f; workMtx4._02 = 0.0f; workMtx4._03 = 0.0f; + workMtx4._10 = 0.0f; workMtx4._11 = 1.0f; workMtx4._12 = 0.0f; workMtx4._13 = -yOffset; + workMtx4._20 = 0.0f; workMtx4._21 = 0.0f; workMtx4._22 = 1.0f; workMtx4._23 = 0.0f; + + nw4r::math::MTX34 workMtx3; + MTX34Mult(&workMtx3, pMtx, &workMtx4); + mMatrixPairs[pinIndex].realMtx = workMtx3; + + nw4r::math::MTX34 workMtx2; + workMtx2._00 = 1.0f; workMtx2._01 = 0.0f; workMtx2._02 = 0.0f; workMtx2._03 = 0.0f; + workMtx2._10 = 0.0f; workMtx2._11 = 1.0f; workMtx2._12 = 0.0f; workMtx2._13 = -yOffset; + workMtx2._20 = 0.0f; workMtx2._21 = 0.0f; workMtx2._22 = 1.0f; workMtx2._23 = 0.0f; + + nw4r::math::MTX34 workMtx1; + nw4r::math::MTX34 workMtx0 = *pMtx; + + // Invert scale/rotation mapping for the reflection calculation + workMtx0._10 *= -1.0f; + workMtx0._11 *= -1.0f; + workMtx0._12 *= -1.0f; + workMtx0._13 *= -1.0f; + + MTX34Mult(&workMtx1, &workMtx0, &workMtx2); + mMatrixPairs[pinIndex].reflectionMtx = workMtx1; +} + +/** + * @brief Clears matrices from the specified start index + * + * @param startIndex Starting pin index + */ +void RPBowPowerThrowsPinManager::ClearMatrices(int startIndex) { + for (s32 i = startIndex; i < 91; i++) { + mMatrixPairs[i].realMtx = nw4r::math::MTX34(0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f); + mMatrixPairs[i].reflectionMtx = nw4r::math::MTX34(0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f); + } +} diff --git a/src/Pack/RPSports/RPBowScene/RPBowPowerThrowsRoundsLayout.cpp b/src/Pack/RPSports/RPBowScene/RPBowPowerThrowsRoundsLayout.cpp new file mode 100644 index 000000000..b46a3f2c2 --- /dev/null +++ b/src/Pack/RPSports/RPBowScene/RPBowPowerThrowsRoundsLayout.cpp @@ -0,0 +1,170 @@ +#include + +/** + * @brief Initializes the Power Throws rounds layout + * + * @param pAcc Layout resource accessor + * @param pMsg System message configuration + */ +void RPBowPowerThrowsRoundsLayout::Init(RPSysLytResAccessor* pAcc, RPSysMessage* pMsg) { + mpMessage = pMsg; + mpLayout = RPSysLayout::create(NULL, pAcc, "bwgCount_01.brlyt"); + mpRootPane = mpLayout->findPane("RootPane"); + + char buf[64]; + PowerThrowsRoundPane* pPane = mAnmPanes; + for (int i = 0; i < 10; i++, pPane++) { + sprintf(buf, "N_ball_%02d", i); + pPane->pane1 = mpLayout->findPane(buf); + + sprintf(buf, "P_check_%02d", i); + pPane->pane2 = mpLayout->findPane(buf); + + RPSysLytAnmObj** ppAnm = pPane->anmObjs; + for (int j = 0; j < 4; j++, ppAnm++) { + sprintf(buf, "bwgCount_01_ballColor_%02d.brlan", j); + *ppAnm = mpLayout->createAnmObj(NULL, pAcc, buf); + } + } + + mAnimationState = 0; + mpTextBoxes[0][0] = mpLayout->findTextBox("T_text_00"); + mpTextBoxes[0][1] = mpLayout->findTextBox("T_text_01"); + mpTextBoxes[1][0] = mpLayout->findTextBox("T_textS_00"); + mpTextBoxes[1][1] = mpLayout->findTextBox("T_textS_01"); +} + +/** + * @brief Resets the layout components and state tracking variables + */ +void RPBowPowerThrowsRoundsLayout::Reset() { + mpLayout->reset(); + mpLayout->unbindAllAnmObj(); + mAnimationState = 0; + + PowerThrowsRoundPane* pPane = mAnmPanes; + for (int i = 0; i < 10; i++, pPane++) { + pPane->activeIdx = -1; + } +} + +/** + * @brief Updates the scoring text boxes and active animations for current frame + * + * @param pContext Bowling scene context + */ +void RPBowPowerThrowsRoundsLayout::Update(SceneContext* pContext) { + int playerIdx = -pContext->mUnkC34; + + if (mAnimationState == 0 || mAnimationState == 3) { + if (unk04) { + mpLayout->startDynAnmIn(playerIdx); + mAnimationState = 1; + mpLayout->unbindAllAnmObj(); + mAnmPanes[0].activeIdx = -1; + mAnmPanes[1].activeIdx = -1; + mAnmPanes[2].activeIdx = -1; + mAnmPanes[3].activeIdx = -1; + mAnmPanes[4].activeIdx = -1; + mAnmPanes[5].activeIdx = -1; + mAnmPanes[6].activeIdx = -1; + mAnmPanes[7].activeIdx = -1; + mAnmPanes[8].activeIdx = -1; + mAnmPanes[9].activeIdx = -1; + } + } + + if (mAnimationState == 1 || mAnimationState == 2) { + if (!unk04) { + mpLayout->startDynAnmOut(playerIdx); + mAnimationState = 3; + } + } + + if (mAnimationState == 1) { + if (mpLayout->isFinishedDynAnmIn()) { + mAnimationState = 2; + } + } + + if (mAnimationState == 3) { + if (mpLayout->isFinishedDynAnmOut()) { + mAnimationState = 0; + } + } + + PowerThrowsRoundPane* pPane = mAnmPanes; + for (int i = 0; i < 10; i++, pPane++) { + s32 anmVal = pContext->unkC60 % 4; + + if (pPane->activeIdx != anmVal) { + if (pPane->activeIdx >= 0) { + RPSysLayout::unbindAnmObjToPane( + pPane->anmObjs[pPane->activeIdx], + pPane->pane1, + true + ); + } + + RPSysLayout::bindAnmObjToPane(pPane->anmObjs[anmVal], pPane->pane1, true); + + RPSysLytAnmObj* pAnm = pPane->anmObjs[anmVal]; + pAnm->setFrame(pAnm->getStartFrame()); + pAnm->setFlags(0); + pAnm->setEnabled(1); + + pPane->activeIdx = anmVal; + } + } + + for (int j = 0; j < 10; j++) { + PowerThrowsRoundPane* pPaneRev = &mAnmPanes[9 - j]; + if (j < pContext->field_0xC40) { + pPaneRev->pane1->SetVisible(false); + } else { + pPaneRev->pane1->SetVisible(true); + } + } + + for (int j = 0; j < 10; j++) { + PowerThrowsRoundPane* pPaneRev = &mAnmPanes[9 - j]; + if (j < pContext->field_0xC40 && pContext->unkC45[j] != 0) { + pPaneRev->pane2->SetVisible(true); + } else { + pPaneRev->pane2->SetVisible(false); + } + } + + s32 score = pContext->unkC50; + u32 msgIdx = !RPSysStringUtility::IsSingular(score); + + wchar_t buffer[32]; + RPSysStringUtility::GetStringHalfSizeNumber(score, buffer, 32, false); + + mpTextBoxes[msgIdx][0]->setMessage(mpMessage, 0x6720, msgIdx, 1, buffer); + mpTextBoxes[msgIdx][1]->setMessage(mpMessage, 0x6720, msgIdx, 1, buffer); + + u32 otherIdx = 1 - msgIdx; + mpTextBoxes[msgIdx][0]->SetVisible(true); + mpTextBoxes[msgIdx][1]->SetVisible(true); + mpTextBoxes[otherIdx][0]->SetVisible(false); + mpTextBoxes[otherIdx][1]->SetVisible(false); + + mpLayout->calc(); +} + +/** + * @brief Draws the layout + */ +void RPBowPowerThrowsRoundsLayout::Draw() { + mpLayout->draw(); +} + +/** + * @brief Tests whether the layout animation has finished + * + * @return True if animation state is 0, false otherwise + */ +bool RPBowPowerThrowsRoundsLayout::IsFinished() const { + return mAnimationState == 0; +} diff --git a/src/Pack/RPSports/RPBowScene/RPBowRegularPinManager.cpp b/src/Pack/RPSports/RPBowScene/RPBowRegularPinManager.cpp new file mode 100644 index 000000000..55aca084f --- /dev/null +++ b/src/Pack/RPSports/RPBowScene/RPBowRegularPinManager.cpp @@ -0,0 +1,246 @@ +#include + +// Extern functions: +bool fn_801C3490(nw4r::math::MTX34* pMtxA, nw4r::math::VEC3* pPos); + +extern char lbl_803C5428[]; +extern char lbl_803C5418[]; + +/** + * @brief Destructor + */ +RPBowRegularPinManager::~RPBowRegularPinManager() {} + +/** + * @brief Initializes the main pin models + * + * @param pRealModel Physical scene model + * @param pReflectionModel Reflection visual model + */ +void RPBowRegularPinManager::InitializeModels(RPGrpModel* pRealModel, RPGrpModel* pReflectionModel) { + mModels[0] = pRealModel; + mModels[1] = pReflectionModel; + + mModels[0]->SetCallback(this); + + if (mModels[1] != NULL) { + mModels[1]->SetCallback(this); + } + + mModels[0]->CreateBoundingInfo(1); +} + +/** + * @brief Stub + */ +void RPBowRegularPinManager::fn_8034F440() { + ; +} + +/** + * @brief Calculates bounding volume and shadow rendering matrices + */ +void RPBowRegularPinManager::Calc() { + nw4r::math::MTX34 mtx; + nw4r::math::MTX34Identity(&mtx); + + if (mUseShadows == 0) { + mpShadowTexture->AddModel(mModels[0], 1.0f); + + nw4r::math::VEC3 minBox(0.0f, 0.0f, 0.0f); + nw4r::math::VEC3 maxBox(0.0f, 0.0f, 0.0f); + + for (int i = 0; i < 10; i++) { + nw4r::math::VEC3 pos( + mMatrices[i][0]._03, + mMatrices[i][0]._13, + mMatrices[i][0]._23 + ); + + if (i == 0 || minBox.x > pos.x) minBox.x = pos.x; + if (i == 0 || minBox.y > pos.y) minBox.y = pos.y; + if (i == 0 || minBox.z > pos.z) minBox.z = pos.z; + + if (i == 0 || maxBox.x < pos.x) maxBox.x = pos.x; + if (i == 0 || maxBox.y < pos.y) maxBox.y = pos.y; + if (i == 0 || maxBox.z < pos.z) maxBox.z = pos.z; + } + + nw4r::math::VEC3 center = (minBox + maxBox) * 0.5f; + + float maxDist = 0.0f; + for (int i = 0; i < 10; i++) { + nw4r::math::VEC3 pos( + mMatrices[i][0]._03, + mMatrices[i][0]._13, + mMatrices[i][0]._23 + ); + + nw4r::math::VEC3 diff = pos - center; + float dist = nw4r::math::VEC3Len(&diff); + + if (maxDist < dist) { + maxDist = dist; + } + } + + if ((4.0f + maxDist) * 0.5f < 0.0f) { + system_halt(lbl_803C5428, 191, lbl_803C5418); + } + + // TODO: 0x74 is part of unknown block in eggShadowTexture.h + *reinterpret_cast((u8*)mpShadowTexture + 0x74) = (4.0f + maxDist) * 0.5f; + + mtx._03 = center.x; + mtx._13 = center.y; + mtx._23 = center.z; + } + + for (int i = 0; i < 2; i++) { + if (mModels[i] != NULL) { + if (mModels[i]->GetModelEx()->getScnObj() != 0) { + mModels[i]->GetScnObj()->SetMtx(nw4r::g3d::ScnObj::MTX_LOCAL, &mtx); + } + } + + mModels[i]->UpdateFrame(); + mModels[i]->Calc(); + mModels[i]->Entry(); + } +} + +/** + * @brief Stub + */ +void RPBowRegularPinManager::fn_8034F164() { + ; +} + +/** + * @brief Copies transformation matrices out to the target model + * + * @param pModel Target render model + */ +void RPBowRegularPinManager::CopyMatricesToModel(RPGrpModel* pModel) { + for (int j = 0; j < 2; j++) { + if (pModel == mModels[j]) { + for (u16 i = 0; i < 10; i++) { + nw4r::math::MTX34* pOutMtx = pModel->ReferWorldMtx(i + 1); + *pOutMtx = mMatrices[i][j]; + } + } + } +} + +/** + * @brief Calculates individual transforms for regular pin positioning + * + * @param index Pin index + * @param yOffset Y-axis position offset + * @param pMtxA First check matrix + * @param pMtxB Second transform matrix + * @param pMtxC Third reference matrix + */ +void RPBowRegularPinManager::CalculatePinTransforms(int index, f32 yOffset, nw4r::math::MTX34* pMtxA, nw4r::math::MTX34* pMtxB, nw4r::math::MTX34* pMtxC) { + nw4r::math::VEC3 checkVecs[6]; + + nw4r::math::MTX34 transMtx1( + 1.0f, 0.0f, 0.0f, 0.0f, + 0.0f, 1.0f, 0.0f, -yOffset, + 0.0f, 0.0f, 1.0f, 0.0f + ); + + nw4r::math::MTX34 outMtx1; + nw4r::math::MTX34Mult(&outMtx1, pMtxB, &transMtx1); + + nw4r::math::VEC3 pos1(outMtx1._03, outMtx1._13, outMtx1._23); + + if (!fn_801C3490(pMtxA, &pos1)) { + nw4r::math::MTX34 dummyMtx1( + 0.0f, 0.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 0.0f, -193.0f + ); + mMatrices[index][0] = dummyMtx1; + } else { + mMatrices[index][0] = outMtx1; + } + + if (pMtxB->_23 < -196.0f) { + nw4r::math::MTX34 dummyMtx2( + 0.0f, 0.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 0.0f, -193.0f + ); + mMatrices[index][1] = dummyMtx2; + return; + } + + nw4r::math::MTX34 localMtxB = *pMtxB; + localMtxB._10 *= -1.0f; + localMtxB._11 *= -1.0f; + localMtxB._12 *= -1.0f; + localMtxB._13 *= -1.0f; + + nw4r::math::MTX34 transMtx2( + 1.0f, 0.0f, 0.0f, 0.0f, + 0.0f, 1.0f, 0.0f, -yOffset, + 0.0f, 0.0f, 1.0f, 0.0f + ); + + nw4r::math::MTX34 outMtx2; + nw4r::math::MTX34Mult(&outMtx2, &localMtxB, &transMtx2); + + if (pMtxC != NULL) { + checkVecs[0] = nw4r::math::VEC3(0.0f, 0.6f, 0.0f); + checkVecs[1] = nw4r::math::VEC3(0.0f, 1.2f, 0.0f); + checkVecs[2] = nw4r::math::VEC3(0.0f, 1.8f, 0.0f); + checkVecs[3] = nw4r::math::VEC3(0.0f, 2.4f, 0.0f); + checkVecs[4] = nw4r::math::VEC3(0.0f, 2.9f, 0.0f); + checkVecs[5] = nw4r::math::VEC3(0.0f, 3.3f, 0.0f); + + f32 minDiff = 0.0f; + for (int i = 0; i < 6; i++) { + nw4r::math::VEC3 outVec; + nw4r::math::VEC3Transform(&outVec, &outMtx2, &checkVecs[i]); + + if (outVec.y > -0.6f && outVec.z > -191.4f) { + f32 diff = -0.6f - outVec.y; + if (minDiff > diff) { + minDiff = diff; + } + } + } + outMtx2._13 += minDiff; + } + + nw4r::math::VEC3 pos2(outMtx2._03, outMtx2._13, outMtx2._23); + + if (!fn_801C3490(pMtxA, &pos2)) { + nw4r::math::MTX34 dummyMtx3( + 0.0f, 0.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 0.0f, -193.0f + ); + mMatrices[index][1] = dummyMtx3; + } else { + mMatrices[index][1] = outMtx2; + } +} + +/** + * @brief Hides excess pins when fewer than 10 are active + * + * @param count Number of active pins to leave visible + */ +void RPBowRegularPinManager::HideExcessPins(int count) { + f32 f2 = (count == 0) ? 0.0f : mMatrices[0][0]._03; + + for (int i = count; i < 10; i++) { + nw4r::math::MTX34 mtx1(0.0f, 0.0f, 0.0f, f2, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, -193.0f); + mMatrices[i][0] = mtx1; + + nw4r::math::MTX34 mtx2(0.0f, 0.0f, 0.0f, f2, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, -193.0f); + mMatrices[i][1] = mtx2; + } +} diff --git a/src/Pack/RPSports/RPBowScene/RPBowScoreLayout.cpp b/src/Pack/RPSports/RPBowScene/RPBowScoreLayout.cpp new file mode 100644 index 000000000..fd29892ba --- /dev/null +++ b/src/Pack/RPSports/RPBowScene/RPBowScoreLayout.cpp @@ -0,0 +1,118 @@ +#include + +/** + * @brief Destructor + */ +RPBowScoreLayout::~RPBowScoreLayout() {} + +/** + * @brief Initializes the player icons for the score layout + */ +void RPBowScoreLayout::InitIcons() { + for (int i = 0; i < 4; i++) { + RPSysKokeshiGenInfo info; + GXColor color = {0, 0, 0, 0}; + + info.SetGenType(RPSysKokeshiManager::GenType_Player); + info.SetPlayerNo(i); + info.SetIconWidth(48); + info.SetIconHeight(48); + info.SetIconBGType((RFLIconBGType)1); + info.SetIconBGColor(color); + info.SetIconMipMap(true); + + mpIcons[i] = new RPSysKokeshiIcon(&info); + } + unkBC0 = 50.0f; + unkBC4 = -50.0f; +} + +/** + * @brief Initializes the main scoring layout elements + * + * @param pAcc Layout resource accessor + * @param unk Unknown configuration parameter + */ +void RPBowScoreLayout::Init(RPSysLytResAccessor* pAcc, u32 unk) { + unkB7C = unk; + mpLayout = RPSysLayout::create(NULL, pAcc, "score_00.brlyt"); + + char buf[64]; + for (int i = 0; i < 10; i++) { + sprintf(buf, "P_frameBG%02d_00", i + 1); + mpFrameBGP[i] = mpLayout->findPane(buf); + + sprintf(buf, "T_frame%02d_00", i + 1); + mpFrameT[i] = mpLayout->findTextBox(buf); + } + + mpFrameBGP[10] = mpLayout->findPane("P_frameBG10_01"); + mpFrameT[10] = mpLayout->findTextBox("T_frame10_01"); + + for (int i = 0; i < 4; i++) { + sprintf(buf, "P_playerBG_%02d", i); + mpPlayerBGP[i] = mpLayout->findPicture(buf); + } + + mpScoreRootP = mpLayout->findPane("N_scoreRoot_00"); + mScoreRoot.x = mpScoreRootP->GetTranslate().x; + mScoreRoot.y = mpScoreRootP->GetTranslate().y; + mScoreRoot.z = mpScoreRootP->GetTranslate().z; + mpRootPane = mpLayout->findPane("RootPane"); + + for (int p = 0; p < 4; p++) { + for (int f = 0; f < 11; f++) { + if (f < 9) { + mFrames[p][f].layout = RPSysLayout::create(NULL, pAcc, "score_01.brlyt"); + } else { + mFrames[p][f].layout = RPSysLayout::create(NULL, pAcc, "score_02.brlyt"); + } + + mFrames[p][f].scoreBG = mFrames[p][f].layout->findPane("P_scoreBG_00"); + mFrames[p][f].rootPane = mFrames[p][f].layout->findPane("RootPane"); + mFrames[p][f].alpha = mFrames[p][f].scoreBG->GetAlpha(); + + mFrames[p][f].rootX = mpFrameBGP[f]->GetTranslate().x; + mFrames[p][f].rootY = mpPlayerBGP[p]->GetTranslate().y; + + for (int t = 0; t < 3; t++) { + sprintf(buf, "T_throw%d_00", t + 1); + mFrames[p][f].throwT[t] = mFrames[p][f].layout->findTextBox(buf); + + sprintf(buf, "P_strike%d_00", t + 1); + mFrames[p][f].strikeP[t] = mFrames[p][f].layout->findPane(buf); + + sprintf(buf, "P_spare%d_00", t + 1); + mFrames[p][f].spareP[t] = mFrames[p][f].layout->findPane(buf); + } + + mFrames[p][f].totalT = mFrames[p][f].layout->findTextBox("T_total_00"); + } + } + + for (int p = 0; p < 4; p++) { + sprintf(buf, "N_playerIcon_%02d", p); + mpPlayerIconP[p] = mpLayout->findPane(buf); + mpIcons[p]->LoadResource(NULL); + } + + unkBCC = 0; +} + +/** + * @brief Resets the layout components and state tracking variables + */ +void RPBowScoreLayout::Reset() { + mpLayout->reset(); + + for (int p = 0; p < 4; p++) { + for (int f = 0; f < 10; f++) { + mFrames[p][f].layout->reset(); + } + } + + unkBA4 = 0; + unkBA0 = 0; + unkBA8 = 0; + unkBCC = 0; +} diff --git a/src/Pack/RPSports/RPBowScene/RPBowTrainingLivesLayout.cpp b/src/Pack/RPSports/RPBowScene/RPBowTrainingLivesLayout.cpp new file mode 100644 index 000000000..df096af5b --- /dev/null +++ b/src/Pack/RPSports/RPBowScene/RPBowTrainingLivesLayout.cpp @@ -0,0 +1,182 @@ +#include + +/** + * @brief Destructor + */ +RPBowTrainingLivesLayout::~RPBowTrainingLivesLayout() {} + +/** + * @brief Initializes the training lives layout + * + * @param pAcc Layout resource accessor + */ +void RPBowTrainingLivesLayout::Init(RPSysLytResAccessor* pAcc) { + mpLayout = RPSysLayout::create(NULL, pAcc, "bwgCount_00.brlyt"); + mpRootPane = mpLayout->findPane("RootPane"); + + char buf[64]; + TrainingLifePane* pPane = mAnmPanes; + for (int i = 0; i < 5; i++, pPane++) { + pPane->bigBallObj = mpLayout->createAnmObj(NULL, pAcc, "bwgCount_00_bigBall_00.brlan"); + pPane->smallBallObj = mpLayout->createAnmObj(NULL, pAcc, "bwgCount_00_smallBall_00.brlan"); + + sprintf(buf, "N_ball_%02d", i); + pPane->pane = mpLayout->findPane(buf); + + for (int j = 0; j < 5; j++) { + sprintf(buf, "bwgCount_00_ballColor_%02d.brlan", j); + pPane->colors[j] = mpLayout->createAnmObj(NULL, pAcc, buf); + } + } + + mAnimationState = 0; +} + +/** + * @brief Resets the layout and animation objects + */ +void RPBowTrainingLivesLayout::Reset() { + mpLayout->reset(); + mpLayout->unbindAllAnmObj(); + mAnimationState = 0; + + mAnmPanes[0].activeIdx2 = -1; + mAnmPanes[0].activeIdx1 = -1; + mAnmPanes[1].activeIdx2 = -1; + mAnmPanes[1].activeIdx1 = -1; + mAnmPanes[2].activeIdx2 = -1; + mAnmPanes[2].activeIdx1 = -1; + mAnmPanes[3].activeIdx2 = -1; + mAnmPanes[3].activeIdx1 = -1; + mAnmPanes[4].activeIdx2 = -1; + mAnmPanes[4].activeIdx1 = -1; +} + +// Global lookup array referenced for scaling +extern nw4r::math::VEC2 lbl_803CADA8[2][2]; + +/** + * @brief Updates the training lives logic and pane states + * + * @param pContext Bowling scene context + */ +void RPBowTrainingLivesLayout::Update(SceneContext* pContext) { + int playerIdx = -pContext->mUnkC34; + + if (mAnimationState == 0 || mAnimationState == 3) { + if (mUnk4) { + mpLayout->startDynAnmIn((short)playerIdx); + mAnimationState = 1; + mpLayout->unbindAllAnmObj(); + + mAnmPanes[0].activeIdx2 = -1; + mAnmPanes[0].activeIdx1 = -1; + mAnmPanes[1].activeIdx2 = -1; + mAnmPanes[1].activeIdx1 = -1; + mAnmPanes[2].activeIdx2 = -1; + mAnmPanes[2].activeIdx1 = -1; + mAnmPanes[3].activeIdx2 = -1; + mAnmPanes[3].activeIdx1 = -1; + mAnmPanes[4].activeIdx2 = -1; + mAnmPanes[4].activeIdx1 = -1; + } + } + + if (mAnimationState == 1 || mAnimationState == 2) { + if (!mUnk4) { + mpLayout->startDynAnmOut((short)playerIdx); + mAnimationState = 3; + } + } + + if (mAnimationState == 1) { + if (mpLayout->isFinishedDynAnmIn()) { + mAnimationState = 2; + } + } + if (mAnimationState == 3) { + if (mpLayout->isFinishedDynAnmOut()) { + mAnimationState = 0; + } + } + + TrainingLifePane* pPaneBase = mAnmPanes; + TrainingLifePane* pPane = pPaneBase; + + for (int i = 0; i < 5; i++, pPane++) { + s32 anmVal1 = 1; + if (i == pContext->field_0xC40) { + anmVal1 = 0; + } + + if (pPane->activeIdx1 != anmVal1) { + if (pPane->activeIdx1 >= 0) { + RPSysLayout::unbindAnmObjToPane( + ((RPSysLytAnmObj**)pPane)[pPane->activeIdx1], + pPane->pane, true); + } + + RPSysLayout::bindAnmObjToPane(((RPSysLytAnmObj**)pPane)[anmVal1], pPane->pane, true); + + s16 len = ((RPSysLytAnmObj**)pPane)[anmVal1]->getStartFrame(); + ((RPSysLytAnmObj**)pPane)[anmVal1]->setFrame(len); + ((RPSysLytAnmObj**)pPane)[anmVal1]->setFlags(0); + ((RPSysLytAnmObj**)pPane)[anmVal1]->setEnabled(1); + + pPane->activeIdx1 = anmVal1; + } + } + + for (int j = 0; j < 5; j++, pPaneBase++) { + s32 anmVal2; + if (j < pContext->field_0xC40) { + anmVal2 = 0; + } else { + anmVal2 = (pContext->unkC60 % 4) + 1; + } + + if (pPaneBase->activeIdx2 != anmVal2) { + if (pPaneBase->activeIdx2 >= 0) { + RPSysLayout::unbindAnmObjToPane( + pPaneBase->colors[pPaneBase->activeIdx2], + pPaneBase->pane, + true + ); + } + + RPSysLayout::bindAnmObjToPane(pPaneBase->colors[anmVal2], pPaneBase->pane, true); + + s16 len2 = pPaneBase->colors[anmVal2]->getStartFrame(); + pPaneBase->colors[anmVal2]->setFrame(len2); + pPaneBase->colors[anmVal2]->setFlags(0); + pPaneBase->colors[anmVal2]->setEnabled(1); + + pPaneBase->activeIdx2 = anmVal2; + } + } + + int tvIdx = (EGG::Screen::GetTVMode() != EGG::Screen::TV_MODE_STD); + int typeIdx = pContext->mUnkC1C; + + f32* pFloats = (f32*)lbl_803CADA8[tvIdx]; + volatile f32 dummyX = pFloats[typeIdx * 2]; + volatile f32 dummyY = pFloats[typeIdx * 2 + 1]; + + mpLayout->calc(); +} + +/** + * @brief Draws the layout + */ +void RPBowTrainingLivesLayout::Draw() { + mpLayout->draw(); +} + +/** + * @brief Tests whether the layout animation has finished + * + * @return True if animation state is 0, false otherwise + */ +bool RPBowTrainingLivesLayout::IsFinished() const { + return mAnimationState == 0; +} diff --git a/src/Pack/RPSports/RPBowScene/RPBowTrajectoryGuide.cpp b/src/Pack/RPSports/RPBowScene/RPBowTrajectoryGuide.cpp index 2c59b0850..58f47f6a0 100644 --- a/src/Pack/RPSports/RPBowScene/RPBowTrajectoryGuide.cpp +++ b/src/Pack/RPSports/RPBowScene/RPBowTrajectoryGuide.cpp @@ -1,7 +1,5 @@ #include -namespace Bowling { - /** * @brief Updates the controller state bitmask * @@ -130,5 +128,3 @@ void RPBowTrajectoryGuide::Draw() { mpDotModels[i]->Entry(); } } - -} // namespace Bowling