From e118cd72efa3b84553f2d0978ad1492e62fe9d04 Mon Sep 17 00:00:00 2001 From: TurtleP Date: Sun, 15 Jan 2023 14:58:58 -0500 Subject: [PATCH] sync some more changes --- CMakeLists.txt | 2 +- include/common/screen.hpp | 11 ++ include/modules/keyboard/keyboard.tcc | 5 - .../cafe/include/modules/keyboard_ext.hpp | 26 ++-- .../include/utilities/driver/framebuffer.hpp | 31 ++++ .../include/utilities/driver/renderer_ext.hpp | 8 + platform/cafe/source/modules/graphics_ext.cpp | 8 +- platform/cafe/source/modules/keyboard_ext.cpp | 8 - .../source/utilities/driver/framebuffer.cpp | 34 ++++- .../source/utilities/driver/renderer_ext.cpp | 139 +++++++++--------- platform/ctr/include/modules/keyboard_ext.hpp | 6 + platform/ctr/source/modules/keyboard_ext.cpp | 4 +- platform/hac/include/modules/keyboard_ext.hpp | 6 + platform/hac/source/modules/keyboard_ext.cpp | 6 +- source/modules/love/scripts/callbacks.lua | 3 +- 15 files changed, 193 insertions(+), 104 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 0c6349c4e..69480902b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -182,7 +182,7 @@ if (NINTENDO_WIIU) target_include_directories(${PROJECT_NAME} PRIVATE ${DEVKITPRO}/portlibs/wiiu/include) target_include_directories(${PROJECT_NAME} PRIVATE ${FREETYPE_INCLUDE_DIRS}) - target_link_libraries(${PROJECT_NAME} PRIVATE SDL2_Mixer mpg123 SDL2) + target_link_libraries(${PROJECT_NAME} PRIVATE SDL2_mixer mpg123 SDL2) endif() # Options for code generation diff --git a/include/common/screen.hpp b/include/common/screen.hpp index 13cecb4f2..2bd95fbe5 100644 --- a/include/common/screen.hpp +++ b/include/common/screen.hpp @@ -98,4 +98,15 @@ namespace love return result; } + + inline std::vector GetScreenEnums() + { + std::vector result {}; + const auto& info = GetScreenInfo(); + + for (auto& item : info) + result.push_back((Screen)item.id); + + return result; + } } // namespace love diff --git a/include/modules/keyboard/keyboard.tcc b/include/modules/keyboard/keyboard.tcc index ad9704c54..b5daad8fe 100644 --- a/include/modules/keyboard/keyboard.tcc +++ b/include/modules/keyboard/keyboard.tcc @@ -63,11 +63,6 @@ namespace love return "love.keyboard"; } - const bool HasTextInput() const - { - return true; - } - const bool HasScreenKeyboard() const { return true; diff --git a/platform/cafe/include/modules/keyboard_ext.hpp b/platform/cafe/include/modules/keyboard_ext.hpp index 8c1758f75..42e425060 100644 --- a/platform/cafe/include/modules/keyboard_ext.hpp +++ b/platform/cafe/include/modules/keyboard_ext.hpp @@ -25,14 +25,6 @@ namespace love virtual ~Keyboard(); - void SetContextState() - { - if (!this->IsShowing()) - return; - - GX2SetContextState(this->state); - } - void SetTextInput(const KeyboardOptions& options); const uint32_t GetMaxEncodingLength(const uint32_t in) @@ -40,10 +32,24 @@ namespace love return in * 0x04; } + const nn::swkbd::State GetState() const + { + return nn::swkbd::GetStateInputForm(); + } + + const bool HasTextInput() const + { + return this->IsShowing(); + } + const bool IsShowing() const { - auto state = nn::swkbd::GetStateInputForm(); - return state != nn::swkbd::State::Hidden; + return this->GetState() != nn::swkbd::State::Hidden; + } + + const bool IsHiding() const + { + return this->GetState() == nn::swkbd::State::FadeOut; } void HideKeyboard() diff --git a/platform/cafe/include/utilities/driver/framebuffer.hpp b/platform/cafe/include/utilities/driver/framebuffer.hpp index 9a51ea801..89c7379ba 100644 --- a/platform/cafe/include/utilities/driver/framebuffer.hpp +++ b/platform/cafe/include/utilities/driver/framebuffer.hpp @@ -1,12 +1,15 @@ #pragma once +#include #include #include #include +#include #include #include +#include #include @@ -16,6 +19,10 @@ namespace love { class Framebuffer { + private: + static constexpr float Z_NEAR = -10.0f; + static constexpr float Z_FAR = 10.0f; + public: struct Transform { @@ -62,6 +69,10 @@ namespace love */ void SetProjection(const glm::highp_mat4& projection); + void SetViewport(const Rect& viewport = Rect::EMPTY); + + void SetScissor(const Rect& scissor = Rect::EMPTY); + /* ** Invalidates the little endian Transform ** to be used in the Uniform Block @@ -93,6 +104,21 @@ namespace love /* Called on Renderer::OnForegroundAcquired */ bool InvalidateDepthBuffer(MEMHeapHandle handle); + void SetContext() + { + GX2SetContextState(this->state); + } + + Rect GetViewport() const + { + return this->viewport; + } + + Rect GetScissor() const + { + return this->scissor; + } + private: static constexpr GX2ScanTarget SCAN_TARGETS[0x02] { GX2_SCAN_TARGET_TV, GX2_SCAN_TARGET_DRC }; @@ -141,6 +167,8 @@ namespace love GX2ColorBuffer colorBuffer; GX2DepthBuffer depthBuffer; + GX2ContextState* state; + uint8_t mode; void* scanBuffer; @@ -148,5 +176,8 @@ namespace love int width; int height; + + Rect viewport; + Rect scissor; }; } // namespace love diff --git a/platform/cafe/include/utilities/driver/renderer_ext.hpp b/platform/cafe/include/utilities/driver/renderer_ext.hpp index bbbfee7fc..3687c4291 100644 --- a/platform/cafe/include/utilities/driver/renderer_ext.hpp +++ b/platform/cafe/include/utilities/driver/renderer_ext.hpp @@ -85,6 +85,8 @@ namespace love void Clear(const Color& color); + void SetDepthWrites(bool write); + void ClearDepthStencil(int stencil, uint8_t mask, double depth); void SetBlendColor(const Color& color); @@ -208,6 +210,12 @@ namespace love GX2FrontFace winding; bool cullFront; bool cullBack; + + bool depthWrite; + bool depthTest; + GX2CompareFunction compareMode; + + uint32_t writeMask; } renderState; std::vector> buffers; diff --git a/platform/cafe/source/modules/graphics_ext.cpp b/platform/cafe/source/modules/graphics_ext.cpp index 60a75e452..6f5c20003 100644 --- a/platform/cafe/source/modules/graphics_ext.cpp +++ b/platform/cafe/source/modules/graphics_ext.cpp @@ -36,6 +36,9 @@ void Graphics::Clear(OptionalColor color, OptionalInt stencil, Op if (stencil.has_value() && depth.has_value()) ::Renderer::Instance().ClearDepthStencil(stencil.value(), 0xFF, depth.value()); + + if (color.has_value() && Shader::current) + ::Renderer::Instance().UseProgram(Shader::current->GetGroup()); } void Graphics::Clear(std::vector& colors, OptionalInt stencil, @@ -44,7 +47,10 @@ void Graphics::Clear(std::vector& colors, Optional int colorCount = colors.size(); if (colorCount == 0 || !stencil.has_value() || !depth.has_value()) - this->Clear(colorCount > 0 ? colors[0] : Color {}, stencil, depth); + return; + + if (stencil.has_value() || depth.has_value()) + ::Renderer::Instance().ClearDepthStencil(stencil.value(), 0xFF, depth.value()); } void Graphics::Present() diff --git a/platform/cafe/source/modules/keyboard_ext.cpp b/platform/cafe/source/modules/keyboard_ext.cpp index 1de1d7b9b..bdb26e286 100644 --- a/platform/cafe/source/modules/keyboard_ext.cpp +++ b/platform/cafe/source/modules/keyboard_ext.cpp @@ -10,7 +10,6 @@ using namespace love; Keyboard::Keyboard() : Keyboard<>(this->GetMaxEncodingLength(MAX_INPUT_LENGTH)), - state(nullptr), createArgs {}, appearArgs {}, client(nullptr), @@ -19,13 +18,6 @@ Keyboard::Keyboard() : void Keyboard::Initialize() { - this->state = (GX2ContextState*)memalign(GX2_CONTEXT_STATE_ALIGNMENT, sizeof(GX2ContextState)); - - if (!this->state) - throw love::Exception("Failed to allocate GX2ContextState for nn::swkbd!"); - - GX2SetupContextStateEx(this->state, false); - this->client = (FSClient*)MEMAllocFromDefaultHeap(sizeof(FSClient)); if (!this->client) diff --git a/platform/cafe/source/utilities/driver/framebuffer.cpp b/platform/cafe/source/utilities/driver/framebuffer.cpp index 469a9fec6..1ff93f162 100644 --- a/platform/cafe/source/utilities/driver/framebuffer.cpp +++ b/platform/cafe/source/utilities/driver/framebuffer.cpp @@ -28,11 +28,16 @@ Framebuffer::Framebuffer() : scanBuffer(nullptr), scanBufferSize(0), width(0), - height(0) + height(0), + viewport {}, + scissor {} {} Framebuffer::~Framebuffer() -{} +{ + free(this->state); + this->state = nullptr; +} void Framebuffer::Create(Screen screen) { @@ -204,6 +209,12 @@ void Framebuffer::SetSize(int width, int height) this->InitColorBuffer(); this->InitDepthBuffer(); + + this->viewport = { 0, 0, width, height }; + this->scissor = { 0, 0, width, height }; + + this->SetViewport(); + this->SetScissor(); } void Framebuffer::SetTVSize() @@ -224,6 +235,22 @@ void Framebuffer::SetDRCSize() GX2SetDRCScale(this->width, this->height); } +void Framebuffer::SetViewport(const Rect& viewport) +{ + if (viewport == Rect::EMPTY) + GX2SetViewport(0, 0, (float)this->width, (float)this->height, Z_NEAR, Z_FAR); + else + GX2SetViewport(viewport.x, viewport.y, viewport.w, viewport.h, Z_NEAR, Z_FAR); +} + +void Framebuffer::SetScissor(const Rect& scissor) +{ + if (scissor == Rect::EMPTY) + GX2SetScissor(0, 0, this->width, this->height); + else + GX2SetScissor(scissor.x, scissor.y, scissor.w, scissor.h); +} + void Framebuffer::SetProjection(const glm::highp_mat4& _projection) { /* glm::value_ptr lets us access the data linearly rather than an XxY matrix */ @@ -243,8 +270,7 @@ void Framebuffer::SetProjection(const glm::highp_mat4& _projection) void Framebuffer::UseProjection() { - GX2Invalidate(Framebuffer::INVALIDATE_UNIFORM, (void*)this->transform, - Framebuffer::TRANSFORM_SIZE); + GX2Invalidate(INVALIDATE_UNIFORM, (void*)this->transform, TRANSFORM_SIZE); GX2SetVertexUniformBlock(1, Framebuffer::TRANSFORM_SIZE, (const void*)this->transform); } diff --git a/platform/cafe/source/utilities/driver/renderer_ext.cpp b/platform/cafe/source/utilities/driver/renderer_ext.cpp index d0e9eec22..23d653003 100644 --- a/platform/cafe/source/utilities/driver/renderer_ext.cpp +++ b/platform/cafe/source/utilities/driver/renderer_ext.cpp @@ -41,17 +41,8 @@ Renderer::Renderer() : GX2Init(attributes); - for (size_t index = 0; index < Renderer::MAX_RENDERTARGETS; index++) - { - const auto screen = (Screen)index; + for (const auto screen : love::GetScreenEnums()) this->framebuffers[screen].Create(screen); - } - - ProcUIRegisterCallback(PROCUI_CALLBACK_ACQUIRE, ProcUIAcquired, nullptr, 100); - ProcUIRegisterCallback(PROCUI_CALLBACK_RELEASE, ProcUIReleased, nullptr, 100); - - if (int result = this->OnForegroundAcquired(); result != 0) - throw love::Exception("Failed to acquire application foreground (error %d).", result); this->state = (GX2ContextState*)memalign(GX2_CONTEXT_STATE_ALIGNMENT, sizeof(GX2ContextState)); @@ -62,17 +53,26 @@ Renderer::Renderer() : GX2SetContextState(this->state); GX2SetDepthOnlyControl(false, false, GX2_COMPARE_FUNC_ALWAYS); - // GX2SetAlphaTest(true, GX2_COMPARE_FUNC_GREATER, 0); + GX2SetAlphaTest(true, GX2_COMPARE_FUNC_GREATER, 0); GX2SetColorControl(GX2_LOGIC_OP_COPY, 0xFF, false, true); GX2SetSwapInterval(1); + ProcUIRegisterCallback(PROCUI_CALLBACK_ACQUIRE, ProcUIAcquired, nullptr, 100); + ProcUIRegisterCallback(PROCUI_CALLBACK_RELEASE, ProcUIReleased, nullptr, 100); + + if (int result = this->OnForegroundAcquired(); result != 0) + throw love::Exception("Failed to acquire application foreground (error %d).", result); + if (Keyboard() != nullptr) Keyboard()->Initialize(); /* set up some state information */ - this->renderState.winding = GX2_FRONT_FACE_CCW; - this->renderState.cullBack = true; + this->renderState.winding = GX2_FRONT_FACE_CCW; + this->renderState.cullBack = true; + this->renderState.depthTest = false; + this->renderState.depthWrite = false; + this->renderState.compareMode = GX2_COMPARE_FUNC_ALWAYS; } uint32_t Renderer::ProcUIAcquired(void* arg) @@ -139,9 +139,6 @@ Renderer::~Renderer() GX2Shutdown(); - free(this->state); - this->state = nullptr; - free(this->commandBuffer); this->commandBuffer = nullptr; } @@ -158,8 +155,17 @@ void Renderer::Clear(const Color& color) GX2SetContextState(this->state); } +void Renderer::SetDepthWrites(bool enable) +{ + GX2SetDepthOnlyControl(this->renderState.depthTest, enable, this->renderState.compareMode); + this->renderState.depthWrite = enable; +} + void Renderer::ClearDepthStencil(int stencil, uint8_t mask, double depth) { + if (!this->renderState.depthWrite) + this->SetDepthWrites(true); + GX2ClearDepthStencilEx(&this->current->GetDepthBuffer(), depth, stencil, GX2_CLEAR_FLAGS_BOTH); GX2SetContextState(this->state); } @@ -167,6 +173,7 @@ void Renderer::ClearDepthStencil(int stencil, uint8_t mask, doubl void Renderer::SetBlendColor(const Color& color) { GX2SetBlendConstantColor(color.r, color.g, color.b, color.a); + GX2SetContextState(this->state); } void Renderer::SetBlendMode(const RenderState::BlendState& state) @@ -239,26 +246,56 @@ void Renderer::BindFramebuffer(Texture* texture) GX2SetColorBuffer(&this->current->GetBuffer(), GX2_RENDER_TARGET_0); GX2SetDepthBuffer(&this->current->GetDepthBuffer()); - this->SetViewport(Rect::EMPTY); - this->SetScissor(Rect::EMPTY); + this->SetViewport(this->current->GetViewport()); + this->SetScissor(this->current->GetScissor()); } this->current->UseProjection(); } +bool Renderer::Render(Graphics::DrawCommand& command) +{ + Shader::defaults[command.shader]->Attach(); + + if (!command.buffer->IsValid()) + return false; + + std::optional primitive; + if (!(primitive = primitiveModes.Find(command.primitveType))) + return false; + + if (!command.handles.empty()) + { + for (size_t index = 0; index < command.handles.size(); index++) + { + auto* texture = command.handles[index]->GetHandle(); + auto* sampler = &command.handles[index]->GetSampler(); + + Shader::current->BindTexture(index, texture, sampler); + } + } + + GX2RSetAttributeBuffer(command.buffer->GetBuffer(), 0, command.stride, 0); + GX2DrawEx(*primitive, command.count, 0, 1); + + this->buffers.push_back(command.buffer); + + return true; +} + void Renderer::Present() { + GX2DrawDone(); + if (Keyboard()->IsShowing()) { nn::swkbd::DrawDRC(); GX2SetContextState(this->state); - Shader::current->Attach(true); } /* copy our color buffers to their scan buffers */ - this->framebuffers[Screen::TV].CopyScanBuffer(); - - this->framebuffers[Screen::GAMEPAD].CopyScanBuffer(); + for (auto& framebuffer : this->framebuffers) + framebuffer.second.CopyScanBuffer(); /* swap scan buffers */ GX2SwapScanBuffers(); @@ -314,36 +351,6 @@ void Renderer::UseProgram(const WHBGfxShaderGroup& group) this->current->UseProjection(); } -bool Renderer::Render(Graphics::DrawCommand& command) -{ - Shader::defaults[command.shader]->Attach(); - - if (!command.buffer->IsValid()) - return false; - - std::optional primitive; - if (!(primitive = primitiveModes.Find(command.primitveType))) - return false; - - if (!command.handles.empty()) - { - for (size_t index = 0; index < command.handles.size(); index++) - { - auto* texture = command.handles[index]->GetHandle(); - auto* sampler = &command.handles[index]->GetSampler(); - - Shader::current->BindTexture(index, texture, sampler); - } - } - - GX2RSetAttributeBuffer(command.buffer->GetBuffer(), 0, command.stride, 0); - GX2DrawEx(*primitive, command.count, 0, 1); - - this->buffers.push_back(command.buffer); - - return true; -} - /* todo */ void Renderer::SetColorMask(const RenderState::ColorMask& mask) { @@ -364,34 +371,22 @@ void Renderer::SetViewport(const Rect& viewport) { this->EnsureInFrame(); - glm::highp_mat4 ortho {}; + float width = viewport.w; + float height = viewport.h; if (viewport == Rect::EMPTY) { - float width = (float)this->current->GetWidth(); - float height = (float)this->current->GetHeight(); - - GX2SetViewport(0.0f, 0.0f, width, height, Z_NEAR, Z_FAR); - ortho = glm::ortho(0.0f, width, height, 0.0f, Z_NEAR, Z_FAR); - } - else - { - GX2SetViewport(viewport.x, viewport.y, viewport.w, viewport.h, Z_NEAR, Z_FAR); - ortho = glm::ortho(0.0f, (float)viewport.w, (float)viewport.h, 0.0f, Z_NEAR, Z_FAR); + width = (float)this->current->GetWidth(); + height = (float)this->current->GetHeight(); } + this->current->SetViewport(viewport); + + auto ortho = glm::ortho(0.0f, width, height, 0.0f, Z_NEAR, Z_FAR); this->current->SetProjection(ortho); } void Renderer::SetScissor(const Rect& scissor) { - if (scissor == Rect::EMPTY) - { - uint32_t width = (uint32_t)this->current->GetWidth(); - uint32_t height = (uint32_t)this->current->GetHeight(); - - GX2SetScissor(0, 0, width, height); - } - else - GX2SetScissor(scissor.x, scissor.y, scissor.w, scissor.h); + this->current->SetScissor(scissor); } diff --git a/platform/ctr/include/modules/keyboard_ext.hpp b/platform/ctr/include/modules/keyboard_ext.hpp index 163bab240..5232dd4a9 100644 --- a/platform/ctr/include/modules/keyboard_ext.hpp +++ b/platform/ctr/include/modules/keyboard_ext.hpp @@ -22,6 +22,11 @@ namespace love return in * 0x03; } + const bool HasTextInput() const + { + return this->showing; + } + // clang-format off static constexpr BidirectionalMap keyboardTypes = { "normal", SWKBD_TYPE_NORMAL, @@ -32,5 +37,6 @@ namespace love private: SwkbdState state; + bool showing; }; } // namespace love diff --git a/platform/ctr/source/modules/keyboard_ext.cpp b/platform/ctr/source/modules/keyboard_ext.cpp index bd27d1d1b..d61f5b680 100644 --- a/platform/ctr/source/modules/keyboard_ext.cpp +++ b/platform/ctr/source/modules/keyboard_ext.cpp @@ -5,7 +5,8 @@ using namespace love; Keyboard::Keyboard() : Keyboard(this->GetMaxEncodingLength(MAX_INPUT_LENGTH * 3) + 1), - state {} + state {}, + showing(false) {} void Keyboard::SetTextInput(const KeyboardOptions& options) @@ -23,6 +24,7 @@ void Keyboard::SetTextInput(const KeyboardOptions& options) if (options.isPassword) swkbdSetPasswordMode(&this->state, SWKBD_PASSWORD_HIDE_DELAY); + this->showing = true; const auto button = swkbdInputText(&this->state, this->text.get(), maxLength); if (button != SWKBD_BUTTON_LEFT) diff --git a/platform/hac/include/modules/keyboard_ext.hpp b/platform/hac/include/modules/keyboard_ext.hpp index 40b58a481..391cc1d20 100644 --- a/platform/hac/include/modules/keyboard_ext.hpp +++ b/platform/hac/include/modules/keyboard_ext.hpp @@ -22,6 +22,11 @@ namespace love void SetTextInput(const KeyboardOptions& options); + const bool HasTextInput() const + { + return this->showing; + } + // clang-format off static constexpr BidirectionalMap keyboardTypes = { "normal", SwkbdType_Normal, @@ -32,5 +37,6 @@ namespace love private: SwkbdConfig config; + bool showing; }; } // namespace love diff --git a/platform/hac/source/modules/keyboard_ext.cpp b/platform/hac/source/modules/keyboard_ext.cpp index 4d62940f6..77caf8637 100644 --- a/platform/hac/source/modules/keyboard_ext.cpp +++ b/platform/hac/source/modules/keyboard_ext.cpp @@ -3,7 +3,10 @@ using namespace love; -Keyboard::Keyboard() : Keyboard<>(this->GetMaxEncodingLength(MAX_INPUT_LENGTH) + 1) +Keyboard::Keyboard() : + Keyboard<>(this->GetMaxEncodingLength(MAX_INPUT_LENGTH) + 1), + config {}, + showing(false) {} void Keyboard::SetTextInput(const KeyboardOptions& options) @@ -26,6 +29,7 @@ void Keyboard::SetTextInput(const KeyboardOptions& options) swkbdConfigSetGuideText(&this->config, options.hint.data()); + this->showing = true; if (R_SUCCEEDED(swkbdShow(&this->config, this->text.get(), maxLength))) HID::Instance().SendTextInput(this->GetText()); diff --git a/source/modules/love/scripts/callbacks.lua b/source/modules/love/scripts/callbacks.lua index 98fe008c0..1056a907c 100644 --- a/source/modules/love/scripts/callbacks.lua +++ b/source/modules/love/scripts/callbacks.lua @@ -215,6 +215,7 @@ function love.run() end local delta = 0 + local is_wii_u = love._os == "Cafe" return function() if love.window and g_windowShown then @@ -239,7 +240,7 @@ function love.run() delta = love.timer.step() end - if love.update then + if love.update and (is_wii_u and not love.keyboard.hasTextInput()) then love.update(delta) end