X-Git-Url: http://git.shiar.net/nemesis.git/blobdiff_plain/6e5871161620420b6f9a532be158954210dd7e4c..68c5a64ac96152091939da019e24abc26e199388:/nemesis.z80 diff --git a/nemesis.z80 b/nemesis.z80 index 6d958b2..9b62f3a 100644 --- a/nemesis.z80 +++ b/nemesis.z80 @@ -57,6 +57,7 @@ nextevent = eventleft+1 ; +6 ;time to next event level_enemy = nextevent+1 ; +7 ;enemy type level_info = level_enemy+1 ; +8 ;info (see below) level_move = level_info+1 ; +9 ;= +time2invert = level_move+1 ;+10 ;time until b<>w switch ; ;--------OBJECTS spacespace = storepos+19 ;+19 groundinfo = spacespace+1 ;+20 @@ -229,18 +230,15 @@ menuloop: jr z,menuchange cp K_EXIT jr z,menuexit - ld hl,_invert cp K_F1 - cal z,undo_invert - cp K_F2 cal z,do_invert cp K_ENTER jr nz,menuloop ld a,(menuitem) dec a - cal nz,New_game - jp samelevel ;game_main_loop + cal nz,New_game ;NEW GAME + jp samelevel ;CONTINUE: game_main_loop menuexit: ld hl,0 @@ -253,11 +251,15 @@ menuchange: ld (menuitem),a jr menuloop -do_invert: - ld (hl),$2F ;cpl - ret -undo_invert - ld (hl),$B7 ;or a +do_invert: ;invert screen (b<>w); destr:b + psh hl + ld b,a ;psh a + ld hl,_invert + ld a,$98 + xor (hl) ;$2F (cpl) <-> $B7 (or a) + ld (hl),a + ld a,b ;pop a + pop hl ret ;---------------------------------------------------------------------------- @@ -267,9 +269,10 @@ undo_invert game_main_loop: ;REPEATS FROM HERE EVERY FRAME ld hl,timer ;update time inc (hl) ;increase by 1 - jr nz,Clear_screen ;continue when new time <> 0 - ld hl,1 ;once every 256 frames, increase score by 1 - cal scoreInc ;do it + ld a,(hl) + and %11111 + ld hl,1 ;once every 32 frames, increase score by 1 + cal z,scoreInc ;do it Clear_screen: ld hl,GRAPH_MEM ;move from (hl) = top left @@ -354,7 +357,10 @@ _gamestuff1: cal Level_event ;insert enemies cal Display_Screen ;display all + ld b,1 +___: halt ;delay + dnz ___ jp game_main_loop ;LOOP ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ inc_weapdamage: @@ -399,31 +405,30 @@ Handle_ground: jr z,ground_tunnel ;tunnel effect ground_boring: ld a,(groundpos) ;type 0 + jr newground+1 ground_tunnel: ld a,(groundpos+14) ld d,a ld hl,spacespace - - ld bc,$201 ;range=1..3 - cal Random ;a=1-3 - dec a - jr z,newground ;same if a=1 - dec a - jr z,gtunneldown ;down if a=2 -gtunnelup: ;up if a=3 - ld a,(hl) + ld bc,$500 ;range=0..4 + cal Random ;a=0..4 + dec a ;a=-1..3 + dec a ;a=-2..2 + ld b,a + add a,(hl) ;add to spacesize (so +2..-2) + cp 10 + jr c,newground ;>=0 then don't change + ld c,a + ld a,d + add a,b ;new position or a - jr z,newground ;a>=0 (a=0 actually) - inc (hl) - inc d - jr newground -gtunneldown: - ld a,1 - cp d - jr z,newground - dec d - dec (hl) + jr z,newground ;may not be 0 (=256) + cp -10 + jr nc,newground ;and not be <0 (>246) +diffground: + ld d,a + ld (hl),c newground: ld a,d ld (groundpos+15),a ;save new byte on the right @@ -678,13 +683,22 @@ displayloop: ld b,16 ;display width = 16 bytes (16*8bits=256pixels) displaytloop: ld a,(hl) ;copy byte from (hl) -_invert: - cpl ;xor $ff: invert byte (white<=>black) +_invert: ;SMC: cpl <-> or a + cpl ;xor $ff: invert byte (white<=>black) ld (de),a ;to (de) inc hl \ inc de ;next byte dnz displaytloop ;16x hl >> de dec c ;next line - jr nz,displayloop ;loop 64x + jr nz,displayloop ;loop 56x + + ld hl,time2invert + ld a,(hl) + or a ;(time2invert)=0: + jr z,noinvert ; do nothing + dec a ;otherwise decrease + cal z,do_invert ;if it became 0 then invert + ld (hl),a ;save new value +noinvert: ld hl,$396b ;Display Score ld (_penCol),hl ;bottom right of screen @@ -715,9 +729,9 @@ Handle_Ship: inc a ;no! next (explosion)frame ld (your_occ),a ;save - cp 34 ;last explosion frame? + cp 64+1 ;last explosion frame? (1-16=1st;49-64=4th) jp c,exploding_you ;not yet: display explosion - cp 40 ;delay finished? + cp 64+16 ;delay finished? jp z,You_die ;yes = game over ret ;don't display anything @@ -781,6 +795,7 @@ no_right: no_up: ld e,(hl) ;e=y ld ix,spr_ship01 ;normal ship sprite +your_shipspr =$-2 ld hl,your_inv ;invulnerable? ld a,(hl) ;load time in a or a ;is it 0? @@ -794,7 +809,8 @@ not_time: and %00000100 ;a switches 0<->1 every 2 frames jr z,disp_ship ;show normal ship inv_flicker: - ld ix,spr_ship01i ;display invulnerable ship + ld bc,spr_ship01i-spr_ship01 + add ix,bc ;display invulnerable ship disp_ship: cal safeputsprite ;display your ship; save de @@ -841,16 +857,17 @@ mult_adv: exploding_you: srl a ;half the framerate - dec a ;first frame is 1>inc>srl>dec = 0 + srl a ;half that framerate + srl a ;and half again that framerate ld hl,x-1 + ld ix,spr_yexplosion ;base sprite -explosion_stuff: ;in:a=frame*2+(0 to 1); (hl)=xpos-- +explosion_stuff: ;in:a=frame*2+(0 to 1); (hl)=xpos-- ix=sprite and %11111110 add a,a add a,a ;frame*8 ld c,a ld b,0 ;bc=a - ld ix,spr_explosion ;base sprite add ix,bc ;go to correct sprite (each spr. is 8 bytes) inc hl ld d,(hl) ;load xpos @@ -861,9 +878,18 @@ explosion_stuff: ;in:a=frame*2+(0 to 1); (hl)=xpos-- ;----hit---- damage_you: ;damages you B points - ld a,(your_inv) ;invulnerability left? + ld a,(your_inv) ;shield left? or a - ret nz ;return if inv>0 + jr z,dothadamage ;no shield + srl b ;shield: half the damage +dothadamage: + ld hl,time2invert + xor a ;a=0 + cp (hl) ;no already inverted? + cal z,do_invert ;then invert screen + ld a,2 + ld (hl),a ;change back 2 frames from now + ld hl,your_armor ;armor left ld a,(hl) ;load hp in A sub b ;decrease hp by B @@ -1098,8 +1124,7 @@ find_ybullet: jr z,found_ybullet ;0 = no bullet here add hl,de dnz find_ybullet ;look next bullet - pop hl ;don't try to fire any other bullets - ret ;so ret twice + ret ;none found, return don't fire found_ybullet: ld (hl),c ;use the bullet and set correct bullet-type @@ -1196,7 +1221,7 @@ display_bullet: dec hl ;@x dec hl ;@damage ld a,(hl) ;bullet damage=size - ld hl,XLbullettable ;pointer to first bullet + ld hl,bullettable ;pointer to first bullet srl a srl a ;per 4 ld d,0 @@ -1361,8 +1386,9 @@ Level_event: or a ;has it reached zero? ret nz ;nope: get outta here! - ld a,0 ;enemy frequency (lvl) -eventtime =$-1 + ld bc,0 ;enemy frequency (lvl) +eventtime =$-2 + cal Random ld (nextevent),a ;set time to next event ld hl,eventleft dec (hl) ;update enemy-counter @@ -1707,6 +1733,8 @@ exploding_enemy: jr z,remove_enemy ;remove when at last frame inc a ld (hl),a ;next frame + dec a ;1-16 -> 0-15 + ld ix,spr_explosion ;base sprite cal explosion_stuff ;display explosion jr next_enemy @@ -2047,7 +2075,22 @@ disp_icons: xor a ;blank line mask cal drawline ;clear scorebar - cal disp_lives +disp_lives: + ld de,5 ;(0,5) + ld a,(your_lives) ;nr of lives + or a + jr z,displivesdone ;no lives + ld b,a +displivesloop: + psh bc + ld ix,spr_lship + cal safeputsprite ;put li'l ship + ld a,lshipsize+1 + add a,d + ld d,a ;x=x+5 + pop bc + dnz displivesloop ;one ship per life +displivesdone: ld ix,spr_icon01 ;armorIcon ld de,$1901 ;icon #1 @@ -2120,11 +2163,15 @@ iconsdone: ret disp_armor: + ld de,16 ;line size ld hl,(57*16)+VIDEO_MEM+3 ld b,3 armorbarclr: dec hl ld (hl),0 + add hl,de + ld (hl),0 + sbc hl,de dnz armorbarclr ld a,(your_armor) ;load your armor @@ -2136,6 +2183,9 @@ armorbarclr: ld b,a ;loop b=a times armorbar: ;starting at ($39*16)+VIDEO_MEM ld (hl),%11111111 ;draw a piece of the bar + add hl,de ;one down (resets carry) + ld (hl),%11111111 ;same piece + sbc hl,de ;up again inc hl ;next position dnz armorbar ;loop it b times @@ -2151,15 +2201,18 @@ armorbarbit: dnz armorbarbit ;repeat B times (so if B=6 then a=%11111100) armorbarready: ; (an if B=3 then a=%11100000) ld (hl),a ;draw this last byte + add hl,de + ld (hl),a ;and just below ret disp_charge: - ld hl,(58*16)+VIDEO_MEM+3 + ld hl,(59*16)+VIDEO_MEM+3 ld b,3 chargebarclr: dec hl ld (hl),0 dnz chargebarclr + ld a,(weapincs) ;load bar size (0-80) srl a ;half the size (0-40) srl a ;again half that size (0-20 pixels) @@ -2172,7 +2225,7 @@ chargebarclr: chargebar: ;starting at ($39*16)+VIDEO_MEM ld (hl),%11111111 ;draw a piece of the bar inc hl ;next position - dnz armorbar ;loop it b times + dnz chargebar ;loop it b times nochargebar: ld a,c ;pop a and %111 ;display last bits of chargebar @@ -2187,36 +2240,30 @@ chargebarready: ; (an if B=3 then a=%11100000) ld (hl),a ;draw this last byte ret -disp_lives: - ld hl,$3A00 ;display Lives - ld (_penCol),hl ;bottom left - ld hl,savestr+2 - ld (hl),'L' - inc hl - ld (hl),'x' - inc hl - - ld a,(your_lives) ;nr of lives in a - add a,'0' ;make digit - ld (hl),a - dec hl \ dec hl - jp _vputs ;display on screen +ret - ;--------------------------- proc ------------------------------------------- Random: ;a=c=b - jr nc,Random ;then add again + psh hl + ld hl,rancount ;amount to increase with (0-255) +randomloop: + inc (hl) ;change for next time + ld a,r ;value $0-7F (can be _anything_ so watch out!) + add a,0 ;add to last random value +ranseed =$-1 ;SMC :P + add a,(hl) ;add the changing increase value + ;(this is because R can be anything; + ; ie always be even so freeze when a must be 1<=a<=1) + ld (ranseed),a ;save for next time + cp b ;a>=b + jr nc,randomloop ;then add again add a,c ;a63 bullets fired) +; # correct weapon loaded when continuing a saved game +; # game doesn't freeze when generating a random value <=1 +; * you explode in a different way than the enemies +; + screen inverts for a brief time when you are hit! +; # stats-bar was messed up when ya got 0 lives left +; * new (big) boss; "asteroids" level #1 +; * score increased once every 32 frames (instead of 256) +; # ground fixed for new random routine (smaller routine; incs -2 to 2) ; ; ; + added - removed * changed # bug fixed \ No newline at end of file