[Soap] Roll back inputcommon changes

git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@2203 8ced0084-cf51-0410-be5f-012b33b47a6e
This commit is contained in:
nakeee 2009-02-10 12:40:06 +00:00
parent cf5fc063ce
commit 3e9b3b266a
15 changed files with 854 additions and 592 deletions

View File

@ -590,7 +590,6 @@
LinkIncremental="1"
SuppressStartupBanner="true"
GenerateManifest="false"
GenerateDebugInformation="true"
ProgramDatabaseFile="$(TargetDir)$(TargetName).pdb"
RandomizedBaseAddress="1"
DataExecutionPrevention="0"

View File

@ -30,17 +30,11 @@ BEGIN_EVENT_TABLE(ConfigDialog,wxDialog)
EVT_CLOSE(ConfigDialog::OnClose)
EVT_BUTTON(ID_CLOSE,ConfigDialog::OnCloseClick)
EVT_BUTTON(ID_PAD_ABOUT,ConfigDialog::DllAbout)
EVT_CHECKBOX(ID_ATTACHED,ConfigDialog::ControllerSettingsChanged)
EVT_CHECKBOX(ID_X360PAD,ConfigDialog::ControllerSettingsChanged)
EVT_CHOICE(ID_X360PAD_CHOICE,ConfigDialog::ControllerSettingsChanged)
EVT_CHECKBOX(ID_RUMBLE,ConfigDialog::ControllerSettingsChanged)
EVT_CHECKBOX(ID_DISABLE,ConfigDialog::ControllerSettingsChanged)
//Recording
EVT_CHECKBOX(ID_RECORDING,ConfigDialog::ControllerSettingsChanged)
EVT_CHECKBOX(ID_PLAYBACK,ConfigDialog::ControllerSettingsChanged)
EVT_BUTTON(ID_SAVE_RECORDING,ConfigDialog::ControllerSettingsChanged)
EVT_BUTTON(CTL_A,ConfigDialog::OnButtonClick)
EVT_BUTTON(CTL_B,ConfigDialog::OnButtonClick)
EVT_BUTTON(CTL_X,ConfigDialog::OnButtonClick)
@ -151,62 +145,18 @@ void ConfigDialog::CreateGUIControls()
#endif
for(int i = 0; i < 4; i++)
{
// --------------------------------------------------------------------
// Settings
// -----------------------------
// Main horizontal container
sDevice[i] = new wxBoxSizer(wxHORIZONTAL);
{
sbDevice[i] = new wxStaticBoxSizer(wxVERTICAL, m_Controller[i], wxT("Controller Settings"));
sDevice[i] = new wxBoxSizer(wxHORIZONTAL);
m_Attached[i] = new wxCheckBox(m_Controller[i], ID_ATTACHED, wxT("Controller attached"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator);
m_Disable[i] = new wxCheckBox(m_Controller[i], ID_DISABLE, wxT("Disable when Dolphin is not in focus"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator);
sbDevice[i]->Add(m_Attached[i], 0, wxEXPAND|wxALL, 1);
sbDevice[i]->Add(m_Disable[i], 0, wxEXPAND|wxALL, 1);
#ifdef _WIN32
m_SizeXInput[i] = new wxStaticBoxSizer(wxVERTICAL, m_Controller[i], wxT("XInput Pad"));
m_X360Pad[i] = new wxCheckBox(m_Controller[i], ID_X360PAD, wxT("Enable X360Pad"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator);
m_X360PadC[i] = new wxChoice(m_Controller[i], ID_X360PAD_CHOICE, wxDefaultPosition, wxDefaultSize, arrayStringFor_X360Pad, 0, wxDefaultValidator);
m_Rumble[i] = new wxCheckBox(m_Controller[i], ID_RUMBLE, wxT("Enable rumble"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator);
m_SizeXInput[i]->Add(m_X360Pad[i], 0, wxEXPAND | wxALL, 1);
m_SizeXInput[i]->Add(m_X360PadC[i], 0, wxEXPAND | wxALL, 1);
m_SizeXInput[i]->Add(m_Rumble[i], 0, wxEXPAND | wxALL, 1);
#endif
m_SizeRecording[i] = new wxStaticBoxSizer(wxVERTICAL, m_Controller[i], wxT("Input Recording"));
m_CheckRecording[i] = new wxCheckBox(m_Controller[i], ID_RECORDING, wxT("Record input"));
m_CheckPlayback[i] = new wxCheckBox(m_Controller[i], ID_PLAYBACK, wxT("Play back input"));
m_BtnSaveRecording[i] = new wxButton(m_Controller[i], ID_SAVE_RECORDING, wxT("Save recording"), wxDefaultPosition, wxDefaultSize);
// Tool tips
m_CheckRecording[i]->SetToolTip(wxT("Your recording will be saved to pad-record.bin in the Dolphin dir when you stop the game"));
m_CheckPlayback[i]->SetToolTip(wxT("Play back the pad-record.bin file from the Dolphin dir"));
m_BtnSaveRecording[i]->SetToolTip(wxT(
"This will save the current recording to pad-record.bin. Your recording will\n"
"also be automatically saved every 60 * 10 frames. And when you shut down the\n"
"game."));
m_SizeRecording[i]->Add(m_CheckRecording[i], 0, wxEXPAND | wxALL, 1);
m_SizeRecording[i]->Add(m_CheckPlayback[i], 0, wxEXPAND | wxALL, 1);
m_SizeRecording[i]->Add(m_BtnSaveRecording[i], 0, wxEXPAND | wxALL, 1);
// Set values
m_Disable[i] = new wxCheckBox(m_Controller[i], ID_DISABLE, wxT("Disable when Dolphin is not in focus"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator);
m_Attached[i]->SetValue(pad[i].bAttached);
m_Disable[i]->SetValue(pad[i].bDisable);
m_CheckRecording[i]->SetValue(pad[i].bRecording);
m_CheckPlayback[i]->SetValue(pad[i].bPlayback);
// Only enable these options for pad 0
m_CheckRecording[i]->Enable(false); m_CheckRecording[0]->Enable(true);
m_CheckPlayback[i]->Enable(false); m_CheckPlayback[0]->Enable(true);
m_BtnSaveRecording[i]->Enable(false); m_BtnSaveRecording[0]->Enable(true);
// Don't allow saving when we are not recording
m_BtnSaveRecording[i]->Enable(g_EmulatorRunning && pad[0].bRecording);
#ifdef _WIN32
// Check if any XInput pad was found
if (arrayStringFor_X360Pad.IsEmpty())
{
m_X360Pad[i]->SetLabel(wxT("Enable X360Pad - No pad connected"));
@ -225,21 +175,19 @@ void ConfigDialog::CreateGUIControls()
m_Rumble[i]->Enable(m_X360Pad[i]->IsChecked());
}
#endif
// Sizers
sDevice[i]->Add(sbDevice[i], 0, wxEXPAND | wxALL, 1);
//sDevice[i]->AddStretchSpacer();
m_Disable[i]->SetValue(pad[i].bDisable);
sDevice[i]->Add(m_Attached[i], 0, wxEXPAND|wxALL, 1);
sDevice[i]->AddStretchSpacer();
#ifdef _WIN32
sDevice[i]->Add(m_SizeXInput[i], 0, wxEXPAND | wxALL, 1);
sDevice[i]->Add(m_SizeRecording[i], 0, wxEXPAND | wxALL, 1);
sDevice[i]->Add(m_X360Pad[i], 0, wxEXPAND|wxALL, 1);
sDevice[i]->Add(m_X360PadC[i], 0, wxEXPAND|wxALL, 1);
sDevice[i]->Add(m_Rumble[i], 0, wxEXPAND|wxALL, 1);
sDevice[i]->AddStretchSpacer();
#endif
// -----------------------------------
sDevice[i]->Add(m_Disable[i], 0, wxEXPAND|wxALL, 1);
sbDevice[i]->Add(sDevice[i], 0, wxEXPAND|wxALL, 1);
// --------------------------------------------------------------------
// Buttons
// -----------------------------
sButtons[i] = new wxStaticBoxSizer(wxVERTICAL, m_Controller[i], wxT("Buttons"));
AddControl(m_Controller[i], &(m_ButtonA[i]), sButtons[i], "A: ", CTL_A, i);
@ -279,13 +227,10 @@ void ConfigDialog::CreateGUIControls()
AddControl(m_Controller[i], &(m_CStickLeft[i]), sCStick[i], "Left: ", CTL_SUBLEFT, i);
AddControl(m_Controller[i], &(m_CStickRight[i]), sCStick[i], "Right: ", CTL_SUBRIGHT, i);
// --------------------------------------------------------------------
// Sizers
// -----------------------------
sPage[i] = new wxGridBagSizer(0, 0);
sPage[i]->SetFlexibleDirection(wxBOTH);
sPage[i]->SetNonFlexibleGrowMode(wxFLEX_GROWMODE_SPECIFIED);
sPage[i]->Add(sDevice[i], wxGBPosition(0, 0), wxGBSpan(1, 5), wxEXPAND|wxALL, 1);
sPage[i]->Add(sbDevice[i], wxGBPosition(0, 0), wxGBSpan(1, 5), wxEXPAND|wxALL, 1);
sPage[i]->Add(sButtons[i], wxGBPosition(1, 0), wxGBSpan(2, 1), wxALL, 1);
sPage[i]->Add(sTriggers[i], wxGBPosition(1, 1), wxGBSpan(1, 1), wxEXPAND|wxALL, 1);
sPage[i]->Add(sModifiers[i], wxGBPosition(2, 1), wxGBSpan(1, 1), wxALL, 1);
@ -346,15 +291,9 @@ void ConfigDialog::ControllerSettingsChanged(wxCommandEvent& event)
switch (event.GetId())
{
// General settings
case ID_ATTACHED:
pad[page].bAttached = m_Attached[page]->GetValue();
break;
case ID_DISABLE:
pad[page].bDisable = m_Disable[page]->GetValue();
break;
// XInput
case ID_X360PAD:
pad[page].bEnableXPad = event.IsChecked();
m_Rumble[page]->Enable(event.IsChecked());
@ -366,22 +305,9 @@ void ConfigDialog::ControllerSettingsChanged(wxCommandEvent& event)
case ID_RUMBLE:
pad[page].bRumble = m_Rumble[page]->GetValue();
break;
case ID_RECORDING:
pad[page].bRecording = m_CheckRecording[page]->GetValue();
// Turn off the other option
pad[page].bPlayback = false; m_CheckPlayback[page]->SetValue(false);
case ID_DISABLE:
pad[page].bDisable = m_Disable[page]->GetValue();
break;
case ID_PLAYBACK:
pad[page].bPlayback = m_CheckPlayback[page]->GetValue();
// Turn off the other option
pad[page].bRecording = false; m_CheckRecording[page]->SetValue(false);
break;
case ID_SAVE_RECORDING:
// Double check again that we are still running a game
if (g_EmulatorRunning) SaveRecord();
break;
}
}

View File

@ -50,7 +50,7 @@ class ConfigDialog : public wxDialog
wxButton *m_About;
wxButton *m_Close;
wxStaticBoxSizer *sbDevice[4], *m_SizeXInput[4], *m_SizeRecording[4];
wxStaticBoxSizer *sbDevice[4];
wxBoxSizer *sDevice[4];
wxGridBagSizer *sPage[4];
wxStaticBoxSizer *sButtons[4];
@ -67,11 +67,6 @@ class ConfigDialog : public wxDialog
wxCheckBox *m_Disable[4];
wxCheckBox *m_Rumble[4];
// Recording
wxCheckBox *m_CheckRecording[4];
wxCheckBox *m_CheckPlayback[4];
wxButton *m_BtnSaveRecording[4];
wxButton *m_ButtonA[4];
wxButton *m_ButtonB[4];
wxButton *m_ButtonX[4];
@ -104,19 +99,11 @@ class ConfigDialog : public wxDialog
ID_CONTROLLERPAGE3,
ID_CONTROLLERPAGE4,
// XInput pad
ID_X360PAD_CHOICE,
ID_X360PAD,
ID_RUMBLE,
// Input recording
ID_RECORDING,
ID_PLAYBACK,
ID_SAVE_RECORDING,
// General settings
ID_ATTACHED,
ID_DISABLE,
ID_RUMBLE,
ID_PAD_ABOUT
};

View File

@ -15,10 +15,6 @@
// Official SVN repository and contact information can be found at
// http://code.google.com/p/dolphin-emu/
//////////////////////////////////////////////////////////////////////////////////////////
// Include
// ¯¯¯¯¯¯¯¯¯¯¯¯¯
#include <stdio.h>
#include <math.h>
@ -26,69 +22,43 @@
#include "pluginspecs_pad.h"
#include "PadSimple.h"
#include "IniFile.h"
#include "ConsoleWindow.h"
#include "StringUtil.h"
#include "ChunkFile.h"
#if defined(HAVE_WX) && HAVE_WX
#include "GUI/ConfigDlg.h"
#include "GUI/ConfigDlg.h"
#endif
#ifdef _WIN32
#include "XInput.h"
#include "DirectInputBase.h"
#include "XInput.h"
#include "DirectInputBase.h"
DInput dinput;
//#elif defined(USE_SDL) && USE_SDL
//#include <SDL.h>
DInput dinput;
//#elif defined(USE_SDL) && USE_SDL
//#include <SDL.h>
#elif defined(HAVE_X11) && HAVE_X11
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/keysym.h>
#include <X11/XKBlib.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/keysym.h>
#include <X11/XKBlib.h>
Display* GXdsp;
bool KeyStatus[NUMCONTROLS];
Display* GXdsp;
bool KeyStatus[NUMCONTROLS];
#elif defined(HAVE_COCOA) && HAVE_COCOA
#include <Cocoa/Cocoa.h>
bool KeyStatus[NUMCONTROLS];
#include <Cocoa/Cocoa.h>
bool KeyStatus[NUMCONTROLS];
#endif
////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////
// Declarations
// ¯¯¯¯¯¯¯¯¯¯¯¯¯
SPads pad[4];
HINSTANCE g_hInstance;
SPADInitialize g_PADInitialize;
////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////
// Input Recording
// ¯¯¯¯¯¯¯¯¯¯¯¯¯
// Enable these to record or play back
//#define RECORD_REPLAY
//#define RECORD_STORE
// Pre defined maxium storage limit
#define RECORD_SIZE (1024 * 128)
SPADStatus recordBuffer[RECORD_SIZE];
int count = 0;
bool g_EmulatorRunning = false;
////////////////////////////////
// TODO: fix this dirty hack to stop missing symbols
void __Log(int log, const char *format, ...) {}
void __Logv(int log, int v, const char *format, ...) {}
//******************************************************************************
// Supporting functions
@ -96,68 +66,46 @@ void __Logv(int log, int v, const char *format, ...) {}
void RecordInput(const SPADStatus& _rPADStatus)
{
if (count >= RECORD_SIZE) return;
if (count >= RECORD_SIZE)
{
return;
}
recordBuffer[count++] = _rPADStatus;
// Logging
//u8 TmpData[sizeof(SPADStatus)];
//memcpy(TmpData, &recordBuffer[count - 1], sizeof(SPADStatus));
//Console::Print("RecordInput(%i): %s\n", count, ArrayToString(TmpData, sizeof(SPADStatus), 0, 30).c_str());
// Auto save every ten seconds
if (count % (60 * 10) == 0) SaveRecord();
}
const SPADStatus& PlayRecord()
{
// Logging
//Console::Print("PlayRecord(%i)\n", count);
if (count >= RECORD_SIZE){return(recordBuffer[0]);}
if (count >= RECORD_SIZE)
{
// Todo: Make the recording size unlimited?
//PanicAlert("The recording reached its end");
return(recordBuffer[0]);
}
return(recordBuffer[count++]);
}
void LoadRecord()
{
FILE* pStream = fopen("pad-record.bin", "rb");
FILE* pStream = fopen("c:\\pad-record.bin", "rb");
if (pStream != NULL)
{
fread(recordBuffer, 1, RECORD_SIZE * sizeof(SPADStatus), pStream);
fclose(pStream);
}
else
{
PanicAlert("SimplePad: Could not open pad-record.bin");
}
//Console::Print("LoadRecord()");
}
void SaveRecord()
{
// Open the file in a way that clears all old data
FILE* pStream = fopen("pad-record.bin", "wb");
FILE* pStream = fopen("c:\\pad-record.bin", "wb");
if (pStream != NULL)
{
fwrite(recordBuffer, 1, RECORD_SIZE * sizeof(SPADStatus), pStream);
fclose(pStream);
}
else
{
PanicAlert("SimplePad: Could not save pad-record.bin");
}
//PanicAlert("SaveRecord()");
//Console::Print("SaveRecord()");
}
// Check if Dolphin is in focus
bool IsFocus()
{
@ -219,6 +167,89 @@ BOOL APIENTRY DllMain(HINSTANCE hinstDLL, // DLL module handle
#endif
//******************************************************************************
// Plugin specification functions
//******************************************************************************
void GetDllInfo(PLUGIN_INFO* _PluginInfo)
{
_PluginInfo->Version = 0x0100;
_PluginInfo->Type = PLUGIN_TYPE_PAD;
#ifdef DEBUGFAST
sprintf(_PluginInfo->Name, "Dolphin KB/X360pad (DebugFast)");
#else
#ifndef _DEBUG
sprintf(_PluginInfo->Name, "Dolphin KB/X360pad");
#else
sprintf(_PluginInfo->Name, "Dolphin KB/X360pad (Debug)");
#endif
#endif
}
void SetDllGlobals(PLUGIN_GLOBALS* _pPluginGlobals) {
}
void DllConfig(HWND _hParent)
{
LoadConfig();
#ifdef _WIN32
wxWindow win;
win.SetHWND(_hParent);
ConfigDialog frame(&win);
frame.ShowModal();
win.SetHWND(0);
#elif defined(HAVE_WX) && HAVE_WX
ConfigDialog frame(NULL);
frame.ShowModal();
#endif
SaveConfig();
}
void DllDebugger(HWND _hParent, bool Show) {
}
void Initialize(void *init)
{
#ifdef RECORD_REPLAY
LoadRecord();
#endif
g_PADInitialize = *(SPADInitialize*)init;
#ifdef _WIN32
dinput.Init((HWND)g_PADInitialize.hWnd);
#elif defined(HAVE_X11) && HAVE_X11
GXdsp = (Display*)g_PADInitialize.hWnd;
#elif defined(HAVE_COCOA) && HAVE_COCOA
#endif
LoadConfig();
}
void DoState(unsigned char **ptr, int mode) {
}
void Shutdown()
{
#ifdef RECORD_STORE
SaveRecord();
#endif
#ifdef _WIN32
dinput.Free();
// Kill xpad rumble
XINPUT_VIBRATION vib;
vib.wLeftMotorSpeed = 0;
vib.wRightMotorSpeed = 0;
for (int i = 0; i < 4; i++)
if (pad[i].bRumble)
XInputSetState(pad[i].XPadPlayer, &vib);
#endif
SaveConfig();
}
const float kDeadZone = 0.1f;
// Implement circular deadzone
@ -252,9 +283,6 @@ void ScaleStickValues(unsigned char* outx,
*outy = 0x80 + iy;
}
//******************************************************************************
// Input
//******************************************************************************
#ifdef _WIN32
void DInput_Read(int _numPAD, SPADStatus* _pPADStatus)
@ -306,8 +334,6 @@ void DInput_Read(int _numPAD, SPADStatus* _pPADStatus)
if (dinput.diks[pad[_numPAD].keyForControl[CTL_DPADLEFT]] & 0xFF){_pPADStatus->button |= PAD_BUTTON_LEFT;}
if (dinput.diks[pad[_numPAD].keyForControl[CTL_DPADRIGHT]]& 0xFF){_pPADStatus->button |= PAD_BUTTON_RIGHT;}
if (dinput.diks[pad[_numPAD].keyForControl[CTL_START]] & 0xFF){_pPADStatus->button |= PAD_BUTTON_START;}
_pPADStatus->MicButton = (dinput.diks[pad[_numPAD].keyForControl[CTL_MIC]] & 0xFF) ? true : false;
}
bool XInput_Read(int XPadPlayer, SPADStatus* _pPADStatus)
@ -355,8 +381,6 @@ bool XInput_Read(int XPadPlayer, SPADStatus* _pPADStatus)
if (xpad.wButtons & XINPUT_GAMEPAD_DPAD_UP) {_pPADStatus->button |= PAD_BUTTON_UP;}
if (xpad.wButtons & XINPUT_GAMEPAD_DPAD_DOWN) {_pPADStatus->button |= PAD_BUTTON_DOWN;}
//_pPADStatus->MicButton = (xpad.wButtons & XINPUT_GAMEPAD_LEFT_SHOULDER) ? true : false;
return true;
}
else
@ -586,124 +610,25 @@ void cocoa_Read(int _numPAD, SPADStatus* _pPADStatus)
}
#endif
//******************************************************************************
// Plugin specification functions
//******************************************************************************
void GetDllInfo(PLUGIN_INFO* _PluginInfo)
{
_PluginInfo->Version = 0x0100;
_PluginInfo->Type = PLUGIN_TYPE_PAD;
#ifdef DEBUGFAST
sprintf(_PluginInfo->Name, "Dolphin KB/X360pad (DebugFast)");
#else
#ifndef _DEBUG
sprintf(_PluginInfo->Name, "Dolphin KB/X360pad");
#else
sprintf(_PluginInfo->Name, "Dolphin KB/X360pad (Debug)");
#endif
#endif
}
void SetDllGlobals(PLUGIN_GLOBALS* _pPluginGlobals) {}
void DllConfig(HWND _hParent)
{
LoadConfig();
#ifdef _WIN32
wxWindow win;
win.SetHWND(_hParent);
ConfigDialog frame(&win);
frame.ShowModal();
win.SetHWND(0);
#elif defined(HAVE_WX) && HAVE_WX
ConfigDialog frame(NULL);
frame.ShowModal();
#endif
SaveConfig();
}
void DllDebugger(HWND _hParent, bool Show) {}
void Initialize(void *init)
{
//Console::Open(70, 5000);
// We are now running a game
g_EmulatorRunning = true;
// Load configuration
LoadConfig();
// Load recorded input if we are to play it back, otherwise begin with a blank recording
if (pad[0].bPlayback) LoadRecord();
g_PADInitialize = *(SPADInitialize*)init;
#ifdef _WIN32
dinput.Init((HWND)g_PADInitialize.hWnd);
#elif defined(HAVE_X11) && HAVE_X11
GXdsp = (Display*)g_PADInitialize.hWnd;
#elif defined(HAVE_COCOA) && HAVE_COCOA
#endif
}
void DoState(unsigned char **ptr, int mode)
{
// Load or save the counter
PointerWrap p(ptr, mode);
p.Do(count);
}
void Shutdown()
{
//Console::Print("ShutDown()\n");
// Save recording
if (pad[0].bRecording) SaveRecord();
// Reset the counter
count = 0;
// We have stopped the game
g_EmulatorRunning = false;
#ifdef _WIN32
dinput.Free();
// Kill xpad rumble
XINPUT_VIBRATION vib;
vib.wLeftMotorSpeed = 0;
vib.wRightMotorSpeed = 0;
for (int i = 0; i < 4; i++)
if (pad[i].bRumble)
XInputSetState(pad[i].XPadPlayer, &vib);
#endif
SaveConfig();
}
// Set buttons status from wxWidgets in the main application
// ¯¯¯¯¯¯¯¯¯¯¯¯¯¯
void PAD_Input(u16 _Key, u8 _UpDown) {}
void PAD_Input(u16 _Key, u8 _UpDown) {
}
void PAD_GetStatus(u8 _numPAD, SPADStatus* _pPADStatus)
{
// Check if all is okay
if (_pPADStatus == NULL) return;
// Play back input instead of accepting any user input
if (pad[0].bPlayback)
if ((_pPADStatus == NULL))
{
*_pPADStatus = PlayRecord();
return;
}
#ifdef RECORD_REPLAY
*_pPADStatus = PlayRecord();
return;
#endif
const int base = 0x80;
// Clear pad
memset(_pPADStatus, 0, sizeof(SPADStatus));
@ -714,18 +639,15 @@ void PAD_GetStatus(u8 _numPAD, SPADStatus* _pPADStatus)
_pPADStatus->substickY = base;
_pPADStatus->button |= PAD_USE_ORIGIN;
#ifdef _WIN32
// Only update pad on focus, don't do this when recording
if (pad[_numPAD].bDisable && !pad[0].bRecording && !IsFocus()) return;
// Just update pad on focus
if (pad[_numPAD].bDisable)
{
if (!IsFocus()) return;
}
// Dolphin doesn't really care about the pad error codes anyways...
_pPADStatus->err = PAD_ERR_NONE;
// Read XInput
if (pad[_numPAD].bEnableXPad) XInput_Read(pad[_numPAD].XPadPlayer, _pPADStatus);
// Read Direct Input
DInput_Read(_numPAD, _pPADStatus);
#elif defined(HAVE_X11) && HAVE_X11
_pPADStatus->err = PAD_ERR_NONE;
X11_Read(_numPAD, _pPADStatus);
@ -734,8 +656,9 @@ void PAD_GetStatus(u8 _numPAD, SPADStatus* _pPADStatus)
cocoa_Read(_numPAD, _pPADStatus);
#endif
// Record input
if (pad[0].bRecording) RecordInput(*_pPADStatus);
#ifdef RECORD_STORE
RecordInput(*_pPADStatus);
#endif
}
@ -819,8 +742,7 @@ void LoadConfig()
DIK_G,
DIK_F,
DIK_H,
DIK_LSHIFT, //halfpress
DIK_M //Mic
DIK_LSHIFT
};
#elif defined(HAVE_X11) && HAVE_X11
const int defaultKeyForControl[NUMCONTROLS] =
@ -846,7 +768,7 @@ void LoadConfig()
XK_f,
XK_h,
XK_Shift_L, //halfpress
XK_p //Mic
XK_p
};
#elif defined(HAVE_COCOA) && HAVE_COCOA
const int defaultKeyForControl[NUMCONTROLS] =
@ -872,7 +794,7 @@ void LoadConfig()
3,
4,
56, //halfpress
35 //Mic
35
};
#endif
IniFile file;
@ -889,9 +811,6 @@ void LoadConfig()
file.Get(SectionName, "Rumble", &pad[i].bRumble, true);
file.Get(SectionName, "XPad#", &pad[i].XPadPlayer);
file.Get(SectionName, "Recording", &pad[i].bRecording, false);
file.Get(SectionName, "Playback", &pad[i].bPlayback, false);
for (int x = 0; x < NUMCONTROLS; x++)
{
file.Get(SectionName, controlNames[x], &pad[i].keyForControl[x],
@ -921,9 +840,6 @@ void SaveConfig()
file.Set(SectionName, "DisableOnBackground", pad[i].bDisable);
file.Set(SectionName, "Rumble", pad[i].bRumble);
file.Set(SectionName, "XPad#", pad[i].XPadPlayer);
// Recording
file.Set(SectionName, "Recording", pad[i].bRecording);
file.Set(SectionName, "Playback", pad[i].bPlayback);
for (int x = 0; x < NUMCONTROLS; x++)
{

View File

@ -73,26 +73,19 @@ static const char* controlNames[] =
"Mic-button",
};
struct SPads
{
struct SPads {
bool bEnableXPad; // Use an XPad in addition to the keyboard?
bool bAttached; // Pad is "attached" to the gamecube/wii
bool bDisable; // Disabled when dolphin isn't in focus
bool bRumble; // Rumble for xpad
bool bRecording;
bool bPlayback;
int XPadPlayer; // Player# of the xpad
unsigned int keyForControl[NUMCONTROLS];// Keyboard mapping
};
extern SPads pad[];
extern bool g_EmulatorRunning;
void LoadConfig();
void SaveConfig();
bool IsFocus();
// Input Recording
void SaveRecord();
#endif

View File

@ -522,6 +522,14 @@
RelativePath=".\Src\Rumble.cpp"
>
</File>
<File
RelativePath=".\Src\XInput.cpp"
>
</File>
<File
RelativePath=".\Src\XInput.h"
>
</File>
</Filter>
<Filter
Name="GUI"

View File

@ -109,7 +109,6 @@ void Config::Save(int Slot)
file.Set("General", "ShowAdvanced", g_Config.bShowAdvanced);
file.Set("General", "SaveByID", g_Config.bSaveByID);
file.Set("General", "CheckForFocus", g_Config.bCheckFocus);
file.Set("General", "NoTriggerFilter", g_Config.bNoTriggerFilter);
// ========================
for (int i = 0; i < 4; i++)
@ -142,23 +141,23 @@ void Config::Save(int Slot)
SectionName = joyinfo[PadMapping[i].ID].Name;
}
file.Set(SectionName.c_str(), "l_shoulder", PadMapping[i].buttons[InputCommon::CTL_L_SHOULDER]);
file.Set(SectionName.c_str(), "r_shoulder", PadMapping[i].buttons[InputCommon::CTL_R_SHOULDER]);
file.Set(SectionName.c_str(), "a_button", PadMapping[i].buttons[InputCommon::CTL_A_BUTTON]);
file.Set(SectionName.c_str(), "b_button", PadMapping[i].buttons[InputCommon::CTL_B_BUTTON]);
file.Set(SectionName.c_str(), "x_button", PadMapping[i].buttons[InputCommon::CTL_X_BUTTON]);
file.Set(SectionName.c_str(), "y_button", PadMapping[i].buttons[InputCommon::CTL_Y_BUTTON]);
file.Set(SectionName.c_str(), "z_trigger", PadMapping[i].buttons[InputCommon::CTL_Z_TRIGGER]);
file.Set(SectionName.c_str(), "start_button", PadMapping[i].buttons[InputCommon::CTL_START]);
file.Set(SectionName.c_str(), "l_shoulder", PadMapping[i].buttons[CTL_L_SHOULDER]);
file.Set(SectionName.c_str(), "r_shoulder", PadMapping[i].buttons[CTL_R_SHOULDER]);
file.Set(SectionName.c_str(), "a_button", PadMapping[i].buttons[CTL_A_BUTTON]);
file.Set(SectionName.c_str(), "b_button", PadMapping[i].buttons[CTL_B_BUTTON]);
file.Set(SectionName.c_str(), "x_button", PadMapping[i].buttons[CTL_X_BUTTON]);
file.Set(SectionName.c_str(), "y_button", PadMapping[i].buttons[CTL_Y_BUTTON]);
file.Set(SectionName.c_str(), "z_trigger", PadMapping[i].buttons[CTL_Z_TRIGGER]);
file.Set(SectionName.c_str(), "start_button", PadMapping[i].buttons[CTL_START]);
file.Set(SectionName.c_str(), "dpad", PadMapping[i].dpad);
file.Set(SectionName.c_str(), "dpad_up", PadMapping[i].dpad2[InputCommon::CTL_D_PAD_UP]);
file.Set(SectionName.c_str(), "dpad_down", PadMapping[i].dpad2[InputCommon::CTL_D_PAD_DOWN]);
file.Set(SectionName.c_str(), "dpad_left", PadMapping[i].dpad2[InputCommon::CTL_D_PAD_LEFT]);
file.Set(SectionName.c_str(), "dpad_right", PadMapping[i].dpad2[InputCommon::CTL_D_PAD_RIGHT]);
file.Set(SectionName.c_str(), "main_x", PadMapping[i].axis[InputCommon::CTL_MAIN_X]);
file.Set(SectionName.c_str(), "main_y", PadMapping[i].axis[InputCommon::CTL_MAIN_Y]);
file.Set(SectionName.c_str(), "sub_x", PadMapping[i].axis[InputCommon::CTL_SUB_X]);
file.Set(SectionName.c_str(), "sub_y", PadMapping[i].axis[InputCommon::CTL_SUB_Y]);
file.Set(SectionName.c_str(), "dpad_up", PadMapping[i].dpad2[CTL_D_PAD_UP]);
file.Set(SectionName.c_str(), "dpad_down", PadMapping[i].dpad2[CTL_D_PAD_DOWN]);
file.Set(SectionName.c_str(), "dpad_left", PadMapping[i].dpad2[CTL_D_PAD_LEFT]);
file.Set(SectionName.c_str(), "dpad_right", PadMapping[i].dpad2[CTL_D_PAD_RIGHT]);
file.Set(SectionName.c_str(), "main_x", PadMapping[i].axis[CTL_MAIN_X]);
file.Set(SectionName.c_str(), "main_y", PadMapping[i].axis[CTL_MAIN_Y]);
file.Set(SectionName.c_str(), "sub_x", PadMapping[i].axis[CTL_SUB_X]);
file.Set(SectionName.c_str(), "sub_y", PadMapping[i].axis[CTL_SUB_Y]);
file.Set(SectionName.c_str(), "deadzone", PadMapping[i].deadzone);
file.Set(SectionName.c_str(), "halfpress", PadMapping[i].halfpress);
@ -168,7 +167,7 @@ void Config::Save(int Slot)
file.Set(SectionName.c_str(), "eventnum", PadMapping[i].eventnum);
file.Set(SectionName.c_str(), "Diagonal", PadMapping[i].SDiagonal);
file.Set(SectionName.c_str(), "SquareToCircle", PadMapping[i].bSquareToCircle);
file.Set(SectionName.c_str(), "SquareToCircle", PadMapping[i].bSquareToCircle);
// ======================================
// Debugging
@ -197,8 +196,6 @@ void Config::Load(bool ChangePad, bool ChangeSaveByID)
// ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
file.Get("General", "ShowAdvanced", &g_Config.bShowAdvanced, false);
file.Get("General", "CheckForFocus", &g_Config.bCheckFocus, false);
file.Get("General", "NoTriggerFilter", &g_Config.bNoTriggerFilter, false);
if(!ChangeSaveByID)
{
file.Get("General", "SaveByID", &Tmp, false); g_Config.bSaveByID = Tmp;
@ -231,23 +228,23 @@ void Config::Load(bool ChangePad, bool ChangeSaveByID)
SectionName = joyinfo[PadMapping[i].ID].Name;
}
file.Get(SectionName.c_str(), "l_shoulder", &PadMapping[i].buttons[InputCommon::CTL_L_SHOULDER], 4);
file.Get(SectionName.c_str(), "r_shoulder", &PadMapping[i].buttons[InputCommon::CTL_R_SHOULDER], 5);
file.Get(SectionName.c_str(), "a_button", &PadMapping[i].buttons[InputCommon::CTL_A_BUTTON], 0);
file.Get(SectionName.c_str(), "b_button", &PadMapping[i].buttons[InputCommon::CTL_B_BUTTON], 1);
file.Get(SectionName.c_str(), "x_button", &PadMapping[i].buttons[InputCommon::CTL_X_BUTTON], 3);
file.Get(SectionName.c_str(), "y_button", &PadMapping[i].buttons[InputCommon::CTL_Y_BUTTON], 2);
file.Get(SectionName.c_str(), "z_trigger", &PadMapping[i].buttons[InputCommon::CTL_Z_TRIGGER], 7);
file.Get(SectionName.c_str(), "start_button", &PadMapping[i].buttons[InputCommon::CTL_START], 9);
file.Get(SectionName.c_str(), "l_shoulder", &PadMapping[i].buttons[CTL_L_SHOULDER], 4);
file.Get(SectionName.c_str(), "r_shoulder", &PadMapping[i].buttons[CTL_R_SHOULDER], 5);
file.Get(SectionName.c_str(), "a_button", &PadMapping[i].buttons[CTL_A_BUTTON], 0);
file.Get(SectionName.c_str(), "b_button", &PadMapping[i].buttons[CTL_B_BUTTON], 1);
file.Get(SectionName.c_str(), "x_button", &PadMapping[i].buttons[CTL_X_BUTTON], 3);
file.Get(SectionName.c_str(), "y_button", &PadMapping[i].buttons[CTL_Y_BUTTON], 2);
file.Get(SectionName.c_str(), "z_trigger", &PadMapping[i].buttons[CTL_Z_TRIGGER], 7);
file.Get(SectionName.c_str(), "start_button", &PadMapping[i].buttons[CTL_START], 9);
file.Get(SectionName.c_str(), "dpad", &PadMapping[i].dpad, 0);
file.Get(SectionName.c_str(), "dpad_up", &PadMapping[i].dpad2[InputCommon::CTL_D_PAD_UP], 0);
file.Get(SectionName.c_str(), "dpad_down", &PadMapping[i].dpad2[InputCommon::CTL_D_PAD_DOWN], 0);
file.Get(SectionName.c_str(), "dpad_left", &PadMapping[i].dpad2[InputCommon::CTL_D_PAD_LEFT], 0);
file.Get(SectionName.c_str(), "dpad_right", &PadMapping[i].dpad2[InputCommon::CTL_D_PAD_RIGHT], 0);
file.Get(SectionName.c_str(), "main_x", &PadMapping[i].axis[InputCommon::CTL_MAIN_X], 0);
file.Get(SectionName.c_str(), "main_y", &PadMapping[i].axis[InputCommon::CTL_MAIN_Y], 1);
file.Get(SectionName.c_str(), "sub_x", &PadMapping[i].axis[InputCommon::CTL_SUB_X], 2);
file.Get(SectionName.c_str(), "sub_y", &PadMapping[i].axis[InputCommon::CTL_SUB_Y], 3);
file.Get(SectionName.c_str(), "dpad_up", &PadMapping[i].dpad2[CTL_D_PAD_UP], 0);
file.Get(SectionName.c_str(), "dpad_down", &PadMapping[i].dpad2[CTL_D_PAD_DOWN], 0);
file.Get(SectionName.c_str(), "dpad_left", &PadMapping[i].dpad2[CTL_D_PAD_LEFT], 0);
file.Get(SectionName.c_str(), "dpad_right", &PadMapping[i].dpad2[CTL_D_PAD_RIGHT], 0);
file.Get(SectionName.c_str(), "main_x", &PadMapping[i].axis[CTL_MAIN_X], 0);
file.Get(SectionName.c_str(), "main_y", &PadMapping[i].axis[CTL_MAIN_Y], 1);
file.Get(SectionName.c_str(), "sub_x", &PadMapping[i].axis[CTL_SUB_X], 2);
file.Get(SectionName.c_str(), "sub_y", &PadMapping[i].axis[CTL_SUB_Y], 3);
file.Get(SectionName.c_str(), "deadzone", &PadMapping[i].deadzone, 9);
file.Get(SectionName.c_str(), "halfpress", &PadMapping[i].halfpress, -1);

View File

@ -29,7 +29,6 @@ struct Config
bool bShowAdvanced; // Only allow one of these
bool bSaveByID;
bool bCheckFocus;
bool bNoTriggerFilter;
};
extern Config g_Config;

View File

@ -37,7 +37,7 @@
#include "../nJoy.h"
#include "Images/controller.xpm"
extern bool g_EmulatorRunning;
extern bool emulator_running;
////////////////////////
/* If we don't use this hack m_MainSizer->GetMinSize().GetWidth() will not change
@ -70,10 +70,8 @@ void ConfigBox::PadGetStatus()
int PhysicalDevice = PadMapping[notebookpage].ID;
int TriggerType = PadMapping[notebookpage].triggertype;
// Check that Dolphin is in focus, otherwise don't update the pad status
if (!g_Config.bCheckFocus && IsFocus())
InputCommon::GetJoyState(PadState[notebookpage], PadMapping[notebookpage], notebookpage, joyinfo[PadMapping[notebookpage].ID].NumButtons);
// Get pad status
GetJoyState(notebookpage);
//////////////////////////////////////
// Analog stick
@ -83,8 +81,8 @@ void ConfigBox::PadGetStatus()
//int deadzone2 = (int)(((float)(-128.00/100.00)) * (float)(PadMapping[_numPAD].deadzone+1));
// Get original values
int main_x = PadState[notebookpage].axis[InputCommon::CTL_MAIN_X];
int main_y = PadState[notebookpage].axis[InputCommon::CTL_MAIN_Y];
int main_x = PadState[notebookpage].axis[CTL_MAIN_X];
int main_y = PadState[notebookpage].axis[CTL_MAIN_Y];
//int sub_x = (PadState[_numPAD].axis[CTL_SUB_X];
//int sub_y = -(PadState[_numPAD].axis[CTL_SUB_Y];
@ -92,7 +90,7 @@ void ConfigBox::PadGetStatus()
int main_x_after = main_x, main_y_after = main_y;
if(PadMapping[notebookpage].bSquareToCircle)
{
std::vector<int> main_xy = InputCommon::Pad_Square_to_Circle(main_x, main_y, notebookpage, PadMapping[notebookpage]);
std::vector<int> main_xy = Pad_Square_to_Circle(main_x, main_y, notebookpage);
main_x_after = main_xy.at(0);
main_y_after = main_xy.at(1);
}
@ -140,14 +138,14 @@ void ConfigBox::PadGetStatus()
m_JoyShoulderR[notebookpage]->GetValue().ToLong(&Right);
// Get the trigger values
int TriggerLeft = PadState[notebookpage].axis[InputCommon::CTL_L_SHOULDER];
int TriggerRight = PadState[notebookpage].axis[InputCommon::CTL_R_SHOULDER];
int TriggerLeft = PadState[notebookpage].axis[CTL_L_SHOULDER];
int TriggerRight = PadState[notebookpage].axis[CTL_R_SHOULDER];
// Convert the triggers values
if (PadMapping[notebookpage].triggertype == InputCommon::CTL_TRIGGER_SDL)
if (PadMapping[notebookpage].triggertype == CTL_TRIGGER_SDL)
{
TriggerLeft = InputCommon::Pad_Convert(TriggerLeft);
TriggerRight = InputCommon::Pad_Convert(TriggerRight);
TriggerLeft = Pad_Convert(TriggerLeft);
TriggerRight = Pad_Convert(TriggerRight);
}
// If we don't have any axis selected for the shoulder buttons
@ -155,8 +153,8 @@ void ConfigBox::PadGetStatus()
if(Right < 1000) TriggerRight = 0;
// Get the digital values
if(Left < 1000 && PadState[notebookpage].buttons[InputCommon::CTL_L_SHOULDER]) TriggerLeft = TriggerValue;
if(Right < 1000 && PadState[notebookpage].buttons[InputCommon::CTL_R_SHOULDER]) TriggerRight = TriggerValue;
if(Left < 1000 && PadState[notebookpage].buttons[CTL_L_SHOULDER]) TriggerLeft = TriggerValue;
if(Right < 1000 && PadState[notebookpage].buttons[CTL_R_SHOULDER]) TriggerRight = TriggerValue;
m_TStatusTriggers[notebookpage]->SetLabel(wxString::Format(
wxT("Left:%03i Right:%03i"),
@ -194,10 +192,6 @@ std::string ShowStatus(int VirtualController)
int Hats = joyinfo[PhysicalDevice].NumHats;
int Buttons = joyinfo[PhysicalDevice].NumButtons;
// Get version
//SDL_version Version;
//SDL_GetVersion(&Version);
// Update the internal values
SDL_JoystickUpdate();
@ -219,7 +213,7 @@ std::string ShowStatus(int VirtualController)
}
return StringFromFormat(
//"Version: %i.%i.%i\n"
"PadMapping\n"
"Enabled: %i %i %i %i\n"
"ID: %i %i %i %i\n"
"Controllertype: %i %i %i %i\n"
@ -231,7 +225,6 @@ std::string ShowStatus(int VirtualController)
"Hats: %s\n"
"But: %s\n"
"Device: Ax: %i Balls:%i Hats:%i But:%i",
//Version.major, Version.minor, Version.patch,
PadMapping[0].enabled, PadMapping[1].enabled, PadMapping[2].enabled, PadMapping[3].enabled,
PadMapping[0].ID, PadMapping[1].ID, PadMapping[2].ID, PadMapping[3].ID,
PadMapping[0].controllertype, PadMapping[1].controllertype, PadMapping[2].controllertype, PadMapping[3].controllertype,
@ -240,7 +233,7 @@ std::string ShowStatus(int VirtualController)
//PadState[PadMapping[0].ID].joy, PadState[PadMapping[1].ID].joy, PadState[PadMapping[2].ID].joy, PadState[PadMapping[3].ID].joy,
#ifdef _WIN32
XInput::IsConnected(0), XInput::GetXI(0, InputCommon::XI_TRIGGER_L), XInput::GetXI(0, InputCommon::XI_TRIGGER_R),
XInput::IsConnected(0), XInput::GetXI(0, XI_TRIGGER_L), XInput::GetXI(0, XI_TRIGGER_R),
#endif
StrAxes.c_str(), StrHats.c_str(), StrBut.c_str(),
Axes, Balls, Hats, Buttons
@ -252,12 +245,10 @@ std::string ShowStatus(int VirtualController)
void ConfigBox::Update()
{
// Show the current status
/**/
#ifdef SHOW_PAD_STATUS
m_pStatusBar->SetLabel(wxString::Format(
"%s", ShowStatus(notebookpage).c_str()
));
#endif
/*
m_pStatusBar->SetLabel(wxString::Format(
"%s", ShowStatus(notebookpage).c_str()
));*/
//LogMsg("Abc%s\n", ShowStatus(notebookpage).c_str());
@ -270,10 +261,6 @@ void ConfigBox::Update()
// ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
void ConfigBox::CreateAdvancedControls(int i)
{
m_TStatusIn[i] = new wxStaticText(m_Controller[i], IDT_STATUS_IN, wxT("In"));
m_TStatusOut[i] = new wxStaticText(m_Controller[i], IDT_STATUS_OUT, wxT("Out"));
m_gStatusIn[i] = new wxStaticBoxSizer( wxHORIZONTAL, m_Controller[i], wxT("Main-stick (In) (Out)"));
m_pInStatus[i] = new wxPanel(m_Controller[i], ID_INSTATUS1 + i, wxDefaultPosition, wxDefaultSize);
m_bmpSquare[i] = new wxStaticBitmap(m_pInStatus[i], ID_STATUSBMP1 + i, CreateBitmap(),
//wxPoint(4, 15), wxSize(70,70));

View File

@ -39,7 +39,7 @@
#include "../nJoy.h"
#include "Images/controller.xpm"
extern bool g_EmulatorRunning;
extern bool emulator_running;
// D-Pad type
static const char* DPadType[] =
@ -74,7 +74,7 @@ BEGIN_EVENT_TABLE(ConfigBox,wxDialog)
// Other settings
EVT_CHECKBOX(IDC_SAVEBYID, ConfigBox::ChangeSettings)
EVT_CHECKBOX(IDC_SHOWADVANCED, ConfigBox::ChangeSettings)
EVT_CHECKBOX(IDCB_CHECKFOCUS, ConfigBox::ChangeSettings)
EVT_CHECKBOX(IDC_CHECKFOCUS, ConfigBox::ChangeSettings)
EVT_COMBOBOX(IDCB_MAINSTICK_DIAGONAL, ConfigBox::ChangeSettings)
EVT_COMBOBOX(IDC_CONTROLTYPE, ConfigBox::ChangeSettings)
EVT_COMBOBOX(IDC_TRIGGERTYPE, ConfigBox::ChangeSettings)
@ -83,7 +83,6 @@ BEGIN_EVENT_TABLE(ConfigBox,wxDialog)
// Advanced settings
EVT_COMBOBOX(IDCB_MAINSTICK_DIAGONAL, ConfigBox::ChangeSettings)
EVT_CHECKBOX(IDCB_MAINSTICK_S_TO_C, ConfigBox::ChangeSettings)
EVT_CHECKBOX(IDCB_FILTER_SETTINGS, ConfigBox::ChangeSettings)
EVT_BUTTON(IDB_SHOULDER_L, ConfigBox::GetButtons)
EVT_BUTTON(IDB_SHOULDER_R, ConfigBox::GetButtons)
@ -162,7 +161,7 @@ void ConfigBox::OnKeyDown(wxKeyEvent& event)
void ConfigBox::OnClose(wxCloseEvent& /*event*/)
{
EndModal(0);
if(!g_EmulatorRunning) Shutdown(); // Close pads, unless we are running a game
if(!emulator_running) Shutdown(); // Close pads, unless we are running a game
}
// Call about dialog
@ -292,8 +291,7 @@ void ConfigBox::OnSaveById()
// Change Joystick
// ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
/* Function: When changing the joystick we save and load the settings and update the PadMapping
and PadState array. PadState[].joy is the gamepad handle that is used to access the pad throughout
the plugin. Joyinfo[].joy is only used the first time the pads are checked. */
and PadState array */
void ConfigBox::DoChangeJoystick()
{
// Close the current pad, unless it's used by another slot
@ -427,34 +425,16 @@ void ConfigBox::ChangeSettings( wxCommandEvent& event )
}
SizeWindow();
break;
// Advanced settings
case IDCB_CHECKFOCUS:
case IDC_CHECKFOCUS:
g_Config.bCheckFocus = m_CBCheckFocus[notebookpage]->IsChecked();
for(int i = 0; i < 4; i++)
{
m_CBCheckFocus[i]->SetValue(g_Config.bCheckFocus);
}
break;
case IDCB_FILTER_SETTINGS:
g_Config.bNoTriggerFilter = m_AdvancedMapFilter[notebookpage]->IsChecked();
for(int i = 0; i < 4; i++)
{
m_AdvancedMapFilter[i]->SetValue(g_Config.bNoTriggerFilter);
}
break;
case IDC_CONTROLTYPE:
if(!g_Config.bSaveByID)
{
PadMapping[notebookpage].controllertype = m_ControlType[notebookpage]->GetSelection();
UpdateGUI(notebookpage);
}
case IDC_TRIGGERTYPE:
if(!g_Config.bSaveByID)
{
PadMapping[notebookpage].triggertype = m_TriggerType[notebookpage]->GetSelection();
UpdateGUI(notebookpage);
}
//UpdateGUI(notebookpage);
break;
case IDC_JOYNAME:
@ -492,10 +472,10 @@ void ConfigBox::UpdateGUI(int _notebookpage)
}
// Update the GUI from PadMapping[]
UpdateGUIButtonMapping(_notebookpage);
UpdateGUIKeys(_notebookpage);
// Collect status
bool Hat = (PadMapping[_notebookpage].controllertype == InputCommon::CTL_DPAD_HAT);
bool Hat = (PadMapping[_notebookpage].controllertype == CTL_DPAD_HAT);
long Left, Right;
m_JoyShoulderL[_notebookpage]->GetValue().ToLong(&Left);
m_JoyShoulderR[_notebookpage]->GetValue().ToLong(&Right);
@ -525,7 +505,6 @@ void ConfigBox::UpdateGUI(int _notebookpage)
m_CBSaveByID[_notebookpage]->SetValue(g_Config.bSaveByID);
m_CBShowAdvanced[_notebookpage]->SetValue(g_Config.bShowAdvanced);
m_CBCheckFocus[_notebookpage]->SetValue(g_Config.bCheckFocus);
m_AdvancedMapFilter[_notebookpage]->SetValue(g_Config.bNoTriggerFilter);
LogMsg("Update: %i\n", g_Config.bSaveByID);
@ -541,8 +520,7 @@ void ConfigBox::UpdateGUI(int _notebookpage)
m_Controller[_notebookpage]->FindItem(IDC_CONTROLTYPE)->Enable(Enabled);
m_Controller[_notebookpage]->FindItem(IDC_TRIGGERTYPE)->Enable(Enabled && XInput);
m_Controller[_notebookpage]->FindItem(IDCB_MAINSTICK_DIAGONAL)->Enable(Enabled);
m_Controller[_notebookpage]->FindItem(IDCB_MAINSTICK_S_TO_C)->Enable(Enabled);
m_Controller[_notebookpage]->FindItem(IDCB_FILTER_SETTINGS)->Enable(Enabled);
m_Controller[_notebookpage]->FindItem(IDCB_MAINSTICK_S_TO_C)->Enable(Enabled);
#endif
// Replace the harder to understand -1 with "" for the sake of user friendliness
@ -641,12 +619,12 @@ void ConfigBox::CreateGUIControls()
// Populate the DPad type and Trigger type list
// -----------------------------
wxArrayString wxAS_DPadType;
wxAS_DPadType.Add(wxString::FromAscii(DPadType[InputCommon::CTL_DPAD_HAT]));
wxAS_DPadType.Add(wxString::FromAscii(DPadType[InputCommon::CTL_DPAD_CUSTOM]));
wxAS_DPadType.Add(wxString::FromAscii(DPadType[CTL_DPAD_HAT]));
wxAS_DPadType.Add(wxString::FromAscii(DPadType[CTL_DPAD_CUSTOM]));
wxArrayString wxAS_TriggerType;
wxAS_TriggerType.Add(wxString::FromAscii(TriggerType[InputCommon::CTL_TRIGGER_SDL]));
wxAS_TriggerType.Add(wxString::FromAscii(TriggerType[InputCommon::CTL_TRIGGER_XINPUT]));
wxAS_TriggerType.Add(wxString::FromAscii(TriggerType[CTL_TRIGGER_SDL]));
wxAS_TriggerType.Add(wxString::FromAscii(TriggerType[CTL_TRIGGER_XINPUT]));
// --------------------------------------------------------------------
// Populate the deadzone list
@ -842,10 +820,12 @@ void ConfigBox::CreateGUIControls()
m_gGenSettingsID[i] = new wxStaticBoxSizer( wxVERTICAL, m_Controller[i], wxT("Settings") );
m_CBSaveByID[i] = new wxCheckBox(m_Controller[i], IDC_SAVEBYID, wxT("Save by ID"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator);
m_CBShowAdvanced[i] = new wxCheckBox(m_Controller[i], IDC_SHOWADVANCED, wxT("Show advanced settings"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator);
m_CBCheckFocus[i] = new wxCheckBox(m_Controller[i], IDC_CHECKFOCUS, wxT("Allow out of focus input"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator);
// Populate general settings 3
m_gGenSettingsID[i]->Add(m_CBSaveByID[i], 0, wxEXPAND | wxALL, 3);
m_gGenSettingsID[i]->Add(m_CBShowAdvanced[i], 0, wxEXPAND | wxALL, 3);
m_gGenSettingsID[i]->Add(m_CBCheckFocus[i], 0, wxEXPAND | wxALL, 3);
// Create tooltips
m_ControlType[i]->SetToolTip(wxT(
@ -860,6 +840,8 @@ void ConfigBox::CreateGUIControls()
"\nto save your settings if you have multiple controllers.")
, i+1
));
m_CBCheckFocus[i]->SetToolTip(wxT(
"Allow gamepad input even when Dolphin is not in focus. Out of focus keyboard input is never allowed."));
// Populate settings
m_sSettings[i] = new wxBoxSizer ( wxHORIZONTAL );
@ -875,13 +857,17 @@ void ConfigBox::CreateGUIControls()
// Advanced settings
// ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
// Input status controls
// Populate input status
/**/
// Input status text
CreateAdvancedControls(i);
m_TStatusIn[i] = new wxStaticText(m_Controller[i], IDT_STATUS_IN, wxT("In"));
m_TStatusOut[i] = new wxStaticText(m_Controller[i], IDT_STATUS_OUT, wxT("Out"));
// Sizers
m_gStatusIn[i] = new wxStaticBoxSizer( wxHORIZONTAL, m_Controller[i], wxT("Main-stick (In) (Out)"));
CreateAdvancedControls(i);
m_GBAdvancedMainStick[i] = new wxGridBagSizer(0, 0);
m_GBAdvancedMainStick[i]->Add(m_pInStatus[i], wxGBPosition(0, 0), wxGBSpan(1, 1), wxALL, 0);
m_GBAdvancedMainStick[i]->Add(m_pOutStatus[i], wxGBPosition(0, 1), wxGBSpan(1, 1), wxLEFT, 5);
m_GBAdvancedMainStick[i]->Add(m_TStatusIn[i], wxGBPosition(1, 0), wxGBSpan(1, 1), wxALL, 0);
@ -925,20 +911,6 @@ void ConfigBox::CreateGUIControls()
m_gStatusTriggers[i] = new wxStaticBoxSizer( wxVERTICAL, m_Controller[i], wxT("Trigger values"));
m_TStatusTriggers[i] = new wxStaticText(m_Controller[i], IDT_TRIGGERS, wxT("Left: Right:"));
m_gStatusTriggers[i]->Add(m_TStatusTriggers[i], 0, (wxALL), 4);
m_gStatusAdvancedSettings[i] = new wxStaticBoxSizer( wxVERTICAL, m_Controller[i], wxT("Advanced settings"));
m_CBCheckFocus[i] = new wxCheckBox(m_Controller[i], IDCB_CHECKFOCUS, wxT("Allow out of focus input"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator);
m_AdvancedMapFilter[i] = new wxCheckBox(m_Controller[i], IDCB_FILTER_SETTINGS , wxT("No trigger filter"));
m_gStatusAdvancedSettings[i]->Add(m_CBCheckFocus[i], 0, (wxALL), 4);
m_gStatusAdvancedSettings[i]->Add(m_AdvancedMapFilter[i], 0, (wxALL), 4);
// Tool tips
m_CBCheckFocus[i]->SetToolTip(wxT(
"Allow gamepad input even when Dolphin is not in focus. Out of focus keyboard input is never allowed."));
m_AdvancedMapFilter[i]->SetToolTip(wxT(
"This will allow you to map a digital axis to the main stick or the C-stick. If you don't have"
" any analog triggers that will be automatically set when the trigger filter is off."
));
////////////////////////// Advanced settings
@ -961,7 +933,6 @@ void ConfigBox::CreateGUIControls()
m_sMainRight[i]->Add(m_gStatusIn[i], 0, wxEXPAND | (wxLEFT), 2);
m_sMainRight[i]->Add(m_gStatusInSettings[i], 0, wxEXPAND | (wxLEFT | wxTOP), 2);
m_sMainRight[i]->Add(m_gStatusTriggers[i], 0, wxEXPAND | (wxLEFT | wxTOP), 2);
m_sMainRight[i]->Add(m_gStatusAdvancedSettings[i], 0, wxEXPAND | (wxLEFT | wxTOP), 2);
// --------------------------------------------------------------------
// Populate main sizer
@ -975,7 +946,7 @@ void ConfigBox::CreateGUIControls()
m_sMainRight[i]->Show(g_Config.bShowAdvanced);
// Don't allow these changes when running
if(g_EmulatorRunning)
if(emulator_running)
{
m_Joyname[i]->Enable(false);
m_Joyattach[i]->Enable(false);
@ -1008,9 +979,7 @@ void ConfigBox::CreateGUIControls()
// --------------------------------------------------------------------
// Debugging
// -----------------------------
#ifdef SHOW_PAD_STATUS
m_pStatusBar = new wxStaticText(this, IDT_DEBUGGING, wxT("Debugging"), wxPoint(135, 100), wxDefaultSize);
#endif
//m_pStatusBar = new wxStaticText(this, IDT_DEBUGGING, wxT("Debugging"), wxPoint(135, 100), wxDefaultSize);
//m_pStatusBar2 = new wxStaticText(this, IDT_DEBUGGING2, wxT("Debugging2"), wxPoint(125, 200), wxDefaultSize);
//m_pStatusBar->SetLabel(wxString::Format("Debugging text"));

View File

@ -48,7 +48,6 @@
#include <wx/statbmp.h>
#include <wx/gbsizer.h>
#include "../nJoy.h"
class ConfigBox : public wxDialog
{
@ -113,15 +112,14 @@ class ConfigBox : public wxDialog
wxStaticBoxSizer *m_gGenSettingsID[4];
wxGridBagSizer * m_gGBGenSettings[4];
wxCheckBox *m_CBSaveByID[4], *m_CBShowAdvanced[4];
wxCheckBox *m_CBSaveByID[4], *m_CBShowAdvanced[4], *m_CBCheckFocus[4];
wxStaticText *m_TSControltype[4], *m_TSTriggerType[4];
wxStaticBoxSizer *m_gStatusIn[4], *m_gStatusInSettings[4], *m_gStatusAdvancedSettings[4]; // Advanced settings
wxStaticBoxSizer *m_gStatusIn[4], *m_gStatusInSettings[4]; // Advanced settings
wxBoxSizer *m_gStatusInSettingsH[4];
wxGridBagSizer * m_GBAdvancedMainStick[4];
wxStaticText *m_TStatusIn[4], *m_TStatusOut[4], *m_STDiagonal[4];
wxComboBox *m_CoBDiagonal[4]; wxCheckBox *m_CBS_to_C[4];
wxCheckBox *m_CBCheckFocus[4], *m_AdvancedMapFilter[4];
wxStaticBoxSizer *m_gStatusTriggers[4]; // Triggers
wxStaticText *m_TStatusTriggers[4];
@ -212,7 +210,7 @@ class ConfigBox : public wxDialog
IDG_CONTROLLERTYPE, IDC_CONTROLTYPE, IDC_TRIGGERTYPE, // Controller type
IDC_SAVEBYID, IDC_SHOWADVANCED, // Settings
IDC_SAVEBYID, IDC_SHOWADVANCED, IDC_CHECKFOCUS, // Settings
ID_INSTATUS1, ID_INSTATUS2, ID_INSTATUS3, ID_INSTATUS4, // Advanced status
ID_STATUSBMP1, ID_STATUSBMP2, ID_STATUSBMP3, ID_STATUSBMP4,
@ -220,7 +218,7 @@ class ConfigBox : public wxDialog
IDT_STATUS_IN, IDT_STATUS_OUT,
// Advaced settings
IDCB_MAINSTICK_DIAGONAL, IDCB_MAINSTICK_S_TO_C, IDT_MAINSTICK_DIAGONAL, IDT_TRIGGERS, IDCB_CHECKFOCUS, IDCB_FILTER_SETTINGS,
IDCB_MAINSTICK_DIAGONAL, IDCB_MAINSTICK_S_TO_C, IDT_MAINSTICK_DIAGONAL, IDT_TRIGGERS,
// Timers
IDTM_CONSTANT, IDTM_BUTTON,
@ -319,7 +317,7 @@ class ConfigBox : public wxDialog
wxBitmap CreateBitmap(); wxBitmap CreateBitmapDot();
void PadGetStatus(); void Update();
void UpdateGUIButtonMapping(int controller);
void UpdateGUIKeys(int controller);
void SaveButtonMapping(int controller, bool DontChangeId = false, int FromSlot = -1);
void SaveButtonMappingAll(int Slot);
void UpdateGUIAll(int Slot);

View File

@ -39,13 +39,13 @@
#include "../nJoy.h"
#include "Images/controller.xpm"
extern bool g_EmulatorRunning;
extern bool emulator_running;
////////////////////////
// Set dialog items from saved values
// ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
void ConfigBox::UpdateGUIButtonMapping(int controller)
void ConfigBox::UpdateGUIKeys(int controller)
{
// http://wiki.wxwidgets.org/Converting_everything_to_and_from_wxString
wxString tmp;
@ -56,22 +56,22 @@ void ConfigBox::UpdateGUIButtonMapping(int controller)
// Update the enabled checkbox
m_Joyattach[controller]->SetValue(PadMapping[controller].enabled == 1 ? true : false);
tmp << PadMapping[controller].buttons[InputCommon::CTL_L_SHOULDER]; m_JoyShoulderL[controller]->SetValue(tmp); tmp.clear();
tmp << PadMapping[controller].buttons[InputCommon::CTL_R_SHOULDER]; m_JoyShoulderR[controller]->SetValue(tmp); tmp.clear();
tmp << PadMapping[controller].buttons[CTL_L_SHOULDER]; m_JoyShoulderL[controller]->SetValue(tmp); tmp.clear();
tmp << PadMapping[controller].buttons[CTL_R_SHOULDER]; m_JoyShoulderR[controller]->SetValue(tmp); tmp.clear();
tmp << PadMapping[controller].buttons[InputCommon::CTL_A_BUTTON]; m_JoyButtonA[controller]->SetValue(tmp); tmp.clear();
tmp << PadMapping[controller].buttons[InputCommon::CTL_B_BUTTON]; m_JoyButtonB[controller]->SetValue(tmp); tmp.clear();
tmp << PadMapping[controller].buttons[InputCommon::CTL_X_BUTTON]; m_JoyButtonX[controller]->SetValue(tmp); tmp.clear();
tmp << PadMapping[controller].buttons[InputCommon::CTL_Y_BUTTON]; m_JoyButtonY[controller]->SetValue(tmp); tmp.clear();
tmp << PadMapping[controller].buttons[InputCommon::CTL_Z_TRIGGER]; m_JoyButtonZ[controller]->SetValue(tmp); tmp.clear();
tmp << PadMapping[controller].buttons[CTL_A_BUTTON]; m_JoyButtonA[controller]->SetValue(tmp); tmp.clear();
tmp << PadMapping[controller].buttons[CTL_B_BUTTON]; m_JoyButtonB[controller]->SetValue(tmp); tmp.clear();
tmp << PadMapping[controller].buttons[CTL_X_BUTTON]; m_JoyButtonX[controller]->SetValue(tmp); tmp.clear();
tmp << PadMapping[controller].buttons[CTL_Y_BUTTON]; m_JoyButtonY[controller]->SetValue(tmp); tmp.clear();
tmp << PadMapping[controller].buttons[CTL_Z_TRIGGER]; m_JoyButtonZ[controller]->SetValue(tmp); tmp.clear();
tmp << PadMapping[controller].buttons[InputCommon::CTL_START]; m_JoyButtonStart[controller]->SetValue(tmp); tmp.clear();
tmp << PadMapping[controller].buttons[CTL_START]; m_JoyButtonStart[controller]->SetValue(tmp); tmp.clear();
tmp << PadMapping[controller].halfpress; m_JoyButtonHalfpress[controller]->SetValue(tmp); tmp.clear();
tmp << PadMapping[controller].axis[InputCommon::CTL_MAIN_X]; m_JoyAnalogMainX[controller]->SetValue(tmp); tmp.clear();
tmp << PadMapping[controller].axis[InputCommon::CTL_MAIN_Y]; m_JoyAnalogMainY[controller]->SetValue(tmp); tmp.clear();
tmp << PadMapping[controller].axis[InputCommon::CTL_SUB_X]; m_JoyAnalogSubX[controller]->SetValue(tmp); tmp.clear();
tmp << PadMapping[controller].axis[InputCommon::CTL_SUB_Y]; m_JoyAnalogSubY[controller]->SetValue(tmp); tmp.clear();
tmp << PadMapping[controller].axis[CTL_MAIN_X]; m_JoyAnalogMainX[controller]->SetValue(tmp); tmp.clear();
tmp << PadMapping[controller].axis[CTL_MAIN_Y]; m_JoyAnalogMainY[controller]->SetValue(tmp); tmp.clear();
tmp << PadMapping[controller].axis[CTL_SUB_X]; m_JoyAnalogSubX[controller]->SetValue(tmp); tmp.clear();
tmp << PadMapping[controller].axis[CTL_SUB_Y]; m_JoyAnalogSubY[controller]->SetValue(tmp); tmp.clear();
// Update the deadzone and controller type controls
m_ControlType[controller]->SetSelection(PadMapping[controller].controllertype);
@ -79,21 +79,20 @@ void ConfigBox::UpdateGUIButtonMapping(int controller)
m_Deadzone[controller]->SetSelection(PadMapping[controller].deadzone);
m_CoBDiagonal[controller]->SetValue(wxString::FromAscii(PadMapping[controller].SDiagonal.c_str()));
m_CBS_to_C[controller]->SetValue(PadMapping[controller].bSquareToCircle);
m_AdvancedMapFilter[controller]->SetValue(g_Config.bNoTriggerFilter);
//LogMsg("m_TriggerType[%i] = %i\n", controller, PadMapping[controller].triggertype);
// Update D-Pad
if(PadMapping[controller].controllertype == InputCommon::CTL_DPAD_HAT)
if(PadMapping[controller].controllertype == CTL_DPAD_HAT)
{
tmp << PadMapping[controller].dpad; m_JoyDpadDown[controller]->SetValue(tmp); tmp.clear();
tmp << PadMapping[controller].dpad; m_JoyDpadUp[controller]->SetValue(tmp); tmp.clear();
}
else
{
tmp << PadMapping[controller].dpad2[InputCommon::CTL_D_PAD_UP]; m_JoyDpadUp[controller]->SetValue(tmp); tmp.clear();
tmp << PadMapping[controller].dpad2[InputCommon::CTL_D_PAD_DOWN]; m_JoyDpadDown[controller]->SetValue(tmp); tmp.clear();
tmp << PadMapping[controller].dpad2[InputCommon::CTL_D_PAD_LEFT]; m_JoyDpadLeft[controller]->SetValue(tmp); tmp.clear();
tmp << PadMapping[controller].dpad2[InputCommon::CTL_D_PAD_RIGHT]; m_JoyDpadRight[controller]->SetValue(tmp); tmp.clear();
tmp << PadMapping[controller].dpad2[CTL_D_PAD_UP]; m_JoyDpadUp[controller]->SetValue(tmp); tmp.clear();
tmp << PadMapping[controller].dpad2[CTL_D_PAD_DOWN]; m_JoyDpadDown[controller]->SetValue(tmp); tmp.clear();
tmp << PadMapping[controller].dpad2[CTL_D_PAD_LEFT]; m_JoyDpadLeft[controller]->SetValue(tmp); tmp.clear();
tmp << PadMapping[controller].dpad2[CTL_D_PAD_RIGHT]; m_JoyDpadRight[controller]->SetValue(tmp); tmp.clear();
}
// Replace "-1" with "" in the GUI controls
@ -122,25 +121,25 @@ void ConfigBox::SaveButtonMapping(int controller, bool DontChangeId, int FromSlo
PadMapping[controller].triggertype = m_TriggerType[FromSlot]->GetSelection();
PadMapping[controller].deadzone = m_Deadzone[FromSlot]->GetSelection();
PadMapping[controller].SDiagonal = m_CoBDiagonal[FromSlot]->GetLabel().mb_str();
PadMapping[controller].bSquareToCircle = m_CBS_to_C[FromSlot]->IsChecked();
PadMapping[controller].bSquareToCircle = m_CBS_to_C[FromSlot]->IsChecked();
// The analog buttons
m_JoyAnalogMainX[FromSlot]->GetValue().ToLong(&value); PadMapping[controller].axis[InputCommon::CTL_MAIN_X] = value; tmp.clear();
m_JoyAnalogMainY[FromSlot]->GetValue().ToLong(&value); PadMapping[controller].axis[InputCommon::CTL_MAIN_Y] = value; tmp.clear();
m_JoyAnalogSubX[FromSlot]->GetValue().ToLong(&value); PadMapping[controller].axis[InputCommon::CTL_SUB_X] = value; tmp.clear();
m_JoyAnalogSubY[FromSlot]->GetValue().ToLong(&value); PadMapping[controller].axis[InputCommon::CTL_SUB_Y] = value; tmp.clear();
m_JoyAnalogMainX[FromSlot]->GetValue().ToLong(&value); PadMapping[controller].axis[CTL_MAIN_X] = value; tmp.clear();
m_JoyAnalogMainY[FromSlot]->GetValue().ToLong(&value); PadMapping[controller].axis[CTL_MAIN_Y] = value; tmp.clear();
m_JoyAnalogSubX[FromSlot]->GetValue().ToLong(&value); PadMapping[controller].axis[CTL_SUB_X] = value; tmp.clear();
m_JoyAnalogSubY[FromSlot]->GetValue().ToLong(&value); PadMapping[controller].axis[CTL_SUB_Y] = value; tmp.clear();
// The shoulder buttons
m_JoyShoulderL[FromSlot]->GetValue().ToLong(&value); PadMapping[controller].buttons[InputCommon::CTL_L_SHOULDER] = value;
m_JoyShoulderR[FromSlot]->GetValue().ToLong(&value); PadMapping[controller].buttons[InputCommon::CTL_R_SHOULDER] = value;
m_JoyShoulderL[FromSlot]->GetValue().ToLong(&value); PadMapping[controller].buttons[CTL_L_SHOULDER] = value;
m_JoyShoulderR[FromSlot]->GetValue().ToLong(&value); PadMapping[controller].buttons[CTL_R_SHOULDER] = value;
// The digital buttons
m_JoyButtonA[FromSlot]->GetValue().ToLong(&value); PadMapping[controller].buttons[InputCommon::CTL_A_BUTTON] = value; tmp.clear();
m_JoyButtonB[FromSlot]->GetValue().ToLong(&value); PadMapping[controller].buttons[InputCommon::CTL_B_BUTTON] = value; tmp.clear();
m_JoyButtonX[FromSlot]->GetValue().ToLong(&value); PadMapping[controller].buttons[InputCommon::CTL_X_BUTTON] = value; tmp.clear();
m_JoyButtonY[FromSlot]->GetValue().ToLong(&value); PadMapping[controller].buttons[InputCommon::CTL_Y_BUTTON] = value; tmp.clear();
m_JoyButtonZ[FromSlot]->GetValue().ToLong(&value); PadMapping[controller].buttons[InputCommon::CTL_Z_TRIGGER] = value; tmp.clear();
m_JoyButtonStart[FromSlot]->GetValue().ToLong(&value); PadMapping[controller].buttons[InputCommon::CTL_START] = value; tmp.clear();
m_JoyButtonA[FromSlot]->GetValue().ToLong(&value); PadMapping[controller].buttons[CTL_A_BUTTON] = value; tmp.clear();
m_JoyButtonB[FromSlot]->GetValue().ToLong(&value); PadMapping[controller].buttons[CTL_B_BUTTON] = value; tmp.clear();
m_JoyButtonX[FromSlot]->GetValue().ToLong(&value); PadMapping[controller].buttons[CTL_X_BUTTON] = value; tmp.clear();
m_JoyButtonY[FromSlot]->GetValue().ToLong(&value); PadMapping[controller].buttons[CTL_Y_BUTTON] = value; tmp.clear();
m_JoyButtonZ[FromSlot]->GetValue().ToLong(&value); PadMapping[controller].buttons[CTL_Z_TRIGGER] = value; tmp.clear();
m_JoyButtonStart[FromSlot]->GetValue().ToLong(&value); PadMapping[controller].buttons[CTL_START] = value; tmp.clear();
//LogMsg("PadMapping[%i].triggertype = %i, m_TriggerType[%i]->GetSelection() = %i\n",
// controller, PadMapping[controller].triggertype, FromSlot, m_TriggerType[FromSlot]->GetSelection());
@ -149,16 +148,16 @@ void ConfigBox::SaveButtonMapping(int controller, bool DontChangeId, int FromSlo
m_JoyButtonHalfpress[FromSlot]->GetValue().ToLong(&value); PadMapping[controller].halfpress = value; tmp.clear();
// The digital pad
if(PadMapping[controller].controllertype == InputCommon::CTL_DPAD_HAT)
if(PadMapping[controller].controllertype == CTL_DPAD_HAT)
{
m_JoyDpadDown[FromSlot]->GetValue().ToLong(&value); PadMapping[controller].dpad = value; tmp.clear();
m_JoyDpadUp[FromSlot]->GetValue().ToLong(&value); PadMapping[controller].dpad = value; tmp.clear();
}
else
{
m_JoyDpadUp[FromSlot]->GetValue().ToLong(&value); PadMapping[controller].dpad2[InputCommon::CTL_D_PAD_UP] = value; tmp.clear();
m_JoyDpadDown[FromSlot]->GetValue().ToLong(&value); PadMapping[controller].dpad2[InputCommon::CTL_D_PAD_DOWN] = value; tmp.clear();
m_JoyDpadLeft[FromSlot]->GetValue().ToLong(&value); PadMapping[controller].dpad2[InputCommon::CTL_D_PAD_LEFT] = value; tmp.clear();
m_JoyDpadRight[FromSlot]->GetValue().ToLong(&value); PadMapping[controller].dpad2[InputCommon::CTL_D_PAD_RIGHT] = value; tmp.clear();
m_JoyDpadUp[FromSlot]->GetValue().ToLong(&value); PadMapping[controller].dpad2[CTL_D_PAD_UP] = value; tmp.clear();
m_JoyDpadDown[FromSlot]->GetValue().ToLong(&value); PadMapping[controller].dpad2[CTL_D_PAD_DOWN] = value; tmp.clear();
m_JoyDpadLeft[FromSlot]->GetValue().ToLong(&value); PadMapping[controller].dpad2[CTL_D_PAD_LEFT] = value; tmp.clear();
m_JoyDpadRight[FromSlot]->GetValue().ToLong(&value); PadMapping[controller].dpad2[CTL_D_PAD_RIGHT] = value; tmp.clear();
}
// Replace "-1" with ""
@ -245,6 +244,21 @@ wxString ConfigBox::GetButtonText(int id, int Page)
// ¯¯¯¯¯¯¯¯¯¯
// Avoid extreme axis values
// ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
/* Function: We have to avoid very big values to becuse some triggers are -0x8000 in the
unpressed state (and then go from -0x8000 to 0x8000 as they are fully pressed) */
bool AvoidValues(int value)
{
// Avoid detecting very small or very big (for triggers) values
if( (value > -0x2000 && value < 0x2000) // Small values
|| (value < -0x6000 || value > 0x6000)) // Big values
return true; // Avoid
else
return false; // Keep
}
// Wait for button press
// ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
/* Loop or timer: There are basically two ways to do this. With a while() or for() loop, or with a
@ -257,7 +271,6 @@ void ConfigBox::GetButtons(wxCommandEvent& event)
{
DoGetButtons(event.GetId());
}
void ConfigBox::DoGetButtons(int GetId)
{
// =============================================
@ -266,17 +279,6 @@ void ConfigBox::DoGetButtons(int GetId)
// Get the current controller
int Controller = notebookpage;
int PadID = PadMapping[Controller].ID;
// Create a shortcut for the pad handle
SDL_Joystick *joy = PadState[Controller].joy;
// Get the number of axes, hats and buttons
int Buttons = SDL_JoystickNumButtons(joy);
int Axes = SDL_JoystickNumAxes(joy);
int Hats = SDL_JoystickNumHats(joy);
Console::Print("PadID: %i Axes: %i\n", PadID, joyinfo[PadID].NumAxes, joyinfo[PadID].joy);
// Get the controller and trigger type
int ControllerType = PadMapping[Controller].controllertype;
@ -286,30 +288,35 @@ void ConfigBox::DoGetButtons(int GetId)
bool LeftRight = (GetId == IDB_SHOULDER_L || GetId == IDB_SHOULDER_R);
bool Axis = (GetId >= IDB_ANALOG_MAIN_X && GetId <= IDB_SHOULDER_R)
&& !(TriggerType == InputCommon::CTL_TRIGGER_XINPUT && (GetId == IDB_SHOULDER_L || GetId == IDB_SHOULDER_R) ); // Don't allow SDL here
&& !(TriggerType == CTL_TRIGGER_XINPUT && (GetId == IDB_SHOULDER_L || GetId == IDB_SHOULDER_R) ); // Don't allow SDL here
bool XInput = (TriggerType == InputCommon::CTL_TRIGGER_XINPUT);
bool XInput = (TriggerType == CTL_TRIGGER_XINPUT);
bool Button = (GetId >= IDB_BUTTON_A && GetId <= IDB_BUTTONHALFPRESS) // All digital buttons
|| (GetId == IDB_SHOULDER_L || GetId == IDB_SHOULDER_R) // both shoulder buttons
|| (GetId >= IDB_DPAD_UP && GetId <= IDB_DPAD_RIGHT && ControllerType == InputCommon::CTL_DPAD_CUSTOM); // Or the custom hat mode
|| (GetId >= IDB_DPAD_UP && GetId <= IDB_DPAD_RIGHT && ControllerType == CTL_DPAD_CUSTOM); // Or the custom hat mode
bool Hat = (GetId >= IDB_DPAD_UP && GetId <= IDB_DPAD_RIGHT) // All DPads
&& (PadMapping[Controller].controllertype == InputCommon::CTL_DPAD_HAT); // Not with the hat option defined
&& (PadMapping[Controller].controllertype == CTL_DPAD_HAT); // Not with the hat option defined
bool NoTriggerFilter = g_Config.bNoTriggerFilter;
/* Open a new joystick. Joysticks[controller].GetId is the system GetId of the physical joystick
that is mapped to controller, for example 0, 1, 2, 3 for the first four PadMapping */
SDL_Joystick *joy = SDL_JoystickOpen(PadMapping[Controller].ID);
// Values used in this function
// Get the number of axes, hats and buttons
int buttons = SDL_JoystickNumButtons(joy);
int axes = SDL_JoystickNumAxes(joy);
int hats = SDL_JoystickNumHats(joy);
// Declare values
char format[128];
int Seconds = 4; // Seconds to wait for
int TimesPerSecond = 40; // How often to run the check
// Values returned from InputCommon::GetButton()
int value; // Axis value
int type; // Button type
int pressed = 0;
bool Succeed = false;
bool Stop = false; // Stop the timer
int pressed = 0;
int Seconds = 4; // Seconds to wait for
int TimesPerSecond = 40; // How often to run the check
// =======================
//Console::Print("Before (%i) Id:%i %i IsRunning:%i\n",
@ -350,10 +357,90 @@ void ConfigBox::DoGetButtons(int GetId)
// If there is a timer but we should not create a new one
else
{
InputCommon::GetButton(
joy, PadID, Buttons, Axes, Hats,
g_Pressed, value, type, pressed, Succeed, Stop,
LeftRight, Axis, XInput, Button, Hat, NoTriggerFilter);
// Update the internal status
SDL_JoystickUpdate();
// For the triggers we accept both a digital or an analog button
if(Axis)
{
for(int i = 0; i < axes; i++)
{
value = SDL_JoystickGetAxis(joy, i);
if(AvoidValues(value)) continue; // Avoid values
pressed = i + (LeftRight ? 1000 : 0); // Identify the analog triggers
type = CTL_AXIS;
Succeed = true;
}
}
// Check for a hat
if(Hat)
{
for(int i = 0; i < hats; i++)
{
if(SDL_JoystickGetHat(joy, i))
{
pressed = i;
type = CTL_HAT;
Succeed = true;
}
}
}
// Check for a button
if(Button)
{
for(int i = 0; i < buttons; i++)
{
// Some kind of bug in SDL 1.3 would give button 9 and 10 (nonexistent) the value 48 on the 360 pad
if (SDL_JoystickGetButton(joy, i) > 1) continue;
if(SDL_JoystickGetButton(joy, i))
{
pressed = i;
type = CTL_BUTTON;
Succeed = true;
}
}
}
// Check for a XInput trigger
#ifdef _WIN32
if(XInput)
{
for(int i = 0; i <= XI_TRIGGER_R; i++)
{
if(XInput::GetXI(0, i))
{
pressed = i + 1000;
type = CTL_AXIS;
Succeed = true;
}
}
}
#endif
// Check for keyboard action
if (g_Pressed && Button)
{
// Todo: Add a separate keyboard vector to remove this restriction
if(g_Pressed >= buttons)
{
pressed = g_Pressed;
type = CTL_BUTTON;
Succeed = true;
g_Pressed = 0;
if(pressed == WXK_ESCAPE) pressed = -1; // Check for the exape key
}
else
{
pressed = g_Pressed;
g_Pressed = -1;
Stop = true;
}
}
}
// ========================= Check for keys
@ -420,6 +507,9 @@ void ConfigBox::DoGetButtons(int GetId)
}
// ======================== Process results
// We don't need this gamepad handle any more
if(SDL_JoystickOpened(PadMapping[Controller].ID)) SDL_JoystickClose(joy);
// Debugging
/*
Console::Print("Change: %i %i %i %i '%s' '%s' '%s' '%s'\n",
@ -427,4 +517,5 @@ void ConfigBox::DoGetButtons(int GetId)
m_JoyButtonHalfpress[0]->GetValue().c_str(), m_JoyButtonHalfpress[1]->GetValue().c_str(), m_JoyButtonHalfpress[2]->GetValue().c_str(), m_JoyButtonHalfpress[3]->GetValue().c_str()
);*/
}
/////////////////////////////////////////////////////////// Configure button mapping

View File

@ -25,7 +25,7 @@ if padenv['HAVE_WX']:
padenv.Append(
CXXFLAGS = [ '-fPIC' ],
LIBS = [ 'common', 'inputcommon' ],
LIBS = [ 'common' ],
)
padenv.SharedLibrary(env['plugin_dir']+name, files)

View File

@ -81,13 +81,13 @@
// ¯¯¯¯¯¯¯¯¯
// Rumble in windows
#define _EXCLUDE_MAIN_ // Avoid certain declarations in nJoy.h
#define _CONTROLLER_STATE_H // Avoid certain declarations in nJoy.h
FILE *pFile;
HINSTANCE nJoy_hInst = NULL;
std::vector<InputCommon::CONTROLLER_INFO> joyinfo;
InputCommon::CONTROLLER_STATE PadState[4];
InputCommon::CONTROLLER_MAPPING PadMapping[4];
bool g_EmulatorRunning = false;
std::vector<CONTROLLER_INFO> joyinfo;
CONTROLLER_STATE PadState[4];
CONTROLLER_MAPPING PadMapping[4];
bool emulator_running = false;
int NumPads = 0, NumGoodPads = 0;
HWND m_hWnd; // Handle to window
SPADInitialize *g_PADInitialize = NULL;
@ -191,9 +191,9 @@ void DllConfig(HWND _hParent)
#ifdef _WIN32
// Start the pads so we can use them in the configuration and advanced controls
if(!g_EmulatorRunning)
if(!emulator_running)
{
Search_Devices(joyinfo, NumPads, NumGoodPads); // Populate joyinfo for all attached devices
NumPads = Search_Devices(); // Populate joyinfo for all attached devices
}
m_frame = new ConfigBox(NULL);
@ -232,7 +232,7 @@ void DllDebugger(HWND _hParent, bool Show) {}
// ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
/* Information: This function can not be run twice without a Shutdown in between. If
it's run twice the SDL_Init() will cause a crash. One solution to this is to keep a
global function that remembers the SDL_Init() and SDL_Quit() (g_EmulatorRunning does
global function that remembers the SDL_Init() and SDL_Quit() (emulator_running does
not do that since we can open and close this without any game running). But I would
suggest that avoiding to run this twice from the Core is better. */
void Initialize(void *init)
@ -241,7 +241,7 @@ void Initialize(void *init)
//Console::Open();
Console::Print("Initialize: %i\n", SDL_WasInit(0));
g_PADInitialize = (SPADInitialize*)init;
g_EmulatorRunning = true;
emulator_running = true;
#ifdef _DEBUG
DEBUG_INIT();
@ -251,7 +251,7 @@ void Initialize(void *init)
m_hWnd = (HWND)g_PADInitialize->hWnd;
#endif
Search_Devices(joyinfo, NumPads, NumGoodPads); // Populate joyinfo for all attached devices
NumPads = Search_Devices(); // Populate joyinfo for all attached devices
/* Check if any of the pads failed to open. In Windows there is a strange "IDirectInputDevice2::
SetDataFormat() DirectX error -2147024809" after a few Open and Close */
@ -265,15 +265,79 @@ void Initialize(void *init)
}
}
bool Search_Devices(std::vector<InputCommon::CONTROLLER_INFO> &_joyinfo, int &_NumPads, int &_NumGoodPads)
// Search attached devices. Populate joyinfo for all attached physical devices.
// ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
int Search_Devices()
{
bool Success = InputCommon::SearchDevices(_joyinfo, _NumPads, _NumGoodPads);
// Load config
#ifdef _DEBUG
DEBUG_INIT();
#endif
/* SDL 1.3 use DirectInput instead of the old Microsoft Multimeda API, and with this we need
the SDL_INIT_VIDEO flag to */
if (!SDL_WasInit(0))
if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_JOYSTICK) < 0)
{
PanicAlert("Could not initialize SDL: %s", SDL_GetError());
return 0;
}
#ifdef _DEBUG
fprintf(pFile, "Scanning for devices\n");
fprintf(pFile, "¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯\n");
#endif
// Get device status
int numjoy = SDL_NumJoysticks();
for (int i = 0; i < numjoy; i++ )
{
CONTROLLER_INFO Tmp;
Tmp.joy = SDL_JoystickOpen(i);
Tmp.ID = i;
Tmp.NumAxes = SDL_JoystickNumAxes(Tmp.joy);
Tmp.NumButtons = SDL_JoystickNumButtons(Tmp.joy);
Tmp.NumBalls = SDL_JoystickNumBalls(Tmp.joy);
Tmp.NumHats = SDL_JoystickNumHats(Tmp.joy);
Tmp.Name = SDL_JoystickName(i);
// Check if the device is okay
if ( Tmp.NumAxes == 0
&& Tmp.NumBalls == 0
&& Tmp.NumButtons == 0
&& Tmp.NumHats == 0
)
{
Tmp.Good = false;
}
else
{
NumGoodPads++;
Tmp.Good = true;
}
joyinfo.push_back(Tmp);
#ifdef _DEBUG
fprintf(pFile, "ID: %d\n", i);
fprintf(pFile, "Name: %s\n", joyinfo[i].Name);
fprintf(pFile, "Buttons: %d\n", joyinfo[i].NumButtons);
fprintf(pFile, "Axes: %d\n", joyinfo[i].NumAxes);
fprintf(pFile, "Hats: %d\n", joyinfo[i].NumHats);
fprintf(pFile, "Balls: %d\n\n", joyinfo[i].NumBalls);
#endif
// We have now read the values we need so we close the device
if (SDL_JoystickOpened(i)) SDL_JoystickClose(joyinfo[i].joy);
}
// Warn the user if no gamepads are detected
if (_NumGoodPads == 0 && g_EmulatorRunning)
if (NumGoodPads == 0 && emulator_running)
{
PanicAlert("nJoy: No Gamepad Detected");
return false;
return joyinfo.size();
}
// Load PadMapping[] etc
@ -287,7 +351,7 @@ bool Search_Devices(std::vector<InputCommon::CONTROLLER_INFO> &_joyinfo, int &_N
PadState[i].joy = SDL_JoystickOpen(PadMapping[i].ID);
}
return Success;
return joyinfo.size();
}
// Shutdown PAD (stop emulation)
@ -308,17 +372,18 @@ void Shutdown()
if(SDL_JoystickOpened(PadMapping[i].ID)) SDL_JoystickClose(PadState[i].joy);
}
// Clear the physical device info
joyinfo.clear();
// Finally close SDL
if (SDL_WasInit(0)) SDL_Quit();
SDL_Quit();
#ifdef _DEBUG
DEBUG_QUIT();
#endif
g_EmulatorRunning = false;
// Clear the physical device info
//delete [] joyinfo;
//joyinfo = NULL;
joyinfo.clear();
emulator_running = false;
#ifdef _WIN32
#ifdef USE_RUMBLE_DINPUT_HACK
@ -340,13 +405,13 @@ void PAD_Input(u16 _Key, u8 _UpDown)
// Check if the keys are interesting, and then update it
for(int i = 0; i < 4; i++)
{
for(int j = InputCommon::CTL_L_SHOULDER; j <= InputCommon::CTL_START; j++)
for(int j = CTL_L_SHOULDER; j <= CTL_START; j++)
{
if (PadMapping[i].buttons[j] == _Key)
{ PadState[i].buttons[j] = _UpDown; break; }
}
for(int j = InputCommon::CTL_D_PAD_UP; j <= InputCommon::CTL_D_PAD_RIGHT; j++)
for(int j = CTL_D_PAD_UP; j <= CTL_D_PAD_RIGHT; j++)
{
if (PadMapping[i].dpad2[j] == _Key)
{ PadState[i].dpad2[j] = _UpDown; break; }
@ -396,9 +461,8 @@ void PAD_GetStatus(u8 _numPAD, SPADStatus* _pPADStatus)
// Clear pad status
memset(_pPADStatus, 0, sizeof(SPADStatus));
// Check that Dolphin is in focus, otherwise don't update the pad status
if (!g_Config.bCheckFocus && IsFocus())
GetJoyState(PadState[_numPAD], PadMapping[_numPAD], _numPAD, joyinfo[PadMapping[_numPAD].ID].NumButtons);
// Update the pad status
GetJoyState(_numPAD);
// Get type
int TriggerType = PadMapping[_numPAD].triggertype;
@ -408,32 +472,32 @@ void PAD_GetStatus(u8 _numPAD, SPADStatus* _pPADStatus)
// -----------
// Read axis values
int i_main_stick_x = PadState[_numPAD].axis[InputCommon::CTL_MAIN_X];
int i_main_stick_y = -PadState[_numPAD].axis[InputCommon::CTL_MAIN_Y];
int i_sub_stick_x = PadState[_numPAD].axis[InputCommon::CTL_SUB_X];
int i_sub_stick_y = -PadState[_numPAD].axis[InputCommon::CTL_SUB_Y];
int TriggerLeft = PadState[_numPAD].axis[InputCommon::CTL_L_SHOULDER];
int TriggerRight = PadState[_numPAD].axis[InputCommon::CTL_R_SHOULDER];
int i_main_stick_x = PadState[_numPAD].axis[CTL_MAIN_X];
int i_main_stick_y = -PadState[_numPAD].axis[CTL_MAIN_Y];
int i_sub_stick_x = PadState[_numPAD].axis[CTL_SUB_X];
int i_sub_stick_y = -PadState[_numPAD].axis[CTL_SUB_Y];
int TriggerLeft = PadState[_numPAD].axis[CTL_L_SHOULDER];
int TriggerRight = PadState[_numPAD].axis[CTL_R_SHOULDER];
// Check if we should make adjustments
if(PadMapping[_numPAD].bSquareToCircle)
{
std::vector<int> main_xy = InputCommon::Pad_Square_to_Circle(i_main_stick_x, i_main_stick_y, _numPAD, PadMapping[_numPAD]);
std::vector<int> main_xy = Pad_Square_to_Circle(i_main_stick_x, i_main_stick_y, _numPAD);
i_main_stick_x = main_xy.at(0);
i_main_stick_y = main_xy.at(1);
}
// Convert axis values
u8 main_stick_x = InputCommon::Pad_Convert(i_main_stick_x);
u8 main_stick_y = InputCommon::Pad_Convert(i_main_stick_y);
u8 sub_stick_x = InputCommon::Pad_Convert(i_sub_stick_x);
u8 sub_stick_y = InputCommon::Pad_Convert(i_sub_stick_y);
u8 main_stick_x = Pad_Convert(i_main_stick_x);
u8 main_stick_y = Pad_Convert(i_main_stick_y);
u8 sub_stick_x = Pad_Convert(i_sub_stick_x);
u8 sub_stick_y = Pad_Convert(i_sub_stick_y);
// Convert the triggers values, if we are using analog triggers at all
if(PadMapping[_numPAD].triggertype == InputCommon::CTL_TRIGGER_SDL)
if(PadMapping[_numPAD].triggertype == CTL_TRIGGER_SDL)
{
if(PadMapping[_numPAD].buttons[InputCommon::CTL_L_SHOULDER] >= 1000) TriggerLeft = InputCommon::Pad_Convert(TriggerLeft);
if(PadMapping[_numPAD].buttons[InputCommon::CTL_R_SHOULDER] >= 1000) TriggerRight = InputCommon::Pad_Convert(TriggerRight);
if(PadMapping[_numPAD].buttons[CTL_L_SHOULDER] >= 1000) TriggerLeft = Pad_Convert(TriggerLeft);
if(PadMapping[_numPAD].buttons[CTL_R_SHOULDER] >= 1000) TriggerRight = Pad_Convert(TriggerRight);
}
// Set Deadzones (perhaps out of function?)
@ -456,7 +520,7 @@ void PAD_GetStatus(u8 _numPAD, SPADStatus* _pPADStatus)
_pPADStatus->button |= PAD_USE_ORIGIN; // Neutral value, no button pressed
// Check if the digital L button is pressed
if (PadState[_numPAD].buttons[InputCommon::CTL_L_SHOULDER])
if (PadState[_numPAD].buttons[CTL_L_SHOULDER])
{
_pPADStatus->button |= PAD_TRIGGER_L;
_pPADStatus->triggerLeft = TriggerValue;
@ -465,7 +529,7 @@ void PAD_GetStatus(u8 _numPAD, SPADStatus* _pPADStatus)
_pPADStatus->triggerLeft = TriggerLeft;
// Check if the digital R button is pressed
if (PadState[_numPAD].buttons[InputCommon::CTL_R_SHOULDER])
if (PadState[_numPAD].buttons[CTL_R_SHOULDER])
{
_pPADStatus->button |= PAD_TRIGGER_R;
_pPADStatus->triggerRight = TriggerValue;
@ -481,26 +545,26 @@ void PAD_GetStatus(u8 _numPAD, SPADStatus* _pPADStatus)
///////////////////////////////////////////////////
// The digital buttons
// -----------
if (PadState[_numPAD].buttons[InputCommon::CTL_A_BUTTON])
if (PadState[_numPAD].buttons[CTL_A_BUTTON])
{
_pPADStatus->button |= PAD_BUTTON_A;
_pPADStatus->analogA = 255; // Perhaps support pressure?
}
if (PadState[_numPAD].buttons[InputCommon::CTL_B_BUTTON])
if (PadState[_numPAD].buttons[CTL_B_BUTTON])
{
_pPADStatus->button |= PAD_BUTTON_B;
_pPADStatus->analogB = 255; // Perhaps support pressure?
}
if (PadState[_numPAD].buttons[InputCommon::CTL_X_BUTTON]) _pPADStatus->button|=PAD_BUTTON_X;
if (PadState[_numPAD].buttons[InputCommon::CTL_Y_BUTTON]) _pPADStatus->button|=PAD_BUTTON_Y;
if (PadState[_numPAD].buttons[InputCommon::CTL_Z_TRIGGER]) _pPADStatus->button|=PAD_TRIGGER_Z;
if (PadState[_numPAD].buttons[InputCommon::CTL_START]) _pPADStatus->button|=PAD_BUTTON_START;
if (PadState[_numPAD].buttons[CTL_X_BUTTON]) _pPADStatus->button|=PAD_BUTTON_X;
if (PadState[_numPAD].buttons[CTL_Y_BUTTON]) _pPADStatus->button|=PAD_BUTTON_Y;
if (PadState[_numPAD].buttons[CTL_Z_TRIGGER]) _pPADStatus->button|=PAD_TRIGGER_Z;
if (PadState[_numPAD].buttons[CTL_START]) _pPADStatus->button|=PAD_BUTTON_START;
///////////////////////////////////////////////////
// The D-pad
// -----------
if (PadMapping[_numPAD].controllertype == InputCommon::CTL_DPAD_HAT)
if (PadMapping[_numPAD].controllertype == CTL_DPAD_HAT)
{
if (PadState[_numPAD].dpad == SDL_HAT_LEFTUP || PadState[_numPAD].dpad == SDL_HAT_UP || PadState[_numPAD].dpad == SDL_HAT_RIGHTUP ) _pPADStatus->button|=PAD_BUTTON_UP;
if (PadState[_numPAD].dpad == SDL_HAT_LEFTUP || PadState[_numPAD].dpad == SDL_HAT_LEFT || PadState[_numPAD].dpad == SDL_HAT_LEFTDOWN ) _pPADStatus->button|=PAD_BUTTON_LEFT;
@ -509,13 +573,13 @@ void PAD_GetStatus(u8 _numPAD, SPADStatus* _pPADStatus)
}
else
{
if (PadState[_numPAD].dpad2[InputCommon::CTL_D_PAD_UP])
if (PadState[_numPAD].dpad2[CTL_D_PAD_UP])
_pPADStatus->button |= PAD_BUTTON_UP;
if (PadState[_numPAD].dpad2[InputCommon::CTL_D_PAD_DOWN])
if (PadState[_numPAD].dpad2[CTL_D_PAD_DOWN])
_pPADStatus->button |= PAD_BUTTON_DOWN;
if (PadState[_numPAD].dpad2[InputCommon::CTL_D_PAD_LEFT])
if (PadState[_numPAD].dpad2[CTL_D_PAD_LEFT])
_pPADStatus->button |= PAD_BUTTON_LEFT;
if (PadState[_numPAD].dpad2[InputCommon::CTL_D_PAD_RIGHT])
if (PadState[_numPAD].dpad2[CTL_D_PAD_RIGHT])
_pPADStatus->button |= PAD_BUTTON_RIGHT;
}
@ -581,7 +645,226 @@ bool IsFocus()
}
//////////////////////////////////////////////////////////////////////////////////////////
// Convert stick values
// ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
/* Convert stick values.
The value returned by SDL_JoystickGetAxis is a signed integer s16
(-32768 to 32767). The value used for the gamecube controller is an unsigned
char u8 (0 to 255) with neutral at 0x80 (128), so that it's equivalent to a signed
-128 to 127.
*/
// ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
int Pad_Convert(int _val)
{
/* If the limits on PadState[].axis[] actually is a u16 then we don't need this
but if it's not actually limited to that we need to apply these limits */
if(_val > 32767) _val = 32767; // upper limit
if(_val < -32768) _val = -32768; // lower limit
// Convert the range (-0x8000 to 0x7fff) to (0 to 0xffff)
_val = 0x8000 +_val;
// Convert the range (-32768 to 32767) to (-128 to 127)
_val = _val >> 8;
//Console::Print("0x%04x %06i\n\n", _val, _val);
return _val;
}
/* Convert the stick raidus from a circular to a square. I don't know what input values
the actual GC controller produce for the GC, it may be a square, a circle or something
in between. But one thing that is certain is that PC pads differ in their output (as
shown in the list below), so it may be beneficiary to convert whatever radius they
produce to the radius the GC games expect. This is the first implementation of this
that convert a square radius to a circual radius. Use the advanced settings to enable
and calibrate it.
Observed diagonals:
Perfect circle: 71% = sin(45)
Logitech Dual Action: 100%
Dual Shock 2 (Original) with Super Dual Box Pro: 90%
XBox 360 Wireless: 85%
GameCube Controller (Third Party) with EMS TrioLinker Plus II: 60%
*/
// ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
float SquareDistance(float deg)
{
// See if we have to adjust the angle
deg = abs(deg);
if( (deg > 45 && deg < 135) ) deg = deg - 90;
float rad = deg * M_PI / 180;
float val = abs(cos(rad));
float dist = 1 / val; // Calculate distance from center
//m_frame->m_pStatusBar2->SetLabel(wxString::Format("Deg:%f Val:%f Dist:%f", deg, val, dist));
return dist;
}
std::vector<int> Pad_Square_to_Circle(int _x, int _y, int _pad)
{
/* Do we need this? */
if(_x > 32767) _x = 32767; if(_y > 32767) _y = 32767; // upper limit
if(_x < -32768) _x = -32768; if(_y > 32767) _y = 32767; // lower limit
// ====================================
// Convert to circle
// -----------
int Tmp = atoi (PadMapping[_pad].SDiagonal.substr(0, PadMapping[_pad].SDiagonal.length() - 1).c_str());
float Diagonal = Tmp / 100.0;
// First make a perfect square in case we don't have one already
float OrigDist = sqrt( pow((float)_y, 2) + pow((float)_x, 2) ); // Get current distance
float rad = atan2((float)_y, (float)_x); // Get current angle
float deg = rad * 180 / M_PI;
// A diagonal of 85% means a distance of 1.20
float corner_circle_dist = ( Diagonal / sin(45 * M_PI / 180) );
float SquareDist = SquareDistance(deg);
float adj_ratio1; // The original-to-square distance adjustment
float adj_ratio2 = SquareDist; // The circle-to-square distance adjustment
// float final_ratio; // The final adjustment to the current distance //TODO: This is not used
float result_dist; // The resulting distance
// Calculate the corner-to-square adjustment ratio
if(corner_circle_dist < SquareDist) adj_ratio1 = SquareDist / corner_circle_dist;
else adj_ratio1 = 1;
// Calculate the resulting distance
result_dist = OrigDist * adj_ratio1 / adj_ratio2;
float x = result_dist * cos(rad); // calculate x
float y = result_dist * sin(rad); // calculate y
int int_x = (int)floor(x);
int int_y = (int)floor(y);
// Debugging
//m_frame->m_pStatusBar2->SetLabel(wxString::Format("%f %f %i", corner_circle_dist, Diagonal, Tmp));
std::vector<int> vec;
vec.push_back(int_x);
vec.push_back(int_y);
return vec;
}
///////////////////////////////////////////////////////////////////// Convert stick values
//////////////////////////////////////////////////////////////////////////////////////////
// Supporting functions
// ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
// Read current joystick status
/* ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
The value PadMapping[].buttons[] is the number of the assigned joypad button,
PadState[].buttons[] is the status of the button, it becomes 0 (no pressed) or 1 (pressed) */
// Read buttons status. Called from GetJoyState().
// ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
void ReadButton(int controller, int button)
{
int ctl_button = PadMapping[controller].buttons[button];
if (ctl_button < joyinfo[PadMapping[controller].ID].NumButtons)
{
PadState[controller].buttons[button] = SDL_JoystickGetButton(PadState[controller].joy, ctl_button);
}
}
// Request joystick state.
// ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
/* Called from: PAD_GetStatus()
Input: The virtual device 0, 1, 2 or 3
Function: Updates the PadState struct with the current pad status. The input value "controller" is
for a virtual controller 0 to 3. */
void GetJoyState(int controller)
{
// Check that Dolphin is in focus, otherwise don't update the pad status
if (!g_Config.bCheckFocus && !IsFocus()) return;
// Update the gamepad status
SDL_JoystickUpdate();
// Save the number of buttons
int Buttons = joyinfo[PadMapping[controller].ID].NumButtons;
// Update axis states. It doesn't hurt much if we happen to ask for nonexisting axises here.
PadState[controller].axis[CTL_MAIN_X] = SDL_JoystickGetAxis(PadState[controller].joy, PadMapping[controller].axis[CTL_MAIN_X]);
PadState[controller].axis[CTL_MAIN_Y] = SDL_JoystickGetAxis(PadState[controller].joy, PadMapping[controller].axis[CTL_MAIN_Y]);
PadState[controller].axis[CTL_SUB_X] = SDL_JoystickGetAxis(PadState[controller].joy, PadMapping[controller].axis[CTL_SUB_X]);
PadState[controller].axis[CTL_SUB_Y] = SDL_JoystickGetAxis(PadState[controller].joy, PadMapping[controller].axis[CTL_SUB_Y]);
// Update the analog trigger axis values
#ifdef _WIN32
if (PadMapping[controller].triggertype == CTL_TRIGGER_SDL)
{
#endif
// If we are using SDL analog triggers the buttons have to be mapped as 1000 or up, otherwise they are not used
if(PadMapping[controller].buttons[CTL_L_SHOULDER] >= 1000) PadState[controller].axis[CTL_L_SHOULDER] = SDL_JoystickGetAxis(PadState[controller].joy, PadMapping[controller].buttons[CTL_L_SHOULDER] - 1000); else PadState[controller].axis[CTL_L_SHOULDER] = 0;
if(PadMapping[controller].buttons[CTL_R_SHOULDER] >= 1000) PadState[controller].axis[CTL_R_SHOULDER] = SDL_JoystickGetAxis(PadState[controller].joy, PadMapping[controller].buttons[CTL_R_SHOULDER] - 1000); else PadState[controller].axis[CTL_R_SHOULDER] = 0;
#ifdef _WIN32
}
else
{
PadState[controller].axis[CTL_L_SHOULDER] = XInput::GetXI(0, PadMapping[controller].buttons[CTL_L_SHOULDER] - 1000);
PadState[controller].axis[CTL_R_SHOULDER] = XInput::GetXI(0, PadMapping[controller].buttons[CTL_R_SHOULDER] - 1000);
}
#endif
// Update button states to on or off
ReadButton(controller, CTL_L_SHOULDER);
ReadButton(controller, CTL_R_SHOULDER);
ReadButton(controller, CTL_A_BUTTON);
ReadButton(controller, CTL_B_BUTTON);
ReadButton(controller, CTL_X_BUTTON);
ReadButton(controller, CTL_Y_BUTTON);
ReadButton(controller, CTL_Z_TRIGGER);
ReadButton(controller, CTL_START);
//
if (PadMapping[controller].halfpress < joyinfo[controller].NumButtons)
PadState[controller].halfpress = SDL_JoystickGetButton(PadState[controller].joy, PadMapping[controller].halfpress);
// Check if we have an analog or digital joypad
if (PadMapping[controller].controllertype == CTL_DPAD_HAT)
{
PadState[controller].dpad = SDL_JoystickGetHat(PadState[controller].joy, PadMapping[controller].dpad);
}
else
{
/* Only do this if the assigned button is in range (to allow for the current way of saving keyboard
keys in the same array) */
if(PadMapping[controller].dpad2[CTL_D_PAD_UP] <= Buttons)
PadState[controller].dpad2[CTL_D_PAD_UP] = SDL_JoystickGetButton(PadState[controller].joy, PadMapping[controller].dpad2[CTL_D_PAD_UP]);
if(PadMapping[controller].dpad2[CTL_D_PAD_DOWN] <= Buttons)
PadState[controller].dpad2[CTL_D_PAD_DOWN] = SDL_JoystickGetButton(PadState[controller].joy, PadMapping[controller].dpad2[CTL_D_PAD_DOWN]);
if(PadMapping[controller].dpad2[CTL_D_PAD_LEFT] <= Buttons)
PadState[controller].dpad2[CTL_D_PAD_LEFT] = SDL_JoystickGetButton(PadState[controller].joy, PadMapping[controller].dpad2[CTL_D_PAD_LEFT]);
if(PadMapping[controller].dpad2[CTL_D_PAD_RIGHT] <= Buttons)
PadState[controller].dpad2[CTL_D_PAD_RIGHT] = SDL_JoystickGetButton(PadState[controller].joy, PadMapping[controller].dpad2[CTL_D_PAD_RIGHT]);
}
/* Debugging
Console::ClearScreen();
Console::Print(
"Controller and handle: %i %i\n"
"Triggers:%i %i %i %i %i | HalfPress: %i Mapping: %i\n",
controller, (int)PadState[controller].joy,
PadMapping[controller].triggertype,
PadMapping[controller].buttons[CTL_L_SHOULDER], PadMapping[controller].buttons[CTL_R_SHOULDER],
PadState[controller].axis[CTL_L_SHOULDER], PadState[controller].axis[CTL_R_SHOULDER],
PadState[controller].halfpress, PadMapping[controller].halfpress
); */
}
//////////////////////////////////////////////////////////////////////////////////////////

View File

@ -35,9 +35,6 @@
// ¯¯¯¯¯¯¯¯¯¯
// Set this if you want to use the rumble 'hack' for controller one
//#define USE_RUMBLE_DINPUT_HACK
// Show a status window with the detected axes, buttons and so on
//#define SHOW_PAD_STATUS
//////////////////////////
@ -48,9 +45,7 @@
#include <cstdio>
#include <ctime>
#include <cmath>
#include "../../../Core/InputCommon/Src/SDL.h" // Core
#include "../../../Core/InputCommon/Src/XInput.h"
#include <SDL.h>
#include "Common.h" // Common
#include "pluginspecs_pad.h"
@ -59,6 +54,7 @@
//#include "Timer.h"
#include "Config.h" // Local
#include "XInput.h"
#if defined(HAVE_WX) && HAVE_WX
#include "GUI/AboutBox.h"
@ -106,6 +102,115 @@
#define THANKYOU "`plot`, Absolute0, Aprentice, Bositman, Brice, ChaosCode, CKemu, CoDeX, Dave2001, dn, drk||Raziel, Florin, Gent, Gigaherz, Hacktarux, JegHegy, Linker, Linuzappz, Martin64, Muad, Knuckles, Raziel, Refraction, Rudy_x, Shadowprince, Snake785, Saqib, vEX, yaz0r, Zilmar, Zenogais and ZeZu."
//////////////////////////////////////////////////////////////////////////////////////////
// Structures
/* ¯¯¯¯¯¯¯¯¯¯
CONTROLLER_STATE buttons (PadState) = 0 or 1
CONTROLLER_MAPPING buttons (joystick) = 0 or 1, 2, 3, 4, a certain joypad button
Please remember: The axis limit is hardcoded here, if you allow more axises (for
example for analog A and B buttons) you must first incrase the size of the axis array
size here
*/
struct CONTROLLER_STATE // GC PAD INFO/STATE
{
int buttons[8]; // Amount of buttons (A B X Y Z, L-Trigger R-Trigger Start) might need to change the triggers buttons
int dpad; // Automatic SDL D-Pad (8 directions + neutral)
int dpad2[4]; // D-pad using buttons
int axis[6]; // 2 x 2 Axes (Main & Sub)
int halfpress; // Halfpress... you know, like not fully pressed ;)...
SDL_Joystick *joy; // SDL joystick device
};
struct CONTROLLER_MAPPING // GC PAD MAPPING
{
int buttons[8]; // (See above)
int dpad; // (See above)
int dpad2[4]; // (See above)
int axis[6]; // (See above)
int halfpress; // (See above)
int enabled; // Pad attached?
int deadzone; // Deadzone... what else?
int ID; // SDL joystick device ID
int controllertype; // Hat: Hat or custom buttons
int triggertype; // Triggers range
std::string SDiagonal;
bool bSquareToCircle;
int eventnum; // Linux Event Number, Can't be found dynamically yet
};
struct CONTROLLER_INFO // CONNECTED WINDOWS DEVICES INFO
{
int NumAxes; // Amount of Axes
int NumButtons; // Amount of Buttons
int NumBalls; // Amount of Balls
int NumHats; // Amount of Hats (POV)
std::string Name; // Joypad/stickname
int ID; // SDL joystick device ID
bool Good;
SDL_Joystick *joy; // SDL joystick device
};
enum
{
// CTL_L_SHOULDER and CTL_R_SHOULDER = 0 and 1
CTL_MAIN_X = 2,
CTL_MAIN_Y,
CTL_SUB_X,
CTL_SUB_Y
};
enum
{
CTL_L_SHOULDER = 0,
CTL_R_SHOULDER,
CTL_A_BUTTON,
CTL_B_BUTTON,
CTL_X_BUTTON,
CTL_Y_BUTTON,
CTL_Z_TRIGGER,
CTL_START
};
// DPad Type
enum
{
CTL_DPAD_HAT = 0, // Automatically use the first hat that SDL finds
CTL_DPAD_CUSTOM // Custom directional pad settings
};
// Trigger Type
enum
{
CTL_TRIGGER_SDL = 0, //
CTL_TRIGGER_XINPUT // The XBox 360 pad
};
enum
{
CTL_D_PAD_UP = 0,
CTL_D_PAD_DOWN,
CTL_D_PAD_LEFT,
CTL_D_PAD_RIGHT
};
// Button type for the configuration
enum
{
CTL_AXIS = 0,
CTL_HAT,
CTL_BUTTON,
CTL_KEY
};
// XInput buttons
enum
{
XI_TRIGGER_L = 0,
XI_TRIGGER_R
};
//////////////////////////////////////////////////////////////////////////////////////////
// Input vector. Todo: Save the configured keys here instead of in joystick
// ¯¯¯¯¯¯¯¯¯
@ -120,11 +225,11 @@ extern std::vector<u8> Keys;
//////////////////////////////////////////////////////////////////////////////////////////
// Variables
// ¯¯¯¯¯¯¯¯¯
#ifndef _EXCLUDE_MAIN_
#ifndef _CONTROLLER_STATE_H
extern FILE *pFile;
extern std::vector<InputCommon::CONTROLLER_INFO> joyinfo;
extern InputCommon::CONTROLLER_STATE PadState[4];
extern InputCommon::CONTROLLER_MAPPING PadMapping[4];
extern std::vector<CONTROLLER_INFO> joyinfo;
extern CONTROLLER_STATE PadState[4];
extern CONTROLLER_MAPPING PadMapping[4];
extern HWND m_hWnd; // Handle to window
extern int NumPads, NumGoodPads; // Number of goods pads
#endif
@ -133,12 +238,16 @@ extern std::vector<u8> Keys;
//////////////////////////////////////////////////////////////////////////////////////////
// Custom Functions
// ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
bool Search_Devices(std::vector<InputCommon::CONTROLLER_INFO> &_joyinfo, int &_NumPads, int &_NumGoodPads);
void GetJoyState(int controller);
int Search_Devices();
void DEBUG_INIT();
void DEBUG_QUIT();
bool IsFocus();
void Pad_Use_Rumble(u8 _numPAD, SPADStatus* _pPADStatus); // Rumble
int Pad_Convert(int _val); // Value conversion
std::vector<int> Pad_Square_to_Circle(int _x, int _y, int _pad); // Value conversion
//void SaveConfig();
//void LoadConfig();