summaryrefslogtreecommitdiff
path: root/libs/JSystem/src/J3DGraphLoader/J3DModelLoaderCalcSize.cpp
diff options
context:
space:
mode:
authorLuke Street <luke@street.dev>2026-03-01 15:35:36 -0700
committerGitHub <noreply@github.com>2026-03-01 14:35:36 -0800
commit9649319ec4926457ef85e6094f8207474c977c2d (patch)
tree1c5cd4c7cc4c1aee03f28921213da47f2775444d /libs/JSystem/src/J3DGraphLoader/J3DModelLoaderCalcSize.cpp
parent6e149819e13b1f70ecbf8a4c66b030c17ffed2bb (diff)
Reorganize library code into `libs/` (#3119)
* Reorganize files into libs/{dolphin,JSystem,PowerPC_EABI_Support,revolution,TRK_MINNOW_DOLPHIN} * Update configure.py and project.py for new libs structure * Refactor `#include <dolphin/x.h>` -> `<x.h>` * Remove `__REVOLUTION_SDK__` forwards from dolphin * Fix dolphin/ references in revolution * Wrap `#include <dolphin.h>` in `!__REVOLUTION_SDK__` * Always build TRK against dolphin headers * Resolve revolution SDK header resolution issues
Diffstat (limited to 'libs/JSystem/src/J3DGraphLoader/J3DModelLoaderCalcSize.cpp')
-rw-r--r--libs/JSystem/src/J3DGraphLoader/J3DModelLoaderCalcSize.cpp328
1 files changed, 328 insertions, 0 deletions
diff --git a/libs/JSystem/src/J3DGraphLoader/J3DModelLoaderCalcSize.cpp b/libs/JSystem/src/J3DGraphLoader/J3DModelLoaderCalcSize.cpp
new file mode 100644
index 0000000000..2e6f7e586c
--- /dev/null
+++ b/libs/JSystem/src/J3DGraphLoader/J3DModelLoaderCalcSize.cpp
@@ -0,0 +1,328 @@
+#include "JSystem/JSystem.h" // IWYU pragma: keep
+
+#include "JSystem/J3DGraphLoader/J3DModelLoaderCalcSize.h"
+#include "JSystem/J3DGraphLoader/J3DModelLoader.h"
+#include "JSystem/J3DGraphLoader/J3DShapeFactory.h"
+#include "JSystem/J3DGraphLoader/J3DMaterialFactory.h"
+#include "JSystem/J3DGraphBase/J3DMaterial.h"
+#include "JSystem/J3DGraphAnimator/J3DJoint.h"
+#include "JSystem/J3DGraphAnimator/J3DModelData.h"
+#include "JSystem/JSupport/JSupport.h"
+#include <os.h>
+#include "global.h"
+
+u16 J3DModelLoader::countMaterialNum(const void* stream) {
+ const J3DModelFileData* header = (const J3DModelFileData*)stream;
+ const J3DModelBlock* block = header->mBlocks;
+ for (int i = 0; i < header->mBlockNum; i++)
+ {
+ if (block->mBlockType == 'MAT3') {
+ const J3DMaterialBlock* materialBlock = (const J3DMaterialBlock*)block;
+ return materialBlock->mMaterialNum;
+ }
+ block = (const J3DModelBlock*)((u8*)block + block->mBlockSize);
+ }
+ return 0;
+}
+
+static void dummy() {
+ JUT_PANIC(0, "Error : null pointer.");
+}
+
+u32 J3DModelLoader::calcLoadSize(void const* stream, u32 flags_) {
+ int flags = flags_;
+ size_t size = 0;
+ // TODO: What sizeof will get us a size of 0xE4?
+ size += 0xE4;
+ const J3DModelFileData* header = static_cast<const J3DModelFileData*>(stream);
+ const J3DModelBlock* nextBlock = header->mBlocks;
+ for (u32 i = 0; i < header->mBlockNum; i++) {
+ switch (nextBlock->mBlockType) {
+ case 'INF1':
+ size += calcSizeInformation((const J3DModelInfoBlock*)nextBlock, flags);
+ break;
+ case 'JNT1':
+ size += calcSizeJoint((const J3DJointBlock*)nextBlock);
+ break;
+ case 'MAT3':
+ size += calcSizeMaterial((const J3DMaterialBlock*)nextBlock, flags);
+ break;
+ case 'SHP1':
+ size += calcSizeShape((const J3DShapeBlock*)nextBlock, flags);
+ break;
+ case 'TEX1':
+ size += calcSizeTexture((const J3DTextureBlock*)nextBlock);
+ break;
+ case 'EVP1':
+ size += calcSizeEnvelope((const J3DEnvelopeBlock*)nextBlock);
+ break;
+ case 'DRW1':
+ size += calcSizeDraw((const J3DDrawBlock*)nextBlock);
+ break;
+ case 'VTX1':
+ break;
+ case 'MAT2':
+ JUT_PANIC(282, "Error : version error.");
+ break;
+ default:
+ OSReport("Unknown data block\n");
+ break;
+ }
+ nextBlock = (const J3DModelBlock*)((u8*)nextBlock + nextBlock->mBlockSize);
+ }
+ return size;
+}
+
+u32 J3DModelLoader::calcLoadMaterialTableSize(const void* stream) {
+ u32 flags = J3DMLF_21 | J3DMLF_Material_UseIndirect | J3DMLF_Material_PE_Full | J3DMLF_Material_Color_LightOn;
+ size_t size = 0;
+ // TODO: What sizeof will get us a size of 0x20? Is this just the file header???
+ size += 0x20;
+ const J3DModelBlock* nextBlock;
+ bool hasTextureTable;
+ const J3DModelFileData* header = reinterpret_cast<const J3DModelFileData*>(stream);
+ nextBlock = header->mBlocks;
+ hasTextureTable = false;
+ for (u32 i = 0; i < header->mBlockNum; i++) {
+ switch (nextBlock->mBlockType) {
+ case 'MAT3':
+ size += calcSizeMaterialTable((const J3DMaterialBlock*)nextBlock, flags);
+ break;
+ case 'TEX1':
+ size += calcSizeTextureTable((const J3DTextureBlock*)nextBlock);
+ hasTextureTable = true;
+ break;
+ case 'MAT2':
+ JUT_PANIC(334, "Error : version error.");
+ break;
+ default:
+ OSReport("Unknown data block\n");
+ break;
+ }
+ nextBlock = (const J3DModelBlock*)((u8*)nextBlock + nextBlock->mBlockSize);
+ }
+
+ if (!hasTextureTable) {
+ size += 12;
+ }
+ return size;
+}
+
+inline u32 getBdlFlag_MaterialType(u32 flags) {
+ return flags & (J3DMLF_13 | J3DMLF_DoBdlMaterialCalc);
+}
+
+// NONMATCHING flags issue
+u32 J3DModelLoader::calcLoadBinaryDisplayListSize(const void* stream, u32 flags) {
+ u32 size = 0;
+ size += sizeof(J3DModelData);
+ const J3DModelFileData* header = (const J3DModelFileData*)stream;
+ const J3DModelBlock* nextBlock = header->mBlocks;
+ for (u32 i = 0; i < header->mBlockNum; i++) {
+ switch (nextBlock->mBlockType) {
+ case 'INF1':
+ size += calcSizeInformation((const J3DModelInfoBlock*)nextBlock, (u32)flags);
+ break;
+ case 'JNT1':
+ size += calcSizeJoint((const J3DJointBlock*)nextBlock);
+ break;
+ case 'SHP1':
+ size += calcSizeShape((const J3DShapeBlock*)nextBlock, (u32)flags);
+ break;
+ case 'TEX1':
+ size += calcSizeTexture((const J3DTextureBlock*)nextBlock);
+ break;
+ case 'MDL3':
+ size += calcSizeMaterialDL((const J3DMaterialDLBlock*)nextBlock, flags);
+ break;
+ case 'MAT3': {
+ u32 flags2 = (J3DMLF_21 | J3DMLF_Material_PE_Full | J3DMLF_Material_Color_LightOn);
+ flags2 |= (u32)flags & (J3DMLF_Material_UseIndirect | J3DMLF_26);
+ mpMaterialBlock = (const J3DMaterialBlock*)nextBlock;
+ u32 flag_mtl_type = getBdlFlag_MaterialType(flags);
+ if (flag_mtl_type == 0) {
+ field_0x18 = 1;
+ size += calcSizeMaterial((const J3DMaterialBlock*)nextBlock, flags2);
+ } else if (flag_mtl_type == J3DMLF_DoBdlMaterialCalc) {
+ field_0x18 = 1;
+ size += calcSizePatchedMaterial((const J3DMaterialBlock*)nextBlock, flags2);
+ }
+ break;
+ }
+ case 'EVP1':
+ size += calcSizeEnvelope((const J3DEnvelopeBlock*)nextBlock);
+ break;
+ case 'DRW1':
+ size += calcSizeDraw((const J3DDrawBlock*)nextBlock);
+ break;
+ case 'VTX1':
+ break;
+ case 'MAT2':
+ JUT_PANIC(436, "Error : version error.");
+ break;
+ default:
+ OSReport("Unknown data block\n");
+ break;
+ }
+ nextBlock = (const J3DModelBlock*)((u8*)nextBlock + nextBlock->mBlockSize);
+ }
+ return size;
+}
+
+u32 J3DModelLoader::calcSizeInformation(const J3DModelInfoBlock* block, u32 flags) {
+ J3D_ASSERT_NULLPTR(462, block);
+ int size = 0;
+ u32 flags2 = flags | block->mFlags;
+ int r27 = 0;
+ switch (flags2 & J3DMLF_MtxTypeMask) {
+ case J3DMLF_None: // Basic
+ size += 4;
+ break;
+ case J3DMLF_MtxSoftImageCalc:
+ size += 4;
+ break;
+ case J3DMLF_MtxMayaCalc:
+ size += 4;
+ break;
+ default:
+ JUT_PANIC(481, "Error : Invalid MtxCalcType.");
+ break;
+ }
+ mpModelHierarchy = JSUConvertOffsetToPtr<J3DModelHierarchy>(block, block->mpHierarchy);
+ return size;
+}
+
+u32 J3DModelLoader::calcSizeJoint(const J3DJointBlock* block) {
+ J3D_ASSERT_NULLPTR(499, block);
+ int size = 0;
+ if (block->mpNameTable) {
+ size += 0x10;
+ }
+ size += (block->mJointNum * sizeof(J3DJoint*));
+ size += (block->mJointNum * sizeof(J3DJoint));
+ return size;
+}
+
+u32 J3DModelLoader::calcSizeEnvelope(const J3DEnvelopeBlock* block) {
+ J3D_ASSERT_NULLPTR(522, block);
+ mEnvelopeSize = block->mWEvlpMtxNum;
+ return 0;
+}
+
+u32 J3DModelLoader::calcSizeDraw(const J3DDrawBlock* block) {
+ J3D_ASSERT_NULLPTR(538, block);
+ u32 size = 0;
+ size += (block->mMtxNum - mEnvelopeSize) * 2;
+ return size;
+}
+
+u32 J3DModelLoader_v26::calcSizeMaterial(const J3DMaterialBlock* block, u32 flags) {
+ J3D_ASSERT_NULLPTR(558, block);
+ size_t size = 0;
+ J3DMaterialFactory factory(*block);
+ u32 count = block->mMaterialNum;
+ int uniqueCount = factory.countUniqueMaterials();
+ if (block->mpNameTable != NULL) {
+ size += 0x10;
+ }
+ size += (count * sizeof(J3DMaterial*));
+
+ if ((flags & J3DMLF_UseUniqueMaterials) != 0) {
+ // calc for allocated materials as well
+ size += ALIGN_NEXT((u16)uniqueCount * sizeof(J3DMaterial), 0x20);
+ }
+ if ((flags & J3DMLF_UseUniqueMaterials) != 0) {
+ for (u32 i = 0; i < uniqueCount; i++) {
+ size += factory.calcSize(NULL, J3DMaterialFactory::MATERIAL_TYPE_NORMAL, i, flags);
+ }
+ }
+ for (u32 i = 0; i < count; i++) {
+ size += factory.calcSize(NULL, J3DMaterialFactory::MATERIAL_TYPE_NORMAL, i, flags);
+ }
+ return size;
+}
+
+u32 J3DModelLoader::calcSizeShape(const J3DShapeBlock* block, u32 flags) {
+ J3D_ASSERT_NULLPTR(616, block);
+ int size = 0;
+ J3DShapeFactory factory(*block);
+ int count = block->mShapeNum;
+ if (block->mpNameTable) {
+ size += 0x10;
+ }
+ size += count * sizeof(J3DShape*);
+ size += factory.calcSizeVcdVatCmdBuffer(count);
+ J3DModelHierarchy* hierarchy;
+ for (hierarchy = mpModelHierarchy; hierarchy->mType != 0; hierarchy++) {
+ if (hierarchy->mType == 0x12) {
+ size += factory.calcSize(hierarchy->mValue, flags);
+ }
+ }
+ return size;
+}
+
+u32 J3DModelLoader::calcSizeTexture(const J3DTextureBlock* block) {
+ J3D_ASSERT_NULLPTR(663, block);
+ // TODO: use sizeofs here.
+ int size = 0;
+ if (block->mpNameTable) {
+ size += 0x10;
+ }
+ size += 0xC;
+ return size;
+}
+
+u32 J3DModelLoader_v26::calcSizeMaterialTable(const J3DMaterialBlock* block, u32 flags) {
+ int size = 0;
+ u32 count = block->mMaterialNum;
+ J3DMaterialFactory factory(*block);
+ if (block->mpNameTable) {
+ size += 0x10;
+ }
+ size += (count * sizeof(J3DMaterial*));
+ for (u16 i = 0; i < count; i++) {
+ size += factory.calcSize(NULL, J3DMaterialFactory::MATERIAL_TYPE_NORMAL, i, flags);
+ }
+ return size;
+}
+
+u32 J3DModelLoader::calcSizeTextureTable(const J3DTextureBlock* block) {
+ return calcSizeTexture(block);
+}
+
+u32 J3DModelLoader::calcSizePatchedMaterial(const J3DMaterialBlock* block, u32 flags) {
+ int size = 0;
+ u32 count = block->mMaterialNum;
+ J3DMaterialFactory factory(*block);
+ if (block->mpNameTable) {
+ size += 0x10;
+ }
+ size += (count * sizeof(J3DMaterial*));
+ for (u16 i = 0; i < count; i++) {
+ size += factory.calcSize(NULL, J3DMaterialFactory::MATERIAL_TYPE_PATCHED, i, flags);
+ }
+ return size;
+}
+
+u32 J3DModelLoader::calcSizeMaterialDL(const J3DMaterialDLBlock* block, u32 flags_) {
+ J3D_ASSERT_NULLPTR(758, block);
+ int flags = flags_;
+ size_t size = 0;
+ J3DMaterialFactory factory(*block);
+ if (!field_0x18) {
+ u32 count = block->mMaterialNum;
+ if (block->mpNameTable) {
+ size += 0x10;
+ }
+ size += count * sizeof(J3DLockedMaterial*);
+ for (u16 i = 0; i < count; i++) {
+ size += factory.calcSize(NULL, J3DMaterialFactory::MATERIAL_TYPE_LOCKED, i, flags);
+ }
+ } else {
+ u32 count = block->mMaterialNum;
+ for (u16 i = 0; i < count; i++) {
+ size += factory.calcSize((J3DMaterial*)this, J3DMaterialFactory::MATERIAL_TYPE_LOCKED, i, flags);
+ }
+ }
+ return size;
+}