Wednesday, November 9, 2011

Part Seven - Hitting the memory and motivation barrier

Throughout September and October of 2009 I worked tirelessly to implement all the various gameplay features. I went through all the transitional objects and implemented them one by one.
Unfortunately I quickly ran into problems due to the fact that I didn't have a double-buffered drawing system.

This video was captured on 25th October 2009, and it shows that basically all of the gameplay features work now. But there's horrible ugly flashing artifacts and generally the performance is rather bad.

I did try various ways to see if I could hide the drawing artifacts, by not wiping the blocks that are redrawn, but rather redrawing them in a way that will clear the previously drawn pixels. This works a bit for the gates (except in the beginning, when they still overlap with the floor), but in general I had to come to the conclusion that this is not a solution for everything.
But I hadn't given up yet.

Then something interesting happened. On 4th November 2009, STE'86 (Steven Day) of Compunet fame posted on the Lemon64 forum that he was working on converting the Prince of Persia animations to C64 sprites:

People showed some interest, including Poharai Attila, who did the old preview for the C64 that I mentioned in my first post. I was still a long way from finishing my version, but I clearly had progressed far. So I panicked. I had to announce what I was doing to make sure nobody else spends a lot of time getting to where I am now only to find out that was much further along. I knew that this would be a serious bummer. :)

So I made a post stating that I'm working on Prince of Persia, but with the intention of not letting myself get dragged into a long discussion that would divert my time from the project. But some people reacted positively and that felt good. I sent a few screenshots and movies to STE'86 and his partner in crime, JCB (PeteD), to prove to them that I've reached a playable prototype stage.

At this point I was still convinced that the REU as a requirement would be enough to fit the game into memory. I considered a cartridge-based solution as an alternative for people without REU but didn't know any details about the cartridge technology, so I only considered it as something for later.
To give you an idea, this is what my memory map looked like in November of 2009:

; Runtime memory:
; $0000-$03FF : Game state + various buffers
; $0400-$3FFF : Code
; $4000-$5FFF : Bitmap
; $6000-$63FF : Screen + Sprite pointers
; $6400-$6FFF : Sprite buffers
; $7000-$79FF : Seqtable
; $7A00-$7EAF : Framedef list
; $7EB0-$7FFF : Tables 2
; $8000-$A80B : Background imagetable
; $A80C-$AFFF : FREE (to be used by additional bg images in palace levels)
; $B000-$B5FF : Tables 3
; $BC00-$BDFD : Kid imagetable header (pointers into REU where to get each image from)
; $BDFE-$BFFF : Kid image buffer
; $C000-$DFFF : Mask bitmap
; $E000-$EBFF : FREE => music/sfx
; $EC00-$F4FF : Level blueprint
; $F500-$FFE8 : Tables

I did put all the Kid images into the REU (pre-mirrored) and DMA-ed them in when needed. Doing the same for background images turned out to be prohibitively slow when redrawing, so I decided to keep them in memory.
The size of the code had almost reached the $4000 barrier, but I didn't have any guard AI or sword fighting in there yet.
And then of course I would need another set of bitmap and screen for the double buffering.

I spent some time to auto-convert the images for a guard, and added those to the REU memory too, but I didn't get anywhere with the code, so I didn't really use them in game yet. I spent some time moving things around and changing the memory layout, and many of the more daring changes would've required me to rewrite a lot of the existing masking code. It started to get annoying.

As it turned out, I had drained my motivation reservoir. By now I had worked six months on this project. While I made some progress, I had no real plan for how to finish it. Having announced it also took a huge chunk out of my desire to further spend time working on this game.

So I slowly stopped working on Prince of Persia. I kept thinking about possible ways to solve my issues, but soon enough I was getting interested in other things and my mind was no longer on the case. It would take 17 months for me to get back to that project.

I leave you this time with the thing that I've promised at the beginning. All my reverse-engineering work of the Apple II version, labels and disassembler output. It's not 100% complete, since I didn't fully investigate the low-level Apple II bits that I didn't need to understand, but it's more than enough to document the high-level logic and game structure which makes it possible to port it to another platform.
You can download the package and get cracking, but please do read the readme.txt file first.

The next time you'll learn how I re-booted the project and what happened next.


  1. Wow, I know how it feels when you run out of memory and motivation. Good to know that you got back to the project after all.

  2. Thanks for the interesting updates. :)

  3. Thanks for source code!
    Have to admire your persistance !!! (even with that 17! month gap ;) ).

  4. I'm still really enjoying these updates. Great to know there will be an end :)

  5. I have to admit that I can't wait to read your next blog post. Please!

  6. Fantastic port, and absolutely brilliant blog about how you made it. I see you have met most of the walls I have in my "secret project". The cool thing about porting games is all the choices you have to make, charmap versus bitmap being a vital one. I think all in all you would have less hazzle with all of the other issues if you had worked on a charmap instead, even if it meant modifying the graphics and animation slightly. And I know the feeling about being faithful to the original, and for that you have been true! Excellent work!

  7. Sorry, though I know I'm late on that, it's still an interesting read. Also, to put my skills on the test to "think in hex" :)

    ; $B000-$B5FF : Tables 3
    ; $BC00-$BDFD : Kid imagetable header (pointers into REU where to get each image from)

    So you obviously had some yet unused extra free space from $B600 to $BBFF, hadn't you? Or there's a typo in :)