home *** CD-ROM | disk | FTP | other *** search
/ ARM Club 3 / TheARMClub_PDCD3.iso / programs / comms_networking / netreact / !NetReact / !RunImage (.txt) < prev    next >
RISC OS BBC BASIC V Source  |  1998-03-07  |  17KB  |  699 lines

  1.  ><NetReact$Dir>.!RunImage
  2.  NetReaction
  3.  By Robert Hampton / FABsoft
  4.  NetGame is (C) Justin Fletcher
  5.  This version has better redraw!
  6. testing%=
  7.  "<BasicLibrary$File>":
  8. initlibrary
  9.  "<HeapLibrary$File>":
  10. initheap
  11.  "<NetGameLibrary$File>"
  12. closemessages:
  13. eerror:
  14.  testing%=
  15. ("Spool"):
  16.  testing%=
  17. *Spool Spooled
  18.  testing%=
  19.  Appname$ is used for task manager & Appname$Dir
  20.  shortname$ is used for iconbar name and should usually be null
  21.  longname$ is used for info window
  22.  AppURL$ is used to for clicks on the version icon
  23. 5Appname$="NetReact":version$="0.52 (27 Feb 1998)"
  24. &shortname$="":longname$="Reaction"
  25. 'Appdir$=
  26. systemvar(Appname$+"$Dir")
  27. JAppURL$="http://www.argonet.co.uk/users/fabland/fabsoft/netreact.html"
  28. initwimp:
  29. initprog
  30. quit%=
  31. :init%=
  32. error
  33.  init% 
  34.  go$=
  35. GetEnv:init%=
  36.  go$<>"" 
  37. loadfile(go$,
  38. filetype(go$))
  39.  quit%=
  40.  "Wimp_CloseDown"
  41. closemessages
  42. netgame_final
  43.  testing%=
  44. *SPOOL
  45.  quit%=-1 for user quit, -2 for taskmanager quit
  46.  "OS_ReadMonotonicTime" 
  47.  "Wimp_Poll",0,b%
  48.  reason%
  49.  reason% 
  50.  Null poll
  51. netgame_poll:
  52.  Check if there is something to do
  53. ,$    
  54.  checking%=
  55. check_board
  56. redrawwindow(b%):
  57.  1 = Redraw window
  58.  "Wimp_OpenWindow",,b%
  59.  "Wimp_CloseWindow",,b%
  60. mouseclick(b%!0,b%!4,b%!8,b%!12,b%!16)
  61.  7 = Drag box dropped on another task
  62. processkey(b%!0,b%!4,b%!24)
  63. menuchoice
  64.  17,18:
  65. receive(b%!16)
  66. receiveack(b%!16)
  67. redrawwindow(b%)
  68.  x0%,y0%,x1%,y1%,scx%,scy%,bx%,by%,lx%,ly%,c%,sprite$
  69.  b%!0=boardwin% 
  70.  "Wimp_RedrawWindow",,b% 
  71.  more%
  72. draw_board(b%,more%)
  73.  The whole redraw routine is sort of fixed.
  74. draw_board(b%,m%)
  75.  lx%,ly%
  76. vars(b%)
  77. coord_realtowin(boardwin%,redraw_minx%,redraw_miny%)
  78. coord_realtowin(boardwin%,redraw_maxx%,redraw_maxy%)
  79.  lx%=0 
  80. J'   
  81.  (lx%/2)=
  82. (lx%/2) 
  83.  c%=1 
  84.  c%=2
  85.  ly%=0 
  86.     c%+=1:
  87.  c%>2 
  88.  c%=1
  89. coord_rec_overlap(lx%*100-4,-ly%*100-4,lx%*100+104,-ly%*100-104,redraw_minx%,redraw_miny%,redraw_maxx%,redraw_maxy%) 
  90. NZ     
  91. sprite_plot("c"+
  92. (c%)+"back",bx%+boardleft%+(lx%)*100,by%+boardtop%-(ly%+1)*100)
  93. O@     
  94.  boardcounter%(lx%,ly%)>0 
  95.  boardcounter%(lx%,ly%)<5 
  96.        
  97. sprite_plot("c"+
  98. (boardcounter%(lx%,ly%))+col$(boardcolour%(lx%,ly%)),bx%+boardleft%+(lx%)*100,by%+boardtop%-(ly%+1)*100)
  99.      
  100. R$     
  101.  bangx%=lx% 
  102.  bangy%=ly% 
  103. S]       
  104. sprite_plot("explosion",bx%+boardleft%+(bangx%)*100,by%+boardtop%-(bangy%+1)*100)
  105.      
  106. U        
  107.  "Wimp_GetRectangle",,b% 
  108. sprite_plot(sprite$,x%,y%)
  109.  (x%>x0%-100 
  110.  x%<x1%+100) 
  111.  (y%>y0%-100 
  112.  y%<y1%+100) 
  113.  "Wimp_ReadPixTrans",&100,sprites%,sprite$,,,,sscale%,strans%
  114.  "OS_SpriteOp",308,sprites%,sprite$,x%,y%,8,sscale%,strans%
  115. boardclick(xpos%,ypos%)
  116.  sx%,sy%
  117.  checking%=
  118. screentowin(boardwin%,xpos%,ypos%)
  119.   sx%=xpos% 
  120.  sx%>7 
  121.  sx%=7
  122.  sx%<0 
  123.  sx%=0
  124.   sy%=-ypos% 
  125.  sy%>7 
  126.  sy%=7
  127.  sy%<0 
  128.  sy%=0
  129. placecounter(sx%,sy%)
  130. placecounter(sx%,sy%)
  131.  boardcolour%(sx%,sy%)=player% 
  132.  boardcolour%(sx%,sy%)=-1 
  133. t#  boardcolour%(sx%,sy%)=player%
  134.   boardcounter%(sx%,sy%)+=1
  135. updatesquare(sx%,sy%)
  136.  3,-15,&7000,0
  137.   checking%=
  138. :turns%+=1
  139.  player%=us% 
  140. z(    
  141. netgame_send("G"+
  142. (sx%)+
  143. (sy%))
  144. check_board
  145.  lx%,ly%
  146. checking%=
  147.  lx%=0 
  148.  ly%=0 
  149.  boardcounter%(lx%,ly%)>boardmaxno%(lx%,ly%) 
  150. 9    boardcounter%(lx%,ly%)=0:boardcolour%(lx%,ly%)=-1
  151. bang(lx%,ly%)
  152. updatesquare(lx%,ly%)
  153.  lx%>0 
  154. %      boardcounter%(lx%-1,ly%)+=1
  155. )      boardcolour%(lx%-1,ly%)=player%
  156. "      
  157. updatesquare(lx%-1,ly%)
  158.       checking%=
  159.         
  160.  lx%<7 
  161. &       boardcounter%(lx%+1,ly%)+=1
  162. )      boardcolour%(lx%+1,ly%)=player%
  163. "      
  164. updatesquare(lx%+1,ly%)
  165.       checking%=
  166.         
  167.  ly%>0 
  168. %      boardcounter%(lx%,ly%-1)+=1
  169. )      boardcolour%(lx%,ly%-1)=player%
  170. "      
  171. updatesquare(lx%,ly%-1)
  172.       checking%=
  173.         
  174.  ly%<7 
  175. %      boardcounter%(lx%,ly%+1)+=1
  176. )      boardcolour%(lx%,ly%+1)=player%
  177. "      
  178. updatesquare(lx%,ly%+1)
  179.       checking%=
  180.         
  181.  checking%=
  182.  ly%=7:lx%=7:
  183.  very bad form!
  184.  ly%:
  185.  checking%=
  186.  player%=pblue% 
  187.  player%=pgreen% 
  188.  player%=pblue%
  189. bangclear:
  190. count
  191. updatetitle
  192. count
  193.  lx%,ly%
  194. pbluesc%=0:pgreensc%=0
  195.  lx%=0 
  196.  ly%=0 
  197.  boardcolour%(lx%,ly%)=pblue% 
  198.  pbluesc%+=boardcounter%(lx%,ly%)
  199.  boardcolour%(lx%,ly%)=pgreen% 
  200.  pgreensc%+=boardcounter%(lx%,ly%)
  201.  ly%:
  202.  pbluesc%=0 
  203.  turns%>1 
  204.  pwon%=pgreen%
  205.  pgreensc%=0 
  206.  turns%>1 
  207.  pwon%=pblue%
  208. seticontext(boardwin%,5,
  209. (pbluesc%))
  210. seticontext(boardwin%,7,
  211. (pgreensc%))
  212.  pwon%<>-1 
  213. gameover
  214. gameover
  215.  dummy%
  216.  pwon%=us% 
  217. 2  dummy%=
  218. errorbox(">Message",">WinUs",%10001)
  219. 4  dummy%=
  220. errorbox(">Message",">WinThem",%10001)
  221. bang(sx%,sy%)
  222. bangclear
  223. bangx%=sx%:bangy%=sy%
  224. updatesquare(bangx%,bangy%)
  225.  2,-15,&3500,0
  226. bangclear
  227.  tempx%,tempy%
  228. tempx%=bangx%:tempy%=bangy%
  229. bangx%=-1:bangy%=-1
  230. updatesquare(tempx%,tempy%)
  231. board_clear(notify%)
  232.  sx%,sy%
  233.  sx%=0 
  234.  sy%=0 
  235. 9    boardcounter%(sx%,sy%)=0:boardcolour%(sx%,sy%)=-1
  236.      
  237. redrawicon(boardwin%,3)
  238. ;turns%=0:pbluesc%=0:pgreensc%=0:player%=pblue%:pwon%=-1
  239. seticontext(boardwin%,5,
  240. (pbluesc%))
  241. seticontext(boardwin%,7,
  242. (pgreensc%))
  243. updatetitle
  244.  notify%=
  245. netgame_send("C")
  246. updatetitle
  247.  pwon%=-1 
  248.  player%=us% 
  249. 4    
  250. windowtitle(boardwin%,">Us:"+col$(player%))
  251. 6    
  252. windowtitle(boardwin%,">Them:"+col$(player%))
  253.  pwon%=us% 
  254. (    
  255. windowtitle(boardwin%,">WinUs")
  256. *    
  257. windowtitle(boardwin%,">WinThem")
  258. updatesquare(sx%,sy%)
  259.  left%,top%,right%,bottom%,more%
  260. left%=boardleft%+sx%*100
  261. top%=boardtop%-sy%*100
  262. right%=left%+100
  263. bottom%=top%-100
  264. b%!0=boardwin%
  265. b%!4=left%:b%!8=bottom%
  266. b%!12=right%:b%!16=top%
  267.  "Wimp_UpdateWindow",,b% 
  268.  more%
  269. draw_board(b%,more%)
  270. vars(B%)
  271. ?x0%=B%!4:y0%=B%!8:x1%=B%!12:y1%=B%!16:scx%=B%!20:scy%=B%!24
  272. bx%=x0%-scx%:by%=y1%-scy%
  273. redraw_minx%=B%!28
  274. redraw_miny%=B%!32
  275. redraw_maxx%=B%!36
  276. redraw_maxy%=B%!40
  277.  Buttons : 1 = Adjust, 2 = Menu, 4 = Select
  278. mouseclick(x,y,but,win,icon)
  279.  win 
  280.  but 
  281. ibmenu
  282.  1,4:
  283.  Select or adjust
  284. netgame_connected 
  285.       
  286. openwin(boardwin%)
  287.         
  288. 0      
  289. openconnect:
  290.  Open the connect window
  291.         
  292.  boardwin%
  293.  icon 
  294.  but=2 
  295. menu(boardmenu%,-1,0)
  296. board_clear(
  297.  but=1 
  298.  but=4 
  299. openwin(sendwin%)
  300.  but=1 
  301.  but=4 
  302. disconnect
  303.  but=2 
  304. menu(boardmenu%,-1,0)
  305. ,          
  306.  but=4 
  307. netgame_connected 
  308. ;            
  309.  pwon%=-1 
  310.  player%=us% 
  311. boardclick(x,y)
  312.           
  313.  infobox%
  314.  icon 
  315. !#   
  316.  testing%=
  317. showfree
  318. "H   
  319. FetchPage("http://www.argonet.co.uk/users/fabland/fabsoft/")
  320. FetchPage(AppURL$)
  321.  connectwin%
  322.  icon 
  323. '7   
  324. menu(
  325. netgame_sitesmenu,-1,-1):
  326.  Sites list
  327. tryconnect
  328.  sendwin%
  329.  icon 
  330. ,*   
  331.  Cancel - clear text and close
  332. -#    
  333. seticontext(sendwin%,0,"")
  334. closewin(sendwin%)
  335.  Send
  336. sendmessage
  337.  msgwin%
  338.  icon 
  339.  Reply
  340. openreply
  341. closewin(win)
  342.  boardwin%
  343.  icon 
  344.  Message
  345. openwin(sendwin%)
  346. =     
  347. setcaretend(sendwin%,0)
  348. greyouticons_cos_disconnected
  349. iconshade(boardwin%,0,1)
  350. iconshade(boardwin%,1,1)
  351.  and menus too!
  352. menushade(boardmenu%,1,1)
  353. menushade(boardmenu%,2,1)
  354. ungreyouticons_cos_connected
  355. iconshade(boardwin%,0,0)
  356. iconshade(boardwin%,1,0)
  357.  and menus too!
  358. menushade(boardmenu%,1,0)
  359. menushade(boardmenu%,2,0)
  360. processkey(win,icon,key)
  361.  keydone:keydone=
  362.  win 
  363.  connectwin%
  364.  key 
  365. W#   
  366.  Escape - close window
  367. closewin(connectwin%)
  368.  Return
  369. tryconnect:keydone=
  370.  sendwin%
  371.  key 
  372. ^#   
  373.  Escape - close window
  374. _%    
  375. closewin(sendwin%):keydone=
  376.  Return
  377. sendmessage:keydone=
  378.  keydone 
  379.  "Wimp_ProcessKey",key
  380. menuchoice
  381. "Wimp_GetPointerInfo",,message_buffer%:mbut%=message_buffer%!8
  382.  curmenu% 
  383. netgame_sitesmenu:
  384.  The sites menu, so select it
  385. netgame_selectsite(!b%,connectwin%,1,3,-1)
  386. l@  curmenu%=
  387. netgame_sitesmenu:
  388.  In case it's been re-created
  389.  ibmenu%
  390.  !b% 
  391.  2:quit%=
  392. p7   
  393. netgame_editsites(bestport%):
  394.  Editing time
  395.  boardmenu%
  396.  !b% 
  397. disconnect
  398. u&   
  399. board_clear(
  400.  tell them
  401.  (mbut%
  402. 1)=1 
  403. recreatemenu 
  404.  curmenu%=-1
  405. disconnect
  406. greyouticons_cos_disconnected
  407. netgame_disconnect
  408. updatetitle
  409. receive(mess)
  410.  mess 
  411.  &400C1 = mode change
  412.  &400C2 = task start up
  413.  &400C3 = task shut down
  414.  &90281:
  415.  Sites file has been updated
  416. netgame_readsites
  417.  0:quit%=
  418.  &502:
  419. Help(b%!32,b%!36,b%!4)
  420. desktopsave(b%!20)
  421. receiveack(mess)
  422.  mess 
  423. desktopsave(file%)
  424.  b%!12=b%!8:
  425.  "Wimp_SendMessage",19,b%,b%!4:
  426.  The above line acknowledges the message if an error occurs
  427.  aborting the desktop save.
  428. #file%,"Run "+Appdir$
  429. loadfile(file$,type)
  430.  type 
  431.  Any messages to be received MUST be noted
  432. initwimp
  433.  messagelist% 256:messptr%=0
  434. notemessage(&502):
  435. notemessage(10):
  436. notemessage(&90281)
  437. notemessage(0)
  438.  "Wimp_Initialise",310,&4B534154,Appname$,messagelist% 
  439.  wimpversion,taskhandle
  440. Gindl%=1024:menul%=1024:
  441.  b% 2048,ind% indl%,menu% menul%,wspc% &800
  442. curmenu%=-1
  443. openmessages
  444. -sprites%=
  445. loadsprites(Appdir$+".Sprites")
  446. $infobox%=
  447. loadtemplate("Info",1)
  448. *connectwin%=
  449. loadtemplate("connect",1)
  450. $sendwin%=
  451. loadtemplate("send",1)
  452. &msgwin%=
  453. loadtemplate("message",1)
  454. &boardwin%=
  455. loadtemplate("Board",1)
  456. b%!0=boardwin%:b%!4=3
  457.  "Wimp_GetIconState",,b%
  458. +boardleft%=(b%!8)+4:boardtop%=(b%!20)-4
  459. seticontext(infobox%,1,Appname$)
  460. seticontext(infobox%,2,longname$+" (port xxxx)")
  461. seticontext(infobox%,4,version$)
  462. :ibhandle=
  463. CreateIconBarIcon("!"+Appname$,shortname$,1)
  464. Aibmenu%=
  465. createmenu(Appname$+"|Info]>infobox%|Sites...|Quit")
  466. Mboardmenu%=
  467. createmenu(Appname$+"|Info]>infobox%|Clear Board|Disconnect")
  468. iboptions%=options%
  469. initprog
  470.  x%,y%
  471.  Initialise the network game library
  472.  bestport% is the port we listen on by default
  473. bestport%=4000
  474. /port=
  475. netgame_init(bestport%):
  476.  Port number
  477.  Ensure that everything went ok
  478.  port=-1 
  479. 6 reply=
  480. errorbox(">Message",">CouldntInit",%10001)
  481.  "Wimp_CloseDown"
  482. closemessages
  483. seticontext(infobox%,2,">Info:"+
  484.  port)
  485.  Mark the correct site in the connect window
  486. seticontext(connectwin%,3,
  487.  port)
  488.  Read the sites from the file
  489. netgame_readsites
  490.  sscale% 16:
  491.  strans% 16:
  492.  for Wimp_ReadPixTrans call
  493.  wins%(1),boardcounter%(7,7),boardcolour%(7,7),col$(1)
  494. !boardcolour%()=-1:checking%=
  495.  boardmaxno%(7,7)
  496.  x%=0 
  497.  y%=0 
  498.     boardmaxno%(x%,y%)=3
  499. (    
  500.  x%*y%=0 
  501.  boardmaxno%(x%,y%)=2
  502. %    
  503.  x%=7 
  504.  boardmaxno%(x%,y%)=2
  505. %    
  506.  y%=7 
  507.  boardmaxno%(x%,y%)=2
  508. ,    
  509.  x%=0 
  510.  y%=0 
  511.  boardmaxno%(x%,y%)=1
  512. ,    
  513.  x%=0 
  514.  y%=7 
  515.  boardmaxno%(x%,y%)=1
  516. ,    
  517.  x%=7 
  518.  y%=0 
  519.  boardmaxno%(x%,y%)=1
  520. ,    
  521.  x%=7 
  522.  y%=7 
  523.  boardmaxno%(x%,y%)=1
  524. ;pblue%=0:pgreen%=1:col$()="blue","green":player%=pblue%
  525. @bangx%=-1:bangy%=-1:pbluesc%=0:pgreensc%=0:pwon%=-1:turns%=0
  526.  load sound samples
  527. *ChannelVoice 2 ReactBang
  528. *ChannelVoice 3 ReactPlip
  529. Help(win,icon,to)
  530. readhelp(win,icon,to)
  531.  Windows
  532.  infobox%,">HInfobox"
  533.  3,">HInfobox3"
  534.  4,">HInfobox4"
  535.  sendwin%,">HSendwin"
  536.  2,">HSCancel"
  537.  3,">HSSend"
  538.  msgwin%,">HMsgwin"
  539.  2,">HReply"
  540.  1,">HOk"
  541.  connectwin%,">HConnectwin"
  542.  4,">HCOk"
  543.  boardwin%,">HBoardwin"
  544.  0,">HBWDisconnect"
  545.  1,">HBWMessage"
  546.  3,">HBWBoard"
  547.  5,">HBWBlue"
  548.  7,">HBWGreen"
  549.  -2,">HIconbar"
  550.  -1,-1
  551.  Menus
  552.  ibmenu%,-1,-1,-1
  553.  0,-1,-1,">HMInfo"
  554.  1,-1,-1,">HMSites"
  555.  2,-1,-1,">HMQuit"
  556.  boardmenu%,-1,-1,-1
  557.  0,-1,-1,">HMInfo"
  558.  1,-1,-1,">HMClear"
  559.  2,-1,-1,">HMDisconnect"
  560.  -2,-2,-2,-2
  561. FetchPage(f$)
  562.  XURI_Dispatch - this protocol is still being decided !
  563.  &6E381,%000,f$+
  564.  ******************** NetGame routines ******************
  565.  They've gone, so we'd better tell them
  566. disconnected(type)
  567.  reply
  568.  type 
  569.  ngs_dead:
  570.  Bad little boy, dropped connection
  571. 2  reply=
  572. errorbox(">Message",">Closed",%10001)
  573.  ngs_going:
  574.  Mr Flibble says 'Game Over', boys
  575. 4  reply=
  576. errorbox(">Message",">GameOver",%10001)
  577.  ngs_failed:
  578.  Couldn't get a connection
  579. 5  reply=
  580. errorbox(">Message",">NoConnect",%10001)
  581. openconnect
  582. theirhost$=""
  583. greyouticons_cos_disconnected
  584.  We've got a connection
  585.  type = ngs_originate if we connected to them
  586.  ngs_answer if they connected to us
  587. connected(host$,type)
  588. theirhost$=host$
  589.  type=ngs_originate 
  590. %C  us%=pblue%:them%=pgreen%:
  591.  we initiated connection, we go 1st
  592. 'D  us%=pgreen%:them%=pblue%:
  593.  they initiated connection, them 1st
  594. )+player%=pblue%:
  595.  blue always goes first
  596. board_clear(
  597.  don't tell them
  598. closewin(connectwin%):
  599.  Close the connect window
  600.  We should open a window or something
  601. ungreyouticons_cos_connected
  602. openwin(boardwin%)
  603.  Message has arrived from them - try not to create a loop
  604.  'cos that is kinda silly...
  605. incoming(msg$)
  606.  If it's a user message we should put it in the message window
  607.  with PROCgotmessage(msg$), otherwise it's a 'go' so we need
  608.  to process it
  609. msg$,1)="M" 
  610. gotmessage(
  611. msg$,2))
  612. msg$,1)="G" 
  613.  G = Go - Player has placed a counter
  614.  If we get a message and it's our go then they're cheating!
  615.  player%=us% 
  616.  checking%=
  617. disconnect
  618.     theirhost$=""
  619.  If we're still checking then finish PDQ!
  620.  checking%=
  621. check_board:
  622. C'  x%=
  623. msg$,2,1)):y%=
  624. msg$,3,1))
  625. placecounter(x%,y%)
  626. msg$,1)="C" 
  627. board_clear(
  628.  don't tell them: They already know!
  629.  ********************** Other routines **********************
  630.  Attempt a connection using the 'connect' window as host
  631. tryconnect
  632.  host$,port
  633. P5host$=
  634. geticontext(connectwin%,1):
  635.  Read the host
  636.  host$="" 
  637.  Read the service number
  638. S?port=
  639. inet_getservbyname(
  640. geticontext(connectwin%,3),"tcp")
  641.  Now do the connection
  642. U#ok=
  643. netgame_connect(host$,port)
  644.  We couldn't connect so tell them
  645. X4 reply=
  646. errorbox(">Message",">NoConnect",%10001)
  647. closewin(connectwin%)
  648.  We've got a message from them so lets stick it on the screen
  649. gotmessage(msg$)
  650. seticontext(msgwin%,0,
  651. msg$,39)):
  652.  Fit it to the icon
  653. openwin(msgwin%):
  654.  Open the window
  655.  Send the message in the 'send' window
  656. sendmessage
  657.  a$:a$=
  658. geticontext(sendwin%,0)
  659.  Send the message
  660.  You need to put some code here :
  661.  like PROCnetgame_send(a$)
  662.  Clear the text and close the window
  663. netgame_send("M"+a$)
  664. seticontext(sendwin%,0,"")
  665. closewin(sendwin%)
  666.  Open the 'connect' window
  667. openconnect
  668. openwincentre(connectwin%)
  669. setcaretend(connectwin%,1)
  670.  Open the 'reply' window
  671. openreply
  672. closewin(msgwin%)
  673. openwin(sendwin%)
  674. setcaretend(sendwin%,0)
  675. screentowin(window%,
  676. !b%=window%:
  677.  &400CB,,b%
  678. &x%=x%+b%!20-b%!4:y%=y%+b%!24-b%!16
  679.  ---- BLIbII ----
  680. coord_rec_overlap(x%,y%,X%,Y%,a%,b%,A%,B%)
  681.  x%<a% 
  682.  X%<a% 
  683.  x%>A% 
  684.  X%>A% 
  685.  y%<b% 
  686.  Y%<b% 
  687.  y%>B% 
  688.  Y%>B% 
  689. coord_realtowin(W%,
  690.  B%:B%=b%
  691. !B%=W%:
  692.  &400CB,,B%
  693. &X%=X%+B%!20-B%!4:Y%=Y%+B%!24-B%!16
  694. coord_wintoreal(W%,
  695.  B%:B%=b%
  696. !B%=W%:
  697.  &400CB,,B%
  698. &X%=X%-B%!20+B%!4:Y%=B%!16-B%!24+Y%
  699.