Fragonite / zmod

Mod loader for Dynasty Warriors 8: Xtreme Legends Complete Edition (DW8XLCE) and Warriors Orochi 4 Ultimate (WO4U)
40 stars 3 forks source link

Possible to have high frame rate in earlier musou games? #4

Open osharp0 opened 3 months ago

osharp0 commented 3 months ago

Your plug-in is amazing! @Fragonite I’m currently looking into high frame rate support in dw4 hyper, and I found game speed is tied to frames rate when above 60fps.

I wonder how your code works for dw8, specifically: https://github.com/Fragonite/zmod/blob/b49ac297515651f923235dbf3f688026b651d658/zmod_dw8xlce_frame_time.cpp#L556

Does dw8 engine already support arbitrary delta time for each game update (animation, physics, camera, game logic, etc…), or did you figure out a way to do so without even the game supporting it?

Your insight would be super helpful! Thanks in advance!

Fragonite commented 3 months ago

DW8 does not support arbitrary delta times, the engine is based around running at 60 Hz with support for 30 Hz. There is a value which I refer to as vsync which is either 1 for 60 Hz or 2 for 30 Hz. You can even set this value to 3 for 15 Hz and so on.

Almost all gameplay systems check this value and use it as a multiplier for their calculations. So for example at 30 Hz the in-game timers will increase by 2 instead of 1.

Some gameplay systems load this value as a float. In these cases, you can overwrite the code to load a custom float instead, such as 0.5 for 120 Hz. This is essentially what the linked code does. Other systems like game timers or offscreen battles use ints and require their own fixes.

I wrote a script to scan the game executable and generate a cheat table to make it easy to toggle and change all the vsync value loads individually. This makes it MUCH easier to find what needs fixing and where to do it.

DW8 has a wait loop function for controlling the amount of time between ticks. I replaced the function call with my own for better frame pacing and setting a custom tick rate.

I recommend using Ghidra to document functions as you go along.

osharp0 commented 3 months ago

Thanks for your explanation! Based on my understanding of the decompiled dw4 hyper code, it really sounds like dw8 works very similarly with hyper's game loop.

Essentially, what you called "vsync" is what I call "timeSteps" in my decompilation project. I didn't try to use 0.5 as timeSteps yet. Definitely worth trying, and with some luck, it might get most of the job done. I'll give it a try after I finish my trip, and then report back.

(Sometimes, I complain that Omega Force's engine never evolves, but in this case, not evolving for 10+ years might work in my favor!)

osharp0 commented 3 months ago

I took a deeper look, and I'm confident to say this is a dead end. None of the dw4 hyper main update logic (entity update, animation, collision & physics, etc..) takes in any timeSteps or delta time. Not to mention feeding in a floating-point half tick 0.5.

The only exception is the realtime opening/ending that comes with their own game update and render loops. The updates in those small loops clearly take in a delta time. That's why the opening/ending can run at high framerate. Just the main game is hardcoded to handle 16.67 ms ticks.

Since now I fully understand the reason, I'm going to conclude that high framerate is not possible for dw4 hyper without rewriting the whole game. Before that, do you have any other ideas to try out? @Fragonite

Fragonite commented 3 months ago

If the game supports true 30 Hz then it should be doable. The functions in DW8 don't take in a delta or vsync value (wait loop function being the exception) but they load the vsync global directly in the code.

If the game only supports 60 Hz then creating a high framerate patch will be very difficult. You could speed up the whole game as a poor man's fix. I prefer the games at 115-120% speed.

Are you getting perfect frame times? That can make a massive difference to perceived smoothness. You can monitor frame times with the below program. The overlay graph should be perfectly smooth.

https://github.com/CXWorld/CapFrameX