-
-
Save BitPatty/008c328743d490be4b61f4fb09f61482 to your computer and use it in GitHub Desktop.
Source for Quarterframe Timer
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
qftRect = 0x817F0094 # u32[4] coordinates of the textbox relative to the top left corner of the screen, in order: left X, top Y, right X, bottom Y | |
qftFormat = 0x817F00A4 # string printf format string of the timer, containing 3 specifiers for minutes, seconds and milliseconds in order | |
qftStop = 0x817F00B2 # bool if nonzero, the timer is stopped on the value of qftOffset, otherwise it continues to run | |
qftReset = 0x817F00B3 # bool if nonzero, the timer will restart from 0 in the next area, otherwise it will continue where it left off | |
qftOffset = 0x817F00B4 # u32 cumulative time spent in previous areas since the last reset, includes current area iff qftStop is true | |
qftFreezeTime = 0x817F00B8 # u32 fixed time to be displayed if qftFreezeFor > 0 and qftStop is false, only includes current area | |
qftFreezeFor = 0x817F00BC # u32 duration of a timer freeze (in frames) | |
qftTextBox = 0x817F0110 # J2DTextBox textbox used to render the timer (0x128 bytes), will be replaced with proper HUD elements before 1.0 | |
# gpMarDirector->_5c is the total number of QFs elapsed in the current area, including pauses | |
# Assumptions: | |
# All qft* labels defined above have values within [0x817F0000, 0x817F7FFF] | |
# qftReset == qftStop + 1 | |
# Constants are initialized by a Gecko code with the following values: | |
# *qftRect = [16, 416, 640, 480] | |
# *qftFormat = "%u:%02u.%03u" | |
# on HUD setup, init textbox and reset qftFreezeFor. to reset timer, qftStop 0; qftOffset = -4 (headstart to align with SGT) | |
@direct__12TMarDirectorFv + 0x88 | |
stb r0, 0x260(r26) # replaced instruction | |
lis r7, 0x817F | |
lbz r0, qftReset@l(r7) | |
cmpwi r0, 0 | |
li r4, 0 | |
stw r4, qftFreezeFor@l(r7) | |
beq- noreset | |
sth r4, qftStop@l(r7) # unset qftStop and qftReset | |
li r0, -4 | |
stw r0, qftOffset@l(r7) | |
noreset: | |
ori r3, r7, qftTextBox@l | |
ori r5, r7, qftRect@l | |
lwz r6, gpSystemFont-_SDA_BASE_(r13) | |
lwz r6, 0x48(r6) | |
ori r7, r7, qftFormat@l | |
li r8, 2 | |
li r9, 0 | |
lis r12, __ct__10J2DTextBoxFUlRC7JUTRectPC7ResFONTPCc18J2DTextBoxHBinding18J2DTextBoxVBinding@h | |
ori r12, r12, __ct__10J2DTextBoxFUlRC7JUTRectPC7ResFONTPCc18J2DTextBoxHBinding18J2DTextBoxVBinding@l | |
mtlr r12 | |
blrl | |
# on HUD update, if qftFreezeFor > 0, decrement it and show qftFreezeTime + qftOffset, else show gpMarDirector->_5c + qftOffset | |
@perform__11TGCConsole2FUlPQ26JDrama9TGraphics + (0x43E4 on JP, 0x36DC on US, 0x379C on PAL, 0x3798 on JPA) | |
lis r3, 0x817F | |
lbz r4, qftStop@l(r3) | |
lwz r8, qftOffset@l(r3) | |
cmpwi r4, 0 | |
bne+ bound | |
lwz r4, qftFreezeFor@l(r3) | |
cmpwi r4, 0 | |
bne+ freeze | |
lwz r8, gpMarDirector-_SDA_BASE_(r13) | |
lwz r8, 0x5C(r8) | |
b offset | |
freeze: | |
subi r4, r4, 1 | |
stw r4, qftFreezeFor@l(r3) | |
lwz r8, qftFreezeTime@l(r3) | |
offset: | |
lwz r0, qftOffset@l(r3) | |
add r8, r8, r0 | |
bound: | |
lis r7, 0xA | |
ori r7, r7, 0xF9B0 # 99:59.994 | |
cmpw r7, r8 | |
bge+ update | |
mr r8, r7 | |
stb r7, qftStop@l(r3) | |
stw r7, qftOffset@l(r3) | |
update: | |
mulli r8, r8, 1001 | |
li r0, 120 | |
divwu r8, r8, r0 | |
li r0, 1000 | |
divwu r7, r8, r0 | |
mullw r0, r7, r0 | |
sub r8, r8, r0 | |
li r0, 60 | |
divwu r6, r7, r0 | |
mullw r0, r6, r0 | |
sub r7, r7, r0 | |
addi r5, r3, qftFormat@l | |
li r4, 15 | |
lwz r3, 0x210(r3) | |
crclr 6 | |
lis r12, snprintf@h | |
ori r12, r12, snprintf@l | |
mtlr r12 | |
blrl | |
lis r3, 0x817F | |
ori r3, r3, qftTextBox@l | |
li r4, 0 | |
li r5, 0 | |
addi r6, r1, # 0xE90 on JP, 0xBD0 on US, 0xBE4 on PAL, 0xBEC on JPA | |
li r7, 0x81 | |
lis r12, draw__9J2DScreenFiiPC14J2DGrafContext@h | |
ori r12, r12, draw__9J2DScreenFiiPC14J2DGrafContext@l | |
mtlr r12 | |
blrl | |
lbz r0, 0x46(r31) # replaced instruction | |
# on area change, if qftStop and qftReset are both unset, qftOffset += gpMarDirector->_5c | |
@__dt__12TMarDirectorFv | |
lis r5, 0x817F | |
lhz r0, qftStop@l(r5) # read qftStop and qftReset | |
cmpwi r0, 0 | |
bne- done | |
lwz r0, qftOffset@l(r5) | |
lwz r6, 0x5C(r3) | |
add r0, r0, r6 | |
stw r0, qftOffset@l(r5) | |
done: | |
mflr r0 # replaced instruction | |
# on Shine Get, qftOffset += gpMarDirector->_5c, round qftOffset to the frame, stop and schedule a reset | |
@fireGetStar__12TMarDirectorFP6TShine + (0x48 on JP/US, 0x84 on PAL/JPA) | |
lis r5, 0x817F | |
lwz r6, qftOffset@l(r5) | |
lwz r0, 0x5C(r3) | |
add r6, r6, r0 | |
addi r6, r6, 3+1 | |
rlwinm r6, r6, 0, 0xFFFFFFFC | |
stw r6, qftOffset@l(r5) | |
li r6, -1 # replaced instruction | |
sth r6, qftStop@l(r5) # set qftStop and qftReset | |
# on Bowser defeat, qftOffset += gpMarDirector->_5c, round qftOffset to the frame, stop and schedule a reset | |
@startDemo__8TBathtubFv + (0x21C on JP/JPA, 0x218 on US/PAL) | |
lis r8, 0x817F | |
lwz r6, qftOffset@l(r8) | |
lwz r0, 0x5C(r3) | |
add r6, r6, r0 | |
addi r6, r6, 3+1 | |
rlwinm r6, r6, 0, 0xFFFFFFFC | |
stw r6, qftOffset@l(r8) | |
li r6, -1 # replaced instruction | |
sth r6, qftStop@l(r8) # set qftStop and qftReset | |
# on file select, schedule a reset | |
@changeScene__9TCardLoadFv + (0x1278 on JP, 0x1384 on US, 0x13B0 on PAL/JPA) | |
cmpwi r3, 1 # replaced instruction | |
lis r3, 0x817F | |
stb r5, qftReset@l(r3) | |
# on death, schedule a reset | |
@nextStateInitialize__12TMarDirectorFUc + (0x56C on JP, 0x5BC on US/PAL/JPA) | |
addi r4, r28, 1 # replaced instruction | |
lis r5, 0x817F | |
stb r4, qftReset@l(r5) | |
# on exit area, freeze on frame time until next area and schedule a reset | |
@changeState__12TMarDirectorFv + 0x328 | |
lis r5, 0x817F | |
li r3, 1 | |
stb r3, qftReset@l(r5) | |
lwz r3, 0x5C(r31) | |
addi r3, r3, 3 | |
rlwinm r3, r3, 0, 0xFFFFFFFC | |
stw r3, qftFreezeTime@l(r5) | |
li r3, -1 | |
stw r3, qftFreezeFor@l(r5) | |
# on loading zone activation, freeze on frame time until next area and cancel any scheduled reset | |
@setNextStage__12TMarDirectorFUsPQ26JDrama6TActor + 0x50 | |
lis r5, 0x817F | |
stb r0, qftReset@l(r5) | |
lwz r0, 0x5C(r30) | |
addic r0, r0, 3+1 | |
rlwinm r0, r0, 0, 0xFFFFFFFC | |
stw r0, qftFreezeTime@l(r5) | |
li r0, -1 | |
stw r0, qftFreezeFor@l(r5) | |
# on red coin grab, freeze on QF time for 30 frames | |
@taken__8TCoinRedFP9THitActor + 0x4C | |
lwz r5, gpMarDirector-_SDA_BASE_(r13) | |
lwz r0, 0x5C(r5) | |
lis r5, 0x817F | |
stw r0, qftFreezeTime@l(r5) | |
li r0, 30 | |
stw r0, qftFreezeFor@l(r5) | |
li r5, 0 # replaced instruction | |
# on blue coin grab, freeze on frame time for 30 frames | |
@taken__9TCoinBlueFP9THitActor + 0x24 | |
mr r3, r0 # replaced instruction | |
lwz r5, 0x5C(r3) | |
addi r5, r5, 3 | |
rlwinm r0, r5, 0, 0xFFFFFFFC | |
lis r5, 0x817F | |
stw r0, qftFreezeTime@l(r5) | |
li r0, 30 | |
stw r0, qftFreezeFor@l(r5) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment