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