diff --git a/include/utility/aglParameter.h b/include/utility/aglParameter.h index 58fea02..60963e7 100644 --- a/include/utility/aglParameter.h +++ b/include/utility/aglParameter.h @@ -102,7 +102,8 @@ class ParameterBase { void applyResource(ResParameter res, f32 t); void applyString(const sead::SafeString& string, bool x); virtual void postApplyResource_(const void*, size_t) {} - void createByTypeName(const sead::SafeString& a, const sead::SafeString& b); + static ParameterBase* createByTypeName(const sead::SafeString& name, + const sead::SafeString& bufferSize); virtual bool isBinary() const { return false; } virtual bool isBinaryInternalBuffer() const { return true; } @@ -302,18 +303,20 @@ class Parameter : public ParameterBase { template class ParameterBuffer : public Parameter { public: - ParameterBuffer(sead::Heap* heap, s32 num) { + ParameterBuffer() = default; + + ~ParameterBuffer() override { freeBuffer(); } + + void allocateBuffer(sead::Heap* heap, u32 num) { SEAD_ASSERT(!isBinaryInternalBuffer()); this->mValue = new (heap) T[num]; mBufferSize = num; mBufferAllocated = true; - for (s32 i = 0; i < num; ++i) + for (u32 i = 0; i < num; ++i) this->mValue[i] = {}; } - ~ParameterBuffer() override { freeBuffer(); } - void freeBuffer() { if (!mBufferAllocated) return; @@ -343,7 +346,7 @@ class ParameterBuffer : public Parameter { void postApplyResource_(const void* data, size_t size) override { if (isBinaryInternalBuffer()) return; - this->mValue = data; + this->mValue = const_cast(static_cast(data)); mBufferSize = size / sizeof(T); } @@ -369,6 +372,8 @@ class ParameterDirection3f : public Parameter { template class ParameterCurve : public ParameterBase { public: + ParameterCurve() { reset(); } + ParameterCurve(const sead::SafeString& name, const sead::SafeString& label, IParameterObj* param_obj); diff --git a/include/utility/aglParameterCurve.hpp b/include/utility/aglParameterCurve.hpp index de23a22..b6a2919 100644 --- a/include/utility/aglParameterCurve.hpp +++ b/include/utility/aglParameterCurve.hpp @@ -13,12 +13,26 @@ inline ParameterCurve::ParameterCurve(const sead::SafeString& name, reset(); } +// NOTE: This is a hack to match ParameterBase::createByTypeName. It doesn't inline using the +// general template. +template <> +inline void ParameterCurve<4>::reset() { + static f32 s_initialize[9] = {0.0, 0.0, 0.5, 0.5, 0.5, 0.5, 1.0, 1.0, 0.5}; + for (u32 i = 0; i < 4; ++i) { + sead::MemUtil::copy(mCurveData[i].f, s_initialize, sizeof(s_initialize)); + for (u32 j = 9; j < cUnitCurveParamNum; ++j) + mCurveData[i].f[j] = 1.0; + mCurves[i].setData(&mCurveData[i], sead::hostio::CurveType::Hermit2D, cUnitCurveParamNum, + 9); + } +} + template inline void ParameterCurve::reset() { static f32 s_initialize[9] = {0.0, 0.0, 0.5, 0.5, 0.5, 0.5, 1.0, 1.0, 0.5}; - for (s32 i = 0; i < N; ++i) { + for (u32 i = 0; i < N; ++i) { sead::MemUtil::copy(mCurveData[i].f, s_initialize, sizeof(s_initialize)); - for (s32 j = 9; j < cUnitCurveParamNum; ++j) + for (u32 j = 9; j < cUnitCurveParamNum; ++j) mCurveData[i].f[j] = 1.0; mCurves[i].setData(&mCurveData[i], sead::hostio::CurveType::Hermit2D, cUnitCurveParamNum, 9); @@ -45,7 +59,7 @@ inline void ParameterCurve::copyUnsafe(const ParameterBase& other) { } sead::MemUtil::copy(ptr(), other.ptr(), size()); - for (s32 i = 0; i < N; ++i) { + for (u32 i = 0; i < N; ++i) { auto& curve = mCurves[i]; auto& curve_other = static_cast&>(other).mCurves[i]; curve.setCurveType(curve_other.getCurveType()); @@ -77,14 +91,14 @@ inline ParameterBase* ParameterCurve::clone(sead::Heap* heap, IParameterObj* template inline void ParameterCurve::postApplyResource_(const void*, size_t size) { if (this->size() == size) { - for (s32 i = 0; i < N; ++i) { + for (u32 i = 0; i < N; ++i) { mCurves[i].setCurveType(sead::hostio::CurveType(mCurveData[i].curveType)); mCurves[i].mFloats = mCurveData[i].f; mCurves[i].mInfo.numFloats = cUnitCurveParamNum; mCurves[i].setNumUse(mCurveData[i].numUse); } } else { - for (s32 i = 0; i < N; ++i) { + for (u32 i = 0; i < N; ++i) { mCurves[i].mInfo.numFloats = cUnitCurveParamNum; mCurves[i].mFloats = mCurveData[i].f; } diff --git a/src/utility/aglParameter.cpp b/src/utility/aglParameter.cpp index 83fa293..c933573 100644 --- a/src/utility/aglParameter.cpp +++ b/src/utility/aglParameter.cpp @@ -5,6 +5,7 @@ #include #include #include +#include #include "utility/aglParameterObj.h" #include "utility/aglParameterStringMgr.h" @@ -414,23 +415,88 @@ bool ParameterBase::makeZero() { return false; } -// TODO: Remove these explicit instantiations once ParameterBase::createByTypeName is implemented. -template class Parameter; -template class Parameter; -template class Parameter; -template class Parameter; -template class Parameter; -template class Parameter; -template class Parameter; -template class Parameter>; -template class Parameter>; -template class Parameter>; -template class Parameter; -template class Parameter; -template class Parameter; -template class ParameterCurve<1>; -template class ParameterCurve<2>; -template class ParameterCurve<3>; -template class ParameterCurve<4>; +ParameterBase* ParameterBase::createByTypeName(const sead::SafeString& name, + const sead::SafeString& bufferSize) { + if (name.isEqual(getParameterTypeName(ParameterType::Bool))) { + return new Parameter; + } + if (name.isEqual(getParameterTypeName(ParameterType::F32))) { + return new Parameter; + } + if (name.isEqual(getParameterTypeName(ParameterType::Int))) { + return new Parameter; + } + if (name.isEqual(getParameterTypeName(ParameterType::U32))) { + return new Parameter; + } + if (name.isEqual(getParameterTypeName(ParameterType::Vec2))) { + return new Parameter; + } + if (name.isEqual(getParameterTypeName(ParameterType::Vec3))) { + return new Parameter; + } + if (name.isEqual(getParameterTypeName(ParameterType::Vec4))) { + return new Parameter; + } + if (name.isEqual(getParameterTypeName(ParameterType::Color))) { + return new Parameter; + } + if (name.isEqual(getParameterTypeName(ParameterType::Quat))) { + return new Parameter; + } + if (name.isEqual(getParameterTypeName(ParameterType::String32))) { + return new Parameter>; + } + if (name.isEqual(getParameterTypeName(ParameterType::String64))) { + return new Parameter>; + } + if (name.isEqual(getParameterTypeName(ParameterType::String256))) { + return new Parameter>; + } + if (name.isEqual(getParameterTypeName(ParameterType::StringRef))) { + return new Parameter; + } + if (name.isEqual(getParameterTypeName(ParameterType::Curve1))) { + return new ParameterCurve<1>; + } + if (name.isEqual(getParameterTypeName(ParameterType::Curve2))) { + return new ParameterCurve<2>; + } + if (name.isEqual(getParameterTypeName(ParameterType::Curve3))) { + return new ParameterCurve<3>; + } + if (name.isEqual(getParameterTypeName(ParameterType::Curve4))) { + return new ParameterCurve<4>; + } + if (name.isEqual(getParameterTypeName(ParameterType::BufferInt))) { + ParameterBuffer* buffer = new ParameterBuffer; + u32 size = + sead::StringUtil::parseS32(bufferSize, sead::StringUtil::CardinalNumber::BaseAuto); + buffer->allocateBuffer(nullptr, size); + return buffer; + } + if (name.isEqual(getParameterTypeName(ParameterType::BufferF32))) { + ParameterBuffer* buffer = new ParameterBuffer; + u32 size = + sead::StringUtil::parseS32(bufferSize, sead::StringUtil::CardinalNumber::BaseAuto); + buffer->allocateBuffer(nullptr, size); + return buffer; + } + if (name.isEqual(getParameterTypeName(ParameterType::BufferU32))) { + ParameterBuffer* buffer = new ParameterBuffer; + u32 size = + sead::StringUtil::parseS32(bufferSize, sead::StringUtil::CardinalNumber::BaseAuto); + buffer->allocateBuffer(nullptr, size); + return buffer; + } + if (name.isEqual(getParameterTypeName(ParameterType::BufferBinary))) { + ParameterBuffer* buffer = new ParameterBuffer; + u32 size = + sead::StringUtil::parseS32(bufferSize, sead::StringUtil::CardinalNumber::BaseAuto); + buffer->allocateBuffer(nullptr, (u32)sead::Mathf::ceil(size * 0.25f) * 4); + return buffer; + } + return nullptr; +} } // namespace agl::utl