;___ÜÛÛÛ________________________________________________________ÜÜÜÜ____________ ; ÛÛÛß ÛÛÛÛÝ ; ÛÛÛ ßÛÛÛ ÞÛÛÜ ;ÞÛÛ ÜÛÛÛÜ ÜÜÛÛÛÛÜÜ ÜÛÛÛÛ ÜÛÛÜ ÜÛÛÜ ÞÛÛ ÛÛÛÛÛ ;ÛÛÝ ÛÛÛÛÛÛÛ ÜÛÛÛÛÛÛÛÛÛÛ ÛÛÛÛÛÛÛ ÛÛÛÛÛÛÛÛÛÛÛÛÜ ÛÛ ÛÛÛ ÛÛÛ ;ÛÛ ÛÛß ßÛÛ ÞÛÛßß ßÛÛÛ ÛÛÛß ÛÛÝ ÛÛß ÛÛÛÛ ßÛÛ ÛÛÝ ÞÛÛÝ ÞÛÛ ;ÛÛ ÛÛ ÛÛ ÛÛ Ü ÛÛÝ ÞÛÛÝ ÞÛÛ ÛÛÛÛÛÛ ÛÛÝ ÛÛÛ ÛÛÛ ÛÛ ;ÛÛ ÛÛ ÛÛ ÛÛ ÛÛ ÞÛÛ ÛÛÛ ÛÛÝ ÛÛÛß ÞÛÛ ßÛÛ ÛÛÛ ÞÛÛÛ ÛÛ ;ÛÛ ÛÛÝ ÞÛÛ ÛÛ ÛÛ ÛÛ ÛÛÝ ÛÛÝÞÛÛÝ ÛÛÝ ÛÛ ÛÛÛÛÛÛß ÛÛ ;ÛÛ ÞÛÛ ÛÛÝ ÞÛÛ ÛÛ ÛÛ ÛÛ ÛÛ ÞÛÛ ÛÛÝ ÛÛÝ ßÛÛÛß ÞÛÛ ;ÛÛÝ ÛÛÜ ÜÛÛ ÛÛÝ ÛÛ ÛÛ ÛÛÝ ÛÛ ÞÛÛÝ ÞÛÛÝ ÛÛÝ ÛÛÝ ;ÞÛÛ ÛÛÛÛÛ ÞÛÛ ÛÛÝ ÞÛÛ ÛÛÝ ÛÛ ßÛÛÜÜÛÛß ÛÛÛ ÞÛÛ ; ÛÛÛ ÛÛÛ ÛÛÝ ÞÛÛ ÛÛÝ ÛÛÛ ÛÛÝ ßÛÛÛÛß ÞÛÛ ÛÛÛ ; ÛÛÛÜ ÜÛÛÛÛÛÜ ÜÛÛÛ ÛÛÝ ÛÛÛ ÞÛÛÝ ÛÛÝ ÛÛÛÜÜ ÜÛÛÛ ; ÛÛÛÛÛÛÛß ßÛÛÛÛÛÛÛ ÞÛÛÜÜÛÛÛÝ ÛÛÛ ÞÛÛ ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÝ ; ßÛÛÛß ßÛÛßß ßÛÛÛÛÛß ÛÛ ÛÛÝ ßÛÛÛÛÛÛÛÛÛß ;_______________________________________________________________________________ ; ; Version : 99% (0.99.34) ; Release Date : 2002 March 4 ; Author(s) : Shiar ; Email Address : wormy@shiar.org ; Web Page : www.shiar.org ; Description : perfect Nibbles game with free movement, nine game ; modes, for 1-4 players, many levels and editor ; Where to get this game : wormy.shiar.org ; Other games by author(s) : Nemesis beta ; Additional Credits to : Matthew Shepcar : wrote original Peaworm, end'98 ; Jonah Cohen : helped writing worm ; Files : wormy.txt (9283) : 12345678901234567890123456789012 ; wormy.z80 (100k) : 515ad14b922572bdc8a96e780b8b24ca ; wormy.86g (8867) : efef32a8c541b4585087f55deb31f51d ;_______________________________________________________________________________ ;--- notes --------------------------------------------------------------------- ; * Game README is wormy.txt ; * Use for LEARNING practises ONLY! ; * Don't _ever_ release altered code w/o permission! ; * Give me credits when you use any of this stuff ; * I'm not responsible for any damage this might cause, yada yada... ; * Although I've commented & labeled quite some stuff, due to ; crazy optimizations and weird coding, it may be harder to ; understand than the average blob of code. This is probably _not_ ; the best source to learn z80 from. w00t the Shyer Way (tm). ; * Email me. If you've got suggestions|patches|questions: tell me. ; * Don't scroll down if you get scared easily. ;--- index --------------------------------------------------------------------- ; * TO_DO : future features ; * #INCLUDE ; * STORAGE : permanent; temporary; layout ; * PROG_START : search levels ; * LEV_SELECT ; * MORE_INIT : trig tables ; * MAIN_MENU : draw menu; options menu; main menu; display ; current settings; handle menukeys; change name ; * MISC_PROCS ; * START_GAME : link; client; set/send worms; host; load game; ; draw level; prepare ; * GAME_LOOP ; * KEYS : pause menu ; * GAME_OVER : who won?; display worms; quit ; * WORM_STUFF ; * WORM_ALIVE : move worm; draw worm ; * BOUNCYBALL ; * WORMY_HIT : multifood; ctf; main; foodmatch|SP; take pea; ; misc ; * PROCS ; * SCORE ; * DISPLAY ; * DRAW : pixel; findpixel; objects; circle; box; ; fatline; line ; * LINK! : multiple bytes; foo; send; recv; common ; * INT_LEVELS ; * DATA : graphics; menus; text; foo; game settings ; * THAT'S_ALL ;_______________________________________________________________________________ ; _______ _____ ______ _____ ; | | | | \ | | ; | |_____| ____ |_____/ |_____| ;_______________________________________________________________________________ ; 98% = PREVIOUS ; X [119] ED: new 53 file format with support for 128 objects instead of 32 ; X [119] LVL: episode #4: 10 hard sp levels (ordered XO-XO-XO-X) ; X [120] fixed greymask (and it now ands instead of ors) ; X [120] fixed growth set after death ; X [121] fixed linkplay (couldn't turn it on anymore..) ; X [121] LVL: Wormage + Wormage ][ (2x 10 sp levels) ; X [121] pea randomizer doesn't give x>128 ; X [121] mixed single-/multipea singleplayer levels (re)set correctly ; X [126] circles left|above 0,0 drawn correctly now! ; X [126] fixed multiple pages of levelfiles ; X [29] optimized a few more bytes (less empty bytes so prettier binary ;) ; X [225] ED: ctf/race level copy/move fix ; X [225] LVL: episode #1: 5 ctf+5 race; episode #3 removed (all in #1 now) ; X [225] add v2 id (yas2) ; X [227] redundant calls removed or moved ; X [227] fixed: ctf score increased by taking _any_ pea ; X [227] no more points in race for dieing on the second half ; X [227] no score decrease for dieing in race (no longer needed, see above) ; 99% = CURRENT ; X [34] two more jp to jr ; X [34] freeze when no space left to place pea (break after 10k tries) ; X [34] wow another bit of code 'reniced' (easter egg or something :) ; X [34] highly improved randomizer (now _really_ with values >127) ; * replace 'left' at the change-control prompt (maybe!!!) ; 1% * LINK: >Somehow do a lot of testing with 2 calcs< *sigh* ; * LVL: episode #5: 10 easy sp levels (do i _have_ to?) ; * LVL: Eric's Yumworms (ep#5?) ; * LVL: Free Bird ; * LVL: Jonah? ; * scorebar last digit (at 128-3) not displayed by _vputs ; 1% * fix any bugs that come up ;--- future features ----------------------------------------------------------- ;just a maybe-list; NO guarantees! ; ; * correct team winners ; * level compression ; * ubersized bouncies ;) ; * arrow to offscreen peas ; * w00t AI ; * sound ; * startpos ; * pause in linkplay ; * coop (DON'T COUNT ON IT) ;_______________________________________________________________________________ ; _/_/_____ __ _ _______ _ _ ______ _______ ; _/_/ | | \ | | | | | | \ |______ ; / / __|__ | \_| |_____ |_____ |_____| |_____/ |______ ;_______________________________________________________________________________ #include "asm86.h" #include "ti86asm.inc" #define cal call #define psh push #define dnz djnz _SHRACC = $4383 ;4x srl a _SHLACC = $438B ;4x sll a _divHLby10 = $4044 ;hl=hl/10 _divAby10 = $4DAF ;a=a/10 _HLTIMES10 = $41BF ;hl=hl*10 _cphlde = $403C ;cp hl,de _clrWindow = $4A86 ;clear screen _asapvar = $D6FC ;own name (worm) _MOV4B = $429B ;4x ld (de),(hl) _MOV5B = $4297 ;5x ld (de),(hl) _mov9b = $4283 ;9x ld (de),(hl) _ldHLind = $4010 ;ld hl,(hl) _swapt_ = $45F3 ;ex ahl,bde (doesn't work?) _Get_Word_ahl = $521D ;ld de,(ahl) _Set_Word_ahl = $5221 ;ld (ahl),de _INC_PTR_AHL = $4637 ;inc ahl _AHL_PLUS_2_PG3 = $4C3F ;add ahl,2 _SET_ABS_SRC_ADDR = $4647 ;set source for mm.ldir =ahl _LOAD_ABS_SRC_ADDR = $5209 ;ahl = mm.ldir source _SET_ABS_DEST_ADDR = $5285 ;set destination for mm.ldir = ahl _SET_MM_NUM_BYTES = $464F ;number of bytes for mm.ldir = ahl _mm_ldir = $52ED ;24bit ldir _MM_LDIR_SET_SIZE = $524D ;_SET_MM_NUM_BYTES + _mm_ldir _RAM_PAGE_1 = $47E3 ;set $8000+ to page 1 _RAM_PAGE_7 = $47F3 ;"""" 7 _PTEMP_END = $D29A ;end of VAT _load_ram_ahl = $462F ;ahl->page+hl _writeb_inc_ahl = $5567 ;ld (ahl++),c _jforce = $409C ;TI-OS stack restored _EXLP = $4493 ;swap (hl),(de) b times _GETB_AHL = $46C3 ;a=(ahl) \ hl=ahl _OP1TOOP6 = $4263 #define id2 ;yas2 level identifier - this'll add (65) bytes #define buffer ;use display buffer, otherwise write directly to screen (11) #define readymask ;"greys" out the field before starting a level (20) ;#define readytext ;-displays "prepare" before level starts (42) #define coolzgfx ;nice graphics for game over screen (98) #define spprotect ;options not changable for singleplayer modes ;#define intlevels ;-internal levels ;-to become invincible, define the magic word :D #define w00t levelhead = 'w' levelhead2 = 97 ;wormy levels header = "0" ;_______________________________________________________________________________ ; _______ _______ _____ ______ _______ ______ _______ ; |______ | | | |_____/ |_____| | ____ |______ ; ______| | |_____| | \_ | | |_____| |______ ;_______________________________________________________________________________ ;--- permanent ----------------------------------------------------------------- ScrBuffer = $8420 ;-A3FF (20*FF=1FE0) worm4p = $A400 ;-A5FF (200) %101001O0 ;free = $A600 ;-A7FF (200) worm2p = $A800 ;-ABFF (400) %10101O00 SinCosTable = $AC00 ;-AD00 (4*40) worm1 = $AD01 ;-AD1E (1E) worm2 = $AD1F ;-AD3C (1E) worm3 = $AD3D ;-AD5A (1E) worm4 = $AD5B ;-AD78 (1E) balls = $AD79 ;-AE00 (<=3x2D) (bb<=45) turn10 = $AE01 ;-AE01 (1) (counter) peaspos = $AE02 ;-AF05 (4-104) (peas) ;free = $AF06 ;-AFFF (F9) worm1p = $B000 ;-B7FF (800) %1011O000 worm3p = $B800 ;-BBFF (400) %10111O00 ;buffer = $BC00 ;-BF90 (390) ;free = $BF91 ;-BFFF (6F) ;program = $D748 ;-EFFF (186D+4A) ;6327 leveldata = $F080 ;-F9FF (<=97F) #ifndef intlevels datalevels = $FA00 ;-FA11 (12) (>=$C000) nrlevels = $FA12 ;-FA1B (A) (<$FA70) defspr = $F078 ;-F07F (8) #endif ;MEM|8---9---A---B---C---D---E---F---| ;there's something wrong ; |..[------]||[]|......[-----]|[].| ;if you still understand < OUTDATED < ; | SCREEN 2* 13 PRGM 4LV | ;after looking at this ;--- temporary ----------------------------------------------------------------- namelength = $BC00 ;(1) @menu datalink = $BC00 ;(8) @init #ifdef buffer DispBuffer = $BC00 ;(10x57d) @game #else DispBuffer = $FC70 #endif linklevel = $AECC ;(<=134) @game+init lefttotalb = $BF91 ;(1) @game drawctfpea1 = peaspos+4 drawctfpea2 = peaspos+6 ;--- layout -------------------------------------------------------------------- ;(wormN) offs: set: heading = 0 ;level* pos = 2 ;level* pos2 = 4 ;level grow = 6 ;level died = 8 ;game: score = 9 delay = 11 lives = 12 head = 13 ; Ú15B (wormNset) tail = 15 ; |also@next level storepos = 17 ; | reserv = 18 ; |loop (race:lap|ctf:pea) left = 19 ; | right = 20 ; | name = 21 ; |_ wormsize = 30 ;^mark^ ;_______________________________________________________________________________ ; _____ ______ _____ ______ _______ _______ _______ ______ _______ ; |_____] |_____/ | | | ____ |______ | |_____| |_____/ | ; | | \_ |_____| |_____| _____ ______| | | | | \_ | ;_______________________________________________________________________________ .org %1101011101001000 start: ;turn back NOW! nop ;and so it begins... jp Start #ifndef id2 ld bc,$5242 rst 10h .dw WormIcon #else ld (bc),a nop ld d,h rst 10h .dw WormIcon .dw WormData #endif ld d,a ld c,a ld d,d ld c,l ld e,c jr nz,$+100 ld a,c jr nz,$+$55 ld c,b .dw 16713 .db %1010010 jr nz,$+47 dec l .db " 99% .34",0 WormIcon: .db 8,2 .db %00000000,%00111100 .db %00000000,%01010010 .db %00000000,%01100001 .db %01100011,%10011001 .db %10010100,%01101001 .db %10011001,%00011001 .db %01000010,%11000001 .db %00111100,%00111110 #ifdef id2 WormData: .db 1 .dw wormlevel wormlevel: .db 4 ;priority .db 12 ;string .db "wor" ;description .dw yasexec ;execution routine .dw yascomment-yasdetect .dw yasdetect-$-1 ;detection routine .dw yasicon-yascomment .dw yascomment-$-1 ;comment routine .dw yasdataend-yasicon .dw yasicon-$-1 ;icon routine yasexec: rst 10h ex de,hl ld a,b cal skiptitle ;title (plus size+header <- all non-0) ; cal skiptitle ;description jp leveldataAHL-3 yasdetect: cal _AHL_PLUS_2_PG3 ;skip past length bytes cal _Get_Word_ahl ld hl,levelhead+(levelhead2*256) call _cphlde ret z scf ret yascomment: inc hl inc hl ;skip header ret yasicon: ld hl,$F400+levelicon-yasicon ld bc,6+(256*1) or a ret levelicon: .db %00011100 ;..XXX... ...XXX.. .db %00011110 ;.X...X.. ...XXXX. .db %00000011 ;.X..X... ......XX .db %10000001 ;X..X..XX X......X .db %01011011 ;X..X..XX .X.XX.XX .db %01101110 ;X...XXX. .XX.XXX. yasdataend: #endif int_handler: ex af,af' in a,($03) bit 3,a jp z,$0039 res 0,a out ($03),a jp $0039 int_end: ;--- search levels ------------------------------------------------------------- Start: cal _runindicoff cal _flushallmenus cal _RAM_PAGE_7 ld hl,$BFFF ;VAT start ld ix,templevels searchloop: ld de,(_PTEMP_END+1) ;VAT end or a ;nc sbc hl,de ;hlno lvls cp (ix+6) ;2nd=255 jr z,loadlevel1 ;->1 lvl levelselectmenu: ;load next page psh ix ;offset ld a,-2 ld (availevels),a cal _clrWindow ld hl,$0320 ld (_penCol),hl ld hl,txtLevsel cal _vputs ;"< SELECT LEVELS >" ld hl,$FC00+(2*16) ld b,16*9 cal menuinvloop ld hl,$FC00+$380 ;(*,56) cal hr ld hl,$0C01 ;x=1 ld (_penCol),hl dispnextlevel: ld de,3 add ix,de ;goto next ld a,(ix) ld h,(ix+1) ld l,(ix+2) cal _load_ram_ahl ;hl=ahl cal _vputs ld hl,availevels inc (hl) ld a,(ix+3) ;next inc a ;cp 255 jr z,__levselect ld hl,_penCol ld (hl),$01 ;x=1 inc hl ld a,(hl) add a,6 ld (hl),a ;y+6 cp 49 ;bottom of screen jr nc,_levselect jr dispnextlevel loadlevel1: psh ix pop hl ld b,-2 jr loadlevel readylevelfile: ;selected level at ahl ; ld hl,templevels-3/0 ld a,b add a,3 ;sellev+3 (#0==-3) ld e,a add a,a ;*2 add a,e ;*3 ld e,a ld d,0 ;de=sellev*3 add hl,de ld a,(hl) ;ade=(hl) inc hl ld d,(hl) inc hl ld e,(hl) ex de,hl ;ahl=ade skiptitle: ld d,a ;psh ahl psh hl cal _GETB_AHL ;ld a,(ahl) pop hl or a ld a,d ;pop ahl psh af cal _INC_PTR_AHL ;ahl++ pop af ;cp 0 jr nz,skiptitle ;goto #0-terminator ret levup: cal menupos dec b ;up ld a,b cp -3 jr nz,levselect inc b ;undo jr levselect levdown: cal menupos inc b ;down ld a,b cp -2 availevels =$-1 jr nz,levselect dec b ;back up levselect: cal menupos ld hl,$3900 ld (_penCol),hl pop hl psh hl cal readylevelfile cal _load_ram_ahl ;hl=ahl ld de,$FFA0 ;desc.text xor a levdescclearloop: ld (de),a ;empty inc de cp d ;de>$FFFF (offscreen) jr nz,levdescclearloop cal _vputs jr levselectmenuloop+1 __levselect: #ifdef intlevels ld ix,templevels-6 ;reset 2 1st page #else ld ix,templevels-3 #endif _levselect: ld b,-2 ;level selected jr levselect levselectmenuloop: psh hl psh bc cal ubergetkey pop bc ;GET_KEY destr. b dec a ;cp K_DOWN jr z,levdown sub K_UP-1 jr z,levup pop hl inc a ;cp K_RIGHT jp z,levelselectmenu cp K_ENTER-K_RIGHT jr z,loadlevel sub K_EXIT-K_RIGHT jp z,ExitNoStats inc a ;cp K_SECOND jr nz,levselectmenuloop ; jr z,loadlevel loadlevel: cal readylevelfile #ifdef intlevels or a ;levelfile on page 0 (=internal) jr z,levelloaded #endif cal skiptitle ;skip description leveldataAHL: cal _Get_Word_ahl ld (leveldataSize),de ld d,9 ;counter ld bc,datalevels cal loadgametype ld (hilvlposa),a ;singleplayer levels ld (hilvlposhl),hl ld d,5 cal loadgametype cal _SET_ABS_SRC_ADDR ;levelsstart xor a ld hl,leveldata cal _SET_ABS_DEST_ADDR ;store in mem. ld hl,0 leveldataSize =$-2 cal _MM_LDIR_SET_SIZE cal _LOAD_ABS_SRC_ADDR ;->ahl ld (hiscrposa),a ld (hiscrposhl),hl cal _RAM_PAGE_1 ld hl,leveldata ld de,defsprsize ldi ;(de),(hl)\inc hl ld (defsprite),hl levelloaded: cal _RAM_PAGE_1 ;_______________________________________________________________________________ ; _______ _____ ______ _______ _____ __ _ _____ _______ ; | | | | | |_____/ |______ | | \ | | | ; | | | |_____| | \_ |______ _____ __|__ | \_| __|__ | ;_______________________________________________________________________________ ; cal _runindicoff ;this is after level selection (run from yas1 or restart) ; cal _flushallmenus ;so this stuff should already be done earlier or by yas ld (SpSave),sp im 1 ld a,$D4 ld h,a ld l,0 ;ld hl,$D400 ld d,a ld e,1 ;ld de,$D401 ld b,e ld c,l ;ld bc,$0100 dec a ;ld a,$D3 ld (hl),a ldir ld hl,int_handler ld d,a ld e,a ;ld de,$D3D3 ld bc,int_end-int_handler ldir inc a ;ld a,$D4 ld i,a im 2 ;...it *does* work ;) res 2,(iy+13) ;appAutoScroll ld a,r ld (Seed),a ld hl,datasingle+3 ld b,8 ld de,8 setdeflevels: ld (hl),1 ;def=level#1 add hl,de ;next dnz setdeflevels ;--- trig tables --------------------------------------------------------------- ld hl,trigtable ;I believe this ld de,SinCosTable ;is one of the few psh de ;pieces of original ld bc,65 ;Peaworm code still ldir ;left intact.. dec hl ld b,63 MirrorSineWave: dec hl ld a,(hl) ld (de),a inc de dnz MirrorSineWave pop hl ;SinCosTable ld b,128+64 NegativeSineWave: xor a sub (hl) ld (de),a inc hl inc de dnz NegativeSineWave ;_______________________________________________________________________________ ; _______ _______ _____ __ _ _______ _______ __ _ _ _ ; | | | |_____| | | \ | | | | |______ | \ | | | ; | | | | | __|__ | \_| _____ | | | |______ | \_| |_____| ;_______________________________________________________________________________ ;--- draw menu ----------------------------------------------------------------- DisplayMenu: cal linkok cal _clrWindow ld de,$FC40 ;(0,4) ld hl,wtPicture ld a,3 optimize__w00t: ;may look like crap, but actually saves 3 bytes! ldi ld bc,6 ex de,hl add hl,bc ex de,hl ;add de,6 ld c,16-7 ;=bc ldir dec a jr nz,optimize__w00t ld c,13*16 ;=bc ldir ld hl,$FC00+$010 ;(*,01) cal hr ld hl,$FC00+$160 ;(*,22) cal hr ld hl,$FC00+$3E0 ;(*,62) cal hr dispmainmenu: ld a,(gametype) dec a ;will be inced @changegame cal changedgame ld hl,changegame ;dispmenusets ;mainMenu psh hl ;jump here after ret ld hl,txtMenu ld ix,posMenu ;Mode|Level|Link|Worms|worm #|controls ; jr dispmenucommon ;cal dispmenucommon_: ld b,36*16/4 dispmenucommon: ld de,$FD80 ;begin pos xor a clroldmenuloop: ld c,4 ld (de),a inc de dec c jr nz,clroldmenuloop+2 dnz clroldmenuloop ld b,(ix) dispmenuloop: ld d,(ix+1) inc ix ld e,(ix+1) inc ix ld (_penCol),de cal _vputs dnz dispmenuloop ; ld b,0 ;b=menu# ret hr: ;draw horizontal line at hl ld b,16 ; jp menuinvloop ;shorter but not good for pausescreen hrloop: ld (hl),-1 inc hl dnz hrloop ret ;--- options menu -------------------------------------------------------------- dispoptionmenu: ld hl,txtoMenu ld ix,posoMenu ;Back|Lives|Limit|Speed|Rotation|Growth cal dispmenucommon_ dispomenusets: #ifdef spprotect ld a,(gamecar) and _datasingl jp nz,LetsGetThisPartyOn ;SP -> start game #endif cal clrold ld hl,$1E3E ld (_penCol),hl cal loadgamecar psh hl cal cshowA ;lives ld hl,$2A3E ld (_penCol),hl pop hl ;loadgamecar inc hl \ inc hl \ inc hl psh hl ld a,(hl) ;(Speed) inc a ;1..99 jr nz,dispspeed ld hl,txtDef cal _vputs jr dispspeeddone dispspeed: cal cshowA dispspeeddone: ld hl,$363E ld (_penCol),hl pop hl ;loadgamecar inc hl psh hl ld a,(hl) ;(growth) inc a ;-1=None; 0..98->1..99 cal cshowA ld hl,$303E ld (_penCol),hl pop hl ;loadgamecar inc hl psh hl ld a,(hl) cp 8 jr nz,dispturn ld hl,txtDef cal _vputs jr dispturndone dispturn: cal cshowA ;turn speed dispturndone: ld hl,$243E ld (_penCol),hl pop hl ;loadgamecar inc hl ld a,(hl) ;(scorelimit) or a psh af cal cshowA ;limit pop af ;a==0? jr z,optionMenu ;do not display 0 behind 'None' ld a,c ;(gamecar) rla ;and _dataPmult jr nz,optionMenu ;in multifood limit == #peas ld a,'0' cal _vputmap ;x10 optionMenu: cal menupos cal menucall jr nz,notoselect oselect: cal menupos ld a,b or a ;1st item? jp z,dispmainmenu ;mainMenu jr optionMenu notoselect cp K_EXIT jp z,dispmainmenu psh af cal menupos cal loadgamecar inc hl pop af sub K_LEFT jr z,seloleft dec a ;K_RIGHT ld a,b jr nz,optionMenu seloright: dec a jr z,changelives dec a jr z,changelimit dec a jr z,changespeed dec a jr z,changeturn dec a jr z,changegrowth seloleft: ld a,b dec a jr z,bchangelives dec a jr z,bchangelimit dec a jr z,bchangespeed dec a jr z,bchangeturn dec a jr z,bchangegrowth _optionMenu: jr optionMenu changelives: cal loadgamecar ;a=(hl) inc a cp 100 jr nc,optionMenu ;>99 changedlives: ld (hl),a _dispomenusets: jp dispomenusets ;optionMenu bchangelives: cal loadgamecar sub 1 ;dec does not set cf jr c,optionMenu ;<0 jr changedlives changelimit: cal changelimitInit inc a cp 100 jr nc,optionMenu ;>99 changedlimit: ld (hl),a jr _dispomenusets ;optionMenu bchangelimit: cal changelimitInit sub 1 ;dec does not set cf jr c,optionMenu ;<0 jr changedlimit changelimitInit: cal loadgamecar ld de,6 add hl,de ld a,(hl) ;(scorelimit) ret changespeed: cal changespeedInit inc a cp 20 jr nc,_optionMenu ;>98 changedspeed: dec hl ;(Speed) ld (hl),a jr _dispomenusets ;optionMenu bchangespeed: cal changespeedInit dec a cp -2 __optionMenu: ;w/ zf jr z,_optionMenu ;<-1 jr changedspeed changespeedInit: cal loadgamecar ld de,3 add hl,de ld a,(hl) ;(Speed) inc hl ;=saves 2 bytes :P ret changeturn: cal changespeedInit inc hl ;(turnspeed) ld a,(hl) inc a cp 26 jr nc,_optionMenu ;>25 changedturn: ld (hl),a jr _dispomenusets ;optionMenu bchangeturn: cal changespeedInit inc hl ld a,(hl) dec a cp 3 jr c,_optionMenu ;<3 jr changedturn changegrowth: cal changespeedInit ld a,(hl) inc a cp 99 jr nc,_optionMenu ;>98 changedgrowth: ld (hl),a jr _dispomenusets ;optionMenu bchangegrowth: cal changespeedInit ld a,(hl) dec a cp -2 jr z,__optionMenu ;<-1 jr changedgrowth ;--- main menu ----------------------------------------------------------------- mainMenu: cal menupos cal menucall jr nz,notselect select: ;2nd/enter cal menupos ld a,b dec a ;2nd item: level jp z,dispoptionmenu sub 3 ;5th item: wormname jp z,changeworms dec a ;6th: controls jp z,changekeys jp LetsGetThisPartyOn ;otherwise changenrworms: cal change4spOnly ld a,(hl) ;hl=nrworms inc a cp 7 jr nc,mainMenu ;may not be >4+2 changednrworms: ld (hl),a jr _dispmenusets ;mainMenu notselect cp K_EXIT jp z,ExitNoStats cp K_MORE jp z,Start psh af cal menupos cal loadgamecar inc hl pop af sub K_LEFT jr z,selleft dec a ;K_RIGHT ld a,b jr nz,mainMenu selright: or a jr z,changegame dec a jr z,changelevel dec a jr z,changelink dec a jr z,changenrworms ; dec a ; jr z,changecurworm changecurworm: ld hl,curworm ld a,(hl) cp 4 jr nc,mainMenu ;may not become >4 inc (hl) jr _dispmenusets ;mainMenu selleft: ld a,b or a jr z,bchangegame dec a jr z,bchangelevel dec a jr z,bchangelink dec a jr z,bchangenrworms ; dec a ; jr z,bchangecurworm bchangecurworm: ld hl,curworm ld a,(hl) dec (hl) ;0-3 jr nz,_dispmenusets ;save >0 inc (hl) _mainMenu: jr mainMenu bchangenrworms: cal change4spOnly ld a,(hl) ;hl=nrworms dec a ;0-(3+2) cp 2 jr nc,changednrworms ;save >=2 jr _mainMenu change4spOnly: ld a,(gametype) cp 3 ret nc pop hl ;cal jr _mainMenu ;don't change for singleplayer changelink: bchangelink: cal change4spOnly dec hl ;inced earlier dec hl ;gamecar ld a,1 ;change LS-bit (=link) xor (hl) ;0=1; 1=0 ld (hl),a _dispmenusets: jr dispmenusets ;mainMenu changegame: ld a,(gametype) inc a cal changedgame jr z,changegame jr dispmenusets ;mainMenu changedgame: cp 9 jr c,changedgameok sub 255-8 ;-1 -> 8 jr nc,changedgameok xor a ;9 -> 0 changedgameok: ld (gametype),a cal getnrlevels xor a cp (hl) ret bchangegame: ld a,(gametype) dec a cal changedgame jr z,bchangegame jr dispmenusets ;mainMenu changelevel: inc hl ;hl=loadgamecar+2 psh hl ld a,(hl) ;(curlevel) cal getnrlevels cp (hl) ;max level for sel.game pop hl jr z,_mainMenu inc a changedlevel: ld (hl),a jr dispmenusets ;mainMenu bchangelevel: inc hl ld a,(hl) ;(curlevel) dec a jr nz,changedlevel jr _mainMenu getnrlevels: ;for current gametype at hl ld hl,gametype ld d,0 ld e,(hl) ld hl,nrlevels add hl,de ret getcustomkey: cal _vputs dec ix waitcustomkey: psh hl cal ubergetkey pop hl or a jr z,waitcustomkey cp K_EXIT ret z cp K_MORE jr z,waitcustomkey ld (ix),a ret changekeys: cal getwormname ld hl,txtKleft cal getcustomkey ;left cal getcustomkey ;right ; jr dispmenusets ;--- display current settings -------------------------------------------------- dispmenusets: ld de,$183E ld (_penCol),de cal clrold cal loadtxtgame cal _vputs ;Singleplayer or smtn ld hl,$2A3E ;worms ld (_penCol),hl cal loadgamecar psh hl inc hl ld a,(hl) dec a ;0-5 and 3 ;0-3 inc a ;1-4 add a,'0' cal _vputmap ld a,(hl) cp 5 ld hl,txtteamed cal nc,_vputs ld hl,$243E ld (_penCol),hl rr c ;(gamecar) ld hl,txtNo jr nc,displink ld hl,txtYes displink: cal _vputs ld hl,$1E3E ;level ld (_penCol),hl pop hl ;loadgamecar psh bc ld d,0 cal hlatlevel ld a,(gametype) or a ;gamesingle jr nz,displvlname ld a,(Level) cal cshowA00 jr lvldisped displvlname: cal _vputs lvldisped: pop bc ld hl,$3032 ld (_penCol),hl ld a,1 curworm =$-1 add a,'0' cal _vputmap ld hl,$303E ld (_penCol),hl cal getwormname psh ix ;wormNname pop hl ;ld hl,ix cal _vputs ld hl,$363E ;controls ld (_penCol),hl ld hl,txtMenuR cal _vputs jp mainMenu ;--- handle menukeys ----------------------------------------------------------- menucall: psh bc menuwaitkey: cal ubergetkey or a jr z,menuwaitkey pop bc ;GET_KEY destr. b cp K_UP cal z,menuup cp K_DOWN cal z,menudown cp K_ENTER ret z cp K_SECOND ret ;z=select menupos: ;highlight #b ld c,b ;psh b ld a,b add a,3 add a,a add a,a sub b add a,a add a,a add a,a ;*24 ld h,$FC/4 ld l,a add hl,hl add hl,hl ;$FD20+item*96 ld b,16*7 menuinvloop: ld a,(hl) cpl ld (hl),a inc hl dnz menuinvloop ld b,c ;pop b ret ;a=-1 menudown: cal menupos inc b jr menuupdown menuup: cal menupos dec b menuupdown: ld a,b cp 6 jr nz,menunewchk xor a ;6=0 menunewchk: inc b jr nz,menunewok ld a,5 ;-1=5 menunewok: ld b,a jr menupos ;--- change name --------------------------------------------------------------- getwormname: ;of (curworm) ld a,(curworm) ld e,a add a,a ;2x add a,a ;4x add a,a ;8x add a,a ;16x sub e ;15x ld e,a ld d,0 ;de=a ld ix,worm1name-15 add ix,de ret changeworms: cal getwormname psh ix pop hl ;ld hl,ix psh hl ld b,8 emptyname: ld (hl),' ' inc hl dnz emptyname ld a,maxnamesize ld (namelength),a enternameloop: ld hl,$FF07 ;begin pos ld a,6 ;nr of lines cal clroldcustom ld hl,$303E ld (_penCol),hl pop hl psh hl ld (ix),a ;clroldcustom -> a=0 cal __vputs ld a,'_' cal __vputmap nokeypressed: cal ubergetkey or a jr z,nokeypressed ld hl,namelength cp K_DEL jr nz,continue backspace: ld a,(hl) cp maxnamesize jr nc,nokeypressed inc (hl) dec ix jr enternameloop continue: ld d,0 cp K_ENTER jr z,nameentered cp K_EXIT jr z,nameentered dec (hl) ;(namelength) jr z,nameentered ld hl,chartable-1 ld e,a ;d=0 add hl,de ld a,(hl) or a jr z,nokeypressed ld (ix),a inc ix cal releasekeys jr enternameloop chartable: ;("!@#$%,0" also used in _D_HL_DECI) .db ".<>!" ;down|L|R|up|-|-|-|- .db "w00t!" ;(makes code look way better) .db "XTOJE0",-2 ;enter|+|-|*|/|^|clear|- .db " WSNID9",-3 ;(-)|3|6|9|)|tan|custom|- .db "ZVRMHC8",-4 ;.|2|5|8|(|cos|prgm|del .db "YUQLGB7#" ;0|1|4|7|ee|sin|table|xvar .db $D9,"-PKFA6'" ;on|sto|,|x2|ln|log|graph|alpha .db "54321*",-5,$D0 ;F5|F4|F3|F2|F1|2nd|exit|more nameentered: ;d=0 pop ix ;stringbegin ld (ix+8),d ;end mark jp DisplayMenu ;_______________________________________________________________________________ ; _______ _____ _______ _______ _____ ______ _____ _______ _______ ; | | | | |______ | |_____] |_____/ | | | |______ ; | | | __|__ ______| |_____ _____ | | \_ |_____| |_____ ______| ;_______________________________________________________________________________ ubergetkey: halt ;woo hoo halt ;save them batteries! yeah! jp GET_KEY clrold: ;destr:acdehl (acd=0) ld hl,$FD97 ;begin pos ld a,35 ;nr of lines clroldcustom: ld de,7 ;bytes to add clroldsettings: ld c,9 ;bytes to clear clroldsetsloop: ld (hl),d ;=0 inc hl dec c jr nz,clroldsetsloop add hl,de dec a jr nz,clroldsettings ret hlatlevel: ;d must be 0 psh hl ;loadgamecar ld a,(gametype) add a,a ld e,a ;=de ld hl,datalevels add hl,de ;+2*mode cal _ldHLind ;ld hl,(hl) ex (sp),hl ;hl=loadgamecar ld e,2 ;=de add hl,de ld a,(hl) ;(curlevel) ld (Level),a ld c,a ;begin level pop hl ;@level1 skiplevelloop: dec c ;levels to skip ret z cal skiplevel jr skiplevelloop ret ;hl=begin of correct level skiplvltitle: ;zf=singleplayer ld a,(hl) or a ;null-terminator inc hl jr nz,skiplvltitle ret skiplevel: ;@hl; de=2 - destr:ab - alter:hl ld a,(gametype) or a ;gamesingle psh af cal nz,skiplvltitle add hl,de add hl,de ;skip 4 ld b,(hl) ;spritesize inc b skipsprite: inc hl dnz skipsprite ld b,(hl) ;balls inc b inc b ;skip 6 pop af ;cp (gametype),0 jr z,skipstuff inc b ;multiplayer lvl inc b inc b ;skip other 3 worms (9 bytes) skipstuff: add hl,de inc hl ;3x(balls+2) dnz skipstuff sub gamerace ;a=(gametype) jr z,skiplaps dec a ;gamectf jr nz,skipobjects add hl,de skiplaps: add hl,de skipobjects: xor a or (hl) inc hl ;nf ret z ;0=end add hl,de add hl,de jr skipobjects loadgamecar: ;in: (gametype) ;out: hl=dataTYPE ;build: c=(gamecar)=(hl-1) ; a=(wormbeglives)=(hl) ;destr: acdehl ld hl,datasingle ld a,(gametype) add a,a add a,a add a,a ;8 bytes per mode ld e,a ld d,0 add hl,de ld a,(hl) ld (gamecar),a ld c,a inc hl ld a,(hl) ld (wormbeglives),a ret ;_______________________________________________________________________________ ; _______ _______ _______ ______ _______ ______ _______ _______ _______ ; |______ | |_____| |_____/ | | ____ |_____| | | | |______ ; ______| | | | | \_ | _____ |_____| | | | | | |______ ;_______________________________________________________________________________ LetsGetThisPartyOn: ld a,$17 ;no exit ld (CheckExit),a ;set exit state setupworms: ld hl,worm1set ld de,worm1 ld a,4 ;4x (all worms) createwormsloop: ex de,hl ld bc,died ;0008 add hl,bc ; ld b,0 ld (hl),b ;+died=0 inc hl ld (hl),b ;+score=0 inc hl ld (hl),b ;+score+1=0 inc hl ld c,2 ld (hl),c ;+delay=2 inc hl ld (hl),3 ;+lives=x wormbeglives =$-1 inc hl ex de,hl ;de=wormX+head ldir ;+head=+tail (2) dec hl dec hl ld c,wormsize-tail ;=bc ldir ;copy 15 bytes dec a ;loop jr nz,createwormsloop OhMyGodItsALabel: ;pj34r my coding skillz cal loadgamecar psh hl ;datatype cal hlatlevel ex (sp),hl ;pop \ psh leveldata psh hl ;psh loadgamecar ld a,(gamecar) rra ;and _datalink jr nc,_StartLevel ;--- link ---------------------------------------------------------------------- wormVhost = 095 wormVclient = 195 linkmatch: cal _clrWindow ld c,wormVhost cal Qsend ld hl,txtWaitn cal _puts cal Crecv ld a,c cp wormVclient jr nz,host ;--- client -------------------------------------------------------------------- client: ; ld hl,txtReceiv ; cal _puts ;shouldnt be necessary since this part always seems to work afaik ;name/keys: wormy#1 = worm #1 = ok ; 2 = link = 0 + link (name1) ; 3 = worm #2 = #2 + local(name2) ; 4 = link = 0 + link (name2) ld e,worm3+left&255 cal moveworm2 ;3=2 ld l,worm1+name&255 cal sendworm ld l,worm2+left&255 cal linkworm ;worm2+4 over link pop hl ;loadgamecar pop de ;leveldata ld de,linklevel ld hl,datalink psh de psh hl ;loadgamecar ld b,8 cal recvstuff ;game setup ld hl,gametype ;+gamecar ld b,2 cal recvstuff ;transmit game ex de,hl ld b,168 cal recvstuff ;level ld d,b cal loadtxtgame ;set CURtxtGame _StartLevel: jr StartLevel linkerror: pop hl ;error jp DisplayMenu ;return to menu ;--- set/send worms ------------------------------------------------------------ moveworm2: ld hl,worm2+left moveworm: ;hl=wormN+left ld d,worm1/256 ld bc,11 ldir ;keys+name worm(de) = worm(hl) ret linkworm: ;hl=wormN+left ld (hl),0 ;worm1|2+left inc hl inc hl ;+name ld b,9 cal recvstuff ld bc,worm3-worm1-11 ;+2 add hl,bc ;b=0 ld (hl),b ;worm3|4+left inc hl inc hl ;+name ld b,9 jp recvstuff sendworm: ;hl=wormN+name ld b,9 cal sendstuff ld bc,worm3-worm1-9 add hl,bc ;worm(N+2)+name ld b,9 jp sendstuff ;--- host ---------------------------------------------------------------------- host: cp wormVhost jr nz,linkerror ld c,wormVclient cal Qsend ;name/keys: wormy#1 = link = 0 + link (name1) ; 2 = worm #1 = #1 + local(name1) ; 3 = link = 0 + link (name2) ; 4 = worm #2 = #2 + local(name2) ld e,worm4+left&255 cal moveworm2 ;4=2 ld e,worm2+left&255 ld hl,worm1+left cal moveworm ;2=1 ld l,worm1+left&255 cal linkworm ;worm1+3 over link ld l,worm2+name&255 cal sendworm pop hl ;loadgamecar pop de ;leveldata psh de psh hl ;loadgamecar ld b,8 cal sendstuff ;setup ld hl,gametype ;+gamecar ld b,2 cal sendstuff ;game ex de,hl ld b,168 cal sendstuff ;level ;--- load level ---------------------------------------------------------------- StartLevel: pop hl ;loadgamecar ld a,(hl) ld (wormbeglives),a inc hl ;nrworms ld b,$11 ;=ignore (ld) ld a,(hl) cp 5 jr c,teamset sub 2 ld b,$CD ;=continue (call) teamset: ld (nrworms),a ld a,b ld (doteam),a ;do team score (CD) or not (11) inc hl ;level inc hl ld a,(hl) ld (customspeed),a inc hl ld a,(hl) ld (growspeed),a ld (turn),a inc hl ld a,(hl) ld (turnleft),a ld (turnright),a ;more efficient inc hl ld l,(hl) ld h,0 ld a,(gamecar) rla ;and _dataPmult ld a,h ;(Left)=256 jr nc,setscorelimit ld a,l ld l,h setscorelimit: ld (customleft),a cal _HLTIMES10 ;hl=10*(hl) ld (scorelimit),hl Nextlevel: cal _clrWindow pop hl ;begin of current level ld a,(hl) inc a ;=255? jp nz,donextlevel psh hl ld hl,Level dec (hl) ;curlevel-- (not beyond last lvl) cal releasekeys pop hl ;show end msg or smtn ld bc,Exit psh bc ;where to go afterwards inc hl ;location of ending-code jp (hl) ;go there ("call") donextlevel: ld de,gametype ld a,(de) or a ;gamesingle psh af jr nz,customnrpeas ;--sp-- inc de ld a,(de) ;gamecar rla ;prepare a rlc (hl) ;bit 7 of (hl)... rra ;...to bit 7 of (gamecar) rrc (hl) ;restore (hl) ld (de),a ld a,(hl) and 127 ;actual #peas jr setnrpeas ;--!sp-- customnrpeas: cal skiplvltitle ld a,0 customleft =$-1 setnrpeas: ld (Left),a inc a ld (lefttotal),a inc hl ld de,Speed ld a,0 customspeed =$-1 inc a ;$FF=def jr nz,setspeed ld a,(hl) ;speed from level inc a setspeed: dec a ld (de),a ;custom speed inc hl ld de,peagrowth ldi ld de,growsize ldi ld a,(hl) inc hl or a jr z,defaultsprite ld d,h ld e,l ;ld de,hl ld c,a ld b,0 ;bc=sprite size add hl,bc ;hl=behind sprite jr setsprite defaultsprite: #ifndef intlevels ld a,42 ;always overwritten #else ld a,defsprsz #endif defsprsize =$-1 defsprite =$+1 ld de,defspr setsprite: ;de=@sprite ;a=sprsize ld (sprsize),a ld (spritepos),de ld a,(hl) inc hl ld (nrballs),a or a jr z,toobad_noballs ld c,a add a,a add a,c ld c,a ld b,0 ld de,balls ldir toobad_noballs: ex de,hl #ifndef invincible ld (thislevel),de #endif ld hl,worm1 pop af ;cp (gametype),0 ld b,1 jr z,worminit ld b,4 worminit: psh bc ;>1 ex de,hl ldi ;+d ld a,SinCosTable/256 ld (de),a inc de ldi ;+y ldi ;+x ex de,hl xor a ld (hl),a ;+y2 inc hl ld (hl),a ;+x2 inc hl ld a,(growsize) ld (hl),a ;+growL inc hl xor a ld (hl),a ;+growH=0 ld bc,(worm2-worm1)-7 add hl,bc pop bc ;<0 dnz worminit inc a ;ld a,1 ld (turn10),a ld (flashtime),a ;--- draw level ---------------------------------------------------------------- initlevel: ld a,(de) inc de sub 128 jr nc,setfieldx xor a ;fieldx<128 setfieldx: ld (FieldWidth),a ld a,(de) inc de ld l,a sub 57 jr nc,setfieldy xor a ;fieldy<57 setfieldy: ld (FieldHeight),a psh de ; >> levelp ld a,l ;pop sub 5 cal ldhl32a ex de,hl ld hl,ScrBuffer psh hl ; >> 1 psh de ; >> 2 ld de,ScrBuffer+1 ld bc,63 ;first 2 rows ld (hl),%11111111 ldir ;draw upper border inc hl ld (hl),%11000000 ;first left border inc hl ld b,31 ClearLine: ld (hl),c ;=0 inc hl ;clear rest of line dnz ClearLine psh hl ; >> 3 ld a,(FieldWidth) add a,126 psh af ; >> 4 and %11111000 rra rra rra ld l,a ld h,c ;0 add hl,de pop af ; << 3 and %00000111 ld b,a ; ld c,0 ld a,%11000000 jr z,NoVertShift VertShift: rra rr c dnz VertShift NoVertShift: ld (hl),a inc hl ld (hl),c ex de,hl pop de ; << 2 pop bc ; << 1 ldir pop hl ; << 0k ld c,64 ldir pop hl ; << levelp ld a,(gametype) cp gamerace ;or gamectf jr c,levelhasbeensetup ld de,peaspos ld c,2 ;ld bc,2 (2 bytes) jr z,loadextralevelstuff ;cp gamerace ld c,4 ;ld bc,4 (2nd flag in ctf) loadextralevelstuff: ldir ld a,1 ;draw delay ld (drawctfpea1),a ld (drawctfpea2),a levelhasbeensetup: cal drawstuff ;--- prepare ------------------------------------------------------------------- leveldone: psh hl ; >> levelp new cal forceshowstats ld a,(gamecar) rla ;and _dataPmult cal c,multnewpea ;a=0 rla ;and _datafood cal nc,NewPea nofood: ld bc,(worm1+pos) cal DisplayField #ifdef readymask ld hl,$FC70 ld de,57*256+%10101010 maskloop: ld a,e cpl ld e,a ld b,$10 maskline: ld a,(hl) and e ld (hl),a inc hl dnz maskline dec d jr nz,maskloop #endif #ifdef readytext ld hl,$FDE0 ld de,$FDE1 ld (hl),%11111111 ld bc,$BF ldir ld hl,4+(txtposReady*256) ld (_curRow),hl set 3,(iy+5) ld hl,txtReady cal _puts res 3,(iy+5) #endif ld b,startdelay ReadyDelay: halt dnz ReadyDelay cal releasekeys ;_______________________________________________________________________________ ; ______ _______ _______ _______ _____ _____ _____ ; | ____ |_____| | | | |______ | | | | | |_____] ; |_____| | | | | | |______ _____ |_____ |_____| |_____| | ;_______________________________________________________________________________ GameLoop: ld bc,(worm1+pos) ;camera worm #1 ld a,(worm1+left) or a ;if #1 not over link jr nz,showfield ld bc,(worm2+pos) ;otherwise view from #2 showfield: cal DisplayField ;display piece of level ld a,1 flashtime =$-1 dec a jr z,noflash ld (flashtime),a ld hl,$fc00+(16*7) screeninvertloop: ld a,(hl) cpl ld (hl),a inc hl xor a cp h ;end at >$FFFF jr nz,screeninvertloop noflash: ld a,0 Speed =$-1 or a jr z,NoDelay Delay: halt dec a jr nz,Delay NoDelay: ld (handledworm),a ;reset ld hl,turn ld a,(hl) inc a ;-1 jr z,nextturnok dec (hl) dec a ;>=0 jr nz,nextturnok growspeed =$+1 ld (hl),$FF ;reset nextturnok: ld a,(gamecar) and _datatime jr z,nodispupdate ld hl,turn10 dec (hl) jr nz,nodispupdate ;just once every 10 turns ld (hl),10 ;reset counter cal forceshowstats ;update score nodispupdate: ld a,(gametype) cp gamectf jr nz,noctfpeas2draw ld de,drawctfpea1 ld hl,(peaspos) cal tryDrawPea ;pea#1 ld de,drawctfpea2 ld hl,(peaspos+2) cal tryDrawPea ;pea#2 noctfpeas2draw: ld a,0 nrballs =$-1 or a cal nz,handlethoseneatlittleballs ld ix,worm1 ld a,1 nrworms =$-1 ld b,a handleworms: psh bc cal HandleWorm ld bc,worm2-worm1 add ix,bc pop bc ld hl,handledworm inc (hl) ;0..nrworms-1 dnz handleworms ;_______________________________________________________________________________ ; _ _ _______ __ __ _______ ; |____/ |______ \_/ |______ ; | \_ |______ | ______| ;_______________________________________________________________________________ HandleKeys: ld a,%10111111 out (1),a in a,(1) rla ;MORE? jr nc,disppausemenu CheckExit: rla ;=$17 (c=EXIT-key) ;or$A7 (c=0) jp c,GameLoop jr Exit ;--- pause menu ---------------------------------------------------------------- disppausemenu: ld hl,txtpMenu ld ix,pospMenu ;Resume|Turn Off|Contrast|Exit|| ld b,25*16/4 cal dispmenucommon ld hl,$FC00+$170 ;(*,23) cal hr ld hl,$FC00+$310 ;(*,49) cal hr cal menupos pauseMenu: psh bc pmenuwaitkey: cal ubergetkey or a jr z,pmenuwaitkey pop bc ;GET_KEY ld d,b ;c=new b cp K_UP jr nz,pmenunotup dec d pmenunotup: cp K_DOWN jr nz,pmenunotdown inc d pmenunotdown: psh af cal menupos ld a,d ;new pos and 3 ;0-3 ld b,a cal menupos pop af cp K_ENTER jr z,pselect cp K_SECOND jr nz,notpselect pselect: ld a,b or a ;1: continue jr z,donepausing dec a ;2: off jr z,turnoff dec a ;3: contrast jr z,pauseMenu jr Exit ;4: exit notpselect cp K_EXIT jr z,donepausing ld hl,CONTRAST sub K_LEFT jr z,contrastdown dec a ;K_RIGHT jr nz,pauseMenu contrastup: inc (hl) jr setcontrast contrastdown: dec (hl) setcontrast: ld a,(hl) out (2),a jr pauseMenu turnoff: ld bc,$0103 out (c),b halt ;pause/off ld b,11 out (c),b ld b,1 jr pauseMenu donepausing: cal releasekeys jp GameLoop ;_______________________________________________________________________________ ; ______ _______ _______ _______ _____ _ _ _______ ______ ; | ____ |_____| | | | |______ | | \ / |______ |_____/ ; |_____| | | | | | |______ _____ |_____| \/ |______ | \_ ;_______________________________________________________________________________ Exit: cal releasekeys ld sp,0 ;pop all SpSave = $-2 ld a,D0LD1L out (7),a ;both wires low = game over signal cal _clrWindow #ifdef coolzgfx ld de,$FC30 ;(0,1) ld hl,wtWormy ld bc,16*7 ldir ld hl,$FC10 ld b,16*11 cal menuinvloop ;invert ld hl,$FC00+$180 cal hr ;menuinvloop w/ b=16 ld hl,$FC00+$E0 cal hr ld hl,_curRow ld (hl),2 #else ld hl,txtGO cal _puts ld hl,$FC00 ld b,16*8 cal menuinvloop ;invert inc h ;$FC00+$180 cal hr ;menuinvloop w/ b=16 ld hl,$FC00+$E0 cal hr ld hl,_curRow inc (hl) #endif ld hl,txtGame CURtxtGame =$-2 cal _puts ld a,$0D ;$0D02 ld (_curCol),a cal showLevel ld de,$1901 ld (_penCol),de ld hl,txtName cal _vputs ;Name ld a,$3C ld (_penCol),a cal _vputs ;Died Score ld de,$0004 ld (_curRow),de ;--- who won? ------------------------------------------------------------------ findwinner: ld hl,(worm1+score) ld (winnerscore),hl ld b,3 ;(nrworms)-1 ld hl,worm2+score findwinnerloop: psh hl cal _ldHLind ld de,(winnerscore) ld a,h cp d jr c,nonewwinner ;hd ld a,e cp l jr nc,nonewwinner ;l$FB) ld hl,worm1+died finddmwinner: cp (hl) jr c,nonewdmwinner ld a,(hl) ;less deaths nonewdmwinner: ld de,worm2-worm1 add hl,de dnz finddmwinner ld (dmwinner),a ;--- display worms ------------------------------------------------------------- ;x123456789012345678901 ;>>>>>> GAME OVER <<<<< ;2Multiplayer ;3Level 01 ;4 Died Score: ;5NameName 03 00070 ;6Worm#02 @ 05 00120 ;7Worm#03 15 00030 ;8Snaky @ 00 04820 ld a,(nrworms) ld b,a ld hl,worm1+died displayWormStats: psh bc psh hl ld bc,left-died add hl,bc ;+left xor a cp (hl) ;left=0 = link jr nz,NoLinkIndic ld a,9 ld (_curCol),a ld a,$DC ;-O cal _putc xor a ld (_curCol),a NoLinkIndic: inc hl inc hl ;+name cal _puts pop hl psh hl ld a,13 ld (_curCol),a ld a,(hl) ;worm+died cal showA0 pop hl psh hl ld a,(gametype) cp gamedeathm jr nz,nodmwinner ;deathmatch? ld a,0 ;winner's deaths dmwinner =$-1 cp (hl) ;equals this worm? scf ;jr nz,notwinner cal z,iswinner nodmwinner: jr c,notwinner ;no singleplayer winners inc hl ;worm+score cal _ldHLind ;ld hl,(hl) ld de,0 winnerscore =$-2 cal _cphlde ;==highest score.. cal z,iswinner notwinner: ld a,16 ld (_curCol),a pop hl psh hl inc hl ;worm+score cal _ldHLind cal _D_HL_DECI cal _puts ;showHL pop hl ld bc,worm2-worm1 add hl,bc pop bc dnz displayWormStats ld de,gametype ld a,(de) or a ;singleplayer (0) only jr nz,hilevelcheckdone checkhilevel: ld hl,nrlevels ld a,(Level) cp (hl) jr c,hilevelcheckdone ld (hl),a ;save local ld c,a ld a,0 hilvlposa =$-1 ld hl,nrlevels hilvlposhl =$-2 ;save external cal _writeb_inc_ahl ;ld (ahl),c hilevelcheckdone: inc de ld a,(de) ;gamecar and _datasingl jr z,hiscorecheckdone ;no SP checkhiscore: cal loadhiscoreposinahl ;cf=0 (and) cal _SET_ABS_SRC_ADDR ;from ahl (lvlfile) ;-wild insertation- xor a ;Be Root to fix a Unix problem ld hl,savestr ;ReBoot to fix a Windows problem cal _SET_ABS_DEST_ADDR ;to local ;W00t W00t to fix an assembly problem cal mmldir5 ;get old score+name ld de,(savestr) ;de=prev. hiscore ld hl,(worm1+score) ;hl=worm1's score cal _cphlde ;sub hl,de jr c,NotNewHigh ;newOld ld (savestr),hl ;store new hiscore ld de,savestr+2 ;to ld hl,worm1+name ;from ld bc,3 ;3 chars ldir ;store new hiname cal loadhiscoreposinahl ;cf=0 (jr c) cal _SET_ABS_DEST_ADDR ;to ahl xor a ld hl,savestr cal _SET_ABS_SRC_ADDR ;from local cal mmldir5 ;save new score+name ld hl,_curRow dec (hl) cal iswinner NotNewHigh: ld hl,$3149 ld (_penCol),hl ld hl,txthiscore cal _vputs ld hl,$0C07 ld (_curRow),hl ld hl,savestr+2 cal _puts ld hl,_curCol inc (hl) ld hl,(savestr) cal _D_HL_DECI cal _puts ;showHL hiscorecheckdone: waitkey: ld hl,DisplayMenu psh hl ;main menu waitkeyloop: cal ubergetkey cp K_ENTER ret z cp K_SECOND ret z cp K_EXIT jr nz,waitkeyloop ret loadhiscoreposinahl: sbc hl,hl ;cf=0 ld a,(gametype) or a ;Singleplayer? jr z,hi__ dec a ;peaworm? jr z,hi_ ld a,(nrlevels+1) ;skip peaworm slots if tron mode hi_: ld bc,(Level) add a,c ld b,a ;levels to skip (including 1 for singleplayer) ld de,5 ;to add per level addlevelposition: add hl,de ;one word+3 bytes for name dnz addlevelposition hi__: xor a ;ahl=0(+hl) ld bc,defhiscrpos hiscrposhl =$-2 add hl,bc hiscrposa =$+1 adc a,0 ;ahl=saveloc ret savestr: ;hiscore (00AAA) _D_HL_DECI (00000) .db $BB,"w00t",0 iswinner: ld a,10 ld (_curCol),a ld a,'*' jp _putc ;..then put * ;--- quit ---------------------------------------------------------------------- ExitNoStats: cal linkok ld hl,_asapvar rst 20h ;_ABS_MOV10TOOP1 rst 10h ;_FINDSYM ld hl,savestart-_asm_exec_ram+4 xor a add hl,de adc a,b ;ahl=bde+4 cal _SET_ABS_DEST_ADDR xor a ld hl,savestart cal _SET_ABS_SRC_ADDR ld hl,saveend-savestart cal _MM_LDIR_SET_SIZE cal releasekeys res 4,(iy+9) set 2,(iy+13) im 1 ;remove keyfix jp _clrWindow ;_______________________________________________________________________________ ; _ _ _ _____ ______ _______ _______ _______ _ _ _______ _______ ; | | | | | |_____/ | | | |______ | | | |______ |______ ; |__|__| |_____| | \_ | | | _____ ______| | |_____| | | ;_______________________________________________________________________________ respawncheck: cp rspawndelay-1 jr nz,unnamedlabel cal saverespawncounter removeworm: ld h,(ix+tail+1) ld l,(ix+tail) ld d,(ix+head+1) ld e,(ix+head) jr DoesWormTailEqualsWormHead ;chk4 size=0 removewormloop: cal removetailbit inc (ix+grow) jr nz,DoesWormTailEqualsWormHead inc (ix+grow+1) ;+256 DoesWormTailEqualsWormHead: cal _cphlde jr nz,removewormloop ;head=tail/size=0 ld a,(gamecar) and _datasingl jr nz,savetailpos ld (ix+grow+1),a ;=0 ld a,0 growsize =$-1 ld (ix+grow),a savetailpos: ld (ix+tail+1),h ld (ix+tail),l ret unnamedlabel: cp 1 ld h,a jr nz,saverespawncounter respawndue: ld l,a cal inputcall ld a,h ;previous cp l ;changed? ret z ld (ix+delay),a ;=0 ret saverespawncounter: ld (ix+delay),a jr inputcall chkkey: ;key=a dec a ld b,a srl b srl b srl b ;b=a/8 and 7 ;a=a\8 ld c,a ;push keybit ld a,-1 out (1),a inc b ld a,%01111111 ;default bitmask: rlca ;rotate left dnz bitmask ;a/8 times out (1),a ;send bitmask in a,(1) ;input keys ld b,c ;pop keybit inc b keybit: rra dnz keybit ;check match (cf set) ret inkeys: ;use jp not call! cal chkkey jr nc,notright ld a,l add a,8 turnright =$-1 ld l,a notright: ld a,(ix+right) cal chkkey ret nc ld a,l sub 8 turnleft =$-1 ld l,a ret inputcall: ld a,(ix+left) or a jr z,inlink ;input by link cal inkeys ;input by keys ld a,(gamecar) rra ;and _datalink ret nc ;no link ld c,l ;send our keys jp Qsend inlink: cal Qrecv ;Crecv ld l,c ret ;_______________________________________________________________________________ ; _ _ _ _____ ______ _______ _______ _____ _ _ _______ ; | | | | | |_____/ | | | |_____| | | \ / |______ ; |__|__| |_____| | \_ | | | _____ | | |_____ __|__ \/ |______ ;_______________________________________________________________________________ HandleWorm: xor a cp (ix+lives) jr nz,alive ld a,(wormbeglives) or a ret nz ;live limit alive: ld a,(ix+delay) dec a jp nz,respawncheck xor a cp 0 turn =$-1 jr nz,nogrow inc (ix+grow) nogrow: ld a,(gamecar) and _datatime jr z,notimescore ld e,1 cal IncScore notimescore: ld l,(ix+heading) cal inputcall donediddelydone: ld (ix+heading),l ld h,(ix+heading+1) ld c,(ix+pos) ld b,(ix+pos+1) ld e,(ix+pos2) ld d,(ix+pos2+1) ;--- move worm ----------------------------------------------------------------- wormmove: psh bc ;pos ld a,(hl) add a,a add a,d ld d,a bit 7,(hl) jr z,notnegX dec b notnegX: jr nc,notmoveX inc b notmoveX: ld a,l add a,$40 ld l,a ld a,(hl) add a,a add a,e ld e,a bit 7,(hl) jr z,notnegY dec c notnegY: jr nc,notmoveY inc c notmoveY: ;bc=newpos ld (ix+pos2),e ld (ix+pos2+1),d ;-check- pop hl ;pos (old) ld a,h sub b ;Xold-Xnew and 1 ;abs ld h,a ld a,l sub c and 1 ;|Yold-Ynew| add a,h ;pixels moved |Dx|+|Dy| ld d,4 ;same pos = 4of4 bytes drawn jr z,GotFour xor 3 ;1 pixel = 2of4 blank; 2 pixels = 3of4 blank ld d,a ;#pixels that should be drawn GotFour: cal chk4pixels ;d-=pixels at b,c rl d ;<0 meaning there were >d pixels cal c,hitworm ;so that wasn't us ;--- draw worm ----------------------------------------------------------------- drawworm: ld (ix+pos),c ld (ix+pos+1),b ld a,(gametype) cp gamerace cal z,checkhitlapline cal set4pixels dec c ld a,(growspeed) or a ;0=tron ret z ;keep tail in "Tron" ld l,(ix+head) ld h,(ix+head+1) ld (hl),c inc hl ld (hl),b inc hl ;(resbit) ld a,h and (ix+storepos) ld h,a ld (ix+head),l ld (ix+head+1),h ld l,(ix+grow) ld h,(ix+grow+1) dec hl ld a,h or l jr z,removetail ld (ix+grow),l ld (ix+grow+1),h ret removetail: ld l,(ix+tail) ld h,(ix+tail+1) cal removetailbit cal savetailpos ;ld (ix+tail),hl ld c,(hl) inc hl ld b,(hl) jr set4pixels ;redraw new last bit removetailbit: ld c,(hl) inc hl ld b,(hl) inc hl ;(resbit) ld a,h and (ix+storepos) ld h,a psh hl cal res4pixels ;rm last bit pop hl ret res4pixels: cal ResPixel inc b cal ResPixel inc c cal ResPixel dec b ResPixel: cal FindPixel cpl and (hl) ld (hl),a ret ;_______________________________________________________________________________ ; ______ _____ _ _ __ _ _______ __ __ ______ _______ ; |_____] | | | | | \ | | \_/ |_____] |_____| | | ; |_____] |_____| |_____| | \_| |_____ | |_____] | | |_____ |_____ ;_______________________________________________________________________________ handlethoseneatlittleballs: ld hl,balls ld b,a ;a=(nrballs) handleballs psh bc psh hl ld c,(hl) inc hl ld b,(hl) inc hl ld d,(hl) cal handleball dec c pop hl ld (hl),c inc hl ld (hl),b inc hl ld (hl),d inc hl pop bc dnz handleballs ret handleball: cal res4pixels dec c ballxmove: bit 0,d ;1=L; 0=R jr z,ballright ballleft: dec b cal checkballhit jr z,ballymove inc b ;undo res 0,d ;go right jr ballymove ballright: inc b cal checkballhit jr z,ballymove dec b ;back set 0,d ;>left ballymove: bit 1,d ;1=up; 0=down jr z,balldown ballup: dec c cal checkballhit jr z,balldone inc c res 1,d ;go down jr balldone balldown: inc c cal checkballhit jr z,balldone dec c set 1,d ;up balldone: set4pixels: ;@(b,c) cal SetPixel inc b cal SetPixel inc c cal SetPixel dec b SetPixel: ;at bc cal FindPixel or (hl) ld (hl),a ret letsmovetheotherway: ld a,1 xor (hl) ld (hl),a ret checkballhit: psh de ld d,0 cal chk4pixels xor a cp d pop de ret ;_______________________________________________________________________________ ; _ _ _ _____ ______ _______ __ __ _ _ _____ _______ ; | | | | | |_____/ | | | \_/ |_____| | | ; |__|__| |_____| | \_ | | | | _____ | | __|__ | ;_______________________________________________________________________________ ;--- multifood ----------------------------------------------------------------- chkmultpeas: ld de,peaspos-1 ld hl,lefttotalb lefttotal =$+1 ld (hl),0 chkmultpealoop: ex de,hl inc hl ld e,(hl) inc hl ld d,(hl) ex de,hl psh de cal chkpeahit pop de jr c,pickmultpea ld hl,lefttotalb dec (hl) jr nz,chkmultpealoop jr _wormdead pickmultpea: ld a,247 ld (de),a dec de ld (de),a jp pickedpea ;--- ctf ----------------------------------------------------------------------- chkctfpeas: ;ctf ld hl,(peaspos) ;1st pea ld a,(ix+reserv) ld e,a ;push a and %01 ;ourpea (0|1) jr z,sel_otherpea ld hl,(peaspos+2) ;2nd pea sel_otherpea: cal chkpeahit jr c,hitflag ;no peas hit: ld a,e ;peek a (that's x86asm for pop\push ;) bit 1,a ;%1O = carrying flag? jr z,_wormdead ;if not just die and %1 ;which flag? ld hl,drawctfpea1 ;restore #1 jr nz,nottheotherflag inc hl ;ld hl,drawctfpea2 inc hl ;restore #2 nottheotherflag: ld (hl),3 ;draw delay 3 turns _wormdead: jp wormdead hitflag: ;correct pea hit ld a,e ;pop a xor %11 ;invert flag taken + ownflag ld (ix+reserv),a and %10 ;just returned? psh bc ;safe position psh af ;safe z-flag cal DrawPea ;remove pop af pop bc ret nz ;flag taken: continue game ;drawworm ld e,20 ;flag captured+returned psh bc cal IncScore pop bc ld a,3 ;draw delay ld (drawctfpea1),a ;redraw.. ld (drawctfpea2),a ;..both flags ret ;drawworm ;--- main ---------------------------------------------------------------------- hitworm: ld a,(gamecar) bit __bitPctf,a jr nz,chkctfpeas rla ;and _dataPmult jr c,chkmultpeas rla ;and _datafood jr c,_wormdead ;no food ;--- foodmatch|SP -------------------------------------------------------------- ld hl,0 PeaY =$-2 PeaX =$-1 cal chkpeahit jp nc,wormdead ;--- take pea ------------------------------------------------------------------ psh hl cal NewPea pop hl pickedpea: cal DrawPea ;remove pea ld a,(ix+grow) ;grow add a,15 peagrowth =$-1 ld (ix+grow),a jr nc,wormset2grow inc (ix+grow+1) wormset2grow: ld hl,Left dec (hl) ;dec left _before_ display psh af ld e,10 cal IncScore pop af ld c,(ix+pos) ;same position ld b,(ix+pos+1) ;we'll just leave pos2 - doubt anybody will care|notice.. ret nz ;(Left)>0 ;drawworm ld a,(gametype) or a jp nz,Exit ;stack restored ld hl,Level ld a,(hl) inc (hl) ld l,a ;hl=Level ld h,0 add hl,hl add hl,hl cal _HLTIMES10 ex de,hl cal _IncScore ;score+(40*level) cal removeworm pop hl ;<yline -> a=1 xor a ;y a=0 checklap: cp (ix+reserv) ret z ;same as before ld (ix+reserv),a ;1st time ld e,a ld a,(handledworm) and 1 ;group 0 (1,3) or 1 (2,4) xor e ret z ;(group 0 and yyline) psh bc ld e,20 cal IncScore ;lap! pop bc ret ;_______________________________________________________________________________ ; _____ ______ _____ _______ _______ ; |_____] |_____/ | | | |______ ; | | \_ |_____| |_____ ______| ;_______________________________________________________________________________ releasekeys: ;---------->promise me you'll never let go... halt ;-------------------->i won't let go.... ld a,%10000000 ;all key-masks out (1),a in a,(1) ;--------------->i'll never let go..... inc a ;cp %11111111 (no keys pressed) jr nz,releasekeys ;keep waitin cal GET_KEY ;clear buffer ret ;--------------------->*die* (we are VICTORIOUS! muha) randompos: ld b,a Random: ;(2..b+2) ld a,r ;0..127 scf ;not just even values: rla ;6543210C Seed =$+1 add a,0 ld (Seed),a cp b jr nc,Random add a,2 ret ldhl32a: ld l,a ld h,0 ;=hl add hl,hl add hl,hl add hl,hl add hl,hl add hl,hl ;32=scr.width ret ;ld hl,32*a mmldir5: ld hl,5 ;=ahl cal _MM_LDIR_SET_SIZE jp _RAM_PAGE_1 wormdead: pop hl ;<0: don't exit dnz checklives anyworm: ld a,$A7 ;exit@end of turn ld (CheckExit),a ;set exit state ret ;finish turn loadtxtgame: ;in:d=0; out:hl=txtGame+(gametype); destr:ade ld a,(gametype) ld e,a ld hl,posGame add hl,de ;hl=posGame+(gametype) ld a,(hl) ;str.offset ld e,a ;^d=0^ ld hl,txtGame add hl,de ;txtGameX ld (CURtxtGame),hl ;save for g/o ret CheckPea: ;@hl; destr:abcde ld c,l ld a,(sprsize) ld e,a chkloopy: ld b,h ld a,(sprsize) ld d,a chkloopx: psh hl cal FindPixel and (hl) pop hl ret nz ;nz=pixel found inc b dec d jr nz,chkloopx inc c dec e jr nz,chkloopy ret ;z=empty space tryDrawPea: ;hl=peapos;bc=dopea ld a,(de) or a ;0=drawn ret z psh de cal CheckPea pop de ret nz ;unsuccesful ex de,hl dec (hl) ;hl=appeartime ex de,hl ;hl=peaspos jr z,DrawPea ret multnewpea: ld de,peaspos ld a,(Left) ld b,a multpealoop: psh bc psh de cal NewPea pop de ld hl,PeaY ldi ldi pop bc dnz multpealoop ld a,-1 ret NewPea: ld de,$293A ;counter :) newpealoop: dec de ld a,d or e jp z,Exit ;break after 10554 tries to prevent freeze when field filled ld a,(FieldWidth) add a,126 cal randompos ld h,a ld a,(FieldHeight) add a,55 cal randompos ld l,a psh de cal CheckPea pop de ;counter jr nz,newpealoop cal sendnewpeaoverlink ld (PeaY),hl DrawPea: ;hl=(PeaY) ld b,h ld c,l drawpea_: ld de,0 spritepos =$-2 ; jp PutSprite PutSprite: ;||@(b,c) ;by SHIAR only ix saved cal FindPixel ld (beginbit),a ld a,0 sprsize =$-1 ld b,a ;rows sprloopy: psh bc ;rows psh hl ld a,(de) ld c,a inc de ld a,(sprsize) ld b,a ;width beginbit =$+1 ld a,1 sprloopx: sla c ;draw? jr nc,sprnodraw psh af xor (hl) ld (hl),a pop af sprnodraw: rrca ;next bit jp nc,nextbitok inc hl ;next byte nextbitok: dnz sprloopx pop hl ld bc,32 ;next line add hl,bc pop bc dnz sprloopy ret ;_______________________________________________________________________________ ; _______ _______ _____ ______ _______ ; |______ | | | |_____/ |______ ; ______| |_____ |_____| | \_ |______ ;_______________________________________________________________________________ addteamscore: ld a,(handledworm) cp 2 ld de,worm3-worm1 jr c,bla ld de,worm1-worm3 bla: psh ix add ix,de ex de,hl cal ldscoreinhl pop ix add hl,de ret _divHLby1000: psh hl ld b,3 divideagain: ;3x cal _divHLby10 dnz divideagain ld a,l ;a=hl/1000 pop hl ret DecScore10: cal ldscoreinhl ld de,-10 add hl,de jr nc,showstats ;<0=0 jr scorecommon extralives: cal _divHLby1000 ld c,a add hl,de ;increase score cal _divHLby1000 cp c jr z,scorecommon ;hl/1000 not increased inc (ix+lives) jr scorecommon timematchscore: ;piece of crap checking whether you've already won in timematch ld a,(nrworms) ld b,a ;# of worms dec a ret z ;singleplayer ld hl,worm1+lives ld de,worm2-worm1 ld a,(handledworm) ld c,a ;wormcounter chktimematchover: xor a cp c jr z,nneexxtt ;yourself cp (hl) ret nz ;someone else still alive dec hl ;+del0ay dec hl ;+score+1 ld a,(hl) cp (ix+score+1) jr c,nneexxtt_ ;you>him ret nz ;not highest dec hl ;+score ld a,(hl) cp (ix+score) ret nc ;you<=him inc hl nneexxtt_: inc hl inc hl nneexxtt: dec c add hl,de dnz chktimematchover jp anyworm ;g/o IncScore: ;inc score by e ld d,0 _IncScore ; inc by de cal ldscoreinhl ld a,(gametype) or a ;if singleplayer... jr z,extralives add hl,de ;score+=de scorecommon: ld (ix+score+1),h ld (ix+score),l ;save doteam: cal addteamscore ;cal=CD | ld de,*=11 ld de,0 scorelimit =$-2 ld a,d or e jr z,showstats ;de=0=no limit cal _cphlde jp nc,Exit showstats: ld a,(gamecar) and _datatime jr nz,timematchscore ;no disp for timematches forceshowstats: psh ix and a sbc hl,hl ;hl=0 ld (_penCol),hl ld a,(nrworms) ld b,a ld ix,worm1 ld a,(gamecar) and _datasingl jr nz,showstatsS showstatloop: #ifdef gamenames #ifdef longnames psh bc ld b,3 psh ix shownameloop: ;1st 3 chars ld a,(ix+name) or a jr z,nameshown cal __vputmap inc ix dnz shownameloop nameshown: ld a,':' cal _vputmap pop ix pop bc #else ld a,(ix+name) cal __vputmap ld a,':' cal __vputmap #endif #endif ld a,(wormbeglives) or a cal nz,showlives ;lives when initlives>0 ld a,' ' cal __vputmap ;small div ld a,(gametype) cp gamedeathm cal nz,showscore ;score in !dm ld a,$D8 cal __vputmap ;div ld de,worm2-worm1 add ix,de ;next dnz showstatloop pop ix ret showscore: cal ldscoreinhl psh bc cal _D_HL_DECI pop bc jr __vputs cshowA: ;small w/ leading 0; 0='none' or a ;destr. ahl jr nz,cshowA00 ld hl,txtNone jp _vputs showlives: ld a,(ix+lives) cshowA00: ;small w/ leading 0 ld l,a ld h,0 cal _divHLby10 psh af ld a,l add a,'0' cal __vputmap pop af cshowA0: add a,'0' __vputmap: psh ix cal _vputmap pop ix ret showstatsS: ;(singleplayer) ld hl,txtLevel cal __vputs ld a,0 Level =$-1 cp 10 psh af cal c,cshowA0 pop af cal nc,cshowA00 ld a,97 ld (_penCol),a cal showscore ld a,123 ld (_penCol),a ld a,(ix+lives) cal cshowA0 ;showlives ld a,(gamecar) and _datafoodl pop ix ret z showleft: ld a,33 ld (_penCol),a ld a,0 Left =$-1 cal cshowA ld hl,txtLeft __vputs: psh ix cal _vputs pop ix ret showLevel: ld hl,txtLevel cal _puts ld a,(Level) showA0: ;big w/ leading 0 ld l,a ld h,0 cal _divHLby10 psh af ld a,l add a,'0' cal _putc pop af add a,'0' jp _putc _D_HL_DECI: ld de,savestr+5 ld b,5 ldhld: cal _divHLby10 add a,'0' dec de ld (de),a dnz ldhld ex de,hl ;ld hl,savestr ret ldscoreinhl: ld h,(ix+score+1) ld l,(ix+score) ret ;_______________________________________________________________________________ ; ______ _____ _______ _____ _______ __ __ ; | \ | |______ |_____] | |_____| \_/ ; |_____/ __|__ ______| | |_____ | | | ;_______________________________________________________________________________ DisplayField: ;all done by Jonah Cohen iirc. (-scrolling is scary-) ld a,c ;not the fastest routine outthere, but it does get the job done. sub 29 ;if something doesn't work, I probably _did_ alter it ;) jr nc,NotMinYScroll xor a NotMinYScroll: cp 43 FieldHeight =$-1 jr c,NotMaxYScroll ld a,(FieldHeight) NotMaxYScroll: cal ldhl32a psh bc ; >> 1 psh de ; >> 2 ld de,ScrBuffer add hl,de ld a,b sub 64 jr nc,NotMinXScroll xor a NotMinXScroll: cp 128 FieldWidth = $-1 jr c,NotMaxXScroll ld a,(FieldWidth) NotMaxXScroll: psh af ; >> 3 and %11111000 rra rra rra ld c,a ld b,0 ld de,DispBuffer pop af ; << 2 and %00000111 psh af ; >> 3 cp 6 jr c,CopyScreen inc c CopyScreen: add hl,bc ld b,57 CopyScreenLoop: psh bc ; >> 4 ld bc,16 ldir ld c,16 add hl,bc pop bc ; << 3 dnz CopyScreenLoop pop af ; << 2 ld c,$b7 ;or a Bit0: jr nz,Bit1 halt halt jr AfterShiftDelay Bit1: dec a jr nz,Bit2 cal ShiftRight1 jr AfterShiftDelay Bit2: dec a jr nz,Bit3 ld a,2 cal ShiftRight jr AfterShiftDelay Bit3: dec a jr nz,Bit4 cal Chunk cal ShiftLeft1 jr AfterShift Bit4: dec a jr nz,Bit5 cal Chunk jr AfterShiftDelay Bit5: dec a jr nz,Bit6 cal Chunk cal ShiftRight1 jr AfterShift Bit6: dec a jr nz,Bit7 ld a,2 cal ShiftLeft jr AfterShift Bit7: cal ShiftLeft AfterShiftDelay: halt AfterShift: #ifdef buffer ld hl,DispBuffer ld de,$fc00+$70 ld bc,1024-$70 ldir #endif pop de ; << 1 pop bc ; << 0k ret ShiftRight1: ld a,1 ShiftRight: ld (ShiftRightCounter),a ld a,c ld (ShiftRightChunk),a ld c,16 add hl,bc ld b,57 ShiftRightLoop: psh bc ld bc,-32 add hl,bc ex de,hl ld a,(de) ShiftRightChunk: or a cal c,_SHLACC ld c,0 ShiftRightCounter = $-1 ShiftRowsLeft: psh hl rla ld b,16 ShiftRowLeft: dec hl rl (hl) dnz ShiftRowLeft pop hl dec c jr nz,ShiftRowsLeft ld bc,-16 add hl,bc ex de,hl pop bc dnz ShiftRightLoop ret ShiftLeft1: ld a,1 ShiftLeft: ld (ShiftLeftCounter),a ld a,c ld (ShiftLeftChunk),a rla jr nc,ShiftLeftSameByte dec hl ShiftLeftSameByte: ex de,hl ld bc,-16 add hl,bc NewSprite: ex de,hl ld b,57 ShiftLeftLoop: psh bc ; >> 1 ld bc,-32 add hl,bc ex de,hl ld a,(de) ShiftLeftChunk: or a cal c,_SHRACC ld c,0 ShiftLeftCounter = $-1 ShiftRowsRight: psh hl ; >> 2 rra ld b,16 ShiftRowRight: rr (hl) inc hl dnz ShiftRowRight pop hl ; << 1 dec c jr nz,ShiftRowsRight ld bc,-16 add hl,bc ex de,hl pop bc ; << 0k dnz ShiftLeftLoop ret Chunk: psh hl ; >> 1 psh de ; >> 2 ld c,16 add hl,bc ld b,57 ChunkScreen: psh bc ; >> 3 ld bc,-32 add hl,bc ex de,hl ld a,(de) cal _SHRACC ld b,16 ChunkRow: dec hl rld dnz ChunkRow ex de,hl pop bc ; << 2 dnz ChunkScreen pop de ; << 1 pop hl ; << 0k ld c,$37 ;scf ret ;_______________________________________________________________________________ ; ______ ______ _______ _ _ _ ; | \ |_____/ |_____| | | | ; |_____/ | \_ | | |__|__| ;_______________________________________________________________________________ ;--- pixel --------------------------------------------------------------------- chk4pixels: cal CheckPixel inc b cal CheckPixel inc c cal CheckPixel dec b cal CheckPixel dec c ret CheckPixel: ;at bc in d cal FindPixel and (hl) ret z dec d ret ;--- findpixel ----------------------------------------------------------------- ;Based on Snake86's findpixel ;160-262 cycles; 31 bytes FindPixel: ;(b,c) to hl:a psh bc ld h,0 ld l,c ;hl=y add hl,hl add hl,hl ld a,b ;a=x rra add hl,hl rra add hl,hl add hl,hl ;hl=32y rra ;a=x/8 or l ld l,a ld a,b ;x and 7 inc a ld b,a ld a,1 pixelloop: rrca dnz pixelloop ld bc,ScrBuffer add hl,bc pop bc ;destr:none ret ;--- objects ------------------------------------------------------------------- drawstuff: ld a,(hl) inc hl or a ;0 = ret z ;no more ld d,(hl) inc hl ld e,(hl) inc hl ld b,(hl) inc hl psh hl ld l,(hl) ld h,b cal drawsmtn pop hl inc hl jr drawstuff drawsmtn: dec a ;1 = line jr z,drawline dec a ;2 = fatline jr z,drawfatline dec a ;3 = box jr z,drawbox ; dec a ;4 = circle ; jp z,drawcircle ;--- circle -------------------------------------------------------------------- ;IMHO, one weery nice routine. Oh lemme be proud just *once*. ;Not perfect since it uses a screwy lineroutine to draw stuff ;but, just _look_ at it. Ain't it grand? Z80 at its best. ;Nice comments, also. So here we go: Shiar's Circle Routine: ;(using the Bresenham method) drawcircle: ;(d,e),h ;de=x,y; h=z ld c,h ;c=yy=z ld a,h neg ld l,a ;l=-z xor a ld b,a ;b=xx=0 dec a ;-$00** ld h,a ;hl=zz=-z circloop: psh de ;x,y ex (sp),hl ;push zz \ pop x,y cal circledraw ;(x-xx,y+yy)-(x+xx,y+yy) ;(x-xx,y-yy)-(x+xx,y-yy) cal circledraw ;(x-yy,y+xx)-(x+yy,y+xx) ;(x-yy,y-xx)-(x+yy,y-xx) ex (sp),hl ;push x,y \ pop zz xor a ld d,a ;d=0 dec a ;-256=yy inc b ;xx++ jr circloop circledraw: ;destr:de psh hl ld a,h ;hl=x,y sub b ;bc=xx,yy jr nc,$+3 ;x x=0 ld d,a ;d=x-xx add hl,bc ;h=x+xx; l=y+yy ld e,l ;e=y+yy cal drawline ;(h-b,l+c)-(h+b,l+c) ld a,l sub c ;a=y again sub c jr nc,$+3 ;y y=0 ld l,a ;l=y-yy ld e,l ;e=l=y-yy cal drawline ;(h-b,l-c)-(h+b,l-c) ld a,b ;swap xx and yy ld b,c ld c,a ;ex b,c pop hl ret ;thats it ;--- box ----------------------------------------------------------------------- drawbox: ;(d,e)-(h,l) ld b,l ;Delta-y ld l,e boxloop: cal drawline inc l inc e dnz boxloop ret ;--- fatline ------------------------------------------------------------------- drawfatline: cal drawline inc d inc h cal drawline inc e inc l cal drawline dec d dec h ; jp drawline ;--- line ---------------------------------------------------------------------- ;A lot like Scabby's line routine in Wonderworm (dunno whether he wrote it ;himself tho.) I did make a few optimizations and commented the thing. ;A nice routine (also Bresenham), but for Wormy not perfect since really ;large lines (>128 pixels in length or something) won't be flawless. drawline: ;(d,e)-(h,l) psh bc ;destr: a psh hl psh de ld a,d ;a=d=x cp h ;h=xx jr c,lineXincs ;if x>xx ex de,hl ;make x ld c,a ;c=mask (always) ld a,h ;a=xx sub b ;xx-x ld b,a ;b=deltax (always>0) ld a,l ;a=yy jr nz,lineexists ;deltax!=0 cp e ;yy==y jr nz,lineexists ;deltay!=0 pop hl ; :