Fixed emulated Wiimote again. Improved keyboard/gamepad controls for Wario Land.

git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@1151 8ced0084-cf51-0410-be5f-012b33b47a6e
This commit is contained in:
John Peterson 2008-11-12 15:03:21 +00:00
parent 85abf9d5f9
commit b698ea376d
18 changed files with 1375 additions and 927 deletions

View File

@ -186,6 +186,7 @@ bool PanicYesNo(const char* text, ...);
bool AskYesNo(const char* text, ...);
extern void __Log(int logNumber, const char* text, ...);
extern void __Logv(int log, int v, const char *format, ...);
// dummy class
@ -237,7 +238,8 @@ void Host_UpdateLogDisplay();
#ifdef LOGGING
#define LOG(t, ...) __Log(LogTypes::t, __VA_ARGS__);
#define LOGV(t,v, ...) __Log(LogTypes::t + v*100, __VA_ARGS__);
//#define LOGV(t,v, ...) __Log(LogTypes::t + v*100, __VA_ARGS__);
#define LOGV(t,v, ...) __Logv(LogTypes::t, v, __VA_ARGS__);
#define _dbg_assert_(_t_, _a_) \
if (!(_a_)){\

View File

@ -76,7 +76,7 @@ void Callback_DSPLog(const TCHAR* _szMessage);
char * Callback_ISOName(void);
void Callback_DSPInterrupt();
void Callback_PADLog(const TCHAR* _szMessage);
void Callback_WiimoteLog(const TCHAR* _szMessage);
void Callback_WiimoteLog(const TCHAR* _szMessage, int _v);
void Callback_WiimoteInput(u16 _channelID, const void* _pData, u32 _Size);
// For keyboard shortcuts.
@ -590,9 +590,9 @@ void Callback_KeyPress(int key, BOOL shift, BOOL control)
// __________________________________________________________________________________________________
// Callback_WiimoteLog
//
void Callback_WiimoteLog(const TCHAR* _szMessage)
void Callback_WiimoteLog(const TCHAR* _szMessage, int _v)
{
LOG(WII_IPC_WIIMOTE, _szMessage);
LOGV(WII_IPC_WIIMOTE, _v, _szMessage);
}
} // end of namespace Core

View File

@ -161,7 +161,7 @@ bool CWII_IPC_HLE_Device_usb_oh1_57e_305::IOCtlV(u32 _CommandAddress)
delete m_pACLBuffer;
m_pACLBuffer = new SIOCtlVBuffer(_CommandAddress);
LOG(WII_IPC_WIIMOTE, "ACL_DATA_ENDPOINT: 0x%08x ", _CommandAddress);
LOGV(WII_IPC_WIIMOTE, 2, "ACL_DATA_ENDPOINT: 0x%08x ", _CommandAddress);
return false;
}
break;
@ -237,7 +237,7 @@ void CWII_IPC_HLE_Device_usb_oh1_57e_305::SendToDevice(u16 _ConnectionHandle, u8
void CWII_IPC_HLE_Device_usb_oh1_57e_305::SendACLFrame(u16 _ConnectionHandle, u8* _pData, u32 _Size)
{
LOG(WII_IPC_WIIMOTE, "Queing ACL frame.");
LOGV(WII_IPC_WIIMOTE, 1, "Queing ACL frame.");
//queue the packet
ACLFrame frame;
@ -283,7 +283,7 @@ u32 CWII_IPC_HLE_Device_usb_oh1_57e_305::Update()
{
ACLFrame& frame = m_AclFrameQue.front();
LOG(WII_IPC_WIIMOTE, "Sending ACL frame.");
LOGV(WII_IPC_WIIMOTE, 1, "Sending ACL frame.");
UACLHeader* pHeader = (UACLHeader*)Memory::GetPointer(m_pACLBuffer->PayloadBuffer[0].m_Address);
pHeader->ConnectionHandle = frame.ConnectionHandle;
pHeader->BCFlag = 0;
@ -788,9 +788,9 @@ bool CWII_IPC_HLE_Device_usb_oh1_57e_305::SendEventNumberOfCompletedPackets(u16
AddEventToQueue(Event);
// Log
LOG(WII_IPC_WIIMOTE, "Event: SendEventNumberOfCompletedPackets");
LOG(WII_IPC_WIIMOTE, " Connection_Handle: 0x%04x", pNumberOfCompletedPackets->Connection_Handle);
LOG(WII_IPC_WIIMOTE, " Number_Of_Completed_Packets: %i", pNumberOfCompletedPackets->Number_Of_Completed_Packets);
LOGV(WII_IPC_WIIMOTE, 1, "Event: SendEventNumberOfCompletedPackets");
LOGV(WII_IPC_WIIMOTE, 1, " Connection_Handle: 0x%04x", pNumberOfCompletedPackets->Connection_Handle);
LOGV(WII_IPC_WIIMOTE, 1, " Number_Of_Completed_Packets: %i", pNumberOfCompletedPackets->Number_Of_Completed_Packets);
return true;
}

View File

@ -320,7 +320,7 @@ void CWII_IPC_HLE_WiiMote::SendACLFrame(u8* _pData, u32 _Size)
u8* pData = _pData + sizeof(SL2CAP_Header);
u32 DataSize = _Size - sizeof(SL2CAP_Header);
LOG(WII_IPC_WIIMOTE, "L2Cap-SendFrame: Channel 0x%04x, Len 0x%x, DataSize 0x%x",
LOGV(WII_IPC_WIIMOTE, 2, "L2Cap-SendFrame: Channel 0x%04x, Len 0x%x, DataSize 0x%x",
pHeader->CID, pHeader->Length, DataSize);
if(pHeader->Length != DataSize)
@ -941,7 +941,7 @@ namespace Core
void Callback_WiimoteInput(u16 _channelID, const void* _pData, u32 _Size)
{
const u8* pData = (const u8*)_pData;
LOG(WII_IPC_WIIMOTE, "Callback_WiimoteInput: 0x%x", _channelID);
LOGV(WII_IPC_WIIMOTE, 2, "Callback_WiimoteInput: 0x%x", _channelID);
std::string Temp;
for (u32 j=0; j<_Size; j++)
{
@ -949,7 +949,7 @@ namespace Core
sprintf(Buffer, "%02x ", pData[j]);
Temp.append(Buffer);
}
LOG(WII_IPC_WIIMOTE, " Data: %s", Temp.c_str());
LOGV(WII_IPC_WIIMOTE, 3, " Data: %s", Temp.c_str());
s_Usb->m_WiiMotes[0].SendL2capData(_channelID, _pData, _Size);
}

View File

@ -45,6 +45,16 @@ void __Log(int log, const char *format, ...)
LogManager::Log((LogTypes::LOG_TYPE)log, temp);
}
void __Logv(int log, int v, const char *format, ...)
{
char* temp = (char*)alloca(strlen(format)+512);
va_list args;
va_start(args, format);
CharArrayFromFormatV(temp, 512, format, args);
va_end(args);
LogManager::Log((LogTypes::LOG_TYPE)(log + v*100), temp);
}
CDebugger_Log::CDebugger_Log(const char* _szShortName, const char* _szName, int a) :
m_bLogToFile(true), // write to file or not
m_bShowInLog(false),

View File

@ -109,10 +109,14 @@ CMemoryWindow::~CMemoryWindow()
void CMemoryWindow::Save(IniFile& _IniFile) const
{
_IniFile.Set("MemoryWindow", "x", GetPosition().x);
_IniFile.Set("MemoryWindow", "y", GetPosition().y);
_IniFile.Set("MemoryWindow", "w", GetSize().GetWidth());
_IniFile.Set("MemoryWindow", "h", GetSize().GetHeight());
// Prevent these bad values that can happen after a crash or hanging
if(GetPosition().x != -32000 && GetPosition().y != -32000)
{
_IniFile.Set("MemoryWindow", "x", GetPosition().x);
_IniFile.Set("MemoryWindow", "y", GetPosition().y);
_IniFile.Set("MemoryWindow", "w", GetSize().GetWidth());
_IniFile.Set("MemoryWindow", "h", GetSize().GetHeight());
}
}

View File

@ -6,11 +6,9 @@
#define _WIIMOTE_H_INCLUDED__
#include "PluginSpecs.h"
#include "ExportProlog.h"
typedef void (*TLog)(const char* _pMessage);
typedef void (*TLogv)(const char* _pMessage, int _v);
// Called when the Wiimote sends input reports to the Core.
// Payload: an L2CAP packet.
@ -20,7 +18,7 @@ typedef void (*TWiimoteInput)(u16 _channelID, const void* _pData, u32 _Size);
typedef struct
{
HWND hWnd;
TLog pLog;
TLogv pLog;
TWiimoteInput pWiimoteInput;
} SWiimoteInitialize;

View File

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="9.00"
Version="9,00"
Name="Plugin_Wiimote"
ProjectGUID="{8D612734-FAA5-4B8A-804F-4DEA2367D495}"
RootNamespace="Plugin_Wiimote_Test"
@ -129,7 +129,7 @@
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="..\..\PluginSpecs;..\..\..\Externals\SDL\include;..\..\Core\Common\Src;..\..\..\Externals\wxWidgets\Include;..\..\..\Externals\wxWidgets\Include\msvc;..\..\..\Externals\WiiUse\inc"
PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;PLUGIN_WIIMOTE_TEST_EXPORTS;_SECURE_SCL=0"
PreprocessorDefinitions="LOGGING;WIN32;_DEBUG;_WINDOWS;_USRDLL;PLUGIN_WIIMOTE_TEST_EXPORTS;_SECURE_SCL=0"
MinimalRebuild="true"
BasicRuntimeChecks="3"
RuntimeLibrary="1"
@ -456,7 +456,7 @@
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories="..\..\PluginSpecs;..\..\..\Externals\SDL\include;..\..\Core\Common\Src;..\..\..\Externals\wxWidgets\Include;..\..\..\Externals\wxWidgets\Include\msvc;..\..\..\Externals\WiiUse\inc"
PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;PLUGIN_WIIMOTE_TEST_EXPORTS;DEBUGFAST;_SECURE_SCL=0"
PreprocessorDefinitions="LOGGING;WIN32;NDEBUG;_WINDOWS;_USRDLL;PLUGIN_WIIMOTE_TEST_EXPORTS;DEBUGFAST;_SECURE_SCL=0"
RuntimeLibrary="0"
WarningLevel="3"
WarnAsError="false"
@ -533,34 +533,58 @@
>
</File>
</Filter>
<Filter
Name="Emulated Wiimote"
>
<File
RelativePath=".\Src\EmuDeclarations.cpp"
>
</File>
<File
RelativePath=".\Src\EmuDeclarations.h"
>
</File>
<File
RelativePath=".\Src\EmuDefinitions.cpp"
>
</File>
<File
RelativePath=".\Src\EmuDefinitions.h"
>
</File>
<File
RelativePath=".\Src\EmuMain.cpp"
>
</File>
<File
RelativePath=".\Src\EmuMain.h"
>
</File>
<File
RelativePath=".\Src\FillReport.cpp"
>
</File>
</Filter>
<Filter
Name="Real Wiimote"
>
<File
RelativePath=".\Src\wiimote_real.cpp"
>
</File>
<File
RelativePath=".\Src\wiimote_real.h"
>
</File>
</Filter>
<File
RelativePath=".\Src\main.cpp"
>
</File>
<File
RelativePath=".\Src\SConscript"
>
</File>
<File
RelativePath=".\Src\wiimote_emu.cpp"
>
</File>
<File
RelativePath=".\Src\wiimote_emu.h"
>
</File>
<File
RelativePath=".\Src\wiimote_hid.h"
>
</File>
<File
RelativePath=".\Src\wiimote_real.cpp"
>
</File>
<File
RelativePath=".\Src\wiimote_real.h"
>
</File>
</Files>
<Globals>
</Globals>

View File

@ -0,0 +1,231 @@
// Copyright (C) 2003-2008 Dolphin Project.
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, version 2.0.
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License 2.0 for more details.
// A copy of the GPL 2.0 should have been included with the program.
// If not, see http://www.gnu.org/licenses/
// Official SVN repository and contact information can be found at
// http://code.google.com/p/dolphin-emu/
#include "pluginspecs_wiimote.h"
#include <vector>
#include <string>
#include "Common.h"
#include "wiimote_hid.h"
#include "EmuDeclarations.h"
#include "EmuDefinitions.h"
#include "Console.h" // for startConsoleWin, wprintf, GetConsoleHwnd
extern SWiimoteInitialize g_WiimoteInitialize;
//extern void __Log(int log, const char *format, ...);
//extern void __Log(int log, int v, const char *format, ...);
namespace WiiMoteEmu
{
//******************************************************************************
// Subroutine declarations
//******************************************************************************
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];
}
void GetMousePos(float& x, float& y)
{
#ifdef _WIN32
POINT point;
GetCursorPos(&point);
ScreenToClient(g_WiimoteInitialize.hWnd, &point);
RECT Rect;
GetClientRect(g_WiimoteInitialize.hWnd, &Rect);
int width = Rect.right - Rect.left;
int height = Rect.bottom - Rect.top;
x = point.x / (float)width;
y = point.y / (float)height;
#else
x = 0.5f;
y = 0.5f;
#endif
}
void CryptBuffer(u8* _buffer, u8 _size)
{
for (int i=0; i<_size; i++)
{
_buffer[i] = ((_buffer[i] - 0x17) ^ 0x17) & 0xFF;
}
}
void WriteCryped16(u8* _baseBlock, u16 _address, u16 _value)
{
u16 cryptedValue = _value;
CryptBuffer((u8*)&cryptedValue, sizeof(u16));
*(u16*)(_baseBlock + _address) = cryptedValue;
}
void Initialize()
{
memset(g_Eeprom, 0, WIIMOTE_EEPROM_SIZE);
memcpy(g_Eeprom, EepromData_0, sizeof(EepromData_0));
memcpy(g_Eeprom + 0x16D0, EepromData_16D0, sizeof(EepromData_16D0));
g_ReportingMode = 0;
WriteCryped16(g_RegExt, 0xfe, 0x0000);
// g_RegExt[0xfd] = 0x1e;
// g_RegExt[0xfc] = 0x9a;
}
void DoState(void* ptr, int mode)
{
//TODO: implement
}
void Shutdown(void)
{
}
void InterruptChannel(u16 _channelID, const void* _pData, u32 _Size)
{
const u8* data = (const u8*)_pData;
// dump raw data
{
LOG(WII_IPC_WIIMOTE, "Wiimote_Input");
std::string Temp;
for (u32 j=0; j<_Size; j++)
{
char Buffer[128];
sprintf(Buffer, "%02x ", data[j]);
Temp.append(Buffer);
}
LOG(WII_IPC_WIIMOTE, " Data: %s", Temp.c_str());
}
hid_packet* hidp = (hid_packet*) data;
switch(hidp->type)
{
case HID_TYPE_DATA:
{
switch(hidp->param)
{
case HID_PARAM_OUTPUT:
{
wm_report* sr = (wm_report*)hidp->data;
WmSendAck(_channelID, sr->channel);
HidOutputReport(_channelID, sr);
}
break;
default:
PanicAlert("HidInput: HID_TYPE_DATA - param 0x%02x", hidp->type, hidp->param);
break;
}
}
break;
default:
PanicAlert("HidInput: Unknown type 0x%02x and param 0x%02x", hidp->type, hidp->param);
break;
}
}
void ControlChannel(u16 _channelID, const void* _pData, u32 _Size)
{
const u8* data = (const u8*)_pData;
// dump raw data
{
LOG(WII_IPC_WIIMOTE, "Wiimote_ControlChannel");
std::string Temp;
for (u32 j=0; j<_Size; j++)
{
char Buffer[128];
sprintf(Buffer, "%02x ", data[j]);
Temp.append(Buffer);
}
LOG(WII_IPC_WIIMOTE, " Data: %s", Temp.c_str());
}
hid_packet* hidp = (hid_packet*) data;
switch(hidp->type)
{
case HID_TYPE_HANDSHAKE:
if (hidp->param == HID_PARAM_INPUT)
{
PanicAlert("HID_TYPE_HANDSHAKE - HID_PARAM_INPUT");
}
else
{
PanicAlert("HID_TYPE_HANDSHAKE - HID_PARAM_OUTPUT");
}
break;
case HID_TYPE_SET_REPORT:
if (hidp->param == HID_PARAM_INPUT)
{
PanicAlert("HID_TYPE_SET_REPORT input");
}
else
{
HidOutputReport(_channelID, (wm_report*)hidp->data);
//return handshake
u8 handshake = 0;
g_WiimoteInitialize.pWiimoteInput(_channelID, &handshake, 1);
}
break;
case HID_TYPE_DATA:
PanicAlert("HID_TYPE_DATA %s", hidp->type, hidp->param == HID_PARAM_INPUT ? "input" : "output");
break;
default:
PanicAlert("HidControlChanel: Unknown type %x and param %x", hidp->type, hidp->param);
break;
}
}
void Update()
{
//LOG(WII_IPC_WIIMOTE, "Wiimote_Update");
switch(g_ReportingMode) {
case 0:
break;
case WM_REPORT_CORE: SendReportCore(g_ReportingChannel); break;
case WM_REPORT_CORE_ACCEL: SendReportCoreAccel(g_ReportingChannel); break;
case WM_REPORT_CORE_ACCEL_IR12: SendReportCoreAccelIr12(g_ReportingChannel);break;
case WM_REPORT_CORE_ACCEL_IR10_EXT6: SendReportCoreAccelIr10Ext(g_ReportingChannel);break;
}
// g_ReportingMode = 0;
}
}

View File

@ -0,0 +1,100 @@
// Copyright (C) 2003-2008 Dolphin Project.
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, version 2.0.
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License 2.0 for more details.
// A copy of the GPL 2.0 should have been included with the program.
// If not, see http://www.gnu.org/licenses/
// Official SVN repository and contact information can be found at
// http://code.google.com/p/dolphin-emu/
#ifndef _EMU_DECLARATIONS_
#define _EMU_DECLARATIONS_
#include "pluginspecs_wiimote.h"
#include <vector>
#include <string>
#include "Common.h"
#include "wiimote_hid.h"
#include "EmuDefinitions.h"
#include "Console.h" // for startConsoleWin, wprintf, GetConsoleHwnd
extern SWiimoteInitialize g_WiimoteInitialize;
//extern void __Log(int log, const char *format, ...);
//extern void __Log(int log, int v, const char *format, ...);
namespace WiiMoteEmu
{
//******************************************************************************
// Definitions and variable declarations
//******************************************************************************
//extern u8 g_Leds = 0x1;
extern u8 g_Leds;
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_RegIr[WIIMOTE_REG_IR_SIZE];
extern u8 g_ReportingMode;
extern u16 g_ReportingChannel;
static const u8 EepromData_0[] = {
0xA1, 0xAA, 0x8B, 0x99, 0xAE, 0x9E, 0x78, 0x30,
0xA7, 0x74, 0xD3, 0xA1, 0xAA, 0x8B, 0x99, 0xAE,
0x9E, 0x78, 0x30, 0xA7, 0x74, 0xD3, 0x82, 0x82,
0x82, 0x15, 0x9C, 0x9C, 0x9E, 0x38, 0x40, 0x3E,
0x82, 0x82, 0x82, 0x15, 0x9C, 0x9C, 0x9E, 0x38,
0x40, 0x3E
};
static const u8 EepromData_16D0[] = {
0x00, 0x00, 0x00, 0xFF, 0x11, 0xEE, 0x00, 0x00,
0x33, 0xCC, 0x44, 0xBB, 0x00, 0x00, 0x66, 0x99,
0x77, 0x88, 0x00, 0x00, 0x2B, 0x01, 0xE8, 0x13
};
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 WmDataReporting(u16 _channelID, wm_data_reporting* dr);
void SendReadDataReply(u16 _channelID, void* _Base, u16 _Address, u8 _Size);
void SendReportCoreAccel(u16 _channelID);
void SendReportCoreAccelIr12(u16 _channelID);
void SendReportCore(u16 _channelID);
void SendReportCoreAccelIr10Ext(u16 _channelID);
int WriteWmReport(u8* dst, u8 channel);
void WmSendAck(u16 _channelID, u8 _reportID);
void FillReportAcc(wm_accel& _acc);
void FillReportInfo(wm_core& _core);
void FillReportIR(wm_ir_extended& _ir0, wm_ir_extended& _ir1);
void FillReportIRBasic(wm_ir_basic& _ir0, wm_ir_basic& _ir1);
u32 convert24bit(const u8* src);
u16 convert16bit(const u8* src);
void GetMousePos(float& x, float& y);
} // namespace
#endif //_EMU_DECLARATIONS_

View File

@ -0,0 +1,55 @@
// Copyright (C) 2003-2008 Dolphin Project.
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, version 2.0.
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License 2.0 for more details.
// A copy of the GPL 2.0 should have been included with the program.
// If not, see http://www.gnu.org/licenses/
// Official SVN repository and contact information can be found at
// http://code.google.com/p/dolphin-emu/
#ifndef _EMU_DECLARATIONS_
#define _EMU_DECLARATIONS_
#include "pluginspecs_wiimote.h"
#include <vector>
#include <string>
#include "Common.h"
#include "wiimote_hid.h"
#include "EmuDefinitions.h"
#include "Console.h" // for startConsoleWin, wprintf, GetConsoleHwnd
extern SWiimoteInitialize g_WiimoteInitialize;
//extern void __Log(int log, const char *format, ...);
//extern void __Log(int log, int v, const char *format, ...);
namespace WiiMoteEmu
{
//******************************************************************************
// Definitions and variable declarations
//******************************************************************************
u8 g_Leds = 0x1;
u8 g_Eeprom[WIIMOTE_EEPROM_SIZE];
u8 g_RegSpeaker[WIIMOTE_REG_SPEAKER_SIZE];
u8 g_RegExt[WIIMOTE_REG_EXT_SIZE];
u8 g_RegIr[WIIMOTE_REG_IR_SIZE];
u8 g_ReportingMode;
u16 g_ReportingChannel;
} // namespace
#endif //_EMU_DECLARATIONS_

View File

@ -0,0 +1,58 @@
// Copyright (C) 2003-2008 Dolphin Project.
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, version 2.0.
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License 2.0 for more details.
// A copy of the GPL 2.0 should have been included with the program.
// If not, see http://www.gnu.org/licenses/
// Official SVN repository and contact information can be found at
// http://code.google.com/p/dolphin-emu/
#ifndef _EMU_DEFINITIONS_
#define _EMU_DEFINITIONS_
#include "pluginspecs_wiimote.h"
#include <vector>
#include <string>
#include "Common.h"
#include "wiimote_hid.h"
#include "Console.h" // for startConsoleWin, wprintf, GetConsoleHwnd
extern SWiimoteInitialize g_WiimoteInitialize;
//extern void __Log(int log, const char *format, ...);
//extern void __Log(int log, int v, const char *format, ...);
namespace WiiMoteEmu
{
//******************************************************************************
// Definitions and variable declarations
//******************************************************************************
/* libogc bounding box, in smoothed IR coordinates: 232,284 792,704, however, it was
possible for me to get a better calibration with these values, if they are not
universal for all PCs we have to make a setting for it. */
#define LEFT 266
#define TOP 211
#define RIGHT 752
#define BOTTOM 728
#define SENSOR_BAR_RADIUS 200
// vars
#define WIIMOTE_EEPROM_SIZE (16*1024)
#define WIIMOTE_REG_SPEAKER_SIZE 10
#define WIIMOTE_REG_EXT_SIZE 0x100
#define WIIMOTE_REG_IR_SIZE 0x34
} // namespace
#endif //_EMU_DEFINITIONS_

View File

@ -0,0 +1,422 @@
// Copyright (C) 2003-2008 Dolphin Project.
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, version 2.0.
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License 2.0 for more details.
// A copy of the GPL 2.0 should have been included with the program.
// If not, see http://www.gnu.org/licenses/
// Official SVN repository and contact information can be found at
// http://code.google.com/p/dolphin-emu/
#include "pluginspecs_wiimote.h"
#include <vector>
#include <string>
#include "Common.h"
#include "wiimote_hid.h"
#include "EmuDeclarations.h"
#include "EmuDefinitions.h"
#include "Console.h" // for startConsoleWin, wprintf, GetConsoleHwnd
extern SWiimoteInitialize g_WiimoteInitialize;
//extern void __Log(int log, const char *format, ...);
//extern void __Log(int log, int v, const char *format, ...);
namespace WiiMoteEmu
{
//******************************************************************************
// Subroutines
//******************************************************************************
void HidOutputReport(u16 _channelID, wm_report* sr) {
LOGV(WII_IPC_WIIMOTE, 0, ">>>========================================================");
LOGV(WII_IPC_WIIMOTE, 0, "HidOutputReport(0x%02x)", sr->channel);
switch(sr->channel)
{
case 0x10:
LOGV(WII_IPC_WIIMOTE, 0, "HidOutputReport: unknown sr->channel 0x10");
break;
case WM_LEDS:
WmLeds(_channelID, (wm_leds*)sr->data);
break;
case WM_READ_DATA:
WmReadData(_channelID, (wm_read_data*)sr->data);
break;
case WM_REQUEST_STATUS:
WmRequestStatus(_channelID, (wm_request_status*)sr->data);
break;
case WM_IR_PIXEL_CLOCK:
case WM_IR_LOGIC:
LOGV(WII_IPC_WIIMOTE, 0, " IR Enable 0x%02x 0x%02x", sr->channel, sr->data[0]);
break;
case WM_WRITE_DATA:
WmWriteData(_channelID, (wm_write_data*)sr->data);
break;
case WM_DATA_REPORTING:
WmDataReporting(_channelID, (wm_data_reporting*)sr->data);
break;
case WM_SPEAKER_ENABLE:
LOGV(WII_IPC_WIIMOTE, 1, " WM Speaker Enable 0x%02x 0x%02x", sr->channel, sr->data[0]);
break;
case WM_SPEAKER_MUTE:
LOGV(WII_IPC_WIIMOTE, 1, " WM Mute Enable 0x%02x 0x%02x", sr->channel, sr->data[0]);
break;
default:
PanicAlert("HidOutputReport: Unknown channel 0x%02x", sr->channel);
return;
}
LOGV(WII_IPC_WIIMOTE, 0, "===========================================================");
}
void WmLeds(u16 _channelID, wm_leds* leds) {
LOG(WII_IPC_WIIMOTE, " Set LEDs");
LOG(WII_IPC_WIIMOTE, " Leds: %x", leds->leds);
LOG(WII_IPC_WIIMOTE, " Rumble: %x", leds->rumble);
g_Leds = leds->leds;
}
void WmSendAck(u16 _channelID, u8 _reportID)
{
u8 DataFrame[1024];
u32 Offset = 0;
// header
hid_packet* pHidHeader = (hid_packet*)(DataFrame + Offset);
pHidHeader->type = HID_TYPE_DATA;
pHidHeader->param = HID_PARAM_INPUT;
Offset += sizeof(hid_packet);
wm_acknowledge* pData = (wm_acknowledge*)(DataFrame + Offset);
pData->Channel = WM_WRITE_DATA_REPLY;
pData->unk0 = 0;
pData->unk1 = 0;
pData->reportID = _reportID;
pData->errorID = 0;
Offset += sizeof(wm_acknowledge);
LOGV(WII_IPC_WIIMOTE, 2, " WMSendAck()");
g_WiimoteInitialize.pWiimoteInput(_channelID, DataFrame, Offset);
}
void WmDataReporting(u16 _channelID, wm_data_reporting* dr)
{
LOG(WII_IPC_WIIMOTE, " Set Data reporting mode");
LOG(WII_IPC_WIIMOTE, " Rumble: %x", dr->rumble);
LOG(WII_IPC_WIIMOTE, " Continuous: %x", dr->continuous);
LOG(WII_IPC_WIIMOTE, " All The Time: %x (not only on data change)", dr->all_the_time);
LOG(WII_IPC_WIIMOTE, " Rumble: %x", dr->rumble);
LOG(WII_IPC_WIIMOTE, " Mode: 0x%02x", dr->mode);
g_ReportingMode = dr->mode;
g_ReportingChannel = _channelID;
switch(dr->mode) { //see Wiimote_Update()
case WM_REPORT_CORE:
case WM_REPORT_CORE_ACCEL:
case WM_REPORT_CORE_ACCEL_IR12:
case WM_REPORT_CORE_ACCEL_IR10_EXT6:
break;
default:
PanicAlert("Wiimote: Unknown reporting mode 0x%x", dr->mode);
}
// WmSendAck(_channelID, WM_DATA_REPORTING);
}
void SendReportCore(u16 _channelID)
{
u8 DataFrame[1024];
u32 Offset = WriteWmReport(DataFrame, WM_REPORT_CORE);
wm_report_core* pReport = (wm_report_core*)(DataFrame + Offset);
Offset += sizeof(wm_report_core);
memset(pReport, 0, sizeof(wm_report_core));
FillReportInfo(pReport->c);
LOG(WII_IPC_WIIMOTE, " SendReportCore()");
g_WiimoteInitialize.pWiimoteInput(_channelID, DataFrame, Offset);
}
void SendReportCoreAccelIr12(u16 _channelID) {
u8 DataFrame[1024];
u32 Offset = WriteWmReport(DataFrame, WM_REPORT_CORE_ACCEL_IR12);
wm_report_core_accel_ir12* pReport = (wm_report_core_accel_ir12*)(DataFrame + Offset);
Offset += sizeof(wm_report_core_accel_ir12);
memset(pReport, 0, sizeof(wm_report_core_accel_ir12));
FillReportInfo(pReport->c);
FillReportAcc(pReport->a);
FillReportIR(pReport->ir[0], pReport->ir[1]);
LOGV(WII_IPC_WIIMOTE, 2, " SendReportCoreAccelIr12()");
g_WiimoteInitialize.pWiimoteInput(_channelID, DataFrame, Offset);
}
void SendReportCoreAccelIr10Ext(u16 _channelID)
{
u8 DataFrame[1024];
u32 Offset = WriteWmReport(DataFrame, WM_REPORT_CORE_ACCEL_IR10_EXT6);
wm_report_core_accel_ir10_ext6* pReport = (wm_report_core_accel_ir10_ext6*)(DataFrame + Offset);
Offset += sizeof(wm_report_core_accel_ir10_ext6);
memset(pReport, 0, sizeof(wm_report_core_accel_ir10_ext6));
FillReportInfo(pReport->c);
FillReportAcc(pReport->a);
FillReportIRBasic(pReport->ir[0], pReport->ir[1]);
LOG(WII_IPC_WIIMOTE, " SendReportCoreAccelIr10Ext()");
g_WiimoteInitialize.pWiimoteInput(_channelID, DataFrame, Offset);
}
void SendReportCoreAccel(u16 _channelID)
{
u8 DataFrame[1024];
u32 Offset = WriteWmReport(DataFrame, WM_REPORT_CORE_ACCEL);
wm_report_core_accel* pReport = (wm_report_core_accel*)(DataFrame + Offset);
Offset += sizeof(wm_report_core_accel);
memset(pReport, 0, sizeof(wm_report_core_accel));
FillReportInfo(pReport->c);
FillReportAcc(pReport->a);
LOG(WII_IPC_WIIMOTE, " SendReportCoreAccel()");
g_WiimoteInitialize.pWiimoteInput(_channelID, DataFrame, Offset);
}
void WmReadData(u16 _channelID, wm_read_data* rd)
{
LOGV(WII_IPC_WIIMOTE, 0, ">>>========================================================");
u32 address = convert24bit(rd->address);
u16 size = convert16bit(rd->size);
LOG(WII_IPC_WIIMOTE, " Read data");
LOG(WII_IPC_WIIMOTE, " Address space: %x", rd->space);
LOG(WII_IPC_WIIMOTE, " Address: 0x%06x", address);
LOG(WII_IPC_WIIMOTE, " Size: 0x%04x", size);
LOG(WII_IPC_WIIMOTE, " Rumble: %x", rd->rumble);
if(rd->space == 0)
{
if (address + size > WIIMOTE_EEPROM_SIZE)
{
PanicAlert("WmReadData: address + size out of bounds!");
return;
}
SendReadDataReply(_channelID, g_Eeprom+address, address, (u8)size);
}
else if(rd->space == WM_SPACE_REGS1 || rd->space == WM_SPACE_REGS2)
{
u8* block;
u32 blockSize;
switch((address >> 16) & 0xFE)
{
/* case 0xA2:
block = g_RegSpeaker;
blockSize = WIIMOTE_REG_SPEAKER_SIZE;
break;*/
case 0xA4:
block = g_RegExt;
blockSize = WIIMOTE_REG_EXT_SIZE;
//PanicAlert("WmReadData: 0xA4 g_RegExt");
LOGV(WII_IPC_WIIMOTE, 0, "WmReadData: 0xA4 g_RegExt");
break;
/* case 0xB0:
block = g_RegIr;
blockSize = WIIMOTE_REG_IR_SIZE;
//PanicAlert("WmReadData: 0xB0 g_RegIr");
LOGV(WII_IPC_WIIMOTE, 0, "WmReadData: 0xB0 g_RegIr");
break;*/
default:
PanicAlert("WmWriteData: bad register block!");
return;
}
address &= 0xFFFF;
if(address + size > blockSize) {
PanicAlert("WmReadData: address + size out of bounds!");
return;
}
SendReadDataReply(_channelID, block+address, address, (u8)size);
}
else
{
PanicAlert("WmReadData: unimplemented parameters (size: %i, addr: 0x%x!", size, rd->space);
}
LOGV(WII_IPC_WIIMOTE, 0, ">>>========================================================");
}
void WmWriteData(u16 _channelID, wm_write_data* wd)
{
u32 address = convert24bit(wd->address);
LOG(WII_IPC_WIIMOTE, " Write data");
LOG(WII_IPC_WIIMOTE, " Address space: %x", wd->space);
LOG(WII_IPC_WIIMOTE, " Address: 0x%06x", address);
LOG(WII_IPC_WIIMOTE, " Size: 0x%02x", wd->size);
LOG(WII_IPC_WIIMOTE, " Rumble: %x", wd->rumble);
if(wd->size <= 16 && wd->space == WM_SPACE_EEPROM)
{
if(address + wd->size > WIIMOTE_EEPROM_SIZE) {
PanicAlert("WmWriteData: address + size out of bounds!");
return;
}
memcpy(g_Eeprom + address, wd->data, wd->size);
// WmSendAck(_channelID, WM_WRITE_DATA);
}
else if(wd->size <= 16 && (wd->space == WM_SPACE_REGS1 || wd->space == WM_SPACE_REGS2))
{
u8* block;
u32 blockSize;
switch((address >> 16) & 0xFE) {
case 0xA2:
block = g_RegSpeaker;
blockSize = WIIMOTE_REG_SPEAKER_SIZE;
break;
case 0xA4:
block = g_RegExt;
blockSize = WIIMOTE_REG_EXT_SIZE;
break;
case 0xB0:
block = g_RegIr;
blockSize = WIIMOTE_REG_IR_SIZE;
break;
default:
PanicAlert("WmWriteData: bad register block!");
return;
}
address &= 0xFFFF;
if(address + wd->size > blockSize) {
PanicAlert("WmWriteData: address + size out of bounds!");
return;
}
memcpy(wd->data, block + address, wd->size);
} else {
PanicAlert("WmWriteData: unimplemented parameters!");
}
// just added for home brew.... hmmmm
WmSendAck(_channelID, WM_WRITE_DATA);
}
int WriteWmReport(u8* dst, u8 channel) {
u32 Offset = 0;
hid_packet* pHidHeader = (hid_packet*)(dst + Offset);
Offset += sizeof(hid_packet);
pHidHeader->type = HID_TYPE_DATA;
pHidHeader->param = HID_PARAM_INPUT;
wm_report* pReport = (wm_report*)(dst + Offset);
Offset += sizeof(wm_report);
pReport->channel = channel;
return Offset;
}
void WmRequestStatus(u16 _channelID, wm_request_status* rs)
{
//PanicAlert("WmRequestStatus");
LOGV(WII_IPC_WIIMOTE, 0, ">>>======================================");
LOGV(WII_IPC_WIIMOTE, 0, " Request Status");
LOG(WII_IPC_WIIMOTE, " Rumble: %x", rs->rumble);
//SendStatusReport();
u8 DataFrame[1024];
u32 Offset = WriteWmReport(DataFrame, WM_STATUS_REPORT);
wm_status_report* pStatus = (wm_status_report*)(DataFrame + Offset);
Offset += sizeof(wm_status_report);
memset(pStatus, 0, sizeof(wm_status_report));
pStatus->leds = g_Leds;
pStatus->ir = 1;
pStatus->battery = 0x4F; //arbitrary number
// this gets us passed the first error, but later brings up the disconnected error
pStatus->extension = 1;
LOGV(WII_IPC_WIIMOTE, 0," SendStatusReport()");
LOGV(WII_IPC_WIIMOTE, 0, " Flags: 0x%02x", pStatus->padding1[2]);
LOGV(WII_IPC_WIIMOTE, 0, " Battery: %d", pStatus->battery);
g_WiimoteInitialize.pWiimoteInput(_channelID, DataFrame, Offset);
LOGV(WII_IPC_WIIMOTE, 0, "==========================================");
}
void SendReadDataReply(u16 _channelID, void* _Base, u16 _Address, u8 _Size)
{
LOGV(WII_IPC_WIIMOTE, 0, ">>>======================================");
int dataOffset = 0;
while (_Size > 0)
{
u8 DataFrame[1024];
u32 Offset = WriteWmReport(DataFrame, WM_READ_DATA_REPLY);
int copySize = _Size;
if (copySize > 16)
{
copySize = 16;
}
wm_read_data_reply* pReply = (wm_read_data_reply*)(DataFrame + Offset);
Offset += sizeof(wm_read_data_reply);
pReply->buttons = 0;
pReply->error = 0;
pReply->size = (copySize - 1) & 0xF;
pReply->address = Common::swap16(_Address + dataOffset);
memcpy(pReply->data + dataOffset, _Base, copySize);
if(copySize < 16)
{
memset(pReply->data + copySize, 0, 16 - copySize);
}
dataOffset += copySize;
LOG(WII_IPC_WIIMOTE, " SendReadDataReply()");
LOG(WII_IPC_WIIMOTE, " Buttons: 0x%04x", pReply->buttons);
LOG(WII_IPC_WIIMOTE, " Error: 0x%x", pReply->error);
LOG(WII_IPC_WIIMOTE, " Size: 0x%x", pReply->size);
LOG(WII_IPC_WIIMOTE, " Address: 0x%04x", pReply->address);
g_WiimoteInitialize.pWiimoteInput(_channelID, DataFrame, Offset);
_Size -= copySize;
}
if (_Size != 0)
{
PanicAlert("WiiMote-Plugin: SendReadDataReply() failed");
}
LOGV(WII_IPC_WIIMOTE, 0, "==========================================");
}
} // end of namespace

View File

@ -0,0 +1,406 @@
// Copyright (C) 2003-2008 Dolphin Project.
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, version 2.0.
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License 2.0 for more details.
// A copy of the GPL 2.0 should have been included with the program.
// If not, see http://www.gnu.org/licenses/
// Official SVN repository and contact information can be found at
// http://code.google.com/p/dolphin-emu/
#include "pluginspecs_wiimote.h"
#include <vector>
#include <string>
#include "Common.h"
#include "wiimote_hid.h"
#include "EmuDeclarations.h"
#include "EmuDefinitions.h"
#include "Console.h" // for startConsoleWin, wprintf, GetConsoleHwnd
extern SWiimoteInitialize g_WiimoteInitialize;
//extern void __Log(int log, const char *format, ...);
//extern void __Log(int log, int v, const char *format, ...);
namespace WiiMoteEmu
{
//******************************************************************************
// Subroutines
//******************************************************************************
bool toggleSideWays = false;
void FillReportInfo(wm_core& _core)
{
memset(&_core, 0x00, sizeof(wm_core));
#ifdef _WIN32
// allow both mouse buttons and keyboard to press a and b
if(GetAsyncKeyState(VK_LBUTTON) ? 1 : 0 || GetAsyncKeyState('A') ? 1 : 0)
_core.a = 1;
if(GetAsyncKeyState(VK_LBUTTON) ? 1 : 0 || GetAsyncKeyState('B') ? 1 : 0)
_core.b = 1;
_core.one = GetAsyncKeyState('1') ? 1 : 0;
_core.two = GetAsyncKeyState('2') ? 1 : 0;
_core.plus = GetAsyncKeyState('P') ? 1 : 0;
_core.minus = GetAsyncKeyState('M') ? 1 : 0;
_core.home = GetAsyncKeyState('H') ? 1 : 0;
if(GetAsyncKeyState('T'))
{
PanicAlert("You turned %s sideways controls", toggleSideWays ? "off" : "on");
toggleSideWays = !toggleSideWays;
}
/* Sideways controls (for example for Wario Land) was not enabled automatically
so I have to use this function. I'm not sure how it works on the actual Wii.
*/
if(toggleSideWays)
{
_core.left = GetAsyncKeyState(VK_DOWN) ? 1 : 0;
_core.up = GetAsyncKeyState(VK_LEFT) ? 1 : 0;
_core.right = GetAsyncKeyState(VK_UP) ? 1 : 0;
_core.down = GetAsyncKeyState(VK_RIGHT) ? 1 : 0;
}
else
{
_core.left = GetAsyncKeyState(VK_LEFT) ? 1 : 0;
_core.up = GetAsyncKeyState(VK_UP) ? 1 : 0;
_core.right = GetAsyncKeyState(VK_RIGHT) ? 1 : 0;
_core.down = GetAsyncKeyState(VK_DOWN) ? 1 : 0;
}
#else
// TODO: fill in
#endif
}
// -----------------------------
// Global declarations for FillReportAcc. The accelerometer x, y and z values range from
// 0x00 to 0xff with [y = 0x80, x = 0x80, z ~ 0xa0] being neutral and 0x00 being (-)
// and 0xff being (+). Or does it not? It's important that all values are not 0x80,
// the the mouse pointer can disappear from the screen permanently, until z is adjusted
// back.
// ----------
// the variables are global so they can be changed during debugging
//int A = 0, B = 128, C = 64; // for debugging
//int a = 1, b = 1, c = 2, d = -2; // for debugging
//int consoleDisplay = 0;
int X = 0x80, Y = 0x80, Z = 160; // neutral values
u8 x = 0x0, y = 0x0, z = 0x00;
int shake = -1, yhistsize = 15; // for the shake function
std::vector<u8> yhist(15); // for the tilt function
void FillReportAcc(wm_accel& _acc)
{
// -----------------------------
// Wiimote to Gamepad translations
// ----------
// Tilting Wiimote (Wario Land aiming, Mario Kart steering) : For some reason 150 and 40
// seemed like decent starting values.
if(GetAsyncKeyState('3'))
{
//if(a < 128) // for debugging
if(y < 250)
{
y += 4; // aim left
//a += c; // debugging values
//y = A + a; // aim left
}
}
else if(GetAsyncKeyState('4'))
{
// if(b < 128) // for debugging
if(y > 5)
{
y -= 4; // aim right
//b -= d; // debugging values
//y = B + b;
}
}
// Single shake of Wiimote while holding it sideways (Wario Land pound ground)
/*
if(GetAsyncKeyState('S'))
z = 0;
else
z = Z;
*/
if(GetAsyncKeyState('S'))
{
z = 0;
y = 0;
shake = 2;
}
else if(shake == 2)
{
z = 128;
y = 0;
shake = 1;
}
else if(shake == 1)
{
z = Z;
y = Y;
shake = -1;
}
// ----------
// -----------------------------
// For tilting: add new value and move all back
// ----------
bool ypressed = false;
yhist[yhist.size() - 1] = (
GetAsyncKeyState('3') ? true : false
|| GetAsyncKeyState('4') ? true : false
|| shake > 0
);
if(yhistsize > yhist.size()) yhistsize = yhist.size();
for (int i = 1; i < yhistsize; i++)
{
yhist[i-1] = yhist[i];
if(yhist[i]) ypressed = true;
}
if(!ypressed) // y was not pressed a single time
{
y = Y;
//a = 0; // for debugging
//b = 0;
}
else if(!GetAsyncKeyState('3') && !GetAsyncKeyState('4'))
{
// perhaps start dropping acceleration back?
}
// ----------
// Write values
_acc.x = X;
_acc.y = y;
_acc.z = z;
// ----------------------------
// Debugging for translating Wiimote to Keyboard (or Gamepad)
// ----------
/*
// Toogle console display
if(GetAsyncKeyState('U'))
{
if(consoleDisplay < 2)
consoleDisplay ++;
else
consoleDisplay = 0;
}
if(GetAsyncKeyState('5'))
A-=1;
else if(GetAsyncKeyState('6'))
A+=1;
if(GetAsyncKeyState('7'))
B-=1;
else if(GetAsyncKeyState('8'))
B+=1;
if(GetAsyncKeyState('9'))
C-=1;
else if(GetAsyncKeyState('0'))
C+=1;
else if(GetAsyncKeyState(VK_INSERT))
a-=1;
else if(GetAsyncKeyState(VK_DELETE))
a+=1;
else if(GetAsyncKeyState(VK_HOME))
b-=1;
else if(GetAsyncKeyState(VK_END))
b+=1;
else if(GetAsyncKeyState(VK_SHIFT))
c-=1;
else if(GetAsyncKeyState(VK_CONTROL))
c+=1;
else if(GetAsyncKeyState(VK_NUMPAD3))
d-=1;
else if(GetAsyncKeyState(VK_NUMPAD6))
d+=1;
else if(GetAsyncKeyState(VK_ADD))
yhistsize-=1;
else if(GetAsyncKeyState(VK_SUBTRACT))
yhistsize+=1;
if(GetAsyncKeyState(VK_NUMPAD1))
X+=1;
else if(GetAsyncKeyState(VK_NUMPAD2))
X-=1;
if(GetAsyncKeyState(VK_NUMPAD4))
Y+=1;
else if(GetAsyncKeyState(VK_NUMPAD5))
Y-=1;
if(GetAsyncKeyState(VK_NUMPAD7))
Z+=1;
else if(GetAsyncKeyState(VK_NUMPAD8))
Z-=1;
/*
if(GetAsyncKeyState('S'))
{
z = Z + C;
}
else
{
z = Z;
}
if(GetAsyncKeyState('D'))
{
y = Y + B;
}
else
{
y = Y;
}
if(GetAsyncKeyState('F'))
{
z = Z + C;
y = Y + B;
}
else if(!GetAsyncKeyState('S') && !GetAsyncKeyState('D'))
{
z = Z;
y = Y;
}
if(consoleDisplay == 0)
wprintf("x: %03i | y: %03i | z: %03i | A:%i B:%i C:%i a:%i b:%i c:%i d:%i X:%i Y:%i Z:%i\n", _acc.x, _acc.y, _acc.z,
A, B, C,
a, b, c, d,
X, Y, Z);
*/
}
/* DESCRIPTION: The calibration is controlled by these values, their absolute value and
the relative distance between between them control the calibration. These integers is
for the debugger so that we can calibrate the best values */
int Top = TOP, Left = LEFT, Right = RIGHT,
Bottom = BOTTOM, SensorBarRadius = SENSOR_BAR_RADIUS;
void FillReportIR(wm_ir_extended& _ir0, wm_ir_extended& _ir1)
{
memset(&_ir0, 0xFF, sizeof(wm_ir_extended));
memset(&_ir1, 0xFF, sizeof(wm_ir_extended));
float MouseX, MouseY;
GetMousePos(MouseX, MouseY);
int y0 = Top + (MouseY * (Bottom - Top));
int y1 = Top + (MouseY * (Bottom - Top));
int x0 = Left + (MouseX * (Right - Left)) - SensorBarRadius;
int x1 = Left + (MouseX * (Right - Left)) + SensorBarRadius;
x0 = 1023 - x0;
_ir0.x = x0 & 0xFF;
_ir0.y = y0 & 0xFF;
_ir0.size = 10;
_ir0.xHi = x0 >> 8;
_ir0.yHi = y0 >> 8;
x1 = 1023 - x1;
_ir1.x = x1;
_ir1.y = y1 & 0xFF;
_ir1.size = 10;
_ir1.xHi = x1 >> 8;
_ir1.yHi = y1 >> 8;
// ----------------------------
// Debugging for calibration
// ----------
/*
if(GetAsyncKeyState(VK_NUMPAD1))
Right +=1;
else if(GetAsyncKeyState(VK_NUMPAD2))
Right -=1;
if(GetAsyncKeyState(VK_NUMPAD4))
Left +=1;
else if(GetAsyncKeyState(VK_NUMPAD5))
Left -=1;
if(GetAsyncKeyState(VK_NUMPAD7))
Top += 1;
else if(GetAsyncKeyState(VK_NUMPAD8))
Top -= 1;
if(GetAsyncKeyState(VK_NUMPAD6))
Bottom += 1;
else if(GetAsyncKeyState(VK_NUMPAD3))
Bottom -= 1;
if(GetAsyncKeyState(VK_INSERT))
SensorBarRadius += 1;
else if(GetAsyncKeyState(VK_DELETE))
SensorBarRadius -= 1;
//ClearScreen();
if(consoleDisplay == 1)
wprintf("x0:%03i x1:%03i y0:%03i y1:%03i irx0:%03i y0:%03i x1:%03i y1:%03i | T:%i L:%i R:%i B:%i S:%i\n",
x0, x1, y0, y1, _ir0.x, _ir0.y, _ir1.x, _ir1.y, Top, Left, Right, Bottom, SensorBarRadius
);
*/
}
void FillReportIRBasic(wm_ir_basic& _ir0, wm_ir_basic& _ir1)
{
memset(&_ir0, 0xFF, sizeof(wm_ir_basic));
memset(&_ir1, 0xFF, sizeof(wm_ir_basic));
float MouseX, MouseY;
GetMousePos(MouseX, MouseY);
int y1 = TOP + (MouseY * (BOTTOM - TOP));
int y2 = TOP + (MouseY * (BOTTOM - TOP));
int x1 = LEFT + (MouseX * (RIGHT - LEFT)) - SENSOR_BAR_RADIUS;
int x2 = LEFT + (MouseX * (RIGHT - LEFT)) + SENSOR_BAR_RADIUS;
x1 = 1023 - x1;
_ir0.x1 = x1 & 0xFF;
_ir0.y1 = y1 & 0xFF;
_ir0.x1High = (x1 >> 8) & 0x3;
_ir0.y1High = (y1 >> 8) & 0x3;
x2 = 1023 - x2;
_ir1.x2 = x2 & 0xFF;
_ir1.y2 = y2 & 0xFF;
_ir1.x2High = (x2 >> 8) & 0x3;
_ir1.y2High = (y2 >> 8) & 0x3;
//ClearScreen();
/*
wprintf("x0:%03i | y0:%03i || x1:%03i | 0.y: %03i || 1.x: %03i | 1.y %03i\n", _ir0.x1, _ir0.y1,
_ir1.x2, _ir1.y2
);
*/
}
} // end of namespace

View File

@ -25,7 +25,7 @@
#include "pluginspecs_wiimote.h"
#include "wiimote_emu.h"
#include "EmuMain.h"
#include "wiimote_real.h"
#include "Console.h" // for startConsoleWin, wprintf, GetConsoleHwnd
@ -121,7 +121,7 @@ extern "C" void Wiimote_Initialize(SWiimoteInitialize _WiimoteInitialize)
WiiMoteEmu::Initialize();
// Debugging window
/*startConsoleWin(100, 30, "Wiimote"); // give room for 20 rows
/*startConsoleWin(160, 30, "Wiimote"); // give room for 20 rows
wprintf("Wiimote console opened\n");
MoveWindow(GetConsoleHwnd(), 0,400, 100*8,30*14, true); // move window, TODO: make this*/
}
@ -207,5 +207,18 @@ void __Log(int log, const char *_fmt, ...)
vsprintf( Msg, _fmt, ap );
va_end( ap );
g_WiimoteInitialize.pLog(Msg);
g_WiimoteInitialize.pLog(Msg, 0);
}
void __Logv(int log, int v, const char *_fmt, ...)
{
char Msg[512];
va_list ap;
va_start( ap, _fmt );
vsprintf( Msg, _fmt, ap );
va_end( ap );
g_WiimoteInitialize.pLog(Msg, v);
}

View File

@ -1,878 +0,0 @@
// Copyright (C) 2003-2008 Dolphin Project.
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, version 2.0.
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License 2.0 for more details.
// A copy of the GPL 2.0 should have been included with the program.
// If not, see http://www.gnu.org/licenses/
// Official SVN repository and contact information can be found at
// http://code.google.com/p/dolphin-emu/
#include "pluginspecs_wiimote.h"
#include <vector>
#include <string>
#include "common.h"
#include "wiimote_hid.h"
#include "Console.h" // for startConsoleWin, wprintf, GetConsoleHwnd
extern SWiimoteInitialize g_WiimoteInitialize;
extern void __Log(int log, const char *format, ...);
namespace WiiMoteEmu
{
//******************************************************************************
// Definitions and variable declarations
//******************************************************************************
//libogc bounding box, in smoothed IR coordinates: 232,284 792,704
//we'll use it to scale our mouse coordinates
#define LEFT 232
#define TOP 284
#define RIGHT 792
#define BOTTOM 704
#define SENSOR_BAR_RADIUS 200
// vars
#define WIIMOTE_EEPROM_SIZE (16*1024)
#define WIIMOTE_REG_SPEAKER_SIZE 10
#define WIIMOTE_REG_EXT_SIZE 0x100
#define WIIMOTE_REG_IR_SIZE 0x34
u8 g_Leds = 0x1;
u8 g_Eeprom[WIIMOTE_EEPROM_SIZE];
u8 g_RegSpeaker[WIIMOTE_REG_SPEAKER_SIZE];
u8 g_RegExt[WIIMOTE_REG_EXT_SIZE];
u8 g_RegIr[WIIMOTE_REG_IR_SIZE];
u8 g_ReportingMode;
u16 g_ReportingChannel;
static const u8 EepromData_0[] = {
0xA1, 0xAA, 0x8B, 0x99, 0xAE, 0x9E, 0x78, 0x30,
0xA7, 0x74, 0xD3, 0xA1, 0xAA, 0x8B, 0x99, 0xAE,
0x9E, 0x78, 0x30, 0xA7, 0x74, 0xD3, 0x82, 0x82,
0x82, 0x15, 0x9C, 0x9C, 0x9E, 0x38, 0x40, 0x3E,
0x82, 0x82, 0x82, 0x15, 0x9C, 0x9C, 0x9E, 0x38,
0x40, 0x3E
};
static const u8 EepromData_16D0[] = {
0x00, 0x00, 0x00, 0xFF, 0x11, 0xEE, 0x00, 0x00,
0x33, 0xCC, 0x44, 0xBB, 0x00, 0x00, 0x66, 0x99,
0x77, 0x88, 0x00, 0x00, 0x2B, 0x01, 0xE8, 0x13
};
//******************************************************************************
// Subroutine declarations
//******************************************************************************
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 WmDataReporting(u16 _channelID, wm_data_reporting* dr);
void SendReadDataReply(u16 _channelID, void* _Base, u16 _Address, u8 _Size);
void SendReportCoreAccel(u16 _channelID);
void SendReportCoreAccelIr12(u16 _channelID);
void SendReportCore(u16 _channelID);
void SendReportCoreAccelIr10Ext(u16 _channelID);
int WriteWmReport(u8* dst, u8 channel);
void WmSendAck(u16 _channelID, u8 _reportID);
static u32 convert24bit(const u8* src) {
return (src[0] << 16) | (src[1] << 8) | src[2];
}
static u16 convert16bit(const u8* src) {
return (src[0] << 8) | src[1];
}
void GetMousePos(float& x, float& y)
{
#ifdef _WIN32
POINT point;
GetCursorPos(&point);
ScreenToClient(g_WiimoteInitialize.hWnd, &point);
RECT Rect;
GetClientRect(g_WiimoteInitialize.hWnd, &Rect);
int width = Rect.right - Rect.left;
int height = Rect.bottom - Rect.top;
x = point.x / (float)width;
y = point.y / (float)height;
#else
x = 0.5f;
y = 0.5f;
#endif
}
void CryptBuffer(u8* _buffer, u8 _size)
{
for (int i=0; i<_size; i++)
{
_buffer[i] = ((_buffer[i] - 0x17) ^ 0x17) & 0xFF;
}
}
void WriteCryped16(u8* _baseBlock, u16 _address, u16 _value)
{
u16 cryptedValue = _value;
CryptBuffer((u8*)&cryptedValue, sizeof(u16));
*(u16*)(_baseBlock + _address) = cryptedValue;
}
void Initialize()
{
memset(g_Eeprom, 0, WIIMOTE_EEPROM_SIZE);
memcpy(g_Eeprom, EepromData_0, sizeof(EepromData_0));
memcpy(g_Eeprom + 0x16D0, EepromData_16D0, sizeof(EepromData_16D0));
g_ReportingMode = 0;
WriteCryped16(g_RegExt, 0xfe, 0x0000);
// g_RegExt[0xfd] = 0x1e;
// g_RegExt[0xfc] = 0x9a;
}
void DoState(void* ptr, int mode)
{
//TODO: implement
}
void Shutdown(void)
{
}
void InterruptChannel(u16 _channelID, const void* _pData, u32 _Size)
{
const u8* data = (const u8*)_pData;
// dump raw data
{
LOG(WII_IPC_WIIMOTE, "Wiimote_Input");
std::string Temp;
for (u32 j=0; j<_Size; j++)
{
char Buffer[128];
sprintf(Buffer, "%02x ", data[j]);
Temp.append(Buffer);
}
LOG(WII_IPC_WIIMOTE, " Data: %s", Temp.c_str());
}
hid_packet* hidp = (hid_packet*) data;
switch(hidp->type)
{
case HID_TYPE_DATA:
{
switch(hidp->param)
{
case HID_PARAM_OUTPUT:
{
wm_report* sr = (wm_report*)hidp->data;
WmSendAck(_channelID, sr->channel);
HidOutputReport(_channelID, sr);
}
break;
default:
PanicAlert("HidInput: HID_TYPE_DATA - param 0x%02x", hidp->type, hidp->param);
break;
}
}
break;
default:
PanicAlert("HidInput: Unknown type 0x%02x and param 0x%02x", hidp->type, hidp->param);
break;
}
}
void ControlChannel(u16 _channelID, const void* _pData, u32 _Size)
{
const u8* data = (const u8*)_pData;
// dump raw data
{
LOG(WII_IPC_WIIMOTE, "Wiimote_ControlChannel");
std::string Temp;
for (u32 j=0; j<_Size; j++)
{
char Buffer[128];
sprintf(Buffer, "%02x ", data[j]);
Temp.append(Buffer);
}
LOG(WII_IPC_WIIMOTE, " Data: %s", Temp.c_str());
}
hid_packet* hidp = (hid_packet*) data;
switch(hidp->type)
{
case HID_TYPE_HANDSHAKE:
if (hidp->param == HID_PARAM_INPUT)
{
PanicAlert("HID_TYPE_HANDSHAKE - HID_PARAM_INPUT");
}
else
{
PanicAlert("HID_TYPE_HANDSHAKE - HID_PARAM_OUTPUT");
}
break;
case HID_TYPE_SET_REPORT:
if (hidp->param == HID_PARAM_INPUT)
{
PanicAlert("HID_TYPE_SET_REPORT input");
}
else
{
HidOutputReport(_channelID, (wm_report*)hidp->data);
//return handshake
u8 handshake = 0;
g_WiimoteInitialize.pWiimoteInput(_channelID, &handshake, 1);
}
break;
case HID_TYPE_DATA:
PanicAlert("HID_TYPE_DATA %s", hidp->type, hidp->param == HID_PARAM_INPUT ? "input" : "output");
break;
default:
PanicAlert("HidControlChanel: Unknown type %x and param %x", hidp->type, hidp->param);
break;
}
}
void Update()
{
//LOG(WII_IPC_WIIMOTE, "Wiimote_Update");
switch(g_ReportingMode) {
case 0:
break;
case WM_REPORT_CORE: SendReportCore(g_ReportingChannel); break;
case WM_REPORT_CORE_ACCEL: SendReportCoreAccel(g_ReportingChannel); break;
case WM_REPORT_CORE_ACCEL_IR12: SendReportCoreAccelIr12(g_ReportingChannel);break;
case WM_REPORT_CORE_ACCEL_IR10_EXT6: SendReportCoreAccelIr10Ext(g_ReportingChannel);break;
}
// g_ReportingMode = 0;
}
//******************************************************************************
// Subroutines
//******************************************************************************
void HidOutputReport(u16 _channelID, wm_report* sr) {
LOG(WII_IPC_WIIMOTE, " HidOutputReport(0x%02x)", sr->channel);
switch(sr->channel)
{
case 0x10:
LOG(WII_IPC_WIIMOTE, "HidOutputReport: unknown sr->channel 0x10");
break;
case WM_LEDS:
WmLeds(_channelID, (wm_leds*)sr->data);
break;
case WM_READ_DATA:
WmReadData(_channelID, (wm_read_data*)sr->data);
break;
case WM_REQUEST_STATUS:
WmRequestStatus(_channelID, (wm_request_status*)sr->data);
break;
case WM_IR_PIXEL_CLOCK:
case WM_IR_LOGIC:
LOG(WII_IPC_WIIMOTE, " IR Enable 0x%02x 0x%02x", sr->channel, sr->data[0]);
break;
case WM_WRITE_DATA:
WmWriteData(_channelID, (wm_write_data*)sr->data);
break;
case WM_DATA_REPORTING:
WmDataReporting(_channelID, (wm_data_reporting*)sr->data);
break;
case WM_SPEAKER_ENABLE:
LOG(WII_IPC_WIIMOTE, " WM Speaker Enable 0x%02x 0x%02x", sr->channel, sr->data[0]);
break;
case WM_SPEAKER_MUTE:
LOG(WII_IPC_WIIMOTE, " WM Mute Enable 0x%02x 0x%02x", sr->channel, sr->data[0]);
break;
default:
PanicAlert("HidOutputReport: Unknown channel 0x%02x", sr->channel);
return;
}
}
void WmLeds(u16 _channelID, wm_leds* leds) {
LOG(WII_IPC_WIIMOTE, " Set LEDs");
LOG(WII_IPC_WIIMOTE, " Leds: %x", leds->leds);
LOG(WII_IPC_WIIMOTE, " Rumble: %x", leds->rumble);
g_Leds = leds->leds;
}
void WmSendAck(u16 _channelID, u8 _reportID)
{
u8 DataFrame[1024];
u32 Offset = 0;
// header
hid_packet* pHidHeader = (hid_packet*)(DataFrame + Offset);
pHidHeader->type = HID_TYPE_DATA;
pHidHeader->param = HID_PARAM_INPUT;
Offset += sizeof(hid_packet);
wm_acknowledge* pData = (wm_acknowledge*)(DataFrame + Offset);
pData->Channel = WM_WRITE_DATA_REPLY;
pData->unk0 = 0;
pData->unk1 = 0;
pData->reportID = _reportID;
pData->errorID = 0;
Offset += sizeof(wm_acknowledge);
LOG(WII_IPC_WIIMOTE, " WMSendAck()");
g_WiimoteInitialize.pWiimoteInput(_channelID, DataFrame, Offset);
}
void WmDataReporting(u16 _channelID, wm_data_reporting* dr)
{
LOG(WII_IPC_WIIMOTE, " Set Data reporting mode");
LOG(WII_IPC_WIIMOTE, " Rumble: %x", dr->rumble);
LOG(WII_IPC_WIIMOTE, " Continuous: %x", dr->continuous);
LOG(WII_IPC_WIIMOTE, " All The Time: %x (not only on data change)", dr->all_the_time);
LOG(WII_IPC_WIIMOTE, " Rumble: %x", dr->rumble);
LOG(WII_IPC_WIIMOTE, " Mode: 0x%02x", dr->mode);
g_ReportingMode = dr->mode;
g_ReportingChannel = _channelID;
switch(dr->mode) { //see Wiimote_Update()
case WM_REPORT_CORE:
case WM_REPORT_CORE_ACCEL:
case WM_REPORT_CORE_ACCEL_IR12:
case WM_REPORT_CORE_ACCEL_IR10_EXT6:
break;
default:
PanicAlert("Wiimote: Unknown reporting mode 0x%x", dr->mode);
}
// WmSendAck(_channelID, WM_DATA_REPORTING);
}
void FillReportInfo(wm_core& _core)
{
memset(&_core, 0x00, sizeof(wm_core));
#ifdef _WIN32
// allow both mouse buttons and keyboard to press a and b
if(GetAsyncKeyState(VK_LBUTTON) ? 1 : 0 || GetAsyncKeyState('A') ? 1 : 0)
_core.a = 1;
if(GetAsyncKeyState(VK_LBUTTON) ? 1 : 0 || GetAsyncKeyState('B') ? 1 : 0)
_core.b = 1;
_core.one = GetAsyncKeyState('1') ? 1 : 0;
_core.two = GetAsyncKeyState('2') ? 1 : 0;
_core.plus = GetAsyncKeyState('P') ? 1 : 0;
_core.minus = GetAsyncKeyState('M') ? 1 : 0;
_core.home = GetAsyncKeyState('H') ? 1 : 0;
// these had to be shuffled around a little bit
_core.left = GetAsyncKeyState(VK_DOWN) ? 1 : 0;
_core.up = GetAsyncKeyState(VK_LEFT) ? 1 : 0;
_core.right = GetAsyncKeyState(VK_UP) ? 1 : 0;
_core.down = GetAsyncKeyState(VK_RIGHT) ? 1 : 0;
#else
// TODO: fill in
#endif
}
// -----------------------------
// Global declarations for FillReportAcc. The accelerometer x, y and z values range from
// 0x00 to 0xff with 0x80 being neutral and 0x00 being - and 0xff being +
// ----------
//int A = 64, B = 64, C = 64; // for debugging
int X = 0x80, Y = 0x80, Z = 0x80; // global so they can be changed during debugging
u8 x = 0x80, y = 0x80, z = 0x80;
int shake = -1; // for the shake function
std::vector<u8> yhist(15); // for the tilt function
void FillReportAcc(wm_accel& _acc)
{
// -----------------------------
// Wiimote to Gamepad translations
// ----------
// Tilting Wiimote (Wario Land aiming, Mario Kart steering)
if(GetAsyncKeyState('3'))
y+=2; // aim left
else if(GetAsyncKeyState('4'))
y-=2; // aim right
// Single shake of Wiimote while holding it sideways (Wario Land pound ground)
if(GetAsyncKeyState('S'))
{
z = 0;
y = 0;
shake = 2;
}
else if(shake == 2)
{
z = 128;
y = 0;
shake = 1;
}
else if(shake == 1)
{
z = Z;
y = Y;
shake = -1;
}
// ----------
// -----------------------------
// Add new value and move all back
// ----------
bool ypressed = false;
yhist[yhist.size() - 1] = (
GetAsyncKeyState('3') ? true : false
|| GetAsyncKeyState('4') ? true : false
|| shake > 0
);
for (int i = 1; i < yhist.size(); i++)
{
yhist[i-1] = yhist[i];
if(yhist[i]) ypressed = true;
}
if(!ypressed) // y was not pressed a single time
{
y = Y;
}
// ----------
// Write values
_acc.x = X;
_acc.y = y;
_acc.z = z;
// ----------------------------
// Debugging for translating Wiimote to Gamepad
// ----------
/*
if(GetAsyncKeyState('5'))
A-=8;
else if(GetAsyncKeyState('6'))
A+=8;
if(GetAsyncKeyState('7'))
B-=8;
else if(GetAsyncKeyState('8'))
B+=8;
if(GetAsyncKeyState('9'))
C-=8;
else if(GetAsyncKeyState('0'))
C+=8;
if(GetAsyncKeyState(VK_NUMPAD1))
X+=8;
else if(GetAsyncKeyState(VK_NUMPAD2))
X-=8;
if(GetAsyncKeyState(VK_NUMPAD4))
Y+=8;
else if(GetAsyncKeyState(VK_NUMPAD5))
Y-=8;
if(GetAsyncKeyState(VK_NUMPAD7))
Z+=8;
else if(GetAsyncKeyState(VK_NUMPAD8))
Z-=8;
if(GetAsyncKeyState('S'))
{
z = Z + C;
}
else
{
z = Z;
}
if(GetAsyncKeyState('D'))
{
y = Y + B;
}
else
{
y = Y;
}
if(GetAsyncKeyState('F'))
{
z = Z + C;
y = Y + B;
}
else if(!GetAsyncKeyState('S') && !GetAsyncKeyState('D'))
{
z = Z;
y = Y;
}
wprintf("x: %03i | y: %03i | z: %03i | A:%i B:%i C:%i X:%i Y:%i Z:%i\n", _acc.x, _acc.y, _acc.z,
A, B, C,
X, Y, Z);
*/
}
void FillReportIR(wm_ir_extended& _ir0, wm_ir_extended& _ir1)
{
memset(&_ir0, 0xFF, sizeof(wm_ir_extended));
memset(&_ir1, 0xFF, sizeof(wm_ir_extended));
float MouseX, MouseY;
GetMousePos(MouseX, MouseY);
int y0 = TOP + (MouseY * (BOTTOM - TOP));
int y1 = TOP + (MouseY * (BOTTOM - TOP));
int x0 = LEFT + (MouseX * (RIGHT - LEFT)) - SENSOR_BAR_RADIUS;
int x1 = LEFT + (MouseX * (RIGHT - LEFT)) + SENSOR_BAR_RADIUS;
x0 = 1023 - x0;
_ir0.x = x0 & 0xFF;
_ir0.y = y0 & 0xFF;
_ir0.size = 10;
_ir0.xHi = x0 >> 8;
_ir0.yHi = y0 >> 8;
x1 = 1023 - x1;
_ir1.x = x1;
_ir1.y = y1 & 0xFF;
_ir1.size = 10;
_ir1.xHi = x1 >> 8;
_ir1.yHi = y1 >> 8;
}
void FillReportIRBasic(wm_ir_basic& _ir0, wm_ir_basic& _ir1)
{
memset(&_ir0, 0xFF, sizeof(wm_ir_basic));
memset(&_ir1, 0xFF, sizeof(wm_ir_basic));
float MouseX, MouseY;
GetMousePos(MouseX, MouseY);
int y1 = TOP + (MouseY * (BOTTOM - TOP));
int y2 = TOP + (MouseY * (BOTTOM - TOP));
int x1 = LEFT + (MouseX * (RIGHT - LEFT)) - SENSOR_BAR_RADIUS;
int x2 = LEFT + (MouseX * (RIGHT - LEFT)) + SENSOR_BAR_RADIUS;
x1 = 1023 - x1;
_ir0.x1 = x1 & 0xFF;
_ir0.y1 = y1 & 0xFF;
_ir0.x1High = (x1 >> 8) & 0x3;
_ir0.y1High = (y1 >> 8) & 0x3;
x2 = 1023 - x2;
_ir1.x2 = x2 & 0xFF;
_ir1.y2 = y2 & 0xFF;
_ir1.x2High = (x2 >> 8) & 0x3;
_ir1.y2High = (y2 >> 8) & 0x3;
}
void SendReportCore(u16 _channelID)
{
u8 DataFrame[1024];
u32 Offset = WriteWmReport(DataFrame, WM_REPORT_CORE);
wm_report_core* pReport = (wm_report_core*)(DataFrame + Offset);
Offset += sizeof(wm_report_core);
memset(pReport, 0, sizeof(wm_report_core));
FillReportInfo(pReport->c);
LOG(WII_IPC_WIIMOTE, " SendReportCore()");
g_WiimoteInitialize.pWiimoteInput(_channelID, DataFrame, Offset);
}
void SendReportCoreAccelIr12(u16 _channelID) {
u8 DataFrame[1024];
u32 Offset = WriteWmReport(DataFrame, WM_REPORT_CORE_ACCEL_IR12);
wm_report_core_accel_ir12* pReport = (wm_report_core_accel_ir12*)(DataFrame + Offset);
Offset += sizeof(wm_report_core_accel_ir12);
memset(pReport, 0, sizeof(wm_report_core_accel_ir12));
FillReportInfo(pReport->c);
FillReportAcc(pReport->a);
FillReportIR(pReport->ir[0], pReport->ir[1]);
LOG(WII_IPC_WIIMOTE, " SendReportCoreAccelIr12()");
g_WiimoteInitialize.pWiimoteInput(_channelID, DataFrame, Offset);
}
void SendReportCoreAccelIr10Ext(u16 _channelID)
{
u8 DataFrame[1024];
u32 Offset = WriteWmReport(DataFrame, WM_REPORT_CORE_ACCEL_IR10_EXT6);
wm_report_core_accel_ir10_ext6* pReport = (wm_report_core_accel_ir10_ext6*)(DataFrame + Offset);
Offset += sizeof(wm_report_core_accel_ir10_ext6);
memset(pReport, 0, sizeof(wm_report_core_accel_ir10_ext6));
FillReportInfo(pReport->c);
FillReportAcc(pReport->a);
FillReportIRBasic(pReport->ir[0], pReport->ir[1]);
LOG(WII_IPC_WIIMOTE, " SendReportCoreAccelIr10Ext()");
g_WiimoteInitialize.pWiimoteInput(_channelID, DataFrame, Offset);
}
void SendReportCoreAccel(u16 _channelID)
{
u8 DataFrame[1024];
u32 Offset = WriteWmReport(DataFrame, WM_REPORT_CORE_ACCEL);
wm_report_core_accel* pReport = (wm_report_core_accel*)(DataFrame + Offset);
Offset += sizeof(wm_report_core_accel);
memset(pReport, 0, sizeof(wm_report_core_accel));
FillReportInfo(pReport->c);
FillReportAcc(pReport->a);
LOG(WII_IPC_WIIMOTE, " SendReportCoreAccel()");
g_WiimoteInitialize.pWiimoteInput(_channelID, DataFrame, Offset);
}
void WmReadData(u16 _channelID, wm_read_data* rd)
{
u32 address = convert24bit(rd->address);
u16 size = convert16bit(rd->size);
LOG(WII_IPC_WIIMOTE, " Read data");
LOG(WII_IPC_WIIMOTE, " Address space: %x", rd->space);
LOG(WII_IPC_WIIMOTE, " Address: 0x%06x", address);
LOG(WII_IPC_WIIMOTE, " Size: 0x%04x", size);
LOG(WII_IPC_WIIMOTE, " Rumble: %x", rd->rumble);
if(rd->space == 0)
{
if (address + size > WIIMOTE_EEPROM_SIZE)
{
PanicAlert("WmReadData: address + size out of bounds!");
return;
}
SendReadDataReply(_channelID, g_Eeprom+address, address, (u8)size);
}
else if(rd->space == WM_SPACE_REGS1 || rd->space == WM_SPACE_REGS2)
{
u8* block;
u32 blockSize;
switch((address >> 16) & 0xFE)
{
/* case 0xA2:
block = g_RegSpeaker;
blockSize = WIIMOTE_REG_SPEAKER_SIZE;
break;*/
case 0xA4:
block = g_RegExt;
blockSize = WIIMOTE_REG_EXT_SIZE;
PanicAlert("fsfsd");
break;
/* case 0xB0:
block = g_RegIr;
blockSize = WIIMOTE_REG_IR_SIZE;
break;*/
default:
PanicAlert("WmWriteData: bad register block!");
return;
}
address &= 0xFFFF;
if(address + size > blockSize) {
PanicAlert("WmReadData: address + size out of bounds!");
return;
}
SendReadDataReply(_channelID, block+address, address, (u8)size);
}
else
{
PanicAlert("WmReadData: unimplemented parameters (size: %i, addr: 0x%x!", size, rd->space);
}
}
void WmWriteData(u16 _channelID, wm_write_data* wd)
{
u32 address = convert24bit(wd->address);
LOG(WII_IPC_WIIMOTE, " Write data");
LOG(WII_IPC_WIIMOTE, " Address space: %x", wd->space);
LOG(WII_IPC_WIIMOTE, " Address: 0x%06x", address);
LOG(WII_IPC_WIIMOTE, " Size: 0x%02x", wd->size);
LOG(WII_IPC_WIIMOTE, " Rumble: %x", wd->rumble);
if(wd->size <= 16 && wd->space == WM_SPACE_EEPROM)
{
if(address + wd->size > WIIMOTE_EEPROM_SIZE) {
PanicAlert("WmWriteData: address + size out of bounds!");
return;
}
memcpy(g_Eeprom + address, wd->data, wd->size);
// WmSendAck(_channelID, WM_WRITE_DATA);
}
else if(wd->size <= 16 && (wd->space == WM_SPACE_REGS1 || wd->space == WM_SPACE_REGS2))
{
u8* block;
u32 blockSize;
switch((address >> 16) & 0xFE) {
case 0xA2:
block = g_RegSpeaker;
blockSize = WIIMOTE_REG_SPEAKER_SIZE;
break;
case 0xA4:
block = g_RegExt;
blockSize = WIIMOTE_REG_EXT_SIZE;
break;
case 0xB0:
block = g_RegIr;
blockSize = WIIMOTE_REG_IR_SIZE;
break;
default:
PanicAlert("WmWriteData: bad register block!");
return;
}
address &= 0xFFFF;
if(address + wd->size > blockSize) {
PanicAlert("WmWriteData: address + size out of bounds!");
return;
}
memcpy(wd->data, block + address, wd->size);
} else {
PanicAlert("WmWriteData: unimplemented parameters!");
}
// just added for home brew.... hmmmm
WmSendAck(_channelID, WM_WRITE_DATA);
}
int WriteWmReport(u8* dst, u8 channel) {
u32 Offset = 0;
hid_packet* pHidHeader = (hid_packet*)(dst + Offset);
Offset += sizeof(hid_packet);
pHidHeader->type = HID_TYPE_DATA;
pHidHeader->param = HID_PARAM_INPUT;
wm_report* pReport = (wm_report*)(dst + Offset);
Offset += sizeof(wm_report);
pReport->channel = channel;
return Offset;
}
void WmRequestStatus(u16 _channelID, wm_request_status* rs) {
LOG(WII_IPC_WIIMOTE, " Request Status");
LOG(WII_IPC_WIIMOTE, " Rumble: %x", rs->rumble);
//SendStatusReport();
u8 DataFrame[1024];
u32 Offset = WriteWmReport(DataFrame, WM_STATUS_REPORT);
wm_status_report* pStatus = (wm_status_report*)(DataFrame + Offset);
Offset += sizeof(wm_status_report);
memset(pStatus, 0, sizeof(wm_status_report));
pStatus->leds = g_Leds;
pStatus->ir = 1;
pStatus->battery = 0x4F; //arbitrary number
pStatus->extension = 0;
LOG(WII_IPC_WIIMOTE, " SendStatusReport()");
LOG(WII_IPC_WIIMOTE, " Flags: 0x%02x", pStatus->padding1[2]);
LOG(WII_IPC_WIIMOTE, " Battery: %d", pStatus->battery);
g_WiimoteInitialize.pWiimoteInput(_channelID, DataFrame, Offset);
}
void SendReadDataReply(u16 _channelID, void* _Base, u16 _Address, u8 _Size)
{
int dataOffset = 0;
while (_Size > 0)
{
u8 DataFrame[1024];
u32 Offset = WriteWmReport(DataFrame, WM_READ_DATA_REPLY);
int copySize = _Size;
if (copySize > 16)
{
copySize = 16;
}
wm_read_data_reply* pReply = (wm_read_data_reply*)(DataFrame + Offset);
Offset += sizeof(wm_read_data_reply);
pReply->buttons = 0;
pReply->error = 0;
pReply->size = (copySize - 1) & 0xF;
pReply->address = Common::swap16(_Address + dataOffset);
memcpy(pReply->data + dataOffset, _Base, copySize);
if(copySize < 16)
{
memset(pReply->data + copySize, 0, 16 - copySize);
}
dataOffset += copySize;
LOG(WII_IPC_WIIMOTE, " SendReadDataReply()");
LOG(WII_IPC_WIIMOTE, " Buttons: 0x%04x", pReply->buttons);
LOG(WII_IPC_WIIMOTE, " Error: 0x%x", pReply->error);
LOG(WII_IPC_WIIMOTE, " Size: 0x%x", pReply->size);
LOG(WII_IPC_WIIMOTE, " Address: 0x%04x", pReply->address);
g_WiimoteInitialize.pWiimoteInput(_channelID, DataFrame, Offset);
_Size -= copySize;
}
if (_Size != 0)
{
PanicAlert("WiiMote-Plugin: SendReadDataReply() failed");
}
}
} // end of namespace

View File

@ -24,10 +24,13 @@
#include "thread.h"
#include "wiimote_hid.h"
#include "wiimote_emu.h"
#include "EmuMain.h"
extern SWiimoteInitialize g_WiimoteInitialize;
extern void __Log(int log, const char *format, ...);
//extern void __Log(int log, const char *format, ...);
//extern void __Log(int log, int v, const char *format, ...);
namespace WiiMoteReal
{