wormy 0.98.225
[wormy.git] / wormy.z80
index 785cea953f037c4c1c8ebe62b6e3df2182c5ec03..7e1367304d19046ea3b6e1c6cfa0d6fe05ccb008 100644 (file)
--- a/wormy.z80
+++ b/wormy.z80
 ;    �����     �����       �������     ��       ���              �����������
 ;_______________________________________________________________________________
 ;
-; Version                  :                                      98% (0.98.118)
-; Release Date             :                                     2002 January 18
+; Version                  :                                      98% (0.98.226)
+; Release Date             :                                    2002 February 26
 ; Author(s)                :                                               Shiar
 ; Email Address            :                                     wormy@shiar.org
 ; Web Page                 :                                       www.shiar.org
-; Description              :       perfect Nibbles game with free movement, nine
-;                                                    game modes, for 1-4 players
-; Where to get this game   :                                       www.shiar.org
+; Description              :  perfect Nibbles game with free movement, nine game
+;                                 modes, for 1-4 players, many levels and editor
+; Where to get this game   :                                     wormy.shiar.org
 ; Other games by author(s) :                                        Nemesis beta
 ; Additional Credits to    : Matthew Shepcar  :   wrote original Peaworm, end'98
 ;                            Jonah Cohen      :              helped writing worm
@@ -36,7 +36,7 @@
 ; * Game README is wormy.txt
 ;  * Use for LEARNING practises ONLY!
 ;   * Don't _ever_ release altered code w/o permission!
-;    * Give me credits when you use stuff inhere
+;    * Give me credits when you use any of this stuff
 ;     * I'm not responsible for any damage this might cause, yada yada...
 ;      * Although I've commented & labeled quite some stuff, due to
 ;         crazy optimizations and weird coding, it may be harder to
 ;    |    |_____| ____ |_____/ |_____|
 ;_______________________________________________________________________________
 
-; 97% = PREVIOUS
-;     X [15] lives >9 dispay
-;     X [15] sp modes not configurable
-;     X [16] LVL: episode #2: 10 sp levels
-;     X [17] lives stats for every liveslimited game (also !dm)
-;     X [18] LINK: fix transmit game/level data
-;     X [19] datalevels+nrlevels not in program if !intlevels
-;     X [19] mem at worm #4 (still 12 bytes or so.. or more? or less?)
-;     X [19] alter level editor to use new address and set level id #97
-;     X [19A] team score!
-;     X [19A] autogrowth doesn't always work -> init (turn)
-;     X [111] ED: disabled objects counted causing CRASH when writing hiscore!
-;     X [111] LINK: init+multiple pea transmit seems to work..
-;     X [111] LINK: host/client swapped (host now sends level config)
-;     X [111] LINK: optimize transmit (most initcode same for client+host)
-;     X [113] menu limit in multifm not x10
-;     X [113] wormhit procedure seperate (called now)
-;     X [114] LINK: peas sent again :P
-;     X [114] internal level check and sprite storage removed
-;     X [115] layout data stuff at bottom
-;     X [115] ED: init place bar fixed
-;     X [115] ED: keys also usable together with mouse
-;     X [115] ED: improved version handling
-;     X [115] LINK: receive message not needed anymore afaik
-;     X [115A] $D8 used for spacing at g/o screen. i rule B)
-;     X [115A] exit at g/o goes back to menu
-;     X [115A] more in menu lets you reselect the levelfile
-;     X [115A] LINK: fixed waiting mode (minor display problem)
-;     X [116] incs at skiplevels effectively replaced by add (-4 bytes)
-;     X [116] another 2 bytes shaved off
-;     X [116] LINK: received gamemode now displayed correctly at g/o
-;     X [116] gamecar right after gametype saves about 20 bytes
-;     X [116] LINK: minimize sent data
-;     X [116] remove +input in worm storage
-;     X [116] head position init uses same data as tail (-4 bytes)
-;     X [116] fix bug at no levels (115A intro)
-;     X [117] saved 6 bytes by hardcoding some empty bytes in title graphics
-;     X [117] two pieces of duplicate code removed
-;     X [117] combined temporary storage for _D_HL_DECI and temp hiscore
-;     X [117] more repetitious code shortened
-;     X [117] wrong stack handling in checkpea, and unnecessary bloat
-;     X [117] stopworm after eating pea (pea|wall overwrite fixed!)
-;     X [117] old code removed from hitworm
-;     X [117] replace jps by jrs (moved code around a bit)
-;     X [117] scorebar doesn't diplay 1st wormname char anymore
-;     X [117] scorebar can display both lives and score when appropriate
-;     X [118] look at init-z in line routine again -> fixed steepline init-z
-;     X [118] snake86 findpixel (saves 1 byte)
-;     X [118] removed flash at new level start
-;     X [118] begin growth set in normal worm init loop
-;     X [118] bad code and potentially bad code reviewed and optimized
-;     X [118] final sourcecode layout ((sub)captions, index, indents, etc)
 ; 98% = CURRENT
 ;     X [119] ED: new 53 file format with support for 128 objects instead of 32
 ;     X [119] LVL: episode #4: 10 hard sp levels (ordered XO-XO-XO-X)
+;     X [120] fixed greymask (and it now ands instead of ors)
+;     X [120] fixed growth set after death
+;     X [121] fixed linkplay (couldn't turn it on anymore..)
+;     X [121] LVL: Wormage + Wormage ][ (2x 10 sp levels)
+;     X [121] pea randomizer doesn't give x>128
+;     X [121] mixed single-/multipea singleplayer levels (re)set correctly
+;     X [126] circles left|above 0,0 drawn correctly now!
+;     X [126] fixed multiple pages of levelfiles
+;     X [29]  optimized a few more bytes (less empty bytes so prettier binary ;)
+;     X [225] ED: ctf/race level copy/move fix
+;     X [225] LVL: episode #1: 5 ctf+5 race; episode #3 removed (all in #1 now)
+;     X [225] add v2 id (yas2)
 ;  1% * LINK: >Somehow do a lot of testing with 2 calcs< *sigh*
-;     * LVL: episode #1: add 2-3 circle- and line levels.
-;     * LVL: episode #3: 6x5 multiplayer levels
 ;     * LVL: episode #5: 10 easy sp levels (do i _have_ to?)
-;     * LVL: Eric? (ep#5?)
-;     * LVL: Wormage
+;     * LVL: Eric's Yumworms (ep#5?)
 ;     * LVL: Free Bird
 ;     * LVL: Jonah?
+;     * scorebar last digit (at 128-3) not displayed by _vputs
 ;  1% * fix any bugs that come up
 
 ;--- future features -----------------------------------------------------------
@@ -228,11 +186,11 @@ _MOV4B             = $429B ;4x ld (de),(hl)
 _MOV5B             = $4297 ;5x ld (de),(hl)
 _mov9b             = $4283 ;9x ld (de),(hl)
 _ldHLind           = $4010 ;ld hl,(hl)
-_swapt_            = $45F3 ;ex_ahl_bde
+_swapt_            = $45F3 ;ex ahl,bde (doesn't work?)
 _Get_Word_ahl      = $521D ;ld de,(ahl)
 _Set_Word_ahl      = $5221 ;ld (ahl),de
-_INC_PTR_AHL       = $4637 ;ahl=ahl+1
-_AHL_PLUS_2_PG3    = $4C3F ;ahl=ahl+2
+_INC_PTR_AHL       = $4637 ;inc ahl
+_AHL_PLUS_2_PG3    = $4C3F ;add ahl,2
 _SET_ABS_SRC_ADDR  = $4647 ;set source for mm.ldir =ahl
 _LOAD_ABS_SRC_ADDR = $5209 ;ahl = mm.ldir source
 _SET_ABS_DEST_ADDR = $5285 ;set destination for mm.ldir = ahl
@@ -247,6 +205,7 @@ _writeb_inc_ahl    = $5567 ;ld (ahl++),c
 _jforce            = $409C ;TI-OS stack restored
 _EXLP              = $4493 ;swap (hl),(de) b times
 _GETB_AHL          = $46C3 ;a=(ahl) \ hl=ahl
+_OP1TOOP6          = $4263
 
  #define buffer     ;use display buffer (otherwise write directly to screen)
  #define readymask  ;"greys" out the field before starting a level
@@ -254,7 +213,11 @@ _GETB_AHL          = $46C3 ;a=(ahl) \ hl=ahl
  #define spprotect  ;options not changable for singleplayer modes
 ;#define intlevels  ;-internal levels
 ;#define readytext  ;-displays "prepare" before level starts
-;#define invincible ;-worms cannot die =)
+ #define id2        ;yas2 level identifier (adds 65 bytes)
+                    ;-to become invincible, define the magic word :D
+
+levelhead  = 'w'
+levelhead2 = 97 ;wormy levels header = "0"
 
 ;_______________________________________________________________________________
 ; _______ _______  _____   ______ _______  ______ _______
@@ -275,7 +238,7 @@ worm3       = $AD3D ;-AD5A (1E)
 worm4       = $AD5B ;-AD78 (1E)
 balls       = $AD79 ;-AE00 (<=3x2D) (bb<=45)
 turn10      = $AE01 ;-AE01 (1)     (counter)
-peaspos     = $AE02 ;-AF05 (4-260)    (peas)
+peaspos     = $AE02 ;-AF05 (4-104)    (peas)
 ;free       = $AF06 ;-AFFF (F9)
 worm1p      = $B000 ;-B7FF (800)      %1011O000
 worm3p      = $B800 ;-BBFF (400)      %10111O00
@@ -340,9 +303,18 @@ wormsize    =   30 ;^mark^
 start:         ;turn back NOW!
   nop      ;and so it begins...
   jp  Start
+#ifdef id2
+  ld  (bc),a
+  nop
+  ld  d,h
+  rst 10h
+ .dw  WormIcon
+ .dw  WormData
+#else
   ld  bc,$5242
   rst 10h
  .dw  WormIcon
+#endif
   ld  d,a
   ld  c,a
   ld  d,d
@@ -356,7 +328,7 @@ start:              ;turn back NOW!
  .db  %1010010
   jr  nz,$+47
   dec l
- .db  " 98% .118",0
+ .db  " 98% .225",0
 WormIcon:
  .db  8,2
  .db  %00000000,%00111100
@@ -367,9 +339,54 @@ WormIcon:
  .db  %10011001,%00011001
  .db  %01000010,%11000001
  .db  %00111100,%00111110
-
-levelhead  = 'w'
-levelhead2 = 97 ;wormy levels header = "97"
+#ifdef id2
+WormData:
+ .db  1
+ .dw  wormlevel
+wormlevel:
+ .db  4        ;priority
+ .db  12       ;string
+ .db  "wor"    ;description
+ .dw  yasexec  ;execution routine
+ .dw  yascomment-yasdetect
+ .dw  yasdetect-$-1    ;detection routine
+ .dw  yasicon-yascomment
+ .dw  yascomment-$-1   ;comment routine
+ .dw  yasdataend-yasicon
+ .dw  yasicon-$-1      ;icon routine
+yasexec:
+  rst 10h
+  ex  de,hl
+  ld  a,b
+  cal skiptitle ;title (plus size+header <- all non-0)
+; cal skiptitle ;description
+  jp  leveldataAHL-3
+yasdetect:
+  cal _AHL_PLUS_2_PG3  ;skip past length bytes
+  cal _Get_Word_ahl
+  ld  hl,levelhead+(levelhead2*256)
+  call _cphlde
+  ret z
+  scf
+  ret
+yascomment:
+  inc hl
+  inc hl ;skip header
+  ret
+yasicon:
+  ld  hl,$F400+levelicon-yasicon
+  ld  bc,6+(256*1)
+  or  a
+  ret
+levelicon:
+ .db %00011100 ;..XXX...  ...XXX..
+ .db %00011110 ;.X...X..  ...XXXX.
+ .db %00000011 ;.X..X...  ......XX
+ .db %10000001 ;X..X..XX  X......X
+ .db %01011011 ;X..X..XX  .X.XX.XX
+ .db %01101110 ;X...XXX.  .XX.XXX.
+yasdataend:
+#endif
 
 int_handler:
   ex  af,af'
@@ -381,34 +398,9 @@ int_handler:
   jp  $0039
 int_end:
 
-Start:
-  ld  (SpSave),sp
-  cal _runindicoff
-  cal _flushallmenus
-
-  im  1
-  ld  a,$D4
-  ld  h,a
-  ld  l,0 ;ld hl,$D400
-  ld  d,a
-  ld  e,1 ;ld de,$D401
-  ld  b,e
-  ld  c,l ;ld bc,$0100
-  dec a   ;ld a,$D3
-  ld  (hl),a
-  ldir
-  ld  hl,int_handler
-  ld  d,a
-  ld  e,a ;ld de,$D3D3
-  ld  bc,int_end-int_handler
-  ldir
-  inc a   ;ld a,$D4
-  ld  i,a
-  im  2 ;...it *does* work ;)
-
 ;--- search levels -------------------------------------------------------------
 
-restart:
+Start:
   cal _RAM_PAGE_7
   ld  hl,$BFFF ;VAT start
   ld  ix,templevels
@@ -448,15 +440,12 @@ stringfound:
   cp  e
   jr  nz,_searchnext ;not worm
   ld  a,levelhead2
-  cp  d
+  cp  d ;=0
   jr  nz,_searchnext
-  inc ix ;save level's ahl
-  ld a,h
-  ld (ix),a
-  inc ix
-  ld a,l
-  ld (ix),a
-  inc ix
+  ld (ix+1),h ;save level's ahl
+  ld (ix+2),l
+  ld  de,3 ;&&&d=0
+  add ix,de
 _searchnext:
   cal _RAM_PAGE_7
   jr  searchnext
@@ -510,16 +499,21 @@ levelselectmenu: ;load next page
   cal menuinvloop
   ld  hl,$FC00+$380 ;(*,56)
   cal hr
-  ld  hl,$0601 ;x=1
+  ld  hl,$0C01 ;x=1
   ld  (_penCol),hl
 dispnextlevel:
   ld  de,3
-  add ix,de
+  add ix,de ;goto next
   ld  a,(ix)
-  ld  b,a
+  ld  h,(ix+1)
+  ld  l,(ix+2)
+  cal _load_ram_ahl ;hl=ahl
+  cal _vputs
+  ld  hl,availevels
+  inc (hl)
+  ld  a,(ix+3) ;next
   inc a ;cp 255
   jr  z,__levselect
-displevel:
   ld  hl,_penCol
   ld  (hl),$01 ;x=1
   inc hl
@@ -528,13 +522,6 @@ displevel:
   ld  (hl),a ;y+6
   cp  49 ;bottom of screen
   jr  nc,_levselect
-  ld  hl,availevels
-  inc (hl)
-  ld  a,b ;(ix+0)
-  ld  h,(ix+1)
-  ld  l,(ix+2) ;ahl=(ix)
-  cal _load_ram_ahl ;hl=ahl
-  cal _vputs
   jr  dispnextlevel
 
 loadlevel1:
@@ -604,7 +591,7 @@ levdescclearloop:
   cp  d ;de>$FFFF (offscreen)
   jr  nz,levdescclearloop
   cal _vputs
-  jr  levselectmenu+1
+  jr  levselectmenuloop+1
 __levselect:
 #ifdef intlevels
   ld  ix,templevels-6 ;reset 2 1st page
@@ -614,7 +601,7 @@ __levselect:
 _levselect:
   ld  b,-2 ;level selected
   jr  levselect
-levselectmenu:
+levselectmenuloop:
   psh hl
   psh bc
   cal ubergetkey
@@ -631,7 +618,7 @@ levselectmenu:
   sub K_EXIT-K_RIGHT
   jp  z,ExitNoStats
   inc a ;cp K_SECOND
-  jr  nz,levselectmenu
+  jr  nz,levselectmenuloop
 ; jr  z,loadlevel
 
 loadlevel:
@@ -641,7 +628,7 @@ loadlevel:
   jr  z,levelloaded
 #endif
   cal skiptitle ;skip description
-
+leveldataAHL:
   cal _Get_Word_ahl
   ld  (leveldataSize),de
 
@@ -673,6 +660,36 @@ leveldataSize =$-2
 levelloaded:
   cal _RAM_PAGE_1
 
+;_______________________________________________________________________________
+; _______  _____   ______ _______       _____ __   _ _____ _______
+; |  |  | |     | |_____/ |______         |   | \  |   |      |
+; |  |  | |_____| |    \_ |______ _____ __|__ |  \_| __|__    |
+;_______________________________________________________________________________
+
+  ld  (SpSave),sp
+  cal _runindicoff
+  cal _flushallmenus
+
+  im  1
+  ld  a,$D4
+  ld  h,a
+  ld  l,0 ;ld hl,$D400
+  ld  d,a
+  ld  e,1 ;ld de,$D401
+  ld  b,e
+  ld  c,l ;ld bc,$0100
+  dec a   ;ld a,$D3
+  ld  (hl),a
+  ldir
+  ld  hl,int_handler
+  ld  d,a
+  ld  e,a ;ld de,$D3D3
+  ld  bc,int_end-int_handler
+  ldir
+  inc a   ;ld a,$D4
+  ld  i,a
+  im  2 ;...it *does* work ;)
+
   res 2,(iy+13) ;appAutoScroll
   ld  a,r
   ld  (Seed),a
@@ -685,12 +702,6 @@ setdeflevels:
   add hl,de ;next
   dnz setdeflevels
 
-;_______________________________________________________________________________
-; _______  _____   ______ _______       _____ __   _ _____ _______
-; |  |  | |     | |_____/ |______         |   | \  |   |      |
-; |  |  | |_____| |    \_ |______ _____ __|__ |  \_| __|__    |
-;_______________________________________________________________________________
-
 ;--- trig tables ---------------------------------------------------------------
 
   ld  hl,trigtable   ;I believe this
@@ -804,8 +815,8 @@ dispoptionmenu:
 dispomenusets:
 #ifdef spprotect
   ld  a,(gamecar)
-  rra ;and _datasingl
-  jp  nc,LetsGetThisPartyOn ;SP -> start game
+  and _datasingl
+  jp  nz,LetsGetThisPartyOn ;SP -> start game
 #endif
   cal clrold
 
@@ -1047,7 +1058,7 @@ notselect
   cp  K_EXIT
   jp  z,ExitNoStats
   cp  K_MORE
-  jp  z,restart
+  jp  z,Start
   psh af
   cal menupos
   cal loadgamecar
@@ -1369,9 +1380,8 @@ enternameloop:
   ld  (_penCol),hl
   pop hl
   psh hl
-  ld  (ix),0
+  ld  (ix),a ;clroldcustom -> a=0
   cal __vputs
-  ld  (ix),' '
   ld  a,'_'
   cal __vputmap
 nokeypressed:
@@ -1390,6 +1400,7 @@ backspace:
   dec ix
   jr  enternameloop
 continue:
+  ld  d,0
   cp  K_ENTER
   jr  z,nameentered
   cp  K_EXIT
@@ -1398,8 +1409,7 @@ continue:
   dec (hl) ;(namelength)
   jr  z,nameentered
   ld  hl,chartable-1
-  ld  e,a
-  ld  d,0
+  ld  e,a ;d=0
   add hl,de
   ld  a,(hl)
   or  a
@@ -1419,9 +1429,9 @@ chartable: ;("!@#$%,0" also used in _D_HL_DECI)
   .db $D9,"-PKFA6'"    ;on|sto|,|x2|ln|log|graph|alpha
   .db "54321*",-5,$D0  ;F5|F4|F3|F2|F1|2nd|exit|more
 
-nameentered:
+nameentered: ;d=0
   pop ix ;stringbegin
-  ld  (ix+8),0 ;end mark
+  ld  (ix+8),d ;end mark
   jp  DisplayMenu
 
 ;_______________________________________________________________________________
@@ -1590,8 +1600,8 @@ OhMyGodItsALabel:  ;pj34r my coding skillz
   ex  (sp),hl ;pop \ psh leveldata
   psh hl ;psh loadgamecar
   ld  a,(gamecar)
-  and _datalink
-  jr  z,_StartLevel
+  rra ;and _datalink
+  jr  nc,_StartLevel
 
 ;--- link ----------------------------------------------------------------------
 
@@ -1746,7 +1756,7 @@ teamset:
   ld  l,(hl)
   ld  h,0
   ld  a,(gamecar)
-  rla
+  rla ;and _dataPmult
   ld  a,h ;(Left)=256
   jr  nc,setscorelimit
   ld  a,l
@@ -1774,29 +1784,32 @@ Nextlevel:
   inc hl   ;location of ending-code
   jp  (hl) ;go there ("call")
 donextlevel:
-  ld  bc,gametype
-  ld  a,(bc)
+  ld  de,gametype
+  ld  a,(de)
   or  a ;gamesingle
   psh af
-  cal nz,skiplvltitle
+  jr  nz,customnrpeas
+;--sp--
+  inc de
+  ld  a,(de) ;gamecar
+  rla ;prepare a
+  rlc (hl) ;bit 7 of (hl)...
+  rra ;...to bit 7 of (gamecar)
+  rrc (hl) ;restore (hl)
+  ld  (de),a
   ld  a,(hl)
-  and 127
-  jr  nz,setleft
-customleft =$+1
+  and 127 ;actual #peas
+  jr  setnrpeas
+;--!sp--
+customnrpeas:
+  cal skiplvltitle
   ld  a,0
-setleft:
+customleft =$-1
+
+setnrpeas:
   ld  (Left),a
   inc a
   ld  (lefttotal),a
-  dec a
-  xor (hl) ;bit (hl),7
-  inc bc ;gamecar
-  ld  a,(bc)
-  jr  z,leftloaded
-  or  128+32
-leftloaded:
-  ld  (bc),a
-  inc de
   inc hl
   ld  de,Speed
   ld  a,0
@@ -1989,22 +2002,30 @@ leveldone:
   psh hl                        ; >> levelp new
   cal forceshowstats
 
+  ld  a,(gamecar)
+  rla ;and _dataPmult
+  cal c,multnewpea ;a=0
+  rla ;and _datafood
+  cal nc,NewPea
+nofood:
+  ld  bc,(worm1+pos)
+  cal DisplayField
+
 #ifdef readymask
   ld  hl,$FC70
-  ld  d,%10101010
-  ld  c,56
+  ld  de,57*256+%10101010
 maskloop:
-  ld  a,d
-  xor %11111111
-  ld  d,a
+  ld  a,e
+  cpl
+  ld  e,a
   ld  b,$10
 maskline:
   ld  a,(hl)
-  or  d
+  and e
   ld  (hl),a
   inc hl
   dnz maskline
-  dec c
+  dec d
   jr  nz,maskloop
 #endif
 #ifdef readytext
@@ -2021,15 +2042,6 @@ maskline:
   res 3,(iy+5)
 #endif
 
-  ld  a,(gamecar)
-  rla ;bit __bitPmult,a
-  cal c,multnewpea ;a=0
-  rla ;bit __bitfood,a
-  cal nc,NewPea
-nofood:
-  ld  bc,(worm1+pos)
-  cal DisplayField
-
   ld  b,startdelay
 ReadyDelay:
   halt
@@ -2423,8 +2435,8 @@ hilevelcheckdone:
 
   inc de
   ld  a,(de) ;gamecar
-  rra ;and _datasingl
-  jr  c,hiscorecheckdone ;no SP
+  and _datasingl
+  jr  z,hiscorecheckdone ;no SP
 checkhiscore:
   cal loadhiscoreposinahl ;cf=0 (and)
   cal _SET_ABS_SRC_ADDR ;from ahl (lvlfile)
@@ -2570,8 +2582,8 @@ DoesWormTailEqualsWormHead:
   jr  nz,removewormloop ;head=tail/size=0
 
   ld  a,(gamecar)
-  rra ;and _datasingl
-  jr  nc,savetailpos
+  and _datasingl
+  jr  nz,savetailpos
   ld  (ix+grow+1),a ;=0
   ld  a,0
 growsize =$-1
@@ -2644,8 +2656,8 @@ inputcall:
   jr  z,inlink ;input by link
   cal inkeys ;input by keys
   ld  a,(gamecar)
-  and _datalink
-  ret z ;no link
+  rra ;and _datalink
+  ret nc ;no link
   ld  c,l ;send our keys
   jp  Qsend
 inlink:
@@ -3131,7 +3143,6 @@ Random: ;(2..b+2)
 Seed =$+1
   add a,0
   ld  (Seed),a
-  and %01111110
   cp  b
   jr  nc,Random
   add a,2
@@ -3155,11 +3166,14 @@ mmldir5:
 wormdead:
   pop hl ;<<call
 WormDead:
-#ifdef invincible
-  jp  stopworm
-#endif
   ld  a,2
   ld  (flashtime),a
+#ifdef w00t
+  ld  h,201
+ .org $-2
+  nop
+ .org $+1
+#endif
   ld  (ix+delay),rspawndelay
 
 thislevel =$+1
@@ -3452,8 +3466,8 @@ forceshowstats:
   ld  b,a
   ld  ix,worm1
   ld  a,(gamecar)
-  rra ;and _datasingl
-  jr  nc,showstatsS
+  and _datasingl
+  jr  nz,showstatsS
 showstatloop:
 #ifdef gamenames
 #ifdef longnames
@@ -3965,6 +3979,8 @@ circledraw:               ;destr:de
   psh hl
   ld  a,h              ;hl=x,y
   sub b                ;bc=xx,yy
+       jr  nc,$+3              ;x<xx
+       xor a                   ;left of screen -> x=0
   ld  d,a              ;d=x-xx
   add hl,bc            ;h=x+xx; l=y+yy
   ld  e,l              ;e=y+yy
@@ -3972,6 +3988,8 @@ circledraw:               ;destr:de
   ld  a,l
   sub c                ;a=y again
   sub c
+       jr  nc,$+3              ;y<yy
+       xor a                   ;above screen -> y=0
   ld  l,a              ;l=y-yy
   ld  e,l              ;e=l=y-yy
   cal drawline         ;(h-b,l-c)-(h+b,l-c)
@@ -4157,8 +4175,8 @@ receivenewpeaoverlink:
   ret
 sendnewpeaoverlink:
   ld  a,(gamecar)
-  and _datalink
-  ret z ;no link
+  rra ;and _datalink
+  ret nc ;no link
   ld  a,(worm1+left)
   or  a
   jr  z,receivenewpeaoverlink
@@ -4480,9 +4498,9 @@ worm4set:  .dw worm4p
            .db  %11111101,0,K_PLUS,K_ENTER
 worm4name: .db   "JIM     ",0
 
-_datasingl  =  %00000001 ;singleplayer=0 (=hiscore+keep_length+nextlevel)
+_datalink   =  %00000001 ;linkplay (1!)
 _datafoodl  =  %00000010 ;left=0 limit
-_datalink   =  %00000100 ;linkplay (1!)
+_datasingl  =  %00000100 ;singleplayer=1 (=hiscore+keep_length+nextlevel)
 _dataPctf   =  %00001000 ;ctf peas=1
 __bitPctf   =  3
 _datatime   =  %00010000 ;time incs score (timematch)
@@ -4499,30 +4517,30 @@ _dataPmult  =  %10000000 ;multiple peas=1 (no _datafood) (7!)
                ;      | | | |  |  |  �turn speed (8=def)
                 ;     | | | |  |  |  |  �score limit (0=none)
 gamesingle  =  0 ;    | | | |  |  |  |  |
-datasingle:.db %00000010,3,1,1,-1,-1, 8, 0 ;Singleplayer (SP; 3 lives)
+datasingle:.db %00000110,3,1,1,-1,-1, 8, 0 ;Singleplayer (SP; 3 lives)
 gamepeas    =  1
-datapeas:  .db %00000000,1,1,1,-1,126,8, 0 ;Peaworm (SP; 1 live, 127 growth)
+datapeas:  .db %00000100,1,1,1,-1,126,8, 0 ;Peaworm (SP; 1 live, 127 growth)
 gametron    =  2
-datatron:  .db %01010000,1,1,1,-1, 0, 8, 0 ;Tron (SP; 1 live, cont.growth)
+datatron:  .db %01010100,1,1,1,-1, 0, 8, 0 ;Tron (SP; 1 live, cont.growth)
 gamedeathm  =  3
-datadeathm:.db %01000001,3,2,1,-1,49, 8, 0 ;Deathmatch (3 lives, 50 growth)
+datadeathm:.db %01000000,3,2,1,-1,42, 8, 0 ;Deathmatch (3 lives, 50 growth)
 gamefoodm   =  4
-datafoodm: .db %00000001,0,2,1,-1,-1, 8,10 ;Foodmatch (100 score)
+datafoodm: .db %00000000,0,2,1,-1,-1, 8,10 ;Foodmatch (100 score)
 gamemfoodm  =  5
-datamfoodm:.db %11000011,0,2,1,-1,-1, 8,10 ;MuchFoodmatch (10 peas)
+datamfoodm:.db %11000010,0,2,1,-1,-1, 8,10 ;MuchFoodmatch (10 peas)
 gametimem   =  6
-datatimem: .db %01010001,1,2,1,-1, 0, 8, 0 ;Timematch (1 live, cont.growth)
+datatimem: .db %01010000,1,2,1,-1, 0, 8, 0 ;Timematch (1 live, cont.growth)
 gamerace    =  7
-datarace:  .db %01000001,0,2,1,-1,-1, 8,10 ;Race (100 score)
+datarace:  .db %01000000,0,2,1,-1,-1, 8,10 ;Race (100 score)
 gamectf     =  8
-datactf:   .db %01001001,0,6,1,-1,-1, 8,10 ;CTF (100 score)
+datactf:   .db %01001000,0,6,1,-1,-1, 8,10 ;CTF (100 score)
 
 gametype:  .db 0 ;last gamemode
 gamecar:         ;made before needed (not saved)
 
 saveend:;---
 
-startdelay  =  17
+startdelay  =  42
 rspawndelay =  31
 maxnamesize =  8+1