home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Virtual Reality Zone
/
VRZONE.ISO
/
mac
/
PC
/
PCGLOVE
/
GLOVE
/
OBJGLV.ZIP
/
SRC
/
DEMO4B
/
USERINT
/
JOYSTICK.CPP
next >
Wrap
C/C++ Source or Header
|
1993-05-02
|
4KB
|
172 lines
/* Read the joystick */
/* Written by Bernie Roehl, January 1992 (broehl@sunee.waterloo.edu)
Adapted from code written by ajmyrvold@violet.waterloo.edu (Alan J. Myrvold)
who got technical assistance from : uunet!netxcom!jallen (John Allen)
*/
/* DSmods: - rotate calibration - switch debounce */
#include <stdio.h>
#include <stdlib.h>
#include <dos.h>
#include <bios.h>
#include "userint.hpp" /* for joystick struct */
#include "rend386.hpp" /* for interrupts_occurred */
/* This routine returns two bits; bit 0 on => joystick 1 found, bit 1 => joystick 2 */
int joystick_check()
{
int c, result;
disable();
outportb(0x201,0xff); /* Trigger joystick */
c = inportb(0x201);
c = inportb(0x201);
c = inportb(0x201);
delay(2); /* wait a few milliseconds */
c ^= inportb(0x201); /* any bits that changed state are now set */
enable();
result = 0;
if (c & 0x03) result |= 1;
if (c & 0x0C) result |= 2;
return result;
}
/* This routine reads the joystick, setting x y and buttons */
#define PIC_MASK 0x21
#define IRQ0_MASK 0xFE /* mask for timer int's */
#define PIC_CMD 0x20 /* constants for PIC EOI command */
#define NONSPEC_EOI 0x20
#include "isr.hpp"
int joystick_read(joystick_data *joy)
{
int c, k, jx, jy;
int savemask;
if (joy->port == -1) return 0;
/* mask all but timer IRQ */
disable();
outportb(PIC_MASK,((savemask=inportb(PIC_MASK))|IRQ0_MASK));
outportb(PIC_CMD, NONSPEC_EOI);
enable();
tempISR::resetInterruptsOccurred();
/* interrupts_occurred = 0; /* repeat if timer interrupt! */
do {
if (segaISR::interruptsOccurred()) for (c = 0; c < 1000; c++); /* let it reset */
segaISR::resetInterruptsOccurred();
/* interrupts_occurred = 0; /* repeat if timer interrupt! */
outportb(0x201, 0xff); /* Trigger joystick */
c = inportb(0x201);
if (joy->port) c >>= 2;
joy->buttons = ((~c) >> 4) & 0x0F;
for (k = 0; c & 3; k++) /* Get X and Y positions */
{
if (c & 1) jx = k;
if (c & 2) jy = k;
c = inportb(0x201);
if (joy->port) c >>= 2;
}
}
while (segaISR::interruptsOccurred());
disable();
outportb(PIC_MASK,savemask); // re-enable
enable();
joy->x = jx - joy->cenx;
joy->y = jy - joy->ceny;
if (joy->scale) {
joy->x = (joy->x * joy->scale) / joy->xrange;
joy->y = (joy->y * joy->scale) / joy->yrange;
}
return 1;
}
/* This routine assumes the joystick is centered; sets the port and the
maximum range for the joystick (i.e. minx to maxx) */
void joystick_init(joystick_data *joy, int port)
{
joy->cenx = joy->ceny = 0;
joy->port = port;
joy->scale = 0;
joystick_read(joy);
joy->cenx = joy->x;
joy->ceny = joy->y;
joy->xrange = 2*joy->x;
joy->yrange = 2*joy->y;
}
void joystick_setscale(joystick_data *joy, int value)
{
joy->scale = value;
}
void joystick_quit()
{
}
/* If dir == 0, we're at top left; else, we're at bottom right */
#pragma argsused
void joystick_scale(joystick_data *joy, int dir)
{
long t;
long maxx, maxy, minx, miny;
maxx = maxy = 0;
minx = miny = 10000;
t = joy->scale;
joy->scale = 0;
do {
joystick_read(joy);
if (joy->x > maxx) maxx = joy->x;
if (joy->y > maxy) maxy = joy->y;
if (joy->x < minx) minx = joy->x;
if (joy->y < miny) miny = joy->y;
}
while (joy->buttons == 0);
joy->xrange = maxx - minx;
joy->yrange = maxy - miny;
delay(10);
do {
joystick_read(joy);
}
while (joy->buttons);
delay(10);
joy->scale = t;
}
#ifdef TEST
void main()
{
joystick_data joy;
if (joystick_check())
printf("We found a joystick!\n");
else {
printf("No joy.\n");
exit(0);
}
joystick_init(&joy, 0);
joystick_setscale(&joy, 100);
printf("Move joystick to upper left:\n");
joystick_scale(&joy, 0);
printf("Move joystick to lower right:\n");
joystick_scale(&joy, 1);
do {
joystick_read(&joy);
printf("%d,%d \r", joy.x, joy.y);
}
while (joy.buttons == 0);
}
#endif