1 ;----------------------------------------------------------------------------
2 ;---------------------- NEMESIS ---------------------------------------------
3 ;----------------------------------------------------------------------------
5 ;by SHIAR | shiar0@hotmail.com | icq#43840958 | www.shiar.org
7 ;Description : cool arcade-shoot-em-up-game
8 ;Other games by author : Worm
9 ;This source should only be used for learning practises, do not
10 ;alter it, and certainly do not distribute an altered version!!
12 ;&&& marks uncertainties or things to optimize
14 ;---------------------- nemesis.z80 start -----------------------------------
17 #include "ti86asm.inc" ;standard ti86 romcalls
18 #include "ti86abs.inc" ;used to save hiscores and so
22 #define cal call ;just to make it harder for you to understand
23 #define psh push ; ^:D
24 #define dnz djnz ;Dec&Jump while NonZero becomes Do w.Non-Zero
26 dispbuffer = $81FA ;= $C9FA ;virtual screen
27 ;VIDEO_MEM = $FC00 ;tha big scareen
28 TEXT_MEM = _textShadow ;text buffer; C0F9-C1A0 (167/$A7 bytes)
30 _clrWindow = $4a86 ;_clrLCD and _clrScrn
31 _ex_ahl_bde = $45f3 ;exchange values between AHL and BDE
32 _shracc = $4383 ;like _shlacc but just the opposite :P
33 _dispahl = $4a33 ;display value in ahl <100000 (cheap TI)
34 _asapvar = $d6fc ;our own variable name (likely "nemesis")
36 storepos = _asm_exec_ram+7000 ;120 OF 165
37 storepos2 = _asm_exec_ram+7200 ;141 OF 167 9000 BYTES
39 ;---------------------- in-game vars ----------------------------------------
41 just_fired = storepos ; +0 ;counts how long a blast lasts
42 menuitem = storepos ; +0 ;used to store menu location
43 hiscorepos = storepos ; +0 ;entering hiscore name
45 x = storepos+1 ; +1 ;your ship's position
46 y = x+1 ; +2 ;your y-pos
47 firex = y+1 ; +3 ;(1 byte)
48 firey = firex+1 ; +4 ;(1 byte)
50 eventleft = storepos+5 ; +5 ;nr. of enemies still to come
51 nextevent = eventleft+1 ; +6 ;time to next event
52 level_enemy = nextevent+1 ; +7 ;enemy type
53 level_info = level_enemy+1 ; +8 ;info (see below)
54 level_move = level_info+1 ; +9 ;=
56 spacespace = storepos+19 ;+19
57 groundinfo = spacespace+1 ;+20
58 groundpos = groundinfo+1 ;+21 $10
59 ceilingpos = groundpos+16 ;+37 $10
61 stars1 = ceilingpos+16 ;+53
62 stars2 = stars1+1 ;+54
64 starx1 = storepos+55 ;+55
66 starx2 = starx1+(nrstars1*2) ;+69
68 your_prevpos = starx2+(nrstars2*2) ;+87 ;save previous positions (32d)
71 ;^-----------------------------------<1 ;-120=$78
73 enemies = storepos2 ; +0 ;info about each enemy
74 enemysize = 9 ;infobytes per enemy
75 nrenemies = 16 ;max. nr of enemies
77 ybullets = enemies+(nrenemies*enemysize) ;60 bytes = 20(state,damg,x,y)
79 ebullets = ybullets+(nrybuls*4) ;+110 ;30 bytes = 10(state,x,y)
81 lvlenemies = ebullets+(nrebuls*3)
83 ;^-----------------------------------<2 ;-141=$8D
85 ; [0000:damage 0:diagfire 0:ground 0:ceiling 0:-]
87 ; [HP64] [000000:HP left 00:(00=no enemy 01=exploding 10=normal 11=moving)]
88 ; [ship type or explosion frame] [x] [y] [movetype] [movecounter] [firecounter] [firefreq]
90 ;---------------------- introduction ----------------------------------------
92 nop ;hello yas/ase/rascall/whathever
93 jp init ;here's the program, but first: a description
94 .dw $0001 ;description type 2 (description + YASicon)
95 .dw Title ;pointer to description (all shells)
96 .dw Icon ;pointer to YAS icon
98 Title: .db "Nemesis v0.98 by SHIAR",0
100 Icon: .db 8,1 ;icon for YAS: width = 1byte; height = 9bytes
103 .db %00111110 ; █████
104 .db %01111001 ; ████ █
105 .db %00111110 ; █████
107 .db %11100000 ; ███ ;recommend 80x50 screen mode
108 .DB 0 ;clear stupid YAS-line
110 ;---------------------- init ------------------------------------------------
112 int_handler: ;new interrupt proc
113 ex af,af' ;just af only (no need for exx)
114 in a,($03) ;read bit 3 port 3
115 bit 3,a ;is ON key pressed?
116 jp z,$0039 ;no: np, return
117 res 0,a ;yes: then we have a problem (freeze), so...
118 out ($03),a ;...mask the ON key interrupts!
119 jp $0039 ;all done, return
122 init: cal BUSY_OFF ;turns the run-indicator off, obviously
123 cal _clrScrn ;clean the screen
125 res 2,(iy+13) ;don't scroll the screen
126 cal _flushallmenus ;remove TI menus
128 FixKeys: ;fixes some key problems like left+down bug
139 ld hl,int_handler ;new interrupt handler
142 ld bc,int_end-int_handler
148 ;---------------------- main menu -------------------------------------------
151 xor a ;white bitmask (a=0)
152 ld hl,logo_nemesis ;from...
153 ld de,VIDEO_MEM+16 ;...to one line from top
154 ld b,e ;ld b,16: one line
156 ld (de),a ;clear/n byte
158 dnz AboveLogo ;repeat for the first line
159 ld bc,16*19 ;logo size
160 ldir ;display one line of logo
162 ld hl,16*$33+VIDEO_MEM ;$33 rows down
163 ld b,16*7 ;draw black 7 lines
164 ld a,%11111111 ;horizontal line mask
166 ld (hl),a ;draw one piece of the divider-line
167 inc hl ;move right (8 pixels = 1 byte)
168 dnz underline ;repeat
170 ld hl,_txt_email ;at the very bottom of tha screen
172 ld hl,txt_email ;hey, my e-mail address so SEND ME SOMETHING!!
173 cal _vputs ;VERY important, so display in small font ?:}
175 set 3,(iy+5) ;set white on black
176 ld de,_txt_about ;near the bottom of the screen
177 ld (_penCol),de ;hl=txt_email++=txt_about
178 cal _vputs ;display version + me
179 res 3,(iy+5) ;return to default black on white
216 cal GET_KEY ;wait for keypress
226 jr z,start_tha_freakin_game
229 start_tha_freakin_game:
233 cal nz,New_game ;NEW GAME
234 jp samelevel ;CONTINUE: game_main_loop
247 do_invert: ;invert screen (b<>w); destr:b
252 xor (hl) ;$2F (cpl) <-> $B7 (or a)
258 ;----------------------------------------------------------------------------
259 ;---------------------- game loop -------------------------------------------
260 ;----------------------------------------------------------------------------
262 game_main_loop: ;REPEATS FROM HERE EVERY FRAME
263 ld hl,timer ;update time
264 inc (hl) ;increase by 1
267 ld hl,1 ;once every 32 frames, increase score by 1
268 cal z,scoreInc ;do it
271 ld hl,dispbuffer ;move from (hl) = top left
272 ld (hl),$00 ;first pixel will be copied all over the screen
273 ld de,dispbuffer+1 ;(de) = next pixel, thus clearing whole screen
274 ld bc,896 ;loop 896 times = (128/8) * (64-8 for scorebar)
277 ld a,0 ;current frame/turn 0-255
279 and %11 ;a=0 once every 4 turns
280 jr z,movestarsdone ;don't move stars once every 4 frames
281 cal movestars1 ;move the stars on the FRONT layer
282 cal movestars2 ;move the distant stars
284 ld a,(stars1) ;star positions (the missing byte...)
285 ld b,nrstars1 ;how many stars? now we know.
286 ld hl,starx1 ;points to the position of the stars
287 cal DisplayStars ;display front layer stars
288 ld a,(stars2) ;weren't you paying attention five lines ago?
289 ld b,nrstars2 ;that many?! whow!
290 ld hl,starx2 ;and there they are
291 cal DisplayStars ;use the same procedure to display back layer
293 ld a,(level_info) ;level info
294 and %00000110 ;isolate ground&ceiling
295 jr z,game_stuff ;both non-present
296 and %00000010 ;bit representing the presence of any ceiling
297 cal nz,Handle_ceiling ;scroll the ceiling (if any) +check4collision
298 cal Handle_ground ;scroll the ground and check if we're dead
301 cal Handle_Ship ;move you
302 ld a,(your_occ) ;are you 100% OK?
304 jr nz,_gamestuff1 ;then don't check for movements/fires/...
307 ld a,%10111111 ;function keys (MORE,EXIT,2ND,F1,F2,F3,F4,F5)
308 out (1),a ;ask for them
309 nop \ nop ;delay 8 clocks
313 bit 6,a ;test bit 6 = exit-key = EXIT
314 jp z,game_over ;<exit> pressed, so be it
315 check_morekey: ;another unused label... poor compiler
316 bit 7,a ;test bit 7 = more-key = PAUSE
317 cal z,Pause ;yes, go to pause
320 bit 5,a ;test bit 5 = 2nd-key = FIRE
321 ld hl,check_selkey ;where to continue after executing Fire_bullet
322 psh hl ;push hl on stack (instead of cal Fire_bullet)
323 jp z,Fire_bullet ;fire smtn (bulletstaillasermultiples+stuff..)
324 pop hl ;no cal to Fire_bullet made, so pop stack
326 ld (just_fired),a ;reset just_fired
329 ld a,%01011111 ;look at first column of keys (ALPHA to STO)
331 nop \ nop ;what's taking you so long
332 in a,(1) ;at last... our precious keyzzz...
334 bit 6,a ;'bout the GRAPH key...
335 cal z,Teacher ;you didn't _press_ it, did you?!?
337 rla ;test bit7 so we know f ALPHA has been pressed
338 cal nc,select ;yeppy, select the currently selected upgrade
340 cal Enemies_hit ;check for collision with enemies
344 cal Handle_enemies ;move enemies
346 cal Handle_bullets ;move your bullets + check for hits
347 cal Enemy_bullets ;move enemy bullets
349 cal Level_event ;insert enemies
350 cal Display_Screen ;display all
356 jp game_main_loop ;LOOP ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
362 cp 97 ;max. 96 times (=96/16=6 increases)
363 ret nc ;return if already maxed
364 ld (weapincs),a ;save new incs
366 and %11110000 ;clear last 4 bits so no cf when rotating
368 rra ;rotate acting as shift (srl a) but just 1B
371 rra ;increase once just every 16 turns
372 ld b,a ;times to increase
374 add a,1 ;increase damage for one increase
376 dnz incthedamage ;a=total increase damage
377 ld b,1 ;minimal damage
379 add a,b ;a=total damage
380 ld (curweapdamage),a ;safe the current damage
384 ;--------------------------- ground -----------------------------------------
388 and %111 ;once every 8 frames
389 jr nz,Display_ground ;otherwise skip the scroll
390 ld bc,15 ;scroll all 16 bytes minus one (teh new byte)
391 ld hl,groundpos+1 ;from..
392 ld de,groundpos ;to (one byte to the left)
393 ldir ;LoaDIncreaseRepeat = scroll!
395 ld a,(groundinfo) ;what kind of ground
397 jr z,ground_tunnel ;tunnel effect
399 ld a,(groundpos) ;type 0
406 ld bc,$500 ;range=0..4
411 add a,(hl) ;add to spacesize (so +2..-2)
413 jr c,newground ;>=0 then don't change
416 add a,b ;new position
418 jr z,newground ;may not be 0 (=256)
420 jr nc,newground ;and not be <0 (>246)
426 ld (groundpos+15),a ;save new byte on the right
429 ld b,16 ;screen width
430 ld de,groundpos-1 ;height of current byte (previous actually)
432 ld hl,dispbuffer+(56*16)-1 ;screen position
436 ld c,b ;push b for groundloopup
437 pop hl \ inc hl ;get screen position and go one right
438 pop de \ inc de ;get height info and set to the next byte
439 psh de \ psh hl ;save these for the next time
440 ld a,(de) ;height of current byte
443 ld de,16 ;to substract to go one line up
444 ld a,%11111111 ;bitmask black
447 ld (hl),a ;display black byte
448 sbc hl,de ;go up (sbc must be used for 16-bit sub)
449 dnz groundloopup ;and loop >groundpos< times
451 ld b,c ;pop b used by groundloopup
452 dnz groundloopright ;loop right for entire screen (16x)
453 pop hl \ pop hl ;restore stack
455 CheckGround: ;check for collision with the ground
473 ;--------------------------- ceiling ----------------------------------------
477 and %111 ;once every 8 frames
478 jr nz,Display_ceiling ;otherwise skip the scroll
479 ld bc,15 ;scroll all 15 bytes (16th is new position)
480 ld hl,ceilingpos+1 ;from..
481 ld de,ceilingpos ;to (one byte to the left)
482 ldir ;LoaDIncreaseRepeat = scroll!
484 ld a,(groundinfo) ;what kind of ceiling
486 jr z,ceiling_tunnel ;tunnel effect
491 ld d,a ;d=new ceiling
494 ld bc,$201 ;range=1..3
497 jr z,newceiling ;1:same
502 or a ;(spacespace)=0:
503 jr z,newceiling+2 ;keep same ceiling
509 cp d ;if size=1 then don't
515 ld (ceilingpos+15),a ;save the new byte
518 ld b,16 ;screen width
519 ld de,ceilingpos-1 ;height of current byte
521 ld hl,dispbuffer-17 ;screen position
525 ld c,b ;push b for groundloopup
526 pop hl \ inc hl ;get screen position and go one right
527 pop de \ inc de ;get height info and set to the next byte
528 psh de \ psh hl ;save these for the next time
529 ld a,(de) ;height of current byte
532 ld de,16 ;to substract to go one line up
533 ld a,%11111111 ;bitmask black
536 ld (hl),a ;display black byte
538 dnz ceilingloopdown ;and loop >groundpos< times
540 ld b,c ;pop b used by groundloopup
541 dnz ceilingloopright ;loop right for entire screen (16x)
542 pop hl \ pop hl ;restore stack
544 CheckCeiling: ;check for collision with the ground
548 srl a ;x/8 (current ceiling-byte)
553 ld de,ceilingpos ;first ceiling-byte
554 add hl,de ;current ceiling-byte
557 cp (hl) ;compare with ceiling
558 ret nc ;carry if ceiling is above you
560 jp damage_you ;otherwise you don't wanna be in that ship
562 ;--------------------------- move stars -------------------------------------
564 DisplayStars: ;inputs: hl=starx# a=stars# b=nrstars#
571 ret ;let's comment this: returns
600 cp 9 ;(GRAPH_MEM&%00001111)-- = $C9FAand15-1 = $A-1
609 ret ;for stupid people, here's another comment...
611 ;--------------------------- pause ------------------------------------------
615 ld hl,$0200 ;top left
617 ld hl,txt_pressenter ;"Enter to continue"
618 cal _puts ;display message
620 cal _getkey ;enter low-power mode and wait for key
621 cp kEnter ;keypressed = enter?
622 jr nz,pause ;no, wait some more
626 ;--------------------------- teacher ----------------------------------------
629 ld (iy+12),5 ;enable flashing cursor
630 cal _clrWindow ;top left
632 cal _puts ;display message
636 cal _getkey ;enter low-power mode and wait for key
637 cp kEnter ;enter pressed?
639 cp kGrMenu ;keypressed = graph?
640 jr nz,teacherloop ;no, wait some more
642 ld (iy+12),0 ;disable cursor
657 ;--------------------------- exit -------------------------------------------
659 quit: im 1 ;release keyfix procedure
660 set 2,(iy+13) ;set back screen scrolling
662 ld (_asapvar+1),a ;next Asm( run will reload the program
663 ld hl,dispbuffer ;graph-screen location
666 ld bc,1024-1 ;do it 1024 times = entire screen
668 jp _clrWindow ;as _clrLCD but also clears TEXT_MEM (like the
669 ;_clrScrn) AND also executes _homeup and ret
671 ;--------------------------- display ----------------------------------------
674 ld hl,dispbuffer ;from buffer (top left)
675 ld de,VIDEO_MEM ;to real screen (top left)
676 ld c,56 ;display height = 64 bytes (minus 8 for bar)
678 ld b,16 ;display width = 16 bytes (16*8bits=256pixels)
680 ld a,(hl) ;copy byte from (hl)
681 _invert: ;SMC: cpl <-> or a
682 cpl ;xor $ff: invert byte (white<=>black)
684 inc hl \ inc de ;next byte
685 dnz displaytloop ;16x hl >> de
687 jr nz,displayloop ;loop 56x
691 or a ;(time2invert)=0:
692 jr z,noinvert ; do nothing
693 dec a ;otherwise decrease
694 cal z,do_invert ;if it became 0 then invert
695 ld (hl),a ;save new value
698 ld hl,$396b ;Display Score
699 ld (_penCol),hl ;bottom right of screen
702 _D_HL_DECI: ;------- display 5-digit value -------
703 ld de,savestr+4 ;savenr saves number string
705 ldhld: cal UNPACK_HL ;one digit of hl
706 add a,'0' ;make number
707 ld (de),a ;save into savenr
708 dec de ;point to next digit
709 dnz ldhld ;repeat for all digits
711 ld hl,savestr ;we (the program) saved the value righthere
712 jp _vputs ;the only thing left to do is to display it
714 savestr: ;@here the score will be stored
715 .db "00000",0 ;don't worry, it's just temporary
717 ;------------------------- handle ship --------------------------------------
724 inc a ;no! next (explosion)frame
725 ld (your_occ),a ;save
727 cp 64+1 ;last explosion frame? (1-16=1st;49-64=4th)
728 jp c,exploding_you ;not yet: display explosion
729 cp 64+16 ;delay finished?
730 jp z,You_die ;yes = game over
731 ret ;don't display anything
735 ld a,%01111110 ;get arrow keys
736 out (1),a ;it's cold outside
737 ld hl,y ;instead of nop\nop do something usefull
738 in a,(1) ;come back in
741 xor -1 ;inverted a: 0 if arrow-key has been pressed
742 ld a,(your_multiples) ;(btw: CPL doesn't set any flags)
743 res 7,a ;reset move bit (no flags changed)
744 jr z,adv_ok ;if so, leave the multiples where they are
745 set 7,a ;set move bit
746 adv_ok: ld (your_multiples),a
748 ld a,(timer) ;framecounter
749 and %1 ;switches 0<>1 each frame
750 inc a ;a = 1 or 2 (1.5 avg)
751 ld c,a ;c = your_speed
754 rra ;rotate right (put last bit in c)
755 ld b,a ;we need a later
760 cp 50 ;56-6 = bottom of screen
765 rr b ;because we now use b, it's rr instead of rra
768 sub c ;<dec a> doesn't affect c-flag
769 jr c,no_left ;-1 = left side
776 cp 122 ;128-6 = right side
785 sub c ;<dec a> doesn't affect carry-flag
786 jr c,no_up ;-1 = top of screen
787 ld (hl),a ;save new y
789 no_up: ld e,(hl) ;e=y
790 ld ix,spr_ship01 ;normal ship sprite
792 ld hl,your_inv ;invulnerable?
793 ld a,(hl) ;load time in a
795 jr z,disp_ship ;yes so ship = normal (display \ continue)
797 ld a,(timer) ;load frame nr.
798 and %00000111 ;a=0 once every four frames
799 jr nz,not_time ;a<>0 = not time to update counter
800 dec (hl) ;decrease inv-time left
802 and %00000100 ;a switches 0<->1 every 2 frames
803 jr z,disp_ship ;show normal ship
805 ld bc,spr_ship01i-spr_ship01
806 add ix,bc ;display invulnerable ship
808 cal safeputsprite ;display your ship; save de
813 ld a,(your_multiples) ;do you have multiples
814 ld b,a ;save a for 2nd check
815 and %111 ;no? (last two bits = nr of multiples)
816 ret z ;then don't handle them either
817 bit 7,b ;move the multiples??? (=move bit set?)
818 jr z,mult_adv ;nope, just let them (saves (y)in y, (x)in x)
820 psh de ;current position = needed later
821 ld hl,mm*14+1+your_prevpos ;previous positions
822 ld de,mm*14+3+your_prevpos ;move all positions one back
824 lddr ;change 0-57 -> 2-59 (if mm=4 that is)
825 inc hl ;your_prevpos+0
828 inc hl ;=current position
832 ld hl,your_prevpos+16 ;first pos.
836 ld d,(hl) ;load coords
839 ld ix,spr_multiple ;sprite
840 cal putsprite ;display
843 add hl,de ;next multiple
846 ret z ;return if all done
847 jr disp_multiples ;loop
852 srl a ;half the framerate
853 srl a ;half that framerate
854 srl a ;and half again that framerate
856 ld ix,spr_yexplosion ;base sprite
858 explosion_stuff: ;in:a=frame*2+(0 to 1); (hl)=xpos-- ix=sprite
864 add ix,bc ;go to correct sprite (each spr. is 8 bytes)
869 jp putsprite ;and display it too
873 damage_you: ;damages you B points
874 ld a,(your_inv) ;shield left?
876 jr z,dothadamage ;no shield
877 srl b ;shield: half the damage
881 cp (hl) ;no already inverted?
882 cal z,do_invert ;then invert screen
884 ld (hl),a ;change back 2 frames from now
886 ld hl,your_armor ;armor left
887 ld a,(hl) ;load hp in A
888 sub b ;decrease hp by B
889 jp m,no_armor ;<0hp left so explode
890 ld (hl),a ;no, so save decreased hp
891 jp disp_armor ;and display new value
893 ld a,%01 ;occ %xxxxxx01 = explode
894 ld (your_occ),a ;too bad, you're dead meat
897 ;------------------------- place multiples ----------------------------------
900 ld hl,your_prevpos ;place all previous positions
901 ld b,mm*7+2 ;all saved positions of them (14 per multiple)
903 ld (hl),e ;set prev-x to d
905 ld (hl),d ;set prev-y to e
907 dnz place_multiples ;repeat
910 ;------------------------- select upgrade -----------------------------------
913 ld a,(your_armor) ;load current armor
914 cp 25-6 ;may not become >=25
915 jr c,doincarmor ;ok then just add 6
916 ld a,24-6 ;set to maximum (6 will be added below)
918 add a,6 ;add 6 to armor
919 ld (your_armor),a ;change armor
923 ld hl,your_pickup ;select pickups
924 ld a,(hl) ;load pickups taken so far
926 ret m ;return if it's 0 (no pickups)
927 jr nz,select2 ;no, carry on
929 ld (hl),a ;reset pickups
931 jp disp_icons ;display and return
934 jr nz,select3 ;no, carry on
935 ld (hl),a ;reset pickups
937 ld (your_tail),a ;ready tail beam
938 jp disp_icons ;display 'n return
941 jr nz,select4 ;no, carry on
942 ld (hl),a ;reset pickups
947 jp nc,disp_icons ;weapon maxed out
948 ld (hl),a ;set new weapon
949 cal loadweapon ;load it (damage and stuff)
950 jp disp_icons ;display n return
953 jr nz,select5 ;no, carry on again
954 ld (hl),a ;reset pickups
957 cp maxweapon ;upgrade from bullet
958 jr nc,upgradelaser ;nope, just upgrade
959 ld a,maxweapon-1 ;yes, set laser #1
963 jp nc,disp_icons ;laser maxed out
966 jp disp_icons ;display + return
969 jr nz,select6 ;no, carry on once more
970 ld (hl),a ;reset pickups
972 ld a,(hl) ;multiples you already got
975 jr nc,enoughmultiples ;maxed out
979 dec a ;if this is your first multiple then...
980 cal z,Place_multiples ;reset multiples positions
981 jp disp_icons ;display, return
983 ld (hl),0 ;reset pickups
984 jp disp_icons ;display/return
986 ;------------------------- fire bullet --------------------------------------
989 ld hl,(your_prevpos+16);then, fire from multiple position
991 dec h ;one up (-2 height: keeps weapons centered)
992 cal fireany ;fire from multiple position
993 pop af ;number of multiples
994 dec a ;one just displayed
995 ret z ;return if none left
996 ld hl,(your_prevpos+30)
1003 ld hl,(your_prevpos+44)
1010 ld hl,(your_prevpos+58)
1020 ld a,(hl) ;just_fired
1021 cp 5 ;already pressed?
1022 ret z ;return when already pressed (=5)
1024 inc (hl) ;otherwise increase counter (0 to 4 >> 1 to 5)
1025 ld a,(your_weapon) ;if you have bullets.....
1027 jr nc,fireOK ;>weapons = laser
1028 ld (hl),5 ;.....then can't fire next turn (go to 5 imm.)
1031 ld a,(your_multiples) ;any multiples?
1032 and %111 ;nr. of multiples
1033 cal nz,fire_multiples ;if >0 then fire them too
1034 ld hl,(x) ;fire from ship position (x)
1036 ld (firex),hl ;set position to fire from
1038 ld ix,weapondata+2-(256*3)
1043 ld b,3 ;go to current weapon (bc=a), b=3 :P
1047 psh bc ;save counter
1048 ld a,(ix) ;load this weapon
1049 cp %11100000 ;%11110000=laser
1050 cal z,fire_laser ;fire laser (will set a=0 when done)
1055 pop bc ;weapon counter (do 3 weapons)
1063 ld a,(ix-2) ;last weapon fired
1064 cp %11100000 ;issit laser
1066 xor %11111 ;smart way of going left instead of right :P
1067 jr fire_ybullet ;fire tail bullet and return
1069 ;-----fire LASER-----
1072 ld b,0 ;overflow counter
1074 ld d,(hl) ;d = your x-pos
1077 ld a,(hl) ;base y-coord (firey)
1078 add a,(ix+1) ;at specified offset (most likely the middle)
1079 ld e,a ;save laser-y in e
1080 psh de ;save unmodified (x,y)
1084 rl b ;b (=0) =b*2+overflow (if y>32 then bc=bc+256)
1085 add a,a ;y*16 (width of screen)
1086 rl b ;b=b*2+overflow (if y>64 then bc=bc+512)
1087 inc a ;8 pixels to right (a=even so no overflow)
1092 add a,d ;a = (Y*16+X/8) mod 256 (c set on overflow)
1094 jr nc,_nolc ;jump if no carry = no overflow = a<=255
1095 inc b ;a>255 so increase bc by 256
1096 _nolc: ld c,a ;c = (Y*16+X/8) mod 256
1097 ld hl,dispbuffer ;save-location
1098 add hl,bc ;bc = Y*16+X/8: hl=screen address
1099 ld a,15 ;128/8=16=screen width ** minus one (inc a ^^)
1100 sub d ;minus x-start (d=X/8)
1104 inc hl ;Go to next byte
1107 pop de ;de=(firex): x-pos unmodified
1109 check_laserhits: ;de = (x,y)
1111 ld b,nrenemies ;check all enemies
1112 ld hl,enemies+1 ;enemy#1+occ/hp00
1113 laserhits: ;hits with normal enemies
1116 and %00000010 ;normal/moving occ.=%1x
1117 jr z,nolashit ;no hit when enemy_occ <> 2/3
1120 or a ;enemy #0 = pickup
1121 jr z,nolashit ;yes: don't destroy
1123 cal find_sprite ;ix=sprite to enemy (hl)
1127 jp m,nolashit ;no hit when enemy is left of you
1131 jr z,enemy_lashit ;a-e=0 = laser on top line of enemy = hit
1132 jr nc,nolashit ;a-e>0 = enemy above laser = no hit
1134 add a,(ix+1) ;add enemy height (according to sprite @ix)
1135 jp m,nolashit ;a-e>0 = hit
1137 ld a,(curweapdamage) ;damage
1138 cal enemy_hit ;hl=enemy+y
1143 add hl,bc ;go to next enemy
1145 dnz laserhits ;check all enemies
1146 xor a ;a=0 otherwise weird things might happen :P
1147 ld (weapincs),a ;reset damage
1151 ;-----fire BULLETs-----
1153 fire_ybullet: ;fire bullet type=C dam=(curweapdamage) at (firex/y)
1154 ld c,a ;save bulletType in c
1155 ld hl,ybullets ;check for unused bullet
1161 jr z,found_ybullet ;0 = no bullet here
1163 dnz find_ybullet ;look next bullet
1164 ret ;none found, return don't fire
1167 ld (hl),c ;use the bullet and set correct bullet-type
1169 ld (hl),1 ;set bullet damage
1171 ld a,(firex) ;your x-pos
1172 add a,5 ;place bullet in front of you
1173 inc hl ;go to bullet-x
1176 ld a,(firey) ;your y-pos
1177 add a,(ix+1) ;place bullet at the middle of your ship
1178 inc hl ;go to bullet-y
1182 ld (weapincs),a ;reset damage
1185 ;------------------------ handle bullets ------------------------------------
1189 and %11111 ;pixels to move
1190 add a,(hl) ;a = X + (hl) to the right
1191 sub 16 ;and 16 to the left (so -16..+15)
1192 jr c,remove_bullet ;remove if x<0
1194 jr nc,remove_bullet ;or x>=128
1195 ld (hl),a ;save new pos.
1200 cal _shracc ;%11110000->1111
1203 jr z,bullet_noymove ;1=straight forward
1205 jr z,bullet_up ;2=up
1207 jr z,bullet_halfup ;3=1/2up
1209 jr z,bullet_down ;4=down
1211 bullet_halfdown: ;5=1/2down
1235 pop hl ;cal bullet_left
1237 ld (hl),0 ;dump this bullet!
1238 jr next_ybullet+1 ;+1:skip pop hl at next_ybullet
1244 psh bc ;bullet counter
1245 psh hl ;save enemy+type
1246 ld (temp1),hl ;needed for check_bullethits
1247 ld a,(hl) ;@bulletType
1252 jp z,next_ybullet ;bulletType=0 >> no bullet
1253 cal bullet_left ;move bullet left
1256 psh de ;save de =position
1259 ld a,(hl) ;bullet damage=size
1260 ld hl,bullettable ;pointer to first bullet
1264 ld e,a ;->16bit (de=a)
1265 add hl,de ;point to correct bullet offset
1266 ld a,(hl) ;load bullet offset
1267 ld e,a ;convert to 16bit (d=0)
1268 ld ix,spr_bullet01 ;first sprite
1269 add ix,de ;add offset (go to correct sprite)
1270 pop de ;saved position
1272 ld a,(ix) ;bullet x-size
1273 ld (bulletxsize),a ;used at check_bullethits
1274 ld a,(ix+1) ;bullet y-size...
1275 ld (bulletysize),a ;...too
1277 cal safeputsprite ;display bullet; DE used for check_bullethits
1279 cal check_bullethits
1282 pop hl ;restore enemy+type
1286 inc hl ;skip type,dam,x,y: next enemy+type
1288 dnz scan_bullets ;next bullet (loop)
1291 ;--------------------------- check bullethits -------------------------------
1293 check_bullethits: ;INPUT: de=X,Y; (temp1)=bullet
1297 hit_enemies: ;Hits with normal enemies
1298 psh bc ;enemy counter
1303 jr z,nohit ;no hit when enemy_occ <> 2/3
1307 or a ;enemy #0 = pickup
1308 jr z,nohit ;yes: don't destroy
1310 cal find_sprite ;set ix to the sprite of this enemy
1314 sub d ;minus bullet x-position
1316 sub 5 ;minus bullet x-size
1320 add a,(ix) ;add enemy width
1325 sub e ;minus bullet y-position
1327 sub 3 ;substract bullet height
1329 jp p,nohit ;nope, missed it
1331 add a,(ix+1) ;add enemy height
1333 jp m,nohit ;missed after all
1335 ;---bullet hits enemy (auch-time!)---
1337 ld hl,0 ;@bulletType
1339 ld (hl),0 ;remove bullet
1341 ld a,(hl) ;set damage
1349 dnz hit_enemies ;check next enemy
1352 enemy_hit: ;*in:a=damage;hl=enemy+y
1353 add a,a ;a=damage to inflict
1354 add a,a ;first 2 bits used for occ.
1360 ld a,(hl) ;load hp00
1361 sub b ;decrease HP (if <0xx then c is set)
1362 ld (hl),a ;save (no flag-changes)
1363 dec hl ;@hp64; no change in c
1364 ld a,(hl) ;load; no c-change
1365 sbc a,0 ;if cf then decrease a
1366 ld (hl),a ;save back the new value
1367 ret nc ;if a>=0 then return, otherwise explode
1369 inc hl ;goto occ again
1370 ld (hl),%01 ;set to explode
1371 ld a,(pickuptimer) ;counts enemies destroyed
1372 dec a ;enough destroyed for a pickup?
1373 jr nz,pickupdone ;otherwise just explode
1374 ld (hl),%110 ;change it into a pickup (with 2 HP)
1375 ld a,18 ;reset enemies counter (18 hits = next)
1377 ld (pickuptimer),a ;save new enemiescounter value
1379 ld (hl),$00 ;explosionFrame 0
1381 ld hl,1 ;increase score by one
1384 ;--------------------------- level events -----------------------------------
1387 ld hl,nextevent ;time to next event <ld a,(nextevent)
1388 dec (hl) ;decrease counter <dec a
1389 ld a,(hl) ;look at counter <ld (nextevent),a
1390 or a ;has it reached zero?
1391 ret nz ;nope: get outta here!
1393 ld bc,0 ;enemy frequency (lvl)
1396 ld (nextevent),a ;set time to next event
1398 dec (hl) ;update enemy-counter
1400 ld a,(hl) ;look at counter
1401 or a ;has it reached 0?
1402 jp z,Next_level ;yes: level finished
1403 dec a ;has it reached 1?
1404 jr z,standby_event ;yes: wait until no enemies present/left
1405 dec a ;has it reached 2?
1406 jr z,place_boss ;yep: place the BigBossTM!
1407 dec a ;has it reached 3?
1408 jr nz,do_event ;nope: >3 = place an enemy
1409 inc hl ;nextevent located behind eventleft
1410 ld (hl),123 ;set delay
1411 ret ;don't place any more enemies
1415 ld hl,enemies+1-enemysize
1420 or a ;0 = no enemy present
1432 ld (nrlvlenemies),a ;just one enemy: the BOSS
1433 ld hl,(levelp) ;the leveldata (including the boss)
1434 dec hl ;points to leveldata\boss\enemynr
1436 ld (lvlenemies),a ;set new enemy (boss)
1439 ld hl,enemies+1-enemysize
1444 cp (hl) ;(hl) = 0 ??
1445 jr nz,chk_noenemy ;jump if enemy present (non-0)
1446 ex de,hl ;de=hl=usable enemy
1448 place_enemy: ;de = enemy+1
1449 ld bc,0 ;0..nrlvlenemies
1450 nrlvlenemies =$-1 ;=nr of enemies minus 1
1451 cal Random ;random enemy b..b+c = 0..nrenemies-1
1455 add hl,bc ;go to a random enemy
1456 ld a,(hl) ;load enemy nr of this mysterious random enemy
1457 cal findenemyspecs ;hl = enemy #a specs
1459 dec de ;goto hp64 (before occ)
1461 ldi ;set hitpoints+occ of enemy class
1462 ld a,(hl) ;save sprite-offset/2 (ldi decs bc so in a)
1467 ld a,(hl) ;load placeInfo
1470 jr z,random_enemy ;yes: create random value <51 in a
1472 jr z,lure_enemy ;yes: create a 100% luring enemy
1474 halflure_enemy: ;yes (of course it is): pick one (50% lure)
1475 ld a,(timer) ;look at frame-number
1476 and %00000001 ;make random if odd frame nr.
1477 jr nz,random_enemy ;1st possibility: random enemy
1478 lure_enemy: ;2nd possibility: luring enemy
1479 ld a,(y) ;place at same y-pos as YOUR ship
1482 ld b,0 ;bc = enemy sprite offset / 2
1483 ld ix,spr_enemy00 ;first enemy sprite
1484 add ix,bc ;add offset for current enemy
1485 add ix,bc ;twice (offset stored as offset/2)
1486 ld a,64-8 ;=57=screen height (8 is scorebar)
1487 sub (ix+1) ;minus sprite height=bottom
1488 ld c,b ;range=0 to...
1490 cal Random ;random value on screen
1491 ypos_OK: ;random value successfully created
1492 ld (de),a ;save y-position
1493 inc de ;@movecounter
1495 ld a,1 ;movecounter = 1
1497 inc de ;@firecounter
1498 ldi ;set time-to-1st-fire
1502 ;--------------------------- enemy fires ------------------------------------
1504 Enemy_fires: ;de = x,y
1514 jr z,found_ebullet ;0 = not used
1515 inc hl \ inc hl \ inc hl
1516 dnz find_ebullet ;look next bullet
1529 ld b,%1011 ;yourY-bulY = negative (=bullet below you)
1532 ld b,%1001 ;yourY-bulY = even more negative (going up)
1537 ld b,%1010 ;bullet going down
1539 jp m,bulletok ;even more going down
1546 ld (hl),a ;set bullet direction
1548 ld (hl),d ;set x-pos
1550 ld (hl),e ;set y-pos
1553 ;----------------------------- enemy bullets --------------------------------
1561 ld a,(hl) ;load bulletType in a
1562 and %1111 ;select direction-bits
1563 jr nz,enemy_bullet ;non-0: handle bullet
1565 pop hl ;do not move the <pop hl>
1567 inc hl \ inc hl \ inc hl
1572 ld b,a ;save type&%1111
1574 ld a,(hl) ;check if it has reached the left side of scrn
1576 jr nz,remove_ebullet ;yes, remove bullet
1577 dec (hl) ;move one left
1578 dec (hl) ;and another one
1582 ld a,b ;restore type
1583 cp %1100 ;is it a normal bullet? (cp = faster than bit)
1584 jr z,ebullet_common ;type %1100: normal bullet
1585 and %111 ;isolate important bits
1586 jr z,ebullet_down ;type %1000: moving down
1588 jr z,ebullet_up ;type %1001: moving up
1597 jr z,ebullet_down ;type %1010: moving down 50%
1598 ;type %1011: moving up 50%
1615 ld ix,spr_bullete1 ;display enemy bullet
1621 jr nz,next_bullet ;0 = you're normal
1641 pop hl ;points to bullettype again
1642 psh hl ;and save it again (ivm call to damage_you)
1643 ld a,(hl) ;load bullettype
1644 cal _shracc ;isolate damage-bits (%1111???? -> %00001111)
1645 ld b,a ;set damage-amount
1646 cal damage_you ;HIT!!
1648 pop hl ;hl could be destroyed by damage_you
1649 ld (hl),0 ;bullet > unused
1650 jr next_bullet+1 ;next bullet (SKIP THE <POP HL> = one byte)
1652 ;--------------------------- handle enemies ---------------------------------
1656 ld b,nrenemies ;handle all enemies
1664 jr z,next_enemy ;occ "no enemy" 0
1666 jr z,exploding_enemy ;occ "exploding" 1
1670 ld c,(hl) ;c = enemy type = de
1684 jr c,enemyonscreenY ;=on screen
1685 cp -20 ;moved off at top
1686 ld e,0 ;reset to top
1687 jr nc,enemyonscreenY
1688 ld e,57 ;otherwise reset to bottom
1690 ld (hl),e ;store new y
1695 jr c,enemyonscreenX ;=on screen
1697 jr c,remove_enemy ;=off screen
1699 ld (hl),d ;store new x
1700 ld a,c ;a = enemy type
1701 or a ;type 0? (pickup)
1702 jr nz,check_enemyfire ;no, a normal enemy; let em fire
1703 ld a,(timer) ;load time
1704 and %1 ;move left once every 2 turns
1705 jr z,firing_done ;don't move now
1706 inc d ;increase x-position (don't move this turn)
1707 inc (hl) ;and save it
1708 jr firing_done ;continue
1715 dec (hl) ;decrease counter till next blast
1716 ld a,(hl) ;&&&doesn't seem efficient to me
1717 or a ;has it reached zero?
1718 jr nz,firing_done ;finished if not
1723 ld (hl),a ;reset counter for next blast
1724 psh de ;save registers for firing-use
1725 cal Enemy_fires ;fires bullet
1726 pop de ;restore (destroyed by Enemy_fires)
1728 cal putwidesprite ;display sprite @ix
1740 ld (hl),$0000 ;bye bye enemy
1741 jr next_enemy+1 ;continue AFTER pop hl (already done)
1747 jr z,remove_enemy ;remove when at last frame
1749 ld (hl),a ;next frame
1751 ld ix,spr_explosion ;base sprite
1752 cal explosion_stuff ;display explosion
1755 ;--------------------------- moving enemies ---------------------------------
1758 ld a,(hl) ;how does this enemy move?
1759 bit 7,a ;direction indicator
1767 res 7,a ;01111111=movetype:
1769 ret z ;0 = don't move
1771 jr z,movetype_updown ;1 = 0 >< up / down
1773 jr z,movetype_vslow ;2 = .75 >>
1775 jr z,movetype_slow ;3 = .5 >>
1777 jr z,movetype_fast ;4 = .5 <<
1779 jr z,movetype_vfast ;5 = 1 <<
1781 jr z,movetype_smart ;6
1783 jr z,movetype_lure ;7 = 1 >> move y towards you
1785 jr z,movetype_slowlure ;8 = 1 >> lure 1/2 speed
1787 ; jr z,movetype_stoplure ;9 = 1 >> slowlure; stop at x=99
1789 ; jr z,movetype_fulllure ;10 = x+y towards you 1/2 speed
1798 ret c ;move left (already did)
1800 inc d ;already moved left, so move right
1807 and 1 ;half the time
1808 jr z,moverightonce ;dont move at all (compensate move left +ret)
1812 jr c,dothelurethingy
1813 inc d ;x<106: full stop
1817 ret z ;don't move if equal
1818 jr c,lure_up ;below you then move up
1819 lure_down: ;above then move down
1827 inc hl ;hl =@ <move>
1836 or a ;reset carry flag
1837 dec hl ;reset hl to <y>
1859 pop hl ;restore stack (no ret used)
1860 jp remove_enemy ;remove this enemy (off screen)
1871 or a ;reset carry flag
1874 ld a,(hl);&&&ld a,e ;load current y-position
1877 moveup: dec a ;decrease y-pos (=move up)
1878 ret m ;don't move off the screen (y<0)
1879 dec e ;save new y-pos
1882 inc a ;increase y-pos
1883 cp 55 ;compare with bottom
1884 ret nc ;return if it has passed that line (>40)
1885 inc e ;otherwise save new position
1888 ;--------------------------- check collision --------------------------------
1891 ld hl,(x) ;e = X, d = Y
1892 ld de,$0707 ;add 7 to both d and e
1895 ld e,l ;e = X+7, d = Y+7
1898 ld b,nrenemies ;check all 20 enemies
1903 jr z,check_next ;2 or 3 = ok
1906 collide_enemy: ;&&& include in Handle_enemy proc
1910 ld a,(hl) ;check x match
1911 sub e ;enemy position minus yours minus 7
1914 add a,(ix) ;enemy width
1918 ld a,(hl) ;check y match
1919 sub d ;same as with x-check
1922 add a,(ix+1) ;enemy height
1929 ld hl,2 ;increase score by 2
1933 ld a,(hl) ;load enemy type
1935 jr nz,collide ;enemy when <>0
1938 ld hl,your_pickup ;your pickups
1943 ld a,1 ;yes: reset to pickup 1
1946 cal disp_icons ;display altered pickupicons
1949 dec hl ;to enemy occ
1950 xor a ;set to 0 = gone
1952 jr check_next ;all done, next..
1955 ld (hl),%01 ;set to explode
1957 ld (hl),0 ;explosionFrame 0
1969 ld b,collidedamage ;damage
1981 ;--------------------------- story ------------------------------------------
2001 ld hl,VIDEO_MEM ;copy text
2002 ld de,dispbuffer ;to GRAPH_MEM
2003 ld bc,1024 ;entire screen
2019 cal storyPage ;do some story
2020 inc hl ;look at next hl
2021 ld a,(hl) ;load in a
2023 inc a ;set z-flag if a = $ff
2024 jr nz,dostory ;otherwise loop
2026 ld bc,2+1 ;story ends
2027 add hl,bc ;set hl to beginning of the level
2028 ld (levelp),hl ;set the level-pointer
2031 ;--------------------------- SFX --------------------------------------------
2033 DoSFX: ;in:a=beginLine;b=nrOfLines
2038 ld a,0 ;get line number
2040 inc a ;go to the next line
2041 ld (curline),a ;update
2048 add hl,hl ;*16 (a pixels down=a*16)
2050 ld b,h ;save hl for later
2053 ld de,VIDEO_MEM ;where to put sfx
2054 add hl,de ;go to ymin
2055 ex de,hl ;put into de again
2061 neg ;a=64-a (lines from bottom)
2063 ; ld c,a ;c=a=(curline)
2065 ; sub c ;lines from bottom
2067 SFXdisp: ;display this frame on screen
2068 ld bc,16 ;one line (=16 bytes, you'd know by now)
2069 ldir ;display (copy actually)
2070 ld bc,-16 ;go up one line (not on screen)
2071 add hl,bc ;so the same line will be displayed
2073 jr nz,SFXdisp ;repeat until whole screen is displayed
2084 ;--------------------------- show icon --------------------------------------
2087 ld (hl),a ;draw one piece of the divider-line
2088 inc hl ;move right (8 pixels = 1 byte)
2089 dnz drawline ;repeat (16bytes * 8pixels =128= screen width)
2093 psh bc \ psh de \ psh hl \ psh ix ;&&&
2095 ld hl,VIDEO_MEM+(16*56);56 rows down = eight rows from bottom
2096 ld (PutWhere),hl ;place icons at bottom of normal screen
2097 ld b,16 ;draw 16x (screen width)
2098 ld a,%11111111 ;horizontal line mask
2099 cal drawline ;draw divider-line
2101 ld b,16*7 ;draw 16x (screen width) 7x (height)
2102 xor a ;blank line mask
2103 cal drawline ;clear scorebar
2107 ld a,(your_lives) ;nr of lives
2109 jr z,displivesdone ;no lives
2114 cal safeputsprite ;put li'l ship
2119 dnz displivesloop ;one ship per life
2122 ld ix,spr_icon01 ;armorIcon
2123 ld de,$1901 ;icon #1
2124 cal putwidesprite ;display icon
2125 cal disp_armor ;display bar
2128 ld a,(your_weapon) ;ur weapon
2129 cp maxweapon ;laser?
2130 psh af ;(your_weapon)
2131 jr nc,no_tail ;if laser (nc) then tail ain't fired
2135 ld ix,spr_icon02 ;tailbeamIcon
2137 ld de,$2901 ;icon #2
2138 cal putwidesprite ;display
2141 pop af ;a=(your_weapon); cf=bullets
2143 jr nc,no_bullets ;=laser
2144 ld hl,$3945 ;position to display bullet-type digit
2145 pop af ;digit=(your_weapon)
2147 inc a ;1 = weapon #1 (=0)
2148 ld (_penCol),hl ;set location
2149 add a,'0' ;make digit
2150 cal _vputmap ;display char
2151 ld ix,spr_icon03 ;bulletIcon
2153 ld de,$3901 ;icon #3
2154 cal putwidesprite ;display icon
2156 ld ix,spr_icon00 ;emptyIcon
2157 pop af ;ld a,(your_weapon)
2159 jr c,no_laser ;popped carry
2160 ld hl,$3955 ;position to display bullet-type digit
2161 ld (_penCol),hl ;set location
2162 ld a,b ;(your_weapon) ;load = faster than push
2163 sub maxweapon-1 ;1 = laser #1 (=maxweapon)
2164 add a,'0' ;make digit
2165 cal _vputmap ;display char
2166 ld ix,spr_icon04 ;laserIcon
2168 ld de,$4901 ;icon #4
2171 ld ix,spr_icon00 ;emptyIcon
2172 ld a,(your_multiples)
2177 ld de,$5901 ;icon #5
2180 ld ix,spr_dividerline
2184 ld a,(your_pickup) ;pickups taken
2185 add a,a ;picks*2 (sets z-flag)
2186 jr z,iconsdone ;return if no pickups
2191 ld d,a ;y-pos = picks * $10 + $0a (19,29,39,49,59)
2192 ld e,$01 ;x-pos = bottom (1a01,2a01,3a01,4a01,5a01)
2197 ld hl,dispbuffer ;normal game-screen
2198 ld (PutWhere),hl ;set sprite-position to normal screen
2200 pop ix \ pop hl \ pop de \ pop bc
2205 ld hl,(57*16)+VIDEO_MEM+3
2215 ld a,(your_armor) ;load your armor (<25)
2219 srl a ;/8: don't display last 3 bits of a (later)
2220 jr z,noarmorbar ;if a=0 then it would loop 256x so skip it
2221 ld b,a ;loop b=a times
2222 armorbar: ;starting at ($39*16)+VIDEO_MEM
2223 ld (hl),%11111111 ;draw a piece of the bar
2224 add hl,de ;one down (resets carry)
2225 ld (hl),%11111111 ;same piece
2227 inc hl ;next position
2228 dnz armorbar ;loop it b times
2232 and %111 ;display last bits of armor
2233 ret z ;if armor=0 then bit = %00000000 (don't disp)
2235 xor a ;bit = %00000000
2238 rra ;rotates A right and sets bit 7 (c-flag)
2239 dnz armorbarbit ;repeat B times (so if B=6 then a=%11111100)
2240 armorbarready: ; (an if B=3 then a=%11100000)
2241 ld (hl),a ;draw this last byte
2243 ld (hl),a ;and just below
2247 ld hl,(59*16)+VIDEO_MEM+3
2254 ld a,(weapincs) ;load bar size (0-80)
2255 srl a ;half the size (0-40)
2256 srl a ;again half that size (0-20 pixels)
2260 srl a ;/8: don't display last 3 bits of a (later)
2261 jr z,nochargebar ;if a=0 then it would loop 256x so skip it
2262 ld b,a ;loop b=a times
2263 chargebar: ;starting at ($39*16)+VIDEO_MEM
2264 ld (hl),%11111111 ;draw a piece of the bar
2265 inc hl ;next position
2266 dnz chargebar ;loop it b times
2269 and %111 ;display last bits of chargebar
2270 ret z ;if armor=0 then bit = %00000000 (don't disp)
2272 xor a ;bit = %00000000
2275 rra ;rotates A right and sets bit 7 (c-flag)
2276 dnz chargebarbit ;repeat B times (so if B=6 then a=%11111100)
2277 chargebarready: ; (an if B=3 then a=%11100000)
2278 ld (hl),a ;draw this last byte
2281 ;--------------------------- proc -------------------------------------------
2283 Random: ;a=c<random<b+c; destr:none
2285 ld hl,rancount ;amount to increase with (0-255)
2287 inc (hl) ;change for next time
2288 ld a,r ;value $0-7F (can be _anything_ so watch out!)
2289 add a,0 ;add to last random value
2290 ranseed =$-1 ;SMC :P
2291 add a,(hl) ;add the changing increase value
2292 ;(this is because R can be anything;
2293 ; ie always be even so freeze when a must be 1<=a<=1)
2294 ld (ranseed),a ;save for next time
2296 jr nc,randomloop ;then add again
2302 RandomY: ;HL = random Y 0..50 right side ((1..51)*16-1)
2304 ld bc,50*256+1 ;range=1..51
2305 cal Random ;a = 1..51
2311 add hl,hl ;hl = 1..51 * 16 (left side at random y)
2312 dec hl ;hl = 0..50 * 16 (" at right side of screen)
2314 add hl,de ;position on screen
2326 find_sprite: ;in:hl=enemy+type | out:ix=sprite to enemy
2329 ld e,(hl) ;e = enemy offset/2
2331 ld ix,spr_enemy00 ;first enemy sprite
2332 add ix,de ;add offset for current enemy
2333 add ix,de ;twice (offset stored as offset/2)
2339 ld hl,VIDEO_MEM ;screen location (top left)
2342 ld bc,1024-1 ;do it 1024 times = entire screen
2344 set 3,(iy+5) ;set white on black
2349 ld a,%10000000 ;all key-masks
2352 inc a ;cp %11111111 (no keys pressed)
2353 jr nz,releasekeys ;keep waitin
2354 cal GET_KEY ;clear buffer
2357 findenemyspecs: ;enemy #a specs in (hl); in:b=0; out:ac=?
2358 ld hl,enemyspecs-8 ;enemy "0" specs (1 before enemy #1)
2362 ld c,a ;b=0; c=bc=type*8
2363 add hl,bc ;hl = enemy specs
2366 ;--------------------------- game over / new game / death -------------------
2368 .db 0,".<>!",0,0,0,0 ;down,L,R,up
2369 .db 0,"xtoje0",0 ;enter..clear
2370 .db " wsnid9",0 ;(-)..custom
2371 .db "zvrmhc8",0 ;dot..del
2372 .db "yuqlgb7#" ;0..xvar
2373 .db $D9,"-pkfa6'" ;on..alpha
2374 .db "54321*",0,$D0 ;F5..more
2377 ld hl,_asapvar ;find own variable
2378 rst 20h ;cal _ABS_MOV10TOOP1
2379 rst 10h ;cal _FINDSYM
2382 ld hl,4+storehi_start-_asm_exec_ram
2383 add hl,de ;hl=pointer to data in original prog
2385 cal _SET_ABS_DEST_ADDR
2388 cal _SET_ABS_SRC_ADDR
2389 ld hl,storehi_end-storehi_start
2390 cal _SET_MM_NUM_BYTES
2391 cal _mm_ldir ;save done (cal \ ret)
2395 ld hl,_asapvar ;find own variable
2396 rst 20h ;cal _ABS_MOV10TOOP1
2397 rst 10h ;cal _FINDSYM
2400 ld hl,4+storesave_start-_asm_exec_ram
2401 add hl,de ;hl=pointer to data in original prog
2403 cal _SET_ABS_DEST_ADDR
2405 ld hl,storesave_start
2406 cal _SET_ABS_SRC_ADDR
2407 ld hl,storesave_end-storesave_start
2408 cal _SET_MM_NUM_BYTES
2409 cal _mm_ldir ;save done (cal \ ret)
2412 game_over: ;stack=+0
2413 cal BLACKLCD ;clear screen
2415 ld (_curRow),hl ;center
2417 cal _puts ;display "GAME OVER"
2418 cal releasekeys ;wait for all keys to be released
2499 xor a ;clear a (Ahl will be displayed)
2500 ld hl,$1006 ;bottom-1 right
2501 ld (_curRow),hl ;set
2502 ld hl,(your_score) ;your score
2503 cal _dispahl ;display it (a=0)
2505 ld hl,$314b ;bottom-1 right before score ^^
2506 ld (_penCol),hl ;set
2507 ld hl,txt_score ;"Score"
2508 cal _vputs ;display (small)
2510 ld hl,$1007 ;bottom right
2511 ld (_curRow),hl ;set
2512 ld hl,(hiscore) ;hi-score
2513 cal _dispahl ;display
2514 ld hl,$3946 ;bottom right before hiscore ^^
2515 ld (_penCol),hl ;set
2516 ld hl,txt_hiscore ;"Hiscore"
2517 cal _vputs ;display (small)
2522 ld hl,VIDEO_MEM+(49*16)-1
2528 cal _getkey ;wait for keypress
2529 jp quit ;restore some things and return to TI-OS/shell
2531 invship: ;procedure used in New_game
2535 ld hl,VIDEO_MEM+$30-$C0;begin pos
2539 ld b,$B0 ;12 lines down
2545 dnz invshiploop ;loop
2549 New_game: ;stack must be +1 (so change the jp in cal :)
2552 ld (PutWhere),hl ;will be reset after displaying iconbar
2553 ld ix,spr_ship01 ;first ship: sprite
2554 ld de,$0105 ;position
2555 ld b,4 ;number of ships to display
2559 cal putwidesprite ;display
2561 ld bc,spr_ship01i-spr_ship01+2
2562 add ix,bc ;go to next ship
2563 ld a,12 ;below the previous one
2567 dnz dispshipsloop ;loop
2583 jr z,startthenewgame
2585 jr z,startthenewgame
2600 ld hl,spr_ship01-(spr_ship02-spr_ship01)
2601 ld de,spr_ship02-spr_ship01
2602 inc b ;your ship #0-3++
2604 add hl,de ;next ship
2608 ld (your_score),a ;reset score
2609 ld (your_score+1),a ;reset score (0)
2610 ld (your_tail),a ;no tail beam
2611 ld (your_weapon),a ;no laser
2612 ld (your_pickup),a ;reset pickups
2613 ld (your_multiples),a ;no multiples
2615 ld (level),a ;reset level nr (#1)
2616 ld hl,level00 ;set level pointer to level#1
2617 ld (levelp),hl ;reset level pointer
2619 ld (your_lives),a ;3 lives (4 will be decreased @ You_die)
2620 ld (pickuptimer),a ;next pickup after 4 enemies destroyed
2622 You_die: ;stack must be +1
2623 pop hl ;restore stack
2625 ld (your_armor),a ;12 HPs/shields
2626 ld a,(your_lives) ;load lives left
2627 dec a ;decrease lives
2628 ld (your_lives),a ;if lives=0ffh GO
2629 inc a ;if -1 then zf set now
2630 jp z,game_over ;and game's over
2633 ;--------------------------- next level -------------------------------------
2635 Next_level: ;stack must be +1
2638 cal inc_armor ;increase armor
2639 ld hl,level ;level number
2646 ld h,0 ;increase score....
2647 ld l,a ;by level number * 4
2650 cal scoreInc ;update score
2652 ld hl,(levelp) ;level pointer
2653 ld b,0 ;advance one level
2655 add hl,bc ;passed the enemies
2657 add hl,bc ;update to point to next level
2658 ld (levelp),hl ;save
2662 ld (your_shipspr),hl
2665 ld (nextevent),a ;time to first enemy appearance
2667 ld hl,(levelp) ;level pointer
2672 ld a,(hl) ;number of (different) enemies in this level
2675 ld (nrlvlenemies),a ;set nr of enemies-1
2676 ld b,0 ;bc=c so we can use ldir
2677 ld de,lvlenemies ;table of enemies
2678 ldir ;load enemies to table
2679 ld a,(hl) ;load new appearance-time
2683 ld (eventtime+1),a ;set
2685 ld a,(hl) ;load nr of enemies in this level
2686 ld (eventleft),a ;set nr of events left
2691 ld a,(hl) ;movement of enemies in this level
2692 ld (level_move),a ;do it
2707 ld (timer),a ;reset time
2708 ld hl,your_occ ;hl = your_occ
2709 ld (hl),a ;reset your ship (not exploding)
2710 inc hl ;hl = your_inv
2711 ld (hl),25 ;set 25*4=100 frames invulnerable
2713 ld (x),de ;begin position (x,y)
2714 cal Place_multiples ;place all multiple-positions at that (0,24)
2716 cal loadweapon ;load (your_weapon)
2718 ld hl,enemies ;remove all enemies and bullets
2719 ld (hl),0 ;clear first byte
2720 ld de,enemies+1 ;copy this to the next byte
2721 ld bc,(nrenemies*enemysize)+(nrybuls*4)+(nrebuls*3)-1
2722 ldir ;clear enemies + bullets (y/e)
2724 ;--------------------------- setup game -------------------------------------
2727 cal BLACKLCD ;white on black
2730 ld (_curRow),de ;center
2731 cal _puts ;display "LEVEL "
2733 ld a,(level) ;current level
2736 cal UNPACK_HL ;create first digit
2739 cal UNPACK_HL ;second digit
2741 cal _putc ;display second digit
2743 cal _putmap ;display first digit
2745 ld hl,txt_lives ;bar text: "Lx0"...
2747 ld (_curRow),de ;display lives left below level nr
2749 ld a,(your_lives) ;lives left
2750 add a,'0' ;make value 0='0'
2753 cal releasekeys ;wait for user to release all keys
2754 ld hl,txt_savekey ;"Press [F1] to save"
2755 ld de,$3A46 ;bottom-right
2759 res 3,(iy+5) ;set white on black
2760 cal _getkey ;wait for keypress
2764 cal _clrLCD ;clear screen
2765 cal disp_icons ;display bottom icons +ret
2769 cal RandomY ;a = random y-pos 1..bottom
2770 ld a,b ;a = b = star nr. = 1..7
2771 add a,a ;a = 2b = 2..14
2773 ld e,a ;de = a = 2-14
2775 sbc hl,de ;substract from random y => random pos anywhere
2777 ld (ix),l ;save x-pos (l)
2778 ld (ix+1),h ;save y-pos (h)
2779 inc ix \ inc ix ;next star
2780 dnz placestars ;repeat for all stars
2793 ld (weapdamage),a ;damage of bullets
2796 ld (weapdaminc),a ;damage increase
2799 ;----------------------------------------------------------------------------
2800 ;--------------------------- putsprite --------------------------------------
2801 ;----------------------------------------------------------------------------
2802 ;in: de=(x,y); ix=sprite
2803 ;out: ix=behind sprite; hl:a=right below sprite; b=0; d=width; ce=?
2806 ld c,(ix) ;save width
2807 _putsprite: ;putsprite with custom width
2809 bit 7,d ;check sign bit of X
2810 jr z,CSpositive ;X>=0
2813 cp (ix) ;off screen?
2814 ret nc ;X<=-width: don't draw at all
2815 ld b,a ;b=|X|mod 8=1..7=bits to draw
2816 ld a,%11111111 ;all bits set (draw everything)
2818 srl a ;remove first bit in a for each b
2819 dnz CSclipleft ;b=1: a=%01111111
2826 res 7,d ;X+128 (right side of screen)
2828 jr CSdisplay ;done clipping
2831 sub 129-8 ;minus (screen width - byte width)
2833 ld a,%11111111 ;clipmask
2834 jr c,CSdisplay ;x+width<128 then entire sprite is on screen
2835 inc b ;b = number of pixels off screen
2837 add a,a ;remove last bit in a for each b
2838 dnz CSclipright ;b=1: a=%11111110
2845 ;b>7: a=%00000000 = off screen
2847 CSdisplay: ;display the sprite ix at (d,e) masked
2848 ld (CSclipmask),a ;set mask
2849 cal findpixel ;convert de to screen location hl:a
2855 psh bc ;save rows to go
2858 ld a,(ix+2) ;load image line
2864 ld a,1 ;saved bitmask
2866 sla c ;test leftmost pixel
2867 jr nc,CSnodraw ;don't draw if it's 0
2868 ld e,a ;psh af: save bitmask
2870 ld (hl),a ;OR pixel with screen
2874 jr nc,CSbitdrawn ;carry set if bit "jumped"
2878 pop hl ;screen at x-offset=0
2880 add hl,bc ;next line
2881 pop bc ;rows counter
2885 ;--------------------------- putbigsprite -----------------------------------
2888 ;destr: abcdehl+ix (ix=behind sprite; hl:a=right below sprite; b=0; d=width)
2891 jr c,putsprite ;width<=8: just draw the sprite
2898 cal _putsprite ;otherwise draw one column (8 pixels wide)
2900 inc ix ;no x-size to load
2902 add a,d ;8 pixels right
2904 pop bc ;then draw the remaining pixels (c=width-8)
2908 safeputsprite: ;cal putsprite with de intact
2914 ;------------------------------- findpixel ----------------------------------
2915 ;based upon CLEM's fp | 131 cycles | 28 bytes | in:(d,e); out:hla; destr:de
2920 add a,a ;add a,a is 7 cycles faster than add hl,hl
2921 ld h,0 ;switch to hl now (Y<64)
2924 rra ;RRA: carry flag must be reset!
2925 add hl,hl ;that's what the adds are for :P
2941 ld de,dispbuffer ;screen base position (where x+y=0)
2946 ;----------------------------------------------------------------------------
2947 ;------------------------------- sprites ------------------------------------
2948 ;----------------------------------------------------------------------------
2951 .db 7,7 ;ship alpha class
2954 .db %01111110 ; ██████
2955 .db %11101000 ;███ █
2956 .db %01111110 ; ██████
2962 .db %11110001 ;████ █
2963 .db %01111111 ; ███████
2964 .db %11101001 ;███ █ █
2965 .db %01111111 ; ███████
2966 .db %11110001 ;████ █
2970 .db 7,7 ;ship beta class
2972 .db %11111000 ;█████
2973 .db %01111100 ; █████
2974 .db %01110010 ; ███ █
2975 .db %01111100 ; █████
2976 .db %11111000 ;█████
2980 .db %11100010 ;███ █
2981 .db %11111001 ;█████ █
2982 .db %01111101 ; █████ █
2983 .db %01110011 ; ███ ██
2984 .db %01111101 ; █████ █
2985 .db %11111001 ;█████ █
2986 .db %11100010 ;███ █
2989 .db 7,7 ;ship gamma class
2990 .db %11111000 ;█████
2992 .db %11111100 ;██████
2993 .db %11100110 ;███ ██
2994 .db %11111100 ;██████
2996 .db %11111000 ;█████
2999 .db %11111010 ;█████ █
3000 .db %01100001 ; ██ █
3001 .db %11111101 ;██████ █
3002 .db %11100111 ;███ ███
3003 .db %11111101 ;██████ █
3004 .db %01100001 ; ██ █
3005 .db %11111010 ;█████ █
3008 .db 7,7 ;ship delta class
3010 .db %11110000 ; ████
3011 .db %11111100 ; ██████
3012 .db %01100010 ; ██ █
3013 .db %11111100 ; ██████
3014 .db %11110000 ; ████
3018 .db %11000010 ; ██ █
3019 .db %11110001 ; ████ █
3020 .db %11111101 ; ██████ █
3021 .db %01100011 ; ██ ██
3022 .db %11111101 ; ██████ █
3023 .db %11110001 ; ████ █
3024 .db %11000010 ; ██ █
3028 .db %01111000 ; ████
3029 .db %11001100 ; ██ ██
3031 .db %11001100 ; ██ ██
3032 .db %01111000 ; ████
3034 ;-------------------------------- explosions --------------------------------
3040 .db %00111110 ; █████
3041 .db %01010110 ; █ █ ██
3047 .db %01001110 ; █ ▒███
3048 .db %10111110 ; █ █████
3049 .db %01001111 ; █ ▒████
3051 .db %00011010 ; ██ █
3054 .db %10110000 ; █ ██
3055 .db %01001110 ; █ ███
3056 .db %10110101 ; █ ██▒█▒█
3057 .db %01000101 ; █ ▒█▒█
3058 .db %00111110 ; █████
3059 .db %01011010 ; █ ██ █
3062 .db %00101010 ; ▒ █▒█ █
3063 .db %01000110 ; █ ▒██
3064 .db %10110101 ; █ ██ █ █
3065 .db %01100110 ; ██ ██▒
3066 .db %00111100 ; ████▒
3067 .db %01011001 ; █ ██ ▒█
3070 .db %01000000 ; █▒ ▒ ▒
3071 .db %00100101 ; ▒█ █▒█
3072 .db %00010100 ; ▒ ▒█ █ ▒
3073 .db %01000100 ; █▒ █
3074 .db %00010010 ; ▒█▒▒█
3075 .db %10011010 ; █▒ ██ █▒
3079 .db %00100000 ; ▒█ ▒ ▒
3080 .db %00000001 ; ▒ ▒ █
3082 .db %00100010 ; █▒ █
3083 .db %01001000 ; ▒█ ▒█ ▒
3086 .db %00001000 ; ▒ █▒
3087 .db %11000010 ; ██ ▒ █
3089 .db %00100000 ; ▒█ ▒
3090 .db %00000001 ; ▒ ▒█
3091 .db %00110000 ; ▒██▒
3095 .db %00000000 ; ▒▒ ▒
3099 .db %00100100 ; █▒ █
3104 .db %00101100 ; █ ██
3105 .db %00011110 ; ████
3106 .db %00110100 ; ██ █
3112 .db %01011100 ; █ ███
3113 .db %10010111 ;█ █ ███
3114 .db %01000110 ; █ ██
3119 .db %00111100 ; ████
3120 .db %01001111 ; █ ████
3121 .db %10100011 ;█ █ ██
3122 .db %11000110 ;██ ██
3123 .db %01110101 ; ███ █ █
3127 .db %00110110 ; ██ ██
3130 .db %01100001 ; ██ █
3132 .db %01010001 ; █ █ █
3134 ;--------------------------------- bullets ----------------------------------
3141 .db %11110000 ;▒████
3153 .db %11110000 ;▒████
3158 .db %11111000 ;▒█████
3162 .db %01110000 ; ▒███
3163 .db %11111000 ;▒█████
3164 .db %01110000 ; ▒███
3167 .db %11110000 ;▒████
3168 .db %11111000 ;▒█████
3169 .db %11110000 ;▒████
3173 .db %10111000 ;▒█▒███
3174 .db %01111000 ; ▒████
3178 .db %00111000 ; ▒███
3179 .db %01111100 ; ▒█████
3180 .db %11111100 ;▒██████
3185 .db %11111100 ;▒██████
3186 .db %00111110 ; ▒█████
3187 .db %01111100 ; ▒█████
3192 .db %11111100 ;▒██████
3193 .db %00111110 ; ▒█████
3194 .db %01111110 ; ▒██████
3195 .db %11111100 ;▒██████
3196 .db %00111000 ; ▒███
3199 .db %00111100 ; ▒████
3200 .db %11111110 ;▒███████
3201 .db %01111111 ; ▒███████
3202 .db %00011111 ; ▒█████
3203 .db %01111111 ; ▒███████
3204 .db %11111110 ;▒███████
3205 .db %00111100 ; ▒████
3209 .db %11110000 ; ████
3213 .db 4,3 ;enemy bullets
3215 .db %11110000 ;████▒
3219 .db (spr_bullet01-spr_bullet01) ;0
3220 .db (spr_bullet02-spr_bullet01) ;4
3221 .db (spr_bullet03-spr_bullet01) ;8
3222 .db (spr_bullet04-spr_bullet01) ;12
3223 .db (spr_bullet05-spr_bullet01) ;16
3224 .db (spr_bullet06-spr_bullet01) ;20
3225 .db (spr_bullet07-spr_bullet01) ;24
3226 .db (spr_bullet08-spr_bullet01) ;28
3227 .db (spr_bullet09-spr_bullet01) ;32
3228 .db (spr_bullet10-spr_bullet01) ;36
3229 .db (spr_bullet11-spr_bullet01) ;40
3230 .db (spr_bullet12-spr_bullet01) ;44
3231 .db (spr_bullet13-spr_bullet01) ;48
3232 .db (spr_bullet13-spr_bullet01) ;52
3233 .db (spr_bullet13-spr_bullet01) ;56
3234 .db (spr_bullet13-spr_bullet01) ;60
3236 ;format:[min.damage] [dam.inc] [000:direction 00000:speed] [offset]
3237 ;damage = min.damage + dam.inc*incs (0<=incs<=6)
3238 ;speed in pixels/frame (>=%10010=forward; <=%01110=backwards)
3239 ;direction: 0=straight forward; 1=up; 2=1/2up; 3=down; 4=1/2down
3243 .db 1,1,%00000000,0,%00000000,0,%00010010,3 ;1 single fire
3244 .db 4,1,%00000000,0,%00000000,0,%00010011,3 ;2 fast single
3245 .db 1,1,%00000000,0,%00010010,0,%00010010,6 ;3 double
3246 .db 1,1,%01110010,2,%10010010,2,%00110010,2 ;4 triple
3247 .db 3,2,%01110011,2,%10010011,2,%00110011,2 ;5
3248 .db 5,3,%01110011,2,%10010100,2,%00110011,2 ;6
3249 .db 7,4,%01110100,2,%10010100,2,%00110100,2 ;7
3250 .db 12,5,%01110110,2,%10010110,2,%00110110,2 ;8
3252 .db 1,1,%00000000,0,%00000000,0,%11100000,3 ;1 single laser
3253 .db 1,1,%00000000,0,%11100000,0,%11100000,6 ;2 double laser
3254 .db 1,1,%11100000,0,%11100000,6,%11100000,3 ;3 triple laser
3259 ;------------------------------------ bar -----------------------------------
3262 .db 5,3 ;li'l ship indicating lives left
3264 .db %01111000 ; ████
3266 lshipsize = 5 ;space between two ship icons
3269 .db 16,7 ;selected.......:.......:
3270 .db %11111111 ;████████████████
3276 .db %11111111 ;████████████████
3286 .db 16,7 ;unused .......:.......:
3287 .db %10101010 ;█ █ █ █ █ █ █ █
3288 .db %11010101 ;██ █ █ █ █ █ █ █
3289 .db %10101010 ;█ █ █ █ █ █ █ █
3290 .db %11010101 ;██ █ █ █ █ █ █ █
3291 .db %10101010 ;█ █ █ █ █ █ █ █
3292 .db %11010101 ;██ █ █ █ █ █ █ █
3293 .db %10101010 ;█ █ █ █ █ █ █ █
3303 .db 16,7 ;armor ;.......:.......:
3304 .db %10000111 ;█ ███████ ▒
3305 .db %10011000 ;█ ██ ██ ▒
3306 .db %10110011 ;█ ██ ████ ██ ▒
3307 .db %10110000 ;█ ██ ████ ██ ▒
3308 .db %10110011 ;█ ██ ████ ██ ▒
3309 .db %10011000 ;█ ██ ██ ▒
3310 .db %10000111 ;█ ███████ ▒
3320 .db 16,7 ;tailbeam.......:.......:
3322 .db %10000011 ;█ ██ ▒
3323 .db %10000001 ;█ ███ ▒
3324 .db %10111011 ;█ ███ ██████ ██▒
3325 .db %10000001 ;█ ███ ▒
3326 .db %10000011 ;█ ██ ▒
3337 .db 16,7 ;torpedo .......:.......:
3338 .db %10111000 ;█ ███ █ █ █▒
3339 .db %10011100 ;█ ███ █ █ █▒
3340 .db %10111000 ;█ ███ █ █ █ ▒
3341 .db %10000000 ;█ ███ █ █ ▒
3342 .db %11100001 ;███ ████ █ █▒
3343 .db %10011000 ;█ ██ ████ █ █▒
3344 .db %11100110 ;███ ██ ██ █ ▒
3354 .db 16,7 ;bullets .......:.......:
3355 .db %10000000 ;█ ██ ▒
3356 .db %10000011 ;█ █████ ▒▒▒ ▒
3357 .db %10011000 ;█ ██ ██ ▒▒▒ ▒
3358 .db %11111100 ;██████ ▒▒▒ ▒
3359 .db %10011000 ;█ ██ ██ ▒▒▒ ▒
3360 .db %10000011 ;█ █████ ▒▒▒ ▒
3361 .db %10000000 ;█ ██ ▒
3371 .db 16,7 ;laser .......:.......:
3373 .db %10001010 ;█ █ █ ▒▒▒ ▒
3374 .db %11101100 ;███ ██ ▒▒▒ ▒
3375 .db %11110111 ;████ ███████▒▒▒█▒
3376 .db %11101100 ;███ ██ ▒▒▒ ▒
3377 .db %10001010 ;█ █ █ ▒▒▒ ▒
3388 .db 16,7 ;multiple.......:.......:
3389 .db %10000011 ;█ ███ ▒
3390 .db %10000001 ;█ ████ ██ ▒
3391 .db %10000001 ;█ ████ ▒
3392 .db %10000011 ;█ ███ ▒
3393 .db %10011000 ;█ ██ ▒
3394 .db %10111100 ;█ ████ ██ ██▒
3395 .db %10011000 ;█ ██ ▒
3406 .db 128,128,128,128,128,128,128 ;128 = %10000000
3408 ;---------------------------- texts -----------------------------------------
3410 txt_email: .db "www.shiar.org ",127 ;title screen
3411 .db " shiar0@hotmail.com",0
3412 _txt_email = $3A01 ;$3A1E=just email
3413 txt_about: .db "v0.98.79 ",127," by Shiar",0 ;right behind txt_email
3415 txt_menu1: .db "NEW GAME",0
3416 txt_menu2: .db "CONTINUE",0
3418 txt_level: .db "LEVEL ",0 ;new level screen
3419 txt_lives: .db "Lx0",0
3420 txt_savekey: .db "Press [F1] to save",0
3422 txt_gameover: .db "GAME OVER!",0 ;game over screen
3423 txt_score: .db "Score",0
3424 txt_hiscore: .db "Hiscore",0
3426 txt_pressenter: .db "Enter to continue",0 ;pause
3427 txt_teacher: .db "(2",Lpi,"*.98)/sin 13",0 ;teacher
3428 txt_teacherans: .db Lneg,"14.6549373495",0
3430 ;---------------------------- save data -------------------------------------
3433 hiscore .dw 0 ;default hiscore
3434 hiname .db "shiar.98",0 ; " " name
3437 storesave_start: ;--SAVED GAME-- defs:
3438 level .db 1 ;level number 1
3439 levelp .dw level01 ;pointer to level data l01
3440 pickuptimer .db 4 ;counts when to place a pickup 4
3441 your_ship .dw spr_ship01 ;your sprite sprs1
3442 your_score .dw 0 ;current score 0
3443 your_pickup .db 3 ;pickups already picked up 0
3444 your_occ .db 0 ;0=normal 1..16=exploding 0
3445 your_inv .db 0 ;invincibility left 0
3446 your_armor .db 12 ;HP left 12
3447 your_lives .db 3 ;lives left 3
3448 your_weapon .db 0 ;current weapon upgrade 0
3449 your_multiples .db 0 ;multiples present 0
3450 your_tail .db 0 ;tail beam present 0
3453 time2invert: .db 0 ;time until b<>w switch (0 at startup)
3455 ;------------------------------ levels data ---------------------------------
3457 ;format:boss: [moveType] [enemyType]
3458 ; @level: [nr.dif.enemies]x [enemy nr]
3459 ; [min. enemy frequency] [enemy frequency max.inc] [next lvl]
3460 ; [level_info: 0000:damage 0:diagfire 0:ground 0:ceiling 0:?]
3461 ; [level_move] [tunnel size] [groundtype]
3462 ; [16_ground] [16_ceiling] [stars1] [stars2]
3463 ;efrequency must be odd if halfluring!
3466 .db 0 ;story identifier
3467 .db $21,$1d,"Cosmic year 6716" ,0,0,$1d,$06
3468 .db $1b,$1d,"STORYLINE COMING SOON" ,0,0,$1d,$06
3469 .db $09,$19,"STORYLINE COMING SOON" ,0,1
3470 .db $2e,$21,"**** NEMESIS 86" ,0,1
3471 .db $52,$36,"by Shiar" ,0,0,$19,$23
3474 .db 20 ;boss for level01
3475 level01: ;intro-like, just a few enemies to begin with
3477 .db 26,70,20,%00010000,0,0,0
3478 .db 1,2,3,4,5,6,6,5,4,3,4,5,4,5,6,5
3479 .db 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
3483 level02: ;first wave of enemies; easeey
3485 .db 20,60,60,%00100000,0,0,0
3486 .db 1,2,3,4,5,6,6,5,4,3,4,5,4,5,6,5
3487 .db 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
3491 level03: ;some more enemies
3493 .db 17,40,75,%00110000,0,0,0
3494 .db 1,2,3,4,5,6,6,5,4,3,4,5,4,5,6,5
3495 .db 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
3498 .db 0,0 ;storyline ID
3499 .db 1,1,"Long-Range scanners are ",
3501 .db 1,8,"lots of enemy vessels on ",
3502 .db "an intercept",0,1
3503 .db 1,15,"course.",0,1
3504 .db 1,24,"I'm changing course to a",
3506 .db 1,31,"asteroid belt and try to",0,1
3507 .db 1,38,"lose them inthere.",0,0
3511 level04: ;light asteroid belt
3513 .db 12,24,80,%00111000
3515 .db 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 ;16
3516 .db 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
3520 level05: ;inside asteroid belt
3522 .db 6,10,180,%01011000
3524 .db 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 ;16
3525 .db 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
3531 .db 30,1,40,%01000000
3533 .db 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 ;16
3534 .db 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
3540 .db $01,01,"And the storyline conti",
3542 .db $01,09,"You decide to fly close",
3544 .db $01,15,"surface of a nearby pl",
3545 .db "anet =)",0,0,1,20
3551 .db $13,40,$4b,%00100100,0,-5,1
3552 .db 1,2,3,4,5,6,6,5,4,3,4,5,4,5,6,5
3553 .db 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
3559 .db $01,01,"Blablabla...",0,1
3560 .db $01,34,"this storyline sux",0,0,1,39
3566 .db $2d,$3f,%00010110,0,-9,1
3567 .db 3,2,4,3,2,2,1,1,1,1 ,1,1,21,17,18,20
3568 .db 1,1,1,1,1,1,1,3,6,12,9,1,21,19,18,18
3569 .db -1,-1 ;=%11111111=line
3574 .db $11,$41,%00100001,0,0,0
3575 .db 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
3576 .db 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
3581 .db $11,$45,%00100101,%10,-7,1
3582 .db 14,12,11,9,10,7,7,5,4,3,4,4,2,3,1,2
3583 .db 1, 1, 1, 1,1, 1,1,1,1,1,1,1,1,1,1,1
3588 .db $19,$3a,%00100111,0,-4,1
3589 .db 20,22,18,15,9,1,1,1,1,1,1,1,1,1,1,1
3590 .db 20,22,18,15,9,1,1,1,1,1,1,1,1,1,1,1
3596 .db $09,$ff,%00100001,0,0,0
3597 .db 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
3598 .db 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
3601 ;------------------------------ enemies -------------------------------------
3603 ;format: [HP64] [000000:HP 00:occ] [sprite] [xpos] [appearance(ypos)]
3604 ; [movetype] [time2fire] [firefreq]
3605 ;appearances: 1=random; 2=lure; 3=halflure
3607 ; 1=updown; 2=1/4x; 3=1/2x; 4=1.5x; 5=2x; 6=smart; 7=y-lure;
3608 ; 8=y-lure 1/2x; 9=8 stop at x=99; 10=x+y-lure 1/2x
3611 .db 0,%00100110,(spr_enemyA1-spr_enemy00)/2,128,1,0,0,0
3612 .db 0,%00111110,(spr_enemyA2-spr_enemy00)/2,128,1,0,0,0
3613 .db 0,%01011010,(spr_enemyA3-spr_enemy00)/2,128,1,4,0,0
3614 .db 1,%00001010,(spr_enemyA4-spr_enemy00)/2,128,1,3,0,0
3615 .db 0,%00111110,(spr_enemyA4-spr_enemy00)/2,128,1,5,0,0
3617 .db 0,%00010010,(spr_enemyE1-spr_enemy00)/2,128,1,0,10,0 ;weak
3618 .db 0,%00110010,(spr_enemyE4-spr_enemy00)/2,128,1,3,6,50 ;slow
3619 .db 0,%00100110,(spr_enemyE2-spr_enemy00)/2,128,1,0,1,0
3620 .db 0,%00101110,(spr_enemyE3-spr_enemy00)/2,128,3,0,19,39
3621 .db 0,%00101010,(spr_enemyE5-spr_enemy00)/2,128,3,4,1,0 ;fast
3622 ;11=jumping bug (up/down)
3623 .db 0,%00001111,(spr_enemyN3-spr_enemy00)/2,128,2,1,87,5
3625 .db 0,%00000011,(spr_enemy00-spr_enemy00)/2,1,0,0,0,0 ;12
3626 .db 0,%00000011,(spr_enemy00-spr_enemy00)/2,1,0,0,0,0 ;13
3627 .db 0,%00000011,(spr_enemy00-spr_enemy00)/2,1,0,0,0,0 ;14
3628 .db 0,%00000011,(spr_enemy00-spr_enemy00)/2,1,0,0,0,0 ;15
3629 .db 0,%00000011,(spr_enemy00-spr_enemy00)/2,1,0,0,0,0 ;16
3630 .db 0,%00000011,(spr_enemy00-spr_enemy00)/2,1,0,0,0,0 ;17
3631 .db 0,%00000011,(spr_enemy00-spr_enemy00)/2,1,0,0,0,0 ;18
3632 .db 0,%00000011,(spr_enemy00-spr_enemy00)/2,1,0,0,0,0 ;19
3634 .db 1,%00101011,(spr_boss0_1-spr_enemy00)/2,127,1,8,20,12 ;20
3635 .db 1,%00110011,(spr_boss0_1-spr_enemy00)/2,127,1,8,15,10 ;21
3636 .db 1,%01001011,(spr_boss0_2-spr_enemy00)/2,127,3,9,10,9 ;22
3637 ;23-24=asteroid bosses
3638 .db 2,%00001011,(spr_boss0_3-spr_enemy00)/2,127,1,10,36,14
3639 .db 2,%00110011,(spr_boss0_3-spr_enemy00)/2,127,2,10,28,12
3641 .db 2,%00000111,(spr_boss0_4-spr_enemy00)/2,127,3,7,18,7 ;25=bigboss1
3642 .db 2,%01001011,(spr_boss0_5-spr_enemy00)/2,127,3,7,18,7 ;26=bigboss2
3646 .db %11111111 ; ████████████
3647 .db %10000110 ; █ ██ █
3648 .db %10000110 ; █ ██ █
3649 .db %10111111 ; █ ████████ █
3650 .db %10111111 ; █ ████████ █
3651 .db %10000110 ; █ ██ █
3652 .db %10000110 ; █ ██ █
3653 .db %11111111 ; ████████████
3666 .db 7,6 ;asteroid one
3668 .db %01101100 ; ██ ██
3669 .db %10011110 ;█ ████
3670 .db %11111010 ;█████ █
3671 .db %10111100 ;█ ████
3674 .db 8,7 ;asteroid two
3675 .db %00111100 ; ████
3676 .db %01011010 ; █ ██ █
3677 .db %01101101 ; ██ ██ █
3678 .db %11111101 ;██████ █
3679 .db %11111111 ;████████
3680 .db %10110110 ;█ ██ ██
3684 .db 8,8 ;asteroid three
3685 .db %00011110 ; ████
3686 .db %01110011 ; ███ ██
3687 .db %01111101 ; █████ █
3688 .db %10110111 ;█ ██ ███
3689 .db %11111110 ;███████
3690 .db %11111101 ;██████ █
3691 .db %01010111 ; █ █ ███
3694 .db 7,6 ;asteroid four
3695 .db %01111000 ; ████
3696 .db %10110110 ;█ ██ ██
3697 .db %11111101 ;██████ █
3698 .db %01111011 ; ████ ██
3699 .db %01001110 ; █ ███
3704 .db %00111100 ; ████
3706 .db %10111000 ;█ ███
3708 .db %10111000 ;█ ███
3710 .db %00111100 ; ████
3714 .db %00111100 ; ████
3719 .db %00111100 ; ████
3721 .db 6,6 ;normal solid (Galaxian enemy)
3722 .db %00111100 ; ████
3727 .db %00111100 ; ████
3731 .db %01101000 ; ██ █
3735 .db %01101000 ; ██ █
3741 .db %01111000 ; ████
3744 .db %01111000 ; ████
3749 .db %00111111 ; █████
3751 .db %10110100 ;█ ██ █
3752 .db %10110100 ;█ ██ █
3754 .db %00111111 ; █████
3756 .db 8,6 ;smaller nacelles
3758 .db %01101100 ; ██ ██
3759 .db %10110100 ;█ ██ █
3760 .db %10110100 ;█ ██ █
3761 .db %01101100 ; ██ ██
3765 .db %00001111 ; ████
3766 .db %01111100 ; █████
3767 .db %10011100 ;█ ███
3768 .db %10011100 ;█ ███
3769 .db %01111100 ; █████
3770 .db %00001111 ; ████
3772 .db 8,6 ;G-Type solid
3773 .db %00111111 ; █████
3774 .db %01111000 ; ████
3775 .db %11111100 ;██████
3776 .db %11111100 ;██████
3777 .db %01111000 ; ████
3778 .db %00111111 ; █████
3780 .db 6,6 ;G lost his head; large window ;)
3781 .db %01111100 ; █████
3783 .db %10111000 ;█ ███
3784 .db %10111000 ;█ ███
3786 .db %01111100 ; █████
3788 .db 7,6 ;small G-type
3789 .db %00011110 ; ████
3790 .db %01111000 ; ████
3793 .db %01111000 ; ████
3794 .db %00011110 ; ████
3799 .db %01111100 ; █████
3800 .db %11111000 ; █████
3801 .db %11111000 ; █████
3802 .db %01111100 ; █████
3805 .db 7,6 ;some attack vessel
3807 .db %01110010 ; ███ █
3808 .db %10101100 ; █ █ ██
3809 .db %10101100 ; █ █ ██
3810 .db %01110010 ; ███ █
3813 .db 7,6 ;interceptor
3814 .db %00011110 ; ████
3815 .db %01111110 ; ██████
3816 .db %11111100 ; ██████
3817 .db %11111100 ; ██████
3818 .db %01111110 ; ██████
3819 .db %00011110 ; ████
3821 .db 8,6 ;cheap intercept
3822 .db %00011011 ; ██ ██
3823 .db %01110110 ; ███ ██
3824 .db %10111100 ; █ ████
3825 .db %10111100 ; █ ████
3826 .db %01110110 ; ███ ██
3827 .db %00011011 ; ██ ██
3830 .db 8,7 ;some cool Nemesis-MSX enemy
3831 .db %00111110 ; █████
3832 .db %11110001 ;████ █
3834 .db %00010101 ; █ █ █
3836 .db %11110001 ;████ █
3837 .db %00111110 ; █████
3841 .db %00111110 ; █████
3842 .db %00011101 ; ███ █
3843 .db %11111111 ;████ ███
3844 .db %01110110 ; ██ ███
3845 .db %11111111 ;████ ███
3846 .db %00011101 ; ███ █
3847 .db %00111110 ; █████
3850 .db 8,7 ;Nem3MSX jumper lvl#3
3851 .db %10111110 ;█ █████
3852 .db %01011101 ; █ ███ █
3853 .db %01111110 ; ██████
3855 .db %01111110 ; ██████
3856 .db %01011101 ; █ ███ █
3857 .db %10111110 ;█ █████
3861 .db 16,10 ;boss type one..:.......:
3862 .db %00000001 ; ██████ ██
3863 .db %00001110 ; ███ █ ███
3864 .db %00110010 ; ██ █ ████
3865 .db %01001101 ; █ ██ ██
3866 .db %11101011 ;███ █ ██ █
3867 .db %11101011 ;███ █ ██ █
3868 .db %01001101 ; █ ██ ██
3869 .db %00110010 ; ██ █ ████
3870 .db %00001110 ; ███ █ ███
3871 .db %00000001 ; ██████ ██
3885 .db 16,10 ;boss type two..:.......:
3886 .db %11111110 ;███████
3887 .db %00000011 ; ███ ████
3888 .db %00110101 ; ██ █ ████ █
3889 .db %01111010 ; ████ █ █ █ ██
3890 .db %10001101 ;█ ██ █ ██ ██
3891 .db %10001101 ;█ ██ █ ██ ██
3892 .db %01111010 ; ████ █ █ █ ██
3893 .db %00110101 ; ██ █ ████ █
3894 .db %00000011 ; ███ ████
3895 .db %11111110 ;███████
3907 .db 16,11 ;bigasteroid one
3908 .db %00011110 ; ████
3909 .db %01110011 ; ███ ███
3910 .db %01111111 ; ███████ █
3911 .db %01111111 ; █████████
3912 .db %11111110 ;███████ ███
3913 .db %11111111 ;███████████
3914 .db %11111111 ;████████████
3915 .db %10111110 ;█ █████ ████
3916 .db %01011111 ; █ ███████
3917 .db %00110111 ; ██ ███
3931 .db 16,18 ;bigboss one :
3933 .db %00000111 ; ███ ███
3934 .db %00000011 ; ████ █
3935 .db %00000001 ; ██ ██
3936 .db %00000011 ; ███ ██
3937 .db %00000000 ; █████
3938 .db %00010111 ; █ ██████████
3939 .db %00111111 ; ██████ ██ ██
3940 .db %11111000 ;█████ ██ █ ███
3941 .db %00001111 ; █████ ██ █ █
3942 .db %11111000 ;█████ ██ █ ███
3943 .db %00111111 ; ██████ ██ ██
3944 .db %00010111 ; █ ██████████
3945 .db %00000000 ; █████
3946 .db %00000011 ; ███ ██
3947 .db %00000001 ; ██ ██
3948 .db %00000011 ; ████ █
3949 .db %00000111 ; ███ ███
3951 .db %01010000 ;modelled after a Nemesis][MSX boss
3971 .db 16,15 ;bigboss two :
3972 .db %00001111 ; █████
3973 .db %00111110 ; █████ █████
3974 .db %01111101 ; █████ █ ███████
3977 .db %00000011 ; █████
3978 .db %00011110 ; ████ ██ ████
3979 .db %11110011 ;████ ██ █ █
3980 .db %00011110 ; ████ ██ ████
3981 .db %00000011 ; █████
3984 .db %01111101 ; █████ █ ███████
3985 .db %00111110 ; █████ █████
3986 .db %00001111 ; █████
3987 .db 15 ;modelled after a Nemesis][MSX boss
4005 ;----------------------------------------------------------------------------
4006 ;----------------------------- logo ------------------------------------------
4007 ;----------------------------------------------------------------------------
4010 .db %11111111,%11111111,%11111111,%11111110,%11111111,%11110111,%11111111,%11111110,%11111111,%111101111,%11111111,%00001011,%11111111,%11111111,%11111111,%11111110
4011 .db %01111111,%11111111,%11111111,%11111110,%11111111,%11110111,%11111111,%11111110,%11111111,%111101111,%11111111,%00011011,%11111111,%11111111,%11111111,%11111100
4012 .db %00111111,%11111111,%11111111,%11111110,%11111111,%11110111,%11111111,%11111110,%11111111,%111101111,%11111111,%00111011,%11111111,%11111111,%11111111,%11111000
4013 .db %00011111,%11111111,%11111111,%11111110,%11111111,%11110111,%11111111,%11111110,%11111111,%111101111,%11111111,%01111011,%11111111,%11111111,%11111111,%11110000
4014 .db %00000000,%00000000,%00000001,%00011110,%00010000,%00000000,%10000001,%00011110,%00010000,%000000001,%00000000,%00001000,%01000000,%00000000,%00000000,%00000000
4015 .db %00000000,%00000000,%00000011,%00011110,%00110000,%00000001,%10000011,%00011110,%00110000,%000000011,%00000000,%00011000,%11000000,%00000000,%00000000,%00000000
4016 .db %00000000,%00000000,%00000111,%00011110,%01110000,%00000011,%10000111,%00011110,%01110000,%000000111,%00000000,%00111001,%11000000,%00000000,%00000000,%00000000
4017 .db %00000000,%00000000,%00001111,%00011110,%11111111,%00000111,%10001111,%00011110,%11111111,%000001111,%11111111,%01111011,%11111111,%11000000,%00000000,%00000000
4018 .db %00000000,%00000000,%00001111,%00011110,%11111111,%00000111,%10001111,%00011110,%11111111,%000001111,%11111111,%01111011,%11111111,%11000000,%00000000,%00000000
4019 .db %00000000,%00000000,%00001111,%00011110,%11111111,%00000111,%10001111,%00011110,%11111111,%000001111,%11111111,%01111011,%11111111,%11000000,%00000000,%00000000
4020 .db %00000000,%00000000,%00001111,%00011110,%11111111,%00000111,%10001111,%00011110,%11111111,%000001111,%11111111,%01111011,%11111111,%11000000,%00000000,%00000000
4021 .db %00000000,%00000000,%00001111,%00011110,%11110000,%00000111,%10001111,%00011110,%11110000,%000000000,%00001111,%01111000,%00000011,%11000000,%00000000,%00000000
4022 .db %00000000,%00000000,%00001111,%00011110,%11110000,%00000111,%10001111,%00011110,%11110000,%000000000,%00001111,%01111000,%00000011,%11000000,%00000000,%00000000
4023 .db %00000000,%00000000,%00001111,%00011110,%11110000,%00000111,%10001111,%00011110,%11110000,%000000000,%00001111,%01111000,%00000011,%11000000,%00000000,%00000000
4024 .db %00000000,%00000000,%00001111,%00011110,%11110000,%00000111,%10001111,%00011110,%11110000,%000000000,%00001111,%01111000,%00000011,%11000000,%00000000,%00000000
4025 .db %00000000,%00000000,%00001111,%00011110,%11111111,%11110111,%10001111,%00011110,%11111111,%111101111,%11111111,%01111011,%11111111,%11000000,%00000111,%11010001
4026 .db %00000000,%00000000,%00001111,%00011110,%11111111,%11110111,%10001111,%00011110,%11111111,%111101111,%11111111,%01111011,%11111111,%11000000,%00000001,%00011011
4027 .db %00000000,%00000000,%00001111,%00011110,%11111111,%11110111,%10001111,%00011110,%11111111,%111101111,%11111111,%01111011,%11111111,%11000000,%00000001,%00010101
4028 .db %00000000,%00000000,%00001111,%00011110,%11111111,%11110111,%10001111,%00011110,%11111111,%111101111,%11111111,%01111011,%11111111,%11000000,%00000001,%00010001
4030 ;----------------------------- end ------------------------------------------
4036 ;----------------------------------------------------------------------------
4037 ;----------------------------------------------------------------------------
4038 ;----------------------------------------------------------------------------
4040 ; 0.98.77 -- 7.VII.00 -- size 6707
4042 ; # bullets do damage in all levels
4043 ; * more armor at armor-upgrade and extra armor at end of a level
4044 ; - internal levels again (no need 4 external, safer/smaller)
4045 ; # some registers not correctly pushed/popped
4046 ; * several optimizations (init.procs some bytes smaller)
4047 ; # enemies hit with hitpoints left disappeared (one pop too much...)
4048 ; + bullets "charge up" (more damage) when not firing
4049 ; - removed contrast changes
4050 ; + more powerful bullets have different sprites (larger=more damage)
4051 ; # multiples appear at your position (begin level/just selected)
4052 ; # when invulnerable multiples acted weird
4053 ; # no more error at activation after APD off after running Nemesis
4054 ; # saves correctly if own name ain't "nemesis" + some bytes smaller
4055 ; # screen wasn't always entirely cleared after quit
4056 ; * waits until all keys have been released after death
4057 ; + different bullets sizes will miss if they're too small
4058 ; + at level start "press F1 to save"-text will be displayed
4059 ; * w3.shiar.org displayed at title screen, black bar behind version nr
4060 ; # score to 0 when exit pressed at main menu
4061 ; # no residual story-text in first frame of game
4062 ; # game doesn't continue again after death (stack messed up)
4063 ; # game over when lives<0 (didn't work in v0.96+)
4064 ; * using some self-modifiing code (so it's smaller)
4065 ; # new random procedure: stars don't appear on one line anymore
4066 ; * weapons appear centered at multiples
4067 ; * laser properties can be changed (damage, charge)
4068 ; + weapon can be combination of bullets/lasers (max. of 3 per weapon)
4069 ; * bullet-icon is removed when laser is selected
4070 ; * enemy sprite table integrated in enemy specs (-1 byte/enemy)
4071 ; + random enemy is chosen from any number of enemies per level
4072 ; * time to first enemy fire defined per enemy, not per level
4073 ; + CLIPPED sprites!! no more in/out popping enemies! wow...
4074 ; * bullets/enemies removed when _entirely_ off screen
4075 ; # enemies would sometimes be hit by bullets going right below them
4076 ; # size of the second bullet was too big (invisible hit)
4077 ; * the frequency an enemy fires bullets is defined per enemy
4078 ; + wide clipped sprites implemented (width 1-16 pixels)
4079 ; # bosses first move left until x=100, otherwise they'd be off-screen
4080 ; * at status bar left below ships are displayed for lives left
4081 ; * armor bar is two pixels high (better visible)
4082 ; # bullet overflow fixed again (>63 bullets fired)
4083 ; # correct weapon loaded when continuing a saved game
4084 ; # game freezed when generating a random value <=1
4085 ; * you explode in a different way than the enemies
4086 ; + screen inverts for a brief time when you are hit!
4087 ; # stats-bar was messed up when ya got 0 lives left
4088 ; * two new (big) bosses modeled after a common MSX Nemesis2-boss
4089 ; * score increased once every 32 frames (instead of every 256)
4090 ; # ground fixed for new random routine (smaller routine; incs -2 to 2)
4091 ; + laser will upgrade as well when you reselect it
4092 ; * 2nd can be used in main menu (wow!)
4093 ; # altered variable storage space because of Nemesis grew beyond 6kb
4094 ; # fixed armor bar display when at maximum
4095 ; + a few new enemies (asteroids) and remade 1st 4 levels; new pickup
4096 ; - torpedo since it was kinda useless
4097 ; + second icon now selects TAIL BEAM: bullet going backwards
4098 ; # armor increase at the end of a level doesn't overflow armorbar
4099 ; + you can choose your own ship out of four vessel after NEW GAME!
4100 ; + enemies can appear at any x-position and move both left and right
4101 ; + move patterns given per enemy, not per level
4102 ; * new (faster) enemy-move system; 10 basic moves (x2 left+right)
4103 ; # enemies can _never_ move above or below visible screen
4104 ; * "randomY"-enemies are placed entirely on screen (height calced)
4105 ; # the major TI-OS crash bug WAS afterall caused by sprites drawn
4106 ; (partially) outside screen memory. temporarily fixed by setting
4107 ; virtual screen buffer to $8200 (enough mem there)
4108 ; + upto 29 cool enemy sprites and redone first five levels
4109 ; * improved enemy-move routine; smooth luring, five speeds+backwards
4110 ; # after pause weapon will not be fired
4111 ; # teacher key fixed (waits for GRAPH to be release before&after)
4113 ; 0.99.79 -- 9.VII.00 -- size 6747
4115 ; + you can have upto FOUR multiples! (~20 pixels apart)
4117 ; + added - removed * changed # bug fixed
4119 ;bullet handling: (255/enemy)+419+putsprite cycles per bullet