Coding

 Reply to this postStart new topic

[CLEO] FPS De-Limiter

Deji
post Oct 24 2010, 05:05 PM
Post #1


Coding like a Rockstar!

Group Icon

Posts: 1,468
From: ???
Joined: 28-May 09



FPS De-Limiter


Edit: Read here.

San Andreas works using a "single-threaded" mode. I don't know much about this, but I do know it means that if any one of the functions has to stop, the whole game will freeze.

So unfortunately, we often have to use "wait 0" to prevent the rest of the game from seizing up while we do some big operations or a long-infinite loop of small operations, which causes a slight delay in scripts. This delay waits for other functions to operate, which is indeed needed.


However, what definitely isn't needed is the additional wait that is inserted before calling a function which runs the scripts... Something I that exists as part of the "Idle" function. This means that there's quite a bit of delay on top of the specified "wait" time, not just waiting for other functions.. but simply staying idle.


SA was made for old, slow PC's like mine (even slower, actually)... So I could assume that this little wait is just there to free up the extra CPU usage... seemingly un-needed, eh? I'd hunted this down from the 0001 opcode upwards and this is the first thing that occurs to cause a delay in the scripts.


Eventually, after managing to slow down and speed up the entire game, I managed to find out how to stop the game waiting for extra time before running the scripts:

SANNY
0A8C: write_memory 0x53E942 size 2 value 0x9090 virtual_protect 1
0A8C: write_memory 0x53E94C size 1 value 0 virtual_protect 1


Pretty basic, but it speeds up the scripts sufficiently.

The change is more noticable on faster PC's (unlike mine), where
SANNY
wait 250

Will actually wait 250 milleseconds, instead of adding extra time onto that. I have only managed to get it to last 250 milleseconds on a few occasions due to my slow computer, but others should be able to notice an increase in speed better.


I've tested some main.scm missions with this, such as "Reuiniting The Famalies" (I hear it has desync problems on some PC's) and the minigames "Dancing", "Go Go Space Monkey" and that bee game tongue.gif They all work fine, so there's no lack of sync at the hands of this change.

If you wanna restore it (dunno why you would wanna do that, but meh), do this:

SANNY
0A8C: write_memory 0x53E942 size 2 value 0xF1F7 virtual_protect 1
0A8C: write_memory 0x53E94C size 1 value 0xE virtual_protect 1



I've used the code posted here to test the speed difference. I'll do some more testing later to determine exactly how much faster it is (on my PC, anyway).


Have fun with it.. text draw is much smoother etc. - which is the main thing I wanted this for.


--------------------
Go to the top of the page
 
+Quote Post
Silent
post Oct 24 2010, 05:14 PM
Post #2


The master of cut retort

Group Icon

Posts: 239
From: Warsaw, PL
Joined: 21-July 10



Tested it with speedtest.
Before - 0.155s
After - 0.145s

Small difference, but my PC is crap too xP
Go to the top of the page
 
+Quote Post
NTAuthority
post Oct 25 2010, 07:26 AM
Post #3


The New Guy!

Posts: 1
Joined: 25-October 10



Let me elaborate on the purpose of this code a bit. This code is a specific 'loop' at the beginning of the function TheGame (for some reason mislabeled _Idle in the gta_sa IDB, and the only thing it has to do with scripts is that it calls CGame::Process, which calls CTheScripts::Process, which calls CRunningScript::Process, which is how Deji found it), which is called for the full processing (from initialization to rendering) of a game frame.

As most of you would understand at least some Sanny code, I'd think it would work to translate this loop to something like it, which I'm doing below.

CODE
$LAST_TIME = 0

:MainLoop
repeat
    01BD: TIME = current_time_in_ms
    TIME -= $LAST_TIME
    
    if
        TIME > 14
    then
        break
    end
until false

01BD: $LAST_TIME = current_time_in_ms

// here the entire game is processed

jump @MainLoop // actually a return as TheGame is a sub function


The reason both Deji and Silent don't notice large differences is that they only have a slow GPU, incapable of rendering a full SA frame in less than 14 milliseconds. That's exactly what this code does: if processing of the last frame took more than 14 milliseconds, it will only continue executing when at least those 14 milliseconds have passed.

During a conversation with Deji last night, I suddenly came up with the reason why. This bit of idle waiting is actually a bug fix for a bug that occurred in GTA III/VC. In there, with the frame limiter disabled (but frame sync not enabled for III, or in the video driver for VC) the game could run up to an infinite frame rate, causing the game itself to run very smooth. However, if I remember correctly, certain physics calculations messed up, and some other even worse thing happened.

That thing is that the menu, which runs at over 1000 FPS with no limiting, can't properly animate anymore with such a high frame rate. For instance, fading in/out (which happens in III/VC) just stops after some time, where usually you can't see the menu. Animations, like the scrolling of the statistics screen also go very laggy and impossible to see. This made such a high frame rate nearly useless.

Apparently Rockstar didn't bother really fixing this when porting SA to the PC, but decided to just block large frames with a loop. Removing this loop (which isn't just about the script) causes my framerate in-game to go up from ~80 FPS (12.5 ms, timers aren't precise) to around 120 FPS (8 ms). Even more so, this causes the game to run as smooth as III/VC do with the frame limiter off, both with and without frame sync... a feature which I really missed in SA.

However, the frontend still gets rendered at 1200 FPS... but as SA doesn't fade the menu in/out anymore, it will still be visible, but scrolling of the statistics, or even scrolling the map just messes up a lot.

Anyway, this is a very useful memory edit even for faster PCs, as most likely, if I forcibly enable VSync in my GPU driver control panel, the game would run as smooth as my III/VC, while not screwing up the menus too bad. smile.gif

For those who don't want to read the entire post, or don't understand: this isn't something to do with script, this is just a buggy frame limiter. tongue.gif

This post has been edited by NTAuthority: Oct 25 2010, 07:32 AM
Go to the top of the page
 
+Quote Post
Deji
post Oct 25 2010, 01:52 PM
Post #4


Coding like a Rockstar!

Group Icon

Posts: 1,468
From: ???
Joined: 28-May 09



Nice.

I initially tried lowering the value (noticing very unchanged effects on my slow PC) to see what happened before just writing the whole thing to make it skip the waiting, which works great on my PC with no bugs at all.. and FPS is something I'm very short of, so this is pretty useful.

However, I guess for other people, this could be turned into a mod that could come with an .ini file to customize how long it waits for before continuing... So hopefully people will be able to customize and find the happy medium between their PC's performance and the optimal SA framerate.


Interesting how this happens only on menus... The memory could be re-written for that occasion, giving a more equal FPS between playing in-game and using the menu.


--------------------
Go to the top of the page
 
+Quote Post
Reply to this postStart new topic

2 User(s) are reading this topic (2 Guests and 0 Anonymous Users)
0 Members: