Saturday, 18 November 2017

Creating a Commodore 64 Game




The Commodore 64 is the computer that always brings back happy memories for me, and I'm sure for millions of others too. As a kid I would write BASIC programs and 'dream' of being able to create a real game, but unless you could write code using Assembler getting any decent results was almost impossible.

All these years later (28 to be precise!) the C64 scene is still alive & kicking! Amazing, and I needed to be a part of it, so after purchasing (several) machines, games & books, I knew what I wanted to do - learn Assembler!!

The main advantage now is clearly the plethora of material online, as well as modern development tools. I checked a few a cross environment applications and came across CBM prg Studio written by Arthur Jordison (http://www.ajordison.co.uk/) - it's great, and includes Sprite editor, Char editor, Screen design and also some SID tools, and the ease of assembling your code and launching it in a C64 Emulator (in my case "Vice 64") is SO fantastic & quick.

I had an idea to set my expectation high, this way falling short could produce something I would be proud of :). I thought it would be cool to create something from the modern day onto the C64, the machine is clearly here to stay so the aim is to create material that could attract a new audience, wow the thought of a new generation playing games on a C64 after all these years! They probably won't appreciate the work involved in even the simplest games but could I create a game they relate too - and find entertaining!?!

I'm a big Game of Thrones fan, so I knew something based along those lines was where I wanted to start, using a Jon Snow-esque character as the main focus, but wait - first I had to start learning!! Me being me, I wanted to see some quick results, so I decided to look at creating my first sprite!

There are 2 sprite modes to choose from, and a mixture of both can be used, these are High-Res (1 colour) or Multi colour (3 colours) but lower resolution - it had to be Multi Colour for me from the offset, I wanted colour! This isn't a ZX Spectrum!

The Sprite editor in CBM prg is WYSIWYG, and I could create high-res or multi color sprites. After getting to grips with the design tools (which is easy to do) I created my first character sprite, you only have 3 colors (exc the background) to play with, so it can be quite tricky (especially from the 64s 16 colour palette)..

After a few different attempts I settled on this design..


It took me about an hour until I was happy with this, but pleased with the result, obviously I knew it needed animating so I copied the sprite into a new frame and adjusted the legs to give the effect of walking - a great feature in the CBM prg Sprite editor is that you can loop the sprites to give a preview..


Great! Very 80's looking! Next for the sword - but if it was to be a weapon I already figured it needed to be detected as a sprite in its own right - so a 2nd sprite was needed (already I'm getting ambitious!) - in CBM prg there is a 'Scratch Pad' that allows you to preview combinations of your Sprites..


I'm happy with this, I think opening the characters mouth adds to the effect!

So, this was fine for moving and 'firing' right, and to copy for the left was easy, you can copy then 'flip' the sprites using the Sprite editor..


This was all well and good but I soon realised watching a looping video did not help produce code! You can export the code for the sprites to copy into the game code (before I learned that it's much more easy to export them to a file and 'load' them in!), here is sample of the sprite code (for just 1 sprite)..

; JSwalkR1
 BYTE 0,168,0,2,168,0,10,164,0
 BYTE 10,152,0,10,149,0,10,84,0
 BYTE 10,144,3,11,148,15,42,224,62
 BYTE 42,168,248,42,171,224,42,175,128
 BYTE 171,190,0,170,120,0,170,88,0
 BYTE 170,232,0,170,168,0,170,160,0
 BYTE 172,176,0,138,40,0,10,40,0

I had already figured out how to put the sprite on screen and move it left & right, using some example written by Richard Bayliss..


These example are great because Richard takes the time to explain the code, so you can follow quite easily, here is an early example (with sprites PRIOR to the ones above) of player movement, including a simple 'jump' :) ..




It was satisfying to see the sprites alive on screen but I knew I could make them better, and I also wanted to give the character more movement, so back to the Sprite editor to create a 'facing' and 'back' sprite (again, with leg movement & sword attack)..



Happy with these, I couldn't wait to see how they looked on screen, this is when I hit my first difficulty - aligning the sword attack with the first sprite, after 4 hours (!!) I finally cracked it using some new commands 'SBC' (Subtract from accumulator) and 'ADC' (Add to accumulator) to off-set from the first sprite, along with turning the sword sprite on & off at the right time (phew!), here's how it looks..



I now did more reading and was like a sponge trying to soak up as much possible, this is when I diverted from the game to look at Bitmap graphics! I always loved the loading screens back in the day (Robocop is one I thought was cool - I loved the film when it came out, and the arcade game was just amazing). 

The code to load in an image is pretty straight-forward, and include a loop at the end which increments the border color to give the load effect we all know and love/hate :) ..


*         =   $1000

                lda $4710
                sta $d020
                sta $d021
                ldx #$00
loaddccimage
                lda $3f40,x
                sta $0400,x
                lda $4040,x
                sta $0500,x
                lda $4140,x
                sta $0600,x
                lda $4240,x
                sta $0700,x
                lda $4328,x
                sta $d800,x
                lda $4428,x
                sta $d900,x
                lda $4528,x
                sta $da00,x
                lda $4628,x
                sta $db00,x
                inx
                bne loaddccimage

                lda #$3b
                sta $d011
                lda #$18
                sta $d016
                lda #$18
                sta $d018
loop
      inc $d020

           jmp loop
 
                *=    $1FFE
                incbin "loader.prg"

But creating the image took a LOT of time (8 hours or so), it was to be the loading screen for my game and I wanted it to look dark and moody, the program I favour most for creating the right resolution and colour is 'Timanthes' (http://csdb.dk/release/?id=75871), I loaded in an image which was then cropped to size and went through and adjusted each individual pixel! There is a color limit of 4 colors per character, one of those shared across all, and using this 'Multi-Color' mode reduces the resolution to 120 x 200, so it meant a LOT of adjustments. Finally, I added "Loading" text The final result is this..



Diversion aside, it actually was a learning experience, and I thought it would be cool to use a Bitmap as a game screen (not knowing how much memory space they take!), so back into Timanthes to create a background, one of the most iconic scenes in GoT is the 'Wall', so I created a rocky background and then spent hours inserting a gate, pixel by pixel - I really take my hat off to developers back in the eighties who had to design pretty much by hand (it must have taken weeks!), here was the end result, with a VERY slow moving character sprite..



It was getting exciting at this point, and I had lots of ideas what I wanted to do, most were unrealistic for my current knowledge, such as the gate lowering down! Once again, I hit a wall (excuse the pun) with where to go next..

The reason for this was background collision - I hadn't attempted this yet and so far the bitmap background looked great but had no boundaries 😩

Taking a step back and concentrating on the sprites & movement, back to the Sprite editor then, to design a couple of 'enemies'..



Pretty scary eh!?! 

Colour is the hardest constraint to work with when designing sprites- all of the sprites (on screen at the same time) share 2 of the same colours, and 1 of their own, so these enemy sprites have blue as their own colour.

I also wanted to have an animated object so I spent some time designing a flame..



This is the point an 'interrupt' is needed - this is basically where the program 'jumps' into another activity, and you can loop this activity without running through all of the beginning instruction, it was tricky to understand but I find that https://www.c64-wiki.com/wiki/Interrupt explains things really well, and examples on http://codebase64.org/doku.php?id=base:interrupts help A LOT.

Putting these sprites on screen is straightforward enough, just setting the XY values of each sprite (and alternating the flame sprite), the current position of the sprites is managed in this routine, another excerpt from one of Bayliss' examples..


expand                
                ldx #$00
xloop           lda spritepos+$01,x
                sta $d001,x
                lda spritepos+$00,x
                asl a                   
                rol $d010  
                sta $d000,x
                inx
                inx
                cpx #$08
                bne xloop

Here's how the new sprites look on screen..



By this point I was still copying the sprite data into the main code, which was becoming tedious every time I made a small change, so I researched the loading of a binary file (containing the sprite data) as the game was compiled - this way I could avoid a lot of copy & paste. It turned out to be really simple (I wish I had learned this earlier), a load command at address $1ffe did the trick..

;Insert spritedata       
*       = $1ffe
                incbin "sprites.bin"

Sticking on the sprites, I thought it would make sense to make the enemies (or at least one of them) actually do something, so I started with making one of them walk from right to left in a continual loop, for this I had to create a few more sprite frames..



To move the sprites, I use the same code as the main character, with a boundary set left & right which reverses the direction once reach, the only difference is that this happens without any user input. Plus, the enemy wont move until the main character moves up from the starting position (just because I could!). I've also added a 2nd flame..




I thought it would be a good idea to also add a title screen, so I created a 'Snow' text (using sprites!) and then joined them together and added the sprite of the character (expanded X and Y). Finally "Press fire to start" (and a pause until fire is pressed, when the screen is cleared and new sprites loaded into the 'start' position). This is all shown at the start of the next video.

Now to add some enemy fire.. this would be a 7th sprite (from a maximum of 8 on screen at once! Well without some trickery, which I'm not capable of - yet), so a spear was designed in the Sprite tool, and then in the code I set the spear to fall vertically from the current position of the enemy, what this actually did is cause the spear to move side to side as it was falling (basically following the enemy movement), as shown in the video below..



New Title Screen and enemy fire :)


The 'Snow' text is actually made up of 5 sprites, and the character above is an expanded (X & Y) of the main character.

Time to place in a background, but not using the Bitmap graphics, I'm going to keep it 'simple' and use characters, some repeated to draw the screen. You have to also remember to copy the color into each character location, this is simple to do, and after a few hours I had a type of 'cave', as shown below..



Also in this video, I figured out how to place objects that need collecting (using characters), and added some very basic sound effects.

I found myself dipping in and out of code at this point, a little lost in which direction it was all going, so I added a 2nd moving enemy and tried to make it more difficult to collect all of the objects without getting hit by a spear, shown in this next video..


This is looking ok, but I'm not satisfied, the development has come to an almost halt, I've been experimenting with 'scrolling' backgrounds, and I want to pursue in that direct now.

Scrolling is tricky to understand (well, it was for me!), and involves a register at $d016, this basically move all of the characters on screen 1 space, this is called rough-scrolling, and a lot of games have used this, but it looks awful! SO some additional codes actually 'roll' the characters a bit at a time, giving a much smoother look. I took a simple 1 line scrolling message and expanded it move along when the character moves to the middle of the screen.

The main character sprite had some intense work here too, this is a sample of the new 'Snow' main character..


I then created some background maps (again using modified characters) and expanded to number of rows to be scrolled to 20, here's a video of this..


Some of the modified characters used to create the background, note that most are used repeatedly to create the background..


Getting this far has now taken almost 2 months of an hour or 2 a day! I'm addicted! And, I realise now that I'm quite OCD with the details!

To be continued..