home *** CD-ROM | disk | FTP | other *** search
/ ticalc.org / ticalc_org_rev_b.iso / archives / 86 / asm / source / invaders.asm < prev    next >
Encoding:
Assembly Source File  |  2001-07-01  |  26.3 KB  |  861 lines

  1. ;
  2. ; Space Invaders v1.0
  3. ; David Phillips <electrum@tfs.net>
  4. ; program started: 04/28/98
  5. ; last     update: 06/05/98
  6. ;
  7.  
  8. #include "ti86asm.inc"
  9. #include "asm86.h"
  10. #include "ti86und.inc"
  11.  
  12. .org _asm_exec_ram
  13.  
  14.  
  15. ;-------------------------------------------------------------------------
  16. ShellTitle:
  17.     nop                        ; for the title line in shells (ASE)
  18.  
  19.     jp Startup              ; jump to real start of program
  20.  
  21.  
  22.  
  23.     .dw $0000                ; used by shell (might be used later for version numbers)
  24.  
  25.     .dw ShellTitleText        ; where the title of the program is
  26. ShellTitleText:
  27.     .db "Space Invaders by David P",0
  28.  
  29. ;-------------------------------------------------------------------------
  30. ; Variables:                    Bytes:
  31.  
  32. ; player:
  33. player         = _textShadow + 0    ; [1] X location of player (always on ground--same Y)
  34. lives          = _textShadow + 1    ; [1] number of lives player has
  35. level       = _textShadow + 2    ; [1] current level player is on
  36. score        = _textShadow + 3    ; [2] score that player has
  37. p_shots     = _textShadow + 5    ; [10] (X, Y) locations of player's shots -- max of 5
  38. fired        = _textShadow + 15    ; [1] flag to make player press fire for every shot
  39.  
  40. ; space invaders:
  41. invader_x     = _textShadow + 16    ; [1] flock's X location
  42. invader_y     = _textShadow + 17  ; [1] flock's Y location
  43. invader_dir    = _textShadow + 18    ; [1] invader's direction (-1 or 1)
  44. invader        = _textShadow + 19  ; [30] 5 x 6 array of aliens -- their life
  45. i_shots        = _textShadow + 49    ; [20] (X, Y) locations of invader's shots -- max of 10
  46. i_left        = _textShadow + 69    ; [1] number of invaders left
  47. shot_move    = _textShadow + 70    ; [1] next time to move invaders shots
  48.  
  49. ;-------------------------------------------------------------------------
  50. Startup:
  51.     call BUSY_OFF                    ; turn off the busy indicator
  52.     res appTextSave,(iy+appflags)      ; we don't want our variables to be overwritten
  53.     call _flushallmenus                ; clear menus, to use last 2 lines for text
  54.  
  55.     call _clrLCD                ; clear the display screen
  56.     ld hl,$0000                    ; load in the upper-left corner (1, 1)
  57.     ld (_curRow),hl                ; actually change the position
  58.     ld hl,titletext                ; load the address of the title screen
  59.     call _puts                    ; print the title screen
  60.     call Pause                    ; call our pause subroutine
  61.  
  62.     xor a                        ; start at level 1 -- NewLevel will up it
  63.     ld (level),a                ; set level
  64.     ld (i_left),a                ; this will force NewLevel to be called
  65.     ld a,3                        ; start with 3 lives
  66.     ld (lives),a                ; set lives
  67.     ld hl,0                        ; start with 0 score
  68.     ld (score),hl                ; set score
  69.  
  70. MainLoop:
  71.     ld a,(i_left)                ; load Aliens left counter
  72.     cp 0                        ; are they all dead?
  73.     call z,NewLevel                ; if they are, time for a new level
  74.     
  75. GetInput:
  76.     call _getky                    ; read a keypress
  77.     cp K_EXIT                    ; was it EXIT?
  78.     jp z,ExitGame                ; time to quit
  79.     cp K_MORE                    ; was it MORE?
  80.     call z,Pause                ; if so, Pause the game
  81.     di                            ; disable interrupts
  82.        ld a,%00111110                ;\  (bitmask for the
  83.  
  84.        out (1),a                    ; |  status of arrow keys
  85.  
  86.        in a,(1)                    ;/   and top keys in A)
  87.  
  88.     ei                            ; re-enable interrupts
  89.        bit 1,a                        ; is left pressed?
  90.  
  91.        jr z,MoveLeft                ; move left
  92.  
  93.        bit 2,a                        ; is right pressed?
  94.  
  95.        jr z,MoveRight                ; move right
  96.     jr OtherKeys                ; no arrows pressed, check other keys
  97. MoveLeft:
  98.     ld a,(player)                ; get the player's position
  99.     cp 1                        ; are we at the left side?
  100.     jr c,OtherKeys                ; if we are, don't move over
  101.     call ErasePlayer            ; erase player's ship before we move him
  102.     ld a,(player)                ; re-load the player's position
  103.     sub 2                        ; move left two
  104.     ld (player),a                ; set the postion
  105.     call DrawPlayer                ; draw the player in the new position
  106.     jr OtherKeys                ; we're done here
  107. MoveRight:
  108.     ld a,(player)                ; get the player's position
  109.     cp $58                        ; are we all at the right side?
  110.     jr nc,OtherKeys                ; if we are, don't move over
  111.     call ErasePlayer            ; erase player's ship before we move him
  112.     ld a,(player)                ; re-load the player's position
  113.     add a,2                        ; move right two
  114.     ld (player),a                ; set the position
  115.     call DrawPlayer                ; draw the player in the new position
  116. OtherKeys:
  117.     di                            ;  disable interrupts
  118.       ld a,%00111111                ;\  (bitmask for the
  119.  
  120.        out (1),a                    ; |  status of 2nd key
  121.  
  122.       in a,(1)                    ;/   in A)
  123.  
  124.     ei                            ; re-enable interrupts
  125.        bit 5,a                        ; is second pressed?
  126.  
  127.     jr z,Fire                    ; let them fire
  128.     xor a                        ; faster than "ld a,0"
  129.     ld (fired),a                ; reset firing flag
  130.     jp UpdateAliens                ; don't want to fire
  131.  
  132. Fire:
  133.     ld a,(fired)                ; load in fired flag
  134.     ld d,a                        ; save it for a little while
  135.     ld a,1                        ; don't want them to fire
  136.     ld (fired),a                ; set fired flag so they can't fire
  137.     ld a,d                        ; get back the old fired flag
  138.     cp 1                        ; is it set to no fire?
  139.     jp z,UpdateAliens            ; then don't let them fire
  140.     ld hl,p_shots                ; load in the invader's shots
  141.     ld b,5                        ; check up to 5 shots
  142. CheckFire:
  143.     ld a,(hl)                    ; load in the shot's x value
  144.     cp $ff                        ; is it empty?
  145.     jr z,FireCDone                ; then we're done
  146.     inc hl                        ; add one to HL
  147.     inc hl                        ; add another to HL (HL += 2)
  148.     djnz CheckFire                ; check another shot
  149.     jr UpdateAliens                ; if we're here, no shots are available
  150. FireCDone:
  151.     ld a,(player)                ; get player's x position
  152.     ld (hl),a                    ; set shot's x value
  153.     inc hl                        ; move to shot's y value
  154.     ld a,$2d                    ; start shot above player
  155.     ld (hl),a                    ; set shot's y value    
  156.  
  157. UpdateAliens:
  158.     ld a,(invader_dir)            ; get the aliens direction
  159.     ld d,a                        ; save it in D
  160.     cp 1                        ; is it 1?
  161.     jp z,MoveIRight                ; then they're moving right
  162.     ld a,(invader_x)            ; get their x position
  163.     cp 0                        ; are they at the left edge?
  164.     jp nz,MoveAliens            ; if not, move we're ready to update position
  165.     ld d,1                        ; we're at edge, time to move right
  166.     ld a,(invader_y)            ; get their y postion
  167.     inc a                        ; move down one pixel
  168.     ld (invader_y),a            ; set new position
  169.     jr MoveAliens                ; ready to update position
  170. MoveIRight:
  171.     ld a,(invader_x)            ; get their x position
  172.     cp 40                        ; are they at the right edge?
  173.     jp nz,MoveAliens            ; if not, update their position
  174.     ld d,-1                        ; we're at edge, let's move left
  175. MoveAliens:
  176.     ld a,d                        ; get their new direction
  177.     ld (invader_dir),a            ; save their new direction
  178.     ld a,(invader_x)            ; get their x position
  179.     add a,d                        ; update postion by adding current direction
  180.     ld (invader_x),a            ; save new position
  181.  
  182. DrawAliens:
  183.     ld ix,invader                ; load pointer to invaders
  184.     ld hl,SP_Enemy1                ; load pointer to their sprites
  185.     ld b,5                        ; there are 5 rows of invaders
  186.     ld a,(invader_y)            ; get their y position
  187.     ld e,a                        ; load it for drawing
  188. DrawYL:
  189.     push bc                        ; save alien y counter
  190.     ld b,6                        ; their are 6 aliens in a row
  191.     ld a,(invader_x)            ; get their x position
  192.     ld d,a                        ; load it for drawing
  193. DrawXL:
  194.     ld a,(ix+0)                    ; get the value at this alien 
  195.     cp 0                        ; is the alien dead?
  196.     jp z,DrawASkip                ; if so, we don't want to draw it
  197. DrawCheckA:
  198.     push bc                        ; save loop counter
  199.     push hl                        ; save bullet pointer
  200.     push de                        ; save draw location
  201.     ld b,5                        ; player has 5 bullets
  202.     ld hl,p_shots                ; pointer to player's shots
  203. DrawCheckAL:
  204.     push bc                        ; save loop counter
  205.     ld a,(hl)                    ; load shot's X coord
  206.     sub d                        ; calc distance from player's X coord
  207.     jr nc,DrawCheckANoCarryX    ; if not negative, skip abs code
  208.     ld b,a                        ; save negative value
  209.     xor a                        ; set A equal to zero
  210.     sub b                        ; make value positive
  211. DrawCheckANoCarryX:
  212.     cp 8                        ; are they closer than 8 pixels?
  213.     jr nc,DrawCheckASkip        ; if not, we're done
  214.     inc hl                        ; move to shot's Y coord
  215.     ld a,(hl)                    ; load shot's Y coord
  216.     sub e                        ; calc distance from player's Y coord
  217.     jr nc,DrawCheckANoCarryY    ; if not negative, skip abs code
  218.     ld b,a                        ; save negative value
  219.     xor a                        ; set A equal to zero
  220.     sub b                        ; make value positive
  221. DrawCheckANoCarryY:
  222.     cp 8                        ; are they closer than 8 pixels?
  223.     jr nc,DrawCheckASkip        ; if not, we're done
  224.     ld a,$ff                    ; $FF means shot is unused
  225.     dec hl                        ; fill shot's X value
  226.     ld b,(hl)                    ; get shot's X value for erasing
  227.     ld (hl),a                    ; this shot's done
  228.     inc hl                        ; go back to shot's Y value
  229.     ld c,(hl)                    ; get shot's Y value for erasing
  230.     push hl                        ; save shot pointer
  231.     ld hl,SP_Blank                ; want to erase the shot
  232.     call PutSprite                ; draw the blank sprite
  233.     pop hl                        ; restore shot pointer
  234.     ld a,(ix+0)                    ; get invader's life
  235.     dec a                        ; drop it by 1
  236.     cp 0                        ; did we kill them?
  237.     ld (ix+0),a                    ; save life
  238.     jr nz,DrawCheckASkip        ; only do killed stuff if life is at zero
  239.     push hl                        ; save pointer
  240.     call UpdateScore            ; score the hit
  241.     pop hl                        ; restore pointer
  242.     ld a,(i_left)                ; load aliens left counter
  243.     dec a                        ; drop counter by 1
  244.     ld (i_left),a                ; set counter
  245. DrawCheckASkip:
  246.     inc hl                        ; move to next bullet's x coord
  247.     pop bc                        ; restore loop counter
  248.     djnz DrawCheckAL            ; check all bullets
  249.     pop de                        ; restore draw location
  250.     pop hl                         ; restore bullet pointer    
  251.     pop bc                        ; restore loop counter    
  252.     push bc                        ; save alien x counter
  253.     push de                        ; save drawing position
  254.     push hl                        ; save sprite pointer
  255.     ld hl,invader_dir            ; find out which direction they're going
  256.     ld a,d                        ; get their x position
  257.     sub (hl)                    ; calc position before we moved them
  258.     ld b,a                        ; save x position for drawing
  259.     ld c,e                        ; save y position for drawing
  260.     ld a,(invader_dir)            ; get their direction again
  261.     cp 1                        ; see if they're going right
  262.     jr nz,DrawANoDrop            ; if not, then they didn't drop--drops on left side
  263.     ld a,(invader_x)            ; get their x position again
  264.     cp 1                        ; check if they're one position over
  265.     jr nz,DrawANoDrop            ; if not, we didn't drop them
  266.     dec c                        ; we dropped them, draw blank up one pixel
  267. DrawANoDrop:
  268.     ld hl,SP_Blank                ; load in a blank sprite
  269.     call PutSprite                ; draw the blank
  270.     pop hl                        ; restore sprite pointer
  271.     pop de                        ; restore saved draw location
  272.     pop bc                        ; restore draw location
  273.     ld a,(ix+0)                    ; get life--might have been hit
  274.     cp 0                        ; did player just kill him?
  275.     jp z,DrawASkip                ; if so, don't draw--but we needed to erase it
  276.  
  277. DrawCheckBottom:
  278.     ld a,56                        ; check if they are at screen bottom
  279.     cp e                        ; do the check
  280.     jr nc,DrawPlayerOK            ; if they not, player isn't dead
  281.     pop hl                        ; clear top of stack
  282.     jp PlayerKilled                ; kill the player
  283.  
  284. DrawPlayerOK:
  285.     ld a,r                        ; get a not-very-random number (memory refresh counter)
  286.  
  287.     cp 40                        ; is it our number?
  288.  
  289.     jr nz,DrawNoFire            ; if not, we're not going to fire
  290.  
  291.     push bc                        ; save loop counters
  292.     push hl                        ; save pointer to alien's sprites    
  293. DrawFire:
  294.     ld hl,i_shots                ; load in the invader's shots
  295.     ld b,10                        ; we need to check all 10 shots
  296. DrawCheckFire:
  297.     ld a,(hl)                    ; load in the shot's x value
  298.     cp $ff                        ; is it empty?
  299.     jr z,DrawFireCDone            ; then we're done
  300.     inc hl                        ; add one to HL
  301.     inc hl                        ; add another to HL (HL += 2)
  302.     djnz DrawCheckFire            ; check another shot
  303.     jp DrawNoFreeShots            ; if we're here, there are no free shots--can't fire
  304. DrawFireCDone:
  305.     ld (hl),d                    ; set shot's x value
  306.     inc hl                        ; move to shot's y value
  307.     ld (hl),e                    ; set shot's y value
  308. DrawNoFreeShots:
  309.     pop hl                        ; restore pointer to alien's sprites
  310.     pop bc                        ; restore loop counters
  311.  
  312. DrawNoFire:
  313.     push bc                        ; save all regs before drawing
  314.     push de                        ; still saving
  315.     push hl                        ; once more, please
  316.     ld b,d                        ; put x coord in for drawing
  317.     ld c,e                        ; put y coord in for drawing        
  318.     call PutSprite                ; draw the alien
  319.     pop hl                        ; restore sprite pointer
  320.     pop de                        ; restore saved draw location
  321.     pop bc                        ; restore loop counter
  322. DrawASkip:
  323.     ld a,d                        ; load in their x coord
  324.     add a,9                        ; next alien is 9 pixels right
  325.     ld d,a                        ; save the coord
  326.     inc ix                        ; move to next alien
  327.     dec b                        ; ------------------------\  loop is too big
  328.     ld a,b                        ;                            \ to use relative
  329.     cp 0                        ;                            / jump instruction
  330.     jp nz,DrawXL                ; loop through entire row /  "djnz DrawXL"
  331.     ld bc,$8                    ; a sprite is 8 bytes long
  332.     add hl,bc                    ; move to the next sprite
  333.     pop bc                        ; restore loop counter
  334.     ld a,e                        ; get their y coord
  335.     add a,8                        ; next alien is 8 pixels down
  336.     ld e,a                        ; save the coord
  337.     dec b                        ; ----------------------\  loop is too big
  338.     ld a,b                        ;                          \ to use relative
  339.     cp 0                        ;                          / jump instruction
  340.     jp nz,DrawYL                ; loop through all rows /  "djnz DrawYL"
  341.  
  342. UpdatePShots:
  343.     ld b,5                        ; we want to draw all 5 shots
  344.     ld hl,p_shots                ; load in the shots
  345. UpdatePLoop:
  346.     push bc                        ; save loop counter
  347.     ld b,(hl)                    ; load in it's x value
  348.     ld a,b                        ; load in the x value for check
  349.     cp $ff                        ; check if the shot's active
  350.     jr z,UpdatePSkip            ; if not, skip it
  351.     inc hl                        ; move to y value
  352.     ld c,(hl)                    ; load in it's y value
  353.     ld a,c                        ; get the shot's y value
  354.     sub 3                        ; move shot up by 3
  355.     ld (hl),a                    ; set shot y value
  356.     cp $80                        ; did it go past the top?
  357.     jr nc,UpdatePExpired        ; then kill it
  358.     inc hl                        ; move to next shot's x value
  359.     push hl                        ; save shot pointer
  360.     push bc                        ; save shot's location
  361.     ld hl,SP_Blank                ; want to erase the shot
  362.     ld a,c                        ; load in the shot's y value
  363.     add a,3                        ; erase 3 pixels down
  364.     ld c,a                        ; set y draw value
  365.     call PutSprite                ; draw the blank sprite
  366.     pop bc                        ; restore shot's location
  367.     ld hl,SP_PShot                ; load pointer to sprite of shot
  368.     call PutSprite                ; draw the shot
  369.     pop hl                        ; restore shot pointer
  370.     jr UpdatePNoSkip            ; don't want to kill the shot
  371. UpdatePExpired:
  372.     dec hl                        ; move back to x value
  373.     ld a,$ff                    ; load in clear value
  374.     ld (hl),a                    ; set shot to cleared
  375.     push hl                        ; save shot pointer
  376.     ld hl,SP_Blank                ; want to erase the shot
  377.     ld c,0                        ; erase at top of screen
  378.     call PutSprite                ; draw the blank sprite
  379.     pop hl                        ; restore shot pointer
  380. UpdatePSkip:    
  381.     inc hl                        ; skip the shot's x value
  382.     inc hl                        ; skip the shot's y value
  383. UpdatePNoSkip:
  384.     pop bc                        ; restore loop counter
  385.     djnz UpdatePLoop            ; loop for all shots
  386.  
  387. UpdateIShots:
  388.     ld a,(shot_move)            ; load in invader shot move timer
  389.     cp 0                        ; is it at 0?
  390.     jr z,UpdateTrue                ; if it is, time to update
  391.     xor a                        ; set a to 0
  392.     ld (shot_move),a            ; move shots next frame
  393.     jp LoopDone                    ; skip updating this time    
  394. UpdateTrue:
  395.     ld a,1                        ; we don't want to be updated next frame
  396.     ld (shot_move),a            ; set shot move timer
  397.     ld b,10                        ; we want to draw all 10 shots
  398.     ld hl,i_shots                ; load in the shots
  399. UpdateILoop:
  400.     push bc                        ; save loop counter
  401.     ld b,(hl)                    ; load in it's x value
  402.     ld a,b                        ; load in the x value for check
  403.     cp $ff                        ; check if the shot's active
  404.     jr z,UpdateISkip            ; if not, skip it
  405.     inc hl                        ; move to y value
  406.     ld a,(hl)                    ; load in it's y value
  407.     inc a                        ; move shot down one
  408.     ld (hl),a                    ; set shot y value
  409.     ld c,a                        ; load in the value for sprite drawing    
  410. UpdateICheck:
  411.     cp 49                        ; see if it's at the player's height
  412.     jr c,UpdateIDraw            ; if not, no collision
  413.     ld a,(player)                ; get player's x value
  414.     sub b                        ; calc distance between player and shot's x value
  415.     jr nc,UpdateINoABS            ; if not negative, skip abs code
  416.     ld d,a                        ; save negative value
  417.     xor a                        ; set A equal to zero
  418.     sub d                        ; make value positive
  419. UpdateINoABS:
  420.     cp 8                        ; are they closer than 8 pixels?
  421.     jr nc,UpdateIDraw            ; if not, we're done here
  422.     pop hl                        ; clear top of stack
  423.     ld a,(level)                ; get the current level
  424.     dec a                        ; it will be incremented by NewLevel
  425.     ld (level),a                ; set new level
  426.     jp PlayerKilled                ; if we're still here, we collided
  427. UpdateIDraw:
  428.     ld a,c                        ; get the shot's y value for compare
  429.     cp 56                        ; did it go past the bottom
  430.     jr nc,UpdateIExpired         ; then kill it
  431.     inc hl                        ; move to next shot's x value
  432.     push hl                        ; save shot pointer
  433.     ld hl,SP_IShot                ; load pointer to sprite of shot
  434.     call PutSprite                ; draw the shot
  435.     pop hl                        ; restore shot pointer
  436.     jr UpdateINoSkip            ; don't want to kill the shot
  437. UpdateIExpired:
  438.     dec hl                        ; move back to x value
  439.     ld a,$ff                    ; load in clear value
  440.     ld (hl),a                    ; set shot to cleared
  441.     push hl                        ; save shot pointer
  442.     ld hl,SP_Blank                ; want to erase the shot
  443.     ld c,56                        ; erase at bottom of screen
  444.     call PutSprite                ; draw the blank sprite
  445.     pop hl                        ; restore shot pointer
  446. UpdateISkip:    
  447.     inc hl                        ; skip the shot's x value
  448.     inc hl                        ; skip the shot's y value
  449. UpdateINoSkip:
  450.     pop bc                        ; restore loop counter
  451.     djnz UpdateILoop            ; loop for all shots
  452.  
  453. LoopDone:
  454.     call DrawScore                ; print our score
  455.     jp MainLoop                    ; time to do the next frame
  456.  
  457. GameOver:
  458.     call _clrLCD                ; clear the screen
  459.     ld hl,$0603                    ; put text at 4,7
  460.     ld (_curRow),hl                ; set new text position
  461.     ld hl,T_gameover            ; tell them the game's over
  462.     call _puts                    ; print the text
  463.     ld hl,$0505                    ; put text at 6,6
  464.     ld (_curRow),hl                ; set new text position
  465.     ld hl,T_score                ; load text "score" to print
  466.     call _puts                    ; print the text
  467.     ld hl,$0b05                    ; put text at 6,11
  468.     ld (_curRow),hl                ; set new text position
  469.     ld hl,(score)                ; load the score to print
  470.     xor a                        ; clear high byte
  471.     call _dispAHL                 ; print the number
  472.     call Pause                    ; wait for a key
  473.  
  474. ExitGame:
  475.     set appTextSave,(iy+appflags)      ; we want _textShadow to be cleared with _clrScrn
  476.     call _clrScrn                    ; clear the screen before exit (including _textShadow)
  477.     ret                                ; return to TI-OS or a shell
  478.  
  479. UpdateScore:
  480.     ld hl,(score)                ; get the current score
  481.     ld de,25                    ; add 25 to it
  482.     add hl,de                    ; do the add
  483.     ld (score),hl                ; store the score
  484.     ret
  485.  
  486. PlayerKilled:
  487.     ld a,(lives)                ; get the player's lives
  488.     dec a                        ; make them lose a life
  489.     ld (lives),a                ; set new lives
  490.     call _clrLCD                ; clear the screen
  491.     ld hl,$0603                    ; place text at 4,7
  492.     ld (_curRow),hl                ; set text position
  493.     ld hl,T_died                ; tell user they are dead
  494.     call _puts                    ; print the string
  495.     call Pause                    ; wait, so they can see the message
  496.     ld a,(lives)                ; does player have lives left?
  497.     cp 0                        ; check if lives are at 0
  498.     jp z,GameOver                ; if they are, game is over
  499.     call NewLevel                ; restart the level--note: advances level by one
  500.     jp GetInput                    ; ready for top of main loop
  501.     
  502.  
  503. ;-------------------------------------------------------------------------
  504. Reset:
  505.  
  506. ClearIShots:
  507.     ld b,10                        ; run loop for all 10 shots
  508.     ld a,$ff                    ; $FF will stand for an unused shot
  509.     ld hl,i_shots               ; hl points to the start of the invader's shots
  510. ClrILoop:
  511.     ld (hl),a                    ; clear out the shot by putting $FF into it
  512.     inc hl                        ; move to the next shot's X value
  513.     inc hl                        ; easier than loading into a 16-bit reg, then adding
  514.     djnz ClrILoop                ; loop through all the shots
  515.  
  516. ClearPShots:
  517.     ld b,5                        ; run loop for all 5 shots
  518.     ld a,$ff                    ; $FF will stand for an unused shot
  519.     ld hl,p_shots                  ; hl points to the start of the player's shots
  520. ClrPLoop:
  521.     ld (hl),a                    ; clear out the shot by putting $FF into it
  522.     inc hl                        ; move to the next shot's X value
  523.     inc hl                        ; easier than loading into a 16-bit reg, then adding
  524.     djnz ClrPLoop                ; loop through all the shots
  525.  
  526. ClearAliens:
  527.     ld a,(level)                ; get the level number
  528.     dec a                        ; subtract one so level/life starts at zero
  529.     sra a                        ; life is equal to level divided by two
  530.     inc a                        ; add one to it--life can't be zero
  531.     ld b,30                        ; run loop for all 30 aliens
  532.     ld hl,invader                  ; hl points to the start of the alien flock
  533. ClrALoop:
  534.     ld (hl),a                    ; set the alien's life
  535.     inc hl                        ; move to the alien
  536.     djnz ClrALoop                ; loop through all the aliens
  537.  
  538.     ret                            ; we're done with the Reset
  539.  
  540.  
  541. ;-------------------------------------------------------------------------
  542. ErasePlayer:
  543.     ld a,(player)                ; get player's position
  544.     ld b,a                        ; that's the X value
  545.     ld c,55                        ; place at bottom row
  546.     ld hl,SP_Blank                ; put blank sprite
  547.     call PutSprite                 ; draw it
  548.     ret                            ; return
  549.  
  550. DrawPlayer:
  551.     ld a,(player)                ; get player's position
  552.     ld b,a                        ; that's the X value
  553.     ld c,55                        ; place at bottom row
  554.     ld hl,SP_Player                ; we want to draw the player's ship
  555.     call PutSprite                 ; draw it
  556.     ret                         ; return
  557.  
  558. DrawStatus:
  559.     ld hl,$1000                    ; ***place at (1, 17)
  560.     ld (_curRow),hl                ; set text position
  561.     ld hl,T_score                ; write text "SCORE"
  562.     call _puts                    ; draw the text
  563.     ld hl,$1003                    ; ***place at (4, 17)
  564.     ld (_curRow),hl                ; set text position
  565.     ld hl,T_level                ; write text "LEVEL"
  566.     call _puts                    ; draw the text
  567.     ld hl,$1004                    ; ***place at (5, 17)
  568.     ld (_curRow),hl                ; set text position
  569.     ld a,(level)                ; load the level to print
  570.     ld l,a                        ; move to low byte
  571.     ld h,0                        ; clear the middle byte
  572.     xor a                        ; clear high byte
  573.     call _dispAHL                 ; print the number
  574.     ld hl,$1006                    ; ***place at (7, 17)
  575.     ld (_curRow),hl                ; set text position
  576.     ld hl,T_lives                ; write text "LIVES"
  577.     call _puts                    ; draw the text
  578.     ld hl,$1007                        ; ***place at (8, 17)
  579.     ld (_curRow),hl                    ; set text position
  580.     ld a,(lives)                    ; load the lives to print
  581.     ld l,a                            ; move to low byte
  582.     ld h,0                            ; clear the middle byte
  583.     xor a                            ; clear high byte
  584.     res appAutoScroll,(iy+appflags)    ; turn off auto scrolling of text
  585.     call _dispAHL                     ; print the number
  586.     set appAutoScroll,(iy+appflags) ; turn it back on (so TI-OS isn't screwed)
  587.  
  588. DrawScore:
  589.     ld hl,$1001                    ; place at (2, 17)
  590.     ld (_curRow),hl                ; set text position
  591.     ld hl,(score)                ; load the score to print
  592.     xor a                        ; clear high byte
  593.     call _dispAHL                 ; print the number
  594.     ret                            ; we're done here
  595.  
  596. ;-------------------------------------------------------------------------
  597. NewLevel:
  598.     ld a,30                        ; there are 30 aliens
  599.     ld (i_left),a                ; set aliens left counter
  600.     ld a,44                        ; start player in center
  601.     ld (player),a                ; set player position
  602.      xor    a                        ; start invaders in upper left (a = 0)
  603.     ld (invader_x),a            ; set invader x
  604.     ld (invader_y),a            ; set invader y
  605.     ld (fired),a                ; let them fire
  606.     ld a,1                        ; start invaders moving right
  607.     ld (invader_dir),a            ; set invader direction
  608.     ld a,(level)                ; load the level number
  609.     inc a                        ; up it by 1
  610.     ld (level),a                ; set level number
  611.     call Reset                    ; setup for the level
  612.  
  613. ShowLevelScrn:
  614.     call _clrLCD                ; clear the display screen
  615.     ld hl,$0102                    ; place at (3, 2)
  616.     ld (_curRow),hl                ; set text position
  617.     ld hl,T_enterlevel            ; load the text to print
  618.     call _puts                    ; print the text
  619.     ld hl,$0704                    ; place at (5, 8)
  620.     ld (_curRow),hl                ; set text position
  621.     ld a,(level)                ; load the level to print
  622.     ld l,a                        ; move to low byte
  623.     ld h,0                        ; clear the middle byte
  624.     xor a                        ; clear high byte
  625.     call _dispAHL                 ; print the number
  626.     ld hl,$0904                    ; place at (5, 10)
  627.     ld (_curRow),hl                ; set text position
  628.     ld a,'<'                    ; load char to print
  629.     call _putc                    ; print the char    
  630.     ld hl,$0c04                    ; place at (5, 13)
  631.     ld (_curRow),hl                ; set text position
  632.     ld a,'>'                    ; load char to print
  633.     call _putc                    ; print the char
  634.     ld hl,$0507                    ; place at (8, 6)
  635.     ld (_curRow),hl                ; set text position
  636.     ld hl,T_pressenter            ; load the text to print
  637.     call _puts                    ; print the text
  638.     call Pause                    ; wait for enter
  639.  
  640. InitScreen:
  641.     call _clrLCD                ; clear the display screen...again
  642.     call DrawStatus                ; print text information
  643.     call DrawPlayer                ; draw the player the first time
  644.  
  645.     ret                            ; NewLevel is done
  646.  
  647.  
  648. ;-------------------------------------------------------------------------
  649. ; ASCR    - Advanced Sprite Clipping Routines
  650. ;
  651. ;     by Jimmy MÃ¥rdell    970304     Last update 970803
  652. ;
  653. ;    modified by David Phillips to remove clipping
  654. ;   faster without clipping--the only routines that worked with this game
  655. ;
  656. PutSprite:         ; BC = x,y  HL = sprite
  657.  push bc
  658.  push de
  659.  push hl
  660.  push ix
  661.  push hl
  662.  pop ix
  663.  ld a,8
  664.  push af
  665.  call FIND_PIXEL
  666. Modify_6:
  667.  ld de,$FC00
  668.  add hl,de
  669.  ld d,a
  670.  pop bc
  671. PSC_PutRow:
  672.  push bc
  673.  push hl
  674.  ld a,$ff
  675.  ld e,a
  676.  ld b,8
  677.  ld c,(ix)
  678.  inc ix
  679. PSC_PutCol:
  680.  push bc
  681.  rlc e
  682.  jr nc,PSC_NextBit
  683.  ld a,d
  684.  rlc c
  685.  jr c,PSC_BitOn
  686.  cpl
  687.  and (hl)
  688.  ld (hl),a
  689.  jr PSC_NextBit
  690. PSC_BitOn:
  691.  or (hl)
  692.  ld (hl),a
  693. PSC_NextBit:
  694.  rrc d
  695.  jr nc,PSC_SSB
  696.  inc hl
  697. PSC_SSB:
  698.  pop bc
  699.  rlc c
  700.  djnz PSC_PutCol
  701.  pop hl
  702.  ld bc,16
  703.  add hl,bc
  704.  pop bc
  705.  djnz PSC_PutRow
  706. EndPS:
  707.  pop ix
  708.  pop hl
  709.  pop de
  710.  pop bc
  711.  ret
  712. FIND_PIXEL:
  713.  push bc
  714.  push de
  715.  ld hl,ExpTable+1
  716.  ld d,0
  717.  ld a,b
  718.  and $07
  719.  ld e,a
  720.  add hl,de
  721.  ld e,(hl)
  722.  ld h,d
  723.  srl b
  724.  srl b
  725.  srl b
  726.  ld a,c
  727.  add a,a
  728.  add a,a
  729.  ld l,a
  730.  add hl,hl
  731.  add hl,hl
  732.  ld a,e
  733.  ld e,b
  734.  add hl,de
  735.  pop de
  736.  pop bc
  737.  ret
  738. ExpTable:
  739.  .db $01,$80,$40,$20,$10,$08,$04,$02,$01
  740.  
  741.  
  742. ;-------------------------------------------------------------------------
  743. Pause:
  744.     call _getky                ; wait for a key to be pressed
  745.     cp K_ENTER                ; was it enter?
  746.     jr z,PauseDone            ; if it was, we're done
  747.     cp K_MORE                ; maybe it was more?
  748.     jr z,PauseDone            ; if so, we're done here also
  749.     cp K_EXIT                ; or was it exit?
  750.     jr nz,Pause                ; if it wasn't, wait for another key press
  751. PauseDone:
  752.     ret                        ; return, since it had to be
  753.  
  754.  
  755. ;-------------------------------------------------------------------------
  756. SP_Blank:
  757.     .db %00000000
  758.     .db %00000000
  759.     .db %00000000
  760.     .db %00000000
  761.     .db %00000000
  762.     .db %00000000
  763.     .db %00000000
  764.     .db %00000000
  765.  
  766. SP_Player:
  767.     .db %00000000
  768.     .db %00000000
  769.     .db %00010000
  770.     .db %00111000
  771.     .db %10111010
  772.     .db %11111110
  773.     .db %10111010
  774.     .db %10000010
  775.  
  776. SP_Enemy1:
  777.     .db %10000001
  778.     .db %10000001
  779.     .db %10111101
  780.     .db %11000011
  781.     .db %11111111
  782.     .db %01111110
  783.     .db %00111100
  784.     .db %00000000
  785.  
  786. SP_Enemy2:
  787.     .db %00000000
  788.     .db %10000001
  789.     .db %11000011
  790.     .db %10111101
  791.     .db %10111101
  792.     .db %11011011
  793.     .db %10011001
  794.     .db %00000000
  795.  
  796. SP_Enemy3:
  797.     .db %00000100
  798.     .db %01000010
  799.     .db %10100100
  800.     .db %00011000
  801.     .db %00011000
  802.     .db %00100101
  803.     .db %01000010
  804.     .db %00100000
  805.  
  806. SP_Enemy4:
  807.     .db %00000000
  808.     .db %01000010
  809.     .db %10000001
  810.     .db %01000010
  811.     .db %00111100
  812.     .db %00111100
  813.     .db %00011000
  814.     .db %00000000
  815.  
  816. SP_Enemy5:
  817.     .db %10000010
  818.     .db %10111010
  819.     .db %11010110
  820.     .db %10101010
  821.     .db %01010100
  822.     .db %00101000
  823.     .db %00010000
  824.     .db %00000000
  825.  
  826. SP_PShot:
  827.     .db %00010000
  828.     .db %00010000
  829.     .db %01010100
  830.     .db %01010100
  831.     .db %01010100
  832.     .db %00000000
  833.     .db %00000000
  834.     .db %00000000
  835.  
  836. SP_IShot:
  837.     .db %00000000
  838.     .db %00000000
  839.     .db %00000000
  840.     .db %00000000
  841.     .db %00000000
  842.     .db %00000101
  843.     .db %00000010
  844.     .db %00000101
  845.  
  846. T_score:
  847.     .db "SCORE",0
  848.  
  849. T_level:
  850.     .db "LEVEL",0
  851.  
  852. T_lives:
  853.     .db "LIVES",0
  854.  
  855. T_enterlevel:
  856.     .db "-=Entering  level=-",0
  857.  
  858. T_pressenter:
  859.     .db "[Hit Enter]",0
  860.  
  861. T_died:
  862.     .db "You died!",0
  863.  
  864. T_gameover:
  865.     .db "GAME OVER",0
  866.  
  867. titletext:
  868.     .db " Space Invaders v1.0 ",
  869.     .db "                     ",
  870.     .db "  by David Phillips  ",
  871.     .db "  electrum@tfs.net   ",
  872.     .db "                     ",
  873.     .db "   Copyright 1998    ",
  874.     .db "                     ",
  875.      .db "      [Ready?]",0
  876.  
  877. .end
  878.