2020-10-01 15:08:46 +00:00
|
|
|
#include <stdint.h>
|
|
|
|
#include <stdio.h>
|
|
|
|
|
|
|
|
#include <libcore/libcore.h>
|
|
|
|
|
2020-10-04 00:30:15 +00:00
|
|
|
#include "extra.h"
|
2020-10-10 23:02:13 +00:00
|
|
|
#include "server/server.h"
|
2020-10-04 00:30:15 +00:00
|
|
|
|
2020-11-21 21:52:27 +00:00
|
|
|
#include "minecraft.h"
|
|
|
|
|
2020-10-14 17:40:32 +00:00
|
|
|
static int mob_spawning = 0;
|
2020-11-20 21:38:23 +00:00
|
|
|
// Override Mob Spawning
|
2020-11-07 22:19:45 +00:00
|
|
|
static uint32_t LevelData_getSpawnMobs_injection(__attribute__((unused)) unsigned char *level_data) {
|
2020-10-14 17:40:32 +00:00
|
|
|
return mob_spawning;
|
|
|
|
}
|
|
|
|
|
2020-11-20 21:38:23 +00:00
|
|
|
// Store Right-Click Status
|
2020-10-14 17:40:32 +00:00
|
|
|
static int is_right_click = 0;
|
|
|
|
void extra_set_is_right_click(int val) {
|
|
|
|
is_right_click = val;
|
2020-10-01 15:08:46 +00:00
|
|
|
}
|
|
|
|
|
2020-11-10 15:08:42 +00:00
|
|
|
// Enable Bow & Arrow Fix
|
|
|
|
static int fix_bow = 0;
|
|
|
|
|
2020-11-21 05:13:09 +00:00
|
|
|
// Store Function Input
|
|
|
|
static int hide_gui_toggle = 0;
|
|
|
|
void extra_hide_gui() {
|
|
|
|
hide_gui_toggle++;
|
|
|
|
}
|
|
|
|
static int third_person_toggle = 0;
|
|
|
|
void extra_third_person() {
|
|
|
|
third_person_toggle++;
|
|
|
|
}
|
|
|
|
|
2020-11-20 21:38:23 +00:00
|
|
|
// Handle Input Fixes
|
2020-11-07 22:19:45 +00:00
|
|
|
static void Minecraft_tickInput_injection(unsigned char *minecraft) {
|
2020-10-01 15:08:46 +00:00
|
|
|
// Call Original Method
|
2020-11-07 22:19:45 +00:00
|
|
|
(*Minecraft_tickInput)(minecraft);
|
2020-10-01 15:08:46 +00:00
|
|
|
|
2020-11-10 15:08:42 +00:00
|
|
|
if (fix_bow && !is_right_click) {
|
|
|
|
// GameMode Is Offset From minecraft By 0x160
|
|
|
|
// Player Is Offset From minecraft By 0x18c
|
2020-11-02 18:56:20 +00:00
|
|
|
unsigned char *game_mode = *(unsigned char **) (minecraft + 0x160);
|
|
|
|
unsigned char *player = *(unsigned char **) (minecraft + 0x18c);
|
|
|
|
if (player != NULL && game_mode != NULL && (*Player_isUsingItem)(player)) {
|
2020-11-02 14:38:40 +00:00
|
|
|
unsigned char *game_mode_vtable = *(unsigned char **) game_mode;
|
2020-11-21 21:52:27 +00:00
|
|
|
GameMode_releaseUsingItem_t GameMode_releaseUsingItem = *(GameMode_releaseUsingItem_t *) (game_mode_vtable + 0x5c);
|
|
|
|
(*GameMode_releaseUsingItem)(game_mode, player);
|
2020-10-01 15:08:46 +00:00
|
|
|
}
|
|
|
|
}
|
2020-10-04 00:30:15 +00:00
|
|
|
|
2020-11-10 15:08:42 +00:00
|
|
|
// Clear Unused Sign Input
|
2020-10-14 17:40:32 +00:00
|
|
|
extra_clear_input();
|
2020-11-21 05:13:09 +00:00
|
|
|
|
|
|
|
// Handle Functions
|
|
|
|
unsigned char *options = minecraft + 0x3c;
|
|
|
|
if (hide_gui_toggle % 2 != 0) {
|
|
|
|
// Toggle Hide GUI
|
|
|
|
*(options + 0xec) = *(options + 0xec) ^ 1;
|
|
|
|
}
|
|
|
|
hide_gui_toggle = 0;
|
|
|
|
if (third_person_toggle % 2 != 0) {
|
|
|
|
// Toggle Third Person
|
|
|
|
*(options + 0xed) = *(options + 0xed) ^ 1;
|
|
|
|
}
|
|
|
|
third_person_toggle = 0;
|
2020-10-01 15:08:46 +00:00
|
|
|
}
|
|
|
|
|
2020-10-01 16:56:28 +00:00
|
|
|
#include <SDL/SDL_events.h>
|
|
|
|
|
2020-11-20 21:38:23 +00:00
|
|
|
// Block UI Interaction When Mouse Is Locked
|
2020-10-29 16:14:51 +00:00
|
|
|
static void Gui_tickItemDrop_injection(unsigned char *this) {
|
2020-10-01 16:56:28 +00:00
|
|
|
if (SDL_ShowCursor(SDL_QUERY) == SDL_ENABLE) {
|
2020-11-07 22:19:45 +00:00
|
|
|
// Call Original Method
|
2020-10-29 16:14:51 +00:00
|
|
|
(*Gui_tickItemDrop)(this);
|
2020-10-01 16:56:28 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-11-20 21:38:23 +00:00
|
|
|
// Block UI Interaction When Mouse Is Locked
|
2020-11-07 22:19:45 +00:00
|
|
|
static void Gui_handleClick_injection(unsigned char *this, int32_t param_2, int32_t param_3, int32_t param_4) {
|
2020-10-01 16:56:28 +00:00
|
|
|
if (SDL_ShowCursor(SDL_QUERY) == SDL_ENABLE) {
|
2020-11-07 22:19:45 +00:00
|
|
|
// Call Original Method
|
2020-10-29 16:14:51 +00:00
|
|
|
(*Gui_handleClick)(this, param_2, param_3, param_4);
|
2020-10-01 16:56:28 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-11-02 18:56:20 +00:00
|
|
|
static int is_survival = -1;
|
|
|
|
|
2020-10-02 21:06:03 +00:00
|
|
|
// Patch Game Mode
|
|
|
|
static void set_is_survival(int new_is_survival) {
|
|
|
|
if (is_survival != new_is_survival) {
|
2020-11-02 20:27:41 +00:00
|
|
|
INFO("Setting Game Mode: %s", new_is_survival ? "Survival" : "Creative");
|
2020-10-02 21:06:03 +00:00
|
|
|
|
|
|
|
// Correct Inventpry UI
|
|
|
|
unsigned char inventory_patch[4] = {new_is_survival ? 0x00 : 0x01, 0x30, 0xa0, 0xe3};
|
|
|
|
patch((void *) 0x16efc, inventory_patch);
|
|
|
|
|
2020-10-14 17:40:32 +00:00
|
|
|
// Use Correct Size For GameMode Object
|
|
|
|
unsigned char size_patch[4] = {new_is_survival ? 0x24 : 0x18, 0x00, 0xa0, 0xe3};
|
|
|
|
patch((void *) 0x16ee4, size_patch);
|
2020-10-02 21:06:03 +00:00
|
|
|
|
2020-11-21 21:52:27 +00:00
|
|
|
// Replace Creator Constructor With CreativeMode Or SurvivalMode Constructor
|
2020-10-14 17:40:32 +00:00
|
|
|
overwrite(Creator, new_is_survival ? SurvivalMode : CreativeMode);
|
2020-10-02 21:06:03 +00:00
|
|
|
|
|
|
|
is_survival = new_is_survival;
|
2020-10-01 15:08:46 +00:00
|
|
|
}
|
2020-10-02 21:06:03 +00:00
|
|
|
}
|
2020-10-01 15:08:46 +00:00
|
|
|
|
2020-11-20 21:38:23 +00:00
|
|
|
// Handle Gamemode Switching
|
2020-10-29 16:14:51 +00:00
|
|
|
static void Minecraft_setIsCreativeMode_injection(unsigned char *this, int32_t new_game_mode) {
|
2020-10-02 21:06:03 +00:00
|
|
|
set_is_survival(!new_game_mode);
|
2020-10-01 15:08:46 +00:00
|
|
|
|
2020-11-07 22:19:45 +00:00
|
|
|
// Call Original Method
|
2020-10-29 16:14:51 +00:00
|
|
|
(*Minecraft_setIsCreativeMode)(this, new_game_mode);
|
2020-10-02 21:06:03 +00:00
|
|
|
}
|
2020-10-01 15:08:46 +00:00
|
|
|
|
2020-11-20 21:38:23 +00:00
|
|
|
// Get Custom Username
|
2020-10-02 22:43:43 +00:00
|
|
|
static char *get_username() {
|
|
|
|
char *username = getenv("MCPI_USERNAME");
|
|
|
|
if (username == NULL) {
|
|
|
|
username = "StevePi";
|
|
|
|
}
|
|
|
|
return username;
|
|
|
|
}
|
|
|
|
|
2020-11-12 23:28:37 +00:00
|
|
|
static int fancy_graphics;
|
|
|
|
static int peaceful_mode;
|
2020-11-21 05:13:09 +00:00
|
|
|
static int anaglyph;
|
2020-11-20 21:38:23 +00:00
|
|
|
// Configure Options
|
2020-10-29 16:14:51 +00:00
|
|
|
static void Minecraft_init_injection(unsigned char *this) {
|
2020-11-07 22:19:45 +00:00
|
|
|
// Call Original Method
|
2020-10-29 16:14:51 +00:00
|
|
|
(*Minecraft_init)(this);
|
2020-10-03 03:25:27 +00:00
|
|
|
|
2020-11-12 23:28:37 +00:00
|
|
|
unsigned char *options = this + 0x3c;
|
2020-10-14 17:40:32 +00:00
|
|
|
// Enable Fancy Graphics
|
2020-11-12 23:28:37 +00:00
|
|
|
*(options + 0x17) = fancy_graphics;
|
|
|
|
// Enable Crosshair In Touch GUI
|
|
|
|
*(options + 0x105) = 1;
|
|
|
|
// Peaceful Mode
|
|
|
|
*(int32_t *) (options + 0xe8) = peaceful_mode ? 0 : 2;
|
2020-11-21 05:13:09 +00:00
|
|
|
// 3D Anaglyph
|
|
|
|
*(options + 0x15) = anaglyph;
|
2020-10-03 03:25:27 +00:00
|
|
|
}
|
|
|
|
|
2020-10-10 23:02:13 +00:00
|
|
|
// Is Dedicated Server
|
|
|
|
static int is_server = 0;
|
|
|
|
|
|
|
|
// Check For Feature
|
2020-10-14 17:40:32 +00:00
|
|
|
int extra_has_feature(const char *name) {
|
2020-10-10 23:02:13 +00:00
|
|
|
if (is_server) {
|
|
|
|
// Enable All Features In Server
|
|
|
|
return 1;
|
|
|
|
} else {
|
|
|
|
char *env = getenv("MCPI_FEATURES");
|
|
|
|
char *features = strdup(env != NULL ? env : "");
|
|
|
|
char *tok = strtok(features, "|");
|
|
|
|
int ret = 0;
|
|
|
|
while (tok != NULL) {
|
|
|
|
if (strcmp(tok, name) == 0) {
|
|
|
|
ret = 1;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
tok = strtok(NULL, "|");
|
|
|
|
}
|
|
|
|
free(features);
|
2020-11-02 20:27:41 +00:00
|
|
|
INFO("Feature: %s: %s", name, ret ? "Enabled" : "Disabled");
|
2020-10-10 23:02:13 +00:00
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-11-20 21:38:23 +00:00
|
|
|
// Get Graphics Mode
|
2020-10-16 19:39:04 +00:00
|
|
|
int extra_get_mode() {
|
|
|
|
char *mode = getenv("MCPI_MODE");
|
2020-10-30 17:27:50 +00:00
|
|
|
if (mode == NULL) {
|
|
|
|
ERR("%s", "MCPI Mode Not Specified");
|
|
|
|
} else if (strcmp("virgl", mode) == 0) {
|
2020-10-16 19:39:04 +00:00
|
|
|
return 0;
|
|
|
|
} else if (strcmp("native", mode) == 0) {
|
|
|
|
return 1;
|
|
|
|
} else if (strcmp("server", mode) == 0) {
|
|
|
|
return 2;
|
|
|
|
} else {
|
2020-10-26 19:58:28 +00:00
|
|
|
ERR("Inavlid MCPI_MODE: %s", mode);
|
2020-10-16 19:39:04 +00:00
|
|
|
}
|
2020-10-10 23:02:13 +00:00
|
|
|
}
|
|
|
|
|
2020-11-20 21:38:23 +00:00
|
|
|
// Enable Touch GUI
|
2020-11-21 21:52:27 +00:00
|
|
|
static int32_t Minecraft_isTouchscreen_injection(__attribute__((unused)) unsigned char *minecraft) {
|
2020-11-12 23:28:37 +00:00
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2020-11-20 21:38:23 +00:00
|
|
|
// Store Smooth Lighting
|
|
|
|
static int smooth_lighting;
|
|
|
|
int extra_get_smooth_lighting() {
|
|
|
|
return smooth_lighting;
|
|
|
|
}
|
|
|
|
|
2020-11-21 21:52:27 +00:00
|
|
|
// Store Left Click (0 = Not Pressed, 1 = Pressed, 2 = Repeat)
|
|
|
|
// This Is Set To Repeat After First Attempted Left-Click Build Interaction
|
|
|
|
static int is_left_click = 0;
|
|
|
|
void extra_set_is_left_click(int val) {
|
|
|
|
if ((is_left_click == 0 && val == 1) || (is_left_click != 0 && val == 0) || (is_left_click == 1 && val == 2)) {
|
|
|
|
is_left_click = val;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Add Attacking To MouseBuildInput
|
2020-11-21 23:32:39 +00:00
|
|
|
static int32_t MouseBuildInput_tickBuild_injection(unsigned char *mouse_build_input, unsigned char *local_player, uint32_t *build_action_intention_return) {
|
2020-11-21 21:52:27 +00:00
|
|
|
// Call Original Method
|
2020-11-21 23:32:39 +00:00
|
|
|
int32_t ret = (*MouseBuildInput_tickBuild)(mouse_build_input, local_player, build_action_intention_return);
|
2020-11-21 21:52:27 +00:00
|
|
|
|
2020-11-21 23:32:39 +00:00
|
|
|
// Use Attack/Place BuildActionIntention If No Other Valid BuildActionIntention Was Selected And This Was Not A Repeated Left Click
|
2020-11-21 21:52:27 +00:00
|
|
|
if (ret != 0 && is_left_click == 1 && *build_action_intention_return == 0xa) {
|
2020-11-21 23:32:39 +00:00
|
|
|
// Get Target HitResult
|
|
|
|
unsigned char *minecraft = *(unsigned char **) (local_player + 0xc90);
|
|
|
|
unsigned char *hit_result = minecraft + 0xc38;
|
|
|
|
int32_t hit_result_type = *(int32_t *) hit_result;
|
|
|
|
// Check if The Target Is An Entity Using HitResult
|
|
|
|
if (hit_result_type == 1) {
|
|
|
|
// Change BuildActionIntention To Attack/Place Mode (Place Will Not Happen Because The HitResult Is An Entity)
|
|
|
|
*build_action_intention_return = 0x8;
|
|
|
|
}
|
|
|
|
// Block Repeat Changes Without Releasing Left Click
|
2020-11-21 21:52:27 +00:00
|
|
|
is_left_click = 2;
|
|
|
|
}
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2020-10-02 21:06:03 +00:00
|
|
|
__attribute__((constructor)) static void init() {
|
2020-10-16 19:39:04 +00:00
|
|
|
is_server = extra_get_mode() == 2;
|
2020-10-10 23:02:13 +00:00
|
|
|
if (is_server) {
|
|
|
|
server_init();
|
|
|
|
}
|
|
|
|
|
2020-11-12 23:28:37 +00:00
|
|
|
int touch_gui = !is_server && extra_has_feature("Touch GUI");
|
|
|
|
if (touch_gui) {
|
2020-11-03 03:18:18 +00:00
|
|
|
// Main UI
|
2020-11-21 21:52:27 +00:00
|
|
|
overwrite((void *) Minecraft_isTouchscreen, Minecraft_isTouchscreen_injection);
|
2020-11-12 23:28:37 +00:00
|
|
|
// Force Correct Toolbar Size
|
|
|
|
unsigned char toolbar_patch[4] = {0x01, 0x00, 0x50, 0xe3};
|
|
|
|
patch((void *) 0x257b0, toolbar_patch);
|
2020-10-01 15:08:46 +00:00
|
|
|
}
|
|
|
|
|
2020-11-03 03:18:18 +00:00
|
|
|
// Dynamic Game Mode Switching
|
2020-10-29 17:00:52 +00:00
|
|
|
set_is_survival(1);
|
2020-11-10 00:49:41 +00:00
|
|
|
overwrite_calls((void *) Minecraft_setIsCreativeMode, Minecraft_setIsCreativeMode_injection);
|
2020-10-29 17:00:52 +00:00
|
|
|
|
2020-10-10 23:02:13 +00:00
|
|
|
// Get Default Game Mode
|
2020-11-02 20:20:49 +00:00
|
|
|
if (!is_server) {
|
|
|
|
int default_game_mode = !extra_has_feature("Survival Mode");
|
2020-10-10 23:02:13 +00:00
|
|
|
|
2020-11-02 20:20:49 +00:00
|
|
|
// Set Default Game Mode
|
|
|
|
unsigned char default_game_mode_patch[4] = {default_game_mode ? 0x01 : 0x00, 0x30, 0xa0, 0xe3};
|
|
|
|
patch((void *) 0x3d9b8, default_game_mode_patch);
|
|
|
|
patch((void *) 0x38a78, default_game_mode_patch);
|
|
|
|
}
|
2020-10-02 21:06:03 +00:00
|
|
|
|
2020-11-02 20:20:49 +00:00
|
|
|
// Disable Item Dropping Using The Cursor When Cursor Is Hidden
|
2020-11-10 00:49:41 +00:00
|
|
|
overwrite_calls((void *) Gui_tickItemDrop, Gui_tickItemDrop_injection);
|
2020-10-01 16:56:28 +00:00
|
|
|
// Disable Opening Inventory Using The Cursor When Cursor Is Hidden
|
2020-11-10 00:49:41 +00:00
|
|
|
overwrite_calls((void *) Gui_handleClick, Gui_handleClick_injection);
|
2020-10-01 16:56:28 +00:00
|
|
|
|
2020-11-10 15:08:42 +00:00
|
|
|
// Enable Bow & Arrow Fix
|
|
|
|
fix_bow = extra_has_feature("Fix Bow & Arrow");
|
|
|
|
// Fix Bow & Arrow + Clear Unused Sign Input
|
|
|
|
overwrite_calls((void *) Minecraft_tickInput, Minecraft_tickInput_injection);
|
2020-10-01 15:08:46 +00:00
|
|
|
|
2020-10-14 17:40:32 +00:00
|
|
|
if (extra_has_feature("Fix Attacking")) {
|
2020-10-01 15:08:46 +00:00
|
|
|
// Allow Attacking Mobs
|
2020-11-21 21:52:27 +00:00
|
|
|
patch_address(MouseBuildInput_tickBuild_vtable_addr, (void *) MouseBuildInput_tickBuild_injection);
|
2020-10-01 15:08:46 +00:00
|
|
|
}
|
|
|
|
|
2020-10-10 23:02:13 +00:00
|
|
|
if (is_server) {
|
|
|
|
mob_spawning = server_get_mob_spawning();
|
|
|
|
} else {
|
2020-10-14 17:40:32 +00:00
|
|
|
mob_spawning = extra_has_feature("Mob Spawning");
|
2020-10-01 15:08:46 +00:00
|
|
|
}
|
2020-10-14 17:40:32 +00:00
|
|
|
// Set Mob Spawning
|
2020-11-21 21:52:27 +00:00
|
|
|
overwrite((void *) LevelData_getSpawnMobs, LevelData_getSpawnMobs_injection);
|
2020-10-02 02:17:22 +00:00
|
|
|
|
|
|
|
// Replace CreatorLevel With ServerLevel (This Fixes Beds And Mob Spawning)
|
2020-11-07 22:19:45 +00:00
|
|
|
unsigned char level_patch[4] = {0x68, 0x7e, 0x01, 0xeb};
|
|
|
|
patch((void *) 0x16f84, level_patch);
|
2020-10-02 02:17:22 +00:00
|
|
|
|
|
|
|
// Allocate Correct Size For ServerLevel
|
2020-11-07 22:19:45 +00:00
|
|
|
unsigned char level_size_patch[4] = {0x94, 0x0b, 0x00, 0x00};
|
|
|
|
patch((void *) 0x17004, level_size_patch);
|
2020-10-04 21:52:42 +00:00
|
|
|
|
2020-11-12 23:28:37 +00:00
|
|
|
// Enable Fancy Graphics
|
|
|
|
fancy_graphics = extra_has_feature("Fancy Graphics");
|
|
|
|
// Peaceful Mode
|
|
|
|
peaceful_mode = extra_has_feature("Peaceful Mode");
|
2020-11-21 05:13:09 +00:00
|
|
|
// 3D Anaglyph
|
|
|
|
anaglyph = extra_has_feature("3D Anaglyph");
|
2020-11-12 23:28:37 +00:00
|
|
|
|
|
|
|
// Set Options
|
|
|
|
overwrite_calls((void *) Minecraft_init, Minecraft_init_injection);
|
2020-10-02 17:54:10 +00:00
|
|
|
|
|
|
|
// Allow Connecting To Non-Pi Servers
|
2020-11-07 22:19:45 +00:00
|
|
|
unsigned char server_patch[4] = {0x0f, 0x00, 0x00, 0xea};
|
|
|
|
patch((void *) 0x6dc70, server_patch);
|
2020-10-02 22:43:43 +00:00
|
|
|
|
|
|
|
// Change Username
|
2020-10-10 23:02:13 +00:00
|
|
|
const char *username;
|
|
|
|
if (is_server) {
|
|
|
|
// MOTD is Username
|
|
|
|
username = server_get_motd();
|
|
|
|
} else {
|
|
|
|
username = get_username();
|
2020-11-02 20:27:41 +00:00
|
|
|
INFO("Setting Username: %s", username);
|
2020-10-10 23:02:13 +00:00
|
|
|
}
|
2020-10-26 19:58:28 +00:00
|
|
|
if (strcmp(*default_username, "StevePi") != 0) {
|
|
|
|
ERR("%s", "Default Username Is Invalid");
|
|
|
|
}
|
|
|
|
patch_address((void *) default_username, (void *) username);
|
2020-10-03 00:34:39 +00:00
|
|
|
|
2020-10-14 17:40:32 +00:00
|
|
|
if (extra_has_feature("Disable Autojump By Default")) {
|
2020-10-03 00:34:39 +00:00
|
|
|
// Disable Autojump By Default
|
|
|
|
unsigned char autojump_patch[4] = {0x00, 0x30, 0xa0, 0xe3};
|
|
|
|
patch((void *) 0x44b90, autojump_patch);
|
|
|
|
}
|
2020-10-04 20:45:00 +00:00
|
|
|
|
2020-11-12 23:28:37 +00:00
|
|
|
// Show Block Outlines
|
|
|
|
int block_outlines = extra_has_feature("Show Block Outlines");
|
2020-11-20 19:05:08 +00:00
|
|
|
unsigned char outline_patch[4] = {block_outlines ? !touch_gui : touch_gui, 0x00, 0x50, 0xe3};
|
|
|
|
patch((void *) 0x4a210, outline_patch);
|
2020-11-20 19:54:07 +00:00
|
|
|
|
|
|
|
if (extra_has_feature("Remove Invalid Item Background")) {
|
|
|
|
// Remove Invalid Item Background (A Red Background That Appears For Items That Are Not Obtainable Without Modding/Inventory Editing)
|
|
|
|
unsigned char invalid_item_background_patch[4] = {0x00, 0xf0, 0x20, 0xe3};
|
|
|
|
patch((void *) 0x63c98, invalid_item_background_patch);
|
|
|
|
}
|
2020-11-20 21:38:23 +00:00
|
|
|
|
|
|
|
smooth_lighting = extra_has_feature("Smooth Lighting");
|
|
|
|
if (smooth_lighting) {
|
|
|
|
// Enable Smooth Lighting
|
|
|
|
unsigned char smooth_lighting_patch[4] = {0x01, 0x00, 0x53, 0xe3};
|
|
|
|
patch((void *) 0x59ea4, smooth_lighting_patch);
|
|
|
|
}
|
2020-10-01 15:08:46 +00:00
|
|
|
}
|