Petri Häkkinen Profile picture
May 9 42 tweets 11 min read Read on X
Trying to reverse my own game, Bloodfest for the Amiga. The game was released 29(!) years ago. I've lost source code and assets a long time ago... A thread! Image
First things first. I downloaded the game from Aminet. Files were archived with LHA which was a very common packer on the Amiga. List of files after unarchiving: Image
The game was written using AMOS Professional. AMOS was a full blown IDE for making games for the Amiga, similar to Pico8 today. But instead of Lua, AMOS used a custom dialect of BASIC which could be compiled to 68k machine code using AMOS Compiler (a seperate product).
The *.abk files are AMOS Bank files. Luckily somebody has already made a tool for dumping them. But there are several unknown/nonstandard file formats used, *.im, *.lev, *.pac, *.aga and *.pal.
For context, here's a playthrough video
The game comes with a README file with this interesting piece of information. This is really useful for the task at hand! Image
So those *.im files must be compressed using a tool called "File Imploder 4.0". I have absolutely no recollection of ever using this tool. A google search turns up with this beauty. 90s aesthetics at its finest! Image
Turns out somebody has already made a tool called "ancient" for uncompressing several old formats, including Turbo Imploder. Sweet!
github.com/temisu/ancient
But there's a problem. After uncompressing the im files, the uncompressed data is not what I'm expecting. They are missing Abk file header. Focusing on samples/laugh.im which I think is the laugh sfx of the end boss confirms my suspicion...
I try to play the sound using Audacity. 8-bit raw is the sound format used by Amiga. It does not sound right at all. Hmm, let's try that on a "real" Amiga. Well, NVM, let's just use the WinUAE Amiga emulator. So I install Workbench, Bloodfest and AMOS Pro.
Rereading the README and suddenly I remember it. Bloodfest used AMCAF extension which adds the capability of loading Turbo Imploder compressed files to AMOS. Let's install it and load, unpack and play the laugh sound. Nope, still doesn't sound right!
Oh dear. That sounds a lot like some simple encryption. Like scrambling the bits with XOR. Gee, likely all data files are scrambled similarly. This explains why the uncompressed files look wrong (headers missing etc.).
I try to xor the data with different bit patterns in AMOS (bringing back memories). Some values make the laugh more garbled, some slightly clearer. Then I find 0xdf10. That's clearly better. There's still some hiss to it so most likely the decoding key is not exactly right.
I try 0xdf10 with some other data files. The other sound effects sound completely broken with it. So maybe different files used different encoding keys. Uhh... this is not going anywhere fast.
Plan B: instead of trying to reverse the data files, which seems like a lot of work, let's inspect the memory of the running game inside WinUAE. If I can find the assets from memory they must already be decypted.
Let’s search for clues from the AMOS Pro manual. It’s a hefty book with probably 500 pages (but no page numbers!). Image
Whoah! Inside the book I find this letter from Germany. Thank you Mr. Richard Dötterl! ❤️
Image
Image
The internal structure of the AMOS memory banks are explained in the book. Very nice of you Mr. (and Mrs.?) book authors Mel Croucher & Stephen Hill! Image
So AMOS graphics banks have "Sprites" or "Icons" string at the beginning. Let's search for those strings in Amiga's memory. Yep! That looks like a valid AMOS graphics memory bank header indeed. Image
Next step: dump the entire memory map to file and write an utility in Lua (my fav scripting language) for analyzing it.
Amiga has two kinds of memory. Chip Mem which the video circuitry can read and Fast Mem which is only CPU accessible. The banks I found are in Fast so there must be pointers to the actual Chip Mem gfx data somewhere in the memory bank header. And sure enough there they are. Image
(Addresses below 0x200000 are in Chip Mem so it's easy to notice them in mem dumps. Chip Mem addresses have the format 000x xxxx.)
After some Lua coding, decoding AMOS banks and trying to remember how the bitplanes graphics mode worked on the Amiga, I get this. First "icon" from bank 0x2831d8 and converted from bitplanes to regular pixel format used on modern devices. Palette still missing but yay! 💪 Image
Side note: bitplanes are an interesting way to save on memory bandwidth. Every pixel on the screen is on N bitplanes (where N is between 1 and 5 usually on Amiga). The first bitplane contains the lowest bit of every pixel on the screen. The second bitplane the second bit etc.
So to draw a single pixel on the Amiga required setting a single bit in N memory locations. With N = 5 you got 2^5 = 32 unique colors on screen. Cumbersome but the advantage was that a single pixel only consumed 5 bits of memory which was a huge deal in those days.
Back to Bloodfest. The palette can be found in the Fast Mem section of the graphics bank. Meaning the same palette is shared for all images in the bank. Every palette entry is RGB with 4 bits per component, so each color in the 32 entry palette could be chosen from 4096 colors. Image
Here are some other interesting finds from the graphics bank at 0x2831d8. The bank contains only the HUD graphics. The health meter was clearly inspired by id Software games :) Image
Let's try our luck with another graphics bank at 0x283db0. The bank contains 142 images so it must be the main graphics bank. Oh dear, the palette is completely broken. I have no clue why... Image
In the game the crew of a spaceship were in "hypersleep" when some terrible accident happened and a gate to another dimension opened (sounds familiar?). That's why some enemies are crew members gone mad and wearing long johns.
I guess the palette is not stored for some reason with the graphics bank 😟. But we can cheat a bit and dump the contents of Amiga video registers which contains the palette among other things. Image
LOL. Loving the graphics. I have always been blessed with working with truly talented artists. Credits for the graphics go to Tomas Björnfot and Jari Jokivuori. Image
I think this pretty much covers it for graphics. But it would be cool to get the sfxs too... Let's try the same trick of searching the sample bank using the string "Samples"... 2 possible sample banks found. Image
On closer inspection though they are not AMOS sample banks. 🤔Probably just some strings written to memory by Amiga OS when I was tinkering with the CLI. Major bummer! Image
This is going to be more involved. Sample banks cannot be found just by searching a string (maybe they could if I knew the right name?). But banks are stored in a linked list. Every bank has a pointer to the next bank. So maybe I can follow the links from gfx banks I found?
But that works only if the sample bank comes after a graphics bank in the linked list. 50-50% chances... Another thought: AMOS Pro manual says that "Work" and "Data" are possible bank names. Curiously there are five "Work" banks in Chip Mem (used for gfx and also *sfx*). Image
Three of the "Work" banks are for fonts. That leaves banks 62c18 and ed198. Image
The bank at ed198 has at least a convenient size of 118720 bytes. Let's dump it to disk and load it as 8-bit PCM to Audacity... 💪
This was a fun challenge and brought back so many memories. Amiga was a really fun machine to work with (with all its warts!) and with it I learned how to code and and make games. What's next? Bloodfest Remastered in 2025 to celebrate its 30th birthday!? 🤣
If you got this far... Thanks for following and have a great summer!
@Raxor1Robin Also, I just remembered I was working on Bloodfest 2 for the Amiga which had a raycast engine similar to Wolfenstein. But I never got farther than a tech demo.
@CDumancic Amos had the advantage that it could interpret the code while developing. Only at the final stage you compiled it down to machine code. So compilation step didn’t slow you down when programming.
@olli_pelz Were you in the army or out of town in 95?

• • •

Missing some Tweet in this thread? You can try to force a refresh
 

Keep Current with Petri Häkkinen

Petri Häkkinen Profile picture

Stay in touch and get notified when new unrolls are available from this author!

Read all threads

This Thread may be Removed Anytime!

PDF

Twitter may remove this content at anytime! Save it as PDF for later use!

Try unrolling a thread yourself!

how to unroll video
  1. Follow @ThreadReaderApp to mention us!

  2. From a Twitter thread mention us with a keyword "unroll"
@threadreaderapp unroll

Practice here first or read more on our help page!

More from @petrih3

May 11
Reversing Bloodfest Part 2: The MYSTERY of *.IM Files! A thread🧵 Image
Last time we cracked the main graphics and sound effects banks. Unfortunately these do not contain the fullscreen background images such as the glorious title and game over screens.

Most likely the screens are stored in these pesky *.IM files that we failed to decode last time: Image
I think the screens cannot be found by scanning memory dumps because they are very likely dynamically loaded and unpacked only when needed. A 320x256 image with 32 colors (5 bitplanes) is about 50 KB. It would simply have been too costly to keep them in memory all the time.
Read 19 tweets

Did Thread Reader help you today?

Support us! We are indie developers!


This site is made by just two indie developers on a laptop doing marketing, support and development! Read more about the story.

Become a Premium Member ($3/month or $30/year) and get exclusive features!

Become Premium

Don't want to be a Premium member but still want to support us?

Make a small donation by buying us coffee ($5) or help with server cost ($10)

Donate via Paypal

Or Donate anonymously using crypto!

Ethereum

0xfe58350B80634f60Fa6Dc149a72b4DFbc17D341E copy

Bitcoin

3ATGMxNzCUFzxpMCHL5sWSt4DVtS8UqXpi copy

Thank you for your support!

Follow Us!

:(