New Wiimote/GCPad: Fix segfault prob in Linux.(thanks glennrics) Some minor changes to real wiimote: force continuous reporting off, since only the last data report is used currently.

git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@5831 8ced0084-cf51-0410-be5f-012b33b47a6e
This commit is contained in:
Jordan Woyak 2010-07-03 20:14:57 +00:00
parent 6cc3e4ba14
commit 2e6a9f9805
4 changed files with 60 additions and 26 deletions

View File

@ -23,7 +23,7 @@
#include "../../InputCommon/Src/InputConfig.h" #include "../../InputCommon/Src/InputConfig.h"
InputPlugin g_plugin("GCPadNew", "Pad", "GCPad"); static InputPlugin g_plugin("GCPadNew", "Pad", "GCPad");
InputPlugin *PAD_GetPlugin() { InputPlugin *PAD_GetPlugin() {
return &g_plugin; return &g_plugin;

View File

@ -62,15 +62,16 @@ void Wiimote::ReportMode(const u16 _channelID, wm_report_mode* dr)
//DEBUG_LOG(WIIMOTE, " All The Time: %x", dr->all_the_time); //DEBUG_LOG(WIIMOTE, " All The Time: %x", dr->all_the_time);
//DEBUG_LOG(WIIMOTE, " Mode: 0x%02x", dr->mode); //DEBUG_LOG(WIIMOTE, " Mode: 0x%02x", dr->mode);
m_reporting_auto = dr->all_the_time; //m_reporting_auto = dr->all_the_time;
m_reporting_auto = dr->continuous; // this right?
m_reporting_mode = dr->mode; m_reporting_mode = dr->mode;
m_reporting_channel = _channelID; m_reporting_channel = _channelID;
// reset IR camera // reset IR camera
//memset(m_reg_ir, 0, sizeof(*m_reg_ir)); //ugly hack //memset(m_reg_ir, 0, sizeof(*m_reg_ir)); //ugly hack
if (0 == dr->all_the_time) if (false == m_reporting_auto)
PanicAlert("Wiimote: Reporting Always is set to OFF! Everything should be fine, but games never do this."); PanicAlert("Wiimote: Reporting is set to OFF! Everything should be fine, but games never do this.");
if (dr->mode >= WM_REPORT_INTERLEAVE1) if (dr->mode >= WM_REPORT_INTERLEAVE1)
PanicAlert("Wiimote: Unsupported Reporting mode."); PanicAlert("Wiimote: Unsupported Reporting mode.");

View File

@ -153,7 +153,7 @@ struct wm_leds {
#define WM_REPORT_MODE 0x12 #define WM_REPORT_MODE 0x12
struct wm_report_mode { struct wm_report_mode {
u8 rumble : 1; u8 rumble : 1;
u8 continuous : 1; u8 continuous : 1; // these 2 seem to be named wrong
u8 all_the_time : 1; u8 all_the_time : 1;
u8 : 5; u8 : 5;
u8 mode; u8 mode;

View File

@ -66,8 +66,8 @@ public:
void Update(); void Update();
void Read(); void Read();
void Disconnect(); void Disconnect();
void DisableDataReporting();
private: private:
void ClearReports(); void ClearReports();
@ -88,21 +88,12 @@ Wiimote::Wiimote(wiimote_t* const wm, const unsigned int index)
, m_channel(0) , m_channel(0)
, m_last_data_report_valid(false) , m_last_data_report_valid(false)
{ {
{
// disable reporting // disable reporting
wm_report_mode rpt = wm_report_mode(); DisableDataReporting();
rpt.mode = WM_REPORT_CORE;
SendPacket(m_wiimote, WM_REPORT_MODE, &rpt, sizeof(rpt));
}
// clear all msgs, silly maybe // clear all msgs, silly maybe
while (wiiuse_io_read(m_wiimote)); // - cleared on first InterruptChannel call
//while (wiiuse_io_read(m_wiimote));
{
// request status, will be sent to game on start
wm_request_status rpt = wm_request_status();
SendPacket(m_wiimote, WM_REQUEST_STATUS, &rpt, sizeof(rpt));
}
//{ //{
// LEDs test // LEDs test
@ -113,12 +104,17 @@ Wiimote::Wiimote(wiimote_t* const wm, const unsigned int index)
// set LEDs // set LEDs
wiiuse_set_leds(m_wiimote, WIIMOTE_LED_1 << m_index); wiiuse_set_leds(m_wiimote, WIIMOTE_LED_1 << m_index);
// TODO: make Dolphin connect wiimote, maybe
} }
Wiimote::~Wiimote() Wiimote::~Wiimote()
{ {
ClearReports(); ClearReports();
// disable reporting / wiiuse might do this on shutdown anyway, o well, don't know for sure
DisableDataReporting();
// send disconnect message to wii, maybe, i hope, naw shit messes up on emu-stop // send disconnect message to wii, maybe, i hope, naw shit messes up on emu-stop
//if (g_WiimoteInitialize.pWiimoteInterruptChannel) //if (g_WiimoteInitialize.pWiimoteInterruptChannel)
//{ //{
@ -132,8 +128,16 @@ Wiimote::~Wiimote()
//} //}
} }
void Wiimote::DisableDataReporting()
{
wm_report_mode rpt = wm_report_mode();
rpt.mode = WM_REPORT_CORE;
SendPacket(m_wiimote, WM_REPORT_MODE, &rpt, sizeof(rpt));
}
void Wiimote::ClearReports() void Wiimote::ClearReports()
{ {
m_last_data_report_valid = false;
while (m_reports.size()) while (m_reports.size())
{ {
delete[] m_reports.front(); delete[] m_reports.front();
@ -152,13 +156,24 @@ void Wiimote::ControlChannel(const u16 channel, const void* const data, const u3
void Wiimote::InterruptChannel(const u16 channel, const void* const data, const u32 size) void Wiimote::InterruptChannel(const u16 channel, const void* const data, const u32 size)
{ {
if (0 == m_channel) // first interrupt/control channel sent
{
// clear all msgs, silly maybe
while (wiiuse_io_read(m_wiimote));
// request status
wm_request_status rpt = wm_request_status();
SendPacket(m_wiimote, WM_REQUEST_STATUS, &rpt, sizeof(rpt));
}
m_channel = channel; m_channel = channel;
wiiuse_io_write(m_wiimote, (byte*)data, size); wiiuse_io_write(m_wiimote, (byte*)data, size);
} }
void Wiimote::Read() void Wiimote::Read()
{ {
if (!m_channel) // if not connected to Dolphin, don't do anything, to keep sanchez happy :p
if (0 == m_channel)
return; return;
if (wiiuse_io_read(m_wiimote)) if (wiiuse_io_read(m_wiimote))
@ -198,15 +213,12 @@ void Wiimote::Update()
void Wiimote::Disconnect() void Wiimote::Disconnect()
{ {
{ m_channel = 0;
// disable reporting // disable reporting
wm_report_mode rpt = wm_report_mode(); DisableDataReporting();
rpt.mode = WM_REPORT_CORE;
SendPacket(m_wiimote, WM_REPORT_MODE, &rpt, sizeof(rpt));
}
// clear queue // clear queue
m_last_data_report_valid = false;
ClearReports(); ClearReports();
// clear out wiiuse queue, or maybe not, silly? idk // clear out wiiuse queue, or maybe not, silly? idk
@ -339,10 +351,29 @@ void InterruptChannel(int _WiimoteNumber, u16 _channelID, const void* _pData, u3
{ {
g_wiimote_critsec.Enter(); // enter g_wiimote_critsec.Enter(); // enter
u8* data = (u8*)_pData;
// some hax, since we just send the last data report to Dolphin on each Update() call
// , make the wiimote only send updated data reports when data changes
// == less bt traffic, eliminates some unneeded packets
if (WM_REPORT_MODE == ((u8*)_pData)[1])
{
// I dont wanna write on the const *_pData
data = new u8[_Size];
memcpy(data, _pData, _Size);
// nice var names :p, this seems to be this one
((wm_report_mode*)(data + 2))->all_the_time = false;
//((wm_report_mode*)(data + 2))->continuous = false;
}
if (g_wiimotes[_WiimoteNumber]) if (g_wiimotes[_WiimoteNumber])
g_wiimotes[_WiimoteNumber]->InterruptChannel(_channelID, _pData, _Size); g_wiimotes[_WiimoteNumber]->InterruptChannel(_channelID, data, _Size);
g_wiimote_critsec.Leave(); // leave g_wiimote_critsec.Leave(); // leave
if (data != _pData)
delete[] data;
} }
void ControlChannel(int _WiimoteNumber, u16 _channelID, const void* _pData, u32 _Size) void ControlChannel(int _WiimoteNumber, u16 _channelID, const void* _pData, u32 _Size)
@ -378,6 +409,8 @@ void StateChange(PLUGIN_EMUSTATE newState)
THREAD_RETURN WiimoteThreadFunc(void* arg) THREAD_RETURN WiimoteThreadFunc(void* arg)
{ {
Common::SetCurrentThreadName("Wiimote Read");
while (g_run_wiimote_thread) while (g_run_wiimote_thread)
{ {
g_wiimote_critsec.Enter(); // enter g_wiimote_critsec.Enter(); // enter