| home
| contents
| previous
| next page
| send comment
| send link
| add bookmark |
input.cpp
/*-------------------------------------------------------------------------*
INPUT.CPP
console input module
by: Stephen R. Schmitt
*-------------------------------------------------------------------------*/
#include <bios.h>
#include <conio.h>
#include <dos.h>
#include <stdio.h>
#include "input.h"
/*-------------------------------------------------------------------------*
* "input" is the class constructor. It determines whether a mouse driver
* is installed and how many buttons the mouse has.
*
* returns: nothing
*/
input::input()
{
union REGS ireg;
ireg.x.ax = 0x00;
int86( 0x33, &ireg, &ireg );
buttons = ireg.x.bx;
present = ireg.x.ax;
delta = 20;
}
/*-------------------------------------------------------------------------*
* "mouse_reset" restores the mouse. It is mainly used when a program
* disables the mouse by writing to the comm port used by the mouse.
*
* returns: nothing
*/
void input::mouse_reset()
{
union REGS ireg;
ireg.x.ax = 0x00;
int86( 0x33, &ireg, &ireg );
buttons = ireg.x.bx;
present = ireg.x.ax;
delta = 20;
}
/*-------------------------------------------------------------------------*
* "mouse_cursor_on" toggles the mouse cursor on. The funtion maintains
* an internal counter that determines whether the cursor is on; if the
* counter is 0, the cursor is on. By calling this function and
* function 0x02, the mouse cursor is switched between on and off.
*
* returns: nothing
*/
void input::mouse_cursor_on()
{
union REGS ireg;
ireg.x.ax = 0x01;
int86(0x33, &ireg, &ireg);
}
/*-------------------------------------------------------------------------*
* "mouse_cursor_off" toggles the mouse cursor off. The function
* decrements the internal cursor counter. Calls to mouse_cursor_on()
* and mouse_cursor_off() should be alternated for things to work
* properly.
*
* returns: nothing
*/
void input::mouse_cursor_off()
{
union REGS ireg;
ireg.x.ax = 0x02;
int86(0x33, &ireg, &ireg);
}
/*-------------------------------------------------------------------------*
* "set_mouse" sets the mouse position. The new values must fall within
* the row-column ranges that have been set. When in the text mode,
* values are rounded to the nearest values permitted.
*
* returns: nothing
*/
void input::set_mouse( int x, // new column
int y ) // new row
{
union REGS ireg;
ireg.x.ax = 0x04;
ireg.x.cx = x * 8;
ireg.x.dx = y * 8;
int86( 0x33, &ireg, &ireg );
}
/*------------------------------------------------------------------------*
* "mouse_move" enables reading the mouse row-col counters.
* Each unit represents about .01 inch and has the range of a signed
* int (about plus/minus 32000). Note that the values returned
* represent the changes in the counts since the last call.
*
* returns: nothing
*/
void input::mouse_move( int *x, // col count
int *y ) // row count
{
union REGS ireg;
ireg.x.ax = 0x0b;
int86(0x33, &ireg, &ireg);
*x = ireg.x.cx;
*y = ireg.x.dx;
}
/*-------------------------------------------------------------------------*
* "read_mouse" obtains the mouse's position and status. On return from
* the interrupt, the following information is available:
*
* ireg.x.bx = button status, where bits 0 and 1 are for the
* left and right buttons. If the button is pressed,
* the bit is 1. If there is a middle button, it
* uses bit 2.
*
* ireg.x.cx = horizontal cursor position
* ireg.x.dx = vertical cursor position
*
* returns: nothing
*/
void input::read_mouse( int *x, // column of mouse cursor
int *y, // row of mouse cursor
int *button ) // status bits
{
union REGS reg;
reg.x.ax = 0x03;
int86( 0x33, ®, ® );
*button = reg.x.bx;
*x = reg.x.cx;
*y = reg.x.dx;
}
/*-------------------------------------------------------------------------*
* "post_key" puts a key press message into the keyboard buffer.
*
* WARNING: The keyboard buffer can hold up to 15 messages and no more.
*
* returns: nothing
*/
void input::post_key( int key ) // the key
{
struct REGPACK reg;
reg.r_ax = 0x05 << 8; // shift 05h into AH
reg.r_cx = key;
intr( 0x16, ® );
}
/*-------------------------------------------------------------------------*
* "xbios_key" returns extended keyboard code for each user key press.
*
* returns: integer corresponding to key.
*/
int input::xbios_key( int op ) // operation selector
{
struct REGPACK reg;
switch( op )
{
case 0: // get next key
reg.r_ax = 0x10 << 8; // shift 10h into AH
intr( 0x16, ® );
return( reg.r_ax );
case 1: // check for key available
reg.r_ax = 0x11 << 8; // shift 11h into AH
intr( 0x16, ®);
if( reg.r_flags & 64 ) // zero flag at 40h
return( 0 );
else
return( reg.r_ax );
case 2: // get special key states
reg.r_ax = 0x12 << 8; // shift 12h into AH
intr( 0x16, ®);
return( reg.r_ax );
}
}
/*-------------------------------------------------------------------------*
* "message" reads the keyboard and mouse for user input. This is
* the user input to the system.
*
* returns: message type code;
* mod indicates whether shift, ctrl, or alt was pressed
*/
unsigned int input::message( int *mod, // keyboard modifier
int *code, // message
int *ampl ) // message amplifier
{
union { int word; unsigned char ch[2]; } key;
int button, msg, mx, my;
*mod = 0;
if( present )
{
while( 1 )
{
read_mouse( &mx, &my, &button );
if( button == 0 )
break;
}
}
while( 1 )
{
if( present )
{
read_mouse( &mx, &my, &button );
*code = mx / 8;
*ampl = my / 8;
if( button == 1 )
return MSG_MOUSE_LF;
else if( button == 2 )
return MSG_MOUSE_RT;
else if( button == 4 )
return MSG_MOUSE_MD;
mouse_move( &mx, &my );
if( mx || my )
{
*code = mx / 8;
*ampl = my / 8;
return MSG_MOUSE_MOVE;
}
}
#ifndef DEBUG_INPUT
key.word = xbios_key( 1 ); // poll the keyboard
if( key.word == 0 )
continue; // no key press
else
#endif
key.word = xbios_key( 0 );
*mod = xbios_key( 2 );
if( key.ch[0] == 224 || key.ch[0] == 0 )
{
*code = key.ch[1] + MAX_ASCII;
msg = MSG_FUNCTION;
}
else if( key.ch[0] )
{
if( *mod & MOD_CTRL )
{
*code = key.ch[0] + CTRL_LETTER;
msg = MSG_FUNCTION;
}
else
{
*code = key.ch[0];
msg = MSG_CHARACTER;
}
}
break;
}
return( msg );
}
| home
| contents
| previous
| next page
| send comment
| send link
| add bookmark |
Copyright © 2004, Stephen R. Schmitt