core/movie: Add MovieFinished mode

Also mentioned in Laws of TAS.
This commit is contained in:
zhupengfei 2020-07-08 23:56:37 +08:00
parent e188f86582
commit 1780f8b5b8
No known key found for this signature in database
GPG key ID: DD129E108BD09378
5 changed files with 35 additions and 24 deletions

View file

@ -1892,7 +1892,8 @@ void GMainWindow::OnCloseMovie(bool shutting_down) {
OnPauseGame(); 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(); Core::Movie::GetInstance().Shutdown();
if (was_recording) { if (was_recording) {
QMessageBox::information(this, tr("Movie Saved"), QMessageBox::information(this, tr("Movie Saved"),
@ -1986,14 +1987,19 @@ void GMainWindow::UpdateStatusBar() {
// Update movie status // Update movie status
const u64 current = Core::Movie::GetInstance().GetCurrentInputIndex(); const u64 current = Core::Movie::GetInstance().GetCurrentInputIndex();
const u64 total = Core::Movie::GetInstance().GetTotalInputCount(); 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->setText(tr("Recording %1").arg(current));
message_label->setVisible(true); message_label->setVisible(true);
message_label_used_for_movie = 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->setText(tr("Playing %1 / %2").arg(current).arg(total));
message_label->setVisible(true); message_label->setVisible(true);
message_label_used_for_movie = 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 } else if (message_label_used_for_movie) { // Clear the label if movie was just closed
message_label->setText(QString{}); message_label->setText(QString{});
message_label->setVisible(false); message_label->setVisible(false);
@ -2291,7 +2297,6 @@ void GMainWindow::OnLanguageChanged(const QString& locale) {
void GMainWindow::OnMoviePlaybackCompleted() { void GMainWindow::OnMoviePlaybackCompleted() {
QMessageBox::information(this, tr("Playback Completed"), tr("Movie playback completed.")); QMessageBox::information(this, tr("Playback Completed"), tr("Movie playback completed."));
ui->action_Close_Movie->setEnabled(false);
} }
void GMainWindow::UpdateWindowTitle() { void GMainWindow::UpdateWindowTitle() {

View file

@ -29,7 +29,7 @@ MoviePlayDialog::MoviePlayDialog(QWidget* parent, GameList* game_list_)
if (Core::System::GetInstance().IsPoweredOn()) { if (Core::System::GetInstance().IsPoweredOn()) {
QString note_text; QString note_text;
note_text = tr("Current running game will be stopped."); 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("<br>Current recording will be discarded.")); note_text.append(tr("<br>Current recording will be discarded."));
} }
ui->note2Label->setText(note_text); ui->note2Label->setText(note_text);

View file

@ -25,7 +25,7 @@ MovieRecordDialog::MovieRecordDialog(QWidget* parent)
QString note_text; QString note_text;
if (Core::System::GetInstance().IsPoweredOn()) { if (Core::System::GetInstance().IsPoweredOn()) {
note_text = tr("Current running game will be restarted."); 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("<br>Current recording will be discarded.")); note_text.append(tr("<br>Current recording will be discarded."));
} }
} else { } else {

View file

@ -28,8 +28,6 @@ namespace Core {
/*static*/ Movie Movie::s_instance; /*static*/ Movie Movie::s_instance;
enum class PlayMode { None, Recording, Playing };
enum class ControllerStateType : u8 { enum class ControllerStateType : u8 {
PadAndCircle, PadAndCircle,
Touch, 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 (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) { if (play_mode == PlayMode::Recording) {
SaveMovie(); SaveMovie();
} }
@ -196,7 +209,6 @@ void Movie::serialize(Archive& ar, const unsigned int file_version) {
play_mode = PlayMode::Playing; play_mode = PlayMode::Playing;
total_input = GetInputCount(recorded_input); total_input = GetInputCount(recorded_input);
} else { } else {
recorded_input = std::move(recorded_input_);
play_mode = PlayMode::Recording; play_mode = PlayMode::Recording;
rerecord_count++; rerecord_count++;
} }
@ -205,11 +217,8 @@ void Movie::serialize(Archive& ar, const unsigned int file_version) {
SERIALIZE_IMPL(Movie) SERIALIZE_IMPL(Movie)
bool Movie::IsPlayingInput() const { Movie::PlayMode Movie::GetPlayMode() const {
return play_mode == PlayMode::Playing; return play_mode;
}
bool Movie::IsRecordingInput() const {
return play_mode == PlayMode::Recording;
} }
u64 Movie::GetCurrentInputIndex() const { u64 Movie::GetCurrentInputIndex() const {
@ -222,9 +231,7 @@ u64 Movie::GetTotalInputCount() const {
void Movie::CheckInputEnd() { void Movie::CheckInputEnd() {
if (current_byte + sizeof(ControllerState) > recorded_input.size()) { if (current_byte + sizeof(ControllerState) > recorded_input.size()) {
LOG_INFO(Movie, "Playback finished"); LOG_INFO(Movie, "Playback finished");
play_mode = PlayMode::None; play_mode = PlayMode::MovieFinished;
init_time = 0;
id = 0;
playback_completion_callback(); playback_completion_callback();
} }
} }
@ -638,7 +645,7 @@ Movie::MovieMetadata Movie::GetMovieMetadata(const std::string& movie_file) cons
} }
void Movie::Shutdown() { void Movie::Shutdown() {
if (IsRecordingInput()) { if (play_mode == PlayMode::Recording) {
SaveMovie(); SaveMovie();
} }
@ -653,11 +660,11 @@ void Movie::Shutdown() {
template <typename... Targs> template <typename... Targs>
void Movie::Handle(Targs&... Fargs) { void Movie::Handle(Targs&... Fargs) {
if (IsPlayingInput()) { if (play_mode == PlayMode::Playing) {
ASSERT(current_byte + sizeof(ControllerState) <= recorded_input.size()); ASSERT(current_byte + sizeof(ControllerState) <= recorded_input.size());
Play(Fargs...); Play(Fargs...);
CheckInputEnd(); CheckInputEnd();
} else if (IsRecordingInput()) { } else if (play_mode == PlayMode::Recording) {
Record(Fargs...); Record(Fargs...);
} }
} }

View file

@ -24,10 +24,10 @@ union PadState;
namespace Core { namespace Core {
struct CTMHeader; struct CTMHeader;
struct ControllerState; struct ControllerState;
enum class PlayMode;
class Movie { class Movie {
public: public:
enum class PlayMode { None, Recording, Playing, MovieFinished };
enum class ValidationResult { enum class ValidationResult {
OK, OK,
RevisionDismatch, RevisionDismatch,
@ -120,8 +120,7 @@ public:
* When playing: Replaces the given input states with the ones stored in the playback file * When playing: Replaces the given input states with the ones stored in the playback file
*/ */
void HandleExtraHidResponse(Service::IR::ExtraHIDResponse& extra_hid_response); void HandleExtraHidResponse(Service::IR::ExtraHIDResponse& extra_hid_response);
bool IsPlayingInput() const; PlayMode GetPlayMode() const;
bool IsRecordingInput() const;
u64 GetCurrentInputIndex() const; u64 GetCurrentInputIndex() const;
u64 GetTotalInputCount() const; u64 GetTotalInputCount() const;