+ ret
+
+dostory:
+ cal storyPage ;do some story
+ inc hl ;look at next hl
+ ld a,(hl) ;load in a
+ dec hl ;restory hl
+ inc a ;set z-flag if a = $ff
+ jr nz,dostory ;otherwise loop
+
+ ld bc,5 ;story ends
+ add hl,bc ;set hl to beginning of the level
+ ld (levelp),hl ;set the level-pointer
+ ret ;and return
+
+;--------------------------- SFX ---------------------------------------------
+
+CDoSFX:
+ ld hl,VIDEO_MEM
+ ld de,GRAPH_MEM
+ ld bc,1024
+ ldir
+ ld b,64
+ ld a,-1
+
+DoSFX: ;ins: a=beginLine b=nrOfLines
+ ld (curline),a
+SFXframe:
+ psh bc
+
+ ld a,(curline) ;get line number
+ inc a ;go to the next line
+ ld (curline),a ;update
+
+ ld l,a
+ ld h,0
+ add hl,hl
+ add hl,hl
+ add hl,hl
+ add hl,hl
+
+ ld b,h ;save hl for later
+ ld c,l
+
+ ld de,VIDEO_MEM
+ add hl,de ;go to ymin
+ ld d,h
+ ld e,l
+
+ ld hl,GRAPH_MEM
+ add hl,bc ;hl->logo
+
+ ld a,(curline) ;Calculate how many lines to draw
+ ld c,a
+ ld a,64
+ sub c
+ ld b,a
+
+SFXdisp: ;display this frame on screen
+ ld a,b ;psh b (a will not be used)
+ ld bc,16 ;one line (=16 bytes, you'd know by now)
+ ldir ;display (copy actually)
+ ld bc,-16 ;go up one line (not on screen)
+ add hl,bc ;so the same line will be displayed
+ ld b,a ;pop b
+ dnz SFXdisp ;repeat until whole screen is displayed
+
+ ld b,8
+SFXdelay:
+ halt
+ dnz SFXdelay
+
+ pop bc
+ dnz SFXframe
+ ret
+
+;--------------------------- show icon ----------------------------------------
+
+drawline:
+ ld (hl),a ;draw one piece of the divider-line
+ inc hl ;move right (8 pixels = 1 byte)
+ dnz drawline ;repeat (16bytes * 8pixels =128= screen width)
+ ret
+
+disp_icons:
+ psh bc \ psh de \ psh hl \ psh ix ;&&&
+
+ ld hl,VIDEO_MEM+(16*56);56 rows down = eight rows from bottom
+ ld (PutWhere),hl ;place icons at bottom of normal screen
+ ld b,16 ;draw 16x (screen width)
+ ld a,%11111111 ;horizontal line mask
+ cal drawline ;draw divider-line
+
+ ld b,16*7 ;draw 16x (screen width) 7x (height)
+ xor a ;blank line mask
+ cal drawline ;clear scorebar
+
+ cal disp_lives
+
+ ld ix,spr_icon01 ;armorIcon
+ ld de,$1901 ;icon #1
+ cal putwidesprite ;display icon
+ cal disp_armor ;display bar
+
+ ld ix,spr_icon00
+ ld a,(torp_occ)
+ or a
+ jr z,no_torp
+ ld ix,spr_icon02 ;torpedoIcon
+no_torp:
+ ld de,$2901 ;icon #2
+ cal putwidesprite ;display
+
+ ld ix,spr_icon03 ;bulletIcon
+ ld de,$3901 ;icon #3
+ cal putwidesprite ;display icon
+ ld hl,$3945 ;position to display bullet-type digit
+ ld a,(your_weapon) ;digit
+ dec a ;minus one (1=laser)
+ ld (_penCol),hl ;set location
+ add a,'0' ;make digit
+ cal _vputmap ;display char
+
+ ld ix,spr_icon00 ;emptyIcon
+ ld a,(your_weapon)
+ dec a
+ jr nz,no_laser
+ ld ix,spr_icon04 ;laserIcon
+no_laser:
+ ld de,$4901 ;icon #4
+ cal putwidesprite
+
+ ld ix,spr_icon00 ;emptyIcon
+ ld a,(your_multiples)
+ and %11
+ jr z,no_multiples
+ ld ix,spr_icon05
+no_multiples:
+ ld de,$5901 ;icon #5
+ cal putwidesprite
+
+ ld ix,spr_dividerline
+ ld de,$6901
+ cal putwidesprite
+
+ ld a,(your_pickup) ;pickups taken
+ add a,a ;picks*2 (sets z-flag)
+ jr z,iconsdone ;return if no pickups
+ add a,a ;picks*4
+ add a,a ;picks*8
+ add a,a ;picks*$10
+ add a,$09 ;add 0ah
+ ld d,a ;y-pos = picks * $10 + $0a (19,29,39,49,59)
+ ld e,$01 ;x-pos = bottom (1a01,2a01,3a01,4a01,5a01)
+
+ ld ix,spr_icon
+ cal putwidesprite
+iconsdone:
+ ld hl,GRAPH_MEM ;normal game-screen
+ ld (PutWhere),hl ;set sprite-position to normal screen
+
+ pop ix \ pop hl \ pop de \ pop bc
+ ret
+
+disp_armor:
+ ld hl,(57*16)+VIDEO_MEM+3
+ ld b,3
+armorbarclr:
+ dec hl
+ ld (hl),0
+ dnz armorbarclr
+
+ ld a,(your_armor) ;load your armor
+ ld c,a ;psh a
+ srl a ;/2
+ srl a ;/4
+ srl a ;/8: don't display last 2 bits of a (later)
+ jr z,noarmorbar ;if a=0 then it would loop 256x so skip it
+ ld b,a ;loop b=a times
+armorbar: ;starting at ($39*16)+VIDEO_MEM
+ ld (hl),%11111111 ;draw a piece of the bar
+ inc hl ;next position
+ dnz armorbar ;loop it b times
+
+noarmorbar:
+ ld a,c ;pop a
+ and %111 ;display last bits of armor
+ ret z ;if armor=0 then bit = %00000000 (don't disp)
+ ld b,a ;into B
+ xor a ;bit = %00000000
+armorbarbit:
+ scf ;set carry flag
+ rra ;rotates A right and sets bit 7 (c-flag)
+ dnz armorbarbit ;repeat B times (so if B=6 then a=%11111100)
+armorbarready: ; (an if B=3 then a=%11100000)
+ ld (hl),a ;draw this last byte
+ ret
+
+disp_lives:
+ ld hl,$3A00 ;display Lives
+ ld (_penCol),hl ;bottom left
+ ld hl,savestr+2
+ ld (hl),'L'
+ inc hl
+ ld (hl),'x'
+ inc hl
+
+ ld a,(your_lives) ;nr of lives in a
+ add a,'0' ;make digit
+ ld (hl),a
+ dec hl \ dec hl
+ jp _vputs ;display on screen +ret
+
+;--------------------------- proc ---------------------------------------------
+
+Random5016:
+ cal Random50 ; a = 0..50
+ inc a ; a = 1..51
+ ld h,0
+ ld l,a ;hl = 1..51
+ add hl,hl ;hl = 1..51 * 2
+ add hl,hl ;hl = 1..51 * 4
+ add hl,hl ;hl = 1..51 * 8
+ add hl,hl ;hl = 1..51 * 16 (left side at random y)
+ dec hl ;hl = 1..51 * 16 (" at right side of screen)
+ ld de,GRAPH_MEM
+ add hl,de ;position on screen
+ ret
+
+Random50:
+ cal Random
+ cp 51 ;y may not be more than 50
+ ret c ;OK if a<51
+ and %00111111 ;a = 0..63
+ sub 13 ;a = -13..50
+ ret nc ;OK if a>=0
+ add a,13+(50-12) ;a = -13..-1 >=> 0..12 >=> 39..50
+ ret
+
+Random:
+ ld a,(RanPos) ;a handy random-var.
+ ld hl,x ;add your x-coord for randomness
+ adc a,(hl)
+ inc hl ;add your y-coord for randomness
+ adc a,(hl)
+ ld (RanPos),a ;save altered random-var
+ ret ;RanPos also in #a
+
+scoreInc:
+ psh bc
+ ld bc,(score)
+ add hl,bc
+ ld (score),hl
+ pop bc
+ ret
+
+find_sprite: ;destroyed: de ix
+ psh hl
+ ld e,(hl) ;e = enemy type
+ ld d,0 ;de = e
+ ld hl,XLenemytable ;hl = @sprites offset-table
+ add hl,de ;points to offset of current enemy offset
+ ld e,(hl) ;de = @enemy offset
+ ld d,0
+
+ ld ix,XLsprenemies ;first enemy sprite
+ add ix,de ;add offset for current enemy
+ add ix,de ;twice (offset stored as offset/2)
+ pop hl
+ ret
+
+BLACKLCD:
+ ld hl,VIDEO_MEM ;screen location (top left)
+ ld de,VIDEO_MEM+1
+ ld (hl),%11111111
+ ld bc,1024-1 ;do it 1024 times = entire screen
+ ldir
+ set 3,(iy+5) ;set white on black
+ ret
+
+waitnokeypressed:
+ halt \ halt
+ cal GET_KEY
+ or a
+ jr nz,waitnokeypressed
+ ret
+
+Decompress: ;hl=source(compressed) de=dest(decompressed)
+ ld a,(hl)
+ bit 7,a
+ jr z,compressed
+ inc hl
+ and %01111111
+ ld b,0
+ ld c,a
+ ldir
+ jr Decompress
+compressed:
+ psh af
+ or %11111100
+ ld b,a
+ inc hl
+ ld c,(hl)
+ inc hl
+ pop af
+ and %01111100
+ rrca
+ rrca
+ or a
+ ret z
+ psh hl
+ ld h,d
+ ld l,e
+ add hl,bc
+ inc a
+ inc a
+ ld b,0
+ ld c,a
+ ldir
+ pop hl
+ jr Decompress
+
+;--------------------------- game over / new game / death ---------------------
+chartable:
+ .db 0,"!<>^",0,0,0,0
+ .db 0,"xtoje0",0 ;enter..clear
+ .db " wsnid9",0 ;(-)..custom
+ .db "zvrmhc8",0 ;dot..del
+ .db "yuqlgb7x" ;0..xvar
+ .db 0,"-pkfa6'" ;on..alpha
+ .db "54321.",0,0 ;F5..more
+
+own_name:
+ .db 7,"nemesis"
+
+save_hi:
+ ld hl,own_name-1 ;find own variable
+ rst 20h ;cal _ABS_MOV10TOOP1
+ rst 10h ;cal _FINDSYM
+ ret c ;not found? who cares...
+
+ xor a
+ ld hl,4+storehi_start-_asm_exec_ram
+ add hl,de ;hl=pointer to data in original prog
+ adc a,b
+ cal _SET_ABS_DEST_ADDR
+ xor a
+ ld hl,storehi_start
+ cal _SET_ABS_SRC_ADDR
+ ld hl,storehi_end-storehi_start
+ cal _SET_MM_NUM_BYTES
+ jp _mm_ldir ;save done (cal \ ret)
+
+save_lvl:
+ ld hl,own_name-1 ;find own variable
+ rst 20h ;cal _ABS_MOV10TOOP1
+ rst 10h ;cal _FINDSYM
+ ret c ;not found? who cares...
+
+ xor a
+ ld hl,4+storesave_start-_asm_exec_ram
+ add hl,de ;hl=pointer to data in original prog
+ adc a,b
+ cal _SET_ABS_DEST_ADDR
+ xor a
+ ld hl,storesave_start
+ cal _SET_ABS_SRC_ADDR
+ ld hl,storesave_end-storesave_start
+ cal _SET_MM_NUM_BYTES
+ jp _mm_ldir ;save done (cal \ ret)
+ ret
+
+game_over:
+ pop hl ;=ret (game_over was called from a procedure)
+game_over_nopop:
+ cal BLACKLCD ;clear screen
+ cal waitnokeypressed
+ ld hl,$0603
+ ld (_curRow),hl ;center
+ ld hl,txt_gameover
+ cal _puts ;display "GAME OVER"
+
+ ld hl,$0007
+ ld (_curRow),hl
+
+ ld de,(score)
+ ld hl,(hiscore)
+ cal CP_HL_DE
+ jr nc,no_hiscore
+ ld (hiscore),de
+
+ask_hiname:
+ ld ix,hiname
+ ld a,9
+ ld (hiscorepos),a
+enter_name_loop:
+ ld a,'_'
+ cal _putc
+ ld hl,_curCol
+ dec (hl)
+nokeypressed:
+ halt \ halt
+ cal GET_KEY
+ or a
+ jr z,nokeypressed
+
+ cp K_DEL
+ jr z,backup
+ cp K_ENTER
+ jr z,nomore
+ cp K_EXIT
+ jr z,nomore
+
+ ld hl,hiscorepos
+ ld b,(hl)
+ dec b
+ jr z,nokeypressed
+ ld (hl),b
+
+ ld hl,chartable
+ ld e,a
+ ld d,0
+ add hl,de
+ ld a,(hl)
+ or a
+ jr z,nokeypressed
+
+ ld (ix),a
+ cal _putc
+ inc ix
+ cal waitnokeypressed
+ jr enter_name_loop
+
+backup:
+ ld hl,hiscorepos
+ ld a,(hl)
+ cp 9
+ jr nc,nokeypressed
+ inc (hl)
+
+ dec ix
+ ld (ix),' '
+ ld a,32
+ cal _putc
+ ld hl,_curCol
+ dec (hl)
+ dec (hl)
+ jr enter_name_loop
+
+nomore:
+ ld a,' '
+ cal _putc
+ ld (ix),0
+ cal save_hi
+ jr hiscoredone
+
+no_hiscore:
+ ld hl,hiname
+ cal _puts
+
+hiscoredone:
+ xor a ;clear a (Ahl will be displayed)
+ ld hl,$1006 ;bottom-1 right
+ ld (_curRow),hl ;set
+ ld hl,(score) ;your score
+ cal _dispahl ;display it (a=0)
+
+ ld hl,$314b ;bottom-1 right before score ^^
+ ld (_penCol),hl ;set
+ ld hl,txt_score ;"Score"
+ cal _vputs ;display (small)
+
+ ld hl,$1007 ;bottom right
+ ld (_curRow),hl ;set
+ ld hl,(hiscore) ;hi-score
+ cal _dispahl ;display
+ ld hl,$3946 ;bottom right before hiscore ^^
+ ld (_penCol),hl ;set
+ ld hl,txt_hiscore ;"Hiscore"
+ cal _vputs ;display (small)
+ res 3,(iy+5)
+
+ ld b,16
+ ld de,16
+ ld hl,VIDEO_MEM+(49*16)-1
+restore_line:
+ set 1,(hl)
+ add hl,de
+ dnz restore_line
+
+ cal _getkey ;wait for keypress
+ jp quit ;restore some things and return to TI-OS/shell
+
+Continue_game:
+ jr nonext_level
+
+New_game:
+ xor a ;ld a,0
+ ld (score),a ;reset score
+ ld (score+1),a ;reset score (0)
+ ld (torp_occ),a ;no torpedoes
+ ld (your_weapon),a ;no laser
+ ld (your_pickup),a ;reset pickups
+ ld (your_multiples),a ;no multiples
+ inc a ;ld a,1
+ ld (level),a ;reset level nr (#1)
+ ld hl,XLlevelsdata ;set level pointer to level#1
+ ld (levelp),hl ;reset level pointer
+ inc a ;ld a,2
+ ld (your_weapon),a ;default weapon
+ ld a,4
+ ld (your_lives),a ;3 lives (4 will be decreased @ You_die)
+ ld (pickuptimer),a ;next pickup after 4 enemies destroyed
+
+ xor a
+ cp (hl)
+ cal z,dostory
+
+You_die:
+ ld a,12
+ ld (your_armor),a ;5 HPs/shields
+ ld hl,your_lives
+ dec (hl) ;decrease lives
+ ld a,(hl) ;load lives left
+ inc a ;if lives=0ffh then a=0
+ jp z,game_over ;if so, game's over
+ jr nonext_level