rott/rott/rt_spbal.c

507 lines
13 KiB
C
Executable File

/*
Copyright (C) 1994-1995 Apogee Software, Ltd.
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include "rt_def.h"
#include "watcom.h"
#include "splib.h"
#include "rt_draw.h"
#include "rt_playr.h"
#include "isr.h"
#include <stdlib.h>
#include "rt_spbal.h"
#include "_rt_spba.h"
#include "sbconfig.h"
#include "rt_main.h"
#include "rt_map.h"
#include "rt_debug.h"
#include "rt_game.h"
#include "rt_str.h"
#include "rt_vid.h"
#include "rt_playr.h"
#include "rt_actor.h"
#include "rt_main.h"
#include "rt_util.h"
#include "rt_draw.h"
#include "rt_in.h"
#include "z_zone.h"
#include "rt_ted.h"
#include "rt_view.h"
#include "develop.h"
#include "version.h"
#include "scriplib.h"
#include <stdlib.h>
#ifdef DOS
#include <conio.h>
#include <io.h>
#include <fcntl.h>
#include <dos.h>
#include <mem.h>
#endif
//MED
#include "memcheck.h"
#ifdef DOS
/* This file and associated .h files and Spaceball libraries:
Copyright 1995 Spacetec IMC Corporation
*/
//static char c[]="Copyright 1995 Spacetec IMC Corporation";
#define MSGN(x) (((x)>0)?1:-1)
#define MABS(x) ((x<0)?(-x):(x))
#define FF(n) FLOAT_TO_FIXED(n)
#define MAX_WARPS 1 // maximum number of ranges in all warps in defaultWarps
static WarpRange defaultWarps[][MAX_WARPS]={
{{ 0, 511, FF(0.00013)}}, // Tx
{{ 0, 511, FF(0.0075 )}}, // Ty
{{ 0, 511, FF(0.0005 )}}, // Tz
{{150, 511, FF(0.0075 )}}, // Rx
{{ 0, 511, FF(0.15 )}} // Ry
};
#undef FF
static WarpRecord defaultRecords[]={
{"Tx", defaultWarps[0], 1},
{"Ty", defaultWarps[1], 1},
{"Tz", defaultWarps[2], 1},
{"Rx", defaultWarps[3], 1},
{"Ry", defaultWarps[4], 1},
};
WarpRecord *WarpTx, *WarpTy, *WarpTz, *WarpRx, *WarpRy;
static char *SpaceBallConfigName = "spwrott.cfg";
static char *ApogeePath = "APOGEECD";
#define TURBO_LIMIT 1000000
static int turbo_increment = 500000,
turbo_count = 0,
turboFire = false;
// sbbuttons mask: 00FE DCBA
#define BUTTON_A 0x01
#define BUTTON_B 0x02
#define BUTTON_C 0x04
#define BUTTON_D 0x08
#define BUTTON_E 0x10
#define BUTTON_F 0x20
// All possible button assignment masks (with defaults)
static
short turboFireMask = BUTTON_A,
attackMask = BUTTON_B,
useMask = BUTTON_C,
mapMask = 0,
swapWeaponMask = BUTTON_D,
singleAxisMask = 0,
planarMask = 0,
aimMask = BUTTON_E,
pauseMask = BUTTON_F;
// Array exists just to make sure two tasks are not assigned to same button
static short *masks[6]={&turboFireMask, &attackMask, &useMask,
&swapWeaponMask, &aimMask, &pauseMask};
//******************************************************************************
//
// ShiftTowardZero ()
//
//******************************************************************************
static short
ShiftTowardZero(short n, short amount)
{
if (MABS(n) >= amount)
return n-((n>0)?amount:-amount);
else
return 0;
}
//******************************************************************************
//
// SPW_SingleAxisFilter
//
// Zeroes all but the largest (in absolute value) element in a RawPacket
//
// returns: nothing
//
//******************************************************************************
static void
SPW_SingleAxisFilter(SpwRawData *p)
{
short *array = &(p->tx), // hope the data are in contigous locations
*largest = array,
newabs, large, array_length = 6;
large = MABS( *array );
while (--array_length > 0) {
++array;
newabs = MABS(*array);
if (newabs > large) {
*largest = 0;
large = newabs;
largest = array;
} else
*array = 0;
}
} /* end of SPW_SingleAxisFilter */
//******************************************************************************
//
// HandleSpaceBallMotion ()
//
//******************************************************************************
static void HandleSpaceBallMotion (SpwRawData * npacket, int controlbuf[])
{
int strafeAngle;
short tx, ty, tz, rx, ry;
long sbtx, sbty, sbtz, sbrx, sbry;
static short ButtonState;
// If they are really cranking on it, limit them to one axis at a time
if ((MABS(npacket->tx) > 450) ||
(MABS(npacket->ty) > 450) ||
(MABS(npacket->tz) > 450) ||
(MABS(npacket->rx) > 450) ||
(MABS(npacket->ry) > 450)) SPW_SingleAxisFilter(npacket);
// Don't want to lose the low end that the sb null_region calc is losing
tx=ShiftTowardZero(npacket->tx,30); // range now approximately +/- 0-480
ty=ShiftTowardZero(npacket->ty,30); // range now approximately +/- 0-480
tz=ShiftTowardZero(npacket->tz,50); // range now approximately +/- 0-460
rx=ShiftTowardZero(npacket->rx,60); // range now approximately +/- 0-450
ry=ShiftTowardZero(npacket->ry,60); // range now approximately +/- 0-450
sbtx = SbFxConfigWarp( WarpTx, tx );
sbty = SbFxConfigWarp( WarpTy, ty );
sbtz = SbFxConfigWarp( WarpTz, tz );
sbrx = SbFxConfigWarp( WarpRx, rx );
sbry = SbFxConfigWarp( WarpRy, ry );
strafeAngle = (player->angle - FINEANGLES/4)&(FINEANGLES-1);
// check for turboFire
if (turboFire)
{
if (MABS(turbo_count) > TURBO_LIMIT)
turbo_increment *= -1;
turbo_count += turbo_increment;
sbry += turbo_increment;
}
controlbuf[0] += -(FixedMul (sbtz, viewcos))+
FixedMul (sbtx, costable[strafeAngle]);
controlbuf[1] += FixedMul (sbtz, viewsin) -
FixedMul (sbtx, sintable[strafeAngle]);
controlbuf[2] += sbry;
// Handle looking up and down ^ flying
ButtonState=npacket->buttons.cur;
// should the user be running?
buttonpoll[bt_run] = true; //((MABS(tx)+MABS(tz)+MABS(ry)) > 320) ? true : false ;
// TY does flying if the user has acquired the ability to fly.
// Currently this is ^'ed with looking up and down
if (player->flags & FL_FLEET)
{
if (sbty != 0)
{
if (sbty > 0)
buttonpoll[bt_lookup ] = true;
else
buttonpoll[bt_lookdown] = true;
}
}
else // Lookup/down || aim up/down ?
{
if ( sbrx != 0 )
{
if (sbrx > 0)
{
if (ButtonState & aimMask)
buttonpoll[bt_horizonup] = true;
else
buttonpoll[bt_lookup] = true;
}
else
{
if (ButtonState & aimMask)
buttonpoll[bt_horizondown] = true;
else
buttonpoll[bt_lookdown] = true;
}
}
}
}
//******************************************************************************
//
// PollSpaceBall ()
//
//******************************************************************************
void PollSpaceBall (void)
{
SpwRawData rawpacket;
short buttonsChanged;
static short buttonState=0;
static int reusePacketNTimes=0;
static SpwRawData lastPacket;
memset(&rawpacket,0,sizeof(rawpacket));
if (SpwSimpleGet(0,&rawpacket))
{
lastPacket=rawpacket;
reusePacketNTimes=6;
}
else if (reusePacketNTimes > 0)
{
rawpacket=lastPacket;
--reusePacketNTimes;
}
else if (buttonState) // did not get a packet but a button is down
rawpacket.buttons.cur=lastPacket.buttons.cur;
else
return;
buttonsChanged=buttonState ^ rawpacket.buttons.cur;
buttonState=rawpacket.buttons.cur;
buttonpoll[bt_attack] = (turboFire = (buttonState & turboFireMask) ? true : false );
if (buttonState & mapMask) DoMap(player->tilex,player->tiley);
if (buttonState & useMask) buttonpoll[bt_use] = true;
if (buttonState & attackMask) buttonpoll[bt_attack] = true;
if (buttonState & swapWeaponMask) buttonpoll[bt_swapweapon] = true;
if (buttonState & singleAxisMask) SPW_SingleAxisFilter(&rawpacket);
if (buttonState & planarMask) rawpacket.ty=rawpacket.rz=rawpacket.rx=0;
if (buttonState & pauseMask) PausePressed=true;
if (!PausePressed) HandleSpaceBallMotion(&rawpacket,controlbuf);
}
//******************************************************************************
//
// OpenSpaceBall ()
//
//******************************************************************************
void OpenSpaceBall (void)
{
int btn;
char filename[ 128 ];
if (SpwSimpleOpen(0))
{
SpwRawData sp;
SpaceBallPresent = true;
printf("Test the Spaceball by moving the ball and/or pressing buttons.\n");
printf("Exit test by pressing any keyboard key...\n");
while(!kbhit())
{
if (SpwSimpleGet(0,&sp))
printf("\r# tx: %4d ty: %4d tz: %4d # rx: %4d ry: %4d rz: %4d # b: %1c-%1c-%1c-%1c-%1c-%1c",
sp.tx, sp.ty, sp.tz,
sp.rx, sp.ry, sp.rz,
sp.buttons.cur & 1 ? 'A':' ', sp.buttons.cur & 2 ? 'B':' ',
sp.buttons.cur & 4 ? 'C':' ', sp.buttons.cur & 8 ? 'D':' ',
sp.buttons.cur & 16 ? 'E':' ', sp.buttons.cur & 32 ? 'F':' ');
}
// Check for configuration file, set defaults if none
GetPathFromEnvironment( filename, ApogeePath, SpaceBallConfigName );
SbConfigParse(filename);
// Check for warp records
WarpTx = SbConfigGetWarpRange("Tx");
WarpTy = SbConfigGetWarpRange("Ty");
WarpTz = SbConfigGetWarpRange("Tz");
WarpRx = SbConfigGetWarpRange("Rx");
WarpRy = SbConfigGetWarpRange("Ry");
if(!WarpTx) WarpTx = &defaultRecords[0];
if(!WarpTy) WarpTy = &defaultRecords[1];
if(!WarpTz) WarpTz = &defaultRecords[2];
if(!WarpRx) WarpRx = &defaultRecords[3];
if(!WarpRy) WarpRy = &defaultRecords[4];
// Check for button assignments
if((btn=SbConfigGetButtonNumber("TURBO_FIRE"))!=-1)
{
if (masks[btn])
*(masks[btn]) = 0; // zero out mask previously assigned to button
masks[btn]= &turboFireMask;
turboFireMask=(short)(1<<btn);
}
if((btn=SbConfigGetButtonNumber("ATTACK"))!=-1)
{
if (masks[btn])
*masks[btn] = 0; // zero out mask previously assigned to button
masks[btn]= &attackMask;
attackMask=(short)(1<<btn);
}
if((btn=SbConfigGetButtonNumber("USE"))!=-1)
{
if (masks[btn])
*masks[btn] = 0; // zero out mask previously assigned to button
masks[btn]= &useMask;
useMask=(short)(1<<btn);
}
if((btn=SbConfigGetButtonNumber("MAP"))!=-1)
{
if (masks[btn])
*masks[btn] = 0; // zero out mask previously assigned to button
masks[btn]= &mapMask;
mapMask=(short)(1<<btn);
}
if((btn=SbConfigGetButtonNumber("SWAP_WEAPON"))!=-1)
{
if (masks[btn])
*masks[btn] = 0; // zero out mask previously assigned to button
masks[btn]= &swapWeaponMask;
swapWeaponMask=(short)(1<<btn);
}
if((btn=SbConfigGetButtonNumber("SINGLE_AXIS_FILTER"))!=-1)
{
if (masks[btn])
*masks[btn] = 0; // zero out mask previously assigned to button
masks[btn]= &singleAxisMask;
singleAxisMask=(short)(1<<btn);
}
if((btn=SbConfigGetButtonNumber("PLANAR_FILTER"))!=-1)
{
if (masks[btn])
*masks[btn] = 0; // zero out mask previously assigned to button
masks[btn]= &planarMask;
planarMask=(short)(1<<btn);
}
if((btn=SbConfigGetButtonNumber("AIM"))!=-1)
{
if (masks[btn])
*masks[btn] = 0; // zero out mask previously assigned to button
masks[btn]= &aimMask;
aimMask=(short)(1<<btn);
}
if((btn=SbConfigGetButtonNumber("PAUSE"))!=-1)
{
if (masks[btn])
*masks[btn] = 0; // zero out mask previously assigned to button
masks[btn]= &pauseMask;
pauseMask=(short)(1<<btn);
}
}
else
{
SpaceBallPresent = false;
}
}
//******************************************************************************
//
// CloseSpaceBall ()
//
//******************************************************************************
void CloseSpaceBall (void)
{
if (SpaceBallPresent)
{
SpwSimpleClose(0);
}
}
//******************************************************************************
//
// GetSpaceBallButtons ()
//
//******************************************************************************
unsigned GetSpaceBallButtons (void)
{
SpwRawData sp;
return ((SpwSimpleGet(0,&sp) & SPW_BUTTON_DOWN));
}
#else
/* This isn't of much use in Linux. */
void PollSpaceBall (void)
{
STUB_FUNCTION;
}
void OpenSpaceBall (void)
{
STUB_FUNCTION;
}
void CloseSpaceBall (void)
{
}
unsigned GetSpaceBallButtons (void)
{
STUB_FUNCTION;
return 0;
}
#endif