Almost completely (except for the lettering) hand drawn. Trying some brush pens with ecoline and other water based ink. Lines done with ballpoint.
Almost completely (except for the lettering) hand drawn. Trying some brush pens with ecoline and other water based ink. Lines done with ballpoint.
For a change of pace I decided to use a few of my trainers (and my new map feature) to try and finish this game for once (never reached the end before!).
At first I implemented the ‘never lose your sword’, ‘giant invulnerability’ and ‘endless lives’ trainer options.
Regrettably I played without making any screenshots until the last, so there wont be many pictures.
OK, I knew the game was hard, but I didn’t exactly know just how hard. With just 5 lives, you have to navigate a maze, make no mistakes in the use of swords, don’t make too many mistakes with wrong turns (where you get a insta-kill), make not too many mistakes with the giants and do some pixel perfect movement to kill the samurai.
I think there are some points where there are samurai you can’t realistically kill. And even with all these trainers it takes a lot of time to come to the place where the princess is.
The game manual tells you that after you have saved the princess you have to get her back to the escape boat while being chased by Li Chi, the angry father.
And boy is he angry! Even with a walking cane he’s very fast. Every screen after finding the princess you have about a second before the father enters the scene and starts chasing you. And you’d better not make a mistake turning a corner because, he’ll be on you right away.
And making a mistake turning a corner isn’t as unlikely as it sounds, because the collision with the environment is not based on visual information, but based on location on an invisible tile system. On the picture you see a tree on the bottom right of the player, that looks to have some free space in its upper left corner. But that’s not passable, because it is part of the tree’s tile.
And so you may have been perfect in the game up to meeting the princess but then you have to navigate the maze and evade the father with just 5 lives. And going into a dead end means another life gone.
In practice for me it would be impossible.
I ended up finding and implementing another trainer option, where the father can’t kill you (quite similar to the trainer option of invulnerability to samurai which I already found, so not hard to do).
In total I think I spent about 15-20 minutes including making the extra trainer option to get to this point:
You can see the father in red below and me and the princess in yellow next to the boat (the sprites overlap so they’re hard to distinguish).
Also you can see I have a score of 103%. I think that’s because I killed three samurai the makers didn’t think I would be able to kill.
Playing this way gave me three ideas I would like to add to the game:
The first one is done, but the other two need some work. But first get the map done properly.
In this part I’m going to describe how I removed a ‘feature’ of the game that I consider to be a bug.
But first: Maybe you imaginary readers would like to have the disassembled source I use, so I uploaded the currenty version. I still add comments to it when I find out stuff, so there will be newer versions later (1).
In the game there is a finite number of swords. Some are just lying around, and some can be retrieved after being thrown by enemies. But once a thrown sword is picked up, that enemy will never throw another sword.
And a sword thrown at an enemy will be spent as well.
So you’d better make good use of that sword. That is part of the challenge of the game: you really have to think about when you use your sword on what.
But you could be carrying a sword and then die by walking to another screen you’ve never been to and be immediately killed by an enemy.
You will not only loose a life but also that sword, probably making the game impossible to finish (I erroneously stated that you would lose a sword when killed by a bridge giant, but that’s not true).
I think that’s unfair so I will try to fix that. Furthermore I think I will not add it to the game as an optional trainer option but always incorporate that in the game.
I wondered how much code this game has. I stripped all data and comments from my disassemled document and ended up with less than 2000 lines of code.
Considering how little one line of assembly code can do (for instance, ‘add 1 to x register’) that’s not much!
Now I have to find the piece of code responsible for handling the acquiring and losing of a sword.
You get a sword by walking over one. That happens when the sprites of the player and the sprite of a sword collide.
The Commodore 64 has a memory location that detects sprite collisions: $D01E (to be more accurate: the video chip detects sprite collisions and updates $D01E accordingly). In the first episode I’ve shown a small part where that memory is read to detect a collision of the player with a giant’s arm. But that part only codes for collision with the giants’ arms. So where else is collision detected? Sadly that is the only part where $D01E is read, so collision detection works differently for picking up swords.
So what now? By now I have a pretty good understanding of the code, so I know where collision detection takes place in the code, but there is is a different way to solve the puzzle: if you press the joystick button AND you have a sword then a sword is thrown.
Finding the code for that is not that hard. The joystick states can be read from memory $DC00 and $DC01 (joystick port 2 resp. 1). I know which port is used so I can search with VICE for the byte sequence 8D 00 DC (LDA $DC00, it could also be LDX or LDY, but that’s less likely)(2).
You get a few hits but one looks promising. Here is the exerpt of the code (you can see some auto-commented code but also some code I added when figuring out how it works).
Two earlier discoveries help me here (3):
& right giant
|not used||enemy sword||sword & key& treasure|
L9C00 LDY $49 ; BNE L9C57 ; LDA $8E ; bit 7 set in $8E: has sword BPL L9C56 ; LDA LDC00 ; Data Port A (Keyboard, Joystick, Paddles, Light-Pen) 7-0 Write Keyboard Column Values for Keyboard Scan 7-6-2006 Read Paddles on Port A / B (01 = Port A, 10 = Port B) 4 Joystick A Fire Button: 1 = Fire 3-2-2006 Paddle Fire Buttons 3-0 Joystick A Direction (0-15) MOS 6526 Complex Interface Adapter (CIA) #2 AND #$10 ; FIRE button bit. Is zero if pressed! BEQ L9C15 ; [code that checks keyboard is left out here, the game can be controlled by keyboard and joystick] L9C15 LDX L01 ; copy player pos to sword pos L9C17 LDA LD000,X ; Sprite 0 X Pos MOS 6566 VIDEO INTERFACE CONTROLLER (VIC) STA LD00A,X ; Sprite 5 X Pos MOS 6566 VIDEO INTERFACE CONTROLLER (VIC) DEX ; BPL L9C17 ; LDY L4343 ; 4343 = player direction? STY L9C8C ; LDA L40A8,Y ; STA spr6point ; set sprite pointer depending on player direction LDX L40A4,Y ; STX $4B ; sword direction? LDA L40A0,Y ; some more table reading CLC ; and adding that to the sprite position based on that table ADC LD00A,X ; Sprite 5 X Pos MOS 6566 VIDEO INTERFACE CONTROLLER (VIC) STA LD00A,X ; Sprite 5 X Pos MOS 6566 VIDEO INTERFACE CONTROLLER (VIC) LDA #$0F ; set color of the sprite STA LD02C ; Sprite 5 Color MOS 6566 VIDEO INTERFACE CONTROLLER (VIC) LDA #$60 ; not sure what this does, yet STA $49 ; LDX #$05 ; position sprite 5 JSR L0DA0 ; LDA #$00 ; set 0 in three memory locations STA $8E ; set to not carrying sword STA L4371 ; STA L436F ; [....]
On a side note: I think there is a bug at ‘adc ld00a,x’. That part places the sword sprite in an offset from the sprite position. But X is always 1 at that point of the code, so indexed addressing is useless here. It could be replaced by ‘adc ld00b’. Now only D00B (Y position of sprite) is changedI think it was meant to be in the loop so the X position would also be changed.
The end of the code here is interesting: 3 memory locations are set to zero. Maybe one of them means ‘not carrying sword’?
I can see $8E is also read in the beginning of the subroutine. It determines if the joystick button is read at all.
So it probably it determines if the player has a sword or not.
We can test it by changing that value live with VICE. It would mean the player could throw a sword again:
Does it work?
So I know what to change. I also found out that address $4371 is as a sword-indicator but only for the visual part. Putting value #$10 in it, makes sure the player walks holding a sword.
If you start to look for parts where both are reset (which typically happens when you die or start a new game), you find a few regions, but the region starting at $9443 seems to be the right part.
; handle death? L9443 LDA #$12 ; only sprites 1 and 5 are multicolour, the brige parts STA LD01C ; Sprites 0-7 Multi-Color Mode Select: 1 = M.C.M. MOS 6566 VIDEO INTERFACE CONTROLLER (VIC) LDA #$00 ; STA LD017 ; Sprites 0-7 Expand 2x Vertical (Y) MOS 6566 VIDEO INTERFACE CONTROLLER (VIC) >> STA L4371 ; 0 = sprite carrying no sword (only visual) LDA #$38 ; start position STA $L5F ; screen number LDX #$01 ; STX $D015 ; Sprite display Enable: 1 = Enable MOS 6566 VIDEO INTERFACE CONTROLLER (VIC) L9476 LDA #$00 ; STA $60 ; STA $61 ; STA $49 ; >> L947E STA $8E ; $8E, value #$80 means, carrying sword LDY #$63 ; STY spr0point ; LDA #$02 ; STA $3F ; JMP L9936 ; goto Main Loop
So I have the way to ‘bugfix’ the game. It will be incorporated in the trained version.
I’d like to end with an animation of a feature I’m working on: the map. I succeeded in generating a map of the game and the objects when the game starts. You can toggle the map. It’s not finished yet, but almost there (I’ll change the colors I promise!).
(1): I made my disassembler program before I used version control software. The newest file I used turned out to have several bugs, that don’t bother me, but make it less readable: you can’t tell the difference between zero page addressing ($xx) and numbers (#$xx).
(2): The A register can be used to for arithmetic (adding subtracting) and bit manipulation which is useful if want to know stuff about the joystick. Bit 5 for instance is the fire button, so AND #$10 sets the zero bit in the status register if bit 5 is not set in the A register.
(3): knowledge of the C64 is necessary to understand what’s happening. Here: knowing $D015 turns sprites on where each bit codes for a sprite.
Oh oh! I came up with an alternative fact myself: it wasn’t Trump who mentioned ‘alternative facts’!
Lately I’ve been in the mood for non-digital pen drawings. The problem I have with those drawings is that there is no ‘undo’. For lettering that’s not a big deal. I think the ‘post-production’ digital lettering has a charm of its own.
But shading or colouring is more problematic. I like the quick sloppy strokes I do by hand but they’re hardly ever good in one take (technically they’re never good, but I don’t go for technically good). And messing up means doing it all over again.
I could make copies, but that’s a hassle too.
Two days ago I came up with another idea: I had a plastic wrapping lying about and I have some whiteboard markers. I can wrap the plastic around the drawing and colour with the markers on the plastic. It turns out that works very well!
Colouring gives a sort of watercolour effect, which I like and wiping works great. At the moment I only have a few standard harsh colours, but I’m planning to buy more (especially greys).
Here are some pictures ‘ behind the scenes’ :
This part I’ll be writing about ripping the music from the game (‘hacking, ‘cracking’, ‘ripping’ the vocabulary of the scene sounds a bit like a pro-wrestling pre-match-rant, doesn’t it?).
One of the reasons the C64 was so popular, was because of the great soundchip and the music that was produced for it. Hackers ripped the music so it could be played on it’s own or as part of a demo. By adding some metadata, the C64 standalone music program can even be converted to a SID file (named after the C64 sound chip) and played by programs developed for modern PC’s.
Ripping music means: extracting the code that plays the music and the accompanying music data and putting it in a single package, so it can be played by itself, without the game.
As it is a game from 1985, the music has been ripped already a long time ago by others. You can find it as part of the High Voltage Sid collection (you can do a search for ‘willow pattern’ on their site).
I use a lot of text to explain stuff. To accompany the stream of words I offer a link to the files that are the result of this ‘session’:
Files included are the assembly code (kickassembler format), the resulting basic-executable program and the music data as binary that is used in the code. Also a resulting SID file is made.
It’s only a few months ago I ripped the music, so I could use some modern tools. The tools I’ve used for this are Vice, an IDE with Assembler a Hex Editor (I’m using HxD editor) and a tool I made myself in Excel.
Most music routines on a C64 have the same basic idea. At regular intervals a counter is decreased . When the counter reaches zero a new musical’event like ‘play a note’ is read and the counter gets the value for the time till the next musical event. There can be all kinds of other things going on, but this is the general method.
The best way to get a regular interval in C64 assembly is by using a Interrupt.
Interrupts are ways of the ‘outside world’ (outside for the CPU that is, so a signal from another chip for instance) to interrupt the regular flow of an executing program. The CPU has a special bit on its status register to deal with interrupts.
A simplified way to describe the working of the CPU of a C64:
But before each instruction-read the CPU checks if the interrupt bit in the CPU’s status register is set. If so, the normal flow is suspended and the CPU starts executing from the address that is coded in a certain part of memory (the interrupt pointer).
A commonly used type of Interrupt for the C64 has its pointer in address $0314/$0315. Scanning memory for the two following bytes $14 and $03 (the C64 is ‘little endian)’ can give you locations where that memory is used or set.
Or you can see what the current values are of that pointer. In Willow Pattern Adventure (WPA) it points to location $0E00.
Interrupts can be used for several types of functionality. Music is one, updating graphics or scanning the keyboard another. WPA has a pretty simple interrupt: it is only used for the music.
If I import all 64k of memory to my Excel program I can trace what parts of memory are used by giving it the start address ($0E00). It will trace the code, take all jumps and all subroutines. Every address tracked will be designated as code, the rest of memory as data.
That way you’ll end up with a very comprehensive view of the code, every byte that has nothing to do with the music is not disassembled but rendered as bytes.
Here’s the beginning of the code, remember this will be called about every 50th of a second (one tick) on a PAL system.
JSR L0F66 ; this subroutine is called every tick: it slightly changes the frequency of the notes played: vibrato DEC L0ED5 ; this is the counter I mentioned before BEQ L0E0B ; if the counter reaches zero goto L0E0B, the main music player routine, to get a new note JMP $EA31 ; return to the standard normal C64 Kernal Interrupt routine which does things like checking the keyboard L0E0B LDA #0C ; set the counter to a standard value. Unusual: the same amount of time between all events! STA L0ED5 ; it is used so you can have the same piece of music in different speeds by changing this value LDA $FA ; [.....]
I now have the routine that plays the music. But I also need the routine that does the initial sound setup. It is likely to be the same part where the interrupt pointer is set.
Using the Vice Monitor I find a few promising parts of memory:
The second address is where the pointer is set to $EA31 which is the standard C64 Interrupt address. I can ignore that. The first address is where the interrupt is set to $0E00 and looks like a small subroutine where some sound things are set and the interrupt pointer.
Now I need to know where the music data is stored.
I can see in the code that indirect addressing is used for reading from memory:
L0E3A LDA(FA),Y ; an address between parenthesis means A is not read from $FA but the address referenced in $FA/$FB with Y value addded to it BEQ L0E57 ; if the note value is zero, no new note is played, a pretty wasteful method, specially because it still uses two bytes STA L0ECF ; the note is also stored for vibrato purposes STA $D400 ; store note value in low frequency register of Voice 1 of the SID-Chip
You could look up the current value in memory but it could change to all values.
I use a plugin for Vice, ICU64. It can show what parts of memory are updated in real time. This is a graphic representation of the memory. Bytes that are read or written to, light up and fade out.
The opening screen is a static screen, so probably all that changes is the music. I guess the green parts are the music data. It moves at a constant speed which is what you would expect from the music routine: I saw in the code it reads notes at a constant interval of n-ticks.
You can zoom in on the green dots and read the actual addresses.
The in-game music is different, so probably occupies a different part of memory, but you can use the same method for that. Just start the game and watch the memory.
Now I have all parts for making a standalone musicplayer. I save the memory containing the music as binary data and export the code as a text file. My Excel program can automatically create labels for addresses used in my code so I can easily relocate the code.
The result is a single file program that can be started from basic and plays the music. But I would like to hear the intro and in-game music, so I add some code that if you run the setup again, the other music starts to play.
The beginning of the code now looks like this:
.pc = $0801 //start of the memory for a basic program .var music1_speed=$0e//$10 //some variables .var music2_speed=$0a//$0c :BasicUpstart($0810) // a way to easily add a basic program that runs machine code from address in parenthesis .pc = $0810 ldx #$00 lda l0f4e //if this address is two, change to zero cmp #$02 beq !+ ldx #$02 //otherwise set to two !: stx l0f4e //this address controls which music is played jsr r0edb // call music setup rts //return from subroutine, back to basic
This all works and can easily be incorporated into another program like an intro.
I know cracking a game is not so special anymore and I’m not too sure if my home-made SID tunes will impress anyone. Also the Willow Pattern tune uses very few computer cycles, which might be useful if I use it in my intro.
But using the same music for the intro and the game sounds a bit lame.
What can I do to make it just a bit special?
I’ll just reverse the music! Really, I have no idea why I came up with that but at least it probably has not been done before.
I have to make a few adjustments to the code:
This all worked pretty well. But to give it that ‘real backwards feeling’ I also have to reverse the way the notes sound.
Sound is synthesized on a C64 using the ADSR Attack Decay Sustain Release technique.
A certain note increases to maximum volume during an Attack phase, drops to a Sustain level in the Decay phase and when triggered will drop to volume 0 in the Release phase. Those four values can be set for each note.
The original tune has a pretty ‘staccato’ sound, caused by an attack time of 0. Almost immediately the note goes to maximum volume.
To create a ‘backwards’ effect you can make a note slowly ‘swell’ to maximum volume.
It does have the disadvantage that notes take longer to be heard. In the backwards tune some notes disappear. But since it doesn’t really resemble the original tune anymore that doesn’t matter much.
Well, that’s almost it for now. As a finalcz touch I would like to convert the tune to .SID format so it could be played with a SID player on a modern PC. Not that the reversed tune sounds that great, but I never made a SID before.
The changes in the code are easy: you have to have an initialization routine that is called with the song number in the A register.
This will do:
[... I removed the basic loader, that will not be used ...] .pc = $1000 / I relocate it to address $1000, not strictly neccesary. asl //a*2, multiply the A register by two because the original routine uses 0 and 2 as song numbers sta l0f4e // store that value in the memory that is already used in the original code for song number jsr r0edb // call the already existing initialization rts //... done!
Now I have to add some meta data to the file. On hvsc.com there is a good description of the file format, so with a Hex editor and that description the file is changed in a jiffy.
I’ve added the resulting SID file to the dropbox folder that is linked in the beginning of this post (so long ago!)
Not sure what I’ll be focussing on next time. I think I will be writing about trainer functionality.
So here’s some background about the project:
First of all: The Commodore 64: it was the computer I grew up with. I loved it. It was quite popular and there were thousands of games. There is an EMORMOUS amount of information about this computer so I won’t go into that here.
You also had hackers, people (often very young), that managed to circumvent the copy protection (‘cracking’) and distributed the cracked games.
The hacker scene was very competitive and they were always trying to be the first to
crack a game or impress by putting a nice intro or trainer-function in the game (they even hacked a game of mine!). In the beginning the intros were simple but the competetiveness brought out the best in the young crackers and after a while you could have intros that had better graphics, sound and programming than the game itself.
Cracking was (and is) illegal and so there was always a air of mystery surrounding hackers. For me hackers were cool!
I wanted to be one, but didn’t know where to start, didn’t know anyone in the scene , I didn’t even know anyone who had a C64 (my brother had the contacts).
Logically I didn’t know much about the tools of the ‘trade’, but we had an expansion you could fit into a slot for the C64: the Power cartridge.
It had all kinds of cool things, like build-in speedloaders, BASIC expansion, a machine code monitor and a way of saving the complete state of the computer to disk.
Those last two options were what made it possible for me to crack a game:
At one point my brother borrowed an original game for copying purposes. It had some copy protection, but with the cartridge you could load the game and then save the state of the computer. Loading that state meant you could always resume from that point. Such a state could not be distributed as a crack, because you needed that same cartridge to load such a state.
But if you opened the machine code monitor you could save parts of memory like regular files and try to find a start address. Then you could load those files, call the starting address (‘SYS’ to start a piece of machine code from BASIC) and maybe if you had all relevant pieces of memory loaded the game would run.
The game in question was not very well protected: you could see the BASIC SYS command in memory and calling that after a reset would run the game. So the challenge was to find the relevant pieces of memory.
To combine those pieces to one part and adding an intro and a music was a big ask for me. With the help of my brother we made some kind of multi-piece loader. It used a weird feature of Commodore BASIC where if you loaded a piece of memory from a running BASIC program, the BASIC program would start from the beginning after loading but with all values of the variables intact .
Even to the standards of hacks then it was a bad hack. But a good starting point for this project!
The game I talk about is The Willow Pattern Adventure A week ago I bought an original of this game. Seemed only reasonable to know what I talk about, and try to repeat the hack I did 30 years ago. You can see a screenshot of the packaging here.
Although I hacked the game, I must admit that I didn’t play it that much at the time. It looked nice and had some OK music, but we had hundreds of games and this game was quite tough! You had no map and the game was also very unforgiving: you could easily make a mistake which made it impossible to finish the game. And it wasn’t some kind of casual game, you had to invest a lot of time even if you played flawless.
But worst of all were the Giants. You had to jump from stone to stone while giants would try to grab you. And being hit or falling not only meant losing a life, it could also mean losing a sword, which could make the game unfinishable:
Jump jump jump jump, phew!, kill a samurai (5), oh no another samurai! now I must go back to get another sword, jump jump jump jump, try to get a sword, die, try again, pick up the sword, jump jump jump DIE LOSE SWORD END OF GAME!.
It didn’t take much of this for me to give up and try something else.
It’s almost the end of the second part. Still not much code, but the next parts will be better (or worse for non-coders).
I will leave with a nice little cheat I discovered during this project. It helps to avoid the grabbing hands of the Giants. Just follow these steps (4):
What is does is change this piece of code
1 2 3
L0C30 LDA LD01E ; Sprite to Sprite Collision Detect MOS 6566 VIDEO INTERFACE CONTROLLER (VIC) LSR ; BCS L0C37 ;
1 2 3
L0C30 LDA LD01E ; Sprite to Sprite Collision Detect MOS 6566 VIDEO INTERFACE CONTROLLER (VIC) CLC ; BCS L0C37 ;
What the code does is read some memory, $D01E where the video chip registers if a sprite hits another sprite. If that sprite is hit, the corresponding bit (in this case the first) is set to one.
LSR, shifts that first bit into the Carry bit of the CPU’s status register. The next instruction BCS is a conditional jump if the carry-bit is set (in this case if a collision has occured).
By changing LSR to CLC, you don’t shift the first bit, but instead always clear the carry bit (which is what CLC does), so the jump is never taken: a hit is now never registered.
(1) quote from the book ‘Only you can save mankind’ by Terry Pratchett. And pretty accurate: those screenshots always were from a version for a more advanced computer.
(2) pimped commodore taken from http://www.remix64.com/board/viewtopic.php?t=4619
(3) picture by Grass
(4) If you’re playing on an emulator you can change memory without resetting. In VICE open monitor with ALT-M, then type ‘> 0C33 18’ then leave the monitor with ‘x’.
(5) Yes, it was a game set in China that had Samurai.