diff --git a/CMakeLists.txt b/CMakeLists.txt index 1235b7ab..c132cefe 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -53,7 +53,7 @@ set(KERNEL_SOURCE_FILES src/core/kernel/kernel.cpp src/core/kernel/resource_limi src/core/kernel/memory_management.cpp src/core/kernel/ports.cpp src/core/kernel/events.cpp src/core/kernel/threads.cpp src/core/kernel/address_arbiter.cpp src/core/kernel/error.cpp - src/core/kernel/file_operations.cpp + src/core/kernel/file_operations.cpp src/core/kernel/directory_operations.cpp ) set(SERVICE_SOURCE_FILES src/core/services/service_manager.cpp src/core/services/apt.cpp src/core/services/hid.cpp src/core/services/fs.cpp src/core/services/gsp_gpu.cpp src/core/services/gsp_lcd.cpp diff --git a/include/kernel/kernel.hpp b/include/kernel/kernel.hpp index b953db8c..e46bb0a2 100644 --- a/include/kernel/kernel.hpp +++ b/include/kernel/kernel.hpp @@ -129,6 +129,11 @@ private: void openLinkFile(u32 messagePointer, Handle file); void setFilePriority(u32 messagePointer, Handle file); + // Directory operations + void handleDirectoryOperation(u32 messagePointer, Handle directory); + void closeDirectory(u32 messagePointer, Handle directory); + void readDirectory(u32 messagePointer, Handle directory); + public: Kernel(CPU& cpu, Memory& mem, GPU& gpu); void initializeFS() { return serviceManager.initializeFS(); } diff --git a/include/renderer_gl/renderer_gl.hpp b/include/renderer_gl/renderer_gl.hpp index 3f78a2d0..88cb285c 100644 --- a/include/renderer_gl/renderer_gl.hpp +++ b/include/renderer_gl/renderer_gl.hpp @@ -95,5 +95,5 @@ public: void setColourBufferLoc(u32 loc) { colourBufferLoc = loc; } void setDepthBufferLoc(u32 loc) { depthBufferLoc = loc; } - static constexpr u32 vertexBufferSize = 0x1500; + static constexpr u32 vertexBufferSize = 0x10000; }; \ No newline at end of file diff --git a/src/core/PICA/gpu.cpp b/src/core/PICA/gpu.cpp index 5b817888..7e9ddfea 100644 --- a/src/core/PICA/gpu.cpp +++ b/src/core/PICA/gpu.cpp @@ -40,6 +40,8 @@ void GPU::drawArrays(bool indexed) { drawArrays(); } +Vertex* vertices = new Vertex[Renderer::vertexBufferSize]; + template void GPU::drawArrays() { // Base address for vertex attributes @@ -50,15 +52,13 @@ void GPU::drawArrays() { // Configures the type of primitive and the number of vertex shader outputs const u32 primConfig = regs[PICAInternalRegs::PrimitiveConfig]; const u32 primType = (primConfig >> 8) & 3; - if (primType != 0 && primType != 1) Helpers::panic("[PICA] Tried to draw unimplemented shape %d\n", primType); + if (primType != 0 && primType != 1 && primType != 3) Helpers::panic("[PICA] Tried to draw unimplemented shape %d\n", primType); if (vertexCount > Renderer::vertexBufferSize) Helpers::panic("[PICA] vertexCount > vertexBufferSize"); if ((primType == 0 && vertexCount % 3) || (primType == 1 && vertexCount < 3)) { Helpers::panic("Invalid vertex count for primitive. Type: %d, vert count: %d\n", primType, vertexCount); } - Vertex vertices[Renderer::vertexBufferSize]; - // Get the configuration for the index buffer, used only for indexed drawing u32 indexBufferConfig = regs[PICAInternalRegs::IndexBufferConfig]; u32 indexBufferPointer = vertexBase + (indexBufferConfig & 0xfffffff); @@ -228,6 +228,7 @@ Vertex GPU::getImmediateModeVertex() { return v; } + void GPU::fireDMA(u32 dest, u32 source, u32 size) { log("[GPU] DMA of %08X bytes from %08X to %08X\n", size, source, dest); constexpr u32 vramStart = VirtualAddrs::VramStart; diff --git a/src/core/fs/archive_ext_save_data.cpp b/src/core/fs/archive_ext_save_data.cpp index 9b8a660e..568431d6 100644 --- a/src/core/fs/archive_ext_save_data.cpp +++ b/src/core/fs/archive_ext_save_data.cpp @@ -38,7 +38,8 @@ DeleteFileResult ExtSaveDataArchive::deleteFile(const FSPath& path) { fs::path p = IOFile::getAppData() / "NAND"; p += fs::path(path.utf16_string).make_preferred(); - bool success = fs::remove(p); + std::error_code ec; + bool success = fs::remove(p, ec); return success ? DeleteFileResult::Success : DeleteFileResult::FileNotFound; } diff --git a/src/core/kernel/directory_operations.cpp b/src/core/kernel/directory_operations.cpp new file mode 100644 index 00000000..44d79111 --- /dev/null +++ b/src/core/kernel/directory_operations.cpp @@ -0,0 +1,46 @@ +#include "kernel.hpp" + +namespace DirectoryOps { + enum : u32 { + Read = 0x08010042, + Close = 0x08020000 + }; +} + +namespace Result { + enum : u32 { + Success = 0 + }; +} + +void Kernel::handleDirectoryOperation(u32 messagePointer, Handle directory) { + const u32 cmd = mem.read32(messagePointer); + switch (cmd) { + case DirectoryOps::Close: closeDirectory(messagePointer, directory); break; + case DirectoryOps::Read: readDirectory(messagePointer, directory); break; + default: Helpers::panic("Unknown directory operation: %08X", cmd); + } +} + +void Kernel::closeDirectory(u32 messagePointer, Handle directory) { + logFileIO("Closed directory %X\n", directory); + + const auto p = getObject(directory, KernelObjectType::Directory); + if (p == nullptr) [[unlikely]] { + Helpers::panic("Called CloseFile on non-existent file"); + } + + p->getData()->isOpen = false; + mem.write32(messagePointer + 4, Result::Success); +} + + +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"); + + mem.write32(messagePointer + 4, Result::Success); + mem.write32(messagePointer + 8, 0); +} \ No newline at end of file diff --git a/src/core/kernel/ports.cpp b/src/core/kernel/ports.cpp index 92aba381..85a7aaf5 100644 --- a/src/core/kernel/ports.cpp +++ b/src/core/kernel/ports.cpp @@ -91,6 +91,14 @@ void Kernel::sendSyncRequest() { return; } + // Check if our sync request is targetting a directory instead of a service + bool isDirectoryOperation = getObject(handle, KernelObjectType::Directory) != nullptr; + if (isDirectoryOperation) { + handleDirectoryOperation(messagePointer, handle); + regs[0] = SVCResult::Success; + return; + } + // If we're actually communicating with a port const auto session = getObject(handle, KernelObjectType::Session); if (session == nullptr) [[unlikely]] { diff --git a/src/core/loader/ncch.cpp b/src/core/loader/ncch.cpp index 4ac38500..c3dd8d2e 100644 --- a/src/core/loader/ncch.cpp +++ b/src/core/loader/ncch.cpp @@ -127,7 +127,7 @@ bool NCCH::loadFromHeader(u8* header, IOFile& file) { } if (stackSize != 0 && stackSize != VirtualAddrs::DefaultStackSize) { - Helpers::panic("Stack size != 0x4000"); + Helpers::warn("Requested stack size is %08X bytes. Temporarily emulated as 0x4000 until adjustable sizes are added\n", stackSize); } if (encrypted) { diff --git a/src/core/services/fs.cpp b/src/core/services/fs.cpp index bc4f341e..ea41d473 100644 --- a/src/core/services/fs.cpp +++ b/src/core/services/fs.cpp @@ -320,7 +320,7 @@ void FSService::deleteFile(u32 messagePointer) { log("FS::DeleteFile\n"); auto archiveObject = kernel.getObject(archiveHandle, KernelObjectType::Archive); if (archiveObject == nullptr) [[unlikely]] { - log("FS::OpenFile: Invalid archive handle %d\n", archiveHandle); + log("FS::DeleteFile: Invalid archive handle %d\n", archiveHandle); mem.write32(messagePointer + 4, Result::Failure); return; } diff --git a/src/main.cpp b/src/main.cpp index 3a078e8f..fbf4514c 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -9,7 +9,7 @@ int main (int argc, char *argv[]) { emu.initGraphicsContext(); - auto romPath = std::filesystem::current_path() / (argc > 1 ? argv[1] : "SimplerTri_AddedLogs.elf"); + auto romPath = std::filesystem::current_path() / (argc > 1 ? argv[1] : "Kirby - Triple Deluxe (Europe) (En,Fr,De,Es,It) (Demo) (Kiosk).3ds"); if (!emu.loadROM(romPath)) { // For some reason just .c_str() doesn't show the proper path Helpers::panic("Failed to load ROM file: %s", romPath.string().c_str());