C# Snippet – cast

One of my major sources of errors in my home game project are integer math issues. Where adding two bytes gets automatically promoted to an int.

Here is my snippet I wrote to quickly cast the issues away. I sort the error to get the cast error messages, double click to get the code highlighted, right click -> Surround With… -> cast. The default type is byte.

<?xml version="1.0" encoding="utf-8"?>
<CodeSnippets xmlns="http://schemas.microsoft.com/VisualStudio/2005/CodeSnippet">
  <CodeSnippet Format="1.0.0">
      <Description>surrounds selection with cast</Description>
      <Author>Simeon Pilgrim</Author>
      <Code Language="csharp">
        <![CDATA[($casttype$)($selected$ )]]>

Game port progress

My last post about Curse of the Azure Bonds was at the beginning on November, and that was quite a productive month. In December I didn’t touch the code at all and I have been doing some work in the last week.

During my holiday in Gisborne I found a copy of the original Forgotten Realms: Azure Bonds book, and seeing this lying on my desk has encouraged me to keep working. So far it appears to be a lucky charm. The evening I started work again on this project, I decided I was going to have a brake through, and that’s just what happened. I worked out how three blocks of functions where related and the shape of the underlying data structure used to manage sprite animation. All max five frames of it.

Sunday evening I was working of the layout of the interrupt structures, and once I had most of those correctly identified I started using the Ralf Brown Interrupt List to decode what the function where doing. I then used the Visual Studio 2005 refactor tools to rename variables/functions so the code made more sense.

Tonight I was working mainly on another memory structure that purpose I have yet to decipher, but it removed a lot of errors once the related variables became Struct_XXXX (which is a class) verses byte[]/short[]/int/object. I also went on a rampage fixing “Cannot implicitly convert type ‘type1’ to ‘type2’. An explicit conversion exists (are you missing a cast?)” type errors.

Currently there are 14,403 Lines of Assembly to translate, 1,066 Errors to remove and 2 Warnings to solve. Thus at the last three months rates, it will take another year to complete this project.

Game Update

Well I’ve been plodding slowing away at my port of CotAB to C#.Net code. I had been quite idle on the project about 1 month ago. In the last week I’ve been working on reducing the number of warnings and errors down.

This was to try get it closer to a compliable state, and I was bored with straight translation.

Tonight I spent a bit of time going back over the file archives, to get an idea of how progress has been over this phase of the development process. Using this I made an Excel graph of Lines of Assembly left to translate (or delete as the case may be), and compiler Errors and Warnings.

There is still lots today once the code is all translated. A large amount of the errors are related with variable size issues. Like .

byte a = 0;

byte b = a + 1;

the a + 1 gets converted into a int which cannot implicitly be cast to byte. The other major error cause is the signed of variables as by default BYTE have been byte type, and WORD have been short. So there is a lot of digging through the assembly to workout how things are been used.

All of this been made worse, by my daydreaming of building a program to do all this silly stuff. Sort of like Clippy but for file alterations. “Oh I see you have changed the same patterned (insert regex here) block 3 times, would you like me to search through you project and we can review the result together.”

Then later.. “There where also other blocks that could have matched if the pattern was more general like this…”. And maybe in complete dream land, after fluffing around with nested and combined if logic it could say. “I see some higher level logic here, would you like me to show the proof”.

And of cause, I’d not have to pay the world for this program in any of the forms of money, my time or others time (ie wait for it).

CotAB progress graph

Curse of the Azure Bonds Project

So I thought I’d write a little about my current development project. It is a port to the .Net platform of the SSI classic “Curse of the Azure Bonds” (which I refer to as coab, but I guess there really should be a t in there). This project started in February of this year when I decided to work on Coab instead of Pool of Radiance (the first in the SSI AD&D series).

So I used the ever trusty IDA Pro from Hex Rays to open the game up, but like a lot of games from this period, the game was compress/encrypted. I got bored of trying to manual decode it, so I used the very helpful debug.exe to decode the game for me. After single stepping through the decompression code a few times, I wanted to dump the ram image of the game. I could not workout the syntax for the write to file command, so I dumped memory to screen. Dump to screen would only do 64K sections, so I needed to change the DI register. This ended up been done by altering the code about to be executed to alter the DI register as required. I wrote all the required commands into a text file so I could redirect this into debugger, and redirect the output to a file. This then gave me an ASCII file of the memory dump. I wrote a C++ program to parse the file and write a bin file. I then loaded this into IDA using the same offset as the original program was loaded at by debug.exe.

One of the things I’d noticed in all this was the way debug.exe loaded the game (16 bit DOS) was different to how IDA loads it. IDA loaded it verbatim and debug.exe removed one byte and altered the next.

Anyway with the uncompressed image now in IDA, I spent a week rebuilding the segment table that the game used. I then found my IDA scripts I had written back in 2000 while working on Pool of Radiance and used them to load the overlay file, and correctly re-write the jump tables etc. The first problem I found was that the scripts that I had were not the last version I had developed when working on PoR due to back-up issues, so I spent a week rewriting the scripts. I also fine tuned how they did there work. Once I did that I started to decode the functions, but soon noticed the library functions were all unmarked due to the flirt engine not have been run. So I load the original decoded bin file again and found out how to force the flirt engine to run. I saved off the changes. Somewhere in there I either applied the changes to the work in progress, or just started again with the flirt version, ether way, I started making progress on decoding the game.

This carried on for about a month in total, when I noticed that even though I’d dump 192K of the decoded game memory, I only had ~70K of it in IDA, I then double check the dump procedure, and the ASCII to bin program. In the end the problem lay in ASCII to bin program as I’d put a limit in there for testing (~4000 lines) that was stopping parsing before the end of file was reached. So I re-parsed the ASCII file. Then I wrote a IDA script to import the missing file at the correct point, and extend the segments to deal with it. The original problem was that the data segment was half missing. With this resolved more of data look-ups in the code made sense.

Another month passed, and I now had a pretty good understanding of the game structures used by the game. The biggest problems were the verbosity of the assembly code. So around May I start writing a C# program to translate the assembly code into C#. The first thing I did was create files from the segments. There were about 50 memory segments in the game due to the overlay memory management system. Then I got function blocks parsed and correct C# replacements. I then worked on parsing the parameters, and local variables. All the rest of the assembly was written in as comments.

At this time there was ~110K lines of assembly to translate. I started from scratch a few times due to errors in the translator, but I ended up getting good at writing Visual Studio regex to match the asm. In reality the fact the original game was un-optimised Pascal was quite nice. Structure access and assignments are done the same each and every time. The one thing that is very annoying about it been Pascal based is the base 1 arrays. Because the global data segment would have a single address used as a byte, and as a word array, and you need to sort the two usage’s out. This is one place IDA is (or I should say was as I’m using a older version) not to great at.

It is now August and there are only 24,485 lines of assembly left in the code. There are ~2.5K errors to deal with, mainly steaming from parameter mismatch, and C#’s overly picky maths rules. But it’s a work in progress. I’m really enjoying working on it.