mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-04-10 03:44:26 +00:00
Rerecording and nJoy: Copied the recording functions to nJoy
git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@2305 8ced0084-cf51-0410-be5f-012b33b47a6e
This commit is contained in:
parent
5cf828c7b9
commit
0b1909aed0
@ -112,8 +112,11 @@ void Pause()
|
|||||||
// Start the timer when a game is booted
|
// Start the timer when a game is booted
|
||||||
void RerecordingStart()
|
void RerecordingStart()
|
||||||
{
|
{
|
||||||
g_FrameCounter == 0;
|
g_FrameCounter = 0;
|
||||||
ReRecTimer.Start();
|
ReRecTimer.Start();
|
||||||
|
|
||||||
|
// Logging
|
||||||
|
Console::Print("RerecordingStart: %i\n", g_FrameCounter);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Reset the frame counter
|
// Reset the frame counter
|
||||||
|
@ -709,7 +709,7 @@ void Shutdown()
|
|||||||
//Console::Print("ShutDown()\n");
|
//Console::Print("ShutDown()\n");
|
||||||
|
|
||||||
// -------------------------------------------
|
// -------------------------------------------
|
||||||
// Play back input instead of accepting any user input
|
// Save the recording and reset the counter
|
||||||
// ----------------------
|
// ----------------------
|
||||||
#ifdef RERECORDING
|
#ifdef RERECORDING
|
||||||
// Save recording
|
// Save recording
|
||||||
|
@ -518,6 +518,10 @@
|
|||||||
RelativePath=".\Src\nJoy.h"
|
RelativePath=".\Src\nJoy.h"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\Src\ReRecording.cpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath=".\Src\Rumble.cpp"
|
RelativePath=".\Src\Rumble.cpp"
|
||||||
>
|
>
|
||||||
|
@ -111,6 +111,10 @@ void Config::Save(int Slot)
|
|||||||
file.Set("General", "SaveByID", g_Config.bSaveByID);
|
file.Set("General", "SaveByID", g_Config.bSaveByID);
|
||||||
file.Set("General", "CheckForFocus", g_Config.bCheckFocus);
|
file.Set("General", "CheckForFocus", g_Config.bCheckFocus);
|
||||||
file.Set("General", "NoTriggerFilter", g_Config.bNoTriggerFilter);
|
file.Set("General", "NoTriggerFilter", g_Config.bNoTriggerFilter);
|
||||||
|
#ifdef RERECORDING
|
||||||
|
file.Set("General", "Recording", g_Config.bRecording);
|
||||||
|
file.Set("General", "Playback", g_Config.bPlayback);
|
||||||
|
#endif
|
||||||
// ========================
|
// ========================
|
||||||
|
|
||||||
for (int i = 0; i < 4; i++)
|
for (int i = 0; i < 4; i++)
|
||||||
@ -199,6 +203,10 @@ void Config::Load(bool ChangePad, bool ChangeSaveByID)
|
|||||||
file.Get("General", "ShowAdvanced", &g_Config.bShowAdvanced, false);
|
file.Get("General", "ShowAdvanced", &g_Config.bShowAdvanced, false);
|
||||||
file.Get("General", "CheckForFocus", &g_Config.bCheckFocus, false);
|
file.Get("General", "CheckForFocus", &g_Config.bCheckFocus, false);
|
||||||
file.Get("General", "NoTriggerFilter", &g_Config.bNoTriggerFilter, false);
|
file.Get("General", "NoTriggerFilter", &g_Config.bNoTriggerFilter, false);
|
||||||
|
#ifdef RERECORDING
|
||||||
|
file.Get("General", "Recording", &g_Config.bRecording, false);
|
||||||
|
file.Get("General", "Playback", &g_Config.bPlayback, false);
|
||||||
|
#endif
|
||||||
|
|
||||||
if(!ChangeSaveByID)
|
if(!ChangeSaveByID)
|
||||||
{
|
{
|
||||||
|
@ -30,6 +30,10 @@ struct Config
|
|||||||
bool bSaveByID;
|
bool bSaveByID;
|
||||||
bool bCheckFocus;
|
bool bCheckFocus;
|
||||||
bool bNoTriggerFilter;
|
bool bNoTriggerFilter;
|
||||||
|
#ifdef RERECORDING
|
||||||
|
bool bRecording;
|
||||||
|
bool bPlayback;
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
extern Config g_Config;
|
extern Config g_Config;
|
||||||
|
@ -299,6 +299,46 @@ void ConfigBox::CreateAdvancedControls(int i)
|
|||||||
|
|
||||||
m_bmpDotOut[i] = new wxStaticBitmap(m_pOutStatus[i], ID_STATUSDOTBMP1 + i, CreateBitmapDot(),
|
m_bmpDotOut[i] = new wxStaticBitmap(m_pOutStatus[i], ID_STATUSDOTBMP1 + i, CreateBitmapDot(),
|
||||||
wxPoint(BoxW / 2, BoxH / 2), wxDefaultSize);
|
wxPoint(BoxW / 2, BoxH / 2), wxDefaultSize);
|
||||||
|
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Rerecording
|
||||||
|
// ¯¯¯¯¯¯¯¯¯
|
||||||
|
#ifdef RERECORDING
|
||||||
|
// Create controls
|
||||||
|
m_SizeRecording[i] = new wxStaticBoxSizer(wxVERTICAL, m_Controller[i], wxT("Input Recording"));
|
||||||
|
m_CheckRecording[i] = new wxCheckBox(m_Controller[i], ID_RECORDING, wxT("Record input"));
|
||||||
|
m_CheckPlayback[i] = new wxCheckBox(m_Controller[i], ID_PLAYBACK, wxT("Play back input"));
|
||||||
|
m_BtnSaveRecording[i] = new wxButton(m_Controller[i], ID_SAVE_RECORDING, wxT("Save recording"), wxDefaultPosition, wxDefaultSize);
|
||||||
|
|
||||||
|
// Tool tips
|
||||||
|
m_CheckRecording[i]->SetToolTip(wxT("Your recording will be saved to pad-record.bin in the Dolphin dir when you stop the game"));
|
||||||
|
m_CheckPlayback[i]->SetToolTip(wxT("Play back the pad-record.bin file from the Dolphin dir"));
|
||||||
|
m_BtnSaveRecording[i]->SetToolTip(wxT(
|
||||||
|
"This will save the current recording to pad-record.bin. Your recording will\n"
|
||||||
|
"also be automatically saved every 60 * 10 frames. And when you shut down the\n"
|
||||||
|
"game."));
|
||||||
|
|
||||||
|
// Sizers
|
||||||
|
m_SizeRecording[i]->Add(m_CheckRecording[i], 0, wxEXPAND | wxALL, 1);
|
||||||
|
m_SizeRecording[i]->Add(m_CheckPlayback[i], 0, wxEXPAND | wxALL, 1);
|
||||||
|
m_SizeRecording[i]->Add(m_BtnSaveRecording[i], 0, wxEXPAND | wxALL, 1);
|
||||||
|
|
||||||
|
// Only enable these options for pad 0
|
||||||
|
m_CheckRecording[i]->Enable(false); m_CheckRecording[0]->Enable(true);
|
||||||
|
m_CheckPlayback[i]->Enable(false); m_CheckPlayback[0]->Enable(true);
|
||||||
|
m_BtnSaveRecording[i]->Enable(false); m_BtnSaveRecording[0]->Enable(true);
|
||||||
|
// Don't allow saving when we are not recording
|
||||||
|
m_BtnSaveRecording[i]->Enable(g_EmulatorRunning && g_Config.bRecording);
|
||||||
|
//sDevice[i]->Add(m_SizeRecording[i], 0, wxEXPAND | wxALL, 1);
|
||||||
|
|
||||||
|
// Set values
|
||||||
|
//m_CheckRecording[0]->SetValue(g_Config.bRecording);
|
||||||
|
//m_CheckPlayback[0]->SetValue(g_Config.bPlayback);
|
||||||
|
|
||||||
|
//Console::Print("m_CheckRecording: %i\n", g_Config.bRecording, g_Config.bPlayback);
|
||||||
|
#endif
|
||||||
|
//////////////////////////////////////
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -84,6 +84,11 @@ BEGIN_EVENT_TABLE(ConfigBox,wxDialog)
|
|||||||
EVT_COMBOBOX(IDCB_MAINSTICK_DIAGONAL, ConfigBox::ChangeSettings)
|
EVT_COMBOBOX(IDCB_MAINSTICK_DIAGONAL, ConfigBox::ChangeSettings)
|
||||||
EVT_CHECKBOX(IDCB_MAINSTICK_S_TO_C, ConfigBox::ChangeSettings)
|
EVT_CHECKBOX(IDCB_MAINSTICK_S_TO_C, ConfigBox::ChangeSettings)
|
||||||
EVT_CHECKBOX(IDCB_FILTER_SETTINGS, ConfigBox::ChangeSettings)
|
EVT_CHECKBOX(IDCB_FILTER_SETTINGS, ConfigBox::ChangeSettings)
|
||||||
|
#ifdef RERECORDING
|
||||||
|
EVT_CHECKBOX(ID_RECORDING, ConfigBox::ChangeSettings)
|
||||||
|
EVT_CHECKBOX(ID_PLAYBACK, ConfigBox::ChangeSettings)
|
||||||
|
EVT_BUTTON(ID_SAVE_RECORDING, ConfigBox::GetButtons)
|
||||||
|
#endif
|
||||||
|
|
||||||
EVT_BUTTON(IDB_SHOULDER_L, ConfigBox::GetButtons)
|
EVT_BUTTON(IDB_SHOULDER_L, ConfigBox::GetButtons)
|
||||||
EVT_BUTTON(IDB_SHOULDER_R, ConfigBox::GetButtons)
|
EVT_BUTTON(IDB_SHOULDER_R, ConfigBox::GetButtons)
|
||||||
@ -448,6 +453,24 @@ void ConfigBox::ChangeSettings( wxCommandEvent& event )
|
|||||||
m_AdvancedMapFilter[i]->SetValue(g_Config.bNoTriggerFilter);
|
m_AdvancedMapFilter[i]->SetValue(g_Config.bNoTriggerFilter);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
#ifdef RERECORDING
|
||||||
|
case ID_RECORDING:
|
||||||
|
g_Config.bRecording = m_CheckRecording[notebookpage]->IsChecked();
|
||||||
|
if(g_Config.bRecording) g_Config.bPlayback = !g_Config.bRecording;
|
||||||
|
for(int i = 0; i < 4; i++) m_CheckRecording[i]->SetValue(g_Config.bRecording);
|
||||||
|
for(int i = 0; i < 4; i++) m_CheckPlayback[i]->SetValue(g_Config.bPlayback);
|
||||||
|
break;
|
||||||
|
case ID_PLAYBACK:
|
||||||
|
g_Config.bPlayback = m_CheckPlayback[notebookpage]->IsChecked();
|
||||||
|
if(g_Config.bPlayback) g_Config.bRecording = !g_Config.bPlayback;
|
||||||
|
for(int i = 0; i < 4; i++) m_CheckPlayback[i]->SetValue(g_Config.bPlayback);
|
||||||
|
for(int i = 0; i < 4; i++) m_CheckPlayback[i]->SetValue(g_Config.bRecording);
|
||||||
|
break;
|
||||||
|
case ID_SAVE_RECORDING:
|
||||||
|
// Double check again that we are still running a game
|
||||||
|
if (g_EmulatorRunning) Recording::Save();
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
|
||||||
case IDC_CONTROLTYPE:
|
case IDC_CONTROLTYPE:
|
||||||
if(!g_Config.bSaveByID)
|
if(!g_Config.bSaveByID)
|
||||||
@ -532,8 +555,12 @@ void ConfigBox::UpdateGUI(int _notebookpage)
|
|||||||
m_CBShowAdvanced[_notebookpage]->SetValue(g_Config.bShowAdvanced);
|
m_CBShowAdvanced[_notebookpage]->SetValue(g_Config.bShowAdvanced);
|
||||||
m_CBCheckFocus[_notebookpage]->SetValue(g_Config.bCheckFocus);
|
m_CBCheckFocus[_notebookpage]->SetValue(g_Config.bCheckFocus);
|
||||||
m_AdvancedMapFilter[_notebookpage]->SetValue(g_Config.bNoTriggerFilter);
|
m_AdvancedMapFilter[_notebookpage]->SetValue(g_Config.bNoTriggerFilter);
|
||||||
|
#ifdef RERECORDING
|
||||||
|
m_CheckRecording[_notebookpage]->SetValue(g_Config.bRecording);
|
||||||
|
m_CheckPlayback[_notebookpage]->SetValue(g_Config.bPlayback);
|
||||||
|
#endif
|
||||||
|
|
||||||
LogMsg("Update: %i\n", g_Config.bSaveByID);
|
//LogMsg("Update: %i\n", g_Config.bSaveByID);
|
||||||
|
|
||||||
// Disabled pages
|
// Disabled pages
|
||||||
bool Enabled = PadMapping[_notebookpage].enabled == 1 ? true : false;
|
bool Enabled = PadMapping[_notebookpage].enabled == 1 ? true : false;
|
||||||
@ -967,7 +994,10 @@ void ConfigBox::CreateGUIControls()
|
|||||||
m_sMainRight[i]->Add(m_gStatusIn[i], 0, wxEXPAND | (wxLEFT), 2);
|
m_sMainRight[i]->Add(m_gStatusIn[i], 0, wxEXPAND | (wxLEFT), 2);
|
||||||
m_sMainRight[i]->Add(m_gStatusInSettings[i], 0, wxEXPAND | (wxLEFT | wxTOP), 2);
|
m_sMainRight[i]->Add(m_gStatusInSettings[i], 0, wxEXPAND | (wxLEFT | wxTOP), 2);
|
||||||
m_sMainRight[i]->Add(m_gStatusTriggers[i], 0, wxEXPAND | (wxLEFT | wxTOP), 2);
|
m_sMainRight[i]->Add(m_gStatusTriggers[i], 0, wxEXPAND | (wxLEFT | wxTOP), 2);
|
||||||
m_sMainRight[i]->Add(m_gStatusAdvancedSettings[i], 0, wxEXPAND | (wxLEFT | wxTOP), 2);
|
m_sMainRight[i]->Add(m_gStatusAdvancedSettings[i], 0, wxEXPAND | (wxLEFT | wxTOP), 2);
|
||||||
|
#ifdef RERECORDING
|
||||||
|
m_sMainRight[i]->Add(m_SizeRecording[i], 0, wxEXPAND | (wxLEFT | wxTOP), 2);
|
||||||
|
#endif
|
||||||
|
|
||||||
// --------------------------------------------------------------------
|
// --------------------------------------------------------------------
|
||||||
// Populate main sizer
|
// Populate main sizer
|
||||||
|
@ -190,6 +190,11 @@ class ConfigBox : public wxDialog
|
|||||||
*m_bmpSquare[4], *m_bmpDot[4], *m_bmpSquareOut[4], *m_bmpDotOut[4];
|
*m_bmpSquare[4], *m_bmpDot[4], *m_bmpSquareOut[4], *m_bmpDotOut[4];
|
||||||
|
|
||||||
int notebookpage; bool ControlsCreated;
|
int notebookpage; bool ControlsCreated;
|
||||||
|
#ifdef RERECORDING
|
||||||
|
wxStaticBoxSizer *m_SizeRecording[4];
|
||||||
|
wxCheckBox *m_CheckRecording[4], *m_CheckPlayback[4];
|
||||||
|
wxButton *m_BtnSaveRecording[4];
|
||||||
|
#endif
|
||||||
|
|
||||||
private:
|
private:
|
||||||
enum
|
enum
|
||||||
@ -221,6 +226,9 @@ class ConfigBox : public wxDialog
|
|||||||
|
|
||||||
// Advaced settings
|
// Advaced settings
|
||||||
IDCB_MAINSTICK_DIAGONAL, IDCB_MAINSTICK_S_TO_C, IDT_MAINSTICK_DIAGONAL, IDT_TRIGGERS, IDCB_CHECKFOCUS, IDCB_FILTER_SETTINGS,
|
IDCB_MAINSTICK_DIAGONAL, IDCB_MAINSTICK_S_TO_C, IDT_MAINSTICK_DIAGONAL, IDT_TRIGGERS, IDCB_CHECKFOCUS, IDCB_FILTER_SETTINGS,
|
||||||
|
#ifdef RERECORDING
|
||||||
|
ID_RECORDING, ID_PLAYBACK, ID_SAVE_RECORDING,
|
||||||
|
#endif
|
||||||
|
|
||||||
// Timers
|
// Timers
|
||||||
IDTM_CONSTANT, IDTM_BUTTON,
|
IDTM_CONSTANT, IDTM_BUTTON,
|
||||||
|
@ -80,7 +80,10 @@ void ConfigBox::UpdateGUIButtonMapping(int controller)
|
|||||||
m_CoBDiagonal[controller]->SetValue(wxString::FromAscii(PadMapping[controller].SDiagonal.c_str()));
|
m_CoBDiagonal[controller]->SetValue(wxString::FromAscii(PadMapping[controller].SDiagonal.c_str()));
|
||||||
m_CBS_to_C[controller]->SetValue(PadMapping[controller].bSquareToCircle);
|
m_CBS_to_C[controller]->SetValue(PadMapping[controller].bSquareToCircle);
|
||||||
m_AdvancedMapFilter[controller]->SetValue(g_Config.bNoTriggerFilter);
|
m_AdvancedMapFilter[controller]->SetValue(g_Config.bNoTriggerFilter);
|
||||||
|
#ifdef RERECORDING
|
||||||
|
m_CheckRecording[controller]->SetValue(g_Config.bRecording);
|
||||||
|
m_CheckPlayback[controller]->SetValue(g_Config.bPlayback);
|
||||||
|
#endif
|
||||||
//LogMsg("m_TriggerType[%i] = %i\n", controller, PadMapping[controller].triggertype);
|
//LogMsg("m_TriggerType[%i] = %i\n", controller, PadMapping[controller].triggertype);
|
||||||
|
|
||||||
// Update D-Pad
|
// Update D-Pad
|
||||||
|
195
Source/Plugins/Plugin_nJoy_SDL/Src/ReRecording.cpp
Normal file
195
Source/Plugins/Plugin_nJoy_SDL/Src/ReRecording.cpp
Normal file
@ -0,0 +1,195 @@
|
|||||||
|
//////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Project description
|
||||||
|
// ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
|
||||||
|
// Name: nJoy
|
||||||
|
// Description: A Dolphin Compatible Input Plugin
|
||||||
|
//
|
||||||
|
// Author: Falcon4ever (nJoy@falcon4ever.com)
|
||||||
|
// Site: www.multigesture.net
|
||||||
|
// Copyright (C) 2003-2008 Dolphin Project.
|
||||||
|
//
|
||||||
|
//////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// Licensetype: GNU General Public License (GPL)
|
||||||
|
//
|
||||||
|
// 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/
|
||||||
|
//
|
||||||
|
//////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// File description
|
||||||
|
/* ¯¯¯¯¯¯¯¯¯
|
||||||
|
|
||||||
|
Rerecording options
|
||||||
|
|
||||||
|
////////////////////////*/
|
||||||
|
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Include
|
||||||
|
// ¯¯¯¯¯¯¯¯¯
|
||||||
|
#include "nJoy.h"
|
||||||
|
#include "FileUtil.h"
|
||||||
|
#include "ChunkFile.h"
|
||||||
|
/////////////////////////
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef RERECORDING
|
||||||
|
|
||||||
|
|
||||||
|
namespace Recording
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Definitions
|
||||||
|
// ¯¯¯¯¯¯¯¯¯¯¯¯¯
|
||||||
|
// Pre defined maxium storage limit
|
||||||
|
#define RECORD_SIZE (1024 * 128)
|
||||||
|
SPADStatus RecordBuffer[RECORD_SIZE];
|
||||||
|
int count = 0;
|
||||||
|
////////////////////////////////
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Recording functions
|
||||||
|
// ¯¯¯¯¯¯¯¯¯¯¯¯¯
|
||||||
|
void RecordInput(const SPADStatus& _rPADStatus)
|
||||||
|
{
|
||||||
|
if (count >= RECORD_SIZE) return;
|
||||||
|
RecordBuffer[count++] = _rPADStatus;
|
||||||
|
|
||||||
|
// Logging
|
||||||
|
//u8 TmpData[sizeof(SPADStatus)];
|
||||||
|
//memcpy(TmpData, &RecordBuffer[count - 1], sizeof(SPADStatus));
|
||||||
|
//Console::Print("RecordInput(%i): %s\n", count, ArrayToString(TmpData, sizeof(SPADStatus), 0, 30).c_str());
|
||||||
|
|
||||||
|
// Auto save every ten seconds
|
||||||
|
if (count % (60 * 10) == 0) Save();
|
||||||
|
}
|
||||||
|
|
||||||
|
const SPADStatus& Play()
|
||||||
|
{
|
||||||
|
// Logging
|
||||||
|
//Console::Print("PlayRecord(%i)\n", count);
|
||||||
|
if (count >= RECORD_SIZE)
|
||||||
|
{
|
||||||
|
// Todo: Make the recording size unlimited?
|
||||||
|
//PanicAlert("The recording reached its end");
|
||||||
|
return(RecordBuffer[0]);
|
||||||
|
}
|
||||||
|
return(RecordBuffer[count++]);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Load()
|
||||||
|
{
|
||||||
|
FILE* pStream = fopen("pad-record.bin", "rb");
|
||||||
|
|
||||||
|
if (pStream != NULL)
|
||||||
|
{
|
||||||
|
fread(RecordBuffer, 1, RECORD_SIZE * sizeof(SPADStatus), pStream);
|
||||||
|
fclose(pStream);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
PanicAlert("SimplePad: Could not open pad-record.bin");
|
||||||
|
}
|
||||||
|
|
||||||
|
//Console::Print("LoadRecord()");
|
||||||
|
}
|
||||||
|
|
||||||
|
void Save()
|
||||||
|
{
|
||||||
|
// Open the file in a way that clears all old data
|
||||||
|
FILE* pStream = fopen("pad-record.bin", "wb");
|
||||||
|
|
||||||
|
if (pStream != NULL)
|
||||||
|
{
|
||||||
|
fwrite(RecordBuffer, 1, RECORD_SIZE * sizeof(SPADStatus), pStream);
|
||||||
|
fclose(pStream);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
PanicAlert("NJoy: Could not save pad-record.bin");
|
||||||
|
}
|
||||||
|
//PanicAlert("SaveRecord()");
|
||||||
|
//Console::Print("SaveRecord()");
|
||||||
|
}
|
||||||
|
////////////////////////////////
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void Initialize()
|
||||||
|
{
|
||||||
|
// -------------------------------------------
|
||||||
|
// Rerecording
|
||||||
|
// ----------------------
|
||||||
|
#ifdef RERECORDING
|
||||||
|
/* Check if we are starting the pad to record the input, and an old file exists. In that case ask
|
||||||
|
if we really want to start the recording and eventually overwrite the file */
|
||||||
|
if (g_Config.bRecording && File::Exists("pad-record.bin"))
|
||||||
|
{
|
||||||
|
if (!AskYesNo("An old version of '%s' aleady exists in your Dolphin directory. You can"
|
||||||
|
" now make a copy of it before you start a new recording and overwrite the file."
|
||||||
|
" Select Yes to continue and overwrite the file. Select No to turn off the input"
|
||||||
|
" recording and continue without recording anything.",
|
||||||
|
"pad-record.bin"))
|
||||||
|
{
|
||||||
|
// Turn off recording and continue
|
||||||
|
g_Config.bRecording = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Load recorded input if we are to play it back, otherwise begin with a blank recording
|
||||||
|
if (g_Config.bPlayback) Recording::Load();
|
||||||
|
#endif
|
||||||
|
// ----------------------
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void ShutDown()
|
||||||
|
{
|
||||||
|
// Save recording
|
||||||
|
if (g_Config.bRecording) Recording::Save();
|
||||||
|
// Reset the counter
|
||||||
|
count = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DoState(unsigned char **ptr, int mode)
|
||||||
|
{
|
||||||
|
// Load or save the counter
|
||||||
|
PointerWrap p(ptr, mode);
|
||||||
|
p.Do(count);
|
||||||
|
|
||||||
|
//Console::Print("count: %i\n", count);
|
||||||
|
|
||||||
|
// Update the frame counter for the sake of the status bar
|
||||||
|
if (mode == PointerWrap::MODE_READ)
|
||||||
|
{
|
||||||
|
#ifdef _WIN32
|
||||||
|
// This only works when rendering to the main window, I think
|
||||||
|
PostMessage(GetParent(g_PADInitialize->hWnd), WM_USER, INPUT_FRAME_COUNTER, count);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
} // Recording
|
||||||
|
|
||||||
|
|
||||||
|
#endif // RERECORDING
|
@ -265,31 +265,9 @@ void Initialize(void *init)
|
|||||||
if(ReloadDLL()) g_PADInitialize->padNumber = -1;
|
if(ReloadDLL()) g_PADInitialize->padNumber = -1;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
#ifdef RERECORDING
|
||||||
|
Recording::Initialize();
|
||||||
bool Search_Devices(std::vector<InputCommon::CONTROLLER_INFO> &_joyinfo, int &_NumPads, int &_NumGoodPads)
|
#endif
|
||||||
{
|
|
||||||
bool Success = InputCommon::SearchDevices(_joyinfo, _NumPads, _NumGoodPads);
|
|
||||||
|
|
||||||
// Warn the user if no gamepads are detected
|
|
||||||
if (_NumGoodPads == 0 && g_EmulatorRunning)
|
|
||||||
{
|
|
||||||
PanicAlert("nJoy: No Gamepad Detected");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Load PadMapping[] etc
|
|
||||||
g_Config.Load();
|
|
||||||
|
|
||||||
// Update the PadState[].joy handle
|
|
||||||
for (int i = 0; i < 4; i++)
|
|
||||||
{
|
|
||||||
if (PadMapping[i].enabled && joyinfo.size() > PadMapping[i].ID)
|
|
||||||
if(joyinfo.at(PadMapping[i].ID).Good)
|
|
||||||
PadState[i].joy = SDL_JoystickOpen(PadMapping[i].ID);
|
|
||||||
}
|
|
||||||
|
|
||||||
return Success;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Shutdown PAD (stop emulation)
|
// Shutdown PAD (stop emulation)
|
||||||
@ -301,6 +279,14 @@ void Shutdown()
|
|||||||
{
|
{
|
||||||
Console::Print("Shutdown: %i\n", SDL_WasInit(0));
|
Console::Print("Shutdown: %i\n", SDL_WasInit(0));
|
||||||
|
|
||||||
|
// -------------------------------------------
|
||||||
|
// Play back input instead of accepting any user input
|
||||||
|
// ----------------------
|
||||||
|
#ifdef RERECORDING
|
||||||
|
Recording::ShutDown();
|
||||||
|
#endif
|
||||||
|
// ----------------------
|
||||||
|
|
||||||
// Always change this variable
|
// Always change this variable
|
||||||
g_EmulatorRunning = false;
|
g_EmulatorRunning = false;
|
||||||
|
|
||||||
@ -378,7 +364,12 @@ void PAD_Input(u16 _Key, u8 _UpDown)
|
|||||||
|
|
||||||
// Save state
|
// Save state
|
||||||
// ¯¯¯¯¯¯¯¯¯¯¯¯¯¯
|
// ¯¯¯¯¯¯¯¯¯¯¯¯¯¯
|
||||||
void DoState(unsigned char **ptr, int mode) {}
|
void DoState(unsigned char **ptr, int mode)
|
||||||
|
{
|
||||||
|
#ifdef RERECORDING
|
||||||
|
Recording::DoState(ptr, mode);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// Set PAD attached pads
|
// Set PAD attached pads
|
||||||
@ -412,6 +403,18 @@ void PAD_GetStatus(u8 _numPAD, SPADStatus* _pPADStatus)
|
|||||||
disconnected */
|
disconnected */
|
||||||
if (!PadMapping[_numPAD].enabled || !PadState[_numPAD].joy) return;
|
if (!PadMapping[_numPAD].enabled || !PadState[_numPAD].joy) return;
|
||||||
|
|
||||||
|
// -------------------------------------------
|
||||||
|
// Play back input instead of accepting any user input
|
||||||
|
// ----------------------
|
||||||
|
#ifdef RERECORDING
|
||||||
|
if (g_Config.bPlayback)
|
||||||
|
{
|
||||||
|
*_pPADStatus = Recording::Play();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
// ----------------------
|
||||||
|
|
||||||
// Clear pad status
|
// Clear pad status
|
||||||
memset(_pPADStatus, 0, sizeof(SPADStatus));
|
memset(_pPADStatus, 0, sizeof(SPADStatus));
|
||||||
|
|
||||||
@ -544,6 +547,15 @@ void PAD_GetStatus(u8 _numPAD, SPADStatus* _pPADStatus)
|
|||||||
// Use rumble
|
// Use rumble
|
||||||
Pad_Use_Rumble(_numPAD, _pPADStatus);
|
Pad_Use_Rumble(_numPAD, _pPADStatus);
|
||||||
|
|
||||||
|
// -------------------------------------------
|
||||||
|
// Rerecording
|
||||||
|
// ----------------------
|
||||||
|
#ifdef RERECORDING
|
||||||
|
// Record input
|
||||||
|
if (g_Config.bRecording) Recording::RecordInput(*_pPADStatus);
|
||||||
|
#endif
|
||||||
|
// ----------------------
|
||||||
|
|
||||||
// Debugging
|
// Debugging
|
||||||
/*
|
/*
|
||||||
// Show the status of all connected pads
|
// Show the status of all connected pads
|
||||||
@ -575,6 +587,36 @@ void PAD_GetStatus(u8 _numPAD, SPADStatus* _pPADStatus)
|
|||||||
// Supporting functions
|
// Supporting functions
|
||||||
//******************************************************************************
|
//******************************************************************************
|
||||||
|
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Search for SDL devices
|
||||||
|
// ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
|
||||||
|
bool Search_Devices(std::vector<InputCommon::CONTROLLER_INFO> &_joyinfo, int &_NumPads, int &_NumGoodPads)
|
||||||
|
{
|
||||||
|
bool Success = InputCommon::SearchDevices(_joyinfo, _NumPads, _NumGoodPads);
|
||||||
|
|
||||||
|
// Warn the user if no gamepads are detected
|
||||||
|
if (_NumGoodPads == 0 && g_EmulatorRunning)
|
||||||
|
{
|
||||||
|
PanicAlert("nJoy: No Gamepad Detected");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Load PadMapping[] etc
|
||||||
|
g_Config.Load();
|
||||||
|
|
||||||
|
// Update the PadState[].joy handle
|
||||||
|
for (int i = 0; i < 4; i++)
|
||||||
|
{
|
||||||
|
if (PadMapping[i].enabled && joyinfo.size() > PadMapping[i].ID)
|
||||||
|
if(joyinfo.at(PadMapping[i].ID).Good)
|
||||||
|
PadState[i].joy = SDL_JoystickOpen(PadMapping[i].ID);
|
||||||
|
}
|
||||||
|
|
||||||
|
return Success;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////////////////
|
||||||
/* Check if any of the pads failed to open. In Windows there is a strange "IDirectInputDevice2::
|
/* Check if any of the pads failed to open. In Windows there is a strange "IDirectInputDevice2::
|
||||||
SetDataFormat() DirectX error -2147024809" after exactly four SDL_Init() and SDL_Quit() */
|
SetDataFormat() DirectX error -2147024809" after exactly four SDL_Init() and SDL_Quit() */
|
||||||
|
@ -54,6 +54,7 @@
|
|||||||
#include "../../../Core/InputCommon/Src/XInput.h"
|
#include "../../../Core/InputCommon/Src/XInput.h"
|
||||||
|
|
||||||
#include "Common.h" // Common
|
#include "Common.h" // Common
|
||||||
|
#include "Setup.h"
|
||||||
#include "pluginspecs_pad.h"
|
#include "pluginspecs_pad.h"
|
||||||
#include "IniFile.h"
|
#include "IniFile.h"
|
||||||
#include "ConsoleWindow.h"
|
#include "ConsoleWindow.h"
|
||||||
@ -122,6 +123,7 @@ extern std::vector<u8> Keys;
|
|||||||
// Variables
|
// Variables
|
||||||
// ¯¯¯¯¯¯¯¯¯
|
// ¯¯¯¯¯¯¯¯¯
|
||||||
#ifndef _EXCLUDE_MAIN_
|
#ifndef _EXCLUDE_MAIN_
|
||||||
|
extern SPADInitialize *g_PADInitialize;
|
||||||
extern FILE *pFile;
|
extern FILE *pFile;
|
||||||
extern std::vector<InputCommon::CONTROLLER_INFO> joyinfo;
|
extern std::vector<InputCommon::CONTROLLER_INFO> joyinfo;
|
||||||
extern InputCommon::CONTROLLER_STATE PadState[4];
|
extern InputCommon::CONTROLLER_STATE PadState[4];
|
||||||
@ -131,6 +133,7 @@ extern std::vector<u8> Keys;
|
|||||||
#endif
|
#endif
|
||||||
extern int NumPads, NumGoodPads, LastPad; // Number of goods pads
|
extern int NumPads, NumGoodPads, LastPad; // Number of goods pads
|
||||||
#endif
|
#endif
|
||||||
|
////////////////////////////////
|
||||||
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////////////////
|
||||||
@ -146,6 +149,25 @@ void Pad_Use_Rumble(u8 _numPAD, SPADStatus* _pPADStatus); // Rumble
|
|||||||
|
|
||||||
//void SaveConfig();
|
//void SaveConfig();
|
||||||
//void LoadConfig();
|
//void LoadConfig();
|
||||||
|
////////////////////////////////
|
||||||
|
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// ReRecording
|
||||||
|
// ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
|
||||||
|
#ifdef RERECORDING
|
||||||
|
namespace Recording
|
||||||
|
{
|
||||||
|
void Initialize();
|
||||||
|
void DoState(unsigned char **ptr, int mode);
|
||||||
|
void ShutDown();
|
||||||
|
void Save();
|
||||||
|
void Load();
|
||||||
|
const SPADStatus& Play();
|
||||||
|
void RecordInput(const SPADStatus& _rPADStatus);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
////////////////////////////////
|
||||||
|
|
||||||
|
|
||||||
#endif __NJOY_h__
|
#endif __NJOY_h__
|
Loading…
x
Reference in New Issue
Block a user