diff --git a/include/renderer_gl/textures.hpp b/include/renderer_gl/textures.hpp index f047e01f..3cf7871c 100644 --- a/include/renderer_gl/textures.hpp +++ b/include/renderer_gl/textures.hpp @@ -29,6 +29,7 @@ struct Texture { }; u32 location; + u32 config; // Magnification/minification filter, wrapping configs, etc Formats format; OpenGL::uvec2 size; bool valid; @@ -40,8 +41,8 @@ struct Texture { Texture() : valid(false) {} - Texture(u32 loc, Formats format, u32 x, u32 y, bool valid = true) - : location(loc), format(format), size({x, y}), valid(valid) { + Texture(u32 loc, Formats format, u32 x, u32 y, u32 config, bool valid = true) + : location(loc), format(format), size({x, y}), config(config), valid(valid) { u64 endLoc = (u64)loc + sizeInBytes(); // Check if start and end are valid here @@ -56,6 +57,7 @@ struct Texture { } void allocate(); + void setNewConfig(u32 newConfig); void decodeTexture(const void* data); void free(); u64 sizeInBytes(); diff --git a/src/core/renderer_gl/renderer_gl.cpp b/src/core/renderer_gl/renderer_gl.cpp index ac0ac68b..43d760e2 100644 --- a/src/core/renderer_gl/renderer_gl.cpp +++ b/src/core/renderer_gl/renderer_gl.cpp @@ -310,13 +310,14 @@ void Renderer::drawVertices(OpenGL::Primitives primType, Vertex* vertices, u32 c // Hack for rendering texture 1 if (regs[0x80] & 1) { - u32 dim = regs[0x82]; - u32 height = dim & 0x7ff; - u32 width = (dim >> 16) & 0x7ff; - u32 addr = (regs[0x85] & 0x0FFFFFFF) << 3; - u32 format = regs[0x8E] & 0xF; + const u32 dim = regs[0x82]; + const u32 config = regs[0x83]; + const u32 height = dim & 0x7ff; + const u32 width = (dim >> 16) & 0x7ff; + const u32 addr = (regs[0x85] & 0x0FFFFFFF) << 3; + const u32 format = regs[0x8E] & 0xF; - Texture targetTex(addr, static_cast(format), width, height); + Texture targetTex(addr, static_cast(format), width, height, config); OpenGL::Texture tex = getTexture(targetTex); tex.bind(); } diff --git a/src/core/renderer_gl/textures.cpp b/src/core/renderer_gl/textures.cpp index 5ac7e907..a5affd57 100644 --- a/src/core/renderer_gl/textures.cpp +++ b/src/core/renderer_gl/textures.cpp @@ -1,15 +1,33 @@ #include "renderer_gl/textures.hpp" #include "colour.hpp" +#include void Texture::allocate() { glGenTextures(1, &texture.m_handle); texture.create(size.u(), size.v(), GL_RGBA8); texture.bind(); - texture.setMinFilter(OpenGL::Nearest); - texture.setMagFilter(OpenGL::Nearest); - texture.setWrapS(OpenGL::Repeat); - texture.setWrapT(OpenGL::Repeat); + setNewConfig(config); +} + +// Set the texture's configuration, which includes min/mag filters, wrapping S/T modes, and so on +void Texture::setNewConfig(u32 cfg) { + config = cfg; + // The wrapping mode field is 3 bits instead of 2 bits. The bottom 4 undocumented wrapping modes are taken from Citra. + static constexpr std::array wrappingModes = { + OpenGL::ClampToEdge, OpenGL::ClampToBorder, OpenGL::Repeat, OpenGL::RepeatMirrored, + OpenGL::ClampToEdge, OpenGL::ClampToBorder, OpenGL::Repeat, OpenGL::Repeat + }; + + const auto magFilter = (cfg & 0x2) != 0 ? OpenGL::Linear : OpenGL::Nearest; + const auto minFilter = (cfg & 0x4) != 0 ? OpenGL::Linear : OpenGL::Nearest; + const auto wrapT = wrappingModes[(cfg >> 8) & 0x7]; + const auto wrapS = wrappingModes[(cfg >> 12) & 0x7]; + + texture.setMinFilter(minFilter); + texture.setMagFilter(magFilter); + texture.setWrapS(wrapS); + texture.setWrapT(wrapT); } void Texture::free() { diff --git a/src/core/services/fs.cpp b/src/core/services/fs.cpp index 3642fa20..ece66603 100644 --- a/src/core/services/fs.cpp +++ b/src/core/services/fs.cpp @@ -164,7 +164,7 @@ void FSService::handleSyncRequest(u32 messagePointer) { case FSCommands::OpenFile: [[likely]] openFile(messagePointer); break; case FSCommands::OpenFileDirectly: [[likely]] openFileDirectly(messagePointer); break; case FSCommands::SetPriority: setPriority(messagePointer); break; - default: Helpers::panic("FS service requested. Command: %08X\n", command); + default: mem.write32(messagePointer + 4, 0); break; Helpers::panic("FS service requested. Command: %08X\n", command); } }