Help! ImGui cannot be touched when implement into UnityGame (Emulator)

Shawn Dao

Platinian
As the title, when i implement the ImGui into UnityGame, the ImGui cannot be touched.
If i implement the ImGui into Cocos2d, it just works.

ImGui implementations in UnityGame and Cocos2d are identical.

The first game in the below VIdeo is Cocos2d, the 2 others are Unity

Note: Everything works just fine on real device. Issue only happen in Emulators




Main.cpp
Code:
// Global menu instance
Menu * g_menu = nullptr;
bool g_menuInitialized = false;

void DrawMenu() {
  if (g_menu == nullptr) {
    LOGI(OBFUSCATE("[DEBUG] Creating new Menu instance"));
    g_menu = new Menu();
  }

  // Initialize on first draw (which happens on main thread)
  if (!g_menuInitialized && g_menu != nullptr) {
    LOGI(OBFUSCATE("[DEBUG] Initializing menu for first time"));
    g_menu -> Initialize();
    g_menuInitialized = true;
    LOGI(OBFUSCATE("[DEBUG] Menu initialization complete"));
  }

  if (g_menu != nullptr) {
    g_menu -> Draw();
  } else {
    LOGE(OBFUSCATE("[ERROR] Menu pointer is null in DrawMenu()"));
  }
}

void * thread(void * ) {
  LOGI(OBFUSCATE("[DEBUG] Initializing Menu"));
  initModMenu((void * ) DrawMenu);

  LOGI(OBFUSCATE("[DEBUG] Main thread exiting"));
  pthread_exit(0);
}

__attribute__((constructor))
void init() {
  LOGI(OBFUSCATE("[DEBUG] init() called - Loading Mod Menu"));

  pthread_t t;
  if (pthread_create( & t, nullptr, thread, nullptr) != 0) {
    LOGE(OBFUSCATE("[ERROR] Failed to create thread"));
    return;
  }
  LOGI(OBFUSCATE("[DEBUG] Thread created successfully"));

  //Don't leave any traces, remap the loader lib as well
  RemapTools::RemapLibrary("libLoader.so");
}

ImGui.h
Code:
void menuStyle();
void( * menuAddress)();

using swapbuffers_orig = EGLBoolean( * )(EGLDisplay dpy, EGLSurface surf);
EGLBoolean swapbuffers_hook(EGLDisplay dpy, EGLSurface surf);
swapbuffers_orig o_swapbuffers = nullptr;

bool isInitialized = false;
int glWidth = 0;
int glHeight = 0;

//This menu_addr is used to allow for multiple game support in the future
void * initModMenu(void * menu_addr) {
  LOGI(OBFUSCATE("[DEBUG] initModMenu started with menu_addr: %p"), menu_addr);
  menuAddress = (void( * )()) menu_addr;
  do {
    sleep(1);
  } while (!isLibraryLoaded(OBFUSCATE("libEGL.so")));
  LOGI(OBFUSCATE("[DEBUG] libEGL.so loaded successfully"));

  auto swapBuffers = ((uintptr_t) DobbySymbolResolver(OBFUSCATE("libEGL.so"), OBFUSCATE("eglSwapBuffers")));
  LOGI(OBFUSCATE("[DEBUG] SwapBuffers address resolved: %p"), (void * ) swapBuffers);

  KittyMemory::setAddressProtection((void * ) swapBuffers, sizeof(swapBuffers), PROT_READ | PROT_WRITE | PROT_EXEC);
  LOGI(OBFUSCATE("[DEBUG] Memory protection set for SwapBuffers"));

  DobbyHook((void * ) swapBuffers, (void * ) swapbuffers_hook, (void ** ) & o_swapbuffers);
  LOGI(OBFUSCATE("[DEBUG] SwapBuffers hook installed"));

  return nullptr;
}

void setupMenu() {
  if (isInitialized) return;

  auto ctx = ImGui::CreateContext();
  if (!ctx) {
    return;
  }

  ImGuiIO & io = ImGui::GetIO();
  io.DisplaySize = ImVec2((float) glWidth, (float) glHeight);
  io.ConfigWindowsMoveFromTitleBarOnly = true;
  io.IniFilename = nullptr;

  // Setup Platform/Renderer backends
  ImGui_ImplAndroid_Init();

  ImGui_ImplOpenGL3_Init("#version 300 es");

  int systemScale = (1.0 / glWidth) * glWidth;
  ImFontConfig font_cfg;
  font_cfg.SizePixels = systemScale * 22.0 f;
  io.Fonts -> AddFontFromMemoryTTF(CustomFont, systemScale * 25.0, 35.0 f);

  ImGui::GetStyle().ScaleAllSizes(2);

  isInitialized = true;
}

void internalDrawMenu(int width, int height) {
  if (!isInitialized) {
    return;
  }

  ImGuiIO & io = ImGui::GetIO();

  ImGui_ImplOpenGL3_NewFrame();
  ImGui_ImplAndroid_NewFrame(width, height);
  ImGui::NewFrame();

  menuAddress();

  ImGui::Render();

  ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData());
}

EGLBoolean swapbuffers_hook(EGLDisplay dpy, EGLSurface surf) {
  EGLint w, h;
  eglQuerySurface(dpy, surf, EGL_WIDTH, & w);
  eglQuerySurface(dpy, surf, EGL_HEIGHT, & h);
  glWidth = w;
  glHeight = h;

  setupMenu();
  internalDrawMenu(w, h);

  return o_swapbuffers(dpy, surf);
}
 
Last edited:
Back
Top Bottom