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