recording: various formatting and review corrections

Squashed commit:

[7955b42e3] recording: Throw errors on fread/fwrite errors.

[5a2160f9e] recording: Remove function implementation from header files

[f2937ab5f] recording: Fixed UndoCount metadata bug and will gracefully fail if savestate is missing

[d7f4d43e5] recording: Refactored code-style to be consistent

[0f77fbb71] recording: Refactor to use switch statements

[28d7945f6] recording: Resolve CMake warnings and use tagged github links for cross-linking to LilyPad

[7c01c6cb4] recording: corrected disparity between comment and code

[17a8bd8d6] recording: Remove all usages of #define

[3830f5a82] recording: Refactor enums and general cleanup

[569ef7d67] recording: Completely disable new console log sources when recording is disabled
This commit is contained in:
Tyler Wilding 2018-11-30 00:13:30 -05:00 committed by lightningterror
parent 08d923ca6f
commit 506ea4c4d2
32 changed files with 867 additions and 620 deletions

1
.gitignore vendored
View File

@ -46,6 +46,7 @@ Thumbs.db
Debug.txt Debug.txt
install_log.txt install_log.txt
padLog.txt
Debug Debug
Release Release

View File

@ -82,7 +82,6 @@ GSwindow_OffsetXplus = Alt-Ctrl-RIGHT
GSwindow_OffsetReset = Alt-Ctrl-KP_DIVIDE GSwindow_OffsetReset = Alt-Ctrl-KP_DIVIDE
# Recording Bindings # Recording Bindings
# TODO: add to http://wiki.pcsx2.net/index.php/Hotkeys
FrameAdvance = SPACE FrameAdvance = SPACE
TogglePause = Shift-P TogglePause = Shift-P
InputRecordingModeToggle = Shift-R InputRecordingModeToggle = Shift-R

View File

@ -626,6 +626,7 @@ else()
set(pcsx2SSources "") set(pcsx2SSources "")
endif() endif()
# common Sources # common Sources
set(Common set(Common
${pcsx2Sources} ${pcsx2Sources}

View File

@ -455,7 +455,7 @@ struct Pcsx2Config
EnableCheats :1, // enables cheat detection and application EnableCheats :1, // enables cheat detection and application
EnableWideScreenPatches :1, EnableWideScreenPatches :1,
#ifndef DISABLE_RECORDING #ifndef DISABLE_RECORDING
EnableRecordingTools : 1, EnableRecordingTools :1,
#endif #endif
// when enabled uses BOOT2 injection, skipping sony bios splashes // when enabled uses BOOT2 injection, skipping sony bios splashes
UseBOOT2Injection :1, UseBOOT2Injection :1,

View File

@ -575,7 +575,7 @@ __fi void rcntUpdate_vSync()
#ifndef DISABLE_RECORDING #ifndef DISABLE_RECORDING
if (g_Conf->EmuOptions.EnableRecordingTools) if (g_Conf->EmuOptions.EnableRecordingTools)
{ {
g_RecordingControls.StopCheck(); g_RecordingControls.HandleFrameAdvanceAndStop();
} }
#endif #endif

View File

@ -434,7 +434,7 @@ void Pcsx2Config::LoadSave( IniInterface& ini )
IniBitBool( EnableCheats ); IniBitBool( EnableCheats );
IniBitBool( EnableWideScreenPatches ); IniBitBool( EnableWideScreenPatches );
#ifndef DISABLE_RECORDING #ifndef DISABLE_RECORDING
IniBitBool(EnableRecordingTools); IniBitBool( EnableRecordingTools );
#endif #endif
IniBitBool( ConsoleToStdio ); IniBitBool( ConsoleToStdio );
IniBitBool( HostFs ); IniBitBool( HostFs );

View File

@ -22,130 +22,126 @@
#include "MemoryTypes.h" #include "MemoryTypes.h"
#include "SaveState.h" #include "SaveState.h"
#include "Recording/RecordingControls.h"
#include "InputRecording.h" #include "InputRecording.h"
#include "Recording/RecordingControls.h"
#include <vector> #include <vector>
InputRecording g_InputRecording; InputRecording g_InputRecording;
// --------------------------------
// Tag and save framecount along with savestate // Tag and save framecount along with savestate
// --------------------------------
void SaveStateBase::InputRecordingFreeze() void SaveStateBase::InputRecordingFreeze()
{ {
FreezeTag("InputRecording"); FreezeTag("InputRecording");
Freeze(g_FrameCount); Freeze(g_FrameCount);
if (IsLoading()) {
g_InputRecordingData.addUndoCount(); if (g_FrameCount > 0 && IsLoading())
{
g_InputRecordingData.AddUndoCount();
} }
} }
//----------------------------------
// Main func for handling controller input data // Main func for handling controller input data
// Called by Sio.cpp::sioWriteController // - Called by Sio.cpp::sioWriteController
//----------------------------------
void InputRecording::ControllerInterrupt(u8 &data, u8 &port, u16 & bufCount, u8 buf[]) void InputRecording::ControllerInterrupt(u8 &data, u8 &port, u16 & bufCount, u8 buf[])
{ {
// TODO - Multi-Tap Support // TODO - Multi-Tap Support
// Only examine controllers 1 / 2 // Only examine controllers 1 / 2
if (port < 0 || 1 < port) if (port != 0 && port != 1)
return;
//==========================
// This appears to try to ensure that we are only paying attention
// to the frames that matter, the ones that are reading from
// the controller.
//
// See - Lilypad.cpp:1254
// 0x42 is the magic number for the default read query
//
// NOTE: this appears to break if you have logging enabled in LilyPad's config!
//==========================
if (bufCount == 1) {
if (data == 0x42)
{ {
fInterruptFrame = true;
}
else {
fInterruptFrame = false;
return; return;
} }
}
else if ( bufCount == 2 ) {
// See - LilyPad.cpp:1255
// 0x5A is always the second byte in the buffer
// when the normal READ_DATA_AND_VIBRRATE (0x42)
// query is executed, this looks like a sanity check
if (buf[bufCount] != 0x5A) {
fInterruptFrame = false;
return;
}
}
/*
This appears to try to ensure that we are only paying attention
to the frames that matter, the ones that are reading from
the controller.
See - Lilypad.cpp::PADpoll - https://github.com/PCSX2/pcsx2/blob/v1.5.0-dev/plugins/LilyPad/LilyPad.cpp#L1193
0x42 is the magic number for the default read query
*/
if (bufCount == 1)
{
fInterruptFrame = data == 0x42;
if (!fInterruptFrame) if (!fInterruptFrame)
{
return; return;
}
if (state == NONE) }
else if ( bufCount == 2 )
{
/*
See - LilyPad.cpp::PADpoll - https://github.com/PCSX2/pcsx2/blob/v1.5.0-dev/plugins/LilyPad/LilyPad.cpp#L1194
0x5A is always the second byte in the buffer
when the normal READ_DATA_AND_VIBRRATE (0x42)
query is executed, this looks like a sanity check
*/
if (buf[bufCount] != 0x5A)
{
fInterruptFrame = false;
return; return;
}
}
if (!fInterruptFrame
|| state == INPUT_RECORDING_MODE_NONE
// We do not want to record or save the first two // We do not want to record or save the first two
// bytes in the data returned from LilyPad // bytes in the data returned from LilyPad
if (bufCount < 3) || bufCount < 3)
{
return; return;
//---------------
// Read or Write
//---------------
const u8 &nowBuf = buf[bufCount];
if (state == RECORD)
{
InputRecordingData.updateFrameMax(g_FrameCount);
InputRecordingData.writeKeyBuf(g_FrameCount, port, bufCount - 3, nowBuf);
} }
else if (state == REPLAY)
// Read or Write
const u8 &nowBuf = buf[bufCount];
if (state == INPUT_RECORDING_MODE_RECORD)
{ {
if (InputRecordingData.getMaxFrame() <= g_FrameCount) InputRecordingData.UpdateFrameMax(g_FrameCount);
InputRecordingData.WriteKeyBuf(g_FrameCount, port, bufCount - 3, nowBuf);
}
else if (state == INPUT_RECORDING_MODE_REPLAY)
{
if (InputRecordingData.GetMaxFrame() <= g_FrameCount)
{ {
// Pause the emulation but the movie is not closed // Pause the emulation but the movie is not closed
g_RecordingControls.Pause(); g_RecordingControls.Pause();
return; return;
} }
u8 tmp = 0; u8 tmp = 0;
if (InputRecordingData.readKeyBuf(tmp, g_FrameCount, port, bufCount - 3)) { if (InputRecordingData.ReadKeyBuf(tmp, g_FrameCount, port, bufCount - 3))
{
buf[bufCount] = tmp; buf[bufCount] = tmp;
} }
} }
} }
//---------------------------------- // GUI Handler - Stop recording
// stop void InputRecording::Stop()
//---------------------------------- {
void InputRecording::Stop() { state = INPUT_RECORDING_MODE_NONE;
state = NONE; if (InputRecordingData.Close())
if (InputRecordingData.Close()) { {
recordingConLog(L"[REC]: InputRecording Recording Stopped.\n"); recordingConLog(L"[REC]: InputRecording Recording Stopped.\n");
} }
} }
//---------------------------------- // GUI Handler - Start recording
// start
//----------------------------------
void InputRecording::Create(wxString FileName, bool fromSaveState, wxString authorName) void InputRecording::Create(wxString FileName, bool fromSaveState, wxString authorName)
{ {
g_RecordingControls.Pause(); g_RecordingControls.Pause();
Stop(); Stop();
// create // create
if (!InputRecordingData.Open(FileName, true, fromSaveState)) { if (!InputRecordingData.Open(FileName, true, fromSaveState))
{
return; return;
} }
// Set author name // Set author name
if (!authorName.IsEmpty()) if (!authorName.IsEmpty())
{ {
InputRecordingData.getHeader().setAuthor(authorName); InputRecordingData.GetHeader().SetAuthor(authorName);
} }
// Set Game Name // Set Game Name
// Code loosely taken from AppCoreThread.cpp to resolve the Game Name // Code loosely taken from AppCoreThread.cpp to resolve the Game Name
@ -164,24 +160,27 @@ void InputRecording::Create(wxString FileName, bool fromSaveState, wxString auth
} }
} }
} }
InputRecordingData.getHeader().setGameName(!gameName.IsEmpty() ? gameName : Path::GetFilename(g_Conf->CurrentIso)); InputRecordingData.GetHeader().SetGameName(!gameName.IsEmpty() ? gameName : Path::GetFilename(g_Conf->CurrentIso));
InputRecordingData.writeHeader(); InputRecordingData.WriteHeader();
state = RECORD; state = INPUT_RECORDING_MODE_RECORD;
recordingConLog(wxString::Format(L"[REC]: Started new recording - [%s]\n", FileName)); recordingConLog(wxString::Format(L"[REC]: Started new recording - [%s]\n", FileName));
// In every case, we reset the g_FrameCount // In every case, we reset the g_FrameCount
g_FrameCount = 0; g_FrameCount = 0;
} }
// GUI Handler - Play a recording
void InputRecording::Play(wxString FileName, bool fromSaveState) void InputRecording::Play(wxString FileName, bool fromSaveState)
{ {
g_RecordingControls.Pause(); g_RecordingControls.Pause();
Stop(); Stop();
if (!InputRecordingData.Open(FileName, false, false)) { if (!InputRecordingData.Open(FileName, false, false))
{
return; return;
} }
if (!InputRecordingData.readHeaderAndCheck()) { if (!InputRecordingData.ReadHeaderAndCheck())
{
recordingConLog(L"[REC]: This file is not a correct InputRecording file.\n"); recordingConLog(L"[REC]: This file is not a correct InputRecording file.\n");
InputRecordingData.Close(); InputRecordingData.Close();
return; return;
@ -189,32 +188,46 @@ void InputRecording::Play(wxString FileName, bool fromSaveState)
// Check author name // Check author name
if (!g_Conf->CurrentIso.IsEmpty()) if (!g_Conf->CurrentIso.IsEmpty())
{ {
if (Path::GetFilename(g_Conf->CurrentIso) != InputRecordingData.getHeader().gameName) { if (Path::GetFilename(g_Conf->CurrentIso) != InputRecordingData.GetHeader().gameName)
{
recordingConLog(L"[REC]: Information on CD in Movie file is Different.\n"); recordingConLog(L"[REC]: Information on CD in Movie file is Different.\n");
} }
} }
state = REPLAY; state = INPUT_RECORDING_MODE_REPLAY;
recordingConLog(wxString::Format(L"[REC]: Replaying movie - [%s]\n", FileName)); recordingConLog(wxString::Format(L"[REC]: Replaying movie - [%s]\n", FileName));
recordingConLog(wxString::Format(L"Recording File Version: %d\n", InputRecordingData.getHeader().version)); recordingConLog(wxString::Format(L"[REC]: Recording File Version: %d\n", InputRecordingData.GetHeader().version));
recordingConLog(wxString::Format(L"Associated Game Name / ISO Filename: %s\n", InputRecordingData.getHeader().gameName)); recordingConLog(wxString::Format(L"[REC]: Associated Game Name / ISO Filename: %s\n", InputRecordingData.GetHeader().gameName));
recordingConLog(wxString::Format(L"Author: %s\n", InputRecordingData.getHeader().author)); recordingConLog(wxString::Format(L"[REC]: Author: %s\n", InputRecordingData.GetHeader().author));
recordingConLog(wxString::Format(L"MaxFrame: %d\n", InputRecordingData.getMaxFrame())); recordingConLog(wxString::Format(L"[REC]: MaxFrame: %d\n", InputRecordingData.GetMaxFrame()));
recordingConLog(wxString::Format(L"UndoCount: %d\n", InputRecordingData.getUndoCount())); recordingConLog(wxString::Format(L"[REC]: UndoCount: %d\n", InputRecordingData.GetUndoCount()));
} }
//---------------------------------- // Keybind Handler - Toggle between recording input and not
// shortcut key
//----------------------------------
void InputRecording::RecordModeToggle() void InputRecording::RecordModeToggle()
{ {
if (state == REPLAY) { if (state == INPUT_RECORDING_MODE_REPLAY)
state = RECORD; {
state = INPUT_RECORDING_MODE_RECORD;
recordingConLog("[REC]: Record mode ON.\n"); recordingConLog("[REC]: Record mode ON.\n");
} }
else if (state == RECORD) { else if (state == INPUT_RECORDING_MODE_RECORD)
state = REPLAY; {
state = INPUT_RECORDING_MODE_REPLAY;
recordingConLog("[REC]: Replay mode ON.\n"); recordingConLog("[REC]: Replay mode ON.\n");
} }
} }
INPUT_RECORDING_MODE InputRecording::GetModeState()
{
return state;
}
InputRecordingFile & InputRecording::GetInputRecordingData()
{
return InputRecordingData;
}
bool InputRecording::IsInterruptFrame()
{
return fInterruptFrame;
}

View File

@ -18,46 +18,37 @@
#include "InputRecordingFile.h" #include "InputRecordingFile.h"
//---------------------------- enum INPUT_RECORDING_MODE
// InputRecording {
//---------------------------- INPUT_RECORDING_MODE_NONE,
class InputRecording { INPUT_RECORDING_MODE_RECORD,
INPUT_RECORDING_MODE_REPLAY,
};
class InputRecording
{
public: public:
InputRecording() {} InputRecording() {}
~InputRecording(){} ~InputRecording(){}
public:
// controller
void ControllerInterrupt(u8 &data, u8 &port, u16 & BufCount, u8 buf[]); void ControllerInterrupt(u8 &data, u8 &port, u16 & BufCount, u8 buf[]);
// menu bar void RecordModeToggle();
INPUT_RECORDING_MODE GetModeState();
InputRecordingFile & GetInputRecordingData();
bool IsInterruptFrame();
void Stop(); void Stop();
void Create(wxString filename, bool fromSaveState, wxString authorName); void Create(wxString filename, bool fromSaveState, wxString authorName);
void Play(wxString filename, bool fromSaveState); void Play(wxString filename, bool fromSaveState);
// shortcut key
void RecordModeToggle();
public:
enum KEY_MOVIE_MODE {
NONE,
RECORD,
REPLAY,
};
public:
// getter
KEY_MOVIE_MODE getModeState() { return state; }
InputRecordingFile & getInputRecordingData() {return InputRecordingData;}
bool isInterruptFrame() { return fInterruptFrame; }
private: private:
InputRecordingFile InputRecordingData; InputRecordingFile InputRecordingData;
KEY_MOVIE_MODE state = NONE; INPUT_RECORDING_MODE state = INPUT_RECORDING_MODE_NONE;
bool fInterruptFrame = false; bool fInterruptFrame = false;
}; };
extern InputRecording g_InputRecording; extern InputRecording g_InputRecording;
#define g_InputRecordingData (g_InputRecording.getInputRecordingData()) static InputRecordingFile& g_InputRecordingData = g_InputRecording.GetInputRecordingData();
#define g_InputRecordingHeader (g_InputRecording.getInputRecordingData().getHeader()) static InputRecordingHeader& g_InputRecordingHeader = g_InputRecording.GetInputRecordingData().GetHeader();

View File

@ -23,25 +23,17 @@
#include "InputRecordingFile.h" #include "InputRecordingFile.h"
#define HEADER_SIZE (sizeof(InputRecordingHeader)+4+4) long InputRecordingFile::GetBlockSeekPoint(const long & frame)
#define SAVESTATE_HEADER_SIZE (sizeof(bool))
#define BLOCK_HEADER_SIZE (0)
#define BLOCK_DATA_SIZE (18*2)
#define BLOCK_SIZE (BLOCK_HEADER_SIZE+BLOCK_DATA_SIZE)
#define SEEKPOINT_FRAMEMAX (sizeof(InputRecordingHeader))
#define SEEKPOINT_UNDOCOUNT (sizeof(InputRecordingHeader)+4)
#define SEEKPOINT_SAVESTATE (SEEKPOINT_UNDOCOUNT+4)
long InputRecordingFile::_getBlockSeekPoint(const long & frame)
{ {
if (savestate.fromSavestate) { if (savestate.fromSavestate)
return HEADER_SIZE {
+ SAVESTATE_HEADER_SIZE return RecordingHeaderSize
+ frame * BLOCK_SIZE; + RecordingSavestateHeaderSize
+ frame * RecordingBlockSize;
} }
else { else
return HEADER_SIZE + sizeof(bool) + (frame)*BLOCK_SIZE; {
return RecordingHeaderSize + sizeof(bool) + (frame)*RecordingBlockSize;
} }
} }
@ -50,11 +42,12 @@ bool InputRecordingFile::Open(const wxString path, bool fNewOpen, bool fromSaveS
{ {
Close(); Close();
wxString mode = L"rb+"; wxString mode = L"rb+";
if (fNewOpen) { if (fNewOpen)
{
mode = L"wb+"; mode = L"wb+";
MaxFrame = 0; MaxFrame = 0;
UndoCount = 0; UndoCount = 0;
header.init(); header.Init();
} }
recordingFile = wxFopen(path, mode); recordingFile = wxFopen(path, mode);
if ( recordingFile == NULL ) if ( recordingFile == NULL )
@ -64,98 +57,114 @@ bool InputRecordingFile::Open(const wxString path, bool fNewOpen, bool fromSaveS
} }
filename = path; filename = path;
// problems seem to be be based in how we are saving the savestate if (fNewOpen)
if (fNewOpen) { {
if (fromSaveState) { if (fromSaveState)
{
savestate.fromSavestate = true; savestate.fromSavestate = true;
// TODO - Return save-state data back into the movie file eventually.
FILE* ssFileCheck = wxFopen(path + "_SaveState.p2s", "r"); FILE* ssFileCheck = wxFopen(path + "_SaveState.p2s", "r");
if (ssFileCheck != NULL) { if (ssFileCheck != NULL)
{
wxCopyFile(path + "_SaveState.p2s", path + "_SaveState.p2s.bak", false); wxCopyFile(path + "_SaveState.p2s", path + "_SaveState.p2s.bak", false);
}
fclose(ssFileCheck); fclose(ssFileCheck);
}
StateCopy_SaveToFile(path + "_SaveState.p2s"); StateCopy_SaveToFile(path + "_SaveState.p2s");
} }
else { else
{
sApp.SysExecute(); sApp.SysExecute();
} }
} }
return true; return true;
} }
// Gracefully close the current recording file
bool InputRecordingFile::Close() bool InputRecordingFile::Close()
{ {
if (recordingFile == NULL) if (recordingFile == NULL)
{
return false; return false;
writeHeader(); }
writeSaveState(); WriteHeader();
WriteSaveState();
fclose(recordingFile); fclose(recordingFile);
recordingFile = NULL; recordingFile = NULL;
filename = ""; filename = "";
return true; return true;
} }
bool InputRecordingFile::writeSaveState() { // Write savestate flag to file
bool InputRecordingFile::WriteSaveState() {
if (recordingFile == NULL) if (recordingFile == NULL)
{
return false; return false;
}
fseek(recordingFile, SEEKPOINT_SAVESTATE, SEEK_SET); fseek(recordingFile, RecordingSeekpointSaveState, SEEK_SET);
if (fwrite(&savestate.fromSavestate, sizeof(bool), 1, recordingFile) != 1) if (fwrite(&savestate.fromSavestate, sizeof(bool), 1, recordingFile) != 1)
{
return false; return false;
}
return true; return true;
} }
//---------------------------------- // Write controller input buffer to file (per frame)
// write frame bool InputRecordingFile::WriteKeyBuf(const uint & frame, const uint port, const uint bufIndex, const u8 & buf)
//----------------------------------
bool InputRecordingFile::writeKeyBuf(const uint & frame, const uint port, const uint bufIndex, const u8 & buf)
{ {
if (recordingFile == NULL) if (recordingFile == NULL)
{
return false; return false;
}
long seek = _getBlockSeekPoint(frame) + BLOCK_HEADER_SIZE + 18 * port + bufIndex; long seek = GetBlockSeekPoint(frame) + RecordingBlockHeaderSize + 18 * port + bufIndex;
if (fseek(recordingFile, seek, SEEK_SET) != 0) if (fseek(recordingFile, seek, SEEK_SET) != 0
return false; || fwrite(&buf, 1, 1, recordingFile) != 1)
if (fwrite(&buf, 1, 1, recordingFile) != 1) {
return false; return false;
}
fflush(recordingFile); fflush(recordingFile);
return true; return true;
} }
//---------------------------------- // Read controller input buffer from file (per frame)
// read frame bool InputRecordingFile::ReadKeyBuf(u8 & result,const uint & frame, const uint port, const uint bufIndex)
//----------------------------------
bool InputRecordingFile::readKeyBuf(u8 & result,const uint & frame, const uint port, const uint bufIndex)
{ {
if (recordingFile == NULL) if (recordingFile == NULL)
{
return false; return false;
}
long seek = _getBlockSeekPoint(frame) + BLOCK_HEADER_SIZE + 18 * port + bufIndex; long seek = GetBlockSeekPoint(frame) + RecordingBlockHeaderSize + 18 * port + bufIndex;
if (fseek(recordingFile, seek, SEEK_SET) != 0) if (fseek(recordingFile, seek, SEEK_SET) != 0)
{
return false; return false;
}
if (fread(&result, 1, 1, recordingFile) != 1) if (fread(&result, 1, 1, recordingFile) != 1)
{
return false; return false;
}
return true; return true;
} }
//===================================
// pad void InputRecordingFile::GetPadData(PadData & result, unsigned long frame)
//===================================
void InputRecordingFile::getPadData(PadData & result, unsigned long frame)
{ {
result.fExistKey = false; result.fExistKey = false;
if (recordingFile == NULL) if (recordingFile == NULL)
{
return; return;
}
long seek = _getBlockSeekPoint(frame) + BLOCK_HEADER_SIZE; long seek = GetBlockSeekPoint(frame) + RecordingBlockHeaderSize;
if (fseek(recordingFile, seek, SEEK_SET) != 0) if (fseek(recordingFile, seek, SEEK_SET) != 0
return; || fread(result.buf, 1, RecordingBlockDataSize, recordingFile) == 0)
if (fread(result.buf, 1, BLOCK_DATA_SIZE, recordingFile) == 0) {
return; return;
}
result.fExistKey = true; result.fExistKey = true;
} }
@ -163,21 +172,33 @@ void InputRecordingFile::getPadData(PadData & result, unsigned long frame)
bool InputRecordingFile::DeletePadData(unsigned long frame) bool InputRecordingFile::DeletePadData(unsigned long frame)
{ {
if (recordingFile == NULL) if (recordingFile == NULL)
{
return false; return false;
}
for (unsigned long i = frame; i < MaxFrame - 1; i++) for (unsigned long i = frame; i < MaxFrame - 1; i++)
{ {
long seek1 = _getBlockSeekPoint(i+1) + BLOCK_HEADER_SIZE; long seek1 = GetBlockSeekPoint(i+1) + RecordingBlockHeaderSize;
long seek2 = _getBlockSeekPoint(i) + BLOCK_HEADER_SIZE; long seek2 = GetBlockSeekPoint(i) + RecordingBlockHeaderSize;
u8 buf[2][18]; u8 buf[2][18];
fseek(recordingFile, seek1, SEEK_SET); fseek(recordingFile, seek1, SEEK_SET);
fread(buf, 1, BLOCK_DATA_SIZE, recordingFile); int rSize = fread(buf, 1, RecordingBlockDataSize, recordingFile);
if (rSize != RecordingBlockDataSize)
{
recordingConLog(wxString::Format("[REC]: Error encountered when reading from file: Expected %d bytes, read %d instead.\n", RecordingBlockDataSize, rSize));
return false;
}
fseek(recordingFile, seek2, SEEK_SET); fseek(recordingFile, seek2, SEEK_SET);
fwrite(buf,1, BLOCK_DATA_SIZE, recordingFile); rSize = fwrite(buf, 1, RecordingBlockDataSize, recordingFile);
if (rSize != RecordingBlockDataSize)
{
recordingConLog(wxString::Format("[REC]: Error encountered when writing to file: Expected %d bytes, read %d instead.\n", RecordingBlockDataSize, rSize));
return false;
}
} }
MaxFrame--; MaxFrame--;
writeMaxFrame(); WriteMaxFrame();
fflush(recordingFile); fflush(recordingFile);
return true; return true;
@ -185,29 +206,42 @@ bool InputRecordingFile::DeletePadData(unsigned long frame)
bool InputRecordingFile::InsertPadData(unsigned long frame, const PadData& key) bool InputRecordingFile::InsertPadData(unsigned long frame, const PadData& key)
{ {
if (recordingFile == NULL) if (recordingFile == NULL || !key.fExistKey)
return false; {
if (!key.fExistKey)
return false; return false;
}
for (unsigned long i = MaxFrame - 1; i >= frame; i--) for (unsigned long i = MaxFrame - 1; i >= frame; i--)
{ {
long seek1 = _getBlockSeekPoint(i) + BLOCK_HEADER_SIZE; long seek1 = GetBlockSeekPoint(i) + RecordingBlockHeaderSize;
long seek2 = _getBlockSeekPoint(i+1) + BLOCK_HEADER_SIZE; long seek2 = GetBlockSeekPoint(i+1) + RecordingBlockHeaderSize;
u8 buf[2][18]; u8 buf[2][18];
fseek(recordingFile, seek1, SEEK_SET); fseek(recordingFile, seek1, SEEK_SET);
fread(buf, 1, BLOCK_DATA_SIZE, recordingFile); int rSize = fread(buf, 1, RecordingBlockDataSize, recordingFile);
fseek(recordingFile, seek2, SEEK_SET); if (rSize != RecordingBlockDataSize)
fwrite(buf, 1, BLOCK_DATA_SIZE, recordingFile);
}
{ {
long seek = _getBlockSeekPoint(frame) + BLOCK_HEADER_SIZE; recordingConLog(wxString::Format("[REC]: Error encountered when reading from file: Expected %d bytes, read %d instead.\n", RecordingBlockDataSize, rSize));
return false;
}
fseek(recordingFile, seek2, SEEK_SET);
rSize = fwrite(buf, 1, RecordingBlockDataSize, recordingFile);
if (rSize != RecordingBlockDataSize)
{
recordingConLog(wxString::Format("[REC]: Error encountered when writing to file: Expected %d bytes, wrote %d instead.\n", RecordingBlockDataSize, rSize));
return false;
}
}
long seek = GetBlockSeekPoint(frame) + RecordingBlockHeaderSize;
fseek(recordingFile, seek, SEEK_SET); fseek(recordingFile, seek, SEEK_SET);
fwrite(key.buf, 1, BLOCK_DATA_SIZE, recordingFile); int rSize = fwrite(key.buf, 1, RecordingBlockDataSize, recordingFile);
if (rSize != RecordingBlockDataSize)
{
recordingConLog(wxString::Format("[REC]: Error encountered when writing to file: Expected %d bytes, wrote %d instead.\n", RecordingBlockDataSize, rSize));
return false;
} }
MaxFrame++; MaxFrame++;
writeMaxFrame(); WriteMaxFrame();
fflush(recordingFile); fflush(recordingFile);
return true; return true;
@ -216,100 +250,149 @@ bool InputRecordingFile::InsertPadData(unsigned long frame, const PadData& key)
bool InputRecordingFile::UpdatePadData(unsigned long frame, const PadData& key) bool InputRecordingFile::UpdatePadData(unsigned long frame, const PadData& key)
{ {
if (recordingFile == NULL) if (recordingFile == NULL)
{
return false; return false;
}
if (!key.fExistKey) if (!key.fExistKey)
{
return false; return false;
}
long seek = _getBlockSeekPoint(frame) + BLOCK_HEADER_SIZE; long seek = GetBlockSeekPoint(frame) + RecordingBlockHeaderSize;
fseek(recordingFile, seek, SEEK_SET); fseek(recordingFile, seek, SEEK_SET);
if (fwrite(key.buf, 1, BLOCK_DATA_SIZE, recordingFile) == 0) if (fwrite(key.buf, 1, RecordingBlockDataSize, recordingFile) == 0)
{
return false; return false;
}
fflush(recordingFile); fflush(recordingFile);
return true; return true;
} }
// Verify header of recording file // Verify header of recording file
bool InputRecordingFile::readHeaderAndCheck() bool InputRecordingFile::ReadHeaderAndCheck()
{ {
if (recordingFile == NULL) return false; if (recordingFile == NULL)
{
return false;
}
rewind(recordingFile); rewind(recordingFile);
if (fread(&header, sizeof(InputRecordingHeader), 1, recordingFile) != 1) return false; if (fread(&header, sizeof(InputRecordingHeader), 1, recordingFile) != 1
if (fread(&MaxFrame, 4, 1, recordingFile) != 1) return false; || fread(&MaxFrame, 4, 1, recordingFile) != 1
if (fread(&UndoCount, 4, 1, recordingFile) != 1) return false; || fread(&UndoCount, 4, 1, recordingFile) != 1
if (fread(&savestate.fromSavestate, sizeof(bool), 1, recordingFile) != 1) return false; || fread(&savestate.fromSavestate, sizeof(bool), 1, recordingFile) != 1)
if (savestate.fromSavestate) { {
return false;
}
if (savestate.fromSavestate)
{
FILE* ssFileCheck = wxFopen(filename + "_SaveState.p2s", "r"); FILE* ssFileCheck = wxFopen(filename + "_SaveState.p2s", "r");
if (ssFileCheck = NULL) { if (ssFileCheck == NULL)
{
recordingConLog(wxString::Format("[REC]: Could not locate savestate file at location - %s\n", filename + "_SaveState.p2s")); recordingConLog(wxString::Format("[REC]: Could not locate savestate file at location - %s\n", filename + "_SaveState.p2s"));
return false; return false;
} }
fclose(ssFileCheck); fclose(ssFileCheck);
StateCopy_LoadFromFile(filename + "_SaveState.p2s"); StateCopy_LoadFromFile(filename + "_SaveState.p2s");
} }
else { else
{
sApp.SysExecute(); sApp.SysExecute();
} }
// Check for current verison // Check for current verison
if (header.version != 1) { if (header.version != 1)
{
recordingConLog(wxString::Format("[REC]: Input recording file is not a supported version - %d\n", header.version)); recordingConLog(wxString::Format("[REC]: Input recording file is not a supported version - %d\n", header.version));
return false; return false;
} }
return true; return true;
} }
bool InputRecordingFile::writeHeader() bool InputRecordingFile::WriteHeader()
{ {
if (recordingFile == NULL) return false; if (recordingFile == NULL)
{
return false;
}
rewind(recordingFile); rewind(recordingFile);
if (fwrite(&header, sizeof(InputRecordingHeader), 1, recordingFile) != 1) return false; if (fwrite(&header, sizeof(InputRecordingHeader), 1, recordingFile) != 1)
{
return false;
}
return true; return true;
} }
bool InputRecordingFile::writeMaxFrame() bool InputRecordingFile::WriteMaxFrame()
{ {
if (recordingFile == NULL)return false; if (recordingFile == NULL)
fseek(recordingFile, SEEKPOINT_FRAMEMAX, SEEK_SET); {
if (fwrite(&MaxFrame, 4, 1, recordingFile) != 1) return false; return false;
}
fseek(recordingFile, RecordingSeekpointFrameMax, SEEK_SET);
if (fwrite(&MaxFrame, 4, 1, recordingFile) != 1)
{
return false;
}
return true; return true;
} }
void InputRecordingFile::updateFrameMax(unsigned long frame) void InputRecordingFile::UpdateFrameMax(unsigned long frame)
{ {
if (MaxFrame >= frame) { if (recordingFile == NULL || MaxFrame >= frame)
{
return; return;
} }
MaxFrame = frame; MaxFrame = frame;
if (recordingFile == NULL)return ; fseek(recordingFile, RecordingSeekpointFrameMax, SEEK_SET);
fseek(recordingFile, SEEKPOINT_FRAMEMAX, SEEK_SET);
fwrite(&MaxFrame, 4, 1, recordingFile); fwrite(&MaxFrame, 4, 1, recordingFile);
} }
void InputRecordingFile::addUndoCount() void InputRecordingFile::AddUndoCount()
{ {
UndoCount++; UndoCount++;
if (recordingFile == NULL) if (recordingFile == NULL)
{
return; return;
fseek(recordingFile, SEEKPOINT_UNDOCOUNT, SEEK_SET); }
fseek(recordingFile, RecordingSeekpointUndoCount, SEEK_SET);
fwrite(&UndoCount, 4, 1, recordingFile); fwrite(&UndoCount, 4, 1, recordingFile);
} }
void InputRecordingHeader::setAuthor(wxString _author) void InputRecordingHeader::SetAuthor(wxString _author)
{ {
int max = ArraySize(author) - 1; int max = ArraySize(author) - 1;
strncpy(author, _author.c_str(), max); strncpy(author, _author.c_str(), max);
author[max] = 0; author[max] = 0;
} }
void InputRecordingHeader::setGameName(wxString _gameName) void InputRecordingHeader::SetGameName(wxString _gameName)
{ {
int max = ArraySize(gameName) - 1; int max = ArraySize(gameName) - 1;
strncpy(gameName, _gameName.c_str(), max); strncpy(gameName, _gameName.c_str(), max);
gameName[max] = 0; gameName[max] = 0;
} }
void InputRecordingHeader::init() void InputRecordingHeader::Init()
{ {
memset(author, 0, ArraySize(author)); memset(author, 0, ArraySize(author));
memset(gameName, 0, ArraySize(gameName)); memset(gameName, 0, ArraySize(gameName));
} }
InputRecordingHeader& InputRecordingFile::GetHeader()
{
return header; }
unsigned long& InputRecordingFile::GetMaxFrame()
{
return MaxFrame;
}
unsigned long& InputRecordingFile::GetUndoCount()
{
return UndoCount;
}
const wxString & InputRecordingFile::GetFilename()
{
return filename;
}

View File

@ -18,6 +18,7 @@
#include "PadData.h" #include "PadData.h"
#include "System.h" #include "System.h"
struct InputRecordingHeader struct InputRecordingHeader
{ {
u8 version = 1; u8 version = 1;
@ -26,11 +27,13 @@ struct InputRecordingHeader
char gameName[255] = ""; char gameName[255] = "";
public: public:
void setAuthor(wxString author); void SetAuthor(wxString author);
void setGameName(wxString cdrom); void SetGameName(wxString cdrom);
void init(); void Init();
}; };
static const int RecordingHeaderSize = sizeof(InputRecordingHeader) + 4 + 4;
// Contains info about the starting point of the movie // Contains info about the starting point of the movie
struct InputRecordingSavestate struct InputRecordingSavestate
{ {
@ -38,8 +41,8 @@ struct InputRecordingSavestate
bool fromSavestate = false; bool fromSavestate = false;
}; };
class InputRecordingFile
class InputRecordingFile { {
public: public:
InputRecordingFile() {} InputRecordingFile() {}
~InputRecordingFile() { Close(); } ~InputRecordingFile() { Close(); }
@ -47,34 +50,42 @@ public:
// Movie File Manipulation // Movie File Manipulation
bool Open(const wxString fn, bool fNewOpen, bool fromSaveState); bool Open(const wxString fn, bool fNewOpen, bool fromSaveState);
bool Close(); bool Close();
bool writeKeyBuf(const uint & frame, const uint port, const uint bufIndex, const u8 & buf); bool WriteKeyBuf(const uint & frame, const uint port, const uint bufIndex, const u8 & buf);
bool readKeyBuf(u8 & result, const uint & frame, const uint port, const uint bufIndex); bool ReadKeyBuf(u8 & result, const uint & frame, const uint port, const uint bufIndex);
// Controller Data // Controller Data
void getPadData(PadData & result_pad, unsigned long frame); void GetPadData(PadData & result_pad, unsigned long frame);
bool DeletePadData(unsigned long frame); bool DeletePadData(unsigned long frame);
bool InsertPadData(unsigned long frame, const PadData& key); bool InsertPadData(unsigned long frame, const PadData& key);
bool UpdatePadData(unsigned long frame, const PadData& key); bool UpdatePadData(unsigned long frame, const PadData& key);
// Header // Header
InputRecordingHeader& getHeader() { return header; } InputRecordingHeader& GetHeader();
unsigned long& getMaxFrame() { return MaxFrame; } unsigned long& GetMaxFrame();
unsigned long& getUndoCount() { return UndoCount; } unsigned long& GetUndoCount();
const wxString & getFilename() { return filename; } const wxString & GetFilename();
bool writeHeader(); bool WriteHeader();
bool writeMaxFrame(); bool WriteMaxFrame();
bool writeSaveState(); bool WriteSaveState();
bool readHeaderAndCheck(); bool ReadHeaderAndCheck();
void updateFrameMax(unsigned long frame); void UpdateFrameMax(unsigned long frame);
void addUndoCount(); void AddUndoCount();
private: private:
static const int RecordingSavestateHeaderSize = sizeof(bool);
static const int RecordingBlockHeaderSize = 0;
static const int RecordingBlockDataSize = 18 * 2;
static const int RecordingBlockSize = RecordingBlockHeaderSize + RecordingBlockDataSize;
static const int RecordingSeekpointFrameMax = sizeof(InputRecordingHeader);
static const int RecordingSeekpointUndoCount = sizeof(InputRecordingHeader) + 4;
static const int RecordingSeekpointSaveState = RecordingSeekpointUndoCount + 4;
// Movie File // Movie File
FILE * recordingFile = NULL; FILE * recordingFile = NULL;
wxString filename = ""; wxString filename = "";
long _getBlockSeekPoint(const long & frame); long GetBlockSeekPoint(const long & frame);
// Header // Header
InputRecordingHeader header; InputRecordingHeader header;

View File

@ -1,81 +0,0 @@
/* PCSX2 - PS2 Emulator for PCs
* Copyright (C) 2002-2019 PCSX2 Dev Team
*
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
* of the GNU Lesser General Public License as published by the Free Software Found-
* ation, either version 3 of the License, or (at your option) any later version.
*
* PCSX2 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 for more details.
*
* You should have received a copy of the GNU General Public License along with PCSX2.
* If not, see <http://www.gnu.org/licenses/>.
*/
#include "PrecompiledHeader.h"
#include "NewRecordingFrame.h"
enum {
File,
Author,
From
};
NewRecordingFrame::NewRecordingFrame(wxWindow *parent)
: wxDialog(parent, wxID_ANY, "New Input Recording", wxDefaultPosition, wxDefaultSize, wxSTAY_ON_TOP | wxCAPTION)
{
wxPanel *panel = new wxPanel(this, wxID_ANY,
wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL, _("panel"));
wxFlexGridSizer *fgs = new wxFlexGridSizer(4, 2, 20, 20);
wxBoxSizer *container = new wxBoxSizer(wxVERTICAL);
m_fileLabel = new wxStaticText(panel, wxID_ANY, _("File Path"), wxDefaultPosition, wxDefaultSize, wxALIGN_CENTER);
m_authorLabel = new wxStaticText(panel, wxID_ANY, _("Author"), wxDefaultPosition, wxDefaultSize, wxALIGN_CENTER);
m_fromLabel = new wxStaticText(panel, wxID_ANY, _("Record From"), wxDefaultPosition, wxDefaultSize, wxALIGN_CENTER);
m_filePicker = new wxFilePickerCtrl(panel, File, wxEmptyString, "File", L"p2m2 file(*.p2m2)|*.p2m2", wxDefaultPosition, wxDefaultSize, wxFLP_SAVE | wxFLP_OVERWRITE_PROMPT | wxFLP_USE_TEXTCTRL);
m_authorInput = new wxTextCtrl(panel, Author, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxTE_PROCESS_ENTER);
wxArrayString choices;
choices.Add("Current Frame");
choices.Add("Power-On");
m_fromChoice = new wxChoice(panel, From, wxDefaultPosition, wxDefaultSize, choices);
m_fromChoice->SetSelection(0);
m_startRecording = new wxButton(panel, wxID_OK, _("Ok"), wxDefaultPosition, wxDefaultSize);
m_cancelRecording = new wxButton(panel, wxID_CANCEL, _("Cancel"), wxDefaultPosition, wxDefaultSize);
fgs->Add(m_fileLabel, 1);
fgs->Add(m_filePicker, 1);
fgs->Add(m_authorLabel, 1);
fgs->Add(m_authorInput, 1, wxEXPAND);
fgs->Add(m_fromLabel, 1);
fgs->Add(m_fromChoice, 1, wxEXPAND);
fgs->Add(m_startRecording, 1);
fgs->Add(m_cancelRecording, 1);
container->Add(fgs, 1, wxALL | wxEXPAND, 15);
panel->SetSizer(container);
panel->GetSizer()->Fit(this);
Centre();
}
wxString NewRecordingFrame::getFile() const
{
return m_filePicker->GetPath();
}
wxString NewRecordingFrame::getAuthor() const
{
return m_authorInput->GetValue();
}
int NewRecordingFrame::getFrom() const
{
return m_fromChoice->GetSelection();
}

View File

@ -1,42 +0,0 @@
/* PCSX2 - PS2 Emulator for PCs
* Copyright (C) 2002-2019 PCSX2 Dev Team
*
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
* of the GNU Lesser General Public License as published by the Free Software Found-
* ation, either version 3 of the License, or (at your option) any later version.
*
* PCSX2 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 for more details.
*
* You should have received a copy of the GNU General Public License along with PCSX2.
* If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <wx/wx.h>
#include <wx/filepicker.h>
/*
* The Dialog to pop-up when recording a new movie
*/
class NewRecordingFrame : public wxDialog
{
public:
NewRecordingFrame(wxWindow *parent);
wxString getFile() const;
wxString getAuthor() const;
int getFrom() const;
private:
wxStaticText *m_fileLabel;
wxFilePickerCtrl *m_filePicker;
wxStaticText *m_authorLabel;
wxTextCtrl *m_authorInput;
wxStaticText *m_fromLabel;
wxChoice *m_fromChoice;
wxButton *m_startRecording;
wxButton *m_cancelRecording;
};

View File

@ -17,17 +17,11 @@
#include "NewRecordingFrame.h" #include "NewRecordingFrame.h"
enum {
File,
Author,
From
};
NewRecordingFrame::NewRecordingFrame(wxWindow *parent) NewRecordingFrame::NewRecordingFrame(wxWindow *parent)
: wxDialog(parent, wxID_ANY, "New Input Recording", wxDefaultPosition, wxDefaultSize, wxSTAY_ON_TOP | wxCAPTION) : wxDialog(parent, wxID_ANY, "New Input Recording", wxDefaultPosition, wxDefaultSize, wxSTAY_ON_TOP | wxCAPTION)
{ {
wxPanel *panel = new wxPanel(this, wxID_ANY, wxPanel *panel = new wxPanel(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL, _("panel"));
wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL, _("panel"));
wxFlexGridSizer *fgs = new wxFlexGridSizer(4, 2, 20, 20); wxFlexGridSizer *fgs = new wxFlexGridSizer(4, 2, 20, 20);
wxBoxSizer *container = new wxBoxSizer(wxVERTICAL); wxBoxSizer *container = new wxBoxSizer(wxVERTICAL);
@ -36,12 +30,12 @@ NewRecordingFrame::NewRecordingFrame(wxWindow *parent)
m_authorLabel = new wxStaticText(panel, wxID_ANY, _("Author"), wxDefaultPosition, wxDefaultSize, wxALIGN_CENTER); m_authorLabel = new wxStaticText(panel, wxID_ANY, _("Author"), wxDefaultPosition, wxDefaultSize, wxALIGN_CENTER);
m_fromLabel = new wxStaticText(panel, wxID_ANY, _("Record From"), wxDefaultPosition, wxDefaultSize, wxALIGN_CENTER); m_fromLabel = new wxStaticText(panel, wxID_ANY, _("Record From"), wxDefaultPosition, wxDefaultSize, wxALIGN_CENTER);
m_filePicker = new wxFilePickerCtrl(panel, File, wxEmptyString, "File", L"p2m2 file(*.p2m2)|*.p2m2", wxDefaultPosition, wxDefaultSize, wxFLP_SAVE | wxFLP_OVERWRITE_PROMPT | wxFLP_USE_TEXTCTRL); m_filePicker = new wxFilePickerCtrl(panel, MenuIds_New_Recording_Frame_File, wxEmptyString, "File", L"p2m2 file(*.p2m2)|*.p2m2", wxDefaultPosition, wxDefaultSize, wxFLP_SAVE | wxFLP_OVERWRITE_PROMPT | wxFLP_USE_TEXTCTRL);
m_authorInput = new wxTextCtrl(panel, Author, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxTE_PROCESS_ENTER); m_authorInput = new wxTextCtrl(panel, MenuIds_New_Recording_Frame_Author, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxTE_PROCESS_ENTER);
wxArrayString choices; wxArrayString choices;
choices.Add("Current Frame"); choices.Add("Current Frame");
choices.Add("Power-On"); choices.Add("Power-On");
m_fromChoice = new wxChoice(panel, From, wxDefaultPosition, wxDefaultSize, choices); m_fromChoice = new wxChoice(panel, MenuIds_New_Recording_Frame_From, wxDefaultPosition, wxDefaultSize, choices);
m_fromChoice->SetSelection(0); m_fromChoice->SetSelection(0);
m_startRecording = new wxButton(panel, wxID_OK, _("Ok"), wxDefaultPosition, wxDefaultSize); m_startRecording = new wxButton(panel, wxID_OK, _("Ok"), wxDefaultPosition, wxDefaultSize);
@ -65,17 +59,17 @@ NewRecordingFrame::NewRecordingFrame(wxWindow *parent)
Centre(); Centre();
} }
wxString NewRecordingFrame::getFile() const wxString NewRecordingFrame::GetFile() const
{ {
return m_filePicker->GetPath(); return m_filePicker->GetPath();
} }
wxString NewRecordingFrame::getAuthor() const wxString NewRecordingFrame::GetAuthor() const
{ {
return m_authorInput->GetValue(); return m_authorInput->GetValue();
} }
int NewRecordingFrame::getFrom() const int NewRecordingFrame::GetFrom() const
{ {
return m_fromChoice->GetSelection(); return m_fromChoice->GetSelection();
} }

View File

@ -18,17 +18,23 @@
#include <wx/wx.h> #include <wx/wx.h>
#include <wx/filepicker.h> #include <wx/filepicker.h>
/*
* The Dialog to pop-up when recording a new movie enum MenuIds_New_Recording_Frame
*/ {
MenuIds_New_Recording_Frame_File = 0,
MenuIds_New_Recording_Frame_Author,
MenuIds_New_Recording_Frame_From
};
// The Dialog to pop-up when recording a new movie
class NewRecordingFrame : public wxDialog class NewRecordingFrame : public wxDialog
{ {
public: public:
NewRecordingFrame(wxWindow *parent); NewRecordingFrame(wxWindow *parent);
wxString getFile() const; wxString GetFile() const;
wxString getAuthor() const; wxString GetAuthor() const;
int getFrom() const; int GetFrom() const;
private: private:
wxStaticText *m_fileLabel; wxStaticText *m_fileLabel;

View File

@ -19,6 +19,7 @@
#include "ConsoleLogger.h" #include "ConsoleLogger.h"
#include "PadData.h" #include "PadData.h"
PadData::PadData() PadData::PadData()
{ {
// TODO - multi-tap support eventually? // TODO - multi-tap support eventually?
@ -33,7 +34,7 @@ PadData::PadData()
} }
} }
void PadData::logPadData(u8 port, u16 bufCount, u8 buf[512]) { void PadData::LogPadData(u8 port, u16 bufCount, u8 buf[512]) {
// skip first two bytes because they dont seem to matter // skip first two bytes because they dont seem to matter
if (port == 0 && bufCount > 2) if (port == 0 && bufCount > 2)
{ {
@ -54,30 +55,33 @@ void PadData::logPadData(u8 port, u16 bufCount, u8 buf[512]) {
} }
} }
int* PadData::getNormalButtons(int port) const std::vector<int> PadData::GetNormalButtons(int port) const
{ {
int buttons[PadDataNormalButtonCount]; std::vector<int> buttons(PadDataNormalButtonCount);
for (int i = 0; i < PadDataNormalButtonCount; i++) for (int i = 0; i < PadDataNormalButtonCount; i++)
{ {
buttons[i] = getNormalButton(port, PadDataNormalButton(i)); buttons[i] = GetNormalButton(port, PadData_NormalButton(i));
} }
return buttons; return buttons;
} }
void PadData::setNormalButtons(int port, int* buttons)
void PadData::SetNormalButtons(int port, std::vector<int> buttons)
{ {
for (int i = 0; i < PadDataNormalButtonCount; i++) for (int i = 0; i < PadDataNormalButtonCount; i++)
{ {
setNormalButton(port, PadDataNormalButton(i), buttons[i]); SetNormalButton(port, PadData_NormalButton(i), buttons[i]);
} }
} }
void PadData::setNormalButton(int port, PadDataNormalButton button, int fpushed) void PadData::SetNormalButton(int port, PadData_NormalButton button, int fpushed)
{ {
if (port < 0 || 1 < port) if (port < 0 || 1 < port)
{
return; return;
}
wxByte keybit[2]; wxByte keybit[2];
getKeyBit(keybit, button); GetKeyBit(keybit, button);
int pressureByteIndex = getPressureByte(button); int pressureByteIndex = GetPressureByte(button);
if (fpushed > 0) if (fpushed > 0)
{ {
@ -104,13 +108,15 @@ void PadData::setNormalButton(int port, PadDataNormalButton button, int fpushed)
} }
} }
int PadData::getNormalButton(int port, PadDataNormalButton button) const int PadData::GetNormalButton(int port, PadData_NormalButton button) const
{ {
if (port < 0 || 1 < port) if (port < 0 || 1 < port)
{
return false; return false;
}
wxByte keybit[2]; wxByte keybit[2];
getKeyBit(keybit, button); GetKeyBit(keybit, button);
int pressureByteIndex = getPressureByte(button); int pressureByteIndex = GetPressureByte(button);
// If the button is pressed on either controller // If the button is pressed on either controller
bool f1 = (~buf[port][0] & keybit[0])>0; bool f1 = (~buf[port][0] & keybit[0])>0;
@ -132,110 +138,195 @@ int PadData::getNormalButton(int port, PadDataNormalButton button) const
return 0; return 0;
} }
void PadData::getKeyBit(wxByte keybit[2], PadDataNormalButton button) const void PadData::GetKeyBit(wxByte keybit[2], PadData_NormalButton button) const
{ {
if (button == UP) { keybit[0] = 0b00010000; keybit[1] = 0b00000000; } switch (button)
else if (button == LEFT) { keybit[0] = 0b10000000; keybit[1] = 0b00000000; } {
else if (button == RIGHT) { keybit[0] = 0b00100000; keybit[1] = 0b00000000; } case PadData_NormalButton_LEFT:
else if (button == DOWN) { keybit[0] = 0b01000000; keybit[1] = 0b00000000; } keybit[0] = 0b10000000;
else if (button == START) { keybit[0] = 0b00001000; keybit[1] = 0b00000000; } keybit[1] = 0b00000000;
else if (button == SELECT) { keybit[0] = 0b00000001; keybit[1] = 0b00000000; } break;
else if (button == CROSS) { keybit[0] = 0b00000000; keybit[1] = 0b01000000; } case PadData_NormalButton_DOWN:
else if (button == CIRCLE) { keybit[0] = 0b00000000; keybit[1] = 0b00100000; } keybit[0] = 0b01000000;
else if (button == SQUARE) { keybit[0] = 0b00000000; keybit[1] = 0b10000000; } keybit[1] = 0b00000000;
else if (button == TRIANGLE) { keybit[0] = 0b00000000; keybit[1] = 0b00010000; } break;
else if (button == L1) { keybit[0] = 0b00000000; keybit[1] = 0b00000100; } case PadData_NormalButton_RIGHT:
else if (button == L2) { keybit[0] = 0b00000000; keybit[1] = 0b00000001; } keybit[0] = 0b00100000;
else if (button == L3) { keybit[0] = 0b00000010; keybit[1] = 0b00000000; } keybit[1] = 0b00000000;
else if (button == R1) { keybit[0] = 0b00000000; keybit[1] = 0b00001000; } break;
else if (button == R2) { keybit[0] = 0b00000000; keybit[1] = 0b00000010; } case PadData_NormalButton_UP:
else if (button == R3) { keybit[0] = 0b00000100; keybit[1] = 0b00000000; } keybit[0] = 0b00010000;
else { keybit[0] = 0; keybit[1] = 0; } keybit[1] = 0b00000000;
break;
case PadData_NormalButton_START:
keybit[0] = 0b00001000;
keybit[1] = 0b00000000;
break;
case PadData_NormalButton_R3:
keybit[0] = 0b00000100;
keybit[1] = 0b00000000;
break;
case PadData_NormalButton_L3:
keybit[0] = 0b00000010;
keybit[1] = 0b00000000;
break;
case PadData_NormalButton_SELECT:
keybit[0] = 0b00000001;
keybit[1] = 0b00000000;
break;
case PadData_NormalButton_SQUARE:
keybit[0] = 0b00000000;
keybit[1] = 0b10000000;
break;
case PadData_NormalButton_CROSS:
keybit[0] = 0b00000000;
keybit[1] = 0b01000000;
break;
case PadData_NormalButton_CIRCLE:
keybit[0] = 0b00000000;
keybit[1] = 0b00100000;
break;
case PadData_NormalButton_TRIANGLE:
keybit[0] = 0b00000000;
keybit[1] = 0b00010000;
break;
case PadData_NormalButton_R1:
keybit[0] = 0b00000000;
keybit[1] = 0b00001000;
break;
case PadData_NormalButton_L1:
keybit[0] = 0b00000000;
keybit[1] = 0b00000100;
break;
case PadData_NormalButton_R2:
keybit[0] = 0b00000000;
keybit[1] = 0b00000010;
break;
case PadData_NormalButton_L2:
keybit[0] = 0b00000000;
keybit[1] = 0b00000001;
break;
default:
keybit[0] = 0;
keybit[1] = 0;
}
} }
// Returns an index for the buffer to set the pressure byte // Returns an index for the buffer to set the pressure byte
// Returns -1 if it is a button that does not support pressure sensitivty // Returns -1 if it is a button that does not support pressure sensitivty
int PadData::getPressureByte(PadDataNormalButton button) const int PadData::GetPressureByte(PadData_NormalButton button) const
{ {
// Pressure Byte Order // Pressure Byte Order
// R - L - U - D - Tri - Sqr - Circle - Cross - L1 - R1 - L2 - R2 // R - L - U - D - Tri - Circle - Cross - Sqr - L1 - R1 - L2 - R2
if (button == UP) switch (button)
return 2; {
else if (button == LEFT) case PadData_NormalButton_RIGHT:
return 1;
else if (button == RIGHT)
return 0; return 0;
else if (button == DOWN) break;
case PadData_NormalButton_LEFT:
return 1;
break;
case PadData_NormalButton_UP:
return 2;
break;
case PadData_NormalButton_DOWN:
return 3; return 3;
else if (button == CROSS) break;
return 6; case PadData_NormalButton_TRIANGLE:
else if (button == CIRCLE)
return 5;
else if (button == SQUARE)
return 7;
else if (button == TRIANGLE)
return 4; return 4;
else if (button == L1) break;
case PadData_NormalButton_CIRCLE:
return 5;
break;
case PadData_NormalButton_CROSS:
return 6;
break;
case PadData_NormalButton_SQUARE:
return 7;
break;
case PadData_NormalButton_L1:
return 8; return 8;
else if (button == L2) break;
return 10; case PadData_NormalButton_R1:
else if (button == R1)
return 9; return 9;
else if (button == R2) break;
case PadData_NormalButton_L2:
return 10;
break;
case PadData_NormalButton_R2:
return 11; return 11;
else break;
default:
return -1; return -1;
}
} }
int* PadData::getAnalogVectors(int port) const std::vector<int> PadData::GetAnalogVectors(int port) const
{ {
int vectors[PadDataAnalogVectorCount]; std::vector<int> vectors(PadDataAnalogVectorCount);
for (int i = 0; i < PadDataAnalogVectorCount; i++) for (int i = 0; i < PadDataAnalogVectorCount; i++)
{ {
vectors[i] = getAnalogVector(port, PadDataAnalogVector(i)); vectors[i] = GetAnalogVector(port, PadData_AnalogVector(i));
} }
return vectors; return vectors;
} }
void PadData::setAnalogVectors(int port, int* vectors) void PadData::SetAnalogVectors(int port, std::vector<int> vectors)
{ {
for (int i = 0; i < PadDataAnalogVectorCount; i++) for (int i = 0; i < PadDataAnalogVectorCount; i++)
{ {
setAnalogVector(port, PadDataAnalogVector(i), vectors[i]); SetAnalogVector(port, PadData_AnalogVector(i), vectors[i]);
} }
} }
void PadData::setAnalogVector(int port, PadDataAnalogVector vector, int val) void PadData::SetAnalogVector(int port, PadData_AnalogVector vector, int val)
{ {
if (port < 0 || 1 < port) if (port < 0 || 1 < port)
{
return; return;
}
if (val < 0) if (val < 0)
{
val = 0; val = 0;
}
else if (val > 255) else if (val > 255)
{
val = 255; val = 255;
}
buf[port][getAnalogVectorByte(vector)] = val; buf[port][GetAnalogVectorByte(vector)] = val;
} }
int PadData::getAnalogVector(int port, PadDataAnalogVector vector) const int PadData::GetAnalogVector(int port, PadData_AnalogVector vector) const
{ {
if (port < 0 || 1 < port) if (port < 0 || 1 < port)
{
return 0; return 0;
}
return buf[port][getAnalogVectorByte(vector)]; return buf[port][GetAnalogVectorByte(vector)];
} }
// Returns an index for the buffer to set the analog's vector // Returns an index for the buffer to set the analog's vector
int PadData::getAnalogVectorByte(PadDataAnalogVector vector) const int PadData::GetAnalogVectorByte(PadData_AnalogVector vector) const
{ {
// Vector Byte Ordering // Vector Byte Ordering
// RX - RY - LX - LY // RX - RY - LX - LY
if (vector == LEFT_ANALOG_X) switch (vector)
return 4; {
else if (vector == LEFT_ANALOG_Y) case PadData_AnalogVector_RIGHT_ANALOG_X:
return 5;
else if (vector == RIGHT_ANALOG_X)
return 2; return 2;
else break;
case PadData_AnalogVector_RIGHT_ANALOG_Y:
return 3; return 3;
break;
case PadData_AnalogVector_LEFT_ANALOG_X:
return 4;
break;
case PadData_AnalogVector_LEFT_ANALOG_Y:
return 5;
break;
default:
return -1;
}
} }

View File

@ -16,35 +16,37 @@
#pragma once #pragma once
#include <map> #include <map>
#include <vector>
#define PadDataNormalButtonCount 16
enum PadDataNormalButton static const int PadDataNormalButtonCount = 16;
enum PadData_NormalButton
{ {
UP, PadData_NormalButton_UP,
RIGHT, PadData_NormalButton_RIGHT,
LEFT, PadData_NormalButton_LEFT,
DOWN, PadData_NormalButton_DOWN,
CROSS, PadData_NormalButton_CROSS,
CIRCLE, PadData_NormalButton_CIRCLE,
SQUARE, PadData_NormalButton_SQUARE,
TRIANGLE, PadData_NormalButton_TRIANGLE,
L1, PadData_NormalButton_L1,
L2, PadData_NormalButton_L2,
R1, PadData_NormalButton_R1,
R2, PadData_NormalButton_R2,
L3, PadData_NormalButton_L3,
R3, PadData_NormalButton_R3,
SELECT, PadData_NormalButton_SELECT,
START PadData_NormalButton_START
}; };
#define PadDataAnalogVectorCount 4 static const int PadDataAnalogVectorCount = 4;
enum PadDataAnalogVector enum PadData_AnalogVector
{ {
LEFT_ANALOG_X, PadData_AnalogVector_LEFT_ANALOG_X,
LEFT_ANALOG_Y, PadData_AnalogVector_LEFT_ANALOG_Y,
RIGHT_ANALOG_X, PadData_AnalogVector_RIGHT_ANALOG_X,
RIGHT_ANALOG_Y PadData_AnalogVector_RIGHT_ANALOG_Y
}; };
struct PadData struct PadData
@ -57,29 +59,29 @@ public:
u8 buf[2][18]; u8 buf[2][18];
// Prints controlller data every frame to the Controller Log filter, disabled by default // Prints controlller data every frame to the Controller Log filter, disabled by default
static void logPadData(u8 port, u16 bufCount, u8 buf[512]); static void LogPadData(u8 port, u16 bufCount, u8 buf[512]);
// Normal Buttons // Normal Buttons
int* getNormalButtons(int port) const; std::vector<int> GetNormalButtons(int port) const;
void setNormalButtons(int port, int* buttons); void SetNormalButtons(int port, std::vector<int> buttons);
// Analog Vectors // Analog Vectors
// max left/up : 0 // max left/up : 0
// neutral : 127 // neutral : 127
// max right/down : 255 // max right/down : 255
int* getAnalogVectors(int port) const; std::vector<int> GetAnalogVectors(int port) const;
// max left/up : 0 // max left/up : 0
// neutral : 127 // neutral : 127
// max right/down : 255 // max right/down : 255
void setAnalogVectors(int port, int* vector); void SetAnalogVectors(int port, std::vector<int> vector);
private: private:
void setNormalButton(int port, PadDataNormalButton button, int pressure); void SetNormalButton(int port, PadData_NormalButton button, int pressure);
int getNormalButton(int port, PadDataNormalButton button) const; int GetNormalButton(int port, PadData_NormalButton button) const;
void getKeyBit(wxByte keybit[2], PadDataNormalButton button) const; void GetKeyBit(wxByte keybit[2], PadData_NormalButton button) const;
int getPressureByte(PadDataNormalButton button) const; int GetPressureByte(PadData_NormalButton button) const;
void setAnalogVector(int port, PadDataAnalogVector vector, int val); void SetAnalogVector(int port, PadData_AnalogVector vector, int val);
int getAnalogVector(int port, PadDataAnalogVector vector) const; int GetAnalogVector(int port, PadData_AnalogVector vector) const;
int getAnalogVectorByte(PadDataAnalogVector vector) const; int GetAnalogVectorByte(PadData_AnalogVector vector) const;
}; };

View File

@ -15,32 +15,31 @@
#include "PrecompiledHeader.h" #include "PrecompiledHeader.h"
#include "GSFrame.h"
#include "MemoryTypes.h"
#include "App.h" #include "App.h"
#include "Counters.h" #include "Counters.h"
#include "GSFrame.h"
#include "MemoryTypes.h"
#include "RecordingControls.h" #include "RecordingControls.h"
RecordingControls g_RecordingControls; RecordingControls g_RecordingControls;
// TODO - I think these functions could be named a lot better...
//----------------------------------------------- //-----------------------------------------------
// Status on whether or not the current recording is stopped // Status on whether or not the current recording is stopped
//----------------------------------------------- //-----------------------------------------------
bool RecordingControls::isStop() bool RecordingControls::HasRecordingStopped()
{ {
return (fPauseState && CoreThread.IsOpen() && CoreThread.IsPaused()); return (fPauseState && CoreThread.IsOpen() && CoreThread.IsPaused());
} }
//----------------------------------------------- //-----------------------------------------------
// Called after inputs are recorded for that frame, places lock on input recording, effectively releasing resources and resuming CoreThread. // Called after inputs are recorded for that frame, places lock on input recording, effectively releasing resources and resuming CoreThread.
//----------------------------------------------- //-----------------------------------------------
void RecordingControls::StartCheck() void RecordingControls::ResumeCoreThreadIfStarted()
{ {
if (fStart && CoreThread.IsOpen() && CoreThread.IsPaused()) { if (fStart && CoreThread.IsOpen() && CoreThread.IsPaused())
{
CoreThread.Resume(); CoreThread.Resume();
fStart = false; fStart = false;
fPauseState = false; fPauseState = false;
@ -51,10 +50,12 @@ void RecordingControls::StartCheck()
// Called at VSYNC End / VRender Begin, updates everything recording related for the next frame, // Called at VSYNC End / VRender Begin, updates everything recording related for the next frame,
// toggles RecordingControl flags back to enable input recording for the next frame. // toggles RecordingControl flags back to enable input recording for the next frame.
//----------------------------------------------- //-----------------------------------------------
void RecordingControls::StopCheck() void RecordingControls::HandleFrameAdvanceAndStop()
{ {
if (fFrameAdvance) { if (fFrameAdvance)
if (stopFrameCount < g_FrameCount) { {
if (stopFrameCount < g_FrameCount)
{
fFrameAdvance = false; fFrameAdvance = false;
fStop = true; fStop = true;
stopFrameCount = g_FrameCount; stopFrameCount = g_FrameCount;
@ -80,11 +81,11 @@ void RecordingControls::StopCheck()
} }
} }
bool RecordingControls::GetStopFlag()
{
return (fStop || fFrameAdvance);
}
//----------------------------------
// shortcut key
//----------------------------------
void RecordingControls::FrameAdvance() void RecordingControls::FrameAdvance()
{ {
stopFrameCount = g_FrameCount; stopFrameCount = g_FrameCount;
@ -92,22 +93,25 @@ void RecordingControls::FrameAdvance()
fStop = false; fStop = false;
fStart = true; fStart = true;
} }
void RecordingControls::TogglePause() void RecordingControls::TogglePause()
{ {
fStop = !fStop; fStop = !fStop;
if (fStop == false) { if (fStop == false)
{
fStart = true; fStart = true;
} }
} }
void RecordingControls::Pause() void RecordingControls::Pause()
{ {
fStop = true; fStop = true;
fFrameAdvance = true; fFrameAdvance = true;
} }
void RecordingControls::UnPause()
void RecordingControls::Unpause()
{ {
fStop = false; fStop = false;
fStart = true; fStart = true;
fFrameAdvance = true; fFrameAdvance = true;
} }

View File

@ -15,13 +15,14 @@
#pragma once #pragma once
class RecordingControls { class RecordingControls
{
public: public:
// Movie controls main functions // Movie controls main functions
bool isStop(); bool HasRecordingStopped();
void StartCheck(); void ResumeCoreThreadIfStarted();
void StopCheck(); void HandleFrameAdvanceAndStop();
// Shortcut Keys // Shortcut Keys
void FrameAdvance(); void FrameAdvance();
@ -29,10 +30,10 @@ public:
// Setters // Setters
void Pause(); void Pause();
void UnPause(); void Unpause();
// Getters // Getters
bool getStopFlag() { return (fStop || fFrameAdvance); } bool GetStopFlag();
private: private:
uint stopFrameCount = false; uint stopFrameCount = false;
@ -43,4 +44,5 @@ private:
bool fPauseState = false; bool fPauseState = false;
}; };
extern RecordingControls g_RecordingControls; extern RecordingControls g_RecordingControls;

View File

@ -18,18 +18,23 @@
#include "RecordingInputManager.h" #include "RecordingInputManager.h"
#include "InputRecording.h" #include "InputRecording.h"
RecordingInputManager g_RecordingInput; RecordingInputManager g_RecordingInput;
RecordingInputManager::RecordingInputManager() RecordingInputManager::RecordingInputManager()
{ {
for (u8 i = 0; i < 2; i++) for (u8 i = 0; i < 2; i++)
{
virtualPad[i] = false; virtualPad[i] = false;
}
} }
void RecordingInputManager::ControllerInterrupt(u8 & data, u8 & port, u16 & BufCount, u8 buf[]) void RecordingInputManager::ControllerInterrupt(u8 & data, u8 & port, u16 & BufCount, u8 buf[])
{ {
if (port >= 2) if (port >= 2)
{
return; return;
}
if (virtualPad[port]) if (virtualPad[port])
{ {
@ -37,36 +42,44 @@ void RecordingInputManager::ControllerInterrupt(u8 & data, u8 & port, u16 & BufC
// first two bytes have nothing of interest in the buffer // first two bytes have nothing of interest in the buffer
// already handled by InputRecording.cpp // already handled by InputRecording.cpp
if (BufCount < 3) if (BufCount < 3)
{
return; return;
}
// Normal keys // Normal keys
// We want to perform an OR, but, since 255 means that no button is pressed and 0 that every button is pressed (and by De Morgan's Laws), we execute an AND. // We want to perform an OR, but, since 255 means that no button is pressed and 0 that every button is pressed (and by De Morgan's Laws), we execute an AND.
if (BufCount <= 4) if (BufCount <= 4)
buf[BufCount] = buf[BufCount] & pad.buf[port][BufCount - 3]; {
buf[BufCount] = buf[BufCount] & pad.buf[port][bufIndex];
}
// Analog keys (! overrides !) // Analog keys (! overrides !)
else if ((BufCount > 4 && BufCount <= 6) && pad.buf[port][BufCount - 3] != 127) else if ((BufCount > 4 && BufCount <= 6) && pad.buf[port][bufIndex] != 127)
buf[BufCount] = pad.buf[port][BufCount - 3]; {
buf[BufCount] = pad.buf[port][bufIndex];
}
// Pressure sensitivity bytes // Pressure sensitivity bytes
else if (BufCount > 6) else if (BufCount > 6)
buf[BufCount] = pad.buf[port][BufCount - 3]; {
buf[BufCount] = pad.buf[port][bufIndex];
}
// Updating movie file // Updating movie file
g_InputRecording.ControllerInterrupt(data, port, BufCount, buf); g_InputRecording.ControllerInterrupt(data, port, BufCount, buf);
} }
} }
void RecordingInputManager::SetButtonState(int port, PadDataNormalButton button, int pressure) void RecordingInputManager::SetButtonState(int port, PadData_NormalButton button, int pressure)
{ {
int* buttons = pad.getNormalButtons(port); std::vector<int> buttons = pad.GetNormalButtons(port);
buttons[button] = pressure; buttons[button] = pressure;
pad.setNormalButtons(port, buttons); pad.SetNormalButtons(port, buttons);
} }
void RecordingInputManager::UpdateAnalog(int port, PadDataAnalogVector vector, int value) void RecordingInputManager::UpdateAnalog(int port, PadData_AnalogVector vector, int value)
{ {
int* vectors = pad.getAnalogVectors(port); std::vector<int> vectors = pad.GetAnalogVectors(port);
vectors[vector] = value; vectors[vector] = value;
pad.setAnalogVectors(port, vectors); pad.SetAnalogVectors(port, vectors);
} }
void RecordingInputManager::SetVirtualPadReading(int port, bool read) void RecordingInputManager::SetVirtualPadReading(int port, bool read)

View File

@ -17,6 +17,7 @@
#include "PadData.h" #include "PadData.h"
class RecordingInputManager class RecordingInputManager
{ {
public: public:
@ -24,9 +25,9 @@ public:
void ControllerInterrupt(u8 &data, u8 &port, u16 & BufCount, u8 buf[]); void ControllerInterrupt(u8 &data, u8 &port, u16 & BufCount, u8 buf[]);
// Handles normal keys // Handles normal keys
void SetButtonState(int port, PadDataNormalButton button, int pressure); void SetButtonState(int port, PadData_NormalButton button, int pressure);
// Handles analog sticks // Handles analog sticks
void UpdateAnalog(int port, PadDataAnalogVector vector, int value); void UpdateAnalog(int port, PadData_AnalogVector vector, int value);
void SetVirtualPadReading(int port, bool read); void SetVirtualPadReading(int port, bool read);
protected: protected:

View File

@ -125,10 +125,12 @@ VirtualPad::VirtualPad(wxWindow* parent, wxWindowID id, const wxString& title, i
void VirtualPad::SetProperties() void VirtualPad::SetProperties()
{ {
if (controllerPort == 0) { if (controllerPort == 0)
{
SetTitle(wxT("Virtual Pad - Port 1")); SetTitle(wxT("Virtual Pad - Port 1"));
} }
else { else
{
SetTitle(wxT("Virtual Pad - Port 2")); SetTitle(wxT("Virtual Pad - Port 2"));
} }
SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW)); SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW));
@ -137,9 +139,13 @@ void VirtualPad::SetProperties()
bool VirtualPad::Show(bool show) bool VirtualPad::Show(bool show)
{ {
if (!wxFrame::Show(show)) if (!wxFrame::Show(show))
{
return false; return false;
}
if (show) if (show)
{
g_RecordingInput.SetVirtualPadReading(controllerPort, true); g_RecordingInput.SetVirtualPadReading(controllerPort, true);
}
return true; return true;
} }
@ -174,7 +180,7 @@ void VirtualPad::OnButtonPress(wxCommandEvent & event)
pressure = 255; pressure = 255;
} }
} }
g_RecordingInput.SetButtonState(controllerPort, PadDataNormalButton(buttonId), pressure); g_RecordingInput.SetButtonState(controllerPort, PadData_NormalButton(buttonId), pressure);
} }
} }
@ -193,10 +199,11 @@ void VirtualPad::OnPressureChange(wxSpinEvent & event)
if (spinnerId != -1) if (spinnerId != -1)
{ {
u8 pressure = 0; u8 pressure = 0;
if (event.IsChecked()) { if (event.IsChecked())
{
pressure = buttonsPressure[spinnerId]->GetValue(); pressure = buttonsPressure[spinnerId]->GetValue();
} }
g_RecordingInput.SetButtonState(controllerPort, PadDataNormalButton(spinnerId), pressure); g_RecordingInput.SetButtonState(controllerPort, PadData_NormalButton(spinnerId), pressure);
} }
} }
@ -217,11 +224,12 @@ void VirtualPad::OnAnalogSliderChange(wxCommandEvent & event)
{ {
analogVals[sliderId]->SetValue(event.GetInt()); analogVals[sliderId]->SetValue(event.GetInt());
} }
else { else
{
analogVals[sliderId]->SetValue(event.GetInt() * -1); analogVals[sliderId]->SetValue(event.GetInt() * -1);
} }
g_RecordingInput.UpdateAnalog(controllerPort, PadDataAnalogVector(sliderId), event.GetInt() + 127); g_RecordingInput.UpdateAnalog(controllerPort, PadData_AnalogVector(sliderId), event.GetInt() + 127);
} }
} }
@ -239,7 +247,7 @@ void VirtualPad::OnAnalogValChange(wxSpinEvent & event)
if (spinnerId != -1) if (spinnerId != -1)
{ {
analogVals[spinnerId]->SetValue(event.GetInt()); analogVals[spinnerId]->SetValue(event.GetInt());
g_RecordingInput.UpdateAnalog(controllerPort, PadDataAnalogVector(spinnerId), event.GetInt() + 127); g_RecordingInput.UpdateAnalog(controllerPort, PadData_AnalogVector(spinnerId), event.GetInt() + 127);
} }
} }

View File

@ -219,15 +219,14 @@ SIO_WRITE sioWriteController(u8 data)
if (g_Conf->EmuOptions.EnableRecordingTools) if (g_Conf->EmuOptions.EnableRecordingTools)
{ {
g_InputRecording.ControllerInterrupt(data, sio.port, sio.bufCount, sio.buf); g_InputRecording.ControllerInterrupt(data, sio.port, sio.bufCount, sio.buf);
if (g_InputRecording.isInterruptFrame()) if (g_InputRecording.IsInterruptFrame())
{ {
g_RecordingInput.ControllerInterrupt(data, sio.port, sio.bufCount, sio.buf); g_RecordingInput.ControllerInterrupt(data, sio.port, sio.bufCount, sio.buf);
} }
PadData::logPadData(sio.port, sio.bufCount, sio.buf); PadData::LogPadData(sio.port, sio.bufCount, sio.buf);
} }
#endif #endif
break; break;
} }
//Console.WriteLn( "SIO: sent = %02X From pad data = %02X bufCnt %08X ", data, sio.buf[sio.bufCount], sio.bufCount); //Console.WriteLn( "SIO: sent = %02X From pad data = %02X bufCnt %08X ", data, sio.buf[sio.bufCount], sio.bufCount);

View File

@ -142,8 +142,8 @@ SysConsoleLogPack::SysConsoleLogPack()
, iopConsole (&TLD_iopConsole) , iopConsole (&TLD_iopConsole)
, deci2 (&TLD_deci2) , deci2 (&TLD_deci2)
#ifndef DISABLE_RECORDING #ifndef DISABLE_RECORDING
, recordingConsole(&TLD_recordingConsole) , recordingConsole (&TLD_recordingConsole)
, controlInfo(&TLD_controlInfo) , controlInfo (&TLD_controlInfo)
#endif #endif
{ {
} }

View File

@ -617,7 +617,7 @@ void Pcsx2App::HandleEvent(wxEvtHandler* handler, wxEventFunction func, wxEvent&
#ifndef DISABLE_RECORDING #ifndef DISABLE_RECORDING
if (g_Conf->EmuOptions.EnableRecordingTools) if (g_Conf->EmuOptions.EnableRecordingTools)
{ {
if (g_RecordingControls.isStop()) if (g_RecordingControls.HasRecordingStopped())
{ {
// While stopping, GSFrame key event also stops, so get key input from here // While stopping, GSFrame key event also stops, so get key input from here
// Along with that, you can not use the shortcut keys set in GSFrame // Along with that, you can not use the shortcut keys set in GSFrame
@ -631,7 +631,7 @@ void Pcsx2App::HandleEvent(wxEvtHandler* handler, wxEventFunction func, wxEvent&
} }
} }
} }
g_RecordingControls.StartCheck(); g_RecordingControls.ResumeCoreThreadIfStarted();
} }
#endif #endif
(handler->*func)(event); (handler->*func)(event);

View File

@ -283,6 +283,22 @@ public:
} }
}; };
enum MenuId_LogSources_Offset
{
MenuId_LogSources_Offset_eeConsole = 0,
MenuId_LogSources_Offset_iopConsole,
MenuId_LogSources_Offset_eeRecPerf,
MenuId_LogSources_Offset_ELF = 4,
MenuId_LogSources_Offset_Event = 6,
MenuId_LogSources_Offset_Thread,
MenuId_LogSources_Offset_sysoutConsole,
MenuId_LogSources_Offset_recordingConsole = 10,
MenuId_LogSources_Offset_controlInfo
};
// WARNING ConsoleLogSources & ConLogDefaults must have the same size // WARNING ConsoleLogSources & ConLogDefaults must have the same size
static ConsoleLogSource* const ConLogSources[] = static ConsoleLogSource* const ConLogSources[] =
{ {
@ -294,7 +310,7 @@ static ConsoleLogSource* const ConLogSources[] =
NULL, NULL,
(ConsoleLogSource*)&pxConLog_Event, (ConsoleLogSource*)&pxConLog_Event,
(ConsoleLogSource*)&pxConLog_Thread, (ConsoleLogSource*)&pxConLog_Thread,
(ConsoleLogSource*)&SysConsole.sysoutConsole (ConsoleLogSource*)&SysConsole.sysoutConsole,
NULL, NULL,
#ifndef DISABLE_RECORDING #ifndef DISABLE_RECORDING
(ConsoleLogSource*)&SysConsole.recordingConsole, (ConsoleLogSource*)&SysConsole.recordingConsole,
@ -571,6 +587,10 @@ void ConsoleLogFrame::OnLoggingChanged()
{ {
GetMenuBar()->Check( MenuId_LogSource_Start+i, log->IsActive() ); GetMenuBar()->Check( MenuId_LogSource_Start+i, log->IsActive() );
} }
#ifndef DISABLE_RECORDING
GetMenuBar()->Enable( MenuId_LogSource_Start + MenuId_LogSources_Offset_recordingConsole, g_Conf->EmuOptions.EnableRecordingTools);
GetMenuBar()->Enable( MenuId_LogSource_Start + MenuId_LogSources_Offset_controlInfo, g_Conf->EmuOptions.EnableRecordingTools);
#endif
} }
} }

View File

@ -132,8 +132,10 @@ GSPanel::GSPanel( wxWindow* parent )
#ifndef DISABLE_RECORDING #ifndef DISABLE_RECORDING
// Retrieving FrameAdvance Key // Retrieving FrameAdvance Key
for (auto itr = m_Accels->begin(); itr != m_Accels->end(); ++itr) { for (auto itr = m_Accels->begin(); itr != m_Accels->end(); ++itr)
if (itr->second->Id == "FrameAdvance") { {
if (itr->second->Id == "FrameAdvance")
{
m_frameAdvanceKey = itr->first; m_frameAdvanceKey = itr->first;
break; break;
} }
@ -377,14 +379,16 @@ void GSPanel::OnKeyDownOrUp( wxKeyEvent& evt )
#endif #endif
if ((PADopen != NULL) && CoreThread.IsOpen()) if ((PADopen != NULL) && CoreThread.IsOpen())
{
return; return;
}
#ifndef DISABLE_RECORDING #ifndef DISABLE_RECORDING
if (g_Conf->EmuOptions.EnableRecordingTools) if (g_Conf->EmuOptions.EnableRecordingTools)
{ {
// TODO-Recording: This is to allow for repeated frame-advance while holding the key // TODO-Recording: This is to allow for repeated frame-advance while holding the key
// However as per the explaination above, this event no longer seems to fire under normal // However as per the explaination above, this event no longer seems to fire under normal
// circumstances and I'm unsure if there is a place to put this logic // circumstances
if (evt.GetKeyCode() == m_frameAdvanceKey) if (evt.GetKeyCode() == m_frameAdvanceKey)
{ {
return; return;
@ -727,23 +731,24 @@ void GSFrame::OnUpdateTitle( wxTimerEvent& evt )
#ifndef DISABLE_RECORDING #ifndef DISABLE_RECORDING
wxString title; wxString title;
wxString movieMode; wxString movieMode;
switch (g_InputRecording.getModeState()) { switch (g_InputRecording.GetModeState())
case InputRecording::KEY_MOVIE_MODE::RECORD: {
case INPUT_RECORDING_MODE_RECORD:
movieMode = "Recording"; movieMode = "Recording";
title = templates.RecordingTemplate; title = templates.RecordingTemplate;
break; break;
case InputRecording::KEY_MOVIE_MODE::REPLAY: case INPUT_RECORDING_MODE_REPLAY:
movieMode = "Replaying"; movieMode = "Replaying";
title = templates.RecordingTemplate; title = templates.RecordingTemplate;
break; break;
case InputRecording::KEY_MOVIE_MODE::NONE: case INPUT_RECORDING_MODE_NONE:
movieMode = "No movie"; movieMode = "No movie";
title = templates.TitleTemplate; title = templates.TitleTemplate;
break; break;
} }
title.Replace(L"${frame}", pxsFmt(L"%d", g_FrameCount)); title.Replace(L"${frame}", pxsFmt(L"%d", g_FrameCount));
title.Replace(L"${maxFrame}", pxsFmt(L"%d", g_InputRecording.getInputRecordingData().getMaxFrame())); title.Replace(L"${maxFrame}", pxsFmt(L"%d", g_InputRecording.GetInputRecordingData().GetMaxFrame()));
title.Replace(L"${mode}", movieMode); title.Replace(L"${mode}", movieMode);
#else #else
wxString title = templates.TitleTemplate; wxString title = templates.TitleTemplate;

View File

@ -18,10 +18,6 @@
#include "AppCommon.h" #include "AppCommon.h"
#include "CpuUsageProvider.h" #include "CpuUsageProvider.h"
#include "wx/dcbuffer.h"
#include "wx/dcgraph.h"
#include <memory> #include <memory>
@ -59,10 +55,10 @@ public:
GSPanel( wxWindow* parent ); GSPanel( wxWindow* parent );
virtual ~GSPanel(); virtual ~GSPanel();
virtual void DoResize(); void DoResize();
void DoShowMouse(); void DoShowMouse();
void DirectKeyCommand( wxKeyEvent& evt ); void DirectKeyCommand( wxKeyEvent& evt );
virtual void DirectKeyCommand( const KeyAcceleratorCode& kac ); void DirectKeyCommand( const KeyAcceleratorCode& kac );
protected: protected:
void AppStatusEvent_OnSettingsApplied(); void AppStatusEvent_OnSettingsApplied();
@ -83,6 +79,7 @@ protected:
void UpdateScreensaver(); void UpdateScreensaver();
}; };
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
// GSFrame // GSFrame
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------

View File

@ -467,48 +467,138 @@ namespace Implementations
void FrameAdvance() void FrameAdvance()
{ {
if (g_Conf->EmuOptions.EnableRecordingTools) if (g_Conf->EmuOptions.EnableRecordingTools)
{
g_RecordingControls.FrameAdvance(); g_RecordingControls.FrameAdvance();
} }
}
void TogglePause() void TogglePause()
{ {
if (g_Conf->EmuOptions.EnableRecordingTools) if (g_Conf->EmuOptions.EnableRecordingTools)
{
g_RecordingControls.TogglePause(); g_RecordingControls.TogglePause();
} }
}
void InputRecordingModeToggle() void InputRecordingModeToggle()
{ {
if (g_Conf->EmuOptions.EnableRecordingTools) if (g_Conf->EmuOptions.EnableRecordingTools)
{
g_InputRecording.RecordModeToggle(); g_InputRecording.RecordModeToggle();
} }
}
void States_SaveSlot(int slot) void States_SaveSlot(int slot)
{ {
States_SetCurrentSlot(slot); States_SetCurrentSlot(slot);
States_FreezeCurrentSlot(); States_FreezeCurrentSlot();
} }
void States_LoadSlot(int slot) void States_LoadSlot(int slot)
{ {
States_SetCurrentSlot(slot); States_SetCurrentSlot(slot);
States_DefrostCurrentSlot(); States_DefrostCurrentSlot();
} }
void States_SaveSlot0() { States_SaveSlot(0); }
void States_SaveSlot1() { States_SaveSlot(1); } void States_SaveSlot0()
void States_SaveSlot2() { States_SaveSlot(2); } {
void States_SaveSlot3() { States_SaveSlot(3); } States_SaveSlot(0);
void States_SaveSlot4() { States_SaveSlot(4); } }
void States_SaveSlot5() { States_SaveSlot(5); }
void States_SaveSlot6() { States_SaveSlot(6); } void States_SaveSlot1()
void States_SaveSlot7() { States_SaveSlot(7); } {
void States_SaveSlot8() { States_SaveSlot(8); } States_SaveSlot(1);
void States_SaveSlot9() { States_SaveSlot(9); } }
void States_LoadSlot0() { States_LoadSlot(0); }
void States_LoadSlot1() { States_LoadSlot(1); } void States_SaveSlot2()
void States_LoadSlot2() { States_LoadSlot(2); } {
void States_LoadSlot3() { States_LoadSlot(3); } States_SaveSlot(2);
void States_LoadSlot4() { States_LoadSlot(4); } }
void States_LoadSlot5() { States_LoadSlot(5); }
void States_LoadSlot6() { States_LoadSlot(6); } void States_SaveSlot3()
void States_LoadSlot7() { States_LoadSlot(7); } {
void States_LoadSlot8() { States_LoadSlot(8); } States_SaveSlot(3);
void States_LoadSlot9() { States_LoadSlot(9); } }
void States_SaveSlot4()
{
States_SaveSlot(4);
}
void States_SaveSlot5()
{
States_SaveSlot(5);
}
void States_SaveSlot6()
{
States_SaveSlot(6);
}
void States_SaveSlot7()
{
States_SaveSlot(7);
}
void States_SaveSlot8()
{
States_SaveSlot(8);
}
void States_SaveSlot9()
{
States_SaveSlot(9);
}
void States_LoadSlot0()
{
States_LoadSlot(0);
}
void States_LoadSlot1()
{
States_LoadSlot(1);
}
void States_LoadSlot2()
{
States_LoadSlot(2);
}
void States_LoadSlot3()
{
States_LoadSlot(3);
}
void States_LoadSlot4()
{
States_LoadSlot(4);
}
void States_LoadSlot5()
{
States_LoadSlot(5);
}
void States_LoadSlot6()
{
States_LoadSlot(6);
}
void States_LoadSlot7()
{
States_LoadSlot(7);
}
void States_LoadSlot8()
{
States_LoadSlot(8);
}
void States_LoadSlot9()
{
States_LoadSlot(9);
}
#endif #endif
} }

View File

@ -372,7 +372,7 @@ MainEmuFrame::MainEmuFrame(wxWindow* parent, const wxString& title)
SetMenuBar( &m_menubar ); SetMenuBar( &m_menubar );
#ifndef DISABLE_RECORDING #ifndef DISABLE_RECORDING
// Append the Recording / Lua options if previous enabled and picked up from ini // Append the Recording options if previously enabled and setting has been picked up from ini
if (g_Conf->EmuOptions.EnableRecordingTools) if (g_Conf->EmuOptions.EnableRecordingTools)
{ {
m_menubar.Append(&m_menuRecording, _("&Recording")); m_menubar.Append(&m_menuRecording, _("&Recording"));

View File

@ -498,10 +498,12 @@ void MainEmuFrame::Menu_EnableRecordingTools_Click(wxCommandEvent&)
{ {
bool checked = GetMenuBar()->IsChecked(MenuId_EnableRecordingTools); bool checked = GetMenuBar()->IsChecked(MenuId_EnableRecordingTools);
// Confirm with User // Confirm with User
if (checked) { if (checked)
{
if (!Msgbox::OkCancel(_("Please be aware that PCSX2's input recording features are still very much a work-in-progress.\n" if (!Msgbox::OkCancel(_("Please be aware that PCSX2's input recording features are still very much a work-in-progress.\n"
"As a result, there may be unforeseen bugs, performance implications and instability with certain games.\n\n" "As a result, there may be unforeseen bugs, performance implications and instability with certain games.\n\n"
"These tools are provided as-is and should be enabled under your own discretion."), "Enabling Recording Tools")) { "These tools are provided as-is and should be enabled under your own discretion."), "Enabling Recording Tools"))
{
checked = false; checked = false;
m_menuSys.FindChildItem(MenuId_EnableRecordingTools)->Check(false); m_menuSys.FindChildItem(MenuId_EnableRecordingTools)->Check(false);
} }
@ -515,12 +517,14 @@ void MainEmuFrame::Menu_EnableRecordingTools_Click(wxCommandEvent&)
else else
{ {
GetMenuBar()->Remove(TopLevelMenu_Recording); GetMenuBar()->Remove(TopLevelMenu_Recording);
// Always turn controller logs off, but never turn it on by default
SysConsole.controlInfo.Enabled = checked;
} }
g_Conf->EmuOptions.EnableRecordingTools = checked; g_Conf->EmuOptions.EnableRecordingTools = checked;
SysConsole.recordingConsole.Enabled = checked; SysConsole.recordingConsole.Enabled = checked;
ConsoleLogFrame* proglog = wxGetApp().GetProgramLog(); ConsoleLogFrame* progLog = wxGetApp().GetProgramLog();
proglog->UpdateLogList(); progLog->UpdateLogList();
AppApplySettings(); AppApplySettings();
AppSaveSettings(); AppSaveSettings();
} }
@ -568,11 +572,11 @@ void MainEmuFrame::Menu_LoadStateFromFile_Click(wxCommandEvent &event)
L"Savestate files (*.p2s)|*.p2s", wxFD_OPEN); L"Savestate files (*.p2s)|*.p2s", wxFD_OPEN);
if (loadStateDialog.ShowModal() == wxID_CANCEL) if (loadStateDialog.ShowModal() == wxID_CANCEL)
{
return; return;
}
wxString path = loadStateDialog.GetPath(); wxString path = loadStateDialog.GetPath();
Console.WriteLn(path);
StateCopy_LoadFromFile(path); StateCopy_LoadFromFile(path);
} }
@ -582,11 +586,11 @@ void MainEmuFrame::Menu_SaveStateToFile_Click(wxCommandEvent &event)
L"Savestate files (*.p2s)|*.p2s", wxFD_OPEN); L"Savestate files (*.p2s)|*.p2s", wxFD_OPEN);
if (saveStateDialog.ShowModal() == wxID_CANCEL) if (saveStateDialog.ShowModal() == wxID_CANCEL)
{
return; return;
}
wxString path = saveStateDialog.GetPath(); wxString path = saveStateDialog.GetPath();
Console.WriteLn(path);
StateCopy_SaveToFile(path); StateCopy_SaveToFile(path);
} }
@ -706,47 +710,70 @@ void MainEmuFrame::Menu_Capture_Video_Stop_Click(wxCommandEvent &event)
void MainEmuFrame::VideoCaptureUpdate() void MainEmuFrame::VideoCaptureUpdate()
{ {
GetMTGS().WaitGS(); // make sure GS is in sync with the audio stream when we start. GetMTGS().WaitGS(); // make sure GS is in sync with the audio stream when we start.
if (m_capturingVideo) { if (m_capturingVideo)
{
// start recording // start recording
// make the recording setup dialog[s] pseudo-modal also for the main PCSX2 window // make the recording setup dialog[s] pseudo-modal also for the main PCSX2 window
// (the GSdx dialog is already properly modal for the GS window) // (the GSdx dialog is already properly modal for the GS window)
bool needsMainFrameEnable = false; bool needsMainFrameEnable = false;
if (GetMainFramePtr() && GetMainFramePtr()->IsEnabled()) { if (GetMainFramePtr() && GetMainFramePtr()->IsEnabled())
{
needsMainFrameEnable = true; needsMainFrameEnable = true;
GetMainFramePtr()->Disable(); GetMainFramePtr()->Disable();
} }
if (GSsetupRecording) { if (GSsetupRecording)
{
// GSsetupRecording can be aborted/canceled by the user. Don't go on to record the audio if that happens. // GSsetupRecording can be aborted/canceled by the user. Don't go on to record the audio if that happens.
if (GSsetupRecording(m_capturingVideo, NULL)) { if (GSsetupRecording(m_capturingVideo, NULL))
if (SPU2setupRecording) SPU2setupRecording(m_capturingVideo, NULL); {
if (SPU2setupRecording)
{
SPU2setupRecording(m_capturingVideo, NULL);
} }
else { }
else
{
// recording dialog canceled by the user. align our state // recording dialog canceled by the user. align our state
m_capturingVideo = false; m_capturingVideo = false;
} }
} }
else { else
{
// the GS doesn't support recording. // the GS doesn't support recording.
if (SPU2setupRecording) SPU2setupRecording(m_capturingVideo, NULL); if (SPU2setupRecording)
{
SPU2setupRecording(m_capturingVideo, NULL);
}
} }
if (GetMainFramePtr() && needsMainFrameEnable) if (GetMainFramePtr() && needsMainFrameEnable)
{
GetMainFramePtr()->Enable(); GetMainFramePtr()->Enable();
}
} }
else { else
{
// stop recording // stop recording
if (GSsetupRecording) GSsetupRecording(m_capturingVideo, NULL); if (GSsetupRecording)
if (SPU2setupRecording) SPU2setupRecording(m_capturingVideo, NULL); {
GSsetupRecording(m_capturingVideo, NULL);
}
if (SPU2setupRecording)
{
SPU2setupRecording(m_capturingVideo, NULL);
}
} }
if (m_capturingVideo) { if (m_capturingVideo)
{
m_submenuVideoCapture.FindItem(MenuId_Capture_Video_Record)->Enable(false); m_submenuVideoCapture.FindItem(MenuId_Capture_Video_Record)->Enable(false);
m_submenuVideoCapture.FindItem(MenuId_Capture_Video_Stop)->Enable(true); m_submenuVideoCapture.FindItem(MenuId_Capture_Video_Stop)->Enable(true);
} }
else { else
{
m_submenuVideoCapture.FindItem(MenuId_Capture_Video_Record)->Enable(true); m_submenuVideoCapture.FindItem(MenuId_Capture_Video_Record)->Enable(true);
m_submenuVideoCapture.FindItem(MenuId_Capture_Video_Stop)->Enable(false); m_submenuVideoCapture.FindItem(MenuId_Capture_Video_Stop)->Enable(false);
} }
@ -755,7 +782,9 @@ void MainEmuFrame::VideoCaptureUpdate()
void MainEmuFrame::Menu_Capture_Screenshot_Screenshot_Click(wxCommandEvent & event) void MainEmuFrame::Menu_Capture_Screenshot_Screenshot_Click(wxCommandEvent & event)
{ {
if (!CoreThread.IsOpen()) if (!CoreThread.IsOpen())
{
return; return;
}
GSmakeSnapshot(g_Conf->Folders.Snapshots.ToAscii()); GSmakeSnapshot(g_Conf->Folders.Snapshots.ToAscii());
} }
@ -772,18 +801,19 @@ void MainEmuFrame::Menu_Recording_New_Click(wxCommandEvent &event)
return; return;
} }
// From Current Frame // From Current Frame
if (NewRecordingFrame->getFrom() == 0) if (NewRecordingFrame->GetFrom() == 0)
{
if (!CoreThread.IsOpen())
{ {
if (!CoreThread.IsOpen()) {
recordingConLog(L"[REC]: Game is not open, aborting new input recording.\n"); recordingConLog(L"[REC]: Game is not open, aborting new input recording.\n");
return; return;
} }
g_InputRecording.Create(NewRecordingFrame->getFile(), true, NewRecordingFrame->getAuthor()); g_InputRecording.Create(NewRecordingFrame->GetFile(), true, NewRecordingFrame->GetAuthor());
} }
// From Power-On // From Power-On
else if (NewRecordingFrame->getFrom() == 1) else if (NewRecordingFrame->GetFrom() == 1)
{ {
g_InputRecording.Create(NewRecordingFrame->getFile(), false, NewRecordingFrame->getAuthor()); g_InputRecording.Create(NewRecordingFrame->GetFile(), false, NewRecordingFrame->GetAuthor());
} }
} }
m_menuRecording.FindChildItem(MenuId_Recording_New)->Enable(false); m_menuRecording.FindChildItem(MenuId_Recording_New)->Enable(false);
@ -795,7 +825,10 @@ void MainEmuFrame::Menu_Recording_Play_Click(wxCommandEvent &event)
g_InputRecording.Stop(); g_InputRecording.Stop();
wxFileDialog openFileDialog(this, _("Select P2M2 record file."), L"", L"", wxFileDialog openFileDialog(this, _("Select P2M2 record file."), L"", L"",
L"p2m2 file(*.p2m2)|*.p2m2", wxFD_OPEN); L"p2m2 file(*.p2m2)|*.p2m2", wxFD_OPEN);
if (openFileDialog.ShowModal() == wxID_CANCEL) return; if (openFileDialog.ShowModal() == wxID_CANCEL)
{
return;
}
wxString path = openFileDialog.GetPath(); wxString path = openFileDialog.GetPath();
g_InputRecording.Play(path, true); g_InputRecording.Play(path, true);
@ -812,12 +845,18 @@ void MainEmuFrame::Menu_Recording_Stop_Click(wxCommandEvent &event)
void MainEmuFrame::Menu_Recording_VirtualPad_Open_Click(wxCommandEvent &event) void MainEmuFrame::Menu_Recording_VirtualPad_Open_Click(wxCommandEvent &event)
{ {
VirtualPad *vp; VirtualPad *vp = NULL;
if (event.GetId() == MenuId_Recording_VirtualPad_Port0) if (event.GetId() == MenuId_Recording_VirtualPad_Port0)
{
vp = wxGetApp().GetVirtualPadPtr(0); vp = wxGetApp().GetVirtualPadPtr(0);
}
else if (event.GetId() == MenuId_Recording_VirtualPad_Port1) else if (event.GetId() == MenuId_Recording_VirtualPad_Port1)
{
vp = wxGetApp().GetVirtualPadPtr(1); vp = wxGetApp().GetVirtualPadPtr(1);
if (vp) }
if (vp != NULL)
{
vp->Show(); vp->Show();
}
} }
#endif #endif