From 360b729141e1a67c26d394b2407f825bd5a071f3 Mon Sep 17 00:00:00 2001 From: gggaa2152 <60614405+gggaa2152@users.noreply.github.com> Date: Mon, 6 Apr 2026 19:15:46 +0800 Subject: [PATCH] Update main.cpp --- main.cpp | 78 ++++++++++++++++++++++++++++---------------------------- 1 file changed, 39 insertions(+), 39 deletions(-) diff --git a/main.cpp b/main.cpp index 08684f040..fab2fbd8d 100644 --- a/main.cpp +++ b/main.cpp @@ -10,17 +10,17 @@ #include "imgui_impl_android.h" #include "imgui_impl_opengl3.h" -#define TAG "AndKitty_Fixer" +#define TAG "AndKitty_Menu" #define LOGI(...) __android_log_print(ANDROID_LOG_INFO, TAG, __VA_ARGS__) static bool g_Initialized = false; static bool g_ShowMenu = true; -// 存储最终计算出的自适应坐标 +// 最终映射后的坐标 struct { float x, y; bool down; -} g_Touch = {0, 0, false}; +} g_FinalTouch = {0, 0, false}; typedef EGLBoolean (*p_eglSwapBuffers)(EGLDisplay dpy, EGLSurface surface); static p_eglSwapBuffers old_eglSwapBuffers = nullptr; @@ -28,50 +28,48 @@ static p_eglSwapBuffers old_eglSwapBuffers = nullptr; typedef int (*p_InputConsumer_consume)(void* instance, void* factory, bool consumeBatches, int64_t frameTime, uint32_t* outSeq, void** outEvent); static p_InputConsumer_consume old_consume = nullptr; -// 自适应处理核心函数 -void handle_adaptive_event(void* event, float renderW, float renderH) { +// 获取系统内置转换 +typedef float (*p_getAxisValue)(void* event, int32_t axis, size_t pointerIndex); +static p_getAxisValue g_getAxisValue = nullptr; + +void process_input_event(void* event, float screenW, float screenH) { if (!event) return; + static auto _getType = (int (*)(void*))dlsym(RTLD_DEFAULT, "AInputEvent_getType"); static auto _getAction = (int (*)(void*))dlsym(RTLD_DEFAULT, "AMotionEvent_getAction"); - - // NDK 原生 API static auto _getX = (float (*)(void*, size_t))dlsym(RTLD_DEFAULT, "AMotionEvent_getX"); static auto _getY = (float (*)(void*, size_t))dlsym(RTLD_DEFAULT, "AMotionEvent_getY"); - // 尝试获取原始坐标和物理范围 - // 在窗口模式下,RawX/Y 通常是屏幕物理像素,而 getX/Y 往往已经被系统转换到了窗口局部坐标 - if (_getType && _getType(event) == 1) { // AINPUT_EVENT_TYPE_MOTION + if (_getType && _getType(event) == 1) { // MotionEvent int action = _getAction(event) & 0xff; - /* * 自适应原理: - * 大多数 Android 窗口系统在分发事件给 InputConsumer 时, - * 已经将坐标转换为了相对于 Surface 的局部坐标。 - * 如果点不准,通常是因为 ImGui 渲染的分辨率与窗口实际 Surface 分辨率不一致。 + /* * 自适应核心逻辑: + * 在窗口化模式下,AInputEvent_getX 返回的是相对于窗口(Surface)的坐标。 + * 但是,这个坐标的单位是系统的“逻辑单位”(例如 3392x2400)。 + * 我们需要根据 ImGui 实际渲染的窗口大小 (renderW/H) 进行二次比例转换。 */ - float rawX = _getX(event, 0); - float rawY = _getY(event, 0); + float sysX = _getX(event, 0); + float sysY = _getY(event, 0); - // 如果你的 dumpsys 显示 Requested w=3392 而 ImGui 是 1426 - // 我们需要做一个简单的动态比例缩放 - // 这里的 3392.0f 和 2400.0f 是从你 dumpsys 里的 Requested w/h 获取的 - float containerW = 3392.0f; - float containerH = 2400.0f; + // 这里 3392 和 2400 是根据你 dumpsys 里的物理逻辑尺寸 + // 如果是全屏,这两个值通常等于 renderW/H,比例就是 1:1 + // 如果是分屏,系统会自动处理偏移,我们只需要缩放比例 + float designW = 3392.0f; + float designH = 2400.0f; - g_Touch.x = (rawX / containerW) * renderW; - g_Touch.y = (rawY / containerH) * renderH; + g_FinalTouch.x = (sysX / designW) * screenW; + g_FinalTouch.y = (sysY / designH) * screenH; - if (action == 0) g_Touch.down = true; - else if (action == 1 || action == 3) g_Touch.down = false; + if (action == 0) g_FinalTouch.down = true; + else if (action == 1 || action == 3) g_FinalTouch.down = false; } } int hook_consume(void* a, void* b, bool c, int64_t d, uint32_t* e, void** f) { int res = old_consume(a, b, c, d, e, f); - // 注意:在这里我们还拿不到渲染窗口的宽高,所以只存下原始事件 - // 具体的坐标转换放在 eglSwapBuffers 里实时计算 if (res == 0 && f && *f) { - // 传递当前全局事件指针 - handle_adaptive_event(*f, ImGui::GetIO().DisplaySize.x, ImGui::GetIO().DisplaySize.y); + // 在此处捕获坐标 + process_input_event(*f, ImGui::GetIO().DisplaySize.x, ImGui::GetIO().DisplaySize.y); } return res; } @@ -91,24 +89,24 @@ EGLBoolean hook_eglSwapBuffers(EGLDisplay dpy, EGLSurface surface) { ImGuiIO& io = ImGui::GetIO(); io.DisplaySize = ImVec2((float)w, (float)h); - // 应用自适应坐标 - io.MousePos = ImVec2(g_Touch.x, g_Touch.y); - io.MouseDown[0] = g_Touch.down; + // 映射坐标到 ImGui + io.MousePos = ImVec2(g_FinalTouch.x, g_FinalTouch.y); + io.MouseDown[0] = g_FinalTouch.down; ImGui_ImplOpenGL3_NewFrame(); ImGui::NewFrame(); - if (g_Touch.down) { - // 画出红色触控点,用于验证自适应是否成功 - ImGui::GetBackgroundDrawList()->AddCircleFilled(io.MousePos, 20.0f, IM_COL32(255, 0, 0, 255)); + // 可视化调试:在触碰点画一个圆 + if (g_FinalTouch.down) { + ImGui::GetBackgroundDrawList()->AddCircleFilled(io.MousePos, 20.0f, IM_COL32(0, 255, 0, 255)); } if (g_ShowMenu) { - ImGui::Begin("AndKitty Adaptive Menu", &g_ShowMenu); - ImGui::Text("Window Size: %.0f x %.0f", io.DisplaySize.x, io.DisplaySize.y); - ImGui::Text("Touch Logic Pos: %.1f, %.1f", g_Touch.x, g_Touch.y); + ImGui::Begin("AndKitty Universal Fixer", &g_ShowMenu); + ImGui::Text("Render Res: %d x %d", w, h); + ImGui::Text("Calculated Pos: %.1f, %.1f", g_FinalTouch.x, g_FinalTouch.y); - if (ImGui::Button("隐藏菜单", ImVec2(-1, 80))) g_ShowMenu = false; + if (ImGui::Button("Close", ImVec2(-1, 80))) g_ShowMenu = false; ImGui::End(); } @@ -125,6 +123,8 @@ void* init_thread(void*) { const char* sym = "_ZN7android13InputConsumer7consumeEPNS_26InputEventFactoryInterfaceEblPjPPNS_10InputEventE"; void* consume = DobbySymbolResolver("libinput.so", sym); if (consume) DobbyHook(consume, (void*)hook_consume, (void**)&old_consume); + + g_getAxisValue = (p_getAxisValue)dlsym(RTLD_DEFAULT, "AMotionEvent_getAxisValue"); return nullptr; }