From 5d8aa2811320ecd5448f3f22fb14c6dcf945c539 Mon Sep 17 00:00:00 2001 From: TheBrokenRail Date: Tue, 17 Dec 2024 09:22:48 -0500 Subject: [PATCH] Make Biome-Tinted Grass Not Suck --- docs/CREDITS.md | 3 +- images/CMakeLists.txt | 2 +- images/mojang/grasscolor.png | Bin 0 -> 25237 bytes mods/src/misc/tinting.cpp | 100 +++++++++++++++++++++--------- symbols/CMakeLists.txt | 2 + symbols/src/level/BiomeSource.def | 9 +++ symbols/src/level/Level.def | 1 + symbols/src/level/Region.def | 5 ++ symbols/src/tile/Tile.def | 1 + 9 files changed, 93 insertions(+), 30 deletions(-) create mode 100644 images/mojang/grasscolor.png create mode 100644 symbols/src/level/BiomeSource.def create mode 100644 symbols/src/level/Region.def diff --git a/docs/CREDITS.md b/docs/CREDITS.md index d3ad7755c2..433b5d2106 100644 --- a/docs/CREDITS.md +++ b/docs/CREDITS.md @@ -7,4 +7,5 @@ | [Ghidra](https://ghidra-sre.org) | Used For Decompiling Minecraft: Pi Edition | | [RetDec](https://retdec.com) | Used For Decompiling Minecraft: Pi Edition | | [minecraft-linux/mcpelauncher-core](https://github.com/minecraft-linux/mcpelauncher-core/blob/6b5e17b5685a612143297ae4595bdd12327284f3/src/patch_utils.cpp#L42) | Original Function Overwrite Code | -| [Hooking C Functions at Runtime - Thomas Finch](http://thomasfinch.me/blog/2015/07/24/Hooking-C-Functions-At-Runtime.html) | Original Patching Code | \ No newline at end of file +| [Hooking C Functions at Runtime - Thomas Finch](http://thomasfinch.me/blog/2015/07/24/Hooking-C-Functions-At-Runtime.html) | Original Patching Code | +| [ReMinecraftPE](https://github.com/ReMinecraftPE/mcpe) | A Lot Of Decompiled Code | \ No newline at end of file diff --git a/images/CMakeLists.txt b/images/CMakeLists.txt index 27aab7e306..ded98ea0cc 100644 --- a/images/CMakeLists.txt +++ b/images/CMakeLists.txt @@ -19,7 +19,7 @@ install( DESTINATION "${MCPI_INSTALL_DIR}/data/images/item" ) install( - FILES "mojang/shadow.png" "mojang/vignette.png" + FILES "mojang/shadow.png" "mojang/vignette.png" "mojang/grasscolor.png" DESTINATION "${MCPI_INSTALL_DIR}/data/images/misc" ) diff --git a/images/mojang/grasscolor.png b/images/mojang/grasscolor.png new file mode 100644 index 0000000000000000000000000000000000000000..a6d9c2090c4d5723c3f01ffc3559ab248e9fcbc1 GIT binary patch literal 25237 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 Y(5}(#`*R6n1pa&zGJoEsIpVDU10aElA^-pY literal 0 HcmV?d00001 diff --git a/mods/src/misc/tinting.cpp b/mods/src/misc/tinting.cpp index e4cd6e4107..b3fa99c48f 100644 --- a/mods/src/misc/tinting.cpp +++ b/mods/src/misc/tinting.cpp @@ -1,42 +1,54 @@ -#include +#include +#include #include #include +#include #include "misc-internal.h" // Change Grass Color -static int32_t get_color(LevelSource *level_source, int32_t x, int32_t z) { - // Get Biome - const Biome *biome = level_source->getBiome(x, z); - if (biome == nullptr) { - return 0; +static bool grass_colors_loaded = false; +#define GRASS_COLORS_SIZE 256 +static uint32_t grass_colors[GRASS_COLORS_SIZE][GRASS_COLORS_SIZE]; +static void Minecraft_init_injection(Minecraft_init_t original, Minecraft *self) { + // Call Original Method + original(self); + // Load + const uint32_t id = self->textures->loadTexture("misc/grasscolor.png", true); + const Texture *data = self->textures->getTemporaryTextureData(id); + if (data == nullptr || data->width != GRASS_COLORS_SIZE || data->height != GRASS_COLORS_SIZE) { + return; } - // Return - return biome->color; -} -#define BIOME_BLEND_SIZE 7 -static int32_t GrassTile_getColor_injection(__attribute__((unused)) GrassTile_getColor_t original, __attribute__((unused)) GrassTile *tile, LevelSource *level_source, const int32_t x, __attribute__((unused)) int32_t y, const int32_t z) { - int r_sum = 0; - int g_sum = 0; - int b_sum = 0; - int color_sum = 0; - const int x_start = x - (BIOME_BLEND_SIZE / 2); - const int z_start = z - (BIOME_BLEND_SIZE / 2); - for (int x_offset = 0; x_offset < BIOME_BLEND_SIZE; x_offset++) { - for (int z_offset = 0; z_offset < BIOME_BLEND_SIZE; z_offset++) { - const int32_t color = get_color(level_source, x_start + x_offset, z_start + z_offset); - r_sum += (color >> 16) & 0xff; - g_sum += (color >> 8) & 0xff; - b_sum += color & 0xff; - color_sum++; + const uint32_t *texture = (uint32_t *) data->data; + // Copy + for (int y = 0; y < GRASS_COLORS_SIZE; y++) { + for (int x = 0; x < GRASS_COLORS_SIZE; x++) { + grass_colors[y][x] = texture[(y * GRASS_COLORS_SIZE) + x]; } } - const int r_avg = r_sum / color_sum; - const int g_avg = g_sum / color_sum; - const int b_avg = b_sum / color_sum; - return (r_avg << 16) | (g_avg << 8) | b_avg; + grass_colors_loaded = true; +} +static int32_t GrassTile_getColor_injection(__attribute__((unused)) GrassTile_getColor_t original, __attribute__((unused)) GrassTile *tile, LevelSource *level_source, const int32_t x, __attribute__((unused)) int32_t y, const int32_t z) { + // Get Level + Level *level = ((Region *) level_source)->level; + // Find Biome Temperature + BiomeSource *biome_source = level->getBiomeSource(); + biome_source->getBiomeBlock(x, z, 1, 1); + const float temperature = biome_source->temperature[0]; + float downfall = biome_source->downfall[0]; + // Get Grass Color + downfall *= temperature; + const int xx = (int) ((1 - temperature) * (GRASS_COLORS_SIZE - 1)); + const int yy = (int) ((1 - downfall) * (GRASS_COLORS_SIZE - 1)); + uint32_t color = grass_colors[yy][xx]; + // Convert From ABGR To ARGB + const uint8_t b = (color >> 16) & 0xff; + const uint8_t g = (color >> 8) & 0xff; + const uint8_t r = color & 0xff; + color = (r << 16) | (g << 8) | b; + return (int32_t) color; } static int32_t TallGrass_getColor_injection(TallGrass_getColor_t original, TallGrass *tile, LevelSource *level_source, const int32_t x, const int32_t y, const int32_t z) { const int32_t original_color = original(tile, level_source, x, y, z); @@ -47,6 +59,32 @@ static int32_t TallGrass_getColor_injection(TallGrass_getColor_t original, TallG } } +// Grass Side Tinting +CUSTOM_VTABLE(grass_side, Tile) { + vtable->shouldRenderFace = [](Tile *self, LevelSource *level_source, const int x, const int y, const int z, const int face) { + return face != 0 && face != 1 && Tile_vtable::base->shouldRenderFace(self, level_source, x, y, z, face); + }; + vtable->getColor = [](Tile *self, LevelSource *level_source, const int32_t x, const int32_t y, const int32_t z) { + return GrassTile_getColor_injection(nullptr, (GrassTile *) self, level_source, x, y, z); + }; +} +static Tile *get_fake_grass_side_tile() { + static Tile *out = nullptr; + if (out == nullptr) { + out = Tile::allocate(); + out->constructor(0, 38, Material::dirt); + out->vtable = get_grass_side_vtable(); + } + return out; +} +static bool TileRenderer_tesselateBlockInWorld_injection(TileRenderer_tesselateBlockInWorld_t original, TileRenderer *self, Tile *tile, const int x, const int y, const int z) { + const bool ret = original(self, tile, x, y, z); + if (tile == Tile::grass && tile->getTexture3((LevelSource *) self->level, x, y, z, 2) == 3) { + original(self, get_fake_grass_side_tile(), x, y, z); + } + return ret; +} + // No Block Tinting template static int32_t Tile_getColor_injection(__attribute__((unused)) const std::function &original, __attribute__((unused)) T *self, __attribute__((unused)) LevelSource *level_source, __attribute__((unused)) int x, __attribute__((unused)) int y, __attribute__((unused)) int z) { @@ -57,8 +95,14 @@ static int32_t Tile_getColor_injection(__attribute__((unused)) const std::functi void _init_misc_tinting() { // Change Grass Color if (feature_has("Add Biome Colors To Grass", server_disabled)) { + overwrite_calls(Minecraft_init, Minecraft_init_injection); overwrite_calls(GrassTile_getColor, GrassTile_getColor_injection); overwrite_calls(TallGrass_getColor, TallGrass_getColor_injection); + // Fancy Grass Side + // This Requires Alpha Testing On The Opaque Render-Layer, Which Could Hurt Performance + overwrite_calls(TileRenderer_tesselateBlockInWorld, TileRenderer_tesselateBlockInWorld_injection); + unsigned char nop_patch[4] = {0x00, 0xf0, 0x20, 0xe3}; // "nop" + patch((void *) 0x4a038, nop_patch); } // Disable Block Tinting diff --git a/symbols/CMakeLists.txt b/symbols/CMakeLists.txt index 14fb2a4b25..51a2a9ea58 100644 --- a/symbols/CMakeLists.txt +++ b/symbols/CMakeLists.txt @@ -97,6 +97,8 @@ set(SRC src/level/DistanceChunkSorter.def src/level/renderer/Chunk.def src/level/LevelStorage.def + src/level/BiomeSource.def + src/level/Region.def src/item/ItemRenderer.def src/item/ItemInHandRenderer.def src/item/AuxDataTileItem.def diff --git a/symbols/src/level/BiomeSource.def b/symbols/src/level/BiomeSource.def new file mode 100644 index 0000000000..ea6aa8d58e --- /dev/null +++ b/symbols/src/level/BiomeSource.def @@ -0,0 +1,9 @@ +static-property float tempScale = 0x110254; +static-property float downfallScale = 0x110250; + +vtable 0x110218; + +virtual-method Biome **getBiomeBlock(int x, int z, int param_1, int param_2) = 0x14; + +property float *temperature = 0x4; +property float *downfall = 0x8; \ No newline at end of file diff --git a/symbols/src/level/Level.def b/symbols/src/level/Level.def index c5cde735fe..b7f8078306 100644 --- a/symbols/src/level/Level.def +++ b/symbols/src/level/Level.def @@ -50,6 +50,7 @@ method bool getDirectSignal(int x, int y, int z, int direction) = 0xa5d2c; method bool canSeeSky(int x, int y, int z) = 0xa39b8; method bool isDay() = 0xa3d9c; method int getTopTile(int x, int z) = 0xa2cc8; +method BiomeSource *getBiomeSource() = 0xa3c64; virtual-method void tick() = 0x28; virtual-method void updateSleepingPlayerList() = 0x2c; diff --git a/symbols/src/level/Region.def b/symbols/src/level/Region.def new file mode 100644 index 0000000000..dd0f7ace5e --- /dev/null +++ b/symbols/src/level/Region.def @@ -0,0 +1,5 @@ +extends LevelSource; + +vtable 0x10ff58; + +property Level *level = 0x10; \ No newline at end of file diff --git a/symbols/src/tile/Tile.def b/symbols/src/tile/Tile.def index 8c38f6e17f..2668c19977 100644 --- a/symbols/src/tile/Tile.def +++ b/symbols/src/tile/Tile.def @@ -57,6 +57,7 @@ virtual-method Tile *setExplodeable(float explodeable) = 0xf4; virtual-method Tile *setDestroyTime(float destroy_time) = 0xf8; virtual-method void spawnResources(Level *level, int x, int y, int z, int data, float chance) = 0x80; virtual-method Tile *setLightBlock(int strength) = 0xec; +virtual-method bool shouldRenderFace(LevelSource *level_source, int x, int y, int z, int face) = 0x24; property int texture = 0x4; property int id = 0x8;