Now Dolphin officially supports Multi-WiiMote (up to 4)

* You can connect/disconnect one or more WiiMote from Menu->Tools any time (must pause game first)

* Up to 4 Emulated Wiimotes can work together at the same timer

(PS: "Wiimote_Real" needs to be rewritten to support Multi-WiiMote, and it could be broken already now)

git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@4736 8ced0084-cf51-0410-be5f-012b33b47a6e
This commit is contained in:
ayuanx 2009-12-27 19:31:02 +00:00
parent 4483f2c7b5
commit d62d6b0c33
36 changed files with 2046 additions and 2749 deletions

Binary file not shown.

View File

@ -148,16 +148,6 @@ bool GetRealWiimote()
return g_bRealWiimote; return g_bRealWiimote;
} }
// This doesn't work yet, I don't understand how the connection work yet
void ReconnectWiimote()
{
// This seems to be a hack that just sets some IPC registers to zero. Dubious.
/* JP: Yes, it's basically nothing right now, I could not figure out how to reset the Wiimote
for reconnection */
HW::InitWiimote();
INFO_LOG(CONSOLE, "ReconnectWiimote()\n");
}
bool isRunning() bool isRunning()
{ {
return (GetState() != CORE_UNINITIALIZED) || g_bHwInit; return (GetState() != CORE_UNINITIALIZED) || g_bHwInit;

View File

@ -61,7 +61,6 @@ namespace Core
void* GetWindowHandle(); void* GetWindowHandle();
bool GetRealWiimote(); bool GetRealWiimote();
void ReconnectWiimote();
extern bool bReadTrace; extern bool bReadTrace;
extern bool bWriteTrace; extern bool bWriteTrace;

View File

@ -44,9 +44,11 @@ CWII_IPC_HLE_Device_usb_oh1_57e_305::CWII_IPC_HLE_Device_usb_oh1_57e_305(u32 _De
, m_LastCmd(0) , m_LastCmd(0)
, m_FreqDividerSync(0) , m_FreqDividerSync(0)
{ {
// Activate the first one Wiimote by default // Activate only first Wiimote by default
m_WiiMotes.push_back(CWII_IPC_HLE_WiiMote(this, 0, true)); m_WiiMotes.push_back(CWII_IPC_HLE_WiiMote(this, 0, true));
m_WiiMotes.push_back(CWII_IPC_HLE_WiiMote(this, 1)); m_WiiMotes.push_back(CWII_IPC_HLE_WiiMote(this, 1));
m_WiiMotes.push_back(CWII_IPC_HLE_WiiMote(this, 2));
m_WiiMotes.push_back(CWII_IPC_HLE_WiiMote(this, 3));
// The BCM2045's btaddr: // The BCM2045's btaddr:
m_ControllerBD.b[0] = 0x11; m_ControllerBD.b[0] = 0x11;
@ -89,6 +91,14 @@ void CWII_IPC_HLE_Device_usb_oh1_57e_305::DoState(PointerWrap &p)
p.Do(m_PacketCount[i]); p.Do(m_PacketCount[i]);
p.Do(m_FreqDividerMote[i]); p.Do(m_FreqDividerMote[i]);
} }
for (unsigned int i = 0; i < m_WiiMotes.size(); i++)
m_WiiMotes[i].DoState(p);
}
bool CWII_IPC_HLE_Device_usb_oh1_57e_305::RemoteDisconnect(u16 _connectionHandle)
{
return SendEventDisconnect(_connectionHandle, 0x13);
} }
// =================================================== // ===================================================
@ -483,7 +493,7 @@ u32 CWII_IPC_HLE_Device_usb_oh1_57e_305::Update()
for (unsigned int i = 0; i < m_WiiMotes.size(); i++) for (unsigned int i = 0; i < m_WiiMotes.size(); i++)
{ {
m_FreqDividerMote[i]++; m_FreqDividerMote[i]++;
if (m_WiiMotes[i].IsLinked() && m_FreqDividerMote[i] >= 150) if (m_WiiMotes[i].IsConnected() == 3 && m_FreqDividerMote[i] >= 150)
{ {
m_FreqDividerMote[i] = 0; m_FreqDividerMote[i] = 0;
CPluginManager::GetInstance().GetWiimote(0)->Wiimote_Update(i); CPluginManager::GetInstance().GetWiimote(0)->Wiimote_Update(i);
@ -1390,13 +1400,13 @@ void CWII_IPC_HLE_Device_usb_oh1_57e_305::CommandDisconnect(u8* _Input)
SendEventDisconnect(pDiscon->con_handle, pDiscon->reason); SendEventDisconnect(pDiscon->con_handle, pDiscon->reason);
PanicAlert("Wiimote (%i) has been disconnected by system due to idle time out.\n"
"Don't panic, this is quite a normal behavior for power saving.\n\n"
"To reconnect, Pasue game and Click \"Menu -> Tools -> Connect Wiimote\"", (pDiscon->con_handle & 0xFF) + 1);
CWII_IPC_HLE_WiiMote* pWiimote = AccessWiiMote(pDiscon->con_handle); CWII_IPC_HLE_WiiMote* pWiimote = AccessWiiMote(pDiscon->con_handle);
if (pWiimote) if (pWiimote)
pWiimote->EventDisconnect(); pWiimote->EventDisconnect();
// Send disconnect message to plugin
u8 Message = WIIMOTE_RECONNECT;
CPluginManager::GetInstance().GetWiimote(0)->Wiimote_ControlChannel(pDiscon->con_handle & 0xFF, 99, &Message, 0);
} }
void CWII_IPC_HLE_Device_usb_oh1_57e_305::CommandAcceptCon(u8* _Input) void CWII_IPC_HLE_Device_usb_oh1_57e_305::CommandAcceptCon(u8* _Input)
@ -1582,15 +1592,6 @@ void CWII_IPC_HLE_Device_usb_oh1_57e_305::CommandSniffMode(u8* _Input)
DEBUG_LOG(WII_IPC_WIIMOTE, " timeout: 0x%04x", pSniffMode->timeout); DEBUG_LOG(WII_IPC_WIIMOTE, " timeout: 0x%04x", pSniffMode->timeout);
SendEventModeChange(pSniffMode->con_handle, 0x02, pSniffMode->max_interval); // 0x02 - sniff mode SendEventModeChange(pSniffMode->con_handle, 0x02, pSniffMode->max_interval); // 0x02 - sniff mode
// Now it is a good time to activate next wiimote
u16 NextHandle = pSniffMode->con_handle + 1;
if ((NextHandle & 0xFFu) < m_WiiMotes.size())
{
CWII_IPC_HLE_WiiMote* pWiimote = AccessWiiMote(NextHandle);
if (pWiimote)
pWiimote->Activate(true);
}
} }
void CWII_IPC_HLE_Device_usb_oh1_57e_305::CommandWriteLinkPolicy(u8* _Input) void CWII_IPC_HLE_Device_usb_oh1_57e_305::CommandWriteLinkPolicy(u8* _Input)

View File

@ -83,6 +83,8 @@ public:
void PurgeACLPool(); void PurgeACLPool();
void PurgeHCIPool(); void PurgeHCIPool();
bool RemoteDisconnect(u16 _connectionHandle);
//hack for wiimote plugin //hack for wiimote plugin
public: public:

View File

@ -30,10 +30,13 @@
static CWII_IPC_HLE_Device_usb_oh1_57e_305* s_Usb; static CWII_IPC_HLE_Device_usb_oh1_57e_305* s_Usb;
CWII_IPC_HLE_Device_usb_oh1_57e_305* GetUsbPointer()
{
return s_Usb;
}
CWII_IPC_HLE_WiiMote::CWII_IPC_HLE_WiiMote(CWII_IPC_HLE_Device_usb_oh1_57e_305* _pHost, int _Number, bool ready) CWII_IPC_HLE_WiiMote::CWII_IPC_HLE_WiiMote(CWII_IPC_HLE_Device_usb_oh1_57e_305* _pHost, int _Number, bool ready)
: m_Linked(false) : m_HIDControlChannel_Connected(false)
, m_HIDControlChannel_Connected(false)
, m_HIDControlChannel_ConnectedWait(false) , m_HIDControlChannel_ConnectedWait(false)
, m_HIDControlChannel_Config(false) , m_HIDControlChannel_Config(false)
, m_HIDControlChannel_ConfigWait(false) , m_HIDControlChannel_ConfigWait(false)
@ -44,7 +47,6 @@ CWII_IPC_HLE_WiiMote::CWII_IPC_HLE_WiiMote(CWII_IPC_HLE_Device_usb_oh1_57e_305*
, m_Name("Nintendo RVL-CNT-01") , m_Name("Nintendo RVL-CNT-01")
, m_pHost(_pHost) , m_pHost(_pHost)
{ {
INFO_LOG(WII_IPC_WIIMOTE, "Wiimote: #%i Constructed", _Number); INFO_LOG(WII_IPC_WIIMOTE, "Wiimote: #%i Constructed", _Number);
@ -78,6 +80,10 @@ CWII_IPC_HLE_WiiMote::CWII_IPC_HLE_WiiMote(CWII_IPC_HLE_Device_usb_oh1_57e_305*
lmp_subversion = 0x229; lmp_subversion = 0x229;
} }
void CWII_IPC_HLE_WiiMote::DoState(PointerWrap &p)
{
p.Do(m_Connected);
}
// //
// //
@ -92,7 +98,7 @@ CWII_IPC_HLE_WiiMote::CWII_IPC_HLE_WiiMote(CWII_IPC_HLE_Device_usb_oh1_57e_305*
bool CWII_IPC_HLE_WiiMote::LinkChannel() bool CWII_IPC_HLE_WiiMote::LinkChannel()
{ {
if ((m_Connected <= 0) || (m_Linked == true)) if (m_Connected != 2)
return false; return false;
// try to connect HID_CONTROL_CHANNEL // try to connect HID_CONTROL_CHANNEL
@ -139,7 +145,7 @@ bool CWII_IPC_HLE_WiiMote::LinkChannel()
return true; return true;
} }
m_Linked = true; m_Connected = 3;
UpdateStatus(); UpdateStatus();
return false; return false;
@ -221,22 +227,29 @@ void CWII_IPC_HLE_WiiMote::UpdateStatus()
// //
void CWII_IPC_HLE_WiiMote::Activate(bool ready) void CWII_IPC_HLE_WiiMote::Activate(bool ready)
{ {
if (ready) if (ready && m_Connected == -1)
{
m_Connected = 0; m_Connected = 0;
else }
m_Connected = -1; else if (!ready)
{
m_pHost->RemoteDisconnect(m_ConnectionHandle);
EventDisconnect();
}
} }
void CWII_IPC_HLE_WiiMote::EventConnectionAccepted() void CWII_IPC_HLE_WiiMote::EventConnectionAccepted()
{ {
m_Connected = 1; m_Connected = 2;
m_Linked = false;
} }
void CWII_IPC_HLE_WiiMote::EventDisconnect() void CWII_IPC_HLE_WiiMote::EventDisconnect()
{ {
// Send disconnect message to plugin
u8 Message = WIIMOTE_DISCONNECT;
CPluginManager::GetInstance().GetWiimote(0)->Wiimote_ControlChannel(m_ConnectionHandle & 0xFF, 99, &Message, 0);
m_Connected = -1; m_Connected = -1;
m_Linked = false;
// Clear channel flags // Clear channel flags
ResetChannels(); ResetChannels();
} }
@ -249,7 +262,7 @@ bool CWII_IPC_HLE_WiiMote::EventPagingChanged(u8 _pageMode)
if ((_pageMode & 0x2) == 0) if ((_pageMode & 0x2) == 0)
return false; return false;
m_Connected = -1; m_Connected = 1;
return true; return true;
} }

View File

@ -18,11 +18,14 @@
#define _WII_IPC_HLE_WII_MOTE_ #define _WII_IPC_HLE_WII_MOTE_
#include <map> #include <map>
#include "hci.h"
#include <string> #include <string>
#include "hci.h"
#include "ChunkFile.h"
class CWII_IPC_HLE_Device_usb_oh1_57e_305; class CWII_IPC_HLE_Device_usb_oh1_57e_305;
CWII_IPC_HLE_Device_usb_oh1_57e_305* GetUsbPointer();
enum enum
{ {
SDP_CHANNEL = 0x01, SDP_CHANNEL = 0x01,
@ -188,15 +191,15 @@ public:
virtual ~CWII_IPC_HLE_WiiMote() virtual ~CWII_IPC_HLE_WiiMote()
{} {}
void DoState(PointerWrap &p);
// ugly Host handling.... // ugly Host handling....
// we really have to clean all this code // we really have to clean all this code
int IsConnected() const { return m_Connected; }
bool LinkChannel(); bool LinkChannel();
void ResetChannels(); void ResetChannels();
void Activate(bool ready); void Activate(bool ready);
bool IsConnected() const { return (m_Connected > 0) ? true : false; }
bool IsLinked() const { return m_Linked; }
void ShowStatus(const void* _pData); // Show status void ShowStatus(const void* _pData); // Show status
void UpdateStatus(); // Update status void UpdateStatus(); // Update status
void ExecuteL2capCmd(u8* _pData, u32 _Size); // From CPU void ExecuteL2capCmd(u8* _pData, u32 _Size); // From CPU
@ -218,9 +221,9 @@ public:
private: private:
// state machine // -1: inactive, 0: ready, 1: connecting 2: linking 3: connected & linked
int m_Connected; // 0: ready, -1: inactive/connecting, 1: connected int m_Connected;
bool m_Linked;
bool m_HIDControlChannel_Connected; bool m_HIDControlChannel_Connected;
bool m_HIDControlChannel_ConnectedWait; bool m_HIDControlChannel_ConnectedWait;
bool m_HIDControlChannel_Config; bool m_HIDControlChannel_Config;

View File

@ -157,12 +157,6 @@ int abc = 0;
else else
main_frame->bRenderToMain = true; main_frame->bRenderToMain = true;
return 0; return 0;
case WIIMOTE_RECONNECT:
// The Wiimote plugin has been shut down, now reconnect the Wiimote
//INFO_LOG(CONSOLE, "WIIMOTE_RECONNECT\n");
Core::ReconnectWiimote();
return 0;
} }
break; break;
} }
@ -233,6 +227,10 @@ EVT_MENU(IDM_MEMCARD, CFrame::OnMemcard)
EVT_MENU(IDM_CHEATS, CFrame::OnShow_CheatsWindow) EVT_MENU(IDM_CHEATS, CFrame::OnShow_CheatsWindow)
EVT_MENU(IDM_CHANGEDISC, CFrame::OnChangeDisc) EVT_MENU(IDM_CHANGEDISC, CFrame::OnChangeDisc)
EVT_MENU(IDM_LOAD_WII_MENU, CFrame::OnLoadWiiMenu) EVT_MENU(IDM_LOAD_WII_MENU, CFrame::OnLoadWiiMenu)
EVT_MENU(IDM_CONNECT_WIIMOTE1, CFrame::OnConnectWiimote)
EVT_MENU(IDM_CONNECT_WIIMOTE2, CFrame::OnConnectWiimote)
EVT_MENU(IDM_CONNECT_WIIMOTE3, CFrame::OnConnectWiimote)
EVT_MENU(IDM_CONNECT_WIIMOTE4, CFrame::OnConnectWiimote)
EVT_MENU(IDM_TOGGLE_FULLSCREEN, CFrame::OnToggleFullscreen) EVT_MENU(IDM_TOGGLE_FULLSCREEN, CFrame::OnToggleFullscreen)
EVT_MENU(IDM_TOGGLE_DUALCORE, CFrame::OnToggleDualCore) EVT_MENU(IDM_TOGGLE_DUALCORE, CFrame::OnToggleDualCore)
EVT_MENU(IDM_TOGGLE_SKIPIDLE, CFrame::OnToggleSkipIdle) EVT_MENU(IDM_TOGGLE_SKIPIDLE, CFrame::OnToggleSkipIdle)

View File

@ -311,6 +311,7 @@ class CFrame : public wxFrame
void OnShow_CheatsWindow(wxCommandEvent& event); void OnShow_CheatsWindow(wxCommandEvent& event);
void OnLoadWiiMenu(wxCommandEvent& event); void OnLoadWiiMenu(wxCommandEvent& event);
void OnConnectWiimote(wxCommandEvent& event);
void GameListChanged(wxCommandEvent& event); void GameListChanged(wxCommandEvent& event);
void OnGameListCtrl_ItemActivated(wxListEvent& event); void OnGameListCtrl_ItemActivated(wxListEvent& event);

View File

@ -62,6 +62,7 @@ Core::GetWindowHandle().
#include "OnFrame.h" #include "OnFrame.h"
#include "HW/DVDInterface.h" #include "HW/DVDInterface.h"
#include "HW/ProcessorInterface.h" #include "HW/ProcessorInterface.h"
#include "IPC_HLE/WII_IPC_HLE_Device_usb.h"
#include "State.h" #include "State.h"
#include "VolumeHandler.h" #include "VolumeHandler.h"
#include "NANDContentLoader.h" #include "NANDContentLoader.h"
@ -90,6 +91,7 @@ extern "C" {
#include "../resources/KDE.h" #include "../resources/KDE.h"
}; };
// Other Windows // Other Windows
wxCheatsWindow* CheatsWindow; wxCheatsWindow* CheatsWindow;
@ -194,6 +196,11 @@ void CFrame::CreateMenu()
{ {
toolsMenu->Append(IDM_LOAD_WII_MENU, _T("Load Wii Menu")); toolsMenu->Append(IDM_LOAD_WII_MENU, _T("Load Wii Menu"));
} }
toolsMenu->AppendSeparator();
toolsMenu->AppendCheckItem(IDM_CONNECT_WIIMOTE1, _T("Connect Wiimote 1"));
toolsMenu->AppendCheckItem(IDM_CONNECT_WIIMOTE2, _T("Connect Wiimote 2"));
toolsMenu->AppendCheckItem(IDM_CONNECT_WIIMOTE3, _T("Connect Wiimote 3"));
toolsMenu->AppendCheckItem(IDM_CONNECT_WIIMOTE4, _T("Connect Wiimote 4"));
m_MenuBar->Append(toolsMenu, _T("&Tools")); m_MenuBar->Append(toolsMenu, _T("&Tools"));
@ -780,6 +787,12 @@ void CFrame::OnLoadWiiMenu(wxCommandEvent& WXUNUSED (event))
BootManager::BootCore(FULL_WII_MENU_DIR); BootManager::BootCore(FULL_WII_MENU_DIR);
} }
void CFrame::OnConnectWiimote(wxCommandEvent& event)
{
int Id = event.GetId() - IDM_CONNECT_WIIMOTE1;
GetUsbPointer()->AccessWiiMote(Id | 0x100)->Activate(event.IsChecked());
}
// Toogle fullscreen. In Windows the fullscreen mode is accomplished by expanding the m_Panel to cover // Toogle fullscreen. In Windows the fullscreen mode is accomplished by expanding the m_Panel to cover
// the entire screen (when we render to the main window). // the entire screen (when we render to the main window).
void CFrame::OnToggleFullscreen(wxCommandEvent& WXUNUSED (event)) void CFrame::OnToggleFullscreen(wxCommandEvent& WXUNUSED (event))
@ -918,6 +931,18 @@ void CFrame::UpdateGUI()
if (DiscIO::CNANDContentManager::Access().GetNANDLoader(FULL_WII_MENU_DIR).IsValid()) if (DiscIO::CNANDContentManager::Access().GetNANDLoader(FULL_WII_MENU_DIR).IsValid())
GetMenuBar()->FindItem(IDM_LOAD_WII_MENU)->Enable(!Initialized); GetMenuBar()->FindItem(IDM_LOAD_WII_MENU)->Enable(!Initialized);
GetMenuBar()->FindItem(IDM_CONNECT_WIIMOTE1)->Enable(Paused && Core::GetStartupParameter().bWii);
GetMenuBar()->FindItem(IDM_CONNECT_WIIMOTE2)->Enable(Paused && Core::GetStartupParameter().bWii);
GetMenuBar()->FindItem(IDM_CONNECT_WIIMOTE3)->Enable(Paused && Core::GetStartupParameter().bWii);
GetMenuBar()->FindItem(IDM_CONNECT_WIIMOTE4)->Enable(Paused && Core::GetStartupParameter().bWii);
if (Initialized && Core::GetStartupParameter().bWii)
{
GetMenuBar()->FindItem(IDM_CONNECT_WIIMOTE1)->Check(GetUsbPointer()->AccessWiiMote(0x0100)->IsConnected() == 3);
GetMenuBar()->FindItem(IDM_CONNECT_WIIMOTE2)->Check(GetUsbPointer()->AccessWiiMote(0x0101)->IsConnected() == 3);
GetMenuBar()->FindItem(IDM_CONNECT_WIIMOTE3)->Check(GetUsbPointer()->AccessWiiMote(0x0102)->IsConnected() == 3);
GetMenuBar()->FindItem(IDM_CONNECT_WIIMOTE4)->Check(GetUsbPointer()->AccessWiiMote(0x0103)->IsConnected() == 3);
}
if (Running) if (Running)
{ {
if (m_ToolBar) if (m_ToolBar)

View File

@ -95,6 +95,10 @@ enum
IDM_PROPERTIES, IDM_PROPERTIES,
IDM_LOAD_WII_MENU, IDM_LOAD_WII_MENU,
IDM_LUA, IDM_LUA,
IDM_CONNECT_WIIMOTE1,
IDM_CONNECT_WIIMOTE2,
IDM_CONNECT_WIIMOTE3,
IDM_CONNECT_WIIMOTE4,
IDM_LISTWAD, IDM_LISTWAD,
IDM_LISTWII, IDM_LISTWII,

View File

@ -59,7 +59,6 @@
namespace InputCommon namespace InputCommon
{ {
// Settings // Settings
// ---------- // ----------
// Show a status window with the detected axes, buttons and so on // Show a status window with the detected axes, buttons and so on
@ -88,6 +87,7 @@ struct CONTROLLER_STATE // GC PAD INFO/STATE
struct CONTROLLER_MAPPING // GC PAD MAPPING struct CONTROLLER_MAPPING // GC PAD MAPPING
{ {
bool enable;
int buttons[8]; // (See above) int buttons[8]; // (See above)
int dpad; // (See above) int dpad; // (See above)
int dpad2[4]; // (See above) int dpad2[4]; // (See above)
@ -100,7 +100,6 @@ struct CONTROLLER_MAPPING // GC PAD MAPPING
std::string SRadius, SDiagonal, SRadiusC, SDiagonalC; std::string SRadius, SDiagonal, SRadiusC, SDiagonalC;
bool bRadiusOnOff, bSquareToCircle, bRadiusOnOffC, bSquareToCircleC; bool bRadiusOnOff, bSquareToCircle, bRadiusOnOffC, bSquareToCircleC;
bool rumble; bool rumble;
bool enable;
int eventnum; // Linux Event Number, Can't be found dynamically yet int eventnum; // Linux Event Number, Can't be found dynamically yet
}; };
@ -169,74 +168,6 @@ enum
XI_TRIGGER_R XI_TRIGGER_R
}; };
union PadAxis
{
int keyForControls[6];
struct
{
int Lx;
int Ly;
int Rx;
int Ry;
int Tl; // Trigger
int Tr; // Trigger
};
};
struct PadWiimote
{
int keyForControls[16];
// Order is A, B, 1, 2, +, -, Home
// L, R, U, D, RollL, RollR, PitchU, PitchD, Shake
};
struct PadNunchuck
{
int keyForControls[11];
// Order is Z, C, L, R, U, D, RollL, RollR, PitchU, PitchD, Shake
};
struct PadClassicController
{
int keyForControls[23];
// Order is A, B, X, Y, +, -, Home
// Tl, Zl, Zr, Tr, Dl, Dr, Du, Dd
// Ll, Lr, Lu, Ld, Rl, Rr, Ru, Rd
};
struct PadGH3Controller
{
int keyForControls[14];
// Order is Green, Red, Yellow, Blue, Orange,
// +, -, Whammy,
// Al, Ar, Au, Ad,
// StrumUp, StrumDown
};
struct CONTROLLER_STATE_NEW // GC PAD INFO/STATE
{
PadAxis Axis; // 6 Axes (Main, Sub, Triggers)
SDL_Joystick *joy; // SDL joystick device
};
struct CONTROLLER_MAPPING_NEW // GC PAD MAPPING
{
PadAxis Axis; // (See above)
PadWiimote Wm;
PadNunchuck Nc;
PadClassicController Cc;
PadGH3Controller GH3c;
bool enabled; // Pad attached?
bool Rumble;
int RumbleStrength;
int DeadZoneL; // Analog 1 Deadzone
int DeadZoneR; // Analog 2 Deadzone
int ID; // SDL joystick device ID
int controllertype; // D-Pad type: Hat or custom buttons
int triggertype; // SDL or XInput trigger
std::string SDiagonal;
bool bSquareToCircle;
bool bCircle2Square;
};
// Declarations // Declarations
// --------- // ---------

View File

@ -30,7 +30,7 @@ enum PLUGIN_COMM
TOGGLE_FULLSCREEN, TOGGLE_FULLSCREEN,
VIDEO_DESTROY, // The video debugging window was destroyed VIDEO_DESTROY, // The video debugging window was destroyed
AUDIO_DESTROY, // The audio debugging window was destroyed AUDIO_DESTROY, // The audio debugging window was destroyed
WIIMOTE_RECONNECT, // Reconnect the Wiimote if it has disconnected WIIMOTE_DISCONNECT, // Disconnect Wiimote
INPUT_FRAME_COUNTER // Wind back the frame counter for rerecording INPUT_FRAME_COUNTER // Wind back the frame counter for rerecording
}; };

View File

@ -30,7 +30,6 @@
// Do not change the order unless you change the related arrays // Do not change the order unless you change the related arrays
// Directionals are ordered as L, R, U, D // Directionals are ordered as L, R, U, D
// Wiimote
static const char* wmControlNames[] = static const char* wmControlNames[] =
{ {
"WmA", "WmA",
@ -49,51 +48,7 @@ static const char* wmControlNames[] =
"WmPitchU", "WmPitchU",
"WmPitchD", "WmPitchD",
"WmShake", "WmShake",
};
static int wmDefaultControls[] =
{
#ifdef _WIN32
'Z',
'X',
'C',
'V',
VK_OEM_PLUS,
VK_OEM_MINUS,
VK_BACK,
VK_LEFT,
VK_RIGHT,
VK_UP,
VK_DOWN,
'N',
'M',
VK_OEM_COMMA,
VK_OEM_PERIOD,
VK_OEM_2 // /
#elif defined(HAVE_X11) && HAVE_X11
'Z',
'X',
'C',
'V',
XK_equal,
XK_minus,
XK_BackSpace,
XK_Left,
XK_Right,
XK_Up,
XK_Down,
'N',
'M',
XK_comma,
XK_period,
XK_slash
#else
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
#endif
};
// Nunchuk
static const char* ncControlNames[] =
{
"NcZ", "NcZ",
"NcC", "NcC",
"NcL", "NcL",
@ -105,41 +60,7 @@ static const char* ncControlNames[] =
"NcPitchU", "NcPitchU",
"NcPitchD", "NcPitchD",
"NcShake", "NcShake",
};
static int nCDefaultControls[] =
{
#ifdef _WIN32
VK_NUMPAD0,
VK_DECIMAL,
VK_NUMPAD4,
VK_NUMPAD6,
VK_NUMPAD8,
VK_NUMPAD5,
VK_NUMPAD7,
VK_NUMPAD9,
VK_NUMPAD1,
VK_NUMPAD3,
VK_NUMPAD2
#elif defined(HAVE_X11) && HAVE_X11
XK_KP_0,
XK_KP_Decimal,
XK_KP_4,
XK_KP_6,
XK_KP_8,
XK_KP_5,
XK_KP_7,
XK_KP_9,
XK_KP_1,
XK_KP_3,
XK_KP_2
#else
0,0,0,0,0,0,0,0,0,0,0
#endif
};
// Classic Controller
static const char* ccControlNames[] =
{
"CcA", "CcA",
"CcB", "CcB",
"CcX", "CcX",
@ -163,9 +84,94 @@ static const char* ccControlNames[] =
"CcRr", "CcRr",
"CcRu", "CcRu",
"CcRd", "CcRd",
"GH3Green",
"GH3Red",
"GH3Yellow",
"GH3Blue",
"GH3Orange",
"GH3Plus",
"GH3Minus",
"GH3Whammy",
"GH3Al",
"GH3Ar",
"GH3Au",
"GH3Ad",
"GH3StrumUp",
"GH3StrumDown",
}; };
static int ccDefaultControls[] =
static int wmDefaultControls[] =
{ {
// Wiimote
#ifdef _WIN32
'Z',
'X',
'C',
'V',
VK_OEM_PLUS,
VK_OEM_MINUS,
VK_BACK,
VK_LEFT,
VK_RIGHT,
VK_UP,
VK_DOWN,
'N',
'M',
VK_OEM_COMMA,
VK_OEM_PERIOD,
VK_OEM_2, // /
#elif defined(HAVE_X11) && HAVE_X11
'Z',
'X',
'C',
'V',
XK_equal,
XK_minus,
XK_BackSpace,
XK_Left,
XK_Right,
XK_Up,
XK_Down,
'N',
'M',
XK_comma,
XK_period,
XK_slash,
#else
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
#endif
// Nunchuck
#ifdef _WIN32
VK_NUMPAD0,
VK_DECIMAL,
VK_NUMPAD4,
VK_NUMPAD6,
VK_NUMPAD8,
VK_NUMPAD5,
VK_NUMPAD7,
VK_NUMPAD9,
VK_NUMPAD1,
VK_NUMPAD3,
VK_NUMPAD2,
#elif defined(HAVE_X11) && HAVE_X11
XK_KP_0,
XK_KP_Decimal,
XK_KP_4,
XK_KP_6,
XK_KP_8,
XK_KP_5,
XK_KP_7,
XK_KP_9,
XK_KP_1,
XK_KP_3,
XK_KP_2,
#else
0,0,0,0,0,0,0,0,0,0,0,
#endif
// Classic Controller
// A, B, X, Y // A, B, X, Y
#ifdef _WIN32 #ifdef _WIN32
VK_OEM_4, // [ VK_OEM_4, // [
@ -212,29 +218,9 @@ static int ccDefaultControls[] =
'J', 'J',
'L', 'L',
'I', 'I',
'K' 'K',
};
// GH3 Default controls // Guttar Hero
static const char* gh3ControlNames[] =
{
"GH3Green",
"GH3Red",
"GH3Yellow",
"GH3Blue",
"GH3Orange",
"GH3Plus",
"GH3Minus",
"GH3Whammy",
"GH3Al",
"GH3Ar",
"GH3Au",
"GH3Ad",
"GH3StrumUp",
"GH3StrumDown",
};
static int GH3DefaultControls[] =
{
'A', 'A',
'S', 'S',
'D', 'D',
@ -269,22 +255,14 @@ Config::Config()
memset(this, 0, sizeof(Config)); memset(this, 0, sizeof(Config));
} }
void Config::Load(bool ChangePad) void Config::Load()
{ {
std::string temp; std::string temp;
IniFile iniFile; IniFile iniFile;
iniFile.Load(FULL_CONFIG_DIR "Wiimote.ini"); iniFile.Load(FULL_CONFIG_DIR "Wiimote.ini");
// General
iniFile.Get("Settings", "InputActive", &bInputActive, true);
iniFile.Get("Settings", "Sideways", &bSideways, false);
iniFile.Get("Settings", "Upright", &bUpright, false);
iniFile.Get("Settings", "ExtensionConnected", &iExtensionConnected, EXT_NONE);
iniFile.Get("Settings", "MotionPlusConnected", &bMotionPlusConnected, false);
// Real Wiimote // Real Wiimote
iniFile.Get("Real", "Connect", &bConnectRealWiimote, true); iniFile.Get("Real", "Connect", &bConnectRealWiimote, true);
iniFile.Get("Real", "Use", &bUseRealWiimote, false);
iniFile.Get("Real", "UpdateStatus", &bUpdateRealWiimote, true); iniFile.Get("Real", "UpdateStatus", &bUpdateRealWiimote, true);
iniFile.Get("Real", "AccNeutralX", &iAccNeutralX, 0); iniFile.Get("Real", "AccNeutralX", &iAccNeutralX, 0);
iniFile.Get("Real", "AccNeutralY", &iAccNeutralY, 0); iniFile.Get("Real", "AccNeutralY", &iAccNeutralY, 0);
@ -298,72 +276,55 @@ void Config::Load(bool ChangePad)
// Slot specific settings // Slot specific settings
char SectionName[32]; char SectionName[32];
sprintf(SectionName, "Wiimote%i", i + 1); sprintf(SectionName, "Wiimote%i", i + 1);
iniFile.Get(SectionName, "NoTriggerFilter", &bNoTriggerFilter, false);
iniFile.Get(SectionName, "TiltTypeWM", &Tilt.TypeWM, Tilt.KEYBOARD); // General
iniFile.Get(SectionName, "TiltTypeNC", &Tilt.TypeNC, Tilt.KEYBOARD); iniFile.Get(SectionName, "Source", &WiiMoteEmu::WiiMapping[i].Source, (i) ? 0 : 1);
iniFile.Get(SectionName, "TiltRollSwing", &Tilt.Range.RollSwing, false); iniFile.Get(SectionName, "Sideways", &WiiMoteEmu::WiiMapping[i].bSideways, false);
iniFile.Get(SectionName, "TiltRollDegree", &Tilt.Range.RollDegree, 60); iniFile.Get(SectionName, "Upright", &WiiMoteEmu::WiiMapping[i].bUpright, false);
Tilt.Range.Roll = (Tilt.Range.RollSwing) ? 0 : Tilt.Range.RollDegree; iniFile.Get(SectionName, "ExtensionConnected", &WiiMoteEmu::WiiMapping[i].iExtensionConnected, WiiMoteEmu::EXT_NONE);
iniFile.Get(SectionName, "TiltRollInvert", &Tilt.RollInvert, false); iniFile.Get(SectionName, "MotionPlusConnected", &WiiMoteEmu::WiiMapping[i].bMotionPlusConnected, false);
iniFile.Get(SectionName, "TiltPitchSwing", &Tilt.Range.PitchSwing, false);
iniFile.Get(SectionName, "TiltPitchDegree", &Tilt.Range.PitchDegree, 60);
Tilt.Range.Pitch = (Tilt.Range.PitchSwing) ? 0 : Tilt.Range.PitchDegree;
iniFile.Get(SectionName, "TiltPitchInvert", &Tilt.PitchInvert, false);
// Wiimote iniFile.Get(SectionName, "TiltInputWM", &WiiMoteEmu::WiiMapping[i].Tilt.InputWM, WiiMoteEmu::FROM_KEYBOARD);
for (int x = 0; x < WM_CONTROLS; x++) iniFile.Get(SectionName, "TiltInputNC", &WiiMoteEmu::WiiMapping[i].Tilt.InputNC, WiiMoteEmu::FROM_KEYBOARD);
iniFile.Get(SectionName, wmControlNames[x], &WiiMoteEmu::PadMapping[i].Wm.keyForControls[x], wmDefaultControls[x]); iniFile.Get(SectionName, "TiltRollDegree", &WiiMoteEmu::WiiMapping[i].Tilt.RollDegree, 60);
// Nunchuck iniFile.Get(SectionName, "TiltRollSwing", &WiiMoteEmu::WiiMapping[i].Tilt.RollSwing, false);
iniFile.Get(SectionName, "NunchuckStick", &Nunchuck.Type, Nunchuck.KEYBOARD); iniFile.Get(SectionName, "TiltRollInvert", &WiiMoteEmu::WiiMapping[i].Tilt.RollInvert, false);
for (int x = 0; x < NC_CONTROLS; x++) WiiMoteEmu::WiiMapping[i].Tilt.RollRange = (WiiMoteEmu::WiiMapping[i].Tilt.RollSwing) ? 0 : WiiMoteEmu::WiiMapping[i].Tilt.RollDegree;
iniFile.Get(SectionName, ncControlNames[x], &WiiMoteEmu::PadMapping[i].Nc.keyForControls[x], nCDefaultControls[x]); iniFile.Get(SectionName, "TiltPitchDegree", &WiiMoteEmu::WiiMapping[i].Tilt.PitchDegree, 60);
iniFile.Get(SectionName, "TiltPitchSwing", &WiiMoteEmu::WiiMapping[i].Tilt.PitchSwing, false);
iniFile.Get(SectionName, "TiltPitchInvert", &WiiMoteEmu::WiiMapping[i].Tilt.PitchInvert, false);
WiiMoteEmu::WiiMapping[i].Tilt.PitchRange = (WiiMoteEmu::WiiMapping[i].Tilt.PitchSwing) ? 0 : WiiMoteEmu::WiiMapping[i].Tilt.PitchDegree;
// Classic Controller // StickMapping
iniFile.Get(SectionName, "CcLeftStick", &ClassicController.LType, ClassicController.KEYBOARD); iniFile.Get(SectionName, "NCStick", &WiiMoteEmu::WiiMapping[i].Stick.NC, WiiMoteEmu::FROM_KEYBOARD);
iniFile.Get(SectionName, "CcRightStick", &ClassicController.RType, ClassicController.KEYBOARD); iniFile.Get(SectionName, "CCStickLeft", &WiiMoteEmu::WiiMapping[i].Stick.CCL, WiiMoteEmu::FROM_KEYBOARD);
iniFile.Get(SectionName, "CcTriggers", &ClassicController.TType, ClassicController.KEYBOARD); iniFile.Get(SectionName, "CCStickRight", &WiiMoteEmu::WiiMapping[i].Stick.CCR, WiiMoteEmu::FROM_KEYBOARD);
for (int x = 0; x < CC_CONTROLS; x++) iniFile.Get(SectionName, "CCTriggers", &WiiMoteEmu::WiiMapping[i].Stick.CCT, WiiMoteEmu::FROM_KEYBOARD);
iniFile.Get(SectionName, ccControlNames[x], &WiiMoteEmu::PadMapping[i].Cc.keyForControls[x], ccDefaultControls[x]); iniFile.Get(SectionName, "GHStick", &WiiMoteEmu::WiiMapping[i].Stick.GH, WiiMoteEmu::FROM_KEYBOARD);
iniFile.Get(SectionName, "GH3Analog", &GH3Controller.AType, GH3Controller.ANALOG1); // ButtonMapping
for (int x = 0; x < GH3_CONTROLS; x++) for (int x = 0; x < WiiMoteEmu::LAST_CONSTANT; x++)
iniFile.Get(SectionName, gh3ControlNames[x], &WiiMoteEmu::PadMapping[i].GH3c.keyForControls[x], GH3DefaultControls[x]); iniFile.Get(SectionName, wmControlNames[x], &WiiMoteEmu::WiiMapping[i].Button[x], wmDefaultControls[x]);
// Don't update this when we are loading settings from the ConfigBox // This pad Id could possibly be higher than the number of pads that are connected,
if(!ChangePad) // but we check later, when needed, that that is not the case
{ iniFile.Get(SectionName, "DeviceID", &WiiMoteEmu::WiiMapping[i].ID, 0);
// This pad Id could possibly be higher than the number of pads that are connected,
// but we check later, when needed, that that is not the case
iniFile.Get(SectionName, "DeviceID", &WiiMoteEmu::PadMapping[i].ID, 0);
iniFile.Get(SectionName, "Enabled", &WiiMoteEmu::PadMapping[i].enabled, true);
}
// Joypad specific settings iniFile.Get(SectionName, "Axis_Lx", &WiiMoteEmu::WiiMapping[i].AxisMapping.Lx, 0);
// Current joypad device ID: PadMapping[i].ID iniFile.Get(SectionName, "Axis_Ly", &WiiMoteEmu::WiiMapping[i].AxisMapping.Ly, 1);
// Current joypad name: joyinfo[PadMapping[i].ID].Name iniFile.Get(SectionName, "Axis_Rx", &WiiMoteEmu::WiiMapping[i].AxisMapping.Rx, 2);
iniFile.Get(SectionName, "Axis_Ry", &WiiMoteEmu::WiiMapping[i].AxisMapping.Ry, 3);
// Prevent a crash from illegal access to joyinfo that will only have values for iniFile.Get(SectionName, "Trigger_L", &WiiMoteEmu::WiiMapping[i].AxisMapping.Tl, 1004);
// the current amount of connected PadMapping iniFile.Get(SectionName, "Trigger_R", &WiiMoteEmu::WiiMapping[i].AxisMapping.Tr, 1005);
if((u32)WiiMoteEmu::PadMapping[i].ID >= WiiMoteEmu::joyinfo.size()) continue; iniFile.Get(SectionName, "DeadZoneL", &WiiMoteEmu::WiiMapping[i].DeadZoneL, 0);
iniFile.Get(SectionName, "DeadZoneR", &WiiMoteEmu::WiiMapping[i].DeadZoneR, 0);
// Create a section name iniFile.Get(SectionName, "Diagonal", &WiiMoteEmu::WiiMapping[i].Diagonal, "100%");
std::string joySectionName = WiiMoteEmu::joyinfo[WiiMoteEmu::PadMapping[i].ID].Name; iniFile.Get(SectionName, "Circle2Square", &WiiMoteEmu::WiiMapping[i].bCircle2Square, false);
iniFile.Get(SectionName, "Rumble", &WiiMoteEmu::WiiMapping[i].Rumble, true);
iniFile.Get(joySectionName.c_str(), "left_x", &WiiMoteEmu::PadMapping[i].Axis.Lx, 0); iniFile.Get(SectionName, "RumbleStrength", &WiiMoteEmu::WiiMapping[i].RumbleStrength, 8); // x10
iniFile.Get(joySectionName.c_str(), "left_y", &WiiMoteEmu::PadMapping[i].Axis.Ly, 1); iniFile.Get(SectionName, "TriggerType", &WiiMoteEmu::WiiMapping[i].TriggerType, 0);
iniFile.Get(joySectionName.c_str(), "right_x", &WiiMoteEmu::PadMapping[i].Axis.Rx, 2);
iniFile.Get(joySectionName.c_str(), "right_y", &WiiMoteEmu::PadMapping[i].Axis.Ry, 3);
iniFile.Get(joySectionName.c_str(), "l_trigger", &WiiMoteEmu::PadMapping[i].Axis.Tl, 1004);
iniFile.Get(joySectionName.c_str(), "r_trigger", &WiiMoteEmu::PadMapping[i].Axis.Tr, 1005);
iniFile.Get(joySectionName.c_str(), "DeadZoneL", &WiiMoteEmu::PadMapping[i].DeadZoneL, 0);
iniFile.Get(joySectionName.c_str(), "DeadZoneR", &WiiMoteEmu::PadMapping[i].DeadZoneR, 0);
iniFile.Get(joySectionName.c_str(), "Diagonal", &WiiMoteEmu::PadMapping[i].SDiagonal, "100%");
iniFile.Get(joySectionName.c_str(), "Circle2Square", &WiiMoteEmu::PadMapping[i].bCircle2Square, false);
iniFile.Get(joySectionName.c_str(), "Rumble", &WiiMoteEmu::PadMapping[i].Rumble, true);
iniFile.Get(joySectionName.c_str(), "RumbleStrength", &WiiMoteEmu::PadMapping[i].RumbleStrength, 9); // x10
iniFile.Get(joySectionName.c_str(), "TriggerType", &WiiMoteEmu::PadMapping[i].triggertype, 0);
} }
// Load the IR cursor settings if it's avaliable for the GameId, if not load the default settings // Load the IR cursor settings if it's avaliable for the GameId, if not load the default settings
iniFile.Load(FULL_CONFIG_DIR "IR Pointer.ini"); iniFile.Load(FULL_CONFIG_DIR "IR Pointer.ini");
char TmpSection[32]; char TmpSection[32];
@ -375,7 +336,6 @@ void Config::Load(bool ChangePad)
// Load a few screen settings to. If these are added to the DirectX plugin it's probably // Load a few screen settings to. If these are added to the DirectX plugin it's probably
// better to place them in the main Dolphin.ini file // better to place them in the main Dolphin.ini file
iniFile.Load(FULL_CONFIG_DIR "gfx_opengl.ini"); iniFile.Load(FULL_CONFIG_DIR "gfx_opengl.ini");
iniFile.Get("Settings", "KeepAR_4_3", &bKeepAR43, false); iniFile.Get("Settings", "KeepAR_4_3", &bKeepAR43, false);
iniFile.Get("Settings", "KeepAR_16_9", &bKeepAR169, false); iniFile.Get("Settings", "KeepAR_16_9", &bKeepAR169, false);
@ -384,18 +344,12 @@ void Config::Load(bool ChangePad)
//DEBUG_LOG(WIIMOTE, "Load()"); //DEBUG_LOG(WIIMOTE, "Load()");
} }
void Config::Save(int Slot) void Config::Save()
{ {
IniFile iniFile; IniFile iniFile;
iniFile.Load(FULL_CONFIG_DIR "Wiimote.ini"); iniFile.Load(FULL_CONFIG_DIR "Wiimote.ini");
iniFile.Set("Settings", "InputActive", bInputActive);
iniFile.Set("Settings", "Sideways", bSideways);
iniFile.Set("Settings", "Upright", bUpright);
iniFile.Set("Settings", "MotionPlusConnected", bMotionPlusConnected);
iniFile.Set("Settings", "ExtensionConnected", iExtensionConnected);
iniFile.Set("Real", "Connect", bConnectRealWiimote); iniFile.Set("Real", "Connect", bConnectRealWiimote);
iniFile.Set("Real", "Use", bUseRealWiimote);
iniFile.Set("Real", "UpdateStatus", bUpdateRealWiimote); iniFile.Set("Real", "UpdateStatus", bUpdateRealWiimote);
iniFile.Set("Real", "AccNeutralX", iAccNeutralX); iniFile.Set("Real", "AccNeutralX", iAccNeutralX);
iniFile.Set("Real", "AccNeutralY", iAccNeutralY); iniFile.Set("Real", "AccNeutralY", iAccNeutralY);
@ -410,64 +364,48 @@ void Config::Save(int Slot)
char SectionName[32]; char SectionName[32];
sprintf(SectionName, "Wiimote%i", i + 1); sprintf(SectionName, "Wiimote%i", i + 1);
iniFile.Set(SectionName, "NoTriggerFilter", bNoTriggerFilter); iniFile.Set(SectionName, "Source", WiiMoteEmu::WiiMapping[i].Source);
iniFile.Set(SectionName, "TiltTypeWM", Tilt.TypeWM); iniFile.Set(SectionName, "Sideways", WiiMoteEmu::WiiMapping[i].bSideways);
iniFile.Set(SectionName, "TiltTypeNC", Tilt.TypeNC); iniFile.Set(SectionName, "Upright", WiiMoteEmu::WiiMapping[i].bUpright);
iniFile.Set(SectionName, "TiltRollDegree", Tilt.Range.RollDegree); iniFile.Set(SectionName, "ExtensionConnected", WiiMoteEmu::WiiMapping[i].iExtensionConnected);
iniFile.Set(SectionName, "TiltRollSwing", Tilt.Range.RollSwing); iniFile.Set(SectionName, "MotionPlusConnected", WiiMoteEmu::WiiMapping[i].bMotionPlusConnected);
iniFile.Set(SectionName, "TiltRollInvert", Tilt.RollInvert);
iniFile.Set(SectionName, "TiltPitchDegree", Tilt.Range.PitchDegree);
iniFile.Set(SectionName, "TiltPitchSwing", Tilt.Range.PitchSwing);
iniFile.Set(SectionName, "TiltPitchInvert", Tilt.PitchInvert);
// Wiimote
for (int x = 0; x < WM_CONTROLS; x++)
iniFile.Set(SectionName, wmControlNames[x], WiiMoteEmu::PadMapping[i].Wm.keyForControls[x]);
// Nunchuck iniFile.Set(SectionName, "TiltInputWM", WiiMoteEmu::WiiMapping[i].Tilt.InputWM);
iniFile.Set(SectionName, "NunchuckStick", Nunchuck.Type); iniFile.Set(SectionName, "TiltInputNC", WiiMoteEmu::WiiMapping[i].Tilt.InputNC);
for (int x = 0; x < NC_CONTROLS; x++) iniFile.Set(SectionName, "TiltRollDegree", WiiMoteEmu::WiiMapping[i].Tilt.RollDegree);
iniFile.Set(SectionName, ncControlNames[x], WiiMoteEmu::PadMapping[i].Nc.keyForControls[x]); iniFile.Set(SectionName, "TiltRollSwing", WiiMoteEmu::WiiMapping[i].Tilt.RollSwing);
iniFile.Set(SectionName, "TiltRollInvert", WiiMoteEmu::WiiMapping[i].Tilt.RollInvert);
iniFile.Set(SectionName, "TiltPitchDegree", WiiMoteEmu::WiiMapping[i].Tilt.PitchDegree);
iniFile.Set(SectionName, "TiltPitchSwing", WiiMoteEmu::WiiMapping[i].Tilt.PitchSwing);
iniFile.Set(SectionName, "TiltPitchInvert", WiiMoteEmu::WiiMapping[i].Tilt.PitchInvert);
// Classic Controller // StickMapping
iniFile.Set(SectionName, "CcLeftStick", ClassicController.LType); iniFile.Set(SectionName, "NCStick", WiiMoteEmu::WiiMapping[i].Stick.NC);
iniFile.Set(SectionName, "CcRightStick", ClassicController.RType); iniFile.Set(SectionName, "CCStickLeft", WiiMoteEmu::WiiMapping[i].Stick.CCL);
iniFile.Set(SectionName, "CcTriggers", ClassicController.TType); iniFile.Set(SectionName, "CCStickRight", WiiMoteEmu::WiiMapping[i].Stick.CCR);
for (int x = 0; x < CC_CONTROLS; x++) iniFile.Set(SectionName, "CCTriggers", WiiMoteEmu::WiiMapping[i].Stick.CCT);
iniFile.Set(SectionName, ccControlNames[x], WiiMoteEmu::PadMapping[i].Cc.keyForControls[x]); iniFile.Set(SectionName, "GHStick", WiiMoteEmu::WiiMapping[i].Stick.GH);
// GH3 // ButtonMapping
iniFile.Set(SectionName, "GH3Analog", GH3Controller.AType); for (int x = 0; x < WiiMoteEmu::LAST_CONSTANT; x++)
for (int x = 0; x < GH3_CONTROLS; x++) iniFile.Set(SectionName, wmControlNames[x], WiiMoteEmu::WiiMapping[i].Button[x]);
iniFile.Set(SectionName, gh3ControlNames[x], WiiMoteEmu::PadMapping[i].GH3c.keyForControls[x]);
// Save the physical device ID number // Save the physical device ID number
iniFile.Set(SectionName, "Enabled", WiiMoteEmu::PadMapping[i].enabled); iniFile.Set(SectionName, "DeviceID", WiiMoteEmu::WiiMapping[i].ID);
iniFile.Set(SectionName, "DeviceID", WiiMoteEmu::PadMapping[i].ID);
// Joypad specific settings iniFile.Set(SectionName, "Axis_Lx", WiiMoteEmu::WiiMapping[i].AxisMapping.Lx);
// Current joypad device ID: PadMapping[i].ID iniFile.Set(SectionName, "Axis_Ly", WiiMoteEmu::WiiMapping[i].AxisMapping.Ly);
// Current joypad name: joyinfo[PadMapping[i].ID].Name iniFile.Set(SectionName, "Axis_Rx", WiiMoteEmu::WiiMapping[i].AxisMapping.Rx);
iniFile.Set(SectionName, "Axis_Ry", WiiMoteEmu::WiiMapping[i].AxisMapping.Ry);
// Save joypad specific settings. Check for "PadMapping[i].ID < SDL_NumJoysticks()" to iniFile.Set(SectionName, "Trigger_L", WiiMoteEmu::WiiMapping[i].AxisMapping.Tl);
// avoid reading a joyinfo that does't exist iniFile.Set(SectionName, "Trigger_R", WiiMoteEmu::WiiMapping[i].AxisMapping.Tr);
if((u32)WiiMoteEmu::PadMapping[i].ID >= WiiMoteEmu::joyinfo.size()) continue; iniFile.Set(SectionName, "DeadZoneL", WiiMoteEmu::WiiMapping[i].DeadZoneL);
iniFile.Set(SectionName, "DeadZoneR", WiiMoteEmu::WiiMapping[i].DeadZoneR);
// Create a new section name after the joypad name iniFile.Set(SectionName, "Diagonal", WiiMoteEmu::WiiMapping[i].Diagonal);
std::string joySectionName = WiiMoteEmu::joyinfo[WiiMoteEmu::PadMapping[i].ID].Name; iniFile.Set(SectionName, "Circle2Square", WiiMoteEmu::WiiMapping[i].bCircle2Square);
iniFile.Set(SectionName, "Rumble", WiiMoteEmu::WiiMapping[i].Rumble);
iniFile.Set(joySectionName.c_str(), "left_x", WiiMoteEmu::PadMapping[i].Axis.Lx); iniFile.Set(SectionName, "RumbleStrength", WiiMoteEmu::WiiMapping[i].RumbleStrength); // x10
iniFile.Set(joySectionName.c_str(), "left_y", WiiMoteEmu::PadMapping[i].Axis.Ly); iniFile.Set(SectionName, "TriggerType", WiiMoteEmu::WiiMapping[i].TriggerType);
iniFile.Set(joySectionName.c_str(), "right_x", WiiMoteEmu::PadMapping[i].Axis.Rx);
iniFile.Set(joySectionName.c_str(), "right_y", WiiMoteEmu::PadMapping[i].Axis.Ry);
iniFile.Set(joySectionName.c_str(), "l_trigger", WiiMoteEmu::PadMapping[i].Axis.Tl);
iniFile.Set(joySectionName.c_str(), "r_trigger", WiiMoteEmu::PadMapping[i].Axis.Tr);
iniFile.Set(joySectionName.c_str(), "DeadZoneL", WiiMoteEmu::PadMapping[i].DeadZoneL);
iniFile.Set(joySectionName.c_str(), "DeadZoneR", WiiMoteEmu::PadMapping[i].DeadZoneR);
iniFile.Set(joySectionName.c_str(), "Diagonal", WiiMoteEmu::PadMapping[i].SDiagonal);
iniFile.Set(joySectionName.c_str(), "Circle2Square", WiiMoteEmu::PadMapping[i].bCircle2Square);
iniFile.Set(joySectionName.c_str(), "Rumble", WiiMoteEmu::PadMapping[i].Rumble);
iniFile.Set(joySectionName.c_str(), "RumbleStrength", WiiMoteEmu::PadMapping[i].RumbleStrength);
iniFile.Set(joySectionName.c_str(), "TriggerType", WiiMoteEmu::PadMapping[i].triggertype);
} }
iniFile.Save(FULL_CONFIG_DIR "Wiimote.ini"); iniFile.Save(FULL_CONFIG_DIR "Wiimote.ini");

View File

@ -22,94 +22,14 @@
#include <X11/keysym.h> #include <X11/keysym.h>
#endif #endif
#define AN_CONTROLS 6
#define WM_CONTROLS 16
#define NC_CONTROLS 11
#define CC_CONTROLS 23
#define GH3_CONTROLS 14
enum
{
EXT_NONE = 0,
EXT_NUNCHUCK,
EXT_CLASSIC_CONTROLLER,
EXT_GUITARHERO3_CONTROLLER,
};
struct Config struct Config
{ {
Config(); Config();
void Load(bool ChangePad = false); void Load();
void Save(int Slot = -1); void Save();
struct TiltRange // For dialog sync
{ int CurrentPage;
int RollDegree;
bool RollSwing;
int Roll;
int PitchDegree;
bool PitchSwing;
int Pitch;
};
struct PadTilt
{
enum ETiltType
{
OFF = 0,
KEYBOARD,
ANALOG1,
ANALOG2,
TRIGGER
};
int TypeWM;
int TypeNC;
bool RollInvert;
bool PitchInvert;
TiltRange Range;
};
struct PadNunchuck
{
enum ENunchuckStick
{
KEYBOARD,
ANALOG1,
ANALOG2
};
int Type;
};
struct PadClassicController
{
enum ECcStick
{
KEYBOARD,
ANALOG1,
ANALOG2,
TRIGGER
};
int LType;
int RType;
int TType;
};
struct PadGH3
{
enum EGH3Stick
{
// KEYBOARD,
ANALOG1,
ANALOG2
};
int AType; // Analog Stick
int TType; // Whammy bar
};
// Emulated Wiimote
bool bInputActive;
bool bSideways;
bool bUpright;
bool bWideScreen;
bool bMotionPlusConnected;
int iExtensionConnected;
// Real Wiimote // Real Wiimote
bool bConnectRealWiimote, bUseRealWiimote, bUpdateRealWiimote; bool bConnectRealWiimote, bUseRealWiimote, bUpdateRealWiimote;
@ -117,12 +37,6 @@ struct Config
int iAccNeutralX, iAccNeutralY, iAccNeutralZ; int iAccNeutralX, iAccNeutralY, iAccNeutralZ;
int iAccNunNeutralX, iAccNunNeutralY, iAccNunNeutralZ; int iAccNunNeutralX, iAccNunNeutralY, iAccNunNeutralZ;
// Gamepad
bool bNoTriggerFilter;
PadTilt Tilt;
PadNunchuck Nunchuck;
PadClassicController ClassicController;
PadGH3 GH3Controller;
// Screen size settings // Screen size settings
bool bKeepAR43, bKeepAR169, bCrop; bool bKeepAR43, bKeepAR169, bCrop;
}; };

View File

@ -31,9 +31,9 @@ BEGIN_EVENT_TABLE(WiimoteBasicConfigDialog,wxDialog)
EVT_BUTTON(ID_CANCEL, WiimoteBasicConfigDialog::ButtonClick) EVT_BUTTON(ID_CANCEL, WiimoteBasicConfigDialog::ButtonClick)
EVT_BUTTON(ID_BUTTONMAPPING, WiimoteBasicConfigDialog::ButtonClick) EVT_BUTTON(ID_BUTTONMAPPING, WiimoteBasicConfigDialog::ButtonClick)
EVT_BUTTON(ID_BUTTONRECORDING, WiimoteBasicConfigDialog::ButtonClick) EVT_BUTTON(ID_BUTTONRECORDING, WiimoteBasicConfigDialog::ButtonClick)
EVT_CHECKBOX(IDC_INPUT_ACTIVE, WiimoteBasicConfigDialog::GeneralSettingsChanged) EVT_NOTEBOOK_PAGE_CHANGED(ID_NOTEBOOK, WiimoteBasicConfigDialog::NotebookPageChanged)
EVT_CHOICE(IDC_INPUT_SOURCE, WiimoteBasicConfigDialog::GeneralSettingsChanged)
EVT_CHECKBOX(IDC_CONNECT_REAL, WiimoteBasicConfigDialog::GeneralSettingsChanged) EVT_CHECKBOX(IDC_CONNECT_REAL, WiimoteBasicConfigDialog::GeneralSettingsChanged)
EVT_CHECKBOX(IDC_USE_REAL, WiimoteBasicConfigDialog::GeneralSettingsChanged)
EVT_CHECKBOX(IDC_SIDEWAYSWIIMOTE, WiimoteBasicConfigDialog::GeneralSettingsChanged) EVT_CHECKBOX(IDC_SIDEWAYSWIIMOTE, WiimoteBasicConfigDialog::GeneralSettingsChanged)
EVT_CHECKBOX(IDC_UPRIGHTWIIMOTE, WiimoteBasicConfigDialog::GeneralSettingsChanged) EVT_CHECKBOX(IDC_UPRIGHTWIIMOTE, WiimoteBasicConfigDialog::GeneralSettingsChanged)
EVT_CHECKBOX(IDC_MOTIONPLUSCONNECTED, WiimoteBasicConfigDialog::GeneralSettingsChanged) EVT_CHECKBOX(IDC_MOTIONPLUSCONNECTED, WiimoteBasicConfigDialog::GeneralSettingsChanged)
@ -59,9 +59,10 @@ WiimoteBasicConfigDialog::WiimoteBasicConfigDialog(wxWindow *parent, wxWindowID
#endif #endif
ControlsCreated = false; ControlsCreated = false;
m_Page = 0;
m_bEnableUseRealWiimote = true; m_bEnableUseRealWiimote = true;
Page = 0;
//g_Config.Load();
CreateGUIControls(); CreateGUIControls();
UpdateGUI(); UpdateGUI();
} }
@ -112,10 +113,14 @@ void WiimoteBasicConfigDialog::ButtonClick(wxCommandEvent& event)
Close(); Close();
break; break;
case ID_BUTTONMAPPING: case ID_BUTTONMAPPING:
g_Config.CurrentPage = m_Page;
m_PadConfigFrame = new WiimotePadConfigDialog(this); m_PadConfigFrame = new WiimotePadConfigDialog(this);
m_PadConfigFrame->ShowModal(); m_PadConfigFrame->ShowModal();
m_PadConfigFrame->Destroy(); m_PadConfigFrame->Destroy();
m_PadConfigFrame = NULL; m_PadConfigFrame = NULL;
m_Page = g_Config.CurrentPage;
m_Notebook->ChangeSelection(g_Config.CurrentPage);
UpdateGUI();
break; break;
case ID_BUTTONRECORDING: case ID_BUTTONRECORDING:
m_RecordingConfigFrame = new WiimoteRecordingConfigDialog(this); m_RecordingConfigFrame = new WiimoteRecordingConfigDialog(this);
@ -126,22 +131,19 @@ void WiimoteBasicConfigDialog::ButtonClick(wxCommandEvent& event)
} }
} }
// Execute a delayed function
void WiimoteBasicConfigDialog::UpdateOnce(wxTimerEvent& event)
{
switch(event.GetId())
{
case IDTM_UPDATE_ONCE:
// Reenable the checkbox
m_bEnableUseRealWiimote = true;
SetCursor(wxCursor(wxCURSOR_ARROW));
UpdateGUI();
break;
}
}
void WiimoteBasicConfigDialog::CreateGUIControls() void WiimoteBasicConfigDialog::CreateGUIControls()
{ {
wxArrayString arrayStringFor_source;
arrayStringFor_source.Add(wxT("Inactive"));
arrayStringFor_source.Add(wxT("Emulated Wiimote"));
arrayStringFor_source.Add(wxT("Real Wiimote"));
wxArrayString arrayStringFor_extension;
arrayStringFor_extension.Add(wxT("None"));
arrayStringFor_extension.Add(wxT("Nunchuck"));
arrayStringFor_extension.Add(wxT("Classic Controller"));
arrayStringFor_extension.Add(wxT("Guitar Hero 3 Guitar"));
m_Notebook = new wxNotebook(this, ID_NOTEBOOK, wxDefaultPosition, wxDefaultSize); m_Notebook = new wxNotebook(this, ID_NOTEBOOK, wxDefaultPosition, wxDefaultSize);
for (int i = 0; i < MAX_WIIMOTES; i++) for (int i = 0; i < MAX_WIIMOTES; i++)
@ -149,45 +151,23 @@ void WiimoteBasicConfigDialog::CreateGUIControls()
m_Controller[i] = new wxPanel(m_Notebook, ID_CONTROLLERPAGE1 + i, wxDefaultPosition, wxDefaultSize); m_Controller[i] = new wxPanel(m_Notebook, ID_CONTROLLERPAGE1 + i, wxDefaultPosition, wxDefaultSize);
m_Notebook->AddPage(m_Controller[i], wxString::Format(wxT("Wiimote %d"), i+1)); m_Notebook->AddPage(m_Controller[i], wxString::Format(wxT("Wiimote %d"), i+1));
m_ConnectRealWiimote[i] = new wxCheckBox(m_Controller[i], IDC_CONNECT_REAL, wxT("Connect Real Wiimote"));
m_UseRealWiimote[i] = new wxCheckBox(m_Controller[i], IDC_USE_REAL, wxT("Use Real Wiimote"));
m_ConnectRealWiimote[0]->SetValue(g_Config.bConnectRealWiimote);
m_UseRealWiimote[0]->SetValue(g_Config.bUseRealWiimote);
m_ConnectRealWiimote[i]->SetToolTip(wxT("Connected to the real wiimote. This can not be changed during gameplay."));
m_UseRealWiimote[i]->SetToolTip(wxT("Use the real Wiimote in the game. This can be changed during gameplay. This can not be selected")
wxT(" when a recording is to be done. No status in this window will be updated when this is checked."));
m_WiiMotionPlusConnected[i] = new wxCheckBox(m_Controller[i], IDC_MOTIONPLUSCONNECTED, wxT("Wii Motion Plus Connected"));
m_WiiMotionPlusConnected[i]->SetValue(g_Config.bMotionPlusConnected);
m_WiiMotionPlusConnected[i]->Enable(false);
wxArrayString arrayStringFor_extension;
arrayStringFor_extension.Add(wxT("None"));
arrayStringFor_extension.Add(wxT("Nunchuck"));
arrayStringFor_extension.Add(wxT("Classic Controller"));
arrayStringFor_extension.Add(wxT("Guitar Hero 3 Guitar"));
//arrayStringFor_extension.Add(wxT("Guitar Hero World Tour Drums Connected"));
// Prolly needs to be a separate plugin
//arrayStringFor_extension.Add(wxT("Balance Board"));
extensionChoice[i] = new wxChoice(m_Controller[i], IDC_EXTCONNECTED, wxDefaultPosition, wxDefaultSize, arrayStringFor_extension, 0, wxDefaultValidator);
extensionChoice[i]->SetSelection(0);
// Basic Settings // Basic Settings
m_InputActive[i] = new wxCheckBox(m_Controller[i], IDC_INPUT_ACTIVE, wxT("Wiimote Input Active")); m_InputSource[i] = new wxChoice(m_Controller[i], IDC_INPUT_SOURCE, wxDefaultPosition, wxDefaultSize, arrayStringFor_source, 0, wxDefaultValidator);
m_InputActive[i]->SetValue(g_Config.bInputActive);
m_InputActive[i]->SetToolTip(wxString::Format(wxT("Decide if Wiimote button events shall be sent to game"), i));
// Emulated Wiimote // Emulated Wiimote
m_SidewaysWiimote[i] = new wxCheckBox(m_Controller[i], IDC_SIDEWAYSWIIMOTE, wxT("Sideways Wiimote")); m_SidewaysWiimote[i] = new wxCheckBox(m_Controller[i], IDC_SIDEWAYSWIIMOTE, wxT("Sideways Wiimote"));
m_SidewaysWiimote[i]->SetValue(g_Config.bSideways);
m_SidewaysWiimote[i]->SetToolTip(wxT("Treat the sideways position as neutral")); m_SidewaysWiimote[i]->SetToolTip(wxT("Treat the sideways position as neutral"));
m_UprightWiimote[i] = new wxCheckBox(m_Controller[i], IDC_UPRIGHTWIIMOTE, wxT("Upright Wiimote")); m_UprightWiimote[i] = new wxCheckBox(m_Controller[i], IDC_UPRIGHTWIIMOTE, wxT("Upright Wiimote"));
m_UprightWiimote[i]->SetValue(g_Config.bUpright);
m_UprightWiimote[i]->SetToolTip(wxT("Treat the upright position as neutral")); m_UprightWiimote[i]->SetToolTip(wxT("Treat the upright position as neutral"));
m_WiiMotionPlusConnected[i] = new wxCheckBox(m_Controller[i], IDC_MOTIONPLUSCONNECTED, wxT("Wii Motion Plus Connected"));
m_WiiMotionPlusConnected[i]->Enable(false);
m_Extension[i] = new wxChoice(m_Controller[i], IDC_EXTCONNECTED, wxDefaultPosition, wxDefaultSize, arrayStringFor_extension, 0, wxDefaultValidator);
m_ConnectRealWiimote[i] = new wxCheckBox(m_Controller[i], IDC_CONNECT_REAL, wxT("Connect Real Wiimote"));
m_ConnectRealWiimote[i]->SetToolTip(wxT("Connected to the real wiimote. This can not be changed during gameplay."));
//IR Pointer //IR Pointer
m_TextScreenWidth[i] = new wxStaticText(m_Controller[i], wxID_ANY, wxT("Width: 000")); m_TextScreenWidth[i] = new wxStaticText(m_Controller[i], wxID_ANY, wxT("Width: 000"));
m_TextScreenHeight[i] = new wxStaticText(m_Controller[i], wxID_ANY, wxT("Height: 000")); m_TextScreenHeight[i] = new wxStaticText(m_Controller[i], wxID_ANY, wxT("Height: 000"));
@ -199,26 +179,18 @@ void WiimoteBasicConfigDialog::CreateGUIControls()
m_SliderLeft[i] = new wxSlider(m_Controller[i], IDS_LEFT, 0, 100, 500, wxDefaultPosition, wxSize(75, -1)); m_SliderLeft[i] = new wxSlider(m_Controller[i], IDS_LEFT, 0, 100, 500, wxDefaultPosition, wxSize(75, -1));
m_SliderTop[i] = new wxSlider(m_Controller[i], IDS_TOP, 0, 0, 500, wxDefaultPosition, wxSize(75, -1)); m_SliderTop[i] = new wxSlider(m_Controller[i], IDS_TOP, 0, 0, 500, wxDefaultPosition, wxSize(75, -1));
//m_ScreenSize = new wxCheckBox(m_Controller[i], IDC_SCREEN_SIZE, wxT("Adjust screen size and position"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator);
//m_ScreenSize[i]->SetToolTip(wxT("Use the adjusted screen size."));
// These are changed from the graphics plugin settings, so they are just here to show the loaded status // These are changed from the graphics plugin settings, so they are just here to show the loaded status
m_TextAR[i] = new wxStaticText(m_Controller[i], wxID_ANY, wxT("Aspect Ratio")); m_TextAR[i] = new wxStaticText(m_Controller[i], wxID_ANY, wxT("Aspect Ratio"));
m_CheckAR43[i] = new wxCheckBox(m_Controller[i], wxID_ANY, wxT("4:3"), wxDefaultPosition, wxSize(-1, -1), 0, wxDefaultValidator); m_CheckAR43[i] = new wxCheckBox(m_Controller[i], wxID_ANY, wxT("4:3"), wxDefaultPosition, wxSize(-1, -1), 0, wxDefaultValidator);
m_CheckAR169[i] = new wxCheckBox(m_Controller[i], wxID_ANY, wxT("16:9"), wxDefaultPosition, wxSize(-1, -1), 0, wxDefaultValidator);
m_Crop[i] = new wxCheckBox(m_Controller[i], wxID_ANY, wxT("Crop"), wxDefaultPosition, wxSize(-1, -1), 0, wxDefaultValidator);
m_CheckAR43[i]->SetValue(g_Config.bKeepAR43);
m_CheckAR169[i]->SetValue(g_Config.bKeepAR169);
m_Crop[i]->SetValue(g_Config.bCrop);
m_CheckAR43[i]->Enable(false); m_CheckAR43[i]->Enable(false);
m_CheckAR169[i] = new wxCheckBox(m_Controller[i], wxID_ANY, wxT("16:9"), wxDefaultPosition, wxSize(-1, -1), 0, wxDefaultValidator);
m_CheckAR169[i]->Enable(false); m_CheckAR169[i]->Enable(false);
m_Crop[i] = new wxCheckBox(m_Controller[i], wxID_ANY, wxT("Crop"), wxDefaultPosition, wxSize(-1, -1), 0, wxDefaultValidator);
m_Crop[i]->Enable(false); m_Crop[i]->Enable(false);
// Sizers // Sizers
m_SizeBasic[i] = new wxStaticBoxSizer(wxVERTICAL, m_Controller[i], wxT("Emulated Wiimote")); m_SizeBasic[i] = new wxStaticBoxSizer(wxVERTICAL, m_Controller[i], wxT("Input Source"));
m_SizeBasic[i]->Add(m_InputActive[i], 0, wxEXPAND | wxALL, 5); m_SizeBasic[i]->Add(m_InputSource[i], 0, wxEXPAND | wxALL, 5);
m_SizeEmu[i] = new wxStaticBoxSizer(wxVERTICAL, m_Controller[i], wxT("Emulated Position")); m_SizeEmu[i] = new wxStaticBoxSizer(wxVERTICAL, m_Controller[i], wxT("Emulated Position"));
m_SizeEmu[i]->Add(m_SidewaysWiimote[i], 0, wxEXPAND | wxALL, 5); m_SizeEmu[i]->Add(m_SidewaysWiimote[i], 0, wxEXPAND | wxALL, 5);
@ -226,17 +198,17 @@ void WiimoteBasicConfigDialog::CreateGUIControls()
m_SizeExtensions[i] = new wxStaticBoxSizer(wxVERTICAL, m_Controller[i], wxT("Emulated Extension")); m_SizeExtensions[i] = new wxStaticBoxSizer(wxVERTICAL, m_Controller[i], wxT("Emulated Extension"));
m_SizeExtensions[i]->Add(m_WiiMotionPlusConnected[i], 0, wxEXPAND | wxALL, 5); m_SizeExtensions[i]->Add(m_WiiMotionPlusConnected[i], 0, wxEXPAND | wxALL, 5);
m_SizeExtensions[i]->Add(extensionChoice[i], 0, wxEXPAND | wxALL, 5); m_SizeExtensions[i]->Add(m_Extension[i], 0, wxEXPAND | wxALL, 5);
m_SizeReal[i] = new wxStaticBoxSizer(wxVERTICAL, m_Controller[i], wxT("Real Wiimote")); m_SizeReal[i] = new wxStaticBoxSizer(wxVERTICAL, m_Controller[i], wxT("Real Wiimote"));
m_SizeReal[i]->Add(m_ConnectRealWiimote[i], 0, wxEXPAND | wxALL, 5); m_SizeReal[i]->Add(m_ConnectRealWiimote[i], 0, wxEXPAND | wxALL, 5);
m_SizeReal[i]->Add(m_UseRealWiimote[i], 0, wxEXPAND | wxALL, 5);
m_SizerIRPointerWidth[i] = new wxBoxSizer(wxHORIZONTAL); m_SizerIRPointerWidth[i] = new wxBoxSizer(wxHORIZONTAL);
m_SizerIRPointerWidth[i]->Add(m_TextScreenLeft[i], 0, wxEXPAND | (wxTOP), 3); m_SizerIRPointerWidth[i]->Add(m_TextScreenLeft[i], 0, wxEXPAND | (wxTOP), 3);
m_SizerIRPointerWidth[i]->Add(m_SliderLeft[i], 0, wxEXPAND | (wxRIGHT), 0); m_SizerIRPointerWidth[i]->Add(m_SliderLeft[i], 0, wxEXPAND | (wxRIGHT), 0);
m_SizerIRPointerWidth[i]->Add(m_TextScreenWidth[i], 0, wxEXPAND | (wxTOP), 3); m_SizerIRPointerWidth[i]->Add(m_TextScreenWidth[i], 0, wxEXPAND | (wxTOP), 3);
m_SizerIRPointerWidth[i]->Add(m_SliderWidth[i], 0, wxEXPAND | (wxLEFT), 0); m_SizerIRPointerWidth[i]->Add(m_SliderWidth[i], 0, wxEXPAND | (wxLEFT), 0);
m_SizerIRPointerHeight[i] = new wxBoxSizer(wxHORIZONTAL); m_SizerIRPointerHeight[i] = new wxBoxSizer(wxHORIZONTAL);
m_SizerIRPointerHeight[i]->Add(m_TextScreenTop[i], 0, wxEXPAND | (wxTOP), 3); m_SizerIRPointerHeight[i]->Add(m_TextScreenTop[i], 0, wxEXPAND | (wxTOP), 3);
m_SizerIRPointerHeight[i]->Add(m_SliderTop[i], 0, wxEXPAND | (wxRIGHT), 0); m_SizerIRPointerHeight[i]->Add(m_SliderTop[i], 0, wxEXPAND | (wxRIGHT), 0);
@ -264,17 +236,11 @@ void WiimoteBasicConfigDialog::CreateGUIControls()
m_SizeBasicGeneralRight[i]->Add(m_SizerIRPointer[i], 0, wxEXPAND | (wxUP), 5); m_SizeBasicGeneralRight[i]->Add(m_SizerIRPointer[i], 0, wxEXPAND | (wxUP), 5);
m_SizeBasicGeneral[i] = new wxBoxSizer(wxHORIZONTAL); m_SizeBasicGeneral[i] = new wxBoxSizer(wxHORIZONTAL);
m_SizeBasicGeneral[i]->Add(m_SizeBasicGeneralLeft[i], 0, wxEXPAND | (wxUP), 0); m_SizeBasicGeneral[i]->Add(m_SizeBasicGeneralLeft[i], 0, wxEXPAND | (wxLEFT | wxRIGHT | wxDOWN), 5);
m_SizeBasicGeneral[i]->Add(m_SizeBasicGeneralRight[i], 0, wxEXPAND | (wxLEFT), 5); m_SizeBasicGeneral[i]->Add(m_SizeBasicGeneralRight[i], 0, wxEXPAND | (wxLEFT | wxRIGHT | wxDOWN), 5);
m_SizeParent[i] = new wxBoxSizer(wxVERTICAL);
m_SizeParent[i]->Add(m_SizeBasicGeneral[i], 0, wxBORDER_STATIC | wxEXPAND | (wxALL), 5);
// The sizer m_sMain will be expanded inside m_Controller, m_SizeParent will not
m_sMain[i] = new wxBoxSizer(wxVERTICAL);
m_sMain[i]->Add(m_SizeParent[i]);
// Set the main sizer // Set the main sizer
m_Controller[i]->SetSizer(m_sMain[i]); m_Controller[i]->SetSizer(m_SizeBasicGeneral[i]);
} }
m_ButtonMapping = new wxButton(this, ID_BUTTONMAPPING, wxT("Button Mapping")); m_ButtonMapping = new wxButton(this, ID_BUTTONMAPPING, wxT("Button Mapping"));
@ -307,6 +273,20 @@ void WiimoteBasicConfigDialog::CreateGUIControls()
ControlsCreated = true; ControlsCreated = true;
} }
// Execute a delayed function
void WiimoteBasicConfigDialog::UpdateOnce(wxTimerEvent& event)
{
switch(event.GetId())
{
case IDTM_UPDATE_ONCE:
// Reenable the checkbox
m_bEnableUseRealWiimote = true;
SetCursor(wxCursor(wxCURSOR_ARROW));
UpdateGUI();
break;
}
}
void WiimoteBasicConfigDialog::DoConnectReal() void WiimoteBasicConfigDialog::DoConnectReal()
{ {
if(g_Config.bConnectRealWiimote) if(g_Config.bConnectRealWiimote)
@ -325,7 +305,7 @@ void WiimoteBasicConfigDialog::DoConnectReal()
void WiimoteBasicConfigDialog::DoUseReal() void WiimoteBasicConfigDialog::DoUseReal()
{ {
if (!g_Config.bUseRealWiimote) if (!g_RealWiiMotePresent || !g_Config.bConnectRealWiimote)
return; return;
// Clear any eventual events in the Wiimote queue // Clear any eventual events in the Wiimote queue
@ -333,7 +313,7 @@ void WiimoteBasicConfigDialog::DoUseReal()
// Are we using an extension now? The report that it's removed, then reconnected. // Are we using an extension now? The report that it's removed, then reconnected.
bool UsingExtension = false; bool UsingExtension = false;
if (g_Config.iExtensionConnected != EXT_NONE) if (WiiMoteEmu::WiiMapping[m_Page].iExtensionConnected != WiiMoteEmu::EXT_NONE)
UsingExtension = true; UsingExtension = true;
DEBUG_LOG(WIIMOTE, "DoUseReal() Connect extension: %i", !UsingExtension); DEBUG_LOG(WIIMOTE, "DoUseReal() Connect extension: %i", !UsingExtension);
@ -362,56 +342,71 @@ void WiimoteBasicConfigDialog::DoUseReal()
void WiimoteBasicConfigDialog::DoExtensionConnectedDisconnected(int Extension) void WiimoteBasicConfigDialog::DoExtensionConnectedDisconnected(int Extension)
{ {
// There is no need for this if no game is running // There is no need for this if no game is running
if(!g_EmulatorRunning) return; if(!g_EmulatorRunning || WiiMoteEmu::WiiMapping[m_Page].Source <= 0)
return;
u8 DataFrame[8]; // make a blank report for it u8 DataFrame[8] = {0}; // make a blank report for it
wm_request_status *rs = (wm_request_status*)DataFrame; wm_request_status *rs = (wm_request_status*)DataFrame;
// Check if a game is running, in that case change the status // Check if a game is running, in that case change the status
if(WiiMoteEmu::g_ReportingChannel > 0) if(WiiMoteEmu::g_ReportingChannel[m_Page] > 0)
WiiMoteEmu::WmRequestStatus(WiiMoteEmu::g_ReportingChannel, rs, Extension); {
WiiMoteEmu::g_ID = m_Page;
WiiMoteEmu::WmRequestStatus(WiiMoteEmu::g_ReportingChannel[m_Page], rs, Extension);
}
} }
// Notebook page changed
void WiimoteBasicConfigDialog::NotebookPageChanged(wxNotebookEvent& event)
{
// Update the global variable
m_Page = event.GetSelection();
// Update GUI
if (ControlsCreated)
UpdateGUI();
}
void WiimoteBasicConfigDialog::GeneralSettingsChanged(wxCommandEvent& event) void WiimoteBasicConfigDialog::GeneralSettingsChanged(wxCommandEvent& event)
{ {
switch (event.GetId()) switch (event.GetId())
{ {
case IDC_CONNECT_REAL: case IDC_CONNECT_REAL:
g_Config.bConnectRealWiimote = m_ConnectRealWiimote[Page]->IsChecked(); g_Config.bConnectRealWiimote = m_ConnectRealWiimote[m_Page]->IsChecked();
DoConnectReal(); DoConnectReal();
break; break;
case IDC_USE_REAL: case IDC_INPUT_SOURCE:
// Enable the Wiimote thread if (m_InputSource[m_Page]->GetSelection() == 2)
g_Config.bUseRealWiimote = m_UseRealWiimote[Page]->IsChecked(); {
DoUseReal(); g_Config.bUseRealWiimote = true;
break; WiiMoteEmu::WiiMapping[m_Page].Source = -1;
case IDC_INPUT_ACTIVE: DoUseReal();
g_Config.bInputActive = m_InputActive[Page]->IsChecked(); }
else
{
g_Config.bUseRealWiimote = false;
WiiMoteEmu::WiiMapping[m_Page].Source = m_InputSource[m_Page]->GetSelection();
}
break; break;
case IDC_SIDEWAYSWIIMOTE: case IDC_SIDEWAYSWIIMOTE:
g_Config.bSideways = m_SidewaysWiimote[Page]->IsChecked(); WiiMoteEmu::WiiMapping[m_Page].bSideways = m_SidewaysWiimote[m_Page]->IsChecked();
break; break;
case IDC_UPRIGHTWIIMOTE: case IDC_UPRIGHTWIIMOTE:
g_Config.bUpright = m_UprightWiimote[Page]->IsChecked(); WiiMoteEmu::WiiMapping[m_Page].bUpright = m_UprightWiimote[m_Page]->IsChecked();
break; break;
case IDC_MOTIONPLUSCONNECTED: case IDC_MOTIONPLUSCONNECTED:
g_Config.bMotionPlusConnected = m_WiiMotionPlusConnected[Page]->IsChecked(); WiiMoteEmu::WiiMapping[m_Page].bMotionPlusConnected = m_WiiMotionPlusConnected[m_Page]->IsChecked();
break; break;
case IDC_EXTCONNECTED: case IDC_EXTCONNECTED:
g_Config.iExtensionConnected = EXT_NONE;
// Disconnect the extension so that the game recognize the change // Disconnect the extension so that the game recognize the change
DoExtensionConnectedDisconnected(); DoExtensionConnectedDisconnected(WiiMoteEmu::EXT_NONE);
// It doesn't seem to be needed but shouldn't it at least take 25 ms to // It doesn't seem to be needed but shouldn't it at least take 25 ms to
// reconnect an extension after we disconnected another? // reconnect an extension after we disconnected another?
if(g_EmulatorRunning) SLEEP(25); if(g_EmulatorRunning) SLEEP(25);
// Update status // Update status
g_Config.iExtensionConnected = extensionChoice[Page]->GetSelection(); WiiMoteEmu::WiiMapping[m_Page].iExtensionConnected = m_Extension[m_Page]->GetSelection();
// Copy the calibration data // Copy the calibration data
WiiMoteEmu::UpdateExtRegisterBlocks(); WiiMoteEmu::UpdateExtRegisterBlocks(m_Page);
// Generate connect/disconnect status event // Generate connect/disconnect status event
DoExtensionConnectedDisconnected(); DoExtensionConnectedDisconnected();
break; break;
@ -424,62 +419,55 @@ void WiimoteBasicConfigDialog::IRCursorChanged(wxScrollEvent& event)
switch (event.GetId()) switch (event.GetId())
{ {
case IDS_WIDTH: case IDS_WIDTH:
g_Config.iIRWidth = m_SliderWidth[Page]->GetValue(); g_Config.iIRWidth = m_SliderWidth[m_Page]->GetValue();
break; break;
case IDS_HEIGHT: case IDS_HEIGHT:
g_Config.iIRHeight = m_SliderHeight[Page]->GetValue(); g_Config.iIRHeight = m_SliderHeight[m_Page]->GetValue();
break; break;
case IDS_LEFT: case IDS_LEFT:
g_Config.iIRLeft = m_SliderLeft[Page]->GetValue(); g_Config.iIRLeft = m_SliderLeft[m_Page]->GetValue();
break; break;
case IDS_TOP: case IDS_TOP:
g_Config.iIRTop = m_SliderTop[Page]->GetValue(); g_Config.iIRTop = m_SliderTop[m_Page]->GetValue();
break; break;
} }
UpdateGUI(); UpdateGUI();
} }
void WiimoteBasicConfigDialog::UpdateIRCalibration() void WiimoteBasicConfigDialog::UpdateGUI()
{
// Update the slider position if a configuration has been loaded
m_SliderWidth[Page]->SetValue(g_Config.iIRWidth);
m_SliderHeight[Page]->SetValue(g_Config.iIRHeight);
m_SliderLeft[Page]->SetValue(g_Config.iIRLeft);
m_SliderTop[Page]->SetValue(g_Config.iIRTop);
// Update the labels
m_TextScreenWidth[Page]->SetLabel(wxString::Format(wxT("Width: %i"), g_Config.iIRWidth));
m_TextScreenHeight[Page]->SetLabel(wxString::Format(wxT("Height: %i"), g_Config.iIRHeight));
m_TextScreenLeft[Page]->SetLabel(wxString::Format(wxT("Left: %i"), g_Config.iIRLeft));
m_TextScreenTop[Page]->SetLabel(wxString::Format(wxT("Top: %i"), g_Config.iIRTop));
}
void WiimoteBasicConfigDialog::UpdateGUI(int Slot)
{ {
/* I have disabled this option during a running game because it's enough to be able to switch /* I have disabled this option during a running game because it's enough to be able to switch
between using and not using then. To also use the connect option during a running game would between using and not using then. To also use the connect option during a running game would
mean that the wiimote must be sent the current reporting mode and the channel ID after it mean that the wiimote must be sent the current reporting mode and the channel ID after it
has been initialized. Functions for that are basically already in place so these two options has been initialized. Functions for that are basically already in place so these two options
could possibly be simplified to one option. */ could possibly be simplified to one option. */
m_ConnectRealWiimote[Page]->SetValue(g_Config.bConnectRealWiimote); m_ConnectRealWiimote[m_Page]->SetValue(g_Config.bConnectRealWiimote);
m_ConnectRealWiimote[Page]->Enable(!g_EmulatorRunning); m_ConnectRealWiimote[m_Page]->Enable(!g_EmulatorRunning);
m_UseRealWiimote[Page]->SetValue(g_Config.bUseRealWiimote); if (WiiMoteEmu::WiiMapping[m_Page].Source < 0)
m_UseRealWiimote[Page]->Enable((m_bEnableUseRealWiimote && g_RealWiiMotePresent && g_Config.bConnectRealWiimote) || (!g_EmulatorRunning && g_Config.bConnectRealWiimote)); m_InputSource[m_Page]->SetSelection(2);
else
m_InputSource[m_Page]->SetSelection(WiiMoteEmu::WiiMapping[m_Page].Source);
m_InputActive[Page]->SetValue(g_Config.bInputActive); m_SidewaysWiimote[m_Page]->SetValue(WiiMoteEmu::WiiMapping[m_Page].bSideways);
m_SidewaysWiimote[Page]->SetValue(g_Config.bSideways); m_UprightWiimote[m_Page]->SetValue(WiiMoteEmu::WiiMapping[m_Page].bUpright);
m_UprightWiimote[Page]->SetValue(g_Config.bUpright); m_WiiMotionPlusConnected[m_Page]->SetValue(WiiMoteEmu::WiiMapping[m_Page].bMotionPlusConnected);
m_WiiMotionPlusConnected[Page]->SetValue(g_Config.bMotionPlusConnected);
/* We only allow a change of extension if we are not currently using the real Wiimote, if it's in use the status will be updated m_Extension[m_Page]->SetSelection(WiiMoteEmu::WiiMapping[m_Page].iExtensionConnected);
from the data scanning functions in main.cpp */
bool AllowExtensionChange = !(g_RealWiiMotePresent && g_Config.bConnectRealWiimote && g_Config.bUseRealWiimote && g_EmulatorRunning);
extensionChoice[Page]->SetSelection(g_Config.iExtensionConnected);
extensionChoice[Page]->Enable(AllowExtensionChange);
// Update the Wiimote IR pointer calibration // Update the Wiimote IR pointer calibration
UpdateIRCalibration(); m_TextScreenWidth[m_Page]->SetLabel(wxString::Format(wxT("Width: %i"), g_Config.iIRWidth));
m_TextScreenHeight[m_Page]->SetLabel(wxString::Format(wxT("Height: %i"), g_Config.iIRHeight));
m_TextScreenLeft[m_Page]->SetLabel(wxString::Format(wxT("Left: %i"), g_Config.iIRLeft));
m_TextScreenTop[m_Page]->SetLabel(wxString::Format(wxT("Top: %i"), g_Config.iIRTop));
// Update the slider position if a configuration has been loaded
m_SliderWidth[m_Page]->SetValue(g_Config.iIRWidth);
m_SliderHeight[m_Page]->SetValue(g_Config.iIRHeight);
m_SliderLeft[m_Page]->SetValue(g_Config.iIRLeft);
m_SliderTop[m_Page]->SetValue(g_Config.iIRTop);
m_CheckAR43[m_Page]->SetValue(g_Config.bKeepAR43);
m_CheckAR169[m_Page]->SetValue(g_Config.bKeepAR169);
m_Crop[m_Page]->SetValue(g_Config.bCrop);
} }

View File

@ -30,6 +30,7 @@
#include <wx/notebook.h> #include <wx/notebook.h>
#include <wx/panel.h> #include <wx/panel.h>
#include <wx/gbsizer.h> #include <wx/gbsizer.h>
#include "wiimote_hid.h"
class WiimoteBasicConfigDialog : public wxDialog class WiimoteBasicConfigDialog : public wxDialog
{ {
@ -43,9 +44,8 @@ class WiimoteBasicConfigDialog : public wxDialog
virtual ~WiimoteBasicConfigDialog(){;} virtual ~WiimoteBasicConfigDialog(){;}
// General open, close and event functions // General open, close and event functions
void UpdateGUI();
void ButtonClick(wxCommandEvent& event); void ButtonClick(wxCommandEvent& event);
void UpdateGUI(int Slot = 0);
void UpdateIRCalibration();
void ShutDown(wxTimerEvent& WXUNUSED(event)); void ShutDown(wxTimerEvent& WXUNUSED(event));
void UpdateOnce(wxTimerEvent& event); void UpdateOnce(wxTimerEvent& event);
@ -53,58 +53,55 @@ class WiimoteBasicConfigDialog : public wxDialog
wxTimer *m_TimeoutOnce, wxTimer *m_TimeoutOnce,
*m_ShutDownTimer; *m_ShutDownTimer;
wxCheckBox *m_UseRealWiimote[4];
private: private:
DECLARE_EVENT_TABLE(); DECLARE_EVENT_TABLE();
bool ControlsCreated, m_bEnableUseRealWiimote; bool ControlsCreated, m_bEnableUseRealWiimote;
int Page; int m_Page;
wxNotebook *m_Notebook; wxNotebook *m_Notebook;
wxPanel *m_Controller[4]; wxPanel *m_Controller[MAX_WIIMOTES];
wxButton *m_OK, wxButton *m_OK,
*m_Cancel, *m_Cancel,
*m_ButtonMapping, *m_ButtonMapping,
*m_Recording; *m_Recording;
wxChoice* extensionChoice[4]; wxChoice *m_InputSource[MAX_WIIMOTES],
*m_Extension[MAX_WIIMOTES];
wxSlider *m_SliderWidth[4], wxSlider *m_SliderWidth[MAX_WIIMOTES],
*m_SliderHeight[4], *m_SliderHeight[MAX_WIIMOTES],
*m_SliderLeft[4], *m_SliderLeft[MAX_WIIMOTES],
*m_SliderTop[4]; *m_SliderTop[MAX_WIIMOTES];
wxCheckBox *m_InputActive[4], wxCheckBox *m_ConnectRealWiimote[MAX_WIIMOTES],
*m_SidewaysWiimote[4], *m_SidewaysWiimote[MAX_WIIMOTES],
*m_UprightWiimote[4], *m_UprightWiimote[MAX_WIIMOTES],
*m_ConnectRealWiimote[4], *m_WiiMotionPlusConnected[MAX_WIIMOTES],
*m_WiiMotionPlusConnected[4], *m_CheckAR43[MAX_WIIMOTES],
*m_CheckAR43[4], *m_CheckAR169[MAX_WIIMOTES],
*m_CheckAR169[4], *m_Crop[MAX_WIIMOTES];
*m_Crop[4];
wxStaticText *m_TextScreenWidth[4], wxStaticText *m_TextScreenWidth[MAX_WIIMOTES],
*m_TextScreenHeight[4], *m_TextScreenHeight[MAX_WIIMOTES],
*m_TextScreenLeft[4], *m_TextScreenLeft[MAX_WIIMOTES],
*m_TextScreenTop[4], *m_TextScreenTop[MAX_WIIMOTES],
*m_TextAR[4]; *m_TextAR[MAX_WIIMOTES];
wxBoxSizer *m_MainSizer, wxBoxSizer *m_MainSizer,
*m_sMain[4], *m_SizeBasicGeneral[MAX_WIIMOTES],
*m_SizeParent[4], *m_SizeBasicGeneralLeft[MAX_WIIMOTES],
*m_SizeBasicGeneral[4], *m_SizeBasicGeneralRight[MAX_WIIMOTES],
*m_SizeBasicGeneralLeft[4], *m_SizerIRPointerWidth[MAX_WIIMOTES],
*m_SizeBasicGeneralRight[4], *m_SizerIRPointerHeight[MAX_WIIMOTES],
*m_SizerIRPointerWidth[4], *m_SizerIRPointerScreen[MAX_WIIMOTES];
*m_SizerIRPointerHeight[4],
*m_SizerIRPointerScreen[4];
wxStaticBoxSizer *m_SizeBasic[4], wxStaticBoxSizer *m_SizeBasic[MAX_WIIMOTES],
*m_SizeEmu[4], *m_SizeEmu[MAX_WIIMOTES],
*m_SizeReal[4], *m_SizeReal[MAX_WIIMOTES],
*m_SizeExtensions[4], *m_SizeExtensions[MAX_WIIMOTES],
*m_SizerIRPointer[4]; *m_SizerIRPointer[MAX_WIIMOTES];
enum enum
{ {
@ -123,7 +120,7 @@ class WiimoteBasicConfigDialog : public wxDialog
ID_CONTROLLERPAGE4, ID_CONTROLLERPAGE4,
// Emulated Wiimote // Emulated Wiimote
IDC_INPUT_ACTIVE, IDC_INPUT_SOURCE,
IDC_SIDEWAYSWIIMOTE, IDC_SIDEWAYSWIIMOTE,
IDC_UPRIGHTWIIMOTE, IDC_UPRIGHTWIIMOTE,
IDC_MOTIONPLUSCONNECTED, IDC_MOTIONPLUSCONNECTED,
@ -131,7 +128,6 @@ class WiimoteBasicConfigDialog : public wxDialog
// Real // Real
IDC_CONNECT_REAL, IDC_CONNECT_REAL,
IDC_USE_REAL,
IDS_WIDTH, IDS_WIDTH,
IDS_HEIGHT, IDS_HEIGHT,
@ -139,8 +135,9 @@ class WiimoteBasicConfigDialog : public wxDialog
IDS_TOP, IDS_TOP,
}; };
void OnClose(wxCloseEvent& event);
void CreateGUIControls(); void CreateGUIControls();
void OnClose(wxCloseEvent& event);
void NotebookPageChanged(wxNotebookEvent& event);
void GeneralSettingsChanged(wxCommandEvent& event); void GeneralSettingsChanged(wxCommandEvent& event);
void IRCursorChanged(wxScrollEvent& event); void IRCursorChanged(wxScrollEvent& event);

View File

@ -20,339 +20,86 @@
#include "ConfigPadDlg.h" #include "ConfigPadDlg.h"
#include "Config.h" #include "Config.h"
#include "EmuMain.h" // for WiiMoteEmu class #include "EmuMain.h" // for WiiMoteEmu class
#include "EmuDefinitions.h"
#if defined(HAVE_X11) && HAVE_X11 #if defined(HAVE_X11) && HAVE_X11
#include "X11InputBase.h" #include "X11InputBase.h"
#endif #endif
// Change Joystick
/* Function: When changing the joystick we save and load the settings and // Replace the harder to understand -1 with "" for the sake of user friendliness
update the PadMapping and PadState array. PadState[].joy is the gamepad void WiimotePadConfigDialog::ToBlank(bool ToBlank, int Id)
handle that is used to access the pad throughout the plugin. Joyinfo[].joy
is only used the first time the pads are checked. */
void WiimotePadConfigDialog::DoChangeJoystick()
{ {
// Close the current pad, unless it's used by another slot if (!ControlsCreated)
//if (PadMapping[Page].enabled) PadClose(Page);
// Before changing the pad we save potential changes to the current pad
DoSave(true);
// Load the settings for the new Id
g_Config.Load(true);
UpdateGUI(Page); // Update the GUI
// Open the new pad
//if (WiiMoteEmu::PadMapping[Page].enabled) PadOpen(Page);
}
void WiimotePadConfigDialog::PadOpen(int Open) // Open for slot 1, 2, 3 or 4
{
// Check that we got a good pad
if (!WiiMoteEmu::joyinfo.at(WiiMoteEmu::PadMapping[Open].ID).Good)
{
DEBUG_LOG(WIIMOTE, "A bad pad was selected");
WiiMoteEmu::PadState[Open].joy = NULL;
return; return;
}
DEBUG_LOG(WIIMOTE, "Update the Slot %i handle to Id %i", Page, WiiMoteEmu::PadMapping[Open].ID); if(ToBlank)
WiiMoteEmu::PadState[Open].joy = SDL_JoystickOpen(WiiMoteEmu::PadMapping[Open].ID);
}
void WiimotePadConfigDialog::PadClose(int _Close) // Close for slot 1, 2, 3 or 4
{
if (SDL_JoystickOpened(WiiMoteEmu::PadMapping[_Close].ID)) SDL_JoystickClose(WiiMoteEmu::PadState[_Close].joy);
WiiMoteEmu::PadState[_Close].joy = NULL;
}
void WiimotePadConfigDialog::DoChangeDeadZone(bool Left)
{
if(Left)
{ {
float Rad = (float)WiiMoteEmu::PadMapping[Page].DeadZoneL * ((float)BoxW / 100.0) * 0.5; if (GetButtonText(Id) == wxString(wxT("-1")))
m_bmpDeadZoneLeftIn[Page]->SetBitmap(CreateBitmapClear()); SetButtonText(Id, wxString());
m_bmpDeadZoneLeftIn[Page]->SetSize(0, 0);
m_bmpDeadZoneLeftIn[Page]->SetBitmap(CreateBitmapDeadZone((int)Rad));
m_bmpDeadZoneLeftIn[Page]->SetPosition(wxPoint(BoxW / 2 - (int)Rad, BoxH / 2 - (int)Rad));
m_bmpDeadZoneLeftIn[Page]->Refresh();
} }
else else
{ {
float Rad = (float)WiiMoteEmu::PadMapping[Page].DeadZoneR * ((float)BoxW / 100.0) * 0.5; if (GetButtonText(Id).IsEmpty())
m_bmpDeadZoneRightIn[Page]->SetBitmap(CreateBitmapClear()); SetButtonText(Id, wxString(wxT("-1")));
m_bmpDeadZoneRightIn[Page]->SetSize(0, 0);
m_bmpDeadZoneRightIn[Page]->SetBitmap(CreateBitmapDeadZone((int)Rad));
m_bmpDeadZoneRightIn[Page]->SetPosition(wxPoint(BoxW / 2 - (int)Rad, BoxH / 2 - (int)Rad));
m_bmpDeadZoneRightIn[Page]->Refresh();
} }
} }
void WiimotePadConfigDialog::DoChangeDeadZone()
// Change settings
// Set the button text for all four Wiimotes
void WiimotePadConfigDialog::SetButtonTextAll(int id, char text[128])
{ {
for (int i = 0; i < 1; i++) // We've got only 1 currently float Rad;
{
// Safety check to avoid crash
if ((int)WiiMoteEmu::joyinfo.size() > WiiMoteEmu::PadMapping[i].ID)
if (WiiMoteEmu::joyinfo[WiiMoteEmu::PadMapping[i].ID].Name == WiiMoteEmu::joyinfo[WiiMoteEmu::PadMapping[Page].ID].Name)
SetButtonText(id, text, i);
};
}
void WiimotePadConfigDialog::SaveButtonMappingAll(int Slot) Rad = (float)WiiMoteEmu::WiiMapping[m_Page].DeadZoneL * ((float)BoxW / 100.0) * 0.5;
{ m_bmpDeadZoneLeftIn[m_Page]->SetBitmap(CreateBitmapClear());
for (int i = 0; i < 4; i++) m_bmpDeadZoneLeftIn[m_Page]->SetSize(0, 0);
{ m_bmpDeadZoneLeftIn[m_Page]->SetBitmap(CreateBitmapDeadZone((int)Rad));
// This can occur when no gamepad is detected m_bmpDeadZoneLeftIn[m_Page]->SetPosition(wxPoint(BoxW / 2 - (int)Rad, BoxH / 2 - (int)Rad));
if ((int)WiiMoteEmu::joyinfo.size() > WiiMoteEmu::PadMapping[i].ID && WiiMoteEmu::PadMapping[i].ID >= 0) m_bmpDeadZoneLeftIn[m_Page]->Refresh();
if (WiiMoteEmu::joyinfo[WiiMoteEmu::PadMapping[i].ID].Name == WiiMoteEmu::joyinfo[WiiMoteEmu::PadMapping[Slot].ID].Name)
SaveButtonMapping(i, false, Slot); Rad = (float)WiiMoteEmu::WiiMapping[m_Page].DeadZoneR * ((float)BoxW / 100.0) * 0.5;
} m_bmpDeadZoneRightIn[m_Page]->SetBitmap(CreateBitmapClear());
m_bmpDeadZoneRightIn[m_Page]->SetSize(0, 0);
m_bmpDeadZoneRightIn[m_Page]->SetBitmap(CreateBitmapDeadZone((int)Rad));
m_bmpDeadZoneRightIn[m_Page]->SetPosition(wxPoint(BoxW / 2 - (int)Rad, BoxH / 2 - (int)Rad));
m_bmpDeadZoneRightIn[m_Page]->Refresh();
} }
// Set dialog items from saved values // Set dialog items from saved values
void WiimotePadConfigDialog::UpdateGUIButtonMapping(int controller)
{
// Temporary storage
wxString tmp;
// Update selected gamepad
m_Joyname[controller]->SetSelection(WiiMoteEmu::PadMapping[controller].ID);
// Update the enabled checkbox
//m_Joyattach[controller]->SetValue(PadMapping[controller].enabled == 1 ? true : false);
// Update the deadzone and controller type controls
m_ComboDeadZoneLeft[controller]->SetSelection(WiiMoteEmu::PadMapping[controller].DeadZoneL);
m_ComboDeadZoneRight[controller]->SetSelection(WiiMoteEmu::PadMapping[controller].DeadZoneR);
m_ComboDiagonal[controller]->SetValue(wxString::FromAscii(WiiMoteEmu::PadMapping[controller].SDiagonal.c_str()));
m_CheckC2S[controller]->SetValue(WiiMoteEmu::PadMapping[controller].bCircle2Square);
m_CheckRumble[controller]->SetValue(WiiMoteEmu::PadMapping[controller].Rumble);
m_RumbleStrength[controller]->SetSelection(WiiMoteEmu::PadMapping[controller].RumbleStrength);
m_TriggerType[controller]->SetSelection(WiiMoteEmu::PadMapping[controller].triggertype);
m_TiltTypeWM[controller]->SetSelection(g_Config.Tilt.TypeWM);
m_TiltTypeNC[controller]->SetSelection(g_Config.Tilt.TypeNC);
m_TiltComboRangeRoll[controller]->SetSelection(g_Config.Tilt.Range.RollDegree / 5 - 1); // 5 to 180, step 5
m_TiltComboRangePitch[controller]->SetSelection(g_Config.Tilt.Range.PitchDegree / 5 - 1); // 5 to 180, step 5
m_TiltRollSwing[controller]->SetValue(g_Config.Tilt.Range.RollSwing);
m_TiltPitchSwing[controller]->SetValue(g_Config.Tilt.Range.PitchSwing);
m_TiltRollInvert[controller]->SetValue(g_Config.Tilt.RollInvert);
m_TiltPitchInvert[controller]->SetValue(g_Config.Tilt.PitchInvert);
for (int i = 0; i < AN_CONTROLS; i++)
{
tmp << WiiMoteEmu::PadMapping[controller].Axis.keyForControls[i];
m_Button_Analog[i][controller]->SetLabel(tmp);
tmp.clear();
}
// Wiimote
#ifdef _WIN32
for (int x = 0; x < WM_CONTROLS; x++)
{
m_Button_Wiimote[x][controller]->SetLabel(wxString::FromAscii(
InputCommon::VKToString(WiiMoteEmu::PadMapping[controller].Wm.keyForControls[x]).c_str()));
}
if(g_Config.iExtensionConnected == EXT_NUNCHUCK)
{
for (int x = 0; x < NC_CONTROLS; x++)
m_Button_NunChuck[x][controller]->SetLabel(wxString::FromAscii(
InputCommon::VKToString(WiiMoteEmu::PadMapping[controller].Nc.keyForControls[x]).c_str()));
}
else if(g_Config.iExtensionConnected == EXT_CLASSIC_CONTROLLER)
{
for (int x = 0; x < CC_CONTROLS; x++)
m_Button_Classic[x][controller]->SetLabel(wxString::FromAscii(
InputCommon::VKToString(WiiMoteEmu::PadMapping[controller].Cc.keyForControls[x]).c_str()));
}
else if(g_Config.iExtensionConnected == EXT_GUITARHERO3_CONTROLLER)
{
for (int x = 0; x < GH3_CONTROLS; x++)
m_Button_GH3[x][controller]->SetLabel(wxString::FromAscii(
InputCommon::VKToString(WiiMoteEmu::PadMapping[controller].GH3c.keyForControls[x]).c_str()));
}
#elif defined(HAVE_X11) && HAVE_X11
char keyStr[10] = {0};
for (int x = 0; x < WM_CONTROLS; x++)
{
InputCommon::XKeyToString(WiiMoteEmu::PadMapping[controller].Wm.keyForControls[x], keyStr);
m_Button_Wiimote[x][controller]->SetLabel(wxString::FromAscii(keyStr));
}
if(g_Config.iExtensionConnected == EXT_NUNCHUCK)
{
for (int x = 0; x < NC_CONTROLS; x++)
{
InputCommon::XKeyToString(WiiMoteEmu::PadMapping[controller].Nc.keyForControls[x], keyStr);
m_Button_NunChuck[x][controller]->SetLabel(wxString::FromAscii(keyStr));
}
}
else if(g_Config.iExtensionConnected == EXT_CLASSIC_CONTROLLER)
{
for (int x = 0; x < CC_CONTROLS; x++)
{
InputCommon::XKeyToString(WiiMoteEmu::PadMapping[controller].Cc.keyForControls[x], keyStr);
m_Button_Classic[x][controller]->SetLabel(wxString::FromAscii(keyStr));
}
}
else if(g_Config.iExtensionConnected == EXT_GUITARHERO3_CONTROLLER)
{
for (int x = 0; x < GH3_CONTROLS; x++)
{
InputCommon::XKeyToString(WiiMoteEmu::PadMapping[controller].GH3c.keyForControls[x], keyStr);
m_Button_GH3[x][controller]->SetLabel(wxString::FromAscii(keyStr));
}
}
#endif
//DEBUG_LOG(WIIMOTE, "m_bWmA[%i] = %i = %s", controller, WiiMoteEmu::PadMapping[controller].Wm.keyForControls[0], InputCommon::VKToString(WiiMoteEmu::PadMapping[controller].Wm.keyForControls[0]).c_str());
}
/* Populate the PadMapping array with the dialog items settings (for example
selected joystick, enabled or disabled status and so on) */
void WiimotePadConfigDialog::SaveButtonMapping(int controller, bool DontChangeId, int FromSlot)
{
// Temporary storage
long value;
// Save from or to the same or different slots
if (FromSlot == -1) FromSlot = controller;
// Replace "" with "-1" in the GUI controls
ToBlank(false);
/* Set physical device Id. GetSelection() should never be -1 here so we don't check that it's zero or higher. If it's possible that it can be
-1 that's a bug that should be fixed. Because the m_Joyname[] combo box should always show <No Gamepad Detected>, or a gamepad name, not a
a blank selection. */
if (!DontChangeId)
WiiMoteEmu::PadMapping[controller].ID = m_Joyname[FromSlot]->GetSelection();
// Set enabled or disable status
if (FromSlot == controller)
WiiMoteEmu::PadMapping[controller].enabled = true; // Only enable one
// Set other settings
WiiMoteEmu::PadMapping[controller].DeadZoneL = m_ComboDeadZoneLeft[FromSlot]->GetSelection();
WiiMoteEmu::PadMapping[controller].DeadZoneR = m_ComboDeadZoneRight[FromSlot]->GetSelection();
WiiMoteEmu::PadMapping[controller].SDiagonal = m_ComboDiagonal[FromSlot]->GetLabel().mb_str();
WiiMoteEmu::PadMapping[controller].bCircle2Square = m_CheckC2S[FromSlot]->IsChecked();
WiiMoteEmu::PadMapping[controller].Rumble = m_CheckRumble[FromSlot]->IsChecked();
WiiMoteEmu::PadMapping[controller].RumbleStrength = m_RumbleStrength[FromSlot]->GetSelection();
WiiMoteEmu::PadMapping[controller].triggertype = m_TriggerType[FromSlot]->GetSelection();
for (int i = 0; i < AN_CONTROLS; i++)
{
m_Button_Analog[i][FromSlot]->GetLabel().ToLong(&value);
WiiMoteEmu::PadMapping[controller].Axis.keyForControls[i] = value;
}
//DEBUG_LOG(WIIMOTE, "WiiMoteEmu::PadMapping[%i].ID = %i, m_Joyname[%i]->GetSelection() = %i",
// controller, WiiMoteEmu::PadMapping[controller].ID, FromSlot, m_Joyname[FromSlot]->GetSelection());
// Replace "-1" with ""
ToBlank();
}
// Save keyboard key mapping
void WiimotePadConfigDialog::SaveKeyboardMapping(int Controller, int Id, int Key)
{
if (IDB_WM_A <= Id && Id <= IDB_WM_SHAKE)
{
WiiMoteEmu::PadMapping[Controller].Wm.keyForControls[Id - IDB_WM_A] = Key;
}
else if (IDB_NC_Z <= Id && Id <= IDB_NC_SHAKE)
{
WiiMoteEmu::PadMapping[Controller].Nc.keyForControls[Id - IDB_NC_Z] = Key;
}
else if (IDB_CC_A <= Id && Id <= IDB_CC_RD)
{
WiiMoteEmu::PadMapping[Controller].Cc.keyForControls[Id - IDB_CC_A] = Key;
}
else if (IDB_GH3_GREEN <= Id && Id <= IDB_GH3_STRUM_DOWN)
{
WiiMoteEmu::PadMapping[Controller].GH3c.keyForControls[Id - IDB_GH3_GREEN] = Key;
}
//DEBUG_LOG(WIIMOTE, "WiiMoteEmu::PadMapping[%i].Wm.A = %i", Controller, WiiMoteEmu::PadMapping[Controller].Wm.A);
}
// Replace the harder to understand -1 with "" for the sake of user friendliness
void WiimotePadConfigDialog::ToBlank(bool _ToBlank)
{
if (!ControlsCreated) return;
for (int j = 0; j < 1; j++)
{
if(_ToBlank)
{
for(int i = IDB_ANALOG_LEFT_X; i <= IDB_TRIGGER_R; i++)
#if !defined _WIN32 && !wxCHECK_VERSION(2, 9, 0)
if(GetButtonText(i, j).ToAscii() == "-1")
SetButtonText(i, (char *)"", j);
#else
if(GetButtonText(i, j) == wxT("-1")) SetButtonText(i, "", j);
#endif
}
else
{
for(int i = IDB_ANALOG_LEFT_X; i <= IDB_TRIGGER_R; i++)
if(GetButtonText(i, j).IsEmpty())
SetButtonText(i, (char *)"-1", j);
}
}
}
// Update the textbox for the buttons // Update the textbox for the buttons
void WiimotePadConfigDialog::SetButtonText(int id, const char text[128], int _Page) void WiimotePadConfigDialog::SetButtonText(int id, const wxString &str)
{ {
// Set controller value
int controller;
if (_Page == -1) controller = Page;
else controller = _Page;
if (IDB_ANALOG_LEFT_X <= id && id <= IDB_TRIGGER_R) if (IDB_ANALOG_LEFT_X <= id && id <= IDB_TRIGGER_R)
m_Button_Analog[id - IDB_ANALOG_LEFT_X][controller]->SetLabel(wxString::FromAscii(text)); m_Button_Analog[id - IDB_ANALOG_LEFT_X][m_Page]->SetLabel(str);
else if (IDB_WM_A <= id && id <= IDB_WM_SHAKE) else if (IDB_WM_A <= id && id <= IDB_WM_SHAKE)
m_Button_Wiimote[id - IDB_WM_A][controller]->SetLabel(wxString::FromAscii(text)); m_Button_Wiimote[id - IDB_WM_A][m_Page]->SetLabel(str);
else if (IDB_NC_Z <= id && id <= IDB_NC_SHAKE) else if (IDB_NC_Z <= id && id <= IDB_NC_SHAKE)
m_Button_NunChuck[id - IDB_NC_Z][controller]->SetLabel(wxString::FromAscii(text)); m_Button_NunChuck[id - IDB_NC_Z][m_Page]->SetLabel(str);
else if (IDB_CC_A <= id && id <= IDB_CC_RD) else if (IDB_CC_A <= id && id <= IDB_CC_RD)
m_Button_Classic[id - IDB_CC_A][controller]->SetLabel(wxString::FromAscii(text)); m_Button_Classic[id - IDB_CC_A][m_Page]->SetLabel(str);
else if (IDB_GH3_GREEN <= id && id <= IDB_GH3_STRUM_DOWN) else if (IDB_GH3_GREEN <= id && id <= IDB_GH3_STRUM_DOWN)
m_Button_GH3[id - IDB_GH3_GREEN][controller]->SetLabel(wxString::FromAscii(text)); m_Button_GH3[id - IDB_GH3_GREEN][m_Page]->SetLabel(str);
//DEBUG_LOG(WIIMOTE, "SetButtonText: %s", text);
} }
// Get the text in the textbox for the buttons // Get the text in the textbox for the buttons
wxString WiimotePadConfigDialog::GetButtonText(int id, int _Page) wxString WiimotePadConfigDialog::GetButtonText(int id)
{ {
//DEBUG_LOG(WIIMOTE, "GetButtonText: %i", id);
// Set controller value
int controller;
if (_Page == -1) controller = Page;
else controller = _Page;
if (IDB_ANALOG_LEFT_X <= id && id <= IDB_TRIGGER_R) if (IDB_ANALOG_LEFT_X <= id && id <= IDB_TRIGGER_R)
return m_Button_Analog[id - IDB_ANALOG_LEFT_X][controller]->GetLabel(); return m_Button_Analog[id - IDB_ANALOG_LEFT_X][m_Page]->GetLabel();
else if (IDB_WM_A <= id && id <= IDB_WM_SHAKE) else if (IDB_WM_A <= id && id <= IDB_WM_SHAKE)
return m_Button_Wiimote[id - IDB_WM_A][controller]->GetLabel(); return m_Button_Wiimote[id - IDB_WM_A][m_Page]->GetLabel();
else if (IDB_NC_Z <= id && id <= IDB_NC_SHAKE) else if (IDB_NC_Z <= id && id <= IDB_NC_SHAKE)
return m_Button_NunChuck[id - IDB_NC_Z][controller]->GetLabel(); return m_Button_NunChuck[id - IDB_NC_Z][m_Page]->GetLabel();
else if (IDB_CC_A <= id && id <= IDB_CC_RD) else if (IDB_CC_A <= id && id <= IDB_CC_RD)
return m_Button_Classic[id - IDB_CC_A][controller]->GetLabel(); return m_Button_Classic[id - IDB_CC_A][m_Page]->GetLabel();
else if (IDB_GH3_GREEN <= id && id <= IDB_GH3_STRUM_DOWN) else if (IDB_GH3_GREEN <= id && id <= IDB_GH3_STRUM_DOWN)
return m_Button_GH3[id - IDB_GH3_GREEN][controller]->GetLabel(); return m_Button_GH3[id - IDB_GH3_GREEN][m_Page]->GetLabel();
return wxString(); return wxString();
} }
// Configure button mapping // Configure button mapping
// Wait for button press // Wait for button press
/* Loop or timer: There are basically two ways to do this. With a while() or /* 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 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 that there is no way to stop it if the user should select to configure
@ -378,13 +125,11 @@ void WiimotePadConfigDialog::GetButtons(wxCommandEvent& event)
void WiimotePadConfigDialog::DoGetButtons(int _GetId) void WiimotePadConfigDialog::DoGetButtons(int _GetId)
{ {
// Collect the starting values // Collect the starting values
// Get the current controller // Get the current controller
int Controller = Page; int PadID = WiiMoteEmu::WiiMapping[m_Page].ID;
int PadID = WiiMoteEmu::PadMapping[Controller].ID;
// Get the controller and trigger type // Get the controller and trigger type
int TriggerType = WiiMoteEmu::PadMapping[Controller].triggertype; int TriggerType = WiiMoteEmu::WiiMapping[m_Page].TriggerType;
// Collect the accepted buttons for this slot // Collect the accepted buttons for this slot
bool LeftRight = (_GetId == IDB_TRIGGER_L || _GetId == IDB_TRIGGER_R); bool LeftRight = (_GetId == IDB_TRIGGER_L || _GetId == IDB_TRIGGER_R);
@ -399,10 +144,9 @@ void WiimotePadConfigDialog::DoGetButtons(int _GetId)
bool Hat = (_GetId >= IDB_WM_A && _GetId <= IDB_GH3_STRUM_DOWN); bool Hat = (_GetId >= IDB_WM_A && _GetId <= IDB_GH3_STRUM_DOWN);
bool NoTriggerFilter = g_Config.bNoTriggerFilter; bool NoTriggerFilter = false;
// Values used in this function // Values used in this function
char format[128];
int Seconds = 4; // Seconds to wait for int Seconds = 4; // Seconds to wait for
int TimesPerSecond = 40; // How often to run the check int TimesPerSecond = 40; // How often to run the check
@ -434,14 +178,13 @@ void WiimotePadConfigDialog::DoGetButtons(int _GetId)
#endif #endif
DEBUG_LOG(WIIMOTE, "Timer Started: Pad:%i _GetId:%i " DEBUG_LOG(WIIMOTE, "Timer Started: Pad:%i _GetId:%i "
"Allowed input is Axis:%i LeftRight:%i XInput:%i Button:%i Hat:%i", "Allowed input is Axis:%i LeftRight:%i XInput:%i Button:%i Hat:%i",
WiiMoteEmu::PadMapping[Controller].ID, _GetId, WiiMoteEmu::WiiMapping[m_Page].ID, _GetId,
Axis, LeftRight, XInput, Button, Hat); Axis, LeftRight, XInput, Button, Hat);
} }
// Check for buttons // Check for buttons
// If there is a timer we should not create a new one // If there is a timer we should not create a new one
else if (WiiMoteEmu::NumGoodPads >0) else if (WiiMoteEmu::NumGoodPads > 0)
{ {
InputCommon::GetButton( InputCommon::GetButton(
WiiMoteEmu::joyinfo[PadID].joy, PadID, WiiMoteEmu::joyinfo[PadID].NumButtons, WiiMoteEmu::joyinfo[PadID].NumAxes, WiiMoteEmu::joyinfo[PadID].NumHats, WiiMoteEmu::joyinfo[PadID].joy, PadID, WiiMoteEmu::joyinfo[PadID].NumButtons, WiiMoteEmu::joyinfo[PadID].NumAxes, WiiMoteEmu::joyinfo[PadID].NumHats,
@ -450,28 +193,24 @@ void WiimotePadConfigDialog::DoGetButtons(int _GetId)
} }
// Process results // Process results
// Count each time // Count each time
GetButtonWaitingTimer++; GetButtonWaitingTimer++;
// This is run every second // This is run every second
if(GetButtonWaitingTimer % TimesPerSecond == 0) if (GetButtonWaitingTimer % TimesPerSecond == 0)
{ {
// Current time // Current time
int TmpTime = Seconds - (GetButtonWaitingTimer / TimesPerSecond); int TmpTime = Seconds - (GetButtonWaitingTimer / TimesPerSecond);
// Update text // Update text
sprintf(format, "[ %d ]", TmpTime); SetButtonText(_GetId, wxString::Format(wxT("[ %d ]"), TmpTime));
SetButtonText(_GetId, format);
} }
// Time's up // Time's up
if( (GetButtonWaitingTimer / TimesPerSecond) >= Seconds ) if (GetButtonWaitingTimer / TimesPerSecond >= Seconds)
{ {
Stop = true; Stop = true;
// Revert back to old label // Revert back to old label
SetButtonText(_GetId, OldLabel.ToAscii()); SetButtonText(_GetId, OldLabel);
} }
// If we got a button // If we got a button
@ -488,32 +227,24 @@ void WiimotePadConfigDialog::DoGetButtons(int _GetId)
else if (value & SDL_HAT_RIGHT) pressed = 0x0100 + 0x0010 * pressed + SDL_HAT_RIGHT; else if (value & SDL_HAT_RIGHT) pressed = 0x0100 + 0x0010 * pressed + SDL_HAT_RIGHT;
else pressed = -1; else pressed = -1;
} }
if (_GetId >= IDB_WM_A && _GetId <= IDB_GH3_STRUM_DOWN) if (IDB_WM_A <= _GetId && _GetId <= IDB_GH3_STRUM_DOWN)
{ {
// Better make the pad button code far from virtual key code // Better make the pad button code far from virtual key code
SaveKeyboardMapping(Page, ClickedButton->GetId(), 0x1000 + pressed); SaveButtonMapping(_GetId, 0x1000 + pressed);
sprintf(format, "PAD: %d", pressed); SetButtonText(_GetId, wxString::Format(wxT("PAD: %d"), pressed));
} }
else else if (IDB_ANALOG_LEFT_X <= _GetId && _GetId <= IDB_TRIGGER_R)
{ {
/* Update the button mapping for all slots that use this device. (It SaveButtonMapping(_GetId, pressed);
doesn't make sense to have several slots controlled by the same SetButtonText(_GetId, wxString::Format(wxT("%d"), pressed));
device, but several DirectInput instances of different but identical
devices may possible have the same id, I don't know. So we have to
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 // Stop the timer
if(Stop) if(Stop)
{ {
DEBUG_LOG(WIIMOTE, "Timer Stopped for Pad:%i _GetId:%i", DEBUG_LOG(WIIMOTE, "Timer Stopped for Pad:%i _GetId:%i",
WiiMoteEmu::PadMapping[Controller].ID, _GetId); WiiMoteEmu::WiiMapping[Controller].ID, _GetId);
m_ButtonMappingTimer->Stop(); m_ButtonMappingTimer->Stop();
GetButtonWaitingTimer = 0; GetButtonWaitingTimer = 0;
@ -525,85 +256,64 @@ void WiimotePadConfigDialog::DoGetButtons(int _GetId)
if(KeyPressed == -1) if(KeyPressed == -1)
{ {
// Update text // Update text
SetButtonTextAll(_GetId, (char *)"PAD: -1"); SetButtonText(_GetId, wxString(wxT("PAD: -1")));
// Notify the user // Notify the user
wxMessageBox(wxString::Format( wxMessageBox(wxString::Format(
wxT("You selected a key with a to low key code (%i), please") wxT("You selected a key with a to low key code (%i), please")
wxT(" select another key with a higher key code."), pressed) wxT(" select another key with a higher key code."), pressed)
, wxT("Notice"), wxICON_INFORMATION); , wxT("Notice"), wxICON_INFORMATION);
} }
// Debugging
/*
DEBUG_LOG(WIIMOTE, "Change: %i %i %i %i '%s' '%s' '%s' '%s'",
WiiMoteEmu::PadMapping[0].halfpress, WiiMoteEmu::PadMapping[1].halfpress, WiiMoteEmu::PadMapping[2].halfpress, WiiMoteEmu::PadMapping[3].halfpress,
m_JoyButtonHalfpress[0]->GetValue().c_str(), m_JoyButtonHalfpress[1]->GetValue().c_str(), m_JoyButtonHalfpress[2]->GetValue().c_str(), m_JoyButtonHalfpress[3]->GetValue().c_str()
);*/
} }
// Show current input status
// Convert the 0x8000 range values to BoxW and BoxH for the plot // Convert the 0x8000 range values to BoxW and BoxH for the plot
void WiimotePadConfigDialog::Convert2Box(int &x) void WiimotePadConfigDialog::Convert2Box(int &x)
{ {
// Border adjustment // Border adjustment
int BoxW_ = BoxW - 2; int BoxH_ = BoxH - 2; int BoxW_ = BoxW - 2; int BoxH_ = BoxH - 2;
// Convert values // Convert values
x = (BoxW_ / 2) + (x * BoxW_ / (32767 * 2)); x = (BoxW_ / 2) + (x * BoxW_ / (32767 * 2));
} }
// Update the input status boxes // Update the input status boxes
void WiimotePadConfigDialog::PadGetStatus() void WiimotePadConfigDialog::UpdatePadInfo(wxTimerEvent& WXUNUSED(event))
{ {
//DEBUG_LOG(WIIMOTE, "SDL_WasInit: %i", SDL_WasInit(0)); //DEBUG_LOG(WIIMOTE, "SDL_WasInit: %i", SDL_WasInit(0));
/* Return if it's not enabled or not detected. The ID should never be less than zero here, /* Return if it's not enabled or not detected. The ID should never be less than zero here,
it can only be that because of a manual ini file change, but we make that check anway. */ it can only be that because of a manual ini file change, but we make that check anway. */
if(!WiiMoteEmu::PadMapping[Page].enabled if (WiiMoteEmu::WiiMapping[m_Page].ID < 0 || WiiMoteEmu::WiiMapping[m_Page].ID >= WiiMoteEmu::NumGoodPads)
|| WiiMoteEmu::PadMapping[Page].ID < 0
|| WiiMoteEmu::PadMapping[Page].ID >= SDL_NumJoysticks()
)
{ {
m_tStatusLeftIn[Page]->SetLabel(wxT("Not connected")); m_tStatusLeftIn[m_Page]->SetLabel(wxT("Not connected"));
m_tStatusLeftOut[Page]->SetLabel(wxT("Not connected")); m_tStatusLeftOut[m_Page]->SetLabel(wxT("Not connected"));
m_tStatusRightIn[Page]->SetLabel(wxT("Not connected")); m_tStatusRightIn[m_Page]->SetLabel(wxT("Not connected"));
m_tStatusRightOut[Page]->SetLabel(wxT("Not connected")); m_tStatusRightOut[m_Page]->SetLabel(wxT("Not connected"));
m_TriggerStatusL[Page]->SetLabel(wxT("000")); m_TriggerStatusL[m_Page]->SetLabel(wxT("000"));
m_TriggerStatusR[Page]->SetLabel(wxT("000")); m_TriggerStatusR[m_Page]->SetLabel(wxT("000"));
return; return;
} }
// Get physical device status
int PhysicalDevice = WiiMoteEmu::PadMapping[Page].ID;
int TriggerType = WiiMoteEmu::PadMapping[Page].triggertype;
// Check that Dolphin is in focus, otherwise don't update the pad status // Check that Dolphin is in focus, otherwise don't update the pad status
//if (IsFocus()) //if (IsFocus())
WiiMoteEmu::GetJoyState(WiiMoteEmu::PadState[Page], WiiMoteEmu::PadMapping[Page], Page, WiiMoteEmu::joyinfo.at(WiiMoteEmu::PadMapping[Page].ID).NumButtons); WiiMoteEmu::GetAxisState(WiiMoteEmu::WiiMapping[m_Page]);
// Analog stick // Analog stick
// Get original values // Get original values
int main_x = WiiMoteEmu::PadState[Page].Axis.Lx; int main_x = WiiMoteEmu::WiiMapping[m_Page].AxisState.Lx;
int main_y = WiiMoteEmu::PadState[Page].Axis.Ly; int main_y = WiiMoteEmu::WiiMapping[m_Page].AxisState.Ly;
int right_x = WiiMoteEmu::PadState[Page].Axis.Rx; int right_x = WiiMoteEmu::WiiMapping[m_Page].AxisState.Rx;
int right_y = WiiMoteEmu::PadState[Page].Axis.Ry; int right_y = WiiMoteEmu::WiiMapping[m_Page].AxisState.Ry;
// Get adjusted values // Get adjusted values
int main_x_after = main_x, main_y_after = main_y; int main_x_after = main_x, main_y_after = main_y;
int right_x_after = right_x, right_y_after = right_y; int right_x_after = right_x, right_y_after = right_y;
// Produce square // Produce square
if(WiiMoteEmu::PadMapping[Page].bCircle2Square) if(WiiMoteEmu::WiiMapping[m_Page].bCircle2Square)
{ InputCommon::Square2Circle(main_x_after, main_y_after, 0, WiiMoteEmu::WiiMapping[m_Page].Diagonal, true);
InputCommon::Square2Circle(main_x_after, main_y_after, Page, WiiMoteEmu::PadMapping[Page].SDiagonal, true);
}
// Check dead zone // Check dead zone
float DeadZoneLeft = (float)WiiMoteEmu::PadMapping[Page].DeadZoneL / 100.0; float DeadZoneLeft = (float)WiiMoteEmu::WiiMapping[m_Page].DeadZoneL / 100.0;
float DeadZoneRight = (float)WiiMoteEmu::PadMapping[Page].DeadZoneR / 100.0; float DeadZoneRight = (float)WiiMoteEmu::WiiMapping[m_Page].DeadZoneR / 100.0;
if (InputCommon::IsDeadZone(DeadZoneLeft, main_x_after, main_y_after)) if (InputCommon::IsDeadZone(DeadZoneLeft, main_x_after, main_y_after))
{ {
main_x_after = 0; main_x_after = 0;
@ -643,63 +353,34 @@ void WiimotePadConfigDialog::PadGetStatus()
float f_Rx_aft = right_x_after / 32767.0; float f_Rx_aft = right_x_after / 32767.0;
float f_Ry_aft = right_y_after / 32767.0; float f_Ry_aft = right_y_after / 32767.0;
m_tStatusLeftIn[Page]->SetLabel(wxString::Format( m_tStatusLeftIn[m_Page]->SetLabel(wxString::Format(wxT("x:%1.2f y:%1.2f"), f_x, f_y ));
wxT("x:%1.2f y:%1.2f"), f_x, f_y m_tStatusLeftOut[m_Page]->SetLabel(wxString::Format(wxT("x:%1.2f y:%1.2f"), f_x_aft, f_y_aft));
)); m_tStatusRightIn[m_Page]->SetLabel(wxString::Format(wxT("x:%1.2f y:%1.2f"), f_Rx, f_Ry));
m_tStatusLeftOut[Page]->SetLabel(wxString::Format( m_tStatusRightOut[m_Page]->SetLabel(wxString::Format(wxT("x:%1.2f y:%1.2f"), f_Rx_aft, f_Ry_aft));
wxT("x:%1.2f y:%1.2f"), f_x_aft, f_y_aft
));
m_tStatusRightIn[Page]->SetLabel(wxString::Format(
wxT("x:%1.2f y:%1.2f"), f_Rx, f_Ry
));
m_tStatusRightOut[Page]->SetLabel(wxString::Format(
wxT("x:%1.2f y:%1.2f"), f_Rx_aft, f_Ry_aft
));
// Adjust the values for the plot // Adjust the values for the plot
Convert2Box(main_x); Convert2Box(main_y); Convert2Box(main_x); Convert2Box(main_y);
Convert2Box(right_x); Convert2Box(right_y); Convert2Box(right_x); Convert2Box(right_y);
Convert2Box(main_x_after); Convert2Box(main_y_after); Convert2Box(main_x_after); Convert2Box(main_y_after);
Convert2Box(right_x_after); Convert2Box(right_y_after); Convert2Box(right_x_after); Convert2Box(right_y_after);
// Adjust the dot // Adjust the dot
m_bmpDotLeftIn[Page]->SetPosition(wxPoint(main_x, main_y)); m_bmpDotLeftIn[m_Page]->SetPosition(wxPoint(main_x, main_y));
m_bmpDotLeftOut[Page]->SetPosition(wxPoint(main_x_after, main_y_after)); m_bmpDotLeftOut[m_Page]->SetPosition(wxPoint(main_x_after, main_y_after));
m_bmpDotRightIn[Page]->SetPosition(wxPoint(right_x, right_y)); m_bmpDotRightIn[m_Page]->SetPosition(wxPoint(right_x, right_y));
m_bmpDotRightOut[Page]->SetPosition(wxPoint(right_x_after, right_y_after)); m_bmpDotRightOut[m_Page]->SetPosition(wxPoint(right_x_after, right_y_after));
// Get the trigger values // Get the trigger values
int TriggerLeft = WiiMoteEmu::PadState[Page].Axis.Tl; int TriggerLeft = WiiMoteEmu::WiiMapping[m_Page].AxisState.Tl;
int TriggerRight = WiiMoteEmu::PadState[Page].Axis.Tr; int TriggerRight = WiiMoteEmu::WiiMapping[m_Page].AxisState.Tr;
// Convert the triggers values // Convert the triggers values
if (WiiMoteEmu::PadMapping[Page].triggertype == InputCommon::CTL_TRIGGER_SDL) if (WiiMoteEmu::WiiMapping[m_Page].TriggerType == InputCommon::CTL_TRIGGER_SDL)
{ {
TriggerLeft = InputCommon::Pad_Convert(TriggerLeft); TriggerLeft = InputCommon::Pad_Convert(TriggerLeft);
TriggerRight = InputCommon::Pad_Convert(TriggerRight); TriggerRight = InputCommon::Pad_Convert(TriggerRight);
} }
m_TriggerStatusL[Page]->SetLabel(wxString::Format( m_TriggerStatusL[m_Page]->SetLabel(wxString::Format(wxT("%03i"), TriggerLeft));
wxT("%03i"), TriggerLeft)); m_TriggerStatusR[m_Page]->SetLabel(wxString::Format(wxT("%03i"), TriggerRight));
m_TriggerStatusR[Page]->SetLabel(wxString::Format(
wxT("%03i"), TriggerRight));
} }
// Populate the advanced tab
void WiimotePadConfigDialog::UpdatePad(wxTimerEvent& WXUNUSED(event))
{
// Show the current status
/*
#ifdef SHOW_PAD_STATUS
m_pStatusBar->SetLabel(wxString::Format(
"%s", ShowStatus(notebookpage).c_str()
));
#endif*/
//LogMsg("Abc%s\n", ShowStatus(notebookpage).c_str());
PadGetStatus();
}

View File

@ -34,9 +34,10 @@ BEGIN_EVENT_TABLE(WiimotePadConfigDialog,wxDialog)
EVT_CLOSE(WiimotePadConfigDialog::OnClose) EVT_CLOSE(WiimotePadConfigDialog::OnClose)
EVT_BUTTON(ID_CLOSE, WiimotePadConfigDialog::CloseClick) EVT_BUTTON(ID_CLOSE, WiimotePadConfigDialog::CloseClick)
// EVT_BUTTON(ID_APPLY, WiimotePadConfigDialog::CloseClick) // EVT_BUTTON(ID_APPLY, WiimotePadConfigDialog::CloseClick)
EVT_NOTEBOOK_PAGE_CHANGED(ID_NOTEBOOK, WiimotePadConfigDialog::NotebookPageChanged)
EVT_TIMER(IDTM_BUTTON, WiimotePadConfigDialog::OnButtonTimer) EVT_TIMER(IDTM_BUTTON, WiimotePadConfigDialog::OnButtonTimer)
EVT_TIMER(IDTM_UPDATE_PAD, WiimotePadConfigDialog::UpdatePad) EVT_TIMER(IDTM_UPDATE_PAD, WiimotePadConfigDialog::UpdatePadInfo)
EVT_COMBOBOX(IDC_JOYNAME, WiimotePadConfigDialog::GeneralSettingsChanged) EVT_COMBOBOX(IDC_JOYNAME, WiimotePadConfigDialog::GeneralSettingsChanged)
EVT_CHECKBOX(IDC_RUMBLE, WiimotePadConfigDialog::GeneralSettingsChanged) EVT_CHECKBOX(IDC_RUMBLE, WiimotePadConfigDialog::GeneralSettingsChanged)
@ -125,18 +126,22 @@ WiimotePadConfigDialog::WiimotePadConfigDialog(wxWindow *parent, wxWindowID id,
GetButtonWaitingID = 0; GetButtonWaitingID = 0;
GetButtonWaitingTimer = 0; GetButtonWaitingTimer = 0;
// Start the permanent timer if (WiiMoteEmu::NumGoodPads)
const int TimesPerSecond = 10; {
m_UpdatePadTimer->Start(1000 / TimesPerSecond); // Start the permanent timer
const int TimesPerSecond = 10;
m_UpdatePadTimer->Start(1000 / TimesPerSecond);
}
#endif #endif
ControlsCreated = false; ControlsCreated = false;
Page = 0;
//g_Config.Load(); //g_Config.Load();
CreatePadGUIControls(); CreatePadGUIControls();
//SetBackgroundColour(m_Notebook->GetBackgroundColour());
m_Page = g_Config.CurrentPage;
m_Notebook->ChangeSelection(m_Page);
// Set control values // Set control values
UpdateGUI(); UpdateGUI();
@ -159,6 +164,19 @@ WiimotePadConfigDialog::~WiimotePadConfigDialog()
} }
} }
// Save keyboard key mapping
void WiimotePadConfigDialog::SaveButtonMapping(int Id, int Key)
{
if (IDB_ANALOG_LEFT_X <= Id && Id <= IDB_TRIGGER_R)
{
WiiMoteEmu::WiiMapping[m_Page].AxisMapping.Code[Id - IDB_ANALOG_LEFT_X] = Key;
}
else if (IDB_WM_A <= Id && Id <= IDB_GH3_STRUM_DOWN)
{
WiiMoteEmu::WiiMapping[m_Page].Button[Id - IDB_WM_A] = Key;
}
}
void WiimotePadConfigDialog::OnKeyDown(wxKeyEvent& event) void WiimotePadConfigDialog::OnKeyDown(wxKeyEvent& event)
{ {
event.Skip(); event.Skip();
@ -173,8 +191,8 @@ void WiimotePadConfigDialog::OnKeyDown(wxKeyEvent& event)
// Allow the escape key to set a blank key // Allow the escape key to set a blank key
if (g_Pressed == WXK_ESCAPE) if (g_Pressed == WXK_ESCAPE)
{ {
SaveKeyboardMapping(Page, ClickedButton->GetId(), -1); SaveButtonMapping(ClickedButton->GetId(), -1);
SetButtonText(ClickedButton->GetId(), ""); SetButtonText(ClickedButton->GetId(), wxString());
} }
else else
{ {
@ -188,10 +206,10 @@ void WiimotePadConfigDialog::OnKeyDown(wxKeyEvent& event)
// Use the left and right specific keys instead of the common ones // Use the left and right specific keys instead of the common ones
if (i == VK_SHIFT || i == VK_CONTROL || i == VK_MENU) continue; if (i == VK_SHIFT || i == VK_CONTROL || i == VK_MENU) continue;
// Update the button label // Update the button label
strcpy(keyStr, InputCommon::VKToString(i).c_str()); SetButtonText(ClickedButton->GetId(),
SetButtonText(ClickedButton->GetId(), keyStr); wxString::FromAscii(InputCommon::VKToString(i).c_str()));
// Save the setting // Save the setting
SaveKeyboardMapping(Page, ClickedButton->GetId(), i); SaveButtonMapping(ClickedButton->GetId(), i);
break; break;
} }
} }
@ -199,7 +217,7 @@ void WiimotePadConfigDialog::OnKeyDown(wxKeyEvent& event)
int XKey = InputCommon::wxCharCodeWXToX(g_Pressed); int XKey = InputCommon::wxCharCodeWXToX(g_Pressed);
InputCommon::XKeyToString(XKey, keyStr); InputCommon::XKeyToString(XKey, keyStr);
SetButtonText(ClickedButton->GetId(), keyStr); SetButtonText(ClickedButton->GetId(), keyStr);
SaveKeyboardMapping(Page, ClickedButton->GetId(), XKey); SaveKeyboardMapping(m_Page, ClickedButton->GetId(), XKey);
#endif #endif
} }
m_ButtonMappingTimer->Stop(); m_ButtonMappingTimer->Stop();
@ -223,20 +241,20 @@ void WiimotePadConfigDialog::OnButtonClick(wxCommandEvent& event)
ClickedButton = (wxButton *)event.GetEventObject(); ClickedButton = (wxButton *)event.GetEventObject();
// Save old label so we can revert back // Save old label so we can revert back
OldLabel = ClickedButton->GetLabel(); OldLabel = ClickedButton->GetLabel();
ClickedButton->SetWindowStyle(wxWANTS_CHARS); //ClickedButton->SetWindowStyle(wxWANTS_CHARS);
ClickedButton->SetLabel(wxT("<Press Key>")); ClickedButton->SetLabel(wxT("<Press Key>"));
DoGetButtons(ClickedButton->GetId()); DoGetButtons(ClickedButton->GetId());
} }
void WiimotePadConfigDialog::OnClose(wxCloseEvent& event) void WiimotePadConfigDialog::OnClose(wxCloseEvent& event)
{ {
if (m_UpdatePadTimer) if (m_UpdatePadTimer)
m_UpdatePadTimer->Stop(); m_UpdatePadTimer->Stop();
if (m_ButtonMappingTimer) if (m_ButtonMappingTimer)
m_ButtonMappingTimer->Stop(); m_ButtonMappingTimer->Stop();
SaveButtonMappingAll(Page); g_Config.CurrentPage = m_Page;
EndModal(wxID_CLOSE); EndModal(wxID_CLOSE);
} }
@ -248,40 +266,10 @@ void WiimotePadConfigDialog::CloseClick(wxCommandEvent& event)
Close(); Close();
break; break;
case ID_APPLY: case ID_APPLY:
SaveButtonMappingAll(Page);
break; break;
} }
} }
void WiimotePadConfigDialog::DoSave(bool ChangePad, int Slot)
{
// Replace "" with "-1" before we are saving
ToBlank(false);
if(ChangePad)
{
// Since we are selecting the pad to save to by the Id we can't update it when we change the pad
for(int i = 0; i < MAX_WIIMOTES; i++)
SaveButtonMapping(i, true);
// Save the settings for the current pad
// g_Config.Save(Slot);
// Now we can update the ID
WiiMoteEmu::PadMapping[Page].ID = m_Joyname[Page]->GetSelection();
}
else
{
// Update PadMapping[] from the GUI controls
for(int i = 0; i < MAX_WIIMOTES; i++)
SaveButtonMapping(i);
// g_Config.Save(Slot);
}
// Then change it back to ""
ToBlank();
DEBUG_LOG(WIIMOTE, "WiiMoteEmu::PadMapping[%i].ID = %i", Page, m_Joyname[Page]->GetSelection());
}
// Bitmap box and dot // Bitmap box and dot
wxBitmap WiimotePadConfigDialog::CreateBitmap() wxBitmap WiimotePadConfigDialog::CreateBitmap()
{ {
@ -357,7 +345,7 @@ void WiimotePadConfigDialog::CreatePadGUIControls()
} }
else else
{ {
StrJoyname.Add(wxString::FromAscii("<No Gamepad Detected>")); StrJoyname.Add(wxT("<No Gamepad Detected>"));
} }
wxArrayString TextDeadZone; wxArrayString TextDeadZone;
@ -377,11 +365,10 @@ void WiimotePadConfigDialog::CreatePadGUIControls()
// The tilt list // The tilt list
wxArrayString StrTilt; wxArrayString StrTilt;
StrTilt.Add(wxString::FromAscii("<Off>")); StrTilt.Add(wxT("Keyboard"));
StrTilt.Add(wxString::FromAscii("Keyboard")); StrTilt.Add(wxT("Analog 1"));
StrTilt.Add(wxString::FromAscii("Analog 1")); StrTilt.Add(wxT("Analog 2"));
StrTilt.Add(wxString::FromAscii("Analog 2")); StrTilt.Add(wxT("Triggers"));
StrTilt.Add(wxString::FromAscii("Triggers"));
// The range is in degrees and are set at even 5 degrees values // The range is in degrees and are set at even 5 degrees values
wxArrayString StrTiltRangeRoll, StrTiltRangePitch; wxArrayString StrTiltRangeRoll, StrTiltRangePitch;
@ -392,24 +379,24 @@ void WiimotePadConfigDialog::CreatePadGUIControls()
// The Trigger type list // The Trigger type list
wxArrayString StrTriggerType; wxArrayString StrTriggerType;
StrTriggerType.Add(wxString::FromAscii("SDL")); // -0x8000 to 0x7fff StrTriggerType.Add(wxT("SDL")); // -0x8000 to 0x7fff
StrTriggerType.Add(wxString::FromAscii("XInput")); // 0x00 to 0xff StrTriggerType.Add(wxT("XInput")); // 0x00 to 0xff
// The Nunchuck stick list // The Nunchuck stick list
wxArrayString StrNunchuck; wxArrayString StrNunchuck;
StrNunchuck.Add(wxString::FromAscii("Keyboard")); StrNunchuck.Add(wxT("Keyboard"));
StrNunchuck.Add(wxString::FromAscii("Analog 1")); StrNunchuck.Add(wxT("Analog 1"));
StrNunchuck.Add(wxString::FromAscii("Analog 2")); StrNunchuck.Add(wxT("Analog 2"));
// The Classic Controller triggers list // The Classic Controller triggers list
wxArrayString StrCcTriggers; wxArrayString StrCcTriggers;
StrCcTriggers.Add(wxString::FromAscii("Keyboard")); StrCcTriggers.Add(wxT("Keyboard"));
StrCcTriggers.Add(wxString::FromAscii("Triggers")); StrCcTriggers.Add(wxT("Triggers"));
// GH3 stick list // GH3 stick list
wxArrayString StrAnalogArray; wxArrayString StrAnalogArray;
StrAnalogArray.Add(wxString::FromAscii("Analog 1")); StrAnalogArray.Add(wxT("Analog 1"));
StrAnalogArray.Add(wxString::FromAscii("Analog 2")); StrAnalogArray.Add(wxT("Analog 2"));
static const wxChar* anText[] = static const wxChar* anText[] =
{ {
@ -579,21 +566,17 @@ void WiimotePadConfigDialog::CreatePadGUIControls()
m_tTiltTypeNC[i] = new wxStaticText(m_Controller[i], wxID_ANY, wxT("Nunchuck")); m_tTiltTypeNC[i] = new wxStaticText(m_Controller[i], wxID_ANY, wxT("Nunchuck"));
m_TiltTypeWM[i] = new wxComboBox(m_Controller[i], IDC_TILT_TYPE_WM, StrTilt[0], wxDefaultPosition, wxSize(70, -1), StrTilt, wxCB_READONLY); m_TiltTypeWM[i] = new wxComboBox(m_Controller[i], IDC_TILT_TYPE_WM, StrTilt[0], wxDefaultPosition, wxSize(70, -1), StrTilt, wxCB_READONLY);
m_TiltTypeWM[i]->SetSelection(g_Config.Tilt.TypeWM);
m_TiltTypeWM[i]->SetToolTip(wxT("Control Wiimote tilting by keyboard or stick or trigger")); m_TiltTypeWM[i]->SetToolTip(wxT("Control Wiimote tilting by keyboard or stick or trigger"));
m_TiltTypeNC[i] = new wxComboBox(m_Controller[i], IDC_TILT_TYPE_NC, StrTilt[0], wxDefaultPosition, wxSize(70, -1), StrTilt, wxCB_READONLY); m_TiltTypeNC[i] = new wxComboBox(m_Controller[i], IDC_TILT_TYPE_NC, StrTilt[0], wxDefaultPosition, wxSize(70, -1), StrTilt, wxCB_READONLY);
m_TiltTypeNC[i]->SetSelection(g_Config.Tilt.TypeNC);
m_TiltTypeNC[i]->SetToolTip(wxT("Control Nunchuck tilting by keyboard or stick or trigger")); m_TiltTypeNC[i]->SetToolTip(wxT("Control Nunchuck tilting by keyboard or stick or trigger"));
m_TiltTextRoll[i] = new wxStaticText(m_Controller[i], wxID_ANY, wxT("Roll Left/Right")); m_TiltTextRoll[i] = new wxStaticText(m_Controller[i], wxID_ANY, wxT("Roll Left/Right"));
m_TiltTextPitch[i] = new wxStaticText(m_Controller[i], wxID_ANY, wxT("Pitch Up/Down")); m_TiltTextPitch[i] = new wxStaticText(m_Controller[i], wxID_ANY, wxT("Pitch Up/Down"));
m_TiltComboRangeRoll[i] = new wxComboBox(m_Controller[i], IDC_TILT_ROLL, StrTiltRangeRoll[0], wxDefaultPosition, wxSize(50, -1), StrTiltRangeRoll, wxCB_READONLY); m_TiltComboRangeRoll[i] = new wxComboBox(m_Controller[i], IDC_TILT_ROLL, StrTiltRangeRoll[0], wxDefaultPosition, wxSize(50, -1), StrTiltRangeRoll, wxCB_READONLY);
m_TiltComboRangeRoll[i]->SetValue(wxString::Format(wxT("%i"), g_Config.Tilt.Range.Roll));
m_TiltComboRangeRoll[i]->SetToolTip(wxT("The maximum Left/Righ Roll in degrees")); m_TiltComboRangeRoll[i]->SetToolTip(wxT("The maximum Left/Righ Roll in degrees"));
m_TiltComboRangePitch[i] = new wxComboBox(m_Controller[i], IDC_TILT_PITCH, StrTiltRangePitch[0], wxDefaultPosition, wxSize(50, -1), StrTiltRangePitch, wxCB_READONLY); m_TiltComboRangePitch[i] = new wxComboBox(m_Controller[i], IDC_TILT_PITCH, StrTiltRangePitch[0], wxDefaultPosition, wxSize(50, -1), StrTiltRangePitch, wxCB_READONLY);
m_TiltComboRangePitch[i]->SetValue(wxString::Format(wxT("%i"), g_Config.Tilt.Range.Pitch));
m_TiltComboRangePitch[i]->SetToolTip(wxT("The maximum Up/Down Pitch in degrees")); m_TiltComboRangePitch[i]->SetToolTip(wxT("The maximum Up/Down Pitch in degrees"));
m_TiltRollSwing[i] = new wxCheckBox(m_Controller[i], IDC_TILT_ROLL_SWING, wxT("Swing")); m_TiltRollSwing[i] = new wxCheckBox(m_Controller[i], IDC_TILT_ROLL_SWING, wxT("Swing"));
m_TiltRollSwing[i]->SetToolTip(wxT("Emulate Swing Left/Right instead of Roll Left/Right")); m_TiltRollSwing[i]->SetToolTip(wxT("Emulate Swing Left/Right instead of Roll Left/Right"));
@ -634,10 +617,10 @@ void WiimotePadConfigDialog::CreatePadGUIControls()
// Stick Status Panels // Stick Status Panels
m_tStatusLeftIn[i] = new wxStaticText(m_Controller[i], wxID_ANY, wxT("In")); m_tStatusLeftIn[i] = new wxStaticText(m_Controller[i], wxID_ANY, wxT("Not connected"));
m_tStatusLeftOut[i] = new wxStaticText(m_Controller[i], wxID_ANY, wxT("Out")); m_tStatusLeftOut[i] = new wxStaticText(m_Controller[i], wxID_ANY, wxT("Not connected"));
m_tStatusRightIn[i] = new wxStaticText(m_Controller[i], wxID_ANY, wxT("In")); m_tStatusRightIn[i] = new wxStaticText(m_Controller[i], wxID_ANY, wxT("Not connected"));
m_tStatusRightOut[i] = new wxStaticText(m_Controller[i], wxID_ANY, wxT("Out")); m_tStatusRightOut[i] = new wxStaticText(m_Controller[i], wxID_ANY, wxT("Not connected"));
m_pLeftInStatus[i] = new wxPanel(m_Controller[i], wxID_ANY, wxDefaultPosition, wxDefaultSize); m_pLeftInStatus[i] = new wxPanel(m_Controller[i], wxID_ANY, wxDefaultPosition, wxDefaultSize);
m_bmpSquareLeftIn[i] = new wxStaticBitmap(m_pLeftInStatus[i], wxID_ANY, CreateBitmap(), wxDefaultPosition, wxDefaultSize); m_bmpSquareLeftIn[i] = new wxStaticBitmap(m_pLeftInStatus[i], wxID_ANY, CreateBitmap(), wxDefaultPosition, wxDefaultSize);
@ -676,12 +659,12 @@ void WiimotePadConfigDialog::CreatePadGUIControls()
m_gStickRight[i] = new wxStaticBoxSizer (wxHORIZONTAL, m_Controller[i], wxT("Analog 2 Status (In) (Out)")); m_gStickRight[i] = new wxStaticBoxSizer (wxHORIZONTAL, m_Controller[i], wxT("Analog 2 Status (In) (Out)"));
m_gStickRight[i]->Add(m_sGridStickRight[i], 0, (wxLEFT | wxRIGHT), 5); m_gStickRight[i]->Add(m_sGridStickRight[i], 0, (wxLEFT | wxRIGHT), 5);
// Trigger Status Panels // Trigger Status Panels
m_TriggerL[i]= new wxStaticText(m_Controller[i], wxID_ANY, wxT("Left: ")); m_TriggerL[i]= new wxStaticText(m_Controller[i], wxID_ANY, wxT("Left: "));
m_TriggerR[i]= new wxStaticText(m_Controller[i], wxID_ANY, wxT("Right: ")); m_TriggerR[i]= new wxStaticText(m_Controller[i], wxID_ANY, wxT("Right: "));
m_TriggerStatusL[i]= new wxStaticText(m_Controller[i], wxID_ANY, wxT("000"), wxDefaultPosition, wxDefaultSize, wxALIGN_RIGHT); m_TriggerStatusL[i]= new wxStaticText(m_Controller[i], wxID_ANY, wxT("000"), wxDefaultPosition, wxDefaultSize, wxALIGN_RIGHT);
m_TriggerStatusR[i]= new wxStaticText(m_Controller[i], wxID_ANY, wxT("000"), wxDefaultPosition, wxDefaultSize, wxALIGN_RIGHT); m_TriggerStatusR[i]= new wxStaticText(m_Controller[i], wxID_ANY, wxT("000"), wxDefaultPosition, wxDefaultSize, wxALIGN_RIGHT);
m_tTriggerSource[i]= new wxStaticText(m_Controller[i], wxID_ANY, wxT("Input Source")); m_tTriggerSource[i]= new wxStaticText(m_Controller[i], wxID_ANY, wxT("Trigger Source"));
m_TriggerType[i] = new wxComboBox(m_Controller[i], IDC_TRIGGER_TYPE, StrTriggerType[0], wxDefaultPosition, wxSize(70, -1), StrTriggerType, wxCB_READONLY); m_TriggerType[i] = new wxComboBox(m_Controller[i], IDC_TRIGGER_TYPE, StrTriggerType[0], wxDefaultPosition, wxSize(70, -1), StrTriggerType, wxCB_READONLY);
// Sizers // Sizers
@ -710,7 +693,7 @@ void WiimotePadConfigDialog::CreatePadGUIControls()
m_sAnalogMiddle[i] = new wxBoxSizer(wxVERTICAL); m_sAnalogMiddle[i] = new wxBoxSizer(wxVERTICAL);
m_sAnalogRight[i] = new wxBoxSizer(wxVERTICAL); m_sAnalogRight[i] = new wxBoxSizer(wxVERTICAL);
for (int x = 0; x < AN_CONTROLS; x++) for (int x = 0; x < 6; x++)
{ {
m_statictext_Analog[x][i] = new wxStaticText(m_Controller[i], wxID_ANY, anText[x]); m_statictext_Analog[x][i] = new wxStaticText(m_Controller[i], wxID_ANY, anText[x]);
m_Button_Analog[x][i] = new wxButton(m_Controller[i], x + IDB_ANALOG_LEFT_X, wxEmptyString, wxDefaultPosition, wxSize(BtW, BtH)); m_Button_Analog[x][i] = new wxButton(m_Controller[i], x + IDB_ANALOG_LEFT_X, wxEmptyString, wxDefaultPosition, wxSize(BtW, BtH));
@ -741,7 +724,7 @@ void WiimotePadConfigDialog::CreatePadGUIControls()
m_sWmVertLeft[i] = new wxBoxSizer(wxVERTICAL); m_sWmVertLeft[i] = new wxBoxSizer(wxVERTICAL);
m_sWmVertRight[i] = new wxBoxSizer(wxVERTICAL); m_sWmVertRight[i] = new wxBoxSizer(wxVERTICAL);
for (int x = 0; x < WM_CONTROLS; x++) for (int x = 0; x <= IDB_WM_SHAKE - IDB_WM_A; x++)
{ {
m_statictext_Wiimote[x][i] = new wxStaticText(m_Controller[i], wxID_ANY, wmText[x]); m_statictext_Wiimote[x][i] = new wxStaticText(m_Controller[i], wxID_ANY, wmText[x]);
m_Button_Wiimote[x][i] = new wxButton(m_Controller[i], x + IDB_WM_A, wxEmptyString, wxDefaultPosition, wxSize(BtW, BtH)); m_Button_Wiimote[x][i] = new wxButton(m_Controller[i], x + IDB_WM_A, wxEmptyString, wxDefaultPosition, wxSize(BtW, BtH));
@ -749,7 +732,7 @@ void WiimotePadConfigDialog::CreatePadGUIControls()
m_Sizer_Wiimote[x][i] = new wxBoxSizer(wxHORIZONTAL); m_Sizer_Wiimote[x][i] = new wxBoxSizer(wxHORIZONTAL);
m_Sizer_Wiimote[x][i]->Add(m_statictext_Wiimote[x][i], 0, (wxUP), 4); m_Sizer_Wiimote[x][i]->Add(m_statictext_Wiimote[x][i], 0, (wxUP), 4);
m_Sizer_Wiimote[x][i]->Add(m_Button_Wiimote[x][i], 0, (wxLEFT), 2); m_Sizer_Wiimote[x][i]->Add(m_Button_Wiimote[x][i], 0, (wxLEFT), 2);
if (x < 7 || x == WM_CONTROLS -1) // Make some balance if (x < 7 || x == IDB_WM_SHAKE - IDB_WM_A) // Make some balance
m_sWmVertLeft[i]->Add(m_Sizer_Wiimote[x][i], 0, wxALIGN_RIGHT | (wxLEFT | wxRIGHT | wxDOWN), 1); m_sWmVertLeft[i]->Add(m_Sizer_Wiimote[x][i], 0, wxALIGN_RIGHT | (wxLEFT | wxRIGHT | wxDOWN), 1);
else else
m_sWmVertRight[i]->Add(m_Sizer_Wiimote[x][i], 0, wxALIGN_RIGHT | (wxLEFT | wxRIGHT | wxDOWN), 1); m_sWmVertRight[i]->Add(m_Sizer_Wiimote[x][i], 0, wxALIGN_RIGHT | (wxLEFT | wxRIGHT | wxDOWN), 1);
@ -760,14 +743,13 @@ void WiimotePadConfigDialog::CreatePadGUIControls()
m_gWiimote[i]->Add(m_sWmVertRight[i], 0, (wxLEFT | wxRIGHT | wxDOWN), 1); m_gWiimote[i]->Add(m_sWmVertRight[i], 0, (wxLEFT | wxRIGHT | wxDOWN), 1);
// Extension Mapping // Extension Mapping
if(g_Config.iExtensionConnected == EXT_NUNCHUCK) if(WiiMoteEmu::WiiMapping[i].iExtensionConnected == WiiMoteEmu::EXT_NUNCHUCK)
{ {
// Stick controls // Stick controls
m_NunchuckTextStick[i] = new wxStaticText(m_Controller[i], wxID_ANY, wxT("Stick")); m_NunchuckTextStick[i] = new wxStaticText(m_Controller[i], wxID_ANY, wxT("Stick"));
m_NunchuckComboStick[i] = new wxComboBox(m_Controller[i], IDC_NUNCHUCK_STICK, StrNunchuck[0], wxDefaultPosition, wxSize(70, -1), StrNunchuck, wxCB_READONLY); m_NunchuckComboStick[i] = new wxComboBox(m_Controller[i], IDC_NUNCHUCK_STICK, StrNunchuck[0], wxDefaultPosition, wxSize(70, -1), StrNunchuck, wxCB_READONLY);
m_NunchuckComboStick[i]->SetSelection(g_Config.Nunchuck.Type);
for (int x = 0; x < NC_CONTROLS; x++) for (int x = 0; x <= IDB_NC_SHAKE - IDB_NC_Z; x++)
{ {
m_statictext_NunChuck[x][i] = new wxStaticText(m_Controller[i], wxID_ANY, ncText[x]); m_statictext_NunChuck[x][i] = new wxStaticText(m_Controller[i], wxID_ANY, ncText[x]);
m_Button_NunChuck[x][i] = new wxButton(m_Controller[i], x + IDB_NC_Z, wxEmptyString, wxDefaultPosition, wxSize(BtW, BtH)); m_Button_NunChuck[x][i] = new wxButton(m_Controller[i], x + IDB_NC_Z, wxEmptyString, wxDefaultPosition, wxSize(BtW, BtH));
@ -787,7 +769,7 @@ void WiimotePadConfigDialog::CreatePadGUIControls()
m_sNCVertRight[i]->Add(m_sNunchuckStick[i], 0, wxALIGN_RIGHT | (wxALL), 2); m_sNCVertRight[i]->Add(m_sNunchuckStick[i], 0, wxALIGN_RIGHT | (wxALL), 2);
m_sNCVertRight[i]->AddSpacer(2); m_sNCVertRight[i]->AddSpacer(2);
for (int x = IDB_NC_Z; x <= IDB_NC_SHAKE; x++) for (int x = IDB_NC_Z ; x <= IDB_NC_SHAKE; x++)
if (x < IDB_NC_ROLL_L) // Make some balance if (x < IDB_NC_ROLL_L) // Make some balance
m_sNCVertLeft[i]->Add(m_Sizer_NunChuck[x - IDB_NC_Z][i], 0, wxALIGN_RIGHT | (wxLEFT | wxRIGHT | wxDOWN), 1); m_sNCVertLeft[i]->Add(m_Sizer_NunChuck[x - IDB_NC_Z][i], 0, wxALIGN_RIGHT | (wxLEFT | wxRIGHT | wxDOWN), 1);
else else
@ -798,20 +780,17 @@ void WiimotePadConfigDialog::CreatePadGUIControls()
m_gNunchuck[i]->Add(m_sNCVertRight[i], 0, wxALIGN_RIGHT | (wxLEFT | wxRIGHT | wxDOWN), 1); m_gNunchuck[i]->Add(m_sNCVertRight[i], 0, wxALIGN_RIGHT | (wxLEFT | wxRIGHT | wxDOWN), 1);
} }
else if(g_Config.iExtensionConnected == EXT_CLASSIC_CONTROLLER) else if(WiiMoteEmu::WiiMapping[i].iExtensionConnected == WiiMoteEmu::EXT_CLASSIC_CONTROLLER)
{ {
// Stick controls // Stick controls
m_CcTextLeftStick[i] = new wxStaticText(m_Controller[i], wxID_ANY, wxT("Left stick")); m_CcTextLeftStick[i] = new wxStaticText(m_Controller[i], wxID_ANY, wxT("Left stick"));
m_CcComboLeftStick[i] = new wxComboBox(m_Controller[i], IDC_CC_LEFT_STICK, StrNunchuck[0], wxDefaultPosition, wxSize(70, -1), StrNunchuck, wxCB_READONLY); m_CcComboLeftStick[i] = new wxComboBox(m_Controller[i], IDC_CC_LEFT_STICK, StrNunchuck[0], wxDefaultPosition, wxSize(70, -1), StrNunchuck, wxCB_READONLY);
m_CcComboLeftStick[i]->SetSelection(g_Config.ClassicController.LType);
m_CcTextRightStick[i] = new wxStaticText(m_Controller[i], wxID_ANY, wxT("Right stick")); m_CcTextRightStick[i] = new wxStaticText(m_Controller[i], wxID_ANY, wxT("Right stick"));
m_CcComboRightStick[i] = new wxComboBox(m_Controller[i], IDC_CC_RIGHT_STICK, StrNunchuck[0], wxDefaultPosition, wxSize(70, -1), StrNunchuck, wxCB_READONLY); m_CcComboRightStick[i] = new wxComboBox(m_Controller[i], IDC_CC_RIGHT_STICK, StrNunchuck[0], wxDefaultPosition, wxSize(70, -1), StrNunchuck, wxCB_READONLY);
m_CcComboRightStick[i]->SetSelection(g_Config.ClassicController.RType);
m_CcTextTriggers[i] = new wxStaticText(m_Controller[i], wxID_ANY, wxT("Triggers")); m_CcTextTriggers[i] = new wxStaticText(m_Controller[i], wxID_ANY, wxT("Triggers"));
m_CcComboTriggers[i] = new wxComboBox(m_Controller[i], IDC_CC_TRIGGERS, StrCcTriggers[0], wxDefaultPosition, wxSize(70, -1), StrCcTriggers, wxCB_READONLY); m_CcComboTriggers[i] = new wxComboBox(m_Controller[i], IDC_CC_TRIGGERS, StrCcTriggers[0], wxDefaultPosition, wxSize(70, -1), StrCcTriggers, wxCB_READONLY);
m_CcComboTriggers[i]->SetSelection(g_Config.ClassicController.TType);
for (int x = 0; x < CC_CONTROLS; x++) for (int x = 0; x <= IDB_CC_RD - IDB_CC_A; x++)
{ {
m_statictext_Classic[x][i] = new wxStaticText(m_Controller[i], wxID_ANY, classicText[x]); m_statictext_Classic[x][i] = new wxStaticText(m_Controller[i], wxID_ANY, classicText[x]);
m_Button_Classic[x][i] = new wxButton(m_Controller[i], x + IDB_CC_A, wxEmptyString, wxDefaultPosition, wxSize(BtW, BtH)); m_Button_Classic[x][i] = new wxButton(m_Controller[i], x + IDB_CC_A, wxEmptyString, wxDefaultPosition, wxSize(BtW, BtH));
@ -863,14 +842,13 @@ void WiimotePadConfigDialog::CreatePadGUIControls()
m_gClassicController[i]->Add(m_sCcVertMiddle[i], 0, wxALIGN_RIGHT | (wxLEFT | wxRIGHT | wxDOWN), 1); m_gClassicController[i]->Add(m_sCcVertMiddle[i], 0, wxALIGN_RIGHT | (wxLEFT | wxRIGHT | wxDOWN), 1);
m_gClassicController[i]->Add(m_sCcVertRight[i], 0, wxALIGN_RIGHT | (wxLEFT | wxRIGHT | wxDOWN), 1); m_gClassicController[i]->Add(m_sCcVertRight[i], 0, wxALIGN_RIGHT | (wxLEFT | wxRIGHT | wxDOWN), 1);
} }
else if(g_Config.iExtensionConnected == EXT_GUITARHERO3_CONTROLLER) else if(WiiMoteEmu::WiiMapping[i].iExtensionConnected == WiiMoteEmu::EXT_GUITARHERO)
{ {
// Stick controls // Stick controls
m_tGH3Analog[i] = new wxStaticText(m_Controller[i], wxID_ANY, wxT("Stick")); m_tGH3Analog[i] = new wxStaticText(m_Controller[i], wxID_ANY, wxT("Stick"));
m_GH3ComboAnalog[i] = new wxComboBox(m_Controller[i], IDC_GH3_ANALOG, StrAnalogArray[0], wxDefaultPosition, wxSize(70, -1), StrAnalogArray, wxCB_READONLY); m_GH3ComboAnalog[i] = new wxComboBox(m_Controller[i], IDC_GH3_ANALOG, StrAnalogArray[0], wxDefaultPosition, wxSize(70, -1), StrAnalogArray, wxCB_READONLY);
m_GH3ComboAnalog[i]->SetSelection(g_Config.GH3Controller.AType);
for (int x = 0; x < GH3_CONTROLS; x++) for (int x = 0; x <= IDB_GH3_STRUM_DOWN - IDB_GH3_GREEN; x++)
{ {
m_statictext_GH3[x][i] = new wxStaticText(m_Controller[i], wxID_ANY, gh3Text[x]); m_statictext_GH3[x][i] = new wxStaticText(m_Controller[i], wxID_ANY, gh3Text[x]);
m_Button_GH3[x][i] = new wxButton(m_Controller[i], x, wxEmptyString, wxDefaultPosition, wxSize(BtW, BtH)); m_Button_GH3[x][i] = new wxButton(m_Controller[i], x, wxEmptyString, wxDefaultPosition, wxSize(BtW, BtH));
@ -902,15 +880,15 @@ void WiimotePadConfigDialog::CreatePadGUIControls()
// Row 4 Sizers: Wiimote and Extension Mapping // Row 4 Sizers: Wiimote and Extension Mapping
m_sHorizControllerMapping[i] = new wxBoxSizer(wxHORIZONTAL); m_sHorizControllerMapping[i] = new wxBoxSizer(wxHORIZONTAL);
m_sHorizControllerMapping[i]->Add(m_gWiimote[i], 0, (wxLEFT), 5); m_sHorizControllerMapping[i]->Add(m_gWiimote[i], 0, (wxLEFT), 5);
switch(g_Config.iExtensionConnected) switch(WiiMoteEmu::WiiMapping[i].iExtensionConnected)
{ {
case EXT_NUNCHUCK: case WiiMoteEmu::EXT_NUNCHUCK:
m_sHorizControllerMapping[i]->Add(m_gNunchuck[i], 0, (wxLEFT), 5); m_sHorizControllerMapping[i]->Add(m_gNunchuck[i], 0, (wxLEFT), 5);
break; break;
case EXT_CLASSIC_CONTROLLER: case WiiMoteEmu::EXT_CLASSIC_CONTROLLER:
m_sHorizControllerMapping[i]->Add(m_gClassicController[i], 0, (wxLEFT), 5); m_sHorizControllerMapping[i]->Add(m_gClassicController[i], 0, (wxLEFT), 5);
break; break;
case EXT_GUITARHERO3_CONTROLLER: case WiiMoteEmu::EXT_GUITARHERO:
m_sHorizControllerMapping[i]->Add(m_gGuitarHero3Controller[i], 0, (wxLEFT), 5); m_sHorizControllerMapping[i]->Add(m_gGuitarHero3Controller[i], 0, (wxLEFT), 5);
break; break;
default: default:
@ -918,7 +896,6 @@ void WiimotePadConfigDialog::CreatePadGUIControls()
} }
// Set up sizers and layout // Set up sizers and layout
// The sizer m_sMain will be expanded inside m_Controller // The sizer m_sMain will be expanded inside m_Controller
m_sMain[i] = new wxBoxSizer(wxVERTICAL); m_sMain[i] = new wxBoxSizer(wxVERTICAL);
m_sMain[i]->Add(m_sHorizController[i], 0, wxEXPAND | (wxLEFT | wxRIGHT | wxDOWN), 5); m_sMain[i]->Add(m_sHorizController[i], 0, wxEXPAND | (wxLEFT | wxRIGHT | wxDOWN), 5);
@ -942,16 +919,9 @@ void WiimotePadConfigDialog::CreatePadGUIControls()
m_MainSizer->Add(m_Notebook, 1, wxEXPAND | wxALL, 5); m_MainSizer->Add(m_Notebook, 1, wxEXPAND | wxALL, 5);
m_MainSizer->Add(sButtons, 0, wxEXPAND | (wxLEFT | wxRIGHT | wxDOWN), 5); m_MainSizer->Add(sButtons, 0, wxEXPAND | (wxLEFT | wxRIGHT | wxDOWN), 5);
for (int i = MAX_WIIMOTES - 1; i > 0; i--) SetSizer(m_MainSizer);
{ Layout();
m_Controller[i]->Enable(false);
}
this->SetSizer(m_MainSizer);
this->Layout();
Fit(); Fit();
// Center the window if there is room for it // Center the window if there is room for it
#ifdef _WIN32 #ifdef _WIN32
if (GetSystemMetrics(SM_CYFULLSCREEN) > 600) if (GetSystemMetrics(SM_CYFULLSCREEN) > 600)
@ -961,96 +931,199 @@ void WiimotePadConfigDialog::CreatePadGUIControls()
ControlsCreated = true; ControlsCreated = true;
} }
// Notebook page changed
void WiimotePadConfigDialog::NotebookPageChanged(wxNotebookEvent& event)
{
// Update the global variable
m_Page = event.GetSelection();
// Update GUI
if (ControlsCreated)
UpdateGUI();
}
void WiimotePadConfigDialog::GeneralSettingsChanged(wxCommandEvent& event) void WiimotePadConfigDialog::GeneralSettingsChanged(wxCommandEvent& event)
{ {
long TmpValue; long TmpValue;
int id = event.GetId();
switch (event.GetId()) switch (id)
{ {
case IDC_JOYNAME: case IDC_JOYNAME:
DoChangeJoystick(); WiiMoteEmu::WiiMapping[m_Page].ID = m_Joyname[m_Page]->GetSelection();
break;
case IDC_DEAD_ZONE_LEFT:
WiiMoteEmu::WiiMapping[m_Page].DeadZoneL = m_ComboDeadZoneLeft[m_Page]->GetSelection();
break;
case IDC_DEAD_ZONE_RIGHT:
WiiMoteEmu::WiiMapping[m_Page].DeadZoneR = m_ComboDeadZoneRight[m_Page]->GetSelection();
break;
case IDC_STICK_DIAGONAL:
WiiMoteEmu::WiiMapping[m_Page].Diagonal = m_ComboDiagonal[m_Page]->GetLabel().mb_str();
break;
case IDC_STICK_C2S:
WiiMoteEmu::WiiMapping[m_Page].bCircle2Square = m_CheckC2S[m_Page]->IsChecked();
break;
case IDC_RUMBLE:
WiiMoteEmu::WiiMapping[m_Page].Rumble = m_CheckRumble[m_Page]->IsChecked();
break;
case IDC_RUMBLE_STRENGTH:
WiiMoteEmu::WiiMapping[m_Page].RumbleStrength = m_RumbleStrength[m_Page]->GetSelection();
break; break;
case IDC_TILT_TYPE_WM: case IDC_TILT_TYPE_WM:
g_Config.Tilt.TypeWM = m_TiltTypeWM[Page]->GetSelection(); WiiMoteEmu::WiiMapping[m_Page].Tilt.InputWM = m_TiltTypeWM[m_Page]->GetSelection();
break; break;
case IDC_TILT_TYPE_NC: case IDC_TILT_TYPE_NC:
g_Config.Tilt.TypeNC = m_TiltTypeNC[Page]->GetSelection(); WiiMoteEmu::WiiMapping[m_Page].Tilt.InputNC = m_TiltTypeNC[m_Page]->GetSelection();
break; break;
case IDC_TILT_ROLL: case IDC_TILT_ROLL:
case IDC_TILT_ROLL_SWING: case IDC_TILT_ROLL_SWING:
m_TiltComboRangeRoll[Page]->GetValue().ToLong(&TmpValue); m_TiltComboRangeRoll[m_Page]->GetValue().ToLong(&TmpValue);
g_Config.Tilt.Range.RollDegree = TmpValue; WiiMoteEmu::WiiMapping[m_Page].Tilt.RollDegree = TmpValue;
g_Config.Tilt.Range.RollSwing = m_TiltRollSwing[Page]->IsChecked(); WiiMoteEmu::WiiMapping[m_Page].Tilt.RollSwing = m_TiltRollSwing[m_Page]->IsChecked();
g_Config.Tilt.Range.Roll = (g_Config.Tilt.Range.RollSwing) ? 0 : g_Config.Tilt.Range.RollDegree; WiiMoteEmu::WiiMapping[m_Page].Tilt.RollRange = (m_TiltRollSwing[m_Page]->IsChecked()) ? 0 : TmpValue;
break; break;
case IDC_TILT_PITCH: case IDC_TILT_PITCH:
case IDC_TILT_PITCH_SWING: case IDC_TILT_PITCH_SWING:
m_TiltComboRangePitch[Page]->GetValue().ToLong(&TmpValue); m_TiltComboRangePitch[m_Page]->GetValue().ToLong(&TmpValue);
g_Config.Tilt.Range.PitchDegree = TmpValue; WiiMoteEmu::WiiMapping[m_Page].Tilt.PitchDegree = TmpValue;
g_Config.Tilt.Range.PitchSwing = m_TiltPitchSwing[Page]->IsChecked(); WiiMoteEmu::WiiMapping[m_Page].Tilt.PitchSwing = m_TiltPitchSwing[m_Page]->IsChecked();
g_Config.Tilt.Range.Pitch = (g_Config.Tilt.Range.PitchSwing) ? 0 : g_Config.Tilt.Range.PitchDegree; WiiMoteEmu::WiiMapping[m_Page].Tilt.PitchRange = (m_TiltPitchSwing[m_Page]->IsChecked()) ? 0 : TmpValue;
break; break;
case IDC_TILT_ROLL_INVERT: case IDC_TILT_ROLL_INVERT:
g_Config.Tilt.RollInvert = m_TiltRollInvert[Page]->IsChecked(); WiiMoteEmu::WiiMapping[m_Page].Tilt.RollInvert = m_TiltRollInvert[m_Page]->IsChecked();
break; break;
case IDC_TILT_PITCH_INVERT: case IDC_TILT_PITCH_INVERT:
g_Config.Tilt.PitchInvert = m_TiltPitchInvert[Page]->IsChecked(); WiiMoteEmu::WiiMapping[m_Page].Tilt.PitchInvert = m_TiltPitchInvert[m_Page]->IsChecked();
break;
case IDC_TRIGGER_TYPE:
WiiMoteEmu::WiiMapping[m_Page].TriggerType = m_TriggerType[m_Page]->GetSelection();
break; break;
case IDC_NUNCHUCK_STICK: case IDC_NUNCHUCK_STICK:
g_Config.Nunchuck.Type = m_NunchuckComboStick[Page]->GetSelection(); WiiMoteEmu::WiiMapping[m_Page].Stick.NC = m_NunchuckComboStick[m_Page]->GetSelection();
break; break;
case IDC_CC_LEFT_STICK: case IDC_CC_LEFT_STICK:
g_Config.ClassicController.LType = m_CcComboLeftStick[Page]->GetSelection(); WiiMoteEmu::WiiMapping[m_Page].Stick.CCL = m_CcComboLeftStick[m_Page]->GetSelection();
break; break;
case IDC_CC_RIGHT_STICK: case IDC_CC_RIGHT_STICK:
g_Config.ClassicController.RType = m_CcComboRightStick[Page]->GetSelection(); WiiMoteEmu::WiiMapping[m_Page].Stick.CCR = m_CcComboRightStick[m_Page]->GetSelection();
break; break;
case IDC_CC_TRIGGERS: case IDC_CC_TRIGGERS:
g_Config.ClassicController.TType = m_CcComboTriggers[Page]->GetSelection(); WiiMoteEmu::WiiMapping[m_Page].Stick.CCT = m_CcComboTriggers[m_Page]->GetSelection();
break; break;
case IDC_GH3_ANALOG: case IDC_GH3_ANALOG:
g_Config.GH3Controller.AType = m_GH3ComboAnalog[Page]->GetSelection(); WiiMoteEmu::WiiMapping[m_Page].Stick.GH = m_GH3ComboAnalog[m_Page]->GetSelection();
break;
// These are defined in PadMapping and we can run the same function to update all of them
case IDC_DEAD_ZONE_LEFT:
case IDC_DEAD_ZONE_RIGHT:
case IDC_STICK_DIAGONAL:
case IDC_STICK_C2S:
case IDC_RUMBLE:
case IDC_RUMBLE_STRENGTH:
case IDC_TRIGGER_TYPE:
SaveButtonMappingAll(Page);
break; break;
} }
// g_Config.Save();
UpdateGUI(); UpdateGUI();
} }
void WiimotePadConfigDialog::UpdateGUI(int Slot) void WiimotePadConfigDialog::UpdateGUI()
{ {
UpdateGUIButtonMapping(Page); if(!ControlsCreated)
DoChangeDeadZone(true); return;
DoChangeDeadZone(false);
// Linux has no FindItem() wxString tmp;
// Disable all pad items if no pads are detected
if(ControlsCreated) m_Joyname[m_Page]->SetSelection(WiiMoteEmu::WiiMapping[m_Page].ID);
m_ComboDeadZoneLeft[m_Page]->SetSelection(WiiMoteEmu::WiiMapping[m_Page].DeadZoneL);
m_ComboDeadZoneRight[m_Page]->SetSelection(WiiMoteEmu::WiiMapping[m_Page].DeadZoneR);
m_ComboDiagonal[m_Page]->SetValue(wxString::FromAscii(WiiMoteEmu::WiiMapping[m_Page].Diagonal.c_str()));
m_CheckC2S[m_Page]->SetValue(WiiMoteEmu::WiiMapping[m_Page].bCircle2Square);
m_CheckRumble[m_Page]->SetValue(WiiMoteEmu::WiiMapping[m_Page].Rumble);
m_RumbleStrength[m_Page]->SetSelection(WiiMoteEmu::WiiMapping[m_Page].RumbleStrength);
m_TriggerType[m_Page]->SetSelection(WiiMoteEmu::WiiMapping[m_Page].TriggerType);
m_TiltTypeWM[m_Page]->SetSelection(WiiMoteEmu::WiiMapping[m_Page].Tilt.InputWM);
m_TiltTypeNC[m_Page]->SetSelection(WiiMoteEmu::WiiMapping[m_Page].Tilt.InputNC);
m_TiltComboRangeRoll[m_Page]->SetSelection(WiiMoteEmu::WiiMapping[m_Page].Tilt.RollDegree / 5 - 1); // 5 to 180, step 5
m_TiltComboRangeRoll[m_Page]->Enable(!WiiMoteEmu::WiiMapping[m_Page].Tilt.RollSwing);
m_TiltComboRangePitch[m_Page]->SetSelection(WiiMoteEmu::WiiMapping[m_Page].Tilt.PitchDegree / 5 - 1); // 5 to 180, step 5
m_TiltComboRangePitch[m_Page]->Enable(!WiiMoteEmu::WiiMapping[m_Page].Tilt.PitchSwing);
m_TiltRollSwing[m_Page]->SetValue(WiiMoteEmu::WiiMapping[m_Page].Tilt.RollSwing);
m_TiltPitchSwing[m_Page]->SetValue(WiiMoteEmu::WiiMapping[m_Page].Tilt.PitchSwing);
m_TiltRollInvert[m_Page]->SetValue(WiiMoteEmu::WiiMapping[m_Page].Tilt.RollInvert);
m_TiltPitchInvert[m_Page]->SetValue(WiiMoteEmu::WiiMapping[m_Page].Tilt.PitchInvert);
for (int i = 0; i <= IDB_TRIGGER_R - IDB_ANALOG_LEFT_X; i++)
{ {
bool PadEnabled = WiiMoteEmu::NumGoodPads != 0; tmp << WiiMoteEmu::WiiMapping[m_Page].AxisMapping.Code[i];
#ifdef _WIN32 m_Button_Analog[i][m_Page]->SetLabel(tmp);
m_Notebook->FindItem(IDC_JOYNAME)->Enable(PadEnabled); tmp.clear();
m_Notebook->FindItem(IDC_DEAD_ZONE_LEFT)->Enable(PadEnabled); }
m_Notebook->FindItem(IDC_DEAD_ZONE_RIGHT)->Enable(PadEnabled);
m_Notebook->FindItem(IDC_STICK_C2S)->Enable(PadEnabled); #ifdef _WIN32
m_Notebook->FindItem(IDC_STICK_DIAGONAL)->Enable(PadEnabled); for (int x = 0; x <= IDB_WM_SHAKE - IDB_WM_A; x++)
m_Notebook->FindItem(IDC_RUMBLE)->Enable(PadEnabled); {
m_Notebook->FindItem(IDC_RUMBLE_STRENGTH)->Enable(PadEnabled); m_Button_Wiimote[x][m_Page]->SetLabel(wxString::FromAscii(
m_Notebook->FindItem(IDC_TRIGGER_TYPE)->Enable(PadEnabled); InputCommon::VKToString(WiiMoteEmu::WiiMapping[m_Page].Button[x + WiiMoteEmu::EWM_A]).c_str()));
m_Notebook->FindItem(IDC_TILT_ROLL)->Enable(!g_Config.Tilt.Range.RollSwing); }
m_Notebook->FindItem(IDC_TILT_PITCH)->Enable(!g_Config.Tilt.Range.PitchSwing); if(WiiMoteEmu::WiiMapping[m_Page].iExtensionConnected == WiiMoteEmu::EXT_NUNCHUCK)
for(int i = IDB_ANALOG_LEFT_X; i <= IDB_TRIGGER_R; i++) {
m_Notebook->FindItem(i)->Enable(PadEnabled); for (int x = 0; x <= IDB_NC_SHAKE - IDB_NC_Z; x++)
#endif m_Button_NunChuck[x][m_Page]->SetLabel(wxString::FromAscii(
} InputCommon::VKToString(WiiMoteEmu::WiiMapping[m_Page].Button[x + WiiMoteEmu::ENC_Z]).c_str()));
}
else if(WiiMoteEmu::WiiMapping[m_Page].iExtensionConnected == WiiMoteEmu::EXT_CLASSIC_CONTROLLER)
{
for (int x = 0; x <= IDB_CC_RD - IDB_CC_A; x++)
m_Button_Classic[x][m_Page]->SetLabel(wxString::FromAscii(
InputCommon::VKToString(WiiMoteEmu::WiiMapping[m_Page].Button[x + WiiMoteEmu::ECC_A]).c_str()));
}
else if(WiiMoteEmu::WiiMapping[m_Page].iExtensionConnected == WiiMoteEmu::EXT_GUITARHERO)
{
for (int x = 0; x <= IDB_GH3_STRUM_DOWN - IDB_GH3_GREEN; x++)
m_Button_GH3[x][m_Page]->SetLabel(wxString::FromAscii(
InputCommon::VKToString(WiiMoteEmu::WiiMapping[m_Page].Button[x + WiiMoteEmu::EGH_Green]).c_str()));
}
#elif defined(HAVE_X11) && HAVE_X11
char keyStr[10] = {0};
for (int x = 0; x <= IDB_WM_SHAKE - IDB_WM_A; x++)
{
InputCommon::XKeyToString(WiiMoteEmu::WiiMapping[m_Page].Button[x + WiiMoteEmu::EWM_A], keyStr);
m_Button_Wiimote[x][m_Page]->SetLabel(wxString::FromAscii(keyStr));
}
if(WiiMoteEmu::WiiMapping[m_Page].iExtensionConnected == WiiMoteEmu::EXT_NUNCHUCK)
{
for (int x = 0; x <= IDB_NC_SHAKE - IDB_NC_Z; x++)
{
InputCommon::XKeyToString(WiiMoteEmu::WiiMapping[m_Page].Button[x + WiiMoteEmu::ENC_Z], keyStr);
m_Button_NunChuck[x][m_Page]->SetLabel(wxString::FromAscii(keyStr));
}
}
else if(WiiMoteEmu::WiiMapping[m_Page].iExtensionConnected == WiiMoteEmu::EXT_CLASSIC_CONTROLLER)
{
for (int x = 0; x <= IDB_CC_RD - IDB_CC_A; x++)
{
InputCommon::XKeyToString(WiiMoteEmu::WiiMapping[m_Page].Button[x + WiiMoteEmu::ECC_A], keyStr);
m_Button_Classic[x][m_Page]->SetLabel(wxString::FromAscii(keyStr));
}
}
else if(WiiMoteEmu::WiiMapping[m_Page].iExtensionConnected == WiiMoteEmu::EXT_GUITARHERO)
{
for (int x = 0; x <= IDB_GH3_STRUM_DOWN - IDB_GH3_GREEN; x++)
{
InputCommon::XKeyToString(WiiMoteEmu::WiiMapping[m_Page].Button[x + WiiMoteEmu::EGH_Green], keyStr);
m_Button_GH3[x][slot]->SetLabel(wxString::FromAscii(keyStr));
}
}
#endif
DoChangeDeadZone();
// Disable all pad items if no pads are detected
bool PadEnabled = WiiMoteEmu::NumGoodPads != 0;
m_Joyname[m_Page]->Enable(PadEnabled);
m_ComboDeadZoneLeft[m_Page]->Enable(PadEnabled);
m_ComboDeadZoneRight[m_Page]->Enable(PadEnabled);
m_CheckC2S[m_Page]->Enable(PadEnabled);
m_ComboDiagonal[m_Page]->Enable(PadEnabled);
m_CheckRumble[m_Page]->Enable(PadEnabled);
m_RumbleStrength[m_Page]->Enable(PadEnabled);
m_TriggerType[m_Page]->Enable(PadEnabled);
for(int i = 0; i <= IDB_TRIGGER_R - IDB_ANALOG_LEFT_X; i++)
m_Button_Analog[i][m_Page]->Enable(PadEnabled);
} }

View File

@ -31,6 +31,7 @@
#include <wx/panel.h> #include <wx/panel.h>
#include <wx/gbsizer.h> #include <wx/gbsizer.h>
#include "Config.h" #include "Config.h"
#include "wiimote_hid.h"
#if defined(HAVE_X11) && HAVE_X11 #if defined(HAVE_X11) && HAVE_X11
#include <X11/Xlib.h> #include <X11/Xlib.h>
@ -51,169 +52,24 @@ class WiimotePadConfigDialog : public wxDialog
long style = wxDEFAULT_DIALOG_STYLE | wxWANTS_CHARS); long style = wxDEFAULT_DIALOG_STYLE | wxWANTS_CHARS);
virtual ~WiimotePadConfigDialog(); virtual ~WiimotePadConfigDialog();
void CloseClick(wxCommandEvent& event);
void UpdateGUI(int Slot = 0);
void UpdateGUIButtonMapping(int controller);
void UpdateControls();
void OnKeyDown(wxKeyEvent& event);
void Convert2Box(int &x); void Convert2Box(int &x);
void ConvertToString();
void OnButtonTimer(wxTimerEvent& WXUNUSED(event)) { DoGetButtons(GetButtonWaitingID); }
void UpdatePad(wxTimerEvent& WXUNUSED(event));
wxTimer *m_UpdatePadTimer, wxTimer *m_UpdatePadTimer,
*m_ButtonMappingTimer; *m_ButtonMappingTimer;
wxStaticBitmap *m_bmpDotLeftIn[4], wxStaticBitmap *m_bmpDotLeftIn[MAX_WIIMOTES],
*m_bmpDotLeftOut[4], *m_bmpDotLeftOut[MAX_WIIMOTES],
*m_bmpDotRightIn[4], *m_bmpDotRightIn[MAX_WIIMOTES],
*m_bmpDotRightOut[4], *m_bmpDotRightOut[MAX_WIIMOTES],
*m_bmpDeadZoneLeftIn[4], *m_bmpDeadZoneLeftIn[MAX_WIIMOTES],
*m_bmpDeadZoneRightIn[4]; *m_bmpDeadZoneRightIn[MAX_WIIMOTES];
private: private:
DECLARE_EVENT_TABLE(); DECLARE_EVENT_TABLE();
bool ControlsCreated;
int Page, BoxW, BoxH;
wxString OldLabel;
wxNotebook *m_Notebook;
wxPanel *m_Controller[4],
*m_pLeftInStatus[4],
*m_pLeftOutStatus[4],
*m_pRightInStatus[4],
*m_pRightOutStatus[4];
wxStaticBitmap *m_bmpSquareLeftIn[4],
*m_bmpSquareLeftOut[4],
*m_bmpSquareRightIn[4],
*m_bmpSquareRightOut[4];
wxCheckBox *m_CheckC2S[4],
*m_CheckRumble[4],
*m_TiltRollSwing[4],
*m_TiltPitchSwing[4],
*m_TiltRollInvert[4],
*m_TiltPitchInvert[4];
wxButton *m_Close, *m_Apply, *ClickedButton,
*m_Button_Analog[AN_CONTROLS][4],
*m_Button_Wiimote[WM_CONTROLS][4],
*m_Button_NunChuck[NC_CONTROLS][4],
*m_Button_Classic[CC_CONTROLS][4],
*m_Button_GH3[GH3_CONTROLS][4];
wxComboBox *m_Joyname[4],
*m_ComboDeadZoneLeft[4],
*m_ComboDeadZoneRight[4],
*m_ComboDiagonal[4],
*m_RumbleStrength[4],
*m_TiltTypeWM[4],
*m_TiltTypeNC[4],
*m_TiltComboRangeRoll[4],
*m_TiltComboRangePitch[4],
*m_TriggerType[4],
*m_NunchuckComboStick[4],
*m_CcComboLeftStick[4],
*m_CcComboRightStick[4],
*m_CcComboTriggers[4],
*m_GH3ComboAnalog[4];
wxGridBagSizer *m_sGridTilt[4],
*m_sGridStickLeft[4],
*m_sGridStickRight[4],
*m_sGridTrigger[4];
wxBoxSizer *m_MainSizer,
*m_sMain[4],
*m_sDeadZoneHoriz[4],
*m_sDeadZone[4],
*m_sDiagonal[4],
*m_sCircle2Square[4],
*m_sC2SDeadZone[4],
*m_sJoyname[4],
*m_sRumble[4],
*m_sTiltType[4],
*m_sHorizController[4],
*m_sHorizStatus[4],
*m_Sizer_Analog[AN_CONTROLS][4],
*m_sAnalogLeft[4],
*m_sAnalogMiddle[4],
*m_sAnalogRight[4],
*m_sHorizAnalogMapping[4],
*m_Sizer_Wiimote[WM_CONTROLS][4],
*m_sWmVertLeft[4],
*m_sWmVertRight[4],
*m_Sizer_NunChuck[NC_CONTROLS][4],
*m_sNunchuckStick[4],
*m_sNCVertLeft[4],
*m_sNCVertRight[4],
*m_Sizer_Classic[CC_CONTROLS][4],
*m_sCcLeftStick[4],
*m_sCcRightStick[4],
*m_sCcTriggers[4],
*m_sCcVertLeft[4],
*m_sCcVertMiddle[4],
*m_sCcVertRight[4],
*m_Sizer_GH3[GH3_CONTROLS][4],
*m_sGH3Analog[4],
*m_sGH3VertLeft[4],
*m_sGH3VertRight[4],
*m_sHorizControllerMapping[4];
wxStaticBoxSizer *m_gJoyPad[4],
*m_gTilt[4],
*m_gStickLeft[4],
*m_gStickRight[4],
*m_gTriggers[4],
*m_gAnalog[4],
*m_gWiimote[4],
*m_gNunchuck[4],
*m_gClassicController[4],
*m_gGuitarHero3Controller[4];
wxStaticText *m_ComboDeadZoneLabel[4],
*m_DiagonalLabel[4],
*m_RumbleStrengthLabel[4],
*m_tTiltTypeWM[4], *m_tTiltTypeNC[4],
*m_TiltTextRoll[4], *m_TiltTextPitch[4],
*m_tStatusLeftIn[4], *m_tStatusLeftOut[4], *m_tStatusRightIn[4], *m_tStatusRightOut[4],
*m_TriggerL[4], *m_TriggerR[4],
*m_TriggerStatusL[4], *m_TriggerStatusR[4],
*m_tTriggerSource[4],
*m_statictext_Analog[AN_CONTROLS][4],
*m_statictext_Wiimote[WM_CONTROLS][4],
*m_statictext_NunChuck[NC_CONTROLS][4],
*m_statictext_Classic[CC_CONTROLS][4],
*m_statictext_GH3[GH3_CONTROLS][4],
*m_NunchuckTextStick[5],
*m_CcTextLeftStick[4],
*m_CcTextRightStick[4],
*m_CcTextTriggers[4],
*m_tGH3Analog[4];
enum enum
{ {
ID_CLOSE = 1000, // <It's important that the internal ordering of these are unchanged>
ID_APPLY,
IDTM_BUTTON, // Timer
IDTM_UPDATE_PAD, // Timer
ID_NOTEBOOK,
ID_CONTROLLERPAGE1,
ID_CONTROLLERPAGE2,
ID_CONTROLLERPAGE3,
ID_CONTROLLERPAGE4,
// Gamepad <It's important that the internal ordering of these are unchanged>
IDB_ANALOG_LEFT_X, IDB_ANALOG_LEFT_Y,
IDB_ANALOG_RIGHT_X, IDB_ANALOG_RIGHT_Y,
IDB_TRIGGER_L, IDB_TRIGGER_R,
// Wiimote // Wiimote
IDB_WM_A, IDB_WM_B, IDB_WM_A, IDB_WM_B,
IDB_WM_1, IDB_WM_2, IDB_WM_1, IDB_WM_2,
@ -259,6 +115,22 @@ class WiimotePadConfigDialog : public wxDialog
IDB_GH3_STRUM_UP, IDB_GH3_STRUM_UP,
IDB_GH3_STRUM_DOWN, IDB_GH3_STRUM_DOWN,
// Gamepad
IDB_ANALOG_LEFT_X, IDB_ANALOG_LEFT_Y,
IDB_ANALOG_RIGHT_X, IDB_ANALOG_RIGHT_Y,
IDB_TRIGGER_L, IDB_TRIGGER_R,
ID_CLOSE = 1000,
ID_APPLY,
IDTM_BUTTON, // Timer
IDTM_UPDATE_PAD, // Timer
ID_NOTEBOOK,
ID_CONTROLLERPAGE1,
ID_CONTROLLERPAGE2,
ID_CONTROLLERPAGE3,
ID_CONTROLLERPAGE4,
// Gamepad settings // Gamepad settings
IDC_JOYNAME, IDC_JOYNAME,
IDC_RUMBLE, IDC_RUMBLE_STRENGTH, IDC_RUMBLE, IDC_RUMBLE_STRENGTH,
@ -274,34 +146,155 @@ class WiimotePadConfigDialog : public wxDialog
IDC_GH3_ANALOG, IDC_GH3_ANALOG,
}; };
bool ControlsCreated;
int m_Page, BoxW, BoxH;
wxString OldLabel;
wxNotebook *m_Notebook;
wxPanel *m_Controller[MAX_WIIMOTES],
*m_pLeftInStatus[MAX_WIIMOTES],
*m_pLeftOutStatus[MAX_WIIMOTES],
*m_pRightInStatus[MAX_WIIMOTES],
*m_pRightOutStatus[MAX_WIIMOTES];
wxStaticBitmap *m_bmpSquareLeftIn[MAX_WIIMOTES],
*m_bmpSquareLeftOut[MAX_WIIMOTES],
*m_bmpSquareRightIn[MAX_WIIMOTES],
*m_bmpSquareRightOut[MAX_WIIMOTES];
wxCheckBox *m_CheckC2S[MAX_WIIMOTES],
*m_CheckRumble[MAX_WIIMOTES],
*m_TiltRollSwing[MAX_WIIMOTES],
*m_TiltPitchSwing[MAX_WIIMOTES],
*m_TiltRollInvert[MAX_WIIMOTES],
*m_TiltPitchInvert[MAX_WIIMOTES];
wxButton *m_Close, *m_Apply, *ClickedButton,
*m_Button_Analog[IDB_TRIGGER_R - IDB_ANALOG_LEFT_X + 1][MAX_WIIMOTES],
*m_Button_Wiimote[IDB_WM_SHAKE - IDB_WM_A + 1][MAX_WIIMOTES],
*m_Button_NunChuck[IDB_NC_SHAKE - IDB_NC_Z + 1][MAX_WIIMOTES],
*m_Button_Classic[IDB_CC_RD - IDB_CC_A + 1][MAX_WIIMOTES],
*m_Button_GH3[IDB_GH3_STRUM_DOWN - IDB_GH3_GREEN + 1][MAX_WIIMOTES];
wxComboBox *m_Joyname[MAX_WIIMOTES],
*m_ComboDeadZoneLeft[MAX_WIIMOTES],
*m_ComboDeadZoneRight[MAX_WIIMOTES],
*m_ComboDiagonal[MAX_WIIMOTES],
*m_RumbleStrength[MAX_WIIMOTES],
*m_TiltTypeWM[MAX_WIIMOTES],
*m_TiltTypeNC[MAX_WIIMOTES],
*m_TiltComboRangeRoll[MAX_WIIMOTES],
*m_TiltComboRangePitch[MAX_WIIMOTES],
*m_TriggerType[MAX_WIIMOTES],
*m_NunchuckComboStick[MAX_WIIMOTES],
*m_CcComboLeftStick[MAX_WIIMOTES],
*m_CcComboRightStick[MAX_WIIMOTES],
*m_CcComboTriggers[MAX_WIIMOTES],
*m_GH3ComboAnalog[MAX_WIIMOTES];
wxGridBagSizer *m_sGridTilt[MAX_WIIMOTES],
*m_sGridStickLeft[MAX_WIIMOTES],
*m_sGridStickRight[MAX_WIIMOTES],
*m_sGridTrigger[MAX_WIIMOTES];
wxBoxSizer *m_MainSizer,
*m_sMain[MAX_WIIMOTES],
*m_sDeadZoneHoriz[MAX_WIIMOTES],
*m_sDeadZone[MAX_WIIMOTES],
*m_sDiagonal[MAX_WIIMOTES],
*m_sCircle2Square[MAX_WIIMOTES],
*m_sC2SDeadZone[MAX_WIIMOTES],
*m_sJoyname[MAX_WIIMOTES],
*m_sRumble[MAX_WIIMOTES],
*m_sTiltType[MAX_WIIMOTES],
*m_sHorizController[MAX_WIIMOTES],
*m_sHorizStatus[MAX_WIIMOTES],
*m_Sizer_Analog[IDB_TRIGGER_R - IDB_ANALOG_LEFT_X + 1][MAX_WIIMOTES],
*m_sAnalogLeft[MAX_WIIMOTES],
*m_sAnalogMiddle[MAX_WIIMOTES],
*m_sAnalogRight[MAX_WIIMOTES],
*m_sHorizAnalogMapping[MAX_WIIMOTES],
*m_Sizer_Wiimote[IDB_WM_SHAKE - IDB_WM_A + 1][MAX_WIIMOTES],
*m_sWmVertLeft[MAX_WIIMOTES],
*m_sWmVertRight[MAX_WIIMOTES],
*m_Sizer_NunChuck[IDB_NC_SHAKE - IDB_NC_Z + 1][MAX_WIIMOTES],
*m_sNunchuckStick[MAX_WIIMOTES],
*m_sNCVertLeft[MAX_WIIMOTES],
*m_sNCVertRight[MAX_WIIMOTES],
*m_Sizer_Classic[IDB_CC_RD - IDB_CC_A + 1][MAX_WIIMOTES],
*m_sCcLeftStick[MAX_WIIMOTES],
*m_sCcRightStick[MAX_WIIMOTES],
*m_sCcTriggers[MAX_WIIMOTES],
*m_sCcVertLeft[MAX_WIIMOTES],
*m_sCcVertMiddle[MAX_WIIMOTES],
*m_sCcVertRight[MAX_WIIMOTES],
*m_Sizer_GH3[IDB_GH3_STRUM_DOWN - IDB_GH3_GREEN + 1][MAX_WIIMOTES],
*m_sGH3Analog[MAX_WIIMOTES],
*m_sGH3VertLeft[MAX_WIIMOTES],
*m_sGH3VertRight[MAX_WIIMOTES],
*m_sHorizControllerMapping[MAX_WIIMOTES];
wxStaticBoxSizer *m_gJoyPad[MAX_WIIMOTES],
*m_gTilt[MAX_WIIMOTES],
*m_gStickLeft[MAX_WIIMOTES],
*m_gStickRight[MAX_WIIMOTES],
*m_gTriggers[MAX_WIIMOTES],
*m_gAnalog[MAX_WIIMOTES],
*m_gWiimote[MAX_WIIMOTES],
*m_gNunchuck[MAX_WIIMOTES],
*m_gClassicController[MAX_WIIMOTES],
*m_gGuitarHero3Controller[MAX_WIIMOTES];
wxStaticText *m_ComboDeadZoneLabel[MAX_WIIMOTES],
*m_DiagonalLabel[MAX_WIIMOTES],
*m_RumbleStrengthLabel[MAX_WIIMOTES],
*m_tTiltTypeWM[MAX_WIIMOTES], *m_tTiltTypeNC[MAX_WIIMOTES],
*m_TiltTextRoll[MAX_WIIMOTES], *m_TiltTextPitch[MAX_WIIMOTES],
*m_tStatusLeftIn[MAX_WIIMOTES], *m_tStatusLeftOut[MAX_WIIMOTES],
*m_tStatusRightIn[MAX_WIIMOTES], *m_tStatusRightOut[MAX_WIIMOTES],
*m_TriggerL[MAX_WIIMOTES], *m_TriggerR[MAX_WIIMOTES],
*m_TriggerStatusL[MAX_WIIMOTES], *m_TriggerStatusR[MAX_WIIMOTES],
*m_tTriggerSource[MAX_WIIMOTES],
*m_statictext_Analog[IDB_TRIGGER_R - IDB_ANALOG_LEFT_X + 1][MAX_WIIMOTES],
*m_statictext_Wiimote[IDB_WM_SHAKE - IDB_WM_A + 1][MAX_WIIMOTES],
*m_statictext_NunChuck[IDB_NC_SHAKE - IDB_NC_Z + 1][MAX_WIIMOTES],
*m_statictext_Classic[IDB_CC_RD - IDB_CC_A + 1][MAX_WIIMOTES],
*m_statictext_GH3[IDB_GH3_STRUM_DOWN - IDB_GH3_GREEN + 1][MAX_WIIMOTES],
*m_NunchuckTextStick[5],
*m_CcTextLeftStick[MAX_WIIMOTES],
*m_CcTextRightStick[MAX_WIIMOTES],
*m_CcTextTriggers[MAX_WIIMOTES],
*m_tGH3Analog[MAX_WIIMOTES];
wxBitmap CreateBitmap(); wxBitmap CreateBitmap();
wxBitmap CreateBitmapDot(); wxBitmap CreateBitmapDot();
wxBitmap CreateBitmapDeadZone(int Radius); wxBitmap CreateBitmapDeadZone(int Radius);
wxBitmap CreateBitmapClear(); wxBitmap CreateBitmapClear();
void OnClose(wxCloseEvent& event); void OnClose(wxCloseEvent& event);
void CloseClick(wxCommandEvent& event);
void CreatePadGUIControls(); void CreatePadGUIControls();
void UpdateGUI();
void NotebookPageChanged(wxNotebookEvent& event);
void OnButtonTimer(wxTimerEvent& WXUNUSED(event)) { DoGetButtons(GetButtonWaitingID); }
void OnKeyDown(wxKeyEvent& event);
void OnButtonClick(wxCommandEvent& event);
void GeneralSettingsChanged(wxCommandEvent& event); void GeneralSettingsChanged(wxCommandEvent& event);
void SaveButtonMapping(int Id, int Key);
// Gamepad configuration // Gamepad configuration
void SetButtonText(int id, const char text[128], int _Page = -1); void SetButtonText(int id,const wxString &str);
void SetButtonTextAll(int id, char text[128]); wxString GetButtonText(int id);
void GetButtons(wxCommandEvent& btn_event); void GetButtons(wxCommandEvent& btn_event);
void DoGetButtons(int id); void DoGetButtons(int id);
void SaveButtonMapping(int controller, bool DontChangeId = false, int FromSlot = -1); void UpdatePadInfo(wxTimerEvent& WXUNUSED(event));
void SaveButtonMappingAll(int Slot); void ToBlank(bool ToBlank, int Id);
void SaveKeyboardMapping(int Controller, int Id, int Key); void DoChangeDeadZone();
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 OnButtonClick(wxCommandEvent& event);
// Configure buttons // Configure buttons
int GetButtonWaitingID, GetButtonWaitingTimer, g_Pressed; int GetButtonWaitingID, GetButtonWaitingTimer, g_Pressed;
wxString GetButtonText(int id, int Page = -1);
}; };
extern WiimotePadConfigDialog *m_PadConfigFrame; extern WiimotePadConfigDialog *m_PadConfigFrame;
#endif #endif

View File

@ -429,11 +429,6 @@ void WiimoteRecordingConfigDialog::RecordMovement(wxCommandEvent& event)
else else
{ {
m_RecordButton[m_iRecordTo]->SetLabel(wxT("Press +")); m_RecordButton[m_iRecordTo]->SetLabel(wxT("Press +"));
// This is for usability purposes, it may not be obvious at all that
// this must be unchecked for the recording to work
for(int i = 0; i < MAX_WIIMOTES; i++)
m_BasicConfigFrame->m_UseRealWiimote[i]->SetValue(false);
g_Config.bUseRealWiimote = false;
return; return;
} }

View File

@ -66,7 +66,6 @@ namespace WiiMoteEmu
// Subroutines // Subroutines
// Update the data reporting mode // Update the data reporting mode
void WmReportMode(u16 _channelID, wm_report_mode* dr) void WmReportMode(u16 _channelID, wm_report_mode* dr)
@ -77,9 +76,9 @@ void WmReportMode(u16 _channelID, wm_report_mode* dr)
DEBUG_LOG(WIIMOTE, " All The Time: %x (not only on data change)", dr->all_the_time); DEBUG_LOG(WIIMOTE, " All The Time: %x (not only on data change)", dr->all_the_time);
DEBUG_LOG(WIIMOTE, " Mode: 0x%02x", dr->mode); DEBUG_LOG(WIIMOTE, " Mode: 0x%02x", dr->mode);
g_ReportingAuto[g_RefreshWiimote] = dr->all_the_time; g_ReportingAuto[g_ID] = dr->all_the_time;
g_ReportingMode = dr->mode; g_ReportingMode[g_ID] = dr->mode;
g_ReportingChannel = _channelID; g_ReportingChannel[g_ID] = _channelID;
// Validation check // Validation check
switch(dr->mode) switch(dr->mode)
@ -96,7 +95,6 @@ void WmReportMode(u16 _channelID, wm_report_mode* dr)
} }
/* Case 0x30: Core Buttons */ /* Case 0x30: Core Buttons */
void SendReportCore(u16 _channelID) void SendReportCore(u16 _channelID)
{ {
@ -114,7 +112,7 @@ void SendReportCore(u16 _channelID)
DEBUG_LOG(WIIMOTE, " Channel: %04x", _channelID); DEBUG_LOG(WIIMOTE, " Channel: %04x", _channelID);
DEBUG_LOG(WIIMOTE, " Size: %08x", Offset); DEBUG_LOG(WIIMOTE, " Size: %08x", Offset);
g_WiimoteInitialize.pWiimoteInput(g_RefreshWiimote, _channelID, DataFrame, Offset); g_WiimoteInitialize.pWiimoteInput(g_ID, _channelID, DataFrame, Offset);
// Debugging // Debugging
//ReadDebugging(true, DataFrame, Offset); //ReadDebugging(true, DataFrame, Offset);
} }
@ -139,7 +137,7 @@ void SendReportCoreAccel(u16 _channelID)
DEBUG_LOG(WIIMOTE, " Channel: %04x", _channelID); DEBUG_LOG(WIIMOTE, " Channel: %04x", _channelID);
DEBUG_LOG(WIIMOTE, " Size: %08x", Offset); DEBUG_LOG(WIIMOTE, " Size: %08x", Offset);
g_WiimoteInitialize.pWiimoteInput(g_RefreshWiimote, _channelID, DataFrame, Offset); g_WiimoteInitialize.pWiimoteInput(g_ID, _channelID, DataFrame, Offset);
// Debugging // Debugging
//ReadDebugging(true, DataFrame, Offset); //ReadDebugging(true, DataFrame, Offset);
@ -158,7 +156,6 @@ void SendReportCoreAccelIr12(u16 _channelID) {
#if defined(HAVE_WX) && HAVE_WX #if defined(HAVE_WX) && HAVE_WX
FillReportInfo(pReport->c); FillReportInfo(pReport->c);
FillReportAcc(pReport->a); FillReportAcc(pReport->a);
// We settle with emulating two objects, not all four. We leave object 2 and 3 with 0xff. // We settle with emulating two objects, not all four. We leave object 2 and 3 with 0xff.
FillReportIR(pReport->ir[0], pReport->ir[1]); FillReportIR(pReport->ir[0], pReport->ir[1]);
#endif #endif
@ -169,7 +166,7 @@ void SendReportCoreAccelIr12(u16 _channelID) {
DEBUG_LOG(WIIMOTE, " Channel: %04x", _channelID); DEBUG_LOG(WIIMOTE, " Channel: %04x", _channelID);
DEBUG_LOG(WIIMOTE, " Size: %08x", Offset); DEBUG_LOG(WIIMOTE, " Size: %08x", Offset);
g_WiimoteInitialize.pWiimoteInput(g_RefreshWiimote, _channelID, DataFrame, Offset); g_WiimoteInitialize.pWiimoteInput(g_ID, _channelID, DataFrame, Offset);
// Debugging // Debugging
//ReadDebugging(true, DataFrame, Offset); //ReadDebugging(true, DataFrame, Offset);
@ -195,13 +192,13 @@ void SendReportCoreAccelExt16(u16 _channelID)
FillReportAcc(pReport->a); FillReportAcc(pReport->a);
#endif #endif
if(g_Config.iExtensionConnected == EXT_NUNCHUCK) if(WiiMapping[g_ID].iExtensionConnected == EXT_NUNCHUCK)
{ {
#if defined(HAVE_WX) && HAVE_WX #if defined(HAVE_WX) && HAVE_WX
FillReportExtension(pReport->ext); FillReportExtension(pReport->ext);
#endif #endif
} }
else if(g_Config.iExtensionConnected == EXT_CLASSIC_CONTROLLER) else if(WiiMapping[g_ID].iExtensionConnected == EXT_CLASSIC_CONTROLLER)
{ {
#if defined(HAVE_WX) && HAVE_WX #if defined(HAVE_WX) && HAVE_WX
FillReportClassicExtension(_ext); FillReportClassicExtension(_ext);
@ -214,7 +211,7 @@ void SendReportCoreAccelExt16(u16 _channelID)
DEBUG_LOG(WIIMOTE, " Channel: %04x", _channelID); DEBUG_LOG(WIIMOTE, " Channel: %04x", _channelID);
DEBUG_LOG(WIIMOTE, " Size: %08x", Offset); DEBUG_LOG(WIIMOTE, " Size: %08x", Offset);
g_WiimoteInitialize.pWiimoteInput(g_RefreshWiimote, _channelID, DataFrame, Offset); g_WiimoteInitialize.pWiimoteInput(g_ID, _channelID, DataFrame, Offset);
// Debugging // Debugging
//ReadDebugging(true, DataFrame, Offset); //ReadDebugging(true, DataFrame, Offset);
@ -242,13 +239,13 @@ void SendReportCoreAccelIr10Ext(u16 _channelID)
FillReportAcc(pReport->a); FillReportAcc(pReport->a);
FillReportIRBasic(pReport->ir[0], pReport->ir[1]); FillReportIRBasic(pReport->ir[0], pReport->ir[1]);
#endif #endif
if(g_Config.iExtensionConnected == EXT_NUNCHUCK) if(WiiMapping[g_ID].iExtensionConnected == EXT_NUNCHUCK)
{ {
#if defined(HAVE_WX) && HAVE_WX #if defined(HAVE_WX) && HAVE_WX
FillReportExtension(pReport->ext); FillReportExtension(pReport->ext);
#endif #endif
} }
else if(g_Config.iExtensionConnected == EXT_CLASSIC_CONTROLLER) else if(WiiMapping[g_ID].iExtensionConnected == EXT_CLASSIC_CONTROLLER)
{ {
#if defined(HAVE_WX) && HAVE_WX #if defined(HAVE_WX) && HAVE_WX
FillReportClassicExtension(_ext); FillReportClassicExtension(_ext);
@ -256,7 +253,7 @@ void SendReportCoreAccelIr10Ext(u16 _channelID)
// Copy _ext to pReport->ext // Copy _ext to pReport->ext
memcpy(&pReport->ext, &_ext, sizeof(_ext)); memcpy(&pReport->ext, &_ext, sizeof(_ext));
} }
else if(g_Config.iExtensionConnected == EXT_GUITARHERO3_CONTROLLER) else if(WiiMapping[g_ID].iExtensionConnected == EXT_GUITARHERO)
{ {
#if defined(HAVE_WX) && HAVE_WX #if defined(HAVE_WX) && HAVE_WX
FillReportGuitarHero3Extension(_GH3_ext); FillReportGuitarHero3Extension(_GH3_ext);
@ -268,7 +265,7 @@ void SendReportCoreAccelIr10Ext(u16 _channelID)
DEBUG_LOG(WIIMOTE, " Channel: %04x", _channelID); DEBUG_LOG(WIIMOTE, " Channel: %04x", _channelID);
DEBUG_LOG(WIIMOTE, " Size: %08x", Offset); DEBUG_LOG(WIIMOTE, " Size: %08x", Offset);
g_WiimoteInitialize.pWiimoteInput(g_RefreshWiimote, _channelID, DataFrame, Offset); g_WiimoteInitialize.pWiimoteInput(g_ID, _channelID, DataFrame, Offset);
// Debugging // Debugging
//ReadDebugging(true, DataFrame, Offset); //ReadDebugging(true, DataFrame, Offset);

View File

@ -36,24 +36,23 @@ namespace WiiMoteEmu
// Definitions and variable declarations // Definitions and variable declarations
//****************************************************************************** //******************************************************************************
u8 g_IR[4];
u8 g_Leds[4]; u8 g_Leds[4];
u8 g_Speaker; u8 g_Speaker;
u8 g_SpeakerVoice; u8 g_SpeakerVoice;
u8 g_IR;
u8 g_RegExt[MAX_WIIMOTES][WIIMOTE_REG_EXT_SIZE];
u8 g_Eeprom[WIIMOTE_EEPROM_SIZE]; u8 g_Eeprom[WIIMOTE_EEPROM_SIZE];
u8 g_RegSpeaker[WIIMOTE_REG_SPEAKER_SIZE]; u8 g_RegSpeaker[WIIMOTE_REG_SPEAKER_SIZE];
u8 g_RegMotionPlus[WIIMOTE_REG_EXT_SIZE]; u8 g_RegMotionPlus[WIIMOTE_REG_EXT_SIZE];
u8 g_RegExt[WIIMOTE_REG_EXT_SIZE];
u8 g_RegExtTmp[WIIMOTE_REG_EXT_SIZE]; u8 g_RegExtTmp[WIIMOTE_REG_EXT_SIZE];
u8 g_RegIr[WIIMOTE_REG_IR_SIZE]; u8 g_RegIr[WIIMOTE_REG_IR_SIZE];
int g_RefreshWiimote; // Current refreshing Wiimote int g_ID; // Current refreshing Wiimote
bool g_ReportingAuto[4]; // Auto report or passive report bool g_ReportingAuto[MAX_WIIMOTES]; // Auto report or passive report
u8 g_ReportingMode; // The reporting mode and channel id u8 g_ReportingMode[MAX_WIIMOTES]; // The reporting mode and channel id
u16 g_ReportingChannel; u16 g_ReportingChannel[MAX_WIIMOTES];
std::vector<wm_ackdelay> AckDelay; // Ackk delay
wiimote_key g_ExtKey; // The extension encryption key wiimote_key g_ExtKey; // The extension encryption key
bool g_Encryption; // Encryption on or off bool g_Encryption; // Encryption on or off
@ -61,16 +60,11 @@ bool g_Encryption; // Encryption on or off
// Gamepad input // Gamepad input
int NumPads = 0, NumGoodPads = 0; // Number of goods pads int NumPads = 0, NumGoodPads = 0; // Number of goods pads
std::vector<InputCommon::CONTROLLER_INFO> joyinfo; std::vector<InputCommon::CONTROLLER_INFO> joyinfo;
InputCommon::CONTROLLER_STATE_NEW PadState[4]; CONTROLLER_MAPPING_WII WiiMapping[MAX_WIIMOTES];
InputCommon::CONTROLLER_MAPPING_NEW PadMapping[4];
// Keyboard input // Keyboard input
KeyboardWiimote g_Wiimote_kbd; bool KeyStatus[LAST_CONSTANT];
KeyboardNunchuck g_NunchuckExt;
KeyboardClassicController g_ClassicContExt;
KeyboardGH3GLP g_GH3Ext;
bool KeyStatus[64];
SWiimoteData g_WiimoteData[4];
} // namespace } // namespace
#endif //_EMU_DECLARATIONS_ #endif //_EMU_DECLARATIONS_

View File

@ -34,7 +34,7 @@ extern SWiimoteInitialize g_WiimoteInitialize;
namespace WiiMoteEmu namespace WiiMoteEmu
{ {
//****************************************************************************** //******************************************************************************
// Definitions and variable declarations // Definitions and variable declarations
//****************************************************************************** //******************************************************************************
@ -68,32 +68,23 @@ extern double g_RecordingCurrentTime[3];
#define WIIMOTE_REG_EXT_SIZE 0x100 #define WIIMOTE_REG_EXT_SIZE 0x100
#define WIIMOTE_REG_IR_SIZE 0x34 #define WIIMOTE_REG_IR_SIZE 0x34
extern u8 g_IR[4];
extern u8 g_Leds[4]; extern u8 g_Leds[4];
extern u8 g_Speaker; extern u8 g_Speaker;
extern u8 g_SpeakerVoice; extern u8 g_SpeakerVoice;
extern u8 g_IR;
extern u8 g_RegExt[MAX_WIIMOTES][WIIMOTE_REG_EXT_SIZE];
extern u8 g_Eeprom[WIIMOTE_EEPROM_SIZE]; extern u8 g_Eeprom[WIIMOTE_EEPROM_SIZE];
extern u8 g_RegSpeaker[WIIMOTE_REG_SPEAKER_SIZE]; extern u8 g_RegSpeaker[WIIMOTE_REG_SPEAKER_SIZE];
extern u8 g_RegMotionPlus[WIIMOTE_REG_EXT_SIZE]; extern u8 g_RegMotionPlus[WIIMOTE_REG_EXT_SIZE];
extern u8 g_RegExt[WIIMOTE_REG_EXT_SIZE];
extern u8 g_RegExtTmp[WIIMOTE_REG_EXT_SIZE]; extern u8 g_RegExtTmp[WIIMOTE_REG_EXT_SIZE];
extern u8 g_RegIr[WIIMOTE_REG_IR_SIZE]; extern u8 g_RegIr[WIIMOTE_REG_IR_SIZE];
extern int g_RefreshWiimote; extern int g_ID;
extern bool g_ReportingAuto[4]; extern bool g_ReportingAuto[MAX_WIIMOTES];
extern u8 g_ReportingMode; extern u8 g_ReportingMode[MAX_WIIMOTES];
extern u16 g_ReportingChannel; extern u16 g_ReportingChannel[MAX_WIIMOTES];
// Ack delay
struct wm_ackdelay
{
u8 Delay;
u8 ReportID;
u16 ChannelID;
bool Sent;
};
extern std::vector<wm_ackdelay> AckDelay;
extern wiimote_key g_ExtKey; // extension encryption key extern wiimote_key g_ExtKey; // extension encryption key
extern bool g_Encryption; extern bool g_Encryption;
@ -151,13 +142,95 @@ static const u8 nothing_id[] = { 0x00, 0x00, 0x00, 0x00, 0x2e, 0x2e };
// The id for a partially inserted extension // The id for a partially inserted extension
static const u8 partially_id[] = { 0x00, 0x00, 0x00, 0x00, 0xff, 0xff }; static const u8 partially_id[] = { 0x00, 0x00, 0x00, 0x00, 0xff, 0xff };
// Gamepad input
extern int NumPads, NumGoodPads; // Number of goods pads
extern std::vector<InputCommon::CONTROLLER_INFO> joyinfo;
extern InputCommon::CONTROLLER_STATE_NEW PadState[4];
extern InputCommon::CONTROLLER_MAPPING_NEW PadMapping[4];
// Wiimote status enum EExtensionType
{
EXT_NONE = 0,
EXT_NUNCHUCK,
EXT_CLASSIC_CONTROLLER,
EXT_GUITARHERO,
};
enum EInputType
{
FROM_KEYBOARD,
FROM_ANALOG1,
FROM_ANALOG2,
FROM_TRIGGER,
};
enum EButtonCode
{
EWM_A = 0, // Keyboard A and Mouse A
EWM_B,
EWM_ONE, EWM_TWO,
EWM_P, EWM_M, EWM_H,
EWM_L, EWM_R, EWM_U, EWM_D,
EWM_ROLL_L, EWM_ROLL_R,
EWM_PITCH_U, EWM_PITCH_D,
EWM_SHAKE,
ENC_Z, ENC_C,
ENC_L, ENC_R, ENC_U, ENC_D,
ENC_ROLL_L, ENC_ROLL_R,
ENC_PITCH_U, ENC_PITCH_D,
ENC_SHAKE,
ECC_A, ECC_B, ECC_X, ECC_Y,
ECC_P, ECC_M, ECC_H,
ECC_Tl, ECC_Tr, ECC_Zl, ECC_Zr,
ECC_Dl, ECC_Dr, ECC_Du, ECC_Dd,
ECC_Ll, ECC_Lr, ECC_Lu, ECC_Ld,
ECC_Rl, ECC_Rr, ECC_Ru, ECC_Rd,
EGH_Green, EGH_Red, EGH_Yellow, EGH_Blue, EGH_Orange,
EGH_Plus, EGH_Minus, EGH_Whammy,
EGH_Al, EGH_Ar, EGH_Au, EGH_Ad,
EGH_StrumUp, EGH_StrumDown,
LAST_CONSTANT,
};
union UAxis
{
int Code[6];
struct
{
int Lx;
int Ly;
int Rx;
int Ry;
int Tl; // Trigger
int Tr; // Trigger
};
};
struct SStickMapping
{
int NC;
int CCL;
int CCR;
int CCT; //Trigger
int GH; // Analog Stick
int GHB; // Whammy bar
};
struct STiltMapping
{
int InputWM;
int InputNC;
bool RollInvert;
bool PitchInvert;
int RollDegree;
bool RollSwing;
int RollRange;
int PitchDegree;
bool PitchSwing;
int PitchRange;
};
struct SDot struct SDot
{ {
int Rx, Ry, X, Y; int Rx, Ry, X, Y;
@ -188,80 +261,47 @@ struct STiltData
} }
}; };
struct SWiimoteData struct SMotion
{ {
// Raw X and Y coordinate and processed X and Y coordinates // Raw X and Y coordinate and processed X and Y coordinates
SIR IR; SIR IR;
STiltData TiltWM; STiltData TiltWM;
STiltData TiltNC; STiltData TiltNC;
}; };
extern SWiimoteData g_WiimoteData[4];
// Keyboard input
struct KeyboardWiimote struct CONTROLLER_MAPPING_WII // WII PAD MAPPING
{ {
enum EKeyboardWiimote SDL_Joystick *joy; // SDL joystick device
{ UAxis AxisState;
A = 0, // Keyboard A and Mouse A UAxis AxisMapping; // 6 Axes (Main, Sub, Triggers)
B, int TriggerType; // SDL or XInput trigger
ONE, TWO, int ID; // SDL joystick device ID
P, M, H, bool Rumble;
L, R, U, D, int RumbleStrength;
ROLL_L, ROLL_R, int DeadZoneL; // Analog 1 Deadzone
PITCH_U, PITCH_D, int DeadZoneR; // Analog 2 Deadzone
SHAKE, bool bCircle2Square;
MA, MB, std::string Diagonal;
LAST_CONSTANT
};
};
extern KeyboardWiimote g_Wiimote_kbd;
struct KeyboardNunchuck int Source; // 0: none, 1: emu, -1: real
{ bool bSideways;
enum EKeyboardNunchuck bool bUpright;
{ bool bMotionPlusConnected;
Z = 18, int iExtensionConnected;
C,
L, R, U, D,
ROLL_L, ROLL_R,
PITCH_U, PITCH_D,
SHAKE,
LAST_CONSTANT
};
};
extern KeyboardNunchuck g_NunchuckExt;
struct KeyboardClassicController STiltMapping Tilt;
{ SStickMapping Stick;
enum EKeyboardClassicController int Button[LAST_CONSTANT];
{ SMotion Motion;
A = 29,
B, X, Y,
P, M, H,
Tl, Tr, Zl, Zr,
Dl, Dr, Du, Dd,
Ll, Lr, Lu, Ld,
Rl, Rr, Ru, Rd,
LAST_CONSTANT
};
}; };
extern KeyboardClassicController g_ClassicContExt;
struct KeyboardGH3GLP
{
enum EKeyboardGH3GLP
{
Green = 52,
Red, Yellow, Blue, Orange,
Plus, Minus, Whammy,
Al, Ar, Au, Ad,
StrumUp, StrumDown,
LAST_CONSTANT
};
};
extern KeyboardGH3GLP g_GH3Ext;
// Gamepad input
extern int NumPads, NumGoodPads; // Number of goods pads
extern std::vector<InputCommon::CONTROLLER_INFO> joyinfo;
extern CONTROLLER_MAPPING_WII WiiMapping[4];
extern bool KeyStatus[64]; extern bool KeyStatus[64];
} // namespace } // namespace
#endif //_EMU_DEFINITIONS_ #endif //_EMU_DEFINITIONS_

View File

@ -39,30 +39,256 @@
namespace WiiMoteEmu namespace WiiMoteEmu
{ {
//****************************************************************************** //******************************************************************************
// Accelerometer functions // Accelerometer functions
//****************************************************************************** //******************************************************************************
/* // Wiimote accelerometer
// Test the calculations /* The accelerometer x, y and z values range from 0x00 to 0xff with the default
void TiltTest(u8 x, u8 y, u8 z) netural values being [y = 0x84, x = 0x84, z = 0x9f] according to a
{ source. The extremes are 0x00 for (-) and 0xff for (+). It's important that
int Roll, Pitch, RollAdj, PitchAdj; all values are not 0x80, the mouse pointer can disappear from the screen
PitchAccelerometerToDegree(x, y, z, Roll, Pitch, RollAdj, PitchAdj); permanently then, until z is adjusted back. This is because the game detects
std::string From = StringFromFormat("From: X:%i Y:%i Z:%i Roll:%s Pitch:%s", x, y, z, a steep pitch of the Wiimote then.
(Roll >= 0) ? StringFromFormat(" %03i", Roll).c_str() : StringFromFormat("%04i", Roll).c_str(),
(Pitch >= 0) ? StringFromFormat(" %03i", Pitch).c_str() : StringFromFormat("%04i", Pitch).c_str()); Wiimote Accelerometer Axes
+ (- -- X -- +)
| ___
| | |\ -
| | + || \
| . || \
Y |. .|| Z
| . || \
| | . || \
| |___|| +
- ---
float _Roll = (float)Roll, _Pitch = (float)Pitch;
PitchDegreeToAccelerometer(_Roll, _Pitch, x, y, z);
std::string To = StringFromFormat("%s\nTo: X:%i Y:%i Z:%i Roll:%s Pitch:%s", From.c_str(), x, y, z,
(_Roll >= 0) ? StringFromFormat(" %03i", (int)_Roll).c_str() : StringFromFormat("%04i", (int)_Roll).c_str(),
(_Pitch >= 0) ? StringFromFormat(" %03i", (int)_Pitch).c_str() : StringFromFormat("%04i", (int)_Pitch).c_str());
NOTICE_LOG(CONSOLE, "\n%s", To.c_str());
}
*/ */
// Single shake step of all three directions
void ShakeToAccelerometer(int &_x, int &_y, int &_z, STiltData &_TiltData)
{
switch(_TiltData.Shake)
{
case 0:
_TiltData.Shake = -1;
break;
case 1:
case 3:
_x = g_wm.cal_zero.x / 2;
_y = g_wm.cal_zero.y / 2;
_z = g_wm.cal_zero.z / 2;
break;
case 5:
case 7:
_x = (0xFF - g_wm.cal_zero.x ) / 2;
_y = (0xFF - g_wm.cal_zero.y ) / 2;
_z = (0xFF - g_wm.cal_zero.z ) / 2;
break;
case 2:
_x = 0x00;
_y = 0x00;
_z = 0x00;
break;
case 6:
_x = 0xFF;
_y = 0xFF;
_z = 0xFF;
break;
case 4:
_x = 0x80;
_y = 0x80;
_z = 0x80;
break;
default:
_TiltData.Shake = -1;
break;
}
_TiltData.Shake++;
if (_TiltData.Shake != 0)
{
DEBUG_LOG(WIIMOTE, "Shake: %i - 0x%02x, 0x%02x, 0x%02x", _TiltData.Shake, _x, _y, _z);
}
}
/* Tilting by gamepad. We can guess that the game will calculate
roll and pitch and use them as measures of the tilting. We are
interested in this tilting range 90 to -90*/
void TiltByGamepad(STiltData &_TiltData, int Type)
{
// Return if we have no pads
if (NumGoodPads == 0) return;
/* Adjust the pad state values, including a downscaling from the original
0x8000 size values to 0x80. The only reason we do this is that the code
below crrently assume that the range is 0 to 255 for all axes. If we
lose any precision by doing this we could consider not doing this
adjustment. And instead for example upsize the XInput trigger from 0x80
to 0x8000. */
int Lx = WiiMapping[g_ID].AxisState.Lx;
int Ly = WiiMapping[g_ID].AxisState.Ly;
int Rx = WiiMapping[g_ID].AxisState.Rx;
int Ry = WiiMapping[g_ID].AxisState.Ry;
int Tl = WiiMapping[g_ID].AxisState.Tl;
int Tr = WiiMapping[g_ID].AxisState.Tr;
// Save the Range in degrees, 45 and 90 are good values in some games
int RollRange = WiiMapping[g_ID].Tilt.RollRange;
int PitchRange = WiiMapping[g_ID].Tilt.PitchRange;
// The trigger currently only controls pitch, no roll, no free swing
if (Type == FROM_TRIGGER)
{
// Make the range the same dimension as the analog stick
Tl = Tl / 2;
Tr = Tr / 2;
// Invert
if (WiiMapping[g_ID].Tilt.PitchInvert) { Tl = -Tl; Tr = -Tr; }
// The final value
_TiltData.Pitch = (int)((float)PitchRange * ((float)(Tl - Tr) / 128.0f));
}
/* For the analog stick roll is by default set to the X-axis, pitch is by
default set to the Y-axis. By changing the axis mapping and the invert
options this can be altered in any way */
else if (Type == FROM_ANALOG1)
{
// Adjust the trigger to go between negative and positive values
Lx = Lx - 0x80;
Ly = Ly - 0x80;
// Invert
if (WiiMapping[g_ID].Tilt.RollInvert) Lx = -Lx; // else Tr = -Tr;
if (WiiMapping[g_ID].Tilt.PitchInvert) Ly = -Ly; // else Tr = -Tr;
// Produce the final value
_TiltData.Roll = (int)((RollRange) ? (float)RollRange * ((float)Lx / 128.0f) : Lx);
_TiltData.Pitch = (int)((PitchRange) ? (float)PitchRange * ((float)Ly / 128.0f) : Ly);
}
// Otherwise we are using ANALOG2
else
{
// Adjust the trigger to go between negative and positive values
Rx = Rx - 0x80;
Ry = Ry - 0x80;
// Invert
if (WiiMapping[g_ID].Tilt.RollInvert) Rx = -Rx; // else Tr = -Tr;
if (WiiMapping[g_ID].Tilt.PitchInvert) Ry = -Ry; // else Tr = -Tr;
// Produce the final value
_TiltData.Roll = (int)((RollRange) ? (float)RollRange * ((float)Rx / 128.0f) : Rx);
_TiltData.Pitch = (int)((PitchRange) ? (float)PitchRange * ((float)Ry / 128.0f) : Ry);
}
}
// Tilting by keyboard
void TiltByKeyboard(STiltData &_TiltData, int Type)
{
int _ROLL_LEFT_ = (Type) ? ENC_ROLL_L : EWM_ROLL_L;
int _ROLL_RIGHT_ = (Type) ? ENC_ROLL_R : EWM_ROLL_R;
int _PITCH_UP_ = (Type) ? ENC_PITCH_U : EWM_PITCH_U;
int _PITCH_DOWN_ = (Type) ? ENC_PITCH_D : EWM_PITCH_D;
// Do roll/pitch or free swing
if (IsKey(_ROLL_LEFT_))
{
if (WiiMapping[g_ID].Tilt.RollRange)
{
// Stop at the lower end of the range
if (_TiltData.Roll > -WiiMapping[g_ID].Tilt.RollRange)
_TiltData.Roll -= 3; // aim left
}
else // Free swing
{
_TiltData.Roll = -0x80 / 2;
}
}
else if (IsKey(_ROLL_RIGHT_))
{
if (WiiMapping[g_ID].Tilt.RollRange)
{
// Stop at the upper end of the range
if (_TiltData.Roll < WiiMapping[g_ID].Tilt.RollRange)
_TiltData.Roll += 3; // aim right
}
else // Free swing
{
_TiltData.Roll = 0x80 / 2;
}
}
else
{
_TiltData.Roll = 0;
}
if (IsKey(_PITCH_UP_))
{
if (WiiMapping[g_ID].Tilt.PitchRange)
{
// Stop at the lower end of the range
if (_TiltData.Pitch > -WiiMapping[g_ID].Tilt.PitchRange)
_TiltData.Pitch -= 3; // aim down
}
else // Free swing
{
_TiltData.Pitch = -0x80 / 2;
}
}
else if (IsKey(_PITCH_DOWN_))
{
if (WiiMapping[g_ID].Tilt.PitchRange)
{
// Stop at the upper end of the range
if (_TiltData.Pitch < WiiMapping[g_ID].Tilt.PitchRange)
_TiltData.Pitch += 3; // aim up
}
else // Free swing
{
_TiltData.Pitch = 0x80 / 2;
}
}
else
{
_TiltData.Pitch = 0;
}
}
// Tilting Wiimote (Wario Land aiming, Mario Kart steering and other things)
void TiltWiimote(int &_x, int &_y, int &_z)
{
// Select input method and return the x, y, x values
if (WiiMapping[g_ID].Tilt.InputWM == FROM_KEYBOARD)
TiltByKeyboard(WiiMapping[g_ID].Motion.TiltWM, 0);
else
TiltByGamepad(WiiMapping[g_ID].Motion.TiltWM, WiiMapping[g_ID].Tilt.InputWM);
// Adjust angles, it's only needed if both roll and pitch is used together
if (WiiMapping[g_ID].Tilt.RollRange && WiiMapping[g_ID].Tilt.PitchRange)
AdjustAngles(WiiMapping[g_ID].Motion.TiltWM.Roll, WiiMapping[g_ID].Motion.TiltWM.Pitch);
// Calculate the accelerometer value from this tilt angle
TiltToAccelerometer(_x, _y, _z,WiiMapping[g_ID].Motion.TiltWM);
//DEBUG_LOG(WIIMOTE, "Roll:%i, Pitch:%i, _x:%u, _y:%u, _z:%u", g_Wiimote_kbd.TiltData.Roll, g_Wiimote_kbd.TiltData.Pitch, _x, _y, _z);
}
// Tilting Nunchuck (Mad World, Dead Space and other things)
void TiltNunchuck(int &_x, int &_y, int &_z)
{
// Select input method and return the x, y, x values
if (WiiMapping[g_ID].Tilt.InputNC == FROM_KEYBOARD)
TiltByKeyboard(WiiMapping[g_ID].Motion.TiltNC, 1);
else
TiltByGamepad(WiiMapping[g_ID].Motion.TiltNC, WiiMapping[g_ID].Tilt.InputNC);
// Adjust angles, it's only needed if both roll and pitch is used together
if (WiiMapping[g_ID].Tilt.RollRange && WiiMapping[g_ID].Tilt.PitchRange)
AdjustAngles(WiiMapping[g_ID].Motion.TiltNC.Roll, WiiMapping[g_ID].Motion.TiltNC.Pitch);
// Calculate the accelerometer value from this tilt angle
TiltToAccelerometer(_x, _y, _z, WiiMapping[g_ID].Motion.TiltNC);
//DEBUG_LOG(WIIMOTE, "Roll:%i, Pitch:%i, _x:%u, _y:%u, _z:%u", g_NunchuckExt.TiltData.Roll, g_NunchuckExt.TiltData.Pitch, _x, _y, _z);
}
/* Angles adjustment for the upside down state when both roll and pitch is /* Angles adjustment for the upside down state when both roll and pitch is
used. When the absolute values of the angles go over 90 the Wiimote is used. When the absolute values of the angles go over 90 the Wiimote is
upside down and these adjustments are needed. */ upside down and these adjustments are needed. */
@ -101,17 +327,17 @@ void TiltToAccelerometer(int &_x, int &_y, int &_z, STiltData &_TiltData)
float x = 0.0f, y = 0.0f, z = 1.0f; // Gravity float x = 0.0f, y = 0.0f, z = 1.0f; // Gravity
// In these cases we can use the simple and accurate formula // In these cases we can use the simple and accurate formula
if(g_Config.Tilt.Range.Roll && g_Config.Tilt.Range.Pitch == 0) if(WiiMapping[g_ID].Tilt.RollRange && !WiiMapping[g_ID].Tilt.PitchRange)
{ {
x = sin(Roll); x = sin(Roll);
z = cos(Roll); z = cos(Roll);
} }
else if (g_Config.Tilt.Range.Pitch && g_Config.Tilt.Range.Roll == 0) else if (WiiMapping[g_ID].Tilt.PitchRange && !WiiMapping[g_ID].Tilt.RollRange)
{ {
y = sin(Pitch); y = sin(Pitch);
z = cos(Pitch); z = cos(Pitch);
} }
else if(g_Config.Tilt.Range.Roll && g_Config.Tilt.Range.Pitch) else if(WiiMapping[g_ID].Tilt.RollRange && WiiMapping[g_ID].Tilt.PitchRange)
{ {
// ==================================================== // ====================================================
/* This seems to always produce the exact same combination of x, y, z /* This seems to always produce the exact same combination of x, y, z
@ -142,33 +368,73 @@ void TiltToAccelerometer(int &_x, int &_y, int &_z, STiltData &_TiltData)
int iy = g_wm.cal_zero.y + (int)(yg * y); int iy = g_wm.cal_zero.y + (int)(yg * y);
int iz = g_wm.cal_zero.z + (int)(zg * z); int iz = g_wm.cal_zero.z + (int)(zg * z);
if (!g_Config.bUpright) if (!WiiMapping[g_ID].bUpright)
{ {
if(g_Config.Tilt.Range.Roll != 0) _x = ix; if(WiiMapping[g_ID].Tilt.RollRange) _x = ix;
if(g_Config.Tilt.Range.Pitch != 0) _y = iy; if(WiiMapping[g_ID].Tilt.PitchRange) _y = iy;
_z = iz; _z = iz;
} }
else // Upright wiimote else // Upright wiimote
{ {
if(g_Config.Tilt.Range.Roll != 0) _x = ix; if(WiiMapping[g_ID].Tilt.RollRange) _x = ix;
if(g_Config.Tilt.Range.Pitch != 0) _z = iy; if(WiiMapping[g_ID].Tilt.PitchRange) _z = iy;
_y = 0xFF - iz; _y = 0xFF - iz;
} }
// Direct mapping for swing, from analog stick to accelerometer // Direct mapping for swing, from analog stick to accelerometer
if (g_Config.Tilt.Range.Roll == 0) if (!WiiMapping[g_ID].Tilt.RollRange)
{ {
_x -= _TiltData.Roll; _x -= _TiltData.Roll;
} }
if (g_Config.Tilt.Range.Pitch == 0) if (!WiiMapping[g_ID].Tilt.PitchRange)
{ {
if (!g_Config.bUpright) if (!WiiMapping[g_ID].bUpright)
_z -= _TiltData.Pitch; _z -= _TiltData.Pitch;
else // Upright wiimote else // Upright wiimote
_y += _TiltData.Pitch; _y += _TiltData.Pitch;
} }
} }
// Rotate IR dot when rolling Wiimote
void RotateIRDot(int &_x, int &_y, STiltData &_TiltData)
{
if (!WiiMapping[g_ID].Tilt.RollRange || !_TiltData.Roll)
return;
// The IR camera resolution is 1023x767
float dot_x = _x - 1023.0f / 2;
float dot_y = _y - 767.0f / 2;
float radius = sqrt(pow(dot_x, 2) + pow(dot_y, 2));
float radian = atan2(dot_y, dot_x);
_x = (int)(radius * cos(radian + InputCommon::Deg2Rad((float)_TiltData.Roll)) + 1023.0f / 2);
_y = (int)(radius * sin(radian + InputCommon::Deg2Rad((float)_TiltData.Roll)) + 767.0f / 2);
// Out of sight check
if (_x < 0 || _x > 1023) _x = 0xFFFF;
if (_y < 0 || _y > 767) _y = 0xFFFF;
}
/*
// Test the calculations
void TiltTest(u8 x, u8 y, u8 z)
{
int Roll, Pitch, RollAdj, PitchAdj;
PitchAccelerometerToDegree(x, y, z, Roll, Pitch, RollAdj, PitchAdj);
std::string From = StringFromFormat("From: X:%i Y:%i Z:%i Roll:%s Pitch:%s", x, y, z,
(Roll >= 0) ? StringFromFormat(" %03i", Roll).c_str() : StringFromFormat("%04i", Roll).c_str(),
(Pitch >= 0) ? StringFromFormat(" %03i", Pitch).c_str() : StringFromFormat("%04i", Pitch).c_str());
float _Roll = (float)Roll, _Pitch = (float)Pitch;
PitchDegreeToAccelerometer(_Roll, _Pitch, x, y, z);
std::string To = StringFromFormat("%s\nTo: X:%i Y:%i Z:%i Roll:%s Pitch:%s", From.c_str(), x, y, z,
(_Roll >= 0) ? StringFromFormat(" %03i", (int)_Roll).c_str() : StringFromFormat("%04i", (int)_Roll).c_str(),
(_Pitch >= 0) ? StringFromFormat(" %03i", (int)_Pitch).c_str() : StringFromFormat("%04i", (int)_Pitch).c_str());
NOTICE_LOG(CONSOLE, "\n%s", To.c_str());
}
// Accelerometer to roll and pitch angles // Accelerometer to roll and pitch angles
float AccelerometerToG(float Current, float Neutral, float G) float AccelerometerToG(float Current, float Neutral, float G)
{ {
@ -219,7 +485,7 @@ void PitchAccelerometerToDegree(u8 _x, u8 _y, u8 _z, int &_Roll, int &_Pitch, in
_Roll = (int)Roll; _Roll = (int)Roll;
_Pitch = (int)Pitch; _Pitch = (int)Pitch;
/* Don't allow forces bigger than 1g */ // Don't allow forces bigger than 1g
if (x < -1.0) x = -1.0; else if (x > 1.0) x = 1.0; if (x < -1.0) x = -1.0; else if (x > 1.0) x = 1.0;
if (y < -1.0) y = -1.0; else if (y > 1.0) y = 1.0; if (y < -1.0) y = -1.0; else if (y > 1.0) y = 1.0;
if (z < -1.0) z = -1.0; else if (z > 1.0) z = 1.0; if (z < -1.0) z = -1.0; else if (z > 1.0) z = 1.0;
@ -237,13 +503,10 @@ void PitchAccelerometerToDegree(u8 _x, u8 _y, u8 _z, int &_Roll, int &_Pitch, in
_PitchAdj = (int)Pitch; _PitchAdj = (int)Pitch;
} }
//****************************************************************************** //******************************************************************************
// IR data functions // IR data functions
//****************************************************************************** //******************************************************************************
/*
// Calculate dot positions from the basic 10 byte IR data // Calculate dot positions from the basic 10 byte IR data
void IRData2DotsBasic(u8 *Data) void IRData2DotsBasic(u8 *Data)
{ {
@ -282,9 +545,7 @@ void IRData2DotsBasic(u8 *Data)
ReorderIRDots(); ReorderIRDots();
IRData2Distance(); IRData2Distance();
} }
*/
/*
// Calculate dot positions from the extented 12 byte IR data // Calculate dot positions from the extented 12 byte IR data
void IRData2Dots(u8 *Data) void IRData2Dots(u8 *Data)
{ {
@ -315,9 +576,7 @@ void IRData2Dots(u8 *Data)
ReorderIRDots(); ReorderIRDots();
IRData2Distance(); IRData2Distance();
} }
*/
/*
// Reorder the IR dots according to their x-axis value // Reorder the IR dots according to their x-axis value
void ReorderIRDots() void ReorderIRDots()
{ {
@ -350,9 +609,7 @@ void ReorderIRDots()
Dot[i].Order = order; Dot[i].Order = order;
} }
} }
*/
/*
// Calculate dot positions from the extented 12 byte IR data // Calculate dot positions from the extented 12 byte IR data
void IRData2Distance() void IRData2Distance()
{ {
@ -383,7 +640,6 @@ void IRData2Distance()
// Save the distance // Save the distance
g_Wiimote_kbd.IR.Distance = (int)sqrt((float)(xd*xd) + (float)(yd*yd)); g_Wiimote_kbd.IR.Distance = (int)sqrt((float)(xd*xd) + (float)(yd*yd));
} }
*/
//****************************************************************************** //******************************************************************************
// Classic Controller functions // Classic Controller functions
@ -400,5 +656,6 @@ std::string CCData2Values(u8 *Data)
((Data[0] & 0xc0) >> 3) | ((Data[1] & 0xc0) >> 5) | ((Data[2] & 0x80) >> 7), ((Data[0] & 0xc0) >> 3) | ((Data[1] & 0xc0) >> 5) | ((Data[2] & 0x80) >> 7),
(Data[2] & 0x1f)); (Data[2] & 0x1f));
} }
*/
} // WiiMoteEmu } // WiiMoteEmu

View File

@ -39,117 +39,6 @@ extern SWiimoteInitialize g_WiimoteInitialize;
namespace WiiMoteEmu namespace WiiMoteEmu
{ {
/* Bit shift conversions */
u32 convert24bit(const u8* src) {
return (src[0] << 16) | (src[1] << 8) | src[2];
}
u16 convert16bit(const u8* src) {
return (src[0] << 8) | src[1];
}
/* Calibrate the mouse position to the emulation window. g_WiimoteInitialize.hWnd is the rendering window handle. */
void GetMousePos(float& x, float& y)
{
#ifdef _WIN32
POINT point;
// Get the cursor position for the entire screen
GetCursorPos(&point);
// Get the cursor position relative to the upper left corner of the rendering window
ScreenToClient(g_WiimoteInitialize.hWnd, &point);
// Get the size of the rendering window. (In my case Rect.top and Rect.left was zero.)
RECT Rect;
GetClientRect(g_WiimoteInitialize.hWnd, &Rect);
// Width and height is the size of the rendering window
float WinWidth = (float)(Rect.right - Rect.left);
float WinHeight = (float)(Rect.bottom - Rect.top);
float XOffset = 0, YOffset = 0;
float PictureWidth = WinWidth, PictureHeight = WinHeight;
/* Calculate the actual picture size and location */
// Output: PictureWidth, PictureHeight, XOffset, YOffset
if (g_Config.bKeepAR43 || g_Config.bKeepAR169)
{
// The rendering window aspect ratio as a proportion of the 4:3 or 16:9 ratio
float Ratio = WinWidth / WinHeight / (g_Config.bKeepAR43 ? (4.0f / 3.0f) : (16.0f / 9.0f));
// Check if height or width is the limiting factor. If ratio > 1 the picture is to wide and have to limit the width.
if (Ratio > 1)
{
// Calculate the new width and height for glViewport, this is not the actual size of either the picture or the screen
PictureWidth = WinWidth / Ratio;
// Calculate the new X offset
// Move the left of the picture to the middle of the screen
XOffset = XOffset + WinWidth / 2.0f;
// Then remove half the picture height to move it to the horizontal center
XOffset = XOffset - PictureWidth / 2.0f;
}
// The window is to high, we have to limit the height
else
{
// Calculate the new width and height for glViewport, this is not the actual size of either the picture or the screen
// Invert the ratio to make it > 1
Ratio = 1.0f / Ratio;
PictureHeight = WinHeight / Ratio;
// Calculate the new Y offset
// Move the top of the picture to the middle of the screen
YOffset = YOffset + WinHeight / 2.0f;
// Then remove half the picture height to move it to the vertical center
YOffset = YOffset - PictureHeight / 2.0f;
}
/*
INFO_LOG(WIIMOTE, "Screen Width:%4.0f Height:%4.0f Ratio:%1.2f", WinWidth, WinHeight, Ratio);
INFO_LOG(WIIMOTE, "Picture Width:%4.1f Height:%4.1f YOffset:%4.0f XOffset:%4.0f", PictureWidth, PictureHeight, YOffset, XOffset);
*/
}
// Crop the picture from 4:3 to 5:4 or from 16:9 to 16:10.
// Output: PictureWidth, PictureHeight, XOffset, YOffset
if ((g_Config.bKeepAR43 || g_Config.bKeepAR169) && g_Config.bCrop)
{
float Ratio = g_Config.bKeepAR43 ? ((4.0f / 3.0f) / (5.0f / 4.0f)) : (((16.0f / 9.0f) / (16.0f / 10.0f)));
// The width and height we will add (calculate this before PictureWidth and PictureHeight is adjusted)
float IncreasedWidth = (Ratio - 1.0f) * PictureWidth;
float IncreasedHeight = (Ratio - 1.0f) * PictureHeight;
// The new width and height
PictureWidth = PictureWidth * Ratio;
PictureHeight = PictureHeight * Ratio;
// Adjust the X and Y offset
XOffset = float(XOffset - (IncreasedWidth / 2.0));
YOffset = float(YOffset - (IncreasedHeight / 2.0));
/*
INFO_LOG(WIIMOTE, "Crop Ratio:%1.2f IncrWidth:%3.0f IncrHeight:%3.0f", Ratio, IncreasedWidth, IncreasedHeight);
INFO_LOG(WIIMOTE, "Picture Width:%4.1f Height:%4.1f YOffset:%4.0f XOffset:%4.0f", PictureWidth, PictureHeight, YOffset, XOffset);
*/
}
// Return the mouse position as a fraction of one, inside the picture, with (0.0, 0.0) being the upper left corner of the picture
x = ((float)point.x - XOffset) / PictureWidth;
y = ((float)point.y - YOffset) / PictureHeight;
/*
INFO_LOG(WIIMOTE, "GetCursorPos: %i %i", point.x, point.y);
INFO_LOG(WIIMOTE, "GetClientRect: %i %i %i %i", Rect.left, Rect.right, Rect.top, Rect.bottom);
INFO_LOG(WIIMOTE, "Position X:%1.2f Y:%1.2f", x, y);
*/
#else
// TODO fix on linux
x = 0.5f;
y = 0.5f;
#endif
}
/* Homebrew encryption for 16 byte zero keys. */ /* Homebrew encryption for 16 byte zero keys. */
void CryptBuffer(u8* _buffer, u8 _size) void CryptBuffer(u8* _buffer, u8 _size)
{ {
@ -167,7 +56,6 @@ void WriteCrypted16(u8* _baseBlock, u16 _address, u16 _value)
*(u16*)(_baseBlock + _address) = cryptedValue; *(u16*)(_baseBlock + _address) = cryptedValue;
} }
/* Calculate Extenstion Regisister Calibration Checksum */ /* Calculate Extenstion Regisister Calibration Checksum */
// This function is not currently used, it's just here to show how the values // This function is not currently used, it's just here to show how the values
// in EmuDefinitions.h are calculated. // in EmuDefinitions.h are calculated.
@ -180,6 +68,27 @@ void GetCalibrationChecksum()
INFO_LOG(WIIMOTE, "0x%02x 0x%02x", (sum + 0x55), (sum + 0xaa)); INFO_LOG(WIIMOTE, "0x%02x 0x%02x", (sum + 0x55), (sum + 0xaa));
} }
// Calculate checksum for the nunchuck calibration. The last two bytes.
void ExtensionChecksum(u8 * Calibration)
{
u8 sum = 0; //u8 Byte15, Byte16;
for (u32 i = 0; i < sizeof(Calibration) - 2; i++)
{
sum += Calibration[i];
//INFO_LOG(WIIMOTE, "Plus 0x%02x", Calibration[i]);
}
// Byte15 = sum + 0x55; // Byte 15
// Byte16 = sum + 0xaa; // Byte 16
}
/* Bit shift conversions */
u32 convert24bit(const u8* src) {
return (src[0] << 16) | (src[1] << 8) | src[2];
}
u16 convert16bit(const u8* src) {
return (src[0] << 8) | src[1];
}
/* Load pre-recorded movements */ /* Load pre-recorded movements */
void LoadRecordedMovements() void LoadRecordedMovements()
@ -290,142 +199,118 @@ void LoadRecordedMovements()
} }
} }
// Update the accelerometer neutral values /* Calibrate the mouse position to the emulation window. g_WiimoteInitialize.hWnd is the rendering window handle. */
void UpdateEeprom() void GetMousePos(float& x, float& y)
{ {
g_wm.cal_zero.x = g_Eeprom[22]; #ifdef _WIN32
g_wm.cal_zero.y = g_Eeprom[23]; POINT point;
g_wm.cal_zero.z = g_Eeprom[24]; // Get the cursor position for the entire screen
g_wm.cal_g.x = g_Eeprom[26] - g_Eeprom[22]; GetCursorPos(&point);
g_wm.cal_g.y = g_Eeprom[27] - g_Eeprom[23]; // Get the cursor position relative to the upper left corner of the rendering window
g_wm.cal_g.z = g_Eeprom[28] - g_Eeprom[24]; ScreenToClient(g_WiimoteInitialize.hWnd, &point);
INFO_LOG(WIIMOTE, "UpdateEeprom: %i %i %i", // Get the size of the rendering window. (In my case Rect.top and Rect.left was zero.)
WiiMoteEmu::g_Eeprom[22], WiiMoteEmu::g_Eeprom[23], WiiMoteEmu::g_Eeprom[28]); RECT Rect;
GetClientRect(g_WiimoteInitialize.hWnd, &Rect);
// Width and height is the size of the rendering window
float WinWidth = (float)(Rect.right - Rect.left);
float WinHeight = (float)(Rect.bottom - Rect.top);
float XOffset = 0, YOffset = 0;
float PictureWidth = WinWidth, PictureHeight = WinHeight;
if(g_Config.iExtensionConnected == EXT_NUNCHUCK) /* Calculate the actual picture size and location */
// Output: PictureWidth, PictureHeight, XOffset, YOffset
if (g_Config.bKeepAR43 || g_Config.bKeepAR169)
{ {
g_nu.cal_zero.x = g_RegExt[0x20]; // The rendering window aspect ratio as a proportion of the 4:3 or 16:9 ratio
g_nu.cal_zero.y = g_RegExt[0x21]; float Ratio = WinWidth / WinHeight / (g_Config.bKeepAR43 ? (4.0f / 3.0f) : (16.0f / 9.0f));
g_nu.cal_zero.z = g_RegExt[0x22];
g_nu.cal_g.x = g_RegExt[0x24] - g_RegExt[0x20];
g_nu.cal_g.y = g_RegExt[0x25] - g_RegExt[0x21];
g_nu.cal_g.z = g_RegExt[0x26] - g_RegExt[0x22];
g_nu.jx.max = g_RegExt[0x28];
g_nu.jx.min = g_RegExt[0x29];
g_nu.jx.center = g_RegExt[0x2a];
g_nu.jy.max = g_RegExt[0x2b];
g_nu.jy.min = g_RegExt[0x2c];
g_nu.jy.center = g_RegExt[0x2d];
INFO_LOG(WIIMOTE, "UpdateNunchuck: %i %i %i %i %i", // Check if height or width is the limiting factor. If ratio > 1 the picture is to wide and have to limit the width.
WiiMoteEmu::g_RegExt[0x2a], WiiMoteEmu::g_RegExt[0x2d], if (Ratio > 1)
WiiMoteEmu::g_RegExt[0x20], WiiMoteEmu::g_RegExt[0x21], WiiMoteEmu::g_RegExt[0x26]); {
} // Calculate the new width and height for glViewport, this is not the actual size of either the picture or the screen
else if(g_Config.iExtensionConnected == EXT_CLASSIC_CONTROLLER) PictureWidth = WinWidth / Ratio;
{
g_ClassicContCalibration.Lx.max = g_RegExt[0x20];
g_ClassicContCalibration.Lx.min = g_RegExt[0x21];
g_ClassicContCalibration.Lx.center = g_RegExt[0x22];
g_ClassicContCalibration.Ly.max = g_RegExt[0x23];
g_ClassicContCalibration.Ly.min = g_RegExt[0x24];
g_ClassicContCalibration.Ly.center = g_RegExt[0x25];
g_ClassicContCalibration.Rx.max = g_RegExt[0x26]; // Calculate the new X offset
g_ClassicContCalibration.Rx.min = g_RegExt[0x27];
g_ClassicContCalibration.Rx.center = g_RegExt[0x28];
g_ClassicContCalibration.Ry.max = g_RegExt[0x29];
g_ClassicContCalibration.Ry.min = g_RegExt[0x2a];
g_ClassicContCalibration.Ry.center = g_RegExt[0x2b];
g_ClassicContCalibration.Tl.neutral = g_RegExt[0x2c]; // Move the left of the picture to the middle of the screen
g_ClassicContCalibration.Tr.neutral = g_RegExt[0x2d]; XOffset = XOffset + WinWidth / 2.0f;
// Then remove half the picture height to move it to the horizontal center
XOffset = XOffset - PictureWidth / 2.0f;
}
// The window is to high, we have to limit the height
else
{
// Calculate the new width and height for glViewport, this is not the actual size of either the picture or the screen
// Invert the ratio to make it > 1
Ratio = 1.0f / Ratio;
PictureHeight = WinHeight / Ratio;
INFO_LOG(WIIMOTE, "UpdateCC: %i %i %i %i %i", // Calculate the new Y offset
WiiMoteEmu::g_RegExt[0x2a], WiiMoteEmu::g_RegExt[0x2d], // Move the top of the picture to the middle of the screen
WiiMoteEmu::g_RegExt[0x20], WiiMoteEmu::g_RegExt[0x21], WiiMoteEmu::g_RegExt[0x26]); YOffset = YOffset + WinHeight / 2.0f;
} // Then remove half the picture height to move it to the vertical center
else if(g_Config.iExtensionConnected == EXT_GUITARHERO3_CONTROLLER) YOffset = YOffset - PictureHeight / 2.0f;
{ }
// TODO get the correct values here /*
g_GH3Calibration.Lx.max = g_RegExt[0x20]; INFO_LOG(WIIMOTE, "Screen Width:%4.0f Height:%4.0f Ratio:%1.2f", WinWidth, WinHeight, Ratio);
g_GH3Calibration.Lx.min = g_RegExt[0x21]; INFO_LOG(WIIMOTE, "Picture Width:%4.1f Height:%4.1f YOffset:%4.0f XOffset:%4.0f", PictureWidth, PictureHeight, YOffset, XOffset);
g_GH3Calibration.Lx.center = g_RegExt[0x22]; */
g_GH3Calibration.Ly.max = g_RegExt[0x23];
g_GH3Calibration.Ly.min = g_RegExt[0x24];
g_GH3Calibration.Ly.center = g_RegExt[0x25];
} }
} // Crop the picture from 4:3 to 5:4 or from 16:9 to 16:10.
// Output: PictureWidth, PictureHeight, XOffset, YOffset
// Calculate checksum for the nunchuck calibration. The last two bytes. if ((g_Config.bKeepAR43 || g_Config.bKeepAR169) && g_Config.bCrop)
void ExtensionChecksum(u8 * Calibration)
{
u8 sum = 0; //u8 Byte15, Byte16;
for (u32 i = 0; i < sizeof(Calibration) - 2; i++)
{ {
sum += Calibration[i]; float Ratio = g_Config.bKeepAR43 ? ((4.0f / 3.0f) / (5.0f / 4.0f)) : (((16.0f / 9.0f) / (16.0f / 10.0f)));
//INFO_LOG(WIIMOTE, "Plus 0x%02x", Calibration[i]);
} // The width and height we will add (calculate this before PictureWidth and PictureHeight is adjusted)
// Byte15 = sum + 0x55; // Byte 15 float IncreasedWidth = (Ratio - 1.0f) * PictureWidth;
// Byte16 = sum + 0xaa; // Byte 16 float IncreasedHeight = (Ratio - 1.0f) * PictureHeight;
}
// Set initial valuesm this done both in Init and Shutdown // The new width and height
void ResetVariables() PictureWidth = PictureWidth * Ratio;
{ PictureHeight = PictureHeight * Ratio;
g_RefreshWiimote = 0;
g_ReportingMode = 0;
g_ReportingChannel = 0;
g_Encryption = false;
for (int i = 0; i < 4; i++) // Adjust the X and Y offset
{ XOffset = float(XOffset - (IncreasedWidth / 2.0));
g_ReportingAuto[i] = false; YOffset = float(YOffset - (IncreasedHeight / 2.0));
memset(&g_WiimoteData[i], 0, sizeof(g_WiimoteData));
}
// Set default recording values /*
#if defined(HAVE_WX) && HAVE_WX INFO_LOG(WIIMOTE, "Crop Ratio:%1.2f IncrWidth:%3.0f IncrHeight:%3.0f", Ratio, IncreasedWidth, IncreasedHeight);
for (int i = 0; i < 3; i++) INFO_LOG(WIIMOTE, "Picture Width:%4.1f Height:%4.1f YOffset:%4.0f XOffset:%4.0f", PictureWidth, PictureHeight, YOffset, XOffset);
{ */
g_RecordingPlaying[i] = -1;
g_RecordingCounter[i] = 0;
g_RecordingPoint[i] = 0;
g_RecordingStart[i] = 0;
g_RecordingCurrentTime[i] = 0;
} }
// Return the mouse position as a fraction of one, inside the picture, with (0.0, 0.0) being the upper left corner of the picture
x = ((float)point.x - XOffset) / PictureWidth;
y = ((float)point.y - YOffset) / PictureHeight;
/*
INFO_LOG(WIIMOTE, "GetCursorPos: %i %i", point.x, point.y);
INFO_LOG(WIIMOTE, "GetClientRect: %i %i %i %i", Rect.left, Rect.right, Rect.top, Rect.bottom);
INFO_LOG(WIIMOTE, "Position X:%1.2f Y:%1.2f", x, y);
*/
#else
// TODO fix on linux
x = 0.5f;
y = 0.5f;
#endif #endif
g_EmulatedWiiMoteInitialized = false;
} }
// Update the extension calibration values with our default values /* This is not needed if we call FreeLibrary() when we stop a game, but if it's
void UpdateExtRegisterBlocks() not called we need to reset these variables. */
void Shutdown()
{ {
// Copy extension id and calibration to its register INFO_LOG(WIIMOTE, "ShutDown");
if(g_Config.iExtensionConnected == EXT_NUNCHUCK)
{
memcpy(g_RegExt + 0x20, nunchuck_calibration, sizeof(nunchuck_calibration));
memcpy(g_RegExt + 0x30, nunchuck_calibration, sizeof(nunchuck_calibration));
memcpy(g_RegExt + 0xfa, nunchuck_id, sizeof(nunchuck_id));
}
else if(g_Config.iExtensionConnected == EXT_CLASSIC_CONTROLLER)
{
memcpy(g_RegExt + 0x20, classic_calibration, sizeof(classic_calibration));
memcpy(g_RegExt + 0x30, classic_calibration, sizeof(classic_calibration));
memcpy(g_RegExt + 0xfa, classic_id, sizeof(classic_id));
}
else if(g_Config.iExtensionConnected == EXT_GUITARHERO3_CONTROLLER)
{
// TODO get the correct values here
memcpy(g_RegExt + 0x20, classic_calibration, sizeof(classic_calibration));
memcpy(g_RegExt + 0x30, classic_calibration, sizeof(classic_calibration));
memcpy(g_RegExt + 0xfa, gh3glp_id, sizeof(gh3glp_id));
}
INFO_LOG(WIIMOTE, "UpdateExtRegisterBlocks()"); ResetVariables();
// Close joypads
UpdateEeprom(); Close_Devices();
// Finally close SDL
if (SDL_WasInit(0))
SDL_Quit();
} }
// Start emulation // Start emulation
@ -433,27 +318,28 @@ void Initialize()
{ {
INFO_LOG(WIIMOTE, "Initialize"); INFO_LOG(WIIMOTE, "Initialize");
//if (g_EmulatedWiiMoteInitialized) return;
// Reset variables // Reset variables
ResetVariables(); ResetVariables();
/* Populate joyinfo for all attached devices and do g_Config.Load() if the
configuration window is not already open, if it's already open we
continue with the settings we have */
if(!g_FrameOpen)
{
g_Config.Load();
Search_Devices(joyinfo, NumPads, NumGoodPads);
}
// Write default Eeprom data to g_Eeprom[], this may be overwritten by // Write default Eeprom data to g_Eeprom[], this may be overwritten by
// WiiMoteReal::Initialize() after this function. // WiiMoteReal::Initialize() after this function.
memset(g_Eeprom, 0, WIIMOTE_EEPROM_SIZE); memset(g_Eeprom, 0, WIIMOTE_EEPROM_SIZE);
memcpy(g_Eeprom, EepromData_0, sizeof(EepromData_0)); memcpy(g_Eeprom, EepromData_0, sizeof(EepromData_0));
memcpy(g_Eeprom + 0x16D0, EepromData_16D0, sizeof(EepromData_16D0)); memcpy(g_Eeprom + 0x16D0, EepromData_16D0, sizeof(EepromData_16D0));
InitCalibration();
/* Populate joyinfo for all attached devices and do g_Config.Load() if the
configuration window is not already open, if it's already open we
continue with the settings we have */
//if(!g_FrameOpen)
Search_Devices(joyinfo, NumPads, NumGoodPads);
g_Config.Load();
// Copy extension id and calibration to its register, g_Config.Load() is needed before this // Copy extension id and calibration to its register, g_Config.Load() is needed before this
UpdateExtRegisterBlocks(); for (int i = 0; i < MAX_WIIMOTES; i++)
UpdateExtRegisterBlocks(i);
// The emulated Wiimote is initialized // The emulated Wiimote is initialized
g_EmulatedWiiMoteInitialized = true; g_EmulatedWiiMoteInitialized = true;
@ -471,23 +357,129 @@ void Initialize()
// g_RegExt[0xfc] = 0x9a; // g_RegExt[0xfc] = 0x9a;
} }
// Set initial valuesm this done both in Init and Shutdown
void ResetVariables()
{
g_EmulatedWiiMoteInitialized = false;
g_ID = 0;
g_Encryption = false;
for (int i = 0; i < MAX_WIIMOTES; i++)
{
g_ReportingAuto[i] = false;
g_ReportingMode[i] = 0;
g_ReportingChannel[i] = 0;
WiiMapping[i].Motion.TiltWM.Shake = 0;
WiiMapping[i].Motion.TiltWM.Roll = 0;
WiiMapping[i].Motion.TiltWM.Pitch = 0;
WiiMapping[i].Motion.TiltNC.Shake = 0;
WiiMapping[i].Motion.TiltNC.Roll = 0;
WiiMapping[i].Motion.TiltNC.Pitch = 0;
}
// Set default recording values
#if defined(HAVE_WX) && HAVE_WX
for (int i = 0; i < 3; i++)
{
g_RecordingPlaying[i] = -1;
g_RecordingCounter[i] = 0;
g_RecordingPoint[i] = 0;
g_RecordingStart[i] = 0;
g_RecordingCurrentTime[i] = 0;
}
#endif
}
// Initiate the accelerometer neutral values
void InitCalibration()
{
g_wm.cal_zero.x = g_Eeprom[22];
g_wm.cal_zero.y = g_Eeprom[23];
g_wm.cal_zero.z = g_Eeprom[24];
g_wm.cal_g.x = g_Eeprom[26] - g_Eeprom[22];
g_wm.cal_g.y = g_Eeprom[27] - g_Eeprom[23];
g_wm.cal_g.z = g_Eeprom[28] - g_Eeprom[24];
g_nu.cal_zero.x = nunchuck_calibration[0x00];
g_nu.cal_zero.y = nunchuck_calibration[0x01];
g_nu.cal_zero.z = nunchuck_calibration[0x02];
g_nu.cal_g.x = nunchuck_calibration[0x04] - nunchuck_calibration[0x00];
g_nu.cal_g.y = nunchuck_calibration[0x05] - nunchuck_calibration[0x01];
g_nu.cal_g.z = nunchuck_calibration[0x06] - nunchuck_calibration[0x02];
g_nu.jx.max = nunchuck_calibration[0x08];
g_nu.jx.min = nunchuck_calibration[0x09];
g_nu.jx.center = nunchuck_calibration[0x0a];
g_nu.jy.max = nunchuck_calibration[0x0b];
g_nu.jy.min = nunchuck_calibration[0x0c];
g_nu.jy.center = nunchuck_calibration[0x0d];
g_ClassicContCalibration.Lx.max = classic_calibration[0x00];
g_ClassicContCalibration.Lx.min = classic_calibration[0x01];
g_ClassicContCalibration.Lx.center = classic_calibration[0x02];
g_ClassicContCalibration.Ly.max = classic_calibration[0x03];
g_ClassicContCalibration.Ly.min = classic_calibration[0x04];
g_ClassicContCalibration.Ly.center = classic_calibration[0x05];
g_ClassicContCalibration.Rx.max = classic_calibration[0x06];
g_ClassicContCalibration.Rx.min = classic_calibration[0x07];
g_ClassicContCalibration.Rx.center = classic_calibration[0x08];
g_ClassicContCalibration.Ry.max = classic_calibration[0x09];
g_ClassicContCalibration.Ry.min = classic_calibration[0x0a];
g_ClassicContCalibration.Ry.center = classic_calibration[0x0b];
g_ClassicContCalibration.Tl.neutral = classic_calibration[0x0c];
g_ClassicContCalibration.Tr.neutral = classic_calibration[0x0d];
// TODO get the correct values here
g_GH3Calibration.Lx.max = classic_calibration[0x00];
g_GH3Calibration.Lx.min = classic_calibration[0x01];
g_GH3Calibration.Lx.center = classic_calibration[0x02];
g_GH3Calibration.Ly.max = classic_calibration[0x03];
g_GH3Calibration.Ly.min = classic_calibration[0x04];
g_GH3Calibration.Ly.center = classic_calibration[0x05];
}
// Update the extension calibration values with our default values
void UpdateExtRegisterBlocks(int Slot)
{
// Copy extension id and calibration to its register
if(WiiMapping[Slot].iExtensionConnected == EXT_NUNCHUCK)
{
memcpy(g_RegExt[Slot] + 0x20, nunchuck_calibration, sizeof(nunchuck_calibration));
memcpy(g_RegExt[Slot] + 0x30, nunchuck_calibration, sizeof(nunchuck_calibration));
memcpy(g_RegExt[Slot] + 0xfa, nunchuck_id, sizeof(nunchuck_id));
}
else if(WiiMapping[Slot].iExtensionConnected == EXT_CLASSIC_CONTROLLER)
{
memcpy(g_RegExt[Slot] + 0x20, classic_calibration, sizeof(classic_calibration));
memcpy(g_RegExt[Slot] + 0x30, classic_calibration, sizeof(classic_calibration));
memcpy(g_RegExt[Slot] + 0xfa, classic_id, sizeof(classic_id));
}
else if(WiiMapping[Slot].iExtensionConnected == EXT_GUITARHERO)
{
// TODO get the correct values here
memcpy(g_RegExt[Slot] + 0x20, classic_calibration, sizeof(classic_calibration));
memcpy(g_RegExt[Slot] + 0x30, classic_calibration, sizeof(classic_calibration));
memcpy(g_RegExt[Slot] + 0xfa, gh3glp_id, sizeof(gh3glp_id));
}
INFO_LOG(WIIMOTE, "UpdateExtRegisterBlocks()");
}
void DoState(PointerWrap &p) void DoState(PointerWrap &p)
{ {
// TODO: Shorten the list // TODO: Shorten the list
p.Do(g_Speaker); p.Do(g_Speaker);
p.Do(g_SpeakerVoice); p.Do(g_SpeakerVoice);
p.Do(g_IR);
p.DoArray(g_Eeprom, WIIMOTE_EEPROM_SIZE); p.DoArray(g_Eeprom, WIIMOTE_EEPROM_SIZE);
p.DoArray(g_RegSpeaker, WIIMOTE_REG_SPEAKER_SIZE); p.DoArray(g_RegSpeaker, WIIMOTE_REG_SPEAKER_SIZE);
p.DoArray(g_RegExt, WIIMOTE_REG_EXT_SIZE); p.DoArray(&g_RegExt[0][0], WIIMOTE_REG_EXT_SIZE * MAX_WIIMOTES);
p.DoArray(g_RegMotionPlus, WIIMOTE_REG_EXT_SIZE); p.DoArray(g_RegMotionPlus, WIIMOTE_REG_EXT_SIZE);
p.DoArray(g_RegExtTmp, WIIMOTE_REG_EXT_SIZE); p.DoArray(g_RegExtTmp, WIIMOTE_REG_EXT_SIZE);
p.DoArray(g_RegIr, WIIMOTE_REG_IR_SIZE); p.DoArray(g_RegIr, WIIMOTE_REG_IR_SIZE);
p.Do(g_ReportingMode);
p.Do(g_ReportingChannel);
p.Do(g_ExtKey); p.Do(g_ExtKey);
p.Do(g_Encryption); p.Do(g_Encryption);
@ -500,39 +492,28 @@ void DoState(PointerWrap &p)
//p.Do(g_NunchuckExt); //p.Do(g_NunchuckExt);
//p.Do(g_ClassicContExt); //p.Do(g_ClassicContExt);
for (int i = 0; i < 4; i++) for (int i = 0; i < MAX_WIIMOTES; i++)
{ {
p.Do(g_ReportingAuto[i]); p.Do(g_ReportingAuto[i]);
p.Do(g_ReportingMode[i]);
p.Do(g_ReportingChannel[i]);
//p.Do(g_IR[i]);
p.Do(g_Leds[i]); p.Do(g_Leds[i]);
p.Do(g_WiimoteData[i]);
} }
return; return;
} }
/* This is not needed if we call FreeLibrary() when we stop a game, but if it's
not called we need to reset these variables. */
void Shutdown()
{
INFO_LOG(WIIMOTE, "ShutDown");
ResetVariables();
// Close joypads
Close_Devices();
// Finally close SDL
if (SDL_WasInit(0))
SDL_Quit();
}
/* This function produce Wiimote Input, i.e. reports from the Wiimote in /* This function produce Wiimote Input, i.e. reports from the Wiimote in
response to Output from the Wii. */ response to Output from the Wii. */
void InterruptChannel(int _number, u16 _channelID, const void* _pData, u32 _Size) void InterruptChannel(int _number, u16 _channelID, const void* _pData, u32 _Size)
{ {
g_RefreshWiimote = _number;
/* Debugging. We have not yet decided how much of 'data' we will use, it's /* Debugging. We have not yet decided how much of 'data' we will use, it's
not determined by sizeof(data). We have to determine it by looking at not determined by sizeof(data). We have to determine it by looking at
the data cases. */ the data cases. */
//InterruptDebugging(true, (const void*)_pData); //InterruptDebugging(true, (const void*)_pData);
g_ID = _number;
hid_packet* hidp = (hid_packet*)_pData; hid_packet* hidp = (hid_packet*)_pData;
INFO_LOG(WIIMOTE, "Emu InterruptChannel (page: %i, type: 0x%02x, param: 0x%02x)", _number, hidp->type, hidp->param); INFO_LOG(WIIMOTE, "Emu InterruptChannel (page: %i, type: 0x%02x, param: 0x%02x)", _number, hidp->type, hidp->param);
@ -572,18 +553,17 @@ void InterruptChannel(int _number, u16 _channelID, const void* _pData, u32 _Size
} }
} }
void ControlChannel(int _number, u16 _channelID, const void* _pData, u32 _Size) void ControlChannel(int _number, u16 _channelID, const void* _pData, u32 _Size)
{ {
// Check for custom communication // Check for custom communication
if(_channelID == 99 && *(const u8*)_pData == WIIMOTE_RECONNECT) if(_channelID == 99 && *(const u8*)_pData == WIIMOTE_DISCONNECT)
{ {
WARN_LOG(WIIMOTE, "Wiimote: #%i Disconnected", _number); WARN_LOG(WIIMOTE, "Wiimote: #%i Disconnected", _number);
g_ReportingAuto[_number] = false; g_ReportingAuto[_number] = false;
return; return;
} }
g_RefreshWiimote = _number; g_ID = _number;
hid_packet* hidp = (hid_packet*)_pData; hid_packet* hidp = (hid_packet*)_pData;
@ -606,8 +586,8 @@ void ControlChannel(int _number, u16 _channelID, const void* _pData, u32 _Size)
// In case it happens, we will send back a handshake which means report failed/rejected // In case it happens, we will send back a handshake which means report failed/rejected
// (TO_BE_VERIFIED) // (TO_BE_VERIFIED)
// //
u8 handshake = 0; u8 handshake = HID_HANDSHAKE_SUCCESS;
g_WiimoteInitialize.pWiimoteInput(g_RefreshWiimote, _channelID, &handshake, 1); g_WiimoteInitialize.pWiimoteInput(g_ID, _channelID, &handshake, 1);
PanicAlert("HID_TYPE_DATA - OUTPUT: Ambiguous Control Channel Report!"); PanicAlert("HID_TYPE_DATA - OUTPUT: Ambiguous Control Channel Report!");
} }
@ -624,7 +604,6 @@ void ControlChannel(int _number, u16 _channelID, const void* _pData, u32 _Size)
} }
/* This is called from Wiimote_Update(). See SystemTimers.cpp for a /* This is called from Wiimote_Update(). See SystemTimers.cpp for a
documentation. I'm not sure exactly how often this function is called but I documentation. I'm not sure exactly how often this function is called but I
think it's tied to the frame rate of the game rather than a certain amount think it's tied to the frame rate of the game rather than a certain amount
@ -634,42 +613,36 @@ void Update(int _number)
if (g_ReportingAuto[_number] == false) if (g_ReportingAuto[_number] == false)
return; return;
g_RefreshWiimote = _number; g_ID = _number;
// Read input or not // Read input or not
if (g_Config.bInputActive) if (WiiMapping[g_ID].Source > 0)
{ {
ReadLinuxKeyboard(); ReadLinuxKeyboard();
/*
if ((g_Config.Tilt.Type == g_Config.Tilt.TRIGGER || g_Config.Tilt.Type == g_Config.Tilt.ANALOG1 || g_Config.Tilt.Type == g_Config.Tilt.ANALOG2
|| g_Config.Nunchuck.Type == g_Config.Nunchuck.ANALOG1 || g_Config.Nunchuck.Type == g_Config.Nunchuck.ANALOG2
|| g_Config.ClassicController.LType == g_Config.ClassicController.ANALOG1 || g_Config.ClassicController.LType == g_Config.ClassicController.ANALOG2
|| g_Config.ClassicController.RType == g_Config.ClassicController.ANALOG1 || g_Config.ClassicController.RType == g_Config.ClassicController.ANALOG2)
&& NumGoodPads > 0 && joyinfo.size() > (u32)PadMapping[0].ID)
*/
// Check if the pad state should be updated // Check if the pad state should be updated
if (NumGoodPads > 0 && joyinfo.size() > (u32)PadMapping[g_RefreshWiimote].ID) if (NumGoodPads > 0 && joyinfo.size() > (u32)WiiMapping[g_ID].ID)
WiiMoteEmu::GetJoyState(PadState[g_RefreshWiimote], PadMapping[g_RefreshWiimote], g_RefreshWiimote, joyinfo[PadMapping[g_RefreshWiimote].ID].NumButtons); UpdatePadState(WiiMapping[g_ID]);
} }
switch(g_ReportingMode) switch(g_ReportingMode[g_ID])
{ {
case 0: case 0:
break; break;
case WM_REPORT_CORE: case WM_REPORT_CORE:
SendReportCore(g_ReportingChannel); SendReportCore(g_ReportingChannel[g_ID]);
break; break;
case WM_REPORT_CORE_ACCEL: case WM_REPORT_CORE_ACCEL:
SendReportCoreAccel(g_ReportingChannel); SendReportCoreAccel(g_ReportingChannel[g_ID]);
break; break;
case WM_REPORT_CORE_ACCEL_IR12: case WM_REPORT_CORE_ACCEL_IR12:
SendReportCoreAccelIr12(g_ReportingChannel); SendReportCoreAccelIr12(g_ReportingChannel[g_ID]);
break; break;
case WM_REPORT_CORE_ACCEL_EXT16: case WM_REPORT_CORE_ACCEL_EXT16:
SendReportCoreAccelExt16(g_ReportingChannel); SendReportCoreAccelExt16(g_ReportingChannel[g_ID]);
break; break;
case WM_REPORT_CORE_ACCEL_IR10_EXT6: case WM_REPORT_CORE_ACCEL_IR10_EXT6:
SendReportCoreAccelIr10Ext(g_ReportingChannel); SendReportCoreAccelIr10Ext(g_ReportingChannel[g_ID]);
break; break;
} }
} }
@ -699,37 +672,11 @@ void ReadLinuxKeyboard()
break; break;
} }
for (int i = g_Wiimote_kbd.A; i < g_Wiimote_kbd.LAST_CONSTANT; i++) for (int i = 0; i < LAST_CONSTANT; i++)
{ {
if (key == PadMapping[0].Wm.keyForControls[i - g_Wiimote_kbd.A]) if (key == WiiMapping[g_ID].Button[i])
KeyStatus[i] = true; KeyStatus[i] = true;
} }
switch (g_Config.iExtensionConnected)
{
case EXT_NUNCHUCK:
for (int i = g_NunchuckExt.Z; i < g_NunchuckExt.LAST_CONSTANT; i++)
{
if (key == PadMapping[0].Nc.keyForControls[i - g_NunchuckExt.Z])
KeyStatus[i] = true;
}
break;
case EXT_CLASSIC_CONTROLLER:
for (int i = g_ClassicContExt.A; i < g_ClassicContExt.LAST_CONSTANT; i++)
{
if (key == PadMapping[0].Cc.keyForControls[i - g_ClassicContExt.A])
KeyStatus[i] = true;
}
break;
case EXT_GUITARHERO3_CONTROLLER:
for (int i = g_GH3Ext.Green; i < g_GH3Ext.LAST_CONSTANT; i++)
{
if (key == PadMapping[0].GH3c.keyForControls[i - g_GH3Ext.Green])
KeyStatus[i] = true;
}
break;
default:
break;
}
break; break;
} }
case KeyRelease: case KeyRelease:
@ -743,38 +690,11 @@ void ReadLinuxKeyboard()
break; break;
} }
for (int i = g_Wiimote_kbd.A; i < g_Wiimote_kbd.LAST_CONSTANT; i++) for (int i = 0; i < LAST_CONSTANT; i++)
{ {
if (key == PadMapping[0].Wm.keyForControls[i - g_Wiimote_kbd.A]) if (key == WiiMapping[g_ID].Button[i])
KeyStatus[i] = false; KeyStatus[i] = false;
} }
switch (g_Config.iExtensionConnected)
{
case EXT_NUNCHUCK:
for (int i = g_NunchuckExt.Z; i < g_NunchuckExt.LAST_CONSTANT; i++)
{
if (key == PadMapping[0].Nc.keyForControls[i - g_NunchuckExt.Z])
KeyStatus[i] = false;
}
break;
case EXT_CLASSIC_CONTROLLER:
for (int i = g_ClassicContExt.A; i < g_ClassicContExt.LAST_CONSTANT; i++)
{
if (key == PadMapping[0].Cc.keyForControls[i - g_ClassicContExt.A])
KeyStatus[i] = false;
}
break;
case EXT_GUITARHERO3_CONTROLLER:
for (int i = g_GH3Ext.Green; i < g_GH3Ext.LAST_CONSTANT; i++)
{
if (key == PadMapping[0].GH3c.keyForControls[i - g_GH3Ext.Green])
KeyStatus[i] = false;
}
break;
default:
break;
}
break; break;
} }
default: default:

View File

@ -32,47 +32,50 @@ namespace WiiMoteEmu
u32 convert24bit(const u8* src); u32 convert24bit(const u8* src);
u16 convert16bit(const u8* src); u16 convert16bit(const u8* src);
void GetMousePos(float& x, float& y);
// General functions // General functions
void ResetVariables();
void Initialize(); void Initialize();
void DoState(PointerWrap &p);
void Shutdown(); void Shutdown();
void InitCalibration();
void UpdateExtRegisterBlocks(int Slot);
void InterruptChannel(int _number, u16 _channelID, const void* _pData, u32 _Size); void InterruptChannel(int _number, u16 _channelID, const void* _pData, u32 _Size);
void ControlChannel(int _number, u16 _channelID, const void* _pData, u32 _Size) ; void ControlChannel(int _number, u16 _channelID, const void* _pData, u32 _Size) ;
void Update(int _number); void Update(int _number);
void DoState(PointerWrap &p);
void ReadLinuxKeyboard(); void ReadLinuxKeyboard();
bool IsKey(int Key);
// Recordings // Recordings
void LoadRecordedMovements(); void LoadRecordedMovements();
void GetMousePos(float& x, float& y);
// Registers and calibration values
void ResetVariables();
void UpdateEeprom();
void UpdateExtRegisterBlocks();
// Gamepad // Gamepad
void Close_Devices(); void Close_Devices();
bool Search_Devices(std::vector<InputCommon::CONTROLLER_INFO> &_joyinfo, int &_NumPads, int &_NumGoodPads); bool Search_Devices(std::vector<InputCommon::CONTROLLER_INFO> &_joyinfo, int &_NumPads, int &_NumGoodPads);
void GetJoyState(InputCommon::CONTROLLER_STATE_NEW &_PadState, InputCommon::CONTROLLER_MAPPING_NEW _PadMapping, int controller, int NumButtons); void GetAxisState(CONTROLLER_MAPPING_WII &_WiiMapping);
void PadStateAdjustments(int &Lx, int &Ly, int &Rx, int &Ry, int &Tl, int &Tr); void UpdatePadState(CONTROLLER_MAPPING_WII &_WiiMapping);
// Accelerometer void TiltWiimote(int &_x, int &_y, int &_z);
void PitchAccelerometerToDegree(u8 _x, u8 _y, u8 _z, int &_Roll, int &_Pitch, int&, int&); void TiltNunchuck(int &_x, int &_y, int &_z);
float AccelerometerToG(float Current, float Neutral, float G);
void ShakeToAccelerometer(int &_x, int &_y, int &_z, STiltData &_TiltData); void ShakeToAccelerometer(int &_x, int &_y, int &_z, STiltData &_TiltData);
void TiltToAccelerometer(int &_x, int &_y, int &_z, STiltData &_TiltData); void TiltToAccelerometer(int &_x, int &_y, int &_z, STiltData &_TiltData);
void AdjustAngles(int &Roll, int &Pitch); void AdjustAngles(int &Roll, int &Pitch);
void RotateIRDot(int &_x, int &_y, STiltData &_TiltData);
// Accelerometer
//void PitchAccelerometerToDegree(u8 _x, u8 _y, u8 _z, int &_Roll, int &_Pitch, int&, int&);
//float AccelerometerToG(float Current, float Neutral, float G);
// IR data // IR data
void RotateIRDots(int &_x, int &_y, STiltData &_TiltData); //void IRData2Dots(u8 *Data);
void IRData2Dots(u8 *Data); //void IRData2DotsBasic(u8 *Data);
void IRData2DotsBasic(u8 *Data);
//void ReorderIRDots(); //void ReorderIRDots();
//void IRData2Distance(); //void IRData2Distance();
// Classic Controller data // Classic Controller data
std::string CCData2Values(u8 *Data); //std::string CCData2Values(u8 *Data);
}; // WiiMoteEmu }; // WiiMoteEmu

View File

@ -46,18 +46,18 @@ extern void PAD_RumbleClose();
void Close_Devices() void Close_Devices()
{ {
PAD_RumbleClose(); PAD_RumbleClose();
/* Close all devices carefully. We must check that we are not accessing any // Close all devices carefully. We must check that we are not accessing any
undefined vector elements or any bad devices */ // undefined vector elements or any bad devices
for (int i = 0; i < 1; i++) for (int i = 0; i < MAX_WIIMOTES; i++)
{ {
if (SDL_WasInit(0) && joyinfo.size() > (u32)PadMapping[i].ID) if (SDL_WasInit(0) && joyinfo.size() > (u32)WiiMapping[i].ID)
if (PadState[i].joy && joyinfo.at(PadMapping[i].ID).Good) if (WiiMapping[i].joy && joyinfo.at(WiiMapping[i].ID).Good)
{ {
INFO_LOG(WIIMOTE, "ShutDown: %i", PadState[i].joy); INFO_LOG(WIIMOTE, "ShutDown: %i", WiiMapping[i].ID);
if(SDL_JoystickOpened(PadMapping[i].ID)) if(SDL_JoystickOpened(WiiMapping[i].ID))
{ {
SDL_JoystickClose(PadState[i].joy); SDL_JoystickClose(WiiMapping[i].joy);
PadState[i].joy = NULL; WiiMapping[i].joy = NULL;
} }
} }
} }
@ -81,99 +81,50 @@ bool Search_Devices(std::vector<InputCommon::CONTROLLER_INFO> &_joyinfo, int &_N
return false; return false;
// Update the PadState[].joy handle // Update the PadState[].joy handle
for (int i = 0; i < 1; i++) for (int i = 0; i < MAX_WIIMOTES; i++)
{ {
if (joyinfo.size() > (u32)PadMapping[i].ID) if (joyinfo.size() > (u32)WiiMapping[i].ID)
if(joyinfo.at(PadMapping[i].ID).Good) if(joyinfo.at(WiiMapping[i].ID).Good)
PadState[i].joy = SDL_JoystickOpen(PadMapping[i].ID); WiiMapping[i].joy = SDL_JoystickOpen(WiiMapping[i].ID);
} }
return WasGotten; return WasGotten;
} }
// Return adjusted input values
void PadStateAdjustments(int &Lx, int &Ly, int &Rx, int &Ry, int &Tl, int &Tr)
{
// This has to be changed if multiple Wiimotes are to be supported later
const int Page = 0;
// Copy all states to a local variable
Lx = PadState[Page].Axis.Lx;
Ly = PadState[Page].Axis.Ly;
Rx = PadState[Page].Axis.Rx;
Ry = PadState[Page].Axis.Ry;
Tl = PadState[Page].Axis.Tl;
Tr = PadState[Page].Axis.Tr;
// Check the circle to square option
if(PadMapping[Page].bCircle2Square)
{
InputCommon::Square2Circle(Lx, Ly, Page, PadMapping[Page].SDiagonal, true);
}
// Dead zone adjustment
float DeadZoneLeft = (float)PadMapping[Page].DeadZoneL / 100.0f;
float DeadZoneRight = (float)PadMapping[Page].DeadZoneR / 100.0f;
if (InputCommon::IsDeadZone(DeadZoneLeft, Lx, Ly))
{
Lx = 0;
Ly = 0;
}
if (InputCommon::IsDeadZone(DeadZoneRight, Rx, Ry))
{
Rx = 0;
Ry = 0;
}
// Downsize the values from 0x8000 to 0x80
Lx = InputCommon::Pad_Convert(Lx);
Ly = InputCommon::Pad_Convert(Ly);
Rx = InputCommon::Pad_Convert(Rx);
Ry = InputCommon::Pad_Convert(Ry);
// The XInput range is already 0 to 0x80
if (PadMapping[Page].triggertype == InputCommon::CTL_TRIGGER_SDL)
{
Tl = InputCommon::Pad_Convert(PadState[Page].Axis.Tl);
Tr = InputCommon::Pad_Convert(PadState[Page].Axis.Tr);
}
}
// Request joystick state // Request joystick state
/* Called from: PAD_GetStatus() Input: The virtual device 0, 1, 2 or 3 /* 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 Function: Updates the PadState struct with the current pad status. The input
value "controller" is for a virtual controller 0 to 3. */ value "controller" is for a virtual controller 0 to 3. */
void GetAxisState(CONTROLLER_MAPPING_WII &_WiiMapping)
void GetJoyState(InputCommon::CONTROLLER_STATE_NEW &_PadState, InputCommon::CONTROLLER_MAPPING_NEW _PadMapping, int controller, int NumButtons)
{ {
// Return if we have no pads
if (NumGoodPads == 0) return;
// Update the gamepad status // Update the gamepad status
SDL_JoystickUpdate(); SDL_JoystickUpdate();
// Update axis states. It doesn't hurt much if we happen to ask for nonexisting axises here. // Update axis states. It doesn't hurt much if we happen to ask for nonexisting axises here.
_PadState.Axis.Lx = SDL_JoystickGetAxis(_PadState.joy, _PadMapping.Axis.Lx); _WiiMapping.AxisState.Lx = SDL_JoystickGetAxis(_WiiMapping.joy, _WiiMapping.AxisMapping.Lx);
_PadState.Axis.Ly = SDL_JoystickGetAxis(_PadState.joy, _PadMapping.Axis.Ly); _WiiMapping.AxisState.Ly = SDL_JoystickGetAxis(_WiiMapping.joy, _WiiMapping.AxisMapping.Ly);
_PadState.Axis.Rx = SDL_JoystickGetAxis(_PadState.joy, _PadMapping.Axis.Rx); _WiiMapping.AxisState.Rx = SDL_JoystickGetAxis(_WiiMapping.joy, _WiiMapping.AxisMapping.Rx);
_PadState.Axis.Ry = SDL_JoystickGetAxis(_PadState.joy, _PadMapping.Axis.Ry); _WiiMapping.AxisState.Ry = SDL_JoystickGetAxis(_WiiMapping.joy, _WiiMapping.AxisMapping.Ry);
// Update the analog trigger axis values // Update the analog trigger axis values
#ifdef _WIN32 #ifdef _WIN32
if (_PadMapping.triggertype == InputCommon::CTL_TRIGGER_SDL) if (_WiiMapping.TriggerType == InputCommon::CTL_TRIGGER_SDL)
{ {
#endif #endif
// If we are using SDL analog triggers the buttons have to be mapped as 1000 or up, otherwise they are not used // If we are using SDL analog triggers the buttons have to be mapped as 1000 or up, otherwise they are not used
// We must also check that we are not asking for a negative axis number because SDL_JoystickGetAxis() has // We must also check that we are not asking for a negative axis number because SDL_JoystickGetAxis() has
// no good way of handling that // no good way of handling that
if ((_PadMapping.Axis.Tl - 1000) >= 0) _PadState.Axis.Tl = SDL_JoystickGetAxis(_PadState.joy, _PadMapping.Axis.Tl - 1000); if ((_WiiMapping.AxisMapping.Tl - 1000) >= 0)
if ((_PadMapping.Axis.Tr - 1000) >= 0) _PadState.Axis.Tr = SDL_JoystickGetAxis(_PadState.joy, _PadMapping.Axis.Tr - 1000); _WiiMapping.AxisState.Tl = SDL_JoystickGetAxis(_WiiMapping.joy, _WiiMapping.AxisMapping.Tl - 1000);
if ((_WiiMapping.AxisMapping.Tr - 1000) >= 0)
_WiiMapping.AxisState.Tr = SDL_JoystickGetAxis(_WiiMapping.joy, _WiiMapping.AxisMapping.Tr - 1000);
#ifdef _WIN32 #ifdef _WIN32
} }
else else
{ {
_PadState.Axis.Tl = XInput::GetXI(0, _PadMapping.Axis.Tl - 1000); _WiiMapping.AxisState.Tl = XInput::GetXI(0, _WiiMapping.AxisMapping.Tl - 1000);
_PadState.Axis.Tr = XInput::GetXI(0, _PadMapping.Axis.Tr - 1000); _WiiMapping.AxisState.Tr = XInput::GetXI(0, _WiiMapping.AxisMapping.Tr - 1000);
} }
#endif #endif
@ -196,5 +147,53 @@ void GetJoyState(InputCommon::CONTROLLER_STATE_NEW &_PadState, InputCommon::CONT
);*/ );*/
} }
void UpdatePadState(CONTROLLER_MAPPING_WII &_WiiMapping)
{
// Return if we have no pads
if (NumGoodPads == 0) return;
GetAxisState(_WiiMapping);
int &Lx = _WiiMapping.AxisState.Lx;
int &Ly = _WiiMapping.AxisState.Ly;
int &Rx = _WiiMapping.AxisState.Rx;
int &Ry = _WiiMapping.AxisState.Ry;
int &Tl = _WiiMapping.AxisState.Tl;
int &Tr = _WiiMapping.AxisState.Tr;
// Check the circle to square option
if(_WiiMapping.bCircle2Square)
{
InputCommon::Square2Circle(Lx, Ly, 0, _WiiMapping.Diagonal, true);
InputCommon::Square2Circle(Rx, Ry, 0, _WiiMapping.Diagonal, true);
}
// Dead zone adjustment
float DeadZoneLeft = (float)_WiiMapping.DeadZoneL / 100.0f;
float DeadZoneRight = (float)_WiiMapping.DeadZoneR / 100.0f;
if (InputCommon::IsDeadZone(DeadZoneLeft, Lx, Ly))
{
Lx = 0;
Ly = 0;
}
if (InputCommon::IsDeadZone(DeadZoneRight, Rx, Ry))
{
Rx = 0;
Ry = 0;
}
// Downsize the values from 0x8000 to 0x80
Lx = InputCommon::Pad_Convert(Lx);
Ly = InputCommon::Pad_Convert(Ly);
Rx = InputCommon::Pad_Convert(Rx);
Ry = InputCommon::Pad_Convert(Ry);
// The XInput range is already 0 to 0x80
if (_WiiMapping.TriggerType == InputCommon::CTL_TRIGGER_SDL)
{
Tl = InputCommon::Pad_Convert(Tl);
Tr = InputCommon::Pad_Convert(Tr);
}
}
} // end of namespace WiiMoteEmu } // end of namespace WiiMoteEmu

View File

@ -69,12 +69,9 @@ void HidOutputReport(u16 _channelID, wm_report* sr)
switch(sr->wm) switch(sr->wm)
{ {
case WM_RUMBLE: // 0x10 case WM_RUMBLE: // 0x10
{ PAD_Rumble(g_ID, sr->data[0]);
// TODO: need more accurate rumble
const int Page = 0;
PAD_Rumble(Page, sr->data[0]);
break; break;
}
case WM_LEDS: // 0x11 case WM_LEDS: // 0x11
WmLeds(_channelID, (wm_leds*)sr->data); WmLeds(_channelID, (wm_leds*)sr->data);
break; break;
@ -88,8 +85,8 @@ void HidOutputReport(u16 _channelID, wm_report* sr)
// This enables or disables the IR lights, we update the global variable g_IR // This enables or disables the IR lights, we update the global variable g_IR
// so that WmRequestStatus() knows about it // so that WmRequestStatus() knows about it
INFO_LOG(WIIMOTE, "WM IR Enable: 0x%02x", sr->data[0]); INFO_LOG(WIIMOTE, "WM IR Enable: 0x%02x", sr->data[0]);
if(sr->data[0] == 0x02) g_IR = 0; if(sr->data[0] == 0x02) g_IR[g_ID] = 0;
else if(sr->data[0] == 0x06) g_IR = 1; else if(sr->data[0] == 0x06) g_IR[g_ID] = 1;
break; break;
case WM_SPEAKER_ENABLE: // 0x14 case WM_SPEAKER_ENABLE: // 0x14
@ -163,8 +160,7 @@ int WriteWmReportHdr(u8* dst, u8 wm)
void WmLeds(u16 _channelID, wm_leds* leds) void WmLeds(u16 _channelID, wm_leds* leds)
{ {
INFO_LOG(WIIMOTE, "Set LEDs: %x, Rumble: %x", leds->leds, leds->rumble); INFO_LOG(WIIMOTE, "Set LEDs: %x, Rumble: %x", leds->leds, leds->rumble);
g_Leds[g_ID] = leds->leds;
g_Leds[g_RefreshWiimote] = leds->leds;
} }
@ -190,7 +186,7 @@ void WmSendAck(u16 _channelID, u8 _reportID)
DEBUG_LOG(WIIMOTE, "WMSendAck"); DEBUG_LOG(WIIMOTE, "WMSendAck");
DEBUG_LOG(WIIMOTE, " Report ID: %02x", _reportID); DEBUG_LOG(WIIMOTE, " Report ID: %02x", _reportID);
g_WiimoteInitialize.pWiimoteInput(g_RefreshWiimote, _channelID, DataFrame, Offset); g_WiimoteInitialize.pWiimoteInput(g_ID, _channelID, DataFrame, Offset);
// Debugging // Debugging
//ReadDebugging(true, DataFrame, Offset); //ReadDebugging(true, DataFrame, Offset);
@ -233,7 +229,7 @@ void WmReadData(u16 _channelID, wm_read_data* rd)
DEBUG_LOG(WIIMOTE, " Case 0xa2: g_RegSpeaker"); DEBUG_LOG(WIIMOTE, " Case 0xa2: g_RegSpeaker");
break; break;
case 0xA4: case 0xA4:
block = g_RegExt; block = g_RegExt[g_ID];
blockSize = WIIMOTE_REG_EXT_SIZE; blockSize = WIIMOTE_REG_EXT_SIZE;
DEBUG_LOG(WIIMOTE, " Case 0xa4: ExtReg"); DEBUG_LOG(WIIMOTE, " Case 0xa4: ExtReg");
break; break;
@ -264,11 +260,11 @@ void WmReadData(u16 _channelID, wm_read_data* rd)
if(((address >> 16) & 0xfe) == 0xa4) if(((address >> 16) & 0xfe) == 0xa4)
{ {
// Check if encrypted reads is on // Check if encrypted reads is on
if(g_RegExt[0xf0] == 0xaa) if(g_RegExt[g_ID][0xf0] == 0xaa)
{ {
/* Copy the registry to a temporary space. We don't want to change the unencrypted /* Copy the registry to a temporary space. We don't want to change the unencrypted
data in the registry */ data in the registry */
memcpy(g_RegExtTmp, g_RegExt, sizeof(g_RegExt)); memcpy(g_RegExtTmp, g_RegExt[g_ID], sizeof(g_RegExt[0]));
// Encrypt g_RegExtTmp at that location // Encrypt g_RegExtTmp at that location
wiimote_encrypt(&g_ExtKey, &g_RegExtTmp[address & 0xffff], (address & 0xffff), (u8)size); wiimote_encrypt(&g_ExtKey, &g_RegExtTmp[address & 0xffff], (address & 0xffff), (u8)size);
@ -364,7 +360,7 @@ void SendReadDataReply(u16 _channelID, void* _Base, u16 _Address, int _Size)
#endif #endif
// Send a piece // Send a piece
g_WiimoteInitialize.pWiimoteInput(g_RefreshWiimote, _channelID, DataFrame, Offset); g_WiimoteInitialize.pWiimoteInput(g_ID, _channelID, DataFrame, Offset);
// Update the size that is left // Update the size that is left
_Size -= copySize; _Size -= copySize;
@ -408,7 +404,7 @@ void WmWriteData(u16 _channelID, wm_write_data* wd)
DEBUG_LOG(WIIMOTE, " Case 0xa2: RegSpeaker"); DEBUG_LOG(WIIMOTE, " Case 0xa2: RegSpeaker");
break; break;
case 0xA4: case 0xA4:
block = g_RegExt; // Extension Controller register block = g_RegExt[g_ID]; // Extension Controller register
blockSize = WIIMOTE_REG_EXT_SIZE; blockSize = WIIMOTE_REG_EXT_SIZE;
DEBUG_LOG(WIIMOTE, " Case 0xa4: ExtReg"); DEBUG_LOG(WIIMOTE, " Case 0xa4: ExtReg");
break; break;
@ -450,7 +446,7 @@ void WmWriteData(u16 _channelID, wm_write_data* wd)
that we send it parts of a key, only the last full key will have an that we send it parts of a key, only the last full key will have an
effect */ effect */
if(address >= 0x40 && address <= 0x4c) if(address >= 0x40 && address <= 0x4c)
wiimote_gen_key(&g_ExtKey, &g_RegExt[0x40]); wiimote_gen_key(&g_ExtKey, &g_RegExt[g_ID][0x40]);
} }
} }
@ -482,8 +478,8 @@ void WmRequestStatus(u16 _channelID, wm_request_status* rs, int Extension)
#if defined(HAVE_WX) && HAVE_WX #if defined(HAVE_WX) && HAVE_WX
FillReportInfo(pStatus->buttons); FillReportInfo(pStatus->buttons);
#endif #endif
pStatus->leds = g_Leds[g_RefreshWiimote]; // leds are 4 bit pStatus->leds = g_Leds[g_ID]; // leds are 4 bit
pStatus->ir = g_IR; // 1 bit pStatus->ir = g_IR[g_ID]; // 1 bit
pStatus->speaker = g_Speaker; // 1 bit pStatus->speaker = g_Speaker; // 1 bit
pStatus->battery_low = 0; // battery is okay pStatus->battery_low = 0; // battery is okay
pStatus->battery = 0x5f; // fully charged pStatus->battery = 0x5f; // fully charged
@ -497,24 +493,18 @@ void WmRequestStatus(u16 _channelID, wm_request_status* rs, int Extension)
if (Extension == -1) if (Extension == -1)
{ {
// Read config value for the first time // Read config value for the first time
if(g_Config.iExtensionConnected == EXT_NONE) pStatus->extension = (WiiMapping[g_ID].iExtensionConnected == EXT_NONE) ? 0 : 1;
pStatus->extension = 0;
else
pStatus->extension = 1;
} }
else else
{ {
if(Extension) pStatus->extension = (Extension) ? 1 : 0;
pStatus->extension = 1;
else
pStatus->extension = 0;
} }
INFO_LOG(WIIMOTE, "Request Status"); INFO_LOG(WIIMOTE, "Request Status");
DEBUG_LOG(WIIMOTE, " Extension: %x", pStatus->extension); DEBUG_LOG(WIIMOTE, " Extension: %x", pStatus->extension);
DEBUG_LOG(WIIMOTE, " Buttons: 0x%04x", pStatus->buttons); DEBUG_LOG(WIIMOTE, " Buttons: 0x%04x", pStatus->buttons);
g_WiimoteInitialize.pWiimoteInput(g_RefreshWiimote, _channelID, DataFrame, Offset); g_WiimoteInitialize.pWiimoteInput(g_ID, _channelID, DataFrame, Offset);
// Debugging // Debugging
//ReadDebugging(true, DataFrame, Offset); //ReadDebugging(true, DataFrame, Offset);

File diff suppressed because it is too large Load Diff

View File

@ -325,7 +325,7 @@ void ReadWiimote()
Temp = ArrayToString(g_WiiMotesFromWiiUse[i]->read_req->buf, sizeof(WiiMoteEmu::EepromData_0), 0, 30); Temp = ArrayToString(g_WiiMotesFromWiiUse[i]->read_req->buf, sizeof(WiiMoteEmu::EepromData_0), 0, 30);
memcpy(WiiMoteEmu::g_Eeprom, g_WiiMotesFromWiiUse[i]->read_req->buf, sizeof(WiiMoteEmu::EepromData_0)); memcpy(WiiMoteEmu::g_Eeprom, g_WiiMotesFromWiiUse[i]->read_req->buf, sizeof(WiiMoteEmu::EepromData_0));
DEBUG_LOG(WIIMOTE, "EEPROM: %s", Temp.c_str()); DEBUG_LOG(WIIMOTE, "EEPROM: %s", Temp.c_str());
WiiMoteEmu::UpdateEeprom(); WiiMoteEmu::InitCalibration();
g_RunTemporary = false; g_RunTemporary = false;
} }
break; break;

View File

@ -72,7 +72,7 @@ void SetDeviceForcesXY(int pad, int nXYForce);
HRESULT InitRumble(HWND hWnd); HRESULT InitRumble(HWND hWnd);
LPDIRECTINPUT8 g_Rumble; // DInput Rumble object LPDIRECTINPUT8 g_Rumble; // DInput Rumble object
RUMBLE pRumble[4]; // 4 GC Rumble Pads RUMBLE pRumble[MAX_WIIMOTES];
////////////////////// //////////////////////
// Use PAD rumble // Use PAD rumble
@ -80,7 +80,7 @@ RUMBLE pRumble[4]; // 4 GC Rumble Pads
void Pad_Use_Rumble(u8 _numPAD) void Pad_Use_Rumble(u8 _numPAD)
{ {
if (PadMapping[_numPAD].Rumble) if (WiiMapping[_numPAD].Rumble)
{ {
if (!g_Rumble) if (!g_Rumble)
{ {
@ -106,12 +106,12 @@ void PAD_Rumble(u8 _numPAD, unsigned int _uType)
int Strenght = 0; int Strenght = 0;
if (PadMapping[_numPAD].Rumble) // rumble activated if (WiiMapping[_numPAD].Rumble) // rumble activated
{ {
if (_uType == 1) if (_uType == 1)
{ {
// it looks like _uStrength is equal to 3 everytime anyway... // it looks like _uStrength is equal to 3 everytime anyway...
Strenght = 1000 * (PadMapping[_numPAD].RumbleStrength); Strenght = 1000 * (WiiMapping[_numPAD].RumbleStrength);
Strenght = Strenght > 10000 ? 10000 : Strenght; Strenght = Strenght > 10000 ? 10000 : Strenght;
} }
else else
@ -138,10 +138,10 @@ HRESULT InitRumble(HWND hWnd)
if (FAILED(hr = g_Rumble->EnumDevices( DI8DEVCLASS_GAMECTRL, EnumFFDevicesCallback, NULL, DIEDFL_ATTACHEDONLY | DIEDFL_FORCEFEEDBACK))) if (FAILED(hr = g_Rumble->EnumDevices( DI8DEVCLASS_GAMECTRL, EnumFFDevicesCallback, NULL, DIEDFL_ATTACHEDONLY | DIEDFL_FORCEFEEDBACK)))
return hr; return hr;
for (int i=0; i<4; i++) for (int i = 0; i < MAX_WIIMOTES; i++)
{ {
if (NULL == pRumble[i].g_pDevice) if (NULL == pRumble[i].g_pDevice)
PadMapping[i].Rumble = false; // Disable Rumble for this pad only. WiiMapping[i].Rumble = false; // Disable Rumble for this pad only.
else else
{ {
pRumble[i].g_pDevice->SetDataFormat(&c_dfDIJoystick); pRumble[i].g_pDevice->SetDataFormat(&c_dfDIJoystick);
@ -161,7 +161,7 @@ HRESULT InitRumble(HWND hWnd)
{ {
PanicAlert("Device %d doesn't seem to work ! \nRumble for device %d is now Disabled !", i+1); PanicAlert("Device %d doesn't seem to work ! \nRumble for device %d is now Disabled !", i+1);
PadMapping[i].Rumble = false; // Disable Rumble for this pad WiiMapping[i].Rumble = false; // Disable Rumble for this pad
continue; // Next pad continue; // Next pad
} }
@ -268,15 +268,15 @@ BOOL CALLBACK EnumFFDevicesCallback(const DIDEVICEINSTANCE* pInst, VOID* pContex
else else
return DIENUM_CONTINUE; return DIENUM_CONTINUE;
//PanicAlert("DInput ID : %d \nSDL ID (1-4) : %d / %d / %d / %d\n", JoystickID, PadMapping[0].ID, PadMapping[1].ID, PadMapping[2].ID, PadMapping[3].ID); //PanicAlert("DInput ID : %d \nSDL ID (1-4) : %d / %d / %d / %d\n", JoystickID, WiiMapping[0].ID, WiiMapping[1].ID, WiiMapping[2].ID, WiiMapping[3].ID);
for (int i=0; i<4; i++) for (int i=0; i<4; i++)
{ {
if (PadMapping[i].ID == JoystickID) // if SDL ID = DInput ID -> we're dealing with the same device if (WiiMapping[i].ID == JoystickID) // if SDL ID = DInput ID -> we're dealing with the same device
{ {
// a DInput device is created even if rumble is disabled on startup // a DInput device is created even if rumble is disabled on startup
// this way, you can toggle the rumble setting while in game // this way, you can toggle the rumble setting while in game
//if (PadMapping[i].enabled) // && PadMapping[i].Rumble //if (WiiMapping[i].enabled) // && WiiMapping[i].Rumble
pRumble[i].g_pDevice = pDevice; // everything looks good, save the DInput device pRumble[i].g_pDevice = pDevice; // everything looks good, save the DInput device
} }
} }
@ -298,7 +298,7 @@ void PAD_RumbleClose()
// It may look weird, but we don't free anything here, it was the cause of crashes // It may look weird, but we don't free anything here, it was the cause of crashes
// on stop, and the DLL isn't unloaded anyway, so the pointers stay // on stop, and the DLL isn't unloaded anyway, so the pointers stay
// We just stop the rumble in case it's still playing an effect. // We just stop the rumble in case it's still playing an effect.
for (int i=0; i<4; i++) for (int i = 0; i < MAX_WIIMOTES; i++)
{ {
if (pRumble[i].g_pDevice && pRumble[i].g_pEffect) if (pRumble[i].g_pDevice && pRumble[i].g_pEffect)
pRumble[i].g_pEffect->Stop(); pRumble[i].g_pEffect->Stop();
@ -337,7 +337,7 @@ bool PAD_Init_Rumble(u8 _numPAD, SDL_Joystick *SDL_Device)
{ {
SDL_HapticClose(pRumble[_numPAD].g_pDevice); // No effect SDL_HapticClose(pRumble[_numPAD].g_pDevice); // No effect
pRumble[_numPAD].g_pDevice = 0; pRumble[_numPAD].g_pDevice = 0;
PadMapping[_numPAD].Rumble = false; WiiMapping[_numPAD].Rumble = false;
return false; return false;
} }
@ -369,7 +369,7 @@ void PAD_Rumble(u8 _numPAD, unsigned int _uType)
int Strenght = 0; int Strenght = 0;
#ifdef SDL_RUMBLE #ifdef SDL_RUMBLE
if (PadMapping[_numPAD].Rumble) // rumble activated if (WiiMapping[_numPAD].Rumble) // rumble activated
{ {
if (!pRumble[_numPAD].g_pDevice) if (!pRumble[_numPAD].g_pDevice)
return; return;

View File

@ -16,22 +16,6 @@
// http://code.google.com/p/dolphin-emu/ // http://code.google.com/p/dolphin-emu/
// Current issues
/*
The real Wiimote fails to answer the core correctly sometmes. Leading to an
unwanted disconnection. And there is currenty no functions to reconnect with
the game. There are two ways to solve this:
1. Make a reconnect function in the IOS emulation
2. Detect failed answers in this plugin and solve it by replacing them with
emulated answers.
The first solution seems easier, if I knew a little better how the /dev/usb/oh1
and Wiimote functions worked.
*/
#include "Common.h" // Common #include "Common.h" // Common
#include "LogManager.h" #include "LogManager.h"
#include "StringUtil.h" #include "StringUtil.h"
@ -80,8 +64,8 @@ gh3_cal g_GH3Calibration;
// Debugging // Debugging
bool g_DebugAccelerometer = false; bool g_DebugAccelerometer = false;
bool g_DebugData = false; bool g_DebugData = false;
bool g_DebugComm = true; bool g_DebugComm = false;
bool g_DebugSoundData = true; bool g_DebugSoundData = false;
bool g_DebugCustom = false; bool g_DebugCustom = false;
// Update speed // Update speed
@ -184,12 +168,12 @@ void DllDebugger(HWND _hParent, bool Show) {}
void DllConfig(HWND _hParent) void DllConfig(HWND _hParent)
{ {
// We do a pad search before creating the dialog
WiiMoteEmu::Search_Devices(WiiMoteEmu::joyinfo, WiiMoteEmu::NumPads, WiiMoteEmu::NumGoodPads);
// Load settings // Load settings
g_Config.Load(); g_Config.Load();
// We do a pad search before creating the dialog
WiiMoteEmu::Search_Devices(WiiMoteEmu::joyinfo, WiiMoteEmu::NumPads, WiiMoteEmu::NumGoodPads);
#if defined(HAVE_WX) && HAVE_WX #if defined(HAVE_WX) && HAVE_WX
if (!m_BasicConfigFrame) if (!m_BasicConfigFrame)
@ -198,9 +182,15 @@ void DllConfig(HWND _hParent)
m_BasicConfigFrame->Close(true); m_BasicConfigFrame->Close(true);
// Only allow one open at a time // Only allow one open at a time
if (!m_BasicConfigFrame->IsShown()) if (!m_BasicConfigFrame->IsShown())
{
g_FrameOpen = true;
m_BasicConfigFrame->ShowModal(); m_BasicConfigFrame->ShowModal();
}
else else
{
g_FrameOpen = false;
m_BasicConfigFrame->Hide(); m_BasicConfigFrame->Hide();
}
#endif #endif
} }
@ -208,11 +198,8 @@ void DllConfig(HWND _hParent)
// Start emulation // Start emulation
void Initialize(void *init) void Initialize(void *init)
{ {
// Declarations
SWiimoteInitialize _WiimoteInitialize = *(SWiimoteInitialize *)init;
g_WiimoteInitialize = _WiimoteInitialize;
g_EmulatorRunning = true; g_EmulatorRunning = true;
g_WiimoteInitialize = *(SWiimoteInitialize *)init;
// Update the GUI if the configuration window is already open // Update the GUI if the configuration window is already open
#if defined(HAVE_WX) && HAVE_WX #if defined(HAVE_WX) && HAVE_WX
@ -220,7 +207,7 @@ void Initialize(void *init)
{ {
// Save the settings // Save the settings
g_Config.Save(); g_Config.Save();
// Save the ISO Id // Load the ISO Id
g_ISOId = g_WiimoteInitialize.ISOId; g_ISOId = g_WiimoteInitialize.ISOId;
// Load the settings // Load the settings
g_Config.Load(); g_Config.Load();
@ -228,15 +215,25 @@ void Initialize(void *init)
} }
#endif #endif
#if defined(HAVE_X11) && HAVE_X11 #if defined(HAVE_X11) && HAVE_X11
WMdisplay = (Display*)_WiimoteInitialize.hWnd; WMdisplay = (Display*)g_WiimoteInitialize.hWnd;
#endif #endif
// Save the ISO Id, again if we had a window open
g_ISOId = g_WiimoteInitialize.ISOId; g_ISOId = g_WiimoteInitialize.ISOId;
DoInitialize();
DEBUG_LOG(WIIMOTE, "ISOId: %08x %s", g_WiimoteInitialize.ISOId, Hex2Ascii(g_WiimoteInitialize.ISOId).c_str()); DEBUG_LOG(WIIMOTE, "ISOId: %08x %s", g_WiimoteInitialize.ISOId, Hex2Ascii(g_WiimoteInitialize.ISOId).c_str());
// Run this first so that WiiMoteReal::Initialize() overwrites g_Eeprom
WiiMoteEmu::Initialize();
/* We will run WiiMoteReal::Initialize() even if we are not using a real
wiimote, to check if there is a real wiimote connected. We will initiate
wiiuse.dll, but we will return before creating a new thread for it if we
find no real Wiimotes. Then g_RealWiiMotePresent will also be
false. This function call will be done instantly whether there is a real
Wiimote connected or not. It takes no time for Wiiuse to check for
connected Wiimotes. */
#if HAVE_WIIUSE
if (g_Config.bConnectRealWiimote) WiiMoteReal::Initialize();
#endif
} }
// If a game is not running this is called by the Configuration window when it's closed // If a game is not running this is called by the Configuration window when it's closed
@ -254,13 +251,6 @@ void Shutdown(void)
#if defined(HAVE_WX) && HAVE_WX #if defined(HAVE_WX) && HAVE_WX
if(m_BasicConfigFrame) m_BasicConfigFrame->UpdateGUI(); if(m_BasicConfigFrame) m_BasicConfigFrame->UpdateGUI();
#endif #endif
// Reset the variables
WiiMoteEmu::ResetVariables();
/* Don't shut down the wiimote when we still have the config window open, we may still want
want to use the Wiimote in the config window. */
return;
} }
#if HAVE_WIIUSE #if HAVE_WIIUSE
@ -278,10 +268,10 @@ void DoState(unsigned char **ptr, int mode)
//p.Do(g_EmulatorRunning); //p.Do(g_EmulatorRunning);
//p.Do(g_ISOId); //p.Do(g_ISOId);
p.Do(g_FrameOpen); //p.Do(g_FrameOpen);
p.Do(g_RealWiiMotePresent); //p.Do(g_RealWiiMotePresent);
p.Do(g_RealWiiMoteInitialized); //p.Do(g_RealWiiMoteInitialized);
p.Do(g_EmulatedWiiMoteInitialized); //p.Do(g_EmulatedWiiMoteInitialized);
//p.Do(g_UpdateCounter); //p.Do(g_UpdateCounter);
//p.Do(g_UpdateTime); //p.Do(g_UpdateTime);
//p.Do(g_UpdateRate); //p.Do(g_UpdateRate);
@ -305,18 +295,16 @@ void DoState(unsigned char **ptr, int mode)
*/ */
void Wiimote_InterruptChannel(int _number, u16 _channelID, const void* _pData, u32 _Size) void Wiimote_InterruptChannel(int _number, u16 _channelID, const void* _pData, u32 _Size)
{ {
const u8* data = (const u8*)_pData;
// Debugging // Debugging
{ #if defined(_DEBUG) || defined(DEBUGFAST)
DEBUG_LOG(WIIMOTE, "Wiimote_InterruptChannel"); DEBUG_LOG(WIIMOTE, "Wiimote_InterruptChannel");
DEBUG_LOG(WIIMOTE, " Channel ID: %04x", _channelID); DEBUG_LOG(WIIMOTE, " Channel ID: %04x", _channelID);
std::string Temp = ArrayToString(data, _Size); std::string Temp = ArrayToString((const u8*)_pData, _Size);
DEBUG_LOG(WIIMOTE, " Data: %s", Temp.c_str()); DEBUG_LOG(WIIMOTE, " Data: %s", Temp.c_str());
} #endif
// Decice where to send the message // Decice where to send the message
if (!g_Config.bUseRealWiimote || !g_RealWiiMotePresent) if (WiiMoteEmu::WiiMapping[_number].Source >= 0)
WiiMoteEmu::InterruptChannel(_number, _channelID, _pData, _Size); WiiMoteEmu::InterruptChannel(_number, _channelID, _pData, _Size);
#if HAVE_WIIUSE #if HAVE_WIIUSE
else if (g_RealWiiMotePresent) else if (g_RealWiiMotePresent)
@ -326,17 +314,17 @@ void Wiimote_InterruptChannel(int _number, u16 _channelID, const void* _pData, u
// Function: Used for the initial Bluetooth HID handshake. // Function: Used for the initial Bluetooth HID handshake.
void Wiimote_ControlChannel(int _number, u16 _channelID, const void* _pData, u32 _Size) void Wiimote_ControlChannel(int _number, u16 _channelID, const void* _pData, u32 _Size)
{ {
// Debugging // Debugging
#if defined(_DEBUG) || defined(DEBUGFAST) #if defined(_DEBUG) || defined(DEBUGFAST)
DEBUG_LOG(WIIMOTE, "Wiimote_ControlChannel"); DEBUG_LOG(WIIMOTE, "Wiimote_ControlChannel");
DEBUG_LOG(WIIMOTE, " Channel ID: %04x", _channelID);
std::string Temp = ArrayToString((const u8*)_pData, _Size); std::string Temp = ArrayToString((const u8*)_pData, _Size);
DEBUG_LOG(WIIMOTE, " Data: %s", Temp.c_str()); DEBUG_LOG(WIIMOTE, " Data: %s", Temp.c_str());
#endif #endif
if (!g_Config.bUseRealWiimote || !g_RealWiiMotePresent) if (WiiMoteEmu::WiiMapping[_number].Source >= 0)
WiiMoteEmu::ControlChannel(_number, _channelID, _pData, _Size); WiiMoteEmu::ControlChannel(_number, _channelID, _pData, _Size);
#if HAVE_WIIUSE #if HAVE_WIIUSE
else if (g_RealWiiMotePresent) else if (g_RealWiiMotePresent)
@ -345,8 +333,7 @@ void Wiimote_ControlChannel(int _number, u16 _channelID, const void* _pData, u32
} }
/* This sends a Data Report from the Wiimote. See SystemTimers.cpp for the documentation of this // This sends a Data Report from the Wiimote. See SystemTimers.cpp for the documentation of this update.
update. */
void Wiimote_Update(int _number) void Wiimote_Update(int _number)
{ {
// Tell us about the update rate, but only about once every second to avoid a major slowdown // Tell us about the update rate, but only about once every second to avoid a major slowdown
@ -366,13 +353,14 @@ void Wiimote_Update(int _number)
// This functions will send: // This functions will send:
// Emulated Wiimote: Only data reports 0x30-0x37 // Emulated Wiimote: Only data reports 0x30-0x37
// Real Wiimote: Both data reports 0x30-0x37 and all other read reports // Real Wiimote: Both data reports 0x30-0x37 and all other read reports
if (!g_Config.bUseRealWiimote || !g_RealWiiMotePresent) if (WiiMoteEmu::WiiMapping[_number].Source >= 0)
WiiMoteEmu::Update(_number); WiiMoteEmu::Update(_number);
#if HAVE_WIIUSE #if HAVE_WIIUSE
else if (g_RealWiiMotePresent) else if (g_RealWiiMotePresent)
WiiMoteReal::Update(); // TODO: Multi-Wiimote WiiMoteReal::Update(); // TODO: Multi-Wiimote
#endif #endif
/*
// Debugging // Debugging
#ifdef _WIN32 #ifdef _WIN32
if( GetAsyncKeyState(VK_HOME) && g_DebugComm ) g_DebugComm = false; // Page Down if( GetAsyncKeyState(VK_HOME) && g_DebugComm ) g_DebugComm = false; // Page Down
@ -387,6 +375,8 @@ void Wiimote_Update(int _number)
if( GetAsyncKeyState(VK_END) && g_DebugCustom ) { g_DebugCustom = false; DEBUG_LOG(WIIMOTE, "Custom Debug: Off");} // End if( GetAsyncKeyState(VK_END) && g_DebugCustom ) { g_DebugCustom = false; DEBUG_LOG(WIIMOTE, "Custom Debug: Off");} // End
else if (GetAsyncKeyState(VK_END) && !g_DebugCustom ) {g_DebugCustom = true; DEBUG_LOG(WIIMOTE, "Custom Debug: Off");} else if (GetAsyncKeyState(VK_END) && !g_DebugCustom ) {g_DebugCustom = true; DEBUG_LOG(WIIMOTE, "Custom Debug: Off");}
#endif #endif
*/
} }
unsigned int Wiimote_GetAttachedControllers() unsigned int Wiimote_GetAttachedControllers()
@ -398,8 +388,6 @@ unsigned int Wiimote_GetAttachedControllers()
// Supporting functions // Supporting functions
// Check if Dolphin is in focus // Check if Dolphin is in focus
bool IsFocus() bool IsFocus()
@ -422,13 +410,55 @@ bool IsFocus()
#endif #endif
} }
/* Returns a timestamp with three decimals for precise time comparisons. The return format is
of the form seconds.milleseconds for example 1234.123. The leding seconds have no particular meaning
but are just there to enable use to tell if we have entered a new second or now. */
// -----------------
/* Calculate the current update frequency. Calculate the time between ten updates, and average
five such rates. If we assume there are 60 updates per second if the game is running at full
speed then we get this measure on average once every second. The reason to have a few updates
between each measurement is becase the milliseconds may not be perfectly accurate and may return
the same time even when a milliseconds has actually passed, for example.*/
int GetUpdateRate()
{
#if defined(HAVE_WX) && HAVE_WX
if(g_UpdateCounter == 10)
{
// Erase the old ones
if(g_UpdateTimeList.size() == 5) g_UpdateTimeList.erase(g_UpdateTimeList.begin() + 0);
// Calculate the time and save it
int Time = (int)(10 / (Common::Timer::GetDoubleTime() - g_UpdateTime));
g_UpdateTimeList.push_back(Time);
//DEBUG_LOG(WIIMOTE, "Time: %i %f", Time, Common::Timer::GetDoubleTime());
int TotalTime = 0;
for (int i = 0; i < (int)g_UpdateTimeList.size(); i++)
TotalTime += g_UpdateTimeList.at(i);
g_UpdateRate = TotalTime / 5;
// Write the new update time
g_UpdateTime = Common::Timer::GetDoubleTime();
g_UpdateCounter = 0;
}
g_UpdateCounter++;
return g_UpdateRate;
#else
return 0;
#endif
}
/*
// Turn off all extensions // Turn off all extensions
void DisableExtensions() void DisableExtensions()
{ {
g_Config.iExtensionConnected = EXT_NONE; g_Config.iExtensionConnected = EXT_NONE;
} }
/*
void ReadDebugging(bool Emu, const void* _pData, int Size) void ReadDebugging(bool Emu, const void* _pData, int Size)
{ {
// //
@ -807,7 +837,6 @@ void ReadDebugging(bool Emu, const void* _pData, int Size)
DEBUG_LOG(WIIMOTE, "Accel x, y, z: %03u %03u %03u", data[4], data[5], data[6]); DEBUG_LOG(WIIMOTE, "Accel x, y, z: %03u %03u %03u", data[4], data[5], data[6]);
} }
} }
*/
void InterruptDebugging(bool Emu, const void* _pData) void InterruptDebugging(bool Emu, const void* _pData)
{ {
@ -951,75 +980,16 @@ void InterruptDebugging(bool Emu, const void* _pData)
{ {
std::string Temp = ArrayToString(data, size + 2, 0, 30); std::string Temp = ArrayToString(data, size + 2, 0, 30);
//LOGV(WIIMOTE, 3, " Data: %s", Temp.c_str()); //LOGV(WIIMOTE, 3, " Data: %s", Temp.c_str());
DEBUG_LOG(WIIMOTE, "%s: %s", Name.c_str(), Temp.c_str()); // No timestamp DEBUG_LOG(WIIMOTE, "%s: %s", Name.c_str(), Temp.c_str());
//DEBUG_LOG(WIIMOTE, " (%s): %s", Tm(true).c_str(), Temp.c_str()); // Timestamp //DEBUG_LOG(WIIMOTE, " (%s): %s", Tm(true).c_str(), Temp.c_str());
} }
if (g_DebugSoundData && SoundData) if (g_DebugSoundData && SoundData)
{ {
std::string Temp = ArrayToString(data, size + 2, 0, 30); std::string Temp = ArrayToString(data, size + 2, 0, 30);
//LOGV(WIIMOTE, 3, " Data: %s", Temp.c_str()); //LOGV(WIIMOTE, 3, " Data: %s", Temp.c_str());
DEBUG_LOG(WIIMOTE, "%s: %s", Name.c_str(), Temp.c_str()); // No timestamp DEBUG_LOG(WIIMOTE, "%s: %s", Name.c_str(), Temp.c_str());
//DEBUG_LOG(WIIMOTE, " (%s): %s", Tm(true).c_str(), Temp.c_str()); // Timestamp //DEBUG_LOG(WIIMOTE, " (%s): %s", Tm(true).c_str(), Temp.c_str());
} }
} }
*/
/* Returns a timestamp with three decimals for precise time comparisons. The return format is
of the form seconds.milleseconds for example 1234.123. The leding seconds have no particular meaning
but are just there to enable use to tell if we have entered a new second or now. */
// -----------------
/* Calculate the current update frequency. Calculate the time between ten updates, and average
five such rates. If we assume there are 60 updates per second if the game is running at full
speed then we get this measure on average once every second. The reason to have a few updates
between each measurement is becase the milliseconds may not be perfectly accurate and may return
the same time even when a milliseconds has actually passed, for example.*/
int GetUpdateRate()
{
#if defined(HAVE_WX) && HAVE_WX
if(g_UpdateCounter == 10)
{
// Erase the old ones
if(g_UpdateTimeList.size() == 5) g_UpdateTimeList.erase(g_UpdateTimeList.begin() + 0);
// Calculate the time and save it
int Time = (int)(10 / (Common::Timer::GetDoubleTime() - g_UpdateTime));
g_UpdateTimeList.push_back(Time);
//DEBUG_LOG(WIIMOTE, "Time: %i %f", Time, Common::Timer::GetDoubleTime());
int TotalTime = 0;
for (int i = 0; i < (int)g_UpdateTimeList.size(); i++)
TotalTime += g_UpdateTimeList.at(i);
g_UpdateRate = TotalTime / 5;
// Write the new update time
g_UpdateTime = Common::Timer::GetDoubleTime();
g_UpdateCounter = 0;
}
g_UpdateCounter++;
return g_UpdateRate;
#else
return 0;
#endif
}
void DoInitialize()
{
// Run this first so that WiiMoteReal::Initialize() overwrites g_Eeprom
WiiMoteEmu::Initialize();
/* We will run WiiMoteReal::Initialize() even if we are not using a real
wiimote, to check if there is a real wiimote connected. We will initiate
wiiuse.dll, but we will return before creating a new thread for it if we
find no real Wiimotes. Then g_RealWiiMotePresent will also be
false. This function call will be done instantly whether there is a real
Wiimote connected or not. It takes no time for Wiiuse to check for
connected Wiimotes. */
#if HAVE_WIIUSE
if (g_Config.bConnectRealWiimote) WiiMoteReal::Initialize();
#endif
}

View File

@ -30,12 +30,10 @@
extern Display* WMdisplay; extern Display* WMdisplay;
#endif #endif
// Definitions and declarations // Definitions and declarations
void DoInitialize();
int GetUpdateRate();
void InterruptDebugging(bool Emu, const void* _pData);
void ReadDebugging(bool Emu, const void* _pData, int Size);
bool IsFocus(); bool IsFocus();
int GetUpdateRate();
//void InterruptDebugging(bool Emu, const void* _pData);
//void ReadDebugging(bool Emu, const void* _pData, int Size);
// Movement recording // Movement recording
#define RECORDING_ROWS 15 #define RECORDING_ROWS 15

View File

@ -25,7 +25,7 @@
#endif #endif
#pragma pack(push, 1) #pragma pack(push, 1)
#define MAX_WIIMOTES 2 #define MAX_WIIMOTES 4
// Source: HID_010_SPC_PFL/1.0 (official HID specification) // Source: HID_010_SPC_PFL/1.0 (official HID specification)

View File

@ -125,7 +125,7 @@ void ReadData()
wiiuse_io_write(m_pWiiMote, (byte*)rEvent.m_PayLoad, rEvent._Size); wiiuse_io_write(m_pWiiMote, (byte*)rEvent.m_PayLoad, rEvent._Size);
m_EventWriteQueue.pop(); m_EventWriteQueue.pop();
InterruptDebugging(false, rEvent.m_PayLoad); // InterruptDebugging(false, rEvent.m_PayLoad);
} }
m_pCriticalSection->Leave(); m_pCriticalSection->Leave();