***************************************************************************** * * * Graphics Unit For The Mouse * * by * * Jean-Laurent PRADEL * * * * Version 2.0 * * * ***************************************************************************** Introduction ____________ When I test the TP6 for the first time, my biggest disappointment was that it was always impossible to program the mouse in graphic mode ! After few weeks, I found a small book about this under TP5. Just the time for my blood to make a turn in my body and I make my first try... At this time, I had only an old 8088 ! (Yeah, really !!!). Here you will find the result of my thinking and some system handing up ! If you don't want to read immediatly all those details, you can try my demo program which could be programmed in a better way, but it is just here to show you what I did... ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄoÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ Types and Constants In first, there is a type which is used to create the mouse pattern : Type MousePattern = Record InsertX : word; InsertY : word; Pattern : Array [0..15] of String [16]; End; The mouse cursor is a small pattern of 16*16 pixels. The variables InsertX and InsertY define the INSERTION POINT in this pattern; it is the point in the pattern which define the mouse position. The array contains the shape of the cursor. For exemple, the arrow is defined by : Const Arrow : MousePattern = (InsertX: 2; InsertY: 1; Pattern: (' 0 ', ' 020 ', ' 0220 ', ' 02220 ', ' 022220 ', ' 0222220 ', ' 02222220 ', ' 022222220 ', ' 0222222220 ', ' 02222222220 ', ' 0222222000 ', ' 02000220 ', ' 0 0220 ', ' 0220 ', ' 0220 ', ' 00 ')); With my method, there is in the same array the mask and the shape. For that you need 4 caracters : - ' ' (Space Caracter) : The background will be displayed. - '0' : A black point will be displayed (BkColor). - '1' : A white point will be displayed (really white). - '2' : The background will be displayed in the complementary colour. I know that it isn't so easy to see the difference between a 1 and a 2 in the middle of others 0, 1 and 2. But it is really easy to type on the keyboard and easier to read than a set of hexadecimal codes !... ÄÄÄÄÄoÄÄÄÄÄ I thought that it was really boring to create a complete box manager when you get my unit. So I defined an objet : Box = Object MidX, MidY : Integer; Width, Height : Integer; COutLine, CInSide, CText : Integer; TypText : TextSettingsType; Text : String; Constructor Init (x,y,w,h : Integer; co,ci,ct : Integer); Procedure SetText (Ft, Dir, CSize : Integer; txt : String); Procedure Bill; Virtual; Procedure UnBill; Virtual; Procedure Wait (b : Integer); Procedure ChangeColor (co,ci,ct : Integer); Procedure Move (nx,ny : Integer); Procedure ChangeText (Ft, Dir, CSize : Integer; txt : String); Function TestButton (Button : Integer) : Boolean; Destructor Done; Virtual; End; You can define children of this type and change the procedures Bill, UnBill and Done (they are Virtual). The variables are used as follow : MidX and MidY : The coordinates of the middle of the box. Width : The width of the box (hehe!!). Height : The height of the box (hohoho!!). COutSide, CInSide and CText : The colors of the border, the inside and the text of the box. TypText : The text parameters (direction, font, ...). Text : The ... text in the box (Yaouhhh!!!). You can use this type as pointer if you don't forget the lows of the CONSTRUCTOR and the DESTRUCTOR (for this, call your knowledge...). ÄÄÄÄÄoÄÄÄÄÄ After that, I have defined 7 constants for the codes of the buttons and 4 others for predefined cursors: Left, Middle, Right, LeftMiddle, MiddleRight, LeftRight, LeftMiddleRight Arrow, Target, Bomb and QuestionMark. KingOfMouse is a variable which is initialized by the function TestMouse. ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄoÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ Procedures Procedure MouseState(Var dx,dy,button:integer); This procedure brings you back the position of the mouse and the state of the button (see constants). dx and dy are the real coordinates between 0 and 639. In CGA mode, the dx coordinate is gave in the range 0..639 (like in EGA or VGA mode). ÄÄÄÄÄoÄÄÄÄÄ Procedure ChangeMouse(Drawing:MousePattern); This procedure changes the mouse cursor with the variable Drawing. The type MousePattern was explained just before. ÄÄÄÄÄoÄÄÄÄÄ Procedure Show_Mouse; This procedure shows the mouse!!! You must be care, the same procedure exists in the Drivers unit of TurboVision, but it is called "ShowMouse" and not "Show_Mouse"!!! ÄÄÄÄÄoÄÄÄÄÄ Procedure Hide_Mouse; This procedure hides the mouse (yeah, really!)!!! And...? You must be care because blablabla... blabla... blablabla... "HideMouse" blablabla... "Hide_Mouse"!!! Nevertheless, it is important to hide the mouse before drawing anything in the background, if you don't want to see some strange things on the screen. ÄÄÄÄÄoÄÄÄÄÄ Procedure PutMouse(x,y:integer); This procedure moves the mouse to the point (x,y). You don't need to use Hide_Mouse before this procedure (and of course to use Show_Mouse after). ÄÄÄÄÄoÄÄÄÄÄ Procedure WaitButton (Var a,b,button:integer); This procedure waits (!) the user clicks a button and gives you back the coordinates of the mouse at this moment and which button was used. ÄÄÄÄÄoÄÄÄÄÄ Procedure MouseLimits (x1,y1,x2,y2:integer); This procedure defines a box (x1,y1),(x2,y2) out of which the mouse can't go. The upper left corner has (0,0) as coordinates... ÄÄÄÄÄoÄÄÄÄÄ Procedure UnLimitMouse; This procedure deletes the limits made by the procedure MouseLimits. ÄÄÄÄÄoÄÄÄÄÄ Procedure LastPress (Var x,y,number,button:integer); This procedure gives you back some informations about the button "button" : x : last position x of the mouse when "button" was pressed. y : - - y - - - - - - - . number : How many times the "button" has been pressed since the last call to this procedure. button : How are the buttons now... (see constants). ÄÄÄÄÄoÄÄÄÄÄ Procedure LastRelease (Var x,y,button:integer); This procedure gives you back some informations about the button "button". This procedure works like the procedure LastPress. ÄÄÄÄÄoÄÄÄÄÄ Procedure MouseRun (Var a,b:integer); This procedure gives you the moving of the mouse since the last call. Those values are in 1/200 inches (generally called 'mickey'). They are positives from left to right and from top to bottom. ÄÄÄÄÄoÄÄÄÄÄ Procedure MouseSpeed (a,b:integer); This procedure is used to fixe the rate between mickeys and pixels. Those news values must be given in mickeys per 8 pixels (max. 32767). The horizontal default value is 8 and the vertical default value is 16. ÄÄÄÄÄoÄÄÄÄÄ Procedure Box (x,y,l,h,ctour,cint,ctext:word;text:String); This procedure has nothing to do with the mouse, but I think that it is really usefull. It draws a box, centred on (x,y), with a length of l and a height of h. The color of the border is ctour, that of the inside is cint. You can put a text in with the colour ctext. ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄoÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ Functions Function TestMouse:Boolean; This function is the first thing that you MUST do in your initialization procedure. This function tests the driver of the mouse. If there is no driver, the result is False. If there is a driver active, the result is True. More, this function initializes the variable KindOfMouse which gives you the number of buttons on the mouse. ÄÄÄÄÄoÄÄÄÄÄ Function TestButton(x1,y1,x2,y2,button:integer):boolean; This function becames True if the mouse is in the box (x1,y1),(x2,y2) and the button "button" is pressed. In any other case, the function is False. ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄoÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ Object BOX Constructor Box.Init (x,y,w,h : Integer; co,ci,ct : Integer); This procedure is the CONSTRUCTOR of the object, you MUST use it to initialize an object. This just initialize the variables MidX, MidY, Width, Height, COutSide, CInSide and CText. But it also creates the VMT... ÄÄÄÄÄoÄÄÄÄÄ Procedure Box.SetText (Ft, Dir, CSize : Integer; txt : String); This procedure initialize the text of the box : font, direction, size and text. If the text it's too long to fit in the box, then the width and the height are adjusted. ÄÄÄÄÄoÄÄÄÄÄ Procedure Box.Bill; Virtual; This procedure draws the box (...!!). It hides the mouse, draws the box with its colors, restores the currents colors (used by the rest of the program) and shows the mouse. ÄÄÄÄÄoÄÄÄÄÄ Procedure Box.UnBill; Virtual; This procedure undraws the box (huhu!!). Like Box.Bill, this procedure hides the mouse, restores the currents colors and shows the mouse. ÄÄÄÄÄoÄÄÄÄÄ Procedure Box.Wait (b : Integer); Waits that the user clicks in the box with the button 'b' (see constants) ÄÄÄÄÄoÄÄÄÄÄ Procedure Box.ChangeColor (co,ci,ct : Integer); Changes the values of the variables COutSide, CInSide and CText with the news values co, ci, ct and draws the "new" box. ÄÄÄÄÄoÄÄÄÄÄ Procedure Box.Move (nx,ny : Integer); Changes the values MidX and MidY only if the entire box it's always in the screen. ÄÄÄÄÄoÄÄÄÄÄ Procedure Box.ChangeText (Ft, Dir, CSize : Integer; txt : String); Changes the text, tests that the box is big enough (adjust if useful) and draws the "new" box. ÄÄÄÄÄoÄÄÄÄÄ Function Box.TestButton (Button : Integer) : Boolean; Returns 'True' if the 'Button' is pressed in the box. This function doesn't wait, but just make a test "in the run". Very useful to finish the loops Repeat .......... Until "the user click in box". (Really !!!) ÄÄÄÄÄoÄÄÄÄÄ Destructor Box.Done; The DESTRUCTOR ! It just deletes the box and cleans the VMT. It's essential to use it if you make pointers with the type Box. ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄoÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ That 's all !!! That 's all, but not at all!!! This unit is the first thing which lives Bob (Bob is my computer) and my house (euh... my appartment). And of course, it is possible to do better (with my program and with my english !). So, I will be very happy if you send me some echos of what happens with my unit. I already know a "problem"... : When you run Windows, this program changes something in your driver. After that, your driver only recognizes 2 buttons (even if you have a lovely mouse with 3 buttons), and my unit only sees a mouse with 2 buttons !!!. The bigger problem that I know is that my unit doesn't work in SVGA mode. I'm really disappointed by this !!! I don't know the solution (for the moment). If you (yes, YOU) have an idee or if you already program directly a graphic card (by using the interruption 10h), you could help me...! Until May 93: After May 93: Jean-Laurent PRADEL Jean-Laurent PRADEL Im Sohlgraben 1A Ch. Piegros Sud D-3550 MARBURG/CAPPEL Villa Le Sapin Bleu Germany 83170 BRIGNOLES France E-Mail : pidou@astro.chemie.uni-marburg.de Thank you and a lot of fun....................Danke und viele Spaá