From 06dc4f89c455b280419c18ac0726ee57da438390 Mon Sep 17 00:00:00 2001 From: gggaa2152 <60614405+gggaa2152@users.noreply.github.com> Date: Mon, 6 Apr 2026 10:13:02 +0800 Subject: [PATCH] Update main.cpp --- main.cpp | 154 +++++++++++++++++++++++-------------------------------- 1 file changed, 64 insertions(+), 90 deletions(-) diff --git a/main.cpp b/main.cpp index 0a95feee1..1c49efe5a 100644 --- a/main.cpp +++ b/main.cpp @@ -10,132 +10,104 @@ #include "dobby.h" #include #include -#include -#define LOG_TAG "AndKitty_Diag" +#define LOG_TAG "AndKitty_Menu" #define LOGI(...) __android_log_print(ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__) -// --- 诊断数据结构 --- -static struct { - bool initialized = false; - bool show_menu = true; - float screen_w = 0, screen_h = 0; - - // 捕获到的实时数据 - float raw_x = 0, raw_y = 0; - int last_action = -1; - int event_counter = 0; - double last_frame_time = 0; - float current_delta = 0; -} g_Data; +// --- 全局状态 --- +static bool g_Initialized = false; +static bool g_ShowMenu = true; +static float g_Width = 0, g_Height = 0; + +// 记录触摸 +struct { + float x, y; + bool down; +} g_Touch = {0, 0, false}; // --- 原函数指针 --- -typedef int (*p_AInputQueue_getEvent)(AInputQueue* queue, AInputEvent** out_event); -static p_AInputQueue_getEvent old_getEvent = nullptr; +typedef int32_t (*p_getPointerId)(const AInputEvent* motion_event, size_t pointer_index); +static p_getPointerId old_getPointerId = nullptr; typedef EGLBoolean (*p_eglSwapBuffers)(EGLDisplay dpy, EGLSurface surface); static p_eglSwapBuffers old_eglSwapBuffers = nullptr; -double get_now() { - struct timespec res; - clock_gettime(CLOCK_MONOTONIC, &res); - return (double)res.tv_sec + (double)res.tv_nsec / 1e9; -} - -// --- 核心诊断 Hook --- -int hook_AInputQueue_getEvent(AInputQueue* queue, AInputEvent** out_event) { - int res = old_getEvent(queue, out_event); - if (res >= 0 && out_event && *out_event && g_Data.initialized) { - AInputEvent* event = *out_event; - +// --- 稳定的坐标获取方案 --- +int32_t hook_getPointerId(const AInputEvent* event, size_t index) { + if (g_ShowMenu && event != nullptr) { if (AInputEvent_getType(event) == AINPUT_EVENT_TYPE_MOTION) { - g_Data.event_counter++; - g_Data.last_action = AMotionEvent_getAction(event) & AMOTION_EVENT_ACTION_MASK; - g_Data.raw_x = AMotionEvent_getX(event, 0); - g_Data.raw_y = AMotionEvent_getY(event, 0); + int32_t action = AMotionEvent_getAction(event) & AMOTION_EVENT_ACTION_MASK; + + // 获取手指 0 的绝对坐标 + float x = AMotionEvent_getX(event, 0); + float y = AMotionEvent_getY(event, 0); - if (g_Data.show_menu) { - ImGuiIO& io = ImGui::GetIO(); - // 强制修正:手动同步坐标 - io.MousePos = ImVec2(g_Data.raw_x, g_Data.raw_y); - - if (g_Data.last_action == AMOTION_EVENT_ACTION_DOWN) io.MouseDown[0] = true; - else if (g_Data.last_action == AMOTION_EVENT_ACTION_UP) io.MouseDown[0] = false; + // 过滤非法值,防止之前出现的天文数字 + if (x >= 0 && y >= 0 && x < 4000 && y < 4000) { + g_Touch.x = x; + g_Touch.y = y; - // 依然让官方后端跑一下,处理多指逻辑 - ImGui_ImplAndroid_HandleInputEvent(event); - - // 【诊断关键点】再次强行锁死坐标,防止 HandleInputEvent 内部由于 Window 指针丢失导致的负数崩溃 - io.MousePos = ImVec2(g_Data.raw_x, g_Data.raw_y); + if (action == AMOTION_EVENT_ACTION_DOWN || action == AMOTION_EVENT_ACTION_POINTER_DOWN) { + g_Touch.down = true; + } else if (action == AMOTION_EVENT_ACTION_UP || action == AMOTION_EVENT_ACTION_POINTER_UP || action == AMOTION_EVENT_ACTION_CANCEL) { + g_Touch.down = false; + } } } } - return res; + return old_getPointerId(event, index); } +// --- 渲染逻辑 --- EGLBoolean hook_eglSwapBuffers(EGLDisplay dpy, EGLSurface surface) { - double now = get_now(); - - if (g_Data.screen_w <= 0) { + if (g_Width <= 0) { EGLint w, h; eglQuerySurface(dpy, surface, EGL_WIDTH, &w); eglQuerySurface(dpy, surface, EGL_HEIGHT, &h); - g_Data.screen_w = (float)w; g_Data.screen_h = (float)h; + g_Width = (float)w; g_Height = (float)h; } - if (!g_Data.initialized) { + if (!g_Initialized) { ImGui::CreateContext(); ImGuiIO& io = ImGui::GetIO(); - io.DisplaySize = ImVec2(g_Data.screen_w, g_Data.screen_h); + io.DisplaySize = ImVec2(g_Width, g_Height); io.ConfigFlags |= ImGuiConfigFlags_IsTouchScreen; ImGui_ImplOpenGL3_Init("#version 300 es"); - ImGui_ImplAndroid_Init(nullptr); - + + // 注意:不调用 ImGui_ImplAndroid_Init,我们手动处理 IO ImGui::StyleColorsDark(); ImGui::GetStyle().ScaleAllSizes(3.0f); - g_Data.initialized = true; - g_Data.last_frame_time = now; + g_Initialized = true; + LOGI("ImGui Simple Ready: %.fx%.f", g_Width, g_Height); } - // 每一帧更新时间,否则无法拖拽 + // 核心:强制同步 IO 状态 ImGuiIO& io = ImGui::GetIO(); - g_Data.current_delta = (float)(now - g_Data.last_frame_time); - io.DeltaTime = (g_Data.current_delta > 0) ? g_Data.current_delta : (1.0f/60.0f); - g_Data.last_frame_time = now; + io.MousePos = ImVec2(g_Touch.x, g_Touch.y); + io.MouseDown[0] = g_Touch.down; + + // 固定的 DeltaTime 保证拖拽逻辑不失效 + io.DeltaTime = 1.0f / 60.0f; ImGui_ImplOpenGL3_NewFrame(); - ImGui_ImplAndroid_NewFrame(); ImGui::NewFrame(); - if (g_Data.show_menu) { - ImGui::SetNextWindowSize(ImVec2(750, 550), ImGuiCond_FirstUseEver); - if (ImGui::Begin("AndKitty Diagnosis Tool", &g_Data.show_menu)) { - - // --- 诊断面板 --- - ImGui::TextColored(ImVec4(1, 1, 0, 1), "SYSTEM STATUS:"); - ImGui::Text("Screen: %.0f x %.0f", g_Data.screen_w, g_Data.screen_h); - ImGui::Text("DeltaTime: %.4f", io.DeltaTime); - ImGui::Text("Total Events: %d", g_Data.event_counter); + if (g_ShowMenu) { + ImGui::SetNextWindowPos(ImVec2(100, 100), ImGuiCond_FirstUseEver); + ImGui::SetNextWindowSize(ImVec2(600, 450), ImGuiCond_FirstUseEver); + + if (ImGui::Begin("AndKitty SGame Lite", &g_ShowMenu)) { + ImGui::Text("Diagnosis:"); + ImGui::BulletText("Pos: %.1f, %.1f", io.MousePos.x, io.MousePos.y); + ImGui::BulletText("Down: %s", io.MouseDown[0] ? "True" : "False"); ImGui::Separator(); - ImGui::TextColored(ImVec4(0, 1, 1, 1), "INPUT TRACKING:"); - ImGui::Text("Raw NDK Pos: %.1f, %.1f", g_Data.raw_x, g_Data.raw_y); - ImGui::Text("ImGui IO Pos: %.1f, %.1f", io.MousePos.x, io.MousePos.y); - ImGui::Text("Action Code: %d (%s)", g_Data.last_action, io.MouseDown[0] ? "DOWN" : "UP"); + static float f = 0.5f; + ImGui::SliderFloat("Slider Test", &f, 0.0f, 1.0f); - ImGui::Separator(); - ImGui::TextColored(ImVec4(1, 0, 1, 1), "CAPTURE TEST:"); - ImGui::Checkbox("Capture Mouse?", &io.WantCaptureMouse); - - static float test_f = 0.5f; - ImGui::SliderFloat("Drag Logic Test", &test_f, 0.0f, 1.0f); - - if (ImGui::Button("Reset Counter")) g_Data.event_counter = 0; - - ImGui::Separator(); - ImGui::TextWrapped("GUIDE: If 'Raw NDK Pos' moves but 'ImGui IO Pos' does not, the override failed."); + if (ImGui::Button("Close Menu")) g_ShowMenu = false; } ImGui::End(); } @@ -146,19 +118,21 @@ EGLBoolean hook_eglSwapBuffers(EGLDisplay dpy, EGLSurface surface) { } void* init_thread(void*) { - sleep(10); // 等待游戏加载 + // 注入后只等 2 秒,确保 libandroid.so 加载 + sleep(2); void* egl = dlsym(RTLD_DEFAULT, "eglSwapBuffers"); if (egl) DobbyHook(egl, (void*)hook_eglSwapBuffers, (void**)&old_eglSwapBuffers); void* libandroid = dlopen("libandroid.so", RTLD_NOW); if (libandroid) { - void* getEvent = dlsym(libandroid, "AInputQueue_getEvent"); - if (getEvent) { - DobbyHook(getEvent, (void*)hook_AInputQueue_getEvent, (void**)&old_getEvent); - LOGI("Diagnostics Hooked Successfully."); + void* getPointerId = dlsym(libandroid, "AMotionEvent_getPointerId"); + if (getPointerId) { + DobbyHook(getPointerId, (void*)hook_getPointerId, (void**)&old_getPointerId); + LOGI("Touch Hook Applied."); } } + return nullptr; }