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 mx = starx2+(nrstars2*2) ;+83 ;position of multiple#1
69 my = mx+1 ;+84 ;multiple y-pos
72 your_locpos = m2y+1 ;+87 ;position in your_prevpos tabl
73 your_prevpos = your_locpos+1 ;+88 ;save previous positions (32d)
75 ;^-----------------------------------<1 ;-120=$78
77 enemies = storepos2 ; +0 ;info about each enemy
78 enemysize = 9 ;infobytes per enemy
79 nrenemies = 16 ;max. nr of enemies
81 ybullets = enemies+(nrenemies*enemysize) ;60 bytes = 20(state,damg,x,y)
83 ebullets = ybullets+(nrybuls*4) ;+110 ;30 bytes = 10(state,x,y)
85 lvlenemies = ebullets+(nrebuls*3)
87 ;^-----------------------------------<2 ;-141=$8D
89 ; [0000:damage 0:diagfire 0:ground 0:ceiling 0:-]
91 ; [HP64] [000000:HP left 00:(00=no enemy 01=exploding 10=normal 11=moving)]
92 ; [ship type or explosion frame] [x] [y] [movetype] [movecounter] [firecounter] [firefreq]
94 ;---------------------- introduction ----------------------------------------
96 nop ;hello yas/ase/rascall/whathever
97 jp init ;here's the program, but first: a description
98 .dw $0001 ;description type 2 (description + YASicon)
99 .dw Title ;pointer to description (all shells)
100 .dw Icon ;pointer to YAS icon
102 Title: .db "Nemesis v0.98 by SHIAR",0
104 Icon: .db 8,1 ;icon for YAS: width = 1byte; height = 9bytes
107 .db %00111110 ; █████
108 .db %01111001 ; ████ █
109 .db %00111110 ; █████
111 .db %11100000 ; ███ ;recommend 80x50 screen mode
112 .DB 0 ;clear stupid YAS-line
114 ;---------------------- init ------------------------------------------------
116 int_handler: ;new interrupt proc
117 ex af,af' ;just af only (no need for exx)
118 in a,($03) ;read bit 3 port 3
119 bit 3,a ;is ON key pressed?
120 jp z,$0039 ;no: np, return
121 res 0,a ;yes: then we have a problem (freeze), so...
122 out ($03),a ;...mask the ON key interrupts!
123 jp $0039 ;all done, return
126 init: cal BUSY_OFF ;turns the run-indicator off, obviously
127 cal _clrScrn ;clean the screen
129 res 2,(iy+13) ;don't scroll the screen
130 cal _flushallmenus ;remove TI menus
132 FixKeys: ;fixes some key problems like left+down bug
143 ld hl,int_handler ;new interrupt handler
146 ld bc,int_end-int_handler
152 ;---------------------- main menu -------------------------------------------
155 xor a ;white bitmask (a=0)
156 ld hl,logo_nemesis ;from...
157 ld de,VIDEO_MEM+16 ;...to one line from top
158 ld b,e ;ld b,16: one line
160 ld (de),a ;clear/n byte
162 dnz AboveLogo ;repeat for the first line
163 ld bc,16*19 ;logo size
164 ldir ;display one line of logo
166 ld hl,16*$33+VIDEO_MEM ;$33 rows down
167 ld b,16*7 ;draw black 7 lines
168 ld a,%11111111 ;horizontal line mask
170 ld (hl),a ;draw one piece of the divider-line
171 inc hl ;move right (8 pixels = 1 byte)
172 dnz underline ;repeat
174 ld hl,_txt_email ;at the very bottom of tha screen
176 ld hl,txt_email ;hey, my e-mail address so SEND ME SOMETHING!!
177 cal _vputs ;VERY important, so display in small font ?:}
179 set 3,(iy+5) ;set white on black
180 ld de,_txt_about ;near the bottom of the screen
181 ld (_penCol),de ;hl=txt_email++=txt_about
182 cal _vputs ;display version + me
183 res 3,(iy+5) ;return to default black on white
220 cal GET_KEY ;wait for keypress
230 jr z,start_tha_freakin_game
233 start_tha_freakin_game:
237 cal nz,New_game ;NEW GAME
238 jp samelevel ;CONTINUE: game_main_loop
251 do_invert: ;invert screen (b<>w); destr:b
256 xor (hl) ;$2F (cpl) <-> $B7 (or a)
262 ;----------------------------------------------------------------------------
263 ;---------------------- game loop -------------------------------------------
264 ;----------------------------------------------------------------------------
266 game_main_loop: ;REPEATS FROM HERE EVERY FRAME
267 ld hl,timer ;update time
268 inc (hl) ;increase by 1
271 ld hl,1 ;once every 32 frames, increase score by 1
272 cal z,scoreInc ;do it
275 ld hl,dispbuffer ;move from (hl) = top left
276 ld (hl),$00 ;first pixel will be copied all over the screen
277 ld de,dispbuffer+1 ;(de) = next pixel, thus clearing whole screen
278 ld bc,896 ;loop 896 times = (128/8) * (64-8 for scorebar)
281 ld a,0 ;current frame/turn 0-255
283 and %11 ;a=0 once every 4 turns
284 jr z,movestarsdone ;don't move stars once every 4 frames
285 cal movestars1 ;move the stars on the FRONT layer
286 cal movestars2 ;move the distant stars
288 ld a,(stars1) ;star positions (the missing byte...)
289 ld b,nrstars1 ;how many stars? now we know.
290 ld hl,starx1 ;points to the position of the stars
291 cal DisplayStars ;display front layer stars
292 ld a,(stars2) ;weren't you paying attention five lines ago?
293 ld b,nrstars2 ;that many?! whow!
294 ld hl,starx2 ;and there they are
295 cal DisplayStars ;use the same procedure to display back layer
297 ld a,(level_info) ;level info
298 and %00000110 ;isolate ground&ceiling
299 jr z,game_stuff ;both non-present
300 and %00000010 ;bit representing the presence of any ceiling
301 cal nz,Handle_ceiling ;scroll the ceiling (if any) +check4collision
302 cal Handle_ground ;scroll the ground and check if we're dead
305 cal Handle_Ship ;move you
306 ld a,(your_occ) ;are you 100% OK?
308 jr nz,_gamestuff1 ;then don't check for movements/fires/...
311 ld a,%10111111 ;function keys (MORE,EXIT,2ND,F1,F2,F3,F4,F5)
312 out (1),a ;ask for them
313 nop \ nop ;delay 8 clocks
317 bit 6,a ;test bit 6 = exit-key = EXIT
318 jp z,game_over ;<exit> pressed, so be it
319 check_morekey: ;another unused label... poor compiler
320 bit 7,a ;test bit 7 = more-key = PAUSE
321 cal z,Pause ;yes, go to pause
324 bit 5,a ;test bit 5 = 2nd-key = FIRE
325 ld hl,check_selkey ;where to continue after executing Fire_bullet
326 psh hl ;push hl on stack (instead of cal Fire_bullet)
327 jp z,Fire_bullet ;fire smtn (bulletstaillasermultiples+stuff..)
328 pop hl ;no cal to Fire_bullet made, so pop stack
330 ld (just_fired),a ;reset just_fired
333 ld a,%01011111 ;look at first column of keys (ALPHA to STO)
335 nop \ nop ;what's taking you so long
336 in a,(1) ;at last... our precious keyzzz...
338 bit 6,a ;'bout the GRAPH key...
339 cal z,Teacher ;you didn't _press_ it, did you?!?
341 rla ;test bit7 so we know f ALPHA has been pressed
342 cal nc,select ;yeppy, select the currently selected upgrade
344 cal Enemies_hit ;check for collision with enemies
348 cal Handle_enemies ;move enemies
350 cal Handle_bullets ;move your bullets + check for hits
351 cal Enemy_bullets ;move enemy bullets
353 cal Level_event ;insert enemies
354 cal Display_Screen ;display all
360 jp game_main_loop ;LOOP ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
366 cp 97 ;max. 96 times (=96/16=6 increases)
367 ret nc ;return if already maxed
368 ld (weapincs),a ;save new incs
370 and %11110000 ;clear last 4 bits so no cf when rotating
372 rra ;rotate acting as shift (srl a) but just 1B
375 rra ;increase once just every 16 turns
376 ld b,a ;times to increase
378 add a,1 ;increase damage for one increase
380 dnz incthedamage ;a=total increase damage
381 ld b,1 ;minimal damage
383 add a,b ;a=total damage
384 ld (curweapdamage),a ;safe the current damage
388 ;--------------------------- ground -----------------------------------------
392 and %111 ;once every 8 frames
393 jr nz,Display_ground ;otherwise skip the scroll
394 ld bc,15 ;scroll all 16 bytes minus one (teh new byte)
395 ld hl,groundpos+1 ;from..
396 ld de,groundpos ;to (one byte to the left)
397 ldir ;LoaDIncreaseRepeat = scroll!
399 ld a,(groundinfo) ;what kind of ground
401 jr z,ground_tunnel ;tunnel effect
403 ld a,(groundpos) ;type 0
410 ld bc,$500 ;range=0..4
415 add a,(hl) ;add to spacesize (so +2..-2)
417 jr c,newground ;>=0 then don't change
420 add a,b ;new position
422 jr z,newground ;may not be 0 (=256)
424 jr nc,newground ;and not be <0 (>246)
430 ld (groundpos+15),a ;save new byte on the right
433 ld b,16 ;screen width
434 ld de,groundpos-1 ;height of current byte (previous actually)
436 ld hl,dispbuffer+(56*16)-1 ;screen position
440 ld c,b ;push b for groundloopup
441 pop hl \ inc hl ;get screen position and go one right
442 pop de \ inc de ;get height info and set to the next byte
443 psh de \ psh hl ;save these for the next time
444 ld a,(de) ;height of current byte
447 ld de,16 ;to substract to go one line up
448 ld a,%11111111 ;bitmask black
451 ld (hl),a ;display black byte
452 sbc hl,de ;go up (sbc must be used for 16-bit sub)
453 dnz groundloopup ;and loop >groundpos< times
455 ld b,c ;pop b used by groundloopup
456 dnz groundloopright ;loop right for entire screen (16x)
457 pop hl \ pop hl ;restore stack
459 CheckGround: ;check for collision with the ground
477 ;--------------------------- ceiling ----------------------------------------
481 and %111 ;once every 8 frames
482 jr nz,Display_ceiling ;otherwise skip the scroll
483 ld bc,15 ;scroll all 15 bytes (16th is new position)
484 ld hl,ceilingpos+1 ;from..
485 ld de,ceilingpos ;to (one byte to the left)
486 ldir ;LoaDIncreaseRepeat = scroll!
488 ld a,(groundinfo) ;what kind of ceiling
490 jr z,ceiling_tunnel ;tunnel effect
495 ld d,a ;d=new ceiling
498 ld bc,$201 ;range=1..3
501 jr z,newceiling ;1:same
506 or a ;(spacespace)=0:
507 jr z,newceiling+2 ;keep same ceiling
513 cp d ;if size=1 then don't
519 ld (ceilingpos+15),a ;save the new byte
522 ld b,16 ;screen width
523 ld de,ceilingpos-1 ;height of current byte
525 ld hl,dispbuffer-17 ;screen position
529 ld c,b ;push b for groundloopup
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
536 ld de,16 ;to substract to go one line up
537 ld a,%11111111 ;bitmask black
540 ld (hl),a ;display black byte
542 dnz ceilingloopdown ;and loop >groundpos< times
544 ld b,c ;pop b used by groundloopup
545 dnz ceilingloopright ;loop right for entire screen (16x)
546 pop hl \ pop hl ;restore stack
548 CheckCeiling: ;check for collision with the ground
552 srl a ;x/8 (current ceiling-byte)
557 ld de,ceilingpos ;first ceiling-byte
558 add hl,de ;current ceiling-byte
561 cp (hl) ;compare with ceiling
562 ret nc ;carry if ceiling is above you
564 jp damage_you ;otherwise you don't wanna be in that ship
566 ;--------------------------- move stars -------------------------------------
568 DisplayStars: ;inputs: hl=starx# a=stars# b=nrstars#
575 ret ;let's comment this: returns
604 cp 9 ;(GRAPH_MEM&%00001111)-- = $C9FAand15-1 = $A-1
613 ret ;for stupid people, here's another comment...
615 ;--------------------------- pause ------------------------------------------
619 ld hl,$0200 ;top left
621 ld hl,txt_pressenter ;"Enter to continue"
622 cal _puts ;display message
624 cal _getkey ;enter low-power mode and wait for key
625 cp kEnter ;keypressed = enter?
626 jr nz,pause ;no, wait some more
630 ;--------------------------- teacher ----------------------------------------
633 ld (iy+12),5 ;enable flashing cursor
634 cal _clrWindow ;top left
636 cal _puts ;display message
640 cal _getkey ;enter low-power mode and wait for key
641 cp kEnter ;enter pressed?
643 cp kGrMenu ;keypressed = graph?
644 jr nz,teacherloop ;no, wait some more
646 ld (iy+12),0 ;disable cursor
661 ;--------------------------- exit -------------------------------------------
663 quit: im 1 ;release keyfix procedure
664 set 2,(iy+13) ;set back screen scrolling
666 ld (_asapvar+1),a ;next Asm( run will reload the program
667 ld hl,dispbuffer ;graph-screen location
670 ld bc,1024-1 ;do it 1024 times = entire screen
672 jp _clrWindow ;as _clrLCD but also clears TEXT_MEM (like the
673 ;_clrScrn) AND also executes _homeup and ret
675 ;--------------------------- display ----------------------------------------
678 ld hl,dispbuffer ;from buffer (top left)
679 ld de,VIDEO_MEM ;to real screen (top left)
680 ld c,56 ;display height = 64 bytes (minus 8 for bar)
682 ld b,16 ;display width = 16 bytes (16*8bits=256pixels)
684 ld a,(hl) ;copy byte from (hl)
685 _invert: ;SMC: cpl <-> or a
686 cpl ;xor $ff: invert byte (white<=>black)
688 inc hl \ inc de ;next byte
689 dnz displaytloop ;16x hl >> de
691 jr nz,displayloop ;loop 56x
695 or a ;(time2invert)=0:
696 jr z,noinvert ; do nothing
697 dec a ;otherwise decrease
698 cal z,do_invert ;if it became 0 then invert
699 ld (hl),a ;save new value
702 ld hl,$396b ;Display Score
703 ld (_penCol),hl ;bottom right of screen
706 _D_HL_DECI: ;------- display 5-digit value -------
707 ld de,savestr+4 ;savenr saves number string
709 ldhld: cal UNPACK_HL ;one digit of hl
710 add a,'0' ;make number
711 ld (de),a ;save into savenr
712 dec de ;point to next digit
713 dnz ldhld ;repeat for all digits
715 ld hl,savestr ;we (the program) saved the value righthere
716 jp _vputs ;the only thing left to do is to display it
718 savestr: ;@here the score will be stored
719 .db "00000",0 ;don't worry, it's just temporary
721 ;------------------------- handle ship --------------------------------------
728 inc a ;no! next (explosion)frame
729 ld (your_occ),a ;save
731 cp 64+1 ;last explosion frame? (1-16=1st;49-64=4th)
732 jp c,exploding_you ;not yet: display explosion
733 cp 64+16 ;delay finished?
734 jp z,You_die ;yes = game over
735 ret ;don't display anything
739 ld a,%01111110 ;get arrow keys
740 out (1),a ;it's cold outside
741 ld hl,y ;instead of nop\nop do something usefull
742 in a,(1) ;come back in
745 xor %11111111 ;inverted a = 0 if arrow-key has been pressed
746 ld a,(your_multiples)
747 jr z,no_adv ;if so, leave the multiples where they are
748 or %100 ;set move bit
750 no_adv: and %11111011 ;reset move bit
752 adv_ok: ld (your_multiples),a
754 ld a,(timer) ;framecounter
755 and %1 ;switches 0<>1 each frame
756 inc a ;a = 1 or 2 (1.5 avg)
757 ld c,a ;c = your_speed
760 rra ;rotate right (put last bit in c)
761 ld b,a ;we need a later
766 cp 50 ;56-6 = bottom of screen
771 rr b ;because we now use b, it's rr instead of rra
774 sub c ;<dec a> doesn't affect c-flag
775 jr c,no_left ;-1 = left side
782 cp 122 ;128-6 = right side
791 sub c ;<dec a> doesn't affect carry-flag
792 jr c,no_up ;-1 = top of screen
793 ld (hl),a ;save new y
795 no_up: ld e,(hl) ;e=y
796 ld ix,spr_ship01 ;normal ship sprite
798 ld hl,your_inv ;invulnerable?
799 ld a,(hl) ;load time in a
801 jr z,disp_ship ;yes so ship = normal (display \ continue)
803 ld a,(timer) ;load frame nr.
804 and %00000111 ;a=0 once every four frames
805 jr nz,not_time ;a<>0 = not time to update counter
806 dec (hl) ;decrease inv-time left
808 and %00000100 ;a switches 0<->1 every 2 frames
809 jr z,disp_ship ;show normal ship
811 ld bc,spr_ship01i-spr_ship01
812 add ix,bc ;display invulnerable ship
814 cal safeputsprite ;display your ship; save de
819 ld a,(your_multiples) ;do you have multiples
820 ld b,a ;save a for 2nd check
821 and %11 ;no? (last two bits = nr of multiples)
822 ret z ;then don't handle them either
824 ld a,b ;restore a (your_multiples)
825 and %100 ;move the multiples??? (=move bit set?)
826 jr z,mult_adv ;nope, just let them (saves (y)in y, (x)in x)
828 ld hl,your_locpos ;location to save this position
830 inc a ;a=a+1 (next position)
831 and %00001111 ;if a>15 then a=a-16
832 ld (hl),a ;save new a
837 ld hl,your_prevpos ;previous positions
838 add hl,bc ;16 turns ago
842 ld (mx),bc ;save multiple position in (mx)
843 ld (hl),d ;save current pos. for 16 turns into the future
852 ld ix,spr_multiple ;sprite of the multiple
853 jp putsprite ;display it + <ret>
858 srl a ;half the framerate
859 srl a ;half that framerate
860 srl a ;and half again that framerate
862 ld ix,spr_yexplosion ;base sprite
864 explosion_stuff: ;in:a=frame*2+(0 to 1); (hl)=xpos-- ix=sprite
870 add ix,bc ;go to correct sprite (each spr. is 8 bytes)
875 jp putsprite ;and display it too
879 damage_you: ;damages you B points
880 ld a,(your_inv) ;shield left?
882 jr z,dothadamage ;no shield
883 srl b ;shield: half the damage
887 cp (hl) ;no already inverted?
888 cal z,do_invert ;then invert screen
890 ld (hl),a ;change back 2 frames from now
892 ld hl,your_armor ;armor left
893 ld a,(hl) ;load hp in A
894 sub b ;decrease hp by B
895 jp m,no_armor ;<0hp left so explode
896 ld (hl),a ;no, so save decreased hp
897 jp disp_armor ;and display new value
899 ld a,%01 ;occ %xxxxxx01 = explode
900 ld (your_occ),a ;too bad, you're dead meat
903 ;------------------------- place multiples ----------------------------------
906 ld (mx),de ;set last multiple-position
907 ld hl,your_prevpos ;place all previous positions
908 ld b,16 ;all 16 of them
910 ld (hl),d ;set prev-x to d
912 ld (hl),e ;set prev-y to e
914 dnz place_multiples ;repeat
917 ;------------------------- select upgrade -----------------------------------
920 ld a,(your_armor) ;load current armor
921 cp 25-6 ;may not become >=25
922 jr c,doincarmor ;ok then just add 6
923 ld a,24-6 ;set to maximum (6 will be added below)
925 add a,6 ;add 6 to armor
926 ld (your_armor),a ;change armor
930 ld hl,your_pickup ;select pickups
931 ld a,(hl) ;load pickups taken so far
933 ret m ;return if it's 0 (no pickups)
934 jr nz,select2 ;no, carry on
936 ld (hl),a ;reset pickups
938 jp disp_icons ;display and return
941 jr nz,select3 ;no, carry on
942 ld (hl),a ;reset pickups
944 ld (your_tail),a ;ready tail beam
945 jp disp_icons ;display 'n return
948 jr nz,select4 ;no, carry on
949 ld (hl),a ;reset pickups
954 jp nc,disp_icons ;weapon maxed out
955 ld (hl),a ;set new weapon
956 cal loadweapon ;load it (damage and stuff)
957 jp disp_icons ;display n return
960 jr nz,select5 ;no, carry on again
961 ld (hl),a ;reset pickups
964 cp maxweapon ;upgrade from bullet
965 jr nc,upgradelaser ;nope, just upgrade
966 ld a,maxweapon-1 ;yes, set laser #1
970 jp nc,disp_icons ;laser maxed out
973 jp disp_icons ;display + return
976 jr nz,select6 ;no, carry on once more
977 ld (hl),a ;reset pickups
979 ld (your_multiples),a
982 jp disp_icons ;display, return
984 ld (hl),0 ;reset pickups
985 jp disp_icons ;display/return
987 ;------------------------- fire bullet --------------------------------------
991 ld a,(hl) ;just_fired
992 cp 5 ;already pressed?
993 ret z ;return when already pressed (=5)
995 inc (hl) ;otherwise increase counter (0 to 4 >> 1 to 5)
996 ld a,(your_weapon) ;if you have bullets.....
998 jr nc,fireOK ;>weapons = laser
999 ld (hl),5 ;.....then can't fire next turn (go to 5 imm.)
1002 ld hl,(x) ;yes: first fire from ship position (x)
1003 ld a,(your_multiples) ;any multiples?
1005 jr z,fireany ;then just fire somethin'
1006 cal fireany ;and blast
1007 ld hl,(mx) ;then, fire from multiple position (mx)
1008 dec h ;one up (-2 height: keeps weapons centered)
1009 ;blast again and <ret>
1011 ld (firex),hl ;set position to fire from
1013 ld ix,weapondata+2-(256*3)
1018 ld b,3 ;go to current weapon (bc=a), b=3 :P
1022 psh bc ;save counter
1023 ld a,(ix) ;load this weapon
1024 cp %11100000 ;%11110000=laser
1025 cal z,fire_laser ;fire laser (will set a=0 when done)
1030 pop bc ;weapon counter (do 3 weapons)
1038 ld a,(ix-2) ;last weapon fired
1039 cp %11100000 ;issit laser
1041 xor %11111 ;smart way of going left instead of right :P
1042 jr fire_ybullet ;fire tail bullet and return
1044 ;-----fire LASER-----
1047 ld b,0 ;overflow counter
1049 ld d,(hl) ;d = your x-pos
1052 ld a,(hl) ;base y-coord (firey)
1053 add a,(ix+1) ;at specified offset (most likely the middle)
1054 ld e,a ;save laser-y in e
1055 psh de ;save unmodified (x,y)
1059 rl b ;b (=0) =b*2+overflow (if y>32 then bc=bc+256)
1060 add a,a ;y*16 (width of screen)
1061 rl b ;b=b*2+overflow (if y>64 then bc=bc+512)
1062 inc a ;8 pixels to right (a=even so no overflow)
1067 add a,d ;a = (Y*16+X/8) mod 256 (c set on overflow)
1069 jr nc,_nolc ;jump if no carry = no overflow = a<=255
1070 inc b ;a>255 so increase bc by 256
1071 _nolc: ld c,a ;c = (Y*16+X/8) mod 256
1072 ld hl,dispbuffer ;save-location
1073 add hl,bc ;bc = Y*16+X/8: hl=screen address
1074 ld a,15 ;128/8=16=screen width ** minus one (inc a ^^)
1075 sub d ;minus x-start (d=X/8)
1079 inc hl ;Go to next byte
1082 pop de ;de=(firex): x-pos unmodified
1084 check_laserhits: ;de = (x,y)
1086 ld b,nrenemies ;check all enemies
1087 ld hl,enemies+1 ;enemy#1+occ/hp00
1088 laserhits: ;hits with normal enemies
1091 and %00000010 ;normal/moving occ.=%1x
1092 jr z,nolashit ;no hit when enemy_occ <> 2/3
1095 or a ;enemy #0 = pickup
1096 jr z,nolashit ;yes: don't destroy
1098 cal find_sprite ;ix=sprite to enemy (hl)
1102 jp m,nolashit ;no hit when enemy is left of you
1106 jr z,enemy_lashit ;a-e=0 = laser on top line of enemy = hit
1107 jr nc,nolashit ;a-e>0 = enemy above laser = no hit
1109 add a,(ix+1) ;add enemy height (according to sprite @ix)
1110 jp m,nolashit ;a-e>0 = hit
1112 ld a,(curweapdamage) ;damage
1113 cal enemy_hit ;hl=enemy+y
1118 add hl,bc ;go to next enemy
1120 dnz laserhits ;check all enemies
1121 xor a ;a=0 otherwise weird things might happen :P
1122 ld (weapincs),a ;reset damage
1126 ;-----fire BULLETs-----
1128 fire_ybullet: ;fire bullet type=C dam=(curweapdamage) at (firex/y)
1129 ld c,a ;save bulletType in c
1130 ld hl,ybullets ;check for unused bullet
1136 jr z,found_ybullet ;0 = no bullet here
1138 dnz find_ybullet ;look next bullet
1139 ret ;none found, return don't fire
1142 ld (hl),c ;use the bullet and set correct bullet-type
1144 ld (hl),1 ;set bullet damage
1146 ld a,(firex) ;your x-pos
1147 add a,5 ;place bullet in front of you
1148 inc hl ;go to bullet-x
1151 ld a,(firey) ;your y-pos
1152 add a,(ix+1) ;place bullet at the middle of your ship
1153 inc hl ;go to bullet-y
1157 ld (weapincs),a ;reset damage
1160 ;------------------------ handle bullets ------------------------------------
1164 and %11111 ;pixels to move
1165 add a,(hl) ;a = X + (hl) to the right
1166 sub 16 ;and 16 to the left (so -16..+15)
1167 jr c,remove_bullet ;remove if x<0
1169 jr nc,remove_bullet ;or x>=128
1170 ld (hl),a ;save new pos.
1175 cal _shracc ;%11110000->1111
1178 jr z,bullet_noymove ;1=straight forward
1180 jr z,bullet_up ;2=up
1182 jr z,bullet_halfup ;3=1/2up
1184 jr z,bullet_down ;4=down
1186 bullet_halfdown: ;5=1/2down
1210 pop hl ;cal bullet_left
1212 ld (hl),0 ;dump this bullet!
1213 jr next_ybullet+1 ;+1:skip pop hl at next_ybullet
1219 psh bc ;bullet counter
1220 psh hl ;save enemy+type
1221 ld (temp1),hl ;needed for check_bullethits
1222 ld a,(hl) ;@bulletType
1227 jp z,next_ybullet ;bulletType=0 >> no bullet
1228 cal bullet_left ;move bullet left
1231 psh de ;save de =position
1234 ld a,(hl) ;bullet damage=size
1235 ld hl,bullettable ;pointer to first bullet
1239 ld e,a ;->16bit (de=a)
1240 add hl,de ;point to correct bullet offset
1241 ld a,(hl) ;load bullet offset
1242 ld e,a ;convert to 16bit (d=0)
1243 ld ix,spr_bullet01 ;first sprite
1244 add ix,de ;add offset (go to correct sprite)
1245 pop de ;saved position
1247 ld a,(ix) ;bullet x-size
1248 ld (bulletxsize),a ;used at check_bullethits
1249 ld a,(ix+1) ;bullet y-size...
1250 ld (bulletysize),a ;...too
1252 cal safeputsprite ;display bullet; DE used for check_bullethits
1254 cal check_bullethits
1257 pop hl ;restore enemy+type
1261 inc hl ;skip type,dam,x,y: next enemy+type
1263 dnz scan_bullets ;next bullet (loop)
1266 ;--------------------------- check bullethits -------------------------------
1268 check_bullethits: ;INPUT: de=X,Y; (temp1)=bullet
1272 hit_enemies: ;Hits with normal enemies
1273 psh bc ;enemy counter
1278 jr z,nohit ;no hit when enemy_occ <> 2/3
1282 or a ;enemy #0 = pickup
1283 jr z,nohit ;yes: don't destroy
1285 cal find_sprite ;set ix to the sprite of this enemy
1289 sub d ;minus bullet x-position
1291 sub 5 ;minus bullet x-size
1295 add a,(ix) ;add enemy width
1300 sub e ;minus bullet y-position
1302 sub 3 ;substract bullet height
1304 jp p,nohit ;nope, missed it
1306 add a,(ix+1) ;add enemy height
1308 jp m,nohit ;missed after all
1310 ;---bullet hits enemy (auch-time!)---
1312 ld hl,0 ;@bulletType
1314 ld (hl),0 ;remove bullet
1316 ld a,(hl) ;set damage
1324 dnz hit_enemies ;check next enemy
1327 enemy_hit: ;*in:a=damage;hl=enemy+y
1328 add a,a ;a=damage to inflict
1329 add a,a ;first 2 bits used for occ.
1335 ld a,(hl) ;load hp00
1336 sub b ;decrease HP (if <0xx then c is set)
1337 ld (hl),a ;save (no flag-changes)
1338 dec hl ;@hp64; no change in c
1339 ld a,(hl) ;load; no c-change
1340 sbc a,0 ;if cf then decrease a
1341 ld (hl),a ;save back the new value
1342 ret nc ;if a>=0 then return, otherwise explode
1344 inc hl ;goto occ again
1345 ld (hl),%01 ;set to explode
1346 ld a,(pickuptimer) ;counts enemies destroyed
1347 dec a ;enough destroyed for a pickup?
1348 jr nz,pickupdone ;otherwise just explode
1349 ld (hl),%110 ;change it into a pickup (with 2 HP)
1350 ld a,18 ;reset enemies counter (18 hits = next)
1352 ld (pickuptimer),a ;save new enemiescounter value
1354 ld (hl),$00 ;explosionFrame 0
1356 ld hl,1 ;increase score by one
1359 ;--------------------------- level events -----------------------------------
1362 ld hl,nextevent ;time to next event <ld a,(nextevent)
1363 dec (hl) ;decrease counter <dec a
1364 ld a,(hl) ;look at counter <ld (nextevent),a
1365 or a ;has it reached zero?
1366 ret nz ;nope: get outta here!
1368 ld bc,0 ;enemy frequency (lvl)
1371 ld (nextevent),a ;set time to next event
1373 dec (hl) ;update enemy-counter
1375 ld a,(hl) ;look at counter
1376 or a ;has it reached 0?
1377 jp z,Next_level ;yes: level finished
1378 dec a ;has it reached 1?
1379 jr z,standby_event ;yes: wait until no enemies present/left
1380 dec a ;has it reached 2?
1381 jr z,place_boss ;yep: place the BigBossTM!
1382 dec a ;has it reached 3?
1383 jr nz,do_event ;nope: >3 = place an enemy
1384 inc hl ;nextevent located behind eventleft
1385 ld (hl),123 ;set delay
1386 ret ;don't place any more enemies
1390 ld hl,enemies+1-enemysize
1395 or a ;0 = no enemy present
1407 ld (nrlvlenemies),a ;just one enemy: the BOSS
1408 ld hl,(levelp) ;the leveldata (including the boss)
1409 dec hl ;points to leveldata\boss\enemynr
1411 ld (lvlenemies),a ;set new enemy (boss)
1414 ld hl,enemies+1-enemysize
1419 cp (hl) ;(hl) = 0 ??
1420 jr nz,chk_noenemy ;jump if enemy present (non-0)
1421 ex de,hl ;de=hl=usable enemy
1423 place_enemy: ;de = enemy+1
1424 ld bc,0 ;0..nrlvlenemies
1425 nrlvlenemies =$-1 ;=nr of enemies minus 1
1426 cal Random ;random enemy b..b+c = 0..nrenemies-1
1430 add hl,bc ;go to a random enemy
1431 ld a,(hl) ;load enemy nr of this mysterious random enemy
1432 cal findenemyspecs ;hl = enemy #a specs
1434 dec de ;goto hp64 (before occ)
1436 ldi ;set hitpoints+occ of enemy class
1437 ld a,(hl) ;save sprite-offset/2 (ldi decs bc so in a)
1442 ld a,(hl) ;load placeInfo
1445 jr z,random_enemy ;yes: create random value <51 in a
1447 jr z,lure_enemy ;yes: create a 100% luring enemy
1449 halflure_enemy: ;yes (of course it is): pick one (50% lure)
1450 ld a,(timer) ;look at frame-number
1451 and %00000001 ;make random if odd frame nr.
1452 jr nz,random_enemy ;1st possibility: random enemy
1453 lure_enemy: ;2nd possibility: luring enemy
1454 ld a,(y) ;place at same y-pos as YOUR ship
1457 ld b,0 ;bc = enemy sprite offset / 2
1458 ld ix,spr_enemy00 ;first enemy sprite
1459 add ix,bc ;add offset for current enemy
1460 add ix,bc ;twice (offset stored as offset/2)
1461 ld a,64-8 ;=57=screen height (8 is scorebar)
1462 sub (ix+1) ;minus sprite height=bottom
1463 ld c,b ;range=0 to...
1465 cal Random ;random value on screen
1466 ypos_OK: ;random value successfully created
1467 ld (de),a ;save y-position
1468 inc de ;@movecounter
1470 ld a,1 ;movecounter = 1
1472 inc de ;@firecounter
1473 ldi ;set time-to-1st-fire
1477 ;--------------------------- enemy fires ------------------------------------
1479 Enemy_fires: ;de = x,y
1489 jr z,found_ebullet ;0 = not used
1490 inc hl \ inc hl \ inc hl
1491 dnz find_ebullet ;look next bullet
1504 ld b,%1011 ;yourY-bulY = negative (=bullet below you)
1507 ld b,%1001 ;yourY-bulY = even more negative (going up)
1512 ld b,%1010 ;bullet going down
1514 jp m,bulletok ;even more going down
1521 ld (hl),a ;set bullet direction
1523 ld (hl),d ;set x-pos
1525 ld (hl),e ;set y-pos
1528 ;----------------------------- enemy bullets --------------------------------
1536 ld a,(hl) ;load bulletType in a
1537 and %1111 ;select direction-bits
1538 jr nz,enemy_bullet ;non-0: handle bullet
1540 pop hl ;do not move the <pop hl>
1542 inc hl \ inc hl \ inc hl
1547 ld b,a ;save type&%1111
1549 ld a,(hl) ;check if it has reached the left side of scrn
1551 jr nz,remove_ebullet ;yes, remove bullet
1552 dec (hl) ;move one left
1553 dec (hl) ;and another one
1557 ld a,b ;restore type
1558 cp %1100 ;is it a normal bullet? (cp = faster than bit)
1559 jr z,ebullet_common ;type %1100: normal bullet
1560 and %111 ;isolate important bits
1561 jr z,ebullet_down ;type %1000: moving down
1563 jr z,ebullet_up ;type %1001: moving up
1572 jr z,ebullet_down ;type %1010: moving down 50%
1573 ;type %1011: moving up 50%
1590 ld ix,spr_bullete1 ;display enemy bullet
1596 jr nz,next_bullet ;0 = you're normal
1616 pop hl ;points to bullettype again
1617 psh hl ;and save it again (ivm call to damage_you)
1618 ld a,(hl) ;load bullettype
1619 cal _shracc ;isolate damage-bits (%1111???? -> %00001111)
1620 ld b,a ;set damage-amount
1621 cal damage_you ;HIT!!
1623 pop hl ;hl could be destroyed by damage_you
1624 ld (hl),0 ;bullet > unused
1625 jr next_bullet+1 ;next bullet (SKIP THE <POP HL> = one byte)
1627 ;--------------------------- handle enemies ---------------------------------
1631 ld b,nrenemies ;handle all enemies
1639 jr z,next_enemy ;occ "no enemy" 0
1641 jr z,exploding_enemy ;occ "exploding" 1
1645 ld c,(hl) ;c = enemy type = de
1659 jr c,enemyonscreenY ;=on screen
1660 cp -20 ;moved off at top
1661 ld e,0 ;reset to top
1662 jr nc,enemyonscreenY
1663 ld e,57 ;otherwise reset to bottom
1665 ld (hl),e ;store new y
1670 jr c,enemyonscreenX ;=on screen
1672 jr c,remove_enemy ;=off screen
1674 ld (hl),d ;store new x
1675 ld a,c ;a = enemy type
1676 or a ;type 0? (pickup)
1677 jr nz,check_enemyfire ;no, a normal enemy; let em fire
1678 ld a,(timer) ;load time
1679 and %1 ;move left once every 2 turns
1680 jr z,firing_done ;don't move now
1681 inc d ;increase x-position (don't move this turn)
1682 inc (hl) ;and save it
1683 jr firing_done ;continue
1690 dec (hl) ;decrease counter till next blast
1691 ld a,(hl) ;&&&doesn't seem efficient to me
1692 or a ;has it reached zero?
1693 jr nz,firing_done ;finished if not
1698 ld (hl),a ;reset counter for next blast
1699 psh de ;save registers for firing-use
1700 cal Enemy_fires ;fires bullet
1701 pop de ;restore (destroyed by Enemy_fires)
1703 cal putwidesprite ;display sprite @ix
1715 ld (hl),$0000 ;bye bye enemy
1716 jr next_enemy+1 ;continue AFTER pop hl (already done)
1722 jr z,remove_enemy ;remove when at last frame
1724 ld (hl),a ;next frame
1726 ld ix,spr_explosion ;base sprite
1727 cal explosion_stuff ;display explosion
1730 ;--------------------------- moving enemies ---------------------------------
1733 ld a,(hl) ;how does this enemy move?
1734 bit 7,a ;direction indicator
1742 res 7,a ;01111111=movetype:
1744 ret z ;0 = don't move
1746 jr z,movetype_updown ;1 = 0 >< up / down
1748 jr z,movetype_vslow ;2 = .75 >>
1750 jr z,movetype_slow ;3 = .5 >>
1752 jr z,movetype_fast ;4 = .5 <<
1754 jr z,movetype_vfast ;5 = 1 <<
1756 jr z,movetype_smart ;6
1758 jr z,movetype_lure ;7 = 1 >> move y towards you
1760 jr z,movetype_slowlure ;8 = 1 >> lure 1/2 speed
1762 ; jr z,movetype_stoplure ;9 = 1 >> slowlure; stop at x=99
1764 ; jr z,movetype_fulllure ;10 = x+y towards you 1/2 speed
1773 ret c ;move left (already did)
1775 inc d ;already moved left, so move right
1782 and 1 ;half the time
1783 jr z,moverightonce ;dont move at all (compensate move left +ret)
1787 jr c,dothelurethingy
1788 inc d ;x<106: full stop
1792 ret z ;don't move if equal
1793 jr c,lure_up ;below you then move up
1794 lure_down: ;above then move down
1802 inc hl ;hl =@ <move>
1811 or a ;reset carry flag
1812 dec hl ;reset hl to <y>
1834 pop hl ;restore stack (no ret used)
1835 jp remove_enemy ;remove this enemy (off screen)
1846 or a ;reset carry flag
1849 ld a,(hl);&&&ld a,e ;load current y-position
1852 moveup: dec a ;decrease y-pos (=move up)
1853 ret m ;don't move off the screen (y<0)
1854 dec e ;save new y-pos
1857 inc a ;increase y-pos
1858 cp 55 ;compare with bottom
1859 ret nc ;return if it has passed that line (>40)
1860 inc e ;otherwise save new position
1863 ;--------------------------- check collision --------------------------------
1866 ld hl,(x) ;e = X, d = Y
1867 ld de,$0707 ;add 7 to both d and e
1870 ld e,l ;e = X+7, d = Y+7
1873 ld b,nrenemies ;check all 20 enemies
1878 jr z,check_next ;2 or 3 = ok
1881 collide_enemy: ;&&& include in Handle_enemy proc
1885 ld a,(hl) ;check x match
1886 sub e ;enemy position minus yours minus 7
1889 add a,(ix) ;enemy width
1893 ld a,(hl) ;check y match
1894 sub d ;same as with x-check
1897 add a,(ix+1) ;enemy height
1904 ld hl,2 ;increase score by 2
1908 ld a,(hl) ;load enemy type
1910 jr nz,collide ;enemy when <>0
1913 ld hl,your_pickup ;your pickups
1918 ld a,1 ;yes: reset to pickup 1
1921 cal disp_icons ;display altered pickupicons
1924 dec hl ;to enemy occ
1925 xor a ;set to 0 = gone
1927 jr check_next ;all done, next..
1930 ld (hl),%01 ;set to explode
1932 ld (hl),0 ;explosionFrame 0
1944 ld b,collidedamage ;damage
1956 ;--------------------------- story ------------------------------------------
1976 ld hl,VIDEO_MEM ;copy text
1977 ld de,dispbuffer ;to GRAPH_MEM
1978 ld bc,1024 ;entire screen
1994 cal storyPage ;do some story
1995 inc hl ;look at next hl
1996 ld a,(hl) ;load in a
1998 inc a ;set z-flag if a = $ff
1999 jr nz,dostory ;otherwise loop
2001 ld bc,2+1 ;story ends
2002 add hl,bc ;set hl to beginning of the level
2003 ld (levelp),hl ;set the level-pointer
2006 ;--------------------------- SFX --------------------------------------------
2008 DoSFX: ;in:a=beginLine;b=nrOfLines
2013 ld a,0 ;get line number
2015 inc a ;go to the next line
2016 ld (curline),a ;update
2023 add hl,hl ;*16 (a pixels down=a*16)
2025 ld b,h ;save hl for later
2028 ld de,VIDEO_MEM ;where to put sfx
2029 add hl,de ;go to ymin
2030 ex de,hl ;put into de again
2036 neg ;a=64-a (lines from bottom)
2038 ; ld c,a ;c=a=(curline)
2040 ; sub c ;lines from bottom
2042 SFXdisp: ;display this frame on screen
2043 ld bc,16 ;one line (=16 bytes, you'd know by now)
2044 ldir ;display (copy actually)
2045 ld bc,-16 ;go up one line (not on screen)
2046 add hl,bc ;so the same line will be displayed
2048 jr nz,SFXdisp ;repeat until whole screen is displayed
2059 ;--------------------------- show icon --------------------------------------
2062 ld (hl),a ;draw one piece of the divider-line
2063 inc hl ;move right (8 pixels = 1 byte)
2064 dnz drawline ;repeat (16bytes * 8pixels =128= screen width)
2068 psh bc \ psh de \ psh hl \ psh ix ;&&&
2070 ld hl,VIDEO_MEM+(16*56);56 rows down = eight rows from bottom
2071 ld (PutWhere),hl ;place icons at bottom of normal screen
2072 ld b,16 ;draw 16x (screen width)
2073 ld a,%11111111 ;horizontal line mask
2074 cal drawline ;draw divider-line
2076 ld b,16*7 ;draw 16x (screen width) 7x (height)
2077 xor a ;blank line mask
2078 cal drawline ;clear scorebar
2082 ld a,(your_lives) ;nr of lives
2084 jr z,displivesdone ;no lives
2089 cal safeputsprite ;put li'l ship
2094 dnz displivesloop ;one ship per life
2097 ld ix,spr_icon01 ;armorIcon
2098 ld de,$1901 ;icon #1
2099 cal putwidesprite ;display icon
2100 cal disp_armor ;display bar
2103 ld a,(your_weapon) ;ur weapon
2104 cp maxweapon ;laser?
2105 psh af ;(your_weapon)
2106 jr nc,no_tail ;if laser (nc) then tail ain't fired
2110 ld ix,spr_icon02 ;tailbeamIcon
2112 ld de,$2901 ;icon #2
2113 cal putwidesprite ;display
2116 pop af ;a=(your_weapon); cf=bullets
2118 jr nc,no_bullets ;=laser
2119 ld hl,$3945 ;position to display bullet-type digit
2120 pop af ;digit=(your_weapon)
2122 inc a ;1 = weapon #1 (=0)
2123 ld (_penCol),hl ;set location
2124 add a,'0' ;make digit
2125 cal _vputmap ;display char
2126 ld ix,spr_icon03 ;bulletIcon
2128 ld de,$3901 ;icon #3
2129 cal putwidesprite ;display icon
2131 ld ix,spr_icon00 ;emptyIcon
2132 pop af ;ld a,(your_weapon)
2134 jr c,no_laser ;popped carry
2135 ld hl,$3955 ;position to display bullet-type digit
2136 ld (_penCol),hl ;set location
2137 ld a,b ;(your_weapon) ;load = faster than push
2138 sub maxweapon-1 ;1 = laser #1 (=maxweapon)
2139 add a,'0' ;make digit
2140 cal _vputmap ;display char
2141 ld ix,spr_icon04 ;laserIcon
2143 ld de,$4901 ;icon #4
2146 ld ix,spr_icon00 ;emptyIcon
2147 ld a,(your_multiples)
2152 ld de,$5901 ;icon #5
2155 ld ix,spr_dividerline
2159 ld a,(your_pickup) ;pickups taken
2160 add a,a ;picks*2 (sets z-flag)
2161 jr z,iconsdone ;return if no pickups
2166 ld d,a ;y-pos = picks * $10 + $0a (19,29,39,49,59)
2167 ld e,$01 ;x-pos = bottom (1a01,2a01,3a01,4a01,5a01)
2172 ld hl,dispbuffer ;normal game-screen
2173 ld (PutWhere),hl ;set sprite-position to normal screen
2175 pop ix \ pop hl \ pop de \ pop bc
2180 ld hl,(57*16)+VIDEO_MEM+3
2190 ld a,(your_armor) ;load your armor (<25)
2194 srl a ;/8: don't display last 3 bits of a (later)
2195 jr z,noarmorbar ;if a=0 then it would loop 256x so skip it
2196 ld b,a ;loop b=a times
2197 armorbar: ;starting at ($39*16)+VIDEO_MEM
2198 ld (hl),%11111111 ;draw a piece of the bar
2199 add hl,de ;one down (resets carry)
2200 ld (hl),%11111111 ;same piece
2202 inc hl ;next position
2203 dnz armorbar ;loop it b times
2207 and %111 ;display last bits of armor
2208 ret z ;if armor=0 then bit = %00000000 (don't disp)
2210 xor a ;bit = %00000000
2213 rra ;rotates A right and sets bit 7 (c-flag)
2214 dnz armorbarbit ;repeat B times (so if B=6 then a=%11111100)
2215 armorbarready: ; (an if B=3 then a=%11100000)
2216 ld (hl),a ;draw this last byte
2218 ld (hl),a ;and just below
2222 ld hl,(59*16)+VIDEO_MEM+3
2229 ld a,(weapincs) ;load bar size (0-80)
2230 srl a ;half the size (0-40)
2231 srl a ;again half that size (0-20 pixels)
2235 srl a ;/8: don't display last 3 bits of a (later)
2236 jr z,nochargebar ;if a=0 then it would loop 256x so skip it
2237 ld b,a ;loop b=a times
2238 chargebar: ;starting at ($39*16)+VIDEO_MEM
2239 ld (hl),%11111111 ;draw a piece of the bar
2240 inc hl ;next position
2241 dnz chargebar ;loop it b times
2244 and %111 ;display last bits of chargebar
2245 ret z ;if armor=0 then bit = %00000000 (don't disp)
2247 xor a ;bit = %00000000
2250 rra ;rotates A right and sets bit 7 (c-flag)
2251 dnz chargebarbit ;repeat B times (so if B=6 then a=%11111100)
2252 chargebarready: ; (an if B=3 then a=%11100000)
2253 ld (hl),a ;draw this last byte
2256 ;--------------------------- proc -------------------------------------------
2258 Random: ;a=c<random<b+c; destr:none
2260 ld hl,rancount ;amount to increase with (0-255)
2262 inc (hl) ;change for next time
2263 ld a,r ;value $0-7F (can be _anything_ so watch out!)
2264 add a,0 ;add to last random value
2265 ranseed =$-1 ;SMC :P
2266 add a,(hl) ;add the changing increase value
2267 ;(this is because R can be anything;
2268 ; ie always be even so freeze when a must be 1<=a<=1)
2269 ld (ranseed),a ;save for next time
2271 jr nc,randomloop ;then add again
2277 RandomY: ;HL = random Y 0..50 right side ((1..51)*16-1)
2279 ld bc,50*256+1 ;range=1..51
2280 cal Random ;a = 1..51
2286 add hl,hl ;hl = 1..51 * 16 (left side at random y)
2287 dec hl ;hl = 0..50 * 16 (" at right side of screen)
2289 add hl,de ;position on screen
2301 find_sprite: ;in:hl=enemy+type | out:ix=sprite to enemy
2304 ld e,(hl) ;e = enemy offset/2
2306 ld ix,spr_enemy00 ;first enemy sprite
2307 add ix,de ;add offset for current enemy
2308 add ix,de ;twice (offset stored as offset/2)
2314 ld hl,VIDEO_MEM ;screen location (top left)
2317 ld bc,1024-1 ;do it 1024 times = entire screen
2319 set 3,(iy+5) ;set white on black
2324 ld a,%10000000 ;all key-masks
2327 inc a ;cp %11111111 (no keys pressed)
2328 jr nz,releasekeys ;keep waitin
2329 cal GET_KEY ;clear buffer
2332 findenemyspecs: ;enemy #a specs in (hl); in:b=0; out:ac=?
2333 ld hl,enemyspecs-8 ;enemy "0" specs (1 before enemy #1)
2337 ld c,a ;b=0; c=bc=type*8
2338 add hl,bc ;hl = enemy specs
2341 ;--------------------------- game over / new game / death -------------------
2343 .db 0,".<>!",0,0,0,0 ;down,L,R,up
2344 .db 0,"xtoje0",0 ;enter..clear
2345 .db " wsnid9",0 ;(-)..custom
2346 .db "zvrmhc8",0 ;dot..del
2347 .db "yuqlgb7#" ;0..xvar
2348 .db $D9,"-pkfa6'" ;on..alpha
2349 .db "54321*",0,$D0 ;F5..more
2352 ld hl,_asapvar ;find own variable
2353 rst 20h ;cal _ABS_MOV10TOOP1
2354 rst 10h ;cal _FINDSYM
2357 ld hl,4+storehi_start-_asm_exec_ram
2358 add hl,de ;hl=pointer to data in original prog
2360 cal _SET_ABS_DEST_ADDR
2363 cal _SET_ABS_SRC_ADDR
2364 ld hl,storehi_end-storehi_start
2365 cal _SET_MM_NUM_BYTES
2366 cal _mm_ldir ;save done (cal \ ret)
2370 ld hl,_asapvar ;find own variable
2371 rst 20h ;cal _ABS_MOV10TOOP1
2372 rst 10h ;cal _FINDSYM
2375 ld hl,4+storesave_start-_asm_exec_ram
2376 add hl,de ;hl=pointer to data in original prog
2378 cal _SET_ABS_DEST_ADDR
2380 ld hl,storesave_start
2381 cal _SET_ABS_SRC_ADDR
2382 ld hl,storesave_end-storesave_start
2383 cal _SET_MM_NUM_BYTES
2384 cal _mm_ldir ;save done (cal \ ret)
2387 game_over: ;stack=+0
2388 cal BLACKLCD ;clear screen
2390 ld (_curRow),hl ;center
2392 cal _puts ;display "GAME OVER"
2393 cal releasekeys ;wait for all keys to be released
2474 xor a ;clear a (Ahl will be displayed)
2475 ld hl,$1006 ;bottom-1 right
2476 ld (_curRow),hl ;set
2477 ld hl,(your_score) ;your score
2478 cal _dispahl ;display it (a=0)
2480 ld hl,$314b ;bottom-1 right before score ^^
2481 ld (_penCol),hl ;set
2482 ld hl,txt_score ;"Score"
2483 cal _vputs ;display (small)
2485 ld hl,$1007 ;bottom right
2486 ld (_curRow),hl ;set
2487 ld hl,(hiscore) ;hi-score
2488 cal _dispahl ;display
2489 ld hl,$3946 ;bottom right before hiscore ^^
2490 ld (_penCol),hl ;set
2491 ld hl,txt_hiscore ;"Hiscore"
2492 cal _vputs ;display (small)
2497 ld hl,VIDEO_MEM+(49*16)-1
2503 cal _getkey ;wait for keypress
2504 jp quit ;restore some things and return to TI-OS/shell
2506 invship: ;procedure used in New_game
2510 ld hl,VIDEO_MEM+$30-$C0;begin pos
2514 ld b,$B0 ;12 lines down
2520 dnz invshiploop ;loop
2524 New_game: ;stack must be +1 (so change the jp in cal :)
2527 ld (PutWhere),hl ;will be reset after displaying iconbar
2528 ld ix,spr_ship01 ;first ship: sprite
2529 ld de,$0105 ;position
2530 ld b,4 ;number of ships to display
2534 cal putwidesprite ;display
2536 ld bc,spr_ship01i-spr_ship01+2
2537 add ix,bc ;go to next ship
2538 ld a,12 ;below the previous one
2542 dnz dispshipsloop ;loop
2558 jr z,startthenewgame
2560 jr z,startthenewgame
2575 ld hl,spr_ship01-(spr_ship02-spr_ship01)
2576 ld de,spr_ship02-spr_ship01
2577 inc b ;your ship #0-3++
2579 add hl,de ;next ship
2583 ld (your_score),a ;reset score
2584 ld (your_score+1),a ;reset score (0)
2585 ld (your_tail),a ;no tail beam
2586 ld (your_weapon),a ;no laser
2587 ld (your_pickup),a ;reset pickups
2588 ld (your_multiples),a ;no multiples
2590 ld (level),a ;reset level nr (#1)
2591 ld hl,level00 ;set level pointer to level#1
2592 ld (levelp),hl ;reset level pointer
2594 ld (your_lives),a ;3 lives (4 will be decreased @ You_die)
2595 ld (pickuptimer),a ;next pickup after 4 enemies destroyed
2597 You_die: ;stack must be +1
2598 pop hl ;restore stack
2600 ld (your_armor),a ;12 HPs/shields
2601 ld a,(your_lives) ;load lives left
2602 dec a ;decrease lives
2603 ld (your_lives),a ;if lives=0ffh GO
2604 inc a ;if -1 then zf set now
2605 jp z,game_over ;and game's over
2608 ;--------------------------- next level -------------------------------------
2610 Next_level: ;stack must be +1
2613 cal inc_armor ;increase armor
2614 ld hl,level ;level number
2621 ld h,0 ;increase score....
2622 ld l,a ;by level number * 4
2625 cal scoreInc ;update score
2627 ld hl,(levelp) ;level pointer
2628 ld b,0 ;advance one level
2630 add hl,bc ;passed the enemies
2632 add hl,bc ;update to point to next level
2633 ld (levelp),hl ;save
2637 ld (your_shipspr),hl
2640 ld (nextevent),a ;time to first enemy appearance
2642 ld hl,(levelp) ;level pointer
2647 ld a,(hl) ;number of (different) enemies in this level
2650 ld (nrlvlenemies),a ;set nr of enemies-1
2651 ld b,0 ;bc=c so we can use ldir
2652 ld de,lvlenemies ;table of enemies
2653 ldir ;load enemies to table
2654 ld a,(hl) ;load new appearance-time
2658 ld (eventtime+1),a ;set
2660 ld a,(hl) ;load nr of enemies in this level
2661 ld (eventleft),a ;set nr of events left
2666 ld a,(hl) ;movement of enemies in this level
2667 ld (level_move),a ;do it
2682 ld (timer),a ;reset time
2683 ld hl,your_occ ;hl = your_occ
2684 ld (hl),a ;reset your ship (not exploding)
2685 inc hl ;hl = your_inv
2686 ld (hl),25 ;set 25*4=100 frames invulnerable
2688 ld (x),de ;begin position (x,y)
2689 cal Place_multiples ;place all multiple-positions at that (0,24)
2691 cal loadweapon ;load (your_weapon)
2693 ld hl,enemies ;remove all enemies and bullets
2694 ld (hl),0 ;clear first byte
2695 ld de,enemies+1 ;copy this to the next byte
2696 ld bc,(nrenemies*enemysize)+(nrybuls*4)+(nrebuls*3)-1
2697 ldir ;clear enemies + bullets (y/e)
2699 ;--------------------------- setup game -------------------------------------
2702 cal BLACKLCD ;white on black
2705 ld (_curRow),de ;center
2706 cal _puts ;display "LEVEL "
2708 ld a,(level) ;current level
2711 cal UNPACK_HL ;create first digit
2714 cal UNPACK_HL ;second digit
2716 cal _putc ;display second digit
2718 cal _putmap ;display first digit
2720 ld hl,txt_lives ;bar text: "Lx0"...
2722 ld (_curRow),de ;display lives left below level nr
2724 ld a,(your_lives) ;lives left
2725 add a,'0' ;make value 0='0'
2728 cal releasekeys ;wait for user to release all keys
2729 ld hl,txt_savekey ;"Press [F1] to save"
2730 ld de,$3A46 ;bottom-right
2734 res 3,(iy+5) ;set white on black
2735 cal _getkey ;wait for keypress
2739 cal _clrLCD ;clear screen
2740 cal disp_icons ;display bottom icons +ret
2744 cal RandomY ;a = random y-pos 1..bottom
2745 ld a,b ;a = b = star nr. = 1..7
2746 add a,a ;a = 2b = 2..14
2748 ld e,a ;de = a = 2-14
2750 sbc hl,de ;substract from random y => random pos anywhere
2752 ld (ix),l ;save x-pos (l)
2753 ld (ix+1),h ;save y-pos (h)
2754 inc ix \ inc ix ;next star
2755 dnz placestars ;repeat for all stars
2768 ld (weapdamage),a ;damage of bullets
2771 ld (weapdaminc),a ;damage increase
2774 ;----------------------------------------------------------------------------
2775 ;--------------------------- putsprite --------------------------------------
2776 ;----------------------------------------------------------------------------
2777 ;in: de=(x,y); ix=sprite
2778 ;out: ix=behind sprite; hl:a=right below sprite; b=0; d=width; ce=?
2781 ld c,(ix) ;save width
2782 _putsprite: ;putsprite with custom width
2784 bit 7,d ;check sign bit of X
2785 jr z,CSpositive ;X>=0
2788 cp (ix) ;off screen?
2789 ret nc ;X<=-width: don't draw at all
2790 ld b,a ;b=|X|mod 8=1..7=bits to draw
2791 ld a,%11111111 ;all bits set (draw everything)
2793 srl a ;remove first bit in a for each b
2794 dnz CSclipleft ;b=1: a=%01111111
2801 res 7,d ;X+128 (right side of screen)
2803 jr CSdisplay ;done clipping
2806 sub 129-8 ;minus (screen width - byte width)
2808 ld a,%11111111 ;clipmask
2809 jr c,CSdisplay ;x+width<128 then entire sprite is on screen
2810 inc b ;b = number of pixels off screen
2812 add a,a ;remove last bit in a for each b
2813 dnz CSclipright ;b=1: a=%11111110
2820 ;b>7: a=%00000000 = off screen
2822 CSdisplay: ;display the sprite ix at (d,e) masked
2823 ld (CSclipmask),a ;set mask
2824 cal findpixel ;convert de to screen location hl:a
2830 psh bc ;save rows to go
2833 ld a,(ix+2) ;load image line
2839 ld a,1 ;saved bitmask
2841 sla c ;test leftmost pixel
2842 jr nc,CSnodraw ;don't draw if it's 0
2843 ld e,a ;psh af: save bitmask
2845 ld (hl),a ;OR pixel with screen
2849 jr nc,CSbitdrawn ;carry set if bit "jumped"
2853 pop hl ;screen at x-offset=0
2855 add hl,bc ;next line
2856 pop bc ;rows counter
2860 ;--------------------------- putbigsprite -----------------------------------
2863 ;destr: abcdehl+ix (ix=behind sprite; hl:a=right below sprite; b=0; d=width)
2866 jr c,putsprite ;width<=8: just draw the sprite
2873 cal _putsprite ;otherwise draw one column (8 pixels wide)
2875 inc ix ;no x-size to load
2877 add a,d ;8 pixels right
2879 pop bc ;then draw the remaining pixels (c=width-8)
2883 safeputsprite: ;cal putsprite with de intact
2889 ;------------------------------- findpixel ----------------------------------
2890 ;based upon CLEM's fp | 131 cycles | 28 bytes | in:(d,e); out:hla; destr:de
2895 add a,a ;add a,a is 7 cycles faster than add hl,hl
2896 ld h,0 ;switch to hl now (Y<64)
2899 rra ;RRA: carry flag must be reset!
2900 add hl,hl ;that's what the adds are for :P
2916 ld de,dispbuffer ;screen base position (where x+y=0)
2921 ;----------------------------------------------------------------------------
2922 ;------------------------------- sprites ------------------------------------
2923 ;----------------------------------------------------------------------------
2926 .db 7,7 ;ship alpha class
2929 .db %01111110 ; ██████
2930 .db %11101000 ;███ █
2931 .db %01111110 ; ██████
2937 .db %11110001 ;████ █
2938 .db %01111111 ; ███████
2939 .db %11101001 ;███ █ █
2940 .db %01111111 ; ███████
2941 .db %11110001 ;████ █
2945 .db 7,7 ;ship beta class
2947 .db %11111000 ;█████
2948 .db %01111100 ; █████
2949 .db %01110010 ; ███ █
2950 .db %01111100 ; █████
2951 .db %11111000 ;█████
2955 .db %11100010 ;███ █
2956 .db %11111001 ;█████ █
2957 .db %01111101 ; █████ █
2958 .db %01110011 ; ███ ██
2959 .db %01111101 ; █████ █
2960 .db %11111001 ;█████ █
2961 .db %11100010 ;███ █
2964 .db 7,7 ;ship gamma class
2965 .db %11111000 ;█████
2967 .db %11111100 ;██████
2968 .db %11100110 ;███ ██
2969 .db %11111100 ;██████
2971 .db %11111000 ;█████
2974 .db %11111010 ;█████ █
2975 .db %01100001 ; ██ █
2976 .db %11111101 ;██████ █
2977 .db %11100111 ;███ ███
2978 .db %11111101 ;██████ █
2979 .db %01100001 ; ██ █
2980 .db %11111010 ;█████ █
2983 .db 7,7 ;ship delta class
2985 .db %11110000 ; ████
2986 .db %11111100 ; ██████
2987 .db %01100010 ; ██ █
2988 .db %11111100 ; ██████
2989 .db %11110000 ; ████
2993 .db %11000010 ; ██ █
2994 .db %11110001 ; ████ █
2995 .db %11111101 ; ██████ █
2996 .db %01100011 ; ██ ██
2997 .db %11111101 ; ██████ █
2998 .db %11110001 ; ████ █
2999 .db %11000010 ; ██ █
3003 .db %01111000 ; ████
3004 .db %11001100 ; ██ ██
3006 .db %11001100 ; ██ ██
3007 .db %01111000 ; ████
3009 ;-------------------------------- explosions --------------------------------
3015 .db %00111110 ; █████
3016 .db %01010110 ; █ █ ██
3022 .db %01001110 ; █ ▒███
3023 .db %10111110 ; █ █████
3024 .db %01001111 ; █ ▒████
3026 .db %00011010 ; ██ █
3029 .db %10110000 ; █ ██
3030 .db %01001110 ; █ ███
3031 .db %10110101 ; █ ██▒█▒█
3032 .db %01000101 ; █ ▒█▒█
3033 .db %00111110 ; █████
3034 .db %01011010 ; █ ██ █
3037 .db %00101010 ; ▒ █▒█ █
3038 .db %01000110 ; █ ▒██
3039 .db %10110101 ; █ ██ █ █
3040 .db %01100110 ; ██ ██▒
3041 .db %00111100 ; ████▒
3042 .db %01011001 ; █ ██ ▒█
3045 .db %01000000 ; █▒ ▒ ▒
3046 .db %00100101 ; ▒█ █▒█
3047 .db %00010100 ; ▒ ▒█ █ ▒
3048 .db %01000100 ; █▒ █
3049 .db %00010010 ; ▒█▒▒█
3050 .db %10011010 ; █▒ ██ █▒
3054 .db %00100000 ; ▒█ ▒ ▒
3055 .db %00000001 ; ▒ ▒ █
3057 .db %00100010 ; █▒ █
3058 .db %01001000 ; ▒█ ▒█ ▒
3061 .db %00001000 ; ▒ █▒
3062 .db %11000010 ; ██ ▒ █
3064 .db %00100000 ; ▒█ ▒
3065 .db %00000001 ; ▒ ▒█
3066 .db %00110000 ; ▒██▒
3070 .db %00000000 ; ▒▒ ▒
3074 .db %00100100 ; █▒ █
3079 .db %00101100 ; █ ██
3080 .db %00011110 ; ████
3081 .db %00110100 ; ██ █
3087 .db %01011100 ; █ ███
3088 .db %10010111 ;█ █ ███
3089 .db %01000110 ; █ ██
3094 .db %00111100 ; ████
3095 .db %01001111 ; █ ████
3096 .db %10100011 ;█ █ ██
3097 .db %11000110 ;██ ██
3098 .db %01110101 ; ███ █ █
3102 .db %00110110 ; ██ ██
3105 .db %01100001 ; ██ █
3107 .db %01010001 ; █ █ █
3109 ;--------------------------------- bullets ----------------------------------
3116 .db %11110000 ;▒████
3128 .db %11110000 ;▒████
3133 .db %11111000 ;▒█████
3137 .db %01110000 ; ▒███
3138 .db %11111000 ;▒█████
3139 .db %01110000 ; ▒███
3142 .db %11110000 ;▒████
3143 .db %11111000 ;▒█████
3144 .db %11110000 ;▒████
3148 .db %10111000 ;▒█▒███
3149 .db %01111000 ; ▒████
3153 .db %00111000 ; ▒███
3154 .db %01111100 ; ▒█████
3155 .db %11111100 ;▒██████
3160 .db %11111100 ;▒██████
3161 .db %00111110 ; ▒█████
3162 .db %01111100 ; ▒█████
3167 .db %11111100 ;▒██████
3168 .db %00111110 ; ▒█████
3169 .db %01111110 ; ▒██████
3170 .db %11111100 ;▒██████
3171 .db %00111000 ; ▒███
3174 .db %00111100 ; ▒████
3175 .db %11111110 ;▒███████
3176 .db %01111111 ; ▒███████
3177 .db %00011111 ; ▒█████
3178 .db %01111111 ; ▒███████
3179 .db %11111110 ;▒███████
3180 .db %00111100 ; ▒████
3184 .db %11110000 ; ████
3188 .db 4,3 ;enemy bullets
3190 .db %11110000 ;████▒
3194 .db (spr_bullet01-spr_bullet01) ;0
3195 .db (spr_bullet02-spr_bullet01) ;4
3196 .db (spr_bullet03-spr_bullet01) ;8
3197 .db (spr_bullet04-spr_bullet01) ;12
3198 .db (spr_bullet05-spr_bullet01) ;16
3199 .db (spr_bullet06-spr_bullet01) ;20
3200 .db (spr_bullet07-spr_bullet01) ;24
3201 .db (spr_bullet08-spr_bullet01) ;28
3202 .db (spr_bullet09-spr_bullet01) ;32
3203 .db (spr_bullet10-spr_bullet01) ;36
3204 .db (spr_bullet11-spr_bullet01) ;40
3205 .db (spr_bullet12-spr_bullet01) ;44
3206 .db (spr_bullet13-spr_bullet01) ;48
3207 .db (spr_bullet13-spr_bullet01) ;52
3208 .db (spr_bullet13-spr_bullet01) ;56
3209 .db (spr_bullet13-spr_bullet01) ;60
3211 ;format:[min.damage] [dam.inc] [000:direction 00000:speed] [offset]
3212 ;damage = min.damage + dam.inc*incs (0<=incs<=6)
3213 ;speed in pixels/frame (>=%10010=forward; <=%01110=backwards)
3214 ;direction: 0=straight forward; 1=up; 2=1/2up; 3=down; 4=1/2down
3218 .db 1,1,%00000000,0,%00000000,0,%00010010,3 ;1 single fire
3219 .db 4,1,%00000000,0,%00000000,0,%00010011,3 ;2 fast single
3220 .db 1,1,%00000000,0,%00010010,0,%00010010,6 ;3 double
3221 .db 1,1,%01110010,2,%10010010,2,%00110010,2 ;4 triple
3222 .db 3,2,%01110011,2,%10010011,2,%00110011,2 ;5
3223 .db 5,3,%01110011,2,%10010100,2,%00110011,2 ;6
3224 .db 7,4,%01110100,2,%10010100,2,%00110100,2 ;7
3225 .db 12,5,%01110110,2,%10010110,2,%00110110,2 ;8
3227 .db 1,1,%00000000,0,%00000000,0,%11100000,3 ;1 single laser
3228 .db 1,1,%00000000,0,%11100000,0,%11100000,6 ;2 double laser
3229 .db 1,1,%11100000,0,%11100000,6,%11100000,3 ;3 triple laser
3234 ;------------------------------------ bar -----------------------------------
3237 .db 5,3 ;li'l ship indicating lives left
3239 .db %01111000 ; ████
3241 lshipsize = 5 ;space between two ship icons
3244 .db 16,7 ;selected.......:.......:
3245 .db %11111111 ;████████████████
3251 .db %11111111 ;████████████████
3261 .db 16,7 ;unused .......:.......:
3262 .db %10101010 ;█ █ █ █ █ █ █ █
3263 .db %11010101 ;██ █ █ █ █ █ █ █
3264 .db %10101010 ;█ █ █ █ █ █ █ █
3265 .db %11010101 ;██ █ █ █ █ █ █ █
3266 .db %10101010 ;█ █ █ █ █ █ █ █
3267 .db %11010101 ;██ █ █ █ █ █ █ █
3268 .db %10101010 ;█ █ █ █ █ █ █ █
3278 .db 16,7 ;armor ;.......:.......:
3279 .db %10000111 ;█ ███████ ▒
3280 .db %10011000 ;█ ██ ██ ▒
3281 .db %10110011 ;█ ██ ████ ██ ▒
3282 .db %10110000 ;█ ██ ████ ██ ▒
3283 .db %10110011 ;█ ██ ████ ██ ▒
3284 .db %10011000 ;█ ██ ██ ▒
3285 .db %10000111 ;█ ███████ ▒
3295 .db 16,7 ;tailbeam.......:.......:
3297 .db %10000011 ;█ ██ ▒
3298 .db %10000001 ;█ ███ ▒
3299 .db %10111011 ;█ ███ ██████ ██▒
3300 .db %10000001 ;█ ███ ▒
3301 .db %10000011 ;█ ██ ▒
3312 .db 16,7 ;torpedo .......:.......:
3313 .db %10111000 ;█ ███ █ █ █▒
3314 .db %10011100 ;█ ███ █ █ █▒
3315 .db %10111000 ;█ ███ █ █ █ ▒
3316 .db %10000000 ;█ ███ █ █ ▒
3317 .db %11100001 ;███ ████ █ █▒
3318 .db %10011000 ;█ ██ ████ █ █▒
3319 .db %11100110 ;███ ██ ██ █ ▒
3329 .db 16,7 ;bullets .......:.......:
3330 .db %10000000 ;█ ██ ▒
3331 .db %10000011 ;█ █████ ▒▒▒ ▒
3332 .db %10011000 ;█ ██ ██ ▒▒▒ ▒
3333 .db %11111100 ;██████ ▒▒▒ ▒
3334 .db %10011000 ;█ ██ ██ ▒▒▒ ▒
3335 .db %10000011 ;█ █████ ▒▒▒ ▒
3336 .db %10000000 ;█ ██ ▒
3346 .db 16,7 ;laser .......:.......:
3348 .db %10001010 ;█ █ █ ▒▒▒ ▒
3349 .db %11101100 ;███ ██ ▒▒▒ ▒
3350 .db %11110111 ;████ ███████▒▒▒█▒
3351 .db %11101100 ;███ ██ ▒▒▒ ▒
3352 .db %10001010 ;█ █ █ ▒▒▒ ▒
3363 .db 16,7 ;multiple.......:.......:
3364 .db %10000011 ;█ ███ ▒
3365 .db %10000001 ;█ ████ ██ ▒
3366 .db %10000001 ;█ ████ ▒
3367 .db %10000011 ;█ ███ ▒
3368 .db %10011000 ;█ ██ ▒
3369 .db %10111100 ;█ ████ ██ ██▒
3370 .db %10011000 ;█ ██ ▒
3381 .db 128,128,128,128,128,128,128 ;128 = %10000000
3383 ;---------------------------- texts -----------------------------------------
3385 txt_email: .db "www.shiar.org ",127 ;title screen
3386 .db " shiar0@hotmail.com",0
3387 _txt_email = $3A01 ;$3A1E=just email
3388 txt_about: .db "v0.98.77 ",127," by Shiar",0 ;right behind txt_email
3390 txt_menu1: .db "NEW GAME",0
3391 txt_menu2: .db "CONTINUE",0
3393 txt_level: .db "LEVEL ",0 ;new level screen
3394 txt_lives: .db "Lx0",0
3395 txt_savekey: .db "Press [F1] to save",0
3397 txt_gameover: .db "GAME OVER!",0 ;game over screen
3398 txt_score: .db "Score",0
3399 txt_hiscore: .db "Hiscore",0
3401 txt_pressenter: .db "Enter to continue",0 ;pause
3402 txt_teacher: .db "(2",Lpi,"*.98)/sin 13",0 ;teacher
3403 txt_teacherans: .db Lneg,"14.6549373495",0
3405 ;---------------------------- save data -------------------------------------
3408 hiscore .dw 0 ;default hiscore
3409 hiname .db "shiar.98",0 ; " " name
3412 storesave_start: ;--SAVED GAME-- defs:
3413 level .db 1 ;level number 1
3414 levelp .dw level01 ;pointer to level data l01
3415 pickuptimer .db 4 ;counts when to place a pickup 4
3416 your_ship .dw spr_ship01 ;your sprite sprs1
3417 your_score .dw 0 ;current score 0
3418 your_pickup .db 0 ;pickups already picked up 0
3419 your_occ .db 0 ;0=normal 1..16=exploding 0
3420 your_inv .db 0 ;invincibility left 0
3421 your_armor .db 12 ;HP left 12
3422 your_lives .db 3 ;lives left 3
3423 your_weapon .db 0 ;current weapon upgrade 0
3424 your_multiples .db 0 ;multiples present 0
3425 your_tail .db 0 ;tail beam present 0
3428 time2invert: .db 0 ;time until b<>w switch (0 at startup)
3430 ;------------------------------ levels data ---------------------------------
3432 ;format:boss: [moveType] [enemyType]
3433 ; @level: [nr.dif.enemies]x [enemy nr]
3434 ; [min. enemy frequency] [enemy frequency max.inc] [next lvl]
3435 ; [level_info: 0000:damage 0:diagfire 0:ground 0:ceiling 0:?]
3436 ; [level_move] [tunnel size] [groundtype]
3437 ; [16_ground] [16_ceiling] [stars1] [stars2]
3438 ;efrequency must be odd if halfluring!
3441 .db 0 ;story identifier
3442 .db $21,$1d,"Cosmic year 6716" ,0,0,$1d,$06
3443 .db $1b,$1d,"STORYLINE COMING SOON" ,0,0,$1d,$06
3444 .db $09,$19,"STORYLINE COMING SOON" ,0,1
3445 .db $2e,$21,"**** NEMESIS 86" ,0,1
3446 .db $52,$36,"by Shiar" ,0,0,$19,$23
3449 .db 20 ;boss for level01
3450 level01: ;intro-like, just a few enemies to begin with
3452 .db 26,70,20,%00010000,0,0,0
3453 .db 1,2,3,4,5,6,6,5,4,3,4,5,4,5,6,5
3454 .db 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
3458 level02: ;first wave of enemies; easeey
3460 .db 20,60,60,%00100000,0,0,0
3461 .db 1,2,3,4,5,6,6,5,4,3,4,5,4,5,6,5
3462 .db 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
3466 level03: ;some more enemies
3468 .db 17,40,75,%00110000,0,0,0
3469 .db 1,2,3,4,5,6,6,5,4,3,4,5,4,5,6,5
3470 .db 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
3473 .db 0,0 ;storyline ID
3474 .db 1,1,"Long-Range scanners are ",
3476 .db 1,8,"lots of enemy vessels on ",
3477 .db "an intercept",0,1
3478 .db 1,15,"course.",0,1
3479 .db 1,24,"I'm changing course to a",
3481 .db 1,31,"asteroid belt and try to",0,1
3482 .db 1,38,"lose them inthere.",0,0
3486 level04: ;light asteroid belt
3488 .db 12,24,80,%00111000
3490 .db 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 ;16
3491 .db 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
3495 level05: ;inside asteroid belt
3497 .db 6,10,180,%01011000
3499 .db 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 ;16
3500 .db 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
3506 .db 30,1,40,%01000000
3508 .db 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 ;16
3509 .db 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
3515 .db $01,01,"And the storyline conti",
3517 .db $01,09,"You decide to fly close",
3519 .db $01,15,"surface of a nearby pl",
3520 .db "anet =)",0,0,1,20
3526 .db $13,40,$4b,%00100100,0,-5,1
3527 .db 1,2,3,4,5,6,6,5,4,3,4,5,4,5,6,5
3528 .db 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
3534 .db $01,01,"Blablabla...",0,1
3535 .db $01,34,"this storyline sux",0,0,1,39
3541 .db $2d,$3f,%00010110,0,-9,1
3542 .db 3,2,4,3,2,2,1,1,1,1 ,1,1,21,17,18,20
3543 .db 1,1,1,1,1,1,1,3,6,12,9,1,21,19,18,18
3544 .db -1,-1 ;=%11111111=line
3549 .db $11,$41,%00100001,0,0,0
3550 .db 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
3551 .db 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
3556 .db $11,$45,%00100101,%10,-7,1
3557 .db 14,12,11,9,10,7,7,5,4,3,4,4,2,3,1,2
3558 .db 1, 1, 1, 1,1, 1,1,1,1,1,1,1,1,1,1,1
3563 .db $19,$3a,%00100111,0,-4,1
3564 .db 20,22,18,15,9,1,1,1,1,1,1,1,1,1,1,1
3565 .db 20,22,18,15,9,1,1,1,1,1,1,1,1,1,1,1
3571 .db $09,$ff,%00100001,0,0,0
3572 .db 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
3573 .db 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
3576 ;------------------------------ enemies -------------------------------------
3578 ;format: [HP64] [000000:HP 00:occ] [sprite] [xpos] [appearance(ypos)]
3579 ; [movetype] [time2fire] [firefreq]
3580 ;appearances: 1=random; 2=lure; 3=halflure
3582 ; 1=updown; 2=1/4x; 3=1/2x; 4=1.5x; 5=2x; 6=smart; 7=y-lure;
3583 ; 8=y-lure 1/2x; 9=8 stop at x=99; 10=x+y-lure 1/2x
3586 .db 0,%00100110,(spr_enemyA1-spr_enemy00)/2,128,1,0,0,0
3587 .db 0,%00111110,(spr_enemyA2-spr_enemy00)/2,128,1,0,0,0
3588 .db 0,%01011010,(spr_enemyA3-spr_enemy00)/2,128,1,4,0,0
3589 .db 1,%00001010,(spr_enemyA4-spr_enemy00)/2,128,1,3,0,0
3590 .db 0,%00111110,(spr_enemyA4-spr_enemy00)/2,128,1,5,0,0
3592 .db 0,%00010010,(spr_enemyE1-spr_enemy00)/2,128,1,0,10,0 ;weak
3593 .db 0,%00110010,(spr_enemyE4-spr_enemy00)/2,128,1,3,6,50 ;slow
3594 .db 0,%00100110,(spr_enemyE2-spr_enemy00)/2,128,1,0,1,0
3595 .db 0,%00101110,(spr_enemyE3-spr_enemy00)/2,128,3,0,19,39
3596 .db 0,%00101010,(spr_enemyE5-spr_enemy00)/2,128,3,4,1,0 ;fast
3597 ;11=jumping bug (up/down)
3598 .db 0,%00001111,(spr_enemyN3-spr_enemy00)/2,128,2,1,87,5
3600 .db 0,%00000011,(spr_enemy00-spr_enemy00)/2,1,0,0,0,0 ;12
3601 .db 0,%00000011,(spr_enemy00-spr_enemy00)/2,1,0,0,0,0 ;13
3602 .db 0,%00000011,(spr_enemy00-spr_enemy00)/2,1,0,0,0,0 ;14
3603 .db 0,%00000011,(spr_enemy00-spr_enemy00)/2,1,0,0,0,0 ;15
3604 .db 0,%00000011,(spr_enemy00-spr_enemy00)/2,1,0,0,0,0 ;16
3605 .db 0,%00000011,(spr_enemy00-spr_enemy00)/2,1,0,0,0,0 ;17
3606 .db 0,%00000011,(spr_enemy00-spr_enemy00)/2,1,0,0,0,0 ;18
3607 .db 0,%00000011,(spr_enemy00-spr_enemy00)/2,1,0,0,0,0 ;19
3609 .db 1,%00101011,(spr_boss0_1-spr_enemy00)/2,127,1,8,20,12 ;20
3610 .db 1,%00110011,(spr_boss0_1-spr_enemy00)/2,127,1,8,15,10 ;21
3611 .db 1,%01001011,(spr_boss0_2-spr_enemy00)/2,127,3,9,10,9 ;22
3612 ;23-24=asteroid bosses
3613 .db 2,%00001011,(spr_boss0_3-spr_enemy00)/2,127,1,10,36,14
3614 .db 2,%00110011,(spr_boss0_3-spr_enemy00)/2,127,2,10,28,12
3616 .db 2,%00000111,(spr_boss0_4-spr_enemy00)/2,127,3,7,18,7 ;25=bigboss1
3617 .db 2,%01001011,(spr_boss0_5-spr_enemy00)/2,127,3,7,18,7 ;26=bigboss2
3621 .db %11111111 ; ████████████
3622 .db %10000110 ; █ ██ █
3623 .db %10000110 ; █ ██ █
3624 .db %10111111 ; █ ████████ █
3625 .db %10111111 ; █ ████████ █
3626 .db %10000110 ; █ ██ █
3627 .db %10000110 ; █ ██ █
3628 .db %11111111 ; ████████████
3641 .db 7,6 ;asteroid one
3643 .db %01101100 ; ██ ██
3644 .db %10011110 ;█ ████
3645 .db %11111010 ;█████ █
3646 .db %10111100 ;█ ████
3649 .db 8,7 ;asteroid two
3650 .db %00111100 ; ████
3651 .db %01011010 ; █ ██ █
3652 .db %01101101 ; ██ ██ █
3653 .db %11111101 ;██████ █
3654 .db %11111111 ;████████
3655 .db %10110110 ;█ ██ ██
3659 .db 8,8 ;asteroid three
3660 .db %00011110 ; ████
3661 .db %01110011 ; ███ ██
3662 .db %01111101 ; █████ █
3663 .db %10110111 ;█ ██ ███
3664 .db %11111110 ;███████
3665 .db %11111101 ;██████ █
3666 .db %01010111 ; █ █ ███
3669 .db 7,6 ;asteroid four
3670 .db %01111000 ; ████
3671 .db %10110110 ;█ ██ ██
3672 .db %11111101 ;██████ █
3673 .db %01111011 ; ████ ██
3674 .db %01001110 ; █ ███
3679 .db %00111100 ; ████
3681 .db %10111000 ;█ ███
3683 .db %10111000 ;█ ███
3685 .db %00111100 ; ████
3689 .db %00111100 ; ████
3694 .db %00111100 ; ████
3696 .db 6,6 ;normal solid (Galaxian enemy)
3697 .db %00111100 ; ████
3702 .db %00111100 ; ████
3706 .db %01101000 ; ██ █
3710 .db %01101000 ; ██ █
3716 .db %01111000 ; ████
3719 .db %01111000 ; ████
3724 .db %00111111 ; █████
3726 .db %10110100 ;█ ██ █
3727 .db %10110100 ;█ ██ █
3729 .db %00111111 ; █████
3731 .db 8,6 ;smaller nacelles
3733 .db %01101100 ; ██ ██
3734 .db %10110100 ;█ ██ █
3735 .db %10110100 ;█ ██ █
3736 .db %01101100 ; ██ ██
3740 .db %00001111 ; ████
3741 .db %01111100 ; █████
3742 .db %10011100 ;█ ███
3743 .db %10011100 ;█ ███
3744 .db %01111100 ; █████
3745 .db %00001111 ; ████
3747 .db 8,6 ;G-Type solid
3748 .db %00111111 ; █████
3749 .db %01111000 ; ████
3750 .db %11111100 ;██████
3751 .db %11111100 ;██████
3752 .db %01111000 ; ████
3753 .db %00111111 ; █████
3755 .db 6,6 ;G lost his head; large window ;)
3756 .db %01111100 ; █████
3758 .db %10111000 ;█ ███
3759 .db %10111000 ;█ ███
3761 .db %01111100 ; █████
3763 .db 7,6 ;small G-type
3764 .db %00011110 ; ████
3765 .db %01111000 ; ████
3768 .db %01111000 ; ████
3769 .db %00011110 ; ████
3774 .db %01111100 ; █████
3775 .db %11111000 ; █████
3776 .db %11111000 ; █████
3777 .db %01111100 ; █████
3780 .db 7,6 ;some attack vessel
3782 .db %01110010 ; ███ █
3783 .db %10101100 ; █ █ ██
3784 .db %10101100 ; █ █ ██
3785 .db %01110010 ; ███ █
3788 .db 7,6 ;interceptor
3789 .db %00011110 ; ████
3790 .db %01111110 ; ██████
3791 .db %11111100 ; ██████
3792 .db %11111100 ; ██████
3793 .db %01111110 ; ██████
3794 .db %00011110 ; ████
3796 .db 8,6 ;cheap intercept
3797 .db %00011011 ; ██ ██
3798 .db %01110110 ; ███ ██
3799 .db %10111100 ; █ ████
3800 .db %10111100 ; █ ████
3801 .db %01110110 ; ███ ██
3802 .db %00011011 ; ██ ██
3805 .db 8,7 ;some cool Nemesis-MSX enemy
3806 .db %00111110 ; █████
3807 .db %11110001 ;████ █
3809 .db %00010101 ; █ █ █
3811 .db %11110001 ;████ █
3812 .db %00111110 ; █████
3816 .db %00111110 ; █████
3817 .db %00011101 ; ███ █
3818 .db %11111111 ;████ ███
3819 .db %01110110 ; ██ ███
3820 .db %11111111 ;████ ███
3821 .db %00011101 ; ███ █
3822 .db %00111110 ; █████
3825 .db 8,7 ;Nem3MSX jumper lvl#3
3826 .db %10111110 ;█ █████
3827 .db %01011101 ; █ ███ █
3828 .db %01111110 ; ██████
3830 .db %01111110 ; ██████
3831 .db %01011101 ; █ ███ █
3832 .db %10111110 ;█ █████
3836 .db 16,10 ;boss type one..:.......:
3837 .db %00000001 ; ██████ ██
3838 .db %00001110 ; ███ █ ███
3839 .db %00110010 ; ██ █ ████
3840 .db %01001101 ; █ ██ ██
3841 .db %11101011 ;███ █ ██ █
3842 .db %11101011 ;███ █ ██ █
3843 .db %01001101 ; █ ██ ██
3844 .db %00110010 ; ██ █ ████
3845 .db %00001110 ; ███ █ ███
3846 .db %00000001 ; ██████ ██
3860 .db 16,10 ;boss type two..:.......:
3861 .db %11111110 ;███████
3862 .db %00000011 ; ███ ████
3863 .db %00110101 ; ██ █ ████ █
3864 .db %01111010 ; ████ █ █ █ ██
3865 .db %10001101 ;█ ██ █ ██ ██
3866 .db %10001101 ;█ ██ █ ██ ██
3867 .db %01111010 ; ████ █ █ █ ██
3868 .db %00110101 ; ██ █ ████ █
3869 .db %00000011 ; ███ ████
3870 .db %11111110 ;███████
3882 .db 16,11 ;bigasteroid one
3883 .db %00011110 ; ████
3884 .db %01110011 ; ███ ███
3885 .db %01111111 ; ███████ █
3886 .db %01111111 ; █████████
3887 .db %11111110 ;███████ ███
3888 .db %11111111 ;███████████
3889 .db %11111111 ;████████████
3890 .db %10111110 ;█ █████ ████
3891 .db %01011111 ; █ ███████
3892 .db %00110111 ; ██ ███
3906 .db 16,18 ;bigboss one :
3908 .db %00000111 ; ███ ███
3909 .db %00000011 ; ████ █
3910 .db %00000001 ; ██ ██
3911 .db %00000011 ; ███ ██
3912 .db %00000000 ; █████
3913 .db %00010111 ; █ ██████████
3914 .db %00111111 ; ██████ ██ ██
3915 .db %11111000 ;█████ ██ █ ███
3916 .db %00001111 ; █████ ██ █ █
3917 .db %11111000 ;█████ ██ █ ███
3918 .db %00111111 ; ██████ ██ ██
3919 .db %00010111 ; █ ██████████
3920 .db %00000000 ; █████
3921 .db %00000011 ; ███ ██
3922 .db %00000001 ; ██ ██
3923 .db %00000011 ; ████ █
3924 .db %00000111 ; ███ ███
3926 .db %01010000 ;modelled after a Nemesis][MSX boss
3946 .db 16,15 ;bigboss two :
3947 .db %00001111 ; █████
3948 .db %00111110 ; █████ █████
3949 .db %01111101 ; █████ █ ███████
3952 .db %00000011 ; █████
3953 .db %00011110 ; ████ ██ ████
3954 .db %11110011 ;████ ██ █ █
3955 .db %00011110 ; ████ ██ ████
3956 .db %00000011 ; █████
3959 .db %01111101 ; █████ █ ███████
3960 .db %00111110 ; █████ █████
3961 .db %00001111 ; █████
3962 .db 15 ;modelled after a Nemesis][MSX boss
3980 ;----------------------------------------------------------------------------
3981 ;----------------------------- logo ------------------------------------------
3982 ;----------------------------------------------------------------------------
3985 .db %11111111,%11111111,%11111111,%11111110,%11111111,%11110111,%11111111,%11111110,%11111111,%111101111,%11111111,%00001011,%11111111,%11111111,%11111111,%11111110
3986 .db %01111111,%11111111,%11111111,%11111110,%11111111,%11110111,%11111111,%11111110,%11111111,%111101111,%11111111,%00011011,%11111111,%11111111,%11111111,%11111100
3987 .db %00111111,%11111111,%11111111,%11111110,%11111111,%11110111,%11111111,%11111110,%11111111,%111101111,%11111111,%00111011,%11111111,%11111111,%11111111,%11111000
3988 .db %00011111,%11111111,%11111111,%11111110,%11111111,%11110111,%11111111,%11111110,%11111111,%111101111,%11111111,%01111011,%11111111,%11111111,%11111111,%11110000
3989 .db %00000000,%00000000,%00000001,%00011110,%00010000,%00000000,%10000001,%00011110,%00010000,%000000001,%00000000,%00001000,%01000000,%00000000,%00000000,%00000000
3990 .db %00000000,%00000000,%00000011,%00011110,%00110000,%00000001,%10000011,%00011110,%00110000,%000000011,%00000000,%00011000,%11000000,%00000000,%00000000,%00000000
3991 .db %00000000,%00000000,%00000111,%00011110,%01110000,%00000011,%10000111,%00011110,%01110000,%000000111,%00000000,%00111001,%11000000,%00000000,%00000000,%00000000
3992 .db %00000000,%00000000,%00001111,%00011110,%11111111,%00000111,%10001111,%00011110,%11111111,%000001111,%11111111,%01111011,%11111111,%11000000,%00000000,%00000000
3993 .db %00000000,%00000000,%00001111,%00011110,%11111111,%00000111,%10001111,%00011110,%11111111,%000001111,%11111111,%01111011,%11111111,%11000000,%00000000,%00000000
3994 .db %00000000,%00000000,%00001111,%00011110,%11111111,%00000111,%10001111,%00011110,%11111111,%000001111,%11111111,%01111011,%11111111,%11000000,%00000000,%00000000
3995 .db %00000000,%00000000,%00001111,%00011110,%11111111,%00000111,%10001111,%00011110,%11111111,%000001111,%11111111,%01111011,%11111111,%11000000,%00000000,%00000000
3996 .db %00000000,%00000000,%00001111,%00011110,%11110000,%00000111,%10001111,%00011110,%11110000,%000000000,%00001111,%01111000,%00000011,%11000000,%00000000,%00000000
3997 .db %00000000,%00000000,%00001111,%00011110,%11110000,%00000111,%10001111,%00011110,%11110000,%000000000,%00001111,%01111000,%00000011,%11000000,%00000000,%00000000
3998 .db %00000000,%00000000,%00001111,%00011110,%11110000,%00000111,%10001111,%00011110,%11110000,%000000000,%00001111,%01111000,%00000011,%11000000,%00000000,%00000000
3999 .db %00000000,%00000000,%00001111,%00011110,%11110000,%00000111,%10001111,%00011110,%11110000,%000000000,%00001111,%01111000,%00000011,%11000000,%00000000,%00000000
4000 .db %00000000,%00000000,%00001111,%00011110,%11111111,%11110111,%10001111,%00011110,%11111111,%111101111,%11111111,%01111011,%11111111,%11000000,%00000111,%11010001
4001 .db %00000000,%00000000,%00001111,%00011110,%11111111,%11110111,%10001111,%00011110,%11111111,%111101111,%11111111,%01111011,%11111111,%11000000,%00000001,%00011011
4002 .db %00000000,%00000000,%00001111,%00011110,%11111111,%11110111,%10001111,%00011110,%11111111,%111101111,%11111111,%01111011,%11111111,%11000000,%00000001,%00010101
4003 .db %00000000,%00000000,%00001111,%00011110,%11111111,%11110111,%10001111,%00011110,%11111111,%111101111,%11111111,%01111011,%11111111,%11000000,%00000001,%00010001
4005 ;----------------------------- end ------------------------------------------
4011 ;----------------------------------------------------------------------------
4012 ;----------------------------------------------------------------------------
4013 ;----------------------------------------------------------------------------
4015 ; 0.98.77 -- 7.VII.00 -- size 6707
4017 ; # bullets do damage in all levels
4018 ; * more armor at armor-upgrade and extra armor at end of a level
4019 ; - internal levels again (no need 4 external, safer/smaller)
4020 ; # some registers not correctly pushed/popped
4021 ; * several optimizations (init.procs some bytes smaller)
4022 ; # enemies hit with hitpoints left disappeared (one pop too much...)
4023 ; + bullets "charge up" (more damage) when not firing
4024 ; - removed contrast changes
4025 ; + more powerful bullets have different sprites (larger=more damage)
4026 ; # multiples appear at your position (begin level/just selected)
4027 ; # when invulnerable multiples acted weird
4028 ; # no more error at activation after APD off after running Nemesis
4029 ; # saves correctly if own name ain't "nemesis" + some bytes smaller
4030 ; # screen wasn't always entirely cleared after quit
4031 ; * waits until all keys have been released after death
4032 ; + different bullets sizes will miss if they're too small
4033 ; + at level start "press F1 to save"-text will be displayed
4034 ; * w3.shiar.org displayed at title screen, black bar behind version nr
4035 ; # score to 0 when exit pressed at main menu
4036 ; # no residual story-text in first frame of game
4037 ; # game doesn't continue again after death (stack messed up)
4038 ; # game over when lives<0 (didn't work in v0.96+)
4039 ; * using some self-modifiing code (so it's smaller)
4040 ; # new random procedure: stars don't appear on one line anymore
4041 ; * weapons appear centered at multiples
4042 ; * laser properties can be changed (damage, charge)
4043 ; + weapon can be combination of bullets/lasers (max. of 3 per weapon)
4044 ; * bullet-icon is removed when laser is selected
4045 ; * enemy sprite table integrated in enemy specs (-1 byte/enemy)
4046 ; + random enemy is chosen from any number of enemies per level
4047 ; * time to first enemy fire defined per enemy, not per level
4048 ; + CLIPPED sprites!! no more in/out popping enemies! wow...
4049 ; * bullets/enemies removed when _entirely_ off screen
4050 ; # enemies would sometimes be hit by bullets going right below them
4051 ; # size of the second bullet was too big (invisible hit)
4052 ; * the frequency an enemy fires bullets is defined per enemy
4053 ; + wide clipped sprites implemented (width 1-16 pixels)
4054 ; # bosses first move left until x=100, otherwise they'd be off-screen
4055 ; * at status bar left below ships are displayed for lives left
4056 ; * armor bar is two pixels high (better visible)
4057 ; # bullet overflow fixed again (>63 bullets fired)
4058 ; # correct weapon loaded when continuing a saved game
4059 ; # game freezed when generating a random value <=1
4060 ; * you explode in a different way than the enemies
4061 ; + screen inverts for a brief time when you are hit!
4062 ; # stats-bar was messed up when ya got 0 lives left
4063 ; * two new (big) bosses modeled after a common MSX Nemesis2-boss
4064 ; * score increased once every 32 frames (instead of every 256)
4065 ; # ground fixed for new random routine (smaller routine; incs -2 to 2)
4066 ; + laser will upgrade as well when you reselect it
4067 ; * 2nd can be used in main menu (wow!)
4068 ; # altered variable storage space because of Nemesis grew beyond 6kb
4069 ; # fixed armor bar display when at maximum
4070 ; + a few new enemies (asteroids) and remade 1st 4 levels; new pickup
4071 ; - torpedo since it was kinda useless
4072 ; + second icon now selects TAIL BEAM: bullet going backwards
4073 ; # armor increase at the end of a level doesn't overflow armorbar
4074 ; + you can choose your own ship out of four vessel after NEW GAME!
4075 ; + enemies can appear at any x-position and move both left and right
4076 ; + move patterns given per enemy, not per level
4077 ; * new (faster) enemy-move system; 10 basic moves (x2 left+right)
4078 ; # enemies can _never_ move above or below visible screen
4079 ; * "randomY"-enemies are placed entirely on screen (height calced)
4080 ; # the major TI-OS crash bug WAS afterall caused by sprites drawn
4081 ; (partially) outside screen memory. temporarily fixed by setting
4082 ; virtual screen buffer to $8200 (enough mem there)
4083 ; + upto 29 cool enemy sprites and redone first five levels
4084 ; * improved enemy-move routine; smooth luring, five speeds+backwards
4085 ; # after pause weapon will not be fired
4086 ; # teacher key fixed (waits for GRAPH to be release before&after)
4088 ; + added - removed * changed # bug fixed