home *** CD-ROM | disk | FTP | other *** search
/ Millennium Time Capsule / AC2000.BIN / disks / hbasic_1 / texts / hbasic.txt < prev    next >
Encoding:
Text File  |  1997-09-27  |  41.5 KB  |  1,219 lines

  1.  
  2.  
  3.          The HiSoft BASIC useful routines and documentation guide
  4.                              by Paul Jones.
  5.                  Disk Compilation/Guide (c) Paul Jones 1997
  6.                        Version 0.06 - 27/09/1997
  7.  
  8. Introduction
  9. ---------------------------------------------------------------------------
  10.  
  11. My name's Paul Jones, and if any of you read the magazine Atari 
  12. Computing, then you'll know I write the Basic BASIC! series of 
  13. tutorials, teaching anyone how to program in HBASIC.
  14.  
  15. I've been programming HBASIC for about three years now, and even 
  16. though I've never released anything, I've been figuring out the odds 
  17. and ends of the HiSoft BASIC package, and other things such as the VA 
  18. protocol.
  19.  
  20. I hope that this guide will provide you, the HiSoft BASIC user, the 
  21. programming power you need to program a really useful application.
  22.  
  23. For those of you who are new to HiSoft BASIC and/or GEM programming, I 
  24. have included my BASIC tutorials (with pictures) to read - with these 
  25. you could create your own GEM program with ease!
  26.  
  27. Each section in this text guide is designed so that it can be updated 
  28. with comments or source when the time comes - it's supposed to be a 
  29. complete guide to HBASIC.
  30.  
  31. How to use the guide
  32. ---------------------------------------------------------------------------
  33.  
  34. The guide contains the latest information on how to use the language 
  35. to it's most effective ability. It gives details on the features of 
  36. HBASIC which are not documented fully, or not at all. Also included is 
  37. routines on what the modern GEM applications use - iconify and 
  38. BubbleGEM. Here is a full list of the subjects covered:
  39.  
  40. The VA protocol
  41. Accessing BubbleGEM
  42. Iconify
  43. Libraries
  44.    - GEMVDI note
  45.    - library list
  46.       - NetWorld
  47.       - MODPLAY
  48.       - WavePlay
  49.       - OOPLIB
  50.    - Writing your own libraries
  51. The Drag&Drop protocol
  52. Multitasking extras
  53. The latest GEMAES.BH file
  54. Tokenising
  55. Sprite mania
  56. Hex/Oct/Bin/Dec
  57. Blind dates
  58. Sources
  59. Shareware methods
  60. GEM globalisation
  61.  
  62. Contact and contributing
  63. Contributers
  64. Copyright status
  65.  
  66.  
  67. Each guide section will always have an introduction of some sort, then 
  68. some source code. It is then explained. If there are brackets "[" and 
  69. "]", then the source code will be found on the disk with that name.
  70.  
  71. The AV protocol
  72. ---------------------------------------------------------------------------
  73.     By Paul Jones
  74.  
  75. The AV protocol was invented for use in the GEMINI desktop, but now 
  76. other desktops like Thing also support the "VA protocol", but what is 
  77. the VA protocol? Well, as you guess by "protocol", it has something to 
  78. do with communication between programs/accessories, and that's exactly 
  79. what it is!
  80.  
  81. The protocol allows your program to communicate with another and 
  82. accessories too. It's also very simple to do and very practical. You 
  83. must have been setting up CAB and wondering "What does 'Supports 
  84. VA_START' mean?". For an accessory, say it loaded up MOD files to play 
  85. when browsing WWW pages, it makes more sence to have it run as a 
  86. background task so you could continue navigating instead of listening 
  87. to the MOD for a while then continuing. So, CAB would have to send the 
  88. acc a message telling it too play.
  89.  
  90. Here's the protocol information:
  91.  
  92.  ------------------------------------------------------
  93. | buffer[0] =|        [Message-type]   (e.g. VA_START) |
  94. | buffer[1] =|           [Sender-ID](from appl_init()) |
  95. | buffer[2] =|                     0    ('overlength') |
  96. | buffer[3] =|        [Control-keys]         (SENDKEY) |
  97. |            |       [Window-handle]     (ACCWINDOPEN) |
  98. |            |       [Window-handle]   (ACCWINDCLOSED) |
  99. |            |       [Window-handle]     (DRAGACCWIND) |
  100. |            | Pointer to path (Low)       (STARTPROG) |
  101. | buffer[4] =|         [Pressed key]         (SENDKEY) |
  102. |            |Pointer to path (High)       (STARTPROG) |
  103. |            |        [Mouse X-Pos.]     (DRAGACCWIND) |
  104. |            |                     0      (all others) |
  105. | buffer[5] =| Pointer to line (Low)       (STARTPROG) |
  106. |            |        [Mouse Y-Pos.]     (DRAGACCWIND) |
  107. |            |                     0      (all others) |
  108. | buffer[6] =|Pointer to line (High)       (STARTPROG) |
  109. |            | Pointer to path (Low)     (DRAGACCWIND) |
  110. |            |                     0      (all others) |
  111. | buffer[7] =|Pointer to path (High)     (DRAGACCWIND) |
  112. |            |                     0      (all others) |
  113.  ------------------------------------------------------
  114.  
  115. In theory it's simple. (The above is taken from the ST-Guide 
  116. information file). And yes, the above is designed for C purposes, but 
  117. we can easyly translate this into HBASIC...
  118.  
  119. [VASEND.BAS]
  120.  
  121. REM $option y+,v+,u+,#,[
  122.  
  123. LIBRARY "GEMAES"
  124. DEFINT a-z
  125.  
  126. a$=SPACE$(16) : a&=VARPTR(a$)
  127. c$="H:\MODS\INTRO.MOD"+CHR$(0) : c&=VARPTR(c$)
  128.  
  129. i=appl_find("VASTART test 1")
  130.  
  131. IF i=-1 THEN PRINT "Not here!"
  132.  
  133. IF i-1 THEN
  134.  
  135. POKEW a&,&H4711
  136. POKEW a&+2,PEEKW(PEEKL(GB+4)+4)
  137. POKEW a&+4,0
  138. POKEL a&+6,c&
  139. POKEW a&+10,0
  140.  
  141. appl_write i,16,a&
  142. END IF
  143.  
  144. ...as the above. Lets go through it... (I'm assuming you read my 
  145. tutorials to understand the basics at least...)
  146.  
  147. a$=SPACE$(16) : a&=VARPTR(a$)
  148.  
  149. Right, first to do a VA_START we need some space to use the appl_write 
  150. command. This creates a string 16 bytes long, and the VARPTR finds the 
  151. address of where this string is in memory.
  152.  
  153. c$="H:\MODS\INTRO.MOD"+CHR$(0) : c&=VARPTR(c$)
  154.  
  155. This is the message text we are going to send, and because the length 
  156. of the string is unknown to the program we send it to, we need to add 
  157. a CHR$(0) onto the end. Again, we find the address of this.
  158.  
  159. i=appl_find("VASTART test 1")
  160.  
  161. We find the program with the specified name (in this case my next 
  162. accessory - next)
  163.  
  164. IF i=-1 THEN PRINT "Not here!"
  165. IF i-1 THEN
  166.  
  167. If it doesn't find it, there isn't much point of continuing...
  168.  
  169. POKEW a&,&H4711
  170.  
  171. Put our first number into where the blank string is, the &H4711 is the 
  172. code for VA_START, there are others (like the BubbleGEM commands).
  173.  
  174. POKEW a&+2,PEEKW(PEEKL(GB+4)+4)
  175.  
  176. Puts the next varible into the string, this time our application number.
  177.  
  178. POKEW a&+4,0
  179.  
  180. A blank space.
  181.  
  182. POKEL a&+6,c&
  183.  
  184. Now we put the address of our string to send in the string, so the 
  185. accessory/program receiving the message will know where the string is, 
  186. as you cannot send strings - only numbers - so you CAN send the 
  187. address of a string in memory (which is why we find the address of the 
  188. string in the top section of the program)
  189.  
  190. POKEW a&+10,0
  191.  
  192. Another blank.
  193.  
  194. appl_write i,16,a&
  195.  
  196. This is how the message is sent. appl_write sends data to an 
  197. program/accessory running in memory, i is the number of the 
  198. application here, the next number is how long the message is, and a& 
  199. is the address of the data (which is why we found it out using 
  200. VARPTR).
  201.  
  202. END IF
  203.  
  204. Finally end...
  205.  
  206. This would send a message to the application called "VASTART test 1". 
  207. I've programmed such an accessory with the source code below, with can 
  208. receive the message we sent. NB: Any application which understands 
  209. VA_START will be able to use the above program.
  210.  
  211. [VAACC.BAS]
  212.  
  213. DEFINT a-z
  214. REM $option y+,v+,u+,#,[,]
  215. REM $option j10
  216.  
  217. LIBRARY "GEMAES"
  218. REM $include gemaes.bh
  219.  
  220. CONST va_start=&H4711
  221. COMMON SHARED junk
  222.  
  223.  
  224. SUB got_vastart
  225. STATIC mess&,id,addr&,addr2&,a,file$,b
  226. SHARED mess(1)
  227.  
  228. file$=""
  229.  
  230. mess&=VARPTR(mess(0))
  231. id=SPEEKW(mess&+2)
  232. addr&=SPEEKL(mess&+6)
  233.  
  234. DO
  235.     a=PEEKB (addr&)
  236.     IF a0 THEN file$=file$+CHR$(a)
  237.     INCR addr&
  238. LOOP UNTIL a=0
  239.  
  240. b=form_alert (1,"[1][ From id:"+STR$(id)+" file name: | "+file$+" ][ Ok ]")
  241.  
  242. END SUB
  243.  
  244. SUB do_message
  245. STATIC cur_front,MessageType,title,item
  246. SHARED exit_item,Finished_Flag,Mess(1),AlreadyOpen
  247.     MessageType=Mess(0)
  248.     junk=wind_get(Mess(3),WF_TOP,cur_front,junk,junk,junk)
  249.      SELECT CASE MessageType
  250.     CASE AC_OPEN:
  251.         junk=form_alert (1,"[1][ VA_START test 1 accessory by | Paul Jones to test VA_START ][ Ok ]")
  252.     CASE VA_START
  253.         CALL got_vastart
  254.     END SELECT
  255. END SUB
  256.  
  257. SUB StartAccessory(daname$)
  258. SHARED WindX,WindY,WindW,WindH
  259. SHARED Mess(1)
  260. STATIC id,mpos
  261. DIM Mess(16)
  262. id=PEEKW(PEEKL(GB+4)+4)
  263. mpos=menu_register(id,daname$)
  264. junk=wind_get(0,WF_WORKXYWH,WindX,WindY,WindW,WindH)
  265.  
  266. DO
  267.     evnt_mesag VARPTR(mess(0))
  268.     do_message
  269. LOOP
  270. END SUB
  271.  
  272. StartAccessory ("  VA_START test 1")
  273.  
  274.  
  275. Again, lets go through it.
  276.  
  277. REM $option j10
  278.  
  279. Tells HBASIC that we're making an accessory and to reserve 10K for it 
  280. to use. Anything after j indicates the number of K to reserve.
  281.  
  282. CONST va_start=&H4711
  283.  
  284. Define the message number of VA_START. There are other message numbers 
  285. too.
  286.  
  287. SUB got_vastart
  288. STATIC mess&,id,addr&,addr2&,a,file$,b
  289. SHARED mess(1)
  290.  
  291. file$=""
  292.  
  293. mess&=VARPTR(mess(0))
  294. id=SPEEKW(mess&+2)
  295. addr&=SPEEKL(mess&+6)
  296.  
  297. DO
  298.     a=PEEKB (addr&)
  299.     IF a0 THEN file$=file$+CHR$(a)
  300.     INCR addr&
  301. LOOP UNTIL a=0
  302.  
  303. b=form_alert (1,"[1][ From id:"+STR$(id)+" file name: | "+file$+" ][ Ok ]")
  304.  
  305. END SUB
  306.  
  307.  
  308. Biggy eh? Pretty simple, mess& is the address of where the data is. 
  309. All we're doing is taking apart the information the program/accessory 
  310. sent us. id will contain the identification number of the program that 
  311. sent us this data, and addr& is the address of where the string data 
  312. is.
  313.  
  314. The DO routine adds all the characters that are not CHR$(0) to file$, 
  315. so we get the string, excluding that CHR$(0).
  316.  
  317. Finally we bring up an alert box which says which application number 
  318. sent it us (0 for programs running in TOS), and the file name, which 
  319. you could do anything with, play a MOD file, display as text, etc.
  320.  
  321. SUB do_message
  322. STATIC cur_front,MessageType,title,item
  323. SHARED exit_item,Finished_Flag,Mess(1),AlreadyOpen
  324.     MessageType=Mess(0)
  325.     junk=wind_get(Mess(3),WF_TOP,cur_front,junk,junk,junk)
  326.      SELECT CASE MessageType
  327.     CASE AC_OPEN:
  328.         junk=form_alert (1,"[1][ VA_START test 1 accessory by 
  329.         | Paul Jones to test VA_START ][ Ok ]")
  330.     CASE VA_START
  331.         CALL got_vastart
  332.     END SELECT
  333. END SUB
  334.  
  335.  
  336. Finds out which message has been sent to us. As you can see, there is 
  337. more than just VA_START. If it is a VA_START, then the goes to the 
  338. got_vastart SUB above. If the accessory is clicked on, the message 
  339. sent is AC_OPEN, and if that's that case, we have a nice alert box 
  340. telling the user about the accessory.
  341.  
  342. SUB StartAccessory(daname$)
  343. SHARED WindX,WindY,WindW,WindH
  344. SHARED Mess(1)
  345. STATIC id,mpos
  346. DIM Mess(16)
  347. id=PEEKW(PEEKL(GB+4)+4)
  348. mpos=menu_register(id,daname$)
  349. junk=wind_get(0,WF_WORKXYWH,WindX,WindY,WindW,WindH)
  350.  
  351. DO
  352.     evnt_mesag VARPTR(mess(0))
  353.     do_message
  354. LOOP
  355. END SUB
  356.  
  357.  
  358. This is the main accessory bit. This is describe is full in the 
  359. accessory section.
  360.  
  361. StartAccessory ("  VA_START test 1")
  362.  
  363. And again.
  364.  
  365. You can also send application specific messages to applications ie 
  366. BubbleGEM. See "Accessing BubbleGEM" for more info.
  367.  
  368. Note with sending VA's, you can actually send ST-guide messages to 
  369. display help files. The format is:
  370.  
  371. FILENAME section
  372.  
  373. eg
  374.  
  375. C:\MYDIR\HELPME.HYP maindialog
  376.  
  377.  
  378. Accessing BubbleGEM
  379. ---------------------------------------------------------------------------
  380.     By Paul Jones
  381.  
  382. On the Reader Disk to Atari Computing issue 5 is a copy of BubbleGEM. 
  383. The main purpose of it is to bring up a speech bubble displaying help 
  384. when you click on the right mouse button of a button in a formwindow 
  385. to see what it will do if you click on that particular button. And 
  386. yes, you too can use it in HBASIC!
  387.  
  388. It works mostly by the same method as above:
  389.  
  390.  
  391. /* BUBBLEGEM_SHOW - Information:
  392.  * msg[0]   $BABB
  393.  * msg[1]   ap_id
  394.  * msg[2]   0
  395.  * msg[3]   Mouse X
  396.  * msg[4]   Mouse Y
  397.  * msg[5/6] Pointer to nullterminated string in globalen
  398.  *          Memory
  399.  * msg[7]   0
  400.  */
  401.  
  402.  
  403. Again, this is in C syntax but we can convert it. Instead of our 
  404. VA_START code (4711 in hex), we use BABB in hex. Looking at the above 
  405. information, you can see it's much the same information is needed as 
  406. in a VA_START. All that's different is the Mouse X and Mouse Y.
  407.  
  408. [SENDBUB.BAS]
  409.  
  410. DEFINT a-x
  411. LIBRARY "GEMAES"
  412.  
  413. c$=SPACE$(16) : c&=VARPTR(c$)
  414. ad$="This is a demo of how to use BubbleGEM. As you can see it brings 
  415. a bubble up on the screen!"
  416. ad$=ad$+" This is useful for help functions in programs, but only if 
  417. the dialog is non-modal. The"
  418. ad$=ad$+" call to access it is a combination of things with a 
  419. appl_write at the end"+CHR$(0) : ad&=VARPTR(ad$)
  420.  
  421. IF LEN(ad$)>255 THEN STOP -1
  422.  
  423. i=appl_find("BUBBLE  ")
  424. IF i=-1 THEN BEEP : STOP-1 
  425.  
  426. POKEW c&,&HBABB
  427. POKEW c&+2,PEEKW(PEEKL(GB+4)+4)
  428. POKEW c&+4,0
  429. POKEW c&+6,MOUSE(0)
  430. POKEW c&+8,MOUSE(1)
  431. POKEL c&+10,ad&
  432. POKEW c&+14,0
  433.  
  434. appl_write i,16,c&
  435.  
  436.  
  437.  
  438. c$=SPACE$(16) : c&=VARPTR(c$)
  439. ad$="This is a demo of how to use BubbleGEM. As you can see it brings 
  440. a bubble up on the screen!"
  441. ad$=ad$+" This is useful for help functions in programs, but only if 
  442. the dialog is non-modal. The"
  443. ad$=ad$+" call to access it is a combination of things with a 
  444. appl_write at the end"+CHR$(0) : ad&=VARPTR(ad$)
  445.  
  446.  
  447. Like in the VA_START code we reserve some space, and create our string 
  448. to be "bubbled"
  449.  
  450. IF LEN(ad$)>255 THEN STOP -1
  451.  
  452. BubbleGEM can only handle strings this than 255 characters long.
  453.  
  454. i=appl_find("BUBBLE  ")
  455. IF i=-1 THEN BEEP : STOP-1 
  456.  
  457.  
  458. Find the application number BubbleGEM is running on. It it isn't 
  459. there, quit.
  460.  
  461. POKEW c&,&HBABB
  462. POKEW c&+2,PEEKW(PEEKL(GB+4)+4)
  463. POKEW c&+4,0
  464. POKEW c&+6,MOUSE(0)
  465. POKEW c&+8,MOUSE(1)
  466. POKEL c&+10,ad&
  467. POKEW c&+14,0
  468.  
  469.  
  470. Much the same as the VA_START code. Notice MOUSE(0) and MOUSE(1)? 
  471. MOUSE(0) will return the current X position of the mouse on screen, 
  472. and MOUSE(1) will do the same for the Y.
  473.  
  474. appl_write i,16,c&
  475.  
  476. This is send our message to BubbleGEM, and will bring up a bubble 
  477. containing the text at the top of the program, at the co-ordinates of 
  478. X,Y.
  479.  
  480. Iconify
  481. ---------------------------------------------------------------------------
  482.     By Paul Jones
  483.  
  484. With the AES 4.1, and with programs which support iconifing, a little 
  485. triangle button appears in the top right hand corner. If you press 
  486. this button, the window is shrinked down to the bottom of the screen, 
  487. which is useful is you have lots of windows open on screen.
  488.  
  489. Iconifing in HBASIC is pretty easy, it requires the new GEMAES.BH file 
  490. (found elsewhere in this document), and that you are using 
  491. windows/formwindows instead of dialogs.
  492.  
  493. First, you must find your routine which get system messages and deals 
  494. with them (if you're using the HGT's, this is in WINDOW.BAS, sub 
  495. WindowMessage). You then need to add:
  496.  
  497.         CASE WM_ICONIFY
  498.             junk=wind_set (mess(3),WF_ICONIFY,mess(4),mess(5),mess(6),mess(7))
  499.             myicon(mess(3))=1
  500.         CASE WM_UNICONIFY
  501.             junk=wind_set (mess(3),WF_UNICONIFY,mess(4),mess(5),mess(6),mess(7))
  502.             myicon(mess(3))=0
  503.  
  504. Note: myicon() must be defined in the formwindow initialisation code 
  505. (found in FORMWIND.BAS).
  506.  
  507. You then need to add another section to your redraw routine, if 
  508. myicon(handle)=1 then the window is iconified and the icon should be 
  509. redrawn. I use a sub program called ProcessUserIconify:
  510.  
  511. SUB ProcessUserIconify (x,y,w,h)
  512. STATIC logo&,xout,yout,wout,hout
  513.  
  514. junk=rsrc_gaddr (0,iconpic,logo&)
  515. ' iconpic is the tree to your icon, it should be 32x32. See ICON.RSC 
  516. ' for an example.
  517. SelectTreeAddr logo&
  518. junk=wind_calc (1,9,x,y,w,h,xout,yout,wout,hout)
  519.  
  520. DECR xout
  521. DECR yout
  522. DECR wout
  523. DECR hout
  524.  
  525. setob_x 0,xout
  526. setob_y 0,yout
  527. setob_width 0,wout
  528. setob_height 0,hout
  529. junk=objc_draw (logo&,0,10,xout,yout,wout,hout)
  530.  
  531. END SUB
  532.  
  533. If myicon(handle)=0 then the redraw should be treated to the 
  534. formwindow/window.
  535.  
  536. Windows should have &H4000 added onto their windowcomp status's.
  537.  
  538. What happens is that the AES tells us that the user has clicked on our 
  539. window and wants it iconified. Then we give a message back saying to 
  540. make it small, as you may have noticed, this is the same sort of thing 
  541. whih happens for other window messages!
  542.  
  543. Libraries
  544. ---------------------------------------------------------------------------
  545.     By Paul Jones
  546.  
  547.    - GEMVDI note
  548.    ------------------------------------------------------------------------
  549.  
  550. You might have noticed that most VDI commands are not in the GEMVDI 
  551. library. The HBASIC manual lists some of them, but there are plently 
  552. more. These are in the FALCON lib. If you have the Atari Compedium, 
  553. you will see these commands. There are just too many to list in this 
  554. short space.
  555.  
  556.    - library lists
  557.    ------------------------------------------------------------------------
  558.  
  559. Please note all libraries here (unless stated) are included on the 
  560. disk.
  561.  
  562. New libraries are created by a third party to enhance HiSoft BASIC. 
  563. They are written in machine code and can be accessed in HBASIC by 
  564. "library <xxx>", where <xxx> is the library you wish you use. Here is 
  565. a list of them, and what they do:
  566.    
  567.       - NetWorld
  568.       ---------------------------------------------------------------------
  569.  
  570. NetWorld is a library so you can use STiK (the ST internet Kit) to 
  571. connect to the internet. It is a simple library, with an include file 
  572. to rid yourself of tedious functions like getting C strings, sending 
  573. data, and connecting to a host etc.
  574.  
  575. Needs: HiSoft BASIC (either major version), a modem and an internet 
  576. account.
  577.  
  578. Achievements: With it you can create your own internet clients!
  579.  
  580. By: Paul Jones, email paulat.jones@zetnet.co.uk
  581.  
  582.       - MODPLAY
  583.       ---------------------------------------------------------------------
  584.  
  585. MODPLAY lets you play MOD files via the DSP on the Falcon on interupt. 
  586. This means only 12% processor time is used and it will run in the 
  587. background without you having do to anything!
  588.  
  589. Needs: HiSoft BASIC (either major version), a Falcon with DSP, MOD 
  590. files!
  591.  
  592. Achievements: Create your own MOD file player.
  593.  
  594. By: MOD player routines by bITmASTER of BSW, original library code by 
  595. Graig Graham, new version by Paul Jones.
  596.  
  597.       - WavePlay
  598.       ---------------------------------------------------------------------
  599.  
  600. WavePlay lets you use System Audio Manager (SAM), with KP SACK to have 
  601. your own program sound effects. The user chooses a sound for a certain 
  602. event, and your program tells SAM to play it. Simple.
  603.  
  604. Needs: TOS 2.xx or greater and DMA sound.
  605.  
  606. Achievements: SAM is quoted as having unleashed potential. Your 
  607. programs would be more in the "multimedia" style if you used SAM.
  608.  
  609. By: WavePlay lib. is by Paul Jones. KP SACK is by Kosmik Phish 
  610. Productions and SAM 1.3 is by Scott Sanders at Atari Corp with bugs 
  611. fixed by KPP.
  612.  
  613.       - OOPLIB
  614.       ---------------------------------------------------------------------
  615.  
  616. Object Orientated Programming LIBrary is for programming where the 
  617. emphasis is on objects. OOP is implemented in C and is claimed to be 
  618. "missing" from HBASIC. Because of the use of objects, it is ideal for  
  619. Graphical User Interface programs.
  620.  
  621. By Graig Graham.
  622.  
  623.    - Writing your own libraries
  624.    ------------------------------------------------------------------------
  625.  
  626. If you wish to write your own libraries, you'll need to know machine 
  627. code. 
  628.  
  629. An example library is included.
  630.  
  631. Libraries need to be linkable (which means you need to write them in a 
  632. Devpac above v1.2).
  633.  
  634. A library structure:
  635.  
  636.     opt    p+,l+,c+
  637.  
  638.     INCLUDE    LIBRARY.H
  639.     
  640.     library LIBRARYNAME
  641.     
  642.     xref    get_string    external references
  643. *                get_string inputs:
  644. *                    a0.l the address of the string
  645. *                outputs:
  646. *                    d1.l the address of string
  647. *                    d4.l the length of the string
  648.     xref    get_array
  649. *                get_array inputs:
  650. *                    a0.l the array desciptor
  651. *                    d0.w number of dimensions the 
  652. *                    array should have.
  653. *                outputs:
  654. *                    a2.l the address of the first 
  655. *                    array element
  656. *                    d4.l total length in bytes of 
  657. *                    array
  658.     xref    make_string
  659. *                make_string inputs:
  660. *                    a0.l the string descriptor of 
  661. *                    a string value
  662. *                    a1.l the address of your copy 
  663. *                    of the string
  664. *                    d4.l the length of the string
  665. *                outputs:
  666. *                    nothing
  667.     xref.l    gl_scratch    this is referenced off global!
  668.  
  669.     xdef    routine1
  670.     xdef    routine2
  671.     
  672.     fn_int    vlng,vlng,int    * routine1 takes in a long,long,int, 
  673. *                                 returns a int
  674.     fn_int_np        * routine2 returns a int - no 
  675. *                                 parameters. Note that anything with 
  676. *                                 a "_np" means no paramters - an 
  677. *                                 addition to the library.h file by 
  678. *                                 Paul Jones
  679.  
  680.     option 'uv'
  681.     
  682.     libstart
  683.     
  684. routine1
  685. * code here
  686.     move.l    4(sp),a0
  687. *Get the long, located at 4(sp). At (sp) is the return address. Each 
  688. *parameter is added onto the stack.
  689.     move.l    8(sp),a1
  690.     move.w    12(sp),a2
  691.     move.w    #1,tos
  692. *anything which is put into tos (really d6) is returned. .w for a int, 
  693. .l for a long.
  694.     rts
  695. routine2
  696. * code here
  697.     rts
  698.  
  699.  
  700. Code must be position independant.
  701.  
  702. The following types are available:
  703.  
  704. subdef        a subprogram
  705. subdef_np    same as above with no parameters
  706. fn_int        function which returns a 16-bit integer
  707. fn_int_np    same as above with no parameters
  708. fn_lng        function which returns a 32-bit integer
  709. fn_lng_np    same as above with no parameters
  710. fn_sng        function which returns a single precision number
  711. fn_sng_np    same as above with no parameters
  712. fn_dbl        function which returns a double precision number
  713. fn_dbl_np    same as above with no parameters
  714.  
  715. There is also types of parameters:
  716.  
  717. int    a 16-bit interger
  718. lng    a 32-bit long integer
  719. sng    a 32-bit FFP single-precision value
  720. dbl    a 64-bit IEEE double-precision value
  721. str    a string value
  722. aint    an array of ints
  723. alng    an array of lngs
  724. asng    an array of sngs
  725. adbl    an array of dbls
  726. astr    an array of strings
  727. vint    varptr(int-variable)
  728. vlng    varptr(lng-variable)
  729. vsng    varptr(sng-variable)
  730. vdbl    varptr(dbl-variable)
  731. vstr    varptr(string-variable)
  732.  
  733. The Drag&Drop protocol
  734. ---------------------------------------------------------------------------
  735.     Example by Michael Wensley
  736.  
  737. In MultiTOS it is possible for you to create a program which when the 
  738. user drags a file onto your window, it can load it. You can also send 
  739. drag&drop messages.
  740.  
  741. Go into the DRAGDROP folder, there is DRAGDROP.BAS. This program was 
  742. created by Michael Wensley. It shows you a simple GEM program and how 
  743. to get a drag&drop message (he hasn't figured out how to send one 
  744. yet).
  745.  
  746. Multitasking extras
  747. ---------------------------------------------------------------------------
  748.     By Paul Jones
  749.  
  750. In a multitasking system, the user wishes to have such features as 
  751. iconify (defined above), drag&drop and have the program display it's 
  752. real name in the desk menu.
  753.  
  754. [MULTITAS.BAS]
  755.  
  756. ' The multitasking library source by Paul Jones 1997
  757. ' This code may be included in your own programs for free
  758.  
  759. FUNCTION aesversion
  760. aesversion=PEEKW(PEEKL(GB+4))
  761. END FUNCTION
  762.  
  763. FUNCTION max_progs
  764. max_progs=PEEKW(PEEKL(GB+4)+ap_count)
  765. END FUNCTION
  766.  
  767. Uses the GB array to check the maximum number of programs. 
  768. Multitasking systems return -1.
  769.  
  770. FUNCTION appl_id
  771. appl_id=PEEKW(PEEKL(GB+4)+ap_id)
  772. END FUNCTION
  773.  
  774. This finds out what our current id number is.
  775.  
  776. SUB Multitask_name (name$)
  777. STATIC mpos
  778. IF max_progs=-1 OR aesversion>=&H410 THEN mpos=menu_register(appl_id,name$)
  779. END SUB
  780.  
  781. This subprogram checks to see if the system is multitasking, and if it 
  782. is it sets the name. This can be included in your programs and save a 
  783. bit of time (it also makes your program look better in the long run 
  784. with extra goodies).
  785.  
  786.  
  787. You also might have noticed that some programs (like KP SACK) can 
  788. automaticlly shutdown when you want to change resolution. Programs 
  789. which don't support this feature have to be closed down manually! To 
  790. make your programs AP_TERM compatible:
  791.  
  792. IF appl_find("AGI?") OR aes_version>= &H410 THEN appl_getinfo_valid=TRUE
  793.  
  794. IF appl_getinfo_valid THEN
  795.     junk=appl_getinfo(10,max_shellwrite,dummy, dummy, dummy)
  796.     junk=appl_getinfo(12,ap_termsent, dummy, dummy, dummy)
  797.     if max_shellwrite>=9 AND ap_termsent!=0 THEN set_apterm=TRUE;
  798. END IF
  799.  
  800. IF aes_version>= &H330 OR set_apterm THEN
  801.     shel_write(9,1,0,0,0)
  802. END IF
  803.  
  804. This above is converted from C. I'm not sure if this works or not, so 
  805. use at your own risk!
  806.  
  807. Thanks to Anthony Jacques for the C code.
  808.  
  809. The latest GEMAES.BH file
  810. ------------------------------------------------------------------------
  811.     Compiled by Paul Jones/Michael Wensley
  812.  
  813. [GEMAES.BH]
  814.  
  815. '  GEMAES.BH 
  816. '  constant file for HiSoft BASIC
  817. ' use defint a-z and option u+
  818.  
  819. 'offsets in bytes for the global array
  820. CONST ap_version=0,ap_count=2,ap_id=4,ap_private=6,ap_ptree=10
  821. ' constants for message types
  822. CONST mn_selected=10,wm_redraw=20,wm_topped=21,wm_closed=22,wm_fulled=23
  823. CONST wm_arrowed=24,wm_hslid=25,wm_vslid=26,wm_sized=27,wm_moved=28
  824. CONST wm_untopped=30,wm_ontop=31
  825. CONST ac_open=40,ac_close=41
  826. CONST ap_term=50,ap_aptfail=51,ap_reschg=57
  827. CONST shut_completed=60,resch_completed=61,ap_dragdrop=63,sh_wdraw=72
  828. CONST ch_exit=80
  829. 'offsets in bytes for OBJECT structure
  830. CONST ob_next=0,ob_head=2,ob_tail=4,ob_type=6,ob_flags=8,ob_state=10
  831. CONST ob_spec=12,ob_x=16,ob_y=18,ob_width=20,ob_height=22
  832. 'offsets in bytes for TEDINFO structure
  833. CONST te_ptext=0,te_ptmplt=4,te_pvalid=8,te_font=12,te_just=16
  834. CONST te_color=18,te_thickness=22,te_txtlen=24,te_tmplen=26
  835. 'offsets in bytes for ICONBLK structure
  836. CONST ib_pmask=0,ib_pdata=4,ib_ptext=8,ib_char=12,ib_xchar=14,ib_ychar=16
  837. CONST ib_xicon=18,ib_yicon=20,ib_wicon=22,ib_hicon=24,ib_xtext=26
  838. CONST ib_ytext=28,ib_wtext=30,ib_htext=32
  839. 'offsets in bytes for BITBLK structure
  840. CONST bi_pdata=0,bi_wb=4,bi_hl=6,bi_x=8,bi_y=10,bi_color=12
  841. 'offsets in bytes for APPLBLK structure
  842. CONST ab_code=0,ab_parm=4
  843. 'offsets in bytes for PARMBLK strucure
  844. CONST pb_tree=0,pb_obj=4,pb_prevstate=6,pb_currstate=8,pb_x=10,pb_y=12
  845. CONST pb_w=14,pb_h=16,pb_xc=18,pb_yc=20,pb_wc=22,pb_hc=24,pb_parm=26
  846. 'OBJECT Types
  847. CONST G_BOX=20,G_TEXT=21,G_BOXTEXT=22,G_IMAGE=23,G_PROGDEF=24,G_IBOX=25
  848. CONST G_BUTTON=26,G_BOXCHAR=27,G_STRING=28,G_FTEXT=29,G_FBOXTEXT=30
  849. CONST G_ICON=31,G_TITLE=32
  850. 'Object flag masks
  851. CONST mask_none=0,mask_selectable=1,mask_default=2,mask_exit=4
  852. CONST mask_editable=8,mask_rbutton=16,mask_lastob=32,mask_touchexit=64
  853. CONST mask_hidetree=128,mask_indirect=256,mask_3d=&h600
  854. ' 3D mask values
  855. CONST fl3dind=&h200,fl3Dback=&h400,fl3dact=&h600
  856. 'Object state masks
  857. CONST mask_normal=0,mask_selected=1,mask_crossed=2,mask_checked=4
  858. CONST mask_disabled=8,mask_outlined=16,mask_shadowed=32
  859. ' constants for wind_create bits
  860. CONST win_name=1,win_close=2,win_full=4,win_move=8,win_info=16,win_size=32
  861. CONST win_uparrow=64,win_dnarrow=128,win_vslide=256,win_lfarrow=512
  862. CONST win_rtarrow=1024,win_hslide=2048,win_all=&hfff
  863. 'constants for wind get and set
  864. CONST wf_name=2,wf_info=3,wf_workxywh=4,wf_currxywh=5,wf_prevxywh=6
  865. CONST wf_fullxywh=7,wf_hslide=8,wf_vslide=9,wf_top=10,wf_firstxywh=11
  866. CONST wf_nextxywh=12,wf_newdesk=14,wf_hslize=15
  867. CONST wf_vslsize=16,wf_screen=17,wf_color=18,wf_dcolor=19,wf_owner=20
  868. CONST wf_bevent=24,wf_bottom=25
  869. 'wind_update constants
  870. CONST END_UPDATE=0,BEG_UPDATE=1,END_MCTRL=2,BEG_MCTRL=3
  871. ' message types for evnt_multi
  872. CONST mu_keybd=1,mu_button=2,mu_m1=4,mu_m2=8,mu_mesag=16,mu_timer=32
  873. CONST type_tree=0,type_object=1,type_string=5,ob_sizeof=24
  874. CONST FMD_START=0, FMD_GROW=1, FMD_SHRINK=2, FMD_FINISH=3
  875. 'objc_sysvar values
  876. CONST lk3dind=1,lk3dact=2,indbutcol=3,actbutcol=4,backgrcol=5,ad3dvalue=6
  877.  
  878. ' end of GEMAES.BH
  879.  
  880. ' additional bits by Paul
  881.  
  882. CONST AP_DRAGDROP=63, DD_OK=0, DD_NAK=1, DD_EXT=2, DD_LEN=3, DD_TRASH=4
  883. CONST DD_PRINTER=5, DD_CLIPBOARD=6
  884. CONST WM_ICONIFY=34, WF_ICONIFY=26, WF_UNICONIFY=27, WF_UNICONIFYXYWH=28
  885. CONST WM_UNICONIFY=35, WM_ALLICONIFY=36
  886.  
  887. Tokenising
  888. ------------------------------------------------------------------------
  889.     By Paul Jones
  890.  
  891. If you include files a lot, which are hardly ever edited, you might 
  892. think about "tokenising" them. This means that the files are compiled 
  893. into a file, and that file is included with the code.
  894.  
  895. To tokenise, create a new blank file. Then cut and paste your listed 
  896. include files to this file. Save the file. Then make sure the 
  897. compilation path and include file options in the dialog box are set to 
  898. nothing. Click on OK, then the same menu, select "dump tokins". These 
  899. will now be compiled and saved to disk.
  900.  
  901. In your main program, when compiling, enter the name of the tokenised 
  902. file in the tokenised path.
  903.  
  904. If you later mess around with your lib files (create another one) and 
  905. try to use tokens, you may get the error "internal error BADRT around 
  906. line <xxx>", in this case you need to re-tokenise your files.
  907.  
  908. In short, tokenised files can save you a lot of compiling time.
  909.  
  910. Sprite mania
  911. ---------------------------------------------------------------------------
  912.     By Paul Jones (example by Michael Wensley)
  913.  
  914. You might like to create a game with HBASIC, and what a good excuse 
  915. it is to have a play! ;-)
  916.  
  917. You can create sprites in a resource editor (such as RSM or Interface) 
  918. and then use them in your programs! The advantage is that GEM will 
  919. automatically find how many colours your system has and display an 
  920. icon nearest to that number of colours.
  921.  
  922. WERCS has trouble with colours icons, and will crash (and even trash 
  923. your RSC file!) if you try to display one in it!
  924.  
  925. If you go into the SPRITE folder, you will find the source code to 
  926. SPRITE.BAS, a little "game" where a icon follows the mouse pointer 
  927. around - an example of a GEM game.
  928.  
  929. At the moment I'm thinking about writing a game library for HBASIC, 
  930. which will include things such as TrueColour sprite displaying 
  931. routines.
  932.  
  933. Another by Michael Wensley.
  934.  
  935. Hex/Oct/Bin/Dec
  936. ---------------------------------------------------------------------------
  937.     By Paul Jones
  938.  
  939. We all know what Decimal is - we use it everyday. It is simply a plain 
  940. number, such as 2. However, programmers, when using large numbers, 
  941. such as memory locations need to use a better system of numbering.
  942.  
  943. A large number such as 652212 is represented in Hexdecimal as 9F3B4. 
  944. As you can see, the second number is smaller - it has a power of 16. 
  945. Octal has has power of 8.
  946.  
  947. Binary is a number system which is used by the computer - 1s and 0s.
  948.  
  949. Here is an example from 0-20 in each form:
  950.  
  951.  ------------------------------------------------------------------
  952. | x  | Decimal (x) | Hexdecimal (&Hx) | Octal (&Ox) | Binary (&Bx) |
  953.  ------------------------------------------------------------------
  954. | 00 |     00      |       00         |      00     |   000000     |
  955. | 01 |     01      |       01         |      01     |   000001     |
  956. | 02 |     02      |       02         |      02     |   000010     |
  957. | 03 |     03      |       03         |      03     |   000011     |
  958. | 04 |     04      |       04         |      04     |   000100     |
  959. | 05 |     05      |       05         |      05     |   000101     |
  960. | 06 |     06      |       06         |      06     |   000110     |
  961. | 07 |     07      |       07         |      07     |   000111     |
  962. | 08 |     08      |       08         |      10     |   001000     |
  963. | 09 |     09      |       09         |      11     |   001001     |
  964. | 10 |     10      |       0A         |      12     |   001010     |
  965. | 11 |     11      |       0B         |      13     |   001011     |
  966. | 12 |     12      |       0C         |      14     |   001100     |
  967. | 13 |     13      |       0D         |      15     |   001101     |
  968. | 14 |     14      |       0E         |      16     |   001110     |
  969. | 15 |     15      |       0F         |      17     |   001111     |
  970. | 16 |     16      |       10         |      20     |   010000     |
  971. | 17 |     17      |       11         |      21     |   010001     |
  972. | 18 |     18      |       12         |      22     |   010010     |
  973. | 19 |     19      |       13         |      23     |   010011     |
  974. | 20 |     20      |       14         |      24     |   010100     |
  975.  ------------------------------------------------------------------
  976.  
  977. A number with &H before it represents a Hexdecimal number, &O for 
  978. Octal and &B for binary. A Decimal number does not need a header.
  979.  
  980. Use HEX$(), BIN$(), VAL() and OCT$() for converted to Hexdecimal, 
  981. Binary, Decimal and Octal respectivly.
  982.  
  983. Blind dates
  984. ---------------------------------------------------------------------------
  985.     By Paul Jones
  986.  
  987. Over the past couple of years, there has been a lot of confusion over 
  988. the millineum problem: what happens to your computer when 2000 comes 
  989. up as the year?
  990.  
  991. For the PC, because most of them use 19xx, where xx is stored in 
  992. memory, when this goes from 99 to 00, the year will be displayed as 
  993. 1900!!
  994.  
  995. The Atari on the other hand uses an offset method, starting from 1980. 
  996. Ie a value of 17 returned from the date function is really 1997. Using 
  997. this method, it is possible to go to 2100.
  998.  
  999. HiSoft BASIC has a bug in it's inbuilt date$ function, the year 2001 
  1000. is returned as 20:1... what's going on? Well, in ASCII the number 
  1001. table goes like 0123456789:;<... change the date to 2021 then display 
  1002. the date the HBASIC. Looks horrid doesn't it?
  1003.  
  1004. Well, this routine gets the date from the GEMDOS function tgetdate% 
  1005. and works perfectly. It also means that you're not resticted to the 
  1006. default American date format!!
  1007.  
  1008. [DATE.BAS]
  1009.  
  1010. LIBRARY "gemdos"
  1011. DEFINT a-z
  1012.  
  1013. a$=BIN$(tgetdate)
  1014. PRINT "HBASIC date:"+DATE$
  1015. PRINT "The REAL date is:"
  1016.  
  1017. day=VAL("&B"+MID$(a$,LEN(a$)-4,5))
  1018. month=VAL("&B"+MID$(a$,LEN(a$)-8,4))
  1019. l=LEN(a$)-9
  1020. year=VAL("&B"+MID$(a$,1,l))
  1021. PRINT day;"/";month;"/";1980+year
  1022.  
  1023.  
  1024. The value returned by tgetdate% is in binary, so first has to be 
  1025. converted, then a number of bits represent data:
  1026.  
  1027. Bits Function
  1028. 0-4  Day 1-31
  1029. 5-8  Month 1-12
  1030. 9-15 Year 0-119 since 1980
  1031.  
  1032. The binary value need to be reversed, you'll find the last 5 bytes the 
  1033. day, the 4 before that are the month and the rest are the year.
  1034.  
  1035. Sources
  1036. ---------------------------------------------------------------------------
  1037.     Compiled by Paul Jones
  1038.  
  1039. These are found in the SOURCE folder:
  1040.  
  1041. COLDIS  .BAS - Displays a "colour circle" displaying the system 
  1042.                colours. By Paul Jones.
  1043. COLOR   .BAS - Starts off as a white screen and fades down to black 
  1044.                using the VDI, useful for a screen saver. By Paul 
  1045.                Jones.
  1046. FSFIRST .BAS - Shows you how to use the GEMDOS command FSFIRST to 
  1047.                retrive an entire directory. By Paul Jones.
  1048. MENUTEST.BAS - With AES v3.3 you can create sub directories in menus, 
  1049.                this gives an example of how to do it. By Paul Jones.
  1050. MULTI   .BAS - Source code to MOD file player (using MODPLAY lib). 
  1051.                Supports VA start. By Paul Jones.
  1052. SPEEDO  .BAS - An example of how to use SpeedoGDOS to display vector 
  1053.                fonts, only works when Speedo/NVDI is installed! By 
  1054.                Paul Jones.
  1055. TPP     .BAS - The Power Protector source code, a program designed for 
  1056.                encryption of files. Buggy, but shows you how it works 
  1057.                ;-) By Paul Jones 1995.
  1058. TRIS    .BAS - The Real Inteligent System. If you've ever used DOS, 
  1059.                then you'll know how boring the command lines are. 
  1060.                Well, TRIS was designed so that you could type in 
  1061.                "TRIS, give me a directory listing of drive D, in the 
  1062.                folder PJCO with the extension .TXT", and it works! I 
  1063.                haven't done anything to it in a while... anyone 
  1064.                willing to continue it? By Paul Jones 1996.
  1065. WWW_CODE.BAS - This code comes from the NeST (NEtwork ST) and is 
  1066.                supposed to be the beginning source code to a HTML 
  1067.                viewer!
  1068. XOR     .BAS - An example of how to encode strings with passwords, by 
  1069.                Paul Jones.
  1070. GIF89A  .BAS - I (Paul Jones) created when I was asked by Matthew 
  1071.                Bacon for his Web.Wizard to get the x and y size of a 
  1072.                GIF file... and here's the result!
  1073.  
  1074. Shareware methods
  1075. ---------------------------------------------------------------------------
  1076.     By Paul Jones
  1077.  
  1078. Shareware is form of release where the programmer retains the 
  1079. copyright to the program, and the program maybe freely distributed 
  1080. like freeware. However, the shareware aspect means that after a 
  1081. certain time of use the user must give the programmer some form of 
  1082. payment (other variations of this are "chocolateware", "postcardware", 
  1083. "contactware" and "emailmailware" but are all related in that they 
  1084. want the programmer to shown some sign of reaction to their shareware 
  1085. notice).
  1086.  
  1087. Some shareware programs have no features disabled, so the user can try 
  1088. out all of the program and "register" if they use the program 
  1089. regualarly. However, we are all very lazy, and Mr. Average (or Mrs.) 
  1090. wouldn't pay money for what they didn't really have too...
  1091.  
  1092. So how do we get around this problem? Well, the common solution is to 
  1093. install a registrion system, where some areas of the program are 
  1094. disabled and when the user registers the program with the user, the 
  1095. programmer gives them a "key" which they type into the program and the 
  1096. actives the before disabled features. Others will have time delays or 
  1097. a registration box popping up ever so often. An example of this is 
  1098. Everest.
  1099.  
  1100. You might have heard of "hackers". These people will try to work 
  1101. something out to change the program without the programmers permission 
  1102. to their own benefit. Some (in the case of games) might try to find a 
  1103. cheat in a program which is imbedded into the compiled game, or in the 
  1104. case of application software try to find your "key" in the program 
  1105. which will be checked against what the user types in to verfify that 
  1106. the program has be registered.
  1107.  
  1108. Because of the way programs are compiled, such things as string can be 
  1109. seen in programs if you use a Disk Editor, such as Knife or DADE. A 
  1110. hacker can go through your program and try to find any strings in the 
  1111. compiled version with a DE and try typing in these for keys.
  1112.  
  1113. For example, if I wrote in my program:
  1114.  
  1115. dummy$="Hello there hacker!"
  1116.  
  1117. A hacker with a Disk Editor would see your little message as some 
  1118. garbage then "Hello there hacker!" without the speech marks! ;-). You 
  1119. could encrypt your password in the program. The hacker then wouldn't 
  1120. be able to tell the difference between the password (which would now 
  1121. look like a load of symbols), and the compiled program.
  1122.  
  1123.  
  1124. So, what could your program do be persuade the user to register. Well, 
  1125. the most obvious is not to supply some features, or disable some. For 
  1126. example for a printing utility only allow the user to print out two 
  1127. documents per program load. On startup you could display a register 
  1128. dialog (like Everest), or after a certain display a "time delay" - a 
  1129. dialog box showing for a certain amount of time so that the user can't 
  1130. do anything else until this box is gone.
  1131.  
  1132. Of course, when the user registers, these "features" go away :-). The 
  1133. idea is to restict the program as much as possible, but making sure 
  1134. the user can try out your software. This might (on the other hand) 
  1135. mean that the user deletes your program all together because he/she 
  1136. was getting annoyed of all those register boxes!
  1137.  
  1138. Back to the drawing board!! :-)
  1139.  
  1140. GEM globalisation
  1141. ---------------------------------------------------------------------------
  1142.     By Paul Jones
  1143.  
  1144. As you might know, the Atari market is being swamped by clones. These 
  1145. clones are not totally compatible with games etc because they use 
  1146. illegal direct hardware registering instead of system calls... 
  1147.  
  1148. All modern programs should not assume that the computer that it's 
  1149. being ran on is an Atari - Atari software now runs on the PC with 
  1150. emulators. For example, art programs. Don't check the hardware 
  1151. registers to find out which screen size/number of colours there are, 
  1152. use the VDI to give you your answer. Likewise, if you're creating a 
  1153. GEM program, don't use GEMDOS to return your keypresses, use the AES's 
  1154. evnt_multi or evnt_keybd.
  1155.  
  1156. Remember if you're trying to get the address of the mouse routines 
  1157. (kbdvbase&+16) or the VBL list, don't assume the address of these 
  1158. lists are always the same - this should be the case for all software.
  1159.  
  1160. Contact and contribution
  1161. ---------------------------------------------------------------------------
  1162.  
  1163. You can email me at paulat.jones@zetnet.co.uk, alternatively you can 
  1164. snail mail me at:
  1165.  
  1166. Paul Jones
  1167. 7 Coppice Close
  1168. Worcestershire
  1169. Droitwich
  1170. WR9 9JD
  1171. United Kingdom
  1172.  
  1173. I welcome any HiSoft BASIC source code, programs you or someone else 
  1174. have created, or text files to be added to the text guide, but I must 
  1175. have permission from the author for it to be included. 
  1176.  
  1177. Contributers
  1178. ---------------------------------------------------------------------------
  1179.  
  1180. In no particular order:
  1181.  
  1182. Paul Jones
  1183.     Email: paulat.jones@zetnet.co.uk
  1184.     URL: http://www.users.zetnet.co.uk/pjones/home.htm
  1185.     Snailmail:
  1186.         7 Coppice Close
  1187.         Droitwich
  1188.         Worcestershire
  1189.         WR9 9JD
  1190.         England
  1191.         United Kingdom
  1192. Michael Wensley
  1193.     Email: send the email to Paul above and he'll pass it on
  1194. Anthony Jacques (who has no interest in HBASIC)
  1195.     Email: jacquesa@zetnet.co.uk
  1196.     Information on SAM for WavePlay lib, C code for AP_TERM 
  1197.     (converted to HBASIC by Paul Jones)
  1198.     
  1199. Copyright status
  1200. ---------------------------------------------------------------------------
  1201.  
  1202. HiSoft BASIC is (c) Copyright 1991 HiSoft. All rights reserved. 
  1203.  
  1204. Where possible, all copyright notices have been recorded and noted. 
  1205. This Disk Compilation is (c) Paul Jones 1997.
  1206.  
  1207. The HBASIC tutorials are (c) Paul Jones/A|C|G 1997.
  1208.  
  1209. The HiSoft BASIC useful routines and documentation guide may not be 
  1210. reproduced, transcribed, stored in a retrieval system, translated into 
  1211. any other languages or transmitted in any form without the consent of 
  1212. Paul Jones or the A|C|G.
  1213.  
  1214. The authors of the software routines cannot be accountable for any 
  1215. damage cause to yourself or the computer in any way.
  1216.  
  1217. All source code contained here in is classed as freeware, this means 
  1218. the author retains copyright of their routine(s) but can be freely 
  1219. used by anyone in their own programs UNLESS STATED.