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
ImGui.h
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: