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();
}