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