diff --git a/include/PR/ultratypes.h b/include/PR/ultratypes.h index 1ebde775..9dec311a 100644 --- a/include/PR/ultratypes.h +++ b/include/PR/ultratypes.h @@ -8,6 +8,8 @@ #define TRUE 1 #define FALSE 0 +#ifndef TARGET_SWITCH + typedef signed char s8; typedef unsigned char u8; typedef signed short int s16; @@ -26,6 +28,14 @@ typedef volatile s16 vs16; typedef volatile s32 vs32; typedef volatile s64 vs64; +#else + +#ifndef SWITCH_VARS +#define SWITCH_VARS +#include +#endif +#endif + typedef float f32; typedef double f64; @@ -33,7 +43,7 @@ typedef double f64; #include #include -#if defined(__MINGW32__) +#if defined(__MINGW32__) #include <_mingw.h> #if !defined(__MINGW64_VERSION_MAJOR) typedef long ssize_t; diff --git a/src/moon/imgui/imgui_impl.cpp b/src/moon/imgui/imgui_impl.cpp index 2f34d05b..7483db4d 100644 --- a/src/moon/imgui/imgui_impl.cpp +++ b/src/moon/imgui/imgui_impl.cpp @@ -4,8 +4,10 @@ #include #include "moon/libs/imgui/imgui.h" +#include "moon/libs/imgui/imgui_internal.h" #include "moon/libs/imgui/imgui_impl_sdl.h" #include "moon/libs/imgui/imgui_impl_opengl3.h" +#include "moon/libs/imgui/imgui_switch_impl.h" #include "moon/mod-engine/hooks/hook.h" #include "moon/mod-engine/textures/mod-texture.h" #include "moon/mod-engine/engine.h" @@ -24,6 +26,14 @@ #ifdef TARGET_SWITCH #include "glad/glad.h" +#include +#include +#include +#include +extern "C" { +#include "nx/m_nx.h" +} +# define RAPI_NAME "OpenGL 4.2" #else #define GL_GLEXT_PROTOTYPES 1 #ifdef USE_GLES @@ -53,26 +63,80 @@ using namespace std; bool showMenu = true; bool showWindowMoon = false; +bool showWindowDemo = false; SDL_Window* window = nullptr; ImGuiIO io; +#ifdef TARGET_SWITCH +namespace MoonNX { + SwkbdConfig kbd; + + static int waitFramesToUpdate = 0; + + void handleVirtualKeyboard(string status){ + if(status == "Init"){ + Result rc = 0; + char tmpoutstr[16] = {0}; + rc = swkbdCreate(&kbd, 0); + if (R_SUCCEEDED(rc)) + swkbdConfigMakePresetDefault(&kbd); + } + + if(status == "FrameUpdate") { + ImGuiIO* io = &ImGui::GetIO(); + int length = 512; + char* message; + + if(waitFramesToUpdate > 0) + waitFramesToUpdate--; + + if(waitFramesToUpdate){ + ImGui::ClearActiveID(); + free(message); + } + + if(io->WantTextInput && !waitFramesToUpdate){ + message = (char*)malloc(length); + ImGuiInputTextState* state = ImGui::GetInputTextState(ImGui::GetActiveID()); + if(!state->InitialTextA.empty()){ + swkbdConfigSetInitialText(&kbd, state->InitialTextA.Data); + } + + Result rc = swkbdShow(&kbd, message, length); + + if(R_SUCCEEDED(rc)){ + state->ClearText(); + state->OverwriteData = &message[0]; + } + + waitFramesToUpdate = 2; + io->WantTextInput = false; + } + } + } +} +#endif + namespace MoonInternal { void setupImGuiModule(string status) { + MoonInternal::setupWindowHook(status); if(status == "PreStartup"){ Moon::registerHookListener({.hookName = WINDOW_API_INIT, .callback = [](HookCall call){ const char* glsl_version = "#version 120"; ImGuiContext* ctx = ImGui::CreateContext(); ImGui::SetCurrentContext(ctx); io = ImGui::GetIO(); (void)io; + io.WantSetMousePos = false; + io.ConfigWindowsMoveFromTitleBarOnly = true; for (auto entry = Moon::fonts.begin(); entry != Moon::fonts.end(); entry++){ ImFontConfig font_cfg; font_cfg.FontDataOwnedByAtlas = false; io.Fonts->AddFontFromMemoryTTF((void*) entry->second->data, entry->second->size, 18.f, &font_cfg); } ImGui::StyleColorsLightGreen(); - io.ConfigWindowsMoveFromTitleBarOnly = true; + MoonInternal::bindHook(IMGUI_API_INIT); MoonInternal::initBindHook(1, (struct HookParameter){.name = "io", .parameter = (void*) &io} @@ -82,6 +146,10 @@ namespace MoonInternal { window = (SDL_Window*) call.baseArgs["window"]; ImGui_ImplSDL2_InitForOpenGL(window, call.baseArgs["context"]); ImGui_ImplOpenGL3_Init(glsl_version); + + #ifdef TARGET_SWITCH + MoonNX::handleVirtualKeyboard("Init"); + #endif }}); Moon::registerHookListener({.hookName = WINDOW_API_HANDLE_EVENTS, .callback = [](HookCall call){ @@ -95,31 +163,43 @@ namespace MoonInternal { } }}); + Moon::registerHookListener({ GFX_POST_END_FRAME, [](HookCall call){ + // recv(socketID, NULL, 1, MSG_PEEK | MSG_DONTWAIT) != 0 + bool retval = 0; + ImGui_ImplOpenGL3_NewFrame(); ImGui_ImplSDL2_NewFrame(window); ImGui::NewFrame(); + #ifdef TARGET_SWITCH + MoonNX::handleVirtualKeyboard("FrameUpdate"); + #endif MoonInternal::bindHook(IMGUI_API_DRAW); MoonInternal::initBindHook(0); MoonInternal::callBindHook(0); + #ifdef GAME_DEBUG + if(showWindowDemo) + ImGui::ShowDemoWindow(NULL); if(showMenu){ ImGui::BeginMainMenuBar(); ImGui::MenuItem("Moon64", NULL, &showWindowMoon); + ImGui::MenuItem("ImGui Demo", NULL, &showWindowDemo); ImGui::EndMainMenuBar(); if (showWindowMoon){ ImGui::PushStyleColor(ImGuiCol_Border, ImVec4(0, 0, 0, 0)); - ImGui::Begin("Moon64 Game Stats", NULL, ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoMove); - ImGui::SetWindowPos(ImVec2(10, 35)); + ImGui::Begin("Moon64 Game Stats", NULL, ImGuiWindowFlags_None); + // ImGui::SetWindowPos(ImVec2(10, 35)); ImGui::Text("Platform: " PLATFORM " (" RAPI_NAME ")"); ImGui::Text("Status: %.3f ms/frame (%.1f FPS)", 1000.0f / ImGui::GetIO().Framerate, ImGui::GetIO().Framerate); ImGui::Text("Version: " GIT_BRANCH " " GIT_HASH); + ImGui::Text("NXLink: %d\n", retval); ImGui::End(); ImGui::PopStyleColor(); } } - + #endif ImGui::Render(); GLint last_program; glGetIntegerv(GL_CURRENT_PROGRAM, &last_program); diff --git a/src/moon/libs/imgui/imgui_draw.cpp b/src/moon/libs/imgui/imgui_draw.cpp index e22cf182..a0b310d2 100644 --- a/src/moon/libs/imgui/imgui_draw.cpp +++ b/src/moon/libs/imgui/imgui_draw.cpp @@ -250,6 +250,10 @@ void ImGui::StyleColorsDark(ImGuiStyle* dst) void ImGui::StyleColorsLightGreen(ImGuiStyle* dst) { ImGuiStyle* style = dst ? dst : &ImGui::GetStyle(); +#ifdef TARGET_SWITCH + style->ScaleAllSizes(3.0f); + style->TouchExtraPadding = ImVec2(5, 5); +#endif ImVec4* colors = style->Colors; colors[ImGuiCol_Text] = ImVec4(1.00f, 1.00f, 1.00f, 1.00f); diff --git a/src/moon/libs/imgui/imgui_impl_sdl.cpp b/src/moon/libs/imgui/imgui_impl_sdl.cpp index d3cd35af..e940aa96 100644 --- a/src/moon/libs/imgui/imgui_impl_sdl.cpp +++ b/src/moon/libs/imgui/imgui_impl_sdl.cpp @@ -47,10 +47,15 @@ #include "imgui.h" #include "imgui_impl_sdl.h" +#include "imgui_switch_impl.h" + +#include + +using namespace std; // SDL -#include -#include +#include +#include #if defined(__APPLE__) #include "TargetConditionals.h" #endif @@ -252,13 +257,13 @@ static void ImGui_ImplSDL2_UpdateMousePosAndButtons() io.MousePos = ImVec2(-FLT_MAX, -FLT_MAX); int mx, my; - Uint32 mouse_buttons = SDL_GetMouseState(&mx, &my); + Uint32 mouse_buttons = MoonInternal::Moon_GetMouseState(&mx, &my); io.MouseDown[0] = g_MousePressed[0] || (mouse_buttons & SDL_BUTTON(SDL_BUTTON_LEFT)) != 0; // If a mouse press event came, always pass it as "mouse held this frame", so we don't miss click-release events that are shorter than 1 frame. io.MouseDown[1] = g_MousePressed[1] || (mouse_buttons & SDL_BUTTON(SDL_BUTTON_RIGHT)) != 0; io.MouseDown[2] = g_MousePressed[2] || (mouse_buttons & SDL_BUTTON(SDL_BUTTON_MIDDLE)) != 0; g_MousePressed[0] = g_MousePressed[1] = g_MousePressed[2] = false; -#if SDL_HAS_CAPTURE_AND_GLOBAL_MOUSE && !defined(__EMSCRIPTEN__) && !defined(__ANDROID__) && !(defined(__APPLE__) && TARGET_OS_IOS) +#if SDL_HAS_CAPTURE_AND_GLOBAL_MOUSE && !defined(__EMSCRIPTEN__) && !defined(__ANDROID__) && !(defined(__APPLE__) && TARGET_OS_IOS) && !defined(TARGET_SWITCH) SDL_Window* focused_window = SDL_GetKeyboardFocus(); if (g_Window == focused_window) { @@ -281,8 +286,8 @@ static void ImGui_ImplSDL2_UpdateMousePosAndButtons() bool any_mouse_button_down = ImGui::IsAnyMouseDown(); SDL_CaptureMouse(any_mouse_button_down ? SDL_TRUE : SDL_FALSE); #else - if (SDL_GetWindowFlags(g_Window) & SDL_WINDOW_INPUT_FOCUS) - io.MousePos = ImVec2((float)mx, (float)my); + io.MousePos = ImVec2((float)mx, (float)my); + // cout << "ImGUI MX: " << io.MousePos.x << " MY: " << io.MousePos.y << " MS: " << mouse_buttons << endl; #endif } diff --git a/src/moon/libs/imgui/imgui_internal.h b/src/moon/libs/imgui/imgui_internal.h index 8006246b..22bd0b72 100644 --- a/src/moon/libs/imgui/imgui_internal.h +++ b/src/moon/libs/imgui/imgui_internal.h @@ -1032,6 +1032,7 @@ struct IMGUI_API ImGuiInputTextState ImGuiInputTextFlags Flags; // copy of InputText() flags ImGuiInputTextCallback UserCallback; // " void* UserCallbackData; // " + char* OverwriteData; ImGuiInputTextState() { memset(this, 0, sizeof(*this)); } void ClearText() { CurLenW = CurLenA = 0; TextW[0] = 0; TextA[0] = 0; CursorClamp(); } diff --git a/src/moon/libs/imgui/imgui_switch_impl.cpp b/src/moon/libs/imgui/imgui_switch_impl.cpp new file mode 100644 index 00000000..cf9e1adc --- /dev/null +++ b/src/moon/libs/imgui/imgui_switch_impl.cpp @@ -0,0 +1,67 @@ +#include "imgui_switch_impl.h" +#include "moon/mod-engine/hooks/hook.h" + +#include +#include +#include + +#ifdef TARGET_SWITCH +#include +#endif + +using namespace std; + +namespace Platform { +#ifdef TARGET_SWITCH + bool isSwitch = true; +#else + bool isSwitch = false; +#endif +} + +namespace MoonInternal { + + int mouseX = -9999; + int mouseY = -9999; + u32 mstate; + +#ifdef TARGET_SWITCH + HidTouchScreenState state; + s32 prev_touchcount; +#endif + + void setupWindowHook(string status){ + if(status == "PreStartup"){ + #ifdef TARGET_SWITCH + hidInitializeTouchScreen(); + #endif + Moon::registerHookListener({.hookName = WINDOW_API_START_FRAME, .callback = [](HookCall call){ + #ifndef TARGET_SWITCH + mstate = SDL_GetMouseState(&mouseX, &mouseY); + cout << "MouseX: " << mouseX << " MouseY: " << mouseY << " Mouse State: " << mstate << endl; + #else + if (hidGetTouchScreenStates(&state, 1)) { + if (state.count != prev_touchcount) { + prev_touchcount = state.count; + } + + if (state.count < prev_touchcount){ + mstate = 0; + } + + for(s32 i = 0; i < state.count; i++) { + mouseX = state.touches[0].x; + mouseY = state.touches[0].y; + mstate = 1; + } + } + #endif + } + } + + u32 Moon_GetMouseState(int *x, int *y){ + *x = mouseX; + *y = mouseY; + return mstate; + } +} \ No newline at end of file diff --git a/src/moon/libs/imgui/imgui_switch_impl.h b/src/moon/libs/imgui/imgui_switch_impl.h new file mode 100644 index 00000000..97b4f25f --- /dev/null +++ b/src/moon/libs/imgui/imgui_switch_impl.h @@ -0,0 +1,15 @@ +#ifndef SWITCH_IMGUI_IMPL +#define SWITCH_IMGUI_IMPL + +#include + +extern "C"{ +#include "types.h" +} + +namespace MoonInternal { + void setupWindowHook(std::string status); + u32 Moon_GetMouseState(int *x, int *y); +} + +#endif \ No newline at end of file diff --git a/src/moon/libs/imgui/imgui_widgets.cpp b/src/moon/libs/imgui/imgui_widgets.cpp index 46d2174f..a0ca37b8 100644 --- a/src/moon/libs/imgui/imgui_widgets.cpp +++ b/src/moon/libs/imgui/imgui_widgets.cpp @@ -4167,6 +4167,7 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_ const bool is_paste = ((is_shortcut_key && IsKeyPressedMap(ImGuiKey_V)) || (is_shift_key_only && IsKeyPressedMap(ImGuiKey_Insert))) && !is_readonly; const bool is_undo = ((is_shortcut_key && IsKeyPressedMap(ImGuiKey_Z)) && !is_readonly && is_undoable); const bool is_redo = ((is_shortcut_key && IsKeyPressedMap(ImGuiKey_Y)) || (is_osx_shift_shortcut && IsKeyPressedMap(ImGuiKey_Z))) && !is_readonly && is_undoable; + const bool is_overwrite = state->OverwriteData != NULL; if (IsKeyPressedMap(ImGuiKey_LeftArrow)) { state->OnKeyPressed((is_startend_key_down ? STB_TEXTEDIT_K_LINESTART : is_wordmove_key_down ? STB_TEXTEDIT_K_WORDLEFT : STB_TEXTEDIT_K_LEFT) | k_mask); } else if (IsKeyPressedMap(ImGuiKey_RightArrow)) { state->OnKeyPressed((is_startend_key_down ? STB_TEXTEDIT_K_LINEEND : is_wordmove_key_down ? STB_TEXTEDIT_K_WORDRIGHT : STB_TEXTEDIT_K_RIGHT) | k_mask); } @@ -4237,9 +4238,9 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_ stb_textedit_cut(state, &state->Stb); } } - else if (is_paste) + else if (is_paste || is_overwrite) { - if (const char* clipboard = GetClipboardText()) + if (const char* clipboard = is_overwrite ? state->OverwriteData : GetClipboardText()) { // Filter pasted buffer const int clipboard_len = (int)strlen(clipboard); @@ -4261,6 +4262,7 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_ stb_textedit_paste(state, &state->Stb, clipboard_filtered, clipboard_filtered_len); state->CursorFollow = true; } + if(is_overwrite) state->OverwriteData = NULL; MemFree(clipboard_filtered); } } diff --git a/src/moon/mod-engine/hooks/hook.h b/src/moon/mod-engine/hooks/hook.h index 91c9567d..89c9cfd9 100644 --- a/src/moon/mod-engine/hooks/hook.h +++ b/src/moon/mod-engine/hooks/hook.h @@ -19,6 +19,7 @@ struct HookParameter { #define WINDOW_API_INIT "WApiInit" #define WINDOW_API_HANDLE_EVENTS "WApiHandleEvents" +#define WINDOW_API_START_FRAME "WApiStartFrame" // Graphics API Hooks #define GFX_PRE_START_FRAME "GFXApiPreStartFrame" diff --git a/src/nx/m_nx.c b/src/nx/m_nx.c index 37933d31..8bc44199 100644 --- a/src/nx/m_nx.c +++ b/src/nx/m_nx.c @@ -4,10 +4,12 @@ #include "m_nx.h" +int socketID = -1; + void initNX(){ appletInitializeGamePlayRecording(); socketInitializeDefault(); - nxlinkStdio(); + socketID = nxlinkStdio(); appletSetGamePlayRecordingState(1); Result rc = psmInitialize(); diff --git a/src/nx/m_nx.h b/src/nx/m_nx.h index 9654a835..af672768 100644 --- a/src/nx/m_nx.h +++ b/src/nx/m_nx.h @@ -1,6 +1,7 @@ #ifndef NX_MODULE #define NX_MODULE +extern int socketID; void initNX(); void exitNX(); float getBatteryPercentage(); diff --git a/src/pc/gfx/gfx_sdl2.c b/src/pc/gfx/gfx_sdl2.c index da72b4c1..464ce018 100644 --- a/src/pc/gfx/gfx_sdl2.c +++ b/src/pc/gfx/gfx_sdl2.c @@ -40,7 +40,7 @@ #ifdef TARGET_SWITCH // can't include or even because // the basic libnx types have the same names as some of the types in this -extern int appletGetOperationMode(void); +#include #include "glad/glad.h" #endif @@ -334,6 +334,15 @@ static void gfx_sdl_onkeyup(int scancode) { } static void gfx_sdl_handle_events(void) { + moon_bind_hook(WINDOW_API_START_FRAME); + moon_init_hook(1, + (struct HookParameter){ + .name = "window", + .parameter = wnd + } + ); + moon_call_hook(0); + SDL_Event event; while (SDL_PollEvent(&event)) { moon_bind_hook(WINDOW_API_HANDLE_EVENTS);