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