core/movie: Add MovieFinished mode
Also mentioned in Laws of TAS.
This commit is contained in:
parent
e188f86582
commit
1780f8b5b8
|
@ -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;
|
||||||
|
|
Reference in New Issue