summaryrefslogtreecommitdiff
path: root/src/KingSystem/Utils/ParamIO.cpp
blob: 2a95c1185f771bc0a5869863b42628579ef7b8ba (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
#include "KingSystem/Utils/ParamIO.h"
#include <cstring>
#include <utility/aglParameter.h>
#include "KingSystem/ActorSystem/actActorParamMgr.h"

namespace ksys {

void ParamIO::applyParameter(char* data, char* data1, agl::utl::ParameterBase* param,
                             const sead::SafeString& parent_name, bool* applied) {
    sead::FixedSafeString<128> name;
    name.format("%s/%s", parent_name.cstr(), param->getName().cstr());
    if (name != data)
        return;

    if (param->getParameterType() == agl::utl::ParameterBase::ParameterType::StringRef) {
        auto* heap = act::ActorParamMgr::instance()->getDebugHeap();
        const auto len = sead::SafeString(data1).calcLength();
        auto* copy = new (heap) char[len + 1];
        std::memcpy(copy, data1, len);
        data1 = copy;
        data1[len] = '\0';
    }

    param->applyString(data1, false);
    *applied = true;
}

void ParamIO::applyParameterObj(char* data, char* data1, agl::utl::IParameterObj* obj,
                                const sead::SafeString& parent_name, bool* applied) {
    sead::FixedSafeString<128> name;
    name.format("%s/%s", parent_name.cstr(), obj->getName().cstr());

    if (obj->getNext())
        applyParameterObj(data, data1, obj->getNext(), parent_name, applied);

    for (auto param = obj->getParamListHead(); param; param = param->getNext()) {
        applyParameter(data, data1, param, name, applied);
        if (param == obj->getParamListTail())
            break;
    }
}

void ParamIO::applyParameterList(char* data, char* data1, agl::utl::IParameterList* list,
                                 const sead::SafeString& parent_name, bool* applied) {
    sead::FixedSafeString<128> name;
    name.format("%s/%s", parent_name.cstr(), list->getName().cstr());

    if (auto* obj = list->getChildObjHead())
        applyParameterObj(data, data1, obj, name, applied);

    if (auto* next = list->getNext())
        applyParameterList(data, data1, next, parent_name, applied);

    if (auto* child = list->getChildListHead())
        applyParameterList(data, data1, child, name, applied);
}

bool ParamIO::applyResourceUpdate(char* data, char* data1) {
    bool applied = false;
    applyParameterList(data, data1, this, "", &applied);
    return applied;
}

const char* ParamIO::getString(const agl::utl::ResParameterObj& obj, const char* key,
                               const char* default_value, void*) const {
    const auto param = agl::utl::getResParameter(obj, key);
    if (!param.ptr())
        return default_value;
    return param.getData<const char>();
}

// NON_MATCHING: how the default_value Vec3f is stored on the stack
sead::Vector3f ParamIO::getVec3(const agl::utl::ResParameterObj& obj, const char* key,
                                sead::Vector3f default_value, void*) const {
    const auto param = agl::utl::getResParameter(obj, key);
    return param.ptr() ? *param.getData<sead::Vector3f>() : default_value;
}

}  // namespace ksys