2 ; Version : 96% (0.96.C21)
3 ; Release Date : UUHHhhh... soon?!?
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 ;-----------------------------
21 ; 1% * misc (pollish, bugs, &&&)
22 ; * mem at worm #4 (still 12 bytes or so.....)
23 ; * fix line proc (+large circles)
25 ; 1% * fix transmit game/level data
27 ;100% = bugs fixed + levels done
29 ;>110%: sound, startpos
30 ;>120%: coop (DON'T COUNT ON IT)
32 ;-----------------------------
33 ;-----------------------------
34 ;------- W O R M Y ---------
35 ;-----------------------------
36 ;-----------------------------
38 #define buffer ;use display buffer (otherwise write directly to screen)
39 #define readymask ;"greys" out the field before starting a level
40 #define coolzgfx ;nice graphics for game over screen
42 ;#define intlevels ;internal levels
43 ;#define readytext ;displays "prepare" before level starts
44 ;#define invincible ;worms cannot die =)
45 ;#define optdie ;in race games worms don't die when they run into each other
52 #include "ti86asm.inc"
53 _SHRACC = $4383 ;4x srl a
54 _SHLACC = $438B ;4x sll a
55 _divHLby10 = $4044 ;hl=hl/10
56 _divAby10 = $4DAF ;a=a/10
57 _HLTIMES10 = $41BF ;hl=hl*10
58 _cphlde = $403C ;cp hl,de
59 _clrWindow = $4A86 ;clear screen
60 _asapvar = $D6FC ;own name (worm)
61 _MOV4B = $429B ;4x ld (de),(hl)
62 _MOV5B = $4297 ;5x ld (de),(hl)
63 _mov9b = $4283 ;9x ld (de),(hl)
64 _ldHLind = $4010 ;ld hl,(hl)
65 _swapt_ = $45F3 ;ex_ahl_bde
66 _Get_Word_ahl = $521D ;ld de,(ahl)
67 _Set_Word_ahl = $5221 ;ld (ahl),de
68 _INC_PTR_AHL = $4637 ;ahl=ahl+1
69 _AHL_PLUS_2_PG3 = $4C3F ;ahl=ahl+2
70 _SET_ABS_SRC_ADDR = $4647 ;set source for mm.ldir =ahl
71 _LOAD_ABS_SRC_ADDR = $5209 ;ahl = mm.ldir source
72 _SET_ABS_DEST_ADDR = $5285 ;set destination for mm.ldir = ahl
73 _SET_MM_NUM_BYTES = $464F ;number of bytes for mm.ldir = ahl
74 _mm_ldir = $52ED ;24bit ldir
75 _MM_LDIR_SET_SIZE = $524D ;_SET_MM_NUM_BYTES + _mm_ldir
76 _RAM_PAGE_1 = $47E3 ;set $8000+ to page 1
77 _RAM_PAGE_7 = $47F3 ;"""" 7
78 _PTEMP_END = $D29A ;end of VAT
79 _load_ram_ahl = $462F ;ahl->page+hl
80 _writeb_inc_ahl = $5567 ;ld (ahl++),c
81 _jforce = $409C ;TI-OS stack restored
82 _EXLP = $4493 ;swap (hl),(de) b times
83 _GETB_AHL = $46C3 ;a=(ahl) \ hl=ahl
85 ;-----------------------------
86 ;------- data storage -------
87 ;-----------------------------
91 ScrBuffer = $8820 ;-A7FF (20*FF=1FE0)
92 worm2p = $A800 ;-ABFF (400) %10101O00
93 worm1 = $AC00 ;-AC1D (31d)
94 worm2 = $AC1F ;-AC3B (1F)
95 worm3 = $AC3E ;-AC59 (1F)
96 worm4 = $AC5D ;-AC77 (1F)
97 balls = $AC7C ;-ACFF (3x43d)
98 SinCosTable = $AD00 ;-AE00 (4*40)
99 turn10 = $AE01 ;-AE01 (1) (counter)
100 peaspos = $AE02 ;-AE05 (4) (peas)
101 ;free = $AE06 ;-AFFF (1FA)
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)
108 ;can you believe i actually left $269 bytes of memory unused?!?
110 ;MEM|8---9---A---B---C---D---E---F---|
111 ; |..[------]||[]|......[-----]|[].|
112 ; | SCREEN 2* 13 PRGM 4LV |
116 namelength = $BC00 ;(1) @menu
117 datalink = $BC00 ;(8) @init
119 DispBuffer = $BC00 ;(10x57d) @game
124 ;-----------------------------
125 ;------- program start -------
126 ;-----------------------------
128 .org %1101011101001000
134 .org $-1 ;3y3 M 1337!
154 .db %00000000,%00111100
155 .db %00000000,%01010010
156 .db %00000000,%01100001
157 .db %01100011,%10011001
158 .db %10010100,%01101001
159 .db %10011001,%00011001
160 .db %01000010,%11000001
161 .db %00111100,%00111110
164 levelhead2 = 95 ;wormy levels header = "95"
195 ld bc,int_end-int_handler
199 im 2 ;...it *does* work ;)
202 ld hl,$BFFF ;VAT start
205 ld de,(_PTEMP_END+1) ;VAT end
235 ex de,hl ;ld ahl,(hl)
236 cal _AHL_PLUS_2_PG3 ;string id
237 cal _Get_Word_ahl ;ld de,(ahl)
241 jr nz,_searchnext ;not worm
245 inc ix ;save level's ahl
258 cal _Get_Word_ahl ;ld de,(ahl++)
260 ld a,e ;set new level
289 cal _vputs ;"< SELECT LEVELS >"
309 cp 49 ;bottom of screen
317 ld l,(ix+2) ;ahl=(ix)
318 cal _load_ram_ahl ;hl=ahl
322 readylevelfile: ;selected level at ahl
323 ; ld hl,templevels-3/0
325 add a,3 ;sellev+3 (#0==-3)
341 cal _GETB_AHL ;ld a,(ahl)
346 cal _INC_PTR_AHL ;ahl++
348 jr nz,skiptitle ;goto #0-terminator
374 cal _load_ram_ahl ;hl=ahl
375 ld de,$FFA0 ;desc.text
380 cp d ;de>$FFFF (offscreen)
381 jr nz,levdescclearloop
386 ld ix,templevels-6 ;reset 2 1st page
391 ld b,-2 ;level selected
397 pop bc ;GET_KEY destr. b
415 or a ;levelfile on page 0 (=internal)
417 cal skiptitle ;skip description
420 ld (leveldataSize),de
425 ld (hilvlposa),a ;singleplayer levels
430 cal _SET_ABS_SRC_ADDR ;levelsstart
433 cal _SET_ABS_DEST_ADDR ;store in mem.
436 cal _MM_LDIR_SET_SIZE
438 cal _LOAD_ABS_SRC_ADDR ;->ahl
445 ldi ;(de),(hl)\inc hl
450 res 2,(iy+13) ;appAutoScroll
458 ld (hl),1 ;def=level#1
462 ;-----------------------------
463 ;----- build trig tables -----
464 ;-----------------------------
489 ;-----------------------------
490 ;---------- menu -------------
491 ;-----------------------------
493 DisplayMenu: ;---draw menu---
500 ld hl,$FC00+$010 ;(*,01)
502 ld hl,$FC00+$160 ;(*,22)
504 ld hl,$FC00+$3E0 ;(*,62)
509 dec a ;will be inced @changegame
512 ld hl,changegame ;dispmenusets ;mainMenu
513 psh hl ;jump here after ret
516 ;Mode|Level|Limit|Worms|worm #|controls
517 ; jr dispmenucommon ;cal
522 ld de,$FD80 ;begin pos
547 hr: ;draw horizontal line at hl
549 ; jp menuinvloop ;shorter but not good for pausescreen
561 ;Back|Lives|Limit|Speed|Rotation|Growth
576 inc hl \ inc hl \ inc hl
594 inc a ;-1=None; 0..98->1..99
609 cal cshowA0 ;turn speed
616 ld a,(hl) ;(scorelimit)
621 jr z,optionMenu ;do not display 0 behind 'None'
633 jp z,dispmainmenu ;mainMenu
677 cal loadgamecar ;a=(hl)
680 jr nc,optionMenu ;>99
684 jp dispomenusets ;optionMenu
687 sub 1 ;dec does not set cf
695 jr nc,optionMenu ;>99
698 jr _dispomenusets ;optionMenu
701 sub 1 ;dec does not set cf
708 ld a,(hl) ;(scorelimit)
715 jr nc,_optionMenu ;>98
719 jr _dispomenusets ;optionMenu
725 jr z,_optionMenu ;<-1
732 inc hl ;=saves 2 bytes :P
741 jr nc,_optionMenu ;>25
744 jr _dispomenusets ;optionMenu
759 jr nc,_optionMenu ;>98
762 jr _dispomenusets ;optionMenu
768 jr z,__optionMenu ;<-1
780 dec a ;2nd item: level
782 sub 3 ;5th item: wormname
786 jp LetsGetThisPartyOn ;otherwise
817 jr nc,mainMenu ;may not become >(nrworms)
821 jr _dispmenusets ;mainMenu
834 ; jr z,bchangecurworm
839 jr nz,changedcurworm ;save >0
844 ld a,(hl) ;hl=nrworms
847 jr nc,mainMenu ;may not be >4
850 jr _dispmenusets ;mainMenu
854 ld a,(hl) ;hl=nrworms
858 ld a,(hl) ;hl=nrworms
861 jr nc,changednrworms ;save >=2
870 jr _mainMenu ;don't change for singleplayer
875 dec hl ;inced earlier
877 ld a,1 ;change LS-bit (=link)
881 jr dispmenusets ;mainMenu
888 jr dispmenusets ;mainMenu
901 jr dispmenusets ;mainMenu
904 inc hl ;hl=loadgamecar+2
906 ld a,(hl) ;(curlevel)
908 cp (hl) ;max level for sel.game
914 jr dispmenusets ;mainMenu
917 ld a,(hl) ;(curlevel)
922 getnrlevels: ;for current gametype at hl
949 cal getcustomkey ;left
950 cal getcustomkey ;right
953 ;---display current settings---
963 add hl,de ;hl=posGame+(Gametype)
964 ld a,(hl) ;str.offset
968 ld (CURtxtGame),hl ;save for g/o
969 cal _vputs ;Singleplayer
1018 ld hl,$363E ;controls
1024 ;--- handle menukeys ---
1032 pop bc ;GET_KEY destr. b
1042 menupos: ;highlight #b
1055 add hl,hl ;$FD20+item*96
1085 ;--- change name ---
1088 getwormname: ;of (curworm)
1116 ld hl,$FF07 ;begin pos
1149 dec (hl) ;(namelength)
1164 .db 0,".<>!",0,0,0,0 ;down,L,R,up
1165 .db 0,"XTOJE0",0 ;enter..clear
1166 .db " WSNID9",0 ;(-)..custom
1167 .db "ZVRMHC8",0 ;dot..del
1168 .db "YUQLGB7#" ;0..xvar
1169 .db $D9,"-PKFA6'" ;on..alpha
1170 .db "54321*",0,$D0 ;F5..more
1174 ld (ix+8),0 ;end mark
1177 ;-----------------------------
1178 ;------- procs-n-stuff -------
1179 ;-----------------------------
1183 halt ;save them batteries! yeah!
1187 ld hl,$FD97 ;begin pos
1188 ld a,35 ;nr of lines
1190 ld de,7 ;bytes to add
1192 ld c,9 ;bytes to clear
1197 jr nz,clroldsetsloop
1200 jr nz,clroldsettings
1203 hlatlevel: ;d must be 0
1205 ld a,(Gametype) ;8bytes -> 7bytes
1210 add a,24+1 ;go to datalevels
1212 sbc hl,de ;datalevels
1213 cal _ldHLind ;ld hl,(hl)
1214 pop de ;de=loadgamecar
1216 ld a,(de) ;(curlevel)
1220 dec d ;levels to skip
1224 ret ;hl=begin of correct level
1226 skiplvltitle: ;zf=singleplayer
1228 or a ;null-terminator
1233 skiplevel: ;@hl - destr:ab - alter:hl
1242 ld b,(hl) ;spritesize
1250 pop af ;cp (Gametype),0
1252 inc b ;multiplayer lvl
1254 inc b ;skip other 3 worms (9 bytes)
1291 ;build: c=(gameCar)=(hl-1)
1292 ; a=(wormbeglives)=(hl)
1298 add a,a ;8 bytes per mode
1310 ;-----------------------------
1311 ;-------- start game ---------
1312 ;-----------------------------
1316 ld (CheckExit),a ;set exit state
1321 ld a,4 ;4x (all worms)
1331 ld (hl),b ;score+1=0
1338 ex de,hl ;de=wormX+head
1342 jr nz,createwormsloop
1344 OhMyGodItsALabel: ;pj34r my coding skillz
1348 ex (sp),hl ;pop \ psh leveldata
1349 psh hl ;psh loadgamecar
1353 jp nc,StartLevel ;&&&jr
1355 ;--------- link ------------
1373 jp DisplayMenu ;return to menu
1383 ;name/keys: wormy#1 = link = 0 + link (name1)
1384 ; 2 = worm #1 = #1 + local(name1)
1385 ; 3 = link = 0 + link (name2)
1386 ; 4 = worm #2 = #2 + local(name2)
1389 ldi ;keys worm#2 = worm#1
1392 ldi ;keys worm#4 = worm#2
1395 ld (worm1+left),a ;worm 1...
1396 ld (worm3+left),a ;and worm 3 via link
1442 ;name/keys: wormy#1 = worm #1 = ok
1443 ; 2 = link = 0 + link (name1)
1444 ; 3 = worm #2 = #2 + local(name2)
1445 ; 4 = link = 0 + link (name2)
1448 ldi ;keys worm#3 = worm#2
1451 ld (worm2+left),a ;worm 2+4..
1452 ld (worm4+left),a ;..over link
1461 ld hl,templevels ;&&&&&&&
1477 ;-------- load level ---------
1496 ld (turnright),a ;more efficient
1500 cal _HLTIMES10 ;hl=10*(hl)
1505 pop hl ;begin of current level
1512 dec (hl) ;curlevel-- (not beyond last lvl)
1515 ;show end msg or smtn
1517 psh bc ;where to go afterwards
1518 inc hl ;location of ending-code
1519 jp (hl) ;go there ("call")
1532 ld a,(hl) ;speed from level
1536 ld (de),a ;custom speed
1555 ld b,0 ;bc=sprite size
1556 add hl,bc ;hl=behind sprite
1563 setsprite: ;de=@sprite ;a=sprsize
1587 pop af ;cp (Gametype),0
1595 ld a,SinCosTable/256
1609 ld bc,(worm2-worm1)-7
1619 ;-------- draw level ---------
1646 add hl,hl ;32=scr.width
1653 ld bc,63 ;first 2 rows
1655 ldir ;draw upper border
1657 ld (hl),%11000000 ;first left border
1662 inc hl ;clear rest of line
1702 cp gamerace ;or gamectf
1703 jr c,levelhasbeensetup
1705 ld c,2 ;ld bc,2 (2 bytes)
1706 jr z,loadextralevelstuff ;cp gamerace
1707 ld c,4 ;ld bc,4 (2nd flag in ctf)
1708 loadextralevelstuff:
1717 ;--------- prepare -----------
1720 psh hl ; >> levelp new
1747 ld hl,4+(txtposReady*256)
1770 ;-----------------------------
1771 ;----------- LOOP ------------
1772 ;-----------------------------
1775 ld bc,(worm1+pos) ;camera worm #1
1777 or a ;if #1 not over link
1779 ld bc,(worm2+pos) ;otherwise view from #2
1781 cal DisplayField ;display piece of level
1796 jr nz,screeninvertloop
1809 ld (handledworm),a ;reset
1827 jr nz,nodispupdate ;just once every 10 turns
1828 ld (hl),10 ;reset counter
1829 cal forceshowstats ;update score
1834 jr nz,noctfpeas2draw
1837 cal tryDrawPea ;pea#1
1840 cal tryDrawPea ;pea#2
1847 cal nz,handlethoseneatlittleballs
1860 inc (hl) ;0..nrworms-1
1863 ;-----------------------------
1864 ;---------- keys -------------
1865 ;-----------------------------
1874 rla ;=$17 (c=EXIT-key)
1879 ;------- pause menu -------
1884 ;Resume|Turn Off|Contrast|Exit||
1887 ld hl,$FC00+$170 ;(*,23)
1889 ld hl,$FC00+$310 ;(*,49)
1965 out (7),a ;both wires low = game over signal
1974 cal menuinvloop ;invert
1976 cal hr ;menuinvloop w/ b=16
1986 cal menuinvloop ;invert
1988 cal hr ;menuinvloop w/ b=16
2007 cal _vputs ;Died Score
2022 jr c,nonewwinner ;h<d
2023 jr nz,newwinner ;h>d
2026 jr nc,nonewwinner ;l<e
2037 cpl ;high value (>$FB)
2042 ld a,(hl) ;less deaths
2049 ;---display worms---
2061 cp (hl) ;input=0 = link
2078 ld a,(hl) ;worm+died
2085 jr nz,nodmwinner ;deathmatch?
2086 ld a,0 ;winner's deaths
2088 cp (hl) ;equals this worm?
2089 scf ;jr nz,notwinner
2092 jr c,notwinner ;no singleplayer winners
2094 cal _ldHLind ;ld hl,(hl)
2097 cal _cphlde ;==highest score..
2112 dnz displayWormStats
2115 or a ;singleplayer (0) only
2116 jr nz,hilevelcheckdone
2121 jr c,hilevelcheckdone
2122 ld (hl),a ;save local
2127 hilvlposhl =$-2 ;save external
2128 cal _writeb_inc_ahl ;ld (ahl),c
2133 jr z,hiscorecheckdone ;no SP
2135 cal loadhiscoreposinahl
2136 cal _SET_ABS_SRC_ADDR ;from ahl (lvlfile)
2139 cal _SET_ABS_DEST_ADDR ;to local
2141 cal _MM_LDIR_SET_SIZE ;get old score+name
2144 ld de,(highsave) ;de=prev. hiscore
2145 ld hl,(worm1+score) ;hl=worm1's score
2146 cal _cphlde ;sub hl,de
2147 jr c,NotNewHigh ;new<old
2148 jr z,NotNewHigh ;new<=old
2150 ld (highsave),hl ;store new hiscore
2151 ld de,highsave+2 ;to
2152 ld hl,worm1+name ;from
2154 ldir ;store new hiname
2155 cal loadhiscoreposinahl
2156 cal _SET_ABS_DEST_ADDR ;to ahl
2159 cal _SET_ABS_SRC_ADDR ;from local
2161 cal _MM_LDIR_SET_SIZE ;save new
2189 ;x123456789012345678901
2190 ;>>>>>> GAME OVER <<<<<
2195 ;6Worm#02 @ 05 00120
2202 rst 20h ;_ABS_MOV10TOOP1
2204 ld hl,savestart-_asm_exec_ram+4
2208 cal _SET_ABS_DEST_ADDR
2212 cal _SET_ABS_SRC_ADDR
2213 ld hl,saveend-savestart
2214 cal _MM_LDIR_SET_SIZE
2222 loadhiscoreposinahl:
2223 ld hl,0 ;for peaworm and singleplayer
2229 ld a,(nrlevels+1) ;skip peaworm slots if tron mode
2233 ld b,a ;levels to skip (including 1 for singleplayer)
2234 ld de,5 ;to add per level
2236 add hl,de ;one word+3 bytes for name
2237 dnz addlevelposition
2244 adc a,0 ;ahl=saveloc
2253 jp _putc ;..then put *
2255 ;-----------------------------
2256 ;----------- worm ------------
2257 ;-----------------------------
2262 cal saverespawncounter
2268 jr DoesWormTailEqualsWormHead ;chk4 size=0
2279 jr nz,DoesWormTailEqualsWormHead
2280 inc (ix+grow+1) ;+256
2281 DoesWormTailEqualsWormHead:
2283 jr nz,removewormloop
2287 jr nz,safewormsizedone
2291 ld (ix+grow+1),0 ;high
2296 ld (ix+tail),e ;head=tail/size=0
2302 jr nz,saverespawncounter
2326 ld a,%01111111 ;default
2329 dnz bitmask ;a/8 times
2330 out (1),a ;send bitmask
2331 in a,(1) ;input keys
2336 dnz keybit ;check match (cf set)
2339 inkeys: ;use jp not call!
2358 jr z,inlink ;input by link
2359 cal inkeys ;input by keys
2363 ld c,l ;send our keys
2370 ;-----------------------------
2371 ;------- handle worm ---------
2372 ;-----------------------------
2425 ;-------- move worm ----------
2453 notmoveY: ;bc=newpos
2460 pop hl ; << pos (old)
2478 ;--------- worm hit ----------
2485 cal z,checkhitotherworm
2488 and _datamultpeas ;&&bit
2492 jp z,WormDead ;no food
2499 cal DrawPea ;remove pea
2514 jp nz,Drawworm ;continue
2520 jp nz,Exit ;stack restored
2531 cal _IncScore ;score+(40*level)
2538 chkpeahit: ;bc=ownpos;hl=peapos (destr:ad)
2554 ld hl,(peaspos) ;1st pea
2557 and %01 ;ourpea (0|1)
2559 ld hl,(peaspos+2) ;2nd pea ;&&&ex de,hl?
2564 ld a,e ;peek a (that's x86asm for pop\push ;)
2565 bit 1,a ;%10 = carrying flag?
2566 jp z,WormDead ;if not just die
2571 pop af ;which flag? (=and %1)
2572 ld hl,drawctfpea1 ;restore #1
2573 jr z,nottheotherflag
2574 ld hl,drawctfpea2 ;restore #2
2576 ld (hl),3 ;draw delay 3 turns
2582 hitflag: ;correct pea hit
2584 xor %11 ;invert flag taken + ownflag
2586 and %10 ;just returned?
2590 jr nz,Drawworm ;flag taken, continue game
2592 ld e,20 ;flag captured+returned
2596 ld (drawctfpea1),a ;redraw..
2597 ld (drawctfpea2),a ;..both flags
2600 ;-----------------------------
2619 jr nz,nextotherwormbit
2629 ld a,(peaspos+1) ;yline
2632 jr nc,checklap ;y>yline -> a=1
2633 xor a ;y<yline -> a=0
2636 ret z ;same as before
2637 ld (ix+reserv),a ;1st time
2640 and 1 ;group 0 (1,3) or 1 (2,4)
2642 ret z ;(group 0 and y<yline) or (group 1 and y>yline)
2649 ;-------- draw worm ----------
2657 cal z,checkhitlapline
2663 ret z ;keep tail in "Tron"
2717 ;-----------------------------
2718 ;---------- ball -------------
2719 ;-----------------------------
2721 handlethoseneatlittleballs:
2767 bit 1,d ;1=up; 0=down
2797 letsmovetheotherway:
2812 ;-----------------------------
2813 ;----------- procs -----------
2814 ;-----------------------------
2818 ld a,%10000000 ;all key-masks
2821 inc a ;cp %11111111 (no keys pressed)
2822 jr nz,releasekeys ;keep waitin
2823 cal GET_KEY ;clear buffer
2851 ld (ix+delay),respawndelay
2870 ld (ix+pos2+1),a ;x2
2877 cp gamectf ;ctf no death penalty
2880 ret nz ;HandleWorm done
2882 or a ;0=no live limit
2883 ret z ;don't end game
2886 jr z,anyworm ;quit at any worm's death
2887 ld a,(nrworms) ;timematch: all worms must've died
2889 ld hl,worm1+lives-(worm2-worm1)
2891 xor a ;check for 0 lives
2893 add hl,de ;next worm
2895 ret nz ;any >0: don't exit
2898 ld a,$A7 ;exit@end of turn
2899 ld (CheckExit),a ;set exit state
2904 .db $dd,$7d ;ld a,lx
2907 jr nz,chkworm2 ; ret nz
2934 CheckPea: ;@hl; destr:abcde
2947 ret nz ;nz=pixel found
2956 tryDrawPea: ;hl=peapos;bc=dopea
2965 dec (hl) ;hl=appeartime
2966 ex de,hl ;hl=peaspos
2981 cal sendnewpeaoverlink
2990 PutSprite: ;||@(b,c)
2991 ;by SHIAR only ix saved
3028 ;----------- score -----------
3031 ;piece of crap checking whether you've already won in timematch
3043 jr z,nneexxtt ;yourself
3045 ret nz ;someone else still alive
3050 jr c,nneexxtt_ ;you>him
3063 dnz chktimematchover
3079 add hl,de ;increase score
3082 jr z,scorecommon ;hl/1000 not increased
3091 jr c,showstats ;<0=0
3094 IncScore: ;inc score by e
3096 _IncScore ; inc by de
3100 or a ;if singleplayer...
3102 add hl,de ;score+=de
3105 ld (ix+score),l ;save
3110 jr z,showstats ;de=0=no limit
3117 jr nz,timematchscore ;no disp for timematches
3118 ld hl,$FC00 ;&&&only necessary in deathmatch
3140 shownameloop: ;1st 3 chars
3169 showstat: ;(multiplayer)
3180 showA: ;small w/o leading 0 (&&&combine w/ cshowA0??)
3199 showstatsS: ;(singleplayer)
3234 showA0: ;big w/ leading 0
3246 cshowA0: ;small w/ leading 0
3281 ;-----------------------------
3399 ld (ShiftRightCounter),a
3401 ld (ShiftRightChunk),a
3415 ShiftRightCounter = $-1
3437 ld (ShiftLeftCounter),a
3439 ld (ShiftLeftChunk),a
3441 jr nc,ShiftLeftSameByte
3460 ShiftLeftCounter = $-1
3471 jr nz,ShiftRowsRight
3505 ;----------- draw ------------
3519 CheckPixel: ;at bc in d
3526 ;CLEM's FIND_PIXEL (131+? cycles; 28+4 bytes)
3527 ;(b,c) to hl:a; "destroyes" ahl
3529 FindPixel: ;(b,c) to hl:a
3592 drawcircle: ;(d,e),h ;de=x,y; h=z
3603 ex (sp),hl ;push zz \ pop x,y
3604 cal circledraw ;(x-xx,y+yy)-(x+xx,y+yy)
3605 ;(x-xx,y-yy)-(x+xx,y-yy)
3606 cal circledraw ;(x-yy,y+xx)-(x+yy,y+xx)
3607 ;(x-yy,y-xx)-(x+yy,y-xx)
3609 ex (sp),hl ;push x,y \ pop zz
3612 dec a ;-256<h<0 = $FF**
3614 jr z,circlenext ;jump if zz<0
3618 add a,a ;a=2yy-2 ;nc
3620 sbc hl,de ;zz=zz-2yy+2
3628 add hl,de ;zz=zz+2xx+3
3637 circledraw: ;destr:de
3642 add hl,bc ;h=x+xx; l=y+yy
3644 cal drawline ;(h-b,l+c)-(h+b,l+c)
3650 cal drawline ;(h-b,l-c)-(h+b,l-c)
3651 ld a,b ;swap xx and yy
3657 drawbox: ;(d,e)-(h,l)
3682 drawline: ;(d,e)-(h,l)
3688 jr c,lineXincs ;if x>xx
3690 lineXincs: ;deltax=|deltax|
3694 cal FindPixel ; (ahl=x+y)
3696 ld c,a ;c=mask (always)
3699 ld b,a ;b=deltax (always>0)
3701 jr nz,lineexists ;deltax!=0
3703 jr nz,lineexists ;deltay!=0
3705 jr DoneLine ;line is 1 pixel
3708 ld de,32 ;go down (def)
3709 jr nc,lineYincs ;cf = deltay<0
3712 lineYincs: ;lets assume y incs as well
3714 jr nc,SteepLine ;deltay<deltax?
3715 ld (line2sm+1),a ;a=deltay
3719 ld (line1sm+1),a ;a=-deltax
3721 add a,h ;a=deltay-deltax/2
3725 psh af ;init z=dy-dx
3739 dnz linedrawxloop ;|deltax| times
3755 ld (line4sm+1),a ;a=deltax
3756 sub h ;a=deltax-deltay
3760 psh af ;init z=2(dx-dy)
3774 dnz linedrawyloop ;|deltay| times
3780 receivenewpeaoverlink:
3792 jr z,receivenewpeaoverlink
3793 ld c,l ;send pea's pos
3796 ; jr Qsend ;that's why it's here
3798 ;..and last but not least..:
3799 ;-----------------------------
3800 ;----------- link ------------
3801 ;-----------------------------
3808 Qsend: ;--- try to send 8 bits in C; CF=error --- destr:abcde ---
3811 jr z,linkerr ;both wires low = exit signal
3812 ld b,8 ;bits to send
3815 rl c ;bit to send in cf
3816 ld a,D0LD1H ;0: lower white
3818 ld a,D0HD1L ;1: lower red
3820 out (7),a ;lower one (send bit)
3822 cal checklink ;other calc must lower other wire
3824 cal linkok ;raise one, ok to raise other (out (7),D0HD1H)
3827 cp %11 ;both raised (by other calc)
3830 dnz sendloop ;repeat for all bits
3832 ld (linklosses),a ;reset number of losses
3837 Crecv: ;--- receive 8 bits into A/C --- destr:abCde ---
3839 ret nc ;return if all went ok
3840 jr Crecv ;and try again
3842 Qrecv: ;--- receive 8 bits into A/C; CF=error --- destr:abCde ---
3844 jr z,linkerr ;both low = error, quit
3845 ld b,8 ;bits to receive
3849 cal linktest ;checklink
3851 jr z,recvwait ;both high = nothing sent (yet)
3853 rra ;received bit in cf
3855 jr c,received ;lower white wire as well
3856 ld a,D0HD1L ;lower red
3859 out (7),a ;both wires low
3862 jr z,recvwaitack ;same wire will be raised again by other calc
3863 cal linkok ;raise both
3865 dnz recvloop ;repeat for all bits
3867 ld (linklosses),a ;reset number of losses
3874 out (7),a ;raise both wires = link ok
3877 checklink: ;load wires in A and check for timeout
3878 dec de ;decrease timer
3881 jr z,linktimeout ;timeout if de==0
3884 out (1),a ;select keys
3894 ld a,0 ;losses so far
3896 inc a ;and this is another one
3898 pop de ;return from link
3899 cp lossout ;quit if too many errors
3900 ret c ;otherwise just continue
3906 ;-----------------------------
3907 ;---------- levels -----------
3908 ;-----------------------------
3911 .db 5,4,15,15,0,0 ;peas,speed,growth,begin_size,sprite,balls
3912 .db 0,2,63 ;start d, y, x
3913 .db 128,57 ;field width (128-255), height (57-255)
3914 .db 0 ;no additional lines, boxes
3922 .db $40,30,2,$C0,30,125, $00,2,64,$80,54,64
3926 .db "Fast Fun :))",0
3928 .db %1110000,%10001000,%10001000,%10001000,%1110000,0
3929 .db $40,30,2,$C0,30,125, $00,2,64,$80,54,64
3935 .db $40,30,2,$C0,30,125, $00,2,64,$80,54,64
3940 LevelDefT: ;tron=no delay
3941 .db "Empty Tron Level",0
3943 .db %1110000,%10001000,%10001000,%10001000,%1110000,0
3944 .db $40,30,64,$C0,30,64, $00,30,64,$80,30,64
3949 .db "Round and Round",0
3951 .db %1110000,%10001000,%10001000,%10001000,%1110000,0
3952 .db $40,23,2,$C0,23,125, $40,35,2,$C0,35,125
3960 .db %1110000,%10001000,%10001000,%10001000,%1110000,0
3961 .db $40,23,2,$C0,23,125, $40,35,2,$C0,35,125
3968 ;-----------------------------
3969 ;---------- data -------------
3970 ;-----------------------------
3973 .db %00011110,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000001,%11000000,%00000000,%00000000,%00000001,%10000000,%00000000,%00001111,%10000000
3974 .db %00111110,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000001,%11100000,%00000000,%00000011,%11000010,%01000011,%10011100,%00110000,%01100000
3975 .db %01110000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%01110000,%00111000,%00001100,%00110001,%00110100,%01100011,%01000000,%00010000
3976 .db %01100000,%01111100,%00000001,%11111111,%00000000,%11110000,%01111001,%11100000,%00110000,%01111100,%00010001,%11001001,%00001000,%00100000,%10000010,%00010000
3977 .db %11100000,%11111110,%00000011,%11111111,%10000011,%11111000,%11111111,%11110000,%00110000,%11101100,%00010001,%11000100,%10000001,%00000100,%10001110,%00001000
3978 .db %11000001,%11000111,%00000111,%00000001,%11000111,%10011001,%11001111,%00111000,%00110000,%11000110,%00001100,%00000010,%01100010,%10011100,%00010001,%00001000
3979 .db %11000001,%10000011,%00000110,%00000000,%11100110,%00000001,%10011111,%10011000,%00111001,%11000110,%00000011,%11000010,%00011100,%01100010,%00100001,%01101000
3980 .db %11000001,%10000011,%00000110,%11000000,%01101110,%00000011,%10111001,%11011100,%00111001,%11000110,%01111000,%00100001,%00000000,%00000001,%11000001,%01101000
3981 .db %11000001,%11000111,%00000110,%11000000,%01101100,%00000011,%00110000,%11001100,%00011111,%10000110,%10000101,%11100001,%00000000,%00000000,%00000001,%00010000
3982 .db %11000000,%11000110,%00000110,%11000000,%01101100,%00000011,%00110000,%11001100,%00001111,%00001110,%10010110,%00010001,%00000000,%00000000,%00000000,%11100000
3983 .db %11100000,%11101110,%00001110,%11000000,%01101100,%00000011,%00111001,%11001100,%00000000,%00001100,%01100100,%00001001,%00111111,%11111111,%11000000,%00000000
3984 .db %01100000,%01111100,%00001100,%11000000,%01101100,%00000011,%00011111,%10001110,%00000000,%00001100,%01000000,%10000001,%01000000,%00000000,%00000000,%00000000
3985 .db %01110000,%00111000,%00011100,%11100000,%11101110,%00000011,%00001111,%00000110,%00000000,%00011100,%01000000,%11000001,%01100101,%01001001,%10000011,%01100011
3986 .db %00111000,%11111110,%00111000,%01110001,%11000110,%00000011,%10000000,%00000111,%10000000,%00111000,%01000001,%00100001,%00110101,%00010101,%01000101,%01010100
3987 .db %00011111,%11101111,%11110000,%00111111,%10000111,%00000001,%10000000,%00000011,%11111111,%11110000,%00111110,%00011110,%00010111,%01011101,%10010101,%01100101
3988 .db %00001111,%10000011,%11100000,%00011111,%00000011,%00000001,%10000000,%00000000,%11111111,%11100000,%00000000,%00000000,%11100101,%01010101,%01000110,%01010011
3991 .db %00000110,%00111000,%00000000,%00111100,%00001111,%10001110,%00111100,%01111000,%00001100,%11011000,%11100011,%10000000,%00000000,%11111100,%00111000,%00000000
3992 .db %00011001,%01000110,%11100000,%11000010,%00011100,%11011111,%01111110,%11111000,%00011110,%11011101,%11110111,%11000000,%00111111,%00000011,%01000110,%11100000
3993 .db %00100000,%10000011,%00010001,%00110010,%00011000,%00010011,%01101010,%11000000,%00111011,%01001101,%10000110,%01000000,%11000000,%00000000,%10000001,%00010000
3994 .db %00100000,%00000000,%00001110,%00110010,%00011001,%10011011,%01101010,%11100000,%00110011,%01101101,%11000111,%10000001,%00011100,%00000000,%00000000,%00001100
3995 .db %01001100,%00011000,%00000000,%00000100,%00011000,%11011111,%01100010,%11001100,%00110011,%01101101,%10000111,%11000001,%00011100,%00111000,%00011000,%10000010
3996 .db %01010010,%00100100,%01100000,%00011000,%00011111,%11011011,%11101110,%11111100,%00011111,%01111000,%11110110,%11100000,%11000000,%11000110,%00101001,%10000010
3997 .db %01100001,%11000011,%10011111,%11100000,%00001111,%10001001,%11001100,%01111000,%00001110,%00110000,%01100110,%01100000,%00111111,%00000001,%11000110,%01111100
3999 ;.db %00000000,%00000001,%10000000,%00000000,%00001111,%10000000
4001 txtMenu: .db "Mode",0 ;1st menu item
4007 .dw $2418,$231E,$2824,$1F2A,$1730
4008 txtMenuR: .db "controls",0
4009 txtoMenu: .db "Back",0 ;1st menu item
4016 .dw $2618,$251E,$2524,$222A,$1A30,$1C36
4017 txtpMenu: .db "Resume",0 ;1st menu item
4018 .db "Turn Off",0 ;2nd
4019 .db "Contrast",$CF,5,0 ;...
4022 .dw $3418,$331E,$2F24,$3A2A
4023 txtGame: .db "Singleplayer",0
4024 txtGame1: .db "Peaworm",0
4025 txtGame2: .db "Tron",0
4026 txtGame3: .db "Deathmatch",0
4027 txtGame4: .db "Foodmatch",0
4028 txtGame5: .db "Timematch",0
4029 txtGame6: .db "Race",0
4030 txtGame7: .db "CTF" ;,0
4033 .db txtGame1-txtGame
4034 .db txtGame2-txtGame
4035 .db txtGame3-txtGame
4036 .db txtGame4-txtGame
4037 .db txtGame5-txtGame
4038 .db txtGame6-txtGame
4039 .db txtGame7-txtGame
4041 txtNone: .db "None",0
4042 txtDef: .db "Default",0
4045 txtKeyleft: .db ":left",0
4046 txtKeyright:.db "/right",0
4048 txtLevsel: .db $CF," SELECT LEVELS ",5,0
4049 txtWaiting: .db "Waiting...",0
4050 txtReceive: .db "Receiving..." ;,0
4053 .db 0, 3, 6, 9, 12, 15, 18, 21
4054 .db 24, 27, 30, 33, 36, 39, 42, 45
4055 .db 48, 51, 54, 57, 59, 62, 65, 67
4056 .db 70, 73, 75, 78, 80, 82, 85, 87
4057 .db 89, 91, 94, 96, 98,100,102,103
4058 .db 105,107,108,110,112,113,114,116
4059 .db 117,118,119,120,121,122,123,123
4060 .db 124,125,125,126,126,126,126,126
4063 txtLevel: .db "Level ",0
4064 txtWorms: .db "Worms: 0",0 ;follows txtLevel
4065 txtName: .db "Name",0
4066 txtWinner: .db "Wins " ;follows txtName
4067 txtDied: .db "Died " ;follows txtWinner
4068 txtScore: .db "Score",0 ;follows txtDied
4069 txtLeft: .db " left",0 ;follows txtScore
4070 txthiscore:.db "HiScore:",0
4072 txtReady: .db "Prepare!",0
4076 txtGO: .db 5,5,5,5,5," GAME OVER ",$CF,$CF,$CF,$CF,$CF,0
4080 datalevels: .dw LevelDef, LevelDefM
4081 .dw LevelDefT,LevelDefM
4082 .dw LevelDefM,LevelDefM
4083 .dw LevelDefR,LevelDefC
4084 nrlevels: .db 0,3,1,3,3,3,3,1 ;=defaults
4086 datalevels: .dw 0,0,0,0,0,0,0,0
4087 nrlevels: .dw 0,0,0,0
4090 _datalink = %0000001 ;linkplay
4091 _datafoodl = %0000010 ;left=0 limit
4092 _datasingl = %0000100 ;singleplayer=1 (=hiscore+keep_length+nextlevel)
4093 _datamultpeas = %0001000 ;multiple peas=1
4094 _datatime = %0010000 ;time incs score (timematch)
4095 _datafood = %0100000 ;food present
4096 _datadie = %1000000 ;worm dies on impact
4097 ;reserved %10000000 ;for future use
4099 savestart: ; �game info (see above)
4100 ; | �lives (0=unlimited)
4101 ; | | �nrworms (can be altered by user)
4102 ; | | | �level (reset to 1 at startup)
4103 ; | | | | �speed/delay (-1=def)
4104 ; | | | | | �grow speed (-1=none; 0=continuous)
4105 ; | | | | | | �turn speed (8=def)
4106 ; | | | | | | | �score limit (0=none)
4107 gamesingle = 0 ;used | | | | | | | |
4108 datasingle: .db %1100110,3,1,1,-1,-1, 8, 0 ;Singleplayer (SP; 3 lives)
4110 datapeas: .db %1100100,1,1,1,-1,-1, 8, 0 ;Peaworm (SP; 1 live)
4112 datatron: .db %1010100,1,1,1,-1, 0, 8, 0 ;Tron (SP; 1 live, cont.growth)
4113 gamedeathm = 3 ;used
4114 datadeathm: .db %1000000,3,2,1,-1,49, 8, 0 ;Deathmatch (3 lives, 50 growth)
4116 datafoodm: .db %1100000,0,2,1,-1,-1, 8,10 ;Foodmatch (100 score)
4118 datatimem: .db %1010000,1,2,1,-1, 0, 8, 0 ;Timematch (tron, 100 score)
4120 datarace: .db %0000000,0,2,1,-1,-1, 8,10 ;Race (100 score, no collision)
4122 datactf: .db %1001000,0,4,1,-1,-1, 8,10 ;CTF (100 score)
4124 worm1set: .dw worm1p,worm1p
4125 .db %11110111,1,-01,K_RIGHT,K_LEFT
4126 worm1name: .db "WORMY ",0
4127 worm2set: .dw worm2p,worm2p
4128 .db %11111011,0,-01,K_F2,K_F1
4129 worm2name: .db "VIPER ",0
4130 worm3set: .dw worm3p,worm3p
4131 .db %11111011,1,-01,K_COMMA,K_STO
4132 worm3name: .db "NIBBLER ",0
4133 worm4set: .dw worm4p,worm4p
4134 .db %11111011,0,-01,K_PLUS,K_ENTER
4135 worm4name: .db "JIM ",0
4146 Gametype: .db 0 ;last gamemode
4160 head = 13 ;4B (head=tail)
4161 tail = 15 ;also@next level
4163 reserv = 18 ;loop (race:lap|ctf:pea)
4164 input = 19 ;---currently unused afaik---
4175 defspriteimg: .db %01100000
4182 .db "Internal Levels",0
4185 .db 0,deflevels/256,deflevels&255
4189 ;-----------------------------
4190 ;----------- end -------------
4191 ;-----------------------------