diff options
Diffstat (limited to 'src/core/hle')
-rw-r--r-- | src/core/hle/kernel/scheduler.cpp | 2 | ||||
-rw-r--r-- | src/core/hle/kernel/scheduler.h | 6 | ||||
-rw-r--r-- | src/core/hle/kernel/svc.cpp | 3 | ||||
-rw-r--r-- | src/core/hle/kernel/thread.cpp | 4 | ||||
-rw-r--r-- | src/core/hle/kernel/thread.h | 2 | ||||
-rw-r--r-- | src/core/hle/service/hid/hid.cpp | 1 | ||||
-rw-r--r-- | src/core/hle/service/hid/hid.h | 4 | ||||
-rw-r--r-- | src/core/hle/service/ns/pl_u.cpp | 56 | ||||
-rw-r--r-- | src/core/hle/service/set/set.cpp | 51 | ||||
-rw-r--r-- | src/core/hle/service/set/set.h | 2 |
10 files changed, 109 insertions, 22 deletions
diff --git a/src/core/hle/kernel/scheduler.cpp b/src/core/hle/kernel/scheduler.cpp index e770b9103..69c812f16 100644 --- a/src/core/hle/kernel/scheduler.cpp +++ b/src/core/hle/kernel/scheduler.cpp @@ -17,7 +17,7 @@ namespace Kernel { std::mutex Scheduler::scheduler_mutex; -Scheduler::Scheduler(ARM_Interface* cpu_core) : cpu_core(cpu_core) {} +Scheduler::Scheduler(Core::ARM_Interface* cpu_core) : cpu_core(cpu_core) {} Scheduler::~Scheduler() { for (auto& thread : thread_list) { diff --git a/src/core/hle/kernel/scheduler.h b/src/core/hle/kernel/scheduler.h index 6a61ef64e..744990c9b 100644 --- a/src/core/hle/kernel/scheduler.h +++ b/src/core/hle/kernel/scheduler.h @@ -11,13 +11,15 @@ #include "core/hle/kernel/object.h" #include "core/hle/kernel/thread.h" +namespace Core { class ARM_Interface; +} namespace Kernel { class Scheduler final { public: - explicit Scheduler(ARM_Interface* cpu_core); + explicit Scheduler(Core::ARM_Interface* cpu_core); ~Scheduler(); /// Returns whether there are any threads that are ready to run. @@ -70,7 +72,7 @@ private: SharedPtr<Thread> current_thread = nullptr; - ARM_Interface* cpu_core; + Core::ARM_Interface* cpu_core; static std::mutex scheduler_mutex; }; diff --git a/src/core/hle/kernel/svc.cpp b/src/core/hle/kernel/svc.cpp index 6be5c474e..cb6253398 100644 --- a/src/core/hle/kernel/svc.cpp +++ b/src/core/hle/kernel/svc.cpp @@ -319,8 +319,7 @@ static ResultCode GetInfo(u64* result, u64 info_id, u64 handle, u64 info_sub_id) *result = Core::CurrentProcess()->is_virtual_address_memory_enabled; break; case GetInfoType::TitleId: - LOG_WARNING(Kernel_SVC, "(STUBBED) Attempted to query titleid, returned 0"); - *result = 0; + *result = Core::CurrentProcess()->program_id; break; case GetInfoType::PrivilegedProcessId: LOG_WARNING(Kernel_SVC, diff --git a/src/core/hle/kernel/thread.cpp b/src/core/hle/kernel/thread.cpp index cf4f94822..4ffd8d5cc 100644 --- a/src/core/hle/kernel/thread.cpp +++ b/src/core/hle/kernel/thread.cpp @@ -283,9 +283,9 @@ static std::tuple<std::size_t, std::size_t, bool> GetFreeThreadLocalSlot( * @param entry_point Address of entry point for execution * @param arg User argument for thread */ -static void ResetThreadContext(ARM_Interface::ThreadContext& context, VAddr stack_top, +static void ResetThreadContext(Core::ARM_Interface::ThreadContext& context, VAddr stack_top, VAddr entry_point, u64 arg) { - memset(&context, 0, sizeof(ARM_Interface::ThreadContext)); + memset(&context, 0, sizeof(Core::ARM_Interface::ThreadContext)); context.cpu_registers[0] = arg; context.pc = entry_point; diff --git a/src/core/hle/kernel/thread.h b/src/core/hle/kernel/thread.h index adc804248..06edc296d 100644 --- a/src/core/hle/kernel/thread.h +++ b/src/core/hle/kernel/thread.h @@ -204,7 +204,7 @@ public: return status == ThreadStatus::WaitSynchAll; } - ARM_Interface::ThreadContext context; + Core::ARM_Interface::ThreadContext context; u32 thread_id; diff --git a/src/core/hle/service/hid/hid.cpp b/src/core/hle/service/hid/hid.cpp index 970942d3f..c0ba330dc 100644 --- a/src/core/hle/service/hid/hid.cpp +++ b/src/core/hle/service/hid/hid.cpp @@ -17,6 +17,7 @@ #include "core/hle/service/hid/irs.h" #include "core/hle/service/hid/xcd.h" #include "core/hle/service/service.h" +#include "core/settings.h" namespace Service::HID { diff --git a/src/core/hle/service/hid/hid.h b/src/core/hle/service/hid/hid.h index e298f23a6..88d926808 100644 --- a/src/core/hle/service/hid/hid.h +++ b/src/core/hle/service/hid/hid.h @@ -4,8 +4,10 @@ #pragma once +#include <array> +#include "common/bit_field.h" +#include "common/common_types.h" #include "core/hle/service/service.h" -#include "core/settings.h" namespace Service::HID { diff --git a/src/core/hle/service/ns/pl_u.cpp b/src/core/hle/service/ns/pl_u.cpp index 53cbf1a6e..923a52cc5 100644 --- a/src/core/hle/service/ns/pl_u.cpp +++ b/src/core/hle/service/ns/pl_u.cpp @@ -35,6 +35,14 @@ static constexpr std::array<std::pair<FontArchives, const char*>, 7> SHARED_FONT std::make_pair(FontArchives::Extension, "nintendo_ext_003.bfttf"), std::make_pair(FontArchives::Extension, "nintendo_ext2_003.bfttf")}; +static constexpr std::array<const char*, 7> SHARED_FONTS_TTF{"FontStandard.ttf", + "FontChineseSimplified.ttf", + "FontExtendedChineseSimplified.ttf", + "FontChineseTraditional.ttf", + "FontKorean.ttf", + "FontNintendoExtended.ttf", + "FontNintendoExtended2.ttf"}; + // The below data is specific to shared font data dumped from Switch on f/w 2.2 // Virtual address and offsets/sizes likely will vary by dump static constexpr VAddr SHARED_FONT_MEM_VADDR{0x00000009d3016000ULL}; @@ -76,6 +84,17 @@ void DecryptSharedFont(const std::vector<u32>& input, std::vector<u8>& output, s offset += transformed_font.size() * sizeof(u32); } +static void EncryptSharedFont(const std::vector<u8>& input, std::vector<u8>& output, + size_t& offset) { + ASSERT_MSG(offset + input.size() + 8 < SHARED_FONT_MEM_SIZE, "Shared fonts exceeds 17mb!"); + const u32 KEY = EXPECTED_MAGIC ^ EXPECTED_RESULT; + std::memcpy(output.data() + offset, &EXPECTED_RESULT, sizeof(u32)); // Magic header + const u32 ENC_SIZE = static_cast<u32>(input.size()) ^ KEY; + std::memcpy(output.data() + offset + sizeof(u32), &ENC_SIZE, sizeof(u32)); + std::memcpy(output.data() + offset + (sizeof(u32) * 2), input.data(), input.size()); + offset += input.size() + (sizeof(u32) * 2); +} + static u32 GetU32Swapped(const u8* data) { u32 value; std::memcpy(&value, data, sizeof(value)); @@ -109,10 +128,10 @@ PL_U::PL_U() : ServiceFramework("pl:u") { RegisterHandlers(functions); // Attempt to load shared font data from disk const auto nand = FileSystem::GetSystemNANDContents(); + size_t offset = 0; // Rebuild shared fonts from data ncas if (nand->HasEntry(static_cast<u64>(FontArchives::Standard), FileSys::ContentRecordType::Data)) { - size_t offset = 0; shared_font = std::make_shared<std::vector<u8>>(SHARED_FONT_MEM_SIZE); for (auto font : SHARED_FONTS) { const auto nca = @@ -152,18 +171,45 @@ PL_U::PL_U() : ServiceFramework("pl:u") { DecryptSharedFont(font_data_u32, *shared_font, offset); SHARED_FONT_REGIONS.push_back(region); } + } else { - const std::string filepath{FileUtil::GetUserPath(FileUtil::UserPath::SysDataDir) + - SHARED_FONT}; + shared_font = std::make_shared<std::vector<u8>>( + SHARED_FONT_MEM_SIZE); // Shared memory needs to always be allocated and a fixed size + + const std::string user_path = FileUtil::GetUserPath(FileUtil::UserPath::SysDataDir); + const std::string filepath{user_path + SHARED_FONT}; + // Create path if not already created if (!FileUtil::CreateFullPath(filepath)) { LOG_ERROR(Service_NS, "Failed to create sharedfonts path \"{}\"!", filepath); return; } + + bool using_ttf = false; + for (const char* font_ttf : SHARED_FONTS_TTF) { + if (FileUtil::Exists(user_path + font_ttf)) { + using_ttf = true; + FileUtil::IOFile file(user_path + font_ttf, "rb"); + if (file.IsOpen()) { + std::vector<u8> ttf_bytes(file.GetSize()); + file.ReadBytes<u8>(ttf_bytes.data(), ttf_bytes.size()); + FontRegion region{ + static_cast<u32>(offset + 8), + static_cast<u32>(ttf_bytes.size())}; // Font offset and size do not account + // for the header + EncryptSharedFont(ttf_bytes, *shared_font, offset); + SHARED_FONT_REGIONS.push_back(region); + } else { + LOG_WARNING(Service_NS, "Unable to load font: {}", font_ttf); + } + } else if (using_ttf) { + LOG_WARNING(Service_NS, "Unable to find font: {}", font_ttf); + } + } + if (using_ttf) + return; FileUtil::IOFile file(filepath, "rb"); - shared_font = std::make_shared<std::vector<u8>>( - SHARED_FONT_MEM_SIZE); // Shared memory needs to always be allocated and a fixed size if (file.IsOpen()) { // Read shared font data ASSERT(file.GetSize() == SHARED_FONT_MEM_SIZE); diff --git a/src/core/hle/service/set/set.cpp b/src/core/hle/service/set/set.cpp index a461e72ec..92b0640e8 100644 --- a/src/core/hle/service/set/set.cpp +++ b/src/core/hle/service/set/set.cpp @@ -32,24 +32,59 @@ constexpr std::array<LanguageCode, 17> available_language_codes = {{ LanguageCode::ZH_HANT, }}; +constexpr size_t pre4_0_0_max_entries = 0xF; +constexpr size_t post4_0_0_max_entries = 0x40; + LanguageCode GetLanguageCodeFromIndex(size_t index) { return available_language_codes.at(index); } -void SET::GetAvailableLanguageCodes(Kernel::HLERequestContext& ctx) { - ctx.WriteBuffer(available_language_codes); +template <size_t size> +static std::array<LanguageCode, size> MakeLanguageCodeSubset() { + std::array<LanguageCode, size> arr; + std::copy_n(available_language_codes.begin(), size, arr.begin()); + return arr; +} +static void PushResponseLanguageCode(Kernel::HLERequestContext& ctx, size_t max_size) { IPC::ResponseBuilder rb{ctx, 3}; rb.Push(RESULT_SUCCESS); - rb.Push(static_cast<u32>(available_language_codes.size())); + if (available_language_codes.size() > max_size) + rb.Push(static_cast<u32>(max_size)); + else + rb.Push(static_cast<u32>(available_language_codes.size())); +} + +void SET::GetAvailableLanguageCodes(Kernel::HLERequestContext& ctx) { + if (available_language_codes.size() > pre4_0_0_max_entries) + ctx.WriteBuffer(MakeLanguageCodeSubset<pre4_0_0_max_entries>()); + else + ctx.WriteBuffer(available_language_codes); + + PushResponseLanguageCode(ctx, pre4_0_0_max_entries); + + LOG_DEBUG(Service_SET, "called"); +} + +void SET::GetAvailableLanguageCodes2(Kernel::HLERequestContext& ctx) { + if (available_language_codes.size() > post4_0_0_max_entries) + ctx.WriteBuffer(MakeLanguageCodeSubset<post4_0_0_max_entries>()); + else + ctx.WriteBuffer(available_language_codes); + + PushResponseLanguageCode(ctx, post4_0_0_max_entries); LOG_DEBUG(Service_SET, "called"); } void SET::GetAvailableLanguageCodeCount(Kernel::HLERequestContext& ctx) { - IPC::ResponseBuilder rb{ctx, 3}; - rb.Push(RESULT_SUCCESS); - rb.Push(static_cast<u32>(available_language_codes.size())); + PushResponseLanguageCode(ctx, pre4_0_0_max_entries); + + LOG_DEBUG(Service_SET, "called"); +} + +void SET::GetAvailableLanguageCodeCount2(Kernel::HLERequestContext& ctx) { + PushResponseLanguageCode(ctx, post4_0_0_max_entries); LOG_DEBUG(Service_SET, "called"); } @@ -69,8 +104,8 @@ SET::SET() : ServiceFramework("set") { {2, nullptr, "MakeLanguageCode"}, {3, &SET::GetAvailableLanguageCodeCount, "GetAvailableLanguageCodeCount"}, {4, nullptr, "GetRegionCode"}, - {5, &SET::GetAvailableLanguageCodes, "GetAvailableLanguageCodes2"}, - {6, &SET::GetAvailableLanguageCodeCount, "GetAvailableLanguageCodeCount2"}, + {5, &SET::GetAvailableLanguageCodes2, "GetAvailableLanguageCodes2"}, + {6, &SET::GetAvailableLanguageCodeCount2, "GetAvailableLanguageCodeCount2"}, {7, nullptr, "GetKeyCodeMap"}, {8, nullptr, "GetQuestFlag"}, }; diff --git a/src/core/hle/service/set/set.h b/src/core/hle/service/set/set.h index 4232b6162..669e740b7 100644 --- a/src/core/hle/service/set/set.h +++ b/src/core/hle/service/set/set.h @@ -38,7 +38,9 @@ public: private: void GetLanguageCode(Kernel::HLERequestContext& ctx); void GetAvailableLanguageCodes(Kernel::HLERequestContext& ctx); + void GetAvailableLanguageCodes2(Kernel::HLERequestContext& ctx); void GetAvailableLanguageCodeCount(Kernel::HLERequestContext& ctx); + void GetAvailableLanguageCodeCount2(Kernel::HLERequestContext& ctx); }; } // namespace Service::Set |