From 86a45e83419f7f26a7eba8a8f76a9bb5ed957f5a Mon Sep 17 00:00:00 2001 From: Mischa Poslawsky Date: Wed, 16 Aug 2000 13:49:22 +0200 Subject: [PATCH] version 0.99 pre2: pause options, gameplay fixes/features # when enemy changed into a pickup, movement is set to vslow * instead of turning into a pickup, enemies explode and a pickup appears at the right side of the screen (moves left slowly) # bullets do damage again (screenflash made damage become 0) + when destroyed by bullets, the armor bar will show 0HP left * all enemy bullets do the same damage in all levels * you now appear at (*32*,30) because enemies can come from left * improved bullet handling (faster, smaller, etc.) + multiples are animated like real Nemesis (pulsating) # fixed a bug that didn't select multiples when you were moving # enemy collision screwed up invert and some other weird stuff + in pause screen change contrast with up/down and B/W mode with F1 + lasers can have different durations (beams last longer) * some sign-flag checkings replaced by carry-flag (thus reducing size) # slow enemies (including pickups) didn't always appear (just 25-50%) + enemies can fire different kinds of bullets: aiming, double, triple * maximum number of bullets increased (48 for enemies, 128 for you) --- nemesis.txt | 31 +- nemesis.z80 | 980 ++++++++++++++++++++++++++++------------------------ 2 files changed, 550 insertions(+), 461 deletions(-) diff --git a/nemesis.txt b/nemesis.txt index 81dbc27..2e0ac9a 100644 --- a/nemesis.txt +++ b/nemesis.txt @@ -1,7 +1,7 @@ ------------------------------------------------------------------------------ Title : Nemesis - Version : 0.99.810 Beta - Release Date : 10.VIII.00 + Version : 0.99.816 Beta + Release Date : 16.VIII.00 Filename : nemesis.86p (size 7kB) Author(s) : Shiar Email Address : shiar0@hotmail.com @@ -34,11 +34,11 @@ for systems including the Game Boy, (S)NES and Play Station. GRAPH : teacher/boss! (press graph again to resume) EXIT : whooo, what does _this_ button do? - Collect the pickups enemies leave after they're destroyed to upgrade your -ship. The highlighted icon in the score bar (bottom) can be activated by -pressing ALPHA. + After destroying several enemies, pickups will appear. Collect them to +upgrade your vessel. The highlighted icon in the score bar (bottom) can be +activated by pressing ALPHA. - Upgrades: ARMOR | TAIL-BEAM | WEAPON-UPG | LASER | MULTIPLES + Upgrades: ARMOR | TAIL-BEAM | BEAM/UPG | LASER/UPG | MULTIPLES The upper bar on the left shows your hitpoints left (armor). The bar below that shows the current power of your weapon. @@ -46,10 +46,8 @@ that shows the current power of your weapon. >>>>>>> BETA STUFF ----------------------------------------------------------- - There are just five levels for now, don't play beyond there. In future -versions I'll add more levels and enemies, maybe obstacles, and I'll release -the source code. I don't think I will add greyscale, sound or a multiplayer -option. + Rightnow I'm finishing the other six (of 12) levels. I don't think I will +add greyscale, sound or a multiplayer option. Continue to send me any IDEAS and BUGS found!! Or send me you like this program, or even send me something if you don't. Again: shiar@mailroom.com, @@ -62,20 +60,19 @@ memory LOCKED! Besides that there shouldn't be any bugs. >>>>>>> CREDITS -------------------------------------------------------------- - Programming/levels/gfx - - - SHIAR - Official betatesters - - - - DAVE -- BLACKBELT -- MATTHEW DALE - Support (advise/ideas/etc) - JONAH -- SCABBY -- BRIAN KOROPOFF -- CULLEN S + Programming/levels/gfx - SHIAR + Official betatesters - DAVE -- BLACKBELT -- MATTHEW DALE + Support (advise/ideas/etc) - JONAH -- SCABBY -- BRIAN KOROPOFF Original engine (Galaxian) - PATRICK DAVIDSON - Original Nemesises - - - - - KONAMI + Original Nemesises - KONAMI Also alot of thanks to EVERYBODY WHO SENT ME SOMETHING and everybody I forgot. >>>>>>> RULEZ AND REGULATIONS ------------------------------------------------ -* Damage to you, your calc, or anything else was not caused by Nemesis - and I am certainly not responsible -* Thou shalt NOT release an altered version of Nemesis +* Thou shalt not hold me responsible for damage to your calc or anything else +* Thou shalt NEVER release an altered version of Nemesis * Thou shalt include this documentation with distribution (except calc2calc) * Thou shalt not ask money for this program * Thou shalt eat plenty of vegetables every day diff --git a/nemesis.z80 b/nemesis.z80 index fed759c..413ab08 100644 --- a/nemesis.z80 +++ b/nemesis.z80 @@ -1,16 +1,17 @@ ;---------------------------------------------------------------------------- ;---------------------- NEMESIS --------------------------------------------- -;---------------------------------------------------------------------------- +;----------------------------------------------- cool arcade-shoot-em-up-game ;by SHIAR | shiar0@hotmail.com | icq#43840958 | www.shiar.org -;Description : cool arcade-shoot-em-up-game -;Other games by author : Worm ;This source should only be used for learning practises, do not ;alter it, and certainly never distribute an altered version!! ;&&& marks uncertainties or things to optimize +;TO DO: +; up-double | torpedoes | levels 7-12 | jp m | better weapons + ;---------------------- nemesis.z80 start ----------------------------------- #include "asm86.h" @@ -68,13 +69,13 @@ mm = 4 ;max. number of multiples ;^-----------------------------------<1 ;-120=$78 enemies = storepos2 ; +0 ;info about each enemy -enemysize = 9 ;infobytes per enemy +enemysize = 10 ;infobytes per enemy nrenemies = 16 ;max. nr of enemies ybullets = enemies+(nrenemies*enemysize) ;60 bytes = 20(state,damg,x,y) -nrybuls = 64 ; +80\ +nrybuls = 128 ; +80\ ebullets = ybullets+(nrybuls*4) ;+110 ;30 bytes = 10(state,x,y) -nrebuls = 16 +nrebuls = 48 lvlenemies = ebullets+(nrebuls*3) ;^-----------------------------------<2 ;-141=$8D @@ -82,7 +83,8 @@ lvlenemies = ebullets+(nrebuls*3) ; [0000:damage 0:diagfire 0:ground 0:ceiling 0:-] ;enemies: ; [HP64] [000000:HP left 00:(00=no enemy 01=exploding 10=normal 11=moving)] -; [ship type or explosion frame] [x] [y] [movetype] [movecounter] [firecounter] [firefreq] +; [ship type or explosion frame] [x] [y] [movetype] [movecounter] +; [firecounter] [firefreq] [firetype] ;---------------------- introduction ---------------------------------------- @@ -92,7 +94,7 @@ lvlenemies = ebullets+(nrebuls*3) .dw Title ;pointer to description (all shells) .dw Icon ;pointer to YAS icon -Title: .db "Nemesis v0.99.810 by SHIAR",0 +Title: .db "Nemesis v0.99.812 by SHIAR",0 Icon: .db 8,1 ;icon for YAS: width = 1byte; height = 9bytes .db %11100000 ; ███ @@ -103,7 +105,7 @@ Icon: .db 8,1 ;icon for YAS: width = 1byte; height = 9bytes .db %01111000 ; ████ .db %11100000 ; ███ ;recommend 80x50 screen mode .db 0 ;YAS 0.92 compatibility -;43 + ;---------------------- init ------------------------------------------------ int_handler: ;new interrupt proc @@ -127,17 +129,17 @@ FixKeys: ;fixes some key problems like left+down bug ld a,$D4 ld bc,$0100 ld h,a - ld l,c ;ld hl,$D400 + ld l,c ;ld hl,$D400 (user silent link routine space) ld d,a ld e,b ;ld de,$D401 dec a ;ld a,$D3 ld (hl),a - ldir + ldir ;fill $D400-D500 with $D3s (slink/user on) ld hl,int_handler ;new interrupt handler ld d,a ld e,a ;ld de,$D3D3 ld bc,int_end-int_handler - ldir + ldir ;load new handler at ($D3D3) inc a ;ld a,$D4 ld i,a im 2 @@ -210,8 +212,6 @@ menuitem =$-1 jr z,start_tha_freakin_game cp K_EXIT jr z,menuexit - cp K_F1 - cal z,do_invert cp K_UP jr z,menuchange cp K_DOWN @@ -234,14 +234,14 @@ menuexit: ld (your_score),hl ;(prevents hiscore while never played) jp game_over ;and go to game over screen -do_invert: ;invert screen (b<>w); destr:b +do_invert: ;invert screen (b<>w) psh hl - ld b,a ;psh a + psh af ;can't destroy b ld hl,_invert ld a,$98 xor (hl) ;$2F (cpl) <-> $B7 (or a) ld (hl),a - ld a,b ;pop a + pop af pop hl ret @@ -313,7 +313,9 @@ check_exitkey: jp z,game_over ; pressed, so be it check_morekey: ;another unused label... poor compiler bit 7,a ;test bit 7 = more-key = PAUSE + psh af cal z,Pause ;yes, go to pause + pop af check_firekey: bit 5,a ;test bit 5 = 2nd-key = FIRE @@ -323,6 +325,7 @@ check_firekey: pop hl ;no cal to Fire_bullet made, so pop stack ld hl,just_fired ;no: ld (hl),5 ;able to fire (five turns = laser duration) +laserdur =$-1 ;SMC laser duration check_selkey: ld a,%01011111 ;look at first column of keys (ALPHA to STO) @@ -499,7 +502,7 @@ CheckGround: ;check for collision with the ground neg cp (hl) ret nc - ld b,5 + ld b,auch_ground jp damage_you ;--------------------------- ceiling ---------------------------------------- @@ -588,7 +591,7 @@ CheckCeiling: ;check for collision with the ground inc a cp (hl) ;compare with ceiling ret nc ;carry if ceiling is above you - ld b,5 + ld b,auch_ground jp damage_you ;otherwise you don't wanna be in that ship ;--------------------------- move stars ------------------------------------- @@ -643,17 +646,35 @@ newstarok: ;--------------------------- pause ------------------------------------------ Pause: - psh af - ld hl,$0200 ;top left + ld hl,_txt_pause + ld (_penCol),hl + ld hl,txt_pause + cal _vputs ;display small font + ld hl,_txt_pressenter ;top centered ld (_curRow),hl ld hl,txt_pressenter ;"Enter to continue" cal _puts ;display message pause: - cal _getkey ;enter low-power mode and wait for key - cp kEnter ;keypressed = enter? - jr nz,pause ;no, wait some more - pop af - ret ;continue + cal getsomekeys ;GET_KEY w/ halts and checks for enter + ret z ;enter/second pressed: continue game + cp K_F1 ;F1 pressed? + cal z,do_invert ;if so then change invert screen (AF saved) + ld hl,CONTRAST ;contrast setting (0-31) + ld b,(hl) ;load contrast into b + cp K_UP ;+ key changes contrast up + jr nz,contr_not_up + inc b ;increase contrast + jr setcontrast ;set +contr_not_up: + cp K_DOWN ;- key + jr nz,pause ;nope: loop + dec b ;decrease contrast +setcontrast: + ld a,b + ld (hl),a + out (2),a ;and set it + cal releasekeys + jr pause ;and loop ;--------------------------- teacher ---------------------------------------- @@ -844,7 +865,7 @@ disp_ship: handle_multiples: ld a,(your_multiples) ;do you have multiples ld b,a ;save a for 2nd check - and %111 ;no? (last two bits = nr of multiples) + and %1111 ;no? (last four bits = nr of multiples) ret z ;then don't handle them either bit 7,b ;move the multiples??? (=move bit set?) jr z,mult_adv ;nope, just let them (saves (y)in y, (x)in x) @@ -861,22 +882,29 @@ handle_multiples: ld (hl),e ;y-pos mult_adv: - ld hl,your_prevpos+16 ;first pos. + ld ix,spr_multiple ;normal sprite + ld hl,timer + bit 3,(hl) ;change sprites every 8 turns + jr z,disp_multiples + ld ix,spr_multiple2 ;second sprite disp_multiples: + ld hl,your_prevpos+16 ;first pos. +dispmultiplesloop: psh af psh hl ld d,(hl) ;load coords inc hl ld e,(hl) - ld ix,spr_multiple ;sprite + psh ix cal putsprite ;display + pop ix ;same sprite next time ;) pop hl ld de,14 add hl,de ;next multiple pop af ;counter dec a ret z ;return if all done - jr disp_multiples ;loop + jr dispmultiplesloop ;loop ;----explode---- @@ -910,21 +938,19 @@ damage_you: ;damages you B points dothadamage: ld hl,time2invert xor a ;a=0 - cp (hl) ;no already inverted? + cp (hl) ;not already inverted? cal z,do_invert ;then invert screen - ld a,2 - ld (hl),a ;change back 2 frames from now + ld (hl),2 ;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 - jp m,no_armor ;<0hp left so explode - ld (hl),a ;no, so save decreased hp - jp disp_armor ;and display new value -no_armor: + jr nc,newarmor ;>=0hp left so don't explode ld a,%01 ;occ %xxxxxx01 = explode ld (your_occ),a ;too bad, you're dead meat - ret +newarmor: + ld (hl),a ;save decreased hp + jp disp_armor ;and display new value ;------------------------- place multiples ---------------------------------- @@ -960,14 +986,14 @@ select: select1: ld (hl),a ;reset pickups cal inc_armor - jp disp_icons ;display and return + jr disp_icons ;display and return select2: dec a ;is it 2? jr nz,select3 ;no, carry on ld (hl),a ;reset pickups inc a ;a=1 ld (your_tail),a ;ready tail beam - jp disp_icons ;display 'n return + jr disp_icons ;display 'n return select3: dec a ;is it 3? jr nz,select4 ;no, carry on @@ -976,10 +1002,10 @@ select3: ld a,(hl) inc a cp maxweapon - jp nc,disp_icons ;weapon maxed out + jr nc,disp_icons ;weapon maxed out ld (hl),a ;set new weapon cal loadweapon ;load it (damage and stuff) - jp disp_icons ;display n return + jr disp_icons ;display n return select4: dec a ;is it 4? jr nz,select5 ;no, carry on again @@ -992,16 +1018,17 @@ select4: upgradelaser: inc a ;next laser cp maxlaser - jp nc,disp_icons ;laser maxed out + jr nc,disp_icons ;laser maxed out ld (hl),a cal loadweapon - jp disp_icons ;display + return + jr disp_icons ;display + return select5: dec a ;is it 5? jr nz,select6 ;no, carry on once more ld (hl),a ;reset pickups ld hl,your_multiples ld a,(hl) ;multiples you already got + and %1111 ;reset movebit so (your_multiples)=real value inc a ;one more cp mm+1 jr nc,enoughmultiples ;maxed out @@ -1010,16 +1037,177 @@ enoughmultiples: ld de,(x) dec a ;if this is your first multiple then... cal z,Place_multiples ;reset multiples positions - jp disp_icons ;display, return + jr disp_icons ;display, return select6: ld (hl),0 ;reset pickups - jp disp_icons ;display/return +; jr disp_icons + +;--------------------------- show icon -------------------------------------- + +disp_icons: + psh bc \ psh de \ psh hl \ psh ix ;&&& + + ld hl,VIDEO_MEM+(16*56);56 rows down = eight rows from bottom + ld (PutWhere),hl ;place icons at bottom of normal screen + ld b,16 ;draw 16x (screen width) + ld a,%11111111 ;horizontal line mask + cal drawline ;draw divider-line + + ld b,16*7 ;draw 16x (screen width) 7x (height) + xor a ;blank line mask + cal drawline ;clear scorebar + +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: + cal disp_armor ;display bar + + ld ix,spr_icon01 ;torpedoIcon + ld de,$1901 ;icon #1 + cal putwidesprite ;display icon + + ld ix,spr_icon00 + ld a,(your_weapon) ;ur weapon + cp maxweapon ;laser? + psh af ;(your_weapon) + jr nc,no_tail ;if laser (nc) then tail ain't fired + ld a,(your_tail) + or a + jr z,no_tail + ld ix,spr_icon02 ;tailbeamIcon +no_tail: + ld de,$2901 ;icon #2 + cal putwidesprite ;display + + ld ix,spr_icon00 + pop af ;a=(your_weapon); cf=bullets + psh af + jr nc,no_bullets ;=laser + ld hl,$3945 ;position to display bullet-type digit + pop af ;digit=(your_weapon) + psh af + inc a ;1 = weapon #1 (=0) + ld (_penCol),hl ;set location + add a,'0' ;make digit + cal _vputmap ;display char + ld ix,spr_icon03 ;bulletIcon +no_bullets: + ld de,$3901 ;icon #3 + cal putwidesprite ;display icon + + ld ix,spr_icon00 ;emptyIcon + pop af ;ld a,(your_weapon) + ld b,a + jr c,no_laser ;popped carry + ld hl,$3955 ;position to display bullet-type digit + ld (_penCol),hl ;set location + ld a,b ;(your_weapon) ;load = faster than push + sub maxweapon-1 ;1 = laser #1 (=maxweapon) + add a,'0' ;make digit + cal _vputmap ;display char + ld ix,spr_icon04 ;laserIcon +no_laser: + ld de,$4901 ;icon #4 + cal putwidesprite + + ld ix,spr_icon00 ;emptyIcon + ld a,(your_multiples) + and %111 + jr z,no_multiples + ld ix,spr_icon05 +no_multiples: + ld de,$5901 ;icon #5 + cal putwidesprite + + ld ix,spr_dividerline + ld de,$6901 + cal putwidesprite + + ld a,(your_pickup) ;pickups taken + add a,a ;picks*2 (sets z-flag) + jr z,iconsdone ;return if no pickups + add a,a ;picks*4 + add a,a ;picks*8 + add a,a ;picks*$10 + add a,$09 ;add 0ah + ld d,a ;y-pos = picks * $10 + $0a (19,29,39,49,59) + ld e,$01 ;x-pos = bottom (1a01,2a01,3a01,4a01,5a01) + + ld ix,spr_icon + cal putwidesprite +iconsdone: + ld hl,dispbuffer ;normal game-screen + ld (PutWhere),hl ;set sprite-position to normal screen + + pop ix \ pop hl \ pop de \ pop bc + 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 (<25) + ld c,a ;psh a + srl a ;/2 + srl a ;/4 + srl a ;/8: don't display last 3 bits of a (later) + jr z,noarmorbar ;if a=0 then it would loop 256x so skip it + 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 + +noarmorbar: + ld a,c ;pop a + and %111 ;display last bits of armor + ret z ;if armor=0 then bit = %00000000 (don't disp) + ld b,a ;into B + xor a ;bit = %00000000 +armorbarbit: + scf ;set carry flag + rra ;rotates A right and sets bit 7 (c-flag) + 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 + +drawline: + ld (hl),a ;draw one piece of the divider-line + inc hl ;move right (8 pixels = 1 byte) + dnz drawline ;repeat (16bytes * 8pixels =128= screen width) + ret ;------------------------- fire bullet -------------------------------------- fire_multiple: psh af - dec h ;one up (-2 height: keeps weapons centered) psh ix ;save ix for next fire cal fireany ;fire from multiple position pop ix ;saving ix is much faster than recalculating @@ -1062,7 +1250,7 @@ fireOK: add ix,bc ;ix=weapon ptr ld a,(your_multiples) ;any multiples? - and %111 ;nr. of multiples + and %1111 ;nr. of multiples cal nz,fire_multiples ;if >0 then fire them too ld hl,(x) ;fire from ship position (x) fireany: ;HL=(x,y) @@ -1071,11 +1259,14 @@ fireany: ;HL=(x,y) fire_weapon: psh bc ;save counter ld a,(ix) ;load this weapon - cp %11100000 ;%11110000=laser - cal z,fire_laser ;fire laser (will set a=0 when done) - or a ;<>0=bullet - cal nz,fire_ybullet - inc ix + ld c,a ;save bulletType in c + and %11100000 ;%111?????=laser + cp %11100000 ;is it? + cal z,fire_laser ;fire laser (will set c=0 when done) + xor a ;<>0=bullet + cp c ;c<>0? + cal nz,fire_ybullet ;then fire bullet + inc ix ;otherwise fire next weapon inc ix pop bc ;weapon counter (do 3 weapons) dnz fire_weapon @@ -1093,7 +1284,6 @@ fire_tail: ;-----fire BULLETs----- fire_ybullet: ;fire bullet type=C dam=(curweapdamage) at (firex/y) - ld c,a ;save bulletType in c ld hl,ybullets ;check for unused bullet ld de,4 ld b,nrybuls @@ -1182,7 +1372,7 @@ laserhits: ;hits with normal enemies inc hl ld a,(hl) ;check x sub d - jp m,nolashit ;no hit when enemy is left of you + jr c,nolashit ;no hit when enemy is left of you inc hl ld a,(hl) ;check y sub e @@ -1201,9 +1391,10 @@ nolashit: add hl,bc ;go to next enemy ld b,a ;pop bc dnz laserhits ;check all enemies - xor a ;a=0 otherwise weird things might happen :P + xor a ld (weapincs),a ;reset damage pop ix + ld c,a ;c=0 ret ;------------------------ handle bullets ------------------------------------ @@ -1391,15 +1582,18 @@ enemy_hit: ;*in:a=damage;hl=enemy+y inc hl ;goto occ again ld (hl),%01 ;set to explode + ld a,(pickuptimer) ;counts enemies destroyed dec a ;enough destroyed for a pickup? + psh af ;save flags and a=0 jr nz,pickupdone ;otherwise just explode - ld (hl),%110 ;change it into a pickup (with 2 HP) ld a,18 ;reset enemies counter (18 hits = next) pickupdone: ld (pickuptimer),a ;save new enemiescounter value - inc hl - ld (hl),$00 ;explosionFrame 0 + inc hl ;@type + ld (hl),0 ;explosionFrame 0 or enemy #0=pickup + pop af + cal z,place_enemy ;place pickup (enemy#=0=a cuz ZF) ld hl,1 ;increase score by one jp scoreInc ;+ret @@ -1428,7 +1622,7 @@ eventtime =$-2 dec a ;has it reached 2? jr z,place_boss ;yep: place the BigBossTM! dec a ;has it reached 3? - jr nz,do_event ;nope: >3 = place an enemy + jr nz,place_ranenemy ;nope: >3 = place an enemy inc hl ;nextevent located behind eventleft ld (hl),123 ;set delay ret ;don't place any more enemies @@ -1437,10 +1631,10 @@ standby_event: ld b,nrenemies ld hl,enemies+1-enemysize ld de,enemysize + xor a chk_enemyleft: add hl,de - ld a,(hl) - or a ;0 = no enemy present + cp (hl) ;0 = no enemy present jr nz,enemyleft dnz chk_enemyleft ret @@ -1450,33 +1644,33 @@ enemyleft: ret +place_ranenemy: + ld bc,0 ;0..nrlvlenemies +nrlvlenemies =$-1 ;=nr of enemies minus 1 + cal Random ;random enemy b..b+c = 0..nrenemies-1 + ld b,0 + ld c,a ;bc=a + ld hl,lvlenemies + add hl,bc ;go to a random enemy + ld a,(hl) ;load enemy nr of this mysterious random enemy + jr place_enemy + place_boss: - ld a,1 - ld (nrlvlenemies),a ;just one enemy: the BOSS ld hl,(levelp) ;the leveldata (including the boss) dec hl ;points to leveldata\boss\enemynr - ld a,(hl) ;load it - ld (lvlenemies),a ;set new enemy (boss) + ld a,(hl) ;load enemy# of boss -do_event: +place_enemy: ;places enemy #=a + psh af ld hl,enemies+1-enemysize ld bc,enemysize xor a ;a=0 -chk_noenemy: - add hl,bc +chk_noenemy: ;find an unused (no) enemy + add hl,bc ;check next enemy cp (hl) ;(hl) = 0 ?? jr nz,chk_noenemy ;jump if enemy present (non-0) - ex de,hl ;de=hl=usable enemy - -place_enemy: ;de = enemy+1 - ld bc,0 ;0..nrlvlenemies -nrlvlenemies =$-1 ;=nr of enemies minus 1 - cal Random ;random enemy b..b+c = 0..nrenemies-1 - ld b,0 - ld c,a ;bc=a - ld hl,lvlenemies - add hl,bc ;go to a random enemy - ld a,(hl) ;load enemy nr of this mysterious random enemy + ex de,hl ;de=hl=usable enemy +1 + pop af ;enemy# to place cal findenemyspecs ;hl = enemy #a specs dec de ;goto hp64 (before occ) @@ -1520,17 +1714,18 @@ ypos_OK: ;random value successfully created inc de ;@firecounter ldi ;set time-to-1st-fire ldi ;set firefreq + ldi ; " firetype ret ;return ;--------------------------- enemy fires ------------------------------------ -Enemy_fires: ;de = x,y +Enemy_fires: ;de = x,y; c = type + ld hl,ebullets ;first bullet to check + ld b,nrebuls dec d dec d ;d = x-2 inc e ;e = y+1 - - ld b,nrebuls - ld hl,ebullets +enemy_fires_again: ;same but hl = first bullet possibly free xor a find_ebullet: cp (hl) @@ -1540,30 +1735,52 @@ find_ebullet: ret found_ebullet: - ld b,1 ;default normal bullet - ld a,(level_info) - and %00001000 - jr z,bulletok + ld a,c + sub 6 + jr c,bulletok ;type #0-5 = done (normal/diag) + or a + jr z,bulletaiming ;type #6 = aiming = type#2..5 + dec a + jr z,bullettriple ;type #7 = triple +bulletdouble: + dec e ;one up + ld c,1 ;type #1 + cal enemy_fires_again ;fire bullet + inc hl ;next bullet position + inc e + inc e ;one down + jr bulletok ;fire another bullet + +bullettriple: + ld c,1 ;type #1 = normal + cal enemy_fires_again ;fire + inc hl ;next bullet + ld c,4 ;type #4 = down 50% + cal enemy_fires_again + inc hl + ld c,5 ;type #5 = up 50% + jr bulletok + +bulletaiming: ld a,(y) sub e add a,10 jp p,bulletnotup - ld b,5 ;yourY-bulY = negative (=bullet below you) + ld c,5 ;yourY-bulY = negative (=bullet below you) add a,10 jp p,bulletnotup - ld b,3 ;yourY-bulY = even more negative (going up) - + ld c,3 ;yourY-bulY = even more negative (going up) bulletnotup: sub 20 - jp m,bulletok - ld b,4 ;bullet going down + jr c,bulletok + ld c,4 ;bullet going down (=jp m) sub 10 - jp m,bulletok ;even more going down - ld b,2 + jr c,bulletok ;even more going down + ld c,2 bulletok: - ld (hl),b ;set bullet direction + ld (hl),c ;set bullet direction inc hl ld (hl),d ;set x-pos inc hl @@ -1573,98 +1790,92 @@ bulletok: ;----------------------------- enemy bullets -------------------------------- Enemy_bullets: - ld hl,ebullets - ld b,nrebuls + ld hl,ebullets ;hl=bullet pointer + ld b,nrebuls ;number of bullets (or _possible_ bullets) handle_bullet: psh bc psh hl ld a,(hl) ;load bulletType in a or a ;bullet present? - jr nz,enemy_bullet ;non-0: handle bullet -next_bullet: - pop hl ;do not move the - pop bc - inc hl \ inc hl \ inc hl - dnz handle_bullet + cal nz,enemy_bullet ;non-0: handle bullet + pop hl ;enemy_bullet could've added one or two to hl + pop bc ;bullet counter + inc hl \ inc hl \ inc hl ;next bullet (3 bytes per bullet) + dnz handle_bullet ;loop for each and every bullet ret enemy_bullet: - ld b,a ;save type&%1111 - inc hl ;bullet x - ld a,(hl) ;check if it has reached the left side of scrn - bit 7,a ;x<0? + inc hl ;@x + ld d,(hl) ;check if it has reached the left side of scrn + bit 7,d ;x<0? jr nz,remove_ebullet ;yes, remove bullet - dec (hl) ;move one left - dec (hl) ;and another one - ld d,(hl) ;d=x - inc hl ;@y + dec d ;move one pixel left + dec d ;and another one (that makes 2) + ld (hl),d ;save new x-coordinate in (HL) and D + inc hl ;@y (BTW: x >= -2) + ld e,(hl) ;e=y - dec b + dec a jr z,ebullet_common ;type 1: normal bullet - dec b + dec a jr z,ebullet_down ;type 2: moving down - dec b + dec a jr z,ebullet_up ;type 3: moving up - ld a,(timer) - rra ;half speed + ld b,a ;save bulletType + ld a,(timer) ;load timer + rra ;half speed (CF set every other turn) jr c,ebullet_common ;if bit then normal bullet dec b jr z,ebullet_down ;type 4: moving down 50% ;type 5: moving up 50% ebullet_up: - ld a,(hl) - dec a - jp m,ebullet_common ;y<0 - ld (hl),a + dec e ;move up + jp m,ebullet_common ;ybottom? + jr z,ebullet_common ;then keep it there + ld (hl),e ;otherwise save new y ebullet_common: - ld e,(hl) ;e=y ld ix,spr_bullete1 ;display enemy bullet + psh hl cal putsprite + pop hl ;we'll need it again ebullet_hits: ld a,(your_occ) or a - jr nz,next_bullet ;0 = you're normal + ret nz ;0 = you're normal - pop hl - psh hl - inc hl ;check x - ld a,(x) + ld a,(y) ;check y collision sub (hl) add a,6 - jp m,next_bullet + ret m cp 9 - jr nc,next_bullet + ret nc - inc hl ;check y - ld a,(y) + dec hl ;check x + ld a,(x) sub (hl) add a,6 - jp m,next_bullet + ret m cp 9 - jr nc,next_bullet + ret nc - pop hl ;points to bullettype again - psh hl ;and save it again (ivm call to damage_you) - ld a,(hl) ;load bullettype - cal _shracc ;isolate damage-bits (%1111???? -> %00001111) - ld b,a ;set damage-amount + ld b,auch_bullet ;set damage-amount + psh hl cal damage_you ;HIT!! + pop hl ;save hl to remove the bullet remove_ebullet: - pop hl ;hl destroyed by damage_you + dec hl ;points to bullettype again ld (hl),0 ;bullet > unused - jr next_bullet+1 ;next bullet (SKIP THE = one byte) + ret ;--------------------------- handle enemies --------------------------------- @@ -1708,7 +1919,7 @@ enemyonscreenY: dec hl ;@x ld a,d ;new x value - cp 128 ;x<128 + cp 129 ;x<=128 jr c,enemyonscreenX ;=on screen cp -7 ;x<=-8 jr c,remove_enemy ;=off screen @@ -1717,11 +1928,6 @@ enemyonscreenX: ld a,c ;a = enemy type or a ;type 0? (pickup) jr nz,check_enemyfire ;no, a normal enemy; let em fire - ld a,(timer) ;load time - and %1 ;move left once every 2 turns - jr z,firing_done ;don't move now - inc d ;increase x-position (don't move this turn) - inc (hl) ;and save it jr firing_done ;continue check_enemyfire: @@ -1734,7 +1940,10 @@ check_enemyfire: inc hl ;@firefreq ld a,(hl) + inc hl ;@firetype + ld c,(hl) ;in c dec hl + dec hl ;@firecount again ld (hl),a ;reset counter for next blast psh de ;save registers for firing-use cal Enemy_fires ;fires bullet @@ -1856,6 +2065,7 @@ movetype_slow: ret c inc d ;don't move ret + movetype_vslow: and %11 ret z @@ -1901,16 +2111,17 @@ Enemies_hit: ld hl,enemies+1 ld b,nrenemies ;check all 20 enemies check_collision: - psh hl + psh bc ;counter + psh hl ;pointer ld a,(hl) - and %00000010 - jr z,check_next ;2 or 3 = ok - inc hl + and %00000010 ;enemy status + jr z,check_next ;2 or 3 = ok, otherwise: next enemy + inc hl ;enemy# collide_enemy: ;&&& include in Handle_enemy proc cal find_sprite - inc hl + inc hl ;@x ld a,(hl) ;check x match sub e ;enemy position minus yours minus 7 jp p,check_next @@ -1921,7 +2132,7 @@ collide_enemy: ;&&& include in Handle_enemy proc inc hl ld a,(hl) ;check y match sub d ;same as with x-check - jp p,check_next + jr nc,check_next ;(=jp p) add a,6 add a,(ix+1) ;enemy height jp m,check_next @@ -1955,30 +2166,24 @@ not_maxpickup: ld (hl),a ;remove jr check_next ;all done, next.. -destroy_enemy: - ld (hl),%01 ;set to explode - inc hl - ld (hl),0 ;explosionFrame 0 - jr collide_done - collide: dec hl ld a,(hl) - and %11111100 - jr z,destroy_enemy - ld a,(hl) - sub collidedamage + sub auch_ecollide ld (hl),a -collide_done: - ld b,collidedamage ;damage + jr nc,enemydamaged ;enemy still ok (HP>=0) + ld (hl),%01 ;set to explode + inc hl + ld (hl),0 ;explosionFrame 0 +enemydamaged: ;damage to enemy delivered + ld b,auch_collide ;your damage cal damage_you check_next: pop hl - ld a,b ;psh bc ld bc,enemysize add hl,bc - ld b,a ;pop bc + pop bc dnz check_collision ret @@ -2072,168 +2277,6 @@ SFXdelay: dnz SFXloop ret -;--------------------------- show icon -------------------------------------- - -drawline: - ld (hl),a ;draw one piece of the divider-line - inc hl ;move right (8 pixels = 1 byte) - dnz drawline ;repeat (16bytes * 8pixels =128= screen width) - ret - -disp_icons: - psh bc \ psh de \ psh hl \ psh ix ;&&& - - ld hl,VIDEO_MEM+(16*56);56 rows down = eight rows from bottom - ld (PutWhere),hl ;place icons at bottom of normal screen - ld b,16 ;draw 16x (screen width) - ld a,%11111111 ;horizontal line mask - cal drawline ;draw divider-line - - ld b,16*7 ;draw 16x (screen width) 7x (height) - xor a ;blank line mask - cal drawline ;clear scorebar - -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 - cal putwidesprite ;display icon - cal disp_armor ;display bar - - ld ix,spr_icon00 - ld a,(your_weapon) ;ur weapon - cp maxweapon ;laser? - psh af ;(your_weapon) - jr nc,no_tail ;if laser (nc) then tail ain't fired - ld a,(your_tail) - or a - jr z,no_tail - ld ix,spr_icon02 ;tailbeamIcon -no_tail: - ld de,$2901 ;icon #2 - cal putwidesprite ;display - - ld ix,spr_icon00 - pop af ;a=(your_weapon); cf=bullets - psh af - jr nc,no_bullets ;=laser - ld hl,$3945 ;position to display bullet-type digit - pop af ;digit=(your_weapon) - psh af - inc a ;1 = weapon #1 (=0) - ld (_penCol),hl ;set location - add a,'0' ;make digit - cal _vputmap ;display char - ld ix,spr_icon03 ;bulletIcon -no_bullets: - ld de,$3901 ;icon #3 - cal putwidesprite ;display icon - - ld ix,spr_icon00 ;emptyIcon - pop af ;ld a,(your_weapon) - ld b,a - jr c,no_laser ;popped carry - ld hl,$3955 ;position to display bullet-type digit - ld (_penCol),hl ;set location - ld a,b ;(your_weapon) ;load = faster than push - sub maxweapon-1 ;1 = laser #1 (=maxweapon) - add a,'0' ;make digit - cal _vputmap ;display char - ld ix,spr_icon04 ;laserIcon -no_laser: - ld de,$4901 ;icon #4 - cal putwidesprite - - ld ix,spr_icon00 ;emptyIcon - ld a,(your_multiples) - and %111 - jr z,no_multiples - ld ix,spr_icon05 -no_multiples: - ld de,$5901 ;icon #5 - cal putwidesprite - - ld ix,spr_dividerline - ld de,$6901 - cal putwidesprite - - ld a,(your_pickup) ;pickups taken - add a,a ;picks*2 (sets z-flag) - jr z,iconsdone ;return if no pickups - add a,a ;picks*4 - add a,a ;picks*8 - add a,a ;picks*$10 - add a,$09 ;add 0ah - ld d,a ;y-pos = picks * $10 + $0a (19,29,39,49,59) - ld e,$01 ;x-pos = bottom (1a01,2a01,3a01,4a01,5a01) - - ld ix,spr_icon - cal putwidesprite -iconsdone: - ld hl,dispbuffer ;normal game-screen - ld (PutWhere),hl ;set sprite-position to normal screen - - pop ix \ pop hl \ pop de \ pop bc - 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 (<25) - ld c,a ;psh a - srl a ;/2 - srl a ;/4 - srl a ;/8: don't display last 3 bits of a (later) - jr z,noarmorbar ;if a=0 then it would loop 256x so skip it - 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 - -noarmorbar: - ld a,c ;pop a - and %111 ;display last bits of armor - ret z ;if armor=0 then bit = %00000000 (don't disp) - ld b,a ;into B - xor a ;bit = %00000000 -armorbarbit: - scf ;set carry flag - rra ;rotates A right and sets bit 7 (c-flag) - 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 - ;--------------------------- proc ------------------------------------------- Random: ;a=c) +; # fixed a bug that didn't select multiples when you were moving +; # enemy collision screwed up invert and some other weird stuff +; + in pause screen change contrast with up/down and B/W mode with F1 +; + lasers can have different durations (beams last longer) +; * some sign-flag checkings replaced by carry-flag (thus reducing size) +; # slow enemies (including pickups) didn't always appear (just 25-50%) +; + enemies can fire different kinds of bullets: aiming, double, triple +; * maximum number of bullets increased (48 for enemies, 128 for you) ; ; + added - removed * changed # bug fixed -- 2.30.0