3 ; Release Date : summer 2001
4 ; Filename : wormy.86p (5kb)
6 ; Email Address : wormy@shiar.org
7 ; Web Page : www.shiar.org
8 ; Description : ruling Nibbles-like game 1-4 players
9 ; Where to get this game : www.shiar.org (home of Wormy)
10 ; Other games by author(s) : Nemesis beta
11 ; Additional Credits to : Matthew Shepcar (wrote original Peaworm, end'98)
12 ; Jonah Cohen (helped writing worm)
14 ;-----------------------------
15 ;----------- TO-DO -----------
16 ;-----------------------------
20 ; [* internal levels ]
21 ; [ * check levels/gametype ]
22 ; [ * enough hiscore saves! ]
23 ; [* complete readme ]
24 ; 1% * misc (pollish, bugs, &&&)
26 ; * fix first packet loss
27 ; 1% * transmit game/level data
28 ; 1% * 1/3 worms over link
29 ;;;1% * get g/o signal (l&l) working
30 ;;;1% * send new peas' positions
32 ;100% = bugs fixed + levels done
34 ;-----------------------------
35 ;-----------------------------
36 ;--------- W O R M ---------
37 ;-----------------------------
38 ;-----------------------------
40 #define buffer ;use display buffer (otherwise write directly to screen)
41 #define readymask ;"greys" out the field before starting a level
42 #define coolzgfx ;nice graphics for game over screen
44 ;#define readytext ;displays "prepare" before level starts
45 ;#define invincible ;worms cannot die =)
46 ;#define optdie ;in race games worms don't die when they run into each other
53 #include "ti86asm.inc"
55 _SHRACC = $4383 ;4x srl a
56 _SHLACC = $438B ;4x sll a
57 _divHLby10 = $4044 ;hl=hl/10
58 _divAby10 = $4DAF ;a=a/10
59 _HLTIMES10 = $41BF ;hl=hl*10
60 _cphlde = $403C ;cp hl,de
61 _clrWindow = $4A86 ;clear screen
62 _asapvar = $D6FC ;own name (worm)
63 _MOV4B = $429B ;4x ld (de),(hl)
64 _MOV5B = $4297 ;5x ld (de),(hl)
65 _mov9b = $4283 ;9x ld (de),(hl)
66 _ldHLind = $4010 ;ld hl,(hl)
67 _swapt_ = $45F3 ;ex_ahl_bde
68 _Get_Word_ahl = $521D ;ld de,(ahl)
69 _Set_Word_ahl = $5221 ;ld (ahl),de
70 _INC_PTR_AHL = $4637 ;ahl=ahl+1
71 _AHL_PLUS_2_PG3 = $4C3F ;ahl=ahl+2
72 _SET_ABS_SRC_ADDR = $4647 ;set source for mm.ldir =ahl
73 _LOAD_ABS_SRC_ADDR = $5209 ;ahl = mm.ldir source
74 _SET_ABS_DEST_ADDR = $5285 ;set destination for mm.ldir = ahl
75 _SET_MM_NUM_BYTES = $464F ;number of bytes for mm.ldir = ahl
76 _mm_ldir = $52ED ;24bit ldir
77 _MM_LDIR_SET_SIZE = $524D ;_SET_MM_NUM_BYTES + _mm_ldir
78 _RAM_PAGE_1 = $47E3 ;set $8000+ to page 1
79 _RAM_PAGE_7 = $47F3 ;"""" 7
80 _PTEMP_END = $D29A ;end of VAT
81 _load_ram_ahl = $462F ;ahl->page+hl
82 _writeb_inc_ahl = $5567 ;ld (ahl++),c
83 _jforce = $409C ;TI-OS stack restored
84 _EXLP = $4493 ;swap (hl),(de) b times
85 _GETB_AHL = $46C3 ;a=(ahl) \ hl=ahl
87 ;-----------------------------
88 ;------- data storage -------
89 ;-----------------------------
93 ScrBuffer = $8820 ;-A7FF (20*FF=1FE0)
94 worm2p = $A800 ;-ABFF (400) %10101O00
95 worm1 = $AC00 ;-AC1D (31d)
96 worm2 = $AC1F ;-AC3B (1F)
97 worm3 = $AC3E ;-AC59 (1F)
98 worm4 = $AC5D ;-AC77 (1F)
99 balls = $AC7C ;-ACFF (3x43d)
100 SinCosTable = $AD00 ;-AE00 (4*40)
101 ;free $AE01 ;-AFFF (1FF)
102 worm1p = $B000 ;-B7FF (800) %1011O000
103 worm3p = $B800 ;-BBFF (400) %10111O00
104 ;free $BF91 ;-BFFF (6F)
105 ;program $D748 ;-EFFF (186D+4A)
106 worm4p = $F000 ;-F3FF (400) %11110O00
107 leveldata = $F400 ;-FA70 (<=671)
109 turn10 = $AE01 ; (1) (counter)
110 peaspos = $AE02 ;-AE05 (4) (peas)
112 ;MEM|8---9---A---B---C---D---E---F---|
113 ; |..[------]||[]|......[-----]|[].|
114 ; | SCREEN 2* 13 PRGM 4LV |
118 namelength = $BC00 ;(1) @menu
120 DispBuffer = $BC00 ;(10x57d) @game
125 ;-----------------------------
126 ;------- program start -------
127 ;-----------------------------
143 .db "WORMY by SHIAR -- beta 95%",0
146 .db %00000000,%00111100
147 .db %00000000,%01010010
148 .db %00000000,%01100001
149 .db %01100011,%10011001
150 .db %10010100,%01101001
151 .db %10011001,%00011001
152 .db %01000010,%11000001
153 .db %00111100,%00111110
156 levelhead2 = 95 ;wormy levels header = "95"
187 ld bc,int_end-int_handler
194 ld hl,$BFFF ;VAT start
197 ld de,(_PTEMP_END+1) ;VAT end
227 ex de,hl ;ld ahl,(hl)
228 cal _AHL_PLUS_2_PG3 ;string id
229 cal _Get_Word_ahl ;ld de,(ahl)
233 jr nz,_searchnext ;not worm
237 inc ix ;save level's ahl
250 cal _Get_Word_ahl ;ld de,(ahl++)
252 ld a,e ;set new level
277 cal _vputs ;"< SELECT LEVELS >"
297 cp 49 ;bottom of screen
305 ld l,(ix+2) ;ahl=(ix)
306 cal _load_ram_ahl ;hl=ahl
310 readylevelfile: ;selected level at ahl
313 add a,3 ;sellev+3 (#0==-3)
329 cal _GETB_AHL ;ld a,(ahl)
334 cal _INC_PTR_AHL ;ahl++
336 jr nz,skiptitle ;goto #0-terminator
362 cal _load_ram_ahl ;hl=ahl
363 ld de,$FFA0 ;desc.text
368 cp d ;de>$FFFF (offscreen)
369 jr nz,levdescclearloop
373 ld ix,templevels-6 ;reset 2 1st page
375 ld b,-2 ;level selected
381 pop bc ;GET_KEY destr. b
399 or a ;levelfile on page 0 (=internal)
401 cal skiptitle ;skip description
404 ld (leveldataSize),de
409 ld (hilvlposa),a ;singleplayer levels
414 cal _SET_ABS_SRC_ADDR ;levelsstart
417 cal _SET_ABS_DEST_ADDR ;store in mem.
420 cal _MM_LDIR_SET_SIZE
422 cal _LOAD_ABS_SRC_ADDR ;->ahl
429 ldi ;(de),(hl)\inc hl
434 res 2,(iy+13) ;appAutoScroll
442 ld (hl),1 ;def=level#1
446 ;-----------------------------
447 ;----- build trig tables -----
448 ;-----------------------------
473 ;-----------------------------
474 ;---------- menu -------------
475 ;-----------------------------
477 DisplayMenu: ;---draw menu---
484 ld hl,$FC00+$010 ;(*,01)
486 ld hl,$FC00+$160 ;(*,22)
488 ld hl,$FC00+$3E0 ;(*,62)
493 dec a ;will be inced @changegame
496 ld hl,changegame ;dispmenusets ;mainMenu
497 psh hl ;jump here after ret
500 ;Mode|Level|Limit|Worms|worm #|controls
501 ; jr dispmenucommon ;cal
504 ld de,$FD80 ;begin pos
528 hr: ;draw horizontal line at hl
537 ;Back|Lives|Limit|Speed|Rotation|Growth
552 inc hl \ inc hl \ inc hl
570 inc a ;-1=None; 0..98->1..99
585 cal cshowA0 ;turn speed
592 ld a,(hl) ;(scorelimit)
597 jr z,optionMenu ;do not display 0 behind 'None'
609 jp z,dispmainmenu ;mainMenu
653 cal loadgamecar ;a=(hl)
656 jr nc,optionMenu ;>99
660 jp dispomenusets ;optionMenu
663 sub 1 ;dec does not set cf
671 jr nc,optionMenu ;>99
674 jr _dispomenusets ;optionMenu
677 sub 1 ;dec does not set cf
684 ld a,(hl) ;(scorelimit)
691 jr nc,_optionMenu ;>98
695 jr _dispomenusets ;optionMenu
701 jr z,_optionMenu ;<-1
708 inc hl ;=saves 2 bytes :P
717 jr nc,_optionMenu ;>25
720 jr _dispomenusets ;optionMenu
735 jr nc,_optionMenu ;>98
738 jr _dispomenusets ;optionMenu
744 jr z,__optionMenu ;<-1
756 dec a ;2nd item: level
758 sub 3 ;5th item: wormname
762 jp LetsGetThisPartyOn ;otherwise
793 jr nc,mainMenu ;may not become >(nrworms)
797 jr _dispmenusets ;mainMenu
810 ; jr z,bchangecurworm
815 jr nz,changedcurworm ;save >0
820 ld a,(hl) ;hl=nrworms
823 jr nc,mainMenu ;may not be >4
826 jr _dispmenusets ;mainMenu
830 ld a,(hl) ;hl=nrworms
834 ld a,(hl) ;hl=nrworms
837 jr nc,changednrworms ;save >=2
846 jr _mainMenu ;don't change for singleplayer
851 dec hl ;inced earlier
853 ld a,1 ;change LS-bit (=link)
857 jr dispmenusets ;mainMenu
864 jr dispmenusets ;mainMenu
877 jr dispmenusets ;mainMenu
880 inc hl ;hl=loadgamecar+2
882 ld a,(hl) ;(curlevel)
884 cp (hl) ;max level for sel.game
890 jr dispmenusets ;mainMenu
893 ld a,(hl) ;(curlevel)
898 getnrlevels: ;for current gametype at hl
925 cal getcustomkey ;left
926 cal getcustomkey ;right
929 ;---display current settings---
939 add hl,de ;hl=posGame+(Gametype)
940 ld a,(hl) ;str.offset
944 ld (CURtxtGame),hl ;save for g/o
945 cal _vputs ;Singleplayer
994 ld hl,$363E ;controls
1000 ;--- handle menukeys ---
1008 pop bc ;GET_KEY destr. b
1018 menupos: ;highlight #b
1031 add hl,hl ;$FD20+item*96
1061 ;--- change name ---
1064 getwormname: ;of (curworm)
1092 ld hl,$FF07 ;begin pos
1125 dec (hl) ;(namelength)
1140 .db 0,".<>!",0,0,0,0 ;down,L,R,up
1141 .db 0,"XTOJE0",0 ;enter..clear
1142 .db " WSNID9",0 ;(-)..custom
1143 .db "ZVRMHC8",0 ;dot..del
1144 .db "YUQLGB7#" ;0..xvar
1145 .db $D9,"-PKFA6'" ;on..alpha
1146 .db "54321*",0,$D0 ;F5..more
1150 ld (ix+8),0 ;end mark
1157 halt ;save them batteries! yeah!
1161 ld hl,$FD97 ;begin pos
1162 ld a,35 ;nr of lines
1164 ld de,7 ;bytes to add
1166 ld c,9 ;bytes to clear
1171 jr nz,clroldsetsloop
1174 jr nz,clroldsettings
1177 hlatlevel: ;d must be 0
1179 ld a,(Gametype) ;8bytes -> 7bytes
1184 add a,24+1 ;go to datalevels
1186 sbc hl,de ;datalevels
1187 cal _ldHLind ;ld hl,(hl)
1188 pop de ;de=loadgamecar
1190 ld a,(de) ;(curlevel)
1194 dec d ;levels to skip
1198 ret ;hl=begin of correct level
1200 skiplvltitle: ;zf=singleplayer
1202 or a ;null-terminator
1207 skiplevel: ;@hl - destr:ab - alter:hl
1216 ld b,(hl) ;spritesize
1224 pop af ;cp (Gametype),0
1226 inc b ;multiplayer lvl
1228 inc b ;skip other 3 worms (9 bytes)
1262 ;build: c=(gameCar)=(hl-1)
1263 ; a=(wormbeglives)=(hl)
1269 add a,a ;8 bytes per mode
1281 ;-----------------------------
1282 ;-------- start game ---------
1283 ;-----------------------------
1287 ld (CheckExit),a ;set exit state
1305 ld (turnright),a ;more efficient
1309 cal _HLTIMES10 ;hl=10*(hl)
1333 jp DisplayMenu ;return to menu
1349 ;-----------------------------
1350 ;--------- game over ---------
1351 ;-----------------------------
1356 ld a,4 ;4x (all worms)
1366 ld (hl),b ;score+1=0
1373 ex de,hl ;de=wormX+head
1377 jr nz,createwormsloop
1381 pop hl ;begin of current level
1388 dec (hl) ;curlevel-- (not beyond last lvl)
1391 ;show end msg or smtn
1393 psh bc ;where to go afterwards
1394 inc hl ;location of ending-code
1395 jp (hl) ;go there ("call")
1408 ld a,(hl) ;speed from level
1412 ld (de),a ;custom speed
1431 ld b,0 ;bc=sprite size
1432 add hl,bc ;hl=behind sprite
1439 setsprite: ;de=@sprite ;a=sprsize
1463 pop af ;cp (Gametype),0
1471 ld a,SinCosTable/256
1482 ld bc,(worm2-worm1)-5
1492 ;-------- draw level ---------
1518 add hl,hl ;32=scr.width
1525 ld bc,63 ;first 2 rows
1527 ldir ;draw upper border
1529 ld (hl),%11000000 ;first left border
1534 inc hl ;clear rest of line
1574 cp gamerace ;or gamectf
1575 jr c,levelhasbeensetup
1577 ld c,2 ;ld bc,2 (2 bytes)
1578 jr z,loadextralevelstuff ;cp gamerace
1579 ld c,4 ;ld bc,4 (2nd flag in ctf)
1580 loadextralevelstuff:
1589 ;-----------------------------
1591 psh hl ; >> levelp new
1619 ld hl,4+(txtposReady*256)
1630 jr nc,initfinished ;no link
1632 SwapPos: ;$18 xx -> $E6 xx
1636 ld (worm1+left),a ;worm 1...
1637 ld (worm3+left),a ;and worm 3 via link
1666 ld (worm2+left),a ;worm 2+4..
1667 ld (worm4+left),a ;..over link
1690 ;-----------------------------
1691 ;----------- LOOP ------------
1692 ;-----------------------------
1695 ld bc,(worm1+pos) ;camera worm #1
1697 or a ;if #1 not over link
1699 ld bc,(worm2+pos) ;otherwise view from #2
1701 cal DisplayField ;display piece of level
1716 jr nz,screeninvertloop
1729 ld (handledworm),a ;reset
1747 jr nz,nodispupdate ;just once every 10 turns
1748 ld (hl),10 ;reset counter
1749 cal forceshowstats ;update score
1754 jr nz,noctfpeas2draw
1757 cal tryDrawPea ;pea#1
1760 cal tryDrawPea ;pea#2
1767 cal nz,handlethoseneatlittleballs
1780 inc (hl) ;0..nrworms-1
1783 ;-----------------------------
1784 ;---------- keys -------------
1785 ;-----------------------------
1800 rla ;=$17 (c=EXIT-key)
1811 ld (ix+delay),respawndelay
1830 ld (ix+pos2+1),a ;x2
1837 cp gamectf ;ctf no death penalty
1840 ret nz ;HandleWorm done
1842 or a ;0=no live limit
1843 ret z ;don't end game
1846 jr z,anyworm ;quit at any worm's death
1847 ld a,(nrworms) ;timematch: all worms must've died
1849 ld hl,worm1+lives-(worm2-worm1)
1851 xor a ;check for 0 lives
1853 add hl,de ;next worm
1855 ret nz ;any >0: don't exit
1858 ld a,$A7 ;exit@end of turn
1859 ld (CheckExit),a ;set exit state
1868 out (7),a ;both wires low = game over signal
1877 cal menuinvloop ;invert
1879 cal hr ;menuinvloop w/ b=16
1889 cal menuinvloop ;invert
1891 cal hr ;menuinvloop w/ b=16
1910 cal _vputs ;Died Score
1925 jr c,nonewwinner ;h<d
1926 jr nz,newwinner ;h>d
1929 jr nc,nonewwinner ;l<e
1940 cpl ;high value (>$FB)
1945 ld a,(hl) ;less deaths
1952 ;---display worms---
1964 cp (hl) ;input=0 = link
1981 ld a,(hl) ;worm+died
1988 jr nz,nodmwinner ;deathmatch?
1989 ld a,0 ;winner's deaths
1991 cp (hl) ;equals this worm?
1992 scf ;jr nz,notwinner
1995 jr c,notwinner ;no singleplayer winners
1997 cal _ldHLind ;ld hl,(hl)
2000 cal _cphlde ;==highest score..
2015 dnz displayWormStats
2018 or a ;singleplayer (0) only
2019 jr nz,hilevelcheckdone
2024 jr c,hilevelcheckdone
2025 ld (hl),a ;save local
2030 hilvlposhl =$-2 ;save external
2031 cal _writeb_inc_ahl ;ld (ahl),c
2036 jr z,hiscorecheckdone ;no SP
2038 cal loadhiscoreposinahl
2039 cal _SET_ABS_SRC_ADDR ;from ahl (lvlfile)
2042 cal _SET_ABS_DEST_ADDR ;to local
2044 cal _MM_LDIR_SET_SIZE ;get old score+name
2047 ld de,(highsave) ;de=prev. hiscore
2048 ld hl,(worm1+score) ;hl=worm1's score
2049 cal _cphlde ;sub hl,de
2050 jr c,NotNewHigh ;new<old
2051 jr z,NotNewHigh ;new<=old
2053 ld (highsave),hl ;store new hiscore
2054 ld de,highsave+2 ;to
2055 ld hl,worm1+name ;from
2057 ldir ;store new hiname
2058 cal loadhiscoreposinahl
2059 cal _SET_ABS_DEST_ADDR ;to ahl
2062 cal _SET_ABS_SRC_ADDR ;from local
2064 cal _MM_LDIR_SET_SIZE ;save new
2092 ;x123456789012345678901
2093 ;>>>>>> GAME OVER <<<<<
2098 ;6Worm#02 @ 05 00120
2105 rst 20h ;_ABS_MOV10TOOP1
2107 ld hl,savestart-_asm_exec_ram+4
2111 cal _SET_ABS_DEST_ADDR
2115 cal _SET_ABS_SRC_ADDR
2116 ld hl,saveend-savestart
2117 cal _MM_LDIR_SET_SIZE
2125 loadhiscoreposinahl:
2126 ld hl,0 ;for peaworm and singleplayer
2132 ld a,(nrlevels+1) ;skip peaworm slots if tron mode
2136 ld b,a ;levels to skip (including 1 for singleplayer)
2137 ld de,5 ;to add per level
2139 add hl,de ;one word+3 bytes for name
2140 dnz addlevelposition
2147 adc a,0 ;ahl=saveloc
2156 jp _putc ;..then put *
2158 ;-----------------------------
2159 ;----------- worm ------------
2160 ;-----------------------------
2165 cal saverespawncounter
2171 jr DoesWormTailEqualsWormHead ;chk4 size=0
2182 DoesWormTailEqualsWormHead:
2184 jr nz,removewormloop
2188 jr nz,safewormsizedone
2196 ld (ix+tail),e ;head=tail/size=0
2202 jr nz,saverespawncounter
2226 ld a,%01111111 ;default
2229 dnz bitmask ;a/8 times
2230 out (1),a ;send bitmask
2231 in a,(1) ;input keys
2236 dnz keybit ;check match (cf set)
2239 inkeys: ;use jp not call!
2258 jr z,inlink ;input by link
2259 cal inkeys ;input by keys
2263 ld c,l ;send our keys
2270 ;------- handle worm ---------
2321 ;-------- move worm ----------
2349 notmoveY: ;bc=newpos
2356 pop hl ; << pos (old)
2374 ;--------- worm hit ----------
2381 cal z,checkhitotherworm
2384 and _datamultpeas ;&&bit
2388 jp z,WormDead ;no food
2395 cal DrawPea ;remove pea
2407 jp nz,Drawworm ;continue
2413 jp nz,Exit ;stack restored
2424 cal _IncScore ;score+(40*level)
2431 chkpeahit: ;bc=ownpos;hl=peapos (destr:ad)
2447 ld hl,(peaspos) ;1st pea
2450 and %01 ;ourpea (0|1)
2452 ld hl,(peaspos+2) ;2nd pea ;&&&ex de,hl?
2457 ld a,e ;peek a (that's x86asm for pop\push ;)
2458 bit 1,a ;%10 = carrying flag?
2459 jp z,WormDead ;if not just die
2464 pop af ;which flag? (=and %1)
2465 ld hl,drawctfpea1 ;restore #1
2466 jr z,nottheotherflag
2467 ld hl,drawctfpea2 ;restore #2
2469 ld (hl),3 ;draw delay 3 turns
2475 hitflag: ;correct pea hit
2477 xor %11 ;invert flag taken + ownflag
2479 and %10 ;just returned?
2483 jr nz,Drawworm ;flag taken, continue game
2485 ld e,20 ;flag captured+returned
2489 ld (drawctfpea1),a ;redraw..
2490 ld (drawctfpea2),a ;..both flags
2493 ;-----------------------------
2512 jr nz,nextotherwormbit
2522 ld a,(peaspos+1) ;yline
2525 jr nc,checklap ;y>yline -> a=1
2526 xor a ;y<yline -> a=0
2529 ret z ;same as before
2530 ld (ix+reserv),a ;1st time
2533 and 1 ;group 0 (1,3) or 1 (2,4)
2535 ret z ;(group 0 and y<yline) or (group 1 and y>yline)
2544 .db $dd,$7d ;ld a,lx
2547 jr nz,chkworm2 ; ret nz
2573 ;-------- draw worm ----------
2581 cal z,checkhitlapline
2587 ret z ;keep tail in "Tron"
2630 ;-----------------------------
2631 ;---------- ball -------------
2632 ;-----------------------------
2634 handlethoseneatlittleballs:
2680 bit 1,d ;1=up; 0=down
2710 letsmovetheotherway:
2725 ;-----------------------------
2726 ;----------- procs -----------
2727 ;-----------------------------
2731 ld a,%10000000 ;all key-masks
2734 inc a ;cp %11111111 (no keys pressed)
2735 jr nz,releasekeys ;keep waitin
2736 cal GET_KEY ;clear buffer
2758 CheckPea: ;@hl; destr:abcde
2771 ret nz ;nz=pixel found
2780 tryDrawPea: ;hl=peapos;bc=dopea
2789 dec (hl) ;hl=appeartime
2790 ex de,hl ;hl=peaspos
2800 jr z,receivenewpeaoverlink
2801 ld c,l ;send pea's pos
2804 jp Qsend ;&&&possible jr
2805 receivenewpeaoverlink:
2823 cal sendnewpeaoverlink
2832 PutSprite: ;||@(b,c)
2833 ;by SHIAR only ix saved
2870 ;----------- score -----------
2872 timematchscore: ;piece of crap checking whether you've already won in timematch
2884 jr z,nneexxtt ;yourself
2886 ret nz ;someone else still alive
2891 jr c,nneexxtt_ ;you>him
2904 dnz chktimematchover
2920 add hl,de ;increase score
2923 jr z,scorecommon ;hl/1000 not increased
2932 jr c,showstats ;<0=0
2935 IncScore: ;inc score by e
2937 _IncScore ; inc by de
2941 or a ;if singleplayer...
2943 add hl,de ;score+=de
2946 ld (ix+score),l ;save
2951 jr z,showstats ;de=0=no limit
2958 jr nz,timematchscore ;no disp for timematches
2959 ld hl,$FC00 ;&&&only necessary in deathmatch
2981 shownameloop: ;1st 3 chars
3010 showstat: ;(multiplayer)
3021 showA: ;small w/o leading 0 (&&&combine w/ cshowA0??)
3040 showstatsS: ;(singleplayer)
3075 showA0: ;big w/ leading 0
3087 cshowA0: ;small w/ leading 0
3122 ;-----------------------------
3240 ld (ShiftRightCounter),a
3242 ld (ShiftRightChunk),a
3256 ShiftRightCounter = $-1
3278 ld (ShiftLeftCounter),a
3280 ld (ShiftLeftChunk),a
3282 jr nc,ShiftLeftSameByte
3301 ShiftLeftCounter = $-1
3312 jr nz,ShiftRowsRight
3346 ;----------- draw ------------
3360 CheckPixel: ;at bc in d
3367 ;CLEM's FIND_PIXEL (131+? cycles; 28+4 bytes)
3368 ;(b,c) to hl:a; "destroyes" ahl
3370 FindPixel: ;(b,c) to hl:a
3433 drawcircle: ;(d,e),h ;de=x,y; h=z
3444 ex (sp),hl ;push zz \ pop x,y
3445 cal circledraw ;(x-xx,y+yy)-(x+xx,y+yy)
3446 ;(x-xx,y-yy)-(x+xx,y-yy)
3447 cal circledraw ;(x-yy,y+xx)-(x+yy,y+xx)
3448 ;(x-yy,y-xx)-(x+yy,y-xx)
3450 ex (sp),hl ;push x,y \ pop zz
3453 dec a ;-256<h<0 = $FF**
3455 jr z,circlenext ;jump if zz<0
3459 add a,a ;a=2yy-2 ;nc
3461 sbc hl,de ;zz=zz-2yy+2
3469 add hl,de ;zz=zz+2xx+3
3478 circledraw: ;destr:de
3483 add hl,bc ;h=x+xx; l=y+yy
3485 cal drawline ;(h-b,l+c)-(h+b,l+c)
3491 cal drawline ;(h-b,l-c)-(h+b,l-c)
3492 ld a,b ;swap xx and yy
3498 drawbox: ;(d,e)-(h,l)
3523 drawline: ;(d,e)-(h,l)
3624 ;-----------------------------
3625 ;----------- link ------------
3626 ;-----------------------------
3630 out (7),a ;raise both wires = link ok
3636 checklink: ;load wires in A and check for timeout
3637 dec de ;decrease timer
3640 jr nz,linkfine ;ok if de>0
3643 ld a,0 ;losses so far
3645 inc a ;and this is another one
3647 pop de ;return from link
3648 cp lossout ;quit if too many errors
3649 ret c ;otherwise just continue
3668 Qsend: ;try to send 8 bits in C; CF=error --- destr:abcde
3671 and %11 ;both wires low = exit signal
3672 jr z,linkerr ;error otherwise
3673 ld b,8 ;bits to send
3676 rl c ;bit to send in cf
3677 ld a,D0LD1H ;0: lower white
3679 ld a,D0HD1L ;1: lower red
3681 out (7),a ;lower one (send bit)
3683 cal checklink ;other calc must lower other wire
3685 cal linkok ;raise one, ok to raise other (out (7),D0HD1H)
3688 cp %11 ;both raised (by other calc)
3691 dnz sendloop ;repeat for all bits
3693 ld (linklosses),a ;reset number of losses
3698 Crecv: ;--- receive 8 bits into A/C --- destr:abcdehl ---
3700 ret nc ;return if all went ok
3701 jr Crecv ;and try again
3703 Qrecv: ;--- receive 8 bits into A/C; CF=error --- destr:abcde ---
3706 jr z,linkerr ;both low = error, quit
3707 ld b,8 ;bits to receive
3713 jr z,recvwait ;both high = nothing sent (yet)
3714 rra ;received bit in cf
3716 jr c,received ;lower white wire as well
3717 ld a,D0HD1L ;lower red
3720 out (7),a ;both wires low
3723 jr z,recvwaitack ;same wire will be raised again by other calc
3724 cal linkok ;raise both
3726 dnz recvloop ;repeat for all bits
3728 ld (linklosses),a ;reset number of losses
3732 ;-----------------------------
3733 ;---------- levels -----------
3734 ;-----------------------------
3737 .db 5,4,15,15,0,0 ;peas,speed,growth,begin_size,sprite,balls
3738 .db 0,2,63 ;start d, y, x
3739 .db 128,57 ;field width (128-255), height (57-255)
3740 .db 0 ;no additional lines, boxes
3748 .db $40,30,2,$C0,30,125, $00,2,64,$80,54,64
3752 .db "Fast Fun :))",0
3754 .db %1110000,%10001000,%10001000,%10001000,%1110000,0
3755 .db $40,30,2,$C0,30,125, $00,2,64,$80,54,64
3761 .db $40,30,2,$C0,30,125, $00,2,64,$80,54,64
3766 LevelDefT: ;tron=no delay
3767 .db "Empty Tron Level",0
3769 .db %1110000,%10001000,%10001000,%10001000,%1110000,0
3770 .db $40,30,64,$C0,30,64, $00,30,64,$80,30,64
3775 .db "Round and Round",0
3777 .db %1110000,%10001000,%10001000,%10001000,%1110000,0
3778 .db $40,23,2,$C0,23,125, $40,35,2,$C0,35,125
3786 .db %1110000,%10001000,%10001000,%10001000,%1110000,0
3787 .db $40,23,2,$C0,23,125, $40,35,2,$C0,35,125
3792 ;-----------------------------
3793 ;---------- data -------------
3794 ;-----------------------------
3797 .db %00011110,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000001,%11000000,%00000000,%00000000,%00000001,%10000000,%00000000,%00001111,%10000000
3798 .db %00111110,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000001,%11100000,%00000000,%00000011,%11000010,%01000011,%10011100,%00110000,%01100000
3799 .db %01110000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%01110000,%00111000,%00001100,%00110001,%00110100,%01100011,%01000000,%00010000
3800 .db %01100000,%01111100,%00000001,%11111111,%00000000,%11110000,%01111001,%11100000,%00110000,%01111100,%00010001,%11001001,%00001000,%00100000,%10000010,%00010000
3801 .db %11100000,%11111110,%00000011,%11111111,%10000011,%11111000,%11111111,%11110000,%00110000,%11101100,%00010001,%11000100,%10000001,%00000100,%10001110,%00001000
3802 .db %11000001,%11000111,%00000111,%00000001,%11000111,%10011001,%11001111,%00111000,%00110000,%11000110,%00001100,%00000010,%01100010,%10011100,%00010001,%00001000
3803 .db %11000001,%10000011,%00000110,%00000000,%11100110,%00000001,%10011111,%10011000,%00111001,%11000110,%00000011,%11000010,%00011100,%01100010,%00100001,%01101000
3804 .db %11000001,%10000011,%00000110,%11000000,%01101110,%00000011,%10111001,%11011100,%00111001,%11000110,%01111000,%00100001,%00000000,%00000001,%11000001,%01101000
3805 .db %11000001,%11000111,%00000110,%11000000,%01101100,%00000011,%00110000,%11001100,%00011111,%10000110,%10000101,%11100001,%00000000,%00000000,%00000001,%00010000
3806 .db %11000000,%11000110,%00000110,%11000000,%01101100,%00000011,%00110000,%11001100,%00001111,%00001110,%10010110,%00010001,%00000000,%00000000,%00000000,%11100000
3807 .db %11100000,%11101110,%00001110,%11000000,%01101100,%00000011,%00111001,%11001100,%00000000,%00001100,%01100100,%00001001,%00111111,%11111111,%11000000,%00000000
3808 .db %01100000,%01111100,%00001100,%11000000,%01101100,%00000011,%00011111,%10001110,%00000000,%00001100,%01000000,%10000001,%01000000,%00000000,%00000000,%00000000
3809 .db %01110000,%00111000,%00011100,%11100000,%11101110,%00000011,%00001111,%00000110,%00000000,%00011100,%01000000,%11000001,%01100101,%01001001,%10000011,%01100011
3810 .db %00111000,%11111110,%00111000,%01110001,%11000110,%00000011,%10000000,%00000111,%10000000,%00111000,%01000001,%00100001,%00110101,%00010101,%01000101,%01010100
3811 .db %00011111,%11101111,%11110000,%00111111,%10000111,%00000001,%10000000,%00000011,%11111111,%11110000,%00111110,%00011110,%00010111,%01011101,%10010101,%01100101
3812 .db %00001111,%10000011,%11100000,%00011111,%00000011,%00000001,%10000000,%00000000,%11111111,%11100000,%00000000,%00000000,%11100101,%01010101,%01000110,%01010011
3815 .db %00000110,%00111000,%00000000,%00111100,%00001111,%10001110,%00111100,%01111000,%00001100,%11011000,%11100011,%10000000,%00000000,%11111100,%00111000,%00000000
3816 .db %00011001,%01000110,%11100000,%11000010,%00011100,%11011111,%01111110,%11111000,%00011110,%11011101,%11110111,%11000000,%00111111,%00000011,%01000110,%11100000
3817 .db %00100000,%10000011,%00010001,%00110010,%00011000,%00010011,%01101010,%11000000,%00111011,%01001101,%10000110,%01000000,%11000000,%00000000,%10000001,%00010000
3818 .db %00100000,%00000000,%00001110,%00110010,%00011001,%10011011,%01101010,%11100000,%00110011,%01101101,%11000111,%10000001,%00011100,%00000000,%00000000,%00001100
3819 .db %01001100,%00011000,%00000000,%00000100,%00011000,%11011111,%01100010,%11001100,%00110011,%01101101,%10000111,%11000001,%00011100,%00111000,%00011000,%10000010
3820 .db %01010010,%00100100,%01100000,%00011000,%00011111,%11011011,%11101110,%11111100,%00011111,%01111000,%11110110,%11100000,%11000000,%11000110,%00101001,%10000010
3821 .db %01100001,%11000011,%10011111,%11100000,%00001111,%10001001,%11001100,%01111000,%00001110,%00110000,%01100110,%01100000,%00111111,%00000001,%11000110,%01111100
3823 ;.db %00000000,%00000001,%10000000,%00000000,%00001111,%10000000
3825 txtMenu: .db "Mode",0 ;1st menu item
3831 posMenu: .dw $2418,$231E,$2824,$1F2A,$1730,$1936
3832 txtMenuR: .db "controls",0
3833 txtoMenu: .db "Back",0 ;1st menu item
3839 posoMenu: .dw $2618,$251E,$2524,$222A,$1A30,$1C36
3840 txtGame: .db "Singleplayer",0
3841 txtGame1: .db "Peaworm",0
3842 txtGame2: .db "Tron",0
3843 txtGame3: .db "Deathmatch",0
3844 txtGame4: .db "Foodmatch",0
3845 txtGame5: .db "Timematch",0
3846 txtGame6: .db "Race",0
3847 txtGame7: .db "CTF" ;,0
3850 .db txtGame1-txtGame
3851 .db txtGame2-txtGame
3852 .db txtGame3-txtGame
3853 .db txtGame4-txtGame
3854 .db txtGame5-txtGame
3855 .db txtGame6-txtGame
3856 .db txtGame7-txtGame
3858 txtNone: .db "None",0
3859 txtDef: .db "Default",0
3862 txtKeyleft: .db ":left",0
3863 txtKeyright:.db "/right",0
3865 txtLevsel: .db $CF," SELECT LEVELS ",5,0
3866 txtWaiting: .db "Waiting...",0
3867 txtReceive: .db "Receiving..." ;,0
3870 .db 0, 3, 6, 9, 12, 15, 18, 21
3871 .db 24, 27, 30, 33, 36, 39, 42, 45
3872 .db 48, 51, 54, 57, 59, 62, 65, 67
3873 .db 70, 73, 75, 78, 80, 82, 85, 87
3874 .db 89, 91, 94, 96, 98,100,102,103
3875 .db 105,107,108,110,112,113,114,116
3876 .db 117,118,119,120,121,122,123,123
3877 .db 124,125,125,126,126,126,126,126
3880 txtLevel: .db "Level ",0
3881 txtWorms: .db "Worms: 0",0 ;follows txtLevel
3882 txtName: .db "Name",0
3883 txtWinner: .db "Wins " ;follows txtName
3884 txtDied: .db "Died " ;follows txtWinner
3885 txtScore: .db "Score",0 ;follows txtDied
3886 txtLeft: .db " left",0 ;follows txtScore
3887 txthiscore:.db "HiScore:",0
3889 txtReady: .db "Prepare!",0
3893 txtGO: .db 5,5,5,5,5," GAME OVER ",$CF,$CF,$CF,$CF,$CF,0
3896 datalevels: .dw LevelDef, LevelDefM
3897 .dw LevelDefT,LevelDefM
3898 .dw LevelDefM,LevelDefM
3899 .dw LevelDefR,LevelDefC
3900 nrlevels: .db 1,3,1,3,3,3,3,1 ;=defaults
3902 _datalink = %0000001 ;linkplay
3903 _datafoodl = %0000010 ;left=0 limit
3904 _datasingl = %0000100 ;singleplayer=1 (=hiscore+keep_length+nextlevel)
3905 _datamultpeas = %0001000 ;multiple peas=1
3906 _datatime = %0010000 ;time incs score (timematch)
3907 _datafood = %0100000 ;food present
3908 _datadie = %1000000 ;worm dies on impact
3909 ;reserved %10000000 ;for future use
3911 savestart: ; �game info (see above)
3912 ; | �lives (0=unlimited)
3913 ; | | �nrworms (can be altered by user)
3914 ; | | | �level (reset to 1 at startup)
3915 ; | | | | �speed/delay (-1=def)
3916 ; | | | | | �grow speed (-1=none; 0=continuous)
3917 ; | | | | | | �turn speed (8=def)
3918 ; | | | | | | | �score limit (0=none)
3919 gamesingle = 0 ;used | | | | | | | |
3920 datasingle: .db %1100110,3,1,1,-1,-1, 8, 0 ;Singleplayer (SP; 3 lives)
3922 datapeas: .db %1100100,1,1,1,-1,-1, 8, 0 ;Peaworm (SP; 1 live)
3924 datatron: .db %1010100,1,1,1,-1, 0, 8, 0 ;Tron (SP; 1 live, cont.growth)
3925 gamedeathm = 3 ;used
3926 datadeathm: .db %1000000,3,2,1,-1,49, 8, 0 ;Deathmatch (3 lives, 50 growth)
3928 datafoodm: .db %1100000,0,2,1,-1,-1, 8,10 ;Foodmatch (100 score)
3930 datatimem: .db %1010000,1,2,1,-1, 0, 8, 0 ;Timematch (tron, 100 score)
3932 datarace: .db %0000000,0,2,1,-1,-1, 8,10 ;Race (100 score, no collision)
3934 datactf: .db %1001000,0,4,1,-1,-1, 8,10 ;CTF (100 score)
3936 worm1set: .dw worm1p,worm1p
3937 .db %11110111,1,-01,K_RIGHT,K_LEFT
3938 worm1name: .db "WORMY ",0
3939 worm2set: .dw worm2p,worm2p
3940 .db %11111011,0,-01,K_F2,K_F1
3941 worm2name: .db "VIPER ",0
3942 worm3set: .dw worm3p,worm3p
3943 .db %11111011,1,-01,K_COMMA,K_STO
3944 worm3name: .db "NIBBLER ",0
3945 worm4set: .dw worm4p,worm4p
3946 .db %11111011,0,-01,K_PLUS,K_ENTER
3947 worm4name: .db "JIM ",0
3956 Gametype: .db 0 ;last gamemode
3970 head = 13 ;4B (head=tail)
3971 tail = 15 ;also@next level
3973 reserv = 18 ;loop (race:lap|ctf:pea)
3984 .db "WWW.SHIAR.ORG WWW.SHIAR.ORG "
3985 .db "WWW.SHIAR.ORG WWW.SHIAR.ORG "
3986 .db "WWW.SHIAR.ORG WWW.SHIAR.ORG "
3987 .db "WWW.SHIAR.ORG WWW.SHIAR.ORG "
3988 .db "WWW.SHIAR.ORG WWW.SHIAR.ORG "
3989 .db "WWW.SHIAR.ORG WWW.SHIAR.ORG "
3990 .db "WWW.SHIAR.ORG WWW.SHIAR.ORG "
3991 .db "WWW.SHIAR.ORG WWW.SHIAR.ORG "
3992 .db "WWW.SHIAR.ORG WWW.SHIAR.ORG "
3993 .db "WWW.SHIAR.ORG WWW.SHIAR.ORG "
3994 .db "WWW.SHIAR.ORG WWW.SHIAR.ORG "
3995 .db "WWW.SHIAR.ORG WWW.SHIAR.ORG "
3996 .db "WWW.SHIAR.ORG WWW.SHIAR.ORG "
3997 .db "WWW.SHIAR.ORG WWW.SHIAR.ORG "
3998 .db "WWW.SHIAR.ORG WWW.SHIAR.ORG "
3999 .db "WWW.SHIAR.ORG WWW.SHIAR.ORG "
4000 .db "WWW.SHIAR.ORG WWW.SHIAR.ORG "
4001 .db "WWW.SHIAR.ORG WWW.SHIAR.ORG "
4002 .db "WWW.SHIAR.ORG WWW.SHIAR.ORG "
4003 .db "WWW.SHIAR.ORG WWW.SHIAR.ORG "
4004 .db "WWW.SHIAR.ORG WWW.SHIAR.ORG "
4005 .db "WWW.SHIAR.ORG WWW.SHIAR.ORG "
4006 .db "WWW.SHIAR.ORG WWW.SHIAR.ORG "
4007 .db "WWW.SHIAR.ORG WWW.SHIAR.ORG "
4008 .db "WWW.SHIAR.ORG WWW.SHIAR.ORG "
4009 .db "WWW.SHIAR.ORG WWW.SHIAR.ORG "
4010 .db "WWW.SHIAR.ORG WWW.SHIAR.ORG "
4011 .db "WWW.SHIAR.ORG WWW.SHIAR.ORG "
4012 .db "WWW.SHIAR.ORG WWW.SHIAR.ORG "
4013 .db " wormy@shiar.org",0
4016 defspriteimg: .db %01100000
4022 .db "Internal Levels",0
4023 .db "by SHIAR -- still t"
4024 .db "o be added...." ;,0
4026 .db 0,deflevels/256,deflevels&255
4029 ;-----------------------------
4030 ;----------- end -------------
4031 ;-----------------------------