Merge pull request #1 from wheremyfoodat/master

Not Ignoring this PR I fucked up something on my Github GUI
This commit is contained in:
Sky 2023-07-03 13:05:46 -07:00 committed by GitHub
commit 0f66527cbe
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
14 changed files with 147 additions and 72 deletions

View file

@ -33,7 +33,7 @@ void Kernel::readDirectory(u32 messagePointer, Handle directory) {
const u32 entryCount = mem.read32(messagePointer + 4);
const u32 outPointer = mem.read32(messagePointer + 12);
logFileIO("Directory::Read (handle = %X, entry count = %d, out pointer = %08X)\n", directory, entryCount, outPointer);
Helpers::panic("Unimplemented FsDir::Read");
Helpers::panicDev("Unimplemented FsDir::Read");
mem.write32(messagePointer + 4, Result::Success);
mem.write32(messagePointer + 8, 0);

View file

@ -59,12 +59,12 @@ void Kernel::setupIdleThread() {
t.fpscr = FPSCR::ThreadDefault;
// Our idle thread should have as low of a priority as possible, because, well, it's an idle thread.
// We handle this by giving it a priority of 0xff, which is lower than is actually allowed for user threads
// (High priority value = low priority)
t.priority = 0xff;
// We handle this by giving it a priority of 0x40, which is lower than is actually allowed for user threads
// (High priority value = low priority). This is the same priority used in the retail kernel.
t.priority = 0x40;
t.status = ThreadStatus::Ready;
// Add idle thread to the list of thread indices
threadIndices.push_back(idleThreadIndex);
sortThreads();
}
}

View file

@ -44,24 +44,21 @@ bool NCCH::loadFromHeader(Crypto::AESEngine &aesEngine, IOFile& file, const FSIn
exheaderInfo.offset = info.offset + 0x200;
exheaderInfo.size = exheaderSize;
exheaderInfo.hashRegionSize = 0;
exheaderInfo.encryptionInfo = std::nullopt;
exeFS.offset = info.offset + u64(*(u32*)&header[0x1A0]) * mediaUnit;
exeFS.size = u64(*(u32*)&header[0x1A4]) * mediaUnit;
exeFS.hashRegionSize = u64(*(u32*)&header[0x1A8]) * mediaUnit;
exeFS.encryptionInfo = std::nullopt;
romFS.offset = info.offset + u64(*(u32*)&header[0x1B0]) * mediaUnit;
romFS.size = u64(*(u32*)&header[0x1B4]) * mediaUnit;
romFS.hashRegionSize = u64(*(u32*)&header[0x1B8]) * mediaUnit;
romFS.encryptionInfo = std::nullopt;
// Shows whether we got the primary and secondary keys correctly
bool gotCryptoKeys = true;
if (encrypted) {
if (!aesEngine.haveKeys()) {
Helpers::panic(
"Loaded an encrypted ROM but AES keys don't seem to have been provided correctly! Navigate to the emulator's\n"
"app data folder and make sure you have a sysdata directory with a file called aes_keys.txt which contains your keys!"
);
return false;
}
Crypto::AESKey primaryKeyY;
Crypto::AESKey secondaryKeyY;
std::memcpy(primaryKeyY.data(), header, primaryKeyY.size());
@ -69,44 +66,36 @@ bool NCCH::loadFromHeader(Crypto::AESEngine &aesEngine, IOFile& file, const FSIn
if (!seedCrypto) {
secondaryKeyY = primaryKeyY;
} else {
Helpers::panic("Seed crypto is not supported");
return false;
Helpers::warn("Seed crypto is not supported");
gotCryptoKeys = false;
}
auto primaryResult = getPrimaryKey(aesEngine, primaryKeyY);
if (!primaryResult.first) {
Helpers::panic("getPrimaryKey failed!");
return false;
}
Crypto::AESKey primaryKey = primaryResult.second;
auto secondaryResult = getSecondaryKey(aesEngine, secondaryKeyY);
if (!secondaryResult.first) {
Helpers::panic("getSecondaryKey failed!");
return false;
if (!primaryResult.first || !secondaryResult.first) {
gotCryptoKeys = false;
} else {
Crypto::AESKey primaryKey = primaryResult.second;
Crypto::AESKey secondaryKey = secondaryResult.second;
EncryptionInfo encryptionInfoTmp;
encryptionInfoTmp.normalKey = primaryKey;
encryptionInfoTmp.initialCounter.fill(0);
for (std::size_t i = 1; i <= sizeof(std::uint64_t) - 1; i++) {
encryptionInfoTmp.initialCounter[i] = header[0x108 + sizeof(std::uint64_t) - 1 - i];
}
encryptionInfoTmp.initialCounter[8] = 1;
exheaderInfo.encryptionInfo = encryptionInfoTmp;
encryptionInfoTmp.initialCounter[8] = 2;
exeFS.encryptionInfo = encryptionInfoTmp;
encryptionInfoTmp.normalKey = secondaryKey;
encryptionInfoTmp.initialCounter[8] = 3;
romFS.encryptionInfo = encryptionInfoTmp;
}
Crypto::AESKey secondaryKey = secondaryResult.second;
EncryptionInfo encryptionInfoTmp;
encryptionInfoTmp.normalKey = primaryKey;
encryptionInfoTmp.initialCounter.fill(0);
for (std::size_t i = 1; i <= sizeof(std::uint64_t) - 1; i++) {
encryptionInfoTmp.initialCounter[i] = header[0x108 + sizeof(std::uint64_t) - 1 - i];
}
encryptionInfoTmp.initialCounter[8] = 1;
exheaderInfo.encryptionInfo = encryptionInfoTmp;
encryptionInfoTmp.initialCounter[8] = 2;
exeFS.encryptionInfo = encryptionInfoTmp;
encryptionInfoTmp.normalKey = secondaryKey;
encryptionInfoTmp.initialCounter[8] = 3;
romFS.encryptionInfo = encryptionInfoTmp;
}
if (exheaderSize != 0) {
@ -125,9 +114,28 @@ bool NCCH::loadFromHeader(Crypto::AESEngine &aesEngine, IOFile& file, const FSIn
if (u32(programID) == u32(jumpID) && encrypted) {
printf("NCSD is supposedly ecrypted but not actually encrypted\n");
encrypted = false;
// Cartridge is not actually encrypted, set all of our encryption info structures to nullopt
exheaderInfo.encryptionInfo = std::nullopt;
romFS.encryptionInfo = std::nullopt;
exeFS.encryptionInfo = std::nullopt;
}
// If it's truly encrypted, we need to read section again.
if (encrypted) {
if (!aesEngine.haveKeys()) {
Helpers::panic(
"Loaded an encrypted ROM but AES keys don't seem to have been provided correctly! Navigate to the emulator's\n"
"app data folder and make sure you have a sysdata directory with a file called aes_keys.txt which contains your keys!"
);
return false;
}
if (!gotCryptoKeys) {
Helpers::panic("ROM is encrypted but it seems we couldn't get either the primary or the secondary key");
return false;
}
auto [success, bytes] = readFromFile(file, exheaderInfo, &exheader[0], 0, exheaderSize);
if (!success || bytes != exheaderSize) {
printf("Failed to read Extended NCCH header\n");

View file

@ -3,6 +3,7 @@
#include "resource_limits.hpp"
#include <cassert>
#include <chrono> // For time since epoch
#include <ctime>
using namespace KernelMemoryTypes;
@ -424,9 +425,20 @@ void Memory::mirrorMapping(u32 destAddress, u32 sourceAddress, u32 size) {
u64 Memory::timeSince3DSEpoch() {
using namespace std::chrono;
// ms since Jan 1 1970
milliseconds ms = duration_cast<milliseconds>(system_clock::now().time_since_epoch());
// ms between Jan 1 1900 and Jan 1 1970 (2208988800 seconds elapsed between the two)
constexpr u64 offset = 2208988800ull * 1000;
return ms.count() + offset;
std::time_t rawTime = std::time(nullptr); // Get current UTC time
auto localTime = std::localtime(&rawTime); // Convert to local time
bool daylightSavings = localTime->tm_isdst > 0; // Get if time includes DST
localTime = std::gmtime(&rawTime);
// Use gmtime + mktime to calculate difference between local time and UTC
auto timezoneDifference = rawTime - std::mktime(localTime);
if (daylightSavings) {
timezoneDifference += 60ull * 60ull; // Add 1 hour (60 seconds * 60 minutes)
}
// seconds between Jan 1 1900 and Jan 1 1970
constexpr u64 offset = 2208988800ull;
milliseconds ms = duration_cast<milliseconds>(seconds(rawTime + timezoneDifference + offset));
return ms.count();
}

View file

@ -931,7 +931,9 @@ void Renderer::bindDepthBuffer() {
tex = depthBufferCache.add(sampleBuffer).texture.m_handle;
}
if (PICA::DepthFmt::Depth24Stencil8 != depthBufferFormat) Helpers::panic("TODO: Should we remove stencil attachment?");
if (PICA::DepthFmt::Depth24Stencil8 != depthBufferFormat) {
Helpers::panicDev("TODO: Should we remove stencil attachment?");
}
auto attachment = depthBufferFormat == PICA::DepthFmt::Depth24Stencil8 ? GL_DEPTH_STENCIL_ATTACHMENT : GL_DEPTH_ATTACHMENT;
glFramebufferTexture2D(GL_FRAMEBUFFER, attachment, GL_TEXTURE_2D, tex, 0);
}

View file

@ -81,7 +81,10 @@ void APTService::handleSyncRequest(u32 messagePointer) {
case APTCommands::SetApplicationCpuTimeLimit: setApplicationCpuTimeLimit(messagePointer); break;
case APTCommands::SetScreencapPostPermission: setScreencapPostPermission(messagePointer); break;
case APTCommands::TheSmashBrosFunction: theSmashBrosFunction(messagePointer); break;
default: Helpers::panic("APT service requested. Command: %08X\n", command);
default:
Helpers::panicDev("APT service requested. Command: %08X\n", command);
mem.write32(messagePointer + 4, Result::Success);
break;
}
}

View file

@ -16,7 +16,10 @@ void CECDService::handleSyncRequest(u32 messagePointer) {
const u32 command = mem.read32(messagePointer);
switch (command) {
case CECDCommands::GetInfoEventHandle: getInfoEventHandle(messagePointer); break;
default: Helpers::panic("CECD service requested. Command: %08X\n", command);
default:
Helpers::panicDev("CECD service requested. Command: %08X\n", command);
mem.write32(messagePointer + 4, Result::Success);
break;
}
}

View file

@ -7,7 +7,9 @@ namespace HIDCommands {
enum : u32 {
GetIPCHandles = 0x000A0000,
EnableAccelerometer = 0x00110000,
DisableAccelerometer = 0x00120000,
EnableGyroscopeLow = 0x00130000,
DisableGyroscopeLow = 0x00140000,
GetGyroscopeLowRawToDpsCoefficient = 0x00150000,
GetGyroscopeLowCalibrateParam = 0x00160000
};
@ -36,6 +38,8 @@ void HIDService::reset() {
void HIDService::handleSyncRequest(u32 messagePointer) {
const u32 command = mem.read32(messagePointer);
switch (command) {
case HIDCommands::DisableAccelerometer: disableAccelerometer(messagePointer); break;
case HIDCommands::DisableGyroscopeLow: disableGyroscopeLow(messagePointer); break;
case HIDCommands::EnableAccelerometer: enableAccelerometer(messagePointer); break;
case HIDCommands::EnableGyroscopeLow: enableGyroscopeLow(messagePointer); break;
case HIDCommands::GetGyroscopeLowCalibrateParam: getGyroscopeLowCalibrateParam(messagePointer); break;
@ -53,6 +57,14 @@ void HIDService::enableAccelerometer(u32 messagePointer) {
mem.write32(messagePointer + 4, Result::Success);
}
void HIDService::disableAccelerometer(u32 messagePointer) {
log("HID::DisableAccelerometer\n");
accelerometerEnabled = false;
mem.write32(messagePointer, IPC::responseHeader(0x12, 1, 0));
mem.write32(messagePointer + 4, Result::Success);
}
void HIDService::enableGyroscopeLow(u32 messagePointer) {
log("HID::EnableGyroscopeLow\n");
gyroEnabled = true;
@ -61,6 +73,14 @@ void HIDService::enableGyroscopeLow(u32 messagePointer) {
mem.write32(messagePointer + 4, Result::Success);
}
void HIDService::disableGyroscopeLow(u32 messagePointer) {
log("HID::DisableGyroscopeLow\n");
gyroEnabled = false;
mem.write32(messagePointer, IPC::responseHeader(0x14, 1, 0));
mem.write32(messagePointer + 4, Result::Success);
}
void HIDService::getGyroscopeLowCalibrateParam(u32 messagePointer) {
log("HID::GetGyroscopeLowCalibrateParam\n");
constexpr s16 unit = 6700; // Approximately from Citra which took it from hardware