home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Scene World 22
/
Scene_World_22_2014-01-22_People_of_Liberty_Scene_World_Magazine_Side_1_of_3.d64
/
planet.code+
< prev
next >
Wrap
Text File
|
2023-02-26
|
35KB
|
1,688 lines
;--------------------------------------
;Scene World #22
;
;C64 6502 Assembly Game Programming
;tutorial
;--------------------------------------
;PLANET POPPER V2
;================
;Programming, Planet Sprites,
;Charset and Music by Richard Bayliss
;Bitmap screen and game sprites by
;Johan Janssen.
;--------------------------------------
;Last time in the assembly programming
;tutorial. We started making a simple
;shoot 'em up game. Now we are going
;to tweak it to make it look better.
;In this part of the tutorial, we are
;going to turn it into an actual game.
;Also slightly different to the
;previous chapter.
;The new version of the game will
;allow you to display a picture, a new
;charset, new sprites and also play
;music. We have started from scratch
;to make way for some new features in
;the game. Enjoy playing around with
;this source.
;We also have a simple front end for
;the game as well.
;--------------------------------------
;First of all, some variables in which
;represent various features for the
;game.
raspos1 = $00;Raster position before
;calling an interrupt
;frame.
raspos2 = $2e;Raster position for irq1
;
;Displays game background
;and game sprites
raspos3 = $f1;Raster position for irq2
;
;Displays status bar for
;score. Also hides
;visible sprites.
raspos4 = $fa;Raster position for
;syncronizing timers and
;playing music.
delaytime = $0801 ;Sync timer
;Object pointers in which are used as a
;ghost sprite. This needs to be used to
;store to an actual hardware sprite
;pointer.
scoreval = $07c7 ;First digit for score
shieldval = $07e5;First Digit for the
;Player's shield.
objpos = $0810 ;Temporary software
;sprite pointers. For
;positioning sprites.
animpointer = $0820 ;Counter for main
;sprite animation
animdelay = $0821 ;Delay pointer for
;sprite animation.
planetstore1 = $0822;Planet animation
planetstore2 = $0823;storage pointers.
planetstore3 = $0824;Where a frame is
planetstore4 = $0825;read from the
planetstore5 = $0826;frame table and
planetstore6 = $0827;then stored to the
playerstore = $0828 ;planets. Or Player
explodedelay = $0829 ;Timing and count
explodeptr = $082a ;for the explosion
explodestore = $082b ;animation
collstore = $0830 ;Software Sprite
;to sprite
;collision
planet1hit = $0840 ;Pointers to check
planet2hit = $0841 ;to see whether or
planet3hit = $0842 ;not the planets
planet4hit = $0852 ;have been shot by
planet5hit = $0862 ;the player.
planet6hit = $0872 ;
planet1speed = $0873 ;Generated speed
planet2speed = $0874 ;pointers in which
planet3speed = $0875 ;are stored to the
planet4speed = $0876 ;planet's movement
planet5speed = $0877 ;routine.
planet6speed = $0878 ;
planetdir = $0879 ;Direction pointer
planettime = $087a ;Duration and
dirpointer = $087b ;direction for
;moving planets
colourstore = $0880 ;Sprite colour
;pointers for
;raster IRQ.
randcounter = $0890 ;Pointer to call
;a random position
randpos = $0891 ;Random position
randspeed = $0892 ;Random speed
firebutton = $0893 ;Joystick fire
;pressed and
;released.
xpos = $0894 ;Title soft scroll
;pointer
titlescreentext = $3800;Where the title
;screen text has
;been stored.
scrolltext = $3c00 ;Same for the
;scrolling msg.
titlelast = $06c0 ;First digit for
;last score
titlebest = $06c0+40 ;First digit for
;high score.
;Music ...
;
;Most music editors/composers in the
;C64 demo scene plays tunes using:
;
;LDA #$00
;JSR $1000 ;init music
;
;JSR $1003
;
;DMC, JCH, GoatTracker, Voicetracker,
;SidWizard, etc use this.
;
songno = $00 ;Song number
musicinit = $1000 ;Initialise music
musicplay = $1003 ;Play music
;Start code. Using crunchers / packers
;set $2800 as JMP address. Antwere else
;will not really help much :) #$37 as
;$01 can be set.
*= $2800
;Initialize Richard's music, as
;this will be used only once for both
;front end and game.
lda #songno
jsr musicinit
titlescreen
sei ;Set IRQ interrupt
lda #$00 ;Black border
sta $d020 ;and screen.
sta $d021
;Setup the title screen text display
ldx #$00 ;
puttitle lda $3800,x ;Copy whole text
sta $0400,x ;memory from
lda $3900,x ;$3800-$3be7 and
sta $0500,x ;put it in the
lda $3a00,x ;default screen
sta $0600,x ;position in VIC
lda $3ae8,x ;Bank #$03.
sta $06e8,x
lda #$0c ;Grey text
sta $d800,x
sta $d900,x
sta $da00,x
sta $dae8,x
inx
bne puttitle
;Ensure all sprites are switched off.
lda #$00
sta $d015
sta $d01b
sta $d01d
sta $d017
;Setup up VIC Bank #$03, and other
;hardware pointers for front end.
lda #$03 ;VIC Bank #$03
sta $dd00
lda #$08 ;Multicolour OFF
sta $d016
lda #$18 ;Charset at $2000
sta $d018
lda #$00 ;Initialize the
sta firebutton ;fire button +
sta xpos ;soft scroll
lda #<scrolltext ;And of
sta messread+1 ;course reset
lda #>scrolltext ;the scroll
sta messread+2 ;message.
;Copy the final score and high score to
;where final and top scores are set.
ldx #$00
copyscores
lda finalscore,x
sta titlelast,x
lda topscore,x
sta titlebest,x
inx
cpx #6
bne copyscores
;Setup title screen interrupts.
lda #<tirq1 ;Low bit of irq
sta $0314 ;Store to vector
lda #>tirq1 ;Hi bit of irq
sta $0315 ;Store to vector
lda #raspos1;Default raster
sta $d012 ;position
lda #$7f ;CIA set to
sta $dc0d ;Interrupt
lda #$1b ;
sta $d011 ;Screen on
lda #$01 ;IRQ sync set
sta $d01a
ror $d019
cli ;Clear IRQ flag
;The main loop of the title screen.
titleloop
lda #0 ;Synchronize the
sta delaytime ;timer.
cmp delaytime
beq *-3
jsr scrollmess ;Call scroller
lda $dc00 ;Wait for fire
lsr a ;on joystick
lsr a ;in port 2
lsr a
lsr a
lsr a
bit firebutton
ror firebutton
bmi titleloop
bvc titleloop
jmp gamestart ;Run game.
;The main scroll text routine.
scrollmess lda xpos ;Control the
sec ;speed and the
sbc #1 ;smoothness of the
and #$07 ;scroll.
sta xpos
bcs endscr
ldx #$00 ;Pull all chars
scroll lda $07c1,x ;inside the loop
sta $07c0,x ;continuously.
inx
cpx #40 ;40 chars row
bne scroll
messread lda scrolltext ;Check if @ is
cmp #$00 ;detected ...
bne nowrap
lda #<scrolltext ;Reset text
sta messread+1 ;for scroll
lda #>scrolltext ;text.
sta messread+2
jmp messread
nowrap sta $07e7
inc messread+1
bne endscr
inc messread+2
endscr rts
;Interrupts for the title screen
tirq1 asl $d019 ;SYNC interrupt
lda $dc0d ;--------------
sta $dd0d
lda #raspos2 ;Second raster
sta $d012
lda xpos ;Smooth scroll at
sta $d016 ;bottom of screen
lda #$01
sta delaytime;Add 1 Sync timer
lda #<tirq2 ;Point low and hi
sta $0314 ;bits to next
lda #>tirq2 ;interrupt TIRQ2
sta $0315
pla ;Infinite loop
tay
pla
tax
pla
rti
tirq2 asl $d019 ;Do same as above
lda #raspos3 ;3rd raster set
sta $d012
lda #$08 ;No smooth scroll
sta $d016 ;or multicolour
lda #<tirq3 ;Point to next
sta $0314 ;interrupt TIRQ3
lda #>tirq3
sta $0315
pla
tay
pla
tax
pla
rti
tirq3 asl $d019 ;Third interrupt
lda #raspos4 ;4th raster
sta $d012
lda xpos ;Smooth scroll
sta $d016
jsr musicplay ;Play music
lda #<tirq1 ;Point back to
sta $0314 ;interrupt1
lda #>tirq1
sta $0315
pla ;Inifinite loop
tay
pla
tax
pla
rti
;Main game code. GAMESTART.
gamestart
sei
;Put all of the colour data into the
;COLOUR RAM ($d800). The picture's
;colour RAM data lies at $5800. I used
;VIDCOM paint for this example.
ldx #$00
setcolrs lda $5800,x
sta $d800,x
lda $5900,x
sta $d900,x
lda $5a00,x
sta $da00,x
lda $5ae8,x
sta $dae8,x
inx
bne setcolrs
;Draw the status chars on to the bottom
;of the screen. Text must be fixed
;to display correctly.
ldx #$00
drawstatus
lda status,x
cmp #$3f ;If lower case then
bcc statok ;no change.
sec
sbc #$40
statok sta $07c0,x
lda #$0e ;Light blue text
sta $dbc0,x
inx
cpx #$28 ;40 chars
bne drawstatus
;Enable sprites on screen. Also allow
;multicolour
lda #$ff
sta $d015 ;Sprites on
sta $d01c ;Sprite MCOL on
;Setup the main 2 outline colours for
;every single sprite.
lda #$0b
sta $d025 ;Spr. Mcol 1
lda #$01
sta $d026 ;Spr. Mcol 2
;Now setup the sprite position ghost
;regs as a start up.
ldx #$00
setupspr lda dfltpos,x
sta objpos,x
inx
cpx #$10
bne setupspr
;Also setup the default frame for the
;sprites. Because of the sprites
;appearing on the space background (A
;VIDCOM bitmap). The SCREEN SPRITE RAM
;at $5FF8-$5FFF is being used for the
;main sprite type. Also we are setting
;up the default sprite colours for
;everything.
ldx #$00
setsprdflt
lda dfltframe,x
sta $5ff8,x
lda dfltcols,x
sta colourstore,x
inx
cpx #$08
bne setsprdflt
;Initialise all game pointers so we
;can default this game. (See pointers
;to understand what those are).
lda #$00 ;Initialize all.
sta animdelay ;pointers.
sta animpointer
sta planet1hit
sta planet2hit
sta planet3hit
sta planet4hit
sta planet5hit
sta planet6hit
sta explodedelay
sta explodeptr
sta randcounter
sta firebutton
sta planettime
sta dirpointer
sta planetdir
lda #$03 ;Start frame
sta explodestore ;explosion
lda #1 ;Default
sta planet1speed ;speed for
lda #2 ;all planets.
sta planet2speed
lda #3
sta planet3speed
lda #4
sta planet4speed
lda #3
sta planet5speed
lda #2
sta planet6speed
;Set low+hi byte pointers to the IRQ
;raster interrupt vectors.
lda #<irq1
sta $0314
lda #>irq1
sta $0315
;Initialise raster position
lda #raspos1
sta $d012
;Setup CIA Timers
lda #$7f
sta $dc0d
;Screen enabled
lda #$1b
sta $d011
;Delay interrupt registers to slow
;things down a little.
lda #$01
sta $d01a
ror $d019
cli ;Clear IRQ flag
;This is our main in game loop. Sync
;timer and call additional routines.
mainloop lda #$00
sta delaytime
cmp delaytime
beq *-3
jsr expandpos
jsr moveplayer
jsr movebullet
jsr moveplanets
jsr animation
jsr collision
jmp mainloop
;Expand the sprite positions and
;correctly display them in place to the
;hardware sprite registry.
expandpos ldx #$00
exploop lda objpos+1,x
sta $d001,x
lda objpos+0,x
asl a
ror $d010
sta $d000,x
inx
inx
cpx #$10
bne exploop
rts
;Control the player using a joystick
;plugged into port 2.
moveplayer
ldy #$02 ;Default ship
sty $5ff8 ;frame. (Ship front)
lda $dc00 ;Read joystick p2
lsr a
bcs notup
ldx objpos+1 ;Move player up
dex
dex
cpx #$32
bcs upok
ldx #$32
upok stx objpos+1
notup lsr a
bcs notdown
ldx objpos+1 ;Move player down
inx
inx
cpx #$d0
bcc downok
ldx #$d0
downok stx objpos+1
notdown lsr a
bcs notleft
ldy #$00 ;Ship tilts left
sty $5ff8
ldx objpos ;Move ship left
dex
cpx #$0c
bcs leftok
ldx #$0c
leftok stx objpos
notleft lsr a
bcs notright
ldy #$01 ;Ship tilts right
sty $5ff8
ldx objpos ;Move ship right
inx
cpx #$a2
bcc rightok
ldx #$a2
rightok stx objpos
;When pressing fire, the player cannot
;autofire when shooting a laser. This
;is where the BIT firebutton and ROR
;firebutton command takes place.
notright lsr a
bit firebutton
ror firebutton
bmi notfire
bvc notfire
;Is the bullet still on screen and
;moving. If so, then ignore the
;process, else disable the button
;pressed. Until released again.
ldy objpos+2
cpy #$00
bne lockfire
ldy objpos
sty objpos+2
ldy objpos+1
sty objpos+3
lockfire lda #$00
sta firebutton
notfire
rts
;Test the player's bullet to see if
;it is enabled. If so, then the bullet
;can move. Otherwise ignore it!
movebullet
ldy objpos+3
dey ;A few of these are for
dey ;speed.
dey
dey
dey
dey
dey
dey
dey
dey
dey
dey
cpy #$0b ;Offset
bcs notoffset
ldy #$00
sty objpos+2
notoffset sty objpos+3
rts
;Call subroutines to move planets. Last
;time, we used a loop. This time round
;since there are going to be different
;things occuring to the game. We are
;going to use a subroutine for each
;planet. Mainly to test each planet.
moveplanets
jsr timemovement
jsr testplanet1
jsr testplanet2
jsr testplanet3
jsr testplanet4
jsr testplanet5
jsr testplanet6
rts
;Time X movement of the planets.
;Default = 0
timemovement
lda planettime
cmp #$a8
beq movedir
inc planettime
rts
movedir lda #$00
sta planettime
ldx dirpointer
lda dirtable,x
sta planetdir
inx
cpx #25
beq resetpdir
inc dirpointer
rts
resetpdir
ldx #$00
stx dirpointer
rts
;Test the first planet. If planet is
;hit. Don't let it move. Otherwise
;allow it to animate and move. Other
;Planet tests are exactly the same.
testplanet1
lda planet1hit ;Planet hit?
cmp #$01
beq destroyplanet1
lda planetstore1;Animate
sta $5ffa
lda objpos+4
clc
adc planetdir
sta objpos+4 ;Move X-POS
lda objpos+5 ;Move Y-POS
clc
adc planet1speed
cmp #$fa
bcc p1ok
jmp resetplan1
p1ok sta objpos+5
rts
destroyplanet1
jsr explode ;Blow up
lda explodestore;Planet
sta $5ffa
ldx explodeptr
cpx #7
beq resetplan1
rts
resetplan1
jsr randomizer
lda randspeed
sta planet1speed
lda randpos
sta objpos+4
lda #$00
sta objpos+5
sta planet1hit
rts
;Now test the second planet
testplanet2
lda planet2hit
cmp #$01
beq destroyplanet2
lda planetstore2
sta $5ffb
lda objpos+6
clc
adc planetdir
sta objpos+6
lda objpos+7
clc
adc planet2speed
cmp #$fa
bcc p2ok
jmp resetplan2
p2ok sta objpos+7
rts
destroyplanet2
jsr explode
lda explodestore
sta $5ffb
ldx explodeptr
cpx #7
beq resetplan2
rts
resetplan2
jsr randomizer
lda randspeed
sta planet2speed
lda randpos
sta objpos+6
lda #$00
sta objpos+7
sta planet2hit
rts
;Now test the third planet
testplanet3
lda planet3hit
cmp #$01
beq destroyplanet3
lda planetstore3
sta $5ffc
lda objpos+8
clc
adc planetdir
sta objpos+8
lda objpos+9
clc
adc planet3speed
cmp #$fa
bcc p3ok
jmp resetplan3
p3ok sta objpos+9
rts
destroyplanet3
jsr explode
lda explodestore
sta $5ffc
ldx explodeptr
cpx #7
beq resetplan3
rts
resetplan3
jsr randomizer
lda randpos
sta objpos+8
lda randspeed
sta planet3speed
lda #$00
sta objpos+9
sta planet3hit
rts
;Test the forth planet
testplanet4
lda planet4hit
cmp #$01
beq destroyplanet4
lda planetstore4
sta $5ffd
lda objpos+10
clc
adc planetdir
sta objpos+10
lda objpos+11
clc
adc planet4speed
cmp #$fa
bcc p4ok
jmp resetplan4
p4ok sta objpos+11
rts
destroyplanet4
jsr explode
lda explodestore
sta $5ffd
ldx explodeptr
cpx #7
beq resetplan4
rts
resetplan4
jsr randomizer
lda randpos
sta objpos+10
lda randspeed
sta planet4speed
lda #$00
sta objpos+11
lda #$00
sta planet4hit
rts
;Test the fith planet
testplanet5
lda planet5hit
cmp #$01
beq destroyplanet5
lda planetstore5
sta $5ffe
lda objpos+12
clc
adc planetdir
sta objpos+12
lda objpos+13
clc
adc planet5speed
cmp #$fa
bcc p5ok
jmp resetplanet5
p5ok sta objpos+13
rts
destroyplanet5
jsr explode
lda explodestore
sta $5ffe
ldx explodeptr
cpx #7
beq resetplanet5
rts
resetplanet5 jsr randomizer
lda randpos
sta objpos+12
lda randspeed
sta planet5speed
lda #$00
sta objpos+13
sta planet5hit
rts
;Test the last planet
testplanet6
lda planet6hit
cmp #$01
beq destroyplanet6
lda planetstore6
sta $5fff
lda objpos+14
clc
adc planetdir
sta objpos+14
lda objpos+15
clc
adc planet6speed
cmp #$fa
bcc p6ok
jmp resetplan6
p6ok sta objpos+15
rts
destroyplanet6
jsr explode
lda explodestore
sta $5fff
ldx explodeptr
cpx #$07
beq resetplan6
rts
resetplan6
jsr randomizer
lda randspeed
sta planet6speed
lda randpos
sta objpos+14
lda #$00
sta objpos+15
sta planet6hit
rts
;Position randomizer (Count 25 times)
randomizer
ldx randcounter
lda randtable,x
sta randpos
lda randspeedtable,x
sta randspeed
inx
cpx #25
beq resetrand
inc randcounter
rts
resetrand ldx #$00
stx randcounter
rts
;Animation for explosion routine
explode
lda explodedelay
cmp #$02
beq expfast
inc explodedelay
rts
expfast lda #$00
sta explodedelay
ldx explodeptr
lda explodetable,x
sta explodestore
inx
cpx #$06
beq stopexplode
inc explodeptr
rts
stopexplode
ldx #$07
stx explodeptr
rts
;Animation for main enemy sprites
animation
lda animdelay
cmp #$04
beq fastenough
inc animdelay
rts
fastenough
lda #$00
sta animdelay
ldx animpointer
lda planetframe1,x
sta planetstore1
lda planetframe2,x
sta planetstore2
lda planetframe3,x
sta planetstore3
lda planetframe4,x
sta planetstore4
lda planetframe5,x
sta planetstore5
lda planetframe6,x
sta planetstore6
inx
cpx #$06
beq resetframe
inc animpointer
rts
resetframe
ldx #$00
stx animpointer
rts
;Test the sprite to sprite collision
collision
jsr tbullcol
jsr tplayercol
jsr planetcol1
jsr planetcol2
jsr planetcol3
jsr planetcol4
jsr planetcol5
jsr planetcol6
rts
;Test the bullet to see if it hits
;the enemies, using a box co-ords type
;collision (see swo #20).
tbullcol lda objpos+2
sec
sbc #$06
sta collstore
clc
adc #$0c
sta collstore+1
lda objpos+3
sec
sbc #$0c
sta collstore+2
clc
adc #$18
sta collstore+3
rts
tplayercol
lda objpos
sec
sbc #$06
sta collstore+4
clc
adc #$0c
sta collstore+5
lda objpos+1
sec
sbc #$0c
sta collstore+6
clc
adc #$18
sta collstore+7
nocoll rts
;To make a fair collision for each of
;the planets. If a planet is exploding
;we ensure that no collision is made
;for that particular planet. Simply by
;jumping straight to the end of the
;RETURN TO SUBROUTINE command (RTS).
planetcol1
lda planet1hit
cmp #$01
beq nothit1b
lda objpos+4
cmp collstore
bcc nothit1a
cmp collstore+1
bcs nothit1a
lda objpos+5
cmp collstore+2
bcc nothit1a
cmp collstore+3
bcs nothit1a
jmp killplanet1
nothit1a
lda objpos+4
cmp collstore+4
bcc nothit1b
cmp collstore+5
bcs nothit1b
lda objpos+5
cmp collstore+6
bcc nothit1b
cmp collstore+7
bcs nothit1b
jmp playerhit
nothit1b rts
planetcol2
lda planet2hit
cmp #$01
beq nothit2b
lda objpos+6
cmp collstore
bcc nothit2a
cmp collstore+1
bcs nothit2a
lda objpos+7
cmp collstore+2
bcc nothit2a
cmp collstore+3
bcs nothit2a
jmp killplanet2
nothit2a
lda objpos+6
cmp collstore+4
bcc nothit2b
cmp collstore+5
bcs nothit2b
lda objpos+7
cmp collstore+6
bcc nothit2b
cmp collstore+7
bcs nothit2b
jmp playerhit
nothit2b rts
planetcol3
lda planet3hit
cmp #$01
beq nothit3b
lda objpos+8
cmp collstore
bcc nothit3a
cmp collstore+1
bcs nothit3a
lda objpos+9
cmp collstore+2
bcc nothit3a
cmp collstore+3
bcs nothit3a
jmp killplanet3
nothit3a
lda objpos+8
cmp collstore+4
bcc nothit3b
cmp collstore+5
bcs nothit3b
lda objpos+9
cmp collstore+6
bcc nothit3b
cmp collstore+7
bcc nothit3b
jmp playerhit
nothit3b rts
planetcol4
lda planet4hit
cmp #$01
beq nothit4b
lda objpos+10
cmp collstore
bcc nothit4a
cmp collstore+1
bcs nothit4a
lda objpos+11
cmp collstore+2
bcc nothit4a
cmp collstore+3
bcs nothit4a
jmp killplanet4
nothit4a
lda objpos+10
cmp collstore+4
bcc nothit4b
cmp collstore+5
bcs nothit4b
lda objpos+11
cmp collstore+6
bcc nothit4b
cmp collstore+7
bcs nothit4b
jmp playerhit
nothit4b rts
planetcol5
lda planet5hit
cmp #$01
beq nothit5b
lda objpos+12
cmp collstore
bcc nothit5a
cmp collstore+1
bcs nothit5a
lda objpos+13
cmp collstore+2
bcc nothit5a
cmp collstore+3
bcs nothit5a
jmp killplanet5
nothit5a
lda objpos+12
cmp collstore+4
bcc nothit5b
cmp collstore+5
bcs nothit5b
lda objpos+13
cmp collstore+6
bcc nothit5b
cmp collstore+7
bcs nothit5b
jmp playerhit
nothit5b rts
planetcol6
lda planet6hit
cmp #$01
beq nothit6b
lda objpos+14
cmp collstore
bcc nothit6a
cmp collstore+1
bcs nothit6a
lda objpos+15
cmp collstore+2
bcc nothit6a
cmp collstore+3
bcs nothit6a
jmp killplanet6
nothit6a lda objpos+14
cmp collstore+4
bcc nothit6b
cmp collstore+5
bcs nothit6b
lda objpos+15
cmp collstore+6
bcc nothit6b
cmp collstore+7
bcs nothit6b
jmp playerhit
nothit6b rts
;The player has been hit by a planet
;therefore damage points will of course
;be taken off the player's shield.
playerhit
jsr drainshield
jsr drainshield
rts
drainshield
dec shieldval+2
ldx #$03
drainloop lda shieldval+0,x
cmp #$2f
bne shieldok
lda #$39
sta shieldval+0,x
dec shieldval-1,x
shieldok dex
bne drainloop
;Check if the shield is below 000
lda shieldval+0
cmp #$2f
beq shipdoomed
rts
;The player ship is doomed. So now we
;blow the ship up in a cool way.
shipdoomed
lda #$30
sta shieldval+0 ;zero counter
sta shieldval+1
sta shieldval+2
lda #$00
sta explodedelay
ldx #$00
stx explodeptr
doomloop
lda #$00
sta delaytime
cmp delaytime
beq *-3
lda #$01
sta $d017 ;expand x and 7
sta $d01d
jsr expandpos
jsr destroyplayer
jmp doomloop
destroyplayer
lda explodedelay
cmp #$02
beq delayfast
inc explodedelay
rts
delayfast
lda #$00
sta explodedelay
ldx explodeptr
lda explodetable,x
sta $5ff8
inx
cpx #6
beq finishedexp
inc explodeptr
rts
finishedexp
ldx #$00
stx explodeptr
lda #$00
sta $d015
;Copy the player's score from the
;screen ram. directly over to the
;game over message.
ldx #$00
copyscore lda scoreval,x
sta finalscore,x
inx
cpx #6
bne copyscore
ldx #$00
copyend lda deadmsg,x
cmp #$3f
bcc msgok
sec
sbc #$40
msgok sta $07c0,x
inx
cpx #$28
bne copyend
;Now see if the player's score has
;beaten the top score.
lda finalscore+5
sec
lda topscore+5
sbc finalscore+5
lda topscore+4
sbc finalscore+4
lda topscore+3
sbc finalscore+3
lda topscore+2
sbc finalscore+2
lda topscore+1
sbc finalscore+1
lda topscore+0
sbc finalscore+0
bpl nohiscore
;High score achieved so this will
;final score will become the new high
;score, before jumping back to the
;front end.
ldx #$00
puthi lda finalscore,x
sta topscore,x
inx
cpx #6
bne puthi
nohiscore
lda #$00
sta firebutton
gameover
;Wait for the player to press fire
;to play again.
waitfire lda $dc00
lsr a
lsr a
lsr a
lsr a
lsr a
bit firebutton
ror firebutton
bmi waitfire
bvc waitfire
jmp titlescreen
;The player successfully shot the first
;planet. So engage destruction mode.
killplanet1
ldx #$00
stx explodeptr
lda #$01
sta planet1hit
jsr score
jmp removebullet
killplanet2
ldx #$00
stx explodeptr
lda #$01
sta planet2hit
jsr score
jmp removebullet
killplanet3
ldx #$00
stx explodeptr
lda #$01
sta planet3hit
jsr score
jmp removebullet
killplanet4
ldx #$00
stx explodeptr
lda #$01
sta planet4hit
jsr score
jmp removebullet
killplanet5
ldx #$00
stx explodeptr
lda #$01
sta planet5hit
jsr score
jmp removebullet
killplanet6
ldx #$00
stx explodeptr
lda #$01
sta planet6hit
jsr score
removebullet
ldx #$00
stx objpos+2
rts
;Player scores points per planet shot
score inc scoreval+4
ldx #$04
scloop lda scoreval+0,x
cmp #$3a
bne scoreok
lda #$30
sta scoreval+0,x
inc scoreval-1,x
scoreok dex
bne scloop
rts
;The first main interrupt. This will
;switch the sync timer on (delaytime).
irq1 asl $d019
lda $dc0d
sta $dd0d
lda #raspos2
sta $d012
lda #$01 ;See TIRQ
sta delaytime
lda #<irq2
sta $0314
lda #>irq2
sta $0315
pla
tay
pla
tax
pla
rti
;The next interrupt will display the
;bitmap picture.
irq2 asl $d019
lda #raspos3
sta $d012
lda #$3b ;Bitmap mode
sta $d011
lda #$18 ;Multicolour on
sta $d016
lda #$78 ;Read VideoRAM $5c00
sta $d018
lda #$02
sta $dd00 ;VIC BANK #$02
lda #$00
sta $d01b ;Sprites in front
lda #$ff
sta $d01c ;Sprite multicolour
;on.
ldx #$00
setcols2
lda colourstore,x ;Sprite cols
sta $d027,x ;set
inx
cpx #8
bne setcols2
lda #<irq3
sta $0314
lda #>irq3
sta $0315
pla
tay
pla
tax
pla
rti
;This interrupt will display the status
;bar at the bottom of the screen. The
;VIC Bank $03 is used, and charset is
;at $2000, so we use $18. Screen
;multicolour is disabled. Also mask the
;sprites to go behind the status bar
;invisibly
irq3 asl $d019
lda #raspos4
sta $d012
lda #$08
sta $d016
lda #$18
sta $d018
lda #$03
sta $dd00
lda #$00
sta $d01c
lda #$ff
sta $d01b
lda #$1b
sta $d011
ldx #$00
makecols lda #$00
sta $d027,x
inx
cpx #8
bne makecols
lda #<irq1
sta $0314
lda #>irq1
sta $0315
jsr $1003
pla
tay
pla
tax
pla
rti
;Status panel for the game:
status
.text "score: 000"
.text "000 -plan"
.text "et popper"
.text "!- [: 100"
;Death message for game over
deadmsg
.text "ship destr"
.text "oyed - fin"
.text "al score w"
.text "as: "
finalscore
.text "000000"
topscore
.text "000000"
;Default sprite frame table.
dfltframe .byte $02,$0e,$0a,$0a
.byte $0a,$0a,$0a,$0a
;Sprite colour table
dfltcols .byte $09,$01,$07,$03
.byte $0e,$05,$04,$0d
;Position table
dfltpos .byte $58,$d0 ;Player start
.byte $00,$00 ;Bullet start
.byte $20,$00 ;Planet 1
.byte $30,$00 ;Planet 2
.byte $40,$00 ;Planet 3
.byte $50,$00 ;Planet 4
.byte $60,$00 ;Planet 5
.byte $a0,$00 ;Planet 6
;Animation frame tables for sprites
planetframe1
.byte $0d,$08,$09,$0a
.byte $0b,$0c
planetframe2
.byte $0c,$0d,$08,$09
.byte $0a,$0b
planetframe3
.byte $0b,$0c,$0d,$08
.byte $09,$0a
planetframe4
.byte $0a,$0b,$0c,$0d
.byte $08,$09
planetframe5
.byte $09,$0a,$0b,$0c
.byte $0d,$08
planetframe6
.byte $08,$09,$0a,$0b
.byte $0c,$0d
explodetable
.byte $03,$04,$05,$06
.byte $10,$10,$10,$10
;Random position and speed tables
randtable
.byte $10,$98,$30,$20,$a0
.byte $48,$60,$80,$78,$28
.byte $50,$38,$20,$60,$10
.byte $88,$90,$30,$18,$50
.byte $48,$a0,$58,$20,$90
randspeedtable
.byte $01,$04,$02,$03,$05
.byte $04,$01,$02,$03,$03
.byte $01,$03,$04,$01,$02
.byte $03,$02,$03,$04,$01
.byte $05,$01,$04,$03,$01
dirtable
.byte $00,$00,$01,$01,$ff
.byte $ff,$00,$00,$02,$02
.byte $fe,$fe,$01,$01,$ff
.byte $ff,$00,$00,$01,$01
.byte $02,$02,$fe,$fe,$01
.byte $01,$ff,$ff,$02,$02