From 3b3e844b6b35d357088787403ab43c66c84c9118 Mon Sep 17 00:00:00 2001 From: ragnarok-clanker Date: Wed, 28 Oct 2026 23:23:02 +0000 Subject: [PATCH] Decompile fn_21110 (CGameActor::ApplyPendingUnknown0408) Batch #1899 by ragnarok-clanker: 0 byte-identical, 1 confirmed by peer review. - fn_21110 CGameActor::ApplyPendingUnknown0408: logic confirmed by peer review Peer-reviewed-by: Yommy Accepted without human review: peers confirmed the logic ("same" ahead by at least 3, with 70% of the votes). --- Source/Contents/Actors/GameActor.h | 11 +- Source/Contents/Actors/GameObject.cpp | 129 +++++++++++++++++++++ Source/Contents/Actors/RenderObject.h | 4 + Source/Contents/Actors/RenderObjectState.h | 5 +- 4 files changed, 146 insertions(+), 3 deletions(-) diff --git a/Source/Contents/Actors/GameActor.h b/Source/Contents/Actors/GameActor.h index 05105ea..f15ac4f 100644 --- a/Source/Contents/Actors/GameActor.h +++ b/Source/Contents/Actors/GameActor.h @@ -25,7 +25,8 @@ public: /* 0238 */ unsigned char unknown_0238; /* 0239 */ unsigned char unknown_0239[0x1B]; /* 0254 */ std::uint32_t routeStartTick; - /* 0258 */ unsigned char unknown_0258[0x08]; + /* 0258 */ unsigned char unknown_0258[0x04]; + /* 025C */ int unknown_025C; /* 0260 */ int unknown_0260; /* 0264 */ unsigned char unknown_0264[0x58]; /* 02BC */ int bodyState; @@ -47,7 +48,10 @@ public: /* 0378 */ float unknown_0378; /* 037C */ unsigned char unknown_037C[0x4C]; /* 03C8 */ int unknown_03C8; - /* 03CC */ unsigned char unknown_03CC[0x44]; + /* 03CC */ unsigned char unknown_03CC[0x38]; + /* 0404 */ int unknown_0404; + /* 0408 */ int unknown_0408; + /* 040C */ unsigned char unknown_040C[0x04]; void SetAnimation(unsigned animation, int motion, int repeat) override; @@ -88,6 +92,7 @@ public: void SetUnknown02E4(int value); void SetUnknown02C8(int value); void SetUnknown0260(int value); + void ApplyPendingUnknown0408(); void ProcessBodyState(); int GetShield(); bool FindRoute(int startX, int startY, int fractionX, int fractionY, int destX, int destY, int speed); @@ -111,6 +116,8 @@ static_assert(offsetof(CGameActor, unknown_0348) == 0x348); static_assert(offsetof(CGameActor, unknown_0360) == 0x360); static_assert(offsetof(CGameActor, unknown_0378) == 0x378); static_assert(offsetof(CGameActor, unknown_03C8) == 0x3C8); +static_assert(offsetof(CGameActor, unknown_025C) == 0x25C); +static_assert(offsetof(CGameActor, unknown_0408) == 0x408); #endif #endif diff --git a/Source/Contents/Actors/GameObject.cpp b/Source/Contents/Actors/GameObject.cpp index 31f4f93..7502fe9 100644 --- a/Source/Contents/Actors/GameObject.cpp +++ b/Source/Contents/Actors/GameObject.cpp @@ -1,7 +1,17 @@ #include "Contents/Actors/GameObject.h" +#include "Contents/Actors/GameActor.h" #include "Client/Replay.h" #include "Contents/Actors/RenderObject.h" +#include "Contents/Configuration/ServiceConfiguration.h" +#include "Render/DeviceContext/DCSurface.h" +#include "Render/Renderer.h" +#include "Render/SpriteQuad.h" +#include "Render/TextureQuad.h" +#include "Render/Textures/SpriteAtlas.h" +#include "Render/Textures/Texture.h" +#include "Resource/ResourceMgr.h" #include "Resource/Sprites/ActionResource.h" +#include "Utility/Math/AffineMatrix.h" #include "Utility/Math/ScalarConversion.h" namespace { @@ -73,8 +83,101 @@ void CRenderObject::Draw(int argument) { // OFFSET: 0x00CB35F0 // OFFSET: 0x00CB39A0 +// FUNCTION: fn_21106 +void CRenderObject::DrawQuad(const SpriteQuad& quad, const std::uint32_t* palette, int blend, float offsetX, float offsetY, int depthOffset) { + SpriteAtlasRecord record{}; + const SpriteRleImage* image = quad.image; + CTexture* texture = static_cast(const_cast(image->unknown_0008)); + if (!texture) { + texture = g_renderer->atlas.Find(image, palette, record); + if (!texture) { + texture = g_renderer->atlas.Insert(*GetRenderSystemHolder()->system, image, palette, record, g_serviceType, g_resourceReuseDelay); + } + } else { + record.u0 = 0.0f; + record.v0 = 0.0f; + record.u1 = static_cast(texture->ImageWidth()) / static_cast(texture->TextureWidth()); + record.v1 = static_cast(texture->ImageHeight()) / static_cast(texture->TextureHeight()); + } + + const double depthBias = depthOffset * 0.000001; + const double rhwBias = depthOffset * 0.0002; + const float bottomRhw = static_cast(rhwBias + quad.bottomRhw); + const float topRhw = static_cast(quad.topRhw + rhwBias); + const float bottomZ = RhwToDepth(static_cast(depthBias + quad.bottomRhw)); + const float topZ = RhwToDepth(static_cast(quad.topRhw + depthBias)); + + RenderPrimitive* primitive = g_renderer->primitives.Acquire(); + RenderVertex* vertices = primitive->vertices; + primitive->texture = texture; + + if (quad.angle != 0.0f) { + const float cosine = ClientCosine(static_cast(quad.angle)); + const float sine = ClientSine(static_cast(quad.angle)); + const float halfWidth = (quad.right - quad.left) * 0.5f; + const float halfHeight = (quad.bottom - quad.top) * 0.5f; + const float centerX = quad.left + halfWidth + offsetX; + const float centerY = quad.top + halfHeight + offsetY; + const float minX = -halfWidth; + const float minY = -halfHeight; + + vertices[0].x = minX * cosine - minY * sine + centerX + 0.5f; + vertices[0].y = minY * cosine + minX * sine + centerY + 0.5f; + vertices[1].x = halfWidth * cosine - minY * sine + centerX + 0.5f; + vertices[1].y = minY * cosine + halfWidth * sine + centerY + 0.5f; + vertices[2].x = minX * cosine - halfHeight * sine + centerX + 0.5f; + vertices[2].y = halfHeight * cosine + minX * sine + centerY + 0.5f; + vertices[3].x = halfWidth * cosine - halfHeight * sine + centerX + 0.5f; + vertices[3].y = halfHeight * cosine + halfWidth * sine + centerY + 0.5f; + } else { + vertices[0].x = quad.left + 0.5f; + vertices[0].y = quad.top + 0.5f; + vertices[1].x = quad.right + 0.5f; + vertices[1].y = quad.top + 0.5f; + vertices[2].x = quad.left + 0.5f; + vertices[2].y = quad.bottom + 0.5f; + vertices[3].x = quad.right + 0.5f; + vertices[3].y = quad.bottom + 0.5f; + } + + if (*palette == 0xD77B) { + record.u1 -= 0.002f; + } + + vertices[0].rhw = topRhw; + vertices[0].z = topZ; + vertices[0].u = record.u0; + vertices[0].v = record.v0; + vertices[0].diffuse = quad.color; + vertices[1].rhw = topRhw; + vertices[1].z = topZ; + vertices[1].u = record.u1; + vertices[1].v = record.v0; + vertices[1].diffuse = quad.color; + vertices[2].rhw = bottomRhw; + vertices[2].z = bottomZ; + vertices[2].u = record.u0; + vertices[2].v = record.v1; + vertices[2].diffuse = quad.color; + vertices[3].rhw = bottomRhw; + vertices[3].z = bottomZ; + vertices[3].u = record.u1; + vertices[3].v = record.v1; + vertices[3].diffuse = quad.color; + + primitive->unknown_0018 = 5; + primitive->unknown_001C = blend != 5 ? 6 : 2; + primitive->unknown_0014 = g_renderer->twoPass != 1; + g_renderer->queues.Submit(primitive, static_cast(blend | this->render.unknown_0124), g_renderer->fog.supported != 0, g_depthStart, g_depthEnd); +} // OFFSET: 0x00CB3F40 +// FUNCTION: fn_21107 +void CRenderObject::DrawFlippedQuad(SpriteQuad& quad, const std::uint32_t* palette, int blend, float x, float y, int depthOffset) { + quad.angle = 180.0f; + this->DrawQuad(quad, palette, blend, (x - quad.right) + (x - quad.left), (y - quad.bottom) + (y - quad.top), depthOffset); +} + // OFFSET: 0x00CB3FA0 // FUNCTION: fn_21108 @@ -102,6 +205,32 @@ void CRenderObject::SendValueMessage(int value, CGameObject* target) { } // OFFSET: 0x00CB4070 +// FUNCTION: fn_21110 +void CGameActor::ApplyPendingUnknown0408() { + const int pending = this->unknown_0408; + this->unknown_0404 = pending; + this->unknown_0408 = 0; + this->render.isLieOnGround = false; + this->render.unknown_00A4Bytes[1] = 1; + this->render.isMotionFreezed = false; + this->render.unknown_0114 = 0; + + int value; + if (pending == 1) { + value = 0x1104; + } else if (pending == 2) { + value = 0x1105; + } else { + value = this->unknown_025C; + } + this->Slot21(value); + this->Slot32(); + + if (this->render.unknown_0070 != 3) { + this->render.unknown_0070 = 0; + this->Slot15(0, 1); + } +} // OFFSET: 0x00CB4100 diff --git a/Source/Contents/Actors/RenderObject.h b/Source/Contents/Actors/RenderObject.h index f244996..6713fcf 100644 --- a/Source/Contents/Actors/RenderObject.h +++ b/Source/Contents/Actors/RenderObject.h @@ -7,6 +7,8 @@ #include +struct SpriteQuad; + class CRenderObject : public CGameObject { public: CRenderObject(ResourceMgr& resources, JobNames& names); @@ -28,6 +30,8 @@ public: void SetActionSpeed(float speed); void DrawSprite(int argument, bool seasonal, float offset); void DrawShadow(int argument, float scale); + void DrawQuad(const SpriteQuad& quad, const std::uint32_t* palette, int blend, float offsetX, float offsetY, int depthOffset); + void DrawFlippedQuad(SpriteQuad& quad, const std::uint32_t* palette, int blend, float x, float y, int depthOffset); void SendValueMessage(int value, CGameObject* target); void SetActionName(ResourceMgr& resources, const char* name); void SetSpriteName(ResourceMgr& resources, const char* name); diff --git a/Source/Contents/Actors/RenderObjectState.h b/Source/Contents/Actors/RenderObjectState.h index 58e33eb..c92754d 100644 --- a/Source/Contents/Actors/RenderObjectState.h +++ b/Source/Contents/Actors/RenderObjectState.h @@ -55,7 +55,10 @@ struct RenderObjectState { /* 00A1 */ unsigned char enabled; /* 00A2 */ unsigned char unknown_00A2; /* 00A3 */ unsigned char unknown_00A3; - /* 00A4 */ std::uint16_t unknown_00A4; + union { + /* 00A4 */ std::uint16_t unknown_00A4; + /* 00A4 */ unsigned char unknown_00A4Bytes[2]; + }; /* 00A6 */ unsigned char unknown_00A6[2]; /* 00A8 */ std::uint32_t unknown_00A8; /* 00AC */ int screenX;