Skip to content

Commit e1ac320

Browse files
committed
[XCX] Port FPS++ to 60FPS mod, dynamic FPS limits and fixed cutscenes
Fixes #475. Thanks to @MetrosexualGarbodor for the generous bounty!
1 parent 468d165 commit e1ac320

File tree

8 files changed

+629
-215
lines changed

8 files changed

+629
-215
lines changed

src/XenobladeChroniclesX/Mods/60FPS/patch_60fps.asm

Lines changed: 0 additions & 153 deletions
This file was deleted.

src/XenobladeChroniclesX/Mods/60FPS/patch_60fps_overdrive.asm

Lines changed: 0 additions & 18 deletions
This file was deleted.

src/XenobladeChroniclesX/Mods/60FPS/patch_60fps_qte.asm

Lines changed: 0 additions & 40 deletions
This file was deleted.
Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
[XCX_FPS++_Cutscene]
2+
moduleMatches = 0x218F6E07, 0xF882D5CF, 0x30B6E091, 0x7672271D ; 1.0.0E, 1.0.1E, 1.0.2U, 1.0.2J
3+
4+
.origin = codecave
5+
6+
forceCutsceneLimit:
7+
.int 0
8+
9+
_useCutsceneLimit:
10+
li r10, 1
11+
lis r9, forceCutsceneLimit@ha
12+
stw r10, forceCutsceneLimit@l(r9)
13+
14+
lfs f11, -0x303C(r8)
15+
blr
16+
17+
_resetCutsceneLimit:
18+
li r10, 0
19+
lis r9, forceCutsceneLimit@ha
20+
stw r10, forceCutsceneLimit@l(r9)
21+
b _restoreRegisters
22+
23+
cutsceneFloatConv:
24+
cutsceneFloatConvHa:
25+
.uint 0
26+
cutsceneFloatConvL:
27+
.uint 0
28+
29+
30+
; Check if a cutscene is ongoing with a set FPS limit
31+
_waitTillCutsceneLimit:
32+
li r10, $cutsceneFPSLimit
33+
cmpwi r10, 1
34+
bne _calculateFPS
35+
lis r10, forceCutsceneLimit@ha
36+
lwz r10, forceCutsceneLimit@l(r10)
37+
cmpwi r10, 1
38+
bne _calculateFPS
39+
40+
; If a cutscene FPS limit is set, lower FPS
41+
_lowerCutsceneFPS:
42+
lis r10, const_30@ha
43+
lfs f12, const_30@l(r10)
44+
45+
; Calculate how many ticks a frame has to take to render at the given FPS limit
46+
lis r10, const_1@ha
47+
lfs f7, const_1@l(r10)
48+
fdivs f12, f7, f12
49+
lis r10, timerTickSpeed@ha
50+
lfs f7, timerTickSpeed@l(r10)
51+
fmuls f12, f7, f12
52+
53+
; Subtract the time that it took for the actual frame to render and make sure that it's not negative (which means a frame already took longer to render then the FPS limit)
54+
fsubs f12, f12, f10
55+
lis r10, const_0.0@ha
56+
lfs f7, const_0.0@l(r10)
57+
fcmpu cr0, f7, f12
58+
ble .+0x8
59+
fmr f12, f7
60+
61+
; Convert the remaining ticks that should be spend idling to an integer (but it requires storing it in memory)
62+
fctiwz f12, f12
63+
lis r10, cutsceneFloatConvHa@ha
64+
stfd f12, cutsceneFloatConvHa@l(r10)
65+
66+
# ; Load the converted integer ticks and sleep for the given amount of time
67+
mr r10, r4
68+
lis r9, cutsceneFloatConvL@ha
69+
lwz r4, cutsceneFloatConvL@l(r9)
70+
mr r11, r3
71+
# li r3, 0
72+
lis r9, cutsceneFloatConvHa@ha
73+
lwz r3, cutsceneFloatConvHa@l(r9)
74+
mflr r9
75+
bl import.coreinit.OSSleepTicks
76+
mtlr r9
77+
mr r3, r11
78+
mr r4, r10
79+
80+
_reacquireTime:
81+
mr r11, r3
82+
mr r10, r4
83+
mflr r9
84+
bl import.coreinit.OSGetSystemTime
85+
mtlr r9
86+
87+
lis r9, prevFrameTime_Up32Bit@ha
88+
stw r3, prevFrameTime_Up32Bit@l(r9)
89+
lis r9, prevFrameTime_Low32Bit@ha
90+
stw r4, prevFrameTime_Low32Bit@l(r9)
91+
mr r3, r11
92+
mr r4, r10
93+
94+
; Directly set the game speed to 30FPS when cutscenes are active
95+
lis r10, const_30@ha
96+
lfs f10, const_30@l(r10)
97+
98+
b _setGameSpeed

0 commit comments

Comments
 (0)