mirror of
https://github.com/izzy2lost/dolphin.git
synced 2026-06-19 01:16:48 -07:00
Wiimote:
1. Fixed the dual mode. You should now be able to change between the real and emulated Wiimote at any time, even when the Nunchuck is connected. It also supports third party Wireless Nunchucks that never sends any calibration values. The Nunchuck status should be automatically updated. The Nunchuck stick may get stuck, but that should fix itself if you disconnect and reconnect again. The only important problems seems to be that the real Wiimote fails to answer sometimes so that the Core functions disconnect it. 2. Began looking at how to reconnect the Wiimote after an unwanted HCI disconnect command git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@2129 8ced0084-cf51-0410-be5f-012b33b47a6e
This commit is contained in:
@@ -18,11 +18,19 @@
|
||||
#ifndef _COMMON_H
|
||||
#define _COMMON_H
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Settings
|
||||
// -----------------
|
||||
#define _CRTDBG_MAP_ALLOC
|
||||
#define _CRTDBG_MAP_ALLOC_NEW
|
||||
|
||||
#define CHECK_HEAP_INTEGRITY()
|
||||
//////////////////////////////
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Include
|
||||
// -----------------
|
||||
#ifdef _WIN32
|
||||
#ifdef _DEBUG
|
||||
#include <crtdbg.h>
|
||||
@@ -49,30 +57,37 @@
|
||||
#include <string.h>
|
||||
|
||||
#include "Paths.h"
|
||||
///////////////////////////////////
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Settings
|
||||
// -----------------
|
||||
|
||||
// Darwin ABI requires that stack frames be aligned to 16-byte boundaries.
|
||||
// This probably wouldn't break anyone either, but hey
|
||||
#ifdef __APPLE__
|
||||
#define STACKALIGN __attribute__((__force_align_arg_pointer__))
|
||||
#define STACKALIGN __attribute__((__force_align_arg_pointer__))
|
||||
#else
|
||||
#define STACKALIGN
|
||||
#define STACKALIGN
|
||||
#endif
|
||||
|
||||
|
||||
// Function Cross-Compatibility
|
||||
#ifdef _WIN32
|
||||
#define strcasecmp _stricmp
|
||||
#define strncasecmp _strnicmp
|
||||
#define unlink _unlink
|
||||
#define snprintf _snprintf
|
||||
#define strcasecmp _stricmp
|
||||
#define strncasecmp _strnicmp
|
||||
#define unlink _unlink
|
||||
#define snprintf _snprintf
|
||||
#else
|
||||
#define _stricmp strcasecmp
|
||||
#define _strnicmp strncasecmp
|
||||
#define _unlink unlink
|
||||
#define ARRAYSIZE(A) (sizeof(A)/sizeof((A)[0]))
|
||||
#define _stricmp strcasecmp
|
||||
#define _strnicmp strncasecmp
|
||||
#define _unlink unlink
|
||||
#define ARRAYSIZE(A) (sizeof(A)/sizeof((A)[0]))
|
||||
#endif
|
||||
|
||||
#ifdef _WIN32
|
||||
|
||||
#ifdef _WIN32
|
||||
// By default, MS' stdio implementation does not support 64-bit offsets.
|
||||
// This little hack fixes that, keeping the code portable to linux where fseek and fread
|
||||
// do support 64-bit offsets in modern distributions.
|
||||
@@ -164,9 +179,19 @@ template<class T>
|
||||
inline T min(const T& a, const T& b) {return a > b ? b : a;}
|
||||
template<class T>
|
||||
inline T max(const T& a, const T& b) {return a > b ? a : b;}
|
||||
///////////////////////////////////
|
||||
|
||||
|
||||
|
||||
// **************************************************************************************
|
||||
// Utility functions
|
||||
// **************************************************************************************
|
||||
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Byte ordering
|
||||
|
||||
// -----------------
|
||||
namespace Common
|
||||
{
|
||||
inline u8 swap8(u8 _data) {return(_data);}
|
||||
@@ -194,12 +219,12 @@ inline u64 swap64(u64 data) {return(((u64)swap32(data) << 32) | swap32(data >> 3
|
||||
#endif
|
||||
|
||||
} // end of namespace Common
|
||||
///////////////////////////////////
|
||||
|
||||
|
||||
// Utility functions
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Message alerts
|
||||
// -----------------
|
||||
enum MSG_TYPE
|
||||
{
|
||||
INFORMATION,
|
||||
@@ -223,10 +248,12 @@ extern bool MsgAlert(const char* caption, bool yes_no, int Style, const char* fo
|
||||
#define PanicYesNo(format, ...) MsgAlert("PANIC", true, WARNING, format, ##__VA_ARGS__)
|
||||
#define AskYesNo(format, ...) MsgAlert("ASK", true, QUESTION, format, ##__VA_ARGS__)
|
||||
#endif
|
||||
///////////////////////////////////
|
||||
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Logging
|
||||
// -----------------
|
||||
|
||||
// dummy class
|
||||
class LogTypes
|
||||
@@ -328,9 +355,12 @@ void Host_UpdateLogDisplay();
|
||||
#define _assert_(a)
|
||||
#define _assert_msg_(...)
|
||||
#endif
|
||||
///////////////////////////////////////
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Compile time asserts
|
||||
// -----------------
|
||||
namespace
|
||||
{
|
||||
|
||||
@@ -346,8 +376,9 @@ namespace
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
///////////////////////////////////////
|
||||
|
||||
|
||||
#endif // #ifndef _COMMON_H
|
||||
#endif // _COMMON_H
|
||||
|
||||
|
||||
|
||||
@@ -95,16 +95,19 @@ void Close()
|
||||
// Print to screen and file
|
||||
int Print(const char *fmt, ...)
|
||||
{
|
||||
// Maximum bytes, mind this value to avoid an overrun
|
||||
static const int MAX_BYTES = 1024*20;
|
||||
|
||||
#if defined(_WIN32)
|
||||
if(__hStdOut)
|
||||
{
|
||||
#endif
|
||||
char s[1024*20]; // Warning, mind this value
|
||||
char s[MAX_BYTES];
|
||||
va_list argptr;
|
||||
int cnt; // To store the vsnprintf return message
|
||||
|
||||
va_start(argptr, fmt);
|
||||
cnt = vsnprintf(s, 500, fmt, argptr);
|
||||
cnt = vsnprintf(s, MAX_BYTES, fmt, argptr);
|
||||
va_end(argptr);
|
||||
|
||||
|
||||
|
||||
@@ -151,16 +151,14 @@ std::string StringFromFormat(const char* format, ...)
|
||||
// ----------------
|
||||
std::string ArrayToString(const u8 *data, u32 size, u32 offset, int line_len, bool Spaces)
|
||||
{
|
||||
std::string Temp;
|
||||
std::string Tmp, Spc;
|
||||
if (Spaces) Spc = " "; else Spc = "";
|
||||
for (u32 i = 0; i < size; i++)
|
||||
{
|
||||
char Buffer[128];
|
||||
if (Spaces) sprintf(Buffer, "%02x ", data[i + offset]);
|
||||
else sprintf(Buffer, "%02x", data[i + offset]);
|
||||
if(i > 0 && i % line_len == 0) Temp.append("\n"); // break long lines
|
||||
Temp.append(Buffer);
|
||||
Tmp += StringFromFormat("%02x%s", data[i + offset], Spc.c_str());
|
||||
if(i > 1 && (i + 1) % line_len == 0) Tmp.append("\n"); // break long lines
|
||||
}
|
||||
return Temp;
|
||||
return Tmp;
|
||||
}
|
||||
// ================
|
||||
|
||||
|
||||
@@ -144,6 +144,12 @@ bool GetRealWiimote()
|
||||
{
|
||||
return g_bRealWiimote;
|
||||
}
|
||||
// This doesn't work yet, I don't understand how the connection work yet
|
||||
void ReconnectWiimote()
|
||||
{
|
||||
HW::InitWiimote();
|
||||
Console::Print("ReconnectWiimote()\n");
|
||||
}
|
||||
/////////////////////////////////////
|
||||
|
||||
|
||||
@@ -293,7 +299,7 @@ THREAD_RETURN EmuThread(void *pArg)
|
||||
LOG(OSREPORT, "Dualcore = %s", _CoreParameter.bUseDualCore ? "Yes" : "No");
|
||||
|
||||
HW::Init();
|
||||
|
||||
|
||||
emuThreadGoing.Set();
|
||||
|
||||
// Load the VideoPlugin
|
||||
|
||||
@@ -60,6 +60,7 @@ namespace Core
|
||||
bool MakeScreenshot(const std::string& _rFilename);
|
||||
void* GetWindowHandle();
|
||||
bool GetRealWiimote();
|
||||
void ReconnectWiimote();
|
||||
|
||||
extern bool bReadTrace;
|
||||
extern bool bWriteTrace;
|
||||
|
||||
@@ -108,4 +108,10 @@ namespace HW
|
||||
AudioInterface::DoState(p);
|
||||
WII_IPCInterface::DoState(p);
|
||||
}
|
||||
|
||||
// Restart Wiimote
|
||||
void InitWiimote()
|
||||
{
|
||||
WII_IPCInterface::Init();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,6 +26,7 @@ namespace HW
|
||||
void Init();
|
||||
void Shutdown();
|
||||
void DoState(PointerWrap &p);
|
||||
void InitWiimote();
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -19,12 +19,13 @@
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Include
|
||||
// ¯¯¯¯¯¯¯¯¯¯¯¯¯
|
||||
#include "WII_IPC_HLE_Device_usb.h"
|
||||
#include "../PluginManager.h"
|
||||
#include "ConsoleWindow.h" // Common
|
||||
|
||||
#include "../Core.h" // Local core functions
|
||||
#include "../Debugger/Debugger_SymbolMap.h"
|
||||
#include "../Host.h"
|
||||
#include "../PluginManager.h"
|
||||
#include "WII_IPC_HLE_Device_usb.h"
|
||||
///////////////////////
|
||||
|
||||
|
||||
@@ -1783,6 +1784,14 @@ void CWII_IPC_HLE_Device_usb_oh1_57e_305::CommandDisconnect(u8* _Input)
|
||||
"anyway. It is strongly recommed to save and/or restart the\n"
|
||||
"emulation.");
|
||||
}
|
||||
Console::Print("IPC CommandDisconnect\n");
|
||||
|
||||
// Send message to plugin
|
||||
/*
|
||||
Common::PluginWiimote* mote = CPluginManager::GetInstance().GetWiimote(0);
|
||||
u8 Message = WIIMOTE_RECONNECT;
|
||||
mote->Wiimote_ControlChannel(99, &Message, 0);
|
||||
*/
|
||||
}
|
||||
|
||||
void CWII_IPC_HLE_Device_usb_oh1_57e_305::CommandWriteLinkSupervisionTimeout(u8* _Input)
|
||||
|
||||
@@ -47,6 +47,7 @@ be accessed from Core::GetWindowHandle().
|
||||
#include "Common.h" // Common
|
||||
#include "FileUtil.h"
|
||||
#include "Timer.h"
|
||||
#include "ConsoleWindow.h"
|
||||
|
||||
#include "ConfigManager.h" // Core
|
||||
#include "Core.h"
|
||||
@@ -170,16 +171,26 @@ int abc = 0;
|
||||
switch(wParam)
|
||||
{
|
||||
// Stop
|
||||
case 5:
|
||||
case OPENGL_WM_USER_STOP:
|
||||
main_frame->DoStop();
|
||||
return 0; // Don't bother letting wxWidgets process this at all
|
||||
|
||||
case 15:
|
||||
case OPENGL_WM_USER_CREATE:
|
||||
// We don't have a local setting for bRenderToMain but we can detect it this way instead
|
||||
//PanicAlert("main call %i %i %i %i", lParam, (HWND)Core::GetWindowHandle(), MSWGetParent_((HWND)Core::GetWindowHandle()), (HWND)this->GetHWND());
|
||||
if (lParam == NULL) main_frame->bRenderToMain = false;
|
||||
else main_frame->bRenderToMain = true;
|
||||
return 0;
|
||||
|
||||
case NJOY_RELOAD:
|
||||
// DirectInput in nJoy has failed
|
||||
return 0;
|
||||
|
||||
case WIIMOTE_RECONNECT:
|
||||
// The Wiimote plugin has been shut down, now reconnect the Wiimote
|
||||
Console::Print("WIIMOTE_RECONNECT\n");
|
||||
Core::ReconnectWiimote();
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
@@ -56,6 +56,7 @@ EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "DolphinWX", "Core\DolphinWX\DolphinWX.vcproj", "{A72606EF-C5C1-4954-90AD-F0F93A8D97D9}"
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
{48AD7E0A-25B1-4974-A1E3-03F8C438D34F} = {48AD7E0A-25B1-4974-A1E3-03F8C438D34F}
|
||||
{CFDCEE0E-FA45-4F72-9FCC-0B88F5A75160} = {CFDCEE0E-FA45-4F72-9FCC-0B88F5A75160}
|
||||
{0318BA30-EF48-441A-9E10-DC85EFAE39F0} = {0318BA30-EF48-441A-9E10-DC85EFAE39F0}
|
||||
{8D612734-FAA5-4B8A-804F-4DEA2367D495} = {8D612734-FAA5-4B8A-804F-4DEA2367D495}
|
||||
{71B16F46-0B00-4EDA-B253-D6D9D03A215C} = {71B16F46-0B00-4EDA-B253-D6D9D03A215C}
|
||||
@@ -228,6 +229,7 @@ Global
|
||||
{CFDCEE0E-FA45-4F72-9FCC-0B88F5A75160}.DebugFast|Win32.ActiveCfg = DebugFast|Win32
|
||||
{CFDCEE0E-FA45-4F72-9FCC-0B88F5A75160}.DebugFast|x64.ActiveCfg = DebugFast|x64
|
||||
{CFDCEE0E-FA45-4F72-9FCC-0B88F5A75160}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{CFDCEE0E-FA45-4F72-9FCC-0B88F5A75160}.Release|Win32.Build.0 = Release|Win32
|
||||
{CFDCEE0E-FA45-4F72-9FCC-0B88F5A75160}.Release|x64.ActiveCfg = Release|x64
|
||||
{CFDCEE0E-FA45-4F72-9FCC-0B88F5A75160}.Release|x64.Build.0 = Release|x64
|
||||
{C573CAF7-EE6A-458E-8049-16C0BF34C2E9}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
|
||||
@@ -17,6 +17,21 @@
|
||||
///////////////////////////////
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
/* Plugin communication. I place this here rather in Common.h since these messages are only received
|
||||
at one place, by the CPanel in Frame.cpp. That way I don't have to rebuild if any of this is changed */
|
||||
// -----------------
|
||||
enum PLUGIN_COMM
|
||||
{
|
||||
// Begin at 10 in case there is already messages with wParam = 0, 1, 2 and so on
|
||||
OPENGL_WM_USER_STOP = 10,
|
||||
OPENGL_WM_USER_CREATE,
|
||||
NJOY_RELOAD, // Reload nJoy if DirectInput has failed
|
||||
WIIMOTE_RECONNECT // Reconnect the Wiimote if it has disconnected
|
||||
};
|
||||
///////////////////////////////
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
// System specific declarations and definitions
|
||||
// ------------
|
||||
|
||||
@@ -138,7 +138,7 @@ namespace EmuWindow
|
||||
switch( iMsg )
|
||||
{
|
||||
case WM_CREATE:
|
||||
PostMessage(m_hMain, WM_USER, 15, (int)m_hParent); // 15 = WM_USER_CREATE, make enum table if it's confusing
|
||||
PostMessage(m_hMain, WM_USER, OPENGL_WM_USER_CREATE, (int)m_hParent);
|
||||
break;
|
||||
|
||||
case WM_PAINT:
|
||||
@@ -154,13 +154,15 @@ namespace EmuWindow
|
||||
//PostQuitMessage(0);
|
||||
|
||||
/* The fullscreen option for Windows users is not very user friendly. With this the user
|
||||
can only get out of the fullscreen mode by pressing Esc or Alt + F4. But that also
|
||||
closes*/
|
||||
can only get out of the fullscreen mode by pressing Esc or Alt + F4. Esc also stops
|
||||
the emulation. Todo: But currently it hangs, so I have disabled the shutdown. */
|
||||
//if(m_hParent == NULL) ExitProcess(0);
|
||||
if(m_hParent == NULL)
|
||||
{
|
||||
{
|
||||
if (g_Config.bFullscreen)
|
||||
PostMessage(m_hMain, WM_USER, 5, 0); // Stop
|
||||
{
|
||||
//PostMessage(m_hMain, WM_USER, OPENGL_WM_USER_STOP, 0); // Stop
|
||||
}
|
||||
else
|
||||
// Toggle maximize and restore
|
||||
if (IsZoomed(hWnd)) ShowWindow(hWnd, SW_RESTORE); else ShowWindow(hWnd, SW_MAXIMIZE);
|
||||
|
||||
@@ -765,7 +765,7 @@ void ConfigDialog::CreateGUIControls()
|
||||
|
||||
|
||||
// ===================================================
|
||||
/* Do use real wiimote */
|
||||
/* Do connect real wiimote */
|
||||
// ----------------
|
||||
void ConfigDialog::DoConnectReal()
|
||||
{
|
||||
@@ -777,15 +777,53 @@ void ConfigDialog::DoConnectReal()
|
||||
}
|
||||
else
|
||||
{
|
||||
if (g_RealWiiMoteInitialized) WiiMoteReal::Shutdown();
|
||||
Console::Print("Post Message: %i\n", g_RealWiiMoteInitialized);
|
||||
if (g_RealWiiMoteInitialized)
|
||||
{
|
||||
WiiMoteReal::Shutdown();
|
||||
/*
|
||||
if (g_WiimoteUnexpectedDisconnect)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
PostMessage(g_ParentHWND, WM_USER, WIIMOTE_RECONNECT, 0);
|
||||
g_WiimoteUnexpectedDisconnect = false;
|
||||
#endif
|
||||
}
|
||||
*/
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// ===================================================
|
||||
/* Do use real wiimote. We let the game set up the real Wiimote reporting mode and init the Extension when we change
|
||||
want to use it again. */
|
||||
// ----------------
|
||||
void ConfigDialog::DoUseReal()
|
||||
{
|
||||
// Clear any eventual events in the Wiimote queue
|
||||
WiiMoteReal::ClearEvents();
|
||||
|
||||
// Are we using an extension now? The report that it's removed, then reconnected.
|
||||
bool UsingExtension = false;
|
||||
if (g_Config.bNunchuckConnected || g_Config.bClassicControllerConnected)
|
||||
UsingExtension = true;
|
||||
|
||||
Console::Print("\nDoUseReal() Connect extension: %i\n", !UsingExtension);
|
||||
DoExtensionConnectedDisconnected(UsingExtension ? 0 : 1);
|
||||
// Sleep this thread
|
||||
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);
|
||||
}
|
||||
|
||||
// ===================================================
|
||||
/* Generate connect/disconnect status event */
|
||||
// ----------------
|
||||
void ConfigDialog::DoExtensionConnectedDisconnected()
|
||||
void ConfigDialog::DoExtensionConnectedDisconnected(int Extension)
|
||||
{
|
||||
// There is no need for this if no game is running
|
||||
if(!g_EmulatorRunning) return;
|
||||
@@ -795,7 +833,7 @@ void ConfigDialog::DoExtensionConnectedDisconnected()
|
||||
|
||||
// Check if a game is running, in that case change the status
|
||||
if(WiiMoteEmu::g_ReportingChannel > 0)
|
||||
WiiMoteEmu::WmRequestStatus(WiiMoteEmu::g_ReportingChannel, rs);
|
||||
WiiMoteEmu::WmRequestStatus(WiiMoteEmu::g_ReportingChannel, rs, Extension);
|
||||
}
|
||||
|
||||
// ===================================================
|
||||
@@ -809,9 +847,9 @@ void ConfigDialog::GeneralSettingsChanged(wxCommandEvent& event)
|
||||
DoConnectReal();
|
||||
break;
|
||||
case ID_USE_REAL:
|
||||
// Enable the Wiimote thread
|
||||
g_Config.bUseRealWiimote = m_UseRealWiimote[Page]->IsChecked();
|
||||
//if(g_Config.bUseRealWiimote) WiiMoteReal::SetDataReportingMode();
|
||||
if(g_Config.bUseRealWiimote) WiiMoteReal::ClearEvents();
|
||||
if(g_Config.bUseRealWiimote) DoUseReal();
|
||||
break;
|
||||
|
||||
case ID_SIDEWAYSDPAD:
|
||||
@@ -842,8 +880,8 @@ 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 + 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));
|
||||
|
||||
// Generate connect/disconnect status event
|
||||
@@ -862,8 +900,8 @@ 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 + 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));
|
||||
// Generate connect/disconnect status event
|
||||
DoExtensionConnectedDisconnected();
|
||||
@@ -925,14 +963,13 @@ void ConfigDialog::UpdateGUI()
|
||||
{
|
||||
Console::Print("UpdateGUI: \n");
|
||||
|
||||
/* We can't allow different values for this one if we are using the real and emulated wiimote
|
||||
side by side so that we can switch between between during gameplay. We update the checked
|
||||
or unchecked values from the g_Config settings, and we make sure they are up to date with
|
||||
unplugged and reinserted extensions. */
|
||||
/* 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);
|
||||
m_NunchuckConnected[Page]->SetValue(g_Config.bNunchuckConnected);
|
||||
m_ClassicControllerConnected[Page]->SetValue(g_Config.bClassicControllerConnected);
|
||||
m_NunchuckConnected[Page]->Enable(!(g_RealWiiMotePresent && g_Config.bConnectRealWiimote && g_EmulatorRunning));
|
||||
m_ClassicControllerConnected[Page]->Enable(!(g_RealWiiMotePresent && g_Config.bConnectRealWiimote && g_EmulatorRunning));
|
||||
m_NunchuckConnected[Page]->Enable(AllowExtensionChange);
|
||||
m_ClassicControllerConnected[Page]->Enable(AllowExtensionChange);
|
||||
|
||||
/* 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
|
||||
|
||||
@@ -156,8 +156,9 @@ class ConfigDialog : public wxDialog
|
||||
void AboutClick(wxCommandEvent& event);
|
||||
|
||||
void DoConnectReal(); // Real
|
||||
void DoUseReal();
|
||||
|
||||
void DoExtensionConnectedDisconnected(); // Emulated
|
||||
void DoExtensionConnectedDisconnected(int Extension = -1); // Emulated
|
||||
|
||||
void GeneralSettingsChanged(wxCommandEvent& event);
|
||||
};
|
||||
|
||||
@@ -50,7 +50,6 @@ u8 g_Eeprom[WIIMOTE_EEPROM_SIZE];
|
||||
u8 g_RegSpeaker[WIIMOTE_REG_SPEAKER_SIZE];
|
||||
u8 g_RegExt[WIIMOTE_REG_EXT_SIZE];
|
||||
u8 g_RegExtTmp[WIIMOTE_REG_EXT_SIZE];
|
||||
u8 g_RegExtTmpReport[WIIMOTE_REG_EXT_SIZE];
|
||||
u8 g_RegIr[WIIMOTE_REG_IR_SIZE];
|
||||
|
||||
u8 g_ReportingMode; // The reporting mode and channel id
|
||||
@@ -59,6 +58,7 @@ u16 g_ReportingChannel;
|
||||
std::vector<wm_ackdelay> AckDelay; // Ackk delay
|
||||
|
||||
wiimote_key g_ExtKey; // The extension encryption key
|
||||
bool g_Encryption; // Encryption on or off
|
||||
|
||||
} // namespace
|
||||
|
||||
|
||||
@@ -78,7 +78,6 @@ extern u8 g_Eeprom[WIIMOTE_EEPROM_SIZE];
|
||||
extern u8 g_RegSpeaker[WIIMOTE_REG_SPEAKER_SIZE];
|
||||
extern u8 g_RegExt[WIIMOTE_REG_EXT_SIZE];
|
||||
extern u8 g_RegExtTmp[WIIMOTE_REG_EXT_SIZE];
|
||||
extern u8 g_RegExtTmpReport[WIIMOTE_REG_EXT_SIZE];
|
||||
extern u8 g_RegIr[WIIMOTE_REG_IR_SIZE];
|
||||
|
||||
extern u8 g_ReportingMode;
|
||||
@@ -95,6 +94,7 @@ struct wm_ackdelay
|
||||
extern std::vector<wm_ackdelay> AckDelay;
|
||||
|
||||
extern wiimote_key g_ExtKey; // extension encryption key
|
||||
extern bool g_Encryption;
|
||||
|
||||
/* An example of a factory default first bytes of the Eeprom memory. There are differences between
|
||||
different Wiimotes, my Wiimote had different neutral values for the accelerometer. */
|
||||
@@ -120,11 +120,15 @@ static const u8 nunchuck_calibration[] =
|
||||
0x80,0x80,0x80,0x00, // accelerometer x, y, z neutral
|
||||
0xb3,0xb3,0xb3,0x00, // x, y, z g-force values
|
||||
|
||||
0xe0, 0x20, 0x80, 0xe0, // 0x80 = analog stick x and y axis center
|
||||
0x20, 0x80, 0xee, 0x43,
|
||||
|
||||
0x80,0x80,0x80,0x00, 0xb3,0xb3,0xb3,0x00, // repeat
|
||||
0xe0,0x20,0x80,0xe0, 0x20,0x80,0xee,0x43
|
||||
0xff, 0x00, 0x80, 0xff, // 0x80 = analog stick x and y axis center
|
||||
0x00, 0x80, 0xee, 0x43 // checksum on the last two bytes
|
||||
};
|
||||
static const u8 wireless_nunchuck_calibration[] =
|
||||
{
|
||||
128, 128, 128, 0x00,
|
||||
181, 181, 181, 0x00,
|
||||
255, 0, 125, 255,
|
||||
0, 126, 0xed, 0x43
|
||||
};
|
||||
|
||||
/* Classic Controller calibration. 0x80 is the neutral for the analog triggers and
|
||||
@@ -133,9 +137,6 @@ static const u8 nunchuck_calibration[] =
|
||||
static const u8 classic_calibration[] =
|
||||
{
|
||||
0xe4,0x1c,0x80,0xe4, 0x1c,0x80,0xd8,0x28,
|
||||
0x80,0xd8,0x28,0x80, 0x20,0x20,0x95,0xea,
|
||||
|
||||
0xe4,0x1c,0x80,0xe4, 0x1c,0x80,0xd8,0x28, // repeat
|
||||
0x80,0xd8,0x28,0x80, 0x20,0x20,0x95,0xea
|
||||
};
|
||||
|
||||
|
||||
@@ -232,10 +232,33 @@ void UpdateEeprom()
|
||||
g_accel.cal_g.y = g_Eeprom[27] - g_Eeprom[24];
|
||||
g_accel.cal_g.z = g_Eeprom[28] - g_Eeprom[24];
|
||||
|
||||
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.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];
|
||||
|
||||
Console::Print("UpdateEeprom: %i %i %i\n",
|
||||
WiiMoteEmu::g_Eeprom[22], WiiMoteEmu::g_Eeprom[23], WiiMoteEmu::g_Eeprom[27]);
|
||||
}
|
||||
|
||||
// Calculate checksum for the nunchuck calibration. The last two bytes.
|
||||
void ExtensionChecksum(u8 * Calibration)
|
||||
{
|
||||
u8 sum = 0; u8 Byte15, Byte16;
|
||||
for (int i = 0; i < sizeof(Calibration) - 2; i++)
|
||||
{
|
||||
sum += Calibration[i];
|
||||
printf("Plus 0x%02x\n", Calibration[i]);
|
||||
}
|
||||
Byte15 = sum + 0x55; // Byte 15
|
||||
Byte16 = sum + 0xaa; // Byte 16
|
||||
}
|
||||
|
||||
// Set initial values
|
||||
void ResetVariables()
|
||||
{
|
||||
@@ -246,6 +269,7 @@ void ResetVariables()
|
||||
|
||||
g_ReportingMode = 0;
|
||||
g_ReportingChannel = 0;
|
||||
g_Encryption = false;
|
||||
|
||||
g_EmulatedWiiMoteInitialized = false;
|
||||
}
|
||||
@@ -277,11 +301,13 @@ void Initialize()
|
||||
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));
|
||||
}
|
||||
|
||||
|
||||
@@ -370,6 +370,7 @@ void SendReadDataReply(u16 _channelID, void* _Base, u16 _Address, u8 _Size)
|
||||
// Add header values
|
||||
pReply->buttons = 0;
|
||||
pReply->error = 0;
|
||||
// 0x1 means two bytes, 0xf means 16 bytes
|
||||
pReply->size = (copySize - 1) & 0xf;
|
||||
pReply->address = Common::swap16(_Address + dataOffset);
|
||||
|
||||
@@ -534,7 +535,7 @@ void WmWriteData(u16 _channelID, wm_write_data* wd)
|
||||
request rs and all its eventual instructions it may include (for example turn off
|
||||
rumble or something else) and just send the status report. */
|
||||
// ----------------
|
||||
void WmRequestStatus(u16 _channelID, wm_request_status* rs)
|
||||
void WmRequestStatus(u16 _channelID, wm_request_status* rs, int Extension)
|
||||
{
|
||||
//PanicAlert("WmRequestStatus");
|
||||
LOGV(WII_IPC_WIIMOTE, 0, "================================================");
|
||||
@@ -562,11 +563,22 @@ void WmRequestStatus(u16 _channelID, wm_request_status* rs)
|
||||
0x55 - 0xff: level 4 */
|
||||
pStatus->battery = 0x5f; // fully charged
|
||||
|
||||
// Read config value for this one
|
||||
if(g_Config.bNunchuckConnected || g_Config.bClassicControllerConnected)
|
||||
pStatus->extension = 1;
|
||||
// Check if we have a specific order about the extension status
|
||||
if (Extension == -1)
|
||||
{
|
||||
// Read config value for this one
|
||||
if(g_Config.bNunchuckConnected || g_Config.bClassicControllerConnected)
|
||||
pStatus->extension = 1;
|
||||
else
|
||||
pStatus->extension = 0;
|
||||
}
|
||||
else
|
||||
pStatus->extension = 0;
|
||||
{
|
||||
if(Extension)
|
||||
pStatus->extension = 1;
|
||||
else
|
||||
pStatus->extension = 0;
|
||||
}
|
||||
|
||||
LOGV(WII_IPC_WIIMOTE, 0, " Extension: %x", pStatus->extension);
|
||||
LOGV(WII_IPC_WIIMOTE, 0, " SendStatusReport()");
|
||||
|
||||
@@ -53,7 +53,7 @@ void HidOutputReport(u16 _channelID, wm_report* sr);
|
||||
void WmLeds(u16 _channelID, wm_leds* leds);
|
||||
void WmReadData(u16 _channelID, wm_read_data* rd);
|
||||
void WmWriteData(u16 _channelID, wm_write_data* wd);
|
||||
void WmRequestStatus(u16 _channelID, wm_request_status* rs);
|
||||
void WmRequestStatus(u16 _channelID, wm_request_status* rs, int Extension = -1);
|
||||
void WmRequestStatus_(u16 _channelID, int a);
|
||||
void WmDataReporting(u16 _channelID, wm_data_reporting* dr);
|
||||
|
||||
|
||||
@@ -777,57 +777,45 @@ void FillReportExtension(wm_extension& _ext)
|
||||
// ------------------------------------
|
||||
// The default joystick and button values unless we use them
|
||||
// --------------
|
||||
_ext.jx = 0x80;
|
||||
_ext.jy = 0x80;
|
||||
_ext.jx = g_nu.jx.center;
|
||||
_ext.jy = g_nu.jy.center;
|
||||
_ext.bt = 0x03; // 0x03 means no button pressed, the button is zero active
|
||||
// ---------------------
|
||||
|
||||
|
||||
#ifdef _WIN32
|
||||
/* We use a 192 range (32 to 224) that match our calibration values in nunchuck_calibration[] */
|
||||
if(GetAsyncKeyState(VK_NUMPAD4)) // left
|
||||
_ext.jx = 0x20;
|
||||
// Set the max values to the current calibration values
|
||||
if(GetAsyncKeyState(VK_NUMPAD4)) // x
|
||||
_ext.jx = g_nu.jx.min;
|
||||
if(GetAsyncKeyState(VK_NUMPAD6))
|
||||
_ext.jx = g_nu.jx.max;
|
||||
|
||||
if(GetAsyncKeyState(VK_NUMPAD5)) // y
|
||||
_ext.jy = g_nu.jy.min;
|
||||
if(GetAsyncKeyState(VK_NUMPAD8))
|
||||
_ext.jy = 0xe0;
|
||||
|
||||
if(GetAsyncKeyState(VK_NUMPAD6)) // right
|
||||
_ext.jx = 0xe0;
|
||||
|
||||
if(GetAsyncKeyState(VK_NUMPAD5))
|
||||
_ext.jy = 0x20;
|
||||
|
||||
_ext.jy = g_nu.jy.max;
|
||||
|
||||
if(GetAsyncKeyState('C'))
|
||||
_ext.bt = 0x01;
|
||||
|
||||
if(GetAsyncKeyState('Z'))
|
||||
_ext.bt = 0x02;
|
||||
|
||||
_ext.bt = 0x02;
|
||||
if(GetAsyncKeyState('C') && GetAsyncKeyState('Z'))
|
||||
_ext.bt = 0x00;
|
||||
#else
|
||||
// TODO linux port
|
||||
#endif
|
||||
|
||||
/* Here we use g_RegExtTmpReport as a temporary storage for the enryption function because
|
||||
the type if array may have some importance for wiimote_encrypt(). We avoid using
|
||||
g_RegExtTmp that is used in EmuMain.cpp because if this runs on a different thread
|
||||
there is a small chance that they may interfer with each other. */
|
||||
|
||||
// Clear g_RegExtTmpReport by copying zeroes to it, this may not be needed
|
||||
memset(g_RegExtTmpReport, 0, sizeof(g_RegExtTmp));
|
||||
|
||||
/* Write the nunchuck inputs to it. We begin writing at 0x08, but it could also be
|
||||
0x00, the important thing is that we begin at an address evenly divisible
|
||||
by 0x08 */
|
||||
memcpy(g_RegExtTmpReport + 0x08, &_ext, sizeof(_ext));
|
||||
/* Here we encrypt the report */
|
||||
|
||||
// Create a temporary storage for the data
|
||||
u8 Tmp[sizeof(_ext)];
|
||||
// Clear the array by copying zeroes to it
|
||||
memset(Tmp, 0, sizeof(_ext));
|
||||
// Copy the data to it
|
||||
memcpy(Tmp, &_ext, sizeof(_ext));
|
||||
// Encrypt it
|
||||
wiimote_encrypt(&g_ExtKey, &g_RegExtTmpReport[0x08], 0x08, sizeof(_ext));
|
||||
|
||||
// Write it back to the extension
|
||||
memcpy(&_ext, &g_RegExtTmpReport[0x08], sizeof(_ext));
|
||||
wiimote_encrypt(&g_ExtKey, Tmp, 0x00, sizeof(_ext));
|
||||
// Write it back to the struct
|
||||
memcpy(&_ext, Tmp, sizeof(_ext));
|
||||
}
|
||||
// =======================
|
||||
|
||||
@@ -1002,17 +990,18 @@ void FillReportClassicExtension(wm_classic_extension& _ext)
|
||||
// TODO linux port
|
||||
#endif
|
||||
|
||||
// Clear g_RegExtTmp by copying zeroes to it
|
||||
memset(g_RegExtTmpReport, 0, sizeof(g_RegExtTmp));
|
||||
|
||||
/* Write the nunchuck inputs to it. We begin writing at 0x08, see comment above. */
|
||||
memcpy(g_RegExtTmpReport + 0x08, &_ext, sizeof(_ext));
|
||||
/* Here we encrypt the report */
|
||||
|
||||
// Create a temporary storage for the data
|
||||
u8 Tmp[sizeof(_ext)];
|
||||
// Clear the array by copying zeroes to it
|
||||
memset(Tmp, 0, sizeof(_ext));
|
||||
// Copy the data to it
|
||||
memcpy(Tmp, &_ext, sizeof(_ext));
|
||||
// Encrypt it
|
||||
wiimote_encrypt(&g_ExtKey, &g_RegExtTmpReport[0x08], 0x08, 0x06);
|
||||
|
||||
// Write it back
|
||||
memcpy(&_ext, &g_RegExtTmpReport[0x08], sizeof(_ext));
|
||||
wiimote_encrypt(&g_ExtKey, Tmp, 0x00, sizeof(_ext));
|
||||
// Write it back to the struct
|
||||
memcpy(&_ext, Tmp, sizeof(_ext));
|
||||
}
|
||||
// =======================
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user