summaryrefslogtreecommitdiff
path: root/src/JSystem/J3DGraphLoader/J3DClusterLoader.cpp
blob: 03a0e66213222254f8df48f43594602068829211 (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
//
// J3DClusterLoader
//

#include "JSystem/JSystem.h" // IWYU pragma: keep

#include "JSystem/J3DGraphLoader/J3DClusterLoader.h"
#include "JSystem/J3DGraphAnimator/J3DSkinDeform.h"
#include "JSystem/JSupport/JSupport.h"
#include "JSystem/JKernel/JKRHeap.h"
#include "dolphin/os.h"
#include <string>

void* J3DClusterLoaderDataBase::load(const void* i_data) {
    J3D_ASSERT_NULLPTR(41, i_data);
    const JUTDataFileHeader* fileHeader = (JUTDataFileHeader*)i_data;
    if (fileHeader->mMagic == 'J3D1' && fileHeader->mType == 'bls1') {
        J3DClusterLoader_v15 loader;
        return loader.load(i_data);
    } else if (fileHeader->mMagic == 'J3D2' && fileHeader->mType == 'bls2') {
        return NULL;
    }
    return NULL;
}

J3DClusterLoader_v15::J3DClusterLoader_v15() {}

J3DClusterLoader_v15::~J3DClusterLoader_v15() {}

void* J3DClusterLoader_v15::load(const void* i_data) {
    J3D_ASSERT_NULLPTR(98, i_data);
    mpDeformData = new J3DDeformData();

    const JUTDataFileHeader* fileHeader = (JUTDataFileHeader*)i_data;
    const JUTDataBlockHeader* block = &fileHeader->mFirstBlock;
    for (int i = 0; i < fileHeader->mBlockNum; i++) {
        switch (block->mType) {
        case 'CLS1':
            readCluster((J3DClusterBlock*)block);
            break;
        default:
            OSReport("Unknown data block\n");
            break;
        }
        block = (JUTDataBlockHeader*)((u8*)block + block->mSize);
    }

    return mpDeformData;
}

void J3DClusterLoader_v15::readCluster(const J3DClusterBlock* block) {
    J3D_ASSERT_NULLPTR(147, block);
    mpDeformData->mClusterNum = block->mClusterNum;
    mpDeformData->mClusterKeyNum = block->mClusterKeyNum;
    mpDeformData->mVtxPosNum = block->mVtxPosNum;
    mpDeformData->mVtxNrmNum = block->mVtxNrmNum;
    mpDeformData->mClusterVertexNum = block->mClusterVertexNum;

    if (block->mClusterName != NULL) {
        mpDeformData->mClusterName =
            new JUTNameTab(JSUConvertOffsetToPtr<ResNTAB>(block, block->mClusterName));
    } else {
        mpDeformData->mClusterName = NULL;
    }
    if (block->mClusterKeyName != NULL) {
        mpDeformData->mClusterKeyName =
            new JUTNameTab(JSUConvertOffsetToPtr<ResNTAB>(block, block->mClusterKeyName));
    } else {
        mpDeformData->mClusterKeyName = NULL;
    }

    mpDeformData->mVtxPos = JSUConvertOffsetToPtr<f32>(block, block->mVtxPos);
    mpDeformData->mVtxNrm = JSUConvertOffsetToPtr<f32>(block, block->mVtxNrm);

    void* clusterPointer = block->mClusterPointer;
    int clusterKeyPointerSize = (intptr_t)block->mClusterKeyPointer - (intptr_t)block->mClusterPointer;
    int clusterVertexPointerSize = (intptr_t)block->mClusterVertex - (intptr_t)block->mClusterPointer;
    int vtxPosSize = (intptr_t)block->mVtxPos - (intptr_t)block->mClusterPointer;
    u8* arr = new (0x20) u8[vtxPosSize];
    memcpy(arr, JSUConvertOffsetToPtr<J3DCluster>(block, block->mClusterPointer), vtxPosSize);
    mpDeformData->mClusterPointer = (J3DCluster*)arr;
    mpDeformData->mClusterKeyPointer = (J3DClusterKey*)&arr[clusterKeyPointerSize];
    mpDeformData->mClusterVertex = (J3DClusterVertex*)&arr[clusterVertexPointerSize];

    for (int i = 0; i < mpDeformData->getClusterNum(); i++) {
        J3DCluster* cluster = &mpDeformData->mClusterPointer[i];
        cluster->mClusterKey = JSUConvertOffsetToPtr<J3DClusterKey>(arr - (intptr_t)clusterPointer, cluster->mClusterKey);
        cluster->field_0x18 = JSUConvertOffsetToPtr<u16>(block, cluster->field_0x18);
        cluster->mClusterVertex =
            JSUConvertOffsetToPtr<J3DClusterVertex>(arr - (intptr_t)clusterPointer, cluster->mClusterVertex);
        J3DDeformer* deformer = new J3DDeformer(mpDeformData);
        if (cluster->field_0x14 != 0) {
            deformer->field_0xc = new f32[cluster->field_0x14 * 3];
        } else {
            deformer->field_0xc = NULL;
        }
        deformer->mFlags = cluster->mFlags;
        deformer->field_0x8 = new f32[cluster->mKeyNum];
        cluster->setDeformer(deformer);
    }

    for (int i = 0; i < mpDeformData->getClusterKeyNum(); i++) {
        J3DClusterKey* clusterKey = &mpDeformData->mClusterKeyPointer[i];
        clusterKey->field_0x4 = JSUConvertOffsetToPtr<u16>(block, clusterKey->field_0x4);
        clusterKey->field_0x8 = JSUConvertOffsetToPtr<u16>(block, clusterKey->field_0x8);
    }

    for (int i = 0; i < mpDeformData->mClusterVertexNum; i++) {
        J3DClusterVertex* clusterVertex = &mpDeformData->mClusterVertex[i];
        clusterVertex->field_0x4 = JSUConvertOffsetToPtr<u16>(block, clusterVertex->field_0x4);
        clusterVertex->field_0x8 = JSUConvertOffsetToPtr<u16>(block, clusterVertex->field_0x8);
    }

    DCStoreRange(arr, vtxPosSize);
}