mirror of
https://github.com/PCSX2/pcsx2.git
synced 2026-01-31 01:15:24 +01:00
1165 lines
32 KiB
C++
1165 lines
32 KiB
C++
/* PCSX2 - PS2 Emulator for PCs
|
|
* Copyright (C) 2002-2021 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 "App.h"
|
|
#include "CDVD/CDVD.h"
|
|
#include "GS.h"
|
|
#include "GSFrame.h"
|
|
#include "SPU2/spu2.h"
|
|
#include "System/SysThreads.h"
|
|
#include "DEV9/DEV9.h"
|
|
#include "USB/USB.h"
|
|
#ifdef _WIN32
|
|
#include "PAD/Windows/PAD.h"
|
|
#else
|
|
#include "PAD/Linux/PAD.h"
|
|
#endif
|
|
|
|
#include "ConsoleLogger.h"
|
|
#include "MainFrame.h"
|
|
#include "IsoDropTarget.h"
|
|
|
|
#include "Dialogs/ModalPopups.h"
|
|
#include "Dialogs/ConfigurationDialog.h"
|
|
#include "Debugger/DisassemblyDialog.h"
|
|
|
|
#include "common/IniInterface.h"
|
|
|
|
#include "fmt/core.h"
|
|
#include "wx/numdlg.h"
|
|
|
|
#ifndef DISABLE_RECORDING
|
|
#include "Recording/InputRecording.h"
|
|
#include "Recording/InputRecordingControls.h"
|
|
#include "Recording/VirtualPad/VirtualPad.h"
|
|
#endif
|
|
|
|
|
|
using namespace Dialogs;
|
|
|
|
extern std::atomic_bool init_gspanel;
|
|
|
|
void MainEmuFrame::Menu_SysSettings_Click(wxCommandEvent& event)
|
|
{
|
|
AppOpenModalDialog<SysConfigDialog>(wxEmptyString, this);
|
|
}
|
|
|
|
void MainEmuFrame::Menu_IPC_Settings_Click(wxCommandEvent& event)
|
|
{
|
|
AppOpenDialog<IPCDialog>(this);
|
|
}
|
|
|
|
void MainEmuFrame::Menu_AudioSettings_Click(wxCommandEvent& event)
|
|
{
|
|
SPU2configure();
|
|
}
|
|
|
|
void MainEmuFrame::Menu_McdSettings_Click(wxCommandEvent& event)
|
|
{
|
|
ScopedCoreThreadClose closed_core;
|
|
closed_core.AllowResume();
|
|
AppOpenModalDialog<McdConfigDialog>(wxEmptyString, this);
|
|
}
|
|
|
|
void MainEmuFrame::Menu_NetworkSettings_Click(wxCommandEvent& event)
|
|
{
|
|
DEV9configure();
|
|
}
|
|
|
|
void MainEmuFrame::Menu_USBSettings_Click(wxCommandEvent& event)
|
|
{
|
|
USBconfigure();
|
|
}
|
|
|
|
void MainEmuFrame::Menu_PADSettings_Click(wxCommandEvent& event)
|
|
{
|
|
PADconfigure();
|
|
}
|
|
|
|
void MainEmuFrame::Menu_GSSettings_Click(wxCommandEvent& event)
|
|
{
|
|
ScopedCoreThreadPause paused_core;
|
|
bool is_frame_init = !(wxGetApp().GetGsFramePtr() == nullptr);
|
|
bool need_shutdown = GetMTGS().IsClosed();
|
|
init_gspanel = false;
|
|
freezeData fP = {0, nullptr};
|
|
MTGS_FreezeData sstate = {&fP, 0};
|
|
if (is_frame_init)
|
|
{
|
|
GetMTGS().Freeze(FreezeAction::Size, sstate);
|
|
fP.data = new u8[fP.size];
|
|
GetMTGS().Freeze(FreezeAction::Save, sstate);
|
|
GetMTGS().Suspend(true);
|
|
}
|
|
GSconfigure();
|
|
if (is_frame_init)
|
|
{
|
|
GetMTGS().Freeze(FreezeAction::Load, sstate);
|
|
delete[] fP.data;
|
|
}
|
|
if (need_shutdown)
|
|
GetMTGS().Suspend(true);
|
|
init_gspanel = true;
|
|
paused_core.AllowResume();
|
|
}
|
|
|
|
void MainEmuFrame::Menu_WindowSettings_Click(wxCommandEvent& event)
|
|
{
|
|
wxCommandEvent evt(pxEvt_SetSettingsPage);
|
|
evt.SetString(L"GS Window");
|
|
AppOpenDialog<SysConfigDialog>(this)->GetEventHandler()->ProcessEvent(evt);
|
|
}
|
|
|
|
void MainEmuFrame::Menu_SelectBios_Click(wxCommandEvent& event)
|
|
{
|
|
AppOpenDialog<SysConfigDialog>(this);
|
|
}
|
|
|
|
void MainEmuFrame::Menu_ChangeLang(wxCommandEvent& event) // Always in English
|
|
{
|
|
AppOpenDialog<InterfaceLanguageDialog>(this);
|
|
}
|
|
|
|
static void WipeSettings()
|
|
{
|
|
wxGetApp().CleanupRestartable();
|
|
wxGetApp().CleanupResources();
|
|
|
|
wxRemoveFile(GetUiSettingsFilename());
|
|
wxRemoveFile(GetVmSettingsFilename());
|
|
|
|
// FIXME: wxRmdir doesn't seem to work here for some reason but deleting the inis folder
|
|
// manually from explorer does work. Can't think of a good work-around at the moment. --air
|
|
|
|
//wxRmdir( GetSettingsFolder().ToString() );
|
|
|
|
wxGetApp().GetRecentIsoManager().Clear();
|
|
g_Conf = std::unique_ptr<AppConfig>(new AppConfig());
|
|
sMainFrame.RemoveCdvdMenu();
|
|
|
|
sApp.WipeUserModeSettings();
|
|
}
|
|
|
|
void MainEmuFrame::RemoveCdvdMenu()
|
|
{
|
|
// Delete() keeps the sub menu and delete the menu item.
|
|
// Remove() does not delete the menu item.
|
|
if (m_menuItem_RecentIsoMenu)
|
|
m_menuCDVD.Delete(m_menuItem_RecentIsoMenu);
|
|
m_menuItem_RecentIsoMenu = nullptr;
|
|
}
|
|
|
|
void MainEmuFrame::Menu_ResetAllSettings_Click(wxCommandEvent& event)
|
|
{
|
|
if (IsBeingDeleted() || m_RestartEmuOnDelete)
|
|
return;
|
|
|
|
{
|
|
ScopedCoreThreadPopup suspender;
|
|
if (!Msgbox::OkCancel(pxsFmt(
|
|
pxE(L"This command clears %s settings and allows you to re-run the First-Time Wizard. You will need to manually restart %s after this operation.\n\nWARNING!! Click OK to delete *ALL* settings for %s and force-close the app, losing any current emulation progress. Are you absolutely sure?"), WX_STR(pxGetAppName()), WX_STR(pxGetAppName()), WX_STR(pxGetAppName())),
|
|
_("Reset all settings?")))
|
|
{
|
|
suspender.AllowResume();
|
|
return;
|
|
}
|
|
}
|
|
|
|
WipeSettings();
|
|
wxGetApp().PostMenuAction(MenuId_Exit);
|
|
}
|
|
|
|
// Return values:
|
|
// wxID_CANCEL - User canceled the action outright.
|
|
// wxID_RESET - User wants to reset the emu in addition to swap discs
|
|
// (anything else) - Standard swap, no reset. (hotswap!)
|
|
wxWindowID SwapOrReset_Iso(wxWindow* owner, IScopedCoreThread& core_control, const wxString& isoFilename, const wxString& descpart1)
|
|
{
|
|
if (GSDump::isRunning)
|
|
{
|
|
wxMessageBox("Please close the GS debugger first before playing a game", _("GS Debugger"), wxICON_ERROR);
|
|
return wxID_CANCEL;
|
|
}
|
|
wxWindowID result = wxID_CANCEL;
|
|
|
|
if ((EmuConfig.CdvdSource == CDVD_SourceType::Iso) && (isoFilename == EmuConfig.CurrentIso))
|
|
{
|
|
core_control.AllowResume();
|
|
return result;
|
|
}
|
|
|
|
if (SysHasValidState())
|
|
{
|
|
core_control.DisallowResume();
|
|
wxDialogWithHelpers dialog(owner, _("Confirm ISO image change"));
|
|
|
|
dialog += dialog.Heading(descpart1); // New lines already applied
|
|
dialog += dialog.Text(isoFilename);
|
|
dialog += dialog.GetCharHeight();
|
|
dialog += dialog.Heading(_("Do you want to swap discs or boot the new image (via system reset)?"));
|
|
|
|
#ifndef DISABLE_RECORDING
|
|
if (g_InputRecording.IsActive() && g_InputRecording.GetInputRecordingData().FromSaveState())
|
|
dialog += dialog.Text(_("\n(Warning: The savestate accompanying the active input recording\nmay not be compatible with the new source)"));
|
|
#endif
|
|
|
|
result = pxIssueConfirmation(dialog, MsgButtons().Reset().Cancel().Custom(_("Swap Disc"), "swap"));
|
|
if (result == wxID_CANCEL)
|
|
{
|
|
core_control.AllowResume();
|
|
return result;
|
|
}
|
|
}
|
|
|
|
g_CDVDReset = true;
|
|
EmuConfig.CdvdSource = CDVD_SourceType::Iso;
|
|
SysUpdateIsoSrcFile(isoFilename);
|
|
|
|
if (result == wxID_RESET)
|
|
{
|
|
core_control.DisallowResume();
|
|
sApp.SysExecute(CDVD_SourceType::Iso);
|
|
}
|
|
else
|
|
{
|
|
Console.Indent().WriteLn("HotSwapping to new ISO src image!");
|
|
//g_Conf->CdvdSource = CDVDsrc_Iso;
|
|
//CoreThread.ChangeCdvdSource();
|
|
core_control.AllowResume();
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
// Return values:
|
|
// wxID_CANCEL - User canceled the action outright.
|
|
// wxID_RESET - User wants to reset the emu in addition to swap discs
|
|
// (anything else) - Standard swap, no reset. (hotswap!)
|
|
wxWindowID SwapOrReset_Disc(wxWindow* owner, IScopedCoreThread& core, const wxString driveLetter)
|
|
{
|
|
if (GSDump::isRunning)
|
|
{
|
|
wxMessageBox("Please close the GS debugger first before playing a game", _("GS Debugger"), wxICON_ERROR);
|
|
return wxID_CANCEL;
|
|
}
|
|
wxWindowID result = wxID_CANCEL;
|
|
|
|
if ((EmuConfig.CdvdSource == CDVD_SourceType::Disc) && (driveLetter == EmuConfig.CurrentDiscDrive))
|
|
{
|
|
core.AllowResume();
|
|
return result;
|
|
}
|
|
|
|
if (SysHasValidState())
|
|
{
|
|
core.DisallowResume();
|
|
wxDialogWithHelpers dialog(owner, _("Confirm disc change"));
|
|
|
|
dialog += dialog.Heading("New drive selected: " + driveLetter);
|
|
dialog += dialog.GetCharHeight();
|
|
dialog += dialog.Heading(_("Do you want to swap discs or boot the new disc (via system reset)?"));
|
|
|
|
#ifndef DISABLE_RECORDING
|
|
if (g_InputRecording.IsActive() && g_InputRecording.GetInputRecordingData().FromSaveState())
|
|
dialog += dialog.Text(_("\n(Warning: The savestate accompanying the active input recording\nmay not be compatible with the new source)"));
|
|
#endif
|
|
|
|
result = pxIssueConfirmation(dialog, MsgButtons().Reset().Cancel().Custom(_("Swap Disc"), "swap"));
|
|
if (result == wxID_CANCEL)
|
|
{
|
|
core.AllowResume();
|
|
return result;
|
|
}
|
|
}
|
|
|
|
EmuConfig.CdvdSource = CDVD_SourceType::Disc;
|
|
SysUpdateDiscSrcDrive(driveLetter);
|
|
if (result == wxID_RESET)
|
|
{
|
|
core.DisallowResume();
|
|
sApp.SysExecute(CDVD_SourceType::Disc);
|
|
}
|
|
else
|
|
{
|
|
Console.Indent().WriteLn("Hot swapping to new disc!");
|
|
core.AllowResume();
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
wxWindowID SwapOrReset_CdvdSrc(wxWindow* owner, CDVD_SourceType newsrc)
|
|
{
|
|
if (GSDump::isRunning)
|
|
{
|
|
wxMessageBox("Please close the GS debugger first before playing a game", _("GS Debugger"), wxICON_ERROR);
|
|
return wxID_CANCEL;
|
|
}
|
|
if (newsrc == EmuConfig.CdvdSource)
|
|
return wxID_CANCEL;
|
|
wxWindowID result = wxID_CANCEL;
|
|
ScopedCoreThreadPopup core;
|
|
|
|
if (SysHasValidState())
|
|
{
|
|
wxDialogWithHelpers dialog(owner, _("Confirm CDVD source change"));
|
|
|
|
wxString changeMsg;
|
|
changeMsg.Printf(_("You've selected to switch the CDVD source from %s to %s."),
|
|
CDVD_SourceLabels[enum_cast(EmuConfig.CdvdSource)], CDVD_SourceLabels[enum_cast(newsrc)]);
|
|
|
|
dialog += dialog.Heading(changeMsg + L"\n\n" +
|
|
_("Do you want to swap discs or boot the new image (system reset)?"));
|
|
|
|
#ifndef DISABLE_RECORDING
|
|
if (g_InputRecording.IsActive() && g_InputRecording.GetInputRecordingData().FromSaveState())
|
|
dialog += dialog.Text(_("\n(Warning: The savestate accompanying the active input recording\nmay not be compatible with the new source)"));
|
|
#endif
|
|
|
|
result = pxIssueConfirmation(dialog, MsgButtons().Reset().Cancel().Custom(_("Swap Disc"), "swap"));
|
|
|
|
if (result == wxID_CANCEL)
|
|
{
|
|
core.AllowResume();
|
|
sMainFrame.UpdateCdvdSrcSelection();
|
|
return result;
|
|
}
|
|
}
|
|
|
|
g_CDVDReset = true;
|
|
CDVD_SourceType oldsrc = EmuConfig.CdvdSource;
|
|
EmuConfig.CdvdSource = newsrc;
|
|
|
|
if (result != wxID_RESET)
|
|
{
|
|
Console.Indent().WriteLn(L"(CdvdSource) HotSwapping CDVD source types from %s to %s.",
|
|
WX_STR(wxString(CDVD_SourceLabels[enum_cast(oldsrc)])),
|
|
WX_STR(wxString(CDVD_SourceLabels[enum_cast(newsrc)])));
|
|
//CoreThread.ChangeCdvdSource();
|
|
sMainFrame.UpdateCdvdSrcSelection();
|
|
core.AllowResume();
|
|
}
|
|
else
|
|
{
|
|
core.DisallowResume();
|
|
sApp.SysExecute(EmuConfig.CdvdSource);
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
static wxString JoinFiletypes(const wxChar** src)
|
|
{
|
|
wxString dest;
|
|
while (*src != NULL)
|
|
{
|
|
if (*src[0] == 0)
|
|
continue;
|
|
if (!dest.IsEmpty())
|
|
dest += L";";
|
|
|
|
dest += pxsFmt(L"*.%ls", *src);
|
|
|
|
if (wxFileName::IsCaseSensitive())
|
|
{
|
|
// omgosh! the filesystem is CaSE SeNSiTiVE!!
|
|
dest += pxsFmt(L";*.%ls", *src).ToUpper();
|
|
}
|
|
|
|
++src;
|
|
}
|
|
|
|
return dest;
|
|
}
|
|
|
|
// Returns FALSE if the user canceled the action.
|
|
bool MainEmuFrame::_DoSelectIsoBrowser(wxString& result)
|
|
{
|
|
static const wxChar* isoSupportedTypes[] =
|
|
{
|
|
L"iso", L"mdf", L"nrg", L"bin", L"img", NULL};
|
|
|
|
const wxString isoSupportedLabel(JoinString(isoSupportedTypes, L" "));
|
|
const wxString isoSupportedList(JoinFiletypes(isoSupportedTypes));
|
|
|
|
wxArrayString isoFilterTypes;
|
|
|
|
isoFilterTypes.Add(pxsFmt(_("All Supported (%s)"), WX_STR((isoSupportedLabel + L" .dump" + L" .gz" + L" .cso" + L" .chd"))));
|
|
isoFilterTypes.Add(isoSupportedList + L";*.dump" + L";*.gz" + L";*.cso" + L";*.chd");
|
|
|
|
isoFilterTypes.Add(pxsFmt(_("Disc Images (%s)"), WX_STR(isoSupportedLabel)));
|
|
isoFilterTypes.Add(isoSupportedList);
|
|
|
|
isoFilterTypes.Add(pxsFmt(_("Blockdumps (%s)"), L".dump"));
|
|
isoFilterTypes.Add(L"*.dump");
|
|
|
|
isoFilterTypes.Add(pxsFmt(_("Compressed (%s)"), L".gz .cso .chd"));
|
|
isoFilterTypes.Add(L"*.gz;*.cso;*.chd");
|
|
|
|
isoFilterTypes.Add(_("All Files (*.*)"));
|
|
isoFilterTypes.Add(L"*.*");
|
|
|
|
wxFileDialog ctrl(this, _("Select disc image, compressed disc image, or block-dump..."), g_Conf->Folders.RunIso.ToString(), wxEmptyString,
|
|
JoinString(isoFilterTypes, L"|"), wxFD_OPEN | wxFD_FILE_MUST_EXIST);
|
|
|
|
if (ctrl.ShowModal() != wxID_CANCEL)
|
|
{
|
|
result = ctrl.GetPath();
|
|
g_Conf->Folders.RunIso = wxFileName(result).GetPath();
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
bool MainEmuFrame::_DoSelectELFBrowser()
|
|
{
|
|
static const wxChar* elfFilterType = L"ELF Files (.elf)|*.elf;*.ELF";
|
|
|
|
wxFileDialog ctrl(this, _("Select ELF file..."), g_Conf->Folders.RunELF.ToString(), wxEmptyString,
|
|
(wxString)elfFilterType + L"|" + _("All Files (*.*)") + L"|*.*", wxFD_OPEN | wxFD_FILE_MUST_EXIST);
|
|
|
|
if (ctrl.ShowModal() != wxID_CANCEL)
|
|
{
|
|
g_Conf->Folders.RunELF = wxFileName(ctrl.GetPath()).GetPath();
|
|
EmuConfig.CurrentELF = ctrl.GetPath();
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
void MainEmuFrame::_DoBootCdvd()
|
|
{
|
|
if (GSDump::isRunning)
|
|
{
|
|
wxMessageBox("Please close the GS debugger first before playing a game", _("GS Debugger"), wxICON_ERROR);
|
|
return;
|
|
}
|
|
ScopedCoreThreadPause paused_core;
|
|
|
|
if (EmuConfig.CdvdSource == CDVD_SourceType::Iso)
|
|
{
|
|
bool selector = EmuConfig.CurrentIso.IsEmpty();
|
|
|
|
if (!selector && !wxFileExists(EmuConfig.CurrentIso))
|
|
{
|
|
// User has an iso selected from a previous run, but it doesn't exist anymore.
|
|
// Issue a courtesy popup and then an Iso Selector to choose a new one.
|
|
|
|
wxDialogWithHelpers dialog(this, _("ISO file not found!"));
|
|
dialog += dialog.Heading(
|
|
_("An error occurred while trying to open the file:") + wxString(L"\n\n") + EmuConfig.CurrentIso + L"\n\n" +
|
|
_("Error: The configured ISO file does not exist. Click OK to select a new ISO source for CDVD."));
|
|
|
|
pxIssueConfirmation(dialog, MsgButtons().OK());
|
|
|
|
selector = true;
|
|
}
|
|
|
|
if (selector || g_Conf->AskOnBoot)
|
|
{
|
|
wxString result;
|
|
if (!_DoSelectIsoBrowser(result))
|
|
{
|
|
paused_core.AllowResume();
|
|
return;
|
|
}
|
|
|
|
SysUpdateIsoSrcFile(result);
|
|
}
|
|
}
|
|
|
|
if (SysHasValidState())
|
|
{
|
|
wxDialogWithHelpers dialog(this, _("Confirm PS2 Reset"));
|
|
dialog += dialog.Heading(GetMsg_ConfirmSysReset());
|
|
bool confirmed = (pxIssueConfirmation(dialog, MsgButtons().Yes().Cancel(), L"BootCdvd.ConfirmReset") != wxID_CANCEL);
|
|
|
|
if (!confirmed)
|
|
{
|
|
paused_core.AllowResume();
|
|
return;
|
|
}
|
|
}
|
|
|
|
sApp.SysExecute(EmuConfig.CdvdSource);
|
|
}
|
|
|
|
void MainEmuFrame::Menu_CdvdSource_Click(wxCommandEvent& event)
|
|
{
|
|
CDVD_SourceType newsrc = CDVD_SourceType::NoDisc;
|
|
|
|
switch (event.GetId())
|
|
{
|
|
case MenuId_Src_Iso:
|
|
newsrc = CDVD_SourceType::Iso;
|
|
break;
|
|
case MenuId_Src_Disc:
|
|
newsrc = CDVD_SourceType::Disc;
|
|
break;
|
|
case MenuId_Src_NoDisc:
|
|
newsrc = CDVD_SourceType::NoDisc;
|
|
break;
|
|
jNO_DEFAULT
|
|
}
|
|
|
|
SwapOrReset_CdvdSrc(this, newsrc);
|
|
#ifndef DISABLE_RECORDING
|
|
if (!g_InputRecording.IsActive())
|
|
#endif
|
|
ApplyCDVDStatus();
|
|
}
|
|
|
|
void MainEmuFrame::Menu_BootCdvd_Click(wxCommandEvent& event)
|
|
{
|
|
#ifndef DISABLE_RECORDING
|
|
if (g_InputRecording.IsActive())
|
|
g_InputRecording.GoToFirstFrame(this);
|
|
else
|
|
#endif
|
|
{
|
|
g_Conf->EmuOptions.UseBOOT2Injection = g_Conf->EnableFastBoot;
|
|
_DoBootCdvd();
|
|
}
|
|
}
|
|
|
|
void MainEmuFrame::Menu_FastBoot_Click(wxCommandEvent& event)
|
|
{
|
|
g_Conf->EnableFastBoot = GetMenuBar()->IsChecked(MenuId_Config_FastBoot);
|
|
AppApplySettings();
|
|
AppSaveSettings();
|
|
UpdateStatusBar();
|
|
}
|
|
|
|
wxString GetMsg_IsoImageChanged()
|
|
{
|
|
return _("You have selected the following ISO image into PCSX2:\n\n");
|
|
}
|
|
|
|
void MainEmuFrame::Menu_IsoBrowse_Click(wxCommandEvent& event)
|
|
{
|
|
ScopedCoreThreadPopup core;
|
|
wxString isofile;
|
|
|
|
if (!_DoSelectIsoBrowser(isofile))
|
|
{
|
|
core.AllowResume();
|
|
return;
|
|
}
|
|
|
|
SwapOrReset_Iso(this, core, isofile, GetMsg_IsoImageChanged());
|
|
AppSaveSettings(); // save the new iso selection; update menus!
|
|
}
|
|
|
|
void MainEmuFrame::Menu_IsoClear_Click(wxCommandEvent& event)
|
|
{
|
|
wxDialogWithHelpers dialog(this, _("Confirm clearing ISO list"));
|
|
dialog += dialog.Heading(_("This will clear the ISO list. If an ISO is running it will remain in the list. Continue?"));
|
|
|
|
bool confirmed = pxIssueConfirmation(dialog, MsgButtons().YesNo()) == wxID_YES;
|
|
|
|
if (confirmed)
|
|
{
|
|
// If the CDVD mode is not ISO, or the system isn't running, wipe the CurrentIso field in INI file
|
|
if (EmuConfig.CdvdSource != CDVD_SourceType::Iso || !SysHasValidState())
|
|
SysUpdateIsoSrcFile("");
|
|
wxGetApp().GetRecentIsoManager().Clear();
|
|
AppSaveSettings();
|
|
}
|
|
}
|
|
|
|
void MainEmuFrame::Menu_Ask_On_Boot_Click(wxCommandEvent& event)
|
|
{
|
|
g_Conf->AskOnBoot = event.IsChecked();
|
|
|
|
if (SysHasValidState())
|
|
return;
|
|
|
|
wxGetApp().GetRecentIsoManager().EnableItems(!event.IsChecked());
|
|
FindItemInMenuBar(MenuId_IsoBrowse)->Enable(!event.IsChecked());
|
|
}
|
|
|
|
void MainEmuFrame::Menu_Debug_CreateBlockdump_Click(wxCommandEvent& event)
|
|
{
|
|
g_Conf->EmuOptions.CdvdDumpBlocks = event.IsChecked();
|
|
if (g_Conf->EmuOptions.CdvdDumpBlocks && SysHasValidState())
|
|
Console.Warning("VM must be rebooted to create a useful block dump.");
|
|
|
|
AppSaveSettings();
|
|
}
|
|
|
|
void MainEmuFrame::Menu_MultitapToggle_Click(wxCommandEvent&)
|
|
{
|
|
g_Conf->EmuOptions.MultitapPort0_Enabled = GetMenuBar()->IsChecked(MenuId_Config_Multitap0Toggle);
|
|
g_Conf->EmuOptions.MultitapPort1_Enabled = GetMenuBar()->IsChecked(MenuId_Config_Multitap1Toggle);
|
|
AppApplySettings();
|
|
AppSaveSettings();
|
|
|
|
//evt.Skip();
|
|
}
|
|
|
|
void MainEmuFrame::Menu_EnableBackupStates_Click(wxCommandEvent&)
|
|
{
|
|
g_Conf->EmuOptions.BackupSavestate = GetMenuBar()->IsChecked(MenuId_EnableBackupStates);
|
|
|
|
//without the next line, after toggling this menu-checkbox, the change only applies from the 2nd save and onwards
|
|
// (1st save after the toggle keeps the old pre-toggle value)..
|
|
// wonder what that means for all the other menu checkboxes which only use AppSaveSettings... (avih)
|
|
AppApplySettings();
|
|
AppSaveSettings();
|
|
}
|
|
|
|
void MainEmuFrame::Menu_EnablePatches_Click(wxCommandEvent&)
|
|
{
|
|
g_Conf->EmuOptions.EnablePatches = GetMenuBar()->IsChecked(MenuId_EnablePatches);
|
|
AppApplySettings();
|
|
AppSaveSettings();
|
|
}
|
|
|
|
void MainEmuFrame::Menu_EnableCheats_Click(wxCommandEvent&)
|
|
{
|
|
g_Conf->EmuOptions.EnableCheats = GetMenuBar()->IsChecked(MenuId_EnableCheats);
|
|
AppApplySettings();
|
|
AppSaveSettings();
|
|
}
|
|
|
|
void MainEmuFrame::Menu_IPC_Enable_Click(wxCommandEvent&)
|
|
{
|
|
g_Conf->EmuOptions.EnableIPC = GetMenuBar()->IsChecked(MenuId_IPC_Enable);
|
|
AppApplySettings();
|
|
AppSaveSettings();
|
|
}
|
|
|
|
void MainEmuFrame::Menu_EnableWideScreenPatches_Click(wxCommandEvent&)
|
|
{
|
|
g_Conf->EmuOptions.EnableWideScreenPatches = GetMenuBar()->IsChecked(MenuId_EnableWideScreenPatches);
|
|
AppApplySettings();
|
|
AppSaveSettings();
|
|
}
|
|
|
|
#ifndef DISABLE_RECORDING
|
|
void MainEmuFrame::Menu_EnableRecordingTools_Click(wxCommandEvent& event)
|
|
{
|
|
bool checked = GetMenuBar()->IsChecked(MenuId_EnableInputRecording);
|
|
// Confirm with User
|
|
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 Input Recording"))
|
|
{
|
|
checked = false;
|
|
m_GameSettingsSubmenu.FindChildItem(MenuId_EnableInputRecording)->Check(false);
|
|
}
|
|
}
|
|
|
|
// If still enabled, add the menu item, else, remove it
|
|
if (checked)
|
|
{
|
|
GetMenuBar()->Insert(TopLevelMenu_InputRecording, &m_menuRecording, _("&Input Record"));
|
|
g_InputRecording.InitVirtualPadWindows(this);
|
|
SysConsole.recordingConsole.Enabled = true;
|
|
// Enable Recording Keybindings
|
|
if (GSFrame* gsFrame = wxGetApp().GetGsFramePtr())
|
|
{
|
|
if (GSPanel* viewport = gsFrame->GetViewport())
|
|
{
|
|
viewport->InitRecordingAccelerators();
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
//Properly close any currently loaded recording file before disabling
|
|
StopInputRecording();
|
|
GetMenuBar()->Remove(TopLevelMenu_InputRecording);
|
|
// Always turn controller logs off, but never turn it on by default
|
|
SysConsole.controlInfo.Enabled = checked;
|
|
// Return Keybindings Back to Normal
|
|
if (GSFrame* gsFrame = wxGetApp().GetGsFramePtr())
|
|
{
|
|
if (GSPanel* viewport = gsFrame->GetViewport())
|
|
{
|
|
viewport->RemoveRecordingAccelerators();
|
|
}
|
|
}
|
|
SysConsole.recordingConsole.Enabled = false;
|
|
if (g_InputRecordingControls.IsPaused())
|
|
g_InputRecordingControls.Resume();
|
|
}
|
|
|
|
g_Conf->EmuOptions.EnableRecordingTools = checked;
|
|
// Update GS Title Frequency
|
|
if (GSFrame* gsFrame = wxGetApp().GetGsFramePtr())
|
|
{
|
|
gsFrame->UpdateTitleUpdateFreq();
|
|
}
|
|
// Enable Recording Logs
|
|
ConsoleLogFrame* progLog = wxGetApp().GetProgramLog();
|
|
progLog->UpdateLogList();
|
|
AppApplySettings();
|
|
AppSaveSettings();
|
|
}
|
|
#endif
|
|
|
|
void MainEmuFrame::Menu_EnableHostFs_Click(wxCommandEvent&)
|
|
{
|
|
g_Conf->EmuOptions.HostFs = GetMenuBar()->IsChecked(MenuId_EnableHostFs);
|
|
AppSaveSettings();
|
|
}
|
|
|
|
void MainEmuFrame::Menu_OpenELF_Click(wxCommandEvent&)
|
|
{
|
|
ScopedCoreThreadClose stopped_core;
|
|
if (_DoSelectELFBrowser())
|
|
{
|
|
g_Conf->EmuOptions.UseBOOT2Injection = true;
|
|
sApp.SysExecute(EmuConfig.CdvdSource, EmuConfig.CurrentELF);
|
|
}
|
|
|
|
stopped_core.AllowResume();
|
|
}
|
|
|
|
void MainEmuFrame::Menu_LoadStates_Click(wxCommandEvent& event)
|
|
{
|
|
if (event.GetId() == MenuId_State_LoadBackup)
|
|
{
|
|
States_DefrostCurrentSlotBackup();
|
|
return;
|
|
}
|
|
|
|
States_SetCurrentSlot(event.GetId() - MenuId_State_Load01 - 1);
|
|
States_DefrostCurrentSlot();
|
|
}
|
|
|
|
void MainEmuFrame::Menu_SaveStates_Click(wxCommandEvent& event)
|
|
{
|
|
States_SetCurrentSlot(event.GetId() - MenuId_State_Save01 - 1);
|
|
States_FreezeCurrentSlot();
|
|
}
|
|
|
|
void MainEmuFrame::Menu_LoadStateFromFile_Click(wxCommandEvent& event)
|
|
{
|
|
wxFileDialog loadStateDialog(this, _("Load State"), L"", L"",
|
|
L"Savestate files (*.p2s)|*.p2s", wxFD_OPEN);
|
|
|
|
if (loadStateDialog.ShowModal() == wxID_CANCEL)
|
|
{
|
|
return;
|
|
}
|
|
|
|
wxString path = loadStateDialog.GetPath();
|
|
StateCopy_LoadFromFile(path);
|
|
}
|
|
|
|
void MainEmuFrame::Menu_SaveStateToFile_Click(wxCommandEvent& event)
|
|
{
|
|
wxFileDialog saveStateDialog(this, _("Save State"), L"", L"",
|
|
L"Savestate files (*.p2s)|*.p2s", wxFD_OPEN);
|
|
|
|
if (saveStateDialog.ShowModal() == wxID_CANCEL)
|
|
{
|
|
return;
|
|
}
|
|
|
|
wxString path = saveStateDialog.GetPath();
|
|
StateCopy_SaveToFile(path);
|
|
}
|
|
|
|
void MainEmuFrame::Menu_Exit_Click(wxCommandEvent& event)
|
|
{
|
|
Close();
|
|
}
|
|
|
|
class SysExecEvent_ToggleSuspend : public SysExecEvent
|
|
{
|
|
public:
|
|
virtual ~SysExecEvent_ToggleSuspend() = default;
|
|
|
|
wxString GetEventName() const { return L"ToggleSuspendResume"; }
|
|
|
|
protected:
|
|
void InvokeEvent()
|
|
{
|
|
if (CoreThread.IsOpen())
|
|
{
|
|
CoreThread.Suspend();
|
|
#ifndef DISABLE_RECORDING
|
|
// Disable recording controls that only make sense if the game is running
|
|
sMainFrame.enableRecordingMenuItem(MenuId_Recording_FrameAdvance, false);
|
|
sMainFrame.enableRecordingMenuItem(MenuId_Recording_TogglePause, false);
|
|
sMainFrame.enableRecordingMenuItem(MenuId_Recording_ToggleRecordingMode, false);
|
|
#endif
|
|
}
|
|
else
|
|
CoreThread.Resume();
|
|
}
|
|
};
|
|
|
|
void MainEmuFrame::Menu_SuspendResume_Click(wxCommandEvent& event)
|
|
{
|
|
if (!SysHasValidState())
|
|
return;
|
|
|
|
// Disable the menu item. The state of the menu is indeterminate until the core thread
|
|
// has responded (it updates status after emulation has engaged successfully).
|
|
|
|
EnableMenuItem(MenuId_Sys_SuspendResume, false);
|
|
GetSysExecutorThread().PostEvent(new SysExecEvent_ToggleSuspend());
|
|
}
|
|
|
|
void MainEmuFrame::Menu_SysShutdown_Click(wxCommandEvent& event)
|
|
{
|
|
bool doShutdown = true;
|
|
#ifndef DISABLE_RECORDING
|
|
if (!g_InputRecording.IsActive())
|
|
{
|
|
if (g_InputRecordingControls.IsPaused())
|
|
g_InputRecordingControls.Resume();
|
|
}
|
|
else
|
|
{
|
|
const bool initiallyPaused = g_InputRecordingControls.IsPaused();
|
|
if (!initiallyPaused)
|
|
g_InputRecordingControls.Pause();
|
|
wxWindowID result = wxID_CANCEL;
|
|
wxDialogWithHelpers dialog(this, _("Shutdown & Close Input Recording"));
|
|
dialog += dialog.Heading(L"\nShutting down emulation will close the active input recording file.\nProceed?");
|
|
result = pxIssueConfirmation(dialog, MsgButtons().Close().Cancel());
|
|
if (result == wxID_CLOSE)
|
|
{
|
|
StopInputRecording();
|
|
g_InputRecordingControls.Resume();
|
|
}
|
|
else if (!initiallyPaused)
|
|
{
|
|
g_InputRecordingControls.Resume();
|
|
doShutdown = false;
|
|
}
|
|
}
|
|
#endif
|
|
if (doShutdown)
|
|
{
|
|
if (m_capturingVideo)
|
|
VideoCaptureToggle();
|
|
UI_DisableSysShutdown();
|
|
Console.SetTitle("PCSX2 Program Log");
|
|
CoreThread.Reset();
|
|
}
|
|
}
|
|
|
|
void MainEmuFrame::Menu_Debug_Open_Click(wxCommandEvent& event)
|
|
{
|
|
DisassemblyDialog* dlg = wxGetApp().GetDisassemblyPtr();
|
|
if (dlg)
|
|
{
|
|
if (event.IsChecked())
|
|
dlg->Show();
|
|
else
|
|
dlg->Hide();
|
|
}
|
|
}
|
|
|
|
void MainEmuFrame::Menu_Debug_MemoryDump_Click(wxCommandEvent& event)
|
|
{
|
|
}
|
|
|
|
void MainEmuFrame::Menu_ShowConsole(wxCommandEvent& event)
|
|
{
|
|
// Use messages to relay open/close commands (thread-safe)
|
|
|
|
g_Conf->ProgLogBox.Visible = event.IsChecked();
|
|
wxCommandEvent evt(wxEVT_MENU, g_Conf->ProgLogBox.Visible ? wxID_OPEN : wxID_CLOSE);
|
|
wxGetApp().ProgramLog_PostEvent(evt);
|
|
}
|
|
|
|
void MainEmuFrame::Menu_ShowConsole_Stdio(wxCommandEvent& event)
|
|
{
|
|
g_Conf->EmuOptions.ConsoleToStdio = GetMenuBar()->IsChecked(MenuId_Console_Stdio);
|
|
AppSaveSettings();
|
|
}
|
|
|
|
void MainEmuFrame::Menu_GetStarted(wxCommandEvent& event)
|
|
{
|
|
wxLaunchDefaultBrowser("https://pcsx2.net/getting-started.html");
|
|
}
|
|
|
|
void MainEmuFrame::Menu_Compatibility(wxCommandEvent& event)
|
|
{
|
|
wxLaunchDefaultBrowser("https://pcsx2.net/compatibility-list.html");
|
|
}
|
|
|
|
void MainEmuFrame::Menu_Forums(wxCommandEvent& event)
|
|
{
|
|
wxLaunchDefaultBrowser("https://forums.pcsx2.net/");
|
|
}
|
|
|
|
void MainEmuFrame::Menu_Website(wxCommandEvent& event)
|
|
{
|
|
wxLaunchDefaultBrowser("https://pcsx2.net/");
|
|
}
|
|
|
|
void MainEmuFrame::Menu_Github(wxCommandEvent& event)
|
|
{
|
|
wxLaunchDefaultBrowser("https://github.com/PCSX2/pcsx2");
|
|
}
|
|
|
|
void MainEmuFrame::Menu_Wiki(wxCommandEvent& event)
|
|
{
|
|
wxLaunchDefaultBrowser("https://wiki.pcsx2.net/Main_Page");
|
|
}
|
|
|
|
void MainEmuFrame::Menu_ShowAboutBox(wxCommandEvent& event)
|
|
{
|
|
AppOpenDialog<AboutBoxDialog>(this);
|
|
}
|
|
|
|
void MainEmuFrame::Menu_ShowGSDump(wxCommandEvent& event)
|
|
{
|
|
AppOpenDialog<GSDumpDialog>(this);
|
|
}
|
|
|
|
void MainEmuFrame::Menu_Capture_Video_ToggleCapture_Click(wxCommandEvent& event)
|
|
{
|
|
ScopedCoreThreadPause paused_core;
|
|
paused_core.AllowResume();
|
|
VideoCaptureToggle();
|
|
}
|
|
|
|
void MainEmuFrame::Menu_Capture_Video_IncludeAudio_Click(wxCommandEvent& event)
|
|
{
|
|
g_Conf->AudioCapture.EnableAudio = GetMenuBar()->IsChecked(MenuId_Capture_Video_IncludeAudio);
|
|
ApplySettings();
|
|
}
|
|
|
|
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
|
|
|
|
// make the recording setup dialog[s] pseudo-modal also for the main PCSX2 window
|
|
// (the GS dialog is already properly modal for the GS window)
|
|
bool needsMainFrameEnable = false;
|
|
if (IsEnabled())
|
|
{
|
|
needsMainFrameEnable = true;
|
|
Disable();
|
|
}
|
|
|
|
// GSsetupRecording can be aborted/canceled by the user. Don't go on to record the audio if that happens
|
|
std::string filename;
|
|
if (GSsetupRecording(filename))
|
|
{
|
|
if (!g_Conf->AudioCapture.EnableAudio || SPU2setupRecording(&filename))
|
|
{
|
|
m_submenuVideoCapture.Enable(MenuId_Capture_Video_Record, false);
|
|
m_submenuVideoCapture.Enable(MenuId_Capture_Video_Stop, true);
|
|
m_submenuVideoCapture.Enable(MenuId_Capture_Video_IncludeAudio, false);
|
|
}
|
|
else
|
|
{
|
|
GSendRecording();
|
|
m_capturingVideo = false;
|
|
}
|
|
}
|
|
else // recording dialog canceled by the user. align our state
|
|
m_capturingVideo = false;
|
|
|
|
if (needsMainFrameEnable)
|
|
Enable();
|
|
}
|
|
else
|
|
{
|
|
// stop recording
|
|
GSendRecording();
|
|
if (g_Conf->AudioCapture.EnableAudio)
|
|
SPU2endRecording();
|
|
m_submenuVideoCapture.Enable(MenuId_Capture_Video_Record, true);
|
|
m_submenuVideoCapture.Enable(MenuId_Capture_Video_Stop, false);
|
|
m_submenuVideoCapture.Enable(MenuId_Capture_Video_IncludeAudio, true);
|
|
}
|
|
}
|
|
|
|
void MainEmuFrame::Menu_Capture_Screenshot_Screenshot_Click(wxCommandEvent& event)
|
|
{
|
|
if (!CoreThread.IsOpen())
|
|
{
|
|
return;
|
|
}
|
|
GSmakeSnapshot(g_Conf->Folders.Snapshots.ToString().char_str());
|
|
}
|
|
|
|
void MainEmuFrame::Menu_Capture_Screenshot_Screenshot_As_Click(wxCommandEvent& event)
|
|
{
|
|
if (!CoreThread.IsOpen())
|
|
return;
|
|
|
|
// Ensure emulation is paused so that the correct image is captured
|
|
bool wasPaused = CoreThread.IsPaused();
|
|
if (!wasPaused)
|
|
CoreThread.Pause({});
|
|
|
|
wxFileDialog fileDialog(this, _("Select a file"), g_Conf->Folders.Snapshots.ToAscii(), wxEmptyString, "PNG files (*.png)|*.png", wxFD_SAVE | wxFD_OVERWRITE_PROMPT);
|
|
|
|
if (fileDialog.ShowModal() == wxID_OK)
|
|
GSmakeSnapshot((char*)fileDialog.GetPath().char_str());
|
|
|
|
// Resume emulation
|
|
if (!wasPaused)
|
|
CoreThread.Resume();
|
|
}
|
|
|
|
#ifndef DISABLE_RECORDING
|
|
void MainEmuFrame::Menu_Recording_New_Click(wxCommandEvent& event)
|
|
{
|
|
const bool emulation_initially_paused = CoreThread.IsPaused();
|
|
const bool recording_initially_paused = g_InputRecordingControls.IsPaused();
|
|
|
|
if (!emulation_initially_paused && !recording_initially_paused)
|
|
g_InputRecordingControls.PauseImmediately();
|
|
|
|
NewRecordingFrame* newRecordingFrame = wxGetApp().GetNewRecordingFramePtr();
|
|
if (newRecordingFrame)
|
|
{
|
|
if (newRecordingFrame->ShowModal(CoreThread.IsOpen()) != wxID_CANCEL)
|
|
{
|
|
if (g_InputRecording.Create(newRecordingFrame->GetFile(), newRecordingFrame->GetFrom(), newRecordingFrame->GetAuthor()))
|
|
{
|
|
if (!g_InputRecording.GetInputRecordingData().FromSaveState())
|
|
StartInputRecording();
|
|
return;
|
|
}
|
|
}
|
|
|
|
if (!emulation_initially_paused && !recording_initially_paused)
|
|
g_InputRecordingControls.ResumeImmediately();
|
|
}
|
|
}
|
|
|
|
void MainEmuFrame::Menu_Recording_Play_Click(wxCommandEvent& event)
|
|
{
|
|
const bool initiallyPaused = g_InputRecordingControls.IsPaused();
|
|
|
|
if (!initiallyPaused)
|
|
g_InputRecordingControls.PauseImmediately();
|
|
|
|
wxFileDialog openFileDialog(this, _("Select P2M2 record file."), L"", L"",
|
|
L"p2m2 file(*.p2m2)|*.p2m2", wxFD_OPEN);
|
|
if (openFileDialog.ShowModal() == wxID_CANCEL)
|
|
{
|
|
if (!initiallyPaused)
|
|
g_InputRecordingControls.Resume();
|
|
return;
|
|
}
|
|
|
|
StopInputRecording();
|
|
if (!g_InputRecording.Play(this, openFileDialog.GetPath()))
|
|
{
|
|
if (!initiallyPaused)
|
|
g_InputRecordingControls.Resume();
|
|
return;
|
|
}
|
|
|
|
if (!g_InputRecording.GetInputRecordingData().FromSaveState())
|
|
StartInputRecording();
|
|
}
|
|
|
|
void MainEmuFrame::ApplyFirstFrameStatus()
|
|
{
|
|
wxMenuItem* cdvd_menu = m_menuSys.FindChildItem(MenuId_Boot_CDVD);
|
|
|
|
wxString keyCodeStr;
|
|
if (GSFrame* gsFrame = wxGetApp().GetGsFramePtr())
|
|
if (GSPanel* viewport = gsFrame->GetViewport())
|
|
keyCodeStr = '\t' + viewport->GetAssociatedKeyCode(("GoToFirstFrame"));
|
|
|
|
cdvd_menu->SetItemLabel(L"Restart Recording" + keyCodeStr);
|
|
if (g_InputRecording.GetInputRecordingData().FromSaveState())
|
|
cdvd_menu->SetHelp(L"Loads the savestate that accompanies the active input recording");
|
|
else
|
|
cdvd_menu->SetHelp(L"Reboots Emulation");
|
|
|
|
UpdateStatusBar();
|
|
}
|
|
|
|
void MainEmuFrame::Menu_Recording_Stop_Click(wxCommandEvent& event)
|
|
{
|
|
StopInputRecording();
|
|
}
|
|
|
|
void MainEmuFrame::Menu_Recording_Config_FrameAdvance(wxCommandEvent& event)
|
|
{
|
|
long result = wxGetNumberFromUser(_("Enter the number of frames to advance per advance"), _("Number of Frames"), _("Configure Frame Advance"), g_Conf->inputRecording.m_frame_advance_amount, 1, INT_MAX);
|
|
if (result != -1)
|
|
{
|
|
g_Conf->inputRecording.m_frame_advance_amount = result;
|
|
g_InputRecordingControls.setFrameAdvanceAmount(result);
|
|
wxString frame_advance_label = wxString(_("Configure Frame Advance"));
|
|
frame_advance_label.Append(fmt::format(" ({})", result));
|
|
m_submenu_recording_settings.SetLabel(MenuId_Recording_Config_FrameAdvance, frame_advance_label);
|
|
}
|
|
}
|
|
|
|
void MainEmuFrame::StartInputRecording()
|
|
{
|
|
m_menuRecording.FindChildItem(MenuId_Recording_New)->Enable(false);
|
|
m_menuRecording.FindChildItem(MenuId_Recording_Stop)->Enable(true);
|
|
m_menuRecording.FindChildItem(MenuId_Recording_ToggleRecordingMode)->Enable(true);
|
|
ApplyFirstFrameStatus();
|
|
}
|
|
|
|
void MainEmuFrame::StopInputRecording()
|
|
{
|
|
if (g_InputRecording.IsActive())
|
|
{
|
|
g_InputRecording.Stop();
|
|
m_menuRecording.FindChildItem(MenuId_Recording_New)->Enable(true);
|
|
m_menuRecording.FindChildItem(MenuId_Recording_Stop)->Enable(false);
|
|
m_menuRecording.FindChildItem(MenuId_Recording_ToggleRecordingMode)->Enable(false);
|
|
ApplyCDVDStatus();
|
|
}
|
|
}
|
|
|
|
void MainEmuFrame::Menu_Recording_TogglePause_Click(wxCommandEvent& event)
|
|
{
|
|
if (g_Conf->EmuOptions.EnableRecordingTools)
|
|
g_InputRecordingControls.TogglePause();
|
|
}
|
|
|
|
void MainEmuFrame::Menu_Recording_FrameAdvance_Click(wxCommandEvent& event)
|
|
{
|
|
if (g_Conf->EmuOptions.EnableRecordingTools)
|
|
g_InputRecordingControls.FrameAdvance();
|
|
}
|
|
|
|
void MainEmuFrame::Menu_Recording_ToggleRecordingMode_Click(wxCommandEvent& event)
|
|
{
|
|
if (g_Conf->EmuOptions.EnableRecordingTools)
|
|
g_InputRecordingControls.RecordModeToggle();
|
|
}
|
|
|
|
void MainEmuFrame::Menu_Recording_VirtualPad_Open_Click(wxCommandEvent& event)
|
|
{
|
|
g_InputRecording.ShowVirtualPad(event.GetId() - MenuId_Recording_VirtualPad_Port0);
|
|
}
|
|
#endif
|