wormy 0.95.1C21
[wormy.git] / wormy.z80
1 ; Title                      : Wormy
2 ; Version                    : 96% (0.96.C21)
3 ; Release Date               : UUHHhhh... soon?!?
4 ; Filename                   : wormy.86p (5kb)
5 ; Author(s)                  : Shiar
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)
13
14 ;-----------------------------
15 ;----------- TO-DO -----------
16 ;-----------------------------
17
18 ; 96% = DONE
19
20 ;     * complete readme
21 ;  1% * misc (pollish, bugs, &&&)
22 ;     * mem at worm #4 (still 12 bytes or so.....)
23 ;     * fix line proc (+large circles)
24 ;   * LINK
25 ;  1% * fix transmit game/level data
26
27 ;100% = bugs fixed + levels done
28
29 ;>110%: sound, startpos
30 ;>120%: coop (DON'T COUNT ON IT)
31
32 ;-----------------------------
33 ;-----------------------------
34 ;-------  W O R M Y  ---------
35 ;-----------------------------
36 ;-----------------------------
37
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
41
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
46
47 #define cal call
48 #define psh push
49 #define dnz djnz
50
51 #include "asm86.h"
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
84
85 ;-----------------------------
86 ;------- data  storage -------
87 ;-----------------------------
88
89 ;--- permanent
90
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?!?
109
110 ;MEM|8---9---A---B---C---D---E---F---|
111 ;   |..[------]||[]|......[-----]|[].|
112 ;   |   SCREEN 2* 13      PRGM   4LV |
113
114 ;--- temporary
115
116 namelength  = $BC00 ;(1)         @menu
117 datalink    = $BC00 ;(8)         @init
118 #ifdef buffer
119 DispBuffer  = $BC00 ;(10x57d)    @game
120 #else
121 DispBuffer  = $FC70
122 #endif
123
124 ;-----------------------------
125 ;------- program start -------
126 ;-----------------------------
127
128  .org %1101011101001000
129
130 start:
131   nop
132   jp  Start
133   ld  bc,42
134  .org $-1   ;3y3 M 1337!
135   .dw WormTxt
136   .dw WormIcon
137 WormTxt:
138   ld  d,a
139   ld  c,a
140   ld  d,d
141   ld  c,l
142   ld  e,c
143   jr  nz,$+100
144   ld  a,c
145   jr  nz,$+$55
146   ld  c,b
147   .dw 16713
148   .db %1010010
149   jr  nz,$+47
150   dec l
151   .db " 96% C21",0
152 WormIcon:
153   .db 8,2
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
162
163 levelhead  = 'w'
164 levelhead2 = 95 ;wormy levels header = "95"
165
166 int_handler:
167   ex  af,af'
168   in  a,($03)
169   bit 3,a
170   jp  z,$0039
171   res 0,a
172   out ($03),a
173   jp  $0039
174 int_end:
175
176 Start:
177   ld  (SpSave),sp
178   cal _runindicoff
179   cal _flushallmenus
180
181   im  1
182   ld  a,$D4
183   ld  h,a
184   ld  l,0 ;ld hl,$D400
185   ld  d,a
186   ld  e,1 ;ld de,$D401
187   ld  b,e
188   ld  c,l ;ld bc,$0100
189   dec a   ;ld a,$D3
190   ld  (hl),a
191   ldir
192   ld  hl,int_handler
193   ld  d,a
194   ld  e,a ;ld de,$D3D3
195   ld  bc,int_end-int_handler
196   ldir
197   inc a   ;ld a,$D4
198   ld  i,a
199   im  2 ;...it *does* work ;)
200
201   cal _RAM_PAGE_7
202   ld  hl,$BFFF ;VAT start
203   ld  ix,templevels
204 searchloop:
205   ld  de,(_PTEMP_END+1) ;VAT end
206   or  a ;nc
207   sbc hl,de ;hl<de?
208   jr  c,searchcomplete
209   add hl,de
210   psh hl
211   ld  a,(hl)
212   cp  $0C ;string
213   jr  z,stringfound
214 searchnext:
215   pop hl
216   dec hl ;5x
217   dec hl
218   dec hl
219   dec hl
220   dec hl
221   ld  b,(hl) ;name size
222   inc b
223 skipname:
224   dec hl
225   dnz skipname
226   jr  searchloop
227
228 stringfound:
229   dec hl
230   ld  e,(hl)
231   dec hl
232   ld  d,(hl)
233   dec hl
234   ld  a,(hl)
235   ex  de,hl ;ld ahl,(hl)
236   cal _AHL_PLUS_2_PG3 ;string id
237   cal _Get_Word_ahl ;ld de,(ahl)
238   ld (ix),a
239   ld  a,levelhead
240   cp  e
241   jr  nz,_searchnext ;not worm
242   ld  a,levelhead2
243   cp  d
244   jr  nz,_searchnext
245   inc ix ;save level's ahl
246   ld a,h
247   ld (ix),a
248   inc ix
249   ld a,l
250   ld (ix),a
251   inc ix
252 _searchnext:
253   cal _RAM_PAGE_7
254   jr searchnext
255
256 loadgametype:
257   psh de
258   cal _Get_Word_ahl ;ld de,(ahl++)
259   psh af
260   ld  a,e ;set new level
261   ld  (bc),a
262   inc bc
263   ld  a,d
264   ld  (bc),a
265   inc bc
266   pop af
267   pop de ;counter
268   dec d ;8x
269   jr  nz,loadgametype
270   ret
271
272 searchcomplete:
273   ld  a,255
274   ld  (ix),a ;end mark
275
276 #ifdef intlevels
277   ld  ix,templevels-6
278 #else
279   ld  ix,templevels-3
280 #endif
281 levelselectmenu:
282   psh ix ;offset
283   ld  a,-2
284   ld  (availevels),a
285   cal _clrWindow
286   ld  hl,$0320
287   ld  (_penCol),hl
288   ld  hl,txtLevsel
289   cal _vputs ;"< SELECT LEVELS >"
290   ld  hl,$FC00+(2*16)
291   ld  b,16*9
292   cal menuinvloop
293   ld  hl,$FC00+(56*16)
294   cal hr
295   ld  hl,$0601 ;x=1
296   ld  (_penCol),hl
297 dispnextlevel:
298   ld  a,(ix+3)
299   ld  b,a
300   inc a ;cp 255
301   jr  z,__levselect
302 displevel:
303   ld  hl,_penCol
304   ld  (hl),$01 ;x=1
305   inc hl
306   ld  a,(hl)
307   add a,6
308   ld  (hl),a ;y+6
309   cp  49 ;bottom of screen
310   jr  nc,_levselect
311   ld  de,3
312   add ix,de
313   ld  hl,availevels
314   inc (hl)
315   ld  a,b ;(ix+0)
316   ld  h,(ix+1)
317   ld  l,(ix+2) ;ahl=(ix)
318   cal _load_ram_ahl ;hl=ahl
319   cal _vputs
320   jr  dispnextlevel
321
322 readylevelfile: ;selected level at ahl
323 ; ld  hl,templevels-3/0
324   ld  a,b
325   add a,3 ;sellev+3 (#0==-3)
326   ld  e,a
327   add a,a ;*2
328   add a,e ;*3
329   ld  e,a
330   ld  d,0 ;de=sellev*3
331   add hl,de
332   ld  a,(hl) ;ade=(hl)
333   inc hl
334   ld  d,(hl)
335   inc hl
336   ld  e,(hl)
337   ex  de,hl ;ahl=ade
338 skiptitle:
339   ld  d,a ;psh ahl
340   psh hl
341   cal _GETB_AHL ;ld a,(ahl)
342   pop hl
343   or  a
344   ld  a,d ;pop ahl
345   psh af
346   cal _INC_PTR_AHL ;ahl++
347   pop af ;cp 0
348   jr  nz,skiptitle ;goto #0-terminator
349   ret
350
351 levup:
352   cal menupos
353   dec b ;up
354   ld  a,b
355   cp  -3
356   jr  nz,levselect
357   inc b ;undo
358   jr  levselect
359 levdown:
360   cal menupos
361   inc b ;down
362   ld  a,b
363   cp  -2
364 availevels =$-1
365   jr  nz,levselect
366   dec b ;back up
367 levselect:
368   cal menupos
369   ld  hl,$3900
370   ld  (_penCol),hl
371   pop hl
372   psh hl
373   cal readylevelfile
374   cal _load_ram_ahl ;hl=ahl
375   ld  de,$FFA0 ;desc.text
376   xor a
377 levdescclearloop:
378   ld (de),a ;empty
379   inc de
380   cp  d ;de>$FFFF (offscreen)
381   jr  nz,levdescclearloop
382   cal _vputs
383   jr  levselectmenu+1
384 __levselect:
385 #ifdef intlevels
386   ld  ix,templevels-6 ;reset 2 1st page
387 #else
388   ld  ix,templevels-3
389 #endif
390 _levselect:
391   ld  b,-2 ;level selected
392   jr  levselect
393 levselectmenu:
394   psh hl
395   psh bc
396   cal ubergetkey
397   pop bc ;GET_KEY destr. b
398   dec a ;cp K_DOWN
399   jr  z,levdown
400   sub K_UP-1
401   jr  z,levup
402   pop hl
403   inc a ;cp K_RIGHT
404   jp  z,levelselectmenu
405   cp  K_ENTER-K_RIGHT
406   jr  z,loadlevel
407   sub K_EXIT-K_RIGHT
408   jp  z,ExitNoStats
409   inc a ;cp K_SECOND
410   jr  nz,levselectmenu
411 ; jr  z,loadlevel
412
413 loadlevel:
414   cal readylevelfile
415   or  a ;levelfile on page 0 (=internal)
416   jr  z,levelloaded
417   cal skiptitle ;skip description
418
419   cal _Get_Word_ahl
420   ld  (leveldataSize),de
421
422   ld  d,8 ;counter
423   ld  bc,datalevels
424   cal loadgametype
425   ld  (hilvlposa),a ;singleplayer levels
426   ld  (hilvlposhl),hl
427   ld  d,4
428   cal loadgametype
429
430   cal _SET_ABS_SRC_ADDR ;levelsstart
431   xor a
432   ld  hl,leveldata
433   cal _SET_ABS_DEST_ADDR ;store in mem.
434   ld  hl,0
435 leveldataSize =$-2
436   cal _MM_LDIR_SET_SIZE
437
438   cal _LOAD_ABS_SRC_ADDR ;->ahl
439   ld  (hiscrposa),a
440   ld  (hiscrposhl),hl
441   cal _RAM_PAGE_1
442
443   ld  hl,leveldata
444   ld  de,defsprsize
445   ldi ;(de),(hl)\inc hl
446   ld  (defsprite),hl
447 levelloaded:
448   cal _RAM_PAGE_1
449
450   res 2,(iy+13) ;appAutoScroll
451   ld  a,r
452   ld  (Seed),a
453
454   ld  hl,datasingle+3
455   ld  b,8
456   ld  de,8
457 setdeflevels:
458   ld  (hl),1 ;def=level#1
459   add hl,de ;next
460   dnz setdeflevels
461
462 ;-----------------------------
463 ;----- build trig tables -----
464 ;-----------------------------
465
466   ld  hl,TrigPrecalc
467   ld  de,SinCosTable
468   psh de
469   ld  bc,65
470   ldir
471   dec hl
472   ld  b,63
473 MirrorSineWave:
474   dec hl
475   ld  a,(hl)
476   ld  (de),a
477   inc de
478   dnz MirrorSineWave
479   pop hl ;SinCosTable
480   ld  b,128+64
481 NegativeSineWave:
482   xor a
483   sub (hl)
484   ld  (de),a
485   inc hl
486   inc de
487   dnz NegativeSineWave
488
489 ;-----------------------------
490 ;---------- menu -------------
491 ;-----------------------------
492
493 DisplayMenu: ;---draw menu---
494   cal linkok
495   cal _clrWindow
496   ld  de,$FC40 ;(0,4)
497   ld  hl,wtPicture
498   ld  bc,16*16
499   ldir
500   ld  hl,$FC00+$010 ;(*,01)
501   cal hr
502   ld  hl,$FC00+$160 ;(*,22)
503   cal hr
504   ld  hl,$FC00+$3E0 ;(*,62)
505   cal hr
506 dispmainmenu:
507   ld  hl,Gametype
508   ld  a,(hl)
509   dec a ;will be inced @changegame
510   and 7
511   ld  (hl),a
512   ld  hl,changegame ;dispmenusets ;mainMenu
513   psh hl ;jump here after ret
514   ld  hl,txtMenu
515   ld  ix,posMenu
516 ;Mode|Level|Limit|Worms|worm #|controls
517 ; jr  dispmenucommon ;cal
518
519 dispmenucommon_:
520   ld  b,36*16/4
521 dispmenucommon:
522   ld  de,$FD80 ;begin pos
523   xor a
524 clroldmenuloop:
525   ld  (de),a
526   inc de
527   ld  (de),a
528   inc de
529   ld  (de),a
530   inc de
531   ld  (de),a
532   inc de
533   dnz clroldmenuloop
534
535   ld  b,(ix)
536 dispmenuloop:
537   ld  d,(ix+1)
538   inc ix
539   ld  e,(ix+1)
540   inc ix
541   ld  (_penCol),de
542   cal _vputs
543   dnz dispmenuloop
544 ; ld  b,0 ;b=menu#
545   ret
546
547 hr: ;draw horizontal line at hl
548   ld  b,16
549 ; jp  menuinvloop ;shorter but not good for pausescreen
550 hrloop:
551   ld  (hl),-1
552   inc hl
553   dnz hrloop
554   ret
555
556 ;--- menu loop ---
557
558 dispoptionmenu:
559   ld  hl,txtoMenu
560   ld  ix,posoMenu
561 ;Back|Lives|Limit|Speed|Rotation|Growth
562   cal dispmenucommon_
563
564 dispomenusets:
565   cal clrold
566
567   ld  hl,$1E3E
568   ld  (_penCol),hl
569   cal loadgamecar
570   psh hl
571   cal cshowA0 ;lives
572
573   ld  hl,$2A3E
574   ld  (_penCol),hl
575   pop hl ;loadgamecar
576   inc hl \ inc hl \ inc hl
577   psh hl
578   ld  a,(hl) ;(Speed)
579   inc a ;1..99
580   jr  nz,dispspeed
581   ld  hl,txtDef
582   cal _vputs
583   jr  dispspeeddone
584 dispspeed:
585   cal cshowA0
586 dispspeeddone:
587
588   ld  hl,$363E
589   ld  (_penCol),hl
590   pop hl ;loadgamecar
591   inc hl
592   psh hl
593   ld  a,(hl) ;(growth)
594   inc a ;-1=None; 0..98->1..99
595   cal cshowA0
596
597   ld  hl,$303E
598   ld  (_penCol),hl
599   pop hl ;loadgamecar
600   inc hl
601   psh hl
602   ld  a,(hl)
603   cp  8
604   jr  nz,dispturn
605   ld  hl,txtDef
606   cal _vputs
607   jr  dispturndone
608 dispturn:
609   cal cshowA0 ;turn speed
610 dispturndone:
611
612   ld  hl,$243E
613   ld  (_penCol),hl
614   pop hl ;loadgamecar
615   inc hl
616   ld  a,(hl) ;(scorelimit)
617   or  a
618   psh af
619   cal cshowA0 ;limit
620   pop af ;a==0?
621   jr  z,optionMenu ;do not display 0 behind 'None'
622   ld  a,'0'
623   cal _vputmap ;x10
624
625 optionMenu:
626   cal menupos
627   cal menucall
628   jr  nz,notoselect
629 oselect:
630   cal menupos
631   ld  a,b
632   or  a ;1st item?
633   jp  z,dispmainmenu ;mainMenu
634   jr  optionMenu
635 notoselect
636   cp  K_EXIT
637   jp  z,dispmainmenu
638   psh af
639   cal menupos
640   cal loadgamecar
641   inc hl
642   pop af
643   sub K_LEFT
644   jr  z,seloleft
645   dec a ;K_RIGHT
646   ld  a,b
647   jr  nz,optionMenu
648
649 seloright:
650   dec a
651   jr  z,changelives
652   dec a
653   jr  z,changelimit
654   dec a
655   jr  z,changespeed
656   dec a
657   jr  z,changeturn
658   dec a
659   jr  z,changegrowth
660
661 seloleft:
662   ld  a,b
663   dec a
664   jr  z,bchangelives
665   dec a
666   jr  z,bchangelimit
667   dec a
668   jr  z,bchangespeed
669   dec a
670   jr  z,bchangeturn
671   dec a
672   jr  z,bchangegrowth
673 _optionMenu:
674   jr  optionMenu
675
676 changelives:
677   cal loadgamecar ;a=(hl)
678   inc a
679   cp  100
680   jr  nc,optionMenu ;>99
681 changedlives:
682   ld  (hl),a
683 _dispomenusets:
684   jp  dispomenusets ;optionMenu
685 bchangelives:
686   cal loadgamecar
687   sub 1 ;dec does not set cf
688   jr  c,optionMenu ;<0
689   jr  changedlives
690
691 changelimit:
692   cal changelimitInit
693   inc a
694   cp  100
695   jr  nc,optionMenu ;>99
696 changedlimit:
697   ld  (hl),a
698   jr  _dispomenusets ;optionMenu
699 bchangelimit:
700   cal changelimitInit
701   sub 1 ;dec does not set cf
702   jr  c,optionMenu ;<0
703   jr  changedlimit
704 changelimitInit:
705   cal loadgamecar
706   ld  de,6
707   add hl,de
708   ld  a,(hl) ;(scorelimit)
709   ret
710
711 changespeed:
712   cal changespeedInit
713   inc a
714   cp  20
715   jr  nc,_optionMenu ;>98
716 changedspeed:
717   dec hl ;(Speed)
718   ld  (hl),a
719   jr  _dispomenusets ;optionMenu
720 bchangespeed:
721   cal changespeedInit
722   dec a
723   cp  -2
724 __optionMenu: ;w/ zf
725   jr  z,_optionMenu ;<-1
726   jr  changedspeed
727 changespeedInit:
728   cal loadgamecar
729   ld  de,3
730   add hl,de
731   ld  a,(hl) ;(Speed)
732   inc hl ;=saves 2 bytes :P
733   ret
734
735 changeturn:
736   cal changespeedInit
737   inc hl ;(turnspeed)
738   ld  a,(hl)
739   inc a
740   cp  26
741   jr  nc,_optionMenu ;>25
742 changedturn:
743   ld  (hl),a
744   jr  _dispomenusets ;optionMenu
745 bchangeturn:
746   cal changespeedInit
747   inc hl
748   ld  a,(hl)
749   dec a
750   cp  3
751   jr  c,_optionMenu ;<3
752   jr  changedturn
753
754 changegrowth:
755   cal changespeedInit
756   ld  a,(hl)
757   inc a
758   cp  99
759   jr  nc,_optionMenu ;>98
760 changedgrowth:
761   ld  (hl),a
762   jr  _dispomenusets ;optionMenu
763 bchangegrowth:
764   cal changespeedInit
765   ld  a,(hl)
766   dec a
767   cp  -2
768   jr  z,__optionMenu ;<-1
769   jr  changedgrowth
770
771 ;---
772
773 mainMenu:
774   cal menupos
775   cal menucall
776   jr  nz,notselect
777 select:   ;2nd/enter
778   cal menupos
779   ld  a,b
780   dec a ;2nd item: level
781   jp  z,dispoptionmenu
782   sub 3 ;5th item: wormname
783   jp  z,changeworms
784   dec a ;6th: controls
785   jp  z,changekeys
786   jp  LetsGetThisPartyOn ;otherwise
787 notselect
788   cp  K_EXIT
789   jp  z,ExitNoStats
790   psh af
791   cal menupos
792   cal loadgamecar
793   inc hl
794   pop af
795   sub K_LEFT
796   jr  z,selleft
797   dec a ;K_RIGHT
798   ld  a,b
799   jr  nz,mainMenu
800
801 selright:
802   or  a
803   jr  z,changegame
804   dec a
805   jr  z,changelevel
806   dec a
807   jr  z,changelink
808   dec a
809   jr  z,changenrworms
810 ; dec a
811 ; jr  z,changecurworm
812
813 changecurworm:
814 ; hl=nrworms
815   ld  a,(curworm)
816   cp  (hl)
817   jr  nc,mainMenu ;may not become >(nrworms)
818   inc a
819 changedcurworm:
820   ld  (curworm),a
821   jr  _dispmenusets ;mainMenu
822
823 selleft:
824   ld  a,b
825   or  a
826   jr  z,bchangegame
827   dec a
828   jr  z,bchangelevel
829   dec a
830   jr  z,bchangelink
831   dec a
832   jr  z,bchangenrworms
833 ; dec a
834 ; jr  z,bchangecurworm
835
836 bchangecurworm:
837   ld  a,(curworm)
838   dec a ;0-3
839   jr  nz,changedcurworm ;save >0
840   jr  mainMenu
841
842 changenrworms:
843   cal change4spOnly
844   ld  a,(hl) ;hl=nrworms
845   inc a
846   cp  5
847   jr  nc,mainMenu ;may not be >4
848 changednrworms:
849   ld  (hl),a
850   jr  _dispmenusets ;mainMenu
851 changenrwormsInit:
852   ld  a,(Gametype)
853   cp  3
854   ld  a,(hl) ;hl=nrworms
855   ret
856 bchangenrworms:
857   cal change4spOnly
858   ld  a,(hl) ;hl=nrworms
859   dec a ;0-3
860   cp  2
861   jr  nc,changednrworms ;save >=2
862 _mainMenu:
863   jr  mainMenu
864
865 change4spOnly:
866   ld  a,(Gametype)
867   cp  3
868   ret nc
869   pop hl ;cal
870   jr  _mainMenu ;don't change for singleplayer
871
872 changelink:
873 bchangelink:
874   cal change4spOnly
875   dec hl ;inced earlier
876   dec hl ;gameCar
877   ld  a,1 ;change LS-bit (=link)
878   xor (hl) ;0=1; 1=0
879   ld  (hl),a
880 _dispmenusets:
881   jr  dispmenusets ;mainMenu
882
883 changegame:
884   ld  a,(Gametype)
885   inc a
886   cal changedgame
887   jr  z,changegame
888   jr  dispmenusets ;mainMenu
889 changedgame:
890   and 7 ;mod 8
891   ld  (Gametype),a
892   cal getnrlevels
893   xor a
894   cp  (hl)
895   ret
896 bchangegame:
897   ld  a,(Gametype)
898   dec a
899   cal changedgame
900   jr  z,bchangegame
901   jr  dispmenusets ;mainMenu
902
903 changelevel:
904   inc hl ;hl=loadgamecar+2
905   psh hl
906   ld  a,(hl) ;(curlevel)
907   cal getnrlevels
908   cp  (hl) ;max level for sel.game
909   pop hl
910   jr  z,_mainMenu
911   inc a
912 changedlevel:
913   ld  (hl),a
914   jr  dispmenusets ;mainMenu
915 bchangelevel:
916   inc hl
917   ld  a,(hl) ;(curlevel)
918   dec a
919   jr  nz,changedlevel
920   jr  _mainMenu
921
922 getnrlevels: ;for current gametype at hl
923   ld  hl,Gametype
924   ld  d,0
925   ld  e,(hl)
926   ld  hl,nrlevels
927   add hl,de
928   ret
929
930 getcustomkey:
931   cal _vputs
932   dec ix
933 waitcustomkey:
934   psh hl
935   cal ubergetkey
936   pop hl
937   or  a
938   jr  z,waitcustomkey
939   cp  K_EXIT
940   ret z
941   cp  K_MORE
942   jr  z,waitcustomkey
943   ld  (ix),a
944   ret
945
946 changekeys:
947   cal getwormname
948   ld  hl,txtKeyleft
949   cal getcustomkey ;left
950   cal getcustomkey ;right
951 ; jr  dispmenusets
952
953 ;---display current settings---
954
955 dispmenusets:
956   cal clrold
957   ld  de,$183E
958   ld  (_penCol),de
959   ld  d,0
960   ld  a,(Gametype)
961   ld  e,a
962   ld  hl,posGame
963   add hl,de ;hl=posGame+(Gametype)
964   ld  a,(hl) ;str.offset
965   ld  e,a ;^d=0^
966   ld  hl,txtGame
967   add hl,de ;txtGameX
968   ld  (CURtxtGame),hl ;save for g/o
969   cal _vputs ;Singleplayer
970
971   ld  hl,$2A3E ;worms
972   ld  (_penCol),hl
973   cal loadgamecar
974   psh hl
975   inc hl
976   ld  a,(hl)
977   add a,'0'
978   cal _vputmap
979
980   ld  hl,$243E
981   ld  (_penCol),hl
982   rr  c ;(gameCar)
983   ld  hl,txtNo
984   jr  nc,displink
985   ld  hl,txtYes
986 displink:
987   cal _vputs
988
989   ld  hl,$1E3E ;level
990   ld  (_penCol),hl
991   pop hl ;loadgamecar
992   psh bc
993   ld  d,0
994   cal hlatlevel
995   ld  a,(Gametype)
996   or  a ;gamesingle
997   jr  nz,displvlname
998   ld  a,(Level)
999   cal cshowA0
1000   jr  lvldisped
1001 displvlname:
1002   cal _vputs
1003 lvldisped:
1004   pop bc
1005
1006   ld  hl,$3032
1007   ld  (_penCol),hl
1008   ld  a,1
1009 curworm =$-1
1010   add a,'0'
1011   cal _vputmap
1012   ld  hl,$303E
1013   ld  (_penCol),hl
1014   cal getwormname
1015   psh ix ;wormNname
1016   pop hl ;ld hl,ix
1017   cal _vputs
1018   ld  hl,$363E ;controls
1019   ld  (_penCol),hl
1020   ld  hl,txtMenuR
1021   cal _vputs
1022   jp  mainMenu
1023
1024 ;--- handle menukeys ---
1025
1026 menucall:
1027   psh bc
1028 menuwaitkey:
1029   cal ubergetkey
1030   or  a
1031   jr  z,menuwaitkey
1032   pop bc ;GET_KEY destr. b
1033   cp  K_UP
1034   cal z,menuup
1035   cp  K_DOWN
1036   cal z,menudown
1037   cp  K_ENTER
1038   ret z
1039   cp  K_SECOND
1040   ret ;z=select
1041
1042 menupos: ;highlight #b
1043   ld  c,b ;psh b
1044   ld  a,b
1045   add a,3
1046   add a,a
1047   add a,a
1048   sub b
1049   add a,a
1050   add a,a
1051   add a,a ;*24
1052   ld  h,$FC/4
1053   ld  l,a
1054   add hl,hl
1055   add hl,hl ;$FD20+item*96
1056   ld  b,16*7
1057 menuinvloop:
1058   ld  a,(hl)
1059   cpl
1060   ld  (hl),a
1061   inc hl
1062   dnz menuinvloop
1063   ld  b,c ;pop b
1064   ret ;a=-1
1065 menudown:
1066   cal menupos
1067   inc b
1068   jr  menuupdown
1069 menuup:
1070   cal menupos
1071   dec b
1072 menuupdown:
1073   ld  a,b
1074   cp  6
1075   jr  nz,menunewchk
1076   xor a ;6=0
1077 menunewchk:
1078   inc b
1079   jr  nz,menunewok
1080   ld  a,5 ;-1=5
1081 menunewok:
1082   ld  b,a
1083   jr  menupos
1084
1085 ;--- change name ---
1086 ; of worm#(curworm)
1087
1088 getwormname: ;of (curworm)
1089   ld  a,(curworm)
1090   add a,a  ;2x
1091   ld  e,a
1092   add a,a  ;4x
1093   add a,a  ;8x
1094   add a,a ;16x
1095   add a,e ;18x
1096   ld  e,a
1097   ld  d,0 ;de=a
1098
1099   ld  ix,worm1name-18
1100   add ix,de
1101   ret
1102
1103 changeworms:
1104   cal getwormname
1105   psh ix
1106   pop hl ;ld hl,ix
1107   psh hl
1108   ld  b,8
1109 emptyname:
1110   ld  (hl),' '
1111   inc hl
1112   dnz emptyname
1113   ld  a,maxnamelength
1114   ld  (namelength),a
1115 enternameloop:
1116   ld  hl,$FF07 ;begin pos
1117   ld  a,6 ;nr of lines
1118   cal clroldcustom
1119   ld  hl,$303E
1120   ld  (_penCol),hl
1121   pop hl
1122   psh hl
1123   ld  (ix),0
1124   cal __vputs
1125   ld  (ix),' '
1126   ld  a,'_'
1127   cal __vputmap
1128 nokeypressed:
1129   cal ubergetkey
1130   or  a
1131   jr  z,nokeypressed
1132
1133   ld  hl,namelength
1134   cp  K_DEL
1135   jr  nz,continue
1136 backspace:
1137   ld  a,(hl)
1138   cp  maxnamelength
1139   jr  nc,nokeypressed
1140   inc (hl)
1141   dec ix
1142   jr  enternameloop
1143 continue:
1144   cp  K_ENTER
1145   jr  z,nameentered
1146   cp  K_EXIT
1147   jr  z,nameentered
1148
1149   dec (hl) ;(namelength)
1150   jr  z,nameentered
1151   ld  hl,chartable
1152   ld  e,a
1153   ld  d,0
1154   add hl,de
1155   ld  a,(hl)
1156   or  a
1157   jr  z,nokeypressed
1158   ld  (ix),a
1159   inc ix
1160   cal releasekeys
1161   jr  enternameloop
1162
1163 chartable:
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
1171
1172 nameentered:
1173   pop ix ;stringbegin
1174   ld  (ix+8),0 ;end mark
1175   jp  DisplayMenu
1176
1177 ;-----------------------------
1178 ;------- procs-n-stuff -------
1179 ;-----------------------------
1180
1181 ubergetkey:
1182   halt ;woo hoo
1183   halt ;save them batteries! yeah!
1184   jp  GET_KEY
1185
1186 clrold:
1187   ld  hl,$FD97 ;begin pos
1188   ld  a,35 ;nr of lines
1189 clroldcustom:
1190   ld  de,7 ;bytes to add
1191 clroldsettings:
1192   ld  c,9 ;bytes to clear
1193 clroldsetsloop:
1194   ld  (hl),d ;=0
1195   inc hl
1196   dec c
1197   jr  nz,clroldsetsloop
1198   add hl,de
1199   dec a
1200   jr  nz,clroldsettings
1201   ret
1202
1203 hlatlevel: ;d must be 0
1204   psh hl ;loadgamecar
1205   ld  a,(Gametype) ;8bytes -> 7bytes
1206   ld  e,a
1207   add a,a ;nc
1208   add a,e
1209   add a,a ;8->2bytes
1210   add a,24+1 ;go to datalevels
1211   ld  e,a ;=de
1212   sbc hl,de ;datalevels
1213   cal _ldHLind ;ld hl,(hl)
1214   pop de ;de=loadgamecar
1215   inc de \ inc de
1216   ld  a,(de) ;(curlevel)
1217   ld  (Level),a
1218   ld  d,a ;begin level
1219 skiplevelloop:
1220   dec d ;levels to skip
1221   ret z
1222   cal skiplevel
1223   jr  skiplevelloop
1224   ret ;hl=begin of correct level
1225
1226 skiplvltitle: ;zf=singleplayer
1227   ld  a,(hl)
1228   or  a ;null-terminator
1229   inc hl
1230   jr  nz,skiplvltitle
1231   ret
1232
1233 skiplevel: ;@hl - destr:ab - alter:hl
1234   ld  a,(Gametype)
1235   or  a ;gamesingle
1236   psh af
1237   cal nz,skiplvltitle
1238   inc hl
1239   inc hl
1240   inc hl
1241   inc hl ;skip 4
1242   ld  b,(hl) ;spritesize
1243   inc b
1244 skipsprite:
1245   inc hl
1246   dnz skipsprite
1247   ld  b,(hl) ;balls
1248   inc b
1249   inc b ;skip 6
1250   pop af ;cp (Gametype),0
1251   jr  z,skipworms
1252   inc b ;multiplayer lvl
1253   inc b
1254   inc b ;skip other 3 worms (9 bytes)
1255 skipworms:
1256   ld  a,b
1257   add a,a
1258   add a,b
1259   ld  b,a ;3x(balls+2)
1260 skipballs:
1261   inc hl
1262   dnz skipballs
1263
1264 skipflags:
1265   ld  a,(Gametype)
1266   cp  gamerace
1267   jr  z,skiplaps
1268   cp  gamectf
1269   jr  nz,noflagstoskip
1270   inc hl
1271   inc hl
1272 skiplaps:
1273   inc hl
1274   inc hl
1275 noflagstoskip:
1276
1277 skipobjects:
1278   xor a
1279   or  (hl)
1280   inc hl ;nf
1281   ret z ;0=end
1282   inc hl
1283   inc hl
1284   inc hl
1285   inc hl
1286   jr  skipobjects
1287
1288 loadgamecar:
1289 ;in:    (Gametype)
1290 ;out:   hl=dataTYPE
1291 ;build: c=(gameCar)=(hl-1)
1292 ;       a=(wormbeglives)=(hl)
1293 ;destr: acdehl
1294   ld  hl,datasingle
1295   ld  a,(Gametype)
1296   add a,a
1297   add a,a
1298   add a,a ;8 bytes per mode
1299   ld  e,a
1300   ld  d,0
1301   add hl,de
1302   ld  a,(hl)
1303   ld  (gameCar),a
1304   ld  c,a
1305   inc hl
1306   ld  a,(hl)
1307   ld  (wormbeglives),a
1308   ret
1309
1310 ;-----------------------------
1311 ;-------- start game ---------
1312 ;-----------------------------
1313
1314 LetsGetThisPartyOn:
1315   ld  a,$17 ;no exit
1316   ld  (CheckExit),a ;set exit state
1317
1318 setupworms:
1319   ld  hl,worm1set
1320   ld  de,worm1
1321   ld  a,4 ;4x (all worms)
1322 createwormsloop:
1323   ex  de,hl
1324   ld  bc,died ;0008
1325   add hl,bc
1326 ; ld  b,0
1327   ld  (hl),b ;died=0
1328   inc hl
1329   ld  (hl),b ;score=0
1330   inc hl
1331   ld  (hl),b ;score+1=0
1332   inc hl
1333   ld  (hl),2 ;delay=2
1334   inc hl
1335   ld  (hl),3 ;lives=x
1336 wormbeglives =$-1
1337   inc hl
1338   ex  de,hl  ;de=wormX+head
1339   ld  bc,18
1340   ldir       ;copy 18 bytes
1341   dec a      ;loop
1342   jr  nz,createwormsloop
1343
1344 OhMyGodItsALabel:       ;pj34r my coding skillz
1345   cal loadgamecar
1346   psh hl ;datatype
1347   cal hlatlevel
1348   ex  (sp),hl ;pop \ psh leveldata
1349   psh hl ;psh loadgamecar
1350   ld  a,0
1351 gameCar =$-1
1352   rra ;and _datalink
1353   jp  nc,StartLevel ;&&&jr
1354
1355 ;--------- link ------------
1356
1357 wormVhost   = 095
1358 wormVclient = 195
1359
1360 linkmatch:
1361   cal _clrWindow
1362   ld  c,wormVhost
1363   cal Qsend
1364   ld  hl,txtWaiting
1365   cal _puts
1366   cal Crecv
1367   ld  a,c
1368   cp  wormVclient
1369   jr  z,client
1370   cp  wormVhost
1371   jr  z,host
1372   pop hl ;error
1373   jp  DisplayMenu ;return to menu
1374
1375 host:
1376   ld  c,wormVclient
1377   cal Qsend
1378   jr  sethost
1379 client:
1380   ld  hl,txtReceive
1381   cal _puts
1382 setclient:
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)
1387   ld  de,worm2+left
1388   ld  hl,worm1+left
1389   ldi ;keys worm#2 = worm#1
1390   ldi ;+right
1391   ld  de,worm4+left
1392   ldi ;keys worm#4 = worm#2
1393   ldi
1394   xor a
1395   ld  (worm1+left),a ;worm 1...
1396   ld  (worm3+left),a ;and worm 3 via link
1397   ld  hl,worm1+name
1398   ld  b,9
1399   cal recvstuff
1400   ld  hl,worm2+name
1401   ld  b,9
1402   cal sendstuff
1403   pop hl ;loadgamecar
1404   pop de ;leveldata
1405   psh de
1406   psh hl ;loadgamecar
1407   ld  b,8
1408   cal sendstuff
1409   ld  hl,gameCar
1410   ld  b,1
1411   cal sendstuff
1412   ld  hl,Gametype
1413   ld  b,1
1414   cal sendstuff
1415   ex  de,hl
1416   ld  b,168
1417   cal sendstuff
1418   jr  StartLevel
1419 sendstuff:
1420   psh de
1421 sendstuffloop:
1422   psh bc
1423   ld  c,(hl)
1424   inc hl
1425   cal Qsend
1426   pop bc
1427   dnz sendstuffloop
1428   pop de
1429   ret
1430 recvstuff:
1431   psh de
1432 recvstuffloop:
1433   psh bc
1434   cal Qrecv
1435   ld  (hl),c
1436   inc hl
1437   pop bc
1438   dnz recvstuffloop
1439   pop de
1440   ret
1441 sethost:
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)
1446   ld  de,worm3+left
1447   ld  hl,worm2+left
1448   ldi ;keys worm#3 = worm#2
1449   ldi ;+right
1450   xor a
1451   ld  (worm2+left),a ;worm 2+4..
1452   ld  (worm4+left),a ;..over link
1453   ld  hl,worm1+name
1454   ld  b,9
1455   cal sendstuff
1456   ld  hl,worm2+name
1457   ld  b,9
1458   cal recvstuff
1459   pop hl ;loadgamecar
1460   pop de ;leveldata
1461   ld  hl,templevels ;&&&&&&&
1462   ld  de,datalink
1463   psh de
1464   psh hl ;loadgamecar
1465   ld  b,8
1466   cal recvstuff
1467   ld  hl,gameCar
1468   ld  b,1
1469   cal recvstuff
1470   ld  hl,Gametype
1471   ld  b,1
1472   cal recvstuff
1473   ex  de,hl
1474   ld  b,168
1475   cal recvstuff
1476
1477 ;-------- load level ---------
1478
1479 StartLevel:
1480   pop hl ;loadgamecar
1481   ld  a,(hl)
1482   ld  (wormbeglives),a
1483   inc hl ;nrworms
1484   ld  a,(hl)
1485   ld  (nrworms),a
1486   inc hl ;level
1487   inc hl
1488   ld  a,(hl)
1489   ld  (customspeed),a
1490   inc hl
1491   ld  a,(hl)
1492   ld  (growspeed),a
1493   inc hl
1494   ld  a,(hl)
1495   ld  (turnleft),a
1496   ld  (turnright),a ;more efficient
1497   inc hl
1498   ld  l,(hl)
1499   ld  h,0
1500   cal _HLTIMES10 ;hl=10*(hl)
1501   ld  (scorelimit),hl
1502
1503 Nextlevel:
1504   cal _clrWindow
1505   pop hl ;begin of current level
1506   ld  a,(hl)
1507   inc a ;=255?
1508   jp  nz,donextlevel
1509
1510   psh hl
1511   ld  hl,Level
1512   dec (hl) ;curlevel-- (not beyond last lvl)
1513   cal releasekeys
1514   pop hl
1515 ;show end msg or smtn
1516   ld  bc,Exit
1517   psh bc   ;where to go afterwards
1518   inc hl   ;location of ending-code
1519   jp  (hl) ;go there ("call")
1520 donextlevel:
1521   ld  a,(Gametype)
1522   or  a ;gamesingle
1523   psh af
1524   cal nz,skiplvltitle
1525   ld  de,Left
1526   ldi
1527   ld  de,Speed
1528   ld  a,0
1529 customspeed =$-1
1530   inc a ;$FF=def
1531   jr  nz,setspeed
1532   ld  a,(hl) ;speed from level
1533   inc a
1534 setspeed:
1535   dec a
1536   ld  (de),a ;custom speed
1537   inc hl
1538   ld  de,peagrowth
1539   ldi
1540   ld  a,(hl)
1541   ld  (worm1+grow),a
1542   ld  (worm2+grow),a
1543   ld  (worm3+grow),a
1544   ld  (worm4+grow),a
1545   ld  (beginsize),a
1546   inc hl
1547
1548   ld  a,(hl)
1549   inc hl
1550   or  a
1551   jr  z,defaultsprite
1552   ld  d,h
1553   ld  e,l ;ld de,hl
1554   ld  c,a
1555   ld  b,0 ;bc=sprite size
1556   add hl,bc ;hl=behind sprite
1557   jr  setsprite
1558 defaultsprite:
1559   ld  a,defspritesz
1560 defsprsize =$-1
1561 defsprite  =$+1
1562   ld  de,defspriteimg
1563 setsprite: ;de=@sprite ;a=sprsize
1564   ld  (sprsize),a
1565   ld  (spritepos),de
1566
1567   ld  a,(hl)
1568   inc hl
1569   ld  (nrballs),a
1570   or  a
1571   jr  z,toobad_noballs
1572   ld  c,a
1573   add a,a
1574   add a,c
1575   ld  c,a
1576   ld  b,0
1577   ld  de,balls
1578   ldir
1579 toobad_noballs:
1580
1581   ex  de,hl
1582 #ifndef invincible
1583   ld  (thislevel),de
1584 #endif
1585
1586   ld  hl,worm1
1587   pop af ;cp (Gametype),0
1588   ld  b,1
1589   jr  z,worminit
1590   ld  b,4
1591 worminit:
1592   psh bc ;>1
1593   ex  de,hl
1594   ldi        ;d
1595   ld  a,SinCosTable/256
1596   ld  (de),a
1597   inc de
1598   ldi        ;y
1599   ldi        ;x
1600   ex  de,hl
1601   xor a
1602   ld  (hl),a ;y2
1603   inc hl
1604   ld  (hl),a ;x2
1605   inc hl
1606   inc hl
1607   ld  (hl),a ;growH=0
1608
1609   ld  bc,(worm2-worm1)-7
1610   add hl,bc
1611   pop bc ;<0
1612   dnz worminit
1613
1614   inc a ;ld a,1
1615   ld  (turn10),a
1616   inc a ;ld a,2
1617   ld  (flashtime),a
1618
1619 ;-------- draw level ---------
1620
1621 initlevel:
1622   ld  a,(de)
1623   inc de
1624   sub 128
1625   jr  nc,setfieldx
1626   xor a ;fieldx<128
1627 setfieldx:
1628   ld  (FieldWidth),a
1629   ld  a,(de)
1630   inc de
1631   ld  l,a
1632   sub 57
1633   jr  nc,setfieldy
1634   xor a ;fieldy<57
1635 setfieldy:
1636   ld  (FieldHeight),a
1637   psh de                        ; >> levelp
1638   ld  a,l ;pop
1639   sub 5
1640   ld  l,a
1641   ld  h,0
1642   add hl,hl
1643   add hl,hl
1644   add hl,hl
1645   add hl,hl
1646   add hl,hl ;32=scr.width
1647   ex  de,hl
1648
1649   ld  hl,ScrBuffer
1650   psh hl                        ; >> 1
1651   psh de                        ; >> 2
1652   ld  de,ScrBuffer+1
1653   ld  bc,63 ;first 2 rows
1654   ld  (hl),%11111111
1655   ldir ;draw upper border
1656   inc hl
1657   ld  (hl),%11000000 ;first left border
1658   inc hl
1659   ld  b,31
1660 ClearLine:
1661   ld  (hl),c ;=0
1662   inc hl ;clear rest of line
1663   dnz ClearLine
1664   psh hl                        ; >> 3
1665
1666   ld  a,(FieldWidth)
1667   add a,126
1668   psh af                        ; >> 4
1669   and %11111000
1670   rra
1671   rra
1672   rra
1673   ld  l,a
1674   ld  h,c ;0
1675   add hl,de
1676   pop af                         ; << 3
1677   and %00000111
1678   ld  b,a
1679 ; ld  c,0
1680   ld  a,%11000000
1681   jr  z,NoVertShift
1682 VertShift:
1683   rra
1684   rr  c
1685   dnz VertShift
1686 NoVertShift:
1687   ld  (hl),a
1688   inc hl
1689   ld  (hl),c
1690
1691   ex  de,hl
1692   pop de                         ; << 2
1693   pop bc                         ; << 1
1694   ldir
1695   pop hl                         ; << 0k
1696   ld  c,64
1697   ldir
1698
1699
1700   pop hl                         ; << levelp
1701   ld  a,(Gametype)
1702   cp  gamerace ;or gamectf
1703   jr  c,levelhasbeensetup
1704   ld  de,peaspos
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:
1709   ldir
1710   ld  a,1 ;draw delay
1711   ld  (drawctfpea1),a
1712   ld  (drawctfpea2),a
1713 levelhasbeensetup:
1714
1715   cal drawstuff
1716
1717 ;--------- prepare -----------
1718
1719 leveldone:
1720   psh hl                        ; >> levelp new
1721   cal forceshowstats
1722
1723 #ifdef readymask
1724   ld  hl,$FC70
1725   ld  d,%10101010
1726   ld  c,56
1727 maskloop:
1728   ld  a,d
1729   xor %11111111
1730   ld  d,a
1731   ld  b,$10
1732 maskline:
1733   ld  a,(hl)
1734   or  d
1735   ld  (hl),a
1736   inc hl
1737   dnz maskline
1738   dec c
1739   jr  nz,maskloop
1740 #endif
1741 #ifdef readytext
1742   ld  hl,$FDE0
1743   ld  de,$FDE1
1744   ld  (hl),%11111111
1745   ld  bc,$BF
1746   ldir
1747   ld  hl,4+(txtposReady*256)
1748   ld  (_curRow),hl
1749   set 3,(iy+5)
1750   ld  hl,txtReady
1751   cal _puts
1752   res 3,(iy+5)
1753 #endif
1754
1755   ld  a,(gameCar)
1756   and _datafood
1757   jr  z,nofood
1758   ld  ix,worm1
1759   cal NewPea
1760 nofood:
1761   ld  bc,(worm1+pos)
1762   cal DisplayField
1763
1764   ld  b,startdelay
1765 ReadyDelay:
1766   halt
1767   dnz ReadyDelay
1768   cal releasekeys
1769
1770 ;-----------------------------
1771 ;----------- LOOP ------------
1772 ;-----------------------------
1773
1774 GameLoop:
1775   ld  bc,(worm1+pos) ;camera worm #1
1776   ld  a,(worm1+left)
1777   or  a ;if #1 not over link
1778   jr  nz,showfield
1779   ld  bc,(worm2+pos) ;otherwise view from #2
1780 showfield:
1781   cal DisplayField ;display piece of level
1782
1783   ld  a,1
1784 flashtime =$-1
1785   dec a
1786   jr  z,noflash
1787   ld  (flashtime),a
1788   ld  hl,$fc00+(16*7)
1789 screeninvertloop:
1790   ld  a,(hl)
1791   cpl
1792   ld  (hl),a
1793   inc hl
1794   xor a
1795   cp  h ;end at >$FFFF
1796   jr  nz,screeninvertloop
1797 noflash:
1798
1799   ld  a,0
1800 Speed =$-1
1801   or  a
1802   jr  z,NoDelay
1803 Delay:
1804   halt
1805   dec a
1806   jr  nz,Delay
1807 NoDelay:
1808
1809   ld  (handledworm),a ;reset
1810
1811   ld  hl,turn
1812   ld  a,(hl)
1813   inc a ;-1
1814   jr  z,nextturnok
1815   dec (hl)
1816   dec a ;0 (now <0)
1817   jr  nz,nextturnok
1818 growspeed =$+1
1819   ld  (hl),$FF
1820 nextturnok:
1821
1822   ld  a,(gameCar)
1823   and _datatime
1824   jr  z,nodispupdate
1825   ld  hl,turn10
1826   dec (hl)
1827   jr  nz,nodispupdate ;just once every 10 turns
1828   ld  (hl),10 ;reset counter
1829   cal forceshowstats ;update score
1830 nodispupdate:
1831
1832   ld  a,(Gametype)
1833   cp  gamectf
1834   jr  nz,noctfpeas2draw
1835   ld  de,drawctfpea1
1836   ld  hl,(peaspos)
1837   cal tryDrawPea ;pea#1
1838   ld  de,drawctfpea2
1839   ld  hl,(peaspos+2)
1840   cal tryDrawPea ;pea#2
1841 noctfpeas2draw:
1842
1843
1844   ld  a,0
1845 nrballs =$-1
1846   or  a
1847   cal nz,handlethoseneatlittleballs
1848
1849   ld  ix,worm1
1850   ld  a,1
1851 nrworms =$-1
1852   ld  b,a
1853 handleworms:
1854   psh bc
1855   cal HandleWorm
1856   ld  bc,worm2-worm1
1857   add ix,bc
1858   pop bc
1859   ld  hl,handledworm
1860   inc (hl) ;0..nrworms-1
1861   dnz handleworms
1862
1863 ;-----------------------------
1864 ;---------- keys -------------
1865 ;-----------------------------
1866
1867 HandleKeys:
1868   ld  a,%10111111
1869   out (1),a
1870   in  a,(1)
1871   rla ;MORE?
1872   jr  nc,disppausemenu
1873 CheckExit:
1874   rla  ;=$17 (c=EXIT-key)
1875       ;or$A7 (c=0)
1876   jp  c,GameLoop
1877   jp  Exit ;jr?
1878
1879 ;------- pause menu -------
1880
1881 disppausemenu:
1882   ld  hl,txtpMenu
1883   ld  ix,pospMenu
1884 ;Resume|Turn Off|Contrast|Exit||
1885   ld  b,25*16/4
1886   cal dispmenucommon
1887   ld  hl,$FC00+$170 ;(*,23)
1888   cal hr
1889   ld  hl,$FC00+$310 ;(*,49)
1890   cal hr
1891   cal menupos
1892
1893 pauseMenu:
1894   psh bc
1895 pmenuwaitkey:
1896   cal ubergetkey
1897   or  a
1898   jr  z,pmenuwaitkey
1899   pop bc ;GET_KEY
1900   ld  d,b ;c=new b
1901   cp  K_UP
1902   jr  nz,pmenunotup
1903   dec d
1904 pmenunotup:
1905   cp  K_DOWN
1906   jr  nz,pmenunotdown
1907   inc d
1908 pmenunotdown:
1909   psh af
1910   cal menupos
1911   ld  a,d ;new pos
1912   and 3 ;0-3
1913   ld  b,a
1914   cal menupos
1915   pop af
1916   cp  K_ENTER
1917   jr  z,pselect
1918   cp  K_SECOND
1919   jr  nz,notpselect
1920 pselect:
1921   ld  a,b
1922   or  a ;1: continue
1923   jr  z,donepausing
1924   dec a ;2: off
1925   jr  z,turnoff
1926   dec a ;3: contrast
1927   jr  z,pauseMenu
1928   jr  Exit ;4: exit
1929 notpselect
1930   cp  K_EXIT
1931   jr  z,donepausing
1932   ld  hl,CONTRAST
1933   sub K_LEFT
1934   jr  z,contrastdown
1935   dec a ;K_RIGHT
1936   jr  nz,pauseMenu
1937 contrastup:
1938   inc (hl)
1939   jr  setcontrast
1940 contrastdown:
1941   dec (hl)
1942 setcontrast:
1943   ld  a,(hl)
1944   out (2),a
1945   jr  pauseMenu
1946
1947 turnoff:
1948   ld  bc,$0103
1949   out (c),b
1950   halt ;pause/off
1951   ld  b,11
1952   out (c),b
1953   ld  b,1
1954   jr  pauseMenu
1955
1956 donepausing:
1957   cal releasekeys
1958   jp  GameLoop
1959
1960 Exit:
1961   cal releasekeys
1962   ld  sp,0 ;pop all
1963 SpSave = $-2
1964   ld  a,D0LD1L
1965   out (7),a     ;both wires low = game over signal
1966   cal _clrWindow
1967 #ifdef coolzgfx
1968   ld  de,$FC30 ;(0,1)
1969   ld  hl,wtWormy
1970   ld  bc,16*7
1971   ldir
1972   ld  hl,$FC10
1973   ld  b,16*11
1974   cal menuinvloop ;invert
1975   ld  hl,$FD80
1976   cal hr ;menuinvloop w/ b=16
1977   ld  hl,$FCE0
1978   cal hr
1979   ld  hl,_curRow
1980   ld  (hl),2
1981 #else
1982   ld  hl,txtGO
1983   cal _puts
1984   ld  hl,$FC00
1985   ld  b,16*8
1986   cal menuinvloop ;invert
1987   inc h ;$FD80
1988   cal hr ;menuinvloop w/ b=16
1989   ld  hl,$FCE0
1990   cal hr
1991   ld  hl,_curRow
1992   inc (hl)
1993 #endif
1994   ld  hl,txtGame
1995 CURtxtGame =$-2
1996   cal _puts
1997   ld  a,$0D ;$0D02
1998   ld  (_curCol),a
1999   cal showLevel
2000
2001   ld  de,$1901
2002   ld  (_penCol),de
2003   ld  hl,txtName
2004   cal _vputs ;Name
2005   ld  a,$3D
2006   ld  (_penCol),a
2007   cal _vputs ;Died    Score
2008   ld  de,$0004
2009   ld  (_curRow),de
2010
2011 findwinner:
2012   ld  hl,(worm1+score)
2013   ld  (winnerscore),hl
2014   ld  b,3 ;(nrworms)-1
2015   ld  hl,worm2+score
2016 findwinnerloop:
2017   psh hl
2018   cal _ldHLind
2019   ld  de,(winnerscore)
2020   ld  a,h
2021   cp  d
2022   jr  c,nonewwinner ;h<d
2023   jr  nz,newwinner  ;h>d
2024   ld  a,e
2025   cp  l
2026   jr  nc,nonewwinner ;l<e
2027 newwinner:
2028   ld  (winnerscore),hl
2029 nonewwinner:
2030   pop hl
2031   ld  de,worm2-worm1
2032   add hl,de
2033   dnz findwinnerloop
2034
2035   ld  a,(nrworms)
2036   ld  b,a
2037   cpl ;high value (>$FB)
2038   ld  hl,worm1+died
2039 finddmwinner:
2040   cp  (hl)
2041   jr  c,nonewdmwinner
2042   ld  a,(hl) ;less deaths
2043 nonewdmwinner:
2044   ld  de,worm2-worm1
2045   add hl,de
2046   dnz finddmwinner
2047   ld  (dmwinner),a
2048
2049 ;---display worms---
2050
2051   ld  a,(nrworms)
2052   ld  b,a
2053   ld  hl,worm1+died
2054 displayWormStats:
2055   psh bc
2056
2057   psh hl
2058   ld  bc,left-died
2059   add hl,bc ;+left
2060   xor a
2061   cp  (hl)  ;input=0 = link
2062   jr  nz,NoLinkIndic
2063   ld  a,9
2064   ld  (_curCol),a
2065   ld  a,$DC ;-O
2066   cal _putc
2067   xor a
2068   ld  (_curCol),a
2069 NoLinkIndic:
2070   inc hl
2071   inc hl ;+name
2072   cal _puts
2073   pop hl
2074
2075   psh hl
2076   ld  a,13
2077   ld  (_curCol),a
2078   ld  a,(hl) ;worm+died
2079   cal showA0
2080   pop hl
2081
2082   psh hl
2083   ld  a,(Gametype)
2084   cp  gamedeathm
2085   jr  nz,nodmwinner ;deathmatch?
2086   ld  a,0 ;winner's deaths
2087 dmwinner =$-1
2088   cp  (hl) ;equals this worm?
2089   scf ;jr nz,notwinner
2090   cal z,iswinner
2091 nodmwinner:
2092   jr  c,notwinner ;no singleplayer winners
2093   inc hl ;worm+score
2094   cal _ldHLind ;ld hl,(hl)
2095   ld  de,0
2096 winnerscore =$-2
2097   cal _cphlde ;==highest score..
2098   cal z,iswinner
2099 notwinner:
2100   ld  a,16
2101   ld  (_curCol),a
2102   pop hl
2103   psh hl
2104   inc hl ;worm+score
2105   cal _ldHLind
2106   cal showHL
2107   pop hl
2108
2109   ld  bc,worm2-worm1
2110   add hl,bc
2111   pop bc
2112   dnz displayWormStats
2113
2114   ld  a,(Gametype)
2115   or  a ;singleplayer (0) only
2116   jr  nz,hilevelcheckdone
2117 checkhilevel:
2118   ld  hl,nrlevels
2119   ld  a,(Level)
2120   cp  (hl)
2121   jr  c,hilevelcheckdone
2122   ld  (hl),a ;save local
2123   ld  c,a
2124   ld  a,0
2125 hilvlposa =$-1
2126   ld  hl,nrlevels
2127 hilvlposhl =$-2 ;save external
2128   cal _writeb_inc_ahl ;ld (ahl),c
2129 hilevelcheckdone:
2130
2131   ld  a,(gameCar)
2132   and _datasingl
2133   jr  z,hiscorecheckdone ;no SP
2134 checkhiscore:
2135   cal loadhiscoreposinahl
2136   cal _SET_ABS_SRC_ADDR ;from ahl (lvlfile)
2137   xor a
2138   ld  hl,highsave
2139   cal _SET_ABS_DEST_ADDR ;to local
2140   ld  hl,5 ;5 bytes
2141   cal _MM_LDIR_SET_SIZE ;get old score+name
2142   cal _RAM_PAGE_1
2143
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
2149 newhigh:            ;New>Old
2150   ld  (highsave),hl ;store new hiscore
2151   ld  de,highsave+2 ;to
2152   ld  hl,worm1+name ;from
2153   ld  bc,3 ;3 chars
2154   ldir ;store new hiname
2155   cal loadhiscoreposinahl
2156   cal _SET_ABS_DEST_ADDR ;to ahl
2157   xor a
2158   ld hl,highsave
2159   cal _SET_ABS_SRC_ADDR ;from local
2160   ld  hl,5
2161   cal _MM_LDIR_SET_SIZE ;save new
2162   cal _RAM_PAGE_1
2163   ld  hl,_curRow
2164   dec (hl)
2165   cal iswinner
2166
2167 NotNewHigh:
2168   ld  hl,$3149
2169   ld  (_penCol),hl
2170   ld  hl,txthiscore
2171   cal _vputs
2172   ld  hl,$0C07
2173   ld  (_curRow),hl
2174   ld  hl,highsave+2
2175   cal _puts
2176   ld  hl,(highsave)
2177   cal showHL
2178 hiscorecheckdone:
2179
2180 waitkey:
2181   cal ubergetkey
2182   cp  K_ENTER
2183   jp  z,DisplayMenu
2184   cp  K_SECOND
2185   jp  z,DisplayMenu
2186   cp  K_EXIT
2187   jr  nz,waitkey
2188
2189 ;x123456789012345678901
2190 ;>>>>>> GAME OVER <<<<<
2191 ;2Multiplayer
2192 ;3Level 01
2193 ;4           Died Score:
2194 ;5NameName     03 00070
2195 ;6Worm#02 @    05 00120
2196 ;7Worm#03      15 00030
2197 ;8Snaky   @    00 04820
2198
2199 ExitNoStats:
2200   cal linkok
2201   ld  hl,_asapvar
2202   rst 20h ;_ABS_MOV10TOOP1
2203   rst 10h ;_FINDSYM
2204   ld  hl,savestart-_asm_exec_ram+4
2205   xor a
2206   add hl,de
2207   adc a,b ;ahl=bde+4
2208   cal _SET_ABS_DEST_ADDR
2209
2210   xor a
2211   ld  hl,savestart
2212   cal _SET_ABS_SRC_ADDR
2213   ld  hl,saveend-savestart
2214   cal _MM_LDIR_SET_SIZE
2215
2216   cal releasekeys
2217   res 4,(iy+9)
2218   set 2,(iy+13)
2219   im  1 ;remove keyfix
2220   jp  _clrWindow
2221
2222 loadhiscoreposinahl:
2223   ld  hl,0 ;for peaworm and singleplayer
2224   ld  a,(Gametype)
2225   or  a ;Singleplayer?
2226   jr  z,hi__
2227   dec a ;peaworm?
2228   jr  z,hi_
2229   ld  a,(nrlevels+1) ;skip peaworm slots if tron mode
2230 hi_:
2231   ld  bc,(Level)
2232   add a,c
2233   ld  b,a ;levels to skip (including 1 for singleplayer)
2234   ld  de,5 ;to add per level
2235 addlevelposition:
2236   add hl,de ;one word+3 bytes for name
2237   dnz addlevelposition
2238 hi__:
2239   xor a ;ahl=0(+hl)
2240   ld  bc,defhiscrpos
2241 hiscrposhl =$-2
2242   add hl,bc
2243 hiscrposa =$+1
2244   adc a,0 ;ahl=saveloc
2245   ret
2246 highsave:
2247   .db 0,0,"WOR ",0
2248
2249 iswinner:
2250   ld  a,10
2251   ld  (_curCol),a
2252   ld  a,'*'
2253   jp  _putc ;..then put *
2254
2255 ;-----------------------------
2256 ;----------- worm ------------
2257 ;-----------------------------
2258
2259 respawncheck:
2260   cp  respawndelay-1
2261   jr  nz,unnamedlabel
2262   cal saverespawncounter
2263 removeworm:
2264   ld  h,(ix+tail+1) ;&
2265   ld  l,(ix+tail)
2266   ld  d,(ix+head+1)
2267   ld  e,(ix+head)
2268   jr  DoesWormTailEqualsWormHead ;chk4 size=0
2269 removewormloop:
2270   ld  c,(hl)
2271   inc hl
2272   ld  b,(hl)
2273   inc hl
2274   cal resbit
2275   psh hl
2276   cal res4pixels
2277   pop hl
2278   inc (ix+grow)
2279   jr  nz,DoesWormTailEqualsWormHead
2280   inc (ix+grow+1) ;+256
2281 DoesWormTailEqualsWormHead:
2282   cal _cphlde
2283   jr  nz,removewormloop
2284
2285   ld  a,(gameCar)
2286   and _datasingl
2287   jr  nz,safewormsizedone
2288   ld  a,0
2289 beginsize =$-1
2290   ld  (ix+grow),a
2291   ld  (ix+grow+1),0 ;high
2292 safewormsizedone:
2293
2294   ;de=ix+head
2295   ld  (ix+tail+1),d
2296   ld  (ix+tail),e ;head=tail/size=0
2297   ret
2298
2299 unnamedlabel:
2300   cp  1
2301   ld  h,a
2302   jr  nz,saverespawncounter
2303 respawndue:
2304   ld  l,a
2305   cal inputcall
2306   ld  a,h ;previous
2307   cp  l   ;changed?
2308   ret z
2309   ld  (ix+delay),a ;=0
2310   ret
2311 saverespawncounter:
2312   ld  (ix+delay),a
2313   jr  inputcall
2314
2315 chkkey: ;key=a
2316   dec a
2317   ld  b,a
2318   srl b
2319   srl b
2320   srl b ;b=a/8
2321   and 7 ;a=a\8
2322   ld  c,a ;push keybit
2323   ld  a,-1
2324   out (1),a
2325   inc b
2326   ld  a,%01111111 ;default
2327 bitmask:
2328   rlca ;rotate left
2329   dnz bitmask ;a/8 times
2330   out (1),a ;send bitmask
2331   in  a,(1) ;input keys
2332   ld  b,c ;pop keybit
2333   inc b
2334 keybit:
2335   rra
2336   dnz keybit ;check match (cf set)
2337   ret
2338
2339 inkeys: ;use jp not call!
2340   cal chkkey
2341   jr  nc,notright
2342   ld  a,l
2343   add a,8
2344 turnright =$-1
2345   ld  l,a
2346 notright:
2347   ld  a,(ix+right)
2348   cal chkkey
2349   ret nc
2350   ld  a,l
2351   sub 8
2352 turnleft =$-1
2353   ld  l,a
2354   ret
2355 inputcall:
2356   ld  a,(ix+left)
2357   or  a
2358   jr  z,inlink ;input by link
2359   cal inkeys ;input by keys
2360   ld  a,(gameCar)
2361   rra ;and _datalink
2362   ret nc ;no link
2363   ld  c,l ;send our keys
2364   jp  Qsend
2365 inlink:
2366   cal Qrecv ;Crecv
2367   ld  l,c
2368   ret
2369
2370 ;-----------------------------
2371 ;------- handle worm ---------
2372 ;-----------------------------
2373
2374 HandleWorm:
2375   xor a
2376   cp  (ix+lives)
2377   jr  nz,alive
2378   ld  a,(wormbeglives)
2379   or  a
2380   ret nz ;live limit
2381 alive:
2382   ld  a,(ix+delay)
2383   dec a
2384   jp  nz,respawncheck
2385
2386   xor a
2387   cp  0
2388 turn =$-1
2389   jr  nz,nogrow
2390   inc (ix+grow)
2391 nogrow:
2392
2393   ld  a,(gameCar)
2394   and _datatime
2395   jr  z,notimescore
2396   ld  e,1
2397   cal IncScore
2398 notimescore:
2399
2400   ld  l,(ix+heading)
2401   cal inputcall
2402 donediddelydone:
2403   ld  (ix+heading),l
2404   ld  h,(ix+heading+1)
2405
2406   ld  c,(ix+pos)
2407   ld  b,(ix+pos+1)
2408   ld  e,(ix+pos2)
2409   ld  d,(ix+pos2+1)
2410
2411 #ifdef optdie
2412   psh hl
2413   ld  hl,previouspos
2414   ld  (hl),c
2415   inc hl
2416   ld  (hl),b
2417   inc hl
2418   inc hl
2419   ld  (hl),e
2420   inc hl
2421   ld  (hl),d
2422   pop hl
2423 #endif
2424
2425 ;-------- move worm ----------
2426
2427 Wormmove:
2428   psh bc                        ; >> pos
2429   ld  a,(hl)
2430   add a,a
2431   add a,d
2432   ld  d,a
2433   bit 7,(hl)
2434   jr  z,notnegX
2435   dec b
2436 notnegX:
2437   jr  nc,notmoveX
2438   inc b
2439 notmoveX:
2440   ld  a,l
2441   add a,$40
2442   ld  l,a
2443   ld  a,(hl)
2444   add a,a
2445   add a,e
2446   ld  e,a
2447   bit 7,(hl)
2448   jr  z,notnegY
2449   dec c
2450 notnegY:
2451   jr  nc,notmoveY
2452   inc c
2453 notmoveY: ;bc=newpos
2454   ld  (ix+pos2),e
2455   ld  (ix+pos2+1),d
2456   ld  (ix+pos),c
2457   ld  (ix+pos+1),b
2458
2459 ;-check-
2460   pop hl                         ; << pos (old)
2461   ld  a,h
2462   sub b
2463   and 1
2464   ld  h,a
2465   ld  a,l
2466   sub c
2467   and 1
2468   add a,h
2469   ld  d,4
2470   jr  z,GotFour
2471   xor 3
2472   ld  d,a
2473 GotFour:
2474   cal chk4pixels
2475   rl  d
2476   jp  nc,Drawworm
2477
2478 ;--------- worm hit ----------
2479
2480 Hitworm:
2481   ld  a,(gameCar)
2482   ld  h,a
2483 #ifdef optdie
2484   and _datadie
2485   cal z,checkhitotherworm
2486   ld  a,h
2487 #endif
2488   and _datamultpeas ;&&bit
2489   jr  nz,chkctfpeas
2490   ld  a,h
2491   and _datafood
2492   jp  z,WormDead ;no food
2493
2494   ld  hl,0
2495 PeaY =$-2
2496 PeaX =$-1
2497   cal chkpeahit
2498   jp  nc,WormDead
2499   cal DrawPea ;remove pea
2500   ld  a,(ix+grow)
2501   add a,15
2502 peagrowth =$-1
2503   ld  (ix+grow),a
2504   jr  nc,wormset2grow
2505   inc (ix+grow+1)
2506 wormset2grow:
2507   cal NewPea
2508   ld  hl,Left
2509   dec (hl)
2510   psh af
2511   ld  e,10
2512   cal IncScore
2513   pop af
2514   jp  nz,Drawworm ;continue
2515   ld  a,(gameCar)
2516   and _datafoodl
2517   jp  z,Drawworm
2518   ld  a,(Gametype)
2519   or  a
2520   jp  nz,Exit ;stack restored
2521
2522   ld  hl,Level
2523   ld  a,(hl)
2524   inc (hl)
2525   ld  l,a ;hl=Level
2526   ld  h,0
2527   add hl,hl
2528   add hl,hl
2529   cal _HLTIMES10
2530   ex  de,hl
2531   cal _IncScore ;score+(40*level)
2532   cal removeworm
2533   pop hl                         ; << call
2534   pop hl                         ; << call
2535   ld  (ix+delay),2
2536   jp  Nextlevel
2537
2538 chkpeahit: ;bc=ownpos;hl=peapos (destr:ad)
2539   ld  a,(sprsize)
2540   inc a
2541   ld  d,a
2542   ld  a,b
2543   sub h
2544   inc a
2545   cp  d ;=(sprsize)+1
2546   ret nc ;nc=no pea
2547   ld  a,c
2548   sub l
2549   inc a
2550   cp  d
2551   ret ;c=pea
2552
2553 chkctfpeas:
2554   ld  hl,(peaspos) ;1st pea
2555   ld  a,(ix+reserv)
2556   ld  e,a ;push a
2557   and %01 ;ourpea (0|1)
2558   jr  z,sel_otherpea
2559   ld  hl,(peaspos+2) ;2nd pea ;&&&ex de,hl?
2560 sel_otherpea:
2561   cal chkpeahit
2562   jr  c,hitflag
2563 ;no peas hit:
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
2567   xor %11 ;drop flag
2568   ld  (ix+reserv),a
2569   psh af
2570   cal WormDead
2571   pop af ;which flag? (=and %1)
2572   ld  hl,drawctfpea1 ;restore #1
2573   jr  z,nottheotherflag
2574   ld  hl,drawctfpea2 ;restore #2
2575 nottheotherflag:
2576   ld  (hl),3 ;draw delay 3 turns
2577   ret
2578
2579 drawctfpea1: .db 0
2580 drawctfpea2: .db 0
2581
2582 hitflag: ;correct pea hit
2583   ld  a,e ;pop a
2584   xor %11 ;invert flag taken + ownflag
2585   ld  (ix+reserv),a
2586   and %10 ;just returned?
2587   psh af ;safe z-flag
2588   cal DrawPea ;remove
2589   pop af
2590   jr  nz,Drawworm ;flag taken, continue game
2591   psh hl
2592   ld  e,20 ;flag captured+returned
2593   cal IncScore
2594   pop hl
2595   ld  a,3 ;draw delay
2596   ld  (drawctfpea1),a ;redraw..
2597   ld  (drawctfpea2),a ;..both flags
2598   jr  Drawworm
2599
2600 ;-----------------------------
2601
2602 nextotherwormbit:
2603   ld  a,c
2604   sub (hl)
2605   inc hl
2606   inc a
2607   cp  4
2608   jr  nc,nothit1 ;no
2609   ld  a,b
2610   sub (hl)
2611   inc a
2612   cp  4
2613   ret c ;nz ;yes
2614 nothit1:
2615   inc hl
2616   cal resbit
2617 ChkWorm:
2618   cal _cphlde
2619   jr  nz,nextotherwormbit
2620   ret ;z
2621
2622 checkhitlapline:
2623   ld  a,(peaspos) ;63
2624   sub b ;x==63
2625   jr  z,nextlaphalf
2626   inc a
2627   ret nz
2628 nextlaphalf:
2629   ld  a,(peaspos+1) ;yline
2630   cp  c ;ypos
2631   ld  a,1
2632   jr  nc,checklap ;y>yline -> a=1
2633   xor a ;y<yline -> a=0
2634 checklap:
2635   cp  (ix+reserv)
2636   ret z ;same as before
2637   ld  (ix+reserv),a ;1st time
2638   ld  e,a
2639   ld  a,(handledworm)
2640   and 1 ;group 0 (1,3) or 1 (2,4)
2641   xor e
2642   ret z ;(group 0 and y<yline) or (group 1 and y>yline)
2643   psh bc
2644   ld  e,20
2645   cal IncScore ;lap!
2646   pop bc
2647   ret
2648
2649 ;-------- draw worm ----------
2650
2651 Drawworm:
2652   ld  c,(ix+pos)
2653   ld  b,(ix+pos+1)
2654
2655   ld  a,(Gametype)
2656   cp  gamerace
2657   cal z,checkhitlapline
2658
2659   cal set4pixels
2660   dec c
2661   ld  a,(growspeed)
2662   or  a ;0=tron
2663   ret z ;keep tail in "Tron"
2664
2665   ld  l,(ix+head)
2666   ld  h,(ix+head+1)
2667   ld  (hl),c
2668   inc hl
2669   ld  (hl),b
2670   inc hl
2671   cal resbit
2672   ld  (ix+head),l
2673   ld  (ix+head+1),h
2674
2675   ld  l,(ix+grow)
2676   ld  h,(ix+grow+1)
2677   dec hl
2678   ld  a,h
2679   or  l
2680   jr  z,removetail
2681   ld  (ix+grow),l
2682   ld  (ix+grow+1),h
2683   ret
2684
2685 removetail:
2686   ld  l,(ix+tail)
2687   ld  h,(ix+tail+1)
2688   ld  c,(hl)
2689   inc hl
2690   ld  b,(hl)
2691   inc hl
2692   cal resbit
2693   ld  (ix+tail),l
2694   ld  (ix+tail+1),h
2695   psh hl
2696   cal res4pixels
2697   pop hl
2698   ld  c,(hl)
2699   inc hl
2700   ld  b,(hl)
2701   jr  set4pixels
2702
2703 res4pixels:
2704   cal ResPixel
2705   inc b
2706   cal ResPixel
2707   inc c
2708   cal ResPixel
2709   dec b
2710 ResPixel:
2711   cal FindPixel
2712   cpl
2713   and (hl)
2714   ld  (hl),a
2715   ret
2716
2717 ;-----------------------------
2718 ;---------- ball -------------
2719 ;-----------------------------
2720
2721 handlethoseneatlittleballs:
2722   ld  hl,balls
2723   ld  b,a ;a=(nrballs)
2724 handleballs
2725   psh bc
2726   psh hl
2727   ld  c,(hl)
2728   inc hl
2729   ld  b,(hl)
2730   inc hl
2731   ld  d,(hl)
2732   cal handleball
2733   dec c
2734   pop hl
2735   ld  (hl),c
2736   inc hl
2737   ld  (hl),b
2738   inc hl
2739   ld  (hl),d
2740   inc hl
2741   pop bc
2742   dnz handleballs
2743   ret
2744
2745 handleball:
2746   cal res4pixels
2747   dec c
2748
2749 ballxmove:
2750   bit 0,d ;1=L; 0=R
2751   jr  z,ballright
2752 ballleft:
2753   dec b
2754   cal checkballhit
2755   jr  z,ballymove
2756   inc b ;undo
2757   res 0,d ;go right
2758   jr  ballymove
2759 ballright:
2760   inc b
2761   cal checkballhit
2762   jr  z,ballymove
2763   dec b ;back
2764   set 0,d ;>left
2765
2766 ballymove:
2767   bit 1,d ;1=up; 0=down
2768   jr  z,balldown
2769 ballup:
2770   dec c
2771   cal checkballhit
2772   jr  z,balldone
2773   inc c
2774   res 1,d ;go down
2775   jr  balldone
2776 balldown:
2777   inc c
2778   cal checkballhit
2779   jr  z,balldone
2780   dec c
2781   set 1,d ;up
2782 balldone:
2783
2784 set4pixels: ;@(b,c)
2785   cal SetPixel
2786   inc b
2787   cal SetPixel
2788   inc c
2789   cal SetPixel
2790   dec b
2791 SetPixel: ;at bc
2792   cal FindPixel
2793   or  (hl)
2794   ld  (hl),a
2795   ret
2796
2797 letsmovetheotherway:
2798   ld  a,1
2799   xor (hl)
2800   ld  (hl),a
2801   ret
2802
2803 checkballhit:
2804   psh de
2805   ld  d,0
2806   cal chk4pixels
2807   xor a
2808   cp  d
2809   pop de
2810   ret
2811
2812 ;-----------------------------
2813 ;----------- procs -----------
2814 ;-----------------------------
2815
2816 releasekeys:
2817   halt
2818   ld  a,%10000000    ;all key-masks
2819   out (1),a
2820   in  a,(1)
2821   inc a              ;cp %11111111 (no keys pressed)
2822   jr  nz,releasekeys ;keep waitin
2823   cal GET_KEY        ;clear buffer
2824   ret
2825
2826 resbit:
2827   ld  a,h
2828   and (ix+storepos)
2829   ld  h,a
2830   ret
2831
2832 randompos:
2833   ld  b,a
2834 Random: ;(2..b+2)
2835   ld  a,r
2836 Seed =$+1
2837   add a,0
2838   ld  (Seed),a
2839   and %01111110
2840   cp  b
2841   jr  nc,Random
2842   add a,2
2843   ret
2844
2845 WormDead:
2846 #ifdef invincible
2847   jp  stopworm
2848 #endif
2849   ld  a,2
2850   ld  (flashtime),a
2851   ld  (ix+delay),respawndelay
2852
2853 thislevel =$+1
2854   ld  hl,0
2855   ld  de,0
2856 handledworm =$-2
2857   add hl,de
2858   add hl,de
2859   add hl,de
2860   ld  a,(hl)
2861   inc hl
2862   ld  (ix+heading),a
2863   ld  a,(hl)
2864   ld  (ix+pos),a ;y
2865   inc hl
2866   ld  a,(hl)
2867   ld  (ix+pos+1),a ;x
2868   xor a
2869   ld  (ix+pos2),a ;y2
2870   ld  (ix+pos2+1),a ;x2
2871
2872   inc (ix+died)
2873   dec (ix+lives)
2874   psh af
2875   ld  de,10
2876   ld  a,(Gametype)
2877   cp  gamectf ;ctf no death penalty
2878   cal nz,DecScore
2879   pop af
2880   ret nz ;HandleWorm done
2881   ld  a,(wormbeglives)
2882   or  a ;0=no live limit
2883   ret z ;don't end game
2884   ld  a,(gameCar)
2885   and _datatime
2886   jr  z,anyworm ;quit at any worm's death
2887   ld  a,(nrworms) ;timematch: all worms must've died
2888   ld  b,a ;# of worms
2889   ld  hl,worm1+lives-(worm2-worm1)
2890   ld  de,worm2-worm1
2891   xor a ;check for 0 lives
2892 checklives:
2893   add hl,de ;next worm
2894   cp  (hl) ;lives==0?
2895   ret nz ;any >0: don't exit
2896   dnz checklives
2897 anyworm:
2898   ld  a,$A7 ;exit@end of turn
2899   ld  (CheckExit),a ;set exit state
2900   ret ;finish turn
2901
2902 #ifdef optdie
2903 checkhitotherworm:
2904  .db  $dd,$7d ;ld a,lx
2905   cp  worm2&255
2906  psh ix
2907  jr nz,chkworm2 ; ret nz
2908   ld  ix,worm1
2909  jr chkworm
2910 chkworm2:
2911  ld ix,worm2
2912
2913 chkworm:
2914  ld h,(ix+tail+1)
2915  ld l,(ix+tail)
2916  ld e,(ix+head)
2917  ld d,(ix+head+1)
2918   cal ChkWorm
2919  pop ix
2920   ret z ;not hit
2921   pop bc ;call
2922
2923 stopworm:
2924   ld  bc,0
2925 previouspos =$-2
2926   ld  de,0
2927   ld  (ix+pos),c
2928   ld  (ix+pos+1),b
2929   ld  (ix+pos2),e
2930   ld  (ix+pos2+1),d
2931   ret
2932 #endif
2933
2934 CheckPea: ;@hl; destr:abcde
2935   ld  c,l
2936   ld  a,(sprsize)
2937   ld  e,a
2938 chkloopy:
2939   ld  b,h
2940   ld  a,(sprsize)
2941   ld  d,a
2942 chkloopx:
2943   psh hl
2944   cal FindPixel
2945   and (hl)
2946   pop hl
2947   ret nz ;nz=pixel found
2948   inc b
2949   dec d
2950   jr  nz,chkloopx
2951   inc c
2952   dec e
2953   jr  nz,chkloopy
2954   ret ;z=empty space
2955
2956 tryDrawPea: ;hl=peapos;bc=dopea
2957   ld  a,(de)
2958   or  a ;0=drawn
2959   ret z
2960   psh de
2961   cal CheckPea
2962   pop de
2963   ret nz ;unsuccesful
2964   ex  de,hl
2965   dec (hl) ;hl=appeartime
2966   ex  de,hl ;hl=peaspos
2967   jr  z,DrawPea
2968   ret
2969
2970 NewPea:
2971   ld  a,(FieldWidth)
2972   add a,127-4
2973   cal randompos
2974   ld  h,a
2975   ld  a,(FieldHeight)
2976   add a,56-4
2977   cal randompos
2978   ld  l,a
2979   cal CheckPea
2980   jr  nz,NewPea
2981   cal sendnewpeaoverlink
2982   ld  (PeaY),hl
2983 DrawPea: ;hl=(PeaY)
2984   ld  b,h
2985   ld  c,l
2986   ld  de,0
2987 spritepos =$-2
2988 ; jp PutSprite
2989
2990 PutSprite:  ;||@(b,c)
2991   ;by SHIAR  only ix saved
2992   cal FindPixel
2993   ld  (beginbit),a
2994   ld  a,0
2995 sprsize =$-1
2996   ld  b,a ;rows
2997 sprloopy:
2998   psh bc ;rows
2999   psh hl
3000   ld  a,(de)
3001   ld  c,a
3002   inc de
3003   ld  a,(sprsize)
3004   ld  b,a ;width
3005 beginbit =$+1
3006   ld  a,1
3007 sprloopx:
3008   sla c ;draw?
3009   jr  nc,sprnodraw
3010   psh af
3011   xor (hl)
3012   ld  (hl),a
3013   pop af
3014 sprnodraw:
3015   rrca ;next bit
3016   jp  nc,nextbitok
3017   inc hl ;next byte
3018 nextbitok:
3019   dnz sprloopx
3020
3021   pop hl
3022   ld  bc,32 ;next line
3023   add hl,bc
3024   pop bc
3025   dnz sprloopy
3026   ret
3027
3028 ;----------- score -----------
3029
3030 timematchscore:
3031   ;piece of crap checking whether you've already won in timematch
3032   ld  a,(nrworms)
3033   ld  b,a ;# of worms
3034   dec a
3035   ret z ;singleplayer
3036   ld  hl,worm1+lives
3037   ld  de,worm2-worm1
3038   ld  a,(handledworm)
3039   ld  c,a ;wormcounter
3040 chktimematchover:
3041   xor a
3042   cp  c
3043   jr  z,nneexxtt ;yourself
3044   cp  (hl)
3045   ret nz ;someone else still alive
3046   dec hl ;+del0ay
3047   dec hl ;+score+1
3048   ld  a,(hl)
3049   cp  (ix+score+1)
3050   jr  c,nneexxtt_ ;you>him
3051   ret nz ;not highest
3052   dec hl ;+score
3053   ld  a,(hl)
3054   cp  (ix+score)
3055   ret nc ;you<=him
3056   inc hl
3057 nneexxtt_:
3058   inc hl
3059   inc hl
3060 nneexxtt:
3061   dec c
3062   add hl,de
3063   dnz chktimematchover
3064   jp  anyworm ;g/o
3065
3066 _divHLby1000:
3067   psh hl
3068   ld  b,3
3069 divideagain: ;3x
3070   cal _divHLby10
3071   dnz divideagain
3072   ld  a,l ;a=hl/1000
3073   pop hl
3074   ret
3075
3076 extralives:
3077   cal _divHLby1000
3078   ld  c,a
3079   add hl,de ;increase score
3080   cal _divHLby1000
3081   cp  c
3082   jr  z,scorecommon ;hl/1000 not increased
3083   inc (ix+lives)
3084   jr  scorecommon
3085
3086 DecScore: ;&&&
3087   ld  h,(ix+score+1)
3088   ld  l,(ix+score)
3089   or  a
3090   sbc hl,de
3091   jr  c,showstats ;<0=0
3092   jr  scorecommon
3093
3094 IncScore: ;inc score by e
3095   ld  d,0
3096 _IncScore ; inc by de
3097   ld  h,(ix+score+1)
3098   ld  l,(ix+score)
3099   ld  a,(Gametype)
3100   or  a ;if singleplayer...
3101   jr  z,extralives
3102   add hl,de ;score+=de
3103 scorecommon:
3104   ld  (ix+score+1),h
3105   ld  (ix+score),l ;save
3106   ld  de,0
3107 scorelimit =$-2
3108   ld  a,d
3109   or  e
3110   jr  z,showstats ;de=0=no limit
3111   cal _cphlde
3112   jp  nc,Exit
3113
3114 showstats:
3115   ld  a,(gameCar)
3116   and _datatime
3117   jr  nz,timematchscore ;no disp for timematches
3118   ld  hl,$FC00 ;&&&only necessary in deathmatch
3119   ld  b,6*16-1 
3120 clearstats:
3121   ld  (hl),a ;=0
3122   inc hl
3123   dnz clearstats
3124 forceshowstats:
3125   psh ix
3126   ld  h,0
3127   ld  l,h
3128   ld  (_penCol),hl
3129   ld  a,(nrworms)
3130   ld  b,a
3131   ld  ix,worm1
3132   ld  a,(gameCar)
3133   and _datasingl
3134   jr  nz,showstatsS
3135 showstatloop:
3136   psh bc
3137 #ifdef longnames
3138   ld  b,3
3139   psh ix
3140 shownameloop: ;1st 3 chars
3141   ld  a,(ix+name)
3142   or  a
3143   jr  z,nameshown
3144   cal __vputmap
3145   inc ix
3146   dnz shownameloop
3147 nameshown:
3148   ld  a,':'
3149   cal _vputmap
3150   pop ix
3151 #else
3152   ld  a,(ix+name)
3153   cal __vputmap
3154   ld  a,':'
3155   cal __vputmap
3156 #endif
3157   cal showstat
3158   ld  de,worm2-worm1
3159   add ix,de ;next
3160   ld  hl,_penCol
3161   ld  a,(hl)
3162   add a,4 ;div
3163   ld  (hl),a
3164   pop bc
3165   dnz showstatloop
3166   pop ix
3167   ret
3168
3169 showstat: ;(multiplayer)
3170   ld  a,(Gametype)
3171   cp  gamedeathm
3172   jr  z,showlives
3173 showscore:
3174   ld  h,(ix+score+1)
3175   ld  l,(ix+score)
3176   cal _D_HL_DECI
3177   jr  __vputs
3178 showlives:
3179   ld  a,(ix+lives)
3180 showA: ;small w/o leading 0 (&&&combine w/ cshowA0??)
3181   cp  10
3182   jr  c,showleastsign
3183   ld  l,a
3184   ld  h,0
3185   cal _divHLby10
3186   psh af
3187   ld  a,l
3188   add a,'0'
3189   cal __vputmap
3190   pop af
3191 showleastsign:
3192   add a,'0'
3193 __vputmap:
3194   psh ix
3195   cal _vputmap
3196   pop ix
3197   ret
3198
3199 showstatsS: ;(singleplayer)
3200   ld  hl,txtLevel
3201   cal __vputs
3202   ld  a,0
3203 Level =$-1
3204   cal showA
3205
3206   ld  a,98
3207   ld  (_penCol),a
3208   cal showscore
3209   ld  a,123
3210   ld  (_penCol),a
3211   cal showlives
3212   ld  a,(gameCar)
3213   and _datafoodl
3214   pop ix
3215   ret z
3216 showleft:
3217   ld  a,31
3218   ld  (_penCol),a
3219   ld  a,0
3220 Left =$-1
3221   cal cshowA0
3222
3223   ld  hl,txtLeft
3224 __vputs:
3225   psh ix
3226   cal _vputs
3227   pop ix
3228   ret
3229
3230 showLevel:
3231   ld  hl,txtLevel
3232   cal _puts
3233   ld  a,(Level)
3234 showA0: ;big w/ leading 0
3235   ld  l,a
3236   ld  h,0
3237   cal _divHLby10
3238   psh af
3239   ld  a,l
3240   add a,'0'
3241   cal _putc
3242   pop af
3243   add a,'0'
3244   jp  _putc
3245
3246 cshowA0: ;small w/ leading 0
3247   or  a
3248   jr  nz,cshowavalue
3249   ld  hl,txtNone
3250   jp  _vputs
3251 cshowavalue:
3252   ld  l,a
3253   ld  h,0
3254   cal _divHLby10
3255   psh af
3256   ld  a,l
3257   add a,'0'
3258   cal __vputmap
3259   pop af
3260   add a,'0'
3261   jp  __vputmap
3262
3263 showHL:
3264   cal _D_HL_DECI
3265   jp  _puts
3266
3267 _D_HL_DECI:
3268   ld  de,savestr+4
3269   ld  b,5
3270 ldhld:
3271   cal _divHLby10
3272   add a,'0'
3273   ld  (de),a
3274   dec de
3275   dnz ldhld
3276   ld  hl,savestr
3277   ret
3278 savestr:
3279   .db "00000",0
3280
3281 ;-----------------------------
3282
3283 DisplayField:
3284   ld  a,c
3285   sub 29
3286   jr  nc,NotMinYScroll
3287   xor a
3288 NotMinYScroll:
3289   cp  43
3290 FieldHeight =$-1
3291   jr  c,NotMaxYScroll
3292   ld  a,(FieldHeight)
3293 NotMaxYScroll:
3294   ld  l,a
3295   ld  h,0
3296   add hl,hl
3297   add hl,hl
3298   add hl,hl
3299   add hl,hl
3300   add hl,hl
3301   psh bc                        ; >> 1
3302   psh de                        ; >> 2
3303   ld  de,ScrBuffer
3304   add hl,de
3305   ld  a,b
3306   sub 64
3307   jr  nc,NotMinXScroll
3308   xor a
3309 NotMinXScroll:
3310   cp  128
3311 FieldWidth = $-1
3312   jr  c,NotMaxXScroll
3313   ld  a,(FieldWidth)
3314 NotMaxXScroll:
3315   psh af                        ; >> 3
3316   and %11111000
3317   rra
3318   rra
3319   rra
3320   ld  c,a
3321   ld  b,0
3322   ld  de,DispBuffer
3323   pop af                         ; << 2
3324   and %00000111
3325   psh af                        ; >> 3
3326   cp  6
3327   jr  c,CopyScreen
3328   inc c
3329 CopyScreen:
3330   add hl,bc
3331   ld  b,57
3332 CopyScreenLoop:
3333   psh bc                        ; >> 4
3334   ld  bc,16
3335   ldir
3336   ld  c,16
3337   add hl,bc
3338   pop bc                         ; << 3
3339   dnz CopyScreenLoop
3340   pop af                         ; << 2
3341   ld  c,$b7 ;or a
3342 Bit0:
3343   jr  nz,Bit1
3344   halt
3345   halt
3346   jr  AfterShiftDelay
3347 Bit1:
3348   dec a
3349   jr  nz,Bit2
3350   cal ShiftRight1
3351   jr  AfterShiftDelay
3352 Bit2:
3353   dec a
3354   jr  nz,Bit3
3355   ld  a,2
3356   cal ShiftRight
3357   jr  AfterShiftDelay
3358 Bit3:
3359   dec a
3360   jr  nz,Bit4
3361   cal Chunk
3362   cal ShiftLeft1
3363   jr  AfterShift
3364 Bit4:
3365   dec a
3366   jr  nz,Bit5
3367   cal Chunk
3368   jr  AfterShiftDelay
3369 Bit5:
3370   dec a
3371   jr  nz,Bit6
3372   cal Chunk
3373   cal ShiftRight1
3374   jr  AfterShift
3375 Bit6:
3376   dec a
3377   jr  nz,Bit7
3378   ld  a,2
3379   cal ShiftLeft
3380   jr  AfterShift
3381 Bit7:
3382   cal ShiftLeft
3383 AfterShiftDelay:
3384   halt
3385 AfterShift:
3386 #ifdef buffer
3387   ld  hl,DispBuffer
3388   ld  de,$fc00+$70
3389   ld  bc,1024-$70
3390   ldir
3391 #endif
3392   pop de                         ; << 1
3393   pop bc                         ; << 0k
3394   ret
3395
3396 ShiftRight1:
3397   ld  a,1
3398 ShiftRight:
3399   ld  (ShiftRightCounter),a
3400   ld  a,c
3401   ld  (ShiftRightChunk),a
3402   ld  c,16
3403   add hl,bc
3404   ld  b,57
3405 ShiftRightLoop:
3406   psh bc
3407   ld  bc,-32
3408   add hl,bc
3409   ex  de,hl
3410   ld  a,(de)
3411 ShiftRightChunk:
3412   or  a
3413   cal c,_SHLACC
3414   ld  c,0
3415 ShiftRightCounter = $-1
3416 ShiftRowsLeft:
3417   psh hl
3418   rla
3419   ld  b,16
3420 ShiftRowLeft:
3421   dec hl
3422   rl  (hl)
3423   dnz ShiftRowLeft
3424   pop hl
3425   dec c
3426   jr  nz,ShiftRowsLeft
3427   ld  bc,-16
3428   add hl,bc
3429   ex  de,hl
3430   pop bc
3431   dnz ShiftRightLoop
3432   ret
3433
3434 ShiftLeft1:
3435   ld  a,1
3436 ShiftLeft:
3437   ld  (ShiftLeftCounter),a
3438   ld  a,c
3439   ld  (ShiftLeftChunk),a
3440   rla
3441   jr  nc,ShiftLeftSameByte
3442   dec hl
3443 ShiftLeftSameByte:
3444   ex  de,hl
3445   ld  bc,-16
3446   add hl,bc
3447 NewSprite:
3448   ex  de,hl
3449   ld  b,57
3450 ShiftLeftLoop:
3451   psh bc                        ; >> 1
3452   ld  bc,-32
3453   add hl,bc
3454   ex  de,hl
3455   ld  a,(de)
3456 ShiftLeftChunk:
3457   or  a
3458   cal c,_SHRACC
3459   ld  c,0
3460 ShiftLeftCounter = $-1
3461 ShiftRowsRight:
3462   psh hl                        ; >> 2
3463   rra
3464   ld  b,16
3465 ShiftRowRight:
3466   rr  (hl)
3467   inc hl
3468   dnz ShiftRowRight
3469   pop hl                         ; << 1
3470   dec c
3471   jr  nz,ShiftRowsRight
3472   ld  bc,-16
3473   add hl,bc
3474   ex  de,hl
3475   pop bc                         ; << 0k
3476   dnz ShiftLeftLoop
3477   ret
3478
3479 Chunk:
3480   psh hl                        ; >> 1
3481   psh de                        ; >> 2
3482   ld  c,16
3483   add hl,bc
3484   ld  b,57
3485 ChunkScreen:
3486   psh bc                        ; >> 3
3487   ld  bc,-32
3488   add hl,bc
3489   ex  de,hl
3490   ld  a,(de)
3491   cal _SHRACC
3492   ld  b,16
3493 ChunkRow:
3494   dec hl
3495   rld
3496   dnz ChunkRow
3497   ex  de,hl
3498   pop bc                         ; << 2
3499   dnz ChunkScreen
3500   pop de                         ; << 1
3501   pop hl                         ; << 0k
3502   ld  c,$37 ;scf
3503   ret
3504
3505 ;----------- draw ------------
3506
3507 ;--- pixel ---
3508
3509 chk4pixels: ;&&
3510   cal CheckPixel
3511   inc b
3512   cal CheckPixel
3513   inc c
3514   cal CheckPixel
3515   dec b
3516   cal CheckPixel
3517   dec c
3518   ret
3519 CheckPixel: ;at bc in d
3520   cal FindPixel
3521   and (hl)
3522   ret z
3523   dec d
3524   ret
3525
3526 ;CLEM's FIND_PIXEL (131+? cycles; 28+4 bytes)
3527 ;(b,c) to hl:a; "destroyes" ahl
3528
3529 FindPixel: ;(b,c) to hl:a
3530   ld  h,0
3531   ld  l,c    ;hl=y
3532   add hl,hl
3533   add hl,hl
3534   ld  a,b    ;a=x
3535   rra
3536   add hl,hl
3537   rra
3538   add hl,hl
3539   add hl,hl  ;hl=32*y
3540   rra        ;a=x/8
3541   or  l
3542   ld  l,a
3543   ld  a,b
3544   and 7
3545   cpl
3546   rlca
3547   rlca
3548   rlca
3549   ld  (FP_Bit),a
3550   xor a
3551 FP_Bit =$+1
3552   set 0,a
3553
3554   psh de ;&&&
3555   ld  de,ScrBuffer
3556   add hl,de
3557   pop de
3558   ret
3559
3560 ;--- objects ---
3561
3562 drawstuff:
3563   ld  a,(hl)
3564   inc hl
3565   or  a ;0 =
3566   ret z ;no more
3567
3568   ld  d,(hl)
3569   inc hl
3570   ld  e,(hl)
3571   inc hl
3572   ld  b,(hl)
3573   inc hl
3574   psh hl
3575   ld  l,(hl)
3576   ld  h,b
3577   cal drawsmtn
3578   pop hl
3579   inc hl
3580   jr  drawstuff
3581
3582 drawsmtn:
3583   dec a ;1 = line
3584   jr  z,drawline
3585   dec a ;2 = fatline
3586   jr  z,drawfatline
3587   dec a ;3 = box
3588   jr  z,drawbox
3589 ; dec a ;4 = circle
3590 ; jp  z,drawcircle
3591
3592 drawcircle: ;(d,e),h    ;de=x,y; h=z
3593   ld  c,h               ;c=yy=z
3594   ld  a,h
3595   neg
3596   ld  l,a               ;l=-z
3597   xor a
3598   ld  b,a               ;b=xx=0
3599   dec a                 ;-$00**
3600   ld  h,a               ;hl=zz=-z
3601 circloop:
3602   psh de                ;x,y
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)
3608
3609   ex  (sp),hl           ;push x,y \ pop zz
3610   xor a
3611   ld  d,a               ;d=0
3612   dec a                 ;-256<h<0 = $FF**
3613   cp  h                 ;h<0?
3614   jr  z,circlenext      ;jump if zz<0
3615
3616   ld  a,c               ;yy
3617   dec a                 ;89<a<128
3618   add a,a               ;a=2yy-2 ;nc
3619   ld  e,a               ;de=a
3620   sbc hl,de             ;zz=zz-2yy+2
3621   dec c                 ;yy--
3622 circlenext:
3623   ld  a,b               ;xx
3624   inc a                 ;0<a<92
3625   add a,a               ;2xx+2
3626   inc a
3627   ld  e,a               ;de=a
3628   add hl,de             ;zz=zz+2xx+3
3629
3630   pop de                ;x,y
3631   ld  a,b
3632   cp  c
3633   ret nc                ;xx>=yy
3634   inc b                 ;xx++
3635   jr  circloop
3636
3637 circledraw:             ;destr:de
3638   psh hl
3639   ld  a,h               ;hl=x,y
3640   sub b                 ;bc=xx,yy
3641   ld  d,a               ;d=x-xx
3642   add hl,bc             ;h=x+xx; l=y+yy
3643   ld  e,l               ;e=y+yy
3644   cal drawline          ;(h-b,l+c)-(h+b,l+c)
3645   ld  a,l
3646   sub c                 ;a=y again
3647   sub c
3648   ld  l,a               ;l=y-yy
3649   ld  e,l               ;e=l=y-yy
3650   cal drawline          ;(h-b,l-c)-(h+b,l-c)
3651   ld  a,b               ;swap xx and yy
3652   ld  b,c
3653   ld  c,a               ;ex b,c
3654   pop hl
3655   ret
3656
3657 drawbox: ;(d,e)-(h,l)
3658   ld  b,l ;Delta-y
3659   ld  l,e
3660 boxloop:
3661   cal drawline
3662   inc l
3663   inc e
3664   dnz boxloop
3665   ret
3666
3667 drawfatline:
3668   cal drawline
3669   inc d
3670   inc h
3671   cal drawline
3672   inc e
3673   inc l
3674   cal drawline
3675   dec d
3676   dec h
3677 ; jp  drawline
3678
3679 ;LINE (d,e)-(h,l)
3680 ;destroyes a
3681
3682 drawline: ;(d,e)-(h,l)
3683   psh bc  ;destr: a
3684   psh hl
3685   psh de
3686   ld  a,d               ;a=d=x
3687   cp  h                 ;h=xx
3688   jr  c,lineXincs       ;if x>xx
3689   ex  de,hl             ;make x<xx
3690 lineXincs:              ;deltax=|deltax|
3691   ld  b,d
3692   ld  c,e               ;bc=x,y
3693   psh hl                ;hl=xx,yy
3694   cal FindPixel         ;  (ahl=x+y)
3695   ex  (sp),hl           ;       :hl>
3696   ld  c,a               ;c=mask (always)
3697   ld  a,h               ;a=xx
3698   sub b                 ;xx-x
3699   ld  b,a               ;b=deltax (always>0)
3700   ld  a,l               ;a=yy
3701   jr  nz,lineexists     ;deltax!=0
3702   cp  e                 ;yy==y
3703   jr  nz,lineexists     ;deltay!=0
3704   pop hl                ;       :<hl
3705   jr  DoneLine          ;line is 1 pixel
3706 lineexists:
3707   sub e                 ;a=deltay
3708   ld  de,32             ;go down (def)
3709   jr  nc,lineYincs      ;cf = deltay<0
3710   neg                   ;a=|deltay|
3711   ld  de,-32            ;go up
3712 lineYincs:              ;lets assume y incs as well
3713   cp  b         
3714   jr  nc,SteepLine      ;deltay<deltax?
3715   ld  (line2sm+1),a     ;a=deltay
3716   ld  h,a
3717   xor a
3718   sub b
3719   ld  (line1sm+1),a     ;a=-deltax
3720   rra
3721   add a,h               ;a=deltay-deltax/2
3722   pop hl                ;       :<hl
3723
3724 linedrawxloop:
3725   psh af                ;init z=dy-dx
3726   ld  a,(hl)
3727   or  c                 ;|c:hl
3728   ld  (hl),a
3729   rrc c
3730   jr  nc,$+3
3731   inc hl                ;(x++,y)
3732   pop af
3733   jp  m,line2sm         ;z<0
3734 line1sm:
3735   add a,0               ;z-=deltax
3736   add hl,de             ;(x,y++)
3737 line2sm:
3738   add a,0               ;z+=deltay
3739   dnz linedrawxloop     ;|deltax| times
3740
3741 DoneLine:
3742   ld  a,(hl)
3743   or  c                 ;|c:hl
3744   ld  (hl),a            ;draw end
3745   pop de
3746   pop hl
3747   pop bc
3748   ret
3749
3750 SteepLine:
3751   ld  h,a               ;h=deltay
3752   neg                   ;a=-deltay
3753   ld  (line3sm+1),a
3754   ld  a,b
3755   ld  (line4sm+1),a     ;a=deltax
3756   sub h                 ;a=deltax-deltay
3757   ld  b,h               ;b=deltay
3758   pop hl                ;       :<hl
3759 linedrawyloop:
3760   psh af                ;init z=2(dx-dy)
3761   ld  a,(hl)
3762   or  c                 ;|c:hl
3763   ld  (hl),a
3764   add hl,de             ;(x,y++)
3765   pop af
3766   jp  m,line4sm         ;z<0
3767 line3sm:
3768   add a,0               ;z-=deltay
3769   rrc c
3770   jr  nc,$+3
3771   inc hl                ;(x++,y)
3772 line4sm:
3773   add a,0               ;z+=deltax
3774   dnz linedrawyloop     ;|deltay| times
3775   jr  DoneLine
3776
3777
3778 ;--- foo ---
3779 ;wild insert
3780 receivenewpeaoverlink:
3781   cal Qrecv ;Crecv
3782   ld  l,c
3783   cal Qrecv ;Crecv
3784   ld  h,c
3785   ret
3786 sendnewpeaoverlink:
3787   ld  a,(gameCar)
3788   rra ;and _datalink
3789   ret nc ;no link
3790   ld  a,(ix+left)
3791   or  a
3792   jr  z,receivenewpeaoverlink
3793   ld  c,l ;send pea's pos
3794   cal Qsend
3795   ld  c,h
3796 ; jr  Qsend ;that's why it's here
3797
3798 ;..and last but not least..:
3799 ;-----------------------------
3800 ;----------- link ------------
3801 ;-----------------------------
3802
3803 timeout = $8000
3804 lossout = 20
3805
3806 ;---- SEND ----
3807
3808 Qsend:          ;--- try to send 8 bits in C; CF=error --- destr:abcde ---
3809   nop \ nop
3810   cal linkfine
3811   jr  z,linkerr         ;both wires low = exit signal
3812   ld  b,8               ;bits to send
3813 sendloop:
3814   ld  de,timeout
3815   rl  c                 ;bit to send in cf
3816   ld  a,D0LD1H          ;0: lower white
3817   jr  nc,sendbit
3818   ld  a,D0HD1L          ;1: lower red
3819 sendbit:
3820   out (7),a             ;lower one (send bit)
3821 sendwaitack:
3822   cal checklink         ;other calc must lower other wire
3823   jr  nz,sendwaitack
3824   cal linkok            ;raise one, ok to raise other (out (7),D0HD1H)
3825 sendfinish:
3826   cal checklink
3827   cp  %11               ;both raised (by other calc)
3828   jr  nz,sendfinish
3829 ; nop \ nop
3830   dnz sendloop          ;repeat for all bits
3831   xor a                 ;nc...
3832   ld (linklosses),a     ;reset number of losses
3833   ret                   ;=ok
3834
3835 ;---- RECV ----
3836
3837 Crecv:          ;--- receive 8 bits into A/C --- destr:abCde ---
3838   cal Qrecv
3839   ret nc                ;return if all went ok
3840   jr  Crecv             ;and try again
3841
3842 Qrecv:          ;--- receive 8 bits into A/C; CF=error --- destr:abCde ---
3843   cal linkfine
3844   jr  z,linkerr         ;both low = error, quit
3845   ld  b,8               ;bits to receive
3846 recvloop:
3847 ;  ld  de,timeout
3848 recvwait:
3849   cal linktest ;checklink
3850   cp  %11
3851   jr  z,recvwait        ;both high = nothing sent (yet)
3852   ld  de,timeout
3853   rra                   ;received bit in cf
3854   ld  a,D0LD1H
3855   jr  c,received        ;lower white wire as well
3856   ld  a,D0HD1L          ;lower red
3857 received:
3858   rl  c                 ;save bit in c
3859   out (7),a             ;both wires low
3860 recvwaitack:
3861   cal checklink
3862   jr  z,recvwaitack     ;same wire will be raised again by other calc
3863   cal linkok            ;raise both
3864 recvfinish:
3865   dnz recvloop          ;repeat for all bits
3866   xor a                 ;nc=no error
3867   ld (linklosses),a     ;reset number of losses
3868   ret
3869
3870 ;---- COMMON ----
3871
3872 linkok:
3873   ld  a,D0HD1H
3874   out (7),a             ;raise both wires = link ok
3875   ret
3876
3877 checklink:              ;load wires in A and check for timeout
3878   dec de                ;decrease timer
3879   ld  a,d
3880   or  e
3881   jr  z,linktimeout     ;timeout if de==0
3882 linktest:
3883   ld  a,$BF
3884   out (1),a             ;select keys
3885   in  a,(1)             ;input
3886   bit 6,a               ;exit key
3887   jp  z,Exit            ;break!
3888 linkfine:
3889   in  a,(7)
3890   and %11
3891   ret
3892 linktimeout: ;de==0
3893   cal linkok
3894   ld a,0                ;losses so far
3895 linklosses =$-1
3896   inc a                 ;and this is another one
3897   ld (linklosses),a
3898   pop de                ;return from link
3899   cp  lossout           ;quit if too many errors
3900   ret c                 ;otherwise just continue
3901 linkerr:
3902   jp  Exit
3903
3904 #ifdef intlevels
3905
3906 ;-----------------------------
3907 ;---------- levels -----------
3908 ;-----------------------------
3909
3910 LevelDef:
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
3915
3916   .db 255               ;last level
3917    ret                  ;ending code
3918
3919 LevelDefM:
3920   .db "Empty Arena",0
3921   .db 8,4,15,15,0,0
3922   .db $40,30,2,$C0,30,125, $00,2,64,$80,54,64
3923   .db 128,57
3924   .db 0
3925
3926   .db "Fast Fun :))",0
3927   .db 8,0,18,12,5
3928   .db %1110000,%10001000,%10001000,%10001000,%1110000,0
3929   .db $40,30,2,$C0,30,125, $00,2,64,$80,54,64
3930   .db 128,57
3931   .db 0
3932
3933   .db "Two Circles",0
3934   .db 8,5,18,12,0,0
3935   .db $40,30,2,$C0,30,125, $00,2,64,$80,54,64
3936   .db 128,57
3937   .db 4,40,26,20,0
3938   .db 4,90,40,11,0,0
3939
3940 LevelDefT: ;tron=no delay
3941   .db "Empty Tron Level",0
3942   .db 8,4,18,12,5
3943   .db %1110000,%10001000,%10001000,%10001000,%1110000,0
3944   .db $40,30,64,$C0,30,64, $00,30,64,$80,30,64
3945   .db 128,57
3946   .db 0
3947
3948 LevelDefR: ;race
3949   .db "Round and Round",0
3950   .db 8,4,18,12,5
3951   .db %1110000,%10001000,%10001000,%10001000,%1110000,0
3952   .db $40,23,2,$C0,23,125, $40,35,2,$C0,35,125
3953   .db 128,57
3954   .db 63,27
3955   .db 4,63,27,10,0,0
3956
3957 LevelDefC: ;ctf
3958   .db "Default CTF",0
3959   .db 8,4,18,12,5
3960   .db %1110000,%10001000,%10001000,%10001000,%1110000,0
3961   .db $40,23,2,$C0,23,125, $40,35,2,$C0,35,125
3962   .db 128,57
3963   .db 27,8,27,116
3964   .db 0
3965
3966 #endif
3967
3968 ;-----------------------------
3969 ;---------- data -------------
3970 ;-----------------------------
3971
3972 wtPicture: ;title
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
3989
3990 wtWormy: ;g/o
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
3998
3999 ;.db %00000000,%00000001,%10000000,%00000000,%00001111,%10000000
4000
4001 txtMenu:  .db "Mode",0  ;1st menu item
4002           .db "Level",0 ;2nd
4003           .db "Link",0  ;...
4004           .db "Worms",0
4005           .db "worm #",0
4006 posMenu:  .db 5
4007           .dw $2418,$231E,$2824,$1F2A,$1730
4008 txtMenuR: .db "controls",0
4009 txtoMenu: .db "Back",0  ;1st menu item
4010           .db "Lives",0 ;2nd
4011           .db "Limit",0 ;...
4012           .db "Speed",0
4013           .db "Rotation",0
4014           .db "Growth",0
4015 posoMenu: .db 6
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  ;...
4020           .db "Exit",0
4021 pospMenu: .db 4
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
4031
4032 posGame:  .db 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
4040
4041 txtNone:   .db "None",0
4042 txtDef:    .db "Default",0
4043 txtYes:    .db "Yes",0
4044 txtNo:     .db "No",0
4045 txtKeyleft: .db ":left",0
4046 txtKeyright:.db "/right",0
4047 posLevsel = $0320
4048 txtLevsel:  .db $CF," SELECT LEVELS ",5,0
4049 txtWaiting: .db "Waiting...",0
4050 txtReceive: .db "Receiving..." ;,0
4051
4052 TrigPrecalc:
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
4061 .db 127
4062
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
4071 #ifdef readytext
4072 txtReady:  .db "Prepare!",0
4073 txtposReady = 7
4074 #endif
4075 #ifndef coolzgfx
4076 txtGO:     .db 5,5,5,5,5," GAME OVER ",$CF,$CF,$CF,$CF,$CF,0
4077 #endif
4078
4079 #ifdef intlevels
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
4085 #else
4086 datalevels: .dw 0,0,0,0,0,0,0,0
4087 nrlevels:   .dw 0,0,0,0
4088 #endif
4089
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
4098
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)
4109 gamepeas     =  1
4110 datapeas:   .db  %1100100,1,1,1,-1,-1, 8, 0 ;Peaworm (SP; 1 live)
4111 gametron     =  2
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)
4115 gamefoodm    =  4
4116 datafoodm:  .db  %1100000,0,2,1,-1,-1, 8,10 ;Foodmatch (100 score)
4117 gametimem    =  5
4118 datatimem:  .db  %1010000,1,2,1,-1, 0, 8, 0 ;Timematch (tron, 100 score)
4119 gamerace     =  6 ;used
4120 datarace:   .db  %0000000,0,2,1,-1,-1, 8,10 ;Race (100 score, no collision)
4121 gamectf      =  7 ;used
4122 datactf:    .db  %1001000,0,4,1,-1,-1, 8,10 ;CTF (100 score)
4123
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
4136
4137 defhiscrpos:
4138 #ifdef intlevels
4139   .db 0,0,"SHI"
4140   .db 0,0,"SHI"
4141   .db 0,0,"SHI"
4142   .db 0,0,"SHI"
4143   .db 0,0,"SHI"
4144 #endif
4145
4146 Gametype:  .db 0 ;last gamemode
4147
4148 saveend:
4149
4150                ;set:
4151 heading  = 0   ;level*
4152 pos      = 2   ;level*
4153 pos2     = 4   ;level
4154 grow     = 6   ;level
4155 died     = 8   ;game
4156 score    = 9   ;game
4157 delay    = 11  ;game
4158                ;19B @game
4159 lives    = 12
4160 head     = 13  ;4B (head=tail)
4161 tail     = 15  ;also@next level
4162 storepos = 17
4163 reserv   = 18  ;loop (race:lap|ctf:pea)
4164 input    = 19 ;---currently unused afaik---
4165 left     = 20
4166 right    = 21
4167 name     = 22
4168 wormsize = 31
4169
4170 startdelay    = 30
4171 respawndelay  = 30
4172 maxnamelength = 8+1
4173
4174 defspritesz = 4
4175 defspriteimg:   .db %01100000
4176                 .db %11110000
4177                 .db %11110000
4178                 .db %01100000
4179
4180 #ifdef intlevels
4181 deflevels:
4182   .db "Internal Levels",0
4183   .db "by Shiar" ;,0
4184
4185   .db 0,deflevels/256,deflevels&255
4186 #endif
4187 templevels:
4188
4189 ;-----------------------------
4190 ;----------- end -------------
4191 ;-----------------------------
4192
4193   .end
4194
4195 .end