home *** CD-ROM | disk | FTP | other *** search
- ;
- ; Space Invaders v1.0
- ; David Phillips <electrum@tfs.net>
- ; program started: 04/28/98
- ; last update: 06/05/98
- ;
-
- #include "ti86asm.inc"
- #include "asm86.h"
- #include "ti86und.inc"
-
- .org _asm_exec_ram
-
-
- ;-------------------------------------------------------------------------
- ShellTitle:
- nop ; for the title line in shells (ASE)
-
- jp Startup ; jump to real start of program
-
-
-
- .dw $0000 ; used by shell (might be used later for version numbers)
-
- .dw ShellTitleText ; where the title of the program is
- ShellTitleText:
- .db "Space Invaders by David P",0
-
- ;-------------------------------------------------------------------------
- ; Variables: Bytes:
-
- ; player:
- player = _textShadow + 0 ; [1] X location of player (always on ground--same Y)
- lives = _textShadow + 1 ; [1] number of lives player has
- level = _textShadow + 2 ; [1] current level player is on
- score = _textShadow + 3 ; [2] score that player has
- p_shots = _textShadow + 5 ; [10] (X, Y) locations of player's shots -- max of 5
- fired = _textShadow + 15 ; [1] flag to make player press fire for every shot
-
- ; space invaders:
- invader_x = _textShadow + 16 ; [1] flock's X location
- invader_y = _textShadow + 17 ; [1] flock's Y location
- invader_dir = _textShadow + 18 ; [1] invader's direction (-1 or 1)
- invader = _textShadow + 19 ; [30] 5 x 6 array of aliens -- their life
- i_shots = _textShadow + 49 ; [20] (X, Y) locations of invader's shots -- max of 10
- i_left = _textShadow + 69 ; [1] number of invaders left
- shot_move = _textShadow + 70 ; [1] next time to move invaders shots
-
- ;-------------------------------------------------------------------------
- Startup:
- call BUSY_OFF ; turn off the busy indicator
- res appTextSave,(iy+appflags) ; we don't want our variables to be overwritten
- call _flushallmenus ; clear menus, to use last 2 lines for text
-
- call _clrLCD ; clear the display screen
- ld hl,$0000 ; load in the upper-left corner (1, 1)
- ld (_curRow),hl ; actually change the position
- ld hl,titletext ; load the address of the title screen
- call _puts ; print the title screen
- call Pause ; call our pause subroutine
-
- xor a ; start at level 1 -- NewLevel will up it
- ld (level),a ; set level
- ld (i_left),a ; this will force NewLevel to be called
- ld a,3 ; start with 3 lives
- ld (lives),a ; set lives
- ld hl,0 ; start with 0 score
- ld (score),hl ; set score
-
- MainLoop:
- ld a,(i_left) ; load Aliens left counter
- cp 0 ; are they all dead?
- call z,NewLevel ; if they are, time for a new level
-
- GetInput:
- call _getky ; read a keypress
- cp K_EXIT ; was it EXIT?
- jp z,ExitGame ; time to quit
- cp K_MORE ; was it MORE?
- call z,Pause ; if so, Pause the game
- di ; disable interrupts
- ld a,%00111110 ;\ (bitmask for the
-
- out (1),a ; | status of arrow keys
-
- in a,(1) ;/ and top keys in A)
-
- ei ; re-enable interrupts
- bit 1,a ; is left pressed?
-
- jr z,MoveLeft ; move left
-
- bit 2,a ; is right pressed?
-
- jr z,MoveRight ; move right
- jr OtherKeys ; no arrows pressed, check other keys
- MoveLeft:
- ld a,(player) ; get the player's position
- cp 1 ; are we at the left side?
- jr c,OtherKeys ; if we are, don't move over
- call ErasePlayer ; erase player's ship before we move him
- ld a,(player) ; re-load the player's position
- sub 2 ; move left two
- ld (player),a ; set the postion
- call DrawPlayer ; draw the player in the new position
- jr OtherKeys ; we're done here
- MoveRight:
- ld a,(player) ; get the player's position
- cp $58 ; are we all at the right side?
- jr nc,OtherKeys ; if we are, don't move over
- call ErasePlayer ; erase player's ship before we move him
- ld a,(player) ; re-load the player's position
- add a,2 ; move right two
- ld (player),a ; set the position
- call DrawPlayer ; draw the player in the new position
- OtherKeys:
- di ; disable interrupts
- ld a,%00111111 ;\ (bitmask for the
-
- out (1),a ; | status of 2nd key
-
- in a,(1) ;/ in A)
-
- ei ; re-enable interrupts
- bit 5,a ; is second pressed?
-
- jr z,Fire ; let them fire
- xor a ; faster than "ld a,0"
- ld (fired),a ; reset firing flag
- jp UpdateAliens ; don't want to fire
-
- Fire:
- ld a,(fired) ; load in fired flag
- ld d,a ; save it for a little while
- ld a,1 ; don't want them to fire
- ld (fired),a ; set fired flag so they can't fire
- ld a,d ; get back the old fired flag
- cp 1 ; is it set to no fire?
- jp z,UpdateAliens ; then don't let them fire
- ld hl,p_shots ; load in the invader's shots
- ld b,5 ; check up to 5 shots
- CheckFire:
- ld a,(hl) ; load in the shot's x value
- cp $ff ; is it empty?
- jr z,FireCDone ; then we're done
- inc hl ; add one to HL
- inc hl ; add another to HL (HL += 2)
- djnz CheckFire ; check another shot
- jr UpdateAliens ; if we're here, no shots are available
- FireCDone:
- ld a,(player) ; get player's x position
- ld (hl),a ; set shot's x value
- inc hl ; move to shot's y value
- ld a,$2d ; start shot above player
- ld (hl),a ; set shot's y value
-
- UpdateAliens:
- ld a,(invader_dir) ; get the aliens direction
- ld d,a ; save it in D
- cp 1 ; is it 1?
- jp z,MoveIRight ; then they're moving right
- ld a,(invader_x) ; get their x position
- cp 0 ; are they at the left edge?
- jp nz,MoveAliens ; if not, move we're ready to update position
- ld d,1 ; we're at edge, time to move right
- ld a,(invader_y) ; get their y postion
- inc a ; move down one pixel
- ld (invader_y),a ; set new position
- jr MoveAliens ; ready to update position
- MoveIRight:
- ld a,(invader_x) ; get their x position
- cp 40 ; are they at the right edge?
- jp nz,MoveAliens ; if not, update their position
- ld d,-1 ; we're at edge, let's move left
- MoveAliens:
- ld a,d ; get their new direction
- ld (invader_dir),a ; save their new direction
- ld a,(invader_x) ; get their x position
- add a,d ; update postion by adding current direction
- ld (invader_x),a ; save new position
-
- DrawAliens:
- ld ix,invader ; load pointer to invaders
- ld hl,SP_Enemy1 ; load pointer to their sprites
- ld b,5 ; there are 5 rows of invaders
- ld a,(invader_y) ; get their y position
- ld e,a ; load it for drawing
- DrawYL:
- push bc ; save alien y counter
- ld b,6 ; their are 6 aliens in a row
- ld a,(invader_x) ; get their x position
- ld d,a ; load it for drawing
- DrawXL:
- ld a,(ix+0) ; get the value at this alien
- cp 0 ; is the alien dead?
- jp z,DrawASkip ; if so, we don't want to draw it
- DrawCheckA:
- push bc ; save loop counter
- push hl ; save bullet pointer
- push de ; save draw location
- ld b,5 ; player has 5 bullets
- ld hl,p_shots ; pointer to player's shots
- DrawCheckAL:
- push bc ; save loop counter
- ld a,(hl) ; load shot's X coord
- sub d ; calc distance from player's X coord
- jr nc,DrawCheckANoCarryX ; if not negative, skip abs code
- ld b,a ; save negative value
- xor a ; set A equal to zero
- sub b ; make value positive
- DrawCheckANoCarryX:
- cp 8 ; are they closer than 8 pixels?
- jr nc,DrawCheckASkip ; if not, we're done
- inc hl ; move to shot's Y coord
- ld a,(hl) ; load shot's Y coord
- sub e ; calc distance from player's Y coord
- jr nc,DrawCheckANoCarryY ; if not negative, skip abs code
- ld b,a ; save negative value
- xor a ; set A equal to zero
- sub b ; make value positive
- DrawCheckANoCarryY:
- cp 8 ; are they closer than 8 pixels?
- jr nc,DrawCheckASkip ; if not, we're done
- ld a,$ff ; $FF means shot is unused
- dec hl ; fill shot's X value
- ld b,(hl) ; get shot's X value for erasing
- ld (hl),a ; this shot's done
- inc hl ; go back to shot's Y value
- ld c,(hl) ; get shot's Y value for erasing
- push hl ; save shot pointer
- ld hl,SP_Blank ; want to erase the shot
- call PutSprite ; draw the blank sprite
- pop hl ; restore shot pointer
- ld a,(ix+0) ; get invader's life
- dec a ; drop it by 1
- cp 0 ; did we kill them?
- ld (ix+0),a ; save life
- jr nz,DrawCheckASkip ; only do killed stuff if life is at zero
- push hl ; save pointer
- call UpdateScore ; score the hit
- pop hl ; restore pointer
- ld a,(i_left) ; load aliens left counter
- dec a ; drop counter by 1
- ld (i_left),a ; set counter
- DrawCheckASkip:
- inc hl ; move to next bullet's x coord
- pop bc ; restore loop counter
- djnz DrawCheckAL ; check all bullets
- pop de ; restore draw location
- pop hl ; restore bullet pointer
- pop bc ; restore loop counter
- push bc ; save alien x counter
- push de ; save drawing position
- push hl ; save sprite pointer
- ld hl,invader_dir ; find out which direction they're going
- ld a,d ; get their x position
- sub (hl) ; calc position before we moved them
- ld b,a ; save x position for drawing
- ld c,e ; save y position for drawing
- ld a,(invader_dir) ; get their direction again
- cp 1 ; see if they're going right
- jr nz,DrawANoDrop ; if not, then they didn't drop--drops on left side
- ld a,(invader_x) ; get their x position again
- cp 1 ; check if they're one position over
- jr nz,DrawANoDrop ; if not, we didn't drop them
- dec c ; we dropped them, draw blank up one pixel
- DrawANoDrop:
- ld hl,SP_Blank ; load in a blank sprite
- call PutSprite ; draw the blank
- pop hl ; restore sprite pointer
- pop de ; restore saved draw location
- pop bc ; restore draw location
- ld a,(ix+0) ; get life--might have been hit
- cp 0 ; did player just kill him?
- jp z,DrawASkip ; if so, don't draw--but we needed to erase it
-
- DrawCheckBottom:
- ld a,56 ; check if they are at screen bottom
- cp e ; do the check
- jr nc,DrawPlayerOK ; if they not, player isn't dead
- pop hl ; clear top of stack
- jp PlayerKilled ; kill the player
-
- DrawPlayerOK:
- ld a,r ; get a not-very-random number (memory refresh counter)
-
- cp 40 ; is it our number?
-
- jr nz,DrawNoFire ; if not, we're not going to fire
-
- push bc ; save loop counters
- push hl ; save pointer to alien's sprites
- DrawFire:
- ld hl,i_shots ; load in the invader's shots
- ld b,10 ; we need to check all 10 shots
- DrawCheckFire:
- ld a,(hl) ; load in the shot's x value
- cp $ff ; is it empty?
- jr z,DrawFireCDone ; then we're done
- inc hl ; add one to HL
- inc hl ; add another to HL (HL += 2)
- djnz DrawCheckFire ; check another shot
- jp DrawNoFreeShots ; if we're here, there are no free shots--can't fire
- DrawFireCDone:
- ld (hl),d ; set shot's x value
- inc hl ; move to shot's y value
- ld (hl),e ; set shot's y value
- DrawNoFreeShots:
- pop hl ; restore pointer to alien's sprites
- pop bc ; restore loop counters
-
- DrawNoFire:
- push bc ; save all regs before drawing
- push de ; still saving
- push hl ; once more, please
- ld b,d ; put x coord in for drawing
- ld c,e ; put y coord in for drawing
- call PutSprite ; draw the alien
- pop hl ; restore sprite pointer
- pop de ; restore saved draw location
- pop bc ; restore loop counter
- DrawASkip:
- ld a,d ; load in their x coord
- add a,9 ; next alien is 9 pixels right
- ld d,a ; save the coord
- inc ix ; move to next alien
- dec b ; ------------------------\ loop is too big
- ld a,b ; \ to use relative
- cp 0 ; / jump instruction
- jp nz,DrawXL ; loop through entire row / "djnz DrawXL"
- ld bc,$8 ; a sprite is 8 bytes long
- add hl,bc ; move to the next sprite
- pop bc ; restore loop counter
- ld a,e ; get their y coord
- add a,8 ; next alien is 8 pixels down
- ld e,a ; save the coord
- dec b ; ----------------------\ loop is too big
- ld a,b ; \ to use relative
- cp 0 ; / jump instruction
- jp nz,DrawYL ; loop through all rows / "djnz DrawYL"
-
- UpdatePShots:
- ld b,5 ; we want to draw all 5 shots
- ld hl,p_shots ; load in the shots
- UpdatePLoop:
- push bc ; save loop counter
- ld b,(hl) ; load in it's x value
- ld a,b ; load in the x value for check
- cp $ff ; check if the shot's active
- jr z,UpdatePSkip ; if not, skip it
- inc hl ; move to y value
- ld c,(hl) ; load in it's y value
- ld a,c ; get the shot's y value
- sub 3 ; move shot up by 3
- ld (hl),a ; set shot y value
- cp $80 ; did it go past the top?
- jr nc,UpdatePExpired ; then kill it
- inc hl ; move to next shot's x value
- push hl ; save shot pointer
- push bc ; save shot's location
- ld hl,SP_Blank ; want to erase the shot
- ld a,c ; load in the shot's y value
- add a,3 ; erase 3 pixels down
- ld c,a ; set y draw value
- call PutSprite ; draw the blank sprite
- pop bc ; restore shot's location
- ld hl,SP_PShot ; load pointer to sprite of shot
- call PutSprite ; draw the shot
- pop hl ; restore shot pointer
- jr UpdatePNoSkip ; don't want to kill the shot
- UpdatePExpired:
- dec hl ; move back to x value
- ld a,$ff ; load in clear value
- ld (hl),a ; set shot to cleared
- push hl ; save shot pointer
- ld hl,SP_Blank ; want to erase the shot
- ld c,0 ; erase at top of screen
- call PutSprite ; draw the blank sprite
- pop hl ; restore shot pointer
- UpdatePSkip:
- inc hl ; skip the shot's x value
- inc hl ; skip the shot's y value
- UpdatePNoSkip:
- pop bc ; restore loop counter
- djnz UpdatePLoop ; loop for all shots
-
- UpdateIShots:
- ld a,(shot_move) ; load in invader shot move timer
- cp 0 ; is it at 0?
- jr z,UpdateTrue ; if it is, time to update
- xor a ; set a to 0
- ld (shot_move),a ; move shots next frame
- jp LoopDone ; skip updating this time
- UpdateTrue:
- ld a,1 ; we don't want to be updated next frame
- ld (shot_move),a ; set shot move timer
- ld b,10 ; we want to draw all 10 shots
- ld hl,i_shots ; load in the shots
- UpdateILoop:
- push bc ; save loop counter
- ld b,(hl) ; load in it's x value
- ld a,b ; load in the x value for check
- cp $ff ; check if the shot's active
- jr z,UpdateISkip ; if not, skip it
- inc hl ; move to y value
- ld a,(hl) ; load in it's y value
- inc a ; move shot down one
- ld (hl),a ; set shot y value
- ld c,a ; load in the value for sprite drawing
- UpdateICheck:
- cp 49 ; see if it's at the player's height
- jr c,UpdateIDraw ; if not, no collision
- ld a,(player) ; get player's x value
- sub b ; calc distance between player and shot's x value
- jr nc,UpdateINoABS ; if not negative, skip abs code
- ld d,a ; save negative value
- xor a ; set A equal to zero
- sub d ; make value positive
- UpdateINoABS:
- cp 8 ; are they closer than 8 pixels?
- jr nc,UpdateIDraw ; if not, we're done here
- pop hl ; clear top of stack
- ld a,(level) ; get the current level
- dec a ; it will be incremented by NewLevel
- ld (level),a ; set new level
- jp PlayerKilled ; if we're still here, we collided
- UpdateIDraw:
- ld a,c ; get the shot's y value for compare
- cp 56 ; did it go past the bottom
- jr nc,UpdateIExpired ; then kill it
- inc hl ; move to next shot's x value
- push hl ; save shot pointer
- ld hl,SP_IShot ; load pointer to sprite of shot
- call PutSprite ; draw the shot
- pop hl ; restore shot pointer
- jr UpdateINoSkip ; don't want to kill the shot
- UpdateIExpired:
- dec hl ; move back to x value
- ld a,$ff ; load in clear value
- ld (hl),a ; set shot to cleared
- push hl ; save shot pointer
- ld hl,SP_Blank ; want to erase the shot
- ld c,56 ; erase at bottom of screen
- call PutSprite ; draw the blank sprite
- pop hl ; restore shot pointer
- UpdateISkip:
- inc hl ; skip the shot's x value
- inc hl ; skip the shot's y value
- UpdateINoSkip:
- pop bc ; restore loop counter
- djnz UpdateILoop ; loop for all shots
-
- LoopDone:
- call DrawScore ; print our score
- jp MainLoop ; time to do the next frame
-
- GameOver:
- call _clrLCD ; clear the screen
- ld hl,$0603 ; put text at 4,7
- ld (_curRow),hl ; set new text position
- ld hl,T_gameover ; tell them the game's over
- call _puts ; print the text
- ld hl,$0505 ; put text at 6,6
- ld (_curRow),hl ; set new text position
- ld hl,T_score ; load text "score" to print
- call _puts ; print the text
- ld hl,$0b05 ; put text at 6,11
- ld (_curRow),hl ; set new text position
- ld hl,(score) ; load the score to print
- xor a ; clear high byte
- call _dispAHL ; print the number
- call Pause ; wait for a key
-
- ExitGame:
- set appTextSave,(iy+appflags) ; we want _textShadow to be cleared with _clrScrn
- call _clrScrn ; clear the screen before exit (including _textShadow)
- ret ; return to TI-OS or a shell
-
- UpdateScore:
- ld hl,(score) ; get the current score
- ld de,25 ; add 25 to it
- add hl,de ; do the add
- ld (score),hl ; store the score
- ret
-
- PlayerKilled:
- ld a,(lives) ; get the player's lives
- dec a ; make them lose a life
- ld (lives),a ; set new lives
- call _clrLCD ; clear the screen
- ld hl,$0603 ; place text at 4,7
- ld (_curRow),hl ; set text position
- ld hl,T_died ; tell user they are dead
- call _puts ; print the string
- call Pause ; wait, so they can see the message
- ld a,(lives) ; does player have lives left?
- cp 0 ; check if lives are at 0
- jp z,GameOver ; if they are, game is over
- call NewLevel ; restart the level--note: advances level by one
- jp GetInput ; ready for top of main loop
-
-
- ;-------------------------------------------------------------------------
- Reset:
-
- ClearIShots:
- ld b,10 ; run loop for all 10 shots
- ld a,$ff ; $FF will stand for an unused shot
- ld hl,i_shots ; hl points to the start of the invader's shots
- ClrILoop:
- ld (hl),a ; clear out the shot by putting $FF into it
- inc hl ; move to the next shot's X value
- inc hl ; easier than loading into a 16-bit reg, then adding
- djnz ClrILoop ; loop through all the shots
-
- ClearPShots:
- ld b,5 ; run loop for all 5 shots
- ld a,$ff ; $FF will stand for an unused shot
- ld hl,p_shots ; hl points to the start of the player's shots
- ClrPLoop:
- ld (hl),a ; clear out the shot by putting $FF into it
- inc hl ; move to the next shot's X value
- inc hl ; easier than loading into a 16-bit reg, then adding
- djnz ClrPLoop ; loop through all the shots
-
- ClearAliens:
- ld a,(level) ; get the level number
- dec a ; subtract one so level/life starts at zero
- sra a ; life is equal to level divided by two
- inc a ; add one to it--life can't be zero
- ld b,30 ; run loop for all 30 aliens
- ld hl,invader ; hl points to the start of the alien flock
- ClrALoop:
- ld (hl),a ; set the alien's life
- inc hl ; move to the alien
- djnz ClrALoop ; loop through all the aliens
-
- ret ; we're done with the Reset
-
-
- ;-------------------------------------------------------------------------
- ErasePlayer:
- ld a,(player) ; get player's position
- ld b,a ; that's the X value
- ld c,55 ; place at bottom row
- ld hl,SP_Blank ; put blank sprite
- call PutSprite ; draw it
- ret ; return
-
- DrawPlayer:
- ld a,(player) ; get player's position
- ld b,a ; that's the X value
- ld c,55 ; place at bottom row
- ld hl,SP_Player ; we want to draw the player's ship
- call PutSprite ; draw it
- ret ; return
-
- DrawStatus:
- ld hl,$1000 ; ***place at (1, 17)
- ld (_curRow),hl ; set text position
- ld hl,T_score ; write text "SCORE"
- call _puts ; draw the text
- ld hl,$1003 ; ***place at (4, 17)
- ld (_curRow),hl ; set text position
- ld hl,T_level ; write text "LEVEL"
- call _puts ; draw the text
- ld hl,$1004 ; ***place at (5, 17)
- ld (_curRow),hl ; set text position
- ld a,(level) ; load the level to print
- ld l,a ; move to low byte
- ld h,0 ; clear the middle byte
- xor a ; clear high byte
- call _dispAHL ; print the number
- ld hl,$1006 ; ***place at (7, 17)
- ld (_curRow),hl ; set text position
- ld hl,T_lives ; write text "LIVES"
- call _puts ; draw the text
- ld hl,$1007 ; ***place at (8, 17)
- ld (_curRow),hl ; set text position
- ld a,(lives) ; load the lives to print
- ld l,a ; move to low byte
- ld h,0 ; clear the middle byte
- xor a ; clear high byte
- res appAutoScroll,(iy+appflags) ; turn off auto scrolling of text
- call _dispAHL ; print the number
- set appAutoScroll,(iy+appflags) ; turn it back on (so TI-OS isn't screwed)
-
- DrawScore:
- ld hl,$1001 ; place at (2, 17)
- ld (_curRow),hl ; set text position
- ld hl,(score) ; load the score to print
- xor a ; clear high byte
- call _dispAHL ; print the number
- ret ; we're done here
-
- ;-------------------------------------------------------------------------
- NewLevel:
- ld a,30 ; there are 30 aliens
- ld (i_left),a ; set aliens left counter
- ld a,44 ; start player in center
- ld (player),a ; set player position
- xor a ; start invaders in upper left (a = 0)
- ld (invader_x),a ; set invader x
- ld (invader_y),a ; set invader y
- ld (fired),a ; let them fire
- ld a,1 ; start invaders moving right
- ld (invader_dir),a ; set invader direction
- ld a,(level) ; load the level number
- inc a ; up it by 1
- ld (level),a ; set level number
- call Reset ; setup for the level
-
- ShowLevelScrn:
- call _clrLCD ; clear the display screen
- ld hl,$0102 ; place at (3, 2)
- ld (_curRow),hl ; set text position
- ld hl,T_enterlevel ; load the text to print
- call _puts ; print the text
- ld hl,$0704 ; place at (5, 8)
- ld (_curRow),hl ; set text position
- ld a,(level) ; load the level to print
- ld l,a ; move to low byte
- ld h,0 ; clear the middle byte
- xor a ; clear high byte
- call _dispAHL ; print the number
- ld hl,$0904 ; place at (5, 10)
- ld (_curRow),hl ; set text position
- ld a,'<' ; load char to print
- call _putc ; print the char
- ld hl,$0c04 ; place at (5, 13)
- ld (_curRow),hl ; set text position
- ld a,'>' ; load char to print
- call _putc ; print the char
- ld hl,$0507 ; place at (8, 6)
- ld (_curRow),hl ; set text position
- ld hl,T_pressenter ; load the text to print
- call _puts ; print the text
- call Pause ; wait for enter
-
- InitScreen:
- call _clrLCD ; clear the display screen...again
- call DrawStatus ; print text information
- call DrawPlayer ; draw the player the first time
-
- ret ; NewLevel is done
-
-
- ;-------------------------------------------------------------------------
- ; ASCR - Advanced Sprite Clipping Routines
- ;
- ; by Jimmy MÃ¥rdell 970304 Last update 970803
- ;
- ; modified by David Phillips to remove clipping
- ; faster without clipping--the only routines that worked with this game
- ;
- PutSprite: ; BC = x,y HL = sprite
- push bc
- push de
- push hl
- push ix
- push hl
- pop ix
- ld a,8
- push af
- call FIND_PIXEL
- Modify_6:
- ld de,$FC00
- add hl,de
- ld d,a
- pop bc
- PSC_PutRow:
- push bc
- push hl
- ld a,$ff
- ld e,a
- ld b,8
- ld c,(ix)
- inc ix
- PSC_PutCol:
- push bc
- rlc e
- jr nc,PSC_NextBit
- ld a,d
- rlc c
- jr c,PSC_BitOn
- cpl
- and (hl)
- ld (hl),a
- jr PSC_NextBit
- PSC_BitOn:
- or (hl)
- ld (hl),a
- PSC_NextBit:
- rrc d
- jr nc,PSC_SSB
- inc hl
- PSC_SSB:
- pop bc
- rlc c
- djnz PSC_PutCol
- pop hl
- ld bc,16
- add hl,bc
- pop bc
- djnz PSC_PutRow
- EndPS:
- pop ix
- pop hl
- pop de
- pop bc
- ret
- FIND_PIXEL:
- push bc
- push de
- ld hl,ExpTable+1
- ld d,0
- ld a,b
- and $07
- ld e,a
- add hl,de
- ld e,(hl)
- ld h,d
- srl b
- srl b
- srl b
- ld a,c
- add a,a
- add a,a
- ld l,a
- add hl,hl
- add hl,hl
- ld a,e
- ld e,b
- add hl,de
- pop de
- pop bc
- ret
- ExpTable:
- .db $01,$80,$40,$20,$10,$08,$04,$02,$01
-
-
- ;-------------------------------------------------------------------------
- Pause:
- call _getky ; wait for a key to be pressed
- cp K_ENTER ; was it enter?
- jr z,PauseDone ; if it was, we're done
- cp K_MORE ; maybe it was more?
- jr z,PauseDone ; if so, we're done here also
- cp K_EXIT ; or was it exit?
- jr nz,Pause ; if it wasn't, wait for another key press
- PauseDone:
- ret ; return, since it had to be
-
-
- ;-------------------------------------------------------------------------
- SP_Blank:
- .db %00000000
- .db %00000000
- .db %00000000
- .db %00000000
- .db %00000000
- .db %00000000
- .db %00000000
- .db %00000000
-
- SP_Player:
- .db %00000000
- .db %00000000
- .db %00010000
- .db %00111000
- .db %10111010
- .db %11111110
- .db %10111010
- .db %10000010
-
- SP_Enemy1:
- .db %10000001
- .db %10000001
- .db %10111101
- .db %11000011
- .db %11111111
- .db %01111110
- .db %00111100
- .db %00000000
-
- SP_Enemy2:
- .db %00000000
- .db %10000001
- .db %11000011
- .db %10111101
- .db %10111101
- .db %11011011
- .db %10011001
- .db %00000000
-
- SP_Enemy3:
- .db %00000100
- .db %01000010
- .db %10100100
- .db %00011000
- .db %00011000
- .db %00100101
- .db %01000010
- .db %00100000
-
- SP_Enemy4:
- .db %00000000
- .db %01000010
- .db %10000001
- .db %01000010
- .db %00111100
- .db %00111100
- .db %00011000
- .db %00000000
-
- SP_Enemy5:
- .db %10000010
- .db %10111010
- .db %11010110
- .db %10101010
- .db %01010100
- .db %00101000
- .db %00010000
- .db %00000000
-
- SP_PShot:
- .db %00010000
- .db %00010000
- .db %01010100
- .db %01010100
- .db %01010100
- .db %00000000
- .db %00000000
- .db %00000000
-
- SP_IShot:
- .db %00000000
- .db %00000000
- .db %00000000
- .db %00000000
- .db %00000000
- .db %00000101
- .db %00000010
- .db %00000101
-
- T_score:
- .db "SCORE",0
-
- T_level:
- .db "LEVEL",0
-
- T_lives:
- .db "LIVES",0
-
- T_enterlevel:
- .db "-=Entering level=-",0
-
- T_pressenter:
- .db "[Hit Enter]",0
-
- T_died:
- .db "You died!",0
-
- T_gameover:
- .db "GAME OVER",0
-
- titletext:
- .db " Space Invaders v1.0 ",
- .db " ",
- .db " by David Phillips ",
- .db " electrum@tfs.net ",
- .db " ",
- .db " Copyright 1998 ",
- .db " ",
- .db " [Ready?]",0
-
- .end
-