/***************************************************************************/

Lib Name:     V M O U S E
Rationale:    Implements graphics mouse cursor functionality for (most) of
              the PC EGA/VGA/SVGA video modes.
Use:          For those of you writing heavy-duty DOS-based graphics
              applications or the next hot 3D game and who don't want the
              featuritis-suffering GUIs of today get in your way.
              You may also take advantage of the blitting routines in
              the SVGA package.  Drawing a mouse cursor is merely a
              bitblitting operation with some tweaking...

Dependencies: For the SVGA videomodes it is assumed that VESA 1.2 or VBE 2.0
              is supported either by the hardware or by some suitable TSR such
              as UNIVBE.
              Linear frame buffer mode is supported via the VBE 2.0 interface.
              The Watcom C compiler version 10.0 was used.  A suitable 
              DOS extender such as DOS4GW or PMODEW is required.
Current
     version: 2.2   Mar 1997

Future plans: A scaling mechanism that lets the cursor appear the same
              size on screen regardless of video mode.

Written by:   Arve Holmbo,
              Tors vei 78,
              3472 Bodalen, Norway.
Relevant
    comments
    from you: Can be sent to address above or to arve@igs.no.
Credits:      If your application hits it big, then mention me and send
              me a cheque carrying an appropriate amount :-)
Legal
  disclaimer:

You may distribute and use this software freely.
The software is provided "as is" without warranty of any kind, either
expressed or implied, including, but not limited to, the implied 
warranties of merchantability and fitness for a particular purpose.
The entire risk as to the performance and operation of this product
is with you.  Should the software fail or prove defective, you assume
the cost of all necessary repair or correction.
In no event will the author or any other party who may have distributed
the software be liable to you for damages incurred by its use in any way.



Overall description of the library:
-----------------------------------

This library provides simple, to the bone, mouse cursor support for
most "popular" PC graphics modes including EGA/VGA 16 color (freebee),
the venerable VGA256 (mode 13h) and the more recent SVGA 640x400/480,
800x600, 1024x768 etc modes.

You can use CGA and Hercules if you must, but these modes are channeled
thru the standard Watcom libraries, so performance is like .. slow.

  The source code is included, to provide you with some gold nuggets
(but hopefully no bombs to my knowledge).

  The VMOUSE routines assumes that a set of drawing routines exist
for the currently selected video mode.  This is figured out when 
SVGAinit is called (Either a priori or by VMOUSEinit).  The drawing
functions are located in SVGA.c and its dependants.  For example
VGA16.c takes care of the EGA/VGA 16-color modes.

SVGA.c handles all the drawing primitives for blitting a rectangular
block from main memory to video memory and back for any of the supported
video modes; In short, all that is required to animate a sprite on screen.
See top of SVGA.c for currently supported modes.  Some VGA mode X modes
are supported as well.

Linear frame buffer support is included, not for speed, but because some
applications will be using it.



Description of the VMOUSE library routines:
-------------------------------------------
  VMOUSEinit       to initialize the mouse package.  Note that the
                   init will fail if a requested video mode is not
                   supported.  This function may or may not call SVGAinit.
  VMOUSEshow       to show the cursor
  VMOUSEgetEvent   to read mouse events such as button clicks and coordinates.
                   Mouse events are buffered in a way similar to that of a
                   keyboard driver.
  VMOUSEsetPos     to position the cursor
  VMOUSEhide       to hide cursor
  VMOUSErestore    to restore things to normal on exit.
  VMOUSEinvertCursor  Invert colors of the standard mouse cursors
  VMOUSEsetCursor  to use one of the standard cursors.
  VMOUSEsetCustomCursor  to install a custom cursor.  The format of a
                   mouse cursor is defined by VMOUSEcurShape.

The VMOUSEcurShape structure defines the overall size of the bitmap
that is to contain the cursor bitmap or sprite.  It defines
the width and height of the rectangle and where within that rectangle
to have the hot-spot.  To have a hot-spot in the upper-left corner
of a cursor bitmap, you will use the offset values dx=0,dy=0


Description of some of the important SVGA library routines:
-----------------------------------------------------------
  SVGAinit         Initialises a given video mode and then can attempt to
                   set that mode.
  SVGAdrawBlock    BitBlitting routine that works for the current video
                   mode set by SVGAinit.
  SVGAgetBlock     Opposite of SVGAdrawBlock.  Reads the video memory into
                   your buffer.
  SVGAdrawTranspBlock  BitBlitting of non-zero pixel values to video memory.
  SVGAgetData      Retrieves the status of the currently used video mode.



Changes from version 2.1 and 2.0:
---------------------------------
- Support for more VESA video modes, particularly 320x200, 320x240, and
  32-bit true-color modes.
- Support for animated cursor sequences
- Support for cursor movement via the keyboard if no mouse connected.
- Minor bug fixes and speed enhancements for 16-color modes and mode X.


Changes from version 1.0:
-------------------------
- Video modes for hi-color and true-color modes now supported as well as
  the 256-color 640x400 mode (mode 100hex).
- Linear frame buffer support.  If your application uses it, then so
  can VMOUSE.
- Minor bug-fix to support logical scanline lenghts larger than display
  scanline length.
- Change in the parameters to VMOUSEinit to allow for a more flexible
  initialisation.


Application notes:
------------------
Note that custom cursors will work in any video mode.  Normally a custom
cursor requires one byte per pixel.  This is automatically expanded
to 2- or 3-byte per pixel by the VMOUSE package when a hi-color or
true-color video mode is in use.  When this is the case, the normal
1-byte per pixel mode uses the standard VGA 256-color palette to
convert to 2- or 3-byte pixels.

You have the option to set a custom cursor in hi- or true-color mode
that exploits these modes color capabilities thru' the
VMOUSEsetCustomCurFullColor function. Just bear in mind the bytes per
pixel requiement for these modes.

When using a custom cursor in 16-color modes then bear in mind the
color reduction that has to take place prior to using the cursor.
You can use the SVGAbufferConvert routine to perform this color
reduction from 256- to 16-color.  You can also use SVGAbufferConvert
to reduce a hi-or true-color buffer to a buffer using 256 colors.

Using cursor animation in banked video modes may cause your
machine to hang on exit from the application.  I am not currently
aware of why, but suspect there may be a cockup with a real-mode
to protected-mode switch or vice versa that might occur while the
CPU is executing an interrupt service routine.

When your application is done, then VMOUSErestore() should be called
to reset things to a 'normal' state.  See the sample application below.



Typical application prototype:
------------------------------

#include <stdlib.h>
#include <graph.h>
#include <vmouse.h>

// Uses default cursor within a rectangle in SVGA 800x600 256 color mode
// Rectangle: llc = (100,200), urc = (400,100)
void someFunc( )
{
  int  x, y;
  uint event;
  short mode = _SVRES256COLOR;
  VMOUSEinitType init;

  init.UseWatcomLib = FALSE;
  init.UseLFB = FALSE;
  init.SetVideoMode = TRUE;  /* minx maxx miny maxy */
  if ( VMOUSEinit( mode, &init, 100, 400, 100, 200 ) == EXIT_FAILURE )
  {
    _setvideomode(3);
    printf("Sorry, I couldn't.\n");
    return;
  }

  VMOUSEshow();    /* Show the default cursor */
  for (;;)  // Event loop
  {
    // The VMOUSEgetEvent function will draw the cursor automatically
    // if the user has moved the mouse.
    // This means that the cursor will 'hang' if the application
    // does some heavy calculations for a while.
    // You can keep the cursor moving by turning on animation
    // via the VMOUSEanimate* functions
    // Anyways, VMOUSEgetEvent will return the mouse cursor position
    // in (x, y) and any button event.
    //
    if (( event = VMOUSEgetEvent( &x, &y )) == VMOUSErightPres )
      break;      // Exit when user presses right mouse button
    // Do something here
    if ( event & VMOUSEleftPres && x == 200 && y == 200 )
    {
      VMOUSEsetCursor( VMOUSEcurCrossHair );   // change cursor shape
    }
  }
  VMOUSErestore();
  _setvideomode(3);
}



The sample application: mus.exe
-------------------------------
The accompanying application shows some mouse cursors for any video
mode supported by this library.
Examples:  mus 18  displays an image at 640x480 @ 16 color.
           mus 261 displays an image at 1024x768 @ 256 color
           mus 279 displays an image at 1024x768 in true-color mode
If your graphics card supports linear frame buffer mode, then
you can use this by running
           mus <mode number> 1
Sorry for the awkward commandline.
The application has a couple of buttons to browse thru' the built-in
cursors and to start a demo cursor animation sequence.



How to link your application to the VMOUSE library:
---------------------------------------------------
THe name of the provided library is either vmouse.lib or
services.lib.  This library contain all the code to get you
going.  Also provided is a small sample application to demonstrate
the use of the VMOUSE library.

The code is organized as a library in vmouse.lib/services.lib that
is created by running wmake -u -f make.lib.  Then there is a sample
application mus.exe that is made by running wmake -u.

Make sure your path variables are set properly:

set LIB=<directory of Watcom libraries>;<directory of vmouse/services.lib>
set INCLUDE=<directory of Watcom include files>;<directory of vmouse includes>

Example:

set INCLUDE=C:\WATCOM\H;d:\wc\serv
set LIB=C:\WATCOM\LIB386;d:\wc\serv


The code in the VMOUSE library has been compiled with the following
compiler switches: 
CFLAGS= -zp4 -zq -bt=dos4g -j -s -e4 -oneatx -5 -fp3
#CFLAGS= -zp4 -zq -bt=dos4g -j -s -e4 -5 -fp3 -d2

The compile/link switches in the makefiles show the correct ones if
different from those shown in this text.
Example application makefile  (Use wmake /u to run it):

#
# Run wcc386 /help to see all the compiler switches
# mus happened to be my test application.  Insert the name
# of your own.
#
CC=wcc386
CFLAGS= -zp4 -zq -bt=dos4g -j -s -e4 -oneatx -5 -fp3
LFLAGS=
#LFLAGS=debug all

COBJ= \
  mus.obj button.obj ...

.c.obj : .AUTODEPEND
        $(CC) $(CFLAGS) $*.c

mus.exe : $(COBJ)
  wlink $(LFLAGS) @ mus.lnk




Example file mus.lnk used in the makefile (Note path of the VMOUSE library):

system dos4g
#option map
name   mus
file   mus,button,ball
library services



/* EOF vmouse.txt */
