
Not so long ago I was engaged in writing fixes for several old games in order to correct the distortion of the picture and interface on widescreen monitors. They asked me to take a look at
FlatOut , so I had an idea to write about it at the same time.
What is needed
To create a full-fledged fix that is easy to install and does not require replacing the game files, I used:
IDA ,
Cheat Engine ,
Visual Studio , the
universal ASI Loader (more on this below), and to launch the game in question in the window -
D3DWindower .
Parsing resources
Let's look in the folder with the installed game to find out what to work with. In this case, the interest is just one file - "flatout.exe". In some games, additional DLLs may be present, for example, in Max Payne, to correct the image aspect ratio, I did inject into e2mfc.dll, and not into an executable file. Flatout.exe is patched to v1.1, but the
official patch from the Russian distributor - the company "BUKA", contains three different EXE:
')

I chose a flatout, 3.exe (2,822,144 bytes) for the study, since the IDA disassembles it into a readable form.
Experiences
Having opened flatout, 3.exe in IDA, first of all I start looking for constants. Judging from my previous experience, most of the old games use one of these to display the interface and 3D images:
640.0, 480.0, 1.3333, 0.0015625 = 1.0 / 640.0, 0.00208333333 = 1.0 / 480.0 , etc. First of all I drive 0.0015625 into the search, since the second most popular constants
640.0 and
480.0 are usually located nearby. IDA finds the required address
0x667CE4 :

Now you can run the game and try to change the value to this memory address. This is how the FlatOut interface looks in 1280x720 resolution:

I run Cheat Engine in parallel, join the process. With the button “Add address manually” I add the address
0x667CE4 to the table:

I am changing its current value to 0.0010, just to see what comes of it. The result shows that half the work is done:

Now it remains to find how to fix the stretching of the 3D image. I did not find the so-called
aspect ratio constant,
4: 3 or
1.3333 , so I decided to try changing all the numbers
480 to
360 . I used this method earlier in Max Payne, I thought that he could help in the search here. In Cheat Engine, I set the following settings and click “First Scan”:

Among the addresses found, I add to the table only those marked in green. Green color means that these addresses belong to the range flatout.exe, and the rest we simply do not need.

Change all found values ​​to
360 :

The image of the game disappears, then an error appears. Experiencedly I find out that the departure is due to the change of two addresses -
FlatOut.exe + 1069C3 (0x5069C3) and
FlatOut.exe + 107CCB (0x507CCB) . I
come to the address
0x5069C3 in IDA, see why it crashes:
480 here is an offset, not a constant, so this function is not of interest, but the attention is attracted by the function below, at address 0x5069D0, which, with a small conversion, gets the following form:

I try to change the constants 4.0 and 3.0 to 16.0 and 9.0, respectively:

I am surprised to find out that this is the very aspect ratio, at the resolution of 1280x720 the picture immediately acquired the correct proportions (as it was / as it became):


Now it remains to write a plugin that calculates the above constants in accordance with the current resolution and makes the image of the game correct for any settings.
C ++
I open Visual Studio, create a new Win32 project, the application type is a DLL library. In the project properties, I set the following options:
- Configuration - Release
- Character Set - Use Multibyte Encoding
- Runtime Library - Multi-threaded (/ MT)
- Warning Level - Level1 (/ W1)
- The final extension is .asi
- The output directory is E: \ Games \ FlatOut \ FlatOut
To work with memory, I use the special class CPatch.
Dllmain:
#include "stdafx.h" #include "CPatch.h" HANDLE HndThread; int* g_Width = (int *)0x6B0D88; int* g_Height = (int *)0x6B0D8C; int g_CameraAspectRatio_x = 0x5069DA; int g_CameraAspectRatio_y = 0x5069E0; int g_hud_stretch_x = 0x667CE4; #define screen_width (float)*g_Width #define screen_height (float)*g_Height float hud_stretch_new = 0.0; int Thread() { while (!screen_width) { Sleep(0); } hud_stretch_new = 1.0/(480.0*(screen_width/screen_height)); CPatch::SetFloat(g_CameraAspectRatio_x, screen_width); CPatch::SetFloat(g_CameraAspectRatio_y, screen_height); CPatch::SetFloat(g_hud_stretch_x, hud_stretch_new); return 0; } BOOL APIENTRY DllMain(HMODULE hModule, DWORD reason, LPVOID lpReserved) { if(reason==DLL_PROCESS_ATTACH) { HndThread = CreateThread(0,0,(LPTHREAD_START_ROUTINE)&Thread,NULL,0,NULL); } return TRUE; }
In order for my ASI library to load along with the game, you need to install the
universal ASI Loader by copying dsound.dll from the archive into the game folder. ASI is just a renamed DLL, and dsound.dll loads ASI into the process of any game that uses DirectSound. Loading from the scripts subfolder is possible.
Result
This is only the first version of the plugin, and most likely it will be updated more than once. There are certain flaws, such as the main menu. Also, in the event of incompatibility, you can add support for other EXE, such as steam-version.



You can download the plugin from
github .
Installation is simple - unpack the archive into the folder with the game.
Update 02.08.2013
Released an updated version, with support for steam-version and steam-demo games.