3 ; Release Date : summer 2001
4 ; Filename : wormy.86p (5kb)
6 ; Email Address : shiar0@hotmail.com
8 ; Web Page : www.shiar.org
9 ; Description : ruling Nibbles-like game 1-4 players
10 ; Where to get this game : www.shiar.org (home of Wormy)
11 ; Other games by author(s) : Nemesis beta
12 ; Additional Credits to : Matthew Shepcar (wrote original Peaworm, end'98)
13 ; Jonah Cohen (helped writing worm)
15 ;-----------------------------
16 ;----------- TO-DO -----------
17 ;-----------------------------
21 ; [* internal levels ]
22 ; [ * check levels/gametype ]
23 ; [ * enough hiscore saves! ]
24 ; [* complete readme ]
25 ; 1% * misc (pollish, bugs, &&&)
27 ; * fix first packet loss
28 ; 1% * transmit game/level data
29 ;;;1% * get g/o signal (l&l) working
30 ; 2% * 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
54 #include "ti86asm.inc"
56 _SHRACC = $4383 ;4x srl a
57 _SHLACC = $438B ;4x sll a
58 _divHLby10 = $4044 ;hl=hl/10
59 _divAby10 = $4DAF ;a=a/10
60 _HLTIMES10 = $41BF ;hl=hl*10
61 _cphlde = $403C ;cp hl,de
62 _clrWindow = $4A86 ;clear screen
63 _asapvar = $D6FC ;own name (worm)
64 _MOV4B = $429B ;4x ld (de),(hl)
65 _MOV5B = $4297 ;5x ld (de),(hl)
66 _mov9b = $4283 ;9x ld (de),(hl)
67 _ldHLind = $4010 ;ld hl,(hl)
68 _swapt_ = $45F3 ;ex_ahl_bde
69 _Get_Word_ahl = $521D ;ld de,(ahl)
70 _Set_Word_ahl = $5221 ;ld (ahl),de
71 _INC_PTR_AHL = $4637 ;ahl=ahl+1
72 _AHL_PLUS_2_PG3 = $4C3F ;ahl=ahl+2
73 _SET_ABS_SRC_ADDR = $4647 ;set source for mm.ldir =ahl
74 _LOAD_ABS_SRC_ADDR = $5209 ;ahl = mm.ldir source
75 _SET_ABS_DEST_ADDR = $5285 ;set destination for mm.ldir = ahl
76 _SET_MM_NUM_BYTES = $464F ;number of bytes for mm.ldir = ahl
77 _mm_ldir = $52ED ;24bit ldir
78 _MM_LDIR_SET_SIZE = $524D ;_SET_MM_NUM_BYTES + _mm_ldir
79 _RAM_PAGE_1 = $47E3 ;set $8000+ to page 1
80 _RAM_PAGE_7 = $47F3 ;"""" 7
81 _PTEMP_END = $D29A ;end of VAT
82 _load_ram_ahl = $462F ;ahl->page+hl
83 _writeb_inc_ahl = $5567 ;ld (ahl++),c
84 _jforce = $409C ;TI-OS stack restored
85 _EXLP = $4493 ;swap (hl),(de) b times
86 _GETB_AHL = $46C3 ;a=(ahl) \ hl=ahl
88 ;-----------------------------
89 ;------- data storage -------
90 ;-----------------------------
94 ScrBuffer = $8820 ;-A7FF (20*FF=1FE0)
95 worm2p = $A800 ;-ABFF (400) %10101O00
96 worm1 = $AC00 ;-AC1D (31d)
97 worm2 = $AC1F ;-AC3B (1F)
98 worm3 = $AC3E ;-AC59 (1F)
99 worm4 = $AC5D ;-AC77 (1F)
100 balls = $AC7C ;-ACFF (3x43d)
101 SinCosTable = $AD00 ;-AE00 (4*40)
102 ;free $AE01 ;-AFFF (1FF)
103 worm1p = $B000 ;-B7FF (800) %1011O000
104 worm3p = $B800 ;-BBFF (400) %10111O00
105 ;free $BF91 ;-BFFF (6F)
106 ;program $D748 ;-EFFF (186D+4A)
107 worm4p = $F000 ;-F3FF (400) %11110O00
108 leveldata = $F400 ;-FA70 (<=671)
110 turn10 = $AE01 ; (1) (counter)
111 peaspos = $AE02 ;-AE05 (4) (peas)
113 ;MEM|8---9---A---B---C---D---E---F---|
114 ; |..[------]||[]|......[-----]|[].|
115 ; | SCREEN 2* 13 PRGM 4LV |
119 namelength = $BC00 ;(1) @menu
121 DispBuffer = $BC00 ;(10x57d) @game
126 ;-----------------------------
127 ;------- program start -------
128 ;-----------------------------
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 >"
298 cp 49 ;bottom of screen
306 ld l,(ix+2) ;ahl=(ix)
307 cal _load_ram_ahl ;hl=ahl
311 readylevelfile: ;selected level at ahl
314 add a,3 ;sellev+3 (#0==-3)
330 cal _GETB_AHL ;ld a,(ahl)
335 cal _INC_PTR_AHL ;ahl++
337 jr nz,skiptitle ;goto #0-terminator
363 cal _load_ram_ahl ;hl=ahl
364 ld de,$FFA0 ;desc.text
369 cp d ;de>$FFFF (offscreen)
370 jr nz,levdescclearloop
374 ld ix,templevels-6 ;reset 2 1st page
376 ld b,-2 ;level selected
382 pop bc ;GET_KEY destr. b
400 or a ;levelfile on page 0 (=internal)
402 cal skiptitle ;skip description
405 ld (leveldataSize),de
410 ld (hilvlposa),a ;singleplayer levels
415 cal _SET_ABS_SRC_ADDR ;levelsstart
418 cal _SET_ABS_DEST_ADDR ;store in mem.
421 cal _MM_LDIR_SET_SIZE
423 cal _LOAD_ABS_SRC_ADDR ;->ahl
430 ldi ;(de),(hl)\inc hl
435 res 2,(iy+13) ;appAutoScroll
443 ld (hl),1 ;def=level#1
447 ;-----------------------------
448 ;----- build trig tables -----
449 ;-----------------------------
474 ;-----------------------------
475 ;---------- menu -------------
476 ;-----------------------------
478 DisplayMenu: ;---draw menu---
485 ld hl,$FC00+$010 ;(*,01)
487 ld hl,$FC00+$160 ;(*,22)
489 ld hl,$FC00+$3E0 ;(*,62)
494 dec a ;will be inced @changegame
497 ld hl,changegame ;dispmenusets ;mainMenu
498 psh hl ;jump here after ret
501 ;Mode|Level|Limit|Worms|worm #|controls
502 ; jr dispmenucommon ;cal
505 ld de,$FD80 ;begin pos
529 hr: ;draw horizontal line at hl
538 ;Back|Lives|Limit|Speed|Rotation|Growth
553 inc hl \ inc hl \ inc hl
571 inc a ;-1=None; 0..98->1..99
586 cal cshowA0 ;turn speed
593 ld a,(hl) ;(scorelimit)
598 jr z,optionMenu ;do not display 0 behind 'None'
610 jp z,dispmainmenu ;mainMenu
654 cal loadgamecar ;a=(hl)
657 jr nc,optionMenu ;>99
661 jp dispomenusets ;optionMenu
664 sub 1 ;dec does not set cf
672 jr nc,optionMenu ;>99
675 jr _dispomenusets ;optionMenu
678 sub 1 ;dec does not set cf
685 ld a,(hl) ;(scorelimit)
692 jr nc,_optionMenu ;>98
696 jr _dispomenusets ;optionMenu
702 jr z,_optionMenu ;<-1
709 inc hl ;=saves 2 bytes :P
718 jr nc,_optionMenu ;>25
721 jr _dispomenusets ;optionMenu
736 jr nc,_optionMenu ;>98
739 jr _dispomenusets ;optionMenu
745 jr z,__optionMenu ;<-1
757 dec a ;2nd item: level
759 sub 3 ;5th item: wormname
763 jp LetsGetThisPartyOn ;otherwise
794 jr nc,mainMenu ;may not become >(nrworms)
798 jr _dispmenusets ;mainMenu
811 ; jr z,bchangecurworm
816 jr nz,changedcurworm ;save >0
821 ld a,(hl) ;hl=nrworms
824 jr nc,mainMenu ;may not be >4
827 jr _dispmenusets ;mainMenu
831 ld a,(hl) ;hl=nrworms
835 ld a,(hl) ;hl=nrworms
838 jr nc,changednrworms ;save >=2
847 jr _mainMenu ;don't change for singleplayer
852 dec hl ;inced earlier
854 ld a,1 ;change LS-bit (=link)
858 jr dispmenusets ;mainMenu
865 jr dispmenusets ;mainMenu
878 jr dispmenusets ;mainMenu
881 inc hl ;hl=loadgamecar+2
883 ld a,(hl) ;(curlevel)
885 cp (hl) ;max level for sel.game
891 jr dispmenusets ;mainMenu
894 ld a,(hl) ;(curlevel)
899 getnrlevels: ;for current gametype at hl
926 cal getcustomkey ;left
927 cal getcustomkey ;right
930 ;---display current settings---
940 add hl,de ;hl=posGame+(Gametype)
941 ld a,(hl) ;str.offset
945 ld (CURtxtGame),hl ;save for g/o
946 cal _vputs ;Singleplayer
995 ld hl,$363E ;controls
1001 ;--- handle menukeys ---
1009 pop bc ;GET_KEY destr. b
1019 menupos: ;highlight #b
1032 add hl,hl ;$FD20+item*96
1062 ;--- change name ---
1065 getwormname: ;of (curworm)
1093 ld hl,$FF07 ;begin pos
1126 dec (hl) ;(namelength)
1141 .db 0,".<>!",0,0,0,0 ;down,L,R,up
1142 .db 0,"XTOJE0",0 ;enter..clear
1143 .db " WSNID9",0 ;(-)..custom
1144 .db "ZVRMHC8",0 ;dot..del
1145 .db "YUQLGB7#" ;0..xvar
1146 .db $D9,"-PKFA6'" ;on..alpha
1147 .db "54321*",0,$D0 ;F5..more
1151 ld (ix+8),0 ;end mark
1158 halt ;save them batteries! yeah!
1162 ld hl,$FD97 ;begin pos
1163 ld a,35 ;nr of lines
1165 ld de,7 ;bytes to add
1167 ld c,9 ;bytes to clear
1172 jr nz,clroldsetsloop
1175 jr nz,clroldsettings
1178 hlatlevel: ;d must be 0
1180 ld a,(Gametype) ;8bytes -> 7bytes
1185 add a,24+1 ;go to datalevels
1187 sbc hl,de ;datalevels
1188 cal _ldHLind ;ld hl,(hl)
1189 pop de ;de=loadgamecar
1191 ld a,(de) ;(curlevel)
1195 dec d ;levels to skip
1199 ret ;hl=begin of correct level
1201 skiplvltitle: ;zf=singleplayer
1203 or a ;null-terminator
1208 skiplevel: ;@hl - destr:ab - alter:hl
1217 ld b,(hl) ;spritesize
1225 pop af ;cp (Gametype),0
1227 inc b ;multiplayer lvl
1229 inc b ;skip other 3 worms (9 bytes)
1263 ;build: c=(gameCar)=(hl-1)
1264 ; a=(wormbeglives)=(hl)
1270 add a,a ;8 bytes per mode
1282 ;-----------------------------
1283 ;-------- start game ---------
1284 ;-----------------------------
1288 ld (CheckExit),a ;set exit state
1306 ld (turnright),a ;more efficient
1310 cal _HLTIMES10 ;hl=10*(hl)
1334 jp DisplayMenu ;return to menu
1350 ;-----------------------------
1351 ;--------- game over ---------
1352 ;-----------------------------
1357 ld a,4 ;4x (all worms)
1367 ld (hl),b ;score+1=0
1374 ex de,hl ;de=wormX+head
1378 jr nz,createwormsloop
1382 pop hl ;begin of current level
1389 dec (hl) ;curlevel-- (not beyond last lvl)
1392 ;show end msg or smtn
1394 psh bc ;where to go afterwards
1395 inc hl ;location of ending-code
1396 jp (hl) ;go there ("call")
1409 ld a,(hl) ;speed from level
1413 ld (de),a ;custom speed
1432 ld b,0 ;bc=sprite size
1433 add hl,bc ;hl=behind sprite
1440 setsprite: ;de=@sprite ;a=sprsize
1464 pop af ;cp (Gametype),0
1472 ld a,SinCosTable/256
1483 ld bc,(worm2-worm1)-5
1493 ;-------- draw level ---------
1519 add hl,hl ;32=scr.width
1526 ld bc,63 ;first 2 rows
1528 ldir ;draw upper border
1530 ld (hl),%11000000 ;first left border
1535 inc hl ;clear rest of line
1575 cp gamerace ;or gamectf
1576 jr c,levelhasbeensetup
1578 ld c,2 ;ld bc,2 (2 bytes)
1579 jr z,loadextralevelstuff ;cp gamerace
1580 ld c,4 ;ld bc,4 (2nd flag in ctf)
1581 loadextralevelstuff:
1590 ;-----------------------------
1592 psh hl ; >> levelp new
1620 ld hl,4+(txtposReady*256)
1631 jr nc,initfinished ;no link
1633 SwapPos: ;$18 xx -> $E6 xx
1637 ld (worm1+left),a ;worm 1...
1638 ld (worm3+left),a ;and worm 3 via link
1667 ld (worm2+left),a ;worm 2+4..
1668 ld (worm4+left),a ;..over link
1691 ;-----------------------------
1692 ;----------- LOOP ------------
1693 ;-----------------------------
1696 ld bc,(worm1+pos) ;camera worm #1
1698 or a ;if #1 not over link
1700 ld bc,(worm2+pos) ;otherwise view from #2
1702 cal DisplayField ;display piece of level
1717 jr nz,screeninvertloop
1730 ld (handledworm),a ;reset
1748 jr nz,nodispupdate ;just once every 10 turns
1749 ld (hl),10 ;reset counter
1750 cal forceshowstats ;update score
1755 jr nz,noctfpeas2draw
1758 cal tryDrawPea ;pea#1
1761 cal tryDrawPea ;pea#2
1768 cal nz,handlethoseneatlittleballs
1781 inc (hl) ;0..nrworms-1
1784 ;-----------------------------
1785 ;---------- keys -------------
1786 ;-----------------------------
1801 rla ;=$17 (c=EXIT-key)
1812 ld (ix+delay),respawndelay
1831 ld (ix+pos2+1),a ;x2
1838 cp gamectf ;ctf no death penalty
1841 ret nz ;HandleWorm done
1843 or a ;0=no live limit
1844 ret z ;don't end game
1847 jr z,anyworm ;quit at any worm's death
1848 ld a,(nrworms) ;timematch: all worms must've died
1850 ld hl,worm1+lives-(worm2-worm1)
1852 xor a ;check for 0 lives
1854 add hl,de ;next worm
1856 ret nz ;any >0: don't exit
1859 ld a,$A7 ;exit@end of turn
1860 ld (CheckExit),a ;set exit state
1869 out (7),a ;both wires low = game over signal
1878 cal menuinvloop ;invert
1880 cal hr ;menuinvloop w/ b=16
1890 cal menuinvloop ;invert
1892 cal hr ;menuinvloop w/ b=16
1911 cal _vputs ;Died Score
1926 jr c,nonewwinner ;h<d
1927 jr nz,newwinner ;h>d
1930 jr nc,nonewwinner ;l<e
1941 cpl ;high value (>$FB)
1946 ld a,(hl) ;less deaths
1953 ;---display worms---
1965 cp (hl) ;input=0 = link
1982 ld a,(hl) ;worm+died
1989 jr nz,nodmwinner ;deathmatch?
1990 ld a,0 ;winner's deaths
1992 cp (hl) ;equals this worm?
1993 scf ;jr nz,notwinner
1996 jr c,notwinner ;no singleplayer winners
1998 cal _ldHLind ;ld hl,(hl)
2001 cal _cphlde ;==highest score..
2016 dnz displayWormStats
2019 or a ;singleplayer (0) only
2020 jr nz,hilevelcheckdone
2025 jr c,hilevelcheckdone
2026 ld (hl),a ;save local
2031 hilvlposhl =$-2 ;save external
2032 cal _writeb_inc_ahl ;ld (ahl),c
2037 jr z,hiscorecheckdone ;no SP
2039 cal loadhiscoreposinahl
2040 cal _SET_ABS_SRC_ADDR ;from ahl (lvlfile)
2043 cal _SET_ABS_DEST_ADDR ;to local
2045 cal _MM_LDIR_SET_SIZE ;get old score+name
2048 ld de,(highsave) ;de=prev. hiscore
2049 ld hl,(worm1+score) ;hl=worm1's score
2050 cal _cphlde ;sub hl,de
2051 jr c,NotNewHigh ;new<old
2052 jr z,NotNewHigh ;new<=old
2054 ld (highsave),hl ;store new hiscore
2055 ld de,highsave+2 ;to
2056 ld hl,worm1+name ;from
2058 ldir ;store new hiname
2059 cal loadhiscoreposinahl
2060 cal _SET_ABS_DEST_ADDR ;to ahl
2063 cal _SET_ABS_SRC_ADDR ;from local
2065 cal _MM_LDIR_SET_SIZE ;save new
2093 ;x123456789012345678901
2094 ;>>>>>> GAME OVER <<<<<
2099 ;6Worm#02 @ 05 00120
2106 rst 20h ;_ABS_MOV10TOOP1
2108 ld hl,savestart-_asm_exec_ram+4
2112 cal _SET_ABS_DEST_ADDR
2116 cal _SET_ABS_SRC_ADDR
2117 ld hl,saveend-savestart
2118 cal _MM_LDIR_SET_SIZE
2126 loadhiscoreposinahl:
2127 ld hl,0 ;for peaworm and singleplayer
2133 ld a,(nrlevels+1) ;skip peaworm slots if tron mode
2137 ld b,a ;levels to skip (including 1 for singleplayer)
2138 ld de,5 ;to add per level
2140 add hl,de ;one word+3 bytes for name
2141 dnz addlevelposition
2148 adc a,0 ;ahl=saveloc
2157 jp _putc ;..then put *
2159 ;-----------------------------
2160 ;----------- worm ------------
2161 ;-----------------------------
2166 cal saverespawncounter
2172 jr DoesWormTailEqualsWormHead ;chk4 size=0
2183 DoesWormTailEqualsWormHead:
2185 jr nz,removewormloop
2189 jr nz,safewormsizedone
2197 ld (ix+tail),e ;head=tail/size=0
2203 jr nz,saverespawncounter
2227 ld a,%01111111 ;default
2230 dnz bitmask ;a/8 times
2231 out (1),a ;send bitmask
2232 in a,(1) ;input keys
2237 dnz keybit ;check match (cf set)
2240 inkeys: ;use jp not call!
2259 jr z,inlink ;input by link
2260 cal inkeys ;input by keys
2264 ld c,l ;send our keys
2271 ;------- handle worm ---------
2322 ;-------- move worm ----------
2350 notmoveY: ;bc=newpos
2357 pop hl ; << pos (old)
2375 ;--------- worm hit ----------
2382 cal z,checkhitotherworm
2385 and _datamultpeas ;&&bit
2389 jp z,WormDead ;no food
2396 cal DrawPea ;remove pea
2408 jp nz,Drawworm ;continue
2414 jp nz,Exit ;stack restored
2425 cal _IncScore ;score+(40*level)
2432 chkpeahit: ;bc=ownpos;hl=peapos (destr:ad)
2448 ld hl,(peaspos) ;1st pea
2451 and %01 ;ourpea (0|1)
2453 ld hl,(peaspos+2) ;2nd pea ;&&&ex de,hl?
2458 ld a,e ;peek a (that's x86asm for pop\push ;)
2459 bit 1,a ;%10 = carrying flag?
2460 jp z,WormDead ;if not just die
2465 pop af ;which flag? (=and %1)
2466 ld hl,drawctfpea1 ;restore #1
2467 jr z,nottheotherflag
2468 ld hl,drawctfpea2 ;restore #2
2470 ld (hl),3 ;draw delay 3 turns
2476 hitflag: ;correct pea hit
2478 xor %11 ;invert flag taken + ownflag
2480 and %10 ;just returned?
2484 jr nz,Drawworm ;flag taken, continue game
2486 ld e,20 ;flag captured+returned
2490 ld (drawctfpea1),a ;redraw..
2491 ld (drawctfpea2),a ;..both flags
2494 ;-----------------------------
2513 jr nz,nextotherwormbit
2523 ld a,(peaspos+1) ;yline
2526 jr nc,checklap ;y>yline -> a=1
2527 xor a ;y<yline -> a=0
2530 ret z ;same as before
2531 ld (ix+reserv),a ;1st time
2534 and 1 ;group 0 (1,3) or 1 (2,4)
2536 ret z ;(group 0 and y<yline) or (group 1 and y>yline)
2545 .db $dd,$7d ;ld a,lx
2548 jr nz,chkworm2 ; ret nz
2574 ;-------- draw worm ----------
2582 cal z,checkhitlapline
2588 ret z ;keep tail in "Tron"
2631 ;-----------------------------
2632 ;---------- ball -------------
2633 ;-----------------------------
2635 handlethoseneatlittleballs:
2681 bit 1,d ;1=up; 0=down
2711 letsmovetheotherway:
2726 ;-----------------------------
2727 ;----------- procs -----------
2728 ;-----------------------------
2732 ld a,%10000000 ;all key-masks
2735 inc a ;cp %11111111 (no keys pressed)
2736 jr nz,releasekeys ;keep waitin
2737 cal GET_KEY ;clear buffer
2759 CheckPea: ;@hl; destr:abcde
2772 ret nz ;nz=pixel found
2781 tryDrawPea: ;hl=peapos;bc=dopea
2790 dec (hl) ;hl=appeartime
2791 ex de,hl ;hl=peaspos
2801 jr z,receivenewpeaoverlink
2802 ld c,l ;send pea's pos
2805 jp Qsend ;&&&possible jr
2806 receivenewpeaoverlink:
2824 cal sendnewpeaoverlink
2833 PutSprite: ;||@(b,c)
2834 ;by SHIAR only ix saved
2871 ;----------- score -----------
2873 timematchscore: ;piece of crap checking whether you've already won in timematch
2883 jr z,nneexxtt ;yourself
2885 ret nz ;someone else still alive
2890 jr c,nneexxtt_ ;you>him
2903 dnz chktimematchover
2919 add hl,de ;increase score
2922 jr z,scorecommon ;hl/1000 not increased
2931 jr c,showstats ;<0=0
2934 IncScore: ;inc score by e
2936 _IncScore ; inc by de
2940 or a ;if singleplayer...
2942 add hl,de ;score+=de
2945 ld (ix+score),l ;save
2950 jr z,showstats ;de=0=no limit
2957 jr nz,timematchscore ;no disp for timematches
2958 ld hl,$FC00 ;&&&only necessary in deathmatch
2980 shownameloop: ;1st 3 chars
3009 showstat: ;(multiplayer)
3020 showA: ;small w/o leading 0 (&&&combine w/ cshowA0??)
3039 showstatsS: ;(singleplayer)
3074 showA0: ;big w/ leading 0
3086 cshowA0: ;small w/ leading 0
3121 ;-----------------------------
3239 ld (ShiftRightCounter),a
3241 ld (ShiftRightChunk),a
3255 ShiftRightCounter = $-1
3277 ld (ShiftLeftCounter),a
3279 ld (ShiftLeftChunk),a
3281 jr nc,ShiftLeftSameByte
3300 ShiftLeftCounter = $-1
3311 jr nz,ShiftRowsRight
3345 ;----------- draw ------------
3359 CheckPixel: ;at bc in d
3366 ;CLEM's FIND_PIXEL (131+? cycles; 28+4 bytes)
3367 ;(b,c) to hl:a; "destroyes" ahl
3369 FindPixel: ;(b,c) to hl:a
3432 drawcircle: ;(d,e),h ;de=x,y; h=z
3443 ex (sp),hl ;push zz \ pop x,y
3444 cal circledraw ;(x-xx,y+yy)-(x+xx,y+yy)
3445 ;(x-xx,y-yy)-(x+xx,y-yy)
3446 cal circledraw ;(x-yy,y+xx)-(x+yy,y+xx)
3447 ;(x-yy,y-xx)-(x+yy,y-xx)
3449 ex (sp),hl ;push x,y \ pop zz
3452 dec a ;-256<h<0 = $FF**
3454 jr z,circlenext ;jump if zz<0
3458 add a,a ;a=2yy-2 ;nc
3460 sbc hl,de ;zz=zz-2yy+2
3468 add hl,de ;zz=zz+2xx+3
3477 circledraw: ;destr:de
3482 add hl,bc ;h=x+xx; l=y+yy
3484 cal drawline ;(h-b,l+c)-(h+b,l+c)
3490 cal drawline ;(h-b,l-c)-(h+b,l-c)
3491 ld a,b ;swap xx and yy
3497 drawbox: ;(d,e)-(h,l)
3522 drawline: ;(d,e)-(h,l)
3623 ;-----------------------------
3624 ;----------- link ------------
3625 ;-----------------------------
3629 out (7),a ;raise both wires = link ok
3635 checklink: ;load wires in A and check for timeout
3636 dec de ;decrease timer
3639 jr nz,linkfine ;ok if de>0
3642 ld a,0 ;losses so far
3644 inc a ;and this is another one
3646 pop de ;return from link
3647 cp lossout ;quit if too many errors
3648 ret c ;otherwise just continue
3667 Qsend: ;try to send 8 bits in C; CF=error --- destr:abcde
3670 and %11 ;both wires low = exit signal
3671 jr z,linkerr ;error otherwise
3672 ld b,8 ;bits to send
3675 rl c ;bit to send in cf
3676 ld a,D0LD1H ;0: lower white
3678 ld a,D0HD1L ;1: lower red
3680 out (7),a ;lower one (send bit)
3682 cal checklink ;other calc must lower other wire
3684 cal linkok ;raise one, ok to raise other (out (7),D0HD1H)
3687 cp %11 ;both raised (by other calc)
3690 dnz sendloop ;repeat for all bits
3692 ld (linklosses),a ;reset number of losses
3697 Crecv: ;--- receive 8 bits into A/C --- destr:abcdehl ---
3699 ret nc ;return if all went ok
3700 jr Crecv ;and try again
3702 Qrecv: ;--- receive 8 bits into A/C; CF=error --- destr:abcde ---
3705 jr z,linkerr ;both low = error, quit
3706 ld b,8 ;bits to receive
3712 jr z,recvwait ;both high = nothing sent (yet)
3713 rra ;received bit in cf
3715 jr c,received ;lower white wire as well
3716 ld a,D0HD1L ;lower red
3719 out (7),a ;both wires low
3722 jr z,recvwaitack ;same wire will be raised again by other calc
3723 cal linkok ;raise both
3725 dnz recvloop ;repeat for all bits
3727 ld (linklosses),a ;reset number of losses
3731 ;-----------------------------
3732 ;---------- levels -----------
3733 ;-----------------------------
3736 .db 5,4,15,15,0,0 ;peas,speed,growth,begin_size,sprite,balls
3737 .db 0,2,63 ;start d, y, x
3738 .db 128,57 ;field width (128-255), height (57-255)
3739 .db 0 ;no additional lines, boxes
3747 .db $40,30,2,$C0,30,125, $00,2,64,$80,54,64
3751 .db "Fast Fun :))",0
3753 .db %1110000,%10001000,%10001000,%10001000,%1110000,0
3754 .db $40,30,2,$C0,30,125, $00,2,64,$80,54,64
3760 .db $40,30,2,$C0,30,125, $00,2,64,$80,54,64
3765 LevelDefT: ;tron=no delay
3766 .db "Empty Tron Level",0
3768 .db %1110000,%10001000,%10001000,%10001000,%1110000,0
3769 .db $40,30,64,$C0,30,64, $00,30,64,$80,30,64
3774 .db "Round and Round",0
3776 .db %1110000,%10001000,%10001000,%10001000,%1110000,0
3777 .db $40,23,2,$C0,23,125, $40,35,2,$C0,35,125
3785 .db %1110000,%10001000,%10001000,%10001000,%1110000,0
3786 .db $40,23,2,$C0,23,125, $40,35,2,$C0,35,125
3791 ;-----------------------------
3792 ;---------- data -------------
3793 ;-----------------------------
3796 .db %00011110,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000001,%11000000,%00000000,%00000000,%00000001,%10000000,%00000000,%00001111,%10000000
3797 .db %00111110,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000001,%11100000,%00000000,%00000011,%11000010,%01000011,%10011100,%00110000,%01100000
3798 .db %01110000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%01110000,%00111000,%00001100,%00110001,%00110100,%01100011,%01000000,%00010000
3799 .db %01100000,%01111100,%00000001,%11111111,%00000000,%11110000,%01111001,%11100000,%00110000,%01111100,%00010001,%11001001,%00001000,%00100000,%10000010,%00010000
3800 .db %11100000,%11111110,%00000011,%11111111,%10000011,%11111000,%11111111,%11110000,%00110000,%11101100,%00010001,%11000100,%10000001,%00000100,%10001110,%00001000
3801 .db %11000001,%11000111,%00000111,%00000001,%11000111,%10011001,%11001111,%00111000,%00110000,%11000110,%00001100,%00000010,%01100010,%10011100,%00010001,%00001000
3802 .db %11000001,%10000011,%00000110,%00000000,%11100110,%00000001,%10011111,%10011000,%00111001,%11000110,%00000011,%11000010,%00011100,%01100010,%00100001,%01101000
3803 .db %11000001,%10000011,%00000110,%11000000,%01101110,%00000011,%10111001,%11011100,%00111001,%11000110,%01111000,%00100001,%00000000,%00000001,%11000001,%01101000
3804 .db %11000001,%11000111,%00000110,%11000000,%01101100,%00000011,%00110000,%11001100,%00011111,%10000110,%10000101,%11100001,%00000000,%00000000,%00000001,%00010000
3805 .db %11000000,%11000110,%00000110,%11000000,%01101100,%00000011,%00110000,%11001100,%00001111,%00001110,%10010110,%00010001,%00000000,%00000000,%00000000,%11100000
3806 .db %11100000,%11101110,%00001110,%11000000,%01101100,%00000011,%00111001,%11001100,%00000000,%00001100,%01100100,%00001001,%00111111,%11111111,%11000000,%00000000
3807 .db %01100000,%01111100,%00001100,%11000000,%01101100,%00000011,%00011111,%10001110,%00000000,%00001100,%01000000,%10000001,%01000000,%00000000,%00000000,%00000000
3808 .db %01110000,%00111000,%00011100,%11100000,%11101110,%00000011,%00001111,%00000110,%00000000,%00011100,%01000000,%11000001,%01100101,%01001001,%10000011,%01100011
3809 .db %00111000,%11111110,%00111000,%01110001,%11000110,%00000011,%10000000,%00000111,%10000000,%00111000,%01000001,%00100001,%00110101,%00010101,%01000101,%01010100
3810 .db %00011111,%11101111,%11110000,%00111111,%10000111,%00000001,%10000000,%00000011,%11111111,%11110000,%00111110,%00011110,%00010111,%01011101,%10010101,%01100101
3811 .db %00001111,%10000011,%11100000,%00011111,%00000011,%00000001,%10000000,%00000000,%11111111,%11100000,%00000000,%00000000,%11100101,%01010101,%01000110,%01010011
3814 .db %00000110,%00111000,%00000000,%00111100,%00001111,%10001110,%00111100,%01111000,%00001100,%11011000,%11100011,%10000000,%00000000,%11111100,%00111000,%00000000
3815 .db %00011001,%01000110,%11100000,%11000010,%00011100,%11011111,%01111110,%11111000,%00011110,%11011101,%11110111,%11000000,%00111111,%00000011,%01000110,%11100000
3816 .db %00100000,%10000011,%00010001,%00110010,%00011000,%00010011,%01101010,%11000000,%00111011,%01001101,%10000110,%01000000,%11000000,%00000000,%10000001,%00010000
3817 .db %00100000,%00000000,%00001110,%00110010,%00011001,%10011011,%01101010,%11100000,%00110011,%01101101,%11000111,%10000001,%00011100,%00000000,%00000000,%00001100
3818 .db %01001100,%00011000,%00000000,%00000100,%00011000,%11011111,%01100010,%11001100,%00110011,%01101101,%10000111,%11000001,%00011100,%00111000,%00011000,%10000010
3819 .db %01010010,%00100100,%01100000,%00011000,%00011111,%11011011,%11101110,%11111100,%00011111,%01111000,%11110110,%11100000,%11000000,%11000110,%00101001,%10000010
3820 .db %01100001,%11000011,%10011111,%11100000,%00001111,%10001001,%11001100,%01111000,%00001110,%00110000,%01100110,%01100000,%00111111,%00000001,%11000110,%01111100
3822 ;.db %00000000,%00000001,%10000000,%00000000,%00001111,%10000000
3824 txtMenu: .db "Mode",0 ;1st menu item
3830 posMenu: .dw $2418,$231E,$2824,$1F2A,$1730,$1936
3831 txtMenuR: .db "controls",0
3832 txtoMenu: .db "Back",0 ;1st menu item
3838 posoMenu: .dw $2618,$251E,$2524,$222A,$1A30,$1C36
3839 txtGame: .db "Singleplayer",0
3840 txtGame1: .db "Peaworm",0
3841 txtGame2: .db "Tron",0
3842 txtGame3: .db "Deathmatch",0
3843 txtGame4: .db "Foodmatch",0
3844 txtGame5: .db "Timematch",0
3845 txtGame6: .db "Race",0
3846 txtGame7: .db "CTF" ;,0
3849 .db txtGame1-txtGame
3850 .db txtGame2-txtGame
3851 .db txtGame3-txtGame
3852 .db txtGame4-txtGame
3853 .db txtGame5-txtGame
3854 .db txtGame6-txtGame
3855 .db txtGame7-txtGame
3857 txtNone: .db "None",0
3858 txtDef: .db "Default",0
3861 txtKeyleft: .db ":left",0
3862 txtKeyright:.db "/right",0
3864 txtLevsel: .db $CF," SELECT LEVELS ",5,0
3865 txtWaiting: .db "Waiting...",0
3866 txtReceive: .db "Receiving..." ;,0
3869 .db 0, 3, 6, 9, 12, 15, 18, 21
3870 .db 24, 27, 30, 33, 36, 39, 42, 45
3871 .db 48, 51, 54, 57, 59, 62, 65, 67
3872 .db 70, 73, 75, 78, 80, 82, 85, 87
3873 .db 89, 91, 94, 96, 98,100,102,103
3874 .db 105,107,108,110,112,113,114,116
3875 .db 117,118,119,120,121,122,123,123
3876 .db 124,125,125,126,126,126,126,126
3879 txtLevel: .db "Level ",0
3880 txtWorms: .db "Worms: 0",0 ;follows txtLevel
3881 txtName: .db "Name",0
3882 txtWinner: .db "Wins " ;follows txtName
3883 txtDied: .db "Died " ;follows txtWinner
3884 txtScore: .db "Score",0 ;follows txtDied
3885 txtLeft: .db " left",0 ;follows txtScore
3886 txthiscore:.db "HiScore:",0
3888 txtReady: .db "Prepare!",0
3892 txtGO: .db 5,5,5,5,5," GAME OVER ",$CF,$CF,$CF,$CF,$CF,0
3895 datalevels: .dw LevelDef, LevelDefM
3896 .dw LevelDefT,LevelDefM
3897 .dw LevelDefM,LevelDefM
3898 .dw LevelDefR,LevelDefC
3899 nrlevels: .db 1,3,1,3,3,3,3,1 ;=defaults
3901 _datalink = %0000001 ;linkplay
3902 _datafoodl = %0000010 ;left=0 limit
3903 _datasingl = %0000100 ;singleplayer=1 (=hiscore+keep_length+nextlevel)
3904 _datamultpeas = %0001000 ;multiple peas=1
3905 _datatime = %0010000 ;time incs score (timematch)
3906 _datafood = %0100000 ;food present
3907 _datadie = %1000000 ;worm dies on impact
3908 ;reserved %10000000 ;for future use
3910 savestart: ; �game info (see above)
3911 ; | �lives (0=unlimited)
3912 ; | | �nrworms (can be altered by user)
3913 ; | | | �level (reset to 1 at startup)
3914 ; | | | | �speed/delay (-1=def)
3915 ; | | | | | �grow speed (-1=none; 0=continuous)
3916 ; | | | | | | �turn speed (8=def)
3917 ; | | | | | | | �score limit (0=none)
3918 gamesingle = 0 ;used | | | | | | | |
3919 datasingle: .db %1100110,3,1,1,-1,-1, 8, 0 ;Singleplayer (SP; 3 lives)
3921 datapeas: .db %1100100,1,1,1,-1,-1, 8, 0 ;Peaworm (SP; 1 live)
3923 datatron: .db %1010100,1,1,1,-1, 0, 8, 0 ;Tron (SP; 1 live, cont.growth)
3924 gamedeathm = 3 ;used
3925 datadeathm: .db %1000000,3,2,1,-1,49, 8, 0 ;Deathmatch (3 lives, 50 growth)
3927 datafoodm: .db %1100000,0,2,1,-1,-1, 8,10 ;Foodmatch (100 score)
3929 datatimem: .db %1010000,1,2,1,-1, 0, 8, 0 ;Timematch (tron, 100 score)
3931 datarace: .db %0000000,0,2,1,-1,-1, 8,10 ;Race (100 score, no collision)
3933 datactf: .db %1001000,0,4,1,-1,-1, 8,10 ;CTF (100 score)
3935 worm1set: .dw worm1p,worm1p
3936 .db %11110111,1,-01,K_RIGHT,K_LEFT
3937 worm1name: .db "WORMY ",0
3938 worm2set: .dw worm2p,worm2p
3939 .db %11111011,0,-01,K_F2,K_F1
3940 worm2name: .db "VIPER ",0
3941 worm3set: .dw worm3p,worm3p
3942 .db %11111011,1,-01,K_COMMA,K_STO
3943 worm3name: .db "NIBBLER ",0
3944 worm4set: .dw worm4p,worm4p
3945 .db %11111011,0,-01,K_PLUS,K_ENTER
3946 worm4name: .db "JIM ",0
3955 Gametype: .db 0 ;last gamemode
3969 head = 13 ;4B (head=tail)
3970 tail = 15 ;also@next level
3972 reserv = 18 ;loop (race:lap|ctf:pea)
3983 .db "WWW.SHIAR.ORG WWW.SHIAR.ORG "
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 " wormy@shiar.org",0
4015 defspriteimg: .db %01100000
4021 .db "Internal Levels",0
4022 .db "by SHIAR -- still t"
4023 .db "o be added...." ;,0
4025 .db 0,deflevels/256,deflevels&255
4028 ;-----------------------------
4029 ;----------- end -------------
4030 ;-----------------------------