version 0.97 rc1: charge bullets
[nemesis.git] / nemesis.z80
1 ;------------------------------------------------------------------------------
2 ;---------------------- NEMESIS -----------------------------------------------
3 ;------------------------------------------------------------------------------
4
5 ; Title                         : Nemesis
6 ; Version                       : 0.96
7 ; Release Date                  : 30.X.99
8 ; Filename                      : nemesis.86p (5kb)
9 ; Author(s)                     : Shiar
10 ; Email Address                 : shiar0@hotmail.com
11 ; ICQ                           ; #43840958
12 ; Web Page                      : www.shiar.org
13 ; Description                   : cool arcade-shoot-em-up-game
14 ; Where to get this game        : www.shiar.org | www.ticalc.org
15 ; Other games by author         : Worm
16
17 ; ABOUT:       This source should only be used for learning practises, do not
18 ;              alter it, and certainly do not distribute an altered version!!
19 ; NOTE:                         &&& marks uncertainties or things to optimize
20
21 ;---------------------- nemesis.z80 start -----------------------------------
22
23 #include        "asm86.h"
24 #include        "ti86asm.inc"   ;standard ti86 romcalls
25 #include        "ti86abs.inc"   ;used to save hiscores and so
26
27         .org _asm_exec_ram
28
29 #define           cal   call    ;just to make it harder for you to understand
30 #define           psh   push    ; ^:D
31 #define           dnz   djnz    ;Dec&Jump while NonZero becomes Do w.Non-Zero
32
33 TEXT_MEM        = _textShadow   ;167 bytes ($A7): C0F9-C1A0
34 _clrWindow      = $4a86         ;a new procedure from AsmStudio86 inc. files
35 _ex_ahl_bde     = $45f3
36 _shracc         = $4383
37 _dispahl        = $4a33
38 _asapvar        = $d6fc
39
40 storepos        = _asm_exec_ram+6000            ;120 OF 165
41 storepos2       = _asm_exec_ram+6200            ;141 OF 167
42
43 ;---------------------- in-game vars ----------------------------------------
44
45 just_fired      = storepos+2            ; +2    ;counts how long a blast lasts
46 curline         = storepos+2            ; +2    ;used to display SFX
47 menuitem        = storepos+2            ; +2    ;used to store menu location
48 hiscorepos      = storepos+2            ; +2
49 RanPos          = storepos+3            ; +3    ;used for making random values
50 timer           = storepos+4            ; +4    ;frame counter
51                                                 ;--------YOU
52 x               = storepos+5            ; +5    ;your ship's position
53 y               = x+1                   ; +6    ;your y-pos
54 firex           = y+1                   ; +7    ;(1 byte)
55 firey           = firex+1               ; +8    ;(1 byte)
56                                         ; **
57                                                 ;--------LEVEL
58 eventtime       = storepos+10           ;+10    ;enemy frequency
59 eventleft       = eventtime+1           ;+11    ;nr. of enemies still to come
60 nextevent       = eventleft+1           ;+12    ;time to next event
61 level_enemy     = nextevent+1           ;+13    ;enemy type
62 level_info      = level_enemy+1         ;+14    ;info (see below)
63 level_move      = level_info+1          ;+15    ;=
64 level_fire      = level_move+1          ;+16
65                                         ; **
66                                                 ;--------OBJECTS
67 spacespace      = storepos+19           ;+19
68 groundinfo      = spacespace+1          ;+20
69 groundpos       = groundinfo+1          ;+21    $10
70 ceilingpos      = groundpos+16          ;+37    $10
71                                         ; ^^    ;--------STARS
72 stars1          = ceilingpos+16         ;+53
73 stars2          = stars1+1              ;+54
74 nrstars1        = 7
75 starx1          = storepos+55           ;+55
76 nrstars2        = 7
77 starx2          = starx1+(nrstars1*2)   ;+69
78                                         ; ^^    ;--------MULTIPLES
79 mx              = starx2+(nrstars2*2)   ;+83    ;position of multiple#1
80 my              = mx+1                  ;+84    ;multiple y-pos
81 m2x             = my+1                  ;+85
82 m2y             = m2x+1                 ;+86
83 your_locpos     = m2y+1                 ;+87    ;position in your_prevpos tabl
84 your_prevpos    = your_locpos+1         ;+88    ;save previous positions (32d)
85
86 ;^-----------------------------------<1 ;-120=$78
87
88 enemies         = storepos2             ;  +0   ;info about each enemy
89 enemysize       = 7                             ;infobytes per enemy
90 nrenemies       = 16                            ;max. nr of enemies
91
92 ybullets        = enemies+(nrenemies*enemysize) ;60 bytes = 20(state,damg,x,y)
93 nrybuls         = 32                    ; +80\
94 ebullets        = ybullets+(nrybuls*4)  ;+110   ;30 bytes = 10(state,x,y)
95 nrebuls         = 16
96
97 ybuls           = ebullets+(nrebuls*3)  ;+140
98 maxbullets = 32
99
100 ;^-----------------------------------<2 ;-141=$8D
101 ;level_info:
102 ;       [0000:damage 0:directfire 0:ground 0:ceiling 0:diagfire]
103 ;enemies:
104 ;       [HP64] [000000:HP left 00:(00=no enemy 01=exploding 10=normal 11=moving)]
105 ;       [ship type or explosion frame] [x] [y] [move] [fire]
106
107 ;---------------------- introduction ----------------------------------------
108
109          nop                    ;hello yas/ase/rascall/whathever
110          jp init                ;here's the program, but first: a description
111         .dw $0001               ;description type 2 (description + YASicon)
112         .dw Title               ;pointer to description (all shells)
113         .dw Icon                ;pointer to YAS icon
114
115 Title:  .db "Nemesis v0.96 by Shiar",0
116
117 Icon:   .db 8,1                 ;icon for YAS: width = 1byte; height = 9bytes
118         .db %11100000           ; ███
119         .db %01111000           ;  ████
120         .db %00111110           ;   █████
121         .db %01111001           ;  ████  █
122         .db %00111110           ;   █████
123         .db %01111000           ;  ████
124         .db %11100000           ; ███             ;recommend 80x50 screen mode
125         .DB 0   ;clear stupid YAS-line
126
127 ;---------------------- init ------------------------------------------------
128
129 level_name: .db 8,"nemesis0"
130
131 int_handler:
132         ex  af,af'
133         in  a,($03)
134         bit 3,a
135         jp  z,$0039
136         res 0,a
137         out ($03),a
138         jp  $0039
139 int_end:
140
141 init:   cal BUSY_OFF            ;turns the run-indicator off, obviously
142         cal _clrScrn            ;clean the screen
143         xor a                   ;ld a,0
144         ld (iy+13),a            ;don't affect TEXT_MEM and don't scroll screen
145         cal _flushallmenus      ;remove TI menus
146         ld (_asapvar+1),a       ;Asm( thinks it's the first time it runs Nems.
147
148 FixKeys:                        ;fixes some key problems like left+down bug
149         im  1
150         ld  a,$D4
151         ld  bc,$0100
152         ld  h,a
153         ld  l,c                 ;ld hl,$D400
154         ld  d,a
155         ld  e,b                 ;ld de,$D401
156         dec a                   ;ld a,$D3
157         ld  (hl),a
158         ldir
159         ld  hl,int_handler
160         ld  d,a
161         ld  e,a                 ;ld de,$D3D3
162         ld  bc,int_end-int_handler
163         ldir
164         inc a                   ;ld a,$D4
165         ld  i,a
166         im  2
167
168 ;---------------------- main menu -------------------------------------------
169
170 LogoPut:
171         xor a                   ;white bitmask (a=0)
172         ld  hl,logo_nemesis     ;from...
173         ld  de,VIDEO_MEM+16     ;...to one line from top
174         ld  b,e                 ;ld b,16: one line
175 AboveLogo:
176         ld  (de),a              ;clear/n byte
177         inc de                  ;next
178         dnz AboveLogo           ;repeat for the first line
179
180         ld  bc,16*19            ;logo size
181         ldir                    ;display one line of logo
182
183         ld  hl,VIDEO_MEM+(16*$39)+4     ;$39 rows down, 4 cols right (4*8=$20)
184         ld  b,8                 ;draw 8x one byte = 8*8 = 64 pixels wide
185         ld  a,%11111111         ;horizontal line mask
186 underline:
187         ld  (hl),a              ;draw one piece of the divider-line
188         inc hl                  ;move right (8 pixels = 1 byte)
189         dnz underline           ;repeat
190
191         set 3,(iy+5)            ;set white on black
192         ld  hl,$3320            ;near the bottom of the screen
193         ld  (_penCol),hl
194         ld  hl,txt_about        ;display version and author (yes, that's me!)
195         cal _vputs              ;useful procedure if you want to display somtn
196         res 3,(iy+5)            ;return to default black on white
197
198         ld  hl,$3a1e            ;below previous stuff
199         ld  (_penCol),hl
200         ld  hl,txt_email        ;hey, my e-mail address so SEND ME SOMETHING!!
201         cal _vputs              ;VERY important, so display in small font ?:}
202
203 dispmenu:
204         ld  de,$0304
205         ld  (_curRow),de
206         ld  hl,txt_menu1
207         cal _puts
208         ld  de,$0305
209         ld  (_curRow),de
210         ld  hl,txt_menu2
211         cal _puts
212
213         xor a
214         ld  (menuitem),a
215
216 menuloop:
217         ld  a,(menuitem)
218         ld  h,$01
219         add a,4
220         ld  l,a
221
222         ld  a,5
223         ld  (_curRow),hl
224         cal _putc
225
226         ld  a,(menuitem)
227         ld  h,$01
228         sub 5
229         neg
230         ld  l,a
231
232         ld  a,32
233         ld  (_curRow),hl
234         cal _putc
235
236         halt \ halt
237
238         cal GET_KEY             ;wait for keypress
239         cp  K_UP
240         jr  z,menuchange
241         cp  K_DOWN
242         jr  z,menuchange
243         cp  K_EXIT
244         jp  z,game_over_nopop
245         ld  hl,_invert
246         cp  K_F1
247         cal z,undo_invert
248         cp  K_F2
249         cal z,do_invert
250         cp  K_ENTER
251         jr  nz,menuloop
252
253         ld  a,(menuitem)
254         dec a
255         jr  nz,startnewgame
256         cal samelevel
257         jr  game_main_loop
258
259 menuchange:
260         ld  a,(menuitem)
261         xor 1
262         ld  (menuitem),a
263         jr  menuloop
264
265 do_invert:
266         ld  (hl),$2F ;cpl
267         ret
268 undo_invert
269         ld  (hl),$B7 ;or a
270         ret
271
272 startnewgame:
273         cal New_game
274
275 ;----------------------------------------------------------------------------
276 ;---------------------- game loop -------------------------------------------
277 ;----------------------------------------------------------------------------
278
279 game_main_loop:                 ;REPEATS FROM HERE EVERY FRAME
280         ld  hl,timer            ;update time
281         inc (hl)                ;increase by 1
282         ld  b,(hl)              ;new time, save for rand# upd. (no flag change)
283         jr  nz,updaterandom     ;continue when new time <> 0
284         ld  hl,1                ;once every 256 frames, increase score by 1
285         cal scoreInc            ;do it
286
287 updaterandom:
288         ld  hl,RanPos           ;random counter
289         ld  a,r                 ;add r register to randomize
290         add a,(hl)              ;add previous random value
291         add a,b                 ;even more random by adding timer
292         ld  (hl),a              ;save even more random value back
293
294 Clear_screen:
295         ld  hl,GRAPH_MEM        ;move from (hl) = top left
296         ld  (hl),$00            ;first pixel will be copied all over the screen
297         ld  de,GRAPH_MEM+1      ;(de) = next pixel, thus clearing whole screen
298         ld  bc,896              ;loop 896 times = (128/8) * (64-8 for scorebar)
299         ldir                    ;clear!
300
301         ld  a,(timer)
302         and %11
303         jr  z,movestarsdone     ;don't move stars once every 4 frames
304
305         cal movestars1          ;move the stars on the FRONT layer
306         cal movestars2          ;move the distant stars
307
308 movestarsdone:
309         ld  a,(stars1)          ;star positions (the missing byte...)
310         ld  b,nrstars1          ;how many stars? now we know.
311         ld  hl,starx1           ;points to the position of the stars
312         cal DisplayStars        ;display front layer stars
313
314         ld  a,(stars2)          ;weren't you paying attention five lines ago?
315         ld  b,nrstars2          ;that many?! whow!
316         ld  hl,starx2           ;and there they are
317         cal DisplayStars        ;use the same procedure to display back layer
318
319         ld  a,(level_info)      ;level info
320         and %00000110           ;isolate ground&ceiling
321         jr  z,game_stuff        ;both non-present
322         and %00000010           ;bit representing the presence of any ceiling
323         cal nz,Handle_ceiling   ;scroll the ceiling (if any)
324         cal Handle_ground       ;scroll the ground
325
326 game_stuff:
327         ld  a,(your_occ)        ;are you 100% OK?
328         or  a                   ;a=0??
329         jr  nz,_gamestuff1      ;then don't check for movements/fires/...
330
331         ld  a,(level_info)      ;the same level info
332         and %00000110           ;isolate ground&ceiling again
333         jr  z,check_keys        ;no ceiling nor ground
334         and %00000010           ;this bit will tell us if there is a ceiling
335         cal nz,CheckCeiling     ;if there is, check it
336         cal CheckGround         ;check for collision with the ground
337
338 check_keys:
339         ld  a,%10111111         ;function keys (MORE,EXIT,2ND,F1,F2,F3,F4,F5)
340         out (1),a               ;ask for them
341         nop \ nop               ;delay 8 clocks
342         in  a,(1)               ;get zem!
343
344 check_exitkey:
345         bit 6,a                 ;test bit 6 = exit-key = EXIT
346         jp  z,game_over_nopop   ;<exit> pressed, so be it
347 check_morekey:                  ;another unused label... poor compiler
348         bit 7,a                 ;test bit 7 = more-key = PAUSE
349         cal z,Pause             ;yes, go to pause
350
351 check_firekey:
352         bit 5,a                 ;test bit 5 = 2nd-key = FIRE
353         ld  hl,check_selkey     ;where to continue after executing Fire_bullet
354         psh hl                  ;push hl on stack (instead of cal Fire_bullet)
355         jp  z,Fire_bullet       ;fire smtn (bulletstorplasermultiples+stuff..)
356         pop hl                  ;no cal to Fire_bullet made, so pop stack
357         xor a                   ;no:
358         ld  (just_fired),a      ;reset just_fired
359
360 check_selkey:
361         ld  a,%01011111         ;look at first column of keys (ALPHA to STO)
362         out (1),a               ;gimme
363         nop \ nop               ;what's taking you so long
364         in  a,(1)               ;at last... our precious keyzzz...
365
366         bit 6,a                 ;'bout the GRAPH key...
367         cal z,Teacher           ;you didn't _press_ it, did you?!?
368
369         rla                     ;test bit7 so we know f ALPHA has been pressed
370         cal nc,select           ;yeppy, select the currently selected upgrade
371
372         cal Enemies_hit         ;check for collision with enemies
373         cal inc_weapdamage
374
375 _gamestuff1:
376         cal Handle_Ship         ;move you
377         cal Handle_bullets      ;move your bullets
378         cal Handle_torp         ;move your torpedo
379
380         cal Handle_enemies      ;move enemies
381         cal Enemy_bullets       ;move enemy bullets
382
383         cal Level_event         ;insert enemies
384         cal Display_Screen      ;display all
385         halt                    ;delay
386
387         jp  game_main_loop      ;LOOP ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
388
389 inc_weapdamage:
390         ld  a,0
391 weapincs =$-1
392         inc a
393         cp  31
394         ret nc                  ;return if increased 16 times or more already
395         ld  (weapincs),a
396
397         ld  b,1
398 weapdamage =$-1
399         add a,b
400
401         ld  (curweapdamage),a
402         ret
403
404 ;--------------------------- ground -----------------------------------------
405
406 Handle_ground:
407         ld  a,(timer)
408         and %111                ;once every 8 frames
409         jr  nz,Display_ground   ;otherwise skip the scroll
410         ld  bc,15               ;scroll all 16 bytes minus one (teh new byte)
411         ld  hl,groundpos+1      ;from..
412         ld  de,groundpos        ;to (one byte to the left)
413         ldir                    ;LoaDIncreaseRepeat = scroll!
414
415         ld  a,(groundinfo)      ;what kind of ground
416         dec a                   ;type 1:
417         jr  z,ground_tunnel     ;tunnel effect
418         jr  ground_boring
419
420 ground_tunnel:
421         ld  a,(groundpos+14)
422         ld  (groundpos+15),a
423         ld  hl,spacespace
424
425         ld  a,(RanPos)
426         ld  b,a
427         bit 1,a
428         jr  z,ground_previous
429         bit 2,a
430         jr  z,gtunneldown
431 gtunnelup:
432         ld  a,(hl)
433         or  a
434         jr  z,ground_previous   ;a>=0 (a=0 actually)
435         inc (hl)
436         ld  a,(groundpos+15)
437         inc a
438         jr  newground
439 gtunneldown:
440         ld  a,(groundpos+15)
441         dec a
442         jr  z,ground_previous
443         dec (hl)
444         jr  newground
445
446 ground_previous:
447         ld  a,(groundpos+14)    ;type 1
448         jr  newground
449 ground_boring:
450         ld  a,(groundpos)       ;type 0
451 newground:
452         ld  (groundpos+15),a    ;save new byte on the right
453         ld  a,(hl)
454         cp  -25
455         jr  nc,Display_ground
456         ld  a,b
457         and %1
458         ld  b,0
459         jr  nz,gtunnelup
460
461 Display_ground:
462         ld  b,16                ;screen width
463         ld  de,groundpos-1      ;height of current byte (previous actually)
464         psh de                  ;use later
465         ld  hl,GRAPH_MEM+(56*16)-1 ;screen position
466         psh hl
467
468 groundloopright:
469         ld  c,b                 ;push b for groundloopup
470         pop hl \ inc hl         ;get screen position and go one right
471         pop de \ inc de         ;get height info and set to the next byte
472         psh de \ psh hl         ;save these for the next time
473         ld  a,(de)              ;height of current byte
474         ld  b,a                 ;save in b
475
476         ld  de,16               ;to substract to go one line up
477         ld  a,%11111111         ;bitmask black
478         or  a
479 groundloopup:
480         ld  (hl),a              ;display black byte
481         sbc hl,de               ;go up (sbc must be used for 16-bit sub)
482         dnz groundloopup        ;and loop >groundpos< times
483
484         ld  b,c                 ;pop b used by groundloopup
485         dnz groundloopright     ;loop right for entire screen (16x)
486         pop hl \ pop hl         ;restore stack
487         ret
488
489 CheckGround:                    ;check for collision with the ground
490         ld  a,(x)
491         srl a
492         srl a
493         srl a
494         inc a
495         ld  l,a
496         ld  h,0
497         ld  de,groundpos
498         add hl,de
499         ld  a,(y)
500         sub 57-7
501         neg
502         cp  (hl)
503         ret nc
504         ld  b,5
505         jp  damage_you
506
507 ;--------------------------- ceiling ----------------------------------------
508
509 Handle_ceiling:
510         ld  a,(timer)
511         and %111                ;once every 8 frames
512         jr  nz,Display_ceiling  ;otherwise skip the scroll
513         ld  bc,15               ;scroll all 15 bytes (16th is new position)
514         ld  hl,ceilingpos+1     ;from..
515         ld  de,ceilingpos       ;to (one byte to the left)
516         ld  a,(de)              ;load byte on left (will be lost after scroll)
517         ldir                    ;LoaDIncreaseRepeat = scroll!
518
519         ld  a,(groundinfo)      ;what kind of ceiling
520         dec a                   ;type 1:
521         jr  z,ceiling_tunnel    ;tunnel effect
522         jr  ceiling_boring
523
524 ceiling_tunnel:
525         ld  a,(ceilingpos+14)
526         ld  (ceilingpos+15),a
527         ld  hl,spacespace
528
529         ld  a,(RanPos)
530         ld  b,a
531         bit 4,a
532         jr  z,ceiling_previous
533         bit 5,a
534         jr  z,ctunnelup
535 ctunneldown:
536         ld  a,(hl)
537         or  a
538         jr  z,ceiling_previous
539         inc (hl)
540         ld  a,(ceilingpos+15)
541         inc a
542         jr  newceiling
543 ctunnelup:
544         ld  a,(ceilingpos+15)
545         dec a
546         jr  z,ceiling_previous
547         dec (hl)
548         jr  newceiling
549
550 ceiling_previous:
551         ld  a,(ceilingpos+14)   ;type 1
552         jr  newceiling
553 ceiling_boring:
554         ld  a,(ceilingpos)      ;type 0
555 newceiling:
556         ld  (ceilingpos+15),a   ;save the new byte
557         ld  a,(hl)
558         cp  -25
559         jr  nc,Display_ceiling
560         ld  a,b
561         and %1
562         ld  b,0
563         jr  nz,ctunneldown
564
565 Display_ceiling:
566         ld  b,16                ;screen width
567         ld  de,ceilingpos-1     ;height of current byte
568         psh de                  ;use later
569         ld  hl,GRAPH_MEM-17     ;screen position
570         psh hl
571
572 ceilingloopright:
573         ld  c,b                 ;push b for groundloopup
574         pop hl \ inc hl         ;get screen position and go one right
575         pop de \ inc de         ;get height info and set to the next byte
576         psh de \ psh hl         ;save these for the next time
577         ld  a,(de)              ;height of current byte
578         ld  b,a                 ;save in b
579
580         ld  de,16               ;to substract to go one line up
581         ld  a,%11111111         ;bitmask black
582         or  a
583 ceilingloopdown:
584         ld  (hl),a              ;display black byte
585         add hl,de               ;go down
586         dnz ceilingloopdown     ;and loop >groundpos< times
587
588         ld  b,c                 ;pop b used by groundloopup
589         dnz ceilingloopright    ;loop right for entire screen (16x)
590         pop hl \ pop hl         ;restore stack
591         ret
592
593 CheckCeiling:                   ;check for collision with the ground
594         ld  a,(x)               ;your x
595         srl a                   ;x/2
596         srl a                   ;x/4
597         srl a                   ;x/8 (current ceiling-byte)
598         inc a                   ;correction
599
600         ld  l,a                 ;hl = a
601         ld  h,0                 ;"
602         ld  de,ceilingpos       ;first ceiling-byte
603         add hl,de               ;current ceiling-byte
604         ld  a,(y)               ;your y-pos
605         inc a
606         cp  (hl)                ;compare with ceiling
607         ret nc                  ;carry if ceiling is above you
608         ld  b,5
609         jp  damage_you          ;otherwise you don't wanna be in that ship
610
611 ;--------------------------- move stars -------------------------------------
612
613 DisplayStars:                   ;inputs: hl=starx# a=stars# b=nrstars#
614         ld  e,(hl)
615         inc hl
616         ld  d,(hl)
617         ld  (de),a
618         inc hl
619         dnz DisplayStars
620         ret                     ;let's comment this: returns
621
622 movestars2:
623         ld  ix,starx2
624         ld  a,(stars2)
625         rlca
626         ld  (stars2),a
627         ret nc
628         ld  b,nrstars2
629         jr  movestars_loop
630
631 movestars1:
632         ld  ix,starx1
633         ld  a,(timer)
634         rra
635         ld  a,(stars1)
636         ret c
637         rlca
638         ld  (stars1),a
639         ret nc
640         ld  b,nrstars1
641
642 movestars_loop:
643         ld  h,(ix+1)
644         ld  l,(ix)
645         dec hl
646
647         ld  a,l
648         and %00001111
649         cp  9                   ;(GRAPH_MEM&%00001111)-- = $C9FAand15-1 = $A-1
650         jr  nz,newstarok
651         cal Random5016
652
653 newstarok:
654         ld  (ix),l
655         ld  (ix+1),h
656         inc ix \ inc ix
657         dnz movestars_loop
658         ret                     ;for stupid people, here's another comment...
659
660 ;--------------------------- pause ------------------------------------------
661
662 Pause:
663         ld  hl,$0200            ;top left
664         ld  (_curRow),hl
665         ld  hl,txt_pressenter   ;"Enter to continue"
666         cal _puts               ;display message
667 pause:
668         cal _getkey             ;enter low-power mode and wait for key
669         cp  kEnter              ;keypressed = enter?
670         jr  nz,pause            ;no, wait some more
671         ret                     ;continue
672
673 ;--------------------------- teacher ----------------------------------------
674
675 Teacher:
676         ld  (iy+12),5           ;enable flashing cursor
677         cal _clrScrn
678         cal _homeup             ;top left
679         ld  hl,txt_teacher
680         cal _puts               ;display message
681
682 teacherloop:
683         cal _getkey             ;enter low-power mode and wait for key
684         cp  kEnter              ;enter pressed?
685         jr  z,teacherans
686         cp  kGrMenu             ;keypressed = graph?
687         jr  nz,teacherloop      ;no, wait some more
688
689         ld  (iy+12),0           ;disable cursor
690         jp  disp_icons          ;+ret
691
692 teacherans:
693         ld  a,' '
694         cal _putc
695
696         ld  hl,$0701
697         ld  (_curRow),hl
698         ld  hl,txt_teacherans
699         cal _puts
700         jr  teacherloop
701
702
703 ;--------------------------- exit -------------------------------------------
704
705 quit:
706         im  1                   ;release keyfix procedure
707         ld  (iy+13),3           ;use textshadow (TEXT_MEM) and scrolling
708
709         ld  hl,GRAPH_MEM        ;graph-screen location
710         ld  de,GRAPH_MEM+1
711         ld  (hl),0
712         ld  bc,1024-1           ;do it 1024 times = entire screen
713         ldir
714
715         jp  _clrWindow          ;as _clrLCD but also clears TEXT_MEM (like the
716                                 ;_clrScrn) AND also executes _homeup and ret
717
718 ;--------------------------- display ----------------------------------------
719
720 Display_Screen:
721         ld  hl,GRAPH_MEM        ;from storage (top left)
722         ld  de,VIDEO_MEM        ;to screen (top left)
723         ld  c,56                ;display height = 64 bytes (minus 8 for bar)
724 displayloop:
725         ld  b,16                ;display width = 16 bytes (16*8bits=256pixels)
726 displaytloop:
727         ld  a,(hl)              ;copy byte from (hl)
728 _invert:
729         cpl                     ;xor $ff: invert byte (white<=>black)
730         ld  (de),a              ;to (de)
731         inc hl \ inc de         ;next byte
732         dnz displaytloop        ;16x hl >> de
733         dec c                   ;next line
734         jr  nz,displayloop      ;loop 64x
735
736         ld  hl,$396b            ;Display Score
737         ld  (_penCol),hl        ;bottom right of screen
738         ld  hl,(score)
739
740 _D_HL_DECI:                     ;------- display 5-digit value -------
741         ld  de,savestr+4        ;savenr saves number string
742         ld  b,5                 ;five digits
743 ldhld:  cal UNPACK_HL           ;one digit of hl
744         add a,'0'               ;make number
745         ld  (de),a              ;save into savenr
746         dec de                  ;point to next digit
747         dnz ldhld               ;repeat for all digits
748
749         ld  hl,savestr          ;we (the program) saved the value righthere
750         jp  _vputs              ;the only thing left to do is to display it
751
752 savestr:                        ;@here the score will be stored
753         .db "00000",0           ;don't worry, it's just temporary
754
755 ;------------------------- handle ship --------------------------------------
756
757 Handle_Ship:
758         ld  a,(your_occ)        ;are
759         or  a                   ;you
760         jr  z,ok                ;ok?
761
762         inc a                   ;no! next (explosion)frame
763         ld  (your_occ),a        ;save
764
765         cp  34                  ;last explosion frame?
766         jp  c,exploding_you     ;not yet: display explosion
767         cp  40                  ;delay finished?
768         jp  z,You_die           ;yes = game over
769         ret                     ;don't display anything
770
771 ok:                             ;we are
772         ld  a,%01111110         ;get arrow keys
773         out (1),a               ;it's cold outside
774         ld  hl,y                ;instead of nop\nop do something usefull
775         in  a,(1)               ;come back in
776
777         ld  b,a                 ;psh a (keys)
778         xor %11111111           ;inverted a = 0 if arrow-key has been pressed
779         ld  a,(your_multiples)
780         jr  z,no_adv            ;if so, leave the multiples where they are
781         or  %100                ;set move bit
782         jr  adv_ok
783 no_adv: and %11111011           ;reset move bit
784
785 adv_ok: ld  (your_multiples),a
786
787         ld  a,(timer)           ;framecounter
788         and %1                  ;switches 0<>1 each frame
789         inc a                   ;a = 1 or 2 (1.5 avg)
790         ld  c,a                 ;c = your_speed
791
792         ld  a,b                 ;pop a (keys)
793         rra                     ;rotate right (put last bit in c)
794         ld  b,a                 ;we need a later
795
796         jr  c,no_down
797         ld  a,(hl)
798         add a,c
799         cp  50                  ;56-6 = bottom of screen
800         jr  nc,no_down
801         ld  (hl),a
802 no_down:
803         dec hl
804         rr  b                   ;because we now use b, it's rr instead of rra
805         jr  c,no_left
806         ld  a,(hl)
807         sub c                   ;<dec a> doesn't affect c-flag
808         jr  c,no_left           ;-1 = left side
809         ld  (hl),a
810 no_left:
811         rr  b
812         jr  c,no_right
813         ld  a,(hl)
814         add a,c
815         cp  122                 ;128-6 = right side
816         jr  nc,no_right
817         ld  (hl),a
818 no_right:
819         ld  d,(hl)
820         inc hl
821         rr  b
822         jr  c,no_up
823         ld  a,(hl)
824         sub c                   ;<dec a> doesn't affect carry-flag
825         jr  c,no_up             ;-1 = top of screen
826         ld  (hl),a              ;save new y
827
828 no_up:  ld  e,(hl)
829         ld  ix,spr_ship01       ;ship sprite
830         ld  hl,your_inv         ;invulnerable?
831         ld  a,(hl)              ;load time in a
832         or  a                   ;is it 0?
833         jr  z,handle_multiples  ;yes so ship = normal (display \ continue)
834
835         ld  a,(timer)           ;load frame nr.
836         and %00000111           ;a=0 once every four frames
837         jr  nz,not_time         ;a<>0 = not time to update counter
838         dec (hl)                ;decrease inv-time left
839 not_time:
840         and %00000100           ;a switches 0<->1 every 2 frames
841         jr  z,handle_multiples  ;show normal ship
842 inv_flicker:
843         ld  ix,spr_ship01i      ;don't display ship
844
845 handle_multiples:
846         cal putsprite           ;display your ship
847
848         ld  a,(your_multiples)  ;do you have multiples
849         ld  b,a                 ;save a for 2nd check
850         and %11                 ;no? (last two bits = nr of multiples)
851         ret z                   ;then don't handle them either
852
853         ld  hl,y
854         ld  a,b                 ;restore a (your_multiples)
855         and %100                ;move the multiples???
856         jr  z,mult_adv          ;nope, just let them (saves (y) in y, (x) in x)
857
858         ld  hl,your_locpos      ;location to save this position
859         ld  a,(hl)              ;load a
860         inc a                   ;a=a+1
861         and %00001111           ;if a>15 then a=a-16
862         ld  (hl),a              ;save new a
863         add a,a                 ;a=a*2
864         ld  c,a                 ;bc=2a
865         ld  b,0
866
867         ld  hl,your_prevpos     ;previous positions
868         add hl,bc               ;16 turns ago
869         ld  d,(hl)              ;old x-pos
870         inc hl                  ;and
871         ld  e,(hl)              ;old y-pos
872         ld  (mx),de             ;save multiple position in (mx)
873
874         ld  a,(y)               ;load new y-pos
875         ld  (hl),a              ;save it for 16 turns in the future
876         dec hl                  ;and
877         ld  a,(x)               ;load new x-pos
878         ld  (hl),a              ;save that too
879
880 mult_adv:
881  ld de,(mx)
882         ld  ix,spr_multiple     ;sprite of the multiple
883         jp  putsprite           ;display it + <ret>
884
885 exploding_you:
886         srl a                   ;half the framerate
887         dec a                   ;first frame is 1>inc>srl>dec = 0
888         ld  hl,x-1
889
890 explosion_stuff:
891         rra
892         add a,a
893         add a,a
894         add a,a
895         ld  c,a
896         ld  b,0
897         ld  ix,spr_explosion
898         add ix,bc
899         inc hl
900         ld  d,(hl)
901         inc hl
902         ld  e,(hl)
903         jp  putsprite
904
905 damage_you:                     ;damages you B points
906         ld  a,(your_inv)        ;invulnerability left?
907         or  a
908         ret nz                  ;return if inv>0
909         ld  hl,your_armor       ;armor left
910         ld  a,(hl)              ;load hp in A
911         sub b                   ;decrease hp by B
912         jp  m,no_armor          ;<0hp left so explode
913         ld  (hl),a              ;no, so save decreased hp
914         cal disp_armor          ;and display new value
915
916         ld  a,(your_pickup)     ;how many pickups do you have?
917         dec a                   ;is the armor-icon selected
918         ret nz                  ;return if not
919
920         psh de \ psh ix         ;&&& just2Bsave
921         ld  hl,VIDEO_MEM+(16*56)
922         ld  (PutWhere),hl
923         ld  ix,spr_icon         ;if so, highlight armorIcon again
924         ld  de,$1901            ;position
925         cal putwidesprite       ;display icon
926         ld  hl,GRAPH_MEM
927         ld  (PutWhere),hl
928         pop ix \ pop de
929         ret                     ;and return
930
931 no_armor:
932         ld  a,%01               ;occ %xxxxxx01 = explode
933         ld  (your_occ),a        ;set to explode
934         ret
935
936 ;------------------------- place multiples ----------------------------------
937
938 Place_multiples:
939         ld  (mx),de             ;set last multiple-position
940         ld  hl,your_prevpos     ;place all previous positions
941         ld  b,16                ;all 16 of them
942 place_multiples:
943         ld  (hl),d              ;set prev-x to d
944         inc hl                  ;next
945         ld  (hl),e              ;set prev-y to e
946         inc hl                  ;next
947         dnz place_multiples     ;repeat
948         ret
949
950 ;------------------------- select upgrade -----------------------------------
951
952 select:
953         ld  hl,your_pickup      ;select pickups
954         ld  a,(hl)              ;load pickups taken so far
955         dec a                   ;is it 1?
956         ret m                   ;return if it's 0 (no pickups)
957         jr  nz,select2          ;no, carry on
958 select1:
959         ld  a,(your_armor)      ;load current armor
960         cp  25-6                ;may not become >=25
961         jr  c,select1_          ;ok then just add 6
962         ld  a,25-6              ;set to maximum (6 will be added below)
963 select1_:
964         add a,6                 ;add 6 to armor
965         ld  (your_armor),a      ;change armor
966         xor a                   ;ld a,0
967         ld  (your_pickup),a     ;reset pickups
968         jp  disp_icons          ;display and return
969 select2:
970         dec a                   ;is it 2?
971         jr  nz,select3          ;no, carry on
972         ld  (hl),a              ;reset pickups
973         inc a                   ;a=1
974         ld  (torp_occ),a        ;ready torpedoes
975         jp  disp_icons          ;display 'n return
976 select3:
977         dec a                   ;is it 3?
978         jr  nz,select4          ;no, carry on
979         ld  (hl),a              ;reset pickups
980         ld  hl,your_weapon
981         ld  a,(hl)
982         inc a
983         cp  maxnrweapons
984         jp  nc,disp_icons       ;weapon maxed out
985         ld  (hl),a              ;set new weapon
986         cal loadweapon          ;load it (damage and stuff)
987         jp  disp_icons          ;display n return
988 select4:
989         dec a                   ;is it 4?
990         jr  nz,select5          ;no, carry on again
991         ld  (hl),a              ;reset pickups
992         inc a                   ;a=1
993         ld  (your_weapon),a     ;ready laser
994         jp  disp_icons          ;display + return
995 select5:
996         dec a                   ;is it 5?
997         jr  nz,select6          ;no, carry on once more
998         ld  (hl),a              ;reset pickups
999         inc a
1000         ld  (your_multiples),a
1001         ld  de,(x)
1002         cal Place_multiples
1003         jp  disp_icons          ;display, return
1004 select6:
1005         ld  (hl),0              ;reset pickups
1006         jp  disp_icons          ;display/return
1007
1008 ;------------------------- fire bullet --------------------------------------
1009
1010 Fire_bullet:
1011         ld  hl,just_fired
1012         ld  a,(hl)              ;just_fired
1013         cp  5                   ;already pressed?
1014         ret z                   ;return when already pressed (=5)
1015
1016         inc (hl)                ;otherwise increase counter (0 to 4 >> 1 to 5)
1017         ld  a,(your_weapon)     ;if you have bullets.....
1018         dec a                   ;(1=laser)
1019         jr  z,fireOK
1020         ld  (hl),5              ;.....then can't fire next turn (go to 5 imm.)
1021
1022 fireOK:
1023         ld  hl,(x)              ;yes: first fire from ship position (x)
1024         ld  (firex),hl          ;set firepos
1025         ld  a,(your_multiples)  ;any multiples?
1026         and %11                 ;nope?
1027         jr  z,fireany           ;then just fire somethin'
1028         cal fireany             ;and blast
1029         ld  hl,(my)             ;then, fire from multiple position (mx)
1030         ld  a,(mx)              ;<ex h,l>
1031         ld  h,a                 ; ^^^^^^
1032         ld  (firex),hl          ;set firepos
1033                                 ;blast again and <ret>
1034 fireany:
1035         cal fire_torp           ;&&&
1036
1037         ld  a,(your_weapon)     ;do you have laser?
1038         dec a                   ;1=yes
1039         jr  z,fire_laser
1040
1041         ld  ix,weapondata-6
1042         add a,a                 ;weap*2
1043         add a,a                 ;    *4
1044         add a,a                 ;    *8
1045         ld  c,a
1046         ld  b,0
1047         add ix,bc
1048
1049         ld  c,(ix)
1050         cal fire_ybullet
1051         inc ix
1052         inc ix
1053         ld  c,(ix)
1054         xor a
1055         cp  c
1056         cal nz,fire_ybullet
1057         inc ix
1058         inc ix
1059         ld  c,(ix)
1060         xor a
1061         cp  c
1062         cal nz,fire_ybullet
1063         ret
1064
1065 fire_torp:
1066         ld  de,(firex)
1067         ld  hl,torp_occ         ;torpedo...
1068         ld  a,(hl)              ;load torpInfo
1069         dec a                   ;do you have (unused) torpedoes?
1070         ret nz                  ;nope (a must be 1)
1071         ld  (hl),2              ;yes; use torpedo
1072         ld  (torp_pos),de       ;save torpedo position (in de)
1073         ret
1074
1075
1076 fire_laser:                     ;yes, fire that laser instead
1077         ld  a,(firex)           ;a = your x-pos
1078         ld  d,a
1079
1080         ld  hl,GRAPH_MEM        ;save-location
1081         ld  a,(firey)           ;y-coord
1082         add a,3                 ;at middle of your ship (y+3)
1083         ld  e,a                 ;save laser-y in e
1084         add a,a                 ;y*2
1085         add a,a                 ;y*4
1086         add a,a                 ;y*8
1087         rl  b                   ;b (=0) =b*2+overflow (if y>32 then bc=bc+256)
1088         add a,a                 ;y*16 (width of screen)
1089         rl  b                   ;b=b*2+overflow (if y>64 then bc=bc+512)
1090         inc a                   ;8 pixels to right (a=even so no overflow)
1091
1092         srl d                   ;X/2
1093         srl d                   ;X/4
1094         srl d                   ;X/8
1095         add a,d                 ;a = (Y*16+X/8) mod 256 (c set on overflow)
1096         jr  nc,_nolc            ;jump if no carry = no overflow = a<=255
1097         inc b                   ;a>255 so increase bc by 256
1098 _nolc:  ld  c,a                 ;c = (Y*16+X/8) mod 256
1099         add hl,bc               ;bc = Y*16+X/8
1100
1101         ld  a,15                ;128/8=16=screen width ** minus one (inc a ^^)
1102         sub d                   ;minus x-start (d=X/8)
1103         ld  b,a
1104 drawlaser:
1105         ld  (hl),%11111111
1106         inc hl                  ;Go to next byte
1107         dnz drawlaser
1108
1109 ;       ld  a,(just_fired)      ;fired for how long
1110 ;       cp  4                   ;if 4th turn
1111 ;       ret nz                  ;then do damage, otherwise quit
1112
1113 handle_laser:
1114         ld  a,(firex)
1115         ld  d,a                 ;d was divided, so reload the laser-x
1116
1117 check_laserhits:                ;de = (x,y)
1118         ld  b,nrenemies
1119         ld  hl,enemies+1
1120
1121 laserhits:                      ;Hits with normal enemies
1122         psh hl
1123
1124         ld  a,(hl)
1125         and %00000010
1126         jr  z,nolashit          ;no hit when enemy_occ <> 2/3
1127
1128         inc hl                  ;enemy type
1129         ld  a,(hl)
1130         or  a                   ;enemy #0 = pickup
1131         jr  z,nolashit          ;yes: don't destroy
1132
1133         inc hl
1134         ld  a,(hl)              ;check x
1135         sub d
1136         jp  m,nolashit          ;no hit when enemy is left of you
1137
1138         inc hl
1139         ld  a,(hl)              ;check y
1140         sub e
1141         jr  z,enemy_lashit      ;a-e=0 = laser on top line of enemy = hit
1142         jr  nc,nolashit         ;a-e>0 = enemy above laser = no hit
1143         add a,5                 ;add enemy height
1144         jp  p,enemy_lashit      ;a-e>0 = hit
1145
1146 nolashit:
1147         pop hl
1148         ld  a,b                 ;psh bc
1149         ld  bc,enemysize
1150         add hl,bc               ;go to next enemy
1151         ld  b,a                 ;pop bc
1152         dnz laserhits           ;check all enemies
1153         ret
1154
1155 enemy_lashit: ;&&&before nolashit
1156         ld  a,1                 ;damage
1157         cal enemy_hit
1158         jr  nolashit
1159
1160 fire_ybullet:
1161         ld  hl,ybullets
1162         ld  de,4
1163         ld  b,maxbullets
1164 find_ybullet:
1165         ld  a,(hl)
1166         or  a
1167         jr  z,found_ybullet     ;0 = no bullet here
1168         add hl,de
1169         dnz find_ybullet        ;look next bullet
1170         pop hl                  ;don't try to fire any other bullets
1171         ret                     ;so ret twice
1172
1173 found_ybullet:
1174         ld  (hl),c              ;use the bullet and set correct bullet-type
1175         inc hl                  ;@damage
1176         ld  (hl),1              ;set bullet damage
1177 curweapdamage =$-1
1178         ld  a,(firex)           ;your x-pos
1179         add a,5                 ;place bullet in front of you
1180         inc hl                  ;go to bullet-x
1181         ld  (hl),a              ;set x
1182
1183         ld  a,(firey)           ;your y-pos
1184         add a,(ix+1)            ;place bullet at the middle of your ship
1185         inc hl                  ;go to bullet-y
1186         ld  (hl),a              ;set y
1187
1188         xor a
1189         ld  (weapincs),a        ;reset damage
1190         ret
1191
1192 ;------------------------ handle bullets ------------------------------------
1193
1194 bullet_left:
1195         ld  a,124
1196         sub b
1197
1198         cp  (hl)                ;off screen? (x>128-5)
1199         jr  c,remove_bullet
1200         ld  a,(hl)              ;a = X
1201         add a,b                 ;move b to the right
1202         ld  (hl),a              ;save new pos.
1203         ld  d,a                 ;d = X
1204
1205         inc hl                  ;@y-pos
1206         ld  a,c
1207         cal _shracc
1208         dec a
1209         jr  z,bullet_noymove
1210         dec a
1211         jr  z,bullet_up
1212         dec a
1213         jr  z,bullet_halfup
1214         dec a
1215         jr  z,bullet_down
1216
1217 bullet_halfdown:
1218         ld  a,(timer)
1219         and 1
1220         jr  z,bullet_noymove
1221 bullet_down:
1222         ld  a,(hl)
1223         inc a
1224         cp  55
1225         jr  z,bullet_noymove
1226         ld  (hl),a
1227 bullet_halfup:
1228         ld  a,(timer)
1229         and 1
1230         jr  z,bullet_noymove
1231 bullet_up:
1232         ld  a,(hl)
1233         dec a
1234         jr  z,bullet_noymove
1235         ld  (hl),a
1236 bullet_noymove:
1237         ld  e,(hl)              ;e = Y
1238         ret
1239
1240 remove_bullet:
1241         pop hl                  ;cal bullet_left
1242         pop hl                  ;enemy+type
1243         ld  (hl),0              ;dump this bullet!
1244         jr  next_ybullet+1      ;+1:skip pop hl at next_ybullet
1245
1246 Handle_bullets:
1247         ld  hl,ybullets
1248         ld  b,maxbullets
1249 scan_bullets:
1250         psh bc                  ;bullet counter
1251         psh hl                  ;save enemy+type
1252         ld  (temp1),hl          ;needed for check_bullethits
1253         ld  a,(hl)              ;@bulletType
1254         inc hl                  ;@damage
1255         inc hl                  ;@x
1256
1257         or  a
1258         jp  z,next_ybullet      ;bulletType=0 >> no bullet
1259
1260         ld  c,a                 ;c=type
1261         and %1111
1262         ld  b,a                 ;b=0000type
1263         cal bullet_left         ;move bullet left
1264
1265 display_bullet:
1266         psh de                  ;save de =position
1267         dec hl                  ;@x
1268         dec hl                  ;@damage
1269         ld  a,(hl)              ;bullet damage=size
1270         ld  hl,XLbullettable    ;pointer to first bullet
1271         srl a
1272         srl a                   ;per 4
1273         inc a                   ;must be at least 1
1274 nextbulletlook:
1275         inc hl                  ;next bullet sprite pointer
1276         dec a                   ;for each 4 points of damage
1277         jr  nz,nextbulletlook
1278         ld  d,a                 ;ld d,0
1279         ld  a,(hl)              ;load pointer offset
1280         ld  e,a                 ;convert to 16bit
1281         ld  ix,spr_bullet01     ;first sprite
1282         add ix,de               ;add offset (go to correct sprite)
1283         pop de                  ;saved position
1284         psh de                  ;but will be altered so save again
1285         cal putsprite           ;display bullet
1286         pop de
1287
1288         cal check_bullethits
1289
1290 next_ybullet:
1291         pop hl                  ;restore enemy+type
1292         inc hl
1293         inc hl
1294         inc hl
1295         inc hl                  ;skip type,dam,x,y: next enemy+type
1296         pop bc                  ;b=counter
1297         dnz scan_bullets        ;next bullet (loop)
1298         ret
1299
1300 ;--------------------------- check bullethits -------------------------------
1301
1302 check_bullethits:               ;INPUT: de=X,Y; (temp1)=bullet
1303         ld  b,nrenemies
1304         ld  hl,enemies+1
1305
1306 hit_enemies:                    ;Hits with normal enemies
1307         psh bc                  ;enemy counter
1308         psh hl
1309
1310         ld  a,(hl)
1311         and %00000010
1312         jr  z,nohit             ;no hit when enemy_occ <> 2/3
1313
1314         inc hl                  ;enemy type
1315         ld  a,(hl)
1316         or  a                   ;enemy #0 = pickup
1317         jr  z,nohit             ;yes: don't destroy
1318
1319         psh de
1320         cal find_sprite
1321         pop de
1322
1323         inc hl
1324         ld  a,(hl)              ;check x
1325         sub d
1326         sub 5
1327         jp  p,nohit
1328         add a,5
1329         add a,(ix)
1330         jp  m,nohit
1331
1332         inc hl
1333         ld  a,(hl)              ;check y
1334         sub e
1335         sub 3
1336         jp  p,nohit
1337         add a,3
1338         add a,(ix+1)
1339         jp  m,nohit
1340
1341         psh hl
1342         ld  hl,0                ;@bulletType
1343 temp1 =$-2
1344         ld  (hl),0              ;remove bullet
1345         inc hl                  ;@damage
1346         ld  a,(hl)              ;set damage
1347         pop hl                  ;enemy+y
1348         cal enemy_hit
1349 nohit:
1350         pop hl
1351         ld  bc,enemysize
1352         add hl,bc
1353         pop bc
1354         dnz hit_enemies ;check next enemy
1355         ret
1356
1357 enemy_hit:              ;in:a=damage;hl=enemy+y
1358         add a,a                 ;a=damage to inflict
1359         add a,a                 ;first 2 bits used for occ.
1360         ld  b,a
1361
1362         dec hl                  ;@x
1363         dec hl                  ;@type
1364         dec hl                  ;@hp00 (occ)
1365         ld  a,(hl)              ;load hp00
1366         sub b                   ;decrease HP (if <0xx then c is set)
1367         ld  (hl),a              ;save (no flag-changes)
1368         dec hl                  ;@hp64; no change in c
1369         ld  a,(hl)              ;load; no c-change
1370         sbc a,0                 ;if cf then decrease a
1371         ld  (hl),a              ;save back the new value
1372         ret nc                  ;if a>=0 then return, otherwise explode
1373
1374         inc hl                  ;goto occ again
1375         ld  (hl),%01            ;set to explode
1376         ld  a,(pickuptimer)     ;counts enemies destroyed
1377         dec a                   ;enough destroyed for a pickup?
1378         jr  nz,pickupdone       ;otherwise just explode
1379         ld  (hl),%110           ;change it into a pickup (with 2 HP)
1380         ld  a,18                ;reset enemies counter (18 hits = next)
1381 pickupdone:
1382         ld  (pickuptimer),a     ;save new enemiescounter value
1383         inc hl
1384         ld  (hl),$00            ;explosionFrame 0
1385
1386         ld  hl,1                ;increase score by one
1387         jp  scoreInc            ;+ret
1388
1389 ;--------------------------- handle torpedo ---------------------------------
1390
1391 Handle_torp:
1392         ld  a,(torp_occ)
1393         sub 2
1394         ret m                   ;return if occ=0/1
1395
1396         ld  hl,torp_pos         ;x-position
1397         ld  a,(hl)              ;load in a
1398         inc a                   ;move right
1399         cp  125                 ;right edge reached
1400         jr  nc,remove_torp      ;remove if x>125
1401         ld  (hl),a              ;save new x
1402         ld  d,a
1403
1404         inc hl                  ;y-position
1405         ld  a,(hl)
1406         inc a                   ;move down
1407         cp  56                  ;bottom reached
1408         jr  nc,remove_torp      ;remove if y>40
1409         ld  (hl),a              ;save new y
1410         ld  e,a
1411
1412         ld  ix,spr_bullett1
1413         psh de
1414         cal putsprite           ;display torpedo
1415         pop de
1416         jp  check_bullethits    ;check for hits with enemies
1417
1418 remove_torp:
1419         ld  a,1
1420         ld  (torp_occ),a
1421         ret
1422
1423 ;--------------------------- level events -----------------------------------
1424
1425 Level_event:
1426         ld  hl,nextevent        ;time to next event     <ld  a,(nextevent)
1427         dec (hl)                ;decrease counter       <dec a
1428         ld  a,(hl)              ;look at counter        <ld  (nextevent),a
1429         or  a                   ;has it reached zero?
1430         ret nz                  ;nope: get outta here!
1431
1432         ld  a,(eventtime)       ;enemy frequency (lvl)
1433         ld  (nextevent),a       ;set time to next event
1434         ld  hl,eventleft
1435         dec (hl)                ;update enemy-counter
1436
1437         ld  a,(hl)              ;look at counter
1438         or  a                   ;has it reached 0?
1439         jp  z,Next_level        ;yes: level finished
1440         dec a                   ;has it reached 1?
1441         jr  z,standby_event     ;yes: wait until no enemies present/left
1442         dec a                   ;has it reached 2?
1443         jr  z,place_boss        ;yep: place the BigBossTM!
1444         dec a                   ;has it reached 3?
1445         jr  nz,do_event         ;nope: >3 = place an enemy
1446         inc hl                  ;nextevent located behind eventleft
1447         ld  (hl),123            ;set delay
1448         ret                     ;don't place any more enemies
1449
1450 place_boss:
1451         ld  hl,(levelp)         ;the leveldata (including the boss)
1452         dec hl                  ;points to leveldata\boss\enemynr
1453         ld  a,(hl)              ;load it
1454         ld  (level_enemy),a     ;set new enemy (boss)
1455         dec hl                  ;points to level\boss\movement
1456         ld  a,(hl)              ;load
1457         ld  (level_move),a      ;set boss movement
1458         dec hl                  ;@level\boss\firefreq
1459         ld  a,(hl)              ;load in a
1460         ld  (level_fire),a      ;set firefrequency
1461         jp  do_event            ;+ret
1462
1463 standby_event:
1464         ld  b,nrenemies
1465         ld  hl,enemies+1-enemysize
1466         ld  de,enemysize
1467 chk_enemyleft:
1468         add hl,de
1469         ld  a,(hl)
1470         or  a                   ;0 = no enemy present
1471         jr  nz,enemyleft
1472         dnz chk_enemyleft
1473         ret
1474 enemyleft:
1475         ld  hl,eventleft
1476         inc (hl)
1477         ret
1478
1479
1480 do_event:
1481         ld  hl,enemies+1-enemysize
1482         ld  bc,enemysize
1483         xor a                   ;a=0
1484 chk_noenemy:
1485         add hl,bc
1486         cp  (hl)                ;(hl) = 0 ??
1487         jr  nz,chk_noenemy      ;jump if enemy present (non-0)
1488         ex  de,hl               ;de=hl=usable enemy
1489
1490 place_enemy:
1491         ld  a,(level_enemy)     ;enemy type to place (lvl)
1492         ld  hl,XLenemyinfos-4   ;enemy "0" specs (1 before enemy #1)
1493         add a,a                 ;a=type*2
1494         add a,a                 ;a=type*4
1495         ld  c,a                 ;c=type
1496         ld  b,0                 ;bc = enemy nr.&&&XX
1497         add hl,bc               ;hl = enemy specs
1498         ld  a,(hl)              ;load hitpoints+occ of this enemy class
1499         ld  (de),a              ;save occ
1500
1501         inc hl                  ;next enemyInfo byte
1502         dec de                  ;goto hp
1503         ld  a,(hl)              ;load hp64
1504         ld  (de),a              ;save hp64
1505         inc de                  ;next byte (or previous): occ again
1506
1507         inc hl                  ;next enemyInfo byte
1508         inc de                  ;next byte of current enemy
1509         ld  a,(hl)              ;load enemy class (nr)
1510         ld  (de),a              ;save enemy type
1511
1512         inc de                  ;set x-pos
1513         psh de
1514         cal find_sprite
1515         pop de
1516         ld  a,128               ;appear at right edge of screen
1517         sub (ix)                ;minus the width of this enemy (not offscreen)
1518         ld  (de),a              ;= x-position (save)
1519
1520         inc de                  ;set y-pos
1521         inc hl                  ;where to place??
1522         ld  a,(hl)              ;load placeInfo
1523         dec a                   ;is it 1?
1524         jr  z,random_enemy      ;yes: create random value <51 in a
1525         dec a                   ;is it 2?
1526         jr  z,lure_enemy        ;yes: create a 100% luring enemy
1527                                 ;otherwise?
1528 halflure_enemy:                 ;yes (of course it is): pick one (50% lure)
1529         ld  a,(timer)           ;look at frame-number
1530         and %00000001           ;make random if odd frame nr.
1531         jr  nz,random_enemy     ;1st possibility: random enemy
1532 lure_enemy:                     ;2nd possibility: luring enemy
1533         ld  a,(y)               ;place at same y-pos as YOUR ship
1534         jr  ypos_OK
1535
1536 random_enemy:
1537         ld  b,e                 ;b will be added to random-value
1538         cal Random50            ;make a (in a) random value 0-51
1539
1540 ypos_OK:                        ;random value successfully created
1541         ld  (de),a              ;save y-position
1542
1543         inc de                  ;set move
1544         ld  a,1                 ;movecounter = 1
1545         ld  (de),a              ;&&&(hl),1 better?
1546
1547         inc de                  ;set fire
1548         ld  a,(level_info)
1549         and %00000001           ;bit meaning directfire
1550         jr  nz,ffireOK          ;(a=time-to-fire) = 1 frame (fires directly)
1551         ld  a,(level_fire)      ;set ttf to normal nr of frames
1552 ffireOK:ld  (de),a              ;save fire
1553         ret                     ;return
1554
1555 ;--------------------------- enemy fires ------------------------------------
1556
1557 Enemy_fires:                    ;de = x,y
1558         dec d
1559         dec d                   ;d = x-2
1560         inc e                   ;e = y+1
1561
1562         ld  b,nrebuls
1563         ld  hl,ebullets
1564 find_ebullet:
1565         ld  a,(hl)
1566         or  a
1567         jr  z,found_ebullet     ;0 = not used
1568         inc hl \ inc hl \ inc hl
1569         dnz find_ebullet        ;look next bullet
1570         ret
1571
1572 found_ebullet:
1573         ld  b,%1100
1574         ld  a,(level_info)
1575         and %00001000
1576         jr  z,bulletok
1577
1578         ld  a,(y)
1579         sub e
1580         add a,10
1581         jp  p,bulletnotup
1582         ld  b,%1011             ;yourY-bulY = negative (=bullet below you)
1583         add a,10
1584         jp  p,bulletnotup
1585         ld  b,%1001             ;yourY-bulY = even more negative (going up)
1586
1587 bulletnotup:
1588         sub 20
1589         jp  m,bulletok
1590         ld  b,%1010             ;bullet going down
1591         sub 10
1592         jp  m,bulletok          ;even more going down
1593         ld  b,%1000
1594
1595 bulletok:
1596         ld  a,(level_info)
1597         and %11110000
1598         or  b
1599         ld  (hl),a              ;set bullet direction
1600         inc hl
1601         ld  (hl),d              ;set x-pos
1602         inc hl
1603         ld  (hl),e              ;set y-pos
1604         ret
1605
1606 ;----------------------------- enemy bullets --------------------------------
1607
1608 Enemy_bullets:
1609         ld  hl,ebullets
1610         ld  b,nrebuls
1611 handle_bullet:
1612         psh bc
1613         psh hl
1614         ld  a,(hl)              ;load bulletType in a
1615         and %1111               ;select direction-bits
1616         jr  nz,enemy_bullet     ;non-0: handle bullet
1617 next_bullet:
1618         pop hl                  ;do not move the <pop hl>
1619         pop bc
1620         inc hl \ inc hl \ inc hl
1621         dnz handle_bullet
1622         ret
1623
1624 enemy_bullet:
1625         ld  b,a                 ;save type&%1111
1626         inc hl                  ;bullet x
1627         ld  a,(hl)              ;check if it has reached the left side of scrn
1628         and %11111110           ;it is <2 (0 or 1)?
1629         jr  z,remove_ebullet    ;yes, remove bullet
1630         dec (hl)                ;move one left
1631         dec (hl)                ;and another one
1632         ld  d,(hl)              ;d=x
1633         inc hl                  ;@y
1634
1635         ld  a,b                 ;restore type
1636         cp %1100                ;is it a normal bullet? (cp = faster than bit)
1637         jr  z,ebullet_common    ;type %1100: normal bullet
1638         and %111                ;isolate important bits
1639         jr  z,ebullet_down      ;type %1000: moving down
1640         dec a
1641         jr  z,ebullet_up        ;type %1001: moving up
1642         ld  b,a
1643
1644         ld  a,(timer)
1645         rra
1646         jr  c,ebullet_common
1647
1648         ld  a,b
1649         dec a
1650         jr  z,ebullet_down      ;type %1010: moving down 50%
1651                                 ;type %1011: moving up 50%
1652 ebullet_up:
1653         ld  a,(hl)
1654         dec a
1655         jp  m,ebullet_common
1656         ld  (hl),a
1657         jr  ebullet_common
1658
1659 ebullet_down:
1660         ld  a,(hl)
1661         inc a
1662         cp  55
1663         jr  z,ebullet_common
1664         ld  (hl),a
1665
1666 ebullet_common:
1667         ld  e,(hl)              ;e=y
1668         ld  ix,spr_bullete1     ;display enemy bullet
1669         cal putsprite
1670
1671 ebullet_hits:
1672         ld  a,(your_occ)
1673         or  a
1674         jr  nz,next_bullet      ;0 = you're normal
1675
1676         pop hl
1677         psh hl
1678         inc hl                  ;check x
1679         ld  a,(x)
1680         sub (hl)
1681         add a,6
1682         jp  m,next_bullet
1683         cp  9
1684         jr  nc,next_bullet
1685
1686         inc hl                  ;check y
1687         ld  a,(y)
1688         sub (hl)
1689         add a,6
1690         jp  m,next_bullet
1691         cp  9
1692         jr  nc,next_bullet
1693
1694         pop hl                  ;points to bullettype again
1695         psh hl                  ;and save it again (ivm call to damage_you)
1696         ld  a,(hl)              ;load bullettype
1697         cal _shracc             ;isolate damage-bits (%1111???? -> %00001111)
1698         ld  b,a                 ;set damage-amount
1699         cal damage_you          ;HIT!!
1700 remove_ebullet:
1701         pop hl                  ;hl could be destroyed by damage_you
1702         ld  (hl),0              ;bullet > unused
1703         jr  next_bullet+1       ;next bullet (SKIP THE <POP HL> = one byte)
1704
1705 ;--------------------------- handle enemies ---------------------------------
1706
1707 Handle_enemies:
1708         ld  hl,enemies+1
1709         ld  b,nrenemies         ;handle all enemies
1710
1711 handle_enemy:
1712         psh bc
1713         psh hl
1714
1715         ld  a,(hl)
1716         and %00000011
1717         jr  z,next_enemy        ;occ "no enemy" 0
1718         dec a
1719         jr  z,exploding_enemy   ;occ "exploding" 1
1720         ld  b,a                 ;b=2 if moving, otherwise b=1
1721
1722 normal_enemy:                   ;occ "normal" 2 or "moving" 3
1723         inc hl
1724         ld  c,(hl)              ;c = enemy type = de
1725         cal find_sprite
1726
1727         inc hl
1728         ld  a,(hl)              ;x
1729         dec a                   ;move left
1730         jr  c,remove_enemy      ;off screen
1731         jr  z,remove_enemy      ;"
1732         ld  d,a
1733
1734         inc hl
1735         ld  e,(hl)              ;y
1736         ld  a,b                 ;moving state was stored in b earlier
1737         dec a                   ;is it 1?
1738         cal nz,moving_enemy     ;2 = moving enemy
1739
1740         ld  (hl),e
1741         dec hl                  ;@x
1742         ld  (hl),d              ;store new x
1743         ld  a,c                 ;a = enemy type
1744         or  a                   ;type 0? (pickup)
1745         jr  nz,check_enemyfire  ;no, a normal enemy; let em fire
1746         ld  a,(timer)           ;load time
1747         and %1                  ;move left once every 2 turns
1748         jr  z,firing_done       ;don't move now
1749         inc d                   ;increase x-position (don't move this turn)
1750         inc (hl)                ;and save it
1751         jr  firing_done         ;continue
1752
1753 check_enemyfire:
1754         inc hl                  ;go to <y>
1755         inc hl                  ;go to <move>
1756         inc hl                  ;go to <fire>
1757         dec (hl)                ;decrease counter till next blast
1758         ld  a,(hl)              ;&&&doesn't seem efficient to me
1759         or  a                   ;has it reached zero?
1760         jr  nz,firing_done      ;finished if not
1761
1762         ld  a,(level_fire)      ;re-set counter for next blast
1763         ld  (hl),a              ;save time to fire
1764         inc hl                  ;next byte = bullettype &&&
1765         psh de                  ;save registers for firing-use
1766         cal Enemy_fires         ;fires bullet
1767         pop de                  ;restore (destroyed by Enemy_fires)
1768 firing_done:
1769         cal putwidesprite       ;display sprite @ix
1770
1771 next_enemy:
1772         pop hl
1773         ld  bc,enemysize
1774         add hl,bc
1775         pop bc
1776         dnz handle_enemy
1777         ret
1778
1779 remove_enemy:
1780         pop hl
1781         ld  (hl),$0000          ;bye bye enemy
1782         jr  next_enemy+1        ;continue AFTER pop hl (already done)
1783
1784 exploding_enemy:
1785         inc hl
1786         psh hl
1787         ld  a,(hl)
1788         cal explosion_stuff     ;display explosion
1789         pop hl
1790
1791         ld  a,(hl)
1792         cp  15
1793         jr  z,remove_enemy      ;remove when at last frame
1794         inc a
1795         ld  (hl),a              ;next frame
1796         jr  next_enemy
1797
1798 ;--------------------------- moving enemies ---------------------------------
1799
1800 moving_enemy:
1801         ld  a,(level_move)
1802         and a
1803         jr  z,movetype_updown   ;type 0
1804         dec a
1805         jr  z,movetype_vslow    ;1
1806         dec a
1807         jr  z,movetype_fast     ;2
1808         dec a
1809         jr  z,movetype_vfast    ;3
1810         dec a
1811         jr  z,movetype_smart    ;4
1812         dec a
1813         jr  z,movetype_lure     ;5
1814         dec a
1815         jr  z,movetype_slowlure ;6
1816         dec a
1817         jr  z,movetype_stoplure ;7
1818 ;       dec a
1819 ;       jr  z,movetype_fulllure ;8
1820
1821 movetype_fulllure:
1822         inc d
1823         ld  a,(timer)
1824         and 1
1825         ret z
1826         cal movetype_lure
1827         ld  a,(x)
1828         cp  d
1829         jr  c,lure_left
1830 lure_right:
1831         inc d
1832         ret
1833 lure_left:
1834         dec d
1835         ret
1836
1837 movetype_stoplure:
1838         inc d
1839         jr  movetype_slowlure
1840
1841 movetype_slowlure:
1842         ld  a,(timer)
1843         and 1
1844         ret z
1845
1846 movetype_lure:
1847         ld  a,(y)
1848         cp  e
1849         jr  c,lure_up
1850 lure_down:
1851         inc e
1852         ret
1853 lure_up:
1854         dec e
1855         ret
1856
1857 movetype_smart:
1858         inc hl                  ;hl =@ <move>
1859         ld  a,(timer)
1860         and %1111               ;     |
1861         ld  a,(hl)              ;&&& \|/
1862         jr  nz,smartupdate
1863         inc a
1864 smartupdate:
1865         ld  (hl),a
1866
1867         or  a                   ;reset carry flag
1868         dec hl                  ;reset hl to <y>
1869         and %11111100
1870         jr  z,movetype_fast
1871
1872 movetype_vslow:
1873         ld  a,(timer)
1874         and %11
1875         ret z
1876         inc d
1877         ret
1878
1879 movetype_fast:
1880         ld  a,(timer)
1881         and %1
1882         ret z
1883 movetype_vfast:
1884         dec d                   ;move left
1885         ret nz                  ;finished
1886         pop hl                  ;restore stack (no ret used)
1887         jp  remove_enemy        ;remove this enemy (off screen)
1888
1889 movetype_updown:
1890         inc hl                  ;@ <move>
1891         ld  a,(hl)
1892         dec a
1893         jr  nz,move_updated
1894         add a,128
1895 move_updated:
1896         ld  (hl),a
1897
1898         or  a                   ;reset carry flag
1899         dec hl                  ;@ <y>
1900         and %00100000
1901         ld  a,(hl);&&&ld a,e    ;load current y-position
1902         jr  z,movedown
1903
1904 moveup: dec a                   ;decrease y-pos (=move up)
1905         ret m                   ;don't move off the screen (y<0)
1906         dec e                   ;save new y-pos
1907         ret                     ;finish
1908 movedown:
1909         inc a                   ;increase y-pos
1910         cp  55                  ;compare with bottom
1911         ret nc                  ;return if it has passed that line (>40)
1912         inc e                   ;otherwise save new position
1913         ret                     ;and return
1914
1915 ;--------------------------- check collision --------------------------------
1916
1917 Enemies_hit:
1918         ld  hl,(x)              ;e = X, d = Y
1919         ld  de,$0707            ;add 7 to both d and e
1920         add hl,de
1921         ld  d,h
1922         ld  e,l                 ;e = X+7, d = Y+7
1923
1924         ld  hl,enemies+1
1925         ld  b,nrenemies         ;check all 20 enemies
1926 check_collision:
1927         psh hl
1928         ld  a,(hl)
1929         and %00000010
1930         jr  z,check_next        ;2 or 3 = ok
1931         inc hl
1932
1933 collide_enemy:                  ;&&& include in Handle_enemy proc
1934         psh de
1935         cal find_sprite
1936         pop de
1937
1938         inc hl
1939         ld  a,(hl)              ;check x match
1940         sub e                   ;enemy position minus yours minus 7
1941         jp  p,check_next
1942         add a,6
1943         add a,(ix)
1944         jp  m,check_next
1945
1946         inc hl
1947         ld  a,(hl)              ;check y match
1948         sub d                   ;same as with x-check
1949         jp  p,check_next
1950         add a,6
1951         add a,(ix+1)
1952         jp  m,check_next
1953         dec hl
1954         dec hl
1955
1956 take_pickup:
1957         psh hl                  ;we need hl
1958         ld  hl,2                ;increase score by 2
1959         cal scoreInc
1960         pop hl                  ;we're done
1961
1962         ld  a,(hl)              ;load enemy type
1963         or  a
1964         jr  nz,collide          ;enemy when <>0
1965
1966         psh hl
1967         ld  hl,your_pickup      ;your pickups
1968         ld  a,(hl)              ;current
1969         inc a                   ;go to next
1970         cp  6                   ;pickups >=6
1971         jr  c,not_maxpickup
1972         ld  a,1                 ;yes: reset to pickup 1
1973 not_maxpickup:
1974         ld  (hl),a              ;save new
1975         cal disp_icons          ;display altered pickupicons
1976         pop hl
1977
1978         dec hl                  ;to enemy occ
1979         xor a                   ;set to 0 = gone
1980         ld  (hl),a              ;remove
1981         jr  check_next          ;all done, next..
1982
1983 destroy_enemy:
1984         ld  (hl),%01            ;set to explode
1985         inc hl
1986         ld  (hl),0              ;explosionFrame 0
1987         jr  collide_done
1988
1989 collide:
1990         dec hl
1991         ld  a,(hl)
1992         and %11111100
1993         jr  z,destroy_enemy
1994         ld  a,(hl)
1995         sub %00000100
1996         ld  (hl),a
1997 collide_done:
1998         ld  b,4                 ;damage
1999         cal damage_you
2000
2001 check_next:
2002         pop hl
2003         ld  a,b                 ;psh bc
2004         ld  bc,enemysize
2005         add hl,bc
2006         ld  b,a                 ;pop bc
2007         dnz check_collision
2008         ret
2009
2010 ;--------------------------- story ------------------------------------------
2011
2012 storyPage:
2013         psh hl
2014         cal _clrLCD
2015         pop hl
2016 storyLine:
2017         inc hl
2018         ld  e,(hl)
2019         inc hl
2020         ld  d,(hl)
2021         ld  (_penCol),de
2022         inc hl
2023         cal _vputs
2024
2025         ld  a,(hl)
2026         dec a
2027         jr  z,storyLine
2028
2029         psh hl
2030         ld  hl,VIDEO_MEM
2031         ld  de,GRAPH_MEM
2032         ld  bc,1024
2033         ldir
2034         cal _clrLCD
2035         pop hl
2036
2037         inc hl
2038         ld  a,(hl)
2039         inc hl
2040         ld  b,(hl)
2041         psh hl
2042         cal DoSFX
2043         cal _getkey
2044         pop hl
2045         ret
2046
2047 dostory:
2048         cal storyPage                   ;do some story
2049         inc hl                          ;look at next hl
2050         ld  a,(hl)                      ;load in a
2051         dec hl                          ;restory hl
2052         inc a                           ;set z-flag if a = $ff
2053         jr  nz,dostory                  ;otherwise loop
2054
2055         ld  bc,5                        ;story ends
2056         add hl,bc                       ;set hl to beginning of the level
2057         ld  (levelp),hl                 ;set the level-pointer
2058         ret                             ;and return
2059
2060 ;--------------------------- SFX --------------------------------------------
2061
2062 CDoSFX:
2063         ld  hl,VIDEO_MEM
2064         ld  de,GRAPH_MEM
2065         ld  bc,1024
2066         ldir
2067         ld  b,64
2068         ld  a,-1
2069
2070 DoSFX:                          ;ins: a=beginLine b=nrOfLines
2071         ld  (curline),a
2072 SFXframe:
2073         psh bc
2074
2075         ld  a,(curline)         ;get line number
2076         inc a                   ;go to the next line
2077         ld  (curline),a         ;update
2078
2079         ld  l,a
2080         ld  h,0
2081         add hl,hl
2082         add hl,hl
2083         add hl,hl
2084         add hl,hl
2085
2086         ld  b,h                 ;save hl for later
2087         ld  c,l
2088
2089         ld  de,VIDEO_MEM
2090         add hl,de               ;go to ymin
2091         ld  d,h
2092         ld  e,l
2093
2094         ld  hl,GRAPH_MEM
2095         add hl,bc               ;hl->logo
2096
2097         ld  a,(curline)         ;Calculate how many lines to draw
2098         ld  c,a
2099         ld  a,64
2100         sub c
2101         ld  b,a
2102
2103 SFXdisp:                        ;display this frame on screen
2104         ld  a,b                 ;psh b (a will not be used)
2105         ld  bc,16               ;one line (=16 bytes, you'd know by now)
2106         ldir                    ;display (copy actually)
2107         ld  bc,-16              ;go up one line (not on screen)
2108         add hl,bc               ;so the same line will be displayed
2109         ld  b,a                 ;pop b
2110         dnz SFXdisp             ;repeat until whole screen is displayed
2111
2112         ld  b,8
2113 SFXdelay:
2114         halt
2115         dnz SFXdelay
2116
2117         pop bc
2118         dnz SFXframe
2119         ret
2120
2121 ;--------------------------- show icon --------------------------------------
2122
2123 drawline:
2124         ld  (hl),a              ;draw one piece of the divider-line
2125         inc hl                  ;move right (8 pixels = 1 byte)
2126         dnz drawline            ;repeat (16bytes * 8pixels =128= screen width)
2127         ret
2128
2129 disp_icons:
2130  psh bc \ psh de \ psh hl \ psh ix ;&&&
2131
2132         ld  hl,VIDEO_MEM+(16*56);56 rows down = eight rows from bottom
2133         ld  (PutWhere),hl       ;place icons at bottom of normal screen
2134         ld  b,16                ;draw 16x (screen width)
2135         ld  a,%11111111         ;horizontal line mask
2136         cal drawline            ;draw divider-line
2137
2138         ld  b,16*7              ;draw 16x (screen width) 7x (height)
2139         xor a                   ;blank line mask
2140         cal drawline            ;clear scorebar
2141
2142         cal disp_lives
2143
2144         ld  ix,spr_icon01       ;armorIcon
2145         ld  de,$1901            ;icon #1
2146         cal putwidesprite       ;display icon
2147         cal disp_armor          ;display bar
2148
2149         ld  ix,spr_icon00
2150         ld  a,(torp_occ)
2151         or  a
2152         jr  z,no_torp
2153         ld  ix,spr_icon02       ;torpedoIcon
2154 no_torp:
2155         ld  de,$2901            ;icon #2
2156         cal putwidesprite       ;display
2157
2158         ld  ix,spr_icon03       ;bulletIcon
2159         ld  de,$3901            ;icon #3
2160         cal putwidesprite       ;display icon
2161         ld  hl,$3945            ;position to display bullet-type digit
2162         ld  a,(your_weapon)     ;digit
2163         dec a                   ;minus one (1=laser)
2164         ld  (_penCol),hl        ;set location
2165         add a,'0'               ;make digit
2166         cal _vputmap            ;display char
2167
2168         ld  ix,spr_icon00       ;emptyIcon
2169         ld  a,(your_weapon)
2170         dec a
2171         jr  nz,no_laser
2172         ld  ix,spr_icon04       ;laserIcon
2173 no_laser:
2174         ld  de,$4901            ;icon #4
2175         cal putwidesprite
2176
2177         ld  ix,spr_icon00       ;emptyIcon
2178         ld  a,(your_multiples)
2179         and %11
2180         jr  z,no_multiples
2181         ld  ix,spr_icon05
2182 no_multiples:
2183         ld  de,$5901            ;icon #5
2184         cal putwidesprite
2185
2186         ld  ix,spr_dividerline
2187         ld  de,$6901
2188         cal putwidesprite
2189
2190         ld  a,(your_pickup)     ;pickups taken
2191         add a,a                 ;picks*2 (sets z-flag)
2192         jr  z,iconsdone         ;return if no pickups
2193         add a,a                 ;picks*4
2194         add a,a                 ;picks*8
2195         add a,a                 ;picks*$10
2196         add a,$09               ;add 0ah
2197         ld  d,a                 ;y-pos = picks * $10 + $0a (19,29,39,49,59)
2198         ld  e,$01               ;x-pos = bottom (1a01,2a01,3a01,4a01,5a01)
2199
2200         ld  ix,spr_icon
2201         cal putwidesprite
2202 iconsdone:
2203         ld  hl,GRAPH_MEM        ;normal game-screen
2204         ld  (PutWhere),hl       ;set sprite-position to normal screen
2205
2206  pop ix \ pop hl \ pop de \ pop bc
2207         ret
2208
2209 disp_armor:
2210         ld  hl,(57*16)+VIDEO_MEM+3
2211         ld  b,3
2212 armorbarclr:
2213         dec hl
2214         ld  (hl),0
2215         dnz armorbarclr
2216
2217         ld  a,(your_armor)      ;load your armor
2218         ld  c,a                 ;psh a
2219         srl a                   ;/2
2220         srl a                   ;/4
2221         srl a                   ;/8: don't display last 2 bits of a (later)
2222         jr  z,noarmorbar        ;if a=0 then it would loop 256x so skip it
2223         ld  b,a                 ;loop b=a times
2224 armorbar:                       ;starting at ($39*16)+VIDEO_MEM
2225         ld  (hl),%11111111      ;draw a piece of the bar
2226         inc hl                  ;next position
2227         dnz armorbar            ;loop it b times
2228
2229 noarmorbar:
2230         ld  a,c                 ;pop a
2231         and %111                ;display last bits of armor
2232         ret z                   ;if armor=0 then bit = %00000000 (don't disp)
2233         ld  b,a                 ;into B
2234         xor a                   ;bit = %00000000
2235 armorbarbit:
2236         scf                     ;set carry flag
2237         rra                     ;rotates A right and sets bit 7 (c-flag)
2238         dnz armorbarbit         ;repeat B times (so if B=6 then a=%11111100)
2239 armorbarready:                  ;               (an if B=3 then a=%11100000)
2240         ld  (hl),a              ;draw this last byte
2241         ret
2242
2243 disp_lives:
2244         ld  hl,$3A00            ;display Lives
2245         ld  (_penCol),hl        ;bottom left
2246         ld  hl,savestr+2
2247         ld  (hl),'L'
2248         inc hl
2249         ld  (hl),'x'
2250         inc hl
2251
2252         ld  a,(your_lives)      ;nr of lives in a
2253         add a,'0'               ;make digit
2254         ld  (hl),a
2255         dec hl \ dec hl
2256         jp  _vputs              ;display on screen +ret
2257
2258 ;--------------------------- proc -------------------------------------------
2259
2260 Random5016:
2261         cal Random50            ; a = 0..50
2262         inc a                   ; a = 1..51
2263         ld  h,0
2264         ld  l,a                 ;hl = 1..51
2265         add hl,hl               ;hl = 1..51 * 2
2266         add hl,hl               ;hl = 1..51 * 4
2267         add hl,hl               ;hl = 1..51 * 8
2268         add hl,hl               ;hl = 1..51 * 16 (left side at random y)
2269         dec hl                  ;hl = 1..51 * 16 (" at right side of screen)
2270         ld  de,GRAPH_MEM
2271         add hl,de               ;position on screen
2272         ret
2273
2274 Random50:
2275         cal Random
2276         cp  51                  ;y may not be more than 50
2277         ret c                   ;OK if a<51
2278         and %00111111           ;a = 0..63
2279         sub 13                  ;a = -13..50
2280         ret nc                  ;OK if a>=0
2281         add a,13+(50-12)        ;a = -13..-1 >=> 0..12 >=> 39..50
2282         ret
2283
2284 Random:
2285         ld  a,(RanPos)          ;a handy random-var.
2286         ld  hl,x                ;add your x-coord for randomness
2287         adc a,(hl)
2288         inc hl                  ;add your y-coord for randomness
2289         adc a,(hl)
2290         ld  (RanPos),a          ;save altered random-var
2291         ret                     ;RanPos also in #a
2292
2293 scoreInc:
2294         psh bc
2295         ld  bc,(score)
2296         add hl,bc
2297         ld  (score),hl
2298         pop bc
2299         ret
2300
2301 find_sprite:                    ;destroyed: de ix
2302         psh hl
2303         ld  e,(hl)              ;e = enemy type
2304         ld  d,0                 ;de = e
2305         ld  hl,XLenemytable     ;hl = @sprites offset-table
2306         add hl,de               ;points to offset of current enemy offset
2307         ld  e,(hl)              ;de = @enemy offset
2308         ld  d,0
2309
2310         ld  ix,XLsprenemies     ;first enemy sprite
2311         add ix,de               ;add offset for current enemy
2312         add ix,de               ;twice (offset stored as offset/2)
2313         pop hl
2314         ret
2315
2316 BLACKLCD:
2317         ld  hl,VIDEO_MEM        ;screen location (top left)
2318         ld  de,VIDEO_MEM+1
2319         ld  (hl),%11111111
2320         ld  bc,1024-1           ;do it 1024 times = entire screen
2321         ldir
2322         set 3,(iy+5)            ;set white on black
2323         ret
2324
2325 waitnokeypressed:
2326         halt \ halt
2327         cal GET_KEY
2328         or  a
2329         jr  nz,waitnokeypressed
2330         ret
2331
2332 Decompress:                     ;hl=source(compressed) de=dest(decompressed)
2333         ld  a,(hl)
2334         bit 7,a
2335         jr  z,compressed
2336         inc hl
2337         and %01111111
2338         ld  b,0
2339         ld  c,a
2340         ldir
2341         jr  Decompress
2342 compressed:
2343         psh af
2344         or  %11111100
2345         ld  b,a
2346         inc hl
2347         ld  c,(hl)
2348         inc hl
2349         pop af
2350         and %01111100
2351         rrca
2352         rrca
2353         or  a
2354         ret z
2355         psh hl
2356         ld  h,d
2357         ld  l,e
2358         add hl,bc
2359         inc a
2360         inc a
2361         ld  b,0
2362         ld  c,a
2363         ldir
2364         pop hl
2365         jr  Decompress
2366
2367 ;--------------------------- game over / new game / death -------------------
2368 chartable:
2369         .db 0,"!<>^",0,0,0,0
2370         .db 0,"xtoje0",0        ;enter..clear
2371         .db " wsnid9",0         ;(-)..custom
2372         .db "zvrmhc8",0         ;dot..del
2373         .db "yuqlgb7x"          ;0..xvar
2374         .db 0,"-pkfa6'"         ;on..alpha
2375         .db "54321.",0,0        ;F5..more
2376
2377 own_name:
2378         .db 7,"nemesis"
2379
2380 save_hi:
2381         ld  hl,own_name-1       ;find own variable
2382         rst 20h                 ;cal _ABS_MOV10TOOP1
2383         rst 10h                 ;cal _FINDSYM
2384         ret c                   ;not found? who cares...
2385
2386         xor a
2387         ld  hl,4+storehi_start-_asm_exec_ram
2388         add hl,de               ;hl=pointer to data in original prog
2389         adc a,b
2390         cal _SET_ABS_DEST_ADDR
2391         xor a
2392         ld  hl,storehi_start
2393         cal _SET_ABS_SRC_ADDR
2394         ld  hl,storehi_end-storehi_start
2395         cal _SET_MM_NUM_BYTES
2396         cal _mm_ldir            ;save done (cal \ ret)
2397         jp  _RAM_PAGE_1
2398
2399 save_lvl:
2400         ld  hl,own_name-1       ;find own variable
2401         rst 20h                 ;cal _ABS_MOV10TOOP1
2402         rst 10h                 ;cal _FINDSYM
2403         ret c                   ;not found? who cares...
2404
2405         xor a
2406         ld  hl,4+storesave_start-_asm_exec_ram
2407         add hl,de               ;hl=pointer to data in original prog
2408         adc a,b
2409         cal _SET_ABS_DEST_ADDR
2410         xor a
2411         ld  hl,storesave_start
2412         cal _SET_ABS_SRC_ADDR
2413         ld  hl,storesave_end-storesave_start
2414         cal _SET_MM_NUM_BYTES
2415         cal _mm_ldir            ;save done (cal \ ret)
2416         jp  _RAM_PAGE_1
2417
2418 game_over:
2419         pop hl                  ;=ret (game_over was called from a procedure)
2420 game_over_nopop:
2421         cal BLACKLCD            ;clear screen
2422         cal waitnokeypressed
2423         ld  hl,$0603
2424         ld  (_curRow),hl        ;center
2425         ld  hl,txt_gameover
2426         cal _puts               ;display "GAME OVER"
2427
2428         ld  hl,$0007
2429         ld  (_curRow),hl
2430
2431         ld  de,(score)
2432         ld  hl,(hiscore)
2433         cal CP_HL_DE
2434         jr  nc,no_hiscore
2435         ld  (hiscore),de
2436
2437 ask_hiname:
2438         ld  ix,hiname
2439         ld  a,9
2440         ld  (hiscorepos),a
2441 enter_name_loop:
2442         ld  a,'_'
2443         cal _putc
2444         ld  hl,_curCol
2445         dec (hl)
2446 nokeypressed:
2447         halt \ halt
2448         cal GET_KEY
2449         or  a
2450         jr  z,nokeypressed
2451
2452         cp  K_DEL
2453         jr  z,backup
2454         cp  K_ENTER
2455         jr  z,nomore
2456         cp  K_EXIT
2457         jr  z,nomore
2458
2459         ld  hl,hiscorepos
2460         ld  b,(hl)
2461         dec b
2462         jr  z,nokeypressed
2463         ld  (hl),b
2464
2465         ld  hl,chartable
2466         ld  e,a
2467         ld  d,0
2468         add hl,de
2469         ld  a,(hl)
2470         or  a
2471         jr  z,nokeypressed
2472
2473         ld  (ix),a
2474         cal _putc
2475         inc ix
2476         cal waitnokeypressed
2477         jr  enter_name_loop
2478
2479 backup:
2480         ld  hl,hiscorepos
2481         ld  a,(hl)
2482         cp  9
2483         jr  nc,nokeypressed
2484         inc (hl)
2485
2486         dec ix
2487         ld  (ix),' '
2488         ld  a,32
2489         cal _putc
2490         ld  hl,_curCol
2491         dec (hl)
2492         dec (hl)
2493         jr  enter_name_loop
2494
2495 nomore:
2496         ld  a,' '
2497         cal _putc
2498         ld  (ix),0
2499         cal save_hi
2500         jr  hiscoredone
2501
2502 no_hiscore:
2503         ld  hl,hiname
2504         cal _puts
2505
2506 hiscoredone:
2507         xor a                   ;clear a (Ahl will be displayed)
2508         ld  hl,$1006            ;bottom-1 right
2509         ld  (_curRow),hl        ;set
2510         ld  hl,(score)          ;your score
2511         cal _dispahl            ;display it (a=0)
2512
2513         ld  hl,$314b            ;bottom-1 right before score ^^
2514         ld  (_penCol),hl        ;set
2515         ld  hl,txt_score        ;"Score"
2516         cal _vputs              ;display (small)
2517
2518         ld  hl,$1007            ;bottom right
2519         ld  (_curRow),hl        ;set
2520         ld  hl,(hiscore)        ;hi-score
2521         cal _dispahl            ;display
2522         ld  hl,$3946            ;bottom right before hiscore ^^
2523         ld  (_penCol),hl        ;set
2524         ld  hl,txt_hiscore      ;"Hiscore"
2525         cal _vputs              ;display (small)
2526         res 3,(iy+5)
2527
2528         ld  b,16
2529         ld  de,16
2530         ld  hl,VIDEO_MEM+(49*16)-1
2531 restore_line:
2532         set 1,(hl)
2533         add hl,de
2534         dnz restore_line
2535
2536         cal _getkey             ;wait for keypress
2537         jp  quit                ;restore some things and return to TI-OS/shell
2538
2539 New_game:
2540         xor a                   ;ld a,0
2541         ld  (score),a           ;reset score
2542         ld  (score+1),a         ;reset score (0)
2543         ld  (torp_occ),a        ;no torpedoes
2544         ld  (your_weapon),a     ;no laser
2545         ld  (your_pickup),a     ;reset pickups
2546         ld  (your_multiples),a  ;no multiples
2547         inc a                   ;ld a,1
2548         ld  (level),a           ;reset level nr (#1)
2549         ld  hl,XLlevelsdata     ;set level pointer to level#1
2550         ld  (levelp),hl         ;reset level pointer
2551         inc a                   ;ld a,2
2552         ld  (your_weapon),a     ;default weapon
2553         ld  a,4
2554         ld  (your_lives),a      ;3 lives (4 will be decreased @ You_die)
2555         ld  (pickuptimer),a     ;next pickup after 4 enemies destroyed
2556
2557 You_die:
2558         ld  a,12
2559         ld  (your_armor),a      ;12 HPs/shields
2560         ld  a,(your_lives)      ;load lives left
2561         dec a                   ;decrease lives
2562         ld  (your_lives),a      ;if lives=0ffh GO
2563         jp  c,game_over
2564         jr  samelevel
2565
2566 ;--------------------------- next level -------------------------------------
2567
2568 Next_level:
2569         ld  a,(your_armor)      ;load current armor
2570         cp  25-8                ;may not become >=25
2571         jr  c,addok             ;ok then just add 8
2572         ld  a,25-8              ;set to maximum (8 will be added below)
2573 addok:
2574         add a,8                 ;add 8 to armor
2575         ld  (your_armor),a      ;change armor
2576
2577         ld  hl,level            ;level number
2578         ld  a,(hl)
2579         inc a
2580         ld  (hl),a
2581
2582         add a,a
2583         add a,a
2584         ld  h,0                 ;increase score....
2585         ld  l,a                 ;by level number * 4
2586         ld  bc,20
2587         add hl,bc               ;plus 20
2588         cal scoreInc            ;update score
2589
2590         ld  hl,(levelp)         ;level pointer
2591         ld  bc,5+32+4+4         ;advance one level
2592         add hl,bc               ;update to point to next level
2593         ld  (levelp),hl         ;save
2594
2595 samelevel:
2596         ld  a,80
2597         ld  (nextevent),a       ;time to first enemy appearance
2598
2599         ld  hl,(levelp)         ;level pointer
2600         xor a
2601         cp  (hl)
2602         cal z,dostory
2603
2604         ld  a,(hl)              ;load new level-enemy type
2605         ld  (level_enemy),a     ;set level-enemy
2606         inc hl
2607         ld  a,(hl)              ;load new appearance-time
2608         ld  (eventtime),a       ;set
2609         inc hl
2610         ld  a,(hl)              ;load nr of enemies in this level
2611         ld  (eventleft),a       ;set nr of events left
2612         inc hl
2613         ld  a,(hl)              ;
2614         ld  (level_info),a      ;
2615         inc hl
2616         ld  a,(hl)              ;movement of enemies in this level
2617         ld  (level_move),a      ;do it
2618         inc hl
2619         ld  a,(hl)              ;how frequent the enemies fire a bullet
2620         ld  (level_fire),a      ;consider it done
2621
2622         inc hl
2623         ld  de,spacespace
2624         ld  bc,17+17+2
2625         ldir
2626
2627         ld  ix,starx1
2628         ld  b,nrstars1
2629         cal placestars
2630         ld  hl,RanPos
2631         inc (hl)
2632         ld  ix,starx2
2633         ld  b,nrstars2
2634         cal placestars
2635
2636         xor a
2637         ld  (timer),a           ;reset time
2638         ld  hl,your_occ         ;hl = your_occ
2639         ld  (hl),a              ;reset your ship (not exploding)
2640         inc hl                  ;hl = your_inv
2641         ld  (hl),25             ;set 25*4=100 frames invulnerable
2642         ld  hl,x                ;begin position x=...
2643         ld  (hl),a              ;...=a=0=left
2644         inc hl                  ;y=...
2645         ld  a,24                ;...=24=middle
2646         ld  (hl),a              ;your y
2647
2648         ld  a,(torp_occ)
2649         or  a                   ;no torpedoes?
2650         jr  z,torpsclear        ;then just continue (=0)
2651         ld  a,1                 ;if so, set to "ready to fire" (=1)
2652 torpsclear:
2653
2654         ld  de,$0018            ;x=0, y=24 (like you..)
2655 ;       cal Place_multiples     ;place all multiple-positions at (0,24)
2656
2657         ld  hl,enemies          ;remove all enemies and bullets
2658         ld  (hl),0              ;clear first byte
2659         ld  de,enemies+1        ;copy this to the next byte
2660         ld  bc,(nrenemies*enemysize)+((nrybuls+nrebuls)*3)-1
2661         ldir                    ;clear enemies + bullets (y/e)
2662
2663 ;--------------------------- setup game -------------------------------------
2664
2665 game_setup:
2666         cal BLACKLCD
2667         ld  hl,$0703
2668         ld  (_curRow),hl        ;center
2669         ld  hl,txt_level
2670         cal _puts               ;display "LEVEL "
2671
2672         ld  a,(level)
2673         ld  l,a
2674         ld  h,$00
2675
2676         cal UNPACK_HL
2677         add a,'0'
2678         ld  b,a
2679         cal UNPACK_HL
2680         add a,'0'
2681         cal _putc               ;display second digit
2682         ld  a,b
2683         cal _putmap             ;display first digit
2684
2685         ld  hl,$0904
2686         ld  (_curRow),hl        ;display lives left below level nr
2687         ld  hl,txt_lives        ;bar text: "Lx0"...
2688         ld  a,(your_lives)      ;lives left
2689         add a,'0'               ;make value
2690         ld  (txt_lives+3),a     ;add to text
2691         cal _puts               ;display the string
2692         res 3,(iy+5)            ;set white on black
2693
2694         cal _getkey             ;wait for keypress
2695         cp  kF1
2696         cal z,save_lvl
2697
2698         cal _clrLCD             ;clear screen
2699         jp  disp_icons          ;display bottom icons +ret
2700
2701 placestars:
2702         cal Random5016          ;a = (0..50)*16 = random y-pos
2703         ld  a,b                 ;a =  b = star nr. = 1..7
2704         add a,a                 ;a = 2b = 2..14
2705         ld  d,0
2706         ld  e,a                 ;de = a = 2-14
2707         add hl,de               ;add to random y => random pos anywhere
2708
2709         ld  (ix),l              ;save x-pos (l)
2710         ld  (ix+1),h            ;save y-pos (h)
2711         inc ix \ inc ix         ;next star
2712         dnz placestars          ;repeat for all stars
2713         ret
2714
2715 loadweapon:
2716         ld  a,(your_weapon)
2717         add a,a                 ;weap*2
2718         add a,a                 ;    *4
2719         add a,a                 ;    *8
2720         ld  c,a
2721         ld  b,0
2722         ld  hl,weapondata-16
2723         add hl,bc
2724         ld  a,(hl)
2725         ld  (weapdamage),a      ;damage of bullets
2726         inc hl
2727         ld  a,(hl)
2728 ;        ld  (weapdaminc),a     ;damage increase
2729         ret
2730
2731 ;--------------------------- putsprite --------------------------------------
2732 ;--------------------------- de =(X,Y) --------------------------------------
2733
2734 offsets_table:
2735         .db $80,$40,$20,$10,8,4,2,1
2736 putsprite:
2737         ld  a,d                 ;a = X
2738         and %00000111           ;a = X mod 8 = bit nr. to mask
2739         ld  hl,offsets_table    ;pixel mask table
2740         ld  c,a                 ;bit nr.
2741         ld  b,0                 ;word
2742         add hl,bc               ;add to table
2743         ld  a,(hl)              ;a = pixel mask
2744         ld  (_smc1+1),a         ;alter pixel mask
2745
2746         ld  hl,GRAPH_MEM        ;save-location
2747         ld  a,e                 ;y-coord
2748         add a,a                 ;y*2
2749         add a,a                 ;y*4
2750         add a,a                 ;y*8
2751         rl  b                   ;b (=0) =b*2+overflow (if y>32 then bc=bc+256)
2752         add a,a                 ;y*16 (width of screen)
2753         rl  b                   ;b=b*2+overflow (if y>64 then bc=bc+512)
2754         srl d                   ;d/2
2755         srl d                   ;d/4
2756         srl d                   ;d/8 (8 bits in byte) ** c is set when overflow
2757         add a,d                 ;a = (Y*16+X/8) mod 256
2758         jr  nc,_n1              ;jump if no carry = no overflow = a<=255
2759         inc b                   ;a>255 so increase bc by 256
2760 _n1:    ld  c,a                 ;c = (Y*16+X/8) mod 256
2761         add hl,bc               ;bc = Y*16+X/8
2762
2763         ld  d,(ix)
2764         ld  b,(ix+1)
2765 _oloop: psh bc                  ;Save # of rows
2766         psh hl                  ;Save screen address
2767         ld  b,d                 ;Load width
2768         ld  c,(ix+2)            ;Load one line of image
2769         inc ix
2770 _smc1:  ld  a,1                 ;Load pixel mask
2771 _iloop: sla c                   ;Test leftmost pixel
2772         jr  nc,_noplot          ;See if a plot is needed
2773         ld  e,a                 ;OR pixel with screen
2774         or  (hl)
2775         ld  (hl),a
2776         ld  a,e
2777 _noplot:rrca
2778         jr  nc,_notedge         ;Test if edge of byte reached
2779         inc hl                  ;Go to next byte
2780 _notedge:
2781         dnz _iloop
2782         pop hl                  ;Restore address
2783         ld  bc,16               ;Go to next line
2784         add hl,bc
2785         pop bc                  ;Restore data
2786         dnz _oloop
2787         ret                     ;<jp>s are used instead of <jr> = faster
2788
2789 ;--------------------------- putbigsprite -----------------------------------
2790
2791 putwidesprite:
2792         ld  a,d
2793         and 7
2794         ld  hl,offsets_table
2795         ld  c,a
2796         ld  b,0
2797         add hl,bc
2798         ld  a,(hl)
2799         ld  (wsmc1+1),a
2800         ld  (wsmc2+1),a
2801         ld  hl,(PutWhere)
2802
2803         ld  a,e
2804         add a,a
2805         add a,a
2806         add a,a
2807
2808         rl  b
2809         add a,a
2810         rl  b
2811         srl d
2812         srl d
2813         srl d
2814         add a,d
2815         jr  nc,n1
2816         inc b
2817 n1:     ld  c,a
2818         add hl,bc
2819
2820         ld  d,(ix)
2821         ld  b,(ix+1)
2822 woloop: psh bc                  ;Save # of rows
2823         psh hl                  ;Save screen address
2824         ld  b,d                 ;Load width
2825         ld  c,(ix+2)            ;Load one line of image
2826         inc ix
2827 wsmc1:  ld  a,1                 ;Load pixel mask
2828 wiloop: sla c                   ;Test leftmost pixel
2829         jr  nc,wnoplot          ;See if a plot is needed
2830         ld  e,a                 ;OR pixel with screen
2831         or  (hl)
2832         ld  (hl),a
2833         ld  a,e
2834 wnoplot:
2835         rrca
2836         jr  nc,wnotedge         ;Test if edge of byte reached
2837         inc hl                  ;Go to next byte
2838 wnotedge:
2839 wsmc2:  cp  1
2840         jr  z,wover_1
2841
2842         dnz wiloop
2843         pop hl                  ;Restore address
2844         ld  bc,16               ;Go to next line
2845         add hl,bc
2846         pop bc                  ;Restore data
2847         dnz woloop
2848         ret
2849 wover_1:
2850         ld  c,(ix+2)
2851         inc ix
2852         dnz wiloop
2853         dec ix
2854         pop hl
2855         ld  bc,16
2856         add hl,bc
2857         pop bc
2858         dnz woloop
2859         ret
2860
2861 ;----------------------------------------------------------------------------
2862 ;------------------------------- sprites ------------------------------------
2863 ;----------------------------------------------------------------------------
2864
2865 spr_ship01:
2866         .db 7,7         ;ship alpha class
2867         .db %01111000   ;  ████
2868         .db %11100000   ; ███
2869         .db %01111100   ;  █████
2870         .db %11110010   ; ████  █
2871         .db %01111100   ;  █████
2872         .db %11100000   ; ███
2873         .db %01111000   ;  ████
2874 spr_ship01i:
2875         .db 7,7         ;ship alpha class
2876         .db %01010000   ;  █ █
2877         .db %10100000   ; █ █
2878         .db %01010100   ;  █ █ █
2879         .db %10100010   ; █ █   █
2880         .db %01010100   ;  █ █ █
2881         .db %10100000   ; █ █
2882         .db %01010000   ;  █ █
2883
2884 spr_ship02:
2885 ;       .db 7,7         ;ship beta class
2886 ;       .db %11100000   ; ███
2887 ;       .db %11110000   ; ████
2888 ;       .db %01111100   ;  █████
2889 ;       .db %01110010   ;  ███  █
2890 ;       .db %01111100   ;  █████
2891 ;       .db %11110000   ; ████
2892 ;       .db %11100000   ; ███
2893 spr_ship02i:
2894 ;       .db 7,7         ;ship beta class
2895 ;       .db %01000000   ;  █
2896 ;       .db %10100000   ; █ █
2897 ;       .db %01010100   ;  █ █ █
2898 ;       .db %00100010   ;   █   █
2899 ;       .db %01010100   ;  █ █ █
2900 ;       .db %10100000   ; █ █
2901 ;       .db %01000000   ;  █
2902
2903 spr_multiple:
2904         .db 6,4         ;multiples
2905         .db %01111000   ;  ████
2906         .db %11111100   ; ██████
2907         .db %11111100   ; ██████
2908         .db %01111000   ;  ████
2909
2910 ;--------------------------------- bullets ----------------------------------
2911
2912 spr_bullet01:
2913         .db 5,3         ;dam=0-3
2914         .db %00110000   ;  ▒██
2915         .db %01001000   ; ▒█ ▒█
2916         .db %00110000   ;  ▒██
2917 spr_bullet02:
2918         .db 5,3         ;dam=4-7
2919         .db %00110000   ;  ▒██
2920         .db %01101000   ; ▒██▒█
2921         .db %00110000   ;  ▒██
2922 spr_bullet03:
2923         .db 5,3         ;dam=8-11
2924         .db %00110000   ;  ▒██
2925         .db %11101000   ;▒███▒█
2926         .db %00110000   ;  ▒██
2927 spr_bullet04:
2928         .db 5,3         ;dam=8-11
2929         .db %00110000   ;  ▒██
2930         .db %11111000   ;▒█████
2931         .db %00110000   ;  ▒██
2932 spr_bullet05:
2933         .db 5,3         ;dam=8-11
2934         .db %01110000   ; ▒███
2935         .db %11111000   ;▒█████
2936         .db %01110000   ; ▒███
2937 spr_bullet06:
2938         .db 5,3
2939         .db %11110000   ;▒████
2940         .db %11111000   ;▒█████
2941         .db %11110000   ;▒████
2942 spr_bullett1:
2943         .db 4,3         ;▒▒▒
2944         .db %11100000   ;▒███
2945         .db %11110000   ; ████
2946         .db %01110000   ;  ███
2947
2948 spr_bullete1:
2949         .db 4,3         ;enemy bullets
2950         .db %01100000   ;  ▒█▓▒░
2951         .db %11110000   ; ▒███▓▒░
2952         .db %01100000   ;  ▒█▓▒░
2953
2954 ;-------------------------------- explosion ---------------------------------
2955
2956 spr_explosion:
2957         .db 8,6         ;1
2958         .db %00000000
2959         .db %00011100   ;    ███
2960         .db %00111110   ;   █████
2961         .db %01010110   ;  █ █ ██
2962         .db %00111000   ;   ███
2963         .db %00000000
2964
2965         .db 8,6         ;2
2966         .db %00110000   ;   ██
2967         .db %01001110   ;  █ ▒███
2968         .db %10111110   ; █ █████
2969         .db %01001111   ;  █ ▒████
2970         .db %00111000   ;   ███
2971         .db %00011010   ;    ██ █
2972
2973         .db 8,6         ;3
2974         .db %10110000   ; █ ██
2975         .db %01001110   ;  █  ███
2976         .db %10110101   ; █ ██▒█▒█
2977         .db %01000101   ;  █  ▒█▒█
2978         .db %00111110   ;   █████
2979         .db %01011010   ;  █ ██ █
2980
2981         .db 8,6         ;4
2982         .db %00101010   ; ▒ █▒█ █
2983         .db %01000110   ;  █  ▒██
2984         .db %10110101   ; █ ██ █ █
2985         .db %01100110   ;  ██  ██▒
2986         .db %00111100   ;   ████▒
2987         .db %01011001   ;  █ ██ ▒█
2988
2989         .db 8,6         ;5
2990         .db %01000000   ;  █▒ ▒ ▒
2991         .db %00100101   ;  ▒█  █▒█
2992         .db %00010100   ; ▒ ▒█ █ ▒
2993         .db %01000100   ;  █▒  █
2994         .db %00010010   ;   ▒█▒▒█
2995         .db %10011010   ; █▒ ██ █▒
2996
2997         .db 8,6         ;6
2998         .db %01000100   ;  █   █
2999         .db %00100000   ;   ▒█ ▒ ▒
3000         .db %00000001   ;    ▒ ▒ █
3001         .db %01000100   ;  █   █
3002         .db %00100010   ;   █▒  █
3003         .db %01001000   ; ▒█ ▒█ ▒
3004
3005         .db 8,6         ;7
3006         .db %00001000   ;  ▒  █▒
3007         .db %11000010   ; ██ ▒  █
3008         .db %00000000   ;        ▒
3009         .db %00100000   ;  ▒█  ▒
3010         .db %00000001   ;   ▒   ▒█
3011         .db %00110000   ;  ▒██▒
3012
3013         .db 8,6         ;8
3014         .db %00000100   ;     ▒█
3015         .db %00000000   ; ▒▒    ▒
3016         .db %01000000   ;  █
3017         .db %00000000   ;   ▒
3018         .db %00000010   ;       █▒
3019         .db %00100100   ;   █▒ █
3020
3021 spr_yexplosion:
3022         .db 8,6         ;8
3023         .db %00000000   ;
3024         .db %00000000   ;
3025         .db %00000000   ;
3026         .db %00000000   ;
3027         .db %00000000   ;
3028         .db %00000000   ;
3029
3030 ;------------------------------------ bar -----------------------------------
3031
3032 spr_iconhalf:
3033         .db 16,7        ;selected .......:
3034         .db %11111111           ; ████████
3035         .db %00000001           ;        █
3036         .db %00000001           ;        █
3037         .db %00000001           ;        █
3038         .db %00000001           ;        █
3039         .db %00000001           ;        █
3040         .db %11111111           ; ████████
3041 spr_icon:
3042         .db 16,7        ;selected .......:.......:
3043         .db %11111111,%11111111 ; ████████████████
3044         .db %11000000,%00000001 ; ██             █
3045         .db %11000000,%00000001 ; ██             █
3046         .db %11000000,%00000001 ; ██             █
3047         .db %11000000,%00000001 ; ██             █
3048         .db %11000000,%00000001 ; ██             █
3049         .db %11111111,%11111111 ; ████████████████
3050 spr_icon00:
3051         .db 16,7        ;unused   .......:.......:
3052         .db %10101010,%10101010 ; █ █ █ █ █ █ █ █
3053         .db %11010101,%01010101 ; ██ █ █ █ █ █ █ █
3054         .db %10101010,%10101010 ; █ █ █ █ █ █ █ █
3055         .db %11010101,%01010101 ; ██ █ █ █ █ █ █ █
3056         .db %10101010,%10101010 ; █ █ █ █ █ █ █ █
3057         .db %11010101,%01010101 ; ██ █ █ █ █ █ █ █
3058         .db %10101010,%10101010 ; █ █ █ █ █ █ █ █
3059 spr_icon01:
3060         .db 16,7        ;armor  ; .......:.......:
3061         .db %10000111,%11110000 ; █    ███████
3062         .db %10011000,%00001100 ; █  ██       ██
3063         .db %10110011,%11000110 ; █ ██  ████   ██
3064         .db %10110000,%11110110 ; █ ██    ████ ██
3065         .db %10110011,%11000110 ; █ ██  ████   ██
3066         .db %10011000,%00001100 ; █  ██       ██
3067         .db %10000111,%11110000 ; █    ███████
3068 spr_icon02:
3069         .db 16,7        ;torpedo  .......:.......:
3070         .db %10111000,%00010101 ; █ ███      █ █ █
3071         .db %10011100,%00010101 ; █  ███     █ █ █
3072         .db %10111000,%01001010 ; █ ███    █  █ █
3073         .db %10000000,%11101010 ; █       ███ █ █
3074         .db %11100001,%11100101 ; ███    ████  █ █
3075         .db %10011000,%11110101 ; █  ██   ████ █ █
3076         .db %11100110,%00110010 ; ███  ██   ██  █
3077 spr_icon03:
3078         .db 16,7        ;bullets  .......:.......:
3079         .db %10000000,%11000000 ; █       ██
3080         .db %10000011,%11100000 ; █     █████ ▒▒▒
3081         .db %10011000,%11000000 ; █  ██   ██  ▒▒▒
3082         .db %11111100,%00000000 ; ██████      ▒▒▒
3083         .db %10011000,%11000000 ; █  ██   ██  ▒▒▒
3084         .db %10000011,%11100000 ; █     █████ ▒▒▒
3085         .db %10000000,%11000000 ; █       ██
3086 spr_icon04:
3087         .db 16,7        ;laser    .......:.......:
3088         .db %10000000,%00000000 ; █
3089         .db %10110010,%10000000 ; █ ██  █ █
3090         .db %10111011,%00000000 ; █ ███ ██
3091         .db %10011101,%11111111 ; █  ███ █████████
3092         .db %10111011,%00000000 ; █ ███ ██
3093         .db %10110010,%10000000 ; █ ██  █ █
3094         .db %10000000,%00000000 ; █
3095 spr_icon05:
3096         .db 16,7        ;multiple .......:.......:
3097         .db %10000011,%10000000 ; █     ███
3098         .db %10000001,%11100110 ; █      ████  ██
3099         .db %10000001,%11100000 ; █      ████
3100         .db %10000011,%10000000 ; █     ███
3101         .db %10011000,%00000000 ; █  ██
3102         .db %10111100,%11000011 ; █ ████  ██    ██
3103         .db %10011000,%00000000 ; █  ██
3104 spr_dividerline:
3105         .db 8,7
3106         .db 128,128,128,128,128,128,128 ;128 = %10000000
3107
3108 ;-------------------------- weapondata --------------------------------------
3109
3110 ;format:[unused] [ybuls(max.bullets)] [0000:direction 0000:speed] [offset]
3111 maxnrweapons = 8+1
3112 weapondata:
3113         .db 2,1,%00000010,2,%00000000,0,%00000000,0     ;single fire
3114         .db 2,1,%00000011,2,%00000000,0,%00000000,0     ;fast single
3115         .db 16,2,%00000010,0,%00000010,5,%00000000,0    ;double
3116         .db 16,1,%00010010,2,%00110010,2,%01000010,2    ;triple
3117         .db 16,1,%00010011,2,%00110011,2,%01000011,2
3118         .db 16,1,%00010011,2,%00110011,2,%01000100,2
3119         .db 16,1,%00010100,2,%00110100,2,%01000101,2
3120         .db 16,1,%00010100,2,%00110100,2,%01000101,2
3121
3122 ;---------------------------- texts -----------------------------------------
3123
3124 txt_about:      .db " v0.96.A30",127,"by Shiar",0
3125 txt_email:      .db "shiar0@hotmail.com",0
3126 txt_menu1:      .db "NEW GAME",0
3127 txt_menu2:      .db "CONTINUE",0
3128
3129 txt_level:      .db "LEVEL ",0
3130 txt_gameover:   .db "GAME OVER!",0
3131 txt_score:      .db "Score",0
3132 txt_hiscore:    .db "Hiscore",0
3133 txt_lives:      .db "Lx0?",0
3134
3135 txt_pressenter: .db "Enter to continue",0
3136 txt_teacher:    .db "(2",Lpi,"*.95)/sin 13",0
3137 txt_teacherans: .db Lneg,"14.2063168184",0
3138
3139 ;---------------------------- save data -------------------------------------
3140
3141 PutWhere        .dw GRAPH_MEM           ;where to put the wide sprites
3142 laserlasts      .db 5
3143
3144 storehi_start:
3145 hiscore         .dw $0000
3146 hiname          .db "Shiar.97",0
3147 storehi_end:
3148
3149 storesave_start:
3150 level           .db $01                 ;level number
3151 levelp          .dw XLlevelsdata        ;pointer to level data
3152 pickuptimer     .db $04                 ;counts when to place a pickup
3153 score           .dw $0000
3154
3155 your_pickup     .db $00
3156 your_occ        .db $00                 ;0=normal 1..16=exploding
3157 your_inv        .db $00                 ;invincibility left
3158 your_armor      .db $0a                 ;HP left
3159 your_lives      .db $03                 ;
3160
3161 your_weapon     .db $02                 ;weapon: 0=no, 1=laser, 2+=bullet n+1
3162 your_multiples  .db $00                 ;multiples present
3163 torp_occ        .db $00                 ;torp.state: 0=unavail 1=avail 2=presnt
3164 torp_pos        .dw $0000               ;torpedo position (x,y)
3165 storesave_end:
3166
3167
3168 ;XLlevelsdata:---------------------------------------------------------------
3169 XLlevelsdata:
3170
3171         .db 0
3172         .db $21,$1d,"Cosmic year 6716"          ,0,0,$1d,$06
3173         .db $1b,$1d,"storyline coming soon..."  ,0,0,$1d,$06
3174         .db $09,$19,"the Nemesis saga continues",0,1
3175         .db $2e,$21,"with NEMESIS 86"           ,0,1
3176         .db $52,$36,"by Shiar"                  ,0,0,$19,$23
3177         .db $ff
3178
3179 ;format:[enemy nr] [enemy frequency] [next lvl]
3180 ;       [level_info: 0000:damage 0:directfire 0:ground 0:ceiling 0:diagfire]
3181 ;       [level_move] [level_fire] [tunnel size] [groundtype] [16_ground]
3182 ;       [16_ceiling] [stars1] [stars2]
3183
3184         .db $15,$07,$08                 ;fireFreq; moveType; enemyType
3185 level01:                                ;efrequency must be odd if halfluring!
3186         .db $01,$1b,$2f,%00010001,0,255,0,0 ;0f>>2f             ; 7
3187         .db 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1                     ;16
3188         .db 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1                     ;16
3189         .db 1,1                                                 ; 2
3190         .db $10,$07,$09                                         ; 3
3191
3192         .db 0
3193         .db $01,01,"And the storyline conti",
3194                 .db "nues.....",0,1
3195         .db $01,09,"You decide to fly close",
3196                 .db " to the",0,1
3197         .db $01,15,"surface of a nearby pl",
3198                 .db "anet =)",0,0,1,20
3199         .db $FF
3200
3201         .db $10,$07,$09                                         ; 3
3202 level02:                                                        ;44
3203         .db $02,$13,$4b,%00100101,0,064,0,0
3204         .db 1,2,3,4,5,6,6,5,4,3,4,5,4,3,2,1
3205         .db 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
3206         .db 1,1
3207         .db $0E,$07,$09
3208
3209         .db 0
3210         .db $01,01,"Blablabla...",0,1
3211         .db $01,34,"this storyline sux",0,0,1,39
3212         .DB $FF
3213
3214         .db $0E,$07,$09
3215 level03:
3216         .db $03,$2d,$3f,%00010110,0,255,-9,1
3217         .db 3,2,4,3,2,2,1,1,1,1 ,1,1,21,17,18,20
3218         .db 1,1,1,1,1,1,1,3,6,12,9,1,21,19,18,18
3219         .db -1,-1
3220
3221         .db $0D,$07,$08
3222 level04:
3223         .db $04,$11,$41,%00100001,0,057,0,0
3224         .db 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
3225         .db 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
3226         .db 1,1
3227         .db $0C,$07,$09
3228 level05:
3229         .db $05,$11,$45,%00100101,%10,031,-7,1
3230         .db 14,12,11,9,10,7,7,5,4,3,4,4,2,3,1,2
3231         .db 1, 1, 1, 1,1, 1,1,1,1,1,1,1,1,1,1,1
3232         .db 1,1
3233         .db $0B,$07,$08
3234 level06:
3235         .db $06,$19,$3a,%00100111,0,255,-4,1
3236         .db 20,22,18,15,9,1,1,1,1,1,1,1,1,1,1,1
3237         .db 20,22,18,15,9,1,1,1,1,1,1,1,1,1,1,1
3238         .db 1,1
3239
3240         .db $08,$07,$09
3241 level07:
3242         .db $07,$09,$ff,%00100001,0,043,0,0
3243         .db 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
3244         .db 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
3245         .db 1,1
3246
3247 ;XLenemytable:---------------------------------------------------------------
3248 XLbullettable:
3249         .db (spr_bullet01-spr_bullet01) ;0
3250         .db (spr_bullet01-spr_bullet01) ;4
3251         .db (spr_bullet02-spr_bullet01) ;8
3252         .db (spr_bullet02-spr_bullet01) ;12
3253         .db (spr_bullet03-spr_bullet01) ;16
3254         .db (spr_bullet03-spr_bullet01) ;20
3255         .db (spr_bullet03-spr_bullet01) ;24
3256         .db (spr_bullet04-spr_bullet01) ;28
3257         .db (spr_bullet04-spr_bullet01) ;32
3258         .db (spr_bullet04-spr_bullet01) ;36
3259         .db (spr_bullet05-spr_bullet01) ;40
3260         .db (spr_bullet05-spr_bullet01) ;44
3261         .db (spr_bullet05-spr_bullet01) ;48
3262         .db (spr_bullet06-spr_bullet01) ;52
3263         .db (spr_bullet06-spr_bullet01) ;56
3264         .db (spr_bullet06-spr_bullet01) ;60
3265
3266 XLenemytable:
3267         .db $00                         ;00
3268         .db (spr_enemy01-spr_enemy00)/2 ;01
3269         .db (spr_enemy02-spr_enemy00)/2 ;02
3270         .db (spr_enemy03-spr_enemy00)/2 ;03
3271         .db (spr_enemy04-spr_enemy00)/2 ;04
3272         .db (spr_enemy05-spr_enemy00)/2 ;05
3273         .db (spr_enemy06-spr_enemy00)/2 ;06
3274         .db (spr_enemy07-spr_enemy00)/2 ;07
3275         .db (spr_boss01 -spr_enemy00)/2 ;08
3276         .db (spr_boss02 -spr_enemy00)/2 ;09
3277         .db (spr_enemy08-spr_enemy00)/2 ;0A
3278         .db (spr_enemy00-spr_enemy00)/2 ;0B
3279         .db (spr_enemy00-spr_enemy00)/2 ;0C
3280         .db (spr_enemy00-spr_enemy00)/2 ;0D
3281         .db (spr_enemy00-spr_enemy00)/2 ;0E
3282         .db (spr_enemy00-spr_enemy00)/2 ;0F
3283
3284 ;XLenemyinfos:---------------------------------------------------------------
3285 XLenemyinfos:
3286
3287 ;format: [000000:HP 00:occ] [HP64] [appearance(ypos)] [unused]
3288
3289         .db %00100110,0,1,1     ;#1     HP:1    app:random
3290         .db %00101010,0,2,3     ;#2     HP:1    app:halflure
3291         .db %00001111,0,3,2     ;#3     HP:1    app:lure
3292
3293         .db %00000110,0,4,2     ;#4     HP:2    app:lure
3294         .db %00000111,0,5,3     ;#5     HP:2    app:random      moving
3295         .db %00001011,0,6,2     ;#6     HP:3    app:lure        moving
3296
3297         .db %00011011,0,7,3     ;#7     HP:7    app:halflure    moving
3298
3299         .db %00110011,1,8,1     ;boss1
3300         .db %00111011,0,9,3     ;boss2
3301
3302         .db %00000000,0,0,0
3303         .db %00000000,0,0,0
3304         .db %00000000,0,0,0
3305         .db %00000000,0,0,0
3306         .db %00000000,0,0,0
3307         .db %00000000,0,0,0
3308         .db %00000000,0,0,0
3309
3310 ;XLsprenemies:---------------------------------------------------------------
3311 XLsprenemies:
3312
3313 spr_enemy00:
3314         .db 8,8                         ;pickup
3315         .db %00011000                   ;    ██
3316         .db %00011000                   ;    ██
3317         .db %00011000                   ;    ██
3318         .db %11111111                   ; ████████
3319         .db %11111111                   ; ████████
3320         .db %00011000                   ;    ██
3321         .db %00011000                   ;    ██
3322         .db %00011000                   ;    ██
3323
3324 spr_enemy01:
3325         .db 6,6                         ;enemy type one
3326         .db %00111100                   ;   ████
3327         .db %01110000                   ;  ███
3328         .db %11110000                   ; ████
3329         .db %11110000                   ; ████
3330         .db %01110000                   ;  ███
3331         .db %00111100                   ;   ████
3332 spr_enemy02:
3333         .db 8,6                         ;enemy type two
3334         .db %00111111                   ;    █████
3335         .db %01111000                   ;  ████
3336         .db %11111100                   ; ██████
3337         .db %11111100                   ; ██████
3338         .db %01111000                   ;  ████
3339         .db %00111111                   ;    █████
3340 spr_enemy03:
3341         .db 6,6                         ;enemy type three
3342         .db %01111100                   ;  █████
3343         .db %11110000                   ; ████
3344         .db %11111000                   ; █████
3345         .db %11111000                   ; █████
3346         .db %11110000                   ; ████
3347         .db %01111100                   ;  █████
3348 spr_enemy04:
3349         .db 6,6                         ;enemy type four
3350         .db %00111000                   ;   ███
3351         .db %01111100                   ;  █████
3352         .db %11111000                   ; █████
3353         .db %11111000                   ; █████
3354         .db %01111100                   ;  █████
3355         .db %00111000                   ;   ███
3356 spr_enemy05:
3357         .db 7,6                         ;enemy type five
3358         .db %00011110                   ;    ████
3359         .db %01111110                   ;  ██████
3360         .db %11111100                   ; ██████
3361         .db %11111100                   ; ██████
3362         .db %01111110                   ;  ██████
3363         .db %00011110                   ;    ████
3364 spr_enemy06:
3365         .db 7,6                         ;enemy type six
3366         .db %00011100                   ;    ███
3367         .db %01111110                   ;  ██████
3368         .db %10111000                   ; █ ███
3369         .db %10111000                   ; █ ███
3370         .db %01111110                   ;  ██████
3371         .db %00011100                   ;    ███
3372 spr_enemy07:
3373         .db 8,6                         ;enemy type seven
3374         .db %00011110                   ;    ████
3375         .db %01111111                   ;  ███████
3376         .db %10011100                   ; █  ███
3377         .db %10011100                   ; █  ███
3378         .db %01111111                   ;  ███████
3379         .db %00011110                   ;    ████
3380
3381 spr_boss01:
3382         .db 16,10                       ;boss type one
3383         .db %00000001,%11111111         ;        █████████
3384         .db %00001111,%11111110         ;     ███████████
3385         .db %00111111,%11110000         ;   ██████████
3386         .db %01011111,%10000000         ;  █ ██████
3387         .db %10011111,%01000000         ; █  █████ █
3388         .db %10011111,%01000000         ; █  █████ █
3389         .db %01011111,%10000000         ;  █ ██████
3390         .db %00111111,%11110000         ;   ██████████
3391         .db %00001111,%11111110         ;     ███████████
3392         .db %00000001,%11111111         ;        █████████
3393 spr_boss02:
3394         .db 16,10                       ;boss type:one   :
3395         .db %11111110,%00000000         ; ███████
3396         .db %00001111,%10001111         ;     █████   ████
3397         .db %00111111,%11100011         ;   █████████   ██
3398         .db %01001111,%11111110         ;  █  ███████████
3399         .db %10001101,%01111100         ; █   ██ █ █████
3400         .db %10001101,%01111100         ; █   ██ █ █████
3401         .db %01001111,%11111110         ;  █  ███████████
3402         .db %00111111,%11100011         ;   █████████   ██
3403         .db %00001111,%10001111         ;     █████   ████
3404         .db %11111110,%00000000         ; ███████
3405
3406
3407 spr_enemy08:
3408         .db 8,6         ;enemy type eight
3409         .db %00011110   ;    ████
3410         .db %01111111   ;  ███████
3411         .db %10011100   ; █  ███
3412         .db %10011100   ; █  ███
3413         .db %01111111   ;  ███████
3414         .db %00011110   ;    ████
3415
3416 ;----------------------------------------------------------------------------
3417 ;----------------------------- logo ------------------------------------------
3418 ;----------------------------------------------------------------------------
3419
3420 logo_nemesis:
3421 .db %11111111,%11111111,%11111111,%11111110,%11111111,%11110111,%11111111,%11111110,%11111111,%111101111,%11111111,%00001011,%11111111,%11111111,%11111111,%11111000
3422 .db %01111111,%11111111,%11111111,%11111110,%11111111,%11110111,%11111111,%11111110,%11111111,%111101111,%11111111,%00011011,%11111111,%11111111,%11111111,%11110000
3423 .db %00111111,%11111111,%11111111,%11111110,%11111111,%11110111,%11111111,%11111110,%11111111,%111101111,%11111111,%00111011,%11111111,%11111111,%11111111,%11100000
3424 .db %00011111,%11111111,%11111111,%11111110,%11111111,%11110111,%11111111,%11111110,%11111111,%111101111,%11111111,%01111011,%11111111,%11111111,%11111111,%11000000
3425 .db %00000000,%00000000,%00000001,%00011110,%00010000,%00000000,%10000001,%00011110,%00010000,%000000001,%00000000,%00001000,%01000000,%00000000,%00000000,%00000000
3426 .db %00000000,%00000000,%00000011,%00011110,%00110000,%00000001,%10000011,%00011110,%00110000,%000000011,%00000000,%00011000,%11000000,%00000000,%00000000,%00000000
3427 .db %00000000,%00000000,%00000111,%00011110,%01110000,%00000011,%10000111,%00011110,%01110000,%000000111,%00000000,%00111001,%11000000,%00000000,%00000000,%00000000
3428 .db %00000000,%00000000,%00001111,%00011110,%11111111,%00000111,%10001111,%00011110,%11111111,%000001111,%11111111,%01111011,%11111111,%11000000,%00000000,%00000000
3429 .db %00000000,%00000000,%00001111,%00011110,%11111111,%00000111,%10001111,%00011110,%11111111,%000001111,%11111111,%01111011,%11111111,%11000000,%00000000,%00000000
3430 .db %00000000,%00000000,%00001111,%00011110,%11111111,%00000111,%10001111,%00011110,%11111111,%000001111,%11111111,%01111011,%11111111,%11000000,%00000000,%00000000
3431 .db %00000000,%00000000,%00001111,%00011110,%11111111,%00000111,%10001111,%00011110,%11111111,%000001111,%11111111,%01111011,%11111111,%11000000,%00000000,%00000000
3432 .db %00000000,%00000000,%00001111,%00011110,%11110000,%00000111,%10001111,%00011110,%11110000,%000000000,%00001111,%01111000,%00000011,%11000000,%00000000,%00000000
3433 .db %00000000,%00000000,%00001111,%00011110,%11110000,%00000111,%10001111,%00011110,%11110000,%000000000,%00001111,%01111000,%00000011,%11000000,%00000000,%00000000
3434 .db %00000000,%00000000,%00001111,%00011110,%11110000,%00000111,%10001111,%00011110,%11110000,%000000000,%00001111,%01111000,%00000011,%11000000,%00000000,%00000000
3435 .db %00000000,%00000000,%00001111,%00011110,%11110000,%00000111,%10001111,%00011110,%11110000,%000000000,%00001111,%01111000,%00000011,%11000000,%00000000,%00000000
3436 .db %00000000,%00000000,%00001111,%00011110,%11111111,%11110111,%10001111,%00011110,%11111111,%111101111,%11111111,%01111011,%11111111,%11000000,%00000111,%11010001
3437 .db %00000000,%00000000,%00001111,%00011110,%11111111,%11110111,%10001111,%00011110,%11111111,%111101111,%11111111,%01111011,%11111111,%11000000,%00000001,%00011011
3438 .db %00000000,%00000000,%00001111,%00011110,%11111111,%11110111,%10001111,%00011110,%11111111,%111101111,%11111111,%01111011,%11111111,%11000000,%00000001,%00010101
3439 .db %00000000,%00000000,%00001111,%00011110,%11111111,%11110111,%10001111,%00011110,%11111111,%111101111,%11111111,%01111011,%11111111,%11000000,%00000001,%00010001
3440
3441 ;----------------------------- end ------------------------------------------
3442
3443         .end
3444 .end
3445
3446
3447 ;----------------------------------------------------------------------------
3448 ;----------------------------------------------------------------------------
3449 ;----------------------------------------------------------------------------
3450
3451 ; 0.95.A22 -- 22.X.99 -- size 5321
3452 ;
3453 ;       * total size of enemy-sprites can now be 510 bytes (space = doubled!)
3454 ;       # bullets hit enemies correctly that aren't 6x6; even the 16x10 bosses!
3455 ;       * at g/o or nextlevel checks for keys released instead of waiting abit
3456 ;       + name stored with hiscore (max. 8 chars, Shiar.95 by default)
3457 ;       + when entering hi-name DEL goes back one char (with check 4 no chars)
3458 ;       # program is reloaded at start so some score-bugs solved! (_asapvar=0)
3459 ;       * at death, upgrades and pickups AREN'T removed! (just armor=0)
3460 ;       # bullet is not displayed after being removed anymore
3461 ;       # armor-icon stays hilighted when armor is decreased
3462 ;       * when stars move off screen, they are placed at a NEW y-pos!
3463 ;       * the starting x-positions of stars are not random, so the stars are
3464 ;         spread all over screen. y is still random and changes during game
3465 ;       * make_random functions smaller and used by different procs
3466 ;       # MAJOR BUG! a "random" value was placed somewhere in mem thus
3467 ;         creating bugs like unexplained loss of armor and stuff! (I think)
3468 ;
3469 ; 0.96.A31 -- 31.X.99 -- size 4836 + 888
3470 ;
3471 ;       # if you were hit when armor-icon selected, prog did weird stuff
3472 ;       + armor-bar (shows armor as a black line left at bottom)
3473 ;       # bugs involving armor-bar changing armor to a wrong value
3474 ;       # YES!!! the saving-bugs were caused by mmldir: it reset all data
3475 ;         at mem $8000, so data is now stored at asmexecram+6000 instead!
3476 ;       * external levels. All leveldata is loaded from "nemesis0"-var
3477 ;       * some optimization (like cal\ret>jp + unused code removed/shortened)
3478 ;       * storyline is loaded from level-file (will be compressed later..)
3479 ;       + story can be _between_ levels, not only at the start of a new game
3480 ;       * "new game" and "continue" in main menu are swapped (new comes 1st)
3481 ;       * enemy bullets can do more than one damage: differs per level
3482 ;       * collision does 4 damage, ground does 5, you start with 12 armor
3483 ;       # running the level-file no longer crashes your calc but just returns
3484 ;       * you now move 1.5 pixels per frame! this way you can outrun enemies
3485 ;       * hellofajob but enemy-data is now stored at one location in 6 bytes,
3486 ;         instead of two 4-byte spaces 40 bytes apart! (cleaner code; faster)
3487 ;       * ground/ceiling/stars are continued when at boss (c00l level 3 boss)
3488 ;
3489 ; 0.97.622 -- 06.VI.99 -- size 5kb
3490 ;
3491 ;       # bullets do damage in all levels
3492 ;       * more armor at armor-upgrade and extra armor at end of a level
3493 ;       - internal levels again (no need 4 external, safer/smaller)
3494 ;       # some registers not correctly pushed/popped
3495 ;       * several optimizations (init.procs some bytes smaller)
3496 ;       + bullets "charge up" (more damage) when not firing
3497 ;       + more powerful bullets have different sprites (larger=more damage)
3498 ;
3499 ;
3500 ;        + added        - removed       * changed       # bug fixed