Add CFG::GetConfigInfoBlk8 implementation

This commit is contained in:
wheremyfoodat 2023-09-24 18:32:37 +03:00
parent d9ddb65b8c
commit fe8a23e0d9
2 changed files with 52 additions and 34 deletions

View file

@ -15,6 +15,7 @@ class CFGService {
// Service functions // Service functions
void getConfigInfoBlk2(u32 messagePointer); void getConfigInfoBlk2(u32 messagePointer);
void getConfigInfoBlk8(u32 messagePointer);
void getCountryCodeID(u32 messagePointer); void getCountryCodeID(u32 messagePointer);
void getLocalFriendCodeSeed(u32 messagePointer); void getLocalFriendCodeSeed(u32 messagePointer);
void getRegionCanadaUSA(u32 messagePointer); void getRegionCanadaUSA(u32 messagePointer);
@ -23,6 +24,8 @@ class CFGService {
void secureInfoGetByte101(u32 messagePointer); void secureInfoGetByte101(u32 messagePointer);
void secureInfoGetRegion(u32 messagePointer); void secureInfoGetRegion(u32 messagePointer);
void getConfigInfo(u32 output, u32 blockID, u32 size, u32 permissionMask);
public: public:
enum class Type { enum class Type {
U, // cfg:u U, // cfg:u

View file

@ -11,6 +11,7 @@
namespace CFGCommands { namespace CFGCommands {
enum : u32 { enum : u32 {
GetConfigInfoBlk2 = 0x00010082, GetConfigInfoBlk2 = 0x00010082,
GetConfigInfoBlk8 = 0x04010082,
SecureInfoGetRegion = 0x00020000, SecureInfoGetRegion = 0x00020000,
GenHashConsoleUnique = 0x00030040, GenHashConsoleUnique = 0x00030040,
GetRegionCanadaUSA = 0x00040000, GetRegionCanadaUSA = 0x00040000,
@ -61,77 +62,91 @@ void CFGService::getConfigInfoBlk2(u32 messagePointer) {
u32 output = mem.read32(messagePointer + 16); // Pointer to write the output data to u32 output = mem.read32(messagePointer + 16); // Pointer to write the output data to
log("CFG::GetConfigInfoBlk2 (size = %X, block ID = %X, output pointer = %08X\n", size, blockID, output); log("CFG::GetConfigInfoBlk2 (size = %X, block ID = %X, output pointer = %08X\n", size, blockID, output);
getConfigInfo(output, blockID, size, 0x2);
mem.write32(messagePointer, IPC::responseHeader(0x1, 1, 2));
mem.write32(messagePointer + 4, Result::Success);
}
void CFGService::getConfigInfoBlk8(u32 messagePointer) {
u32 size = mem.read32(messagePointer + 4);
u32 blockID = mem.read32(messagePointer + 8);
u32 output = mem.read32(messagePointer + 16); // Pointer to write the output data to
log("CFG::GetConfigInfoBlk8 (size = %X, block ID = %X, output pointer = %08X\n", size, blockID, output);
getConfigInfo(output, blockID, size, 0x8);
mem.write32(messagePointer, IPC::responseHeader(0x401, 1, 2));
mem.write32(messagePointer + 4, Result::Success);
}
void CFGService::getConfigInfo(u32 output, u32 blockID, u32 size, u32 permissionMask) {
// TODO: Make this not bad // TODO: Make this not bad
if (size == 1 && blockID == 0x70001) { // Sound output mode if (size == 1 && blockID == 0x70001) { // Sound output mode
mem.write8(output, static_cast<u8>(DSPService::SoundOutputMode::Stereo)); mem.write8(output, static_cast<u8>(DSPService::SoundOutputMode::Stereo));
} else if (size == 1 && blockID == 0xA0002){ // System language } else if (size == 1 && blockID == 0xA0002) { // System language
mem.write8(output, static_cast<u8>(LanguageCodes::English)); mem.write8(output, static_cast<u8>(LanguageCodes::English));
} else if (size == 4 && blockID == 0xB0000) { // Country info } else if (size == 4 && blockID == 0xB0000) { // Country info
mem.write8(output, 0); // Unknown mem.write8(output, 0); // Unknown
mem.write8(output + 1, 0); // Unknown mem.write8(output + 1, 0); // Unknown
mem.write8(output + 2, 2); // Province (Temporarily stubbed to Washington DC like Citra) mem.write8(output + 2, 2); // Province (Temporarily stubbed to Washington DC like Citra)
mem.write8(output + 3, static_cast<u8>(country)); // Country code mem.write8(output + 3, static_cast<u8>(country)); // Country code
} else if (size == 0x20 && blockID == 0x50005) { } else if (size == 0x20 && blockID == 0x50005) {
// "Stereo Camera settings" // "Stereo Camera settings"
// Implementing this properly fixes NaN uniforms in some games. Values taken from 3dmoo & Citra // Implementing this properly fixes NaN uniforms in some games. Values taken from 3dmoo & Citra
static constexpr std::array<float, 8> STEREO_CAMERA_SETTINGS = { static constexpr std::array<float, 8> STEREO_CAMERA_SETTINGS = {
62.0f, 289.0f, 76.80000305175781f, 46.08000183105469f, 62.0f, 289.0f, 76.80000305175781f, 46.08000183105469f, 10.0f, 5.0f, 55.58000183105469f, 21.56999969482422f,
10.0f, 5.0f, 55.58000183105469f, 21.56999969482422f
}; };
for (int i = 0; i < 8; i++) { for (int i = 0; i < 8; i++) {
mem.write32(output + i * 4, Helpers::bit_cast<u32, float>(STEREO_CAMERA_SETTINGS[i])); mem.write32(output + i * 4, Helpers::bit_cast<u32, float>(STEREO_CAMERA_SETTINGS[i]));
} }
} else if (size == 0x1C && blockID == 0xA0000) { // Username } else if (size == 0x1C && blockID == 0xA0000) { // Username
writeStringU16(output, u"Pander"); writeStringU16(output, u"Pander");
} else if (size == 0xC0 && blockID == 0xC0000) { // Parental restrictions info } else if (size == 0xC0 && blockID == 0xC0000) { // Parental restrictions info
for (int i = 0; i < 0xC0; i++) for (int i = 0; i < 0xC0; i++) mem.write8(output + i, 0);
mem.write8(output + i, 0); } else if (size == 4 && blockID == 0xD0000) { // Agreed EULA version (first 2 bytes) and latest EULA version (next 2 bytes)
} else if (size == 4 && blockID == 0xD0000) { // Agreed EULA version (first 2 bytes) and latest EULA version (next 2 bytes)
log("Read EULA info\n"); log("Read EULA info\n");
mem.write16(output, 0x0202); // Agreed EULA version = 2.2 (Random number. TODO: Check) mem.write16(output, 0x0202); // Agreed EULA version = 2.2 (Random number. TODO: Check)
mem.write16(output + 2, 0x0202); // Latest EULA version = 2.2 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 } 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 languageCount = 16;
constexpr size_t nameSize = 0x80; // Max size of each name in bytes 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 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++) { for (int i = 0; i < languageCount; i++) {
u32 pointer = output + i * nameSize; u32 pointer = output + i * nameSize;
writeStringU16(pointer, name); writeStringU16(pointer, name);
} }
} else if (size == 0x800 && blockID == 0xB0002) { // UTF-16 name for our state in every language at 0x80 byte intervals } 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 languageCount = 16;
constexpr size_t nameSize = 0x80; // Max size of each name in bytes 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 std::u16string name = u"Pandington"; // Note: This + the null terminator needs to fit in 0x80 bytes
for (int i = 0; i < languageCount; i++) { for (int i = 0; i < languageCount; i++) {
u32 pointer = output + i * nameSize; u32 pointer = output + i * nameSize;
writeStringU16(pointer, name); writeStringU16(pointer, name);
} }
} else if (size == 4 && blockID == 0xB0003) { // Coordinates (latidude and longtitude) as s16 } else if (size == 4 && blockID == 0xB0003) { // Coordinates (latidude and longtitude) as s16
mem.write16(output, 0); // Latitude mem.write16(output, 0); // Latitude
mem.write16(output + 2, 0); // Longtitude mem.write16(output + 2, 0); // Longtitude
} else if (size == 2 && blockID == 0xA0001) { // Birthday } else if (size == 2 && blockID == 0xA0001) { // Birthday
mem.write8(output, 5); // Month (May) mem.write8(output, 5); // Month (May)
mem.write8(output + 1, 5); // Day (Fifth) mem.write8(output + 1, 5); // Day (Fifth)
} else if (size == 8 && blockID == 0x30001) { // User time offset } else if (size == 8 && blockID == 0x30001) { // User time offset
printf("Read from user time offset field in NAND. TODO: What is this\n"); printf("Read from user time offset field in NAND. TODO: What is this\n");
mem.write64(output, 0); mem.write64(output, 0);
} else if (size == 20 && blockID == 0xC0001) { // COPPACS restriction data, used by games when they detect a USA/Canada region for market restriction stuff } else if (size == 20 && blockID == 0xC0001) { // COPPACS restriction data, used by games when they detect a USA/Canada region for market
// restriction stuff
for (u32 i = 0; i < size; i += 4) { for (u32 i = 0; i < size; i += 4) {
mem.write32(output + i, 0); mem.write32(output + i, 0);
} }
} else if (size == 4 && blockID == 0x170000) { // Miiverse access key } else if (size == 4 && blockID == 0x170000) { // Miiverse access key
mem.write32(output, 0); mem.write32(output, 0);
} else if (size == 8 && blockID == 0x00090000) { } else if (size == 8 && blockID == 0x00090000) {
mem.write64(output, 0); // Some sort of key used with nwm::UDS::InitializeWithVersion mem.write64(output, 0); // Some sort of key used with nwm::UDS::InitializeWithVersion
} else { } else {
Helpers::panic("Unhandled GetConfigInfoBlk2 configuration. Size = %d, block = %X", size, blockID); Helpers::panic("Unhandled GetConfigInfoBlk2 configuration. Size = %d, block = %X", size, blockID);
} }
mem.write32(messagePointer, IPC::responseHeader(0x1, 1, 2));
mem.write32(messagePointer + 4, Result::Success);
} }
void CFGService::secureInfoGetRegion(u32 messagePointer) { void CFGService::secureInfoGetRegion(u32 messagePointer) {