home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Virtual Reality Zone
/
VRZONE.ISO
/
mac
/
PC
/
PCGLOVE
/
GLOVE
/
OBJGLV.ZIP
/
SRC
/
DEMO4B
/
JUST3D.CPP
< prev
next >
Wrap
C/C++ Source or Header
|
1993-04-21
|
5KB
|
228 lines
#include <stdio.h>
#include <stdlib.h>
#include <dos.h>
#include <bios.h>
#include <signal.h>
#include <string.h>
#include "segasupp.hpp"
#include "rend386.hpp"
#include "vd2.hpp"
int sega_port_image = 0;
/****************** SWITCHER DRIVER INTERFACE *************/
#define SW_INIT 0
#define SW_QUIT 1
#define SW_ADV_SWITCH 2
#define SW_SYNC_SWITCH 3
#define sub_exit atexit
static int (*switch_driver)(int, int) = NULL;
static void sdriver_quit()
{
if (switch_driver) switch_driver(SW_QUIT, 0);
}
typedef int (*driver_func)(int, int);
Boolean init_switch_driver(char *sdname)
{
if (!stricmp(sdname, "sega"))
{
sub_exit(sega_off);
return True;
}
switch_driver = (driver_func)load_driver(sdname);
if (switch_driver == NULL)
{
fprintf(stderr,"Cannot read switcher driver %s\n", sdname);
return False;
// exit(0);
}
switch_driver = (driver_func)(MK_FP(FP_SEG(switch_driver), 16+FP_OFF(switch_driver))); /* entry point */
switch_driver(SW_INIT, 0);
sub_exit(sdriver_quit);
return True;
}
/********************* SEGA GLASSES CONTROL *****************/
int left_page = 0; /* left image */
int right_page = 1; /* right image */
int has_switched; /* = 3 once both switched in */
static int adv_has_switched = 0;
#define SEGA_LEFT 0x30
#define SEGA_RIGHT 0x20
#define SEGA_OFF 0x00
#define SEGA_MASK 0x30 /* bits writeable for Sega */
#define COMPORT 0x3fc /* com1 = 0x3fc, com2 = 0x2fc */
int sega_left = SEGA_LEFT;
int sega_right = SEGA_RIGHT;
int sega_address = COMPORT;
int sega_mask = SEGA_MASK;
int sega_doff = SEGA_OFF;
static int phase = 1; /* current image */
void select_sega_port(int port)
{
sega_address = port;
}
static void sega_write(int data) /* write Sega data w/o disturbance */
{
disable();
// can also handle glove, Sega on same port
// oops not anymore.
/*****
if (sega_address == glove_out_port)
sega_port_image = port_image =
(port_image & (~sega_mask)) | (data & sega_mask);
else
*****/
sega_port_image = (sega_port_image & (~sega_mask)) | (data & sega_mask);
outportb(sega_address, sega_port_image);
enable();
}
void switch_sega(int to_go) /* now gets arg, sync at 0, 1 = advanced signal */
{ /* 2-step switching ensures adr. load of VGA */
if (switch_driver)
{
if (to_go == 1)
{
if (phase == sega_left)
{
phase = sega_right;
if (switch_driver(SW_ADV_SWITCH, 0) )
set_vpage(right_page);
adv_has_switched = 1;
}
else
{
phase = sega_left;
if (switch_driver(SW_ADV_SWITCH, 1) )
set_vpage(left_page);
adv_has_switched = 2;
}
}
if (to_go == 0)
{
switch_driver(SW_SYNC_SWITCH, (phase == sega_left) ? 1 : 0);
has_switched |= adv_has_switched;
adv_has_switched = 0;
}
}
else
{
if (to_go == 1)
{
if (phase == sega_left)
{
phase = sega_right;
set_vpage(right_page);
adv_has_switched = 1;
}
else
{
phase = sega_left;
set_vpage(left_page);
adv_has_switched = 2;
}
}
if (to_go == 0)
{
sega_write(phase);
has_switched |= adv_has_switched;
adv_has_switched = 0;
}
}
}
void sega_off()
{
sega_write(sega_doff); /* turn glasses driver off to save lcds! */
}
#include "isr.hpp"
#include "timerdef.h"
#define LATCH_COUNT 0x00 // command to latch count
// Time (microseconds) of advance in vert. interrupt. Will act as
// "vertical hold" adjustment.
#define ADVANCE 100
void BaseSegaISR::handleGlasses()
{
frame_interrupt_routine(glovecount-1);
if (--glovecount <= 0) glovecount = glove_rate;
else return;
syncount--;
if (syncount < 0)
{
syncount = SYNC_INTERVAL;
// stop timer
outportb(TIMER_CONTROL, TIMER_MODE);
outportb(TIMER_0, 255);
outportb(TIMER_0, 255);
enable();
disable();
vsync();
// restart timer
outportb(TIMER_CONTROL, TIMER_MODE);
outportb(TIMER_0, clock_rate_lo);
outportb(TIMER_0, clock_rate_hi);
}
}
// BaseSegaISR::findSegaSpeed()
// Routine to compute vertical frame time.
// Call after setting video mode.
//
int BaseSegaISR::findSegaSpeed() // "vertical hold" adjustment
{
// Routine to compute vertical frame
unsigned int sp_old, sp_new;
vsync();
outportb(TIMER_CONTROL, TIMER_MODE);
outportb(TIMER_0, 0);
outportb(TIMER_0, 0); // timer must count modulo 65536
disable(); // time of vert. retrace
vsync();
outportb(TIMER_CONTROL,LATCH_COUNT);
enable();
sp_old = inportb(TIMER_0) & 0xFF;
sp_old |= (inportb(TIMER_0) << 8);
vsync(); // time 2 vert. retraces later
disable();
vsync();
outportb(TIMER_CONTROL,LATCH_COUNT);
enable();
sp_new = inportb(TIMER_0) & 0xFF;
sp_new |= (inportb(TIMER_0) << 8);
return ((sp_old-sp_new)>>1) - ADVANCE; // compute interrupt rate
}