mirror of
https://github.com/PabloMK7/citra.git
synced 2025-10-11 12:00:03 +00:00
core: Eliminate more uses of Core::System::GetInstance(). (#7313)
This commit is contained in:
parent
8e2037b3ff
commit
f2ee9baec7
47 changed files with 416 additions and 387 deletions
|
@ -20,6 +20,9 @@
|
|||
#include "core/hle/service/soc/soc_u.h"
|
||||
#include "core/memory.h"
|
||||
|
||||
SERIALIZE_EXPORT_IMPL(Service::AC::Module)
|
||||
SERVICE_CONSTRUCT_IMPL(Service::AC::Module)
|
||||
|
||||
namespace Service::AC {
|
||||
void Module::Interface::CreateDefaultConfig(Kernel::HLERequestContext& ctx) {
|
||||
IPC::RequestParser rp(ctx);
|
||||
|
@ -96,7 +99,7 @@ void Module::Interface::GetWifiStatus(Kernel::HLERequestContext& ctx) {
|
|||
IPC::RequestParser rp(ctx);
|
||||
bool can_reach_internet = false;
|
||||
|
||||
std::shared_ptr<SOC::SOC_U> socu_module = SOC::GetService(Core::System::GetInstance());
|
||||
std::shared_ptr<SOC::SOC_U> socu_module = SOC::GetService(ac->system);
|
||||
if (socu_module) {
|
||||
can_reach_internet = socu_module->GetDefaultInterfaceInfo().has_value();
|
||||
}
|
||||
|
@ -194,11 +197,13 @@ Module::Interface::Interface(std::shared_ptr<Module> ac, const char* name, u32 m
|
|||
|
||||
void InstallInterfaces(Core::System& system) {
|
||||
auto& service_manager = system.ServiceManager();
|
||||
auto ac = std::make_shared<Module>();
|
||||
auto ac = std::make_shared<Module>(system);
|
||||
std::make_shared<AC_I>(ac)->InstallAsService(service_manager);
|
||||
std::make_shared<AC_U>(ac)->InstallAsService(service_manager);
|
||||
}
|
||||
|
||||
Module::Module(Core::System& system_) : system(system_) {}
|
||||
|
||||
template <class Archive>
|
||||
void Module::serialize(Archive& ar, const unsigned int) {
|
||||
ar& ac_connected;
|
||||
|
@ -207,7 +212,6 @@ void Module::serialize(Archive& ar, const unsigned int) {
|
|||
ar& disconnect_event;
|
||||
// default_config is never written to
|
||||
}
|
||||
SERIALIZE_IMPL(Module)
|
||||
|
||||
} // namespace Service::AC
|
||||
|
||||
SERIALIZE_IMPL(Service::AC::Module)
|
||||
|
|
|
@ -19,6 +19,9 @@ class Event;
|
|||
namespace Service::AC {
|
||||
class Module final {
|
||||
public:
|
||||
explicit Module(Core::System& system_);
|
||||
~Module() = default;
|
||||
|
||||
class Interface : public ServiceFramework<Interface> {
|
||||
public:
|
||||
Interface(std::shared_ptr<Module> ac, const char* name, u32 max_session);
|
||||
|
@ -169,11 +172,16 @@ protected:
|
|||
std::shared_ptr<Kernel::Event> disconnect_event;
|
||||
|
||||
private:
|
||||
Core::System& system;
|
||||
|
||||
template <class Archive>
|
||||
void serialize(Archive& ar, const unsigned int file_version);
|
||||
void serialize(Archive& ar, const unsigned int);
|
||||
friend class boost::serialization::access;
|
||||
};
|
||||
|
||||
void InstallInterfaces(Core::System& system);
|
||||
|
||||
} // namespace Service::AC
|
||||
|
||||
BOOST_CLASS_EXPORT_KEY(Service::AC::Module)
|
||||
SERVICE_CONSTRUCT(Service::AC::Module)
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
#include <cryptopp/modes.h>
|
||||
#include <fmt/format.h>
|
||||
#include "common/alignment.h"
|
||||
#include "common/archives.h"
|
||||
#include "common/common_paths.h"
|
||||
#include "common/file_util.h"
|
||||
#include "common/logging/log.h"
|
||||
|
@ -33,6 +34,9 @@
|
|||
#include "core/loader/smdh.h"
|
||||
#include "core/nus_download.h"
|
||||
|
||||
SERIALIZE_EXPORT_IMPL(Service::AM::Module)
|
||||
SERVICE_CONSTRUCT_IMPL(Service::AM::Module)
|
||||
|
||||
namespace Service::AM {
|
||||
|
||||
constexpr u16 PLATFORM_CTR = 0x0004;
|
||||
|
@ -81,8 +85,9 @@ public:
|
|||
std::vector<CryptoPP::CBC_Mode<CryptoPP::AES>::Decryption> content;
|
||||
};
|
||||
|
||||
CIAFile::CIAFile(Service::FS::MediaType media_type)
|
||||
: media_type(media_type), decryption_state(std::make_unique<DecryptionState>()) {}
|
||||
CIAFile::CIAFile(Core::System& system_, Service::FS::MediaType media_type)
|
||||
: system(system_), media_type(media_type),
|
||||
decryption_state(std::make_unique<DecryptionState>()) {}
|
||||
|
||||
CIAFile::~CIAFile() {
|
||||
Close();
|
||||
|
@ -361,8 +366,7 @@ bool CIAFile::Close() const {
|
|||
// are closed.
|
||||
std::string to_delete =
|
||||
GetTitleContentPath(media_type, old_tmd.GetTitleID(), old_index);
|
||||
if (!(Core::System::GetInstance().IsPoweredOn() &&
|
||||
Core::System::GetInstance().SetSelfDelete(to_delete))) {
|
||||
if (!system.IsPoweredOn() || !system.SetSelfDelete(to_delete)) {
|
||||
FileUtil::Delete(to_delete);
|
||||
}
|
||||
}
|
||||
|
@ -425,6 +429,7 @@ InstallStatus InstallCIA(const std::string& path,
|
|||
FileSys::CIAContainer container;
|
||||
if (container.Load(path) == Loader::ResultStatus::Success) {
|
||||
Service::AM::CIAFile installFile(
|
||||
Core::System::GetInstance(),
|
||||
Service::AM::GetTitleMediaType(container.GetTitleMetadata().GetTitleID()));
|
||||
|
||||
bool title_key_available = container.GetTicket().GetTitleKey().has_value();
|
||||
|
@ -502,7 +507,7 @@ InstallStatus InstallCIA(const std::string& path,
|
|||
InstallStatus InstallFromNus(u64 title_id, int version) {
|
||||
LOG_DEBUG(Service_AM, "Downloading {:X}", title_id);
|
||||
|
||||
CIAFile install_file{GetTitleMediaType(title_id)};
|
||||
CIAFile install_file{Core::System::GetInstance(), GetTitleMediaType(title_id)};
|
||||
|
||||
std::string path = fmt::format("/ccs/download/{:016X}/tmd", title_id);
|
||||
if (version != -1) {
|
||||
|
@ -1327,7 +1332,7 @@ void Module::Interface::BeginImportProgram(Kernel::HLERequestContext& ctx) {
|
|||
// Citra will store contents out to sdmc/nand
|
||||
const FileSys::Path cia_path = {};
|
||||
auto file = std::make_shared<Service::FS::File>(
|
||||
am->kernel, std::make_unique<CIAFile>(media_type), cia_path);
|
||||
am->system.Kernel(), std::make_unique<CIAFile>(am->system, media_type), cia_path);
|
||||
|
||||
am->cia_installing = true;
|
||||
|
||||
|
@ -1354,7 +1359,7 @@ void Module::Interface::BeginImportProgramTemporarily(Kernel::HLERequestContext&
|
|||
// contents out to sdmc/nand
|
||||
const FileSys::Path cia_path = {};
|
||||
auto file = std::make_shared<Service::FS::File>(
|
||||
am->kernel, std::make_unique<CIAFile>(FS::MediaType::NAND), cia_path);
|
||||
am->system.Kernel(), std::make_unique<CIAFile>(am->system, FS::MediaType::NAND), cia_path);
|
||||
|
||||
am->cia_installing = true;
|
||||
|
||||
|
@ -1769,8 +1774,8 @@ void Module::Interface::BeginImportTicket(Kernel::HLERequestContext& ctx) {
|
|||
IPC::RequestParser rp(ctx);
|
||||
|
||||
// Create our TicketFile handle for the app to write to
|
||||
auto file = std::make_shared<Service::FS::File>(am->kernel, std::make_unique<TicketFile>(),
|
||||
FileSys::Path{});
|
||||
auto file = std::make_shared<Service::FS::File>(
|
||||
am->system.Kernel(), std::make_unique<TicketFile>(), FileSys::Path{});
|
||||
|
||||
IPC::RequestBuilder rb = rp.MakeBuilder(1, 2);
|
||||
rb.Push(ResultSuccess); // No error
|
||||
|
@ -1789,13 +1794,19 @@ void Module::Interface::EndImportTicket(Kernel::HLERequestContext& ctx) {
|
|||
LOG_WARNING(Service_AM, "(STUBBED) called");
|
||||
}
|
||||
|
||||
Module::Module(Core::System& system) : kernel(system.Kernel()) {
|
||||
template <class Archive>
|
||||
void Module::serialize(Archive& ar, const unsigned int) {
|
||||
ar& cia_installing;
|
||||
ar& am_title_list;
|
||||
ar& system_updater_mutex;
|
||||
}
|
||||
SERIALIZE_IMPL(Module)
|
||||
|
||||
Module::Module(Core::System& system) : system(system) {
|
||||
ScanForAllTitles();
|
||||
system_updater_mutex = system.Kernel().CreateMutex(false, "AM::SystemUpdaterMutex");
|
||||
}
|
||||
|
||||
Module::Module(Kernel::KernelSystem& kernel) : kernel(kernel) {}
|
||||
|
||||
Module::~Module() = default;
|
||||
|
||||
void InstallInterfaces(Core::System& system) {
|
||||
|
|
|
@ -11,7 +11,6 @@
|
|||
#include <vector>
|
||||
#include <boost/serialization/array.hpp>
|
||||
#include <boost/serialization/shared_ptr.hpp>
|
||||
#include <boost/serialization/vector.hpp>
|
||||
#include "common/common_types.h"
|
||||
#include "common/construct.h"
|
||||
#include "common/swap.h"
|
||||
|
@ -80,7 +79,7 @@ using ProgressCallback = void(std::size_t, std::size_t);
|
|||
// A file handled returned for CIAs to be written into and subsequently installed.
|
||||
class CIAFile final : public FileSys::FileBackend {
|
||||
public:
|
||||
explicit CIAFile(Service::FS::MediaType media_type);
|
||||
explicit CIAFile(Core::System& system_, Service::FS::MediaType media_type);
|
||||
~CIAFile();
|
||||
|
||||
ResultVal<std::size_t> Read(u64 offset, std::size_t length, u8* buffer) const override;
|
||||
|
@ -95,6 +94,8 @@ public:
|
|||
void Flush() const override;
|
||||
|
||||
private:
|
||||
Core::System& system;
|
||||
|
||||
// Whether it's installing an update, and what step of installation it is at
|
||||
bool is_update = false;
|
||||
CIAInstallState install_state = CIAInstallState::InstallStarted;
|
||||
|
@ -706,8 +707,6 @@ public:
|
|||
};
|
||||
|
||||
private:
|
||||
explicit Module(Kernel::KernelSystem& kernel);
|
||||
|
||||
/**
|
||||
* Scans the for titles in a storage medium for listing.
|
||||
* @param media_type the storage medium to scan
|
||||
|
@ -719,27 +718,13 @@ private:
|
|||
*/
|
||||
void ScanForAllTitles();
|
||||
|
||||
Kernel::KernelSystem& kernel;
|
||||
Core::System& system;
|
||||
bool cia_installing = false;
|
||||
std::array<std::vector<u64_le>, 3> am_title_list;
|
||||
std::shared_ptr<Kernel::Mutex> system_updater_mutex;
|
||||
|
||||
template <class Archive>
|
||||
void serialize(Archive& ar, const unsigned int) {
|
||||
ar& cia_installing;
|
||||
ar& am_title_list;
|
||||
ar& system_updater_mutex;
|
||||
}
|
||||
|
||||
template <class Archive>
|
||||
static void load_construct(Archive& ar, Module* t, const unsigned int file_version) {
|
||||
::new (t) Module(Core::Global<Kernel::KernelSystem>());
|
||||
}
|
||||
|
||||
template <class Archive>
|
||||
void save_construct(Archive& ar, const unsigned int file_version) const {}
|
||||
|
||||
friend class ::construct_access;
|
||||
void serialize(Archive& ar, const unsigned int);
|
||||
friend class boost::serialization::access;
|
||||
};
|
||||
|
||||
|
@ -747,4 +732,5 @@ void InstallInterfaces(Core::System& system);
|
|||
|
||||
} // namespace Service::AM
|
||||
|
||||
BOOST_SERIALIZATION_CONSTRUCT(Service::AM::Module);
|
||||
BOOST_CLASS_EXPORT_KEY(Service::AM::Module)
|
||||
SERVICE_CONSTRUCT(Service::AM::Module)
|
||||
|
|
|
@ -8,6 +8,10 @@
|
|||
#include "core/core.h"
|
||||
#include "core/frontend/input.h"
|
||||
#include "core/hle/applets/applet.h"
|
||||
#include "core/hle/applets/erreula.h"
|
||||
#include "core/hle/applets/mii_selector.h"
|
||||
#include "core/hle/applets/mint.h"
|
||||
#include "core/hle/applets/swkbd.h"
|
||||
#include "core/hle/service/am/am.h"
|
||||
#include "core/hle/service/apt/applet_manager.h"
|
||||
#include "core/hle/service/apt/errors.h"
|
||||
|
@ -22,6 +26,8 @@ namespace Service::APT {
|
|||
|
||||
/// The interval at which the home button update callback will be called, 16.6ms
|
||||
static constexpr u64 button_update_interval_us = 16666;
|
||||
/// The interval at which the HLE Applet update callback will be called, 16.6ms.
|
||||
static constexpr u64 hle_applet_update_interval_us = 16666;
|
||||
|
||||
struct AppletTitleData {
|
||||
// There are two possible applet ids for each applet.
|
||||
|
@ -222,8 +228,8 @@ void AppletManager::CancelAndSendParameter(const MessageParameter& parameter) {
|
|||
parameter.sender_id, parameter.destination_id, parameter.signal, parameter.buffer.size());
|
||||
|
||||
// If the applet is being HLEd, send directly to the applet.
|
||||
if (auto dest_applet = HLE::Applets::Applet::Get(parameter.destination_id)) {
|
||||
dest_applet->ReceiveParameter(parameter);
|
||||
if (hle_applets.contains(parameter.destination_id)) {
|
||||
hle_applets[parameter.destination_id]->ReceiveParameter(parameter);
|
||||
} else {
|
||||
// Otherwise, send the parameter the LLE way.
|
||||
next_parameter = parameter;
|
||||
|
@ -497,6 +503,52 @@ void AppletManager::SendNotificationToAll(Notification notification) {
|
|||
}
|
||||
}
|
||||
|
||||
Result AppletManager::CreateHLEApplet(AppletId id, AppletId parent, bool preload) {
|
||||
switch (id) {
|
||||
case AppletId::SoftwareKeyboard1:
|
||||
case AppletId::SoftwareKeyboard2:
|
||||
hle_applets[id] = std::make_shared<HLE::Applets::SoftwareKeyboard>(
|
||||
system, id, parent, preload, shared_from_this());
|
||||
break;
|
||||
case AppletId::Ed1:
|
||||
case AppletId::Ed2:
|
||||
hle_applets[id] = std::make_shared<HLE::Applets::MiiSelector>(system, id, parent, preload,
|
||||
shared_from_this());
|
||||
break;
|
||||
case AppletId::Error:
|
||||
case AppletId::Error2:
|
||||
hle_applets[id] = std::make_shared<HLE::Applets::ErrEula>(system, id, parent, preload,
|
||||
shared_from_this());
|
||||
break;
|
||||
case AppletId::Mint:
|
||||
case AppletId::Mint2:
|
||||
hle_applets[id] =
|
||||
std::make_shared<HLE::Applets::Mint>(system, id, parent, preload, shared_from_this());
|
||||
break;
|
||||
default:
|
||||
LOG_ERROR(Service_APT, "Could not create applet {}", id);
|
||||
// TODO(Subv): Find the right error code
|
||||
return Result(ErrorDescription::NotFound, ErrorModule::Applet, ErrorSummary::NotSupported,
|
||||
ErrorLevel::Permanent);
|
||||
}
|
||||
|
||||
AppletAttributes attributes;
|
||||
attributes.applet_pos.Assign(AppletPos::AutoLibrary);
|
||||
attributes.is_home_menu.Assign(false);
|
||||
const auto lock_handle_data = GetLockHandle(attributes);
|
||||
|
||||
Initialize(id, lock_handle_data->corrected_attributes);
|
||||
Enable(lock_handle_data->corrected_attributes);
|
||||
if (preload) {
|
||||
FinishPreloadingLibraryApplet(id);
|
||||
}
|
||||
|
||||
// Schedule the update event
|
||||
system.CoreTiming().ScheduleEvent(usToCycles(hle_applet_update_interval_us),
|
||||
hle_applet_update_event, static_cast<u64>(id));
|
||||
return ResultSuccess;
|
||||
}
|
||||
|
||||
Result AppletManager::PrepareToStartLibraryApplet(AppletId applet_id) {
|
||||
// The real APT service returns an error if there's a pending APT parameter when this function
|
||||
// is called.
|
||||
|
@ -523,14 +575,13 @@ Result AppletManager::PrepareToStartLibraryApplet(AppletId applet_id) {
|
|||
}
|
||||
|
||||
// If we weren't able to load the native applet title, try to fallback to an HLE implementation.
|
||||
auto applet = HLE::Applets::Applet::Get(applet_id);
|
||||
if (applet) {
|
||||
LOG_WARNING(Service_APT, "applet has already been started id={:03X}", applet_id);
|
||||
if (hle_applets.contains(applet_id)) {
|
||||
LOG_WARNING(Service_APT, "Applet has already been started id={:03X}", applet_id);
|
||||
return ResultSuccess;
|
||||
} else {
|
||||
auto parent = GetAppletSlotId(last_library_launcher_slot);
|
||||
LOG_DEBUG(Service_APT, "Creating HLE applet {:03X} with parent {:03X}", applet_id, parent);
|
||||
return HLE::Applets::Applet::Create(applet_id, parent, false, shared_from_this());
|
||||
return CreateHLEApplet(applet_id, parent, false);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -551,14 +602,13 @@ Result AppletManager::PreloadLibraryApplet(AppletId applet_id) {
|
|||
}
|
||||
|
||||
// If we weren't able to load the native applet title, try to fallback to an HLE implementation.
|
||||
auto applet = HLE::Applets::Applet::Get(applet_id);
|
||||
if (applet) {
|
||||
LOG_WARNING(Service_APT, "applet has already been started id={:08X}", applet_id);
|
||||
if (hle_applets.contains(applet_id)) {
|
||||
LOG_WARNING(Service_APT, "Applet has already been started id={:08X}", applet_id);
|
||||
return ResultSuccess;
|
||||
} else {
|
||||
auto parent = GetAppletSlotId(last_library_launcher_slot);
|
||||
LOG_DEBUG(Service_APT, "Creating HLE applet {:03X} with parent {:03X}", applet_id, parent);
|
||||
return HLE::Applets::Applet::Create(applet_id, parent, true, shared_from_this());
|
||||
return CreateHLEApplet(applet_id, parent, true);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1387,8 +1437,8 @@ static void CaptureFrameBuffer(Core::System& system, u32 capture_offset, VAddr s
|
|||
return;
|
||||
}
|
||||
|
||||
Memory::RasterizerFlushVirtualRegion(src, GSP::FRAMEBUFFER_WIDTH * height * bpp,
|
||||
Memory::FlushMode::Flush);
|
||||
system.Memory().RasterizerFlushVirtualRegion(src, GSP::FRAMEBUFFER_WIDTH * height * bpp,
|
||||
Memory::FlushMode::Flush);
|
||||
|
||||
// Address in VRAM that APT copies framebuffer captures to.
|
||||
constexpr VAddr screen_capture_base_vaddr = Memory::VRAM_VADDR + 0x500000;
|
||||
|
@ -1416,8 +1466,8 @@ static void CaptureFrameBuffer(Core::System& system, u32 capture_offset, VAddr s
|
|||
}
|
||||
}
|
||||
|
||||
Memory::RasterizerFlushVirtualRegion(dst_vaddr, GSP::FRAMEBUFFER_WIDTH_POW2 * height * bpp,
|
||||
Memory::FlushMode::Invalidate);
|
||||
system.Memory().RasterizerFlushVirtualRegion(
|
||||
dst_vaddr, GSP::FRAMEBUFFER_WIDTH_POW2 * height * bpp, Memory::FlushMode::Invalidate);
|
||||
}
|
||||
|
||||
void AppletManager::CaptureFrameBuffers() {
|
||||
|
@ -1441,6 +1491,30 @@ void AppletManager::LoadInputDevices() {
|
|||
Settings::values.current_input_profile.buttons[Settings::NativeButton::Power]);
|
||||
}
|
||||
|
||||
/// Handles updating the current Applet every time it's called.
|
||||
void AppletManager::HLEAppletUpdateEvent(std::uintptr_t user_data, s64 cycles_late) {
|
||||
const auto id = static_cast<AppletId>(user_data);
|
||||
if (!hle_applets.contains(id)) {
|
||||
// Dead applet, exit event loop.
|
||||
LOG_WARNING(Service_APT, "Attempted to update dead applet id={:03X}", id);
|
||||
return;
|
||||
}
|
||||
|
||||
const auto applet = hle_applets[id];
|
||||
if (applet->IsActive()) {
|
||||
applet->Update();
|
||||
}
|
||||
|
||||
// If the applet is still running after the last update, reschedule the event
|
||||
if (applet->IsRunning()) {
|
||||
system.CoreTiming().ScheduleEvent(usToCycles(hle_applet_update_interval_us) - cycles_late,
|
||||
hle_applet_update_event, user_data);
|
||||
} else {
|
||||
// Otherwise the applet has terminated, in which case we should clean it up
|
||||
hle_applets[id] = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void AppletManager::ButtonUpdateEvent(std::uintptr_t user_data, s64 cycles_late) {
|
||||
if (is_device_reload_pending.exchange(false)) {
|
||||
LoadInputDevices();
|
||||
|
@ -1485,7 +1559,10 @@ AppletManager::AppletManager(Core::System& system) : system(system) {
|
|||
slot_data.parameter_event =
|
||||
system.Kernel().CreateEvent(Kernel::ResetType::OneShot, "APT:Parameter");
|
||||
}
|
||||
HLE::Applets::Init();
|
||||
hle_applet_update_event = system.CoreTiming().RegisterEvent(
|
||||
"HLE Applet Update Event", [this](std::uintptr_t user_data, s64 cycles_late) {
|
||||
HLEAppletUpdateEvent(user_data, cycles_late);
|
||||
});
|
||||
button_update_event = system.CoreTiming().RegisterEvent(
|
||||
"APT Button Update Event", [this](std::uintptr_t user_data, s64 cycles_late) {
|
||||
ButtonUpdateEvent(user_data, cycles_late);
|
||||
|
@ -1494,7 +1571,8 @@ AppletManager::AppletManager(Core::System& system) : system(system) {
|
|||
}
|
||||
|
||||
AppletManager::~AppletManager() {
|
||||
HLE::Applets::Shutdown();
|
||||
system.CoreTiming().RemoveEvent(hle_applet_update_event);
|
||||
system.CoreTiming().RemoveEvent(button_update_event);
|
||||
}
|
||||
|
||||
void AppletManager::ReloadInputDevices() {
|
||||
|
|
|
@ -23,6 +23,10 @@ namespace Core {
|
|||
class System;
|
||||
}
|
||||
|
||||
namespace HLE::Applets {
|
||||
class Applet;
|
||||
}
|
||||
|
||||
namespace Service::APT {
|
||||
|
||||
/// Signals used by APT functions
|
||||
|
@ -291,7 +295,6 @@ public:
|
|||
|
||||
ResultVal<Notification> InquireNotification(AppletId app_id);
|
||||
Result SendNotification(Notification notification);
|
||||
void SendNotificationToAll(Notification notification);
|
||||
|
||||
Result PrepareToStartLibraryApplet(AppletId applet_id);
|
||||
Result PreloadLibraryApplet(AppletId applet_id);
|
||||
|
@ -481,6 +484,9 @@ private:
|
|||
// It also affects the results of APT:GetTargetPlatform and APT:GetApplicationRunningMode.
|
||||
bool new_3ds_mode_blocked = false;
|
||||
|
||||
std::unordered_map<AppletId, std::shared_ptr<HLE::Applets::Applet>> hle_applets;
|
||||
Core::TimingEventType* hle_applet_update_event;
|
||||
|
||||
Core::TimingEventType* button_update_event;
|
||||
std::atomic<bool> is_device_reload_pending{true};
|
||||
std::unique_ptr<Input::ButtonDevice> home_button;
|
||||
|
@ -506,10 +512,15 @@ private:
|
|||
/// otherwise it queues for sending when the application registers itself with APT::Enable.
|
||||
void SendApplicationParameterAfterRegistration(const MessageParameter& parameter);
|
||||
|
||||
void SendNotificationToAll(Notification notification);
|
||||
|
||||
void EnsureHomeMenuLoaded();
|
||||
|
||||
void CaptureFrameBuffers();
|
||||
|
||||
Result CreateHLEApplet(AppletId id, AppletId parent, bool preload);
|
||||
void HLEAppletUpdateEvent(std::uintptr_t user_data, s64 cycles_late);
|
||||
|
||||
void LoadInputDevices();
|
||||
void ButtonUpdateEvent(std::uintptr_t user_data, s64 cycles_late);
|
||||
|
||||
|
|
|
@ -1133,8 +1133,7 @@ void Module::APTInterface::GetProgramId(Kernel::HLERequestContext& ctx) {
|
|||
IPC::RequestBuilder rb = rp.MakeBuilder(3, 0);
|
||||
rb.Push(ResultSuccess);
|
||||
|
||||
auto fs_user =
|
||||
Core::System::GetInstance().ServiceManager().GetService<Service::FS::FS_USER>("fs:USER");
|
||||
auto fs_user = apt->system.ServiceManager().GetService<Service::FS::FS_USER>("fs:USER");
|
||||
ASSERT_MSG(fs_user != nullptr, "fs:USER service is missing.");
|
||||
|
||||
auto program_info_result = fs_user->GetProgramLaunchInfo(process_id);
|
||||
|
|
|
@ -517,8 +517,8 @@ void Y2R_U::StartConversion(Kernel::HLERequestContext& ctx) {
|
|||
// dst_image_size would seem to be perfect for this, but it doesn't include the gap :(
|
||||
u32 total_output_size =
|
||||
conversion.input_lines * (conversion.dst.transfer_unit + conversion.dst.gap);
|
||||
Memory::RasterizerFlushVirtualRegion(conversion.dst.address, total_output_size,
|
||||
Memory::FlushMode::FlushAndInvalidate);
|
||||
system.Memory().RasterizerFlushVirtualRegion(conversion.dst.address, total_output_size,
|
||||
Memory::FlushMode::FlushAndInvalidate);
|
||||
|
||||
HW::Y2R::PerformConversion(system.Memory(), conversion);
|
||||
|
||||
|
|
|
@ -477,9 +477,10 @@ static void CopyFrameBuffer(Core::System& system, VAddr dst, VAddr src, u32 stri
|
|||
return;
|
||||
}
|
||||
|
||||
Memory::RasterizerFlushVirtualRegion(src, stride * lines, Memory::FlushMode::Flush);
|
||||
system.Memory().RasterizerFlushVirtualRegion(src, stride * lines, Memory::FlushMode::Flush);
|
||||
std::memcpy(dst_ptr, src_ptr, stride * lines);
|
||||
Memory::RasterizerFlushVirtualRegion(dst, stride * lines, Memory::FlushMode::Invalidate);
|
||||
system.Memory().RasterizerFlushVirtualRegion(dst, stride * lines,
|
||||
Memory::FlushMode::Invalidate);
|
||||
}
|
||||
|
||||
void GSP_GPU::SaveVramSysArea(Kernel::HLERequestContext& ctx) {
|
||||
|
@ -497,8 +498,8 @@ void GSP_GPU::SaveVramSysArea(Kernel::HLERequestContext& ctx) {
|
|||
LOG_INFO(Service_GSP, "called");
|
||||
|
||||
// TODO: This should also save LCD register state.
|
||||
Memory::RasterizerFlushVirtualRegion(Memory::VRAM_VADDR, Memory::VRAM_SIZE,
|
||||
Memory::FlushMode::Flush);
|
||||
system.Memory().RasterizerFlushVirtualRegion(Memory::VRAM_VADDR, Memory::VRAM_SIZE,
|
||||
Memory::FlushMode::Flush);
|
||||
const auto vram = system.Memory().GetPointer(Memory::VRAM_VADDR);
|
||||
saved_vram.emplace(std::vector<u8>(Memory::VRAM_SIZE));
|
||||
std::memcpy(saved_vram.get().data(), vram, Memory::VRAM_SIZE);
|
||||
|
@ -548,8 +549,8 @@ void GSP_GPU::RestoreVramSysArea(Kernel::HLERequestContext& ctx) {
|
|||
// TODO: This should also restore LCD register state.
|
||||
auto vram = system.Memory().GetPointer(Memory::VRAM_VADDR);
|
||||
std::memcpy(vram, saved_vram.get().data(), Memory::VRAM_SIZE);
|
||||
Memory::RasterizerFlushVirtualRegion(Memory::VRAM_VADDR, Memory::VRAM_SIZE,
|
||||
Memory::FlushMode::Invalidate);
|
||||
system.Memory().RasterizerFlushVirtualRegion(Memory::VRAM_VADDR, Memory::VRAM_SIZE,
|
||||
Memory::FlushMode::Invalidate);
|
||||
}
|
||||
|
||||
IPC::RequestBuilder rb = rp.MakeBuilder(1, 0);
|
||||
|
|
|
@ -135,7 +135,7 @@ private:
|
|||
};
|
||||
|
||||
struct MIC_U::Impl {
|
||||
explicit Impl(Core::System& system) : timing(system.CoreTiming()) {
|
||||
explicit Impl(Core::System& system) : system(system), timing(system.CoreTiming()) {
|
||||
buffer_full_event =
|
||||
system.Kernel().CreateEvent(Kernel::ResetType::OneShot, "MIC_U::buffer_full_event");
|
||||
buffer_write_event = timing.RegisterEvent(
|
||||
|
@ -376,7 +376,7 @@ struct MIC_U::Impl {
|
|||
}
|
||||
|
||||
mic = AudioCore::GetInputDetails(Settings::values.input_type.GetValue())
|
||||
.create_input(Settings::values.input_device.GetValue());
|
||||
.create_input(system, Settings::values.input_device.GetValue());
|
||||
if (was_sampling) {
|
||||
StartSampling();
|
||||
}
|
||||
|
@ -392,6 +392,7 @@ struct MIC_U::Impl {
|
|||
bool allow_shell_closed = false;
|
||||
bool clamp = false;
|
||||
std::unique_ptr<AudioCore::Input> mic;
|
||||
Core::System& system;
|
||||
Core::Timing& timing;
|
||||
State state{};
|
||||
Encoding encoding{};
|
||||
|
|
|
@ -36,15 +36,13 @@
|
|||
#include "core/loader/loader.h"
|
||||
|
||||
SERIALIZE_EXPORT_IMPL(Service::PLGLDR::PLG_LDR)
|
||||
SERVICE_CONSTRUCT_IMPL(Service::PLGLDR::PLG_LDR)
|
||||
|
||||
namespace Service::PLGLDR {
|
||||
|
||||
const Kernel::CoreVersion PLG_LDR::plgldr_version = Kernel::CoreVersion(1, 0, 0);
|
||||
PLG_LDR::PluginLoaderContext PLG_LDR::plgldr_context;
|
||||
bool PLG_LDR::allow_game_change = true;
|
||||
PAddr PLG_LDR::plugin_fb_addr = 0;
|
||||
static const Kernel::CoreVersion plgldr_version = Kernel::CoreVersion(1, 0, 0);
|
||||
|
||||
PLG_LDR::PLG_LDR() : ServiceFramework{"plg:ldr", 1} {
|
||||
PLG_LDR::PLG_LDR(Core::System& system_) : ServiceFramework{"plg:ldr", 1}, system(system_) {
|
||||
static const FunctionInfo functions[] = {
|
||||
// clang-format off
|
||||
{0x0001, nullptr, "LoadPlugin"},
|
||||
|
@ -67,6 +65,33 @@ PLG_LDR::PLG_LDR() : ServiceFramework{"plg:ldr", 1} {
|
|||
plgldr_context.plugin_loaded = false;
|
||||
}
|
||||
|
||||
template <class Archive>
|
||||
void PLG_LDR::PluginLoaderContext::serialize(Archive& ar, const unsigned int) {
|
||||
ar& is_enabled;
|
||||
ar& plugin_loaded;
|
||||
ar& is_default_path;
|
||||
ar& plugin_path;
|
||||
ar& use_user_load_parameters;
|
||||
ar& user_load_parameters;
|
||||
ar& plg_event;
|
||||
ar& plg_reply;
|
||||
ar& memory_changed_handle;
|
||||
ar& is_exe_load_function_set;
|
||||
ar& exe_load_checksum;
|
||||
ar& load_exe_func;
|
||||
ar& load_exe_args;
|
||||
}
|
||||
SERIALIZE_IMPL(PLG_LDR::PluginLoaderContext)
|
||||
|
||||
template <class Archive>
|
||||
void PLG_LDR::serialize(Archive& ar, const unsigned int) {
|
||||
ar& boost::serialization::base_object<Kernel::SessionRequestHandler>(*this);
|
||||
ar& plgldr_context;
|
||||
ar& plugin_fb_addr;
|
||||
ar& allow_game_change;
|
||||
}
|
||||
SERIALIZE_IMPL(PLG_LDR)
|
||||
|
||||
void PLG_LDR::OnProcessRun(Kernel::Process& process, Kernel::KernelSystem& kernel) {
|
||||
if (!plgldr_context.is_enabled || plgldr_context.plugin_loaded) {
|
||||
return;
|
||||
|
@ -91,7 +116,7 @@ void PLG_LDR::OnProcessRun(Kernel::Process& process, Kernel::KernelSystem& kerne
|
|||
std::string(plgldr_context.user_load_parameters.path + 1);
|
||||
plgldr_context.is_default_path = false;
|
||||
plgldr_context.plugin_path = plugin_file;
|
||||
plugin_loader.Load(plgldr_context, process, kernel);
|
||||
plugin_loader.Load(plgldr_context, process, kernel, *this);
|
||||
} else {
|
||||
const std::string plugin_root =
|
||||
FileUtil::GetUserPath(FileUtil::UserPath::SDMCDir) + "luma/plugins/";
|
||||
|
@ -103,7 +128,7 @@ void PLG_LDR::OnProcessRun(Kernel::Process& process, Kernel::KernelSystem& kerne
|
|||
if (!child.isDirectory && child.physicalName.ends_with(".3gx")) {
|
||||
plgldr_context.is_default_path = false;
|
||||
plgldr_context.plugin_path = child.physicalName;
|
||||
if (plugin_loader.Load(plgldr_context, process, kernel) ==
|
||||
if (plugin_loader.Load(plgldr_context, process, kernel, *this) ==
|
||||
Loader::ResultStatus::Success) {
|
||||
return;
|
||||
}
|
||||
|
@ -114,7 +139,7 @@ void PLG_LDR::OnProcessRun(Kernel::Process& process, Kernel::KernelSystem& kerne
|
|||
if (FileUtil::Exists(default_path)) {
|
||||
plgldr_context.is_default_path = true;
|
||||
plgldr_context.plugin_path = default_path;
|
||||
plugin_loader.Load(plgldr_context, process, kernel);
|
||||
plugin_loader.Load(plgldr_context, process, kernel, *this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -134,9 +159,9 @@ ResultVal<Kernel::Handle> PLG_LDR::GetMemoryChangedHandle(Kernel::KernelSystem&
|
|||
return plgldr_context.memory_changed_handle;
|
||||
}
|
||||
|
||||
std::shared_ptr<Kernel::Event> evt = kernel.CreateEvent(
|
||||
Kernel::ResetType::OneShot,
|
||||
fmt::format("event-{:08x}", Core::System::GetInstance().GetRunningCore().GetReg(14)));
|
||||
std::shared_ptr<Kernel::Event> evt =
|
||||
kernel.CreateEvent(Kernel::ResetType::OneShot,
|
||||
fmt::format("event-{:08x}", system.GetRunningCore().GetReg(14)));
|
||||
R_TRY(kernel.GetCurrentProcess()->handle_table.Create(
|
||||
std::addressof(plgldr_context.memory_changed_handle), std::move(evt)));
|
||||
return plgldr_context.memory_changed_handle;
|
||||
|
@ -274,7 +299,7 @@ std::shared_ptr<PLG_LDR> GetService(Core::System& system) {
|
|||
}
|
||||
|
||||
void InstallInterfaces(Core::System& system) {
|
||||
std::make_shared<PLG_LDR>()->InstallAsNamedPort(system.Kernel());
|
||||
std::make_shared<PLG_LDR>(system)->InstallAsNamedPort(system.Kernel());
|
||||
}
|
||||
|
||||
} // namespace Service::PLGLDR
|
||||
|
|
|
@ -22,7 +22,7 @@
|
|||
#pragma once
|
||||
|
||||
#include <memory>
|
||||
#include <boost/serialization/version.hpp>
|
||||
#include <boost/serialization/export.hpp>
|
||||
#include "core/hle/service/service.h"
|
||||
|
||||
namespace Core {
|
||||
|
@ -70,25 +70,11 @@ public:
|
|||
u32_le load_exe_args[4] = {0};
|
||||
|
||||
template <class Archive>
|
||||
void serialize(Archive& ar, const unsigned int) {
|
||||
ar& is_enabled;
|
||||
ar& plugin_loaded;
|
||||
ar& is_default_path;
|
||||
ar& plugin_path;
|
||||
ar& use_user_load_parameters;
|
||||
ar& user_load_parameters;
|
||||
ar& plg_event;
|
||||
ar& plg_reply;
|
||||
ar& memory_changed_handle;
|
||||
ar& is_exe_load_function_set;
|
||||
ar& exe_load_checksum;
|
||||
ar& load_exe_func;
|
||||
ar& load_exe_args;
|
||||
}
|
||||
void serialize(Archive& ar, const unsigned int);
|
||||
friend class boost::serialization::access;
|
||||
};
|
||||
|
||||
PLG_LDR();
|
||||
PLG_LDR(Core::System& system_);
|
||||
~PLG_LDR() {}
|
||||
|
||||
void OnProcessRun(Kernel::Process& process, Kernel::KernelSystem& kernel);
|
||||
|
@ -96,31 +82,31 @@ public:
|
|||
ResultVal<Kernel::Handle> GetMemoryChangedHandle(Kernel::KernelSystem& kernel);
|
||||
void OnMemoryChanged(Kernel::Process& process, Kernel::KernelSystem& kernel);
|
||||
|
||||
static void SetEnabled(bool enabled) {
|
||||
void SetEnabled(bool enabled) {
|
||||
plgldr_context.is_enabled = enabled;
|
||||
}
|
||||
static bool GetEnabled() {
|
||||
bool GetEnabled() {
|
||||
return plgldr_context.is_enabled;
|
||||
}
|
||||
static void SetAllowGameChangeState(bool allow) {
|
||||
void SetAllowGameChangeState(bool allow) {
|
||||
allow_game_change = allow;
|
||||
}
|
||||
static bool GetAllowGameChangeState() {
|
||||
bool GetAllowGameChangeState() {
|
||||
return allow_game_change;
|
||||
}
|
||||
static void SetPluginFBAddr(PAddr addr) {
|
||||
void SetPluginFBAddr(PAddr addr) {
|
||||
plugin_fb_addr = addr;
|
||||
}
|
||||
static PAddr GetPluginFBAddr() {
|
||||
PAddr GetPluginFBAddr() {
|
||||
return plugin_fb_addr;
|
||||
}
|
||||
|
||||
private:
|
||||
static const Kernel::CoreVersion plgldr_version;
|
||||
Core::System& system;
|
||||
|
||||
static PluginLoaderContext plgldr_context;
|
||||
static PAddr plugin_fb_addr;
|
||||
static bool allow_game_change;
|
||||
PluginLoaderContext plgldr_context;
|
||||
PAddr plugin_fb_addr = 0;
|
||||
bool allow_game_change = true;
|
||||
|
||||
void IsEnabled(Kernel::HLERequestContext& ctx);
|
||||
void SetEnabled(Kernel::HLERequestContext& ctx);
|
||||
|
@ -131,12 +117,7 @@ private:
|
|||
void GetPluginPath(Kernel::HLERequestContext& ctx);
|
||||
|
||||
template <class Archive>
|
||||
void serialize(Archive& ar, const unsigned int) {
|
||||
ar& boost::serialization::base_object<Kernel::SessionRequestHandler>(*this);
|
||||
ar& plgldr_context;
|
||||
ar& plugin_fb_addr;
|
||||
ar& allow_game_change;
|
||||
}
|
||||
void serialize(Archive& ar, const unsigned int);
|
||||
friend class boost::serialization::access;
|
||||
};
|
||||
|
||||
|
@ -147,3 +128,4 @@ void InstallInterfaces(Core::System& system);
|
|||
} // namespace Service::PLGLDR
|
||||
|
||||
BOOST_CLASS_EXPORT_KEY(Service::PLGLDR::PLG_LDR)
|
||||
SERVICE_CONSTRUCT(Service::PLGLDR::PLG_LDR)
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
#include "core/hle/service/ptm/ptm_u.h"
|
||||
|
||||
SERIALIZE_EXPORT_IMPL(Service::PTM::Module)
|
||||
SERVICE_CONSTRUCT_IMPL(Service::PTM::Module)
|
||||
|
||||
namespace Service::PTM {
|
||||
|
||||
|
@ -136,7 +137,7 @@ void Module::Interface::CheckNew3DS(Kernel::HLERequestContext& ctx) {
|
|||
void Module::Interface::GetSystemTime(Kernel::HLERequestContext& ctx) {
|
||||
IPC::RequestParser rp(ctx);
|
||||
|
||||
auto& share_page = Core::System::GetInstance().Kernel().GetSharedPageHandler();
|
||||
auto& share_page = ptm->system.Kernel().GetSharedPageHandler();
|
||||
const u64 console_time = share_page.GetSystemTimeSince2000();
|
||||
|
||||
IPC::RequestBuilder rb = rp.MakeBuilder(3, 0);
|
||||
|
@ -207,7 +208,7 @@ static GameCoin ReadGameCoinData() {
|
|||
return gamecoin_data;
|
||||
}
|
||||
|
||||
Module::Module() {
|
||||
Module::Module(Core::System& system_) : system(system_) {
|
||||
// Open the SharedExtSaveData archive 0xF000000B and create the gamecoin.dat file if it doesn't
|
||||
// exist
|
||||
const std::string& nand_directory = FileUtil::GetUserPath(FileUtil::UserPath::NANDDir);
|
||||
|
@ -221,6 +222,14 @@ Module::Module() {
|
|||
}
|
||||
}
|
||||
|
||||
template <class Archive>
|
||||
void Module::serialize(Archive& ar, const unsigned int) {
|
||||
ar& shell_open;
|
||||
ar& battery_is_charging;
|
||||
ar& pedometer_is_counting;
|
||||
}
|
||||
SERIALIZE_IMPL(Module)
|
||||
|
||||
u16 Module::GetPlayCoins() {
|
||||
return ReadGameCoinData().total_coins;
|
||||
}
|
||||
|
@ -238,7 +247,7 @@ Module::Interface::Interface(std::shared_ptr<Module> ptm, const char* name, u32
|
|||
|
||||
void InstallInterfaces(Core::System& system) {
|
||||
auto& service_manager = system.ServiceManager();
|
||||
auto ptm = std::make_shared<Module>();
|
||||
auto ptm = std::make_shared<Module>(system);
|
||||
std::make_shared<PTM_Gets>(ptm)->InstallAsService(service_manager);
|
||||
std::make_shared<PTM_Play>(ptm)->InstallAsService(service_manager);
|
||||
std::make_shared<PTM_Sets>(ptm)->InstallAsService(service_manager);
|
||||
|
|
|
@ -47,7 +47,9 @@ void CheckNew3DS(IPC::RequestBuilder& rb);
|
|||
|
||||
class Module final {
|
||||
public:
|
||||
Module();
|
||||
explicit Module(Core::System& system_);
|
||||
~Module() = default;
|
||||
|
||||
static u16 GetPlayCoins();
|
||||
static void SetPlayCoins(u16 play_coins);
|
||||
|
||||
|
@ -150,16 +152,14 @@ public:
|
|||
};
|
||||
|
||||
private:
|
||||
Core::System& system;
|
||||
|
||||
bool shell_open = true;
|
||||
bool battery_is_charging = true;
|
||||
bool pedometer_is_counting = false;
|
||||
|
||||
template <class Archive>
|
||||
void serialize(Archive& ar, const unsigned int) {
|
||||
ar& shell_open;
|
||||
ar& battery_is_charging;
|
||||
ar& pedometer_is_counting;
|
||||
}
|
||||
void serialize(Archive& ar, const unsigned int);
|
||||
friend class boost::serialization::access;
|
||||
};
|
||||
|
||||
|
@ -168,3 +168,4 @@ void InstallInterfaces(Core::System& system);
|
|||
} // namespace Service::PTM
|
||||
|
||||
BOOST_CLASS_EXPORT_KEY(Service::PTM::Module)
|
||||
SERVICE_CONSTRUCT(Service::PTM::Module)
|
||||
|
|
|
@ -249,7 +249,7 @@ void SRV::PublishToSubscriber(Kernel::HLERequestContext& ctx) {
|
|||
// console. Normally, this is handled by NS. If notification handling is properly implemented,
|
||||
// this piece of code should be removed, and handled by subscribing from NS instead.
|
||||
if (notification_id == 0x203) {
|
||||
Core::System::GetInstance().RequestShutdown();
|
||||
system.RequestShutdown();
|
||||
} else {
|
||||
LOG_WARNING(Service_SRV, "(STUBBED) called, notification_id=0x{:X}, flags={}",
|
||||
notification_id, flags);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue