SimplePad: Added input recording options to the GUI, now we just need to get rerecording to work to, perhaps one can rewind the input counter when a state is loaded? So the input counter is saved in the savestate for the pad.

git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@2184 8ced0084-cf51-0410-be5f-012b33b47a6e
This commit is contained in:
John Peterson 2009-02-09 20:06:27 +00:00
parent 09c8368180
commit 5edef94753
13 changed files with 312 additions and 196 deletions

View File

@ -240,23 +240,14 @@ void GetJoyState(CONTROLLER_STATE &_PadState, CONTROLLER_MAPPING _PadMapping, in
// ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
/* 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,int AdvancedMapFilter)
bool AvoidValues(int value, bool NoTriggerFilter)
{
// Avoid detecting very small or very big (for triggers) values
if( (value > -0x2000 && value < 0x2000) )// Small values
{
return true; //Avoid
}
if( (value > -0x2000 && value < 0x2000) // Small values
|| ((value < -0x6000 || value > 0x6000) && !NoTriggerFilter)) // Big values
return true; // Avoid
else
{
if (!AdvancedMapFilter)
{
if (value < -0x6000 || value > 0x6000) // Big values
return true; //Avoid
}
return false; //Keep
}
return false; // Keep
}
@ -264,7 +255,7 @@ bool AvoidValues(int value,int AdvancedMapFilter)
// ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
void GetButton(SDL_Joystick *joy, int ControllerID, int buttons, int axes, int hats,
int &KeyboardKey, int &value, int &type, int &pressed, bool &Succeed, bool &Stop,
bool LeftRight, bool Axis, bool XInput, bool Button, bool Hat , int FilterSet)
bool LeftRight, bool Axis, bool XInput, bool Button, bool Hat, bool NoTriggerFilter)
{
// It needs the wxWidgets excape keycode
static const int WXK_ESCAPE = 27;
@ -279,13 +270,12 @@ void GetButton(SDL_Joystick *joy, int ControllerID, int buttons, int axes, int h
{
value = SDL_JoystickGetAxis(joy, i);
if(AvoidValues(value,FilterSet)) continue; // Avoid values
if(AvoidValues(value, NoTriggerFilter)) continue; // Avoid values
pressed = i + (LeftRight ? 1000 : 0); // Identify the analog triggers
type = InputCommon::CTL_AXIS;
Succeed = true;
}
Console::Print("Id: %i\n", joy);
}
// Check for a hat
@ -358,7 +348,7 @@ void GetButton(SDL_Joystick *joy, int ControllerID, int buttons, int axes, int h
}
}
// Only accept the escape key
else
else if (KeyboardKey == WXK_ESCAPE)
{
Succeed = true;
KeyboardKey = 0;

View File

@ -86,7 +86,7 @@ struct CONTROLLER_MAPPING // GC PAD MAPPING
int triggertype; // Triggers range
std::string SDiagonal;
bool bSquareToCircle;
bool bFilterSettings;
bool bNoTriggerFilter;
int eventnum; // Linux Event Number, Can't be found dynamically yet
};
@ -181,7 +181,7 @@ struct CONTROLLER_MAPPING_NEW // GC PAD MAPPING
int triggertype; // SDL or XInput trigger
std::string SDiagonal;
bool bSquareToCircle;
bool bFilterSettings;
bool bNoTriggerFilter;
};
////////////////////////////
@ -193,7 +193,7 @@ struct CONTROLLER_MAPPING_NEW // GC PAD MAPPING
// General functions
bool SearchDevices(std::vector<CONTROLLER_INFO> &_joyinfo, int &NumPads, int &NumGoodPads);
void GetJoyState(CONTROLLER_STATE &_PadState, CONTROLLER_MAPPING _PadMapping, int controller, int NumButtons);
void GetButton(SDL_Joystick*, int,int,int,int, int&,int&,int&,int&,bool&,bool&, bool,bool,bool,bool,bool,int);
void GetButton(SDL_Joystick*, int,int,int,int, int&,int&,int&,int&,bool&,bool&, bool,bool,bool,bool,bool,bool);
// Value conversion
int Pad_Convert(int _val);

View File

@ -59,6 +59,7 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "DolphinWX", "Core\DolphinWX
{0318BA30-EF48-441A-9E10-DC85EFAE39F0} = {0318BA30-EF48-441A-9E10-DC85EFAE39F0}
{8D612734-FAA5-4B8A-804F-4DEA2367D495} = {8D612734-FAA5-4B8A-804F-4DEA2367D495}
{71B16F46-0B00-4EDA-B253-D6D9D03A215C} = {71B16F46-0B00-4EDA-B253-D6D9D03A215C}
{9A183B48-ECC2-4121-876A-9B3793686073} = {9A183B48-ECC2-4121-876A-9B3793686073}
{33546D62-7F34-4EA6-A88E-D538B36E16BF} = {33546D62-7F34-4EA6-A88E-D538B36E16BF}
{3E03C179-8251-46E4-81F4-466F114BAC63} = {3E03C179-8251-46E4-81F4-466F114BAC63}
{95CCAABC-7062-47C4-B8C1-A064DD5F16FF} = {95CCAABC-7062-47C4-B8C1-A064DD5F16FF}
@ -185,6 +186,7 @@ Global
{9A183B48-ECC2-4121-876A-9B3793686073}.DebugFast|Win32.ActiveCfg = DebugFast|Win32
{9A183B48-ECC2-4121-876A-9B3793686073}.DebugFast|x64.ActiveCfg = DebugFast|x64
{9A183B48-ECC2-4121-876A-9B3793686073}.Release|Win32.ActiveCfg = Release|Win32
{9A183B48-ECC2-4121-876A-9B3793686073}.Release|Win32.Build.0 = Release|Win32
{9A183B48-ECC2-4121-876A-9B3793686073}.Release|x64.ActiveCfg = Release|x64
{9A183B48-ECC2-4121-876A-9B3793686073}.Release|x64.Build.0 = Release|x64
{29C2ABC1-ADA5-42CD-A5FC-96022D52A510}.Debug|Win32.ActiveCfg = Debug|Win32

View File

@ -30,11 +30,16 @@ 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(CTL_A,ConfigDialog::OnButtonClick)
EVT_BUTTON(CTL_B,ConfigDialog::OnButtonClick)
EVT_BUTTON(CTL_X,ConfigDialog::OnButtonClick)
@ -145,18 +150,51 @@ void ConfigDialog::CreateGUIControls()
#endif
for(int i = 0; i < 4; i++)
{
sbDevice[i] = new wxStaticBoxSizer(wxVERTICAL, m_Controller[i], wxT("Controller Settings"));
{
// --------------------------------------------------------------------
// Settings
// -----------------------------
// Main horizontal container
sDevice[i] = new wxBoxSizer(wxHORIZONTAL);
sbDevice[i] = new wxStaticBoxSizer(wxVERTICAL, m_Controller[i], wxT("Controller Settings"));
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_Disable[i] = new wxCheckBox(m_Controller[i], ID_DISABLE, wxT("Disable when Dolphin is not in focus"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator);
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_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_SizeRecording[i]->Add(m_CheckRecording[i], 0, wxEXPAND | wxALL, 1);
m_SizeRecording[i]->Add(m_CheckPlayback[i], 0, wxEXPAND | wxALL, 1);
// Set values
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);
// Disable
m_CheckRecording[i]->Enable(false); m_CheckRecording[0]->Enable(true);
m_CheckPlayback[i]->Enable(false); m_CheckPlayback[0]->Enable(true);
#ifdef _WIN32
// Check if any XInput pad was found
if (arrayStringFor_X360Pad.IsEmpty())
{
m_X360Pad[i]->SetLabel(wxT("Enable X360Pad - No pad connected"));
@ -175,19 +213,21 @@ void ConfigDialog::CreateGUIControls()
m_Rumble[i]->Enable(m_X360Pad[i]->IsChecked());
}
#endif
m_Disable[i]->SetValue(pad[i].bDisable);
sDevice[i]->Add(m_Attached[i], 0, wxEXPAND|wxALL, 1);
sDevice[i]->AddStretchSpacer();
// Sizers
sDevice[i]->Add(sbDevice[i], 0, wxEXPAND | wxALL, 1);
//sDevice[i]->AddStretchSpacer();
#ifdef _WIN32
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();
sDevice[i]->Add(m_SizeXInput[i], 0, wxEXPAND | wxALL, 1);
sDevice[i]->Add(m_SizeRecording[i], 0, wxEXPAND | wxALL, 1);
#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);
@ -227,10 +267,13 @@ 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(sbDevice[i], wxGBPosition(0, 0), wxGBSpan(1, 5), wxEXPAND|wxALL, 1);
sPage[i]->Add(sDevice[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);
@ -291,9 +334,15 @@ 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());
@ -305,8 +354,16 @@ void ConfigDialog::ControllerSettingsChanged(wxCommandEvent& event)
case ID_RUMBLE:
pad[page].bRumble = m_Rumble[page]->GetValue();
break;
case ID_DISABLE:
pad[page].bDisable = m_Disable[page]->GetValue();
case ID_RECORDING:
pad[page].bRecording = m_CheckRecording[page]->GetValue();
// Turn off the other option
pad[page].bPlayback = false; m_CheckPlayback[page]->SetValue(false);
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;
}
}

View File

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

View File

@ -15,6 +15,10 @@
// Official SVN repository and contact information can be found at
// http://code.google.com/p/dolphin-emu/
//////////////////////////////////////////////////////////////////////////////////////////
// Include
// ¯¯¯¯¯¯¯¯¯¯¯¯¯
#include <stdio.h>
#include <math.h>
@ -22,43 +26,61 @@
#include "pluginspecs_pad.h"
#include "PadSimple.h"
#include "IniFile.h"
#include "ConsoleWindow.h"
#include "StringUtil.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;
////////////////////////////////
//******************************************************************************
// Supporting functions
@ -66,46 +88,60 @@ int count = 0;
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(): %s\n", ArrayToString(TmpData, sizeof(SPADStatus), 0, 30).c_str());
}
const SPADStatus& PlayRecord()
{
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("c:\\pad-record.bin", "rb");
FILE* pStream = fopen("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");
}
}
void SaveRecord()
{
FILE* pStream = fopen("c:\\pad-record.bin", "wb");
FILE* pStream = fopen("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");
}
// Reset the counter
count = 0;
}
// Check if Dolphin is in focus
bool IsFocus()
{
@ -167,89 +203,6 @@ 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
@ -284,6 +237,92 @@ void ScaleStickValues(unsigned char* outx,
}
//******************************************************************************
// 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);
// Load configuration
LoadConfig();
// Load recorded input
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) {
}
void Shutdown()
{
// Save recording
if (pad[0].bRecording) SaveRecord();
#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();
}
#ifdef _WIN32
void DInput_Read(int _numPAD, SPADStatus* _pPADStatus)
{
@ -614,25 +653,24 @@ void cocoa_Read(int _numPAD, SPADStatus* _pPADStatus)
}
#endif
// 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))
if (_pPADStatus == NULL) return;
// Play back input instead of accepting any user input
if (pad[0].bPlayback)
{
*_pPADStatus = PlayRecord();
return;
}
#ifdef RECORD_REPLAY
*_pPADStatus = PlayRecord();
return;
#endif
const int base = 0x80;
// Clear pad
memset(_pPADStatus, 0, sizeof(SPADStatus));
@ -643,15 +681,18 @@ void PAD_GetStatus(u8 _numPAD, SPADStatus* _pPADStatus)
_pPADStatus->substickY = base;
_pPADStatus->button |= PAD_USE_ORIGIN;
#ifdef _WIN32
// Just update pad on focus
if (pad[_numPAD].bDisable)
{
if (!IsFocus()) return;
}
// Only update pad on focus, don't do this when recording
if (pad[_numPAD].bDisable && !pad[0].bRecording && !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);
@ -660,9 +701,8 @@ void PAD_GetStatus(u8 _numPAD, SPADStatus* _pPADStatus)
cocoa_Read(_numPAD, _pPADStatus);
#endif
#ifdef RECORD_STORE
RecordInput(*_pPADStatus);
#endif
// Record input
if (pad[0].bRecording) RecordInput(*_pPADStatus);
}
@ -816,6 +856,9 @@ 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],
@ -845,6 +888,9 @@ 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,11 +73,14 @@ 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
};

View File

@ -91,7 +91,7 @@ void Config::Load(bool ChangePad)
iniFile.Get(SectionName.c_str(), "TriggerType", &WiiMoteEmu::PadMapping[i].triggertype, 0);
iniFile.Get(SectionName.c_str(), "Diagonal", &WiiMoteEmu::PadMapping[i].SDiagonal, "100%");
iniFile.Get(SectionName.c_str(), "SquareToCircle", &WiiMoteEmu::PadMapping[i].bSquareToCircle, false);
iniFile.Get(SectionName.c_str(), "AdvancedMapFilter", &WiiMoteEmu::PadMapping[i].bFilterSettings,false);
iniFile.Get(SectionName.c_str(), "NoTriggerFilter", &WiiMoteEmu::PadMapping[i].bNoTriggerFilter, false);
}
// =============================
Console::Print("Load()\n");
@ -154,7 +154,7 @@ void Config::Save()
iniFile.Set(SectionName.c_str(), "TriggerType", WiiMoteEmu::PadMapping[i].triggertype);
//iniFile.Set(SectionName.c_str(), "Diagonal", PadMapping[i].SDiagonal);
//iniFile.Set(SectionName.c_str(), "SquareToCircle", PadMapping[i].bSquareToCircle);
iniFile.Set(SectionName.c_str(), "AdvancedMapFilter", WiiMoteEmu::PadMapping[i].bFilterSettings);
iniFile.Set(SectionName.c_str(), "NoTriggerFilter", WiiMoteEmu::PadMapping[i].bNoTriggerFilter);
// ======================================
}

View File

@ -254,7 +254,7 @@ void ConfigDialog::DoGetButtons(int GetId)
bool Hat = false; // No hats allowed
bool AdvancedMapFilter = WiiMoteEmu::PadMapping[Controller].bFilterSettings;
bool NoTriggerFilter = WiiMoteEmu::PadMapping[Controller].bNoTriggerFilter;
// Values used in this function
char format[128];
@ -314,7 +314,7 @@ void ConfigDialog::DoGetButtons(int GetId)
InputCommon::GetButton(
WiiMoteEmu::joyinfo[PadID].joy, PadID, WiiMoteEmu::joyinfo[PadID].NumButtons, WiiMoteEmu::joyinfo[PadID].NumAxes, WiiMoteEmu::joyinfo[PadID].NumHats,
g_Pressed, value, type, pressed, Succeed, Stop,
LeftRight, Axis, XInput, Button, Hat, AdvancedMapFilter);
LeftRight, Axis, XInput, Button, Hat, NoTriggerFilter);
}
// ========================= Check for keys
@ -336,8 +336,8 @@ void ConfigDialog::DoGetButtons(int GetId)
sprintf(format, "[%d]", TmpTime);
SetButtonText(GetId, format);
/* Debug */
Console::Print("Keyboard: %i\n", g_Pressed);
/* Debug
Console::Print("Keyboard: %i\n", g_Pressed);*/
}
// Time's up

View File

@ -168,7 +168,7 @@ void Config::Save(int Slot)
file.Set(SectionName.c_str(), "Diagonal", PadMapping[i].SDiagonal);
file.Set(SectionName.c_str(), "SquareToCircle", PadMapping[i].bSquareToCircle);
file.Set(SectionName.c_str(), "AdvancedMapFilter", PadMapping[i].bFilterSettings);
file.Set(SectionName.c_str(), "AdvancedMapFilter", PadMapping[i].bNoTriggerFilter);
// ======================================
// Debugging
@ -255,7 +255,7 @@ void Config::Load(bool ChangePad, bool ChangeSaveByID)
file.Get(SectionName.c_str(), "Diagonal", &PadMapping[i].SDiagonal, "100%");
file.Get(SectionName.c_str(), "SquareToCircle", &Tmp, false); PadMapping[i].bSquareToCircle = Tmp;
file.Get(SectionName.c_str(), "AdvancedMapFilter", &Tmp,false); PadMapping[i].bFilterSettings = Tmp;
file.Get(SectionName.c_str(), "AdvancedMapFilter", &Tmp, false); PadMapping[i].bNoTriggerFilter = Tmp;
// =============================
// Debugging

View File

@ -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(IDC_CHECKFOCUS, ConfigBox::ChangeSettings)
EVT_CHECKBOX(IDCB_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,7 @@ 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(IDFILTER_SETTINGS, ConfigBox::ChangeSettings)
EVT_CHECKBOX(IDCB_FILTER_SETTINGS, ConfigBox::ChangeSettings)
EVT_BUTTON(IDB_SHOULDER_L, ConfigBox::GetButtons)
EVT_BUTTON(IDB_SHOULDER_R, ConfigBox::GetButtons)
@ -426,7 +426,7 @@ void ConfigBox::ChangeSettings( wxCommandEvent& event )
}
SizeWindow();
break;
case IDC_CHECKFOCUS:
case IDCB_CHECKFOCUS:
g_Config.bCheckFocus = m_CBCheckFocus[notebookpage]->IsChecked();
for(int i = 0; i < 4; i++)
{
@ -522,7 +522,7 @@ void ConfigBox::UpdateGUI(int _notebookpage)
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(IDFILTER_SETTINGS)->Enable(Enabled);
m_Controller[_notebookpage]->FindItem(IDCB_FILTER_SETTINGS)->Enable(Enabled);
#endif
// Replace the harder to understand -1 with "" for the sake of user friendliness
@ -822,12 +822,10 @@ 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(
@ -842,8 +840,6 @@ 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 );
@ -898,10 +894,8 @@ void ConfigBox::CreateGUIControls()
"This will convert a square stick radius to a circle stick radius like the one that the actual GameCube pad produce."
" That is also the input the games expect to see."
));
AdvancedMapFilter[i] = new wxCheckBox(m_Controller[i],IDFILTER_SETTINGS,_("Advanced Controller filtering"));
m_gStatusInSettings[i]->Add(m_CBS_to_C[i], 0, (wxALL), 4);
m_gStatusInSettings[i]->Add(AdvancedMapFilter[i],0,(wxALL),4);
m_gStatusInSettings[i]->Add(m_gStatusInSettingsH[i], 0, (wxLEFT | wxRIGHT | wxBOTTOM), 4);
m_gStatusInSettingsH[i]->Add(m_STDiagonal[i], 0, wxTOP, 3);
@ -911,6 +905,20 @@ 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
@ -933,6 +941,7 @@ 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

View File

@ -113,15 +113,15 @@ class ConfigBox : public wxDialog
wxStaticBoxSizer *m_gGenSettingsID[4];
wxGridBagSizer * m_gGBGenSettings[4];
wxCheckBox *m_CBSaveByID[4], *m_CBShowAdvanced[4], *m_CBCheckFocus[4];
wxCheckBox *m_CBSaveByID[4], *m_CBShowAdvanced[4];
wxStaticText *m_TSControltype[4], *m_TSTriggerType[4];
wxStaticBoxSizer *m_gStatusIn[4], *m_gStatusInSettings[4]; // Advanced settings
wxStaticBoxSizer *m_gStatusIn[4], *m_gStatusInSettings[4], *m_gStatusAdvancedSettings[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 *AdvancedMapFilter[4];
wxCheckBox *m_CBCheckFocus[4], *m_AdvancedMapFilter[4];
wxStaticBoxSizer *m_gStatusTriggers[4]; // Triggers
wxStaticText *m_TStatusTriggers[4];
@ -212,7 +212,7 @@ class ConfigBox : public wxDialog
IDG_CONTROLLERTYPE, IDC_CONTROLTYPE, IDC_TRIGGERTYPE, // Controller type
IDC_SAVEBYID, IDC_SHOWADVANCED, IDC_CHECKFOCUS, // Settings
IDC_SAVEBYID, IDC_SHOWADVANCED, // Settings
ID_INSTATUS1, ID_INSTATUS2, ID_INSTATUS3, ID_INSTATUS4, // Advanced status
ID_STATUSBMP1, ID_STATUSBMP2, ID_STATUSBMP3, ID_STATUSBMP4,
@ -220,7 +220,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,IDFILTER_SETTINGS,
IDCB_MAINSTICK_DIAGONAL, IDCB_MAINSTICK_S_TO_C, IDT_MAINSTICK_DIAGONAL, IDT_TRIGGERS, IDCB_CHECKFOCUS, IDCB_FILTER_SETTINGS,
// Timers
IDTM_CONSTANT, IDTM_BUTTON,

View File

@ -79,8 +79,7 @@ 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);
AdvancedMapFilter[controller]->SetValue(PadMapping[controller].bFilterSettings);
m_AdvancedMapFilter[controller]->SetValue(PadMapping[controller].bNoTriggerFilter);
//LogMsg("m_TriggerType[%i] = %i\n", controller, PadMapping[controller].triggertype);
@ -124,8 +123,7 @@ void ConfigBox::SaveButtonMapping(int controller, bool DontChangeId, int FromSlo
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].bFilterSettings = AdvancedMapFilter[FromSlot]->IsChecked();
PadMapping[controller].bNoTriggerFilter = m_AdvancedMapFilter[FromSlot]->IsChecked();
// The analog buttons
m_JoyAnalogMainX[FromSlot]->GetValue().ToLong(&value); PadMapping[controller].axis[InputCommon::CTL_MAIN_X] = value; tmp.clear();
@ -299,7 +297,7 @@ void ConfigBox::DoGetButtons(int GetId)
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
bool AdvancedMapFilter = PadMapping[Controller].bFilterSettings;
bool NoTriggerFilter = PadMapping[Controller].bNoTriggerFilter;
// Values used in this function
char format[128];
@ -355,7 +353,7 @@ void ConfigBox::DoGetButtons(int GetId)
InputCommon::GetButton(
joyinfo[PadID].joy, PadID, joyinfo[PadID].NumButtons, joyinfo[PadID].NumAxes, joyinfo[PadID].NumHats,
g_Pressed, value, type, pressed, Succeed, Stop,
LeftRight, Axis, XInput, Button, Hat, AdvancedMapFilter);
LeftRight, Axis, XInput, Button, Hat, NoTriggerFilter);
}
// ========================= Check for keys