;___ÜÛÛÛ________________________________________________________ÜÜÜÜ____________ ; ÛÛÛß ÛÛÛÛÝ ; ÛÛÛ ßÛÛÛ ÞÛÛÜ ;ÞÛÛ ÜÛÛÛÜ ÜÜÛÛÛÛÜÜ ÜÛÛÛÛ ÜÛÛÜ ÜÛÛÜ ÞÛÛ ÛÛÛÛÛ ;ÛÛÝ ÛÛÛÛÛÛÛ ÜÛÛÛÛÛÛÛÛÛÛ ÛÛÛÛÛÛÛ ÛÛÛÛÛÛÛÛÛÛÛÛÜ ÛÛ ÛÛÛ ÛÛÛ ;ÛÛ ÛÛß ßÛÛ ÞÛÛßß ßÛÛÛ ÛÛÛß ÛÛÝ ÛÛß ÛÛÛÛ ßÛÛ ÛÛÝ ÞÛÛÝ ÞÛÛ ;ÛÛ ÛÛ ÛÛ ÛÛ Ü ÛÛÝ ÞÛÛÝ ÞÛÛ ÛÛÛÛÛÛ ÛÛÝ ÛÛÛ ÛÛÛ ÛÛ ;ÛÛ ÛÛ ÛÛ ÛÛ ÛÛ ÞÛÛ ÛÛÛ ÛÛÝ ÛÛÛß ÞÛÛ ßÛÛ ÛÛÛ ÞÛÛÛ ÛÛ ;ÛÛ ÛÛÝ ÞÛÛ ÛÛ ÛÛ ÛÛ ÛÛÝ ÛÛÝÞÛÛÝ ÛÛÝ ÛÛ ÛÛÛÛÛÛß ÛÛ ;ÛÛ ÞÛÛ ÛÛÝ ÞÛÛ ÛÛ ÛÛ ÛÛ ÛÛ ÞÛÛ ÛÛÝ ÛÛÝ ßÛÛÛß ÞÛÛ ;ÛÛÝ ÛÛÜ ÜÛÛ ÛÛÝ ÛÛ ÛÛ ÛÛÝ ÛÛ ÞÛÛÝ ÞÛÛÝ ÛÛÝ ÛÛÝ ;ÞÛÛ ÛÛÛÛÛ ÞÛÛ ÛÛÝ ÞÛÛ ÛÛÝ ÛÛ ßÛÛÜÜÛÛß ÛÛÛ ÞÛÛ ; ÛÛÛ ÛÛÛ ÛÛÝ ÞÛÛ ÛÛÝ ÛÛÛ ÛÛÝ ßÛÛÛÛß ÞÛÛ ÛÛÛ ; ÛÛÛÜ ÜÛÛÛÛÛÜ ÜÛÛÛ ÛÛÝ ÛÛÛ ÞÛÛÝ ÛÛÝ ÛÛÛÜÜ ÜÛÛÛ ; ÛÛÛÛÛÛÛß ßÛÛÛÛÛÛÛ ÞÛÛÜÜÛÛÛÝ ÛÛÛ ÞÛÛ ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÝ ; ßÛÛÛß ßÛÛßß ßÛÛÛÛÛß ÛÛ ÛÛÝ ßÛÛÛÛÛÛÛÛÛß ;_______________________________________________________________________________ ; ; Version : 98% (0.98.118) ; Release Date : 2002 January 18 ; 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 ; Where to get this game : www.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.z80 (89kB) : 515ad14b922572bdc8a96e780b8b24ca ; wormy.86p (6512) : 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 stuff inhere ; * 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, 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 ;_______________________________________________________________________________ ; _______ _____ ______ _____ ; | | | | \ | | ; | |_____| ____ |_____/ |_____| ;_______________________________________________________________________________ ; 97% = PREVIOUS ; X [15] lives >9 dispay ; X [15] sp modes not configurable ; X [16] LVL: episode #2: 10 sp levels ; X [17] lives stats for every liveslimited game (also !dm) ; X [18] LINK: fix transmit game/level data ; X [19] datalevels+nrlevels not in program if !intlevels ; X [19] mem at worm #4 (still 12 bytes or so.. or more? or less?) ; X [19] alter level editor to use new address and set level id #97 ; X [19A] team score! ; X [19A] autogrowth doesn't always work -> init (turn) ; X [111] ED: disabled objects counted causing CRASH when writing hiscore! ; X [111] LINK: init+multiple pea transmit seems to work.. ; X [111] LINK: host/client swapped (host now sends level config) ; X [111] LINK: optimize transmit (most initcode same for client+host) ; X [113] menu limit in multifm not x10 ; X [113] wormhit procedure seperate (called now) ; X [114] LINK: peas sent again :P ; X [114] internal level check and sprite storage removed ; X [115] layout data stuff at bottom ; X [115] ED: init place bar fixed ; X [115] ED: keys also usable together with mouse ; X [115] ED: improved version handling ; X [115] LINK: receive message not needed anymore afaik ; X [115A] $D8 used for spacing at g/o screen. i rule B) ; X [115A] exit at g/o goes back to menu ; X [115A] more in menu lets you reselect the levelfile ; X [115A] LINK: fixed waiting mode (minor display problem) ; X [116] incs at skiplevels effectively replaced by add (-4 bytes) ; X [116] another 2 bytes shaved off ; X [116] LINK: received gamemode now displayed correctly at g/o ; X [116] gamecar right after gametype saves about 20 bytes ; X [116] LINK: minimize sent data ; X [116] remove +input in worm storage ; X [116] head position init uses same data as tail (-4 bytes) ; X [116] fix bug at no levels (115A intro) ; X [117] saved 6 bytes by hardcoding some empty bytes in title graphics ; X [117] two pieces of duplicate code removed ; X [117] combined temporary storage for _D_HL_DECI and temp hiscore ; X [117] more repetitious code shortened ; X [117] wrong stack handling in checkpea, and unnecessary bloat ; X [117] stopworm after eating pea (pea|wall overwrite fixed!) ; X [117] old code removed from hitworm ; X [117] replace jps by jrs (moved code around a bit) ; X [117] scorebar doesn't diplay 1st wormname char anymore ; X [117] scorebar can display both lives and score when appropriate ; X [118] look at init-z in line routine again -> fixed steepline init-z ; X [118] snake86 findpixel (saves 1 byte) ; X [118] removed flash at new level start ; X [118] begin growth set in normal worm init loop ; X [118] bad code and potentially bad code reviewed and optimized ; X [118] final sourcecode layout ((sub)captions, index, indents, etc) ; 98% = CURRENT ; 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) ; 1% * LINK: >Somehow do a lot of testing with 2 calcs< *sigh* ; * LVL: episode #1: add 2-3 circle- and line levels. ; * LVL: episode #3: 6x5 multiplayer levels ; * LVL: episode #5: 10 easy sp levels (do i _have_ to?) ; * LVL: Eric? (ep#5?) ; * LVL: Wormage ; * LVL: Free Bird ; * LVL: Jonah? ; 1% * fix any bugs that come up ;--- future features ----------------------------------------------------------- ;just a maybe-list; NO guarantees! ; ; * correct team winners ; * level compression ; * arrow to offscreen peas ; * 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 _Get_Word_ahl = $521D ;ld de,(ahl) _Set_Word_ahl = $5221 ;ld (ahl),de _INC_PTR_AHL = $4637 ;ahl=ahl+1 _AHL_PLUS_2_PG3 = $4C3F ;ahl=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 #define buffer ;use display buffer (otherwise write directly to screen) #define readymask ;"greys" out the field before starting a level #define coolzgfx ;nice graphics for game over screen #define spprotect ;options not changable for singleplayer modes ;#define intlevels ;-internal levels ;#define readytext ;-displays "prepare" before level starts ;#define invincible ;-worms cannot die =) ;_______________________________________________________________________________ ; _______ _______ _____ ______ _______ ______ _______ ; |______ | | | |_____/ |_____| | ____ |______ ; ______| | |_____| | \_ | | |_____| |______ ;_______________________________________________________________________________ ;--- 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-260) (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) 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 ld bc,$5242 rst 10h .dw WormIcon 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 " 98% .118",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 levelhead = 'w' levelhead2 = 97 ;wormy levels header = "97" int_handler: ex af,af' in a,($03) bit 3,a jp z,$0039 res 0,a out ($03),a jp $0039 int_end: Start: ld (SpSave),sp cal _runindicoff cal _flushallmenus 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 ;) ;--- search levels ------------------------------------------------------------- restart: 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,$0601 ;x=1 ld (_penCol),hl dispnextlevel: ld de,3 add ix,de ld a,(ix) ld b,a inc a ;cp 255 jr z,__levselect displevel: 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 ld hl,availevels inc (hl) ld a,b ;(ix+0) ld h,(ix+1) ld l,(ix+2) ;ahl=(ix) cal _load_ram_ahl ;hl=ahl cal _vputs 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 levselectmenu+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 levselectmenu: 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,levselectmenu ; jr z,loadlevel loadlevel: cal readylevelfile #ifdef intlevels or a ;levelfile on page 0 (=internal) jr z,levelloaded #endif cal skiptitle ;skip description 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 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) rra ;and _datasingl jp nc,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,restart 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),0 cal __vputs ld (ix),' ' 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: 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 ld 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: pop ix ;stringbegin ld (ix+8),0 ;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) and _datalink jr z,_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 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 bc,gametype ld a,(bc) or a ;gamesingle psh af cal nz,skiplvltitle ld a,(hl) and 127 jr nz,setleft customleft =$+1 ld a,0 setleft: ld (Left),a inc a ld (lefttotal),a dec a xor (hl) ;bit (hl),7 inc bc ;gamecar ld a,(bc) jr z,leftloaded or 128+32 leftloaded: ld (bc),a inc de 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 #ifdef readymask ld hl,$FC70 ld d,%10101010 ld c,56 maskloop: ld a,d xor %11111111 ld d,a ld b,$10 maskline: ld a,(hl) or d ld (hl),a inc hl dnz maskline dec c 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 a,(gamecar) rla ;bit __bitPmult,a cal c,multnewpea ;a=0 rla ;bit __bitfood,a cal nc,NewPea nofood: ld bc,(worm1+pos) cal DisplayField 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 jp Exit ;jr? ;--- 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 rra ;and _datasingl jr c,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) rra ;and _datasingl jr nc,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) and _datalink ret z ;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 cal resbit 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 cal resbit 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 ;%10 = carrying flag? jr z,_wormdead ;if not just die xor %11 ;drop flag ld (ix+reserv),a ld hl,drawctfpea1 ;restore #1 jr z,nottheotherflag ;which flag? (=and %1) 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 af ;safe z-flag psh bc ;safe position cal DrawPea ;remove ld e,20 ;flag captured+returned cal z,IncScore pop bc pop af ret nz ;flag taken: continue game ;drawworm 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 jr 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: halt ld a,%10000000 ;all key-masks out (1),a in a,(1) inc a ;cp %11111111 (no keys pressed) jr nz,releasekeys ;keep waitin cal GET_KEY ;clear buffer ret resbit: ld a,h and (ix+storepos) ld h,a ret randompos: ld b,a Random: ;(2..b+2) ld a,r Seed =$+1 add a,0 ld (Seed),a and %01111110 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 a,(FieldWidth) add a,127-4 cal randompos ld h,a ld a,(FieldHeight) add a,56-4 cal randompos ld l,a cal CheckPea jr nz,NewPea 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) rra ;and _datasingl jr nc,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 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 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 ; :