2003-02-16 04:01:45 +00:00
|
|
|
#include "global.h"
|
2002-04-16 17:31:00 +00:00
|
|
|
/*
|
|
|
|
|
-----------------------------------------------------------------------------
|
|
|
|
|
Class: InputMapper
|
|
|
|
|
|
|
|
|
|
Desc: See Header.
|
|
|
|
|
|
2002-05-19 01:59:48 +00:00
|
|
|
Copyright (c) 2001-2002 by the person(s) listed below. All rights reserved.
|
2002-04-16 17:31:00 +00:00
|
|
|
Chris Danford
|
|
|
|
|
-----------------------------------------------------------------------------
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
#include "InputMapper.h"
|
|
|
|
|
#include "IniFile.h"
|
|
|
|
|
#include "GameManager.h"
|
2002-07-23 01:41:40 +00:00
|
|
|
#include "GameState.h"
|
2002-07-31 19:40:40 +00:00
|
|
|
#include "RageLog.h"
|
2002-09-08 06:11:59 +00:00
|
|
|
#include "InputFilter.h"
|
2002-11-29 20:37:12 +00:00
|
|
|
#include "RageUtil.h"
|
2003-05-28 02:35:05 +00:00
|
|
|
#include "PrefsManager.h"
|
|
|
|
|
#include "RageInput.h"
|
2003-07-22 07:47:27 +00:00
|
|
|
#include "arch/arch.h"
|
2002-04-16 17:31:00 +00:00
|
|
|
|
|
|
|
|
|
2002-05-19 01:59:48 +00:00
|
|
|
InputMapper* INPUTMAPPER = NULL; // global and accessable from anywhere in our program
|
2002-04-16 17:31:00 +00:00
|
|
|
|
2003-07-22 07:47:27 +00:00
|
|
|
#define KEYMAPS_PATH BASE_PATH "Data" SLASH "Keymaps.ini"
|
2002-04-16 17:31:00 +00:00
|
|
|
|
|
|
|
|
InputMapper::InputMapper()
|
|
|
|
|
{
|
2003-09-01 17:12:36 +00:00
|
|
|
ReadMappingsFromDisk();
|
2002-04-16 17:31:00 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
InputMapper::~InputMapper()
|
|
|
|
|
{
|
|
|
|
|
SaveMappingsToDisk();
|
|
|
|
|
}
|
|
|
|
|
|
2002-07-31 19:40:40 +00:00
|
|
|
void InputMapper::ClearAllMappings()
|
|
|
|
|
{
|
|
|
|
|
for( int i=0; i<MAX_GAME_CONTROLLERS; i++ )
|
|
|
|
|
for( int j=0; j<MAX_GAME_BUTTONS; j++ )
|
|
|
|
|
for( int k=0; k<NUM_GAME_TO_DEVICE_SLOTS; k++ )
|
|
|
|
|
m_GItoDI[i][j][k].MakeInvalid();
|
|
|
|
|
}
|
|
|
|
|
|
2002-08-13 23:26:46 +00:00
|
|
|
void InputMapper::AddDefaultMappingsForCurrentGameIfUnmapped()
|
2002-07-31 19:40:40 +00:00
|
|
|
{
|
2002-08-13 23:26:46 +00:00
|
|
|
// Clear default mappings. Default mappings are in the third slot.
|
2002-07-31 19:40:40 +00:00
|
|
|
for( int i=0; i<MAX_GAME_CONTROLLERS; i++ )
|
|
|
|
|
for( int j=0; j<MAX_GAME_BUTTONS; j++ )
|
2002-08-13 23:26:46 +00:00
|
|
|
ClearFromInputMap( GameInput((GameController)i,(GameButton)j), 2 );
|
2002-07-31 19:40:40 +00:00
|
|
|
|
|
|
|
|
GameDef* pGameDef = GAMESTATE->GetCurrentGameDef();
|
|
|
|
|
for( int c=0; c<MAX_GAME_CONTROLLERS; c++ )
|
|
|
|
|
{
|
|
|
|
|
for( int b=0; b<pGameDef->m_iButtonsPerController; b++ )
|
|
|
|
|
{
|
|
|
|
|
int key = pGameDef->m_iDefaultKeyboardKey[c][b];
|
2002-08-13 23:26:46 +00:00
|
|
|
if( key == -1 ) // "no key" marker"
|
|
|
|
|
continue;
|
2002-07-31 19:40:40 +00:00
|
|
|
DeviceInput DeviceI( DEVICE_KEYBOARD, key );
|
|
|
|
|
GameInput GameI( (GameController)c, (GameButton)b );
|
2002-08-13 23:26:46 +00:00
|
|
|
if( !IsMapped(DeviceI) ) // if this key isn't already being used by another user-made mapping
|
2002-07-31 19:40:40 +00:00
|
|
|
SetInputMap( DeviceI, GameI, 2 );
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2002-04-16 17:31:00 +00:00
|
|
|
|
2003-05-28 02:35:05 +00:00
|
|
|
struct AutoJoyMapping
|
|
|
|
|
{
|
|
|
|
|
Game game;
|
2003-08-02 19:28:55 +00:00
|
|
|
const char *szDeviceDescription; // reported by InputHandler
|
|
|
|
|
const char *szControllerName; // the product name of the controller
|
2003-05-28 02:35:05 +00:00
|
|
|
struct {
|
2003-08-02 19:28:55 +00:00
|
|
|
int iSlotIndex; // -1 == end marker
|
2003-05-28 02:35:05 +00:00
|
|
|
int deviceButton;
|
|
|
|
|
GameButton gb;
|
2003-05-28 04:22:52 +00:00
|
|
|
/* If this is true, this is an auxilliary mapping assigned to the second
|
|
|
|
|
* player. If two of the same device are found, and the device has secondary
|
|
|
|
|
* entries, the later entries take precedence. This way, if a Pump pad is
|
|
|
|
|
* found, it'll map P1 to the primary pad and P2 to the secondary pad.
|
|
|
|
|
* (We can't tell if a slave pad is actually there.) Then, if a second primary
|
|
|
|
|
* is found (DEVICE_PUMP2), 2P will be mapped to it.
|
|
|
|
|
*
|
|
|
|
|
* This isn't well-tested; I only have one Pump pad. */
|
|
|
|
|
bool SecondController;
|
2003-08-03 03:02:42 +00:00
|
|
|
} maps[32];
|
2003-05-28 02:35:05 +00:00
|
|
|
};
|
|
|
|
|
const AutoJoyMapping g_AutoJoyMappings[] =
|
|
|
|
|
{
|
|
|
|
|
{
|
|
|
|
|
GAME_DANCE,
|
|
|
|
|
"GIC USB Joystick",
|
2003-08-02 19:28:55 +00:00
|
|
|
"Boom USB convertor (black/gray)",
|
2003-05-28 02:35:05 +00:00
|
|
|
{
|
2003-08-02 19:28:55 +00:00
|
|
|
{ 0, JOY_16, DANCE_BUTTON_LEFT },
|
|
|
|
|
{ 0, JOY_14, DANCE_BUTTON_RIGHT },
|
|
|
|
|
{ 0, JOY_13, DANCE_BUTTON_UP },
|
|
|
|
|
{ 0, JOY_15, DANCE_BUTTON_DOWN },
|
|
|
|
|
{-1, NULL, NULL },
|
2003-05-28 02:35:05 +00:00
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
GAME_DANCE,
|
2003-08-02 19:28:55 +00:00
|
|
|
"4 axis 16 button joystick",
|
|
|
|
|
"PC Magic Box",
|
2003-05-28 02:35:05 +00:00
|
|
|
{
|
2003-08-02 19:28:55 +00:00
|
|
|
{ 0, JOY_16, DANCE_BUTTON_LEFT },
|
|
|
|
|
{ 0, JOY_14, DANCE_BUTTON_RIGHT },
|
|
|
|
|
{ 0, JOY_13, DANCE_BUTTON_UP },
|
|
|
|
|
{ 0, JOY_15, DANCE_BUTTON_DOWN },
|
|
|
|
|
{-1, NULL, NULL },
|
2003-05-28 02:35:05 +00:00
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
GAME_DANCE,
|
|
|
|
|
"GamePad Pro USB ", // yes, there is a space at the end
|
2003-08-02 19:28:55 +00:00
|
|
|
"GamePad Pro USB",
|
2003-05-28 02:35:05 +00:00
|
|
|
{
|
2003-08-02 19:28:55 +00:00
|
|
|
{ 0, JOY_LEFT, DANCE_BUTTON_LEFT },
|
|
|
|
|
{ 0, JOY_RIGHT, DANCE_BUTTON_RIGHT },
|
|
|
|
|
{ 0, JOY_UP, DANCE_BUTTON_UP },
|
|
|
|
|
{ 0, JOY_DOWN, DANCE_BUTTON_DOWN },
|
|
|
|
|
{ 1, JOY_1, DANCE_BUTTON_LEFT },
|
|
|
|
|
{ 1, JOY_3, DANCE_BUTTON_RIGHT },
|
|
|
|
|
{ 1, JOY_4, DANCE_BUTTON_UP },
|
|
|
|
|
{ 1, JOY_2, DANCE_BUTTON_DOWN },
|
|
|
|
|
{ 0, JOY_5, DANCE_BUTTON_UPLEFT },
|
|
|
|
|
{ 0, JOY_6, DANCE_BUTTON_UPRIGHT },
|
|
|
|
|
{ 0, JOY_9, DANCE_BUTTON_BACK },
|
|
|
|
|
{ 0, JOY_10, DANCE_BUTTON_START },
|
|
|
|
|
{-1, NULL, NULL },
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
GAME_DANCE,
|
|
|
|
|
"4 axis 12 button joystick with hat switch",
|
|
|
|
|
"Super Joy Box 5",
|
|
|
|
|
{
|
|
|
|
|
{ 0, JOY_HAT_LEFT, DANCE_BUTTON_LEFT },
|
|
|
|
|
{ 0, JOY_HAT_RIGHT, DANCE_BUTTON_RIGHT },
|
|
|
|
|
{ 0, JOY_HAT_UP, DANCE_BUTTON_UP },
|
|
|
|
|
{ 0, JOY_HAT_DOWN, DANCE_BUTTON_DOWN },
|
2003-08-02 19:53:36 +00:00
|
|
|
{ 1, JOY_4, DANCE_BUTTON_LEFT },
|
|
|
|
|
{ 1, JOY_2, DANCE_BUTTON_RIGHT },
|
|
|
|
|
{ 1, JOY_1, DANCE_BUTTON_UP },
|
|
|
|
|
{ 1, JOY_3, DANCE_BUTTON_DOWN },
|
|
|
|
|
{ 0, JOY_5, DANCE_BUTTON_UPLEFT },
|
|
|
|
|
{ 0, JOY_6, DANCE_BUTTON_UPRIGHT },
|
|
|
|
|
{ 1, JOY_7, DANCE_BUTTON_UPLEFT },
|
|
|
|
|
{ 1, JOY_8, DANCE_BUTTON_UPRIGHT },
|
|
|
|
|
{ 0, JOY_10, DANCE_BUTTON_BACK },
|
|
|
|
|
{ 0, JOY_9, DANCE_BUTTON_START },
|
|
|
|
|
{-1, NULL, NULL },
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
GAME_DANCE,
|
|
|
|
|
"MP-8866 Dual USB Joypad",
|
|
|
|
|
"Super Dual Box",
|
|
|
|
|
{
|
|
|
|
|
{ 0, JOY_HAT_LEFT, DANCE_BUTTON_LEFT },
|
|
|
|
|
{ 0, JOY_HAT_RIGHT, DANCE_BUTTON_RIGHT },
|
|
|
|
|
{ 0, JOY_HAT_UP, DANCE_BUTTON_UP },
|
|
|
|
|
{ 0, JOY_HAT_DOWN, DANCE_BUTTON_DOWN },
|
2003-08-02 19:28:55 +00:00
|
|
|
{ 1, JOY_4, DANCE_BUTTON_LEFT },
|
|
|
|
|
{ 1, JOY_2, DANCE_BUTTON_RIGHT },
|
|
|
|
|
{ 1, JOY_1, DANCE_BUTTON_UP },
|
|
|
|
|
{ 1, JOY_3, DANCE_BUTTON_DOWN },
|
|
|
|
|
{ 0, JOY_5, DANCE_BUTTON_UPLEFT },
|
|
|
|
|
{ 0, JOY_6, DANCE_BUTTON_UPRIGHT },
|
|
|
|
|
{ 1, JOY_7, DANCE_BUTTON_UPLEFT },
|
|
|
|
|
{ 1, JOY_8, DANCE_BUTTON_UPRIGHT },
|
|
|
|
|
{ 0, JOY_10, DANCE_BUTTON_BACK },
|
|
|
|
|
{ 0, JOY_9, DANCE_BUTTON_START },
|
|
|
|
|
{-1, NULL, NULL },
|
2003-07-22 07:47:27 +00:00
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
GAME_DANCE,
|
|
|
|
|
"XBOX Gamepad Plugin V0.01",
|
2003-08-02 19:28:55 +00:00
|
|
|
"X-Box gamepad",
|
2003-07-22 07:47:27 +00:00
|
|
|
{
|
2003-08-02 19:28:55 +00:00
|
|
|
{ 0, JOY_HAT_LEFT, DANCE_BUTTON_LEFT },
|
|
|
|
|
{ 0, JOY_HAT_RIGHT, DANCE_BUTTON_RIGHT },
|
|
|
|
|
{ 0, JOY_HAT_UP, DANCE_BUTTON_UP },
|
|
|
|
|
{ 0, JOY_HAT_DOWN, DANCE_BUTTON_DOWN },
|
|
|
|
|
{ 1, JOY_1, DANCE_BUTTON_DOWN }, // A
|
|
|
|
|
{ 1, JOY_2, DANCE_BUTTON_RIGHT }, // B
|
|
|
|
|
{ 1, JOY_3, DANCE_BUTTON_LEFT }, // X
|
|
|
|
|
{ 1, JOY_4, DANCE_BUTTON_UP }, // Y
|
|
|
|
|
{ 0, JOY_7, DANCE_BUTTON_UPLEFT }, // L shoulder
|
|
|
|
|
{ 0, JOY_8, DANCE_BUTTON_UPRIGHT }, // R shoulder
|
|
|
|
|
{ 0, JOY_9, DANCE_BUTTON_START },
|
|
|
|
|
{ 0, JOY_10, DANCE_BUTTON_BACK },
|
|
|
|
|
{-1, NULL, NULL },
|
2003-05-28 02:35:05 +00:00
|
|
|
}
|
|
|
|
|
},
|
2003-05-28 04:22:52 +00:00
|
|
|
{
|
|
|
|
|
GAME_PUMP,
|
|
|
|
|
"Pump USB",
|
2003-08-02 19:28:55 +00:00
|
|
|
"Pump USB pad",
|
2003-05-28 04:22:52 +00:00
|
|
|
{
|
2003-08-02 19:28:55 +00:00
|
|
|
{ 0, PUMP_UL, PUMP_BUTTON_UPLEFT },
|
|
|
|
|
{ 0, PUMP_UR, PUMP_BUTTON_UPRIGHT },
|
|
|
|
|
{ 0, PUMP_MID, PUMP_BUTTON_CENTER },
|
|
|
|
|
{ 0, PUMP_DL, PUMP_BUTTON_DOWNLEFT },
|
|
|
|
|
{ 0, PUMP_DR, PUMP_BUTTON_DOWNRIGHT },
|
|
|
|
|
{ 0, PUMP_ESCAPE, PUMP_BUTTON_BACK },
|
|
|
|
|
{ 0, PUMP_2P_UL, PUMP_BUTTON_UPLEFT, true },
|
|
|
|
|
{ 0, PUMP_2P_UR, PUMP_BUTTON_UPRIGHT, true },
|
|
|
|
|
{ 0, PUMP_2P_MID, PUMP_BUTTON_CENTER, true },
|
|
|
|
|
{ 0, PUMP_2P_DL, PUMP_BUTTON_DOWNLEFT, true },
|
|
|
|
|
{ 0, PUMP_2P_DR, PUMP_BUTTON_DOWNRIGHT, true },
|
|
|
|
|
{-1, NULL, NULL },
|
2003-05-28 04:22:52 +00:00
|
|
|
}
|
|
|
|
|
},
|
2003-05-28 02:35:05 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
void InputMapper::AutoMapJoysticksForCurrentGame()
|
|
|
|
|
{
|
|
|
|
|
vector<InputDevice> vDevices;
|
|
|
|
|
vector<CString> vDescriptions;
|
|
|
|
|
INPUTMAN->GetDevicesAndDescriptions(vDevices,vDescriptions);
|
2003-08-02 19:28:55 +00:00
|
|
|
|
|
|
|
|
int iNumJoysticksMapped = 0;
|
|
|
|
|
|
2003-05-28 02:35:05 +00:00
|
|
|
for( unsigned i=0; i<vDevices.size(); i++ )
|
|
|
|
|
{
|
|
|
|
|
InputDevice device = vDevices[i];
|
|
|
|
|
CString sDescription = vDescriptions[i];
|
2003-08-03 03:02:42 +00:00
|
|
|
for( unsigned j=0; j<ARRAYSIZE(g_AutoJoyMappings); j++ )
|
2003-05-28 02:35:05 +00:00
|
|
|
{
|
|
|
|
|
const AutoJoyMapping& mapping = g_AutoJoyMappings[j];
|
|
|
|
|
|
2003-08-02 19:28:55 +00:00
|
|
|
if( sDescription == mapping.szDeviceDescription )
|
2003-05-28 02:35:05 +00:00
|
|
|
{
|
2003-08-02 19:28:55 +00:00
|
|
|
//
|
|
|
|
|
// We have a mapping for this joystick
|
|
|
|
|
//
|
|
|
|
|
GameController gc = (GameController)iNumJoysticksMapped;
|
|
|
|
|
if( gc >= GAME_CONTROLLER_INVALID )
|
|
|
|
|
break; // stop mapping. We already mapped one device for each game controller.
|
2003-05-28 02:35:05 +00:00
|
|
|
|
2003-08-02 19:28:55 +00:00
|
|
|
LOG->Info( "Applying default joystick mapping #%d for device '%s' (%s)",
|
|
|
|
|
iNumJoysticksMapped+1, mapping.szDeviceDescription, mapping.szControllerName );
|
2003-05-28 02:35:05 +00:00
|
|
|
|
2003-08-03 03:02:42 +00:00
|
|
|
for( int k=0; mapping.maps[k].iSlotIndex != -1; k++ )
|
2003-05-28 02:35:05 +00:00
|
|
|
{
|
2003-08-03 03:02:42 +00:00
|
|
|
if( mapping.maps[k].SecondController )
|
2003-05-28 04:22:52 +00:00
|
|
|
gc = GAME_CONTROLLER_2;
|
|
|
|
|
|
2003-08-03 03:02:42 +00:00
|
|
|
DeviceInput di( device, mapping.maps[k].deviceButton );
|
|
|
|
|
GameInput gi( gc, mapping.maps[k].gb );
|
|
|
|
|
SetInputMap( di, gi, mapping.maps[k].iSlotIndex );
|
2003-05-28 02:35:05 +00:00
|
|
|
}
|
2003-08-02 19:28:55 +00:00
|
|
|
|
|
|
|
|
iNumJoysticksMapped++;
|
2003-05-28 02:35:05 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2002-04-16 17:31:00 +00:00
|
|
|
void InputMapper::ReadMappingsFromDisk()
|
|
|
|
|
{
|
2002-05-27 08:23:27 +00:00
|
|
|
ASSERT( GAMEMAN != NULL );
|
2002-04-16 17:31:00 +00:00
|
|
|
|
2002-07-31 19:40:40 +00:00
|
|
|
ClearAllMappings();
|
|
|
|
|
|
2002-04-16 17:31:00 +00:00
|
|
|
IniFile ini;
|
2003-07-22 07:47:27 +00:00
|
|
|
ini.SetPath( KEYMAPS_PATH );
|
2002-08-13 23:26:46 +00:00
|
|
|
if( !ini.ReadFile() )
|
2003-07-22 07:47:27 +00:00
|
|
|
LOG->Warn( "could not input mapping file '%s'.", KEYMAPS_PATH );
|
2002-04-16 17:31:00 +00:00
|
|
|
|
2003-01-18 03:54:41 +00:00
|
|
|
const IniFile::key *Key = ini.GetKey( GAMESTATE->GetCurrentGameDef()->m_szName );
|
2002-04-16 17:31:00 +00:00
|
|
|
|
2003-01-03 22:37:44 +00:00
|
|
|
if( Key )
|
2002-04-16 17:31:00 +00:00
|
|
|
{
|
2003-01-03 22:37:44 +00:00
|
|
|
for( IniFile::key::const_iterator i = Key->begin();
|
|
|
|
|
i != Key->end(); ++i )
|
2002-07-31 19:40:40 +00:00
|
|
|
{
|
2002-10-24 23:08:18 +00:00
|
|
|
CString name = i->first;
|
|
|
|
|
CString value = i->second;
|
2002-04-16 17:31:00 +00:00
|
|
|
|
2002-07-31 19:40:40 +00:00
|
|
|
GameInput GameI;
|
|
|
|
|
GameI.fromString( name );
|
2002-04-16 17:31:00 +00:00
|
|
|
|
2002-07-31 19:40:40 +00:00
|
|
|
CStringArray sDeviceInputStrings;
|
|
|
|
|
split( value, ",", sDeviceInputStrings, false );
|
2002-04-16 17:31:00 +00:00
|
|
|
|
2002-11-16 08:55:46 +00:00
|
|
|
for( unsigned i=0; i<sDeviceInputStrings.size() && i<unsigned(NUM_GAME_TO_DEVICE_SLOTS); i++ )
|
2002-07-31 19:40:40 +00:00
|
|
|
{
|
|
|
|
|
DeviceInput DeviceI;
|
|
|
|
|
DeviceI.fromString( sDeviceInputStrings[i] );
|
|
|
|
|
if( DeviceI.IsValid() )
|
|
|
|
|
SetInputMap( DeviceI, GameI, i );
|
|
|
|
|
}
|
2002-04-16 17:31:00 +00:00
|
|
|
}
|
|
|
|
|
}
|
2002-07-31 19:40:40 +00:00
|
|
|
|
2002-08-13 23:26:46 +00:00
|
|
|
AddDefaultMappingsForCurrentGameIfUnmapped();
|
2002-04-16 17:31:00 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void InputMapper::SaveMappingsToDisk()
|
|
|
|
|
{
|
|
|
|
|
IniFile ini;
|
2003-07-22 07:47:27 +00:00
|
|
|
ini.SetPath( KEYMAPS_PATH );
|
2003-01-18 03:54:41 +00:00
|
|
|
ini.ReadFile();
|
|
|
|
|
|
|
|
|
|
// erase the key so that we overwrite everything for this game
|
|
|
|
|
ini.DeleteKey( GAMESTATE->GetCurrentGameDef()->m_szName );
|
2002-04-16 17:31:00 +00:00
|
|
|
|
|
|
|
|
// iterate over our input map and write all mappings to the ini file
|
2002-07-27 19:29:51 +00:00
|
|
|
for( int i=0; i<MAX_GAME_CONTROLLERS; i++ )
|
2002-04-16 17:31:00 +00:00
|
|
|
{
|
2002-07-27 19:29:51 +00:00
|
|
|
for( int j=0; j<MAX_GAME_BUTTONS; j++ )
|
2002-04-16 17:31:00 +00:00
|
|
|
{
|
|
|
|
|
CString sNameString, sValueString;
|
|
|
|
|
|
2002-07-27 19:29:51 +00:00
|
|
|
GameInput GameI( (GameController)i, (GameButton)j );
|
2002-04-16 17:31:00 +00:00
|
|
|
sNameString = GameI.toString();
|
|
|
|
|
sValueString = ssprintf( "%s,%s,%s",
|
2003-04-25 00:01:35 +00:00
|
|
|
m_GItoDI[i][j][0].toString().c_str(), m_GItoDI[i][j][1].toString().c_str(), m_GItoDI[i][j][2].toString().c_str() );
|
2002-04-16 17:31:00 +00:00
|
|
|
|
2003-01-18 03:54:41 +00:00
|
|
|
ini.SetValue( GAMESTATE->GetCurrentGameDef()->m_szName, sNameString, sValueString );
|
2002-04-16 17:31:00 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ini.WriteFile();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2002-07-31 19:40:40 +00:00
|
|
|
void InputMapper::SetInputMap( DeviceInput DeviceI, GameInput GameI, int iSlotIndex )
|
2002-04-16 17:31:00 +00:00
|
|
|
{
|
|
|
|
|
// remove the old input
|
|
|
|
|
ClearFromInputMap( DeviceI );
|
|
|
|
|
ClearFromInputMap( GameI, iSlotIndex );
|
|
|
|
|
|
2002-07-27 19:29:51 +00:00
|
|
|
m_GItoDI[GameI.controller][GameI.button][iSlotIndex] = DeviceI;
|
2002-04-16 17:31:00 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
UpdateTempDItoGI();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void InputMapper::ClearFromInputMap( DeviceInput DeviceI )
|
|
|
|
|
{
|
|
|
|
|
// search for where this DeviceI maps to
|
|
|
|
|
|
2002-07-27 19:29:51 +00:00
|
|
|
for( int p=0; p<MAX_GAME_CONTROLLERS; p++ )
|
2002-04-16 17:31:00 +00:00
|
|
|
{
|
2002-07-27 19:29:51 +00:00
|
|
|
for( int b=0; b<MAX_GAME_BUTTONS; b++ )
|
2002-04-16 17:31:00 +00:00
|
|
|
{
|
|
|
|
|
for( int s=0; s<NUM_GAME_TO_DEVICE_SLOTS; s++ )
|
|
|
|
|
{
|
|
|
|
|
if( m_GItoDI[p][b][s] == DeviceI )
|
2002-07-31 19:40:40 +00:00
|
|
|
m_GItoDI[p][b][s].MakeInvalid();
|
2002-04-16 17:31:00 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
UpdateTempDItoGI();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void InputMapper::ClearFromInputMap( GameInput GameI, int iSlotIndex )
|
|
|
|
|
{
|
2002-07-31 19:40:40 +00:00
|
|
|
if( !GameI.IsValid() )
|
2002-04-16 17:31:00 +00:00
|
|
|
return;
|
|
|
|
|
|
2002-07-31 19:40:40 +00:00
|
|
|
m_GItoDI[GameI.controller][GameI.button][iSlotIndex].MakeInvalid();
|
2002-04-16 17:31:00 +00:00
|
|
|
|
|
|
|
|
UpdateTempDItoGI();
|
|
|
|
|
}
|
|
|
|
|
|
2002-07-31 19:40:40 +00:00
|
|
|
bool InputMapper::IsMapped( DeviceInput DeviceI )
|
|
|
|
|
{
|
|
|
|
|
return m_tempDItoGI[DeviceI.device][DeviceI.button].IsValid();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool InputMapper::IsMapped( GameInput GameI )
|
|
|
|
|
{
|
|
|
|
|
for( int i=0; i<NUM_GAME_TO_DEVICE_SLOTS; i++ )
|
|
|
|
|
if( m_GItoDI[GameI.controller][GameI.button][i].IsValid() )
|
|
|
|
|
return true;
|
|
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2002-04-16 17:31:00 +00:00
|
|
|
void InputMapper::UpdateTempDItoGI()
|
|
|
|
|
{
|
|
|
|
|
// clear out m_tempDItoGI
|
|
|
|
|
for( int d=0; d<NUM_INPUT_DEVICES; d++ )
|
|
|
|
|
{
|
|
|
|
|
for( int b=0; b<NUM_DEVICE_BUTTONS; b++ )
|
|
|
|
|
{
|
2002-07-31 19:40:40 +00:00
|
|
|
m_tempDItoGI[d][b].MakeInvalid();
|
2002-04-16 17:31:00 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// repopulate m_tempDItoGI
|
2002-07-27 19:29:51 +00:00
|
|
|
for( int n=0; n<MAX_GAME_CONTROLLERS; n++ )
|
2002-04-16 17:31:00 +00:00
|
|
|
{
|
2002-07-27 19:29:51 +00:00
|
|
|
for( int b=0; b<MAX_GAME_BUTTONS; b++ )
|
2002-04-16 17:31:00 +00:00
|
|
|
{
|
|
|
|
|
for( int s=0; s<NUM_GAME_TO_DEVICE_SLOTS; s++ )
|
|
|
|
|
{
|
2002-07-27 19:29:51 +00:00
|
|
|
GameInput GameI( (GameController)n, (GameButton)b );
|
2002-04-16 17:31:00 +00:00
|
|
|
DeviceInput DeviceI = m_GItoDI[n][b][s];
|
|
|
|
|
|
2002-07-31 19:40:40 +00:00
|
|
|
if( DeviceI.IsValid() )
|
|
|
|
|
m_tempDItoGI[DeviceI.device][DeviceI.button] = GameI;
|
2002-04-16 17:31:00 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool InputMapper::DeviceToGame( DeviceInput DeviceI, GameInput& GameI ) // return true if there is a mapping from device to pad
|
|
|
|
|
{
|
|
|
|
|
GameI = m_tempDItoGI[DeviceI.device][DeviceI.button];
|
2002-11-16 08:45:40 +00:00
|
|
|
return GameI.controller != GAME_CONTROLLER_INVALID;
|
2002-04-16 17:31:00 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool InputMapper::GameToDevice( GameInput GameI, int iSoltNum, DeviceInput& DeviceI ) // return true if there is a mapping from pad to device
|
|
|
|
|
{
|
2002-07-27 19:29:51 +00:00
|
|
|
DeviceI = m_GItoDI[GameI.controller][GameI.button][iSoltNum];
|
2002-04-16 17:31:00 +00:00
|
|
|
return DeviceI.device != DEVICE_NONE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void InputMapper::GameToStyle( GameInput GameI, StyleInput &StyleI )
|
|
|
|
|
{
|
2003-01-30 07:18:33 +00:00
|
|
|
if( GAMESTATE->m_CurStyle == STYLE_INVALID )
|
2002-06-14 22:25:22 +00:00
|
|
|
{
|
2002-07-31 19:40:40 +00:00
|
|
|
StyleI.MakeInvalid();
|
2002-06-14 22:25:22 +00:00
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2002-08-22 23:36:03 +00:00
|
|
|
const StyleDef* pStyleDef = GAMESTATE->GetCurrentStyleDef();
|
2002-04-16 17:31:00 +00:00
|
|
|
StyleI = pStyleDef->GameInputToStyleInput( GameI );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void InputMapper::GameToMenu( GameInput GameI, MenuInput &MenuI )
|
|
|
|
|
{
|
2002-08-22 23:36:03 +00:00
|
|
|
const GameDef* pGameDef = GAMESTATE->GetCurrentGameDef();
|
2002-04-16 17:31:00 +00:00
|
|
|
MenuI = pGameDef->GameInputToMenuInput( GameI );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void InputMapper::StyleToGame( StyleInput StyleI, GameInput &GameI )
|
|
|
|
|
{
|
2002-08-22 23:36:03 +00:00
|
|
|
const StyleDef* pStyleDef = GAMESTATE->GetCurrentStyleDef();
|
2002-04-16 17:31:00 +00:00
|
|
|
GameI = pStyleDef->StyleInputToGameInput( StyleI );
|
|
|
|
|
}
|
|
|
|
|
|
2002-07-31 19:40:40 +00:00
|
|
|
|
|
|
|
|
void InputMapper::MenuToGame( MenuInput MenuI, GameInput GameIout[4] )
|
2002-04-16 17:31:00 +00:00
|
|
|
{
|
2002-07-23 01:41:40 +00:00
|
|
|
GameDef* pGameDef = GAMESTATE->GetCurrentGameDef();
|
2002-07-31 19:40:40 +00:00
|
|
|
pGameDef->MenuInputToGameInput( MenuI, GameIout );
|
2002-04-16 17:31:00 +00:00
|
|
|
}
|
|
|
|
|
|
2002-07-31 19:40:40 +00:00
|
|
|
|
2002-04-16 17:31:00 +00:00
|
|
|
bool InputMapper::IsButtonDown( GameInput GameI )
|
|
|
|
|
{
|
|
|
|
|
for( int i=0; i<NUM_GAME_TO_DEVICE_SLOTS; i++ )
|
|
|
|
|
{
|
|
|
|
|
DeviceInput DeviceI;
|
|
|
|
|
|
|
|
|
|
if( GameToDevice( GameI, i, DeviceI ) )
|
2002-09-08 06:11:59 +00:00
|
|
|
if( INPUTFILTER->IsBeingPressed( DeviceI ) )
|
2002-04-16 17:31:00 +00:00
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool InputMapper::IsButtonDown( MenuInput MenuI )
|
|
|
|
|
{
|
2002-07-31 19:40:40 +00:00
|
|
|
GameInput GameI[4];
|
2002-04-16 17:31:00 +00:00
|
|
|
MenuToGame( MenuI, GameI );
|
2002-07-31 19:40:40 +00:00
|
|
|
for( int i=0; i<4; i++ )
|
|
|
|
|
if( GameI[i].IsValid() && IsButtonDown(GameI[i]) )
|
|
|
|
|
return true;
|
|
|
|
|
|
|
|
|
|
return false;
|
2002-04-16 17:31:00 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool InputMapper::IsButtonDown( StyleInput StyleI )
|
|
|
|
|
{
|
|
|
|
|
GameInput GameI;
|
|
|
|
|
StyleToGame( StyleI, GameI );
|
|
|
|
|
return IsButtonDown( GameI );
|
|
|
|
|
}
|
2002-10-18 19:01:32 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
float InputMapper::GetSecsHeld( GameInput GameI )
|
|
|
|
|
{
|
|
|
|
|
float fMaxSecsHeld = 0;
|
|
|
|
|
|
|
|
|
|
for( int i=0; i<NUM_GAME_TO_DEVICE_SLOTS; i++ )
|
|
|
|
|
{
|
|
|
|
|
DeviceInput DeviceI;
|
|
|
|
|
|
|
|
|
|
if( GameToDevice( GameI, i, DeviceI ) )
|
|
|
|
|
fMaxSecsHeld = max( fMaxSecsHeld, INPUTFILTER->GetSecsHeld(DeviceI) );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return fMaxSecsHeld;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
float InputMapper::GetSecsHeld( MenuInput MenuI )
|
|
|
|
|
{
|
|
|
|
|
float fMaxSecsHeld = 0;
|
|
|
|
|
|
|
|
|
|
GameInput GameI[4];
|
|
|
|
|
MenuToGame( MenuI, GameI );
|
|
|
|
|
for( int i=0; i<4; i++ )
|
|
|
|
|
if( GameI[i].IsValid() )
|
|
|
|
|
fMaxSecsHeld = max( fMaxSecsHeld, GetSecsHeld(GameI[i]) );
|
|
|
|
|
|
|
|
|
|
return fMaxSecsHeld;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
float InputMapper::GetSecsHeld( StyleInput StyleI )
|
|
|
|
|
{
|
|
|
|
|
GameInput GameI;
|
|
|
|
|
StyleToGame( StyleI, GameI );
|
|
|
|
|
return GetSecsHeld( GameI );
|
|
|
|
|
}
|