nJoy: Fixed the analog trigger buttons

git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@1934 8ced0084-cf51-0410-be5f-012b33b47a6e
This commit is contained in:
John Peterson
2009-01-19 17:47:00 +00:00
parent be1e403435
commit 8f40075f8f
13 changed files with 478 additions and 358 deletions

View File

@ -130,28 +130,36 @@ void ConfigBox::PadGetStatus()
// Show the current pad status
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
std::string ShowStatus()
std::string ShowStatus(int Controller)
{
SDL_Joystick *joy = SDL_JoystickOpen(0);
int axes = SDL_JoystickNumAxes(joy);
int hats = SDL_JoystickNumHats(joy);
int but = SDL_JoystickNumButtons(joy);
// Make local shortcut
SDL_Joystick *joy = joystate[joysticks[Controller].ID].joy;
// Temporary storage
std::string StrAxes, StrHats, StrBut;
int value;
// Go through all axes and read out their values
// Get status
int Axes = joyinfo[joysticks[Controller].ID].NumAxes;
int Balls = joyinfo[joysticks[Controller].ID].NumBalls;
int Hats = joyinfo[joysticks[Controller].ID].NumHats;
int Buttons = joyinfo[joysticks[Controller].ID].NumButtons;
// Update the internal values
SDL_JoystickUpdate();
for(int i = 0; i < axes; i++)
// Go through all axes and read out their values
for(int i = 0; i < Axes; i++)
{
value = SDL_JoystickGetAxis(joy, i);
StrAxes += StringFromFormat(" %i:%05i", i, value);
}
for(int i = 0;i < hats; i++)
for(int i = 0;i < Hats; i++)
{
value = SDL_JoystickGetHat(joy, i);
StrHats += StringFromFormat(" %i:%i", i, value);
}
for(int i = 0;i < but; i++)
for(int i = 0;i < Buttons; i++)
{
value = SDL_JoystickGetButton(joy, i);
StrBut += StringFromFormat(" %i:%i", i+1, value);
@ -159,9 +167,8 @@ std::string ShowStatus()
return StringFromFormat(
"Axes: %s\nHats: %s\nBut: %s\nDevice: Ax: %i Balls:%i But:%i Hats:%i",
StrAxes.c_str(), StrHats.c_str(), StrBut.c_str(),
joyinfo[joysticks[0].ID].NumAxes, joyinfo[joysticks[0].ID].NumBalls,
joyinfo[joysticks[0].ID].NumButtons, joyinfo[joysticks[0].ID].NumHats
StrAxes.c_str(), StrHats.c_str(), StrBut.c_str(),
Axes, Balls, Hats, Buttons
);
}
@ -173,10 +180,10 @@ void ConfigBox::Update()
if(!g_Config.bShowAdvanced) StrangeHack = false; else StrangeHack = true;
// Show the current status
/**/
/*
m_pStatusBar->SetLabel(wxString::Format(
"%s", ShowStatus().c_str()
));
"%s", ShowStatus(notebookpage).c_str()
));*/
}

View File

@ -43,12 +43,10 @@ extern CONTROLLER_INFO *joyinfo;
//extern CONTROLLER_MAPPING joysticks[4];
extern bool emulator_running;
static const char* ControllerType[] =
static const char* DPadType[] =
{
"Joystick (with hat)",
"Joystick (no hat)",
// "Joytstick (xbox360)", // Shoulder buttons -> axis
// "Keyboard" // Not supported yet, sorry F|RES ;( ...
"Hat",
"Custom",
};
////////////////////////
@ -91,16 +89,14 @@ BEGIN_EVENT_TABLE(ConfigBox,wxDialog)
EVT_BUTTON(IDB_ANALOG_SUB_Y, ConfigBox::GetButtons)
#if wxUSE_TIMER
EVT_TIMER(wxID_ANY, ConfigBox::OnTimer)
EVT_TIMER(IDTM_CONSTANT, ConfigBox::OnTimer)
EVT_TIMER(IDTM_BUTTON, ConfigBox::OnButtonTimer)
#endif
END_EVENT_TABLE()
ConfigBox::ConfigBox(wxWindow *parent, wxWindowID id, const wxString &title,
const wxPoint &position, const wxSize& size, long style)
: wxDialog(parent, id, title, position, size, style)
#if wxUSE_TIMER
, m_timer(this)
#endif
{
// Define values
notebookpage = 0;
@ -110,21 +106,28 @@ ConfigBox::ConfigBox(wxWindow *parent, wxWindowID id, const wxString &title,
CreateGUIControls();
#if wxUSE_TIMER
m_ConstantTimer = new wxTimer(this, IDTM_CONSTANT);
m_ButtonMappingTimer = new wxTimer(this, IDTM_BUTTON);
// Reset values
GetButtonWaitingID = 0; GetButtonWaitingTimer = 0;
// Start the constant timer
int TimesPerSecond = 30;
m_timer.Start( floor((double)(1000 / TimesPerSecond)) );
m_ConstantTimer->Start( floor((double)(1000 / TimesPerSecond)) );
#endif
wxTheApp->Connect(wxID_ANY, wxEVT_KEY_DOWN,
// wxEVT_KEY_DOWN is blocked for enter, tab and the directional keys
wxTheApp->Connect(wxID_ANY, wxEVT_KEY_UP,
wxKeyEventHandler(ConfigBox::OnKeyDown),
(wxObject*)0, this);
}
ConfigBox::~ConfigBox()
{
// The statbar sample has this so I add this to
#if wxUSE_TIMER
if (m_timer.IsRunning()) m_timer.Stop();
if (m_ConstantTimer->IsRunning()) m_ConstantTimer->Stop();
#endif
}
@ -177,7 +180,7 @@ void ConfigBox::OKClick(wxCommandEvent& event)
if (Tmp == wxOK) return; else if (Tmp == wxNO) g_Config.bSaveByIDNotice = false;
}
for(int i=0; i<4 ;i++) GetControllerAll(i); // Update joysticks array
for(int i=0; i<4 ;i++) SaveButtonMapping(i); // Update joysticks array
g_Config.Save(true); // Save settings
g_Config.Load(); // Reload settings
Close(); // Call OnClose()
@ -243,24 +246,29 @@ void ConfigBox::EnableDisable(wxCommandEvent& event)
// Update GUI
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
// Called from: SetControllerAll(), ChangeControllertype()
// Called from: UpdateGUIKeys(), ChangeControllertype()
void ConfigBox::UpdateGUI(int _notebookpage)
{
// Update the enable / disable status
joysticks[_notebookpage].enabled = m_Joyattach[_notebookpage]->GetValue();
// Controller type settings
bool HasHat = (joysticks[_notebookpage].controllertype == CTL_TYPE_JOYSTICK);
m_JoyDpadDown[_notebookpage]->Show(HasHat);
m_JoyDpadLeft[_notebookpage]->Show(HasHat);
m_JoyDpadRight[_notebookpage]->Show(HasHat);
m_bJoyDpadDown[_notebookpage]->Show(HasHat);
m_bJoyDpadLeft[_notebookpage]->Show(HasHat);
m_bJoyDpadRight[_notebookpage]->Show(HasHat);
m_textDpadUp[_notebookpage]->Show(HasHat);
m_textDpadDown[_notebookpage]->Show(HasHat);
m_textDpadLeft[_notebookpage]->Show(HasHat);
m_textDpadRight[_notebookpage]->Show(HasHat);
bool Hat = (joysticks[_notebookpage].controllertype == CTL_DPAD_HAT);
m_JoyDpadLeft[_notebookpage]->Show(!Hat);
m_JoyDpadRight[_notebookpage]->Show(!Hat);
m_JoyDpadDown[_notebookpage]->Show(!Hat);
m_bJoyDpadLeft[_notebookpage]->Show(!Hat);
m_bJoyDpadRight[_notebookpage]->Show(!Hat);
m_bJoyDpadDown[_notebookpage]->Show(!Hat);
m_textDpadDown[_notebookpage]->Show(!Hat);
m_textDpadLeft[_notebookpage]->Show(!Hat);
m_textDpadRight[_notebookpage]->Show(!Hat);
m_textDpadUp[_notebookpage]->SetLabel(Hat ? wxT("Select hat") : wxT("Up"));
m_bJoyDpadUp[_notebookpage]->SetToolTip(Hat ?
wxT("Select a hat by pressing the hat in any direction") : wxT(""));
// General settings
m_CBSaveByID[_notebookpage]->SetValue(g_Config.bSaveByID.at(_notebookpage));
@ -283,7 +291,6 @@ void ConfigBox::UpdateGUI(int _notebookpage)
m_Controller[_notebookpage]->FindItem(IDC_DEADZONE)->Enable(joysticks[_notebookpage].enabled);
//m_Controller[_notebookpage]->FindItem(IDC_CONTROLTYPE)->Enable(joysticks[_notebookpage].enabled);
#endif
m_Controltype[_notebookpage]->SetSelection(HasHat ? 0 : 1);
// Repaint the background
m_Controller[_notebookpage]->Refresh();
@ -306,7 +313,7 @@ void ConfigBox::ChangeJoystick(wxCommandEvent& event)
{
// Before chaning the pad we save potential changes (to support SaveByID)
int TmpID = joysticks[notebookpage].ID; // Don't update the ID
GetControllerAll(notebookpage);
SaveButtonMapping(notebookpage);
joysticks[notebookpage].ID = TmpID;
g_Config.Save();
@ -317,20 +324,22 @@ void ConfigBox::ChangeJoystick(wxCommandEvent& event)
// Update the controller type
if(joyinfo[joysticks[notebookpage].ID].NumHats > 0)
joysticks[notebookpage].controllertype = CTL_TYPE_JOYSTICK;
joysticks[notebookpage].controllertype = CTL_DPAD_HAT;
//PanicAlert("%i %i", joysticks[notebookpage].ID, notebookpage);
// Load device settings to support SaveByID
g_Config.Load(true); // Then load the current
SetControllerAll(notebookpage); // Update joystick dialog items
UpdateGUIKeys(notebookpage); // Update joystick dialog items
UpdateGUI(notebookpage); // Update other dialog items
// Remap the controller
if (joysticks[notebookpage].enabled)
{
return;
if (SDL_JoystickOpened(notebookpage)) SDL_JoystickClose(joystate[notebookpage].joy);
joystate[notebookpage].joy = SDL_JoystickOpen(joysticks[notebookpage].ID);
PanicAlert("");
}
}
@ -361,9 +370,6 @@ void ConfigBox::CreateGUIControls()
SetIcon(wxNullIcon);
//WxStaticBitmap1_BITMAP(ConfigBox_WxStaticBitmap1_XPM);
//WxStaticBitmap1_BITMAP = new WxStaticBitmap1_BITMAP(ConfigBox_WxStaticBitmap1_XPM);
#ifndef _WIN32
// Force a 8pt font so that it looks more or less "correct" regardless of the default font setting
wxFont f(8, wxFONTFAMILY_DEFAULT, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_NORMAL);
@ -423,10 +429,8 @@ void ConfigBox::CreateGUIControls()
// Populate the controller type list
// -----------------------------
wxArrayString arrayStringFor_Controltype;
arrayStringFor_Controltype.Add(wxString::FromAscii(ControllerType[CTL_TYPE_JOYSTICK]));
arrayStringFor_Controltype.Add(wxString::FromAscii(ControllerType[CTL_TYPE_JOYSTICK_NO_HAT]));
// arrayStringFor_Controltype.Add(wxString::FromAscii(ControllerType[CTL_TYPE_JOYSTICK_XBOX360]));
// arrayStringFor_Controltype.Add(wxString::FromAscii(ControllerType[CTL_TYPE_KEYBOARD]));
arrayStringFor_Controltype.Add(wxString::FromAscii(DPadType[CTL_DPAD_HAT]));
arrayStringFor_Controltype.Add(wxString::FromAscii(DPadType[CTL_DPAD_CUSTOM]));
// --------------------------------------------------------------------
@ -451,7 +455,7 @@ void ConfigBox::CreateGUIControls()
int t = -75; // Top
int l = -4; // Left
m_sKeys[i] = new wxStaticBoxSizer( wxVERTICAL, m_Controller[i], wxT("Keys"));
m_pKeys[i] = new wxPanel(m_Controller[i], ID_KEYSPANEL1 + i, wxDefaultPosition, wxSize(600, 400));
m_pKeys[i] = new wxPanel(m_Controller[i], ID_KEYSPANEL1 + i, wxDefaultPosition, wxSize(600, 400), 0);
//m_sKeys[i] = new wxStaticBox (m_Controller[i], IDG_JOYSTICK, wxT("Keys"), wxDefaultPosition, wxSize(608, 500));
m_sKeys[i]->Add(m_pKeys[i], 0, (wxALL), 0); // margin = 0
@ -487,7 +491,7 @@ void ConfigBox::CreateGUIControls()
m_bJoyShoulderR[i] = new wxButton(m_pKeys[i], IDB_SHOULDER_R, wxEmptyString, wxPoint(l + 526, t + 108), wxSize(21, 14), 0, wxDefaultValidator, wxEmptyString);
// Left analog
int ALt = 170; int ALw = ALt + 14; int ALb = ALw + 2; // Set offset
int ALt = 169; int ALw = ALt + 14; int ALb = ALw + 2; // Set offset
m_JoyAnalogMainX[i] = new wxTextCtrl(m_pKeys[i], ID_ANALOG_MAIN_X, wxT("0"), wxPoint(l + 6, t + ALw), wxSize(59, 19), wxTE_READONLY | wxTE_CENTRE, wxDefaultValidator, wxT("0"));
m_JoyAnalogMainX[i]->Enable(false);
m_JoyAnalogMainY[i] = new wxTextCtrl(m_pKeys[i], ID_ANALOG_MAIN_Y, wxT("0"), wxPoint(l + 6, t + ALw + 36), wxSize(59, 19), wxTE_READONLY | wxTE_CENTRE, wxDefaultValidator, wxT("0"));
@ -496,9 +500,9 @@ void ConfigBox::CreateGUIControls()
m_bJoyAnalogMainY[i] = new wxButton(m_pKeys[i], IDB_ANALOG_MAIN_Y, wxEmptyString, wxPoint(l + 70, t + ALb + 36), wxSize(21, 14), 0, wxDefaultValidator, wxEmptyString);
m_textMainX[i] = new wxStaticText(m_pKeys[i], IDT_ANALOG_MAIN_X, wxT("X-axis"), wxPoint(l + 6, t + ALt), wxDefaultSize, 0, wxT("X-axis"));
m_textMainY[i] = new wxStaticText(m_pKeys[i], IDT_ANALOG_MAIN_Y, wxT("Y-axis"), wxPoint(l + 6, t + ALt + 36), wxDefaultSize, 0, wxT("Y-axis"));
// D-Pad
int DPt = 255; int DPw = DPt + 14; int DPb = DPw + 2; // Set offset
int DPt = 250; int DPw = DPt + 14; int DPb = DPw + 2; // Set offset
m_JoyDpadUp[i] = new wxTextCtrl(m_pKeys[i], ID_DPAD_UP, wxT("0"), wxPoint(l + 6, t + DPw), wxSize(59, 19), wxTE_READONLY | wxTE_CENTRE, wxDefaultValidator, wxT("0"));
m_JoyDpadDown[i] = new wxTextCtrl(m_pKeys[i], ID_DPAD_DOWN, wxT("0"), wxPoint(l + 6, t + DPw + 36*1), wxSize(59, 19), wxTE_READONLY | wxTE_CENTRE, wxDefaultValidator, wxT("0"));
m_JoyDpadLeft[i] = new wxTextCtrl(m_pKeys[i], ID_DPAD_LEFT, wxT("0"), wxPoint(l + 6, t + DPw + 36*2), wxSize(59, 19), wxTE_READONLY | wxTE_CENTRE, wxDefaultValidator, wxT("0"));
@ -515,7 +519,7 @@ void ConfigBox::CreateGUIControls()
m_textDpadDown[i] = new wxStaticText(m_pKeys[i], IDT_DPAD_DOWN, wxT("Down"), wxPoint(l + 6, t + DPt + 36*1), wxDefaultSize, 0, wxT("Down"));
m_textDpadLeft[i] = new wxStaticText(m_pKeys[i], IDT_DPAD_LEFT, wxT("Left"), wxPoint(l + 6, t + DPt + 36*2), wxDefaultSize, 0, wxT("Left"));
m_textDpadRight[i] = new wxStaticText(m_pKeys[i], IDT_DPAD_RIGHT, wxT("Right"), wxPoint(l + 6, t + DPt + 36*3), wxDefaultSize, 0, wxT("Right"));
// Buttons
m_JoyButtonA[i] = new wxTextCtrl(m_pKeys[i], ID_BUTTON_A, wxT("0"), wxPoint(l + 552, t + 280), wxSize(59, 19), wxTE_READONLY | wxTE_CENTRE, wxDefaultValidator, wxT("0"));
m_JoyButtonA[i]->Enable(false);
@ -604,19 +608,16 @@ void ConfigBox::CreateGUIControls()
m_gGBExtrasettings[i]->Add(m_bJoyButtonHalfpress[i], wxGBPosition(1, 2), wxGBSpan(1, 1), (wxLEFT | wxTOP), 2);
m_gExtrasettings[i]->Add(m_gGBExtrasettings[i], 0, wxEXPAND | wxALL, 3);
// Why is there a setting for this? Is it to replaced the analog stick with the digital pad?
// Populate controller typ
m_gControllertype[i] = new wxStaticBoxSizer( wxVERTICAL, m_Controller[i], wxT("Controller type"));
m_gControllertype[i] = new wxStaticBoxSizer( wxVERTICAL, m_Controller[i], wxT("D-Pad"));
m_Controltype[i] = new wxComboBox(m_Controller[i], IDC_CONTROLTYPE, arrayStringFor_Controltype[0], wxDefaultPosition, wxDefaultSize, arrayStringFor_Controltype, wxCB_READONLY);
m_gControllertype[i]->Add(m_Controltype[i], 0, wxEXPAND | wxALL, 3);
m_Controltype[i]->Enable(false);
m_gControllertype[i]->Add(m_Controltype[i], 0, wxEXPAND | wxALL, 3);
m_Controltype[i]->SetToolTip(wxT("Use a 'hat' on your gamepad or configure a custom button for each direction."));
// Create objects for general settings
m_gGenSettings[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_CBSaveByIDNotice[i] = new wxCheckBox(m_Controller[i], IDC_SAVEBYIDNOTICE, wxT("Notice"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator);
m_CBSaveByIDNotice[i] = new wxCheckBox(m_Controller[i], IDC_SAVEBYIDNOTICE, wxT("Notify"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator);
m_CBShowAdvanced[i] = new wxCheckBox(m_Controller[i], IDC_SHOWADVANCED, wxT("Show advanced settings"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator);
// Populate general settings
@ -735,7 +736,7 @@ void ConfigBox::CreateGUIControls()
}
// Set dialog items from saved values
SetControllerAll(i);
UpdateGUIKeys(i);
// Update GUI
UpdateGUI(i);
@ -763,7 +764,7 @@ void ConfigBox::CreateGUIControls()
// --------------------------------------------------------------------
// Debugging
// -----------------------------
m_pStatusBar = new wxStaticText(this, IDT_DEBUGGING, wxT("Debugging"), wxPoint(100, 490), wxDefaultSize);
//m_pStatusBar = new wxStaticText(this, IDT_DEBUGGING, wxT("Debugging"), wxPoint(100, 490), wxDefaultSize);
//m_pStatusBar2 = new wxStaticText(this, IDT_DEBUGGING2, wxT("Debugging2"), wxPoint(100, 530), wxDefaultSize);
//m_pStatusBar->SetLabel(wxString::Format("Debugging text"));

View File

@ -63,7 +63,8 @@ class ConfigBox : public wxDialog
#if wxUSE_TIMER
void OnTimer(wxTimerEvent& WXUNUSED(event)) { Update(); }
wxTimer m_timer;
void OnButtonTimer(wxTimerEvent& WXUNUSED(event)) { DoGetButtons(GetButtonWaitingID); }
wxTimer *m_ConstantTimer, *m_ButtonMappingTimer;
#endif
// Debugging
@ -71,6 +72,9 @@ class ConfigBox : public wxDialog
// Status window
int BoxW, BoxH;
// Configure buttons
int GetButtonWaitingID, GetButtonWaitingTimer;
private:
wxButton *m_About;
@ -86,7 +90,6 @@ class ConfigBox : public wxDialog
wxStaticBoxSizer * m_sKeys[4];
wxBoxSizer *m_sMain[4], *m_sMainLeft[4], *m_sMainRight[4];
/////////////////////////////
// Settings
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
@ -208,6 +211,9 @@ class ConfigBox : public wxDialog
// Advaced settings
IDCB_MAINSTICK_DIAGONAL, IDCB_MAINSTICK_S_TO_C, IDT_MAINSTICK_DIAGONAL,
// Timers
IDTM_CONSTANT, IDTM_BUTTON,
// --------------------------------------------------------------------
// Keys objects
@ -292,12 +298,12 @@ class ConfigBox : public wxDialog
wxBitmap CreateBitmap(); wxBitmap CreateBitmapDot();
void PadGetStatus(); void Update();
void SetControllerAll(int controller);
void GetControllerAll(int controller);
void UpdateGUIKeys(int controller);
void SaveButtonMapping(int controller);
void NotebookPageChanged(wxNotebookEvent& event);
void GetButtons(wxCommandEvent& event);
void GetButtons(wxCommandEvent& event); void DoGetButtons(int);
void GetHats(int ID);
void GetAxis(wxCommandEvent& event);

View File

@ -47,7 +47,7 @@ extern bool emulator_running;
// Set dialog items from saved values
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
void ConfigBox::SetControllerAll(int controller)
void ConfigBox::UpdateGUIKeys(int controller)
{
// http://wiki.wxwidgets.org/Converting_everything_to_and_from_wxString
wxString tmp;
@ -82,7 +82,7 @@ void ConfigBox::SetControllerAll(int controller)
UpdateGUI(controller);
if(joysticks[controller].controllertype == CTL_TYPE_JOYSTICK)
if(joysticks[controller].controllertype == CTL_DPAD_HAT)
{
tmp << joysticks[controller].dpad; m_JoyDpadUp[controller]->SetValue(tmp); tmp.clear();
}
@ -98,17 +98,20 @@ void ConfigBox::SetControllerAll(int controller)
/* Populate the joysticks array with the dialog items settings, for example
selected joystick, enabled or disabled status and so on */
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
void ConfigBox::GetControllerAll(int controller)
void ConfigBox::SaveButtonMapping(int controller)
{
// Temporary storage
wxString tmp;
long value;
// The controller ID
joysticks[controller].ID = m_Joyname[controller]->GetSelection();
if(joyinfo[joysticks[controller].ID].NumHats > 0) joysticks[controller].controllertype = CTL_TYPE_JOYSTICK;
m_JoyShoulderL[controller]->GetValue().ToLong(&value); joysticks[controller].buttons[CTL_L_SHOULDER] = value; tmp.clear();
m_JoyShoulderR[controller]->GetValue().ToLong(&value); joysticks[controller].buttons[CTL_R_SHOULDER] = value; tmp.clear();
// The shoulder buttons
m_JoyShoulderL[controller]->GetValue().ToLong(&value); joysticks[controller].buttons[CTL_L_SHOULDER] = value;
m_JoyShoulderR[controller]->GetValue().ToLong(&value); joysticks[controller].buttons[CTL_R_SHOULDER] = value;
// The digital buttons
m_JoyButtonA[controller]->GetValue().ToLong(&value); joysticks[controller].buttons[CTL_A_BUTTON] = value; tmp.clear();
m_JoyButtonB[controller]->GetValue().ToLong(&value); joysticks[controller].buttons[CTL_B_BUTTON] = value; tmp.clear();
m_JoyButtonX[controller]->GetValue().ToLong(&value); joysticks[controller].buttons[CTL_X_BUTTON] = value; tmp.clear();
@ -118,7 +121,8 @@ void ConfigBox::GetControllerAll(int controller)
m_JoyButtonHalfpress[controller]->GetValue().ToLong(&value); joysticks[controller].halfpress = value; tmp.clear();
if(joysticks[controller].controllertype == CTL_TYPE_JOYSTICK)
// Digital pad type
if(joysticks[controller].controllertype == CTL_DPAD_HAT)
{
m_JoyDpadUp[controller]->GetValue().ToLong(&value); joysticks[controller].dpad = value; tmp.clear();
}
@ -155,83 +159,52 @@ void ConfigBox::ChangeControllertype(wxCommandEvent& event)
}
// Update the textbox for the buttons
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
void ConfigBox::SetButtonText(int id, char text[128])
{
int controller = notebookpage;
switch(id)
{
case IDB_DPAD_RIGHT:
m_JoyDpadRight[controller]->SetValue(wxString::FromAscii(text)); break;
case IDB_DPAD_UP:
m_JoyDpadUp[controller]->SetValue(wxString::FromAscii(text)); break;
case IDB_DPAD_DOWN:
m_JoyDpadDown[controller]->SetValue(wxString::FromAscii(text)); break;
case IDB_DPAD_LEFT:
m_JoyDpadLeft[controller]->SetValue(wxString::FromAscii(text)); break;
case IDB_ANALOG_MAIN_X:
m_JoyAnalogMainX[controller]->SetValue(wxString::FromAscii(text)); break;
case IDB_ANALOG_MAIN_Y:
m_JoyAnalogMainY[controller]->SetValue(wxString::FromAscii(text)); break;
case IDB_ANALOG_SUB_X:
m_JoyAnalogSubX[controller]->SetValue(wxString::FromAscii(text)); break;
case IDB_ANALOG_SUB_Y:
m_JoyAnalogSubY[controller]->SetValue(wxString::FromAscii(text)); break;
case IDB_SHOULDER_L:
m_JoyShoulderL[controller]->SetValue(wxString::FromAscii(text)); break;
case IDB_SHOULDER_R:
m_JoyShoulderR[controller]->SetValue(wxString::FromAscii(text)); break;
case IDB_BUTTON_A:
m_JoyButtonA[controller]->SetValue(wxString::FromAscii(text)); break;
m_JoyButtonA[controller]->SetValue(wxString::FromAscii(text)); break;
case IDB_BUTTON_B:
{
m_JoyButtonB[controller]->SetValue(wxString::FromAscii(text));
}
break;
m_JoyButtonB[controller]->SetValue(wxString::FromAscii(text)); break;
case IDB_BUTTON_X:
{
m_JoyButtonX[controller]->SetValue(wxString::FromAscii(text));
}
break;
m_JoyButtonX[controller]->SetValue(wxString::FromAscii(text)); break;
case IDB_BUTTON_Y:
m_JoyButtonY[controller]->SetValue(wxString::FromAscii(text)); break;
case IDB_BUTTON_Z:
m_JoyButtonZ[controller]->SetValue(wxString::FromAscii(text)); break;
case IDB_BUTTONSTART:
{
m_JoyButtonStart[controller]->SetValue(wxString::FromAscii(text));
}
break;
m_JoyButtonStart[controller]->SetValue(wxString::FromAscii(text)); break;
case IDB_BUTTONHALFPRESS:
{
m_JoyButtonHalfpress[controller]->SetValue(wxString::FromAscii(text));
}
break;
case IDB_DPAD_UP:
{
m_JoyDpadUp[controller]->SetValue(wxString::FromAscii(text));
}
break;
case IDB_DPAD_DOWN:
{
m_JoyDpadDown[controller]->SetValue(wxString::FromAscii(text));
}
break;
case IDB_DPAD_LEFT:
{
m_JoyDpadLeft[controller]->SetValue(wxString::FromAscii(text));
}
break;
case IDB_DPAD_RIGHT:
m_JoyDpadRight[controller]->SetValue(wxString::FromAscii(text)); break;
case IDB_ANALOG_MAIN_X:
m_JoyAnalogMainX[controller]->SetValue(wxString::FromAscii(text)); break;
case IDB_ANALOG_MAIN_Y:
m_JoyAnalogMainY[controller]->SetValue(wxString::FromAscii(text)); break;
case IDB_ANALOG_SUB_X:
m_JoyAnalogSubX[controller]->SetValue(wxString::FromAscii(text)); break;
case IDB_ANALOG_SUB_Y:
m_JoyAnalogSubY[controller]->SetValue(wxString::FromAscii(text)); break;
m_JoyButtonHalfpress[controller]->SetValue(wxString::FromAscii(text)); break;
default:
break;
@ -240,7 +213,7 @@ void ConfigBox::SetButtonText(int id, char text[128])
//////////////////////////////////////////////////////////////////////////////////////////
// Condifigure button mapping
// Configure button mapping
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
@ -261,23 +234,37 @@ bool AvoidValues(int value)
// Wait for button press
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
/* Loop or timer: There are basically two ways to do this. With a while() or for() loop, or with a
timer. The downside with the while() or for() loop is that there is no way to stop it if the user
should select to configure another button while we are still in an old loop. What will happen then
is that we start another parallel loop (at least in Windows) that blocks the old loop. And our only
option to wait for the old loop to finish is with a new loop, and that will block the old loop for as
long as it's going on. Therefore a timer is easier to control. */
void ConfigBox::GetButtons(wxCommandEvent& event)
{
DoGetButtons(event.GetId());
}
void ConfigBox::DoGetButtons(int GetId)
{
// =============================================
// Collect the starting values
// ----------------
// Get the current controller
int controller = notebookpage;
// Get the ID for the wxWidgets button that was pressed
int ID = event.GetId();
int Controller = notebookpage;
// Collect the accepted buttons for this slot
bool Axis = (event.GetId() >= IDB_ANALOG_MAIN_X && event.GetId() <= IDB_SHOULDER_R);
bool Button = (event.GetId() >= IDB_BUTTON_A && event.GetId() <= IDB_BUTTONSTART)
|| (event.GetId() == IDB_SHOULDER_L || event.GetId() == IDB_SHOULDER_R);
bool Hat = (event.GetId() >= IDB_DPAD_UP && event.GetId() <= IDB_DPAD_RIGHT);
bool LeftRight = (GetId == IDB_SHOULDER_L || GetId == IDB_SHOULDER_R);
bool Axis = (GetId >= IDB_ANALOG_MAIN_X && GetId <= IDB_SHOULDER_R);
bool Button = (GetId >= IDB_BUTTON_A && GetId <= IDB_BUTTONSTART)
|| (GetId == IDB_SHOULDER_L || GetId == IDB_SHOULDER_R)
|| (GetId >= IDB_DPAD_UP && GetId <= IDB_DPAD_RIGHT && joysticks[Controller].controllertype == CTL_DPAD_CUSTOM);
bool Hat = (GetId >= IDB_DPAD_UP && GetId <= IDB_DPAD_RIGHT)
&& (joysticks[Controller].controllertype == CTL_DPAD_HAT);
/* Open a new joystick. Joysticks[controller].ID is the system ID of the physical joystick
/* 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 joysticks */
SDL_Joystick *joy = SDL_JoystickOpen(joysticks[controller].ID);
SDL_Joystick *joy = SDL_JoystickOpen(joysticks[Controller].ID);
// Get the number of axes, hats and buttons
int buttons = SDL_JoystickNumButtons(joy);
@ -287,18 +274,47 @@ void ConfigBox::GetButtons(wxCommandEvent& event)
// Declare values
char format[128];
int value; // Axis value
bool waiting = true;
bool succeed = false;
int type; // Button type
bool Succeed = false;
bool Stop = false; // Stop the timer
int pressed = 0;
int counter1 = 0; // Waiting limits
int counter2 = 30; // Iterations to wait for
int Seconds = 4; // Seconds to wait for
int TimesPerSecond = 40; // How often to run the check
// =======================
// Update the text box
sprintf(format, "[%d]", counter2);
SetButtonText(ID, format);
wxWindow::Update(); // Win only? doesnt seem to work in linux...
//Console::Print("Before (%i) Id:%i %i IsRunning:%i\n",
// GetButtonWaitingTimer, GetButtonWaitingID, GetId, m_ButtonMappingTimer->IsRunning());
while(waiting)
// If the Id has changed or the timer is not running we should start one
if( GetButtonWaitingID != GetId || !m_ButtonMappingTimer->IsRunning() )
{
if(m_ButtonMappingTimer->IsRunning())
{
m_ButtonMappingTimer->Stop();
GetButtonWaitingTimer = 0;
// Update the old textbox
SetButtonText(GetButtonWaitingID, "");
}
// Save the button Id
GetButtonWaitingID = GetId;
// Reset the key in case we happen to have an old one
g_Pressed = 0;
// Update the text box
sprintf(format, "[%d]", Seconds);
SetButtonText(GetId, format);
// Start the timer
#if wxUSE_TIMER
m_ButtonMappingTimer->Start( floor((double)(1000 / TimesPerSecond)) );
#endif
}
// If there is a timer but we should not create a new one
else
{
// Update the internal status
SDL_JoystickUpdate();
@ -312,10 +328,9 @@ void ConfigBox::GetButtons(wxCommandEvent& event)
if(AvoidValues(value)) continue; // Avoid values
pressed = i;
waiting = false;
succeed = true;
break; // Stop this loop
pressed = i + (LeftRight ? 1000 : 0); // Identify the analog triggers
type = CTL_AXIS;
Succeed = true;
}
}
@ -324,13 +339,11 @@ void ConfigBox::GetButtons(wxCommandEvent& event)
{
for(int i = 0; i < hats; i++)
{
value = SDL_JoystickGetHat(joy, i);
if(value)
if(SDL_JoystickGetHat(joy, i))
{
pressed = value;
waiting = false;
succeed = true;
break;
pressed = i;
type = CTL_HAT;
Succeed = true;
}
}
}
@ -342,25 +355,23 @@ void ConfigBox::GetButtons(wxCommandEvent& event)
{
if(SDL_JoystickGetButton(joy, i))
{
pressed = i;
waiting = false;
succeed = true;
break;
pressed = i;
type = CTL_BUTTON;
Succeed = true;
}
}
}
// Check for keyboard action
if (g_Pressed)
if (g_Pressed && Button)
{
// Todo: Add a separate keyboard vector to remove this restriction
if(g_Pressed >= buttons)
{
pressed = g_Pressed;
waiting = false;
succeed = true;
g_Pressed = 0;
break;
type = CTL_BUTTON;
Succeed = true;
g_Pressed = 0;
}
else
{
@ -370,48 +381,66 @@ void ConfigBox::GetButtons(wxCommandEvent& event)
, wxT("Notice"), wxICON_INFORMATION);
pressed = g_Pressed;
waiting = false;
succeed = false;
g_Pressed = 0;
break;
Succeed = false;
g_Pressed = 0;
}
}
// Stop waiting for a button
counter1++;
if(counter1 == 25)
// Count each time
GetButtonWaitingTimer++;
// This is run every second
if(GetButtonWaitingTimer % TimesPerSecond == 0)
{
counter1 = 0;
counter2--;
sprintf(format, "[%d]", counter2);
SetButtonText(ID, format);
wxWindow::Update(); // win only? doesnt seem to work in linux...
wxYieldIfNeeded(); // Let through the keyboard input event
if(counter2 < 0) waiting = false;
//Console::Print("Second\n\n");
// Current time
int TmpTime = Seconds - (GetButtonWaitingTimer / TimesPerSecond);
// Update text
sprintf(format, "[%d]", TmpTime);
SetButtonText(GetId, format);
}
// Sleep for 10 ms then poll for keys again
SLEEP(10);
// Debugging
/*
m_pStatusBar->SetLabel(wxString::Format(
"ID: %i %i",
counter1, NumKeys
));
*/
// Time's up
if( (GetButtonWaitingTimer / TimesPerSecond) >= Seconds )
{
Stop = true;
// Leave a blank mapping
SetButtonText(GetId, "");
}
// If we got a button
if(Succeed)
{
Stop = true;
// Write the number of the pressed button to the text box
sprintf(format, "%d", pressed);
SetButtonText(GetId, format);
}
}
// Write the number of the pressed button to the text box
sprintf(format, "%d", succeed ? pressed : -1);
SetButtonText(ID, format);
// Stop the timer
if(Stop)
{
m_ButtonMappingTimer->Stop();
GetButtonWaitingTimer = 0;
}
// We don't need thisgamepad handle any more
if(SDL_JoystickOpened(joysticks[controller].ID)) SDL_JoystickClose(joy);
if(SDL_JoystickOpened(joysticks[Controller].ID)) SDL_JoystickClose(joy);
// Update the button mapping
SaveButtonMapping(Controller);
// Debugging
//Console::Print("IsRunning: %i\n", m_ButtonMappingTimer->IsRunning());
}
#if 0
// Wait for Analog
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
void ConfigBox::GetAxis(wxCommandEvent& event)
@ -476,7 +505,7 @@ void ConfigBox::GetAxis(wxCommandEvent& event)
SDL_JoystickClose(joy);
// Update the axises for the advanced settings status
GetControllerAll(controller);
SaveButtonMapping(controller);
}
@ -530,5 +559,6 @@ void ConfigBox::GetHats(int ID)
if(SDL_JoystickOpened(joysticks[controller].ID))
SDL_JoystickClose(joy);
}
#endif
/////////////////////////////////////////////////////////// Configure button mapping