/* %kw # %v %n %d %t # */ /* Version # 2 JOYEVENT.C 29-Dec-93 18:03:38 # */ /**********************************************************/ /* METAGRAPHICS SOFTWARE CORPORATION (c) 1993 */ /* */ /* Description: */ /* This program installs an event handler for the joy */ /* stick port on a PC. The handler used by this */ /* sample uses the timer tick interrupt to poll the */ /* joystick. When joystick information changes, an event */ /* is posted. This sample was written using the Borland */ /* conventions for C interrupt handlers. */ /* */ /**********************************************************/ #include #include #include #include #include "metawndo.h" /* special stack size declaration if using Turbo or Borland C++ */ #ifdef TurboC extern unsigned _stklen = 14336U; /* set stack size to 14K */ #endif /*TurboC*/ // prototype for our new handler void interrupt handler(void); // global function pointer for holding old handler void interrupt (*oldhandler)(void); void ReadJoy( int *xpos, int *ypos, int *buttons ); void main() { int i, y; char buf[280]; mwEvent myevent; /* get into VGA graphics mode, mouse driver */ InitGraphics(VGA640x480); SetDisplay( GrafPg0 ); InitMouse( MsDriver ); /* enable queue */ EventQueue(True); MaskEvent( evntALL ); /* install our handler on the timer tick interrupt */ oldhandler = getvect (0x1C); // save original handler address setvect ( 0x1C, handler ); // set new handler /* spin in a loop displaying events */ while ( 1 ) { /* get an event */ i = KeyEvent( False, &myevent ); if( i ) y = 200; /* print real events low */ else y = 20; /* print null events high */ /* exit on a shift-E */ if( myevent.eventChar == 'E' ) break; /* dump out the event */ sprintf( buf, "Time = %4u, Type = %2xh, Source = %2d", myevent.eventTime, myevent.eventType, myevent.eventSource ); MoveTo( 10,y ); DrawString( buf ); sprintf( buf, "Char = %3d, Scan = %4d, State = %4xh", myevent.eventChar, myevent.eventScan, myevent.eventState ); MoveTo( 10,y+20 ); DrawString( buf ); sprintf( buf, "Buttons = %2xh, X = %4d, Y = %4d", myevent.eventButtons, myevent.eventX, myevent.eventY); MoveTo( 10,y+40 ); DrawString( buf ); } /* end of spin loop */ /* clean up and exit */ /* restore original interrupt handler */ setvect ( 0x1C, oldhandler ); SetDisplay( TextPg0 ); StopGraphics(); exit(0); } // our new interrupt handler void interrupt handler(void) { mwEvent intEvent; static int lastx, lasty, lastbutton = 0; int xpos, ypos, buttons; /* chain to original handler */ (*oldhandler)(); ReadJoy( &xpos, &ypos, &buttons ); intEvent.eventChar = 0; intEvent.eventScan = 0; intEvent.eventState = 0; intEvent.eventSource = 5; /* Event source device ID */ // intEvent.eventTime = filled in by StoreEvent() intEvent.eventButtons = buttons; /* Positional device buttons */ intEvent.eventX = xpos; /* Positional device X */ intEvent.eventY = ypos; /* Positional device Y */ // anything change ? if( xpos != lastx || ypos != lasty ) { intEvent.eventType = evntMOVE; StoreEvent( &intEvent ); lastx = xpos; lasty = ypos; } if( buttons != lastbutton ) { if( buttons > lastbutton ) intEvent.eventType = evntPRESS; else intEvent.eventType = evntRELEASE; StoreEvent( &intEvent ); lastbutton = buttons; } } void ReadJoy( int *xpos, int *ypos, int *buttons ) { int i; int watchdog; int starttime, x, y, needx, needy; #define JOY 0x201 #define TIMERDATA 0x40 #define TIMERMODE 0x43 needx = needy = True; // read the current timer 0 time value outp( TIMERMODE, 0 ); // timer 0 latch command starttime = inp( TIMERDATA ); // low byte starttime += inp( TIMERDATA ) << 8; // high byte x = y = starttime; // fire joystick oneshots outp( JOY, 0 ); for( watchdog = 1; watchdog > 0; watchdog++ ) { // read joystick port i = inp( JOY ); if( needx ) { if( (i & 01) == 0 ) { outp( TIMERMODE, 0 ); // timer 0 latch command x = inp( TIMERDATA ); // low byte x += inp( TIMERDATA ) << 8; needx = 0; } } if( needy ) { if( (i & 02) == 0 ) { outp( TIMERMODE, 0 ); // timer 0 latch command y = inp( TIMERDATA ); // low byte y += inp( TIMERDATA ) << 8; // high byte needy = 0; } } if( !(needx || needy) ) break; } // end of watchdog loop x = abs( starttime - x ); y = abs( starttime - y ); // drop the last digit *xpos = (x + 5 ) / 10; *ypos = (y + 5 ) / 10; // invert button state i = ~i; *buttons = i >> 4; }