Recently I decided to try cracking some game. Just to know if I can do it and how much effort does it require. Maybe you know my Czech friend Fandal, who is definitely most advanced cracker on our little Atari. He somehow inspired me to try it, so I decided to change one game and add multijoy4 support into it. Currently is game in working state, but not completely finished.
Game I chose is called Dynakillers:
… now I will try to explain why I made such choice in 3 main points:
1. Game is programmed by Slovak group GMG (Globe, Marco, Goldmaster)
Yes, it’s some patriotism that helped me to chose this game. GMG was group that I admired with my Atari friends long time ago (elementary school :D). They created some demos and we were looking forward to see literally anything that they did. I remember time when Dynakillers was announced, we cannot wait to play it. If you watch their old megademo called Wanted, they also announced dungeon game called Ríša Zla (demo here – i LOVE this demo song, it’s one of my favourites) which was like unbelievable and also there is announcement of action game Robot Assault (demo) that should use 256color graphics in APAC mode. Unfortunately both of these announcements did not turn into real games or even a playable demoversions.
2. Game uses sampled sounds during gameplay
Yes, you can object that there are many other games that uses samples, but Dynakillers is one of very few games, that uses samples during actual gameplay (when there is something happening during playing samples). I’d like to point out some games that uses samples (I discussed this topic with Fandal and he knew some other games with samples I did not know before):
Games that uses ingame samples during actual gameplay: Megablast, Tempest Xtreem, International Karate (it has other controls than World Karate, but Fandal does not have it – press ‘S’ to enable samples), Kennedy Approach, Dynakillers
3. Game allows to play 3 players simultaneously without additional HW required
This is actually something you might not know before, but there is option to turn on 3-player mode in settings. 3rd player is controlled by keyboard using combination of Shift, Function keys and Keyboard keys. This feature made game very good and I played it with my friends very often back in ’90s. Keyboard controls are very well designed, responsive and it does not result in blocking of controls (since Atari does not support more than 1 keyboard button pressed same time – except Shift). Anyway, there are some other Dyna Blaster clones for our 8-bit Atari, but this game is much fun than others like:
- Dyna Blaster – very fancy, but only 2 players supported
- Tekblast – nicely done, beautiful sprites , 3-player support – controls are not good, its slow (takes ages to get to other players), uses sampled explosions (i guess)
- Pang – 2 players, quite ok but slow
- Blastermind – 3 players, simple gfx, bad controls
Ok, now let’s talk about actual cracking…
Fandal provided dissasembler called RSdis created by Raster, it is internal tool so I cannot publish it. It’s just one PHP script that loads executable and returns dissassembled code which can be compiled by MADS.
Dynakillers was created for cassettes in Turbo 2000 so binary version which is available for download contains only 1 data block. Whole game is compressed and uses OSRom and BasicRom areas to store data. So I had to find where depacking routine ends and jumps to startaddress of actual game. I dumped all memory at this moment and created my own xex file with new start address. Fortunately game uses OSRom and BasicRom areas just as temporary storage.. so there is no code there, just binary data.
So now I have my own decompressed version of game that is finally suitable for disassembling.
What disassembler does?
It took start address and mapped all conditional and unconditional branches, created labels of every branch and every accessed memory area that could be traced by disassembling engine. Areas that were not accessed directly from code were just inserted as data (dta lines).
What disassembler does not?
It cannot automatically disassemble VBIs and DLIs because addresses of interrupts are set using X and Y register. It also cannot discover indirect jumps and jumps or accesses that are performed by selfchanging routines. Fortunately you can manually add additional addresses to decompiler initialization so once you discover where is DLI or VBI, you can force disassembler to disassemble those areas as well. Disassembler does not replace known labels (i.e. Rom areas) with address names, so you have to do it by yourself, which is time consuming.
Ok, so now I have disassembled source code, but what it does? If you have read this far, you should know that if you consider trying to crack some game, its not something that can be done by any n00b. As you will read below, magnitude of this crack is really great so you have to be advanced Atari coder to be able to do so.
First things first… I had to replace many generated labels (Rom area) to official address names (according to Mapping The Atari). This made code much readable (at least for me). Next step was finding routines with controls, I also renamed labels of those discovered routines to make code clearer. Then I had to replace routines of player controls by multijoy routines. Game uses almost whole memory, so I had to put this code into area of some picture. I have not finished this version yet, so yet I have not found empty space in memory – where it will be relocated eventually.
Code is sequential and also data is aligned with code. So there is literally one memory block from $0800 to $bfff. I could not just add some code inside of existing routines, because that would shift rest of code and data forward in memory which could (and in most cases it did) result in program crash. So there are 2 options how to handle it:
- When your change results in shorter code than original, you can replace original code and fill saved bytes by NOPs. This requires good knowledge of instructions in terms of their length (in bytes) that depends on used addressing modes.
- When your change results in longer code than original (or you cannot decide it before you actually code it) you can add either JMP (or JSR in some cases) which jumps into your routine placed somewhere else, which ends by RTS (when it replaces whole routine from which it was called) or returns by other JMP somewhere into original routine to continue. You still have to keep in mind that if you add JMP instruction to code, it will cost 3 bytes which have to be saved by commenting out some next instructions of original routine. In case of using JSR (jump to subroutine), you will not remain any “dead” code behind, so you have to replace existing 3-byte long instruction by JSR $xxxx and move this instruction inside that subroutine which is called.
Ok, so first step was to be able to control all 3 players using joysticks via multijoy interface. This was not that hard. If you try the game, you can see that 2 PMGs are used for each player when in 2-player mode. When you start 3-player mode, each player is made only by 1 PMG, so it was quite easy to guess that 4th PMG is unused and can be added into game.
First thing was to be able to set 4player mode in game options, I had to find correct address which contains this info and then search all its usages in further code to see how many forks are made regarding number of players. I had to change all those forks by modifying or completely replacing of many routines.
The hardest part was cracking internal game storage. Each player has its own vertical/horizontal position (PMG) also transposition to underlying characters (game map), flame length, bomb count, special abilities, colors, score and many other properties that are stored in memory and it had to be decoded and recognized in order to expand it by adding one more player to game. It was quite hard but I eventually did that and 4th player was added into game only two days after I started whole cracking job:
Game has scoreboard and it evaluates winner of final round, so if there are two players with same score at the top, you have to play one more round to decide who is the winner. This is quite easy when you have 2 or 3 players, but it’s more complicated when it comes to 4 players. So I had to replace whole routine with my own which sorts all scores and simply compares top 2 scores to get winner or tie. It also needed to expand inter-level scoreboard screens by 4th player – and also add 4th player name query. I made many changes to game, but I also preserved possibility of 2-player and 3-player game – but only using multijoy.
Everything is working fine, but I wanted to add some nice small features to game which were missing there (i.e. player color selection). During cracking this game I realized how the whole samples engine works. Its pretty straightforward, but I had to see how it works in order to understand it. Thing is, that whole gameplay is performed during VBI. I mean, player movement, animation, bomb explosions and pretty everything that happens in game… except samples. Samples are played in prime-time (I call it that way :)), so there are 4bit samples played in one channel (2 stereo channels) and sample timing is made by waiting for horizontal synchronization (sta wsync). I replaced this routine with my own, which is able to play 2 samples simultaneously so it results in better sound effect experience. This is very handy because there are more than 6 sampled special effects and when 4 players play game, they run many sfxes and this prevents most of sfx callings to be muted by next sfx calls few milliseconds later. Ideal solution would be having 1 sfx channel for each of players, but Atari cannot handle it in nice quality, so there are 2 channels used and it really makes it much better than using only 1 channel (originally).
Why is not game released yet? What is missing?
Well, gameplay is almost finished – its fully playable according to rules of original game. I would like to add one more feature there, which I keep for myself this time. I did not want to make some huge changes to game (for instance player graphics), because it will not change gameplay, just visual experience… which is not that important. You might not agree with me, especially when you know I coded Ridiculous Reality, which is eye-candy, but changing graphics was not my target when I decided to crack Dynakillers. One part that is missing and has to be recreated is whole memory map of game. I cut out some samples and graphics in order to run it and be able to modify it. So I have to create my own memory management routine which will rebuild all data (code,gfx,samples) and move them into correct memory areas (under Rom) to make everything the way it should be… and also find some place for new/modified code that will not collide with gamedata. There is more than 1kB of new code added into game, it is hard to find area for it considering game uses all memory.