wormy 0.93.1304: circles, customisable controls
authorMischa Poslawsky <wormy@shiar.org>
Sun, 4 Mar 2001 13:31:42 +0000 (14:31 +0100)
committerMischa Poslawsky <wormy@shiar.org>
Sun, 22 Feb 2009 15:41:57 +0000 (16:41 +0100)
- update title picture to new name
- player keys can be entered from menu
- some bugs fixed like the one that stored names wrong
- game over screen looks better (less basic)
- levels can have *circles* in them!
  - wrote a nice routine from scratch (mostly on paper during vacation)
- default player names (Wormy, Viper, Nibbler, Spunky)

wormy.txt
wormy.z80

index 993be739777605f34a1a78b8c0c496a0e84fd504..e57cee40885f4756211f405ea053b875f6f732ef 100644 (file)
--- a/wormy.txt
+++ b/wormy.txt
-                          #################
-                  Title : ### W O R M Y ###
-                          #################
-                Version : 86%
-           Release Date : hopefully before may 2000
-                File(s) : wormy.86p (4kB)
-                          wormlvl.86s (1kB)
-                          wormy.txt
-                 Author : Shiar
+                  Title : W O R M Y
+                          ---------
+                Version : 0.93.34
+                 Author : SHIAR
+                File(s) : wormy.86p (6kb) + wormy.86s + wormy.txt
+           Release Date : summer 2001
           Email Address : shiar@mailroom.com
                 ICQ UIN : #43840958
-               Web Page : www.games3.net/shiar
-            Description : singleplayer/multiplayer Nibbles-like game
- Where to get this game : games3.net/shiar (home of Wormy)
+               Web Page : www.shiar.org
+            Description : Nibbles-like game, 1-4 players.
+ Where to get this game : www.shiar.org (home of Worm) or ticalc.org
   Other games by author : Nemesis (beta)
-  Additional Credits to : Matthew Shepcar (wrote original Peaworm)
-                          Jonah Cohen (wrote some parts of Worm)
+  Additional Credits to : Matthew Shepcar and Jonah Cohen
 
-*** MAIN MENU
+MAIN MENU =----------------------------------------------------------------
+Alter game settings with the arrow keys (game mode, level, g/o-limit,
+and players (+names and controls). Press enter/2nd to start the game.
 
-*** GAME
-Avoid your worm from crashing by it turning left/right. The controls are:
-1) left/right  2) F1/F2  3) sto/,  4) enter/+
-EXIT : exits to the stats-screen.
-MORE : turns your calc off (pauses).
+GENERAL =------------------------------------------------------------------
+Avoid your worm from crashing by turning it left/right. Default controls
+are 1)left/right 2)F1/F2 3)sto/, 4)enter/+ but they can be altered to
+anything except EXIT (exits to the stats-screen) and MORE (turns calc off.)
 
-*** STATS-SCREEN
-At the end of each game, the stats-screen will be displayed. It shows
-the score and deaths for each worm. Hit enter to return to the main menu.
+STATS-SCREEN =-------------------------------------------------------------
+At the end of each game, the stats-screen will be displayed. It shows the
+score and deaths for each worm, and hiscore for singleplayer games.
+Hit enter to return to the main menu.
 
-*** SINGLEPLAYER
-Move your worm (left/right) over the "food". When you ate enough food
-you advance to the next, more difficult, level.
-On the top of the screen you can see in which level you are, how many
-peas you still have to eat, your score and your lives left.
+SINGLEPLAYER =-------------------------------------------------------------
+Move your worm over the "food". When you ate enough food you advance to the
+next, more difficult, level. At the top of the screen you can see in which
+level you are, how many peas you still have to eat, your score and your
+lives left. You can start in any level you've been before.
 
-*** PEAWORM
+PEAWORM =------------------------------------------------------------------
 Get as many peas possible in a single level.
 
-*** DEATHMATCH
-A multiplayer game where you have to kill the other worm(s) before they
-kill you. When you have no lives left, the game ends. The number of lives
-left for each player are displayed on the top of the screen. You can play
-with 2-4 humans.
-
-*** FOODMATCH
-Like deathmatch, with the difference that your objective is to score 100
-points. You'll get 10 points for taking a pea. If you die however, you
-lose 10.
-
-*** HUNTING
-In this game, the hunter (player 1) has to "catch" the prey (2). The hunter
-must hit the prey with his head, killing the prey and scoring 10 points.
-However, the prey gains 5 points for every 250 turns he's alive. The first
-one scoring 100 points wins.
-
-*** RACE
-In this gametype, all worms have to move around like race-cars. The first
-one to complete 3 laps wins.
-
-*** CTF
-Each player has to capture the enemy flag, and return it to its own flag.
-
-*** DOMINATION
-There are several control points which you have to control. Every ten turns
-each player is given one point for each control point he/she controls.
-The first one scoring 100 points wins.
-
-*** LEVELS &&&
+TRON =---------------------------------------------------------------------
+Like the movie ;)
+
+DEATHMATCH =---------------------------------------------------------------
+A multiplayer game for 2-4 players, where you have to kill the other
+worm(s) before they kill you. When you have no lives left, the game ends.
+You can set the number of lives at the main menu, and it'll be displayed
+during the game at the top of the screen for each player.
+
+FOODMATCH =----------------------------------------------------------------
+Like deathmatch, with the difference that your objective is to score a
+certain amount of points (100 by default.) You'll earn 10 for eating food,
+but if you die you'll lose 10.
+
+//HUNTING =------------------------------------------------------------------
+//In hunting, the hunter (player 1) has to "catch" the prey (2). The hunter
+//must hit the prey with his head, killing the prey and scoring 10 points.
+//However, the prey gains 5 points for every 250 turns he's alive. The first
+//one scoring 100 points wins.
+
+RACE =---------------------------------------------------------------------
+In this gametype, all worms have to move around like race-cars. For each
+lap you complete you'll get 40 points. You lose 10 for dieing, but you
+cannot be killed by running into other worms (you will be slowed down
+though).
+
+CTF =----------------------------------------------------------------------
+Each player has to capture the enemy flag, and return it to his own flag.
+
+//DOMINATION =---------------------------------------------------------------
+//There are several control points which you have to control (by running over
+//them). Every ten turns each player  is given  one point  for each control
+//point he/she controls. The first one scoring 100 points wins.
+
+LEVELS =-------------------------------------------------------------------
 The file WORMLVL.Z80 can be altered to create your own levels. Compile this
 file by running WORMLVL.BAT. Levels may be distributed freely, but I would
 appreciate it if you send me a copy of your levels.
 
-*** CREDITS
+OF COURSE =----------------------------------------------------------------
+I am not responisble for any damage Worm causes. Furthermore, you may not
+release an altered version of Worm, distribute it without this readme file
+included, nor may you charge money for it.
+
+HISTORY =------------------------------------------------------------------
+This is a historical overview of Worm(y) (facts may not match reality)
+* End 1998: Matthew Shepcar releases Peaworm, worm in it's simplest form
+* Scabby didn't release another version with levels and vertical scrolling
+* End 1999: I (Shiar) asked him whether I could complete Worm
+* Jonah Cohen helped me for a while, but soon he either died or got bored
+* June 2000: Worm just didn't want to work correctly (linkplay problems
+   mostly), so I decided to take a break to continue later..
+* Feb 2001: After a huge break I figured it's time to complete WormY.
+* Summer 2001: Shiar finally completed Wormy and everybody was happy (???)
+
+CREDITS =------------------------------------------------------------------
 This game was made by SHIAR. Please contact me at shiar@mailroom.com, or
-ICQ UIN #43840958.
-Also visit the home of Wormy at www.games3.net/shiar (come.to/shiar) for the
-latest news about Wormy and other games by me.
-
-You may not release an altered version of this program, and all files must
-be included with any distribution.
+ICQ UIN #43840958. Also visit the home of Wormy at  www.shiar.org  for the
+latest news about Wormy and new levels (also has over 150 game reviews so
+be sure to visit.)
 
-*** TNX2
-Matthew Shepcar - for writing the original Peaworm
-Jonah Cohen - wrote some parts of Worm
+Matthew Shepcar - for writing the original Peaworm and Wonderworm
+Jonah Cohen     - wrote some parts of Worm
+Free Bird       - calc2calc linkplay testing
+JQL             - betatesting
 
-.
+. =------------------------------------------------------------------------
\ No newline at end of file
index 22711b9a9c9cb7a2e239815d967fc04d5499d7a0..e76ab019faa03442085b7a3e463ad982207bd73d 100644 (file)
--- a/wormy.z80
+++ b/wormy.z80
@@ -1,6 +1,6 @@
 ; Title                      : Wormy
-; Version                    : 92.5%
-; Release Date               : february 2001
+; Version                    : 93%
+; Release Date               : summer 2001
 ; Filename                   : wormy.86p (5kb)
 ; Author(s)                  : Shiar
 ; Email Address              : shiar0@hotmail.com
 ;----------- TO-DO -----------
 ;-----------------------------
 
-; 92% = DONE
+; 93% = DONE
 
-;     * implement circle-routine!
-;  1% * customizable keys
 ;     * internal levels
 ;       * check levels/gametype
 ;       * enough hiscore saves!
@@ -125,8 +123,8 @@ DispBuffer  = $FC70
 
 .org _asm_exec_ram
 
-wormVhost   = 092
-wormVclient = 192
+wormVhost   = 093
+wormVclient = 193
 
 start:
   nop
@@ -136,7 +134,7 @@ start:
   .dw WormIcon
 
 WormTxt:
-  .db "WORMY by SHIAR -- alpha 92.5%",0
+  .db "WORMY by SHIAR -- alpha 93%",0
 WormIcon:
   .db 9,2
   .db %10010110,%01101111
@@ -150,7 +148,7 @@ WormIcon:
   .db %11000011,%10000000
 
 levelhead  = 'w'
-levelhead2 = 92 ;wormy levels header = "92"
+levelhead2 = 93 ;wormy levels header = "93"
 
 int_handler:
   ex af,af'
@@ -401,29 +399,21 @@ NegativeSineWave:
 
 DisplayMenu: ;---draw menu---
   cal _clrWindow
-  ld  de,$FC42 ;(10,2)
+  ld  de,$FC40 ;(0,4)
   ld  hl,wtPicture
-  ld  a,16 ;height
-disptitleloop:
-  ld  bc,8 ;width
+  ld  bc,16*16
   ldir
-  ex  de,hl
-  ld  bc,8 ;next line
-  add hl,bc
-  ex  de,hl
-  dec a
-  jr  nz,disptitleloop
 
   ld  hl,txtMenu
   ld  ix,posMenu
-  ld  b,5
+  ld  b,6
 dispmenuloop:
   ld  d,(ix)
   inc ix
   ld  e,(ix)
   inc ix
   ld  (_penCol),de
-  cal _vputs ;by Shiar \ Mode \ Level \ Limit \ Worms
+  cal _vputs ;Mode \ Level \ Limit \ Worms \ worm # \ controls
   dnz dispmenuloop
 
   ld  b,0 ;b=menu#
@@ -436,15 +426,20 @@ mainMenu:
   cal menucall
   jr  nz,notselect
 select:   ;2nd/enter
+  cal menupos
   ld  a,b
-  dec a ;2nd item?
+  sub 4 ;4th item?
   jp  z,changeworms
-  jp  LetsGetThisPartyOn ;1/3/4
+  dec a ;5th?
+  jp  z,changekeys
+  jp  LetsGetThisPartyOn ;1/2/3/5
 notselect
   cp  K_EXIT
   jp  z,ExitNoStats
   psh af
   cal menupos
+  cal loadgamecar
+  inc hl
   pop af
   cp  K_LEFT
   jr  z,selleft
@@ -456,25 +451,23 @@ selright:
   or  a
   jr  z,changegame
   dec a
-  jr  z,changelevel
+  jp  z,changelevel ;&&&jr??
   dec a
   jr  z,changelives
+  dec a
+  jr  z,changenrworms
 ; dec a
-; jr  z,changenrworms
+; jr  z,changecurworm
 
-changenrworms:
-  ld  a,(Gametype)
-  cp  2
-  jr  c,mainMenu ;type 0/1
-  ld  hl,nrworms
-  ld  a,(hl)
+changecurworm:
+; hl=nrworms
+  ld  a,(curworm)
+  cp  (hl)
+  jr  nc,mainMenu ;may not become >(nrworms)
   inc a
-  cp  5
-  jr  nc,mainMenu ;may not be >4
-changednrworms:
-  ld  (hl),a
-  jr  dispmenusets ;mainMenu
-
+changedcurworm:
+  ld  (curworm),a
+  jp  dispmenusets ;mainMenu
 
 selleft:
   ld  a,b
@@ -484,11 +477,31 @@ selleft:
   jr  z,bchangelevel
   dec a
   jr  z,bchangelives
+  dec a
+  jr  z,bchangenrworms
 ; dec a
-; jr  z,bchangenrworms
+; jr  z,bchangecurworm
+
+bchangecurworm:
+  ld  a,(curworm)
+  dec a ;0-3
+  jr  nz,changedcurworm ;save >0
+  jr  mainMenu
 
+changenrworms:
+  ld  a,(Gametype)
+  cp  2
+  jr  c,mainMenu ;type 0/1
+  ;hl=nrworms
+  ld  a,(hl)
+  inc a
+  cp  5
+  jr  nc,mainMenu ;may not be >4
+changednrworms:
+  ld  (hl),a
+  jr  dispmenusets ;mainMenu
 bchangenrworms:
-  ld  hl,nrworms
+  ;hl=nrworms
   ld  a,(hl)
   dec a ;0-3
   jr  nz,changednrworms ;save >0
@@ -505,12 +518,6 @@ changedgame:
 setgame:
   ld  a,1
   ld  (curlevel),a ;reset level#
-  ld  hl,nrworms ;reset #worms
-  ld  a,(Gametype)
-  cp  2
-  ld  (hl),1
-  jr  c,dispmenusets ;<2=singleplayer
-  inc (hl) ;2
   jr  dispmenusets ;mainMenu
 bchangegame:
   ld  a,(Gametype)
@@ -521,7 +528,7 @@ changelives:
   cal changelivesInit
   inc a
   cp  100
-  jr  nc,mainMenu
+  jr  nc,_mainMenu ;&& _?
 changedlives:
   ld  (hl),a
   jr  dispmenusets ;mainMenu
@@ -559,17 +566,40 @@ bchangelevel:
   ld  a,(curlevel)
   dec a
   jr  nz,changedlevel
-__mainMenu:
   jr  _mainMenu
 
+getcustomkey:
+  cal _vputs
+  dec ix
+waitcustomkey:
+  halt \ halt
+  psh hl
+  cal GET_KEY
+  pop hl
+  or  a
+  jr  z,waitcustomkey
+  cp  K_EXIT
+  ret z
+  cp  K_MORE
+  jr  z,waitcustomkey
+  ld  (ix),a
+  ret
+
+changekeys:
+  cal getwormname
+  ld  hl,txtKeyleft
+  cal getcustomkey ;left
+  cal getcustomkey ;right
+; jr  dispmenusets
+
 ;---display current settings---
 
 dispmenusets:
-  ld  hl,$FD95
-  ld  de,5
-  ld  a,23
+  ld  hl,$FD97 ;begin pos
+  ld  de,7 ;bytes to add
+  ld  a,35 ;nr of lines
 clroldsettings:
-  ld  c,11
+  ld  c,9 ;bytes to clear
 clroldsetsloop:
   ld  (hl),d ;=0
   inc hl
@@ -579,7 +609,7 @@ clroldsetsloop:
   dec a
   jr  nz,clroldsettings
 
-  ld  de,$182E
+  ld  de,$183E
   ld  (_penCol),de
   ld  d,0
   ld  a,(Gametype)
@@ -593,19 +623,14 @@ clroldsetsloop:
   ld  (CURtxtGame),hl ;save for g/o
   cal _vputs ;Singleplayer
 
-  ld  hl,$1E2E ;level
+  ld  hl,$1E3E ;level
   ld  (_penCol),hl
   ld  a,(curlevel)
   cal cshowA
 
-  ld  hl,$2A2E ;worms
-  ld  (_penCol),hl
-  ld  a,(nrworms)
-  add a,'0'
-  cal _vputmap
-
   cal loadgamecar
-  ld  hl,$242E
+  psh hl
+  ld  hl,$243E
   ld  (_penCol),hl
   cal cshowA ;liveslimit
   sub '0' ;original A
@@ -617,7 +642,32 @@ clroldsetsloop:
   ld  a,'0'
 limitok:
   cal _vputmap ;x10
-  jr  __mainMenu
+
+  ld  hl,$2A3E ;worms
+  ld  (_penCol),hl
+  pop hl ;cal loadgamecar
+  inc hl
+  ld  a,(hl)
+  add a,'0'
+  cal _vputmap
+
+  ld  hl,$3032
+  ld  (_penCol),hl
+  ld  a,1
+curworm =$-1
+  add a,'0'
+  cal _vputmap
+  ld  hl,$303E
+  ld  (_penCol),hl
+  cal getwormname
+  ld  hl,worm1name-18
+  add hl,de
+  cal _vputs
+  ld  hl,$363E ;controls
+  ld  (_penCol),hl
+;  ld  hl,txtMenu
+;  cal _vputs
+  jp  mainMenu
 
 ;--- handle menukeys ---
 
@@ -670,45 +720,47 @@ menuup:
   dec b
 menuupdown:
   ld  a,b
-  and %11 ;4=0;-1=3
+  cp  6
+  jr  nz,menunewchk
+  xor a ;6=0
+menunewchk:
+  inc b
+  jr  nz,menunewok
+  ld  a,5 ;-1=5
+menunewok:
   ld  b,a
   jr  menupos
 
 ;--- change name ---
-; of worm#(nrworms)
-;or #1 if Gametype<2
+; of worm#(curworm)
 
-changeworms:
-  cal _clrWindow
-  ld  hl,txtName
-  cal _puts ;"Enter name player "
-  ld  a,(Gametype)
-  cp  2
-  ld  a,1
-  jr  c,wormnrname
-nrworms =$+1
-  ld  a,1
-wormnrname:
-  add a,'0'
-  cal _putc
-  sub '0'
-
-  ld  d,a  ;1x
+getwormname: ;of (curworm)
+  ld  a,(curworm)
   add a,a  ;2x
   ld  e,a
   add a,a  ;4x
   add a,a  ;8x
   add a,a ;16x
   add a,e ;18x
-  add a,d ;19x
   ld  e,a
   ld  d,0 ;de=a
 
-  ld  ix,worm1name-19
+  ld  ix,worm1name-18
   add ix,de
+  ret
+
+changeworms:
+  cal _clrWindow
+  ld  hl,txtEName
+  cal _puts ;"Enter name player "
+  ld  a,(curworm)
+  add a,'0'
+  cal _putc
+
+  cal getwormname
   ld  a,maxnamelength
   cal entername
-  ld  (ix),0
+  ld  (ix),0 ;end mark
   jp  DisplayMenu
 
 entername:
@@ -837,7 +889,9 @@ loadgamecar:
 ;destr: acdehl
   ld  hl,datasingle
   ld  a,(Gametype)
+  ld  e,a
   add a,a
+  add a,e
   ld  e,a
   ld  d,0
   add hl,de
@@ -858,22 +912,22 @@ LetsGetThisPartyOn:
   ld  (CheckExit),a ;set exit state
 
   cal loadgamecar
-  ld  l,a
+  ld  b,a ;psh a
+  inc hl ;nrworms
+  ld  a,(hl)
+  ld  (nrworms),a
+  ld  l,b ;pop a
   ld  h,0             ;hl=a
   cal _HLTIMES10      ;hl=10*(hl)
   ld  (scorelimit),hl ;set limit
 
   cal loadgamecar ;nc
-  ld  e,24+1 ;=de
+  ld  a,(Gametype) ;3bytes -> 2bytes
+  add a,24+1 ;go to datalevels
+  ld  e,a ;=de
   sbc hl,de ;datalevels
 
   ld  a,c ;(gameCar)
-  and _datasingl
-  jr  z,notsingle
-  ld  a,1
-  ld  (nrworms),a
-notsingle:
-  ld  a,c
   and _datascore
   jr  nz,scorelimitset
   dec a ;ld a,$FF ;=no_limit
@@ -903,12 +957,11 @@ linkmatch:
   ld  hl,txtWaiting
   cal _puts
   cal Crecv
-;  ld  a,c
+  ld  a,c
   cp  wormVclient
   jr  z,client
   cp  wormVhost
   jr  nz,linkiniterror
-
 host:
   ld  c,wormVclient
   cal Qsend
@@ -922,8 +975,7 @@ linkiniterror:
 client:
   ld  hl,txtReceive
   cal _puts
-
-  ld  a,$f6
+  ld  a,$E6
 multiplayer:
   ld  (SwapPos),a
   ld  a,2
@@ -934,6 +986,8 @@ multiplayer:
 ;-----------------------------
 
 GameOver:
+  ld  a,%11000000
+  out (7),a ;link normal
   cal _clrLCD
   ld  hl,worm1set
   ld  de,worm1
@@ -1190,25 +1244,16 @@ maskline:
 gameCar =$-1
   and _datalink
   jr  z,initfinished ;no link
-
   xor a
-  ld  (worm2+input),a ;worm 2 via link
-  ld  (worm2+left),a
   ld  (Speed),a ;max.speed
-SwapPos: ;$18 xx -> $F6 xx
-         ; jr xx ->  or xx
+SwapPos: ;$18 xx -> $E6 xx
+         ; jr xx -> and xx
+  jr  sethost
+setclient:
+  ld  (worm1+left),a ;worm 1 via link
   jr  initfinished
-  inc a
-  ld  (worm2+left),a ;1
-  ld  hl,worm1
-  ld  de,worm2
-  ld  b,4 ;+heading +pos
-  cal _EXLP ;swap positions
-;&&& over link
-  ld  hl,worm1+name
-  ld  de,worm2+name
-  ld  b,maxnamelength
-  cal _EXLP ;swap positions
+sethost:
+  ld  (worm2+left),a ;worm 2 via link
 initfinished:
 
   ld  b,startdelay
@@ -1251,13 +1296,16 @@ Delay:
   jr  nz,Delay
 NoDelay:
 
+  ld  (handledworm),a ;=0
+
   ld  a,0
 nrballs =$-1
   or  a
   cal nz,handlethoseneatlittleballs
 
   ld  ix,worm1
-  ld  a,(nrworms)
+  ld  a,1
+nrworms =$-1
   ld  b,a
 handleworms:
   psh bc
@@ -1265,6 +1313,8 @@ handleworms:
   ld  bc,worm2-worm1
   add ix,bc
   pop bc
+  ld  hl,handledworm
+  inc (hl) ;1..nrworms
   dnz handleworms
 
 ;-----------------------------
@@ -1298,14 +1348,19 @@ WormDead:
   ld  (ix+delay),respawndelay
 
 thislevel =$+1
+  ld  hl,0
   ld  de,0
-  ld  a,(de)
-  inc de
+handledworm =$-2
+  add hl,de
+  add hl,de
+  add hl,de
+  ld  a,(hl)
+  inc hl
   ld  (ix+heading),a
-  ld  a,(de)
+  ld  a,(hl)
   ld  (ix+pos),a
-  inc de
-  ld  a,(de)
+  inc hl
+  ld  a,(hl)
   ld  (ix+pos+1),a
 
   inc (ix+died)
@@ -1331,19 +1386,36 @@ SpSave = $-2
   cal _clrWindow
   ld  hl,txtGO
   cal _puts
+  ld  hl,$FC00
+  ld  b,16*8
+  cal menuinvloop ;invert
+  inc h ;$FD80
+  ld  b,16
+  cal menuinvloop ;<hr>
+  ld  hl,$FCE0
+  ld  b,16
+  cal menuinvloop ;<hr>
+; ld  l,$74
+; ld  b,8
+; cal menuinvloop
+  ld  hl,_curRow
+  inc (hl)
   ld  hl,txtGame
 CURtxtGame =$-2
   cal _puts
-  ld  de,0002
-  ld  (_curRow),de
+  ld  a,$0D ;$0D02
+  ld  (_curCol),a
   cal showLevel
-  ld  de,$0B03
+
+  ld  de,$1901
+  ld  (_penCol),de
+  ld  hl,txtName
+  cal _vputs ;Name
+  ld  a,$4F
+  ld  (_penCol),a
+  cal _vputs ;Died    Score
+  ld  de,$0004
   ld  (_curRow),de
-  ld  hl,txtDied
-  cal _puts
-  cal _puts ;txtScore
-  xor a
-  ld  (_curCol),a
 
   ld  a,(nrworms)
   ld  b,a
@@ -1352,26 +1424,18 @@ displayWormStats:
   psh bc
   psh hl
 
-  ld  bc,input-died
-  add hl,bc ;+input
+  ld  bc,left-died
+  add hl,bc ;+left
   xor a
   cp  (hl)  ;input=0 = link
   jr  nz,NoLinkIndic
-  ld  b,7 ;{DOWN}
-  inc hl ;+left
-  cp  (hl)
-  jr  z,hostLinkIndic
-  dec b   ;{UP}
-hostLinkIndic:
   ld  a,8
   ld  (_curCol),a
-  ld  a,b
+  ld  a,$DC ;-O
   cal _putc
   xor a
   ld  (_curCol),a
-  dec hl
 NoLinkIndic:
-  inc hl
   inc hl
   inc hl ;+name
   cal _puts
@@ -1463,7 +1527,7 @@ waitkey:
   jr  nz,waitkey
 
 ;x123456789012345678901
-;1----- GAME OVER -----
+;>>>>>> GAME OVER <<<<<
 ;2Multiplayer
 ;3Level 01
 ;4           Died Score:
@@ -1576,7 +1640,6 @@ unnamedlabel:
 respawndue:
   ld  l,a
   cal inputcall
-  ld  (sendbyte),a
   ld  a,h ;previous
   cp  l   ;changed?
   ret z
@@ -1590,51 +1653,62 @@ saverespawncounter:
 ;  jr  z,inlink
 ;  ret
 
-inkeys: ;use jp not call!
-  out (1),a ;nop\nop
-  in  a,(1)
+chkkey: ;key=a
+  dec a
   ld  b,a
-  and (ix+right)
-  jr  z,notright
+  srl b
+  srl b
+  srl b ;b=a/8
+  and 7 ;a=a\8
+  ld  c,a ;push keybit
+  ld  a,-1
+  out (1),a
+  inc b
+  ld  a,%01111111 ;default
+bitmask:
+  rlca ;rotate left
+  dnz bitmask ;a/8 times
+  out (1),a ;send bitmask
+  in  a,(1) ;input keys
+  ld  b,c ;pop keybit
+  inc b
+keybit:
+  rra
+  dnz keybit ;check match (cf set)
+  ret
+
+inkeys: ;use jp not call!
+  cal chkkey
+  jr  nc,notright
   ld  a,l
   add a,8
   ld  l,a
 notright:
-  ld  a,b
-  and (ix+left)
-  ret z
+  ld  a,(ix+right)
+  cal chkkey
+  ret nc
   ld  a,l
   sub 8
   ld  l,a
   ret
-
 inputcall:
-  ld  a,(ix+input)
+  ld  a,(ix+left)
   or  a
-  jr  nz,inkeys
-
-inlink:
-  ld  b,(ix+left)
-  dec b
-  jr  z,receivefirst
+  jr  z,inlink ;input by link
+  cal inkeys ;input by keys
+  ld  a,(gameCar)
+  and _datalink
+  ret z ;no link
+  ld  c,l ;send our keys
   psh hl
-  ld  c,0
-sendbyte =$-1
-  cal Csend
-  cal Crecv
+  cal Qsend ;Csend
   pop hl
-  ld  l,c
   ret
-receivefirst:
+inlink:
   psh hl
-  cal Crecv
+  cal Qrecv ;Crecv
   pop hl
   ld  l,c
-  psh hl
-  ld  a,(sendbyte)
-  ld  c,a
-  cal Csend
-  pop hl
   ret
 
 ;------- handle worm ---------
@@ -1654,8 +1728,6 @@ notron:
   ld  l,(ix+heading)
   cal inputcall
 donediddelydone:
-  ld  a,l
-  ld  (sendbyte),a
   ld  (ix+heading),l
   ld  h,(ix+heading+1)
 
@@ -1824,9 +1896,9 @@ multiple_peas:
 sel_ownpea:
   cal chkpeahit
   pop hl ;(peapos) 1st pea
-  jp  c,stopworm ;own pea hit
+  jp  c,WormDead ;stopworm ;own pea hit
 
-  ld  a,e ;peek a (that x86 asm for pop\push ;)
+  ld  a,e ;peek a (that's x86 asm for pop\push ;)
   and %01
   jr  z,sel_otherpea
   ld  hl,(peaspos+2) ;2nd pea
@@ -2204,6 +2276,10 @@ scorelimit =$-2
   jp  nc,Exit
 
 showstats:
+  ld  a,(Gametype)
+  cp  gametron
+  ret z
+showstatsEven4tron:
   psh ix
   ld  h,0
   ld  l,h
@@ -2683,6 +2759,8 @@ drawstuff:
   cal z,drawfatline
   dec a ;3 = box
   cal z,drawbox
+  dec a ;4 = circle
+  cal z,circle
 
   pop hl
   inc hl
@@ -2814,6 +2892,195 @@ line4sm:
   dnz LineLoopSteep
   jr  DoneLine
 
+;CIRCLE (d,e),h
+;destroyes ?
+
+circle:                ;de=x,y; h=z
+  ld  c,h              ;c=yy=z
+  ld  a,h
+  neg
+  ld  l,a              ;l=-z
+  xor a
+  ld  b,a              ;b=xx=0
+  dec a                ;-$00**
+  ld  h,a              ;hl=zz=-z
+circloop:
+  psh de               ;x,y
+  ex  (sp),hl          ;push zz \ pop x,y
+  cal circledraw       ;(x-xx,y+yy)-(x+xx,y+yy)
+                       ;(x-xx,y-yy)-(x+xx,y-yy)
+  cal circledraw       ;(x-yy,y+xx)-(x+yy,y+xx)
+                       ;(x-yy,y-xx)-(x+yy,y-xx)
+
+  ex  (sp),hl          ;push x,y \ pop zz
+  xor a
+  ld  d,a              ;d=0
+  dec a                ;-256<h<0 = $FF**
+  cp  h                ;h<0?
+  jr  z,circlenext     ;jump if zz<0
+
+  ld  a,c              ;yy
+  dec a                ;89<a<128
+  add a,a              ;a=2yy-2 ;nc
+  ld  e,a              ;de=a
+  sbc hl,de            ;zz=zz-2yy+2
+  dec c                ;yy--
+circlenext:
+  ld  a,b              ;xx
+  inc a                ;0<a<92
+  add a,a              ;2xx+2
+  inc a
+  ld  e,a              ;de=a
+  add hl,de            ;zz=zz+2xx+3
+
+  pop de               ;x,y
+  ld  a,b
+  cp  c
+  ret nc               ;xx>=yy
+  inc b                ;xx++
+  jr  circloop
+
+circledraw:            ;destr:de
+  psh hl
+  ld  a,h              ;hl=x,y
+  sub b                ;bc=xx,yy
+  ld  d,a              ;d=x-xx
+  add hl,bc            ;h=x+xx; l=y+yy
+  ld  e,l              ;e=y+yy
+  cal drawline         ;(h-b,l+c)-(h+b,l+c)
+  ld  a,l
+  sub c                ;a=y again
+  sub c
+  ld  l,a              ;l=y-yy
+  ld  e,l              ;e=l=y-yy
+  cal drawline         ;(h-b,l-c)-(h+b,l-c)
+  ld  a,b              ;swap xx and yy
+  ld  b,c
+  ld  c,a              ;ex b,c
+  pop hl
+  ret
+
+
+
+
+
+;**** link routines ****
+;these are identical in concept to the routines used in ZTetris, ZPong, and probably
+;every other link game out there.  However, these are commented :)
+losses: .dw 0
+Csend:
+  cal Qsend
+  jr  c,Csend
+  ret
+Qsend:
+send:
+;inputs: c=byte to send, both wires must be high by default
+;outputs: b=8-number of bits sent, both wires high, goes to game over on certain conditions
+;destroys: af,bc,de
+       in a,(7)
+       and %00000011
+       jr z,killlink           ;if both lines low, get out of here (game over signal)
+       ld b,8                          ;sending 8 bits
+sendloop:
+       ld de,$8000                     ;error timer
+       rl c                            ;force high bit into carry
+       ld a,%11010100          ;lower the red wire by default (sending 0) ($d4)
+       jr nc,selected          ;if high bit was 0, use above value
+       ld a,%11101000          ;if 1, lower the white wire instead ($e8)
+selected:
+       out (7),a                       ;put it out the link port
+waitconfirm:
+       call linktimer
+       in a,(7)                        ;see what the wires are doing
+       and %00000011           ;check lower 2 bits
+       jr nz,waitconfirm       ;if both bits 0, data was received ok (both wires low)
+       ld a,%11000000
+       out (7),a                       ;give the ok to raise both wires (one will be done automatically) ($c0)
+waitconfirm2:
+       call linktimer
+       in a,(7)
+       and %00000011
+       cp 3
+       jr nz,waitconfirm2      ;wait for other calc to raise the other wire
+       djnz sendloop           ;continue sending
+       xor a                           ;reset c; ld a,0
+       ld (losses),a           ;reset number of losses
+       ret
+
+
+Crecv:
+  cal receive
+  jr  c,Crecv
+  ret
+Qrecv:
+receive:
+;inputs: both wires must be high by default
+;outputs: c=byte received, b=8-number of bits received, both wires high
+;      goes to game over on certain conditions
+;destroys: af,bc,de
+       in a,(7)
+       and %00000011
+       jr z,killlink           ;game over signal applies to receiving too
+       ld b,8                          ;receiving 8 bits
+receiveloop:
+       ld de,$8000                     ;error timer
+waitreceive:
+       call linktimer
+       in a,(7)
+       and %00000011
+       cp 3                            ;if bits 0 and 1 set, both wires are high
+       jr z,waitreceive        ;wait for one of the wires to go low
+       rra                                     ;check red wire status
+       rl c                            ;if set, red is high (thus white is low), so put the correct bit into c
+       rra                                     ;now check white wire (since the flags are destroyed)
+       ld a,%11010100          ;$d4
+       jr nc,selected2         ;if white is low, lower red and vice versa              
+       ld a,%11101000          ;$e8
+selected2:
+       out (7),a                       ;so now both wires are low
+waitreceive2:
+       call linktimer
+       in a,(7)
+       and %00000011
+       jr z,waitreceive2       ;wait for the wire we didn't lower to go high again (the other will remain low)
+       ld a,%11000000          ;$c0
+       out (7),a                       ;raise both wires since the other calc will have given the ok sign
+       djnz receiveloop        ;if not done, wait for next bit
+       xor a                           ;reset c
+       ld (losses),a           ;reset number of losses
+       ret
+
+linktimer:                             ;leave if we have to wait too long (and return an error)
+       dec de
+       ld a,d
+       or e                            ;see if de is 0
+       ret nz                          ;if not, keep going as usual
+                                               ;otherwise we have to deal with a link failure
+       ld a,%11000000          ;$c0
+       out (7),a                       ;reset link status (both high)
+       ld a,(losses)           ;see how many consecutive losses we have
+       inc a
+       ld (losses),a           ;add this loss to it
+       pop de                          ;fix the stack to leave the link routine (de is ok to destroy)
+       cp 20                           ;see if this is the 20th consecutive failure
+       ret c                           ;if not, keep playing
+                                               ;otherwise, all is probably lost...
+
+killlink2:
+       jr linkend
+killlink:
+linkend:
+  jp  z,Exit
+
+
+
+
+
+
+
+
+
+#ifdef 0
 ;-----------------------------
 ;----------- link ------------
 ;-----------------------------
@@ -2926,6 +3193,7 @@ recvfinish:
   xor a                        ;nc=no error
   ld  a,c              ;result in a
   ret
+#endif
 
 ;-----------------------------
 ;---------- levels -----------
@@ -2936,7 +3204,6 @@ LevelDef:
   .db 0,2,63           ;start d, y, x
   .db 128,57           ;field width (128-255), height (57-255)
   .db 0                ;no additional lines, boxes
-
   .db 255
    ret
 
@@ -2952,60 +3219,78 @@ LevelDefM:
   .db 128,57
   .db 0
 
-LevelDefT:
+  .db 8,5,18,12,0,0
+  .db $40,30,2,$C0,30,125, $00,2,64,$80,54,64
+  .db 128,57
+ .db 4,40,26,20,0
+ .db 4,90,40,11,0,0
+
+LevelDefT: ;tron=no delay
   .db 8,4,18,12,5
   .db %1110000,%10001000,%10001000,%10001000,%1110000,0
   .db $40,30,64,$C0,30,64, $00,30,64,$80,30,64
   .db 128,57
   .db 0
 
+LevelDefC: ;ctf
+  .db 8,4,18,12,5
+  .db %1110000,%10001000,%10001000,%10001000,%1110000,0
+  .db $40,30,64,$C0,30,64, $00,30,64,$80,30,64
+  .db 128,57
+  .db 10,10,50,50
+  .db 0
+
 ;-----------------------------
 ;---------- data -------------
 ;-----------------------------
 
+wdPicture = 16
 wtPicture:
-.db %00011110,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000
-.db %00111110,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000
-.db %01110000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000
-.db %01100000,%01111100,%00000001,%11111111,%00000000,%11110000,%01111001,%11100000
-.db %11100000,%11111110,%00000011,%11111111,%10000011,%11111000,%11111111,%11110000
-.db %11000001,%11000111,%00000111,%00000001,%11000111,%10011001,%11001111,%00111000
-.db %11000001,%10000011,%00000110,%00000000,%11100110,%00000001,%10011111,%10011000
-.db %11000001,%10000011,%00000110,%11000000,%01101110,%00000011,%10111001,%11011100
-.db %11000001,%11000111,%00000110,%11000000,%01101100,%00000011,%00110000,%11001100
-.db %11000000,%11000110,%00000110,%11000000,%01101100,%00000011,%00110000,%11001100
-.db %11100000,%11101110,%00001110,%11000000,%01101100,%00000011,%00111001,%11001100
-.db %01100000,%01111100,%00001100,%11000000,%01101100,%00000011,%00011111,%10001100
-.db %01110000,%00111000,%00011100,%11100000,%11101110,%00000011,%00001111,%00001100
-.db %00111000,%11111110,%00111000,%01110001,%11000110,%00000011,%10000000,%00011100
-.db %00011111,%11101111,%11110000,%00111111,%10000111,%00000001,%10000000,%00011000
-.db %00001111,%10000011,%11100000,%00011111,%00000011,%00000001,%10000000,%00011000
-
-txtMenu:    .db "by Shiar",0
-           .db "Mode",0
-            .db "Level",0      ;4th menu item
-            .db "Limit",0      ;3rd
-            .db "Worms",0      ;2nd
-posMenu:    .dw $0D5A,$1418,$131E,$1524,$0F2A
-txtGame:    .db "Singleplayer",0       ;0 (1st)
-txtGame1:   .db "Peaworm",0    ;1 (next 1st)
-txtGame2:   .db "Tron",0       ;2
-txtGame3:   .db "Deathmatch",0 ;3
-txtGame4:   .db "Foodmatch",0  ;4
-txtGame5:   .db "LinkMatch",0  ;5
-txtGame6:   .db "Race",0       ;6
-txtGame7:   .db "CTF",0        ;7
+.db %01001010,%00101001,%00000111,%10000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%01110000,%00000000,%00000000,%00000000,%01000000,%00000000
+.db %10001010,%10101000,%10001111,%10000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%01111000,%00000000,%00000000,%00000000,%10100100,%01000000
+.db %10101010,%10101010,%10011100,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00011100,%00001110,%00000000,%00000000,%10101010,%10100000
+.db %01010001,%01000101,%00011000,%00011111,%00000000,%01111111,%11000000,%00111100,%00011110,%01111000,%00001100,%00011111,%00000000,%00000000,%11001001,%10100000
+.db %00000000,%00000000,%00111000,%00111111,%10000000,%11111111,%11100000,%11111110,%00111111,%11111100,%00001100,%00111011,%10000000,%00000011,%10001000,%00100000
+.db %01101010,%10010011,%00110000,%01110001,%11000001,%11000000,%01110001,%11100110,%01110011,%11001110,%00001100,%00110001,%10000000,%00000000,%10010000,%00100000
+.db %10001010,%00101010,%10110000,%01100000,%11000001,%10000000,%00111001,%10000000,%01100111,%11100110,%00001110,%01110001,%10000000,%00000000,%01100000,%01000000
+.db %11101110,%10111011,%00110000,%01100000,%11000001,%10110000,%00011011,%10000000,%11101110,%01110111,%00001110,%01110001,%10000011,%11100000,%00000011,%10000000
+.db %00101010,%10101010,%10110000,%01110001,%11000001,%10110000,%00011011,%00000000,%11001100,%00110011,%00000111,%11100001,%10001100,%00011000,%00010000,%00000000
+.db %11001010,%10101010,%10110000,%00110001,%10000001,%10110000,%00011011,%00000000,%11001100,%00110011,%00000011,%11000011,%10010000,%00000100,%00100011,%00001100
+.db %00000000,%00000000,%00111000,%00111011,%10000011,%10110000,%00011011,%00000000,%11001110,%01110011,%00000000,%00000011,%00010011,%00000100,%00100100,%10010010
+.db %00111001,%11000111,%00011000,%00011111,%00000011,%00110000,%00011011,%00000000,%11000111,%11100011,%10000000,%00000011,%00001100,%10000100,%00101000,%10010100
+.db %01100101,%00101000,%00011100,%00001110,%00000111,%00111000,%00111011,%10000000,%11000011,%11000001,%10000000,%00000111,%00000000,%01001110,%00101000,%10011000
+.db %01001101,%11001011,%00001110,%00111111,%10001110,%00011100,%01110001,%10000000,%11100000,%00000001,%11100000,%00001110,%00000000,%01010101,%00101000,%10011000
+.db %00111001,%01100111,%00000111,%11111011,%11111100,%00001111,%11100001,%11000000,%01100000,%00000000,%11111111,%11111100,%00000000,%10010101,%00100110,%00010100
+.db %00000000,%00000000,%00000011,%11100000,%11111000,%00000111,%11000000,%11000000,%01100000,%00000000,%00111111,%11111000,%11111111,%00001000,%11000001,%11100011
+
+txtMenu:  .db "Mode",0  ;1st menu item
+         .db "Level",0 ;2nd
+         .db "Limit",0 ;...
+         .db "Worms",0
+         .db "worm #",0
+         .db "controls",0
+posMenu:  .dw $$2418,$231E,$2524,$1F2A,$1730,$1936
+txtGame:  .db "Singleplayer",0
+txtGame1: .db "Peaworm",0
+txtGame2: .db "Tron",0
+txtGame3: .db "Deathmatch",0
+txtGame4: .db "Foodmatch",0
+txtGame5: .db "LinkMatch",0
+txtGame6: .db "Race",0
+txtGame7: .db "CTF",0
 ;            .db "Domination",0    ;8
-posGame:    .db 0,txtGame1-txtGame
-           .db txtGame2-txtGame
-           .db txtGame3-txtGame
-           .db txtGame4-txtGame
-           .db txtGame5-txtGame
-           .db txtGame6-txtGame
-           .db txtGame7-txtGame
-
+posGame:  .db 0,txtGame1-txtGame
+         .db txtGame2-txtGame
+         .db txtGame3-txtGame
+         .db txtGame4-txtGame
+         .db txtGame5-txtGame
+         .db txtGame6-txtGame
+         .db txtGame7-txtGame
+
+txtKeyleft: .db "Left",0
+txtKeyright:.db " | Right",0
 txtLevsel:  .db $CF," Select levels: ",5,0
-txtName:    .db "Enter name player ",0
+txtEName:   .db "Enter name player ",0
 txtWaiting: .db "Waiting...",0
 txtReceive: .db "Receiving..." ;,0
 
@@ -3021,14 +3306,15 @@ TrigPrecalc:
 .db 127
 
 txtLevel:  .db "Level ",0
-txtWorms:  .db "Worms: 0",0 ;follows txtLevel
-txtDied:   .db "Died ",0
-txtScore:  .db "Score",0    ;follows txtDied
-txtLeft:   .db " left",0    ;follows txtScore
+txtWorms:  .db "Worms: 0",0    ;follows txtLevel
+txtName:   .db "Name",0
+txtDied:   .db "Died    "      ;follows txtName
+txtScore:  .db "Score",0       ;follows txtDied
+txtLeft:   .db " left",0       ;follows txtScore
 txthiscore:.db "HiScore:",0
 txtReady:  .db "Prepare!",0
 txtposReady = 7
-txtGO:     .db "----- GAME OVER -----",0
+txtGO:     .db 5,5,5,5,5," GAME OVER ",$CF,$CF,$CF,$CF,$CF,0
 
 _datalink  = %00000001 ;linkplay
 _datalivel = %00000010 ;lives=0 limit
@@ -3042,48 +3328,48 @@ _datascore = %10000000 ;score>=100 limit
 _datamultpeas = %00100000
 _datasp    = %01011110
 
-datalevels: .dw LevelDef, LevelDefM
+datalevels: .dw LevelDef, LevelDefT
             .dw LevelDefT,LevelDefM
             .dw LevelDefM,LevelDefM
-            .dw LevelDefM,LevelDefM
-nrlevels:   .db 1,2,2,2,2,2,2,1     ;=defaults
+            .dw LevelDefM,LevelDefC
+nrlevels:   .db 1,3,1,3,3,3,3,1     ;=defaults
 
 savestart:
 
 gamesingle   =  0
-datasingle: .db %01011110,3 ;3 lives (<must b unique)
+datasingle: .db %01011110,3,1 ;3 lives (<must b unique)
 gamepeas     =  1
-datapeas:   .db %01011010,1 ;1 "
+datapeas:   .db %01011010,1,1 ;1 "
 gametron     =  2
-datatron:   .db %01000010,1
+datatron:   .db %01000010,1,2
 gamedeathm   =  3
-datadeathm: .db %01000010,3
+datadeathm: .db %01000010,3,2
 gamefoodm    =  4
-datafoodm:  .db %11010000,10 ;10 score limit (=100)
+datafoodm:  .db %11010000,10,2 ;10 score limit (=100)
 gamelinkm    =  5
-datalinkm:  .db %01000011,3
+datalinkm:  .db %01000011,3,2
 gamerace     =  6
-datarace:   .db %10000000,10
+datarace:   .db %10000000,10,2
 gamectf      =  7
-datactf:    .db %11100000,9
+datactf:    .db %11100000,9,4
 ;gamedomin    =  8
 ;datadomin:  .db %01100000,3 ;==(8 modes)
 
 worm1set:  .dw worm1p,worm1p
-           .db %11110111,%00,%01111110,%10,%100 ;< >
-worm1name: .db "worm #01",0
+           .db %11110111,%00,%01111110,K_RIGHT,K_LEFT
+worm1name: .db "Wormy   ",0
 worm2set:  .dw worm2p,worm2p
-           .db %11111011,%11,%00111111,%10000,%1000 ;f1 f2
-worm2name: .db "worm #02",0
+           .db %11111011,%11,%00111111,K_F2,K_F1
+worm2name: .db "Viper   ",0
 worm3set:  .dw worm3p,worm3p
-           .db %11111011,0,%01011111,%10,%100 ;sto ,
-worm3name: .db "worm #03",0
+           .db %11111011,0,%01011111,K_COMMA,K_STO
+worm3name: .db "Nibbler ",0
 worm4set:  .dw worm4p,worm4p
-           .db %11111011,0,%01111101,%10,%1 ;enter +
-worm4name: .db "worm #04",0
+           .db %11111011,0,%01111101,K_PLUS,K_ENTER
+worm4name: .db "Spunky  ",0
 
 defhiscrpos:
-  .dw 0,0,0,0,0
+  .dw 0,0,0,0,0,0
 
 saveend:
 
@@ -3100,9 +3386,7 @@ lives    = 12
 head     = 13  ;4B (head=tail)
 tail     = 15  ;also@next level
 storepos = 17
-reserv   = 18  ;loop
- ;race:lap
- ;ctf:pea
+reserv   = 18  ;loop (race:lap|ctf:pea)
 input    = 19
 left     = 20
 right    = 21
@@ -3125,10 +3409,10 @@ maxnamelength = 8+1
 .db "   shiar0@hotmail.com",0
 
 defspritesz = 4
-defspriteimg: .db %01100000
-              .db %11110000
-              .db %11110000
-              .db %01100000
+defspriteimg:  .db %01100000
+               .db %11110000
+               .db %11110000
+               .db %01100000
 
 deflevels:
   .db 15,"Internal Levels"