From ad867f827e41c4656dd955dae9a2c7aeb1b71b0e Mon Sep 17 00:00:00 2001 From: Crementif <26669564+Crementif@users.noreply.github.com> Date: Wed, 13 Jan 2021 02:01:57 +0100 Subject: [PATCH] [BotW] Fix FPS++ hot-reloading of FPS targets --- .../Mods/FPS++/patch_FenceMethod.asm | 43 +------------------ .../Mods/FPS++/patch_GameSpeed.asm | 22 ++++++---- 2 files changed, 14 insertions(+), 51 deletions(-) diff --git a/src/BreathOfTheWild/Mods/FPS++/patch_FenceMethod.asm b/src/BreathOfTheWild/Mods/FPS++/patch_FenceMethod.asm index cea4f91c..38d44b99 100644 --- a/src/BreathOfTheWild/Mods/FPS++/patch_FenceMethod.asm +++ b/src/BreathOfTheWild/Mods/FPS++/patch_FenceMethod.asm @@ -34,45 +34,4 @@ blr ; Return to the instruction that jumped to this part to the code cave 0x31FAAE8 = bla _conditionalPerformanceFence ; Jumps to the conditional performance part of the code cave that creates the performance fence skip if that preset has been chosen. 0x31FAAF8 = bla _conditionalAccurateAndSkipFence ; Jumps to the conditional accurate part of the code cave that creates the accurate fence skip if that preset has been chosen. -0x31FAAFC = beq .+0x08 ; This part is the crucial part of the fence skip method. It skips the GX2SetGPUFence call in which case there's no fence skip, if the conditional register that has previously been set by the accurate code cave was true. - -[BotW_FenceMethod_V176V192] -moduleMatches = 0xFD091F9F, 0xD472D8A5 - -# Code Cave -codeCaveSize = 0x50 - -# Fence Method Value -_fenceMethod = 0x0000000 -0x0000000 = .int $fenceMethod - -# Performance Fence method - -_conditionalPerformanceFence = 0x0000004 -0x0000004 = lis r11, _fenceMethod@ha -0x0000008 = lwz r11, _fenceMethod@l(r11) -0x000000C = cmpwi r11, 1 -0x0000010 = bne .+0x0C -0x0000014 = li r0, 1 -0x0000018 = blr -0x000001C = lwz r0, 0x388(r31) -0x0000020 = blr - -# Accurate and Skip Fence methods - -_conditionalAccurateAndSkipFence = 0x0000024 -0x0000024 = lis r5, _fenceMethod@ha -0x0000028 = lwz r11, _fenceMethod@l(r5) -0x000002C = cmpwi r11, 2 -0x0000030 = li r5, 6 -0x0000034 = add r6, r12, r0 -0x0000038 = bne .+0x10 -0x000003C = cmpwi r6, 500 -0x0000040 = blt .+0x08 -0x0000044 = subi r6, r6, 1 -0x0000048 = cmpwi r11, 3 -0x000004C = blr - -0x31F9FEC = bla _conditionalPerformanceFence -0x31F9FFC = bla _conditionalAccurateAndSkipFence -0x31FA000 = beq .+0x08 \ No newline at end of file +0x31FAAFC = beq .+0x08 ; This part is the crucial part of the fence skip method. It skips the GX2SetGPUFence call in which case there's no fence skip, if the conditional register that has previously been set by the accurate code cave was true. \ No newline at end of file diff --git a/src/BreathOfTheWild/Mods/FPS++/patch_GameSpeed.asm b/src/BreathOfTheWild/Mods/FPS++/patch_GameSpeed.asm index 8b87d28a..aa724276 100644 --- a/src/BreathOfTheWild/Mods/FPS++/patch_GameSpeed.asm +++ b/src/BreathOfTheWild/Mods/FPS++/patch_GameSpeed.asm @@ -47,18 +47,21 @@ averageFPS1Inv: averageSum: .float $fpsLimit*$frameAverageAmount +initBuffer: +.byte 0 + bufferStart: -.ptr 0xDC +.ptr 0xD8 bufferCurrEntry: -.ptr 0xDC +.ptr 0xD8 bufferEnd: -.ptr 0xDC+(4*$frameAverageAmount) +.ptr 0xD8+(4*$frameAverageAmount) ; Useful for trying potential FPS values. Need to set debugMode = 1 to enable the debugging in the interface and code. debugAddr: -.ptr 0x1040CE78 +.ptr 0x00000000 debugMultiplier: .float $debugMultiplier @@ -95,11 +98,14 @@ lis r12, busSpeed@ha ; Load wii u bus speed... lfs f12, busSpeed@l(r12) ; ...into f12 fmuls f10, f12, f10 ; Multiply bus speed to have current fps in f10. (1/ticks)*bus speed -; Initialize the circular buffer with default values +; Initialize the circular buffer with default values whenever a setting gets changed _initializeAverageBuffer: -lwz r11, 0xD8(r30) ; Check whether/what the current buffer settings are -cmpwi r11, $frameAverageAmount ; Compare the previously $frameAverageAmount with the current $frameAverageAmount +lis r12, initBuffer@ha ; Load the initBuffer variable to see whether the buffer has to be initialized/reset again +lbz r11, initBuffer@l(r12) ; ...to check whether/what the current buffer settings are +cmpwi r11, 1 ; Compare the previously $frameAverageAmount with the current $frameAverageAmount beq _calcAverageFPS ; Continue to calulating the average FPS if the previous settings are the same as the permanently set settings +li r11, 1 ; Load "1" into r11 +stb r11, initBuffer@l(r12) ; Store that 1 into the initBuffer so that it will only initialize this once lis r12, fpsLimit@ha ; Load current FPS limit... lfs f10, fpsLimit@l(r12) ; ...into f10 lis r12, bufferStart@ha ; Load offset to the start of the averaging buffer... @@ -111,8 +117,6 @@ stfs f10, 0x0(r11) ; Store f10 to the address in r12 + 0x04 using this specif addi r12, r12, 0x04 ; Add 0x04 to the buffer offset to make the next entry offset cmpw r12, r3 ; Compare the current address offset in r12 with the address offset in r3 ble .-0x10 ; Loop back until the whole buffer is initialized with the value from f12 -li r11, $frameAverageAmount ; Load current $frameAverageAmount again... -stw r11, 0xD8(r30) ; ...to store that value again in the permanent (doesn't change after reloading) memory ; Calculate the rolling average FPS over the last N amount of frames which are stored in the circular buffer _calcAverageFPS: