Wiimote: Fixed the dual mode bug I mentioned in the last commit, now the Nunchuck should not get stuck when switching between the real and emulated Nunchuck. The only important problem left is disconnect problem that occurs about one in five times you switch to the real wiimote.

git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@2130 8ced0084-cf51-0410-be5f-012b33b47a6e
This commit is contained in:
John Peterson 2009-02-07 04:19:52 +00:00
parent fcdd2a8e17
commit 382b4af74b
6 changed files with 88 additions and 51 deletions

View File

@ -98,6 +98,7 @@ BEGIN_EVENT_TABLE(ConfigDialog,wxDialog)
EVT_BUTTON(IDB_RECORD + 15, ConfigDialog::RecordMovement)
EVT_TIMER(IDTM_UPDATE, ConfigDialog::Update)
EVT_TIMER(IDTM_UPDATE_ONCE, ConfigDialog::UpdateOnce)
EVT_TIMER(IDTM_SHUTDOWN, ConfigDialog::ShutDown)
END_EVENT_TABLE()
//////////////////////////////////////
@ -113,13 +114,14 @@ ConfigDialog::ConfigDialog(wxWindow *parent, wxWindowID id, const wxString &titl
#if wxUSE_TIMER
m_TimeoutTimer = new wxTimer(this, IDTM_UPDATE);
m_ShutDownTimer = new wxTimer(this, IDTM_SHUTDOWN);
m_TimeoutATimer = new wxTimer(this, IDTM_UPDATEA);
m_TimeoutOnce = new wxTimer(this, IDTM_UPDATE_ONCE);
// Reset values
m_bWaitForRecording = false;
m_bRecording = false;
#endif
ControlsCreated = false;
m_bEnableUseRealWiimote = true;
Page = 0;
m_vRecording.resize(RECORDING_ROWS + 1);
@ -201,6 +203,20 @@ void ConfigDialog::CloseClick(wxCommandEvent& event)
void ConfigDialog::AboutClick(wxCommandEvent& WXUNUSED (event))
{
}
// Execute a delayed function
void ConfigDialog::UpdateOnce(wxTimerEvent& event)
{
switch(event.GetId())
{
case IDTM_UPDATE_ONCE:
// Reenable the checkbox
m_bEnableUseRealWiimote = true;
SetCursor(wxCursor(wxCURSOR_ARROW));
UpdateGUI();
break;
}
}
//////////////////////////////////////
@ -811,13 +827,21 @@ void ConfigDialog::DoUseReal()
Console::Print("\nDoUseReal() Connect extension: %i\n", !UsingExtension);
DoExtensionConnectedDisconnected(UsingExtension ? 0 : 1);
// Sleep this thread
sleep(100);
// Disable the checkbox for a moment
SetCursor(wxCursor(wxCURSOR_WAIT));
m_bEnableUseRealWiimote = false;
// We don't need this, there is already a message queue that allows the nessesary timeout
//sleep(100);
UsingExtension = !UsingExtension;
Console::Print("\nDoUseReal() Connect extension: %i\n", !UsingExtension);
DoExtensionConnectedDisconnected(UsingExtension ? 1 : 0);
// Sleep again, to allow the approximate time it takes for the Wiimote to come online
sleep(200);
/* Start the timer to allow the approximate time it takes for the Wiimote to come online
it would simpler to use sleep(1000) but that doesn't work because we need the functions in main.cpp
to work */
m_TimeoutOnce->Start(1000, true);
}
// ===================================================
@ -880,9 +904,7 @@ void ConfigDialog::GeneralSettingsChanged(wxCommandEvent& event)
g_Config.bNunchuckConnected = m_NunchuckConnected[Page]->IsChecked();
// Copy the calibration data
memcpy(WiiMoteEmu::g_RegExt + 0x20, WiiMoteEmu::nunchuck_calibration, sizeof(WiiMoteEmu::nunchuck_calibration));
memcpy(WiiMoteEmu::g_RegExt + 0x30, WiiMoteEmu::nunchuck_calibration, sizeof(WiiMoteEmu::nunchuck_calibration));
memcpy(WiiMoteEmu::g_RegExt + 0xfa, WiiMoteEmu::nunchuck_id, sizeof(WiiMoteEmu::nunchuck_id));
WiiMoteEmu::SetDefaultExtensionRegistry();
// Generate connect/disconnect status event
DoExtensionConnectedDisconnected();
@ -900,9 +922,7 @@ void ConfigDialog::GeneralSettingsChanged(wxCommandEvent& event)
g_Config.bClassicControllerConnected = m_ClassicControllerConnected[Page]->IsChecked();
// Copy the calibration data
memcpy(WiiMoteEmu::g_RegExt + 0x20, WiiMoteEmu::classic_calibration, sizeof(WiiMoteEmu::classic_calibration));
memcpy(WiiMoteEmu::g_RegExt + 0x30, WiiMoteEmu::classic_calibration, sizeof(WiiMoteEmu::classic_calibration));
memcpy(WiiMoteEmu::g_RegExt + 0xfa, WiiMoteEmu::classic_id, sizeof(WiiMoteEmu::classic_id));
WiiMoteEmu::SetDefaultExtensionRegistry();
// Generate connect/disconnect status event
DoExtensionConnectedDisconnected();
break;
@ -977,7 +997,7 @@ void ConfigDialog::UpdateGUI()
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]->Enable(!g_EmulatorRunning);
m_UseRealWiimote[Page]->Enable((g_RealWiiMotePresent && g_Config.bConnectRealWiimote) || !g_EmulatorRunning);
m_UseRealWiimote[Page]->Enable((m_bEnableUseRealWiimote && g_RealWiiMotePresent && g_Config.bConnectRealWiimote) || !g_EmulatorRunning);
// Linux has no FindItem()
#ifdef _WIN32

View File

@ -60,15 +60,15 @@ class ConfigDialog : public wxDialog
void DoRecordMovement(u8 _x, u8 _y, u8 _z, const u8 *_IR, int IRBytes);
void DoRecordA(bool Pressed);
void ConvertToString();
wxTimer *m_TimeoutTimer, *m_ShutDownTimer, *m_TimeoutATimer;
wxTimer *m_TimeoutTimer, *m_ShutDownTimer, *m_TimeoutOnce;
void Update(wxTimerEvent& WXUNUSED(event));
void ShutDown(wxTimerEvent& WXUNUSED(event));
void UpdateA(wxTimerEvent& WXUNUSED(event));
void UpdateOnce(wxTimerEvent& event);
private:
DECLARE_EVENT_TABLE();
bool ControlsCreated; int Page, BoxW, BoxH;
bool ControlsCreated, m_bEnableUseRealWiimote; int Page, BoxW, BoxH;
wxNotebook *m_Notebook;
wxPanel *m_Controller[4], *m_PageRecording;
@ -131,7 +131,7 @@ class ConfigDialog : public wxDialog
ID_CLOSE = 1000,
ID_APPLY,
ID_ABOUTOGL,
IDTM_EXIT, IDTM_UPDATE, IDTM_SHUTDOWN, IDTM_UPDATEA, // Timer
IDTM_EXIT, IDTM_UPDATE, IDTM_SHUTDOWN, IDTM_UPDATE_ONCE, // Timer
ID_NOTEBOOK, ID_CONTROLLERPAGE1, ID_CONTROLLERPAGE2, ID_CONTROLLERPAGE3, ID_CONTROLLERPAGE4, ID_PAGE_RECORDING,

View File

@ -424,13 +424,6 @@ void ConfigDialog::Update(wxTimerEvent& WXUNUSED(event))
UpdateGUI();
}
// One second timeout for another A press
void ConfigDialog::UpdateA(wxTimerEvent& WXUNUSED(event))
{
m_bAllowA = true;
Console::Print("A allowed again");
}
void ConfigDialog::RecordMovement(wxCommandEvent& event)
{
m_iRecordTo = event.GetId() - 2000;
@ -460,7 +453,6 @@ void ConfigDialog::RecordMovement(wxCommandEvent& event)
UpdateGUI();
m_TimeoutTimer->Start(5000, true);
//m_TimeoutATimer->Start(500, true);
}
void ConfigDialog::DoRecordA(bool Pressed)

View File

@ -234,7 +234,7 @@ void UpdateEeprom()
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_zero.z = g_RegExt[0x26]; // Including the g-force
g_nu.jx.max = g_RegExt[0x28];
g_nu.jx.min = g_RegExt[0x29];
g_nu.jx.center = g_RegExt[0x2a];
@ -242,8 +242,12 @@ void UpdateEeprom()
g_nu.jy.min = g_RegExt[0x2c];
g_nu.jy.center = g_RegExt[0x2d];
Console::Print("UpdateEeprom: %i %i %i\n",
Console::Print("\nUpdateEeprom: %i %i %i\n",
WiiMoteEmu::g_Eeprom[22], WiiMoteEmu::g_Eeprom[23], WiiMoteEmu::g_Eeprom[27]);
Console::Print("UpdateExtension: %i %i %i %i %i\n\n",
WiiMoteEmu::g_RegExt[0x2a], WiiMoteEmu::g_RegExt[0x2d],
WiiMoteEmu::g_RegExt[20], WiiMoteEmu::g_RegExt[21], WiiMoteEmu::g_RegExt[26]);
}
// Calculate checksum for the nunchuck calibration. The last two bytes.
@ -274,6 +278,26 @@ void ResetVariables()
g_EmulatedWiiMoteInitialized = false;
}
// Update the extension calibration values with our default values
void SetDefaultExtensionRegistry()
{
// Copy extension id and calibration to its register
if(g_Config.bNunchuckConnected)
{
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.bClassicControllerConnected)
{
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));
}
UpdateEeprom();
}
// ===================================================
/* Write initial values to Eeprom and registers. */
// ----------------
@ -289,27 +313,8 @@ void Initialize()
memcpy(g_Eeprom, EepromData_0, sizeof(EepromData_0));
memcpy(g_Eeprom + 0x16D0, EepromData_16D0, sizeof(EepromData_16D0));
// Write default accelerometer neutral values
UpdateEeprom();
/* Extension data for homebrew applications that use the 0x00000000 key. This
writes 0x0000 in encrypted form (0xfefe) to 0xfe in the extension register. */
//WriteCrypted16(g_RegExt, 0xfe, 0x0000); // Fully inserted Nunchuk
// Copy extension id and calibration to its register
if(g_Config.bNunchuckConnected)
{
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.bClassicControllerConnected)
{
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));
}
SetDefaultExtensionRegistry();
g_ReportingMode = 0;
g_EmulatedWiiMoteInitialized = true;
@ -327,7 +332,11 @@ void Initialize()
g_RecordingCurrentTime[i] = 0;
}
// I forgot what these were for?
/* The Nuncheck extension ID for homebrew applications that use the zero key. This writes 0x0000
in encrypted form (0xfefe) to 0xfe in the extension register. */
//WriteCrypted16(g_RegExt, 0xfe, 0x0000); // Fully inserted Nunchuk
// I forgot what these were for? Is this the zero key encrypted 0xa420?
// g_RegExt[0xfd] = 0x1e;
// g_RegExt[0xfc] = 0x9a;
}

View File

@ -28,7 +28,7 @@ u32 convert24bit(const u8* src);
u16 convert16bit(const u8* src);
void GetMousePos(float& x, float& y);
void UpdateEeprom();
// General functions
void Initialize();
void DoState(void* ptr, int mode);
void Shutdown(void);
@ -36,8 +36,13 @@ void InterruptChannel(u16 _channelID, const void* _pData, u32 _Size);
void ControlChannel(u16 _channelID, const void* _pData, u32 _Size) ;
void Update();
// Recordings
void LoadRecordedMovements();
// Registers and calibration values
void UpdateEeprom();
void SetDefaultExtensionRegistry();
};
#endif

View File

@ -517,10 +517,21 @@ void ReadDebugging(bool Emu, const void* _pData, int Size)
Console::Print("JS.Center.y: %i\n\n", data[7 + 13]);
// Save the values
if (!Emu && data[7 + 0] != 0xff)
if (!Emu)
{
memcpy(WiiMoteEmu::g_RegExt + 0x20, &data[7], 0x10);
memcpy(WiiMoteEmu::g_RegExt + 0x30, &data[7], 0x10);
// Save the values from the Nunchuck
if(data[7 + 0] != 0xff)
{
memcpy(WiiMoteEmu::g_RegExt + 0x20, &data[7], 0x10);
memcpy(WiiMoteEmu::g_RegExt + 0x30, &data[7], 0x10);
}
// Save the default values that should work with Wireless Nunchucks
else
{
WiiMoteEmu::SetDefaultExtensionRegistry();
}
WiiMoteEmu::UpdateEeprom();
}
// We got a third party nunchuck
else if(data[7 + 0] == 0xff)