Paper Mario DX
Paper Mario (N64) modding
 
Loading...
Searching...
No Matches
model.c
Go to the documentation of this file.
1#include "common.h"
2#include "ld_addrs.h"
3#include "model.h"
4#include "effects.h"
5#include "hud_element.h"
7#include "nu/nusys.h"
8#include "qsort.h"
9#include <string.h>
10
11// models are rendered in two stages by the RDP:
12// (1) main and aux textures are combined in the color combiner
13// (2) the combined texture is blended with either tint or fog by the blender
14
15// supported values for auxCombineType
16enum {
28};
29
30// supported values for auxCombineSubType
31// different subtypes are only supported for textures with EXTRA_TILE_NONE
32enum {
33 AUX_COMBINE_SUB_0 = 0, // multiply TEX * SHADE for color, use TEX for alpha
34 AUX_COMBINE_SUB_1 = 1, // lerp from TEX to SHADE based on TEX alpha
35 AUX_COMBINE_SUB_2 = 2, // TEX only, shade is ignored
37};
38
39// different methods for combining main/aux texture maps
40// derives from auxCombineType and auxCombineSubType
41enum {
42 // no texture
44
45 // extra tile mode = EXTRA_TILE_NONE
49
50 // extra tile mode = EXTRA_TILE_MIPMAPS
54
55 // extra tile mode = EXTRA_TILE_AUX_SAME_AS_MAIN
59
60 // extra tile mode = EXTRA_TILE_AUX_INDEPENDENT
61 // NOTE: unused; copy of TEX_COMBINE_AUX_SHARED; may not work properly
65
66 // special types selected by auxCombineType (these ignore auxCombineSubType)
75};
76
77enum {
83};
84
85enum {
86 RENDER_CLASS_1CYC = 1, // render modes are single-cycle
87 RENDER_CLASS_2CYC = 2, // render modes are two-cycle, starting with G_RM_PASS
88 RENDER_CLASS_FOG = 3, // render modes are two-cycle, starting with G_RM_FOG_SHADE_A
89 RENDER_CLASS_1CYC_SHROUD = 4, // render modes use Gfx_RM2_SURFACE_OPA, but overwrite
90 RENDER_CLASS_2CYC_SHROUD = 5, // render modes use Gfx_RM2_SURFACE_OPA, but overwrite
94};
95
96enum {
97 RENDER_TASK_LIST_NEAR, // dist < 800K
99 RENDER_TASK_LIST_FAR, // dist >= 3M
100};
101
102#define WORLD_TEXTURE_MEMORY_SIZE 0x20000
103#define BATTLE_TEXTURE_MEMORY_SIZE 0x8000
104
105u8* gBackgroundTintModePtr; // NOTE: the type for this u8 is TintMode, as shown in SetModelTintMode
108
109extern Addr TextureHeap;
110
111typedef struct FogSettings {
112 /* 0x00 */ s32 enabled;
113 /* 0x04 */ Color4i color;
114 /* 0x14 */ s32 startDistance;
115 /* 0x18 */ s32 endDistance;
116} FogSettings; // size = 0x1C
117
118extern Gfx Gfx_RM1_SURFACE_OPA[];
119extern Gfx Gfx_RM1_DECAL_OPA[];
121extern Gfx Gfx_RM1_ALPHATEST[];
122extern Gfx Gfx_RM1_SURFACE_XLU[];
123extern Gfx Gfx_RM1_DECAL_XLU[];
138extern Gfx Gfx_RM1_CLOUD[];
139extern Gfx Gfx_RM1_CLOUD_NO_ZB[];
140extern Gfx Gfx_RM2_SURFACE_OPA[];
141extern Gfx Gfx_RM2_DECAL_OPA[];
143extern Gfx Gfx_RM2_ALPHATEST[];
144extern Gfx Gfx_RM2_SURFACE_XLU[];
145extern Gfx Gfx_RM2_DECAL_XLU[];
158extern Gfx Gfx_RM2_CLOUD[];
159extern Gfx Gfx_RM2_CLOUD_NO_ZB[];
160extern Gfx Gfx_RM3_SURFACE_OPA[];
161extern Gfx Gfx_RM3_DECAL_OPA[];
163extern Gfx Gfx_RM3_ALPHATEST[];
164extern Gfx Gfx_RM3_SURFACE_XLU[];
165extern Gfx Gfx_RM3_DECAL_XLU[];
178extern Gfx Gfx_RM3_CLOUD[];
179extern Gfx Gfx_RM3_CLOUD_NO_ZB[];
180
243};
244
252 },
253
260 },
267 },
274 },
275
276 // blend LODs in first cycle, tint in second cycle
277 // all three sub-types are identical
284 },
291 },
298 },
299
300 // blend main/aux textures in first cycle, tint in second cycle
301 // all three sub-types are identical
308 },
315 },
322 },
323
324 // blend main/aux textures in first cycle, tint in second cycle
325 // all three sub-types are identical
332 },
339 },
346 },
347
348 // shaded color multiplied main/aux textures for alpha
349 [TEX_COMBINE_3] {
355 },
356 // lerp between main/aux textures with shade alpha
357 [TEX_COMBINE_4] {
363 },
364 [TEX_COMBINE_5] {
370 },
371 [TEX_COMBINE_6] {
377 },
378 [TEX_COMBINE_7] {
384 },
385 [TEX_COMBINE_8] {
391 },
392 [TEX_COMBINE_9] {
398 },
399 [TEX_COMBINE_A] {
405 },
406};
407
415 },
416
423 },
430 },
437 },
438
439 // blend LODs in first cycle, tint in second cycle
446 },
453 },
460 },
461
462 // blend main/aux textures in first cycle, tint in second cycle
469 },
476 },
483 },
484
485 // blend main/aux textures in first cycle, tint in second cycle
492 },
499 },
506 },
507
508 [TEX_COMBINE_3] {
514 },
515 [TEX_COMBINE_4] {
521 },
522 [TEX_COMBINE_5] {
528 },
529 [TEX_COMBINE_6] {
535 },
536 [TEX_COMBINE_7] {
542 },
543 [TEX_COMBINE_8] {
549 },
550 [TEX_COMBINE_9] {
556 },
557 [TEX_COMBINE_A] {
563 },
564};
565
567
572
580u8 DepthTintColA = 0; // unused?
583
590
592 1.000000, 0.000000, 0.000000, 0.000000,
593 0.000000, 1.000000, 0.000000, 0.000000,
594 0.000000, 0.000000, 1.000000, 0.000000,
595 0.000000, 0.000000, 0.000000, 1.000000
596);
597
598// The depth buffer contains values encoded in a custom 18-bit floating-point format.
599// There are 3 bits of exponent, 11 bits of mantissa, and 4 bits of "dz".
600// However, two of the "dz" bits are inaccessible to the CPU because it can only access 8 of the 9
601// bits of each RDRAM byte (the N64 has 9-bit RAM).
602// Therefore, the CPU sees it as a 16-bit value.
603
604// Fields in floating point depth buffer format
605#define DEPTH_EXPONENT_MASK 0xE000
606#define DEPTH_MANTISSA_MASK 0x1FFC
607#define DEPTH_DZ_MASK 0x0003
608
609#define DEPTH_EXPONENT_SHIFT 13
610#define DEPTH_MANTISSA_SHIFT 2
611#define DEPTH_DZ_SHIFT 0
612
613// Lookup table for converting depth buffer values to a 15.3 fixed-point format.
614typedef struct DepthFloatFactors {
615 /* 0x00 */ s32 shift;
616 /* 0x04 */ s32 bias;
618
620 { 6, 0x00000 },
621 { 5, 0x20000 },
622 { 4, 0x30000 },
623 { 3, 0x38000 },
624 { 2, 0x3C000 },
625 { 1, 0x3E000 },
626 { 0, 0x3F000 },
627 { 0, 0x3F800 },
628 { 0, 0x00000 },
629};
630
631// Maximum depth value after the viewport transform.
632// The multiplication by 2 comes from transforming depth from (-0.5, 0.5) to (0.0, 1.0).
633// The multiplication by 32 comes from scaling the RSP does to increase depth precision.
634#define MAX_VIEWPORT_DEPTH (2 * 32 * ((G_MAXZ / 2)))
635
637
638// ----------------------------------------------------------------------------
639// RENDER_CLASS_1CYC, basic AA variants
640
641// RENDER_MODE_IDX_00: RENDER_MODE_SURFACE_OPA, RENDER_CLASS_1CYC
642// used by entity models
651
652// RENDER_MODE_IDX_02: RENDER_MODE_DECAL_OPA, RENDER_CLASS_1CYC
653// used by entity models
662
663// RENDER_MODE_IDX_04: RENDER_MODE_INTERSECTING_OPA, RENDER_CLASS_1CYC
664// used by entity models
673
674// RENDER_MODE_IDX_06: RENDER_MODE_ALPHATEST, RENDER_CLASS_1CYC
675// used by entity models and item entities
683
684// RENDER_MODE_IDX_08: RENDER_MODE_SURFACE_XLU, RENDER_CLASS_1CYC
685// used by entity models
693
694// RENDER_MODE_IDX_0C: RENDER_MODE_DECAL_XLU, RENDER_CLASS_1CYC
695// used by entity models
703
704// RENDER_MODE_IDX_0E: RENDER_MODE_INTERSECTING_XLU, RENDER_CLASS_1CYC
705// used by entity models
713
714// ----------------------------------------------------------------------------
715// RENDER_CLASS_1CYC, basic NO_AA variants
716
717// RENDER_MODE_IDX_01: RENDER_MODE_SURFACE_OPA_NO_AA, RENDER_CLASS_1CYC
725
726// RENDER_MODE_IDX_03: RENDER_MODE_DECAL_OPA_NO_AA, RENDER_CLASS_1CYC
734
735// RENDER_MODE_IDX_05: unused
743
744// RENDER_MODE_IDX_07: RENDER_MODE_ALPHATEST_ONESIDED, RENDER_CLASS_1CYC
745// used by entity models
753
754// RENDER_MODE_IDX_0A: RENDER_MODE_SURFACE_XLU_NO_AA, RENDER_CLASS_1CYC
755// used by entity models
763
764// RENDER_MODE_IDX_0D: RENDER_MODE_DECAL_XLU_NO_AA, RENDER_CLASS_1CYC
765// used by entity models
773
774// ----------------------------------------------------------------------------
775// RENDER_CLASS_1CYC, special modes
776
777// RENDER_MODE_IDX_0F: unused
778// used by entity models for RENDER_MODE_PASS_THROUGH
785
786// RENDER_MODE_IDX_09: RENDER_MODE_SURFACE_XLU_AA_ZB_ZUPD, RENDER_CLASS_1CYC
797
798// RENDER_MODE_IDX_2E: RENDER_MODE_SURFACE_OPA_NO_ZB, RENDER_CLASS_1CYC
799// used by entity models
807
808// RENDER_MODE_IDX_2F: RENDER_MODE_ALPHATEST_NO_ZB, RENDER_CLASS_1CYC
809// used by entity models
817
818// RENDER_MODE_IDX_30: RENDER_MODE_SURFACE_XLU_NO_ZB, RENDER_CLASS_1CYC
819// used by entity models
827
828// RENDER_MODE_IDX_0B: RENDER_MODE_SURFACE_XLU_ZB_ZUPD, RENDER_CLASS_1CYC
829// custom render mode similar to RM_AA_XLU_SURF, using ZMODE_XLU instead of ZMODE_OPA and setting Z_CMP | Z_UPD
840
841// no corresponding RENDER_MODE_IDX
842// used by entity models for RENDER_MODE_CLOUD_NO_ZCMP
843// custom render mode is identical to RM_ZB_CLD_SURF, except leaving out Z_CMP
854
855// RENDER_MODE_IDX_37: RENDER_MODE_CLOUD, RENDER_CLASS_1CYC
863
864// RENDER_MODE_IDX_38: RENDER_MODE_CLOUD_NO_ZB, RENDER_CLASS_1CYC
872
873// ----------------------------------------------------------------------------
874// RENDER_CLASS_2CYC, basic AA variants
875
876// RENDER_MODE_IDX_10: RENDER_MODE_SURFACE_OPA, RENDER_CLASS_2CYC
884
885// RENDER_MODE_IDX_12: RENDER_MODE_DECAL_OPA, RENDER_CLASS_2CYC
893
894// RENDER_MODE_IDX_14: RENDER_MODE_INTERSECTING_OPA, RENDER_CLASS_2CYC
902
903// RENDER_MODE_IDX_16: RENDER_MODE_ALPHATEST, RENDER_CLASS_2CYC
904// used by entity models, item entities with shading
912
913// RENDER_MODE_IDX_18: RENDER_MODE_SURFACE_XLU, RENDER_CLASS_2CYC
921
922// RENDER_MODE_IDX_1B: RENDER_MODE_DECAL_XLU, RENDER_CLASS_2CYC
930
931// RENDER_MODE_IDX_1D: RENDER_MODE_INTERSECTING_XLU, RENDER_CLASS_2CYC
939
940// ----------------------------------------------------------------------------
941// RENDER_CLASS_2CYC, basic NO_AA variants
942
943// RENDER_MODE_IDX_11: RENDER_MODE_SURFACE_OPA_NO_AA, RENDER_CLASS_2CYC
951
952// RENDER_MODE_IDX_13: RENDER_MODE_DECAL_OPA_NO_AA, RENDER_CLASS_2CYC
960
961// RENDER_MODE_IDX_15: unused
970
971// RENDER_MODE_IDX_17: RENDER_MODE_ALPHATEST_ONESIDED, RENDER_CLASS_2CYC
978
979// RENDER_MODE_IDX_1A: RENDER_MODE_SURFACE_XLU_NO_AA, RENDER_CLASS_2CYC
987
988// RENDER_MODE_IDX_1C: RENDER_MODE_DECAL_XLU_NO_AA, RENDER_CLASS_2CYC
996
997// ----------------------------------------------------------------------------
998// RENDER_CLASS_2CYC, special modes
999
1000// RENDER_MODE_IDX_1E: unused
1007
1008// RENDER_MODE_IDX_19: RENDER_MODE_SURFACE_XLU_AA_ZB_ZUPD, RENDER_CLASS_2CYC
1016
1017// RENDER_MODE_IDX_31: RENDER_MODE_SURFACE_OPA_NO_ZB, RENDER_CLASS_2CYC
1025
1026// RENDER_MODE_IDX_32: RENDER_MODE_ALPHATEST_NO_ZB, RENDER_CLASS_2CYC
1034
1035// RENDER_MODE_IDX_33: RENDER_MODE_SURFACE_XLU_NO_ZB, RENDER_CLASS_2CYC
1043
1044// RENDER_MODE_IDX_39: RENDER_MODE_CLOUD, RENDER_CLASS_2CYC
1052
1053// RENDER_MODE_IDX_3A: RENDER_MODE_CLOUD_NO_ZB, RENDER_CLASS_2CYC
1061
1062// ----------------------------------------------------------------------------
1063// RENDER_CLASS_FOG+, basic AA variants
1064
1065// RENDER_MODE_IDX_1F: RENDER_MODE_SURFACE_OPA, RENDER_CLASS_FOG / RENDER_CLASS_FOG_SHROUD / RENDER_CLASS_1CYC_SHROUD / RENDER_CLASS_1CYC_DEPTH
1066// used by entity models
1074
1075// RENDER_MODE_IDX_21: RENDER_MODE_DECAL_OPA, RENDER_CLASS_FOG / RENDER_CLASS_FOG_SHROUD / RENDER_CLASS_1CYC_SHROUD / RENDER_CLASS_1CYC_DEPTH
1076// used by entity models
1084
1085// RENDER_MODE_IDX_23: RENDER_MODE_INTERSECTING_OPA, RENDER_CLASS_FOG / RENDER_CLASS_FOG_SHROUD / RENDER_CLASS_1CYC_SHROUD / RENDER_CLASS_1CYC_DEPTH
1086// used by entity models
1094
1095// RENDER_MODE_IDX_25: RENDER_MODE_ALPHATEST, RENDER_CLASS_FOG / RENDER_CLASS_FOG_SHROUD / RENDER_CLASS_1CYC_SHROUD / RENDER_CLASS_1CYC_DEPTH
1096// used by entity models
1104
1105// RENDER_MODE_IDX_27: RENDER_MODE_SURFACE_XLU, RENDER_CLASS_FOG / RENDER_CLASS_FOG_SHROUD
1106// used by entity models
1114
1115// RENDER_MODE_IDX_2A: RENDER_MODE_DECAL_XLU, RENDER_CLASS_FOG / RENDER_CLASS_FOG_SHROUD
1116// used by entity models
1124
1125// RENDER_MODE_IDX_2C: RENDER_MODE_INTERSECTING_XLU, RENDER_CLASS_FOG / RENDER_CLASS_FOG_SHROUD
1126// used by entity models
1134
1135// ----------------------------------------------------------------------------
1136// RENDER_CLASS_FOG+, basic NO_AA variants
1137
1138//RENDER_MODE_IDX_20: RENDER_MODE_SURFACE_OPA_NO_AA, RENDER_CLASS_FOG / RENDER_CLASS_FOG_SHROUD
1146
1147// RENDER_MODE_IDX_22: RENDER_MODE_DECAL_OPA_NO_AA, RENDER_CLASS_FOG / RENDER_CLASS_FOG_SHROUD
1155
1156// RENDER_MODE_IDX_24: unused
1164
1165// RENDER_MODE_IDX_26: RENDER_MODE_ALPHATEST_ONESIDED, RENDER_CLASS_FOG / RENDER_CLASS_FOG_SHROUD
1172
1173// RENDER_MODE_IDX_29: RENDER_MODE_SURFACE_XLU_NO_AA, RENDER_CLASS_FOG / RENDER_CLASS_FOG_SHROUD
1181
1182// RENDER_MODE_IDX_2B: RENDER_MODE_DECAL_XLU_NO_AA, RENDER_CLASS_FOG / RENDER_CLASS_FOG_SHROUD
1190
1191// ----------------------------------------------------------------------------
1192// RENDER_CLASS_FOG+, special modes
1193
1194// RENDER_MODE_IDX_2D: unused
1201
1202// RENDER_MODE_IDX_28: RENDER_MODE_SURFACE_XLU_AA_ZB_ZUPD, RENDER_CLASS_FOG / RENDER_CLASS_FOG_SHROUD
1210
1211// RENDER_MODE_IDX_34: RENDER_MODE_SURFACE_OPA_NO_ZB, RENDER_CLASS_FOG / RENDER_CLASS_FOG_SHROUD
1219
1220// RENDER_MODE_IDX_35: RENDER_MODE_ALPHATEST_NO_ZB, RENDER_CLASS_FOG / RENDER_CLASS_FOG_SHROUD
1228
1229// RENDER_MODE_IDX_36: RENDER_MODE_SURFACE_XLU_NO_ZB, RENDER_CLASS_FOG / RENDER_CLASS_FOG_SHROUD
1237
1238// RENDER_MODE_IDX_3B: RENDER_MODE_CLOUD, RENDER_CLASS_FOG / RENDER_CLASS_FOG_SHROUD / RENDER_CLASS_1CYC_SHROUD / RENDER_CLASS_1CYC_DEPTH
1246
1247// RENDER_MODE_IDX_3C: RENDER_MODE_CLOUD_NO_ZB, RENDER_CLASS_FOG / RENDER_CLASS_FOG_SHROUD / RENDER_CLASS_1CYC_SHROUD / RENDER_CLASS_1CYC_DEPTH
1255
1258 [RENDER_MODE_SURFACE_OPA] = 1000000,
1259 [RENDER_MODE_02_UNUSED] = 1000000,
1262 [RENDER_MODE_DECAL_OPA] = 1000000,
1263 [RENDER_MODE_06_UNUSED] = 1000000,
1264 [RENDER_MODE_DECAL_OPA_NO_AA] = 1000000,
1266 [RENDER_MODE_INTERSECTING_OPA] = 1000000,
1267 [RENDER_MODE_0A_UNUSED] = 1000000,
1268 [RENDER_MODE_0B_UNUSED] = 1000000,
1270 [RENDER_MODE_ALPHATEST] = 1000000,
1271 [RENDER_MODE_0E_UNUSED] = 1000000,
1275 [RENDER_MODE_12_UNUSED] = 8000000,
1280 [RENDER_MODE_17_UNUSED] = 7500000,
1281 [RENDER_MODE_18_UNUSED] = 7500000,
1283 [RENDER_MODE_DECAL_XLU] = 7000000,
1284 [RENDER_MODE_1B_UNUSED] = 7000000,
1285 [RENDER_MODE_DECAL_XLU_NO_AA] = 7000000,
1286 [RENDER_MODE_1D_UNUSED] = 7000000,
1287 [RENDER_MODE_DECAL_XLU_AHEAD] = 6500000,
1288 [RENDER_MODE_1F_UNUSED] = 6500000,
1289 [RENDER_MODE_SHADOW] = 6500000,
1292 [RENDER_MODE_23_UNUSED] = 6000000,
1293 [RENDER_MODE_24_UNUSED] = 6000000,
1295 [RENDER_MODE_INTERSECTING_XLU] = 5500000,
1296 [RENDER_MODE_27_UNUSED] = 5500000,
1297 [RENDER_MODE_PASS_THROUGH] = 5500000,
1302 [RENDER_MODE_CLOUD_NO_ZCMP] = 4500000,
1303 [RENDER_MODE_CLOUD] = 8000000,
1304 [RENDER_MODE_CLOUD_NO_ZB] = 700000,
1305};
1306
1311
1313
1316
1319
1322
1328
1333
1354
1356
1357extern Addr BattleEntityHeapBottom; // todo ???
1358
1360void appendGfx_model_group(void* model);
1362void render_transform_group(void* group);
1363void make_texture_gfx(TextureHeader*, Gfx**, IMG_PTR raster, PAL_PTR palette, IMG_PTR auxRaster, PAL_PTR auxPalette, u8, u8, u16, u16);
1366void build_custom_gfx(void);
1367
1368void appendGfx_model(void* data) {
1369 Model* model = data;
1374 s8 renderMode;
1377 s32 flags = model->flags;
1378
1379 ModelNode* modelNode;
1380 u16 customGfxIndex;
1384
1385 s32 fogMin, fogMax;
1386 s32 fogR, fogG, fogB;
1387 Gfx** gfxPos = &gMainGfxPos;
1388
1391 modelNode = model->modelNode;
1392
1393 if (model->textureID != 0) {
1394 textureHandle = &TextureHandles[model->textureID + model->textureVariation];
1396
1397 if (textureHandle->gfx != nullptr) {
1399 } else {
1400 textureHeader = nullptr;
1401 }
1402 } else {
1403 textureHandle = nullptr;
1404 textureHeader = nullptr;
1405 }
1406
1407 renderMode = model->renderMode;
1408 tintCombineType = 0;
1409
1410 if (textureHeader != nullptr) {
1411 switch (extraTileType) {
1412 case EXTRA_TILE_NONE:
1414 break;
1415 case EXTRA_TILE_MIPMAPS:
1419 break;
1420 default:
1422 break;
1423 }
1424 } else {
1426 }
1427
1428 if (textureHeader != nullptr || renderMode <= RENDER_MODES_LAST_OPAQUE) {
1432 }
1433 }
1434
1435 // if a model has a tint applied, set it up now
1436 switch ((u32)(model->customGfxIndex >> 4)) {
1437 case ENV_TINT_SHROUD:
1440 break;
1441 case ENV_TINT_DEPTH:
1442 if (renderMode <= RENDER_MODES_LAST_OPAQUE) {
1448 }
1449 break;
1450 case ENV_TINT_REMAP:
1455 break;
1456 }
1457
1458 gDPPipeSync((*gfxPos)++);
1459
1460 if (model->groupData != nullptr) {
1461 Lightsn* lights = model->groupData->lightingGroup;
1462 if (model->groupData->lightingGroup != nullptr) {
1463 switch (model->groupData->numLights) {
1464 case 0:
1465 gSPSetLights0((*gfxPos)++, lights[0]);
1466 break;
1467 case 1:
1468 gSPSetLights1((*gfxPos)++, lights[0]);
1469 break;
1470 case 2:
1471 gSPSetLights2((*gfxPos)++, lights[0]);
1472 break;
1473 case 3:
1474 gSPSetLights3((*gfxPos)++, lights[0]);
1475 break;
1476 case 4:
1477 gSPSetLights4((*gfxPos)++, lights[0]);
1478 break;
1479 case 5:
1480 gSPSetLights5((*gfxPos)++, lights[0]);
1481 break;
1482 case 6:
1483 gSPSetLights6((*gfxPos)++, lights[0]);
1484 break;
1485 case 7:
1486 gSPSetLights7((*gfxPos)++, lights[0]);
1487 break;
1488 }
1489 }
1490 }
1491
1492 if (textureHeader != nullptr) {
1493 switch (extraTileType) {
1495 case EXTRA_TILE_4:
1497 if (prop != nullptr) {
1498 s32 shift = prop->data.s;
1499 u16 offsetS = prop->dataType;
1500 s32 offsetT = prop->dataType;
1502 textureHandle->raster, textureHandle->palette,
1503 textureHandle->auxRaster, textureHandle->auxPalette,
1504 (shift >> 12) & 0xF, (shift >> 16) & 0xF,
1505 offsetS & 0xFFF, (offsetT >> 12) & 0xFFF);
1506
1507 } else {
1509 }
1510 break;
1511 default:
1513 break;
1514 }
1515 } else {
1516 gSPTexture((*gfxPos)++, 0, 0, 0, G_TX_RENDERTILE, G_OFF);
1520 }
1521
1522 // setup combine modes for main/aux texture blending when fog or tint is enabled
1524 || renderMode == RENDER_MODE_ALPHATEST
1525 || renderMode == RENDER_MODE_ALPHATEST_ONESIDED
1526 ) {
1528
1529 // only the following aux combine modes are ever used:
1530 // (A) 0x00 -> 0, 0
1531 // (B) 0x08 -> 2, 0
1532 // (C) 0x0D -> 3, 1
1533 // (D) 0x10 -> 4, 0
1534 if (textureHeader != nullptr) {
1535 u32 auxCombineType = textureHeader->auxCombineType;
1536 if (auxCombineType >= 3) {
1537 // combine modes 3, 4, ... are directly appended to the end of the table and subtype is ignored
1538 texCombineType = TEX_COMBINE_3 + (auxCombineType - 3);
1539 } else {
1540 // select based on aux combine subtypes
1541 // in practice, auxCombineSubType is ALWAYS zero here since the only (A) and (B) may reach this block
1543 }
1544 }
1545
1546 if (!(renderMode == RENDER_MODE_ALPHATEST || renderMode == RENDER_MODE_ALPHATEST_ONESIDED)) {
1548 } else {
1550 }
1551 (*gfxPos)++;
1552 }
1553
1554 // setup geometry modes and render modes
1555 switch (renderClass) {
1556 case RENDER_CLASS_1CYC:
1557 switch (renderMode) {
1560 break;
1563 break;
1566 break;
1569 break;
1572 break;
1575 break;
1578 break;
1581 break;
1586 break;
1589 break;
1592 break;
1595 break;
1598 break;
1601 break;
1604 break;
1607 break;
1610 break;
1611 case RENDER_MODE_CLOUD:
1613 break;
1616 break;
1617 default:
1619 break;
1620 }
1622 break;
1623 case RENDER_CLASS_2CYC:
1624 switch (renderMode) {
1627 break;
1630 break;
1633 break;
1636 break;
1639 break;
1642 break;
1645 break;
1650 break;
1653 break;
1656 break;
1659 break;
1662 break;
1665 break;
1668 break;
1671 break;
1674 break;
1675 case RENDER_MODE_CLOUD:
1677 break;
1680 break;
1681 default:
1683 break;
1684 }
1686 break;
1687 case RENDER_CLASS_FOG:
1688 switch (renderMode) {
1691 break;
1694 break;
1697 break;
1700 break;
1703 break;
1706 break;
1709 break;
1714 break;
1717 break;
1720 break;
1723 break;
1726 break;
1729 break;
1732 break;
1735 break;
1738 break;
1739 case RENDER_MODE_CLOUD:
1741 break;
1744 break;
1745 default:
1747 break;
1748 }
1752 break;
1755 if (ShroudTintAmt == 255) {
1756 return;
1757 }
1759 switch (renderMode) {
1762 break;
1765 break;
1768 break;
1771 break;
1774 break;
1777 break;
1780 break;
1783 break;
1786 break;
1789 break;
1792 break;
1795 break;
1798 break;
1801 break;
1804 break;
1807 break;
1810 break;
1811 case RENDER_MODE_CLOUD:
1813 break;
1816 break;
1817 }
1820 gSPFogPosition((*gfxPos)++, 970, 1000);
1821 break;
1823 switch (renderMode) {
1826 break;
1829 break;
1832 break;
1835 break;
1838 break;
1841 break;
1844 break;
1849 break;
1852 break;
1855 break;
1858 break;
1861 break;
1864 break;
1867 break;
1870 break;
1873 break;
1874 case RENDER_MODE_CLOUD:
1876 break;
1879 break;
1880 default:
1882 break;
1883 }
1885
1886 // lerp between scene fog and shroud fog based on ShroudTintAmt
1890
1891 fogMin = (gFogSettings->startDistance * (255 - ShroudTintAmt) + 900 * ShroudTintAmt) / 255;
1892 fogMax = (gFogSettings->endDistance * (255 - ShroudTintAmt) + 1000 * ShroudTintAmt) / 255;
1893
1896 break;
1899 switch (renderMode) {
1902 break;
1905 break;
1908 break;
1911 break;
1912 case RENDER_MODE_CLOUD:
1914 break;
1917 break;
1918 default:
1920 break;
1921 }
1923 break;
1924 }
1925
1929 if (mtxPushMode != G_MTX_NOPUSH) {
1931 }
1932 if (mtxLoadMode != G_MTX_MUL) {
1934 }
1935 }
1936 } else {
1940 if (mtxPushMode != G_MTX_NOPUSH) {
1942 }
1943 }
1944 }
1945
1946 // custom gfx 'pre'
1948 customGfxIndex = (model->customGfxIndex & 0xF) * 2;
1949 if ((*gCurrentCustomModelGfxPtr)[customGfxIndex] != nullptr) {
1950 gSPDisplayList((*gfxPos)++, (*gCurrentCustomModelGfxPtr)[customGfxIndex]);
1951 }
1952 }
1953
1954 // add tex panner gfx
1955 if (textureHeader != nullptr) {
1957 s32 panMainU = texPannerMainU[model->texPannerID] >> 8;
1958 s32 panMainV = texPannerMainV[model->texPannerID] >> 8;
1959 s32 panAuxU = texPannerAuxU[model->texPannerID] >> 8;
1960 s32 panAuxV = texPannerAuxV[model->texPannerID] >> 8;
1961
1962 switch (extraTileType) {
1964 gDPSetTileSize((*gfxPos)++, G_TX_RENDERTILE, panMainU, panMainV, (textureHeader->mainW - 1) * 4 + panMainU, (textureHeader->mainH / 2 - 1) * 4 + panMainV);
1965 gDPSetTileSize((*gfxPos)++, G_TX_RENDERTILE + 1, panAuxU, panAuxV, (textureHeader->mainW - 1) * 4 + panAuxU, (textureHeader->mainH / 2 - 1) * 4 + panAuxV);
1966 break;
1968 gDPSetTileSize((*gfxPos)++, G_TX_RENDERTILE, panMainU, panMainV, (textureHeader->mainW - 1) * 4 + panMainU, (textureHeader->mainH - 1) * 4 + panMainV);
1969 gDPSetTileSize((*gfxPos)++, G_TX_RENDERTILE + 1, panAuxU, panAuxV, (textureHeader->auxW - 1) * 4 + panAuxU, (textureHeader->auxH - 1) * 4 + panAuxV);
1970 break;
1971 default:
1972 gDPSetTileSize((*gfxPos)++, G_TX_RENDERTILE, panMainU, panMainV, (textureHeader->mainW - 1) * 4 + panMainU, (textureHeader->mainH - 1) * 4 + panMainV);
1973 break;
1974 }
1975 }
1976 }
1977
1980 if (mtxPushMode != G_MTX_NOPUSH) {
1982 }
1983 if (mtxLoadMode != G_MTX_MUL) {
1985 }
1986 }
1987
1988 // render the model
1990 gSPDisplayList((*gfxPos)++, modelNode->displayData->displayList);
1991 }
1992
1993 // custom gfx 'post'
1995 customGfxIndex++;
1996 if ((*gCurrentCustomModelGfxPtr)[customGfxIndex] != nullptr) {
1997 gSPDisplayList((*gfxPos)++, (*gCurrentCustomModelGfxPtr)[customGfxIndex]);
1998 }
1999 }
2000
2001 if (mtxPushMode == G_MTX_NOPUSH) {
2003 }
2004
2005 gDPPipeSync((*gfxPos)++);
2006}
2007
2009 Gfx** temp;
2010
2011 // load main img + palette to texture heap
2012 handle->raster = (IMG_PTR) TextureHeapPos;
2013 if (mainPalSize != 0) {
2014 handle->palette = (PAL_PTR) (TextureHeapPos + mainSize);
2015 } else {
2016 handle->palette = nullptr;
2017 }
2021
2022 // load aux img + palette to texture heap
2023 if (auxSize != 0) {
2024 handle->auxRaster = (IMG_PTR) TextureHeapPos;
2025 if (auxPalSize != 0) {
2026 handle->auxPalette = (PAL_PTR) (TextureHeapPos + auxSize);
2027 } else {
2028 handle->auxPalette = nullptr;
2029 }
2032 } else {
2033 handle->auxPalette = nullptr;
2034 handle->auxRaster = nullptr;
2035 }
2036
2037 // copy header data and create a display list for the texture
2038 handle->gfx = (Gfx*) TextureHeapPos;
2039 memcpy(&handle->header, header, sizeof(*header));
2040 make_texture_gfx(header, (Gfx**) &TextureHeapPos, handle->raster, handle->palette, handle->auxRaster, handle->auxPalette, 0, 0, 0, 0);
2041
2042 temp = (Gfx**) &TextureHeapPos;
2043 gSPEndDisplayList((*temp)++);
2044}
2045
2047 char* textureName = (char*)propertyName->data.p;
2049 s32 textureIdx = 0;
2051 u32 rasterSize;
2054 TextureHeader* header;
2056 s32 mainSize;
2057
2058 if (textureName == nullptr) {
2059 (*gCurrentModelTreeNodeInfo)[TreeIterPos].textureID = 0;
2060 return;
2061 }
2062
2063 while (romOffset < startOffset + size) {
2065 header = &gCurrentTextureHeader;
2066
2067 rasterSize = header->mainW * header->mainH;
2068
2069 // compute mipmaps size
2070 if (header->mainBitDepth == G_IM_SIZ_4b) {
2071 if (header->extraTiles == EXTRA_TILE_MIPMAPS) {
2072 s32 d = 2;
2073 while (header->mainW / d >= 16 && header->mainH / d > 0) {
2074 rasterSize += header->mainW / d * header->mainH / d;
2075 d *= 2;
2076 }
2077 }
2078 rasterSize /= 2;
2079 } else if (header->mainBitDepth == G_IM_SIZ_8b) {
2080 if (header->extraTiles == EXTRA_TILE_MIPMAPS) {
2081 s32 d = 2;
2082 while (header->mainW / d >= 8 && header->mainH / d > 0) {
2083 rasterSize += header->mainW / d * header->mainH / d;
2084 d *= 2;
2085 }
2086 }
2087 } else if (header->mainBitDepth == G_IM_SIZ_16b) {
2088 if (header->extraTiles == EXTRA_TILE_MIPMAPS) {
2089 s32 d = 2;
2090 while (header->mainW / d >= 4 && header->mainH / d > 0) {
2091 rasterSize += header->mainW / d * header->mainH / d;
2092 d *= 2;
2093 }
2094 }
2095 rasterSize *= 2;
2096 } else if (header->mainBitDepth == G_IM_SIZ_32b) {
2097 if (header->extraTiles == EXTRA_TILE_MIPMAPS) {
2098 s32 d = 2;
2099 while (header->mainW / d >= 2 && header->mainH / d > 0) {
2100 rasterSize += header->mainW / d * header->mainH / d;
2101 d *= 2;
2102 }
2103 }
2104 rasterSize *= 4;
2105 }
2106
2107 // compute palette size
2108 if (header->mainFmt == G_IM_FMT_CI) {
2109 paletteSize = 0x20;
2110 if (header->mainBitDepth == G_IM_SIZ_8b) {
2111 paletteSize = 0x200;
2112 }
2113 } else {
2114 paletteSize = 0;
2115 }
2116
2117 // compute aux tile size
2118 if (header->extraTiles == EXTRA_TILE_AUX_INDEPENDENT) {
2119 auxRasterSize = header->auxW * header->auxH;
2120 if (header->auxBitDepth == G_IM_SIZ_4b) {
2121 auxRasterSize /= 2;
2122 } else if (header->auxBitDepth == G_IM_SIZ_8b) {
2123 } else if (header->auxBitDepth == G_IM_SIZ_16b) {
2124 auxRasterSize *= 2;
2125 } else {
2126 if (header->auxBitDepth == G_IM_SIZ_32b) {
2127 auxRasterSize *= 4;
2128 }
2129 }
2130 if (header->auxFmt == G_IM_FMT_CI) {
2131 auxPaletteSize = 0x20;
2132 if (header->auxBitDepth == G_IM_SIZ_8b) {
2133 auxPaletteSize = 0x200;
2134 }
2135 } else {
2136 auxPaletteSize = 0;
2137 }
2138 } else {
2139 auxPaletteSize = 0;
2140 auxRasterSize = 0;
2141 }
2142
2143 if (strcmp(textureName, header->name) == 0) {
2144 // found the texture with `textureName`
2145 break;
2146 }
2147
2148 textureIdx++;
2149 mainSize = rasterSize + paletteSize + sizeof(*header);
2152 }
2153
2154 if (romOffset >= startOffset + 0x40000) {
2155 // did not find the texture with `textureName`
2156 printf("could not find texture '%s'\n", textureName);
2157 (*gCurrentModelTreeNodeInfo)[TreeIterPos].textureID = 0;
2158 return;
2159 }
2160
2161 (*gCurrentModelTreeNodeInfo)[TreeIterPos].textureID = textureIdx + 1;
2162 textureHandle = &TextureHandles[(*gCurrentModelTreeNodeInfo)[TreeIterPos].textureID];
2163 romOffset += sizeof(*header);
2164
2165 if (textureHandle->gfx == nullptr) {
2168 }
2169}
2170
2171// loads variations for current texture by looping through the following textures until a non-variant is found
2173 u32 offset;
2175 TextureHeader* header;
2177 u32 rasterSize;
2181 s32 mainSize;
2182 s32 currentTextureID = textureID;
2183
2184 for (offset = romOffset; offset < baseOffset + size;) {
2185 dma_copy((u8*)offset, (u8*)offset + sizeof(iterTextureHeader), &iterTextureHeader);
2186 header = &iterTextureHeader;
2187
2188 if (strcmp(header->name, "end_of_textures") == 0) {
2189 return;
2190 }
2191
2192 if (!header->isVariant) {
2193 // done reading variants
2194 break;
2195 }
2196
2197 rasterSize = header->mainW * header->mainH;
2198
2199 // compute mipmaps size
2200 if (header->mainBitDepth == G_IM_SIZ_4b) {
2201 if (header->extraTiles == EXTRA_TILE_MIPMAPS) {
2202 s32 d = 2;
2203 while (header->mainW / d >= 16 && header->mainH / d > 0) {
2204 rasterSize += header->mainW / d * header->mainH / d;
2205 d *= 2;
2206 }
2207 }
2208 rasterSize /= 2;
2209 } else if (header->mainBitDepth == G_IM_SIZ_8b) {
2210 if (header->extraTiles == EXTRA_TILE_MIPMAPS) {
2211 s32 d = 2;
2212 while (header->mainW / d >= 8 && header->mainH / d > 0) {
2213 rasterSize += header->mainW / d * header->mainH / d;
2214 d *= 2;
2215 }
2216 }
2217 } else if (header->mainBitDepth == G_IM_SIZ_16b) {
2218 if (header->extraTiles == EXTRA_TILE_MIPMAPS) {
2219 s32 d = 2;
2220 while (header->mainW / d >= 4 && header->mainH / d > 0) {
2221 rasterSize += header->mainW / d * header->mainH / d;
2222 d *= 2;
2223 }
2224 }
2225 rasterSize *= 2;
2226 } else if (header->mainBitDepth == G_IM_SIZ_32b) {
2227 if (header->extraTiles == EXTRA_TILE_MIPMAPS) {
2228 s32 d = 2;
2229 while (header->mainW / d >= 2 && header->mainH / d > 0) {
2230 rasterSize += header->mainW / d * header->mainH / d;
2231 d *= 2;
2232 }
2233 }
2234 rasterSize *= 4;
2235 }
2236
2237 // compute palette size
2238 if (header->mainFmt == G_IM_FMT_CI) {
2239 paletteSize = 0x20;
2240 if (header->mainBitDepth == G_IM_SIZ_8b) {
2241 paletteSize = 0x200;
2242 }
2243 } else {
2244 paletteSize = 0;
2245 }
2246
2247 // compute aux tile size
2248 if (header->extraTiles == EXTRA_TILE_AUX_INDEPENDENT) {
2249 auxRasterSize = header->auxW * header->auxH;
2250 if (header->auxBitDepth == G_IM_SIZ_4b) {
2251 auxRasterSize /= 2;
2252 } else if (header->auxBitDepth == G_IM_SIZ_8b) {
2253 } else if (header->auxBitDepth == G_IM_SIZ_16b) {
2254 auxRasterSize *= 2;
2255 } else {
2256 if (header->auxBitDepth == G_IM_SIZ_32b) {
2257 auxRasterSize *= 4;
2258 }
2259 }
2260 if (header->auxFmt == G_IM_FMT_CI) {
2261 auxPaletteSize = 0x20;
2262 if (header->auxBitDepth == G_IM_SIZ_8b) {
2263 auxPaletteSize = 0x200;
2264 }
2265 } else {
2266 auxPaletteSize = 0;
2267 }
2268 } else {
2269 auxPaletteSize = 0;
2270 auxRasterSize = 0;
2271 }
2272
2273 textureID++;
2274 currentTextureID = textureID;
2276 load_texture_impl(offset + sizeof(*header), textureHandle, header, rasterSize, paletteSize, auxRasterSize, auxPaletteSize);
2277
2278 mainSize = rasterSize + paletteSize + sizeof(*header);
2279 offset += mainSize;
2280 offset += auxRasterSize + auxPaletteSize;
2281 }
2282}
2283
2285 s32 numProperties = node->numProperties;
2286 ModelNodeProperty* propertyList = node->propertyList;
2287 s32 i;
2288
2289 for (i = 0; i < numProperties; i++, propertyList++) {
2290 if (propertyList->key == key) {
2291 return propertyList;
2292 }
2293 }
2294 return nullptr;
2295}
2296
2297// load textures used by models, starting from current model
2299 if (model->type != SHAPE_TYPE_MODEL) {
2300 if (model->groupData != nullptr) {
2301 s32 numChildren = model->groupData->numChildren;
2302
2303 if (numChildren != 0) {
2304 s32 i;
2305
2306 for (i = 0; i < numChildren; i++) {
2307 load_next_model_textures(model->groupData->childList[i], romOffset, texSize);
2308 }
2309 }
2310 }
2311 } else {
2313 if (propTextureName != nullptr) {
2315 }
2316 }
2317 TreeIterPos++;
2318}
2319
2320// load all textures used by models, starting from the root
2322 s32 baseOffset = 0;
2323
2324 // textures are loaded to the upper half of the texture heap when not in the world
2327 }
2328
2330
2331 if (rootModel != nullptr && romOffset != 0 && size != 0) {
2332 s32 i;
2333
2334 for (i = 0; i < ARRAY_COUNT(TextureHandles); i++) {
2335 TextureHandles[i].gfx = nullptr;
2336 }
2337
2338 TreeIterPos = 0;
2339 if (rootModel != nullptr) {
2341 }
2342 }
2343}
2344
2346 s32 ret = 0;
2347
2348 if (model->type != SHAPE_TYPE_MODEL && model->groupData != nullptr) {
2349 s32 numChildren = model->groupData->numChildren;
2350
2351 if (numChildren != 0) {
2352 s32 i;
2353
2354 ret += numChildren;
2355 for (i = 0; i < numChildren; i++) {
2356 ret += mdl_get_child_count(model->groupData->childList[i]);
2357 }
2358 }
2359 }
2360 return ret;
2361}
2362
2364 s32 i;
2365
2375 ShroudTintAmt = 0;
2376 ShroudTintR = 0;
2377 ShroudTintG = 0;
2378 ShroudTintB = 0;
2380 } else {
2390 }
2391
2392 for (i = 0; i < ARRAY_COUNT(*gCurrentModels); i++) {
2393 (*gCurrentModels)[i] = 0;
2394 }
2395
2396 for (i = 0; i < ARRAY_COUNT(*gCurrentTransformGroups); i++) {
2397 (*gCurrentTransformGroups)[i] = 0;
2398 }
2399
2400 for (i = 0; i < ARRAY_COUNT(*gCurrentCustomModelGfxPtr); i++) {
2401 (*gCurrentCustomModelGfxPtr)[i] = 0;
2402 (*gCurrentCustomModelGfxBuildersPtr)[i] = 0;
2403 }
2404
2405 *gCurrentModelTreeRoot = nullptr;
2406
2407 for (i = 0; i < ARRAY_COUNT(*gCurrentModelTreeNodeInfo); i++) {
2408 (*gCurrentModelTreeNodeInfo)[i].modelIndex = -1;
2409 (*gCurrentModelTreeNodeInfo)[i].treeDepth = 0;
2410 (*gCurrentModelTreeNodeInfo)[i].textureID = 0;
2411 }
2412
2414 gFogSettings->enabled = false;
2415 gFogSettings->color.r = 10;
2416 gFogSettings->color.g = 10;
2417 gFogSettings->color.b = 10;
2418 gFogSettings->color.a = 0;
2420 gFogSettings->endDistance = 1000;
2421
2422 for (i = 0; i < ARRAY_COUNT(texPannerAuxV); i++) {
2423 texPannerAuxV[i] = 0;
2424 texPannerAuxU[i] = 0;
2425 texPannerMainV[i] = 0;
2426 texPannerMainU[i] = 0;
2427 }
2428}
2429
2453
2455 s32 i;
2456
2457 for (i = 0; i < ARRAY_COUNT(*gCurrentModels); i++) {
2458 Model* model = (*gCurrentModels)[i];
2459
2460 if (model != nullptr) {
2462
2463 bb->halfSizeX = (bb->maxX - bb->minX) * 0.5;
2464 bb->halfSizeY = (bb->maxY - bb->minY) * 0.5;
2465 bb->halfSizeZ = (bb->maxZ - bb->minZ) * 0.5;
2467 }
2468 }
2469}
2470
2472 ModelNode* node = bp->mdlNode;
2475 s32 modelIdx;
2476 Model* model;
2477 f32 x, y, z;
2478
2480 modelIdx = 0;
2481 if (prop != nullptr) {
2482 s32 replaceWithFlame = (prop->data.s >> 4) & 0xF;
2483
2484 if (replaceWithFlame != 0) {
2486 if (prop != nullptr) {
2488 EffectInstance* effect;
2489
2491 (bb->minX + bb->maxX) * 0.5f,
2492 bb->minY,
2493 (bb->minZ + bb->maxZ) * 0.5f,
2494 1.0f,
2495 &effect);
2496 return;
2497 }
2498 }
2499 }
2500
2502 if ((*gCurrentModels)[modelIdx] == nullptr) {
2503 break;
2504 }
2505 }
2506
2507 (*gCurrentModels)[modelIdx] = model = heap_malloc(sizeof(*model));
2508 model->flags = bp->flags | MODEL_FLAG_VALID;
2509 model->modelID = TreeIterPos;
2510 model->modelNode = bp->mdlNode;
2511 model->groupData = bp->groupData;
2512 model->matrixFreshness = 0;
2513 node = model->modelNode;
2514
2516 if (prop != nullptr) {
2517 model->texPannerID = prop->data.s & 0xF;
2518 } else {
2519 model->texPannerID = TEX_PANNER_0;
2520 }
2521 model->customGfxIndex = CUSTOM_GFX_0;
2522
2523 if (node->type != SHAPE_TYPE_GROUP) {
2525 } else {
2527
2528 if (prop != nullptr) {
2529 // GROUP_INFO properties always come in pairs, with the second giving the render mode
2530 prop++;
2531 }
2532 }
2533
2534 if (prop != nullptr) {
2535 model->renderMode = prop->data.s;
2536 } else {
2537 model->renderMode = RENDER_MODE_SURFACE_OPA;
2538 }
2539
2540 model->textureID = (*gCurrentModelTreeNodeInfo)[TreeIterPos].textureID;
2541 model->textureVariation = 0;
2542
2543 if (!is_identity_fixed_mtx(bp->mtx)) {
2544 model->bakedMtx = heap_malloc(sizeof(*model->bakedMtx));
2545 *model->bakedMtx = *bp->mtx;
2546 model->savedMtx = *model->bakedMtx;
2547 } else {
2548 model->bakedMtx = nullptr;
2549 guMtxIdent(&model->savedMtx);
2551 }
2552
2553 guMtxIdentF(model->userTransformMtx);
2554 model->finalMtx = nullptr;
2556 if (prop != nullptr) {
2558
2559 x = (bb->minX + bb->maxX) * 0.5f;
2560 y = (bb->minY + bb->maxY) * 0.5f;
2561 z = (bb->minZ + bb->maxZ) * 0.5f;
2562 } else {
2563 x = y = z = 0.0f;
2564 }
2565
2566 if (model->bakedMtx != nullptr) {
2567 guMtxXFML(model->bakedMtx, x, y, z, &x, &y, &z);
2568 }
2569
2570 model->center.x = x;
2571 model->center.y = y;
2572 model->center.z = z;
2573
2575 x = bb->maxX - bb->minX;
2576 y = bb->maxY - bb->minY;
2577 z = bb->maxZ - bb->minZ;
2578 bb->halfSizeX = x * 0.5;
2579 bb->halfSizeY = y * 0.5;
2580 bb->halfSizeZ = z * 0.5;
2581
2582 if (model->bakedMtx == nullptr && x < 100.0f && y < 100.0f && z < 100.0f) {
2584 }
2585 (*gCurrentModelTreeNodeInfo)[TreeIterPos].modelIndex = modelIdx;
2586}
2587
2591 f32 mX, mY, mZ;
2592 f32 mtgX, mtgY, mtgZ;
2593 Model* model;
2594 Mtx* curMtx;
2597 s32 i;
2598
2599 for (i = 0; i < ARRAY_COUNT(*gCurrentModels); i++) {
2600 model = (*gCurrentModels)[i];
2601 if (model != nullptr && (model->flags != 0) && !(model->flags & MODEL_FLAG_INACTIVE)) {
2602 if (!(model->flags & MODEL_FLAG_MATRIX_DIRTY)) {
2603 if (model->matrixFreshness != 0) {
2604 // matrix was recalculated recently and stored on the matrix stack
2605 // since DisplayContexts alternate, we can fetch the previous matrix from the other context
2607 if (model->matrixFreshness == 0) {
2608 // since it hasn't changed in a few frames, cache the matrix
2609 model->savedMtx = *model->finalMtx;
2610 }
2611 // copy matrix from previous DisplayContext stack to current one
2612 curMtx = model->finalMtx;
2614 *model->finalMtx = *curMtx;
2615 } else {
2616 // transform matrix is not changed, have gfx build with saved matrix
2617 model->finalMtx = &model->savedMtx;
2618 }
2619 } else {
2620 // first frame with dirty matrix, need to recalculate it
2622 model->matrixFreshness = 2;
2623
2624 // write matrix to the matrix stack
2626 if (model->bakedMtx == nullptr || (model->flags & MODEL_FLAG_TRANSFORM_GROUP_MEMBER)) {
2627 guMtxF2L(model->userTransformMtx, curMtx);
2628 } else {
2629 guMtxL2F(tempModelMtx, model->bakedMtx);
2630 guMtxCatF(model->userTransformMtx, tempModelMtx, tempModelMtx);
2632 }
2634
2635 // recalculate the center of the model with transformation applied
2637 mX = (bb->minX + bb->maxX) * 0.5f;
2638 mY = (bb->minY + bb->maxY) * 0.5f;
2639 mZ = (bb->minZ + bb->maxZ) * 0.5f;
2640 guMtxXFML(curMtx, mX, mY, mZ, &mX, &mY, &mZ);
2641 model->center.x = mX;
2642 model->center.y = mY;
2643 model->center.z = mZ;
2644
2645 // point matrix for gfx building to our matrix on the stack
2646 model->finalMtx = curMtx;
2647
2648 // disable bounds culling for models with dynamic transformations
2650 }
2651 }
2652 }
2653
2654 for (i = 0; i < ARRAY_COUNT((*gCurrentTransformGroups)); i++) {
2655 mtg = (*gCurrentTransformGroups)[i];
2656 if (mtg != nullptr && mtg->flags != 0 && !(mtg->flags & TRANSFORM_GROUP_FLAG_INACTIVE)) {
2657 if (!(mtg->flags & TRANSFORM_GROUP_FLAG_MATRIX_DIRTY)) {
2658 if (mtg->matrixFreshness != 0) {
2659 // matrix was recalculated recently and stored on the matrix stack
2660 // since DisplayContexts alternate, we can fetch the previous matrix from the other context
2661 mtg->matrixFreshness--;
2662 if (mtg->matrixFreshness == 0) {
2663 // since it hasn't changed in a few frames, cache the matrix
2664 mtg->savedMtx = *mtg->finalMtx;
2665 }
2666 // copy matrix from previous DisplayContext stack to current one
2667 curMtx = mtg->finalMtx;
2669 *mtg->finalMtx = *curMtx;
2670 } else {
2671 // transform matrix is not changed, have gfx build with saved matrix
2672 mtg->finalMtx = &mtg->savedMtx;
2673 }
2674 } else {
2675 // first frame with dirty matrix, need to recalculate it
2677 mtg->matrixFreshness = 2;
2678
2679 // write matrix to the matrix stack
2681 if (mtg->bakedMtx == nullptr) {
2682 guMtxF2L(mtg->userTransformMtx, curMtx);
2683 } else {
2684 guMtxL2F(tempGroupMtx, mtg->bakedMtx);
2685 guMtxCatF(mtg->userTransformMtx, tempGroupMtx, tempGroupMtx);
2687 }
2689
2690 // recalculate the center of the transform group with transformation applied
2692 mtgX = (bb->minX + bb->maxX) * 0.5f;
2693 mtgY = (bb->minY + bb->maxY) * 0.5f;
2694 mtgZ = (bb->minZ + bb->maxZ) * 0.5f;
2696 mtg->center.x = mtgX;
2697 mtg->center.y = mtgY;
2698 mtg->center.z = mtgZ;
2699
2700 // point matrix for gfx building to our matrix on the stack
2701 mtg->finalMtx = curMtx;
2702 }
2703 }
2704 }
2705
2707}
2708
2709void render_models(void) {
2710 RenderTask rt;
2711 RenderTask* rtPtr = &rt;
2712 f32 outX, outY, outZ, outW;
2713 f32 m00, m01, m02, m03;
2714 f32 m10, m11, m12, m13;
2715 f32 m20, m21, m22, m23;
2716 f32 m30, m31, m32, m33;
2717 f32 centerX, centerY, centerZ;
2718 f32 bbx, bby, bbz;
2719
2721 Model* model;
2724 f32 xComp, yComp, zComp;
2725
2726 s32 distance;
2728 s32 i;
2729
2730#define TEST_POINT_VISIBILITY \
2731 outX = (m00 * xComp) + (m10 * yComp) + (m20 * zComp) + m30; \
2732 outY = (m01 * xComp) + (m11 * yComp) + (m21 * zComp) + m31; \
2733 outZ = (m02 * xComp) + (m12 * yComp) + (m22 * zComp) + m32; \
2734 outW = (m03 * xComp) + (m13 * yComp) + (m23 * zComp) + m33; \
2735 if (outW == 0.0f) { \
2736 break; \
2737 } \
2738 /* Perspective divide */ \
2739 outW = 1.0f / outW; \
2740 xComp = outX * outW; \
2741 yComp = outY * outW; \
2742 zComp = outZ * outW; \
2743 if (zComp > -1.0f && xComp >= -1.0f && xComp <= 1.0f && yComp >= -1.0f && yComp <= 1.0f) { \
2744 break; \
2745 }
2746
2747 m00 = camera->mtxPerspective[0][0];
2748 m01 = camera->mtxPerspective[0][1];
2749 m02 = camera->mtxPerspective[0][2];
2750 m03 = camera->mtxPerspective[0][3];
2751 m10 = camera->mtxPerspective[1][0];
2752 m11 = camera->mtxPerspective[1][1];
2753 m12 = camera->mtxPerspective[1][2];
2754 m13 = camera->mtxPerspective[1][3];
2755 m20 = camera->mtxPerspective[2][0];
2756 m21 = camera->mtxPerspective[2][1];
2757 m22 = camera->mtxPerspective[2][2];
2758 m23 = camera->mtxPerspective[2][3];
2759 m30 = camera->mtxPerspective[3][0];
2760 m31 = camera->mtxPerspective[3][1];
2761 m32 = camera->mtxPerspective[3][2];
2762 m33 = camera->mtxPerspective[3][3];
2763
2764 // enqueue all visible models not in transform groups
2765 for (i = 0; i < ARRAY_COUNT(*gCurrentModels); i++) {
2766 model = (*gCurrentModels)[i];
2767 if (model == nullptr) {
2768 continue;
2769 }
2770 if (model->flags == 0) {
2771 continue;
2772 }
2773 if (model->flags & MODEL_FLAG_INACTIVE) {
2774 continue;
2775 }
2776 if (model->flags & MODEL_FLAG_HIDDEN) {
2777 continue;
2778 }
2779 if (model->flags & MODEL_FLAG_20) {
2780 continue;
2781 }
2783 continue;
2784 }
2785
2786 centerX = model->center.x;
2787 centerY = model->center.y;
2788 centerZ = model->center.z;
2789
2790 // for models that are small enough to do bounds culling, only render if at least one
2791 // corner of its boundary box is visible
2792 if (model->flags & MODEL_FLAG_DO_BOUNDS_CULLING) {
2793 notVisible = false;
2794 boundingBox = (ModelBoundingBox*) model->modelNode->propertyList;
2795 bbx = boundingBox->halfSizeX;
2796 bby = boundingBox->halfSizeY;
2797 bbz = boundingBox->halfSizeZ;
2798
2799 while (true) {
2800 if (true) {
2801 xComp = centerX - bbx;
2802 yComp = centerY - bby;
2803 zComp = centerZ - bbz;
2805 }
2806
2807 if (bbx != 0.0f) {
2808 xComp = centerX + bbx;
2809 yComp = centerY - bby;
2810 zComp = centerZ - bbz;
2812 }
2813
2814 if (bby != 0.0f) {
2815 xComp = centerX - bbx;
2816 yComp = centerY + bby;
2817 zComp = centerZ - bbz;
2819 }
2820
2821 if (bbx != 0.0f && bby != 0.0f) {
2822 xComp = centerX + bbx;
2823 yComp = centerY + bby;
2824 zComp = centerZ - bbz;
2826 }
2827
2828 if (bbz != 0.0f) {
2829 xComp = centerX - bbx;
2830 yComp = centerY - bby;
2831 zComp = centerZ + bbz;
2833 }
2834
2835 if (bbx != 0.0f && bbz != 0.0f) {
2836 xComp = centerX + bbx;
2837 yComp = centerY - bby;
2838 zComp = centerZ + bbz;
2840 }
2841
2842 if (bby != 0.0f && bbz != 0.0f) {
2843 xComp = centerX - bbx;
2844 yComp = centerY + bby;
2845 zComp = centerZ + bbz;
2847 }
2848
2849 if (bbx != 0.0f && bby != 0.0f && bbz != 0.0f) {
2850 xComp = centerX + bbx;
2851 yComp = centerY + bby;
2852 zComp = centerZ + bbz;
2854 }
2855 notVisible = true;
2856 break;
2857 }
2858 // no points of the models bounding box were visible
2859 if (notVisible) {
2860 continue;
2861 }
2862 }
2863
2864 // map all model depths to the interval [0, 10k] and submit render task
2865 transform_point(camera->mtxPerspective, centerX, centerY, centerZ, 1.0f, &outX, &outY, &outZ, &outW);
2866 distance = outZ + 5000.0f;
2867 if (distance < 0) {
2868 distance = 0;
2869 } else if (distance > 10000) {
2870 distance = 10000;
2871 }
2872 rtPtr->appendGfxArg = model;
2873 if (model->modelNode->type == SHAPE_TYPE_GROUP) {
2874 rtPtr->appendGfx = appendGfx_model_group;
2875 } else {
2876 rtPtr->appendGfx = appendGfx_model;
2877 }
2878 rtPtr->dist = -distance;
2879 rtPtr->renderMode = model->renderMode;
2881 }
2882
2883 // enqueue models in transform groups
2884 // only the center of the group is used for depth sorting
2885 for (i = 0; i < ARRAY_COUNT(*gCurrentTransformGroups); i++) {
2886 transformGroup = (*gCurrentTransformGroups)[i];
2887 if (transformGroup == nullptr) {
2888 continue;
2889 }
2890
2891 if (transformGroup->flags == 0) {
2892 continue;
2893 }
2894
2896 continue;
2897 }
2898
2899 xComp = transformGroup->center.x;
2900 yComp = transformGroup->center.y;
2901 zComp = transformGroup->center.z;
2902
2904 camera->mtxPerspective,
2905 xComp, yComp, zComp, 1.0f,
2906 &outX, &outY, &outZ, &outW
2907 );
2908 if (outW == 0.0f) {
2909 outW = 1.0f;
2910 }
2911
2912 distance = ((outZ / outW) * 10000.0f);
2913
2915 rtPtr->appendGfx = render_transform_group;
2916 rtPtr->appendGfxArg = transformGroup;
2917 rtPtr->dist = -distance;
2918 rtPtr->renderMode = transformGroup->renderMode;
2920 }
2921 }
2922}
2923
2924void appendGfx_model_group(void* data) {
2925 Model* model = data;
2926 s32 modelTreeDepth = (*gCurrentModelTreeNodeInfo)[model->modelID].treeDepth;
2927 s32 i;
2928
2929 for (i = model->modelID - 1; i >= 0; i--) {
2930 if (modelTreeDepth >= (*gCurrentModelTreeNodeInfo)[i].treeDepth) {
2931 break;
2932 }
2933 }
2934
2935 TreeIterPos = i + 1;
2937}
2938
2940 Model* mdl = model; // temps needed to match
2941 ModelNode* modelNode = mdl->modelNode;
2942
2943 if (model->modelNode->type != SHAPE_TYPE_MODEL) {
2944 if (modelNode->groupData != nullptr) {
2945 s32 numChildren = modelNode->groupData->numChildren;
2946
2947 if (numChildren != 0) {
2948 s32 i;
2949
2950 for (i = 0; i < numChildren; i++, TreeIterPos++) {
2951 Model newModel = *mdl;
2953
2954 newModel.flags = mdl->flags;
2955 newModel.finalMtx = mdl->finalMtx;
2956 newModel.modelNode = modelNode->groupData->childList[i];
2957 newModel.texPannerID = mdl->texPannerID;
2958 newModel.customGfxIndex = mdl->customGfxIndex;
2959
2960 if (newModel.modelNode->type == SHAPE_TYPE_MODEL) {
2962 } else {
2963 prop = nullptr;
2964 }
2965
2966 if (prop != nullptr) {
2967 newModel.renderMode = prop->data.s;
2968 } else {
2969 newModel.renderMode = 0;
2970 }
2971
2972 newModel.textureID = (*gCurrentModelTreeNodeInfo)[TreeIterPos].textureID;
2973 newModel.textureVariation = 0;
2975 }
2976 }
2977 }
2978 } else {
2980 }
2981}
2982
2983// this looks like a switch, but I can't figure it out
2985 Gfx** gfx = &gMainGfxPos;
2986 Model* model;
2987
2988 if (node != nullptr) {
2989 if (node->type == SHAPE_TYPE_GROUP) {
2991
2992 if (groupInfoProp != nullptr && groupInfoProp->data.s != 0) {
2994 if (!(model->flags & MODEL_FLAG_HIDDEN)) {
2996 }
2997 mtg_IterIdx++;
2998 return;
2999 }
3000 }
3001 if (node->type != SHAPE_TYPE_MODEL) {
3002 if (node->groupData != nullptr) {
3003 s32 numChildren;
3004 s32 i;
3005
3006 if (node->groupData->transformMatrix != nullptr) {
3007 gSPMatrix((*gfx)++, node->groupData->transformMatrix, G_MTX_PUSH | G_MTX_MUL | G_MTX_MODELVIEW);
3008 }
3009
3010 numChildren = node->groupData->numChildren;
3011 if (numChildren != 0) {
3012 for (i = 0; i < numChildren; i++) {
3013 render_transform_group_node(node->groupData->childList[i]);
3014 }
3015 }
3016
3017 if (node->groupData->transformMatrix != nullptr) {
3018 gSPPopMatrix((*gfx)++, G_MTX_MODELVIEW);
3019 }
3020 }
3021 return;
3022 }
3023
3025 if (!(model->flags & MODEL_FLAG_HIDDEN)) {
3027 }
3028 mtg_IterIdx++;
3029 }
3030}
3031
3032// gfx temps needed
3033void render_transform_group(void* data) {
3034 ModelTransformGroup* group = data;
3035 Gfx** gfx = &gMainGfxPos;
3036
3037 if (!(group->flags & TRANSFORM_GROUP_FLAG_INACTIVE)) {
3039 if (!(group->flags & TRANSFORM_GROUP_FLAG_IGNORE_MATRIX)) {
3040 gSPMatrix((*gfx)++, group->finalMtx, (G_MTX_PUSH | G_MTX_LOAD) | G_MTX_MODELVIEW);
3041 }
3042
3043 render_transform_group_node(group->baseModelNode);
3044
3045 if (!(group->flags & TRANSFORM_GROUP_FLAG_IGNORE_MATRIX)) {
3046 gSPPopMatrix((*gfx)++, G_MTX_MODELVIEW);
3047 }
3048 gDPPipeSync((*gfx)++);
3049 }
3050}
3051
3055 s32 mainFmt;
3056 s32 auxFmt;
3057 s32 mainWrapW, mainWrapH;
3058 s32 auxWrapW, auxWrapH;
3061 s32 lod;
3066 s32 lutMode;
3067 s32 lodMode;
3070 s32 mainBitDepth;
3071 s32 auxBitDepth;
3072
3073 mainWidth = header->mainW;
3074 mainHeight = header->mainH;
3075
3076 lod = 0;
3077 auxPaletteIndex = 0;
3078
3081
3082 mainWrapW = header->mainWrapW;
3083 mainWrapH = header->mainWrapH;
3084
3085 mainFmt = header->mainFmt;
3086 mainBitDepth = header->mainBitDepth;
3087
3088 extraTileType = header->extraTiles;
3090
3091 auxWidth = header->auxW;
3092 auxHeight = header->auxH;
3093
3096
3097 auxWrapW = header->auxWrapW;
3098 auxWrapH = header->auxWrapH;
3099 auxFmt = header->auxFmt;
3100 auxBitDepth = header->auxBitDepth;
3101
3103 if (palette != nullptr) {
3104 auxPaletteIndex = 1;
3105 } else {
3106 auxPaletteIndex = 0;
3107 }
3108 }
3109
3110 if (palette != nullptr || auxPalette != nullptr) {
3112 if (palette != nullptr) {
3113 if (mainBitDepth == G_IM_SIZ_4b) {
3114 gDPLoadTLUT_pal16((*gfxPos)++, 0, palette);
3115 } else if (mainBitDepth == G_IM_SIZ_8b) {
3116 gDPLoadTLUT_pal256((*gfxPos)++, palette);
3117 }
3118 }
3119 if (auxPalette != nullptr) {
3120 if (auxBitDepth == G_IM_SIZ_4b) {
3121 gDPLoadTLUT_pal16((*gfxPos)++, auxPaletteIndex, auxPalette);
3122 } else if (auxBitDepth == G_IM_SIZ_8b) {
3123 gDPLoadTLUT_pal256((*gfxPos)++, auxPalette);
3124 }
3125 }
3126 } else {
3128 }
3129
3130 // only the following aux combine modes are ever used:
3131 // (A) 0x00 -> 0, 0
3132 // (B) 0x08 -> 2, 0
3133 // (C) 0x0D -> 3, 1
3134 // (D) 0x10 -> 4, 0
3136 if (texCombineType >= 3) {
3137 // combine modes 3, 4, ... are directly appended to the end of the table and subtype is ignored
3139 } else {
3140 // select based on aux combine subtypes
3141 // in practice, auxCombineSubType is ALWAYS zero here since the only (A) and (B) may reach this block
3143 }
3144
3146 (*gfxPos)++;
3147
3148 switch (extraTileType) {
3149 case EXTRA_TILE_NONE:
3151 gSPTexture((*gfxPos)++, 0xFFFF, 0xFFFF, 0, G_TX_RENDERTILE, G_ON);
3152 switch (mainBitDepth) {
3153 case G_IM_SIZ_4b:
3154 gDPLoadTextureBlock_4b((*gfxPos)++, raster, mainFmt,
3156 mainWrapW, mainWrapH, mainMasks, mainMaskt, G_TX_NOLOD, G_TX_NOLOD);
3157 break;
3158 case G_IM_SIZ_8b:
3159 gDPLoadTextureBlock((*gfxPos)++, raster, mainFmt, G_IM_SIZ_8b,
3161 mainWrapW, mainWrapH, mainMasks, mainMaskt, G_TX_NOLOD, G_TX_NOLOD);
3162 break;
3163 case G_IM_SIZ_16b:
3164 gDPLoadTextureBlock((*gfxPos)++, raster, mainFmt, G_IM_SIZ_16b,
3166 mainWrapW, mainWrapH, mainMasks, mainMaskt, G_TX_NOLOD, G_TX_NOLOD);
3167 break;
3168 case 3:
3169 gDPLoadTextureBlock((*gfxPos)++, raster, mainFmt, G_IM_SIZ_32b,
3171 mainWrapW, mainWrapH, mainMasks, mainMaskt, G_TX_NOLOD, G_TX_NOLOD);
3172 break;
3173 }
3174 break;
3175 case EXTRA_TILE_MIPMAPS:
3176 lodMode = G_TL_LOD;
3177 switch (mainBitDepth) {
3178 case G_IM_SIZ_4b:
3179 for (rasterPtr = raster, lod = 0, lodDivisor = 1;
3180 mainWidth / lodDivisor * 4 >= 64 && mainHeight / lodDivisor != 0;
3182 {
3183 gDPLoadMultiTile_4b((*gfxPos)++, rasterPtr, (u32)(rasterPtr - raster) >> 3, lod, mainFmt,
3185 0, 0, mainWidth / lodDivisor - 1, mainHeight / lodDivisor - 1, 0,
3186 mainWrapW, mainWrapH, mainMasks - lod, mainMaskt - lod, lod, lod);
3187 }
3188 break;
3189 case G_IM_SIZ_8b:
3190 for (rasterPtr = raster, lod = 0, lodDivisor = 1;
3191 mainWidth / lodDivisor * 8 >= 64 && mainHeight / lodDivisor != 0;
3193 {
3194 gDPLoadMultiTile((*gfxPos)++, rasterPtr, ((u32)(rasterPtr - raster)) >> 3, lod, mainFmt, G_IM_SIZ_8b,
3196 0, 0, mainWidth / lodDivisor - 1, mainHeight / lodDivisor - 1, 0,
3197 mainWrapW, mainWrapH, mainMasks - lod, mainMaskt - lod, lod, lod);
3198 }
3199 break;
3200 case G_IM_SIZ_16b:
3201 for (rasterPtr = raster, lod = 0, lodDivisor = 1;
3202 mainWidth / lodDivisor * 16 >= 64 && mainHeight / lodDivisor != 0;
3204 {
3205 gDPLoadMultiTile((*gfxPos)++, rasterPtr, ((u32)(rasterPtr - raster)) >> 3, lod, mainFmt, G_IM_SIZ_16b,
3207 0, 0, mainWidth / lodDivisor - 1, mainHeight / lodDivisor - 1, 0,
3208 mainWrapW, mainWrapH, mainMasks - lod, mainMaskt - lod, lod, lod);
3209 }
3210 break;
3211 case G_IM_SIZ_32b:
3212 for (rasterPtr = raster, lod = 0, lodDivisor = 1;
3213 mainWidth / lodDivisor * 32 >= 64 && mainHeight / lodDivisor != 0;
3215 {
3216 gDPLoadMultiTile((*gfxPos)++, rasterPtr, ((u32)(rasterPtr - raster)) >> 4, lod, mainFmt, G_IM_SIZ_32b,
3218 0, 0, mainWidth / lodDivisor - 1, mainHeight / lodDivisor - 1, 0,
3219 mainWrapW, mainWrapH, mainMasks - lod, mainMaskt - lod, lod, lod);
3220 }
3221 break;
3222 }
3223 gSPTexture((*gfxPos)++, 0xFFFF, 0xFFFF, lod - 1, G_TX_RENDERTILE, G_ON);
3224 break;
3226 gSPTexture((*gfxPos)++, 0xFFFF, 0xFFFF, 0, G_TX_RENDERTILE, G_ON);
3227 gDPPipeSync((*gfxPos)++);
3229 switch (mainBitDepth) {
3230 case G_IM_SIZ_4b:
3232 mainWrapW, mainWrapH, mainMasks, mainMaskt, G_TX_NOLOD, G_TX_NOLOD,
3234 break;
3235 case G_IM_SIZ_8b:
3237 mainWrapW, mainWrapH, mainMasks, mainMaskt, G_TX_NOLOD, G_TX_NOLOD,
3239 break;
3240 case G_IM_SIZ_16b:
3242 mainWrapW, mainWrapH, mainMasks, mainMaskt, G_TX_NOLOD, G_TX_NOLOD,
3244 break;
3245 case G_IM_SIZ_32b:
3247 mainWrapW, mainWrapH, mainMasks, mainMaskt, G_TX_NOLOD, G_TX_NOLOD,
3249 break;
3250 }
3251 break;
3253 gSPTexture((*gfxPos)++, 0xFFFF, 0xFFFF, 0, G_TX_RENDERTILE, G_ON);
3255 switch (mainBitDepth) {
3256 case G_IM_SIZ_4b:
3257 gDPLoadTextureTile_4b((*gfxPos)++, raster, mainFmt, mainWidth, mainHeight,
3258 0, 0, mainWidth - 1, mainHeight - 1, 0,
3259 mainWrapW, mainWrapH, mainMasks, mainMaskt, G_TX_NOLOD, G_TX_NOLOD);
3260 lodDivisor = (((mainWidth * mainHeight) >> 1) + 7)>>3; // required to use lodDivisor here
3261 break;
3262 case G_IM_SIZ_8b:
3263 gDPLoadTextureTile((*gfxPos)++, raster, mainFmt, G_IM_SIZ_8b, mainWidth, mainHeight,
3264 0, 0, mainWidth - 1, mainHeight - 1, 0,
3265 mainWrapW, mainWrapH, mainMasks, mainMaskt, G_TX_NOLOD, G_TX_NOLOD);
3266 lodDivisor = ((mainWidth * mainHeight) + 7)>>3;
3267 break;
3268 case G_IM_SIZ_16b:
3270 0, 0, mainWidth - 1, mainHeight - 1, 0,
3271 mainWrapW, mainWrapH, mainMasks, mainMaskt, G_TX_NOLOD, G_TX_NOLOD);
3272 lodDivisor = ((mainWidth * mainHeight) * 2 + 7)>>3;
3273 break;
3274 case G_IM_SIZ_32b:
3276 0, 0, mainWidth - 1, mainHeight - 1, 0,
3277 mainWrapW, mainWrapH, mainMasks, mainMaskt, G_TX_NOLOD, G_TX_NOLOD);
3278 lodDivisor = ((mainWidth * mainHeight / 2) * 2 + 7)>>3;
3279 break;
3280 }
3281
3282 switch (auxBitDepth) {
3283 case G_IM_SIZ_4b:
3284 gDPScrollMultiTile_4b((*gfxPos)++, auxRaster, lodDivisor, 1, auxFmt, auxWidth, auxHeight,
3285 0, 0, auxWidth - 1, auxHeight - 1, auxPaletteIndex,
3286 auxWrapW, auxWrapH, auxMasks, auxMaskt,
3288 break;
3289 case G_IM_SIZ_8b:
3290 gDPScrollMultiTile((*gfxPos)++, auxRaster, lodDivisor, 1, auxFmt, G_IM_SIZ_8b, auxWidth, auxHeight,
3291 0, 0, auxWidth - 1, auxHeight - 1, auxPaletteIndex,
3292 auxWrapW, auxWrapH, auxMasks, auxMaskt,
3294 break;
3295 case G_IM_SIZ_16b:
3296 gDPScrollMultiTile((*gfxPos)++, auxRaster, lodDivisor, 1, auxFmt, G_IM_SIZ_16b, auxWidth, auxHeight,
3297 0, 0, auxWidth - 1, auxHeight - 1, auxPaletteIndex,
3298 auxWrapW, auxWrapH, auxMasks, auxMaskt,
3300 break;
3301 case G_IM_SIZ_32b:
3302 gDPScrollMultiTile((*gfxPos)++, auxRaster, lodDivisor, 1, auxFmt, G_IM_SIZ_32b, auxWidth, auxHeight,
3303 0, 0, auxWidth - 1, auxHeight - 1, auxPaletteIndex,
3304 auxWrapW, auxWrapH, auxMasks, auxMaskt,
3306 break;
3307 }
3308 }
3310}
3311
3313 return (*gCurrentModels)[listIndex];
3314}
3315
3317 Matrix4f mtx;
3318
3319 guMtxIdentF(mtx);
3320
3321 if (texturesOffset != 0) {
3323 }
3324
3326 TreeIterPos = 0;
3327
3328 if (rootModel != nullptr) {
3329 load_model_transforms(rootModel, nullptr, mtx, 0);
3330 }
3331}
3332
3335 Mtx sp50;
3339 s32 i;
3340
3341 if (model->groupData != nullptr && model->groupData->numChildren != 0) {
3342 s32 groupType;
3343
3344 if (model->groupData->transformMatrix != nullptr) {
3346
3347 guMtxL2F(tempMtx, model->groupData->transformMatrix);
3349 }
3350
3352 if (prop == nullptr) {
3354 } else {
3355 groupType = prop->data.s;
3356 }
3357
3358 if (model->type != SHAPE_TYPE_GROUP || groupType == GROUP_TYPE_0) {
3359 for (i = 0; i < model->groupData->numChildren; i++) {
3360 load_model_transforms(model->groupData->childList[i], model,
3361 model->groupData->transformMatrix != nullptr ? combinedMtx : mdlTransformMtx,
3362 treeDepth + 1);
3363 }
3364
3365 (*gCurrentModelTreeNodeInfo)[TreeIterPos].modelIndex = -1;
3366 (*gCurrentModelTreeNodeInfo)[TreeIterPos].treeDepth = treeDepth;
3367 TreeIterPos++;
3368 return;
3369 }
3370 }
3371
3373 modelBPptr->flags = 0;
3374 modelBPptr->mdlNode = model;
3375 modelBPptr->groupData = parent->groupData;
3376 modelBPptr->mtx = &sp50;
3377
3378 if (model->type == SHAPE_TYPE_GROUP) {
3380
3381 for (i = TreeIterPos; i < TreeIterPos + childCount; i++) {
3382 (*gCurrentModelTreeNodeInfo)[i].modelIndex = -1;
3383 (*gCurrentModelTreeNodeInfo)[i].treeDepth = treeDepth + 1;
3384 }
3386 }
3387
3389 (*gCurrentModelTreeNodeInfo)[TreeIterPos].treeDepth = treeDepth;
3390 TreeIterPos++;
3391}
3392
3394 s32 i;
3395
3396 if (treeIndex < MAX_MODELS) {
3397 u8 modelIndex = (*gCurrentModelTreeNodeInfo)[treeIndex].modelIndex;
3398
3399 if (modelIndex != (u8)-1) {
3400 return modelIndex;
3401 }
3402 }
3403
3404 for (i = 0; i < MAX_MODELS; i++) {
3406
3407 if (model != nullptr && model->modelID == treeIndex) {
3408 return i;
3409 }
3410 }
3411 return 0;
3412}
3413
3416 s32 i;
3417
3418 for (i = 0; i < MAX_MODEL_TRANSFORM_GROUPS; i++) {
3420
3421 if (group != nullptr && group->groupModelID == modelID) {
3422 return i;
3423 }
3424 }
3425
3426 return -1;
3427}
3428
3429void get_model_center_and_size(u16 modelID, f32* centerX, f32* centerY, f32* centerZ, f32* sizeX, f32* sizeY, f32* sizeZ) {
3431 ModelNode* node = model->modelNode;
3433
3434 *centerX = model->center.x;
3435 *centerY = model->center.y;
3436 *centerZ = model->center.z;
3437
3439
3440 if (bb != nullptr) {
3441 *sizeX = bb->halfSizeX;
3442 *sizeY = bb->halfSizeY;
3443 *sizeZ = bb->halfSizeZ;
3444 } else {
3445 *sizeX = *sizeY = *sizeZ = 0.0f;
3446 }
3447}
3448
3452
3453// find group info?
3457 s32 numChildren;
3458 s32 i;
3459 u16 currentID;
3460
3461 // stop searching if node is a model
3462 if (node->type == SHAPE_TYPE_MODEL) {
3464 return;
3465 }
3466
3467 // stop searching if node is a group with GROUP_TYPE_0
3468 if (node->type == SHAPE_TYPE_GROUP) {
3470 if (prop != nullptr && prop->data.s != GROUP_TYPE_0) {
3473 return;
3474 }
3475 }
3476
3477 if (node->groupData != nullptr) {
3478 numChildren = node->groupData->numChildren;
3479 if (numChildren != 0) {
3480 for (i = 0; i < numChildren; i++) {
3481 currentNode = node->groupData->childList[i];
3483
3484 if (currentNode->type == SHAPE_TYPE_GROUP) {
3486 if (prop != nullptr && prop->data.s != GROUP_TYPE_0) {
3488 }
3489 }
3491
3492 if (mtg_FoundModelNode != nullptr) {
3493 // not possible
3494 return;
3495 }
3496
3497 // the current model is the one we're looking for
3501 return;
3502 }
3503
3504 TreeIterPos++;
3505 }
3506 }
3507 }
3508}
3509
3511 TreeIterPos = 0;
3512 mtg_FoundModelNode = nullptr;
3513 mtg_SearchModelID = modelID;
3514 mtg_MaxChild = 0;
3515 mtg_MinChild = 0;
3517
3518 if (mtg_FoundModelNode != nullptr) {
3520 ModelNode* node;
3523 f32 x, y, z;
3524 s32 i;
3525
3526 for (i = 0; i < ARRAY_COUNT(*gCurrentTransformGroups); i++) {
3527 if ((*gCurrentTransformGroups)[i] == nullptr) {
3528 break;
3529 }
3530 }
3531
3532 (*gCurrentTransformGroups)[i] = newMtg = heap_malloc(sizeof(*newMtg));
3534 newMtg->groupModelID = modelID;
3537 newMtg->matrixFreshness = 0;
3538 newMtg->bakedMtx = nullptr;
3539 newMtg->baseModelNode = mtg_FoundModelNode;
3540 guMtxIdent(&newMtg->savedMtx);
3542 guMtxIdentF(newMtg->userTransformMtx);
3543
3544 node = newMtg->baseModelNode;
3545
3546 if (node->type != SHAPE_TYPE_GROUP) {
3548 } else {
3550
3551 if (prop != nullptr) {
3552 // GROUP_INFO properties always come in pairs, with the second giving the render mode
3553 prop++;
3554 }
3555 }
3556
3557 if (prop != nullptr) {
3558 newMtg->renderMode = prop->data.s;
3559 } else {
3560 newMtg->renderMode = RENDER_MODE_SURFACE_OPA;
3561 }
3562
3564 if (bb != nullptr) {
3565 x = (bb->minX + bb->maxX) * 0.5f;
3566 y = (bb->minY + bb->maxY) * 0.5f;
3567 z = (bb->minZ + bb->maxZ) * 0.5f;
3568 } else {
3569 x = y = z = 0.0f;
3570 }
3571
3572 if (newMtg->bakedMtx != nullptr) {
3573 guMtxXFML(newMtg->bakedMtx, x, y, z, &x, &y, &z);
3574 }
3575
3576 newMtg->center.x = x;
3577 newMtg->center.y = y;
3578 newMtg->center.z = z;
3579 enable_transform_group(modelID);
3580 }
3581}
3582
3585 s32 i;
3586
3588
3589 for (i = group->minChildModelIndex; i <= group->maxChildModelIndex; i++) {
3591
3593
3594 if (model->bakedMtx != nullptr) {
3596 }
3597 }
3598}
3599
3602 s32 i;
3603
3605
3606 for (i = group->minChildModelIndex; i <= group->maxChildModelIndex; i++) {
3608
3610
3611 if (model->bakedMtx != nullptr) {
3613 }
3614 }
3615}
3616
3619 Model* newModel;
3620 s32 i;
3621
3622 for (i = 0; i < ARRAY_COUNT(*gCurrentModels); i++) {
3623 if ((*gCurrentModels)[i] == nullptr) {
3624 break;
3625 }
3626 }
3627
3628 (*gCurrentModels)[i] = newModel = heap_malloc(sizeof(*newModel));
3629 *newModel = *srcModel;
3630 newModel->modelID = newModelID;
3631}
3632
3633void mdl_group_set_visibility(u16 treeIndex, s32 flags, s32 mode) {
3634 s32 maxGroupIndex = -1;
3636 s32 modelIndex = (*gCurrentModelTreeNodeInfo)[treeIndex].modelIndex;
3638 s32 i;
3639
3640 if (modelIndex < MAX_MODELS - 1) {
3641 minGroupIndex = maxGroupIndex = modelIndex;
3642 } else {
3643 s32 treeDepth = (*gCurrentModelTreeNodeInfo)[treeIndex].treeDepth;
3644 for (i = treeIndex - 1; i >= 0; i--) {
3645 if ((*gCurrentModelTreeNodeInfo)[i].treeDepth <= treeDepth) {
3646 break;
3647 }
3648
3649 siblingIndex = (*gCurrentModelTreeNodeInfo)[i].modelIndex;
3650
3651 if (siblingIndex < MAX_MODELS - 1) {
3652 if (maxGroupIndex == -1) {
3654 }
3656 }
3657 }
3658 }
3659
3660 if (mode < 2) {
3661 for (i = minGroupIndex; i <= maxGroupIndex; i++) {
3662 Model* model = (*gCurrentModels)[i];
3663 if (mode != MODEL_GROUP_HIDDEN) {
3664 model->flags &= ~flags;
3665 } else {
3666 model->flags |= flags;
3667 }
3668 }
3669 } else {
3670 for (i = 0; i < minGroupIndex; i++) {
3671 Model* model = (*gCurrentModels)[i];
3672 if (mode == MODEL_GROUP_OTHERS_VISIBLE) {
3673 model->flags &= ~flags;
3674 } else {
3675 model->flags |= flags;
3676 }
3677 }
3678 for (i = maxGroupIndex + 1; i < MAX_MODELS; i++) {
3679 Model* model = (*gCurrentModels)[i];
3680 if (model != nullptr) {
3681 if (mode == MODEL_GROUP_OTHERS_VISIBLE) {
3682 model->flags &= ~flags;
3683 } else {
3684 model->flags |= flags;
3685 }
3686 }
3687 }
3688 }
3689}
3690
3691void mdl_group_set_custom_gfx(u16 groupModelID, s32 customGfxIndex, s32 tintType, b32 invertSelection) {
3692 s32 maxGroupIndex = -1;
3693 s32 i;
3695 s32 modelIndex = (*gCurrentModelTreeNodeInfo)[groupModelID].modelIndex;
3698
3699 if (modelIndex < MAX_MODELS - 1) {
3700 minGroupIndex = maxGroupIndex = modelIndex;
3701 } else {
3702 s32 treeDepth = (*gCurrentModelTreeNodeInfo)[groupModelID].treeDepth;
3703 for (i = groupModelID - 1; i >= 0; i--) {
3704 if ((*gCurrentModelTreeNodeInfo)[i].treeDepth <= treeDepth) {
3705 break;
3706 }
3707
3708 siblingIndex = (*gCurrentModelTreeNodeInfo)[i].modelIndex;
3709
3710 if (siblingIndex < MAX_MODELS - 1) {
3711 if (maxGroupIndex == -1) {
3713 }
3715 }
3716 }
3717 }
3718
3719 maskLow = maskHigh = 0;
3720
3721 if (customGfxIndex < 0) {
3722 maskLow = 0xF;
3723 customGfxIndex = 0;
3724 }
3725
3726 if (tintType < 0) {
3727 maskHigh = 0xF0;
3728 tintType = 0;
3729 }
3730
3731 packed = customGfxIndex + (tintType << 4);
3732
3733 if (!invertSelection) {
3734 for (i = minGroupIndex; i <= maxGroupIndex; i++) {
3735 Model* model = (*gCurrentModels)[i];
3736 model->customGfxIndex = (model->customGfxIndex & (maskLow + maskHigh)) + packed;
3737 }
3738 } else {
3739 for (i = 0; i < minGroupIndex; i++) {
3740 Model* model = (*gCurrentModels)[i];
3741 model->customGfxIndex = (model->customGfxIndex & (maskLow + maskHigh)) + packed;
3742 }
3743 for (i = maxGroupIndex + 1; i < MAX_MODELS; i++) {
3744 Model* model = (*gCurrentModels)[i];
3745 if (model != nullptr) {
3746 model->customGfxIndex = (model->customGfxIndex & (maskLow + maskHigh)) + packed;
3747 }
3748 }
3749 }
3750}
3751
3753 s32 i;
3754
3755 for (i = 0; i < ARRAY_COUNT(*gCurrentModels); i++) {
3756 Model* model = (*gCurrentModels)[i];
3757
3758 if (model != nullptr) {
3760 }
3761 }
3762
3763 for (i = 0; i < ARRAY_COUNT(*gCurrentTransformGroups); i++) {
3764 ModelTransformGroup* transformGroup = (*gCurrentTransformGroups)[i];
3765
3766 if (transformGroup != nullptr) {
3768 }
3769 }
3770}
3771
3773 gFogSettings->enabled = true;
3774}
3775
3777 gFogSettings->enabled = false;
3778}
3779
3780void set_world_fog_dist(s32 start, s32 end) {
3781 gFogSettings->startDistance = start;
3783}
3784
3786 gFogSettings->color.r = r;
3787 gFogSettings->color.g = g;
3788 gFogSettings->color.b = b;
3789 gFogSettings->color.a = a;
3790}
3791
3793 return gFogSettings->enabled;
3794}
3795
3796void get_world_fog_distance(s32* start, s32* end) {
3797 *start = gFogSettings->startDistance;
3798 *end = gFogSettings->endDistance;
3799}
3800
3801void get_world_fog_color(s32* r, s32* g, s32* b, s32* a) {
3802 *r = gFogSettings->color.r;
3803 *g = gFogSettings->color.g;
3804 *b = gFogSettings->color.b;
3805 *a = gFogSettings->color.a;
3806}
3807
3808void set_tex_panner(Model* model, s32 texPannerID) {
3809 model->texPannerID = texPannerID;
3810}
3811
3812void set_main_pan_u(s32 texPannerID, s32 value) {
3813 texPannerMainU[texPannerID] = value;
3814}
3815
3816void set_main_pan_v(s32 texPannerID, s32 value) {
3817 texPannerMainV[texPannerID] = value;
3818}
3819
3820void set_aux_pan_u(s32 texPannerID, s32 value) {
3821 texPannerAuxU[texPannerID] = value;
3822}
3823
3824void set_aux_pan_v(s32 texPannerID, s32 value) {
3825 texPannerAuxV[texPannerID] = value;
3826}
3827
3829 if (customGfxIndex == -1) {
3830 customGfxIndex = model->customGfxIndex & 0xF;
3831 }
3832
3833 if (tintType == -1) {
3834 tintType = model->customGfxIndex >> 4;
3835 }
3836
3837 model->customGfxIndex = (customGfxIndex & 0xF) + ((tintType & 0xF) << 4);
3838}
3839
3840void set_custom_gfx(s32 customGfxIndex, Gfx* pre, Gfx* post) {
3841 (*gCurrentCustomModelGfxPtr)[customGfxIndex * 2] = pre;
3842 (*gCurrentCustomModelGfxPtr)[customGfxIndex * 2 + 1] = post;
3843}
3844
3846 (*gCurrentCustomModelGfxBuildersPtr)[customGfxIndex * 2] = pre;
3847 (*gCurrentCustomModelGfxBuildersPtr)[customGfxIndex * 2 + 1] = post;
3848}
3849
3851 Gfx* gfx = gMainGfxPos;
3854 s32 i;
3855
3856 // placeholder branch
3857 gSPBranchList(gMainGfxPos++, 0x00000000);
3858
3859 for (i = 0; i < ARRAY_COUNT(*gCurrentCustomModelGfxPtr) / 2; i++) {
3860 preFunc = (*gCurrentCustomModelGfxBuildersPtr)[i * 2];
3861
3862 if (preFunc != nullptr) {
3863 (*gCurrentCustomModelGfxPtr)[i * 2] = gMainGfxPos;
3864 preFunc(i);
3866 }
3867
3868 postFunc = (*gCurrentCustomModelGfxBuildersPtr)[i * 2 + 1];
3869 if (postFunc != nullptr) {
3870 (*gCurrentCustomModelGfxPtr)[i * 2 + 1] = gMainGfxPos;
3871 postFunc(i);
3873 }
3874 }
3875
3876 // overwrite placeholder with final branch address
3878}
3879
3880// weird temps necessary to match
3883 s32* mtxIt = (s32*)mtx;
3884 s32* identityIt;
3885 s32 i;
3886
3887 if (mtx == nullptr) {
3888 return true;
3889 }
3890
3892
3893 for (i = 0; i < 16; i++, mtxIt++, identityIt++) {
3894 if (*mtxIt != *identityIt) {
3895 return false;
3896 }
3897 }
3898
3899 return true;
3900}
3901
3903 ShroudTintR = r;
3904 ShroudTintG = g;
3905 ShroudTintB = b;
3906 ShroudTintAmt = a;
3907}
3908
3909void mdl_get_shroud_tint_params(u8* r, u8* g, u8* b, u8* a) {
3910 *r = ShroudTintR;
3911 *g = ShroudTintG;
3912 *b = ShroudTintB;
3913 *a = ShroudTintAmt;
3914}
3915
3916void mdl_set_depth_tint_params(u8 primR, u8 primG, u8 primB, u8 primA, u8 fogR, u8 fogG, u8 fogB, s32 fogStart, s32 fogEnd) {
3917 DepthTintBaseR = primR;
3918 DepthTintBaseG = primG;
3919 DepthTintBaseB = primB;
3920 DepthTintBaseA = primA;
3926}
3927
3928void mdl_get_depth_tint_params(u8* primR, u8* primG, u8* primB, u8* primA, u8* fogR, u8* fogG, u8* fogB,
3929 s32* fogStart, s32* fogEnd) {
3930 *primR = DepthTintBaseR;
3931 *primG = DepthTintBaseG;
3932 *primB = DepthTintBaseB;
3933 *primA = DepthTintBaseA;
3939}
3940
3949
3950void mdl_get_remap_tint_params(u8* primR, u8* primG, u8* primB, u8* envR, u8* envG, u8* envB) {
3951 *primR = RemapTintMaxR;
3952 *primG = RemapTintMaxG;
3953 *primB = RemapTintMaxB;
3954 *envR = RemapTintMinR;
3955 *envG = RemapTintMinG;
3956 *envB = RemapTintMinB;
3957}
3958
3959void mdl_get_vertex_count(Gfx* gfx, s32* numVertices, Vtx** baseVtx, s32* gfxCount, Vtx* baseAddr) {
3960
3961 s32 vtxCount;
3962 u32 w0, w1;
3963 u32 cmd;
3965 s32 minVtx;
3966 s32 maxVtx;
3968
3969 minVtx = 0;
3970 maxVtx = 0;
3971
3972 if (gfx == nullptr) {
3973 *numVertices = 0;
3974 *baseVtx = nullptr;
3975 } else {
3976 Gfx* baseGfx = gfx;
3977
3978 do {
3979 w0 = gfx->words.w0;
3980 w1 = gfx->words.w1;
3981 cmd = _SHIFTR(w0,24,8);
3982
3983 if (cmd == G_VTX) {
3984 vtxStartAddr = w1;
3985 if (baseAddr != nullptr) {
3986 vtxStartAddr = (vtxStartAddr & 0xFFFF) + (s32)baseAddr;
3987 }
3988 vtxCount = _SHIFTR(w0,12,8);
3989 if (minVtx == 0) {
3991 maxVtx = vtxStartAddr + (vtxCount * sizeof(Vtx));
3992 }
3993 vtxEndAddr = vtxStartAddr + (vtxCount * sizeof(Vtx));
3994 if (maxVtx < vtxEndAddr) {
3996 }
3997 if (minVtx > vtxEndAddr) {
3999 }
4000 }
4001 gfx++;
4002 } while (cmd != G_ENDDL);
4003
4004 *numVertices = (maxVtx - minVtx) >> 4;
4005 *baseVtx = (Vtx*)minVtx;
4006 *gfxCount = gfx - baseGfx;
4007 w1 = 64; // TODO required to match -- can be any operation that stores w1
4008 }
4009}
4010
4012 u32 w0;
4013 Vtx* w1;
4014 do {
4015 w0 = (*((unsigned long long*)nodeDlist)) >> 0x20; // TODO required to match
4016 w1 = (Vtx*)nodeDlist->words.w1;
4017 if (w0 >> 0x18 == G_VTX) {
4018 w1 = arg3 + (w1 - baseVtx);
4019 }
4020 arg2->words.w0 = w0;
4021 arg2->words.w1 = (u32)w1;
4022 nodeDlist++;
4023 arg2++;
4024 } while (w0 >> 0x18 != G_ENDDL);
4025}
4026
4028 u32 i;
4029
4030 for (i = 0; i < num * sizeof(*src); i++) {
4031 ((u8*)dest)[i] = ((u8*)src)[i];
4032 }
4033}
4034
4036 s32 numVertices;
4037 Vtx* baseVtx;
4038 s32 gfxCount;
4039 Gfx* nodeDlist;
4040 Model* model;
4042 s32 i;
4043
4045 nodeDlist = model->modelNode->displayData->displayList;
4046 mdl_get_vertex_count(nodeDlist, &numVertices, &baseVtx, &gfxCount, nullptr);
4047
4048 copy = (*gCurrentModelLocalVtxBuffers)[copyIndex] = heap_malloc(sizeof(*copy));
4049
4050 if (isMakingCopy) {
4051 for (i = 0; i < ARRAY_COUNT(copy->gfxCopy); i++) {
4052 copy->gfxCopy[i] = heap_malloc(gfxCount * sizeof(*copy->gfxCopy[i]));
4053 copy->vtxCopy[i] = heap_malloc(numVertices * sizeof(*copy->vtxCopy[i]));
4054 mdl_local_gfx_update_vtx_pointers(nodeDlist, baseVtx, copy->gfxCopy[i], copy->vtxCopy[i]);
4055 mdl_local_gfx_copy_vertices(baseVtx, numVertices, copy->vtxCopy[i]);
4056 }
4058 } else {
4059 for (i = 0; i < ARRAY_COUNT(copy->gfxCopy); i++) {
4060 copy->gfxCopy[i] = nullptr;
4061 copy->vtxCopy[i] = nullptr;
4062 }
4063 model->flags |= MODEL_FLAG_HIDDEN;
4064 }
4065
4066 copy->selector = 0;
4067 copy->numVertices = numVertices;
4068 copy->minVertexAddr = baseVtx;
4069}
4070
4072 ModelLocalVertexCopy* mlvc = (*gCurrentModelLocalVtxBuffers)[copyIndex];
4073 s32 selector = mlvc->selector;
4074
4075 *firstVertex = mlvc->minVertexAddr;
4076 *copiedVertices = mlvc->vtxCopy[selector];
4077 *numCopied = mlvc->numVertices;
4078}
4079
4081 ModelLocalVertexCopy* mlvc = (*gCurrentModelLocalVtxBuffers)[copyIndex];
4082 s32 selector = mlvc->selector;
4083 Gfx* gfxCopy = mlvc->gfxCopy[selector];
4084
4085 mlvc->selector++;
4086 if (mlvc->selector > ARRAY_COUNT(mlvc->gfxCopy) - 1) {
4087 mlvc->selector = 0;
4088 }
4089
4090 return gfxCopy;
4091}
4092
4094 s32 sp18;
4095 Vtx* baseVtx;
4096 s32 sp20;
4097 f32 v1tc1;
4098 f32 v2tc1;
4099 f32 sp2C;
4100 f32 v0tc1;
4101 f32 sp40;
4102 f32 v1tc0;
4103 f32 v1ob2;
4104 f32 ob2;
4105 f32 ob1;
4106 f32 v0ob0;
4107 f32 v0ob2;
4108 f32 v0tc0;
4109 f32 v2ob0;
4110 f32 v2tc0;
4111 f32 v1ob0;
4112 f32 v2ob2;
4113 f32 ob0;
4114 f32 var_f10;
4115 f32 var_f24;
4116 f32 var_f26;
4117 f32 tc1;
4118 f32 var_f30;
4119 f32 tc0;
4120 f32 var_f6_2;
4121 s32 i;
4122 u32 cnB;
4123 u32 cnG;
4124 u32 cnR;
4125 f32 var_f20;
4126
4127 s32 listIndex;
4128 Model* model;
4129 Gfx* dlist;
4130 s32 cmd;
4131 Vtx* tempVert;
4132
4133 s8 zero = 0; // TODO needed to match
4134
4135 listIndex = get_model_list_index_from_tree_index(modelID & 0xFFFF);
4136 model = get_model_from_list_index(listIndex);
4137 dlist = model->modelNode->displayData->displayList;
4138
4139 while (true) {
4140 cmd = dlist->words.w0 >> 0x18;
4141 tempVert = (Vtx*)dlist->words.w1;
4142 if (cmd == G_ENDDL) {
4143 break;
4144 }
4145 if (cmd == G_VTX) {
4146 baseVtx = tempVert;
4147 break;
4148 }
4149 dlist++;
4150 }
4151
4152 v0ob0 = baseVtx[zero].v.ob[0];
4153 v0ob2 = baseVtx[zero].v.ob[2];
4154 v0tc0 = baseVtx[zero].v.tc[0];
4155 v0tc1 = baseVtx[zero].v.tc[1];
4156
4157 v1ob0 = baseVtx[1].v.ob[0];
4158 v1ob2 = baseVtx[1].v.ob[2];
4159 v1tc0 = baseVtx[1].v.tc[0];
4160 v1tc1 = baseVtx[1].v.tc[1];
4161
4162 v2ob0 = baseVtx[2].v.ob[0];
4163 v2ob2 = baseVtx[2].v.ob[2];
4164 v2tc0 = baseVtx[2].v.tc[0];
4165 v2tc1 = baseVtx[2].v.tc[1];
4166
4167 cnR = baseVtx[0].v.cn[0];
4168 cnG = baseVtx[0].v.cn[1];
4169 cnB = baseVtx[0].v.cn[2];
4170
4171 if (v0ob0 != v1ob0) {
4172 f32 f2 = v0ob0 - v2ob0;
4173 f32 f14 = v0ob0 - v1ob0;
4174 f32 f8 = v0tc0 - v1tc0;
4175 f32 f2a = f2 / f14;
4176 f32 f0 = f2a * f8;
4177 f32 f12 = v0ob2 - v1ob2;
4178 f32 f10 = f2a * f12;
4179 f32 f4 = v0tc0 - v2tc0;
4180 f32 f6 = v0ob2 - v2ob2;
4181 f32 f0a = f0 - f4;
4182 f32 f10a = f10 - f6;
4183
4184 f32 f0b, f4a, f2b, f8a, f6a, f0c, f2c, f12a;
4185
4186 sp40 = f0a / f10a; // used later
4187 f0b = f12 * sp40;
4188 f4a = v0tc1 - v1tc1;
4189 f2b = f2a * f4a;
4190 f8a = f8 - f0b;
4191 var_f30 = f8a / f14; // used later
4192 f6a = var_f30 * v0ob0;
4193 f0c = v0tc1 - v2tc1;
4194 f2c = f2b - f0c;
4195 var_f26 = f2c / f10a; // used later
4196 f12a = f12 * var_f26;
4197 var_f24 = (f4a - f12a) / f14; // used later
4198 sp2C = v0tc0 - f6a - sp40 * v0ob2; // used later
4199 var_f20 = v0tc1 - var_f24 * v0ob0 - var_f26 * v0ob2; // used later
4200 } else {
4201 f32 f2 = v0ob2 - v2ob2;
4202 f32 f14 = v0ob2 - v1ob2;
4203 f32 f8 = v0tc0 - v1tc0;
4204 f32 f12 = v0ob0 - v1ob0;
4205 f32 f4 = v0tc0 - v2tc0;
4206 f32 f6 = v0ob0 - v2ob0;
4207 f32 f0 = f2 / f14 * f8;
4208 f32 f10 = f2 / f14 * f12;
4209
4210 f32 f0b, f4a, f2b, f8a, f6a, f0c, f8b;
4211
4212 var_f30 = (f0 - f4) / (f10 - f6); // used later
4213 f0b = f12 * var_f30;
4214 f6a = var_f30 * v0ob0;
4215 f4a = v0tc1 - v1tc1;
4216 f2b = f2 / f14 * f4a;
4217 f8a = f8 - f0b;
4218 sp40 = f8a / f14; // used later
4219 f8b = sp40 * v0ob2;
4220 f0c = v0tc1 - v2tc1;
4221 var_f24 = (f2b - f0c) / (f10 - f6); // used later
4222 var_f26 = (f4a - f12 * var_f24) / f14; // used later
4223 sp2C = v0tc0 - f6a - f8b; // used later
4224 var_f20 = v0tc1 - var_f24 * v0ob0 - var_f26 * v0ob2; // used later
4225 }
4226
4228
4229 for (i = 0; i < sp18; i++) {
4230 ob0 = baseVtx->v.ob[0];
4231 ob1 = baseVtx->v.ob[1];
4232 ob2 = baseVtx->v.ob[2];
4233 if (arg2 != nullptr) {
4234 var_f10 = (arg2[0][0] * ob0) + (arg2[1][0] * ob1) + (arg2[2][0] * ob2) + arg2[3][0];
4235 var_f6_2 = (arg2[0][2] * ob0) + (arg2[1][2] * ob1) + (arg2[2][2] * ob2) + arg2[3][2];
4236 } else {
4237 var_f10 = ob0;
4238 var_f6_2 = ob2;
4239 }
4240 tc0 = (var_f30 * var_f10) + (sp40 * var_f6_2) + sp2C;
4241 tc1 = (var_f24 * var_f10) + (var_f26 * var_f6_2) + var_f20;
4242 if (tc0 < 0.0f) {
4243 tc0 -= 0.5;
4244 } else if (tc0 > 0.0f) {
4245 tc0 += 0.5;
4246 }
4247
4248 if (tc1 < 0.0f) {
4249 tc1 -= 0.5;
4250 } else if (tc1 > 0.0f) {
4251 tc1 += 0.5;
4252 }
4253
4254 baseVtx->v.tc[0] = tc0;
4255 baseVtx->v.tc[1] = tc1;
4256 baseVtx->v.cn[0] = cnR;
4257 baseVtx->v.cn[1] = cnG;
4258 baseVtx->v.cn[2] = cnB;
4259 baseVtx++;
4260 }
4261}
4262
4263// Checks if the center of a model is visible.
4264// If `depthQueryID` is nonnegative, the depth buffer is checked to see if the model's center is occluded by geometry.
4265// Otherwise, the occlusion check is skipped.
4266// `depthQueryID` must be between 0 and the size of `DepthCopyBuffer` minus 1.
4267// Every nonnegative value of `depthQueryID` must be unique within a frame, otherwise the result will corrupt the data
4268// of the previous query that shared the same ID.
4269// Occlusion visibility checks are always one frame out of date, as they reference the previous frame's depth buffer.
4273 f32 outX;
4274 f32 outY;
4275 f32 outZ;
4276 f32 outW;
4277
4283
4284 // If an invalid depth query id was provided, return false.
4285 if (depthQueryID >= ARRAY_COUNT(DepthCopyBuffer)) {
4286 return false;
4287 }
4288 // Transform the model's center into clip space.
4289 transform_point(camera->mtxPerspective, model->center.x, model->center.y, model->center.z, 1.0f, &outX, &outY, &outZ, &outW);
4290 if (outW == 0.0f) {
4291 *screenX = 0.0f;
4292 *screenY = 0.0f;
4293 return true;
4294 }
4295 // Perform the perspective divide (divide xyz by w) to convert to normalized device coords.
4296 // Normalized device coords have a range of (-1, 1) on each axis.
4297 outW = 1.0f / outW;
4298 outX *= outW;
4299 outY *= -outW;
4300 outZ *= outW;
4301 // Perform the viewport transform for x and y (convert normalized device coords to viewport coords).
4302 // Viewport coords have a range of (0, Width) for x and (0, Height) for y.
4303 outX = (outX * camera->viewportW + camera->viewportW) * 0.5;
4304 outX += camera->viewportStartX;
4305 outY = (outY * camera->viewportH + camera->viewportH) * 0.5;
4306 outY += camera->viewportStartY;
4307 // Convert depth from (-1, 1) to (0, 1).
4308 outZ = (outZ + 1.0f) * 0.5;
4309 // Write out the calculated x and y values.
4310 *screenX = (s32)outX;
4311 *screenY = (s32)outY;
4312 // If a depth query wasn't requested, simply check if the point is within the view frustum.
4313 if (depthQueryID < 0) {
4314 if (outZ > 0.0f) {
4315 return false;
4316 } else {
4317 return true;
4318 }
4319 }
4320 if (outX >= 0.0f && outY >= 0.0f && outX < 320.0f && outY < 240.0f) {
4322 // Load a 4x1 pixel tile of the depth buffer
4324 (s32) outX, 0, (s32) outX + 3, 0,
4325 0,
4327 9, G_TX_NOMASK,
4330 // Set the current color image to the buffer where copied depth values are stored.
4333 // Set up 1 cycle mode and all other relevant othermode params.
4334 // One cycle mode must be used here because only one pixel is copied, and copy mode only supports multiples of 4 pixels.
4340 gSPTexture(gMainGfxPos++, 0xFFFF, 0xFFFF, 0, G_TX_RENDERTILE, G_ON);
4344 // Adjust the scissor to only draw to the specified pixel.
4345 gDPSetScissor(gMainGfxPos++, G_SC_NON_INTERLACE, depthQueryID, 0, depthQueryID + 1, 1);
4346 // Draw a texrect to copy one pixel of the loaded depth tile to the output buffer.
4347 gSPTextureRectangle(gMainGfxPos++, depthQueryID << 2, 0 << 2, 4 << 2, 1 << 2, G_TX_RENDERTILE, (s32) outX << 5, 0, 1 << 10, 1 << 10);
4348 // Sync and swap the color image back to the current framebuffer.
4352 // Reconfigure the frame's normal scissor.
4353 gDPSetScissor(gMainGfxPos++, G_SC_NON_INTERLACE, camera->viewportStartX, camera->viewportStartY, camera->viewportStartX + camera->viewportW, camera->viewportStartY + camera->viewportH);
4354
4355 // The following code will use last frame's depth value, since the copy that was just written won't be executed until the current frame is drawn.
4356
4357 // Extract the exponent and mantissa from the depth buffer value.
4360 // Convert the exponent and mantissa into a fixed-point value.
4363 // Remove the 3 fractional bits of precision.
4365 // Convert the calculated screen depth into viewport depth.
4367 if (decodedDepth < scaledDepth) {
4368 return false;
4369 }
4370 }
4371 return outZ > 0.0f;
4372}
4373
4374// Checks if a point is visible on screen.
4375// If `depthQueryID` is nonnegative, the depth buffer is checked to see if the point is occluded by geometry.
4376// Otherwise, the occlusion check is skipped.
4377// `depthQueryID` must be between 0 and the size of `DepthCopyBuffer` minus 1.
4378// Every nonnegative value of `depthQueryID` must be unique within a frame, otherwise the result will corrupt the data
4379// of the previous query that shared the same ID.
4380// Occlusion visibility checks are always one frame out of date, as they reference the previous frame's depth buffer.
4383 f32 outX;
4384 f32 outY;
4385 f32 outZ;
4386 f32 outW;
4387
4393
4394 // If an invalid depth query id was provided, return false.
4395 if (depthQueryID >= ARRAY_COUNT(DepthCopyBuffer)) {
4396 return false;
4397 }
4398 // Transform the point into clip space.
4399 transform_point(camera->mtxPerspective, x, y, z, 1.0f, &outX, &outY, &outZ, &outW);
4400 if (outW == 0.0f) {
4401 *screenX = 0.0f;
4402 *screenY = 0.0f;
4403 return true;
4404 }
4405 // Perform the perspective divide (divide xyz by w) to convert to normalized device coords.
4406 // Normalized device coords have a range of (-1, 1) on each axis.
4407 outW = 1.0f / outW;
4408 outX *= outW;
4409 outY *= -outW;
4410 outZ *= outW;
4411 // Perform the viewport transform for x and y (convert normalized device coords to viewport coords).
4412 // Viewport coords have a range of (0, Width) for x and (0, Height) for y.
4413 outX = (outX * camera->viewportW + camera->viewportW) * 0.5;
4414 outX += camera->viewportStartX;
4415 outY = (outY * camera->viewportH + camera->viewportH) * 0.5;
4416 outY += camera->viewportStartY;
4417 // Convert depth from (-1, 1) to (0, 1).
4418 outZ = (outZ + 1.0f) * 0.5;
4419 // Write out the calculated x and y values.
4420 *screenX = outX;
4421 *screenY = outY;
4422 // If a depth query wasn't requested, simply check if the point is within the view frustum.
4423 if (depthQueryID < 0) {
4424 return outZ > 0.0f;
4425 }
4426 if (outX >= 0.0f && outY >= 0.0f && outX < 320.0f && outY < 240.0f) {
4428 // Load a 4x1 pixel tile of the depth buffer
4430 (s32) outX, 0, (s32) outX + 3, 0,
4431 0,
4433 9, G_TX_NOMASK,
4436 // Set the current color image to the buffer where copied depth values are stored.
4439 // Set up 1 cycle mode and all other relevant othermode params.
4440 // One cycle mode must be used here because only one pixel is copied, and copy mode only supports multiples of 4 pixels.
4446 gSPTexture(gMainGfxPos++, 0xFFFF, 0xFFFF, 0, G_TX_RENDERTILE, G_ON);
4450 // Adjust the scissor to only draw to the specified pixel.
4451 gDPSetScissor(gMainGfxPos++, G_SC_NON_INTERLACE, depthQueryID, 0, depthQueryID + 1, 1);
4452 // Draw a texrect to copy one pixel of the loaded depth tile to the output buffer.
4453 gSPTextureRectangle(gMainGfxPos++, depthQueryID << 2, 0 << 2, (depthQueryID + 1) << 2, 1 << 2, G_TX_RENDERTILE, (s32) outX << 5, 0, 1 << 10, 1 << 10);
4454 // Sync and swap the color image back to the current framebuffer.
4458 // Reconfigure the frame's normal scissor.
4459 gDPSetScissor(gMainGfxPos++, G_SC_NON_INTERLACE, camera->viewportStartX, camera->viewportStartY, camera->viewportStartX + camera->viewportW, camera->viewportStartY + camera->viewportH);
4460
4461 // The following code will use last frame's depth value, since the copy that was just written won't be executed until the current frame is drawn.
4462
4463 // Extract the exponent and mantissa from the depth buffer value.
4466 // Convert the exponent and mantissa into a fixed-point value.
4469 // Remove the 3 fractional bits of precision.
4471 // Convert the calculated screen depth into viewport depth.
4473 if (decodedDepth < scaledDepth) {
4474 return false;
4475 }
4476 }
4477 return outZ > 0.0f;
4478}
4479
4482 Model copied = *model;
4483 Gfx* oldGfxPos;
4484 s32 flag;
4485
4486 if (*arg0 == gMainGfxPos) {
4487 flag = 1;
4488 }
4489
4491 gMainGfxPos = *arg0;
4492
4495
4496 *arg0 = gMainGfxPos;
4497
4498 if (flag == 0) {
4500 }
4501}
4502
4504 u32 offset = TextureHeapPos - TextureHeapBase + 0x3F;
4505
4506 offset = (offset >> 6) << 6;
4507
4509 return nullptr;
4510 } else {
4511 return TextureHeapBase + offset;
4512 }
4513}
4514
4517 Model* model;
4518 s32 type = tintType; // weirdness here and the next line needed to match
4519 s32 i = tintType;
4520
4521 for (i = 0; i < ARRAY_COUNT(*modelList); i++) {
4522 model = (*modelList)[i];
4523
4524 if (model != nullptr) {
4526 }
4527 }
4528}
4529
4531 s32 i;
4532
4533 for (i = 0; i < ARRAY_COUNT(ClearRenderTaskLists); i++) {
4535 }
4536
4537 for (i = 0; i < ARRAY_COUNT(RenderTaskCount); i++) {
4538 RenderTaskCount[i] = 0;
4539 }
4540}
4541
4543 s32 dist = RenderTaskBasePriorities[task->renderMode] - task->dist;
4545 if (dist >= 3000000) listIdx = RENDER_TASK_LIST_FAR;
4546 else if (dist < 800000) listIdx = RENDER_TASK_LIST_NEAR;
4547
4549
4551
4553
4554 ret->renderMode = RENDER_TASK_FLAG_ENABLED;
4555 if (task->renderMode == RENDER_MODE_CLOUD_NO_ZCMP) {
4556 ret->renderMode |= RENDER_TASK_FLAG_20;
4557 }
4558
4559 ret->appendGfxArg = task->appendGfxArg;
4560 ret->appendGfx = task->appendGfx;
4561 ret->dist = dist;
4562
4563 return ret;
4564}
4565
4567 s32 i, j;
4569 s32* sorted;
4573 void (*appendGfx)(void*);
4574 s32 tmp;
4575
4576 for (s32 j = 0; j < ARRAY_COUNT(RenderTaskCount); j++) {
4577 for (i = 0; i < RenderTaskCount[j]; i++) {
4578 sorteds[j][i] = i;
4579 }
4580 }
4581
4582 // sort in ascending order of dist
4585#define LESS(i, j) taskList[sorted[i]].dist < taskList[sorted[j]].dist
4586#define SWAP(i, j) tmp = sorted[i], sorted[i] = sorted[j], sorted[j] = tmp
4588
4589 // tasks with dist >= 3M sort in descending order
4592#define LESS(i, j) taskList[sorted[i]].dist > taskList[sorted[j]].dist
4594
4595 // tasks with dist <= 800k sort in descending order
4599
4602 Mtx* dispMtx;
4603 Gfx* savedGfxPos = nullptr;
4604
4605 guScaleF(mtxFlipY, 1.0f, -1.0f, 1.0f);
4608 for (j = 0; j < NUM_RENDER_TASK_LISTS; j++) {
4609 for (i = 0; i < RenderTaskCount[j]; i++) {
4610 task = &RenderTaskLists[j][sorteds[j][i]];
4611 appendGfx = task->appendGfx;
4612
4613 if (task->renderMode & RENDER_TASK_FLAG_REFLECT_FLOOR) {
4615 }
4616
4617 appendGfx(task->appendGfxArg);
4618
4619 if (task->renderMode & RENDER_TASK_FLAG_REFLECT_FLOOR) {
4626 }
4627 }
4628 }
4629 } else {
4630 for (j = 0; j < NUM_RENDER_TASK_LISTS; j++) {
4631 for (i = 0; i < RenderTaskCount[j]; i++) {
4632 task = &RenderTaskLists[j][sorteds[j][i]];
4633 appendGfx = task->appendGfx;
4634 appendGfx(task->appendGfxArg);
4635 }
4636 }
4637 }
4638
4642}
BSS s32 PopupMenu_SelectedIndex
u16 * nuGfxCfb_ptr
Definition cam_main.c:13
Mtx matrixStack[0x200]
#define PAL_PTR
#define IMG_PTR
s32 b32
f32 Matrix4f[4][4]
s8 flags
Definition demo_api.c:15
#define transform_point
#define is_point_visible
#define queue_render_task
#define guMtxF2L
#define guMtxCatF
#define mdl_draw_hidden_panel_surface
#define mdl_get_shroud_tint_params
#define guScaleF
#define ASSERT(condition)
@ TEX_PANNER_0
Definition enums.h:3983
@ ENV_TINT_SHROUD
Definition enums.h:3972
@ ENV_TINT_DEPTH
Definition enums.h:3974
@ ENV_TINT_REMAP
Definition enums.h:3978
@ ENV_TINT_NONE
Definition enums.h:3970
@ TRANSFORM_GROUP_FLAG_INACTIVE
Definition enums.h:4667
@ TRANSFORM_GROUP_FLAG_HIDDEN
Definition enums.h:4666
@ TRANSFORM_GROUP_FLAG_VALID
Definition enums.h:4665
@ TRANSFORM_GROUP_FLAG_MATRIX_DIRTY
Definition enums.h:4669
@ TRANSFORM_GROUP_FLAG_IGNORE_MATRIX
Definition enums.h:4670
@ RENDER_MODE_IDX_1D
Definition enums.h:3257
@ RENDER_MODE_IDX_14
Definition enums.h:3248
@ RENDER_MODE_IDX_29
Definition enums.h:3270
@ RENDER_MODE_IDX_18
Definition enums.h:3252
@ RENDER_MODE_IDX_2B
Definition enums.h:3272
@ RENDER_MODE_IDX_0B
Definition enums.h:3238
@ RENDER_MODE_IDX_3A
Definition enums.h:3288
@ RENDER_MODE_IDX_1B
Definition enums.h:3255
@ RENDER_MODE_IDX_26
Definition enums.h:3267
@ RENDER_MODE_IDX_16
Definition enums.h:3250
@ RENDER_MODE_IDX_33
Definition enums.h:3280
@ RENDER_MODE_IDX_15
Definition enums.h:3249
@ RENDER_MODE_IDX_39
Definition enums.h:3287
@ RENDER_MODE_IDX_34
Definition enums.h:3281
@ RENDER_MODE_IDX_07
Definition enums.h:3234
@ RENDER_MODE_IDX_31
Definition enums.h:3278
@ RENDER_MODE_IDX_09
Definition enums.h:3236
@ RENDER_MODE_IDX_2A
Definition enums.h:3271
@ RENDER_MODE_IDX_02
Definition enums.h:3229
@ RENDER_MODE_IDX_27
Definition enums.h:3268
@ RENDER_MODE_IDX_3C
Definition enums.h:3290
@ RENDER_MODE_IDX_13
Definition enums.h:3247
@ RENDER_MODE_IDX_1F
Definition enums.h:3260
@ RENDER_MODE_IDX_2D
Definition enums.h:3274
@ RENDER_MODE_IDX_0C
Definition enums.h:3239
@ RENDER_MODE_IDX_12
Definition enums.h:3246
@ RENDER_MODE_IDX_11
Definition enums.h:3245
@ RENDER_MODE_IDX_1E
Definition enums.h:3258
@ RENDER_MODE_IDX_3B
Definition enums.h:3289
@ RENDER_MODE_IDX_38
Definition enums.h:3286
@ RENDER_MODE_IDX_22
Definition enums.h:3263
@ RENDER_MODE_IDX_25
Definition enums.h:3266
@ RENDER_MODE_IDX_23
Definition enums.h:3264
@ RENDER_MODE_IDX_19
Definition enums.h:3253
@ RENDER_MODE_IDX_32
Definition enums.h:3279
@ RENDER_MODE_IDX_30
Definition enums.h:3277
@ RENDER_MODE_IDX_0F
Definition enums.h:3242
@ RENDER_MODE_IDX_06
Definition enums.h:3233
@ RENDER_MODE_IDX_28
Definition enums.h:3269
@ RENDER_MODE_IDX_20
Definition enums.h:3261
@ RENDER_MODE_IDX_1C
Definition enums.h:3256
@ RENDER_MODE_IDX_10
Definition enums.h:3244
@ RENDER_MODE_IDX_2C
Definition enums.h:3273
@ RENDER_MODE_IDX_37
Definition enums.h:3285
@ RENDER_MODE_IDX_2F
Definition enums.h:3276
@ RENDER_MODE_IDX_01
Definition enums.h:3228
@ RENDER_MODE_IDX_1A
Definition enums.h:3254
@ RENDER_MODE_IDX_35
Definition enums.h:3282
@ RENDER_MODE_IDX_08
Definition enums.h:3235
@ RENDER_MODE_IDX_0D
Definition enums.h:3240
@ RENDER_MODE_IDX_36
Definition enums.h:3283
@ RENDER_MODE_IDX_2E
Definition enums.h:3275
@ RENDER_MODE_IDX_04
Definition enums.h:3231
@ RENDER_MODE_IDX_17
Definition enums.h:3251
@ RENDER_MODE_IDX_0A
Definition enums.h:3237
@ RENDER_MODE_IDX_0E
Definition enums.h:3241
@ RENDER_MODE_IDX_21
Definition enums.h:3262
@ RENDER_MODE_IDX_05
Definition enums.h:3232
@ RENDER_MODE_IDX_03
Definition enums.h:3230
@ RENDER_MODE_IDX_00
Definition enums.h:3227
@ RENDER_MODE_IDX_24
Definition enums.h:3265
@ MODEL_FLAG_DO_BOUNDS_CULLING
Definition enums.h:3951
@ MODEL_FLAG_IGNORE_MATRIX
Definition enums.h:3955
@ MODEL_FLAG_HAS_LOCAL_VERTEX_COPY
Definition enums.h:3949
@ MODEL_FLAG_INACTIVE
Definition enums.h:3944
@ MODEL_FLAG_HIDDEN
Definition enums.h:3943
@ MODEL_FLAG_VALID
Definition enums.h:3942
@ MODEL_FLAG_BILLBOARD
Definition enums.h:3950
@ MODEL_FLAG_20
Definition enums.h:3947
@ MODEL_FLAG_USES_CUSTOM_GFX
Definition enums.h:3946
@ MODEL_FLAG_TRANSFORM_GROUP_MEMBER
Definition enums.h:3945
@ MODEL_FLAG_MATRIX_DIRTY
Definition enums.h:3954
@ MODEL_FLAG_HAS_TEX_PANNER
Definition enums.h:3953
@ MODEL_FLAG_IGNORE_FOG
Definition enums.h:3948
@ RENDER_TASK_FLAG_20
Definition enums.h:3353
@ RENDER_TASK_FLAG_REFLECT_FLOOR
Definition enums.h:3352
@ RENDER_TASK_FLAG_ENABLED
Definition enums.h:3351
@ MODEL_GROUP_OTHERS_VISIBLE
Definition enums.h:3964
@ MODEL_GROUP_HIDDEN
Definition enums.h:3961
@ CONTEXT_WORLD
Definition enums.h:3562
@ RENDER_MODE_ALPHATEST_ONESIDED
Definition enums.h:3312
@ RENDER_MODE_SURFACE_OPA_NO_ZB
Definition enums.h:3301
@ RENDER_MODE_24_UNUSED
Definition enums.h:3335
@ RENDER_MODE_1D_UNUSED
Definition enums.h:3328
@ RENDER_MODE_1F_UNUSED
Definition enums.h:3330
@ RENDER_MODE_DECAL_OPA
Definition enums.h:3302
@ RENDER_MODE_0E_UNUSED
Definition enums.h:3311
@ RENDER_MODE_SURFACE_XLU_LAYER3
Definition enums.h:3333
@ RENDER_MODE_21_UNUSED
Definition enums.h:3332
@ RENDER_MODE_DECAL_XLU_NO_AA
Definition enums.h:3327
@ RENDER_MODE_SURFACE_XLU_LAYER2
Definition enums.h:3321
@ RENDER_MODE_SURFACE_XLU_NO_AA
Definition enums.h:3318
@ RENDER_MODE_SURF_SOLID_AA_ZB_LAYER0
Definition enums.h:3297
@ RENDER_MODE_INTERSECTING_XLU
Definition enums.h:3337
@ RENDER_MODE_PASS_THROUGH
Definition enums.h:3340
@ RENDER_MODE_DECAL_XLU
Definition enums.h:3325
@ RENDER_MODE_SHADOW
Definition enums.h:3331
@ RENDER_MODE_02_UNUSED
Definition enums.h:3299
@ RENDER_MODE_SURFACE_OPA_NO_AA
Definition enums.h:3300
@ RENDER_MODE_SURFACE_XLU_NO_ZB
Definition enums.h:3319
@ RENDER_MODE_1B_UNUSED
Definition enums.h:3326
@ RENDER_MODE_DECAL_OPA_NO_AA
Definition enums.h:3304
@ RENDER_MODE_0A_UNUSED
Definition enums.h:3307
@ RENDER_MODE_SURFACE_XLU_NO_ZB_BEHIND
Definition enums.h:3344
@ RENDER_MODE_SURFACE_OPA_NO_ZB_BEHIND
Definition enums.h:3342
@ RENDER_MODE_25_UNUSED
Definition enums.h:3336
@ RENDER_MODE_SURFACE_XLU_ZB_ZUPD
Definition enums.h:3320
@ RENDER_MODE_23_UNUSED
Definition enums.h:3334
@ RENDER_MODE_DECAL_XLU_AHEAD
Definition enums.h:3329
@ RENDER_MODE_18_UNUSED
Definition enums.h:3323
@ RENDER_MODE_0B_UNUSED
Definition enums.h:3308
@ RENDER_MODE_ALPHATEST_NO_ZB_BEHIND
Definition enums.h:3343
@ RENDER_MODE_INTERSECTING_OPA
Definition enums.h:3306
@ RENDER_MODE_ALPHATEST
Definition enums.h:3310
@ RENDER_MODE_12_UNUSED
Definition enums.h:3317
@ RENDER_MODE_08_UNUSED
Definition enums.h:3305
@ RENDER_MODE_SURFACE_OPA
Definition enums.h:3298
@ RENDER_MODE_CLOUD_NO_ZB
Definition enums.h:3347
@ RENDER_MODE_CLOUD
Definition enums.h:3346
@ RENDER_MODE_06_UNUSED
Definition enums.h:3303
@ RENDER_MODE_19_UNUSED
Definition enums.h:3324
@ RENDER_MODES_LAST_OPAQUE
Definition enums.h:3314
@ RENDER_MODE_ALPHATEST_NO_ZB
Definition enums.h:3313
@ RENDER_MODE_SURFACE_XLU_LAYER1
Definition enums.h:3316
@ RENDER_MODE_0C_UNUSED
Definition enums.h:3309
@ RENDER_MODE_27_UNUSED
Definition enums.h:3338
@ RENDER_MODE_SURFACE_XLU_AA_ZB_ZUPD
Definition enums.h:3341
@ RENDER_MODE_CLOUD_NO_ZCMP
Definition enums.h:3345
@ RENDER_MODE_17_UNUSED
Definition enums.h:3322
@ CUSTOM_GFX_0
Definition enums.h:4006
@ CUSTOM_GFX_NONE
Definition enums.h:4005
@ GLOBAL_OVERRIDES_ENABLE_FLOOR_REFLECTION
Definition enums.h:3911
u32 dma_copy(Addr romStart, Addr romEnd, void *vramDest)
Definition 43F0.c:442
void * heap_malloc(s32 size)
Definition heap.c:34
#define gDPScrollMultiTile(pkt, timg, tmem, rtile, fmt, siz, width, height, uls, ult, lrs, lrt, pal, cms, cmt, masks, maskt, shifts, shiftt, scrolls, scrollt)
Definition gbi_custom.h:116
#define gDPScrollTextureBlockHalfHeight_4b(pkt, timg, fmt, width, height, pal, cms, cmt, masks, maskt, shifts, shiftt, scrolls, scrollt, shifts2, shiftt2)
Definition gbi_custom.h:173
#define gDPScrollTextureBlockHalfHeight(pkt, timg, fmt, siz, width, height, pal, cms, cmt, masks, maskt, shifts, shiftt, scrolls, scrollt, shifts2, shiftt2)
Definition gbi_custom.h:143
#define gDPScrollMultiTile_4b(pkt, timg, tmem, rtile, fmt, width, height, uls, ult, lrs, lrt, pal, cms, cmt, masks, maskt, shifts, shiftt, scrolls, scrollt)
Definition gbi_custom.h:88
int printf(const char *restrict fmt,...)
Definition is_debug.c:25
u16 * nuGfxZBuffer
Definition main.c:46
BSS s32 TreeIterPos
Definition model.c:1336
Gfx Gfx_RM3_SURFACE_OPA[]
Definition model.c:1067
Gfx Gfx_RM2_DECAL_OPA[]
Definition model.c:886
#define DEPTH_MANTISSA_SHIFT
Definition model.c:610
u8 RemapTintMinG
Definition model.c:588
Gfx * mdl_get_copied_gfx(s32 copyIndex)
Definition model.c:4080
void func_8011B1D8(ModelNode *node)
Definition model.c:3454
Gfx Gfx_RM3_DECAL_XLU[]
Definition model.c:1117
void render_transform_group(void *group)
Definition model.c:3033
ModelCustomGfxList * gCurrentCustomModelGfxPtr
Definition model.c:1310
void clone_model(u16 srcModelID, u16 newModelID)
Definition model.c:3617
Gfx Gfx_RM3_DECAL_OPA[]
Definition model.c:1077
s32 DepthTintEnd
Definition model.c:582
void mdl_set_shroud_tint_params(u8 r, u8 g, u8 b, u8 a)
Definition model.c:3902
Gfx Gfx_RM2_INTERSECTING_OPA_NO_AA[]
Definition model.c:962
BSS s32 texPannerMainV[MAX_TEX_PANNERS]
Definition model.c:1341
s32 is_model_center_visible(u16 modelID, s32 depthQueryID, f32 *screenX, f32 *screenY)
Definition model.c:4270
BSS s8 bBackgroundTintMode
Definition model.c:1335
void enable_transform_group(u16 modelID)
Definition model.c:3583
void mdl_local_gfx_copy_vertices(Vtx *src, s32 num, Vtx *dest)
Definition model.c:4027
s32 get_transform_group_index(s32 modelID)
Definition model.c:3414
Gfx Gfx_RM2_DECAL_XLU_NO_AA[]
Definition model.c:989
Gfx Gfx_RM3_SURFACE_XLU_NO_ZB[]
Definition model.c:1230
Gfx Gfx_RM2_SURFACE_XLU_NO_ZB[]
Definition model.c:1036
s32 get_model_list_index_from_tree_index(s32 treeIndex)
Definition model.c:3393
Gfx Gfx_RM2_INTERSECTING_XLU[]
Definition model.c:932
s32 endDistance
Definition model.c:115
Gfx Gfx_RM2_INTERSECTING_OPA[]
Definition model.c:895
void render_transform_group_node(ModelNode *node)
Definition model.c:2984
BSS ModelTreeInfoList wModelTreeNodeInfo
Definition model.c:1331
ModelNode ** gCurrentModelTreeRoot
Definition model.c:1308
Gfx Gfx_RM1_CLOUD_NO_ZB[]
Definition model.c:865
void func_80117D00(Model *model)
Definition model.c:2939
s32 startDistance
Definition model.c:114
void init_model_data(void)
Definition model.c:2430
BSS s32 texPannerAuxV[MAX_TEX_PANNERS]
Definition model.c:1343
void clear_render_tasks(void)
Definition model.c:4530
Gfx Gfx_RM3_INTERSECTING_OPA_NO_AA[]
Definition model.c:1157
void clear_model_data(void)
Definition model.c:2363
Gfx Gfx_RM1_PASS_THROUGH[]
Definition model.c:779
Gfx Gfx_RM1_INTERSECTING_OPA_NO_AA[]
Definition model.c:736
BSS s8 wBackgroundTintMode
Definition model.c:1334
#define BATTLE_TEXTURE_MEMORY_SIZE
Definition model.c:103
u8 DepthTintBaseR
Definition model.c:573
void mdl_project_tex_coords(s32 modelID, Gfx *outGfx, Matrix4f arg2, Vtx *arg3)
Definition model.c:4093
void set_tex_panner(Model *model, s32 texPannerID)
Definition model.c:3808
void mdl_reset_transform_flags(void)
Definition model.c:3752
Gfx Gfx_RM1_SURFACE_XLU[]
Definition model.c:686
void set_world_fog_color(s32 r, s32 g, s32 b, s32 a)
Definition model.c:3785
Gfx Gfx_RM1_DECAL_XLU[]
Definition model.c:696
BSS ModelNode * bModelTreeRoot
Definition model.c:1330
Gfx Gfx_RM2_SURFACE_OPA_NO_ZB[]
Definition model.c:1018
void mdl_get_vertex_count(Gfx *gfx, s32 *numVertices, Vtx **baseVtx, s32 *gfxCount, Vtx *baseAddr)
Definition model.c:3959
void * TextureHeapBase
Definition model.c:566
Gfx Gfx_RM2_DECAL_OPA_NO_AA[]
Definition model.c:953
Gfx Gfx_RM1_SURFACE_XLU_AA_ZB_ZUPD[]
Definition model.c:787
TextureHandle TextureHandles[128]
Definition model.c:1355
void mdl_calculate_model_sizes(void)
Definition model.c:2454
Model * get_model_from_list_index(s32 listIndex)
Definition model.c:3312
#define WORLD_TEXTURE_MEMORY_SIZE
Definition model.c:102
Gfx Gfx_RM3_PASS_THROUGH[]
Definition model.c:1195
#define DEPTH_MANTISSA_MASK
Definition model.c:606
u8 RemapTintMaxR
Definition model.c:584
Gfx Gfx_RM2_SURFACE_XLU[]
Definition model.c:914
Gfx Gfx_RM3_SURFACE_OPA_NO_ZB[]
Definition model.c:1212
BSS ModelTransformGroupList bTransformGroups
Definition model.c:1318
u8 RemapTintMaxG
Definition model.c:585
Gfx Gfx_RM2_SURFACE_XLU_NO_AA[]
Definition model.c:980
#define SWAP(i, j)
Gfx Gfx_RM3_DECAL_OPA_NO_AA[]
Definition model.c:1148
void disable_world_fog(void)
Definition model.c:3776
BSS ModelTreeInfoList bModelTreeNodeInfo
Definition model.c:1332
Gfx Gfx_RM2_ALPHATEST_NO_ZB[]
Definition model.c:1027
Gfx Gfx_RM2_SURFACE_OPA[]
Definition model.c:877
Gfx Gfx_RM2_ALPHATEST[]
Definition model.c:905
BSS ModelLocalVertexCopyList bModelLocalVtxBuffers
Definition model.c:1326
void mdl_set_all_tint_type(s32 tintType)
Definition model.c:4515
u8 DepthTintColA
Definition model.c:580
void load_data_for_models(ModelNode *rootModel, s32 texturesOffset, s32 size)
Definition model.c:3316
void load_next_model_textures(ModelNode *model, s32 romOffset, s32 texSize)
Definition model.c:2298
void load_model_transforms(ModelNode *model, ModelNode *parent, Matrix4f mdlTxMtx, s32 treeDepth)
Definition model.c:3333
BSS FogSettings bFogSettings
Definition model.c:1338
s32 is_world_fog_enabled(void)
Definition model.c:3792
Gfx Gfx_RM3_CLOUD[]
Definition model.c:1239
BSS s32 RenderTaskCount[3]
Definition model.c:1353
void set_custom_gfx_builders(s32 customGfxIndex, ModelCustomGfxBuilderFunc pre, ModelCustomGfxBuilderFunc post)
Definition model.c:3845
BSS u16 mtg_MaxChild
Definition model.c:1349
@ AUX_COMBINE_SUB_1
Definition model.c:34
@ AUX_COMBINE_SUB_2
Definition model.c:35
@ AUX_COMBINE_SUB_COUNT
Definition model.c:36
@ AUX_COMBINE_SUB_0
Definition model.c:33
u8 DepthTintBaseG
Definition model.c:574
BSS ModelNode * wModelTreeRoot
Definition model.c:1329
void mdl_get_remap_tint_params(u8 *primR, u8 *primG, u8 *primB, u8 *envR, u8 *envG, u8 *envB)
Definition model.c:3950
void disable_transform_group(u16 modelID)
Definition model.c:3600
BSS ModelNode * mtg_FoundModelNode
Definition model.c:1347
Gfx SolidCombineModes[][5]
Definition model.c:245
u8 * gBackgroundTintModePtr
Definition model.c:105
void mdl_make_transform_group(u16 modelID)
Definition model.c:3510
void load_texture_variants(u32 romOffset, s32 textureID, s32 baseOffset, s32 size)
Definition model.c:2172
BSS ModelList wModelList
Definition model.c:1314
void appendGfx_model_group(void *model)
Definition model.c:2924
u8 DepthTintColR
Definition model.c:577
void set_custom_gfx(s32 customGfxIndex, Gfx *pre, Gfx *post)
Definition model.c:3840
void * mdl_get_next_texture_address(s32 size)
Definition model.c:4503
s32 gLastRenderTaskCount
Definition model.c:636
Gfx Gfx_RM2_CLOUD[]
Definition model.c:1045
Gfx Gfx_RM3_ALPHATEST_ONESIDED[]
Definition model.c:1166
Gfx Gfx_RM2_PASS_THROUGH[]
Definition model.c:1001
BSS s32 RenderTaskListIdx
Definition model.c:1352
BSS ModelCustomGfxBuilderList bCustomModelGfxBuilders
Definition model.c:1324
Gfx Gfx_RM1_SURFACE_OPA_NO_ZB[]
Definition model.c:800
s32 mdl_get_child_count(ModelNode *model)
Definition model.c:2345
void build_custom_gfx(void)
Definition model.c:3850
BSS RenderTask * RenderTaskLists[3]
Definition model.c:1351
@ TEX_COMBINE_AUX_IND_2
Definition model.c:64
@ TEX_COMBINE_A
Definition model.c:74
@ TEX_COMBINE_AUX_IND_1
Definition model.c:63
@ TEX_COMBINE_AUX_IND_0
Definition model.c:62
@ TEX_COMBINE_NOTEX
Definition model.c:43
@ TEX_COMBINE_4
Definition model.c:68
@ TEX_COMBINE_8
Definition model.c:72
@ TEX_COMBINE_AUX_SHARED_1
Definition model.c:57
@ TEX_COMBINE_5
Definition model.c:69
@ TEX_COMBINE_MAIN_ONLY_2
Definition model.c:48
@ TEX_COMBINE_MIPMAPS_1
Definition model.c:52
@ TEX_COMBINE_9
Definition model.c:73
@ TEX_COMBINE_7
Definition model.c:71
@ TEX_COMBINE_MIPMAPS_2
Definition model.c:53
@ TEX_COMBINE_MAIN_ONLY_0
Definition model.c:46
@ TEX_COMBINE_MAIN_ONLY_1
Definition model.c:47
@ TEX_COMBINE_AUX_SHARED_0
Definition model.c:56
@ TEX_COMBINE_AUX_SHARED_2
Definition model.c:58
@ TEX_COMBINE_3
Definition model.c:67
@ TEX_COMBINE_MIPMAPS_0
Definition model.c:51
@ TEX_COMBINE_6
Definition model.c:70
DepthFloatFactors DepthFloatLookupTable[]
Definition model.c:619
void load_texture_by_name(ModelNodeProperty *propertyName, s32 romOffset, s32 size)
Definition model.c:2046
BSS s32 texPannerAuxU[MAX_TEX_PANNERS]
Definition model.c:1342
Gfx Gfx_RM1_DECAL_OPA[]
Definition model.c:654
u8 RemapTintMinB
Definition model.c:589
ModelCustomGfxBuilderList * gCurrentCustomModelGfxBuildersPtr
Definition model.c:1307
void enable_world_fog(void)
Definition model.c:3772
Gfx Gfx_RM2_SURFACE_OPA_NO_AA[]
Definition model.c:944
Gfx Gfx_RM3_SURFACE_OPA_NO_AA[]
Definition model.c:1139
void mdl_group_set_custom_gfx(u16 groupModelID, s32 customGfxIndex, s32 tintType, b32 invertSelection)
Definition model.c:3691
void mdl_set_remap_tint_params(u8 maxR, u8 maxG, u8 maxB, u8 minR, u8 minG, u8 minB)
Definition model.c:3941
ModelTransformGroupList * gCurrentTransformGroups
Definition model.c:1309
void set_mdl_custom_gfx_set(Model *model, s32 customGfxIndex, u32 tintType)
Definition model.c:3828
Gfx Gfx_RM2_SURFACE_XLU_AA_ZB_ZUPD[]
Definition model.c:1009
s32 is_identity_fixed_mtx(Mtx *mtx)
Definition model.c:3882
void mdl_get_depth_tint_params(u8 *primR, u8 *primG, u8 *primB, u8 *primA, u8 *fogR, u8 *fogG, u8 *fogB, s32 *fogStart, s32 *fogEnd)
Definition model.c:3928
Gfx Gfx_RM3_SURFACE_XLU_NO_AA[]
Definition model.c:1174
@ TINT_COMBINE_DEPTH
Definition model.c:81
@ TINT_COMBINE_REMAP
Definition model.c:82
@ TINT_COMBINE_SHROUD
Definition model.c:80
@ TINT_COMBINE_FOG
Definition model.c:79
@ TINT_COMBINE_NONE
Definition model.c:78
Gfx Gfx_RM1_ALPHATEST[]
Definition model.c:676
void set_aux_pan_v(s32 texPannerID, s32 value)
Definition model.c:3824
s32 DepthTintStart
Definition model.c:581
void mdl_make_local_vertex_copy(s32 copyIndex, u16 modelID, s32 isMakingCopy)
Definition model.c:4035
void set_world_fog_dist(s32 start, s32 end)
Definition model.c:3780
Addr BattleEntityHeapBottom
void set_main_pan_u(s32 texPannerID, s32 value)
Definition model.c:3812
Gfx Gfx_RM1_INTERSECTING_XLU[]
Definition model.c:706
Gfx Gfx_RM2_CLOUD_NO_ZB[]
Definition model.c:1054
Gfx Gfx_RM1_SURFACE_OPA[]
Definition model.c:643
Gfx Gfx_RM3_DECAL_XLU_NO_AA[]
Definition model.c:1183
Gfx Gfx_RM3_INTERSECTING_XLU[]
Definition model.c:1127
Gfx Gfx_RM1_CLOUD[]
Definition model.c:856
s32 enabled
Definition model.c:112
BSS FogSettings * gFogSettings
Definition model.c:1339
void mdl_create_model(ModelBlueprint *bp, s32 unused)
Definition model.c:2471
u8 RemapTintMaxB
Definition model.c:586
Gfx Gfx_RM3_INTERSECTING_OPA[]
Definition model.c:1087
Gfx Gfx_RM1_SURFACE_XLU_ZB_ZUPD[]
Definition model.c:830
ModelTreeInfoList * gCurrentModelTreeNodeInfo
Definition model.c:107
Gfx Gfx_RM1_DECAL_OPA_NO_AA[]
Definition model.c:727
u8 ShroudTintR
Definition model.c:569
void mdl_load_all_textures(ModelNode *rootModel, s32 romOffset, s32 size)
Definition model.c:2321
void set_aux_pan_u(s32 texPannerID, s32 value)
Definition model.c:3820
BSS ModelCustomGfxList bCustomModelGfx
Definition model.c:1321
Addr TextureHeap
#define MAX_VIEWPORT_DEPTH
Definition model.c:634
Gfx Gfx_RM2_ALPHATEST_ONESIDED[]
Definition model.c:972
void mdl_local_gfx_update_vtx_pointers(Gfx *nodeDlist, Vtx *baseVtx, Gfx *arg2, Vtx *arg3)
Definition model.c:4011
u8 RemapTintMinR
Definition model.c:587
Gfx * ModelRenderModes[]
Definition model.c:181
u8 DepthTintBaseA
Definition model.c:576
OPTIMIZE_OFAST void execute_render_tasks(void)
Definition model.c:4566
Gfx AlphaTestCombineModes[][5]
Definition model.c:408
Gfx Gfx_RM1_ALPHATEST_ONESIDED[]
Definition model.c:746
BSS void * TextureHeapPos
Definition model.c:1344
void get_world_fog_color(s32 *r, s32 *g, s32 *b, s32 *a)
Definition model.c:3801
BSS FogSettings wFogSettings
Definition model.c:1337
BSS ModelLocalVertexCopyList wModelLocalVtxBuffers
Definition model.c:1325
void render_models(void)
Definition model.c:2709
ModelList * gCurrentModels
Definition model.c:106
void make_texture_gfx(TextureHeader *, Gfx **, IMG_PTR raster, PAL_PTR palette, IMG_PTR auxRaster, PAL_PTR auxPalette, u8, u8, u16, u16)
Definition model.c:3052
void set_main_pan_v(s32 texPannerID, s32 value)
Definition model.c:3816
BSS u16 mtg_IterIdx
Definition model.c:1345
u8 ShroudTintAmt
Definition model.c:568
#define LESS(i, j)
Gfx Gfx_RM1_SURFACE_XLU_NO_ZB[]
Definition model.c:820
@ RENDER_TASK_LIST_FAR
Definition model.c:99
@ RENDER_TASK_LIST_NEAR
Definition model.c:97
@ RENDER_TASK_LIST_MID
Definition model.c:98
void load_texture_impl(u32 romOffset, TextureHandle *handle, TextureHeader *header, s32 mainSize, s32 mainPalSize, s32 auxSize, s32 auxPalSize)
Definition model.c:2008
Color4i color
Definition model.c:113
BSS u16 mtg_SearchModelID
Definition model.c:1346
Mtx ReferenceIdentityMtx
Definition model.c:591
u8 ShroudTintB
Definition model.c:571
BSS ModelCustomGfxBuilderList wCustomModelGfxBuilders
Definition model.c:1323
Gfx Gfx_RM3_SURFACE_XLU_AA_ZB_ZUPD[]
Definition model.c:1203
Gfx Gfx_RM1_ALPHATEST_NO_ZB[]
Definition model.c:810
Gfx Gfx_RM3_ALPHATEST[]
Definition model.c:1097
ModelNodeProperty * get_model_property(ModelNode *node, ModelPropertyKeys key)
Definition model.c:2284
void mdl_get_copied_vertices(s32 copyIndex, Vtx **firstVertex, Vtx **copiedVertices, s32 *numCopied)
Definition model.c:4071
BSS ModelList bModelList
Definition model.c:1315
void appendGfx_model(void *data)
Definition model.c:1368
Gfx Gfx_RM1_SURFACE_XLU_NO_AA[]
Definition model.c:756
void get_world_fog_distance(s32 *start, s32 *end)
Definition model.c:3796
void mdl_update_transform_matrices(void)
Definition model.c:2588
u8 DepthTintColG
Definition model.c:578
Gfx Gfx_RM1_CLOUD_NO_ZCMP[]
Definition model.c:844
BSS ModelTransformGroupList wTransformGroups
Definition model.c:1317
BSS ModelLocalVertexCopyList * gCurrentModelLocalVtxBuffers
Definition model.c:1327
Gfx Gfx_RM2_DECAL_XLU[]
Definition model.c:923
BSS s32 texPannerMainU[MAX_TEX_PANNERS]
Definition model.c:1340
#define DEPTH_EXPONENT_SHIFT
Definition model.c:609
u8 DepthTintColB
Definition model.c:579
u8 ShroudTintG
Definition model.c:570
s32 RenderTaskBasePriorities[]
Definition model.c:1256
BSS u16 mtg_MinChild
Definition model.c:1348
BSS u16 DepthCopyBuffer[16]
Definition model.c:1350
BSS ModelCustomGfxList wCustomModelGfx
Definition model.c:1320
Gfx Gfx_RM1_DECAL_XLU_NO_AA[]
Definition model.c:766
@ RENDER_CLASS_1CYC
Definition model.c:86
@ RENDER_CLASS_1CYC_SHROUD
Definition model.c:89
@ RENDER_CLASS_2CYC
Definition model.c:87
@ RENDER_CLASS_2CYC_DEPTH
Definition model.c:93
@ RENDER_CLASS_1CYC_DEPTH
Definition model.c:92
@ RENDER_CLASS_FOG
Definition model.c:88
@ RENDER_CLASS_2CYC_SHROUD
Definition model.c:90
@ RENDER_CLASS_FOG_SHROUD
Definition model.c:91
u8 DepthTintBaseB
Definition model.c:575
void mdl_group_set_visibility(u16 treeIndex, s32 flags, s32 mode)
Definition model.c:3633
Gfx Gfx_RM3_ALPHATEST_NO_ZB[]
Definition model.c:1221
Gfx Gfx_RM1_INTERSECTING_OPA[]
Definition model.c:665
Gfx Gfx_RM3_SURFACE_XLU[]
Definition model.c:1107
void get_model_center_and_size(u16 modelID, f32 *centerX, f32 *centerY, f32 *centerZ, f32 *sizeX, f32 *sizeY, f32 *sizeZ)
Definition model.c:3429
ModelTransformGroup * get_transform_group(s32 index)
Definition model.c:3449
#define TEST_POINT_VISIBILITY
Gfx Gfx_RM1_SURFACE_OPA_NO_AA[]
Definition model.c:718
@ AUX_COMBINE_0
Definition model.c:17
@ AUX_COMBINE_7
Definition model.c:24
@ AUX_COMBINE_A
Definition model.c:27
@ AUX_COMBINE_6
Definition model.c:23
@ AUX_COMBINE_1
Definition model.c:18
@ AUX_COMBINE_2
Definition model.c:19
@ AUX_COMBINE_5
Definition model.c:22
@ AUX_COMBINE_3
Definition model.c:20
@ AUX_COMBINE_8
Definition model.c:25
@ AUX_COMBINE_4
Definition model.c:21
@ AUX_COMBINE_9
Definition model.c:26
#define DEPTH_DZ_MASK
Definition model.c:607
Gfx Gfx_RM3_CLOUD_NO_ZB[]
Definition model.c:1248
void mdl_set_depth_tint_params(u8 primR, u8 primG, u8 primB, u8 primA, u8 fogR, u8 fogG, u8 fogB, s32 fogStart, s32 fogEnd)
Definition model.c:3916
ModelLocalVertexCopy * ModelLocalVertexCopyList[16]
Definition model.h:110
ModelCustomGfxBuilderFunc ModelCustomGfxBuilderList[32]
Definition model.h:139
void(* ModelCustomGfxBuilderFunc)(s32 index)
Definition model.h:136
struct ModelNode ** childList
Definition model.h:43
Gfx * displayList
Definition model.h:47
Model * ModelList[256]
Definition model.h:94
u16 flags
Definition model.h:60
Gfx * gfx
Definition model.h:120
ModelTransformGroup * ModelTransformGroupList[4]
Definition model.h:95
s32 numChildren
Definition model.h:42
u8 customGfxIndex
Definition model.h:71
ModelDisplayData * displayData
Definition model.h:53
TextureHeader header
Definition model.h:121
@ EXTRA_TILE_AUX_INDEPENDENT
Definition model.h:167
@ EXTRA_TILE_NONE
Definition model.h:164
@ EXTRA_TILE_MIPMAPS
Definition model.h:165
@ EXTRA_TILE_AUX_SAME_AS_MAIN
Definition model.h:166
@ EXTRA_TILE_4
Definition model.h:168
ModelTreeInfo ModelTreeInfoList[0x200]
Definition model.h:187
@ SHAPE_TYPE_MODEL
Definition model.h:152
@ SHAPE_TYPE_GROUP
Definition model.h:153
struct ModelGroupData * groupData
Definition model.h:56
Gfx * ModelCustomGfxList[32]
Definition model.h:138
ModelPropertyKeys
Definition model.h:141
@ MODEL_PROP_KEY_BOUNDING_BOX
Definition model.h:147
@ MODEL_PROP_KEY_SPECIAL
Definition model.h:145
@ MODEL_PROP_KEY_GROUP_INFO
Definition model.h:146
@ MODEL_PROP_KEY_TEXTURE_NAME
Definition model.h:144
@ MODEL_PROP_KEY_RENDER_MODE
Definition model.h:142
@ GROUP_TYPE_0
Definition model.h:159
Definition model.h:59
BSS RenderTask ClearRenderTaskLists[3][0x100]
#define NUM_RENDER_TASK_LISTS
#define QSORT(Q_N, Q_LESS, Q_SWAP)
Definition qsort.h:161
#define RDP_MATRIX( Ax, Bx, Cx, Dx, Ay, By, Cy, Dy, Az, Bz, Cz, Dz, Aw, Bw, Cw, Dw)
Definition macros.h:244
#define PM_CC_TEX_COMBINE_3C
Definition macros.h:382
#define PM_CC_TEX_COMBINE_3B
Definition macros.h:381
#define PM_RM_SHROUD
Definition macros.h:285
#define PM_CC_ALT_INTERFERENCE
Definition macros.h:388
#define SCREEN_WIDTH
Definition macros.h:108
#define PM_CC_TINT_REMAP_SHADE_ALPHA
Definition macros.h:371
#define PM_CC_20
Definition macros.h:344
#define PM_CC1_24
Definition macros.h:377
#define BSS
Definition macros.h:6
#define PM_CC1_29
Definition macros.h:384
#define ARRAY_COUNT(arr)
Definition macros.h:39
#define OPTIMIZE_OFAST
Definition macros.h:591
#define PM_CC_TEX_COMBINE_3A
Definition macros.h:380
#define PM_CC_NOISE
Definition macros.h:322
#define PM_CC_22
Definition macros.h:375
#define INTEGER_LOG2(x)
#define PM_CC2_29
Definition macros.h:385
#define PM_CC2_MULTIPLY_SHADE
Definition macros.h:320
#define PM_CC_TINT_REMAP_NO_SHADE
Definition macros.h:363
#define ALIGNED(x)
Definition macros.h:9
#define PM_CC_TINT_DEPTH_NO_SHADE
Definition macros.h:338
#define PM_CC_23
Definition macros.h:376
#define PM_CC_TINT_DEPTH_MIPMAPS
Definition macros.h:348
#define PM_CC2_24
Definition macros.h:378
#define MAX_MODEL_TRANSFORM_GROUPS
Definition macros.h:88
#define PM_CC_TINT_REMAP_NOTEX
Definition macros.h:355
#define PM_CC_1A
Definition macros.h:324
#define MAX_TEX_PANNERS
Definition macros.h:95
#define PM_CC_TINT_DEPTH_NOTEX
Definition macros.h:330
#define MAX_MODELS
Definition macros.h:87
void(* appendGfx)(void *)
u8 Addr[]
Linker symbol address, as in ld_addrs.h.
Definition types.h:16
s32 gOverrideFlags
Definition main_loop.c:10
GameStatus * gGameStatusPtr
Definition main_loop.c:31
Camera gCameras[4]
Definition cam_main.c:16
Gfx * gMainGfxPos
Definition cam_main.c:14
u16 gMatrixListPos
Definition main_loop.c:44
s32 gCurrentCameraID
Definition cam_math.c:5
DisplayContext * gDisplayContext
Definition cam_main.c:15
s16 gCurrentCamID
Definition cam_main.c:12