Skip to main content

Upscaling Maluch Racer 3

I have a lot of free time now since I quit my job at the end of August. A couple days ago I was hanging out on PolishSpeedrunners Discord voice channel and I heard a conversation about an old Polish racing game – Maluch Racer 3 (also known as Bambino Rally 3 and 2Fast Driver 2; you can buy it on Steam). The issue one guy had was related to the fact that he had a 4K monitor and the game UI didn’t scale up with the resolution at all. In fact, it looks like it was made for 640x480 or 800x600 at most.

Screenshot taken at 800x600.
Screenshot taken at 800x600. Scene rendering doesn’t work properly because I was running the game with Wine on Linux but the UI behaves just like it does on Windows.

I first had a look at the files of the game. It turned out that it stores graphics as DDS and PNG files directly in the game tree without extra intermediate formats or archives. Just for the sake of it, I upscaled all assets by a factor of 2. As you might have already guessed, it didn’t work. The game still worked but the UI was the same size as before but only the top-left quarter of each asset was used. Radar didn’t work and all the text was off; the gauge on the speedometer was broken.

That’s actually something I anticipated from the very beginning because there ought to be some logic to drawing. I found references in two types of files: .mis and .dso. .mis files are just “mission”, i.e. level descriptions. Each map in game had a hardcoded parameters for a displayed minimap. Luckily it was enough to just sed these files with new, twice as big, values. The only side-effect of the change was a need to generate new shader cache for each level when loading it for the first time but the game takes care of it by itself.

.dso files, on the other hand, are a compiled game script files that maintain some internal structures and offsets. The same trick as before didn’t work here and the game crashed when the size of texture changed from 3 to 4 digits. After doing some research, I found a source code of the newer version of the engine that I could use to write a basic version of parser that was compatible with the game because the basic concepts were still there. The remaining opcodes and structures were easy to figure out from the trial and error using a hex editor. Equipped with the parser, I could update all the strings1 in the readable form. The last step was to “compile” the scripts back to dso files.

Screenshot taken at 1920x1080 before and after upscaling the UI.
Screenshot taken at 1920x1080 before and after upscaling the UI by a factor of 2. You can only imagine how ridiculously small it is in 4K. Minimap and speedometer are still functional.

After some debugging sessions I had everything I needed to create a PoC of an upscaler for the game. The library I wrote for parsing and patching dso files and the PoC itself (in examples dir) are available on my github.


  1. It turned out that texture sizes were also saved as strings. I don’t judge. ↩︎