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;
}
// 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()
{
return (GetState() != CORE_UNINITIALIZED) || g_bHwInit;

View File

@ -61,7 +61,6 @@ namespace Core
void* GetWindowHandle();
bool GetRealWiimote();
void ReconnectWiimote();
extern bool bReadTrace;
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_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, 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:
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_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++)
{
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;
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);
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);
if (pWiimote)
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)
@ -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);
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)

View File

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

View File

@ -30,10 +30,13 @@
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)
: m_Linked(false)
, m_HIDControlChannel_Connected(false)
: m_HIDControlChannel_Connected(false)
, m_HIDControlChannel_ConnectedWait(false)
, m_HIDControlChannel_Config(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_pHost(_pHost)
{
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;
}
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()
{
if ((m_Connected <= 0) || (m_Linked == true))
if (m_Connected != 2)
return false;
// try to connect HID_CONTROL_CHANNEL
@ -139,7 +145,7 @@ bool CWII_IPC_HLE_WiiMote::LinkChannel()
return true;
}
m_Linked = true;
m_Connected = 3;
UpdateStatus();
return false;
@ -221,22 +227,29 @@ void CWII_IPC_HLE_WiiMote::UpdateStatus()
//
void CWII_IPC_HLE_WiiMote::Activate(bool ready)
{
if (ready)
if (ready && m_Connected == -1)
{
m_Connected = 0;
else
m_Connected = -1;
}
else if (!ready)
{
m_pHost->RemoteDisconnect(m_ConnectionHandle);
EventDisconnect();
}
}
void CWII_IPC_HLE_WiiMote::EventConnectionAccepted()
{
m_Connected = 1;
m_Linked = false;
m_Connected = 2;
}
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_Linked = false;
// Clear channel flags
ResetChannels();
}
@ -249,7 +262,7 @@ bool CWII_IPC_HLE_WiiMote::EventPagingChanged(u8 _pageMode)
if ((_pageMode & 0x2) == 0)
return false;
m_Connected = -1;
m_Connected = 1;
return true;
}

View File

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

View File

@ -157,12 +157,6 @@ int abc = 0;
else
main_frame->bRenderToMain = true;
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;
}
@ -233,6 +227,10 @@ EVT_MENU(IDM_MEMCARD, CFrame::OnMemcard)
EVT_MENU(IDM_CHEATS, CFrame::OnShow_CheatsWindow)
EVT_MENU(IDM_CHANGEDISC, CFrame::OnChangeDisc)
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_DUALCORE, CFrame::OnToggleDualCore)
EVT_MENU(IDM_TOGGLE_SKIPIDLE, CFrame::OnToggleSkipIdle)

View File

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

View File

@ -62,6 +62,7 @@ Core::GetWindowHandle().
#include "OnFrame.h"
#include "HW/DVDInterface.h"
#include "HW/ProcessorInterface.h"
#include "IPC_HLE/WII_IPC_HLE_Device_usb.h"
#include "State.h"
#include "VolumeHandler.h"
#include "NANDContentLoader.h"
@ -90,6 +91,7 @@ extern "C" {
#include "../resources/KDE.h"
};
// Other Windows
wxCheatsWindow* CheatsWindow;
@ -194,6 +196,11 @@ void CFrame::CreateMenu()
{
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"));
@ -780,6 +787,12 @@ void CFrame::OnLoadWiiMenu(wxCommandEvent& WXUNUSED (event))
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
// the entire screen (when we render to the main window).
void CFrame::OnToggleFullscreen(wxCommandEvent& WXUNUSED (event))
@ -918,6 +931,18 @@ void CFrame::UpdateGUI()
if (DiscIO::CNANDContentManager::Access().GetNANDLoader(FULL_WII_MENU_DIR).IsValid())
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 (m_ToolBar)

View File

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

View File

@ -59,7 +59,6 @@
namespace InputCommon
{
// Settings
// ----------
// 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
{
bool enable;
int buttons[8]; // (See above)
int dpad; // (See above)
int dpad2[4]; // (See above)
@ -100,7 +100,6 @@ struct CONTROLLER_MAPPING // GC PAD MAPPING
std::string SRadius, SDiagonal, SRadiusC, SDiagonalC;
bool bRadiusOnOff, bSquareToCircle, bRadiusOnOffC, bSquareToCircleC;
bool rumble;
bool enable;
int eventnum; // Linux Event Number, Can't be found dynamically yet
};
@ -169,74 +168,6 @@ enum
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
// ---------

View File

@ -30,7 +30,7 @@ enum PLUGIN_COMM
TOGGLE_FULLSCREEN,
VIDEO_DESTROY, // The video 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
};

View File

@ -30,7 +30,6 @@
// Do not change the order unless you change the related arrays
// Directionals are ordered as L, R, U, D
// Wiimote
static const char* wmControlNames[] =
{
"WmA",
@ -49,51 +48,7 @@ static const char* wmControlNames[] =
"WmPitchU",
"WmPitchD",
"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",
"NcC",
"NcL",
@ -105,41 +60,7 @@ static const char* ncControlNames[] =
"NcPitchU",
"NcPitchD",
"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",
"CcB",
"CcX",
@ -163,9 +84,94 @@ static const char* ccControlNames[] =
"CcRr",
"CcRu",
"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
#ifdef _WIN32
VK_OEM_4, // [
@ -212,29 +218,9 @@ static int ccDefaultControls[] =
'J',
'L',
'I',
'K'
};
'K',
// GH3 Default controls
static const char* gh3ControlNames[] =
{
"GH3Green",
"GH3Red",
"GH3Yellow",
"GH3Blue",
"GH3Orange",
"GH3Plus",
"GH3Minus",
"GH3Whammy",
"GH3Al",
"GH3Ar",
"GH3Au",
"GH3Ad",
"GH3StrumUp",
"GH3StrumDown",
};
static int GH3DefaultControls[] =
{
// Guttar Hero
'A',
'S',
'D',
@ -269,22 +255,14 @@ Config::Config()
memset(this, 0, sizeof(Config));
}
void Config::Load(bool ChangePad)
void Config::Load()
{
std::string temp;
IniFile iniFile;
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
iniFile.Get("Real", "Connect", &bConnectRealWiimote, true);
iniFile.Get("Real", "Use", &bUseRealWiimote, false);
iniFile.Get("Real", "UpdateStatus", &bUpdateRealWiimote, true);
iniFile.Get("Real", "AccNeutralX", &iAccNeutralX, 0);
iniFile.Get("Real", "AccNeutralY", &iAccNeutralY, 0);
@ -298,72 +276,55 @@ void Config::Load(bool ChangePad)
// Slot specific settings
char SectionName[32];
sprintf(SectionName, "Wiimote%i", i + 1);
iniFile.Get(SectionName, "NoTriggerFilter", &bNoTriggerFilter, false);
iniFile.Get(SectionName, "TiltTypeWM", &Tilt.TypeWM, Tilt.KEYBOARD);
iniFile.Get(SectionName, "TiltTypeNC", &Tilt.TypeNC, Tilt.KEYBOARD);
iniFile.Get(SectionName, "TiltRollSwing", &Tilt.Range.RollSwing, false);
iniFile.Get(SectionName, "TiltRollDegree", &Tilt.Range.RollDegree, 60);
Tilt.Range.Roll = (Tilt.Range.RollSwing) ? 0 : Tilt.Range.RollDegree;
iniFile.Get(SectionName, "TiltRollInvert", &Tilt.RollInvert, 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);
// General
iniFile.Get(SectionName, "Source", &WiiMoteEmu::WiiMapping[i].Source, (i) ? 0 : 1);
iniFile.Get(SectionName, "Sideways", &WiiMoteEmu::WiiMapping[i].bSideways, false);
iniFile.Get(SectionName, "Upright", &WiiMoteEmu::WiiMapping[i].bUpright, false);
iniFile.Get(SectionName, "ExtensionConnected", &WiiMoteEmu::WiiMapping[i].iExtensionConnected, WiiMoteEmu::EXT_NONE);
iniFile.Get(SectionName, "MotionPlusConnected", &WiiMoteEmu::WiiMapping[i].bMotionPlusConnected, false);
// Wiimote
for (int x = 0; x < WM_CONTROLS; x++)
iniFile.Get(SectionName, wmControlNames[x], &WiiMoteEmu::PadMapping[i].Wm.keyForControls[x], wmDefaultControls[x]);
// Nunchuck
iniFile.Get(SectionName, "NunchuckStick", &Nunchuck.Type, Nunchuck.KEYBOARD);
for (int x = 0; x < NC_CONTROLS; x++)
iniFile.Get(SectionName, ncControlNames[x], &WiiMoteEmu::PadMapping[i].Nc.keyForControls[x], nCDefaultControls[x]);
iniFile.Get(SectionName, "TiltInputWM", &WiiMoteEmu::WiiMapping[i].Tilt.InputWM, WiiMoteEmu::FROM_KEYBOARD);
iniFile.Get(SectionName, "TiltInputNC", &WiiMoteEmu::WiiMapping[i].Tilt.InputNC, WiiMoteEmu::FROM_KEYBOARD);
iniFile.Get(SectionName, "TiltRollDegree", &WiiMoteEmu::WiiMapping[i].Tilt.RollDegree, 60);
iniFile.Get(SectionName, "TiltRollSwing", &WiiMoteEmu::WiiMapping[i].Tilt.RollSwing, false);
iniFile.Get(SectionName, "TiltRollInvert", &WiiMoteEmu::WiiMapping[i].Tilt.RollInvert, false);
WiiMoteEmu::WiiMapping[i].Tilt.RollRange = (WiiMoteEmu::WiiMapping[i].Tilt.RollSwing) ? 0 : WiiMoteEmu::WiiMapping[i].Tilt.RollDegree;
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
iniFile.Get(SectionName, "CcLeftStick", &ClassicController.LType, ClassicController.KEYBOARD);
iniFile.Get(SectionName, "CcRightStick", &ClassicController.RType, ClassicController.KEYBOARD);
iniFile.Get(SectionName, "CcTriggers", &ClassicController.TType, ClassicController.KEYBOARD);
for (int x = 0; x < CC_CONTROLS; x++)
iniFile.Get(SectionName, ccControlNames[x], &WiiMoteEmu::PadMapping[i].Cc.keyForControls[x], ccDefaultControls[x]);
// StickMapping
iniFile.Get(SectionName, "NCStick", &WiiMoteEmu::WiiMapping[i].Stick.NC, WiiMoteEmu::FROM_KEYBOARD);
iniFile.Get(SectionName, "CCStickLeft", &WiiMoteEmu::WiiMapping[i].Stick.CCL, WiiMoteEmu::FROM_KEYBOARD);
iniFile.Get(SectionName, "CCStickRight", &WiiMoteEmu::WiiMapping[i].Stick.CCR, WiiMoteEmu::FROM_KEYBOARD);
iniFile.Get(SectionName, "CCTriggers", &WiiMoteEmu::WiiMapping[i].Stick.CCT, WiiMoteEmu::FROM_KEYBOARD);
iniFile.Get(SectionName, "GHStick", &WiiMoteEmu::WiiMapping[i].Stick.GH, WiiMoteEmu::FROM_KEYBOARD);
iniFile.Get(SectionName, "GH3Analog", &GH3Controller.AType, GH3Controller.ANALOG1);
for (int x = 0; x < GH3_CONTROLS; x++)
iniFile.Get(SectionName, gh3ControlNames[x], &WiiMoteEmu::PadMapping[i].GH3c.keyForControls[x], GH3DefaultControls[x]);
// ButtonMapping
for (int x = 0; x < WiiMoteEmu::LAST_CONSTANT; 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
if(!ChangePad)
{
// 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);
iniFile.Get(SectionName, "DeviceID", &WiiMoteEmu::WiiMapping[i].ID, 0);
iniFile.Get(SectionName, "Axis_Lx", &WiiMoteEmu::WiiMapping[i].AxisMapping.Lx, 0);
iniFile.Get(SectionName, "Axis_Ly", &WiiMoteEmu::WiiMapping[i].AxisMapping.Ly, 1);
iniFile.Get(SectionName, "Axis_Rx", &WiiMoteEmu::WiiMapping[i].AxisMapping.Rx, 2);
iniFile.Get(SectionName, "Axis_Ry", &WiiMoteEmu::WiiMapping[i].AxisMapping.Ry, 3);
iniFile.Get(SectionName, "Trigger_L", &WiiMoteEmu::WiiMapping[i].AxisMapping.Tl, 1004);
iniFile.Get(SectionName, "Trigger_R", &WiiMoteEmu::WiiMapping[i].AxisMapping.Tr, 1005);
iniFile.Get(SectionName, "DeadZoneL", &WiiMoteEmu::WiiMapping[i].DeadZoneL, 0);
iniFile.Get(SectionName, "DeadZoneR", &WiiMoteEmu::WiiMapping[i].DeadZoneR, 0);
iniFile.Get(SectionName, "Diagonal", &WiiMoteEmu::WiiMapping[i].Diagonal, "100%");
iniFile.Get(SectionName, "Circle2Square", &WiiMoteEmu::WiiMapping[i].bCircle2Square, false);
iniFile.Get(SectionName, "Rumble", &WiiMoteEmu::WiiMapping[i].Rumble, true);
iniFile.Get(SectionName, "RumbleStrength", &WiiMoteEmu::WiiMapping[i].RumbleStrength, 8); // x10
iniFile.Get(SectionName, "TriggerType", &WiiMoteEmu::WiiMapping[i].TriggerType, 0);
}
// Joypad specific settings
// Current joypad device ID: PadMapping[i].ID
// Current joypad name: joyinfo[PadMapping[i].ID].Name
// Prevent a crash from illegal access to joyinfo that will only have values for
// the current amount of connected PadMapping
if((u32)WiiMoteEmu::PadMapping[i].ID >= WiiMoteEmu::joyinfo.size()) continue;
// Create a section name
std::string joySectionName = WiiMoteEmu::joyinfo[WiiMoteEmu::PadMapping[i].ID].Name;
iniFile.Get(joySectionName.c_str(), "left_x", &WiiMoteEmu::PadMapping[i].Axis.Lx, 0);
iniFile.Get(joySectionName.c_str(), "left_y", &WiiMoteEmu::PadMapping[i].Axis.Ly, 1);
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
iniFile.Load(FULL_CONFIG_DIR "IR Pointer.ini");
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
// better to place them in the main Dolphin.ini file
iniFile.Load(FULL_CONFIG_DIR "gfx_opengl.ini");
iniFile.Get("Settings", "KeepAR_4_3", &bKeepAR43, false);
iniFile.Get("Settings", "KeepAR_16_9", &bKeepAR169, false);
@ -384,18 +344,12 @@ void Config::Load(bool ChangePad)
//DEBUG_LOG(WIIMOTE, "Load()");
}
void Config::Save(int Slot)
void Config::Save()
{
IniFile iniFile;
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", "Use", bUseRealWiimote);
iniFile.Set("Real", "UpdateStatus", bUpdateRealWiimote);
iniFile.Set("Real", "AccNeutralX", iAccNeutralX);
iniFile.Set("Real", "AccNeutralY", iAccNeutralY);
@ -410,64 +364,48 @@ void Config::Save(int Slot)
char SectionName[32];
sprintf(SectionName, "Wiimote%i", i + 1);
iniFile.Set(SectionName, "NoTriggerFilter", bNoTriggerFilter);
iniFile.Set(SectionName, "TiltTypeWM", Tilt.TypeWM);
iniFile.Set(SectionName, "TiltTypeNC", Tilt.TypeNC);
iniFile.Set(SectionName, "TiltRollDegree", Tilt.Range.RollDegree);
iniFile.Set(SectionName, "TiltRollSwing", Tilt.Range.RollSwing);
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]);
iniFile.Set(SectionName, "Source", WiiMoteEmu::WiiMapping[i].Source);
iniFile.Set(SectionName, "Sideways", WiiMoteEmu::WiiMapping[i].bSideways);
iniFile.Set(SectionName, "Upright", WiiMoteEmu::WiiMapping[i].bUpright);
iniFile.Set(SectionName, "ExtensionConnected", WiiMoteEmu::WiiMapping[i].iExtensionConnected);
iniFile.Set(SectionName, "MotionPlusConnected", WiiMoteEmu::WiiMapping[i].bMotionPlusConnected);
// Nunchuck
iniFile.Set(SectionName, "NunchuckStick", Nunchuck.Type);
for (int x = 0; x < NC_CONTROLS; x++)
iniFile.Set(SectionName, ncControlNames[x], WiiMoteEmu::PadMapping[i].Nc.keyForControls[x]);
iniFile.Set(SectionName, "TiltInputWM", WiiMoteEmu::WiiMapping[i].Tilt.InputWM);
iniFile.Set(SectionName, "TiltInputNC", WiiMoteEmu::WiiMapping[i].Tilt.InputNC);
iniFile.Set(SectionName, "TiltRollDegree", WiiMoteEmu::WiiMapping[i].Tilt.RollDegree);
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
iniFile.Set(SectionName, "CcLeftStick", ClassicController.LType);
iniFile.Set(SectionName, "CcRightStick", ClassicController.RType);
iniFile.Set(SectionName, "CcTriggers", ClassicController.TType);
for (int x = 0; x < CC_CONTROLS; x++)
iniFile.Set(SectionName, ccControlNames[x], WiiMoteEmu::PadMapping[i].Cc.keyForControls[x]);
// StickMapping
iniFile.Set(SectionName, "NCStick", WiiMoteEmu::WiiMapping[i].Stick.NC);
iniFile.Set(SectionName, "CCStickLeft", WiiMoteEmu::WiiMapping[i].Stick.CCL);
iniFile.Set(SectionName, "CCStickRight", WiiMoteEmu::WiiMapping[i].Stick.CCR);
iniFile.Set(SectionName, "CCTriggers", WiiMoteEmu::WiiMapping[i].Stick.CCT);
iniFile.Set(SectionName, "GHStick", WiiMoteEmu::WiiMapping[i].Stick.GH);
// GH3
iniFile.Set(SectionName, "GH3Analog", GH3Controller.AType);
for (int x = 0; x < GH3_CONTROLS; x++)
iniFile.Set(SectionName, gh3ControlNames[x], WiiMoteEmu::PadMapping[i].GH3c.keyForControls[x]);
// ButtonMapping
for (int x = 0; x < WiiMoteEmu::LAST_CONSTANT; x++)
iniFile.Set(SectionName, wmControlNames[x], WiiMoteEmu::WiiMapping[i].Button[x]);
// Save the physical device ID number
iniFile.Set(SectionName, "Enabled", WiiMoteEmu::PadMapping[i].enabled);
iniFile.Set(SectionName, "DeviceID", WiiMoteEmu::PadMapping[i].ID);
iniFile.Set(SectionName, "DeviceID", WiiMoteEmu::WiiMapping[i].ID);
// Joypad specific settings
// Current joypad device ID: PadMapping[i].ID
// Current joypad name: joyinfo[PadMapping[i].ID].Name
// Save joypad specific settings. Check for "PadMapping[i].ID < SDL_NumJoysticks()" to
// avoid reading a joyinfo that does't exist
if((u32)WiiMoteEmu::PadMapping[i].ID >= WiiMoteEmu::joyinfo.size()) continue;
// Create a new section name after the joypad name
std::string joySectionName = WiiMoteEmu::joyinfo[WiiMoteEmu::PadMapping[i].ID].Name;
iniFile.Set(joySectionName.c_str(), "left_x", WiiMoteEmu::PadMapping[i].Axis.Lx);
iniFile.Set(joySectionName.c_str(), "left_y", WiiMoteEmu::PadMapping[i].Axis.Ly);
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.Set(SectionName, "Axis_Lx", WiiMoteEmu::WiiMapping[i].AxisMapping.Lx);
iniFile.Set(SectionName, "Axis_Ly", WiiMoteEmu::WiiMapping[i].AxisMapping.Ly);
iniFile.Set(SectionName, "Axis_Rx", WiiMoteEmu::WiiMapping[i].AxisMapping.Rx);
iniFile.Set(SectionName, "Axis_Ry", WiiMoteEmu::WiiMapping[i].AxisMapping.Ry);
iniFile.Set(SectionName, "Trigger_L", WiiMoteEmu::WiiMapping[i].AxisMapping.Tl);
iniFile.Set(SectionName, "Trigger_R", WiiMoteEmu::WiiMapping[i].AxisMapping.Tr);
iniFile.Set(SectionName, "DeadZoneL", WiiMoteEmu::WiiMapping[i].DeadZoneL);
iniFile.Set(SectionName, "DeadZoneR", WiiMoteEmu::WiiMapping[i].DeadZoneR);
iniFile.Set(SectionName, "Diagonal", WiiMoteEmu::WiiMapping[i].Diagonal);
iniFile.Set(SectionName, "Circle2Square", WiiMoteEmu::WiiMapping[i].bCircle2Square);
iniFile.Set(SectionName, "Rumble", WiiMoteEmu::WiiMapping[i].Rumble);
iniFile.Set(SectionName, "RumbleStrength", WiiMoteEmu::WiiMapping[i].RumbleStrength); // x10
iniFile.Set(SectionName, "TriggerType", WiiMoteEmu::WiiMapping[i].TriggerType);
}
iniFile.Save(FULL_CONFIG_DIR "Wiimote.ini");

View File

@ -22,94 +22,14 @@
#include <X11/keysym.h>
#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
{
Config();
void Load(bool ChangePad = false);
void Save(int Slot = -1);
void Load();
void Save();
struct TiltRange
{
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;
// For dialog sync
int CurrentPage;
// Real Wiimote
bool bConnectRealWiimote, bUseRealWiimote, bUpdateRealWiimote;
@ -117,12 +37,6 @@ struct Config
int iAccNeutralX, iAccNeutralY, iAccNeutralZ;
int iAccNunNeutralX, iAccNunNeutralY, iAccNunNeutralZ;
// Gamepad
bool bNoTriggerFilter;
PadTilt Tilt;
PadNunchuck Nunchuck;
PadClassicController ClassicController;
PadGH3 GH3Controller;
// Screen size settings
bool bKeepAR43, bKeepAR169, bCrop;
};

View File

@ -31,9 +31,9 @@ BEGIN_EVENT_TABLE(WiimoteBasicConfigDialog,wxDialog)
EVT_BUTTON(ID_CANCEL, WiimoteBasicConfigDialog::ButtonClick)
EVT_BUTTON(ID_BUTTONMAPPING, 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_USE_REAL, WiimoteBasicConfigDialog::GeneralSettingsChanged)
EVT_CHECKBOX(IDC_SIDEWAYSWIIMOTE, WiimoteBasicConfigDialog::GeneralSettingsChanged)
EVT_CHECKBOX(IDC_UPRIGHTWIIMOTE, WiimoteBasicConfigDialog::GeneralSettingsChanged)
EVT_CHECKBOX(IDC_MOTIONPLUSCONNECTED, WiimoteBasicConfigDialog::GeneralSettingsChanged)
@ -59,9 +59,10 @@ WiimoteBasicConfigDialog::WiimoteBasicConfigDialog(wxWindow *parent, wxWindowID
#endif
ControlsCreated = false;
m_Page = 0;
m_bEnableUseRealWiimote = true;
Page = 0;
//g_Config.Load();
CreateGUIControls();
UpdateGUI();
}
@ -112,10 +113,14 @@ void WiimoteBasicConfigDialog::ButtonClick(wxCommandEvent& event)
Close();
break;
case ID_BUTTONMAPPING:
g_Config.CurrentPage = m_Page;
m_PadConfigFrame = new WiimotePadConfigDialog(this);
m_PadConfigFrame->ShowModal();
m_PadConfigFrame->Destroy();
m_PadConfigFrame = NULL;
m_Page = g_Config.CurrentPage;
m_Notebook->ChangeSelection(g_Config.CurrentPage);
UpdateGUI();
break;
case ID_BUTTONRECORDING:
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()
{
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);
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_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
m_InputActive[i] = new wxCheckBox(m_Controller[i], IDC_INPUT_ACTIVE, wxT("Wiimote Input Active"));
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));
m_InputSource[i] = new wxChoice(m_Controller[i], IDC_INPUT_SOURCE, wxDefaultPosition, wxDefaultSize, arrayStringFor_source, 0, wxDefaultValidator);
// Emulated 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_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_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
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"));
@ -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_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
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_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_CheckAR169[i] = new wxCheckBox(m_Controller[i], wxID_ANY, wxT("16:9"), wxDefaultPosition, wxSize(-1, -1), 0, wxDefaultValidator);
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);
// Sizers
m_SizeBasic[i] = new wxStaticBoxSizer(wxVERTICAL, m_Controller[i], wxT("Emulated Wiimote"));
m_SizeBasic[i]->Add(m_InputActive[i], 0, wxEXPAND | wxALL, 5);
m_SizeBasic[i] = new wxStaticBoxSizer(wxVERTICAL, m_Controller[i], wxT("Input Source"));
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]->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]->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]->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]->Add(m_TextScreenLeft[i], 0, wxEXPAND | (wxTOP), 3);
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_SliderWidth[i], 0, wxEXPAND | (wxLEFT), 0);
m_SizerIRPointerHeight[i] = new wxBoxSizer(wxHORIZONTAL);
m_SizerIRPointerHeight[i]->Add(m_TextScreenTop[i], 0, wxEXPAND | (wxTOP), 3);
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_SizeBasicGeneral[i] = new wxBoxSizer(wxHORIZONTAL);
m_SizeBasicGeneral[i]->Add(m_SizeBasicGeneralLeft[i], 0, wxEXPAND | (wxUP), 0);
m_SizeBasicGeneral[i]->Add(m_SizeBasicGeneralRight[i], 0, wxEXPAND | (wxLEFT), 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]);
m_SizeBasicGeneral[i]->Add(m_SizeBasicGeneralLeft[i], 0, wxEXPAND | (wxLEFT | wxRIGHT | wxDOWN), 5);
m_SizeBasicGeneral[i]->Add(m_SizeBasicGeneralRight[i], 0, wxEXPAND | (wxLEFT | wxRIGHT | wxDOWN), 5);
// 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"));
@ -307,6 +273,20 @@ void WiimoteBasicConfigDialog::CreateGUIControls()
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()
{
if(g_Config.bConnectRealWiimote)
@ -325,7 +305,7 @@ void WiimoteBasicConfigDialog::DoConnectReal()
void WiimoteBasicConfigDialog::DoUseReal()
{
if (!g_Config.bUseRealWiimote)
if (!g_RealWiiMotePresent || !g_Config.bConnectRealWiimote)
return;
// 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.
bool UsingExtension = false;
if (g_Config.iExtensionConnected != EXT_NONE)
if (WiiMoteEmu::WiiMapping[m_Page].iExtensionConnected != WiiMoteEmu::EXT_NONE)
UsingExtension = true;
DEBUG_LOG(WIIMOTE, "DoUseReal() Connect extension: %i", !UsingExtension);
@ -362,56 +342,71 @@ void WiimoteBasicConfigDialog::DoUseReal()
void WiimoteBasicConfigDialog::DoExtensionConnectedDisconnected(int Extension)
{
// 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;
// Check if a game is running, in that case change the status
if(WiiMoteEmu::g_ReportingChannel > 0)
WiiMoteEmu::WmRequestStatus(WiiMoteEmu::g_ReportingChannel, rs, Extension);
if(WiiMoteEmu::g_ReportingChannel[m_Page] > 0)
{
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)
{
switch (event.GetId())
{
case IDC_CONNECT_REAL:
g_Config.bConnectRealWiimote = m_ConnectRealWiimote[Page]->IsChecked();
g_Config.bConnectRealWiimote = m_ConnectRealWiimote[m_Page]->IsChecked();
DoConnectReal();
break;
case IDC_USE_REAL:
// Enable the Wiimote thread
g_Config.bUseRealWiimote = m_UseRealWiimote[Page]->IsChecked();
case IDC_INPUT_SOURCE:
if (m_InputSource[m_Page]->GetSelection() == 2)
{
g_Config.bUseRealWiimote = true;
WiiMoteEmu::WiiMapping[m_Page].Source = -1;
DoUseReal();
break;
case IDC_INPUT_ACTIVE:
g_Config.bInputActive = m_InputActive[Page]->IsChecked();
}
else
{
g_Config.bUseRealWiimote = false;
WiiMoteEmu::WiiMapping[m_Page].Source = m_InputSource[m_Page]->GetSelection();
}
break;
case IDC_SIDEWAYSWIIMOTE:
g_Config.bSideways = m_SidewaysWiimote[Page]->IsChecked();
WiiMoteEmu::WiiMapping[m_Page].bSideways = m_SidewaysWiimote[m_Page]->IsChecked();
break;
case IDC_UPRIGHTWIIMOTE:
g_Config.bUpright = m_UprightWiimote[Page]->IsChecked();
WiiMoteEmu::WiiMapping[m_Page].bUpright = m_UprightWiimote[m_Page]->IsChecked();
break;
case IDC_MOTIONPLUSCONNECTED:
g_Config.bMotionPlusConnected = m_WiiMotionPlusConnected[Page]->IsChecked();
WiiMoteEmu::WiiMapping[m_Page].bMotionPlusConnected = m_WiiMotionPlusConnected[m_Page]->IsChecked();
break;
case IDC_EXTCONNECTED:
g_Config.iExtensionConnected = EXT_NONE;
// 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
// reconnect an extension after we disconnected another?
if(g_EmulatorRunning) SLEEP(25);
// Update status
g_Config.iExtensionConnected = extensionChoice[Page]->GetSelection();
WiiMoteEmu::WiiMapping[m_Page].iExtensionConnected = m_Extension[m_Page]->GetSelection();
// Copy the calibration data
WiiMoteEmu::UpdateExtRegisterBlocks();
WiiMoteEmu::UpdateExtRegisterBlocks(m_Page);
// Generate connect/disconnect status event
DoExtensionConnectedDisconnected();
break;
@ -424,62 +419,55 @@ void WiimoteBasicConfigDialog::IRCursorChanged(wxScrollEvent& event)
switch (event.GetId())
{
case IDS_WIDTH:
g_Config.iIRWidth = m_SliderWidth[Page]->GetValue();
g_Config.iIRWidth = m_SliderWidth[m_Page]->GetValue();
break;
case IDS_HEIGHT:
g_Config.iIRHeight = m_SliderHeight[Page]->GetValue();
g_Config.iIRHeight = m_SliderHeight[m_Page]->GetValue();
break;
case IDS_LEFT:
g_Config.iIRLeft = m_SliderLeft[Page]->GetValue();
g_Config.iIRLeft = m_SliderLeft[m_Page]->GetValue();
break;
case IDS_TOP:
g_Config.iIRTop = m_SliderTop[Page]->GetValue();
g_Config.iIRTop = m_SliderTop[m_Page]->GetValue();
break;
}
UpdateGUI();
}
void WiimoteBasicConfigDialog::UpdateIRCalibration()
{
// 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)
void WiimoteBasicConfigDialog::UpdateGUI()
{
/* 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
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
could possibly be simplified to one option. */
m_ConnectRealWiimote[Page]->SetValue(g_Config.bConnectRealWiimote);
m_ConnectRealWiimote[Page]->Enable(!g_EmulatorRunning);
m_ConnectRealWiimote[m_Page]->SetValue(g_Config.bConnectRealWiimote);
m_ConnectRealWiimote[m_Page]->Enable(!g_EmulatorRunning);
m_UseRealWiimote[Page]->SetValue(g_Config.bUseRealWiimote);
m_UseRealWiimote[Page]->Enable((m_bEnableUseRealWiimote && g_RealWiiMotePresent && g_Config.bConnectRealWiimote) || (!g_EmulatorRunning && g_Config.bConnectRealWiimote));
if (WiiMoteEmu::WiiMapping[m_Page].Source < 0)
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[Page]->SetValue(g_Config.bSideways);
m_UprightWiimote[Page]->SetValue(g_Config.bUpright);
m_WiiMotionPlusConnected[Page]->SetValue(g_Config.bMotionPlusConnected);
m_SidewaysWiimote[m_Page]->SetValue(WiiMoteEmu::WiiMapping[m_Page].bSideways);
m_UprightWiimote[m_Page]->SetValue(WiiMoteEmu::WiiMapping[m_Page].bUpright);
m_WiiMotionPlusConnected[m_Page]->SetValue(WiiMoteEmu::WiiMapping[m_Page].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
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);
m_Extension[m_Page]->SetSelection(WiiMoteEmu::WiiMapping[m_Page].iExtensionConnected);
// 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/panel.h>
#include <wx/gbsizer.h>
#include "wiimote_hid.h"
class WiimoteBasicConfigDialog : public wxDialog
{
@ -43,9 +44,8 @@ class WiimoteBasicConfigDialog : public wxDialog
virtual ~WiimoteBasicConfigDialog(){;}
// General open, close and event functions
void UpdateGUI();
void ButtonClick(wxCommandEvent& event);
void UpdateGUI(int Slot = 0);
void UpdateIRCalibration();
void ShutDown(wxTimerEvent& WXUNUSED(event));
void UpdateOnce(wxTimerEvent& event);
@ -53,58 +53,55 @@ class WiimoteBasicConfigDialog : public wxDialog
wxTimer *m_TimeoutOnce,
*m_ShutDownTimer;
wxCheckBox *m_UseRealWiimote[4];
private:
DECLARE_EVENT_TABLE();
bool ControlsCreated, m_bEnableUseRealWiimote;
int Page;
int m_Page;
wxNotebook *m_Notebook;
wxPanel *m_Controller[4];
wxPanel *m_Controller[MAX_WIIMOTES];
wxButton *m_OK,
*m_Cancel,
*m_ButtonMapping,
*m_Recording;
wxChoice* extensionChoice[4];
wxChoice *m_InputSource[MAX_WIIMOTES],
*m_Extension[MAX_WIIMOTES];
wxSlider *m_SliderWidth[4],
*m_SliderHeight[4],
*m_SliderLeft[4],
*m_SliderTop[4];
wxSlider *m_SliderWidth[MAX_WIIMOTES],
*m_SliderHeight[MAX_WIIMOTES],
*m_SliderLeft[MAX_WIIMOTES],
*m_SliderTop[MAX_WIIMOTES];
wxCheckBox *m_InputActive[4],
*m_SidewaysWiimote[4],
*m_UprightWiimote[4],
*m_ConnectRealWiimote[4],
*m_WiiMotionPlusConnected[4],
*m_CheckAR43[4],
*m_CheckAR169[4],
*m_Crop[4];
wxCheckBox *m_ConnectRealWiimote[MAX_WIIMOTES],
*m_SidewaysWiimote[MAX_WIIMOTES],
*m_UprightWiimote[MAX_WIIMOTES],
*m_WiiMotionPlusConnected[MAX_WIIMOTES],
*m_CheckAR43[MAX_WIIMOTES],
*m_CheckAR169[MAX_WIIMOTES],
*m_Crop[MAX_WIIMOTES];
wxStaticText *m_TextScreenWidth[4],
*m_TextScreenHeight[4],
*m_TextScreenLeft[4],
*m_TextScreenTop[4],
*m_TextAR[4];
wxStaticText *m_TextScreenWidth[MAX_WIIMOTES],
*m_TextScreenHeight[MAX_WIIMOTES],
*m_TextScreenLeft[MAX_WIIMOTES],
*m_TextScreenTop[MAX_WIIMOTES],
*m_TextAR[MAX_WIIMOTES];
wxBoxSizer *m_MainSizer,
*m_sMain[4],
*m_SizeParent[4],
*m_SizeBasicGeneral[4],
*m_SizeBasicGeneralLeft[4],
*m_SizeBasicGeneralRight[4],
*m_SizerIRPointerWidth[4],
*m_SizerIRPointerHeight[4],
*m_SizerIRPointerScreen[4];
*m_SizeBasicGeneral[MAX_WIIMOTES],
*m_SizeBasicGeneralLeft[MAX_WIIMOTES],
*m_SizeBasicGeneralRight[MAX_WIIMOTES],
*m_SizerIRPointerWidth[MAX_WIIMOTES],
*m_SizerIRPointerHeight[MAX_WIIMOTES],
*m_SizerIRPointerScreen[MAX_WIIMOTES];
wxStaticBoxSizer *m_SizeBasic[4],
*m_SizeEmu[4],
*m_SizeReal[4],
*m_SizeExtensions[4],
*m_SizerIRPointer[4];
wxStaticBoxSizer *m_SizeBasic[MAX_WIIMOTES],
*m_SizeEmu[MAX_WIIMOTES],
*m_SizeReal[MAX_WIIMOTES],
*m_SizeExtensions[MAX_WIIMOTES],
*m_SizerIRPointer[MAX_WIIMOTES];
enum
{
@ -123,7 +120,7 @@ class WiimoteBasicConfigDialog : public wxDialog
ID_CONTROLLERPAGE4,
// Emulated Wiimote
IDC_INPUT_ACTIVE,
IDC_INPUT_SOURCE,
IDC_SIDEWAYSWIIMOTE,
IDC_UPRIGHTWIIMOTE,
IDC_MOTIONPLUSCONNECTED,
@ -131,7 +128,6 @@ class WiimoteBasicConfigDialog : public wxDialog
// Real
IDC_CONNECT_REAL,
IDC_USE_REAL,
IDS_WIDTH,
IDS_HEIGHT,
@ -139,8 +135,9 @@ class WiimoteBasicConfigDialog : public wxDialog
IDS_TOP,
};
void OnClose(wxCloseEvent& event);
void CreateGUIControls();
void OnClose(wxCloseEvent& event);
void NotebookPageChanged(wxNotebookEvent& event);
void GeneralSettingsChanged(wxCommandEvent& event);
void IRCursorChanged(wxScrollEvent& event);

View File

@ -20,339 +20,86 @@
#include "ConfigPadDlg.h"
#include "Config.h"
#include "EmuMain.h" // for WiiMoteEmu class
#include "EmuDefinitions.h"
#if defined(HAVE_X11) && HAVE_X11
#include "X11InputBase.h"
#endif
// Change Joystick
/* Function: When changing the joystick we save and load the settings and
update the PadMapping and PadState array. PadState[].joy is the gamepad
handle that is used to access the pad throughout the plugin. Joyinfo[].joy
is only used the first time the pads are checked. */
void WiimotePadConfigDialog::DoChangeJoystick()
// Replace the harder to understand -1 with "" for the sake of user friendliness
void WiimotePadConfigDialog::ToBlank(bool ToBlank, int Id)
{
// Close the current pad, unless it's used by another slot
//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;
if (!ControlsCreated)
return;
}
DEBUG_LOG(WIIMOTE, "Update the Slot %i handle to Id %i", Page, WiiMoteEmu::PadMapping[Open].ID);
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)
if(ToBlank)
{
float Rad = (float)WiiMoteEmu::PadMapping[Page].DeadZoneL * ((float)BoxW / 100.0) * 0.5;
m_bmpDeadZoneLeftIn[Page]->SetBitmap(CreateBitmapClear());
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();
if (GetButtonText(Id) == wxString(wxT("-1")))
SetButtonText(Id, wxString());
}
else
{
float Rad = (float)WiiMoteEmu::PadMapping[Page].DeadZoneR * ((float)BoxW / 100.0) * 0.5;
m_bmpDeadZoneRightIn[Page]->SetBitmap(CreateBitmapClear());
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();
if (GetButtonText(Id).IsEmpty())
SetButtonText(Id, wxString(wxT("-1")));
}
}
// Change settings
// Set the button text for all four Wiimotes
void WiimotePadConfigDialog::SetButtonTextAll(int id, char text[128])
void WiimotePadConfigDialog::DoChangeDeadZone()
{
for (int i = 0; i < 1; i++) // We've got only 1 currently
{
// Safety check to avoid crash
if ((int)WiiMoteEmu::joyinfo.size() > WiiMoteEmu::PadMapping[i].ID)
if (WiiMoteEmu::joyinfo[WiiMoteEmu::PadMapping[i].ID].Name == WiiMoteEmu::joyinfo[WiiMoteEmu::PadMapping[Page].ID].Name)
SetButtonText(id, text, i);
};
}
float Rad;
void WiimotePadConfigDialog::SaveButtonMappingAll(int Slot)
{
for (int i = 0; i < 4; i++)
{
// This can occur when no gamepad is detected
if ((int)WiiMoteEmu::joyinfo.size() > WiiMoteEmu::PadMapping[i].ID && WiiMoteEmu::PadMapping[i].ID >= 0)
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].DeadZoneL * ((float)BoxW / 100.0) * 0.5;
m_bmpDeadZoneLeftIn[m_Page]->SetBitmap(CreateBitmapClear());
m_bmpDeadZoneLeftIn[m_Page]->SetSize(0, 0);
m_bmpDeadZoneLeftIn[m_Page]->SetBitmap(CreateBitmapDeadZone((int)Rad));
m_bmpDeadZoneLeftIn[m_Page]->SetPosition(wxPoint(BoxW / 2 - (int)Rad, BoxH / 2 - (int)Rad));
m_bmpDeadZoneLeftIn[m_Page]->Refresh();
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
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
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)
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)
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)
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)
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)
m_Button_GH3[id - IDB_GH3_GREEN][controller]->SetLabel(wxString::FromAscii(text));
//DEBUG_LOG(WIIMOTE, "SetButtonText: %s", text);
m_Button_GH3[id - IDB_GH3_GREEN][m_Page]->SetLabel(str);
}
// 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)
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)
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)
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)
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)
return m_Button_GH3[id - IDB_GH3_GREEN][controller]->GetLabel();
return m_Button_GH3[id - IDB_GH3_GREEN][m_Page]->GetLabel();
return wxString();
}
// Configure button mapping
// Wait for button press
/* Loop or timer: There are basically two ways to do this. With a while() or
for() loop, or with a timer. The downside with the while() or for() loop is
that there is no way to stop it if the user should select to configure
@ -378,13 +125,11 @@ void WiimotePadConfigDialog::GetButtons(wxCommandEvent& event)
void WiimotePadConfigDialog::DoGetButtons(int _GetId)
{
// Collect the starting values
// Get the current controller
int Controller = Page;
int PadID = WiiMoteEmu::PadMapping[Controller].ID;
int PadID = WiiMoteEmu::WiiMapping[m_Page].ID;
// 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
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 NoTriggerFilter = g_Config.bNoTriggerFilter;
bool NoTriggerFilter = false;
// Values used in this function
char format[128];
int Seconds = 4; // Seconds to wait for
int TimesPerSecond = 40; // How often to run the check
@ -434,14 +178,13 @@ void WiimotePadConfigDialog::DoGetButtons(int _GetId)
#endif
DEBUG_LOG(WIIMOTE, "Timer Started: Pad:%i _GetId:%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);
}
// Check for buttons
// If there is a timer we should not create a new one
else if (WiiMoteEmu::NumGoodPads >0)
else if (WiiMoteEmu::NumGoodPads > 0)
{
InputCommon::GetButton(
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
// Count each time
GetButtonWaitingTimer++;
// This is run every second
if(GetButtonWaitingTimer % TimesPerSecond == 0)
if (GetButtonWaitingTimer % TimesPerSecond == 0)
{
// Current time
int TmpTime = Seconds - (GetButtonWaitingTimer / TimesPerSecond);
// Update text
sprintf(format, "[ %d ]", TmpTime);
SetButtonText(_GetId, format);
SetButtonText(_GetId, wxString::Format(wxT("[ %d ]"), TmpTime));
}
// Time's up
if( (GetButtonWaitingTimer / TimesPerSecond) >= Seconds )
if (GetButtonWaitingTimer / TimesPerSecond >= Seconds)
{
Stop = true;
// Revert back to old label
SetButtonText(_GetId, OldLabel.ToAscii());
SetButtonText(_GetId, OldLabel);
}
// 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 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
SaveKeyboardMapping(Page, ClickedButton->GetId(), 0x1000 + pressed);
sprintf(format, "PAD: %d", pressed);
SaveButtonMapping(_GetId, 0x1000 + 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
doesn't make sense to have several slots controlled by the same
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);
SaveButtonMapping(_GetId, pressed);
SetButtonText(_GetId, wxString::Format(wxT("%d"), pressed));
}
SetButtonTextAll(_GetId, format);
}
// Stop the timer
if(Stop)
{
DEBUG_LOG(WIIMOTE, "Timer Stopped for Pad:%i _GetId:%i",
WiiMoteEmu::PadMapping[Controller].ID, _GetId);
WiiMoteEmu::WiiMapping[Controller].ID, _GetId);
m_ButtonMappingTimer->Stop();
GetButtonWaitingTimer = 0;
@ -525,85 +256,64 @@ void WiimotePadConfigDialog::DoGetButtons(int _GetId)
if(KeyPressed == -1)
{
// Update text
SetButtonTextAll(_GetId, (char *)"PAD: -1");
SetButtonText(_GetId, wxString(wxT("PAD: -1")));
// Notify the user
wxMessageBox(wxString::Format(
wxT("You selected a key with a to low key code (%i), please")
wxT(" select another key with a higher key code."), pressed)
, 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
void WiimotePadConfigDialog::Convert2Box(int &x)
{
// Border adjustment
int BoxW_ = BoxW - 2; int BoxH_ = BoxH - 2;
// Convert values
x = (BoxW_ / 2) + (x * BoxW_ / (32767 * 2));
}
// Update the input status boxes
void WiimotePadConfigDialog::PadGetStatus()
void WiimotePadConfigDialog::UpdatePadInfo(wxTimerEvent& WXUNUSED(event))
{
//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,
it can only be that because of a manual ini file change, but we make that check anway. */
if(!WiiMoteEmu::PadMapping[Page].enabled
|| WiiMoteEmu::PadMapping[Page].ID < 0
|| WiiMoteEmu::PadMapping[Page].ID >= SDL_NumJoysticks()
)
if (WiiMoteEmu::WiiMapping[m_Page].ID < 0 || WiiMoteEmu::WiiMapping[m_Page].ID >= WiiMoteEmu::NumGoodPads)
{
m_tStatusLeftIn[Page]->SetLabel(wxT("Not connected"));
m_tStatusLeftOut[Page]->SetLabel(wxT("Not connected"));
m_tStatusRightIn[Page]->SetLabel(wxT("Not connected"));
m_tStatusRightOut[Page]->SetLabel(wxT("Not connected"));
m_TriggerStatusL[Page]->SetLabel(wxT("000"));
m_TriggerStatusR[Page]->SetLabel(wxT("000"));
m_tStatusLeftIn[m_Page]->SetLabel(wxT("Not connected"));
m_tStatusLeftOut[m_Page]->SetLabel(wxT("Not connected"));
m_tStatusRightIn[m_Page]->SetLabel(wxT("Not connected"));
m_tStatusRightOut[m_Page]->SetLabel(wxT("Not connected"));
m_TriggerStatusL[m_Page]->SetLabel(wxT("000"));
m_TriggerStatusR[m_Page]->SetLabel(wxT("000"));
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
//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
// Get original values
int main_x = WiiMoteEmu::PadState[Page].Axis.Lx;
int main_y = WiiMoteEmu::PadState[Page].Axis.Ly;
int right_x = WiiMoteEmu::PadState[Page].Axis.Rx;
int right_y = WiiMoteEmu::PadState[Page].Axis.Ry;
int main_x = WiiMoteEmu::WiiMapping[m_Page].AxisState.Lx;
int main_y = WiiMoteEmu::WiiMapping[m_Page].AxisState.Ly;
int right_x = WiiMoteEmu::WiiMapping[m_Page].AxisState.Rx;
int right_y = WiiMoteEmu::WiiMapping[m_Page].AxisState.Ry;
// Get adjusted values
int main_x_after = main_x, main_y_after = main_y;
int right_x_after = right_x, right_y_after = right_y;
// Produce square
if(WiiMoteEmu::PadMapping[Page].bCircle2Square)
{
InputCommon::Square2Circle(main_x_after, main_y_after, Page, WiiMoteEmu::PadMapping[Page].SDiagonal, true);
}
if(WiiMoteEmu::WiiMapping[m_Page].bCircle2Square)
InputCommon::Square2Circle(main_x_after, main_y_after, 0, WiiMoteEmu::WiiMapping[m_Page].Diagonal, true);
// Check dead zone
float DeadZoneLeft = (float)WiiMoteEmu::PadMapping[Page].DeadZoneL / 100.0;
float DeadZoneRight = (float)WiiMoteEmu::PadMapping[Page].DeadZoneR / 100.0;
float DeadZoneLeft = (float)WiiMoteEmu::WiiMapping[m_Page].DeadZoneL / 100.0;
float DeadZoneRight = (float)WiiMoteEmu::WiiMapping[m_Page].DeadZoneR / 100.0;
if (InputCommon::IsDeadZone(DeadZoneLeft, main_x_after, main_y_after))
{
main_x_after = 0;
@ -643,63 +353,34 @@ void WiimotePadConfigDialog::PadGetStatus()
float f_Rx_aft = right_x_after / 32767.0;
float f_Ry_aft = right_y_after / 32767.0;
m_tStatusLeftIn[Page]->SetLabel(wxString::Format(
wxT("x:%1.2f y:%1.2f"), f_x, f_y
));
m_tStatusLeftOut[Page]->SetLabel(wxString::Format(
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
));
m_tStatusLeftIn[m_Page]->SetLabel(wxString::Format(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_tStatusRightOut[m_Page]->SetLabel(wxString::Format(wxT("x:%1.2f y:%1.2f"), f_Rx_aft, f_Ry_aft));
// Adjust the values for the plot
Convert2Box(main_x); Convert2Box(main_y);
Convert2Box(right_x); Convert2Box(right_y);
Convert2Box(main_x_after); Convert2Box(main_y_after);
Convert2Box(right_x_after); Convert2Box(right_y_after);
// Adjust the dot
m_bmpDotLeftIn[Page]->SetPosition(wxPoint(main_x, main_y));
m_bmpDotLeftOut[Page]->SetPosition(wxPoint(main_x_after, main_y_after));
m_bmpDotRightIn[Page]->SetPosition(wxPoint(right_x, right_y));
m_bmpDotRightOut[Page]->SetPosition(wxPoint(right_x_after, right_y_after));
m_bmpDotLeftIn[m_Page]->SetPosition(wxPoint(main_x, main_y));
m_bmpDotLeftOut[m_Page]->SetPosition(wxPoint(main_x_after, main_y_after));
m_bmpDotRightIn[m_Page]->SetPosition(wxPoint(right_x, right_y));
m_bmpDotRightOut[m_Page]->SetPosition(wxPoint(right_x_after, right_y_after));
// Get the trigger values
int TriggerLeft = WiiMoteEmu::PadState[Page].Axis.Tl;
int TriggerRight = WiiMoteEmu::PadState[Page].Axis.Tr;
int TriggerLeft = WiiMoteEmu::WiiMapping[m_Page].AxisState.Tl;
int TriggerRight = WiiMoteEmu::WiiMapping[m_Page].AxisState.Tr;
// 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);
TriggerRight = InputCommon::Pad_Convert(TriggerRight);
}
m_TriggerStatusL[Page]->SetLabel(wxString::Format(
wxT("%03i"), TriggerLeft));
m_TriggerStatusR[Page]->SetLabel(wxString::Format(
wxT("%03i"), TriggerRight));
m_TriggerStatusL[m_Page]->SetLabel(wxString::Format(wxT("%03i"), TriggerLeft));
m_TriggerStatusR[m_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_BUTTON(ID_CLOSE, 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_UPDATE_PAD, WiimotePadConfigDialog::UpdatePad)
EVT_TIMER(IDTM_UPDATE_PAD, WiimotePadConfigDialog::UpdatePadInfo)
EVT_COMBOBOX(IDC_JOYNAME, WiimotePadConfigDialog::GeneralSettingsChanged)
EVT_CHECKBOX(IDC_RUMBLE, WiimotePadConfigDialog::GeneralSettingsChanged)
@ -125,17 +126,21 @@ WiimotePadConfigDialog::WiimotePadConfigDialog(wxWindow *parent, wxWindowID id,
GetButtonWaitingID = 0;
GetButtonWaitingTimer = 0;
if (WiiMoteEmu::NumGoodPads)
{
// Start the permanent timer
const int TimesPerSecond = 10;
m_UpdatePadTimer->Start(1000 / TimesPerSecond);
}
#endif
ControlsCreated = false;
Page = 0;
//g_Config.Load();
CreatePadGUIControls();
//SetBackgroundColour(m_Notebook->GetBackgroundColour());
m_Page = g_Config.CurrentPage;
m_Notebook->ChangeSelection(m_Page);
// Set control values
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)
{
event.Skip();
@ -173,8 +191,8 @@ void WiimotePadConfigDialog::OnKeyDown(wxKeyEvent& event)
// Allow the escape key to set a blank key
if (g_Pressed == WXK_ESCAPE)
{
SaveKeyboardMapping(Page, ClickedButton->GetId(), -1);
SetButtonText(ClickedButton->GetId(), "");
SaveButtonMapping(ClickedButton->GetId(), -1);
SetButtonText(ClickedButton->GetId(), wxString());
}
else
{
@ -188,10 +206,10 @@ void WiimotePadConfigDialog::OnKeyDown(wxKeyEvent& event)
// Use the left and right specific keys instead of the common ones
if (i == VK_SHIFT || i == VK_CONTROL || i == VK_MENU) continue;
// Update the button label
strcpy(keyStr, InputCommon::VKToString(i).c_str());
SetButtonText(ClickedButton->GetId(), keyStr);
SetButtonText(ClickedButton->GetId(),
wxString::FromAscii(InputCommon::VKToString(i).c_str()));
// Save the setting
SaveKeyboardMapping(Page, ClickedButton->GetId(), i);
SaveButtonMapping(ClickedButton->GetId(), i);
break;
}
}
@ -199,7 +217,7 @@ void WiimotePadConfigDialog::OnKeyDown(wxKeyEvent& event)
int XKey = InputCommon::wxCharCodeWXToX(g_Pressed);
InputCommon::XKeyToString(XKey, keyStr);
SetButtonText(ClickedButton->GetId(), keyStr);
SaveKeyboardMapping(Page, ClickedButton->GetId(), XKey);
SaveKeyboardMapping(m_Page, ClickedButton->GetId(), XKey);
#endif
}
m_ButtonMappingTimer->Stop();
@ -223,12 +241,11 @@ void WiimotePadConfigDialog::OnButtonClick(wxCommandEvent& event)
ClickedButton = (wxButton *)event.GetEventObject();
// Save old label so we can revert back
OldLabel = ClickedButton->GetLabel();
ClickedButton->SetWindowStyle(wxWANTS_CHARS);
//ClickedButton->SetWindowStyle(wxWANTS_CHARS);
ClickedButton->SetLabel(wxT("<Press Key>"));
DoGetButtons(ClickedButton->GetId());
}
void WiimotePadConfigDialog::OnClose(wxCloseEvent& event)
{
if (m_UpdatePadTimer)
@ -236,7 +253,8 @@ void WiimotePadConfigDialog::OnClose(wxCloseEvent& event)
if (m_ButtonMappingTimer)
m_ButtonMappingTimer->Stop();
SaveButtonMappingAll(Page);
g_Config.CurrentPage = m_Page;
EndModal(wxID_CLOSE);
}
@ -248,40 +266,10 @@ void WiimotePadConfigDialog::CloseClick(wxCommandEvent& event)
Close();
break;
case ID_APPLY:
SaveButtonMappingAll(Page);
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
wxBitmap WiimotePadConfigDialog::CreateBitmap()
{
@ -357,7 +345,7 @@ void WiimotePadConfigDialog::CreatePadGUIControls()
}
else
{
StrJoyname.Add(wxString::FromAscii("<No Gamepad Detected>"));
StrJoyname.Add(wxT("<No Gamepad Detected>"));
}
wxArrayString TextDeadZone;
@ -377,11 +365,10 @@ void WiimotePadConfigDialog::CreatePadGUIControls()
// The tilt list
wxArrayString StrTilt;
StrTilt.Add(wxString::FromAscii("<Off>"));
StrTilt.Add(wxString::FromAscii("Keyboard"));
StrTilt.Add(wxString::FromAscii("Analog 1"));
StrTilt.Add(wxString::FromAscii("Analog 2"));
StrTilt.Add(wxString::FromAscii("Triggers"));
StrTilt.Add(wxT("Keyboard"));
StrTilt.Add(wxT("Analog 1"));
StrTilt.Add(wxT("Analog 2"));
StrTilt.Add(wxT("Triggers"));
// The range is in degrees and are set at even 5 degrees values
wxArrayString StrTiltRangeRoll, StrTiltRangePitch;
@ -392,24 +379,24 @@ void WiimotePadConfigDialog::CreatePadGUIControls()
// The Trigger type list
wxArrayString StrTriggerType;
StrTriggerType.Add(wxString::FromAscii("SDL")); // -0x8000 to 0x7fff
StrTriggerType.Add(wxString::FromAscii("XInput")); // 0x00 to 0xff
StrTriggerType.Add(wxT("SDL")); // -0x8000 to 0x7fff
StrTriggerType.Add(wxT("XInput")); // 0x00 to 0xff
// The Nunchuck stick list
wxArrayString StrNunchuck;
StrNunchuck.Add(wxString::FromAscii("Keyboard"));
StrNunchuck.Add(wxString::FromAscii("Analog 1"));
StrNunchuck.Add(wxString::FromAscii("Analog 2"));
StrNunchuck.Add(wxT("Keyboard"));
StrNunchuck.Add(wxT("Analog 1"));
StrNunchuck.Add(wxT("Analog 2"));
// The Classic Controller triggers list
wxArrayString StrCcTriggers;
StrCcTriggers.Add(wxString::FromAscii("Keyboard"));
StrCcTriggers.Add(wxString::FromAscii("Triggers"));
StrCcTriggers.Add(wxT("Keyboard"));
StrCcTriggers.Add(wxT("Triggers"));
// GH3 stick list
wxArrayString StrAnalogArray;
StrAnalogArray.Add(wxString::FromAscii("Analog 1"));
StrAnalogArray.Add(wxString::FromAscii("Analog 2"));
StrAnalogArray.Add(wxT("Analog 1"));
StrAnalogArray.Add(wxT("Analog 2"));
static const wxChar* anText[] =
{
@ -579,21 +566,17 @@ void WiimotePadConfigDialog::CreatePadGUIControls()
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]->SetSelection(g_Config.Tilt.TypeWM);
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]->SetSelection(g_Config.Tilt.TypeNC);
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_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]->SetValue(wxString::Format(wxT("%i"), g_Config.Tilt.Range.Roll));
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]->SetValue(wxString::Format(wxT("%i"), g_Config.Tilt.Range.Pitch));
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]->SetToolTip(wxT("Emulate Swing Left/Right instead of Roll Left/Right"));
@ -634,10 +617,10 @@ void WiimotePadConfigDialog::CreatePadGUIControls()
// Stick Status Panels
m_tStatusLeftIn[i] = new wxStaticText(m_Controller[i], wxID_ANY, wxT("In"));
m_tStatusLeftOut[i] = new wxStaticText(m_Controller[i], wxID_ANY, wxT("Out"));
m_tStatusRightIn[i] = new wxStaticText(m_Controller[i], wxID_ANY, wxT("In"));
m_tStatusRightOut[i] = new wxStaticText(m_Controller[i], wxID_ANY, wxT("Out"));
m_tStatusLeftIn[i] = new wxStaticText(m_Controller[i], wxID_ANY, wxT("Not connected"));
m_tStatusLeftOut[i] = new wxStaticText(m_Controller[i], wxID_ANY, wxT("Not connected"));
m_tStatusRightIn[i] = new wxStaticText(m_Controller[i], wxID_ANY, wxT("Not connected"));
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_bmpSquareLeftIn[i] = new wxStaticBitmap(m_pLeftInStatus[i], wxID_ANY, CreateBitmap(), wxDefaultPosition, wxDefaultSize);
@ -681,7 +664,7 @@ void WiimotePadConfigDialog::CreatePadGUIControls()
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_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);
// Sizers
@ -710,7 +693,7 @@ void WiimotePadConfigDialog::CreatePadGUIControls()
m_sAnalogMiddle[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_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_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_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]->Add(m_statictext_Wiimote[x][i], 0, (wxUP), 4);
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);
else
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);
// Extension Mapping
if(g_Config.iExtensionConnected == EXT_NUNCHUCK)
if(WiiMoteEmu::WiiMapping[i].iExtensionConnected == WiiMoteEmu::EXT_NUNCHUCK)
{
// Stick controls
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]->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_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]->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
m_sNCVertLeft[i]->Add(m_Sizer_NunChuck[x - IDB_NC_Z][i], 0, wxALIGN_RIGHT | (wxLEFT | wxRIGHT | wxDOWN), 1);
else
@ -798,20 +780,17 @@ void WiimotePadConfigDialog::CreatePadGUIControls()
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
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]->SetSelection(g_Config.ClassicController.LType);
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]->SetSelection(g_Config.ClassicController.RType);
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]->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_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_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
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]->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_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
m_sHorizControllerMapping[i] = new wxBoxSizer(wxHORIZONTAL);
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);
break;
case EXT_CLASSIC_CONTROLLER:
case WiiMoteEmu::EXT_CLASSIC_CONTROLLER:
m_sHorizControllerMapping[i]->Add(m_gClassicController[i], 0, (wxLEFT), 5);
break;
case EXT_GUITARHERO3_CONTROLLER:
case WiiMoteEmu::EXT_GUITARHERO:
m_sHorizControllerMapping[i]->Add(m_gGuitarHero3Controller[i], 0, (wxLEFT), 5);
break;
default:
@ -918,7 +896,6 @@ void WiimotePadConfigDialog::CreatePadGUIControls()
}
// Set up sizers and layout
// The sizer m_sMain will be expanded inside m_Controller
m_sMain[i] = new wxBoxSizer(wxVERTICAL);
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(sButtons, 0, wxEXPAND | (wxLEFT | wxRIGHT | wxDOWN), 5);
for (int i = MAX_WIIMOTES - 1; i > 0; i--)
{
m_Controller[i]->Enable(false);
}
this->SetSizer(m_MainSizer);
this->Layout();
SetSizer(m_MainSizer);
Layout();
Fit();
// Center the window if there is room for it
#ifdef _WIN32
if (GetSystemMetrics(SM_CYFULLSCREEN) > 600)
@ -961,96 +931,199 @@ void WiimotePadConfigDialog::CreatePadGUIControls()
ControlsCreated = true;
}
void WiimotePadConfigDialog::GeneralSettingsChanged(wxCommandEvent& event)
// Notebook page changed
void WiimotePadConfigDialog::NotebookPageChanged(wxNotebookEvent& event)
{
long TmpValue;
// Update the global variable
m_Page = event.GetSelection();
switch (event.GetId())
{
case IDC_JOYNAME:
DoChangeJoystick();
break;
case IDC_TILT_TYPE_WM:
g_Config.Tilt.TypeWM = m_TiltTypeWM[Page]->GetSelection();
break;
case IDC_TILT_TYPE_NC:
g_Config.Tilt.TypeNC = m_TiltTypeNC[Page]->GetSelection();
break;
case IDC_TILT_ROLL:
case IDC_TILT_ROLL_SWING:
m_TiltComboRangeRoll[Page]->GetValue().ToLong(&TmpValue);
g_Config.Tilt.Range.RollDegree = TmpValue;
g_Config.Tilt.Range.RollSwing = m_TiltRollSwing[Page]->IsChecked();
g_Config.Tilt.Range.Roll = (g_Config.Tilt.Range.RollSwing) ? 0 : g_Config.Tilt.Range.RollDegree;
break;
case IDC_TILT_PITCH:
case IDC_TILT_PITCH_SWING:
m_TiltComboRangePitch[Page]->GetValue().ToLong(&TmpValue);
g_Config.Tilt.Range.PitchDegree = TmpValue;
g_Config.Tilt.Range.PitchSwing = m_TiltPitchSwing[Page]->IsChecked();
g_Config.Tilt.Range.Pitch = (g_Config.Tilt.Range.PitchSwing) ? 0 : g_Config.Tilt.Range.PitchDegree;
break;
case IDC_TILT_ROLL_INVERT:
g_Config.Tilt.RollInvert = m_TiltRollInvert[Page]->IsChecked();
break;
case IDC_TILT_PITCH_INVERT:
g_Config.Tilt.PitchInvert = m_TiltPitchInvert[Page]->IsChecked();
break;
case IDC_NUNCHUCK_STICK:
g_Config.Nunchuck.Type = m_NunchuckComboStick[Page]->GetSelection();
break;
case IDC_CC_LEFT_STICK:
g_Config.ClassicController.LType = m_CcComboLeftStick[Page]->GetSelection();
break;
case IDC_CC_RIGHT_STICK:
g_Config.ClassicController.RType = m_CcComboRightStick[Page]->GetSelection();
break;
case IDC_CC_TRIGGERS:
g_Config.ClassicController.TType = m_CcComboTriggers[Page]->GetSelection();
break;
case IDC_GH3_ANALOG:
g_Config.GH3Controller.AType = m_GH3ComboAnalog[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;
}
// g_Config.Save();
// Update GUI
if (ControlsCreated)
UpdateGUI();
}
void WiimotePadConfigDialog::UpdateGUI(int Slot)
void WiimotePadConfigDialog::GeneralSettingsChanged(wxCommandEvent& event)
{
UpdateGUIButtonMapping(Page);
DoChangeDeadZone(true);
DoChangeDeadZone(false);
long TmpValue;
int id = event.GetId();
// Linux has no FindItem()
// Disable all pad items if no pads are detected
if(ControlsCreated)
switch (id)
{
bool PadEnabled = WiiMoteEmu::NumGoodPads != 0;
#ifdef _WIN32
m_Notebook->FindItem(IDC_JOYNAME)->Enable(PadEnabled);
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);
m_Notebook->FindItem(IDC_STICK_DIAGONAL)->Enable(PadEnabled);
m_Notebook->FindItem(IDC_RUMBLE)->Enable(PadEnabled);
m_Notebook->FindItem(IDC_RUMBLE_STRENGTH)->Enable(PadEnabled);
m_Notebook->FindItem(IDC_TRIGGER_TYPE)->Enable(PadEnabled);
m_Notebook->FindItem(IDC_TILT_ROLL)->Enable(!g_Config.Tilt.Range.RollSwing);
m_Notebook->FindItem(IDC_TILT_PITCH)->Enable(!g_Config.Tilt.Range.PitchSwing);
for(int i = IDB_ANALOG_LEFT_X; i <= IDB_TRIGGER_R; i++)
m_Notebook->FindItem(i)->Enable(PadEnabled);
#endif
case IDC_JOYNAME:
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;
case IDC_TILT_TYPE_WM:
WiiMoteEmu::WiiMapping[m_Page].Tilt.InputWM = m_TiltTypeWM[m_Page]->GetSelection();
break;
case IDC_TILT_TYPE_NC:
WiiMoteEmu::WiiMapping[m_Page].Tilt.InputNC = m_TiltTypeNC[m_Page]->GetSelection();
break;
case IDC_TILT_ROLL:
case IDC_TILT_ROLL_SWING:
m_TiltComboRangeRoll[m_Page]->GetValue().ToLong(&TmpValue);
WiiMoteEmu::WiiMapping[m_Page].Tilt.RollDegree = TmpValue;
WiiMoteEmu::WiiMapping[m_Page].Tilt.RollSwing = m_TiltRollSwing[m_Page]->IsChecked();
WiiMoteEmu::WiiMapping[m_Page].Tilt.RollRange = (m_TiltRollSwing[m_Page]->IsChecked()) ? 0 : TmpValue;
break;
case IDC_TILT_PITCH:
case IDC_TILT_PITCH_SWING:
m_TiltComboRangePitch[m_Page]->GetValue().ToLong(&TmpValue);
WiiMoteEmu::WiiMapping[m_Page].Tilt.PitchDegree = TmpValue;
WiiMoteEmu::WiiMapping[m_Page].Tilt.PitchSwing = m_TiltPitchSwing[m_Page]->IsChecked();
WiiMoteEmu::WiiMapping[m_Page].Tilt.PitchRange = (m_TiltPitchSwing[m_Page]->IsChecked()) ? 0 : TmpValue;
break;
case IDC_TILT_ROLL_INVERT:
WiiMoteEmu::WiiMapping[m_Page].Tilt.RollInvert = m_TiltRollInvert[m_Page]->IsChecked();
break;
case IDC_TILT_PITCH_INVERT:
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;
case IDC_NUNCHUCK_STICK:
WiiMoteEmu::WiiMapping[m_Page].Stick.NC = m_NunchuckComboStick[m_Page]->GetSelection();
break;
case IDC_CC_LEFT_STICK:
WiiMoteEmu::WiiMapping[m_Page].Stick.CCL = m_CcComboLeftStick[m_Page]->GetSelection();
break;
case IDC_CC_RIGHT_STICK:
WiiMoteEmu::WiiMapping[m_Page].Stick.CCR = m_CcComboRightStick[m_Page]->GetSelection();
break;
case IDC_CC_TRIGGERS:
WiiMoteEmu::WiiMapping[m_Page].Stick.CCT = m_CcComboTriggers[m_Page]->GetSelection();
break;
case IDC_GH3_ANALOG:
WiiMoteEmu::WiiMapping[m_Page].Stick.GH = m_GH3ComboAnalog[m_Page]->GetSelection();
break;
}
UpdateGUI();
}
void WiimotePadConfigDialog::UpdateGUI()
{
if(!ControlsCreated)
return;
wxString tmp;
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++)
{
tmp << WiiMoteEmu::WiiMapping[m_Page].AxisMapping.Code[i];
m_Button_Analog[i][m_Page]->SetLabel(tmp);
tmp.clear();
}
#ifdef _WIN32
for (int x = 0; x <= IDB_WM_SHAKE - IDB_WM_A; x++)
{
m_Button_Wiimote[x][m_Page]->SetLabel(wxString::FromAscii(
InputCommon::VKToString(WiiMoteEmu::WiiMapping[m_Page].Button[x + WiiMoteEmu::EWM_A]).c_str()));
}
if(WiiMoteEmu::WiiMapping[m_Page].iExtensionConnected == WiiMoteEmu::EXT_NUNCHUCK)
{
for (int x = 0; x <= IDB_NC_SHAKE - IDB_NC_Z; x++)
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/gbsizer.h>
#include "Config.h"
#include "wiimote_hid.h"
#if defined(HAVE_X11) && HAVE_X11
#include <X11/Xlib.h>
@ -51,169 +52,24 @@ class WiimotePadConfigDialog : public wxDialog
long style = wxDEFAULT_DIALOG_STYLE | wxWANTS_CHARS);
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 ConvertToString();
void OnButtonTimer(wxTimerEvent& WXUNUSED(event)) { DoGetButtons(GetButtonWaitingID); }
void UpdatePad(wxTimerEvent& WXUNUSED(event));
wxTimer *m_UpdatePadTimer,
*m_ButtonMappingTimer;
wxStaticBitmap *m_bmpDotLeftIn[4],
*m_bmpDotLeftOut[4],
*m_bmpDotRightIn[4],
*m_bmpDotRightOut[4],
*m_bmpDeadZoneLeftIn[4],
*m_bmpDeadZoneRightIn[4];
wxStaticBitmap *m_bmpDotLeftIn[MAX_WIIMOTES],
*m_bmpDotLeftOut[MAX_WIIMOTES],
*m_bmpDotRightIn[MAX_WIIMOTES],
*m_bmpDotRightOut[MAX_WIIMOTES],
*m_bmpDeadZoneLeftIn[MAX_WIIMOTES],
*m_bmpDeadZoneRightIn[MAX_WIIMOTES];
private:
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
{
ID_CLOSE = 1000,
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,
// <It's important that the internal ordering of these are unchanged>
// Wiimote
IDB_WM_A, IDB_WM_B,
IDB_WM_1, IDB_WM_2,
@ -259,6 +115,22 @@ class WiimotePadConfigDialog : public wxDialog
IDB_GH3_STRUM_UP,
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
IDC_JOYNAME,
IDC_RUMBLE, IDC_RUMBLE_STRENGTH,
@ -274,34 +146,155 @@ class WiimotePadConfigDialog : public wxDialog
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 CreateBitmapDot();
wxBitmap CreateBitmapDeadZone(int Radius);
wxBitmap CreateBitmapClear();
void OnClose(wxCloseEvent& event);
void CloseClick(wxCommandEvent& event);
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 SaveButtonMapping(int Id, int Key);
// Gamepad configuration
void SetButtonText(int id, const char text[128], int _Page = -1);
void SetButtonTextAll(int id, char text[128]);
void SetButtonText(int id,const wxString &str);
wxString GetButtonText(int id);
void GetButtons(wxCommandEvent& btn_event);
void DoGetButtons(int id);
void SaveButtonMapping(int controller, bool DontChangeId = false, int FromSlot = -1);
void SaveButtonMappingAll(int Slot);
void SaveKeyboardMapping(int Controller, int Id, int Key);
void ToBlank(bool ToBlank = true);
void PadGetStatus();
void DoSave(bool ChangePad = false, int Slot = -1);
void DoChangeJoystick();
void PadOpen(int Open); void PadClose(int Close);
void DoChangeDeadZone(bool Left);
void OnButtonClick(wxCommandEvent& event);
void UpdatePadInfo(wxTimerEvent& WXUNUSED(event));
void ToBlank(bool ToBlank, int Id);
void DoChangeDeadZone();
// Configure buttons
int GetButtonWaitingID, GetButtonWaitingTimer, g_Pressed;
wxString GetButtonText(int id, int Page = -1);
};
extern WiimotePadConfigDialog *m_PadConfigFrame;
#endif

View File

@ -429,11 +429,6 @@ void WiimoteRecordingConfigDialog::RecordMovement(wxCommandEvent& event)
else
{
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;
}

View File

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

View File

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

View File

@ -68,32 +68,23 @@ extern double g_RecordingCurrentTime[3];
#define WIIMOTE_REG_EXT_SIZE 0x100
#define WIIMOTE_REG_IR_SIZE 0x34
extern u8 g_IR[4];
extern u8 g_Leds[4];
extern u8 g_Speaker;
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_RegSpeaker[WIIMOTE_REG_SPEAKER_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_RegIr[WIIMOTE_REG_IR_SIZE];
extern int g_RefreshWiimote;
extern bool g_ReportingAuto[4];
extern u8 g_ReportingMode;
extern u16 g_ReportingChannel;
// Ack delay
struct wm_ackdelay
{
u8 Delay;
u8 ReportID;
u16 ChannelID;
bool Sent;
};
extern std::vector<wm_ackdelay> AckDelay;
extern int g_ID;
extern bool g_ReportingAuto[MAX_WIIMOTES];
extern u8 g_ReportingMode[MAX_WIIMOTES];
extern u16 g_ReportingChannel[MAX_WIIMOTES];
extern wiimote_key g_ExtKey; // extension encryption key
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
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
{
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
SIR IR;
STiltData TiltWM;
STiltData TiltNC;
};
extern SWiimoteData g_WiimoteData[4];
// Keyboard input
struct KeyboardWiimote
struct CONTROLLER_MAPPING_WII // WII PAD MAPPING
{
enum EKeyboardWiimote
{
A = 0, // Keyboard A and Mouse A
B,
ONE, TWO,
P, M, H,
L, R, U, D,
ROLL_L, ROLL_R,
PITCH_U, PITCH_D,
SHAKE,
MA, MB,
LAST_CONSTANT
};
};
extern KeyboardWiimote g_Wiimote_kbd;
SDL_Joystick *joy; // SDL joystick device
UAxis AxisState;
UAxis AxisMapping; // 6 Axes (Main, Sub, Triggers)
int TriggerType; // SDL or XInput trigger
int ID; // SDL joystick device ID
bool Rumble;
int RumbleStrength;
int DeadZoneL; // Analog 1 Deadzone
int DeadZoneR; // Analog 2 Deadzone
bool bCircle2Square;
std::string Diagonal;
struct KeyboardNunchuck
{
enum EKeyboardNunchuck
{
Z = 18,
C,
L, R, U, D,
ROLL_L, ROLL_R,
PITCH_U, PITCH_D,
SHAKE,
LAST_CONSTANT
};
};
extern KeyboardNunchuck g_NunchuckExt;
int Source; // 0: none, 1: emu, -1: real
bool bSideways;
bool bUpright;
bool bMotionPlusConnected;
int iExtensionConnected;
struct KeyboardClassicController
{
enum EKeyboardClassicController
{
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
};
STiltMapping Tilt;
SStickMapping Stick;
int Button[LAST_CONSTANT];
SMotion Motion;
};
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];
} // namespace
#endif //_EMU_DEFINITIONS_

View File

@ -39,30 +39,256 @@
namespace WiiMoteEmu
{
//******************************************************************************
// Accelerometer functions
//******************************************************************************
/*
// 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());
// Wiimote accelerometer
/* The accelerometer x, y and z values range from 0x00 to 0xff with the default
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
all values are not 0x80, the mouse pointer can disappear from the screen
permanently then, until z is adjusted back. This is because the game detects
a steep pitch of the Wiimote then.
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
used. When the absolute values of the angles go over 90 the Wiimote is
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
// 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);
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);
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
@ -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 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(g_Config.Tilt.Range.Pitch != 0) _y = iy;
if(WiiMapping[g_ID].Tilt.RollRange) _x = ix;
if(WiiMapping[g_ID].Tilt.PitchRange) _y = iy;
_z = iz;
}
else // Upright wiimote
{
if(g_Config.Tilt.Range.Roll != 0) _x = ix;
if(g_Config.Tilt.Range.Pitch != 0) _z = iy;
if(WiiMapping[g_ID].Tilt.RollRange) _x = ix;
if(WiiMapping[g_ID].Tilt.PitchRange) _z = iy;
_y = 0xFF - iz;
}
// 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;
}
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;
else // Upright wiimote
_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
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;
_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 (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;
@ -237,13 +503,10 @@ void PitchAccelerometerToDegree(u8 _x, u8 _y, u8 _z, int &_Roll, int &_Pitch, in
_PitchAdj = (int)Pitch;
}
//******************************************************************************
// IR data functions
//******************************************************************************
/*
// Calculate dot positions from the basic 10 byte IR data
void IRData2DotsBasic(u8 *Data)
{
@ -282,9 +545,7 @@ void IRData2DotsBasic(u8 *Data)
ReorderIRDots();
IRData2Distance();
}
*/
/*
// Calculate dot positions from the extented 12 byte IR data
void IRData2Dots(u8 *Data)
{
@ -315,9 +576,7 @@ void IRData2Dots(u8 *Data)
ReorderIRDots();
IRData2Distance();
}
*/
/*
// Reorder the IR dots according to their x-axis value
void ReorderIRDots()
{
@ -350,9 +609,7 @@ void ReorderIRDots()
Dot[i].Order = order;
}
}
*/
/*
// Calculate dot positions from the extented 12 byte IR data
void IRData2Distance()
{
@ -383,7 +640,6 @@ void IRData2Distance()
// Save the distance
g_Wiimote_kbd.IR.Distance = (int)sqrt((float)(xd*xd) + (float)(yd*yd));
}
*/
//******************************************************************************
// 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[2] & 0x1f));
}
*/
} // WiiMoteEmu

View File

@ -39,117 +39,6 @@ extern SWiimoteInitialize g_WiimoteInitialize;
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. */
void CryptBuffer(u8* _buffer, u8 _size)
{
@ -167,7 +56,6 @@ void WriteCrypted16(u8* _baseBlock, u16 _address, u16 _value)
*(u16*)(_baseBlock + _address) = cryptedValue;
}
/* Calculate Extenstion Regisister Calibration Checksum */
// This function is not currently used, it's just here to show how the values
// in EmuDefinitions.h are calculated.
@ -180,6 +68,27 @@ void GetCalibrationChecksum()
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 */
void LoadRecordedMovements()
@ -290,142 +199,118 @@ void LoadRecordedMovements()
}
}
// Update the accelerometer neutral values
void UpdateEeprom()
/* Calibrate the mouse position to the emulation window. g_WiimoteInitialize.hWnd is the rendering window handle. */
void GetMousePos(float& x, float& y)
{
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];
#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);
INFO_LOG(WIIMOTE, "UpdateEeprom: %i %i %i",
WiiMoteEmu::g_Eeprom[22], WiiMoteEmu::g_Eeprom[23], WiiMoteEmu::g_Eeprom[28]);
// 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;
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];
g_nu.cal_zero.y = g_RegExt[0x21];
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];
// 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));
INFO_LOG(WIIMOTE, "UpdateNunchuck: %i %i %i %i %i",
WiiMoteEmu::g_RegExt[0x2a], WiiMoteEmu::g_RegExt[0x2d],
WiiMoteEmu::g_RegExt[0x20], WiiMoteEmu::g_RegExt[0x21], WiiMoteEmu::g_RegExt[0x26]);
// 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;
}
else if(g_Config.iExtensionConnected == EXT_CLASSIC_CONTROLLER)
// The window is to high, we have to limit the height
else
{
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];
// 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;
g_ClassicContCalibration.Rx.max = g_RegExt[0x26];
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];
g_ClassicContCalibration.Tr.neutral = g_RegExt[0x2d];
INFO_LOG(WIIMOTE, "UpdateCC: %i %i %i %i %i",
WiiMoteEmu::g_RegExt[0x2a], WiiMoteEmu::g_RegExt[0x2d],
WiiMoteEmu::g_RegExt[0x20], WiiMoteEmu::g_RegExt[0x21], WiiMoteEmu::g_RegExt[0x26]);
// 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;
}
else if(g_Config.iExtensionConnected == EXT_GUITARHERO3_CONTROLLER)
{
// TODO get the correct values here
g_GH3Calibration.Lx.max = g_RegExt[0x20];
g_GH3Calibration.Lx.min = g_RegExt[0x21];
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];
/*
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);
*/
}
}
// 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++)
// 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)
{
sum += Calibration[i];
//INFO_LOG(WIIMOTE, "Plus 0x%02x", Calibration[i]);
}
// Byte15 = sum + 0x55; // Byte 15
// Byte16 = sum + 0xaa; // Byte 16
}
float Ratio = g_Config.bKeepAR43 ? ((4.0f / 3.0f) / (5.0f / 4.0f)) : (((16.0f / 9.0f) / (16.0f / 10.0f)));
// Set initial valuesm this done both in Init and Shutdown
void ResetVariables()
{
g_RefreshWiimote = 0;
g_ReportingMode = 0;
g_ReportingChannel = 0;
g_Encryption = false;
// 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;
for (int i = 0; i < 4; i++)
{
g_ReportingAuto[i] = false;
memset(&g_WiimoteData[i], 0, sizeof(g_WiimoteData));
// 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);
*/
}
// 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;
}
// 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
g_EmulatedWiiMoteInitialized = false;
}
// Update the extension calibration values with our default values
void UpdateExtRegisterBlocks()
/* 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()
{
// Copy extension id and calibration to its register
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, "ShutDown");
INFO_LOG(WIIMOTE, "UpdateExtRegisterBlocks()");
UpdateEeprom();
ResetVariables();
// Close joypads
Close_Devices();
// Finally close SDL
if (SDL_WasInit(0))
SDL_Quit();
}
// Start emulation
@ -433,27 +318,28 @@ void Initialize()
{
INFO_LOG(WIIMOTE, "Initialize");
//if (g_EmulatedWiiMoteInitialized) return;
// Reset variables
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
// WiiMoteReal::Initialize() after this function.
memset(g_Eeprom, 0, WIIMOTE_EEPROM_SIZE);
memcpy(g_Eeprom, EepromData_0, sizeof(EepromData_0));
memcpy(g_Eeprom + 0x16D0, EepromData_16D0, sizeof(EepromData_16D0));
/* 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();
InitCalibration();
// 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
g_EmulatedWiiMoteInitialized = true;
@ -471,23 +357,129 @@ void Initialize()
// 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)
{
// TODO: Shorten the list
p.Do(g_Speaker);
p.Do(g_SpeakerVoice);
p.Do(g_IR);
p.DoArray(g_Eeprom, WIIMOTE_EEPROM_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_RegExtTmp, WIIMOTE_REG_EXT_SIZE);
p.DoArray(g_RegIr, WIIMOTE_REG_IR_SIZE);
p.Do(g_ReportingMode);
p.Do(g_ReportingChannel);
p.Do(g_ExtKey);
p.Do(g_Encryption);
@ -500,39 +492,28 @@ void DoState(PointerWrap &p)
//p.Do(g_NunchuckExt);
//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_ReportingMode[i]);
p.Do(g_ReportingChannel[i]);
//p.Do(g_IR[i]);
p.Do(g_Leds[i]);
p.Do(g_WiimoteData[i]);
}
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
response to Output from the Wii. */
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
not determined by sizeof(data). We have to determine it by looking at
the data cases. */
//InterruptDebugging(true, (const void*)_pData);
g_ID = _number;
hid_packet* hidp = (hid_packet*)_pData;
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)
{
// 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);
g_ReportingAuto[_number] = false;
return;
}
g_RefreshWiimote = _number;
g_ID = _number;
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
// (TO_BE_VERIFIED)
//
u8 handshake = 0;
g_WiimoteInitialize.pWiimoteInput(g_RefreshWiimote, _channelID, &handshake, 1);
u8 handshake = HID_HANDSHAKE_SUCCESS;
g_WiimoteInitialize.pWiimoteInput(g_ID, _channelID, &handshake, 1);
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
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
@ -634,42 +613,36 @@ void Update(int _number)
if (g_ReportingAuto[_number] == false)
return;
g_RefreshWiimote = _number;
g_ID = _number;
// Read input or not
if (g_Config.bInputActive)
if (WiiMapping[g_ID].Source > 0)
{
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
if (NumGoodPads > 0 && joyinfo.size() > (u32)PadMapping[g_RefreshWiimote].ID)
WiiMoteEmu::GetJoyState(PadState[g_RefreshWiimote], PadMapping[g_RefreshWiimote], g_RefreshWiimote, joyinfo[PadMapping[g_RefreshWiimote].ID].NumButtons);
if (NumGoodPads > 0 && joyinfo.size() > (u32)WiiMapping[g_ID].ID)
UpdatePadState(WiiMapping[g_ID]);
}
switch(g_ReportingMode)
switch(g_ReportingMode[g_ID])
{
case 0:
break;
case WM_REPORT_CORE:
SendReportCore(g_ReportingChannel);
SendReportCore(g_ReportingChannel[g_ID]);
break;
case WM_REPORT_CORE_ACCEL:
SendReportCoreAccel(g_ReportingChannel);
SendReportCoreAccel(g_ReportingChannel[g_ID]);
break;
case WM_REPORT_CORE_ACCEL_IR12:
SendReportCoreAccelIr12(g_ReportingChannel);
SendReportCoreAccelIr12(g_ReportingChannel[g_ID]);
break;
case WM_REPORT_CORE_ACCEL_EXT16:
SendReportCoreAccelExt16(g_ReportingChannel);
SendReportCoreAccelExt16(g_ReportingChannel[g_ID]);
break;
case WM_REPORT_CORE_ACCEL_IR10_EXT6:
SendReportCoreAccelIr10Ext(g_ReportingChannel);
SendReportCoreAccelIr10Ext(g_ReportingChannel[g_ID]);
break;
}
}
@ -699,37 +672,11 @@ void ReadLinuxKeyboard()
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;
}
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;
}
case KeyRelease:
@ -743,38 +690,11 @@ void ReadLinuxKeyboard()
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;
}
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;
}
default:

View File

@ -32,47 +32,50 @@ namespace WiiMoteEmu
u32 convert24bit(const u8* src);
u16 convert16bit(const u8* src);
void GetMousePos(float& x, float& y);
// General functions
void ResetVariables();
void Initialize();
void DoState(PointerWrap &p);
void Shutdown();
void InitCalibration();
void UpdateExtRegisterBlocks(int Slot);
void InterruptChannel(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 DoState(PointerWrap &p);
void ReadLinuxKeyboard();
bool IsKey(int Key);
// Recordings
void LoadRecordedMovements();
// Registers and calibration values
void ResetVariables();
void UpdateEeprom();
void UpdateExtRegisterBlocks();
void GetMousePos(float& x, float& y);
// Gamepad
void Close_Devices();
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 PadStateAdjustments(int &Lx, int &Ly, int &Rx, int &Ry, int &Tl, int &Tr);
void GetAxisState(CONTROLLER_MAPPING_WII &_WiiMapping);
void UpdatePadState(CONTROLLER_MAPPING_WII &_WiiMapping);
// Accelerometer
void PitchAccelerometerToDegree(u8 _x, u8 _y, u8 _z, int &_Roll, int &_Pitch, int&, int&);
float AccelerometerToG(float Current, float Neutral, float G);
void TiltWiimote(int &_x, int &_y, int &_z);
void TiltNunchuck(int &_x, int &_y, int &_z);
void ShakeToAccelerometer(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 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
void RotateIRDots(int &_x, int &_y, STiltData &_TiltData);
void IRData2Dots(u8 *Data);
void IRData2DotsBasic(u8 *Data);
//void IRData2Dots(u8 *Data);
//void IRData2DotsBasic(u8 *Data);
//void ReorderIRDots();
//void IRData2Distance();
// Classic Controller data
std::string CCData2Values(u8 *Data);
//std::string CCData2Values(u8 *Data);
}; // WiiMoteEmu

View File

@ -46,18 +46,18 @@ extern void PAD_RumbleClose();
void Close_Devices()
{
PAD_RumbleClose();
/* Close all devices carefully. We must check that we are not accessing any
undefined vector elements or any bad devices */
for (int i = 0; i < 1; i++)
// Close all devices carefully. We must check that we are not accessing any
// undefined vector elements or any bad devices
for (int i = 0; i < MAX_WIIMOTES; i++)
{
if (SDL_WasInit(0) && joyinfo.size() > (u32)PadMapping[i].ID)
if (PadState[i].joy && joyinfo.at(PadMapping[i].ID).Good)
if (SDL_WasInit(0) && joyinfo.size() > (u32)WiiMapping[i].ID)
if (WiiMapping[i].joy && joyinfo.at(WiiMapping[i].ID).Good)
{
INFO_LOG(WIIMOTE, "ShutDown: %i", PadState[i].joy);
if(SDL_JoystickOpened(PadMapping[i].ID))
INFO_LOG(WIIMOTE, "ShutDown: %i", WiiMapping[i].ID);
if(SDL_JoystickOpened(WiiMapping[i].ID))
{
SDL_JoystickClose(PadState[i].joy);
PadState[i].joy = NULL;
SDL_JoystickClose(WiiMapping[i].joy);
WiiMapping[i].joy = NULL;
}
}
}
@ -81,99 +81,50 @@ bool Search_Devices(std::vector<InputCommon::CONTROLLER_INFO> &_joyinfo, int &_N
return false;
// 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.at(PadMapping[i].ID).Good)
PadState[i].joy = SDL_JoystickOpen(PadMapping[i].ID);
if (joyinfo.size() > (u32)WiiMapping[i].ID)
if(joyinfo.at(WiiMapping[i].ID).Good)
WiiMapping[i].joy = SDL_JoystickOpen(WiiMapping[i].ID);
}
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
/* Called from: PAD_GetStatus() Input: The virtual device 0, 1, 2 or 3
Function: Updates the PadState struct with the current pad status. The input
value "controller" is for a virtual controller 0 to 3. */
void GetJoyState(InputCommon::CONTROLLER_STATE_NEW &_PadState, InputCommon::CONTROLLER_MAPPING_NEW _PadMapping, int controller, int NumButtons)
void GetAxisState(CONTROLLER_MAPPING_WII &_WiiMapping)
{
// Return if we have no pads
if (NumGoodPads == 0) return;
// Update the gamepad status
SDL_JoystickUpdate();
// 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);
_PadState.Axis.Ly = SDL_JoystickGetAxis(_PadState.joy, _PadMapping.Axis.Ly);
_PadState.Axis.Rx = SDL_JoystickGetAxis(_PadState.joy, _PadMapping.Axis.Rx);
_PadState.Axis.Ry = SDL_JoystickGetAxis(_PadState.joy, _PadMapping.Axis.Ry);
_WiiMapping.AxisState.Lx = SDL_JoystickGetAxis(_WiiMapping.joy, _WiiMapping.AxisMapping.Lx);
_WiiMapping.AxisState.Ly = SDL_JoystickGetAxis(_WiiMapping.joy, _WiiMapping.AxisMapping.Ly);
_WiiMapping.AxisState.Rx = SDL_JoystickGetAxis(_WiiMapping.joy, _WiiMapping.AxisMapping.Rx);
_WiiMapping.AxisState.Ry = SDL_JoystickGetAxis(_WiiMapping.joy, _WiiMapping.AxisMapping.Ry);
// Update the analog trigger axis values
#ifdef _WIN32
if (_PadMapping.triggertype == InputCommon::CTL_TRIGGER_SDL)
if (_WiiMapping.TriggerType == InputCommon::CTL_TRIGGER_SDL)
{
#endif
// If we are using SDL analog triggers the buttons have to be mapped as 1000 or up, otherwise they are not used
// We must also check that we are not asking for a negative axis number because SDL_JoystickGetAxis() has
// no good way of handling that
if ((_PadMapping.Axis.Tl - 1000) >= 0) _PadState.Axis.Tl = SDL_JoystickGetAxis(_PadState.joy, _PadMapping.Axis.Tl - 1000);
if ((_PadMapping.Axis.Tr - 1000) >= 0) _PadState.Axis.Tr = SDL_JoystickGetAxis(_PadState.joy, _PadMapping.Axis.Tr - 1000);
if ((_WiiMapping.AxisMapping.Tl - 1000) >= 0)
_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
}
else
{
_PadState.Axis.Tl = XInput::GetXI(0, _PadMapping.Axis.Tl - 1000);
_PadState.Axis.Tr = XInput::GetXI(0, _PadMapping.Axis.Tr - 1000);
_WiiMapping.AxisState.Tl = XInput::GetXI(0, _WiiMapping.AxisMapping.Tl - 1000);
_WiiMapping.AxisState.Tr = XInput::GetXI(0, _WiiMapping.AxisMapping.Tr - 1000);
}
#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

View File

@ -69,12 +69,9 @@ void HidOutputReport(u16 _channelID, wm_report* sr)
switch(sr->wm)
{
case WM_RUMBLE: // 0x10
{
// TODO: need more accurate rumble
const int Page = 0;
PAD_Rumble(Page, sr->data[0]);
PAD_Rumble(g_ID, sr->data[0]);
break;
}
case WM_LEDS: // 0x11
WmLeds(_channelID, (wm_leds*)sr->data);
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
// so that WmRequestStatus() knows about it
INFO_LOG(WIIMOTE, "WM IR Enable: 0x%02x", sr->data[0]);
if(sr->data[0] == 0x02) g_IR = 0;
else if(sr->data[0] == 0x06) g_IR = 1;
if(sr->data[0] == 0x02) g_IR[g_ID] = 0;
else if(sr->data[0] == 0x06) g_IR[g_ID] = 1;
break;
case WM_SPEAKER_ENABLE: // 0x14
@ -163,8 +160,7 @@ int WriteWmReportHdr(u8* dst, u8 wm)
void WmLeds(u16 _channelID, wm_leds* leds)
{
INFO_LOG(WIIMOTE, "Set LEDs: %x, Rumble: %x", leds->leds, leds->rumble);
g_Leds[g_RefreshWiimote] = leds->leds;
g_Leds[g_ID] = leds->leds;
}
@ -190,7 +186,7 @@ void WmSendAck(u16 _channelID, u8 _reportID)
DEBUG_LOG(WIIMOTE, "WMSendAck");
DEBUG_LOG(WIIMOTE, " Report ID: %02x", _reportID);
g_WiimoteInitialize.pWiimoteInput(g_RefreshWiimote, _channelID, DataFrame, Offset);
g_WiimoteInitialize.pWiimoteInput(g_ID, _channelID, DataFrame, Offset);
// Debugging
//ReadDebugging(true, DataFrame, Offset);
@ -233,7 +229,7 @@ void WmReadData(u16 _channelID, wm_read_data* rd)
DEBUG_LOG(WIIMOTE, " Case 0xa2: g_RegSpeaker");
break;
case 0xA4:
block = g_RegExt;
block = g_RegExt[g_ID];
blockSize = WIIMOTE_REG_EXT_SIZE;
DEBUG_LOG(WIIMOTE, " Case 0xa4: ExtReg");
break;
@ -264,11 +260,11 @@ void WmReadData(u16 _channelID, wm_read_data* rd)
if(((address >> 16) & 0xfe) == 0xa4)
{
// 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
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
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
// 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
_Size -= copySize;
@ -408,7 +404,7 @@ void WmWriteData(u16 _channelID, wm_write_data* wd)
DEBUG_LOG(WIIMOTE, " Case 0xa2: RegSpeaker");
break;
case 0xA4:
block = g_RegExt; // Extension Controller register
block = g_RegExt[g_ID]; // Extension Controller register
blockSize = WIIMOTE_REG_EXT_SIZE;
DEBUG_LOG(WIIMOTE, " Case 0xa4: ExtReg");
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
effect */
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
FillReportInfo(pStatus->buttons);
#endif
pStatus->leds = g_Leds[g_RefreshWiimote]; // leds are 4 bit
pStatus->ir = g_IR; // 1 bit
pStatus->leds = g_Leds[g_ID]; // leds are 4 bit
pStatus->ir = g_IR[g_ID]; // 1 bit
pStatus->speaker = g_Speaker; // 1 bit
pStatus->battery_low = 0; // battery is okay
pStatus->battery = 0x5f; // fully charged
@ -497,24 +493,18 @@ void WmRequestStatus(u16 _channelID, wm_request_status* rs, int Extension)
if (Extension == -1)
{
// Read config value for the first time
if(g_Config.iExtensionConnected == EXT_NONE)
pStatus->extension = 0;
else
pStatus->extension = 1;
pStatus->extension = (WiiMapping[g_ID].iExtensionConnected == EXT_NONE) ? 0 : 1;
}
else
{
if(Extension)
pStatus->extension = 1;
else
pStatus->extension = 0;
pStatus->extension = (Extension) ? 1 : 0;
}
INFO_LOG(WIIMOTE, "Request Status");
DEBUG_LOG(WIIMOTE, " Extension: %x", pStatus->extension);
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
//ReadDebugging(true, DataFrame, Offset);

View File

@ -37,7 +37,6 @@ extern SWiimoteInitialize g_WiimoteInitialize;
namespace WiiMoteEmu
{
// Recorded movements
// Variables: 0 = Wiimote, 1 = Nunchuck
int g_RecordingPlaying[3]; //g_RecordingPlaying[0] = -1; g_RecordingPlaying[1] = -1;
@ -134,8 +133,8 @@ bool RecordingPlayAccIR(u8 &_x, u8 &_y, u8 &_z, IRReportType &_IR, int Wm)
// Return if the IR mode is wrong
if (Wm == WM_RECORDING_IR
&& ( (IRBytes == 12 && !(g_ReportingMode == 0x33))
|| (IRBytes == 10 && !(g_ReportingMode == 0x36 || g_ReportingMode == 0x37))
&& ( (IRBytes == 12 && !(g_ReportingMode[g_ID] == 0x33))
|| (IRBytes == 10 && !(g_ReportingMode[g_ID] == 0x36 || g_ReportingMode[g_ID] == 0x37))
)
)
{
@ -203,6 +202,7 @@ bool RecordingPlayAccIR(u8 &_x, u8 &_y, u8 &_z, IRReportType &_IR, int Wm)
return true;
}
/* Because the playback is neatly controlled by RecordingPlayAccIR() we use these functions to be able to
use RecordingPlayAccIR() for both accelerometer and IR recordings */
bool RecordingPlay(u8 &_x, u8 &_y, u8 &_z, int Wm)
@ -210,6 +210,7 @@ bool RecordingPlay(u8 &_x, u8 &_y, u8 &_z, int Wm)
wm_ir_basic IR;
return RecordingPlayAccIR(_x, _y, _z, IR, Wm);
}
template<class IRReportType>
bool RecordingPlayIR(IRReportType &_IR)
{
@ -282,8 +283,6 @@ int RecordingCheckKeys(int WmNuIr)
}
}
// Return nothing if we don't have a match
if (!Match) return -1;
@ -295,80 +294,48 @@ int RecordingCheckKeys(int WmNuIr)
}
// Subroutines
int GetMapKeyState(int _MapKey, int Key)
// Multi System Input Status Check
bool IsKey(int Key)
{
if (g_Config.bInputActive)
{
const int Page = 0;
int Ret = NULL;
if (_MapKey < 256)
if (WiiMapping[g_ID].Source > 0)
{
int MapKey = WiiMapping[g_ID].Button[Key];
if (MapKey < 256)
{
#ifdef _WIN32
return GetAsyncKeyState(_MapKey); // Keyboard (Windows)
Ret = GetAsyncKeyState(MapKey); // Keyboard (Windows)
#else
return KeyStatus[Key]; // Keyboard (Linux)
Ret = KeyStatus[MapKey]; // Keyboard (Linux)
#endif
if (_MapKey < 0x1100)
return SDL_JoystickGetButton(PadState[Page].joy, _MapKey - 0x1000); // Pad button
}
else if (MapKey < 0x1100)
{
Ret = SDL_JoystickGetButton(WiiMapping[g_ID].joy, MapKey - 0x1000); // Pad button
}
else // Pad hat
{
u8 HatCode, HatKey;
HatCode = SDL_JoystickGetHat(PadState[Page].joy, (_MapKey - 0x1100) / 0x0010);
HatKey = (_MapKey - 0x1100) % 0x0010;
HatCode = SDL_JoystickGetHat(WiiMapping[g_ID].joy, (MapKey - 0x1100) / 0x0010);
HatKey = (MapKey - 0x1100) % 0x0010;
if (HatCode & HatKey)
return HatKey;
Ret = HatKey;
}
}
return NULL;
}
// Multi System Input Status Check
int IsKey(int Key)
{
if (Key == g_Wiimote_kbd.SHAKE)
{
#ifdef _WIN32
return GetMapKeyState(PadMapping[0].Wm.keyForControls[Key - g_Wiimote_kbd.A], Key) || GetAsyncKeyState(VK_MBUTTON);
#else
return GetMapKeyState(PadMapping[0].Wm.keyForControls[Key - g_Wiimote_kbd.A], Key);
if ((Key == EWM_SHAKE && GetAsyncKeyState(VK_MBUTTON))
|| (Key == EWM_A && GetAsyncKeyState(VK_LBUTTON))
|| (Key == EWM_B && GetAsyncKeyState(VK_RBUTTON)))
Ret = 1;
#endif
}
if (g_Wiimote_kbd.A <= Key && Key <= g_Wiimote_kbd.PITCH_D)
{
return GetMapKeyState(PadMapping[0].Wm.keyForControls[Key - g_Wiimote_kbd.A], Key);
}
if (g_NunchuckExt.Z <= Key && Key <= g_NunchuckExt.SHAKE)
{
return GetMapKeyState(PadMapping[0].Nc.keyForControls[Key - g_NunchuckExt.Z], Key);
}
if (g_ClassicContExt.A <= Key && Key <= g_ClassicContExt.Rd)
{
return GetMapKeyState(PadMapping[0].Cc.keyForControls[Key - g_ClassicContExt.A], Key);
}
if (g_GH3Ext.Green <= Key && Key <= g_GH3Ext.StrumDown)
{
return GetMapKeyState(PadMapping[0].GH3c.keyForControls[Key - g_GH3Ext.Green], Key);
}
#ifdef _WIN32
switch(Key)
{
// Wiimote
case g_Wiimote_kbd.MA:
return GetAsyncKeyState(VK_LBUTTON);
case g_Wiimote_kbd.MB:
return GetAsyncKeyState(VK_RBUTTON);
// This should not happen
default:
PanicAlert("There is syntax error in a function that is calling IsKey(%i)", Key);
return false;
}
#else
return KeyStatus[Key];
#endif
}
}
return (Ret) ? true : false;
}
// Wiimote core buttons
void FillReportInfo(wm_core& _core)
@ -376,352 +343,32 @@ void FillReportInfo(wm_core& _core)
// Check that Dolphin is in focus
if (!IsFocus()) return;
// Check the mouse position. Don't allow mouse clicks from outside the window.
float x, y; GetMousePos(x, y);
bool InsideScreen = !(x < 0 || x > 1 || y < 0 || y > 1);
// Allow both mouse buttons and keyboard to press a and b
if((IsKey(g_Wiimote_kbd.MA) && InsideScreen) || IsKey(g_Wiimote_kbd.A))
_core.a = 1;
if((IsKey(g_Wiimote_kbd.MB) && InsideScreen) || IsKey(g_Wiimote_kbd.B))
_core.b = 1;
_core.one = IsKey(g_Wiimote_kbd.ONE) ? 1 : 0;
_core.two = IsKey(g_Wiimote_kbd.TWO) ? 1 : 0;
_core.plus = IsKey(g_Wiimote_kbd.P) ? 1 : 0;
_core.minus = IsKey(g_Wiimote_kbd.M) ? 1 : 0;
_core.home = IsKey(g_Wiimote_kbd.H) ? 1 : 0;
_core.a = IsKey(EWM_A);
_core.b = IsKey(EWM_B);
_core.one = IsKey(EWM_ONE);
_core.two = IsKey(EWM_TWO);
_core.plus = IsKey(EWM_P);
_core.minus = IsKey(EWM_M);
_core.home = IsKey(EWM_H);
/* Sideways controls (for example for Wario Land) if the Wiimote is intended to be held sideways */
if(g_Config.bSideways)
if(WiiMapping[g_ID].bSideways)
{
_core.left = IsKey(g_Wiimote_kbd.D) ? 1 : 0;
_core.up = IsKey(g_Wiimote_kbd.L) ? 1 : 0;
_core.right = IsKey(g_Wiimote_kbd.U) ? 1 : 0;
_core.down = IsKey(g_Wiimote_kbd.R) ? 1 : 0;
_core.left = IsKey(EWM_D);
_core.up = IsKey(EWM_L);
_core.right = IsKey(EWM_U);
_core.down = IsKey(EWM_R);
}
else
{
_core.left = IsKey(g_Wiimote_kbd.L) ? 1 : 0;
_core.up = IsKey(g_Wiimote_kbd.U) ? 1 : 0;
_core.right = IsKey(g_Wiimote_kbd.R) ? 1 : 0;
_core.down = IsKey(g_Wiimote_kbd.D) ? 1 : 0;
_core.left = IsKey(EWM_L);
_core.up = IsKey(EWM_U);
_core.right = IsKey(EWM_R);
_core.down = IsKey(EWM_D);
}
}
// Wiimote accelerometer
/* The accelerometer x, y and z values range from 0x00 to 0xff with the default
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
all values are not 0x80, the mouse pointer can disappear from the screen
permanently then, until z is adjusted back. This is because the game detects
a steep pitch of the Wiimote then.
Wiimote Accelerometer Axes
+ (- -- X -- +)
| ___
| | |\ -
| | + || \
| . || \
Y |. .|| Z
| . || \
| | . || \
| |___|| +
- ---
*/
// 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;
// This has to be changed if multiple Wiimotes are to be supported later
const int Page = 0;
/* 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, Ly, Rx, Ry, Tl, Tr;
PadStateAdjustments(Lx, Ly, Rx, Ry, Tl, Tr);
// Save the Range in degrees, 45 and 90 are good values in some games
int &RollRange = g_Config.Tilt.Range.Roll;
int &PitchRange = g_Config.Tilt.Range.Pitch;
// The trigger currently only controls pitch, no roll, no free swing
if (Type == g_Config.Tilt.TRIGGER)
{
// Make the range the same dimension as the analog stick
Tl = Tl / 2;
Tr = Tr / 2;
// Invert
if (g_Config.Tilt.PitchInvert) { Tl = -Tl; Tr = -Tr; }
// The final value
_TiltData.Pitch = (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 == g_Config.Tilt.ANALOG1)
{
// Adjust the trigger to go between negative and positive values
Lx = Lx - 0x80;
Ly = Ly - 0x80;
// Invert
if (g_Config.Tilt.RollInvert) Lx = -Lx; // else Tr = -Tr;
if (g_Config.Tilt.PitchInvert) Ly = -Ly; // else Tr = -Tr;
// Produce the final value
_TiltData.Roll = (RollRange) ? (float)RollRange * ((float)Lx / 128.0f) : Lx;
_TiltData.Pitch = (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 (g_Config.Tilt.RollInvert) Rx = -Rx; // else Tr = -Tr;
if (g_Config.Tilt.PitchInvert) Ry = -Ry; // else Tr = -Tr;
// Produce the final value
_TiltData.Roll = (RollRange) ? (float)RollRange * ((float)Rx / 128.0f) : Rx;
_TiltData.Pitch = (PitchRange) ? (float)PitchRange * ((float)Ry / 128.0f) : Ry;
}
}
// Tilting Wiimote by keyboard
void TiltByKeyboardWM(STiltData &_TiltData)
{
// Do roll/pitch or free swing
if (IsKey(g_Wiimote_kbd.ROLL_L))
{
if (g_Config.Tilt.Range.Roll)
{
// Stop at the lower end of the range
if (_TiltData.Roll > -g_Config.Tilt.Range.Roll)
_TiltData.Roll -= 3; // aim left
}
else // Free swing
{
_TiltData.Roll = -0x80 / 2;
}
}
else if (IsKey(g_Wiimote_kbd.ROLL_R))
{
if (g_Config.Tilt.Range.Roll)
{
// Stop at the upper end of the range
if (_TiltData.Roll < g_Config.Tilt.Range.Roll)
_TiltData.Roll += 3; // aim right
}
else // Free swing
{
_TiltData.Roll = 0x80 / 2;
}
}
else
{
_TiltData.Roll = 0;
}
if (IsKey(g_Wiimote_kbd.PITCH_U))
{
if (g_Config.Tilt.Range.Pitch)
{
// Stop at the lower end of the range
if (_TiltData.Pitch > -g_Config.Tilt.Range.Pitch)
_TiltData.Pitch -= 3; // aim down
}
else // Free swing
{
_TiltData.Pitch = -0x80 / 2;
}
}
else if (IsKey(g_Wiimote_kbd.PITCH_D))
{
if (g_Config.Tilt.Range.Pitch)
{
// Stop at the upper end of the range
if (_TiltData.Pitch < g_Config.Tilt.Range.Pitch)
_TiltData.Pitch += 3; // aim up
}
else // Free swing
{
_TiltData.Pitch = 0x80 / 2;
}
}
else
{
_TiltData.Pitch = 0;
}
}
// Tilting Nunchuck by keyboard
void TiltByKeyboardNC(STiltData &_TiltData)
{
// Do roll/pitch or free swing
if (IsKey(g_NunchuckExt.ROLL_L))
{
if (g_Config.Tilt.Range.Roll)
{
// Stop at the lower end of the range
if (_TiltData.Roll > -g_Config.Tilt.Range.Roll)
_TiltData.Roll -= 3; // aim left
}
else // Free swing
{
_TiltData.Roll = -0x80 / 2;
}
}
else if (IsKey(g_NunchuckExt.ROLL_R))
{
if (g_Config.Tilt.Range.Roll)
{
// Stop at the upper end of the range
if (_TiltData.Roll < g_Config.Tilt.Range.Roll)
_TiltData.Roll += 3; // aim right
}
else // Free swing
{
_TiltData.Roll = 0x80 / 2;
}
}
else
{
_TiltData.Roll = 0;
}
if (IsKey(g_NunchuckExt.PITCH_U))
{
if (g_Config.Tilt.Range.Pitch)
{
// Stop at the lower end of the range
if (_TiltData.Pitch > -g_Config.Tilt.Range.Pitch)
_TiltData.Pitch -= 3; // aim up
}
else // Free swing
{
_TiltData.Pitch = -0x80 / 2;
}
}
else if (IsKey(g_NunchuckExt.PITCH_D))
{
if (g_Config.Tilt.Range.Pitch)
{
// Stop at the upper end of the range
if (_TiltData.Pitch < g_Config.Tilt.Range.Pitch)
_TiltData.Pitch += 3; // aim down
}
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)
{
// Check if it's on
if (g_Config.Tilt.TypeWM == g_Config.Tilt.OFF)
return;
// Select input method and return the x, y, x values
else if (g_Config.Tilt.TypeWM == g_Config.Tilt.KEYBOARD)
TiltByKeyboardWM(g_WiimoteData[g_RefreshWiimote].TiltWM);
else
TiltByGamepad(g_WiimoteData[g_RefreshWiimote].TiltWM, g_Config.Tilt.TypeWM);
// Adjust angles, it's only needed if both roll and pitch is used together
if (g_Config.Tilt.Range.Roll != 0 && g_Config.Tilt.Range.Pitch != 0)
AdjustAngles(g_WiimoteData[g_RefreshWiimote].TiltWM.Roll, g_WiimoteData[g_RefreshWiimote].TiltWM.Pitch);
// Calculate the accelerometer value from this tilt angle
TiltToAccelerometer(_x, _y, _z, g_WiimoteData[g_RefreshWiimote].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)
{
// Check if it's on
if (g_Config.Tilt.TypeNC == g_Config.Tilt.OFF)
return;
// Select input method and return the x, y, x values
else if (g_Config.Tilt.TypeNC == g_Config.Tilt.KEYBOARD)
TiltByKeyboardNC(g_WiimoteData[g_RefreshWiimote].TiltNC);
else
TiltByGamepad(g_WiimoteData[g_RefreshWiimote].TiltNC, g_Config.Tilt.TypeNC);
// Adjust angles, it's only needed if both roll and pitch is used together
if (g_Config.Tilt.Range.Roll != 0 && g_Config.Tilt.Range.Pitch != 0)
AdjustAngles(g_WiimoteData[g_RefreshWiimote].TiltNC.Roll, g_WiimoteData[g_RefreshWiimote].TiltNC.Pitch);
// Calculate the accelerometer value from this tilt angle
TiltToAccelerometer(_x, _y, _z, g_WiimoteData[g_RefreshWiimote].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);
}
void FillReportAcc(wm_accel& _acc)
{
// Recorded movements
@ -744,12 +391,12 @@ void FillReportAcc(wm_accel& _acc)
_acc.z = g_wm.cal_zero.z;
// Adjust position, also add some noise to prevent disconnection
if (!g_Config.bUpright)
_acc.z += g_wm.cal_g.z + g_WiimoteData[g_RefreshWiimote].TiltWM.FakeNoise;
if (!WiiMapping[g_ID].bUpright)
_acc.z += g_wm.cal_g.z + WiiMapping[g_ID].Motion.TiltWM.FakeNoise;
else // Upright wiimote
_acc.y -= g_wm.cal_g.y + g_WiimoteData[g_RefreshWiimote].TiltWM.FakeNoise;
_acc.y -= g_wm.cal_g.y + WiiMapping[g_ID].Motion.TiltWM.FakeNoise;
g_WiimoteData[g_RefreshWiimote].TiltWM.FakeNoise = -g_WiimoteData[g_RefreshWiimote].TiltWM.FakeNoise;
WiiMapping[g_ID].Motion.TiltWM.FakeNoise = -WiiMapping[g_ID].Motion.TiltWM.FakeNoise;
if (IsFocus())
{
@ -757,14 +404,14 @@ void FillReportAcc(wm_accel& _acc)
int acc_y = _acc.y;
int acc_z = _acc.z;
if (IsKey(g_Wiimote_kbd.SHAKE) && g_WiimoteData[g_RefreshWiimote].TiltWM.Shake == 0)
g_WiimoteData[g_RefreshWiimote].TiltWM.Shake = 1;
if (IsKey(EWM_SHAKE) && !WiiMapping[g_ID].Motion.TiltWM.Shake)
WiiMapping[g_ID].Motion.TiltWM.Shake = 1;
// Step the shake simulation one step
ShakeToAccelerometer(acc_x, acc_y, acc_z, g_WiimoteData[g_RefreshWiimote].TiltWM);
ShakeToAccelerometer(acc_x, acc_y, acc_z, WiiMapping[g_ID].Motion.TiltWM);
// Tilt Wiimote, allow the shake function to interrupt it
if (g_WiimoteData[g_RefreshWiimote].TiltWM.Shake == 0)
if (!WiiMapping[g_ID].Motion.TiltWM.Shake)
TiltWiimote(acc_x, acc_y, acc_z);
// Boundary check
@ -855,32 +502,6 @@ void FillReportAcc(wm_accel& _acc)
);*/
}
// Rotate IR dot when rolling Wiimote
void RotateIRDot(int &_x, int &_y, STiltData &_TiltData)
{
if (g_Config.Tilt.Range.Roll == 0 || _TiltData.Roll == 0)
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 = radius * cos(radian + InputCommon::Deg2Rad((float)_TiltData.Roll)) + 1023.0f / 2;
_y = 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;
}
/*
int Top = TOP, Left = LEFT, Right = RIGHT,
Bottom = BOTTOM, SensorBarRadius = SENSOR_BAR_RADIUS;
*/
// The extended 12 byte (3 byte per object) reporting
void FillReportIR(wm_ir_extended& _ir0, wm_ir_extended& _ir1)
{
@ -916,8 +537,8 @@ void FillReportIR(wm_ir_extended& _ir0, wm_ir_extended& _ir1)
int x0 = 1023 - g_Config.iIRLeft - g_Config.iIRWidth * MouseX - SENSOR_BAR_WIDTH / 2;
int x1 = x0 + SENSOR_BAR_WIDTH;
RotateIRDot(x0, y0, g_WiimoteData[g_RefreshWiimote].TiltWM);
RotateIRDot(x1, y1, g_WiimoteData[g_RefreshWiimote].TiltWM);
RotateIRDot(x0, y0, WiiMapping[g_ID].Motion.TiltWM);
RotateIRDot(x1, y1, WiiMapping[g_ID].Motion.TiltWM);
// Converted to IR data
_ir0.x = x0 & 0xff; _ir0.xHi = x0 >> 8;
@ -963,7 +584,6 @@ void FillReportIR(wm_ir_extended& _ir0, wm_ir_extended& _ir1)
// The 10 byte reporting used when an extension is connected
void FillReportIRBasic(wm_ir_basic& _ir0, wm_ir_basic& _ir1)
{
// Recorded movements
// Check for a playback command
if(g_RecordingPlaying[2] < 0)
@ -993,8 +613,8 @@ void FillReportIRBasic(wm_ir_basic& _ir0, wm_ir_basic& _ir1)
int x1 = 1023 - g_Config.iIRLeft - g_Config.iIRWidth * MouseX - SENSOR_BAR_WIDTH / 2;
int x2 = x1 + SENSOR_BAR_WIDTH;
RotateIRDot(x1, y1, g_WiimoteData[g_RefreshWiimote].TiltWM);
RotateIRDot(x2, y2, g_WiimoteData[g_RefreshWiimote].TiltWM);
RotateIRDot(x1, y1, WiiMapping[g_ID].Motion.TiltWM);
RotateIRDot(x2, y2, WiiMapping[g_ID].Motion.TiltWM);
/* As with the extented report we settle with emulating two out of four
possible objects the only difference is that we don't report any size of
@ -1046,9 +666,6 @@ void FillReportIRBasic(wm_ir_basic& _ir0, wm_ir_basic& _ir1)
}
// Extensions
/* Generate the 6 byte extension report for the Nunchuck, encrypted. The bytes
are JX JY AX AY AZ BT. */
void FillReportExtension(wm_extension& _ext)
@ -1076,20 +693,20 @@ void FillReportExtension(wm_extension& _ext)
_ext.ay = g_nu.cal_zero.y;
_ext.az = g_nu.cal_zero.z + g_nu.cal_g.z;
if (IsFocus())
{
if (IsFocus())
{
int acc_x = _ext.ax;
int acc_y = _ext.ay;
int acc_z = _ext.az;
if (IsKey(g_NunchuckExt.SHAKE) && g_WiimoteData[g_RefreshWiimote].TiltNC.Shake == 0)
g_WiimoteData[g_RefreshWiimote].TiltNC.Shake = 1;
if (IsKey(ENC_SHAKE) && !WiiMapping[g_ID].Motion.TiltNC.Shake)
WiiMapping[g_ID].Motion.TiltNC.Shake = 1;
// Step the shake simulation one step
ShakeToAccelerometer(acc_x, acc_y, acc_z, g_WiimoteData[g_RefreshWiimote].TiltNC);
ShakeToAccelerometer(acc_x, acc_y, acc_z, WiiMapping[g_ID].Motion.TiltNC);
// Tilt Nunchuck, allow the shake function to interrupt it
if (g_WiimoteData[g_RefreshWiimote].TiltNC.Shake == 0)
if (!WiiMapping[g_ID].Motion.TiltNC.Shake)
TiltNunchuck(acc_x, acc_y, acc_z);
// Boundary check
@ -1105,17 +722,17 @@ if (IsFocus())
_ext.az = acc_z;
// Update the analog stick
if (g_Config.Nunchuck.Type == g_Config.Nunchuck.KEYBOARD)
if (WiiMapping[g_ID].Stick.NC == FROM_KEYBOARD)
{
// Set the max values to the current calibration values
if(IsKey(g_NunchuckExt.L)) // x
if(IsKey(ENC_L)) // x
_ext.jx = g_nu.jx.min;
if(IsKey(g_NunchuckExt.R))
if(IsKey(ENC_R))
_ext.jx = g_nu.jx.max;
if(IsKey(g_NunchuckExt.D)) // y
if(IsKey(ENC_D)) // y
_ext.jy = g_nu.jy.min;
if(IsKey(g_NunchuckExt.U))
if(IsKey(ENC_U))
_ext.jy = g_nu.jy.max;
// On a real stick, the initialization value of center is 0x80,
@ -1128,8 +745,11 @@ if (IsFocus())
else
{
// Get adjusted pad state values
int _Lx, _Ly, _Rx, _Ry, _Tl, _Tr;
PadStateAdjustments(_Lx, _Ly, _Rx, _Ry, _Tl, _Tr);
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;
// The Y-axis is inverted
_Ly = 0xff - _Ly;
_Ry = 0xff - _Ry;
@ -1170,7 +790,7 @@ if (IsFocus())
if (_Ry > 0xff) _Ry = 0xff; if (_Ry < 0) _Ry = 0;
}
if (g_Config.Nunchuck.Type == g_Config.Nunchuck.ANALOG1)
if (WiiMapping[g_ID].Stick.NC == FROM_ANALOG1)
{
_ext.jx = _Lx;
_ext.jy = _Ly;
@ -1182,14 +802,9 @@ if (IsFocus())
}
}
if(IsKey(g_NunchuckExt.C))
_ext.bt = 0x01;
if(IsKey(g_NunchuckExt.Z))
_ext.bt = 0x02;
if(IsKey(g_NunchuckExt.C) && IsKey(g_NunchuckExt.Z))
_ext.bt = 0x00;
}
if(IsKey(ENC_C)) _ext.bt &= ~0x02;
if(IsKey(ENC_Z)) _ext.bt &= ~0x01;
}
/* Here we encrypt the report */
@ -1254,15 +869,15 @@ void FillReportClassicExtension(wm_classic_extension& _ext)
*/
// Update the left analog stick
if (g_Config.ClassicController.LType == g_Config.ClassicController.KEYBOARD)
if (WiiMapping[g_ID].Stick.CCL == FROM_KEYBOARD)
{
if(IsKey(g_ClassicContExt.Ll)) // Left analog left
if(IsKey(ECC_Ll)) // Left analog left
Lx = g_ClassicContCalibration.Lx.min;
if(IsKey(g_ClassicContExt.Lu)) // up
Ly = g_ClassicContCalibration.Ly.max;
if(IsKey(g_ClassicContExt.Lr)) // right
if(IsKey(ECC_Lr)) // right
Lx = g_ClassicContCalibration.Lx.max;
if(IsKey(g_ClassicContExt.Ld)) // down
if(IsKey(ECC_Lu)) // up
Ly = g_ClassicContCalibration.Ly.max;
if(IsKey(ECC_Ld)) // down
Ly = g_ClassicContCalibration.Ly.min;
// On a real stick, the initialization value of center is 0x80,
@ -1275,8 +890,11 @@ void FillReportClassicExtension(wm_classic_extension& _ext)
else
{
// Get adjusted pad state values
int _Lx, _Ly, _Rx, _Ry, _Tl, _Tr;
PadStateAdjustments(_Lx, _Ly, _Rx, _Ry, _Tl, _Tr);
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;
// The Y-axis is inverted
_Ly = 0xff - _Ly;
_Ry = 0xff - _Ry;
@ -1290,7 +908,7 @@ void FillReportClassicExtension(wm_classic_extension& _ext)
with the real Classic Controller
*/
if (g_Config.ClassicController.LType == g_Config.ClassicController.ANALOG1)
if (WiiMapping[g_ID].Stick.CCL == FROM_ANALOG1)
{
Lx = _Lx;
Ly = _Ly;
@ -1303,15 +921,15 @@ void FillReportClassicExtension(wm_classic_extension& _ext)
}
// Update the right analog stick
if (g_Config.ClassicController.RType == g_Config.ClassicController.KEYBOARD)
if (WiiMapping[g_ID].Stick.CCR == FROM_KEYBOARD)
{
if(IsKey(g_ClassicContExt.Rl)) // Right analog left
if(IsKey(ECC_Rl)) // Right analog left
Rx = g_ClassicContCalibration.Rx.min;
if(IsKey(g_ClassicContExt.Ru)) // up
Ry = g_ClassicContCalibration.Ry.max;
if(IsKey(g_ClassicContExt.Rr)) // right
if(IsKey(ECC_Rr)) // right
Rx = g_ClassicContCalibration.Rx.max;
if(IsKey(g_ClassicContExt.Rd)) // down
if(IsKey(ECC_Ru)) // up
Ry = g_ClassicContCalibration.Ry.max;
if(IsKey(ECC_Rd)) // down
Ry = g_ClassicContCalibration.Ry.min;
// On a real stick, the initialization value of center is 0x80,
@ -1324,8 +942,11 @@ void FillReportClassicExtension(wm_classic_extension& _ext)
else
{
// Get adjusted pad state values
int _Lx, _Ly, _Rx, _Ry, _Tl, _Tr;
PadStateAdjustments(_Lx, _Ly, _Rx, _Ry, _Tl, _Tr);
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;
// The Y-axis is inverted
_Ly = 0xff - _Ly;
_Ry = 0xff - _Ry;
@ -1339,7 +960,7 @@ void FillReportClassicExtension(wm_classic_extension& _ext)
with the real Classic Controller
*/
if (g_Config.ClassicController.RType == g_Config.ClassicController.ANALOG1)
if (WiiMapping[g_ID].Stick.CCR == FROM_ANALOG1)
{
Rx = _Lx;
Ry = _Ly;
@ -1352,18 +973,18 @@ void FillReportClassicExtension(wm_classic_extension& _ext)
}
// Update the left and right analog triggers
if (g_Config.ClassicController.TType == g_Config.ClassicController.KEYBOARD)
if (WiiMapping[g_ID].Stick.CCT == FROM_KEYBOARD)
{
if(IsKey(g_ClassicContExt.Tl)) // analog left trigger
if(IsKey(ECC_Tl)) // analog left trigger
{ _ext.b1.bLT = 0x00; lT = 0x1f; }
if(IsKey(g_ClassicContExt.Tr)) // analog right trigger
if(IsKey(ECC_Tr)) // analog right trigger
{ _ext.b1.bRT = 0x00; rT = 0x1f; }
}
else // g_Config.ClassicController.TRIGGER
{
// Get adjusted pad state values
int _Lx, _Ly, _Rx, _Ry, _Tl, _Tr;
PadStateAdjustments(_Lx, _Ly, _Rx, _Ry, _Tl, _Tr);
int _Tl = WiiMapping[g_ID].AxisState.Tl;
int _Tr = WiiMapping[g_ID].AxisState.Tr;
/* This is if we are also using a real Classic Controller that we
are sharing the calibration with. It's not needed if we are
@ -1385,8 +1006,6 @@ void FillReportClassicExtension(wm_classic_extension& _ext)
rT = _Tr;
}
/* D-Pad
u8 b1;
@ -1398,10 +1017,10 @@ void FillReportClassicExtension(wm_classic_extension& _ext)
0: bdU
1: bdL
*/
if(IsKey(g_ClassicContExt.Dl)) _ext.b2.bdL = 0x00; // Digital left
if(IsKey(g_ClassicContExt.Du)) _ext.b2.bdU = 0x00; // Up
if(IsKey(g_ClassicContExt.Dr)) _ext.b1.bdR = 0x00; // Right
if(IsKey(g_ClassicContExt.Dd)) _ext.b1.bdD = 0x00; // Down
if(IsKey(ECC_Dl)) _ext.b2.bdL = 0x00; // Digital left
if(IsKey(ECC_Du)) _ext.b2.bdU = 0x00; // Up
if(IsKey(ECC_Dr)) _ext.b1.bdR = 0x00; // Right
if(IsKey(ECC_Dd)) _ext.b1.bdD = 0x00; // Down
/* Buttons
u8 b1;
@ -1419,32 +1038,15 @@ void FillReportClassicExtension(wm_classic_extension& _ext)
6: bB
7: bZl
*/
if(IsKey(g_ClassicContExt.A))
_ext.b2.bA = 0x00;
if(IsKey(g_ClassicContExt.B))
_ext.b2.bB = 0x00;
if(IsKey(g_ClassicContExt.Y))
_ext.b2.bY = 0x00;
if(IsKey(g_ClassicContExt.X))
_ext.b2.bX = 0x00;
if(IsKey(g_ClassicContExt.P))
_ext.b1.bP = 0x00;
if(IsKey(g_ClassicContExt.M))
_ext.b1.bM = 0x00;
if(IsKey(g_ClassicContExt.H))
_ext.b1.bH = 0x00;
if(IsKey(g_ClassicContExt.Zl))
_ext.b2.bZL = 0x00;
if(IsKey(g_ClassicContExt.Zr))
_ext.b2.bZR = 0x00;
if(IsKey(ECC_A)) _ext.b2.bA = 0x00;
if(IsKey(ECC_B)) _ext.b2.bB = 0x00;
if(IsKey(ECC_Y)) _ext.b2.bY = 0x00;
if(IsKey(ECC_X)) _ext.b2.bX = 0x00;
if(IsKey(ECC_P)) _ext.b1.bP = 0x00;
if(IsKey(ECC_M)) _ext.b1.bM = 0x00;
if(IsKey(ECC_H)) _ext.b1.bH = 0x00;
if(IsKey(ECC_Zl)) _ext.b2.bZL = 0x00;
if(IsKey(ECC_Zr)) _ext.b2.bZR = 0x00;
// All buttons pressed
//if(GetAsyncKeyState('C') && GetAsyncKeyState('Z'))
@ -1461,7 +1063,6 @@ void FillReportClassicExtension(wm_classic_extension& _ext)
// 5 bit to the next 2 bit
_ext.Rx3 = ((Rx >> 3) >> 3) & 0x03;
_ext.Ry = (Ry >> 3);
// 5 bit to 3 bit
_ext.lT = (lT >> 3) & 0x07;
// 5 bit to the highest two bits
@ -1469,7 +1070,6 @@ void FillReportClassicExtension(wm_classic_extension& _ext)
_ext.rT = (rT >> 3);
/* Here we encrypt the report */
// Create a temporary storage for the data
u8 Tmp[sizeof(_ext)];
// Clear the array by copying zeroes to it
@ -1484,13 +1084,11 @@ void FillReportClassicExtension(wm_classic_extension& _ext)
/* Generate the 6 byte extension report for the GH3 Controller, encrypted.
The bytes are ... */
void FillReportGuitarHero3Extension(wm_GH3_extension& _ext)
{
// u8 TB : 5; // not used in GH3
// u8 WB : 5;
u8 SX = g_GH3Calibration.Lx.center,
SY = g_GH3Calibration.Ly.center;
u8 SX = g_GH3Calibration.Lx.center, SY = g_GH3Calibration.Ly.center;
_ext.pad1 = 3;
_ext.pad2 = 3;
@ -1512,38 +1110,34 @@ void FillReportGuitarHero3Extension(wm_GH3_extension& _ext)
_ext.Red = 1;
_ext.Orange = 1;
// Check that Dolphin is in focus
if (IsFocus())
{
// Update the left analog stick
// TODO: Fix using the keyboard for the joystick
// only seems to work if there is a PanicAlert after setting the value
/* if (g_Config.GH3Controller.AType == g_Config.GH3Controller.KEYBOARD)
if (WiiMapping[g_ID].Stick.GH == FROM_KEYBOARD)
{
if(IsKey(g_GH3Ext.Al)) // Left analog left
if(IsKey(EGH_Al)) // Left analog left
_ext.SX = g_GH3Calibration.Lx.min;
if(IsKey(g_GH3Ext.Au)) // up
_ext.SY = g_GH3Calibration.Ly.max;
if(IsKey(g_GH3Ext.Ar)) // right
if(IsKey(EGH_Ar)) // right
_ext.SX = g_GH3Calibration.Lx.max;
if(IsKey(g_GH3Ext.Ad)) // down
if(IsKey(EGH_Au)) // up
_ext.SY = g_GH3Calibration.Ly.max;
if(IsKey(EGH_Ad)) // down
_ext.SY = g_GH3Calibration.Ly.min;
}
else
*/ {
{
// Get adjusted pad state values
int _Lx, _Ly, _Rx, _Ry,
_Tl, _Tr; // Not used
PadStateAdjustments(_Lx, _Ly, _Rx, _Ry, _Tl, _Tr);
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;
// The Y-axis is inverted
_Ly = 0xff - _Ly;
_Ry = 0xff - _Ry;
if (g_Config.GH3Controller.AType == g_Config.GH3Controller.ANALOG1)
if (WiiMapping[g_ID].Stick.GH == FROM_ANALOG1)
{
SX = _Lx;
SY = _Ly;
@ -1555,24 +1149,15 @@ void FillReportGuitarHero3Extension(wm_GH3_extension& _ext)
}
}
if(IsKey(g_GH3Ext.StrumUp)) _ext.StrumUp = 0; // Strum Up
if(IsKey(g_GH3Ext.StrumDown)) _ext.StrumDown= 0; // Strum Down
if(IsKey(g_GH3Ext.Plus))
_ext.Plus = 0;
if(IsKey(g_GH3Ext.Minus))
_ext.Minus = 0;
if(IsKey(g_GH3Ext.Yellow))
_ext.Yellow = 0;
if(IsKey(g_GH3Ext.Green))
_ext.Green = 0;
if(IsKey(g_GH3Ext.Blue))
_ext.Blue = 0;
if(IsKey(g_GH3Ext.Red))
_ext.Red = 0;
if(IsKey(g_GH3Ext.Orange))
_ext.Orange = 0;
if(IsKey(EGH_Yellow)) _ext.Yellow = 0;
if(IsKey(EGH_Green)) _ext.Green = 0;
if(IsKey(EGH_Blue)) _ext.Blue = 0;
if(IsKey(EGH_Red)) _ext.Red = 0;
if(IsKey(EGH_Orange)) _ext.Orange = 0;
if(IsKey(EGH_Plus)) _ext.Plus = 0;
if(IsKey(EGH_Minus)) _ext.Minus = 0;
if(IsKey(EGH_StrumUp)) _ext.StrumUp = 0; // Strum Up
if(IsKey(EGH_StrumDown)) _ext.StrumDown= 0; // Strum Down
}
// Convert data for reporting
@ -1580,7 +1165,6 @@ void FillReportGuitarHero3Extension(wm_GH3_extension& _ext)
_ext.SY = (SY >> 2);
/* Here we encrypt the report */
// Create a temporary storage for the data
u8 Tmp[sizeof(_ext)];
// Clear the array by copying zeroes to it
@ -1591,7 +1175,6 @@ void FillReportGuitarHero3Extension(wm_GH3_extension& _ext)
wiimote_encrypt(&g_ExtKey, Tmp, 0x00, sizeof(_ext));
// Write it back to the struct
memcpy(&_ext, Tmp, sizeof(_ext));
}
} // end of namespace

View File

@ -325,7 +325,7 @@ void ReadWiimote()
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));
DEBUG_LOG(WIIMOTE, "EEPROM: %s", Temp.c_str());
WiiMoteEmu::UpdateEeprom();
WiiMoteEmu::InitCalibration();
g_RunTemporary = false;
}
break;

View File

@ -72,7 +72,7 @@ void SetDeviceForcesXY(int pad, int nXYForce);
HRESULT InitRumble(HWND hWnd);
LPDIRECTINPUT8 g_Rumble; // DInput Rumble object
RUMBLE pRumble[4]; // 4 GC Rumble Pads
RUMBLE pRumble[MAX_WIIMOTES];
//////////////////////
// Use PAD rumble
@ -80,7 +80,7 @@ RUMBLE pRumble[4]; // 4 GC Rumble Pads
void Pad_Use_Rumble(u8 _numPAD)
{
if (PadMapping[_numPAD].Rumble)
if (WiiMapping[_numPAD].Rumble)
{
if (!g_Rumble)
{
@ -106,12 +106,12 @@ void PAD_Rumble(u8 _numPAD, unsigned int _uType)
int Strenght = 0;
if (PadMapping[_numPAD].Rumble) // rumble activated
if (WiiMapping[_numPAD].Rumble) // rumble activated
{
if (_uType == 1)
{
// 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;
}
else
@ -138,10 +138,10 @@ HRESULT InitRumble(HWND hWnd)
if (FAILED(hr = g_Rumble->EnumDevices( DI8DEVCLASS_GAMECTRL, EnumFFDevicesCallback, NULL, DIEDFL_ATTACHEDONLY | DIEDFL_FORCEFEEDBACK)))
return hr;
for (int i=0; i<4; i++)
for (int i = 0; i < MAX_WIIMOTES; i++)
{
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
{
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);
PadMapping[i].Rumble = false; // Disable Rumble for this pad
WiiMapping[i].Rumble = false; // Disable Rumble for this pad
continue; // Next pad
}
@ -268,15 +268,15 @@ BOOL CALLBACK EnumFFDevicesCallback(const DIDEVICEINSTANCE* pInst, VOID* pContex
else
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++)
{
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
// 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
}
}
@ -298,7 +298,7 @@ void PAD_RumbleClose()
// 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
// 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)
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
pRumble[_numPAD].g_pDevice = 0;
PadMapping[_numPAD].Rumble = false;
WiiMapping[_numPAD].Rumble = false;
return false;
}
@ -369,7 +369,7 @@ void PAD_Rumble(u8 _numPAD, unsigned int _uType)
int Strenght = 0;
#ifdef SDL_RUMBLE
if (PadMapping[_numPAD].Rumble) // rumble activated
if (WiiMapping[_numPAD].Rumble) // rumble activated
{
if (!pRumble[_numPAD].g_pDevice)
return;

View File

@ -16,22 +16,6 @@
// 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 "LogManager.h"
#include "StringUtil.h"
@ -80,8 +64,8 @@ gh3_cal g_GH3Calibration;
// Debugging
bool g_DebugAccelerometer = false;
bool g_DebugData = false;
bool g_DebugComm = true;
bool g_DebugSoundData = true;
bool g_DebugComm = false;
bool g_DebugSoundData = false;
bool g_DebugCustom = false;
// Update speed
@ -184,12 +168,12 @@ void DllDebugger(HWND _hParent, bool Show) {}
void DllConfig(HWND _hParent)
{
// We do a pad search before creating the dialog
WiiMoteEmu::Search_Devices(WiiMoteEmu::joyinfo, WiiMoteEmu::NumPads, WiiMoteEmu::NumGoodPads);
// Load settings
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 (!m_BasicConfigFrame)
@ -198,9 +182,15 @@ void DllConfig(HWND _hParent)
m_BasicConfigFrame->Close(true);
// Only allow one open at a time
if (!m_BasicConfigFrame->IsShown())
{
g_FrameOpen = true;
m_BasicConfigFrame->ShowModal();
}
else
{
g_FrameOpen = false;
m_BasicConfigFrame->Hide();
}
#endif
}
@ -208,11 +198,8 @@ void DllConfig(HWND _hParent)
// Start emulation
void Initialize(void *init)
{
// Declarations
SWiimoteInitialize _WiimoteInitialize = *(SWiimoteInitialize *)init;
g_WiimoteInitialize = _WiimoteInitialize;
g_EmulatorRunning = true;
g_WiimoteInitialize = *(SWiimoteInitialize *)init;
// Update the GUI if the configuration window is already open
#if defined(HAVE_WX) && HAVE_WX
@ -220,7 +207,7 @@ void Initialize(void *init)
{
// Save the settings
g_Config.Save();
// Save the ISO Id
// Load the ISO Id
g_ISOId = g_WiimoteInitialize.ISOId;
// Load the settings
g_Config.Load();
@ -228,15 +215,25 @@ void Initialize(void *init)
}
#endif
#if defined(HAVE_X11) && HAVE_X11
WMdisplay = (Display*)_WiimoteInitialize.hWnd;
WMdisplay = (Display*)g_WiimoteInitialize.hWnd;
#endif
// Save the ISO Id, again if we had a window open
g_ISOId = g_WiimoteInitialize.ISOId;
DoInitialize();
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
@ -254,13 +251,6 @@ void Shutdown(void)
#if defined(HAVE_WX) && HAVE_WX
if(m_BasicConfigFrame) m_BasicConfigFrame->UpdateGUI();
#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
@ -278,10 +268,10 @@ void DoState(unsigned char **ptr, int mode)
//p.Do(g_EmulatorRunning);
//p.Do(g_ISOId);
p.Do(g_FrameOpen);
p.Do(g_RealWiiMotePresent);
p.Do(g_RealWiiMoteInitialized);
p.Do(g_EmulatedWiiMoteInitialized);
//p.Do(g_FrameOpen);
//p.Do(g_RealWiiMotePresent);
//p.Do(g_RealWiiMoteInitialized);
//p.Do(g_EmulatedWiiMoteInitialized);
//p.Do(g_UpdateCounter);
//p.Do(g_UpdateTime);
//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)
{
const u8* data = (const u8*)_pData;
// Debugging
{
#if defined(_DEBUG) || defined(DEBUGFAST)
DEBUG_LOG(WIIMOTE, "Wiimote_InterruptChannel");
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());
}
#endif
// Decice where to send the message
if (!g_Config.bUseRealWiimote || !g_RealWiiMotePresent)
if (WiiMoteEmu::WiiMapping[_number].Source >= 0)
WiiMoteEmu::InterruptChannel(_number, _channelID, _pData, _Size);
#if HAVE_WIIUSE
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.
void Wiimote_ControlChannel(int _number, u16 _channelID, const void* _pData, u32 _Size)
{
// Debugging
#if defined(_DEBUG) || defined(DEBUGFAST)
DEBUG_LOG(WIIMOTE, "Wiimote_ControlChannel");
DEBUG_LOG(WIIMOTE, " Channel ID: %04x", _channelID);
std::string Temp = ArrayToString((const u8*)_pData, _Size);
DEBUG_LOG(WIIMOTE, " Data: %s", Temp.c_str());
#endif
if (!g_Config.bUseRealWiimote || !g_RealWiiMotePresent)
if (WiiMoteEmu::WiiMapping[_number].Source >= 0)
WiiMoteEmu::ControlChannel(_number, _channelID, _pData, _Size);
#if HAVE_WIIUSE
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
update. */
// This sends a Data Report from the Wiimote. See SystemTimers.cpp for the documentation of this update.
void Wiimote_Update(int _number)
{
// 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:
// Emulated Wiimote: Only data reports 0x30-0x37
// 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);
#if HAVE_WIIUSE
else if (g_RealWiiMotePresent)
WiiMoteReal::Update(); // TODO: Multi-Wiimote
#endif
/*
// Debugging
#ifdef _WIN32
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
else if (GetAsyncKeyState(VK_END) && !g_DebugCustom ) {g_DebugCustom = true; DEBUG_LOG(WIIMOTE, "Custom Debug: Off");}
#endif
*/
}
unsigned int Wiimote_GetAttachedControllers()
@ -398,8 +388,6 @@ unsigned int Wiimote_GetAttachedControllers()
// Supporting functions
// Check if Dolphin is in focus
bool IsFocus()
@ -422,13 +410,55 @@ bool IsFocus()
#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
void DisableExtensions()
{
g_Config.iExtensionConnected = EXT_NONE;
}
/*
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]);
}
}
*/
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);
//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", Tm(true).c_str(), Temp.c_str()); // Timestamp
DEBUG_LOG(WIIMOTE, "%s: %s", Name.c_str(), Temp.c_str());
//DEBUG_LOG(WIIMOTE, " (%s): %s", Tm(true).c_str(), Temp.c_str());
}
if (g_DebugSoundData && SoundData)
{
std::string Temp = ArrayToString(data, size + 2, 0, 30);
//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", Tm(true).c_str(), Temp.c_str()); // Timestamp
DEBUG_LOG(WIIMOTE, "%s: %s", Name.c_str(), Temp.c_str());
//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;
#endif
// 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();
int GetUpdateRate();
//void InterruptDebugging(bool Emu, const void* _pData);
//void ReadDebugging(bool Emu, const void* _pData, int Size);
// Movement recording
#define RECORDING_ROWS 15

View File

@ -25,7 +25,7 @@
#endif
#pragma pack(push, 1)
#define MAX_WIIMOTES 2
#define MAX_WIIMOTES 4
// 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);
m_EventWriteQueue.pop();
InterruptDebugging(false, rEvent.m_PayLoad);
// InterruptDebugging(false, rEvent.m_PayLoad);
}
m_pCriticalSection->Leave();