diff --git a/Makefile.switch b/Makefile.switch index a553810..af88bca 100644 --- a/Makefile.switch +++ b/Makefile.switch @@ -114,7 +114,8 @@ CFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.c))) CPPFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.cpp))) SFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.s))) GLSLFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.glsl))) -GFXFILES := $(foreach dir,$(GRAPHICS),$(notdir $(wildcard $(dir)/*.png))) +PNGFILES := $(foreach dir,$(GRAPHICS),$(notdir $(wildcard $(dir)/*.png))) +ASTCFILES := $(foreach dir,$(GRAPHICS),$(notdir $(wildcard $(dir)/*.astc))) BINFILES := $(foreach dir,$(DATA),$(notdir $(wildcard $(dir)/*.*))) #--------------------------------------------------------------------------------- @@ -145,7 +146,9 @@ ifneq ($(strip $(ROMFS)),) ROMFS_FOLDERS += $(ROMFS_SHADERS) endif - ROMFS_GFX := $(addprefix $(ROMFS)/,$(GFXFILES:.png=.rgba.zst)) + ROMFS_PNG := $(addprefix $(ROMFS)/,$(PNGFILES:.png=.rgba.zst)) + ROMFS_ASTC := $(addprefix $(ROMFS)/,$(ASTCFILES:.astc=.astc.zst)) + ROMFS_GFX := $(ROMFS_PNG) $(ROMFS_ASTC) ROMFS_TARGETS += $(ROMFS_GFX) ROMFS_FOLDERS += $(ROMFS) @@ -222,7 +225,10 @@ $(ROMFS_FOLDERS): $(BUILD)/%.rgba: $(GRAPHICS)/%.png | $(BUILD) @convert $< $@ -$(ROMFS_GFX): $(ROMFS)/%.rgba.zst: $(BUILD)/%.rgba +$(ROMFS_PNG): $(ROMFS)/%.rgba.zst: $(BUILD)/%.rgba + @zstd -f $< -o $@ --ultra -22 + +$(ROMFS_ASTC): $(ROMFS)/%.astc.zst: $(GRAPHICS)/%.astc @zstd -f $< -o $@ --ultra -22 $(ROMFS_SHADERS)/%_vsh.dksh: %_vsh.glsl diff --git a/source/switch/imgui_nx.cpp b/source/switch/imgui_nx.cpp index 435e8be..ab4febc 100644 --- a/source/switch/imgui_nx.cpp +++ b/source/switch/imgui_nx.cpp @@ -1238,15 +1238,14 @@ void moveMouse (ImGuiIO &io_, ImVec2 const &pos_, bool const force_ = false) } /// \brief Update mouse buttons +/// \param mouseState_ Mouse state /// \param io_ ImGui IO -void updateMouseButtons (ImGuiIO &io_) +void updateMouseButtons (HidMouseState const &mouseState_, ImGuiIO &io_) { // read mouse buttons - auto const buttons = hidMouseButtonsHeld (); - for (std::size_t i = 0; i < IM_ARRAYSIZE (io_.MouseDown); ++i) { - io_.MouseDown[i] = buttons & BIT (i); + io_.MouseDown[i] = mouseState_.buttons & BIT (i); // force mouse cursor to show on click if (io_.MouseDown[i]) @@ -1255,48 +1254,43 @@ void updateMouseButtons (ImGuiIO &io_) } /// \brief Update mouse position +/// \param mouseState_ Mouse state /// \param io_ ImGui IO -void updateMousePos (ImGuiIO &io_) +void updateMousePos (HidMouseState const &mouseState_, ImGuiIO &io_) { - MousePosition pos; - hidMouseRead (&pos); - - if (pos.scrollVelocityX > 0) + if (mouseState_.wheel_delta_x > 0) io_.MouseWheel += 1; - else if (pos.scrollVelocityX < 0) + else if (mouseState_.wheel_delta_x < 0) io_.MouseWheel -= 1; - if (pos.scrollVelocityY > 0) + if (mouseState_.wheel_delta_y > 0) io_.MouseWheelH += 1; - else if (pos.scrollVelocityY < 0) + else if (mouseState_.wheel_delta_y < 0) io_.MouseWheelH -= 1; - moveMouse ( - io_, ImVec2 (s_mousePos.x + 2.0f * pos.velocityX, s_mousePos.y + 2.0f * pos.velocityY)); + moveMouse (io_, + ImVec2 ( + s_mousePos.x + 2.0f * mouseState_.delta_x, s_mousePos.y + 2.0f * mouseState_.delta_y)); } /// \brief Update touch position +/// \param touchState_ Touch screen state /// \param io_ ImGui IO -void updateTouch (ImGuiIO &io_) +void updateTouch (HidTouchScreenState const &touchState_, ImGuiIO &io_) { - // read touch positions - auto const touchCount = hidTouchCount (); - if (touchCount < 1) + if (touchState_.count < 1) return; - // use first touch position - touchPosition pos; - hidTouchRead (&pos, 0); - // set mouse position to touch point; force hide mouse cursor - moveMouse (io_, ImVec2 (pos.px, pos.py)); + moveMouse (io_, ImVec2 (touchState_.touches[0].x, touchState_.touches[0].y)); io_.MouseDown[0] = true; s_showMouse = false; } /// \brief Update gamepad inputs +/// \param padState_ Gamepad state /// \param io_ ImGui IO -void updateGamepads (ImGuiIO &io_) +void updateGamepads (PadState const &padState_, ImGuiIO &io_) { // clear navigation inputs std::memset (io_.NavInputs, 0, sizeof (io_.NavInputs)); @@ -1317,7 +1311,7 @@ void updateGamepads (ImGuiIO &io_) }; // read buttons from primary controller - auto const keys = hidKeysHeld (CONTROLLER_P1_AUTO); + auto const keys = padGetButtons (&padState_); for (auto const &[in, out] : buttonMapping) { if (keys & in) @@ -1337,16 +1331,15 @@ void updateGamepads (ImGuiIO &io_) } // update joystick - JoystickPosition js; + auto const jsLeft = padGetStickPos (&padState_, 0); auto const analogMapping = { - std::make_tuple (std::ref (js.dx), ImGuiNavInput_LStickLeft, -0.3f, -0.9f), - std::make_tuple (std::ref (js.dx), ImGuiNavInput_LStickRight, +0.3f, +0.9f), - std::make_tuple (std::ref (js.dy), ImGuiNavInput_LStickUp, +0.3f, +0.9f), - std::make_tuple (std::ref (js.dy), ImGuiNavInput_LStickDown, -0.3f, -0.9f), + std::make_tuple (std::ref (jsLeft.x), ImGuiNavInput_LStickLeft, -0.3f, -0.9f), + std::make_tuple (std::ref (jsLeft.x), ImGuiNavInput_LStickRight, +0.3f, +0.9f), + std::make_tuple (std::ref (jsLeft.y), ImGuiNavInput_LStickUp, +0.3f, +0.9f), + std::make_tuple (std::ref (jsLeft.y), ImGuiNavInput_LStickDown, -0.3f, -0.9f), }; // read left joystick from primary controller - hidJoystickRead (&js, CONTROLLER_P1_AUTO, JOYSTICK_LEFT); for (auto const &[in, out, min, max] : analogMapping) { auto const value = in / static_cast (JOYSTICK_MAX); @@ -1359,32 +1352,27 @@ void updateGamepads (ImGuiIO &io_) scale = 1.0f; if (keys & KEY_R) scale = 20.0f; - hidJoystickRead (&js, CONTROLLER_P1_AUTO, JOYSTICK_RIGHT); + + auto const jsRight = padGetStickPos (&padState_, 1); // move mouse moveMouse (io_, - ImVec2 (s_mousePos.x + js.dx / static_cast (JOYSTICK_MAX) * scale, - s_mousePos.y - js.dy / static_cast (JOYSTICK_MAX) * scale)); + ImVec2 (s_mousePos.x + jsRight.x / static_cast (JOYSTICK_MAX) * scale, + s_mousePos.y - jsRight.y / static_cast (JOYSTICK_MAX) * scale)); } /// \brief Update keyboard inputs +/// \param kbState_ Keyboard state /// \param io_ ImGui IO -void updateKeyboard (ImGuiIO &io_) +void updateKeyboard (HidKeyboardState const &kbState_, ImGuiIO &io_) { - io_.KeyCtrl = - hidKeyboardModifierHeld (static_cast (KBD_MOD_LCTRL | KBD_MOD_RCTRL)); - - io_.KeyShift = hidKeyboardModifierHeld ( - static_cast (KBD_MOD_LSHIFT | KBD_MOD_RSHIFT)); - - io_.KeyAlt = - hidKeyboardModifierHeld (static_cast (KBD_MOD_LALT | KBD_MOD_RALT)); - - io_.KeySuper = - hidKeyboardModifierHeld (static_cast (KBD_MOD_LMETA | KBD_MOD_RMETA)); + io_.KeyCtrl = kbState_.modifiers & HidKeyboardModifier_Control; + io_.KeyShift = kbState_.modifiers & HidKeyboardModifier_Shift; + io_.KeyAlt = kbState_.modifiers & (HidKeyboardModifier_LeftAlt | HidKeyboardModifier_RightAlt); + io_.KeySuper = kbState_.modifiers & HidKeyboardModifier_Gui; for (int i = 0; i < 256; ++i) - io_.KeysDown[i] = hidKeyboardHeld (static_cast (i)); + io_.KeysDown[i] = kbState_.keys[i / 64] & (1 << (i % 64)); static enum { INACTIVE, @@ -1521,7 +1509,10 @@ bool imgui::nx::init () return true; } -void imgui::nx::newFrame () +void imgui::nx::newFrame (PadState const *const padState_, + HidTouchScreenState const *const touchState_, + HidMouseState const *const mouseState_, + HidKeyboardState const *const kbState_) { auto &io = ImGui::GetIO (); @@ -1545,11 +1536,20 @@ void imgui::nx::newFrame () if (s_focused) { // update inputs - updateMouseButtons (io); - updateMousePos (io); - updateTouch (io); - updateGamepads (io); - updateKeyboard (io); + if (mouseState_) + { + updateMouseButtons (*mouseState_, io); + updateMousePos (*mouseState_, io); + } + + if (touchState_) + updateTouch (*touchState_, io); + + if (padState_) + updateGamepads (*padState_, io); + + if (kbState_) + updateKeyboard (*kbState_, io); } // whether to draw mouse cursor diff --git a/source/switch/imgui_nx.h b/source/switch/imgui_nx.h index 3048507..37dd8d5 100644 --- a/source/switch/imgui_nx.h +++ b/source/switch/imgui_nx.h @@ -28,6 +28,8 @@ #pragma once #ifndef CLASSIC +#include + namespace imgui { namespace nx @@ -38,7 +40,14 @@ bool init (); void exit (); /// \brief Prepare switch for a new frame -void newFrame (); +/// \param padState_ Gamepad state +/// \param touchState_ Touch screen state +/// \param mouseState_ Mouse state +/// \param kbState_ Keyboard state +void newFrame (PadState const *padState_, + HidTouchScreenState const *touchState_ = nullptr, + HidMouseState const *mouseState_ = nullptr, + HidKeyboardState const *kbState_ = nullptr); } } #endif diff --git a/source/switch/platform.cpp b/source/switch/platform.cpp index e0b0f64..24a4c34 100644 --- a/source/switch/platform.cpp +++ b/source/switch/platform.cpp @@ -78,9 +78,9 @@ enum TextureIndex }; /// \brief deko3d logo width -constexpr auto LOGO_WIDTH = 500; +constexpr auto LOGO_WIDTH = 504; /// \brief deko3d logo height -constexpr auto LOGO_HEIGHT = 493; +constexpr auto LOGO_HEIGHT = 504; /// \brief icon width constexpr auto ICON_WIDTH = 24; @@ -103,6 +103,15 @@ unsigned s_width = 1920; /// \brief Framebuffer height unsigned s_height = 1080; +/// \brief Gamepad state +PadState s_padState; +/// \brief Touch screen state +HidTouchScreenState s_touchState; +/// \brief Mouse state +HidMouseState s_mouseState; +/// \brief Keyboard state +HidKeyboardState s_kbState; + /// \brief deko3d device dk::UniqueDevice s_device; @@ -206,6 +215,13 @@ void rebuildSwapchain (unsigned const width_, unsigned const height_) /// \brief Initialize deko3d void deko3dInit () { + padConfigureInput (1, HidNpadStyleSet_NpadStandard); + padInitializeDefault (&s_padState); + + hidInitializeTouchScreen (); + hidInitializeMouse (); + hidInitializeKeyboard (); + // create deko3d device s_device = dk::DeviceMaker{}.create (); @@ -263,26 +279,44 @@ void loadTextures () { struct TextureInfo { - TextureInfo (char const *const path_, unsigned const width_, unsigned const height_) - : path (path_), width (width_), height (height_) + TextureInfo (char const *const path_, + DkImageFormat const format_, + unsigned const width_, + unsigned const height_) + : path (path_), format (format_), width (width_), height (height_) { } char const *const path; - unsigned width; - unsigned height; + DkImageFormat const format; + unsigned const width; + unsigned const height; }; - TextureInfo textureInfos[] = {TextureInfo ("romfs:/deko3d.rgba.zst", LOGO_WIDTH, LOGO_HEIGHT), - TextureInfo ("romfs:/battery_icon.rgba.zst", ICON_WIDTH, ICON_HEIGHT), - TextureInfo ("romfs:/charging_icon.rgba.zst", ICON_WIDTH, ICON_HEIGHT), - TextureInfo ("romfs:/eth_none_icon.rgba.zst", ICON_WIDTH, ICON_HEIGHT), - TextureInfo ("romfs:/eth_icon.rgba.zst", ICON_WIDTH, ICON_HEIGHT), - TextureInfo ("romfs:/airplane_icon.rgba.zst", ICON_WIDTH, ICON_HEIGHT), - TextureInfo ("romfs:/wifi_none_icon.rgba.zst", ICON_WIDTH, ICON_HEIGHT), - TextureInfo ("romfs:/wifi1_icon.rgba.zst", ICON_WIDTH, ICON_HEIGHT), - TextureInfo ("romfs:/wifi2_icon.rgba.zst", ICON_WIDTH, ICON_HEIGHT), - TextureInfo ("romfs:/wifi3_icon.rgba.zst", ICON_WIDTH, ICON_HEIGHT)}; + TextureInfo textureInfos[] = { + // clang-format off + TextureInfo ( + "romfs:/deko3d.12x12.astc.zst", DkImageFormat_RGBA_ASTC_12x12, LOGO_WIDTH, LOGO_HEIGHT), + TextureInfo ( + "romfs:/battery_icon.rgba.zst", DkImageFormat_RGBA8_Unorm, ICON_WIDTH, ICON_HEIGHT), + TextureInfo ( + "romfs:/charging_icon.rgba.zst", DkImageFormat_RGBA8_Unorm, ICON_WIDTH, ICON_HEIGHT), + TextureInfo ( + "romfs:/eth_none_icon.rgba.zst", DkImageFormat_RGBA8_Unorm, ICON_WIDTH, ICON_HEIGHT), + TextureInfo ( + "romfs:/eth_icon.rgba.zst", DkImageFormat_RGBA8_Unorm, ICON_WIDTH, ICON_HEIGHT), + TextureInfo ( + "romfs:/airplane_icon.rgba.zst", DkImageFormat_RGBA8_Unorm, ICON_WIDTH, ICON_HEIGHT), + TextureInfo ( + "romfs:/wifi_none_icon.rgba.zst", DkImageFormat_RGBA8_Unorm, ICON_WIDTH, ICON_HEIGHT), + TextureInfo ( + "romfs:/wifi1_icon.rgba.zst", DkImageFormat_RGBA8_Unorm, ICON_WIDTH, ICON_HEIGHT), + TextureInfo ( + "romfs:/wifi2_icon.rgba.zst", DkImageFormat_RGBA8_Unorm, ICON_WIDTH, ICON_HEIGHT), + TextureInfo ( + "romfs:/wifi3_icon.rgba.zst", DkImageFormat_RGBA8_Unorm, ICON_WIDTH, ICON_HEIGHT) + // clang-format on + }; // create memblock for transfer (large enough for the largest source file) dk::UniqueMemBlock memBlock = @@ -349,7 +383,7 @@ void loadTextures () dk::ImageLayout layout; dk::ImageLayoutMaker{s_device} .setFlags (0) - .setFormat (DkImageFormat_RGBA8_Unorm) + .setFormat (textureInfo.format) .setDimensions (textureInfo.width, textureInfo.height) .initialize (layout); @@ -585,23 +619,27 @@ bool platform::loop () if (!appletMainLoop ()) return false; - hidScanInput (); + padUpdate (&s_padState); - auto const keysDown = hidKeysDown (CONTROLLER_P1_AUTO); + auto const keys = padGetButtons (&s_padState); // check if the user wants to exit - if (keysDown & KEY_PLUS) + if (keys & HidNpadButton_Plus) return false; // check if the user wants to toggle the backlight - if (keysDown & KEY_MINUS) + if (keys & HidNpadButton_Minus) { s_backlight = !s_backlight; appletSetLcdBacklightOffEnabled (!s_backlight); } #ifndef CLASSIC - imgui::nx::newFrame (); + auto const touchState = hidGetTouchScreenStates (&s_touchState, 1) ? &s_touchState : nullptr; + auto const mouseState = hidGetMouseStates (&s_mouseState, 1) ? &s_mouseState : nullptr; + auto const kbState = hidGetKeyboardStates (&s_kbState, 1) ? &s_kbState : nullptr; + + imgui::nx::newFrame (&s_padState, touchState, mouseState, kbState); ImGui::NewFrame (); auto const &io = ImGui::GetIO (); diff --git a/switch/gfx/deko3d.12x12.astc b/switch/gfx/deko3d.12x12.astc new file mode 100644 index 0000000..26ff676 Binary files /dev/null and b/switch/gfx/deko3d.12x12.astc differ diff --git a/switch/gfx/deko3d.png b/switch/gfx/deko3d.png deleted file mode 100644 index fbf1adf..0000000 Binary files a/switch/gfx/deko3d.png and /dev/null differ