From 1780f8b5b81ef9a80b41dd5e614d09605b703c44 Mon Sep 17 00:00:00 2001 From: zhupengfei Date: Wed, 8 Jul 2020 23:56:37 +0800 Subject: [PATCH] core/movie: Add MovieFinished mode Also mentioned in Laws of TAS. --- src/citra_qt/main.cpp | 13 +++++--- src/citra_qt/movie/movie_play_dialog.cpp | 2 +- src/citra_qt/movie/movie_record_dialog.cpp | 2 +- src/core/movie.cpp | 37 +++++++++++++--------- src/core/movie.h | 5 ++- 5 files changed, 35 insertions(+), 24 deletions(-) diff --git a/src/citra_qt/main.cpp b/src/citra_qt/main.cpp index d9612fce8..6e9b9d553 100644 --- a/src/citra_qt/main.cpp +++ b/src/citra_qt/main.cpp @@ -1892,7 +1892,8 @@ void GMainWindow::OnCloseMovie(bool shutting_down) { OnPauseGame(); } - const bool was_recording = Core::Movie::GetInstance().IsRecordingInput(); + const bool was_recording = + Core::Movie::GetInstance().GetPlayMode() == Core::Movie::PlayMode::Recording; Core::Movie::GetInstance().Shutdown(); if (was_recording) { QMessageBox::information(this, tr("Movie Saved"), @@ -1986,14 +1987,19 @@ void GMainWindow::UpdateStatusBar() { // Update movie status const u64 current = Core::Movie::GetInstance().GetCurrentInputIndex(); const u64 total = Core::Movie::GetInstance().GetTotalInputCount(); - if (Core::Movie::GetInstance().IsRecordingInput()) { + const auto play_mode = Core::Movie::GetInstance().GetPlayMode(); + if (play_mode == Core::Movie::PlayMode::Recording) { message_label->setText(tr("Recording %1").arg(current)); message_label->setVisible(true); message_label_used_for_movie = true; - } else if (Core::Movie::GetInstance().IsPlayingInput()) { + } else if (play_mode == Core::Movie::PlayMode::Playing) { message_label->setText(tr("Playing %1 / %2").arg(current).arg(total)); message_label->setVisible(true); message_label_used_for_movie = true; + } else if (play_mode == Core::Movie::PlayMode::MovieFinished) { + message_label->setText(tr("Movie Finished")); + message_label->setVisible(true); + message_label_used_for_movie = true; } else if (message_label_used_for_movie) { // Clear the label if movie was just closed message_label->setText(QString{}); message_label->setVisible(false); @@ -2291,7 +2297,6 @@ void GMainWindow::OnLanguageChanged(const QString& locale) { void GMainWindow::OnMoviePlaybackCompleted() { QMessageBox::information(this, tr("Playback Completed"), tr("Movie playback completed.")); - ui->action_Close_Movie->setEnabled(false); } void GMainWindow::UpdateWindowTitle() { diff --git a/src/citra_qt/movie/movie_play_dialog.cpp b/src/citra_qt/movie/movie_play_dialog.cpp index bfb38341a..0a389985a 100644 --- a/src/citra_qt/movie/movie_play_dialog.cpp +++ b/src/citra_qt/movie/movie_play_dialog.cpp @@ -29,7 +29,7 @@ MoviePlayDialog::MoviePlayDialog(QWidget* parent, GameList* game_list_) if (Core::System::GetInstance().IsPoweredOn()) { QString note_text; note_text = tr("Current running game will be stopped."); - if (Core::Movie::GetInstance().IsRecordingInput()) { + if (Core::Movie::GetInstance().GetPlayMode() == Core::Movie::PlayMode::Recording) { note_text.append(tr("
Current recording will be discarded.")); } ui->note2Label->setText(note_text); diff --git a/src/citra_qt/movie/movie_record_dialog.cpp b/src/citra_qt/movie/movie_record_dialog.cpp index 6f0954909..9b7967d9a 100644 --- a/src/citra_qt/movie/movie_record_dialog.cpp +++ b/src/citra_qt/movie/movie_record_dialog.cpp @@ -25,7 +25,7 @@ MovieRecordDialog::MovieRecordDialog(QWidget* parent) QString note_text; if (Core::System::GetInstance().IsPoweredOn()) { note_text = tr("Current running game will be restarted."); - if (Core::Movie::GetInstance().IsRecordingInput()) { + if (Core::Movie::GetInstance().GetPlayMode() == Core::Movie::PlayMode::Recording) { note_text.append(tr("
Current recording will be discarded.")); } } else { diff --git a/src/core/movie.cpp b/src/core/movie.cpp index 0c90950b4..f96842d5b 100644 --- a/src/core/movie.cpp +++ b/src/core/movie.cpp @@ -28,8 +28,6 @@ namespace Core { /*static*/ Movie Movie::s_instance; -enum class PlayMode { None, Recording, Playing }; - enum class ControllerStateType : u8 { PadAndCircle, Touch, @@ -178,8 +176,23 @@ void Movie::serialize(Archive& ar, const unsigned int file_version) { } } + // Whether the state was made in MovieFinished state + bool post_movie = play_mode == PlayMode::MovieFinished; + if (file_version > 0) { + ar& post_movie; + } + if (Archive::is_loading::value && id != 0) { - if (read_only) { // Do not replace the previously recorded input. + if (!read_only) { + recorded_input = std::move(recorded_input_); + } + + if (post_movie) { + play_mode = PlayMode::MovieFinished; + return; + } + + if (read_only) { if (play_mode == PlayMode::Recording) { SaveMovie(); } @@ -196,7 +209,6 @@ void Movie::serialize(Archive& ar, const unsigned int file_version) { play_mode = PlayMode::Playing; total_input = GetInputCount(recorded_input); } else { - recorded_input = std::move(recorded_input_); play_mode = PlayMode::Recording; rerecord_count++; } @@ -205,11 +217,8 @@ void Movie::serialize(Archive& ar, const unsigned int file_version) { SERIALIZE_IMPL(Movie) -bool Movie::IsPlayingInput() const { - return play_mode == PlayMode::Playing; -} -bool Movie::IsRecordingInput() const { - return play_mode == PlayMode::Recording; +Movie::PlayMode Movie::GetPlayMode() const { + return play_mode; } u64 Movie::GetCurrentInputIndex() const { @@ -222,9 +231,7 @@ u64 Movie::GetTotalInputCount() const { void Movie::CheckInputEnd() { if (current_byte + sizeof(ControllerState) > recorded_input.size()) { LOG_INFO(Movie, "Playback finished"); - play_mode = PlayMode::None; - init_time = 0; - id = 0; + play_mode = PlayMode::MovieFinished; playback_completion_callback(); } } @@ -638,7 +645,7 @@ Movie::MovieMetadata Movie::GetMovieMetadata(const std::string& movie_file) cons } void Movie::Shutdown() { - if (IsRecordingInput()) { + if (play_mode == PlayMode::Recording) { SaveMovie(); } @@ -653,11 +660,11 @@ void Movie::Shutdown() { template void Movie::Handle(Targs&... Fargs) { - if (IsPlayingInput()) { + if (play_mode == PlayMode::Playing) { ASSERT(current_byte + sizeof(ControllerState) <= recorded_input.size()); Play(Fargs...); CheckInputEnd(); - } else if (IsRecordingInput()) { + } else if (play_mode == PlayMode::Recording) { Record(Fargs...); } } diff --git a/src/core/movie.h b/src/core/movie.h index e62dfe5c2..15cd631ca 100644 --- a/src/core/movie.h +++ b/src/core/movie.h @@ -24,10 +24,10 @@ union PadState; namespace Core { struct CTMHeader; struct ControllerState; -enum class PlayMode; class Movie { public: + enum class PlayMode { None, Recording, Playing, MovieFinished }; enum class ValidationResult { OK, RevisionDismatch, @@ -120,8 +120,7 @@ public: * When playing: Replaces the given input states with the ones stored in the playback file */ void HandleExtraHidResponse(Service::IR::ExtraHIDResponse& extra_hid_response); - bool IsPlayingInput() const; - bool IsRecordingInput() const; + PlayMode GetPlayMode() const; u64 GetCurrentInputIndex() const; u64 GetTotalInputCount() const;