summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorelijah-thomas774 <elijahthomas774@gmail.com>2026-10-19 13:13:46 -0400
committerelijah-thomas774 <elijahthomas774@gmail.com>2026-10-19 13:13:46 -0400
commitffe45f52ac6f4e1bccf0ed306c2d870e5fdee9cb (patch)
tree1c3374a59ed1193a1cbdb5264bf8848fbdc58499
parent5633a09e0223ddcea4fd0bb2cc79a126d3816182 (diff)
parentd418bd839cd6cc8f98c0c7976d006159e9e6ee28 (diff)
Merge remote-tracking branch 'upstream/HEAD' into bases
-rw-r--r--config/SOUE01/rels/d_a_obj_control_panelNP/symbols.txt196
-rw-r--r--config/SOUE01/symbols.txt8
-rw-r--r--include/d/a/obj/d_a_obj_D3_dummy.h12
-rw-r--r--include/d/a/obj/d_a_obj_control_panel.h125
-rw-r--r--include/d/lyt/msg_window/d_lyt_msg_window.h4
-rw-r--r--include/toBeSorted/misc_actor.h5
-rw-r--r--src/REL/d/a/obj/d_a_obj_control_panel.cpp825
7 files changed, 1077 insertions, 98 deletions
diff --git a/config/SOUE01/rels/d_a_obj_control_panelNP/symbols.txt b/config/SOUE01/rels/d_a_obj_control_panelNP/symbols.txt
index 33f368ca..5b699ef0 100644
--- a/config/SOUE01/rels/d_a_obj_control_panelNP/symbols.txt
+++ b/config/SOUE01/rels/d_a_obj_control_panelNP/symbols.txt
@@ -3,30 +3,26 @@ _epilog = .text:0x00000030; // type:function size:0x2C scope:global
_unresolved = .text:0x00000060; // type:function size:0x4 scope:global
__register_global_object = .text:0x00000070; // type:function size:0x1C scope:global
__destroy_global_chain = .text:0x00000090; // type:function size:0x54 scope:global
-fn_598_F0 = .text:0x000000F0; // type:function size:0x40
+__dt__7mVec3_cFv = .text:0x000000F0; // type:function size:0x40
dAcOCtrlPnl_c_classInit__Fv = .text:0x00000130; // type:function size:0x154
-fn_598_290 = .text:0x00000290; // type:function size:0x4
+__ct__7mVec3_cFv = .text:0x00000290; // type:function size:0x4
__dt__26sFState_c<13dAcOCtrlPnl_c>Fv = .text:0x000002A0; // type:function size:0x58
__dt__29sFStateFct_c<13dAcOCtrlPnl_c>Fv = .text:0x00000300; // type:function size:0x6C
__dt__82sStateMgr_c<13dAcOCtrlPnl_c,20sStateMethodUsr_FI_c,12sFStateFct_c,13sStateIDChk_c>Fv = .text:0x00000370; // type:function size:0xA0
__dt__52sFStateMgr_c<13dAcOCtrlPnl_c,20sStateMethodUsr_FI_c>Fv = .text:0x00000410; // type:function size:0xA4
-fn_598_4C0 = .text:0x000004C0; // type:function size:0x74
-fn_598_540 = .text:0x00000540; // type:function size:0xC
-fn_598_54C = .text:0x0000054C; // type:function size:0x4
-fn_598_550 = .text:0x00000550; // type:function size:0xC
-fn_598_55C = .text:0x0000055C; // type:function size:0x4
-fn_598_560 = .text:0x00000560; // type:function size:0xC
-fn_598_56C = .text:0x0000056C; // type:function size:0x4
-fn_598_570 = .text:0x00000570; // type:function size:0xC
-fn_598_57C = .text:0x0000057C; // type:function size:0x4
-AcOControlPanel__initModels = .text:0x00000580; // type:function size:0xD4
-AcOControlPanel__init = .text:0x00000660; // type:function size:0x210
+__dt__Q213dAcOCtrlPnl_c10callback_cFv = .text:0x000004C0; // type:function size:0x74
+enterMoveCb__FPv = .text:0x00000540; // type:function size:0x10
+finishMoveCb__FPv = .text:0x00000550; // type:function size:0x10
+afterControlPanelFirstCb__FPv = .text:0x00000560; // type:function size:0x10
+afterControlPanelCb__FPv = .text:0x00000570; // type:function size:0x10
+createHeap__13dAcOCtrlPnl_cFv = .text:0x00000580; // type:function size:0xD4
+actorCreate__13dAcOCtrlPnl_cFv = .text:0x00000660; // type:function size:0x210
changeState__82sStateMgr_c<13dAcOCtrlPnl_c,20sStateMethodUsr_FI_c,12sFStateFct_c,13sStateIDChk_c>FRC12sStateIDIf_c = .text:0x00000870; // type:function size:0x10
-AcOControlPanel__init2 = .text:0x00000880; // type:function size:0x12C
-fn_598_9B0 = .text:0x000009B0; // type:function size:0x14
-AcOControlPanel__update = .text:0x000009D0; // type:function size:0x100
+actorPostCreate__13dAcOCtrlPnl_cFv = .text:0x00000880; // type:function size:0x12C
+doDelete__13dAcOCtrlPnl_cFv = .text:0x000009B0; // type:function size:0x14
+actorExecute__13dAcOCtrlPnl_cFv = .text:0x000009D0; // type:function size:0x100
executeState__82sStateMgr_c<13dAcOCtrlPnl_c,20sStateMethodUsr_FI_c,12sFStateFct_c,13sStateIDChk_c>Fv = .text:0x00000AD0; // type:function size:0x10
-AcOControlPanel__draw = .text:0x00000AE0; // type:function size:0x28
+draw__13dAcOCtrlPnl_cFv = .text:0x00000AE0; // type:function size:0x28
initializeState_Wait__13dAcOCtrlPnl_cFv = .text:0x00000B10; // type:function size:0x4
executeState_Wait__13dAcOCtrlPnl_cFv = .text:0x00000B20; // type:function size:0x84
finalizeState_Wait__13dAcOCtrlPnl_cFv = .text:0x00000BB0; // type:function size:0x4
@@ -36,34 +32,34 @@ finalizeState_Control__13dAcOCtrlPnl_cFv = .text:0x00000D70; // type:function si
initializeState_EndEvent__13dAcOCtrlPnl_cFv = .text:0x00000D80; // type:function size:0x4
executeState_EndEvent__13dAcOCtrlPnl_cFv = .text:0x00000D90; // type:function size:0x4
finalizeState_EndEvent__13dAcOCtrlPnl_cFv = .text:0x00000DA0; // type:function size:0x20
-fn_598_DC0 = .text:0x00000DC0; // type:function size:0x80
-fn_598_E40 = .text:0x00000E40; // type:function size:0x60
-fn_598_EA0 = .text:0x00000EA0; // type:function size:0xB0
-fn_598_F50 = .text:0x00000F50; // type:function size:0x18
-fn_598_F70 = .text:0x00000F70; // type:function size:0x18
-fn_598_F90 = .text:0x00000F90; // type:function size:0x6C
-fn_598_1000 = .text:0x00001000; // type:function size:0xB8
-fn_598_10C0 = .text:0x000010C0; // type:function size:0x2C
-fn_598_10F0 = .text:0x000010F0; // type:function size:0x1D4
-fn_598_12D0 = .text:0x000012D0; // type:function size:0x134
-fn_598_1410 = .text:0x00001410; // type:function size:0x228
-fn_598_1640 = .text:0x00001640; // type:function size:0x5E8
-fn_598_1C30 = .text:0x00001C30; // type:function size:0x198
-fn_598_1DD0 = .text:0x00001DD0; // type:function size:0x168
-fn_598_1F40 = .text:0x00001F40; // type:function size:0xD4
-AcOControlPanel__updatePuzzleFromFile = .text:0x00002020; // type:function size:0xA8
-fn_598_20D0 = .text:0x000020D0; // type:function size:0x24
-fn_598_2100 = .text:0x00002100; // type:function size:0x1C
-fn_598_2120 = .text:0x00002120; // type:function size:0x4C
-AcOControlPanel__savePuzzleState = .text:0x00002170; // type:function size:0x60
-fn_598_21D0 = .text:0x000021D0; // type:function size:0xC0
-fn_598_2290 = .text:0x00002290; // type:function size:0x4C
-AcOControlPanel__isFirstTime = .text:0x000022E0; // type:function size:0x90
-AcOControlPanel__changedPuzzle = .text:0x00002370; // type:function size:0x6C
-fn_598_23E0 = .text:0x000023E0; // type:function size:0x98
-fn_598_2480 = .text:0x00002480; // type:function size:0x38
-fn_598_24C0 = .text:0x000024C0; // type:function size:0x1EC
-fn_598_26B0 = .text:0x000026B0; // type:function size:0x34C
+doInteraction__13dAcOCtrlPnl_cFl = .text:0x00000DC0; // type:function size:0x80
+enterMove__13dAcOCtrlPnl_cFv = .text:0x00000E40; // type:function size:0x60
+finishMove__13dAcOCtrlPnl_cFv = .text:0x00000EA0; // type:function size:0xB0
+afterControlPanelFirst__13dAcOCtrlPnl_cFv = .text:0x00000F50; // type:function size:0x18
+afterControlPanel__13dAcOCtrlPnl_cFv = .text:0x00000F70; // type:function size:0x18
+handleSlidingTile__13dAcOCtrlPnl_cFv = .text:0x00000F90; // type:function size:0x6C
+updateTileScales__13dAcOCtrlPnl_cFv = .text:0x00001000; // type:function size:0xB8
+hasAdjacentEmptySpot__13dAcOCtrlPnl_cFl = .text:0x000010C0; // type:function size:0x2C
+getAdjacentEmptySpot__13dAcOCtrlPnl_cFlPl = .text:0x000010F0; // type:function size:0x1D4
+setupNeighbors__13dAcOCtrlPnl_cFv = .text:0x000012D0; // type:function size:0x134
+handleEvent__13dAcOCtrlPnl_cFv = .text:0x00001410; // type:function size:0x228
+handleControl__13dAcOCtrlPnl_cFv = .text:0x00001640; // type:function size:0x5E8
+updateDoorSceneflags__13dAcOCtrlPnl_cFv = .text:0x00001C30; // type:function size:0x198
+getSpotForCursor__13dAcOCtrlPnl_cFR7mVec2_c = .text:0x00001DD0; // type:function size:0x168
+getMoveDirection__13dAcOCtrlPnl_cFll = .text:0x00001F40; // type:function size:0xD4
+updatePuzzleFromFile__13dAcOCtrlPnl_cFv = .text:0x00002020; // type:function size:0xA8
+setTileID__13dAcOCtrlPnl_cFUlUl = .text:0x000020D0; // type:function size:0x24
+getTileID__13dAcOCtrlPnl_cFUl = .text:0x00002100; // type:function size:0x1C
+resetPuzzleState__13dAcOCtrlPnl_cFv = .text:0x00002120; // type:function size:0x4C
+savePuzzleState__13dAcOCtrlPnl_cFv = .text:0x00002170; // type:function size:0x60
+updateTilePositions__13dAcOCtrlPnl_cFv = .text:0x000021D0; // type:function size:0xC0
+updateSpotTilesFromPuzzle__13dAcOCtrlPnl_cFv = .text:0x00002290; // type:function size:0x4C
+isFirstTime__13dAcOCtrlPnl_cFv = .text:0x000022E0; // type:function size:0x90
+changedPuzzle__13dAcOCtrlPnl_cFv = .text:0x00002370; // type:function size:0x6C
+getScreenCenter__13dAcOCtrlPnl_cFR7mVec3_c = .text:0x000023E0; // type:function size:0x98
+setLinkVisibility__13dAcOCtrlPnl_cFb = .text:0x00002480; // type:function size:0x38
+timingB__Q213dAcOCtrlPnl_c10callback_cFUlPQ34nw4r3g3d13WorldMtxManipQ34nw4r3g3d6ResMdl = .text:0x000024C0; // type:function size:0x1EC
+updateTileColors__13dAcOCtrlPnl_cFv = .text:0x000026B0; // type:function size:0x34C
__dt__13dAcOCtrlPnl_cFv = .text:0x00002A00; // type:function size:0x144
getStateID__82sStateMgr_c<13dAcOCtrlPnl_c,20sStateMethodUsr_FI_c,12sFStateFct_c,13sStateIDChk_c>CFv = .text:0x00002B50; // type:function size:0x10
build__29sFStateFct_c<13dAcOCtrlPnl_c>FRC12sStateIDIf_c = .text:0x00002B60; // type:function size:0x60
@@ -86,55 +82,83 @@ isSameName__28sFStateID_c<13dAcOCtrlPnl_c>CFPCc = .text:0x00003090; // type:func
_ctors = .ctors:0x00000000; // type:label scope:global
_dtors = .dtors:0x00000000; // type:label scope:global
__destroy_global_chain_reference = .dtors:0x00000000; // type:object size:0x4 scope:global
-lbl_598_rodata_0 = .rodata:0x00000000; // type:object size:0x58 data:float
+unused = .rodata:0x00000000; // type:object size:0x28 data:float
+lbl_598_rodata_28 = .rodata:0x00000028; // type:object size:0x20 align:4
+lbl_598_rodata_48 = .rodata:0x00000048; // type:object size:0x4 align:4 data:float
+lbl_598_rodata_4C = .rodata:0x0000004C; // type:object size:0x4 align:4 data:float
+lbl_598_rodata_50 = .rodata:0x00000050; // type:object size:0x4 align:4 data:float
+lbl_598_rodata_54 = .rodata:0x00000054; // type:object size:0x4 align:4 data:float
lbl_598_rodata_58 = .rodata:0x00000058; // type:object size:0x18 align:4 data:float
lbl_598_rodata_70 = .rodata:0x00000070; // type:object size:0x4 align:4 data:float
lbl_598_rodata_74 = .rodata:0x00000074; // type:object size:0x4 align:4 data:float
lbl_598_rodata_78 = .rodata:0x00000078; // type:object size:0x4 align:4 data:float
lbl_598_rodata_7C = .rodata:0x0000007C; // type:object size:0x1C align:4 data:float
lbl_598_rodata_98 = .rodata:0x00000098; // type:object size:0x4 align:4 data:float
-lbl_598_rodata_A0 = .rodata:0x000000A0; // type:object size:0x44 align:8
-s_ControlPanel_80f19b70 = .data:0x00000000; // type:object size:0x10 data:4byte
-lbl_598_data_10 = .data:0x00000010; // type:object size:0x4 data:4byte
-lbl_598_data_14 = .data:0x00000014; // type:object size:0x17 data:string
-lbl_598_data_30 = .data:0x00000030; // type:object size:0x12 data:string
-lbl_598_data_48 = .data:0x00000048; // type:object size:0x7 data:string
-lbl_598_data_50 = .data:0x00000050; // type:object size:0x7 data:string
-lbl_598_data_58 = .data:0x00000058; // type:object size:0x7 data:string
-lbl_598_data_60 = .data:0x00000060; // type:object size:0x7 data:string
-lbl_598_data_68 = .data:0x00000068; // type:object size:0x7 data:string
-lbl_598_data_70 = .data:0x00000070; // type:object size:0x7 data:string
-lbl_598_data_78 = .data:0x00000078; // type:object size:0x7 data:string
-lbl_598_data_80 = .data:0x00000080; // type:object size:0x7 data:string
-lbl_598_data_A8 = .data:0x000000A8; // type:object size:0x30
+lbl_598_rodata_A0 = .rodata:0x000000A0; // type:object size:0x8 align:8 data:float
+lbl_598_rodata_A8 = .rodata:0x000000A8; // type:object size:0x4 align:4
+lbl_598_rodata_AC = .rodata:0x000000AC; // type:object size:0x4 align:4
+lbl_598_rodata_B0 = .rodata:0x000000B0; // type:object size:0x4 align:4
+lbl_598_rodata_B4 = .rodata:0x000000B4; // type:object size:0x4 align:4 data:float
+lbl_598_rodata_B8 = .rodata:0x000000B8; // type:object size:0x4 align:4 data:float
+lbl_598_rodata_C0 = .rodata:0x000000C0; // type:object size:0x8 align:8 data:float
+lbl_598_rodata_C8 = .rodata:0x000000C8; // type:object size:0x4 align:4 data:float
+lbl_598_rodata_CC = .rodata:0x000000CC; // type:object size:0x4 align:4 data:float
+lbl_598_rodata_D0 = .rodata:0x000000D0; // type:object size:0x4 align:4 data:float
+lbl_598_rodata_D4 = .rodata:0x000000D4; // type:object size:0x4 align:4 data:float
+lbl_598_rodata_D8 = .rodata:0x000000D8; // type:object size:0x4 align:4 data:float
+lbl_598_rodata_DC = .rodata:0x000000DC; // type:object size:0x4 align:4 data:float
+lbl_598_rodata_E0 = .rodata:0x000000E0; // type:object size:0x4 align:4
+@33134 = .data:0x00000000; // type:object size:0x10 data:4byte
+eventName = .data:0x00000010; // type:object size:0x4 data:4byte
+@33462 = .data:0x00000014; // type:object size:0x17 data:string
+@33463 = .data:0x00000030; // type:object size:0x12 data:string
+@33115 = .data:0x00000048; // type:object size:0x7 data:string
+@33116 = .data:0x00000050; // type:object size:0x7 data:string
+@33117 = .data:0x00000058; // type:object size:0x7 data:string
+@33118 = .data:0x00000060; // type:object size:0x7 data:string
+@33119 = .data:0x00000068; // type:object size:0x7 data:string
+@33120 = .data:0x00000070; // type:object size:0x7 data:string
+@33121 = .data:0x00000078; // type:object size:0x7 data:string
+@33122 = .data:0x00000080; // type:object size:0x7 data:string
+interactionTarget = .data:0x000000A8; // type:object size:0x30
g_profile_OBJ_CONTROL_PANEL = .data:0x000000D8; // type:object size:0x10
-lbl_598_data_E8 = .data:0x000000E8; // type:object size:0xD data:string
-lbl_598_data_F8 = .data:0x000000F8; // type:object size:0x9 data:string
-lbl_598_data_104 = .data:0x00000104; // type:object size:0x9 data:string
-lbl_598_data_110 = .data:0x00000110; // type:object size:0x9 data:string
-lbl_598_data_11C = .data:0x0000011C; // type:object size:0x9 data:string
-lbl_598_data_128 = .data:0x00000128; // type:object size:0x9 data:string
-lbl_598_data_134 = .data:0x00000134; // type:object size:0x9 data:string
-lbl_598_data_140 = .data:0x00000140; // type:object size:0x9 data:string
-lbl_598_data_14C = .data:0x0000014C; // type:object size:0x9 data:string
-lbl_598_data_158 = .data:0x00000158; // type:object size:0x1B data:string
+@38836 = .data:0x000000E8; // type:object size:0xD data:string
+@33201 = .data:0x000000F8; // type:object size:0x9 data:string
+@33202 = .data:0x00000104; // type:object size:0x9 data:string
+@33203 = .data:0x00000110; // type:object size:0x9 data:string
+@33204 = .data:0x0000011C; // type:object size:0x9 data:string
+@33205 = .data:0x00000128; // type:object size:0x9 data:string
+@33206 = .data:0x00000134; // type:object size:0x9 data:string
+@33207 = .data:0x00000140; // type:object size:0x9 data:string
+@33208 = .data:0x0000014C; // type:object size:0x9 data:string
+@38879 = .data:0x00000158; // type:object size:0x1B data:string
lbl_598_data_174 = .data:0x00000174; // type:object size:0xB data:string
-lbl_598_data_180 = .data:0x00000180; // type:object size:0xB data:string
+@33235 = .data:0x00000180; // type:object size:0xB data:string
lbl_598_data_18C = .data:0x0000018C; // type:object size:0xB data:string
-lbl_598_data_198 = .data:0x00000198; // type:object size:0xB data:string
-lbl_598_data_1A4 = .data:0x000001A4; // type:object size:0xB data:string
-lbl_598_data_1B0 = .data:0x000001B0; // type:object size:0xB data:string
-lbl_598_data_1BC = .data:0x000001BC; // type:object size:0xB data:string
+@33237 = .data:0x00000198; // type:object size:0xB data:string
+@33238 = .data:0x000001A4; // type:object size:0xB data:string
+@33239 = .data:0x000001B0; // type:object size:0xB data:string
+@33240 = .data:0x000001BC; // type:object size:0xB data:string
lbl_598_data_1C8 = .data:0x000001C8; // type:object size:0x48
-AcOControlPanel__vtable = .data:0x00000210; // type:object size:0x80
-lbl_598_data_290 = .data:0x00000290; // type:object size:0x30
-lbl_598_data_2C0 = .data:0x000002C0; // type:object size:0x30
-lbl_598_data_2F0 = .data:0x000002F0; // type:object size:0x18
-lbl_598_data_308 = .data:0x00000308; // type:object size:0x18
-lbl_598_data_320 = .data:0x00000320; // type:object size:0xE0
-lbl_598_data_400 = .data:0x00000400; // type:object size:0x34
+__vt__13dAcOCtrlPnl_c = .data:0x00000210; // type:object size:0x80
+__vt__52sFStateMgr_c<13dAcOCtrlPnl_c,20sStateMethodUsr_FI_c> = .data:0x00000290; // type:object size:0x30
+__vt__82sStateMgr_c<13dAcOCtrlPnl_c,20sStateMethodUsr_FI_c,12sFStateFct_c,13sStateIDChk_c> = .data:0x000002C0; // type:object size:0x30
+__vt__29sFStateFct_c<13dAcOCtrlPnl_c> = .data:0x000002F0; // type:object size:0x14
+__vt__26sFState_c<13dAcOCtrlPnl_c> = .data:0x00000308; // type:object size:0x18
+__vt__Q213dAcOCtrlPnl_c10callback_c = .data:0x00000320; // type:object size:0x18
+@39632 = .data:0x00000338; // type:object size:0xC
+@39633 = .data:0x00000344; // type:object size:0xC
+@39634 = .data:0x00000350; // type:object size:0xC
+@39635 = .data:0x0000035C; // type:object size:0xC
+@39636 = .data:0x00000368; // type:object size:0xC
+@39637 = .data:0x00000374; // type:object size:0xC
+@39638 = .data:0x00000380; // type:object size:0xC
+@39639 = .data:0x0000038C; // type:object size:0xC
+lbl_598_data_398 = .data:0x00000398; // type:object size:0xC
+lbl_598_data_3A4 = .data:0x000003A4; // type:object size:0x5C
+__vt__28sFStateID_c<13dAcOCtrlPnl_c> = .data:0x00000400; // type:object size:0x34
__global_destructor_chain = .bss:0x00000000; // type:object size:0x4 scope:global
-lbl_598_bss_8 = .bss:0x00000008; // type:object size:0x78 data:4byte
-AcOControlPanel__StateID_Wait = .bss:0x00000080; // type:object size:0x40 data:4byte
-AcOControlPanel__StateID_Control = .bss:0x000000C0; // type:object size:0x40 data:4byte
-AcOControlPanel__StateID_EndEvent = .bss:0x00000100; // type:object size:0x30 data:4byte
+sSpotPositions = .bss:0x00000008; // type:object size:0x78 data:4byte
+StateID_Wait__13dAcOCtrlPnl_c = .bss:0x00000080; // type:object size:0x30 data:4byte
+StateID_Control__13dAcOCtrlPnl_c = .bss:0x000000C0; // type:object size:0x30 data:4byte
+StateID_EndEvent__13dAcOCtrlPnl_c = .bss:0x00000100; // type:object size:0x30 data:4byte
diff --git a/config/SOUE01/symbols.txt b/config/SOUE01/symbols.txt
index 851d242d..a986b2f4 100644
--- a/config/SOUE01/symbols.txt
+++ b/config/SOUE01/symbols.txt
@@ -10439,14 +10439,14 @@ dAcOClef__IsSceneflagValid = .text:0x80194E90; // type:function size:0x2C
dAcOClef__isTempflagSet = .text:0x80194EC0; // type:function size:0x58
dAcOClef__getSceneflag = .text:0x80194F20; // type:function size:0xC
checkIsInSkykeepPuzzle__Fv = .text:0x80194F30; // type:function size:0x8
-isInSkyKeepPuzzleRoom = .text:0x80194F40; // type:function size:0xA4
+getCurrentSkyKeepRoomTileId__Fv = .text:0x80194F40; // type:function size:0xA4
isInAnySkyKeepRoom = .text:0x80194FF0; // type:function size:0x38
maybeResetSkykeepPuzzle = .text:0x80195030; // type:function size:0xB4
saveSkykeepPuzzleToGlobal = .text:0x801950F0; // type:function size:0x58
restoreSkykeepPuzzleFromGlobal__Fv = .text:0x80195150; // type:function size:0x68
relatedToSkeepMapStuff = .text:0x801951C0; // type:function size:0x120
-getSKDoorSceneflag = .text:0x801952E0; // type:function size:0x18
-checkSKDoorHasSceneflag = .text:0x80195300; // type:function size:0x34
+getSKDoorSceneflag__Fll = .text:0x801952E0; // type:function size:0x18
+checkSKDoorHasSceneflag__Fll = .text:0x80195300; // type:function size:0x34
setSceneflagsForSkykeepPuzzleDoors = .text:0x80195340; // type:function size:0x220
fn_80195560 = .text:0x80195560; // type:function size:0x94
fn_80195600 = .text:0x80195600; // type:function size:0x6C
@@ -42501,7 +42501,7 @@ sSandStreamList__11dTgStream_c = .sbss:0x805756D0; // type:object size:0x8 data:
lbl_805756D8 = .sbss:0x805756D8; // type:object size:0x8 data:4byte
IMPRISONED_PTR = .sbss:0x805756E0; // type:object size:0x4 data:4byte
sInstance__13dTgClefGame_c = .sbss:0x805756E4; // type:object size:0x4 data:4byte
-IS_IN_SKYKEEP_PUZZLE = .sbss:0x805756E8; // type:object size:0x1 data:byte
+sIsInSkykeepPuzzle = .sbss:0x805756E8; // type:object size:0x1 data:byte
lbl_805756E9 = .sbss:0x805756E9; // type:object size:0x1 data:byte
sInstance__10dTgSndMg_c = .sbss:0x805756EC; // type:object size:0x4 data:4byte
s_pInstance__Q24dHbm8Manage_c = .sbss:0x805756F0; // type:object size:0x8 data:4byte
diff --git a/include/d/a/obj/d_a_obj_D3_dummy.h b/include/d/a/obj/d_a_obj_D3_dummy.h
index 6038bd67..48892644 100644
--- a/include/d/a/obj/d_a_obj_D3_dummy.h
+++ b/include/d/a/obj/d_a_obj_D3_dummy.h
@@ -2,6 +2,7 @@
#define D_A_OBJ_D3_DUMMY_H
#include "d/a/obj/d_a_obj_base.h"
+#include "d/col/bg/d_bg_w.h"
#include "s/s_State.hpp"
class dAcOD3Dummy_c : public dAcObjBase_c {
@@ -11,8 +12,17 @@ public:
STATE_FUNC_DECLARE(dAcOD3Dummy_c, Wait);
+ void setField_0x1570(u8 val) {
+ field_0x1570 = val;
+ }
+
private:
- /* 0x??? */ STATE_MGR_DECLARE(dAcOD3Dummy_c);
+ /* 0x0330 */ dBgW field_330[8];
+ /* 0x13B0 */ u8 unk[0x180];
+ /* 0x1530 */ STATE_MGR_DECLARE(dAcOD3Dummy_c);
+ /* 0x156C */ u8 field_0x156C[4];
+ /* 0x1570 */ u8 field_0x1570;
+ /* 0x1571 */ u8 field_0x1571[0xB];
};
#endif
diff --git a/include/d/a/obj/d_a_obj_control_panel.h b/include/d/a/obj/d_a_obj_control_panel.h
index 4427b2c5..7f32a5c8 100644
--- a/include/d/a/obj/d_a_obj_control_panel.h
+++ b/include/d/a/obj/d_a_obj_control_panel.h
@@ -1,20 +1,141 @@
#ifndef D_A_OBJ_CONTROL_PANEL_H
#define D_A_OBJ_CONTROL_PANEL_H
+#include "c/c_lib.h"
+#include "common.h"
+#include "d/a/d_a_base.h"
+#include "d/a/obj/d_a_obj_D3_dummy.h"
#include "d/a/obj/d_a_obj_base.h"
+#include "d/col/bg/d_bg_w.h"
+#include "d/d_message.h"
+#include "d/flag/sceneflag_manager.h"
+#include "m/m3d/m_mdl.h"
+#include "m/m3d/m_smdl.h"
+#include "m/m_color.h"
+#include "m/m_vec.h"
+#include "nw4r/g3d/res/g3d_resfile.h"
#include "s/s_State.hpp"
+#include "toBeSorted/actor_event.h"
+#include "toBeSorted/d_flow_mgr.h"
class dAcOCtrlPnl_c : public dAcObjBase_c {
+ class callback_c : public m3d::callback_c {
+ public:
+ void timingB(u32, nw4r::g3d::WorldMtxManip *, nw4r::g3d::ResMdl) override;
+ void setPosAndScale(int tileId, const mVec3_c &vec, f32 f) {
+ mTilePositions[tileId] = vec;
+ mTileScales[tileId] = f;
+ }
+ void setNodeID(int i, s32 nodeID) {
+ mTileNodeIDs[i] = nodeID;
+ }
+
+ private:
+ /* 0x00 */ mVec3_c mTilePositions[8];
+ /* 0x20 */ f32 mTileScales[8];
+ /* 0x40 */ s32 mTileNodeIDs[8];
+ };
+ friend class callback_c;
+ struct Spot {
+ /* 0x00 */ Spot *mNeighbors[4];
+ /* 0x10 */ u8 mSpot;
+ /* 0x11 */ u8 mCurrentTile;
+
+ Spot *getNeighbor(s32 direction) {
+ return mNeighbors[direction];
+ }
+ };
+
public:
- dAcOCtrlPnl_c() : mStateMgr(*this) {}
+ dAcOCtrlPnl_c() : mStateMgr(*this), mEvent(*this, nullptr), mFlowMgr(&mFlow) {}
virtual ~dAcOCtrlPnl_c() {}
+ virtual int doDelete() override;
+ virtual int draw() override;
+ virtual bool createHeap() override;
+ virtual int actorCreate() override;
+ virtual int actorPostCreate() override;
+ virtual int actorExecute() override;
+ virtual void doInteraction(s32 /* InteractionType */) override;
+
+ void updatePuzzleFromFile();
+ void savePuzzleState();
+ bool handleSlidingTile();
+ void setupNeighbors();
+ void updateTileScales();
+ bool hasAdjacentEmptySpot(s32);
+ bool getAdjacentEmptySpot(s32, s32 *);
+ void handleEvent();
+ void handleControl();
+ void updateDoorSceneflags();
+ u8 getSpotForCursor(mVec2_c &);
+ u8 getMoveDirection(s32, s32);
+ void setTileID(u32, u32);
+ u8 getTileID(u32);
+ void resetPuzzleState();
+ void updateTilePositions();
+ void updateSpotTilesFromPuzzle();
+ void getScreenCenter(mVec3_c &);
+ void setLinkVisibility(bool);
+ void updateTileColors();
+ void afterControlPanel();
+ void afterControlPanelFirst();
+ void enterMove();
+ void finishMove();
+ bool changedPuzzle();
+ bool isFirstTime();
+
+ bool doChaseTilePosToTarget() {
+ return cLib::chasePos(mTilePositions[mMovingTile], mGrabTargetPosition, 10.f) > 0;
+ }
+
+ void setSceneflag(u8 flag) {
+ SceneflagManager::sInstance->setFlag(mRoomID, flag);
+ }
+
+ void unsetSceneflag(u8 flag) {
+ SceneflagManager::sInstance->unsetFlag(mRoomID, flag);
+ }
STATE_FUNC_DECLARE(dAcOCtrlPnl_c, Wait);
STATE_FUNC_DECLARE(dAcOCtrlPnl_c, Control);
STATE_FUNC_DECLARE(dAcOCtrlPnl_c, EndEvent);
private:
- /* 0x??? */ STATE_MGR_DECLARE(dAcOCtrlPnl_c);
+ /* 0x330 */ nw4r::g3d::ResFile mRes;
+ /* 0x334 */ m3d::mdl_c mModel;
+ /* 0x358 */ mVec3_c mTilePositions[8];
+ /* 0x3B8 */ STATE_MGR_DECLARE(dAcOCtrlPnl_c);
+ /* 0x3F4 */ ActorEventRelated mEvent;
+ /* 0x444 */ mVec3_c mGrabTargetPosition;
+ /* 0x450 */ s32 mMovingTile;
+ /* 0x454 */ dBgW mBgW;
+ /* 0x664 */ s32 mCurrentlyHoveredTile;
+ /* 0x668 */ s32 mCurrentlyHoveredSpot;
+ /** The spots where tiles can be, in the following order:
+ * 0 | 1 | 2
+ * ---+---+---
+ * 3 | 4 | 5
+ * ---+---+---
+ * 6 | 7 | 8
+ */
+ /* 0x66C */ Spot mSpots[9];
+ /* 0x720 */ dAcRef_c<dAcOD3Dummy_c> mD3DummyRef;
+ /* 0x72C */ bool mIsGrabbing;
+ /* 0x72D */ u8 mGrabTargetMoveDirection;
+ /* 0x72E */ u8 mGrabTargetSpot;
+ /* 0x730 */ mVec2_c mGrabStartCursorPos;
+ /* 0x738 */ bool mHasMovedATile;
+ /* 0x739 */ bool mLeavePuzzle;
+ /* 0x73C */ dFlow_c mFlow;
+ /* 0x7A0 */ dFlowMgrBase_c mFlowMgr;
+ /* 0x7F8 */ u8 mSkykeepPuzzle[9];
+ /* 0x801 */ u8 mSkykeepPuzzleOriginal[9];
+ /* 0x80C */ callback_c mCallback;
+ /* 0x8B0 */ f32 mTileScales[8];
+ /* 0x8D0 */ s32 mTilePlateMatIDs[8];
+ /* 0x8F0 */ s32 mTriforceMatIDs[3];
+ /* 0x8FC */ mColor mNormalPlateColor;
+ /* 0x900 */ s32 mTimer;
};
#endif
diff --git a/include/d/lyt/msg_window/d_lyt_msg_window.h b/include/d/lyt/msg_window/d_lyt_msg_window.h
index d3cb9ae3..a9d2b9b2 100644
--- a/include/d/lyt/msg_window/d_lyt_msg_window.h
+++ b/include/d/lyt/msg_window/d_lyt_msg_window.h
@@ -126,6 +126,10 @@ public:
mValidChangeBtnMask |= flag;
}
+ static void setFlowMgr(dFlowMgrBase_c *flowMgr) {
+ sFlowMgr = flowMgr;
+ }
+
private:
bool setTextToDisplay(const wchar_t *text);
void createSubMsgManager(u8 type);
diff --git a/include/toBeSorted/misc_actor.h b/include/toBeSorted/misc_actor.h
index ade8210e..c921a729 100644
--- a/include/toBeSorted/misc_actor.h
+++ b/include/toBeSorted/misc_actor.h
@@ -12,6 +12,11 @@
bool checkIsInSkykeepPuzzle();
void restoreSkykeepPuzzleFromGlobal();
+s32 getSKDoorSceneflag(s32, s32);
+bool checkSKDoorHasSceneflag(s32, s32);
+s32 getCurrentSkyKeepRoomTileId();
+
+extern bool sIsInSkykeepPuzzle;
extern const u8 sTadtoneSceneflags[];
extern const u8 sTadtoneGroupSizes[];
diff --git a/src/REL/d/a/obj/d_a_obj_control_panel.cpp b/src/REL/d/a/obj/d_a_obj_control_panel.cpp
index 9e16c8bc..a6a0457d 100644
--- a/src/REL/d/a/obj/d_a_obj_control_panel.cpp
+++ b/src/REL/d/a/obj/d_a_obj_control_panel.cpp
@@ -1,17 +1,832 @@
#include "d/a/obj/d_a_obj_control_panel.h"
+#include "c/c_lib.h"
+#include "common.h"
+#include "d/a/d_a_itembase.h"
+#include "d/a/d_a_player.h"
+#include "d/a/obj/d_a_obj_D3_dummy.h"
+#include "d/a/obj/d_a_obj_base.h"
+#include "d/col/bg/d_bg_s.h"
+#include "d/d_base.h"
+#include "d/d_camera.h"
+#include "d/d_cs_game.h"
+#include "d/d_pad.h"
+#include "d/d_sc_game.h"
+#include "d/flag/itemflag_manager.h"
+#include "d/flag/sceneflag_manager.h"
+#include "d/lyt/d_lyt_do_button.h"
+#include "d/lyt/d_lyt_unknowns.h"
+#include "d/lyt/meter/d_lyt_meter.h"
+#include "d/lyt/msg_window/d_lyt_msg_window.h"
+#include "d/snd/d_snd_small_effect_mgr.h"
+#include "d/snd/d_snd_wzsound.h"
+#include "egg/math/eggMath.h"
+#include "f/f_base.h"
+#include "f/f_manager.h"
+#include "f/f_profile_name.h"
+#include "m/m_angle.h"
+#include "m/m_color.h"
+#include "m/m_mtx.h"
+#include "m/m_pad.h"
+#include "m/m_vec.h"
+#include "nw4r/g3d/res/g3d_resfile.h"
+#include "nw4r/g3d/res/g3d_resmdl.h"
+#include "nw4r/g3d/res/g3d_resnode.h"
+#include "nw4r/math/math_triangular.h"
+#include "rvl/GX/GXTypes.h"
+#include "toBeSorted/attention.h"
+#include "toBeSorted/d_d3d.h"
+#include "toBeSorted/event.h"
+#include "toBeSorted/event_manager.h"
+#include "toBeSorted/file_manager.h"
+#include "toBeSorted/misc_actor.h"
+
+static const char *eventName = "ControlPanel";
+static const char *firstAfterEvent = "AfterControlPanelFirst";
+static const char *afterEvent = "AfterControlPanel";
+
+static const u8 unused[] = {0x00, 0xff, 0x00, 0xaa, 0x00, 0x50, 0x00, 0x00, 0x00, 0x50, 0x00, 0x3c, 0x00, 0x00,
+ 0x00, 0x00, 0x43, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
+
+const void *getUnused() {
+ return unused;
+}
+
+static const char *sSkyKeepRooms[] = {
+ "D003_0", "D003_1", "D003_2", "D003_3", "D003_4", "D003_5", "D003_6", "D003_7",
+};
+
+const void *getUnused2() {
+ return sSkyKeepRooms;
+}
+
+static InteractionTargetDef interactionTarget = {0, 3, 1, EXAMINE_TALK, 0, 200.0f,
+ 60.0f, 60.0f, -100.0f, 100.0f, 50.0f, 1.0f};
+
+static mVec3_c sSpotPositions[9] = {
+ mVec3_c(-43.2, 14.78, -40.59), mVec3_c(0.0, 14.78, -40.59), mVec3_c(43.2, 14.78, -40.59),
+ mVec3_c(-43.2, 0.0, 0.0), mVec3_c(0.0, 0.0, 0.0), mVec3_c(43.2, 0.0, 0.0),
+ mVec3_c(-43.2, -14.78, 40.59), mVec3_c(0.0, -14.78, 40.59), mVec3_c(43.2, -14.78, 40.59),
+};
+
SPECIAL_ACTOR_PROFILE(OBJ_CONTROL_PANEL, dAcOCtrlPnl_c, fProfile::OBJ_CONTROL_PANEL, 0x159, 0, 3);
STATE_DEFINE(dAcOCtrlPnl_c, Wait);
STATE_DEFINE(dAcOCtrlPnl_c, Control);
STATE_DEFINE(dAcOCtrlPnl_c, EndEvent);
+void enterMoveCb(void *actor) {
+ if (actor == nullptr) {
+ return;
+ }
+ static_cast<dAcOCtrlPnl_c *>(actor)->enterMove();
+}
+
+void finishMoveCb(void *actor) {
+ if (actor == nullptr) {
+ return;
+ }
+ static_cast<dAcOCtrlPnl_c *>(actor)->finishMove();
+}
+
+void afterControlPanelFirstCb(void *actor) {
+ if (actor == nullptr) {
+ return;
+ }
+ static_cast<dAcOCtrlPnl_c *>(actor)->afterControlPanelFirst();
+}
+
+void afterControlPanelCb(void *actor) {
+ if (actor == nullptr) {
+ return;
+ }
+ static_cast<dAcOCtrlPnl_c *>(actor)->afterControlPanel();
+}
+
+bool dAcOCtrlPnl_c::createHeap() {
+ const char *oarcName = "ControlPanel";
+ mRes = nw4r::g3d::ResFile(getOarcResFile(oarcName));
+ nw4r::g3d::ResMdl mdl = mRes.GetResMdl("ControlPanel");
+ if (!mModel.create(mdl, &mAllocator, 0x120, 1, nullptr)) {
+ return false;
+ }
+ void *dzb = getOarcDZB(oarcName, "ControlPanel");
+ void *plc = getOarcPLC(oarcName, "ControlPanel");
+ updateMatrix();
+ return !mBgW.Set((cBgD_t *)dzb, (PLC *)plc, cBgW::LOCK_e | cBgW::MOVE_BG_e, &mWorldMtx, &mScale);
+}
+
+int dAcOCtrlPnl_c::actorCreate() {
+ CREATE_ALLOCATOR_SIZE(dAcOCtrlPnl_c, 0x8000);
+ dBgS::GetInstance()->Regist(&mBgW, this);
+ mAcceleration = 0.f;
+ mMaxSpeed = 0.f;
+ mBoundingBox.Set(mVec3_c(-200.f, -0.f, -200.f), mVec3_c(200.f, 200.f, 200.f));
+ updatePuzzleFromFile();
+ updateTilePositions();
+ mMovingTile = -1;
+ setupNeighbors();
+ updateDoorSceneflags();
+ if ((s32)getFromParams(0x18, 3) == 1) {
+ return FAILED;
+ }
+ char *plateModels[] = {
+ "CPPlate1", "CPPlate2", "CPPlate3", "CPPlate4", "CPPlate5", "CPPlate6", "CPPlate7", "CPPlate8",
+ };
+ nw4r::g3d::ResMdl resMdl = mModel.getResMdl();
+ for (int i = 0; i < 8; i++) {
+ nw4r::g3d::ResNode node = resMdl.GetResNode(plateModels[i]);
+ mCallback.setNodeID(i, node.GetID());
+ mCallback.setPosAndScale(i, mTilePositions[i], 1.f);
+ }
+ mModel.setLocalMtx(mWorldMtx);
+ mModel.setCallback(&mCallback);
+ mModel.calc(false);
+ mCurrentlyHoveredTile = -1;
+ mStateMgr.changeState(StateID_Wait);
+ return SUCCEEDED;
+}
+
+int dAcOCtrlPnl_c::actorPostCreate() {
+ dAcOD3Dummy_c *ptr = static_cast<dAcOD3Dummy_c *>(fManager_c::searchBaseByProfName(fProfile::OBJ_D3_DUMMY));
+ mD3DummyRef.link(ptr);
+ static const char *plateModels[] = {
+ "m_CPPlate1", "m_CPPlate2", "m_CPPlate3", "m_CPPlate4", "m_CPPlate5", "m_CPPlate6", "m_CPPlate7", "m_CPPlate8",
+ };
+ for (int i = 0; i < 8; i++) {
+ mTilePlateMatIDs[i] = mModel.getMatID(plateModels[i]);
+ if (mTilePlateMatIDs[i] < 0) {
+ return FAILED;
+ }
+ }
+ // just a guess
+ static const char *triforcePlates[] = {
+ "m_CPPlate1",
+ "m_CPPlate3",
+ "m_CPPlate4",
+ };
+ for (int i = 0; i < 3; i++) {
+ mTriforceMatIDs[i] = mModel.getMatID(triforcePlates[i]);
+ if (mTriforceMatIDs[i] < 0) {
+ return FAILED;
+ }
+ }
+ if (!mModel.getResMdl().GetResMat("m_CPPlate1").GetResMatTevColor().GXGetTevColor(GX_TEVREG1, &mNormalPlateColor)) {
+ return FAILED;
+ }
+ return SUCCEEDED;
+}
+
+int dAcOCtrlPnl_c::doDelete() {
+ sIsInSkykeepPuzzle = false;
+ return SUCCEEDED;
+}
+
+int dAcOCtrlPnl_c::actorExecute() {
+ mTimer++;
+ mStateMgr.executeState();
+
+ for (int i = 0; i < 8; i++) {
+ mCallback.setPosAndScale(i, mTilePositions[i], mTileScales[i]);
+ }
+ updateTileColors();
+ updateTileScales();
+ mModel.calc(false);
+ return SUCCEEDED;
+}
+
+int dAcOCtrlPnl_c::draw() {
+ drawModelType1(&mModel);
+ return SUCCEEDED;
+}
+
void dAcOCtrlPnl_c::initializeState_Wait() {}
-void dAcOCtrlPnl_c::executeState_Wait() {}
+void dAcOCtrlPnl_c::executeState_Wait() {
+ AttentionManager::GetInstance()->addTarget(*this, interactionTarget, 0, nullptr);
+ if (EventManager::isInEvent(this, eventName)) {
+ handleEvent();
+ mStateMgr.changeState(StateID_Control);
+ }
+}
void dAcOCtrlPnl_c::finalizeState_Wait() {}
void dAcOCtrlPnl_c::initializeState_Control() {}
-void dAcOCtrlPnl_c::executeState_Control() {}
+void dAcOCtrlPnl_c::executeState_Control() {
+ handleEvent();
+ dCamera_c *camera = dScGame_c::getCamera();
+ if (camera != nullptr) {
+ f32 camVal = 60.f;
+ mVec3_c local48(0.f, 240.f, 0.f);
+ mVec3_c local54(0.f, 0.f, 0.f);
+ f32 fVar1 = nw4r::math::CosDeg(20);
+ f32 fVar2 = nw4r::math::SinDeg(20);
+ local54.y += (fVar2 * 100.f) / fVar1 + 70.f;
+ local48.rotX(0xe39);
+ fVar1 = nw4r::math::CosDeg(20);
+ fVar2 = nw4r::math::SinDeg(20);
+ local48.y += (fVar2 * 100.f) / fVar1 + 70.f;
+ local48.rotY(mRotation.y);
+ local54.rotY(mRotation.y);
+ local48 += mPosition;
+ local54 += mPosition;
+ camera->setEventCamView(local54, local48, camVal, 0.f);
+ }
+}
void dAcOCtrlPnl_c::finalizeState_Control() {}
-void dAcOCtrlPnl_c::initializeState_EndEvent() {}
-void dAcOCtrlPnl_c::executeState_EndEvent() {}
-void dAcOCtrlPnl_c::finalizeState_EndEvent() {}
+void dAcOCtrlPnl_c::initializeState_EndEvent() {
+ handleEvent();
+}
+void dAcOCtrlPnl_c::executeState_EndEvent() {
+ handleEvent();
+}
+void dAcOCtrlPnl_c::finalizeState_EndEvent() {
+ SceneflagManager::sInstance->setFlag(mRoomID, getFromParams(0x10, 0xFF));
+}
+
+void dAcOCtrlPnl_c::doInteraction(s32) {
+ Event event(eventName, getOarcZev("ControlPanel"), 100, 0x100001, (void *)enterMoveCb, (void *)finishMoveCb);
+ mEvent.scheduleEvent(event, 0);
+}
+
+void dAcOCtrlPnl_c::enterMove() {
+ setLinkVisibility(false);
+ mCurrentlyHoveredSpot = 0xFF;
+ mCurrentlyHoveredTile = -1;
+ mHasMovedATile = false;
+ mLeavePuzzle = false;
+ updatePuzzleFromFile();
+ sIsInSkykeepPuzzle = true;
+}
+void dAcOCtrlPnl_c::finishMove() {
+ setLinkVisibility(true);
+ bool changed = changedPuzzle();
+ sIsInSkykeepPuzzle = false;
+ savePuzzleState();
+ if (mD3DummyRef.isLinked()) {
+ mD3DummyRef.get()->setField_0x1570(1);
+ }
+ if (changed) {
+ mStateMgr.changeState(StateID_EndEvent);
+ } else {
+ mStateMgr.changeState(StateID_Wait);
+ }
+}
+void dAcOCtrlPnl_c::afterControlPanelFirst() {
+ mStateMgr.changeState(StateID_Wait);
+}
+void dAcOCtrlPnl_c::afterControlPanel() {
+ mStateMgr.changeState(StateID_Wait);
+}
+// returns true when the tile finished moving
+bool dAcOCtrlPnl_c::handleSlidingTile() {
+ if (doChaseTilePosToTarget()) {
+ mMovingTile = -1;
+ return true;
+ } else {
+ return false;
+ }
+}
+void dAcOCtrlPnl_c::updateTileScales() {
+ updateMatrix();
+ mModel.setLocalMtx(mWorldMtx);
+ for (int i = 0; i < 8; i++) {
+ if (i == mCurrentlyHoveredTile && hasAdjacentEmptySpot(mCurrentlyHoveredTile)) {
+ mTileScales[i] = 1.1f;
+ } else {
+ mTileScales[i] = 1.0f;
+ }
+ }
+}
+bool dAcOCtrlPnl_c::hasAdjacentEmptySpot(s32 idx) {
+ s32 out = -1;
+ return getAdjacentEmptySpot(idx, &out);
+}
+
+bool dAcOCtrlPnl_c::getAdjacentEmptySpot(s32 tileID, s32 *pEmptySpot) {
+ if (tileID < 0) {
+ return false;
+ }
+ if (tileID == getCurrentSkyKeepRoomTileId()) {
+ return false;
+ }
+ s32 tileSpot = -1;
+ for (s32 spot = 0; spot < 9; spot++) {
+ if (tileID == mSpots[spot].mCurrentTile) {
+ tileSpot = spot;
+ break;
+ }
+ }
+ if (tileSpot < 0) {
+ return false;
+ }
+ for (int direction = 0; direction < 4; direction++) {
+ dAcOCtrlPnl_c::Spot *adjacent = mSpots[tileSpot].getNeighbor(direction);
+ if (adjacent != nullptr && adjacent->mCurrentTile == 0xFF) {
+ *pEmptySpot = adjacent->mSpot;
+ return true;
+ }
+ }
+ return false;
+}
+void dAcOCtrlPnl_c::setupNeighbors() {
+ mSpots[0].mNeighbors[0] = nullptr;
+ mSpots[0].mNeighbors[1] = &mSpots[1];
+ mSpots[0].mNeighbors[2] = &mSpots[3];
+ mSpots[0].mNeighbors[3] = nullptr;
+ mSpots[1].mNeighbors[0] = nullptr;
+ mSpots[1].mNeighbors[1] = &mSpots[2];
+ mSpots[1].mNeighbors[2] = &mSpots[4];
+ mSpots[1].mNeighbors[3] = &mSpots[0];
+ mSpots[2].mNeighbors[0] = nullptr;
+ mSpots[2].mNeighbors[1] = nullptr;
+ mSpots[2].mNeighbors[2] = &mSpots[5];
+ mSpots[2].mNeighbors[3] = &mSpots[1];
+ mSpots[3].mNeighbors[0] = &mSpots[0];
+ mSpots[3].mNeighbors[1] = &mSpots[4];
+ mSpots[3].mNeighbors[2] = &mSpots[6];
+ mSpots[3].mNeighbors[3] = nullptr;
+ mSpots[4].mNeighbors[0] = &mSpots[1];
+ mSpots[4].mNeighbors[1] = &mSpots[5];
+ mSpots[4].mNeighbors[2] = &mSpots[7];
+ mSpots[4].mNeighbors[3] = &mSpots[3];
+ mSpots[5].mNeighbors[0] = &mSpots[2];
+ mSpots[5].mNeighbors[1] = nullptr;
+ mSpots[5].mNeighbors[2] = &mSpots[8];
+ mSpots[5].mNeighbors[3] = &mSpots[4];
+ mSpots[6].mNeighbors[0] = &mSpots[3];
+ mSpots[6].mNeighbors[1] = &mSpots[7];
+ mSpots[6].mNeighbors[2] = nullptr;
+ mSpots[6].mNeighbors[3] = nullptr;
+ mSpots[7].mNeighbors[0] = &mSpots[4];
+ mSpots[7].mNeighbors[1] = &mSpots[8];
+ mSpots[7].mNeighbors[2] = nullptr;
+ mSpots[7].mNeighbors[3] = &mSpots[6];
+ mSpots[8].mNeighbors[0] = &mSpots[5];
+ mSpots[8].mNeighbors[1] = nullptr;
+ mSpots[8].mNeighbors[2] = nullptr;
+ mSpots[8].mNeighbors[3] = &mSpots[7];
+ for (int i = 0; i < 9; i++) {
+ mSpots[i].mSpot = i;
+ }
+ updateSpotTilesFromPuzzle();
+}
+
+void dAcOCtrlPnl_c::handleEvent() {
+ u16 flow = getFromParams(0, 0xFFFF);
+ switch (mEvent.getCurrentEventCommand()) {
+ case 'wait': mEvent.advanceNext(); break;
+ case 'ctrl':
+ handleControl();
+ if (mLeavePuzzle) {
+ setLinkVisibility(true);
+ mCurrentlyHoveredSpot = 0xFF;
+ mCurrentlyHoveredTile = -1;
+ dSndSmallEffectMgr_c::GetInstance()->playSound(SE_S_CtrlPnl_DECIDE);
+ mEvent.advanceNext();
+ }
+ break;
+ case 'msg ':
+ if (mEvent.isAdvance()) {
+ s32 part2 = flow < 10000U ? 1000 : 100;
+ s32 truncate = (flow / part2);
+
+ u16 lower = flow - truncate * part2;
+
+ s32 part1 = flow < 10000U ? 1000 : 100;
+ u16 upper = flow / part1;
+ mFlowMgr.triggerEntryPoint(upper, lower, 0, 0);
+ dLytMsgWindow_c::setFlowMgr(&mFlowMgr);
+ } else {
+ mFlowMgr.checkFinished();
+ if (mFlowMgr.fn_800C40F0()) {
+ mEvent.advanceNext();
+ }
+ }
+ break;
+ case 'end ':
+ void *zev = getOarcZev("ControlPanel");
+ if (changedPuzzle()) {
+ if (isFirstTime()) {
+ Event event(firstAfterEvent, zev, 100, 0x100001, nullptr, (void *)afterControlPanelFirstCb);
+ EventManager::setEvent(this, &event, nullptr);
+ } else {
+ Event event(afterEvent, zev, 100, 0x100001, nullptr, (void *)afterControlPanelCb);
+ EventManager::setEvent(this, &event, nullptr);
+ }
+ }
+ mEvent.advanceNext();
+ break;
+ }
+}
+
+// non matching
+void dAcOCtrlPnl_c::handleControl() {
+ bool canGrabTile = hasAdjacentEmptySpot(mCurrentlyHoveredTile);
+ if (mIsGrabbing) {
+ dLytDobutton_c::setActionTextStuff(dLytDobutton_c::ICON_29, dLytDobutton_c::ACT_DO_MOVE_2, true);
+ } else if (canGrabTile) {
+ dLytDobutton_c::setActionTextStuff(dLytDobutton_c::ICON_11, dLytDobutton_c::ACT_DO_GRAB_3, true);
+ } else {
+ dLytDobutton_c::setActionTextStuff(dLytDobutton_c::ICON_4, dLytDobutton_c::ACT_DO_SELECT, true);
+ }
+ if (!mIsGrabbing) {
+ if (canGrabTile) {
+ dLytMeter_c::GetInstance()->setFlags(METER_BTN_NUN_STK);
+ LytDoButtonRelated::set(LytDoButtonRelated::DO_BUTTON_A, LytDoButtonRelated::ACT_IE_INFO_GRAB_2);
+ } else {
+ dLytMeter_c::GetInstance()->clearFlags(METER_BTN_NUN_STK);
+ }
+ }
+ dLytMeter_c::GetInstance()->setFlags(METER_BTN_B);
+ LytDoButtonRelated::set(LytDoButtonRelated::DO_BUTTON_B, LytDoButtonRelated::ACT_IE_ETC_DONE);
+ dLytMeter_c::GetInstance()->setFlags(METER_BTN_C);
+ LytDoButtonRelated::set(LytDoButtonRelated::DO_BUTTON_C, LytDoButtonRelated::ACT_IE_ETC_RESET_PANELS);
+ dLytMeter_c::GetInstance()->clearFlags(METER_BTN_CROSS_UP);
+ dLytMeter_c::GetInstance()->clearFlags(METER_BTN_CROSS_LEFT);
+ dLytMeter_c::GetInstance()->clearFlags(METER_BTN_CROSS_RIGHT);
+ dLytMeter_c::GetInstance()->clearFlags(METER_BTN_MINUS);
+ dLytMeter_c::GetInstance()->clearFlags(METER_BTN_1);
+ dLytMeter_c::GetInstance()->clearFlags(METER_BTN_Z);
+ dLytMeter_c::GetInstance()->setFlags(METER_BTN_CROSS_DOWN);
+ LytDoButtonRelated::setCrossDown(LytDoButtonRelated::ACT_IE_ETC_CENTER, true);
+ bool downPressed = dPad::getDownTrigDown();
+ if (downPressed) {
+ dPad::ex_c::m_current_ex->centerCursor(mPad::getCurrentCoreID(), true);
+ }
+ dCsGame_c *game = dCsGame_c::GetInstance();
+ if (game != nullptr) {
+ if (game != nullptr) {
+ if (mIsGrabbing) {
+ game->pointerCatSet();
+ } else {
+ game->pointerDefSet();
+ }
+ }
+ mVec2_c cursorPos = game->getCursorIf()->getCursorPos();
+ // non matching: weird branches here
+ bool allowInteraction = true;
+ if (mMovingTile >= 0) {
+ if (handleSlidingTile()) {
+ mHasMovedATile = true;
+ mIsGrabbing = false;
+ u8 tile0 = mSpots[mCurrentlyHoveredSpot].mCurrentTile;
+ u8 tile1 = mSpots[mGrabTargetSpot].mCurrentTile;
+ mSpots[mCurrentlyHoveredSpot].mCurrentTile = tile1;
+ mSpots[mGrabTargetSpot].mCurrentTile = tile0;
+ setTileID(mGrabTargetSpot, tile0);
+ setTileID(mCurrentlyHoveredSpot, tile1);
+ updateDoorSceneflags();
+ dAcOD3Dummy_c *dummy = mD3DummyRef.get();
+ if (dummy != nullptr) {
+ savePuzzleState();
+ dummy->setField_0x1570(1);
+ }
+ }
+ allowInteraction = false;
+ }
+ if (!mIsGrabbing) {
+ if (dPad::getDownTrigB()) {
+ mLeavePuzzle = true;
+ allowInteraction = false;
+ } else if (dPad::getDownTrigC()) {
+ if (changedPuzzle()) {
+ dSndSmallEffectMgr_c::GetInstance()->playSound(SE_S_CtrlPnl_RESET);
+ }
+ resetPuzzleState();
+ updateTilePositions();
+ updateSpotTilesFromPuzzle();
+ updateDoorSceneflags();
+ allowInteraction = false;
+ }
+ }
+ if (allowInteraction) {
+ if (!mIsGrabbing) {
+ s32 hoveredSpot = getSpotForCursor(cursorPos);
+ mCurrentlyHoveredSpot = hoveredSpot;
+ if (hoveredSpot == 0xFF) {
+ mCurrentlyHoveredTile = -1;
+ } else {
+ s32 oldHoveredTile = mCurrentlyHoveredTile;
+ s32 hoveredTile = getTileID(hoveredSpot);
+ mCurrentlyHoveredTile = hoveredTile;
+ if (hoveredTile == 0xFF) {
+ mCurrentlyHoveredTile = -1;
+ }
+ if (oldHoveredTile != mCurrentlyHoveredTile && hasAdjacentEmptySpot(mCurrentlyHoveredTile)) {
+ startSound(SE_CtrlPnl_TAKE);
+ }
+ }
+ s32 emptyAdjacentSpot = -1;
+ // check if the player grabbed the tile
+ if (mCurrentlyHoveredTile >= 0 && dPad::getDownTrigA() &&
+ getAdjacentEmptySpot(mCurrentlyHoveredTile, &emptyAdjacentSpot)) {
+ mIsGrabbing = true;
+ mGrabTargetMoveDirection = getMoveDirection(mCurrentlyHoveredSpot, emptyAdjacentSpot);
+ mGrabStartCursorPos = cursorPos;
+ mGrabTargetSpot = emptyAdjacentSpot;
+ mGrabTargetPosition = sSpotPositions[emptyAdjacentSpot];
+ }
+ } else if (dPad::getUpTrigA()) {
+ mIsGrabbing = false;
+ } else {
+ mVec2_c diff = cursorPos - mGrabStartCursorPos;
+ if (mGrabTargetMoveDirection == 0) {
+ if (diff.y > 30.f) {
+ mMovingTile = mCurrentlyHoveredTile;
+ startSound(SE_CtrlPnl_SLIDE);
+ }
+ } else if (mGrabTargetMoveDirection == 1) {
+ if (diff.x > 30.f) {
+ mMovingTile = mCurrentlyHoveredTile;
+ startSound(SE_CtrlPnl_SLIDE);
+ }
+ } else if (mGrabTargetMoveDirection == 2) {
+ if (diff.y < -30.f) {
+ mMovingTile = mCurrentlyHoveredTile;
+ startSound(SE_CtrlPnl_SLIDE);
+ }
+ } else {
+ if (diff.x < -30.f) {
+ mMovingTile = mCurrentlyHoveredTile;
+ startSound(SE_CtrlPnl_SLIDE);
+ }
+ }
+ }
+ }
+ }
+}
+
+void dAcOCtrlPnl_c::updateDoorSceneflags() {
+ for (int spot = 0; spot < 9; spot++) {
+ s32 tile = mSpots[spot].mCurrentTile;
+ if (tile != 0xFF) {
+ for (int direction = 0; direction < 4; direction++) {
+ if (checkSKDoorHasSceneflag(tile, direction)) {
+ s32 sceneflag = getSKDoorSceneflag(tile, direction);
+ if (spot == 7 && direction == 2 && checkSKDoorHasSceneflag(tile, direction)) {
+ setSceneflag(sceneflag);
+ } else {
+ dAcOCtrlPnl_c::Spot *neighbor = mSpots[spot].mNeighbors[direction];
+ if (neighbor == nullptr) {
+ unsetSceneflag(sceneflag);
+ } else {
+ s32 curTile = neighbor->mCurrentTile;
+ s32 otherDirection;
+ if (direction == 0) {
+ otherDirection = 2;
+ }
+ if (direction == 2) {
+ otherDirection = 0;
+ }
+ if (direction == 3) {
+ otherDirection = 1;
+ }
+ if (direction == 1) {
+ otherDirection = 3;
+ }
+ if (curTile == 0xFF) {
+ unsetSceneflag(sceneflag);
+ } else if (checkSKDoorHasSceneflag(curTile, otherDirection)) {
+ setSceneflag(sceneflag);
+ } else {
+ unsetSceneflag(sceneflag);
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+}
+
+inline bool checkSpotBounds(f32 *spotBounds, const mVec2_c &vec, mVec2_c &cursorPos) {
+ return vec.x + spotBounds[0] < cursorPos.x && cursorPos.x < vec.x + spotBounds[2] &&
+ vec.y + spotBounds[1] < cursorPos.y && cursorPos.y < vec.y + spotBounds[3];
+}
+
+u8 dAcOCtrlPnl_c::getSpotForCursor(mVec2_c &cursorPos) {
+ f32 spotBoundaries[9][4];
+ mVec3_c vec;
+ spotBoundaries[0][0] = -90.0;
+ spotBoundaries[0][1] = 40.0;
+ spotBoundaries[0][2] = -30.0;
+ spotBoundaries[0][3] = 120.0;
+ spotBoundaries[1][0] = -30.0;
+ spotBoundaries[1][1] = 40.0;
+ spotBoundaries[1][2] = 30.0;
+ spotBoundaries[1][3] = 120.0;
+ spotBoundaries[2][0] = 30.0;
+ spotBoundaries[2][1] = 40.0;
+ spotBoundaries[2][2] = 90.0;
+ spotBoundaries[2][3] = 120.0;
+ spotBoundaries[3][0] = -90.0;
+ spotBoundaries[3][1] = -40.0;
+ spotBoundaries[3][2] = -30.0;
+ spotBoundaries[3][3] = 40.0;
+ spotBoundaries[4][0] = -30.0;
+ spotBoundaries[4][1] = -40.0;
+ spotBoundaries[4][2] = 30.0;
+ spotBoundaries[4][3] = 40.0;
+ spotBoundaries[5][0] = 30.0;
+ spotBoundaries[5][1] = -40.0;
+ spotBoundaries[5][2] = 90.0;
+ spotBoundaries[5][3] = 40.0;
+ spotBoundaries[6][0] = -90.0;
+ spotBoundaries[6][1] = -120.0;
+ spotBoundaries[6][2] = -30.0;
+ spotBoundaries[6][3] = -40.0;
+ spotBoundaries[7][0] = -30.0;
+ spotBoundaries[7][1] = -120.0;
+ spotBoundaries[7][2] = 30.0;
+ spotBoundaries[7][3] = -40.0;
+ spotBoundaries[8][0] = 30.0;
+ spotBoundaries[8][1] = -120.0;
+ spotBoundaries[8][2] = 90.0;
+ spotBoundaries[8][3] = -40.0;
+ getScreenCenter(vec);
+ f32(*current)[4] = spotBoundaries;
+ s32 j = 0;
+ for (s32 remaining = 9; remaining != 0; remaining--, j++) {
+ current = spotBoundaries;
+ current += j;
+ if (vec.x + (*current)[0] < cursorPos.x && cursorPos.x < vec.x + (*current)[2] &&
+ vec.y + (*current)[1] < cursorPos.y && cursorPos.y < vec.y + (*current)[3]) {
+ return j;
+ }
+ }
+ return 0xFF;
+}
+
+// non matching
+u8 dAcOCtrlPnl_c::getMoveDirection(s32 currentSpot, s32 targetSpot) {
+ s32 x1 = currentSpot % 3;
+ s32 x2 = targetSpot % 3;
+ s32 y1 = currentSpot / 3;
+ s32 y2 = targetSpot / 3;
+ if (x1 != x2 && y1 != y2) {
+ return 0xFF;
+ }
+ // non matching: regswap
+ s32 xAbs = EGG::Math<int>::abs(x1 - x2);
+ s32 yAbs = EGG::Math<int>::abs(y1 - y2);
+ if (xAbs > 1 || yAbs > 1) {
+ return 0xFF;
+ }
+ s32 xDiff = x2 - x1;
+ s32 yDiff = y2 - y1;
+ if (xDiff == 1) {
+ return 1;
+ }
+ if (xDiff == -1) {
+ return 3;
+ }
+ if (yDiff == 1) {
+ return 2;
+ }
+ if (yDiff == -1) {
+ return 0;
+ }
+ return 0xFF;
+}
+
+void dAcOCtrlPnl_c::updatePuzzleFromFile() {
+ for (int i = 0; i < 9; i++) {
+ mSkykeepPuzzle[i] = FileManager::GetInstance()->getSkykeepPuzzleTile(i);
+ }
+ for (int i = 0; i < 9; i++) {
+ mSkykeepPuzzleOriginal[i] = mSkykeepPuzzle[i];
+ }
+}
+
+void dAcOCtrlPnl_c::setTileID(u32 slot, u32 tile) {
+ if (slot > 8) {
+ return;
+ }
+ if (tile != 0xFF && tile > 7) {
+ return;
+ }
+ mSkykeepPuzzle[slot] = tile;
+}
+
+u8 dAcOCtrlPnl_c::getTileID(u32 spot) {
+ if (spot <= 8) {
+ return mSkykeepPuzzle[spot];
+ }
+ return 0xFF;
+}
+
+void dAcOCtrlPnl_c::resetPuzzleState() {
+ for (int i = 0; i < 9; i++) {
+ mSkykeepPuzzle[i] = mSkykeepPuzzleOriginal[i];
+ }
+}
+
+void dAcOCtrlPnl_c::savePuzzleState() {
+ for (int i = 0; i < 9; i++) {
+ FileManager::GetInstance()->setSkykeepPuzzle(i, mSkykeepPuzzle[i]);
+ }
+}
+
+void dAcOCtrlPnl_c::updateTilePositions() {
+ for (int i = 0; i < 9; i++) {
+ s32 tile = mSkykeepPuzzle[i];
+ if (tile != 0xFF) {
+ mTilePositions[tile] = sSpotPositions[i];
+ }
+ }
+}
+
+void dAcOCtrlPnl_c::updateSpotTilesFromPuzzle() {
+ for (int i = 0; i < 9; i++) {
+ mSpots[i].mCurrentTile = mSkykeepPuzzle[i];
+ }
+}
+
+bool dAcOCtrlPnl_c::isFirstTime() {
+ u8 flag = getFromParams(0x10, 0xFF);
+ return !(flag < 0xFF) || (flag < 0xFF && !SceneflagManager::sInstance->checkBoolFlag(mRoomID, flag));
+}
+
+bool dAcOCtrlPnl_c::changedPuzzle() {
+ for (int i = 0; i < 9; i++) {
+ if (mSkykeepPuzzleOriginal[i] != getTileID(i)) {
+ return true;
+ }
+ }
+ return false;
+}
+
+void dAcOCtrlPnl_c::getScreenCenter(mVec3_c &outVec) {
+ mVec3_c local = mPosition + sSpotPositions[4];
+ s32 _weird_zero = 0;
+ local.y += (146.f + _weird_zero);
+ d3d::worldToScreen(outVec, local);
+}
+
+void dAcOCtrlPnl_c::setLinkVisibility(bool isVisible) {
+ if (dAcPy_c::GetLinkM() == nullptr) {
+ return;
+ }
+ if (isVisible) {
+ dAcPy_c::GetLinkM()->unsetObjectProperty(OBJ_PROP_0x200);
+ } else {
+ dAcPy_c::GetLinkM()->setObjectProperty(OBJ_PROP_0x200);
+ }
+}
+
+void dAcOCtrlPnl_c::callback_c::timingB(u32 nodeID, nw4r::g3d::WorldMtxManip *result, nw4r::g3d::ResMdl) {
+ bool isTileNode = false;
+ for (int i = 0; i < 8; i++) {
+ if (mTileNodeIDs[i] == nodeID) {
+ isTileNode = true;
+ break;
+ }
+ }
+ if (isTileNode) {
+ int tileId = -1;
+ for (int i = 0; i < 8; i++) {
+ if (mTileNodeIDs[i] == nodeID) {
+ tileId = i;
+ }
+ }
+ mMtx_c mtx;
+ result->GetMtx(mtx);
+ mtx.transM(mTilePositions[tileId]);
+ mtx.scaleM(mTileScales[tileId], mTileScales[tileId], mTileScales[tileId]);
+ result->SetMtx(mtx);
+ }
+}
+
+void dAcOCtrlPnl_c::updateTileColors() {
+ ITEM_ID triforceItemflags[3] = {
+ ITEM_TRI_COURAGE,
+ ITEM_TRI_POWER,
+ ITEM_TRI_WISDOM,
+ };
+ mColor triforceColors[3] = {
+ mColor(0, 0xFF, 0, 0),
+ mColor(0xFF, 0, 0, 0),
+ mColor(0, 0, 0xFF, 0),
+ };
+ mColor def;
+ for (int i = 0; i < 3; i++) {
+ if (ItemflagManager::sInstance->getFlagDirect(triforceItemflags[i])) {
+ mModel.setTevColor(mTriforceMatIDs[i], GX_TEVREG2, mColor(0, 0, 0, 0), false);
+ } else {
+ def.r = triforceColors[i].r * (nw4r::math::SinIdx(mTimer * 0xFFFF / 0x3C) + 1.f) * 0.5f;
+ def.g = triforceColors[i].g * (nw4r::math::SinIdx(mTimer * 0xFFFF / 0x3C) + 1.f) * 0.5f;
+ def.b = triforceColors[i].b * (nw4r::math::SinIdx(mTimer * 0xFFFF / 0x3C) + 1.f) * 0.5f;
+ def.a = 0;
+ mModel.setTevColor(mTriforceMatIDs[i], GX_TEVREG2, def, false);
+ }
+ }
+ for (int i = 0; i < 8; i++) {
+ if (i == getCurrentSkyKeepRoomTileId()) {
+ mModel.setTevColor(mTilePlateMatIDs[i], GX_TEVREG1, mColor(0, 0, 0, 0), false);
+ } else {
+ mModel.setTevColor(mTilePlateMatIDs[i], GX_TEVREG1, mNormalPlateColor, false);
+ }
+ }
+}
+
+// missing 0x0000003C in rodata