Decompile 9 functions in Source/Client/ReplayControl.cpp, Source/Client/Replay.h, ...

Batch #1043 by ragnarok-clanker: 0 byte-identical, 9 confirmed by peer review.

- fn_19316 Replay::AnimationScale: logic confirmed by peer review
- fn_19343 Replay::SetState: logic confirmed by peer review
- fn_21118 CRenderObject::SetAnimation: logic confirmed by peer review
- fn_21119 CRenderObject::SetColor: logic confirmed by peer review
- fn_21130 CRenderObject::SetSequenceDeadline: logic confirmed by peer review
- fn_21131 CRenderObject::SetSequenceInterval: logic confirmed by peer review
- fn_21132 CRenderObject::SetAnimationSequence: logic confirmed by peer review
- fn_21133 CRenderObject::SetFrameSequence: logic confirmed by peer review
- fn_21140 CRenderObject::SetAnimationSpeed: logic confirmed by peer review

Reviewed-by: ragnarok-clanker
Adds to the build: Source/Client/ReplayControl.cpp
This commit is contained in:
ragnarok-clanker 2026-10-27 11:01:59 +00:00
commit 2a43504543
6 changed files with 229 additions and 4 deletions

View file

@ -99,6 +99,8 @@ public:
bool WriteSection(int id, std::vector<unsigned char>& bytes, int event);
int WriteHeader(int event);
std::vector<unsigned char> BuildMetadata();
float AnimationScale() const;
bool SetState(int state);
};
extern int g_replayAnimationScaling;

View file

@ -0,0 +1,53 @@
#include "Client/Replay.h"
// OFFSET: 0x00B844C0
// FUNCTION: fn_19316
float Replay::AnimationScale() const {
if (this->speed == 0.25f) {
return 1.4f;
}
if (this->speed == 0.5f) {
return 1.2f;
}
if (this->speed == 1.0f) {
return 1.0f;
}
if (this->speed == 2.0f) {
return 0.8f;
}
if (this->speed == 4.0f) {
return 0.6f;
}
if (this->speed == 8.0f) {
return 0.4f;
}
if (this->speed == 16.0f) {
return 0.2f;
}
return 1.0f;
}
// OFFSET: 0x00B872F0
// FUNCTION: fn_19343
bool Replay::SetState(int state) {
if (state == 4) {
this->state = 1;
return true;
}
if (state == 5) {
this->state = 6;
return true;
}
if (state >= 1 && state <= 8) {
this->state = state;
if (state <= 3) {
g_replayAnimationScaling = 0;
}
} else {
this->state = 1;
}
if (state >= 6 && state <= 8) {
g_replayAnimationScaling = 1;
}
return true;
}

View file

@ -1,7 +1,12 @@
#include "Contents/Actors/RenderObject.h"
#include "Client/Replay.h"
#include "Resource/Sprites/ActionResource.h"
#include "Utility/Math/ScalarConversion.h"
#include <windows.h>
#include <timeapi.h>
// OFFSET: 0x00CA8730
// FUNCTION: fn_20991
CRenderObject::CRenderObject(ResourceMgr& resources, JobNames& names) : render(resources, names) {
@ -33,3 +38,136 @@ void CRenderObject::SetScreenPosition(float x, float y) {
this->render.screenX = TruncateToInt(x);
this->render.screenY = TruncateToInt(y);
}
// OFFSET: 0x00CBFAE0
// FUNCTION: fn_21118
void CRenderObject::SetAnimation(unsigned animation, int, int repeat) {
float speed = this->render.action->Speed(animation);
if (g_replayAnimationScaling != 0) {
speed *= Replay::Instance().AnimationScale();
}
if (speed > 0.0f) {
this->render.speed = speed;
}
if (this->render.speed < 1.0f) {
if (g_replayAnimationScaling != 0) {
speed = Replay::Instance().AnimationScale();
if (speed > 0.0f) {
this->render.speed = speed;
}
} else {
this->render.speed = 1.0f;
}
}
speed = this->render.speed * this->render.unknown_0064;
if (g_replayAnimationScaling != 0) {
speed *= Replay::Instance().AnimationScale();
}
if (speed > 0.0f) {
this->render.speed = speed;
}
this->render.animation = animation;
this->render.previousAnimation = animation;
this->render.unknown_003C = 0;
this->render.unknown_006C = repeat;
this->render.unknown_009C[1] = 0;
this->render.unknown_0060 = 1.0f;
this->render.unknown_0064 = 1.0f;
this->render.unknown_00C8 = 0;
this->render.unknown_00D8 = 0;
this->render.unknown_00DC = 0;
}
// OFFSET: 0x00CBFC00
// FUNCTION: fn_21119
void CRenderObject::SetColor(int alpha, int red, int green, int blue) {
if (alpha != -1) {
this->render.color = (this->render.color & 0x00FFFFFFu) | (static_cast<std::uint32_t>(alpha) << 24);
}
if (red != -1) {
this->render.color = (this->render.color & 0xFF00FFFFu) | ((static_cast<std::uint32_t>(red) & 0xFFu) << 16);
}
if (green != -1) {
this->render.color = (this->render.color & 0xFFFF00FFu) | ((static_cast<std::uint32_t>(green) & 0xFFu) << 8);
}
if (blue != -1) {
this->render.color = (this->render.color & 0xFFFFFF00u) | static_cast<unsigned char>(blue);
}
}
// OFFSET: 0x00CC1E70
// FUNCTION: fn_21130
void CRenderObject::SetSequenceDeadline(std::uint32_t duration) {
this->render.sequenceDeadline = timeGetTime() + duration;
}
// OFFSET: 0x00CC1E90
// FUNCTION: fn_21131
void CRenderObject::SetSequenceInterval(unsigned char interval) {
this->render.unknown_00C2 = interval;
}
// OFFSET: 0x00CC1EA0
// FUNCTION: fn_21132
void CRenderObject::SetAnimationSequence(
unsigned char animation0, unsigned char frame0, unsigned char animation1, unsigned char frame1,
unsigned char animation2, unsigned char frame2, unsigned char animation3, unsigned char frame3,
unsigned char animation4, unsigned char frame4, int timed, std::uint32_t duration, int loop
) {
this->render.sequenceAnimations[0] = animation0;
this->render.sequenceFrames[0] = frame0;
this->render.sequenceAnimations[1] = animation1;
this->render.sequenceFrames[1] = frame1;
this->render.sequenceAnimations[2] = animation2;
this->render.sequenceFrames[2] = frame2;
this->render.sequenceAnimations[3] = animation3;
this->render.sequenceFrames[3] = frame3;
this->render.sequenceAnimations[4] = animation4;
this->render.sequenceFrames[4] = frame4;
this->render.sequenceAnimation = animation0;
this->render.sequenceFrame = frame0;
this->render.sequenceIndex = 0;
this->render.sequenceLast = 4;
this->render.sequenceLoop = loop;
this->render.sequenceTimed = timed;
this->render.sequenceFinished = 0;
this->render.unknown_00D8 = 1;
this->render.unknown_00C8 = 0;
this->render.unknown_00DC = 0;
this->render.sequenceDeadline = timed != 0 ? timeGetTime() + duration : 0;
this->render.sequenceTick = 1;
}
// OFFSET: 0x00CC1FA0
// FUNCTION: fn_21133
void CRenderObject::SetFrameSequence(
unsigned char animation, unsigned char firstFrame, unsigned char lastFrame, unsigned char finishAnimation,
unsigned char finishFrame, int timed, std::uint32_t duration, int loop
) {
this->render.sequenceAnimation = animation;
this->render.sequenceFrame = firstFrame;
this->render.sequenceIndex = firstFrame;
this->render.sequenceLast = lastFrame;
this->render.sequenceFinishAnimation = finishAnimation;
this->render.sequenceFinishFrame = finishFrame;
this->render.sequenceLoop = loop;
this->render.sequenceTimed = timed;
this->render.sequenceFinished = 0;
this->render.unknown_00C8 = 1;
this->render.unknown_00DC = 0;
this->render.unknown_00D8 = 0;
this->render.sequenceDeadline = timed != 0 ? timeGetTime() + duration : 0;
this->render.sequenceTick = 1;
}
// OFFSET: 0x00CC2780
// FUNCTION: fn_21140
void CRenderObject::SetAnimationSpeed(float speed) {
if (g_replayAnimationScaling != 0) {
speed *= Replay::Instance().AnimationScale();
}
if (speed > 0.0f) {
this->render.speed = speed;
}
}

View file

@ -14,10 +14,24 @@ public:
virtual void SetScreenBounds(const float* bounds, float x, float y);
virtual void SetScreenPosition(float x, float y);
virtual void SetAnimation(unsigned animation, int motion, int repeat);
static float __stdcall Heading(float x, float z, float targetX, float targetZ);
void Face(float x, float z);
float HorizontalDistance(float x, float z) const;
float Distance(float x, float y, float z) const;
void SetAnimationSpeed(float speed);
void SetColor(int alpha, int red, int green, int blue);
void SetSequenceDeadline(std::uint32_t duration);
void SetSequenceInterval(unsigned char interval);
void SetAnimationSequence(
unsigned char animation0, unsigned char frame0, unsigned char animation1, unsigned char frame1,
unsigned char animation2, unsigned char frame2, unsigned char animation3, unsigned char frame3,
unsigned char animation4, unsigned char frame4, int timed, std::uint32_t duration, int loop
);
void SetFrameSequence(
unsigned char animation, unsigned char firstFrame, unsigned char lastFrame, unsigned char finishAnimation,
unsigned char finishFrame, int timed, std::uint32_t duration, int loop
);
RenderObjectState render;
};

View file

@ -3,6 +3,7 @@
#include "Contents/InstantVar.h"
#include <cstddef>
#include <cstdint>
#include <string>
@ -57,14 +58,24 @@ struct RenderObjectState {
/* 00AC */ int screenX;
/* 00B0 */ int screenY;
/* 00B4 */ unsigned char unknown_00B4;
/* 00B5 */ unsigned char unknown_00B5[13];
/* 00B5 */ unsigned char sequenceAnimation;
/* 00B6 */ unsigned char sequenceFrame;
/* 00B7 */ unsigned char sequenceAnimations[5];
/* 00BC */ unsigned char sequenceFrames[5];
/* 00C1 */ unsigned char sequenceLast;
/* 00C2 */ unsigned char unknown_00C2;
/* 00C3 */ unsigned char unknown_00C3[5];
/* 00C3 */ unsigned char sequenceFinishAnimation;
/* 00C4 */ unsigned char sequenceFinishFrame;
/* 00C5 */ unsigned char sequenceIndex;
/* 00C6 */ unsigned char unknown_00C6[2];
/* 00C8 */ std::uint32_t unknown_00C8;
/* 00CC */ unsigned char unknown_00CC[12];
/* 00CC */ int sequenceLoop;
/* 00D0 */ int sequenceTimed;
/* 00D4 */ int sequenceFinished;
/* 00D8 */ std::uint32_t unknown_00D8;
/* 00DC */ std::uint32_t unknown_00DC;
/* 00E0 */ unsigned char unknown_00E0[8];
/* 00E0 */ std::uint32_t sequenceTick;
/* 00E4 */ std::uint32_t sequenceDeadline;
/* 00E8 */ std::uint32_t flags;
/* 00EC */ std::uint32_t unknown_00EC;
/* 00F0 */ std::uint16_t unknown_00F0;
@ -94,6 +105,12 @@ struct RenderObjectState {
#if defined(_WIN32) && !defined(_WIN64)
static_assert(sizeof(RenderObjectState) == 296);
static_assert(offsetof(RenderObjectState, sequenceAnimation) == 0xA5);
static_assert(offsetof(RenderObjectState, sequenceAnimations) == 0xA7);
static_assert(offsetof(RenderObjectState, sequenceFrames) == 0xAC);
static_assert(offsetof(RenderObjectState, sequenceFinishAnimation) == 0xB3);
static_assert(offsetof(RenderObjectState, sequenceLoop) == 0xBC);
static_assert(offsetof(RenderObjectState, sequenceDeadline) == 0xD4);
#endif
#endif

View file

@ -262,6 +262,7 @@
"Source/Client/ModeFadeOut.cpp": 0,
"Source/Client/Registry.cpp": 0,
"Source/Client/Replay.cpp": 0,
"Source/Client/ReplayControl.cpp": 0,
"Source/Client/ReplayPacketRecorder.cpp": 2,
"Source/Client/Session.cpp": 0,
"Source/Contents/ActorGeometry.cpp": 4,