Man spricht Deutsch

Bei Open Source-Projekten habe ich mir eigentlich angewöhnt, in Englisch zu kommunizieren, so auch bei FreeBMP. Größeres Interesse an dem Projekt herrscht aber im Wesentlichen im deutschsprachigen Raum, insofern werde ich in Zukunft zwar nicht zwingend exklusiv, aber deutlich vermehrt, auf Deutsch schreiben und auch schauen, denn Inhalt im Wiki auch in Deutsch anzubieten.

For the English readers: new content will be mostly in German from now on, but feel free to contact me if you have any questions.

Posted in General information | Tagged , | Leave a comment

The Big Picture

There was an issue that some images, when converted from VGA to Bitmap, then edited and converted back to VGA, could not be processed by BMH (for example the background screen, 129.VGA, or the training screen map, 12.VGA). This is due to the fact that the original VGA files are run-length encoded (see the Wiki for details) but the conversion from Bitmap to VGA does not encode anything. The resulting file is “big”, about 128.000 bytes for BMH (320*200*(2bytes per pixel)); for BMP, there was no issue, probably due to the fact that each byte stands for 4 pixels, which means that the maximum file size is (width*height/4).

In order to fix this, I did not implement the same run-length encoding as the original VGA files but a simpler one which only compresses multiple blocks of the same color into one block. In Hex notation, for example, 5 blocks of index 10 were, in the first versions of the conversion tools

AB 00 0A 00 0A 00 0A 00 0A 00 0A CD

Now, this is

AB 84 0A CD

The 0×84 results from 0×05 + 0x7F, where 0x7F is the (fixed) offset. This reduces 10 bytes to 2 bytes and is, in real life”, even more effective. The newly encoded 12.VGA, for example, now has 44207 bytes (the original has 27965 bytes). This is still about one and a half times more, but BMH seems to be able to deal with it. Of course, images without any long stretches of color would not give any benefit with this encoding, but this is quite unlikely. Until further problems occur, we should be good with this encoding scheme.

Posted in Graphics, Technical information | Tagged , | Leave a comment

24 bit RGB

I’ve written previously about how to insert your own images into BMP or BMH, but I forgot to mention one thing: when you have indexed an image with the palette from BMP/BMH/EM, you need to convert it back to a 24 bit RGB file before you save it, otherwise the converters will have problems and will report that a color is not correct even though this is not true:

Parsing file '/home/roland/Desktop/27.VGA.bmp'
Bitmap size: Width x Height = 256 x 76
Color not valid at 0/75 (Color (BGR): 76 0 0)!
Invalid color

If you receive a similar error but are sure that your palette is correct, convert the image to a 24 bit RGB and try again. I have adapted the description of the conversion process for both BMP and BMH.


I added a check for input files to be 24bit. If not, you get the following, more fitting error now:

roland@chrome $ ./bmp_to_vga -p h 129.VGA.bmp 129.VGA
Parsing file '129.VGA.bmp'
Can only load bitmap with 3 bytes per pixel, this image has 1 byte(s) per pixel
Hint: Save your image as 24 bit RGB, this should fix this error
Posted in Graphics | Tagged , , , | Leave a comment

Changing pictures in Bundesliga Manager Hattrick

A guide of how pictures can be added to Bundesliga Manager Hattrick (BMH) has been put up on the Wiki. Adding pictures to BMH is considerably easier than adding pictures to BMP/TM and gives better results as the images in BMH are composed of single pixels, not blocks of 2px*2px. In order for the BMP->VGA conversion to work, a new version of the tools has been released (v0.3.0) which can be downloaded on the SourceForge download page.

Posted in Graphics | Tagged , , , | Leave a comment

BMPs save game file format

For detailed information on BMPs save game file format, look at this PDF explaining how the data to be saved is encrypted and decrypted by BMP. Python scripts to decrypt and encrypt save game files can be downloaded here.

The analysis of the payload data is still in progress, up to date results can be found here in the wiki; feel free to contribute!

Posted in Save games, Tools | Tagged , , | Leave a comment

Persistence pays

My, my, that was quite a lot of work, but I finally made a breakthrough: from the save file creation that I logged using DOSBox, I can now successfully created an encrypted save game. I basically thought I could just match all encoded bytes and write them to a file and then compare it with a saved game (without header), but there were always differences.

Today, I realized that the two occurences where ES:[6A44] is written to the save game are the key: these are checksums!

The checksum is computed as follows:

  • At position 0, first add the initial Y value (see this post), then the encoded byte.
  • At any other position, add the encoded byte, but only take the lower two bytes (this is identical to doing a mod 256).

The checksum byte is written at offset 27971 and as the last byte at offset 34333. With this knowledge I should finally be able to really decode a save game. And the good thing is, I can always check with the result from the log file if I got everything correct and can even check that re-encrypting works – yeah!

Posted in Save games | Tagged , , | Leave a comment

An alternative approach

I am just trying a new approach to finally see what’s the issue with the save games: using DOSBox’ heavy debug version, I can use the LOG command to save a number of cycles to a text file. These look, for example, like this:

39F6:0000064A  mov  ah,3E  EAX:00000000 EBX:00000005 ECX:00000016 EDX:0000392E ESI:00000121 EDI:00000001 EBP:0000ACE2 ESP:0000ACE2 DS:4C73 ES:40C2 FS:0000 GS:0000 SS:4C73 CF:1 ZF:0 SF:1 OF:0 AF:0 PF:0 IF:1

With the instruction and register information, there should be everything I need. Furthermore, I have the saved file and can see what is actually saved.

I breaked on INT 21,40 when doing the save process, removed the breakpoint and started to log. 2,000,000 cycles gives a 7.8GB file with 33,554,432 lines – I found the above line, which sets the INT21 function 3E, “close file using handle”, at line 1,381,935 (1,381,964 if a new file was created) – I’ll have to experiment to see if  100,000 cycles are enough as well (from the relation of the lines, it should be around 8,500).

P.S.:  100,000 cycles were not enough, but 300,00 were more than enough.

Posted in Save games | Tagged , | Leave a comment

Quiet time

No update for a long time, but I have been quite “busy” behind the scenes – at least as far as time allows. It seems like the savegame unraveling does not work as I had hoped. Of course just saving the last byte doesn’t work as the checksum is wrong, but I detected that the decryption does not yield the correct results. I made a log with DOSBox and compared it with a decryption, but some bytes are off. It start with only a couple, then a lot are correct again, then a couple more are of until after around 5k all bytes are wrong. The algorithm in general seems to be correct, though, and it is a lot of work to look into what is wrong, but I try to investigate it. It’s a pity, as changing the save game would surely allow for investigating the game’s mechanics more quickly.

On the positive, I got one of the BMH palettes correct. That doesn’t help with BMP, the main goal, but is at least something positive as most of the BMH graphics files can be decrypted and encrypted. It’s tedious, though, and I doubt I will have a lot of time as I am currently putting more time into my PhD. If anybody wants to help, I’ll surely be glad. :)

Posted in General information, Graphics, Save games | Tagged , , , , , | Leave a comment

Savegames unraveled!

Hooray! I’ve finally broken the save game encryption mechanism! Basically, it’s not that difficult, but no wonder I did not manage to break this when I was younger, it was not that easy. I used the great DOSBox debug version, set breakpoints on writing to the file and could thereby identify a function that is used to encrypt the bytes before saving to a file. A random value is used as a seed and a fixed value (0xD7) is used as modulo. For example, if the random value is 0xBC and the first bytes are 0×04 0×05 0×06 0×07, the process is as follows:

- Let a0 be the input value (0×04 in the first round, 0×05 in the second round etc.)

- Let y0 be the initial seed value (0xBC)

- Let z be the fixed modulo value (0xD7)

Round 1:

- a_encrypted = ((y0 XOR a0) + y0 ) % 0×100 = ((0xBC XOR 0×4) + 0xBC) % 0×100 = (0xB8 +0xBC) % 0×100 = 0×174 % 0×100 = 0×74

- y1 = (z + y0) % 0×100= (0xD7 +0xBC) % 0×100 = 0×93

Round 2:

- a_encrypted = ((y1 XOR a1) + y1) % 0×100 = ((0×93 XOR 0×05) + 0×93) % 0×100 = (0×96 + 0×93) % 0×100 = 129 % 0×100 = 0×29

- y2 = (z + y0) % 0×100 = (0xD7 + 0×93) % 0×100 = 6A

Round 3:

I think you got the point by now. :)

The only thing I have not found out yet is how the last byte is computed. No problem with that, when decrypting the file I just save the last byte with the decrypted file and use it when re-encrypting it again (this obviously only works for analyzing the file, changing it is not possible yet). For encrypting and decrypting, there are two Python scripts which you can download here from the file manager. You can use both of them with python /PATH/TO/SAVEGAME and python /PATH/TO/DECRYPTED_SAVEGAME. There is not much information about the structure documented in the Project Wiki for now, but you can gather some bits from the DOSBox cheating page.

Posted in Save games, Technical information | Tagged , | Leave a comment

BMP graphics palettes unraveled

Finally, I have found all BMP graphics palettes – at least for the german version:

  • Title palette – only used for the title logo (32 colors)
  • Advertisment palette – only used for the advertisments screen (32 colors)
  • Greyscale palette – used for the newspaper photographs (16 colors)
  • Normal palette – used for everything else (32 colors)

At the moment, only vga_to_bmp can use all palettes, which means all .VGA files can be converted to bitmaps. You need to get the trunk from the SVN repository for now and build the file yourself.

On a side note, all .VGA files except the one with the stadium stuff from Eishockey Manager can be converted to bitmaps as well – currently, I am not sure where the second palette for EM is stored. For Bundesliga Manager Hattrick, I have to look for the palette again – “I had it, and I lost it, now you’ve got to help me get it back again” to quote The Hippos. :)

P.S.: The french version obviously uses the same palettes – 46.CP (advertisments) has some strange colors, but works if these are set to the highest palette value (which is the default for the converters, anyway).

P.P.S.: The english palettes seem to be identical as well, with the exception that in the normal palette what should be blue in the game is then black – so I need to get the palette from the exe, even though there is only a minimal difference – thanks a lot, Software 2000!

Posted in Graphics | Tagged , , , , | Leave a comment