mirror of
https://github.com/RetroDECK/Supermodel.git
synced 2024-11-23 06:15:37 +00:00
5e247021be
- Fixed bug with mapping of multiple assignments. - Added new ! operator for input mappings, which lets the user specify that an input must not be active. - Added option to print info about input system (such as settings and detected keyboards, mice and joysticks) during input configuration. - Added new trigger input for lightgun games with a configurable option to automatically pull trigger when offscreen input is activated (this makes playing with the mouse easier as the gun can be reloaded with single mouse button, rather than having to press both buttons at the same time). - Added -xinput command line option that switches to using XInput API rather than DirectInput for XBox 360 controllers (this allows the XBox 360 controller's two triggers to be read independently which works better for driving games when they are mapped to accele rator and brake). - Added initial version of force feedback implementation to DirectInputSystem (this still needs work).
142 lines
4.1 KiB
C++
142 lines
4.1 KiB
C++
#include "Supermodel.h"
|
|
|
|
CInput::CInput(const char *inputId, const char *inputLabel, unsigned inputFlags, unsigned inputGameFlags, const char *defaultMapping, UINT16 initValue) :
|
|
id(inputId), label(inputLabel), flags(inputFlags), gameFlags(inputGameFlags), m_defaultMapping(defaultMapping), value(initValue), prevValue(initValue),
|
|
m_system(NULL), m_source(NULL)
|
|
{
|
|
ResetToDefaultMapping();
|
|
}
|
|
|
|
void CInput::CreateSource()
|
|
{
|
|
// If already have a source, then release it now
|
|
if (m_system != NULL && m_source != NULL)
|
|
m_system->ReleaseSource(m_source);
|
|
|
|
// If no system set yet or mapping is empty or NONE, then set source to NULL
|
|
if (m_system == NULL || m_mapping[0] == '\0' || stricmp(m_mapping, "NONE") == 0)
|
|
m_source = NULL;
|
|
else
|
|
{
|
|
// Otherwise, ask system to parse mapping into appropriate input source
|
|
m_source = m_system->ParseSource(m_mapping, !!(flags & INPUT_FLAGS_AXIS));
|
|
|
|
// Check that mapping was parsed okay and if not then fall back to default mapping
|
|
if (m_source == NULL && stricmp(m_mapping, m_defaultMapping) != 0)
|
|
{
|
|
ErrorLog("Unable to map input %s to [%s] - switching to default [%s].\n", id, m_mapping, m_defaultMapping);
|
|
|
|
ResetToDefaultMapping();
|
|
}
|
|
}
|
|
}
|
|
|
|
void CInput::Initialize(CInputSystem *system)
|
|
{
|
|
m_system = system;
|
|
|
|
CreateSource();
|
|
}
|
|
|
|
const char* CInput::GetInputGroup()
|
|
{
|
|
switch (gameFlags)
|
|
{
|
|
case GAME_INPUT_UI: return "User Interface Controls";
|
|
case GAME_INPUT_COMMON: return "Common Controls";
|
|
case GAME_INPUT_JOYSTICK1: // Fall through to below
|
|
case GAME_INPUT_JOYSTICK2: return "8-Way Joysticks";
|
|
case GAME_INPUT_FIGHTING: return "Fighting Game Buttons";
|
|
case GAME_INPUT_SOCCER: return "Virtua Striker Buttons";
|
|
case GAME_INPUT_VEHICLE: return "Racing Game Steering Controls";
|
|
case GAME_INPUT_SHIFT4: return "Racing Game Gear Shift";
|
|
case GAME_INPUT_VR: return "Racing Game VR View Buttons";
|
|
case GAME_INPUT_RALLY: return "Sega Rally Buttons";
|
|
case GAME_INPUT_TWIN_JOYSTICKS: return "Virtua On Controls";
|
|
case GAME_INPUT_ANALOG_JOYSTICK: return "Analog Joystick";
|
|
case GAME_INPUT_GUN1: // Fall through to below
|
|
case GAME_INPUT_GUN2: return "Lightguns";
|
|
default: return "Misc";
|
|
}
|
|
}
|
|
|
|
const char *CInput::GetMapping()
|
|
{
|
|
return m_mapping;
|
|
}
|
|
|
|
void CInput::ClearMapping()
|
|
{
|
|
SetMapping("NONE");
|
|
}
|
|
|
|
void CInput::SetMapping(const char *mapping)
|
|
{
|
|
strncpy(m_mapping, mapping, MAX_MAPPING_LENGTH - 1);
|
|
m_mapping[MAX_MAPPING_LENGTH - 1] = '\0';
|
|
CreateSource();
|
|
}
|
|
|
|
void CInput::AppendMapping(const char *mapping)
|
|
{
|
|
// If mapping is empty or NONE, then simply set mapping
|
|
if (m_mapping[0] == '\0' || stricmp(m_mapping, "NONE") == 0)
|
|
SetMapping(mapping);
|
|
else
|
|
{
|
|
// Otherwise, append to mapping string and recreate source from new mapping string
|
|
int size = MAX_MAPPING_LENGTH - strlen(m_mapping);
|
|
strncat(m_mapping, ",", size--);
|
|
strncat(m_mapping, mapping, size);
|
|
CreateSource();
|
|
}
|
|
}
|
|
|
|
void CInput::ResetToDefaultMapping()
|
|
{
|
|
SetMapping(m_defaultMapping);
|
|
}
|
|
|
|
void CInput::ReadFromINIFile(CINIFile *ini, const char *section)
|
|
{
|
|
if (!IsConfigurable())
|
|
return;
|
|
string key("Input");
|
|
key.append(id);
|
|
string mapping;
|
|
if (ini->Get(section, key, mapping) == OKAY)
|
|
SetMapping(mapping.c_str());
|
|
}
|
|
|
|
void CInput::WriteToINIFile(CINIFile *ini, const char *section)
|
|
{
|
|
if (!IsConfigurable())
|
|
return;
|
|
string key("Input");
|
|
key.append(id);
|
|
ini->Set(section, key, m_mapping);
|
|
}
|
|
|
|
bool CInput::Configure(bool append, const char *escapeMapping)
|
|
{
|
|
char mapping[MAX_MAPPING_LENGTH];
|
|
if (!m_system->ReadMapping(mapping, MAX_MAPPING_LENGTH, !!(flags & INPUT_FLAGS_AXIS), READ_ALL, escapeMapping))
|
|
return false;
|
|
if (append)
|
|
AppendMapping(mapping);
|
|
else
|
|
SetMapping(mapping);
|
|
return true;
|
|
}
|
|
|
|
bool CInput::Changed()
|
|
{
|
|
return value != prevValue;
|
|
}
|
|
|
|
bool CInput::SendForceFeedbackCmd(ForceFeedbackCmd *ffCmd)
|
|
{
|
|
if (m_source == NULL)
|
|
return false;
|
|
return m_source->SendForceFeedbackCmd(ffCmd);
|
|
} |