Thursday, 03 March, 2005

Fixing a TriTryst bug / binary patches

I've had many reports over the years of my game TriTryst failing on non-US versions of Windows.  I didn't give it much thought, figuring that the game was trying to do something culture-specific.  Since I don't have the program's source code or a non-US version of Windows to play with, I just told everybody that it was a known issue with no fix.  I got another of those reports the other day and somehow it dawned on me that one likely cause was the thousands separator in the score display.  You see, we created a custom font for the score display but only created characters for the digits and the comma.  "What would happen," I thought to myself, "if somebody used something other than the comma for a digits separator?"

I found the regional settings for Windows 2000, changed the digits separator to a period, and fired up TriTryst.  Sure enough, when the score reached 1,000 points, the game crashed.  Better, Visual Studio offered to let me debug the program.  You just gotta love just-in-time debugging.  Looking at the disassembly, the problem was obvious.  The code knows about the comma and the digits, and anything else in the score string will cause the program to crash.  A couple of minutes with an assembler and my trusty file dump/patch utility, and I had a program that would handle just about any digits separator I'm likely to encounter.

Making the patch on my system was pretty easy once I figured out the problem.  But distributing the patch turns out to be a major pain.  All I need to do is change two bytes in the executable program.

Back in the DOS days when programs often were smaller than 64K, it was a trivial matter to create a batch file that would load the program in DEBUG, patch a few bytes, and write the file back to disk.  DEBUG was a standard part of DOS so you could count on it being there.  DEBUG is still installed with Windows XP, but it's still designed for use with 16-bit programs that are smaller than 64K.  If there's a way to automate it to patch beyond the first 64K, I don't know what it is.

I also couldn't find a free Windows-based binary patch program that I could use to make a simple patch distribution.    After considering all of my options, I wrote a custom Delphi program to do it and posted the program on my TriTryst BugFix page.  I'm not terribly happy with that solution, though.  If you know of a free binary patch program that I can use to distribute simple patches, I'd sure like to hear about it.