From f992ecacab82f163bb5c645f20cc9da7c79e9e2a Mon Sep 17 00:00:00 2001 From: wheremyfoodat Date: Thu, 26 Jan 2023 01:26:22 +0200 Subject: [PATCH] [CFG] Add more configs --- include/services/cfg.hpp | 3 +++ src/core/services/cfg.cpp | 42 ++++++++++++++++++++++++++++++++++++++- 2 files changed, 44 insertions(+), 1 deletion(-) diff --git a/include/services/cfg.hpp b/include/services/cfg.hpp index 4eae51b5..64667ef8 100644 --- a/include/services/cfg.hpp +++ b/include/services/cfg.hpp @@ -1,4 +1,5 @@ #pragma once +#include #include "helpers.hpp" #include "logger.hpp" #include "memory.hpp" @@ -8,6 +9,8 @@ class CFGService { Memory& mem; MAKE_LOG_FUNCTION(log, cfgLogger) + void writeStringU16(u32 pointer, const std::u16string& string); + // Service functions void getConfigInfoBlk2(u32 messagePointer); void secureInfoGetRegion(u32 messagePointer); diff --git a/src/core/services/cfg.cpp b/src/core/services/cfg.cpp index c5f68c15..66192485 100644 --- a/src/core/services/cfg.cpp +++ b/src/core/services/cfg.cpp @@ -26,6 +26,16 @@ void CFGService::handleSyncRequest(u32 messagePointer) { } } +// Write a UTF16 string to 3DS memory starting at "pointer". Appends a null terminator. +void CFGService::writeStringU16(u32 pointer, const std::u16string& string) { + for (auto c : string) { + mem.write16(pointer, static_cast(c)); + pointer += 2; + } + + mem.write16(pointer, static_cast(u'\0')); // Null terminator +} + void CFGService::getConfigInfoBlk2(u32 messagePointer) { u32 size = mem.read32(messagePointer + 4); u32 blockID = mem.read32(messagePointer + 8); @@ -42,8 +52,38 @@ void CFGService::getConfigInfoBlk2(u32 messagePointer) { mem.write8(output + 1, 0); // Unknown mem.write8(output + 2, 2); // Province (Temporarily stubbed to Washington DC like Citra) mem.write8(output + 3, 49); // Country code (Temporarily stubbed to USA like Citra) - }else if (size == 0x20 && blockID == 0x50005) { + } else if (size == 0x20 && blockID == 0x50005) { printf("[Unimplemented] Read stereo display settings from NAND\n"); + } else if (size == 0x1C && blockID == 0xA0000) { // Username + writeStringU16(output, u"Pander"); + } else if (size == 0xC0 && blockID == 0xC0000) { // Parental restrictions info + for (int i = 0; i < 0xC0; i++) + mem.write8(output + i, 0); + } else if (size == 4 && blockID == 0xD0000) { // Agreed EULA version (first 2 bytes) and latest EULA version (next 2 bytes) + log("Read EULA info\n"); + mem.write16(output, 0x0202); // Agreed EULA version = 2.2 (Random number. TODO: Check) + mem.write16(output + 2, 0x0202); // Latest EULA version = 2.2 + } else if (size == 0x800 && blockID == 0xB0001) { // UTF-16 name for our country in every language at 0x80 byte intervals + constexpr size_t languageCount = 16; + constexpr size_t nameSize = 0x80; // Max size of each name in bytes + std::u16string name = u"PandaLand (Home of PandaSemi LLC) (aka Pandistan)"; // Note: This + the null terminator needs to fit in 0x80 bytes + + for (int i = 0; i < languageCount; i++) { + u32 pointer = output + i * nameSize; + writeStringU16(pointer, name); + } + } else if (size == 0x800 && blockID == 0xB0002) { // UTF-16 name for our state in every language at 0x80 byte intervals + constexpr size_t languageCount = 16; + constexpr size_t nameSize = 0x80; // Max size of each name in bytes + std::u16string name = u"Pandington"; // Note: This + the null terminator needs to fit in 0x80 bytes + + for (int i = 0; i < languageCount; i++) { + u32 pointer = output + i * nameSize; + writeStringU16(pointer, name); + } + } else if (size == 4 && blockID == 0xB0003) { // Coordinates (latidude and longtitude) as s16 + mem.write16(output, 0); // Latitude + mem.write16(output + 2, 0); // Longtitude } else { Helpers::panic("Unhandled GetConfigInfoBlk2 configuration"); }