diff --git a/Source/Contents/Actors/SpriteDrawingPolicy.h b/Source/Contents/Actors/SpriteDrawingPolicy.h index 19c55b2..f3f5aa3 100644 --- a/Source/Contents/Actors/SpriteDrawingPolicy.h +++ b/Source/Contents/Actors/SpriteDrawingPolicy.h @@ -2,6 +2,11 @@ #define RAGNAROK_SOURCE_CONTENTS_ACTORS_SPRITEDRAWINGPOLICY_H class LuaScript; +struct SpriteCellQuad; +struct SpriteColor; +struct SpriteFrameCell; +struct SpriteRleImage; +struct tagRECT; struct SpriteDrawingPolicy { LuaScript& script; @@ -15,6 +20,10 @@ struct SpriteDrawingPolicy { bool DrawOnTop() const; bool SetRobe(int robe); + bool ProjectCell( + int unused, int layer, float scale, const SpriteFrameCell& cell, float x, float y, const float* position, float shift, float& bottomDepth, + float& topDepth, const SpriteRleImage& image, SpriteCellQuad& quad, tagRECT& bounds, SpriteColor& color, int offsetX, int offsetY, int flags + ) const; }; #endif diff --git a/Source/Render/SpriteGeometry.cpp b/Source/Render/SpriteGeometry.cpp new file mode 100644 index 0000000..121de88 --- /dev/null +++ b/Source/Render/SpriteGeometry.cpp @@ -0,0 +1,67 @@ +#include "Contents/Actors/SpriteDrawingPolicy.h" +#include "Render/Renderer.h" +#include "Render/SpriteGeometry.h" +#include "Render/Textures/SpritePixels.h" + +#include + +// GLOBAL: gl_24537 +float g_tangent = 0.16f; +// GLOBAL: gl_24577 +float g_cameraScaleY = 0.000009f; +// GLOBAL: gl_24578 +float g_cameraScaleX = 0.000036f; +// GLOBAL: gl_24535 +float g_heightScale = 1.34f; + +// OFFSET: 0x0080D7B0 +// FUNCTION: fn_10102 +bool SpriteDrawingPolicy::ProjectCell( + int unused, int layer, float scale, const SpriteFrameCell& cell, float x, float y, const float* position, float shift, float& bottomDepth, + float& topDepth, const SpriteRleImage& image, SpriteCellQuad& quad, tagRECT& bounds, SpriteColor& color, int offsetX, int offsetY, int flags +) const { + const float depthBias = scale / g_heightScale * g_cameraScaleX; + const double scaleY = scale * cell.scaleY; + const double scaleX = scale * cell.scaleX; + const float top = (cell.y + offsetY) * scaleY + y; + const float bottom = ((image.unknown_0006 + 1) * image.height + cell.y + offsetY) * scaleY + y + 1.0; + float left; + float right; + + if (cell.mirrored & 1) { + left = ((image.unknown_0004 + 1) * image.width + cell.x + offsetX) * scaleX + x; + right = (offsetX + cell.x) * scaleX + x + 1.0; + + if (top >= g_renderer->viewport.height || bottom <= 0.0f || right >= g_renderer->viewport.width || left <= 0.0f) { + return false; + } + } else { + left = (cell.x + offsetX) * scaleX + x; + right = ((image.unknown_0004 + 1) * image.width + cell.x + offsetX) * scaleX + x + 1.0; + + if (top >= g_renderer->viewport.height || bottom <= 0.0f || left >= g_renderer->viewport.width || right <= 0.0f) { + return false; + } + } + + bottomDepth = 1.0f / ((bottom - y) * g_tangent + position[2]) + (layer + 3) * g_cameraScaleY + depthBias; + topDepth = 1.0f / ((top - y) * g_tangent + position[2]) + (layer + 3) * g_cameraScaleY + depthBias; + quad.left = left + shift; + quad.top = top; + quad.bottom = bottom; + quad.right = right + shift; + quad.bottomDepth = bottomDepth; + quad.topDepth = topDepth; + quad.angle = static_cast(cell.unknown_001C); + bounds.left = static_cast(left); + bounds.top = static_cast(top); + bounds.right = static_cast(right); + bounds.bottom = static_cast(bottom); + color.alpha = static_cast((cell.color >> 24) * 255.0f / 255.0f); + color.red = static_cast((cell.color & 0xFF) * 255.0f / 255.0f); + color.green = static_cast((cell.color >> 8 & 0xFF) * 255.0f / 255.0f); + color.blue = static_cast((cell.color >> 16 & 0xFF) * 255.0f / 255.0f); + quad.color = color; + + return true; +} diff --git a/Source/Render/SpriteGeometry.h b/Source/Render/SpriteGeometry.h new file mode 100644 index 0000000..5166c48 --- /dev/null +++ b/Source/Render/SpriteGeometry.h @@ -0,0 +1,34 @@ +#ifndef RAGNAROK_SOURCE_RENDER_SPRITEGEOMETRY_H +#define RAGNAROK_SOURCE_RENDER_SPRITEGEOMETRY_H + +#include +#include + +struct SpriteColor { + /* 0000 */ std::uint8_t blue; + /* 0001 */ std::uint8_t green; + /* 0002 */ std::uint8_t red; + /* 0003 */ std::uint8_t alpha; +}; + +struct SpriteCellQuad { + /* 0000 */ float top; + /* 0004 */ float left; + /* 0008 */ float bottom; + /* 000C */ float right; + /* 0010 */ float bottomDepth; + /* 0014 */ float topDepth; + /* 0018 */ SpriteColor color; + /* 001C */ float angle; +}; + +extern float g_tangent; +extern float g_cameraScaleY; +extern float g_cameraScaleX; +extern float g_heightScale; + +static_assert(sizeof(SpriteColor) == 4); +static_assert(sizeof(SpriteCellQuad) == 0x20); +static_assert(offsetof(SpriteCellQuad, color) == 0x18); + +#endif diff --git a/data/compile.json b/data/compile.json index fad499c..3e6b785 100644 --- a/data/compile.json +++ b/data/compile.json @@ -524,6 +524,7 @@ "Source/Render/RendererDX7.cpp": 0, "Source/Render/ScreenGeometry.cpp": 0, "Source/Render/ScreenRectangle.cpp": 0, + "Source/Render/SpriteGeometry.cpp": 0, "Source/Render/Text/FontCache.cpp": 0, "Source/Render/Text/TextContext.cpp": 0, "Source/Render/TextureQuad.cpp": 0,