version 0.99 rc1: hardcore mode, enemy updates
[nemesis.git] / nemesis.z80
1 ;----------------------------------------------------------------------------
2 ;-------------------------------- NEMESIS -----------------------------------
3 ;----------------------------------------------- cool arcade-shoot-em-up-game
4
5 ;------- by SHIAR | shiar0@hotmail.com | icq#43840958 | www.shiar.org -------
6
7 ;!!! This source should only be used for learning practises, do not !!!
8 ;!!! alter it, and certainly never  distribute an altered version!! !!!
9
10 ;TO DO:  levels 11,12,13 | draw bosses 12 and 13 (41/42)
11 ;        store B<>W mode | ship info at ship selection screen
12 ;        store ship sprite pointers as word | look over &&& markings
13
14 ;---------------------- nemesis.z80 start -----------------------------------
15
16 #include        "asm86.h"
17 #include        "ti86asm.inc"   ;standard ti86 romcalls
18 #include        "ti86abs.inc"   ;used to save hiscores and so
19
20         .org _asm_exec_ram
21
22 #define           cal   call    ;just to make it harder for you to understand
23 #define           psh   push    ; ^:D
24 #define           dnz   djnz    ;Dec&Jump while NonZero becomes Do w.Non-Zero
25
26 dispbuffer      = $81FA ;= $C9FA                ;virtual screen
27 ;VIDEO_MEM      = $FC00         ;tha big scareen
28
29 _clrWindow      = $4a86         ;_clrLCD and _clrScrn
30 _ex_ahl_bde     = $45f3         ;exchange values between AHL and BDE
31 _shracc         = $4383         ;like _shlacc but just the opposite :P
32 _dispahl        = $4a33         ;display value in ahl <100000 (cheap TI)
33 _asapvar        = $d6fc         ;our own variable name (likely "nemesis")
34
35 storepos        = _asm_exec_ram+7000    ;1024 bytes needed to store things
36
37 ;---------------------- in-game vars ----------------------------------------
38
39 just_fired      = storepos              ;  +0   ;counts how long a blast lasts
40 hiscorepos      = storepos              ;  +0   ;entering hiscore name
41
42 x               = storepos+1            ;  +1   ;your ship's position
43 y               = x+1                   ;  +2   ;your y-pos
44 firex           = y+1                   ;  +3   ;(1 byte)
45 firey           = firex+1               ;  +4   ;(1 byte)
46
47 eventleft       = firey+1               ;  +5   ;nr. of enemies still to come
48 level_enemy     = eventleft+1           ;  +6   ;enemy type
49 level_info      = level_enemy+1         ;  +7   ;ceiling/ground (%00) present
50 spacespace      = level_info+1          ;  +8
51 groundinfo      = spacespace+1          ;  +9
52 stars1          = groundinfo+1          ; +10   ;slow stars byte  (<< %1)
53 stars2          = stars1+1              ; +11   ;fast stars byte (<<< %1)
54 groundpos       = stars2+1              ; +12   $10
55 ceilingpos      = groundpos+16          ; +28   $10
56 nrstars1        = 10
57 starx1          = ceilingpos+16         ; +44   ;20
58 nrstars2        = 10
59 starx2          = starx1+(nrstars1*2)   ; +64   ;20
60
61 mm              = 4                             ;max. number of multiples
62 your_prevpos    = starx2+(nrstars2*2)   ; +84   ;14*mm+2 ;previous positions
63
64
65 enemies         = storepos+200          ;+200   ;info about each enemy
66 enemysize       = 11                            ;infobytes per enemy
67 nrenemies       = 16                            ;max. nr of enemies
68
69 ybullets        = enemies+(nrenemies*enemysize) ;60 bytes = 20(state,damg,x,y)
70 nrybuls         = 128                   ;+376\
71 ebullets        = ybullets+(nrybuls*4)  ;+888   ;30 bytes = 10(state,x,y)
72 nrebuls         = 48
73 lvlenemies      = ebullets+(nrebuls*3)  ;-1032
74
75 ;enemies:
76 ;       [HP64] [000000:HP left 00:(00=no enemy 01=exploding 1X=normal)]
77 ;       [ship sprite (DW!) or explosion frame] [x] [y] [movetype] [movecounter]
78 ;       [firecounter] [firefreq] [firetype]
79
80 ;---------------------- introduction ----------------------------------------
81
82          nop                    ;hello yas/ase/rascall/whathever
83          jp init                ;here's the program, but first: a description
84         .dw $0001               ;description type 2 (description + YASicon)
85         .dw Title               ;pointer to description (all shells)
86         .dw Icon                ;pointer to YAS icon
87
88 Title:  .db "Nemesis v0.99.829 by SHIAR",0
89
90 Icon:   .db 8,1                 ;icon for YAS: width = 1byte; height = 7bytes
91         .db %11100000           ; ███
92         .db %01111000           ;  ████
93         .db %00111110           ;   █████
94         .db %01111001           ;  ████  █
95         .db %00111110           ;   █████
96         .db %01111000           ;  ████
97         .db %11100000           ; ███             ;recommend 80x50 screen mode
98         .db 0                   ;YAS 0.92 compatibility
99
100 ;---------------------- init ------------------------------------------------
101
102 int_handler:                    ;new interrupt proc
103         ex  af,af'              ;just af only (no need for exx)
104         in  a,($03)             ;read bit 3 port 3
105         bit 3,a                 ;is ON key pressed?
106         jp  z,$0039             ;no: np, return
107         res 0,a                 ;yes: then we have a problem (freeze), so...
108         out ($03),a             ;...mask the ON key interrupts!
109         jp  $0039               ;all done, return
110 int_end:
111
112 init:   cal BUSY_OFF            ;turns the run-indicator off, obviously
113         cal _clrScrn            ;clean the screen
114         xor a                   ;ld a,0
115         res 2,(iy+13)           ;don't scroll the screen
116         cal _flushallmenus      ;remove TI menus
117
118 FixKeys:                        ;fixes some key problems like left+down bug
119         im  1
120         ld  a,$D4
121         ld  bc,$0100
122         ld  h,a
123         ld  l,c                 ;ld hl,$D400 (user silent link routine space)
124         ld  d,a
125         ld  e,b                 ;ld de,$D401
126         dec a                   ;ld a,$D3
127         ld  (hl),a
128         ldir                    ;fill $D400-D500 with $D3s (slink/user on)
129         ld  hl,int_handler      ;new interrupt handler
130         ld  d,a
131         ld  e,a                 ;ld de,$D3D3
132         ld  bc,int_end-int_handler
133         ldir                    ;load new handler at ($D3D3)
134         inc a                   ;ld a,$D4
135         ld  i,a
136         im  2
137
138 ;---------------------- main menu -------------------------------------------
139
140 LogoPut:
141         xor a                   ;white bitmask (a=0)
142         ld  hl,logo_nemesis     ;from...
143         ld  de,VIDEO_MEM+16     ;...to one line from top
144         ld  b,e                 ;ld b,16: one line
145 AboveLogo:
146         ld  (de),a              ;clear/n byte
147         inc de                  ;next
148         dnz AboveLogo           ;repeat for the first line
149         ld  bc,16*19            ;logo size
150         ldir                    ;display one line of logo
151
152         ld  hl,16*$33+VIDEO_MEM ;$33 rows down
153         ld  b,16*7              ;draw black 7 lines
154         ld  a,%11111111         ;horizontal line mask
155 underline:
156         ld  (hl),a              ;draw one piece of the divider-line
157         inc hl                  ;move right (8 pixels = 1 byte)
158         dnz underline           ;repeat
159
160         ld  hl,_txt_email       ;at the very bottom of tha screen
161         ld  (_penCol),hl
162         ld  hl,txt_email        ;hey, my e-mail address so SEND ME SOMETHING!!
163         cal _vputs              ;VERY important, so display in small font ?:}
164
165         set 3,(iy+5)            ;set white on black
166         ld  de,_txt_about       ;near the bottom of the screen
167         ld  (_penCol),de        ;hl=txt_email++=txt_about
168         cal _vputs              ;display version + me
169         res 3,(iy+5)            ;return to default black on white
170
171 dispmenu:
172         ld  de,$0304
173         ld  (_curRow),de
174         ld  hl,txt_menu1
175         cal _puts
176         ld  de,$0305
177         ld  (_curRow),de
178         ld  hl,txt_menu2
179         cal _puts
180
181 menuloop:
182         ld  a,0                 ;current menu item (0 or 1); 0 by default
183 menuitem =$-1
184         ld  h,$01
185         add a,4
186         ld  l,a
187
188         ld  a,5
189         ld  (_curRow),hl
190         cal _putc
191
192         ld  a,(menuitem)
193         ld  h,$01
194         sub 5
195         neg
196         ld  l,a
197
198         ld  a,32
199         ld  (_curRow),hl
200         cal _putc
201
202         cal getsomekeys         ;read keys (z if enter/2nd pressed)
203         jr  z,start_tha_freakin_game
204         cp  K_EXIT
205         jr  z,menuexit
206         cp  K_UP
207         jr  z,menuchange
208         cp  K_DOWN
209         jr  nz,menuloop
210 menuchange:
211         ld  hl,menuitem
212         ld  a,(hl)
213         xor 1                   ;0=1; 1=0
214         ld  (hl),a              ;set new menu item
215         jr  menuloop
216
217 start_tha_freakin_game:
218         ld  a,(menuitem)
219         dec a
220         cal nz,New_game         ;NEW GAME
221         jp  samelevel           ;CONTINUE: game_main_loop
222
223 menuexit:
224         ld  hl,0                ;reset score
225         ld  (your_score),hl     ;(prevents hiscore while never played)
226         jp  game_over           ;and go to game over screen
227
228 do_invert:                      ;invert screen (b<>w)
229         psh hl
230         psh af                  ;can't destroy b
231         ld  hl,_invert
232         ld  a,$98
233         xor (hl)                ;$2F (cpl) <-> $B7 (or a)
234         ld  (hl),a
235         pop af
236         pop hl
237         ret
238
239 mode_invert:
240         ld  hl,invertmode       ;change invert mode (will be stored)
241         ld  a,$98
242         xor (hl)                ;$2F (cpl) <-> $B7 (or a)
243         ld  (hl),a
244         ld  de,1
245         psh de                  ;size
246         psh hl                  ;dest (invertmode)
247         ld  hl,4+invertmode-_asm_exec_ram
248         psh hl                  ;src
249         jp  storesmtn
250
251 ;----------------------------------------------------------------------------
252 ;---------------------- game loop -------------------------------------------
253 ;----------------------------------------------------------------------------
254
255 game_main_loop:                 ;REPEATS FROM HERE EVERY FRAME
256         ld  hl,timer            ;update time
257         inc (hl)                ;increase by 1
258         ld  a,(hl)
259         and %11111
260         ld  hl,1                ;once every 32 frames, increase score by 1
261         cal z,scoreInc          ;do it
262
263 Clear_screen:
264         ld  hl,dispbuffer       ;move from (hl) = top left
265         ld  (hl),0              ;first pixel will be copied all over the screen
266         ld  de,dispbuffer+1     ;(de) = next pixel, thus clearing whole screen
267         ld  bc,16*56-1          ;loop 896 times = (128/8) * (64-8 for scorebar)
268         ldir                    ;all clear!
269
270         ld  a,0                 ;current frame/turn 0-255
271 timer =$-1
272         and %11                 ;a=0 once every 4 turns
273         jr  z,movestarsdone     ;don't move stars once every 4 frames
274         cal movestars1          ;move the stars on the FRONT layer
275         cal movestars2          ;move the distant stars
276 movestarsdone:
277         ld  a,(stars1)          ;star positions (the missing byte...)
278         ld  b,nrstars1          ;how many stars? now we know.
279         ld  hl,starx1           ;points to the position of the stars
280         cal DisplayStars        ;display front layer stars
281         ld  a,(stars2)          ;weren't you paying attention five lines ago?
282         ld  b,nrstars2          ;that many?! whow!
283         ld  hl,starx2           ;and there they are
284         cal DisplayStars        ;use the same procedure to display back layer
285
286         ld  a,(level_info)      ;level info
287         rra                     ;ground present? (%1)
288         jr  nc,game_stuff       ;no, so both non-present
289         rra                     ;bit representing the presence of any ceiling
290         cal nz,Handle_ceiling   ;scroll the ceiling (if any) +check4collision
291         cal Handle_ground       ;scroll the ground and check if we're dead
292
293 game_stuff:
294         cal Handle_Ship         ;move you
295         ld  a,(your_occ)        ;are you 100% OK?
296         or  a                   ;a=0??
297         jr  nz,_gamestuff1      ;then don't check for movements/fires/...
298
299 check_keys:
300         ld  a,%10111111         ;function keys (MORE,EXIT,2ND,F1,F2,F3,F4,F5)
301         out (1),a               ;ask for them
302         nop \ nop               ;delay 8 clocks
303         in  a,(1)               ;gettem!
304
305 check_exitkey:
306         bit 6,a                 ;test bit 6 = exit-key = EXIT
307         jp  z,game_over         ;<exit> pressed, so be it
308 check_morekey:                  ;another unused label... poor compiler
309         bit 7,a                 ;test bit 7 = more-key = PAUSE
310         psh af
311         cal z,Pause             ;yes, go to pause
312         pop af
313
314 check_firekey:
315         bit 5,a                 ;test bit 5 = 2nd-key = FIRE
316         ld  hl,check_selkey     ;where to continue after executing Fire_bullet
317         psh hl                  ;push hl on stack (instead of cal Fire_bullet)
318         jp  z,Fire_bullet       ;fire smtn (bulletstaillasermultiples+stuff..)
319         pop hl                  ;no cal to Fire_bullet made, so pop stack
320         ld  hl,just_fired       ;no:
321         ld  (hl),5              ;able to fire (five turns = laser duration)
322 laserdur =$-1                   ;SMC laser duration
323
324 check_selkey:
325         ld  a,%01011111         ;look at first column of keys (ALPHA to STO)
326         out (1),a
327         in  a,(1)               ;our precious keys
328
329         bit 6,a                 ;'bout the GRAPH key...
330         cal z,Teacher           ;you didn't _press_ it, did you?!?
331
332         rla                     ;test bit7 so we know f ALPHA has been pressed
333         cal nc,select           ;yeppy, select the currently selected upgrade
334
335         cal Enemies_hit         ;check for collision with enemies
336         cal inc_weapdamage
337
338 _gamestuff1:
339         cal Handle_enemies      ;move enemies
340
341         cal Handle_bullets      ;move your bullets + check for hits
342         cal Enemy_bullets       ;move enemy bullets
343
344         cal Level_event         ;insert enemies
345         cal Display_Screen      ;display all
346
347 delay:
348         halt                    ;delay and preserve batteries :)
349         jp  game_main_loop      ;LOOP ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
350
351 ;------- weapon -------
352
353 inc_weapdamage:
354         ld  a,0
355 weapincs =$-1
356         inc a
357         cp  97                  ;max. 96 times (=96/16=6 increases)
358         ret nc                  ;return if already maxed
359         ld  (weapincs),a        ;save new incs
360
361         and %11110000           ;clear last 4 bits so no cf when rotating
362                                 ;btw: AND resets cf
363         rra                     ;rotate acting as shift (srl a) but just 1B
364         rra
365         rra
366         rra                     ;increase once just every 16 turns
367         ld  b,a                 ;times to increase
368 incthedamage:
369         add  a,1                ;increase damage for one increase
370 weapdaminc =$-1
371         dnz incthedamage        ;a=total increase damage
372         ld  b,1                 ;minimal damage
373 weapdamage =$-1
374         add a,b                 ;a=total damage
375         ld  (curweapdamage),a   ;safe the current damage
376
377
378 disp_charge:                    ;display charge bar
379         ld  hl,(59*16)+VIDEO_MEM+3
380         ld  b,3
381 chargebarclr:
382         dec hl
383         ld  (hl),0
384         dnz chargebarclr
385
386         ld  a,(weapincs)        ;load bar size (0-80)
387         srl a                   ;half the size (0-40)
388         srl a                   ;again half that size (0-20 pixels)
389         ld  c,a                 ;psh a
390         srl a                   ;/2
391         srl a                   ;/4
392         srl a                   ;/8: don't display last 3 bits of a (later)
393         jr  z,nochargebar       ;if a=0 then it would loop 256x so skip it
394         ld  b,a                 ;loop b=a times
395 chargebar:                      ;starting at ($39*16)+VIDEO_MEM
396         ld  (hl),%11111111      ;draw a piece of the bar
397         inc hl                  ;next position
398         dnz chargebar           ;loop it b times
399 nochargebar:
400         ld  a,c                 ;pop a
401         and %111                ;display last bits of chargebar
402         ret z                   ;if armor=0 then bit = %00000000 (don't disp)
403         ld  b,a                 ;into B
404         xor a                   ;bit = %00000000
405 chargebarbit:
406         scf                     ;set carry flag
407         rra                     ;rotates A right and sets bit 7 (c-flag)
408         dnz chargebarbit        ;repeat B times (so if B=6 then a=%11111100)
409 chargebarready:                 ;               (an if B=3 then a=%11100000)
410         ld  (hl),a              ;draw this last byte
411         ret
412
413 ;--------------------------- ground -----------------------------------------
414
415 Handle_ground:
416         ld  a,(timer)
417         and %111                ;once every 8 frames
418         jr  nz,Display_ground   ;otherwise skip the scroll
419         ld  bc,15               ;scroll all 16 bytes minus one (teh new byte)
420         ld  hl,groundpos+1      ;from..
421         ld  de,groundpos        ;to (one byte to the left)
422         ldir                    ;LoaDIncreaseRepeat = scroll!
423
424         ld  a,(groundinfo)      ;what kind of ground
425         dec a                   ;type 1:
426         jr  z,ground_tunnel     ;tunnel effect
427 ground_boring:
428         ld  a,(groundpos)       ;type 0
429         jr  newground+1
430
431 ground_tunnel:
432         ld  a,(groundpos+14)
433         ld  d,a
434         ld  hl,spacespace
435         ld  bc,$500             ;range=0..4
436         cal Random              ;a=0..4
437         dec a                   ;a=-1..3
438         dec a                   ;a=-2..2
439         ld  b,a
440         add a,(hl)              ;add to spacesize (so +2..-2)
441         cp  10
442         jr  c,newground         ;>=0 then don't change
443         ld  c,a
444         ld  a,d
445         add a,b                 ;new position
446         or  a
447         jr  z,newground         ;may not be 0 (=256)
448         cp  -10
449         jr  nc,newground        ;and not be <0 (>246)
450 diffground:
451         ld  d,a
452         ld  (hl),c
453 newground:
454         ld  a,d
455         ld  (groundpos+15),a    ;save new byte on the right
456
457 Display_ground:
458         ld  b,16                ;screen width
459         ld  de,groundpos-1      ;height of current byte (previous actually)
460         psh de                  ;use later
461         ld  hl,dispbuffer+(56*16)-1 ;screen position
462         psh hl
463
464 groundloopright:
465         ld  c,b                 ;push b for groundloopup
466         pop hl \ inc hl         ;get screen position and go one right
467         pop de \ inc de         ;get height info and set to the next byte
468         psh de \ psh hl         ;save these for the next time
469         ld  a,(de)              ;height of current byte
470         ld  b,a                 ;save in b
471
472         ld  de,16               ;to substract to go one line up
473         ld  a,%11111111         ;bitmask black
474         or  a
475 groundloopup:
476         ld  (hl),a              ;display black byte
477         sbc hl,de               ;go up (sbc must be used for 16-bit sub)
478         dnz groundloopup        ;and loop >groundpos< times
479
480         ld  b,c                 ;pop b used by groundloopup
481         dnz groundloopright     ;loop right for entire screen (16x)
482         pop hl \ pop hl         ;restore stack
483
484 CheckGround:                    ;check for collision with the ground
485         ld  a,(x)
486         srl a
487         srl a
488         srl a
489         inc a
490         ld  l,a
491         ld  h,0
492         ld  de,groundpos
493         add hl,de
494         ld  a,(y)
495         sub 57-7
496         neg
497         cp  (hl)
498         ret nc
499         ld  b,auch_ground
500         jp  damage_you
501
502 ;--------------------------- ceiling ----------------------------------------
503
504 Handle_ceiling:
505         ld  a,(timer)
506         and %111                ;once every 8 frames
507         jr  nz,Display_ceiling  ;otherwise skip the scroll
508         ld  bc,15               ;scroll all 15 bytes (16th is new position)
509         ld  hl,ceilingpos+1     ;from..
510         ld  de,ceilingpos       ;to (one byte to the left)
511         ldir                    ;LoaDIncreaseRepeat = scroll!
512
513         ld  a,(groundinfo)      ;what kind of ceiling
514         dec a                   ;type 1:
515         jr  z,ceiling_tunnel    ;tunnel effect
516 ceiling_boring:
517
518 ceiling_tunnel:
519         ld  a,(ceilingpos+14)
520         ld  d,a                 ;d=new ceiling
521         ld  hl,spacespace
522
523         ld  bc,$201             ;range=1..3
524         cal Random              ;a=1-3
525         dec a
526         jr  z,newceiling        ;1:same
527         dec a
528         jr  z,ctunnelup         ;2:up
529 ctunneldown:                    ;3:down
530         ld  a,(hl)
531         or  a                   ;(spacespace)=0:
532         jr  z,newceiling+2      ;keep same ceiling
533         inc (hl)
534         inc d
535         jr  newceiling
536 ctunnelup:
537         ld  a,1
538         cp  d                   ;if size=1 then don't
539         jr  z,newceiling
540         dec d
541         dec (hl)
542 newceiling:
543         ld  a,d
544         ld  (ceilingpos+15),a   ;save the new byte
545
546 Display_ceiling:
547         ld  b,16                ;screen width
548         ld  de,ceilingpos-1     ;height of current byte
549         psh de                  ;use later
550         ld  hl,dispbuffer-17    ;screen position
551         psh hl
552
553 ceilingloopright:
554         ld  c,b                 ;push b for groundloopup
555         pop hl \ inc hl         ;get screen position and go one right
556         pop de \ inc de         ;get height info and set to the next byte
557         psh de \ psh hl         ;save these for the next time
558         ld  a,(de)              ;height of current byte
559         ld  b,a                 ;save in b
560
561         ld  de,16               ;to substract to go one line up
562         ld  a,%11111111         ;bitmask black
563         or  a
564 ceilingloopdown:
565         ld  (hl),a              ;display black byte
566         add hl,de               ;go down
567         dnz ceilingloopdown     ;and loop >groundpos< times
568
569         ld  b,c                 ;pop b used by groundloopup
570         dnz ceilingloopright    ;loop right for entire screen (16x)
571         pop hl \ pop hl         ;restore stack
572
573 CheckCeiling:                   ;check for collision with the ground
574         ld  a,(x)               ;your x
575         srl a                   ;x/2
576         srl a                   ;x/4
577         srl a                   ;x/8 (current ceiling-byte)
578         inc a                   ;correction
579
580         ld  l,a                 ;hl = a
581         ld  h,0                 ;"
582         ld  de,ceilingpos       ;first ceiling-byte
583         add hl,de               ;current ceiling-byte
584         ld  a,(y)               ;your y-pos
585         inc a
586         cp  (hl)                ;compare with ceiling
587         ret nc                  ;carry if ceiling is above you
588         ld  b,auch_ground
589         jp  damage_you          ;otherwise you don't wanna be in that ship
590
591 ;--------------------------- move stars -------------------------------------
592
593 DisplayStars:                   ;inputs: hl=starx# a=stars# b=nrstars#
594         ld  e,(hl)
595         inc hl
596         ld  d,(hl)
597         ld  (de),a
598         inc hl
599         dnz DisplayStars
600         ret                     ;let's comment this: returns
601
602 movestars2:
603         ld  ix,starx2
604         ld  a,(stars2)
605         rlca                    ;move bits (star) left
606         ld  (stars2),a
607         ret nc                  ;if star didn't went from left to right bit
608         ld  b,nrstars2          ;otherwise move all stars one byte left
609         jr  movestars_loop
610
611 movestars1:
612         ld  ix,starx1
613         ld  a,(timer)
614         rra
615         ld  a,(stars1)
616         ret c
617         rlca
618         ld  (stars1),a
619         ret nc
620         ld  b,nrstars1
621
622 movestars_loop:
623         ld  h,(ix+1)
624         ld  l,(ix)
625         dec hl
626
627         ld  a,l
628         and %00001111
629         cp  (dispbuffer&15)-1   ;$C9FAand15-- = 9
630         jr  nz,newstarok
631         cal RandomY
632
633 newstarok:
634         ld  (ix),l
635         ld  (ix+1),h
636         inc ix \ inc ix
637         dnz movestars_loop
638         ret                     ;for stupid people, here's another comment...
639
640 ;--------------------------- pause ------------------------------------------
641
642 Pause:
643         ld  hl,_txt_pause
644         ld  (_penCol),hl
645         ld  hl,txt_pause
646         cal _vputs              ;display small font
647         ld  hl,_txt_pressenter  ;top centered
648         ld  (_curRow),hl
649         ld  hl,txt_pressenter   ;"Enter to continue"
650         cal _puts               ;display message
651 pause:
652         cal getsomekeys         ;GET_KEY w/ halts and checks for enter
653         ret z                   ;enter/second pressed: continue game
654         cp  K_F1                ;F1 pressed?
655         jr  nz,notinvert
656         cal do_invert           ;if so then change invert screen (AF saved)
657         cal mode_invert         ;and screen mode (will be saved)
658 notinvert:
659         ld  hl,CONTRAST         ;contrast setting (0-31)
660         ld  b,(hl)              ;load contrast into b
661         cp  K_UP                ;+ key changes contrast up
662         jr  nz,contr_not_up
663         inc b                   ;increase contrast
664         jr  setcontrast         ;set
665 contr_not_up:
666         cp  K_DOWN              ;- key
667         jr  nz,pause            ;nope: loop
668         dec b                   ;decrease contrast
669 setcontrast:
670         ld  a,b
671         ld  (hl),a
672         out (2),a               ;and set it
673         cal releasekeys
674         jr  pause               ;and loop
675
676 ;--------------------------- teacher ----------------------------------------
677
678 Teacher:
679         ld  (iy+12),5           ;enable flashing cursor
680         cal _clrWindow          ;top left
681         ld  hl,txt_teacher
682         cal _puts               ;display message
683         cal releasekeys
684
685 teacherloop:
686         cal _getkey             ;enter low-power mode and wait for key
687         cp  kEnter              ;enter pressed?
688         jr  z,teacherans
689         cp  kGrMenu             ;keypressed = graph?
690         jr  nz,teacherloop      ;no, wait some more
691
692         ld  (iy+12),0           ;disable cursor
693         cal releasekeys
694         jp  disp_icons          ;+ret
695
696 teacherans:
697         ld  a,' '
698         cal _putc
699
700         ld  hl,$0701
701         ld  (_curRow),hl
702         ld  hl,txt_teacherans
703         cal _puts
704         jr  teacherloop
705
706
707 ;--------------------------- exit -------------------------------------------
708
709 quit:   im  1                   ;release keyfix procedure
710         set 2,(iy+13)           ;set back screen scrolling
711         xor a
712         ld (_asapvar+1),a       ;next Asm( run will reload the program
713         ld  hl,dispbuffer       ;graph-screen location
714         ld  de,dispbuffer+1
715         ld  (hl),a
716         ld  bc,1024-1           ;do it 1024 times = entire screen
717         ldir
718         jp  _clrWindow          ;as _clrLCD but also clears TEXT_MEM (like the
719                                 ;_clrScrn) AND also executes _homeup and ret
720
721 ;--------------------------- display ----------------------------------------
722
723 Display_Screen:
724         ld  hl,dispbuffer       ;from buffer (top left)
725         ld  de,VIDEO_MEM        ;to real screen (top left)
726         ld  c,56                ;display height = 64 bytes (minus 8 for bar)
727 displayloop:
728         ld  b,16                ;display width = 16 bytes (16*8bits=256pixels)
729 displaytloop:
730         ld  a,(hl)              ;copy byte from (hl)
731 _invert:                        ;SMC: cpl <-> or a
732         cpl                     ;xor $ff: invert byte (white<=>black)
733         ld  (de),a              ;to (de)
734         inc hl \ inc de         ;next byte
735         dnz displaytloop        ;16x hl >> de
736         dec c                   ;next line
737         jr  nz,displayloop      ;loop 56x
738
739         ld  hl,time2invert
740         ld  a,(hl)
741         or  a                   ;(time2invert)=0:
742         jr  z,noinvert          ; do nothing
743         dec a                   ;otherwise decrease
744         cal z,do_invert         ;if it became 0 then invert
745         ld  (hl),a              ;save new value
746 noinvert:
747
748         ld  hl,$396b            ;Display Score
749         ld  (_penCol),hl        ;bottom right of screen
750         ld  hl,(your_score)
751
752 _D_HL_DECI:                     ;------- display 5-digit value -------
753         ld  de,savestr+4        ;savenr saves number string
754         ld  b,5                 ;five digits
755 ldhld:  cal UNPACK_HL           ;one digit of hl
756         add a,'0'               ;make number
757         ld  (de),a              ;save into savenr
758         dec de                  ;point to next digit
759         dnz ldhld               ;repeat for all digits
760
761         ld  hl,savestr          ;we (the program) saved the value righthere
762         jp  _vputs              ;the only thing left to do is to display it
763
764 savestr:                        ;@here the score will be stored
765         .db "00000",0           ;don't worry, it's just temporary
766
767 ;------------------------- handle ship --------------------------------------
768
769 Handle_Ship:
770         ld  a,(your_occ)        ;are
771         or  a                   ;you
772         jr  z,ok                ;ok?
773
774         inc a                   ;no! next (explosion)frame
775         ld  (your_occ),a        ;save
776
777         cp  64+1                ;last explosion frame? (1-16=1st;49-64=4th)
778         jp  c,exploding_you     ;not yet: display explosion
779         cp  64+16               ;delay finished?
780         jp  z,You_die           ;yes = game over
781         ret                     ;don't display anything
782
783 ;----move----
784 ok:                             ;we are
785         ld  a,%01111110         ;get arrow keys
786         out (1),a               ;it's cold outside
787         ld  hl,y                ;instead of nop\nop do something usefull
788         in  a,(1)               ;come back in
789
790         ld  b,a                 ;psh a (keys)
791         xor -1                  ;inverted a: 0 if arrow-key has been pressed
792         ld  a,(your_multiples)          ;(btw: CPL doesn't set any flags)
793         res 7,a                 ;reset move bit (no flags changed)
794         jr  z,adv_ok            ;if so, leave the multiples where they are
795         set 7,a                 ;set move bit
796 adv_ok: ld  (your_multiples),a
797
798         ld  a,(timer)           ;framecounter
799         and %1                  ;switches 0<>1 each frame
800         inc a                   ;a = 1 or 2 (1.5 avg)
801         ld  c,a                 ;c = your_speed
802
803         ld  a,b                 ;pop a (keys)
804         rra                     ;rotate right (put last bit in c)
805         ld  b,a                 ;we need a later
806
807         jr  c,no_down
808         ld  a,(hl)
809         add a,c
810         cp  50                  ;56-6 = bottom of screen
811         jr  nc,no_down
812         ld  (hl),a
813 no_down:
814         dec hl
815         rr  b                   ;because we now use b, it's rr instead of rra
816         jr  c,no_left
817         ld  a,(hl)
818         sub c                   ;<dec a> doesn't affect c-flag
819         jr  c,no_left           ;-1 = left side
820         ld  (hl),a
821 no_left:
822         rr  b
823         jr  c,no_right
824         ld  a,(hl)
825         add a,c
826         cp  122                 ;128-6 = right side
827         jr  nc,no_right
828         ld  (hl),a
829 no_right:
830         ld  d,(hl)              ;d=x
831         inc hl
832         rr  b
833         jr  c,no_up
834         ld  a,(hl)
835         sub c                   ;<dec a> doesn't affect carry-flag
836         jr  c,no_up             ;-1 = top of screen
837         ld  (hl),a              ;save new y
838
839 no_up:  ld  e,(hl)              ;e=y
840         ld  ix,spr_ship01       ;normal ship sprite
841 your_shipspr =$-2
842         ld  hl,your_shield      ;shielded?
843         ld  a,(hl)              ;load time in a
844         or  a                   ;is it 0?
845         jr  z,disp_ship         ;yes so ship = normal (display \ continue)
846
847         ld  a,(timer)           ;load frame nr.
848         and %00000111           ;a=0 once every four frames
849         jr  nz,not_time         ;a<>0 = not time to update counter
850         dec (hl)                ;decrease inv-time left
851 not_time:
852         and %00000100           ;a switches 0<->1 every 2 frames
853         jr  z,disp_ship         ;show normal ship
854 inv_flicker:
855         ld  bc,spr_ship01i-spr_ship01
856         add ix,bc               ;display invulnerable ship
857 disp_ship:
858         cal safeputsprite       ;display your ship; save de
859
860 ;----multiples----
861
862 handle_multiples:
863         ld  a,(your_multiples)  ;do you have multiples
864         ld  b,a                 ;save a for 2nd check
865         and %1111               ;no? (last four bits = nr of multiples)
866         ret z                   ;then don't handle them either
867         bit 7,b                 ;move the multiples??? (=move bit set?)
868         jr  z,mult_adv          ;nope, just let them (saves (y)in y, (x)in x)
869
870         psh de                  ;current position = needed later
871         ld  hl,mm*14+1+your_prevpos     ;previous positions
872         ld  de,mm*14+3+your_prevpos     ;move all positions one back
873         ld  bc,mm*14+2
874         lddr                    ;change 0-57 -> 2-59 (if mm=4 that is)
875         inc hl                  ;your_prevpos+0
876         pop de
877         ld  (hl),d              ;x-pos
878         inc hl                  ;=current position
879         ld  (hl),e              ;y-pos
880
881 mult_adv:
882         ld  ix,spr_multiple     ;normal sprite
883         ld  hl,timer
884         bit 3,(hl)              ;change sprites every 8 turns
885         jr  z,disp_multiples
886         ld  ix,spr_multiple2    ;second sprite
887 disp_multiples:
888         ld  hl,your_prevpos+16  ;first pos.
889 dispmultiplesloop:
890         psh af
891         psh hl
892         ld  d,(hl)              ;load coords
893         inc hl
894         ld  e,(hl)
895         psh ix
896         cal putsprite           ;display
897         pop ix                  ;same sprite next time ;)
898         pop hl
899         ld  de,14
900         add hl,de               ;next multiple
901         pop af                  ;counter
902         dec a
903         ret z                   ;return if all done
904         jr  dispmultiplesloop   ;loop
905
906 ;----explode----
907
908 exploding_you:
909         srl a                   ;half the framerate
910         srl a                   ;half that framerate
911         srl a                   ;and half again that framerate
912         ld  hl,x-1
913         ld  ix,spr_yexplosion   ;base sprite
914
915 explosion_stuff:                ;in:a=frame*2+(0 to 1); (hl)=xpos-- ix=sprite
916         and %11111110
917         add a,a
918         add a,a                 ;frame*8
919         ld  c,a
920         ld  b,0                 ;bc=a
921         add ix,bc               ;go to correct sprite (each spr. is 8 bytes)
922         inc hl                  ;@x
923         ld  d,(hl)              ;load xpos
924         inc hl                  ;@y
925         ld  e,(hl)              ;and y
926         jp  putsprite           ;and display it too
927
928 ;----hit----
929
930 damage_you:                     ;damages you B points
931         ld  a,(hardcore)        ;hardcore mode?
932         or  a
933         jr  z,damageok          ;0 = no  = don't modify
934 ;       sla b                   ;1 = yes = double tha damage (b shifted left)
935         .db $CB,$30     ;sll b  ;damage=2b|1 (CB3r = unsupported SLL r)
936 damageok:
937         ld  a,(your_shield)     ;shield left?
938         or  a
939         jr  z,dothadamage       ;no shield
940         srl b                   ;shield: half the damage
941 dothadamage:
942         ld  hl,time2invert
943         xor a                   ;a=0
944         cp  (hl)                ;not already inverted?
945         cal z,do_invert         ;then invert screen
946         ld  (hl),2              ;change back 2 frames from now
947
948         ld  hl,your_armor       ;armor left
949         ld  a,(hl)              ;load hp in A
950         sub b                   ;decrease hp by B
951         jr  nc,newarmor         ;>=0hp left so don't explode
952         ld  a,%01               ;occ %xxxxxx01 = explode
953         ld  (your_occ),a        ;too bad, you're dead meat
954 newarmor:
955         ld  (hl),a              ;save decreased hp
956         jp  disp_armor          ;and display new value
957
958 ;------------------------- place multiples ----------------------------------
959
960 Place_multiples:
961         ld  hl,your_prevpos     ;place all previous positions
962         ld  b,mm*7+1            ;all saved positions of them (14 per multiple)
963 place_multiples:
964         ld  (hl),e              ;set prev-x to d
965         inc hl                  ;next
966         ld  (hl),d              ;set prev-y to e
967         inc hl                  ;next
968         dnz place_multiples     ;repeat
969         ret
970
971 ;------------------------- select upgrade -----------------------------------
972
973 inc_armor:
974         ld  a,(your_armor)      ;load current armor
975         cp  50-6                ;may not become >=50
976         jr  c,doincarmor        ;ok then just add 6
977         ld  a,49-6              ;set to maximum (6 will be added below)
978 doincarmor:
979         add a,6                 ;add 6 to armor
980         ld  (your_armor),a      ;change armor
981         ret
982
983 select:
984         ld  de,your_weapon      ;current weapon, required for most selections
985         ld  hl,your_pickup      ;select pickups
986         ld  a,(hl)              ;load pickups taken so far
987         dec a                   ;is it 1?
988         ret m                   ;return if it's 0 (no pickups)
989         jr  nz,select2          ;no, carry on
990 select1:
991         ld  (hl),a              ;reset pickups
992         cal inc_armor           ;increase armor (like at end of level)
993         ld  a,30                ;activate shield for 30*4=120 frames
994         ld  (your_shield),a
995         jr  disp_icons          ;display and return
996 select2:
997         dec a                   ;is it 2?
998         jr  nz,select3          ;no, carry on
999         ld  (hl),a              ;reset (otherwise could be used to cheat)
1000         ld  a,(de)              ;(your_weapon)
1001         cp  maxweapon
1002         jr  nc,disp_icons       ;no beam with laser
1003         ld  a,(your_extramode)  ;indicates whether this is tailbeam/double
1004         ld  (your_extra),a      ;ready extra beam
1005         jr  disp_icons          ;display 'n return
1006 select3:
1007         dec a                   ;is it 3?
1008         jr  nz,select4          ;no, carry on
1009         ld  (hl),a              ;reset pickups
1010         ld  a,(de)              ;(your_weapon)
1011         inc a                   ;next
1012         cp  maxweapon
1013         jr  c,selected3         ;weapon OK
1014         jr  z,disp_icons        ;weapon maxed out
1015         xor a                   ;laser was selected: set to first weapon
1016 selected3:
1017         ld  (de),a              ;set new weapon
1018         cal loadweapon          ;load it (damage and stuff)
1019         xor a
1020         ld  (your_multiples),a  ;no multiples with beam
1021         jr  disp_icons          ;display n return
1022 select4:
1023         dec a                   ;is it 4?
1024         jr  nz,select5          ;no, carry on again
1025         ld  (hl),a              ;reset pickups
1026         ld  (your_extra),a      ;no extra beams (tailbeam/up-double)
1027         ld  a,(de)              ;(your_weapon)
1028         cp  maxweapon           ;upgrade from bullet?
1029         jr  nc,upgradelaser     ;nope, just upgrade
1030         ld  a,maxweapon-1       ;yes, set laser #1
1031 upgradelaser:
1032         inc a                   ;next laser
1033         cp  maxlaser
1034         jr  nc,disp_icons       ;laser maxed out
1035         ld  (de),a
1036         cal loadweapon
1037         jr  disp_icons          ;display + return
1038 select5:
1039         dec a                   ;is it 5?
1040         jr  nz,select6          ;no, carry on once more
1041         ld  (hl),a              ;reset pickups
1042         ld  a,(de)              ;(your_weapon)
1043         cp  maxweapon+1         ;laser or beams?
1044         jr  c,disp_icons        ;if beams used then no multiples
1045         ld  hl,your_multiples
1046         ld  a,(hl)              ;multiples you already got
1047         and %1111               ;reset movebit so (your_multiples)=real value
1048         inc a                   ;one more
1049         cp  mm+1
1050         jr  nc,enoughmultiples  ;maxed out
1051         ld  (hl),a
1052 enoughmultiples:
1053         ld  de,(x)
1054         dec a                   ;if this is your first multiple then...
1055         cal z,Place_multiples   ;reset multiples positions
1056         jr  disp_icons          ;display, return
1057 select6:
1058         ld  (hl),0              ;reset pickups
1059 ;       jr  disp_icons
1060
1061 ;--------------------------- show icon --------------------------------------
1062
1063 disp_icons:
1064  psh bc \ psh de \ psh hl \ psh ix ;&&&
1065
1066         ld  hl,VIDEO_MEM+(16*56);56 rows down = eight rows from bottom
1067         ld  (PutWhere),hl       ;place icons at bottom of normal screen
1068         ld  b,16                ;draw 16x (screen width)
1069         ld  a,%11111111         ;horizontal line mask
1070         cal drawline            ;draw divider-line
1071
1072         ld  b,16*7              ;draw 16x (screen width) 7x (height)
1073         xor a                   ;blank line mask
1074         cal drawline            ;clear scorebar
1075
1076 disp_lives:
1077         ld  de,5                ;(0,5)
1078         ld  a,(your_lives)      ;nr of lives
1079         or  a
1080         jr  z,displivesdone     ;no lives
1081         ld  b,a
1082 displivesloop:
1083         psh bc
1084         ld  ix,spr_lship
1085         cal safeputsprite       ;put li'l ship
1086         ld  a,lshipsize+1
1087         add a,d
1088         ld  d,a                 ;x=x+5
1089         pop bc
1090         dnz displivesloop       ;one ship per life
1091 displivesdone:
1092         cal disp_armor          ;display bar
1093
1094         ld  ix,spr_icon01       ;torpedoIcon
1095         ld  de,$1901            ;icon #1
1096         cal putwidesprite       ;display icon
1097
1098         ld  ix,spr_icon00
1099         ld  a,(your_extra)
1100         or  a
1101         jr  z,no_tail
1102         ld  ix,spr_icon02a      ;tailbeamIcon
1103         dec a
1104         jr  z,no_tail           ;(your_extra)=1 = tailbeam
1105         ld  ix,spr_icon02b      ;updoubleIcon
1106 no_tail:
1107         ld  de,$2901            ;icon #2
1108         cal putwidesprite       ;display
1109
1110         ld  ix,spr_icon00
1111         ld  a,(your_weapon)     ;ur weapon
1112         cp  maxweapon           ;laser?
1113         psh af                  ;a=(your_weapon); cf=bullets
1114         jr  nc,no_bullets       ;=laser
1115         ld  hl,$3945            ;position to display bullet-type digit
1116         pop af                  ;digit=(your_weapon)
1117         psh af
1118         inc a                   ;1 = weapon #1 (=0)
1119         ld  (_penCol),hl        ;set location
1120         add a,'0'               ;make digit
1121         cal _vputmap            ;display char
1122         ld  ix,spr_icon03       ;bulletIcon
1123 no_bullets:
1124         ld  de,$3901            ;icon #3
1125         cal putwidesprite       ;display icon
1126
1127         ld  ix,spr_icon00       ;emptyIcon
1128         pop af                  ;ld a,(your_weapon)
1129         ld  b,a
1130         jr  c,no_laser          ;popped carry
1131         ld  hl,$3955            ;position to display bullet-type digit
1132         ld  (_penCol),hl        ;set location
1133         ld  a,b                 ;(your_weapon)  ;load = faster than push
1134         sub maxweapon-1         ;1 = laser #1 (=maxweapon)
1135         add a,'0'               ;make digit
1136         cal _vputmap            ;display char
1137         ld  ix,spr_icon04       ;laserIcon
1138 no_laser:
1139         ld  de,$4901            ;icon #4
1140         cal putwidesprite
1141
1142         ld  ix,spr_icon00       ;emptyIcon
1143         ld  a,(your_multiples)
1144         and %111
1145         jr  z,no_multiples
1146         ld  ix,spr_icon05
1147 no_multiples:
1148         ld  de,$5901            ;icon #5
1149         cal putwidesprite
1150
1151         ld  ix,spr_dividerline
1152         ld  de,$6901
1153         cal putwidesprite
1154
1155         ld  a,(your_pickup)     ;pickups taken
1156         add a,a                 ;picks*2 (sets z-flag)
1157         jr  z,iconsdone         ;return if no pickups
1158         add a,a                 ;picks*4
1159         add a,a                 ;picks*8
1160         add a,a                 ;picks*$10
1161         add a,$09               ;add 0ah
1162         ld  d,a                 ;y-pos = picks * $10 + $0a (19,29,39,49,59)
1163         ld  e,$01               ;x-pos = bottom (1a01,2a01,3a01,4a01,5a01)
1164
1165         ld  ix,spr_icon
1166         cal putwidesprite
1167 iconsdone:
1168         ld  hl,dispbuffer       ;normal game-screen
1169         ld  (PutWhere),hl       ;set sprite-position to normal screen
1170
1171  pop ix \ pop hl \ pop de \ pop bc
1172         ret
1173
1174 disp_armor:
1175         ld  de,16               ;line size
1176         ld  hl,(57*16)+VIDEO_MEM+3
1177         ld  b,3
1178 armorbarclr:
1179         dec hl
1180         ld  (hl),0
1181         add hl,de
1182         ld  (hl),0
1183         sbc hl,de
1184         dnz armorbarclr
1185
1186         ld  a,(your_armor)      ;load your armor (<50)
1187         srl a                   ;/2 (<25)
1188         ld  c,a                 ;psh a
1189         and %11111000           ;clear last three bits
1190         rra                     ;so we can use rotate instead of shift right
1191         rra                     ;which saves 3(-2) bytes and speed
1192         rra                     ;/8: don't display last 3 bits of a (later)
1193         jr  z,noarmorbar        ;if a=0 then it would loop 256x so skip it
1194         ld  b,a                 ;loop b=a times
1195 armorbar:                       ;starting at ($39*16)+VIDEO_MEM
1196         ld  (hl),%11111111      ;draw a piece of the bar
1197         add hl,de               ;one down (resets carry)
1198         ld  (hl),%11111111      ;same piece
1199         sbc hl,de               ;up again
1200         inc hl                  ;next position
1201         dnz armorbar            ;loop it b times
1202
1203 noarmorbar:
1204         ld  a,c                 ;pop a
1205         and %111                ;display last bits of armor
1206         ret z                   ;if armor=0 then bit = %00000000 (don't disp)
1207         ld  b,a                 ;into B
1208         xor a                   ;bit = %00000000
1209 armorbarbit:
1210         scf                     ;set carry flag
1211         rra                     ;rotates A right and sets bit 7 (c-flag)
1212         dnz armorbarbit         ;repeat B times (so if B=6 then a=%11111100)
1213 armorbarready:                  ;               (an if B=3 then a=%11100000)
1214         ld  (hl),a              ;draw this last byte
1215         add hl,de
1216         ld  (hl),a              ;and just below
1217         ret
1218
1219 drawline:
1220         ld  (hl),a              ;draw one piece of the divider-line
1221         inc hl                  ;move right (8 pixels = 1 byte)
1222         dnz drawline            ;repeat (16bytes * 8pixels =128= screen width)
1223         ret
1224
1225 ;------------------------- fire bullet --------------------------------------
1226
1227 fire_multiple:
1228         psh af
1229         psh ix                  ;save ix for next fire
1230         cal fireany             ;fire from multiple position
1231         pop ix                  ;saving ix is much faster than recalculating
1232         pop af                  ;number of multiples
1233         dec a                   ;one just displayed
1234         pop hl                  ;ret
1235         ret z                   ;ret2 if none left
1236         jp  (hl)                ;real ret
1237
1238 fire_multiples:
1239         ld  hl,(your_prevpos+16);then, fire from multiple position
1240         cal fire_multiple
1241         ld  hl,(your_prevpos+30)
1242         cal fire_multiple
1243         ld  hl,(your_prevpos+44)
1244         cal fire_multiple
1245         ld  hl,(your_prevpos+58)
1246         cal fire_multiple       ;no JP: that messes up the stack
1247         ret
1248
1249 Fire_bullet:
1250         ld  hl,just_fired       ;=for how long you may hold fire (2nd)
1251         ld  a,(hl)              ;a = time left
1252         dec a                   ;decrease timer
1253         ret z                   ;may not fire when (just_fired) became 0
1254         ld  (hl),a              ;save new decreased value
1255
1256         ld  a,(your_weapon)     ;if you have bullets.....
1257         cp  maxweapon
1258         jr  nc,fireOK           ;>weapons = laser
1259         ld  (hl),1              ;bullet may last one turn (just fire 1 bullet)
1260 fireOK:
1261         ld  a,(your_weapon)     ;weapon nr.
1262         ld  ix,weapondata+2
1263         add a,a                 ;weap*2
1264         add a,a                 ;    *4
1265         add a,a                 ;    *8
1266         ld  c,a
1267         ld  b,0                 ;go to current weapon (bc=a)
1268         add ix,bc               ;ix=weapon ptr
1269
1270         ld  a,(your_multiples)  ;any multiples?
1271         and %1111               ;nr. of multiples
1272         cal nz,fire_multiples   ;if >0 then fire them too
1273         ld  hl,(x)              ;fire from ship position (x)
1274 fireany:                        ;HL=(x,y)
1275         ld  (firex),hl          ;set position to fire from
1276         ld  b,3  ;or use the proc at fireOK with ld ix,weapondata+2-(256*3)
1277 fire_weapon:
1278         psh bc                  ;save counter
1279         ld  a,(ix)              ;load this weapon
1280         ld  c,a                 ;save bulletType in c
1281         and %11100000           ;%111?????=laser
1282         cp  %11100000           ;is it?
1283         cal z,fire_laser        ;fire laser (will set c=0 when done)
1284         xor a                   ;<>0=bullet
1285         cp  c                   ;c<>0?
1286         cal nz,fire_ybullet     ;then fire bullet
1287         inc ix                  ;otherwise fire next weapon
1288         inc ix
1289         pop bc                  ;weapon counter (do 3 weapons)
1290         dnz fire_weapon
1291
1292 fire_tail:
1293         ld  ix,extrabulletpos-1 ;extra bullet's position
1294         ld  hl,your_extra       ;data
1295         ld  a,(hl)
1296         or  a
1297         ret z
1298         ld  c,tailbeam          ;tailbeam weapon data
1299         dec a                   ;(your_extra)=1
1300         jr  z,fire_ybullet      ;=tail
1301         ld  c,doublebeam        ;up double data
1302                                 ;(your_extra)=2 =double
1303 ;-----fire BULLETs-----
1304
1305 fire_ybullet:           ;fire bullet type=C dam=(curweapdamage) at (firex/y)
1306         ld  hl,ybullets         ;check for unused bullet
1307         ld  de,4
1308         ld  b,nrybuls
1309 find_ybullet:
1310         ld  a,(hl)
1311         or  a
1312         jr  z,found_ybullet     ;0 = no bullet here
1313         add hl,de
1314         dnz find_ybullet        ;look next bullet
1315         ret                     ;none found, return don't fire
1316
1317 found_ybullet:
1318         ld  (hl),c              ;use the bullet and set correct bullet-type
1319         inc hl                  ;@damage
1320         ld  (hl),1              ;set bullet damage
1321 curweapdamage =$-1
1322         ld  a,(firex)           ;your x-pos
1323         add a,5                 ;place bullet in front of you
1324         inc hl                  ;go to bullet-x
1325         ld  (hl),a              ;set x
1326
1327         ld  a,(firey)           ;your y-pos
1328         add a,(ix+1)            ;place bullet at the middle of your ship
1329         inc hl                  ;go to bullet-y
1330         ld  (hl),a              ;set y
1331
1332         xor a
1333         ld  (weapincs),a        ;reset damage
1334         ret
1335
1336 ;-----fire LASER-----
1337
1338 fire_laser:
1339         ld  b,0                 ;overflow counter
1340         ld  hl,firex
1341         ld  d,(hl)              ;d = your x-pos
1342         inc hl
1343
1344         ld  a,(hl)              ;base y-coord (firey)
1345         add a,(ix+1)            ;at specified offset (most likely the middle)
1346         ld  e,a                 ;save laser-y in e
1347         psh de                  ;save unmodified (x,y)
1348         add a,a                 ;y*2
1349         add a,a                 ;y*4
1350         add a,a                 ;y*8
1351         rl  b                   ;b (=0) =b*2+overflow (if y>32 then bc=bc+256)
1352         add a,a                 ;y*16 (width of screen)
1353         rl  b                   ;b=b*2+overflow (if y>64 then bc=bc+512)
1354         inc a                   ;8 pixels to right (a=even so no overflow)
1355
1356         srl d                   ;X/2
1357         srl d                   ;X/4
1358         srl d                   ;X/8
1359         add a,d                 ;a = (Y*16+X/8) mod 256 (c set on overflow)
1360
1361         jr  nc,_nolc            ;jump if no carry = no overflow = a<=255
1362         inc b                   ;a>255 so increase bc by 256
1363 _nolc:  ld  c,a                 ;c = (Y*16+X/8) mod 256
1364         ld  hl,dispbuffer       ;save-location
1365         add hl,bc               ;bc = Y*16+X/8: hl=screen address
1366         ld  a,15                ;128/8=16=screen width ** minus one (inc a ^^)
1367         sub d                   ;minus x-start (d=X/8)
1368         ld  b,a
1369 drawlaser:
1370         ld  (hl),%11111111
1371         inc hl                  ;Go to next byte
1372         dnz drawlaser
1373 handle_laser:
1374         pop de                  ;de=(firex): x-pos unmodified
1375
1376 check_laserhits:                ;de = (x,y)
1377         psh ix
1378         ld  b,nrenemies         ;check all enemies
1379         ld  hl,enemies+1        ;enemy#1+occ/hp00
1380 laserhits:                      ;hits with normal enemies
1381         psh hl
1382         ld  a,(hl)              ;occ+hp00
1383         and %11                 ;normal enemy occ = %11
1384         cp  %11
1385         jr  nz,nolashit         ;no hit when enemy_occ <> 11
1386
1387         inc hl                  ;@type
1388         cal find_sprite         ;ix=sprite to enemy (hl)
1389         inc hl                  ;@x
1390         ld  a,(hl)              ;check x
1391         sub d
1392         jr  c,nolashit          ;no hit when enemy is left of you
1393         inc hl                  ;@y
1394         ld  a,(hl)              ;check y
1395         sub e
1396         jr  z,enemy_lashit      ;a-e=0 = laser on top line of enemy = hit
1397         jr  nc,nolashit         ;a-e>0 = enemy above laser = no hit
1398         dec a                   ;minus one
1399         add a,(ix+1)            ;add enemy height (according to sprite @ix)
1400         jp  m,nolashit          ;a-e>0 = hit
1401 enemy_lashit:
1402         ld  a,(curweapdamage)   ;damage
1403         cal enemy_hit           ;hl=enemy+y
1404 nolashit:
1405         pop hl                  ;enemy+1
1406         ld  a,b                 ;psh bc
1407         ld  bc,enemysize
1408         add hl,bc               ;go to next enemy
1409         ld  b,a                 ;pop bc
1410         dnz laserhits           ;check all enemies
1411         xor a
1412         ld  (weapincs),a        ;reset damage
1413         pop ix
1414         ld  c,a                 ;c=0
1415         ret
1416
1417 ;------------------------ handle bullets ------------------------------------
1418
1419 remove_bullet:
1420         pop hl                  ;enemy+type
1421         ld  (hl),0              ;dump this bullet!
1422         jr  next_ybullet+1      ;+1:skip pop hl at next_ybullet
1423
1424 Handle_bullets:
1425         ld  hl,ybullets
1426         ld  b,nrybuls
1427 scan_bullets:
1428         ld  a,(hl)              ;@bulletType
1429         or  a                   ;bulletType=0 >> no bullet
1430         jp  z,next_ybullet+2    ;skip pops (+2); jP for speed
1431
1432         psh bc                  ;bullet counter
1433         psh hl                  ;save enemy+type
1434         ld  (temp1),hl          ;needed for check_bullethits
1435         inc hl                  ;@damage
1436         inc hl                  ;@x
1437
1438 move_bullet:
1439         ld  c,a                 ;c=type
1440         and %11111              ;pixels to move
1441         add a,(hl)              ;a = X + (hl) to the right
1442         sub 16                  ;and 16 to the left (so -16..+15)
1443         jr  c,remove_bullet     ;remove if x<0
1444         cp  128
1445         jr  nc,remove_bullet    ;or x>=128
1446         ld  (hl),a              ;save new pos.
1447         ld  d,a                 ;d = X
1448
1449         inc hl                  ;@y-pos
1450         ld  a,c
1451         cal _shracc             ;%11100000->1110
1452 ;Note: a _shracc procedure inside Nemesis itself would be 27 cycles faster
1453         srl a                   ;%1110->111
1454         dec a
1455         jr  z,bullet_noymove    ;1=straight forward
1456         dec a
1457         jr  z,bullet_up         ;2=up
1458         dec a
1459         jr  z,bullet_halfup     ;3=1/2up
1460         dec a
1461         jr  z,bullet_down       ;4=down
1462 bullet_halfdown:                ;5=1/2down
1463         ld  a,(timer)
1464         rra                     ;carry once every other turn
1465         jr  c,bullet_noymove
1466 bullet_down:
1467         ld  a,(hl)
1468         inc a
1469         cp  55
1470         jr  z,bullet_noymove
1471         ld  (hl),a
1472 bullet_halfup:
1473         ld  a,(timer)
1474         rra                     ;CF every other turn
1475         jr  c,bullet_noymove
1476 bullet_up:
1477         ld  a,(hl)
1478         dec a
1479         jr  z,bullet_noymove
1480         ld  (hl),a
1481 bullet_noymove:
1482         ld  e,(hl)              ;e = Y
1483
1484 display_bullet:
1485         dec hl                  ;@x
1486         dec hl                  ;@damage
1487         ld  a,(hl)              ;bullet damage=size
1488         ld  hl,bullettable      ;pointer to first bullet
1489         srl a
1490         srl a                   ;per 4
1491         ld  b,0
1492         ld  c,a                 ;->16bit (de=a)
1493         add hl,bc               ;point to correct bullet offset
1494         ld  a,(hl)              ;load bullet offset
1495         ld  c,a                 ;convert to 16bit (d=0)
1496         ld  ix,spr_bullet01     ;first sprite
1497         add ix,bc               ;add offset (go to correct sprite)
1498
1499         ld  a,(ix)              ;bullet x-size
1500         ld  (bulletxsize),a     ;used at check_bullethits
1501         ld  a,(ix+1)            ;bullet y-size...
1502         ld  (bulletysize),a     ;...too
1503
1504         cal safeputsprite       ;display bullet; DE used for check_bullethits
1505
1506         cal check_bullethits
1507
1508 next_ybullet:
1509         pop hl                  ;restore enemy+type
1510         pop bc                  ;b=counter
1511         ld  de,4
1512         add hl,de
1513         dnz scan_bullets        ;next bullet (loop)
1514         ret
1515
1516 ;--------------------------- check bullethits -------------------------------
1517
1518 check_bullethits:               ;INPUT: de=X,Y; (temp1)=bullet
1519         ld  b,nrenemies
1520         ld  hl,enemies+1
1521
1522 hit_enemies:                    ;Hits with normal enemies
1523         psh bc                  ;enemy counter
1524         psh hl
1525
1526         ld  a,(hl)
1527         and %11
1528         cp  %11
1529         jr  nz,nohit            ;no hit when enemy_occ <> %11
1530
1531         inc hl                  ;enemy type
1532         cal find_sprite         ;set ix to the sprite of this enemy
1533
1534         inc hl                  ;@x
1535         ld  a,(hl)              ;check x
1536         sub d                   ;minus bullet x-position
1537         ld  b,a                 ;psh a
1538         sub 5                   ;minus bullet x-size
1539 bulletxsize =$-1
1540         jp  p,nohit             ;miss
1541         ld  a,b                 ;pop a
1542         add a,(ix)              ;add enemy width
1543         jp  m,nohit             ;miss
1544
1545         inc hl                  ;@y
1546         ld  a,(hl)              ;check y
1547         sub e                   ;minus bullet y-position
1548         ld  b,a                 ;psh a
1549         sub 3                   ;substract bullet height
1550 bulletysize =$-1
1551         jp  p,nohit             ;nope, missed it
1552         ld  a,b                 ;pop a
1553         add a,(ix+1)            ;add enemy height
1554         dec a                   ;minus one
1555         jp  m,nohit             ;missed after all
1556
1557                                 ;---bullet hits enemy (auch-time!)---
1558         psh hl
1559         ld  hl,0                ;@bulletType
1560 temp1 =$-2
1561         ld  (hl),0              ;remove bullet
1562         inc hl                  ;@damage
1563         ld  a,(hl)              ;set damage
1564         pop hl                  ;enemy+y
1565         cal enemy_hit
1566 nohit:
1567         pop hl
1568         ld  bc,enemysize
1569         add hl,bc
1570         pop bc
1571         dnz hit_enemies         ;check next enemy
1572         ret
1573
1574 enemy_hit:                      ;*in:a=damage;hl=enemy+y
1575         add a,a                 ;a=damage to inflict
1576         add a,a                 ;first 2 bits used for occ.
1577         ld  b,a
1578
1579         dec hl                  ;@x
1580         dec hl                  ;@sprite+1
1581         dec hl                  ;@sprite
1582         dec hl                  ;@hp00 (occ)
1583         ld  a,(hl)              ;load hp00
1584         sub b                   ;decrease HP (if <0xx then c is set)
1585         ld  (hl),a              ;save (no flag-changes)
1586         dec hl                  ;@hp64; no change in c
1587         ld  a,(hl)              ;load; no c-change
1588         sbc a,0                 ;if cf then decrease a
1589         ld  (hl),a              ;save back the new value
1590         ret nc                  ;if a>=0 then return, otherwise explode
1591
1592         inc hl                  ;goto occ again
1593         ld  (hl),%01            ;set to explode
1594
1595         ld  a,(pickuptimer)     ;counts enemies destroyed
1596         dec a                   ;enough destroyed for a pickup?
1597         psh af                  ;save flags and a=0
1598         jr  nz,pickupdone       ;otherwise just explode
1599         ld  a,pickupfreq        ;reset enemies counter
1600 pickupdone:
1601         ld  (pickuptimer),a     ;save new enemiescounter value
1602         inc hl                  ;@sprite (=explosionFrame)
1603         ld  (hl),0              ;explosionFrame 0 or enemy #0=pickup
1604         pop af
1605         cal z,place_enemy       ;place pickup (enemy#=0=a cuz ZF)
1606
1607         ld  hl,1                ;increase score by one
1608         jp  scoreInc            ;+ret
1609
1610 ;--------------------------- level events -----------------------------------
1611
1612 Level_event:
1613         ld  a,0                 ;time to next event
1614 nextevent =$-1
1615         dec a                   ;decrease counter
1616         ld  (nextevent),a       ;store new value
1617         ret nz                  ;hasn't reached zero yet: get outta here!
1618
1619         ld  bc,0                ;enemy frequency (lvl)
1620 eventtime =$-2
1621         cal Random
1622         ld  (nextevent),a       ;set time to next event
1623         ld  hl,eventleft
1624         dec (hl)                ;update enemy-counter
1625
1626         ld  a,(hl)              ;look at counter
1627         or  a                   ;has it reached 0?
1628         jp  z,Next_level        ;yes: level finished
1629         dec a                   ;has it reached 1?
1630         jr  z,standby_event     ;yes: wait until no enemies present/left
1631         dec a                   ;has it reached 2?
1632         jr  z,place_boss        ;yep: place the BigBossTM!
1633         dec a                   ;has it reached 3?
1634         jr  nz,place_ranenemy   ;nope: >3 = place an enemy
1635         inc hl                  ;nextevent located behind eventleft
1636         ld  (hl),193            ;set delay
1637         ret                     ;don't place any more enemies
1638
1639 standby_event:
1640         ld  b,nrenemies
1641         ld  hl,enemies+1-enemysize
1642         ld  de,enemysize
1643         xor a
1644 chk_enemyleft:
1645         add hl,de
1646         cp  (hl)                ;0 = no enemy present
1647         jr  nz,enemyleft
1648         dnz chk_enemyleft
1649         ret
1650 enemyleft:
1651         ld  hl,eventleft
1652         inc (hl)
1653         ret
1654
1655
1656 place_ranenemy:
1657         ld  bc,0                ;0..nrlvlenemies
1658 nrlvlenemies =$-1               ;=nr of enemies minus 1
1659         cal Random              ;random enemy b..b+c = 0..nrenemies-1
1660         ld  b,0
1661         ld  c,a                 ;bc=a
1662         ld  hl,lvlenemies
1663         add hl,bc               ;go to a random enemy
1664         ld  a,(hl)              ;load enemy nr of this mysterious random enemy
1665         jr  place_enemy
1666
1667 place_boss:
1668         ld  hl,(levelp)         ;the leveldata (including the boss)
1669         dec hl                  ;points to leveldata\boss\enemynr
1670         ld  a,(hl)              ;load enemy# of boss
1671
1672 place_enemy:                    ;places enemy #=a
1673         psh af
1674         ld  hl,enemies+1-enemysize
1675         ld  bc,enemysize
1676         xor a                   ;a=0
1677 chk_noenemy:                    ;find an unused (no) enemy
1678         add hl,bc               ;check next enemy
1679         cp  (hl)                ;(hl) = 0 ??
1680         jr  nz,chk_noenemy      ;jump if enemy present (non-0)
1681         ex  de,hl               ;de=hl=usable enemy +1
1682         pop af                  ;enemy# to place
1683         cal findenemyspecs      ;hl = enemy #a specs
1684
1685         dec de                  ;goto hp64 (before occ)
1686         ldi                     ;set hp64
1687         ldi                     ;set hitpoints+occ of enemy class
1688         ld  a,(hl)
1689         .db $DD,$6F ;ld hx,a
1690         ldi                     ;set sprite
1691         ld  a,(hl)
1692         .db $DD,$67 ;ld lx,a
1693         ldi                     ;set sprite + 1
1694         ldi                     ;set x-position
1695
1696         ld  a,(hl)              ;load placeInfo
1697         inc hl
1698         dec a                   ;is it 1?
1699         jr  z,random_enemy      ;yes: create random value <51 in a
1700         dec a                   ;is it 2?
1701         jr  z,lure_enemy        ;yes: create a 100% luring enemy
1702                                 ;otherwise?
1703 halflure_enemy:                 ;yes (of course it is): pick one (50% lure)
1704         ld  a,(timer)           ;look at frame-number
1705         rra                     ;make random if odd frame nr.
1706         jr  nc,random_enemy     ;1st possibility: random enemy
1707 lure_enemy:                     ;2nd possibility: luring enemy
1708         ld  a,(y)               ;place at same y-pos as YOUR ship
1709         jr  ypos_OK
1710 random_enemy:
1711         ld  a,64-8              ;=57=screen height (8 is scorebar)
1712         sub (ix+1)              ;minus sprite height=bottom
1713         ld  c,b                 ;range=0 to...
1714         ld  b,a                 ;...57-y
1715         cal Random              ;random value on screen
1716 ypos_OK:                        ;random value successfully created
1717         ld  (de),a              ;save y-position
1718         inc de                  ;@movecounter
1719         ldi                     ;set move-type
1720         ld  a,1                 ;movecounter = 1
1721         ld  (de),a              ;set
1722         inc de                  ;@firecounter
1723         ldi                     ;set time-to-1st-fire
1724         ldi                     ;set firefreq
1725         ldi                     ; "  firetype
1726         ret                     ;return
1727
1728 ;--------------------------- enemy fires ------------------------------------
1729
1730 Enemy_fires:                    ;de = x,y; c = type; ix = enemy_sprite
1731         ld  hl,ebullets         ;first bullet to check
1732         ld  b,nrebuls
1733         dec d
1734         dec d                   ;d = x of firing enemy minus 2
1735
1736         ld  a,(ix+1)            ;the height of the enemy firing this bullet
1737         srl a                   ;halved
1738         add a,e                 ;added to his y-position
1739         ld  e,a                 ;into e
1740         dec e                   ;minus one (bullet height)
1741
1742 enemy_fires_again:              ;same but hl = first bullet possibly free
1743         xor a
1744 find_ebullet:
1745         cp  (hl)
1746         jr  z,found_ebullet     ;0 = not used
1747         inc hl \ inc hl \ inc hl
1748         dnz find_ebullet        ;look next bullet
1749         ret
1750
1751 found_ebullet:
1752         ld  a,c
1753         sub 6
1754         jr  c,bulletok          ;type #0-5 = done (normal/diag)
1755         or  a
1756         jr  z,bulletaiming      ;type #6 = aiming = type#2..5
1757         dec a
1758         jr  z,bullettriple      ;type #7 = triple
1759         dec a
1760         jr  z,bulletdouble      ;type #8 = double
1761         dec a
1762         jr  z,bulletquad        ;type #9 = quad
1763
1764 bulletdquad:
1765         cal bulletquad          ;fire type #1 to 5
1766         inc hl
1767         ld  a,e
1768         sub 5
1769         ld  e,a                 ;offset 5 up
1770         ld  c,1                 ;type #1 = normal
1771         cal enemy_fires_again
1772         inc hl
1773         ld  a,e
1774         add a,10
1775         ld  e,a                 ;offset 10 down (5 total)
1776         jr  enemy_fires_again
1777
1778 bulletquad:
1779         cal bullettriple        ;fire type #1, 4 and 5
1780         inc hl                  ;next bullet
1781         ld  c,2                 ;type #2 = down
1782         cal enemy_fires_again
1783         inc hl
1784         ld  c,3                 ;type #3 = up
1785         jr  enemy_fires_again
1786
1787 bulletdouble:
1788         dec e                   ;one up
1789         ld  c,1                 ;type #1
1790         cal bulletok            ;fire bullet
1791         inc hl                  ;next bullet position
1792         inc e
1793         inc e                   ;two px down
1794         jr  enemy_fires_again   ;find and fire another bullet
1795
1796 bullettriple:
1797         ld  c,1                 ;type #1 = normal
1798         cal bulletok            ;fire
1799         inc hl                  ;next bullet
1800         ld  c,4                 ;type #4 = down 50%
1801         cal enemy_fires_again
1802         inc hl
1803         ld  c,5                 ;type #5 = up 50%
1804         jr  enemy_fires_again
1805
1806 bulletaiming:
1807         ld  a,(y)
1808         sub e                   ;a = yourY-bulY = pixels bullet is above you
1809         add a,10
1810         jp  p,bulletnotup       ;jump when 10 pixels below you or higher
1811         ld  c,5                 ;go slightly down
1812         add a,10                ;10 to 20 pixels below you
1813         jp  p,bulletok          ;yes: all done.
1814         ld  c,3                 ;otherwise move down even more
1815         jr  bulletok
1816 bulletnotup:
1817         ld  c,1                 ;normal bullet...
1818         sub 20                  ;...when...
1819         jp  m,bulletok          ;...10 pixels below you to 20 pixels above
1820         ld  c,4                 ;bullet going slightly up...
1821         sub 10                  ;...when...
1822         jr  c,bulletok          ;...20 to 30 pixels above you
1823         ld  c,2                 ;else (more than 30 pixels) move up more
1824 bulletok:
1825         ld  (hl),c              ;set bullet direction
1826         inc hl
1827         ld  (hl),d              ;set x-pos
1828         inc hl
1829         ld  (hl),e              ;set y-pos
1830         ret
1831
1832 ;----------------------------- enemy bullets --------------------------------
1833
1834 Enemy_bullets:
1835         ld  hl,ebullets         ;hl=bullet pointer
1836         ld  b,nrebuls           ;number of bullets (or _possible_ bullets)
1837 handle_bullet:
1838         psh bc
1839         psh hl
1840         ld  a,(hl)              ;load bulletType in a
1841         or  a                   ;bullet present?
1842         cal nz,enemy_bullet     ;non-0: handle bullet
1843         pop hl                  ;enemy_bullet could've added one or two to hl
1844         pop bc                  ;bullet counter
1845         inc hl \ inc hl \ inc hl ;next bullet (3 bytes per bullet)
1846         dnz handle_bullet       ;loop for each and every bullet
1847         ret
1848
1849 enemy_bullet:
1850         inc hl                  ;@x
1851         ld  d,(hl)              ;check if it has reached the left side of scrn
1852         bit 7,d                 ;x<0?
1853         jr  nz,remove_ebullet   ;yes, remove bullet
1854         dec d                   ;move one pixel left
1855         dec d                   ;and another one (that makes 2)
1856         ld  (hl),d              ;save new x-coordinate in (HL) and D
1857         inc hl                  ;@y   (BTW: x >= -2)
1858         ld  e,(hl)              ;e=y
1859
1860         dec a
1861         jr  z,ebullet_common    ;type 1: normal bullet
1862         dec a
1863         jr  z,ebullet_down      ;type 2: moving down
1864         dec a
1865         jr  z,ebullet_up        ;type 3: moving up
1866
1867         ld  b,a                 ;save bulletType
1868         ld  a,(timer)           ;load timer
1869         rra                     ;half speed (CF set every other turn)
1870         jr  c,ebullet_common    ;if bit then normal bullet
1871
1872         dec b
1873         jr  z,ebullet_down      ;type 4: moving down 50%
1874                                 ;type 5: moving up 50%
1875 ebullet_up:
1876         dec e                   ;move up
1877         jp  m,ebullet_common    ;y<top; don't save new value (so y=0)
1878         ld  (hl),e
1879         jr  ebullet_common
1880 ebullet_down:
1881         inc e                   ;move down
1882         ld  a,e                 ;a=y too
1883         cp  58-3                ;y>bottom?
1884         jr  z,ebullet_common    ;then keep it there
1885         ld  (hl),e              ;otherwise save new y
1886
1887 ebullet_common:
1888         ld  ix,spr_bullete1     ;display enemy bullet
1889         psh hl
1890         cal putsprite
1891         pop hl                  ;we'll need it again
1892
1893 ebullet_hits:
1894         ld  a,(your_occ)
1895         or  a
1896         ret nz                  ;0 = you're normal
1897
1898         ld  a,(y)               ;check y collision
1899         sub (hl)
1900         add a,6
1901         ret m
1902         cp  9
1903         ret nc
1904
1905         dec hl                  ;check x
1906         ld  a,(x)
1907         sub (hl)
1908         add a,6
1909         ret m
1910         cp  9
1911         ret nc
1912
1913         ld  b,auch_bullet       ;set damage-amount
1914         psh hl
1915         cal damage_you          ;HIT!!
1916         pop hl                  ;save hl to remove the bullet
1917 remove_ebullet:
1918         dec hl                  ;points to bullettype again
1919         ld  (hl),0              ;bullet > unused
1920         ret
1921
1922 ;--------------------------- handle enemies ---------------------------------
1923
1924 Handle_enemies:
1925         ld  hl,enemies+1
1926         ld  b,nrenemies         ;handle all enemies
1927
1928 handle_enemy:
1929         psh bc
1930         psh hl
1931
1932         ld  a,(hl)
1933         and %11
1934         jr  z,next_enemy        ;occ "no enemy" 00
1935         dec a
1936         jr  z,exploding_enemy   ;occ "exploding" 01
1937
1938 normal_enemy:
1939         ld  c,a                 ;c = occ-1 = %10 (normal) or %01 (pickup)
1940         inc hl                  ;@sprite
1941         cal find_sprite
1942
1943         inc hl                  ;@x
1944         ld  d,(hl)              ;x
1945         inc hl                  ;@y
1946         ld  e,(hl)              ;y
1947
1948         inc hl                  ;@movetype
1949         cal moving_enemy
1950         dec hl
1951
1952         ld  a,e                 ;new y value
1953         cp  57
1954         jr  c,enemyonscreenY    ;=on screen
1955         cp  -20                 ;moved off at top
1956         ld  e,0                 ;reset to top
1957         jr  nc,enemyonscreenY
1958         ld  e,57                ;otherwise reset to bottom
1959 enemyonscreenY:
1960         ld  (hl),e              ;store new y
1961         dec hl                  ;@x
1962
1963         ld  a,d                 ;new x value
1964         cp  129                 ;x<=128
1965         jr  c,enemyonscreenX    ;=on screen
1966         cp  -7                  ;x<=-8
1967         jr  c,remove_enemy      ;=off screen
1968 enemyonscreenX:
1969         ld  (hl),d              ;store new x
1970         dec c                   ;is this a pickup? (c=%01 so ZF=1)
1971         jr  nz,check_enemyfire  ;no, a normal enemy; let em fire
1972         jr  firing_done         ;continue
1973
1974 check_enemyfire:
1975         ld  bc,4                ;4x inc hl
1976         add hl,bc               ;@firecount
1977         ld  a,(hl)              ;counter till next blast
1978         dec a                   ;decrease it
1979         ld  (hl),a              ;save new value
1980         jr  nz,firing_done      ;finished if not reached 0 yet
1981
1982         inc hl                  ;@firefreq
1983         ld  a,(hl)              ;=time 'til next blast
1984         inc hl                  ;@firetype
1985         ld  c,(hl)              ;in c
1986         dec hl
1987         dec hl                  ;@firecount again
1988         ld  (hl),a              ;reset counter for next blast
1989         psh de                  ;save registers for firing-use
1990         cal Enemy_fires         ;fires bullet
1991         pop de                  ;restore (destroyed by Enemy_fires)
1992 firing_done:
1993         cal putwidesprite       ;display sprite @ix
1994
1995 next_enemy:
1996         pop hl
1997         ld  bc,enemysize
1998         add hl,bc
1999         pop bc
2000         dnz handle_enemy
2001         ret
2002
2003 exploding_enemy:
2004         inc hl
2005         ld  a,(hl)
2006         cp  16
2007         jr  nz,keep_enemy       ;remove when at last frame
2008 remove_enemy:
2009         pop hl
2010         ld  (hl),$0000          ;bye bye enemy
2011         jr  next_enemy+1        ;continue AFTER pop hl (already done)
2012 keep_enemy:
2013         inc a
2014         ld  (hl),a              ;next frame
2015         dec a                   ;1-16 -> 0-15
2016         ld  ix,spr_explosion    ;base sprite
2017         inc hl                  ;@x
2018         cal explosion_stuff     ;display explosion
2019         jr  next_enemy
2020
2021 ;--------------------------- moving enemies ---------------------------------
2022
2023 moving_enemy:
2024         dec d                   ;move left once
2025         ld  a,(hl)              ;how does this enemy move?
2026         and a
2027         ret z                   ;0 = (1<)
2028         ld  b,a
2029         ld  a,(timer)
2030         dec b
2031         jr  z,movetype_updown   ;1 = (1<) up / down
2032         dec b
2033         jr  z,movetype_vslow    ;2 = (.25<)
2034         dec b
2035         jr  z,movetype_slow     ;3 = (.5 <)
2036         dec b
2037         jr  z,movetype_lslow    ;4 = (.75<)
2038         dec b
2039         jr  z,movetype_fast     ;5 = (1.5<)
2040         dec b
2041         jr  z,movetype_vfast    ;6 = (2  <)
2042         dec b
2043         jr  z,movetype_slowlure ;7 = (1<) move y towards you 50%
2044
2045         inc d                   ;speed 0
2046         dec b
2047         jr  z,movetype_lure     ;8 = (0) move y towards you
2048         dec b
2049         jr  z,movetype_slowlure ;9 = (0) lure 1/2 speed
2050         dec b
2051         jr  z,movetype_fulllure ;10 = x+y towards you 1/2 speed
2052         dec b
2053         jr  z,movetype_right    ;11 = (.5>)
2054         dec b
2055         jr  z,movetype_fright   ;12 = (1>)
2056
2057 movetype_right:
2058         rra
2059         ret c                   ;speed 0 50%
2060 movetype_fright:
2061         inc d                   ;move right one px
2062         ret
2063
2064 movetype_fulllure:
2065         rra
2066         ret c                   ;50% speed
2067         cal movetype_lure
2068         ld  a,(x)
2069         cp  d
2070         jr  c,movetype_vfast    ;moves left (again)
2071 lure_right:
2072         inc d                   ;move right
2073         ret
2074
2075 movetype_slowlure:
2076         rra                     ;half the time
2077         ret c
2078 movetype_lure:
2079         ld  a,110
2080         cp  d
2081         jr  nc,dothelurethingy
2082         dec d                   ;x>109: move left
2083 dothelurethingy:
2084         ld  a,(y)
2085         cp  e
2086         ret z                   ;don't move vertically if equal
2087         jr  c,lure_up           ;below you then move up
2088 lure_down:                      ;above then move down
2089         inc e
2090         ret
2091 lure_up:dec e
2092         ret
2093
2094 movetype_smart:
2095         inc hl                  ;@movecount
2096         ld  a,(hl)
2097         inc a
2098         and %1111
2099         ld  (hl),a
2100
2101         or  a                   ;reset carry flag
2102         dec hl                  ;reset hl to <y>
2103         and %11111100
2104         jr  z,movetype_fast
2105
2106 movetype_lslow:
2107         and %11
2108         ret nz
2109         inc d                   ;don't move 25% of the time
2110         ret
2111 movetype_slow:
2112         rra
2113         ret c
2114         inc d                   ;don't move 50%
2115         ret
2116 movetype_vslow:
2117         and %11
2118         ret z
2119         inc d                   ;don't move 75%
2120         ret
2121
2122 movetype_fast:
2123         rra
2124         ret c                   ;once every other turn
2125 movetype_vfast:
2126         dec d                   ;move left twice
2127         ret
2128
2129 movetype_updown:
2130         inc hl                  ;@movecount
2131         ld  a,(hl)
2132         dec a
2133         and 127                 ;range 0..127
2134         ld  (hl),a              ;store new movecounter
2135         dec hl                  ;reset hl to @movetype
2136         and %00100000           ;ZF changes once every 64 turns
2137         ld  a,e                 ;load current y-position
2138         jr  z,movedown
2139 moveup: dec a                   ;decrease y-pos (=move up)
2140         ret m                   ;don't move off the screen (y<0)
2141         dec e                   ;save new y-pos
2142         ret                     ;finish
2143 movedown:
2144         inc a                   ;increase y-pos
2145         cp  55                  ;compare with bottom
2146         ret nc                  ;return if it has passed that line (>40)
2147         inc e                   ;otherwise save new position
2148         ret                     ;and return
2149
2150 ;--------------------------- check collision --------------------------------
2151
2152 Enemies_hit:
2153         ld  hl,(x)              ;e = X, d = Y
2154         ld  de,$0707            ;add 7 to both d and e
2155         add hl,de
2156         ex  de,hl               ;e = X+7, d = Y+7
2157
2158         ld  hl,enemies+1
2159         ld  b,nrenemies         ;check all 20 enemies
2160 check_collision:
2161         psh bc                  ;counter
2162         psh hl                  ;pointer
2163         ld  a,(hl)
2164         and %10                 ;enemy status (%11=normal; %10=pickup)
2165         jr  z,check_next        ;2 or 3 = ok, otherwise: next enemy
2166         inc hl                  ;enemy#
2167
2168 collide_enemy:                  ;&&& include in Handle_enemy proc
2169         cal find_sprite
2170
2171         inc hl                  ;@x
2172         ld  a,(hl)              ;check x match
2173         sub e                   ;enemy position minus yours minus 7
2174         jp  p,check_next
2175         add a,6
2176         add a,(ix)              ;enemy width
2177         jp  m,check_next
2178
2179         inc hl                  ;@y
2180         ld  a,(hl)              ;check y match
2181         sub d                   ;same as with x-check
2182         jr  nc,check_next       ;(=jp p)
2183         add a,6
2184         add a,(ix+1)            ;enemy height
2185         jp  m,check_next
2186         dec hl                  ;@x
2187         dec hl                  ;@sprite+1
2188         dec hl                  ;@sprite
2189         dec hl                  ;@occ
2190
2191 take_pickup:
2192         psh hl                  ;we need hl
2193         ld  hl,2                ;increase score by 2
2194         cal scoreInc
2195         pop hl                  ;we're done
2196
2197         ld  a,(hl)              ;load enemy occ
2198         rra                     ;if occ = %10 (can't be %00) then pickup
2199         jr  c,collide           ;otherwise normal enemy so you collide
2200
2201         psh hl
2202         ld  hl,your_pickup      ;your pickups
2203         ld  a,(hl)              ;current
2204         inc a                   ;go to next
2205         cp  6                   ;pickups >=6
2206         jr  c,not_maxpickup
2207         ld  a,1                 ;yes: reset to pickup 1
2208 not_maxpickup:
2209         ld  (hl),a              ;save new
2210         cal disp_icons          ;display altered pickupicons
2211         pop hl
2212
2213         xor a                   ;set to 0 = gone
2214         ld  (hl),a              ;remove
2215         jr  check_next          ;all done, next..
2216
2217 collide:
2218         ld  a,(hl)
2219         sub auch_ecollide
2220         ld  (hl),a
2221         jr  nc,enemydamaged     ;enemy still ok (HP>=0)
2222         ld  (hl),%01            ;set to explode
2223         inc hl
2224         ld  (hl),0              ;explosionFrame 0
2225 enemydamaged:                   ;damage to enemy delivered
2226         ld  b,auch_collide      ;your damage
2227         cal damage_you
2228
2229 check_next:
2230         pop hl
2231         ld  bc,enemysize
2232         add hl,bc
2233         pop bc
2234         dnz check_collision
2235         ret
2236
2237 ;--------------------------- story ------------------------------------------
2238
2239 storyPage:
2240         psh hl                  ;hl will be destroyed by _clrLCD
2241         cal _clrLCD             ;clear screen
2242         pop hl
2243         ld  a,(hl)
2244         ld  (curline),a         ;begin line for special effect
2245 storyLine:
2246         ld  d,(hl)              ;vertical position of text
2247         inc hl
2248         ld  e,(hl)              ;horizontal text-position
2249         ld  (_penCol),de        ;set position
2250         inc hl
2251         cal _vputs              ;display text
2252
2253         ld  a,(hl)              ;load next byte
2254         inc hl
2255         or  a                   ;0 means more text
2256         jr  z,storyLine         ;loop if there is
2257
2258         psh af
2259         psh hl
2260         ld  hl,VIDEO_MEM        ;copy text
2261         ld  de,dispbuffer       ;to GRAPH_MEM
2262         ld  bc,1024             ;entire screen
2263         ldir
2264         cal _clrLCD             ;clear VIDEO_MEM
2265         pop hl
2266         pop bc                  ;last byte (<>0) is lines to SFX
2267         psh hl
2268         cal DoSFX               ;do special effects
2269         cal getsomekeys         ;wait for a key
2270         pop hl
2271         ret
2272
2273 dostory:
2274         cal storyPage                   ;do some story
2275         ld  a,(hl)                      ;load next byte in a
2276         inc a                           ;set z-flag if a = $ff
2277         jr  nz,dostory                  ;otherwise loop
2278         inc hl
2279         inc hl                          ;set hl to beginning of the level
2280         ld  (levelp),hl                 ;set the level-pointer
2281         ret                             ;and return
2282
2283 ;--------------------------- SFX --------------------------------------------
2284
2285 DoSFX:                          ;in:(curline)=beginLine;b=nrOfLines
2286 SFXloop:
2287         psh bc
2288
2289         ld  a,0                 ;get line number
2290 curline =$-1
2291         inc a                   ;go to the next line
2292         ld  (curline),a         ;update
2293         ld  l,a
2294         ld  h,0                 ;hl=a
2295         add hl,hl
2296         add hl,hl
2297         add hl,hl
2298         add hl,hl               ;*16 (a pixels down=a*16)
2299         sub 64                  ;a=a-64
2300         neg                     ;a=64-a (lines from bottom)
2301
2302         ld  b,h                 ;save hl for later
2303         ld  c,l
2304         ld  de,VIDEO_MEM        ;where to put sfx
2305         add hl,de               ;go to ymin
2306         ex  de,hl               ;put into de again
2307         ld  hl,dispbuffer       ;source of original
2308         add hl,bc               ;hl->source
2309
2310 SFXdisp:                        ;display this frame on screen
2311         ld  bc,16               ;one line (=16 bytes, you'd know by now)
2312         ldir                    ;display (copy actually)
2313         ld  bc,-16              ;go up one line (not on screen)
2314         add hl,bc               ;so the same line will be displayed
2315         dec a                   ;counter
2316         jr  nz,SFXdisp          ;repeat until whole screen is displayed
2317
2318         ld  b,8
2319 SFXdelay:
2320         halt                    ;delay
2321         dnz SFXdelay            ;8x
2322
2323         pop bc                  ;counter
2324         dnz SFXloop
2325         ret
2326
2327 ;--------------------------- proc -------------------------------------------
2328
2329 Random:                         ;a=c<random<b+c; destr:none
2330         psh hl
2331         ld  hl,rancount         ;amount to increase with (0-255)
2332 randomloop:
2333         inc (hl)                ;change for next time
2334         ld  a,r                 ;value $0-7F (can be _anything_ so watch out!)
2335         add a,0                 ;add to last random value
2336 ranseed =$-1                    ;SMC :P
2337         add a,(hl)              ;add the changing increase value
2338                         ;(this is because R can be anything;
2339                         ; ie always be even so freeze when a must be 1<=a<=1)
2340         ld  (ranseed),a         ;save for next time
2341         cp  b                   ;a>=b
2342         jr  nc,randomloop       ;then add again
2343         add a,c                 ;a<b; a=a+c
2344         pop hl
2345         ret
2346 rancount: .db 0
2347
2348 RandomY:                        ;HL = random Y 0..50 right side ((1..51)*16-1)
2349         psh bc
2350         ld  bc,50*256+1         ;range=1..51
2351         cal Random              ;a = 1..51
2352         ld  h,0
2353         ld  l,a                 ;hl = 1..51
2354         add hl,hl
2355         add hl,hl
2356         add hl,hl
2357         add hl,hl               ;hl = 1..51 * 16 (left side at random y)
2358         dec hl                  ;hl = 0..50 * 16 (" at right side of screen)
2359         ld  de,dispbuffer
2360         add hl,de               ;position on screen
2361         pop bc
2362         ret
2363
2364 scoreInc:                       ;increase score by HL
2365         psh bc                  ;don't destroy bc (or any registers Xcept hl)
2366         ld  bc,(your_score)     ;your current score in bc
2367         psh af                  ;don't destroy a either
2368         ld  a,(hardcore)        ;load hardcore mode settings in a
2369         or  a                   ;is it zero?
2370         jr  z,scoreincok        ;then skip the next instruction (score = ok)
2371         add hl,hl               ;otherwise (hardcore) double the inc.score
2372 scoreincok:
2373         pop af                  ;restore a register
2374         add hl,bc               ;add bc to hl (or vice versa)
2375         ld  (your_score),hl     ;save new increased score
2376         pop bc                  ;all registers to what they were
2377         ret
2378
2379 find_sprite:                    ;in:hl=enemy+type | out:ix=sprite to enemy
2380         ld  a,(hl)              ;sprite byte #1
2381         .db $DD,$6F ;ld hx,a
2382         inc hl                  ;@sprite+1
2383         ld  a,(hl)              ;sprite byte #2
2384         .db $DD,$67 ;ld lx,a    ;ld ix,(hl)
2385         ret
2386
2387 BLACKLCD:
2388         ld  hl,VIDEO_MEM        ;screen location (top left)
2389         ld  de,VIDEO_MEM+1
2390         ld  (hl),%11111111
2391         ld  bc,1024-1           ;do it 1024 times = entire screen
2392         ldir
2393         set 3,(iy+5)            ;set white on black
2394         ret
2395
2396 getsomekeys:
2397         halt                    ;wait a li'l while and save batteries :P
2398         halt
2399         cal GET_KEY             ;input keys
2400         or  a
2401         jr  z,getsomekeys       ;wait if none
2402         cp  K_SECOND            ;2nd pressed?
2403         ret z                   ;then return with zf set
2404         cp  K_ENTER             ;enter pressed
2405         ret                     ;then return with zf set, otherwise zf reset
2406
2407 releasekeys:
2408         halt
2409         ld  a,%10000000         ;all key-masks
2410         out (1),a
2411         in  a,(1)
2412         inc a                   ;cp %11111111 (no keys pressed)
2413         jr  nz,releasekeys      ;keep waitin
2414         jp  GET_KEY             ;clear buffer
2415
2416 findenemyspecs:                 ;enemy #a specs in (hl); in:b=0; out:ac=?
2417         ld  hl,enemyspecs       ;enemy "0" specs
2418         add a,a                 ;a=type*2
2419         ld  c,a                 ;b=0; bc=c=a=type*2
2420         add hl,bc               ;hl = enm#0 + type*2
2421         add a,a                 ;a=type*4 (max.type<64)
2422         ld  c,a                 ;bc=type*4
2423         add hl,bc               ;hl = enm#0 + type*6
2424         add hl,bc               ;hl = enm#0 + type*10
2425         ret                     ;hl = enemy specs
2426
2427 ;--------------------------- game over / new game / death -------------------
2428
2429 chartable:
2430         .db 0,".<>!",0,0,0,0  ;down,L,R,up
2431         .db 0,"xtoje0",0      ;enter..clear
2432         .db " wsnid9",0       ;(-)..custom
2433         .db "zvrmhc8",0       ;dot..del
2434         .db "yuqlgb7#"        ;0..xvar
2435         .db $D9,"-pkfa6'"     ;on..alpha
2436         .db "54321*",0,$D0    ;F5..more
2437
2438 save_lvl:
2439         ld  hl,storesave_end-storesave_start
2440         psh hl                  ;size
2441         ld  hl,storesave_start
2442         psh hl                  ;dest
2443         ld  hl,4+storesave_start-_asm_exec_ram
2444         psh hl                  ;src
2445         jr  storesmtn
2446
2447 save_hi:
2448         ld  hl,storehi_end-storehi_start
2449         psh hl                  ;size
2450         ld  hl,storehi_start
2451         psh hl                  ;destination
2452         ld  hl,4+storehi_start-_asm_exec_ram
2453         psh hl                  ;source
2454
2455 storesmtn:              ;stores data [stack=src; stack+1=dest; stack+2=size]
2456         ld  hl,_asapvar         ;find own variable
2457         rst 20h                 ;cal _ABS_MOV10TOOP1
2458         rst 10h                 ;cal _FINDSYM
2459
2460         xor a                   ;bde=pointer to begin of real program
2461         pop hl                  ;data offset
2462         add hl,de               ;hl=pointer to data in real prog
2463         adc a,b                 ;if hl overflow also increase a
2464         cal _SET_ABS_DEST_ADDR  ;destination = real program = ahl
2465         xor a                   ;RAM page #0
2466         pop hl                  ;data position in normal program ($D748+)
2467         cal _SET_ABS_SRC_ADDR   ;set as source (ahl)
2468         pop hl                  ;size
2469         cal _SET_MM_NUM_BYTES   ;set
2470         cal _mm_ldir            ;copy data to real program
2471         jp  _RAM_PAGE_1         ;and finally: reset ram page
2472
2473 game_over:                      ;stack=+0
2474         cal BLACKLCD            ;clear screen
2475         ld  hl,$0603
2476         ld  (_curRow),hl        ;center
2477         ld  hl,txt_gameover
2478         cal _puts               ;display "GAME OVER"
2479         cal releasekeys         ;wait for all keys to be released
2480
2481         ld  hl,$0007
2482         ld  (_curRow),hl
2483
2484         ld  de,(your_score)
2485         ld  hl,(hiscore)
2486         cal CP_HL_DE
2487         jr  nc,no_hiscore
2488         ld  (hiscore),de
2489
2490 ask_hiname:
2491         ld  ix,hiname
2492         ld  a,9
2493         ld  (hiscorepos),a
2494 enter_name_loop:
2495         ld  a,'_'
2496         cal _putc
2497         ld  hl,_curCol
2498         dec (hl)
2499 nokeypressed:
2500         cal getsomekeys
2501         jr  z,nomore
2502         or  a
2503         jr  z,nokeypressed
2504
2505         cp  K_DEL
2506         jr  z,backup
2507         cp  K_EXIT
2508         jr  z,nomore
2509
2510         ld  hl,hiscorepos
2511         ld  b,(hl)
2512         dec b
2513         jr  z,nokeypressed
2514         ld  (hl),b
2515
2516         ld  hl,chartable
2517         ld  e,a
2518         ld  d,0
2519         add hl,de
2520         ld  a,(hl)
2521         or  a
2522         jr  z,nokeypressed
2523
2524         ld  (ix),a
2525         cal _putc
2526         inc ix
2527         cal releasekeys
2528         jr  enter_name_loop
2529
2530 backup:
2531         ld  hl,hiscorepos
2532         ld  a,(hl)
2533         cp  9
2534         jr  nc,nokeypressed
2535         inc (hl)
2536
2537         dec ix
2538         ld  (ix),' '
2539         ld  a,32
2540         cal _putc
2541         ld  hl,_curCol
2542         dec (hl)
2543         dec (hl)
2544         jr  enter_name_loop
2545
2546 nomore:
2547         ld  a,' '
2548         cal _putc
2549         ld  (ix),0
2550         cal save_hi
2551         jr  hiscoredone
2552
2553 no_hiscore:
2554         ld  hl,hiname
2555         cal _puts
2556
2557 hiscoredone:
2558         xor a                   ;clear a (Ahl will be displayed)
2559         ld  hl,$1006            ;bottom-1 right
2560         ld  (_curRow),hl        ;set
2561         ld  hl,(your_score)     ;your score
2562         cal _dispahl            ;display it (a=0)
2563
2564         ld  hl,$314b            ;bottom-1 right before score ^^
2565         ld  (_penCol),hl        ;set
2566         ld  hl,txt_score        ;"Score"
2567         cal _vputs              ;display (small)
2568
2569         ld  hl,$1007            ;bottom right
2570         ld  (_curRow),hl        ;set
2571         ld  hl,(hiscore)        ;hi-score
2572         cal _dispahl            ;display
2573         ld  hl,$3946            ;bottom right before hiscore ^^
2574         ld  (_penCol),hl        ;set
2575         ld  hl,txt_hiscore      ;"Hiscore"
2576         cal _vputs              ;display (small)
2577         res 3,(iy+5)
2578
2579         ld  b,16
2580         ld  de,16
2581         ld  hl,VIDEO_MEM+(49*16)-1
2582 restore_line:
2583         set 1,(hl)
2584         add hl,de
2585         dnz restore_line
2586
2587         cal getsomekeys         ;wait for keypress
2588         jp  quit                ;restore some things and return to TI-OS/shell
2589
2590 invship:                        ;procedure used in New_game
2591         psh af
2592         inc b
2593         ld  de,$C0
2594         ld  hl,VIDEO_MEM+$30-$C0;begin pos
2595 invshipinit:
2596         add hl,de
2597         dnz invshipinit
2598         ld  b,$B0               ;12 lines down
2599 invshiploop:
2600         ld  a,(hl)
2601         cpl                     ;invert byte
2602         ld  (hl),a
2603         inc hl
2604         dnz invshiploop         ;loop
2605         pop af
2606         ret
2607
2608 New_game:                       ;stack must be +1 (so change the jp in cal :)
2609         cal _clrLCD
2610         ld  hl,VIDEO_MEM
2611         ld  (PutWhere),hl       ;will be reset after displaying iconbar
2612         ld  ix,spr_ship01       ;first ship: sprite
2613         ld  de,$0105            ;position
2614         ld  b,4                 ;number of ships to display
2615 dispshipsloop:
2616         psh bc                  ;counter
2617         psh de                  ;position
2618         ld  h,e
2619         ld  l,40                ;x=40
2620         ld  (_penCol),hl        ;small cursor position
2621         psh ix                  ;ix destroyed by _vputmap
2622         ld  hl,txt_difhardcore  ;hardcore ships text
2623         ld  a,b                 ;ship displaying (4 to 1)
2624         dec a                   ;minus 1 (3..0)
2625         psh af
2626         and %10                 ;gives 1,1,0,0 (for ships 0,0,1,1)
2627         jr  z,dispdifficulty    ;0 indicates hardcore difficulty ship
2628         ld  hl,txt_difnormal    ;normal difficulty ships text
2629 dispdifficulty:
2630         cal _vputs              ;display difficulty
2631         ld  a,95
2632         ld  (_penCol),a         ;set x=95
2633         pop af                  ;ship nr (backwards 3..0)
2634         ld  hl,txt_updouble     ;updouble for ships 1
2635         and %1                  ;gives 0,1,0,1 (for ships 0,1,0,1)
2636         jr  nz,dispsbeam
2637         ld  hl,txt_tailbeam     ;tailbeam for ships 0
2638 dispsbeam:
2639         cal _vputs              ;display special beam type
2640         pop ix
2641         pop de
2642         psh de                  ;peek de
2643         cal putwidesprite       ;display ship
2644         pop de
2645
2646         ld  bc,spr_ship01i-spr_ship01+2
2647         add ix,bc               ;go to next ship
2648         ld  a,12                ;below the previous one
2649         add a,e
2650         ld  e,a
2651         pop bc
2652         dnz dispshipsloop       ;loop
2653
2654         ld  b,0                 ;menu pos.
2655 selectship:
2656         psh bc
2657         cal invship
2658 selectshiploop:
2659         cal getsomekeys
2660         pop bc
2661         jr  z,startthenewgame   ;enter/2nd
2662         psh bc
2663         cal invship
2664         pop bc
2665         cp  K_DOWN
2666         jr  nz,selnotdown
2667         inc b
2668 selnotdown:
2669         cp  K_UP
2670         jr  nz,selnotup
2671         dec b
2672 selnotup:
2673         ld  a,b
2674         and %11
2675         ld  b,a
2676         jr  selectship
2677
2678 startthenewgame:
2679         ld  hl,spr_ship01-(spr_ship02-spr_ship01)
2680         ld  de,spr_ship02-spr_ship01
2681         psh bc                  ;save b (ship#)
2682         inc b                   ;your ship #0-3++
2683         ld  a,b                 ;ship #1-4
2684 searchyourship:
2685         add hl,de               ;next ship
2686         dnz searchyourship
2687         ld  (your_ship),hl
2688         and 1                   ;gives: 1,0,1,0 for the ships
2689         inc a                   ;ships now give 1,2,1,2
2690         ld  (your_extramode),a  ;sets tail beam or up double (1 or 2)
2691         pop af                  ;ship# 0..3
2692         and %10                 ;ships give 0,0,1,1
2693         ld  (hardcore),a        ;hardcore mode set for ships 3 and 4
2694         xor a                   ;ld a,0
2695         ld  (your_score),a      ;reset score
2696         ld  (your_score+1),a    ;reset score (0)
2697         ld  (your_extra),a      ;no extra beam
2698         ld  (your_weapon),a     ;no laser
2699         ld  (your_pickup),a     ;reset pickups
2700         ld  (your_multiples),a  ;no multiples
2701         inc a                   ;ld a,1
2702         ld  (level),a           ;reset level nr (#1)
2703         ld  hl,levelstart       ;set level pointer to level#1
2704         ld  (levelp),hl         ;reset level pointer
2705         ld  a,4
2706         ld  (your_lives),a      ;3 lives (4 will be decreased @ You_die)
2707         ld  (pickuptimer),a     ;next pickup after 4 enemies destroyed
2708
2709 You_die:                        ;stack must be +1
2710         pop hl                  ;restore stack
2711         ld  a,24
2712         ld  (your_armor),a      ;24 HPs/shields
2713         ld  a,(your_lives)      ;load lives left
2714         dec a                   ;decrease lives
2715         ld  (your_lives),a      ;if lives=0ffh GO
2716         inc a                   ;if -1 then zf set now
2717         jp  z,game_over         ;and game's over
2718         jr  samelevel
2719
2720 gamedone:
2721         cal dostory             ;display end (hl=(levelp))
2722         ld  hl,250
2723         cal scoreInc            ;game complete bonus: 250
2724         jp  game_over           ;game over (+hiscore)
2725
2726 ;--------------------------- next level -------------------------------------
2727
2728 Next_level:                     ;stack must be +1
2729         pop hl
2730
2731         cal inc_armor           ;increase armor
2732
2733         ld  hl,(levelp)         ;level pointer
2734         ld  b,0                 ;advance one level
2735         ld  c,(hl)
2736         add hl,bc               ;passed the enemies
2737         ld  c,10
2738         add hl,bc               ;update to point to next level
2739         ld  (levelp),hl         ;save
2740
2741         ld  a,(level)           ;level number
2742         inc a                   ;next level #
2743         cp  endlevel+1          ;last level done?
2744         jr  nc,gamedone         ;yes: display end story and quit
2745         ld  (level),a
2746
2747         add a,a
2748         add a,a
2749         ld  h,0                 ;increase score....
2750         ld  l,a                 ;by level number * 4
2751         ld  bc,20
2752         add hl,bc               ;plus 20
2753         cal scoreInc            ;update score
2754
2755 samelevel:
2756         ld  hl,invertmode
2757         ld  de,_invert          ;sets B<>W mode
2758         ldi                     ;ld (_invert),(invertmode)
2759         ld  de,your_shipspr     ;sets your ship's sprite
2760         ldi                     ;ld (your_shipspr),(your_ship)
2761
2762         ld  a,80
2763         ld  (nextevent),a       ;time to first enemy appearance
2764
2765         ld  hl,(levelp)         ;level pointer
2766         dec hl                  ;byte before level (boss byte)
2767         xor a                   ;if it's zero it means here's a story
2768         cp  (hl)
2769         inc hl                  ;begin of level
2770         cal z,dostory           ;do the story and set (levelp) to real level
2771
2772         ld  a,(hl)              ;number of (different) enemies in this level
2773         inc hl
2774         ld  c,a
2775         ld  (nrlvlenemies),a    ;set nr of enemies-1
2776         ld  b,0                 ;bc=c so we can use ldir
2777         ld  de,lvlenemies       ;table of enemies
2778         ldir                    ;load enemies to table
2779         ld  a,(hl)              ;load new appearance-time
2780         ld  (eventtime),a
2781         inc hl
2782         ld  a,(hl)
2783         ld  (eventtime+1),a     ;set
2784         inc hl
2785         ld  a,(hl)              ;load nr of enemies in this level
2786         ld  (eventleft),a       ;set nr of events left
2787         inc hl
2788         ld  de,level_info
2789         ld  c,5                 ;5xLDI:  loads (level_info) (spacespace)
2790         ldir                    ;              (groundinfo) (stars1) (stars2)
2791         ld  a,1
2792         ld  b,32                ;fill (groundpos) and (ceilingpos)
2793 fillground:
2794         ld  (de),a
2795         inc de
2796         dnz fillground
2797
2798         ld  ix,starx1
2799         ld  b,nrstars1
2800         cal placestars
2801         ld  ix,starx2
2802         ld  b,nrstars2
2803         cal placestars
2804
2805         xor a
2806         ld  (timer),a           ;reset time
2807         ld  hl,your_occ         ;hl = your_occ
2808         ld  (hl),a              ;reset your ship (not exploding)
2809         inc hl                  ;hl = your_shield
2810         ld  (hl),25             ;set 25*4=100 frames shielded
2811         ld  de,$1820
2812         ld  (x),de              ;begin position (x,y)
2813         cal Place_multiples     ;place all multiple-positions at that (0,24)
2814
2815         cal loadweapon          ;load (your_weapon)
2816
2817         ld  hl,enemies          ;remove all enemies and bullets
2818         ld  (hl),0              ;clear first byte
2819         ld  de,enemies+1        ;copy this to the next byte
2820         ld  bc,(nrenemies*enemysize)+(nrybuls*4)+(nrebuls*3)-1
2821         ldir                    ;clear enemies + bullets (y/e)
2822
2823 ;--------------------------- setup game -------------------------------------
2824
2825 game_setup:
2826         cal BLACKLCD            ;white on black
2827         ld  hl,txt_level
2828         ld  de,$0703
2829         ld  (_curRow),de        ;center
2830         cal _puts               ;display "LEVEL "
2831
2832         ld  a,(level)           ;current level
2833         ld  l,a
2834         ld  h,0                 ;in hl
2835         cal UNPACK_HL           ;create first digit
2836         add a,'0'               ;0-9
2837         ld  b,a                 ;into b
2838         cal UNPACK_HL           ;second digit
2839         add a,'0'               ;0-9
2840         cal _putc               ;display second digit
2841         ld  a,b
2842         cal _putmap             ;display first digit
2843
2844         ld  hl,txt_lives        ;bar text: "Lx0"...
2845         ld  de,$0904
2846         ld  (_curRow),de        ;display lives left below level nr
2847         cal _puts
2848         ld  a,(your_lives)      ;lives left
2849         add a,'0'               ;make value 0='0'
2850         cal _putc
2851
2852         cal releasekeys         ;wait for user to release all keys
2853         ld  hl,txt_savekey      ;"Press [F1] to save"
2854         ld  de,$3A46            ;bottom-right
2855         ld  (_penCol),de
2856         cal _vputs
2857
2858         res 3,(iy+5)            ;set white on black
2859         cal getsomekeys         ;wait for keypress
2860         cp  K_F1
2861         cal z,save_lvl
2862
2863         cal _clrLCD             ;clear screen
2864         cal disp_icons          ;display bottom icons +ret
2865         jp  game_main_loop
2866
2867 placestars:
2868         cal RandomY             ;a = random y-pos 1..bottom
2869         ld  a,b                 ;a =  b = star nr. = 1..7
2870         add a,a                 ;a = 2b = 2..14
2871         ld  d,0
2872         ld  e,a                 ;de = a = 2-14
2873         or  a
2874         sbc hl,de               ;substract from random y => random pos anywhere
2875
2876         ld  (ix),l              ;save x-pos (l)
2877         ld  (ix+1),h            ;save y-pos (h)
2878         inc ix \ inc ix         ;next star
2879         dnz placestars          ;repeat for all stars
2880         ret
2881
2882 loadweapon:
2883         ld  a,(your_weapon)
2884         add a,a                 ;weap*2
2885         add a,a                 ;    *4
2886         add a,a                 ;    *8
2887         ld  c,a
2888         ld  b,0
2889         ld  hl,weapondata
2890         add hl,bc
2891         ld  a,(hl)
2892         ld  (weapdamage),a      ;damage of bullets
2893         inc hl
2894         ld  a,(hl)
2895         ld  (weapdaminc),a      ;damage increase
2896         inc hl
2897         ld  a,(hl)
2898         and %00011111           ;laser duration
2899         ld  (laserdur),a
2900         ret
2901
2902 ;----------------------------------------------------------------------------
2903 ;--------------------------- putsprite --------------------------------------
2904 ;----------------------------------------------------------------------------
2905 ;in:  de=(x,y); ix=sprite
2906 ;out: ix=behind sprite; hl:a=right below sprite; b=0; d=width; ce=?
2907
2908 putsprite:
2909         ld  c,(ix)              ;save width
2910 _putsprite:                     ;putsprite with custom width
2911         ld  a,d                 ;a=X
2912         bit 7,d                 ;check sign bit of X
2913         jr  z,CSpositive        ;X>=0
2914
2915         neg                     ;a=|X|
2916         cp  (ix)                ;off screen?
2917         ret nc                  ;X<=-width: don't draw at all
2918         ld  b,a                 ;b=|X|mod 8=1..7=bits to draw
2919         ld  a,%11111111         ;all bits set (draw everything)
2920 CSclipleft:
2921         srl a                   ;remove first bit in a for each b
2922         dnz CSclipleft          ;b=1: a=%01111111
2923                                 ;b=2: a=%00111111
2924                                 ;b=3: a=%00011111
2925                                 ;b=4: a=%00001111
2926                                 ;b=5: a=%00000111
2927                                 ;b=6: a=%00000011
2928                                 ;b=7: a=%00000001
2929         res 7,d                 ;X+128 (right side of screen)
2930         dec e                   ;Y--
2931         jr  CSdisplay           ;done clipping
2932
2933 CSpositive:
2934         sub 129-8               ;minus (screen width - byte width)
2935         ld  b,a
2936         ld  a,%11111111         ;clipmask
2937         jr  c,CSdisplay         ;x+width<128 then entire sprite is on screen
2938         inc b                   ;b = number of pixels off screen
2939 CSclipright:
2940         add a,a                 ;remove last bit in a for each b
2941         dnz CSclipright         ;b=1: a=%11111110
2942                                 ;b=2: a=%11111100
2943                                 ;b=3: a=%11111000
2944                                 ;b=4: a=%11110000
2945                                 ;b=5: a=%11100000
2946                                 ;b=6: a=%11000000
2947                                 ;b=7: a=%10000000
2948                                 ;b>7: a=%00000000 = off screen
2949
2950 CSdisplay:                      ;display the sprite ix at (d,e) masked
2951         ld  (CSclipmask),a      ;set mask
2952         cal findpixel           ;convert de to screen location hl:a
2953         ld  (CSbitmask),a
2954
2955         ld  d,c                 ;width
2956         ld  b,(ix+1)            ;height
2957 CSyloop:
2958         psh bc                  ;save rows to go
2959         psh hl                  ;screen
2960         ld  b,d                 ;width
2961         ld  a,(ix+2)            ;load image line
2962         and 255                 ;mask
2963 CSclipmask =$-1
2964         ld  c,a                 ;c=image
2965         inc ix                  ;next
2966 CSbitmask =$+1
2967         ld  a,1                 ;saved bitmask
2968 CSxloop:
2969         sla c                   ;test leftmost pixel
2970         jr  nc,CSnodraw         ;don't draw if it's 0
2971         ld  e,a                 ;psh af: save bitmask
2972         or  (hl)
2973         ld  (hl),a              ;OR pixel with screen
2974         ld  a,e                 ;pop af
2975 CSnodraw:
2976         rrca                    ;next bit
2977         jr  nc,CSbitdrawn       ;carry set if bit "jumped"
2978         inc hl                  ;next byte
2979 CSbitdrawn:
2980         dnz CSxloop
2981         pop hl                  ;screen at x-offset=0
2982         ld  bc,16
2983         add hl,bc               ;next line
2984         pop bc                  ;rows counter
2985         dnz CSyloop
2986 CSdone: ret
2987
2988 ;--------------------------- putbigsprite -----------------------------------
2989
2990 putwidesprite:
2991 ;destr: abcdehl+ix (ix=behind sprite; hl:a=right below sprite; b=0; d=width)
2992         ld  a,(ix)              ;width
2993         cp  9
2994         jr  c,putsprite         ;width<=8: just draw the sprite
2995
2996         ld  a,(ix)
2997         sub 8                   ;width>8
2998         psh af
2999         ld  c,8
3000         psh de
3001         cal _putsprite          ;otherwise draw one column (8 pixels wide)
3002         pop de
3003         inc ix                  ;no x-size to load
3004         ld  a,8                 ;next
3005         add a,d                 ;8 pixels right
3006         ld  d,a
3007         pop bc                  ;then draw the remaining pixels (c=width-8)
3008         ld  c,b
3009         jr  _putsprite
3010
3011 safeputsprite:                  ;cal putsprite with de intact
3012         psh de
3013         cal putsprite
3014         pop de
3015         ret
3016
3017 ;------------------------------- findpixel ----------------------------------
3018 ;based upon CLEM's fp | 131 cycles | 28 bytes | in:(d,e); out:hla; destr:de
3019
3020 findpixel:
3021         ld  a,e                 ;a=e=Y
3022         add a,a
3023         add a,a                 ;add a,a is 7 cycles faster than add hl,hl
3024         ld  h,0                 ;switch to hl now (Y<64)
3025         ld  l,a                 ;hl=4*Y
3026         ld  a,d                 ;a=d=X
3027         rra                     ;RRA: carry flag must be reset!
3028         add hl,hl               ;that's what the adds are for :P
3029         rra
3030         add hl,hl               ;hl=16*Y
3031         rra                     ;a=X/8
3032         or  l
3033         ld  l,a                 ;hl=hl+a
3034         ld  a,d
3035         and 7                   ;a=X\8
3036         cpl
3037         rlca
3038         rlca
3039         rlca
3040         ld (FPbit),a
3041         xor a
3042 FPbit =$+1
3043         set 0,a
3044         ld  de,dispbuffer       ;screen base position (where x+y=0)
3045 PutWhere =$-2
3046         add hl,de
3047         ret
3048
3049 ;----------------------------------------------------------------------------
3050 ;------------------------------- sprites ------------------------------------
3051 ;----------------------------------------------------------------------------
3052
3053 spr_ship01:             ;(normal; up double)
3054         .db 7,7         ;ship alpha class (vic viper)
3055         .db %11000000   ;██
3056         .db %11110000   ;████
3057         .db %01111110   ; ██████
3058         .db %11101000   ;███ █
3059         .db %01111110   ; ██████
3060         .db %11110000   ;████
3061         .db %11000000   ;██
3062 spr_ship01i:
3063         .db 8,7
3064         .db %11001010   ;██  █ █
3065         .db %11110101   ;████ █ █
3066         .db %01111110   ; ██████
3067         .db %11101001   ;███ █  █
3068         .db %01111110   ; ██████
3069         .db %11110101   ;████ █ █
3070         .db %11001010   ;██  █ █
3071
3072 spr_ship02:             ;(normal; tail beam)
3073         .db 7,7         ;ship gamma class
3074         .db %11111000   ;█████
3075         .db %01100000   ; ██
3076         .db %11111100   ;██████
3077         .db %11100110   ;███  ██
3078         .db %11111100   ;██████
3079         .db %01100000   ; ██
3080         .db %11111000   ;█████
3081 spr_ship02i:
3082         .db 8,7
3083         .db %11111010   ;█████ █
3084         .db %01100001   ; ██    █
3085         .db %11111101   ;██████ █
3086         .db %11100111   ;███  ███
3087         .db %11111101   ;██████ █
3088         .db %01100001   ; ██    █
3089         .db %11111010   ;█████ █
3090
3091 spr_ship03:             ;(hardcore; up double)
3092         .db 7,7         ;ship delta class (lord british)
3093         .db %11000000   ; ██
3094         .db %11110000   ; ████
3095         .db %11111100   ; ██████
3096         .db %01100010   ;  ██   █
3097         .db %11111100   ; ██████
3098         .db %11110000   ; ████
3099         .db %11000000   ; ██
3100 spr_ship03i:
3101         .db 8,7
3102         .db %11111100   ; ██████
3103         .db %11110010   ; ████  █
3104         .db %11111101   ; ██████ █
3105         .db %01100011   ;  ██   ██
3106         .db %11111101   ; ██████ █
3107         .db %11110010   ; ████  █
3108         .db %11111100   ; ██████
3109
3110 spr_ship04:             ;(hardcore; tail beam)
3111         .db 7,7         ;XC1701II ship
3112         .db %11110000   ;████
3113         .db %10001100   ;█   ██
3114         .db %11110010   ;████  █
3115         .db %01011110   ; █ ████
3116         .db %11110010   ;████  █
3117         .db %10001100   ;█   ██
3118         .db %11110000   ;████
3119 spr_ship04i:
3120         .db 7,7
3121         .db %11110000   ;████
3122         .db %10011100   ;█  ███
3123         .db %11111110   ;███████
3124         .db %01011110   ; █ ████
3125         .db %11111110   ;███████
3126         .db %10011100   ;█  ███
3127         .db %11110000   ;████
3128
3129 auch_bullet  = 1        ;damage to you when hit by an enemy bullet
3130 auch_ground  = 5        ;the same when you hit the ground/ceiling
3131 auch_collide = 3        ;when you hit an enemy
3132 auch_ecollide = 2*4     ;damage to both the enemy that hit you (skip bit 0/1)
3133
3134 spr_multiple:
3135         .db 6,6         ;multiples
3136         .db %00000000   ;
3137         .db %00111000   ;  ███
3138         .db %01111100   ; █████
3139         .db %01111100   ; █████
3140         .db %01111100   ; █████
3141         .db %00111000   ;  ███
3142 spr_multiple2:
3143         .db 7,7         ;multiples
3144         .db %00111000   ;  ███
3145         .db %01111100   ; █████
3146         .db %11111110   ;███████
3147         .db %11111110   ;███████
3148         .db %11111110   ;███████
3149         .db %01111100   ; █████
3150         .db %00111000   ;  ███
3151
3152 ;-------------------------------- explosions --------------------------------
3153
3154 spr_explosion:
3155         .db 8,6         ;1
3156         .db %00000000
3157         .db %00011100   ;    ███
3158         .db %00111110   ;   █████
3159         .db %01010110   ;  █ █ ██
3160         .db %00111000   ;   ███
3161         .db %00000000
3162
3163         .db 8,6         ;2
3164         .db %00110000   ;   ██
3165         .db %01001110   ;  █ ▒███
3166         .db %10111110   ; █ █████
3167         .db %01001111   ;  █ ▒████
3168         .db %00111000   ;   ███
3169         .db %00011010   ;    ██ █
3170
3171         .db 8,6         ;3
3172         .db %10110000   ; █ ██
3173         .db %01001110   ;  █  ███
3174         .db %10110101   ; █ ██▒█▒█
3175         .db %01000101   ;  █  ▒█▒█
3176         .db %00111110   ;   █████
3177         .db %01011010   ;  █ ██ █
3178
3179         .db 8,6         ;4
3180         .db %00101010   ; ▒ █▒█ █
3181         .db %01000110   ;  █  ▒██
3182         .db %10110101   ; █ ██ █ █
3183         .db %01100110   ;  ██  ██▒
3184         .db %00111100   ;   ████▒
3185         .db %01011001   ;  █ ██ ▒█
3186
3187         .db 8,6         ;5
3188         .db %01000000   ;  █▒ ▒ ▒
3189         .db %00100101   ;  ▒█  █▒█
3190         .db %00010100   ; ▒ ▒█ █ ▒
3191         .db %01000100   ;  █▒  █
3192         .db %00010010   ;   ▒█▒▒█
3193         .db %10011010   ; █▒ ██ █▒
3194
3195         .db 8,6         ;6
3196         .db %01000100   ;  █   █
3197         .db %00100000   ;   ▒█ ▒ ▒
3198         .db %00000001   ;    ▒ ▒ █
3199         .db %01000100   ;  █   █
3200         .db %00100010   ;   █▒  █
3201         .db %01001000   ; ▒█ ▒█ ▒
3202
3203         .db 8,6         ;7
3204         .db %00001000   ;  ▒  █▒
3205         .db %11000010   ; ██ ▒  █
3206         .db %00000000   ;        ▒
3207         .db %00100000   ;  ▒█  ▒
3208         .db %00000001   ;   ▒   ▒█
3209         .db %00110000   ;  ▒██▒
3210
3211         .db 8,6         ;8
3212         .db %00000100   ;     ▒█
3213         .db %00000000   ; ▒▒    ▒
3214         .db %01000000   ;  █
3215         .db %00000000   ;   ▒
3216         .db %00000010   ;       █▒
3217         .db %00100100   ;   █▒ █
3218
3219 spr_yexplosion:
3220         .db 8,5         ;1
3221         .db %00000000
3222         .db %00101100   ;  █ ██
3223         .db %00011110   ;   ████
3224         .db %00110100   ;  ██ █
3225         .db %00011000   ;   ██
3226         .db %00000000
3227
3228         .db 8,5         ;2
3229         .db %00111000   ;  ███
3230         .db %01011100   ; █ ███
3231         .db %10010111   ;█  █ ███
3232         .db %01000110   ; █   ██
3233         .db %00111000   ;  ███
3234         .db %00000000
3235
3236         .db 8,6         ;3
3237         .db %00111100   ;   ████
3238         .db %01001111   ; █  ████
3239         .db %10100011   ;█ █   ██
3240         .db %11000110   ;██   ██
3241         .db %01110101   ; ███ █ █
3242         .db %00111000   ;  ███
3243
3244         .db 8,6         ;4
3245         .db %00110110   ;  ██ ██
3246         .db %00000101   ;     █ █
3247         .db %11000001   ;██     █
3248         .db %01100001   ; ██    █
3249         .db %11000010   ;██    █
3250         .db %01010001   ; █ █   █
3251
3252 ;--------------------------------- bullets ----------------------------------
3253
3254 bullettable:
3255         .db (spr_bullet01-spr_bullet01) ;0
3256         .db (spr_bullet02-spr_bullet01) ;4
3257         .db (spr_bullet03-spr_bullet01) ;8
3258         .db (spr_bullet04-spr_bullet01) ;12
3259         .db (spr_bullet05-spr_bullet01) ;16
3260         .db (spr_bullet06-spr_bullet01) ;20
3261         .db (spr_bullet07-spr_bullet01) ;24
3262         .db (spr_bullet08-spr_bullet01) ;28
3263         .db (spr_bullet09-spr_bullet01) ;32
3264         .db (spr_bullet10-spr_bullet01) ;36
3265         .db (spr_bullet11-spr_bullet01) ;40
3266         .db (spr_bullet12-spr_bullet01) ;44
3267         .db (spr_bullet13-spr_bullet01) ;48
3268         .db (spr_bullet13-spr_bullet01) ;52
3269         .db (spr_bullet13-spr_bullet01) ;56
3270         .db (spr_bullet13-spr_bullet01) ;60
3271
3272 spr_bullet01:
3273         .db 2,1
3274         .db %11000000   ;▒██
3275 spr_bullet02:
3276         .db 4,1
3277         .db %11110000   ;▒████
3278 spr_bullet03:
3279         .db 2,2
3280         .db %11000000   ;▒██
3281         .db %11000000   ;▒██
3282 spr_bullet04:
3283         .db 4,2
3284         .db %10110000   ;▒█▒██
3285         .db %10110000   ;▒█▒██
3286 spr_bullet05:
3287         .db 4,3
3288         .db %01100000   ; ▒██
3289         .db %11110000   ;▒████
3290         .db %01100000   ; ▒██
3291 spr_bullet06:
3292         .db 5,3
3293         .db %00110000   ;  ▒██
3294         .db %11111000   ;▒█████
3295         .db %00110000   ;  ▒██
3296 spr_bullet07:
3297         .db 5,3
3298         .db %01110000   ; ▒███
3299         .db %11111000   ;▒█████
3300         .db %01110000   ; ▒███
3301 spr_bullet08:
3302         .db 5,3
3303         .db %11110000   ;▒████
3304         .db %11111000   ;▒█████
3305         .db %11110000   ;▒████
3306 spr_bullet09:
3307         .db 5,4
3308         .db %00010000   ;   ▒█
3309         .db %10111000   ;▒█▒███
3310         .db %01111000   ; ▒████
3311         .db %00010000   ;   ▒█
3312 spr_bullet10:
3313         .db 6,4
3314         .db %00111000   ;  ▒███
3315         .db %01111100   ; ▒█████
3316         .db %11111100   ;▒██████
3317         .db %00110000   ;  ▒██
3318 spr_bullet11:
3319         .db 7,5
3320         .db %00011000   ;   ▒██
3321         .db %11111100   ;▒██████
3322         .db %00111110   ;  ▒█████
3323         .db %01111100   ; ▒█████
3324         .db %00011000   ;   ▒██
3325 spr_bullet12:
3326         .db 7,6
3327         .db %00110000   ;  ▒██
3328         .db %11111100   ;▒██████
3329         .db %00111110   ;  ▒█████
3330         .db %01111110   ; ▒██████
3331         .db %11111100   ;▒██████
3332         .db %00111000   ;  ▒███
3333 spr_bullet13:
3334         .db 8,8
3335         .db %00111100   ;  ▒████
3336         .db %11111110   ;▒███████
3337         .db %01111111   ; ▒███████
3338         .db %00011111   ;   ▒█████
3339         .db %01111111   ; ▒███████
3340         .db %11111110   ;▒███████
3341         .db %00111100   ;  ▒████
3342
3343 spr_bullett1:
3344         .db 4,3         ;▒▒▒
3345         .db %11100000   ;▒███
3346         .db %11110000   ; ████
3347         .db %01110000   ;  ███
3348
3349 spr_bullete1:
3350         .db 4,3         ;enemy bullets
3351         .db %01100000   ; ██▒
3352         .db %11110000   ;████▒
3353         .db %01100000   ; ██▒
3354
3355 ;format:[min.damage] [dam.inc] [000:direction 00000:speed] [offset]
3356 ;damage = min.damage + dam.inc*incs (0<=incs<=6)
3357 ;speed in pixels/frame (>=%10010=forward; <=%01110=backwards)
3358 ;direction: 001=straight forward; 010=up; 011=1/2up; 100=down; 101=1/2down
3359 ;           111=laser (speed=duration 00010-00000)
3360
3361 weapondata:
3362         .db  1,1,%00110010,3,%00000000,0,%00000000,0    ;1 single beam
3363         .db  3,1,%00110011,3,%00000000,0,%00000000,0    ;2 fast single
3364         .db  1,1,%00110010,0,%00110010,6,%00000000,0    ;3 double
3365         .db  1,1,%01110010,2,%10010010,2,%00110010,2    ;4 triple
3366         .db  3,2,%01110011,2,%10010011,2,%00110011,2    ;5
3367         .db  6,2,%01110011,2,%10010100,2,%00110011,2    ;6
3368         .db  9,3,%01110100,2,%10010100,2,%00110100,2    ;7
3369         .db 13,3,%01110110,2,%10010110,2,%00110110,2    ;8
3370         .db 18,4,%01110110,2,%10010110,2,%00110110,2    ;9
3371 maxweapon  = 9
3372         .db  1,1,%11100100,3,%00000000,0,%00000000,0    ;1 single laser
3373         .db  2,3,%11100011,3,%00000000,0,%00000000,0    ;2 short
3374         .db  1,2,%11100100,3,%11100000,4,%00000000,0    ;3 fat
3375         .db  1,2,%11100101,0,%11100000,6,%00000000,0    ;4 double
3376         .db  3,4,%11100011,3,%00000000,0,%00000000,0    ;5 short
3377         .db  1,2,%11100100,3,%11100000,6,%11100000,0    ;6 triple
3378         .db  1,3,%11101010,3,%11100000,6,%11100000,0    ;7 triple long
3379         .db  2,4,%11100101,2,%11100000,4,%00000000,0    ;8 double
3380         .db  2,1,%11101011,3,%11100000,2,%11100000,4    ;9 big fat long
3381 maxlaser   = 18
3382 tailbeam   = %00101101  ;180 degrees
3383 doublebeam = %01010010  ;45 degrees
3384 extrabulletpos:
3385         .db  3 ;tail/double yposition
3386
3387 ;------------------------------------ bar -----------------------------------
3388
3389 spr_lship:
3390         .db 5,3                 ;li'l ship indicating lives left
3391         .db %11100000           ;███
3392         .db %01111000           ; ████
3393         .db %11100000           ;███
3394 lshipsize = 5                   ;space between two ship icons
3395
3396 spr_icon:
3397         .db 16,7        ;selected.......:.......:
3398         .db %11111111           ;████████████████
3399         .db %11000000           ;██             █
3400         .db %11000000           ;██             █
3401         .db %11000000           ;██             █
3402         .db %11000000           ;██             █
3403         .db %11000000           ;██             █
3404         .db %11111111           ;████████████████
3405         .db 7
3406         .db %11111111
3407         .db %00000001
3408         .db %00000001
3409         .db %00000001
3410         .db %00000001
3411         .db %00000001
3412         .db %11111111
3413 spr_icon00:
3414         .db 16,7        ;unused  .......:.......:
3415         .db %10101010           ;█ █ █ █ █ █ █ █
3416         .db %11010101           ;██ █ █ █ █ █ █ █
3417         .db %10101010           ;█ █ █ █ █ █ █ █
3418         .db %11010101           ;██ █ █ █ █ █ █ █
3419         .db %10101010           ;█ █ █ █ █ █ █ █
3420         .db %11010101           ;██ █ █ █ █ █ █ █
3421         .db %10101010           ;█ █ █ █ █ █ █ █
3422         .db 7
3423         .db %10101010
3424         .db %01010101
3425         .db %10101010
3426         .db %01010101
3427         .db %10101010
3428         .db %01010101
3429         .db %10101010
3430 spr_icon01:
3431         .db 16,7        ;shield  .......:.......:
3432         .db %10001111           ;█   ███████  █  ▒
3433         .db %10011001           ;█  ██  █████  █ ▒
3434         .db %10111100           ;█ ████   ████ █ ▒
3435         .db %10111000           ;█ ███   █  ██ █ ▒
3436         .db %10111100           ;█ ████   ████ █ ▒
3437         .db %10011001           ;█  ██  █████  █ ▒
3438         .db %10001111           ;█   ███████  █  ▒
3439         .db 7
3440         .db %11100100
3441         .db %11110010
3442         .db %01111010
3443         .db %10011010
3444         .db %01111010
3445         .db %11110010
3446         .db %11100100
3447 spr_icon02a:
3448         .db 16,7        ;tailbeam.......:.......:
3449         .db %10000000           ;█               ▒
3450         .db %10000011           ;█     ██        ▒
3451         .db %10000001           ;█      ███      ▒
3452         .db %10111011           ;█ ███ ███ ██  ██▒
3453         .db %10000001           ;█      ███      ▒
3454         .db %10000011           ;█     ██        ▒
3455         .db %10000000           ;█               ▒
3456         .db 5
3457         .db %00000000
3458         .db %00000000
3459         .db %11000000
3460         .db %10110011
3461         .db %11000000
3462 spr_icon02b:
3463         .db 16,7        ;updouble.......:.......:
3464         .db %10000000           ;█          ██   ▒
3465         .db %10000000           ;█         ██    ▒
3466         .db %10110000           ;█ ██     ██     ▒
3467         .db %10011100           ;█  ███          ▒
3468         .db %10111011           ;█ ███ ██   ████ ▒
3469         .db %10011100           ;█  ███          ▒
3470         .db %10110000           ;█ ██            ▒
3471         .db 5
3472         .db %00011000
3473         .db %00110000
3474         .db %01100000
3475         .db %00000000
3476         .db %00011110
3477 spr_icon03:
3478         .db 11,7        ;bullets .......:.......:
3479         .db %10000000           ;█       ██      ▒
3480         .db %10000011           ;█     █████ ▒▒▒ ▒
3481         .db %10011000           ;█  ██   ██  ▒▒▒ ▒
3482         .db %11111100           ;██████      ▒▒▒ ▒
3483         .db %10011000           ;█  ██   ██  ▒▒▒ ▒
3484         .db %10000011           ;█     █████ ▒▒▒ ▒
3485         .db %10000000           ;█       ██      ▒
3486         .db 7
3487         .db %11000000
3488         .db %11100000
3489         .db %11000000
3490         .db %00000000
3491         .db %11000000
3492         .db %11100000
3493         .db %11000000
3494 spr_icon04:
3495         .db 16,7        ;laser   .......:.......:
3496         .db %10000000           ;█               ▒
3497         .db %10001010           ;█   █ █     ▒▒▒ ▒
3498         .db %11101100           ;███ ██      ▒▒▒ ▒
3499         .db %11110111           ;████ ███████▒▒▒█▒
3500         .db %11101100           ;███ ██      ▒▒▒ ▒
3501         .db %10001010           ;█   █ █     ▒▒▒ ▒
3502         .db %10000000           ;█               ▒
3503         .db 4
3504         .db %00000000
3505         .db %00000000
3506         .db %00000000
3507         .db %11111111
3508 spr_icon05:
3509         .db 16,7        ;multiple.......:.......:
3510         .db %10000011           ;█     ███       ▒
3511         .db %10000001           ;█      ████  ██ ▒
3512         .db %10000001           ;█      ████     ▒
3513         .db %10000011           ;█     ███       ▒
3514         .db %10011000           ;█  ██           ▒
3515         .db %10111100           ;█ ████  ██    ██▒
3516         .db %10011000           ;█  ██           ▒
3517         .db 6
3518         .db %10000000
3519         .db %11100110
3520         .db %11100000
3521         .db %10000000
3522         .db %00000000
3523         .db %11000011
3524 spr_dividerline:
3525         .db 8,7
3526         .db 128,128,128,128,128,128,128 ;128 = %10000000
3527
3528 ;---------------------------- texts -----------------------------------------
3529
3530 txt_email:      .db "www.shiar.org ",127 ;title screen
3531                 .db " shiar0@hotmail.com",0
3532 _txt_email        = $3A01 ;$3A1E=just email
3533 txt_about:      .db "v0.99.829 ",127," by Shiar",0 ;right behind txt_email
3534 _txt_about        = $3321
3535 txt_menu1:      .db "NEW GAME",0
3536 txt_menu2:      .db "CONTINUE",0
3537
3538 txt_difhardcore:.db "Hardcore!",0
3539 txt_difnormal:  .db "Normal",0
3540 txt_updouble:   .db "Up Double",0
3541 txt_tailbeam:   .db "Tail Beam",0
3542
3543 txt_level:      .db "LEVEL ",0 ;new level screen
3544 txt_lives:      .db   "Lx0",0
3545 txt_savekey:    .db "Press [F1] to save",0
3546
3547 txt_gameover:   .db "GAME OVER!",0 ;game over screen
3548 txt_score:      .db "Score",0
3549 txt_hiscore:    .db "Hiscore",0
3550
3551 txt_pause:      .db " ",6,"/",7," ",$1C,"contrast; "
3552                 .db "F1",$1C,"B",$CF,5,"W Mode",0
3553 _txt_pause        = $020B
3554 txt_pressenter: .db "Enter to continue",0 ;pause
3555 _txt_pressenter   = $0201
3556 txt_teacher:    .db "(2",Lpi,"*.98)/sin 13",0 ;teacher
3557 txt_teacherans: .db Lneg,"14.6549373495",0
3558
3559 ;---------------------------- save data -------------------------------------
3560
3561 storehi_start:
3562 hiscore         .dw 0                   ;default hiscore
3563 hiname          .db "shiar.99",0        ;   "       "    name
3564 storehi_end:
3565
3566 invertmode:      cpl                    ;saves B<>W mode setting        cpl
3567
3568 storesave_start:                        ;--SAVED GAME--                 defs:
3569 your_ship       .dw spr_ship01          ;your sprite (^invertmode^)     sprs1
3570 level           .db  1                  ;level number                   1
3571 levelp          .dw level00             ;pointer to level data          lev00
3572 pickuptimer     .db  4                  ;counts when to place a pickup  4
3573 your_extramode  .db  1                  ;you have tail or double        1
3574 your_score      .dw  0                  ;current score                  0
3575 your_pickup     .db  0                  ;pickups already picked up      0
3576 your_occ        .db  0                  ;0=normal 1..16=exploding       0
3577 your_shield     .db  0                  ;invincibility left             0
3578 your_armor      .db 24                  ;HP left                        12
3579 your_lives      .db  3                  ;lives left                     3
3580 your_weapon     .db  3                  ;current weapon upgrade         0
3581 your_multiples  .db  0                  ;multiples present              0
3582 your_extra      .db  0                  ;extra beam present             0
3583 hardcore        .db  0                  ;hardcore mode if non-0         0
3584 storesave_end:
3585
3586 time2invert:    .db 0                   ;time until b<>w switch (0 at startup)
3587
3588 ;------------------------------ levels data ---------------------------------
3589
3590 ;format:boss: [moveType] [enemyType]
3591 ;       @level: [nr.dif.enemies]x [enemy nr]
3592 ;       [min. enemy frequency] [enemy frequency max.inc]
3593 ;       [next lvl (=nrenemies+4)] [level_info: 1:ceiling 1:ground]
3594 ;       [tunnel size] [groundtype] [stars1] [stars2]
3595 ;efrequency must be odd if halfluring!
3596
3597         .db 0   ;storyline ID
3598 levelstart:     ;[y-pos] [x-pos] [text,0] [SFX lines; 0=more text] [-1=end]
3599         .db 25,33,"Imperial ships have",0,0
3600         .db 31,9,"been sent to intercept you",0,31-25+6,-1
3601
3602         .db 30
3603 level00:.db 5,2,4,2,1,1
3604         .db 28,73,13
3605         .db %00,0,0,1,1
3606
3607         .db 31 ;boss for level01
3608 level01:.db 2,2,4 ;enemies
3609         .db 26,70,20
3610         .db %00,0,0,1,1
3611
3612         .db 32
3613 level02:.db 3,2,3,4
3614         .db 20,60,60
3615         .db %00,0,0,1,1
3616
3617         .db 33
3618 level03:.db 4,3,4,5,6
3619         .db 17,40,75
3620         .db %00,0,0,1,1
3621
3622         .db 0
3623         .db 1,1,"Long-Range scanners are ",
3624         .db     "showing",0,0
3625         .db 8,1,"lots of enemy vessels ",
3626         .db     "advancing fast.",0,8-1+6
3627         .db 24,1,"I'm changing course to a",
3628         .db     " nearby ",0,0
3629         .db 31,1,"asteroid belt and try to",0,0
3630         .db 38,1,"lose them inthere.",0,38-24+6,-1
3631
3632 ;---- approaching asteroid belt
3633         .db 34
3634 level04:.db 5,7,7,8,10,11
3635         .db 17,27,70
3636         .db %00,0,0,1,1
3637
3638 ;---- light asteroid belt
3639         .db 35
3640 level05:.db 7,9,10,8,10,11,11,13
3641         .db 12,24,80
3642         .db %00,0,0,1,1
3643
3644 ;---- inside asteroid belt
3645         .db 36
3646 level06:.db 10,9,10,11,11,13,12,12,13,14,14
3647         .db 7,18,180
3648         .db %00,0,0,1,1
3649
3650         .db 37
3651 level07:.db 4,15,16,17,5
3652         .db 22,29,62
3653         .db %00,0,0,1,1 ;-1=%11111111=line
3654
3655         .db 38
3656 level08:.db 5,15,16,17,18,18
3657         .db 20,38,57
3658         .db %00,0,0,1,1
3659
3660         .db 39
3661 level09:.db 3,18,19,20
3662         .db 19,63,57
3663         .db %00,0,0,1,1
3664
3665         .db 0,1,1,"That`s all folks...",0,0
3666         .db 20,50,"for now...",0,20-0+6,-1
3667
3668 endlevel = 10
3669
3670 pickupfreq = 10
3671
3672 ;------------------------------ enemies -------------------------------------
3673
3674 ;format:        [HP64] [000000:HP 00:occ] [sprite] [xpos] [appearance(ypos)]
3675 ;               [movetype] [time2fire] [firefreq] [firetype]
3676 ;occ:           00=no enemy; 01=exploding (sprite=frame); 10=pickup; 11=enemy
3677 ;appearances:   1=random; 2=lure; 3=halflure
3678 ;movetypes:     1=updown; 2=1/4x; 3=1/2x; 4=3/4x; 5=3/2x; 6=2x; 7=ylure50%;
3679 ;               7=ylure; 8=ylure50%; 9=x; 10=x+y-lure 50%; 11=-1/2x; 12=-1x
3680 ;firetypes:     1=normal; 6=aiming; 7=triple; 8=double
3681
3682 enemyspecs:  ;10 bytes/enemy | max.enemies <64 | sprites use <768 bytes
3683         .db 0,%00000110,spr_enemy00&255,spr_enemy00/256,128,2,03, 0, 0,1 ;pickup
3684 ;1-6=basic enemies     ,               ,               ,   , ,  ,  ,  ,
3685         .db 0,%00000111,spr_enemyE0&255,spr_enemyE0/256,128,1,00,12, 0,1 ;intro
3686         .db 0,%00010011,spr_enemyE1&255,spr_enemyE1/256,128,1,00,10, 0,1 ;weak
3687         .db 0,%00110011,spr_enemyE4&255,spr_enemyE4/256,128,1,03, 6,50,1 ;slow
3688         .db 0,%00100111,spr_enemyE2&255,spr_enemyE2/256,128,1,00, 1, 0,1
3689         .db 0,%00101111,spr_enemyE3&255,spr_enemyE3/256,128,3,00,19,39,8 ;heavy
3690         .db 0,%00101011,spr_enemyE5&255,spr_enemyE5/256,128,3,05, 1, 0,1 ;fast
3691 ;7-9=backwards enemies ,               ,               ,   , ,  ,  ,  ,
3692         .db 0,%00011111,spr_enemyB1&255,spr_enemyB1/256,000,3,11,19,92,1
3693         .db 0,%00101111,spr_enemyB2&255,spr_enemyB2/256,000,1,12,11,45,1
3694         .db 0,%00110111,spr_enemyB3&255,spr_enemyB3/256,000,1,11,10,41,8 ;small
3695 ;10-14=asteroid        ,               ,               ,   , ,  ,  ,  ,
3696         .db 0,%00100111,spr_enemyA1&255,spr_enemyA1/256,128,1,04, 0, 0,1
3697         .db 0,%00111111,spr_enemyA2&255,spr_enemyA2/256,128,1,00, 0, 0,1
3698         .db 0,%01011011,spr_enemyA3&255,spr_enemyA3/256,128,1,05, 0, 0,1
3699         .db 1,%00001011,spr_enemyA4&255,spr_enemyA4/256,128,1,03, 0, 0,1 ;slow+hard
3700         .db 0,%00111111,spr_enemyA4&255,spr_enemyA4/256,128,1,06, 0, 0,1
3701 ;15-20=improved enemies,               ,               ,   , ,  ,  ,  ,
3702         .db 0,%01001011,spr_enemyG1&255,spr_enemyG1/256,128,3,00, 3,40,1
3703         .db 0,%01011111,spr_enemyG2&255,spr_enemyG2/256,128,3,00, 1,36,1
3704         .db 0,%00110011,spr_enemyG5&255,spr_enemyG5/256,128,1,01, 9,52,1 ;updown
3705         .db 0,%01111011,spr_enemyG3&255,spr_enemyG3/256,128,3,04, 7,99,7 ;3x
3706         .db 0,%10110111,spr_enemyG4&255,spr_enemyG4/256,128,2,01,17, 0,7 ;updown3x
3707         .db 0,%10001011,spr_enemyG6&255,spr_enemyG6/256,128,2,07,62,60,8 ;lure
3708 ;21-29=unused,         ,               ,               ,   , ,  ,  ,  ,
3709         .db 0,%00000011,spr_enemy00&255,spr_enemy00/256,128,2,03, 0, 0,1 ;21
3710         .db 0,%00000011,spr_enemy00&255,spr_enemy00/256,128,2,03, 0, 0,1 ;22
3711         .db 0,%00000011,spr_enemy00&255,spr_enemy00/256,128,2,03, 0, 0,1 ;23
3712         .db 0,%00000011,spr_enemy00&255,spr_enemy00/256,128,2,03, 0, 0,1 ;24
3713         .db 0,%00000011,spr_enemy00&255,spr_enemy00/256,128,2,03, 0, 0,1 ;25
3714         .db 0,%00000011,spr_enemy00&255,spr_enemy00/256,128,2,03, 0, 0,1 ;26
3715         .db 0,%00000011,spr_enemy00&255,spr_enemy00/256,128,2,03, 0, 0,1 ;27
3716         .db 0,%00000011,spr_enemy00&255,spr_enemy00/256,128,2,03, 0, 0,1 ;28
3717         .db 0,%00000011,spr_enemy00&255,spr_enemy00/256,128,2,03, 0, 0,1 ;29
3718 ;30-34=first bosses    ,               ,               ,   , ,  ,  ,  ,
3719         .db 1,%00100011,spr_boss01 &255,spr_boss01 /256,127,1,09,35,50,7 ;triple
3720         .db 1,%00101011,spr_boss02 &255,spr_boss02 /256,127,1,09,20,12,1 ;small
3721         .db 1,%00111111,spr_boss03 &255,spr_boss03 /256,127,1,09,15,11,8 ;normal
3722         .db 1,%01001111,spr_boss04 &255,spr_boss04 /256,127,3,10,10,11,1 ;moving
3723         .db 0,%11111111,spr_boss05 &255,spr_boss05 /256,127,2,10, 1, 4,1 ;weak+rapidfire
3724 ;35-36=asteroid bosses ,               ,               ,   , ,  ,  ,  ,
3725         .db 2,%00001011,spr_bossA1 &255,spr_bossA1 /256,127,1,10,36,14,6
3726         .db 2,%00110011,spr_bossA1 &255,spr_bossA1 /256,127,2,10,28,12,6
3727 ;37-40=big bosses      ,               ,                   ,   , ,  ,  ,  ,
3728         .db 2,%00000011,spr_boss07 &255,spr_boss07 /256,127,3,08,31, 8,7
3729         .db 2,%00100111,spr_boss06 &255,spr_boss06 /256,127,3,08,13, 7,7
3730         .db 2,%00100111,spr_boss08 &255,spr_boss08 /256,127,1,08,18, 8,9  ;quad
3731         .db 2,%10010011,spr_boss09 &255,spr_boss09 /256,127,1,08,21, 9,10 ;6x
3732
3733 spr_enemy00:
3734         .db 10,8                        ;pickup
3735         .db %00111111                   ;  ██████
3736         .db %01100001                   ; ██    ██
3737         .db %10001100                   ;█   ██   █
3738         .db %10111111                   ;█ ██████ █
3739         .db %10111111                   ;█ ██████ █
3740         .db %10001100                   ;█   ██   █
3741         .db %01100001                   ; ██    ██
3742         .db %00111111                   ;  ██████
3743         .db 7
3744         .db %00000000
3745         .db %10000000
3746         .db %01000000
3747         .db %01000000
3748         .db %01000000
3749         .db %01000000
3750         .db %10000000
3751
3752 spr_enemyE0:
3753         .db 6,7                         ;weak
3754         .db %00011100                   ;   ███
3755         .db %00100100                   ;  █  █
3756         .db %01101000                   ; ██ █
3757         .db %10110100                   ;█ ██ █
3758         .db %01101000                   ; ██ █
3759         .db %00100100                   ;  █  █
3760         .db %00011100                   ;   ███
3761 spr_enemyE1:
3762         .db 6,7                         ;weak
3763         .db %00111100                   ;  ████
3764         .db %01000100                   ; █   █
3765         .db %10111000                   ;█ ███
3766         .db %11100000                   ;███
3767         .db %10111000                   ;█ ███
3768         .db %01000100                   ; █   █
3769         .db %00111100                   ;  ████
3770 spr_enemyE2:
3771         .db 6,6                         ;weak
3772         .db %00111100                   ;  ████
3773         .db %01010000                   ; █ █
3774         .db %10100000                   ;█ █
3775         .db %10100000                   ;█ █
3776         .db %01010000                   ; █ █
3777         .db %00111100                   ;  ████
3778 spr_enemyE3:
3779         .db 6,6                         ;normal solid (Galaxian enemy)
3780         .db %00111100                   ;  ████
3781         .db %01010000                   ; █ █
3782         .db %11010000                   ;██ █
3783         .db %11010000                   ;██ █
3784         .db %01010000                   ; █ █
3785         .db %00111100                   ;  ████
3786 spr_enemyE4:
3787         .db 6,7
3788         .db %00011100                   ;   ███
3789         .db %01101000                   ; ██ █
3790         .db %10011000                   ;█  ██
3791         .db %01110000                   ; ███
3792         .db %10011000                   ;█  ██
3793         .db %01101000                   ; ██ █
3794         .db %00011100                   ;   ███
3795 spr_enemyE5:
3796         .db 6,6                         ;speedy
3797         .db %00010100                   ;   █ █
3798         .db %01111000                   ; ████
3799         .db %10100000                   ;█ █
3800         .db %10100000                   ;█ █
3801         .db %01111000                   ; ████
3802         .db %00010100                   ;   █ █
3803
3804 spr_enemyB1:
3805         .db 6,6                         ;solid backwards
3806         .db %11110000                   ;████
3807         .db %00101000                   ;  █ █
3808         .db %01010100                   ; █ █ █
3809         .db %01010100                   ; █ █ █
3810         .db %00101000                   ;  █ █
3811         .db %11110000                   ;████
3812 spr_enemyB2:
3813         .db 6,7
3814         .db %11110000                   ;████
3815         .db %01001000                   ; █  █
3816         .db %01110100                   ; ███ █
3817         .db %00100100                   ;  █  █
3818         .db %01110100                   ; ███ █
3819         .db %01001000                   ; █  █
3820         .db %11110000                   ;████
3821 spr_enemyB3:
3822         .db 5,7
3823         .db %11100000                   ;███
3824         .db %01010000                   ; █ █
3825         .db %01111000                   ; ████
3826         .db %01000000                   ; █
3827         .db %01111000                   ; ████
3828         .db %01010000                   ; █ █
3829         .db %11100000                   ;███
3830
3831 spr_enemyA1:
3832         .db 7,6                         ;asteroid one
3833         .db %00011000                   ;   ██
3834         .db %01101100                   ; ██ ██
3835         .db %10011110                   ;█  ████
3836         .db %11111010                   ;█████ █
3837         .db %10111100                   ;█ ████
3838         .db %01110000                   ; ███
3839 spr_enemyA2:
3840         .db 8,7                         ;asteroid two
3841         .db %00111100                   ;  ████
3842         .db %01011010                   ; █ ██ █
3843         .db %01101101                   ; ██ ██ █
3844         .db %11111101                   ;██████ █
3845         .db %11111111                   ;████████
3846         .db %10110110                   ;█ ██ ██
3847         .db %01100000                   ; ██
3848 spr_enemyA3:
3849         .db 8,8                         ;asteroid three
3850         .db %00011110                   ;   ████
3851         .db %01110011                   ; ███  ██
3852         .db %01111101                   ; █████ █
3853         .db %10110111                   ;█ ██ ███
3854         .db %11111110                   ;███████
3855         .db %11111101                   ;██████ █
3856         .db %01010111                   ; █ █ ███
3857         .db %00001110                   ;    ███
3858 spr_enemyA4:
3859         .db 7,6                         ;asteroid four
3860         .db %01111000                   ; ████
3861         .db %10110110                   ;█ ██ ██
3862         .db %11111101                   ;██████ █
3863         .db %01111011                   ; ████ ██
3864         .db %01001110                   ; █  ███
3865         .db %00110000                   ;  ██
3866
3867 spr_enemyG1:
3868         .db 8,6                         ;G-Type
3869         .db %00011111                   ;   █████
3870         .db %01001000                   ; █  █
3871         .db %10110100                   ;█ ██ █
3872         .db %10110100                   ;█ ██ █
3873         .db %01001000                   ; █  █
3874         .db %00011111                   ;   █████
3875 spr_enemyG2:
3876         .db 8,6                         ;smaller nacelles
3877         .db %00010111                   ;   █ ███
3878         .db %01101100                   ; ██ ██
3879         .db %10110100                   ;█ ██ █
3880         .db %10110100                   ;█ ██ █
3881         .db %01101100                   ; ██ ██
3882         .db %00010111                   ;   █ ███
3883 spr_enemyG3:
3884         .db 8,6                         ;shuttle
3885         .db %00001111                   ;    ████
3886         .db %01110100                   ; ███ █
3887         .db %10011100                   ;█  ███
3888         .db %10011100                   ;█  ███
3889         .db %01110100                   ; ███ █
3890         .db %00001111                   ;    ████
3891 spr_enemyG4:
3892         .db 8,6                         ;G-Type solid
3893         .db %00111101                   ;   ███ █
3894         .db %01111000                   ; ████
3895         .db %11110100                   ;████ █
3896         .db %11110100                   ;████ █
3897         .db %01111000                   ; ████
3898         .db %00111101                   ;   ███ █
3899 spr_enemyG5:
3900         .db 6,6
3901         .db %01111100                   ; █████
3902         .db %10110000                   ;█ ██
3903         .db %10101000                   ;█ █ █
3904         .db %10101000                   ;█ █ █
3905         .db %10110000                   ;█ ██
3906         .db %01111100                   ; █████
3907 spr_enemyG6:
3908         .db 8,5                         ;shuttle
3909         .db %00001111                   ;    ████
3910         .db %01110100                   ; ███ █
3911         .db %10011010                   ;█  ██ █
3912         .db %01110100                   ; ███ █
3913         .db %00001111                   ;    ████
3914
3915 spr_enemyS1:
3916         .db 6,6                         ;solid
3917         .db %00111000                   ;   ███
3918         .db %01111100                   ;  █████
3919         .db %11111000                   ; █████
3920         .db %11111000                   ; █████
3921         .db %01111100                   ;  █████
3922         .db %00111000                   ;   ███
3923 spr_enemyS2:
3924         .db 7,6                         ;some attack vessel
3925         .db %00011100                   ;    ███
3926         .db %01110010                   ;  ███  █
3927         .db %10101100                   ; █ █ ██
3928         .db %10101100                   ; █ █ ██
3929         .db %01110010                   ;  ███  █
3930         .db %00011100                   ;    ███
3931 spr_enemyS3:
3932         .db 7,6                         ;interceptor
3933         .db %00011110                   ;    ████
3934         .db %01111110                   ;  ██████
3935         .db %11111100                   ; ██████
3936         .db %11111100                   ; ██████
3937         .db %01111110                   ;  ██████
3938         .db %00011110                   ;    ████
3939 spr_enemyS4:
3940         .db 8,6                         ;cheap intercept
3941         .db %00011011                   ;    ██ ██
3942         .db %01110110                   ;  ███ ██
3943         .db %10111100                   ; █ ████
3944         .db %10111100                   ; █ ████
3945         .db %01110110                   ;  ███ ██
3946         .db %00011011                   ;    ██ ██
3947
3948 spr_enemyN1:
3949         .db 8,7                         ;some cool Nemesis-MSX enemy
3950         .db %00111110                   ;  █████
3951         .db %11110001                   ;████   █
3952         .db %00001110                   ;    ███
3953         .db %00010101                   ;   █ █ █
3954         .db %00001110                   ;    ███
3955         .db %11110001                   ;████   █
3956         .db %00111110                   ;  █████
3957 spr_enemyN2:
3958         .db 8,7                         ;
3959         .db %00111110                   ;  █████
3960         .db %00011101                   ;   ███ █
3961         .db %11111111                   ;████ ███
3962         .db %01110110                   ; ██ ███
3963         .db %11111111                   ;████ ███
3964         .db %00011101                   ;   ███ █
3965         .db %00111110                   ;  █████
3966 spr_enemyN3:
3967         .db 8,7                         ;Nem3MSX jumper lvl#3
3968         .db %10111110                   ;█ █████
3969         .db %01011101                   ; █ ███ █
3970         .db %01111110                   ; ██████
3971         .db %00010100                   ;   █ █
3972         .db %01111110                   ; ██████
3973         .db %01011101                   ; █ ███ █
3974         .db %10111110                   ;█ █████
3975 spr_enemyN4:
3976         .db 8,8                         ;Stolen from XC1701II
3977         .db %01111110                   ; ██████
3978         .db %11110101                   ;████ █ █
3979         .db %00011111                   ;   █████
3980         .db %00111101                   ;  ████ █
3981         .db %00111001                   ;  ███  █
3982         .db %00011111                   ;   █████
3983         .db %11110101                   ;████ █ █
3984         .db %01111110                   ; ██████
3985 spr_enemyN5:
3986         .db 7,8                         ;Stolen from XC1701II
3987         .db %00111100                   ;  ████
3988         .db %01010010                   ; █ █  █
3989         .db %11111110                   ;███████
3990         .db %01001010                   ; █  █ █
3991         .db %01011010                   ; █ ██ █
3992         .db %11111110                   ;███████
3993         .db %01010010                   ; █ █  █
3994         .db %01111100                   ;  ████
3995
3996 spr_boss01:
3997         .db 9,12                        ;.......:.2.....:
3998         .db %00000111                   ;     ████
3999         .db %00011100                   ;   ███
4000         .db %00101010                   ;  █ █ █
4001         .db %01011011                   ; █ ██ ██
4002         .db %10100110                   ;█ █  ██ █
4003         .db %11010101                   ;██ █ █ █
4004         .db %11010101                   ;██ █ █ █
4005         .db %10100110                   ;█ █  ██ █
4006         .db %01011011                   ; █ ██ ██
4007         .db %00101010                   ;  █ █ █
4008         .db %00011100                   ;   ███
4009         .db %00000111                   ;     ████
4010         .db 12
4011         .db %10000000
4012         .db %00000000
4013         .db %00000000
4014         .db %00000000
4015         .db %10000000
4016         .db %00000000
4017         .db %00000000
4018         .db %10000000
4019         .db %00000000
4020         .db %00000000
4021         .db %00000000
4022         .db %10000000
4023 spr_boss02:
4024         .db 12,12                       ;.......:....5..:
4025         .db %00011110                   ;   ████
4026         .db %01100001                   ; ██    ██
4027         .db %10110010                   ;█ ██  █  ██
4028         .db %00000101                   ;     █ ██ █
4029         .db %00001010                   ;    █ █  ██
4030         .db %00011010                   ;   ██ █ █  █
4031         .db %00011010                   ;   ██ █ █  █
4032         .db %00001010                   ;    █ █  ██
4033         .db %00000101                   ;     █ ██ █
4034         .db %10110010                   ;█ ██  █  ██
4035         .db %01100001                   ; ██    ██
4036         .db %00011110                   ;   ████
4037         .db 11
4038         .db %00000000
4039         .db %10000000
4040         .db %01100000
4041         .db %10100000
4042         .db %01100000
4043         .db %10010000
4044         .db %10010000
4045         .db %01100000
4046         .db %10100000
4047         .db %01100000
4048         .db %10000000
4049 spr_boss03:
4050         .db 16,10                       ;.......:.......:
4051         .db %00000001                   ;       ██████ ██
4052         .db %00001110                   ;    ███   █ ███
4053         .db %00110010                   ;  ██  █ ████
4054         .db %01001101                   ; █  ██ ██
4055         .db %11101011                   ;███ █ ██ █
4056         .db %11101011                   ;███ █ ██ █
4057         .db %01001101                   ; █  ██ ██
4058         .db %00110010                   ;  ██  █ ████
4059         .db %00001110                   ;    ███   █ ███
4060         .db %00000001                   ;       ██████ ██
4061         .db 10
4062         .db %11111011
4063         .db %00101110
4064         .db %11110000
4065         .db %10000000
4066         .db %01000000
4067         .db %01000000
4068         .db %10000000
4069         .db %11110000
4070         .db %00101110
4071         .db %11111011
4072 spr_boss04:
4073         .db 16,10                       ;.......:.......:
4074         .db %00000000                   ;           █████
4075         .db %00000000                   ;        ███    █
4076         .db %00000111                   ;     ████ █████
4077         .db %00111101                   ;  ████ █ █ ████
4078         .db %01001010                   ; █  █ █ ██ ███ █
4079         .db %10110110                   ;█ ██ ██ ███  █ █
4080         .db %10110110                   ;█ ██ ██ ███  █ █
4081         .db %01001010                   ; █  █ █ ██ ███ █
4082         .db %00111101                   ;  ████ █ █ ████
4083         .db %00000111                   ;     ████ █████
4084         .db 12                          ;        ███    █
4085         .db %00011111                   ;           █████
4086         .db %11100001
4087         .db %10111110
4088         .db %01011110
4089         .db %11011101
4090         .db %11100101
4091         .db %11100101
4092         .db %11011101
4093         .db %01011110
4094         .db %10111110
4095         .db %11100001
4096         .db %00011111
4097 spr_boss05:
4098         .db 16,10                       ;.......:.......:
4099         .db %11111110                   ;███████
4100         .db %00000011                   ;      ███   ████
4101         .db %00110101                   ;  ██ █ ████    █
4102         .db %01111010                   ; ████ █ █  █ ██
4103         .db %10001101                   ;█   ██ █ ██ ██ █
4104         .db %10001101                   ;█   ██ █ ██ ██ █
4105         .db %01111010                   ; ████ █ █  █ ██
4106         .db %00110101                   ;  ██ █ ████    █
4107         .db %00000011                   ;      ███   ████
4108         .db %11111110                   ;███████
4109         .db 9
4110         .db %00000000
4111         .db %10001111
4112         .db %11100001
4113         .db %10010110
4114         .db %01101101
4115         .db %01101101
4116         .db %10010110
4117         .db %11100001
4118         .db %10001111
4119 spr_bossA1:
4120         .db 12,11                       ;AsteroidBoss one
4121         .db %00011110                   ;   ████
4122         .db %01110011                   ; ███  ███
4123         .db %01111111                   ; ███████ █
4124         .db %01111111                   ; █████████
4125         .db %11111110                   ;███████ ███
4126         .db %11111111                   ;███████████
4127         .db %11111111                   ;████████████
4128         .db %10111110                   ;█ █████ ████
4129         .db %01011111                   ; █ ███████
4130         .db %00110111                   ;  ██ ███
4131         .db %00001110                   ;    ███
4132         .db 9
4133         .db %00000000
4134         .db %10000000
4135         .db %01000000
4136         .db %11000000
4137         .db %11100000
4138         .db %11100000
4139         .db %11110000
4140         .db %11110000
4141         .db %11000000
4142 spr_boss06:
4143         .db 16,15                       ;.......:.......:
4144         .db %00001111                   ;    █████
4145         .db %00111110                   ;  █████ █████
4146         .db %01111101                   ; █████ █ ███████
4147         .db %00000011                   ;      ██
4148         .db %00000100                   ;     █  █
4149         .db %00000011                   ;      █████
4150         .db %00011110                   ;   ████ ██ ████
4151         .db %11110011                   ;████  ██ █ █
4152         .db %00011110                   ;   ████ ██ ████
4153         .db %00000011                   ;      █████
4154         .db %00000100                   ;     █  █
4155         .db %00000011                   ;      ██
4156         .db %01111101                   ; █████ █ ███████
4157         .db %00111110                   ;  █████ █████
4158         .db %00001111                   ;    █████
4159         .db 15                          ;modelled after a Nemesis][MSX boss
4160         .db %10000000
4161         .db %11111000
4162         .db %01111111
4163         .db %00000000
4164         .db %10000000
4165         .db %11100000
4166         .db %11011110
4167         .db %01010000
4168         .db %11011110
4169         .db %11100000
4170         .db %10000000
4171         .db %00000000
4172         .db %01111111
4173         .db %11111000
4174         .db %10000000
4175 spr_boss07:
4176         .db 16,18                       ;.......:.......:
4177         .db %00000000                   ;         █ █
4178         .db %00000111                   ;     ███ ███
4179         .db %00000011                   ;      ████ █
4180         .db %00000001                   ;       ██ ██
4181         .db %00000011                   ;      ███ ██
4182         .db %00000000                   ;        █████
4183         .db %00010111                   ;   █ ██████████
4184         .db %00111111                   ;  ██████ ██ ██
4185         .db %11111000                   ;█████   ██ █ ███
4186         .db %00001111                   ;    █████ ██ █ █
4187         .db %11111000                   ;█████   ██ █ ███
4188         .db %00111111                   ;  ██████ ██ ██
4189         .db %00010111                   ;   █ ██████████
4190         .db %00000000                   ;        █████
4191         .db %00000011                   ;      ███ ██
4192         .db %00000001                   ;       ██ ██
4193         .db %00000011                   ;      ████ █
4194         .db %00000111                   ;     ███ ███
4195         .db 19                          ;         █ █
4196         .db %01010000                   ;modelled after a Nemesis][MSX boss
4197         .db %01110000
4198         .db %11010000
4199         .db %10110000
4200         .db %10110000
4201         .db %11111000
4202         .db %11111110
4203         .db %01101100
4204         .db %11010111
4205         .db %10110101
4206         .db %11010111
4207         .db %01101100
4208         .db %11111110
4209         .db %11111000
4210         .db %10110000
4211         .db %10110000
4212         .db %11010000
4213         .db %01110000
4214         .db %01010000
4215 spr_boss08:
4216         .db 14,14                       ;.......:......7:
4217         .db %01100111                   ; ██  ████  ██
4218         .db %11001011                   ;██  █ ██ █  ██
4219         .db %10110000                   ;█ ██      ██ █
4220         .db %10101111                   ;█ █ ██████ █ █
4221         .db %01010000                   ; █ ██    ██ █
4222         .db %01010011                   ; █ █  ██   █ █
4223         .db %10100111                   ;█ █  ████ ██ █
4224         .db %10100111                   ;█ █  ████ ██ █
4225         .db %01010011                   ; █ █  ██   █ █
4226         .db %01010000                   ; █ ██    ██ █
4227         .db %10101111                   ;█ █ ██████ █ █
4228         .db %10110000                   ;█ ██      ██ █
4229         .db %11001001                   ;██  █ ██ █  ██
4230         .db %01100111                   ; ██  ████  ██
4231         .db 14
4232         .db %10011000
4233         .db %01001100
4234         .db %00110100
4235         .db %11010100
4236         .db %00101000
4237         .db %00010100
4238         .db %10110100
4239         .db %10110100
4240         .db %00010100
4241         .db %00101000
4242         .db %11010100
4243         .db %00110100
4244         .db %01001100
4245         .db %10011000
4246 spr_boss09:
4247         .db 16,19                       ;.......:.......:
4248         .db %01111011                   ; ████ ███
4249         .db %10000110                   ;█    ██ █████
4250         .db %00000011                   ;      ███ █
4251         .db %00111011                   ;  ███ ██   ███
4252         .db %00000111                   ;     ███ ███
4253         .db %00001100                   ;    ██  ███ █
4254         .db %00110111                   ;  ██ █████ █ ██
4255         .db %01111011                   ; ████ ██  █ ██ █
4256         .db %11100100                   ;███  █  ██ ██  █
4257         .db %00000001                   ;    ██████ ██  █
4258         .db %11100100                   ;███  █  ██ ██  █
4259         .db %01111011                   ; ████ ██  █ ██ █
4260         .db %00110111                   ;  ██ █████ █ ██
4261         .db %00001100                   ;    ██  ███ █
4262         .db %00000111                   ;     ███ ██
4263         .db %00111011                   ;  ███ ██   ███
4264         .db %00000011                   ;      ███ █
4265         .db %10000110                   ;█    ██ █████
4266         .db %01111011                   ; ████ ███
4267         .db 19
4268         .db %10000000
4269         .db %11111000
4270         .db %10100000
4271         .db %00011100
4272         .db %01110000
4273         .db %11101000
4274         .db %11010110
4275         .db %00101101
4276         .db %11011001
4277         .db %11011001
4278         .db %11011001
4279         .db %00101101
4280         .db %11010110
4281         .db %11101000
4282         .db %01100000
4283         .db %00011100
4284         .db %10100000
4285         .db %11111000
4286         .db %10000000
4287
4288 ;----------------------------------------------------------------------------
4289 ;----------------------------- logo ------------------------------------------
4290 ;----------------------------------------------------------------------------
4291
4292 logo_nemesis:
4293 .db %11111111,%11111111,%11111111,%11111110,%11111111,%11110111,%11111111,%11111110,%11111111,%111101111,%11111111,%00001011,%11111111,%11111111,%11111111,%11111110
4294 .db %01111111,%11111111,%11111111,%11111110,%11111111,%11110111,%11111111,%11111110,%11111111,%111101111,%11111111,%00011011,%11111111,%11111111,%11111111,%11111100
4295 .db %00111111,%11111111,%11111111,%11111110,%11111111,%11110111,%11111111,%11111110,%11111111,%111101111,%11111111,%00111011,%11111111,%11111111,%11111111,%11111000
4296 .db %00011111,%11111111,%11111111,%11111110,%11111111,%11110111,%11111111,%11111110,%11111111,%111101111,%11111111,%01111011,%11111111,%11111111,%11111111,%11110000
4297 .db %00000000,%00000000,%00000001,%00011110,%00010000,%00000000,%10000001,%00011110,%00010000,%000000001,%00000000,%00001000,%01000000,%00000000,%00000000,%00000000
4298 .db %00000000,%00000000,%00000011,%00011110,%00110000,%00000001,%10000011,%00011110,%00110000,%000000011,%00000000,%00011000,%11000000,%00000000,%00000000,%00000000
4299 .db %00000000,%00000000,%00000111,%00011110,%01110000,%00000011,%10000111,%00011110,%01110000,%000000111,%00000000,%00111001,%11000000,%00000000,%00000000,%00000000
4300 .db %00000000,%00000000,%00001111,%00011110,%11111111,%00000111,%10001111,%00011110,%11111111,%000001111,%11111111,%01111011,%11111111,%11000000,%00000000,%00000000
4301 .db %00000000,%00000000,%00001111,%00011110,%11111111,%00000111,%10001111,%00011110,%11111111,%000001111,%11111111,%01111011,%11111111,%11000000,%00000000,%00000000
4302 .db %00000000,%00000000,%00001111,%00011110,%11111111,%00000111,%10001111,%00011110,%11111111,%000001111,%11111111,%01111011,%11111111,%11000000,%00000000,%00000000
4303 .db %00000000,%00000000,%00001111,%00011110,%11111111,%00000111,%10001111,%00011110,%11111111,%000001111,%11111111,%01111011,%11111111,%11000000,%00000000,%00000000
4304 .db %00000000,%00000000,%00001111,%00011110,%11110000,%00000111,%10001111,%00011110,%11110000,%000000000,%00001111,%01111000,%00000011,%11000000,%00000000,%00000000
4305 .db %00000000,%00000000,%00001111,%00011110,%11110000,%00000111,%10001111,%00011110,%11110000,%000000000,%00001111,%01111000,%00000011,%11000000,%00000000,%00000000
4306 .db %00000000,%00000000,%00001111,%00011110,%11110000,%00000111,%10001111,%00011110,%11110000,%000000000,%00001111,%01111000,%00000011,%11000000,%00000000,%00000000
4307 .db %00000000,%00000000,%00001111,%00011110,%11110000,%00000111,%10001111,%00011110,%11110000,%000000000,%00001111,%01111000,%00000011,%11000000,%00000000,%00000000
4308 .db %00000000,%00000000,%00001111,%00011110,%11111111,%11110111,%10001111,%00011110,%11111111,%111101111,%11111111,%01111011,%11111111,%11000000,%00000111,%11010001
4309 .db %00000000,%00000000,%00001111,%00011110,%11111111,%11110111,%10001111,%00011110,%11111111,%111101111,%11111111,%01111011,%11111111,%11000000,%00000001,%00011011
4310 .db %00000000,%00000000,%00001111,%00011110,%11111111,%11110111,%10001111,%00011110,%11111111,%111101111,%11111111,%01111011,%11111111,%11000000,%00000001,%00010101
4311 .db %00000000,%00000000,%00001111,%00011110,%11111111,%11110111,%10001111,%00011110,%11111111,%111101111,%11111111,%01111011,%11111111,%11000000,%00000001,%00010001
4312
4313 ;----------------------------- end ------------------------------------------
4314
4315         .end
4316 .end
4317
4318
4319 ;----------------------------------------------------------------------------
4320 ;----------------------------------------------------------------------------
4321 ;----------------------------------------------------------------------------
4322
4323 ; 0.98.77 -- 7.VII.00 -- size 6707
4324 ;
4325 ;       # bullets do damage in all levels
4326 ;       * more armor at armor-upgrade and extra armor at end of a level
4327 ;       - internal levels again (no need 4 external, safer/smaller)
4328 ;       # some registers not correctly pushed/popped
4329 ;       * several optimizations (init.procs some bytes smaller)
4330 ;       # enemies hit with hitpoints left disappeared (one pop too much...)
4331 ;       + bullets "charge up" (more damage) when not firing
4332 ;       - removed contrast changes
4333 ;       + more powerful bullets have different sprites (larger=more damage)
4334 ;       # multiples appear at your position (begin level/just selected)
4335 ;       # when invulnerable multiples acted weird
4336 ;       # no more error at activation after APD off after running Nemesis
4337 ;       # saves correctly if own name ain't "nemesis" + some bytes smaller
4338 ;       # screen wasn't always entirely cleared after quit
4339 ;       * waits until all keys have been released after death
4340 ;       + different bullets sizes will miss if they're too small
4341 ;       + at level start "press F1 to save"-text will be displayed
4342 ;       * w3.shiar.org displayed at title screen, black bar behind version nr
4343 ;       # score to 0 when exit pressed at main menu
4344 ;       # no residual story-text in first frame of game
4345 ;       # game doesn't continue again after death (stack messed up)
4346 ;       # game over when lives<0 (didn't work in v0.96+)
4347 ;       * using some self-modifiing code (so it's smaller)
4348 ;       # new random procedure: stars don't appear on one line anymore
4349 ;       * weapons appear centered at multiples
4350 ;       * laser properties can be changed (damage, charge)
4351 ;       + weapon can be combination of bullets/lasers (max. of 3 per weapon)
4352 ;       * bullet-icon is removed when laser is selected
4353 ;       * enemy sprite table integrated in enemy specs (-1 byte/enemy)
4354 ;       + random enemy is chosen from any number of enemies per level
4355 ;       * time to first enemy fire defined per enemy, not per level
4356 ;       + CLIPPED sprites!! no more in/out popping enemies! wow...
4357 ;       * bullets/enemies removed when _entirely_ off screen
4358 ;       # enemies would sometimes be hit by bullets going right below them
4359 ;       # size of the second bullet was too big (invisible hit)
4360 ;       * the frequency an enemy fires bullets is defined per enemy
4361 ;       + wide clipped sprites implemented (width 1-16 pixels)
4362 ;       # bosses first move left until x=100, otherwise they'd be off-screen
4363 ;       * at status bar left below ships are displayed for lives left
4364 ;       * armor bar is two pixels high (better visible)
4365 ;       # bullet overflow fixed again (>63 bullets fired)
4366 ;       # correct weapon loaded when continuing a saved game
4367 ;       # game freezed when generating a random value <=1
4368 ;       * you explode in a different way than the enemies
4369 ;       + screen inverts for a brief time when you are hit!
4370 ;       # stats-bar was messed up when ya got 0 lives left
4371 ;       * two new (big) bosses modeled after a common MSX Nemesis2-boss
4372 ;       * score increased once every 32 frames (instead of every 256)
4373 ;       # ground fixed for new random routine (smaller routine; incs -2 to 2)
4374 ;       + laser will upgrade as well when you reselect it
4375 ;       * 2nd can be used in main menu (wow!)
4376 ;       # altered variable storage space because of Nemesis grew beyond 6kb
4377 ;       # fixed armor bar display when at maximum
4378 ;       + a few new enemies (asteroids) and remade 1st 4 levels; new pickup
4379 ;       - torpedo since it was kinda useless
4380 ;       + second icon now selects TAIL BEAM: bullet going backwards
4381 ;       # armor increase at the end of a level doesn't overflow armorbar
4382 ;       + you can choose your own ship out of four vessel after NEW GAME!
4383 ;       + enemies can appear at any x-position and move both left and right
4384 ;       + move patterns given per enemy, not per level
4385 ;       * new (faster) enemy-move system; 10 basic moves (x2 left+right)
4386 ;       # enemies can _never_ move above or below visible screen
4387 ;       * "randomY"-enemies are placed entirely on screen (height calced)
4388 ;       # the major TI-OS crash bug WAS afterall caused by sprites drawn
4389 ;          (partially) outside screen memory. temporarily fixed by setting
4390 ;          virtual screen buffer to $8200 (enough mem there)
4391 ;       + upto 29 cool enemy sprites and redone first five levels
4392 ;       * improved enemy-move routine; smooth luring, five speeds+backwards
4393 ;       # after pause weapon will not be fired
4394 ;       # teacher key fixed (waits for GRAPH to be release before&after)
4395 ;
4396 ; 0.99.829 -- 29.VIII.00 -- size 6861
4397 ;
4398 ;       + you can have upto FOUR multiples! (~20 pixels apart)
4399 ;       * some optimizations: keycall, menu handling, port nops removed,
4400 ;          more SMC, fire handling, fast bullet handling, enemy movement
4401 ;       * better "backwards" enemies handling (and implemented in game)
4402 ;       # when enemy changed into a pickup, movement is set to vslow
4403 ;       * instead of turning into a pickup, enemies explode and a pickup
4404 ;          appears at the right side of the screen (moves left slowly)
4405 ;       # bullets do damage again (screenflash made damage become 0)
4406 ;       + when destroyed by bullets, the armor bar will show 0HP left
4407 ;       * all enemy bullets do the same damage in all levels
4408 ;       * you now appear at (*32*,30) because enemies can come from left
4409 ;       * improved bullet handling (faster, smaller, etc.)
4410 ;       + multiples are animated like real Nemesis (grow-shrink-grow-shrink>)
4411 ;       # fixed a bug that didn't select multiples when you were moving
4412 ;       # enemy collision screwed up invert and some other weird stuff
4413 ;       + in pause screen change contrast with up/down and B/W mode with F1
4414 ;       + lasers can have different durations (beams last longer)
4415 ;       * some sign-flag checkings replaced by carry-flag (thus reducing size)
4416 ;       # slow enemies (including pickups) didn't always appear (just 25-50%)
4417 ;       + enemies can fire different kinds of bullets: aiming, double, triple
4418 ;       * maximum number of bullets increased (48 for enemies, 128 for you)
4419 ;       * beamweapon can be selected when you got laser (like vice versa)
4420 ;       * selecting laser removes tailbeam or up-double
4421 ;       # tail beam/up-double correctly centered
4422 ;       # disappearing bullets (when enemies fired multiple bullets) fixed
4423 ;       + bullets and lasers both upgradable upto level 9
4424 ;       # fixed end story (_vputs didn't recognize 0-end when "'" in string)
4425 ;       # stars couldn't be altered anymore since recent levelformat changes
4426 ;       * maximum different enemies increased from 28 to 63
4427 ;       * pickup sprite altered, small changes to some enemies
4428 ;       + new moves implemented: 75% speed and lure-while-moving
4429 ;       # fixed the enemy aiming bullets procedure
4430 ;       * enemies fire their bullets centered too! (even the large bosses)
4431 ;       * you may NOT have any multiples together with beams, just lasers
4432 ;       + added new enemy guns: quad- and 6x-fire!!
4433 ;       * sprite table length increased to 768 bytes (stored DIV3)
4434 ;       + ships 3/4 select hardcore mode: score and damage are doubled
4435 ;       + first icon not only increases armor, but also activates shield for
4436 ;          some time (shield halves damage and absorbs bullets in normal mode)
4437 ;       + ship selection screen also shows ship specs (hardcore/tailbeam/etc)
4438 ;       * shield looks different for each ship
4439 ;       * hiscore/savegame procedure optimized (several bytes smaller)
4440 ;       + B<>W mode setting will be stored
4441 ;       * enemy sprite pointers stored as words (thus increasing sprite table
4442 ;          length from 768B to 65kB, and increasing sprite calculation speed)
4443 ;       * hardcore mode does _more_ than doubled damage (bulletsdamage +1)
4444 ;
4445 ;        + added        - removed       * changed       # bug fixed
4446
4447 ;bullet handling: (255/enemy)+419+putsprite cycles per bullet