From e3d9319dd50cdd66d7c625c16d7f5f841e000711 Mon Sep 17 00:00:00 2001 From: GaryOderNichts <12049776+GaryOderNichts@users.noreply.github.com> Date: Wed, 20 Jul 2022 02:28:45 +0200 Subject: [PATCH 1/8] wiiu: Initial gx2 backend --- .gitignore | 6 + backends/gx2/imgui_impl_gx2.cpp | 333 ++++++++++++++++++++++++++ backends/gx2/imgui_impl_gx2.h | 15 ++ backends/gx2/shaders/build-shaders.sh | 8 + backends/gx2/shaders/shader.h | 150 ++++++++++++ backends/gx2/shaders/shader.psh | 25 ++ backends/gx2/shaders/shader.vsh | 51 ++++ examples/example_gx2/Makefile | 135 +++++++++++ examples/example_gx2/main.cpp | 110 +++++++++ imgui_draw.cpp | 10 + 10 files changed, 843 insertions(+) create mode 100644 backends/gx2/imgui_impl_gx2.cpp create mode 100644 backends/gx2/imgui_impl_gx2.h create mode 100755 backends/gx2/shaders/build-shaders.sh create mode 100644 backends/gx2/shaders/shader.h create mode 100644 backends/gx2/shaders/shader.psh create mode 100644 backends/gx2/shaders/shader.vsh create mode 100644 examples/example_gx2/Makefile create mode 100644 examples/example_gx2/main.cpp diff --git a/.gitignore b/.gitignore index 86bed609c54e..caa5a459094e 100644 --- a/.gitignore +++ b/.gitignore @@ -51,3 +51,9 @@ examples/example_glut_opengl2/example_glut_opengl2 examples/example_null/example_null examples/example_sdl_opengl2/example_sdl_opengl2 examples/example_sdl_opengl3/example_sdl_opengl3 + +## Wii U things +*.rpx +*.elf +*.gsh +build/ diff --git a/backends/gx2/imgui_impl_gx2.cpp b/backends/gx2/imgui_impl_gx2.cpp new file mode 100644 index 000000000000..3ea67abd6514 --- /dev/null +++ b/backends/gx2/imgui_impl_gx2.cpp @@ -0,0 +1,333 @@ +// dear imgui: Renderer Backend for the Nintendo Wii U using GX2 +#include "imgui.h" +#include "imgui_impl_gx2.h" +#include +#include // intptr_t +#include // memalign + +// GX2 includes +#include +#include +#include +#include +#include +#include + +// Include shader data +#include "shaders/shader.h" + +// GX2 Texture / contains a texture and sampler +struct ImGui_ImplGX2_Texture +{ + GX2Texture texture; + GX2Sampler sampler; + + ImGui_ImplGX2_Texture() { memset(this, 0, sizeof(*this)); } +}; + +// GX2 Data +struct ImGui_ImplGX2_Data +{ + uint32_t VertexBufferSize; + void* VertexBuffer; + uint32_t IndexBufferSize; + void* IndexBuffer; + + ImGui_ImplGX2_Texture* FontTexture; + + WHBGfxShaderGroup* ShaderGroup; + + ImGui_ImplGX2_Data() { memset(this, 0, sizeof(*this)); } +}; + +// Backend data stored in io.BackendRendererUserData to allow support for multiple Dear ImGui contexts +// It is STRONGLY preferred that you use docking branch with multi-viewports (== single Dear ImGui context + multiple windows) instead of multiple Dear ImGui contexts. +static ImGui_ImplGX2_Data* ImGui_ImplGX2_GetBackendData() +{ + return ImGui::GetCurrentContext() ? (ImGui_ImplGX2_Data*)ImGui::GetIO().BackendRendererUserData : NULL; +} + +// Functions +bool ImGui_ImplGX2_Init() +{ + ImGuiIO& io = ImGui::GetIO(); + IM_ASSERT(io.BackendRendererUserData == NULL && "Already initialized a renderer backend!"); + + ImGui_ImplGX2_Data* bd = IM_NEW(ImGui_ImplGX2_Data)(); + io.BackendRendererUserData = (void*)bd; + io.BackendRendererName = "imgui_impl_gx2"; + + io.BackendFlags |= ImGuiBackendFlags_RendererHasVtxOffset; // We can honor the ImDrawCmd::VtxOffset field, allowing for large meshes. + + return true; +} + +void ImGui_ImplGX2_Shutdown() +{ + ImGui_ImplGX2_Data* bd = ImGui_ImplGX2_GetBackendData(); + IM_ASSERT(bd != NULL && "No renderer backend to shutdown, or already shutdown?"); + ImGuiIO& io = ImGui::GetIO(); + + ImGui_ImplGX2_DestroyDeviceObjects(); + io.BackendRendererName = NULL; + io.BackendRendererUserData = NULL; + IM_DELETE(bd); +} + +void ImGui_ImplGX2_NewFrame() +{ + ImGui_ImplGX2_Data* bd = ImGui_ImplGX2_GetBackendData(); + IM_ASSERT(bd != NULL && "Did you call ImGui_ImplOpenGL3_Init()?"); + + if (!bd->ShaderGroup) + ImGui_ImplGX2_CreateDeviceObjects(); +} + +static void ImGui_ImplGX2_SetupRenderState(ImDrawData* draw_data, int fb_width, int fb_height) +{ + ImGui_ImplGX2_Data* bd = ImGui_ImplGX2_GetBackendData(); + + // Setup render state: alpha-blending enabled, no face culling, no depth testing + GX2SetColorControl(GX2_LOGIC_OP_COPY, 0xFF, FALSE, TRUE); + GX2SetBlendControl(GX2_RENDER_TARGET_0, + GX2_BLEND_MODE_SRC_ALPHA, + GX2_BLEND_MODE_INV_SRC_ALPHA, + GX2_BLEND_COMBINE_MODE_ADD, + TRUE, + GX2_BLEND_MODE_ONE, + GX2_BLEND_MODE_INV_SRC_ALPHA, + GX2_BLEND_COMBINE_MODE_ADD); + GX2SetCullOnlyControl(GX2_FRONT_FACE_CCW, FALSE, FALSE); + GX2SetDepthOnlyControl(FALSE, FALSE, GX2_COMPARE_FUNC_NEVER); + + // Setup viewport, orthographic projection matrix + // Our visible imgui space lies from draw_data->DisplayPos (top left) to draw_data->DisplayPos+data_data->DisplaySize (bottom right). DisplayPos is (0,0) for single viewport apps. + GX2SetViewport(0, 0, (float)fb_width, (float)fb_height, 0.0f, 1.0f); + + GX2SetFetchShader(&bd->ShaderGroup->fetchShader); + GX2SetVertexShader(bd->ShaderGroup->vertexShader); + GX2SetPixelShader(bd->ShaderGroup->pixelShader); + + float L = draw_data->DisplayPos.x; + float R = draw_data->DisplayPos.x + draw_data->DisplaySize.x; + float T = draw_data->DisplayPos.y; + float B = draw_data->DisplayPos.y + draw_data->DisplaySize.y; + const float ortho_projection[4][4] = + { + { 2.0f/(R-L), 0.0f, 0.0f, 0.0f }, + { 0.0f, 2.0f/(T-B), 0.0f, 0.0f }, + { 0.0f, 0.0f, -1.0f, 0.0f }, + { (R+L)/(L-R), (T+B)/(B-T), 0.0f, 1.0f }, + }; + + GX2SetVertexUniformReg(0, sizeof(ortho_projection) / sizeof(float), &ortho_projection[0][0]); +} + +void ImGui_ImplGX2_RenderDrawData(ImDrawData* draw_data) +{ + // Avoid rendering when minimized, scale coordinates for retina displays (screen coordinates != framebuffer coordinates) + int fb_width = (int)(draw_data->DisplaySize.x * draw_data->FramebufferScale.x); + int fb_height = (int)(draw_data->DisplaySize.y * draw_data->FramebufferScale.y); + if (fb_width <= 0 || fb_height <= 0) + return; + + ImGui_ImplGX2_Data* bd = ImGui_ImplGX2_GetBackendData(); + + ImGui_ImplGX2_SetupRenderState(draw_data, fb_width, fb_height); + + // Will project scissor/clipping rectangles into framebuffer space + ImVec2 clip_off = draw_data->DisplayPos; // (0,0) unless using multi-viewports + ImVec2 clip_scale = draw_data->FramebufferScale; // (1,1) unless using retina display which are often (2,2) + + // Create continuous vertex/index buffers + uint32_t vtx_buffer_size = (uint32_t)draw_data->TotalVtxCount * (int)sizeof(ImDrawVert); + uint32_t idx_buffer_size = (uint32_t)draw_data->TotalIdxCount * (int)sizeof(ImDrawIdx); + + // Grow buffers if needed + if (bd->VertexBufferSize < vtx_buffer_size) + { + bd->VertexBufferSize = vtx_buffer_size; + free(bd->VertexBuffer); + bd->VertexBuffer = memalign(GX2_VERTEX_BUFFER_ALIGNMENT, vtx_buffer_size); + } + if (bd->IndexBufferSize < idx_buffer_size) + { + bd->IndexBufferSize = idx_buffer_size; + free(bd->IndexBuffer); + bd->IndexBuffer = memalign(GX2_INDEX_BUFFER_ALIGNMENT, idx_buffer_size); + } + + // Copy data into continuous buffers + uint8_t* vtx_dst = (uint8_t*)bd->VertexBuffer; + uint8_t* idx_dst = (uint8_t*)bd->IndexBuffer; + for (int n = 0; n < draw_data->CmdListsCount; n++) + { + const ImDrawList* cmd_list = draw_data->CmdLists[n]; + + memcpy(vtx_dst, cmd_list->VtxBuffer.Data, cmd_list->VtxBuffer.Size * sizeof(ImDrawVert)); + vtx_dst += cmd_list->VtxBuffer.Size * sizeof(ImDrawVert); + + memcpy(idx_dst, cmd_list->IdxBuffer.Data, cmd_list->IdxBuffer.Size * sizeof(ImDrawIdx)); + idx_dst += cmd_list->IdxBuffer.Size * sizeof(ImDrawIdx); + } + + // Flush memory + GX2Invalidate(GX2_INVALIDATE_MODE_CPU_ATTRIBUTE_BUFFER, bd->VertexBuffer, vtx_buffer_size); + GX2Invalidate(GX2_INVALIDATE_MODE_CPU, bd->IndexBuffer, idx_buffer_size); + + GX2SetAttribBuffer(0, vtx_buffer_size, sizeof(ImDrawVert), bd->VertexBuffer); + + // Render command lists + // (Because we merged all buffers into a single one, we maintain our own offset into them) + int global_vtx_offset = 0; + int global_idx_offset = 0; + for (int n = 0; n < draw_data->CmdListsCount; n++) + { + const ImDrawList* cmd_list = draw_data->CmdLists[n]; + + for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.Size; cmd_i++) + { + const ImDrawCmd* pcmd = &cmd_list->CmdBuffer[cmd_i]; + if (pcmd->UserCallback != NULL) + { + // User callback, registered via ImDrawList::AddCallback() + // (ImDrawCallback_ResetRenderState is a special callback value used by the user to request the renderer to reset render state.) + if (pcmd->UserCallback == ImDrawCallback_ResetRenderState) + ImGui_ImplGX2_SetupRenderState(draw_data, fb_width, fb_height); + else + pcmd->UserCallback(cmd_list, pcmd); + } + else + { + // Project scissor/clipping rectangles into framebuffer space + ImVec2 clip_min((pcmd->ClipRect.x - clip_off.x) * clip_scale.x, (pcmd->ClipRect.y - clip_off.y) * clip_scale.y); + ImVec2 clip_max((pcmd->ClipRect.z - clip_off.x) * clip_scale.x, (pcmd->ClipRect.w - clip_off.y) * clip_scale.y); + if (clip_max.x <= clip_min.x || clip_max.y <= clip_min.y) + continue; + + // Apply scissor/clipping rectangle + GX2SetScissor((uint32_t)clip_min.x, (uint32_t)clip_min.y, (uint32_t)(clip_max.x - clip_min.x), (uint32_t)(clip_max.y - clip_min.y)); + + // Bind texture, Draw + ImGui_ImplGX2_Texture* tex = (ImGui_ImplGX2_Texture*) pcmd->GetTexID(); + + GX2SetPixelTexture(&tex->texture, 0); + GX2SetPixelSampler(&tex->sampler, 0); + + GX2DrawIndexedEx(GX2_PRIMITIVE_MODE_TRIANGLES, pcmd->ElemCount, + sizeof(ImDrawIdx) == 2 ? GX2_INDEX_TYPE_U16 : GX2_INDEX_TYPE_U32, + (uint8_t*) bd->IndexBuffer + (pcmd->IdxOffset + global_idx_offset) * sizeof(ImDrawIdx), + global_vtx_offset + pcmd->VtxOffset, 1); + } + } + global_idx_offset += cmd_list->IdxBuffer.Size; + global_vtx_offset += cmd_list->VtxBuffer.Size; + } +} + +bool ImGui_ImplGX2_CreateFontsTexture() +{ + ImGuiIO& io = ImGui::GetIO(); + ImGui_ImplGX2_Data* bd = ImGui_ImplGX2_GetBackendData(); + + if (bd->FontTexture) + { + return false; + } + + // Build texture atlas + unsigned char* src_pixels; + int width, height; + io.Fonts->GetTexDataAsRGBA32(&src_pixels, &width, &height); // Load as RGBA 32-bit (75% of the memory is wasted, but default font is so small) because it is more likely to be compatible with user's existing shaders. + + bd->FontTexture = IM_NEW(ImGui_ImplGX2_Texture)(); + + GX2Texture* tex = &bd->FontTexture->texture; + memset(tex, 0, sizeof(GX2Texture)); + + tex->surface.dim = GX2_SURFACE_DIM_TEXTURE_2D; + tex->surface.use = GX2_SURFACE_USE_TEXTURE; + tex->surface.width = width; + tex->surface.height = height; + tex->surface.depth = 1; + tex->surface.mipLevels = 1; + tex->surface.format = GX2_SURFACE_FORMAT_UNORM_R8_G8_B8_A8; + tex->surface.aa = GX2_AA_MODE1X; + tex->surface.tileMode = GX2_TILE_MODE_LINEAR_ALIGNED; + tex->viewNumSlices = 1; + tex->viewNumMips = 1; + // swapped for endianness + tex->compMap = GX2_COMP_MAP(GX2_SQ_SEL_A, GX2_SQ_SEL_B, GX2_SQ_SEL_G, GX2_SQ_SEL_R); + + GX2RCreateSurface(&tex->surface, GX2R_RESOURCE_BIND_TEXTURE | GX2R_RESOURCE_USAGE_CPU_WRITE | GX2R_RESOURCE_USAGE_GPU_READ); + GX2InitTextureRegs(tex); + + unsigned char* dst_pixels = (unsigned char*) GX2RLockSurfaceEx(&tex->surface, 0, GX2R_RESOURCE_BIND_NONE); + + for (int y = 0; y < height; y++) { + memcpy(dst_pixels + (y * tex->surface.pitch * 4), src_pixels + (y * width * 4), width * 4); + } + + GX2RUnlockSurfaceEx(&tex->surface, 0, GX2R_RESOURCE_BIND_NONE); + + GX2InitSampler(&bd->FontTexture->sampler, GX2_TEX_CLAMP_MODE_CLAMP, GX2_TEX_XY_FILTER_MODE_LINEAR); + + // Store our identifier + io.Fonts->SetTexID((ImTextureID) bd->FontTexture); + + return true; +} + +void ImGui_ImplGX2_DestroyFontsTexture() +{ + ImGuiIO& io = ImGui::GetIO(); + ImGui_ImplGX2_Data* bd = ImGui_ImplGX2_GetBackendData(); + if (bd->FontTexture) + { + GX2RDestroySurfaceEx(&bd->FontTexture->texture.surface, GX2R_RESOURCE_BIND_NONE); + io.Fonts->SetTexID(0); + IM_DELETE(bd->FontTexture); + bd->FontTexture = nullptr; + } +} + +bool ImGui_ImplGX2_CreateDeviceObjects() +{ + ImGui_ImplGX2_Data* bd = ImGui_ImplGX2_GetBackendData(); + bd->ShaderGroup = IM_NEW(WHBGfxShaderGroup)(); + + if (!WHBGfxLoadGFDShaderGroup(bd->ShaderGroup, 0, shader_gsh)) { + IM_DELETE(bd->ShaderGroup); + return false; + } + + WHBGfxInitShaderAttribute(bd->ShaderGroup, "Position", 0, 0, GX2_ATTRIB_FORMAT_FLOAT_32_32); + WHBGfxInitShaderAttribute(bd->ShaderGroup, "UV", 0, 8, GX2_ATTRIB_FORMAT_FLOAT_32_32); + WHBGfxInitShaderAttribute(bd->ShaderGroup, "Color", 0, 16, GX2_ATTRIB_TYPE_8_8_8_8); + + if (!WHBGfxInitFetchShader(bd->ShaderGroup)) { + IM_DELETE(bd->ShaderGroup); + return false; + } + + ImGui_ImplGX2_CreateFontsTexture(); + + return true; +} + +void ImGui_ImplGX2_DestroyDeviceObjects() +{ + ImGui_ImplGX2_Data* bd = ImGui_ImplGX2_GetBackendData(); + + free(bd->VertexBuffer); + bd->VertexBuffer = nullptr; + + free(bd->IndexBuffer); + bd->IndexBuffer = nullptr; + + WHBGfxFreeShaderGroup(bd->ShaderGroup); + IM_DELETE(bd->ShaderGroup); + bd->ShaderGroup = nullptr; + + ImGui_ImplGX2_DestroyFontsTexture(); +} diff --git a/backends/gx2/imgui_impl_gx2.h b/backends/gx2/imgui_impl_gx2.h new file mode 100644 index 000000000000..9cce97b10525 --- /dev/null +++ b/backends/gx2/imgui_impl_gx2.h @@ -0,0 +1,15 @@ +// dear imgui: Renderer Backend for the Nintendo Wii U using GX2 +#pragma once +#include "imgui.h" // IMGUI_IMPL_API + +// Backend API +IMGUI_IMPL_API bool ImGui_ImplGX2_Init(); +IMGUI_IMPL_API void ImGui_ImplGX2_Shutdown(); +IMGUI_IMPL_API void ImGui_ImplGX2_NewFrame(); +IMGUI_IMPL_API void ImGui_ImplGX2_RenderDrawData(ImDrawData* draw_data); + +// (Optional) Called by Init/NewFrame/Shutdown +IMGUI_IMPL_API bool ImGui_ImplGX2_CreateFontsTexture(); +IMGUI_IMPL_API void ImGui_ImplGX2_DestroyFontsTexture(); +IMGUI_IMPL_API bool ImGui_ImplGX2_CreateDeviceObjects(); +IMGUI_IMPL_API void ImGui_ImplGX2_DestroyDeviceObjects(); diff --git a/backends/gx2/shaders/build-shaders.sh b/backends/gx2/shaders/build-shaders.sh new file mode 100755 index 000000000000..13262ad0c26e --- /dev/null +++ b/backends/gx2/shaders/build-shaders.sh @@ -0,0 +1,8 @@ +#!/bin/bash + +# to build shaders you need to place a copy of latte-assembler into the current directory +# latte-assembler is part of decaf-emu + +# shader +./latte-assembler assemble --vsh=shader.vsh --psh=shader.psh shader.gsh +xxd -i shader.gsh > shader.h diff --git a/backends/gx2/shaders/shader.h b/backends/gx2/shaders/shader.h new file mode 100644 index 000000000000..ee6e6a8f7f2e --- /dev/null +++ b/backends/gx2/shaders/shader.h @@ -0,0 +1,150 @@ +unsigned char shader_gsh[] = { + 0x47, 0x66, 0x78, 0x32, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x07, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x4c, 0x4b, 0x7b, + 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x01, 0xd8, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x04, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0xff, 0xff, 0x01, 0x00, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x03, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, + 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, + 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, + 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, + 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, + 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, + 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, + 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, + 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, + 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, + 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x01, 0x90, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xd0, 0x60, 0x01, 0x34, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x03, 0xd0, 0x60, 0x01, 0x48, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xca, 0x70, 0x01, 0x78, 0x00, 0x00, 0x00, 0x1d, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xca, 0x70, 0x01, 0x80, + 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xca, 0x70, 0x01, 0x8c, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x01, 0xca, 0x70, 0x01, 0x90, 0x00, 0x00, 0x00, 0x0b, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x50, 0x72, 0x6f, 0x6a, + 0x4d, 0x74, 0x78, 0x00, 0x50, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, + 0x00, 0x00, 0x00, 0x00, 0x55, 0x56, 0x00, 0x00, 0x43, 0x6f, 0x6c, 0x6f, + 0x72, 0x00, 0x00, 0x00, 0xd0, 0x60, 0x00, 0xe8, 0xd0, 0x60, 0x01, 0x08, + 0xca, 0x70, 0x01, 0x34, 0xca, 0x70, 0x01, 0x48, 0xca, 0x70, 0x01, 0x58, + 0xca, 0x70, 0x01, 0x68, 0x7d, 0x42, 0x4c, 0x4b, 0x00, 0x00, 0x00, 0x28, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x98, 0xd0, 0x60, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x20, 0xd0, 0x60, 0x01, 0x78, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x06, 0xd0, 0x60, 0x01, 0x98, 0x42, 0x4c, 0x4b, 0x7b, + 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x01, 0x90, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x09, + 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44, 0xa0, 0x3c, 0xa0, 0x00, 0x00, + 0x88, 0x06, 0x00, 0x94, 0x00, 0x40, 0x01, 0x00, 0x08, 0x09, 0x80, 0x13, + 0x01, 0xc0, 0x01, 0x00, 0x88, 0x06, 0x20, 0x14, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfd, 0x60, 0x20, 0x00, + 0x80, 0x00, 0x00, 0x00, 0xfd, 0x64, 0xa0, 0x00, 0x80, 0x00, 0x00, 0x20, + 0xfd, 0x68, 0x20, 0x01, 0x80, 0x00, 0x00, 0x40, 0xfd, 0x6c, 0xa0, 0x81, + 0x80, 0x00, 0x00, 0x60, 0x00, 0x00, 0x80, 0x3f, 0x00, 0x00, 0x80, 0x3f, + 0x00, 0x00, 0x80, 0x3f, 0x00, 0x00, 0x80, 0x3f, 0xf8, 0x40, 0x20, 0x00, + 0xfe, 0x00, 0xe2, 0x0f, 0xf8, 0x44, 0xa0, 0x00, 0xfe, 0x04, 0xe2, 0x2f, + 0xf8, 0x48, 0x20, 0x01, 0xfe, 0x08, 0xe2, 0x4f, 0xf8, 0x4c, 0xa0, 0x81, + 0xfe, 0x0c, 0xe2, 0x6f, 0x01, 0x24, 0x20, 0x00, 0xfe, 0x00, 0xe2, 0x0f, + 0x01, 0x24, 0xa0, 0x00, 0xfe, 0x04, 0xe2, 0x2f, 0x01, 0x24, 0x20, 0x01, + 0xfe, 0x08, 0xe2, 0x4f, 0x01, 0x24, 0xa0, 0x81, 0xfe, 0x0c, 0xe2, 0x6f, + 0x01, 0x00, 0x20, 0x00, 0xfe, 0x00, 0x22, 0x00, 0x01, 0x00, 0xa0, 0x00, + 0xfe, 0x04, 0x22, 0x20, 0x01, 0x00, 0x20, 0x01, 0xfe, 0x08, 0x22, 0x40, + 0x01, 0x00, 0xa0, 0x81, 0xfe, 0x0c, 0x22, 0x60, 0x42, 0x4c, 0x4b, 0x7b, + 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x01, 0x2c, 0x00, 0x00, 0x00, 0x02, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, + 0x14, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, + 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x01, 0x90, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, + 0xd0, 0x60, 0x00, 0xe8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xca, 0x70, 0x00, 0xf4, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x54, 0x65, 0x78, 0x74, + 0x75, 0x72, 0x65, 0x00, 0xd0, 0x60, 0x00, 0xd4, 0xca, 0x70, 0x00, 0xe8, + 0x7d, 0x42, 0x4c, 0x4b, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xfc, 0xd0, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, + 0xd0, 0x60, 0x00, 0xf4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, + 0xd0, 0x60, 0x00, 0xfc, 0x42, 0x4c, 0x4b, 0x7b, 0x00, 0x00, 0x00, 0x20, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, + 0x00, 0x00, 0x01, 0x90, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, + 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x80, 0x20, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0c, 0xa0, 0x00, 0x00, 0x00, 0x00, 0x88, 0x06, 0x20, 0x94, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x80, 0x01, 0x90, 0x00, 0x00, 0x00, + 0x00, 0x24, 0x00, 0x01, 0x90, 0x00, 0x00, 0x20, 0x00, 0x28, 0x80, 0x00, + 0x90, 0x00, 0x00, 0x40, 0x00, 0x2c, 0x00, 0x80, 0x90, 0x00, 0x00, 0x60, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x10, 0x00, 0x00, 0x00, 0x00, 0x10, 0x0d, 0xf0, 0x00, 0x00, 0x80, 0x10, + 0x00, 0x00, 0x00, 0x00, 0x42, 0x4c, 0x4b, 0x7b, 0x00, 0x00, 0x00, 0x20, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00 +}; +unsigned int shader_gsh_len = 1764; diff --git a/backends/gx2/shaders/shader.psh b/backends/gx2/shaders/shader.psh new file mode 100644 index 000000000000..20363ac09d28 --- /dev/null +++ b/backends/gx2/shaders/shader.psh @@ -0,0 +1,25 @@ +; $MODE = "UniformRegister" + +; $NUM_SPI_PS_INPUT_CNTL = 2 +; Frag_UV R0 +; $SPI_PS_INPUT_CNTL[0].SEMANTIC = 0 +; $SPI_PS_INPUT_CNTL[0].DEFAULT_VAL = 1 +; Frag_Color R1 +; $SPI_PS_INPUT_CNTL[1].SEMANTIC = 1 +; $SPI_PS_INPUT_CNTL[1].DEFAULT_VAL = 1 + +; $SAMPLER_VARS[0].name = "Texture" +; $SAMPLER_VARS[0].type = "SAMPLER2D" +; $SAMPLER_VARS[0].location = 0 + +; Note: R1 is swapped for endianness + +00 TEX: ADDR(48) CNT(1) VALID_PIX + 0 SAMPLE R0, R0.xy0x, t0, s0 +01 ALU: ADDR(32) CNT(4) + 1 x: MUL R0.x, R0.x, R1.w + y: MUL R0.y, R0.y, R1.z + z: MUL R0.z, R0.z, R1.y + w: MUL R0.w, R0.w, R1.x +02 EXP_DONE: PIX0, R0 +END_OF_PROGRAM diff --git a/backends/gx2/shaders/shader.vsh b/backends/gx2/shaders/shader.vsh new file mode 100644 index 000000000000..8d63c65f6471 --- /dev/null +++ b/backends/gx2/shaders/shader.vsh @@ -0,0 +1,51 @@ +; $MODE = "UniformRegister" + +; $SPI_VS_OUT_CONFIG.VS_EXPORT_COUNT = 1 +; $NUM_SPI_VS_OUT_ID = 1 +; uv +; $SPI_VS_OUT_ID[0].SEMANTIC_0 = 0 +; color +; $SPI_VS_OUT_ID[0].SEMANTIC_1 = 1 + +; C0 +; $UNIFORM_VARS[0].name = "ProjMtx" +; $UNIFORM_VARS[0].type = "mat4" +; $UNIFORM_VARS[0].count = 1 +; $UNIFORM_VARS[0].block = -1 +; $UNIFORM_VARS[0].offset = 0 + +; R1 +; $ATTRIB_VARS[0].name = "Position" +; $ATTRIB_VARS[0].type = "vec2" +; $ATTRIB_VARS[0].location = 0 +; R2 +; $ATTRIB_VARS[1].name = "UV" +; $ATTRIB_VARS[1].type = "vec2" +; $ATTRIB_VARS[1].location = 1 +; R3 +; $ATTRIB_VARS[2].name = "Color" +; $ATTRIB_VARS[2].type = "vec4" +; $ATTRIB_VARS[2].location = 2 + +00 CALL_FS NO_BARRIER +01 ALU: ADDR(32) CNT(18) + 0 x: MUL ____, 1.0f, C3.x + y: MUL ____, 1.0f, C3.y + z: MUL ____, 1.0f, C3.z + w: MUL ____, 1.0f, C3.w + 1 x: MULADD R127.x, 0.0f, C2.x, PV0.x + y: MULADD R127.y, 0.0f, C2.y, PV0.y + z: MULADD R127.z, 0.0f, C2.z, PV0.z + w: MULADD R127.w, 0.0f, C2.w, PV0.w + 2 x: MULADD R127.x, R1.y, C1.x, PV0.x + y: MULADD R127.y, R1.y, C1.y, PV0.y + z: MULADD R127.z, R1.y, C1.z, PV0.z + w: MULADD R127.w, R1.y, C1.w, PV0.w + 3 x: MULADD R1.x, R1.x, C0.x, PV0.x + y: MULADD R1.y, R1.x, C0.y, PV0.y + z: MULADD R1.z, R1.x, C0.z, PV0.z + w: MULADD R1.w, R1.x, C0.w, PV0.w +02 EXP_DONE: POS0, R1 +03 EXP: PARAM0, R2.xy00 NO_BARRIER +04 EXP_DONE: PARAM1, R3 NO_BARRIER +END_OF_PROGRAM diff --git a/examples/example_gx2/Makefile b/examples/example_gx2/Makefile new file mode 100644 index 000000000000..62f2b051844a --- /dev/null +++ b/examples/example_gx2/Makefile @@ -0,0 +1,135 @@ +#------------------------------------------------------------------------------- +.SUFFIXES: +#------------------------------------------------------------------------------- + +ifeq ($(strip $(DEVKITPRO)),) +$(error "Please set DEVKITPRO in your environment. export DEVKITPRO=/devkitpro") +endif + +TOPDIR ?= $(CURDIR) + +include $(DEVKITPRO)/wut/share/wut_rules + +#------------------------------------------------------------------------------- +# TARGET is the name of the output +# BUILD is the directory where object files & intermediate files will be placed +# SOURCES is a list of directories containing source code +# DATA is a list of directories containing data files +# INCLUDES is a list of directories containing header files +#------------------------------------------------------------------------------- +TARGET := $(notdir $(CURDIR)) +BUILD := build +SOURCES := . ../../ ../../backends/gx2 +DATA := data +INCLUDES := . ../../ ../../backends/gx2 + +#------------------------------------------------------------------------------- +# options for code generation +#------------------------------------------------------------------------------- +CFLAGS := -g -Wall -O2 -ffunction-sections \ + $(MACHDEP) + +CFLAGS += $(INCLUDE) -D__WIIU__ -D__WUT__ + +CXXFLAGS := $(CFLAGS) + +ASFLAGS := -g $(ARCH) +LDFLAGS = -g $(ARCH) $(RPXSPECS) -Wl,-Map,$(notdir $*.map) + +LIBS := -lwut + +#------------------------------------------------------------------------------- +# list of directories containing libraries, this must be the top level +# containing include and lib +#------------------------------------------------------------------------------- +LIBDIRS := $(PORTLIBS) $(WUT_ROOT) + + +#------------------------------------------------------------------------------- +# no real need to edit anything past this point unless you need to add additional +# rules for different file extensions +#------------------------------------------------------------------------------- +ifneq ($(BUILD),$(notdir $(CURDIR))) +#------------------------------------------------------------------------------- + +export OUTPUT := $(CURDIR)/$(TARGET) +export TOPDIR := $(CURDIR) + +export VPATH := $(foreach dir,$(SOURCES),$(CURDIR)/$(dir)) \ + $(foreach dir,$(DATA),$(CURDIR)/$(dir)) + +export DEPSDIR := $(CURDIR)/$(BUILD) + +CFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.c))) +CPPFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.cpp))) +SFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.s))) +BINFILES := $(foreach dir,$(DATA),$(notdir $(wildcard $(dir)/*.*))) + +#------------------------------------------------------------------------------- +# use CXX for linking C++ projects, CC for standard C +#------------------------------------------------------------------------------- +ifeq ($(strip $(CPPFILES)),) +#------------------------------------------------------------------------------- + export LD := $(CC) +#------------------------------------------------------------------------------- +else +#------------------------------------------------------------------------------- + export LD := $(CXX) +#------------------------------------------------------------------------------- +endif +#------------------------------------------------------------------------------- + +export OFILES_BIN := $(addsuffix .o,$(BINFILES)) +export OFILES_SRC := $(CPPFILES:.cpp=.o) $(CFILES:.c=.o) $(SFILES:.s=.o) +export OFILES := $(OFILES_BIN) $(OFILES_SRC) +export HFILES_BIN := $(addsuffix .h,$(subst .,_,$(BINFILES))) + +export INCLUDE := $(foreach dir,$(INCLUDES),-I$(CURDIR)/$(dir)) \ + $(foreach dir,$(LIBDIRS),-I$(dir)/include) \ + -I$(CURDIR)/$(BUILD) + +export LIBPATHS := $(foreach dir,$(LIBDIRS),-L$(dir)/lib) + +.PHONY: $(BUILD) clean all + +#------------------------------------------------------------------------------- +all: $(BUILD) + +$(BUILD): + @[ -d $@ ] || mkdir -p $@ + @$(MAKE) --no-print-directory -C $(BUILD) -f $(CURDIR)/Makefile + +#------------------------------------------------------------------------------- +clean: + @echo clean ... + @rm -fr $(BUILD) $(TARGET).rpx $(TARGET).elf + +#------------------------------------------------------------------------------- +else +.PHONY: all + +DEPENDS := $(OFILES:.o=.d) + +#------------------------------------------------------------------------------- +# main targets +#------------------------------------------------------------------------------- +all : $(OUTPUT).rpx + +$(OUTPUT).rpx : $(OUTPUT).elf +$(OUTPUT).elf : $(OFILES) + +$(OFILES_SRC) : $(HFILES_BIN) + +#------------------------------------------------------------------------------- +# you need a rule like this for each extension you use as binary data +#------------------------------------------------------------------------------- +%.bin.o %_bin.h : %.bin +#------------------------------------------------------------------------------- + @echo $(notdir $<) + @$(bin2o) + +-include $(DEPENDS) + +#------------------------------------------------------------------------------- +endif +#------------------------------------------------------------------------------- diff --git a/examples/example_gx2/main.cpp b/examples/example_gx2/main.cpp new file mode 100644 index 000000000000..a360ff9daf7f --- /dev/null +++ b/examples/example_gx2/main.cpp @@ -0,0 +1,110 @@ +// Dear ImGui: standalone example application for the Wii U +#include "imgui.h" +#include "imgui_impl_gx2.h" +#include + +#include +#include +#include +#include + +int main(int, char**) +{ + // Init ProcUI and GX2 + WHBProcInit(); + WHBGfxInit(); + + // Setup Dear ImGui context + IMGUI_CHECKVERSION(); + ImGui::CreateContext(); + ImGuiIO& io = ImGui::GetIO(); (void)io; + + // Setup Dear ImGui style + ImGui::StyleColorsDark(); + //ImGui::StyleColorsClassic(); + + // Setup Renderer backends + ImGui_ImplGX2_Init(); + + // Our state + bool show_demo_window = true; + bool show_another_window = false; + ImVec4 clear_color = ImVec4(0.45f, 0.55f, 0.60f, 1.00f); + + // Main loop + while (WHBProcIsRunning()) + { + // Start a new frame / We'll be using the TV buffer + WHBGfxBeginRender(); + WHBGfxBeginRenderTV(); + + io.DisplaySize.x = (float)WHBGfxGetTVColourBuffer()->surface.width; // set the current display width + io.DisplaySize.y = (float)WHBGfxGetTVColourBuffer()->surface.height; // set the current display height here + + // Start the Dear ImGui frame + ImGui_ImplGX2_NewFrame(); + ImGui::NewFrame(); + + // 1. Show the big demo window (Most of the sample code is in ImGui::ShowDemoWindow()! You can browse its code to learn more about Dear ImGui!). + if (show_demo_window) { + ImGui::ShowDemoWindow(&show_demo_window); + } + + // 2. Show a simple window that we create ourselves. We use a Begin/End pair to created a named window. + { + static float f = 0.0f; + static int counter = 0; + + ImGui::Begin("Hello, world!"); // Create a window called "Hello, world!" and append into it. + + ImGui::Text("This is some useful text."); // Display some text (you can use a format strings too) + ImGui::Checkbox("Demo Window", &show_demo_window); // Edit bools storing our window open/close state + ImGui::Checkbox("Another Window", &show_another_window); + + ImGui::SliderFloat("float", &f, 0.0f, 1.0f); // Edit 1 float using a slider from 0.0f to 1.0f + ImGui::ColorEdit3("clear color", (float*)&clear_color); // Edit 3 floats representing a color + + if (ImGui::Button("Button")) // Buttons return true when clicked (most widgets return true when edited/activated) + counter++; + ImGui::SameLine(); + ImGui::Text("counter = %d", counter); + + ImGui::Text("Application average %.3f ms/frame (%.1f FPS)", 1000.0f / ImGui::GetIO().Framerate, ImGui::GetIO().Framerate); + ImGui::End(); + } + + // 3. Show another simple window. + if (show_another_window) + { + ImGui::Begin("Another Window", &show_another_window); // Pass a pointer to our bool variable (the window will have a closing button that will clear the bool when clicked) + ImGui::Text("Hello from another window!"); + if (ImGui::Button("Close Me")) + show_another_window = false; + ImGui::End(); + } + + // Rendering + ImGui::Render(); + float display_w = (float)WHBGfxGetTVColourBuffer()->surface.width; + float display_h = (float)WHBGfxGetTVColourBuffer()->surface.height; + GX2SetViewport(0, 0, display_w, display_h, 1.0f, 0.0f); + WHBGfxClearColor(clear_color.x * clear_color.w, clear_color.y * clear_color.w, clear_color.z * clear_color.w, clear_color.w); + + ImGui_ImplGX2_RenderDrawData(ImGui::GetDrawData()); + + WHBGfxFinishRenderTV(); + // copy the tv buffer to the drc as well + GX2CopyColorBufferToScanBuffer(WHBGfxGetTVColourBuffer(), GX2_SCAN_TARGET_DRC); + + WHBGfxFinishRender(); + } + + // Cleanup + ImGui_ImplGX2_Shutdown(); + ImGui::DestroyContext(); + + WHBGfxShutdown(); + WHBProcShutdown(); + + return 0; +} diff --git a/imgui_draw.cpp b/imgui_draw.cpp index 256dd6f98a1c..1fb3e8fb80ec 100644 --- a/imgui_draw.cpp +++ b/imgui_draw.cpp @@ -753,7 +753,12 @@ void ImDrawList::AddPolyline(const ImVec2* points, const int points_count, ImU32 // Temporary buffer // The first items are normals at each line point, then after that there are either 2 or 4 temp points for each line point +#ifdef __WIIU__ + // avoid using alloca on the Wii U + ImVec2 temp_normals[points_count * ((use_texture || !thick_line) ? 3 : 5) * sizeof(ImVec2)]; //-V630 +#else ImVec2* temp_normals = (ImVec2*)alloca(points_count * ((use_texture || !thick_line) ? 3 : 5) * sizeof(ImVec2)); //-V630 +#endif ImVec2* temp_points = temp_normals + points_count; // Calculate normals (tangents) for each line segment @@ -1001,7 +1006,12 @@ void ImDrawList::AddConvexPolyFilled(const ImVec2* points, const int points_coun } // Compute normals +#ifdef __WIIU__ + // Avoid using alloca on the Wii U + ImVec2 temp_normals[points_count * sizeof(ImVec2)]; //-V630 +#else ImVec2* temp_normals = (ImVec2*)alloca(points_count * sizeof(ImVec2)); //-V630 +#endif for (int i0 = points_count - 1, i1 = 0; i1 < points_count; i0 = i1++) { const ImVec2& p0 = points[i0]; From d99130d3ace6a7e40979d98c3a27bc3e78f7dd7a Mon Sep 17 00:00:00 2001 From: GaryOderNichts <12049776+GaryOderNichts@users.noreply.github.com> Date: Wed, 20 Jul 2022 02:57:23 +0200 Subject: [PATCH 2/8] wiiu: Use 2x scaling and add touch input to example --- examples/example_gx2/main.cpp | 31 ++++++++++++++++++++++++++++--- 1 file changed, 28 insertions(+), 3 deletions(-) diff --git a/examples/example_gx2/main.cpp b/examples/example_gx2/main.cpp index a360ff9daf7f..4bbaea3a4aef 100644 --- a/examples/example_gx2/main.cpp +++ b/examples/example_gx2/main.cpp @@ -1,13 +1,18 @@ // Dear ImGui: standalone example application for the Wii U + +// ImGui includes #include "imgui.h" #include "imgui_impl_gx2.h" -#include +// Graphics includes #include #include #include #include +// Input includes +#include + int main(int, char**) { // Init ProcUI and GX2 @@ -27,10 +32,16 @@ int main(int, char**) ImGui_ImplGX2_Init(); // Our state + bool was_touched = false; bool show_demo_window = true; bool show_another_window = false; ImVec4 clear_color = ImVec4(0.45f, 0.55f, 0.60f, 1.00f); + // Setup display sizes and scales + io.DisplaySize.x = (float)WHBGfxGetTVColourBuffer()->surface.width; // set the current display width + io.DisplaySize.y = (float)WHBGfxGetTVColourBuffer()->surface.height; // set the current display height here + io.DisplayFramebufferScale = ImVec2(2.0f, 2.0f); + // Main loop while (WHBProcIsRunning()) { @@ -38,8 +49,22 @@ int main(int, char**) WHBGfxBeginRender(); WHBGfxBeginRenderTV(); - io.DisplaySize.x = (float)WHBGfxGetTVColourBuffer()->surface.width; // set the current display width - io.DisplaySize.y = (float)WHBGfxGetTVColourBuffer()->surface.height; // set the current display height here + VPADStatus vpad; + VPADRead(VPAD_CHAN_0, &vpad, 1, nullptr); + + VPADTouchData touch; + VPADGetTPCalibratedPoint(VPAD_CHAN_0, &touch, &vpad.tpNormal); + + if (touch.touched) { + float scale_x = (io.DisplaySize.x / io.DisplayFramebufferScale.x) / 1280.0f; + float scale_y = (io.DisplaySize.y / io.DisplayFramebufferScale.y) / 720.0f; + io.AddMousePosEvent(touch.x * scale_x, touch.y * scale_y); + } + + if (touch.touched != was_touched) { + io.AddMouseButtonEvent(0, touch.touched); + was_touched = touch.touched; + } // Start the Dear ImGui frame ImGui_ImplGX2_NewFrame(); From 4eb3d8db98ff387f32ce6dd0429339aa7120e82f Mon Sep 17 00:00:00 2001 From: GaryOderNichts <12049776+GaryOderNichts@users.noreply.github.com> Date: Wed, 20 Jul 2022 22:22:13 +0200 Subject: [PATCH 3/8] wiiu: Add platform backend --- backends/{gx2 => wiiu}/imgui_impl_gx2.cpp | 33 ++-- backends/{gx2 => wiiu}/imgui_impl_gx2.h | 0 backends/wiiu/imgui_impl_wiiu.cpp | 184 ++++++++++++++++++ backends/wiiu/imgui_impl_wiiu.h | 19 ++ .../{gx2 => wiiu}/shaders/build-shaders.sh | 0 backends/{gx2 => wiiu}/shaders/shader.h | 0 backends/{gx2 => wiiu}/shaders/shader.psh | 0 backends/{gx2 => wiiu}/shaders/shader.vsh | 0 .../{example_gx2 => example_wiiu}/Makefile | 4 +- .../{example_gx2 => example_wiiu}/main.cpp | 43 ++-- 10 files changed, 241 insertions(+), 42 deletions(-) rename backends/{gx2 => wiiu}/imgui_impl_gx2.cpp (93%) rename backends/{gx2 => wiiu}/imgui_impl_gx2.h (100%) create mode 100644 backends/wiiu/imgui_impl_wiiu.cpp create mode 100644 backends/wiiu/imgui_impl_wiiu.h rename backends/{gx2 => wiiu}/shaders/build-shaders.sh (100%) rename backends/{gx2 => wiiu}/shaders/shader.h (100%) rename backends/{gx2 => wiiu}/shaders/shader.psh (100%) rename backends/{gx2 => wiiu}/shaders/shader.vsh (100%) rename examples/{example_gx2 => example_wiiu}/Makefile (98%) rename examples/{example_gx2 => example_wiiu}/main.cpp (81%) diff --git a/backends/gx2/imgui_impl_gx2.cpp b/backends/wiiu/imgui_impl_gx2.cpp similarity index 93% rename from backends/gx2/imgui_impl_gx2.cpp rename to backends/wiiu/imgui_impl_gx2.cpp index 3ea67abd6514..c8ebb5341171 100644 --- a/backends/gx2/imgui_impl_gx2.cpp +++ b/backends/wiiu/imgui_impl_gx2.cpp @@ -19,8 +19,8 @@ // GX2 Texture / contains a texture and sampler struct ImGui_ImplGX2_Texture { - GX2Texture texture; - GX2Sampler sampler; + GX2Texture Texture; + GX2Sampler Sampler; ImGui_ImplGX2_Texture() { memset(this, 0, sizeof(*this)); } }; @@ -40,8 +40,7 @@ struct ImGui_ImplGX2_Data ImGui_ImplGX2_Data() { memset(this, 0, sizeof(*this)); } }; -// Backend data stored in io.BackendRendererUserData to allow support for multiple Dear ImGui contexts -// It is STRONGLY preferred that you use docking branch with multi-viewports (== single Dear ImGui context + multiple windows) instead of multiple Dear ImGui contexts. +// Backend data stored in io.BackendRendererUserData static ImGui_ImplGX2_Data* ImGui_ImplGX2_GetBackendData() { return ImGui::GetCurrentContext() ? (ImGui_ImplGX2_Data*)ImGui::GetIO().BackendRendererUserData : NULL; @@ -77,7 +76,7 @@ void ImGui_ImplGX2_Shutdown() void ImGui_ImplGX2_NewFrame() { ImGui_ImplGX2_Data* bd = ImGui_ImplGX2_GetBackendData(); - IM_ASSERT(bd != NULL && "Did you call ImGui_ImplOpenGL3_Init()?"); + IM_ASSERT(bd != NULL && "Did you call ImGui_ImplGX2_Init()?"); if (!bd->ShaderGroup) ImGui_ImplGX2_CreateDeviceObjects(); @@ -211,8 +210,8 @@ void ImGui_ImplGX2_RenderDrawData(ImDrawData* draw_data) // Bind texture, Draw ImGui_ImplGX2_Texture* tex = (ImGui_ImplGX2_Texture*) pcmd->GetTexID(); - GX2SetPixelTexture(&tex->texture, 0); - GX2SetPixelSampler(&tex->sampler, 0); + GX2SetPixelTexture(&tex->Texture, 0); + GX2SetPixelSampler(&tex->Sampler, 0); GX2DrawIndexedEx(GX2_PRIMITIVE_MODE_TRIANGLES, pcmd->ElemCount, sizeof(ImDrawIdx) == 2 ? GX2_INDEX_TYPE_U16 : GX2_INDEX_TYPE_U32, @@ -242,7 +241,7 @@ bool ImGui_ImplGX2_CreateFontsTexture() bd->FontTexture = IM_NEW(ImGui_ImplGX2_Texture)(); - GX2Texture* tex = &bd->FontTexture->texture; + GX2Texture* tex = &bd->FontTexture->Texture; memset(tex, 0, sizeof(GX2Texture)); tex->surface.dim = GX2_SURFACE_DIM_TEXTURE_2D; @@ -270,7 +269,7 @@ bool ImGui_ImplGX2_CreateFontsTexture() GX2RUnlockSurfaceEx(&tex->surface, 0, GX2R_RESOURCE_BIND_NONE); - GX2InitSampler(&bd->FontTexture->sampler, GX2_TEX_CLAMP_MODE_CLAMP, GX2_TEX_XY_FILTER_MODE_LINEAR); + GX2InitSampler(&bd->FontTexture->Sampler, GX2_TEX_CLAMP_MODE_CLAMP, GX2_TEX_XY_FILTER_MODE_LINEAR); // Store our identifier io.Fonts->SetTexID((ImTextureID) bd->FontTexture); @@ -284,10 +283,10 @@ void ImGui_ImplGX2_DestroyFontsTexture() ImGui_ImplGX2_Data* bd = ImGui_ImplGX2_GetBackendData(); if (bd->FontTexture) { - GX2RDestroySurfaceEx(&bd->FontTexture->texture.surface, GX2R_RESOURCE_BIND_NONE); + GX2RDestroySurfaceEx(&bd->FontTexture->Texture.surface, GX2R_RESOURCE_BIND_NONE); io.Fonts->SetTexID(0); IM_DELETE(bd->FontTexture); - bd->FontTexture = nullptr; + bd->FontTexture = NULL; } } @@ -296,7 +295,8 @@ bool ImGui_ImplGX2_CreateDeviceObjects() ImGui_ImplGX2_Data* bd = ImGui_ImplGX2_GetBackendData(); bd->ShaderGroup = IM_NEW(WHBGfxShaderGroup)(); - if (!WHBGfxLoadGFDShaderGroup(bd->ShaderGroup, 0, shader_gsh)) { + if (!WHBGfxLoadGFDShaderGroup(bd->ShaderGroup, 0, shader_gsh)) + { IM_DELETE(bd->ShaderGroup); return false; } @@ -305,7 +305,8 @@ bool ImGui_ImplGX2_CreateDeviceObjects() WHBGfxInitShaderAttribute(bd->ShaderGroup, "UV", 0, 8, GX2_ATTRIB_FORMAT_FLOAT_32_32); WHBGfxInitShaderAttribute(bd->ShaderGroup, "Color", 0, 16, GX2_ATTRIB_TYPE_8_8_8_8); - if (!WHBGfxInitFetchShader(bd->ShaderGroup)) { + if (!WHBGfxInitFetchShader(bd->ShaderGroup)) + { IM_DELETE(bd->ShaderGroup); return false; } @@ -320,14 +321,14 @@ void ImGui_ImplGX2_DestroyDeviceObjects() ImGui_ImplGX2_Data* bd = ImGui_ImplGX2_GetBackendData(); free(bd->VertexBuffer); - bd->VertexBuffer = nullptr; + bd->VertexBuffer = NULL; free(bd->IndexBuffer); - bd->IndexBuffer = nullptr; + bd->IndexBuffer = NULL; WHBGfxFreeShaderGroup(bd->ShaderGroup); IM_DELETE(bd->ShaderGroup); - bd->ShaderGroup = nullptr; + bd->ShaderGroup = NULL; ImGui_ImplGX2_DestroyFontsTexture(); } diff --git a/backends/gx2/imgui_impl_gx2.h b/backends/wiiu/imgui_impl_gx2.h similarity index 100% rename from backends/gx2/imgui_impl_gx2.h rename to backends/wiiu/imgui_impl_gx2.h diff --git a/backends/wiiu/imgui_impl_wiiu.cpp b/backends/wiiu/imgui_impl_wiiu.cpp new file mode 100644 index 000000000000..bf6a4e4f6c77 --- /dev/null +++ b/backends/wiiu/imgui_impl_wiiu.cpp @@ -0,0 +1,184 @@ +// dear imgui: Platform Backend for the Wii U +#include "imgui.h" +#include "imgui_impl_wiiu.h" +#include // malloc/free + +// Software keyboard +#include + +// Wii U Data +struct ImGui_ImplWiiU_Data +{ + nn::swkbd::CreateArg CreateArg; + nn::swkbd::AppearArg AppearArg; + + bool WantedTextInput; + bool WasTouched; + + ImGui_ImplWiiU_Data() { memset((void*)this, 0, sizeof(*this)); } +}; + +// Backend data stored in io.BackendPlatformUserData +static ImGui_ImplWiiU_Data* ImGui_ImplWiiU_GetBackendData() +{ + return ImGui::GetCurrentContext() ? (ImGui_ImplWiiU_Data*)ImGui::GetIO().BackendPlatformUserData : NULL; +} + +bool ImGui_ImplWiiU_Init() +{ + ImGuiIO& io = ImGui::GetIO(); + IM_ASSERT(io.BackendPlatformUserData == NULL && "Already initialized a platform backend!"); + + // Setup backend data + ImGui_ImplWiiU_Data* bd = IM_NEW(ImGui_ImplWiiU_Data)(); + io.BackendPlatformUserData = (void*)bd; + io.BackendPlatformName = "imgui_impl_wiiu"; + + // Initialize and create software keyboard + nn::swkbd::CreateArg createArg; + + createArg.workMemory = malloc(nn::swkbd::GetWorkMemorySize(0)); + createArg.fsClient = (FSClient*) malloc(sizeof(FSClient)); + if (!createArg.workMemory || !createArg.fsClient) + { + free(createArg.workMemory); + free(createArg.fsClient); + return false; + } + + FSAddClient(createArg.fsClient, FS_ERROR_FLAG_NONE); + + if (!nn::swkbd::Create(createArg)) + return false; + + nn::swkbd::AppearArg appearArg; + bd->CreateArg = createArg; + bd->AppearArg = appearArg; + + return true; +} + +void ImGui_ImplWiiU_Shutdown() +{ + ImGui_ImplWiiU_Data* bd = ImGui_ImplWiiU_GetBackendData(); + IM_ASSERT(bd != NULL && "No platform backend to shutdown, or already shutdown?"); + ImGuiIO& io = ImGui::GetIO(); + + // Destroy software keyboard + nn::swkbd::Destroy(); + free(bd->CreateArg.workMemory); + bd->CreateArg.workMemory = NULL; + + if (bd->CreateArg.fsClient) + { + FSDelClient(bd->CreateArg.fsClient, FS_ERROR_FLAG_NONE); + free(bd->CreateArg.fsClient); + bd->CreateArg.fsClient = NULL; + } + + io.BackendPlatformName = NULL; + io.BackendPlatformUserData = NULL; + IM_DELETE(bd); +} + +static void ImGui_ImplWiiU_UpdateKeyboardInput(ImGui_ImplWiiU_ControllerInput* input) +{ + ImGuiIO& io = ImGui::GetIO(); + + VPADGetTPCalibratedPoint(VPAD_CHAN_0, &input->vpad->tpNormal, &input->vpad->tpNormal); + + nn::swkbd::ControllerInfo controllerInfo; + controllerInfo.vpad = input->vpad; + for (int i = 0; i < 4; i++) + controllerInfo.kpad[i] = input->kpad[i]; + + nn::swkbd::Calc(controllerInfo); + + if (nn::swkbd::IsNeedCalcSubThreadFont()) + nn::swkbd::CalcSubThreadFont(); + + if (nn::swkbd::IsNeedCalcSubThreadPredict()) + nn::swkbd::CalcSubThreadPredict(); + + if (nn::swkbd::IsDecideOkButton(NULL)) + { + // Add entered text + const char16_t* string = nn::swkbd::GetInputFormString(); + for (int i = 0; *string; string++) + io.AddInputCharacterUTF16(string[i]); + + // close keyboard + nn::swkbd::DisappearInputForm(); + } + + if (nn::swkbd::IsDecideCancelButton(NULL)) + nn::swkbd::DisappearInputForm(); +} + +static void ImGui_ImplWiiU_UpdateTouchInput(ImGui_ImplWiiU_ControllerInput* input) +{ + ImGui_ImplWiiU_Data* bd = ImGui_ImplWiiU_GetBackendData(); + ImGuiIO& io = ImGui::GetIO(); + + VPADTouchData touch; + VPADGetTPCalibratedPoint(VPAD_CHAN_0, &touch, &input->vpad->tpNormal); + + if (touch.touched) + { + float scale_x = (io.DisplaySize.x / io.DisplayFramebufferScale.x) / 1280.0f; + float scale_y = (io.DisplaySize.y / io.DisplayFramebufferScale.y) / 720.0f; + io.AddMousePosEvent(touch.x * scale_x, touch.y * scale_y); + } + + if (touch.touched != bd->WasTouched) + { + io.AddMouseButtonEvent(ImGuiMouseButton_Left, touch.touched); + bd->WasTouched = touch.touched; + } +} + +static void ImGui_ImplWiiU_UpdateControllerInput(ImGui_ImplWiiU_ControllerInput* input) +{ + +} + +bool ImGui_ImplWiiU_ProcessInput(ImGui_ImplWiiU_ControllerInput* input) +{ + ImGui_ImplWiiU_Data* bd = ImGui_ImplWiiU_GetBackendData(); + IM_ASSERT(bd != NULL && "Did you call ImGui_ImplWiiU_Init()?"); + ImGuiIO& io = ImGui::GetIO(); + + // Show keyboard if wanted + if (io.WantTextInput && !bd->WantedTextInput) + { + if (nn::swkbd::GetStateInputForm() == nn::swkbd::State::Hidden) + nn::swkbd::AppearInputForm(bd->AppearArg); + } + bd->WantedTextInput = io.WantTextInput; + + // Update keyboard input + if (nn::swkbd::GetStateInputForm() != nn::swkbd::State::Hidden) + { + ImGui_ImplWiiU_UpdateKeyboardInput(input); + return true; + } + + // Update touch screen + ImGui_ImplWiiU_UpdateTouchInput(input); + + // Update gamepads + ImGui_ImplWiiU_UpdateControllerInput(input); + + return false; +} + +void ImGui_ImplWiiU_DrawKeyboardOverlay(bool drawDRC) +{ + if (nn::swkbd::GetStateInputForm() != nn::swkbd::State::Hidden) + { + if (drawDRC) + nn::swkbd::DrawDRC(); + else + nn::swkbd::DrawTV(); + } +} diff --git a/backends/wiiu/imgui_impl_wiiu.h b/backends/wiiu/imgui_impl_wiiu.h new file mode 100644 index 000000000000..83152636ba5d --- /dev/null +++ b/backends/wiiu/imgui_impl_wiiu.h @@ -0,0 +1,19 @@ +// dear imgui: Platform Backend for the Wii U +#pragma once +#include "imgui.h" // IMGUI_IMPL_API + +// GamePad Input +#include +// Controller Input +#include + +struct ImGui_ImplWiiU_ControllerInput +{ + VPADStatus* vpad = nullptr; + KPADStatus* kpad[4] = { nullptr }; +}; + +IMGUI_IMPL_API bool ImGui_ImplWiiU_Init(); +IMGUI_IMPL_API void ImGui_ImplWiiU_Shutdown(); +IMGUI_IMPL_API bool ImGui_ImplWiiU_ProcessInput(ImGui_ImplWiiU_ControllerInput* input); +IMGUI_IMPL_API void ImGui_ImplWiiU_DrawKeyboardOverlay(bool drawDRC); diff --git a/backends/gx2/shaders/build-shaders.sh b/backends/wiiu/shaders/build-shaders.sh similarity index 100% rename from backends/gx2/shaders/build-shaders.sh rename to backends/wiiu/shaders/build-shaders.sh diff --git a/backends/gx2/shaders/shader.h b/backends/wiiu/shaders/shader.h similarity index 100% rename from backends/gx2/shaders/shader.h rename to backends/wiiu/shaders/shader.h diff --git a/backends/gx2/shaders/shader.psh b/backends/wiiu/shaders/shader.psh similarity index 100% rename from backends/gx2/shaders/shader.psh rename to backends/wiiu/shaders/shader.psh diff --git a/backends/gx2/shaders/shader.vsh b/backends/wiiu/shaders/shader.vsh similarity index 100% rename from backends/gx2/shaders/shader.vsh rename to backends/wiiu/shaders/shader.vsh diff --git a/examples/example_gx2/Makefile b/examples/example_wiiu/Makefile similarity index 98% rename from examples/example_gx2/Makefile rename to examples/example_wiiu/Makefile index 62f2b051844a..8a553903d911 100644 --- a/examples/example_gx2/Makefile +++ b/examples/example_wiiu/Makefile @@ -19,9 +19,9 @@ include $(DEVKITPRO)/wut/share/wut_rules #------------------------------------------------------------------------------- TARGET := $(notdir $(CURDIR)) BUILD := build -SOURCES := . ../../ ../../backends/gx2 +SOURCES := . ../../ ../../backends/wiiu DATA := data -INCLUDES := . ../../ ../../backends/gx2 +INCLUDES := . ../../ ../../backends/wiiu #------------------------------------------------------------------------------- # options for code generation diff --git a/examples/example_gx2/main.cpp b/examples/example_wiiu/main.cpp similarity index 81% rename from examples/example_gx2/main.cpp rename to examples/example_wiiu/main.cpp index 4bbaea3a4aef..f790cbd4c78a 100644 --- a/examples/example_gx2/main.cpp +++ b/examples/example_wiiu/main.cpp @@ -3,6 +3,7 @@ // ImGui includes #include "imgui.h" #include "imgui_impl_gx2.h" +#include "imgui_impl_wiiu.h" // Graphics includes #include @@ -28,11 +29,11 @@ int main(int, char**) ImGui::StyleColorsDark(); //ImGui::StyleColorsClassic(); - // Setup Renderer backends + // Setup platform and renderer backends + ImGui_ImplWiiU_Init(); ImGui_ImplGX2_Init(); // Our state - bool was_touched = false; bool show_demo_window = true; bool show_another_window = false; ImVec4 clear_color = ImVec4(0.45f, 0.55f, 0.60f, 1.00f); @@ -45,35 +46,24 @@ int main(int, char**) // Main loop while (WHBProcIsRunning()) { - // Start a new frame / We'll be using the TV buffer - WHBGfxBeginRender(); - WHBGfxBeginRenderTV(); - VPADStatus vpad; VPADRead(VPAD_CHAN_0, &vpad, 1, nullptr); - VPADTouchData touch; - VPADGetTPCalibratedPoint(VPAD_CHAN_0, &touch, &vpad.tpNormal); - - if (touch.touched) { - float scale_x = (io.DisplaySize.x / io.DisplayFramebufferScale.x) / 1280.0f; - float scale_y = (io.DisplaySize.y / io.DisplayFramebufferScale.y) / 720.0f; - io.AddMousePosEvent(touch.x * scale_x, touch.y * scale_y); - } + ImGui_ImplWiiU_ControllerInput input; + input.vpad = &vpad; + ImGui_ImplWiiU_ProcessInput(&input); - if (touch.touched != was_touched) { - io.AddMouseButtonEvent(0, touch.touched); - was_touched = touch.touched; - } + // Start a new frame / We'll be using the TV buffer + WHBGfxBeginRender(); + WHBGfxBeginRenderTV(); // Start the Dear ImGui frame ImGui_ImplGX2_NewFrame(); ImGui::NewFrame(); // 1. Show the big demo window (Most of the sample code is in ImGui::ShowDemoWindow()! You can browse its code to learn more about Dear ImGui!). - if (show_demo_window) { + if (show_demo_window) ImGui::ShowDemoWindow(&show_demo_window); - } // 2. Show a simple window that we create ourselves. We use a Begin/End pair to created a named window. { @@ -110,15 +100,19 @@ int main(int, char**) // Rendering ImGui::Render(); - float display_w = (float)WHBGfxGetTVColourBuffer()->surface.width; - float display_h = (float)WHBGfxGetTVColourBuffer()->surface.height; - GX2SetViewport(0, 0, display_w, display_h, 1.0f, 0.0f); + GX2SetViewport(0, 0, io.DisplaySize.x, io.DisplaySize.y, 0.0f, 1.0f); WHBGfxClearColor(clear_color.x * clear_color.w, clear_color.y * clear_color.w, clear_color.z * clear_color.w, clear_color.w); + // Render draw data ImGui_ImplGX2_RenderDrawData(ImGui::GetDrawData()); + // Render keyboard overlay + GX2SetViewport(0, 0, io.DisplaySize.x, io.DisplaySize.y, 0.0f, 1.0f); + GX2SetScissor(0, 0, io.DisplaySize.x, io.DisplaySize.y); + ImGui_ImplWiiU_DrawKeyboardOverlay(true); + WHBGfxFinishRenderTV(); - // copy the tv buffer to the drc as well + // Copy the TV buffer to the drc as well GX2CopyColorBufferToScanBuffer(WHBGfxGetTVColourBuffer(), GX2_SCAN_TARGET_DRC); WHBGfxFinishRender(); @@ -126,6 +120,7 @@ int main(int, char**) // Cleanup ImGui_ImplGX2_Shutdown(); + ImGui_ImplWiiU_Shutdown(); ImGui::DestroyContext(); WHBGfxShutdown(); From 8e61fae95e8a497da481dac0f182b309ca8be86d Mon Sep 17 00:00:00 2001 From: GaryOderNichts <12049776+GaryOderNichts@users.noreply.github.com> Date: Wed, 20 Jul 2022 23:12:44 +0200 Subject: [PATCH 4/8] wiiu: Don't use DisplayFramebufferScale for scaling --- examples/example_wiiu/main.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/examples/example_wiiu/main.cpp b/examples/example_wiiu/main.cpp index f790cbd4c78a..6ae2d55b841a 100644 --- a/examples/example_wiiu/main.cpp +++ b/examples/example_wiiu/main.cpp @@ -29,6 +29,10 @@ int main(int, char**) ImGui::StyleColorsDark(); //ImGui::StyleColorsClassic(); + // Scale everything by 2 for the Wii U + ImGui::GetStyle().ScaleAllSizes(2.0f); + io.FontGlobalScale = 2.0f; + // Setup platform and renderer backends ImGui_ImplWiiU_Init(); ImGui_ImplGX2_Init(); @@ -41,7 +45,6 @@ int main(int, char**) // Setup display sizes and scales io.DisplaySize.x = (float)WHBGfxGetTVColourBuffer()->surface.width; // set the current display width io.DisplaySize.y = (float)WHBGfxGetTVColourBuffer()->surface.height; // set the current display height here - io.DisplayFramebufferScale = ImVec2(2.0f, 2.0f); // Main loop while (WHBProcIsRunning()) From 4e779bfdb3026d62bcaa856b6d66859dd9ca9b4f Mon Sep 17 00:00:00 2001 From: GaryOderNichts <12049776+GaryOderNichts@users.noreply.github.com> Date: Thu, 21 Jul 2022 01:55:10 +0200 Subject: [PATCH 5/8] wiiu: Gamepad navigation support --- backends/wiiu/imgui_impl_wiiu.cpp | 85 +++++++++++++++++++++++++++++++ examples/example_wiiu/main.cpp | 25 +++++++-- 2 files changed, 106 insertions(+), 4 deletions(-) diff --git a/backends/wiiu/imgui_impl_wiiu.cpp b/backends/wiiu/imgui_impl_wiiu.cpp index bf6a4e4f6c77..9d5057d04ab2 100644 --- a/backends/wiiu/imgui_impl_wiiu.cpp +++ b/backends/wiiu/imgui_impl_wiiu.cpp @@ -33,6 +33,7 @@ bool ImGui_ImplWiiU_Init() ImGui_ImplWiiU_Data* bd = IM_NEW(ImGui_ImplWiiU_Data)(); io.BackendPlatformUserData = (void*)bd; io.BackendPlatformName = "imgui_impl_wiiu"; + io.BackendFlags |= ImGuiBackendFlags_HasGamepad; // Initialize and create software keyboard nn::swkbd::CreateArg createArg; @@ -83,6 +84,9 @@ void ImGui_ImplWiiU_Shutdown() static void ImGui_ImplWiiU_UpdateKeyboardInput(ImGui_ImplWiiU_ControllerInput* input) { + if (!input->vpad) + return; + ImGuiIO& io = ImGui::GetIO(); VPADGetTPCalibratedPoint(VPAD_CHAN_0, &input->vpad->tpNormal, &input->vpad->tpNormal); @@ -117,6 +121,9 @@ static void ImGui_ImplWiiU_UpdateKeyboardInput(ImGui_ImplWiiU_ControllerInput* i static void ImGui_ImplWiiU_UpdateTouchInput(ImGui_ImplWiiU_ControllerInput* input) { + if (!input->vpad) + return; + ImGui_ImplWiiU_Data* bd = ImGui_ImplWiiU_GetBackendData(); ImGuiIO& io = ImGui::GetIO(); @@ -137,9 +144,87 @@ static void ImGui_ImplWiiU_UpdateTouchInput(ImGui_ImplWiiU_ControllerInput* inpu } } +#define IM_CLAMP(V, MN, MX) ((V) < (MN) ? (MN) : (V) > (MX) ? (MX) : (V)) + static void ImGui_ImplWiiU_UpdateControllerInput(ImGui_ImplWiiU_ControllerInput* input) { + ImGuiIO& io = ImGui::GetIO(); + if ((io.ConfigFlags & ImGuiConfigFlags_NavEnableGamepad) == 0) + return; + + uint32_t vpad_buttons = input->vpad ? input->vpad->hold : 0; + uint32_t wpad_buttons = 0; + uint32_t classic_buttons = 0; + uint32_t pro_buttons = 0; + + float stick_l_x = input->vpad ? input->vpad->leftStick.x : 0.0f; + float stick_l_y = input->vpad ? input->vpad->leftStick.y : 0.0f; + float stick_r_x = input->vpad ? input->vpad->rightStick.x : 0.0f; + float stick_r_y = input->vpad ? input->vpad->rightStick.y : 0.0f; + + for (int i = 0; i < 4; i++) + { + KPADStatus* kpad = input->kpad[i]; + if (!kpad) + continue; + + switch (kpad->extensionType) + { + case WPAD_EXT_CORE: + case WPAD_EXT_NUNCHUK: + case WPAD_EXT_MPLUS: + case WPAD_EXT_MPLUS_NUNCHUK: + wpad_buttons |= kpad->hold; + break; + case WPAD_EXT_CLASSIC: + classic_buttons |= kpad->classic.hold; + stick_l_x += kpad->classic.leftStick.x; + stick_l_y += kpad->classic.leftStick.y; + stick_r_x += kpad->classic.rightStick.x; + stick_r_y += kpad->classic.rightStick.y; + break; + case WPAD_EXT_PRO_CONTROLLER: + pro_buttons |= kpad->pro.hold; + stick_l_x += kpad->pro.leftStick.x; + stick_l_y += kpad->pro.leftStick.y; + stick_r_x += kpad->pro.rightStick.x; + stick_r_y += kpad->pro.rightStick.y; + break; + } + } + io.AddKeyEvent(ImGuiKey_GamepadStart, (vpad_buttons & VPAD_BUTTON_PLUS) || (wpad_buttons & WPAD_BUTTON_PLUS) || (classic_buttons & WPAD_CLASSIC_BUTTON_PLUS) || (pro_buttons & WPAD_PRO_BUTTON_PLUS)); + io.AddKeyEvent(ImGuiKey_GamepadBack, (vpad_buttons & VPAD_BUTTON_MINUS) || (wpad_buttons & WPAD_BUTTON_MINUS) || (classic_buttons & WPAD_CLASSIC_BUTTON_MINUS) || (pro_buttons & WPAD_PRO_BUTTON_MINUS)); + io.AddKeyEvent(ImGuiKey_GamepadFaceLeft, (vpad_buttons & VPAD_BUTTON_Y) || (classic_buttons & WPAD_CLASSIC_BUTTON_Y) || (pro_buttons & WPAD_PRO_BUTTON_Y)); + io.AddKeyEvent(ImGuiKey_GamepadFaceRight, (vpad_buttons & VPAD_BUTTON_A) || (wpad_buttons & WPAD_BUTTON_A) || (classic_buttons & WPAD_CLASSIC_BUTTON_A) || (pro_buttons & WPAD_PRO_BUTTON_A)); + io.AddKeyEvent(ImGuiKey_GamepadFaceUp, (vpad_buttons & VPAD_BUTTON_X) || (classic_buttons & WPAD_CLASSIC_BUTTON_X) || (pro_buttons & WPAD_PRO_BUTTON_X)); + io.AddKeyEvent(ImGuiKey_GamepadFaceDown, (vpad_buttons & VPAD_BUTTON_B) || (wpad_buttons & WPAD_BUTTON_B) || (classic_buttons & WPAD_CLASSIC_BUTTON_B) || (pro_buttons & WPAD_PRO_BUTTON_B)); + io.AddKeyEvent(ImGuiKey_GamepadDpadLeft, (vpad_buttons & VPAD_BUTTON_LEFT) || (wpad_buttons & WPAD_BUTTON_LEFT) || (classic_buttons & WPAD_CLASSIC_BUTTON_LEFT) || (pro_buttons & WPAD_PRO_BUTTON_LEFT)); + io.AddKeyEvent(ImGuiKey_GamepadDpadRight, (vpad_buttons & VPAD_BUTTON_RIGHT) || (wpad_buttons & WPAD_BUTTON_RIGHT) || (classic_buttons & WPAD_CLASSIC_BUTTON_RIGHT) || (pro_buttons & WPAD_PRO_BUTTON_RIGHT)); + io.AddKeyEvent(ImGuiKey_GamepadDpadUp, (vpad_buttons & VPAD_BUTTON_UP) || (wpad_buttons & WPAD_BUTTON_UP) || (classic_buttons & WPAD_CLASSIC_BUTTON_UP) || (pro_buttons & WPAD_PRO_BUTTON_UP)); + io.AddKeyEvent(ImGuiKey_GamepadDpadDown, (vpad_buttons & VPAD_BUTTON_DOWN) || (wpad_buttons & WPAD_BUTTON_DOWN) || (classic_buttons & WPAD_CLASSIC_BUTTON_DOWN) || (pro_buttons & WPAD_PRO_BUTTON_DOWN)); + io.AddKeyEvent(ImGuiKey_GamepadL1, (vpad_buttons & VPAD_BUTTON_L) || (classic_buttons & WPAD_CLASSIC_BUTTON_L) || (pro_buttons & WPAD_PRO_TRIGGER_L)); + io.AddKeyEvent(ImGuiKey_GamepadR1, (vpad_buttons & VPAD_BUTTON_R) || (classic_buttons & WPAD_CLASSIC_BUTTON_R) || (pro_buttons & WPAD_PRO_TRIGGER_R)); + io.AddKeyEvent(ImGuiKey_GamepadL2, (vpad_buttons & VPAD_BUTTON_ZL) || (classic_buttons & WPAD_CLASSIC_BUTTON_ZL) || (pro_buttons & WPAD_PRO_TRIGGER_ZL)); + io.AddKeyEvent(ImGuiKey_GamepadR2, (vpad_buttons & VPAD_BUTTON_ZR) || (classic_buttons & WPAD_CLASSIC_BUTTON_ZR) || (pro_buttons & WPAD_PRO_TRIGGER_ZR)); + io.AddKeyEvent(ImGuiKey_GamepadL3, (vpad_buttons & VPAD_BUTTON_STICK_L) || (pro_buttons & WPAD_PRO_BUTTON_STICK_L)); + io.AddKeyEvent(ImGuiKey_GamepadR3, (vpad_buttons & VPAD_BUTTON_STICK_R) || (pro_buttons & WPAD_PRO_BUTTON_STICK_R)); + + stick_l_x = IM_CLAMP(stick_l_x, -1.0f, 1.0f); + io.AddKeyAnalogEvent(ImGuiKey_GamepadLStickLeft, stick_l_x < -0.1f, (stick_l_x < -0.1f) ? (stick_l_x * -1.0f) : 0.0f); + io.AddKeyAnalogEvent(ImGuiKey_GamepadLStickRight, stick_l_x > 0.1f, (stick_l_x > 0.1f) ? stick_l_x : 0.0f); + + stick_l_y = IM_CLAMP(stick_l_y, -1.0f, 1.0f); + io.AddKeyAnalogEvent(ImGuiKey_GamepadLStickUp, stick_l_y > 0.1f, (stick_l_y > 0.1f) ? stick_l_y : 0.0f); + io.AddKeyAnalogEvent(ImGuiKey_GamepadLStickDown, stick_l_y < -0.1f, (stick_l_y < -0.1f) ? (stick_l_y * -1.0f) : 0.0f); + + stick_r_x = IM_CLAMP(stick_r_x, -1.0f, 1.0f); + io.AddKeyAnalogEvent(ImGuiKey_GamepadRStickLeft, stick_r_x < -0.1f, (stick_r_x < -0.1f) ? (stick_r_x * -1.0f) : 0.0f); + io.AddKeyAnalogEvent(ImGuiKey_GamepadRStickRight, stick_r_x > 0.1f, (stick_r_x > 0.1f) ? stick_r_x : 0.0f); + + stick_r_y = IM_CLAMP(stick_r_y, -1.0f, 1.0f); + io.AddKeyAnalogEvent(ImGuiKey_GamepadRStickUp, stick_r_y > 0.1f, (stick_r_y > 0.1f) ? stick_r_y : 0.0f); + io.AddKeyAnalogEvent(ImGuiKey_GamepadRStickDown, stick_r_y < -0.1f, (stick_r_y < -0.1f) ? (stick_r_y * -1.0f) : 0.0f); } bool ImGui_ImplWiiU_ProcessInput(ImGui_ImplWiiU_ControllerInput* input) diff --git a/examples/example_wiiu/main.cpp b/examples/example_wiiu/main.cpp index 6ae2d55b841a..5dc9053f5f9b 100644 --- a/examples/example_wiiu/main.cpp +++ b/examples/example_wiiu/main.cpp @@ -20,10 +20,15 @@ int main(int, char**) WHBProcInit(); WHBGfxInit(); + // Initialize KPAD and enable Pro Controller + KPADInit(); + WPADEnableURCC(TRUE); + // Setup Dear ImGui context IMGUI_CHECKVERSION(); ImGui::CreateContext(); ImGuiIO& io = ImGui::GetIO(); (void)io; + io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad; // Enable Gamepad Controls // Setup Dear ImGui style ImGui::StyleColorsDark(); @@ -49,11 +54,23 @@ int main(int, char**) // Main loop while (WHBProcIsRunning()) { + ImGui_ImplWiiU_ControllerInput input; + VPADStatus vpad; - VPADRead(VPAD_CHAN_0, &vpad, 1, nullptr); + VPADReadError vpad_error; + VPADRead(VPAD_CHAN_0, &vpad, 1, &vpad_error); + if (vpad_error == VPAD_READ_SUCCESS) + input.vpad = &vpad; + + KPADStatus status[4]; + for (int i = 0; i < 4; i++) + { + KPADError kpad_error; + KPADReadEx((KPADChan) i, &status[i], 1, &kpad_error); + if (kpad_error == KPAD_ERROR_OK) + input.kpad[i] = &status[i]; + } - ImGui_ImplWiiU_ControllerInput input; - input.vpad = &vpad; ImGui_ImplWiiU_ProcessInput(&input); // Start a new frame / We'll be using the TV buffer @@ -114,8 +131,8 @@ int main(int, char**) GX2SetScissor(0, 0, io.DisplaySize.x, io.DisplaySize.y); ImGui_ImplWiiU_DrawKeyboardOverlay(true); + // Copy the TV buffer to the scanbuffers WHBGfxFinishRenderTV(); - // Copy the TV buffer to the drc as well GX2CopyColorBufferToScanBuffer(WHBGfxGetTVColourBuffer(), GX2_SCAN_TARGET_DRC); WHBGfxFinishRender(); From d7d16a25626c0f008b0b47a6f8b9e2c23b03d838 Mon Sep 17 00:00:00 2001 From: GaryOderNichts <12049776+GaryOderNichts@users.noreply.github.com> Date: Thu, 21 Jul 2022 02:36:54 +0200 Subject: [PATCH 6/8] wiiu: Controller support for keyboard overlay --- backends/wiiu/imgui_impl_wiiu.cpp | 34 +++++++++++++++++++++++++------ backends/wiiu/imgui_impl_wiiu.h | 12 ++++++++++- examples/example_wiiu/main.cpp | 2 +- 3 files changed, 40 insertions(+), 8 deletions(-) diff --git a/backends/wiiu/imgui_impl_wiiu.cpp b/backends/wiiu/imgui_impl_wiiu.cpp index 9d5057d04ab2..caa23694d75a 100644 --- a/backends/wiiu/imgui_impl_wiiu.cpp +++ b/backends/wiiu/imgui_impl_wiiu.cpp @@ -11,6 +11,7 @@ struct ImGui_ImplWiiU_Data { nn::swkbd::CreateArg CreateArg; nn::swkbd::AppearArg AppearArg; + nn::swkbd::ControllerType LastController; bool WantedTextInput; bool WasTouched; @@ -84,9 +85,6 @@ void ImGui_ImplWiiU_Shutdown() static void ImGui_ImplWiiU_UpdateKeyboardInput(ImGui_ImplWiiU_ControllerInput* input) { - if (!input->vpad) - return; - ImGuiIO& io = ImGui::GetIO(); VPADGetTPCalibratedPoint(VPAD_CHAN_0, &input->vpad->tpNormal, &input->vpad->tpNormal); @@ -141,6 +139,7 @@ static void ImGui_ImplWiiU_UpdateTouchInput(ImGui_ImplWiiU_ControllerInput* inpu { io.AddMouseButtonEvent(ImGuiMouseButton_Left, touch.touched); bd->WasTouched = touch.touched; + bd->LastController = nn::swkbd::ControllerType::DrcGamepad; } } @@ -148,6 +147,7 @@ static void ImGui_ImplWiiU_UpdateTouchInput(ImGui_ImplWiiU_ControllerInput* inpu static void ImGui_ImplWiiU_UpdateControllerInput(ImGui_ImplWiiU_ControllerInput* input) { + ImGui_ImplWiiU_Data* bd = ImGui_ImplWiiU_GetBackendData(); ImGuiIO& io = ImGui::GetIO(); if ((io.ConfigFlags & ImGuiConfigFlags_NavEnableGamepad) == 0) return; @@ -178,6 +178,9 @@ static void ImGui_ImplWiiU_UpdateControllerInput(ImGui_ImplWiiU_ControllerInput* break; case WPAD_EXT_CLASSIC: classic_buttons |= kpad->classic.hold; + if (classic_buttons & WPAD_CLASSIC_BUTTON_X) + bd->LastController = (nn::swkbd::ControllerType) i; + stick_l_x += kpad->classic.leftStick.x; stick_l_y += kpad->classic.leftStick.y; stick_r_x += kpad->classic.rightStick.x; @@ -185,6 +188,9 @@ static void ImGui_ImplWiiU_UpdateControllerInput(ImGui_ImplWiiU_ControllerInput* break; case WPAD_EXT_PRO_CONTROLLER: pro_buttons |= kpad->pro.hold; + if (pro_buttons & WPAD_PRO_BUTTON_X) + bd->LastController = (nn::swkbd::ControllerType) i; + stick_l_x += kpad->pro.leftStick.x; stick_l_y += kpad->pro.leftStick.y; stick_r_x += kpad->pro.rightStick.x; @@ -193,6 +199,9 @@ static void ImGui_ImplWiiU_UpdateControllerInput(ImGui_ImplWiiU_ControllerInput* } } + if (vpad_buttons & VPAD_BUTTON_X) + bd->LastController = nn::swkbd::ControllerType::DrcGamepad; + io.AddKeyEvent(ImGuiKey_GamepadStart, (vpad_buttons & VPAD_BUTTON_PLUS) || (wpad_buttons & WPAD_BUTTON_PLUS) || (classic_buttons & WPAD_CLASSIC_BUTTON_PLUS) || (pro_buttons & WPAD_PRO_BUTTON_PLUS)); io.AddKeyEvent(ImGuiKey_GamepadBack, (vpad_buttons & VPAD_BUTTON_MINUS) || (wpad_buttons & WPAD_BUTTON_MINUS) || (classic_buttons & WPAD_CLASSIC_BUTTON_MINUS) || (pro_buttons & WPAD_PRO_BUTTON_MINUS)); io.AddKeyEvent(ImGuiKey_GamepadFaceLeft, (vpad_buttons & VPAD_BUTTON_Y) || (classic_buttons & WPAD_CLASSIC_BUTTON_Y) || (pro_buttons & WPAD_PRO_BUTTON_Y)); @@ -236,6 +245,9 @@ bool ImGui_ImplWiiU_ProcessInput(ImGui_ImplWiiU_ControllerInput* input) // Show keyboard if wanted if (io.WantTextInput && !bd->WantedTextInput) { + // Open the keyboard for the controller which requested the text input + bd->AppearArg.keyboardArg.configArg.controllerType = bd->LastController; + if (nn::swkbd::GetStateInputForm() == nn::swkbd::State::Hidden) nn::swkbd::AppearInputForm(bd->AppearArg); } @@ -257,13 +269,23 @@ bool ImGui_ImplWiiU_ProcessInput(ImGui_ImplWiiU_ControllerInput* input) return false; } -void ImGui_ImplWiiU_DrawKeyboardOverlay(bool drawDRC) +void ImGui_ImplWiiU_DrawKeyboardOverlay(ImGui_ImplWiiU_KeyboardOverlayType type) { + ImGui_ImplWiiU_Data* bd = ImGui_ImplWiiU_GetBackendData(); + IM_ASSERT(bd != NULL && "Did you call ImGui_ImplWiiU_Init()?"); + if (nn::swkbd::GetStateInputForm() != nn::swkbd::State::Hidden) { - if (drawDRC) + if (type == ImGui_KeyboardOverlay_Auto) + { + if (bd->LastController == nn::swkbd::ControllerType::DrcGamepad) + nn::swkbd::DrawDRC(); + else + nn::swkbd::DrawTV(); + } + else if (type == ImGui_KeyboardOverlay_DRC) nn::swkbd::DrawDRC(); - else + else if (type == ImGui_KeyboardOverlay_TV) nn::swkbd::DrawTV(); } } diff --git a/backends/wiiu/imgui_impl_wiiu.h b/backends/wiiu/imgui_impl_wiiu.h index 83152636ba5d..b48fb9a59f18 100644 --- a/backends/wiiu/imgui_impl_wiiu.h +++ b/backends/wiiu/imgui_impl_wiiu.h @@ -13,7 +13,17 @@ struct ImGui_ImplWiiU_ControllerInput KPADStatus* kpad[4] = { nullptr }; }; +enum ImGui_ImplWiiU_KeyboardOverlayType +{ + //! Draw for the DRC + ImGui_KeyboardOverlay_DRC, + //! Draw for the TV + ImGui_KeyboardOverlay_TV, + //! Draw for the controller which requested the keyboard + ImGui_KeyboardOverlay_Auto +}; + IMGUI_IMPL_API bool ImGui_ImplWiiU_Init(); IMGUI_IMPL_API void ImGui_ImplWiiU_Shutdown(); IMGUI_IMPL_API bool ImGui_ImplWiiU_ProcessInput(ImGui_ImplWiiU_ControllerInput* input); -IMGUI_IMPL_API void ImGui_ImplWiiU_DrawKeyboardOverlay(bool drawDRC); +IMGUI_IMPL_API void ImGui_ImplWiiU_DrawKeyboardOverlay(ImGui_ImplWiiU_KeyboardOverlayType type = ImGui_KeyboardOverlay_Auto); diff --git a/examples/example_wiiu/main.cpp b/examples/example_wiiu/main.cpp index 5dc9053f5f9b..dd71e9f96b74 100644 --- a/examples/example_wiiu/main.cpp +++ b/examples/example_wiiu/main.cpp @@ -129,7 +129,7 @@ int main(int, char**) // Render keyboard overlay GX2SetViewport(0, 0, io.DisplaySize.x, io.DisplaySize.y, 0.0f, 1.0f); GX2SetScissor(0, 0, io.DisplaySize.x, io.DisplaySize.y); - ImGui_ImplWiiU_DrawKeyboardOverlay(true); + ImGui_ImplWiiU_DrawKeyboardOverlay(); // Copy the TV buffer to the scanbuffers WHBGfxFinishRenderTV(); From 08a8b652be3651997fbaac4a07568183f0de4411 Mon Sep 17 00:00:00 2001 From: GaryOderNichts <12049776+GaryOderNichts@users.noreply.github.com> Date: Thu, 21 Jul 2022 15:17:30 +0200 Subject: [PATCH 7/8] wiiu: Remove unnecessary mul in vertex shader --- backends/wiiu/shaders/shader.h | 80 ++++++++++++++++---------------- backends/wiiu/shaders/shader.vsh | 10 ++-- 2 files changed, 42 insertions(+), 48 deletions(-) diff --git a/backends/wiiu/shaders/shader.h b/backends/wiiu/shaders/shader.h index ee6e6a8f7f2e..74572b58586f 100644 --- a/backends/wiiu/shaders/shader.h +++ b/backends/wiiu/shaders/shader.h @@ -21,7 +21,7 @@ unsigned char shader_gsh[] = { 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x01, 0x90, + 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x01, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xd0, 0x60, 0x01, 0x34, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, @@ -45,9 +45,9 @@ unsigned char shader_gsh[] = { 0x00, 0x00, 0x00, 0x20, 0xd0, 0x60, 0x01, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0xd0, 0x60, 0x01, 0x98, 0x42, 0x4c, 0x4b, 0x7b, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x01, 0x90, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x01, 0x70, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x09, - 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44, 0xa0, 0x3c, 0xa0, 0x00, 0x00, + 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x34, 0xa0, 0x3c, 0xa0, 0x00, 0x00, 0x88, 0x06, 0x00, 0x94, 0x00, 0x40, 0x01, 0x00, 0x08, 0x09, 0x80, 0x13, 0x01, 0xc0, 0x01, 0x00, 0x88, 0x06, 0x20, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, @@ -71,20 +71,18 @@ unsigned char shader_gsh[] = { 0x80, 0x00, 0x00, 0x00, 0xfd, 0x64, 0xa0, 0x00, 0x80, 0x00, 0x00, 0x20, 0xfd, 0x68, 0x20, 0x01, 0x80, 0x00, 0x00, 0x40, 0xfd, 0x6c, 0xa0, 0x81, 0x80, 0x00, 0x00, 0x60, 0x00, 0x00, 0x80, 0x3f, 0x00, 0x00, 0x80, 0x3f, - 0x00, 0x00, 0x80, 0x3f, 0x00, 0x00, 0x80, 0x3f, 0xf8, 0x40, 0x20, 0x00, - 0xfe, 0x00, 0xe2, 0x0f, 0xf8, 0x44, 0xa0, 0x00, 0xfe, 0x04, 0xe2, 0x2f, - 0xf8, 0x48, 0x20, 0x01, 0xfe, 0x08, 0xe2, 0x4f, 0xf8, 0x4c, 0xa0, 0x81, - 0xfe, 0x0c, 0xe2, 0x6f, 0x01, 0x24, 0x20, 0x00, 0xfe, 0x00, 0xe2, 0x0f, - 0x01, 0x24, 0xa0, 0x00, 0xfe, 0x04, 0xe2, 0x2f, 0x01, 0x24, 0x20, 0x01, - 0xfe, 0x08, 0xe2, 0x4f, 0x01, 0x24, 0xa0, 0x81, 0xfe, 0x0c, 0xe2, 0x6f, - 0x01, 0x00, 0x20, 0x00, 0xfe, 0x00, 0x22, 0x00, 0x01, 0x00, 0xa0, 0x00, - 0xfe, 0x04, 0x22, 0x20, 0x01, 0x00, 0x20, 0x01, 0xfe, 0x08, 0x22, 0x40, - 0x01, 0x00, 0xa0, 0x81, 0xfe, 0x0c, 0x22, 0x60, 0x42, 0x4c, 0x4b, 0x7b, - 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x01, 0x2c, 0x00, 0x00, 0x00, 0x02, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, - 0x14, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, - 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x80, 0x3f, 0x00, 0x00, 0x80, 0x3f, 0x01, 0x24, 0x20, 0x00, + 0xfe, 0x00, 0xe2, 0x0f, 0x01, 0x24, 0xa0, 0x00, 0xfe, 0x04, 0xe2, 0x2f, + 0x01, 0x24, 0x20, 0x01, 0xfe, 0x08, 0xe2, 0x4f, 0x01, 0x24, 0xa0, 0x81, + 0xfe, 0x0c, 0xe2, 0x6f, 0x01, 0x00, 0x20, 0x00, 0xfe, 0x00, 0x22, 0x00, + 0x01, 0x00, 0xa0, 0x00, 0xfe, 0x04, 0x22, 0x20, 0x01, 0x00, 0x20, 0x01, + 0xfe, 0x08, 0x22, 0x40, 0x01, 0x00, 0xa0, 0x81, 0xfe, 0x0c, 0x22, 0x60, + 0x42, 0x4c, 0x4b, 0x7b, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x01, 0x2c, + 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, + 0x00, 0x00, 0x00, 0x02, 0x14, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x01, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, @@ -94,26 +92,24 @@ unsigned char shader_gsh[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, - 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x01, 0x90, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x10, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x90, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, - 0xd0, 0x60, 0x00, 0xe8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xca, 0x70, 0x00, 0xf4, - 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x54, 0x65, 0x78, 0x74, - 0x75, 0x72, 0x65, 0x00, 0xd0, 0x60, 0x00, 0xd4, 0xca, 0x70, 0x00, 0xe8, - 0x7d, 0x42, 0x4c, 0x4b, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0xfc, 0xd0, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, - 0xd0, 0x60, 0x00, 0xf4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, - 0xd0, 0x60, 0x00, 0xfc, 0x42, 0x4c, 0x4b, 0x7b, 0x00, 0x00, 0x00, 0x20, - 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, - 0x00, 0x00, 0x01, 0x90, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, - 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x80, 0x20, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x0c, 0xa0, 0x00, 0x00, 0x00, 0x00, 0x88, 0x06, 0x20, 0x94, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x01, 0xd0, 0x60, 0x00, 0xe8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xca, 0x70, 0x00, 0xf4, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x54, 0x65, 0x78, 0x74, 0x75, 0x72, 0x65, 0x00, 0xd0, 0x60, 0x00, 0xd4, + 0xca, 0x70, 0x00, 0xe8, 0x7d, 0x42, 0x4c, 0x4b, 0x00, 0x00, 0x00, 0x28, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xd0, 0x60, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x08, 0xd0, 0x60, 0x00, 0xf4, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x02, 0xd0, 0x60, 0x00, 0xfc, 0x42, 0x4c, 0x4b, 0x7b, + 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x01, 0x90, 0x00, 0x00, 0x00, 0x03, + 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x80, + 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0xa0, 0x00, 0x00, 0x00, 0x00, + 0x88, 0x06, 0x20, 0x94, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, @@ -131,10 +127,11 @@ unsigned char shader_gsh[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x80, 0x01, 0x90, 0x00, 0x00, 0x00, - 0x00, 0x24, 0x00, 0x01, 0x90, 0x00, 0x00, 0x20, 0x00, 0x28, 0x80, 0x00, - 0x90, 0x00, 0x00, 0x40, 0x00, 0x2c, 0x00, 0x80, 0x90, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x80, 0x01, + 0x90, 0x00, 0x00, 0x00, 0x00, 0x24, 0x00, 0x01, 0x90, 0x00, 0x00, 0x20, + 0x00, 0x28, 0x80, 0x00, 0x90, 0x00, 0x00, 0x40, 0x00, 0x2c, 0x00, 0x80, + 0x90, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, @@ -142,9 +139,10 @@ unsigned char shader_gsh[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x10, 0x00, 0x00, 0x00, 0x00, 0x10, 0x0d, 0xf0, 0x00, 0x00, 0x80, 0x10, - 0x00, 0x00, 0x00, 0x00, 0x42, 0x4c, 0x4b, 0x7b, 0x00, 0x00, 0x00, 0x20, - 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00 + 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x10, 0x0d, 0xf0, + 0x00, 0x00, 0x80, 0x10, 0x00, 0x00, 0x00, 0x00, 0x42, 0x4c, 0x4b, 0x7b, + 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x00 }; -unsigned int shader_gsh_len = 1764; +unsigned int shader_gsh_len = 1732; diff --git a/backends/wiiu/shaders/shader.vsh b/backends/wiiu/shaders/shader.vsh index 8d63c65f6471..3b321d238c6a 100644 --- a/backends/wiiu/shaders/shader.vsh +++ b/backends/wiiu/shaders/shader.vsh @@ -28,20 +28,16 @@ ; $ATTRIB_VARS[2].location = 2 00 CALL_FS NO_BARRIER -01 ALU: ADDR(32) CNT(18) +01 ALU: ADDR(32) CNT(14) 0 x: MUL ____, 1.0f, C3.x y: MUL ____, 1.0f, C3.y z: MUL ____, 1.0f, C3.z w: MUL ____, 1.0f, C3.w - 1 x: MULADD R127.x, 0.0f, C2.x, PV0.x - y: MULADD R127.y, 0.0f, C2.y, PV0.y - z: MULADD R127.z, 0.0f, C2.z, PV0.z - w: MULADD R127.w, 0.0f, C2.w, PV0.w - 2 x: MULADD R127.x, R1.y, C1.x, PV0.x + 1 x: MULADD R127.x, R1.y, C1.x, PV0.x y: MULADD R127.y, R1.y, C1.y, PV0.y z: MULADD R127.z, R1.y, C1.z, PV0.z w: MULADD R127.w, R1.y, C1.w, PV0.w - 3 x: MULADD R1.x, R1.x, C0.x, PV0.x + 2 x: MULADD R1.x, R1.x, C0.x, PV0.x y: MULADD R1.y, R1.x, C0.y, PV0.y z: MULADD R1.z, R1.x, C0.z, PV0.z w: MULADD R1.w, R1.x, C0.w, PV0.w From fc9b42b0c334e2f87fba8889acc0bcc55c287a56 Mon Sep 17 00:00:00 2001 From: Maschell Date: Thu, 21 Jul 2022 01:30:04 +0200 Subject: [PATCH 8/8] Trivial HID-Mouse PoC --- backends/wiiu/imgui_impl_wiiu.cpp | 88 +++++++++++++++++++++++++++++++ 1 file changed, 88 insertions(+) diff --git a/backends/wiiu/imgui_impl_wiiu.cpp b/backends/wiiu/imgui_impl_wiiu.cpp index caa23694d75a..30a75373007f 100644 --- a/backends/wiiu/imgui_impl_wiiu.cpp +++ b/backends/wiiu/imgui_impl_wiiu.cpp @@ -5,6 +5,9 @@ // Software keyboard #include +#include +#include +#include // Wii U Data struct ImGui_ImplWiiU_Data @@ -16,6 +19,10 @@ struct ImGui_ImplWiiU_Data bool WantedTextInput; bool WasTouched; + bool MouseClientAdded; + HIDClient MouseHIDClient; + uint8_t *MouseMemory; + ImGui_ImplWiiU_Data() { memset((void*)this, 0, sizeof(*this)); } }; @@ -25,6 +32,74 @@ static ImGui_ImplWiiU_Data* ImGui_ImplWiiU_GetBackendData() return ImGui::GetCurrentContext() ? (ImGui_ImplWiiU_Data*)ImGui::GetIO().BackendPlatformUserData : NULL; } +static void ImGui_ImplWiiU_MouseReadCallback(uint32_t handle, uint32_t error, uint8_t * buffer, uint32_t bytes_transferred, void *data) { + ImGui_ImplWiiU_Data *bd = ImGui_ImplWiiU_GetBackendData(); + IM_ASSERT(bd != nullptr && "Did you call ImGui_ImplWiiU_Init()?"); + if (error == 0) { + if(nn::swkbd::GetStateInputForm() == nn::swkbd::State::Hidden) { + ImGuiIO &io = ImGui::GetIO(); + auto xpos = io.MousePos.x; + auto ypos = io.MousePos.y; + + if (buffer[1] != 0 || buffer[2] != 0) { + io.MouseDrawCursor = true; + + xpos += ((int8_t) buffer[1]) * 1.5f; + ypos += ((int8_t) buffer[2]) * 1.5f; + + if (xpos < 0) { + xpos = 0.0; + } else if (xpos > io.DisplaySize.x) { + xpos = io.DisplaySize.x; + } + + if (ypos < 0) { + ypos = 0.0; + } else if (ypos > io.DisplaySize.y) { + ypos = io.DisplaySize.y; + } + + io.AddMousePosEvent(xpos, ypos); + } + + io.AddMouseButtonEvent(ImGuiMouseButton_Left, buffer[0x00] & 1); + io.AddMouseButtonEvent(ImGuiMouseButton_Right, buffer[0x00] & 2); + } + + HIDRead(handle, (uint8_t *) bd->MouseMemory, bytes_transferred, reinterpret_cast(ImGui_ImplWiiU_MouseReadCallback), nullptr); + } else { + HIDDelClient(&bd->MouseHIDClient); + bd->MouseClientAdded = false; + } +} + +static int ImGui_ImplWiiU_MouseAttachCallback(HIDClient *client, HIDDevice *device, HIDAttachEvent attach) { + ImGui_ImplWiiU_Data *bd = ImGui_ImplWiiU_GetBackendData(); + IM_ASSERT(bd != nullptr && "Did you call ImGui_ImplWiiU_Init()?"); + if (attach) { + if (bd->MouseMemory) { + OSReport("Can't attach more than one mouse\n"); + return 1; + } else { + if ((device->subClass == 1) && (device->protocol == 2)) { + HIDSetProtocol(device->handle, device->interfaceIndex, 2, nullptr, nullptr); + HIDSetIdle(device->handle, device->interfaceIndex, 0, nullptr, nullptr); + + bd->MouseMemory = (uint8_t *) memalign(0x40, device->maxPacketSizeRx); + + HIDRead(device->handle, (uint8_t *) bd->MouseMemory, device->maxPacketSizeRx, reinterpret_cast(ImGui_ImplWiiU_MouseReadCallback), nullptr); + + return 1; + } + } + } else { + free(bd->MouseMemory); + bd->MouseMemory = nullptr; + } + + return 0; +} + bool ImGui_ImplWiiU_Init() { ImGuiIO& io = ImGui::GetIO(); @@ -57,6 +132,10 @@ bool ImGui_ImplWiiU_Init() bd->CreateArg = createArg; bd->AppearArg = appearArg; + HIDAddClient(&bd->MouseHIDClient, static_cast(ImGui_ImplWiiU_MouseAttachCallback)); + + bd->MouseClientAdded = true; + return true; } @@ -78,6 +157,8 @@ void ImGui_ImplWiiU_Shutdown() bd->CreateArg.fsClient = NULL; } + HIDDelClient(&bd->MouseHIDClient); + io.BackendPlatformName = NULL; io.BackendPlatformUserData = NULL; IM_DELETE(bd); @@ -133,6 +214,7 @@ static void ImGui_ImplWiiU_UpdateTouchInput(ImGui_ImplWiiU_ControllerInput* inpu float scale_x = (io.DisplaySize.x / io.DisplayFramebufferScale.x) / 1280.0f; float scale_y = (io.DisplaySize.y / io.DisplayFramebufferScale.y) / 720.0f; io.AddMousePosEvent(touch.x * scale_x, touch.y * scale_y); + io.MouseDrawCursor = false; } if (touch.touched != bd->WasTouched) @@ -266,6 +348,12 @@ bool ImGui_ImplWiiU_ProcessInput(ImGui_ImplWiiU_ControllerInput* input) // Update gamepads ImGui_ImplWiiU_UpdateControllerInput(input); + // Check Mouse + if(!bd->MouseClientAdded) { + HIDAddClient(&bd->MouseHIDClient, static_cast(ImGui_ImplWiiU_MouseAttachCallback)); + bd->MouseClientAdded = true; + } + return false; }