Now WiiMote button mapping supports both Keyboard & Joypad, or even mixed, no need to bother Xpadder. :)

But I've only tested on Win32 SDL, don't know about Linux or 360pad.

git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@4630 8ced0084-cf51-0410-be5f-012b33b47a6e
This commit is contained in:
ayuanx 2009-11-29 17:58:52 +00:00
parent 8eb821722f
commit 5ef159a971
9 changed files with 147 additions and 100 deletions

View file

@ -160,7 +160,7 @@ void RadiusAdjustment(int &_x, int &_y, int _pad, std::string SRadius)
// ---------------------
/* Calculate the distance from the outer edges of the box to the outer edges of the circle inside the box
at any angle from 0° to 360°. The returned value is 1 + Distance, for example at most sqrt(2) in the
at any angle from 0 to 360. The returned value is 1 + Distance, for example at most sqrt(2) in the
corners and at least 1.0 at the horizontal and vertical angles. */
float Square2CircleDistance(float deg)
{
@ -240,9 +240,13 @@ std::string VKToString(int keycode)
#ifdef _WIN32
// Default value
char KeyStr[64] = {0};
std::string KeyString;
// TODO: Switch to unicode GetKeyNameText?
if (keycode < 256) // Keyboard
GetKeyNameTextA(MapVirtualKey(keycode, MAPVK_VK_TO_VSC) << 16, KeyStr, 64);
std::string KeyString = KeyStr;
else // Pad
sprintf(KeyStr, "PAD: %d", keycode - 0x1000);
switch(keycode)
{
@ -263,7 +267,7 @@ std::string VKToString(int keycode)
case VK_RCONTROL: return "RIGHT CTRL";
case VK_LMENU: return "LEFT ALT";
default: return KeyString;
default: return KeyString = KeyStr;
}
#else
// An equivalent name translation can probably be used on other systems to?

View file

@ -293,7 +293,8 @@ void GetButton(SDL_Joystick *joy, int ControllerID, int buttons, int axes, int h
{
for(int i = 0; i < hats; i++)
{
if(SDL_JoystickGetHat(joy, i))
value = SDL_JoystickGetHat(joy, i);
if(value)
{
pressed = i;
type = InputCommon::CTL_HAT;

View file

@ -67,21 +67,22 @@ WiimoteBasicConfigDialog::WiimoteBasicConfigDialog(wxWindow *parent, wxWindowID
void WiimoteBasicConfigDialog::OnClose(wxCloseEvent& event)
{
event.Skip();
g_FrameOpen = false;
g_Config.Save();
if (m_PadConfigFrame)
{
m_PadConfigFrame->EndModal(wxID_CLOSE);
delete m_PadConfigFrame;
m_PadConfigFrame = NULL;
}
if (m_RecordingConfigFrame)
{
m_RecordingConfigFrame->EndModal(wxID_CLOSE);
delete m_RecordingConfigFrame;
m_RecordingConfigFrame = NULL;
}
if (!g_EmulatorRunning) Shutdown();
// This will let the Close() function close and remove the wxDialog
event.Skip();
if (!g_EmulatorRunning)
Shutdown();
EndModal(wxID_CLOSE);
}
/* Timeout the shutdown. In Windows at least the g_pReadThread execution will hang at any attempt to
@ -89,11 +90,13 @@ void WiimoteBasicConfigDialog::OnClose(wxCloseEvent& event)
We must therefore shut down the thread from here and wait for that before we can call ShutDown(). */
void WiimoteBasicConfigDialog::ShutDown(wxTimerEvent& WXUNUSED(event))
{
// Close() is a wxWidgets function that will trigger EVT_CLOSE() and then call this->Destroy().
// Wait for the Wiimote thread to stop, then close and shutdown
WiiMoteReal::g_Shutdown = true;
m_ShutDownTimer->Start(10);
if(!WiiMoteReal::g_ThreadGoing)
{
m_ShutDownTimer->Stop();
Close();
}
}
@ -102,24 +105,14 @@ void WiimoteBasicConfigDialog::ButtonClick(wxCommandEvent& event)
switch(event.GetId())
{
case ID_CLOSE:
// Wait for the Wiimote thread to stop, then close and shutdown
if(!g_EmulatorRunning)
{
WiiMoteReal::g_Shutdown = true;
m_ShutDownTimer->Start(10);
}
// Close directly
else
{
// Close() is a wxWidgets function that will trigger EVT_CLOSE() and then call this->Destroy().
Close();
}
break;
case ID_APPLY:
g_Config.Save();
break;
case ID_BUTTONMAPPING:
if (m_PadConfigFrame)
m_PadConfigFrame->EndModal(wxID_CLOSE);
if (!m_PadConfigFrame)
m_PadConfigFrame = new WiimotePadConfigDialog(this);
if (!m_PadConfigFrame->IsShown())
m_PadConfigFrame->ShowModal();

View file

@ -90,7 +90,7 @@ void WiimotePadConfigDialog::DoChangeDeadZone(bool Left)
// Set the button text for all four Wiimotes
void WiimotePadConfigDialog::SetButtonTextAll(int id, char text[128])
{
for (int i = 0; i < 1; i++)
for (int i = 0; i < 1; i++) // We've got only 1 currently
{
// Safety check to avoid crash
if ((int)WiiMoteEmu::joyinfo.size() > WiiMoteEmu::PadMapping[i].ID)
@ -299,7 +299,7 @@ void WiimotePadConfigDialog::ToBlank(bool _ToBlank)
// Update the textbox for the buttons
void WiimotePadConfigDialog::SetButtonText(int id, char text[128], int _Page)
void WiimotePadConfigDialog::SetButtonText(int id, const char text[128], int _Page)
{
// Set controller value
int controller;
@ -367,6 +367,14 @@ wxString WiimotePadConfigDialog::GetButtonText(int id, int _Page)
on. Therefore a timer is easier to control. */
void WiimotePadConfigDialog::GetButtons(wxCommandEvent& event)
{
if (event.GetEventType() != wxEVT_COMMAND_BUTTON_CLICKED)
return;
if (m_ButtonMappingTimer->IsRunning())
return;
OldLabel.clear();
SetButtonText(event.GetId(), "<Axis>");
DoGetButtons(event.GetId());
}
@ -390,9 +398,9 @@ void WiimotePadConfigDialog::DoGetButtons(int _GetId)
bool XInput = (TriggerType == InputCommon::CTL_TRIGGER_XINPUT);
bool Button = false; // No digital buttons allowed
bool Button = (_GetId >= IDB_WM_A && _GetId <= IDB_GH3_STRUM_DOWN);
bool Hat = false; // No hats allowed
bool Hat = (_GetId >= IDB_WM_A && _GetId <= IDB_GH3_STRUM_DOWN);
bool NoTriggerFilter = g_Config.bNoTriggerFilter;
@ -402,8 +410,9 @@ void WiimotePadConfigDialog::DoGetButtons(int _GetId)
int TimesPerSecond = 40; // How often to run the check
// Values returned from InputCommon::GetButton()
int value; // Axis value
int value; // Axis value or Hat value
int type; // Button type
int pressed = 0;
bool Succeed = false;
bool Stop = false; // Stop the timer
@ -415,24 +424,14 @@ void WiimotePadConfigDialog::DoGetButtons(int _GetId)
if( GetButtonWaitingID != _GetId || !m_ButtonMappingTimer->IsRunning() )
{
if(m_ButtonMappingTimer->IsRunning())
{
m_ButtonMappingTimer->Stop();
GetButtonWaitingTimer = 0;
// Update the old textbox
SetButtonText(GetButtonWaitingID, (char *)"");
}
// Save the button Id
GetButtonWaitingID = _GetId;
GetButtonWaitingTimer = 0;
// 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)) );
@ -459,6 +458,7 @@ void WiimotePadConfigDialog::DoGetButtons(int _GetId)
// Count each time
GetButtonWaitingTimer++;
// This is run every second
if(GetButtonWaitingTimer % TimesPerSecond == 0)
{
@ -468,34 +468,39 @@ void WiimotePadConfigDialog::DoGetButtons(int _GetId)
// Update text
sprintf(format, "[ %d ]", TmpTime);
SetButtonText(_GetId, format);
/* Debug
DEBUG_LOG(WIIMOTE, "Keyboard: %i", g_Pressed);*/
}
// Time's up
if( (GetButtonWaitingTimer / TimesPerSecond) >= Seconds )
{
Stop = true;
// Leave a blank mapping
SetButtonTextAll(_GetId, (char *)"-1");
// Revert back to old label
SetButtonText(_GetId, OldLabel.ToAscii());
}
// If we got a button
if(Succeed)
{
Stop = true;
// Write the number of the pressed button to the text box
sprintf(format, "%d", pressed);
SetButtonTextAll(_GetId, format);
}
// Stop the timer
if(Stop)
// We need to assign hat special code
if (type == InputCommon::CTL_HAT)
{
// Index of pressed starts from 0
if (value & SDL_HAT_UP) pressed = 0x0100 + 0x0010 * pressed + SDL_HAT_UP;
else if (value & SDL_HAT_DOWN) pressed = 0x0100 + 0x0010 * pressed + SDL_HAT_DOWN;
else if (value & SDL_HAT_LEFT) pressed = 0x0100 + 0x0010 * pressed + SDL_HAT_LEFT;
else if (value & SDL_HAT_RIGHT) pressed = 0x0100 + 0x0010 * pressed + SDL_HAT_RIGHT;
else pressed = -1;
}
if (_GetId >= IDB_WM_A && _GetId <= IDB_GH3_STRUM_DOWN)
{
// Better make the pad button code far from virtual key code
SaveKeyboardMapping(Page, ClickedButton->GetId(), 0x1000 + pressed);
sprintf(format, "PAD: %d", pressed);
}
else
{
m_ButtonMappingTimer->Stop();
GetButtonWaitingTimer = 0;
/* Update the button mapping for all slots that use this device. (It
doesn't make sense to have several slots controlled by the same
device, but several DirectInput instances of different but identical
@ -503,16 +508,29 @@ void WiimotePadConfigDialog::DoGetButtons(int _GetId)
do this. The user may also have selected the same device for several
disabled slots. */
SaveButtonMappingAll(Controller);
// Write the number of the pressed button to the text box
sprintf(format, "%d", pressed);
}
SetButtonTextAll(_GetId, format);
}
// Stop the timer
if(Stop)
{
DEBUG_LOG(WIIMOTE, "Timer Stopped for Pad:%i _GetId:%i",
WiiMoteEmu::PadMapping[Controller].ID, _GetId);
m_ButtonMappingTimer->Stop();
GetButtonWaitingTimer = 0;
GetButtonWaitingID = 0;
ClickedButton = NULL;
}
// If we got a bad button
if(g_Pressed == -1)
{
// Update text
SetButtonTextAll(_GetId, (char *)"-1");
SetButtonTextAll(_GetId, (char *)"PAD: -1");
// Notify the user
wxMessageBox(wxString::Format(

View file

@ -114,7 +114,7 @@ WiimotePadConfigDialog::WiimotePadConfigDialog(wxWindow *parent, wxWindowID id,
GetButtonWaitingTimer = 0;
// Start the permanent timer
const int TimesPerSecond = 30;
const int TimesPerSecond = 10;
m_UpdatePad->Start( floor((double)(1000 / TimesPerSecond)) );
#endif
@ -134,26 +134,33 @@ WiimotePadConfigDialog::WiimotePadConfigDialog(wxWindow *parent, wxWindowID id,
(wxObject*)0, this);
}
WiimotePadConfigDialog::~WiimotePadConfigDialog()
{
if (m_ButtonMappingTimer)
delete m_ButtonMappingTimer;
if (m_UpdatePad)
delete m_UpdatePad;
}
void WiimotePadConfigDialog::OnKeyDown(wxKeyEvent& event)
{
event.Skip();
// Save the key
g_Pressed = event.GetKeyCode();
// Handle the keyboard key mapping
char keyStr[64] = {0};
if(ClickedButton != NULL)
{
// Save the key
g_Pressed = event.GetKeyCode();
// Handle the keyboard key mapping
char keyStr[128] = {0};
// Allow the escape key to set a blank key
if (g_Pressed == WXK_ESCAPE)
{
SaveKeyboardMapping(Page, ClickedButton->GetId(), -1);
SetButtonText(ClickedButton->GetId(), "");
ClickedButton = NULL;
return;
}
else
{
#ifdef _WIN32
BYTE keyState[256];
GetKeyboardState(keyState);
@ -178,37 +185,41 @@ void WiimotePadConfigDialog::OnKeyDown(wxKeyEvent& event)
SaveKeyboardMapping(Page, ClickedButton->GetId(), g_Pressed);
#endif
}
m_ButtonMappingTimer->Stop();
GetButtonWaitingTimer = 0;
GetButtonWaitingID = 0;
ClickedButton = NULL;
}
}
// Input button clicked
void WiimotePadConfigDialog::OnButtonClick(wxCommandEvent& event)
{
//DEBUG_LOG(WIIMOTE, "OnButtonClick: %i", g_Pressed);
if (m_ButtonMappingTimer->IsRunning()) return;
// Don't allow space to start a new Press Key option, that will interfer with setting a key to space
if (g_Pressed == WXK_SPACE) { g_Pressed = 0; return; }
// Reset the old label
if(ClickedButton) ClickedButton->SetLabel(OldLabel);
// Create the button object
ClickedButton = (wxButton *)event.GetEventObject();
// Save old label so we can revert back
OldLabel = ClickedButton->GetLabel();
ClickedButton->SetLabel(wxT("<Press Key>"));
// Allow Tab and directional keys to
ClickedButton->SetWindowStyle(wxWANTS_CHARS);
ClickedButton->SetLabel(wxT("<Press Key>"));
DoGetButtons(ClickedButton->GetId());
}
void WiimotePadConfigDialog::OnClose(wxCloseEvent& event)
{
event.Skip();
g_FrameOpen = false;
SaveButtonMappingAll(Page);
if(m_UpdatePad)
m_UpdatePad->Stop();
g_Config.Save();
event.Skip();
SaveButtonMappingAll(Page);
EndModal(wxID_CLOSE);
}
void WiimotePadConfigDialog::CloseClick(wxCommandEvent& event)
@ -220,7 +231,6 @@ void WiimotePadConfigDialog::CloseClick(wxCommandEvent& event)
break;
case ID_APPLY:
SaveButtonMappingAll(Page);
g_Config.Save();
break;
}
}

View file

@ -49,7 +49,7 @@ class WiimotePadConfigDialog : public wxDialog
const wxPoint& pos = wxDefaultPosition,
const wxSize& size = wxDefaultSize,
long style = wxDEFAULT_DIALOG_STYLE | wxWANTS_CHARS);
virtual ~WiimotePadConfigDialog(){;}
virtual ~WiimotePadConfigDialog();
void CloseClick(wxCommandEvent& event);
void UpdateGUI(int Slot = 0);
@ -70,6 +70,7 @@ class WiimotePadConfigDialog : public wxDialog
*m_bmpDotRightOut[4],
*m_bmpDeadZoneLeftIn[4],
*m_bmpDeadZoneRightIn[4];
private:
DECLARE_EVENT_TABLE();
@ -250,15 +251,19 @@ class WiimotePadConfigDialog : public wxDialog
void GeneralSettingsChanged(wxCommandEvent& event);
// Gamepad configuration
void SetButtonText(int id, char text[128], int _Page = -1); void SetButtonTextAll(int id, char text[128]);
void SetButtonText(int id, const char text[128], int _Page = -1);
void SetButtonTextAll(int id, char text[128]);
wxString GetButtonText(int id, int Page = -1);
void GetButtons(wxCommandEvent& event); void DoGetButtons(int);
void SaveButtonMapping(int controller, bool DontChangeId = false, int FromSlot = -1); void SaveButtonMappingAll(int Slot);
void SaveButtonMapping(int controller, bool DontChangeId = false, int FromSlot = -1);
void SaveButtonMappingAll(int Slot);
void SaveKeyboardMapping(int Controller, int Id, int Key);
void ToBlank(bool ToBlank = true);
void PadGetStatus();
void DoSave(bool ChangePad = false, int Slot = -1);
void DoChangeJoystick(); void PadOpen(int Open); void PadClose(int Close); void DoChangeDeadZone(bool Left);
void DoChangeJoystick();
void PadOpen(int Open); void PadClose(int Close);
void DoChangeDeadZone(bool Left);
void OnButtonClick(wxCommandEvent& event);
// Configure buttons

View file

@ -85,10 +85,10 @@ WiimoteRecordingConfigDialog::WiimoteRecordingConfigDialog(wxWindow *parent, wxW
void WiimoteRecordingConfigDialog::OnClose(wxCloseEvent& event)
{
event.Skip();
g_FrameOpen = false;
SaveFile();
g_Config.Save();
event.Skip();
EndModal(wxID_CLOSE);
}
@ -100,7 +100,6 @@ void WiimoteRecordingConfigDialog::CloseClick(wxCommandEvent& event)
Close();
break;
case ID_APPLY:
g_Config.Save();
SaveFile();
WiiMoteEmu::LoadRecordedMovements();
break;

View file

@ -297,28 +297,49 @@ int RecordingCheckKeys(int WmNuIr)
// Subroutines
int GetMapKeyState(int _MapKey)
{
const int Page = 0;
if (_MapKey < 256)
return GetAsyncKeyState(_MapKey); // Keyboard
else if (_MapKey < 0x1100)
return SDL_JoystickGetButton(PadState[Page].joy, _MapKey - 0x1000); // Pad button
else // Pad hat
{
u8 HatCode, HatKey;
HatCode = SDL_JoystickGetHat(PadState[Page].joy, (_MapKey - 0x1100) / 0x0010);
HatKey = (_MapKey - 0x1100) % 0x0010;
if (HatCode & HatKey)
return HatKey;
}
return NULL;
}
// Multi System Input Status Check
int IsKey(int Key)
{
#ifdef _WIN32
if (Key == g_Wiimote_kbd.SHAKE)
return GetAsyncKeyState(PadMapping[0].Wm.keyForControls[Key - g_Wiimote_kbd.A]) || GetAsyncKeyState(VK_MBUTTON);
if (g_Wiimote_kbd.A <= Key && Key <= g_Wiimote_kbd.PITCH_R)
{
return GetAsyncKeyState(PadMapping[0].Wm.keyForControls[Key - g_Wiimote_kbd.A]);
return GetMapKeyState(PadMapping[0].Wm.keyForControls[Key - g_Wiimote_kbd.A]);
}
if (Key == g_Wiimote_kbd.SHAKE)
{
return GetMapKeyState(PadMapping[0].Wm.keyForControls[Key - g_Wiimote_kbd.A]) || GetAsyncKeyState(VK_MBUTTON);
}
if (g_NunchuckExt.Z <= Key && Key <= g_NunchuckExt.SHAKE)
{
return GetAsyncKeyState(PadMapping[0].Nc.keyForControls[Key - g_NunchuckExt.Z]);
return GetMapKeyState(PadMapping[0].Nc.keyForControls[Key - g_NunchuckExt.Z]);
}
if (g_ClassicContExt.A <= Key && Key <= g_ClassicContExt.Rd)
{
return GetAsyncKeyState(PadMapping[0].Cc.keyForControls[Key - g_ClassicContExt.A]);
return GetMapKeyState(PadMapping[0].Cc.keyForControls[Key - g_ClassicContExt.A]);
}
if (g_GH3Ext.Green <= Key && Key <= g_GH3Ext.StrumDown)
{
return GetAsyncKeyState(PadMapping[0].GH3c.keyForControls[Key - g_GH3Ext.Green]);
return GetMapKeyState(PadMapping[0].GH3c.keyForControls[Key - g_GH3Ext.Green]);
}
switch(Key)

View file

@ -191,14 +191,10 @@ void DllConfig(HWND _hParent)
if (!m_BasicConfigFrame)
m_BasicConfigFrame = new WiimoteBasicConfigDialog(GetParentedWxWindow(_hParent));
else if (!m_BasicConfigFrame->GetParent()->IsShown())
m_BasicConfigFrame->Close(true);
// Only allow one open at a time
if (!m_BasicConfigFrame->IsShown())
m_BasicConfigFrame->ShowModal();
else
m_BasicConfigFrame->Hide();
#endif
}