diff options
-rw-r--r-- | src/yuzu/bootmanager.cpp | 9 | ||||
-rw-r--r-- | src/yuzu/bootmanager.h | 6 | ||||
-rw-r--r-- | src/yuzu/main.cpp | 100 | ||||
-rw-r--r-- | src/yuzu/main.h | 5 | ||||
-rw-r--r-- | src/yuzu/main.ui | 90 |
5 files changed, 153 insertions, 57 deletions
diff --git a/src/yuzu/bootmanager.cpp b/src/yuzu/bootmanager.cpp index 822ba1a34..105f36d33 100644 --- a/src/yuzu/bootmanager.cpp +++ b/src/yuzu/bootmanager.cpp @@ -303,6 +303,7 @@ GRenderWindow::GRenderWindow(GMainWindow* parent, EmuThread* emu_thread_, connect(this, &GRenderWindow::ExecuteProgramSignal, parent, &GMainWindow::OnExecuteProgram, Qt::QueuedConnection); connect(this, &GRenderWindow::ExitSignal, parent, &GMainWindow::OnExit, Qt::QueuedConnection); + connect(this, &GRenderWindow::TasPlaybackStateChanged, parent, &GMainWindow::OnTasStateChanged); } void GRenderWindow::ExecuteProgram(std::size_t program_index) { @@ -319,10 +320,18 @@ GRenderWindow::~GRenderWindow() { void GRenderWindow::OnFrameDisplayed() { input_subsystem->GetTas()->UpdateThread(); + TasInput::TasState new_tas_state = std::get<0>(input_subsystem->GetTas()->GetStatus()); + if (!first_frame) { + last_tas_state = new_tas_state; first_frame = true; emit FirstFrameDisplayed(); } + + if (new_tas_state != last_tas_state) { + last_tas_state = new_tas_state; + emit TasPlaybackStateChanged(); + } } bool GRenderWindow::IsShown() const { diff --git a/src/yuzu/bootmanager.h b/src/yuzu/bootmanager.h index 40fd4a9d6..061e3605f 100644 --- a/src/yuzu/bootmanager.h +++ b/src/yuzu/bootmanager.h @@ -41,6 +41,10 @@ enum class LoadCallbackStage; class RendererBase; } // namespace VideoCore +namespace TasInput { +enum class TasState; +} + class EmuThread final : public QThread { Q_OBJECT @@ -203,6 +207,7 @@ signals: void ExecuteProgramSignal(std::size_t program_index); void ExitSignal(); void MouseActivity(); + void TasPlaybackStateChanged(); private: void TouchBeginEvent(const QTouchEvent* event); @@ -236,6 +241,7 @@ private: QWidget* child_widget = nullptr; bool first_frame = false; + TasInput::TasState last_tas_state; std::array<std::size_t, 16> touch_ids{}; diff --git a/src/yuzu/main.cpp b/src/yuzu/main.cpp index c4c76b094..73278f29f 100644 --- a/src/yuzu/main.cpp +++ b/src/yuzu/main.cpp @@ -965,6 +965,9 @@ void GMainWindow::InitializeHotkeys() { const QString toggle_status_bar = QStringLiteral("Toggle Status Bar"); const QString fullscreen = QStringLiteral("Fullscreen"); const QString capture_screenshot = QStringLiteral("Capture Screenshot"); + const QString tas_start_stop = QStringLiteral("TAS Start/Stop"); + const QString tas_record = QStringLiteral("TAS Record"); + const QString tas_reset = QStringLiteral("TAS Reset"); ui->action_Load_File->setShortcut(hotkey_registry.GetKeySequence(main_window, load_file)); ui->action_Load_File->setShortcutContext( @@ -1005,6 +1008,18 @@ void GMainWindow::InitializeHotkeys() { ui->action_Fullscreen->setShortcutContext( hotkey_registry.GetShortcutContext(main_window, fullscreen)); + ui->action_TAS_Start->setShortcut(hotkey_registry.GetKeySequence(main_window, tas_start_stop)); + ui->action_TAS_Start->setShortcutContext( + hotkey_registry.GetShortcutContext(main_window, tas_start_stop)); + + ui->action_TAS_Record->setShortcut(hotkey_registry.GetKeySequence(main_window, tas_record)); + ui->action_TAS_Record->setShortcutContext( + hotkey_registry.GetShortcutContext(main_window, tas_record)); + + ui->action_TAS_Reset->setShortcut(hotkey_registry.GetKeySequence(main_window, tas_reset)); + ui->action_TAS_Reset->setShortcutContext( + hotkey_registry.GetShortcutContext(main_window, tas_reset)); + connect(hotkey_registry.GetHotkey(main_window, QStringLiteral("Load File"), this), &QShortcut::activated, this, &GMainWindow::OnMenuLoadFile); connect( @@ -1095,28 +1110,6 @@ void GMainWindow::InitializeHotkeys() { render_window->setAttribute(Qt::WA_Hover, true); } }); - connect(hotkey_registry.GetHotkey(main_window, QStringLiteral("TAS Start/Stop"), this), - &QShortcut::activated, this, [&] { - if (!emulation_running) { - return; - } - input_subsystem->GetTas()->StartStop(); - }); - connect(hotkey_registry.GetHotkey(main_window, QStringLiteral("TAS Reset"), this), - &QShortcut::activated, this, [&] { input_subsystem->GetTas()->Reset(); }); - connect(hotkey_registry.GetHotkey(main_window, QStringLiteral("TAS Record"), this), - &QShortcut::activated, this, [&] { - if (!emulation_running) { - return; - } - bool is_recording = input_subsystem->GetTas()->Record(); - if (!is_recording) { - const auto res = QMessageBox::question(this, tr("TAS Recording"), - tr("Overwrite file of player 1?"), - QMessageBox::Yes | QMessageBox::No); - input_subsystem->GetTas()->SaveRecording(res == QMessageBox::Yes); - } - }); } void GMainWindow::SetDefaultUIGeometry() { @@ -1236,11 +1229,11 @@ void GMainWindow::ConnectMenuEvents() { connect(ui->action_Restart, &QAction::triggered, this, [this] { BootGame(QString(game_path)); }); connect(ui->action_Configure, &QAction::triggered, this, &GMainWindow::OnConfigure); - connect(ui->action_Configure_Tas, &QAction::triggered, this, &GMainWindow::OnConfigureTas); connect(ui->action_Configure_Current_Game, &QAction::triggered, this, &GMainWindow::OnConfigurePerGame); // View + connect(ui->action_Fullscreen, &QAction::triggered, this, &GMainWindow::ToggleFullscreen); connect(ui->action_Single_Window_Mode, &QAction::triggered, this, &GMainWindow::ToggleWindowMode); connect(ui->action_Display_Dock_Widget_Headers, &QAction::triggered, this, @@ -1258,17 +1251,20 @@ void GMainWindow::ConnectMenuEvents() { ui->menu_Reset_Window_Size->addAction(ui->action_Reset_Window_Size_900); ui->menu_Reset_Window_Size->addAction(ui->action_Reset_Window_Size_1080); - // Fullscreen - connect(ui->action_Fullscreen, &QAction::triggered, this, &GMainWindow::ToggleFullscreen); - - // Movie + // Tools + connect(ui->action_Rederive, &QAction::triggered, this, + std::bind(&GMainWindow::OnReinitializeKeys, this, ReinitializeKeyBehavior::Warning)); connect(ui->action_Capture_Screenshot, &QAction::triggered, this, &GMainWindow::OnCaptureScreenshot); + // TAS + connect(ui->action_TAS_Start, &QAction::triggered, this, &GMainWindow::OnTasStartStop); + connect(ui->action_TAS_Record, &QAction::triggered, this, &GMainWindow::OnTasRecord); + connect(ui->action_TAS_Reset, &QAction::triggered, this, &GMainWindow::OnTasReset); + connect(ui->action_Configure_Tas, &QAction::triggered, this, &GMainWindow::OnConfigureTas); + // Help connect(ui->action_Open_yuzu_Folder, &QAction::triggered, this, &GMainWindow::OnOpenYuzuFolder); - connect(ui->action_Rederive, &QAction::triggered, this, - std::bind(&GMainWindow::OnReinitializeKeys, this, ReinitializeKeyBehavior::Warning)); connect(ui->action_About, &QAction::triggered, this, &GMainWindow::OnAbout); } @@ -1582,6 +1578,7 @@ void GMainWindow::ShutdownGame() { game_list->SetFilterFocus(); tas_label->clear(); input_subsystem->GetTas()->Stop(); + OnTasStateChanged(); render_window->removeEventFilter(render_window); render_window->setAttribute(Qt::WA_Hover, false); @@ -2509,6 +2506,7 @@ void GMainWindow::OnStartGame() { ui->action_Restart->setEnabled(true); ui->action_Configure_Current_Game->setEnabled(true); ui->action_Report_Compatibility->setEnabled(true); + OnTasStateChanged(); discord_rpc->Update(); ui->action_Load_Amiibo->setEnabled(true); @@ -2821,6 +2819,33 @@ void GMainWindow::OnConfigureTas() { } } +void GMainWindow::OnTasStartStop() { + if (!emulation_running) { + return; + } + input_subsystem->GetTas()->StartStop(); + OnTasStateChanged(); +} + +void GMainWindow::OnTasRecord() { + if (!emulation_running) { + return; + } + bool is_recording = input_subsystem->GetTas()->Record(); + if (!is_recording) { + const auto res = + QMessageBox::question(this, tr("TAS Recording"), tr("Overwrite file of player 1?"), + QMessageBox::Yes | QMessageBox::No); + input_subsystem->GetTas()->SaveRecording(res == QMessageBox::Yes); + } + OnTasStateChanged(); +} + +void GMainWindow::OnTasReset() { + input_subsystem->GetTas()->Reset(); +} + + void GMainWindow::OnConfigurePerGame() { const u64 title_id = system->GetCurrentProcessProgramID(); OpenPerGameConfiguration(title_id, game_path.toStdString()); @@ -3014,6 +3039,23 @@ QString GMainWindow::GetTasStateDescription() const { } } +void GMainWindow::OnTasStateChanged() { + bool is_running = false; + bool is_recording = false; + if (emulation_running) { + TasInput::TasState tas_status = std::get<0>(input_subsystem->GetTas()->GetStatus()); + is_running = tas_status == TasInput::TasState::Running; + is_recording = tas_status == TasInput::TasState::Recording; + } + + ui->action_TAS_Start->setText(is_running ? tr("&Stop Running") : tr("&Start")); + ui->action_TAS_Record->setText(is_recording ? tr("Stop R&ecording") : tr("R&ecord")); + + ui->action_TAS_Start->setEnabled(emulation_running); + ui->action_TAS_Record->setEnabled(emulation_running); + ui->action_TAS_Reset->setEnabled(emulation_running); +} + void GMainWindow::UpdateStatusBar() { if (emu_thread == nullptr) { status_bar_update_timer.stop(); diff --git a/src/yuzu/main.h b/src/yuzu/main.h index 24633ff2d..556cbbaf7 100644 --- a/src/yuzu/main.h +++ b/src/yuzu/main.h @@ -177,6 +177,7 @@ public slots: void WebBrowserOpenWebPage(const std::string& main_url, const std::string& additional_args, bool is_local); void OnAppFocusStateChanged(Qt::ApplicationState state); + void OnTasStateChanged(); private: void RegisterMetaTypes(); @@ -268,6 +269,9 @@ private slots: void OnMenuRecentFile(); void OnConfigure(); void OnConfigureTas(); + void OnTasStartStop(); + void OnTasRecord(); + void OnTasReset(); void OnConfigurePerGame(); void OnLoadAmiibo(); void OnOpenYuzuFolder(); @@ -313,6 +317,7 @@ private: void OpenURL(const QUrl& url); void LoadTranslation(); void OpenPerGameConfiguration(u64 title_id, const std::string& file_name); + QString GetTasStateDescription() const; std::unique_ptr<Ui::MainWindow> ui; diff --git a/src/yuzu/main.ui b/src/yuzu/main.ui index a62e39a06..c58aa2866 100644 --- a/src/yuzu/main.ui +++ b/src/yuzu/main.ui @@ -79,39 +79,39 @@ <string>&View</string> </property> <widget class="QMenu" name="menu_Reset_Window_Size"> - <property name="title"> - <string>&Reset Window Size</string> - </property> + <property name="title"> + <string>&Reset Window Size</string> + </property> + </widget> + <widget class="QMenu" name="menu_View_Debugging"> + <property name="title"> + <string>&Debugging</string> + </property> </widget> <action name="action_Reset_Window_Size_720"> - <property name="text"> - <string>Reset Window Size to &720p</string> - </property> - <property name="iconText"> - <string>Reset Window Size to 720p</string> - </property> + <property name="text"> + <string>Reset Window Size to &720p</string> + </property> + <property name="iconText"> + <string>Reset Window Size to 720p</string> + </property> </action> <action name="action_Reset_Window_Size_900"> - <property name="text"> - <string>Reset Window Size to &900p</string> - </property> - <property name="iconText"> - <string>Reset Window Size to 900p</string> - </property> + <property name="text"> + <string>Reset Window Size to &900p</string> + </property> + <property name="iconText"> + <string>Reset Window Size to 900p</string> + </property> </action> <action name="action_Reset_Window_Size_1080"> - <property name="text"> - <string>Reset Window Size to &1080p</string> - </property> - <property name="iconText"> - <string>Reset Window Size to 1080p</string> - </property> - </action> - <widget class="QMenu" name="menu_View_Debugging"> - <property name="title"> - <string>&Debugging</string> + <property name="text"> + <string>Reset Window Size to &1080p</string> </property> - </widget> + <property name="iconText"> + <string>Reset Window Size to 1080p</string> + </property> + </action> <addaction name="action_Fullscreen"/> <addaction name="action_Single_Window_Mode"/> <addaction name="action_Display_Dock_Widget_Headers"/> @@ -125,10 +125,20 @@ <property name="title"> <string>&Tools</string> </property> + <widget class="QMenu" name="menuTAS"> + <property name="title"> + <string>&TAS</string> + </property> + <addaction name="action_TAS_Start"/> + <addaction name="action_TAS_Record"/> + <addaction name="action_TAS_Reset"/> + <addaction name="separator"/> + <addaction name="action_Configure_Tas"/> + </widget> <addaction name="action_Rederive"/> <addaction name="separator"/> <addaction name="action_Capture_Screenshot"/> - <addaction name="action_Configure_Tas"/> + <addaction name="menuTAS"/> </widget> <widget class="QMenu" name="menu_Help"> <property name="title"> @@ -309,7 +319,7 @@ </action> <action name="action_Configure_Tas"> <property name="text"> - <string>Configure &TAS...</string> + <string>&Configure TAS...</string> </property> </action> <action name="action_Configure_Current_Game"> @@ -320,6 +330,30 @@ <string>Configure C&urrent Game...</string> </property> </action> + <action name="action_TAS_Start"> + <property name="enabled"> + <bool>false</bool> + </property> + <property name="text"> + <string>&Start</string> + </property> + </action> + <action name="action_TAS_Reset"> + <property name="enabled"> + <bool>false</bool> + </property> + <property name="text"> + <string>&Reset</string> + </property> + </action> + <action name="action_TAS_Record"> + <property name="enabled"> + <bool>false</bool> + </property> + <property name="text"> + <string>R&ecord</string> + </property> + </action> </widget> <resources> <include location="yuzu.qrc"/> |