From c60cdbba0773f2b08e0859177821463e6a98b7c2 Mon Sep 17 00:00:00 2001 From: sonicfind <52436993+sonicfind@users.noreply.github.com> Date: Sun, 20 Sep 2020 23:26:02 -0500 Subject: [PATCH] Capture: Optimizations with filenames, audio, and capture mainFrame gui *Resulting .wavs should get saved in the same location as the video file on linux *Keep gui capture state consistent regardless of the method used to start recording *Reworked mainFrame capture menu video options to route to a single toggleCapture_click function *Split GS & SPU2 recording into start & end functions --- common/include/PS2Edefs.h | 12 ++-- pcsx2/PluginManager.cpp | 2 + pcsx2/SPU2/SndOut.h | 2 +- pcsx2/SPU2/Wavedump_wav.cpp | 17 +++--- pcsx2/SPU2/spu2.cpp | 15 +++-- pcsx2/SPU2/spu2.h | 5 +- pcsx2/gui/GlobalCommands.cpp | 39 ++++++------ pcsx2/gui/MainFrame.cpp | 5 +- pcsx2/gui/MainFrame.h | 5 +- pcsx2/gui/MainMenuClicks.cpp | 64 +++++++++----------- plugins/GSdx/GS.cpp | 41 ++++++------- plugins/GSdx/GSCapture.cpp | 31 ++++++---- plugins/GSdx/GSCapture.h | 2 +- plugins/GSdx/GSUtil.cpp | 2 +- plugins/GSdx/GSdx.def | 1 + plugins/GSdx/Renderers/Common/GSRenderer.cpp | 4 +- plugins/GSdx/Renderers/Common/GSRenderer.h | 2 +- plugins/GSdx/Window/GSCaptureDlg.cpp | 3 +- 18 files changed, 125 insertions(+), 127 deletions(-) diff --git a/common/include/PS2Edefs.h b/common/include/PS2Edefs.h index a175f72ab0..c227430894 100644 --- a/common/include/PS2Edefs.h +++ b/common/include/PS2Edefs.h @@ -133,10 +133,12 @@ void CALLBACK GSsetGameCRC(int crc, int gameoptions); // controls frame skipping in the GS, if this routine isn't present, frame skipping won't be done void CALLBACK GSsetFrameSkip(int frameskip); -// if start is 1, starts recording spu2 data, else stops +// Starts recording GS frame data // returns a non zero value if successful -// for now, pData is not used -int CALLBACK GSsetupRecording(int start, void *pData); +int CALLBACK GSsetupRecording(std::string& filename); + +// Stops recording GS frame data +void CALLBACK GSendRecording(); void CALLBACK GSreset(); //deprecated: GSgetTitleInfo was used in PCSX2 but no plugin supported it prior to r4070: @@ -183,7 +185,8 @@ typedef void(CALLBACK *_GSsetGameCRC)(int, int); typedef void(CALLBACK *_GSsetFrameSkip)(int frameskip); typedef void(CALLBACK *_GSsetVsync)(int enabled); typedef void(CALLBACK *_GSsetExclusive)(int isExclusive); -typedef std::wstring*(CALLBACK *_GSsetupRecording)(int); +typedef int(CALLBACK* _GSsetupRecording)(std::string&); +typedef void(CALLBACK* _GSendRecording)(); typedef void(CALLBACK *_GSreset)(); typedef void(CALLBACK *_GSwriteCSR)(u32 value); typedef bool(CALLBACK *_GSmakeSnapshot)(const char *path); @@ -220,6 +223,7 @@ extern _GSsetGameCRC GSsetGameCRC; extern _GSsetFrameSkip GSsetFrameSkip; extern _GSsetVsync GSsetVsync; extern _GSsetupRecording GSsetupRecording; +extern _GSendRecording GSendRecording; extern _GSreset GSreset; extern _GSwriteCSR GSwriteCSR; #endif diff --git a/pcsx2/PluginManager.cpp b/pcsx2/PluginManager.cpp index 2e30bed139..4880c04378 100644 --- a/pcsx2/PluginManager.cpp +++ b/pcsx2/PluginManager.cpp @@ -177,6 +177,7 @@ _GSsetFrameSkip GSsetFrameSkip; _GSsetVsync GSsetVsync; _GSsetExclusive GSsetExclusive; _GSsetupRecording GSsetupRecording; +_GSendRecording GSendRecording; _GSreset GSreset; _GSwriteCSR GSwriteCSR; #endif @@ -316,6 +317,7 @@ static const LegacyApi_OptMethod s_MethMessOpt_GS[] = { "GSopen2", (vMeth**)&GSopen2 }, { "GSreset", (vMeth**)&GSreset }, { "GSsetupRecording", (vMeth**)&GSsetupRecording }, + { "GSendRecording", (vMeth**)&GSendRecording }, { "GSmakeSnapshot2", (vMeth**)&GSmakeSnapshot2 }, { "GSgifSoftReset", (vMeth**)&GSgifSoftReset }, { "GSreadFIFO", (vMeth**)&GSreadFIFO }, diff --git a/pcsx2/SPU2/SndOut.h b/pcsx2/SPU2/SndOut.h index d1b5d59a2c..14db7bfd5e 100644 --- a/pcsx2/SPU2/SndOut.h +++ b/pcsx2/SPU2/SndOut.h @@ -682,7 +682,7 @@ extern SndOutModule* mods[]; extern bool WavRecordEnabled; -extern void RecordStart(std::wstring* filename); +extern int RecordStart(const std::string* filename); extern void RecordStop(); extern void RecordWrite(const StereoOut16& sample); diff --git a/pcsx2/SPU2/Wavedump_wav.cpp b/pcsx2/SPU2/Wavedump_wav.cpp index d75d5bb5f5..9bd8cdf22f 100644 --- a/pcsx2/SPU2/Wavedump_wav.cpp +++ b/pcsx2/SPU2/Wavedump_wav.cpp @@ -110,28 +110,27 @@ bool WavRecordEnabled = false; static WavOutFile* m_wavrecord = nullptr; static Mutex WavRecordMutex; -void RecordStart(std::wstring* filename) +int RecordStart(const std::string* filename) { - WavRecordEnabled = false; - try { ScopedLock lock(WavRecordMutex); safe_delete(m_wavrecord); -#ifdef _WIN32 if (filename) - m_wavrecord = new WavOutFile((*filename) + "wav", 48000, 16, 2); + m_wavrecord = new WavOutFile(filename->c_str(), 48000, 16, 2); else m_wavrecord = new WavOutFile("audio_recording.wav", 48000, 16, 2); -#elif defined(__unix__) - m_wavrecord = new WavOutFile("audio_recording.wav", 48000, 16, 2); -#endif WavRecordEnabled = true; + return 1; } catch (std::runtime_error&) { m_wavrecord = nullptr; // not needed, but what the heck. :) - SysMessage("SPU2 couldn't open file for recording: %s.\nRecording to wavfile disabled.", "audio_recording.wav"); + if (filename) + SysMessage("SPU2-X couldn't open file for recording: %s.\nWavfile capture disabled.", filename->c_str()); + else + SysMessage("SPU2-X couldn't open file for recording: audio_recording.wav.\nWavfile capture disabled."); + return 0; } } diff --git a/pcsx2/SPU2/spu2.cpp b/pcsx2/SPU2/spu2.cpp index 375c901660..6c4f69882d 100644 --- a/pcsx2/SPU2/spu2.cpp +++ b/pcsx2/SPU2/spu2.cpp @@ -578,17 +578,16 @@ void SPU2write(u32 rmem, u16 value) } } -// if start is 1, starts recording spu2 data, else stops // returns a non zero value if successful -// for now, pData is not used -int SPU2setupRecording(int start, std::wstring* filename) +int SPU2setupRecording(const std::string* filename) { - if (start == 0) - RecordStop(); - else if (start == 1) - RecordStart(filename); + return RecordStart(filename); +} - return 0; +void SPU2endRecording() +{ + if (WavRecordEnabled) + RecordStop(); } s32 SPU2freeze(int mode, freezeData* data) diff --git a/pcsx2/SPU2/spu2.h b/pcsx2/SPU2/spu2.h index 829cccbdf7..43de2fe724 100644 --- a/pcsx2/SPU2/spu2.h +++ b/pcsx2/SPU2/spu2.h @@ -31,10 +31,9 @@ void SPU2write(u32 mem, u16 value); u16 SPU2read(u32 mem); // extended funcs -// if start is 1, starts recording spu2 data, else stops // returns a non zero value if successful -// for now, pData is not used -int SPU2setupRecording(int start, std::wstring* filename); +int SPU2setupRecording(const std::string* filename); +void SPU2endRecording(); void SPU2setClockPtr(u32* ptr); diff --git a/pcsx2/gui/GlobalCommands.cpp b/pcsx2/gui/GlobalCommands.cpp index f1829ea26a..c715b49a1c 100644 --- a/pcsx2/gui/GlobalCommands.cpp +++ b/pcsx2/gui/GlobalCommands.cpp @@ -40,7 +40,7 @@ uint renderswitch_delay = 0; extern bool switchAR; -static int g_Pcsx2Recording = 0; // true 1 if recording video and sound +static bool g_Pcsx2Recording = false; // true if recording video and sound KeyAcceleratorCode::KeyAcceleratorCode(const wxKeyEvent& evt) @@ -450,9 +450,14 @@ namespace Implementations ScopedCoreThreadPause paused_core; paused_core.AllowResume(); - g_Pcsx2Recording ^= 1; + if (wxGetApp().HasGUI()) + { + sMainFrame.VideoCaptureToggle(); + return; + } GetMTGS().WaitGS(); // make sure GS is in sync with the audio stream when we start. + g_Pcsx2Recording = !g_Pcsx2Recording; if (g_Pcsx2Recording) { // start recording @@ -469,23 +474,17 @@ namespace Implementations if (GSsetupRecording) { // GSsetupRecording can be aborted/canceled by the user. Don't go on to record the audio if that happens. - std::wstring* filename = nullptr; - if (filename = GSsetupRecording(g_Pcsx2Recording)) - { - SPU2setupRecording(g_Pcsx2Recording, filename); - delete filename; - } - else - { - // recording dialog canceled by the user. align our state - g_Pcsx2Recording ^= 1; - } + std::string filename; + if (GSsetupRecording(filename)) + // Note: Add a dialog box here (or in the function) that prompts the user to answer whether a failed + // SPU2 recording setup should still lead to the visuals being recorded. + SPU2setupRecording(&filename); + else // recording dialog canceled by the user. align our state + g_Pcsx2Recording = false; } + // the GS doesn't support recording else - { - // the GS doesn't support recording - SPU2setupRecording(g_Pcsx2Recording, NULL); - } + g_Pcsx2Recording = SPU2setupRecording(nullptr); if (GetMainFramePtr() && needsMainFrameEnable) GetMainFramePtr()->Enable(); @@ -493,9 +492,9 @@ namespace Implementations else { // stop recording - if (GSsetupRecording) - GSsetupRecording(g_Pcsx2Recording); - SPU2setupRecording(g_Pcsx2Recording, NULL); + if (GSendRecording) + GSendRecording(); + SPU2endRecording(); } } diff --git a/pcsx2/gui/MainFrame.cpp b/pcsx2/gui/MainFrame.cpp index 42292612a2..0099bfd6f1 100644 --- a/pcsx2/gui/MainFrame.cpp +++ b/pcsx2/gui/MainFrame.cpp @@ -289,8 +289,8 @@ void MainEmuFrame::ConnectMenus() Bind(wxEVT_MENU, &MainEmuFrame::Menu_Debug_Open_Click, this, MenuId_Debug_Open); // Capture - Bind(wxEVT_MENU, &MainEmuFrame::Menu_Capture_Video_Record_Click, this, MenuId_Capture_Video_Record); - Bind(wxEVT_MENU, &MainEmuFrame::Menu_Capture_Video_Stop_Click, this, MenuId_Capture_Video_Stop); + Bind(wxEVT_MENU, &MainEmuFrame::Menu_Capture_Video_ToggleCapture_Click, this, MenuId_Capture_Video_Record); + Bind(wxEVT_MENU, &MainEmuFrame::Menu_Capture_Video_ToggleCapture_Click, this, MenuId_Capture_Video_Stop); Bind(wxEVT_MENU, &MainEmuFrame::Menu_Capture_Screenshot_Screenshot_Click, this, MenuId_Capture_Screenshot_Screenshot); Bind(wxEVT_MENU, &MainEmuFrame::Menu_Capture_Screenshot_Screenshot_As_Click, this, MenuId_Capture_Screenshot_Screenshot_As); @@ -573,6 +573,7 @@ MainEmuFrame::MainEmuFrame(wxWindow* parent, const wxString& title) { m_RestartEmuOnDelete = false; + m_capturingVideo = false; for (int i = 0; i < PluginId_Count; ++i) m_PluginMenuPacks[i].Populate((PluginsEnum_t)i); diff --git a/pcsx2/gui/MainFrame.h b/pcsx2/gui/MainFrame.h index 796793e747..ef4a481e56 100644 --- a/pcsx2/gui/MainFrame.h +++ b/pcsx2/gui/MainFrame.h @@ -172,6 +172,7 @@ public: void CommitPreset_noTrigger(); void AppendShortcutToMenuOption(wxMenuItem& item, wxString keyCodeStr); void UpdateStatusBar(); + void VideoCaptureToggle(); #ifndef DISABLE_RECORDING void initializeRecordingMenuItem(MenuIdentifiers menuId, wxString keyCodeStr, bool enable = true); void enableRecordingMenuItem(MenuIdentifiers menuId, bool enable); @@ -252,9 +253,7 @@ protected: void Menu_Wiki(wxCommandEvent& event); void Menu_ShowAboutBox(wxCommandEvent& event); - void Menu_Capture_Video_Record_Click(wxCommandEvent& event); - void Menu_Capture_Video_Stop_Click(wxCommandEvent& event); - void VideoCaptureUpdate(); + void Menu_Capture_Video_ToggleCapture_Click(wxCommandEvent& event); void Menu_Capture_Screenshot_Screenshot_Click(wxCommandEvent& event); void Menu_Capture_Screenshot_Screenshot_As_Click(wxCommandEvent& event); diff --git a/pcsx2/gui/MainMenuClicks.cpp b/pcsx2/gui/MainMenuClicks.cpp index 903b8d9935..70067d6441 100644 --- a/pcsx2/gui/MainMenuClicks.cpp +++ b/pcsx2/gui/MainMenuClicks.cpp @@ -848,27 +848,17 @@ void MainEmuFrame::Menu_ShowAboutBox(wxCommandEvent& event) AppOpenDialog(this); } -void MainEmuFrame::Menu_Capture_Video_Record_Click(wxCommandEvent& event) +void MainEmuFrame::Menu_Capture_Video_ToggleCapture_Click(wxCommandEvent& event) { ScopedCoreThreadPause paused_core; paused_core.AllowResume(); - - m_capturingVideo = true; - VideoCaptureUpdate(); + VideoCaptureToggle(); } -void MainEmuFrame::Menu_Capture_Video_Stop_Click(wxCommandEvent& event) -{ - ScopedCoreThreadPause paused_core; - paused_core.AllowResume(); - - m_capturingVideo = false; - VideoCaptureUpdate(); -} - -void MainEmuFrame::VideoCaptureUpdate() +void MainEmuFrame::VideoCaptureToggle() { GetMTGS().WaitGS(); // make sure GS is in sync with the audio stream when we start. + m_capturingVideo = !m_capturingVideo; if (m_capturingVideo) { // start recording @@ -876,20 +866,23 @@ void MainEmuFrame::VideoCaptureUpdate() // 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 (IsEnabled()) { needsMainFrameEnable = true; - GetMainFramePtr()->Disable(); + Disable(); } if (GSsetupRecording) { // GSsetupRecording can be aborted/canceled by the user. Don't go on to record the audio if that happens - std::wstring* filename = nullptr; - if (filename = GSsetupRecording(m_capturingVideo)) + std::string filename; + if (GSsetupRecording(filename)) { - SPU2setupRecording(m_capturingVideo, filename); - delete filename; + // Note: Add a dialog box here (or in the function) that prompts the user to answer whether a failed + // SPU2 recording setup should still lead to the visuals being recorded. + SPU2setupRecording(&filename); + m_submenuVideoCapture.Enable(MenuId_Capture_Video_Record, false); + m_submenuVideoCapture.Enable(MenuId_Capture_Video_Stop, true); } else { @@ -900,29 +893,26 @@ void MainEmuFrame::VideoCaptureUpdate() else { // the GS doesn't support recording. - SPU2setupRecording(m_capturingVideo, nullptr); + if (SPU2setupRecording(nullptr)) + { + m_submenuVideoCapture.Enable(MenuId_Capture_Video_Record, false); + m_submenuVideoCapture.Enable(MenuId_Capture_Video_Stop, true); + } + else + m_capturingVideo = false; } - if (GetMainFramePtr() && needsMainFrameEnable) - GetMainFramePtr()->Enable(); + if (needsMainFrameEnable) + Enable(); } else { // stop recording - if (GSsetupRecording) - GSsetupRecording(m_capturingVideo); - SPU2setupRecording(m_capturingVideo, nullptr); - } - - if (m_capturingVideo) - { - m_submenuVideoCapture.FindItem(MenuId_Capture_Video_Record)->Enable(false); - m_submenuVideoCapture.FindItem(MenuId_Capture_Video_Stop)->Enable(true); - } - else - { - m_submenuVideoCapture.FindItem(MenuId_Capture_Video_Record)->Enable(true); - m_submenuVideoCapture.FindItem(MenuId_Capture_Video_Stop)->Enable(false); + if (GSendRecording) + GSendRecording(); + SPU2endRecording(); + m_submenuVideoCapture.Enable(MenuId_Capture_Video_Record, true); + m_submenuVideoCapture.Enable(MenuId_Capture_Video_Stop, false); } } diff --git a/plugins/GSdx/GS.cpp b/plugins/GSdx/GS.cpp index c8c9b239d0..4396d6a53e 100644 --- a/plugins/GSdx/GS.cpp +++ b/plugins/GSdx/GS.cpp @@ -677,7 +677,11 @@ EXPORT_C_(uint32) GSmakeSnapshot(char* path) { // Allows for providing a complete path std::string extension = s.substr(s.size() - 4, 4); - std::transform(extension.begin(), extension.end(), extension.begin(), tolower); +#ifdef _WIN32 + std::transform(extension.begin(), extension.end(), extension.begin(), (char(_cdecl*)(int))tolower); +#else + std::transform(extension.begin(), extension.end(), extension.begin(), tolower); +#endif if (extension == ".png") return s_gs->MakeSnapshot(s); else if (s[s.length() - 1] != DIRECTORY_SEPARATOR) @@ -807,41 +811,36 @@ void pt(const char* str){ printf("%02i:%02i:%02i%s", current->tm_hour, current->tm_min, current->tm_sec, str); } -EXPORT_C_(std::wstring*) GSsetupRecording(int start) +EXPORT_C_(int) GSsetupRecording(std::string& filename) { if (s_gs == NULL) { printf("GSdx: no s_gs for recording\n"); - return nullptr; + return 0; } #if defined(__unix__) || defined(__APPLE__) if (!theApp.GetConfigB("capture_enabled")) { printf("GSdx: Recording is disabled\n"); - return nullptr; + return 0; } #endif - std::wstring* filename = nullptr; - if(start & 1) + printf("GSdx: Recording start command\n"); + if (s_gs->BeginCapture(filename)) { - printf("GSdx: Recording start command\n"); - filename = s_gs->BeginCapture(); - if (filename) - { - pt(" - Capture started\n"); - } - else - { - pt(" - Capture cancelled\n"); - return nullptr; - } + pt(" - Capture started\n"); + return 1; } else { - printf("GSdx: Recording end command\n"); - s_gs->EndCapture(); - pt(" - Capture ended\n"); + pt(" - Capture cancelled\n"); + return 0; } +} - return filename; +EXPORT_C_(void) GSendRecording() +{ + printf("GSdx: Recording end command\n"); + s_gs->EndCapture(); + pt(" - Capture ended\n"); } EXPORT_C GSsetGameCRC(uint32 crc, int options) diff --git a/plugins/GSdx/GSCapture.cpp b/plugins/GSdx/GSCapture.cpp index a10ece3f93..1b7ede5b7a 100644 --- a/plugins/GSdx/GSCapture.cpp +++ b/plugins/GSdx/GSCapture.cpp @@ -404,7 +404,7 @@ GSCapture::~GSCapture() EndCapture(); } -std::wstring* GSCapture::BeginCapture(float fps, GSVector2i recommendedResolution, float aspect) +int GSCapture::BeginCapture(float fps, GSVector2i recommendedResolution, float aspect, std::string& filename) { printf("Recommended resolution: %d x %d, DAR for muxing: %.4f\n", recommendedResolution.x, recommendedResolution.y, aspect); std::lock_guard lock(m_lock); @@ -418,10 +418,10 @@ std::wstring* GSCapture::BeginCapture(float fps, GSVector2i recommendedResolutio GSCaptureDlg dlg; if (IDOK != dlg.DoModal()) - return nullptr; + return 0; { - int start = dlg.m_filename.length() - 4; + const int start = dlg.m_filename.length() - 4; if (start > 0) { std::string test = dlg.m_filename.substr(start); @@ -438,11 +438,11 @@ std::wstring* GSCapture::BeginCapture(float fps, GSVector2i recommendedResolutio else { dlg.InvalidFile(); - return nullptr; + return 0; } } - std::wstring fn{dlg.m_filename.begin(), dlg.m_filename.end()}; + ; m_size.x = (dlg.m_width + 7) & ~7; m_size.y = (dlg.m_height + 7) & ~7; @@ -456,9 +456,9 @@ std::wstring* GSCapture::BeginCapture(float fps, GSVector2i recommendedResolutio if(FAILED(hr = m_graph.CoCreateInstance(CLSID_FilterGraph)) || FAILED(hr = cgb.CoCreateInstance(CLSID_CaptureGraphBuilder2)) || FAILED(hr = cgb->SetFiltergraph(m_graph)) - || FAILED(hr = cgb->SetOutputFileName(&MEDIASUBTYPE_Avi, fn.c_str(), &mux, NULL))) + || FAILED(hr = cgb->SetOutputFileName(&MEDIASUBTYPE_Avi, std::wstring(dlg.m_filename.begin(), dlg.m_filename.end()).c_str(), &mux, NULL))) { - return nullptr; + return 0; } m_src = new GSSource(m_size.x, m_size.y, fps, NULL, hr, dlg.m_colorspace); @@ -466,22 +466,22 @@ std::wstring* GSCapture::BeginCapture(float fps, GSVector2i recommendedResolutio if (dlg.m_enc==0) { if (FAILED(hr = m_graph->AddFilter(m_src, L"Source"))) - return nullptr; + return 0; if (FAILED(hr = m_graph->ConnectDirect(GetFirstPin(m_src, PINDIR_OUTPUT), GetFirstPin(mux, PINDIR_INPUT), NULL))) - return nullptr; + return 0; } else { if(FAILED(hr = m_graph->AddFilter(m_src, L"Source")) || FAILED(hr = m_graph->AddFilter(dlg.m_enc, L"Encoder"))) { - return nullptr; + return 0; } if(FAILED(hr = m_graph->ConnectDirect(GetFirstPin(m_src, PINDIR_OUTPUT), GetFirstPin(dlg.m_enc, PINDIR_INPUT), NULL)) || FAILED(hr = m_graph->ConnectDirect(GetFirstPin(dlg.m_enc, PINDIR_OUTPUT), GetFirstPin(mux, PINDIR_INPUT), NULL))) { - return nullptr; + return 0; } } @@ -509,7 +509,8 @@ std::wstring* GSCapture::BeginCapture(float fps, GSVector2i recommendedResolutio CComQIPtr(m_src)->DeliverNewSegment(); m_capturing = true; - return new std::wstring(dlg.m_filename.begin(), dlg.m_filename.end() - 3); + filename = dlg.m_filename.erase(dlg.m_filename.length() - 3, 3) + "wav"; + return 1; #elif defined(__unix__) // Note I think it doesn't support multiple depth creation GSmkdir(m_out_dir.c_str()); @@ -525,7 +526,8 @@ std::wstring* GSCapture::BeginCapture(float fps, GSVector2i recommendedResolutio } m_capturing = true; - return new std::wstring(); + filename = m_out_dir + "/audio_recording.wav"; + return 1; #endif } @@ -564,6 +566,9 @@ bool GSCapture::DeliverFrame(const void* bits, int pitch, bool rgba) bool GSCapture::EndCapture() { + if (!m_capturing) + return false; + std::lock_guard lock(m_lock); #ifdef _WIN32 diff --git a/plugins/GSdx/GSCapture.h b/plugins/GSdx/GSCapture.h index 4fd4c1fdd5..e12087636e 100644 --- a/plugins/GSdx/GSCapture.h +++ b/plugins/GSdx/GSCapture.h @@ -53,7 +53,7 @@ public: GSCapture(); virtual ~GSCapture(); - std::wstring* BeginCapture(float fps, GSVector2i recommendedResolution, float aspect); + int BeginCapture(float fps, GSVector2i recommendedResolution, float aspect, std::string& filename); bool DeliverFrame(const void* bits, int pitch, bool rgba); bool EndCapture(); diff --git a/plugins/GSdx/GSUtil.cpp b/plugins/GSdx/GSUtil.cpp index d8ff463132..b5f0f06d2c 100644 --- a/plugins/GSdx/GSUtil.cpp +++ b/plugins/GSdx/GSUtil.cpp @@ -336,7 +336,7 @@ void GSmkdir(const wchar_t* dir) if (!CreateDirectory(dir, nullptr)) { DWORD errorID = ::GetLastError(); if (errorID != ERROR_ALREADY_EXISTS) { - fprintf(stderr, "Failed to create directory: %s error %u\n", dir, errorID); + fprintf(stderr, "Failed to create directory: %ls error %u\n", dir, errorID); } } #else diff --git a/plugins/GSdx/GSdx.def b/plugins/GSdx/GSdx.def index 8c43f0ca67..2d20602b2b 100644 --- a/plugins/GSdx/GSdx.def +++ b/plugins/GSdx/GSdx.def @@ -34,6 +34,7 @@ EXPORTS GSreadFIFO2 GSirqCallback GSsetupRecording + GSendRecording GSsetGameCRC GSsetFrameSkip GSsetVsync diff --git a/plugins/GSdx/Renderers/Common/GSRenderer.cpp b/plugins/GSdx/Renderers/Common/GSRenderer.cpp index bfdd83bbad..d87030781e 100644 --- a/plugins/GSdx/Renderers/Common/GSRenderer.cpp +++ b/plugins/GSdx/Renderers/Common/GSRenderer.cpp @@ -533,12 +533,12 @@ bool GSRenderer::MakeSnapshot(const std::string& path) return true; } -std::wstring* GSRenderer::BeginCapture() +int GSRenderer::BeginCapture(std::string& filename) { GSVector4i disp = m_wnd->GetClientRect().fit(m_aspectratio); float aspect = (float)disp.width() / std::max(1, disp.height()); - return m_capture.BeginCapture(GetTvRefreshRate(), GetInternalResolution(), aspect); + return m_capture.BeginCapture(GetTvRefreshRate(), GetInternalResolution(), aspect, filename); } void GSRenderer::EndCapture() diff --git a/plugins/GSdx/Renderers/Common/GSRenderer.h b/plugins/GSdx/Renderers/Common/GSRenderer.h index f64bd987aa..98f4afc01c 100644 --- a/plugins/GSdx/Renderers/Common/GSRenderer.h +++ b/plugins/GSdx/Renderers/Common/GSRenderer.h @@ -72,7 +72,7 @@ public: void SetAspectRatio(int aspect) {m_aspectratio = aspect;} void SetVSync(int vsync); - virtual std::wstring* BeginCapture(); + virtual int BeginCapture(std::string& filename); virtual void EndCapture(); void PurgePool(); diff --git a/plugins/GSdx/Window/GSCaptureDlg.cpp b/plugins/GSdx/Window/GSCaptureDlg.cpp index d17495defa..af81899b71 100644 --- a/plugins/GSdx/Window/GSCaptureDlg.cpp +++ b/plugins/GSdx/Window/GSCaptureDlg.cpp @@ -40,7 +40,8 @@ void GSCaptureDlg::InvalidFile() { wchar_t tmp[512]; - swprintf_s(tmp, L"GSdx couldn't open file for capturing: %s.\nCapture aborted.", m_filename.c_str()); + std::wstring tmpstr(m_filename.begin(), m_filename.end()); + swprintf_s(tmp, L"GSdx couldn't open file for capturing: %ls.\nCapture aborted.", tmpstr.c_str()); MessageBox(GetActiveWindow(), tmp, L"GSdx System Message", MB_OK | MB_SETFOREGROUND); }