From 443af2d8a4201faa460e1fecacbe83f456c04e01 Mon Sep 17 00:00:00 2001 From: TurtleP Date: Sat, 2 Nov 2024 11:47:38 -0400 Subject: [PATCH] add wiimote pos/angle functions for joysticks --- include/modules/graphics/Graphics.tcc | 2 + include/modules/graphics/wrap_Graphics.hpp | 2 + include/modules/joystick/wrap_Joystick.hpp | 4 ++ .../include/driver/display/Framebuffer.hpp | 2 + .../modules/joystick/kpad/Joystick.hpp | 6 ++- .../source/driver/display/Framebuffer.cpp | 6 +-- .../source/modules/joystick/kpad/Joystick.cpp | 33 ++++++++---- source/modules/graphics/Graphics.cpp | 5 ++ source/modules/graphics/wrap_Graphics.cpp | 50 +++++++++++++++++++ source/modules/joystick/wrap_Joystick.cpp | 45 ++++++++++++++++- 10 files changed, 139 insertions(+), 16 deletions(-) diff --git a/include/modules/graphics/Graphics.tcc b/include/modules/graphics/Graphics.tcc index 156af4fc..3f8042b1 100644 --- a/include/modules/graphics/Graphics.tcc +++ b/include/modules/graphics/Graphics.tcc @@ -460,6 +460,8 @@ namespace love void setBlendMode(BlendMode mode, BlendAlpha alphaMode); + Quad* newQuad(Quad::Viewport viewport, double sourceWidth, double sourceHeight) const; + virtual TextureBase* newTexture(const TextureBase::Settings& settings, const TextureBase::Slices* data = nullptr) = 0; diff --git a/include/modules/graphics/wrap_Graphics.hpp b/include/modules/graphics/wrap_Graphics.hpp index ac7a9cbe..8c351a09 100644 --- a/include/modules/graphics/wrap_Graphics.hpp +++ b/include/modules/graphics/wrap_Graphics.hpp @@ -163,6 +163,8 @@ namespace Wrap_Graphics int newTexture(lua_State* L); + int newQuad(lua_State* L); + int newImage(lua_State* L); int newCanvas(lua_State* L); diff --git a/include/modules/joystick/wrap_Joystick.hpp b/include/modules/joystick/wrap_Joystick.hpp index 827c7e6d..fc9f7f56 100644 --- a/include/modules/joystick/wrap_Joystick.hpp +++ b/include/modules/joystick/wrap_Joystick.hpp @@ -67,4 +67,8 @@ namespace Wrap_Joystick int setSensorEnabled(lua_State* L); int getSensorData(lua_State* L); + + int getPosition(lua_State* L); + + int getAngle(lua_State* L); } // namespace Wrap_Joystick diff --git a/platform/cafe/include/driver/display/Framebuffer.hpp b/platform/cafe/include/driver/display/Framebuffer.hpp index 074aaf49..a8c19b4a 100644 --- a/platform/cafe/include/driver/display/Framebuffer.hpp +++ b/platform/cafe/include/driver/display/Framebuffer.hpp @@ -62,7 +62,9 @@ namespace love GX2ScanTarget id; Uniform* uniform = nullptr; + glm::mat4 tmpModel; + glm::highp_mat4 ortho; void* scanBuffer; uint32_t scanBufferSize; diff --git a/platform/cafe/include/modules/joystick/kpad/Joystick.hpp b/platform/cafe/include/modules/joystick/kpad/Joystick.hpp index 9a62ac7f..35b36615 100644 --- a/platform/cafe/include/modules/joystick/kpad/Joystick.hpp +++ b/platform/cafe/include/modules/joystick/kpad/Joystick.hpp @@ -1,5 +1,7 @@ #pragma once +#include "common/Vector.hpp" + #include "modules/joystick/Joystick.tcc" #include @@ -59,9 +61,9 @@ namespace love virtual std::vector getSensorData(Sensor::SensorType type) const override; - std::array getPosition() const; + Vector2 getPosition() const; - std::array getAngle() const; + Vector2 getAngle() const; using JoystickBase::getConstant; diff --git a/platform/cafe/source/driver/display/Framebuffer.cpp b/platform/cafe/source/driver/display/Framebuffer.cpp index f8241019..c5eb39da 100644 --- a/platform/cafe/source/driver/display/Framebuffer.cpp +++ b/platform/cafe/source/driver/display/Framebuffer.cpp @@ -120,7 +120,7 @@ namespace love this->viewport = { 0, 0, info.width, info.height }; this->scissor = { 0, 0, info.width, info.height }; - auto ortho = glm::ortho(0.0f, (float)info.width, (float)info.height, 0.0f, Z_NEAR, Z_FAR); + this->ortho = glm::ortho(0.0f, (float)info.width, (float)info.height, 0.0f, Z_NEAR, Z_FAR); /* glm::value_ptr lets us access the data linearly rather than an XxY matrix */ uint32_t* dstModel = (uint32_t*)glm::value_ptr(this->uniform->modelView); @@ -132,11 +132,9 @@ namespace love for (size_t index = 0; index < count; index++) dstModel[index] = __builtin_bswap32(model[index]); - uint32_t* projection = (uint32_t*)glm::value_ptr(ortho); + uint32_t* projection = (uint32_t*)glm::value_ptr(this->ortho); for (size_t index = 0; index < count; index++) dstProj[index] = __builtin_bswap32(projection[index]); - - love::debugUniform(this->uniform); } void Framebuffer::setScissor(const Rect& scissor) diff --git a/platform/cafe/source/modules/joystick/kpad/Joystick.cpp b/platform/cafe/source/modules/joystick/kpad/Joystick.cpp index 6ac250da..9280c83d 100644 --- a/platform/cafe/source/modules/joystick/kpad/Joystick.cpp +++ b/platform/cafe/source/modules/joystick/kpad/Joystick.cpp @@ -1,3 +1,5 @@ +#include "common/screen.hpp" + #include "modules/joystick/kpad/Joystick.hpp" namespace love @@ -435,17 +437,27 @@ namespace love return data; } - std::array Joystick::getPosition() const + static Vector2 ndcToScreen(const KPADVec2D& input) { - std::array result {}; + Vector2 result {}; + const auto& info = love::getScreenInfo((Screen)0); + + result.x = ((input.x) / 2) * info.width; + result.y = ((input.y + 1.0f) / 2) * info.height; + + return result; + } + Vector2 Joystick::getPosition() const + { switch (this->gamepadType) { case GAMEPAD_TYPE_NINTENDO_WII_REMOTE: case GAMEPAD_TYPE_NINTENDO_WII_REMOTE_NUNCHUK: { - result[0] = this->status.pos.x; - result[1] = this->status.pos.y; + if (this->status.posValid) + return ndcToScreen(this->status.pos); + break; } case GAMEPAD_TYPE_NINTENDO_WII_CLASSIC: @@ -454,20 +466,23 @@ namespace love break; } - return result; + return Vector2 {}; } - std::array Joystick::getAngle() const + Vector2 Joystick::getAngle() const { - std::array result {}; + Vector2 result {}; switch (this->gamepadType) { case GAMEPAD_TYPE_NINTENDO_WII_REMOTE: case GAMEPAD_TYPE_NINTENDO_WII_REMOTE_NUNCHUK: { - result[0] = this->status.angle.x; - result[1] = this->status.angle.y; + if (!this->status.posValid) + break; + + result.x = this->status.angle.x; + result.y = this->status.angle.y; break; } case GAMEPAD_TYPE_NINTENDO_WII_CLASSIC: diff --git a/source/modules/graphics/Graphics.cpp b/source/modules/graphics/Graphics.cpp index 33a015d0..61b19b40 100644 --- a/source/modules/graphics/Graphics.cpp +++ b/source/modules/graphics/Graphics.cpp @@ -401,6 +401,11 @@ namespace love return data; } + Quad* GraphicsBase::newQuad(Quad::Viewport viewport, double sourceWidth, double sourceHeight) const + { + return new Quad(viewport, sourceWidth, sourceHeight); + } + TextBatch* GraphicsBase::newTextBatch(FontBase* font, const std::vector& text) { return new TextBatch(font, text); diff --git a/source/modules/graphics/wrap_Graphics.cpp b/source/modules/graphics/wrap_Graphics.cpp index cd2d16a2..e3f99466 100644 --- a/source/modules/graphics/wrap_Graphics.cpp +++ b/source/modules/graphics/wrap_Graphics.cpp @@ -977,6 +977,55 @@ int Wrap_Graphics::newTexture(lua_State* L) return pushNewTexture(L, slicesRef, settings); } +int Wrap_Graphics::newQuad(lua_State* L) +{ + luax_checkgraphicscreated(L); + + Quad::Viewport viewport {}; + viewport.x = luaL_checknumber(L, 1); + viewport.y = luaL_checknumber(L, 2); + viewport.w = luaL_checknumber(L, 3); + viewport.h = luaL_checknumber(L, 4); + + double sourceWidth = 0.0f; + double sourceHeight = 0.0f; + + int layer = 0; + + if (luax_istype(L, 5, TextureBase::type)) + { + TextureBase* texture = luax_checktexture(L, 5); + sourceWidth = texture->getWidth(); + sourceHeight = texture->getHeight(); + } + else if (luax_istype(L, 6, TextureBase::type)) + { + layer = (int)luaL_checkinteger(L, 5) - 1; + TextureBase* texture = luax_checktexture(L, 6); + sourceWidth = texture->getWidth(); + sourceHeight = texture->getHeight(); + } + else if (!lua_isnoneornil(L, 7)) + { + layer = (int)luaL_checkinteger(L, 5) - 1; + sourceWidth = luaL_checknumber(L, 6); + sourceHeight = luaL_checknumber(L, 7); + } + else + { + sourceWidth = luaL_checknumber(L, 5); + sourceHeight = luaL_checknumber(L, 6); + } + + Quad* quad = instance()->newQuad(viewport, sourceWidth, sourceHeight); + quad->setLayer(layer); + + luax_pushtype(L, quad); + quad->release(); + + return 1; +} + int Wrap_Graphics::newImage(lua_State* L) { return newTexture(L); @@ -1823,6 +1872,7 @@ static constexpr luaL_Reg functions[] = { "line", Wrap_Graphics::line }, { "newTexture", Wrap_Graphics::newTexture }, + { "newQuad", Wrap_Graphics::newQuad }, { "newImage", Wrap_Graphics::newImage }, // { "newMesh", Wrap_Graphics::newMesh }, diff --git a/source/modules/joystick/wrap_Joystick.cpp b/source/modules/joystick/wrap_Joystick.cpp index f99f0a39..d340d6d4 100644 --- a/source/modules/joystick/wrap_Joystick.cpp +++ b/source/modules/joystick/wrap_Joystick.cpp @@ -430,6 +430,49 @@ static constexpr luaL_Reg functions[] = { { "getSensorData", Wrap_Joystick::getSensorData }, { "getConnectedIndex", Wrap_JoystickModule::getIndex } }; + +#if !defined(__WIIU__) +static constexpr luaL_Reg extFunctions[] = {}; +#else +#include "modules/joystick/kpad/Joystick.hpp" + +int Wrap_Joystick::getPosition(lua_State*L) +{ + auto* base = luax_checkjoystick(L, 1); + const auto type = base->getGamepadType(); + + if (type != GAMEPAD_TYPE_NINTENDO_WII_REMOTE && type != GAMEPAD_TYPE_NINTENDO_WII_REMOTE_NUNCHUK) + return luaL_error(L, "Invalid controller! Must be of type Wii Remote"); + + auto position = ((kpad::Joystick*)base)->getPosition(); + + lua_pushnumber(L, position.x); + lua_pushnumber(L, position.y); + + return 2; +} + +int Wrap_Joystick::getAngle(lua_State*L) +{ + auto* base = luax_checkjoystick(L, 1); + const auto type = base->getGamepadType(); + + if (type != GAMEPAD_TYPE_NINTENDO_WII_REMOTE && type != GAMEPAD_TYPE_NINTENDO_WII_REMOTE_NUNCHUK) + return luaL_error(L, "Invalid controller! Must be of type Wii Remote"); + + auto angle = ((kpad::Joystick*)base)->getAngle(); + + lua_pushnumber(L, angle.x); + lua_pushnumber(L, angle.y); + + return 2; +} + +static constexpr luaL_Reg extFunctions[] = { + { "getPosition", Wrap_Joystick::getPosition }, + { "getAngle", Wrap_Joystick::getAngle } +}; +#endif // clang-format on namespace love @@ -441,6 +484,6 @@ namespace love int open_joystick(lua_State* L) { - return luax_register_type(L, &JoystickBase::type, functions); + return luax_register_type(L, &JoystickBase::type, functions, extFunctions); } } // namespace love