Skip to content

Commit

Permalink
Decode CurveData<T> with RawBuffer.
Browse files Browse the repository at this point in the history
Include getter/setter to modify data of a CurveData.
No allocator implemented to create/destroy/resize number of points of a curve.

WIP, it needs more testing.
  • Loading branch information
poirierlouis committed May 17, 2024
1 parent 1c283c3 commit 12d5788
Show file tree
Hide file tree
Showing 2 changed files with 112 additions and 7 deletions.
65 changes: 65 additions & 0 deletions include/RED4ext/NativeTypes-inl.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -288,3 +288,68 @@ RED4EXT_INLINE bool RED4ext::Variant::CanBeInlined(const RED4ext::CBaseRTTIType*
{
return aType->GetSize() <= InlineSize && aType->GetAlignment() <= InlineAlignment;
}

template<typename T>
RED4EXT_INLINE float* RED4ext::CurveBuffer<T>::GetPoints() const noexcept
{
return this + offsetPoints;
}

template<typename T>
RED4EXT_INLINE T* RED4ext::CurveBuffer<T>::GetValues() const noexcept
{
return this + offsetValues;
}

template<typename T>
RED4EXT_INLINE RED4ext::CurveBuffer<T>* RED4ext::CurveData<T>::GetCurve() const noexcept
{
return reinterpret_cast<RED4ext::CurveBuffer<T>*>(buffer.data);
}

template<typename T>
RED4EXT_INLINE uint32_t RED4ext::CurveData<T>::GetSize() const noexcept
{
return GetCurve()->size;
}

template<typename T>
RED4EXT_INLINE RED4ext::CurvePoint<T> RED4ext::CurveData<T>::GetPoint(uint32_t aIndex) const noexcept
{
if (aIndex >= GetSize())
{
return {.point = std::numeric_limits<float>::infinity(), .value = T()};
}
const CurveBuffer<T>* curve = GetCurve();
const float* points = curve->GetPoints();
const T* values = curve->GetValues();

return {points[aIndex], values[aIndex]};
}

template<typename T>
RED4EXT_INLINE void RED4ext::CurveData<T>::SetPoint(uint32_t aIndex, const RED4ext::CurvePoint<T>& aPoint) noexcept
{
SetPoint(aIndex, aPoint.point, aPoint.value);
}

template<typename T>
RED4EXT_INLINE void RED4ext::CurveData<T>::SetPoint(uint32_t aIndex, float aPoint, T aValue) noexcept
{
if (aIndex >= GetSize())
{
return;
}
const CurveBuffer<T>* curve = GetCurve();
float* points = curve->GetPoints();
T* values = curve->GetValues();

points[aIndex] = aPoint;
values[aIndex] = aValue;
}

template<typename T>
RED4EXT_INLINE RED4ext::CurvePoint<T> RED4ext::CurveData<T>::operator[](uint32_t aIndex) const noexcept
{
return GetPoint(aIndex);
}
54 changes: 47 additions & 7 deletions include/RED4ext/NativeTypes.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

#include <array>
#include <cstdint>
#include <limits>
#include <string_view>

#include <RED4ext/Buffer.hpp>
Expand All @@ -13,6 +14,8 @@
#include <RED4ext/InstanceType.hpp>
#include <RED4ext/NodeRef.hpp>
#include <RED4ext/ResourceReference.hpp>
#include <RED4ext/Scripting/Natives/Generated/curve/EInterpolationType.hpp>
#include <RED4ext/Scripting/Natives/Generated/curve/ESegmentsLinkType.hpp>

namespace RED4ext
{
Expand Down Expand Up @@ -209,18 +212,55 @@ static_assert(sizeof(StaticArray<std::array<uint8_t, 5>, 32>) ==
template<typename T, uint32_t MAX_LEN>
using NativeArray = std::array<T, MAX_LEN>;

template<typename T>
struct CurvePoint
{
float point;
T value;
};

template<typename T>
struct CurveBuffer
{
float* GetPoints() const noexcept;
T* GetValues() const noexcept;

uint32_t size; // 00
uint32_t unk04; // 04
uint32_t offsetPoints; // 08
uint32_t offsetValues; // 12
// float points[size]; // 16
// T values[size]; // 16 + size * sizeof(float)
};
RED4EXT_ASSERT_SIZE(CurveBuffer<float>, 0x10);
RED4EXT_ASSERT_OFFSET(CurveBuffer, size, 0x00);
RED4EXT_ASSERT_OFFSET(CurveBuffer, offsetPoints, 0x08);
RED4EXT_ASSERT_OFFSET(CurveBuffer, offsetValues, 0x12);

template<typename T>
struct CurveData
{
uint64_t unk00; // 00
uint64_t unk08; // 08
uint64_t unk10; // 10
uint64_t unk18; // 18
uint64_t unk20; // 20
uint64_t unk28; // 28
uint64_t unk30; // 30
CurveBuffer<T>* GetCurve() const noexcept;
uint32_t GetSize() const noexcept;

CurvePoint<T> GetPoint(uint32_t aIndex) const noexcept;
void SetPoint(uint32_t aIndex, const CurvePoint<T>& aPoint) noexcept;
void SetPoint(uint32_t aIndex, float aPoint, T aValue) noexcept;

[[nodiscard]] inline CurvePoint<T> operator[](uint32_t aIndex) const noexcept;

CName name; // 00
RawBuffer buffer; // 08
CBaseRTTIType* unk40; // 40 type to be tested
curve::EInterpolationType interpolationType; // 48
curve::ESegmentsLinkType linkType; // 49
};
RED4EXT_ASSERT_SIZE(CurveData<float>, 0x38);
RED4EXT_ASSERT_OFFSET(CurveData, name, 0x00);
RED4EXT_ASSERT_OFFSET(CurveData, buffer, 0x08);
RED4EXT_ASSERT_OFFSET(CurveData, unk40, 0x40);
RED4EXT_ASSERT_OFFSET(CurveData, interpolationType, 0x48);
RED4EXT_ASSERT_OFFSET(CurveData, linkType, 0x49);

template<typename T>
struct ScriptRef
Expand Down

0 comments on commit 12d5788

Please sign in to comment.