home *** CD-ROM | disk | FTP | other *** search
/ No Fragments Archive 10: Diskmags / nf_archive_10.iso / MAGS / ST_USER / 1990 / USEROC90.MSA / TEXT_CLINIC.DOC < prev    next >
Text File  |  1990-08-19  |  15KB  |  322 lines

  1.                          PROGRAMMERS' CLINIC
  2.  
  3.  
  4. Questions and answers about Spectrum 512 pictures, bombing programs, and
  5. changing dialog button text make Mathew Lodge's clinic this month. Setting the
  6. double click speed from the AUTO folder also makes a comeback.
  7.  
  8.  
  9. Back To The Double-Click III
  10. ============================
  11.  
  12. A few months ago when the Clinic was still in ST World, I had a query from Pete
  13. Ellis - he wanted to set the GEM double click speed to five using a program in
  14. the AUTO folder to improve mouse response. The general consensus was that you
  15. couldn't do it, but several "workarounds" were presented. Nigel Garvey of
  16. Wellesbourne, Warwickshire has done some research on the problem which is
  17. presented here:
  18.  
  19.     "The way to set or read the double-click speed is to use the AES routine
  20. evnt_dclick, whose parameters are the same as those in the Control Panel. This
  21. would seem to be the answer, but for two problems:
  22.  
  23.     "Firstly, AUTO folder programs run before the AES is activated, so any TRAP
  24. #2 calls just hit a dummy RTE instruction and do nothing. The other problem,
  25. which I only discovered while working on this, is that entering the desktop
  26. automatically sets a default double-click speed of three. Even the saved
  27. Control Panel setting counts for nothing here, as accessories are started up
  28. before the Desktop starts. If the double click speed is set within an
  29. application the new setting will survive until the application quits.
  30. Accessories don't terminate, so leaving them doesn't affect the setting.
  31.  
  32.     "My compromise solution (Program 1), accepts defeat by the desktop, but
  33. automatically sets the double click speed whenever an AES application is run.
  34. It claws its way through a series of parasitic processes, using an idea filched
  35. from HiSoft's replacement file selector, HFSEL.PRG.
  36.  
  37.     "The AUTO part of the program re-routes TRAP #13 BIOS calls through an
  38. intercept routine. This routine waits for a setexc call to be made in
  39. supervisor mode, to reset the critical error handler vector to an address
  40. within the operating system. This is assumed to be the boot process switching
  41. in the GEM error handler, with the implication that the TRAP #2 vector is now
  42. pointing to a working GEM entry point.
  43.  
  44.     "On return from this setexc call, another intercept is hooked up to the
  45. TRAP #2 vector. This one waits for the AES's appl_init function to be called
  46. (normally the first move by any application seeking legitimacy) and smuggles in
  47. an evnt_dclick call under the same exception."
  48.  
  49. -------------------- Program 1 : Set Double Click Speed ----------------------
  50. * ASETDCLK.PRG
  51. * By Nigel Garvey, 8th-26th April 1990
  52. * AUTO folder program to set the mouse double-click time
  53. * Effective only during clickable programs which use the AES
  54.  
  55. * Assembler: DevpacST v.2.08
  56.  
  57. * Double-click time equate.  Set to taste (machine defaults to 3):
  58. dclick_time     EQU 4        Values: 0 (longest) to 4 (shortest)
  59.  
  60. start   BRA     auto_prg     Branch to AUTO-folder bit
  61.  
  62.  
  63. tr13_intcpt
  64. * TRAP #13 calls diverted through here.  Watch for critical error vector
  65. reset:
  66.         BTST    #5,(A7)         Call made from supervisor mode?
  67.         BEQ.S   jmp_bios        Jump straight to BIOS if not
  68.         CMPI.L  #$50101,6(A7)   setexc call re vector #$101?
  69.         BNE.S   jmp_bios        Jump to BIOS if not
  70.         TST.L   10(A7)          Address parameter or read only?
  71.         BMI.S   jmp_bios        Jump to BIOS if read only
  72.         MOVE.L  D0,-(A7)        (Store D0, just in case)
  73.         MOVE.L  10+4(A7),D0     Get address parameter
  74.         CMP.L   $4F2.W,D0       Compare with OS base pointer
  75.         MOVEM.L (A7)+,D0        (Restore D0, preserving CCR flags)
  76.         BLO.S   jmp_bios        Jump if address not in OS
  77.         MOVE.L  2(A7),setxc_out+2  Move ret addr to ch_tr2v exit jump
  78.         MOVE.L  #ch_tr2v,2(A7)  Make ch_tr2v entry the new return addr
  79. jmp_bios        JMP     0000    (dummy) Jump to BIOS
  80.  
  81. ch_tr2v
  82. * The doctored setexc call RTE's to here.  Reset the TRAP #2 vector:
  83.         LEA     tr2_intcpt(PC),A0 Get address of tr2_intcpt routine
  84.         CMPA.L  $88.W,A0         TRAP #2 vector (still) pointing there?
  85.         BEQ.S   setxc_out        Leave alone if so
  86.         MOVE.L  $88.W,jmp_gem+2  Else move GEM addr to exit jump
  87.         MOVE.L  A0,$88.W         Move routine's address to vector
  88. setxc_out       JMP     0000    (dummy) Return from setexc call
  89.  
  90. tr2_intcpt
  91. * TRAP #2 calls diverted through here.  Watch for appl_init:
  92.         CMPI.W  #$C8,D0         AES call?
  93.         BNE.S   jmp_gem         Jump straight to GEM if not
  94.         MOVE.L  A0,-(A7)        (Store A0, just in case)
  95.         MOVEA.L D1,A0           Get call's parameter block address
  96.         MOVEA.L (A0),A0         Find the control array
  97.         CMPI.W  #10,(A0)        appl_init call?
  98.         MOVEA.L (A7)+,A0        (Restore A0, CCR not affected)
  99.         BNE.S   jmp_gem         Jump if not
  100.         MOVE.W  (A7)+,rte_sr    Else store stacked status register
  101.         MOVE.L  (A7)+,rte_addr  Ditto return address
  102.         PEA     do_evdclk(PC)   Substitute do_evdclk address...
  103.         MOVE.W  SR,-(A7)        ...and current SR
  104.         BRA.S   jmp_gem         Do appl_init
  105.  
  106. do_evdclk
  107. * The doctored appl_init call RTE's to here.  Slip in evnt_dclick:
  108.         MOVE.L  #aes_pblk,D1    Address of own parameter block
  109.         MOVE.W  #$C8,D0         AES call code
  110.         MOVE.L  rte_addr(PC),-(A7) Use original return address
  111.         MOVE.W  rte_sr(PC),-(A7) Ditto original SR
  112.  
  113. jmp_gem JMP     0000    (dummy) Jump to GEM
  114.  
  115. * Own AES parameter tables, preset for evnt_dclick:
  116. aes_pblk        DC.L    control,global,int_in,int_out,addr_in,addr_out
  117. control DC.W    26,2,1,0,0
  118. global  DS.W    14
  119. int_in  DC.W    dclick_time,1
  120. int_out DS.W    1
  121. addr_in DS.L    1
  122. addr_out        DS.L    1
  123.  
  124. * Storage for appl_init call RTE info (can't store on super stack):
  125. rte_addr        DS.L    1
  126. rte_sr  DS.W    1
  127.  
  128. auto_prg
  129. * The AUTO-folder program.  Installs and starts the above intercepts
  130. * Inform the user:
  131.         LEA     message_a(PC),A0 Print first part of message -
  132.         BSR.S   print
  133.         LEA     message_b(PC),A0 Get base address of setting strings
  134.         MOVEQ.L #dclick_time,D0 Take the required time setting
  135.         ASL.L   #4,D0           Multiply by 16 (length of strings)
  136.         ADDA.L  D0,A0           Add as offset to base address
  137.         BSR.S   print           Print relevent setting
  138.         LEA     message_c(PC),A0 Print end of message -
  139.         BSR.S   print
  140.  
  141. * Reset the TRAP #13 vector:
  142.         PEA     ch_tr13v(PC)    Address of ch_tr13v subroutine
  143.         MOVE.W  #$26,-(A7)      Perform in supervisor mode (supexec):
  144.         TRAP    #14
  145.         ADDQ.L  #6,A7
  146.  
  147. * Protect the program memory and exit:
  148.         CLR.W   -(A7)           (No errors!)
  149.         MOVE.L  #auto_prg-start+$100,-(A7)  No. of bytes to retain
  150.         MOVE.W  #$31,-(A7)      p_termres
  151.         TRAP    #1
  152.  
  153. ch_tr13v
  154. * Subroutine to revector TRAP #13 calls through tr13_intcpt (above):
  155.         MOVE.L  $B4.W,jmp_bios+2  BIOS address to routine's exit jump
  156.         MOVE.L  #tr13_intcpt,$B4.W Routine's address to TRAP #13 vect
  157.         RTS
  158.  
  159. print
  160. * Subroutine to print out a string to the screen:
  161.         MOVE.L  A0,-(A7)         String address passed in A0
  162.         MOVE.W  #9,-(A7)         c_conws
  163.         TRAP    #1
  164.         ADDQ.L  #6,A7
  165.         RTS
  166.  
  167. message_a       DC.B    13,10,10,"ASETDCLK.PRG    by Nigel Garvey
  168. 1990",13,10,10
  169.         DC.B    "The mouse double-click time will be",13,10
  170.         DC.B    "set at ",0
  171. message_b       DC.B    "0 (longest)",0,0,0,0,0
  172.         DC.B    "1 (longish)",0,0,0,0,0
  173.         DC.B    "2 (medium)",0,0,0,0,0,0
  174.         DC.B    "3 (shortish)",0,0,0,0
  175.         DC.B    "4 (shortest)",0,0,0,0
  176. message_c       DC.B    " during clickable",13,10
  177.         DC.B    "applications which use the AES.",13,10,10,0
  178.         EVEN
  179.  
  180.         END
  181. ------------------------------------------------------------------------------7
  182.  
  183.  
  184. Bombing Out
  185. ===========
  186.  
  187. How many times have you had a program crash and the familiar line of bombs
  188. appear on your screen. As most STers know, the number of bombs tells you what
  189. caused the crash, but you have to look up the reason against the number of
  190. bombs. The next query comes from Jonny Rodin in Harrow, Middlesex, who has been
  191. writing a program to display an English message instead of the bombs.
  192.  
  193.     "The program sometimes fails to intercept the exceptions for some unknown
  194. reason. The program uses the bios 5 call (setexec) to change the exception
  195. vector and terminates with Gemdos 31 (Ptermres or Keep Process). I wonder if
  196. anyone could enlighten me as to the reason why my program fails to work
  197. sometimes or possibly they could give me a solution - the only reason I can
  198. think of is that sometimes the OS decides to reset the vectors. If this is
  199. true, the only solution would probably be to have the program running under
  200. interrupt continuously setting them."
  201.  
  202.  
  203. Paint your ST
  204. =============
  205.  
  206. A.J. Dolan has been trying to display Spectrum 512 and Quantum paint pictures
  207. in their full 512 colour glory. These programs require carefully coded and
  208. timed routines to switch colour palettes at just the right moment.
  209.  
  210.     "Is there anybody who can explain how to achieve stable palette switching
  211. on each scan line, or even parts of one. I have tried many ways, including the
  212. program given by Jonathan Millar in ST World 27, May 88, but none of them give
  213. a completely satisfactory result. It's obvious it can be done, but how?"
  214.  
  215.  
  216. Dialogue Button Text Change
  217. ===========================
  218.  
  219. Les Kneeling, from Ilford, Essex has a reply to the query from Ian McCall about
  220. changing the text in a dialog box in Laser C.
  221.  
  222.     "The ob_spec field of the OBJECT definition (shown below), is indeed a
  223. character pointer to the text to be held in the G_BUTTON. All that is necessary
  224. to put your own text in the button is to redirect this pointer to your own
  225. string. In the event of the new text being longer than the old, it is also
  226. necessary to change the width of the object accordingly. The listing also shows
  227. how to position the object by changing the ob_x and ob_y values.
  228.  
  229.     "Just to show that the Megamax object definition is correct I have
  230. included it in the listing (Program 2) instead of #including the usual
  231. header."
  232.  
  233. ----------------------- Program 2 : Change button text -----------------------
  234. #include <stdio.h>
  235.  
  236. /* The supplied Megamax definition of an object             */
  237. typedef struct object {
  238.     int     ob_next;        /* -> object's next sibling     */
  239.     int     ob_head;        /* -> head of object's children */
  240.     int     ob_tail;        /* -> tail of object's children */
  241.     unsigned int ob_type;   /* type of object- BOX, CHAR,.. */
  242.     unsigned int ob_flags;  /* flags */
  243.     unsigned int ob_state;  /* state- SELECTED, OPEN, ...   */
  244.     char *ob_spec;          /* "out"- -> anything else      */
  245.     int     ob_x;           /* upper left corner of object  */
  246.     int     ob_y;           /* upper left corner of object  */
  247.     int     ob_width;       /* width of obj                 */
  248.     int     ob_height;      /* height of obj                */
  249. } OBJECT;
  250.  
  251. #define TREE00 0    /* Standard information created in RCP              */
  252. #define BUTTON 1
  253.  
  254. unsigned char BUTTONDEF[] = {
  255.     0,0,0,44,0,44,0,44,0,44,0,44,0,36,0,44,0,44,    /* A dialog box     */
  256.     0,92,0,2,0,1,0,0,0,0,0,0,0,0,0,0,0,96,          /* containing a     */
  257.     66,85,84,84,79,78,0,0,255,255,0,1,0,1,0,20,0,0, /* single button    */
  258.     0,16,0,2,17,0,0,0,0,0,0,17,0,3,0,0,255,255,     /* with the text    */
  259.     255,255,0,26,0,39,0,0,0,0,0,36,0,2,0,1,0,13,    /* 'BUTTON' in it   */
  260.     0,1,0,0,0,44
  261. };
  262.  
  263. OBJECT *dialog;                 /* The object pointer                   */
  264.  
  265. char newtext[40] = "A longer piece of text";
  266. /* The new text for the button          */
  267.  
  268. main()
  269. {
  270. appl_init();                        /* Initialise ROMS                  */
  271. mrsrc_load( BUTTONDEF );            /* 'Load' the resource definition   */
  272. rsrc_gaddr(0, TREE00, &dialog );    /* Get the address                  */
  273. dialog[TREE00].ob_x = 20;           /* Position the dialog box on the   */
  274. dialog[TREE00].ob_y = 20;           /* screen                           */
  275. objc_draw( dialog, TREE00, 1, 0, 0, 640, 400 ); /* Show the dialog      */
  276. dialog[TREE00].ob_y = 80;           /* Reposition the dialog box so we  */
  277. dialog[BUTTON].ob_spec = newtext;   /* can see the new text             */
  278. dialog[TREE00].ob_width = 224;      /* Make the boxes wide enough to    */
  279. dialog[BUTTON].ob_width = 192;      /* contain the longer text          */
  280. objc_draw( dialog, TREE00, 1, 0, 0, 640, 400 ); /* Show it again        */
  281. getchar();                          /* Wait                             */
  282. appl_exit();
  283. }
  284. ------------------------------------------------------------------------------
  285.  
  286.     Finally, Jim Taylor of Cleadon, Sunderland has some tips for retrieving
  287. floating point numbers from dialog boxes.
  288.  
  289.     "Like G.A. Cox I encountered the problem of retrieving floating point
  290. numbers from the dialog box. This is quite easily done in BASIC by splitting
  291. the string into a mantissa part and a fractional part, converting them to real
  292. values then adding them together."
  293.  
  294.  
  295. Winding down
  296. ============
  297.  
  298. Keep the letters coming - especially the solutions and comments on other
  299. people's problems and ideas, but don't forget that the clinic depends on your
  300. problems too! Remember to include your full name (or title, if preferred), and
  301. give your phone number if possible.
  302.  
  303.     If you have a listing longer than about 25 lines then please include it on
  304. a disk - I haven't got time to type long listings in. Putting the text of your
  305. letter on disk is doubly helpful - First Word or First Word Plus format if
  306. possible, but straight ASCII is fine. While on the subject of file formats, I
  307. can't decipher tokenised Fast Basic .BSC files - please send an ASCII version.
  308.  
  309.     If you are sending a complete program, then I also like to see it running
  310. before putting it into the column, so please include a double-clickable version
  311. of your program if at all possible. If you want the disk and/or listing back,
  312. also include a stamped addressed envelope. No SAE, no disk.
  313.  
  314. Mathew Lodge
  315. "Programmer's Clinic"
  316. "Maen Melin"
  317. Holmes Chapel Road
  318. Lach Dennis
  319. Northwich
  320. Cheshire
  321. CW9 7SZ
  322.