diff --git a/include/common/math.hpp b/include/common/math.hpp index b9435650..010e81ac 100644 --- a/include/common/math.hpp +++ b/include/common/math.hpp @@ -1,6 +1,7 @@ #pragma once #include // for CHAR_BIT +#include #include // for rand() and RAND_MAX #include @@ -47,7 +48,7 @@ namespace love { struct Rect { - static constexpr int EMPTY[4] = { 0, 0, 0, 0 }; + static constexpr int EMPTY[4] = { -1, -1, -1, -1 }; int x, y, w, h; @@ -71,6 +72,11 @@ namespace love } }; + inline void DEBUG_RECT(const Rect& rectangle) + { + std::printf("x: %d, y: %d, w: %d, h: %d\n", rectangle.x, rectangle.y, rectangle.w, rectangle.h); + } + /* ** Clamps 3DS textures between min ** and max texture size to prevent diff --git a/include/driver/display/Renderer.tcc b/include/driver/display/Renderer.tcc index 8c235e07..6dcc1db3 100644 --- a/include/driver/display/Renderer.tcc +++ b/include/driver/display/Renderer.tcc @@ -27,33 +27,6 @@ namespace love RENDERER_INFO_DEVICE }; - struct BatchedVertexData - { - Vertex* stream; - }; - - struct BatchedDrawState - { - Vertex* vertices; - size_t verticesSize; - - StreamBuffer::MapInfo vertexMap = StreamBuffer::MapInfo(); - - StreamBuffer* indexBuffer; - StreamBuffer::MapInfo indexMap = StreamBuffer::MapInfo(); - - PrimitiveType primitiveMode = PRIMITIVE_TRIANGLES; - ShaderBase::StandardShader shader = ShaderBase::STANDARD_DEFAULT; - CommonFormat format = CommonFormat::NONE; - - StrongRef texture; - - int vertexCount = 0; - int indexCount = 0; - - bool flushing = false; - }; - RendererBase() : batchedDrawState {} { size_t size = sizeof(uint16_t) * LOVE_UINT16_MAX; diff --git a/include/driver/graphics/DrawCommand.hpp b/include/driver/graphics/DrawCommand.hpp index fc13dec6..fe2c83fc 100644 --- a/include/driver/graphics/DrawCommand.hpp +++ b/include/driver/graphics/DrawCommand.hpp @@ -119,4 +119,31 @@ namespace love TextureBase* texture; CullMode cullMode = CULL_NONE; }; + + struct BatchedVertexData + { + Vertex* stream; + }; + + struct BatchedDrawState + { + Vertex* vertices; + size_t verticesSize; + + StreamBuffer::MapInfo vertexMap = StreamBuffer::MapInfo(); + + StreamBuffer* indexBuffer; + StreamBuffer::MapInfo indexMap = StreamBuffer::MapInfo(); + + PrimitiveType primitiveMode = PRIMITIVE_TRIANGLES; + ShaderBase::StandardShader shader = ShaderBase::STANDARD_DEFAULT; + CommonFormat format = CommonFormat::NONE; + + StrongRef texture; + + int vertexCount = 0; + int indexCount = 0; + + bool flushing = false; + }; } // namespace love diff --git a/include/modules/graphics/StreamBuffer.tcc b/include/modules/graphics/StreamBuffer.tcc deleted file mode 100644 index 52d4fc6a..00000000 --- a/include/modules/graphics/StreamBuffer.tcc +++ /dev/null @@ -1,85 +0,0 @@ -/** - * Copyright (c) 2006-2024 LOVE Development Team - * - * This software is provided 'as-is', without any express or implied - * warranty. In no event will the authors be held liable for any damages - * arising from the use of this software. - * - * Permission is granted to anyone to use this software for any purpose, - * including commercial applications, and to alter it and redistribute it - * freely, subject to the following restrictions: - * - * 1. The origin of this software must not be misrepresented; you must not - * claim that you wrote the original software. If you use this software - * in a product, an acknowledgment in the product documentation would be - * appreciated but is not required. - * 2. Altered source versions must be plainly marked as such, and must not be - * misrepresented as being the original software. - * 3. This notice may not be removed or altered from any source distribution. - **/ - -#pragma once - -// LOVE -#include "common/Object.hpp" -#include "common/int.hpp" - -#include "modules/graphics/Resource.hpp" -#include "modules/graphics/vertex.hpp" - -// C -#include - -namespace love -{ - class StreamBufferBase : public Object, public Resource - { - public: - struct MapInfo - { - uint8_t* data = nullptr; - size_t size = 0; - - MapInfo() - {} - - MapInfo(uint8_t* data, size_t size) : data(data), size(size) - {} - }; - - virtual ~StreamBufferBase() - {} - - size_t getSize() const - { - return bufferSize; - } - - BufferUsage getMode() const - { - return mode; - } - - size_t getUsableSize() const - { - return bufferSize - frameGPUReadOffset; - } - - virtual size_t getGPUReadOffset() const = 0; - - virtual MapInfo map(size_t minsize) = 0; - virtual size_t unmap(size_t usedsize) = 0; - virtual void markUsed(size_t usedsize) = 0; - - virtual void nextFrame() - {} - - protected: - StreamBufferBase(BufferUsage mode, size_t size); - - size_t bufferSize; - size_t frameGPUReadOffset; - BufferUsage mode; - - }; // StreamBuffer -} // namespace love diff --git a/include/modules/graphics/vertex.hpp b/include/modules/graphics/vertex.hpp index 57a1f26c..63d9b323 100644 --- a/include/modules/graphics/vertex.hpp +++ b/include/modules/graphics/vertex.hpp @@ -244,7 +244,7 @@ namespace love inline CommonFormat getSinglePositionFormat(bool is2D) { - return is2D ? CommonFormat::XYf : CommonFormat::XYf; + return is2D ? CommonFormat::XYf : CommonFormat::XYZf; } struct DataFormatInfo diff --git a/include/modules/graphics/wrap_Graphics.hpp b/include/modules/graphics/wrap_Graphics.hpp index 9d07fe51..554b20ab 100644 --- a/include/modules/graphics/wrap_Graphics.hpp +++ b/include/modules/graphics/wrap_Graphics.hpp @@ -3,39 +3,51 @@ #include "common/luax.hpp" #include "modules/graphics/Graphics.hpp" -template -static void luax_checkstandardtransform(lua_State* L, int index, const T& func) -{ - /* TODO: check Transform type */ - - int nargs = lua_gettop(L); - - float x = luaL_optnumber(L, index + 0, 0.0); - float y = luaL_optnumber(L, index + 1, 0.0); - float a = luaL_optnumber(L, index + 2, 0.0); - float sx = luaL_optnumber(L, index + 3, 1.0); - float sy = luaL_optnumber(L, index + 4, sx); - - float ox = 0.0f; - float oy = 0.0f; - - if (nargs >= index + 5) - { - ox = luaL_optnumber(L, index + 5, 0.0); - oy = luaL_optnumber(L, index + 6, 0.0); - } - - float kx = 0.0f; - float ky = 0.0f; +#include "modules/math/Transform.hpp" - if (nargs >= index + 7) +namespace love +{ + template + static void luax_checkstandardtransform(lua_State* L, int index, const T& func) { - kx = luaL_optnumber(L, index + 7, 0.0); - ky = luaL_optnumber(L, index + 8, 0.0); + /* TODO: check Transform type */ + + auto* transform = luax_totype(L, index); + + if (transform != nullptr) + func(transform->getMatrix()); + else + { + int nargs = lua_gettop(L); + + float x = luaL_optnumber(L, index + 0, 0.0); + float y = luaL_optnumber(L, index + 1, 0.0); + float a = luaL_optnumber(L, index + 2, 0.0); + float sx = luaL_optnumber(L, index + 3, 1.0); + float sy = luaL_optnumber(L, index + 4, sx); + + float ox = 0.0f; + float oy = 0.0f; + + if (nargs >= index + 5) + { + ox = luaL_optnumber(L, index + 5, 0.0); + oy = luaL_optnumber(L, index + 6, 0.0); + } + + float kx = 0.0f; + float ky = 0.0f; + + if (nargs >= index + 7) + { + kx = luaL_optnumber(L, index + 7, 0.0); + ky = luaL_optnumber(L, index + 8, 0.0); + } + + func(love::Matrix4(x, y, a, sx, sy, ox, oy, kx, ky)); + } } - - func(love::Matrix4(x, y, a, sx, sy, ox, oy, kx, ky)); -} +} // namespace love namespace Wrap_Graphics { diff --git a/platform/ctr/include/driver/display/Framebuffer.hpp b/platform/ctr/include/driver/display/Framebuffer.hpp index 5aee3daf..368374c2 100644 --- a/platform/ctr/include/driver/display/Framebuffer.hpp +++ b/platform/ctr/include/driver/display/Framebuffer.hpp @@ -35,8 +35,11 @@ namespace love return this->projection; } + static void calculateBounds(const Rect& bounds, Rect& out, const int width, const int height); + private: - static constexpr auto FORMAT = GPU_RB_DEPTH16; + static constexpr auto DEPTH_FORMAT = GPU_RB_DEPTH16; + static constexpr auto COLOR_FORMAT = GPU_RB_RGBA8; static constexpr auto DISPLAY_TRANSFER_FLAGS = GX_TRANSFER_FLIP_VERT(0) | GX_TRANSFER_OUT_TILED(0) | GX_TRANSFER_RAW_COPY(0) | diff --git a/platform/ctr/include/driver/display/Renderer.hpp b/platform/ctr/include/driver/display/Renderer.hpp index ac3898cd..ddd52968 100644 --- a/platform/ctr/include/driver/display/Renderer.hpp +++ b/platform/ctr/include/driver/display/Renderer.hpp @@ -129,9 +129,6 @@ namespace love private: static GPU_TEXTURE_WRAP_PARAM getWrapMode(SamplerState::WrapMode mode); - static constexpr int MAX_OBJECTS = 0x1000; - static constexpr int VERTEX_BUFFER_SIZE = 6 * MAX_OBJECTS; // 6 vertices per object - void ensureInFrame(); void createFramebuffers(); diff --git a/platform/ctr/include/driver/display/citro3d/VertexRing.hpp b/platform/ctr/include/driver/display/citro3d/VertexRing.hpp deleted file mode 100644 index 598c5dc9..00000000 --- a/platform/ctr/include/driver/display/citro3d/VertexRing.hpp +++ /dev/null @@ -1,66 +0,0 @@ -#pragma once - -#include <3ds.h> - -namespace love -{ - class VertexRing - { - public: - VertexRing() : memory(nullptr), sliceSize(0), currentSlice(0), sliceCount(0) - {} - - VertexRing(const VertexRing&) = delete; - - VertexRing& operator=(const VertexRing&) = delete; - - ~VertexRing() - { - linearFree(this->memory); - } - - bool allocate(size_t numSlices, size_t size) - { - if (this->memory) - linearFree(this->memory); - - this->memory = linearAlloc(size * numSlices); - - if (this->memory == nullptr) - return false; - - this->sliceSize = size; - this->sliceCount = numSlices; - - return true; - } - - size_t getSize() - { - return this->sliceSize * this->sliceCount; - } - - void* getBuffer() const - { - return this->memory; - } - - void* begin() const - { - const auto offset = this->currentSlice * this->sliceSize; - return (void*)((char*)this->memory + offset); - } - - void end() - { - this->currentSlice = (this->currentSlice + 1) % this->sliceCount; - } - - private: - void* memory; - size_t sliceSize; - - size_t currentSlice; - size_t sliceCount; - }; -} // namespace love diff --git a/platform/ctr/source/common/screen.cpp b/platform/ctr/source/common/screen.cpp index efe65aa3..bd5faa91 100644 --- a/platform/ctr/source/common/screen.cpp +++ b/platform/ctr/source/common/screen.cpp @@ -9,21 +9,21 @@ namespace love // clang-format off inline constinit ScreenInfo GFX_3D[0x03] = { - { GFX_TOP, 0, "left", 400, 240 }, - { GFX_TOP, 1, "right", 400, 240 }, - { GFX_BOTTOM, 2, "bottom", 320, 240 } + { GFX_TOP, 0, "left", GSP_SCREEN_HEIGHT_TOP, GSP_SCREEN_WIDTH }, + { GFX_TOP, 1, "right", GSP_SCREEN_HEIGHT_TOP, GSP_SCREEN_WIDTH }, + { GFX_BOTTOM, 2, "bottom", GSP_SCREEN_HEIGHT_BOTTOM, GSP_SCREEN_WIDTH } }; inline constinit ScreenInfo GFX_2D[0x02] = { - { GFX_TOP, 0, "top", 400, 240 }, - { GFX_BOTTOM, 1, "bottom", 320, 240 } + { GFX_TOP, 0, "top", GSP_SCREEN_HEIGHT_TOP, GSP_SCREEN_WIDTH }, + { GFX_BOTTOM, 1, "bottom", GSP_SCREEN_HEIGHT_BOTTOM, GSP_SCREEN_WIDTH } }; inline constinit ScreenInfo GFX_WIDE[0x02] = { - { GFX_TOP, 0, "top", 800, 240 }, - { GFX_BOTTOM, 1, "bottom", 320, 240 } + { GFX_TOP, 0, "top", GSP_SCREEN_HEIGHT_TOP_2X, GSP_SCREEN_WIDTH }, + { GFX_BOTTOM, 1, "bottom", GSP_SCREEN_HEIGHT_BOTTOM, GSP_SCREEN_WIDTH } }; // clang-format on diff --git a/platform/ctr/source/driver/display/Framebuffer.cpp b/platform/ctr/source/driver/display/Framebuffer.cpp index 55514b72..92f47973 100644 --- a/platform/ctr/source/driver/display/Framebuffer.cpp +++ b/platform/ctr/source/driver/display/Framebuffer.cpp @@ -13,10 +13,10 @@ namespace love { const auto side = (gfxIs3D() && info.name == "right") ? GFX_RIGHT : GFX_LEFT; - this->target = C3D_RenderTargetCreate(info.width, info.height, GPU_RB_RGBA8, FORMAT); + this->target = C3D_RenderTargetCreate(info.width, info.height, COLOR_FORMAT, DEPTH_FORMAT); if (!this->target) - throw love::Exception("Failed to create render target."); + throw love::Exception("Failed to create render target '{:s}'.", info.name); const auto screen = (gfxScreen_t)info.id; C3D_RenderTargetSetOutput(this->target, screen, side, DISPLAY_TRANSFER_FLAGS); @@ -30,8 +30,6 @@ namespace love this->viewport = { 0, 0, this->width, this->height }; this->scissor = { 0, 0, this->width, this->height }; - - this->setScissor(Rect::EMPTY); } void Framebuffer::destroy() @@ -43,7 +41,7 @@ namespace love } } - static const Rect calculateBounds(const Rect& bounds, int width, int height) + void Framebuffer::calculateBounds(const Rect& bounds, Rect& out, const int width, const int height) { // clang-format off const uint32_t left = height > (bounds.y + bounds.h) ? height - (bounds.y + bounds.h) : 0; @@ -52,7 +50,7 @@ namespace love const uint32_t bottom = width - bounds.x; // clang-format on - return { (int)left, (int)top, (int)right, (int)bottom }; + out = { (int)left, (int)top, (int)right, (int)bottom }; } void Framebuffer::setScissor(const Rect& scissor) @@ -60,12 +58,10 @@ namespace love const bool enabled = scissor != Rect::EMPTY; GPU_SCISSORMODE mode = enabled ? GPU_SCISSOR_NORMAL : GPU_SCISSOR_DISABLE; - auto result = calculateBounds(scissor, this->width, this->height); - - if (result == Rect::EMPTY) - result = calculateBounds(this->scissor, this->width, this->height); + Rect result {}; + calculateBounds(scissor, result, this->width, this->height); - C3D_SetScissor(mode, result.y, result.x, result.h, result.w); this->scissor = result; + C3D_SetScissor(mode, result.y, result.x, result.h, result.w); } } // namespace love diff --git a/platform/ctr/source/driver/display/Renderer.cpp b/platform/ctr/source/driver/display/Renderer.cpp index 67ee46f5..c3baa8eb 100644 --- a/platform/ctr/source/driver/display/Renderer.cpp +++ b/platform/ctr/source/driver/display/Renderer.cpp @@ -111,9 +111,8 @@ namespace love this->context.target = this->targets[currentScreen]; auto viewport = this->context.target.getViewport(); - this->setViewport(viewport, this->context.target.get()->linked); - C3D_FrameDrawOn(this->context.target.get()); + this->setViewport(viewport, this->context.target.get()->linked); } void Renderer::present() @@ -145,22 +144,20 @@ namespace love void Renderer::setViewport(const Rect& viewport, bool tilt) { - this->context.viewport = viewport; + this->context.viewport = viewport; + this->context.dirtyProjection = true; if (viewport.h == GSP_SCREEN_WIDTH && tilt) { if (viewport.w == GSP_SCREEN_HEIGHT_TOP || viewport.w == GSP_SCREEN_HEIGHT_TOP_2X) { Mtx_Copy(&this->context.projection, &this->targets[0].getProjection()); - this->context.dirtyProjection = true; return; } else if (viewport.w == GSP_SCREEN_HEIGHT_BOTTOM) { const auto index = gfxIs3D() ? 2 : 1; - Mtx_Copy(&this->context.projection, &this->targets[index].getProjection()); - this->context.dirtyProjection = true; return; } } @@ -170,7 +167,6 @@ namespace love ortho(&this->context.projection, 0.0f, viewport.w, viewport.h, 0.0f, Framebuffer::Z_NEAR, Framebuffer::Z_FAR, true); // clang-format on - this->context.dirtyProjection = true; C3D_SetViewport(0, 0, (uint32_t)viewport.w, (uint32_t)viewport.h); } diff --git a/source/modules/graphics/vertex.cpp b/source/modules/graphics/vertex.cpp index 5bee17ac..2ec93121 100644 --- a/source/modules/graphics/vertex.cpp +++ b/source/modules/graphics/vertex.cpp @@ -45,6 +45,7 @@ namespace love case CommonFormat::XYf_STPf_RGBAf: return sizeof(XYf_STPf_RGBAf); } + return 0; }