the Magicball Network Forums

the Magicball Network Forums (https://forum.magicball.net/index.php)
-   LBA Modifications - General (https://forum.magicball.net/forumdisplay.php?f=37)
-   -   LbaWin low power patch (https://forum.magicball.net/showthread.php?t=18263)

jhl 2018-08-12 04:52

LbaWin low power patch
 
1 Attachment(s)
I recently dug out LBA for the first time in a few years... and a few minutes in, my laptop fan was going nuts and my battery was fading fast. It was so annoying I had to crank the sound up to mask it! For a game engine from the mid-'90s this seemed like something was a bit wrong. Given that I actually wanted to be able to play more than 20 minutes on a charge, I did a bit of reverse engineering to figure out how to calm it down a bit. Here's what I did and what came out, I'd be interested to hear if anyone else finds this useful. I know "here I patched it" can mean all sorts of things, so I'm going to explain exactly what I changed and you can decide how you feel about it ;)

As with most software of the era, LbaWin uses 100% of the CPU regardless of how busy it is; it spends all its time checking for new input a squillion times a second. With those computers it wasn't a big deal, but now that so many of us have moved to mobile devices, it's a little troublesome for the user experience.

Interestingly, LbaWin already has an FPS limiter: according to the change notes, the FPS was limited to 500 to avoid problems with collision detection. Here's the FPS limiter code in LbaWin.exe:
http://james.laird-wah.net/lba/fpshax/fps_limiter.png
It loops over and over, checking the inputs, until it's time for the next frame - using 100% CPU. Then it sets the next time 2ms in the future, to get that 500FPS limit.

This is easy to fix: we just need a little sleep in that loop. Even a sleep of just 1ms would do the job. Of course, there's no empty space here to insert some code, so it's got to go elsewhere; and perhaps more importantly, this isn't the only place the game spins in a tight loop.
It turns out that this loop governs the main rendering when you're running around in the world, but there are other loops that take over during dialogue, for example. If we just patch this loop, the fan still cranks up while you're listening to people talk! Also annoying.

Luckily, the answer lies in the polling routine sub_4034A0. This is called from most places where the game spins waiting for timers or input. It looks like this:
http://james.laird-wah.net/lba/fpsha..._eventloop.png
sub_4036D0 does housekeeping related to FPS calculation and timers (and FPS display if you press F).
sub_4033E0 handles input from Windows' event system (so keyboard input, Alt+F4, et cetera). And it returns a flag indicating if the game has been asked to quit: if so, it calls into sub_403480, which exits the game.

As it happens, sub_403480, the exit routine, is placed just before this code:
http://james.laird-wah.net/lba/fpsha..._eventloop.png

Conveniently, this gives us a little space to work in. The exit routine calls PostQuitMessage before calling _exit, but this doesn't actually achieve anything, because _exit exits the process immediately.
So by cutting that out and moving the _exit call up a bit, we score a few free bytes of space to build something in...

So here's what I did: I replaced the call to sub_4036D0 to call the new empty space. There, I wrote a new function which calls Sleep() to sleep a few milliseconds, and then calls sub_4036D0 itself. (I also changed a few sub names on the way to this pic.)
http://james.laird-wah.net/lba/fpshax/patched.png

In the end, I decided that running at 500FPS was also over the top, so I changed the FPS limit to 60FPS (waiting 16ms instead of 2ms between frames). This seems like an entirely reasonable limit for all purposes, but feel free to let me know if you have a strong opinion! It drops CPU usage by about 8x so that's pretty big.
Thus I chose to set the sleep in the loop to 4ms, so it should poll for input 3-4 times on every frame. Again, that should be more than enough for any usage, right?

Now the CPU usage is comfortably at 5-10% while playing on my laptop, the fan never runs, and I can enjoy the game properly |)

(I also had a problem with Wine; it was burning up another CPU in wined3d_cs_run() and I had to disable CSMT using regedit... not sure if that's a Wine bug or an LbaWin bug.)

Anyway, this scratches my itch; I'd be curious to hear if it's useful for anyone else.

jhl 2018-08-12 04:52

Uh... if anyone could tell me how to make the pictures not ridiculously huge that'd be very helpful ^_^

Bot13 2018-08-12 10:43

Interesting read and very nice find!

Quetch 2018-08-27 21:16

how on earth u managed to dig and discover all those things is beyond me ... the level of interpretation you were able to give to all those ASM routines is wtf-level. Hats down man, u are truly a wizard, go grab your tunic, u've earned it!!!


All times are GMT +2. The time now is 08:19.

Powered by vBulletin®
Copyright ©2000 - 2020, Jelsoft Enterprises Ltd.
Copyright ©2000 - 2019, the Magicball Network