Path: news.weeg.uiowa.edu!news.uiowa.edu!uunet!usc!wupost!waikato.ac.nz!comp.vuw.ac.nz!actrix!David.Empson Newsgroups: comp.sys.apple2 Subject: Re: PS to mousetext & hyperc Message-ID: <1992Jul24.134358.3132@actrix.gen.nz> From: David.Empson@bbs.actrix.gen.nz Date: Fri, 24 Jul 1992 13:43:58 GMT Sender: David.Empson@actrix.gen.nz (David Empson) References: <9207231157.AA10723@aitgw.ge.com> Organization: Actrix Information Exchange Lines: 135 In article <9207231157.AA10723@aitgw.ge.com> TEFFTA@TSENGR.dnet.ge.com (Andrew Tefft) writes: > > [snip] > > The next obvious question is "how can I tell if a character on the screen > is mousetext?" > > One would need this if they were going to print a pointer-type mouse cursor, > since they would need to restore the character they obliterated after moving > the pointer, and mousetext would probably be used in such displays. > > It seems that there must be some way to preserve the mousetext-ness of > characters on the screen, since mousetext stays mousetext when the screen > scrolls... so there must also be some way to query the mousetext-ness > of a character on the screen, too, no? How do you intend to read characters directly off the screen? There is no way to do this using the 80-column firmware. As far as I know, you'll have to access the screen yourself. You'll therefore need a routine that calculates the address of a screen character, including handling switching between page 1 and 2 for 80-column mode. The following code is (roughly) how you might implement a mouse cursor in ORCA/C on the IIgs. You should be able to adapt this to Hyper C without much trouble (the screen addressing is identical). E-Mail me if you have any questions. You may have difficulty understanding open_screen and close_screen unless you understand how the text screen is addressed. I'm assuming that HyperC will only access a single byte when a character pointer is dereferenced. If it always accesses two bytes, and discards the high byte, then the soft-switch accesses won't work. To use the routines, make an initial call to init_mouse(), then to show_mouse(), hide_mouse() and move_mouse() as appropriate. No routines in your own program should call open_screen() or close_screen(), but other routines may call peek_screen() and poke_screen(). IMPORTANT: make sure the mouse is hidden before you output any text to the screen (or use an input routine), or it may cause the old characters to reappear when the mouse moves. Another point: all of these routines deal with X coordinates in the range 0 to 79 and Y coordinates in the range 0 to 23. Using X or Y values outside these ranges could trash memory at random. Don't try it! If HyperC normally uses 1 to 80 and 1 to 24, you'll need to make some changes to these routines. /******************** Mouse cursor handling routines ****************/ static int mouse_visible; /* TRUE if mouse cursor is on screen */ static int mouse_x, mouse_y; /* mouse cursor coordinates */ static int oldchar; /* the character "under" the cursor */ /* These four macros define the soft-switches used to control the 80-column display. */ #define PAGE1 *((char *)0xC054) #define PAGE2 *((char *)0xC055) #define ON_80STORE *((char *)0xC001) #define OFF_80STORE *((char *)0xC000) #define SCREEN 0x0400 static char *open_screen(int x, int y) { int base, dummy; /* Calculate base address of the line */ base = SCREEN + (y >> 3) * 0x28 + (y & 7) * 0x80; /* Enable 80-column store and select the appropriate page */ ON_80STORE = 0; /* Must WRITE */ if (x & 1) /* Least significant bit set, i.e. ODD number */ dummy = PAGE1; /* odd columns: main memory (page 1) */ else dummy = PAGE2; /* even columns: aux memory (page 2) */ /* Return the address of the character */ return (char *)(base + (y >> 1)); } static void close_screen(void) { int dummy; dummy = PAGE1; /* Reselect page 1 (just in case) */ OFF_80STORE = 0; /* Turn off 80-column store */ } int peek_screen(int x, int y) { int ch; ch = *open_screen(x, y); close_screen(); return ch; } void poke_screen(int x, int y, int ch) { *open_screen(x, y) = ch; close_screen(); } void hide_mouse(void) { if (mouse_visible) { poke_screen(mouse_x, mouse_y, oldchar); mouse_visible = FALSE; } } void show_mouse(void) { if (!mouse_visible) { oldchar = peek_screen(mouse_x, mouse_y); poke_screen(mouse_x, mouse_y, 0x42); /* Mouse arrow */ mouse_visible = TRUE; } } void move_mouse(int x, int y) { int old_visible; old_visible = mouse_visible; if (old_visible) hide_mouse(); mouse_x = x; mouse_y = y; if (old_visible) show_mouse(); } void init_mouse(void) { /* I'm assuming you've already initialized the mouse hardware, clamping, etc. */ mouse_visible = FALSE; mouse_x = mouse_y = 0; } -- David Empson Internet: David.Empson@bbs.actrix.gen.nz EMPSON_D@kosmos.wcc.govt.nz Snail mail: P.O. Box 27-103, Wellington, New Zealand