mirror of https://github.com/PCSX2/pcsx2.git
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:
parent
08d923ca6f
commit
506ea4c4d2
|
@ -46,6 +46,7 @@ Thumbs.db
|
|||
|
||||
Debug.txt
|
||||
install_log.txt
|
||||
padLog.txt
|
||||
|
||||
Debug
|
||||
Release
|
||||
|
|
|
@ -82,7 +82,6 @@ GSwindow_OffsetXplus = Alt-Ctrl-RIGHT
|
|||
GSwindow_OffsetReset = Alt-Ctrl-KP_DIVIDE
|
||||
|
||||
# Recording Bindings
|
||||
# TODO: add to http://wiki.pcsx2.net/index.php/Hotkeys
|
||||
FrameAdvance = SPACE
|
||||
TogglePause = Shift-P
|
||||
InputRecordingModeToggle = Shift-R
|
||||
|
|
|
@ -626,6 +626,7 @@ else()
|
|||
set(pcsx2SSources "")
|
||||
endif()
|
||||
|
||||
|
||||
# common Sources
|
||||
set(Common
|
||||
${pcsx2Sources}
|
||||
|
|
|
@ -455,7 +455,7 @@ struct Pcsx2Config
|
|||
EnableCheats :1, // enables cheat detection and application
|
||||
EnableWideScreenPatches :1,
|
||||
#ifndef DISABLE_RECORDING
|
||||
EnableRecordingTools : 1,
|
||||
EnableRecordingTools :1,
|
||||
#endif
|
||||
// when enabled uses BOOT2 injection, skipping sony bios splashes
|
||||
UseBOOT2Injection :1,
|
||||
|
|
|
@ -575,7 +575,7 @@ __fi void rcntUpdate_vSync()
|
|||
#ifndef DISABLE_RECORDING
|
||||
if (g_Conf->EmuOptions.EnableRecordingTools)
|
||||
{
|
||||
g_RecordingControls.StopCheck();
|
||||
g_RecordingControls.HandleFrameAdvanceAndStop();
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
|
@ -320,9 +320,9 @@ struct SysConsoleLogPack
|
|||
ConsoleLogSource eeRecPerf;
|
||||
ConsoleLogSource sysoutConsole;
|
||||
|
||||
ConsoleLogFromVM<Color_Cyan> eeConsole;
|
||||
ConsoleLogFromVM<Color_Yellow> iopConsole;
|
||||
ConsoleLogFromVM<Color_Cyan> deci2;
|
||||
ConsoleLogFromVM<Color_Cyan> eeConsole;
|
||||
ConsoleLogFromVM<Color_Yellow> iopConsole;
|
||||
ConsoleLogFromVM<Color_Cyan> deci2;
|
||||
|
||||
#ifndef DISABLE_RECORDING
|
||||
ConsoleLogFromVM<Color_StrongMagenta> recordingConsole;
|
||||
|
|
|
@ -434,7 +434,7 @@ void Pcsx2Config::LoadSave( IniInterface& ini )
|
|||
IniBitBool( EnableCheats );
|
||||
IniBitBool( EnableWideScreenPatches );
|
||||
#ifndef DISABLE_RECORDING
|
||||
IniBitBool(EnableRecordingTools);
|
||||
IniBitBool( EnableRecordingTools );
|
||||
#endif
|
||||
IniBitBool( ConsoleToStdio );
|
||||
IniBitBool( HostFs );
|
||||
|
|
|
@ -22,130 +22,126 @@
|
|||
#include "MemoryTypes.h"
|
||||
#include "SaveState.h"
|
||||
|
||||
#include "Recording/RecordingControls.h"
|
||||
#include "InputRecording.h"
|
||||
#include "Recording/RecordingControls.h"
|
||||
|
||||
#include <vector>
|
||||
|
||||
|
||||
InputRecording g_InputRecording;
|
||||
|
||||
// --------------------------------
|
||||
// Tag and save framecount along with savestate
|
||||
// --------------------------------
|
||||
void SaveStateBase::InputRecordingFreeze()
|
||||
{
|
||||
FreezeTag("InputRecording");
|
||||
Freeze(g_FrameCount);
|
||||
if (IsLoading()) {
|
||||
g_InputRecordingData.addUndoCount();
|
||||
|
||||
if (g_FrameCount > 0 && IsLoading())
|
||||
{
|
||||
g_InputRecordingData.AddUndoCount();
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------
|
||||
// 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[])
|
||||
{
|
||||
// TODO - Multi-Tap Support
|
||||
// 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)
|
||||
/*
|
||||
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)
|
||||
{
|
||||
fInterruptFrame = true;
|
||||
}
|
||||
else {
|
||||
fInterruptFrame = false;
|
||||
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) {
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
if (!fInterruptFrame)
|
||||
if (!fInterruptFrame
|
||||
|| state == INPUT_RECORDING_MODE_NONE
|
||||
// We do not want to record or save the first two
|
||||
// bytes in the data returned from LilyPad
|
||||
|| bufCount < 3)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (state == NONE)
|
||||
return;
|
||||
|
||||
// We do not want to record or save the first two
|
||||
// bytes in the data returned from LilyPad
|
||||
if (bufCount < 3)
|
||||
return;
|
||||
|
||||
//---------------
|
||||
// Read or Write
|
||||
//---------------
|
||||
const u8 &nowBuf = buf[bufCount];
|
||||
if (state == RECORD)
|
||||
if (state == INPUT_RECORDING_MODE_RECORD)
|
||||
{
|
||||
InputRecordingData.updateFrameMax(g_FrameCount);
|
||||
InputRecordingData.writeKeyBuf(g_FrameCount, port, bufCount - 3, nowBuf);
|
||||
InputRecordingData.UpdateFrameMax(g_FrameCount);
|
||||
InputRecordingData.WriteKeyBuf(g_FrameCount, port, bufCount - 3, nowBuf);
|
||||
}
|
||||
else if (state == REPLAY)
|
||||
else if (state == INPUT_RECORDING_MODE_REPLAY)
|
||||
{
|
||||
if (InputRecordingData.getMaxFrame() <= g_FrameCount)
|
||||
if (InputRecordingData.GetMaxFrame() <= g_FrameCount)
|
||||
{
|
||||
// Pause the emulation but the movie is not closed
|
||||
g_RecordingControls.Pause();
|
||||
return;
|
||||
}
|
||||
u8 tmp = 0;
|
||||
if (InputRecordingData.readKeyBuf(tmp, g_FrameCount, port, bufCount - 3)) {
|
||||
if (InputRecordingData.ReadKeyBuf(tmp, g_FrameCount, port, bufCount - 3))
|
||||
{
|
||||
buf[bufCount] = tmp;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//----------------------------------
|
||||
// stop
|
||||
//----------------------------------
|
||||
void InputRecording::Stop() {
|
||||
state = NONE;
|
||||
if (InputRecordingData.Close()) {
|
||||
// GUI Handler - Stop recording
|
||||
void InputRecording::Stop()
|
||||
{
|
||||
state = INPUT_RECORDING_MODE_NONE;
|
||||
if (InputRecordingData.Close())
|
||||
{
|
||||
recordingConLog(L"[REC]: InputRecording Recording Stopped.\n");
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------
|
||||
// start
|
||||
//----------------------------------
|
||||
// GUI Handler - Start recording
|
||||
void InputRecording::Create(wxString FileName, bool fromSaveState, wxString authorName)
|
||||
{
|
||||
g_RecordingControls.Pause();
|
||||
Stop();
|
||||
|
||||
// create
|
||||
if (!InputRecordingData.Open(FileName, true, fromSaveState)) {
|
||||
if (!InputRecordingData.Open(FileName, true, fromSaveState))
|
||||
{
|
||||
return;
|
||||
}
|
||||
// Set author name
|
||||
if (!authorName.IsEmpty())
|
||||
{
|
||||
InputRecordingData.getHeader().setAuthor(authorName);
|
||||
InputRecordingData.GetHeader().SetAuthor(authorName);
|
||||
}
|
||||
// Set 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.writeHeader();
|
||||
state = RECORD;
|
||||
InputRecordingData.GetHeader().SetGameName(!gameName.IsEmpty() ? gameName : Path::GetFilename(g_Conf->CurrentIso));
|
||||
InputRecordingData.WriteHeader();
|
||||
state = INPUT_RECORDING_MODE_RECORD;
|
||||
recordingConLog(wxString::Format(L"[REC]: Started new recording - [%s]\n", FileName));
|
||||
|
||||
// In every case, we reset the g_FrameCount
|
||||
g_FrameCount = 0;
|
||||
}
|
||||
|
||||
// GUI Handler - Play a recording
|
||||
void InputRecording::Play(wxString FileName, bool fromSaveState)
|
||||
{
|
||||
g_RecordingControls.Pause();
|
||||
Stop();
|
||||
|
||||
if (!InputRecordingData.Open(FileName, false, false)) {
|
||||
if (!InputRecordingData.Open(FileName, false, false))
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (!InputRecordingData.readHeaderAndCheck()) {
|
||||
if (!InputRecordingData.ReadHeaderAndCheck())
|
||||
{
|
||||
recordingConLog(L"[REC]: This file is not a correct InputRecording file.\n");
|
||||
InputRecordingData.Close();
|
||||
return;
|
||||
|
@ -189,32 +188,46 @@ void InputRecording::Play(wxString FileName, bool fromSaveState)
|
|||
// Check author name
|
||||
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");
|
||||
}
|
||||
}
|
||||
state = REPLAY;
|
||||
state = INPUT_RECORDING_MODE_REPLAY;
|
||||
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"Associated Game Name / ISO Filename: %s\n", InputRecordingData.getHeader().gameName));
|
||||
recordingConLog(wxString::Format(L"Author: %s\n", InputRecordingData.getHeader().author));
|
||||
recordingConLog(wxString::Format(L"MaxFrame: %d\n", InputRecordingData.getMaxFrame()));
|
||||
recordingConLog(wxString::Format(L"UndoCount: %d\n", InputRecordingData.getUndoCount()));
|
||||
recordingConLog(wxString::Format(L"[REC]: Recording File Version: %d\n", InputRecordingData.GetHeader().version));
|
||||
recordingConLog(wxString::Format(L"[REC]: Associated Game Name / ISO Filename: %s\n", InputRecordingData.GetHeader().gameName));
|
||||
recordingConLog(wxString::Format(L"[REC]: Author: %s\n", InputRecordingData.GetHeader().author));
|
||||
recordingConLog(wxString::Format(L"[REC]: MaxFrame: %d\n", InputRecordingData.GetMaxFrame()));
|
||||
recordingConLog(wxString::Format(L"[REC]: UndoCount: %d\n", InputRecordingData.GetUndoCount()));
|
||||
}
|
||||
|
||||
//----------------------------------
|
||||
// shortcut key
|
||||
//----------------------------------
|
||||
// Keybind Handler - Toggle between recording input and not
|
||||
void InputRecording::RecordModeToggle()
|
||||
{
|
||||
if (state == REPLAY) {
|
||||
state = RECORD;
|
||||
if (state == INPUT_RECORDING_MODE_REPLAY)
|
||||
{
|
||||
state = INPUT_RECORDING_MODE_RECORD;
|
||||
recordingConLog("[REC]: Record mode ON.\n");
|
||||
}
|
||||
else if (state == RECORD) {
|
||||
state = REPLAY;
|
||||
else if (state == INPUT_RECORDING_MODE_RECORD)
|
||||
{
|
||||
state = INPUT_RECORDING_MODE_REPLAY;
|
||||
recordingConLog("[REC]: Replay mode ON.\n");
|
||||
}
|
||||
}
|
||||
|
||||
INPUT_RECORDING_MODE InputRecording::GetModeState()
|
||||
{
|
||||
return state;
|
||||
}
|
||||
|
||||
InputRecordingFile & InputRecording::GetInputRecordingData()
|
||||
{
|
||||
return InputRecordingData;
|
||||
}
|
||||
|
||||
bool InputRecording::IsInterruptFrame()
|
||||
{
|
||||
return fInterruptFrame;
|
||||
}
|
||||
|
|
|
@ -18,46 +18,37 @@
|
|||
#include "InputRecordingFile.h"
|
||||
|
||||
|
||||
//----------------------------
|
||||
// InputRecording
|
||||
//----------------------------
|
||||
class InputRecording {
|
||||
enum INPUT_RECORDING_MODE
|
||||
{
|
||||
INPUT_RECORDING_MODE_NONE,
|
||||
INPUT_RECORDING_MODE_RECORD,
|
||||
INPUT_RECORDING_MODE_REPLAY,
|
||||
};
|
||||
|
||||
class InputRecording
|
||||
{
|
||||
public:
|
||||
InputRecording() {}
|
||||
~InputRecording(){}
|
||||
public:
|
||||
// controller
|
||||
|
||||
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 Create(wxString filename, bool fromSaveState, wxString authorName);
|
||||
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:
|
||||
InputRecordingFile InputRecordingData;
|
||||
KEY_MOVIE_MODE state = NONE;
|
||||
INPUT_RECORDING_MODE state = INPUT_RECORDING_MODE_NONE;
|
||||
bool fInterruptFrame = false;
|
||||
|
||||
|
||||
};
|
||||
|
||||
extern InputRecording g_InputRecording;
|
||||
#define g_InputRecordingData (g_InputRecording.getInputRecordingData())
|
||||
#define g_InputRecordingHeader (g_InputRecording.getInputRecordingData().getHeader())
|
||||
static InputRecordingFile& g_InputRecordingData = g_InputRecording.GetInputRecordingData();
|
||||
static InputRecordingHeader& g_InputRecordingHeader = g_InputRecording.GetInputRecordingData().GetHeader();
|
||||
|
|
|
@ -23,25 +23,17 @@
|
|||
|
||||
#include "InputRecordingFile.h"
|
||||
|
||||
#define HEADER_SIZE (sizeof(InputRecordingHeader)+4+4)
|
||||
#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)
|
||||
long InputRecordingFile::GetBlockSeekPoint(const long & frame)
|
||||
{
|
||||
if (savestate.fromSavestate) {
|
||||
return HEADER_SIZE
|
||||
+ SAVESTATE_HEADER_SIZE
|
||||
+ frame * BLOCK_SIZE;
|
||||
if (savestate.fromSavestate)
|
||||
{
|
||||
return RecordingHeaderSize
|
||||
+ RecordingSavestateHeaderSize
|
||||
+ frame * RecordingBlockSize;
|
||||
}
|
||||
else {
|
||||
return HEADER_SIZE + sizeof(bool) + (frame)*BLOCK_SIZE;
|
||||
else
|
||||
{
|
||||
return RecordingHeaderSize + sizeof(bool) + (frame)*RecordingBlockSize;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -50,11 +42,12 @@ bool InputRecordingFile::Open(const wxString path, bool fNewOpen, bool fromSaveS
|
|||
{
|
||||
Close();
|
||||
wxString mode = L"rb+";
|
||||
if (fNewOpen) {
|
||||
if (fNewOpen)
|
||||
{
|
||||
mode = L"wb+";
|
||||
MaxFrame = 0;
|
||||
UndoCount = 0;
|
||||
header.init();
|
||||
header.Init();
|
||||
}
|
||||
recordingFile = wxFopen(path, mode);
|
||||
if ( recordingFile == NULL )
|
||||
|
@ -64,98 +57,114 @@ bool InputRecordingFile::Open(const wxString path, bool fNewOpen, bool fromSaveS
|
|||
}
|
||||
filename = path;
|
||||
|
||||
// problems seem to be be based in how we are saving the savestate
|
||||
if (fNewOpen) {
|
||||
if (fromSaveState) {
|
||||
if (fNewOpen)
|
||||
{
|
||||
if (fromSaveState)
|
||||
{
|
||||
savestate.fromSavestate = true;
|
||||
// TODO - Return save-state data back into the movie file eventually.
|
||||
FILE* ssFileCheck = wxFopen(path + "_SaveState.p2s", "r");
|
||||
if (ssFileCheck != NULL) {
|
||||
if (ssFileCheck != NULL)
|
||||
{
|
||||
wxCopyFile(path + "_SaveState.p2s", path + "_SaveState.p2s.bak", false);
|
||||
fclose(ssFileCheck);
|
||||
}
|
||||
fclose(ssFileCheck);
|
||||
StateCopy_SaveToFile(path + "_SaveState.p2s");
|
||||
}
|
||||
else {
|
||||
else
|
||||
{
|
||||
sApp.SysExecute();
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// Gracefully close the current recording file
|
||||
bool InputRecordingFile::Close()
|
||||
{
|
||||
if (recordingFile == NULL)
|
||||
{
|
||||
return false;
|
||||
writeHeader();
|
||||
writeSaveState();
|
||||
}
|
||||
WriteHeader();
|
||||
WriteSaveState();
|
||||
fclose(recordingFile);
|
||||
recordingFile = NULL;
|
||||
filename = "";
|
||||
return true;
|
||||
}
|
||||
|
||||
bool InputRecordingFile::writeSaveState() {
|
||||
// Write savestate flag to file
|
||||
bool InputRecordingFile::WriteSaveState() {
|
||||
if (recordingFile == NULL)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
fseek(recordingFile, SEEKPOINT_SAVESTATE, SEEK_SET);
|
||||
fseek(recordingFile, RecordingSeekpointSaveState, SEEK_SET);
|
||||
if (fwrite(&savestate.fromSavestate, sizeof(bool), 1, recordingFile) != 1)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//----------------------------------
|
||||
// write frame
|
||||
//----------------------------------
|
||||
bool InputRecordingFile::writeKeyBuf(const uint & frame, const uint port, const uint bufIndex, const u8 & buf)
|
||||
// Write controller input buffer to file (per frame)
|
||||
bool InputRecordingFile::WriteKeyBuf(const uint & frame, const uint port, const uint bufIndex, const u8 & buf)
|
||||
{
|
||||
if (recordingFile == NULL)
|
||||
{
|
||||
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)
|
||||
return false;
|
||||
if (fwrite(&buf, 1, 1, recordingFile) != 1)
|
||||
if (fseek(recordingFile, seek, SEEK_SET) != 0
|
||||
|| fwrite(&buf, 1, 1, recordingFile) != 1)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
fflush(recordingFile);
|
||||
return true;
|
||||
}
|
||||
|
||||
//----------------------------------
|
||||
// read frame
|
||||
//----------------------------------
|
||||
bool InputRecordingFile::readKeyBuf(u8 & result,const uint & frame, const uint port, const uint bufIndex)
|
||||
// Read controller input buffer from file (per frame)
|
||||
bool InputRecordingFile::ReadKeyBuf(u8 & result,const uint & frame, const uint port, const uint bufIndex)
|
||||
{
|
||||
if (recordingFile == NULL)
|
||||
{
|
||||
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)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (fread(&result, 1, 1, recordingFile) != 1)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//===================================
|
||||
// pad
|
||||
//===================================
|
||||
void InputRecordingFile::getPadData(PadData & result, unsigned long frame)
|
||||
|
||||
void InputRecordingFile::GetPadData(PadData & result, unsigned long frame)
|
||||
{
|
||||
result.fExistKey = false;
|
||||
if (recordingFile == NULL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
long seek = _getBlockSeekPoint(frame) + BLOCK_HEADER_SIZE;
|
||||
if (fseek(recordingFile, seek, SEEK_SET) != 0)
|
||||
return;
|
||||
if (fread(result.buf, 1, BLOCK_DATA_SIZE, recordingFile) == 0)
|
||||
long seek = GetBlockSeekPoint(frame) + RecordingBlockHeaderSize;
|
||||
if (fseek(recordingFile, seek, SEEK_SET) != 0
|
||||
|| fread(result.buf, 1, RecordingBlockDataSize, recordingFile) == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
result.fExistKey = true;
|
||||
}
|
||||
|
@ -163,21 +172,33 @@ void InputRecordingFile::getPadData(PadData & result, unsigned long frame)
|
|||
bool InputRecordingFile::DeletePadData(unsigned long frame)
|
||||
{
|
||||
if (recordingFile == NULL)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
for (unsigned long i = frame; i < MaxFrame - 1; i++)
|
||||
{
|
||||
long seek1 = _getBlockSeekPoint(i+1) + BLOCK_HEADER_SIZE;
|
||||
long seek2 = _getBlockSeekPoint(i) + BLOCK_HEADER_SIZE;
|
||||
long seek1 = GetBlockSeekPoint(i+1) + RecordingBlockHeaderSize;
|
||||
long seek2 = GetBlockSeekPoint(i) + RecordingBlockHeaderSize;
|
||||
|
||||
u8 buf[2][18];
|
||||
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);
|
||||
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--;
|
||||
writeMaxFrame();
|
||||
WriteMaxFrame();
|
||||
fflush(recordingFile);
|
||||
|
||||
return true;
|
||||
|
@ -185,29 +206,42 @@ bool InputRecordingFile::DeletePadData(unsigned long frame)
|
|||
|
||||
bool InputRecordingFile::InsertPadData(unsigned long frame, const PadData& key)
|
||||
{
|
||||
if (recordingFile == NULL)
|
||||
return false;
|
||||
if (!key.fExistKey)
|
||||
if (recordingFile == NULL || !key.fExistKey)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
for (unsigned long i = MaxFrame - 1; i >= frame; i--)
|
||||
{
|
||||
long seek1 = _getBlockSeekPoint(i) + BLOCK_HEADER_SIZE;
|
||||
long seek2 = _getBlockSeekPoint(i+1) + BLOCK_HEADER_SIZE;
|
||||
long seek1 = GetBlockSeekPoint(i) + RecordingBlockHeaderSize;
|
||||
long seek2 = GetBlockSeekPoint(i+1) + RecordingBlockHeaderSize;
|
||||
|
||||
u8 buf[2][18];
|
||||
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);
|
||||
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, wrote %d instead.\n", RecordingBlockDataSize, rSize));
|
||||
return false;
|
||||
}
|
||||
}
|
||||
long seek = GetBlockSeekPoint(frame) + RecordingBlockHeaderSize;
|
||||
fseek(recordingFile, seek, SEEK_SET);
|
||||
int rSize = fwrite(key.buf, 1, RecordingBlockDataSize, recordingFile);
|
||||
if (rSize != RecordingBlockDataSize)
|
||||
{
|
||||
long seek = _getBlockSeekPoint(frame) + BLOCK_HEADER_SIZE;
|
||||
fseek(recordingFile, seek, SEEK_SET);
|
||||
fwrite(key.buf, 1, BLOCK_DATA_SIZE, recordingFile);
|
||||
recordingConLog(wxString::Format("[REC]: Error encountered when writing to file: Expected %d bytes, wrote %d instead.\n", RecordingBlockDataSize, rSize));
|
||||
return false;
|
||||
}
|
||||
MaxFrame++;
|
||||
writeMaxFrame();
|
||||
WriteMaxFrame();
|
||||
fflush(recordingFile);
|
||||
|
||||
return true;
|
||||
|
@ -216,100 +250,149 @@ bool InputRecordingFile::InsertPadData(unsigned long frame, const PadData& key)
|
|||
bool InputRecordingFile::UpdatePadData(unsigned long frame, const PadData& key)
|
||||
{
|
||||
if (recordingFile == NULL)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (!key.fExistKey)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
long seek = _getBlockSeekPoint(frame) + BLOCK_HEADER_SIZE;
|
||||
long seek = GetBlockSeekPoint(frame) + RecordingBlockHeaderSize;
|
||||
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;
|
||||
}
|
||||
|
||||
fflush(recordingFile);
|
||||
return true;
|
||||
}
|
||||
|
||||
// Verify header of recording file
|
||||
bool InputRecordingFile::readHeaderAndCheck()
|
||||
bool InputRecordingFile::ReadHeaderAndCheck()
|
||||
{
|
||||
if (recordingFile == NULL) return false;
|
||||
if (recordingFile == NULL)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
rewind(recordingFile);
|
||||
if (fread(&header, sizeof(InputRecordingHeader), 1, recordingFile) != 1) return false;
|
||||
if (fread(&MaxFrame, 4, 1, recordingFile) != 1) return false;
|
||||
if (fread(&UndoCount, 4, 1, recordingFile) != 1) return false;
|
||||
if (fread(&savestate.fromSavestate, sizeof(bool), 1, recordingFile) != 1) return false;
|
||||
if (savestate.fromSavestate) {
|
||||
if (fread(&header, sizeof(InputRecordingHeader), 1, recordingFile) != 1
|
||||
|| fread(&MaxFrame, 4, 1, recordingFile) != 1
|
||||
|| fread(&UndoCount, 4, 1, recordingFile) != 1
|
||||
|| fread(&savestate.fromSavestate, sizeof(bool), 1, recordingFile) != 1)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (savestate.fromSavestate)
|
||||
{
|
||||
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"));
|
||||
return false;
|
||||
}
|
||||
fclose(ssFileCheck);
|
||||
StateCopy_LoadFromFile(filename + "_SaveState.p2s");
|
||||
}
|
||||
else {
|
||||
else
|
||||
{
|
||||
sApp.SysExecute();
|
||||
}
|
||||
|
||||
// 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));
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
bool InputRecordingFile::writeHeader()
|
||||
bool InputRecordingFile::WriteHeader()
|
||||
{
|
||||
if (recordingFile == NULL) return false;
|
||||
if (recordingFile == NULL)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
rewind(recordingFile);
|
||||
if (fwrite(&header, sizeof(InputRecordingHeader), 1, recordingFile) != 1) return false;
|
||||
if (fwrite(&header, sizeof(InputRecordingHeader), 1, recordingFile) != 1)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool InputRecordingFile::writeMaxFrame()
|
||||
bool InputRecordingFile::WriteMaxFrame()
|
||||
{
|
||||
if (recordingFile == NULL)return false;
|
||||
fseek(recordingFile, SEEKPOINT_FRAMEMAX, SEEK_SET);
|
||||
if (fwrite(&MaxFrame, 4, 1, recordingFile) != 1) return false;
|
||||
if (recordingFile == NULL)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
fseek(recordingFile, RecordingSeekpointFrameMax, SEEK_SET);
|
||||
if (fwrite(&MaxFrame, 4, 1, recordingFile) != 1)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void InputRecordingFile::updateFrameMax(unsigned long frame)
|
||||
void InputRecordingFile::UpdateFrameMax(unsigned long frame)
|
||||
{
|
||||
if (MaxFrame >= frame) {
|
||||
if (recordingFile == NULL || MaxFrame >= frame)
|
||||
{
|
||||
return;
|
||||
}
|
||||
MaxFrame = frame;
|
||||
if (recordingFile == NULL)return ;
|
||||
fseek(recordingFile, SEEKPOINT_FRAMEMAX, SEEK_SET);
|
||||
fseek(recordingFile, RecordingSeekpointFrameMax, SEEK_SET);
|
||||
fwrite(&MaxFrame, 4, 1, recordingFile);
|
||||
}
|
||||
|
||||
void InputRecordingFile::addUndoCount()
|
||||
void InputRecordingFile::AddUndoCount()
|
||||
{
|
||||
UndoCount++;
|
||||
if (recordingFile == NULL)
|
||||
{
|
||||
return;
|
||||
fseek(recordingFile, SEEKPOINT_UNDOCOUNT, SEEK_SET);
|
||||
}
|
||||
fseek(recordingFile, RecordingSeekpointUndoCount, SEEK_SET);
|
||||
fwrite(&UndoCount, 4, 1, recordingFile);
|
||||
}
|
||||
|
||||
void InputRecordingHeader::setAuthor(wxString _author)
|
||||
void InputRecordingHeader::SetAuthor(wxString _author)
|
||||
{
|
||||
int max = ArraySize(author) - 1;
|
||||
strncpy(author, _author.c_str(), max);
|
||||
author[max] = 0;
|
||||
}
|
||||
|
||||
void InputRecordingHeader::setGameName(wxString _gameName)
|
||||
void InputRecordingHeader::SetGameName(wxString _gameName)
|
||||
{
|
||||
int max = ArraySize(gameName) - 1;
|
||||
strncpy(gameName, _gameName.c_str(), max);
|
||||
gameName[max] = 0;
|
||||
}
|
||||
|
||||
void InputRecordingHeader::init()
|
||||
void InputRecordingHeader::Init()
|
||||
{
|
||||
memset(author, 0, ArraySize(author));
|
||||
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;
|
||||
}
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
#include "PadData.h"
|
||||
#include "System.h"
|
||||
|
||||
|
||||
struct InputRecordingHeader
|
||||
{
|
||||
u8 version = 1;
|
||||
|
@ -26,11 +27,13 @@ struct InputRecordingHeader
|
|||
char gameName[255] = "";
|
||||
|
||||
public:
|
||||
void setAuthor(wxString author);
|
||||
void setGameName(wxString cdrom);
|
||||
void init();
|
||||
void SetAuthor(wxString author);
|
||||
void SetGameName(wxString cdrom);
|
||||
void Init();
|
||||
};
|
||||
|
||||
static const int RecordingHeaderSize = sizeof(InputRecordingHeader) + 4 + 4;
|
||||
|
||||
// Contains info about the starting point of the movie
|
||||
struct InputRecordingSavestate
|
||||
{
|
||||
|
@ -38,8 +41,8 @@ struct InputRecordingSavestate
|
|||
bool fromSavestate = false;
|
||||
};
|
||||
|
||||
|
||||
class InputRecordingFile {
|
||||
class InputRecordingFile
|
||||
{
|
||||
public:
|
||||
InputRecordingFile() {}
|
||||
~InputRecordingFile() { Close(); }
|
||||
|
@ -47,38 +50,46 @@ public:
|
|||
// Movie File Manipulation
|
||||
bool Open(const wxString fn, bool fNewOpen, bool fromSaveState);
|
||||
bool Close();
|
||||
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 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);
|
||||
|
||||
// Controller Data
|
||||
void getPadData(PadData & result_pad, unsigned long frame);
|
||||
void GetPadData(PadData & result_pad, unsigned long frame);
|
||||
bool DeletePadData(unsigned long frame);
|
||||
bool InsertPadData(unsigned long frame, const PadData& key);
|
||||
bool UpdatePadData(unsigned long frame, const PadData& key);
|
||||
|
||||
// Header
|
||||
InputRecordingHeader& getHeader() { return header; }
|
||||
unsigned long& getMaxFrame() { return MaxFrame; }
|
||||
unsigned long& getUndoCount() { return UndoCount; }
|
||||
const wxString & getFilename() { return filename; }
|
||||
InputRecordingHeader& GetHeader();
|
||||
unsigned long& GetMaxFrame();
|
||||
unsigned long& GetUndoCount();
|
||||
const wxString & GetFilename();
|
||||
|
||||
bool writeHeader();
|
||||
bool writeMaxFrame();
|
||||
bool writeSaveState();
|
||||
bool WriteHeader();
|
||||
bool WriteMaxFrame();
|
||||
bool WriteSaveState();
|
||||
|
||||
bool readHeaderAndCheck();
|
||||
void updateFrameMax(unsigned long frame);
|
||||
void addUndoCount();
|
||||
bool ReadHeaderAndCheck();
|
||||
void UpdateFrameMax(unsigned long frame);
|
||||
void AddUndoCount();
|
||||
|
||||
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
|
||||
FILE * recordingFile = NULL;
|
||||
wxString filename = "";
|
||||
long _getBlockSeekPoint(const long & frame);
|
||||
long GetBlockSeekPoint(const long & frame);
|
||||
|
||||
// Header
|
||||
InputRecordingHeader header;
|
||||
InputRecordingSavestate savestate;
|
||||
unsigned long MaxFrame = 0;
|
||||
unsigned long UndoCount = 0;
|
||||
unsigned long MaxFrame = 0;
|
||||
unsigned long UndoCount = 0;
|
||||
};
|
||||
|
|
|
@ -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();
|
||||
}
|
|
@ -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;
|
||||
};
|
||||
|
|
@ -17,17 +17,11 @@
|
|||
|
||||
#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"));
|
||||
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);
|
||||
|
@ -36,12 +30,12 @@ NewRecordingFrame::NewRecordingFrame(wxWindow *parent)
|
|||
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);
|
||||
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, MenuIds_New_Recording_Frame_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 = new wxChoice(panel, MenuIds_New_Recording_Frame_From, wxDefaultPosition, wxDefaultSize, choices);
|
||||
m_fromChoice->SetSelection(0);
|
||||
|
||||
m_startRecording = new wxButton(panel, wxID_OK, _("Ok"), wxDefaultPosition, wxDefaultSize);
|
||||
|
@ -65,17 +59,17 @@ NewRecordingFrame::NewRecordingFrame(wxWindow *parent)
|
|||
Centre();
|
||||
}
|
||||
|
||||
wxString NewRecordingFrame::getFile() const
|
||||
wxString NewRecordingFrame::GetFile() const
|
||||
{
|
||||
return m_filePicker->GetPath();
|
||||
}
|
||||
|
||||
wxString NewRecordingFrame::getAuthor() const
|
||||
wxString NewRecordingFrame::GetAuthor() const
|
||||
{
|
||||
return m_authorInput->GetValue();
|
||||
}
|
||||
|
||||
int NewRecordingFrame::getFrom() const
|
||||
int NewRecordingFrame::GetFrom() const
|
||||
{
|
||||
return m_fromChoice->GetSelection();
|
||||
}
|
||||
|
|
|
@ -18,17 +18,23 @@
|
|||
#include <wx/wx.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
|
||||
{
|
||||
public:
|
||||
NewRecordingFrame(wxWindow *parent);
|
||||
|
||||
wxString getFile() const;
|
||||
wxString getAuthor() const;
|
||||
int getFrom() const;
|
||||
wxString GetFile() const;
|
||||
wxString GetAuthor() const;
|
||||
int GetFrom() const;
|
||||
|
||||
private:
|
||||
wxStaticText *m_fileLabel;
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
#include "ConsoleLogger.h"
|
||||
#include "PadData.h"
|
||||
|
||||
|
||||
PadData::PadData()
|
||||
{
|
||||
// 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
|
||||
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++)
|
||||
{
|
||||
buttons[i] = getNormalButton(port, PadDataNormalButton(i));
|
||||
buttons[i] = GetNormalButton(port, PadData_NormalButton(i));
|
||||
}
|
||||
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++)
|
||||
{
|
||||
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)
|
||||
{
|
||||
return;
|
||||
}
|
||||
wxByte keybit[2];
|
||||
getKeyBit(keybit, button);
|
||||
int pressureByteIndex = getPressureByte(button);
|
||||
GetKeyBit(keybit, button);
|
||||
int pressureByteIndex = GetPressureByte(button);
|
||||
|
||||
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)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
wxByte keybit[2];
|
||||
getKeyBit(keybit, button);
|
||||
int pressureByteIndex = getPressureByte(button);
|
||||
GetKeyBit(keybit, button);
|
||||
int pressureByteIndex = GetPressureByte(button);
|
||||
|
||||
// If the button is pressed on either controller
|
||||
bool f1 = (~buf[port][0] & keybit[0])>0;
|
||||
|
@ -132,110 +138,195 @@ int PadData::getNormalButton(int port, PadDataNormalButton button) const
|
|||
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; }
|
||||
else if (button == LEFT) { keybit[0] = 0b10000000; keybit[1] = 0b00000000; }
|
||||
else if (button == RIGHT) { keybit[0] = 0b00100000; keybit[1] = 0b00000000; }
|
||||
else if (button == DOWN) { keybit[0] = 0b01000000; keybit[1] = 0b00000000; }
|
||||
else if (button == START) { keybit[0] = 0b00001000; keybit[1] = 0b00000000; }
|
||||
else if (button == SELECT) { keybit[0] = 0b00000001; keybit[1] = 0b00000000; }
|
||||
else if (button == CROSS) { keybit[0] = 0b00000000; keybit[1] = 0b01000000; }
|
||||
else if (button == CIRCLE) { keybit[0] = 0b00000000; keybit[1] = 0b00100000; }
|
||||
else if (button == SQUARE) { keybit[0] = 0b00000000; keybit[1] = 0b10000000; }
|
||||
else if (button == TRIANGLE) { keybit[0] = 0b00000000; keybit[1] = 0b00010000; }
|
||||
else if (button == L1) { keybit[0] = 0b00000000; keybit[1] = 0b00000100; }
|
||||
else if (button == L2) { keybit[0] = 0b00000000; keybit[1] = 0b00000001; }
|
||||
else if (button == L3) { keybit[0] = 0b00000010; keybit[1] = 0b00000000; }
|
||||
else if (button == R1) { keybit[0] = 0b00000000; keybit[1] = 0b00001000; }
|
||||
else if (button == R2) { keybit[0] = 0b00000000; keybit[1] = 0b00000010; }
|
||||
else if (button == R3) { keybit[0] = 0b00000100; keybit[1] = 0b00000000; }
|
||||
else { keybit[0] = 0; keybit[1] = 0; }
|
||||
switch (button)
|
||||
{
|
||||
case PadData_NormalButton_LEFT:
|
||||
keybit[0] = 0b10000000;
|
||||
keybit[1] = 0b00000000;
|
||||
break;
|
||||
case PadData_NormalButton_DOWN:
|
||||
keybit[0] = 0b01000000;
|
||||
keybit[1] = 0b00000000;
|
||||
break;
|
||||
case PadData_NormalButton_RIGHT:
|
||||
keybit[0] = 0b00100000;
|
||||
keybit[1] = 0b00000000;
|
||||
break;
|
||||
case PadData_NormalButton_UP:
|
||||
keybit[0] = 0b00010000;
|
||||
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 -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
|
||||
// R - L - U - D - Tri - Sqr - Circle - Cross - L1 - R1 - L2 - R2
|
||||
if (button == UP)
|
||||
return 2;
|
||||
else if (button == LEFT)
|
||||
return 1;
|
||||
else if (button == RIGHT)
|
||||
return 0;
|
||||
else if (button == DOWN)
|
||||
return 3;
|
||||
else if (button == CROSS)
|
||||
return 6;
|
||||
else if (button == CIRCLE)
|
||||
return 5;
|
||||
else if (button == SQUARE)
|
||||
return 7;
|
||||
else if (button == TRIANGLE)
|
||||
return 4;
|
||||
else if (button == L1)
|
||||
return 8;
|
||||
else if (button == L2)
|
||||
return 10;
|
||||
else if (button == R1)
|
||||
return 9;
|
||||
else if (button == R2)
|
||||
return 11;
|
||||
else
|
||||
return -1;
|
||||
// R - L - U - D - Tri - Circle - Cross - Sqr - L1 - R1 - L2 - R2
|
||||
switch (button)
|
||||
{
|
||||
case PadData_NormalButton_RIGHT:
|
||||
return 0;
|
||||
break;
|
||||
case PadData_NormalButton_LEFT:
|
||||
return 1;
|
||||
break;
|
||||
case PadData_NormalButton_UP:
|
||||
return 2;
|
||||
break;
|
||||
case PadData_NormalButton_DOWN:
|
||||
return 3;
|
||||
break;
|
||||
case PadData_NormalButton_TRIANGLE:
|
||||
return 4;
|
||||
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;
|
||||
break;
|
||||
case PadData_NormalButton_R1:
|
||||
return 9;
|
||||
break;
|
||||
case PadData_NormalButton_L2:
|
||||
return 10;
|
||||
break;
|
||||
case PadData_NormalButton_R2:
|
||||
return 11;
|
||||
break;
|
||||
default:
|
||||
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++)
|
||||
{
|
||||
vectors[i] = getAnalogVector(port, PadDataAnalogVector(i));
|
||||
vectors[i] = GetAnalogVector(port, PadData_AnalogVector(i));
|
||||
}
|
||||
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++)
|
||||
{
|
||||
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)
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (val < 0)
|
||||
{
|
||||
val = 0;
|
||||
}
|
||||
else if (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)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
return buf[port][getAnalogVectorByte(vector)];
|
||||
return buf[port][GetAnalogVectorByte(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
|
||||
// RX - RY - LX - LY
|
||||
if (vector == LEFT_ANALOG_X)
|
||||
return 4;
|
||||
else if (vector == LEFT_ANALOG_Y)
|
||||
return 5;
|
||||
else if (vector == RIGHT_ANALOG_X)
|
||||
return 2;
|
||||
else
|
||||
return 3;
|
||||
switch (vector)
|
||||
{
|
||||
case PadData_AnalogVector_RIGHT_ANALOG_X:
|
||||
return 2;
|
||||
break;
|
||||
case PadData_AnalogVector_RIGHT_ANALOG_Y:
|
||||
return 3;
|
||||
break;
|
||||
case PadData_AnalogVector_LEFT_ANALOG_X:
|
||||
return 4;
|
||||
break;
|
||||
case PadData_AnalogVector_LEFT_ANALOG_Y:
|
||||
return 5;
|
||||
break;
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,35 +16,37 @@
|
|||
#pragma once
|
||||
|
||||
#include <map>
|
||||
#include <vector>
|
||||
|
||||
#define PadDataNormalButtonCount 16
|
||||
enum PadDataNormalButton
|
||||
|
||||
static const int PadDataNormalButtonCount = 16;
|
||||
enum PadData_NormalButton
|
||||
{
|
||||
UP,
|
||||
RIGHT,
|
||||
LEFT,
|
||||
DOWN,
|
||||
CROSS,
|
||||
CIRCLE,
|
||||
SQUARE,
|
||||
TRIANGLE,
|
||||
L1,
|
||||
L2,
|
||||
R1,
|
||||
R2,
|
||||
L3,
|
||||
R3,
|
||||
SELECT,
|
||||
START
|
||||
PadData_NormalButton_UP,
|
||||
PadData_NormalButton_RIGHT,
|
||||
PadData_NormalButton_LEFT,
|
||||
PadData_NormalButton_DOWN,
|
||||
PadData_NormalButton_CROSS,
|
||||
PadData_NormalButton_CIRCLE,
|
||||
PadData_NormalButton_SQUARE,
|
||||
PadData_NormalButton_TRIANGLE,
|
||||
PadData_NormalButton_L1,
|
||||
PadData_NormalButton_L2,
|
||||
PadData_NormalButton_R1,
|
||||
PadData_NormalButton_R2,
|
||||
PadData_NormalButton_L3,
|
||||
PadData_NormalButton_R3,
|
||||
PadData_NormalButton_SELECT,
|
||||
PadData_NormalButton_START
|
||||
};
|
||||
|
||||
#define PadDataAnalogVectorCount 4
|
||||
enum PadDataAnalogVector
|
||||
static const int PadDataAnalogVectorCount = 4;
|
||||
enum PadData_AnalogVector
|
||||
{
|
||||
LEFT_ANALOG_X,
|
||||
LEFT_ANALOG_Y,
|
||||
RIGHT_ANALOG_X,
|
||||
RIGHT_ANALOG_Y
|
||||
PadData_AnalogVector_LEFT_ANALOG_X,
|
||||
PadData_AnalogVector_LEFT_ANALOG_Y,
|
||||
PadData_AnalogVector_RIGHT_ANALOG_X,
|
||||
PadData_AnalogVector_RIGHT_ANALOG_Y
|
||||
};
|
||||
|
||||
struct PadData
|
||||
|
@ -57,29 +59,29 @@ public:
|
|||
u8 buf[2][18];
|
||||
|
||||
// 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
|
||||
int* getNormalButtons(int port) const;
|
||||
void setNormalButtons(int port, int* buttons);
|
||||
std::vector<int> GetNormalButtons(int port) const;
|
||||
void SetNormalButtons(int port, std::vector<int> buttons);
|
||||
|
||||
// Analog Vectors
|
||||
// max left/up : 0
|
||||
// neutral : 127
|
||||
// max right/down : 255
|
||||
int* getAnalogVectors(int port) const;
|
||||
std::vector<int> GetAnalogVectors(int port) const;
|
||||
// max left/up : 0
|
||||
// neutral : 127
|
||||
// max right/down : 255
|
||||
void setAnalogVectors(int port, int* vector);
|
||||
void SetAnalogVectors(int port, std::vector<int> vector);
|
||||
|
||||
private:
|
||||
void setNormalButton(int port, PadDataNormalButton button, int pressure);
|
||||
int getNormalButton(int port, PadDataNormalButton button) const;
|
||||
void getKeyBit(wxByte keybit[2], PadDataNormalButton button) const;
|
||||
int getPressureByte(PadDataNormalButton button) const;
|
||||
void SetNormalButton(int port, PadData_NormalButton button, int pressure);
|
||||
int GetNormalButton(int port, PadData_NormalButton button) const;
|
||||
void GetKeyBit(wxByte keybit[2], PadData_NormalButton button) const;
|
||||
int GetPressureByte(PadData_NormalButton button) const;
|
||||
|
||||
void setAnalogVector(int port, PadDataAnalogVector vector, int val);
|
||||
int getAnalogVector(int port, PadDataAnalogVector vector) const;
|
||||
int getAnalogVectorByte(PadDataAnalogVector vector) const;
|
||||
void SetAnalogVector(int port, PadData_AnalogVector vector, int val);
|
||||
int GetAnalogVector(int port, PadData_AnalogVector vector) const;
|
||||
int GetAnalogVectorByte(PadData_AnalogVector vector) const;
|
||||
};
|
||||
|
|
|
@ -15,32 +15,31 @@
|
|||
|
||||
#include "PrecompiledHeader.h"
|
||||
|
||||
#include "GSFrame.h"
|
||||
|
||||
#include "MemoryTypes.h"
|
||||
#include "App.h"
|
||||
#include "Counters.h"
|
||||
#include "GSFrame.h"
|
||||
#include "MemoryTypes.h"
|
||||
|
||||
#include "RecordingControls.h"
|
||||
|
||||
|
||||
RecordingControls g_RecordingControls;
|
||||
|
||||
// TODO - I think these functions could be named a lot better...
|
||||
|
||||
//-----------------------------------------------
|
||||
// Status on whether or not the current recording is stopped
|
||||
//-----------------------------------------------
|
||||
bool RecordingControls::isStop()
|
||||
bool RecordingControls::HasRecordingStopped()
|
||||
{
|
||||
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.
|
||||
//-----------------------------------------------
|
||||
void RecordingControls::StartCheck()
|
||||
void RecordingControls::ResumeCoreThreadIfStarted()
|
||||
{
|
||||
if (fStart && CoreThread.IsOpen() && CoreThread.IsPaused()) {
|
||||
if (fStart && CoreThread.IsOpen() && CoreThread.IsPaused())
|
||||
{
|
||||
CoreThread.Resume();
|
||||
fStart = false;
|
||||
fPauseState = false;
|
||||
|
@ -51,10 +50,12 @@ void RecordingControls::StartCheck()
|
|||
// 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.
|
||||
//-----------------------------------------------
|
||||
void RecordingControls::StopCheck()
|
||||
void RecordingControls::HandleFrameAdvanceAndStop()
|
||||
{
|
||||
if (fFrameAdvance) {
|
||||
if (stopFrameCount < g_FrameCount) {
|
||||
if (fFrameAdvance)
|
||||
{
|
||||
if (stopFrameCount < g_FrameCount)
|
||||
{
|
||||
fFrameAdvance = false;
|
||||
fStop = true;
|
||||
stopFrameCount = g_FrameCount;
|
||||
|
@ -80,11 +81,11 @@ void RecordingControls::StopCheck()
|
|||
}
|
||||
}
|
||||
|
||||
bool RecordingControls::GetStopFlag()
|
||||
{
|
||||
return (fStop || fFrameAdvance);
|
||||
}
|
||||
|
||||
|
||||
//----------------------------------
|
||||
// shortcut key
|
||||
//----------------------------------
|
||||
void RecordingControls::FrameAdvance()
|
||||
{
|
||||
stopFrameCount = g_FrameCount;
|
||||
|
@ -92,22 +93,25 @@ void RecordingControls::FrameAdvance()
|
|||
fStop = false;
|
||||
fStart = true;
|
||||
}
|
||||
|
||||
void RecordingControls::TogglePause()
|
||||
{
|
||||
fStop = !fStop;
|
||||
if (fStop == false) {
|
||||
if (fStop == false)
|
||||
{
|
||||
fStart = true;
|
||||
}
|
||||
}
|
||||
|
||||
void RecordingControls::Pause()
|
||||
{
|
||||
fStop = true;
|
||||
fFrameAdvance = true;
|
||||
}
|
||||
void RecordingControls::UnPause()
|
||||
|
||||
void RecordingControls::Unpause()
|
||||
{
|
||||
fStop = false;
|
||||
fStart = true;
|
||||
fFrameAdvance = true;
|
||||
}
|
||||
|
||||
|
|
|
@ -15,13 +15,14 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
class RecordingControls {
|
||||
class RecordingControls
|
||||
{
|
||||
public:
|
||||
|
||||
// Movie controls main functions
|
||||
bool isStop();
|
||||
void StartCheck();
|
||||
void StopCheck();
|
||||
bool HasRecordingStopped();
|
||||
void ResumeCoreThreadIfStarted();
|
||||
void HandleFrameAdvanceAndStop();
|
||||
|
||||
// Shortcut Keys
|
||||
void FrameAdvance();
|
||||
|
@ -29,10 +30,10 @@ public:
|
|||
|
||||
// Setters
|
||||
void Pause();
|
||||
void UnPause();
|
||||
void Unpause();
|
||||
|
||||
// Getters
|
||||
bool getStopFlag() { return (fStop || fFrameAdvance); }
|
||||
bool GetStopFlag();
|
||||
|
||||
private:
|
||||
uint stopFrameCount = false;
|
||||
|
@ -43,4 +44,5 @@ private:
|
|||
bool fPauseState = false;
|
||||
|
||||
};
|
||||
|
||||
extern RecordingControls g_RecordingControls;
|
||||
|
|
|
@ -18,18 +18,23 @@
|
|||
#include "RecordingInputManager.h"
|
||||
#include "InputRecording.h"
|
||||
|
||||
|
||||
RecordingInputManager g_RecordingInput;
|
||||
|
||||
RecordingInputManager::RecordingInputManager()
|
||||
{
|
||||
for (u8 i = 0; i < 2; i++)
|
||||
{
|
||||
virtualPad[i] = false;
|
||||
}
|
||||
}
|
||||
|
||||
void RecordingInputManager::ControllerInterrupt(u8 & data, u8 & port, u16 & BufCount, u8 buf[])
|
||||
{
|
||||
if (port >= 2)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
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
|
||||
// already handled by InputRecording.cpp
|
||||
if (BufCount < 3)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// 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.
|
||||
if (BufCount <= 4)
|
||||
buf[BufCount] = buf[BufCount] & pad.buf[port][BufCount - 3];
|
||||
{
|
||||
buf[BufCount] = buf[BufCount] & pad.buf[port][bufIndex];
|
||||
}
|
||||
// Analog keys (! overrides !)
|
||||
else if ((BufCount > 4 && BufCount <= 6) && pad.buf[port][BufCount - 3] != 127)
|
||||
buf[BufCount] = pad.buf[port][BufCount - 3];
|
||||
else if ((BufCount > 4 && BufCount <= 6) && pad.buf[port][bufIndex] != 127)
|
||||
{
|
||||
buf[BufCount] = pad.buf[port][bufIndex];
|
||||
}
|
||||
// Pressure sensitivity bytes
|
||||
else if (BufCount > 6)
|
||||
buf[BufCount] = pad.buf[port][BufCount - 3];
|
||||
{
|
||||
buf[BufCount] = pad.buf[port][bufIndex];
|
||||
}
|
||||
|
||||
// Updating movie file
|
||||
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;
|
||||
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;
|
||||
pad.setAnalogVectors(port, vectors);
|
||||
pad.SetAnalogVectors(port, vectors);
|
||||
}
|
||||
|
||||
void RecordingInputManager::SetVirtualPadReading(int port, bool read)
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
|
||||
#include "PadData.h"
|
||||
|
||||
|
||||
class RecordingInputManager
|
||||
{
|
||||
public:
|
||||
|
@ -24,9 +25,9 @@ public:
|
|||
|
||||
void ControllerInterrupt(u8 &data, u8 &port, u16 & BufCount, u8 buf[]);
|
||||
// Handles normal keys
|
||||
void SetButtonState(int port, PadDataNormalButton button, int pressure);
|
||||
void SetButtonState(int port, PadData_NormalButton button, int pressure);
|
||||
// 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);
|
||||
|
||||
protected:
|
||||
|
|
|
@ -125,10 +125,12 @@ VirtualPad::VirtualPad(wxWindow* parent, wxWindowID id, const wxString& title, i
|
|||
|
||||
void VirtualPad::SetProperties()
|
||||
{
|
||||
if (controllerPort == 0) {
|
||||
if (controllerPort == 0)
|
||||
{
|
||||
SetTitle(wxT("Virtual Pad - Port 1"));
|
||||
}
|
||||
else {
|
||||
else
|
||||
{
|
||||
SetTitle(wxT("Virtual Pad - Port 2"));
|
||||
}
|
||||
SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW));
|
||||
|
@ -137,9 +139,13 @@ void VirtualPad::SetProperties()
|
|||
bool VirtualPad::Show(bool show)
|
||||
{
|
||||
if (!wxFrame::Show(show))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (show)
|
||||
{
|
||||
g_RecordingInput.SetVirtualPadReading(controllerPort, true);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -174,7 +180,7 @@ void VirtualPad::OnButtonPress(wxCommandEvent & event)
|
|||
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)
|
||||
{
|
||||
u8 pressure = 0;
|
||||
if (event.IsChecked()) {
|
||||
if (event.IsChecked())
|
||||
{
|
||||
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());
|
||||
}
|
||||
else {
|
||||
else
|
||||
{
|
||||
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)
|
||||
{
|
||||
analogVals[spinnerId]->SetValue(event.GetInt());
|
||||
g_RecordingInput.UpdateAnalog(controllerPort, PadDataAnalogVector(spinnerId), event.GetInt() + 127);
|
||||
g_RecordingInput.UpdateAnalog(controllerPort, PadData_AnalogVector(spinnerId), event.GetInt() + 127);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -219,15 +219,14 @@ SIO_WRITE sioWriteController(u8 data)
|
|||
if (g_Conf->EmuOptions.EnableRecordingTools)
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
PadData::logPadData(sio.port, sio.bufCount, sio.buf);
|
||||
PadData::LogPadData(sio.port, sio.bufCount, sio.buf);
|
||||
}
|
||||
#endif
|
||||
|
||||
break;
|
||||
}
|
||||
//Console.WriteLn( "SIO: sent = %02X From pad data = %02X bufCnt %08X ", data, sio.buf[sio.bufCount], sio.bufCount);
|
||||
|
|
|
@ -135,15 +135,15 @@ TLD_controlInfo = {
|
|||
; // End init of TraceLogDescriptors
|
||||
|
||||
SysConsoleLogPack::SysConsoleLogPack()
|
||||
: ELF (&TLD_ELF, Color_Gray)
|
||||
, eeRecPerf (&TLD_eeRecPerf, Color_Gray)
|
||||
: ELF (&TLD_ELF, Color_Gray)
|
||||
, eeRecPerf (&TLD_eeRecPerf, Color_Gray)
|
||||
, sysoutConsole(&TLD_sysoutConsole, Color_Gray)
|
||||
, eeConsole (&TLD_eeConsole)
|
||||
, iopConsole (&TLD_iopConsole)
|
||||
, deci2 (&TLD_deci2)
|
||||
, eeConsole (&TLD_eeConsole)
|
||||
, iopConsole (&TLD_iopConsole)
|
||||
, deci2 (&TLD_deci2)
|
||||
#ifndef DISABLE_RECORDING
|
||||
, recordingConsole(&TLD_recordingConsole)
|
||||
, controlInfo(&TLD_controlInfo)
|
||||
, recordingConsole (&TLD_recordingConsole)
|
||||
, controlInfo (&TLD_controlInfo)
|
||||
#endif
|
||||
{
|
||||
}
|
||||
|
|
|
@ -763,11 +763,11 @@ Pcsx2App::Pcsx2App()
|
|||
m_UseGUI = true;
|
||||
m_NoGuiExitPrompt = true;
|
||||
|
||||
m_id_MainFrame = wxID_ANY;
|
||||
m_id_GsFrame = wxID_ANY;
|
||||
m_id_ProgramLogBox = wxID_ANY;
|
||||
m_id_Disassembler = wxID_ANY;
|
||||
m_ptr_ProgramLog = NULL;
|
||||
m_id_MainFrame = wxID_ANY;
|
||||
m_id_GsFrame = wxID_ANY;
|
||||
m_id_ProgramLogBox = wxID_ANY;
|
||||
m_id_Disassembler = wxID_ANY;
|
||||
m_ptr_ProgramLog = NULL;
|
||||
|
||||
SetAppName( L"PCSX2" );
|
||||
BuildCommandHash();
|
||||
|
|
|
@ -617,7 +617,7 @@ void Pcsx2App::HandleEvent(wxEvtHandler* handler, wxEventFunction func, wxEvent&
|
|||
#ifndef DISABLE_RECORDING
|
||||
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
|
||||
// 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
|
||||
(handler->*func)(event);
|
||||
|
|
|
@ -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
|
||||
static ConsoleLogSource* const ConLogSources[] =
|
||||
{
|
||||
|
@ -294,7 +310,7 @@ static ConsoleLogSource* const ConLogSources[] =
|
|||
NULL,
|
||||
(ConsoleLogSource*)&pxConLog_Event,
|
||||
(ConsoleLogSource*)&pxConLog_Thread,
|
||||
(ConsoleLogSource*)&SysConsole.sysoutConsole
|
||||
(ConsoleLogSource*)&SysConsole.sysoutConsole,
|
||||
NULL,
|
||||
#ifndef DISABLE_RECORDING
|
||||
(ConsoleLogSource*)&SysConsole.recordingConsole,
|
||||
|
@ -571,6 +587,10 @@ void ConsoleLogFrame::OnLoggingChanged()
|
|||
{
|
||||
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
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -132,8 +132,10 @@ GSPanel::GSPanel( wxWindow* parent )
|
|||
|
||||
#ifndef DISABLE_RECORDING
|
||||
// Retrieving FrameAdvance Key
|
||||
for (auto itr = m_Accels->begin(); itr != m_Accels->end(); ++itr) {
|
||||
if (itr->second->Id == "FrameAdvance") {
|
||||
for (auto itr = m_Accels->begin(); itr != m_Accels->end(); ++itr)
|
||||
{
|
||||
if (itr->second->Id == "FrameAdvance")
|
||||
{
|
||||
m_frameAdvanceKey = itr->first;
|
||||
break;
|
||||
}
|
||||
|
@ -377,14 +379,16 @@ void GSPanel::OnKeyDownOrUp( wxKeyEvent& evt )
|
|||
#endif
|
||||
|
||||
if ((PADopen != NULL) && CoreThread.IsOpen())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
#ifndef DISABLE_RECORDING
|
||||
if (g_Conf->EmuOptions.EnableRecordingTools)
|
||||
{
|
||||
// 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
|
||||
// circumstances and I'm unsure if there is a place to put this logic
|
||||
// circumstances
|
||||
if (evt.GetKeyCode() == m_frameAdvanceKey)
|
||||
{
|
||||
return;
|
||||
|
@ -727,23 +731,24 @@ void GSFrame::OnUpdateTitle( wxTimerEvent& evt )
|
|||
#ifndef DISABLE_RECORDING
|
||||
wxString title;
|
||||
wxString movieMode;
|
||||
switch (g_InputRecording.getModeState()) {
|
||||
case InputRecording::KEY_MOVIE_MODE::RECORD:
|
||||
movieMode = "Recording";
|
||||
title = templates.RecordingTemplate;
|
||||
break;
|
||||
case InputRecording::KEY_MOVIE_MODE::REPLAY:
|
||||
movieMode = "Replaying";
|
||||
title = templates.RecordingTemplate;
|
||||
break;
|
||||
case InputRecording::KEY_MOVIE_MODE::NONE:
|
||||
movieMode = "No movie";
|
||||
title = templates.TitleTemplate;
|
||||
break;
|
||||
switch (g_InputRecording.GetModeState())
|
||||
{
|
||||
case INPUT_RECORDING_MODE_RECORD:
|
||||
movieMode = "Recording";
|
||||
title = templates.RecordingTemplate;
|
||||
break;
|
||||
case INPUT_RECORDING_MODE_REPLAY:
|
||||
movieMode = "Replaying";
|
||||
title = templates.RecordingTemplate;
|
||||
break;
|
||||
case INPUT_RECORDING_MODE_NONE:
|
||||
movieMode = "No movie";
|
||||
title = templates.TitleTemplate;
|
||||
break;
|
||||
}
|
||||
|
||||
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);
|
||||
#else
|
||||
wxString title = templates.TitleTemplate;
|
||||
|
|
|
@ -18,10 +18,6 @@
|
|||
|
||||
#include "AppCommon.h"
|
||||
#include "CpuUsageProvider.h"
|
||||
|
||||
#include "wx/dcbuffer.h"
|
||||
#include "wx/dcgraph.h"
|
||||
|
||||
#include <memory>
|
||||
|
||||
|
||||
|
@ -59,10 +55,10 @@ public:
|
|||
GSPanel( wxWindow* parent );
|
||||
virtual ~GSPanel();
|
||||
|
||||
virtual void DoResize();
|
||||
void DoResize();
|
||||
void DoShowMouse();
|
||||
void DirectKeyCommand( wxKeyEvent& evt );
|
||||
virtual void DirectKeyCommand( const KeyAcceleratorCode& kac );
|
||||
void DirectKeyCommand( const KeyAcceleratorCode& kac );
|
||||
|
||||
protected:
|
||||
void AppStatusEvent_OnSettingsApplied();
|
||||
|
@ -83,6 +79,7 @@ protected:
|
|||
void UpdateScreensaver();
|
||||
};
|
||||
|
||||
|
||||
// --------------------------------------------------------------------------------------
|
||||
// GSFrame
|
||||
// --------------------------------------------------------------------------------------
|
||||
|
|
|
@ -467,48 +467,138 @@ namespace Implementations
|
|||
void FrameAdvance()
|
||||
{
|
||||
if (g_Conf->EmuOptions.EnableRecordingTools)
|
||||
{
|
||||
g_RecordingControls.FrameAdvance();
|
||||
}
|
||||
}
|
||||
|
||||
void TogglePause()
|
||||
{
|
||||
if (g_Conf->EmuOptions.EnableRecordingTools)
|
||||
{
|
||||
g_RecordingControls.TogglePause();
|
||||
}
|
||||
}
|
||||
|
||||
void InputRecordingModeToggle()
|
||||
{
|
||||
if (g_Conf->EmuOptions.EnableRecordingTools)
|
||||
{
|
||||
g_InputRecording.RecordModeToggle();
|
||||
}
|
||||
}
|
||||
|
||||
void States_SaveSlot(int slot)
|
||||
{
|
||||
States_SetCurrentSlot(slot);
|
||||
States_FreezeCurrentSlot();
|
||||
}
|
||||
|
||||
void States_LoadSlot(int slot)
|
||||
{
|
||||
States_SetCurrentSlot(slot);
|
||||
States_DefrostCurrentSlot();
|
||||
}
|
||||
void States_SaveSlot0() { States_SaveSlot(0); }
|
||||
void States_SaveSlot1() { States_SaveSlot(1); }
|
||||
void States_SaveSlot2() { States_SaveSlot(2); }
|
||||
void States_SaveSlot3() { States_SaveSlot(3); }
|
||||
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); }
|
||||
|
||||
void States_SaveSlot0()
|
||||
{
|
||||
States_SaveSlot(0);
|
||||
}
|
||||
|
||||
void States_SaveSlot1()
|
||||
{
|
||||
States_SaveSlot(1);
|
||||
}
|
||||
|
||||
void States_SaveSlot2()
|
||||
{
|
||||
States_SaveSlot(2);
|
||||
}
|
||||
|
||||
void States_SaveSlot3()
|
||||
{
|
||||
States_SaveSlot(3);
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
|
|
|
@ -372,7 +372,7 @@ MainEmuFrame::MainEmuFrame(wxWindow* parent, const wxString& title)
|
|||
SetMenuBar( &m_menubar );
|
||||
|
||||
#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)
|
||||
{
|
||||
m_menubar.Append(&m_menuRecording, _("&Recording"));
|
||||
|
|
|
@ -498,10 +498,12 @@ void MainEmuFrame::Menu_EnableRecordingTools_Click(wxCommandEvent&)
|
|||
{
|
||||
bool checked = GetMenuBar()->IsChecked(MenuId_EnableRecordingTools);
|
||||
// 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"
|
||||
"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;
|
||||
m_menuSys.FindChildItem(MenuId_EnableRecordingTools)->Check(false);
|
||||
}
|
||||
|
@ -515,12 +517,14 @@ void MainEmuFrame::Menu_EnableRecordingTools_Click(wxCommandEvent&)
|
|||
else
|
||||
{
|
||||
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;
|
||||
SysConsole.recordingConsole.Enabled = checked;
|
||||
ConsoleLogFrame* proglog = wxGetApp().GetProgramLog();
|
||||
proglog->UpdateLogList();
|
||||
ConsoleLogFrame* progLog = wxGetApp().GetProgramLog();
|
||||
progLog->UpdateLogList();
|
||||
AppApplySettings();
|
||||
AppSaveSettings();
|
||||
}
|
||||
|
@ -568,11 +572,11 @@ void MainEmuFrame::Menu_LoadStateFromFile_Click(wxCommandEvent &event)
|
|||
L"Savestate files (*.p2s)|*.p2s", wxFD_OPEN);
|
||||
|
||||
if (loadStateDialog.ShowModal() == wxID_CANCEL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
wxString path = loadStateDialog.GetPath();
|
||||
Console.WriteLn(path);
|
||||
|
||||
StateCopy_LoadFromFile(path);
|
||||
}
|
||||
|
||||
|
@ -582,11 +586,11 @@ void MainEmuFrame::Menu_SaveStateToFile_Click(wxCommandEvent &event)
|
|||
L"Savestate files (*.p2s)|*.p2s", wxFD_OPEN);
|
||||
|
||||
if (saveStateDialog.ShowModal() == wxID_CANCEL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
wxString path = saveStateDialog.GetPath();
|
||||
Console.WriteLn(path);
|
||||
|
||||
StateCopy_SaveToFile(path);
|
||||
}
|
||||
|
||||
|
@ -706,47 +710,70 @@ void MainEmuFrame::Menu_Capture_Video_Stop_Click(wxCommandEvent &event)
|
|||
void MainEmuFrame::VideoCaptureUpdate()
|
||||
{
|
||||
GetMTGS().WaitGS(); // make sure GS is in sync with the audio stream when we start.
|
||||
if (m_capturingVideo) {
|
||||
if (m_capturingVideo)
|
||||
{
|
||||
// start recording
|
||||
|
||||
// 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)
|
||||
bool needsMainFrameEnable = false;
|
||||
if (GetMainFramePtr() && GetMainFramePtr()->IsEnabled()) {
|
||||
if (GetMainFramePtr() && GetMainFramePtr()->IsEnabled())
|
||||
{
|
||||
needsMainFrameEnable = true;
|
||||
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.
|
||||
if (GSsetupRecording(m_capturingVideo, NULL)) {
|
||||
if (SPU2setupRecording) SPU2setupRecording(m_capturingVideo, NULL);
|
||||
if (GSsetupRecording(m_capturingVideo, NULL))
|
||||
{
|
||||
if (SPU2setupRecording)
|
||||
{
|
||||
SPU2setupRecording(m_capturingVideo, NULL);
|
||||
}
|
||||
}
|
||||
else {
|
||||
else
|
||||
{
|
||||
// recording dialog canceled by the user. align our state
|
||||
m_capturingVideo = false;
|
||||
}
|
||||
}
|
||||
else {
|
||||
else
|
||||
{
|
||||
// the GS doesn't support recording.
|
||||
if (SPU2setupRecording) SPU2setupRecording(m_capturingVideo, NULL);
|
||||
if (SPU2setupRecording)
|
||||
{
|
||||
SPU2setupRecording(m_capturingVideo, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
if (GetMainFramePtr() && needsMainFrameEnable)
|
||||
{
|
||||
GetMainFramePtr()->Enable();
|
||||
}
|
||||
|
||||
}
|
||||
else {
|
||||
else
|
||||
{
|
||||
// stop recording
|
||||
if (GSsetupRecording) GSsetupRecording(m_capturingVideo, NULL);
|
||||
if (SPU2setupRecording) SPU2setupRecording(m_capturingVideo, NULL);
|
||||
if (GSsetupRecording)
|
||||
{
|
||||
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_Stop)->Enable(true);
|
||||
}
|
||||
else {
|
||||
else
|
||||
{
|
||||
m_submenuVideoCapture.FindItem(MenuId_Capture_Video_Record)->Enable(true);
|
||||
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)
|
||||
{
|
||||
if (!CoreThread.IsOpen())
|
||||
{
|
||||
return;
|
||||
}
|
||||
GSmakeSnapshot(g_Conf->Folders.Snapshots.ToAscii());
|
||||
}
|
||||
|
||||
|
@ -772,18 +801,19 @@ void MainEmuFrame::Menu_Recording_New_Click(wxCommandEvent &event)
|
|||
return;
|
||||
}
|
||||
// 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");
|
||||
return;
|
||||
}
|
||||
g_InputRecording.Create(NewRecordingFrame->getFile(), true, NewRecordingFrame->getAuthor());
|
||||
g_InputRecording.Create(NewRecordingFrame->GetFile(), true, NewRecordingFrame->GetAuthor());
|
||||
}
|
||||
// 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);
|
||||
|
@ -795,7 +825,10 @@ void MainEmuFrame::Menu_Recording_Play_Click(wxCommandEvent &event)
|
|||
g_InputRecording.Stop();
|
||||
wxFileDialog openFileDialog(this, _("Select P2M2 record file."), L"", L"",
|
||||
L"p2m2 file(*.p2m2)|*.p2m2", wxFD_OPEN);
|
||||
if (openFileDialog.ShowModal() == wxID_CANCEL) return;
|
||||
if (openFileDialog.ShowModal() == wxID_CANCEL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
wxString path = openFileDialog.GetPath();
|
||||
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)
|
||||
{
|
||||
VirtualPad *vp;
|
||||
VirtualPad *vp = NULL;
|
||||
if (event.GetId() == MenuId_Recording_VirtualPad_Port0)
|
||||
{
|
||||
vp = wxGetApp().GetVirtualPadPtr(0);
|
||||
}
|
||||
else if (event.GetId() == MenuId_Recording_VirtualPad_Port1)
|
||||
{
|
||||
vp = wxGetApp().GetVirtualPadPtr(1);
|
||||
if (vp)
|
||||
}
|
||||
if (vp != NULL)
|
||||
{
|
||||
vp->Show();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
|
Loading…
Reference in New Issue