mirror of
				https://github.com/PabloMK7/citra.git
				synced 2025-10-30 21:30:04 +00:00 
			
		
		
		
	core: De-globalize movie (#6659)
This commit is contained in:
		
							parent
							
								
									a955f02771
								
							
						
					
					
						commit
						f8b8b6e53c
					
				
					 51 changed files with 182 additions and 104 deletions
				
			
		|  | @ -26,6 +26,7 @@ | ||||||
| #include "core/hle/service/nfc/nfc.h" | #include "core/hle/service/nfc/nfc.h" | ||||||
| #include "core/loader/loader.h" | #include "core/loader/loader.h" | ||||||
| #include "core/savestate.h" | #include "core/savestate.h" | ||||||
|  | #include "core/telemetry_session.h" | ||||||
| #include "jni/android_common/android_common.h" | #include "jni/android_common/android_common.h" | ||||||
| #include "jni/applets/mii_selector.h" | #include "jni/applets/mii_selector.h" | ||||||
| #include "jni/applets/swkbd.h" | #include "jni/applets/swkbd.h" | ||||||
|  | @ -621,7 +622,7 @@ jobjectArray Java_org_citra_citra_1emu_NativeLibrary_GetSavestateInfo( | ||||||
|         return nullptr; |         return nullptr; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     const auto savestates = Core::ListSaveStates(title_id); |     const auto savestates = Core::ListSaveStates(title_id, system.Movie().GetCurrentMovieID()); | ||||||
|     const jobjectArray array = |     const jobjectArray array = | ||||||
|         env->NewObjectArray(static_cast<jsize>(savestates.size()), savestate_info_class, nullptr); |         env->NewObjectArray(static_cast<jsize>(savestates.size()), savestate_info_class, nullptr); | ||||||
|     for (std::size_t i = 0; i < savestates.size(); ++i) { |     for (std::size_t i = 0; i < savestates.size(); ++i) { | ||||||
|  |  | ||||||
|  | @ -8,6 +8,7 @@ | ||||||
| #include <boost/serialization/vector.hpp> | #include <boost/serialization/vector.hpp> | ||||||
| #include <boost/serialization/weak_ptr.hpp> | #include <boost/serialization/weak_ptr.hpp> | ||||||
| #include "audio_core/audio_types.h" | #include "audio_core/audio_types.h" | ||||||
|  | #include "common/archives.h" | ||||||
| #ifdef HAVE_MF | #ifdef HAVE_MF | ||||||
| #include "audio_core/hle/wmf_decoder.h" | #include "audio_core/hle/wmf_decoder.h" | ||||||
| #elif HAVE_AUDIOTOOLBOX | #elif HAVE_AUDIOTOOLBOX | ||||||
|  |  | ||||||
|  | @ -19,7 +19,6 @@ | ||||||
| #include "common/detached_tasks.h" | #include "common/detached_tasks.h" | ||||||
| #include "common/file_util.h" | #include "common/file_util.h" | ||||||
| #include "common/logging/backend.h" | #include "common/logging/backend.h" | ||||||
| #include "common/logging/filter.h" |  | ||||||
| #include "common/logging/log.h" | #include "common/logging/log.h" | ||||||
| #include "common/scm_rev.h" | #include "common/scm_rev.h" | ||||||
| #include "common/scope_exit.h" | #include "common/scope_exit.h" | ||||||
|  | @ -28,18 +27,15 @@ | ||||||
| #include "core/core.h" | #include "core/core.h" | ||||||
| #include "core/dumping/backend.h" | #include "core/dumping/backend.h" | ||||||
| #include "core/dumping/ffmpeg_backend.h" | #include "core/dumping/ffmpeg_backend.h" | ||||||
| #include "core/file_sys/cia_container.h" |  | ||||||
| #include "core/frontend/applets/default_applets.h" | #include "core/frontend/applets/default_applets.h" | ||||||
| #include "core/frontend/framebuffer_layout.h" | #include "core/frontend/framebuffer_layout.h" | ||||||
| #include "core/gdbstub/gdbstub.h" |  | ||||||
| #include "core/hle/service/am/am.h" | #include "core/hle/service/am/am.h" | ||||||
| #include "core/hle/service/cfg/cfg.h" | #include "core/hle/service/cfg/cfg.h" | ||||||
| #include "core/loader/loader.h" |  | ||||||
| #include "core/movie.h" | #include "core/movie.h" | ||||||
|  | #include "core/telemetry_session.h" | ||||||
| #include "input_common/main.h" | #include "input_common/main.h" | ||||||
| #include "network/network.h" | #include "network/network.h" | ||||||
| #include "video_core/renderer_base.h" | #include "video_core/renderer_base.h" | ||||||
| #include "video_core/video_core.h" |  | ||||||
| 
 | 
 | ||||||
| #undef _UNICODE | #undef _UNICODE | ||||||
| #include <getopt.h> | #include <getopt.h> | ||||||
|  | @ -331,7 +327,7 @@ int main(int argc, char** argv) { | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     auto& system = Core::System::GetInstance(); |     auto& system = Core::System::GetInstance(); | ||||||
|     auto& movie = Core::Movie::GetInstance(); |     auto& movie = system.Movie(); | ||||||
| 
 | 
 | ||||||
|     if (!movie_record.empty()) { |     if (!movie_record.empty()) { | ||||||
|         movie.PrepareForRecording(); |         movie.PrepareForRecording(); | ||||||
|  |  | ||||||
|  | @ -9,6 +9,7 @@ | ||||||
| #include "citra_qt/compatdb.h" | #include "citra_qt/compatdb.h" | ||||||
| #include "common/telemetry.h" | #include "common/telemetry.h" | ||||||
| #include "core/core.h" | #include "core/core.h" | ||||||
|  | #include "core/telemetry_session.h" | ||||||
| #include "ui_compatdb.h" | #include "ui_compatdb.h" | ||||||
| 
 | 
 | ||||||
| CompatDB::CompatDB(Core::TelemetrySession& telemetry_session_, QWidget* parent) | CompatDB::CompatDB(Core::TelemetrySession& telemetry_session_, QWidget* parent) | ||||||
|  |  | ||||||
|  | @ -6,6 +6,7 @@ | ||||||
| #include <QFileDialog> | #include <QFileDialog> | ||||||
| #include <QUrl> | #include <QUrl> | ||||||
| #include "citra_qt/configuration/configure_storage.h" | #include "citra_qt/configuration/configure_storage.h" | ||||||
|  | #include "common/file_util.h" | ||||||
| #include "common/settings.h" | #include "common/settings.h" | ||||||
| #include "core/core.h" | #include "core/core.h" | ||||||
| #include "ui_configure_storage.h" | #include "ui_configure_storage.h" | ||||||
|  |  | ||||||
|  | @ -5,11 +5,10 @@ | ||||||
| #include <array> | #include <array> | ||||||
| #include "citra_qt/debugger/wait_tree.h" | #include "citra_qt/debugger/wait_tree.h" | ||||||
| #include "citra_qt/uisettings.h" | #include "citra_qt/uisettings.h" | ||||||
| #include "citra_qt/util/util.h" |  | ||||||
| #include "common/assert.h" | #include "common/assert.h" | ||||||
| #include "common/settings.h" |  | ||||||
| #include "core/hle/kernel/event.h" | #include "core/hle/kernel/event.h" | ||||||
| #include "core/hle/kernel/mutex.h" | #include "core/hle/kernel/mutex.h" | ||||||
|  | #include "core/hle/kernel/process.h" | ||||||
| #include "core/hle/kernel/semaphore.h" | #include "core/hle/kernel/semaphore.h" | ||||||
| #include "core/hle/kernel/thread.h" | #include "core/hle/kernel/thread.h" | ||||||
| #include "core/hle/kernel/timer.h" | #include "core/hle/kernel/timer.h" | ||||||
|  |  | ||||||
|  | @ -9,10 +9,11 @@ | ||||||
| #include "citra_qt/uisettings.h" | #include "citra_qt/uisettings.h" | ||||||
| #include "common/common_types.h" | #include "common/common_types.h" | ||||||
| #include "core/core.h" | #include "core/core.h" | ||||||
|  | #include "core/loader/loader.h" | ||||||
| 
 | 
 | ||||||
| namespace DiscordRPC { | namespace DiscordRPC { | ||||||
| 
 | 
 | ||||||
| DiscordImpl::DiscordImpl() { | DiscordImpl::DiscordImpl(const Core::System& system_) : system{system_} { | ||||||
|     DiscordEventHandlers handlers{}; |     DiscordEventHandlers handlers{}; | ||||||
| 
 | 
 | ||||||
|     // The number is the client ID for Citra, it's used for images and the
 |     // The number is the client ID for Citra, it's used for images and the
 | ||||||
|  | @ -34,12 +35,15 @@ void DiscordImpl::Update() { | ||||||
|                          std::chrono::system_clock::now().time_since_epoch()) |                          std::chrono::system_clock::now().time_since_epoch()) | ||||||
|                          .count(); |                          .count(); | ||||||
|     std::string title; |     std::string title; | ||||||
|     if (Core::System::GetInstance().IsPoweredOn()) |     const bool is_powered_on = system.IsPoweredOn(); | ||||||
|         Core::System::GetInstance().GetAppLoader().ReadTitle(title); |     if (is_powered_on) { | ||||||
|  |         system.GetAppLoader().ReadTitle(title); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|     DiscordRichPresence presence{}; |     DiscordRichPresence presence{}; | ||||||
|     presence.largeImageKey = "citra"; |     presence.largeImageKey = "citra"; | ||||||
|     presence.largeImageText = "Citra is an emulator for the Nintendo 3DS"; |     presence.largeImageText = "Citra is an emulator for the Nintendo 3DS"; | ||||||
|     if (Core::System::GetInstance().IsPoweredOn()) { |     if (is_powered_on) { | ||||||
|         presence.state = title.c_str(); |         presence.state = title.c_str(); | ||||||
|         presence.details = "Currently in game"; |         presence.details = "Currently in game"; | ||||||
|     } else { |     } else { | ||||||
|  |  | ||||||
|  | @ -6,15 +6,22 @@ | ||||||
| 
 | 
 | ||||||
| #include "citra_qt/discord.h" | #include "citra_qt/discord.h" | ||||||
| 
 | 
 | ||||||
|  | namespace Core { | ||||||
|  | class System; | ||||||
|  | } | ||||||
|  | 
 | ||||||
| namespace DiscordRPC { | namespace DiscordRPC { | ||||||
| 
 | 
 | ||||||
| class DiscordImpl : public DiscordInterface { | class DiscordImpl : public DiscordInterface { | ||||||
| public: | public: | ||||||
|     DiscordImpl(); |     DiscordImpl(const Core::System& system); | ||||||
|     ~DiscordImpl() override; |     ~DiscordImpl() override; | ||||||
| 
 | 
 | ||||||
|     void Pause() override; |     void Pause() override; | ||||||
|     void Update() override; |     void Update() override; | ||||||
|  | 
 | ||||||
|  | private: | ||||||
|  |     const Core::System& system; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| } // namespace DiscordRPC
 | } // namespace DiscordRPC
 | ||||||
|  |  | ||||||
|  | @ -14,6 +14,7 @@ | ||||||
| #include <QtGui> | #include <QtGui> | ||||||
| #include <QtWidgets> | #include <QtWidgets> | ||||||
| #include <fmt/format.h> | #include <fmt/format.h> | ||||||
|  | #include "core/telemetry_session.h" | ||||||
| #ifdef __APPLE__ | #ifdef __APPLE__ | ||||||
| #include <unistd.h> // for chdir
 | #include <unistd.h> // for chdir
 | ||||||
| #endif | #endif | ||||||
|  | @ -73,7 +74,6 @@ | ||||||
| #include "common/microprofile.h" | #include "common/microprofile.h" | ||||||
| #include "common/scm_rev.h" | #include "common/scm_rev.h" | ||||||
| #include "common/scope_exit.h" | #include "common/scope_exit.h" | ||||||
| #include "common/string_util.h" |  | ||||||
| #if CITRA_ARCH(x86_64) | #if CITRA_ARCH(x86_64) | ||||||
| #include "common/x64/cpu_detect.h" | #include "common/x64/cpu_detect.h" | ||||||
| #endif | #endif | ||||||
|  | @ -173,7 +173,7 @@ static QString PrettyProductName() { | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| GMainWindow::GMainWindow(Core::System& system_) | GMainWindow::GMainWindow(Core::System& system_) | ||||||
|     : ui{std::make_unique<Ui::MainWindow>()}, system{system_}, movie{Core::Movie::GetInstance()}, |     : ui{std::make_unique<Ui::MainWindow>()}, system{system_}, movie{system.Movie()}, | ||||||
|       config{std::make_unique<Config>()}, emu_thread{nullptr} { |       config{std::make_unique<Config>()}, emu_thread{nullptr} { | ||||||
|     Common::Log::Initialize(); |     Common::Log::Initialize(); | ||||||
|     Common::Log::Start(); |     Common::Log::Start(); | ||||||
|  | @ -1413,7 +1413,7 @@ void GMainWindow::UpdateSaveStates() { | ||||||
|     if (system.GetAppLoader().ReadProgramId(title_id) != Loader::ResultStatus::Success) { |     if (system.GetAppLoader().ReadProgramId(title_id) != Loader::ResultStatus::Success) { | ||||||
|         return; |         return; | ||||||
|     } |     } | ||||||
|     auto savestates = Core::ListSaveStates(title_id); |     auto savestates = Core::ListSaveStates(title_id, movie.GetCurrentMovieID()); | ||||||
|     for (u32 i = 0; i < Core::SaveStateSlotCount; ++i) { |     for (u32 i = 0; i < Core::SaveStateSlotCount; ++i) { | ||||||
|         actions_load_state[i]->setEnabled(false); |         actions_load_state[i]->setEnabled(false); | ||||||
|         actions_load_state[i]->setText(tr("Slot %1").arg(i + 1)); |         actions_load_state[i]->setText(tr("Slot %1").arg(i + 1)); | ||||||
|  | @ -2125,7 +2125,7 @@ void GMainWindow::OnCreateGraphicsSurfaceViewer() { | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void GMainWindow::OnRecordMovie() { | void GMainWindow::OnRecordMovie() { | ||||||
|     MovieRecordDialog dialog(this); |     MovieRecordDialog dialog(this, system); | ||||||
|     if (dialog.exec() != QDialog::Accepted) { |     if (dialog.exec() != QDialog::Accepted) { | ||||||
|         return; |         return; | ||||||
|     } |     } | ||||||
|  | @ -2142,7 +2142,7 @@ void GMainWindow::OnRecordMovie() { | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void GMainWindow::OnPlayMovie() { | void GMainWindow::OnPlayMovie() { | ||||||
|     MoviePlayDialog dialog(this, game_list); |     MoviePlayDialog dialog(this, game_list, system); | ||||||
|     if (dialog.exec() != QDialog::Accepted) { |     if (dialog.exec() != QDialog::Accepted) { | ||||||
|         return; |         return; | ||||||
|     } |     } | ||||||
|  | @ -2847,7 +2847,7 @@ void GMainWindow::RetranslateStatusBar() { | ||||||
| void GMainWindow::SetDiscordEnabled([[maybe_unused]] bool state) { | void GMainWindow::SetDiscordEnabled([[maybe_unused]] bool state) { | ||||||
| #ifdef USE_DISCORD_PRESENCE | #ifdef USE_DISCORD_PRESENCE | ||||||
|     if (state) { |     if (state) { | ||||||
|         discord_rpc = std::make_unique<DiscordRPC::DiscordImpl>(); |         discord_rpc = std::make_unique<DiscordRPC::DiscordImpl>(system); | ||||||
|     } else { |     } else { | ||||||
|         discord_rpc = std::make_unique<DiscordRPC::NullImpl>(); |         discord_rpc = std::make_unique<DiscordRPC::NullImpl>(); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  | @ -15,8 +15,9 @@ | ||||||
| #include "core/movie.h" | #include "core/movie.h" | ||||||
| #include "ui_movie_play_dialog.h" | #include "ui_movie_play_dialog.h" | ||||||
| 
 | 
 | ||||||
| MoviePlayDialog::MoviePlayDialog(QWidget* parent, GameList* game_list_) | MoviePlayDialog::MoviePlayDialog(QWidget* parent, GameList* game_list_, const Core::System& system_) | ||||||
|     : QDialog(parent), ui(std::make_unique<Ui::MoviePlayDialog>()), game_list(game_list_) { |     : QDialog(parent), | ||||||
|  |       ui(std::make_unique<Ui::MoviePlayDialog>()), game_list{game_list_}, system{system_} { | ||||||
|     ui->setupUi(this); |     ui->setupUi(this); | ||||||
| 
 | 
 | ||||||
|     ui->buttonBox->button(QDialogButtonBox::Ok)->setEnabled(false); |     ui->buttonBox->button(QDialogButtonBox::Ok)->setEnabled(false); | ||||||
|  | @ -26,10 +27,10 @@ MoviePlayDialog::MoviePlayDialog(QWidget* parent, GameList* game_list_) | ||||||
|     connect(ui->buttonBox, &QDialogButtonBox::accepted, this, &MoviePlayDialog::accept); |     connect(ui->buttonBox, &QDialogButtonBox::accepted, this, &MoviePlayDialog::accept); | ||||||
|     connect(ui->buttonBox, &QDialogButtonBox::rejected, this, &MoviePlayDialog::reject); |     connect(ui->buttonBox, &QDialogButtonBox::rejected, this, &MoviePlayDialog::reject); | ||||||
| 
 | 
 | ||||||
|     if (Core::System::GetInstance().IsPoweredOn()) { |     if (system.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().GetPlayMode() == Core::Movie::PlayMode::Recording) { |         if (system.Movie().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); | ||||||
|  | @ -43,7 +44,7 @@ QString MoviePlayDialog::GetMoviePath() const { | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| QString MoviePlayDialog::GetGamePath() const { | QString MoviePlayDialog::GetGamePath() const { | ||||||
|     const auto metadata = Core::Movie::GetInstance().GetMovieMetadata(GetMoviePath().toStdString()); |     const auto metadata = system.Movie().GetMovieMetadata(GetMoviePath().toStdString()); | ||||||
|     return game_list->FindGameByProgramID(metadata.program_id, GameListItemPath::FullPathRole); |     return game_list->FindGameByProgramID(metadata.program_id, GameListItemPath::FullPathRole); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -67,9 +68,10 @@ void MoviePlayDialog::UpdateUIDisplay() { | ||||||
|     ui->lengthLineEdit->clear(); |     ui->lengthLineEdit->clear(); | ||||||
|     ui->note1Label->setVisible(true); |     ui->note1Label->setVisible(true); | ||||||
| 
 | 
 | ||||||
|  |     const auto& movie = system.Movie(); | ||||||
|     const auto path = GetMoviePath().toStdString(); |     const auto path = GetMoviePath().toStdString(); | ||||||
| 
 | 
 | ||||||
|     const auto validation_result = Core::Movie::GetInstance().ValidateMovie(path); |     const auto validation_result = movie.ValidateMovie(path); | ||||||
|     if (validation_result == Core::Movie::ValidationResult::Invalid) { |     if (validation_result == Core::Movie::ValidationResult::Invalid) { | ||||||
|         ui->note1Label->setText(tr("Invalid movie file.")); |         ui->note1Label->setText(tr("Invalid movie file.")); | ||||||
|         ui->buttonBox->button(QDialogButtonBox::Ok)->setEnabled(false); |         ui->buttonBox->button(QDialogButtonBox::Ok)->setEnabled(false); | ||||||
|  | @ -94,7 +96,7 @@ void MoviePlayDialog::UpdateUIDisplay() { | ||||||
|         UNREACHABLE(); |         UNREACHABLE(); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     const auto metadata = Core::Movie::GetInstance().GetMovieMetadata(path); |     const auto metadata = movie.GetMovieMetadata(path); | ||||||
| 
 | 
 | ||||||
|     // Format game title
 |     // Format game title
 | ||||||
|     const auto title = |     const auto title = | ||||||
|  |  | ||||||
|  | @ -11,11 +11,15 @@ namespace Ui { | ||||||
| class MoviePlayDialog; | class MoviePlayDialog; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | namespace Core { | ||||||
|  | class System; | ||||||
|  | } | ||||||
|  | 
 | ||||||
| class MoviePlayDialog : public QDialog { | class MoviePlayDialog : public QDialog { | ||||||
|     Q_OBJECT |     Q_OBJECT | ||||||
| 
 | 
 | ||||||
| public: | public: | ||||||
|     explicit MoviePlayDialog(QWidget* parent, GameList* game_list); |     explicit MoviePlayDialog(QWidget* parent, GameList* game_list, const Core::System& system); | ||||||
|     ~MoviePlayDialog() override; |     ~MoviePlayDialog() override; | ||||||
| 
 | 
 | ||||||
|     QString GetMoviePath() const; |     QString GetMoviePath() const; | ||||||
|  | @ -27,4 +31,5 @@ private: | ||||||
| 
 | 
 | ||||||
|     std::unique_ptr<Ui::MoviePlayDialog> ui; |     std::unique_ptr<Ui::MoviePlayDialog> ui; | ||||||
|     GameList* game_list; |     GameList* game_list; | ||||||
|  |     const Core::System& system; | ||||||
| }; | }; | ||||||
|  |  | ||||||
|  | @ -10,8 +10,8 @@ | ||||||
| #include "core/movie.h" | #include "core/movie.h" | ||||||
| #include "ui_movie_record_dialog.h" | #include "ui_movie_record_dialog.h" | ||||||
| 
 | 
 | ||||||
| MovieRecordDialog::MovieRecordDialog(QWidget* parent) | MovieRecordDialog::MovieRecordDialog(QWidget* parent, const Core::System& system_) | ||||||
|     : QDialog(parent), ui(std::make_unique<Ui::MovieRecordDialog>()) { |     : QDialog(parent), ui(std::make_unique<Ui::MovieRecordDialog>()), system{system_} { | ||||||
|     ui->setupUi(this); |     ui->setupUi(this); | ||||||
| 
 | 
 | ||||||
|     ui->buttonBox->button(QDialogButtonBox::Ok)->setEnabled(false); |     ui->buttonBox->button(QDialogButtonBox::Ok)->setEnabled(false); | ||||||
|  | @ -23,9 +23,9 @@ MovieRecordDialog::MovieRecordDialog(QWidget* parent) | ||||||
|     connect(ui->buttonBox, &QDialogButtonBox::rejected, this, &MovieRecordDialog::reject); |     connect(ui->buttonBox, &QDialogButtonBox::rejected, this, &MovieRecordDialog::reject); | ||||||
| 
 | 
 | ||||||
|     QString note_text; |     QString note_text; | ||||||
|     if (Core::System::GetInstance().IsPoweredOn()) { |     if (system.IsPoweredOn()) { | ||||||
|         note_text = tr("Current running game will be restarted."); |         note_text = tr("Current running game will be restarted."); | ||||||
|         if (Core::Movie::GetInstance().GetPlayMode() == Core::Movie::PlayMode::Recording) { |         if (system.Movie().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 { | ||||||
|  |  | ||||||
|  | @ -9,11 +9,15 @@ namespace Ui { | ||||||
| class MovieRecordDialog; | class MovieRecordDialog; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | namespace Core { | ||||||
|  | class System; | ||||||
|  | } | ||||||
|  | 
 | ||||||
| class MovieRecordDialog : public QDialog { | class MovieRecordDialog : public QDialog { | ||||||
|     Q_OBJECT |     Q_OBJECT | ||||||
| 
 | 
 | ||||||
| public: | public: | ||||||
|     explicit MovieRecordDialog(QWidget* parent); |     explicit MovieRecordDialog(QWidget* parent, const Core::System& system); | ||||||
|     ~MovieRecordDialog() override; |     ~MovieRecordDialog() override; | ||||||
| 
 | 
 | ||||||
|     QString GetPath() const; |     QString GetPath() const; | ||||||
|  | @ -24,4 +28,5 @@ private: | ||||||
|     void UpdateUIDisplay(); |     void UpdateUIDisplay(); | ||||||
| 
 | 
 | ||||||
|     std::unique_ptr<Ui::MovieRecordDialog> ui; |     std::unique_ptr<Ui::MovieRecordDialog> ui; | ||||||
|  |     const Core::System& system; | ||||||
| }; | }; | ||||||
|  |  | ||||||
|  | @ -2,8 +2,6 @@ | ||||||
| // Licensed under GPLv2 or any later version
 | // Licensed under GPLv2 or any later version
 | ||||||
| // Refer to the license.txt file included.
 | // Refer to the license.txt file included.
 | ||||||
| 
 | 
 | ||||||
| #include <exception> |  | ||||||
| #include <memory> |  | ||||||
| #include <stdexcept> | #include <stdexcept> | ||||||
| #include <utility> | #include <utility> | ||||||
| #include <boost/serialization/array.hpp> | #include <boost/serialization/array.hpp> | ||||||
|  | @ -16,6 +14,8 @@ | ||||||
| #include "core/arm/arm_interface.h" | #include "core/arm/arm_interface.h" | ||||||
| #include "core/arm/exclusive_monitor.h" | #include "core/arm/exclusive_monitor.h" | ||||||
| #include "core/hle/service/cam/cam.h" | #include "core/hle/service/cam/cam.h" | ||||||
|  | #include "core/hle/service/hid/hid.h" | ||||||
|  | #include "core/hle/service/ir/ir_user.h" | ||||||
| #if CITRA_ARCH(x86_64) || CITRA_ARCH(arm64) | #if CITRA_ARCH(x86_64) || CITRA_ARCH(arm64) | ||||||
| #include "core/arm/dynarmic/arm_dynarmic.h" | #include "core/arm/dynarmic/arm_dynarmic.h" | ||||||
| #endif | #endif | ||||||
|  | @ -35,9 +35,7 @@ | ||||||
| #include "core/hle/service/cam/cam.h" | #include "core/hle/service/cam/cam.h" | ||||||
| #include "core/hle/service/fs/archive.h" | #include "core/hle/service/fs/archive.h" | ||||||
| #include "core/hle/service/gsp/gsp.h" | #include "core/hle/service/gsp/gsp.h" | ||||||
| #include "core/hle/service/hid/hid.h" |  | ||||||
| #include "core/hle/service/ir/ir_rst.h" | #include "core/hle/service/ir/ir_rst.h" | ||||||
| #include "core/hle/service/ir/ir_user.h" |  | ||||||
| #include "core/hle/service/mic_u.h" | #include "core/hle/service/mic_u.h" | ||||||
| #include "core/hle/service/plgldr/plgldr.h" | #include "core/hle/service/plgldr/plgldr.h" | ||||||
| #include "core/hle/service/service.h" | #include "core/hle/service/service.h" | ||||||
|  | @ -48,6 +46,7 @@ | ||||||
| #include "core/loader/loader.h" | #include "core/loader/loader.h" | ||||||
| #include "core/movie.h" | #include "core/movie.h" | ||||||
| #include "core/rpc/server.h" | #include "core/rpc/server.h" | ||||||
|  | #include "core/telemetry_session.h" | ||||||
| #include "network/network.h" | #include "network/network.h" | ||||||
| #include "video_core/custom_textures/custom_tex_manager.h" | #include "video_core/custom_textures/custom_tex_manager.h" | ||||||
| #include "video_core/renderer_base.h" | #include "video_core/renderer_base.h" | ||||||
|  | @ -72,6 +71,8 @@ Core::Timing& Global() { | ||||||
|     return System::GetInstance().CoreTiming(); |     return System::GetInstance().CoreTiming(); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | System::System() : movie{*this} {} | ||||||
|  | 
 | ||||||
| System::~System() = default; | System::~System() = default; | ||||||
| 
 | 
 | ||||||
| System::ResultStatus System::RunLoop(bool tight_loop) { | System::ResultStatus System::RunLoop(bool tight_loop) { | ||||||
|  | @ -372,7 +373,8 @@ System::ResultStatus System::Init(Frontend::EmuWindow& emu_window, | ||||||
|     timing = std::make_unique<Timing>(num_cores, Settings::values.cpu_clock_percentage.GetValue()); |     timing = std::make_unique<Timing>(num_cores, Settings::values.cpu_clock_percentage.GetValue()); | ||||||
| 
 | 
 | ||||||
|     kernel = std::make_unique<Kernel::KernelSystem>( |     kernel = std::make_unique<Kernel::KernelSystem>( | ||||||
|         *memory, *timing, [this] { PrepareReschedule(); }, memory_mode, num_cores, n3ds_hw_caps); |         *memory, *timing, [this] { PrepareReschedule(); }, memory_mode, num_cores, n3ds_hw_caps, | ||||||
|  |         movie.GetOverrideInitTime()); | ||||||
| 
 | 
 | ||||||
|     exclusive_monitor = MakeExclusiveMonitor(*memory, num_cores); |     exclusive_monitor = MakeExclusiveMonitor(*memory, num_cores); | ||||||
|     cpu_cores.reserve(num_cores); |     cpu_cores.reserve(num_cores); | ||||||
|  | @ -508,6 +510,14 @@ const VideoCore::CustomTexManager& System::CustomTexManager() const { | ||||||
|     return *custom_tex_manager; |     return *custom_tex_manager; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | Core::Movie& System::Movie() { | ||||||
|  |     return movie; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | const Core::Movie& System::Movie() const { | ||||||
|  |     return movie; | ||||||
|  | } | ||||||
|  | 
 | ||||||
| void System::RegisterMiiSelector(std::shared_ptr<Frontend::MiiSelector> mii_selector) { | void System::RegisterMiiSelector(std::shared_ptr<Frontend::MiiSelector> mii_selector) { | ||||||
|     registered_mii_selector = std::move(mii_selector); |     registered_mii_selector = std::move(mii_selector); | ||||||
| } | } | ||||||
|  | @ -702,7 +712,7 @@ void System::serialize(Archive& ar, const unsigned int file_version) { | ||||||
|     ar&* kernel.get(); |     ar&* kernel.get(); | ||||||
|     VideoCore::serialize(ar, file_version); |     VideoCore::serialize(ar, file_version); | ||||||
|     if (file_version >= 1) { |     if (file_version >= 1) { | ||||||
|         ar& Movie::GetInstance(); |         ar& movie; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     // This needs to be set from somewhere - might as well be here!
 |     // This needs to be set from somewhere - might as well be here!
 | ||||||
|  |  | ||||||
|  | @ -10,18 +10,17 @@ | ||||||
| #include <string> | #include <string> | ||||||
| #include <boost/serialization/version.hpp> | #include <boost/serialization/version.hpp> | ||||||
| #include "common/common_types.h" | #include "common/common_types.h" | ||||||
| #include "core/frontend/applets/mii_selector.h" | #include "core/arm/arm_interface.h" | ||||||
| #include "core/frontend/applets/swkbd.h" | #include "core/movie.h" | ||||||
| #include "core/loader/loader.h" |  | ||||||
| #include "core/memory.h" |  | ||||||
| #include "core/perf_stats.h" | #include "core/perf_stats.h" | ||||||
| #include "core/telemetry_session.h" |  | ||||||
| 
 | 
 | ||||||
| class ARM_Interface; | class ARM_Interface; | ||||||
| 
 | 
 | ||||||
| namespace Frontend { | namespace Frontend { | ||||||
| class EmuWindow; | class EmuWindow; | ||||||
| class ImageInterface; | class ImageInterface; | ||||||
|  | class MiiSelector; | ||||||
|  | class SoftwareKeyboard; | ||||||
| } // namespace Frontend
 | } // namespace Frontend
 | ||||||
| 
 | 
 | ||||||
| namespace Memory { | namespace Memory { | ||||||
|  | @ -47,7 +46,9 @@ class ArchiveManager; | ||||||
| 
 | 
 | ||||||
| namespace Kernel { | namespace Kernel { | ||||||
| class KernelSystem; | class KernelSystem; | ||||||
| } | struct New3dsHwCapabilities; | ||||||
|  | enum class MemoryMode : u8; | ||||||
|  | } // namespace Kernel
 | ||||||
| 
 | 
 | ||||||
| namespace Cheats { | namespace Cheats { | ||||||
| class CheatEngine; | class CheatEngine; | ||||||
|  | @ -62,8 +63,13 @@ class CustomTexManager; | ||||||
| class RendererBase; | class RendererBase; | ||||||
| } // namespace VideoCore
 | } // namespace VideoCore
 | ||||||
| 
 | 
 | ||||||
|  | namespace Loader { | ||||||
|  | class AppLoader; | ||||||
|  | } | ||||||
|  | 
 | ||||||
| namespace Core { | namespace Core { | ||||||
| 
 | 
 | ||||||
|  | class TelemetrySession; | ||||||
| class ExclusiveMonitor; | class ExclusiveMonitor; | ||||||
| class Timing; | class Timing; | ||||||
| 
 | 
 | ||||||
|  | @ -95,6 +101,7 @@ public: | ||||||
|         ErrorUnknown               ///< Any other error
 |         ErrorUnknown               ///< Any other error
 | ||||||
|     }; |     }; | ||||||
| 
 | 
 | ||||||
|  |     explicit System(); | ||||||
|     ~System(); |     ~System(); | ||||||
| 
 | 
 | ||||||
|     /**
 |     /**
 | ||||||
|  | @ -258,6 +265,12 @@ public: | ||||||
|     /// Gets a const reference to the custom texture cache system
 |     /// Gets a const reference to the custom texture cache system
 | ||||||
|     [[nodiscard]] const VideoCore::CustomTexManager& CustomTexManager() const; |     [[nodiscard]] const VideoCore::CustomTexManager& CustomTexManager() const; | ||||||
| 
 | 
 | ||||||
|  |     /// Gets a reference to the movie recorder
 | ||||||
|  |     [[nodiscard]] Core::Movie& Movie(); | ||||||
|  | 
 | ||||||
|  |     /// Gets a const reference to the movie recorder
 | ||||||
|  |     [[nodiscard]] const Core::Movie& Movie() const; | ||||||
|  | 
 | ||||||
|     /// Video Dumper interface
 |     /// Video Dumper interface
 | ||||||
| 
 | 
 | ||||||
|     void RegisterVideoDumper(std::shared_ptr<VideoDumper::Backend> video_dumper); |     void RegisterVideoDumper(std::shared_ptr<VideoDumper::Backend> video_dumper); | ||||||
|  | @ -373,6 +386,9 @@ private: | ||||||
|     std::shared_ptr<Frontend::MiiSelector> registered_mii_selector; |     std::shared_ptr<Frontend::MiiSelector> registered_mii_selector; | ||||||
|     std::shared_ptr<Frontend::SoftwareKeyboard> registered_swkbd; |     std::shared_ptr<Frontend::SoftwareKeyboard> registered_swkbd; | ||||||
| 
 | 
 | ||||||
|  |     /// Movie recorder
 | ||||||
|  |     Core::Movie movie; | ||||||
|  | 
 | ||||||
|     /// Cheats manager
 |     /// Cheats manager
 | ||||||
|     std::unique_ptr<Cheats::CheatEngine> cheat_engine; |     std::unique_ptr<Cheats::CheatEngine> cheat_engine; | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -12,8 +12,8 @@ | ||||||
| #include "common/common_types.h" | #include "common/common_types.h" | ||||||
| #include "common/file_util.h" | #include "common/file_util.h" | ||||||
| #include "common/swap.h" | #include "common/swap.h" | ||||||
| #include "core/core.h" |  | ||||||
| #include "core/file_sys/romfs_reader.h" | #include "core/file_sys/romfs_reader.h" | ||||||
|  | #include "core/loader/loader.h" | ||||||
| 
 | 
 | ||||||
| enum NCSDContentIndex { Main = 0, Manual = 1, DLP = 2, New3DSUpdate = 6, Update = 7 }; | enum NCSDContentIndex { Main = 0, Manual = 1, DLP = 2, New3DSUpdate = 6, Update = 7 }; | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -4,6 +4,7 @@ | ||||||
| 
 | 
 | ||||||
| #include <algorithm> | #include <algorithm> | ||||||
| #include <vector> | #include <vector> | ||||||
|  | #include "common/archives.h" | ||||||
| #include "common/assert.h" | #include "common/assert.h" | ||||||
| #include "common/common_types.h" | #include "common/common_types.h" | ||||||
| #include "core/core.h" | #include "core/core.h" | ||||||
|  |  | ||||||
|  | @ -25,13 +25,13 @@ namespace Kernel { | ||||||
| KernelSystem::KernelSystem(Memory::MemorySystem& memory, Core::Timing& timing, | KernelSystem::KernelSystem(Memory::MemorySystem& memory, Core::Timing& timing, | ||||||
|                            std::function<void()> prepare_reschedule_callback, |                            std::function<void()> prepare_reschedule_callback, | ||||||
|                            MemoryMode memory_mode, u32 num_cores, |                            MemoryMode memory_mode, u32 num_cores, | ||||||
|                            const New3dsHwCapabilities& n3ds_hw_caps) |                            const New3dsHwCapabilities& n3ds_hw_caps, u64 override_init_time) | ||||||
|     : memory(memory), timing(timing), |     : memory(memory), timing(timing), | ||||||
|       prepare_reschedule_callback(std::move(prepare_reschedule_callback)), memory_mode(memory_mode), |       prepare_reschedule_callback(std::move(prepare_reschedule_callback)), memory_mode(memory_mode), | ||||||
|       n3ds_hw_caps(n3ds_hw_caps) { |       n3ds_hw_caps(n3ds_hw_caps) { | ||||||
|     std::generate(memory_regions.begin(), memory_regions.end(), |     std::generate(memory_regions.begin(), memory_regions.end(), | ||||||
|                   [] { return std::make_shared<MemoryRegionInfo>(); }); |                   [] { return std::make_shared<MemoryRegionInfo>(); }); | ||||||
|     MemoryInit(memory_mode, n3ds_hw_caps.memory_mode); |     MemoryInit(memory_mode, n3ds_hw_caps.memory_mode, override_init_time); | ||||||
| 
 | 
 | ||||||
|     resource_limits = std::make_unique<ResourceLimitList>(*this); |     resource_limits = std::make_unique<ResourceLimitList>(*this); | ||||||
|     for (u32 core_id = 0; core_id < num_cores; ++core_id) { |     for (u32 core_id = 0; core_id < num_cores; ++core_id) { | ||||||
|  |  | ||||||
|  | @ -134,7 +134,8 @@ class KernelSystem { | ||||||
| public: | public: | ||||||
|     explicit KernelSystem(Memory::MemorySystem& memory, Core::Timing& timing, |     explicit KernelSystem(Memory::MemorySystem& memory, Core::Timing& timing, | ||||||
|                           std::function<void()> prepare_reschedule_callback, MemoryMode memory_mode, |                           std::function<void()> prepare_reschedule_callback, MemoryMode memory_mode, | ||||||
|                           u32 num_cores, const New3dsHwCapabilities& n3ds_hw_caps); |                           u32 num_cores, const New3dsHwCapabilities& n3ds_hw_caps, | ||||||
|  |                           u64 override_init_time = 0); | ||||||
|     ~KernelSystem(); |     ~KernelSystem(); | ||||||
| 
 | 
 | ||||||
|     using PortPair = std::pair<std::shared_ptr<ServerPort>, std::shared_ptr<ClientPort>>; |     using PortPair = std::pair<std::shared_ptr<ServerPort>, std::shared_ptr<ClientPort>>; | ||||||
|  | @ -330,7 +331,7 @@ public: | ||||||
|     Core::Timing& timing; |     Core::Timing& timing; | ||||||
| 
 | 
 | ||||||
| private: | private: | ||||||
|     void MemoryInit(MemoryMode memory_mode, New3dsMemoryMode n3ds_mode); |     void MemoryInit(MemoryMode memory_mode, New3dsMemoryMode n3ds_mode, u64 override_init_time); | ||||||
| 
 | 
 | ||||||
|     std::function<void()> prepare_reschedule_callback; |     std::function<void()> prepare_reschedule_callback; | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -37,7 +37,8 @@ static const u32 memory_region_sizes[8][3] = { | ||||||
|     {0x0B200000, 0x02E00000, 0x02000000}, // 7
 |     {0x0B200000, 0x02E00000, 0x02000000}, // 7
 | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| void KernelSystem::MemoryInit(MemoryMode memory_mode, New3dsMemoryMode n3ds_mode) { | void KernelSystem::MemoryInit(MemoryMode memory_mode, New3dsMemoryMode n3ds_mode, | ||||||
|  |                               u64 override_init_time) { | ||||||
|     const bool is_new_3ds = Settings::values.is_new_3ds.GetValue(); |     const bool is_new_3ds = Settings::values.is_new_3ds.GetValue(); | ||||||
|     u32 mem_type_index = static_cast<u32>(memory_mode); |     u32 mem_type_index = static_cast<u32>(memory_mode); | ||||||
|     u32 reported_mem_type = static_cast<u32>(memory_mode); |     u32 reported_mem_type = static_cast<u32>(memory_mode); | ||||||
|  | @ -73,7 +74,7 @@ void KernelSystem::MemoryInit(MemoryMode memory_mode, New3dsMemoryMode n3ds_mode | ||||||
|     config_mem.sys_mem_alloc = memory_regions[1]->size; |     config_mem.sys_mem_alloc = memory_regions[1]->size; | ||||||
|     config_mem.base_mem_alloc = memory_regions[2]->size; |     config_mem.base_mem_alloc = memory_regions[2]->size; | ||||||
| 
 | 
 | ||||||
|     shared_page_handler = std::make_shared<SharedPage::Handler>(timing); |     shared_page_handler = std::make_shared<SharedPage::Handler>(timing, override_init_time); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| std::shared_ptr<MemoryRegionInfo> KernelSystem::GetMemoryRegion(MemoryRegion region) { | std::shared_ptr<MemoryRegionInfo> KernelSystem::GetMemoryRegion(MemoryRegion region) { | ||||||
|  |  | ||||||
|  | @ -19,7 +19,8 @@ namespace boost::serialization { | ||||||
| 
 | 
 | ||||||
| template <class Archive> | template <class Archive> | ||||||
| void load_construct_data(Archive& ar, SharedPage::Handler* t, const unsigned int) { | void load_construct_data(Archive& ar, SharedPage::Handler* t, const unsigned int) { | ||||||
|     ::new (t) SharedPage::Handler(Core::System::GetInstance().CoreTiming()); |     ::new (t) SharedPage::Handler(Core::System::GetInstance().CoreTiming(), | ||||||
|  |                                   Core::System::GetInstance().Movie().GetOverrideInitTime()); | ||||||
| } | } | ||||||
| template void load_construct_data<iarchive>(iarchive& ar, SharedPage::Handler* t, | template void load_construct_data<iarchive>(iarchive& ar, SharedPage::Handler* t, | ||||||
|                                             const unsigned int); |                                             const unsigned int); | ||||||
|  | @ -28,8 +29,7 @@ template void load_construct_data<iarchive>(iarchive& ar, SharedPage::Handler* t | ||||||
| 
 | 
 | ||||||
| namespace SharedPage { | namespace SharedPage { | ||||||
| 
 | 
 | ||||||
| static std::chrono::seconds GetInitTime() { | static std::chrono::seconds GetInitTime(u64 override_init_time) { | ||||||
|     const u64 override_init_time = Core::Movie::GetInstance().GetOverrideInitTime(); |  | ||||||
|     if (override_init_time != 0) { |     if (override_init_time != 0) { | ||||||
|         // Override the clock init time with the one in the movie
 |         // Override the clock init time with the one in the movie
 | ||||||
|         return std::chrono::seconds(override_init_time); |         return std::chrono::seconds(override_init_time); | ||||||
|  | @ -62,7 +62,7 @@ static std::chrono::seconds GetInitTime() { | ||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| Handler::Handler(Core::Timing& timing) : timing(timing) { | Handler::Handler(Core::Timing& timing, u64 override_init_time) : timing(timing) { | ||||||
|     std::memset(&shared_page, 0, sizeof(shared_page)); |     std::memset(&shared_page, 0, sizeof(shared_page)); | ||||||
| 
 | 
 | ||||||
|     shared_page.running_hw = 0x1; // product
 |     shared_page.running_hw = 0x1; // product
 | ||||||
|  | @ -76,7 +76,7 @@ Handler::Handler(Core::Timing& timing) : timing(timing) { | ||||||
|     shared_page.battery_state.is_adapter_connected.Assign(1); |     shared_page.battery_state.is_adapter_connected.Assign(1); | ||||||
|     shared_page.battery_state.is_charging.Assign(1); |     shared_page.battery_state.is_charging.Assign(1); | ||||||
| 
 | 
 | ||||||
|     init_time = GetInitTime(); |     init_time = GetInitTime(override_init_time); | ||||||
| 
 | 
 | ||||||
|     using namespace std::placeholders; |     using namespace std::placeholders; | ||||||
|     update_time_event = timing.RegisterEvent("SharedPage::UpdateTimeCallback", |     update_time_event = timing.RegisterEvent("SharedPage::UpdateTimeCallback", | ||||||
|  |  | ||||||
|  | @ -86,7 +86,7 @@ static_assert(sizeof(SharedPageDef) == Memory::SHARED_PAGE_SIZE, | ||||||
| 
 | 
 | ||||||
| class Handler : public BackingMem { | class Handler : public BackingMem { | ||||||
| public: | public: | ||||||
|     Handler(Core::Timing& timing); |     Handler(Core::Timing& timing, u64 override_init_time); | ||||||
| 
 | 
 | ||||||
|     void SetMacAddress(const MacAddress&); |     void SetMacAddress(const MacAddress&); | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -5,6 +5,7 @@ | ||||||
| #include <algorithm> | #include <algorithm> | ||||||
| #include <array> | #include <array> | ||||||
| #include <fmt/format.h> | #include <fmt/format.h> | ||||||
|  | #include "common/archives.h" | ||||||
| #include "common/logging/log.h" | #include "common/logging/log.h" | ||||||
| #include "common/microprofile.h" | #include "common/microprofile.h" | ||||||
| #include "common/scm_rev.h" | #include "common/scm_rev.h" | ||||||
|  | @ -38,7 +39,6 @@ | ||||||
| #include "core/hle/lock.h" | #include "core/hle/lock.h" | ||||||
| #include "core/hle/result.h" | #include "core/hle/result.h" | ||||||
| #include "core/hle/service/plgldr/plgldr.h" | #include "core/hle/service/plgldr/plgldr.h" | ||||||
| #include "core/hle/service/service.h" |  | ||||||
| 
 | 
 | ||||||
| namespace Kernel { | namespace Kernel { | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -13,6 +13,7 @@ | ||||||
| #include <boost/serialization/split_member.hpp> | #include <boost/serialization/split_member.hpp> | ||||||
| #include "common/common_types.h" | #include "common/common_types.h" | ||||||
| #include "common/memory_ref.h" | #include "common/memory_ref.h" | ||||||
|  | #include "core/hle/kernel/memory.h" | ||||||
| #include "core/hle/result.h" | #include "core/hle/result.h" | ||||||
| #include "core/memory.h" | #include "core/memory.h" | ||||||
| #include "core/mmio.h" | #include "core/mmio.h" | ||||||
|  |  | ||||||
|  | @ -4,6 +4,7 @@ | ||||||
| 
 | 
 | ||||||
| #include "core/core.h" | #include "core/core.h" | ||||||
| #include "core/hle/ipc_helpers.h" | #include "core/hle/ipc_helpers.h" | ||||||
|  | #include "core/hle/kernel/shared_memory.h" | ||||||
| #include "core/hle/service/act/act.h" | #include "core/hle/service/act/act.h" | ||||||
| #include "core/hle/service/act/act_a.h" | #include "core/hle/service/act/act_a.h" | ||||||
| #include "core/hle/service/act/act_u.h" | #include "core/hle/service/act/act_u.h" | ||||||
|  |  | ||||||
|  | @ -2,6 +2,8 @@ | ||||||
| // Licensed under GPLv2 or any later version
 | // Licensed under GPLv2 or any later version
 | ||||||
| // Refer to the license.txt file included.
 | // Refer to the license.txt file included.
 | ||||||
| 
 | 
 | ||||||
|  | #include "common/archives.h" | ||||||
|  | #include "common/file_util.h" | ||||||
| #include "common/settings.h" | #include "common/settings.h" | ||||||
| #include "core/core.h" | #include "core/core.h" | ||||||
| #include "core/frontend/input.h" | #include "core/frontend/input.h" | ||||||
|  |  | ||||||
|  | @ -33,6 +33,8 @@ | ||||||
| #include "core/hle/service/service.h" | #include "core/hle/service/service.h" | ||||||
| #include "core/hw/aes/ccm.h" | #include "core/hw/aes/ccm.h" | ||||||
| #include "core/hw/aes/key.h" | #include "core/hw/aes/key.h" | ||||||
|  | #include "core/loader/loader.h" | ||||||
|  | #include "core/telemetry_session.h" | ||||||
| 
 | 
 | ||||||
| SERVICE_CONSTRUCT_IMPL(Service::APT::Module) | SERVICE_CONSTRUCT_IMPL(Service::APT::Module) | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -5,9 +5,9 @@ | ||||||
| #include <array> | #include <array> | ||||||
| #include <cstring> | #include <cstring> | ||||||
| #include <vector> | #include <vector> | ||||||
|  | #include "common/archives.h" | ||||||
| #include "common/assert.h" | #include "common/assert.h" | ||||||
| #include "common/logging/log.h" | #include "common/logging/log.h" | ||||||
| #include "common/string_util.h" |  | ||||||
| #include "core/core.h" | #include "core/core.h" | ||||||
| #include "core/hle/ipc_helpers.h" | #include "core/hle/ipc_helpers.h" | ||||||
| #include "core/hle/kernel/event.h" | #include "core/hle/kernel/event.h" | ||||||
|  |  | ||||||
|  | @ -150,7 +150,7 @@ void Module::UpdatePadCallback(std::uintptr_t user_data, s64 cycles_late) { | ||||||
|     circle_pad_old_y.erase(circle_pad_old_y.begin()); |     circle_pad_old_y.erase(circle_pad_old_y.begin()); | ||||||
|     circle_pad_old_y.push_back(circle_pad_new_y); |     circle_pad_old_y.push_back(circle_pad_new_y); | ||||||
| 
 | 
 | ||||||
|     Core::Movie::GetInstance().HandlePadAndCircleStatus(state, circle_pad_x, circle_pad_y); |     system.Movie().HandlePadAndCircleStatus(state, circle_pad_x, circle_pad_y); | ||||||
| 
 | 
 | ||||||
|     const DirectionState direction = GetStickDirectionState(circle_pad_x, circle_pad_y); |     const DirectionState direction = GetStickDirectionState(circle_pad_x, circle_pad_y); | ||||||
|     state.circle_up.Assign(direction.up); |     state.circle_up.Assign(direction.up); | ||||||
|  | @ -200,7 +200,7 @@ void Module::UpdatePadCallback(std::uintptr_t user_data, s64 cycles_late) { | ||||||
|     touch_entry.y = static_cast<u16>(y * Core::kScreenBottomHeight); |     touch_entry.y = static_cast<u16>(y * Core::kScreenBottomHeight); | ||||||
|     touch_entry.valid.Assign(pressed ? 1 : 0); |     touch_entry.valid.Assign(pressed ? 1 : 0); | ||||||
| 
 | 
 | ||||||
|     Core::Movie::GetInstance().HandleTouchStatus(touch_entry); |     system.Movie().HandleTouchStatus(touch_entry); | ||||||
| 
 | 
 | ||||||
|     // TODO(bunnei): We're not doing anything with offset 0xA8 + 0x18 of HID SharedMemory, which
 |     // TODO(bunnei): We're not doing anything with offset 0xA8 + 0x18 of HID SharedMemory, which
 | ||||||
|     // supposedly is "Touch-screen entry, which contains the raw coordinate data prior to being
 |     // supposedly is "Touch-screen entry, which contains the raw coordinate data prior to being
 | ||||||
|  | @ -246,7 +246,7 @@ void Module::UpdateAccelerometerCallback(std::uintptr_t user_data, s64 cycles_la | ||||||
|     accelerometer_entry.y = static_cast<s16>(accel.y); |     accelerometer_entry.y = static_cast<s16>(accel.y); | ||||||
|     accelerometer_entry.z = static_cast<s16>(accel.z); |     accelerometer_entry.z = static_cast<s16>(accel.z); | ||||||
| 
 | 
 | ||||||
|     Core::Movie::GetInstance().HandleAccelerometerStatus(accelerometer_entry); |     system.Movie().HandleAccelerometerStatus(accelerometer_entry); | ||||||
| 
 | 
 | ||||||
|     // Make up "raw" entry
 |     // Make up "raw" entry
 | ||||||
|     // TODO(wwylele):
 |     // TODO(wwylele):
 | ||||||
|  | @ -287,7 +287,7 @@ void Module::UpdateGyroscopeCallback(std::uintptr_t user_data, s64 cycles_late) | ||||||
|     gyroscope_entry.y = static_cast<s16>(gyro.y); |     gyroscope_entry.y = static_cast<s16>(gyro.y); | ||||||
|     gyroscope_entry.z = static_cast<s16>(gyro.z); |     gyroscope_entry.z = static_cast<s16>(gyro.z); | ||||||
| 
 | 
 | ||||||
|     Core::Movie::GetInstance().HandleGyroscopeStatus(gyroscope_entry); |     system.Movie().HandleGyroscopeStatus(gyroscope_entry); | ||||||
| 
 | 
 | ||||||
|     // Make up "raw" entry
 |     // Make up "raw" entry
 | ||||||
|     mem->gyroscope.raw_entry.x = gyroscope_entry.x; |     mem->gyroscope.raw_entry.x = gyroscope_entry.x; | ||||||
|  |  | ||||||
|  | @ -5,8 +5,6 @@ | ||||||
| #include <fmt/format.h> | #include <fmt/format.h> | ||||||
| #include "common/alignment.h" | #include "common/alignment.h" | ||||||
| #include "common/settings.h" | #include "common/settings.h" | ||||||
| #include "common/string_util.h" |  | ||||||
| #include "core/core.h" |  | ||||||
| #include "core/core_timing.h" | #include "core/core_timing.h" | ||||||
| #include "core/hle/service/ir/extra_hid.h" | #include "core/hle/service/ir/extra_hid.h" | ||||||
| #include "core/movie.h" | #include "core/movie.h" | ||||||
|  | @ -65,7 +63,8 @@ enum class ResponseID : u8 { | ||||||
|     ReadCalibrationData = 0x11, |     ReadCalibrationData = 0x11, | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| ExtraHID::ExtraHID(SendFunc send_func, Core::Timing& timing) : IRDevice(send_func), timing(timing) { | ExtraHID::ExtraHID(SendFunc send_func, Core::Timing& timing_, Core::Movie& movie_) | ||||||
|  |     : IRDevice(send_func), timing{timing_}, movie{movie_} { | ||||||
|     LoadInputDevices(); |     LoadInputDevices(); | ||||||
| 
 | 
 | ||||||
|     // The data below was retrieved from a New 3DS
 |     // The data below was retrieved from a New 3DS
 | ||||||
|  | @ -249,7 +248,7 @@ void ExtraHID::SendHIDStatus() { | ||||||
|     response.buttons.r_not_held.Assign(1); |     response.buttons.r_not_held.Assign(1); | ||||||
|     response.unknown = 0; |     response.unknown = 0; | ||||||
| 
 | 
 | ||||||
|     Core::Movie::GetInstance().HandleExtraHidResponse(response); |     movie.HandleExtraHidResponse(response); | ||||||
| 
 | 
 | ||||||
|     std::vector<u8> response_buffer(sizeof(response)); |     std::vector<u8> response_buffer(sizeof(response)); | ||||||
|     memcpy(response_buffer.data(), &response, sizeof(response)); |     memcpy(response_buffer.data(), &response, sizeof(response)); | ||||||
|  |  | ||||||
|  | @ -16,6 +16,7 @@ | ||||||
| namespace Core { | namespace Core { | ||||||
| struct TimingEventType; | struct TimingEventType; | ||||||
| class Timing; | class Timing; | ||||||
|  | class Movie; | ||||||
| } // namespace Core
 | } // namespace Core
 | ||||||
| 
 | 
 | ||||||
| namespace Service::IR { | namespace Service::IR { | ||||||
|  | @ -43,7 +44,7 @@ static_assert(sizeof(ExtraHIDResponse) == 6, "HID status response has wrong size | ||||||
|  */ |  */ | ||||||
| class ExtraHID final : public IRDevice { | class ExtraHID final : public IRDevice { | ||||||
| public: | public: | ||||||
|     explicit ExtraHID(SendFunc send_func, Core::Timing& timing); |     explicit ExtraHID(SendFunc send_func, Core::Timing& timing, Core::Movie& movie); | ||||||
|     ~ExtraHID(); |     ~ExtraHID(); | ||||||
| 
 | 
 | ||||||
|     void OnConnect() override; |     void OnConnect() override; | ||||||
|  | @ -60,6 +61,7 @@ private: | ||||||
|     void LoadInputDevices(); |     void LoadInputDevices(); | ||||||
| 
 | 
 | ||||||
|     Core::Timing& timing; |     Core::Timing& timing; | ||||||
|  |     Core::Movie& movie; | ||||||
|     u8 hid_period; |     u8 hid_period; | ||||||
|     Core::TimingEventType* hid_polling_callback_id; |     Core::TimingEventType* hid_polling_callback_id; | ||||||
|     std::array<u8, 0x40> calibration_data; |     std::array<u8, 0x40> calibration_data; | ||||||
|  |  | ||||||
|  | @ -83,7 +83,7 @@ void IR_RST::UpdateCallback(std::uintptr_t user_data, s64 cycles_late) { | ||||||
|     s16 c_stick_x = static_cast<s16>(c_stick_x_f * MAX_CSTICK_RADIUS); |     s16 c_stick_x = static_cast<s16>(c_stick_x_f * MAX_CSTICK_RADIUS); | ||||||
|     s16 c_stick_y = static_cast<s16>(c_stick_y_f * MAX_CSTICK_RADIUS); |     s16 c_stick_y = static_cast<s16>(c_stick_y_f * MAX_CSTICK_RADIUS); | ||||||
| 
 | 
 | ||||||
|     Core::Movie::GetInstance().HandleIrRst(state, c_stick_x, c_stick_y); |     system.Movie().HandleIrRst(state, c_stick_x, c_stick_y); | ||||||
| 
 | 
 | ||||||
|     if (!raw_c_stick) { |     if (!raw_c_stick) { | ||||||
|         const HID::DirectionState direction = HID::GetStickDirectionState(c_stick_x, c_stick_y); |         const HID::DirectionState direction = HID::GetStickDirectionState(c_stick_x, c_stick_y); | ||||||
|  |  | ||||||
|  | @ -9,7 +9,7 @@ | ||||||
| #include <boost/serialization/shared_ptr.hpp> | #include <boost/serialization/shared_ptr.hpp> | ||||||
| #include <boost/serialization/unique_ptr.hpp> | #include <boost/serialization/unique_ptr.hpp> | ||||||
| #include <fmt/format.h> | #include <fmt/format.h> | ||||||
| #include "common/string_util.h" | #include "common/archives.h" | ||||||
| #include "common/swap.h" | #include "common/swap.h" | ||||||
| #include "core/core.h" | #include "core/core.h" | ||||||
| #include "core/hle/ipc_helpers.h" | #include "core/hle/ipc_helpers.h" | ||||||
|  | @ -467,7 +467,7 @@ IR_USER::IR_USER(Core::System& system) : ServiceFramework("ir:USER", 1) { | ||||||
|     receive_event = system.Kernel().CreateEvent(ResetType::OneShot, "IR:ReceiveEvent"); |     receive_event = system.Kernel().CreateEvent(ResetType::OneShot, "IR:ReceiveEvent"); | ||||||
| 
 | 
 | ||||||
|     extra_hid = std::make_unique<ExtraHID>([this](std::span<const u8> data) { PutToReceive(data); }, |     extra_hid = std::make_unique<ExtraHID>([this](std::span<const u8> data) { PutToReceive(data); }, | ||||||
|                                            system.CoreTiming()); |                                            system.CoreTiming(), system.Movie()); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| IR_USER::~IR_USER() { | IR_USER::~IR_USER() { | ||||||
|  |  | ||||||
|  | @ -7,13 +7,14 @@ | ||||||
| #include <boost/crc.hpp> | #include <boost/crc.hpp> | ||||||
| #include <cryptopp/osrng.h> | #include <cryptopp/osrng.h> | ||||||
| 
 | 
 | ||||||
|  | #include "common/file_util.h" | ||||||
| #include "common/logging/log.h" | #include "common/logging/log.h" | ||||||
| #include "common/string_util.h" |  | ||||||
| #include "core/core.h" | #include "core/core.h" | ||||||
| #include "core/hle/kernel/shared_page.h" | #include "core/hle/kernel/shared_page.h" | ||||||
| #include "core/hle/service/nfc/amiibo_crypto.h" | #include "core/hle/service/nfc/amiibo_crypto.h" | ||||||
| #include "core/hle/service/nfc/nfc_device.h" | #include "core/hle/service/nfc/nfc_device.h" | ||||||
| #include "core/hw/aes/key.h" | #include "core/hw/aes/key.h" | ||||||
|  | #include "core/loader/loader.h" | ||||||
| 
 | 
 | ||||||
| SERVICE_CONSTRUCT_IMPL(Service::NFC::NfcDevice) | SERVICE_CONSTRUCT_IMPL(Service::NFC::NfcDevice) | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -6,6 +6,7 @@ | ||||||
| #include "common/string_util.h" | #include "common/string_util.h" | ||||||
| #include "core/core.h" | #include "core/core.h" | ||||||
| #include "core/hle/ipc_helpers.h" | #include "core/hle/ipc_helpers.h" | ||||||
|  | #include "core/hle/kernel/event.h" | ||||||
| #include "core/hle/service/nim/nim_u.h" | #include "core/hle/service/nim/nim_u.h" | ||||||
| 
 | 
 | ||||||
| SERVICE_CONSTRUCT_IMPL(Service::NIM::NIM_U) | SERVICE_CONSTRUCT_IMPL(Service::NIM::NIM_U) | ||||||
|  |  | ||||||
|  | @ -53,6 +53,7 @@ | ||||||
| #include "core/hle/service/soc_u.h" | #include "core/hle/service/soc_u.h" | ||||||
| #include "core/hle/service/ssl_c.h" | #include "core/hle/service/ssl_c.h" | ||||||
| #include "core/hle/service/y2r_u.h" | #include "core/hle/service/y2r_u.h" | ||||||
|  | #include "core/loader/loader.h" | ||||||
| 
 | 
 | ||||||
| namespace Service { | namespace Service { | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -14,7 +14,6 @@ | ||||||
| #include "common/file_util.h" | #include "common/file_util.h" | ||||||
| #include "core/file_sys/romfs_reader.h" | #include "core/file_sys/romfs_reader.h" | ||||||
| #include "core/hle/kernel/kernel.h" | #include "core/hle/kernel/kernel.h" | ||||||
| #include "core/hle/kernel/object.h" |  | ||||||
| 
 | 
 | ||||||
| namespace Kernel { | namespace Kernel { | ||||||
| struct AddressMapping; | struct AddressMapping; | ||||||
|  |  | ||||||
|  | @ -27,6 +27,7 @@ | ||||||
| #include "core/loader/smdh.h" | #include "core/loader/smdh.h" | ||||||
| #include "core/memory.h" | #include "core/memory.h" | ||||||
| #include "core/system_titles.h" | #include "core/system_titles.h" | ||||||
|  | #include "core/telemetry_session.h" | ||||||
| #include "network/network.h" | #include "network/network.h" | ||||||
| 
 | 
 | ||||||
| namespace Loader { | namespace Loader { | ||||||
|  |  | ||||||
|  | @ -10,13 +10,11 @@ | ||||||
| #include <boost/optional.hpp> | #include <boost/optional.hpp> | ||||||
| #include <cryptopp/hex.h> | #include <cryptopp/hex.h> | ||||||
| #include <cryptopp/osrng.h> | #include <cryptopp/osrng.h> | ||||||
| #include <fmt/format.h> | #include "common/archives.h" | ||||||
| #include "common/bit_field.h" | #include "common/bit_field.h" | ||||||
| #include "common/common_types.h" |  | ||||||
| #include "common/file_util.h" | #include "common/file_util.h" | ||||||
| #include "common/logging/log.h" | #include "common/logging/log.h" | ||||||
| #include "common/scm_rev.h" | #include "common/scm_rev.h" | ||||||
| #include "common/string_util.h" |  | ||||||
| #include "common/swap.h" | #include "common/swap.h" | ||||||
| #include "common/timer.h" | #include "common/timer.h" | ||||||
| #include "core/core.h" | #include "core/core.h" | ||||||
|  | @ -24,12 +22,11 @@ | ||||||
| #include "core/hle/service/ir/extra_hid.h" | #include "core/hle/service/ir/extra_hid.h" | ||||||
| #include "core/hle/service/ir/ir_rst.h" | #include "core/hle/service/ir/ir_rst.h" | ||||||
| #include "core/hw/gpu.h" | #include "core/hw/gpu.h" | ||||||
|  | #include "core/loader/loader.h" | ||||||
| #include "core/movie.h" | #include "core/movie.h" | ||||||
| 
 | 
 | ||||||
| namespace Core { | namespace Core { | ||||||
| 
 | 
 | ||||||
| /*static*/ Movie Movie::s_instance; |  | ||||||
| 
 |  | ||||||
| enum class ControllerStateType : u8 { | enum class ControllerStateType : u8 { | ||||||
|     PadAndCircle, |     PadAndCircle, | ||||||
|     Touch, |     Touch, | ||||||
|  | @ -146,6 +143,10 @@ static u64 GetInputCount(std::span<const u8> input) { | ||||||
|     return input_count; |     return input_count; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | Movie::Movie(const Core::System& system_) : system{system_} {} | ||||||
|  | 
 | ||||||
|  | Movie::~Movie() = default; | ||||||
|  | 
 | ||||||
| template <class Archive> | template <class Archive> | ||||||
| void Movie::serialize(Archive& ar, const unsigned int file_version) { | void Movie::serialize(Archive& ar, const unsigned int file_version) { | ||||||
|     // Only serialize what's needed to make savestates useful for TAS:
 |     // Only serialize what's needed to make savestates useful for TAS:
 | ||||||
|  | @ -565,7 +566,7 @@ void Movie::StartRecording(const std::string& movie_file, const std::string& aut | ||||||
| 
 | 
 | ||||||
|     // Get program ID
 |     // Get program ID
 | ||||||
|     program_id = 0; |     program_id = 0; | ||||||
|     Core::System::GetInstance().GetAppLoader().ReadProgramId(program_id); |     system.GetAppLoader().ReadProgramId(program_id); | ||||||
| 
 | 
 | ||||||
|     LOG_INFO(Movie, "Enabling Movie recording, ID: {:016X}", id); |     LOG_INFO(Movie, "Enabling Movie recording, ID: {:016X}", id); | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -23,25 +23,29 @@ union PadState; | ||||||
| } // namespace Service
 | } // namespace Service
 | ||||||
| 
 | 
 | ||||||
| namespace Core { | namespace Core { | ||||||
|  | 
 | ||||||
|  | class System; | ||||||
| struct CTMHeader; | struct CTMHeader; | ||||||
| struct ControllerState; | struct ControllerState; | ||||||
| 
 | 
 | ||||||
| class Movie { | class Movie { | ||||||
| public: | public: | ||||||
|     enum class PlayMode { None, Recording, Playing, MovieFinished }; |     enum class PlayMode : u32 { | ||||||
|     enum class ValidationResult { |         None, | ||||||
|  |         Recording, | ||||||
|  |         Playing, | ||||||
|  |         MovieFinished, | ||||||
|  |     }; | ||||||
|  | 
 | ||||||
|  |     enum class ValidationResult : u32 { | ||||||
|         OK, |         OK, | ||||||
|         RevisionDismatch, |         RevisionDismatch, | ||||||
|         InputCountDismatch, |         InputCountDismatch, | ||||||
|         Invalid, |         Invalid, | ||||||
|     }; |     }; | ||||||
|     /**
 | 
 | ||||||
|      * Gets the instance of the Movie singleton class. |     explicit Movie(const Core::System& system); | ||||||
|      * @returns Reference to the instance of the Movie singleton class. |     ~Movie(); | ||||||
|      */ |  | ||||||
|     static Movie& GetInstance() { |  | ||||||
|         return s_instance; |  | ||||||
|     } |  | ||||||
| 
 | 
 | ||||||
|     void SetPlaybackCompletionCallback(std::function<void()> completion_callback); |     void SetPlaybackCompletionCallback(std::function<void()> completion_callback); | ||||||
|     void StartPlayback(const std::string& movie_file); |     void StartPlayback(const std::string& movie_file); | ||||||
|  | @ -133,8 +137,6 @@ public: | ||||||
|     void SaveMovie(); |     void SaveMovie(); | ||||||
| 
 | 
 | ||||||
| private: | private: | ||||||
|     static Movie s_instance; |  | ||||||
| 
 |  | ||||||
|     void CheckInputEnd(); |     void CheckInputEnd(); | ||||||
| 
 | 
 | ||||||
|     template <typename... Targs> |     template <typename... Targs> | ||||||
|  | @ -159,6 +161,8 @@ private: | ||||||
|     ValidationResult ValidateHeader(const CTMHeader& header) const; |     ValidationResult ValidateHeader(const CTMHeader& header) const; | ||||||
|     ValidationResult ValidateInput(std::span<const u8> input, u64 expected_count) const; |     ValidationResult ValidateInput(std::span<const u8> input, u64 expected_count) const; | ||||||
| 
 | 
 | ||||||
|  | private: | ||||||
|  |     const Core::System& system; | ||||||
|     PlayMode play_mode; |     PlayMode play_mode; | ||||||
| 
 | 
 | ||||||
|     std::string record_movie_file; |     std::string record_movie_file; | ||||||
|  |  | ||||||
|  | @ -3,11 +3,14 @@ | ||||||
| // Refer to the license.txt file included.
 | // Refer to the license.txt file included.
 | ||||||
| 
 | 
 | ||||||
| #include <chrono> | #include <chrono> | ||||||
|  | #include <sstream> | ||||||
| #include <cryptopp/hex.h> | #include <cryptopp/hex.h> | ||||||
| #include <fmt/format.h> | #include <fmt/format.h> | ||||||
| #include "common/archives.h" | #include "common/archives.h" | ||||||
|  | #include "common/file_util.h" | ||||||
| #include "common/logging/log.h" | #include "common/logging/log.h" | ||||||
| #include "common/scm_rev.h" | #include "common/scm_rev.h" | ||||||
|  | #include "common/swap.h" | ||||||
| #include "common/zstd_compression.h" | #include "common/zstd_compression.h" | ||||||
| #include "core/core.h" | #include "core/core.h" | ||||||
| #include "core/movie.h" | #include "core/movie.h" | ||||||
|  | @ -30,8 +33,7 @@ static_assert(sizeof(CSTHeader) == 256, "CSTHeader should be 256 bytes"); | ||||||
| 
 | 
 | ||||||
| constexpr std::array<u8, 4> header_magic_bytes{{'C', 'S', 'T', 0x1B}}; | constexpr std::array<u8, 4> header_magic_bytes{{'C', 'S', 'T', 0x1B}}; | ||||||
| 
 | 
 | ||||||
| static std::string GetSaveStatePath(u64 program_id, u32 slot) { | static std::string GetSaveStatePath(u64 program_id, u64 movie_id, u32 slot) { | ||||||
|     const u64 movie_id = Movie::GetInstance().GetCurrentMovieID(); |  | ||||||
|     if (movie_id) { |     if (movie_id) { | ||||||
|         return fmt::format("{}{:016X}.movie{:016X}.{:02d}.cst", |         return fmt::format("{}{:016X}.movie{:016X}.{:02d}.cst", | ||||||
|                            FileUtil::GetUserPath(FileUtil::UserPath::StatesDir), program_id, |                            FileUtil::GetUserPath(FileUtil::UserPath::StatesDir), program_id, | ||||||
|  | @ -43,8 +45,8 @@ static std::string GetSaveStatePath(u64 program_id, u32 slot) { | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static bool ValidateSaveState(const CSTHeader& header, SaveStateInfo& info, u64 program_id, | static bool ValidateSaveState(const CSTHeader& header, SaveStateInfo& info, u64 program_id, | ||||||
|                               u32 slot) { |                               u64 movie_id, u32 slot) { | ||||||
|     const auto path = GetSaveStatePath(program_id, slot); |     const auto path = GetSaveStatePath(program_id, movie_id, slot); | ||||||
|     if (header.filetype != header_magic_bytes) { |     if (header.filetype != header_magic_bytes) { | ||||||
|         LOG_WARNING(Core, "Invalid save state file {}", path); |         LOG_WARNING(Core, "Invalid save state file {}", path); | ||||||
|         return false; |         return false; | ||||||
|  | @ -66,11 +68,11 @@ static bool ValidateSaveState(const CSTHeader& header, SaveStateInfo& info, u64 | ||||||
|     return true; |     return true; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| std::vector<SaveStateInfo> ListSaveStates(u64 program_id) { | std::vector<SaveStateInfo> ListSaveStates(u64 program_id, u64 movie_id) { | ||||||
|     std::vector<SaveStateInfo> result; |     std::vector<SaveStateInfo> result; | ||||||
|     result.reserve(SaveStateSlotCount); |     result.reserve(SaveStateSlotCount); | ||||||
|     for (u32 slot = 1; slot <= SaveStateSlotCount; ++slot) { |     for (u32 slot = 1; slot <= SaveStateSlotCount; ++slot) { | ||||||
|         const auto path = GetSaveStatePath(program_id, slot); |         const auto path = GetSaveStatePath(program_id, movie_id, slot); | ||||||
|         if (!FileUtil::Exists(path)) { |         if (!FileUtil::Exists(path)) { | ||||||
|             continue; |             continue; | ||||||
|         } |         } | ||||||
|  | @ -92,7 +94,7 @@ std::vector<SaveStateInfo> ListSaveStates(u64 program_id) { | ||||||
|             LOG_ERROR(Core, "Could not read from file {}", path); |             LOG_ERROR(Core, "Could not read from file {}", path); | ||||||
|             continue; |             continue; | ||||||
|         } |         } | ||||||
|         if (!ValidateSaveState(header, info, program_id, slot)) { |         if (!ValidateSaveState(header, info, program_id, movie_id, slot)) { | ||||||
|             continue; |             continue; | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|  | @ -111,7 +113,8 @@ void System::SaveState(u32 slot) const { | ||||||
|     const auto data = std::span<const u8>{reinterpret_cast<const u8*>(str.data()), str.size()}; |     const auto data = std::span<const u8>{reinterpret_cast<const u8*>(str.data()), str.size()}; | ||||||
|     auto buffer = Common::Compression::CompressDataZSTDDefault(data); |     auto buffer = Common::Compression::CompressDataZSTDDefault(data); | ||||||
| 
 | 
 | ||||||
|     const auto path = GetSaveStatePath(title_id, slot); |     const u64 movie_id = movie.GetCurrentMovieID(); | ||||||
|  |     const auto path = GetSaveStatePath(title_id, movie_id, slot); | ||||||
|     if (!FileUtil::CreateFullPath(path)) { |     if (!FileUtil::CreateFullPath(path)) { | ||||||
|         throw std::runtime_error("Could not create path " + path); |         throw std::runtime_error("Could not create path " + path); | ||||||
|     } |     } | ||||||
|  | @ -143,7 +146,8 @@ void System::LoadState(u32 slot) { | ||||||
|         throw std::runtime_error("Unable to load while connected to multiplayer"); |         throw std::runtime_error("Unable to load while connected to multiplayer"); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     const auto path = GetSaveStatePath(title_id, slot); |     const u64 movie_id = movie.GetCurrentMovieID(); | ||||||
|  |     const auto path = GetSaveStatePath(title_id, movie_id, slot); | ||||||
| 
 | 
 | ||||||
|     std::vector<u8> decompressed; |     std::vector<u8> decompressed; | ||||||
|     { |     { | ||||||
|  | @ -159,7 +163,7 @@ void System::LoadState(u32 slot) { | ||||||
| 
 | 
 | ||||||
|         // validate header
 |         // validate header
 | ||||||
|         SaveStateInfo info; |         SaveStateInfo info; | ||||||
|         if (!ValidateSaveState(header, info, title_id, slot)) { |         if (!ValidateSaveState(header, info, title_id, movie_id, slot)) { | ||||||
|             throw std::runtime_error("Invalid savestate"); |             throw std::runtime_error("Invalid savestate"); | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -20,6 +20,6 @@ struct SaveStateInfo { | ||||||
| 
 | 
 | ||||||
| constexpr u32 SaveStateSlotCount = 10; // Maximum count of savestate slots
 | constexpr u32 SaveStateSlotCount = 10; // Maximum count of savestate slots
 | ||||||
| 
 | 
 | ||||||
| std::vector<SaveStateInfo> ListSaveStates(u64 program_id); | std::vector<SaveStateInfo> ListSaveStates(u64 program_id, u64 movie_id); | ||||||
| 
 | 
 | ||||||
| } // namespace Core
 | } // namespace Core
 | ||||||
|  |  | ||||||
|  | @ -11,6 +11,7 @@ | ||||||
| #include "common/scm_rev.h" | #include "common/scm_rev.h" | ||||||
| #include "common/settings.h" | #include "common/settings.h" | ||||||
| #include "core/core.h" | #include "core/core.h" | ||||||
|  | #include "core/loader/loader.h" | ||||||
| #include "core/telemetry_session.h" | #include "core/telemetry_session.h" | ||||||
| #include "network/network_settings.h" | #include "network/network_settings.h" | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -7,6 +7,7 @@ | ||||||
| #include "audio_core/hle/hle.h" | #include "audio_core/hle/hle.h" | ||||||
| #include "audio_core/lle/lle.h" | #include "audio_core/lle/lle.h" | ||||||
| #include "common/common_paths.h" | #include "common/common_paths.h" | ||||||
|  | #include "common/file_util.h" | ||||||
| #include "core/core_timing.h" | #include "core/core_timing.h" | ||||||
| #include "core/memory.h" | #include "core/memory.h" | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -6,6 +6,7 @@ | ||||||
| #include "audio_core/hle/decoder.h" | #include "audio_core/hle/decoder.h" | ||||||
| #include "audio_core/lle/lle.h" | #include "audio_core/lle/lle.h" | ||||||
| #include "common/common_paths.h" | #include "common/common_paths.h" | ||||||
|  | #include "common/file_util.h" | ||||||
| #include "core/core_timing.h" | #include "core/core_timing.h" | ||||||
| #include "core/memory.h" | #include "core/memory.h" | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -11,6 +11,8 @@ | ||||||
| #include "common/texture.h" | #include "common/texture.h" | ||||||
| #include "core/core.h" | #include "core/core.h" | ||||||
| #include "core/frontend/image_interface.h" | #include "core/frontend/image_interface.h" | ||||||
|  | #include "core/hle/kernel/kernel.h" | ||||||
|  | #include "core/hle/kernel/process.h" | ||||||
| #include "video_core/custom_textures/custom_tex_manager.h" | #include "video_core/custom_textures/custom_tex_manager.h" | ||||||
| #include "video_core/rasterizer_cache/surface_params.h" | #include "video_core/rasterizer_cache/surface_params.h" | ||||||
| #include "video_core/rasterizer_cache/utils.h" | #include "video_core/rasterizer_cache/utils.h" | ||||||
|  |  | ||||||
|  | @ -5,7 +5,6 @@ | ||||||
| #include <cstring> | #include <cstring> | ||||||
| #include <fmt/format.h> | #include <fmt/format.h> | ||||||
| 
 | 
 | ||||||
| #include "common/assert.h" |  | ||||||
| #include "common/common_paths.h" | #include "common/common_paths.h" | ||||||
| #include "common/common_types.h" | #include "common/common_types.h" | ||||||
| #include "common/file_util.h" | #include "common/file_util.h" | ||||||
|  | @ -14,7 +13,7 @@ | ||||||
| #include "common/settings.h" | #include "common/settings.h" | ||||||
| #include "common/zstd_compression.h" | #include "common/zstd_compression.h" | ||||||
| #include "core/core.h" | #include "core/core.h" | ||||||
| #include "core/hle/kernel/process.h" | #include "core/loader/loader.h" | ||||||
| #include "video_core/renderer_opengl/gl_shader_disk_cache.h" | #include "video_core/renderer_opengl/gl_shader_disk_cache.h" | ||||||
| 
 | 
 | ||||||
| namespace OpenGL { | namespace OpenGL { | ||||||
|  |  | ||||||
|  | @ -7,6 +7,7 @@ | ||||||
| #include "common/bit_set.h" | #include "common/bit_set.h" | ||||||
| #include "common/logging/log.h" | #include "common/logging/log.h" | ||||||
| #include "core/core.h" | #include "core/core.h" | ||||||
|  | #include "core/telemetry_session.h" | ||||||
| #include "video_core/pica_state.h" | #include "video_core/pica_state.h" | ||||||
| #include "video_core/renderer_opengl/gl_shader_decompiler.h" | #include "video_core/renderer_opengl/gl_shader_decompiler.h" | ||||||
| #include "video_core/renderer_opengl/gl_shader_gen.h" | #include "video_core/renderer_opengl/gl_shader_gen.h" | ||||||
|  |  | ||||||
|  | @ -9,6 +9,7 @@ | ||||||
| #include "common/assert.h" | #include "common/assert.h" | ||||||
| #include "common/logging/log.h" | #include "common/logging/log.h" | ||||||
| #include "core/core.h" | #include "core/core.h" | ||||||
|  | #include "core/telemetry_session.h" | ||||||
| #include "video_core/regs_framebuffer.h" | #include "video_core/regs_framebuffer.h" | ||||||
| #include "video_core/regs_lighting.h" | #include "video_core/regs_lighting.h" | ||||||
| #include "video_core/regs_texturing.h" | #include "video_core/regs_texturing.h" | ||||||
|  |  | ||||||
|  | @ -7,6 +7,7 @@ | ||||||
| #include "common/bit_set.h" | #include "common/bit_set.h" | ||||||
| #include "common/logging/log.h" | #include "common/logging/log.h" | ||||||
| #include "core/core.h" | #include "core/core.h" | ||||||
|  | #include "core/telemetry_session.h" | ||||||
| #include "video_core/pica_state.h" | #include "video_core/pica_state.h" | ||||||
| #include "video_core/regs_framebuffer.h" | #include "video_core/regs_framebuffer.h" | ||||||
| #include "video_core/renderer_opengl/gl_shader_decompiler.h" | #include "video_core/renderer_opengl/gl_shader_decompiler.h" | ||||||
|  |  | ||||||
|  | @ -3,6 +3,7 @@ | ||||||
| // Refer to the license.txt file included.
 | // Refer to the license.txt file included.
 | ||||||
| 
 | 
 | ||||||
| #include "core/core.h" | #include "core/core.h" | ||||||
|  | #include "core/telemetry_session.h" | ||||||
| #include "video_core/renderer_vulkan/vk_shader_gen_spv.h" | #include "video_core/renderer_vulkan/vk_shader_gen_spv.h" | ||||||
| 
 | 
 | ||||||
| using Pica::FramebufferRegs; | using Pica::FramebufferRegs; | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue