Resolve Recording Issues for Linux / OnePad users (#3293)

* git: Ignore uncaught linux build artifacts

* onepad-legacy: Return legitimate key event on `PADkeyEvent` call

Onepad-legacy was the plugin that was building and being used on my linux environment.  I'm not sure if t hat's expected and normal 'onepad' has yet to take over.

* onepad: Return legitimate key event on `PADkeyEvent` call

* recording: Remove unnecessary `PadKeyDispatch(ev)` wrapping func

* recording: Cleanup key event handling when GSFrame CoreThread is paused

* recording: Refactor recording status check to be more explicit

* recording: Define additional key bindings for capitalized varient

Despite the advice of the docstrings in these files, on linux this seems to be required for the bindings to consistently fire.

* onepad: Declare `AnalyzeKeyEvent` not static

* recording: Ensure file extension is appended to recording file on linux

* recording: Correct typo in comment

* recording: Better wording around linux keybinding handling

* Remove unneeded `extern`
This commit is contained in:
Tyler Wilding 2020-07-25 20:58:50 -04:00 committed by GitHub
parent aee23929dc
commit ef96e050f9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
13 changed files with 76 additions and 29 deletions

5
.gitignore vendored
View File

@ -39,6 +39,8 @@ pcsx2.snapshot_*
svnrev.h svnrev.h
/build /build
/build_dev
/build_dbg
/obj-* /obj-*
.DS_Store .DS_Store
@ -47,6 +49,8 @@ Thumbs.db
Debug.txt Debug.txt
install_log.txt install_log.txt
padLog.txt padLog.txt
GSdx_opengl_debug_hw.txt
GSdx_opengl_debug_sw.txt
Debug Debug
Release Release
@ -70,6 +74,7 @@ oprofile_data/
/bin/**/*.lib /bin/**/*.lib
/bin/**/*.pdb /bin/**/*.pdb
/bin/PCSX2 /bin/PCSX2
/bin/PCSX2-linux.sh
/bin/*ReplayLoader /bin/*ReplayLoader
/bin/PCSX2-linux.sh /bin/PCSX2-linux.sh
/bin/GSdx*.txt /bin/GSdx*.txt

View File

@ -48,6 +48,14 @@ public:
return m_queue.size(); return m_queue.size();
} }
T dequeue()
{
std::lock_guard<std::mutex> guard(m_mtx);
T item = m_queue.front();
m_queue.pop();
return item;
}
template <typename F> template <typename F>
void consume_all(F f) void consume_all(F f)
{ {

View File

@ -1,5 +1,5 @@
/* PCSX2 - PS2 Emulator for PCs /* PCSX2 - PS2 Emulator for PCs
* Copyright (C) 2002-2019 PCSX2 Dev Team * Copyright (C) 2002-2020 PCSX2 Dev Team
* *
* PCSX2 is free software: you can redistribute it and/or modify it under the terms * 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- * of the GNU Lesser General Public License as published by the Free Software Found-
@ -62,7 +62,13 @@ NewRecordingFrame::NewRecordingFrame(wxWindow *parent)
wxString NewRecordingFrame::GetFile() const wxString NewRecordingFrame::GetFile() const
{ {
return m_filePicker->GetPath(); wxString path = m_filePicker->GetPath();
// wxWidget's removes the extension if it contains wildcards
// on wxGTK https://trac.wxwidgets.org/ticket/15285
if (!path.EndsWith(".p2m2")) {
return wxString::Format("%s.p2m2", path);
}
return path;
} }
wxString NewRecordingFrame::GetAuthor() const wxString NewRecordingFrame::GetAuthor() const

View File

@ -1,5 +1,5 @@
/* PCSX2 - PS2 Emulator for PCs /* PCSX2 - PS2 Emulator for PCs
* Copyright (C) 2002-2019 PCSX2 Dev Team * Copyright (C) 2002-2020 PCSX2 Dev Team
* *
* PCSX2 is free software: you can redistribute it and/or modify it under the terms * 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- * of the GNU Lesser General Public License as published by the Free Software Found-
@ -17,6 +17,7 @@
#include "App.h" #include "App.h"
#include "Counters.h" #include "Counters.h"
#include "Common.h"
#include "GSFrame.h" #include "GSFrame.h"
#include "MemoryTypes.h" #include "MemoryTypes.h"
@ -27,11 +28,13 @@
RecordingControls g_RecordingControls; RecordingControls g_RecordingControls;
//----------------------------------------------- //-----------------------------------------------
// Status on whether or not the current recording is stopped // Current recording status, returns true if:
// - Recording is Paused
// - GSFrame CoreThread is both running AND paused
//----------------------------------------------- //-----------------------------------------------
bool RecordingControls::HasRecordingStopped() bool RecordingControls::IsEmulationAndRecordingPaused()
{ {
return (fPauseState && CoreThread.IsOpen() && CoreThread.IsPaused()); return fPauseState && CoreThread.IsOpen() && CoreThread.IsPaused();
} }
//----------------------------------------------- //-----------------------------------------------

View File

@ -1,5 +1,5 @@
/* PCSX2 - PS2 Emulator for PCs /* PCSX2 - PS2 Emulator for PCs
* Copyright (C) 2002-2019 PCSX2 Dev Team * Copyright (C) 2002-2020 PCSX2 Dev Team
* *
* PCSX2 is free software: you can redistribute it and/or modify it under the terms * 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- * of the GNU Lesser General Public License as published by the Free Software Found-
@ -21,7 +21,7 @@ class RecordingControls
public: public:
// Movie controls main functions // Movie controls main functions
bool HasRecordingStopped(); bool IsEmulationAndRecordingPaused();
void ResumeCoreThreadIfStarted(); void ResumeCoreThreadIfStarted();
void HandleFrameAdvanceAndStop(); void HandleFrameAdvanceAndStop();

View File

@ -664,11 +664,6 @@ protected:
void OpenWizardConsole(); void OpenWizardConsole();
void PadKeyDispatch( const keyEvent& ev ); void PadKeyDispatch( const keyEvent& ev );
#ifndef DISABLE_RECORDING
public:
void Recording_PadKeyDispatch(const keyEvent& ev) { PadKeyDispatch(ev); }
#endif
protected: protected:
void HandleEvent(wxEvtHandler* handler, wxEventFunction func, wxEvent& event) const; void HandleEvent(wxEvtHandler* handler, wxEventFunction func, wxEvent& event) const;
void HandleEvent(wxEvtHandler* handler, wxEventFunction func, wxEvent& event); void HandleEvent(wxEvtHandler* handler, wxEventFunction func, wxEvent& event);

View File

@ -620,17 +620,16 @@ 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.HasRecordingStopped()) if (g_RecordingControls.IsEmulationAndRecordingPaused())
{ {
// While stopping, GSFrame key event also stops, so get key input from here // When the GSFrame CoreThread is paused, so is the logical VSync
// Along with that, you can not use the shortcut keys set in GSFrame // Meaning that we have to grab the user-input through here to potentially
if (PADkeyEvent != NULL) // resume emulation.
if (const keyEvent* ev = PADkeyEvent() )
{ {
// Acquire key information, possibly calling it only once per frame if( ev->key != 0 )
const keyEvent* ev = PADkeyEvent();
if (ev != NULL)
{ {
sApp.Recording_PadKeyDispatch(*ev); PadKeyDispatch( *ev );
} }
} }
} }

View File

@ -102,6 +102,12 @@ void GSPanel::InitRecordingAccelerators()
m_Accels->Map(AAC(WXK_SPACE), "FrameAdvance"); m_Accels->Map(AAC(WXK_SPACE), "FrameAdvance");
m_Accels->Map(AAC(wxKeyCode('p')).Shift(), "TogglePause"); m_Accels->Map(AAC(wxKeyCode('p')).Shift(), "TogglePause");
m_Accels->Map(AAC(wxKeyCode('r')).Shift(), "InputRecordingModeToggle"); m_Accels->Map(AAC(wxKeyCode('r')).Shift(), "InputRecordingModeToggle");
#if defined(__unix__)
// Shift+P (80) and Shift+p (112) have two completely different codes
// On Linux the former is sometimes fired so define bindings for both
m_Accels->Map(AAC(wxKeyCode('P')).Shift(), "TogglePause");
m_Accels->Map(AAC(wxKeyCode('R')).Shift(), "InputRecordingModeToggle");
#endif
m_Accels->Map(AAC(WXK_NUMPAD0).Shift(), "States_SaveSlot0"); m_Accels->Map(AAC(WXK_NUMPAD0).Shift(), "States_SaveSlot0");
m_Accels->Map(AAC(WXK_NUMPAD1).Shift(), "States_SaveSlot1"); m_Accels->Map(AAC(WXK_NUMPAD1).Shift(), "States_SaveSlot1");
@ -123,6 +129,8 @@ void GSPanel::InitRecordingAccelerators()
m_Accels->Map(AAC(WXK_NUMPAD7), "States_LoadSlot7"); m_Accels->Map(AAC(WXK_NUMPAD7), "States_LoadSlot7");
m_Accels->Map(AAC(WXK_NUMPAD8), "States_LoadSlot8"); m_Accels->Map(AAC(WXK_NUMPAD8), "States_LoadSlot8");
m_Accels->Map(AAC(WXK_NUMPAD9), "States_LoadSlot9"); m_Accels->Map(AAC(WXK_NUMPAD9), "States_LoadSlot9");
recordingConLog(L"Initialized Recording Key Bindings\n");
} }
#endif #endif

View File

@ -117,7 +117,7 @@ static bool s_Shift = false;
static unsigned int s_previous_mouse_x = 0; static unsigned int s_previous_mouse_x = 0;
static unsigned int s_previous_mouse_y = 0; static unsigned int s_previous_mouse_y = 0;
static void AnalyzeKeyEvent(keyEvent &evt) void AnalyzeKeyEvent(keyEvent &evt)
{ {
KeySym key = (KeySym)evt.key; KeySym key = (KeySym)evt.key;
int pad = 0; int pad = 0;

View File

@ -26,6 +26,7 @@
#if defined(__unix__) || defined(__APPLE__) #if defined(__unix__) || defined(__APPLE__)
extern void AnalyzeKeyEvent(keyEvent &evt);
extern void UpdateKeyboardInput(); extern void UpdateKeyboardInput();
extern bool PollForNewKeyboardKeys(u32 &pkey); extern bool PollForNewKeyboardKeys(u32 &pkey);
#ifndef __APPLE__ #ifndef __APPLE__

View File

@ -25,6 +25,7 @@
#include <string.h> #include <string.h>
#include <stdarg.h> #include <stdarg.h>
#include "keyboard.h"
#include "onepad.h" #include "onepad.h"
#include "svnrev.h" #include "svnrev.h"
#include "state_management.h" #include "state_management.h"
@ -332,17 +333,26 @@ PADkeyEvent()
} }
} }
#endif #endif
if (g_ev_fifo.size() == 0) {
// PAD_LOG("No events in queue, returning empty event\n");
s_event = event; s_event = event;
event.evt = 0; event.evt = 0;
event.key = 0; event.key = 0;
return &s_event; return &s_event;
}
s_event = g_ev_fifo.dequeue();
AnalyzeKeyEvent(s_event);
// PAD_LOG("Returning Event. Event Type: %d, Key: %d\n", s_event.evt, s_event.key);
return &s_event;
} }
#if defined(__unix__) #if defined(__unix__)
EXPORT_C_(void) EXPORT_C_(void)
PADWriteEvent(keyEvent &evt) PADWriteEvent(keyEvent &evt)
{ {
// if (evt.evt != 6) { // Skip mouse move events for logging
// PAD_LOG("Pushing Event. Event Type: %d, Key: %d\n", evt.evt, evt.key);
// }
g_ev_fifo.push(evt); g_ev_fifo.push(evt);
} }
#endif #endif

View File

@ -29,6 +29,7 @@
#include "Linux/linux.h" #include "Linux/linux.h"
extern Display *GSdsp; extern Display *GSdsp;
extern void AnalyzeKeyEvent(keyEvent &evt);
extern void PollForX11KeyboardInput(); extern void PollForX11KeyboardInput();
extern bool PollX11KeyboardMouseEvent(u32 &pkey); extern bool PollX11KeyboardMouseEvent(u32 &pkey);
extern Window GSwin; extern Window GSwin;

View File

@ -25,6 +25,7 @@
#include <string.h> #include <string.h>
#include <stdarg.h> #include <stdarg.h>
#include "keyboard.h"
#include "onepad.h" #include "onepad.h"
#include "svnrev.h" #include "svnrev.h"
#include "state_management.h" #include "state_management.h"
@ -329,15 +330,25 @@ EXPORT_C_(u8) PADpoll(u8 value)
// PADkeyEvent is called every vsync (return NULL if no event) // PADkeyEvent is called every vsync (return NULL if no event)
EXPORT_C_(keyEvent *) PADkeyEvent() EXPORT_C_(keyEvent *) PADkeyEvent()
{ {
if (g_ev_fifo.size() == 0) {
// PAD_LOG("No events in queue, returning empty event\n");
s_event = event; s_event = event;
event.evt = 0; event.evt = 0;
event.key = 0; event.key = 0;
return &s_event; return &s_event;
}
s_event = g_ev_fifo.dequeue();
AnalyzeKeyEvent(s_event);
// PAD_LOG("Returning Event. Event Type: %d, Key: %d\n", s_event.evt, s_event.key);
return &s_event;
} }
#if defined(__unix__) #if defined(__unix__)
EXPORT_C_(void) PADWriteEvent(keyEvent &evt) EXPORT_C_(void) PADWriteEvent(keyEvent &evt)
{ {
// if (evt.evt != 6) { // Skip mouse move events for logging
// PAD_LOG("Pushing Event. Event Type: %d, Key: %d\n", evt.evt, evt.key);
// }
g_ev_fifo.push(evt); g_ev_fifo.push(evt);
} }
#endif #endif