mirror of https://github.com/sm64pc/sm64pc.git
Added switch imgui input support and some fixes
This commit is contained in:
parent
00b5bec4be
commit
24513256f7
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
||||
|
|
|
@ -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(); }
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -4,10 +4,12 @@
|
|||
|
||||
#include "m_nx.h"
|
||||
|
||||
int socketID = -1;
|
||||
|
||||
void initNX(){
|
||||
appletInitializeGamePlayRecording();
|
||||
socketInitializeDefault();
|
||||
nxlinkStdio();
|
||||
socketID = nxlinkStdio();
|
||||
appletSetGamePlayRecordingState(1);
|
||||
|
||||
Result rc = psmInitialize();
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
#ifndef NX_MODULE
|
||||
#define NX_MODULE
|
||||
|
||||
extern int socketID;
|
||||
void initNX();
|
||||
void exitNX();
|
||||
float getBatteryPercentage();
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue