From 4b3a1aac37582240ab8bd8c8617c4a0ccfcd3e7a Mon Sep 17 00:00:00 2001 From: sup39 Date: Sat, 24 Feb 2024 04:51:15 +0900 Subject: [PATCH] feat: add QFSGT --- QFSGT/@code.xml | 215 +++++++++++++++++++++++++++++++++ QFSGT/info.xml | 11 ++ QFSGT/make.py | 21 ++++ QFSGT/src/onAreaDeinit.s | 15 +++ QFSGT/src/onAreaInit.s | 19 +++ QFSGT/src/onBrowserFightDone.s | 15 +++ QFSGT/src/onExitArea.s | 17 +++ QFSGT/src/onFileStart.s | 8 ++ QFSGT/src/onLoadingZone.s | 15 +++ QFSGT/src/onMiss.s | 7 ++ QFSGT/src/onShineGet.s | 15 +++ QFSGT/src/showTimer.s | 38 ++++++ 12 files changed, 396 insertions(+) create mode 100644 QFSGT/@code.xml create mode 100644 QFSGT/info.xml create mode 100644 QFSGT/make.py create mode 100644 QFSGT/src/onAreaDeinit.s create mode 100644 QFSGT/src/onAreaInit.s create mode 100644 QFSGT/src/onBrowserFightDone.s create mode 100644 QFSGT/src/onExitArea.s create mode 100644 QFSGT/src/onFileStart.s create mode 100644 QFSGT/src/onLoadingZone.s create mode 100644 QFSGT/src/onMiss.s create mode 100644 QFSGT/src/onShineGet.s create mode 100644 QFSGT/src/showTimer.s diff --git a/QFSGT/@code.xml b/QFSGT/@code.xml new file mode 100644 index 0000000..4273037 --- /dev/null +++ b/QFSGT/@code.xml @@ -0,0 +1,215 @@ + + QFSGT + timer + QFSGT + sup39(サポミク), Noki Doki + 0.1 + Feb 24, 2024 + + Show Quarterframe timer with in-game timer appearance on shine get. + + + C20ECE44 00000005 + 981A0260 3CE0817F + 880700B3 2C000000 + 41820010 B00700B2 + 3800FFFC 900700B4 + 60000000 00000000 + C20EFA30 00000005 + 3CA0817F A00500B2 + 2C000000 40820014 + 800500B4 80C3005C + 7C003214 900500B4 + 7C0802A6 00000000 + C20EDB30 00000005 + 3CA0817F 80C500B4 + 8003005C 7CC60214 + 38C60004 54C6003A + 90C500B4 38C0FFFF + B0C500B2 00000000 + C21D1F38 00000005 + 3D00817F 80C800B4 + 8003005C 7CC60214 + 38C60004 54C6003A + 90C800B4 38C0FFFF + B0C800B2 00000000 + C22257CC 00000002 + 2C030001 3C60817F + 98A300B3 00000000 + C20EBD78 00000002 + 389C0001 3CA0817F + 988500B3 00000000 + C20EC72C 00000002 + 3CA0817F 38600001 + 986500B3 00000000 + C20ED8F0 00000002 + 3CA0817F 980500B3 + 60000000 00000000 + C2206774 0000000C + 3C60817F 888300B2 + 2C040000 41A20048 + 38800000 988300B2 + 7FE3FB78 3D808021 + 398CC428 7D8803A6 + 4E800021 7FE3FB78 + 3C80817F 808400B4 + 380004B0 1C8403E9 + 7C840396 3D808021 + 398C9E14 7D8803A6 + 4E800021 881F0044 + 60000000 00000000 + + + C22998C0 00000005 + 981A0260 3CE0817F + 880700B3 2C000000 + 41820010 B00700B2 + 3800FFFC 900700B4 + 60000000 00000000 + C229C520 00000005 + 3CA0817F A00500B2 + 2C000000 40820014 + 800500B4 80C3005C + 7C003214 900500B4 + 7C0802A6 00000000 + C229A5AC 00000005 + 3CA0817F 80C500B4 + 8003005C 7CC60214 + 38C60004 54C6003A + 90C500B4 38C0FFFF + B0C500B2 00000000 + C21FA384 00000005 + 3D00817F 80C800B4 + 8003005C 7CC60214 + 38C60004 54C6003A + 90C800B4 38C0FFFF + B0C800B2 00000000 + C2164E24 00000002 + 2C030001 3C60817F + 98A300B3 00000000 + C229880C 00000002 + 389C0001 3CA0817F + 988500B3 00000000 + C22991A8 00000002 + 3CA0817F 38600001 + 986500B3 00000000 + C229A36C 00000002 + 3CA0817F 980500B3 + 60000000 00000000 + C2143F54 0000000C + 3C60817F 888300B2 + 2C040000 41A20048 + 38800000 988300B2 + 7FE3FB78 3D808015 + 398CAFCC 7D8803A6 + 4E800021 7FE3FB78 + 3C80817F 808400B4 + 380004B0 1C8403E9 + 7C840396 3D808015 + 398C836C 7D8803A6 + 4E800021 881F0044 + 60000000 00000000 + + + C2291758 00000005 + 981A0260 3CE0817F + 880700B3 2C000000 + 41820010 B00700B2 + 3800FFFC 900700B4 + 60000000 00000000 + C22943FC 00000005 + 3CA0817F A00500B2 + 2C000000 40820014 + 800500B4 80C3005C + 7C003214 900500B4 + 7C0802A6 00000000 + C2292480 00000005 + 3CA0817F 80C500B4 + 8003005C 7CC60214 + 38C60004 54C6003A + 90C500B4 38C0FFFF + B0C500B2 00000000 + C21F225C 00000005 + 3D00817F 80C800B4 + 8003005C 7CC60214 + 38C60004 54C6003A + 90C800B4 38C0FFFF + B0C800B2 00000000 + C2159E9C 00000002 + 2C030001 3C60817F + 98A300B3 00000000 + C22906A4 00000002 + 389C0001 3CA0817F + 988500B3 00000000 + C2291040 00000002 + 3CA0817F 38600001 + 986500B3 00000000 + C2292204 00000002 + 3CA0817F 980500B3 + 60000000 00000000 + C2138B90 0000000C + 3C60817F 888300B2 + 2C040000 41A20048 + 38800000 988300B2 + 7FE3FB78 3D808014 + 398CFC5C 7D8803A6 + 4E800021 7FE3FB78 + 3C80817F 808400B4 + 380004B0 1C8403E9 + 7C840396 3D808014 + 398CCFF0 7D8803A6 + 4E800021 881F0044 + 60000000 00000000 + + + C2279570 00000005 + 981A0260 3CE0817F + 880700B3 2C000000 + 41820010 B00700B2 + 3800FFFC 900700B4 + 60000000 00000000 + C227C214 00000005 + 3CA0817F A00500B2 + 2C000000 40820014 + 800500B4 80C3005C + 7C003214 900500B4 + 7C0802A6 00000000 + C227A298 00000005 + 3CA0817F 80C500B4 + 8003005C 7CC60214 + 38C60004 54C6003A + 90C500B4 38C0FFFF + B0C500B2 00000000 + C21DA0FC 00000005 + 3D00817F 80C800B4 + 8003005C 7CC60214 + 38C60004 54C6003A + 90C800B4 38C0FFFF + B0C800B2 00000000 + C2145EBC 00000002 + 2C030001 3C60817F + 98A300B3 00000000 + C22784B4 00000002 + 389C0001 3CA0817F + 988500B3 00000000 + C2278E58 00000002 + 3CA0817F 38600001 + 986500B3 00000000 + C227A01C 00000002 + 3CA0817F 980500B3 + 60000000 00000000 + C21252E0 0000000C + 3C60817F 888300B2 + 2C040000 41A20048 + 38800000 988300B2 + 7FE3FB78 3D808013 + 398CC3C0 7D8803A6 + 4E800021 7FE3FB78 + 3C80817F 808400B4 + 380004B0 1C8403E9 + 7C840396 3D808013 + 398C9740 7D8803A6 + 4E800021 881F0044 + 60000000 00000000 + + diff --git a/QFSGT/info.xml b/QFSGT/info.xml new file mode 100644 index 0000000..0cae98f --- /dev/null +++ b/QFSGT/info.xml @@ -0,0 +1,11 @@ + + QFSGT + timer + QFSGT + sup39(サポミク), Noki Doki + 0.1 + Feb 24, 2024 + + Show Quarterframe timer with in-game timer appearance on shine get. + + diff --git a/QFSGT/make.py b/QFSGT/make.py new file mode 100644 index 0000000..68a4f45 --- /dev/null +++ b/QFSGT/make.py @@ -0,0 +1,21 @@ +from supSMSGecko import make_xml, symbols + +def main(g, ver): + S = symbols[ver] + + g.C2(S['TMarDirector_direct'] + 0x88, 'src/onAreaInit.s') + g.C2(S['TMarDirector_delete_0'], 'src/onAreaDeinit.s') + g.C2(S['TMarDirector_fireGetStar'] + (0x48 if ver in ['GMSJ01', 'GMSE01'] else 0x84), 'src/onShineGet.s') + g.C2(S['TBathtub_startDemo'] + (0x21c if ver in ['GMSJ01', 'GMSJ0A'] else 0x21c), 'src/onBrowserFightDone.s') + g.C2(S['TCardLoad_changeScene'] + { + 'GMSJ01': 0x1278, + 'GMSE01': 0x1384, + 'GMSP01': 0x13b0, + 'GMSJ0A': 0x13b0, + }[ver], 'src/onFileStart.s') + g.C2(S['TMarDirector_nextStateInitialize'] + (0x56c if ver == 'GMSJ01' else 0x5bc), 'src/onMiss.s') + g.C2(S['TMarDirector_changeState'] + 0x328, 'src/onExitArea.s') + g.C2(S['TMarDirector_setNextStage'] + 0x50, 'src/onLoadingZone.s') + g.C2(S['TGCConsole2_drawWater'] - 0x28c, 'src/showTimer.s') + +make_xml(main) diff --git a/QFSGT/src/onAreaDeinit.s b/QFSGT/src/onAreaDeinit.s new file mode 100644 index 0000000..cb419da --- /dev/null +++ b/QFSGT/src/onAreaDeinit.s @@ -0,0 +1,15 @@ +/** Disassemble from Noki Doki's Quarterframe Timer code */ + +## if Stop at QFT Offset flag + lis r5, 0x817f + lhz r0, 0xb2(r5) + cmpwi r0, 0 + bne- .done +## cumulative time += globalQF + lwz r0, 0xb4(r5) + lwz r6, 0x5c(r3) ## globalQF + add r0, r0, r6 + stw r0, 0xb4(r5) +## orig +.done: + mflr r0 diff --git a/QFSGT/src/onAreaInit.s b/QFSGT/src/onAreaInit.s new file mode 100644 index 0000000..c042b87 --- /dev/null +++ b/QFSGT/src/onAreaInit.s @@ -0,0 +1,19 @@ +/** Disassemble from Noki Doki's Quarterframe Timer code */ + +## orig + stb r0, 0x260(r26) +## check if should reset QFT (0xb3 flag) + lis r7, 0x817f + lbz r0, 0xb3(r7) + cmpwi r0, 0 +## duration of timer freeze = 0 +# li r0, 0 +# stw r0, 0xbc(r7) + beq .done +## reset QFT +### stop at QFT offset flag = false + sth r0, 0xb2(r7) +### cumulative time = -4 + li r0, -4 + stw r0, 0xb4(r7) +.done: diff --git a/QFSGT/src/onBrowserFightDone.s b/QFSGT/src/onBrowserFightDone.s new file mode 100644 index 0000000..7cf54a8 --- /dev/null +++ b/QFSGT/src/onBrowserFightDone.s @@ -0,0 +1,15 @@ +/** Disassemble from Noki Doki's Quarterframe Timer code */ + +## r8 = cumulative time + global QF + lis r8, 0x817f + lwz r6, 0xb4(r8) ## cumulative time + lwz r0, 0x5c(r3) ## global QF + add r6, r6, r0 +## round cumulative time to next 4x QF + addi r6, r6, 4 + clrrwi r6, r6, 2 ## clear least significant 2 bits + stw r6, 0xb4(r8) +## stop at QFT offset flag (0xb2 flag) = true (0xFF) +## restart flag (0xb3 flag) = true (0xFF) + li r6, -1 + sth r6, 0xb2(r8) diff --git a/QFSGT/src/onExitArea.s b/QFSGT/src/onExitArea.s new file mode 100644 index 0000000..43945c0 --- /dev/null +++ b/QFSGT/src/onExitArea.s @@ -0,0 +1,17 @@ +/** Disassemble from Noki Doki's Quarterframe Timer code */ + +## restart flag = 1 + lis r5, 0x817f + li r3, 1 + stb r3, 0xb3(r5) +## displayed time = rounded up frame +# lwz r3, 0x5c(r31) +# addi r3, r3, 3 +# clrrwi r3, r3, 2 +# stw r3, 0xb8(r5) +## freeze duration = -1 +# li r3, -1 +# stw r3, 0xbc(r5) + +## orig ignored? +# sth r28, 0x94(r1) diff --git a/QFSGT/src/onFileStart.s b/QFSGT/src/onFileStart.s new file mode 100644 index 0000000..0185db2 --- /dev/null +++ b/QFSGT/src/onFileStart.s @@ -0,0 +1,8 @@ +/** Disassemble from Noki Doki's Quarterframe Timer code */ + +## r5 = 0x40005 in TFlagManager::getFlag() +## orig + cmpwi r3, 1 +## restart flag = true + lis r3, 0x817f + stb r5, 0xb3(r3) diff --git a/QFSGT/src/onLoadingZone.s b/QFSGT/src/onLoadingZone.s new file mode 100644 index 0000000..14abffa --- /dev/null +++ b/QFSGT/src/onLoadingZone.s @@ -0,0 +1,15 @@ +/** Disassemble from Noki Doki's Quarterframe Timer code */ + +## r0 = 0 +## QFT restart flag = 0 + lis r5, 0x817f + stb r0, 0xb3(r5) +## round global QF to next 4x +# lwz r0, 0x5c(r30) +# addic r0, r0, 4 +# clrrwi r0, r0, 2 +## displayed time = rounded QF +# stw r0, 0xb8(r5) +## freeze duration = -1 +# li r0, -1 +# stw r0, 0xbc(r5) diff --git a/QFSGT/src/onMiss.s b/QFSGT/src/onMiss.s new file mode 100644 index 0000000..a4dbc0a --- /dev/null +++ b/QFSGT/src/onMiss.s @@ -0,0 +1,7 @@ +/** Disassemble from Noki Doki's Quarterframe Timer code */ + +## orig (r4 = 0x20001) + addi r4, r28, 1 +## restart flag = true (1) + lis r5, 0x817f + stb r4, 0xb3(r5) diff --git a/QFSGT/src/onShineGet.s b/QFSGT/src/onShineGet.s new file mode 100644 index 0000000..bdbf8b2 --- /dev/null +++ b/QFSGT/src/onShineGet.s @@ -0,0 +1,15 @@ +/** Disassemble from Noki Doki's Quarterframe Timer code */ + +## r6 = cumulative time + global QF + lis r5, 0x817f + lwz r6, 0xb4(r5) ## cumulative time + lwz r0, 0x5c(r3) ## global QF + add r6, r6, r0 +## update cumulative time and round to next 4x QF + addi r6, r6, 4 + clrrwi r6, r6, 2 ## clear least significant 2 bits + stw r6, 0xb4(r5) +## stop at QFT offset flag (0xb2 flag) = true (0xFF) +## restart flag (0xb3 flag) = true (0xFF) + li r6, -1 + sth r6, 0xb2(r5) diff --git a/QFSGT/src/showTimer.s b/QFSGT/src/showTimer.s new file mode 100644 index 0000000..7993c4f --- /dev/null +++ b/QFSGT/src/showTimer.s @@ -0,0 +1,38 @@ +## only start showing timer when finished (stop at QFT offset flag == true) + lis r3, 0x817f + lbz r4, 0xb2(r3) + cmpwi r4, 0 + beq+ .done +## reset stop at QFT offset flag (only start showing once) + li r4, 0 + stb r4, 0xb2(r3) + +## tgcConsole2.startAppearTime(this, isCountDown=false) +### r3 = this + mr r3, r31 +### r4 (isCountDown) = false (count up) +# li r4, 0 +### call + lis r12, TGCConsole2_startAppearTimer@ha + la r12, TGCConsole2_startAppearTimer@l(r12) + mtlr r12 + blrl + +## tgcConsole2.setTimer(this, time) +### r3 = this + mr r3, r31 +### r4 = cumulative time + lis r4, 0x817f + lwz r4, 0xb4(r4) + li r0, 1200 + mulli r4, r4, 1001 + divwu r4, r4, r0 +### call + lis r12, TGCConsole2_setTimer@ha + la r12, TGCConsole2_setTimer@l(r12) + mtlr r12 + blrl + +.done: +## orig + lbz r0, 0x44(r31)