mirror of
				https://github.com/PabloMK7/citra.git
				synced 2025-10-31 05:40:04 +00:00 
			
		
		
		
	core/movie: Add MovieFinished mode
Also mentioned in Laws of TAS.
This commit is contained in:
		
							parent
							
								
									e188f86582
								
							
						
					
					
						commit
						1780f8b5b8
					
				
					 5 changed files with 35 additions and 24 deletions
				
			
		|  | @ -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() { | ||||||
|  |  | ||||||
|  | @ -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); | ||||||
|  |  | ||||||
|  | @ -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 { | ||||||
|  |  | ||||||
|  | @ -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...); | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -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; | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue