Fix Mouse Cursor Bugs
This commit is contained in:
parent
0f6c3c2e43
commit
747d2032e6
@ -1,5 +1,8 @@
|
|||||||
# Changelog
|
# Changelog
|
||||||
|
|
||||||
|
**2.0.2**
|
||||||
|
* Fix Mouse Cursor Bugs
|
||||||
|
|
||||||
**2.0.1**
|
**2.0.1**
|
||||||
* Fix Blank Screen On Twister OS
|
* Fix Blank Screen On Twister OS
|
||||||
|
|
||||||
|
@ -12,6 +12,9 @@ typedef uint32_t bool;
|
|||||||
|
|
||||||
// Globals
|
// Globals
|
||||||
|
|
||||||
|
typedef void (*renderCursor_t)(float x, float y, unsigned char *minecraft);
|
||||||
|
static renderCursor_t renderCursor = (renderCursor_t) 0x480c4;
|
||||||
|
|
||||||
static char **default_path = (char **) 0xe264; // /.minecraft/
|
static char **default_path = (char **) 0xe264; // /.minecraft/
|
||||||
static char **default_username = (char **) 0x18fd4; // StevePi
|
static char **default_username = (char **) 0x18fd4; // StevePi
|
||||||
|
|
||||||
@ -120,6 +123,20 @@ static uint32_t Minecraft_command_server_property_offset = 0xcc0; // CommandServ
|
|||||||
static uint32_t Minecraft_screen_property_offset = 0xc10; // Screen *
|
static uint32_t Minecraft_screen_property_offset = 0xc10; // Screen *
|
||||||
static uint32_t Minecraft_gui_property_offset = 0x198; // Gui
|
static uint32_t Minecraft_gui_property_offset = 0x198; // Gui
|
||||||
|
|
||||||
|
// GameRenderer
|
||||||
|
|
||||||
|
typedef void (*GameRenderer_render_t)(unsigned char *game_renderer, float param_1);
|
||||||
|
static GameRenderer_render_t GameRenderer_render = (GameRenderer_render_t) 0x4a338;
|
||||||
|
|
||||||
|
static uint32_t GameRenderer_minecraft_property_offset = 0x4; // Minecraft *
|
||||||
|
|
||||||
|
// Mouse
|
||||||
|
|
||||||
|
typedef int (*Mouse_get_t)();
|
||||||
|
|
||||||
|
static Mouse_get_t Mouse_getX = (Mouse_get_t) 0x1385c;
|
||||||
|
static Mouse_get_t Mouse_getY = (Mouse_get_t) 0x1386c;
|
||||||
|
|
||||||
// CommandServer
|
// CommandServer
|
||||||
|
|
||||||
static uint32_t CommandServer_minecraft_property_offset = 0x18; // Minecraft *
|
static uint32_t CommandServer_minecraft_property_offset = 0x18; // Minecraft *
|
||||||
|
@ -280,39 +280,82 @@ void media_cleanup() {
|
|||||||
#endif // #ifndef MCPI_SERVER_MODE
|
#endif // #ifndef MCPI_SERVER_MODE
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef MCPI_SERVER_MODE
|
// Store Cursor State
|
||||||
static SDL_GrabMode fake_grab_mode = SDL_GRAB_OFF;
|
static int cursor_grabbed = 0;
|
||||||
#endif // #ifdef MCPI_SERVER_MODE
|
static int cursor_visible = 1;
|
||||||
|
|
||||||
// Fix SDL Cursor Visibility/Grabbing
|
// Update GLFW Cursor State (Client Only)
|
||||||
SDL_GrabMode SDL_WM_GrabInput(SDL_GrabMode mode) {
|
#ifndef MCPI_SERVER_MODE
|
||||||
#ifdef MCPI_SERVER_MODE
|
static void update_glfw_cursor() {
|
||||||
// Don't Grab Input In Server Mode
|
// Store Old Mode
|
||||||
if (mode != SDL_GRAB_QUERY) {
|
int old_mode = glfwGetInputMode(glfw_window, GLFW_CURSOR);
|
||||||
fake_grab_mode = mode;
|
|
||||||
|
// Handle Cursor Visibility
|
||||||
|
int new_mode;
|
||||||
|
if (!cursor_visible) {
|
||||||
|
if (cursor_grabbed) {
|
||||||
|
new_mode = GLFW_CURSOR_DISABLED;
|
||||||
|
} else {
|
||||||
|
new_mode = GLFW_CURSOR_HIDDEN;
|
||||||
}
|
}
|
||||||
return fake_grab_mode;
|
} else {
|
||||||
#else // #ifdef MCPI_SERVER_MODE
|
new_mode = GLFW_CURSOR_NORMAL;
|
||||||
if (mode != SDL_GRAB_QUERY && mode != SDL_WM_GrabInput(SDL_GRAB_QUERY)) {
|
}
|
||||||
glfwSetInputMode(glfw_window, GLFW_CURSOR, mode == SDL_GRAB_OFF ? GLFW_CURSOR_NORMAL : GLFW_CURSOR_DISABLED);
|
if (new_mode != old_mode) {
|
||||||
#if GLFW_VERSION_MAJOR > 3 || (GLFW_VERSION_MAJOR == 3 && GLFW_VERSION_MINOR >= 3)
|
// Set New Mode
|
||||||
glfwSetInputMode(glfw_window, GLFW_RAW_MOUSE_MOTION, mode == SDL_GRAB_OFF ? GLFW_FALSE : GLFW_TRUE);
|
glfwSetInputMode(glfw_window, GLFW_CURSOR, new_mode);
|
||||||
#endif // #if GLFW_VERSION_MAJOR > 3 || (GLFW_VERSION_MAJOR == 3 && GLFW_VERSION_MINOR >= 3)
|
|
||||||
|
|
||||||
|
// Handle Cursor Lock/Unlock
|
||||||
|
if ((new_mode == GLFW_CURSOR_DISABLED && old_mode != GLFW_CURSOR_DISABLED) || (new_mode != GLFW_CURSOR_DISABLED && old_mode == GLFW_CURSOR_DISABLED)) {
|
||||||
|
// Use Raw Mouse Motion (GLFW 3.3+ Only)
|
||||||
|
#ifdef GLFW_RAW_MOUSE_MOTION
|
||||||
|
glfwSetInputMode(glfw_window, GLFW_RAW_MOUSE_MOTION, new_mode == GLFW_CURSOR_DISABLED ? GLFW_TRUE : GLFW_FALSE);
|
||||||
|
#endif
|
||||||
// Reset Last Mouse Position
|
// Reset Last Mouse Position
|
||||||
ignore_relative_mouse = 1;
|
ignore_relative_mouse = 1;
|
||||||
}
|
}
|
||||||
return mode == SDL_GRAB_QUERY ? (glfwGetInputMode(glfw_window, GLFW_CURSOR) == GLFW_CURSOR_NORMAL ? SDL_GRAB_OFF : SDL_GRAB_ON) : mode;
|
}
|
||||||
#endif // #ifdef MCPI_SERVER_MODE
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Fix SDL Cursor Visibility/Grabbing
|
||||||
|
SDL_GrabMode SDL_WM_GrabInput(SDL_GrabMode mode) {
|
||||||
|
if (mode == SDL_GRAB_QUERY) {
|
||||||
|
// Query
|
||||||
|
return cursor_grabbed ? SDL_GRAB_ON : SDL_GRAB_OFF;
|
||||||
|
} else if (mode == SDL_GRAB_ON) {
|
||||||
|
// Store State
|
||||||
|
cursor_grabbed = 1;
|
||||||
|
} else if (mode == SDL_GRAB_OFF) {
|
||||||
|
// Store State
|
||||||
|
cursor_grabbed = 0;
|
||||||
|
}
|
||||||
|
// Update Cursor GLFW State (Client Only)
|
||||||
|
#ifndef MCPI_SERVER_MODE
|
||||||
|
update_glfw_cursor();
|
||||||
|
#endif
|
||||||
|
// Return
|
||||||
|
return mode;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Stub SDL Cursor Visibility
|
// Stub SDL Cursor Visibility
|
||||||
int SDL_ShowCursor(int toggle) {
|
int SDL_ShowCursor(int toggle) {
|
||||||
#ifdef MCPI_SERVER_MODE
|
if (toggle == SDL_QUERY) {
|
||||||
return toggle == SDL_QUERY ? (fake_grab_mode == SDL_GRAB_OFF ? SDL_ENABLE : SDL_DISABLE) : toggle;
|
// Query
|
||||||
#else // #ifdef MCPI_SERVER_MODE
|
return cursor_visible ? SDL_ENABLE : SDL_DISABLE;
|
||||||
return toggle == SDL_QUERY ? (glfwGetInputMode(glfw_window, GLFW_CURSOR) == GLFW_CURSOR_NORMAL ? SDL_ENABLE : SDL_DISABLE) : toggle;
|
} else if (toggle == SDL_ENABLE) {
|
||||||
#endif // #ifdef MCPI_SERVER_MODE
|
// Store State
|
||||||
|
cursor_visible = 1;
|
||||||
|
} else if (toggle == SDL_DISABLE) {
|
||||||
|
// Store State
|
||||||
|
cursor_visible = 0;
|
||||||
|
}
|
||||||
|
// Update Cursor GLFW State (Client Only)
|
||||||
|
#ifndef MCPI_SERVER_MODE
|
||||||
|
update_glfw_cursor();
|
||||||
|
#endif
|
||||||
|
// Return
|
||||||
|
return toggle;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get Framebuffer Size
|
// Get Framebuffer Size
|
||||||
|
@ -35,6 +35,9 @@ target_link_libraries(misc reborn feature util)
|
|||||||
add_library(options SHARED src/options/options.c)
|
add_library(options SHARED src/options/options.c)
|
||||||
target_link_libraries(options reborn feature)
|
target_link_libraries(options reborn feature)
|
||||||
|
|
||||||
|
add_library(touch SHARED src/touch/touch.c)
|
||||||
|
target_link_libraries(touch reborn feature)
|
||||||
|
|
||||||
add_library(override SHARED src/override/override.c)
|
add_library(override SHARED src/override/override.c)
|
||||||
target_link_libraries(override reborn dl home)
|
target_link_libraries(override reborn dl home)
|
||||||
|
|
||||||
@ -51,13 +54,13 @@ add_library(test SHARED src/test/test.c)
|
|||||||
target_link_libraries(test reborn home)
|
target_link_libraries(test reborn home)
|
||||||
|
|
||||||
add_library(init SHARED src/init/init.c)
|
add_library(init SHARED src/init/init.c)
|
||||||
target_link_libraries(init compat game_mode camera input misc options textures chat home test)
|
target_link_libraries(init compat game_mode camera input misc options touch textures chat home test)
|
||||||
if(MCPI_SERVER_MODE)
|
if(MCPI_SERVER_MODE)
|
||||||
target_link_libraries(init server)
|
target_link_libraries(init server)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
## Install Mods
|
## Install Mods
|
||||||
install(TARGETS init compat readdir feature override game_mode camera input misc options textures chat home test DESTINATION "${MCPI_INSTALL_DIR}/mods")
|
install(TARGETS init compat readdir feature override game_mode camera input misc options touch textures chat home test DESTINATION "${MCPI_INSTALL_DIR}/mods")
|
||||||
if(MCPI_SERVER_MODE)
|
if(MCPI_SERVER_MODE)
|
||||||
install(TARGETS server DESTINATION "${MCPI_INSTALL_DIR}/mods")
|
install(TARGETS server DESTINATION "${MCPI_INSTALL_DIR}/mods")
|
||||||
endif()
|
endif()
|
||||||
|
@ -12,6 +12,13 @@
|
|||||||
#include "../init/init.h"
|
#include "../init/init.h"
|
||||||
#include "compat.h"
|
#include "compat.h"
|
||||||
|
|
||||||
|
// Mouse Cursor Is Always Invisible In Vanilla MCPI
|
||||||
|
// Because In Vanilla MCPI, The GPU Overlay Covered The Normal Mouse Cursor
|
||||||
|
HOOK(SDL_ShowCursor, int, (int toggle)) {
|
||||||
|
ensure_SDL_ShowCursor();
|
||||||
|
return (*real_SDL_ShowCursor)(toggle == SDL_QUERY ? SDL_QUERY : SDL_DISABLE);
|
||||||
|
}
|
||||||
|
|
||||||
// Intercept SDL Events
|
// Intercept SDL Events
|
||||||
HOOK(SDL_PollEvent, int, (SDL_Event *event)) {
|
HOOK(SDL_PollEvent, int, (SDL_Event *event)) {
|
||||||
// In Server Mode, Exit Requests Are Handled In src/server/server.cpp
|
// In Server Mode, Exit Requests Are Handled In src/server/server.cpp
|
||||||
|
@ -4,17 +4,17 @@
|
|||||||
#include <libreborn/media-layer/core.h>
|
#include <libreborn/media-layer/core.h>
|
||||||
|
|
||||||
// Functions That Have Their Return Values Used
|
// Functions That Have Their Return Values Used
|
||||||
static EGLSurface eglCreateWindowSurface_overwrite(__attribute__((unused)) EGLDisplay display, __attribute__((unused)) EGLConfig config, __attribute__((unused)) NativeWindowType native_window, __attribute__((unused)) EGLint const *attrib_list) {
|
static EGLSurface eglCreateWindowSurface_injection(__attribute__((unused)) EGLDisplay display, __attribute__((unused)) EGLConfig config, __attribute__((unused)) NativeWindowType native_window, __attribute__((unused)) EGLint const *attrib_list) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
static EGLDisplay eglGetDisplay_overwrite(__attribute__((unused)) NativeDisplayType native_display) {
|
static EGLDisplay eglGetDisplay_injection(__attribute__((unused)) NativeDisplayType native_display) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
static EGLContext eglCreateContext_overwrite(__attribute__((unused)) EGLDisplay display, __attribute__((unused)) EGLConfig config, __attribute__((unused)) EGLContext share_context, __attribute__((unused)) EGLint const *attrib_list) {
|
static EGLContext eglCreateContext_injection(__attribute__((unused)) EGLDisplay display, __attribute__((unused)) EGLConfig config, __attribute__((unused)) EGLContext share_context, __attribute__((unused)) EGLint const *attrib_list) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
// Call media_swap_buffers()
|
// Call media_swap_buffers()
|
||||||
static EGLBoolean eglSwapBuffers_overwrite(__attribute__((unused)) EGLDisplay display, __attribute__((unused)) EGLSurface surface) {
|
static EGLBoolean eglSwapBuffers_injection(__attribute__((unused)) EGLDisplay display, __attribute__((unused)) EGLSurface surface) {
|
||||||
media_swap_buffers();
|
media_swap_buffers();
|
||||||
return EGL_TRUE;
|
return EGL_TRUE;
|
||||||
}
|
}
|
||||||
@ -25,15 +25,15 @@ __attribute__((constructor)) static void patch_egl_calls() {
|
|||||||
unsigned char nop_patch[4] = {0x00, 0xf0, 0x20, 0xe3}; // "nop"
|
unsigned char nop_patch[4] = {0x00, 0xf0, 0x20, 0xe3}; // "nop"
|
||||||
patch((void *) 0x1250c, nop_patch); // eglTerminate
|
patch((void *) 0x1250c, nop_patch); // eglTerminate
|
||||||
patch((void *) 0x12580, nop_patch); // eglBindAPI
|
patch((void *) 0x12580, nop_patch); // eglBindAPI
|
||||||
overwrite_call((void *) 0x12638, (void *) eglCreateWindowSurface_overwrite); // eglCreateWindowSurface
|
overwrite_call((void *) 0x12638, (void *) eglCreateWindowSurface_injection); // eglCreateWindowSurface
|
||||||
patch((void *) 0x12578, nop_patch); // eglChooseConfig
|
patch((void *) 0x12578, nop_patch); // eglChooseConfig
|
||||||
patch((void *) 0x1255c, nop_patch); // eglInitialize
|
patch((void *) 0x1255c, nop_patch); // eglInitialize
|
||||||
patch((void *) 0x124f0, nop_patch); // eglMakeCurrent #1
|
patch((void *) 0x124f0, nop_patch); // eglMakeCurrent #1
|
||||||
patch((void *) 0x12654, nop_patch); // eglMakeCurrent #2
|
patch((void *) 0x12654, nop_patch); // eglMakeCurrent #2
|
||||||
overwrite_call((void *) 0x124dc, (void *) eglSwapBuffers_overwrite); // eglSwapBuffers #1
|
overwrite_call((void *) 0x124dc, (void *) eglSwapBuffers_injection); // eglSwapBuffers #1
|
||||||
overwrite_call((void *) 0x14b6c, (void *) eglSwapBuffers_overwrite); // eglSwapBuffers #2
|
overwrite_call((void *) 0x14b6c, (void *) eglSwapBuffers_injection); // eglSwapBuffers #2
|
||||||
overwrite_call((void *) 0x1254c, (void *) eglGetDisplay_overwrite); // eglGetDisplay
|
overwrite_call((void *) 0x1254c, (void *) eglGetDisplay_injection); // eglGetDisplay
|
||||||
patch((void *) 0x124fc, nop_patch); // eglDestroySurface #1
|
patch((void *) 0x124fc, nop_patch); // eglDestroySurface #1
|
||||||
patch((void *) 0x12504, nop_patch); // eglDestroySurface #2
|
patch((void *) 0x12504, nop_patch); // eglDestroySurface #2
|
||||||
overwrite_call((void *) 0x12594, (void *) eglCreateContext_overwrite); // eglCreateContext
|
overwrite_call((void *) 0x12594, (void *) eglCreateContext_injection); // eglCreateContext
|
||||||
}
|
}
|
||||||
|
@ -11,6 +11,7 @@ __attribute__((constructor)) static void init() {
|
|||||||
init_misc();
|
init_misc();
|
||||||
init_camera();
|
init_camera();
|
||||||
init_options();
|
init_options();
|
||||||
|
init_touch();
|
||||||
init_textures();
|
init_textures();
|
||||||
init_chat();
|
init_chat();
|
||||||
init_home();
|
init_home();
|
||||||
|
@ -14,6 +14,7 @@ void init_input();
|
|||||||
void init_misc();
|
void init_misc();
|
||||||
void init_camera();
|
void init_camera();
|
||||||
void init_options();
|
void init_options();
|
||||||
|
void init_touch();
|
||||||
void init_textures();
|
void init_textures();
|
||||||
void init_chat();
|
void init_chat();
|
||||||
void init_home();
|
void init_home();
|
||||||
|
@ -3,7 +3,6 @@ This mod allows various options to be configured, including:
|
|||||||
- Mob Spawning
|
- Mob Spawning
|
||||||
- The Render Distance
|
- The Render Distance
|
||||||
- The Username
|
- The Username
|
||||||
- Touch GUI
|
|
||||||
- Peaceful Mode
|
- Peaceful Mode
|
||||||
- 3D Anaglyph
|
- 3D Anaglyph
|
||||||
- Autojump
|
- Autojump
|
||||||
|
@ -68,21 +68,8 @@ static void Minecraft_init_injection(unsigned char *this) {
|
|||||||
*(int32_t *) (options + Options_render_distance_property_offset) = render_distance;
|
*(int32_t *) (options + Options_render_distance_property_offset) = render_distance;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Enable Touch GUI
|
// Init
|
||||||
static int32_t Minecraft_isTouchscreen_injection(__attribute__((unused)) unsigned char *minecraft) {
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
void init_options() {
|
void init_options() {
|
||||||
int touch_gui = feature_has("Touch GUI");
|
|
||||||
if (touch_gui) {
|
|
||||||
// Main UI
|
|
||||||
overwrite((void *) Minecraft_isTouchscreen, Minecraft_isTouchscreen_injection);
|
|
||||||
// Force Correct Toolbar Size
|
|
||||||
unsigned char toolbar_patch[4] = {0x01, 0x00, 0x50, 0xe3}; // "cmp r0, #0x1"
|
|
||||||
patch((void *) 0x257b0, toolbar_patch);
|
|
||||||
}
|
|
||||||
|
|
||||||
mob_spawning = feature_has("Mob Spawning");
|
mob_spawning = feature_has("Mob Spawning");
|
||||||
// Set Mob Spawning
|
// Set Mob Spawning
|
||||||
overwrite((void *) LevelData_getSpawnMobs, LevelData_getSpawnMobs_injection);
|
overwrite((void *) LevelData_getSpawnMobs, LevelData_getSpawnMobs_injection);
|
||||||
@ -125,11 +112,6 @@ void init_options() {
|
|||||||
patch((void *) 0xa6628, display_nametags_patch);
|
patch((void *) 0xa6628, display_nametags_patch);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Show Block Outlines
|
|
||||||
int block_outlines = feature_has("Show Block Outlines");
|
|
||||||
unsigned char outline_patch[4] = {block_outlines ? !touch_gui : touch_gui, 0x00, 0x50, 0xe3}; // "cmp r0, #0x1" or "cmp r0, #0x0"
|
|
||||||
patch((void *) 0x4a210, outline_patch);
|
|
||||||
|
|
||||||
smooth_lighting = feature_has("Smooth Lighting");
|
smooth_lighting = feature_has("Smooth Lighting");
|
||||||
if (smooth_lighting) {
|
if (smooth_lighting) {
|
||||||
// Enable Smooth Lighting
|
// Enable Smooth Lighting
|
||||||
|
2
mods/src/touch/README.md
Normal file
2
mods/src/touch/README.md
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
# ``touch`` Mod
|
||||||
|
This mod allows the hidden touch GUI to be activated.
|
54
mods/src/touch/touch.c
Normal file
54
mods/src/touch/touch.c
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
#include <libreborn/libreborn.h>
|
||||||
|
|
||||||
|
#include "../feature/feature.h"
|
||||||
|
#include "../init/init.h"
|
||||||
|
|
||||||
|
#include <libreborn/minecraft.h>
|
||||||
|
|
||||||
|
// Enable Touch GUI
|
||||||
|
static int32_t Minecraft_isTouchscreen_injection(__attribute__((unused)) unsigned char *minecraft) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Custom Cursor Rendering
|
||||||
|
// The Default Behavior For Touch GUI Is To Only Render The Cursor When The Mouse Is Clicking, This Fixes That
|
||||||
|
static void GameRenderer_render_injection(unsigned char *game_renderer, float param_1) {
|
||||||
|
// Call Real Method
|
||||||
|
(*GameRenderer_render)(game_renderer, param_1);
|
||||||
|
|
||||||
|
// Render Cursor
|
||||||
|
unsigned char *minecraft = *(unsigned char **) (game_renderer + GameRenderer_minecraft_property_offset);
|
||||||
|
unsigned char *current_screen = *(unsigned char **) (minecraft + Minecraft_screen_property_offset);
|
||||||
|
// Check If Cursor Should Render
|
||||||
|
if (current_screen != NULL) {
|
||||||
|
// Get X And Y
|
||||||
|
float x = (*Mouse_getX)() * (*InvGuiScale);
|
||||||
|
float y = (*Mouse_getY)() * (*InvGuiScale);
|
||||||
|
// Render
|
||||||
|
(*renderCursor)(x, y, minecraft);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Init
|
||||||
|
void init_touch() {
|
||||||
|
int touch_gui = feature_has("Touch GUI");
|
||||||
|
if (touch_gui) {
|
||||||
|
// Main UI
|
||||||
|
overwrite((void *) Minecraft_isTouchscreen, Minecraft_isTouchscreen_injection);
|
||||||
|
|
||||||
|
// Disable Normal Cursor Rendering
|
||||||
|
unsigned char disable_cursor_patch[4] = {0x00, 0xf0, 0x20, 0xe3}; // "nop"
|
||||||
|
patch((void *) 0x4a6c0, disable_cursor_patch);
|
||||||
|
// Add Custom Cursor Rendering
|
||||||
|
overwrite_calls((void *) GameRenderer_render, (void *) GameRenderer_render_injection);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Force Correct Toolbar Size
|
||||||
|
unsigned char toolbar_patch[4] = {0x01, 0x00, 0x50, 0xe3}; // "cmp r0, #0x1"
|
||||||
|
patch((void *) 0x257b0, toolbar_patch);
|
||||||
|
|
||||||
|
// Show Block Outlines
|
||||||
|
int block_outlines = feature_has("Show Block Outlines");
|
||||||
|
unsigned char outline_patch[4] = {block_outlines ? !touch_gui : touch_gui, 0x00, 0x50, 0xe3}; // "cmp r0, #0x1" or "cmp r0, #0x0"
|
||||||
|
patch((void *) 0x4a210, outline_patch);
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user