diff --git a/dependencies/symbol-processor/src b/dependencies/symbol-processor/src index 0b696bd..059e572 160000 --- a/dependencies/symbol-processor/src +++ b/dependencies/symbol-processor/src @@ -1 +1 @@ -Subproject commit 0b696bd55b31416929d0a29d84ad50ab5ba0ceae +Subproject commit 059e572256667f696f2f1ac9f5253859d54f50c4 diff --git a/launcher/src/client/available-feature-flags b/launcher/src/client/available-feature-flags index a8436a3..feba5ff 100644 --- a/launcher/src/client/available-feature-flags +++ b/launcher/src/client/available-feature-flags @@ -8,7 +8,7 @@ TRUE Fix Sign Placement TRUE Show Block Outlines FALSE Expand Creative Mode Inventory FALSE Remove Creative Mode Restrictions -TRUE Animated Water +TRUE Animated Water & Lava TRUE Remove Invalid Item Background TRUE Disable "gui_blocks" Atlas TRUE Fix Camera Rendering diff --git a/libreborn/include/libreborn/util.h b/libreborn/include/libreborn/util.h index 46e9d8f..b63e86b 100644 --- a/libreborn/include/libreborn/util.h +++ b/libreborn/include/libreborn/util.h @@ -50,6 +50,25 @@ const char *reborn_get_version(); int reborn_is_headless(); int reborn_is_server(); +// Customize VTable +#define CUSTOM_VTABLE(name, parent) \ + static void _setup_##name##_vtable(parent##_vtable *vtable); \ + static parent##_vtable *get_##name##_vtable() { \ + static parent##_vtable *vtable = NULL; \ + /* Allocate VTable */ \ + if (vtable == NULL) { \ + /* Init */ \ + vtable = dup_##parent##_vtable(parent##_vtable_base); \ + ALLOC_CHECK(vtable); \ + /* Setup */ \ + _setup_##name##_vtable(vtable); \ + } \ + /* Return */ \ + return vtable; \ + } \ + /* User-Defined Setup Code */ \ + static void _setup_##name##_vtable(parent##_vtable *vtable) + #ifdef __cplusplus } #endif diff --git a/mods/CMakeLists.txt b/mods/CMakeLists.txt index 2931a92..b367523 100644 --- a/mods/CMakeLists.txt +++ b/mods/CMakeLists.txt @@ -95,6 +95,7 @@ else() src/screenshot/screenshot.c # textures src/textures/textures.cpp + src/textures/lava.cpp ) endif() diff --git a/mods/src/bucket/bucket.cpp b/mods/src/bucket/bucket.cpp index 60b9638..888a4ee 100644 --- a/mods/src/bucket/bucket.cpp +++ b/mods/src/bucket/bucket.cpp @@ -117,19 +117,10 @@ static int32_t BucketItem_useOn(__attribute__((unused)) Item *item, ItemInstance } // Bucket VTable -static Item_vtable *get_bucket_vtable() { - static Item_vtable *vtable = NULL; - if (vtable == NULL) { - // Init - vtable = dup_Item_vtable(Item_vtable_base); - ALLOC_CHECK(vtable); - - // Modify - vtable->getDescriptionId = BucketItem_getDescriptionId; - vtable->getIcon = BucketItem_getIcon; - vtable->useOn = BucketItem_useOn; - } - return vtable; +CUSTOM_VTABLE(bucket, Item) { + vtable->getDescriptionId = BucketItem_getDescriptionId; + vtable->getIcon = BucketItem_getIcon; + vtable->useOn = BucketItem_useOn; } // Create Items diff --git a/mods/src/textures/lava.cpp b/mods/src/textures/lava.cpp new file mode 100644 index 0000000..edc416d --- /dev/null +++ b/mods/src/textures/lava.cpp @@ -0,0 +1,245 @@ +#include + +#include +#include + +#include "textures-internal.h" + +// Lava texture code was originally decompield by @iProgramMC as part of ReMinecraftPE. +// See: https://github.com/ReMinecraftPE/mcpe + +// Structures +struct LavaTexture { + DynamicTexture super; + int field_14; + int field_18; + float m_data1[256]; + float m_data2[256]; + float m_data3[256]; + float m_data4[256]; +}; +struct LavaSideTexture { + DynamicTexture super; + int field_14; + int field_18; + int field_1C; + float m_data1[256]; + float m_data2[256]; + float m_data3[256]; + float m_data4[256]; +}; +struct FireTexture { + DynamicTexture super; + float m_data1[320]; + float m_data2[320]; + Random m_random; +}; + +// LavaTexture +CUSTOM_VTABLE(lava_texture, DynamicTexture) { + vtable->tick = [](DynamicTexture *super) { + LavaTexture *self = (LavaTexture *) super; + for (int x = 0; x < 16; x++) { + for (int y = 0; y < 16; y++) { + float f = 0.0F; + int ax = int(Mth_sin((float(x) * float(M_PI) * 2) / 16.0f) * 1.2f); + int ay = int(Mth_sin((float(y) * float(M_PI) * 2) / 16.0f) * 1.2f); + for (int bx = x - 1; bx <= x + 1; bx++) { + for (int by = y - 1; by <= y + 1; by++) { + int k2 = (bx + ay) & 0xf; + int i3 = (by + ax) & 0xf; + f += self->m_data1[k2 + i3 * 16]; + } + } + self->m_data2[x + y * 16] = f / 10.0f + ((self->m_data3[(x & 0xf) + ((y + 0) & 0xf) * 16] + self->m_data3[((x + 1) & 0xf) + (y & 0xf) * 16] + self->m_data3[((x + 1) & 0xf) + ((y + 1) & 0xf) * 16] + self->m_data3[(x & 0xf) + ((y + 1) & 0xf) * 16]) * 0.25f) * 0.8f; + self->m_data3[x + y * 16] += self->m_data4[x + y * 16] * 0.01f; + if (self->m_data3[x + y * 16] < 0.0f) { + self->m_data3[x + y * 16] = 0.0f; + } + self->m_data4[x + y * 16] -= 0.06f; + if (Mth_random() < 0.005f) { + self->m_data4[x + y * 16] = 1.5f; + } + } + } + std::swap(self->m_data1, self->m_data2); + for (int i = 0; i < 256; i++) { + float x1 = self->m_data1[i] * 2.0f; + if (x1 > 1.0f) { + x1 = 1.0f; + } + if (x1 < 0.0f) { + x1 = 0.0f; + } + self->super.pixels[i * 4 + 0] = int(155.0f + 100.0f * x1); + self->super.pixels[i * 4 + 1] = int(255.0f * x1 * x1); + self->super.pixels[i * 4 + 2] = int(128.0f * x1 * x1 * x1 * x1); + self->super.pixels[i * 4 + 3] = 255; + } + }; +} +static DynamicTexture *create_lava_texture() { + // Construct + LavaTexture *texture = new LavaTexture; + ALLOC_CHECK(texture); + DynamicTexture_constructor(&texture->super, Tile_lava->texture); + // Set VTable + texture->super.vtable = get_lava_texture_vtable(); + // Setup + texture->field_14 = 0; + texture->field_18 = 0; + for (int i = 0; i < 256; i++) { + texture->m_data1[i] = 0.0f; + texture->m_data2[i] = 0.0f; + texture->m_data3[i] = 0.0f; + texture->m_data4[i] = 0.0f; + } + // Return + return (DynamicTexture *) texture; +} + +// LavaSideTexture +CUSTOM_VTABLE(lava_side_texture, DynamicTexture) { + vtable->tick = [](DynamicTexture *super) { + LavaSideTexture *self = (LavaSideTexture *) super; + self->field_1C++; + for (int x = 0; x < 16; x++) { + for (int y = 0; y < 16; y++) { + float f = 0.0F; + int ax = int(Mth_sin((float(x) * float(M_PI) * 2) / 16.0f) * 1.2f); + int ay = int(Mth_sin((float(y) * float(M_PI) * 2) / 16.0f) * 1.2f); + for (int bx = x - 1; bx <= x + 1; bx++) { + for (int by = y - 1; by <= y + 1; by++) { + int k2 = (bx + ay) & 0xf; + int i3 = (by + ax) & 0xf; + f += self->m_data1[k2 + i3 * 16]; + } + } + self->m_data2[x + y * 16] = f / 10.0f + ((self->m_data3[(x & 0xf) + ((y + 0) & 0xf) * 16] + self->m_data3[((x + 1) & 0xf) + (y & 0xf) * 16] + self->m_data3[((x + 1) & 0xf) + ((y + 1) & 0xf) * 16] + self->m_data3[(x & 0xf) + ((y + 1) & 0xf) * 16]) * 0.25f) * 0.8f; + self->m_data3[x + y * 16] += self->m_data4[x + y * 16] * 0.01f; + if (self->m_data3[x + y * 16] < 0.0f) { + self->m_data3[x + y * 16] = 0.0f; + } + self->m_data4[x + y * 16] -= 0.06f; + if (Mth_random() < 0.005f) { + self->m_data4[x + y * 16] = 1.5f; + } + } + } + std::swap(self->m_data1, self->m_data2); + for (int i = 0; i < 256; i++) { + float x1 = self->m_data1[(i - 16 * (self->field_1C / 3)) & 0xFF] * 2.0f; + if (x1 > 1.0f) { + x1 = 1.0f; + } + if (x1 < 0.0f) { + x1 = 0.0f; + } + self->super.pixels[i * 4 + 0] = int(155.0f + 100.0f * x1); + self->super.pixels[i * 4 + 1] = int(255.0f * x1 * x1); + self->super.pixels[i * 4 + 2] = int(128.0f * x1 * x1 * x1 * x1); + self->super.pixels[i * 4 + 3] = 255; + } + }; +} +static DynamicTexture *create_lava_side_texture() { + // Construct + LavaSideTexture *texture = new LavaSideTexture; + ALLOC_CHECK(texture); + DynamicTexture_constructor(&texture->super, Tile_lava->texture + 1); + // Set VTable + texture->super.vtable = get_lava_side_texture_vtable(); + // Setup + texture->field_14 = 0; + texture->field_18 = 0; + texture->field_1C = 0; + texture->super.texture_size = 2; + for (int i = 0; i < 256; i++) { + texture->m_data1[i] = 0.0f; + texture->m_data2[i] = 0.0f; + texture->m_data3[i] = 0.0f; + texture->m_data4[i] = 0.0f; + } + // Return + return (DynamicTexture *) texture; +} + +// FireTexture +CUSTOM_VTABLE(fire_texture, DynamicTexture) { + vtable->tick = [](DynamicTexture *super) { + FireTexture *self = (FireTexture *) super; + for (int i = 0; i < 16; i++) { + for (int j = 0; j < 20; j++) { + int l = 18; + float f1 = self->m_data1[i + ((j + 1) % 20) * 16] * l; + for (int i1 = i - 1; i1 <= i + 1; i1++) { + for (int k1 = j; k1 <= j + 1; k1++) { + int i2 = i1; + int k2 = k1; + if (i2 >= 0 && k2 >= 0 && i2 < 16 && k2 < 20) + { + f1 += self->m_data1[i2 + k2 * 16]; + } + l++; + } + } + self->m_data2[i + j * 16] = f1 / 25.2f; + if (j >= 19) { + union { + uint32_t x; + uint8_t b[4]; + } a; + a.x = Random_genrand_int32(&self->m_random); + self->m_data2[i + j * 16] = 0.2f + (((a.b[3] / 256.0f) * 0.1f) + ((((a.b[0] / 256.0f) * (a.b[1] / 256.0f)) * (a.b[2] / 256.0f)) * 4.0f)); + } + } + } + std::swap(self->m_data1, self->m_data2); + for (int i = 0; i < 256; i++) { + float x = self->m_data1[i] * 1.8f; + if (x > 1.0f) { + x = 1.0f; + } + if (x < 0.0f) { + x = 0.0f; + } + self->super.pixels[4 * i + 0] = int(x * 155.0f + 100.0f); + self->super.pixels[4 * i + 1] = int(x * x * 255.0f); + self->super.pixels[4 * i + 2] = int(x * x * x * x * x * x * x * x * x * x * 255.0f); + self->super.pixels[4 * i + 3] = x >= 0.5f ? 255 : 0; + } + }; +} +static DynamicTexture *create_fire_texture(int a2) { + // Construct + FireTexture *texture = new FireTexture; + ALLOC_CHECK(texture); + DynamicTexture_constructor(&texture->super, Tile_fire->texture + (16 * a2)); + // Set VTable + texture->super.vtable = get_fire_texture_vtable(); + // Setup Random + int seed = Common_getTimeMs(); + texture->m_random.seed = seed; + texture->m_random.param_1 = 0x271; + texture->m_random.param_2 = false; + texture->m_random.param_3 = 0; + // Return + return (DynamicTexture *) texture; +} + +// Add Textures +static void Textures_addDynamicTexture_injection(Textures *textures, DynamicTexture *dynamic_texture) { + // Call Original Method + Textures_addDynamicTexture(textures, dynamic_texture); + + // Add Lava + Textures_addDynamicTexture(textures, create_lava_texture()); + Textures_addDynamicTexture(textures, create_lava_side_texture()); + Textures_addDynamicTexture(textures, create_fire_texture(0)); + Textures_addDynamicTexture(textures, create_fire_texture(1)); +} + +// Init +void _init_textures_lava() { + overwrite_call((void *) 0x170b4, (void *) Textures_addDynamicTexture_injection); +} diff --git a/mods/src/textures/textures-internal.h b/mods/src/textures/textures-internal.h new file mode 100644 index 0000000..d195604 --- /dev/null +++ b/mods/src/textures/textures-internal.h @@ -0,0 +1,3 @@ +#pragma once + +__attribute__((visibility("internal"))) void _init_textures_lava(); diff --git a/mods/src/textures/textures.cpp b/mods/src/textures/textures.cpp index 091edd3..297fcd6 100644 --- a/mods/src/textures/textures.cpp +++ b/mods/src/textures/textures.cpp @@ -11,6 +11,7 @@ #include #include #include +#include "textures-internal.h" #include "stb_image.h" @@ -213,8 +214,10 @@ static Texture AppPlatform_linux_loadTexture_injection(__attribute__((unused)) A // Init void init_textures() { // Tick Dynamic Textures (Animated Water) - if (feature_has("Animated Water", server_disabled)) { + if (feature_has("Animated Water & Lava", server_disabled)) { misc_run_on_tick(Minecraft_tick_injection); + // Animated Lava + _init_textures_lava(); } // Scale Animated Textures diff --git a/symbols/CMakeLists.txt b/symbols/CMakeLists.txt index 75341d0..005dec3 100644 --- a/symbols/CMakeLists.txt +++ b/symbols/CMakeLists.txt @@ -131,12 +131,14 @@ set(SRC src/misc/Vec3.def src/misc/HitResult.def src/misc/PerfRenderer.def - src/misc/Texture.def - src/misc/Textures.def + src/textures/Texture.def + src/textures/Textures.def + src/textures/DynamicTexture.def src/misc/SoundEngine.def src/misc/Common.def src/misc/Config.def src/misc/Random.def + src/misc/Mth.def src/input/IMoveInput.def src/input/IBuildInput.def src/input/MouseBuildInput.def diff --git a/symbols/src/misc/Common.def b/symbols/src/misc/Common.def index 076b533..1d75668 100644 --- a/symbols/src/misc/Common.def +++ b/symbols/src/misc/Common.def @@ -5,3 +5,4 @@ static-method void renderCursor(float x, float y, Minecraft *minecraft) = 0x480c static-method void sleepMs(int x) = 0x13cf4; static-method int sdl_key_to_minecraft_key(int sdl_key) = 0x1243c; static-method void anGenBuffers(int count, uint *buffers) = 0x5f28c; +static-method int getTimeMs() = 0x13cd4; diff --git a/symbols/src/misc/Mth.def b/symbols/src/misc/Mth.def new file mode 100644 index 0000000..a3cc129 --- /dev/null +++ b/symbols/src/misc/Mth.def @@ -0,0 +1,5 @@ +static-property Random _random = 0x17a87c; +static-method float random() = 0x777a4; + +static-method float sin(float x) = 0x7775c; +static-method float cos(float x) = 0x77728; diff --git a/symbols/src/misc/Random.def b/symbols/src/misc/Random.def index 5ceca14..1a6fdbc 100644 --- a/symbols/src/misc/Random.def +++ b/symbols/src/misc/Random.def @@ -1,3 +1,10 @@ -method int genrand_int32() = 0x42cf8; +size 0x9d0; -static-property Random random = 0x17a87c; +method float nextFloat() = 0x42cf8; +method uint genrand_int32() = 0x50e14; +method void init_genrand(uint seed) = 0x27d38; + +property uint seed = 0x0; +property int param_1 = 0x9c4; // Set To 0x271 +property bool param_2 = 0x9c8; // Set To False +property float param_3 = 0x9cc; // Set To 0 diff --git a/symbols/src/textures/DynamicTexture.def b/symbols/src/textures/DynamicTexture.def new file mode 100644 index 0000000..152690e --- /dev/null +++ b/symbols/src/textures/DynamicTexture.def @@ -0,0 +1,12 @@ +vtable 0x108120; +vtable-size 0x10; + +size 0x40c; +constructor (int texture) = 0x66154; + +virtual-method void tick() = 0x8; +virtual-method void bindTexture(Textures *textures) = 0xc; + +property int texture_index = 0x4; +property int texture_size = 0x8; +property uchar pixels[1024] = 0xc; diff --git a/symbols/src/misc/Texture.def b/symbols/src/textures/Texture.def similarity index 100% rename from symbols/src/misc/Texture.def rename to symbols/src/textures/Texture.def diff --git a/symbols/src/misc/Textures.def b/symbols/src/textures/Textures.def similarity index 72% rename from symbols/src/misc/Textures.def rename to symbols/src/textures/Textures.def index 82fe458..f906892 100644 --- a/symbols/src/misc/Textures.def +++ b/symbols/src/textures/Textures.def @@ -1,3 +1,4 @@ method void tick(bool param_1) = 0x531c4; method int loadAndBindTexture(std::string *name) = 0x539cc; method int assignTexture(std::string *name, uchar *data) = 0x5354c; +method void addDynamicTexture(DynamicTexture *texture) = 0x534f8; diff --git a/symbols/src/tile/Tile.def b/symbols/src/tile/Tile.def index fe01648..33da5e0 100644 --- a/symbols/src/tile/Tile.def +++ b/symbols/src/tile/Tile.def @@ -15,6 +15,7 @@ virtual-method int getColor(LevelSource *level_source, int x, int y, int z) = 0x virtual-method int getRenderShape() = 0xc; virtual-method Tile *setDescriptionId(std::string *description_id) = 0xe0; +property int texture = 0x4; property int id = 0x8; property int category = 0x3c; @@ -38,6 +39,7 @@ static-property Tile *info_updateGame2 = 0x181c6c; static-property Tile *bedrock = 0x181cc4; static-property Tile *tallgrass = 0x181d0c; static-property Tile *stoneSlab = 0x181b44; +static-property Tile *fire = 0x181de0; // "Carried" Tiles static-property Tile *leaves = 0x18120c;