version 0.93 (public): (hi)score, better pickup/multiple movement
[nemesis.git] / nemesis.z80
1         .include "asm86.h"
2         .include "ti86asm.inc"
3         .include "ram86.inc"
4         .include "ti86abs.inc"
5
6         .org _asm_exec_ram
7
8 TEXT_MEM = _textShadow
9 DELC_LEN = _undelBufLen         ;$64 bytes long
10 _dispahl = $4a33
11
12          nop
13          jp init
14         .dw $0001               ;description type 2 (= +YASicon)
15         .dw Title               ;pointer to description
16         .dw spr_ship            ;pointer to YAS icon
17
18 Title:  .db "Nemesis v0.93.911 by Shiar",0
19
20 just_fired      = TEXT_MEM      ;byte
21 temp1           = TEXT_MEM+1    ;word
22 RanPos          = TEXT_MEM+3    ;byte
23 firex           = TEXT_MEM+4    ;byte
24 firey           = firex+1       ;byte
25 mx              = TEXT_MEM+6    ;byte
26 my              = mx+1          ;byte
27 your_locpos     = TEXT_MEM+8    ;byte
28 your_prevpos    = TEXT_MEM+9    ;16 words
29
30 nrybullets      = 20
31 ybullets        = your_prevpos+32                       ;20 x (state,x,y)
32 nrebullets      = 10
33 ebullets        = ybullets+(nrybullets*3)               ;10 x (state,x,y)
34
35 nrenemies       = 10
36 enemies         = DELC_LEN
37         ; %111111 (HP left) 11 (00=no enemy 01=exploding 10=normal 11=moving)
38         ; %11111111 (ship type or explosion frame)  %11111111 (x) %11111111 (y)
39 add2enemy       = nrenemies*4
40 enemiesxtra     = enemies+add2enemy
41         ; $11 (move) $11 (fire)
42
43 ;---------------------- init --------------------------------------------------
44
45 init:
46         call _runindicoff       ;turn the run-indicator off, obviously
47         call _clrLCD            ;clean the screen
48         ld  (iy+13),0
49         xor a
50         ld  (DELC_LEN),a
51
52         ld  a,(CONTRAST)        ;load current contrast level
53         cp  $1f                 ;if already at maximum...
54         jr  z,skipdarken        ;...then skip level increase
55         inc a                   ;otherwise increase contrast level
56 skipdarken:
57         out (2),a               ;set it
58
59 ;---------------------- main menu ---------------------------------------------
60
61 LogoPut:
62         ld hl,logo_nemesis      ;from...
63         ld de,VIDEO_MEM+16      ;...to one line from top
64         ld a,19                 ;19 rows
65 LogoLoop:
66         ld bc,16                ;set screen width
67         ldir                    ;display one line
68         dec a                   ;decrease line-counter
69         jr nz,LogoLoop          ;repeat when counter is not yet zero
70
71         ld  hl,VIDEO_MEM+(16*$39)+4     ;$39 rows down, 4 cols right (4*8=$20)
72         ld  b,$8                ;draw 8x one byte = 8*8 = 64 pixels wide
73         ld  a,%11111111         ;horizontal line mask
74 underline:
75         ld  (hl),a              ;draw one piece of the divider-line
76         inc hl                  ;move right (8 pixels = 1 byte)
77         djnz underline          ;repeat (16bytes * 8pixels =128= screen width)
78
79         set 3,(iy+5)
80         ld  hl,$3320            ;near the bottom of the screen
81         ld  (_penCol),hl
82         ld  hl,txt_about        ;display version and author (yes, that's me!)
83         call _vputs
84         res 3,(iy+5)
85
86         ld  hl,$3a1e            ;below previous stuff
87         ld  (_penCol),hl
88         ld  hl,txt_email        ;hey, my e-mail address so SEND ME SOMETHING!!
89         call _vputs             ;VERY important, so display in small font ?:}
90
91         call _getkey            ;wait for keypress
92         call New_game           ;prepare level
93
94 ;------------------------------------------------------------------------------
95 ;---------------------- game loop ---------------------------------------------
96 ;------------------------------------------------------------------------------
97
98 game_main_loop:                 ;REPEATS FROM HERE EVERY FRAME
99         ld  hl,timer            ;update time
100         inc (hl)                ;increase by 1
101         ld  b,(hl)              ;new time, save for rand# upd. (no flag change)
102         jr  nz,updaterandom     ;continue when new time <> 0
103         ld  hl,1                ;once every 256 frames, increase score by 1
104         call scoreInc           ;do it
105
106 updaterandom:
107         ld  hl,RanPos           ;random counter
108         ld  a,(hl)              ;random value
109         add a,b                 ;even more random by adding timer
110 .db     $80+7                   ;<add a,r>
111         ld  (hl),a              ;save even more random value back
112
113 Clear_screen:
114         ld  hl,GRAPH_MEM        ;move from (hl) = top left
115         ld  (hl),$00            ;first pixel will be copied all over the screen
116         ld  de,GRAPH_MEM+1      ;(de) = next pixel, thus clearing whole screen
117         ld  bc,896              ;loop 896 times = (128/8) * (64-8 for scorebar)
118         ldir                    ;clear!
119
120 check_keys:
121         ld  a,%00111111         ;function keys (MORE,EXIT,2ND,F1,F2,F3,F4,F5)
122         out (1),a               ;ask for them
123         nop \ nop               ;delay 8 clocks
124         in  a,(1)               ;get zem!
125
126 check_exitkey:
127         bit 6,a                 ;test bit 6 = exit-key = EXIT
128         jp  z,game_over_nopop   ;<exit> pressed, so be it
129 check_morekey:
130         bit 7,a                 ;test bit 7 = more-key = PAUSE
131         call z,Pause            ;yes, go to pause
132
133 check_firekey:
134         bit 5,a                 ;test bit 5 = 2nd-key = FIRE
135         ld  hl,game_stuff       ;where to continue after executing Fire_bullet
136         push hl                 ;push hl on stack (instead of call Fire_bullet)
137         jp  z,Fire_bullet       ;fire smtn (bulletstorplasersmultiples+stuff..)
138         pop hl                  ;no call to Fire_bullet made, so pop stack
139         ld  hl,just_fired       ;no:
140         ld  (hl),0              ;reset just_fired
141
142 game_stuff:
143         call Level_event        ;insert enemies
144         call Handle_Ship        ;move you
145         call Handle_enemies     ;move enemies
146
147         ld  a,(your_occ)        ;are you 100% OK?
148         or  a                   ;a=0??
149         jr  nz,activesdone      ;then don't check for movements/fires/...
150
151         ld  a,%01011111         ;look at first column of keys (ALPHA to STO)
152         out (1),a               ;gimme gimme
153         nop \ nop               ;what's taking you so long
154         in  a,(1)               ;at last... our precious keyzzz...
155                                 ;old: <bit 7,a \ call z,select> now see this:
156         rla                     ;test bit 7 so we know f ALPHA has been pressed
157         call nc,select          ;yeppy, select the currently selected upgrade
158         call Enemies_hit        ;check for collision with enemies
159
160 activesdone:
161         call Handle_bullets     ;move your bullets
162         call Handle_torp        ;move your torpedo
163         call Enemy_bullets      ;move enemy bullets
164
165         call Display_Screen     ;display all
166         halt                    ;delay
167
168         jr   game_main_loop     ;LOOP
169
170 ;--------------------------- pause --------------------------------------------
171
172 Pause:
173         ld  hl,$0200            ;top left
174         ld  (_curRow),hl
175         ld  hl,txt_pressenter   ;"Enter to continue"
176         call _puts              ;display message
177 pause:
178         call _getkey            ;enter low-power mode and wait for key
179         cp  kEnter              ;keypressed = enter?
180         jr  nz,pause            ;no, wait some more
181         ret                     ;continue
182
183 ;--------------------------- exit ---------------------------------------------
184
185 quit:
186         call _clrLCD            ;clears screen
187         call _homeup            ;set cursor to top-left
188         ld  a,(CONTRAST)        ;load original contrast level
189         out (2),a               ;and set it back
190         ld  (iy+13),6           ;restore system-flags
191         ret                     ;quit Nemesis :(
192
193 ;--------------------------- display ------------------------------------------
194
195 Display_Screen:
196         ld  hl,GRAPH_MEM        ;from storage (top left)
197         ld  de,VIDEO_MEM        ;to screen (top left)
198         ld  a,56                ;display height = 64 bytes (minus 8 for bar)
199 displayloop:
200         ld  bc,16               ;display width = 16 bytes (16*8bits=256pixels)
201         ldir                    ;16x de >> hl
202         dec a                   ;next line
203         jr  nz,displayloop      ;loop 64x
204
205         ld  hl,$396b            ;Display Score
206         ld  (_penCol),hl        ;bottom right of screen
207         ld  hl,(score)
208
209 _D_HL_DECI:             ;------- display 5-digit value -------
210         ld   de,savestr+4       ;savenr saves number string
211         ld   b,5                ;five digits
212 ldhld:  call UNPACK_HL          ;one digit of hl
213         add  a,'0'              ;make number
214         ld   (de),a             ;save into savenr
215         dec  de                 ;point to next digit
216         djnz ldhld              ;repeat for all digits
217
218         ld   hl,savestr
219         call _vputs             ;display string
220         ret
221
222 savestr:
223         .db "00000",0
224
225 ;------------------------- handle ship ----------------------------------------
226
227 Handle_Ship:
228         ld  a,(your_occ)
229         or  a
230         jr  z,ok                ;0 = normal stat
231
232         inc a                   ;next (explosion)frame
233         ld  (your_occ),a        ;save
234
235         cp  34                  ;last explosion frame?
236         jp  c,exploding_you     ;not yet: display explosion
237         cp  40                  ;delay finished?
238         jp  z,You_die           ;yes = game over
239         ret                     ;don't display anything
240
241 ok:
242         ld  a,%01111110
243         out (1),a
244         ld  hl,y                ;instead of nop\nop do something usefull
245         in  a,(1)
246
247         ld  b,a                 ;push a (keys)
248         xor %11111111           ;inverted a = 0 if arrow-key has been pressed
249         ld  a,(your_multiples)
250         jr  z,no_adv            ;if so, leave the multiples where they are
251         or  %100                ;set move bit
252         jr  adv_ok
253 no_adv:
254         and %11111011           ;reset move bit
255 adv_ok:
256         ld  (your_multiples),a
257         ld  a,b                 ;pop a (keys)
258
259         rra                     ;rotate right (put last bit in c)
260         ld  b,a                 ;we need a
261
262         jr  c,no_down
263         ld  a,(hl)
264         cp  49                  ;55-6 = bottom of screen
265         jr  z,no_down
266         inc a
267         ld  (hl),a
268 no_down:
269         dec hl
270         rr  b                   ;because we now use b, it's rr instead of rra
271         jr  c,no_left
272         ld  a,(hl)
273         sub 1                   ;<dec a> doesn't affect c-flag
274         jr  c,no_left           ;-1 = left side
275         ld  (hl),a
276 no_left:
277         rr  b   
278         jr  c,no_right
279         ld  a,(hl)
280         cp  121                 ;127-6 = right side
281         jr  z,no_right
282         inc a
283         ld  (hl),a
284 no_right:
285         ld  d,(hl)
286         inc hl
287         rr  b
288         jr  c,no_up
289         ld  a,(hl)
290         sub 1                   ;<dec a> doesn't affect carry-flag
291         jr  c,no_up             ;-1 = top of screen
292         ld  (hl),a              ;save new y
293
294 no_up:  ld  e,(hl)
295         ld  ix,spr_ship01       ;ship sprite
296         ld  hl,your_inv         ;invulnerable?
297         ld  a,(hl)              ;load time in a
298         or  a                   ;is it 0?
299         jr  z,handle_multiples  ;yes so ship = normal (display \ continue)
300
301         ld  b,a                 ;save inv-time
302         ld  a,(timer)           ;load frame nr.
303         and %00000011           ;a=0 once every four frames
304         jr  nz,not_time         ;a<>0 = not time to update counter
305         dec (hl)                ;decrease inv-time left
306 not_time:
307         and %00000010           ;a switches 0<->1 every 2 frames
308         jr  z,no_flicker        ;don't show normal sprite anyway
309         ld  a,b                 ;pop inv-time
310         and %11110000           ;inv-time <16 ticks left?
311         jr  z,handle_multiples  ;yes: display normal sprite and continue
312
313 no_flicker:
314         ld  ix,spr_ship01i      ;display inv-ship (ld ix is faster than add ix)
315
316 handle_multiples:
317         call putsprite          ;display your ship
318
319         ld  a,(your_multiples)  ;do you have multiples
320         ld  b,a                 ;save a for 2nd check
321         and %11                 ;no? (last two bits = nr of multiples)
322         ret z                   ;then don't handle them either
323
324         ld  hl,y
325         ld  a,b                 ;restore a (your_multiples)
326         and %100                ;move the multiples???
327         jr  z,mult_adv          ;nope, just let them (saves (y) in y, (x) in x)
328
329         ld  hl,your_locpos      ;location to save this position
330         ld  a,(hl)              ;load a
331         inc a                   ;a=a+1
332         and %00001111           ;if a>15 then a=a-16
333         ld  (hl),a              ;save new a
334         add a,a                 ;a=a*2
335         ld  c,a                 ;bc=2a
336         ld  b,0
337
338         ld  hl,your_prevpos     ;previous positions
339         add hl,bc               ;16 turns ago
340         ld  d,(hl)              ;old x-pos
341         inc hl                  ;and
342         ld  e,(hl)              ;old y-pos
343         ld  (mx),de             ;save multiple position in (mx)
344
345         ld  a,(y)               ;load new y-pos
346         ld  (hl),a              ;save it for 16 turns in the future
347         dec hl                  ;and
348         ld  a,(x)               ;load new x-pos
349         ld  (hl),a              ;save that too
350
351 mult_adv:
352  ld de,(mx)
353         ld  ix,spr_multiple     ;sprite of the multiple
354         jp  putsprite           ;display it + <ret>
355
356 exploding_you:
357         srl a                   ;half the framerate
358         dec a                   ;first frame is 1>inc>srl>dec = 0
359         ld  hl,x-1
360
361 explosion_stuff:
362         rra
363         add a,a
364         add a,a
365         add a,a
366         ld  c,a
367         ld  b,0
368         ld  ix,spr_explosion
369         add ix,bc
370         inc hl
371         ld  d,(hl)
372         inc hl
373         ld  e,(hl)
374         jp  putsprite
375
376 damage_you:
377         ld  a,(your_inv)        ;invulnerability left?
378         or  a
379         ret nz                  ;return if inv>0
380         ld  hl,your_armor       ;armor left
381         ld  a,(hl)              ;check
382         dec a                   ;is it 0?
383         jp  m,no_armor          ;yes, 0hp left so explode
384         ld  (hl),a              ;no, so save decreased hp
385         call disp_armor         ;and display new value
386         ret                     ;and return
387 no_armor:
388         ld  a,%01               ;occ %xxxxxx01 = explode
389         ld  (your_occ),a        ;set to explode
390         ret
391
392 ;------------------------- place multiples ------------------------------------
393
394 Place_multiples
395         ld  (mx),de             ;set last multiple-position
396         ld  hl,your_prevpos     ;place all previous positions
397         ld  b,16                ;all 16 of them
398 place_multiples:
399         ld  (hl),d              ;set prev-x to d
400         inc hl                  ;next
401         ld  (hl),e              ;set prev-y to e
402         inc hl                  ;next
403         djnz place_multiples    ;repeat
404         ret
405
406 ;------------------------- select upgrade -------------------------------------
407
408 select:
409         ld  hl,your_pickup      ;select pickups
410         ld  a,(hl)              ;load pickups taken so far
411         dec a                   ;is it 1?
412         jr  nz,select2          ;no, carry on
413         ld  (hl),a              ;reset pickups (a=0)
414         ld  hl,your_armor       ;change armor
415         inc (hl)                ;increase HPs by one
416         jp  disp_icons          ;display and return
417 select2:
418         dec a                   ;is it 2?
419         jr  nz,select3          ;no, carry on
420         ld  (hl),a              ;reset pickups
421         inc a                   ;a=1
422         ld  (torp_occ),a        ;ready torpedoes
423         jp  disp_icons          ;display 'n return
424 select3:
425         dec a                   ;is it 3?
426         jr  nz,select4          ;no, carry on
427         ld  (hl),a              ;reset pickups
428         jp  disp_icons          ;display n return
429 select4:
430         dec a                   ;is it 4?
431         jr  nz,select5          ;no, carry on again
432         ld  (hl),a              ;reset pickups
433         inc a                   ;a=1
434         ld  (your_laser),a      ;ready laser
435         jp  disp_icons          ;display + return
436 select5:
437         dec a                   ;is it 5?
438         jr  nz,select6          ;no, carry on once more
439         ld  (hl),a              ;reset pickups
440         inc a
441         ld  (your_multiples),a
442         ld  de,(x)
443         call Place_multiples
444         jp  disp_icons          ;display, return
445 select6:
446         ld  (hl),0              ;reset pickups
447         jp  disp_icons          ;display/return
448
449 ;------------------------- fire bullet ----------------------------------------
450
451 Fire_bullet:
452         ld  hl,RanPos           ;random
453         inc (hl)                ;update random counter
454
455         ld  hl,just_fired
456         ld  a,(hl)              ;just_fired
457         cp  5                   ;already pressed?
458         ret z                   ;return when already pressed (=5)
459         inc (hl)                ;otherwise increase counter (0 to 4 >> 1 to 5)
460         ld  a,(your_laser)      ;if you have bullets.....
461         or  a                   ;(0=no laser)
462         jr  nz,fireOK
463         ld  (hl),5              ;.....then can't fire next turn (go to 5 imm.)
464
465 fireOK:
466         ld  hl,(x)              ;yes: first fire from ship position (x)
467         ld  (firex),hl          ;set firepos
468         ld  a,(your_multiples)  ;any multiples?
469         and %11                 ;nope?
470         jr  z,fireany           ;then just fire somethin'
471         call fireany            ;and blast
472         ld  hl,(my)             ;then, fire from multiple position (mx)
473         ld  a,(mx)              ;<ex h,l>
474         ld  h,a                 ; ^^^^^^
475         ld  (firex),hl          ;set firepos
476                                 ;blast again and <ret>
477 fireany:
478         ld  a,(your_laser)      ;do you have laser?
479         dec a                   ;1=yes
480         jr  nz,fire_ybullet     ;no, just fire a bullet
481
482 fire_laser:                     ;yes, fire that laser instead
483         ld  a,(firex)           ;a = your x-pos
484         ld  d,a
485
486         ld  hl,GRAPH_MEM        ;save-location
487         ld  a,(firey)           ;y-coord
488         add a,3                 ;at middle of your ship (y+3)
489         ld  e,a                 ;save laser-y in e
490         add a,a                 ;y*2
491         add a,a                 ;y*4
492         add a,a                 ;y*8
493         rl  b                   ;b (=0) =b*2+overflow (if y>32 then bc=bc+256)
494         add a,a                 ;y*16 (width of screen)
495         rl  b                   ;b=b*2+overflow (if y>64 then bc=bc+512)
496         inc a                   ;8 pixels to right (a=even so no overflow)
497
498         srl d                   ;X/2
499         srl d                   ;X/4
500         srl d                   ;X/8
501         add a,d                 ;a = (Y*16+X/8) mod 256 (c set on overflow)
502         jr  nc,_nolc            ;jump if no carry = no overflow = a<=255
503         inc b                   ;a>255 so increase bc by 256
504 _nolc:  ld  c,a                 ;c = (Y*16+X/8) mod 256
505         add hl,bc               ;bc = Y*16+X/8
506           
507         ld  a,15                ;128/8=16=screen width ** minus one (inc a ^^)
508         sub d                   ;minus x-start (d=X/8)
509         ld  b,a
510         ld  c,0
511 drawlaser:
512         ld  (hl),%11111111
513         inc hl                  ;Go to next byte
514         djnz drawlaser
515
516 handle_laser:
517         ld  a,(firex)
518         ld  d,a                 ;d was divided, so reload the laser-x
519
520 check_laserhits:                ;de = (x,y)
521         ld  ix,nolashit
522         ld  b,nrenemies
523         ld  hl,enemies
524
525 laserhits:                      ;Hits with normal enemies
526         push hl
527
528         ld  a,(hl)
529         and %00000010
530         jr  z,nolashit          ;no hit when enemy_occ <> 2/3
531
532         inc hl                  ;enemy type
533         ld  a,(hl)
534         or  a                   ;enemy #0 = pickup
535         jr  z,nolashit          ;yes: don't destroy
536
537         inc hl
538         ld  a,(hl)              ;check x
539         sub d
540         jp  m,nolashit          ;no hit when enemy is left of you
541
542         inc hl
543         ld  a,(hl)              ;check y
544         sub e
545         jp  z,enemy_hit         ;a-e=0 = laser on top line of enemy = hit
546         jr  nc,nolashit         ;a-e>0 = enemy above laser = no hit
547         add a,5                 ;add enemy height
548         jp  p,enemy_hit         ;a-e>0 = hit
549
550 nolashit:
551         pop hl
552         inc hl                  ;go to next enemy
553         inc hl
554         inc hl
555         inc hl
556         djnz laserhits          ;check all enemies
557
558         ld  a,d                 ;<ex d,e>
559         ld  d,e
560         ld  e,a
561         jr  fire_torp           ;fire torpedoes as well
562
563 fire_ybullet:
564         ld  hl,ybullets
565         ld  de,3
566         ld  b,nrybullets
567 find_ybullet:
568         ld  a,(hl)
569         or  a
570         jr  z,found_ybullet     ;0 = no bullet here
571         add hl,de
572         djnz find_ybullet       ;look next bullet
573         ret
574
575 found_ybullet:
576         ld  (hl),1              ;use bullet
577         ld  a,(firex)           ;your x-pos
578         add a,5                 ;place bullet in front of you
579         inc hl                  ;go to bullet-x
580         ld  (hl),a              ;set x
581         ld  e,a                 ;save torp-x in e
582
583         ld  a,(firey)           ;your y-pos
584         add a,2                 ;place bullet at the middle of your ship
585         inc hl                  ;go to bullet-y
586         ld  (hl),a              ;set y
587         add a,3                 ;place torpedo at bottom of ship
588         ld  d,a                 ;save torp-y in d
589
590 fire_torp:
591         ld  hl,torp_occ         ;torpedo...
592         ld  a,(hl)              ;load torpInfo
593         dec a                   ;do you have (unused) torpedoes?
594         ret nz                  ;nope (a must be 1)
595         ld  (hl),2              ;yes; use torpedo
596         ld  (torp_pos),de       ;save torpedo position (in de)
597         ret
598
599 ;------------------------ handle bullets --------------------------------------
600
601 remove_bullet:
602         dec hl
603         ld  (hl),0              ;dump this bullet!
604         ret
605
606 Handle_bullets:
607         ld  hl,ybullets
608         ld  b,nrybullets
609 scan_bullets:
610         push bc
611         push hl
612         ld  (temp1),hl
613         ld  a,(hl)
614         inc hl
615         dec a                   ;type 1?
616         call z,bullet_2left     ;yes: 2left
617         pop hl
618         pop bc
619         ld  de,3
620         add hl,de               ;3 x <inc hl>
621         djnz scan_bullets       ;next bullet (loop)
622         ret
623
624 bullet_2left:
625         ld  a,(hl)              ;d = X
626         cp  122                 ;off screen? (x>128-5)
627         jr  nc,remove_bullet
628         add a,2                 ;move 2 2 the right
629         ld  (hl),a              ;save new pos.
630         ld  d,a
631
632         inc hl                  ;to y-pos
633         ld  e,(hl)              ;e = Y
634
635         ld  ix,spr_bullet01
636         push de
637         call putsprite          ;display bullet
638         pop de
639
640 check_bullethits:               ;INPUT: de=X,Y
641         ld  b,nrenemies
642         ld  hl,enemies
643         ld  ix,nohit
644
645 hit_enemies:                    ;Hits with normal enemies
646         push hl
647
648         ld  a,(hl)
649         and %00000010
650         jr  z,nohit             ;no hit when enemy_occ <> 2/3
651
652         inc hl                  ;enemy type
653         ld  a,(hl)
654         or  a                   ;enemy #0 = pickup
655         jr  z,nohit             ;yes: don't destroy
656
657         inc hl
658         ld  a,(hl)              ;check x
659         sub d
660         add a,5
661         jp  m,nohit
662         cp  8
663         jr  nc,nohit
664
665         inc hl
666         ld  a,(hl)              ;check y
667         sub e
668         add a,5
669         jp  m,nohit
670         cp  10
671         jr  nc,nohit
672
673         push hl
674         ld  hl,(temp1)
675         ld  (hl),$00            ;remove bullet
676         pop hl
677
678 enemy_hit:
679         dec hl
680         dec hl
681         dec hl
682         ld  a,(hl)              ;occ
683         ld  c,a                 ;push occ
684         and %11111100           ;occ/4 = HP left        ;<srl a\srl a
685         jr  nz,hpleft           ;not zero -> jump
686         ld  (hl),%01            ;set to explode
687
688         ld  a,(pickuptimer)     ;counts enemies destroyed
689         dec a                   ;enough destroyed for a pickup?
690         jr  nz,pickupdone       ;otherwise just explode
691         ld  (hl),%00000110      ;change it into a pickup (with 2 HP)
692         ld  a,18                ;reset enemies counter (18 hits = next)
693 pickupdone:
694         ld  (pickuptimer),a     ;save new enemiescounter value
695         inc hl
696         ld  (hl),$00            ;explosionFrame 0
697
698         ld  hl,1                ;increase score by one
699         call scoreInc
700         jp  (ix)
701
702 hpleft:
703         ld  a,c                 ;pop occ
704         sub %00000100           ;decrease HP by one
705         ld  (hl),a              ;save
706         jp  (ix)
707
708 nohit:
709         pop hl
710         inc hl
711         inc hl
712         inc hl
713         inc hl
714         djnz hit_enemies        ;check next enemy
715         ret
716
717 ;--------------------------- handle torpedo -----------------------------------
718
719 Handle_torp:
720         ld  a,(torp_occ)
721         sub 2
722         ret m                   ;return if occ=0/1
723
724         ld  hl,torp_pos         ;x-position
725         ld  a,(hl)              ;load in a
726         inc a                   ;move right
727         cp  125                 ;right edge reached
728         jr  nc,remove_torp      ;remove if x>125
729         ld  (hl),a              ;save new x
730         ld  d,a
731
732         inc hl                  ;y-position
733         ld  a,(hl)
734         inc a                   ;move down
735         cp  56                  ;bottom reached
736         jr  nc,remove_torp      ;remove if y>40
737         ld  (hl),a              ;save new y
738         ld  e,a
739
740         ld  ix,spr_bullett1
741         push de
742         call putsprite          ;display torpedo
743         pop de
744         jp  check_bullethits    ;check for hits with enemies
745
746 remove_torp:
747         ld  a,1
748         ld  (torp_occ),a
749         ret
750
751 ;--------------------------- level events -------------------------------------
752
753 Level_event:
754         ld  hl,nextevent        ;time to next event     <ld  a,(nextevent)
755         dec (hl)                ;decrease counter       <dec a
756         ld  a,(hl)              ;look at counter        <ld  (nextevent),a
757         or  a                   ;has it reached zero?
758         ret nz                  ;nope: get outta here!
759
760         ld  a,(eventtime)       ;enemy frequency (lvl)
761         ld  (nextevent),a       ;set time to next event
762         ld  hl,eventleft
763         dec (hl)                ;update enemy-counter
764
765         ld  a,(hl)              ;look at counter
766         or  a                   ;has it reached 0?
767         jp  z,Next_level        ;yes: level finished
768         dec a                   ;has it reached 1?
769         jr  nz,do_event         ;nope: wait for enemies to leave
770         inc hl                  ;nextevent located behind eventleft
771         ld  (hl),119            ;set delay
772         ret                     ;don't place any more enemies
773
774 do_event:
775         ld  de,enemies-4
776 chk_noenemy:
777         inc de
778         inc de
779         inc de
780         inc de
781         ld  a,(de)
782         or  a                   ;0 = no enemy present
783         jr  nz,chk_noenemy
784
785 place_enemy:
786         ld  a,(eventenemy)      ;enemy type to place (lvl)
787         ld  hl,enemy00          ;enemy 1 specs
788         add a,a                 ;a=type*2
789         add a,a                 ;a=type*4
790         ld  c,a                 ;c=type
791         ld  b,0                 ;bc = enemy nr.
792         add hl,bc               ;hl = enemy specs
793         ld  a,(hl)              ;load hitpoints+occ of this enemy class
794         ld  (de),a              ;occ
795
796         inc hl                  ;next enemyInfo byte
797         inc de                  ;next byte of current enemy
798         ld  a,(hl)              ;load movement+type of this enemy class
799         ld  (de),a              ;enemy type
800
801         inc de                  ;set x-pos
802         ld  a,122               ;appear at right edge of screen (128-6)
803         ld  (de),a              ;= x-position
804
805         inc de                  ;set y-pos
806         inc hl                  ;where to place??
807         ld  a,(hl)              ;load placeInfo
808         dec a                   ;is it 1?
809         jr  z,random_enemy      ;yes: create random value <51 in a
810         dec a                   ;is it 2?
811         jr  z,lure_enemy        ;yes: create a 100% luring enemy
812                                 ;otherwise?
813 halflure_enemy:                 ;yes (of course it is): pick one (50% lure)
814         ld  a,(timer)           ;look at frame-number
815         and %00000001           ;make random if odd frame nr.
816         jr  nz,random_enemy     ;1st possibility: random enemy
817 lure_enemy:                     ;2nd possibility: luring enemy
818         ld  a,(y)               ;place at same y-pos as YOUR ship
819         jr  ypos_OK
820
821 random_enemy:
822         call Random             ;make a (in a) random value 0-255
823         cp  51                  ;y may not be more than 51
824         jr  c,ypos_OK           ;OK if a<51
825         and %00111111           ;a = 0..63
826         sub 13                  ;a = -13..50
827         jr  c,random_enemy      ;not OK if a<0
828
829 ypos_OK:                        ;random value successfully created
830         ld  (de),a              ;save y-position
831
832         ld  hl,add2enemy-3      ;offset to xtra enemy info
833         add hl,de               ;hl points to <xtra info: move>
834         ld  (hl),1              ;set move-counter to 1
835         inc hl                  ;hl to <xtra info: fire>
836         ld  (hl),1              ;set time-to-fire to 1 frame (fires directly)
837         ret                     ;return
838
839 Random:
840         ld  a,(RanPos)          ;a handy random-var.
841         ld  hl,x                ;add your x-coord for randomness
842         adc a,(hl)
843         ld  hl,y                ;add your y-coord for randomness
844         adc a,(hl)
845         ld  (RanPos),a          ;save altered random-var
846         ret                     ;RanPos also in #a
847
848 ;--------------------------- enemy fires --------------------------------------
849
850 Enemy_fires:                    ;de = x,y
851         push de
852         dec d
853         dec d                   ;d = x-2
854         inc e                   ;e = y+1
855
856         ld  b,nrebullets
857         ld  hl,ebullets
858 find_ebullet:
859         ld  a,(hl)
860         or  a
861         jr  z,found_ebullet     ;0 = not used
862         inc hl \ inc hl \ inc hl
863         djnz find_ebullet       ;look next bullet
864         ret
865
866 found_ebullet:
867         ld  (hl),1              ;use bullet &&&
868         inc hl
869         ld  (hl),d              ;set x-pos
870         inc hl
871         ld  (hl),e              ;set y-pos
872         pop de
873         ret         
874
875 ;----------------------------- enemy bullets ----------------------------------
876
877 Enemy_bullets:
878         ld  hl,ebullets
879         ld  b,nrebullets
880 handle_bullet:
881         push bc
882         push hl
883         ld  a,(hl)              ;load bulletType in a
884         or  a                   ;is it 0?
885         jr  nz,enemy_bullet     ;no: handle bullet
886 next_bullet:
887         pop hl                  ;do not move the <pop hl>
888         pop bc
889         inc hl \ inc hl \ inc hl
890         djnz handle_bullet
891         ret
892
893 enemy_bullet:
894         ld  b,a                 ;save type
895         inc hl                  ;bullet x
896         ld  a,(hl)              ;check if it has reached the left side of scrn
897         and %11111110           ;it is <2 (0 or 1)?
898         jr  z,remove_ebullet    ;yes, remove bullet
899         dec (hl)                ;move one left
900         dec (hl)                ;and another one
901         ld  d,(hl)              ;d=x
902         inc hl                  ;@y
903
904         ld  a,b                 ;restore type
905         dec a                   ;type 1?
906         jr  z,ebullet_common    ;normal bullet
907
908 ebullet_down:
909         ld  a,(timer)
910         rra
911         jr  c,ebullet_common
912         inc (hl)
913
914 ebullet_common:
915         ld  e,(hl)              ;e=y
916         ld  ix,spr_bullete1     ;display enemy bullet
917         call putsprite
918
919 ebullet_hits:
920         ld  a,(your_occ)
921         or  a
922         jr  nz,next_bullet      ;0 = you're normal
923
924         pop hl
925         push hl
926         inc hl                  ;check x
927         ld  a,(x)
928         sub (hl)
929         add a,6
930         jp  m,next_bullet
931         cp  9
932         jr  nc,next_bullet
933
934         inc hl                  ;check y
935         ld  a,(y)
936         sub (hl)
937         add a,6
938         jp  m,next_bullet
939         cp  9
940         jr  nc,next_bullet
941
942         call damage_you         ;HIT!!
943 remove_ebullet:
944         pop hl                  ;hl could be destroyed by damage_you
945         ld  (hl),0              ;bullet > unused
946         jr  next_bullet+1       ;next bullet (SKIP THE <POP HL> = one byte)
947
948 ;--------------------------- handle enemies -----------------------------------
949
950 Handle_enemies:
951         ld  hl,enemies
952         ld  b,nrenemies         ;handle all enemies
953
954 handle_enemy:
955         push bc
956         push hl
957
958         ld  a,(hl)
959         and %00000011
960         jr  z,next_enemy        ;occ "no enemy" 0
961         dec a
962         jr  z,exploding_enemy   ;occ "exploding" 1
963         ld  b,a                 ;b=2 if moving, otherwise b=1
964
965 normal_enemy:                   ;occ "normal" 2 or "moving" 3
966         inc hl
967         push hl
968
969         ld  e,(hl)              ;e = enemy type
970         ld  c,e                 ;c = e
971         ld  d,0                 ;de = e
972         ld  hl,sprites          ;hl = @sprites offset-table
973         add hl,de               ;points to offset of current enemy offset
974         ld  e,(hl)              ;de = @enemy offset
975
976         ld  ix,spr_enemy00      ;first enemy sprite
977         add ix,de               ;add offset for current enemy
978         pop hl
979
980         inc hl
981         ld  a,(hl)              ;x
982         dec a                   ;move left
983         jr  c,remove_enemy      ;off screen
984         jr  z,remove_enemy      ;"
985         ld  d,a
986
987         inc hl
988         ld  e,(hl)              ;y
989         ld  a,b                 ;moving state was stored in b earlier
990         dec a                   ;is it 1?
991         call nz,moving_enemy    ;2 = moving enemy
992
993         dec hl                  ;@x
994         ld  (hl),d              ;store new x
995         ld  a,c                 ;a = enemy type
996         or  a                   ;type 0? (pickup)
997         jr  nz,check_enemyfire  ;no, a normal enemy; let em fire
998         ld  a,(timer)           ;load time
999         and %1                  ;move left once every 2 turns
1000         jr  z,firing_done       ;don't move now
1001         inc d                   ;increase x-position (don't move this turn)
1002         inc (hl)                ;and save it
1003         jr  firing_done         ;continue
1004
1005 check_enemyfire:
1006         ld  bc,add2enemy+1-2    ;offset of <xtra enemy info: fire>
1007         add hl,bc               ;go there (@hl)
1008         dec (hl)                ;decrease counter till next blast
1009         ld  a,(hl)              ;load new counter
1010         or  a                   ;has it reached zero?
1011         jr  nz,firing_done      ;finished if not
1012
1013         add a,64                ;re-set counter for next blast
1014         ld  (hl),a              ;save
1015         call Enemy_fires        ;fires bullet
1016
1017 firing_done:
1018         push de                 ;save registers for firing-use
1019         call putsprite          ;display sprite @ix
1020         pop  de                 ;restore (destroyed by putsprite)
1021
1022 next_enemy:
1023         pop hl
1024         ld  bc,$0004
1025         add hl,bc
1026         pop bc
1027         djnz handle_enemy
1028         ret
1029
1030 remove_enemy:
1031         pop hl
1032         ld  (hl),$0000          ;bye bye enemy
1033         push hl
1034         jr  next_enemy
1035
1036 exploding_enemy:
1037         inc  hl
1038         push hl
1039         ld   a,(hl)
1040         call explosion_stuff    ;display explosion
1041         pop  hl
1042
1043         ld  a,(hl)
1044         cp  15
1045         jr  z,remove_enemy      ;remove when at last frame
1046         inc a
1047         ld  (hl),a              ;next frame
1048         jr  next_enemy
1049
1050 ;--------------------------- moving enemies -----------------------------------
1051
1052 moving_enemy:
1053 movetype_updown:
1054         ld  bc,add2enemy
1055         add hl,bc
1056
1057         ld  a,(hl)
1058         dec a
1059         jr  nz,move_updated
1060         add a,128
1061 move_updated:
1062         ld  (hl),a
1063
1064         or  a                   ;reset carry flag
1065         sbc hl,bc
1066         and %00100000
1067         jr  z,movedown
1068
1069 moveup:
1070         ld  a,(hl)              ;load y-position
1071         dec a                   ;decrease y-pos (=move up)
1072         ret m                   ;don't move off the screen (y<0)
1073         ld  (hl),a              ;save new y-pos
1074         ret                     ;finish
1075 movedown:
1076         ld  a,(hl)              ;load current y
1077         inc a                   ;increase y-pos
1078         cp  55                  ;compare with bottom
1079         ret nc                  ;return if it has passed that line (>40)
1080         ld  (hl),a              ;otherwise save new position
1081         ret                     ;and return
1082
1083 ;--------------------------- check collision ----------------------------------
1084
1085 Enemies_hit:
1086         ld  de,(x)              ;e = X, d = Y
1087         ld  hl,enemies
1088         ld  b,nrenemies         ;check all 20 enemies
1089 check_collision:
1090         push hl
1091         ld  a,(hl)
1092         and %00000010
1093         jr  z,check_next        ;2 or 3 = ok
1094         inc hl
1095
1096 collide_enemy:
1097 ;       push hl
1098 ;       push bc
1099 ;       ld  hl,enemy00          ;enemy 1 specs
1100 ;       add a,a                 ;a=type*2
1101 ;       add a,a                 ;a=type*4
1102 ;       ld  c,a                 ;c=type
1103 ;       ld  b,0                 ;bc = 4 * enemy nr.
1104 ;       add hl,bc               ;hl = enemy specs
1105 ;       ld  a,(hl)              ;load size byte
1106 ;       pop bc
1107 ;       pop hl
1108 ;       ld  c,a                 ;save size in c
1109
1110         inc hl
1111         ld  a,(hl)              ;check x match
1112         sub e                   ;enemy position minus yours
1113         add a,6
1114         jp  m,check_next
1115         cp  12
1116         jr  nc,check_next
1117
1118         inc hl
1119         ld  a,(hl)              ;check y match
1120         sub d                   ;same as with x-check
1121         add a,6
1122         jp  m,check_next
1123         cp  12
1124         jr  nc,check_next
1125         dec hl
1126         dec hl
1127
1128 take_pickup:
1129         ld  a,(hl)              ;load enemy type
1130
1131         push hl                 ;we need hl
1132         ld   hl,2               ;increase score by 2
1133         call scoreInc
1134         pop  hl                 ;we're done
1135
1136         or  a
1137         jr  nz,collide          ;enemy when <>0
1138
1139         push hl
1140         ld  hl,your_pickup      ;your pickups
1141         ld  a,(hl)              ;current
1142         inc a                   ;go to next
1143         cp  6                   ;pickups >=6
1144         jr  c,not_maxpickup
1145         ld  a,1                 ;yes: reset to pickup 1
1146 not_maxpickup:
1147         ld  (hl),a              ;save new
1148         call disp_icons         ;display altered pickupicons
1149         pop hl
1150
1151         dec hl                  ;to enemy occ
1152         xor a                   ;set to 0 = gone
1153         ld  (hl),a              ;remove
1154         jr  check_next          ;all done, next..
1155
1156 collide:
1157         xor a
1158         ld  (hl),a              ;explosionFrame 0
1159         dec hl
1160         inc a
1161         ld  (hl),a              ;set to explode
1162         call damage_you         ;auch!
1163
1164 check_next:
1165         pop hl
1166         inc hl
1167         inc hl
1168         inc hl
1169         inc hl
1170         djnz check_collision
1171         ret
1172
1173 ;--------------------------- update score -------------------------------------
1174
1175 scoreInc:
1176         push bc
1177         ld  bc,(score)
1178         add hl,bc
1179         ld  (score),hl
1180         pop bc
1181         ret
1182
1183 ;--------------------------- show icon ----------------------------------------
1184
1185 disp_icons:
1186         ld  hl,VIDEO_MEM+(16*57);57 rows down = seven rows from bottom
1187         ld  b,16*7              ;draw 16x (screen width) 7x (height)
1188         xor a                   ;blank line mask
1189 cleanline:
1190         ld  (hl),a              ;draw one piece of the divider-line
1191         inc hl                  ;move right (8 pixels = 1 byte)
1192         djnz cleanline          ;repeat (16bytes * 7rows * 8pixels)
1193
1194         ld  hl,VIDEO_MEM+(56*16)
1195         ld  (PutWhere),hl
1196
1197         call disp_lives
1198
1199         ld  ix,spr_icon01       ;armorIcon
1200         ld  de,$1901            ;icon #1
1201         call putwidesprite      ;display icon
1202         call disp_armor         ;display value
1203
1204         ld  ix,spr_icon00
1205         ld  a,(torp_occ)
1206         or  a
1207         jr  z,no_torp
1208         ld  ix,spr_icon02       ;torpedoIcon
1209 no_torp:
1210         ld  de,$2901            ;icon #2
1211         call putwidesprite      ;display
1212
1213         ld  ix,spr_icon03       ;emptyIcon
1214         ld  de,$3901            ;icon #3
1215         call putwidesprite
1216
1217         ld  ix,spr_icon00       ;emptyIcon
1218         ld  a,(your_laser)
1219         or  a
1220         jr  z,no_laser
1221         ld  ix,spr_icon04       ;laserIcon
1222 no_laser:
1223         ld  de,$4901            ;icon #4
1224         call putwidesprite
1225
1226         ld  ix,spr_icon00       ;emptyIcon
1227         ld  a,(your_multiples)
1228         and %11
1229         jr  z,no_multiples
1230         ld  ix,spr_icon05
1231 no_multiples:
1232         ld  de,$5901            ;icon #5
1233         call putwidesprite
1234
1235         ld  ix,spr_icon03
1236         ld  de,$6901
1237         call putwidesprite
1238
1239         ld  a,(your_pickup)     ;pickups taken
1240         add a,a                 ;picks*2
1241         ret z                   ;return if no pickups
1242         add a,a                 ;picks*4
1243         add a,a                 ;picks*8
1244         add a,a                 ;picks*$10
1245         add a,$09               ;add 0ah
1246         ld  d,a                 ;y-pos = picks * $10 + $0a (19,29,39,49,59)
1247         ld  e,$01               ;x-pos = bottom (1a01,2a01,3a01,4a01,5a01)
1248
1249         ld  ix,spr_icon
1250         call putwidesprite
1251         ret
1252
1253 disp_armor:
1254         ld  hl,$3925            ;Display Armor left
1255         ld  (_penCol),hl        ;place @ armorIcon
1256         ld  a,(your_armor)      ;load armor left
1257         add a,'0'               ;make digit
1258         call _vputmap           ;display char
1259         ret
1260
1261 disp_lives:
1262         ld  hl,$3900            ;display Lives
1263         ld  (_penCol),hl        ;bottom left
1264         ld  hl,savestr+2
1265         ld  (hl),'L'
1266         inc hl
1267         ld  (hl),'x'
1268         inc hl
1269
1270         ld  a,(lives)           ;nr of lives in a
1271         add a,'0'               ;make digit
1272         ld  (hl),a
1273         dec hl \ dec hl
1274         call _vputs             ;display on screen
1275         ret
1276
1277 ;--------------------------- game over / new game / death ---------------------
1278 own_name:
1279         .db $12,7,"nemesis"
1280
1281 save_hi:
1282         ld   hl,own_name        ; Find own variable
1283         xor  a
1284         call _ABS_MOV10TOOP1
1285         call _FINDSYM
1286         ret  c                  ; If not found, give up
1287
1288         ld  a,b                        ; Save the stored section
1289         ld  h,d
1290         ld  l,e
1291         ld  b,0
1292         ld  de,4+stored_data_start-_asm_exec_ram
1293         add hl,de
1294         adc a,b
1295         call _SET_ABS_DEST_ADDR
1296         ld   a,0
1297         ld   hl,stored_data_start
1298         call _SET_ABS_SRC_ADDR
1299         ld   hl,stored_data_end-stored_data_start
1300         call _SET_MM_NUM_BYTES
1301         call _mm_ldir
1302
1303         ret
1304
1305 game_over:
1306         pop hl                  ;=ret (game_over was called from a procedure)
1307 game_over_nopop:
1308         call _clrLCD            ;clear screen
1309         ld  hl,$0603
1310         ld  (_curRow),hl        ;center
1311         ld  hl,txt_gameover
1312         call _puts              ;display "GAME OVER"
1313
1314         xor  a                  ;clear a (AHL will be displayed)
1315         ld   hl,$1006           ;bottom-1 right
1316         ld   (_curRow),hl       ;set
1317         ld   hl,(score)         ;your score
1318         call _dispahl           ;display it (a=0)
1319         ld  hl,$314b            ;bottom-1 right before score ^^
1320         ld  (_penCol),hl        ;set
1321         ld  hl,txt_score        ;"Score"
1322         call _vputs             ;display (small)
1323
1324         ld   hl,$1007           ;bottom right
1325         ld   (_curRow),hl       ;set
1326         ld   hl,(hiscore)       ;hi-score
1327         call _dispahl           ;display
1328         ld  hl,$3946            ;bottom right before hiscore ^^
1329         ld  (_penCol),hl        ;set
1330         ld  hl,txt_hiscore      ;"Hiscore"
1331         call _vputs             ;display (small)
1332
1333         ld  de,(score)
1334         ld  hl,(hiscore)
1335         call CP_HL_DE
1336         jr  nc,no_hiscore
1337         ld  (hiscore),de
1338
1339 no_hiscore:
1340         call save_hi
1341
1342         ld  b,$20
1343 wait2:  halt \ halt
1344         djnz wait2              ;delay
1345         call _getkey            ;wait for keypress
1346         jp  quit                ;restore some things and return to TI-OS/shell
1347
1348 New_game:
1349         xor a                   ;score 0
1350         ld  (score),a           ;reset score
1351         ld  (score+1),a         ;reset score
1352         inc a                   ;level #1
1353         ld  (level),a           ;reset level nr
1354         ld  hl,level01          ;set level pointer to level#1
1355         ld  (levelp),hl         ;reset level pointer
1356         ld  hl,lives            ;starting lives
1357         ld  (hl),4              ;3 lives (will be decreased @ You_die)
1358
1359 You_die:
1360         ld  hl,lives
1361         dec (hl)                ;decrease lives
1362         ld  a,(hl)              ;load lives left
1363         inc a                   ;if lives=0ffh then a=0
1364         jr  z,game_over         ;if so, game's over
1365
1366         xor a                   ;a=0
1367         ld  (your_armor),a      ;no armor
1368         ld  (torp_occ),a        ;no torpedoes
1369         ld  (your_laser),a      ;no laser
1370         ld  (your_pickup),a     ;reset pickups
1371         ld  (your_multiples),a  ;no multiples
1372         jr  nonext_level
1373
1374 ;--------------------------- next level ---------------------------------------
1375
1376 Next_level:
1377         ld  hl,level            ;level number
1378         ld  a,(hl)
1379         inc a
1380         ld  (hl),a
1381
1382         ld  hl,(levelp)         ;level pointer
1383         inc hl
1384         inc hl
1385         inc hl                  ;update to point to next level
1386         ld  (levelp),hl         ;save
1387
1388         ld  h,0                 ;increase score....
1389         ld  l,a                 ;by level number
1390         ld  bc,20
1391         add hl,bc               ;plus 20
1392         call scoreInc           ;update score
1393
1394 nonext_level:
1395         ld  a,80
1396         ld  (nextevent),a       ;time to first enemy appearance
1397
1398         ld  hl,(levelp)         ;level pointer
1399         ld  a,(hl)              ;load new level-enemy type
1400         ld  (eventenemy),a      ;set level-enemy
1401         inc hl
1402         ld  a,(hl)              ;load new appearance-time
1403         ld  (eventtime),a       ;set
1404         inc hl
1405         ld  a,(hl)              ;load nr of enemies in this level
1406         ld  (eventleft),a       ;set nr of events left
1407
1408         xor a
1409         ld  (timer),a           ;reset time
1410         ld  hl,your_occ         ;hl = your_occ
1411         ld  (hl),a              ;reset your ship (not exploding)
1412         inc hl                  ;hl = your_inv
1413         ld  (hl),50             ;set 50 frames invulnerable
1414         ld  hl,x                ;begin position x=...
1415         ld  (hl),a              ;...=a=0=left
1416         inc hl                  ;y=...
1417         ld  (hl),24             ;...=24=middle
1418
1419         ld  a,(torp_occ)
1420         or  a                   ;no torpedoes?
1421         jr  z,torpsclear        ;then just continue (=0)
1422         ld  a,1                 ;if so, set to "ready to fire" (=1)
1423 torpsclear:
1424
1425         ld  de,$0018            ;x=0, y=24 (like you..)
1426         call Place_multiples    ;place all multiple-positions at (0,24)
1427
1428         ld  hl,ybullets         ;clear your/enemy bullets
1429         ld  (hl),a              ;clear first byte
1430         ld  de,ybullets+1       ;and copy this byte to the next byte
1431         ld  bc,(nrybullets+nrebullets)*3-1      ;bc times (all bullets)
1432         ldir
1433
1434         ld  hl,enemies          ;and remove all enemies as well
1435         ld  (hl),a              ;clear first byte
1436         ld  de,enemies+1        ;point to the next
1437         ld  bc,add2enemy+nrenemies*2    ;clear enemy-info + enemiesxtra
1438         ldir
1439
1440 ;--------------------------- setup game ---------------------------------------
1441
1442 game_setup:
1443         call _clrLCD            ;clear screen
1444         ld a,%10111011
1445         ld  hl,VIDEO_MEM        ;screen location (top left)
1446         ld  b,0                 ;b = 0 (loop 0-1 = 0FFh = 256 times)
1447 clearloop2:
1448         inc a
1449         ld  (hl),a              ;clear four times (total = 256*4 = 1024 bytes)
1450         inc hl
1451         ld  (hl),a
1452         inc hl
1453         xor $ff
1454         ld  (hl),a
1455         inc hl
1456         ld  (hl),a
1457         inc hl
1458         xor $ff
1459         djnz clearloop2         ;repeat 256x
1460
1461         ld  hl,$0703
1462         ld  (_curRow),hl        ;center
1463         ld  hl,txt_level
1464         call _puts              ;display "LEVEL "
1465
1466         ld  a,(level)
1467         ld  l,a
1468         ld  h,$00
1469
1470         call UNPACK_HL
1471         add a,'0'
1472         ld  b,a
1473         call UNPACK_HL
1474         add a,'0'
1475         call _putc              ;display second digit
1476         ld  a,b
1477         call _putmap            ;display first digit
1478
1479         ld  hl,$0904
1480         ld  (_curRow),hl        ;display lives left below level nr
1481         ld  hl,txt_lives        ;bar text: "Lx0"...
1482         ld  a,(lives)           ;lives left
1483         add a,'0'               ;make value
1484         ld  (txt_lives+3),a     ;add to text
1485         call _puts              ;display the string
1486
1487         ld  b,$20
1488 wait:   halt \ halt
1489         djnz wait               ;delay
1490         call _getkey            ;wait for keypress
1491
1492         call _clrLCD            ;clear screen
1493         call disp_icons         ;display bottom icons
1494
1495         ld  hl,VIDEO_MEM+(16*56);56 rows down = eight rows from bottom
1496         ld  b,16                ;draw 16x (screen width)
1497         ld  a,%11111111         ;horizontal line mask
1498 drawline:
1499         ld  (hl),a              ;draw one piece of the divider-line
1500         inc hl                  ;move right (8 pixels = 1 byte)
1501         djnz drawline           ;repeat (16bytes * 8pixels =128= screen width)
1502         ret
1503
1504 ;--------------------------- putsprite ----------------------------------------
1505 ;--------------------------- de =(X,Y) ----------------------------------------
1506
1507 offsets_table:
1508         .db 128,64,32,%10000,%01000,%00100,%00010,%00001
1509 putsprite:
1510         ld  a,d                 ;a = X
1511         and %00000111           ;a = X mod 8 = bit nr. to mask
1512         ld  hl,offsets_table    ;pixel mask table
1513         ld  c,a                 ;bit nr.
1514         ld  b,0                 ;word
1515         add hl,bc               ;add to table
1516         ld  a,(hl)              ;a = pixel mask
1517         ld  (_smc1+1),a         ;alter pixel mask
1518
1519         ld  hl,GRAPH_MEM        ;save-location
1520         ld  a,e                 ;y-coord
1521         add a,a                 ;y*2
1522         add a,a                 ;y*4
1523         add a,a                 ;y*8
1524         rl  b                   ;b (=0) =b*2+overflow (if y>32 then bc=bc+256)
1525         add a,a                 ;y*16 (width of screen)
1526         rl  b                   ;b=b*2+overflow (if y>64 then bc=bc+512)
1527         srl d                   ;d/2
1528         srl d                   ;d/4
1529         srl d                   ;d/8 (8 bits in byte) ** c is set when overflow
1530         add a,d                 ;a = (Y*16+X/8) mod 256
1531         jr  nc,_n1              ;jump if no carry = no overflow = a<=255
1532         inc b                   ;a>255 so increase bc by 256
1533 _n1:    ld  c,a                 ;c = (Y*16+X/8) mod 256
1534         add hl,bc               ;bc = Y*16+X/8
1535           
1536         ld  d,(ix)
1537         ld  b,(ix+1)
1538 _oloop: push bc                 ;Save # of rows
1539         push hl                 ;Save screen address
1540         ld  b,d                 ;Load width
1541         ld  c,(ix+2)            ;Load one line of image
1542         inc ix
1543 _smc1:  ld  a,1                 ;Load pixel mask
1544 _iloop: sla c                   ;Test leftmost pixel
1545         jr  nc,_noplot          ;See if a plot is needed
1546         ld  e,a                 ;OR pixel with screen
1547         or  (hl)
1548         ld  (hl),a
1549         ld  a,e
1550 _noplot:rrca
1551         jr  nc,_notedge         ;Test if edge of byte reached
1552         inc hl                  ;Go to next byte
1553 _notedge:
1554         djnz _iloop
1555         pop hl                  ;Restore address
1556         ld  bc,16               ;Go to next line
1557         add hl,bc
1558         pop bc                  ;Restore data
1559         djnz _oloop
1560         ret
1561
1562 ;--------------------------- putbigsprite -------------------------------------
1563
1564 putwidesprite:
1565         ld       a,d
1566         and      7
1567         ld       hl,offsets_table
1568         ld       c,a
1569         ld       b,0
1570         add      hl,bc
1571         ld       a,(hl)
1572         ld       (wsmc1+1),a
1573         ld       (wsmc2+1),a
1574         ld       hl,(PutWhere)
1575
1576         ld       a,e
1577         add      a,a
1578         add      a,a
1579         add      a,a
1580
1581         rl       b
1582         add      a,a
1583         rl       b
1584         srl      d
1585         srl      d
1586         srl      d
1587         add      a,d
1588         jr       nc,n1
1589         inc      b
1590 n1:     ld       c,a
1591         add      hl,bc                                    
1592           
1593         ld       d,(ix)       
1594         ld       b,(ix+1)        
1595 woloop: push     bc                         ;Save # of rows
1596         push     hl                         ;Save screen address
1597         ld       b,d                        ;Load width
1598         ld       c,(ix+2)                   ;Load one line of image
1599         inc      ix
1600 wsmc1:  ld       a,1                        ;Load pixel mask
1601 wiloop: sla      c                          ;Test leftmost pixel
1602         jr       nc,wnoplot                 ;See if a plot is needed
1603         ld       e,a                        ;OR pixel with screen
1604         or       (hl)
1605         ld       (hl),a
1606         ld       a,e
1607 wnoplot:
1608         rrca
1609         jr       nc,wnotedge                ;Test if edge of byte reached
1610         inc      hl                         ;Go to next byte
1611 wnotedge:
1612 wsmc2:  cp       1
1613         jr       z,wover_1
1614
1615         djnz     wiloop
1616         pop      hl                         ;Restore address
1617         ld       bc,16                      ;Go to next line
1618         add      hl,bc
1619         pop      bc                         ;Restore data
1620         djnz     woloop
1621         ret
1622 wover_1:
1623         ld       c,(ix+2)
1624         inc      ix
1625         djnz     wiloop
1626         dec      ix
1627         pop      hl
1628         ld       bc,16
1629         add      hl,bc
1630         pop      bc
1631         djnz     woloop
1632         ret
1633
1634 ;------------------------------------------------------------------------------
1635 ;------------------------------- sprites --------------------------------------
1636 ;------------------------------------------------------------------------------
1637
1638 spr_ship:
1639         .db 9,1         ;ship icon
1640         .db %11100000   ; ███
1641         .db %01111000   ;  ████
1642         .db %00111110   ;   █████
1643         .db %01111001   ;  ████  █
1644         .db %01111001   ;  ████  █
1645         .db %01111001   ;  ████  █
1646         .db %00111110   ;   █████
1647         .db %01111000   ;  ████
1648         .db %11100000   ; ███
1649
1650 spr_ship01:
1651         .db 7,7         ;ship alpha class
1652         .db %01111000   ;  ████
1653         .db %11100000   ; ███
1654         .db %11111100   ; ██████
1655         .db %11110010   ; ████  █
1656         .db %11111100   ; ██████
1657         .db %11100000   ; ███
1658         .db %01111000   ;  ████
1659 spr_ship01i:
1660         .db 7,7         ;ship alpha class
1661         .db %01010000   ;  █ █
1662         .db %10100000   ; █ █
1663         .db %01010100   ;  █ █ █
1664         .db %10100010   ; █ █   █
1665         .db %01010100   ;  █ █ █
1666         .db %10100000   ; █ █
1667         .db %01010000   ;  █ █
1668
1669 spr_ship02:
1670         .db 7,7         ;ship beta class
1671         .db %11100000   ; ███
1672         .db %11110000   ; ████
1673         .db %01111100   ;  █████
1674         .db %01110010   ;  ███  █
1675         .db %01111100   ;  █████
1676         .db %11110000   ; ████
1677         .db %11100000   ; ███
1678 spr_ship02i:
1679         .db 7,7         ;ship beta class
1680         .db %01000000   ;  █
1681         .db %10100000   ; █ █
1682         .db %01010100   ;  █ █ █
1683         .db %00100010   ;   █   █
1684         .db %01010100   ;  █ █ █
1685         .db %10100000   ; █ █
1686         .db %01000000   ;  █
1687
1688 spr_multiple:
1689         .db 6,4         ;multiples
1690         .db %01111000   ;  ████
1691         .db %11111100   ; ██████
1692         .db %11111100   ; ██████
1693         .db %01111000   ;  ████
1694
1695 spr_bullet01:
1696         .db 5,3         ;your bullets
1697         .db %00110000   ;   ░▒▓█▒
1698         .db %11111000   ; ░▒▓████▒
1699         .db %00110000   ;   ░▒▓█▒
1700 spr_bullet02:
1701         .db 5,3
1702         .db %11110000   ; ░▒▓███▒
1703         .db %11111000   ; ░▒▓████▒
1704         .db %11110000   ; ░▒▓███▒
1705 spr_bullett1:
1706         .db 4,3         ;▒▒▒
1707         .db %11100000   ;▒███
1708         .db %11110000   ; ████
1709         .db %01110000   ;  ███
1710
1711 spr_bullete1:
1712         .db 4,3         ;enemy bullets
1713         .db %01100000   ;  ▒█▓▒░
1714         .db %11110000   ; ▒███▓▒░
1715         .db %01100000   ;  ▒█▓▒░
1716
1717 ;---------------------------------------- explosion -------------------------------------------
1718
1719 spr_explosion:                               
1720         .db 8,6         ;1
1721         .db %00000000
1722         .db %00011100   ;    ███
1723         .db %00111110   ;   █████
1724         .db %01010110   ;  █ █ ██
1725         .db %00111000   ;   ███
1726         .db %00000000
1727
1728         .db 8,6         ;2
1729         .db %00110000   ;   ██
1730         .db %01001110   ;  █ ▒███
1731         .db %10111110   ; █ █████
1732         .db %01001111   ;  █ ▒████
1733         .db %00111000   ;   ███
1734         .db %00011010   ;    ██ █
1735
1736         .db 8,6         ;3
1737         .db %10110000   ; █ ██
1738         .db %01001110   ;  █  ███
1739         .db %10110101   ; █ ██▒█▒█
1740         .db %01000101   ;  █  ▒█▒█
1741         .db %00111110   ;   █████
1742         .db %01011010   ;  █ ██ █
1743
1744         .db 8,6         ;4
1745         .db %00101010   ; ▒ █▒█ █
1746         .db %01000110   ;  █  ▒██
1747         .db %10110101   ; █ ██ █ █
1748         .db %01100110   ;  ██  ██▒
1749         .db %00111100   ;   ████▒
1750         .db %01011001   ;  █ ██ ▒█
1751
1752         .db 8,6         ;5
1753         .db %01000000   ;  █▒ ▒ ▒
1754         .db %00100101   ;  ▒█  █▒█
1755         .db %00010100   ; ▒ ▒█ █ ▒
1756         .db %01000100   ;  █▒  █
1757         .db %00010010   ;   ▒█▒▒█
1758         .db %10011010   ; █▒ ██ █▒
1759
1760         .db 8,6         ;6
1761         .db %01000100   ;  █   █
1762         .db %00100000   ;   ▒█ ▒ ▒
1763         .db %00000001   ;    ▒ ▒ █
1764         .db %01000100   ;  █   █
1765         .db %00100010   ;   █▒  █
1766         .db %01001000   ; ▒█ ▒█ ▒
1767
1768         .db 8,6         ;7
1769         .db %00001000   ;  ▒  █▒
1770         .db %11000010   ; ██ ▒  █
1771         .db %00000000   ;        ▒
1772         .db %00100000   ;  ▒█  ▒
1773         .db %00000001   ;   ▒   ▒█
1774         .db %00110000   ;  ▒██▒
1775
1776         .db 8,6         ;8
1777         .db %00000100   ;     ▒█
1778         .db %00000000   ; ▒▒    ▒
1779         .db %01000000   ;  █
1780         .db %00000000   ;   ▒
1781         .db %00000010   ;       █▒
1782         .db %00100100   ;   █▒ █
1783
1784 ;--------------------------------------- bar -----------------------------------
1785
1786 spr_icon:
1787         .db 16,7        ;selected .......:.......:
1788         .db %11111111,%11111111 ; ████████████████
1789         .db %11000000,%00000001 ; ██             █
1790         .db %11000000,%00000001 ; ██             █
1791         .db %11000000,%00000001 ; ██             █
1792         .db %11000000,%00000001 ; ██             █
1793         .db %11000000,%00000001 ; ██             █
1794         .db %11111111,%11111111 ; ████████████████
1795 spr_icon00:
1796         .db 16,7        ;unused   .......:.......:
1797         .db %10101010,%10101010 ; █ █ █ █ █ █ █ █
1798         .db %11010101,%01010101 ; ██ █ █ █ █ █ █ █
1799         .db %10101010,%10101010 ; █ █ █ █ █ █ █ █
1800         .db %11010101,%01010101 ; ██ █ █ █ █ █ █ █
1801         .db %10101010,%10101010 ; █ █ █ █ █ █ █ █
1802         .db %11010101,%01010101 ; ██ █ █ █ █ █ █ █
1803         .db %10101010,%10101010 ; █ █ █ █ █ █ █ █
1804 spr_icon01:
1805         .db 16,7        ;armor  ; .......:.......:
1806         .db %10001111,%10000000 ; █   █████
1807         .db %10010000,%01000000 ; █  █     █  ▒▒▒
1808         .db %10101110,%00100000 ; █ █ ███   █ ▒▒▒
1809         .db %10100111,%10100000 ; █ █  ████ █ ▒▒▒
1810         .db %10101110,%00100000 ; █ █ ███   █ ▒▒▒
1811         .db %10010000,%01000000 ; █  █     █  ▒▒▒
1812         .db %10001111,%10000000 ; █   █████
1813 spr_icon02:
1814         .db 16,7        ;torpedo  .......:.......:
1815         .db %10111000,%00010101 ; █ ███      █ █ █
1816         .db %10011100,%00010101 ; █  ███     █ █ █
1817         .db %10111000,%01001010 ; █ ███    █  █ █
1818         .db %10000000,%11101010 ; █       ███ █ █
1819         .db %11100001,%11100101 ; ███    ████  █ █
1820         .db %10011000,%11110101 ; █  ██   ████ █ █
1821         .db %11100110,%00110010 ; ███  ██   ██  █
1822 spr_icon03:
1823         .db 16,7        ;empty    .......:.......:
1824         .db %10000000,%00000000 ; █
1825         .db %10000000,%00000000 ; █
1826         .db %10000000,%00000000 ; █
1827         .db %10000000,%00000000 ; █
1828         .db %10000000,%00000000 ; █
1829         .db %10000000,%00000000 ; █
1830         .db %10000000,%00000000 ; █
1831 spr_icon04:
1832         .db 16,7        ;laser    .......:.......:
1833         .db %10000000,%00000000 ; █
1834         .db %10110010,%10000000 ; █ ██  █ █
1835         .db %10111011,%00000000 ; █ ███ ██
1836         .db %10011101,%11111111 ; █  ███ █████████
1837         .db %10111011,%00000000 ; █ ███ ██
1838         .db %10110010,%10000000 ; █ ██  █ █
1839         .db %10000000,%00000000 ; █
1840 spr_icon05:
1841         .db 16,7        ;multiple .......:.......:
1842         .db %10000011,%10000000 ; █     ███      
1843         .db %10000001,%11100110 ; █      ████  ██ 
1844         .db %10000001,%11100000 ; █      ████    
1845         .db %10000011,%10000000 ; █     ███      
1846         .db %10011000,%00000000 ; █  ██          
1847         .db %10111100,%11000011 ; █ ████  ██    ██
1848         .db %10011000,%00000000 ; █  ██          
1849
1850 ;---------------------------- texts -------------------------------------------
1851
1852 txt_about:      .db " v0.93.911",127,"by Shiar",0
1853 txt_email:      .db "shiar0@hotmail.com",0
1854 txt_level:      .db "LEVEL ",0
1855 txt_gameover:   .db "GAME OVER!",0
1856 txt_score:      .db "Score",0
1857 txt_hiscore:    .db "Hiscore",0
1858 txt_lives:      .db "Lx0?",0
1859 txt_pressenter: .db "Enter to continue",0
1860
1861 ;---------------------------- save data ---------------------------------------
1862
1863 PutWhere        .dw GRAPH_MEM           ;where to put the wide sprites
1864
1865 timer           .db $00                 ;frame counter
1866 level           .db $00                 ;level number
1867 levelp          .dw level01             ;pointer to level data
1868
1869 eventenemy      .db $02                 ;enemy type
1870 eventtime       .db $15                 ;enemy frequency
1871 eventleft       .db $00                 ;nr. of enemies still to come
1872 nextevent       .db $50                 ;time to next event
1873 pickuptimer     .db $04
1874
1875 score           .dw $0000
1876 stored_data_start:
1877 hiscore         .dw $0000
1878 stored_data_end:
1879
1880 your_pickup     .db $00
1881 your_occ        .db $00                 ;0=normal 1..16=exploding
1882 your_inv        .db $50                 ;invincibility left
1883 your_armor      .db $13                 ;HP left
1884 lives           .db $04                 ;
1885 x               .db $16                 ;x-pos
1886 y               .db $46                 ;think about it..
1887 hp              .db $00                 ;hitpoints left
1888
1889 your_laser      .db $01                 ;laser avail: 0=no, 1=yes
1890 your_multiples  .db $00                 ;multiples present
1891 torp_occ        .db $00                 ;torp.state: 0=unavail 1=avail 2=presnt
1892 torp_pos        .dw $0000               ;torpedo position (x,y)
1893
1894 ;---------------------------- enemy data --------------------------------------
1895
1896 sprites:
1897         .db $00
1898         .db spr_enemy01-spr_enemy00
1899         .db spr_enemy02-spr_enemy00
1900         .db spr_enemy03-spr_enemy00
1901         .db spr_enemy04-spr_enemy00
1902         .db spr_enemy05-spr_enemy00
1903         .db spr_enemy06-spr_enemy00
1904         .db spr_enemy07-spr_enemy00
1905
1906 spr_enemy00:
1907         .db 7,5         ;pickup
1908         .db %11111110   ; ███████
1909         .db %11111110   ; ███████
1910         .db %11000110   ; ██   ██
1911         .db %11111110   ; ███████
1912         .db %11111110   ; ███████
1913 spr_enemy01:
1914         .db 6,6         ;enemy type one
1915         .db %00111100   ;   ████
1916         .db %01110000   ;  ███
1917         .db %11110000   ; ████
1918         .db %11110000   ; ████
1919         .db %01110000   ;  ███
1920         .db %00111100   ;   ████
1921 spr_enemy02:
1922         .db 8,6         ;enemy type two
1923         .db %00111111   ;    █████
1924         .db %01111000   ;  ████
1925         .db %11111100   ; ██████
1926         .db %11111100   ; ██████
1927         .db %01111000   ;  ████
1928         .db %00111111   ;    █████
1929 spr_enemy03:
1930         .db 6,6         ;enemy type three
1931         .db %01111100   ;  █████
1932         .db %11110000   ; ████
1933         .db %11111000   ; █████
1934         .db %11111000   ; █████
1935         .db %11110000   ; ████
1936         .db %01111100   ;  █████
1937 spr_enemy04:
1938         .db 6,6         ;enemy type four
1939         .db %00111000   ;   ███
1940         .db %01111100   ;  █████
1941         .db %11111000   ; █████
1942         .db %11111000   ; █████
1943         .db %01111100   ;  █████
1944         .db %00111000   ;   ███
1945 spr_enemy05:
1946         .db 7,6         ;enemy type four
1947         .db %00011110   ;    ████
1948         .db %01111110   ;  ██████
1949         .db %11111100   ; ██████
1950         .db %11111100   ; ██████
1951         .db %01111110   ;  ██████
1952         .db %00011110   ;    ████
1953 spr_enemy06:
1954         .db 7,6         ;enemy type four
1955         .db %00011100   ;    ███
1956         .db %01111110   ;  ██████
1957         .db %10111000   ; █ ███
1958         .db %10111000   ; █ ███
1959         .db %01111110   ;  ██████
1960         .db %00011100   ;    ███
1961 spr_enemy07:
1962         .db 8,6         ;enemy type four
1963         .db %00011110   ;    ████
1964         .db %01111111   ;  ███████
1965 enemy00:.db %10011100   ; █  ███
1966         .db %10011100   ; █  ███
1967         .db %01111111   ;  ███████
1968         .db %00011110   ;    ████
1969
1970         ;enemyInfo:     %000000:HP %10:occ $00:type $00:app $00:unused
1971 enemy01:                        ;#1     HP:1    app:random
1972         .db %00000010,1,1,0
1973 enemy02:                        ;#2     HP:1    app:halflure
1974         .db %00000010,2,3,0
1975 enemy03:                        ;#3     HP:1    app:random      moving
1976         .db %00000011,3,1,0
1977 enemy04:                        ;#4     HP:2    app:lure
1978         .db %00000110,4,2,0
1979 enemy05:                        ;#5     HP:2    app:random      moving
1980         .db %00000111,5,1,0
1981 enemy06:                        ;#6     HP:3    app:lure        moving
1982         .db %00001011,6,2,0
1983 enemy07:                        ;#7     HP:6    app:halflure    moving
1984         .db %00010111,7,3,0
1985
1986 ;----------------------------- level info -------------------------------------
1987
1988 level01:
1989         .db $01,$1b,$2f                 ;enemy nr ; enemy frequency ; next lvl
1990 level02:                                ;frequency must be odd if halfluring!
1991         .db $02,$11,$4b
1992 level03:
1993         .db $03,$1f,$3f
1994 level04:
1995         .db $04,$0d,$4f
1996 level05:
1997         .db $05,$23,$3d
1998 level06:
1999         .db $06,$1f,$39
2000 level07:
2001         .db $07,$1d,$f9
2002
2003 ;----------------------------- logo -------------------------------------------
2004
2005 logo_nemesis:
2006 .db %11111111,%11111111,%11111111,%11111110,%11111111,%11110111,%11111111,%11111110,%11111111,%111101111,%11111111,%00001011,%11111111,%11111111,%11111111,%11111000
2007 .db %01111111,%11111111,%11111111,%11111110,%11111111,%11110111,%11111111,%11111110,%11111111,%111101111,%11111111,%00011011,%11111111,%11111111,%11111111,%11110000
2008 .db %00111111,%11111111,%11111111,%11111110,%11111111,%11110111,%11111111,%11111110,%11111111,%111101111,%11111111,%00111011,%11111111,%11111111,%11111111,%11100000
2009 .db %00011111,%11111111,%11111111,%11111110,%11111111,%11110111,%11111111,%11111110,%11111111,%111101111,%11111111,%01111011,%11111111,%11111111,%11111111,%11000000
2010 .db %00000000,%00000000,%00000001,%00011110,%00010000,%00000000,%10000001,%00011110,%00010000,%000000001,%00000000,%00001000,%01000000,%00000000,%00000000,%00000000
2011 .db %00000000,%00000000,%00000011,%00011110,%00110000,%00000001,%10000011,%00011110,%00110000,%000000011,%00000000,%00011000,%11000000,%00000000,%00000000,%00000000
2012 .db %00000000,%00000000,%00000111,%00011110,%01110000,%00000011,%10000111,%00011110,%01110000,%000000111,%00000000,%00111001,%11000000,%00000000,%00000000,%00000000
2013 .db %00000000,%00000000,%00001111,%00011110,%11111111,%00000111,%10001111,%00011110,%11111111,%000001111,%11111111,%01111011,%11111111,%11000000,%00000000,%00000000
2014 .db %00000000,%00000000,%00001111,%00011110,%11111111,%00000111,%10001111,%00011110,%11111111,%000001111,%11111111,%01111011,%11111111,%11000000,%00000000,%00000000
2015 .db %00000000,%00000000,%00001111,%00011110,%11111111,%00000111,%10001111,%00011110,%11111111,%000001111,%11111111,%01111011,%11111111,%11000000,%00000000,%00000000
2016 .db %00000000,%00000000,%00001111,%00011110,%11111111,%00000111,%10001111,%00011110,%11111111,%000001111,%11111111,%01111011,%11111111,%11000000,%00000000,%00000000
2017 .db %00000000,%00000000,%00001111,%00011110,%11110000,%00000111,%10001111,%00011110,%11110000,%000000000,%00001111,%01111000,%00000011,%11000000,%00000000,%00000000
2018 .db %00000000,%00000000,%00001111,%00011110,%11110000,%00000111,%10001111,%00011110,%11110000,%000000000,%00001111,%01111000,%00000011,%11000000,%00000000,%00000000
2019 .db %00000000,%00000000,%00001111,%00011110,%11110000,%00000111,%10001111,%00011110,%11110000,%000000000,%00001111,%01111000,%00000011,%11000000,%00000000,%00000000
2020 .db %00000000,%00000000,%00001111,%00011110,%11110000,%00000111,%10001111,%00011110,%11110000,%000000000,%00001111,%01111000,%00000011,%11000000,%00000000,%00000000
2021 .db %00000000,%00000000,%00001111,%00011110,%11111111,%11110111,%10001111,%00011110,%11111111,%111101111,%11111111,%01111011,%11111111,%11000000,%00000111,%11010001
2022 .db %00000000,%00000000,%00001111,%00011110,%11111111,%11110111,%10001111,%00011110,%11111111,%111101111,%11111111,%01111011,%11111111,%11000000,%00000001,%00011011
2023 .db %00000000,%00000000,%00001111,%00011110,%11111111,%11110111,%10001111,%00011110,%11111111,%111101111,%11111111,%01111011,%11111111,%11000000,%00000001,%00010101
2024 .db %00000000,%00000000,%00001111,%00011110,%11111111,%11110111,%10001111,%00011110,%11111111,%111101111,%11111111,%01111011,%11111111,%11000000,%00000001,%00010001
2025
2026 ;----------------------------- end --------------------------------------------
2027
2028         .end
2029 .end
2030
2031 ;----------------------------- NEMESIS'86 by Shiar ----------------------------
2032
2033 ;Game · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · NEMESIS
2034 ;Version  · · · · · · · · · · · · · · · · · · · · · · · · · · · · · ·  0.93.911
2035 ;Latest modification  · · · · · · · · · · · · · · · · · · · · · · · ·  11.IX.99
2036 ;Calc · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · ·  TI-86 only
2037 ;Size · · · · · · · · · · · · · · · · · · · · · · · · · · ·  3098 bytes on calc
2038
2039 ;Author · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · SHIAR
2040 ;ICQ  · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · #43840958
2041 ;E-mail · · · · · · · · · · · · · · · · · · · · · · · · · ·  shiar0@hotmail.com
2042 ;Homepage · · · · · · · · · · · · · · · · · · · · · · · · · · · · come.to/shiar
2043
2044 ;Notes:
2045 ;  <*> This game is not yet finished (BETA) and there may still be some bugs.
2046 ;  <*> I'll probably release the source when the game has been finished.
2047 ;  <*> Have fun, and have even more fun with the completed version of NEMESIS!
2048
2049 ;----------------------------- version history --------------------------------
2050
2051 ;0.01.717 -- 17.VII.99 -- size 909
2052 ;
2053 ;       + used "Galaxian"-game engine (drawings, movement, enemy-routines)
2054 ;       + movement of ship over 3/4 screen (96 pixels; 32 pixels for score)
2055 ;       + enemies moving from right to left, appearing right at specified times
2056 ;
2057 ; 0.1.718 -- 18.VII.99 -- size 832
2058 ;
2059 ;       # no crash when level restarts for the third time
2060 ;       * exit-procedure updated, unnecessary stuff/keychecks removed
2061 ;       - alot of unused code removed
2062 ;       + different types of enemies (just look different)
2063 ;       + collision detection!! enemy ships disappear when you hit them
2064 ;
2065 ; 0.2.718 -- 18.VII.99 -- size 1078
2066 ;
2067 ;       + ability to fire bullets (F1). Enemies disappear on impact
2068 ;       * enemies explode instead of disappearing
2069 ;
2070 ; 0.3.719 -- 19.VII.99 -- size 1326
2071 ;
2072 ;       * bullets appear correctly (not INSIDE your ship)
2073 ;       + some enemies can take multiple hits (differs per class)
2074 ;       + all enemies fire bullets at random
2075 ;       + if you're hit by bullet/enemy, you'll lose one hitpoint
2076 ;
2077 ; 0.4.720 -- 20.VII.99 -- size 1406
2078 ;
2079 ;       # collision detection fixed and optimized (much faster now!)
2080 ;       + shell-icon added (YAS type)
2081 ;       * code optimizations, some data "compression"
2082 ;       * explosion looks better, and some vars removed/smaller
2083 ;       # enemies are removed when at left side (instead of becoming invisible)
2084 ;       + displays level number before each level begins
2085 ;
2086 ; 0.5.725 -- 25.VII.99 -- size 1703
2087 ;
2088 ;       * waits a sec at level display (in case of accidental keypress)
2089 ;       * moving enemies (move up+down)
2090 ;       # bullets removed correctly so they can be used again later
2091 ;       * first level made
2092 ;       # enemy weaponfire is fired from correct positions
2093 ;       + your ship explodes on impact with ships/bullets
2094 ;       * game over screen will be displayed just *after* your ship's gone
2095 ;       + frame counter onscreen
2096 ;
2097 ; 0.6.820 -- 20.IIX.99 -- size 2077 -- MAJOR UPGRADE first release (not on web)
2098 ;
2099 ;       * play field increased to full screen instead of 3/4
2100 ;       + bottom eight lines used for score (etc) display
2101 ;       - no more solid levels, enemies are placed at random
2102 ;       + enemies appear every x turns (depends on level)
2103 ;       # fixed bullets so they don't disappear at 3/4 of the screen
2104 ;       * A LOT of optimizations both in speed and size!!
2105 ;       + enemy type, frequency, and number specified per level
2106 ;       + bottom score bar displays score, lives and icons (to be used later)
2107 ;       * smarter enemy handling (so enemies have different sizes)
2108 ;       + bottom bar divided from playing field by a horizontal line
2109 ;       + five levels (and five enemies) made
2110 ;       # game vars reset at start and game over
2111 ;       + NEMESIS LOGO displayed at startup!! (also, program grew 350bytes ):
2112 ;       + version/credits string displayed below logo: v0.6.820 by shiar (ICQ#)
2113 ;
2114 ;0.61.825 -- 25.IIX.99 -- size 2085 -- small changes to v0.6
2115 ;
2116 ;       # pointer to fifth ship corrected (ships in level 5 weren't displayed)
2117 ;       # calc doesn't crash anymore when game is continued after game over!!
2118 ;       + lives are decreased when ship is destroyed
2119 ;       # last eight pixels of divider line are shown correctly now
2120 ;
2121 ;  0.7.92 -- 02.IX .99 -- size 2303 -- optimizations and pickups
2122 ;
2123 ;       + contrast is increased one level at startup (and restored on exit)
2124 ;       + invulnerable for a sec when you enter the game (inv-pickup later)
2125 ;       + when in invulnerable-mode, your ship look different!
2126 ;       + at the beginning you get three *hitpoints* so you can be hit 3 times
2127 ;       * bottomline icons are now 16 pixels wide and 7 pixels high!
2128 ;       + hitpoint icon added: displays nr. of hps left next to a nice picture
2129 ;       * maximum invulnerability-time is increased (can last upto 1024 frames)
2130 ;       + when invulnerable-mode has nearly expired, your ship flashes!
2131 ;       * again a lot of optimizations esp. in size ('bout 100 bytes)
2132 ;       + pickups! 10% chance a destroyed enemy changes into an armor-pickup
2133 ;       # code optimization caused some bullets to reappear as "fake" bullets
2134 ;       * pickups can't be destroyed by bullets (they pass right through it)
2135 ;
2136 ;  0.8.93 -- 03.IX .99 -- size 2433 -- small improvements and bugfixes
2137 ;
2138 ;       + enemies move individually, not all at the same time!! Looks very nice
2139 ;       # titlescreen background is cleared (looked weird in Rascall and TI-OS)
2140 ;       + enemies fire at a ### rate instead of firing at will (too random)
2141 ;       # moving enemies don't move off the screen top/bottom (they wait there)
2142 ;       + seven playable levels going easy to hard (including moving enemies)
2143 ;       # xtraInfo data wasn't reset when a moving enemy entered the game
2144 ;       * longer delay when level is completed (NextLevel screen came too soon)
2145 ;
2146 ;  0.9.94 -- 04.IX .99 -- size 2693 -- FIRST MAJOR (BETA) RELEASE; on websites
2147 ;
2148 ;       # pickups no longer fire bullets like normal enemies
2149 ;       + <halt>s added so the game runs slower and looks better
2150 ;       + TORPEDOES!!! Bullets that fire downwards! Just like in Nemesis
2151 ;       * a pickup selects the next icon on bottom bar instead of increasing hp
2152 ;       + an icon can be taken by pressing F2. second icon selects torpedoes
2153 ;       + first icon increases armor, icon 3 and 4 are unused for now
2154 ;       * selecting an unused icon (3+4) resets pickups like icon 1 and 2
2155 ;       * when you're destroyed, you loose one life instead of going game over
2156 ;         you also loose all upgrades and pickups, but remain in the same level
2157 ;       * random is more randomized, no more "tricks" to fool the randomizer
2158 ;       # after game over the game is terminated instead of continuing+crashing
2159 ;       - no more armor to start with. you'll have to collect them on your own
2160 ;       * of course optimizations and a few tiny bug fixes (not important)
2161 ;       * increased the size of the enemy bullets so they're better to see
2162 ;
2163 ; 0.91.95 -- 05.IX .99 -- size 2797 -- good improvements (upgrades); beta rel.
2164 ;
2165 ;       + LASERS!!!!! four pickups and you fire laserbeams instead of bullets
2166 ;       * multiple enemies can be hit at once, very usefull when firing lasers
2167 ;       + MULTIPLE!! like the (shadow-)multiple from MSX-Nemesis. for 5 pickups
2168 ;         you get an multiple following you, firing bullets and lasers like you
2169 ;       * most data (enemy positions) stored at TEXT_MEM and DELC_LEN positions
2170 ;         instead of in program, saving A LOT of bytes in program-size
2171 ;       - at release of 0.91 bullets didn't work, laser is used instead
2172 ;
2173 ; 0.92.98 -- 08.IX .99 -- size 2831 -- beta released to testers
2174 ;
2175 ;       + all bullets and enemies are removed at the start of a level
2176 ;       # you can fire bullets again (no more laser at startup)
2177 ;       * pickups aren't given at random, but appear every x enemies destroyed
2178 ;       # solved a minor bug in invulnerability flashing display
2179 ;       * clearScreen procedure improved (faster and smaller)
2180 ;       # fifth icon couldn't be selected (so no multiples selectable). fixed
2181 ;       * laserbeam lasts 5 turns (laser wasnt good enough compared to bullets)
2182 ;
2183 ;0.93.911 -- 11.IX .99 -- size 3098
2184 ;
2185 ;       # torpedo-upgrade was cleared when firing torpedo at the end of a level
2186 ;       * pickups move away half the speed of enemies (one pixel every 2 turns)
2187 ;       # fixed a bug causing some calcs to crash on quit
2188 ;       # contrast was not restored after game over (remained one step darker)
2189 ;       * fire key changed from F1 to 2ND, select key changed from F2 to ALPHA
2190 ;       * improved key-checking procedureS (much faster, smaller, better, yea)
2191 ;       * changed title screen, displays version white on black and my e-mail
2192 ;       + score count!! simple system: one point for an enemy destroyed, two
2193 ;         for collision, and one point every 256 frames. plus level clear bonus
2194 ;       + saves HISCORE!!! At game-over screen your- and hi-score are displayed
2195 ;       * Game over screen will be displayed before quit after pressing <exit>
2196 ;       + screen is cleared and cursor moved to top-left on quit
2197 ;       * multiples move only when YOU move, just like the original MSX-Nemesis
2198 ;       * multiple is placed at your position when selected/at start of level
2199 ;       * minor changes in iconbar (3rd icon is empty, line between 5th/score)
2200
2201
2202 ;        + added        - removed       * changed       # bug fixed