core/movie: Movie refactor, add a completion callback
This commit is contained in:
parent
6cb9a45154
commit
0f44f7b481
5 changed files with 77 additions and 47 deletions
|
@ -118,10 +118,10 @@ struct CTMHeader {
|
|||
static_assert(sizeof(CTMHeader) == 256, "CTMHeader should be 256 bytes");
|
||||
#pragma pack(pop)
|
||||
|
||||
bool Movie::IsPlayingInput() {
|
||||
bool Movie::IsPlayingInput() const {
|
||||
return play_mode == PlayMode::Playing;
|
||||
}
|
||||
bool Movie::IsRecordingInput() {
|
||||
bool Movie::IsRecordingInput() const {
|
||||
return play_mode == PlayMode::Recording;
|
||||
}
|
||||
|
||||
|
@ -129,6 +129,7 @@ void Movie::CheckInputEnd() {
|
|||
if (current_byte + sizeof(ControllerState) > recorded_input.size()) {
|
||||
LOG_INFO(Movie, "Playback finished");
|
||||
play_mode = PlayMode::None;
|
||||
playback_completion_callback();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -343,33 +344,35 @@ void Movie::Record(const Service::IR::ExtraHIDResponse& extra_hid_response) {
|
|||
Record(s);
|
||||
}
|
||||
|
||||
bool Movie::ValidateHeader(const CTMHeader& header) {
|
||||
Movie::ValidationResult Movie::ValidateHeader(const CTMHeader& header) const {
|
||||
if (header_magic_bytes != header.filetype) {
|
||||
LOG_ERROR(Movie, "Playback file does not have valid header");
|
||||
return false;
|
||||
return ValidationResult::Invalid;
|
||||
}
|
||||
|
||||
std::string revision =
|
||||
Common::ArrayToString(header.revision.data(), header.revision.size(), 21, false);
|
||||
revision = Common::ToLower(revision);
|
||||
|
||||
if (revision != Common::g_scm_rev) {
|
||||
LOG_WARNING(Movie,
|
||||
"This movie was created on a different version of Citra, playback may desync");
|
||||
}
|
||||
|
||||
u64 program_id;
|
||||
Core::System::GetInstance().GetAppLoader().ReadProgramId(program_id);
|
||||
if (program_id != header.program_id) {
|
||||
LOG_WARNING(Movie, "This movie was recorded using a ROM with a different program id");
|
||||
return ValidationResult::GameDismatch;
|
||||
}
|
||||
|
||||
return true;
|
||||
if (revision != Common::g_scm_rev) {
|
||||
LOG_WARNING(Movie,
|
||||
"This movie was created on a different version of Citra, playback may desync");
|
||||
return ValidationResult::RevisionDismatch;
|
||||
}
|
||||
|
||||
return ValidationResult::OK;
|
||||
}
|
||||
|
||||
void Movie::SaveMovie() {
|
||||
LOG_INFO(Movie, "Saving movie");
|
||||
FileUtil::IOFile save_record(Settings::values.movie_record, "wb");
|
||||
LOG_INFO(Movie, "Saving recorded movie to '{}'", record_movie_file);
|
||||
FileUtil::IOFile save_record(record_movie_file, "wb");
|
||||
|
||||
if (!save_record.IsGood()) {
|
||||
LOG_ERROR(Movie, "Unable to open file to save movie");
|
||||
|
@ -394,31 +397,45 @@ void Movie::SaveMovie() {
|
|||
}
|
||||
}
|
||||
|
||||
void Movie::Init() {
|
||||
if (!Settings::values.movie_play.empty()) {
|
||||
LOG_INFO(Movie, "Loading Movie for playback");
|
||||
FileUtil::IOFile save_record(Settings::values.movie_play, "rb");
|
||||
u64 size = save_record.GetSize();
|
||||
void Movie::StartPlayback(const std::string& movie_file,
|
||||
std::function<void()> completion_callback) {
|
||||
LOG_INFO(Movie, "Loading Movie for playback");
|
||||
FileUtil::IOFile save_record(movie_file, "rb");
|
||||
const u64 size = save_record.GetSize();
|
||||
|
||||
if (save_record.IsGood() && size > sizeof(CTMHeader)) {
|
||||
CTMHeader header;
|
||||
save_record.ReadArray(&header, 1);
|
||||
if (ValidateHeader(header)) {
|
||||
play_mode = PlayMode::Playing;
|
||||
recorded_input.resize(size - sizeof(CTMHeader));
|
||||
save_record.ReadArray(recorded_input.data(), recorded_input.size());
|
||||
current_byte = 0;
|
||||
}
|
||||
} else {
|
||||
LOG_ERROR(Movie, "Failed to playback movie: Unable to open '{}'",
|
||||
Settings::values.movie_play);
|
||||
if (save_record.IsGood() && size > sizeof(CTMHeader)) {
|
||||
CTMHeader header;
|
||||
save_record.ReadArray(&header, 1);
|
||||
if (ValidateHeader(header) != ValidationResult::Invalid) {
|
||||
play_mode = PlayMode::Playing;
|
||||
recorded_input.resize(size - sizeof(CTMHeader));
|
||||
save_record.ReadArray(recorded_input.data(), recorded_input.size());
|
||||
current_byte = 0;
|
||||
playback_completion_callback = completion_callback;
|
||||
}
|
||||
} else {
|
||||
LOG_ERROR(Movie, "Failed to playback movie: Unable to open '{}'", movie_file);
|
||||
}
|
||||
}
|
||||
|
||||
void Movie::StartRecording(const std::string& movie_file) {
|
||||
LOG_INFO(Movie, "Enabling Movie recording");
|
||||
play_mode = PlayMode::Recording;
|
||||
record_movie_file = movie_file;
|
||||
}
|
||||
|
||||
Movie::ValidationResult Movie::ValidateMovie(const std::string& movie_file) const {
|
||||
LOG_INFO(Movie, "Validating Movie file '{}'", movie_file);
|
||||
FileUtil::IOFile save_record(movie_file, "rb");
|
||||
const u64 size = save_record.GetSize();
|
||||
|
||||
if (!save_record || size <= sizeof(CTMHeader)) {
|
||||
return ValidationResult::Invalid;
|
||||
}
|
||||
|
||||
if (!Settings::values.movie_record.empty()) {
|
||||
LOG_INFO(Movie, "Enabling Movie recording");
|
||||
play_mode = PlayMode::Recording;
|
||||
}
|
||||
CTMHeader header;
|
||||
save_record.ReadArray(&header, 1);
|
||||
return ValidateHeader(header);
|
||||
}
|
||||
|
||||
void Movie::Shutdown() {
|
||||
|
@ -428,6 +445,7 @@ void Movie::Shutdown() {
|
|||
|
||||
play_mode = PlayMode::None;
|
||||
recorded_input.resize(0);
|
||||
record_movie_file.clear();
|
||||
current_byte = 0;
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue