Make Biome-Tinted Grass Not Suck
This commit is contained in:
parent
aea31dd4c8
commit
5d8aa28113
@ -7,4 +7,5 @@
|
|||||||
| [Ghidra](https://ghidra-sre.org) | Used For Decompiling Minecraft: Pi Edition |
|
| [Ghidra](https://ghidra-sre.org) | Used For Decompiling Minecraft: Pi Edition |
|
||||||
| [RetDec](https://retdec.com) | 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 |
|
| [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 |
|
| [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 |
|
@ -19,7 +19,7 @@ install(
|
|||||||
DESTINATION "${MCPI_INSTALL_DIR}/data/images/item"
|
DESTINATION "${MCPI_INSTALL_DIR}/data/images/item"
|
||||||
)
|
)
|
||||||
install(
|
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"
|
DESTINATION "${MCPI_INSTALL_DIR}/data/images/misc"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
BIN
images/mojang/grasscolor.png
Normal file
BIN
images/mojang/grasscolor.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 25 KiB |
@ -1,42 +1,54 @@
|
|||||||
#include <libreborn/patch.h>
|
#include <cstdint>
|
||||||
|
|
||||||
|
#include <libreborn/patch.h>
|
||||||
#include <symbols/minecraft.h>
|
#include <symbols/minecraft.h>
|
||||||
|
|
||||||
#include <mods/feature/feature.h>
|
#include <mods/feature/feature.h>
|
||||||
|
#include <mods/extend/extend.h>
|
||||||
|
|
||||||
#include "misc-internal.h"
|
#include "misc-internal.h"
|
||||||
|
|
||||||
// Change Grass Color
|
// Change Grass Color
|
||||||
static int32_t get_color(LevelSource *level_source, int32_t x, int32_t z) {
|
static bool grass_colors_loaded = false;
|
||||||
// Get Biome
|
#define GRASS_COLORS_SIZE 256
|
||||||
const Biome *biome = level_source->getBiome(x, z);
|
static uint32_t grass_colors[GRASS_COLORS_SIZE][GRASS_COLORS_SIZE];
|
||||||
if (biome == nullptr) {
|
static void Minecraft_init_injection(Minecraft_init_t original, Minecraft *self) {
|
||||||
return 0;
|
// 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
|
const uint32_t *texture = (uint32_t *) data->data;
|
||||||
return biome->color;
|
// Copy
|
||||||
}
|
for (int y = 0; y < GRASS_COLORS_SIZE; y++) {
|
||||||
#define BIOME_BLEND_SIZE 7
|
for (int x = 0; x < GRASS_COLORS_SIZE; x++) {
|
||||||
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) {
|
grass_colors[y][x] = texture[(y * GRASS_COLORS_SIZE) + x];
|
||||||
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 int r_avg = r_sum / color_sum;
|
grass_colors_loaded = true;
|
||||||
const int g_avg = g_sum / color_sum;
|
}
|
||||||
const int b_avg = b_sum / color_sum;
|
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) {
|
||||||
return (r_avg << 16) | (g_avg << 8) | b_avg;
|
// 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) {
|
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);
|
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
|
// No Block Tinting
|
||||||
template <typename T>
|
template <typename T>
|
||||||
static int32_t Tile_getColor_injection(__attribute__((unused)) const std::function<int(T *, LevelSource *, int, int, int)> &original, __attribute__((unused)) T *self, __attribute__((unused)) LevelSource *level_source, __attribute__((unused)) int x, __attribute__((unused)) int y, __attribute__((unused)) int z) {
|
static int32_t Tile_getColor_injection(__attribute__((unused)) const std::function<int(T *, LevelSource *, int, int, int)> &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() {
|
void _init_misc_tinting() {
|
||||||
// Change Grass Color
|
// Change Grass Color
|
||||||
if (feature_has("Add Biome Colors To Grass", server_disabled)) {
|
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(GrassTile_getColor, GrassTile_getColor_injection);
|
||||||
overwrite_calls(TallGrass_getColor, TallGrass_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
|
// Disable Block Tinting
|
||||||
|
@ -97,6 +97,8 @@ set(SRC
|
|||||||
src/level/DistanceChunkSorter.def
|
src/level/DistanceChunkSorter.def
|
||||||
src/level/renderer/Chunk.def
|
src/level/renderer/Chunk.def
|
||||||
src/level/LevelStorage.def
|
src/level/LevelStorage.def
|
||||||
|
src/level/BiomeSource.def
|
||||||
|
src/level/Region.def
|
||||||
src/item/ItemRenderer.def
|
src/item/ItemRenderer.def
|
||||||
src/item/ItemInHandRenderer.def
|
src/item/ItemInHandRenderer.def
|
||||||
src/item/AuxDataTileItem.def
|
src/item/AuxDataTileItem.def
|
||||||
|
9
symbols/src/level/BiomeSource.def
Normal file
9
symbols/src/level/BiomeSource.def
Normal file
@ -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;
|
@ -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 canSeeSky(int x, int y, int z) = 0xa39b8;
|
||||||
method bool isDay() = 0xa3d9c;
|
method bool isDay() = 0xa3d9c;
|
||||||
method int getTopTile(int x, int z) = 0xa2cc8;
|
method int getTopTile(int x, int z) = 0xa2cc8;
|
||||||
|
method BiomeSource *getBiomeSource() = 0xa3c64;
|
||||||
|
|
||||||
virtual-method void tick() = 0x28;
|
virtual-method void tick() = 0x28;
|
||||||
virtual-method void updateSleepingPlayerList() = 0x2c;
|
virtual-method void updateSleepingPlayerList() = 0x2c;
|
||||||
|
5
symbols/src/level/Region.def
Normal file
5
symbols/src/level/Region.def
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
extends LevelSource;
|
||||||
|
|
||||||
|
vtable 0x10ff58;
|
||||||
|
|
||||||
|
property Level *level = 0x10;
|
@ -57,6 +57,7 @@ virtual-method Tile *setExplodeable(float explodeable) = 0xf4;
|
|||||||
virtual-method Tile *setDestroyTime(float destroy_time) = 0xf8;
|
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 void spawnResources(Level *level, int x, int y, int z, int data, float chance) = 0x80;
|
||||||
virtual-method Tile *setLightBlock(int strength) = 0xec;
|
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 texture = 0x4;
|
||||||
property int id = 0x8;
|
property int id = 0x8;
|
||||||
|
Loading…
Reference in New Issue
Block a user