home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Virtual Reality Zone
/
VRZONE.ISO
/
mac
/
PC
/
REND386
/
JIREND
/
GDC.C
< prev
next >
Wrap
C/C++ Source or Header
|
1993-04-11
|
9KB
|
338 lines
// gdc.c
// Support for Global Devices 3D Controller
// uses serial.c routines
// written by Jerry Isdale and Joe Gradecki
// March 1993
//---------------------------------------------------
// Define TEST to compile as a test program
// Define REND386 to use with REND386
//---------------------------------------------------
#include <stdio.h>
#include <dos.h>
#include <bios.h>
#include "serial.h"
#include "gdc.h"
//---------------------------------------------------
int use_gdc = 0; // global devices controller ball
// set to com port number if to be used
//---------------------------------------------------
unsigned G3D_Mode = GDC_MODE_BYTE1;
int G3D_Port = 2;
// for early GDC versions
//#define SINGLE_MODE
#define GDC_REQUEST_CONFIG 0x8f
//---------------------------------------------------
unsigned char gdc_init( int port )
{
unsigned in;
G3D_Port = port;
com_install ( port, 100, 100 ); // dont need large buffers
com_set_speed ( port, 9600 );
com_set_parity ( port, COM_NONE, 1 );
// NOTE: Request only works on newer boxes (not V0.4)
#ifndef SINGLE_MODE
com_tx ( port, GDC_REQUEST_CONFIG );
while ( (in= com_rx(port)) == '\0' );
G3D_Mode = in;
#endif
return G3D_Mode;
}
unsigned char gdc_set_mode ( unsigned char mode )
{
#ifdef SINGLE_MODE
return TRUE;
#else
unsigned in;
if (G3D_Mode == mode)
return TRUE;
com_tx(G3D_Port, mode+0x50);
while ( (in=com_rx(G3D_Port)) == '\0' )
;
G3D_Mode = in;
if (in == mode)
return 1;
else
return 0;
#endif
}
void gdc_read (unsigned *linear, unsigned *rotation, unsigned *button)
{
unsigned bytea, byteb, bytec;
switch (G3D_Mode)
{
case GDC_MODE_POLLED:
com_tx(G3D_Port, 0x81);
while ( (bytea=com_rx(G3D_Port)) == '\0' );
while ( (byteb=com_rx(G3D_Port)) == '\0' );
while ( (bytec=com_rx(G3D_Port)) == '\0' );
if (linear){
if ( (bytea & 0xC0) == 0x40) *linear = ~bytea & 0x3f;
if ( (byteb & 0xC0) == 0x40) *linear = ~byteb & 0x3f;
if ( (bytec & 0xC0) == 0x40) *linear = ~bytec & 0x3f;
}
if (rotation)
{
if ( (bytea & 0xC0) == 0xC0) *rotation = ~bytea & 0x3f;
if ( (byteb & 0xC0) == 0xC0) *rotation = ~byteb & 0x3f;
if ( (bytec & 0xC0) == 0xC0) *rotation = ~bytec & 0x3f;
}
if (button)
{
if ( (bytea & 0xC0) == 0x80) *button = ~bytea & 0x3f;
if ( (byteb & 0xC0) == 0x80) *button = ~byteb & 0x3f;
if ( (bytec & 0xC0) == 0x80) *button = ~bytec & 0x3f;
}
return;
case GDC_MODE_BYTE3:
bytea=com_rx(G3D_Port);
if ( bytea != '\0' )
{
while ( (byteb=com_rx(G3D_Port)) == '\0' );
while ( (bytec=com_rx(G3D_Port)) == '\0' );
if (linear){
if ( (bytea & 0xC0) == 0x40) *linear = ~bytea & 0x3f;
if ( (byteb & 0xC0) == 0x40) *linear = ~byteb & 0x3f;
if ( (bytec & 0xC0) == 0x40) *linear = ~bytec & 0x3f;
}
if (rotation)
{
if ( (bytea & 0xC0) == 0xC0) *rotation = ~bytea & 0x3f;
if ( (byteb & 0xC0) == 0xC0) *rotation = ~byteb & 0x3f;
if ( (bytec & 0xC0) == 0xC0) *rotation = ~bytec & 0x3f;
}
if (button)
{
if ( (bytea & 0xC0) == 0x80) *button = ~bytea & 0x3f;
if ( (byteb & 0xC0) == 0x80) *button = ~byteb & 0x3f;
if ( (bytec & 0xC0) == 0x80) *button = ~bytec & 0x3f;
}
}
return;
case GDC_MODE_BYTE1:
bytea = com_rx(G3D_Port);
if ( bytea != '\0' )
{
if ( (bytea & 0xC0) == 0x40) // Linear
if (linear) *linear = ~bytea & 0x3f;
if ( (bytea & 0xC0) == 0xC0)
if (rotation) *rotation = ~bytea & 0x3f;
if ( (bytea & 0xC0) == 0x80)
if (button) *button = ~bytea & 0x3f;
}
return;
}
}
void gdc_tactile ( unsigned char intensity, int length )
{
if ( intensity <= 0 )
com_tx(G3D_Port, 0xA0);
else if ( intensity >= 15 )
com_tx(G3D_Port, 0xAF);
else
com_tx(G3D_Port, 0xA0|intensity);
delay ( length );
com_tx(G3D_Port, 0xA0);
}
void gdc_tactile_pulse ( unsigned char time )
{
if ( time <= 0 )
com_tx(G3D_Port, 0xB0);
else if ( time >= 15 )
com_tx(G3D_Port, 0xBF);
else
com_tx(G3D_Port, 0xB0|time);
}
void gdc_remove(void)
{
com_deinstall(G3D_Port);
}
//----------------------------------------------------------
#ifdef TEST
void main()
{
unsigned char status_of_3d;
int linear = 0;
int rotation = 0;
status_of_3d = gdc_init ( 2 ); // com1=1, com2=2, com3=3, com4=4
if (!gdc_set_mode ( GDC_MODE_BYTE1 ))
{
printf("Error Cant set mode!\n");
exit(0);
}
clrscr();
while ( !kbhit() )
{
gdc_read( &linear, &rotation, NULL );
gotoxy(2,14);
printf("Linear: x%0.2x Rotation: x%0.2x\n",linear, rotation);
printf ( " down = %d, up = %d, left = %d, right = %d, ahead = %d, back = %d\n",
(linear & GDC_MOVE_DN)?1:0,
(linear & GDC_MOVE_UP)?1:0,
(linear & GDC_MOVE_LF)?1:0,
(linear & GDC_MOVE_RT)?1:0,
(linear & GDC_MOVE_FW)?1:0,
(linear & GDC_MOVE_BK)?1:0
);
printf ( " rollc = %d, roll = %d, pitchd = %d, pitchu = %d, yawl = %d, yawr = %d\n",
(rotation & GDC_ROLL_CC)?1:0,
(rotation & GDC_ROLL_CW)?1:0,
(rotation & GDC_PITCH_D)?1:0,
(rotation & GDC_PITCH_U)?1:0,
(rotation & GDC_YAW_LEF)?1:0,
(rotation & GDC_YAW_RIT)?1:0
);
delay(50);
}
gdc_tactile_pulse (8);
gdc_remove();
}
#endif //TEST
//----------------------------------------------------------
#ifdef REND386
#include "rend386.h"
#include "intmath.h"
#include "eprint.h"
#include "math.h"
extern long spacestep;
extern int stepsize;
extern VIEW *current_view;
extern int redraw, review;
extern long anglestep;
extern long longitude;
#define to_rad(a) ((a) * 3.14159262 / 180.0)
#define sine(x) sin(to_rad(x/65536L))
#define cosine(x) cos(to_rad(x/65536L))
static unsigned linear_state = 0;
static unsigned rotate_state = 0;
void gdc_UpdatePos(void)
{
gdc_read(&linear_state, &rotate_state, NULL);
// actions as in do_key if !use_old_keys
if (linear_state & GDC_MOVE_DN)
{
current_view->ey -= (stepsize * spacestep);
}
if (linear_state & GDC_MOVE_UP)
{
current_view->ey += (stepsize * spacestep);
}
if (linear_state & GDC_MOVE_LF)
{
current_view->ex -= 2*((stepsize * spacestep) * cosine(current_view->pan));
current_view->ez += 2*((stepsize * spacestep) * sine(current_view->pan));
}
if (linear_state & GDC_MOVE_RT)
{
current_view->ex += 2*((stepsize * spacestep) * cosine(current_view->pan));
current_view->ez -= 2*((stepsize * spacestep) * sine(current_view->pan));
}
if (linear_state & GDC_MOVE_BK)
{
current_view->ex -= 2*((stepsize * spacestep) * sine(current_view->pan));
current_view->ez -= 2*((stepsize * spacestep) * cosine(current_view->pan));
}
if (linear_state & GDC_MOVE_FW)
{
current_view->ex += 2*((stepsize * spacestep) * sine(current_view->pan));
current_view->ez += 2*((stepsize * spacestep) * cosine(current_view->pan));
}
// Rotations use 1/4 size of keyboard
if (rotate_state & GDC_ROLL_CC)
{
current_view->roll -= (stepsize * anglestep)/4;
}
if (rotate_state & GDC_ROLL_CW)
{
current_view->roll += (stepsize * anglestep)/4;
}
if (rotate_state & GDC_PITCH_D)
{
current_view->tilt += (stepsize * anglestep)/4;
}
if (rotate_state & GDC_PITCH_U)
{
current_view->tilt -= (stepsize * anglestep)/4;
}
if (rotate_state & GDC_YAW_LEF)
{
current_view->pan -= (stepsize * anglestep)/4;
}
if (rotate_state & GDC_YAW_RIT)
{
current_view->pan += (stepsize * anglestep)/4;
longitude -= (stepsize * anglestep)/4;
}
if (rotate_state | linear_state)
{
review = redraw = 1;
#ifdef DEBUG
eprintf("Updated from GDC:\n");
eprintf(" View: xyz(%ld %ld %ld)\n",
current_view->ex, current_view->ey, current_view->ez);
eprintf(" View: ptr(%ld %ld %ld)\n",
current_view->pan, current_view->tilt, current_view->roll);
#endif
}
}
#endif // REND386