438 lines
		
	
	
		
			11 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
			
		
		
	
	
			438 lines
		
	
	
		
			11 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
_runtimePath_ "../../runtime"
 | 
						|
_runtimeStart_ &h7FFF
 | 
						|
_arraysStart_ &h7FFF
 | 
						|
_codeRomType_ ROMv3
 | 
						|
 | 
						|
'size of your most complex expression, (temporary variables required)*2, defaults to 8
 | 
						|
_tempVarSize_ 4
 | 
						|
 | 
						|
'free string work area, (better not use any of the string runtime!)
 | 
						|
free STRINGWORKAREA
 | 
						|
 | 
						|
'use this after _runtimeStart_ to specify maximum number of sprites if you have more than 48
 | 
						|
'_maxNumSprites_ 61
 | 
						|
 | 
						|
'defines the amount of contiguous RAM needed for sprite stripes, (in this case 15*6 + 1), also min address and search direction
 | 
						|
_spriteStripeChunks_ 15, &h3BA0, descending
 | 
						|
 | 
						|
const Barrier = 0
 | 
						|
load sprite, ../../../res/image/Invader/Barrier.tga, Barrier, NoFlip
 | 
						|
 | 
						|
const Saucer = 1
 | 
						|
load sprite, ../../../res/image/Invader/Saucer.tga, Saucer + 0, NoFlip
 | 
						|
load sprite, ../../../res/image/Invader/Saucer.tga, Saucer + 1, FlipX
 | 
						|
 | 
						|
const Player = 3
 | 
						|
load sprite, ../../../res/image/Invader/Player.tga, Player + 0, NoFlip
 | 
						|
load sprite, ../../../res/image/Invader/Player.tga, Player + 1, FlipX
 | 
						|
 | 
						|
const InvBigLt = 5
 | 
						|
load sprite, ../../../res/image/Invader/InvBig_0.tga, InvBigLt + 0, NoFlip
 | 
						|
load sprite, ../../../res/image/Invader/InvBig_1.tga, InvBigLt + 1, NoFlip
 | 
						|
 | 
						|
const InvBigRt = 7 'instance and hardware flip, (native code), in the X direction to save memory
 | 
						|
load sprite, ../../../res/image/Invader/InvBig_0.tga, InvBigRt + 0, FlipX
 | 
						|
load sprite, ../../../res/image/Invader/InvBig_1.tga, InvBigRt + 1, FlipX
 | 
						|
 | 
						|
const InvMedLt = 9
 | 
						|
load sprite, ../../../res/image/Invader/InvMed_0.tga, InvMedLt + 0, NoFlip
 | 
						|
load sprite, ../../../res/image/Invader/InvMed_1.tga, InvMedLt + 1, NoFlip
 | 
						|
 | 
						|
const InvMedRt = 11 'instance and hardware flip, (native code), in the X direction to save memory
 | 
						|
load sprite, ../../../res/image/Invader/InvMed_0.tga, InvMedRt + 0, FlipX
 | 
						|
load sprite, ../../../res/image/Invader/InvMed_1.tga, InvMedRt + 1, FlipX
 | 
						|
 | 
						|
const InvSmlLt = 13
 | 
						|
load sprite, ../../../res/image/Invader/InvSml_0.tga, InvSmlLt + 0, NoFlip
 | 
						|
load sprite, ../../../res/image/Invader/InvSml_1.tga, InvSmlLt + 1, NoFlip
 | 
						|
 | 
						|
const InvSmlRt = 15 'instance and hardware flip, (native code), in the X direction to save memory
 | 
						|
load sprite, ../../../res/image/Invader/InvSml_0.tga, InvSmlRt + 0, FlipX
 | 
						|
load sprite, ../../../res/image/Invader/InvSml_1.tga, InvSmlRt + 1, FlipX
 | 
						|
 | 
						|
const InvBlk = 17
 | 
						|
load sprite, ../../../res/image/Invader/InvBlk.tga, InvBlk, NoFlip
 | 
						|
 | 
						|
const IExplode = 18
 | 
						|
load sprite, ../../../res/image/Invader/IExplode.tga, IExplode + 0, NoFlip
 | 
						|
load sprite, ../../../res/image/Invader/IExplode.tga, IExplode + 1, FlipX
 | 
						|
 | 
						|
const SCORE_LEN = 7
 | 
						|
dim highBCD%(SCORE_LEN - 1) = 0
 | 
						|
dim scoreBCD%(SCORE_LEN - 1) = 0
 | 
						|
dim pointsBCD%(SCORE_LEN - 1) = 0
 | 
						|
 | 
						|
const INVADERS_J = 5
 | 
						|
const INVADERS_I = 10
 | 
						|
dim invaders(INVADERS_J - 1, INVADERS_I - 1) = {1+0*256, 1+0*256, 1+0*256, 1+0*256, 1+0*256, 1+0*256, 1+0*256, 1+0*256, 1+0*256, 1+0*256,
 | 
						|
                                                1+1*256, 1+1*256, 1+1*256, 1+1*256, 1+1*256, 1+1*256, 1+1*256, 1+1*256, 1+1*256, 1+1*256,
 | 
						|
                                                1+1*256, 1+1*256, 1+1*256, 1+1*256, 1+1*256, 1+1*256, 1+1*256, 1+1*256, 1+1*256, 1+1*256,
 | 
						|
                                                1+2*256, 1+2*256, 1+2*256, 1+2*256, 1+2*256, 1+2*256, 1+2*256, 1+2*256, 1+2*256, 1+2*256,
 | 
						|
                                                1+2*256, 1+2*256, 1+2*256, 1+2*256, 1+2*256, 1+2*256, 1+2*256, 1+2*256, 1+2*256, 1+2*256}
 | 
						|
 | 
						|
const INVADERS_H = 8
 | 
						|
const INVADERS_Y = 10
 | 
						|
const INVADERS_X = 12
 | 
						|
 | 
						|
dim iaddress(INVADERS_J - 1) = @invaders(0,0), @invaders(1,0), @invaders(2,0), @invaders(3,0), @invaders(4,0)
 | 
						|
dim iypos%(INVADERS_J - 1) = 4*INVADERS_Y, 3*INVADERS_Y, 2*INVADERS_Y, 1*INVADERS_Y, 0*INVADERS_Y
 | 
						|
dim ixpos%(INVADERS_I - 1) = 0*INVADERS_X, 1*INVADERS_X, 2*INVADERS_X, 3*INVADERS_X, 4*INVADERS_X, 5*INVADERS_X, 6*INVADERS_X, 7*INVADERS_X, 8*INVADERS_X, 9*INVADERS_X
 | 
						|
 | 
						|
const DIVX = &h0500
 | 
						|
def byte(DIVX, x, 0.0, 160.0, 160) = floor(x / INVADERS_X)
 | 
						|
 | 
						|
const DIVY = &h0600
 | 
						|
def byte(DIVY, x, 0.0, 120.0, 120) = floor(x / INVADERS_Y)
 | 
						|
 | 
						|
const IORIGIN_Y = 57
 | 
						|
const IORIGIN_X = 1
 | 
						|
 | 
						|
const INV_SML = 0
 | 
						|
const INV_MED = 0
 | 
						|
const INV_BIG = 0
 | 
						|
 | 
						|
const MAX_LIVES    = 3
 | 
						|
const NUM_IBULLETS = 3
 | 
						|
const NUM_ITYPES   = 3
 | 
						|
const NUM_BARRIERS = 3
 | 
						|
 | 
						|
const BARRIER_Y = 90
 | 
						|
const BARRIER_X = 20
 | 
						|
const BARRIER_OFFSET = 48
 | 
						|
 | 
						|
const PLAYER_Y = 114
 | 
						|
const PLAYER_X = 1
 | 
						|
const PLAYER_XEND = 147
 | 
						|
 | 
						|
 | 
						|
dim irsprites%(NUM_ITYPES - 1) = InvSmlRt, InvMedRt, InvBigRt
 | 
						|
dim ilsprites%(NUM_ITYPES - 1) = InvSmlLt, InvMedLt, InvBigLt
 | 
						|
 | 
						|
def livesLevel, px, py, ixorigin, iyorigin, ii, jj, xflip, iflip, timeTicks, pflip, imarch, gameOver, pbxy, pbullet, icount, iexplode, itimer, buttonPrev
 | 
						|
 | 
						|
 | 
						|
call initSystem
 | 
						|
    
 | 
						|
reset:
 | 
						|
    call resetLevel
 | 
						|
    
 | 
						|
start:
 | 
						|
    call startLevel
 | 
						|
    
 | 
						|
init:
 | 
						|
    call initVars
 | 
						|
 | 
						|
repeat
 | 
						|
    wait
 | 
						|
 | 
						|
    call checkInvaders
 | 
						|
    call drawPlayerBullet
 | 
						|
    call drawInvaders
 | 
						|
    
 | 
						|
    if &(gameOver) then goto reset
 | 
						|
    
 | 
						|
    call handleInput
 | 
						|
 | 
						|
    call drawPlayer
 | 
						|
    call movePlayer
 | 
						|
    
 | 
						|
    inc timeTicks.lo
 | 
						|
    if timeTicks.lo &&= 60
 | 
						|
        timeTicks.lo = 0
 | 
						|
        inc timeTicks.hi
 | 
						|
    endif
 | 
						|
&forever
 | 
						|
 | 
						|
 | 
						|
proc drawPlayerBullet
 | 
						|
    'no bullets while invader is asploding
 | 
						|
    if &(iexplode) then return
 | 
						|
    
 | 
						|
    'no bullet so exit
 | 
						|
    if pbullet.hi &&= 0 then return
 | 
						|
 | 
						|
    asm 'setup SYS function
 | 
						|
        LDWI    SYS_VDrawBits_134
 | 
						|
        STW     giga_sysFn
 | 
						|
    endasm
 | 
						|
 | 
						|
    if peek(pbxy) &&= &h0C
 | 
						|
        pbullet.lo = 0
 | 
						|
        
 | 
						|
        gosub smashBarrier
 | 
						|
    endif
 | 
						|
 | 
						|
    asm 'setup SYS params
 | 
						|
        LDWI    0x3F00
 | 
						|
        STW     giga_sysArg0
 | 
						|
        LDW     _pbxy
 | 
						|
        STW     giga_sysArg4        
 | 
						|
    endasm
 | 
						|
 | 
						|
    if &(pbullet.lo)
 | 
						|
        asm 'draw bullet
 | 
						|
            LDI     0xF8
 | 
						|
            ST      giga_sysArg2
 | 
						|
            SYS     134
 | 
						|
        endasm
 | 
						|
        
 | 
						|
        pbxy.hi = pbxy.hi - 2
 | 
						|
        if pbxy.hi &&< 8
 | 
						|
            pbullet = 0
 | 
						|
            
 | 
						|
            asm 'erase bullet if top of screen
 | 
						|
                LDI     0x00
 | 
						|
                ST      giga_sysArg2
 | 
						|
                SYS     134
 | 
						|
            endasm
 | 
						|
        endif
 | 
						|
        return
 | 
						|
    endif
 | 
						|
    
 | 
						|
    asm 'erase bullet if pbullet.lo = 0
 | 
						|
        LDI     0x00
 | 
						|
        ST      giga_sysArg2
 | 
						|
        SYS     134
 | 
						|
    endasm
 | 
						|
    
 | 
						|
    pbullet = 0
 | 
						|
endproc
 | 
						|
 | 
						|
proc drawPlayer
 | 
						|
    if (pflip.lo)
 | 
						|
        sprite FlipX,  Player + 1, px, py
 | 
						|
    else
 | 
						|
        sprite NoFlip, Player + 0, px, py
 | 
						|
    endif
 | 
						|
endproc
 | 
						|
 | 
						|
proc handleInput
 | 
						|
    local button
 | 
						|
    
 | 
						|
    button = get("BUTTON_STATE") XOR 255
 | 
						|
    if &(button AND &h01) then pflip = &h0101
 | 
						|
    if &(button AND &h02) then pflip = &h0100
 | 
						|
    if &((buttonPrev AND &h80) = 0)
 | 
						|
        if &(button AND &h80)
 | 
						|
            gosub playerBullet
 | 
						|
        endif
 | 
						|
    endif
 | 
						|
    buttonPrev = button
 | 
						|
endproc
 | 
						|
 | 
						|
playerBullet:
 | 
						|
    if &(pbullet.hi) then return
 | 
						|
    
 | 
						|
    pbullet = &h0101
 | 
						|
    if &(pflip.lo)
 | 
						|
        pbxy = (px + 6) + ((py - 5 + 8) LSL 8)
 | 
						|
    else
 | 
						|
        pbxy = (px + 5) + ((py - 5 + 8) LSL 8)
 | 
						|
    endif
 | 
						|
return
 | 
						|
 | 
						|
proc movePlayer
 | 
						|
    if &(pflip.hi)
 | 
						|
        pflip.hi = 0
 | 
						|
 | 
						|
        if &(pflip.lo)
 | 
						|
            inc px
 | 
						|
            if px &&> PLAYER_XEND
 | 
						|
                px = PLAYER_XEND
 | 
						|
            endif
 | 
						|
        else
 | 
						|
            dec px
 | 
						|
            if px &&< PLAYER_X
 | 
						|
               px = PLAYER_X
 | 
						|
            endif
 | 
						|
        endif
 | 
						|
    endif
 | 
						|
endproc
 | 
						|
 | 
						|
proc initVars
 | 
						|
    'initialises all variables, (to zero), starting at @timeTicks
 | 
						|
    init vars @timeTicks
 | 
						|
endproc
 | 
						|
 | 
						|
proc startLevel
 | 
						|
    bcdint @pointsBCD, 0
 | 
						|
endproc
 | 
						|
 | 
						|
proc drawInvaders
 | 
						|
    local x, y, invader
 | 
						|
    
 | 
						|
    if &(iexplode) then return
 | 
						|
    
 | 
						|
    repeat
 | 
						|
        invader = deek(iaddress(jj) + ii + ii)
 | 
						|
        if &(invader.lo)
 | 
						|
            x = ixorigin + ixpos(ii)
 | 
						|
            y = iyorigin - iypos(jj)
 | 
						|
 | 
						|
            if y &&>= PLAYER_Y - 6
 | 
						|
                wait 120
 | 
						|
                gameOver = 1
 | 
						|
                return
 | 
						|
            endif
 | 
						|
 | 
						|
            if xflip &&= 2
 | 
						|
                sprite FlipX, irsprites(invader.hi) + ((x LSR 1) AND 1), x, y
 | 
						|
            else
 | 
						|
                sprite NoFlip, ilsprites(invader.hi) + ((x LSR 1) AND 1), x, y
 | 
						|
            endif
 | 
						|
            
 | 
						|
            if &(imarch.lo)
 | 
						|
                sprite NoFlip, InvBlk, x, y - INVADERS_Y
 | 
						|
            endif
 | 
						|
            
 | 
						|
            if x &&>= PLAYER_XEND
 | 
						|
                iflip = -2
 | 
						|
            elseif x &&<= 1
 | 
						|
                iflip = 2
 | 
						|
            endif
 | 
						|
        endif
 | 
						|
        
 | 
						|
        inc ii
 | 
						|
        if ii &= INVADERS_I
 | 
						|
            ii = 0
 | 
						|
            dec jj
 | 
						|
            if jj &&< 0
 | 
						|
                if &(imarch.lo) then imarch.lo = 0
 | 
						|
 | 
						|
                jj = INVADERS_J - 1
 | 
						|
                if iflip &&<> xflip
 | 
						|
                    imarch.lo = 1
 | 
						|
                    iyorigin = iyorigin + INVADERS_H
 | 
						|
                else
 | 
						|
                    ixorigin = ixorigin + iflip
 | 
						|
                endif
 | 
						|
 | 
						|
                xflip = iflip
 | 
						|
            endif
 | 
						|
        endif
 | 
						|
            
 | 
						|
    until (invader.lo)
 | 
						|
endproc
 | 
						|
 | 
						|
smashBarrier:
 | 
						|
    asm
 | 
						|
        LDWI    0x0C00
 | 
						|
        STW     giga_sysArg0        'FGBG colour
 | 
						|
        LDWI    0xFEFF
 | 
						|
        ADDW    _pbxy
 | 
						|
        STW     giga_sysArg4        'offset
 | 
						|
        LD      giga_rand0
 | 
						|
        ANDI    0xC0
 | 
						|
        ST      giga_sysArg2
 | 
						|
        SYS     134                 'left damage
 | 
						|
        INC     giga_sysArg4
 | 
						|
        LDI     0x00
 | 
						|
        ST      giga_sysArg2
 | 
						|
        SYS     134                 'center damage
 | 
						|
        INC     giga_sysArg4
 | 
						|
        LD      giga_rand2
 | 
						|
        ANDI    0xC0
 | 
						|
        ST      giga_sysArg2
 | 
						|
        SYS     134                 'right damage
 | 
						|
    endasm
 | 
						|
return
 | 
						|
 | 
						|
proc drawBarriers
 | 
						|
    local i, x, y
 | 
						|
    
 | 
						|
    x = BARRIER_X : y = BARRIER_Y
 | 
						|
    for i=0 &to NUM_BARRIERS - 1
 | 
						|
        sprite NoFlip, Barrier, x, y
 | 
						|
        x = x + BARRIER_OFFSET
 | 
						|
    next i
 | 
						|
endproc
 | 
						|
 | 
						|
proc checkInvaders
 | 
						|
    local i, j, x, y, iaddr
 | 
						|
 | 
						|
    'erase invader explosion and restart invader march
 | 
						|
    if &(iexplode)
 | 
						|
        inc itimer
 | 
						|
        if itimer &&= 10
 | 
						|
            sprite NoFlip, InvBlk, iexplode.lo, iexplode.hi
 | 
						|
            itimer = 0 : iexplode = itimer
 | 
						|
        endif
 | 
						|
        return
 | 
						|
    endif
 | 
						|
 | 
						|
    if pbullet.hi &&= 0 then return
 | 
						|
 | 
						|
    y = iyorigin - (pbxy.hi - (8 + 3))
 | 
						|
    if y &&< 0 then return
 | 
						|
    
 | 
						|
    x = pbxy.lo - ixorigin
 | 
						|
    if x &&< 0 then return
 | 
						|
 | 
						|
    i = peek(DIVX + x)
 | 
						|
    if i &&>= INVADERS_I then return
 | 
						|
 | 
						|
    j = (INVADERS_J - 1) - peek(DIVY + y)
 | 
						|
    if j &&>= INVADERS_J then return
 | 
						|
    if j &&< 0 then return
 | 
						|
    
 | 
						|
    iaddr = iaddress(j) + i + i : if peek(iaddr) &= 0 then return
 | 
						|
    
 | 
						|
    'erase invader
 | 
						|
    poke iaddr, 0
 | 
						|
    pbullet.lo = 0
 | 
						|
    
 | 
						|
    'explode invader
 | 
						|
    x = ixorigin + ((i LSL 3) + (i LSL 2))  'x = ixorigin + i*INVADERS_X
 | 
						|
    j = (INVADERS_J - 1) - j
 | 
						|
    y = iyorigin - ((j LSL 3) + j + j)      'y = iyorigin - j*INVADERS_Y;
 | 
						|
    
 | 
						|
    if xflip &> 0
 | 
						|
        sprite NoFlip, IExplode, x, y
 | 
						|
    else
 | 
						|
        sprite FlipX, IExplode + 1, x, y
 | 
						|
    endif
 | 
						|
 | 
						|
    'halt march to display explosion
 | 
						|
    itimer = 0 : iexplode = x + (y LSL 8)
 | 
						|
 | 
						|
    'erase previous row invader if invaders just marched vertically
 | 
						|
    if &(imarch.lo)
 | 
						|
        sprite NoFlip, InvBlk, x, y - INVADERS_Y
 | 
						|
    endif
 | 
						|
    
 | 
						|
    inc icount
 | 
						|
    if icount &&= (INVADERS_J * INVADERS_I)
 | 
						|
        gameOver = 1
 | 
						|
    endif
 | 
						|
endproc
 | 
						|
 | 
						|
 | 
						|
proc resetLevel
 | 
						|
    local i, j
 | 
						|
    
 | 
						|
    for j=0 to INVADERS_J - 1
 | 
						|
        for i=0 to INVADERS_I - 1
 | 
						|
            invaders(j, i).lo = 1
 | 
						|
        next i
 | 
						|
    next j
 | 
						|
    
 | 
						|
    cls
 | 
						|
    livesLevel = 3*256 + 0
 | 
						|
    bcdint @scoreBCD, 0
 | 
						|
 | 
						|
    px = PLAYER_X : py = PLAYER_Y
 | 
						|
    
 | 
						|
    ixorigin = IORIGIN_X : iyorigin = IORIGIN_Y
 | 
						|
    ii = 0 : jj = INVADERS_J - 1
 | 
						|
    iflip = 2 : xflip = iflip
 | 
						|
    
 | 
						|
    call drawBarriers
 | 
						|
endproc
 | 
						|
 | 
						|
proc initSystem
 | 
						|
    'audio fix for ROMv5a
 | 
						|
    poke &h21, peek(&h21) OR 3
 | 
						|
 | 
						|
    mode 2
 | 
						|
    set FGBG_COLOUR, 0
 | 
						|
endproc |