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