Figured I do a small tutorial on fixing up something one of my blog readers sent in. Managed to fix up GOG.com’s mess when it comes to Moto Racer 1.
The problem, was that no audio was being played. To compensate for the lack of CDs and ISOs, GOG.com wrote a small wrapper which also seems to hook some needed functions in order for the game to run properly as well as having emulated Redbook audio by hooking MCI calls to play audio from WAV files. However, it seems they missed one end user scenario: what if the end user doesn’t have a CD drive of any form? Which means, an improper crack.
So naturally, I thought I would look into this, plus the idea seemed a nice diversion from other things…
First things first, I look around for any calls to do with drive management and polling. Some calls I found were:
GetLogicalDrives is the first call:
It lists the number of drives in the first place and what drives are present. Pretty important and logical.
Second is GetDriveType, the most logical one to use. It tells the application what drive type fits what path.
And sure enough, found some references in game.exe to the functions.
When looking through those checks, GetDriveType looked most suspicious. It seems that the result of it is checked against the number 5, which is the ID for CD drives….So it uses that to check whether a CD drive is present.
To debug the game, I attached to game.exe just after running the launcher, to compensate for weird crashes when debugging straight from game.exe. I noticed using dgVooodoo allowed for the game to run more easily with regards to stability as well as easy windowed mode which is needed for debugging. The game does have a warning if it doesn’t detect a CD ROM in the drive, which is good, since it makes the job easier.
After attaching, just select the “Memory map” tab and select the text section for the game.exe.
Then, place breakpoints as needed, which in my case were:
And then let the game run. At some point these will be hit which is here…
It then gets the bitmask for the drives…
Then checks the type of drive…
If the type of drive that is checked doesn’t match the ID for a CD drive it goes along in the drive array to find one. However if EAX is forced to “5” (the ID for a CD drive) it would fall into the following code…
Call 004B14D3 is interesting due to the type of calls inside the function..
MCI commands. MCI commands are used by some old games to communicate with the CD drive to play back audio. In this case, GOG Limited patched these calls and hooked them so that audio plays back from WAV files. The WAV files’ filenames map to CD tracks. Pretty nifty. The devs of Delphine were nice enough to leave decent debug messages which makes this nice, so we know we have the right function.
Basically the code beforehand traces through the drives and sees if a CD drive exists. If it does MCI commands to play a track are done. Simple. So the solution is patch the game so that music is played *no matter what*.
An example of said patching would be…
Just patched out the GetDriveTypeA call to a mov eax,5 so that it always thinks a CD drive is present. Simple. Tested and works.
A more elegant patch would be:
Removing the call and skipping over all redundant code in the function. Removes all unneeded searching of drives.
A patch to fix this bug is here