Added switch imgui input support and some fixes

This commit is contained in:
KiritoDev 2021-07-24 18:16:52 -05:00
parent 00b5bec4be
commit 24513256f7
12 changed files with 212 additions and 15 deletions

View File

@ -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 <switch/types.h>
#endif
#endif
typedef float f32;
typedef double f64;
@ -33,7 +43,7 @@ typedef double f64;
#include <stdint.h>
#include <sys/types.h>
#if defined(__MINGW32__)
#if defined(__MINGW32__)
#include <_mingw.h>
#if !defined(__MINGW64_VERSION_MAJOR)
typedef long ssize_t;

View File

@ -4,8 +4,10 @@
#include <iostream>
#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 <switch.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <sys/errno.h>
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);

View File

@ -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);

View File

@ -47,10 +47,15 @@
#include "imgui.h"
#include "imgui_impl_sdl.h"
#include "imgui_switch_impl.h"
#include <iostream>
using namespace std;
// SDL
#include <SDL.h>
#include <SDL_syswm.h>
#include <SDL2/SDL.h>
#include <SDL2/SDL_syswm.h>
#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
}

View File

@ -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(); }

View File

@ -0,0 +1,67 @@
#include "imgui_switch_impl.h"
#include "moon/mod-engine/hooks/hook.h"
#include <SDL2/SDL.h>
#include <string>
#include <iostream>
#ifdef TARGET_SWITCH
#include <switch.h>
#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;
}
}

View File

@ -0,0 +1,15 @@
#ifndef SWITCH_IMGUI_IMPL
#define SWITCH_IMGUI_IMPL
#include <string>
extern "C"{
#include "types.h"
}
namespace MoonInternal {
void setupWindowHook(std::string status);
u32 Moon_GetMouseState(int *x, int *y);
}
#endif

View File

@ -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);
}
}

View File

@ -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"

View File

@ -4,10 +4,12 @@
#include "m_nx.h"
int socketID = -1;
void initNX(){
appletInitializeGamePlayRecording();
socketInitializeDefault();
nxlinkStdio();
socketID = nxlinkStdio();
appletSetGamePlayRecordingState(1);
Result rc = psmInitialize();

View File

@ -1,6 +1,7 @@
#ifndef NX_MODULE
#define NX_MODULE
extern int socketID;
void initNX();
void exitNX();
float getBatteryPercentage();

View File

@ -40,7 +40,7 @@
#ifdef TARGET_SWITCH
// can't include <switch.h> or even <switch/services/applet.h> because
// the basic libnx types have the same names as some of the types in this
extern int appletGetOperationMode(void);
#include <switch.h>
#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);