Wiimote:
1. First test version of movement recording (play back recordings with Shift + 0-9 or Ctrl + 0-9) 2. Really fixed the problem that the Wiimote get stuck on rumble when a game is stopped (sorry about that) git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@2033 8ced0084-cf51-0410-be5f-012b33b47a6e
This commit is contained in:
parent
933217bd7b
commit
a35579c40b
|
@ -28,6 +28,7 @@
|
|||
#include "main.h"
|
||||
#include "ConfigDlg.h"
|
||||
#include "Config.h"
|
||||
#include "EmuMain.h" // for LoadRecordedMovements()
|
||||
#include "EmuSubroutines.h" // for WmRequestStatus
|
||||
/////////////////////////////
|
||||
|
||||
|
@ -44,7 +45,9 @@
|
|||
BEGIN_EVENT_TABLE(ConfigDialog,wxDialog)
|
||||
EVT_CLOSE(ConfigDialog::OnClose)
|
||||
EVT_BUTTON(ID_CLOSE, ConfigDialog::CloseClick)
|
||||
EVT_BUTTON(ID_APPLY, ConfigDialog::CloseClick)
|
||||
EVT_BUTTON(ID_ABOUTOGL, ConfigDialog::AboutClick)
|
||||
|
||||
EVT_CHECKBOX(ID_SIDEWAYSDPAD, ConfigDialog::GeneralSettingsChanged)
|
||||
EVT_CHECKBOX(ID_WIDESCREEN, ConfigDialog::GeneralSettingsChanged)
|
||||
EVT_CHECKBOX(ID_NUNCHUCKCONNECTED, ConfigDialog::GeneralSettingsChanged)
|
||||
|
@ -54,6 +57,22 @@ BEGIN_EVENT_TABLE(ConfigDialog,wxDialog)
|
|||
EVT_CHECKBOX(ID_USE_REAL, ConfigDialog::GeneralSettingsChanged)
|
||||
EVT_CHECKBOX(ID_UPDATE_REAL, ConfigDialog::GeneralSettingsChanged)
|
||||
|
||||
EVT_CHOICE(IDC_RECORD + 1, ConfigDialog::GeneralSettingsChanged)
|
||||
EVT_CHOICE(IDC_RECORD + 2, ConfigDialog::GeneralSettingsChanged)
|
||||
EVT_CHOICE(IDC_RECORD + 3, ConfigDialog::GeneralSettingsChanged)
|
||||
EVT_CHOICE(IDC_RECORD + 4, ConfigDialog::GeneralSettingsChanged)
|
||||
EVT_CHOICE(IDC_RECORD + 5, ConfigDialog::GeneralSettingsChanged)
|
||||
EVT_CHOICE(IDC_RECORD + 6, ConfigDialog::GeneralSettingsChanged)
|
||||
EVT_CHOICE(IDC_RECORD + 7, ConfigDialog::GeneralSettingsChanged)
|
||||
EVT_CHOICE(IDC_RECORD + 8, ConfigDialog::GeneralSettingsChanged)
|
||||
EVT_CHOICE(IDC_RECORD + 9, ConfigDialog::GeneralSettingsChanged)
|
||||
EVT_CHOICE(IDC_RECORD + 10, ConfigDialog::GeneralSettingsChanged)
|
||||
EVT_CHOICE(IDC_RECORD + 11, ConfigDialog::GeneralSettingsChanged)
|
||||
EVT_CHOICE(IDC_RECORD + 12, ConfigDialog::GeneralSettingsChanged)
|
||||
EVT_CHOICE(IDC_RECORD + 13, ConfigDialog::GeneralSettingsChanged)
|
||||
EVT_CHOICE(IDC_RECORD + 14, ConfigDialog::GeneralSettingsChanged)
|
||||
EVT_CHOICE(IDC_RECORD + 15, ConfigDialog::GeneralSettingsChanged)
|
||||
|
||||
EVT_BUTTON(IDB_RECORD + 1, ConfigDialog::RecordMovement)
|
||||
EVT_BUTTON(IDB_RECORD + 2, ConfigDialog::RecordMovement)
|
||||
EVT_BUTTON(IDB_RECORD + 3, ConfigDialog::RecordMovement)
|
||||
|
@ -70,7 +89,6 @@ BEGIN_EVENT_TABLE(ConfigDialog,wxDialog)
|
|||
EVT_BUTTON(IDB_RECORD + 14, ConfigDialog::RecordMovement)
|
||||
EVT_BUTTON(IDB_RECORD + 15, ConfigDialog::RecordMovement)
|
||||
|
||||
EVT_TIMER(IDTM_EXIT, ConfigDialog::FlashLights)
|
||||
EVT_TIMER(IDTM_UPDATE, ConfigDialog::Update)
|
||||
END_EVENT_TABLE()
|
||||
/////////////////////////////
|
||||
|
@ -84,10 +102,6 @@ ConfigDialog::ConfigDialog(wxWindow *parent, wxWindowID id, const wxString &titl
|
|||
: wxDialog(parent, id, title, position, size, style)
|
||||
{
|
||||
#if wxUSE_TIMER
|
||||
m_ExitTimer = new wxTimer(this, IDTM_EXIT);
|
||||
// Reset values
|
||||
ShutDown = false;
|
||||
|
||||
m_TimeoutTimer = new wxTimer(this, IDTM_UPDATE);
|
||||
m_TimeoutATimer = new wxTimer(this, IDTM_UPDATEA);
|
||||
// Reset values
|
||||
|
@ -134,15 +148,23 @@ void ConfigDialog::OnClose(wxCloseEvent& WXUNUSED (event))
|
|||
EndModal(0);
|
||||
}
|
||||
|
||||
void ConfigDialog::CloseClick(wxCommandEvent& WXUNUSED (event))
|
||||
void ConfigDialog::CloseClick(wxCommandEvent& event)
|
||||
{
|
||||
switch(event.GetId())
|
||||
{
|
||||
case ID_CLOSE:
|
||||
// wxWidgets function. This will also trigger EVT_CLOSE().
|
||||
Close();
|
||||
break;
|
||||
case ID_APPLY:
|
||||
SaveFile();
|
||||
WiiMoteEmu::LoadRecordedMovements();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void ConfigDialog::AboutClick(wxCommandEvent& WXUNUSED (event))
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void ConfigDialog::LoadFile()
|
||||
|
@ -234,8 +256,9 @@ void ConfigDialog::CreateGUIControls()
|
|||
|
||||
// Buttons
|
||||
//m_About = new wxButton(this, ID_ABOUTOGL, wxT("About"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator);
|
||||
m_Close = new wxButton(this, ID_CLOSE, wxT("Close"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator);
|
||||
|
||||
m_Apply = new wxButton(this, ID_APPLY, wxT("Apply"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator);
|
||||
m_Close = new wxButton(this, ID_CLOSE, wxT("Close"));
|
||||
m_Close->SetToolTip(wxT("Apply and Close"));
|
||||
|
||||
////////////////////////////////////////////
|
||||
// Put notebook and buttons in sMain
|
||||
|
@ -244,12 +267,13 @@ void ConfigDialog::CreateGUIControls()
|
|||
sButtons = new wxBoxSizer(wxHORIZONTAL);
|
||||
//sButtons->Add(m_About, 0, wxALL, 5); // there is no about
|
||||
sButtons->AddStretchSpacer();
|
||||
sButtons->Add(m_Close, 0, wxALL, 5);
|
||||
sButtons->Add(m_Apply, 0, (wxALL), 0);
|
||||
sButtons->Add(m_Close, 0, (wxLEFT), 5);
|
||||
|
||||
wxBoxSizer* sMain;
|
||||
sMain = new wxBoxSizer(wxVERTICAL);
|
||||
sMain->Add(m_Notebook, 1, wxEXPAND | wxALL, 5);
|
||||
sMain->Add(sButtons, 0, wxEXPAND, 5);
|
||||
sMain->Add(sButtons, 0, wxEXPAND | (wxLEFT | wxRIGHT | wxDOWN), 5);
|
||||
/////////////////////////////////
|
||||
|
||||
|
||||
|
@ -302,7 +326,7 @@ void ConfigDialog::CreateGUIControls()
|
|||
m_UpdateMeters->SetValue(g_Config.bUpdateRealWiimote);
|
||||
|
||||
m_UpdateMeters->SetToolTip(wxT(
|
||||
"You can turn this off when a game is running to avoid a unnecessary slowdown that comes from redrawing the\n"
|
||||
"You can turn this off when a game is running to avoid a potential slowdown that may come from redrawing the\n"
|
||||
"configuration screen. Remember that you also need to press '+' on your Wiimote before you can record movements."
|
||||
));
|
||||
|
||||
|
@ -387,9 +411,10 @@ void ConfigDialog::CreateGUIControls()
|
|||
|
||||
wxArrayString StrHotKey;
|
||||
for(int i = 0; i < 10; i++) StrHotKey.Add(wxString::Format(wxT("%i"), i));
|
||||
StrHotKey.Add(wxT(""));
|
||||
|
||||
wxArrayString StrPlayBackSpeed;
|
||||
for(int i = 1; i < 15; i++) StrPlayBackSpeed.Add(wxString::Format(wxT("%i"), i*25));
|
||||
for(int i = 1; i <= 20; i++) StrPlayBackSpeed.Add(wxString::Format(wxT("%i"), i*25));
|
||||
|
||||
wxBoxSizer * sRealRecord[RECORDING_ROWS + 1];
|
||||
|
||||
|
@ -409,7 +434,7 @@ void ConfigDialog::CreateGUIControls()
|
|||
"current update rate in the Status window above when a game is running.) However, if your framerate is only at 50% of full speed\n"
|
||||
"you may want to select a playback rate of 50, because then the game might perceive the playback as a full speed playback. (This\n"
|
||||
"holds if Wiimote_Update() is tied to the framerate, I'm not sure that this is the case. It seemed to vary somewhat with different\n"
|
||||
"framerates but not nearly enough to say that it was tied to the framerate.) So until this is better understood you'll have\n"
|
||||
"framerates but perhaps not enough to say that it was exactly tied to the framerate.) So until this is better understood you'll have\n"
|
||||
"to try different playback rates and see which one that works."
|
||||
));
|
||||
|
||||
|
@ -426,7 +451,7 @@ void ConfigDialog::CreateGUIControls()
|
|||
{
|
||||
sRealRecord[i] = new wxBoxSizer(wxHORIZONTAL);
|
||||
m_RecordButton[i] = new wxButton(m_PageReal, IDB_RECORD + i, wxEmptyString, wxDefaultPosition, wxSize(80, 20), 0, wxDefaultValidator, wxEmptyString);
|
||||
m_RecordHotKey[i] = new wxChoice(m_PageReal, IDC_RECORD, wxDefaultPosition, wxDefaultSize, StrHotKey);
|
||||
m_RecordHotKey[i] = new wxChoice(m_PageReal, IDC_RECORD + i, wxDefaultPosition, wxDefaultSize, StrHotKey);
|
||||
m_RecordText[i] = new wxTextCtrl(m_PageReal, IDT_RECORD_TEXT, wxT(""), wxDefaultPosition, wxSize(200, 19));
|
||||
m_RecordGameText[i] = new wxTextCtrl(m_PageReal, IDT_RECORD_GAMETEXT, wxT(""), wxDefaultPosition, wxSize(200, 19));
|
||||
m_RecordSpeed[i] = new wxTextCtrl(m_PageReal, IDT_RECORD_SPEED, wxT(""), wxDefaultPosition, wxSize(30, 19), wxTE_READONLY | wxTE_CENTRE);
|
||||
|
@ -636,66 +661,6 @@ void ConfigDialog::DoRecordMovement(u8 _x, u8 _y, u8 _z)
|
|||
/////////////////////////////////
|
||||
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
/* Flash lights and rumble (for Connect and Disconnect) in its own thread like this
|
||||
to avoid a delay when the Connect checkbox is pressed (that would occur if we use
|
||||
Sleep() instead). */
|
||||
// ------------
|
||||
void ConfigDialog::StartTimer()
|
||||
{
|
||||
TimerCounter = 0;
|
||||
|
||||
// Start the constant timer
|
||||
int TimesPerSecond = 10;
|
||||
m_ExitTimer->Start( floor((double)(1000 / TimesPerSecond)) );
|
||||
|
||||
// Run it immedeately for the first time
|
||||
DoFlashLights();
|
||||
}
|
||||
|
||||
void ConfigDialog::DoFlashLights()
|
||||
{
|
||||
TimerCounter++;
|
||||
|
||||
if(TimerCounter == 1)
|
||||
wiiuse_rumble(WiiMoteReal::g_WiiMotesFromWiiUse[0], 1);
|
||||
|
||||
if(TimerCounter == 1)
|
||||
wiiuse_set_leds(WiiMoteReal::g_WiiMotesFromWiiUse[0], WIIMOTE_LED_1 | WIIMOTE_LED_2 | WIIMOTE_LED_3 | WIIMOTE_LED_4);
|
||||
|
||||
// Make the rumble period equal on both Init and Shutdown
|
||||
if (TimerCounter == 1 && ShutDown) TimerCounter++;
|
||||
|
||||
if (TimerCounter >= 3 || TimerCounter <= 5)
|
||||
wiiuse_rumble(WiiMoteReal::g_WiiMotesFromWiiUse[0], 0);
|
||||
|
||||
if(TimerCounter == 3)
|
||||
{
|
||||
if(ShutDown)
|
||||
{
|
||||
// Set led 4
|
||||
wiiuse_set_leds(WiiMoteReal::g_WiiMotesFromWiiUse[0], WIIMOTE_LED_4);
|
||||
|
||||
// Clean up wiiuse
|
||||
wiiuse_cleanup(WiiMoteReal::g_WiiMotesFromWiiUse, WiiMoteReal::g_NumberOfWiiMotes);
|
||||
|
||||
ShutDown = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
wiiuse_set_leds(WiiMoteReal::g_WiiMotesFromWiiUse[0], WIIMOTE_LED_1);
|
||||
}
|
||||
|
||||
// Stop timer
|
||||
m_ExitTimer->Stop();
|
||||
}
|
||||
|
||||
Console::Print("TimerCounter == %i\n", TimerCounter);
|
||||
}
|
||||
/////////////////////////////////
|
||||
|
||||
|
||||
// ===================================================
|
||||
/* Do use real wiimote */
|
||||
// ----------------
|
||||
|
@ -804,6 +769,31 @@ void ConfigDialog::GeneralSettingsChanged(wxCommandEvent& event)
|
|||
case ID_UPDATE_REAL:
|
||||
g_Config.bUpdateRealWiimote = m_UpdateMeters->IsChecked();
|
||||
break;
|
||||
case IDC_RECORD + 1:
|
||||
case IDC_RECORD + 2:
|
||||
case IDC_RECORD + 3:
|
||||
case IDC_RECORD + 4:
|
||||
case IDC_RECORD + 5:
|
||||
case IDC_RECORD + 6:
|
||||
case IDC_RECORD + 7:
|
||||
case IDC_RECORD + 8:
|
||||
case IDC_RECORD + 9:
|
||||
case IDC_RECORD + 10:
|
||||
case IDC_RECORD + 11:
|
||||
case IDC_RECORD + 12:
|
||||
case IDC_RECORD + 13:
|
||||
case IDC_RECORD + 14:
|
||||
case IDC_RECORD + 15:
|
||||
// Check if any of the other choice boxes has the same hotkey
|
||||
for (int i = 1; i < (RECORDING_ROWS + 1); i++)
|
||||
{
|
||||
int CurrentChoiceBox = (event.GetId() - IDC_RECORD);
|
||||
if (i == CurrentChoiceBox) continue;
|
||||
if (m_RecordHotKey[i]->GetSelection() == m_RecordHotKey[CurrentChoiceBox]->GetSelection()) m_RecordHotKey[i]->SetSelection(10);
|
||||
Console::Print("HotKey: %i %i\n",
|
||||
m_RecordHotKey[i]->GetSelection(), m_RecordHotKey[CurrentChoiceBox]->GetSelection());
|
||||
}
|
||||
break;
|
||||
/////////////////
|
||||
}
|
||||
g_Config.Save();
|
||||
|
|
|
@ -51,13 +51,6 @@ class ConfigDialog : public wxDialog
|
|||
// Status
|
||||
wxStaticText * m_TextUpdateRate;
|
||||
|
||||
// Flash lights on connect functions
|
||||
wxTimer * m_ExitTimer;
|
||||
void DoFlashLights();
|
||||
void StartTimer();
|
||||
void FlashLights(wxTimerEvent& WXUNUSED(event)) { DoFlashLights(); }
|
||||
bool ShutDown; int TimerCounter;
|
||||
|
||||
// Wiimote status
|
||||
wxGauge *m_GaugeBattery, *m_GaugeRoll[2], *m_GaugeGForce[3], *m_GaugeAccel[3];
|
||||
bool m_bWaitForRecording, m_bRecording, m_bAllowA;
|
||||
|
@ -73,8 +66,7 @@ class ConfigDialog : public wxDialog
|
|||
private:
|
||||
DECLARE_EVENT_TABLE();
|
||||
|
||||
wxButton *m_About;
|
||||
wxButton *m_Close;
|
||||
wxButton *m_About, *m_Close, *m_Apply;
|
||||
wxNotebook *m_Notebook;
|
||||
wxPanel *m_PageEmu, *m_PageReal;
|
||||
|
||||
|
@ -108,6 +100,7 @@ class ConfigDialog : public wxDialog
|
|||
enum
|
||||
{
|
||||
ID_CLOSE = 1000,
|
||||
ID_APPLY,
|
||||
ID_ABOUTOGL,
|
||||
IDTM_EXIT, IDTM_UPDATE, IDTM_UPDATEA, // Timer
|
||||
|
||||
|
|
|
@ -56,7 +56,7 @@ u8 g_RegIr[WIIMOTE_REG_IR_SIZE];
|
|||
u8 g_ReportingMode; // The reporting mode and channel id
|
||||
u16 g_ReportingChannel;
|
||||
|
||||
std::vector<wm_ackdelay> AckDelay;
|
||||
std::vector<wm_ackdelay> AckDelay; // Ackk delay
|
||||
|
||||
wiimote_key g_ExtKey; // The extension encryption key
|
||||
|
||||
|
|
|
@ -77,14 +77,14 @@ extern u8 g_RegIr[WIIMOTE_REG_IR_SIZE];
|
|||
extern u8 g_ReportingMode;
|
||||
extern u16 g_ReportingChannel;
|
||||
|
||||
struct wm_ackdelay // Ack delay
|
||||
// Ack delay
|
||||
struct wm_ackdelay
|
||||
{
|
||||
u8 Delay;
|
||||
u8 ReportID;
|
||||
u16 ChannelID;
|
||||
bool Sent;
|
||||
};
|
||||
|
||||
extern std::vector<wm_ackdelay> AckDelay;
|
||||
|
||||
extern wiimote_key g_ExtKey; // extension encryption key
|
||||
|
@ -110,8 +110,12 @@ static const u8 EepromData_16D0[] = {
|
|||
neutral z accelerometer that is adjusted for gravity. */
|
||||
static const u8 nunchuck_calibration[] =
|
||||
{
|
||||
0x80,0x80,0x80,0x00, 0xb3,0xb3,0xb3,0x00,
|
||||
0xe0,0x20,0x80,0xe0, 0x20,0x80,0xee,0x43,
|
||||
0x80,0x80,0x80,0x00, // x and y neutral
|
||||
0xb3,0xb3,0xb3,0x00, // z neutral
|
||||
|
||||
0xe0,0x20,0x80,0xe0,
|
||||
0x20,0x80,0xee,0x43,
|
||||
|
||||
0x80,0x80,0x80,0x00, 0xb3,0xb3,0xb3,0x00,
|
||||
0xe0,0x20,0x80,0xe0, 0x20,0x80,0xee,0x43
|
||||
};
|
||||
|
|
|
@ -106,41 +106,10 @@ void WriteCrypted16(u8* _baseBlock, u16 _address, u16 _value)
|
|||
|
||||
|
||||
// ===================================================
|
||||
/* Write initial values to Eeprom and registers. */
|
||||
/* Load pre-recorded movements */
|
||||
// ----------------
|
||||
void Initialize()
|
||||
void LoadRecordedMovements()
|
||||
{
|
||||
if (g_EmulatedWiiMoteInitialized) return;
|
||||
|
||||
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;
|
||||
|
||||
|
||||
/* Extension data for homebrew applications that use the 0x00000000 key. This
|
||||
writes 0x0000 in encrypted form (0xfefe) to 0xfe in the extension register. */
|
||||
//WriteCrypted16(g_RegExt, 0xfe, 0x0000); // Fully inserted Nunchuk
|
||||
|
||||
|
||||
// Copy extension id and calibration to its register
|
||||
if(g_Config.bNunchuckConnected)
|
||||
{
|
||||
memcpy(g_RegExt + 0x20, nunchuck_calibration, sizeof(nunchuck_calibration));
|
||||
memcpy(g_RegExt + 0xfa, nunchuck_id, sizeof(nunchuck_id));
|
||||
}
|
||||
else if(g_Config.bClassicControllerConnected)
|
||||
{
|
||||
memcpy(g_RegExt + 0x20, classic_calibration, sizeof(classic_calibration));
|
||||
memcpy(g_RegExt + 0xfa, classic_id, sizeof(classic_id));
|
||||
}
|
||||
|
||||
g_EmulatedWiiMoteInitialized = true;
|
||||
|
||||
//////////////////////////////////////
|
||||
// Load pre-recorded movements
|
||||
// ---------------
|
||||
IniFile file;
|
||||
file.Load("WiimoteMovement.ini");
|
||||
|
||||
|
@ -173,10 +142,12 @@ void Initialize()
|
|||
Tmp.x = (u8)TmpZ;
|
||||
|
||||
// Go to next set of time values
|
||||
int Time = atoi(TmpTime.substr(k, 5).c_str());
|
||||
double Time = (double)atoi(TmpTime.substr(k, 5).c_str());
|
||||
Tmp.Time = (double)(Time/1000);
|
||||
VRecording.at(i).Recording.push_back(Tmp);
|
||||
k += 6;
|
||||
|
||||
//Console::Print("Time:%f\n", Tmp.Time);
|
||||
}
|
||||
|
||||
// HotKey
|
||||
|
@ -191,7 +162,47 @@ void Initialize()
|
|||
VRecording.at(i).Recording.size(), VRecording.at(i).HotKey, VRecording.at(i).PlaybackSpeed
|
||||
);
|
||||
}
|
||||
//////////////////////////
|
||||
}
|
||||
// ================
|
||||
|
||||
|
||||
|
||||
|
||||
// ===================================================
|
||||
/* Write initial values to Eeprom and registers. */
|
||||
// ----------------
|
||||
void Initialize()
|
||||
{
|
||||
if (g_EmulatedWiiMoteInitialized) return;
|
||||
|
||||
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;
|
||||
|
||||
|
||||
/* Extension data for homebrew applications that use the 0x00000000 key. This
|
||||
writes 0x0000 in encrypted form (0xfefe) to 0xfe in the extension register. */
|
||||
//WriteCrypted16(g_RegExt, 0xfe, 0x0000); // Fully inserted Nunchuk
|
||||
|
||||
|
||||
// Copy extension id and calibration to its register
|
||||
if(g_Config.bNunchuckConnected)
|
||||
{
|
||||
memcpy(g_RegExt + 0x20, nunchuck_calibration, sizeof(nunchuck_calibration));
|
||||
memcpy(g_RegExt + 0xfa, nunchuck_id, sizeof(nunchuck_id));
|
||||
}
|
||||
else if(g_Config.bClassicControllerConnected)
|
||||
{
|
||||
memcpy(g_RegExt + 0x20, classic_calibration, sizeof(classic_calibration));
|
||||
memcpy(g_RegExt + 0xfa, classic_id, sizeof(classic_id));
|
||||
}
|
||||
|
||||
g_EmulatedWiiMoteInitialized = true;
|
||||
|
||||
// Load pre-recorded movements
|
||||
LoadRecordedMovements();
|
||||
|
||||
// I forgot what these were for?
|
||||
// g_RegExt[0xfd] = 0x1e;
|
||||
|
|
|
@ -35,6 +35,8 @@ void InterruptChannel(u16 _channelID, const void* _pData, u32 _Size);
|
|||
void ControlChannel(u16 _channelID, const void* _pData, u32 _Size) ;
|
||||
void Update();
|
||||
|
||||
void LoadRecordedMovements();
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
#include "StringUtil.h" // For ArrayToString
|
||||
|
||||
#include "wiimote_hid.h"
|
||||
#include "main.h"
|
||||
#include "EmuMain.h"
|
||||
#include "EmuSubroutines.h"
|
||||
#include "EmuDefinitions.h"
|
||||
|
@ -41,6 +42,137 @@ extern SWiimoteInitialize g_WiimoteInitialize;
|
|||
namespace WiiMoteEmu
|
||||
{
|
||||
|
||||
|
||||
//******************************************************************************
|
||||
// Recorded movements
|
||||
//******************************************************************************
|
||||
|
||||
// ------------------------------------------
|
||||
// Variables
|
||||
// ----------------
|
||||
int g_RecordingPlaying = -1;
|
||||
int g_RecordingCounter = 0;
|
||||
int g_RecordingPoint = 0;
|
||||
double g_RecordingStart = 0;
|
||||
double g_RecordingCurrentTime = 0;
|
||||
// --------------------------
|
||||
|
||||
void RecordingPlay(u8 &_x, u8 &_y, u8 &_z)
|
||||
{
|
||||
// Return if the list is empty
|
||||
if(VRecording.at(g_RecordingPlaying).Recording.size() == 0)
|
||||
{
|
||||
g_RecordingPlaying = -1;
|
||||
Console::Print("Empty\n\n");
|
||||
return;
|
||||
}
|
||||
|
||||
// Return if the playback speed is unset
|
||||
if(VRecording.at(g_RecordingPlaying).PlaybackSpeed < 0)
|
||||
{
|
||||
g_RecordingPlaying = -1;
|
||||
Console::Print("PlaybackSpeed empty\n\n");
|
||||
return;
|
||||
}
|
||||
|
||||
// Get starting time
|
||||
if(g_RecordingCounter == 0) g_RecordingStart = GetDoubleTime();
|
||||
|
||||
// Get current time
|
||||
g_RecordingCurrentTime = GetDoubleTime() - g_RecordingStart;
|
||||
|
||||
// Modify the current time
|
||||
g_RecordingCurrentTime *= ((25.0 + (double)VRecording.at(g_RecordingPlaying).PlaybackSpeed * 25.0) / 100.0);
|
||||
|
||||
// Select reading
|
||||
for (int i = 0; i < VRecording.at(g_RecordingPlaying).Recording.size(); i++)
|
||||
if (VRecording.at(g_RecordingPlaying).Recording.at(i).Time > g_RecordingCurrentTime)
|
||||
{
|
||||
g_RecordingPoint = i;
|
||||
break; // Break loop
|
||||
}
|
||||
|
||||
// Return if we are at the end of the list
|
||||
if(g_RecordingCurrentTime >=
|
||||
VRecording.at(g_RecordingPlaying).Recording.at(
|
||||
VRecording.at(g_RecordingPlaying).Recording.size() - 1).Time)
|
||||
{
|
||||
g_RecordingCounter = 0;
|
||||
g_RecordingPlaying = -1;
|
||||
g_RecordingStart = 0;
|
||||
g_RecordingCurrentTime = 0;
|
||||
Console::Print("End\n\n");
|
||||
return;
|
||||
}
|
||||
|
||||
// Update values
|
||||
_x = VRecording.at(g_RecordingPlaying).Recording.at(g_RecordingPoint).x;
|
||||
_y = VRecording.at(g_RecordingPlaying).Recording.at(g_RecordingPoint).y;
|
||||
_z = VRecording.at(g_RecordingPlaying).Recording.at(g_RecordingPoint).z;
|
||||
|
||||
Console::Print("Current time: %f %f %i %i\n",
|
||||
VRecording.at(g_RecordingPlaying).Recording.at(g_RecordingPoint).Time, g_RecordingCurrentTime,
|
||||
VRecording.at(g_RecordingPlaying).Recording.size(), g_RecordingPoint
|
||||
);
|
||||
|
||||
g_RecordingCounter++;
|
||||
}
|
||||
|
||||
// Check if we should play a recording
|
||||
int RecordingCheckKeys(bool Wiimote)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
//Console::Print("RecordingCheckKeys\n");
|
||||
|
||||
// Return if we don't have both a Shift and Ctrl
|
||||
if ( (GetAsyncKeyState(VK_SHIFT) && GetAsyncKeyState(VK_CONTROL)) ) return -1;
|
||||
|
||||
// Return if we don't have both a Wiimote and Shift
|
||||
if ( Wiimote && !GetAsyncKeyState(VK_SHIFT) ) return -1;
|
||||
|
||||
// Return if we don't have both a Nunchuck and Ctrl
|
||||
if ( !Wiimote && !GetAsyncKeyState(VK_CONTROL) ) return -1;
|
||||
|
||||
// Check if we have exactly one numerical key
|
||||
int Keys = 0;
|
||||
for(int i = 0; i < 10; i++)
|
||||
{
|
||||
std::string Key = StringFromFormat("%i", i);
|
||||
if(GetAsyncKeyState(Key[0])) Keys++;
|
||||
}
|
||||
|
||||
//Console::Print("RecordingCheckKeys: %i\n", Keys);
|
||||
|
||||
// Return if we have less than or more than one
|
||||
if (Keys != 1) return -1;
|
||||
|
||||
// Check which key it is
|
||||
int Key;
|
||||
for(int i = 0; i < 10; i++)
|
||||
{
|
||||
std::string TmpKey = StringFromFormat("%i", i);
|
||||
if(GetAsyncKeyState(TmpKey[0])) { Key = i; break; }
|
||||
}
|
||||
|
||||
// Check if we have a HotKey match
|
||||
bool Match = false;
|
||||
for(int i = 0; i < RECORDING_ROWS; i++)
|
||||
{
|
||||
if (VRecording.at(i).HotKey == Key) Match = true;
|
||||
}
|
||||
|
||||
// Return nothing if we don't have a match
|
||||
if (!Match) return -1;
|
||||
|
||||
// Return the match
|
||||
return Key;
|
||||
#else
|
||||
return -1;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
||||
//******************************************************************************
|
||||
// Subroutines
|
||||
//******************************************************************************
|
||||
|
@ -56,6 +188,9 @@ void FillReportInfo(wm_core& _core)
|
|||
memset(&_core, 0x00, sizeof(wm_core));
|
||||
|
||||
#ifdef _WIN32
|
||||
// These keys are reserved for the recording
|
||||
if ( GetAsyncKeyState(VK_SHIFT) || GetAsyncKeyState(VK_CONTROL) ) return;
|
||||
|
||||
// Allow both mouse buttons and keyboard to press a and b
|
||||
if(GetAsyncKeyState(VK_LBUTTON) ? 1 : 0 || GetAsyncKeyState('A') ? 1 : 0)
|
||||
_core.a = 1;
|
||||
|
@ -112,7 +247,24 @@ std::vector<u8> yhist(15); // for the tilt function
|
|||
void FillReportAcc(wm_accel& _acc)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
// -----------------------------
|
||||
// ------------------------------------
|
||||
// Recorded movements
|
||||
// --------------
|
||||
// Check for a playback command
|
||||
if(g_RecordingPlaying < 0)
|
||||
{
|
||||
g_RecordingPlaying = RecordingCheckKeys(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
RecordingPlay(_acc.x, _acc.y, _acc.z);
|
||||
//Console::Print("X: %u\n", _acc.x);
|
||||
return;
|
||||
}
|
||||
// ---------------------
|
||||
|
||||
|
||||
// ------------------------------------
|
||||
// Wiimote to Gamepad translations
|
||||
// ----------
|
||||
// Tilting Wiimote (Wario Land aiming, Mario Kart steering) : For some reason 150 and 40
|
||||
|
@ -467,6 +619,23 @@ int abc = 0;
|
|||
// ----------------
|
||||
void FillReportExtension(wm_extension& _ext)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
// ------------------------------------
|
||||
// Recorded movements
|
||||
// --------------
|
||||
// Check for a playback command
|
||||
if(g_RecordingPlaying < 0)
|
||||
{
|
||||
g_RecordingPlaying = RecordingCheckKeys(false);
|
||||
}
|
||||
else
|
||||
{
|
||||
RecordingPlay(_ext.ax, _ext.ay, _ext.az);
|
||||
//Console::Print("X: %u\n", _acc.x);
|
||||
return;
|
||||
}
|
||||
// ---------------------
|
||||
#endif
|
||||
|
||||
/* These are the default neutral values for the nunchuck accelerometer according
|
||||
to a source. */
|
||||
|
|
|
@ -253,6 +253,22 @@ void SendEvent(SEvent& _rEvent)
|
|||
//******************************************************************************
|
||||
// Function Definitions
|
||||
//******************************************************************************
|
||||
|
||||
// Flash lights, and if connecting, also rumble
|
||||
void FlashLights(bool Connect)
|
||||
{
|
||||
if(Connect) wiiuse_rumble(WiiMoteReal::g_WiiMotesFromWiiUse[0], 1);
|
||||
wiiuse_set_leds(WiiMoteReal::g_WiiMotesFromWiiUse[0], WIIMOTE_LED_1 | WIIMOTE_LED_2 | WIIMOTE_LED_3 | WIIMOTE_LED_4);
|
||||
Sleep(100);
|
||||
if(Connect) wiiuse_rumble(WiiMoteReal::g_WiiMotesFromWiiUse[0], 0);
|
||||
|
||||
// End with light 1 or 4
|
||||
if(Connect)
|
||||
wiiuse_set_leds(WiiMoteReal::g_WiiMotesFromWiiUse[0], WIIMOTE_LED_1);
|
||||
else
|
||||
wiiuse_set_leds(WiiMoteReal::g_WiiMotesFromWiiUse[0], WIIMOTE_LED_4);
|
||||
}
|
||||
|
||||
int Initialize()
|
||||
{
|
||||
if (g_RealWiiMoteInitialized) return g_NumberOfWiiMotes;
|
||||
|
@ -277,7 +293,7 @@ int Initialize()
|
|||
//wiiuse_set_timeout(g_WiiMotesFromWiiUse, MAX_WIIMOTES, 500, 1000);
|
||||
//wiiuse_set_flags(g_WiiMotesFromWiiUse[0], WIIUSE_CONTINUOUS, NULL);
|
||||
|
||||
if(frame) frame->StartTimer();
|
||||
FlashLights(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -319,26 +335,14 @@ void Shutdown(void)
|
|||
g_WiiMotes[i] = NULL;
|
||||
}
|
||||
|
||||
#if defined(HAVE_WX) && HAVE_WX
|
||||
/* We can only do this if we are not unloading the DLL, otherwise we can get stuck with a
|
||||
a rumble after we Stop a game */
|
||||
if (!g_EmulatorRunning)
|
||||
{
|
||||
if(frame) frame->ShutDown = true;
|
||||
if(frame) frame->StartTimer();
|
||||
}
|
||||
else
|
||||
{
|
||||
#else
|
||||
// Flash flights
|
||||
if (!g_EmulatorRunning) FlashLights(false);
|
||||
|
||||
// Clean up wiiuse
|
||||
wiiuse_cleanup(g_WiiMotesFromWiiUse, g_NumberOfWiiMotes);
|
||||
|
||||
// Uninitialized
|
||||
g_RealWiiMoteInitialized = false;
|
||||
#endif
|
||||
#if defined(HAVE_WX) && HAVE_WX
|
||||
}
|
||||
#endif
|
||||
|
||||
// Uninitialized
|
||||
g_RealWiiMoteInitialized = false;
|
||||
|
@ -387,7 +391,7 @@ void Update()
|
|||
{
|
||||
if(g_EmulatorRunning)
|
||||
for (int i = 0; i < g_NumberOfWiiMotes; i++) g_WiiMotes[i]->ReadData();
|
||||
else if (!g_Config.bUseRealWiimote)
|
||||
if (!g_Config.bUseRealWiimote)
|
||||
ReadWiimote();
|
||||
}
|
||||
return 0;
|
||||
|
|
Loading…
Reference in New Issue