Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Disable ForceMax60FPS for GOW games and replace it with fixed 60 fps #15640

Merged
merged 7 commits into from
Jul 10, 2022

Conversation

LunaMoo
Copy link
Collaborator

@LunaMoo LunaMoo commented Jul 1, 2022

An attempt to fix #8299 and make fixed 60fps patch obsolete/available to everyone. Unfortunately it can't really be called from other syscall since it's used in other functions and would mess up videos and other screens if done the easy way.

Never used function replacements, so if I messed up and it works by accident please let me know.

This problem with GOW:GOS is very annoying due to softlock in vortex stage that can trigger even on real hardware, the choices seems to be:

  • not adding fixed fps hacks at all and just removing ForceMax60FPS which is enough to fix the game, but will reduce performance a lot killing it for low end devices,
  • remove it from ForceMax60FPS, but add other means to make the game lighter,
  • hacking the function that times the vortex stage to keep any of the game breaking 60 fps hacks minus the breaking the game part.

This draft currently add's 60 and an optional 30 fixed fps patches to GOW games, disabled for GOW:GOS due to softlock, 30 fps version doesn't cause softlock, but disabled by default due to obvious reasons. My goal would be to hack the vortex timing to work with fixed fps(kind of done already), however I don't disagree that improving timing to make it lighter and removing it from ForceMax60FPS hack would be a nicer solution, especially since I have problems locating that timer>.>.

@LunaMoo LunaMoo marked this pull request as draft July 1, 2022 05:47
@LunaMoo LunaMoo marked this pull request as draft July 1, 2022 05:47
@LunaMoo
Copy link
Collaborator Author

LunaMoo commented Jul 1, 2022

Broken and untested as I only checked the 30 fps version to check if the hack works that way, also have some problems with github now, probably need to update my web browser, unfortunately don't have time now, so I'll leave it as a draft now for later.

One good thing from it is that it seems all gow games have same function that can be patched.

@hrydgard
Copy link
Owner

hrydgard commented Jul 1, 2022

Function replacements for things like this are a little scary since they might mess up other games too (that goes in general...)

Maybe we should have a facility for function replacements gated by game ID, seems like a logical thing to have.

@LunaMoo
Copy link
Collaborator Author

LunaMoo commented Jul 1, 2022

Well I had the time to test it properly as I only checked 30 fps to easily see if the FPS in-game are affected and it did, it turns out however that it breaks that one sensitive part of the game as well, so I'm clearly doing something wrong. Never used replacements or at least don't remember, do I have to re-create original game function in addition to add extra code?
Edit: NVM figured it out, it now works. I had to call the function and return zero instead of returning the function.

Replacement activated by gameID seems fine, but I first have to make it work as planned and remove placing the display dependency on core I guess.

@superevr
Copy link

superevr commented Jul 1, 2022

Not sure if I'm doing it right, but I pulled the build for Mac and gave it a try. Performance and framerate was pretty solid (59-66 fps). But it doesn't appear to work for me. It took about 2:30 minutes to pass the first portion of the vortex, but was stuck in the second portion for 9:34 minutes until finally dying (12 minutes total). I've gotten pretty good at this stage by now and wish I had a physical PSP to compare - but I think anything longer than 5 minutes for that portion or 8 minutes total is stuck.

By the way, thanks for the effort in working out the issue here. I spent way too long on this level before realizing it was glitched and figuring out how to fix it from random forums and youtube videos having the same problem. I think a fix will make a lot of people happy.

@LunaMoo
Copy link
Collaborator Author

LunaMoo commented Jul 1, 2022

This code doesn't work, it's an early draft, my edit about it working includes a change that's not present here yet. Through I am testing it now and it only works with 30 fps version, the 60 fps still get's stuck unless I eat enough cycles(something around 50k) to drop it under 60, so basically 60 fps hack ends up working for that spot similar to ForceMax60FPS, breaking the game.

It's annoying, but I currently see a choice between:

  • not adding fixed fps hacks at all and just removing ForceMax60FPS which is enough to fix the game, but will reduce performance a lot killing it for low end devices,
  • remove it from ForceMax60FPS, but add 30 fps hack as an option for those that are performance limited,
  • dropping fps under 60 in heavy scenes by making this function to eat a lot of cycles(I guess it would also make it more performance friendly, but in the end that would be similar to underclocking emulated PSP CPU),
  • and hacking the function that times it to keep 60 fps hack without breaking the game.

@LunaMoo
Copy link
Collaborator Author

LunaMoo commented Jul 2, 2022

Soo far I found out replacement behaves differently than CWCheat version of the "fixed 60 fps" which via cwcheat still fluctuates in that heavy spot reducing at times to 30 fps due to switching threads by calling the syscall, this makes it workaround the glitchy spot better, but isn't trully fixing the fps to 60 as claimed.

With function replacement it doesn't call that syscall, just runs it's function and ends up with true 60 fps, unfortunately while it might be positive overall, due to that it keeps that one place broken.

Interesting note - following this https://gamefaqs.gamespot.com/boards/995953-god-of-war-ghost-of-sparta/57043163 seems this was a game bug ocassionally happening even on real hardware, it was different there, but while testing I eventually managed to replicate the bug that happens on real PSP, instead of enemies spawning without end as with hacks on PPSSPP, they stopped spawning.

I believe the game wants to work this scene by launching few different waves of enemies, but during the last one they spawn without end and the timer starts which get's the ship closer and closer to the vortex until it's get's sucked in via cutscene. On PPSSPP with hacks this timer never progresses, the timer can sometimes glitch even on real PSP and overflow resetting the ship to furthest position and stopping the last wave from being respawned and due to lack of previous waves it softlocks with nothing to do on an empty ship.

I didn't yet found the timer, but it must be adding/subtracting difference of frames from 60 or something as even if the timer works fine and then I switch builds to one that fixes fps properly to 60, it stops progressing, also the bigger the difference from 60 the faster it finishes which is why both overclocking and underclocking PSP CPU affect how fast it progresses and both allowing the game to run over 60 and under 60 does work. This is also why actively killing enemies affects how long the timer will run, it's not necessary to fight enemies from last wave through, the timer runs even when they're holding the player.

@unknownbrackets
Copy link
Collaborator

Really, the right solution here is to try to improve our GPU timing enough that performance is similar (this is hard, though.) It runs differently in PPSSPP because graphics rendering is taking less emulated time than it should, which is also why performance is bad.

I don't love the idea of changing games in the emulator "secretly." That said, whether it's an HLE function behaving differently, a function replacement, or a patch to its code - it's probably not really "different." In theory, we could just modify the instruction (or use a replacement) that the cheat does if we want the same behavior.

Maybe it makes sense to increase the vertex cost estimate with some GoW specific compat flag, though. Maybe that would help more. I remember part of the balancing act was a formula that didn't ruin other games.

-[Unknown]

Also more stable than it's CWCheat version, unfortunately because of that,
still causes softlock in GOW:GOS vortex stage.
@LunaMoo
Copy link
Collaborator Author

LunaMoo commented Jul 2, 2022

I agree it's not a best solution since I'd still have to find and patch the vortex timer function in GOW:GOS basically replacing one hack with two(or three counting 30 fps version), through I'll still try to investigate the GOW:GOS vortex timer function as I find it interesting that similar softlock could happen on real hardware without any hacks as well and figuring out game glitches is the kind of puzzle I enjoy.

Leaving the draft for now as it's still potentially an improvement outside of that vortex stage as technically it does the same as cheat version, but actually in the heavier scenes it's more stable, stupidly it's also the reason why the 60 fps cheat version can pass it... it just drops frames heavilly in there.

@LunaMoo
Copy link
Collaborator Author

LunaMoo commented Jul 3, 2022

I'll probably not investigate this further until next time, so I updated it with a hack that breaks the vortex timer, it's bad and will need more time, but with it, the game works at 60 fps and doesn't softlock in vortex stage. Really need to figure out how it decides to increase the timer based on the fps and then try to at least roughtly match the PSP's variable fps timing.

This just breaks it, increasing the timer every frame which is wrong and probably makes the last part of the fight end too quickly, not tested much outside of the vortex, so it might even affect other timers althrough that could be easily fixed with some extra checks in the hack.

@LunaMoo LunaMoo marked this pull request as ready for review July 3, 2022 20:21
@hrydgard
Copy link
Owner

hrydgard commented Jul 3, 2022

I think in a way something like this can be excused by the fact that the timing-dependent mechanism in the game does appear to actually be buggy, and as has already been posted is known to sometimes be malfunctioning on real hardware. Getting GPU timing 100% correct all the way down to say texture cache fetches is just not practical, and this could also be influenced by CPU timing errors, which we are also not going to be correct for similar reasons (full-on cpu cache emulation is too slow and hard to get right). Of course, it might be that it's possible to get close enough, with some game specific parameters, like Unknown suggests.

It is sketchy though, heh.

@LunaMoo
Copy link
Collaborator Author

LunaMoo commented Jul 3, 2022

I consider this work finished and ready for review/testing.
It works much better than both the cwcheat hack and what we currently have.

It's basically what author of the fixed fps cheats tried to achieve, but without the issue of switching threads after syscall meaning it's always fixed 60 fps and doesn't accidently drop a lot of frames at heavier scenes(like the vortex where the cheat version works awfuly framerate wise), it's also obviously much lighter than just removing ForceMax60FPS.

The function patching vortex timer doesn't exist in other GOW game, so I used just one compat hack for both replaced functions.

@hrydgard
Copy link
Owner

hrydgard commented Jul 3, 2022

Do we know that this function is only used by the vortex timer, by the way?

@LunaMoo
Copy link
Collaborator Author

LunaMoo commented Jul 3, 2022

It's used for other timers as well, but I filtered it to arguments set only for vortex stage, but it didn't trigger for other things as far as I tested even without the extra checks, since it mostly passes higher values.

assets/compat.ini Outdated Show resolved Hide resolved
assets/compat.ini Outdated Show resolved Hide resolved
@LunaMoo
Copy link
Collaborator Author

LunaMoo commented Jul 5, 2022

I think I used some different test build while changing the timing as I'm getting around 1:40-1:50 time from the timer starts running up until the end of the scripted event, however looked up old videos and videos recorded on ps3 and the time of this scripted event with the hack as it is right now seems to match hardware behaviour, so I updated the comment in it.

@LunaMoo
Copy link
Collaborator Author

LunaMoo commented Jul 10, 2022

@superevr could you(or anyone) test the performance of this?
Not interested much in the vortex scene as I observed it far too long and know for sure:

  • it works around vortex timer issue at 60 fps,
  • runs at 60 fps there compared to "fixed 60 fps" cheat running at 30-40 in that spot.

More interested in performance in other places and whenever it holds 60 fps. I guess I could split the 60 fps hack from vortex workaround as it would be easier to accept the latter without the first and fix the issue already.

Edit: NVM blah I last updated my personal build when the flag was disabling all compat.ini checks and this got me really worried about hack not working and wondering if it's something with my PC, it's simply because all compat.ini hacks were disabled. >.>

@hrydgard hrydgard added this to the v1.13.0 milestone Jul 10, 2022
@hrydgard hrydgard added Game Bug Bug is actually in the game, not the emulator. GE emulation Backend-independent GPU issues HLE/Kernel Kernel, memory manager, other HLE issues labels Jul 10, 2022
@hrydgard
Copy link
Owner

It's not pretty, but in summary, fixes a game breaking problem caused by a bug in the game that seems to work by accident of timing on the real hardware (while sometimes breaking even there), and we really don't have a better solution at this time. So I'm reluctantly gonna merge and hope that this doesn't end up messing up something else in the game...

@hrydgard hrydgard enabled auto-merge July 10, 2022 21:25
@hrydgard hrydgard merged commit d2002ea into hrydgard:master Jul 10, 2022
@Uka-Uka
Copy link

Uka-Uka commented Oct 14, 2023

@LunaMoo Thanks for your work. It makes GoW playable on my sony android tv. Would it be possible to do the same for spider-man 3?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Game Bug Bug is actually in the game, not the emulator. GE emulation Backend-independent GPU issues HLE/Kernel Kernel, memory manager, other HLE issues
Projects
None yet
Development

Successfully merging this pull request may close these issues.

God of War Ghost Of Sparta unlimited enemies in The Vortex
5 participants