summaryrefslogtreecommitdiff
path: root/src/KingSystem/Physics/System/physMaterialTable.cpp
blob: 50bfe70fde1ba2920cee79e4144fe595358aba63 (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
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
#include "KingSystem/Physics/System/physMaterialTable.h"
#include <heap/seadFrameHeap.h>

namespace ksys::phys {

MaterialTable::MaterialTable() = default;

MaterialTable::~MaterialTable() = default;

void MaterialTable::loadMaterialTable(sead::Heap* heap, agl::utl::ResParameterArchive archive) {
    addMaterialTableList("MaterialTable");

    for (int i = 0; i < Material::size(); ++i) {
        const char* material_name = materialToText(i);
        auto& obj = mMaterialTable[i];
        mMaterialTablePList.addObj(&obj, material_name);

        for (int j = 0; j < Material::size(); ++j) {
            const char* target_name = materialToText(j);
            obj.values[j].init(sead::Vector2f::zero, target_name, target_name, &obj);
        }
    }

    mMaterialTablePIO.applyResParameterArchive(archive);
}

void MaterialTable::loadSubMaterialTable(sead::Heap* heap, agl::utl::ResParameterArchive archive) {
    addSubMaterialTableList("SubMaterialTable");

    const auto SubMaterialTable = archive.getRootList().getResParameterList(0);

    auto* str_heap = sead::FrameHeap::create(
        0, "SubMaterialString", heap, 8, sead::Heap::HeapDirection::cHeapDirection_Forward, false);

    for (int i = 0; i < Material::size() && i < SubMaterialTable.getResParameterObjNum(); ++i) {
        const char* material_name = materialToText(i);
        auto& obj = mSubMaterialTable[i];
        mSubMaterialTablePList.addObj(&obj, material_name);
        obj.num_values = SubMaterialTable.getResParameterObj(i).getNum();

        for (int submat = 0; submat < obj.values.size(); ++submat) {
            auto* key = new (str_heap) sead::FormatFixedSafeString<32>("submat_%d", submat);
            obj.values[submat].init(sead::SafeString::cEmptyString, *key, *key, &obj);
        }
    }

    if (archive.getRootList().getResParameterListNum() >= 2) {
        mSubMaterialTablePIO.addList(&mSoundSubMaterialTablePList, "SoundSubMaterialTable");
        for (int i = 0; i < Material::size() && i < SubMaterialTable.getResParameterObjNum(); ++i) {
            const char* material_name = materialToText(i);
            auto& obj = mSoundSubMaterialTable[i];
            mSoundSubMaterialTablePList.addObj(&obj, material_name);
            obj.num_values = SubMaterialTable.getResParameterObj(i).getNum();

            for (int submat = 0; submat < obj.values.size(); ++submat) {
                auto* key = new (str_heap) sead::FormatFixedSafeString<32>("submat_%d", submat);
                obj.values[submat].init(sead::SafeString::cEmptyString, *key, *key, &obj);
            }
        }
    }

    if (archive.getRootList().getResParameterListNum() >= 3) {
        mSubMaterialTablePIO.addList(&mSoundMatchingSubMaterialTablePList,
                                     "SoundMatchingSubMaterialTable");
        const auto list = archive.getRootList().getResParameterList(2);
        for (int i = 0; i < Material::size() && i < list.getResParameterObjNum(); ++i) {
            const char* material_name = materialToText(i);
            auto& obj = mSoundMatchingSubMaterialTable[i];
            mSoundMatchingSubMaterialTablePList.addObj(&obj, material_name);
            obj.num_values = list.getResParameterObj(i).getNum();

            for (int submat = 0; submat < obj.values.size(); ++submat) {
                auto* key = new (str_heap) sead::FormatFixedSafeString<32>("submat_%d", submat);
                obj.values[submat].init(sead::SafeString::cEmptyString, *key, *key, &obj);
            }
        }
    }

    str_heap->adjust();
    mSubMaterialTablePIO.applyResParameterArchive(archive);
}

const sead::SafeString& MaterialTable::getSubMaterial(Material material, int submat_idx) const {
    return mSubMaterialTable[material].values[submat_idx].ref();
}

const sead::SafeString& MaterialTable::getSoundMatchingSubMaterial(Material material,
                                                                   int submat_idx) const {
    return mSoundMatchingSubMaterialTable[material].values[submat_idx].ref();
}

static int getSubMaterialIdx_(const MaterialTable::SubValues& table, Material material,
                              const sead::SafeString& submat_name) {
    for (int i = 0; i < table.num_values; ++i) {
        if (submat_name == table.values[i].ref())
            return i;
    }

    if (submat_name == sead::SafeString::cEmptyString)
        return 0;

    return -1;
}

int MaterialTable::getSubMaterialIdx(Material material, const sead::SafeString& submat_name) const {
    const auto& table = mSubMaterialTable[material];
    return getSubMaterialIdx_(table, material, submat_name);
}

int MaterialTable::getSoundSubMaterialIdx(Material material,
                                          const sead::SafeString& submat_name) const {
    const auto& table = mSoundSubMaterialTable[material];
    return getSubMaterialIdx_(table, material, submat_name);
}

int MaterialTable::getNumSubMaterials(Material material) const {
    return mSubMaterialTable[material].num_values;
}

bool MaterialTable::subMaterialHasSound(Material material, int submat_idx) const {
    return getSoundSubMaterialIdx(material, getSubMaterial(material, submat_idx)) != -1;
}

}  // namespace ksys::phys