mirror of
https://github.com/kevinbentley/Descent3.git
synced 2025-01-22 11:28:56 +00:00
917 lines
33 KiB
C++
917 lines
33 KiB
C++
/*
|
|
* $Logfile: /DescentIII/Main/ddio_mac/macController.cpp $
|
|
* $Revision: 1.1.1.1 $
|
|
* $Date: 2003/08/26 03:56:55 $
|
|
* $Author: kevinb $
|
|
*
|
|
* Keyboard IO for macintosh
|
|
*
|
|
* $Log: macController.cpp,v $
|
|
* Revision 1.1.1.1 2003/08/26 03:56:55 kevinb
|
|
* initial 1.5 import
|
|
*
|
|
*
|
|
* 5 4/12/00 6:52p Matt
|
|
* From Duane for 1.4: deadzone stuff
|
|
*
|
|
* 4 3/20/00 12:43p Matt
|
|
* Merge of Duane's post-1.3 changes.
|
|
*
|
|
* 3 10/21/99 3:33p Jeff
|
|
* Macintosh merges
|
|
*
|
|
* 2 7/28/99 3:31p Kevin
|
|
* Mac Stuff!
|
|
*
|
|
* 4 5/21/97 5:17 PM Jeremy
|
|
* switch keyboard controls to default values of PC (still need to
|
|
* implement needs/controls structure)
|
|
*
|
|
* 3 5/15/97 1:43 AM Jeremy
|
|
* changed mprintf's to be standard (with newline at end)
|
|
*
|
|
* 2 5/13/97 11:45 AM Jeremy
|
|
* implementation for gameMacController object as well as create/destroy
|
|
* controller object (still stubbed out)
|
|
*
|
|
* 1 5/11/97 8:09 PM Jeremy
|
|
* Initial check in
|
|
*
|
|
* $NoKeywords: $
|
|
*/
|
|
// ----------------------------------------------------------------------------
|
|
// Keyboard Interface
|
|
// ----------------------------------------------------------------------------
|
|
// ANSI Headers
|
|
#include <stdlib.h>
|
|
#include <math.h>
|
|
|
|
// Macintosh Headers
|
|
#include <Events.h>
|
|
#include <InputSprocket.h>
|
|
#include "InSprocket.h"
|
|
// Descent 3 Headers
|
|
#include "pserror.h"
|
|
#include "mono.h"
|
|
#include "macController.h"
|
|
#include "Controller.h"
|
|
#include "controls.h"
|
|
#include "ddio_common.h"
|
|
#include "ddio.h"
|
|
#include "hud.h"
|
|
|
|
#define SIGN(a) ((a < 0) ? -1 : 1)
|
|
|
|
typedef struct {
|
|
ubyte pcAction;
|
|
ubyte isEvent;
|
|
} PC_IS_Map;
|
|
PC_IS_Map m_pc_is_map[] = {{ctfFORWARD_THRUSTAXIS, kInputEvent_None},
|
|
{ctfFORWARD_THRUSTKEY, kInputEvent_None},
|
|
{ctfREVERSE_THRUSTKEY, kInputEvent_None},
|
|
{ctfUP_THRUSTAXIS, kInputEvent_None},
|
|
{ctfUP_THRUSTKEY, kInputEvent_None},
|
|
{ctfDOWN_THRUSTKEY, kInputEvent_None},
|
|
{ctfRIGHT_THRUSTAXIS, kInputEvent_None},
|
|
{ctfRIGHT_THRUSTKEY, kInputEvent_None},
|
|
{ctfLEFT_THRUSTKEY, kInputEvent_None},
|
|
{ctfPITCH_DOWNAXIS, kInputEvent_None},
|
|
{ctfPITCH_DOWNKEY, kInputEvent_None},
|
|
{ctfPITCH_UPKEY, kInputEvent_None},
|
|
{ctfBANK_RIGHTAXIS, kInputEvent_None},
|
|
{ctfBANK_RIGHTKEY, kInputEvent_None},
|
|
{ctfBANK_LEFTKEY, kInputEvent_None},
|
|
{ctfHEADING_RIGHTAXIS, kInputEvent_None},
|
|
{ctfHEADING_RIGHTKEY, kInputEvent_None},
|
|
{ctfHEADING_LEFTKEY, kInputEvent_None},
|
|
{ctfFIREPRIMARY_BUTTON, kInputEvent_FirePrim_On},
|
|
{ctfFIREPRIMARY_KEY, kInputEvent_None},
|
|
{ctfFIREPRIMARY_KEY2, kInputEvent_None},
|
|
{ctfFIRESECONDARY_BUTTON, kInputEvent_FireSecond_On},
|
|
{ctfFIRESECONDARY_KEY, kInputEvent_None},
|
|
{ctfTOGGLE_SLIDEKEY, kInputEvent_None},
|
|
{ctfTOGGLE_SLIDEBUTTON, kInputEvent_Slide_On},
|
|
{ctfFIREFLARE_KEY, kInputEvent_None},
|
|
{ctfFIREFLARE_BUTTON, kInputEvent_Flare},
|
|
{ctfUP_BUTTON, kInputEvent_SlideUp_On},
|
|
{ctfDOWN_BUTTON, kInputEvent_SlideDown_On},
|
|
{ctfLEFT_BUTTON, kInputEvent_SlideLeft_On},
|
|
{ctfRIGHT_BUTTON, kInputEvent_SlideRight_On},
|
|
{ctfAFTERBURN_KEY, kInputEvent_None},
|
|
{ctfAFTERBURN_BUTTON, kInputEvent_AfterBurn_On},
|
|
{ctfFORWARD_BUTTON, kInputEvent_Accelerate_On},
|
|
{ctfREVERSE_BUTTON, kInputEvent_Reverse_On},
|
|
{ctfTOGGLE_BANKKEY, kInputEvent_None},
|
|
{ctfTOGGLE_BANKBUTTON, kInputEvent_Bank_On},
|
|
{ctfHEADING_LEFTBUTTON, kInputEvent_TurnLeft_On},
|
|
{ctfHEADING_RIGHTBUTTON, kInputEvent_TurnRight_On},
|
|
{ctfPITCH_UPBUTTON, kInputEvent_PitchUp_On},
|
|
{ctfPITCH_DOWNBUTTON, kInputEvent_PitchDown_On},
|
|
{ctfBANK_LEFTBUTTON, kInputEvent_BankLeft_On},
|
|
{ctfBANK_RIGHTBUTTON, kInputEvent_BankRight_On},
|
|
{ctfAUTOMAP_KEY, kInputEvent_None},
|
|
{ctfPREV_INVKEY, kInputEvent_None},
|
|
{ctfNEXT_INVKEY, kInputEvent_None},
|
|
{ctfINV_USEKEY, kInputEvent_None},
|
|
{ctfPREV_CNTMSKEY, kInputEvent_None},
|
|
{ctfNEXT_CNTMSKEY, kInputEvent_None},
|
|
{ctfCNTMS_USEKEY, kInputEvent_None},
|
|
{ctfHEADLIGHT_KEY, kInputEvent_None},
|
|
{ctfHEADLIGHT_BUTTON, kInputEvent_HeadLight},
|
|
{ctfAUTOMAP_BUTTON, kInputEvent_Map},
|
|
{ctfPREV_INVBTN, kInputEvent_InventoryPrev},
|
|
{ctfNEXT_INVBTN, kInputEvent_InventoryNext},
|
|
{ctfINV_USEBTN, kInputEvent_InventoryUse},
|
|
{ctfPREV_CNTMSBTN, kInputEvent_CounterPrev},
|
|
{ctfNEXT_CNTMSBTN, kInputEvent_CounterNext},
|
|
{ctfCNTMS_USEBTN, kInputEvent_CounterUse},
|
|
{ctfWPNSEL_PCYCLEKEY, kInputEvent_None},
|
|
{ctfWPNSEL_PCYCLEBTN, kInputEvent_NextPrim},
|
|
{ctfWPNSEL_SCYCLEKEY, kInputEvent_None},
|
|
{ctfWPNSEL_SCYCLEBTN, kInputEvent_NextSecond},
|
|
{ctfREARVIEW_KEY, kInputEvent_None},
|
|
{ctfREARVIEW_BTN, kInputEvent_RearView_On},
|
|
{ctfAUDIOTAUNT1_KEY, kInputEvent_None},
|
|
{ctfAUDIOTAUNT1_BTN, kInputEvent_ATaunt1},
|
|
{ctfAUDIOTAUNT2_KEY, kInputEvent_None},
|
|
{ctfAUDIOTAUNT2_BTN, kInputEvent_ATaunt2},
|
|
{ctfAUDIOTAUNT3_KEY, kInputEvent_None},
|
|
{ctfAUDIOTAUNT3_BTN, kInputEvent_ATaunt3},
|
|
{ctfAUDIOTAUNT4_KEY, kInputEvent_None},
|
|
{ctfAUDIOTAUNT4_BTN, kInputEvent_ATaunt4}};
|
|
inline ubyte ConvertPC_IS(ubyte action) {
|
|
if (m_pc_is_map[action].pcAction == action) {
|
|
return m_pc_is_map[action].isEvent;
|
|
} else {
|
|
for (int i = 0; i < NUM_CONTROLLER_FUNCTIONS; i++) {
|
|
if (m_pc_is_map[i].pcAction == action) {
|
|
return m_pc_is_map[i].isEvent;
|
|
}
|
|
}
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
struct {
|
|
float DownTime;
|
|
float UpTime;
|
|
bool state;
|
|
} iSbutton[kNumEvents];
|
|
|
|
gameMacController::gameMacController(int num_funcs, ct_function *gameFunctions, char *remote_adr)
|
|
: gameController(num_funcs, gameFunctions) {
|
|
for (int i = 0; i < kNumEvents; i++) {
|
|
iSbutton[i].DownTime = 0.0;
|
|
iSbutton[i].UpTime = 0.0;
|
|
iSbutton[i].state = false;
|
|
}
|
|
// inSprocket_Init();
|
|
|
|
enum_controllers(remote_adr);
|
|
for (int i = 0; i < num_funcs; i++)
|
|
assign_function(&gameFunctions[i]);
|
|
m_Suspended = 0;
|
|
// m_frame_timer_ms = -1;
|
|
// m_frame_time = 1.0f;
|
|
// m_ControlList[MC_JOY].deadzone = 8;
|
|
|
|
gameMacController::flush();
|
|
}
|
|
gameMacController::~gameMacController(void) {
|
|
// inSprocket_Exit();
|
|
}
|
|
// these functions suspend or resume any controller reading. this is really only useful for
|
|
// preemptive controller polling, but they should be used to activate and deactivate controller
|
|
// reading.
|
|
void gameMacController::suspend() {
|
|
inSprocket_Activate(false);
|
|
|
|
for (int i = 0; i < kNumEvents; i++) {
|
|
iSbutton[i].DownTime = 0.0;
|
|
iSbutton[i].UpTime = 0.0;
|
|
iSbutton[i].state = false;
|
|
}
|
|
}
|
|
void gameMacController::flush() {
|
|
InSprocket_Flush();
|
|
for (int i = 0; i < kNumEvents; i++) {
|
|
iSbutton[i].DownTime = 0;
|
|
iSbutton[i].UpTime = 0;
|
|
iSbutton[i].state = false;
|
|
}
|
|
}
|
|
|
|
void gameMacController::resume() { inSprocket_Activate(true); }
|
|
// this functions polls the controllers if needed. some systems may not need to implement
|
|
// this function.
|
|
#define IS_MOUSE 0
|
|
#define IS_JOY 1
|
|
|
|
float is_mouse[6];
|
|
int is_joy[6];
|
|
void MacInSprocketHandler(void) {
|
|
TInputEvent iSevent;
|
|
|
|
float cur_time = timer_GetTime();
|
|
|
|
is_mouse[kNeed_Yaw] = inSprocket_GetMouse(kNeed_Yaw);
|
|
is_mouse[kNeed_Pitch] = inSprocket_GetMouse(kNeed_Pitch);
|
|
is_mouse[kNeed_Roll] = inSprocket_GetMouse(kNeed_Roll);
|
|
is_mouse[kNeed_MoveX] = inSprocket_GetMouse(kNeed_MoveX);
|
|
is_mouse[kNeed_MoveZ] = inSprocket_GetMouse(kNeed_MoveZ);
|
|
is_mouse[kNeed_MoveY] = inSprocket_GetMouse(kNeed_MoveY);
|
|
is_joy[kNeed_Yaw] = inSprocket_GetAxisInt(kNeed_Yaw);
|
|
is_joy[kNeed_Pitch] = inSprocket_GetAxisInt(kNeed_Pitch);
|
|
is_joy[kNeed_Roll] = inSprocket_GetAxisInt(kNeed_Roll);
|
|
is_joy[kNeed_MoveX] = inSprocket_GetAxisInt(kNeed_MoveX);
|
|
is_joy[kNeed_MoveZ] = inSprocket_GetAxisInt(kNeed_MoveZ);
|
|
is_joy[kNeed_MoveY] = inSprocket_GetAxisInt(kNeed_MoveY);
|
|
|
|
while ((iSevent = inSprocket_GetButtonEvent()) != kInputEvent_None) {
|
|
switch (iSevent) {
|
|
case kInputEvent_Accelerate_On:
|
|
case kInputEvent_Reverse_On:
|
|
case kInputEvent_SlideLeft_On:
|
|
case kInputEvent_SlideRight_On:
|
|
case kInputEvent_SlideUp_On:
|
|
case kInputEvent_SlideDown_On:
|
|
case kInputEvent_BankLeft_On:
|
|
case kInputEvent_BankRight_On:
|
|
case kInputEvent_TurnLeft_On:
|
|
case kInputEvent_TurnRight_On:
|
|
case kInputEvent_PitchUp_On:
|
|
case kInputEvent_PitchDown_On:
|
|
case kInputEvent_FirePrim_On:
|
|
case kInputEvent_FireSecond_On:
|
|
iSbutton[iSevent].state = true;
|
|
if (iSbutton[iSevent].DownTime == 0.0)
|
|
iSbutton[iSevent].DownTime = cur_time;
|
|
break;
|
|
|
|
case kInputEvent_Accelerate_Off:
|
|
case kInputEvent_Reverse_Off:
|
|
case kInputEvent_SlideLeft_Off:
|
|
case kInputEvent_SlideRight_Off:
|
|
case kInputEvent_SlideUp_Off:
|
|
case kInputEvent_SlideDown_Off:
|
|
case kInputEvent_BankLeft_Off:
|
|
case kInputEvent_BankRight_Off:
|
|
case kInputEvent_TurnLeft_Off:
|
|
case kInputEvent_TurnRight_Off:
|
|
case kInputEvent_PitchUp_Off:
|
|
case kInputEvent_PitchDown_Off:
|
|
case kInputEvent_FirePrim_Off:
|
|
case kInputEvent_FireSecond_Off:
|
|
iSbutton[iSevent - 1].state = false;
|
|
iSbutton[iSevent - 1].UpTime = cur_time;
|
|
break;
|
|
|
|
case kInputEvent_CounterUse:
|
|
case kInputEvent_CounterNext:
|
|
case kInputEvent_CounterPrev:
|
|
case kInputEvent_InventoryUse:
|
|
case kInputEvent_InventoryNext:
|
|
case kInputEvent_InventoryPrev:
|
|
case kInputEvent_NextPrim:
|
|
case kInputEvent_NextSecond:
|
|
case kInputEvent_Map:
|
|
case kInputEvent_Flare:
|
|
case kInputEvent_HeadLight:
|
|
case kInputEvent_Bank_On:
|
|
case kInputEvent_Slide_On:
|
|
case kInputEvent_AfterBurn_On:
|
|
case kInputEvent_RearView_On:
|
|
iSbutton[iSevent].state = true;
|
|
break;
|
|
case kInputEvent_Bank_Off:
|
|
case kInputEvent_Slide_Off:
|
|
case kInputEvent_AfterBurn_Off:
|
|
case kInputEvent_RearView_Off:
|
|
iSbutton[iSevent - 1].state = false;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
void gameMacController::poll() {
|
|
// TInputEvent iSevent;
|
|
// extern float Frametime;
|
|
/*
|
|
float cur_time = timer_GetTime();
|
|
|
|
// while((iSevent = inSprocket_GetEvent()) != kInputEvent_None) {
|
|
for(int i = 0; i < kNumEvents; i++) {
|
|
switch(i) {
|
|
case kInputEvent_SlideLeft_On:
|
|
mprintf((1, "ln %f %f\n", iSbutton[i].UpTime, iSbutton[i].DownTime));
|
|
break;
|
|
}
|
|
switch(i) {
|
|
case kInputEvent_EnergyShield_Off:
|
|
case kInputEvent_Accelerate_Off:
|
|
case kInputEvent_Reverse_Off:
|
|
case kInputEvent_SlideLeft_Off:
|
|
case kInputEvent_SlideRight_Off:
|
|
case kInputEvent_SlideUp_Off:
|
|
case kInputEvent_SlideDown_Off:
|
|
case kInputEvent_BankLeft_Off:
|
|
case kInputEvent_BankRight_Off:
|
|
case kInputEvent_TurnLeft_Off:
|
|
case kInputEvent_TurnRight_Off:
|
|
case kInputEvent_PitchUp_Off:
|
|
case kInputEvent_PitchDown_Off:
|
|
iSbutton[i-1].UpTime = cur_time;
|
|
break;
|
|
case kInputEvent_Flare:
|
|
case kInputEvent_Bomb:
|
|
case kInputEvent_Map:
|
|
case kInputEvent_NextPrim:
|
|
case kInputEvent_PrevPrim:
|
|
case kInputEvent_NextSecond:
|
|
case kInputEvent_PrevSecond:
|
|
case kInputEvent_HeadLight:
|
|
case kInputEvent_Bank_On:
|
|
case kInputEvent_Slide_On:
|
|
case kInputEvent_FirePrim_On:
|
|
case kInputEvent_FireSecond_On:
|
|
case kInputEvent_AfterBurn_On:
|
|
case kInputEvent_RearView_On:
|
|
case kInputEvent_CounterPrev:
|
|
if(iSbutton[i].DownTime != 0.0)
|
|
iSbutton[i].DeltaTime = 1.0;
|
|
|
|
if(iSbutton[i].UpTime) {
|
|
iSbutton[i].DownTime = iSbutton[i].UpTime = 0.0;
|
|
}
|
|
break;
|
|
|
|
case kInputEvent_Accelerate_On:
|
|
case kInputEvent_Reverse_On:
|
|
case kInputEvent_SlideLeft_On:
|
|
case kInputEvent_BankRight_On:
|
|
case kInputEvent_TurnRight_On:
|
|
case kInputEvent_SlideDown_On:
|
|
case kInputEvent_PitchUp_On:
|
|
case kInputEvent_SlideRight_On:
|
|
case kInputEvent_BankLeft_On:
|
|
case kInputEvent_TurnLeft_On:
|
|
case kInputEvent_SlideUp_On:
|
|
case kInputEvent_PitchDown_On:
|
|
if(iSbutton[i].DownTime != 0.0) {
|
|
iSbutton[i].DeltaTime = cur_time - iSbutton[i].DownTime;
|
|
}
|
|
break;
|
|
|
|
case kInputEvent_Bank_Off:
|
|
case kInputEvent_Slide_Off:
|
|
|
|
case kInputEvent_FirePrim_Off:
|
|
case kInputEvent_FireSecond_Off:
|
|
case kInputEvent_AfterBurn_Off:
|
|
case kInputEvent_RearView_Off:
|
|
case kInputEvent_InventoryPrev:
|
|
case kInputEvent_CounterNext:
|
|
case kInputEvent_EnergyShield_Off:
|
|
case kInputEvent_Accelerate_Off:
|
|
case kInputEvent_Reverse_Off:
|
|
case kInputEvent_SlideLeft_Off:
|
|
case kInputEvent_SlideRight_Off:
|
|
case kInputEvent_SlideUp_Off:
|
|
case kInputEvent_SlideDown_Off:
|
|
case kInputEvent_BankLeft_Off:
|
|
case kInputEvent_BankRight_Off:
|
|
case kInputEvent_TurnLeft_Off:
|
|
case kInputEvent_TurnRight_Off:
|
|
case kInputEvent_PitchUp_Off:
|
|
case kInputEvent_PitchDown_Off:
|
|
if(iSbutton[i-1].DownTime != 0.0) {
|
|
if(iSbutton[i-1].UpTime != 0)
|
|
iSbutton[i-1].DeltaTime = iSbutton[i-1].UpTime - iSbutton[i-1].DownTime;
|
|
iSbutton[i-1].UpTime = iSbutton[i-1].DownTime = 0.0;
|
|
} else {
|
|
iSbutton[i-1].DeltaTime = 0.0;
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
*/
|
|
}
|
|
// all systems need to implement this function. this returns information about the controller
|
|
bool gameMacController::get_packet(int id, ct_packet *packet, ct_format alt_format) {
|
|
bool success = false;
|
|
float val = (float)0.0;
|
|
packet->flags = 0;
|
|
int i;
|
|
packet->format = (alt_format != ctNoFormat) ? alt_format : m_ElementList[id].format;
|
|
alt_format = packet->format;
|
|
if (!m_ElementList[id].enabled) {
|
|
return success;
|
|
}
|
|
if (m_ElementList[id].ctype[0] == ctKey)
|
|
val += get_key_value(m_ElementList[id].value[0], alt_format);
|
|
if (m_ElementList[id].ctype[1] == ctKey)
|
|
val += get_key_value(m_ElementList[id].value[1], alt_format);
|
|
|
|
if (m_ElementList[id].ctype[0] == ctButton)
|
|
val += get_button_value(id);
|
|
if (m_ElementList[id].ctype[1] == ctButton)
|
|
val += get_button_value(id);
|
|
|
|
if (m_ElementList[id].ctype[0] == ctAxis)
|
|
val += get_axis_value(0, m_ElementList[id].value[0], alt_format, false);
|
|
|
|
if (val)
|
|
packet->flags |= CTPK_ELEMENTACTIVE;
|
|
packet->value = val;
|
|
|
|
return success;
|
|
}
|
|
gameController *CreateController(int num_funcs, ct_function *gameFunctions, char *remote_ip) {
|
|
mprintf((0, "Creating mac game controller.\n"));
|
|
|
|
return new gameMacController(num_funcs, gameFunctions);
|
|
}
|
|
void DestroyController(gameController *ctl) {
|
|
mprintf((0, "Destroying mac game controller.\n"));
|
|
|
|
if (ctl)
|
|
delete ctl;
|
|
}
|
|
// temporarily enables or disables a function
|
|
void gameMacController::enable_function(int id, bool enable) { m_ElementList[id].enabled = enable; }
|
|
// returns information about a requested function
|
|
void gameMacController::get_controller_function(int id, ct_type *type, ct_config_data *value, ubyte *flags) {
|
|
type[0] = m_ElementList[id].ctype[0];
|
|
type[1] = m_ElementList[id].ctype[1];
|
|
*value = makeword(CONTROLLER_CTL_INFO(m_ElementList[id].ctl[0], m_ElementList[id].ctl[1]),
|
|
CONTROLLER_CTL_VALUE(m_ElementList[id].value[0], m_ElementList[id].value[1]));
|
|
flags[0] = m_ElementList[id].flags[0];
|
|
flags[1] = m_ElementList[id].flags[1];
|
|
}
|
|
// sets the configuration of a function
|
|
void gameMacController::set_controller_function(int id, const ct_type *type, ct_config_data value, const ubyte *flags) {
|
|
ct_element elem;
|
|
if (id >= CT_MAX_ELEMENTS)
|
|
return;
|
|
// auto assign keyboard controller if type is key.
|
|
if (type[0] == ctKey)
|
|
elem.ctl[0] = CONTROLLER_CTL1_INFO(0);
|
|
else
|
|
elem.ctl[0] = CONTROLLER_CTL1_INFO(CONTROLLER_INFO(value));
|
|
if (type[1] == ctKey)
|
|
elem.ctl[1] = CONTROLLER_CTL2_INFO(0);
|
|
else
|
|
elem.ctl[1] = CONTROLLER_CTL2_INFO(CONTROLLER_INFO(value));
|
|
elem.ctype[0] = type[0];
|
|
elem.ctype[1] = type[1];
|
|
elem.format = m_ElementList[id].format;
|
|
elem.value[0] = CONTROLLER_CTL1_VALUE(CONTROLLER_VALUE(value));
|
|
elem.value[1] = CONTROLLER_CTL2_VALUE(CONTROLLER_VALUE(value));
|
|
elem.flags[0] = flags[0];
|
|
elem.flags[1] = flags[1];
|
|
elem.enabled = m_ElementList[id].enabled;
|
|
// if controller doesn't exist, set it to invalid.
|
|
if (elem.ctl[0] > CT_MAX_CONTROLLERS)
|
|
elem.ctl[0] = NULL_WINCONTROLLER;
|
|
if (elem.ctl[1] >= CT_MAX_CONTROLLERS)
|
|
elem.ctl[1] = NULL_WINCONTROLLER;
|
|
assign_element(id, &elem);
|
|
}
|
|
#define TABLE_LOOKUP
|
|
// note controller is index into ControlList.
|
|
float gameMacController::get_axis_value(sbyte controller, ubyte axis, ct_format format, bool invert) {
|
|
float axisval = 0.0;
|
|
|
|
switch (axis) {
|
|
// note we take care of mouse controls and external controls here
|
|
case CT_X_AXIS:
|
|
axisval += is_mouse[kNeed_Yaw];
|
|
if (ABS(is_joy[kNeed_Yaw]) > m_ControlList[MC_JOY].deadzone && m_ControlList[MC_JOY].sens[AXIS_YAW] != 0.0) {
|
|
#if defined TABLE_LOOKUP
|
|
axisval += SIGN(is_joy[kNeed_Yaw]) * m_ControlList[MC_JOY].sens_curve[AXIS_YAW][ABS(is_joy[kNeed_Yaw])];
|
|
#elif defined REAL_POW
|
|
if (m_ControlList[MC_JOY].sens[AXIS_YAW] == 1.0)
|
|
axisval += is_joy[kNeed_Yaw];
|
|
else
|
|
axisval += powf(ABS(is_joy[kNeed_Yaw]), m_ControlList[MC_JOY].inv_sens[AXIS_YAW]) * SIGN(is_joy[kNeed_Yaw]);
|
|
#else
|
|
axisval += is_joy[kNeed_Yaw] * m_ControlList[MC_JOY].sens[AXIS_YAW];
|
|
#endif
|
|
}
|
|
break;
|
|
|
|
case CT_Y_AXIS:
|
|
axisval -= is_mouse[kNeed_Pitch];
|
|
if (ABS(is_joy[kNeed_Pitch]) > m_ControlList[MC_JOY].deadzone && m_ControlList[MC_JOY].sens[AXIS_PITCH] != 0.0) {
|
|
#if defined TABLE_LOOKUP
|
|
axisval -=
|
|
SIGN(is_joy[kNeed_Pitch]) * m_ControlList[MC_JOY].sens_curve[AXIS_PITCH][ABS((int)(is_joy[kNeed_Pitch]))];
|
|
#elif defined REAL_POW
|
|
if (m_ControlList[MC_JOY].sens[AXIS_PITCH] == 1.0)
|
|
axisval -= is_joy[kNeed_Pitch];
|
|
else
|
|
axisval -=
|
|
powf(ABS(is_joy[kNeed_Pitch]), m_ControlList[MC_JOY].inv_sens[AXIS_PITCH]) * SIGN(is_joy[kNeed_Pitch]);
|
|
#else
|
|
axisval -= is_joy[kNeed_Pitch] * m_ControlList[MC_JOY].sens[AXIS_PITCH];
|
|
#endif
|
|
}
|
|
break;
|
|
|
|
case CT_R_AXIS:
|
|
axisval += is_mouse[kNeed_Roll];
|
|
if (ABS(is_joy[kNeed_Roll]) > m_ControlList[MC_JOY].deadzone && m_ControlList[MC_JOY].sens[AXIS_ROLL] != 0.0) {
|
|
#if defined TABLE_LOOKUP
|
|
axisval += SIGN(is_joy[kNeed_Roll]) * m_ControlList[MC_JOY].sens_curve[AXIS_ROLL][ABS((int)(is_joy[kNeed_Roll]))];
|
|
#elif defined REAL_POW
|
|
if (m_ControlList[MC_JOY].sens[AXIS_ROLL] == 1.0)
|
|
axisval += is_joy[kNeed_Roll];
|
|
else
|
|
axisval += powf(ABS(is_joy[kNeed_Roll]), m_ControlList[MC_JOY].inv_sens[AXIS_ROLL]) * SIGN(is_joy[kNeed_Roll]);
|
|
#else
|
|
axisval += is_joy[kNeed_Roll] * m_ControlList[MC_JOY].sens[AXIS_ROLL];
|
|
#endif
|
|
}
|
|
break;
|
|
|
|
case CT_Z_AXIS:
|
|
axisval -= is_mouse[kNeed_MoveZ];
|
|
if (ABS(is_joy[kNeed_MoveZ]) > m_ControlList[MC_JOY].deadzone && m_ControlList[MC_JOY].sens[AXIS_FORWARD] != 0.0) {
|
|
#if defined TABLE_LOOKUP
|
|
axisval -=
|
|
SIGN(is_joy[kNeed_MoveZ]) * m_ControlList[MC_JOY].sens_curve[AXIS_FORWARD][ABS((int)(is_joy[kNeed_MoveZ]))];
|
|
#elif defined REAL_POW
|
|
if (m_ControlList[MC_JOY].sens[AXIS_FORWARD] == 1.0)
|
|
axisval -= is_joy[kNeed_MoveZ];
|
|
else
|
|
axisval -=
|
|
powf(ABS(is_joy[kNeed_MoveZ]), m_ControlList[MC_JOY].inv_sens[AXIS_FORWARD]) * SIGN(is_joy[kNeed_MoveZ]);
|
|
#else
|
|
axisval -= is_joy[kNeed_MoveZ] * m_ControlList[MC_JOY].sens[AXIS_FORWARD];
|
|
#endif
|
|
}
|
|
break;
|
|
|
|
case CT_U_AXIS:
|
|
axisval += is_mouse[kNeed_MoveX];
|
|
if (ABS(is_joy[kNeed_MoveX]) > m_ControlList[MC_JOY].deadzone && m_ControlList[MC_JOY].sens[AXIS_SIDE] != 0.0) {
|
|
#if defined TABLE_LOOKUP
|
|
axisval +=
|
|
SIGN(is_joy[kNeed_MoveX]) * m_ControlList[MC_JOY].sens_curve[AXIS_SIDE][ABS((int)(is_joy[kNeed_MoveX]))];
|
|
#elif defined REAL_POW
|
|
if (m_ControlList[MC_JOY].sens[AXIS_SIDE] == 1.0)
|
|
axisval += is_joy[kNeed_MoveX];
|
|
else
|
|
axisval +=
|
|
powf(ABS(is_joy[kNeed_MoveX]), m_ControlList[MC_JOY].inv_sens[AXIS_SIDE]) * SIGN(is_joy[kNeed_MoveX]);
|
|
#else
|
|
axisval += is_joy[kNeed_MoveX] * m_ControlList[MC_JOY].sens[AXIS_SIDE];
|
|
#endif
|
|
}
|
|
break;
|
|
|
|
case CT_V_AXIS:
|
|
axisval -= is_mouse[kNeed_MoveY];
|
|
if (ABS(is_joy[kNeed_MoveY]) > m_ControlList[MC_JOY].deadzone && m_ControlList[MC_JOY].sens[AXIS_VERT] != 0.0) {
|
|
#if defined TABLE_LOOKUP
|
|
axisval -=
|
|
SIGN(is_joy[kNeed_MoveY]) * m_ControlList[MC_JOY].sens_curve[AXIS_VERT][ABS((int)(is_joy[kNeed_MoveY]))];
|
|
#elif defined REAL_POW
|
|
if (m_ControlList[MC_JOY].sens[AXIS_VERT] == 1.0)
|
|
axisval -= is_joy[kNeed_MoveY];
|
|
else
|
|
axisval -=
|
|
powf(ABS(is_joy[kNeed_MoveY]), m_ControlList[MC_JOY].inv_sens[AXIS_VERT]) * SIGN(is_joy[kNeed_MoveY]);
|
|
#else
|
|
axisval -= is_joy[kNeed_MoveY] * m_ControlList[MC_JOY].sens[AXIS_VERT];
|
|
#endif
|
|
}
|
|
break;
|
|
default:
|
|
mprintf((2, "invalid axis %d\n", axis));
|
|
Int3(); // NOT A VALID AXIS
|
|
break;
|
|
}
|
|
// mprintf((2, "x %d y %d z %d p %d h %d r %d\n",
|
|
// is_joy[kNeed_MoveX],is_joy[kNeed_MoveY],is_joy[kNeed_MoveZ],is_joy[kNeed_Pitch],is_joy[kNeed_Yaw],is_joy[kNeed_Roll]));
|
|
|
|
return axisval;
|
|
}
|
|
// get keyboard info
|
|
float gameMacController::get_key_value(int key, ct_format format) {
|
|
float val = (float)0.0;
|
|
ASSERT(key < DDIO_MAX_KEYS);
|
|
switch (format) {
|
|
// note we take care of mouse controls and external controls here
|
|
case ctDigital:
|
|
if (KEY_STATE(key))
|
|
val = 1.0f;
|
|
break;
|
|
case ctDownCount:
|
|
val = (float)ddio_KeyDownCount(key);
|
|
break;
|
|
case ctTime:
|
|
val = (float)ddio_KeyDownTime(key);
|
|
break;
|
|
default:
|
|
mprintf((1, "gameController::key unsupported format for function\n"));
|
|
}
|
|
return val;
|
|
}
|
|
// get keyboard info
|
|
float gameMacController::get_button_value(int button) {
|
|
float down_time = (float)0.0;
|
|
int sprockButton = ConvertPC_IS(button);
|
|
float cur_time = timer_GetTime();
|
|
|
|
switch (button) {
|
|
case ctfAFTERBURN_BUTTON:
|
|
case ctfTOGGLE_SLIDEBUTTON:
|
|
case ctfTOGGLE_BANKBUTTON:
|
|
if (iSbutton[sprockButton].state)
|
|
down_time = 1;
|
|
else
|
|
down_time = 0;
|
|
break;
|
|
|
|
case ctfWPNSEL_PCYCLEBTN:
|
|
case ctfWPNSEL_SCYCLEBTN:
|
|
case ctfREARVIEW_BTN:
|
|
case ctfPREV_CNTMSBTN:
|
|
case ctfNEXT_CNTMSBTN:
|
|
case ctfCNTMS_USEBTN:
|
|
case ctfPREV_INVBTN:
|
|
case ctfNEXT_INVBTN:
|
|
case ctfINV_USEBTN:
|
|
case ctfHEADLIGHT_BUTTON:
|
|
case ctfFIREFLARE_BUTTON:
|
|
case ctfAUTOMAP_BUTTON:
|
|
if (iSbutton[sprockButton].state) {
|
|
down_time = 1;
|
|
iSbutton[sprockButton].state = false;
|
|
} else {
|
|
down_time = 0;
|
|
}
|
|
break;
|
|
|
|
default:
|
|
if (iSbutton[sprockButton].state) {
|
|
if (iSbutton[sprockButton].DownTime != 0.0) {
|
|
down_time = cur_time - iSbutton[sprockButton].DownTime;
|
|
}
|
|
} else {
|
|
if (iSbutton[sprockButton].UpTime != 0.0 && iSbutton[sprockButton].DownTime != 0.0) {
|
|
down_time = iSbutton[sprockButton].UpTime - iSbutton[sprockButton].DownTime;
|
|
iSbutton[sprockButton].UpTime = iSbutton[sprockButton].DownTime = 0.0;
|
|
}
|
|
}
|
|
}
|
|
if (!(button == ctfFIREPRIMARY_BUTTON || button == ctfFIRESECONDARY_BUTTON))
|
|
if (down_time > 1.0)
|
|
down_time = 1.0;
|
|
return down_time;
|
|
}
|
|
int gameMacController::assign_function(ct_function *func) {
|
|
// for now this is a straight forward translation (that is, no mapping of needs to controller
|
|
// list to create elements.
|
|
ct_element elem;
|
|
int i;
|
|
for (i = 0; i < CTLBINDS_PER_FUNC; i++) {
|
|
elem.ctl[i] = NULL_WINCONTROLLER;
|
|
switch (func->ctype[i]) {
|
|
case ctNone:
|
|
break;
|
|
case ctKey:
|
|
elem.ctl[i] = 0;
|
|
break;
|
|
case ctAxis:
|
|
elem.ctl[i] = get_axis_controller(func->value[i]);
|
|
break;
|
|
case ctButton:
|
|
elem.ctl[i] = get_button_controller(func->value[i]);
|
|
break;
|
|
case ctMouseAxis:
|
|
elem.ctl[i] = 1;
|
|
break;
|
|
case ctMouseButton:
|
|
// find a free mouse button.
|
|
if ((m_ControlList[1].btnmask & (1 << (func->value[i] - 1))) &&
|
|
((func->value[i] - 1) < m_ControlList[1].buttons)) {
|
|
elem.ctl[i] = 1;
|
|
}
|
|
break;
|
|
case ctPOV:
|
|
elem.ctl[i] = get_pov_controller();
|
|
break;
|
|
}
|
|
elem.ctype[i] = func->ctype[i];
|
|
elem.value[i] = func->value[i];
|
|
}
|
|
elem.format = func->format;
|
|
elem.flags[0] = func->flags[0];
|
|
elem.flags[1] = func->flags[1];
|
|
elem.enabled = true;
|
|
assign_element(func->id, &elem);
|
|
return func->id;
|
|
}
|
|
// sets up an elements information structure
|
|
void gameMacController::assign_element(int id, ct_element *elem) {
|
|
// assign element, check to see if valid.
|
|
int i;
|
|
m_ElementList[id].format = elem->format;
|
|
m_ElementList[id].flags[0] = elem->flags[0];
|
|
m_ElementList[id].flags[1] = elem->flags[1];
|
|
m_ElementList[id].enabled = elem->enabled;
|
|
// look through each controller and validate each element
|
|
for (i = 0; i < CTLBINDS_PER_FUNC; i++) {
|
|
m_ElementList[id].ctl[i] = elem->ctl[i];
|
|
m_ElementList[id].value[i] = elem->value[i];
|
|
m_ElementList[id].ctype[i] = elem->ctype[i];
|
|
if (m_ElementList[id].ctl[i] != NULL_WINCONTROLLER) {
|
|
// this function shouldn't do any error checking!!!! keep same controller values and bindings unless
|
|
// bindings are truly bogus.
|
|
switch (m_ElementList[id].ctype[i]) {
|
|
case ctMouseButton:
|
|
case ctButton:
|
|
if (elem->value[i] > CT_MAX_BUTTONS) {
|
|
m_ElementList[id].ctl[i] = NULL_WINCONTROLLER;
|
|
m_ElementList[id].value[i] = NULL_BINDING;
|
|
}
|
|
break;
|
|
case ctMouseAxis:
|
|
case ctAxis:
|
|
// if (!(m_ControlList[elem->ctl[i]].flags & (1<<(elem->value[i]-1))))
|
|
// m_ElementList[id].ctl[i] = NULL_WINCONTROLLER;
|
|
break;
|
|
case ctPOV:
|
|
// if (!(m_ControlList[elem->ctl[i]].flags & CTF_POV))
|
|
// m_ElementList[id].ctl[i] = NULL_WINCONTROLLER;
|
|
break;
|
|
case ctKey:
|
|
break;
|
|
default:
|
|
m_ElementList[id].value[i] = NULL_BINDING;
|
|
m_ElementList[id].ctl[i] = NULL_WINCONTROLLER;
|
|
}
|
|
} else {
|
|
m_ElementList[id].value[i] = NULL_BINDING;
|
|
}
|
|
}
|
|
}
|
|
sbyte gameMacController::get_axis_controller(ubyte axis) {
|
|
return 2;
|
|
// return NULL_CONTROLLER;
|
|
}
|
|
sbyte gameMacController::get_button_controller(ubyte btn) { return NULL_CONTROLLER; }
|
|
sbyte gameMacController::get_pov_controller() { return NULL_CONTROLLER; }
|
|
// enumerate all controllers on system
|
|
bool gameMacController::enum_controllers(char *remote_adr) {
|
|
int num_devs = 0, dev;
|
|
int i;
|
|
for (i = 0; i < CT_MAX_CONTROLLERS; i++)
|
|
m_ControlList[i].id = CTID_INVALID;
|
|
// Add keyboard controller
|
|
m_ControlList[num_devs].id = CTID_KEYBOARD;
|
|
m_ControlList[num_devs].buttons = 0;
|
|
m_ControlList[num_devs].flags = 0;
|
|
num_devs++;
|
|
return true;
|
|
}
|
|
// gets sensitivity of axis item
|
|
float gameMacController::get_axis_sensitivity(ct_type axis_type, ubyte axis) {
|
|
axis--;
|
|
ASSERT(axis < CT_NUM_AXES);
|
|
switch (axis_type) {
|
|
case ctMouseAxis:
|
|
return m_ControlList[1].sens[axis];
|
|
case ctAxis:
|
|
return m_ControlList[MC_JOY].sens[axis];
|
|
default:
|
|
Int3();
|
|
}
|
|
return 0.0f;
|
|
}
|
|
// sets sensitivity of axis item
|
|
void gameMacController::set_axis_sensitivity(ct_type axis_type, ubyte axis, float val) {
|
|
int i;
|
|
axis--;
|
|
ASSERT(axis < CT_NUM_AXES);
|
|
switch (axis_type) {
|
|
case ctMouseAxis:
|
|
m_ControlList[1].sens[axis] = val;
|
|
break;
|
|
case ctAxis:
|
|
for (i = 2; i < CT_MAX_CONTROLLERS; i++) {
|
|
m_ControlList[i].sens[axis] = val;
|
|
// m_ControlList[i].inv_sens[axis] = 1.0/val;
|
|
m_ControlList[i].sens_curve[axis][0] = 0;
|
|
for (int j = 1; j <= JOY_SAMPLES; j++) {
|
|
m_ControlList[i].sens_curve[axis][j] = powf((float)j / (float)(JOY_SAMPLES), 1.0 / val);
|
|
}
|
|
}
|
|
break;
|
|
default:
|
|
Int3();
|
|
}
|
|
}
|
|
// #ifndef MACINTOSH
|
|
// toggles use of deadzone for controllers. ctl can be 0 to ???
|
|
// dead zone is from 0.0 to 0.5
|
|
void gameMacController::set_controller_deadzone(int ctl, float deadzone) {
|
|
if (deadzone < 0.0)
|
|
deadzone = 0.0;
|
|
if (deadzone > 25)
|
|
deadzone = 25;
|
|
m_ControlList[MC_JOY].deadzone = deadzone * 2;
|
|
}
|
|
float gameMacController::get_controller_deadzone(int ctl) {
|
|
float val = m_ControlList[MC_JOY].deadzone / 2;
|
|
return val;
|
|
}
|
|
|
|
// #endif
|
|
char Ctltext_AxisBindings[][16] = {"", "X-axis", "Y-axis", "Z-axis", "R-axis", "U-axis", "V-axis"};
|
|
char Ctltext_BtnBindings[][16] = {"", "btn1", "btn2", "btn3", "btn4", "btn5", "btn6", "btn7", "btn8",
|
|
"btn9", "btn10", "btn11", "btn12", "btn13", "btn14", "btn15", "btn16", "btn17",
|
|
"btn18", "btn19", "btn20", "btn21", "btn22", "btn23", "btn24", "btn25", "btn26",
|
|
"btn27", "btn28", "btn29", "btn30", "btn31", "btn32"};
|
|
char Ctltext_PovBindings[][16] = {"", "pov-U", "pov-R", "pov-D", "pov-L"};
|
|
#define NUM_AXISBINDSTRINGS (sizeof(Ctltext_AxisBindings) / sizeof(Ctltext_AxisBindings[0]))
|
|
#define NUM_BTNBINDSTRINGS (sizeof(Ctltext_BtnBindings) / sizeof(Ctltext_AxisBindings[0]))
|
|
#ifdef MACINTOSH
|
|
// retrieves binding text for desired function, binding, etc.
|
|
const char *gameMacController::get_binding_text(ct_type type, ubyte ctrl, ubyte bind) {
|
|
static char binding_text[16];
|
|
const char *str;
|
|
if (ctrl == NULL_CONTROLLER) {
|
|
return NULL;
|
|
}
|
|
switch (type) {
|
|
case ctAxis: {
|
|
ASSERT(bind < NUM_AXISBINDSTRINGS);
|
|
str = Ctltext_AxisBindings[bind];
|
|
if ((ctrl - 2) > 0) {
|
|
sprintf(binding_text, "J%d:%s", (ctrl - 2) + 1, str);
|
|
} else {
|
|
return str;
|
|
}
|
|
break;
|
|
}
|
|
case ctMouseAxis: {
|
|
str = ddio_MouseGetAxisText(((sbyte)bind) - 1);
|
|
return str;
|
|
}
|
|
case ctButton: {
|
|
ASSERT(bind < NUM_BTNBINDSTRINGS);
|
|
str = Ctltext_BtnBindings[bind];
|
|
if ((ctrl - 2) > 0) {
|
|
sprintf(binding_text, "J%d:%s", (ctrl - 2) + 1, str);
|
|
} else {
|
|
return str;
|
|
}
|
|
break;
|
|
}
|
|
case ctMouseButton: {
|
|
str = ddio_MouseGetBtnText(((sbyte)bind) - 1);
|
|
return str;
|
|
}
|
|
case ctPOV:
|
|
case ctPOV2:
|
|
case ctPOV3:
|
|
case ctPOV4: {
|
|
ushort povpos = bind;
|
|
if (povpos == JOYPOV_UP)
|
|
str = Ctltext_PovBindings[1];
|
|
else if (povpos == JOYPOV_DOWN)
|
|
str = Ctltext_PovBindings[3];
|
|
else if (povpos == JOYPOV_LEFT)
|
|
str = Ctltext_PovBindings[4];
|
|
else if (povpos == JOYPOV_RIGHT)
|
|
str = Ctltext_PovBindings[2];
|
|
else
|
|
str = Ctltext_PovBindings[0];
|
|
if ((ctrl - 2) > 0) {
|
|
if (type - ctPOV) {
|
|
sprintf(binding_text, "J%d:%s%d", (ctrl - 2) + 1, str, type - ctPOV);
|
|
} else {
|
|
sprintf(binding_text, "J%d:%s", (ctrl - 2) + 1, str);
|
|
}
|
|
} else {
|
|
if (type - ctPOV) {
|
|
sprintf(binding_text, "%s%d", str, type - ctPOV);
|
|
} else {
|
|
return str;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case ctKey:
|
|
break;
|
|
default:
|
|
if (type == ctNone) {
|
|
Int3();
|
|
}
|
|
binding_text[0] = 0;
|
|
}
|
|
return binding_text;
|
|
}
|
|
#endif |