From 15a0a4f023bd3c5ef3d4dc4512886bffa828a33a Mon Sep 17 00:00:00 2001 From: Mr-Auto <36127424+Mr-Auto@users.noreply.github.com> Date: Thu, 8 Aug 2024 18:33:08 +0200 Subject: [PATCH] some render stuff --- docs/game_data/spel2.lua | 11 +++- docs/src/includes/_enums.md | 1 + docs/src/includes/_types.md | 11 +++- src/game_api/game_api.hpp | 21 +++---- src/game_api/render_api.cpp | 11 ++-- src/game_api/render_api.hpp | 55 ++++++++----------- src/game_api/script/usertypes/entity_lua.cpp | 18 ++++-- .../script/usertypes/vanilla_render_lua.cpp | 2 +- src/game_api/script/usertypes/vtables_lua.cpp | 3 +- src/game_api/thread_utils.hpp | 6 +- 10 files changed, 78 insertions(+), 61 deletions(-) diff --git a/docs/game_data/spel2.lua b/docs/game_data/spel2.lua index 8c57890d4..152286f64 100644 --- a/docs/game_data/spel2.lua +++ b/docs/game_data/spel2.lua @@ -2459,13 +2459,18 @@ function PRNG:random(min, max) end ---@class RenderInfo ---@field x number ---@field y number + ---@field offset_x number + ---@field offset_y number ---@field shader WORLD_SHADER ---@field source Quad ---@field destination Quad ---@field tilew number ---@field tileh number ---@field facing_left boolean + ---@field angle number + ---@field animation_frame integer ---@field render_inactive boolean + ---@field brightness number ---@field texture_num integer ---@field get_entity fun(self): Entity ---@field set_normal_map_texture fun(self, texture_id: TEXTURE): boolean @Sets second_texture to the texture specified, then sets third_texture to SHINE_0 and texture_num to 3. You still have to change shader to 30 to render with normal map (same as COG normal maps) @@ -2479,8 +2484,10 @@ function PRNG:random(min, max) end ---@field clear_virtual fun(self, callback_id: CallbackId): nil @Clears the hook given by `callback_id`, alternatively use `clear_callback()` inside the hook. ---@field set_pre_dtor fun(self, fun: fun(self: RenderInfo): nil): CallbackId @Hooks before the virtual function.
The callback signature is `nil dtor(RenderInfo self)` ---@field set_post_dtor fun(self, fun: fun(self: RenderInfo): nil): CallbackId @Hooks after the virtual function.
The callback signature is `nil dtor(RenderInfo self)` - ---@field set_pre_render fun(self, fun: fun(self: RenderInfo, number: number, vanilla_render_context: VanillaRenderContext): boolean): CallbackId @Hooks before the virtual function.
The callback signature is `bool render(RenderInfo self, number number, VanillaRenderContext vanilla_render_context)` - ---@field set_post_render fun(self, fun: fun(self: RenderInfo, number: number, vanilla_render_context: VanillaRenderContext): boolean): CallbackId @Hooks after the virtual function.
The callback signature is `nil render(RenderInfo self, number number, VanillaRenderContext vanilla_render_context)` + ---@field set_pre_draw fun(self, fun: fun(self: RenderInfo): boolean): CallbackId @Hooks before the virtual function.
The callback signature is `bool draw(RenderInfo self)`
Virtual function docs:
Called when entity enters view of the camera + ---@field set_post_draw fun(self, fun: fun(self: RenderInfo): boolean): CallbackId @Hooks after the virtual function.
The callback signature is `nil draw(RenderInfo self)`
Virtual function docs:
Called when entity enters view of the camera + ---@field set_pre_render fun(self, fun: fun(self: RenderInfo, offset: Vec2, vanilla_render_context: VanillaRenderContext): boolean): CallbackId @Hooks before the virtual function.
The callback signature is `bool render(RenderInfo self, Vec2 offset, VanillaRenderContext vanilla_render_context)` + ---@field set_post_render fun(self, fun: fun(self: RenderInfo, offset: Vec2, vanilla_render_context: VanillaRenderContext): boolean): CallbackId @Hooks after the virtual function.
The callback signature is `nil render(RenderInfo self, Vec2 offset, VanillaRenderContext vanilla_render_context)` ---@class Entity ---@field type EntityDB @Type of the entity, contains special properties etc. If you want to edit them just for this entity look at the EntityDB diff --git a/docs/src/includes/_enums.md b/docs/src/includes/_enums.md index c814abaf5..4cb867525 100644 --- a/docs/src/includes/_enums.md +++ b/docs/src/includes/_enums.md @@ -1231,6 +1231,7 @@ Name | Data | Description Name | Data | Description ---- | ---- | ----------- [DTOR](https://github.com/spelunky-fyi/overlunky/search?l=Lua&q=RENDER_INFO_OVERRIDE.DTOR) | 0 | +[DRAW](https://github.com/spelunky-fyi/overlunky/search?l=Lua&q=RENDER_INFO_OVERRIDE.DRAW) | 1 | [RENDER](https://github.com/spelunky-fyi/overlunky/search?l=Lua&q=RENDER_INFO_OVERRIDE.RENDER) | 3 | ## REPEAT_TYPE diff --git a/docs/src/includes/_types.md b/docs/src/includes/_types.md index ebdf84372..aa72f9220 100644 --- a/docs/src/includes/_types.md +++ b/docs/src/includes/_types.md @@ -939,13 +939,18 @@ Type | Name | Description ---- | ---- | ----------- float | [x](https://github.com/spelunky-fyi/overlunky/search?l=Lua&q=x) | float | [y](https://github.com/spelunky-fyi/overlunky/search?l=Lua&q=y) | +float | [offset_x](https://github.com/spelunky-fyi/overlunky/search?l=Lua&q=offset_x) | +float | [offset_y](https://github.com/spelunky-fyi/overlunky/search?l=Lua&q=offset_y) | [WORLD_SHADER](#WORLD_SHADER) | [shader](https://github.com/spelunky-fyi/overlunky/search?l=Lua&q=shader) | [Quad](#Quad) | [source](https://github.com/spelunky-fyi/overlunky/search?l=Lua&q=source) | [Quad](#Quad) | [destination](https://github.com/spelunky-fyi/overlunky/search?l=Lua&q=destination) | float | [tilew](https://github.com/spelunky-fyi/overlunky/search?l=Lua&q=tilew) | float | [tileh](https://github.com/spelunky-fyi/overlunky/search?l=Lua&q=tileh) | bool | [facing_left](https://github.com/spelunky-fyi/overlunky/search?l=Lua&q=facing_left) | +float | [angle](https://github.com/spelunky-fyi/overlunky/search?l=Lua&q=angle) | +int | [animation_frame](https://github.com/spelunky-fyi/overlunky/search?l=Lua&q=animation_frame) | bool | [render_inactive](https://github.com/spelunky-fyi/overlunky/search?l=Lua&q=render_inactive) | +float | [brightness](https://github.com/spelunky-fyi/overlunky/search?l=Lua&q=brightness) | int | [texture_num](https://github.com/spelunky-fyi/overlunky/search?l=Lua&q=texture_num) | [Entity](#Entity) | [get_entity()](https://github.com/spelunky-fyi/overlunky/search?l=Lua&q=get_entity) | bool | [set_normal_map_texture(TEXTURE texture_id)](https://github.com/spelunky-fyi/overlunky/search?l=Lua&q=set_normal_map_texture) | Sets second_texture to the texture specified, then sets third_texture to SHINE_0 and texture_num to 3. You still have to change shader to 30 to render with normal map (same as COG normal maps) @@ -959,8 +964,10 @@ bool | [set_texture_num(int num)](https://github.com/spelunky-fyi/overlunky/sear nil | [clear_virtual(CallbackId callback_id)](https://github.com/spelunky-fyi/overlunky/search?l=Lua&q=clear_virtual) | Clears the hook given by `callback_id`, alternatively use `clear_callback()` inside the hook. [CallbackId](#Aliases) | [set_pre_dtor(function fun)](https://github.com/spelunky-fyi/overlunky/search?l=Lua&q=set_pre_dtor) | Hooks before the virtual function.
The callback signature is `nil dtor(RenderInfo self)` [CallbackId](#Aliases) | [set_post_dtor(function fun)](https://github.com/spelunky-fyi/overlunky/search?l=Lua&q=set_post_dtor) | Hooks after the virtual function.
The callback signature is `nil dtor(RenderInfo self)` -[CallbackId](#Aliases) | [set_pre_render(function fun)](https://github.com/spelunky-fyi/overlunky/search?l=Lua&q=set_pre_render) | Hooks before the virtual function.
The callback signature is `bool render(RenderInfo self, float float, VanillaRenderContext vanilla_render_context)` -[CallbackId](#Aliases) | [set_post_render(function fun)](https://github.com/spelunky-fyi/overlunky/search?l=Lua&q=set_post_render) | Hooks after the virtual function.
The callback signature is `nil render(RenderInfo self, float float, VanillaRenderContext vanilla_render_context)` +[CallbackId](#Aliases) | [set_pre_draw(function fun)](https://github.com/spelunky-fyi/overlunky/search?l=Lua&q=set_pre_draw) | Hooks before the virtual function.
The callback signature is `bool draw(RenderInfo self)`
Virtual function docs:
Called when entity enters view of the camera +[CallbackId](#Aliases) | [set_post_draw(function fun)](https://github.com/spelunky-fyi/overlunky/search?l=Lua&q=set_post_draw) | Hooks after the virtual function.
The callback signature is `nil draw(RenderInfo self)`
Virtual function docs:
Called when entity enters view of the camera +[CallbackId](#Aliases) | [set_pre_render(function fun)](https://github.com/spelunky-fyi/overlunky/search?l=Lua&q=set_pre_render) | Hooks before the virtual function.
The callback signature is `bool render(RenderInfo self, Vec2 offset, VanillaRenderContext vanilla_render_context)` +[CallbackId](#Aliases) | [set_post_render(function fun)](https://github.com/spelunky-fyi/overlunky/search?l=Lua&q=set_post_render) | Hooks after the virtual function.
The callback signature is `nil render(RenderInfo self, Vec2 offset, VanillaRenderContext vanilla_render_context)` ### RoomOwnerDetails diff --git a/src/game_api/game_api.hpp b/src/game_api/game_api.hpp index d60a5c601..9f1f6da3f 100644 --- a/src/game_api/game_api.hpp +++ b/src/game_api/game_api.hpp @@ -8,13 +8,15 @@ struct Renderer { + // check x64dbg plugin for up to date structure + uint32_t render_width; // same as window size unless resolution scale is set uint32_t render_height; uint32_t fps; // changing it doesn't seam to do anything uint32_t fps_denominator; - uint32_t render_width2; // repeat? + uint32_t render_width2; // used by the liquids to know what part(?) of screen to draw on top of the liquid (for all the transformation effects) uint32_t render_height2; uint8_t flags1; @@ -27,14 +29,13 @@ struct Renderer size_t unknown38; // bool? float unknown39; // not sure if actually float - float unknown40; - float unknown41; + float unknown40; // some float counter + float brightness; // whole game brightness, can be set above 1 uint8_t unknown42[4]; - const char** unknown43a; // font/floor it's changing - const char** unknown43b; // noise0.dds - const char** unknown43c; // noise1.dds - size_t unknown44[4]; // null? - size_t unknown45; // bool? + const char** textures_to_load[7]; // textures to load for entity + uint32_t texture_num; // number of textures in use + + uint32_t unknown45; // padding? // feels like two standard containers or something size_t* unknown46; @@ -88,8 +89,8 @@ struct Renderer uint8_t skip3[0xAD8]; // probably some static arrays of ... stuff - size_t swap_chain; - // 3 more pointers, some bit fields, then 5 more pointers + size_t swap_chain; // unsure? + // a lot of stuff more, total size is 0x81138 bytes // somewhere there should be shaders stored diff --git a/src/game_api/render_api.cpp b/src/game_api/render_api.cpp index 2c22c2466..1562ce428 100644 --- a/src/game_api/render_api.cpp +++ b/src/game_api/render_api.cpp @@ -23,7 +23,6 @@ #include "state.hpp" // for State, StateMemory #include "strings.hpp" // #include "texture.hpp" // for Texture, get_textures, get_texture -#include "thread_utils.hpp" // for OnHeapPointer class JournalPage; struct Camera; @@ -660,7 +659,7 @@ void init_render_api_hooks() Entity* RenderInfo::get_entity() const { - return OnHeapPointer{entity_offset}.decode_local(); + return entity_offset.decode_local(); } uint32_t RenderInfo::get_aux_id() const @@ -672,7 +671,7 @@ bool RenderInfo::set_second_texture(TEXTURE texture_id) { if (auto* new_texture = ::get_texture(texture_id)) { - second_texture_name = new_texture->name; + texture_names[1] = new_texture->name; return true; } return false; @@ -682,7 +681,7 @@ bool RenderInfo::set_third_texture(TEXTURE texture_id) { if (auto* new_texture = ::get_texture(texture_id)) { - third_texture_name = new_texture->name; + texture_names[2] = new_texture->name; return true; } return false; @@ -691,7 +690,7 @@ bool RenderInfo::set_third_texture(TEXTURE texture_id) bool RenderInfo::set_texture_num(uint32_t num) { // Prevent some crashes - if ((num >= 2 && !second_texture_name) || (num >= 3 && !third_texture_name) || num >= 4) + if ((num >= 2 && !texture_names[1]) || (num >= 3 && !texture_names[2]) || num >= 4) { return false; } @@ -704,7 +703,7 @@ bool RenderInfo::set_normal_map_texture(TEXTURE texture_id) if (set_second_texture(texture_id)) { constexpr uint32_t SHINE_TEXTURE = 400; - third_texture_name = ::get_texture(SHINE_TEXTURE)->name; + texture_names[2] = ::get_texture(SHINE_TEXTURE)->name; texture_num = 3; return true; } diff --git a/src/game_api/render_api.hpp b/src/game_api/render_api.hpp index 0ccd13c10..ab8e4087d 100644 --- a/src/game_api/render_api.hpp +++ b/src/game_api/render_api.hpp @@ -17,6 +17,7 @@ #include "containers/game_vector.hpp" // for game_vector #include "math.hpp" // for Quad, AABB (ptr only) #include "texture.hpp" // for Texture +#include "thread_utils.hpp" // for OnHeapPointer struct JournalUI; struct Layer; @@ -261,12 +262,13 @@ struct RenderInfo float x; float y; uint32_t unknown3; - float unknown4; - uint32_t unknown5; + float offset_x; + float offset_y; uint32_t unknown6; uint32_t unknown7; - uint32_t unknown8; - uint32_t unknown9; + float unknown8; // used for parallax? + float unknown9; // automatically goes to 0, while it's non 0 game does (unknown9/unknown8) or something like that and influences position + float x_dupe1; // position last refresh float y_dupe1; // position last refresh uint32_t unknown10; @@ -274,7 +276,7 @@ struct RenderInfo float y_dupe2; uint32_t unknown11; uint8_t unknown_timer1; // can someone test this at higher refresh rate if it's tided to the fps or Hz? - uint8_t unknown_timer2; // for some entities this stops when the entity is not on screen but the above one don't + uint8_t unknown_timer2; // for some entities this stops when the entity is not on screen but the above one doesn't bool unknown12c; bool unknown12d; bool render_inactive; // stops all the rendering stuff, the value is forced thou @@ -287,7 +289,7 @@ struct RenderInfo bool unknown17; bool unknown18; uint32_t unknown19; - WORLD_SHADER shader; // 0 - 36, game crash at around 55 + WORLD_SHADER shader; uint8_t unknown20a; uint8_t unknown20b; uint8_t unknown20c; @@ -319,37 +321,26 @@ struct RenderInfo float angle2; float angle_related; uint32_t animation_frame; - uint32_t unknown38; - Texture* texture; - const char** texture_name; - - const char** second_texture_name; // Normal map texture on COG entities (shader 30), shine texture on ice entities. May not have a correct value on entities that don't use it - const char** third_texture_name; // Shine texture on COG entities (shader 30). May not have a correct value on entities that don't use it - size_t unknown41; // fourth texture?? seems to be somehow used if changing the texture_num to 4 - size_t unknown42; - size_t unknown43; - size_t unknown44; + uint32_t unknown38; // padding + Texture* texture; // probably just used for definition + const char** texture_names[7]; + // second_texture_name Normal map texture on COG entities (shader 30), shine texture on ice entities. May not have a correct value on entities that don't use it + // third_texture_name Shine texture on COG entities (shader 30). May not have a correct value on entities that don't use it + uint32_t texture_num; // liquids use 0, most sprite entities use 1, ice uses 2, COG entities use 3 - uint32_t unknown50; - size_t entity_offset; // the offset of the associated entity in memory, starting from the memory segment that State resides in + uint32_t padding1; + OnHeapPointer entity_offset; bool flip_horizontal; // facing left - uint8_t unknown52; - uint8_t unknown53; - uint8_t unknown54; + uint8_t padding2[3]; uint32_t unknown55; - float darkness; // 0.0 = completely black ; 1.0 = normal (dark effect like when on fire) - uint32_t unknown56; - uint32_t unknown57; - uint32_t unknown58; - float* unknown59; - uint32_t unknown60; - uint32_t unknown61; // end, next RenderInfo below + float brightness; // 0.0 = completely black ; 1.0 = normal (used for dark effect like when on fire) virtual ~RenderInfo() = 0; - virtual void unknown_v2() = 0; - virtual void update() = 0; - virtual void render(float*) = 0; - virtual bool unknown_3() = 0; // init? sets darkness to 1.0 at the start, then does some other stuff + /// Called when entity enters view of the camera + virtual void draw() = 0; // initializes positions + virtual void update() = 0; // math, basically always runs before render + virtual void render(Vec2* offset) = 0; + virtual bool set_entity(Texture* texture, Entity* entity) = 0; // gets the entity owning this RenderInfo Entity* get_entity() const; diff --git a/src/game_api/script/usertypes/entity_lua.cpp b/src/game_api/script/usertypes/entity_lua.cpp index 5a37bb72f..59884962c 100644 --- a/src/game_api/script/usertypes/entity_lua.cpp +++ b/src/game_api/script/usertypes/entity_lua.cpp @@ -91,6 +91,10 @@ void register_usertypes(sol::state& lua) &RenderInfo::x, "y", &RenderInfo::y, + "offset_x", + &RenderInfo::offset_x, + "offset_y", + &RenderInfo::offset_y, "shader", &RenderInfo::shader, "source", @@ -114,8 +118,14 @@ void register_usertypes(sol::state& lua) &RenderInfo::tileh, "facing_left", &RenderInfo::flip_horizontal, + "angle", + &RenderInfo::angle1, + "animation_frame", + &RenderInfo::animation_frame, "render_inactive", &RenderInfo::render_inactive, + "brightness", + &RenderInfo::brightness, "texture_num", sol::readonly(&RenderInfo::texture_num), "get_entity", @@ -125,20 +135,20 @@ void register_usertypes(sol::state& lua) "get_second_texture", [](const RenderInfo& ri) -> std::optional { - if (!ri.second_texture_name || ri.texture_num < 2) + if (!ri.texture_names[1] || ri.texture_num < 2) { return std::nullopt; } - return ::get_texture(std::string_view(*ri.second_texture_name)) /**/; + return ::get_texture(std::string_view(*ri.texture_names[1])) /**/; }, "get_third_texture", [](const RenderInfo& ri) -> std::optional { - if (!ri.third_texture_name || ri.texture_num < 3) + if (!ri.texture_names[2] || ri.texture_num < 3) { return std::nullopt; } - return ::get_texture(std::string_view(*ri.third_texture_name)) /**/; + return ::get_texture(std::string_view(*ri.texture_names[2])) /**/; }, "set_second_texture", &RenderInfo::set_second_texture, diff --git a/src/game_api/script/usertypes/vanilla_render_lua.cpp b/src/game_api/script/usertypes/vanilla_render_lua.cpp index 5e5f4246f..cf2c521e9 100644 --- a/src/game_api/script/usertypes/vanilla_render_lua.cpp +++ b/src/game_api/script/usertypes/vanilla_render_lua.cpp @@ -138,7 +138,7 @@ auto g_angle_style = CORNER_FINISH::ADAPTIVE; void VanillaRenderContext::set_corner_finish(CORNER_FINISH c) { - g_angle_style = c; + g_angle_style = c; // can i make this per lua environment instead of global? } // get a Quad to fill out the corner between two lines and fix their overlap diff --git a/src/game_api/script/usertypes/vtables_lua.cpp b/src/game_api/script/usertypes/vtables_lua.cpp index 5cb5f67f7..b690445fd 100644 --- a/src/game_api/script/usertypes/vtables_lua.cpp +++ b/src/game_api/script/usertypes/vtables_lua.cpp @@ -93,7 +93,8 @@ void register_usertypes(sol::state& lua) RenderInfo, CallbackType::Entity, VTableEntry<"dtor", 0x0, void()>, - VTableEntry<"render", 0x3, void(float*), BackBinder>>; + VTableEntry<"draw", 0x1, void()>, + VTableEntry<"render", 0x3, void(Vec2*), BackBinder>>; static RenderInfoVTable render_info_vtable(lua, lua["RenderInfo"], "RENDER_INFO_OVERRIDE"); // Define the implementations for the LuaBackend handlers diff --git a/src/game_api/thread_utils.hpp b/src/game_api/thread_utils.hpp index d36fd826d..73853283b 100644 --- a/src/game_api/thread_utils.hpp +++ b/src/game_api/thread_utils.hpp @@ -20,12 +20,12 @@ class OnHeapPointer { } - T* decode() + T* decode() const { return reinterpret_cast(ptr_ + heap_base()); } - T* decode_local() + T* decode_local() const { auto lhb = local_heap_base(); if (lhb == 0) @@ -34,7 +34,7 @@ class OnHeapPointer return reinterpret_cast(ptr_ + lhb); } - T* operator->() + T* operator->() const { return decode(); }