mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-07-23 06:09:50 -06:00
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:
@ -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;
|
||||
|
@ -61,7 +61,6 @@ namespace Core
|
||||
|
||||
void* GetWindowHandle();
|
||||
bool GetRealWiimote();
|
||||
void ReconnectWiimote();
|
||||
|
||||
extern bool bReadTrace;
|
||||
extern bool bWriteTrace;
|
||||
|
@ -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);
|
||||
pWiimote->EventDisconnect();
|
||||
}
|
||||
|
||||
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)
|
||||
|
@ -83,6 +83,8 @@ public:
|
||||
void PurgeACLPool();
|
||||
void PurgeHCIPool();
|
||||
|
||||
bool RemoteDisconnect(u16 _connectionHandle);
|
||||
|
||||
//hack for wiimote plugin
|
||||
|
||||
public:
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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)
|
||||
|
@ -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);
|
||||
|
@ -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)
|
||||
|
@ -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,
|
||||
|
@ -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
|
||||
// ---------
|
||||
|
||||
|
Reference in New Issue
Block a user