diff --git a/include/PICA/regs.hpp b/include/PICA/regs.hpp index 8815668f..8ef46e67 100644 --- a/include/PICA/regs.hpp +++ b/include/PICA/regs.hpp @@ -81,6 +81,7 @@ namespace PICAInternalRegs { CmdBufTrigger1 = 0x23D, PrimitiveConfig = 0x25E, + PrimitiveRestart = 0x25F, // Vertex shader registers VertexShaderAttrNum = 0x242, diff --git a/include/services/fs.hpp b/include/services/fs.hpp index 27944c13..67ea472c 100644 --- a/include/services/fs.hpp +++ b/include/services/fs.hpp @@ -39,6 +39,7 @@ class FSService { // Service commands void createFile(u32 messagePointer); void closeArchive(u32 messagePointer); + void controlArchive(u32 messagePointer); void deleteFile(u32 messagePointer); void formatSaveData(u32 messagePointer); void getFormatInfo(u32 messagePointer); diff --git a/src/core/PICA/regs.cpp b/src/core/PICA/regs.cpp index 91b1d8e4..33cf570a 100644 --- a/src/core/PICA/regs.cpp +++ b/src/core/PICA/regs.cpp @@ -111,6 +111,14 @@ void GPU::writeInternalReg(u32 index, u32 value, u32 mask) { } break; + // Restart immediate mode primitive drawing + case PrimitiveRestart: + if (value & 1) { + immediateModeAttrIndex = 0; + immediateModeVertIndex = 0; + } + break; + case FixedAttribData0: case FixedAttribData1: case FixedAttribData2: fixedAttrBuff[fixedAttribCount++] = value; diff --git a/src/core/services/fs.cpp b/src/core/services/fs.cpp index 3642fa20..372110c6 100644 --- a/src/core/services/fs.cpp +++ b/src/core/services/fs.cpp @@ -16,6 +16,7 @@ namespace FSCommands { CreateFile = 0x08080202, OpenDirectory = 0x080B0102, OpenArchive = 0x080C00C2, + ControlArchive = 0x080D0144, CloseArchive = 0x080E0080, IsSdmcDetected = 0x08170000, GetFormatInfo = 0x084500C2, @@ -151,6 +152,7 @@ void FSService::handleSyncRequest(u32 messagePointer) { const u32 command = mem.read32(messagePointer); switch (command) { case FSCommands::CreateFile: createFile(messagePointer); break; + case FSCommands::ControlArchive: controlArchive(messagePointer); break; case FSCommands::CloseArchive: closeArchive(messagePointer); break; case FSCommands::DeleteFile: deleteFile(messagePointer); break; case FSCommands::FormatSaveData: formatSaveData(messagePointer); break; @@ -215,7 +217,7 @@ void FSService::openArchive(u32 messagePointer) { } void FSService::openFile(u32 messagePointer) { - const u32 archiveHandle = mem.read64(messagePointer + 8); + const Handle archiveHandle = mem.read64(messagePointer + 8); const u32 filePathType = mem.read32(messagePointer + 16); const u32 filePathSize = mem.read32(messagePointer + 20); const u32 openFlags = mem.read32(messagePointer + 24); @@ -335,7 +337,7 @@ void FSService::createFile(u32 messagePointer) { } void FSService::deleteFile(u32 messagePointer) { - const u32 archiveHandle = mem.read64(messagePointer + 8); + const Handle archiveHandle = mem.read64(messagePointer + 8); const u32 filePathType = mem.read32(messagePointer + 16); const u32 filePathSize = mem.read32(messagePointer + 20); const u32 filePathPointer = mem.read32(messagePointer + 28); @@ -402,6 +404,33 @@ void FSService::formatSaveData(u32 messagePointer) { printf("Stubbed FS::FormatSaveData. File num: %d, directory num: %d\n", fileNum, directoryNum); } +void FSService::controlArchive(u32 messagePointer) { + const Handle archiveHandle = mem.read64(messagePointer + 4); + const u32 action = mem.read32(messagePointer + 12); + const u32 inputSize = mem.read32(messagePointer + 16); + const u32 outputSize = mem.read32(messagePointer + 20); + const u32 input = mem.read32(messagePointer + 28); + const u32 output = mem.read32(messagePointer + 36); + + log("FS::ControlArchive (action = %X, handle = %X)\n", action, archiveHandle); + + auto archiveObject = kernel.getObject(archiveHandle, KernelObjectType::Archive); + if (archiveObject == nullptr) [[unlikely]] { + log("FS::ControlArchive: Invalid archive handle %d\n", archiveHandle); + mem.write32(messagePointer + 4, ResultCode::Failure); + return; + } + + switch (action) { + case 0: // Commit save data changes. Shouldn't need us to do anything + mem.write32(messagePointer + 4, ResultCode::Success); + break; + default: + Helpers::panic("Unimplemented action for ControlArchive (action = %X)\n", action); + break; + } +} + void FSService::getPriority(u32 messagePointer) { log("FS::GetPriority\n");