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

Add TickSource-based turbo mode #6456

Open
wants to merge 8 commits into
base: master
Choose a base branch
from
Open

Conversation

nico-abram
Copy link
Contributor

@nico-abram nico-abram commented Mar 10, 2024

This PR adds a hotkey that, while held, toggles on a "turbo mode" flag that multiplies elapsed CPU TickSource ticks, which should speed up any games that use delta time between frames for physics calculations.

TODO:

  • TickSource currently stores the multiplier as a public static. Is this alright, or should it be turned into a private static and a method added? Changed to an instance field.
  • Should the multiplier setting go in System settings? (It's where it's currently at) Moved to CPU
  • Keyboard hotkeys cannot be assigned to a controller. Should the hotkey instead be in the input config?
  • It's implemented as a "Hold" button. Did not see any such buttons in the avalonia UI (Only "toggle on press" buttons) so the way this was implemented might be a bit hacky, It checks IsPressed whenever (currentHotkeyState != _prevHotkeyState) and if it differs from turboMode it updates the multiplier.
  • I set the interval for the setting to [50, 500] % , might need some discussion around what this should be ("What are reasonable values")
  • Need to define a default hotkey. I set it to F3 but didn't think much about it. Unbounded.
  • riperi mentioned on discord that "if this is added, it should also increase the vsync rate". I tried adjusting _ticksPerFrame in SurfaceFlinger.cs, but the game I've been testing on (Xenoblade DE, 30fps game, unmodded) was getting FPS over 30 with VSync on even without modifying that.

@github-actions github-actions bot added cpu Related to ARMeilleure horizon Related to Ryujinx.HLE gui Related to Ryujinx.Ui labels Mar 10, 2024
@gdkchan
Copy link
Member

gdkchan commented Mar 10, 2024

TickSource currently stores the multiplier as a public static. Is this alright, or should it be turned into a private static and a method added?

It should not be static at all, it should have a separate multiplier per TickSource instance. That is useful if we want to have multiple emulation contexts in the future with different multipliers for example.

Should the multiplier setting go in System settings?

Should be in CPU tab IMO.

Keyboard hotkeys cannot be assigned to a controller. Should the hotkey instead be in the input config?

No, it should be in hotkeys since it is a hotkey, not regular controller button binding.

Need to define a default hotkey. I set it to F3 but didn't think much about it.

Does it need a default hotkey? If it's not something most people will use I think it's fine to be unbound by default.


Just answering some of the questions, I didn't look at the code yet or the overall approach. I think this is usually called "Speed Hack" (or at least Cheat Engine seems to have a similar setting that they called that).

@nico-abram
Copy link
Contributor Author

Moved the setting to the CPU tab (Put it under a "Hacks" header), removed the global, and made the hotkey unbounded by default

@nico-abram
Copy link
Contributor Author

Here's a video of what it looks like in action in ys origin:
(Apologies for how pixelated it turned out)
https://github.com/Ryujinx/Ryujinx/assets/24706838/682deb46-e1c4-4619-a942-58f9b622cf1d

Ryujinx_G1rF89lbBh.mp4

@gdkchan
Copy link
Member

gdkchan commented Mar 21, 2024

Some open questions I had after testing this feature:

  • It seems that it is only possible to enable "turbo mode" by holding the configured hotkey. This make it difficult to keep it enabled for a long time. Perhaps we need another configuration to control how it should work: "Always on", "On while button is held", "Toggle on button press". I'm not sure if we need both the toggle and hold behaviour, I guess hold is useful if you want it enabled for a short time.
  • On some games, it has no effect because the game logic speed is tied to presentation speed (example: Super Mario Odyssey). Do we want to make that setting also change swap interval somehow to try correcthing that? One problem is that it will still have no effect if the user machine is not fast enough to achieve the multiplied frame rate target. I think we should probably not bother, but users will be confused when the speed hack does nothing. There's also Add custom refresh rate to VSync option #5735 that allows setting a custom frame rate target, so maybe that is good enough.
  • Should it also change audio playback speed? I think it is probably quite complicated to implement as has little benefit, so likely not worth it.

@nico-abram
Copy link
Contributor Author

It seems that it is only possible to enable "turbo mode" by holding the configured hotkey. This make it difficult to keep it enabled for a long time. Perhaps we need another configuration to control how it should work: "Always on", "On while button is held", "Toggle on button press". I'm not sure if we need both the toggle and hold behaviour, I guess hold is useful if you want it enabled for a short time.

I personally mostly use features like this for short periods of time on most games (e.g when moving in a straight line, since maneuvering at a higher speed can be very hard, or when speeding up a short battle animation mid fight, etc) which is why I made it a hold. I'll try adding a setting to switch between "hold" and "toggle" for now in case that ends up the desired behaviour.

On some games, it has no effect because the game logic speed is tied to presentation speed (example: Super Mario Odyssey). Do we want to make that setting also change swap interval somehow to try correcthing that? One problem is that it will still have no effect if the user machine is not fast enough to achieve the multiplied frame rate target. I think we should probably not bother, but users will be confused when the speed hack does nothing. There's also #5735 that allows setting a custom frame rate target, so maybe that is good enough.

I think this might be what peri meant by "if this is added, it should also increase the vsync rate". I agree it's not entirely clear if this should be the same setting. I should mention that on at least one game I've tested (Xenoblade 1 DE) speeding up TickSource increased FPS, even with VSync on.
https://github.com/Ryujinx/Ryujinx/assets/24706838/9814e34f-87cc-4ec1-aee6-575623f1c5df

Ryujinx_fzkEHkFJGa.mp4

Should it also change audio playback speed? I think it is probably quite complicated to implement as has little benefit, so likely not worth it.

I've run into cutscenes that were not sped up with this change in games that normally were, I assume that is related to either video decoding or audio playback speed, so there might be a benefit to implementing something like this in some games? I personally enjoyed being able to play games sped up without butchering the music (Which was my prior experience on GBA emulators), so if added it should probably be a toggle. I'm not sure if the potential benefit is worth the effort and the settings screen real estate.

@MetrosexualGarbodor MetrosexualGarbodor changed the title Add TickSource based turbo mode Add TickSource-based turbo mode Mar 27, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
cpu Related to ARMeilleure gui Related to Ryujinx.Ui horizon Related to Ryujinx.HLE
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants