core: De-globalize movie (#6659)

This commit is contained in:
GPUCode 2023-08-01 03:57:38 +03:00 committed by GitHub
parent a955f02771
commit f8b8b6e53c
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
51 changed files with 182 additions and 104 deletions

View file

@ -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) {

View file

@ -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

View file

@ -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();

View file

@ -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)

View file

@ -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"

View file

@ -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"

View file

@ -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 {

View file

@ -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

View file

@ -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>();
} }

View file

@ -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 =

View file

@ -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;
}; };

View file

@ -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 {

View file

@ -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;
}; };

View file

@ -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!

View file

@ -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;

View file

@ -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 };

View file

@ -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"

View file

@ -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) {

View file

@ -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;

View file

@ -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) {

View file

@ -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",

View file

@ -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&);

View file

@ -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 {

View file

@ -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"

View file

@ -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"

View file

@ -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"

View file

@ -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)

View file

@ -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"

View file

@ -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;

View file

@ -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));

View file

@ -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;

View file

@ -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);

View file

@ -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() {

View file

@ -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)

View file

@ -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)

View file

@ -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 {

View file

@ -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;

View file

@ -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 {

View file

@ -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);
} }

View file

@ -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;

View 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");
} }

View file

@ -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

View file

@ -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"

View file

@ -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"

View file

@ -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"

View file

@ -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"

View file

@ -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 {

View file

@ -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"

View file

@ -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"

View file

@ -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"

View file

@ -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;