A$$emble IT -
Project Housekeeping and Additional Game Programming
Project Housekeeping / Custom sprite movement / Directional Detection Movement / Game 8: Granny's Teeth (Craptastic version) / Recorded Path Movement / Timed Control Movement
/ Background + Character Animation and Star Fields / Horizontal Scrolling / GAME 9: Blastopia
the most boring subject in the Assemble It feature, but it can be a
good option for you to learn from. Although there is nothing to
download from this little chapter. There are some example games which
also use the housekeeping method anyway. So how helpful is this part of
the chapter supposed to be for you?. Let us put things this way. If you
were to create a bigger game project, and use just one assembly file to
program your game. There could be very long strings of code, and you
can easily get yourself lost. (Like you probably are already in this
part of the chapter).
Let us say for example, you are writing a
new C64 game, it has a title screen, the main game, and fully animated
end sequence. You should create SEPARATE assembly files in which should
be linked to your project. Let us take for example, Missile Blasta
(from the previous chapter) for example. The game should be split into
separate assembly files: The main project code (to assemble to should
be MISSILEBLASTA.ASM TITLESCREEN.ASM, GAMECODE.ASM, ENDING.ASM. (To
create your own assembly source code, simply do the same as you did
before when you created a new project. (ADD, NEW ASSEMBLY FILE, enter
name of your assembly code). It will be placed in the project.
Now what if you wanted to link the entire source together, which you already done - placed into separate files?
You enter !source "assemblyfile.asm"
An example for setting a Missile Blasta V2, project with additional ASM files would sort of look something like this:
;Missile Blasta - Remastered V2
;by Richard Bayliss
;For Assemble It 2018
;setup basic / sys start address (since nothing
;is overlapping memory $0801)
;insert the sprites
;insert the status screen (pre-built from older build)
;insert the game binary charset
;insert the game screen binary (made from charpad)
;insert the game screen matrix (made from charpad)
;Insert the title screen matrix (made from charpad)
;Main game code
;Insert title screen code
;Insert end sequence code
;insert the music (,,2 prg)
;goat tracker custom sound effects table
remember, any time you create a new C64 project (Which you will
discover in the next few chapters on this page), always organize your
project into separate parts. It isn't all that hard.
BACK TO TOP
Custom Sprite Movement lda objpos+4
are several different ways in which you can make a custom based
movement of an object. Let us say for example rather than a sprite
going one specific direction, you can alter directions for each sprite.
The directional detection movement
Example: Honey Bee
is also another method to sprite movement. Let us take for example you
are writing a game, such as Honey Bee, Balloonacy or any sort of single
screen dodge, collect and platform game. You would want to have objects
moving in a fixed direction, then flip from one direction to another.
This is probably the most simplest approach to custom sprite movement.
A subroutine is called to first check the value of a pointer, for
example ObjDir is set as the object direction. If the value of ObjDir
is set to a specific value, called, for example 0 = Up, 1 = Down, 2 =
Left, 3 = Right then the code should call the sprite object to move
that specific direction. That is of course until it reaches the set
limited position, from either a fixed value, or a value from a
custom pointer. Then the code forces the object to change direction.
The code snipped below shows an example of how to move a single sprite
object using that specific method.
;Move sprite, according to direction snippet
;Move sprite UP, then once set at limited position,
;switch the direction to DOWN.
lda ObjPos+1 ;Grab position of object Y
sbc #2 ;Movement speed backwards
cmp #$32 ;Stopping position
bcs UpdateUp ;Not reached destination yet
lda #DOWN ;Force DOWN to pointer ObjDir
UpdateUp ;Store new position to object Y
;Move sprite DOWN, then once set at limited position,
;switch the direction to UP.
lda Objpos+1 ;As before, grab position of object Y
adc #2 ;Movement speed forwards
cmp #$f2 ;Has sprite reached the bottom?
bcc UpdateDown ;Not reached destination yet
lda #UP ;Force UP to pointer ObjDir
UpdateDown ;Store new position to object Y
;Move sprite LEFT, then once set at limited position,
;switch the direction to RIGHT.
lda ObjPos ;This time we are using X
sbc #1 ;Movement speed backwards
cmp #$0c ;Has sprite reached left most limit
bcs UpdateLeft ;Not reached destination yet
lda #RIGHT ;Force RIGHT to pointer ObjDir
UpdateLeft ;Store new position to object X
;Move sprite RIGHT, then once set at limited position
;set the direction to LEFT.
lda ObjPos ;Grab current position of sprite
adc #1 ;Movement speed forwards
cmp #$a2 ;Has the sprite reached right most limit?
bcc UpdateRight ;Not reached destination yet
lda #LEFT ;Force direction LEFT to pointer ObjDir
UpdateRight ;Store now position to object X
code snippet above shows only an example of moving one sprite back and
forth, depending on which direction you have set the pointers. But what
if you wanted to do this to ALL 8 sprites? Well, it is possible to move
each sprite individually using multiple routines and macros. Simply
define some pointers for direction for each sprite, also define macros
correctly and call a few subroutines to test each sprite movement. Also
have a play around with the example source snippet and see what you can
make from it.
View source code
BACK TO TOP
GAME 8: Granny's Teeth (The original 4K Craptastic Compo version)
I have showed you an example of the code above to allow all 8 sprites
move according to path/direction. We are going to show you an example
game, which uses a similar approach, although it is quite an old game.
Back in 2016 I entered the C64 craptastic game making compo, which was
to create and develop a game that squeezed into 4K (after compression
through the ALZ64 compressor). It was a platform game, inspired by one
of those games creator games, from back in the early-mid 1980's. This
game was made to look a bit like one of those Games Creator/Creations
games, only just for fun. However, to prove that this game was NOT made
with the games creator. A complete project binary+source has been
provided to accompany this chapter on fixed sprite movement and
So what's this game all about?. You play
the role of Granny, who has tucked her grandchildren into bed. Locked
all of the doors, and placed her teeth safely into her room and went to
sleep. The next morning, Granny wakes up to find her teeth had gone
missing. Also, she finds that her house has been ransacked. The
floorboard had collapsed revealing that her house was built over a
swimming pool. Her cat and dog are on the loose, a bird has flown in,
and who the heck let that spider in?. If all was that bad? Her teeth
had gone missing. The kids were playing with her teeth and thrown them
into the fishbowl. It is now up to you to try and fish your teeth out.
must jump from platform, to platform, avoiding contact with any tacks
strewn on the floor. She cannot swim either. She has to avoid any
moving objects or pets in sight and pick up her teeth. You will score
bonus points and move on to the next level for every time teeth have
been picked up.
This game also features an implementation of Achim Volker's useful Sprite/Background collision which
calculates the X, Y position of the player sprite, and checks whether
or not the lower part of the sprite is touching the pixel of the
background (When using software sprite/background based collision, X
and Y position of the player sprite must be accurately set to the pixel
which the player object lands. This game also uses the directional
control of the sprite movement, similar to very first example in this
category. A software sprite/sprite collision detection is used. The
project also uses the project housekeeping method which helps organize
the program files and code. The active assembly file is of course
Granny.asm. So this file should be marked as active source when
compiling the binary data and code.
Download the full C64 Studio binary + source code to Granny's Teeth
BACK TO TOP
You are writing a space
shoot 'em up. You have a player which is controlled by a joystick. The
player can fire, but there are also enemies that can move around. There
are two different ways in which you could create an attack movement
pattern for an enemy sprite. They are as follows:
Recorded Path Movement
recorded path movement is simply created utility based. The utility
based path movement, is where you record and create the movement,
according to the position of a sprite you set it. A maximum of 256
units is used for making your own alien path movement. One
particular tool which can produce custom object movements, based on
sprite position is the TND Alien Movement Maker V1.0+ (Available
in the utilities section). This tool allows you set a starting position
to a sprite and then record its movement. Be very careful when using
this. You'll need to remember the screen size which you plan your game
project. I first created my own source code to do this for the
game X-Force (pictured above). A small code example for moving an
object based on table movement would look something like this:
;Example path movement code (based on reading the table)
ldx Enemy1MovePointer ;Pointer to set position of enemy
lda PositionTable,x ;Read PositionTableX to grab a X position
sta EnemySpritePosX ;Write the position to the sprite X position
lda PositionTable+$100,x ;Read PositionTableY to grab a Y position
sta EnemySpritePosY ;Write the position to the sprite Y position
;Increment value of
pointer loop for moving object
beq RemoveEnemy1 ;Until all 256 byts are read
inc Enemy1MovePointer ;Increment EnemySpritePos X+Y table by 1 byte
256 bytes from X+Y position table complete.
;Reset the pointer of the enemy
jsr SetNextTable ;Call a subroutine to move the next table.
;Example binary file (inside project)
*=$7000 ;Or where to put the movement data
Please also note that this method uses slightly more memory.
Alternatively, if you cannot wait all that long .... You can check out
issue 27 of Scene World, and check out the source code for Zap Zone
Alternatively, if you want to learn an even bigger/advanced phase in game programming. You could always try Star Toast from
issue 28 of Scene World magazine. Please note that both games were
coded in 64ASM, which means that you will need to alter some of the
pseudo commands, should you wish to port those games to C64STUDIO, and
tweak the code for fun. (Or make your own game from it).
BACK TO TOP
The Timed Control Movement
is also another example, which is slightly trickier, compared to the
option (above). Especially if you want to have objects using timed
movement, based on behaviour patterns. This is because you need to use
MORE pointers, although it does use up less memory. The trick does work a
treat. You first set the starting X, Y position of a sprite outside the
border. Set the
pointer/delay and then another pointer read, to read the table
position, also your read the speed table of the sprite. After the time
of one position has expired, the table read pointer increments to the
next position on the table, recording the next X,Y speed (direction) of
the object. Then store it to the sprite position. Sometimes this can
result into awkward consequences, but eventually you can get some great
enemy movement patterns - and not just going one straight direction. Of
course, you will need to create/generate a table of bytes that set the
time value for each movement, X-Speed, Y-Speed of moving sprite, and of
course some other bits. You will be able to see a full implementation
of enemy movement code in GAME 9 - BLASTOPIA. Which is also available
on this chapter.
;Example timed speed object movement
;Calculate flip properties - So that
;the movement can be triggered to change
;Actual flip test for alien 1
lda Alien1FlipDelay ;Alien flip delay test ... Counter
beq Alien1SwitchToNextMotion ;Switch to next motion from table
;Switch alien motion
;Reset alien flip delay
ldx Alien1FlipPointer ;Read pointer
lda Alien1_XSpeed,x ;Read selected X direction/speed from table
sta Alien1XSpeedStore ;Store it to alien speed X (Alien1SpeedStore)
lda Alien1_YSpeed,x ;Read selected Y direction/speed from table
sta Alien1YSpeedStore ;Store it to alien speed Y (Alien1SpeedStore)
;Has the table reached the last
byte on each speed table?
beq Alien1SpeedReset ;Yes ... Reset the speed table.
inc Alien1FlipPointer ;Then move to next table setup (To be Self-modified)
;Reset flip table and delay for alien 1
;Time alien 1's movement. Has it reach its movement deadline
;if so. Switch over to the next set of properties for the next
;alien. Then spawn the next alien object.
BACK TO TOP
Background Character Animation and Starfields
producing a game or a demo, it is possible to generate animation
through character sets. There are different methods in which you can
animate a character. You could scroll a character, (or a set of
characters) to form an effect, or maybe roll through a set of
characters one after another by using frames. Here are a few examples
to try in C64Studio.
The scrolling character
most easiest way to scroll a character would be to scroll it
left/right. Or alternatively you could scroll the character up or down.
The concept would be to pick out the address of the 8 bytes of a
character you wish to scroll and produce a simple loop to roll the
character along. Scrolling characters left/right are the most simplest
way to move them. However if you wanted to scroll characters UP/DOWN
then you would need to generate some pointers for those.
A small example of scrolling a char left:
;Small example of scrolling a character left
!basic 2064 ;SYS2064
lda #$18 ;Set character mode to $2000-$2800
;Fill the entire screen with zeroed character
lda #$00 ;Very first char (@)
;Scroll the very first character
;to the left.
lda $2000,x ;Each char = 8 bytes.
rol $2000,x ;Rotate char to the left by one byte
cpx #8 ;8 bytes read
;Let's make a custom character for char 0 (Alternatively
;as a shortcut, you can import a charset using the !bin command
;End of program
Without changing the additional source in GREEN. Copy the code and change the YELLOW example to this next example below.
A small example of scrolling a character to the right
lda $2000,x ;Each char = 8 bytes.
ror $2000,x ;Rotate char to the right
the characters left/right are much easy to perform. A word of warning
however. If you try and scroll multicolour chars, they will change
colour. In order to solve this problem. You could add and extra LSR ROR
$CHAR, or ASL ROL $CHAR. This should prevent colour shifts of each
Moving Charsets Up / Down
What if you wanted
to move characters up or down? It works completely differently. You
would need to make a temp byte to store the current character byte to.
Scroll the character in a forward or backward loop (depending on the
direction your character is scrolling) then store the stored loop to
either the FIRST or LAST byte of the character that is being read.
A small example of scrolling a character up
lda $2001,x ;Fetch last char
sta $2000,x ;move to the next char
sta $2007 ;Grab last character
CharbyteStore !byte 0
A small example of scrolling a character down
sta CharByteStore ;We just reverse the above
ldx #$07 ;process
is also possible to animate charsets by swapping their own frames. You
will want to work out how many frames your animation charset should use
and how to come about with them. We simply copy 8 bytes of the first
character, and paste it to the last character. Then call a simple loop
which pulls each of the 8 bytes of each character frame. So that there
is an actual character animation. This works like this:
cpx #8 ;8 bytes = 1 char
cpx #$40 ;Max, 8 charaacter frames!
AnimDelay !byte 0
char-based star fields can be quite awkward, but are actually VERY EASY
to implement. All you need is to know the memory address of where the
frames for your char star field is. Then roll each byte forward or
backwards and follow on, for the other charsets. Here is a small
example on how a star field animation is formed (Using different
layers). The example code below uses a star field that consists of four
characters in the char set. $2000-$2020. A pixel skip is placed in the
code, in order to rotate the same byte of the whole 4 characters. It is
possible to increase the size of the star field. Simply by generating
;Character based wrap-around animation. Produce
;a starfield, by rolling the bytes of the
;selected layers to be animated at different speeds
;Animate the first chosen pixel on the
;current charset - Scroll it to the left.
That covers this section on character animation.
BACK TO TOP
SCREEN HORIZONTAL SCROLLING
an earlier chapter, I showed you how to scroll text messages. This time
round, I am going to show you how to scroll more than just text. Let us
assume you are writing a new C64 game, and you want to scroll a
background for the first time, without having to generate blocks/maps.
Well, it is possible. What you have to do is set a speed of a scrolling
pointer. Then we pull characters back through a loop. Once that has
been done, a memory read of the map area is then placed as last
character for each row. Then we update the code to increment to the
next LO-BYTE of the map column address on the picked row. A code
snippet below shows this simple example.
;Simple Screen Horizontal Scrolling
;by Richard Bayliss
SCRN = $0400
;Start by setting the scroll speed.
;Shift a byte from each character on screen
;then move it to the next character on screen.
;Split this into four different loops. (5 rows per
ldx #00 ;Grab last value of char - then add it
lda SCRN+1,x ;Grab one screen column higher
sta SCRN,x ;pull it to the previous column
ldx #00 ;Do the same thing for the next set of rows
ldx #00 ;Once again do the same for the next set of rows
ldx #00 ;Finally for the last 5 rows
;Now place the self-mod stored character on to the
;last byte of each row.
;Now to get a new character fetched from the map, increment
;the lo/byte of the self-modifying addresses in order to
;allow all 256 bytes to update the last character that was
;used after every frame scrolled.
if you wanted to initialise the map so it starts again you would need
to LOAD the LO-BYTE of the map address, and then STORE it to self-mod
code. For example, if MAPROW address of map to be read = $4000. We
place the low byte of MAPROW to the self mod one byte after the address
where the label pointer mapSM1 is. Also we place the hi byte of MAPROW
to the self mod address 2 bytes after the address where the label
pointer mapSM1+1 is. To get the whole 20 rows cycling like the first
MAPROW, we select every 256th address of low and hibyte to set up the
map row / column.
VIEW COMPLETE SOURCE
don't forget to use charpad to draw your own test charset and map
(Export your test project as charset, and map). For this example, your
map needs to be 20 rows by 256 columns with tiles disabled.
should you wish to try and build scrolling background using
BLOCKS+MAPS, instead. I strongly recommend that you check out Achim
Volker's chapter on column map extraction, on Codebase64.
BACK TO TOP
GAME 10 - BLASTOPIA
I have covered a lot of tips in the previous few sub chapters that are
in this chapter. I have decided to come up with a brand new game
project, for us to play with. As a fan of the retro blasting shoot 'em
up genre. I have come up with a new shoot 'em up specially for this
project. If you want to just play the original game, without the
source, you will find it on the TND games page, under BLASTOPIA :).
This awesome game features a short front end and end screen, 8
fast paced levels of alien blasting mayhem (all controlled by
pointers), 24 different alien sprites, camels (which you must rescue
during play), sprite/sprite collision, sprite/background collision
(Based on Achim Volker's codebase
example). There's also plenty of thumping trance music and sound
effects. Hopefully you should have loads of fun playing this game (or
maybe exploring through the code). Full instructions on how to play the
game, can be found in the RELEASE folder. Which also consists with a
finally compiled disk and .tap version (with tape master if you want to
write this game to a real tape).
About the project:
are the game sprites, that I will be using for Blastopia. There are 4
frames for each sprite, except for the bullet and the explosion
animation. The player ship sprite animation are the first 4 sprites, a
bullet is the second. The explosion sprites, followed by all of the
aliens. The last 4 sprites are the camels which the player will have to
rescue. Each sprite has its own colour and animation scheme.
is the complete character set for BLASTOPIA. It represents all of the
characters that builds each level map screen. If you load in one of the
example level files into charpad and then use IMPORT RAW/BIN FILE
/ CHARSET, select the folder FILES and select gamecharset.bin. You
should get this set of characters. The characters 0 - 3 have been
chosen to be animated as a star field (More on this in the tutorial).
Character 42 has been chosen as the lazer gate character. Characters 33
and 38 represent the flashing lights for the landing pad. The rest of
the graphics (Except for the letters, symbol and numbers) are deadly
characters - The landing pad characters 35-40 (except for
character 38) are special characters.
you can see the whole map of LEVEL 1, which consists of 256 characters
per row and 20 rows. There are also additional charpad level
files where each map is built by 5 rows and 64 columns of 4x4 tiles.
Disabling the tile mode gives you tiles. The last 5 rows are saved for a blank gap, and the game's status panel.
LEVEL MAP CRUNCHING / ADDING A BACKWARDS DECRUNCHER
the files DIR are all of the example maps (Un-Compressed). These maps
have been extracted as RAW binary format. However, if you're making a
full game, you'll want to consider crunching each level map. So that
they will fit in the game code. To crunch each exported map. You can
use the EXOMIZER to crunch the memory down, and use a DECRUNCHER source
program to extract the data. The command used as an example:
exomizer mem -l $b400 level1map.bin,$9ffe -o level1map_cr.prg -P0
Please also note, if you are not using Exomizer V3, but V2 instead you won't need to -P0 prefix
$b400 has been set for the address where to place the crunched data.
is where the data should decrunch to ($9ffe is 2 bytes offset before
the actual decrunch address for raw files. PRG source files can use
$a000 instead of $9ffe).
The -P0 is a prefix for using
V2.0 level compression. As V3 hasn't got an actual decrunch source yet.
For the decruncher, you will need DASM cross assembler, and edit
WRAP2.s in notepad to set the address of the decruncher. Then in the
command prompt enter
DASM wrap2.s -oleveldecruncher.prg
edited the wrap2.s to set the address of the exomizer decruncher at
$c400. Once assembled through DASM to leveldecruncher.prg, the file
gets copied over to the FILES folder, along with the other binary data,
including sprites, alien sprite formation data, charset, uncrunched
SETTING UP SPRITE FORMATION
provided with the binary and source code. I have provided an
exclusively modified version of my Alien Formation Maker V1.0+, which
has been made for BLASTOPIA. So you can have a go at creating your own
alien formation, and then import it into the game code later on (if you
want to that is). The aliens should have a selected movement during the
game. While using the editor press F1, F3, F5, F7 to alter the
formation speed. Select inside the red border (where the cursor cannot
be seen) by placing the cursor as the
start position. Then hold down the fire button to record the path
movement by playing around with the joystick. You have 256 units to use
up per formation. These will be used quite quickly with slower
movements. Watch you don't make too any mistakes. 256 bytes of the
alien formation are stored for X ($3000-$30ff) and Y ($3100-31ff). If
you are finished with an alien formation and you still have units spare
- make sure it ends inside the red border. Otherwise the alien
formation will look very odd indeeed :)
THE GAME MUSIC
have chosen three tunes crammed to one file, done in Goat Tracker V2.7.
this example. The theme is once again, like with a few of my latest
space shoot 'em ups, TRANCE themed. The game is intending to be a
fast-paced game, and the music is set to be fast and very trance like.
game also will feature SFX, based on the instrument editor made in Goat
Tracker. The three tunes picked are title music, in game music and end
screen music. Game Over has sound effects.
NOW LET'S CREATE THE GAME
the complete source (or view each source separately in TXT format by
clicking on the link, corresponding to the code. If you choose to
download the code and the source. Load the project in to C64Studio
V5.8, or higher. The
filename is BLASTOPIA.S64. The project folder contains multiple files
are as follows You are also required EXOMIZER V2 or higher, in
c:\EXOMIZER\WIN32 directory, otherwise delete the postbuild from
blastopia.asm and manually compress the program with a cross platform or native C64 packer/cruncher of your own choice :).
blastiopa.asm - This is the main file that needs to be assembled
variables.asm - A list of variables, that has been linked to the code
titlescreen.asm - Quick code for the front end
gamecode.asm - The main game code
pointers.asm - Series of pointers and text that the game code uses for varied tasks
- This is a command, which was set to import a charpad map, and in
post-build properties. A command to Exomizer is used to level crunch
the imported map. (exomizer -l mem $xxxx loadname.prg -o
project also has a series of binary and PRG files which have also been
included in the ZIP archive. These are part of the game project. The
selected binary/program files are read in blastopia.asm
won't go through the entire source individually, as the code is all
there is self-detailed. I'll just give you a brief explanation about
each source file. Simply click on the source file to view the code in
.txt format (Or go all the way to the bottom of this chapter and
download the entire C64Studio project.
source consists of importing/linking the binary data files and possibly additional source code. First a starting
level is set in the code (Default is 0). We then generate the program
file to assemble to called "BLASTOPIA.PRG". Then link the source variables.asm to the source code.
$0800-$0fff is the address where the game graphics charset data is being imported to.
FORMATION TABLE WRITING
has been reserved for the copied set level X and Y alien formation
data. This is self-modified in the game's code for every time an alien
formation is complete, a new one gets copied over to that specific
address. $1000 = X formation, and $1100 = Y formation
$2000-$3c00 is being used for all of the sprites. I'm using default memory BANK $03 for the screen memory.
STARTING MAP (Plain Stars)
inserts the game's starting map (The plain starfield), which is used
for the title screen, the main game starting point, level complete and
also the game's ending.
TITLE CODE, GAME CODE, TABLES AND POINTERS + ALIEN FORMATION DATA
$4000 - $8EFF consists of the main code
and pointers. The address starts by switching the KERNAL mode, to be
allowed to use addresses exceeding $9000, and before $D000. The game
will be using standard KERNAL interrupts. Also we call one time code
that checks the C64's system (PAL/NTSC) and also checks for a hidden
cheat. Which if detected BIT out the decrementing LIVES counter. Also
imported into the code area (as additional pointers) are all 24
different alien formation tables (extracted from a .D64 which consists
of the BLASTOPIA ALIEN FORMATION MAKER). Also the low/hi byte of
the title screen code is set to the RESTORE pointers. So that every
time the RESTORE key is pressed, the title screen restarts.
$8F00 - $9fff
is the Goat Tracker music player. You may use any other music player,
but the SFX won't work, and will probably crash the player. Zeropage
for GoatTracker tunes is best set to $fd-$ff.
DECOMPRESSED MAP (Full Level Map)
the game map (after it has been decompressed by Exomizer's decrunch
routine). The LEVELSTART+LEVELEND labels represent the starting and
ending position of the compressed map data. If you look at C64Studio
V5.8, and assemble the program. The specific addresses of where the
data/code lies is displayed on the left of the screen.
EXOMIZER COMPRESSED LEVEL MAPS
contains all of the crunched level maps. Each level map has labels with
END. Which is used as the low/hi-byte address for decrunching the level
EXOMIZER DECRUNCHER SOURCE
$c400-$c5ff is the Exomizer's level backwards decruncher source code.
STATUS /SCORE PANEL SCREEN
$c600-$c6c8 is the game status panel / scoring matrix
TITLE SCREEN LOGO
$c700-$c900 is the title screen logo matrix
A list of variables/labels set for specific addresses, values and zeropage pointers
First of all the source code imports the titlescreen.asm
code, which indicates the code for the main front end for the game.
More on this later. After the title screen code has finished running.
GAMESTART is called which does a fresh start of the game.
sets up all of the graphics data, resets the quota, score and other
bits, should a new game start. Test background multi colours are set -
although for the game start that isn't really needed, since a table of
colours is normally read. Level pointers are set, and the score is
zeroed (Probably yet again not required, since the titlescreen code
does all that).
NEWLEVEL initialises any existing interrupts in
the background. This basically kills all IRQs while trying to set up
new levels . The shield count is reset to 50 on the player's shield
counter. The alien X and Y formation table is cleaned up with
padded zeroes. Specific pointers are reset, so that the correct aliens
and formation are used when starting a brand new game or level. Then we
call a loop, which prepares the level. LEVELPOINTER cycles through the
level properties. If the level is OVER the last level, then the code
automatically jumps to the end screen code. Otherwise, all low and high
bytes of the MAP DECRUNCH END ADDRESSES are stored to the self-mod area
of the EXOMIZER decrunch routine. The LOW+HI BYTE values of the colour
table are read and stored to specific colour areas - so that each level
has its own set colour. LEVEL SELECT TABLES, set up the selection of
aliens and their formation according to level. Finally
CAMELQUOTADIGITLEFT and CAMELQUOTADIGITRIGHT will set up the camel
rescue quota according to level.
After the level selection
code process has been made. The code then writes the new LEVEL ALIEN
SELECT table, to the ACTUAL alien select table. There are 24 bytes
stored since each level uses 24 attack formations. The SID chip
is initialised, so during the map decrunch process everything is
silent. The level map is then decrunched.
the status panel and the starfield, which will afterwards display the
game complete text. It will also prompt the player to press fire. Then
records the final score and checks if it is a new high score. If the
player's score is a new high score, then the title screen will display
the new high score. The end screen also resets the game interrupts and
set the END MUSIC to initialise and play. Also if after pressing fire to
exit the well done screen. If the cheat mode has been detected then the
player will NOT have a new high score. The cheat mode is then disabled
and the code will run back to the title screen.
will decrunch the level map data which the end low/hi byte address has
been set to decrunch the program backwards until the decruncher reaches
the load address of the file. The map is extracted in full to
The game code continues by initialising the
starting position of ALL ROWS AND COLUMNS of the map. Also alien
properties are reset for the chosen level. The default starting
position for sprites are set, along with the colour settings .
Additional pointers for indicating the player dead, lazer time and
lazer on are also initialised. The game IRQs are set up initialising
the in game music and playing it. The frame of the player's sprite is
set by default.
MAINGAMESTART disables the launch pad, also
draws the starfield starting map, and also sets the game char colour
redraws the status panel.
GAMELOOP Synchronizes the game
timer and expands the screen position so that sprites can use the full
screen area.. A pause key (CONTROL) is checked to see whether on not
the key is pressed. If CONTROL is pressed. The game is paused. If FIRE
on joystick in port 2 is pressed then the game can continue to run its
main body of the code.
- Scrolls the game map. This is made by pulling 20 rows of characters
from the last character position to the previous character position.
The map code then positions the current pointer position of the map to
the very last character. Then the code increments the position of the
low byte of each character. Basically after one full draw, the map will
move on to the next map draw column. Then resets after 256 bytes has
been read. After all a single byte can be from 0 - 255.
- Animates the starfield. Basically it scrolls the selected bytes of
pixels over each character, depending on which byte has been chosen.
ASL, ROL will roll bytes to the left, LSR ROR will roll bytes to the
- Checks whether or not the lazer character is switched on or off. If
the lazer is off, then a blank char replaces the lazer char. Otherwise
if it is on, the char is switched on. The lazer is controlled by a
looping timer and two logic switches (LAZERON = 0 represents OFF,
LAZERON = 1 represents ON)
ANIMSPRITES - Creates animation
frames from sprite value tables and stores those to custom pointers -
The speed of the animation is controlled by a delay. Max of 4 bytes is
read for the sprite animation.
- Sets up the properties of the player. It checks whether or not the
player is alive or dead. If the player is dead, then the explosion
animation takes place. Otherwise if the player is alive, the player can
move, and animate. There's also code for bullet properties
included in the PLAYERPROPERTIES, which allows the player to shoot fast
bullets unless one bullet sprite is on screen. If the bullet is offset,
then it can be fired again.
TESTALIENPROPERTIES - Tests alien
properties. Macro code is created to check for each alien property,
control its formation, etc. If the alien is alive (ALIENDEAD = 0) and
ALIENOFFSET = 0 and ALIENSPAWNED = 1. This means that the alien is able
to move around the screen. ALIENDEAD will trigger the explosion of the
alien (if enabled) then resets the alien to ALIENOFFSET mode. The macro
code is LINKED to all 5 aliens that are being blasted. If all aliens
are OFFSET. A spawn timer is reset, then after the timer
expired, spawns the aliens on to the screen with their own attack
TESTCAMELPROPERTIES - Tests whether or not a
complete fleet of aliens have been destroyed. If so, then the camel is
released from the last alien shot.
SPRITETOSPRITE - This tests
the sprite to sprite collision. The values of the collision
co-ordinates (from variables) are set from the player and bullet. Then
some macros are made to check each alien collision. For example if
ALIEN1DEAD = 1, then no collision should take place. If the alien hits
the player, then the shield should decrease (If the player is not
invulnerable). If an alien hits a bullet and is not dead. The bullet is
removed, and then the alien is triggered to be dead. Where
TESTALIENPROPERTIES will then force the alien to explode. The alien
shot is stored to a pointer, which the camel gets released from if all
5 aliens of the same fleet have been shot.
This tests the position of the player. The player collision position
has been set to the central area of the ship (1 single character). If
that area of the player's hit hits any background while the player is
invulnerable. Nothing should happen. However, if the player hits the
background, and it isn't a specific character. Like with the sprite to
sprite collision, the background drains the player's shield. Only chars
0-3 are excluded from the deadly background, and aware classed as safe
chars. The landing pad 34-40 (excluding 38) is checked - If PADENABLED
= 1 then the landing pad is NOT a deadly background. It is used to
detect that the level is complete (Where the background flash and level
complete message is triggered). The lazer character (42) is only deadly
when the pointer LAZERON = 1. Otherwise if LAZERON=0, the lazer is
removed and collision with that specific char is ignored.
Checks whether or not the landing pad is enabled or not. If the landing
pad is enabled, it calls out a timed animation to set the lights
flashing (Simply by swapping two char animation frames from two
- Checks to see whether or not
the camel pickup quota has been reached. If it has, then the camels
cannot be released, and also the code will trigger the landing pad for
availability. The camel quota check code will check fro a direct match
between CAMELQUOTA and PICKEDQUOTA. The landing pad will not be enabled
quota doesn't match. Therefore the player has to keep on blasting.
of all pointers that support the code in the entire game project. For
example sprite animation frames, level settings, etc. A lot of the
stuff in the code and pointers have its own explanation. So there's no
need for me to go through it all again :)
the interrupts, displays the credits and also shows the previous and
high score. The status panel is then reset to zero
And there you
go. A quick and brief explanation of some of the source code. I
recommend you explore it, as you'll probably won't grasp it straight
away, but at least you'll know how to code a basic horizontal scrolling
shoot 'em up with its own limitations.
BACK TO TOP