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 "gcc/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[];
120extern Gfx Gfx_RM1_INTERSECTING_OPA[];
121extern Gfx Gfx_RM1_ALPHATEST[];
122extern Gfx Gfx_RM1_SURFACE_XLU[];
123extern Gfx Gfx_RM1_DECAL_XLU[];
124extern Gfx Gfx_RM1_INTERSECTING_XLU[];
125extern Gfx Gfx_RM1_SURFACE_OPA_NO_AA[];
126extern Gfx Gfx_RM1_DECAL_OPA_NO_AA[];
128extern Gfx Gfx_RM1_ALPHATEST_ONESIDED[];
129extern Gfx Gfx_RM1_SURFACE_XLU_NO_AA[];
130extern Gfx Gfx_RM1_DECAL_XLU_NO_AA[];
131extern Gfx Gfx_RM1_PASS_THROUGH[];
133extern Gfx Gfx_RM1_SURFACE_OPA_NO_ZB[];
134extern Gfx Gfx_RM1_ALPHATEST_NO_ZB[];
135extern Gfx Gfx_RM1_SURFACE_XLU_NO_ZB[];
136extern Gfx Gfx_RM1_SURFACE_XLU_ZB_ZUPD[];
137extern Gfx Gfx_RM1_CLOUD_NO_ZCMP[];
138extern Gfx Gfx_RM1_CLOUD[];
139extern Gfx Gfx_RM1_CLOUD_NO_ZB[];
140extern Gfx Gfx_RM2_SURFACE_OPA[];
141extern Gfx Gfx_RM2_DECAL_OPA[];
142extern Gfx Gfx_RM2_INTERSECTING_OPA[];
143extern Gfx Gfx_RM2_ALPHATEST[];
144extern Gfx Gfx_RM2_SURFACE_XLU[];
145extern Gfx Gfx_RM2_DECAL_XLU[];
146extern Gfx Gfx_RM2_INTERSECTING_XLU[];
147extern Gfx Gfx_RM2_SURFACE_OPA_NO_AA[];
148extern Gfx Gfx_RM2_DECAL_OPA_NO_AA[];
150extern Gfx Gfx_RM2_ALPHATEST_ONESIDED[];
151extern Gfx Gfx_RM2_SURFACE_XLU_NO_AA[];
152extern Gfx Gfx_RM2_DECAL_XLU_NO_AA[];
153extern Gfx Gfx_RM2_PASS_THROUGH[];
155extern Gfx Gfx_RM2_SURFACE_OPA_NO_ZB[];
156extern Gfx Gfx_RM2_ALPHATEST_NO_ZB[];
157extern Gfx Gfx_RM2_SURFACE_XLU_NO_ZB[];
158extern Gfx Gfx_RM2_CLOUD[];
159extern Gfx Gfx_RM2_CLOUD_NO_ZB[];
160extern Gfx Gfx_RM3_SURFACE_OPA[];
161extern Gfx Gfx_RM3_DECAL_OPA[];
162extern Gfx Gfx_RM3_INTERSECTING_OPA[];
163extern Gfx Gfx_RM3_ALPHATEST[];
164extern Gfx Gfx_RM3_SURFACE_XLU[];
165extern Gfx Gfx_RM3_DECAL_XLU[];
166extern Gfx Gfx_RM3_INTERSECTING_XLU[];
167extern Gfx Gfx_RM3_SURFACE_OPA_NO_AA[];
168extern Gfx Gfx_RM3_DECAL_OPA_NO_AA[];
170extern Gfx Gfx_RM3_ALPHATEST_ONESIDED[];
171extern Gfx Gfx_RM3_SURFACE_XLU_NO_AA[];
172extern Gfx Gfx_RM3_DECAL_XLU_NO_AA[];
173extern Gfx Gfx_RM3_PASS_THROUGH[];
175extern Gfx Gfx_RM3_SURFACE_OPA_NO_ZB[];
176extern Gfx Gfx_RM3_ALPHATEST_NO_ZB[];
177extern Gfx Gfx_RM3_SURFACE_XLU_NO_ZB[];
178extern Gfx Gfx_RM3_CLOUD[];
179extern Gfx Gfx_RM3_CLOUD_NO_ZB[];
180
243};
244
247 [TINT_COMBINE_NONE] gsDPSetCombineMode(G_CC_SHADE, G_CC_SHADE),
248 [TINT_COMBINE_FOG] gsDPSetCombineMode(G_CC_SHADE, G_CC_PASS2),
249 [TINT_COMBINE_SHROUD] gsDPSetCombineMode(G_CC_SHADE, G_CC_PASS2),
250 [TINT_COMBINE_DEPTH] gsDPSetCombineMode(PM_CC_TINT_DEPTH_NOTEX, G_CC_PASS2),
251 [TINT_COMBINE_REMAP] gsDPSetCombineMode(PM_CC_TINT_REMAP_NOTEX, G_CC_PASS2),
252 },
253
255 [TINT_COMBINE_NONE] gsDPSetCombineMode(G_CC_MODULATEIA, G_CC_MODULATEIA),
256 [TINT_COMBINE_FOG] gsDPSetCombineMode(G_CC_MODULATEIDECALA, G_CC_PASS2),
257 [TINT_COMBINE_SHROUD] gsDPSetCombineMode(G_CC_MODULATEIA, G_CC_PASS2),
258 [TINT_COMBINE_DEPTH] gsDPSetCombineMode(G_CC_MODULATEIDECALA, PM_CC_20),
259 [TINT_COMBINE_REMAP] gsDPSetCombineMode(G_CC_MODULATEIA, PM_CC_TINT_REMAP_NO_SHADE),
260 },
262 [TINT_COMBINE_NONE] gsDPSetCombineMode(G_CC_BLENDRGBA, G_CC_BLENDRGBA),
263 [TINT_COMBINE_FOG] gsDPSetCombineMode(G_CC_BLENDRGBA, G_CC_PASS2),
264 [TINT_COMBINE_SHROUD] gsDPSetCombineMode(G_CC_BLENDRGBA, G_CC_PASS2),
265 [TINT_COMBINE_DEPTH] gsDPSetCombineMode(G_CC_BLENDRGBDECALA, PM_CC_TINT_DEPTH_NO_SHADE),
266 [TINT_COMBINE_REMAP] gsDPSetCombineMode(G_CC_BLENDRGBA, PM_CC_TINT_REMAP_NO_SHADE),
267 },
269 [TINT_COMBINE_NONE] gsDPSetCombineMode(G_CC_DECALRGBA, G_CC_DECALRGBA),
270 [TINT_COMBINE_FOG] gsDPSetCombineMode(G_CC_DECALRGBA, G_CC_PASS2),
271 [TINT_COMBINE_SHROUD] gsDPSetCombineMode(G_CC_DECALRGBA, G_CC_PASS2),
272 [TINT_COMBINE_DEPTH] gsDPSetCombineMode(PM_CC_1A, G_CC_PASS2),
273 [TINT_COMBINE_REMAP] gsDPSetCombineMode(G_CC_DECALRGBA, PM_CC_TINT_REMAP_NO_SHADE),
274 },
275
276 // blend LODs in first cycle, tint in second cycle
277 // all three sub-types are identical
279 [TINT_COMBINE_NONE] gsDPSetCombineMode(G_CC_TRILERP, G_CC_MODULATEIA2),
280 [TINT_COMBINE_FOG] gsDPSetCombineMode(G_CC_TRILERP, PM_CC2_MULTIPLY_SHADE),
281 [TINT_COMBINE_SHROUD] gsDPSetCombineMode(G_CC_TRILERP, G_CC_MODULATEIA2),
282 [TINT_COMBINE_DEPTH] gsDPSetCombineMode(G_CC_TRILERP, PM_CC_TINT_DEPTH_MIPMAPS),
283 [TINT_COMBINE_REMAP] gsDPSetCombineMode(G_CC_TRILERP, PM_CC_TINT_REMAP_NO_SHADE),
284 },
286 [TINT_COMBINE_NONE] gsDPSetCombineMode(G_CC_TRILERP, G_CC_MODULATEIA2),
287 [TINT_COMBINE_FOG] gsDPSetCombineMode(G_CC_TRILERP, PM_CC2_MULTIPLY_SHADE),
288 [TINT_COMBINE_SHROUD] gsDPSetCombineMode(G_CC_TRILERP, G_CC_MODULATEIA2),
289 [TINT_COMBINE_DEPTH] gsDPSetCombineMode(G_CC_TRILERP, PM_CC_TINT_DEPTH_MIPMAPS),
290 [TINT_COMBINE_REMAP] gsDPSetCombineMode(G_CC_TRILERP, PM_CC_TINT_REMAP_NO_SHADE),
291 },
293 [TINT_COMBINE_NONE] gsDPSetCombineMode(G_CC_TRILERP, G_CC_MODULATEIA2),
294 [TINT_COMBINE_FOG] gsDPSetCombineMode(G_CC_TRILERP, PM_CC2_MULTIPLY_SHADE),
295 [TINT_COMBINE_SHROUD] gsDPSetCombineMode(G_CC_TRILERP, G_CC_MODULATEIA2),
296 [TINT_COMBINE_DEPTH] gsDPSetCombineMode(G_CC_TRILERP, PM_CC_TINT_DEPTH_MIPMAPS),
297 [TINT_COMBINE_REMAP] gsDPSetCombineMode(G_CC_TRILERP, PM_CC_TINT_REMAP_NO_SHADE),
298 },
299
300 // blend main/aux textures in first cycle, tint in second cycle
301 // all three sub-types are identical
303 [TINT_COMBINE_NONE] gsDPSetCombineMode(PM_CC_ALT_INTERFERENCE, G_CC_MODULATEIA2),
304 [TINT_COMBINE_FOG] gsDPSetCombineMode(G_CC_INTERFERENCE, PM_CC2_MULTIPLY_SHADE),
305 [TINT_COMBINE_SHROUD] gsDPSetCombineMode(PM_CC_ALT_INTERFERENCE, G_CC_MODULATEIA2),
306 [TINT_COMBINE_DEPTH] gsDPSetCombineMode(PM_CC_ALT_INTERFERENCE, G_CC_MODULATEIA2),
308 },
310 [TINT_COMBINE_NONE] gsDPSetCombineMode(PM_CC_ALT_INTERFERENCE, G_CC_MODULATEIA2),
311 [TINT_COMBINE_FOG] gsDPSetCombineMode(G_CC_INTERFERENCE, PM_CC2_MULTIPLY_SHADE),
312 [TINT_COMBINE_SHROUD] gsDPSetCombineMode(PM_CC_ALT_INTERFERENCE, G_CC_MODULATEIA2),
313 [TINT_COMBINE_DEPTH] gsDPSetCombineMode(PM_CC_ALT_INTERFERENCE, G_CC_MODULATEIA2),
315 },
317 [TINT_COMBINE_NONE] gsDPSetCombineMode(PM_CC_ALT_INTERFERENCE, G_CC_MODULATEIA2),
318 [TINT_COMBINE_FOG] gsDPSetCombineMode(G_CC_INTERFERENCE, PM_CC2_MULTIPLY_SHADE),
319 [TINT_COMBINE_SHROUD] gsDPSetCombineMode(PM_CC_ALT_INTERFERENCE, G_CC_MODULATEIA2),
320 [TINT_COMBINE_DEPTH] gsDPSetCombineMode(PM_CC_ALT_INTERFERENCE, G_CC_MODULATEIA2),
322 },
323
324 // blend main/aux textures in first cycle, tint in second cycle
325 // all three sub-types are identical
327 [TINT_COMBINE_NONE] gsDPSetCombineMode(PM_CC_ALT_INTERFERENCE, G_CC_MODULATEIA2),
328 [TINT_COMBINE_FOG] gsDPSetCombineMode(G_CC_INTERFERENCE, PM_CC2_MULTIPLY_SHADE),
329 [TINT_COMBINE_SHROUD] gsDPSetCombineMode(PM_CC_ALT_INTERFERENCE, G_CC_MODULATEIA2),
330 [TINT_COMBINE_DEPTH] gsDPSetCombineMode(PM_CC_ALT_INTERFERENCE, G_CC_MODULATEIA2),
332 },
334 [TINT_COMBINE_NONE] gsDPSetCombineMode(PM_CC_ALT_INTERFERENCE, G_CC_MODULATEIA2),
335 [TINT_COMBINE_FOG] gsDPSetCombineMode(G_CC_INTERFERENCE, PM_CC2_MULTIPLY_SHADE),
336 [TINT_COMBINE_SHROUD] gsDPSetCombineMode(PM_CC_ALT_INTERFERENCE, G_CC_MODULATEIA2),
337 [TINT_COMBINE_DEPTH] gsDPSetCombineMode(PM_CC_ALT_INTERFERENCE, G_CC_MODULATEIA2),
339 },
341 [TINT_COMBINE_NONE] gsDPSetCombineMode(PM_CC_ALT_INTERFERENCE, G_CC_MODULATEIA2),
342 [TINT_COMBINE_FOG] gsDPSetCombineMode(G_CC_INTERFERENCE, PM_CC2_MULTIPLY_SHADE),
343 [TINT_COMBINE_SHROUD] gsDPSetCombineMode(PM_CC_ALT_INTERFERENCE, G_CC_MODULATEIA2),
344 [TINT_COMBINE_DEPTH] gsDPSetCombineMode(PM_CC_ALT_INTERFERENCE, G_CC_MODULATEIA2),
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] {
358 [TINT_COMBINE_NONE] gsDPSetCombineMode(PM_CC_22, G_CC_PASS2),
359 [TINT_COMBINE_FOG] gsDPSetCombineMode(PM_CC_22, G_CC_PASS2),
360 [TINT_COMBINE_SHROUD] gsDPSetCombineMode(PM_CC_22, G_CC_PASS2),
361 [TINT_COMBINE_DEPTH] gsDPSetCombineMode(PM_CC_22, G_CC_PASS2),
363 },
364 [TEX_COMBINE_5] {
365 [TINT_COMBINE_NONE] gsDPSetCombineMode(PM_CC1_24, PM_CC2_24),
366 [TINT_COMBINE_FOG] gsDPSetCombineMode(PM_CC1_24, PM_CC2_24),
367 [TINT_COMBINE_SHROUD] gsDPSetCombineMode(PM_CC1_24, PM_CC2_24),
368 [TINT_COMBINE_DEPTH] gsDPSetCombineMode(PM_CC1_24, PM_CC2_24),
369 [TINT_COMBINE_REMAP] gsDPSetCombineMode(PM_CC1_24, PM_CC2_24),
370 },
371 [TEX_COMBINE_6] {
372 [TINT_COMBINE_NONE] gsDPSetCombineMode(PM_CC_23, PM_CC_23),
373 [TINT_COMBINE_FOG] gsDPSetCombineMode(PM_CC_23, G_CC_PASS2),
374 [TINT_COMBINE_SHROUD] gsDPSetCombineMode(PM_CC_23, G_CC_PASS2),
375 [TINT_COMBINE_DEPTH] gsDPSetCombineMode(PM_CC_23, G_CC_PASS2),
377 },
378 [TEX_COMBINE_7] {
379 [TINT_COMBINE_NONE] gsDPSetCombineMode(PM_CC1_29, PM_CC2_29),
380 [TINT_COMBINE_FOG] gsDPSetCombineMode(PM_CC1_29, PM_CC2_29),
381 [TINT_COMBINE_SHROUD] gsDPSetCombineMode(PM_CC1_29, PM_CC2_29),
382 [TINT_COMBINE_DEPTH] gsDPSetCombineMode(PM_CC1_29, PM_CC2_29),
383 [TINT_COMBINE_REMAP] gsDPSetCombineMode(PM_CC1_29, PM_CC2_29),
384 },
385 [TEX_COMBINE_8] {
386 [TINT_COMBINE_NONE] gsDPSetCombineMode(PM_CC_NOISE, PM_CC_NOISE),
387 [TINT_COMBINE_FOG] gsDPSetCombineMode(PM_CC_NOISE, PM_CC_NOISE),
388 [TINT_COMBINE_SHROUD] gsDPSetCombineMode(PM_CC_NOISE, PM_CC_NOISE),
389 [TINT_COMBINE_DEPTH] gsDPSetCombineMode(PM_CC_NOISE, PM_CC_NOISE),
390 [TINT_COMBINE_REMAP] gsDPSetCombineMode(PM_CC_NOISE, PM_CC_NOISE),
391 },
392 [TEX_COMBINE_9] {
393 [TINT_COMBINE_NONE] gsDPSetCombineMode(PM_CC_NOISE, PM_CC_NOISE),
394 [TINT_COMBINE_FOG] gsDPSetCombineMode(PM_CC_NOISE, PM_CC_NOISE),
395 [TINT_COMBINE_SHROUD] gsDPSetCombineMode(PM_CC_NOISE, PM_CC_NOISE),
396 [TINT_COMBINE_DEPTH] gsDPSetCombineMode(PM_CC_NOISE, PM_CC_NOISE),
397 [TINT_COMBINE_REMAP] gsDPSetCombineMode(PM_CC_NOISE, PM_CC_NOISE),
398 },
399 [TEX_COMBINE_A] {
400 [TINT_COMBINE_NONE] gsDPSetCombineMode(PM_CC_NOISE, PM_CC_NOISE),
401 [TINT_COMBINE_FOG] gsDPSetCombineMode(PM_CC_NOISE, PM_CC_NOISE),
402 [TINT_COMBINE_SHROUD] gsDPSetCombineMode(PM_CC_NOISE, PM_CC_NOISE),
403 [TINT_COMBINE_DEPTH] gsDPSetCombineMode(PM_CC_NOISE, PM_CC_NOISE),
404 [TINT_COMBINE_REMAP] gsDPSetCombineMode(PM_CC_NOISE, PM_CC_NOISE),
405 },
406};
407
410 [TINT_COMBINE_NONE] gsDPSetCombineMode(G_CC_SHADE, G_CC_SHADE),
411 [TINT_COMBINE_FOG] gsDPSetCombineMode(G_CC_SHADE, G_CC_PASS2),
412 [TINT_COMBINE_SHROUD] gsDPSetCombineMode(G_CC_SHADE, G_CC_PASS2),
413 [TINT_COMBINE_DEPTH] gsDPSetCombineMode(PM_CC_TINT_DEPTH_NOTEX, G_CC_PASS2),
414 [TINT_COMBINE_REMAP] gsDPSetCombineMode(PM_CC_TINT_REMAP_NOTEX, G_CC_PASS2),
415 },
416
418 [TINT_COMBINE_NONE] gsDPSetCombineMode(G_CC_MODULATEIDECALA, G_CC_MODULATEIDECALA),
419 [TINT_COMBINE_FOG] gsDPSetCombineMode(G_CC_MODULATEIDECALA, G_CC_PASS2),
420 [TINT_COMBINE_SHROUD] gsDPSetCombineMode(G_CC_MODULATEIDECALA, G_CC_PASS2),
421 [TINT_COMBINE_DEPTH] gsDPSetCombineMode(G_CC_MODULATEIDECALA, PM_CC_20),
422 [TINT_COMBINE_REMAP] gsDPSetCombineMode(G_CC_MODULATEIDECALA, PM_CC_TINT_REMAP_NO_SHADE),
423 },
425 [TINT_COMBINE_NONE] gsDPSetCombineMode(G_CC_BLENDRGBA, G_CC_BLENDRGBA),
426 [TINT_COMBINE_FOG] gsDPSetCombineMode(G_CC_BLENDRGBA, G_CC_PASS2),
427 [TINT_COMBINE_SHROUD] gsDPSetCombineMode(G_CC_BLENDRGBA, G_CC_PASS2),
428 [TINT_COMBINE_DEPTH] gsDPSetCombineMode(G_CC_BLENDRGBDECALA, PM_CC_TINT_DEPTH_NO_SHADE),
429 [TINT_COMBINE_REMAP] gsDPSetCombineMode(G_CC_BLENDRGBA, PM_CC_TINT_REMAP_NO_SHADE),
430 },
432 [TINT_COMBINE_NONE] gsDPSetCombineMode(G_CC_DECALRGBA, G_CC_DECALRGBA),
433 [TINT_COMBINE_FOG] gsDPSetCombineMode(G_CC_DECALRGBA, G_CC_PASS2),
434 [TINT_COMBINE_SHROUD] gsDPSetCombineMode(G_CC_DECALRGBA, G_CC_PASS2),
435 [TINT_COMBINE_DEPTH] gsDPSetCombineMode(PM_CC_1A, G_CC_PASS2),
436 [TINT_COMBINE_REMAP] gsDPSetCombineMode(G_CC_DECALRGBA, PM_CC_TINT_REMAP_NO_SHADE),
437 },
438
439 // blend LODs in first cycle, tint in second cycle
441 [TINT_COMBINE_NONE] gsDPSetCombineMode(G_CC_TRILERP, G_CC_MODULATEI2),
442 [TINT_COMBINE_FOG] gsDPSetCombineMode(G_CC_TRILERP, PM_CC2_MULTIPLY_SHADE),
443 [TINT_COMBINE_SHROUD] gsDPSetCombineMode(G_CC_TRILERP, G_CC_MODULATEI2),
444 [TINT_COMBINE_DEPTH] gsDPSetCombineMode(G_CC_TRILERP, PM_CC_TINT_DEPTH_MIPMAPS),
445 [TINT_COMBINE_REMAP] gsDPSetCombineMode(G_CC_TRILERP, PM_CC_TINT_REMAP_NO_SHADE),
446 },
448 [TINT_COMBINE_NONE] gsDPSetCombineMode(G_CC_TRILERP, G_CC_MODULATEIA2),
449 [TINT_COMBINE_FOG] gsDPSetCombineMode(G_CC_TRILERP, PM_CC2_MULTIPLY_SHADE),
450 [TINT_COMBINE_SHROUD] gsDPSetCombineMode(G_CC_TRILERP, G_CC_MODULATEIA2),
451 [TINT_COMBINE_DEPTH] gsDPSetCombineMode(G_CC_TRILERP, PM_CC_TINT_DEPTH_MIPMAPS),
452 [TINT_COMBINE_REMAP] gsDPSetCombineMode(G_CC_TRILERP, PM_CC_TINT_REMAP_NO_SHADE),
453 },
455 [TINT_COMBINE_NONE] gsDPSetCombineMode(G_CC_TRILERP, G_CC_MODULATEIA2),
456 [TINT_COMBINE_FOG] gsDPSetCombineMode(G_CC_TRILERP, PM_CC2_MULTIPLY_SHADE),
457 [TINT_COMBINE_SHROUD] gsDPSetCombineMode(G_CC_TRILERP, G_CC_MODULATEIA2),
458 [TINT_COMBINE_DEPTH] gsDPSetCombineMode(G_CC_TRILERP, PM_CC_TINT_DEPTH_MIPMAPS),
459 [TINT_COMBINE_REMAP] gsDPSetCombineMode(G_CC_TRILERP, PM_CC_TINT_REMAP_NO_SHADE),
460 },
461
462 // blend main/aux textures in first cycle, tint in second cycle
465 [TINT_COMBINE_FOG] gsDPSetCombineMode(G_CC_INTERFERENCE, PM_CC2_MULTIPLY_SHADE),
469 },
472 [TINT_COMBINE_FOG] gsDPSetCombineMode(G_CC_INTERFERENCE, PM_CC2_MULTIPLY_SHADE),
476 },
479 [TINT_COMBINE_FOG] gsDPSetCombineMode(G_CC_INTERFERENCE, PM_CC2_MULTIPLY_SHADE),
483 },
484
485 // blend main/aux textures in first cycle, tint in second cycle
488 [TINT_COMBINE_FOG] gsDPSetCombineMode(G_CC_INTERFERENCE, PM_CC2_MULTIPLY_SHADE),
492 },
495 [TINT_COMBINE_FOG] gsDPSetCombineMode(G_CC_INTERFERENCE, PM_CC2_MULTIPLY_SHADE),
499 },
502 [TINT_COMBINE_FOG] gsDPSetCombineMode(G_CC_INTERFERENCE, PM_CC2_MULTIPLY_SHADE),
506 },
507
508 [TEX_COMBINE_3] {
514 },
515 [TEX_COMBINE_4] {
516 [TINT_COMBINE_NONE] gsDPSetCombineMode(PM_CC_22, G_CC_PASS2),
517 [TINT_COMBINE_FOG] gsDPSetCombineMode(PM_CC_22, G_CC_PASS2),
518 [TINT_COMBINE_SHROUD] gsDPSetCombineMode(PM_CC_22, G_CC_PASS2),
519 [TINT_COMBINE_DEPTH] gsDPSetCombineMode(PM_CC_22, G_CC_PASS2),
521 },
522 [TEX_COMBINE_5] {
523 [TINT_COMBINE_NONE] gsDPSetCombineMode(PM_CC1_24, PM_CC2_24),
524 [TINT_COMBINE_FOG] gsDPSetCombineMode(PM_CC1_24, PM_CC2_24),
525 [TINT_COMBINE_SHROUD] gsDPSetCombineMode(PM_CC1_24, PM_CC2_24),
526 [TINT_COMBINE_DEPTH] gsDPSetCombineMode(PM_CC1_24, PM_CC2_24),
527 [TINT_COMBINE_REMAP] gsDPSetCombineMode(PM_CC1_24, PM_CC2_24),
528 },
529 [TEX_COMBINE_6] {
530 [TINT_COMBINE_NONE] gsDPSetCombineMode(PM_CC_23, PM_CC_23),
531 [TINT_COMBINE_FOG] gsDPSetCombineMode(PM_CC_23, G_CC_PASS2),
532 [TINT_COMBINE_SHROUD] gsDPSetCombineMode(PM_CC_23, G_CC_PASS2),
533 [TINT_COMBINE_DEPTH] gsDPSetCombineMode(PM_CC_23, G_CC_PASS2),
535 },
536 [TEX_COMBINE_7] {
537 [TINT_COMBINE_NONE] gsDPSetCombineMode(PM_CC1_29, PM_CC2_29),
538 [TINT_COMBINE_FOG] gsDPSetCombineMode(PM_CC1_29, PM_CC2_29),
539 [TINT_COMBINE_SHROUD] gsDPSetCombineMode(PM_CC1_29, PM_CC2_29),
540 [TINT_COMBINE_DEPTH] gsDPSetCombineMode(PM_CC1_29, PM_CC2_29),
541 [TINT_COMBINE_REMAP] gsDPSetCombineMode(PM_CC1_29, PM_CC2_29),
542 },
543 [TEX_COMBINE_8] {
544 [TINT_COMBINE_NONE] gsDPSetCombineMode(PM_CC_NOISE, PM_CC_NOISE),
545 [TINT_COMBINE_FOG] gsDPSetCombineMode(PM_CC_NOISE, PM_CC_NOISE),
546 [TINT_COMBINE_SHROUD] gsDPSetCombineMode(PM_CC_NOISE, PM_CC_NOISE),
547 [TINT_COMBINE_DEPTH] gsDPSetCombineMode(PM_CC_NOISE, PM_CC_NOISE),
548 [TINT_COMBINE_REMAP] gsDPSetCombineMode(PM_CC_NOISE, PM_CC_NOISE),
549 },
550 [TEX_COMBINE_9] {
551 [TINT_COMBINE_NONE] gsDPSetCombineMode(PM_CC_NOISE, PM_CC_NOISE),
552 [TINT_COMBINE_FOG] gsDPSetCombineMode(PM_CC_NOISE, PM_CC_NOISE),
553 [TINT_COMBINE_SHROUD] gsDPSetCombineMode(PM_CC_NOISE, PM_CC_NOISE),
554 [TINT_COMBINE_DEPTH] gsDPSetCombineMode(PM_CC_NOISE, PM_CC_NOISE),
555 [TINT_COMBINE_REMAP] gsDPSetCombineMode(PM_CC_NOISE, PM_CC_NOISE),
556 },
557 [TEX_COMBINE_A] {
558 [TINT_COMBINE_NONE] gsDPSetCombineMode(PM_CC_NOISE, PM_CC_NOISE),
559 [TINT_COMBINE_FOG] gsDPSetCombineMode(PM_CC_NOISE, PM_CC_NOISE),
560 [TINT_COMBINE_SHROUD] gsDPSetCombineMode(PM_CC_NOISE, PM_CC_NOISE),
561 [TINT_COMBINE_DEPTH] gsDPSetCombineMode(PM_CC_NOISE, PM_CC_NOISE),
562 [TINT_COMBINE_REMAP] gsDPSetCombineMode(PM_CC_NOISE, PM_CC_NOISE),
563 },
564};
565
567
572
580u8 DepthTintColA = 0; // unused?
582s32 DepthTintEnd = 1000;
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
644 gsDPSetRenderMode(G_RM_AA_ZB_OPA_SURF, G_RM_AA_ZB_OPA_SURF2),
645 gsDPSetCycleType(G_CYC_1CYCLE),
646 gsSPClearGeometryMode(G_SHADE | G_CULL_BOTH | G_FOG | G_LIGHTING | G_TEXTURE_GEN | G_TEXTURE_GEN_LINEAR | G_LOD |
647 G_SHADING_SMOOTH),
648 gsSPSetGeometryMode(G_ZBUFFER | G_SHADE | G_CULL_BACK | G_LIGHTING | G_SHADING_SMOOTH),
649 gsSPEndDisplayList(),
650};
651
652// RENDER_MODE_IDX_02: RENDER_MODE_DECAL_OPA, RENDER_CLASS_1CYC
653// used by entity models
655 gsDPSetRenderMode(G_RM_AA_ZB_OPA_DECAL, G_RM_AA_ZB_OPA_DECAL2),
656 gsDPSetCycleType(G_CYC_1CYCLE),
657 gsSPClearGeometryMode(G_SHADE | G_CULL_BOTH | G_FOG | G_LIGHTING | G_TEXTURE_GEN | G_TEXTURE_GEN_LINEAR | G_LOD |
658 G_SHADING_SMOOTH),
659 gsSPSetGeometryMode(G_ZBUFFER | G_SHADE | G_CULL_BACK | G_LIGHTING | G_SHADING_SMOOTH),
660 gsSPEndDisplayList(),
661};
662
663// RENDER_MODE_IDX_04: RENDER_MODE_INTERSECTING_OPA, RENDER_CLASS_1CYC
664// used by entity models
666 gsDPSetRenderMode(G_RM_AA_ZB_OPA_INTER, G_RM_AA_ZB_OPA_INTER2),
667 gsDPSetCycleType(G_CYC_1CYCLE),
668 gsSPClearGeometryMode(G_SHADE | G_CULL_BOTH | G_FOG | G_LIGHTING | G_TEXTURE_GEN | G_TEXTURE_GEN_LINEAR | G_LOD |
669 G_SHADING_SMOOTH),
670 gsSPSetGeometryMode(G_ZBUFFER | G_SHADE | G_CULL_BACK | G_LIGHTING | G_SHADING_SMOOTH),
671 gsSPEndDisplayList(),
672};
673
674// RENDER_MODE_IDX_06: RENDER_MODE_ALPHATEST, RENDER_CLASS_1CYC
675// used by entity models and item entities
677 gsDPSetRenderMode(G_RM_AA_ZB_TEX_EDGE, G_RM_AA_ZB_TEX_EDGE2),
678 gsDPSetCycleType(G_CYC_1CYCLE),
679 gsSPClearGeometryMode(G_SHADE | G_CULL_BOTH | G_FOG | G_LIGHTING | G_TEXTURE_GEN | G_TEXTURE_GEN_LINEAR | G_LOD | G_SHADING_SMOOTH),
680 gsSPSetGeometryMode(G_ZBUFFER | G_SHADE | G_LIGHTING | G_SHADING_SMOOTH),
681 gsSPEndDisplayList(),
682};
683
684// RENDER_MODE_IDX_08: RENDER_MODE_SURFACE_XLU, RENDER_CLASS_1CYC
685// used by entity models
687 gsDPSetRenderMode(G_RM_AA_ZB_XLU_SURF, G_RM_AA_ZB_XLU_SURF2),
688 gsDPSetCycleType(G_CYC_1CYCLE),
689 gsSPClearGeometryMode(G_SHADE | G_CULL_BOTH | G_FOG | G_LIGHTING | G_TEXTURE_GEN | G_TEXTURE_GEN_LINEAR | G_LOD | G_SHADING_SMOOTH),
690 gsSPSetGeometryMode(G_ZBUFFER | G_SHADE | G_LIGHTING | G_SHADING_SMOOTH),
691 gsSPEndDisplayList(),
692};
693
694// RENDER_MODE_IDX_0C: RENDER_MODE_DECAL_XLU, RENDER_CLASS_1CYC
695// used by entity models
697 gsDPSetRenderMode(G_RM_AA_ZB_XLU_DECAL, G_RM_AA_ZB_XLU_DECAL2),
698 gsDPSetCycleType(G_CYC_1CYCLE),
699 gsSPClearGeometryMode(G_SHADE | G_CULL_BOTH | G_FOG | G_LIGHTING | G_TEXTURE_GEN | G_TEXTURE_GEN_LINEAR | G_LOD | G_SHADING_SMOOTH),
700 gsSPSetGeometryMode(G_ZBUFFER | G_SHADE | G_LIGHTING | G_SHADING_SMOOTH),
701 gsSPEndDisplayList(),
702};
703
704// RENDER_MODE_IDX_0E: RENDER_MODE_INTERSECTING_XLU, RENDER_CLASS_1CYC
705// used by entity models
707 gsDPSetRenderMode(G_RM_AA_ZB_XLU_INTER, G_RM_AA_ZB_XLU_INTER2),
708 gsDPSetCycleType(G_CYC_1CYCLE),
709 gsSPClearGeometryMode(G_SHADE | G_CULL_BOTH | G_FOG | G_LIGHTING | G_TEXTURE_GEN | G_TEXTURE_GEN_LINEAR | G_LOD | G_SHADING_SMOOTH),
710 gsSPSetGeometryMode(G_ZBUFFER | G_SHADE | G_LIGHTING | G_SHADING_SMOOTH),
711 gsSPEndDisplayList(),
712};
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
719 gsDPSetRenderMode(G_RM_ZB_OPA_SURF, G_RM_ZB_OPA_SURF2),
720 gsDPSetCycleType(G_CYC_1CYCLE),
721 gsSPClearGeometryMode(G_SHADE | G_CULL_BOTH | G_FOG | G_LIGHTING | G_TEXTURE_GEN | G_TEXTURE_GEN_LINEAR | G_LOD | G_SHADING_SMOOTH),
722 gsSPSetGeometryMode(G_ZBUFFER | G_SHADE | G_CULL_BACK | G_LIGHTING | G_SHADING_SMOOTH),
723 gsSPEndDisplayList(),
724};
725
726// RENDER_MODE_IDX_03: RENDER_MODE_DECAL_OPA_NO_AA, RENDER_CLASS_1CYC
728 gsDPSetRenderMode(G_RM_ZB_OPA_DECAL, G_RM_ZB_OPA_DECAL2),
729 gsDPSetCycleType(G_CYC_1CYCLE),
730 gsSPClearGeometryMode(G_SHADE | G_CULL_BOTH | G_FOG | G_LIGHTING | G_TEXTURE_GEN | G_TEXTURE_GEN_LINEAR | G_LOD | G_SHADING_SMOOTH),
731 gsSPSetGeometryMode(G_ZBUFFER | G_SHADE | G_CULL_BACK | G_LIGHTING | G_SHADING_SMOOTH),
732 gsSPEndDisplayList(),
733};
734
735// RENDER_MODE_IDX_05: unused
737 gsDPSetRenderMode(G_RM_AA_ZB_OPA_INTER, G_RM_AA_ZB_OPA_INTER2),
738 gsSPClearGeometryMode(G_SHADE | G_CULL_BOTH | G_FOG | G_LIGHTING | G_TEXTURE_GEN | G_TEXTURE_GEN_LINEAR | G_LOD | G_SHADING_SMOOTH),
739 gsSPSetGeometryMode(G_ZBUFFER | G_SHADE | G_CULL_BACK | G_LIGHTING | G_SHADING_SMOOTH),
740 gsDPSetCombineMode(G_CC_SHADE, G_CC_SHADE),
741 gsSPEndDisplayList(),
742};
743
744// RENDER_MODE_IDX_07: RENDER_MODE_ALPHATEST_ONESIDED, RENDER_CLASS_1CYC
745// used by entity models
747 gsDPSetRenderMode(G_RM_AA_ZB_TEX_EDGE, G_RM_AA_ZB_TEX_EDGE2),
748 gsDPSetCycleType(G_CYC_1CYCLE),
749 gsSPClearGeometryMode(G_SHADE | G_CULL_BOTH | G_FOG | G_LIGHTING | G_TEXTURE_GEN | G_TEXTURE_GEN_LINEAR | G_LOD | G_SHADING_SMOOTH),
750 gsSPSetGeometryMode(G_ZBUFFER | G_SHADE | G_CULL_BACK | G_LIGHTING | G_SHADING_SMOOTH),
751 gsSPEndDisplayList(),
752};
753
754// RENDER_MODE_IDX_0A: RENDER_MODE_SURFACE_XLU_NO_AA, RENDER_CLASS_1CYC
755// used by entity models
757 gsDPSetRenderMode(G_RM_ZB_XLU_SURF, G_RM_ZB_XLU_SURF2),
758 gsDPSetCycleType(G_CYC_1CYCLE),
759 gsSPClearGeometryMode(G_SHADE | G_CULL_BOTH | G_FOG | G_LIGHTING | G_TEXTURE_GEN | G_TEXTURE_GEN_LINEAR | G_LOD | G_SHADING_SMOOTH),
760 gsSPSetGeometryMode(G_ZBUFFER | G_SHADE | G_LIGHTING | G_SHADING_SMOOTH),
761 gsSPEndDisplayList(),
762};
763
764// RENDER_MODE_IDX_0D: RENDER_MODE_DECAL_XLU_NO_AA, RENDER_CLASS_1CYC
765// used by entity models
767 gsDPSetRenderMode(G_RM_ZB_OVL_SURF, G_RM_ZB_OVL_SURF2),
768 gsDPSetCycleType(G_CYC_1CYCLE),
769 gsSPClearGeometryMode(G_SHADE | G_CULL_BOTH | G_FOG | G_LIGHTING | G_TEXTURE_GEN | G_TEXTURE_GEN_LINEAR | G_LOD | G_SHADING_SMOOTH),
770 gsSPSetGeometryMode(G_ZBUFFER | G_SHADE | G_LIGHTING | G_SHADING_SMOOTH),
771 gsSPEndDisplayList(),
772};
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
780 gsDPSetCycleType(G_CYC_1CYCLE),
781 gsSPClearGeometryMode(G_SHADE | G_CULL_BOTH | G_FOG | G_LIGHTING | G_TEXTURE_GEN | G_TEXTURE_GEN_LINEAR | G_LOD | G_SHADING_SMOOTH),
782 gsSPSetGeometryMode(G_ZBUFFER | G_SHADE | G_LIGHTING | G_SHADING_SMOOTH),
783 gsSPEndDisplayList(),
784};
785
786// RENDER_MODE_IDX_09: RENDER_MODE_SURFACE_XLU_AA_ZB_ZUPD, RENDER_CLASS_1CYC
788 gsDPSetRenderMode(AA_EN | Z_CMP | Z_UPD | IM_RD | CLR_ON_CVG | CVG_DST_WRAP | ZMODE_XLU | FORCE_BL |
789 GBL_c1(G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_1MA), AA_EN | Z_CMP | Z_UPD | IM_RD |
790 CLR_ON_CVG | CVG_DST_WRAP | ZMODE_XLU | FORCE_BL |
791 GBL_c2(G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_1MA)),
792 gsDPSetCycleType(G_CYC_1CYCLE),
793 gsSPClearGeometryMode(G_SHADE | G_CULL_BOTH | G_FOG | G_LIGHTING | G_TEXTURE_GEN | G_TEXTURE_GEN_LINEAR | G_LOD | G_SHADING_SMOOTH),
794 gsSPSetGeometryMode(G_ZBUFFER | G_SHADE | G_LIGHTING | G_SHADING_SMOOTH),
795 gsSPEndDisplayList(),
796};
797
798// RENDER_MODE_IDX_2E: RENDER_MODE_SURFACE_OPA_NO_ZB, RENDER_CLASS_1CYC
799// used by entity models
801 gsDPSetRenderMode(G_RM_AA_OPA_SURF, G_RM_AA_OPA_SURF2),
802 gsDPSetCycleType(G_CYC_1CYCLE),
803 gsSPClearGeometryMode(G_ZBUFFER | G_SHADE | G_CULL_BOTH | G_FOG | G_LIGHTING | G_TEXTURE_GEN | G_TEXTURE_GEN_LINEAR | G_LOD | G_SHADING_SMOOTH),
804 gsSPSetGeometryMode(G_SHADE | G_CULL_BACK | G_LIGHTING | G_SHADING_SMOOTH),
805 gsSPEndDisplayList(),
806};
807
808// RENDER_MODE_IDX_2F: RENDER_MODE_ALPHATEST_NO_ZB, RENDER_CLASS_1CYC
809// used by entity models
811 gsDPSetRenderMode(G_RM_AA_TEX_EDGE, G_RM_AA_TEX_EDGE2),
812 gsDPSetCycleType(G_CYC_1CYCLE),
813 gsSPClearGeometryMode(G_ZBUFFER | G_SHADE | G_CULL_BOTH | G_FOG | G_LIGHTING | G_TEXTURE_GEN | G_TEXTURE_GEN_LINEAR | G_LOD | G_SHADING_SMOOTH),
814 gsSPSetGeometryMode(G_SHADE | G_LIGHTING | G_SHADING_SMOOTH),
815 gsSPEndDisplayList(),
816};
817
818// RENDER_MODE_IDX_30: RENDER_MODE_SURFACE_XLU_NO_ZB, RENDER_CLASS_1CYC
819// used by entity models
821 gsDPSetRenderMode(G_RM_AA_XLU_SURF, G_RM_AA_XLU_SURF2),
822 gsDPSetCycleType(G_CYC_1CYCLE),
823 gsSPClearGeometryMode(G_ZBUFFER | G_SHADE | G_CULL_BOTH | G_FOG | G_LIGHTING | G_TEXTURE_GEN | G_TEXTURE_GEN_LINEAR | G_LOD | G_SHADING_SMOOTH),
824 gsSPSetGeometryMode(G_SHADE | G_LIGHTING | G_SHADING_SMOOTH),
825 gsSPEndDisplayList(),
826};
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
831 gsDPSetRenderMode(AA_EN | IM_RD | CVG_DST_WRAP | CLR_ON_CVG | FORCE_BL | Z_CMP | Z_UPD |
832 GBL_c1(G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_1MA),
833 AA_EN | IM_RD | CVG_DST_WRAP | CLR_ON_CVG | FORCE_BL | Z_CMP | Z_UPD | ZMODE_XLU |
834 GBL_c2(G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_1MA)),
835 gsDPSetCycleType(G_CYC_1CYCLE),
836 gsSPClearGeometryMode(G_SHADE | G_CULL_BOTH | G_FOG | G_LIGHTING | G_TEXTURE_GEN | G_TEXTURE_GEN_LINEAR | G_LOD | G_SHADING_SMOOTH),
837 gsSPSetGeometryMode(G_ZBUFFER | G_SHADE | G_LIGHTING | G_SHADING_SMOOTH),
838 gsSPEndDisplayList(),
839};
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
845 gsDPSetRenderMode(IM_RD | CVG_DST_SAVE | ZMODE_XLU | FORCE_BL |
846 GBL_c1(G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_1MA),
847 IM_RD | CVG_DST_SAVE | ZMODE_XLU | FORCE_BL |
848 GBL_c2(G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_1MA)),
849 gsDPSetCycleType(G_CYC_1CYCLE),
850 gsSPClearGeometryMode(G_SHADE | G_CULL_BOTH | G_FOG | G_LIGHTING | G_TEXTURE_GEN | G_TEXTURE_GEN_LINEAR | G_LOD | G_SHADING_SMOOTH),
851 gsSPSetGeometryMode(G_ZBUFFER | G_SHADE | G_LIGHTING | G_SHADING_SMOOTH),
852 gsSPEndDisplayList(),
853};
854
855// RENDER_MODE_IDX_37: RENDER_MODE_CLOUD, RENDER_CLASS_1CYC
857 gsDPSetRenderMode(G_RM_ZB_CLD_SURF, G_RM_ZB_CLD_SURF2),
858 gsDPSetCycleType(G_CYC_1CYCLE),
859 gsSPClearGeometryMode(G_SHADE | G_CULL_BOTH | G_FOG | G_LIGHTING | G_TEXTURE_GEN | G_TEXTURE_GEN_LINEAR | G_LOD | G_SHADING_SMOOTH),
860 gsSPSetGeometryMode(G_ZBUFFER | G_SHADE | G_LIGHTING | G_SHADING_SMOOTH),
861 gsSPEndDisplayList(),
862};
863
864// RENDER_MODE_IDX_38: RENDER_MODE_CLOUD_NO_ZB, RENDER_CLASS_1CYC
866 gsDPSetRenderMode(G_RM_CLD_SURF, G_RM_CLD_SURF2),
867 gsDPSetCycleType(G_CYC_1CYCLE),
868 gsSPClearGeometryMode(G_SHADE | G_CULL_BOTH | G_FOG | G_LIGHTING | G_TEXTURE_GEN | G_TEXTURE_GEN_LINEAR | G_LOD | G_SHADING_SMOOTH),
869 gsSPSetGeometryMode(G_ZBUFFER | G_SHADE | G_LIGHTING | G_SHADING_SMOOTH),
870 gsSPEndDisplayList(),
871};
872
873// ----------------------------------------------------------------------------
874// RENDER_CLASS_2CYC, basic AA variants
875
876// RENDER_MODE_IDX_10: RENDER_MODE_SURFACE_OPA, RENDER_CLASS_2CYC
878 gsDPSetRenderMode(G_RM_PASS, G_RM_AA_ZB_OPA_SURF2),
879 gsDPSetCycleType(G_CYC_2CYCLE),
880 gsSPClearGeometryMode(G_SHADE | G_CULL_BOTH | G_FOG | G_LIGHTING | G_TEXTURE_GEN | G_TEXTURE_GEN_LINEAR | G_LOD | G_SHADING_SMOOTH),
881 gsSPSetGeometryMode(G_ZBUFFER | G_SHADE | G_CULL_BACK | G_LIGHTING | G_SHADING_SMOOTH),
882 gsSPEndDisplayList(),
883};
884
885// RENDER_MODE_IDX_12: RENDER_MODE_DECAL_OPA, RENDER_CLASS_2CYC
887 gsDPSetRenderMode(G_RM_PASS, G_RM_AA_ZB_OPA_DECAL2),
888 gsDPSetCycleType(G_CYC_2CYCLE),
889 gsSPClearGeometryMode(G_SHADE | G_CULL_BOTH | G_FOG | G_LIGHTING | G_TEXTURE_GEN | G_TEXTURE_GEN_LINEAR | G_LOD | G_SHADING_SMOOTH),
890 gsSPSetGeometryMode(G_ZBUFFER | G_SHADE | G_CULL_BACK | G_LIGHTING | G_SHADING_SMOOTH),
891 gsSPEndDisplayList(),
892};
893
894// RENDER_MODE_IDX_14: RENDER_MODE_INTERSECTING_OPA, RENDER_CLASS_2CYC
896 gsDPSetRenderMode(G_RM_PASS, G_RM_AA_ZB_OPA_INTER2),
897 gsDPSetCycleType(G_CYC_2CYCLE),
898 gsSPClearGeometryMode(G_SHADE | G_CULL_BOTH | G_FOG | G_LIGHTING | G_TEXTURE_GEN | G_TEXTURE_GEN_LINEAR | G_LOD | G_SHADING_SMOOTH),
899 gsSPSetGeometryMode(G_ZBUFFER | G_SHADE | G_CULL_BACK | G_LIGHTING | G_SHADING_SMOOTH),
900 gsSPEndDisplayList(),
901};
902
903// RENDER_MODE_IDX_16: RENDER_MODE_ALPHATEST, RENDER_CLASS_2CYC
904// used by entity models, item entities with shading
906 gsDPSetRenderMode(G_RM_PASS, G_RM_AA_ZB_TEX_EDGE2),
907 gsDPSetCycleType(G_CYC_2CYCLE),
908 gsSPClearGeometryMode(G_SHADE | G_CULL_BOTH | G_FOG | G_LIGHTING | G_TEXTURE_GEN | G_TEXTURE_GEN_LINEAR | G_LOD | G_SHADING_SMOOTH),
909 gsSPSetGeometryMode(G_ZBUFFER | G_SHADE | G_LIGHTING | G_SHADING_SMOOTH),
910 gsSPEndDisplayList(),
911};
912
913// RENDER_MODE_IDX_18: RENDER_MODE_SURFACE_XLU, RENDER_CLASS_2CYC
915 gsDPSetRenderMode(G_RM_PASS, G_RM_AA_ZB_XLU_SURF2),
916 gsDPSetCycleType(G_CYC_2CYCLE),
917 gsSPClearGeometryMode(G_SHADE | G_CULL_BOTH | G_FOG | G_LIGHTING | G_TEXTURE_GEN | G_TEXTURE_GEN_LINEAR | G_LOD | G_SHADING_SMOOTH),
918 gsSPSetGeometryMode(G_ZBUFFER | G_SHADE | G_LIGHTING | G_SHADING_SMOOTH),
919 gsSPEndDisplayList(),
920};
921
922// RENDER_MODE_IDX_1B: RENDER_MODE_DECAL_XLU, RENDER_CLASS_2CYC
924 gsDPSetRenderMode(G_RM_PASS, G_RM_AA_ZB_XLU_DECAL2),
925 gsDPSetCycleType(G_CYC_2CYCLE),
926 gsSPClearGeometryMode(G_SHADE | G_CULL_BOTH | G_FOG | G_LIGHTING | G_TEXTURE_GEN | G_TEXTURE_GEN_LINEAR | G_LOD | G_SHADING_SMOOTH),
927 gsSPSetGeometryMode(G_ZBUFFER | G_SHADE | G_LIGHTING | G_SHADING_SMOOTH),
928 gsSPEndDisplayList(),
929};
930
931// RENDER_MODE_IDX_1D: RENDER_MODE_INTERSECTING_XLU, RENDER_CLASS_2CYC
933 gsDPSetRenderMode(G_RM_PASS, G_RM_AA_ZB_XLU_INTER2),
934 gsDPSetCycleType(G_CYC_2CYCLE),
935 gsSPClearGeometryMode(G_SHADE | G_CULL_BOTH | G_FOG | G_LIGHTING | G_TEXTURE_GEN | G_TEXTURE_GEN_LINEAR | G_LOD | G_SHADING_SMOOTH),
936 gsSPSetGeometryMode(G_ZBUFFER | G_SHADE | G_LIGHTING | G_SHADING_SMOOTH),
937 gsSPEndDisplayList(),
938};
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
945 gsDPSetRenderMode(G_RM_PASS, G_RM_ZB_OPA_SURF2),
946 gsDPSetCycleType(G_CYC_2CYCLE),
947 gsSPClearGeometryMode(G_SHADE | G_CULL_BOTH | G_FOG | G_LIGHTING | G_TEXTURE_GEN | G_TEXTURE_GEN_LINEAR | G_LOD | G_SHADING_SMOOTH),
948 gsSPSetGeometryMode(G_ZBUFFER | G_SHADE | G_CULL_BACK | G_LIGHTING | G_SHADING_SMOOTH),
949 gsSPEndDisplayList(),
950};
951
952// RENDER_MODE_IDX_13: RENDER_MODE_DECAL_OPA_NO_AA, RENDER_CLASS_2CYC
954 gsDPSetRenderMode(G_RM_PASS, G_RM_ZB_OPA_DECAL2),
955 gsDPSetCycleType(G_CYC_2CYCLE),
956 gsSPClearGeometryMode(G_SHADE | G_CULL_BOTH | G_FOG | G_LIGHTING | G_TEXTURE_GEN | G_TEXTURE_GEN_LINEAR | G_LOD | G_SHADING_SMOOTH),
957 gsSPSetGeometryMode(G_ZBUFFER | G_SHADE | G_CULL_BACK | G_LIGHTING | G_SHADING_SMOOTH),
958 gsSPEndDisplayList(),
959};
960
961// RENDER_MODE_IDX_15: unused
963 gsDPSetRenderMode(G_RM_PASS, G_RM_AA_ZB_OPA_INTER2),
964 gsDPSetCycleType(G_CYC_2CYCLE),
965 gsSPClearGeometryMode(G_SHADE | G_CULL_BOTH | G_FOG | G_LIGHTING | G_TEXTURE_GEN | G_TEXTURE_GEN_LINEAR | G_LOD | G_SHADING_SMOOTH),
966 gsSPSetGeometryMode(G_ZBUFFER | G_SHADE | G_CULL_BACK | G_LIGHTING | G_SHADING_SMOOTH),
967 gsDPSetCombineMode(G_CC_SHADE, G_CC_SHADE),
968 gsSPEndDisplayList(),
969};
970
971// RENDER_MODE_IDX_17: RENDER_MODE_ALPHATEST_ONESIDED, RENDER_CLASS_2CYC
973 gsDPSetRenderMode(G_RM_PASS, G_RM_AA_ZB_TEX_EDGE2),
974 gsDPSetCycleType(G_CYC_2CYCLE),
975 gsSPClearGeometryMode(G_SHADE | G_CULL_BOTH | G_FOG | G_LIGHTING | G_TEXTURE_GEN | G_TEXTURE_GEN_LINEAR | G_LOD | G_SHADING_SMOOTH),
976 gsSPEndDisplayList(),
977};
978
979// RENDER_MODE_IDX_1A: RENDER_MODE_SURFACE_XLU_NO_AA, RENDER_CLASS_2CYC
981 gsDPSetRenderMode(G_RM_PASS, G_RM_ZB_XLU_SURF2),
982 gsDPSetCycleType(G_CYC_2CYCLE),
983 gsSPClearGeometryMode(G_SHADE | G_CULL_BOTH | G_FOG | G_LIGHTING | G_TEXTURE_GEN | G_TEXTURE_GEN_LINEAR | G_LOD | G_SHADING_SMOOTH),
984 gsSPSetGeometryMode(G_ZBUFFER | G_SHADE | G_LIGHTING | G_SHADING_SMOOTH),
985 gsSPEndDisplayList(),
986};
987
988// RENDER_MODE_IDX_1C: RENDER_MODE_DECAL_XLU_NO_AA, RENDER_CLASS_2CYC
990 gsDPSetRenderMode(G_RM_PASS, G_RM_ZB_XLU_DECAL2),
991 gsDPSetCycleType(G_CYC_2CYCLE),
992 gsSPClearGeometryMode(G_SHADE | G_CULL_BOTH | G_FOG | G_LIGHTING | G_TEXTURE_GEN | G_TEXTURE_GEN_LINEAR | G_LOD | G_SHADING_SMOOTH),
993 gsSPSetGeometryMode(G_ZBUFFER | G_SHADE | G_LIGHTING | G_SHADING_SMOOTH),
994 gsSPEndDisplayList(),
995};
996
997// ----------------------------------------------------------------------------
998// RENDER_CLASS_2CYC, special modes
999
1000// RENDER_MODE_IDX_1E: unused
1002 gsDPSetCycleType(G_CYC_2CYCLE),
1003 gsSPClearGeometryMode(G_SHADE | G_CULL_BOTH | G_FOG | G_LIGHTING | G_TEXTURE_GEN | G_TEXTURE_GEN_LINEAR | G_LOD | G_SHADING_SMOOTH),
1004 gsSPSetGeometryMode(G_ZBUFFER | G_SHADE | G_LIGHTING | G_SHADING_SMOOTH),
1005 gsSPEndDisplayList(),
1006};
1007
1008// RENDER_MODE_IDX_19: RENDER_MODE_SURFACE_XLU_AA_ZB_ZUPD, RENDER_CLASS_2CYC
1010 gsDPSetRenderMode(G_RM_PASS, G_RM_AA_ZB_XLU_SURF2),
1011 gsDPSetCycleType(G_CYC_2CYCLE),
1012 gsSPClearGeometryMode(G_SHADE | G_CULL_BOTH | G_FOG | G_LIGHTING | G_TEXTURE_GEN | G_TEXTURE_GEN_LINEAR | G_LOD | G_SHADING_SMOOTH),
1013 gsSPSetGeometryMode(G_ZBUFFER | G_SHADE | G_LIGHTING | G_SHADING_SMOOTH),
1014 gsSPEndDisplayList(),
1015};
1016
1017// RENDER_MODE_IDX_31: RENDER_MODE_SURFACE_OPA_NO_ZB, RENDER_CLASS_2CYC
1019 gsDPSetRenderMode(G_RM_PASS, G_RM_AA_OPA_SURF2),
1020 gsDPSetCycleType(G_CYC_2CYCLE),
1021 gsSPClearGeometryMode(G_ZBUFFER | G_SHADE | G_CULL_BOTH | G_FOG | G_LIGHTING | G_TEXTURE_GEN | G_TEXTURE_GEN_LINEAR | G_LOD | G_SHADING_SMOOTH),
1022 gsSPSetGeometryMode(G_SHADE | G_CULL_BACK | G_LIGHTING | G_SHADING_SMOOTH),
1023 gsSPEndDisplayList(),
1024};
1025
1026// RENDER_MODE_IDX_32: RENDER_MODE_ALPHATEST_NO_ZB, RENDER_CLASS_2CYC
1028 gsDPSetRenderMode(G_RM_PASS, G_RM_AA_TEX_EDGE2),
1029 gsDPSetCycleType(G_CYC_2CYCLE),
1030 gsSPClearGeometryMode(G_ZBUFFER | G_SHADE | G_CULL_BOTH | G_FOG | G_LIGHTING | G_TEXTURE_GEN | G_TEXTURE_GEN_LINEAR | G_LOD | G_SHADING_SMOOTH),
1031 gsSPSetGeometryMode(G_SHADE | G_LIGHTING | G_SHADING_SMOOTH),
1032 gsSPEndDisplayList(),
1033};
1034
1035// RENDER_MODE_IDX_33: RENDER_MODE_SURFACE_XLU_NO_ZB, RENDER_CLASS_2CYC
1037 gsDPSetRenderMode(G_RM_PASS, G_RM_AA_XLU_SURF2),
1038 gsDPSetCycleType(G_CYC_2CYCLE),
1039 gsSPClearGeometryMode(G_ZBUFFER | G_SHADE | G_CULL_BOTH | G_FOG | G_LIGHTING | G_TEXTURE_GEN | G_TEXTURE_GEN_LINEAR | G_LOD | G_SHADING_SMOOTH),
1040 gsSPSetGeometryMode(G_SHADE | G_LIGHTING | G_SHADING_SMOOTH),
1041 gsSPEndDisplayList(),
1042};
1043
1044// RENDER_MODE_IDX_39: RENDER_MODE_CLOUD, RENDER_CLASS_2CYC
1046 gsDPSetRenderMode(G_RM_PASS, G_RM_ZB_CLD_SURF2),
1047 gsDPSetCycleType(G_CYC_2CYCLE),
1048 gsSPClearGeometryMode(G_SHADE | G_CULL_BOTH | G_FOG | G_LIGHTING | G_TEXTURE_GEN | G_TEXTURE_GEN_LINEAR | G_LOD | G_SHADING_SMOOTH),
1049 gsSPSetGeometryMode(G_ZBUFFER | G_SHADE | G_LIGHTING | G_SHADING_SMOOTH),
1050 gsSPEndDisplayList(),
1051};
1052
1053// RENDER_MODE_IDX_3A: RENDER_MODE_CLOUD_NO_ZB, RENDER_CLASS_2CYC
1055 gsDPSetRenderMode(G_RM_PASS, G_RM_CLD_SURF2),
1056 gsDPSetCycleType(G_CYC_2CYCLE),
1057 gsSPClearGeometryMode(G_SHADE | G_CULL_BOTH | G_FOG | G_LIGHTING | G_TEXTURE_GEN | G_TEXTURE_GEN_LINEAR | G_LOD | G_SHADING_SMOOTH),
1058 gsSPSetGeometryMode(G_ZBUFFER | G_SHADE | G_LIGHTING | G_SHADING_SMOOTH),
1059 gsSPEndDisplayList(),
1060};
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
1068 gsDPSetRenderMode(G_RM_FOG_SHADE_A, G_RM_AA_ZB_OPA_SURF2),
1069 gsDPSetCycleType(G_CYC_2CYCLE),
1070 gsSPClearGeometryMode(G_SHADE | G_CULL_BOTH | G_FOG | G_LIGHTING | G_TEXTURE_GEN | G_TEXTURE_GEN_LINEAR | G_LOD | G_SHADING_SMOOTH),
1071 gsSPSetGeometryMode(G_ZBUFFER | G_SHADE | G_CULL_BACK | G_FOG | G_LIGHTING | G_SHADING_SMOOTH),
1072 gsSPEndDisplayList(),
1073};
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
1078 gsDPSetRenderMode(G_RM_FOG_SHADE_A, G_RM_AA_ZB_OPA_DECAL2),
1079 gsDPSetCycleType(G_CYC_2CYCLE),
1080 gsSPClearGeometryMode(G_SHADE | G_CULL_BOTH | G_FOG | G_LIGHTING | G_TEXTURE_GEN | G_TEXTURE_GEN_LINEAR | G_LOD | G_SHADING_SMOOTH),
1081 gsSPSetGeometryMode(G_ZBUFFER | G_SHADE | G_CULL_BACK | G_FOG | G_LIGHTING | G_SHADING_SMOOTH),
1082 gsSPEndDisplayList(),
1083};
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
1088 gsDPSetRenderMode(G_RM_FOG_SHADE_A, G_RM_AA_ZB_OPA_INTER2),
1089 gsDPSetCycleType(G_CYC_2CYCLE),
1090 gsSPClearGeometryMode(G_SHADE | G_CULL_BOTH | G_FOG | G_LIGHTING | G_TEXTURE_GEN | G_TEXTURE_GEN_LINEAR | G_LOD | G_SHADING_SMOOTH),
1091 gsSPSetGeometryMode(G_ZBUFFER | G_SHADE | G_CULL_BACK | G_FOG | G_LIGHTING | G_SHADING_SMOOTH),
1092 gsSPEndDisplayList(),
1093};
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
1098 gsDPSetRenderMode(G_RM_FOG_SHADE_A, G_RM_AA_ZB_TEX_EDGE2),
1099 gsDPSetCycleType(G_CYC_2CYCLE),
1100 gsSPClearGeometryMode(G_SHADE | G_CULL_BOTH | G_FOG | G_LIGHTING | G_TEXTURE_GEN | G_TEXTURE_GEN_LINEAR | G_LOD | G_SHADING_SMOOTH),
1101 gsSPSetGeometryMode(G_ZBUFFER | G_SHADE | G_FOG | G_LIGHTING | G_SHADING_SMOOTH),
1102 gsSPEndDisplayList(),
1103};
1104
1105// RENDER_MODE_IDX_27: RENDER_MODE_SURFACE_XLU, RENDER_CLASS_FOG / RENDER_CLASS_FOG_SHROUD
1106// used by entity models
1108 gsDPSetRenderMode(G_RM_FOG_SHADE_A, G_RM_AA_ZB_XLU_SURF2),
1109 gsDPSetCycleType(G_CYC_2CYCLE),
1110 gsSPClearGeometryMode(G_SHADE | G_CULL_BOTH | G_FOG | G_LIGHTING | G_TEXTURE_GEN | G_TEXTURE_GEN_LINEAR | G_LOD | G_SHADING_SMOOTH),
1111 gsSPSetGeometryMode(G_ZBUFFER | G_SHADE | G_FOG | G_LIGHTING | G_SHADING_SMOOTH),
1112 gsSPEndDisplayList(),
1113};
1114
1115// RENDER_MODE_IDX_2A: RENDER_MODE_DECAL_XLU, RENDER_CLASS_FOG / RENDER_CLASS_FOG_SHROUD
1116// used by entity models
1118 gsDPSetRenderMode(G_RM_FOG_SHADE_A, G_RM_AA_ZB_XLU_DECAL2),
1119 gsDPSetCycleType(G_CYC_2CYCLE),
1120 gsSPClearGeometryMode(G_SHADE | G_CULL_BOTH | G_FOG | G_LIGHTING | G_TEXTURE_GEN | G_TEXTURE_GEN_LINEAR | G_LOD | G_SHADING_SMOOTH),
1121 gsSPSetGeometryMode(G_ZBUFFER | G_SHADE | G_FOG | G_LIGHTING | G_SHADING_SMOOTH),
1122 gsSPEndDisplayList(),
1123};
1124
1125// RENDER_MODE_IDX_2C: RENDER_MODE_INTERSECTING_XLU, RENDER_CLASS_FOG / RENDER_CLASS_FOG_SHROUD
1126// used by entity models
1128 gsDPSetRenderMode(G_RM_FOG_SHADE_A, G_RM_AA_ZB_XLU_INTER2),
1129 gsDPSetCycleType(G_CYC_2CYCLE),
1130 gsSPClearGeometryMode(G_SHADE | G_CULL_BOTH | G_FOG | G_LIGHTING | G_TEXTURE_GEN | G_TEXTURE_GEN_LINEAR | G_LOD | G_SHADING_SMOOTH),
1131 gsSPSetGeometryMode(G_ZBUFFER | G_SHADE | G_FOG | G_LIGHTING | G_SHADING_SMOOTH),
1132 gsSPEndDisplayList(),
1133};
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
1140 gsDPSetRenderMode(G_RM_FOG_SHADE_A, G_RM_ZB_OPA_SURF2),
1141 gsDPSetCycleType(G_CYC_2CYCLE),
1142 gsSPClearGeometryMode(G_SHADE | G_CULL_BOTH | G_FOG | G_LIGHTING | G_TEXTURE_GEN | G_TEXTURE_GEN_LINEAR | G_LOD | G_SHADING_SMOOTH),
1143 gsSPSetGeometryMode(G_ZBUFFER | G_SHADE | G_CULL_BACK | G_FOG | G_LIGHTING | G_SHADING_SMOOTH),
1144 gsSPEndDisplayList(),
1145};
1146
1147// RENDER_MODE_IDX_22: RENDER_MODE_DECAL_OPA_NO_AA, RENDER_CLASS_FOG / RENDER_CLASS_FOG_SHROUD
1149 gsDPSetRenderMode(G_RM_FOG_SHADE_A, G_RM_ZB_OPA_DECAL2),
1150 gsDPSetCycleType(G_CYC_2CYCLE),
1151 gsSPClearGeometryMode(G_SHADE | G_CULL_BOTH | G_FOG | G_LIGHTING | G_TEXTURE_GEN | G_TEXTURE_GEN_LINEAR | G_LOD | G_SHADING_SMOOTH),
1152 gsSPSetGeometryMode(G_ZBUFFER | G_SHADE | G_CULL_BACK | G_FOG | G_LIGHTING | G_SHADING_SMOOTH),
1153 gsSPEndDisplayList(),
1154};
1155
1156// RENDER_MODE_IDX_24: unused
1158 gsDPSetRenderMode(G_RM_FOG_SHADE_A, G_RM_AA_ZB_OPA_INTER2),
1159 gsDPSetCycleType(G_CYC_2CYCLE),
1160 gsSPClearGeometryMode(G_SHADE | G_CULL_BOTH | G_FOG | G_LIGHTING | G_TEXTURE_GEN | G_TEXTURE_GEN_LINEAR | G_LOD | G_SHADING_SMOOTH),
1161 gsSPSetGeometryMode(G_ZBUFFER | G_SHADE | G_CULL_BACK | G_FOG | G_LIGHTING | G_SHADING_SMOOTH),
1162 gsSPEndDisplayList(),
1163};
1164
1165// RENDER_MODE_IDX_26: RENDER_MODE_ALPHATEST_ONESIDED, RENDER_CLASS_FOG / RENDER_CLASS_FOG_SHROUD
1167 gsDPSetRenderMode(G_RM_FOG_SHADE_A, G_RM_AA_ZB_TEX_EDGE2),
1168 gsDPSetCycleType(G_CYC_2CYCLE),
1169 gsSPClearGeometryMode(G_SHADE | G_CULL_BOTH | G_FOG | G_LIGHTING | G_TEXTURE_GEN | G_TEXTURE_GEN_LINEAR | G_LOD | G_SHADING_SMOOTH),
1170 gsSPEndDisplayList(),
1171};
1172
1173// RENDER_MODE_IDX_29: RENDER_MODE_SURFACE_XLU_NO_AA, RENDER_CLASS_FOG / RENDER_CLASS_FOG_SHROUD
1175 gsDPSetRenderMode(G_RM_FOG_SHADE_A, G_RM_ZB_XLU_SURF2),
1176 gsDPSetCycleType(G_CYC_2CYCLE),
1177 gsSPClearGeometryMode(G_SHADE | G_CULL_BOTH | G_FOG | G_LIGHTING | G_TEXTURE_GEN | G_TEXTURE_GEN_LINEAR | G_LOD | G_SHADING_SMOOTH),
1178 gsSPSetGeometryMode(G_ZBUFFER | G_SHADE | G_FOG | G_LIGHTING | G_SHADING_SMOOTH),
1179 gsSPEndDisplayList(),
1180};
1181
1182// RENDER_MODE_IDX_2B: RENDER_MODE_DECAL_XLU_NO_AA, RENDER_CLASS_FOG / RENDER_CLASS_FOG_SHROUD
1184 gsDPSetRenderMode(G_RM_FOG_SHADE_A, G_RM_ZB_XLU_DECAL2),
1185 gsDPSetCycleType(G_CYC_2CYCLE),
1186 gsSPClearGeometryMode(G_SHADE | G_CULL_BOTH | G_FOG | G_LIGHTING | G_TEXTURE_GEN | G_TEXTURE_GEN_LINEAR | G_LOD | G_SHADING_SMOOTH),
1187 gsSPSetGeometryMode(G_ZBUFFER | G_SHADE | G_FOG | G_LIGHTING | G_SHADING_SMOOTH),
1188 gsSPEndDisplayList(),
1189};
1190
1191// ----------------------------------------------------------------------------
1192// RENDER_CLASS_FOG+, special modes
1193
1194// RENDER_MODE_IDX_2D: unused
1196 gsDPSetCycleType(G_CYC_2CYCLE),
1197 gsSPClearGeometryMode(G_SHADE | G_CULL_BOTH | G_FOG | G_LIGHTING | G_TEXTURE_GEN | G_TEXTURE_GEN_LINEAR | G_LOD | G_SHADING_SMOOTH),
1198 gsSPSetGeometryMode(G_ZBUFFER | G_SHADE | G_FOG | G_LIGHTING | G_SHADING_SMOOTH),
1199 gsSPEndDisplayList(),
1200};
1201
1202// RENDER_MODE_IDX_28: RENDER_MODE_SURFACE_XLU_AA_ZB_ZUPD, RENDER_CLASS_FOG / RENDER_CLASS_FOG_SHROUD
1204 gsDPSetRenderMode(G_RM_FOG_SHADE_A, G_RM_AA_ZB_XLU_SURF2),
1205 gsDPSetCycleType(G_CYC_2CYCLE),
1206 gsSPClearGeometryMode(G_SHADE | G_CULL_BOTH | G_FOG | G_LIGHTING | G_TEXTURE_GEN | G_TEXTURE_GEN_LINEAR | G_LOD | G_SHADING_SMOOTH),
1207 gsSPSetGeometryMode(G_ZBUFFER | G_SHADE | G_FOG | G_LIGHTING | G_SHADING_SMOOTH),
1208 gsSPEndDisplayList(),
1209};
1210
1211// RENDER_MODE_IDX_34: RENDER_MODE_SURFACE_OPA_NO_ZB, RENDER_CLASS_FOG / RENDER_CLASS_FOG_SHROUD
1213 gsDPSetRenderMode(G_RM_FOG_SHADE_A, G_RM_AA_OPA_SURF2),
1214 gsDPSetCycleType(G_CYC_2CYCLE),
1215 gsSPClearGeometryMode(G_ZBUFFER | G_SHADE | G_CULL_BOTH | G_FOG | G_LIGHTING | G_TEXTURE_GEN | G_TEXTURE_GEN_LINEAR | G_LOD | G_SHADING_SMOOTH),
1216 gsSPSetGeometryMode(G_SHADE | G_CULL_BACK | G_FOG | G_LIGHTING | G_SHADING_SMOOTH),
1217 gsSPEndDisplayList(),
1218};
1219
1220// RENDER_MODE_IDX_35: RENDER_MODE_ALPHATEST_NO_ZB, RENDER_CLASS_FOG / RENDER_CLASS_FOG_SHROUD
1222 gsDPSetRenderMode(G_RM_FOG_SHADE_A, G_RM_AA_TEX_EDGE2),
1223 gsDPSetCycleType(G_CYC_2CYCLE),
1224 gsSPClearGeometryMode(G_ZBUFFER | G_SHADE | G_CULL_BOTH | G_FOG | G_LIGHTING | G_TEXTURE_GEN | G_TEXTURE_GEN_LINEAR | G_LOD | G_SHADING_SMOOTH),
1225 gsSPSetGeometryMode(G_SHADE | G_FOG | G_LIGHTING | G_SHADING_SMOOTH),
1226 gsSPEndDisplayList(),
1227};
1228
1229// RENDER_MODE_IDX_36: RENDER_MODE_SURFACE_XLU_NO_ZB, RENDER_CLASS_FOG / RENDER_CLASS_FOG_SHROUD
1231 gsDPSetRenderMode(G_RM_FOG_SHADE_A, G_RM_AA_XLU_SURF2),
1232 gsDPSetCycleType(G_CYC_2CYCLE),
1233 gsSPClearGeometryMode(G_ZBUFFER | G_SHADE | G_CULL_BOTH | G_FOG | G_LIGHTING | G_TEXTURE_GEN | G_TEXTURE_GEN_LINEAR | G_LOD | G_SHADING_SMOOTH),
1234 gsSPSetGeometryMode(G_SHADE | G_FOG | G_LIGHTING | G_SHADING_SMOOTH),
1235 gsSPEndDisplayList(),
1236};
1237
1238// RENDER_MODE_IDX_3B: RENDER_MODE_CLOUD, RENDER_CLASS_FOG / RENDER_CLASS_FOG_SHROUD / RENDER_CLASS_1CYC_SHROUD / RENDER_CLASS_1CYC_DEPTH
1240 gsDPSetRenderMode(G_RM_FOG_SHADE_A, G_RM_ZB_CLD_SURF2),
1241 gsDPSetCycleType(G_CYC_2CYCLE),
1242 gsSPClearGeometryMode(G_SHADE | G_CULL_BOTH | G_FOG | G_LIGHTING | G_TEXTURE_GEN | G_TEXTURE_GEN_LINEAR | G_LOD | G_SHADING_SMOOTH),
1243 gsSPSetGeometryMode(G_ZBUFFER | G_SHADE | G_LIGHTING | G_SHADING_SMOOTH),
1244 gsSPEndDisplayList(),
1245};
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
1249 gsDPSetRenderMode(G_RM_FOG_SHADE_A, G_RM_CLD_SURF2),
1250 gsDPSetCycleType(G_CYC_2CYCLE),
1251 gsSPClearGeometryMode(G_SHADE | G_CULL_BOTH | G_FOG | G_LIGHTING | G_TEXTURE_GEN | G_TEXTURE_GEN_LINEAR | G_LOD | G_SHADING_SMOOTH),
1252 gsSPSetGeometryMode(G_ZBUFFER | G_SHADE | G_LIGHTING | G_SHADING_SMOOTH),
1253 gsSPEndDisplayList(),
1254};
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
1312BSS TextureHeader gCurrentTextureHeader ALIGNED(16);
1313
1316
1319
1322
1328
1333
1354
1356
1357extern Addr BattleEntityHeapBottom; // todo ???
1358
1359void func_80117D00(Model* model);
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);
1364void load_model_transforms(ModelNode* model, ModelNode* parent, Matrix4f mdlTxMtx, s32 treeDepth);
1365s32 is_identity_fixed_mtx(Mtx* mtx);
1366void build_custom_gfx(void);
1367
1368void appendGfx_model(void* data) {
1369 Model* model = data;
1370 s32 mtxPushMode;
1371 TextureHandle* textureHandle;
1372 TextureHeader* textureHeader;
1373 u32 extraTileType;
1374 s8 renderMode;
1375 s32 renderClass;
1376 s32 renderModeIdx;
1377 s32 flags = model->flags;
1378
1379 ModelNode* modelNode;
1380 u16 customGfxIndex;
1381 s32 mtxLoadMode;
1382 s32 tintCombineType;
1383 ModelNodeProperty* prop;
1384 s32 temp;
1385
1386 s32 fogMin, fogMax;
1387 s32 fogR, fogG, fogB, fogA;
1388 Gfx** gfxPos = &gMainGfxPos;
1389
1390 mtxPushMode = G_MTX_PUSH;
1391 mtxLoadMode = G_MTX_LOAD;
1392 modelNode = model->modelNode;
1393
1394 if (model->textureID != 0) {
1395 textureHandle = &TextureHandles[model->textureID + model->textureVariation];
1396 textureHeader = &textureHandle->header;
1397
1398 if (textureHandle->gfx != NULL) {
1399 extraTileType = textureHandle->header.extraTiles;
1400 } else {
1401 textureHeader = NULL;
1402 }
1403 } else {
1404 textureHandle = NULL;
1405 textureHeader = NULL;
1406 }
1407
1408 renderMode = model->renderMode;
1409 tintCombineType = 0;
1410
1411 if (textureHeader != NULL) {
1412 switch (extraTileType) {
1413 case EXTRA_TILE_NONE:
1414 renderClass = RENDER_CLASS_1CYC;
1415 break;
1416 case EXTRA_TILE_MIPMAPS:
1419 renderClass = RENDER_CLASS_2CYC;
1420 break;
1421 default:
1422 renderClass = RENDER_CLASS_1CYC;
1423 break;
1424 }
1425 } else {
1426 renderClass = RENDER_CLASS_1CYC;
1427 }
1428
1429 if (textureHeader != NULL || renderMode <= RENDER_MODES_LAST_OPAQUE) {
1431 renderClass = RENDER_CLASS_FOG;
1432 tintCombineType = TINT_COMBINE_FOG;
1433 }
1434 }
1435
1436 // if a model has a tint applied, set it up now
1437 switch ((u32)(model->customGfxIndex >> 4)) {
1438 case ENV_TINT_SHROUD:
1440 tintCombineType = TINT_COMBINE_SHROUD;
1441 break;
1442 case ENV_TINT_DEPTH:
1443 if (renderMode <= RENDER_MODES_LAST_OPAQUE) {
1444 gDPSetPrimColor((*gfxPos)++, 0, 0, DepthTintBaseR, DepthTintBaseG, DepthTintBaseB, DepthTintBaseA);
1445 gDPSetFogColor((*gfxPos)++, DepthTintColR, DepthTintColG, DepthTintColB, 0);
1446 gSPFogPosition((*gfxPos)++, DepthTintStart, DepthTintEnd);
1447 renderClass += (RENDER_CLASS_1CYC_DEPTH - RENDER_CLASS_1CYC);
1448 tintCombineType = TINT_COMBINE_DEPTH;
1449 }
1450 break;
1451 case ENV_TINT_REMAP:
1452 renderClass = RENDER_CLASS_2CYC;
1453 tintCombineType = TINT_COMBINE_REMAP;
1454 gDPSetPrimColor((*gfxPos)++, 0, 0, RemapTintMaxR, RemapTintMaxG, RemapTintMaxB, 255);
1455 gDPSetEnvColor((*gfxPos)++, RemapTintMinR, RemapTintMinG, RemapTintMinB, 255);
1456 break;
1457 }
1458
1459 gDPPipeSync((*gfxPos)++);
1460
1461 if (model->groupData != NULL) {
1462 Lightsn* lights = model->groupData->lightingGroup;
1463 if (model->groupData->lightingGroup != NULL) {
1464 switch (model->groupData->numLights) {
1465 case 0:
1466 gSPSetLights0((*gfxPos)++, lights[0]);
1467 break;
1468 case 1:
1469 gSPSetLights1((*gfxPos)++, lights[0]);
1470 break;
1471 case 2:
1472 gSPSetLights2((*gfxPos)++, lights[0]);
1473 break;
1474 case 3:
1475 gSPSetLights3((*gfxPos)++, lights[0]);
1476 break;
1477 case 4:
1478 gSPSetLights4((*gfxPos)++, lights[0]);
1479 break;
1480 case 5:
1481 gSPSetLights5((*gfxPos)++, lights[0]);
1482 break;
1483 case 6:
1484 gSPSetLights6((*gfxPos)++, lights[0]);
1485 break;
1486 case 7:
1487 gSPSetLights7((*gfxPos)++, lights[0]);
1488 break;
1489 }
1490 }
1491 }
1492
1493 if (textureHeader != NULL) {
1494 switch (extraTileType) {
1496 case EXTRA_TILE_4:
1497 prop = get_model_property(modelNode, MODEL_PROP_KEY_SPECIAL);
1498 if (prop != NULL) {
1499 s32 shift = prop->data.s;
1500 u16 offsetS = prop->dataType;
1501 s32 offsetT = prop->dataType;
1502 make_texture_gfx(textureHeader, gfxPos,
1503 textureHandle->raster, textureHandle->palette,
1504 textureHandle->auxRaster, textureHandle->auxPalette,
1505 (shift >> 12) & 0xF, (shift >> 16) & 0xF,
1506 offsetS & 0xFFF, (offsetT >> 12) & 0xFFF);
1507
1508 } else {
1509 gSPDisplayList((*gfxPos)++, textureHandle->gfx);
1510 }
1511 break;
1512 default:
1513 gSPDisplayList((*gfxPos)++, textureHandle->gfx);
1514 break;
1515 }
1516 } else {
1517 gSPTexture((*gfxPos)++, 0, 0, 0, G_TX_RENDERTILE, G_OFF);
1518 gDPSetCombineMode((*gfxPos)++, G_CC_SHADE, G_CC_SHADE);
1519 gDPSetColorDither((*gfxPos)++, G_CD_MAGICSQ);
1520 gDPSetAlphaDither((*gfxPos)++, G_AD_PATTERN);
1521 }
1522
1523 // setup combine modes for main/aux texture blending when fog or tint is enabled
1524 if (tintCombineType != TINT_COMBINE_NONE
1525 || renderMode == RENDER_MODE_ALPHATEST
1526 || renderMode == RENDER_MODE_ALPHATEST_ONESIDED
1527 ) {
1528 u32 texCombineType = TEX_COMBINE_NOTEX;
1529
1530 // only the following aux combine modes are ever used:
1531 // (A) 0x00 -> 0, 0
1532 // (B) 0x08 -> 2, 0
1533 // (C) 0x0D -> 3, 1
1534 // (D) 0x10 -> 4, 0
1535 if (textureHeader != NULL) {
1536 u32 auxCombineType = textureHeader->auxCombineType;
1537 if (auxCombineType >= 3) {
1538 // combine modes 3, 4, ... are directly appended to the end of the table and subtype is ignored
1539 texCombineType = TEX_COMBINE_3 + (auxCombineType - 3);
1540 } else {
1541 // select based on aux combine subtypes
1542 // in practice, auxCombineSubType is ALWAYS zero here since the only (A) and (B) may reach this block
1543 texCombineType = 1 + extraTileType * AUX_COMBINE_SUB_COUNT + textureHeader->auxCombineSubType;
1544 }
1545 }
1546
1547 if (!(renderMode == RENDER_MODE_ALPHATEST || renderMode == RENDER_MODE_ALPHATEST_ONESIDED)) {
1548 *(*gfxPos) = SolidCombineModes[texCombineType][tintCombineType];
1549 } else {
1550 *(*gfxPos) = AlphaTestCombineModes[texCombineType][tintCombineType];
1551 }
1552 (*gfxPos)++;
1553 }
1554
1555 // setup geometry modes and render modes
1556 switch (renderClass) {
1557 case RENDER_CLASS_1CYC:
1558 switch (renderMode) {
1560 renderModeIdx = RENDER_MODE_IDX_00;
1561 break;
1563 renderModeIdx = RENDER_MODE_IDX_01;
1564 break;
1566 renderModeIdx = RENDER_MODE_IDX_02;
1567 break;
1569 renderModeIdx = RENDER_MODE_IDX_03;
1570 break;
1572 renderModeIdx = RENDER_MODE_IDX_04;
1573 break;
1575 renderModeIdx = RENDER_MODE_IDX_06;
1576 break;
1578 renderModeIdx = RENDER_MODE_IDX_07;
1579 break;
1581 renderModeIdx = RENDER_MODE_IDX_09;
1582 break;
1586 renderModeIdx = RENDER_MODE_IDX_08;
1587 break;
1589 renderModeIdx = RENDER_MODE_IDX_0A;
1590 break;
1592 renderModeIdx = RENDER_MODE_IDX_0B;
1593 break;
1595 renderModeIdx = RENDER_MODE_IDX_0C;
1596 break;
1598 renderModeIdx = RENDER_MODE_IDX_0D;
1599 break;
1601 renderModeIdx = RENDER_MODE_IDX_0E;
1602 break;
1604 renderModeIdx = RENDER_MODE_IDX_2E;
1605 break;
1607 renderModeIdx = RENDER_MODE_IDX_2F;
1608 break;
1610 renderModeIdx = RENDER_MODE_IDX_30;
1611 break;
1612 case RENDER_MODE_CLOUD:
1613 renderModeIdx = RENDER_MODE_IDX_37;
1614 break;
1616 renderModeIdx = RENDER_MODE_IDX_38;
1617 break;
1618 default:
1619 renderModeIdx = RENDER_MODE_IDX_00;
1620 break;
1621 }
1622 gSPDisplayList((*gfxPos)++, ModelRenderModes[renderModeIdx]);
1623 break;
1624 case RENDER_CLASS_2CYC:
1625 switch (renderMode) {
1627 renderModeIdx = RENDER_MODE_IDX_10;
1628 break;
1630 renderModeIdx = RENDER_MODE_IDX_11;
1631 break;
1633 renderModeIdx = RENDER_MODE_IDX_12;
1634 break;
1636 renderModeIdx = RENDER_MODE_IDX_13;
1637 break;
1639 renderModeIdx = RENDER_MODE_IDX_14;
1640 break;
1642 renderModeIdx = RENDER_MODE_IDX_16;
1643 break;
1645 renderModeIdx = RENDER_MODE_IDX_17;
1646 break;
1650 renderModeIdx = RENDER_MODE_IDX_18;
1651 break;
1653 renderModeIdx = RENDER_MODE_IDX_19;
1654 break;
1656 renderModeIdx = RENDER_MODE_IDX_1A;
1657 break;
1659 renderModeIdx = RENDER_MODE_IDX_1B;
1660 break;
1662 renderModeIdx = RENDER_MODE_IDX_1C;
1663 break;
1665 renderModeIdx = RENDER_MODE_IDX_1D;
1666 break;
1668 renderModeIdx = RENDER_MODE_IDX_31;
1669 break;
1671 renderModeIdx = RENDER_MODE_IDX_32;
1672 break;
1674 renderModeIdx = RENDER_MODE_IDX_33;
1675 break;
1676 case RENDER_MODE_CLOUD:
1677 renderModeIdx = RENDER_MODE_IDX_39;
1678 break;
1680 renderModeIdx = RENDER_MODE_IDX_3A;
1681 break;
1682 default:
1683 renderModeIdx = RENDER_MODE_IDX_10;
1684 break;
1685 }
1686 gSPDisplayList((*gfxPos)++, ModelRenderModes[renderModeIdx]);
1687 break;
1688 case RENDER_CLASS_FOG:
1689 switch (renderMode) {
1691 renderModeIdx = RENDER_MODE_IDX_1F;
1692 break;
1694 renderModeIdx = RENDER_MODE_IDX_20;
1695 break;
1697 renderModeIdx = RENDER_MODE_IDX_21;
1698 break;
1700 renderModeIdx = RENDER_MODE_IDX_22;
1701 break;
1703 renderModeIdx = RENDER_MODE_IDX_23;
1704 break;
1706 renderModeIdx = RENDER_MODE_IDX_25;
1707 break;
1709 renderModeIdx = RENDER_MODE_IDX_26;
1710 break;
1714 renderModeIdx = RENDER_MODE_IDX_27;
1715 break;
1717 renderModeIdx = RENDER_MODE_IDX_28;
1718 break;
1720 renderModeIdx = RENDER_MODE_IDX_29;
1721 break;
1723 renderModeIdx = RENDER_MODE_IDX_2A;
1724 break;
1726 renderModeIdx = RENDER_MODE_IDX_2B;
1727 break;
1729 renderModeIdx = RENDER_MODE_IDX_2C;
1730 break;
1732 renderModeIdx = RENDER_MODE_IDX_34;
1733 break;
1735 renderModeIdx = RENDER_MODE_IDX_35;
1736 break;
1738 renderModeIdx = RENDER_MODE_IDX_36;
1739 break;
1740 case RENDER_MODE_CLOUD:
1741 renderModeIdx = RENDER_MODE_IDX_3B;
1742 break;
1744 renderModeIdx = RENDER_MODE_IDX_3C;
1745 break;
1746 default:
1747 renderModeIdx = RENDER_MODE_IDX_1F;
1748 break;
1749 }
1750 gSPDisplayList((*gfxPos)++, ModelRenderModes[renderModeIdx]);
1751 gDPSetFogColor((*gfxPos)++, gFogSettings->color.r, gFogSettings->color.g, gFogSettings->color.b, gFogSettings->color.a);
1752 gSPFogPosition((*gfxPos)++, gFogSettings->startDistance, gFogSettings->endDistance);
1753 break;
1756 if (ShroudTintAmt == 255) {
1757 return;
1758 }
1759 gSPDisplayList((*gfxPos)++, ModelRenderModes[RENDER_MODE_IDX_10]);
1760 switch (renderMode) {
1762 gDPSetRenderMode(gMainGfxPos++, PM_RM_SHROUD, G_RM_AA_ZB_OPA_SURF2);
1763 break;
1765 gDPSetRenderMode(gMainGfxPos++, PM_RM_SHROUD, G_RM_ZB_OPA_SURF2);
1766 break;
1768 gDPSetRenderMode(gMainGfxPos++, PM_RM_SHROUD, G_RM_AA_ZB_OPA_DECAL2);
1769 break;
1771 gDPSetRenderMode(gMainGfxPos++, PM_RM_SHROUD, G_RM_ZB_OPA_DECAL2);
1772 break;
1774 gDPSetRenderMode(gMainGfxPos++, PM_RM_SHROUD, G_RM_AA_ZB_OPA_INTER2);
1775 break;
1777 gDPSetRenderMode(gMainGfxPos++, PM_RM_SHROUD, G_RM_AA_ZB_TEX_EDGE2);
1778 break;
1780 gDPSetRenderMode(gMainGfxPos++, PM_RM_SHROUD, G_RM_AA_ZB_TEX_EDGE2);
1781 break;
1783 gDPSetRenderMode(gMainGfxPos++, PM_RM_SHROUD, G_RM_AA_ZB_XLU_SURF2);
1784 break;
1786 gDPSetRenderMode(gMainGfxPos++, PM_RM_SHROUD, G_RM_AA_ZB_XLU_SURF2);
1787 break;
1789 gDPSetRenderMode(gMainGfxPos++, PM_RM_SHROUD, G_RM_AA_ZB_XLU_SURF2);
1790 break;
1792 gDPSetRenderMode(gMainGfxPos++, PM_RM_SHROUD, G_RM_ZB_XLU_SURF2);
1793 break;
1795 gDPSetRenderMode(gMainGfxPos++, PM_RM_SHROUD, G_RM_AA_ZB_XLU_DECAL2);
1796 break;
1798 gDPSetRenderMode(gMainGfxPos++, PM_RM_SHROUD, G_RM_AA_ZB_XLU_DECAL2);
1799 break;
1801 gDPSetRenderMode(gMainGfxPos++, PM_RM_SHROUD, G_RM_AA_ZB_XLU_INTER2);
1802 break;
1804 gDPSetRenderMode(gMainGfxPos++, PM_RM_SHROUD, G_RM_AA_OPA_SURF2);
1805 break;
1807 gDPSetRenderMode(gMainGfxPos++, PM_RM_SHROUD, G_RM_AA_TEX_EDGE2);
1808 break;
1810 gDPSetRenderMode(gMainGfxPos++, PM_RM_SHROUD, G_RM_AA_XLU_SURF2);
1811 break;
1812 case RENDER_MODE_CLOUD:
1813 gDPSetRenderMode(gMainGfxPos++, PM_RM_SHROUD, G_RM_ZB_CLD_SURF2);
1814 break;
1816 gDPSetRenderMode(gMainGfxPos++, PM_RM_SHROUD, G_RM_CLD_SURF2);
1817 break;
1818 }
1819 gDPSetFogColor((*gfxPos)++, gFogSettings->color.r, gFogSettings->color.g, gFogSettings->color.b, ShroudTintAmt);
1820 gDPSetBlendColor((*gfxPos)++, ShroudTintR, ShroudTintG, ShroudTintB, 255);
1821 gSPFogPosition((*gfxPos)++, 970, 1000);
1822 break;
1824 switch (renderMode) {
1826 renderModeIdx = RENDER_MODE_IDX_1F;
1827 break;
1829 renderModeIdx = RENDER_MODE_IDX_20;
1830 break;
1832 renderModeIdx = RENDER_MODE_IDX_21;
1833 break;
1835 renderModeIdx = RENDER_MODE_IDX_22;
1836 break;
1838 renderModeIdx = RENDER_MODE_IDX_23;
1839 break;
1841 renderModeIdx = RENDER_MODE_IDX_25;
1842 break;
1844 renderModeIdx = RENDER_MODE_IDX_26;
1845 break;
1849 renderModeIdx = RENDER_MODE_IDX_27;
1850 break;
1852 renderModeIdx = RENDER_MODE_IDX_28;
1853 break;
1855 renderModeIdx = RENDER_MODE_IDX_29;
1856 break;
1858 renderModeIdx = RENDER_MODE_IDX_2A;
1859 break;
1861 renderModeIdx = RENDER_MODE_IDX_2B;
1862 break;
1864 renderModeIdx = RENDER_MODE_IDX_2C;
1865 break;
1867 renderModeIdx = RENDER_MODE_IDX_34;
1868 break;
1870 renderModeIdx = RENDER_MODE_IDX_35;
1871 break;
1873 renderModeIdx = RENDER_MODE_IDX_36;
1874 break;
1875 case RENDER_MODE_CLOUD:
1876 renderModeIdx = RENDER_MODE_IDX_3B;
1877 break;
1879 renderModeIdx = RENDER_MODE_IDX_3C;
1880 break;
1881 default:
1882 renderModeIdx = RENDER_MODE_IDX_1F;
1883 break;
1884 }
1885 gSPDisplayList((*gfxPos)++, ModelRenderModes[renderModeIdx]);
1886
1887 // lerp between scene fog and shroud fog based on ShroudTintAmt
1888 fogR = (gFogSettings->color.r * (255 - ShroudTintAmt) + ShroudTintR * ShroudTintAmt) / 255;
1889 fogG = (gFogSettings->color.g * (255 - ShroudTintAmt) + ShroudTintG * ShroudTintAmt) / 255;
1890 fogB = (gFogSettings->color.b * (255 - ShroudTintAmt) + ShroudTintB * ShroudTintAmt) / 255;
1891
1892 fogMin = (gFogSettings->startDistance * (255 - ShroudTintAmt) + 900 * ShroudTintAmt) / 255;
1893 fogMax = (gFogSettings->endDistance * (255 - ShroudTintAmt) + 1000 * ShroudTintAmt) / 255;
1894
1895 gDPSetFogColor(gMainGfxPos++, fogR, fogG, fogB, gFogSettings->color.a);
1896 gSPFogPosition((*gfxPos)++, fogMin, fogMax);
1897 break;
1900 switch (renderMode) {
1902 renderModeIdx = RENDER_MODE_IDX_1F;
1903 break;
1905 renderModeIdx = RENDER_MODE_IDX_21;
1906 break;
1908 renderModeIdx = RENDER_MODE_IDX_23;
1909 break;
1911 renderModeIdx = RENDER_MODE_IDX_25;
1912 break;
1913 case RENDER_MODE_CLOUD:
1914 renderModeIdx = RENDER_MODE_IDX_3B;
1915 break;
1917 renderModeIdx = RENDER_MODE_IDX_3C;
1918 break;
1919 default:
1920 renderModeIdx = RENDER_MODE_IDX_1F;
1921 break;
1922 }
1923 gSPDisplayList((*gfxPos)++, ModelRenderModes[renderModeIdx]);
1924 break;
1925 }
1926
1929 gSPMatrix((*gfxPos)++, model->finalMtx, mtxLoadMode | mtxPushMode | G_MTX_MODELVIEW);
1930 if (mtxPushMode != G_MTX_NOPUSH) {
1931 mtxPushMode = G_MTX_NOPUSH;
1932 }
1933 if (mtxLoadMode != G_MTX_MUL) {
1934 mtxLoadMode = G_MTX_MUL;
1935 }
1936 }
1937 } else {
1938 mtxLoadMode = G_MTX_MUL;
1940 gSPMatrix((*gfxPos)++, model->finalMtx, mtxLoadMode | mtxPushMode | G_MTX_MODELVIEW);
1941 if (mtxPushMode != G_MTX_NOPUSH) {
1942 mtxPushMode = G_MTX_NOPUSH;
1943 }
1944 }
1945 }
1946
1947 // custom gfx 'pre'
1949 customGfxIndex = (model->customGfxIndex & 0xF) * 2;
1950 if ((*gCurrentCustomModelGfxPtr)[customGfxIndex] != NULL) {
1951 gSPDisplayList((*gfxPos)++, (*gCurrentCustomModelGfxPtr)[customGfxIndex]);
1952 }
1953 }
1954
1955 // add tex panner gfx
1956 if (textureHeader != NULL) {
1958 s32 panMainU = texPannerMainU[model->texPannerID] >> 8;
1959 s32 panMainV = texPannerMainV[model->texPannerID] >> 8;
1960 s32 panAuxU = texPannerAuxU[model->texPannerID] >> 8;
1961 s32 panAuxV = texPannerAuxV[model->texPannerID] >> 8;
1962
1963 switch (extraTileType) {
1965 gDPSetTileSize((*gfxPos)++, G_TX_RENDERTILE, panMainU, panMainV, (textureHeader->mainW - 1) * 4 + panMainU, (textureHeader->mainH / 2 - 1) * 4 + panMainV);
1966 gDPSetTileSize((*gfxPos)++, G_TX_RENDERTILE + 1, panAuxU, panAuxV, (textureHeader->mainW - 1) * 4 + panAuxU, (textureHeader->mainH / 2 - 1) * 4 + panAuxV);
1967 break;
1969 gDPSetTileSize((*gfxPos)++, G_TX_RENDERTILE, panMainU, panMainV, (textureHeader->mainW - 1) * 4 + panMainU, (textureHeader->mainH - 1) * 4 + panMainV);
1970 gDPSetTileSize((*gfxPos)++, G_TX_RENDERTILE + 1, panAuxU, panAuxV, (textureHeader->auxW - 1) * 4 + panAuxU, (textureHeader->auxH - 1) * 4 + panAuxV);
1971 break;
1972 default:
1973 gDPSetTileSize((*gfxPos)++, G_TX_RENDERTILE, panMainU, panMainV, (textureHeader->mainW - 1) * 4 + panMainU, (textureHeader->mainH - 1) * 4 + panMainV);
1974 break;
1975 }
1976 }
1977 }
1978
1980 gSPMatrix((*gfxPos)++, gCameras[gCurrentCamID].mtxBillboard, mtxLoadMode | mtxPushMode | G_MTX_MODELVIEW);
1981 if (mtxPushMode != G_MTX_NOPUSH) {
1982 mtxPushMode = G_MTX_NOPUSH;
1983 }
1984 if (mtxLoadMode != G_MTX_MUL) {
1985 mtxLoadMode = G_MTX_MUL;
1986 }
1987 }
1988
1989 // render the model
1991 gSPDisplayList((*gfxPos)++, modelNode->displayData->displayList);
1992 }
1993
1994 // custom gfx 'post'
1996 customGfxIndex++;
1997 if ((*gCurrentCustomModelGfxPtr)[customGfxIndex] != NULL) {
1998 gSPDisplayList((*gfxPos)++, (*gCurrentCustomModelGfxPtr)[customGfxIndex]);
1999 }
2000 }
2001
2002 if (mtxPushMode == G_MTX_NOPUSH) {
2003 gSPPopMatrix((*gfxPos)++, G_MTX_MODELVIEW);
2004 }
2005
2006 gDPPipeSync((*gfxPos)++);
2007}
2008
2009void load_texture_impl(u32 romOffset, TextureHandle* handle, TextureHeader* header, s32 mainSize, s32 mainPalSize, s32 auxSize, s32 auxPalSize) {
2010 Gfx** temp;
2011
2012 // load main img + palette to texture heap
2013 handle->raster = (IMG_PTR) TextureHeapPos;
2014 if (mainPalSize != 0) {
2015 handle->palette = (PAL_PTR) (TextureHeapPos + mainSize);
2016 } else {
2017 handle->palette = NULL;
2018 }
2019 dma_copy((u8*) romOffset, (u8*) (romOffset + mainSize + mainPalSize), TextureHeapPos);
2020 romOffset += mainSize + mainPalSize;
2021 TextureHeapPos += mainSize + mainPalSize;
2022
2023 // load aux img + palette to texture heap
2024 if (auxSize != 0) {
2025 handle->auxRaster = (IMG_PTR) TextureHeapPos;
2026 if (auxPalSize != 0) {
2027 handle->auxPalette = (PAL_PTR) (TextureHeapPos + auxSize);
2028 } else {
2029 handle->auxPalette = NULL;
2030 }
2031 dma_copy((u8*) romOffset, (u8*) (romOffset + auxSize + auxPalSize), TextureHeapPos);
2032 TextureHeapPos += auxSize + auxPalSize;
2033 } else {
2034 handle->auxPalette = NULL;
2035 handle->auxRaster = NULL;
2036 }
2037
2038 // copy header data and create a display list for the texture
2039 handle->gfx = (Gfx*) TextureHeapPos;
2040 memcpy(&handle->header, header, sizeof(*header));
2041 make_texture_gfx(header, (Gfx**) &TextureHeapPos, handle->raster, handle->palette, handle->auxRaster, handle->auxPalette, 0, 0, 0, 0);
2042
2043 temp = (Gfx**) &TextureHeapPos;
2044 gSPEndDisplayList((*temp)++);
2045}
2046
2047void load_texture_by_name(ModelNodeProperty* propertyName, s32 romOffset, s32 size) {
2048 char* textureName = (char*)propertyName->data.p;
2049 u32 startOffset = romOffset;
2050 s32 textureIdx = 0;
2051 u32 paletteSize;
2052 u32 rasterSize;
2053 u32 auxPaletteSize;
2054 u32 auxRasterSize;
2055 TextureHeader* header;
2056 TextureHandle* textureHandle;
2057 s32 mainSize;
2058
2059 if (textureName == NULL) {
2060 (*gCurrentModelTreeNodeInfo)[TreeIterPos].textureID = 0;
2061 return;
2062 }
2063
2064 while (romOffset < startOffset + size) {
2065 dma_copy((u8*)romOffset, (u8*)romOffset + sizeof(gCurrentTextureHeader), &gCurrentTextureHeader);
2066 header = &gCurrentTextureHeader;
2067
2068 rasterSize = header->mainW * header->mainH;
2069
2070 // compute mipmaps size
2071 if (header->mainBitDepth == G_IM_SIZ_4b) {
2072 if (header->extraTiles == EXTRA_TILE_MIPMAPS) {
2073 s32 d = 2;
2074 while (header->mainW / d >= 16 && header->mainH / d > 0) {
2075 rasterSize += header->mainW / d * header->mainH / d;
2076 d *= 2;
2077 }
2078 }
2079 rasterSize /= 2;
2080 } else if (header->mainBitDepth == G_IM_SIZ_8b) {
2081 if (header->extraTiles == EXTRA_TILE_MIPMAPS) {
2082 s32 d = 2;
2083 while (header->mainW / d >= 8 && header->mainH / d > 0) {
2084 rasterSize += header->mainW / d * header->mainH / d;
2085 d *= 2;
2086 }
2087 }
2088 } else if (header->mainBitDepth == G_IM_SIZ_16b) {
2089 if (header->extraTiles == EXTRA_TILE_MIPMAPS) {
2090 s32 d = 2;
2091 while (header->mainW / d >= 4 && header->mainH / d > 0) {
2092 rasterSize += header->mainW / d * header->mainH / d;
2093 d *= 2;
2094 }
2095 }
2096 rasterSize *= 2;
2097 } else if (header->mainBitDepth == G_IM_SIZ_32b) {
2098 if (header->extraTiles == EXTRA_TILE_MIPMAPS) {
2099 s32 d = 2;
2100 while (header->mainW / d >= 2 && header->mainH / d > 0) {
2101 rasterSize += header->mainW / d * header->mainH / d;
2102 d *= 2;
2103 }
2104 }
2105 rasterSize *= 4;
2106 }
2107
2108 // compute palette size
2109 if (header->mainFmt == G_IM_FMT_CI) {
2110 paletteSize = 0x20;
2111 if (header->mainBitDepth == G_IM_SIZ_8b) {
2112 paletteSize = 0x200;
2113 }
2114 } else {
2115 paletteSize = 0;
2116 }
2117
2118 // compute aux tile size
2119 if (header->extraTiles == EXTRA_TILE_AUX_INDEPENDENT) {
2120 auxRasterSize = header->auxW * header->auxH;
2121 if (header->auxBitDepth == G_IM_SIZ_4b) {
2122 auxRasterSize /= 2;
2123 } else if (header->auxBitDepth == G_IM_SIZ_8b) {
2124 } else if (header->auxBitDepth == G_IM_SIZ_16b) {
2125 auxRasterSize *= 2;
2126 } else {
2127 if (header->auxBitDepth == G_IM_SIZ_32b) {
2128 auxRasterSize *= 4;
2129 }
2130 }
2131 if (header->auxFmt == G_IM_FMT_CI) {
2132 auxPaletteSize = 0x20;
2133 if (header->auxBitDepth == G_IM_SIZ_8b) {
2134 auxPaletteSize = 0x200;
2135 }
2136 } else {
2137 auxPaletteSize = 0;
2138 }
2139 } else {
2140 auxPaletteSize = 0;
2141 auxRasterSize = 0;
2142 }
2143
2144 if (strcmp(textureName, header->name) == 0) {
2145 // found the texture with `textureName`
2146 break;
2147 }
2148
2149 textureIdx++;
2150 mainSize = rasterSize + paletteSize + sizeof(*header);
2151 romOffset += mainSize;
2152 romOffset += auxRasterSize + auxPaletteSize;
2153 }
2154
2155 if (romOffset >= startOffset + 0x40000) {
2156 // did not find the texture with `textureName`
2157 osSyncPrintf("could not find texture '%s'\n", textureName);
2158 (*gCurrentModelTreeNodeInfo)[TreeIterPos].textureID = 0;
2159 return;
2160 }
2161
2162 (*gCurrentModelTreeNodeInfo)[TreeIterPos].textureID = textureIdx + 1;
2163 textureHandle = &TextureHandles[(*gCurrentModelTreeNodeInfo)[TreeIterPos].textureID];
2164 romOffset += sizeof(*header);
2165
2166 if (textureHandle->gfx == NULL) {
2167 load_texture_impl(romOffset, textureHandle, header, rasterSize, paletteSize, auxRasterSize, auxPaletteSize);
2168 load_texture_variants(romOffset + rasterSize + paletteSize + auxRasterSize + auxPaletteSize, (*gCurrentModelTreeNodeInfo)[TreeIterPos].textureID, startOffset, size);
2169 }
2170}
2171
2172// loads variations for current texture by looping through the following textures until a non-variant is found
2173void load_texture_variants(u32 romOffset, s32 textureID, s32 baseOffset, s32 size) {
2174 u32 offset;
2175 TextureHeader iterTextureHeader;
2176 TextureHeader* header;
2177 TextureHandle* textureHandle;
2178 u32 rasterSize;
2179 s32 paletteSize;
2180 u32 auxRasterSize;
2181 u32 auxPaletteSize;
2182 s32 mainSize;
2183 s32 currentTextureID = textureID;
2184
2185 for (offset = romOffset; offset < baseOffset + size;) {
2186 dma_copy((u8*)offset, (u8*)offset + sizeof(iterTextureHeader), &iterTextureHeader);
2187 header = &iterTextureHeader;
2188
2189 if (strcmp(header->name, "end_of_textures") == 0) {
2190 return;
2191 }
2192
2193 if (!header->isVariant) {
2194 // done reading variants
2195 break;
2196 }
2197
2198 rasterSize = header->mainW * header->mainH;
2199
2200 // compute mipmaps size
2201 if (header->mainBitDepth == G_IM_SIZ_4b) {
2202 if (header->extraTiles == EXTRA_TILE_MIPMAPS) {
2203 s32 d = 2;
2204 while (header->mainW / d >= 16 && header->mainH / d > 0) {
2205 rasterSize += header->mainW / d * header->mainH / d;
2206 d *= 2;
2207 }
2208 }
2209 rasterSize /= 2;
2210 } else if (header->mainBitDepth == G_IM_SIZ_8b) {
2211 if (header->extraTiles == EXTRA_TILE_MIPMAPS) {
2212 s32 d = 2;
2213 while (header->mainW / d >= 8 && header->mainH / d > 0) {
2214 rasterSize += header->mainW / d * header->mainH / d;
2215 d *= 2;
2216 }
2217 }
2218 } else if (header->mainBitDepth == G_IM_SIZ_16b) {
2219 if (header->extraTiles == EXTRA_TILE_MIPMAPS) {
2220 s32 d = 2;
2221 while (header->mainW / d >= 4 && header->mainH / d > 0) {
2222 rasterSize += header->mainW / d * header->mainH / d;
2223 d *= 2;
2224 }
2225 }
2226 rasterSize *= 2;
2227 } else if (header->mainBitDepth == G_IM_SIZ_32b) {
2228 if (header->extraTiles == EXTRA_TILE_MIPMAPS) {
2229 s32 d = 2;
2230 while (header->mainW / d >= 2 && header->mainH / d > 0) {
2231 rasterSize += header->mainW / d * header->mainH / d;
2232 d *= 2;
2233 }
2234 }
2235 rasterSize *= 4;
2236 }
2237
2238 // compute palette size
2239 if (header->mainFmt == G_IM_FMT_CI) {
2240 paletteSize = 0x20;
2241 if (header->mainBitDepth == G_IM_SIZ_8b) {
2242 paletteSize = 0x200;
2243 }
2244 } else {
2245 paletteSize = 0;
2246 }
2247
2248 // compute aux tile size
2249 if (header->extraTiles == EXTRA_TILE_AUX_INDEPENDENT) {
2250 auxRasterSize = header->auxW * header->auxH;
2251 if (header->auxBitDepth == G_IM_SIZ_4b) {
2252 auxRasterSize /= 2;
2253 } else if (header->auxBitDepth == G_IM_SIZ_8b) {
2254 } else if (header->auxBitDepth == G_IM_SIZ_16b) {
2255 auxRasterSize *= 2;
2256 } else {
2257 if (header->auxBitDepth == G_IM_SIZ_32b) {
2258 auxRasterSize *= 4;
2259 }
2260 }
2261 if (header->auxFmt == G_IM_FMT_CI) {
2262 auxPaletteSize = 0x20;
2263 if (header->auxBitDepth == G_IM_SIZ_8b) {
2264 auxPaletteSize = 0x200;
2265 }
2266 } else {
2267 auxPaletteSize = 0;
2268 }
2269 } else {
2270 auxPaletteSize = 0;
2271 auxRasterSize = 0;
2272 }
2273
2274 textureID++;
2275 currentTextureID = textureID;
2276 textureHandle = &TextureHandles[currentTextureID];
2277 load_texture_impl(offset + sizeof(*header), textureHandle, header, rasterSize, paletteSize, auxRasterSize, auxPaletteSize);
2278
2279 mainSize = rasterSize + paletteSize + sizeof(*header);
2280 offset += mainSize;
2281 offset += auxRasterSize + auxPaletteSize;
2282 }
2283}
2284
2286 s32 numProperties = node->numProperties;
2287 ModelNodeProperty* propertyList = node->propertyList;
2288 s32 i;
2289
2290 for (i = 0; i < numProperties; i++, propertyList++) {
2291 if (propertyList->key == key) {
2292 return propertyList;
2293 }
2294 }
2295 return NULL;
2296}
2297
2298// load textures used by models, starting from current model
2299void load_next_model_textures(ModelNode* model, s32 romOffset, s32 texSize) {
2300 if (model->type != SHAPE_TYPE_MODEL) {
2301 if (model->groupData != NULL) {
2302 s32 numChildren = model->groupData->numChildren;
2303
2304 if (numChildren != 0) {
2305 s32 i;
2306
2307 for (i = 0; i < numChildren; i++) {
2308 load_next_model_textures(model->groupData->childList[i], romOffset, texSize);
2309 }
2310 }
2311 }
2312 } else {
2314 if (propTextureName != NULL) {
2315 load_texture_by_name(propTextureName, romOffset, texSize);
2316 }
2317 }
2318 TreeIterPos++;
2319}
2320
2321// load all textures used by models, starting from the root
2322void mdl_load_all_textures(ModelNode* rootModel, s32 romOffset, s32 size) {
2323 s32 baseOffset = 0;
2324
2325 // textures are loaded to the upper half of the texture heap when not in the world
2327 baseOffset = WORLD_TEXTURE_MEMORY_SIZE;
2328 }
2329
2330 TextureHeapPos = TextureHeapBase + baseOffset;
2331
2332 if (rootModel != NULL && romOffset != 0 && size != 0) {
2333 s32 i;
2334
2335 for (i = 0; i < ARRAY_COUNT(TextureHandles); i++) {
2336 TextureHandles[i].gfx = NULL;
2337 }
2338
2339 TreeIterPos = 0;
2340 if (rootModel != NULL) {
2341 load_next_model_textures(rootModel, romOffset, size);
2342 }
2343 }
2344}
2345
2347 s32 ret = 0;
2348
2349 if (model->type != SHAPE_TYPE_MODEL && model->groupData != NULL) {
2350 s32 numChildren = model->groupData->numChildren;
2351
2352 if (numChildren != 0) {
2353 s32 i;
2354
2355 ret += numChildren;
2356 for (i = 0; i < numChildren; i++) {
2357 ret += mdl_get_child_count(model->groupData->childList[i]);
2358 }
2359 }
2360 }
2361 return ret;
2362}
2363
2365 s32 i;
2366
2376 ShroudTintAmt = 0;
2377 ShroudTintR = 0;
2378 ShroudTintG = 0;
2379 ShroudTintB = 0;
2381 } else {
2391 }
2392
2393 for (i = 0; i < ARRAY_COUNT(*gCurrentModels); i++) {
2394 (*gCurrentModels)[i] = 0;
2395 }
2396
2397 for (i = 0; i < ARRAY_COUNT(*gCurrentTransformGroups); i++) {
2398 (*gCurrentTransformGroups)[i] = 0;
2399 }
2400
2401 for (i = 0; i < ARRAY_COUNT(*gCurrentCustomModelGfxPtr); i++) {
2402 (*gCurrentCustomModelGfxPtr)[i] = 0;
2403 (*gCurrentCustomModelGfxBuildersPtr)[i] = 0;
2404 }
2405
2406 *gCurrentModelTreeRoot = NULL;
2407
2408 for (i = 0; i < ARRAY_COUNT(*gCurrentModelTreeNodeInfo); i++) {
2409 (*gCurrentModelTreeNodeInfo)[i].modelIndex = -1;
2410 (*gCurrentModelTreeNodeInfo)[i].treeDepth = 0;
2411 (*gCurrentModelTreeNodeInfo)[i].textureID = 0;
2412 }
2413
2415 gFogSettings->enabled = FALSE;
2416 gFogSettings->color.r = 10;
2417 gFogSettings->color.g = 10;
2418 gFogSettings->color.b = 10;
2419 gFogSettings->color.a = 0;
2421 gFogSettings->endDistance = 1000;
2422
2423 for (i = 0; i < ARRAY_COUNT(texPannerAuxV); i++) {
2424 texPannerAuxV[i] = 0;
2425 texPannerAuxU[i] = 0;
2426 texPannerMainV[i] = 0;
2427 texPannerMainU[i] = 0;
2428 }
2429}
2430
2454
2456 s32 i;
2457
2458 for (i = 0; i < ARRAY_COUNT(*gCurrentModels); i++) {
2459 Model* model = (*gCurrentModels)[i];
2460
2461 if (model != NULL) {
2463
2464 bb->halfSizeX = (bb->maxX - bb->minX) * 0.5;
2465 bb->halfSizeY = (bb->maxY - bb->minY) * 0.5;
2466 bb->halfSizeZ = (bb->maxZ - bb->minZ) * 0.5;
2468 }
2469 }
2470}
2471
2472void mdl_create_model(ModelBlueprint* bp, s32 unused) {
2473 ModelNode* node = bp->mdlNode;
2474 ModelNodeProperty* prop;
2475 ModelBoundingBox* bb;
2476 s32 modelIdx;
2477 Model* model;
2478 f32 x, y, z;
2479
2481 modelIdx = 0;
2482 if (prop != NULL) {
2483 s32 replaceWithFlame = (prop->data.s >> 4) & 0xF;
2484
2485 if (replaceWithFlame != 0) {
2487 if (prop != NULL) {
2488 ModelBoundingBox* bb = (ModelBoundingBox*) prop;
2489 EffectInstance* effect;
2490
2491 fx_flame(replaceWithFlame - 1,
2492 (bb->minX + bb->maxX) * 0.5f,
2493 bb->minY,
2494 (bb->minZ + bb->maxZ) * 0.5f,
2495 1.0f,
2496 &effect);
2497 return;
2498 }
2499 }
2500 }
2501
2502 for (modelIdx = 0; modelIdx < ARRAY_COUNT(*gCurrentModels); modelIdx++) {
2503 if ((*gCurrentModels)[modelIdx] == NULL) {
2504 break;
2505 }
2506 }
2507
2508 (*gCurrentModels)[modelIdx] = model = heap_malloc(sizeof(*model));
2509 model->flags = bp->flags | MODEL_FLAG_VALID;
2510 model->modelID = TreeIterPos;
2511 model->modelNode = bp->mdlNode;
2512 model->groupData = bp->groupData;
2513 model->matrixFreshness = 0;
2514 node = model->modelNode;
2515
2517 if (prop != NULL) {
2518 model->texPannerID = prop->data.s & 0xF;
2519 } else {
2520 model->texPannerID = TEX_PANNER_0;
2521 }
2523
2524 if (node->type != SHAPE_TYPE_GROUP) {
2526 } else {
2528
2529 if (prop != NULL) {
2530 // GROUP_INFO properties always come in pairs, with the second giving the render mode
2531 prop++;
2532 }
2533 }
2534
2535 if (prop != NULL) {
2536 model->renderMode = prop->data.s;
2537 } else {
2539 }
2540
2541 model->textureID = (*gCurrentModelTreeNodeInfo)[TreeIterPos].textureID;
2542 model->textureVariation = 0;
2543
2544 if (!is_identity_fixed_mtx(bp->mtx)) {
2545 model->bakedMtx = heap_malloc(sizeof(*model->bakedMtx));
2546 *model->bakedMtx = *bp->mtx;
2547 model->savedMtx = *model->bakedMtx;
2548 } else {
2549 model->bakedMtx = NULL;
2550 guMtxIdent(&model->savedMtx);
2552 }
2553
2554 guMtxIdentF(model->userTransformMtx);
2555 model->finalMtx = NULL;
2557 if (prop != NULL) {
2558 ModelBoundingBox* bb = (ModelBoundingBox*) prop;
2559
2560 x = (bb->minX + bb->maxX) * 0.5f;
2561 y = (bb->minY + bb->maxY) * 0.5f;
2562 z = (bb->minZ + bb->maxZ) * 0.5f;
2563 } else {
2564 x = y = z = 0.0f;
2565 }
2566
2567 if (model->bakedMtx != NULL) {
2568 guMtxXFML(model->bakedMtx, x, y, z, &x, &y, &z);
2569 }
2570
2571 model->center.x = x;
2572 model->center.y = y;
2573 model->center.z = z;
2574
2575 bb = (ModelBoundingBox*) prop;
2576 x = bb->maxX - bb->minX;
2577 y = bb->maxY - bb->minY;
2578 z = bb->maxZ - bb->minZ;
2579 bb->halfSizeX = x * 0.5;
2580 bb->halfSizeY = y * 0.5;
2581 bb->halfSizeZ = z * 0.5;
2582
2583 if (model->bakedMtx == NULL && x < 100.0f && y < 100.0f && z < 100.0f) {
2585 }
2586 (*gCurrentModelTreeNodeInfo)[TreeIterPos].modelIndex = modelIdx;
2587}
2588
2590 Matrix4f tempModelMtx;
2591 Matrix4f tempGroupMtx;
2592 f32 mX, mY, mZ;
2593 f32 mtgX, mtgY, mtgZ;
2594 Model* model;
2595 Mtx* curMtx;
2596 ModelBoundingBox* bb;
2598 s32 i;
2599
2600 for (i = 0; i < ARRAY_COUNT(*gCurrentModels); i++) {
2601 model = (*gCurrentModels)[i];
2602 if (model != NULL && (model->flags != 0) && !(model->flags & MODEL_FLAG_INACTIVE)) {
2603 if (!(model->flags & MODEL_FLAG_MATRIX_DIRTY)) {
2604 if (model->matrixFreshness != 0) {
2605 // matrix was recalculated recently and stored on the matrix stack
2606 // since DisplayContexts alternate, we can fetch the previous matrix from the other context
2607 model->matrixFreshness--;
2608 if (model->matrixFreshness == 0) {
2609 // since it hasn't changed in a few frames, cache the matrix
2610 model->savedMtx = *model->finalMtx;
2611 }
2612 // copy matrix from previous DisplayContext stack to current one
2613 curMtx = model->finalMtx;
2615 *model->finalMtx = *curMtx;
2616 } else {
2617 // transform matrix is not changed, have gfx build with saved matrix
2618 model->finalMtx = &model->savedMtx;
2619 }
2620 } else {
2621 // first frame with dirty matrix, need to recalculate it
2622 model->flags &= ~MODEL_FLAG_MATRIX_DIRTY;
2623 model->matrixFreshness = 2;
2624
2625 // write matrix to the matrix stack
2627 if (model->bakedMtx == NULL || (model->flags & MODEL_FLAG_TRANSFORM_GROUP_MEMBER)) {
2628 guMtxF2L(model->userTransformMtx, curMtx);
2629 } else {
2630 guMtxL2F(tempModelMtx, model->bakedMtx);
2631 guMtxCatF(model->userTransformMtx, tempModelMtx, tempModelMtx);
2632 guMtxF2L(tempModelMtx, curMtx);
2633 }
2634 model->flags &= ~MODEL_FLAG_IGNORE_MATRIX;
2635
2636 // recalculate the center of the model with transformation applied
2638 mX = (bb->minX + bb->maxX) * 0.5f;
2639 mY = (bb->minY + bb->maxY) * 0.5f;
2640 mZ = (bb->minZ + bb->maxZ) * 0.5f;
2641 guMtxXFML(curMtx, mX, mY, mZ, &mX, &mY, &mZ);
2642 model->center.x = mX;
2643 model->center.y = mY;
2644 model->center.z = mZ;
2645
2646 // point matrix for gfx building to our matrix on the stack
2647 model->finalMtx = curMtx;
2648
2649 // disable bounds culling for models with dynamic transformations
2650 model->flags &= ~MODEL_FLAG_DO_BOUNDS_CULLING;
2651 }
2652 }
2653 }
2654
2655 for (i = 0; i < ARRAY_COUNT((*gCurrentTransformGroups)); i++) {
2656 mtg = (*gCurrentTransformGroups)[i];
2657 if (mtg != NULL && mtg->flags != 0 && !(mtg->flags & TRANSFORM_GROUP_FLAG_INACTIVE)) {
2659 if (mtg->matrixFreshness != 0) {
2660 // matrix was recalculated recently and stored on the matrix stack
2661 // since DisplayContexts alternate, we can fetch the previous matrix from the other context
2662 mtg->matrixFreshness--;
2663 if (mtg->matrixFreshness == 0) {
2664 // since it hasn't changed in a few frames, cache the matrix
2665 mtg->savedMtx = *mtg->finalMtx;
2666 }
2667 // copy matrix from previous DisplayContext stack to current one
2668 curMtx = mtg->finalMtx;
2670 *mtg->finalMtx = *curMtx;
2671 } else {
2672 // transform matrix is not changed, have gfx build with saved matrix
2673 mtg->finalMtx = &mtg->savedMtx;
2674 }
2675 } else {
2676 // first frame with dirty matrix, need to recalculate it
2677 mtg->flags &= ~TRANSFORM_GROUP_FLAG_MATRIX_DIRTY;
2678 mtg->matrixFreshness = 2;
2679
2680 // write matrix to the matrix stack
2682 if (mtg->bakedMtx == NULL) {
2683 guMtxF2L(mtg->userTransformMtx, curMtx);
2684 } else {
2685 guMtxL2F(tempGroupMtx, mtg->bakedMtx);
2686 guMtxCatF(mtg->userTransformMtx, tempGroupMtx, tempGroupMtx);
2687 guMtxF2L(tempGroupMtx, curMtx);
2688 }
2689 mtg->flags &= ~TRANSFORM_GROUP_FLAG_IGNORE_MATRIX;
2690
2691 // recalculate the center of the transform group with transformation applied
2693 mtgX = (bb->minX + bb->maxX) * 0.5f;
2694 mtgY = (bb->minY + bb->maxY) * 0.5f;
2695 mtgZ = (bb->minZ + bb->maxZ) * 0.5f;
2696 guMtxXFML(curMtx, mtgX, mtgY, mtgZ, &mtgX, &mtgY, &mtgZ);
2697 mtg->center.x = mtgX;
2698 mtg->center.y = mtgY;
2699 mtg->center.z = mtgZ;
2700
2701 // point matrix for gfx building to our matrix on the stack
2702 mtg->finalMtx = curMtx;
2703 }
2704 }
2705 }
2706
2708}
2709
2710void render_models(void) {
2711 RenderTask rt;
2712 RenderTask* rtPtr = &rt;
2713 f32 outX, outY, outZ, outW;
2714 f32 m00, m01, m02, m03;
2715 f32 m10, m11, m12, m13;
2716 f32 m20, m21, m22, m23;
2717 f32 m30, m31, m32, m33;
2718 f32 centerX, centerY, centerZ;
2719 f32 bbx, bby, bbz;
2720
2721 Camera* camera = &gCameras[gCurrentCameraID];
2722 Model* model;
2723 ModelBoundingBox* boundingBox;
2724 ModelTransformGroup* transformGroup;
2725 f32 xComp, yComp, zComp;
2726
2727 s32 distance;
2728 s32 notVisible;
2729 s32 i;
2730
2731#define TEST_POINT_VISIBILITY \
2732 outX = (m00 * xComp) + (m10 * yComp) + (m20 * zComp) + m30; \
2733 outY = (m01 * xComp) + (m11 * yComp) + (m21 * zComp) + m31; \
2734 outZ = (m02 * xComp) + (m12 * yComp) + (m22 * zComp) + m32; \
2735 outW = (m03 * xComp) + (m13 * yComp) + (m23 * zComp) + m33; \
2736 if (outW == 0.0f) { \
2737 break; \
2738 } \
2739 /* Perspective divide */ \
2740 outW = 1.0f / outW; \
2741 xComp = outX * outW; \
2742 yComp = outY * outW; \
2743 zComp = outZ * outW; \
2744 if (zComp > -1.0f && xComp >= -1.0f && xComp <= 1.0f && yComp >= -1.0f && yComp <= 1.0f) { \
2745 break; \
2746 }
2747
2748 m00 = camera->mtxPerspective[0][0];
2749 m01 = camera->mtxPerspective[0][1];
2750 m02 = camera->mtxPerspective[0][2];
2751 m03 = camera->mtxPerspective[0][3];
2752 m10 = camera->mtxPerspective[1][0];
2753 m11 = camera->mtxPerspective[1][1];
2754 m12 = camera->mtxPerspective[1][2];
2755 m13 = camera->mtxPerspective[1][3];
2756 m20 = camera->mtxPerspective[2][0];
2757 m21 = camera->mtxPerspective[2][1];
2758 m22 = camera->mtxPerspective[2][2];
2759 m23 = camera->mtxPerspective[2][3];
2760 m30 = camera->mtxPerspective[3][0];
2761 m31 = camera->mtxPerspective[3][1];
2762 m32 = camera->mtxPerspective[3][2];
2763 m33 = camera->mtxPerspective[3][3];
2764
2765 // enqueue all visible models not in transform groups
2766 for (i = 0; i < ARRAY_COUNT(*gCurrentModels); i++) {
2767 model = (*gCurrentModels)[i];
2768 if (model == NULL) {
2769 continue;
2770 }
2771 if (model->flags == 0) {
2772 continue;
2773 }
2774 if (model->flags & MODEL_FLAG_INACTIVE) {
2775 continue;
2776 }
2777 if (model->flags & MODEL_FLAG_HIDDEN) {
2778 continue;
2779 }
2780 if (model->flags & MODEL_FLAG_20) {
2781 continue;
2782 }
2784 continue;
2785 }
2786
2787 centerX = model->center.x;
2788 centerY = model->center.y;
2789 centerZ = model->center.z;
2790
2791 // for models that are small enough to do bounds culling, only render if at least one
2792 // corner of its boundary box is visible
2793 if (model->flags & MODEL_FLAG_DO_BOUNDS_CULLING) {
2794 notVisible = FALSE;
2795 boundingBox = (ModelBoundingBox*) model->modelNode->propertyList;
2796 bbx = boundingBox->halfSizeX;
2797 bby = boundingBox->halfSizeY;
2798 bbz = boundingBox->halfSizeZ;
2799
2800 while (TRUE) {
2801 if (TRUE) {
2802 xComp = centerX - bbx;
2803 yComp = centerY - bby;
2804 zComp = centerZ - bbz;
2806 }
2807
2808 if (bbx != 0.0f) {
2809 xComp = centerX + bbx;
2810 yComp = centerY - bby;
2811 zComp = centerZ - bbz;
2813 }
2814
2815 if (bby != 0.0f) {
2816 xComp = centerX - bbx;
2817 yComp = centerY + bby;
2818 zComp = centerZ - bbz;
2820 }
2821
2822 if (bbx != 0.0f && bby != 0.0f) {
2823 xComp = centerX + bbx;
2824 yComp = centerY + bby;
2825 zComp = centerZ - bbz;
2827 }
2828
2829 if (bbz != 0.0f) {
2830 xComp = centerX - bbx;
2831 yComp = centerY - bby;
2832 zComp = centerZ + bbz;
2834 }
2835
2836 if (bbx != 0.0f && bbz != 0.0f) {
2837 xComp = centerX + bbx;
2838 yComp = centerY - bby;
2839 zComp = centerZ + bbz;
2841 }
2842
2843 if (bby != 0.0f && bbz != 0.0f) {
2844 xComp = centerX - bbx;
2845 yComp = centerY + bby;
2846 zComp = centerZ + bbz;
2848 }
2849
2850 if (bbx != 0.0f && bby != 0.0f && bbz != 0.0f) {
2851 xComp = centerX + bbx;
2852 yComp = centerY + bby;
2853 zComp = centerZ + bbz;
2855 }
2856 notVisible = TRUE;
2857 break;
2858 }
2859 // no points of the models bounding box were visible
2860 if (notVisible) {
2861 continue;
2862 }
2863 }
2864
2865 // map all model depths to the interval [0, 10k] and submit render task
2866 transform_point(camera->mtxPerspective, centerX, centerY, centerZ, 1.0f, &outX, &outY, &outZ, &outW);
2867 distance = outZ + 5000.0f;
2868 if (distance < 0) {
2869 distance = 0;
2870 } else if (distance > 10000) {
2871 distance = 10000;
2872 }
2873 rtPtr->appendGfxArg = model;
2874 if (model->modelNode->type == SHAPE_TYPE_GROUP) {
2876 } else {
2877 rtPtr->appendGfx = appendGfx_model;
2878 }
2879 rtPtr->dist = -distance;
2880 rtPtr->renderMode = model->renderMode;
2881 queue_render_task(rtPtr);
2882 }
2883
2884 // enqueue models in transform groups
2885 // only the center of the group is used for depth sorting
2886 for (i = 0; i < ARRAY_COUNT(*gCurrentTransformGroups); i++) {
2887 transformGroup = (*gCurrentTransformGroups)[i];
2888 if (transformGroup == NULL) {
2889 continue;
2890 }
2891
2892 if (transformGroup->flags == 0) {
2893 continue;
2894 }
2895
2896 if (transformGroup->flags & TRANSFORM_GROUP_FLAG_INACTIVE) {
2897 continue;
2898 }
2899
2900 xComp = transformGroup->center.x;
2901 yComp = transformGroup->center.y;
2902 zComp = transformGroup->center.z;
2903
2905 camera->mtxPerspective,
2906 xComp, yComp, zComp, 1.0f,
2907 &outX, &outY, &outZ, &outW
2908 );
2909 if (outW == 0.0f) {
2910 outW = 1.0f;
2911 }
2912
2913 distance = ((outZ / outW) * 10000.0f);
2914
2915 if (!(transformGroup->flags & TRANSFORM_GROUP_FLAG_HIDDEN)) {
2917 rtPtr->appendGfxArg = transformGroup;
2918 rtPtr->dist = -distance;
2919 rtPtr->renderMode = transformGroup->renderMode;
2920 queue_render_task(rtPtr);
2921 }
2922 }
2923}
2924
2925void appendGfx_model_group(void* data) {
2926 Model* model = data;
2927 s32 modelTreeDepth = (*gCurrentModelTreeNodeInfo)[model->modelID].treeDepth;
2928 s32 i;
2929
2930 for (i = model->modelID - 1; i >= 0; i--) {
2931 if (modelTreeDepth >= (*gCurrentModelTreeNodeInfo)[i].treeDepth) {
2932 break;
2933 }
2934 }
2935
2936 TreeIterPos = i + 1;
2937 func_80117D00(model);
2938}
2939
2940void func_80117D00(Model* model) {
2941 Model* mdl = model; // temps needed to match
2942 ModelNode* modelNode = mdl->modelNode;
2943
2944 if (model->modelNode->type != SHAPE_TYPE_MODEL) {
2945 if (modelNode->groupData != NULL) {
2946 s32 numChildren = modelNode->groupData->numChildren;
2947
2948 if (numChildren != 0) {
2949 s32 i;
2950
2951 for (i = 0; i < numChildren; i++, TreeIterPos++) {
2952 Model newModel = *mdl;
2953 ModelNodeProperty* prop;
2954
2955 newModel.flags = mdl->flags;
2956 newModel.finalMtx = mdl->finalMtx;
2957 newModel.modelNode = modelNode->groupData->childList[i];
2958 newModel.texPannerID = mdl->texPannerID;
2959 newModel.customGfxIndex = mdl->customGfxIndex;
2960
2961 if (newModel.modelNode->type == SHAPE_TYPE_MODEL) {
2963 } else {
2964 prop = NULL;
2965 }
2966
2967 if (prop != NULL) {
2968 newModel.renderMode = prop->data.s;
2969 } else {
2970 newModel.renderMode = 0;
2971 }
2972
2973 newModel.textureID = (*gCurrentModelTreeNodeInfo)[TreeIterPos].textureID;
2974 newModel.textureVariation = 0;
2975 func_80117D00(&newModel);
2976 }
2977 }
2978 }
2979 } else {
2980 appendGfx_model(mdl);
2981 }
2982}
2983
2984// this looks like a switch, but I can't figure it out
2986 Gfx** gfx = &gMainGfxPos;
2987 Model* model;
2988
2989 if (node != NULL) {
2990 if (node->type == SHAPE_TYPE_GROUP) {
2992
2993 if (groupInfoProp != NULL && groupInfoProp->data.s != 0) {
2995 if (!(model->flags & MODEL_FLAG_HIDDEN)) {
2996 appendGfx_model_group(model);
2997 }
2998 mtg_IterIdx++;
2999 return;
3000 }
3001 }
3002 if (node->type != SHAPE_TYPE_MODEL) {
3003 if (node->groupData != NULL) {
3004 s32 numChildren;
3005 s32 i;
3006
3007 if (node->groupData->transformMatrix != NULL) {
3008 gSPMatrix((*gfx)++, node->groupData->transformMatrix, G_MTX_PUSH | G_MTX_MUL | G_MTX_MODELVIEW);
3009 }
3010
3011 numChildren = node->groupData->numChildren;
3012 if (numChildren != 0) {
3013 for (i = 0; i < numChildren; i++) {
3015 }
3016 }
3017
3018 if (node->groupData->transformMatrix != NULL) {
3019 gSPPopMatrix((*gfx)++, G_MTX_MODELVIEW);
3020 }
3021 }
3022 return;
3023 }
3024
3026 if (!(model->flags & MODEL_FLAG_HIDDEN)) {
3027 appendGfx_model(model);
3028 }
3029 mtg_IterIdx++;
3030 }
3031}
3032
3033// gfx temps needed
3034void render_transform_group(void* data) {
3035 ModelTransformGroup* group = data;
3036 Gfx** gfx = &gMainGfxPos;
3037
3038 if (!(group->flags & TRANSFORM_GROUP_FLAG_INACTIVE)) {
3040 if (!(group->flags & TRANSFORM_GROUP_FLAG_IGNORE_MATRIX)) {
3041 gSPMatrix((*gfx)++, group->finalMtx, (G_MTX_PUSH | G_MTX_LOAD) | G_MTX_MODELVIEW);
3042 }
3043
3045
3046 if (!(group->flags & TRANSFORM_GROUP_FLAG_IGNORE_MATRIX)) {
3047 gSPPopMatrix((*gfx)++, G_MTX_MODELVIEW);
3048 }
3049 gDPPipeSync((*gfx)++);
3050 }
3051}
3052
3053void make_texture_gfx(TextureHeader* header, Gfx** gfxPos, IMG_PTR raster, PAL_PTR palette, IMG_PTR auxRaster, PAL_PTR auxPalette, u8 auxShiftS, u8 auxShiftT, u16 auxOffsetS, u16 auxOffsetT) {
3054 s32 mainWidth, mainHeight;
3055 s32 auxWidth, auxHeight;
3056 s32 mainFmt;
3057 s32 auxFmt;
3058 s32 mainWrapW, mainWrapH;
3059 s32 auxWrapW, auxWrapH;
3060 s32 extraTileType;
3061 u32 texCombineType;
3062 s32 lod;
3063 s32 lodDivisor;
3064 IMG_PTR rasterPtr;
3065 s32 filteringMode;
3066 s32 auxPaletteIndex;
3067 s32 lutMode;
3068 s32 lodMode;
3069 s32 mainMasks, mainMaskt;
3070 s32 auxMasks, auxMaskt;
3071 s32 mainBitDepth;
3072 s32 auxBitDepth;
3073 s32 temp;
3074
3075 mainWidth = header->mainW;
3076 mainHeight = header->mainH;
3077
3078 lod = 0;
3079 auxPaletteIndex = 0;
3080
3081 mainMasks = INTEGER_LOG2(mainWidth);
3082 mainMaskt = INTEGER_LOG2(mainHeight);
3083
3084 mainWrapW = header->mainWrapW;
3085 mainWrapH = header->mainWrapH;
3086
3087 mainFmt = header->mainFmt;
3088 mainBitDepth = header->mainBitDepth;
3089
3090 extraTileType = header->extraTiles;
3091 filteringMode = header->filtering << G_MDSFT_TEXTFILT;
3092
3093 auxWidth = header->auxW;
3094 auxHeight = header->auxH;
3095
3096 auxMasks = INTEGER_LOG2(auxWidth);
3097 auxMaskt = INTEGER_LOG2(auxHeight);
3098
3099 auxWrapW = header->auxWrapW;
3100 auxWrapH = header->auxWrapH;
3101 auxFmt = header->auxFmt;
3102 auxBitDepth = header->auxBitDepth;
3103
3104
3105 if (extraTileType == EXTRA_TILE_AUX_INDEPENDENT) {
3106 if (palette != NULL) {
3107 auxPaletteIndex = 1;
3108 } else {
3109 auxPaletteIndex = 0;
3110 }
3111 }
3112
3113 if (palette != NULL || auxPalette != NULL) {
3114 lutMode = G_TT_RGBA16;
3115 if (palette != NULL) {
3116 if (mainBitDepth == G_IM_SIZ_4b) {
3117 gDPLoadTLUT_pal16((*gfxPos)++, 0, palette);
3118 } else if (mainBitDepth == G_IM_SIZ_8b) {
3119 gDPLoadTLUT_pal256((*gfxPos)++, palette);
3120 }
3121 }
3122 if (auxPalette != NULL) {
3123 if (auxBitDepth == G_IM_SIZ_4b) {
3124 gDPLoadTLUT_pal16((*gfxPos)++, auxPaletteIndex, auxPalette);
3125 } else if (auxBitDepth == G_IM_SIZ_8b) {
3126 gDPLoadTLUT_pal256((*gfxPos)++, auxPalette);
3127 }
3128 }
3129 } else {
3130 lutMode = G_TT_NONE;
3131 }
3132
3133 // only the following aux combine modes are ever used:
3134 // (A) 0x00 -> 0, 0
3135 // (B) 0x08 -> 2, 0
3136 // (C) 0x0D -> 3, 1
3137 // (D) 0x10 -> 4, 0
3138 texCombineType = header->auxCombineType;
3139 if (texCombineType >= 3) {
3140 // combine modes 3, 4, ... are directly appended to the end of the table and subtype is ignored
3141 texCombineType = TEX_COMBINE_3 + (texCombineType - 3);
3142 } else {
3143 // select based on aux combine subtypes
3144 // in practice, auxCombineSubType is ALWAYS zero here since the only (A) and (B) may reach this block
3145 texCombineType = 1 + header->extraTiles * AUX_COMBINE_SUB_COUNT + header->auxCombineSubType;
3146 }
3147
3148 *(*gfxPos) = SolidCombineModes[texCombineType][TINT_COMBINE_NONE];
3149 (*gfxPos)++;
3150
3151 switch (extraTileType) {
3152 case EXTRA_TILE_NONE:
3153 lodMode = G_TL_TILE;
3154 gSPTexture((*gfxPos)++, 0xFFFF, 0xFFFF, 0, G_TX_RENDERTILE, G_ON);
3155 switch (mainBitDepth) {
3156 case G_IM_SIZ_4b:
3157 gDPLoadTextureBlock_4b((*gfxPos)++, raster, mainFmt,
3158 mainWidth, mainHeight, 0,
3159 mainWrapW, mainWrapH, mainMasks, mainMaskt, G_TX_NOLOD, G_TX_NOLOD);
3160 break;
3161 case G_IM_SIZ_8b:
3162 gDPLoadTextureBlock((*gfxPos)++, raster, mainFmt, G_IM_SIZ_8b,
3163 mainWidth, mainHeight, 0,
3164 mainWrapW, mainWrapH, mainMasks, mainMaskt, G_TX_NOLOD, G_TX_NOLOD);
3165 break;
3166 case G_IM_SIZ_16b:
3167 gDPLoadTextureBlock((*gfxPos)++, raster, mainFmt, G_IM_SIZ_16b,
3168 mainWidth, mainHeight, 0,
3169 mainWrapW, mainWrapH, mainMasks, mainMaskt, G_TX_NOLOD, G_TX_NOLOD);
3170 break;
3171 case 3:
3172 gDPLoadTextureBlock((*gfxPos)++, raster, mainFmt, G_IM_SIZ_32b,
3173 mainWidth, mainHeight, 0,
3174 mainWrapW, mainWrapH, mainMasks, mainMaskt, G_TX_NOLOD, G_TX_NOLOD);
3175 break;
3176 }
3177 break;
3178 case EXTRA_TILE_MIPMAPS:
3179 lodMode = G_TL_LOD;
3180 switch (mainBitDepth) {
3181 case G_IM_SIZ_4b:
3182 for (rasterPtr = raster, lod = 0, lodDivisor = 1;
3183 mainWidth / lodDivisor * 4 >= 64 && mainHeight / lodDivisor != 0;
3184 rasterPtr += mainWidth / lodDivisor * mainHeight / lodDivisor / 2, lodDivisor *= 2, lod++)
3185 {
3186 gDPLoadMultiTile_4b((*gfxPos)++, rasterPtr, (u32)(rasterPtr - raster) >> 3, lod, mainFmt,
3187 mainWidth / lodDivisor, mainHeight / lodDivisor,
3188 0, 0, mainWidth / lodDivisor - 1, mainHeight / lodDivisor - 1, 0,
3189 mainWrapW, mainWrapH, mainMasks - lod, mainMaskt - lod, lod, lod);
3190 }
3191 break;
3192 case G_IM_SIZ_8b:
3193 for (rasterPtr = raster, lod = 0, lodDivisor = 1;
3194 mainWidth / lodDivisor * 8 >= 64 && mainHeight / lodDivisor != 0;
3195 rasterPtr += mainWidth / lodDivisor * mainHeight / lodDivisor, lodDivisor *= 2, lod++)
3196 {
3197 gDPLoadMultiTile((*gfxPos)++, rasterPtr, ((u32)(rasterPtr - raster)) >> 3, lod, mainFmt, G_IM_SIZ_8b,
3198 mainWidth / lodDivisor, mainHeight / lodDivisor,
3199 0, 0, mainWidth / lodDivisor - 1, mainHeight / lodDivisor - 1, 0,
3200 mainWrapW, mainWrapH, mainMasks - lod, mainMaskt - lod, lod, lod);
3201 }
3202 break;
3203 case G_IM_SIZ_16b:
3204 for (rasterPtr = raster, lod = 0, lodDivisor = 1;
3205 mainWidth / lodDivisor * 16 >= 64 && mainHeight / lodDivisor != 0;
3206 rasterPtr += mainWidth / lodDivisor * mainHeight / lodDivisor * 2, lodDivisor *= 2, lod++)
3207 {
3208 gDPLoadMultiTile((*gfxPos)++, rasterPtr, ((u32)(rasterPtr - raster)) >> 3, lod, mainFmt, G_IM_SIZ_16b,
3209 mainWidth / lodDivisor, mainHeight / lodDivisor,
3210 0, 0, mainWidth / lodDivisor - 1, mainHeight / lodDivisor - 1, 0,
3211 mainWrapW, mainWrapH, mainMasks - lod, mainMaskt - lod, lod, lod);
3212 }
3213 break;
3214 case G_IM_SIZ_32b:
3215 for (rasterPtr = raster, lod = 0, lodDivisor = 1;
3216 mainWidth / lodDivisor * 32 >= 64 && mainHeight / lodDivisor != 0;
3217 rasterPtr += mainWidth / lodDivisor * mainHeight / lodDivisor * 4, lodDivisor *= 2, lod++)
3218 {
3219 gDPLoadMultiTile((*gfxPos)++, rasterPtr, ((u32)(rasterPtr - raster)) >> 4, lod, mainFmt, G_IM_SIZ_32b,
3220 mainWidth / lodDivisor, mainHeight / lodDivisor,
3221 0, 0, mainWidth / lodDivisor - 1, mainHeight / lodDivisor - 1, 0,
3222 mainWrapW, mainWrapH, mainMasks - lod, mainMaskt - lod, lod, lod);
3223 }
3224 break;
3225 }
3226 gSPTexture((*gfxPos)++, 0xFFFF, 0xFFFF, lod - 1, G_TX_RENDERTILE, G_ON);
3227 break;
3229 gSPTexture((*gfxPos)++, 0xFFFF, 0xFFFF, 0, G_TX_RENDERTILE, G_ON);
3230 gDPPipeSync((*gfxPos)++);
3231 lodMode = G_TL_TILE;
3232 switch (mainBitDepth) {
3233 case G_IM_SIZ_4b:
3234 gDPScrollTextureBlockHalfHeight_4b((*gfxPos)++, raster, mainFmt, mainWidth, mainHeight, 0,
3235 mainWrapW, mainWrapH, mainMasks, mainMaskt, G_TX_NOLOD, G_TX_NOLOD,
3236 auxOffsetS, auxOffsetT, auxShiftS, auxShiftT);
3237 break;
3238 case G_IM_SIZ_8b:
3239 gDPScrollTextureBlockHalfHeight((*gfxPos)++, raster, mainFmt, G_IM_SIZ_8b, mainWidth, mainHeight, 0,
3240 mainWrapW, mainWrapH, mainMasks, mainMaskt, G_TX_NOLOD, G_TX_NOLOD,
3241 auxOffsetS, auxOffsetT, auxShiftS, auxShiftT);
3242 break;
3243 case G_IM_SIZ_16b:
3244 gDPScrollTextureBlockHalfHeight((*gfxPos)++, raster, mainFmt, G_IM_SIZ_16b, mainWidth, mainHeight, 0,
3245 mainWrapW, mainWrapH, mainMasks, mainMaskt, G_TX_NOLOD, G_TX_NOLOD,
3246 auxOffsetS, auxOffsetT, auxShiftS, auxShiftT);
3247 break;
3248 case G_IM_SIZ_32b:
3249 gDPScrollTextureBlockHalfHeight((*gfxPos)++, raster, mainFmt, G_IM_SIZ_32b, mainWidth, mainHeight, 0,
3250 mainWrapW, mainWrapH, mainMasks, mainMaskt, G_TX_NOLOD, G_TX_NOLOD,
3251 auxOffsetS, auxOffsetT, auxShiftS, auxShiftT);
3252 break;
3253 }
3254 break;
3256 gSPTexture((*gfxPos)++, 0xFFFF, 0xFFFF, 0, G_TX_RENDERTILE, G_ON);
3257 lodMode = G_TL_TILE;
3258 switch (mainBitDepth) {
3259 case G_IM_SIZ_4b:
3260 gDPLoadTextureTile_4b((*gfxPos)++, raster, mainFmt, mainWidth, mainHeight,
3261 0, 0, mainWidth - 1, mainHeight - 1, 0,
3262 mainWrapW, mainWrapH, mainMasks, mainMaskt, G_TX_NOLOD, G_TX_NOLOD);
3263 lodDivisor = (((mainWidth * mainHeight) >> 1) + 7)>>3; // required to use lodDivisor here
3264 break;
3265 case G_IM_SIZ_8b:
3266 gDPLoadTextureTile((*gfxPos)++, raster, mainFmt, G_IM_SIZ_8b, mainWidth, mainHeight,
3267 0, 0, mainWidth - 1, mainHeight - 1, 0,
3268 mainWrapW, mainWrapH, mainMasks, mainMaskt, G_TX_NOLOD, G_TX_NOLOD);
3269 lodDivisor = ((mainWidth * mainHeight) + 7)>>3;
3270 break;
3271 case G_IM_SIZ_16b:
3272 gDPLoadTextureTile((*gfxPos)++, raster, mainFmt, G_IM_SIZ_16b, mainWidth, mainHeight,
3273 0, 0, mainWidth - 1, mainHeight - 1, 0,
3274 mainWrapW, mainWrapH, mainMasks, mainMaskt, G_TX_NOLOD, G_TX_NOLOD);
3275 lodDivisor = ((mainWidth * mainHeight) * 2 + 7)>>3;
3276 break;
3277 case G_IM_SIZ_32b:
3278 gDPLoadTextureTile((*gfxPos)++, raster, mainFmt, G_IM_SIZ_32b, mainWidth, mainHeight,
3279 0, 0, mainWidth - 1, mainHeight - 1, 0,
3280 mainWrapW, mainWrapH, mainMasks, mainMaskt, G_TX_NOLOD, G_TX_NOLOD);
3281 lodDivisor = ((mainWidth * mainHeight / 2) * 2 + 7)>>3;
3282 break;
3283 }
3284
3285 switch (auxBitDepth) {
3286 case G_IM_SIZ_4b:
3287 gDPScrollMultiTile_4b((*gfxPos)++, auxRaster, lodDivisor, 1, auxFmt, auxWidth, auxHeight,
3288 0, 0, auxWidth - 1, auxHeight - 1, auxPaletteIndex,
3289 auxWrapW, auxWrapH, auxMasks, auxMaskt,
3290 auxShiftS, auxShiftT, auxOffsetS, auxOffsetT);
3291 break;
3292 case G_IM_SIZ_8b:
3293 gDPScrollMultiTile((*gfxPos)++, auxRaster, lodDivisor, 1, auxFmt, G_IM_SIZ_8b, auxWidth, auxHeight,
3294 0, 0, auxWidth - 1, auxHeight - 1, auxPaletteIndex,
3295 auxWrapW, auxWrapH, auxMasks, auxMaskt,
3296 auxShiftS, auxShiftT, auxOffsetS, auxOffsetT);
3297 break;
3298 case G_IM_SIZ_16b:
3299 gDPScrollMultiTile((*gfxPos)++, auxRaster, lodDivisor, 1, auxFmt, G_IM_SIZ_16b, auxWidth, auxHeight,
3300 0, 0, auxWidth - 1, auxHeight - 1, auxPaletteIndex,
3301 auxWrapW, auxWrapH, auxMasks, auxMaskt,
3302 auxShiftS, auxShiftT, auxOffsetS, auxOffsetT);
3303 break;
3304 case G_IM_SIZ_32b:
3305 gDPScrollMultiTile((*gfxPos)++, auxRaster, lodDivisor, 1, auxFmt, G_IM_SIZ_32b, auxWidth, auxHeight,
3306 0, 0, auxWidth - 1, auxHeight - 1, auxPaletteIndex,
3307 auxWrapW, auxWrapH, auxMasks, auxMaskt,
3308 auxShiftS, auxShiftT, auxOffsetS, auxOffsetT);
3309 break;
3310 }
3311 }
3312 gSPSetOtherMode((*gfxPos)++, G_SETOTHERMODE_H, 4, 16, filteringMode | G_TC_FILT | lutMode | lodMode | G_TP_PERSP );
3313}
3314
3316 return (*gCurrentModels)[listIndex];
3317}
3318
3319void load_data_for_models(ModelNode* rootModel, s32 texturesOffset, s32 size) {
3320 Matrix4f mtx;
3321
3322 guMtxIdentF(mtx);
3323
3324 if (texturesOffset != 0) {
3325 mdl_load_all_textures(rootModel, texturesOffset, size);
3326 }
3327
3328 *gCurrentModelTreeRoot = rootModel;
3329 TreeIterPos = 0;
3330
3331 if (rootModel != NULL) {
3332 load_model_transforms(rootModel, NULL, mtx, 0);
3333 }
3334}
3335
3336void load_model_transforms(ModelNode* model, ModelNode* parent, Matrix4f mdlTransformMtx, s32 treeDepth) {
3337 Matrix4f combinedMtx;
3338 Mtx sp50;
3339 ModelBlueprint modelBP;
3340 ModelBlueprint* modelBPptr = &modelBP;
3341 ModelNodeProperty* prop;
3342 ModelNode* modelTemp;
3343 s32 i;
3344
3345 if (model->groupData != NULL && model->groupData->numChildren != 0) {
3346 s32 groupType;
3347
3348 if (model->groupData->transformMatrix != NULL) {
3349 Matrix4f tempMtx;
3350
3351 guMtxL2F(tempMtx, model->groupData->transformMatrix);
3352 guMtxCatF(tempMtx, mdlTransformMtx, combinedMtx);
3353 }
3354
3356 if (prop == NULL) {
3357 groupType = GROUP_TYPE_0;
3358 } else {
3359 groupType = prop->data.s;
3360 }
3361
3362 if (model->type != SHAPE_TYPE_GROUP || groupType == GROUP_TYPE_0) {
3363 for (i = 0; i < model->groupData->numChildren; i++) {
3364 load_model_transforms(model->groupData->childList[i], model,
3365 model->groupData->transformMatrix != NULL ? combinedMtx : mdlTransformMtx,
3366 treeDepth + 1);
3367 }
3368
3369 (*gCurrentModelTreeNodeInfo)[TreeIterPos].modelIndex = -1;
3370 (*gCurrentModelTreeNodeInfo)[TreeIterPos].treeDepth = treeDepth;
3371 TreeIterPos += 1;
3372 return;
3373 }
3374 }
3375
3376 guMtxF2L(mdlTransformMtx, &sp50);
3377 modelBPptr->flags = 0;
3378 modelBPptr->mdlNode = model;
3379 modelBPptr->groupData = parent->groupData;
3380 modelBPptr->mtx = &sp50;
3381
3382 if (model->type == SHAPE_TYPE_GROUP) {
3383 s32 childCount = mdl_get_child_count(model);
3384
3385 for (i = TreeIterPos; i < TreeIterPos + childCount; i++) {
3386 (*gCurrentModelTreeNodeInfo)[i].modelIndex = -1;
3387 (*gCurrentModelTreeNodeInfo)[i].treeDepth = treeDepth + 1;
3388 }
3389 TreeIterPos += childCount;
3390 }
3391
3392 mdl_create_model(modelBPptr, 4);
3393 (*gCurrentModelTreeNodeInfo)[TreeIterPos].treeDepth = treeDepth;
3394 TreeIterPos += 1;
3395}
3396
3398 s32 i;
3399
3400 if (treeIndex < MAX_MODELS) {
3401 u8 modelIndex = (*gCurrentModelTreeNodeInfo)[treeIndex].modelIndex;
3402
3403 if (modelIndex != (u8)-1) {
3404 return modelIndex;
3405 }
3406 }
3407
3408 for (i = 0; i < MAX_MODELS; i++) {
3409 Model* model = get_model_from_list_index(i);
3410
3411 if (model != NULL && model->modelID == treeIndex) {
3412 return i;
3413 }
3414 }
3415 return 0;
3416}
3417
3419 ModelTransformGroup* group;
3420 s32 i;
3421
3422 for (i = 0; i < MAX_MODEL_TRANSFORM_GROUPS; i++) {
3423 group = get_transform_group(i);
3424
3425 if (group != NULL && group->groupModelID == modelID) {
3426 return i;
3427 }
3428 }
3429
3430 return -1;
3431}
3432
3433void get_model_center_and_size(u16 modelID, f32* centerX, f32* centerY, f32* centerZ, f32* sizeX, f32* sizeY, f32* sizeZ) {
3435 ModelNode* node = model->modelNode;
3436 ModelBoundingBox* bb;
3437
3438 *centerX = model->center.x;
3439 *centerY = model->center.y;
3440 *centerZ = model->center.z;
3441
3443
3444 if (bb != NULL) {
3445 *sizeX = bb->halfSizeX;
3446 *sizeY = bb->halfSizeY;
3447 *sizeZ = bb->halfSizeZ;
3448 } else {
3449 *sizeX = *sizeY = *sizeZ = 0.0f;
3450 }
3451}
3452
3454 return (*gCurrentTransformGroups)[index];
3455}
3456
3457// find group info?
3459 ModelNode* currentNode;
3460 ModelNodeProperty* prop;
3461 s32 numChildren;
3462 s32 i;
3463 u16 currentID;
3464
3465 // stop searching if node is a model
3466 if (node->type == SHAPE_TYPE_MODEL) {
3468 return;
3469 }
3470
3471 // stop searching if node is a group with GROUP_TYPE_0
3472 if (node->type == SHAPE_TYPE_GROUP) {
3474 if (prop != NULL && prop->data.s != GROUP_TYPE_0) {
3477 return;
3478 }
3479 }
3480
3481 if (node->groupData != NULL) {
3482 numChildren = node->groupData->numChildren;
3483 if (numChildren != 0) {
3484 for (i = 0; i < numChildren; i++) {
3485 currentNode = node->groupData->childList[i];
3486 currentID = TreeIterPos;
3487
3488 if (currentNode->type == SHAPE_TYPE_GROUP) {
3489 prop = get_model_property(currentNode, MODEL_PROP_KEY_GROUP_INFO);
3490 if (prop != NULL && prop->data.s != GROUP_TYPE_0) {
3491 currentID += mdl_get_child_count(currentNode);
3492 }
3493 }
3494 func_8011B1D8(currentNode);
3495
3496 if (mtg_FoundModelNode != NULL) {
3497 // not possible
3498 return;
3499 }
3500
3501 // the current model is the one we're looking for
3503 mtg_FoundModelNode = currentNode;
3504 mtg_MinChild = currentID;
3505 return;
3506 }
3507
3508 TreeIterPos++;
3509 }
3510 }
3511 }
3512}
3513
3514void mdl_make_transform_group(u16 modelID) {
3515 TreeIterPos = 0;
3516 mtg_FoundModelNode = NULL;
3517 mtg_SearchModelID = modelID;
3518 mtg_MaxChild = 0;
3519 mtg_MinChild = 0;
3521
3522 if (mtg_FoundModelNode != NULL) {
3523 ModelTransformGroup* newMtg;
3524 ModelNode* node;
3525 ModelNodeProperty* prop;
3526 ModelBoundingBox* bb;
3527 f32 x, y, z;
3528 s32 i;
3529
3530 for (i = 0; i < ARRAY_COUNT(*gCurrentTransformGroups); i++) {
3531 if ((*gCurrentTransformGroups)[i] == NULL) {
3532 break;
3533 }
3534 }
3535
3536 (*gCurrentTransformGroups)[i] = newMtg = heap_malloc(sizeof(*newMtg));
3538 newMtg->groupModelID = modelID;
3541 newMtg->matrixFreshness = 0;
3542 newMtg->bakedMtx = NULL;
3544 guMtxIdent(&newMtg->savedMtx);
3546 guMtxIdentF(newMtg->userTransformMtx);
3547
3548 node = newMtg->baseModelNode;
3549
3550 if (node->type != SHAPE_TYPE_GROUP) {
3552 } else {
3554
3555 if (prop != NULL) {
3556 // GROUP_INFO properties always come in pairs, with the second giving the render mode
3557 prop++;
3558 }
3559 }
3560
3561 if (prop != NULL) {
3562 newMtg->renderMode = prop->data.s;
3563 } else {
3565 }
3566
3568 if (bb != NULL) {
3569 x = (bb->minX + bb->maxX) * 0.5f;
3570 y = (bb->minY + bb->maxY) * 0.5f;
3571 z = (bb->minZ + bb->maxZ) * 0.5f;
3572 } else {
3573 x = y = z = 0.0f;
3574 }
3575
3576 if (newMtg->bakedMtx != NULL) {
3577 guMtxXFML(newMtg->bakedMtx, x, y, z, &x, &y, &z);
3578 }
3579
3580 newMtg->center.x = x;
3581 newMtg->center.y = y;
3582 newMtg->center.z = z;
3583 enable_transform_group(modelID);
3584 }
3585}
3586
3587void enable_transform_group(u16 modelID) {
3589 s32 i;
3590
3591 group->flags &= ~TRANSFORM_GROUP_FLAG_INACTIVE;
3592
3593 for (i = group->minChildModelIndex; i <= group->maxChildModelIndex; i++) {
3594 Model* model = get_model_from_list_index(i);
3595
3597
3598 if (model->bakedMtx != NULL) {
3600 }
3601 }
3602}
3603
3604void disable_transform_group(u16 modelID) {
3606 s32 i;
3607
3609
3610 for (i = group->minChildModelIndex; i <= group->maxChildModelIndex; i++) {
3611 Model* model = get_model_from_list_index(i);
3612
3613 model->flags &= ~MODEL_FLAG_TRANSFORM_GROUP_MEMBER;
3614
3615 if (model->bakedMtx != NULL) {
3617 }
3618 }
3619}
3620
3621void clone_model(u16 srcModelID, u16 newModelID) {
3623 Model* newModel;
3624 s32 i;
3625
3626 for (i = 0; i < ARRAY_COUNT(*gCurrentModels); i++) {
3627 if ((*gCurrentModels)[i] == NULL) {
3628 break;
3629 }
3630 }
3631
3632 (*gCurrentModels)[i] = newModel = heap_malloc(sizeof(*newModel));
3633 *newModel = *srcModel;
3634 newModel->modelID = newModelID;
3635}
3636
3637void mdl_group_set_visibility(u16 treeIndex, s32 flags, s32 mode) {
3638 s32 maxGroupIndex = -1;
3639 s32 minGroupIndex;
3640 s32 modelIndex = (*gCurrentModelTreeNodeInfo)[treeIndex].modelIndex;
3641 s32 siblingIndex;
3642 s32 i;
3643
3644 if (modelIndex < MAX_MODELS - 1) {
3645 minGroupIndex = maxGroupIndex = modelIndex;
3646 } else {
3647 s32 treeDepth = (*gCurrentModelTreeNodeInfo)[treeIndex].treeDepth;
3648 for (i = treeIndex - 1; i >= 0; i--) {
3649 if ((*gCurrentModelTreeNodeInfo)[i].treeDepth <= treeDepth) {
3650 break;
3651 }
3652
3653 siblingIndex = (*gCurrentModelTreeNodeInfo)[i].modelIndex;
3654
3655 if (siblingIndex < MAX_MODELS - 1) {
3656 if (maxGroupIndex == -1) {
3657 maxGroupIndex = siblingIndex;
3658 }
3659 minGroupIndex = siblingIndex;
3660 }
3661 }
3662 }
3663
3664 if (mode < 2) {
3665 for (i = minGroupIndex; i <= maxGroupIndex; i++) {
3666 Model* model = (*gCurrentModels)[i];
3667 if (mode != MODEL_GROUP_HIDDEN) {
3668 model->flags &= ~flags;
3669 } else {
3670 model->flags |= flags;
3671 }
3672 }
3673 } else {
3674 for (i = 0; i < minGroupIndex; i++) {
3675 Model* model = (*gCurrentModels)[i];
3676 if (mode == MODEL_GROUP_OTHERS_VISIBLE) {
3677 model->flags &= ~flags;
3678 } else {
3679 model->flags |= flags;
3680 }
3681 }
3682 for (i = maxGroupIndex + 1; i < MAX_MODELS; i++) {
3683 Model* model = (*gCurrentModels)[i];
3684 if (model != NULL) {
3685 if (mode == MODEL_GROUP_OTHERS_VISIBLE) {
3686 model->flags &= ~flags;
3687 } else {
3688 model->flags |= flags;
3689 }
3690 }
3691 }
3692 }
3693}
3694
3695void mdl_group_set_custom_gfx(u16 groupModelID, s32 customGfxIndex, s32 tintType, b32 invertSelection) {
3696 s32 maxGroupIndex = -1;
3697 s32 i;
3698 s32 minGroupIndex;
3699 s32 modelIndex = (*gCurrentModelTreeNodeInfo)[groupModelID].modelIndex;
3700 s32 siblingIndex;
3701 s32 maskLow, maskHigh, packed;
3702
3703 if (modelIndex < MAX_MODELS - 1) {
3704 minGroupIndex = maxGroupIndex = modelIndex;
3705 } else {
3706 s32 treeDepth = (*gCurrentModelTreeNodeInfo)[groupModelID].treeDepth;
3707 for (i = groupModelID - 1; i >= 0; i--) {
3708 if ((*gCurrentModelTreeNodeInfo)[i].treeDepth <= treeDepth) {
3709 break;
3710 }
3711
3712 siblingIndex = (*gCurrentModelTreeNodeInfo)[i].modelIndex;
3713
3714 if (siblingIndex < MAX_MODELS - 1) {
3715 if (maxGroupIndex == -1) {
3716 maxGroupIndex = siblingIndex;
3717 }
3718 minGroupIndex = siblingIndex;
3719 }
3720 }
3721 }
3722
3723 maskLow = maskHigh = 0;
3724
3725 if (customGfxIndex < 0) {
3726 maskLow = 0xF;
3727 customGfxIndex = 0;
3728 }
3729
3730 if (tintType < 0) {
3731 maskHigh = 0xF0;
3732 tintType = 0;
3733 }
3734
3735 packed = customGfxIndex + (tintType << 4);
3736
3737 if (!invertSelection) {
3738 for (i = minGroupIndex; i <= maxGroupIndex; i++) {
3739 Model* model = (*gCurrentModels)[i];
3740 model->customGfxIndex = (model->customGfxIndex & (maskLow + maskHigh)) + packed;
3741 }
3742 } else {
3743 for (i = 0; i < minGroupIndex; i++) {
3744 Model* model = (*gCurrentModels)[i];
3745 model->customGfxIndex = (model->customGfxIndex & (maskLow + maskHigh)) + packed;
3746 }
3747 for (i = maxGroupIndex + 1; i < MAX_MODELS; i++) {
3748 Model* model = (*gCurrentModels)[i];
3749 if (model != NULL) {
3750 model->customGfxIndex = (model->customGfxIndex & (maskLow + maskHigh)) + packed;
3751 }
3752 }
3753 }
3754}
3755
3757 s32 i;
3758
3759 for (i = 0; i < ARRAY_COUNT(*gCurrentModels); i++) {
3760 Model* model = (*gCurrentModels)[i];
3761
3762 if (model != NULL) {
3763 model->flags &= ~MODEL_FLAG_HAS_TRANSFORM;
3764 }
3765 }
3766
3767 for (i = 0; i < ARRAY_COUNT(*gCurrentTransformGroups); i++) {
3768 ModelTransformGroup* transformGroup = (*gCurrentTransformGroups)[i];
3769
3770 if (transformGroup != NULL) {
3771 transformGroup->flags &= ~TRANSFORM_GROUP_FLAG_HAS_TRANSFORM;
3772 }
3773 }
3774}
3775
3777 gFogSettings->enabled = TRUE;
3778}
3779
3781 gFogSettings->enabled = FALSE;
3782}
3783
3784void set_world_fog_dist(s32 start, s32 end) {
3785 gFogSettings->startDistance = start;
3787}
3788
3789void set_world_fog_color(s32 r, s32 g, s32 b, s32 a) {
3790 gFogSettings->color.r = r;
3791 gFogSettings->color.g = g;
3792 gFogSettings->color.b = b;
3793 gFogSettings->color.a = a;
3794}
3795
3797 return gFogSettings->enabled;
3798}
3799
3800void get_world_fog_distance(s32* start, s32* end) {
3801 *start = gFogSettings->startDistance;
3802 *end = gFogSettings->endDistance;
3803}
3804
3805void get_world_fog_color(s32* r, s32* g, s32* b, s32* a) {
3806 *r = gFogSettings->color.r;
3807 *g = gFogSettings->color.g;
3808 *b = gFogSettings->color.b;
3809 *a = gFogSettings->color.a;
3810}
3811
3812void set_tex_panner(Model* model, s32 texPannerID) {
3813 model->texPannerID = texPannerID;
3814}
3815
3816void set_main_pan_u(s32 texPannerID, s32 value) {
3817 texPannerMainU[texPannerID] = value;
3818}
3819
3820void set_main_pan_v(s32 texPannerID, s32 value) {
3821 texPannerMainV[texPannerID] = value;
3822}
3823
3824void set_aux_pan_u(s32 texPannerID, s32 value) {
3825 texPannerAuxU[texPannerID] = value;
3826}
3827
3828void set_aux_pan_v(s32 texPannerID, s32 value) {
3829 texPannerAuxV[texPannerID] = value;
3830}
3831
3832void set_mdl_custom_gfx_set(Model* model, s32 customGfxIndex, u32 tintType) {
3833 if (customGfxIndex == -1) {
3834 customGfxIndex = model->customGfxIndex & 0xF;
3835 }
3836
3837 if (tintType == -1) {
3838 tintType = model->customGfxIndex >> 4;
3839 }
3840
3841 model->customGfxIndex = (customGfxIndex & 0xF) + ((tintType & 0xF) << 4);
3842}
3843
3844void set_custom_gfx(s32 customGfxIndex, Gfx* pre, Gfx* post) {
3845 (*gCurrentCustomModelGfxPtr)[customGfxIndex * 2] = pre;
3846 (*gCurrentCustomModelGfxPtr)[customGfxIndex * 2 + 1] = post;
3847}
3848
3850 (*gCurrentCustomModelGfxBuildersPtr)[customGfxIndex * 2] = pre;
3851 (*gCurrentCustomModelGfxBuildersPtr)[customGfxIndex * 2 + 1] = post;
3852}
3853
3855 Gfx* gfx = gMainGfxPos;
3858 s32 i;
3859
3860 // placeholder branch
3861 gSPBranchList(gMainGfxPos++, 0x00000000);
3862
3863 for (i = 0; i < ARRAY_COUNT(*gCurrentCustomModelGfxPtr) / 2; i++) {
3864 preFunc = (*gCurrentCustomModelGfxBuildersPtr)[i * 2];
3865
3866 if (preFunc != NULL) {
3867 (*gCurrentCustomModelGfxPtr)[i * 2] = gMainGfxPos;
3868 preFunc(i);
3869 gSPEndDisplayList(gMainGfxPos++);
3870 }
3871
3872 postFunc = (*gCurrentCustomModelGfxBuildersPtr)[i * 2 + 1];
3873 if (postFunc != NULL) {
3874 (*gCurrentCustomModelGfxPtr)[i * 2 + 1] = gMainGfxPos;
3875 postFunc(i);
3876 gSPEndDisplayList(gMainGfxPos++);
3877 }
3878 }
3879
3880 // overwrite placeholder with final branch address
3881 gSPBranchList(gfx, gMainGfxPos);
3882}
3883
3884// weird temps necessary to match
3887 s32* mtxIt = (s32*)mtx;
3888 s32* identityIt;
3889 s32 i;
3890
3891 if (mtx == NULL) {
3892 return TRUE;
3893 }
3894
3895 identityIt = (s32*)&ReferenceIdentityMtx;
3896
3897 for (i = 0; i < 16; i++, mtxIt++, identityIt++) {
3898 if (*mtxIt != *identityIt) {
3899 return FALSE;
3900 }
3901 }
3902
3903 return TRUE;
3904}
3905
3906void mdl_set_shroud_tint_params(u8 r, u8 g, u8 b, u8 a) {
3907 ShroudTintR = r;
3908 ShroudTintG = g;
3909 ShroudTintB = b;
3910 ShroudTintAmt = a;
3911}
3912
3913void mdl_get_shroud_tint_params(u8* r, u8* g, u8* b, u8* a) {
3914 *r = ShroudTintR;
3915 *g = ShroudTintG;
3916 *b = ShroudTintB;
3917 *a = ShroudTintAmt;
3918}
3919
3920void mdl_set_depth_tint_params(u8 primR, u8 primG, u8 primB, u8 primA, u8 fogR, u8 fogG, u8 fogB, s32 fogStart, s32 fogEnd) {
3921 DepthTintBaseR = primR;
3922 DepthTintBaseG = primG;
3923 DepthTintBaseB = primB;
3924 DepthTintBaseA = primA;
3925 DepthTintColR = fogR;
3926 DepthTintColG = fogG;
3927 DepthTintColB = fogB;
3928 DepthTintStart = fogStart;
3929 DepthTintEnd = fogEnd;
3930}
3931
3932void mdl_get_depth_tint_params(u8* primR, u8* primG, u8* primB, u8* primA, u8* fogR, u8* fogG, u8* fogB,
3933 s32* fogStart, s32* fogEnd) {
3934 *primR = DepthTintBaseR;
3935 *primG = DepthTintBaseG;
3936 *primB = DepthTintBaseB;
3937 *primA = DepthTintBaseA;
3938 *fogR = DepthTintColR;
3939 *fogG = DepthTintColG;
3940 *fogB = DepthTintColB;
3941 *fogStart = DepthTintStart;
3942 *fogEnd = DepthTintEnd;
3943}
3944
3945void mdl_set_remap_tint_params(u8 maxR, u8 maxG, u8 maxB, u8 minR, u8 minG, u8 minB) {
3946 RemapTintMaxR = maxR;
3947 RemapTintMaxG = maxG;
3948 RemapTintMaxB = maxB;
3949 RemapTintMinR = minR;
3950 RemapTintMinG = minG;
3951 RemapTintMinB = minB;
3952}
3953
3954void mdl_get_remap_tint_params(u8* primR, u8* primG, u8* primB, u8* envR, u8* envG, u8* envB) {
3955 *primR = RemapTintMaxR;
3956 *primG = RemapTintMaxG;
3957 *primB = RemapTintMaxB;
3958 *envR = RemapTintMinR;
3959 *envG = RemapTintMinG;
3960 *envB = RemapTintMinB;
3961}
3962
3963void mdl_get_vertex_count(Gfx* gfx, s32* numVertices, Vtx** baseVtx, s32* gfxCount, Vtx* baseAddr) {
3964 s8 stuff[2];
3965
3966 s32 vtxCount;
3967 u32 w0, w1;
3968 u32 cmd;
3969 u32 vtxEndAddr;
3970 s32 minVtx;
3971 s32 maxVtx;
3972 u32 vtxStartAddr;
3973
3974 minVtx = 0;
3975 maxVtx = 0;
3976
3977 if (gfx == NULL) {
3978 *numVertices = 0;
3979 *baseVtx = NULL;
3980 } else {
3981 Gfx* baseGfx = gfx;
3982
3983 do {
3984 w0 = gfx->words.w0;
3985 w1 = gfx->words.w1;
3986 cmd = _SHIFTR(w0,24,8);
3987
3988 if (cmd == G_VTX) {
3989 vtxStartAddr = w1;
3990 if (baseAddr != NULL) {
3991 vtxStartAddr = (vtxStartAddr & 0xFFFF) + (s32)baseAddr;
3992 }
3993 vtxCount = _SHIFTR(w0,12,8);
3994 if (minVtx == 0) {
3995 minVtx = vtxStartAddr;
3996 maxVtx = vtxStartAddr + (vtxCount * sizeof(Vtx));
3997 }
3998 vtxEndAddr = vtxStartAddr + (vtxCount * sizeof(Vtx));
3999 if (maxVtx < vtxEndAddr) {
4000 maxVtx = vtxEndAddr;
4001 }
4002 if (minVtx > vtxEndAddr) {
4003 minVtx = vtxEndAddr;
4004 }
4005 }
4006 gfx++;
4007 } while (cmd != G_ENDDL);
4008
4009 *numVertices = (maxVtx - minVtx) >> 4;
4010 *baseVtx = (Vtx*)minVtx;
4011 *gfxCount = gfx - baseGfx;
4012 w1 = 64; // TODO required to match -- can be any operation that stores w1
4013 }
4014}
4015
4016void mdl_local_gfx_update_vtx_pointers(Gfx *nodeDlist, Vtx *baseVtx, Gfx *arg2, Vtx *arg3) {
4017 u32 w0;
4018 Vtx* w1;
4019 do {
4020 w0 = (*((unsigned long long*)nodeDlist)) >> 0x20; // TODO required to match
4021 w1 = (Vtx*)nodeDlist->words.w1;
4022 if (w0 >> 0x18 == G_VTX) {
4023 w1 = arg3 + (w1 - baseVtx);
4024 }
4025 arg2->words.w0 = w0;
4026 arg2->words.w1 = (u32)w1;
4027 nodeDlist++;
4028 arg2++;
4029 } while (w0 >> 0x18 != G_ENDDL);
4030}
4031
4032void mdl_local_gfx_copy_vertices(Vtx* src, s32 num, Vtx* dest) {
4033 u32 i;
4034
4035 for (i = 0; i < num * sizeof(*src); i++) {
4036 ((u8*)dest)[i] = ((u8*)src)[i];
4037 }
4038}
4039
4040
4041void mdl_make_local_vertex_copy(s32 copyIndex, u16 modelID, s32 isMakingCopy) {
4042 s32 numVertices;
4043 Vtx* baseVtx;
4044 s32 gfxCount;
4045 Gfx* nodeDlist;
4046 Model* model;
4048 s32 i;
4049
4051 nodeDlist = model->modelNode->displayData->displayList;
4052 mdl_get_vertex_count(nodeDlist, &numVertices, &baseVtx, &gfxCount, NULL);
4053
4054 copy = (*gCurrentModelLocalVtxBuffers)[copyIndex] = heap_malloc(sizeof(*copy));
4055
4056 if (isMakingCopy) {
4057 for (i = 0; i < ARRAY_COUNT(copy->gfxCopy); i++) {
4058 copy->gfxCopy[i] = heap_malloc(gfxCount * sizeof(*copy->gfxCopy[i]));
4059 copy->vtxCopy[i] = heap_malloc(numVertices * sizeof(*copy->vtxCopy[i]));
4060 mdl_local_gfx_update_vtx_pointers(nodeDlist, baseVtx, copy->gfxCopy[i], copy->vtxCopy[i]);
4061 mdl_local_gfx_copy_vertices(baseVtx, numVertices, copy->vtxCopy[i]);
4062 }
4064 } else {
4065 for (i = 0; i < ARRAY_COUNT(copy->gfxCopy); i++) {
4066 copy->gfxCopy[i] = NULL;
4067 copy->vtxCopy[i] = NULL;
4068 }
4069 model->flags |= MODEL_FLAG_HIDDEN;
4070 }
4071
4072 copy->selector = 0;
4073 copy->numVertices = numVertices;
4074 copy->minVertexAddr = baseVtx;
4075}
4076
4077void mdl_get_copied_vertices(s32 copyIndex, Vtx** firstVertex, Vtx** copiedVertices, s32* numCopied) {
4078 ModelLocalVertexCopy* mlvc = (*gCurrentModelLocalVtxBuffers)[copyIndex];
4079 s32 selector = mlvc->selector;
4080
4081 *firstVertex = mlvc->minVertexAddr;
4082 *copiedVertices = mlvc->vtxCopy[selector];
4083 *numCopied = mlvc->numVertices;
4084}
4085
4086Gfx* mdl_get_copied_gfx(s32 copyIndex) {
4087 ModelLocalVertexCopy* mlvc = (*gCurrentModelLocalVtxBuffers)[copyIndex];
4088 s32 selector = mlvc->selector;
4089 Gfx* gfxCopy = mlvc->gfxCopy[selector];
4090
4091 mlvc->selector++;
4092 if (mlvc->selector > ARRAY_COUNT(mlvc->gfxCopy) - 1) {
4093 mlvc->selector = 0;
4094 }
4095
4096 return gfxCopy;
4097}
4098
4099void mdl_project_tex_coords(s32 modelID, Gfx* outGfx, Matrix4f arg2, Vtx* arg3) {
4100 s32 sp18;
4101 Vtx* baseVtx;
4102 s32 sp20;
4103 f32 v1tc1;
4104 f32 v2tc1;
4105 f32 sp2C;
4106 f32 v0tc1;
4107 f32 sp40;
4108 f32 v1tc0;
4109 f32 v1ob2;
4110 f32 ob2;
4111 f32 ob1;
4112 f32 v0ob0;
4113 f32 v0ob2;
4114 f32 v0tc0;
4115 f32 v2ob0;
4116 f32 v2tc0;
4117 f32 v1ob0;
4118 f32 v2ob2;
4119 f32 ob0;
4120 f32 var_f10;
4121 f32 var_f24;
4122 f32 var_f26;
4123 f32 tc1;
4124 f32 var_f30;
4125 f32 tc0;
4126 f32 var_f6_2;
4127 s32 i;
4128 u32 cnB;
4129 u32 cnG;
4130 u32 cnR;
4131 f32 var_f20;
4132
4133 s32 listIndex;
4134 Model* model;
4135 Gfx* dlist;
4136 s32 cmd;
4137 Vtx* tempVert;
4138
4139 s8 zero = 0; // TODO needed to match
4140
4141 listIndex = get_model_list_index_from_tree_index(modelID & 0xFFFF);
4142 model = get_model_from_list_index(listIndex);
4143 dlist = model->modelNode->displayData->displayList;
4144
4145 while (TRUE) {
4146 cmd = dlist->words.w0 >> 0x18;
4147 tempVert = (Vtx*)dlist->words.w1;
4148 if (cmd == G_ENDDL) {
4149 break;
4150 }
4151 if (cmd == G_VTX) {
4152 baseVtx = tempVert;
4153 break;
4154 }
4155 dlist++;
4156 }
4157
4158 v0ob0 = baseVtx[zero].v.ob[0];
4159 v0ob2 = baseVtx[zero].v.ob[2];
4160 v0tc0 = baseVtx[zero].v.tc[0];
4161 v0tc1 = baseVtx[zero].v.tc[1];
4162
4163 v1ob0 = baseVtx[1].v.ob[0];
4164 v1ob2 = baseVtx[1].v.ob[2];
4165 v1tc0 = baseVtx[1].v.tc[0];
4166 v1tc1 = baseVtx[1].v.tc[1];
4167
4168 v2ob0 = baseVtx[2].v.ob[0];
4169 v2ob2 = baseVtx[2].v.ob[2];
4170 v2tc0 = baseVtx[2].v.tc[0];
4171 v2tc1 = baseVtx[2].v.tc[1];
4172
4173 cnR = baseVtx[0].v.cn[0];
4174 cnG = baseVtx[0].v.cn[1];
4175 cnB = baseVtx[0].v.cn[2];
4176
4177 if (v0ob0 != v1ob0) {
4178 f32 f2 = v0ob0 - v2ob0;
4179 f32 f14 = v0ob0 - v1ob0;
4180 f32 f8 = v0tc0 - v1tc0;
4181 f32 f2a = f2 / f14;
4182 f32 f0 = f2a * f8;
4183 f32 f12 = v0ob2 - v1ob2;
4184 f32 f10 = f2a * f12;
4185 f32 f4 = v0tc0 - v2tc0;
4186 f32 f6 = v0ob2 - v2ob2;
4187 f32 f0a = f0 - f4;
4188 f32 f10a = f10 - f6;
4189
4190 f32 f0b, f4a, f2b, f8a, f6a, f0c, f8b, f2c, f12a, f2d, f4b, f0d, f6b, f0e;
4191
4192 sp40 = f0a / f10a; // used later
4193 f0b = f12 * sp40;
4194 f4a = v0tc1 - v1tc1;
4195 f2b = f2a * f4a;
4196 f8a = f8 - f0b;
4197 var_f30 = f8a / f14; // used later
4198 f6a = var_f30 * v0ob0;
4199 f0c = v0tc1 - v2tc1;
4200 f2c = f2b - f0c;
4201 var_f26 = f2c / f10a; // used later
4202 f12a = f12 * var_f26;
4203 var_f24 = (f4a - f12a) / f14; // used later
4204 sp2C = v0tc0 - f6a - sp40 * v0ob2; // used later
4205 var_f20 = v0tc1 - var_f24 * v0ob0 - var_f26 * v0ob2; // used later
4206 } else {
4207 f32 f2 = v0ob2 - v2ob2;
4208 f32 f14 = v0ob2 - v1ob2;
4209 f32 f8 = v0tc0 - v1tc0;
4210 f32 f12 = v0ob0 - v1ob0;
4211 f32 f4 = v0tc0 - v2tc0;
4212 f32 f6 = v0ob0 - v2ob0;
4213 f32 f0 = f2 / f14 * f8;
4214 f32 f10 = f2 / f14 * f12;
4215
4216 f32 f0b, f4a, f2b, f8a, f6a, f0c, f8b, f2c, f12a, f2d, f4b, f0d, f6b, f0e;
4217
4218 var_f30 = (f0 - f4) / (f10 - f6); // used later
4219 f0b = f12 * var_f30;
4220 f6a = var_f30 * v0ob0;
4221 f4a = v0tc1 - v1tc1;
4222 f2b = f2 / f14 * f4a;
4223 f8a = f8 - f0b;
4224 sp40 = f8a / f14; // used later
4225 f8b = sp40 * v0ob2;
4226 f0c = v0tc1 - v2tc1;
4227 var_f24 = (f2b - f0c) / (f10 - f6); // used later
4228 var_f26 = (f4a - f12 * var_f24) / f14; // used later
4229 sp2C = v0tc0 - f6a - f8b; // used later
4230 var_f20 = v0tc1 - var_f24 * v0ob0 - var_f26 * v0ob2; // used later
4231 }
4232
4233 mdl_get_vertex_count(outGfx, &sp18, &baseVtx, &sp20, arg3);
4234
4235 for (i = 0; i < sp18; i++) {
4236 ob0 = baseVtx->v.ob[0];
4237 ob1 = baseVtx->v.ob[1];
4238 ob2 = baseVtx->v.ob[2];
4239 if (arg2 != NULL) {
4240 var_f10 = (arg2[0][0] * ob0) + (arg2[1][0] * ob1) + (arg2[2][0] * ob2) + arg2[3][0];
4241 var_f6_2 = (arg2[0][2] * ob0) + (arg2[1][2] * ob1) + (arg2[2][2] * ob2) + arg2[3][2];
4242 } else {
4243 var_f10 = ob0;
4244 var_f6_2 = ob2;
4245 }
4246 tc0 = (var_f30 * var_f10) + (sp40 * var_f6_2) + sp2C;
4247 tc1 = (var_f24 * var_f10) + (var_f26 * var_f6_2) + var_f20;
4248 if (tc0 < 0.0f) {
4249 tc0 -= 0.5;
4250 } else if (tc0 > 0.0f) {
4251 tc0 += 0.5;
4252 }
4253
4254 if (tc1 < 0.0f) {
4255 tc1 -= 0.5;
4256 } else if (tc1 > 0.0f) {
4257 tc1 += 0.5;
4258 }
4259
4260 baseVtx->v.tc[0] = tc0;
4261 baseVtx->v.tc[1] = tc1;
4262 baseVtx->v.cn[0] = cnR;
4263 baseVtx->v.cn[1] = cnG;
4264 baseVtx->v.cn[2] = cnB;
4265 baseVtx++;
4266 }
4267}
4268
4269// Checks if the center of a model is visible.
4270// If `depthQueryID` is nonnegative, the depth buffer is checked to see if the model's center is occluded by geometry.
4271// Otherwise, the occlusion check is skipped.
4272// `depthQueryID` must be between 0 and the size of `DepthCopyBuffer` minus 1.
4273// Every nonnegative value of `depthQueryID` must be unique within a frame, otherwise the result will corrupt the data
4274// of the previous query that shared the same ID.
4275// Occlusion visibility checks are always one frame out of date, as they reference the previous frame's depth buffer.
4276s32 is_model_center_visible(u16 modelID, s32 depthQueryID, f32* screenX, f32* screenY) {
4277 Camera* camera = &gCameras[gCurrentCameraID];
4279 f32 outX;
4280 f32 outY;
4281 f32 outZ;
4282 f32 outW;
4283
4284 s32 depthExponent;
4285 s32 depthMantissa;
4286 u32 shiftedMantissa, mantissaBias;
4287 u32 decodedDepth;
4288 s32 scaledDepth;
4289
4290 // If an invalid depth query id was provided, return false.
4291 if (depthQueryID >= ARRAY_COUNT(DepthCopyBuffer)) {
4292 return FALSE;
4293 }
4294 // Transform the model's center into clip space.
4295 transform_point(camera->mtxPerspective, model->center.x, model->center.y, model->center.z, 1.0f, &outX, &outY, &outZ, &outW);
4296 if (outW == 0.0f) {
4297 *screenX = 0.0f;
4298 *screenY = 0.0f;
4299 return TRUE;
4300 }
4301 // Perform the perspective divide (divide xyz by w) to convert to normalized device coords.
4302 // Normalized device coords have a range of (-1, 1) on each axis.
4303 outW = 1.0f / outW;
4304 outX *= outW;
4305 outY *= -outW;
4306 outZ *= outW;
4307 // Perform the viewport transform for x and y (convert normalized device coords to viewport coords).
4308 // Viewport coords have a range of (0, Width) for x and (0, Height) for y.
4309 outX = (outX * camera->viewportW + camera->viewportW) * 0.5;
4310 outX += camera->viewportStartX;
4311 outY = (outY * camera->viewportH + camera->viewportH) * 0.5;
4312 outY += camera->viewportStartY;
4313 // Convert depth from (-1, 1) to (0, 1).
4314 outZ = (outZ + 1.0f) * 0.5;
4315 // Write out the calculated x and y values.
4316 *screenX = (s32)outX;
4317 *screenY = (s32)outY;
4318 // If a depth query wasn't requested, simply check if the point is within the view frustum.
4319 if (depthQueryID < 0) {
4320 if (outZ > 0.0f) {
4321 return FALSE;
4322 } else {
4323 return TRUE;
4324 }
4325 }
4326 if (outX >= 0.0f && outY >= 0.0f && outX < 320.0f && outY < 240.0f) {
4327 gDPPipeSync(gMainGfxPos++);
4328 // Load a 4x1 pixel tile of the depth buffer
4329 gDPLoadTextureTile(gMainGfxPos++, osVirtualToPhysical(&nuGfxZBuffer[(s32) outY * SCREEN_WIDTH]), G_IM_FMT_RGBA, G_IM_SIZ_16b, SCREEN_WIDTH, 1,
4330 (s32) outX, 0, (s32) outX + 3, 0,
4331 0,
4332 G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMIRROR | G_TX_WRAP,
4333 9, G_TX_NOMASK,
4334 G_TX_NOLOD, G_TX_NOLOD);
4335 gDPPipeSync(gMainGfxPos++);
4336 // Set the current color image to the buffer where copied depth values are stored.
4337 gDPSetColorImage(gMainGfxPos++, G_IM_FMT_RGBA, G_IM_SIZ_16b, SCREEN_WIDTH, DepthCopyBuffer);
4338 gDPPipeSync(gMainGfxPos++);
4339 // Set up 1 cycle mode and all other relevant othermode params.
4340 // One cycle mode must be used here because only one pixel is copied, and copy mode only supports multiples of 4 pixels.
4341 gDPSetCycleType(gMainGfxPos++, G_CYC_1CYCLE);
4342 gDPSetRenderMode(gMainGfxPos++, G_RM_OPA_SURF, G_RM_OPA_SURF2);
4343 gDPSetCombineMode(gMainGfxPos++, G_CC_DECALRGBA, G_CC_DECALRGBA);
4344 gDPSetTextureFilter(gMainGfxPos++, G_TF_POINT);
4345 gDPSetTexturePersp(gMainGfxPos++, G_TP_NONE);
4346 gSPTexture(gMainGfxPos++, 0xFFFF, 0xFFFF, 0, G_TX_RENDERTILE, G_ON);
4347 gDPSetTextureLUT(gMainGfxPos++, G_TT_NONE);
4348 gDPSetTextureDetail(gMainGfxPos++, G_TD_CLAMP);
4349 gDPSetTextureLOD(gMainGfxPos++, G_TL_TILE);
4350 // Adjust the scissor to only draw to the specified pixel.
4351 gDPSetScissor(gMainGfxPos++, G_SC_NON_INTERLACE, depthQueryID, 0, depthQueryID + 1, 1);
4352 // Draw a texrect to copy one pixel of the loaded depth tile to the output buffer.
4353 gSPTextureRectangle(gMainGfxPos++, depthQueryID << 2, 0 << 2, 4 << 2, 1 << 2, G_TX_RENDERTILE, (s32) outX << 5, 0, 1 << 10, 1 << 10);
4354 // Sync and swap the color image back to the current framebuffer.
4355 gDPPipeSync(gMainGfxPos++);
4356 gDPSetColorImage(gMainGfxPos++, G_IM_FMT_RGBA, G_IM_SIZ_16b, SCREEN_WIDTH, osVirtualToPhysical(nuGfxCfb_ptr));
4357 gDPPipeSync(gMainGfxPos++);
4358 // Reconfigure the frame's normal scissor.
4359 gDPSetScissor(gMainGfxPos++, G_SC_NON_INTERLACE, camera->viewportStartX, camera->viewportStartY, camera->viewportStartX + camera->viewportW, camera->viewportStartY + camera->viewportH);
4360
4361 // 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.
4362
4363 // Extract the exponent and mantissa from the depth buffer value.
4364 depthExponent = DepthCopyBuffer[depthQueryID] >> DEPTH_EXPONENT_SHIFT;
4365 depthMantissa = (DepthCopyBuffer[depthQueryID] & (DEPTH_MANTISSA_MASK | DEPTH_DZ_MASK)) >> DEPTH_MANTISSA_SHIFT;
4366 // Convert the exponent and mantissa into a fixed-point value.
4367 shiftedMantissa = depthMantissa << DepthFloatLookupTable[depthExponent].shift;
4368 mantissaBias = DepthFloatLookupTable[depthExponent].bias;
4369 // Remove the 3 fractional bits of precision.
4370 decodedDepth = (shiftedMantissa + mantissaBias) >> 3;
4371 // Convert the calculated screen depth into viewport depth.
4372 scaledDepth = outZ * MAX_VIEWPORT_DEPTH;
4373 if (decodedDepth < scaledDepth) {
4374 return FALSE;
4375 }
4376 }
4377 return outZ > 0.0f;
4378}
4379
4380// Checks if a point is visible on screen.
4381// If `depthQueryID` is nonnegative, the depth buffer is checked to see if the point is occluded by geometry.
4382// Otherwise, the occlusion check is skipped.
4383// `depthQueryID` must be between 0 and the size of `DepthCopyBuffer` minus 1.
4384// Every nonnegative value of `depthQueryID` must be unique within a frame, otherwise the result will corrupt the data
4385// of the previous query that shared the same ID.
4386// Occlusion visibility checks are always one frame out of date, as they reference the previous frame's depth buffer.
4387OPTIMIZE_OFAST s32 is_point_visible(f32 x, f32 y, f32 z, s32 depthQueryID, f32* screenX, f32* screenY) {
4388 Camera* camera = &gCameras[gCurrentCameraID];
4389 f32 outX;
4390 f32 outY;
4391 f32 outZ;
4392 f32 outW;
4393
4394 s32 depthExponent;
4395 s32 depthMantissa;
4396 u32 shiftedMantissa, mantissaBias;
4397 u32 decodedDepth;
4398 s32 scaledDepth;
4399
4400 // If an invalid depth query id was provided, return false.
4401 if (depthQueryID >= ARRAY_COUNT(DepthCopyBuffer)) {
4402 return FALSE;
4403 }
4404 // Transform the point into clip space.
4405 transform_point(camera->mtxPerspective, x, y, z, 1.0f, &outX, &outY, &outZ, &outW);
4406 if (outW == 0.0f) {
4407 *screenX = 0.0f;
4408 *screenY = 0.0f;
4409 return TRUE;
4410 }
4411 // Perform the perspective divide (divide xyz by w) to convert to normalized device coords.
4412 // Normalized device coords have a range of (-1, 1) on each axis.
4413 outW = 1.0f / outW;
4414 outX *= outW;
4415 outY *= -outW;
4416 outZ *= outW;
4417 // Perform the viewport transform for x and y (convert normalized device coords to viewport coords).
4418 // Viewport coords have a range of (0, Width) for x and (0, Height) for y.
4419 outX = (outX * camera->viewportW + camera->viewportW) * 0.5;
4420 outX += camera->viewportStartX;
4421 outY = (outY * camera->viewportH + camera->viewportH) * 0.5;
4422 outY += camera->viewportStartY;
4423 // Convert depth from (-1, 1) to (0, 1).
4424 outZ = (outZ + 1.0f) * 0.5;
4425 // Write out the calculated x and y values.
4426 *screenX = outX;
4427 *screenY = outY;
4428 // If a depth query wasn't requested, simply check if the point is within the view frustum.
4429 if (depthQueryID < 0) {
4430 return outZ > 0.0f;
4431 }
4432 if (outX >= 0.0f && outY >= 0.0f && outX < 320.0f && outY < 240.0f) {
4433 gDPPipeSync(gMainGfxPos++);
4434 // Load a 4x1 pixel tile of the depth buffer
4435 gDPLoadTextureTile(gMainGfxPos++, osVirtualToPhysical(&nuGfxZBuffer[(s32) outY * SCREEN_WIDTH]), G_IM_FMT_RGBA, G_IM_SIZ_16b, SCREEN_WIDTH, 1,
4436 (s32) outX, 0, (s32) outX + 3, 0,
4437 0,
4438 G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMIRROR | G_TX_WRAP,
4439 9, G_TX_NOMASK,
4440 G_TX_NOLOD, G_TX_NOLOD);
4441 gDPPipeSync(gMainGfxPos++);
4442 // Set the current color image to the buffer where copied depth values are stored.
4443 gDPSetColorImage(gMainGfxPos++, G_IM_FMT_RGBA, G_IM_SIZ_16b, SCREEN_WIDTH, DepthCopyBuffer);
4444 gDPPipeSync(gMainGfxPos++);
4445 // Set up 1 cycle mode and all other relevant othermode params.
4446 // One cycle mode must be used here because only one pixel is copied, and copy mode only supports multiples of 4 pixels.
4447 gDPSetCycleType(gMainGfxPos++, G_CYC_1CYCLE);
4448 gDPSetRenderMode(gMainGfxPos++, G_RM_OPA_SURF, G_RM_OPA_SURF2);
4449 gDPSetCombineMode(gMainGfxPos++, G_CC_DECALRGBA, G_CC_DECALRGBA);
4450 gDPSetTextureFilter(gMainGfxPos++, G_TF_POINT);
4451 gDPSetTexturePersp(gMainGfxPos++, G_TP_NONE);
4452 gSPTexture(gMainGfxPos++, 0xFFFF, 0xFFFF, 0, G_TX_RENDERTILE, G_ON);
4453 gDPSetTextureLUT(gMainGfxPos++, G_TT_NONE);
4454 gDPSetTextureDetail(gMainGfxPos++, G_TD_CLAMP);
4455 gDPSetTextureLOD(gMainGfxPos++, G_TL_TILE);
4456 // Adjust the scissor to only draw to the specified pixel.
4457 gDPSetScissor(gMainGfxPos++, G_SC_NON_INTERLACE, depthQueryID, 0, depthQueryID + 1, 1);
4458 // Draw a texrect to copy one pixel of the loaded depth tile to the output buffer.
4459 gSPTextureRectangle(gMainGfxPos++, depthQueryID << 2, 0 << 2, (depthQueryID + 1) << 2, 1 << 2, G_TX_RENDERTILE, (s32) outX << 5, 0, 1 << 10, 1 << 10);
4460 // Sync and swap the color image back to the current framebuffer.
4461 gDPPipeSync(gMainGfxPos++);
4462 gDPSetColorImage(gMainGfxPos++, G_IM_FMT_RGBA, G_IM_SIZ_16b, SCREEN_WIDTH, osVirtualToPhysical(nuGfxCfb_ptr));
4463 gDPPipeSync(gMainGfxPos++);
4464 // Reconfigure the frame's normal scissor.
4465 gDPSetScissor(gMainGfxPos++, G_SC_NON_INTERLACE, camera->viewportStartX, camera->viewportStartY, camera->viewportStartX + camera->viewportW, camera->viewportStartY + camera->viewportH);
4466
4467 // 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.
4468
4469 // Extract the exponent and mantissa from the depth buffer value.
4470 depthExponent = DepthCopyBuffer[depthQueryID] >> DEPTH_EXPONENT_SHIFT;
4471 depthMantissa = (DepthCopyBuffer[depthQueryID] & (DEPTH_MANTISSA_MASK | DEPTH_DZ_MASK)) >> DEPTH_MANTISSA_SHIFT;
4472 // Convert the exponent and mantissa into a fixed-point value.
4473 shiftedMantissa = depthMantissa << DepthFloatLookupTable[depthExponent].shift;
4474 mantissaBias = DepthFloatLookupTable[depthExponent].bias;
4475 // Remove the 3 fractional bits of precision.
4476 decodedDepth = (shiftedMantissa + mantissaBias) >> 3;
4477 // Convert the calculated screen depth into viewport depth.
4478 scaledDepth = outZ * MAX_VIEWPORT_DEPTH;
4479 if (decodedDepth < scaledDepth) {
4480 return FALSE;
4481 }
4482 }
4483 return outZ > 0.0f;
4484}
4485
4486void mdl_draw_hidden_panel_surface(Gfx** arg0, u16 treeIndex) {
4488 Model copied = *model;
4489 Gfx* oldGfxPos;
4490 s32 flag;
4491
4492 if (*arg0 == gMainGfxPos) {
4493 flag = 1;
4494 }
4495
4496 oldGfxPos = gMainGfxPos;
4497 gMainGfxPos = *arg0;
4498
4500 appendGfx_model(&copied);
4501
4502 *arg0 = gMainGfxPos;
4503
4504 if (flag == 0) {
4505 gMainGfxPos = oldGfxPos;
4506 }
4507}
4508
4510 u32 offset = TextureHeapPos - TextureHeapBase + 0x3F;
4511
4512 offset = (offset >> 6) << 6;
4513
4515 return NULL;
4516 } else {
4517 return TextureHeapBase + offset;
4518 }
4519}
4520
4521void mdl_set_all_tint_type(s32 tintType) {
4522 ModelList* modelList = gCurrentModels;
4523 Model* model;
4524 s32 type = tintType; // weirdness here and the next line needed to match
4525 s32 i = tintType;
4526
4527 for (i = 0; i < ARRAY_COUNT(*modelList); i++) {
4528 model = (*modelList)[i];
4529
4530 if (model != NULL) {
4532 }
4533 }
4534}
4535
4537 s32 i;
4538
4539 for (i = 0; i < ARRAY_COUNT(ClearRenderTaskLists); i++) {
4541 }
4542
4543 for (i = 0; i < ARRAY_COUNT(RenderTaskCount); i++) {
4544 RenderTaskCount[i] = 0;
4545 }
4546}
4547
4549 s32 dist = RenderTaskBasePriorities[task->renderMode] - task->dist;
4550 s32 listIdx = RENDER_TASK_LIST_MID;
4551 if (dist >= 3000000) listIdx = RENDER_TASK_LIST_FAR;
4552 else if (dist < 800000) listIdx = RENDER_TASK_LIST_NEAR;
4553
4554 RenderTask* ret = RenderTaskLists[listIdx];
4555
4557
4558 ret = &ret[RenderTaskCount[listIdx]++];
4559
4563 }
4564
4565 ret->appendGfxArg = task->appendGfxArg;
4566 ret->appendGfx = task->appendGfx;
4567 ret->dist = dist;
4568
4569 return ret;
4570}
4571
4573 s32 i, j;
4575 s32* sorted;
4576 RenderTask* taskList;
4577 RenderTask* task;
4578 RenderTask* task2;
4579 Matrix4f mtxFlipY;
4580 void (*appendGfx)(void*);
4581 s32 tmp;
4582
4583 for (s32 j = 0; j < ARRAY_COUNT(RenderTaskCount); j++) {
4584 for (i = 0; i < RenderTaskCount[j]; i++) {
4585 sorteds[j][i] = i;
4586 }
4587 }
4588
4589 // sort in ascending order of dist
4591 sorted = &sorteds[RENDER_TASK_LIST_MID];
4592#define LESS(i, j) taskList[sorted[i]].dist < taskList[sorted[j]].dist
4593#define SWAP(i, j) tmp = sorted[i], sorted[i] = sorted[j], sorted[j] = tmp
4595
4596 // tasks with dist >= 3M sort in descending order
4598 sorted = &sorteds[RENDER_TASK_LIST_FAR];
4599#define LESS(i, j) taskList[sorted[i]].dist > taskList[sorted[j]].dist
4601
4602 // tasks with dist <= 800k sort in descending order
4604 sorted = &sorteds[RENDER_TASK_LIST_NEAR];
4606
4609 Mtx* dispMtx;
4610 Gfx* savedGfxPos = NULL;
4611
4612 guScaleF(mtxFlipY, 1.0f, -1.0f, 1.0f);
4615 for (j = 0; j < NUM_RENDER_TASK_LISTS; j++) {
4616 for (i = 0; i < RenderTaskCount[j]; i++) {
4617 task = &RenderTaskLists[j][sorteds[j][i]];
4618 appendGfx = task->appendGfx;
4619
4621 savedGfxPos = gMainGfxPos++;
4622 }
4623
4624 appendGfx(task->appendGfxArg);
4625
4627 gSPEndDisplayList(gMainGfxPos++);
4628 gSPBranchList(savedGfxPos, gMainGfxPos);
4629 gSPDisplayList(gMainGfxPos++, savedGfxPos + 1);
4630 gSPMatrix(gMainGfxPos++, dispMtx, G_MTX_NOPUSH | G_MTX_MUL | G_MTX_PROJECTION);
4631 gSPDisplayList(gMainGfxPos++, savedGfxPos + 1);
4632 gSPMatrix(gMainGfxPos++, &gDisplayContext->camPerspMatrix[gCurrentCamID], G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_PROJECTION);
4633 }
4634 }
4635 }
4636 } else {
4637 for (j = 0; j < NUM_RENDER_TASK_LISTS; j++) {
4638 for (i = 0; i < RenderTaskCount[j]; i++) {
4639 task = &RenderTaskLists[j][sorteds[j][i]];
4640 appendGfx = task->appendGfx;
4641 appendGfx(task->appendGfxArg);
4642 }
4643 }
4644 }
4645
4649}
u16 * nuGfxCfb_ptr
Definition cam_main.c:14
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:4398
@ ENV_TINT_SHROUD
Definition enums.h:4387
@ ENV_TINT_DEPTH
Definition enums.h:4389
@ ENV_TINT_REMAP
Definition enums.h:4393
@ ENV_TINT_NONE
Definition enums.h:4385
@ TRANSFORM_GROUP_FLAG_INACTIVE
Definition enums.h:5082
@ TRANSFORM_GROUP_FLAG_HIDDEN
Definition enums.h:5081
@ TRANSFORM_GROUP_FLAG_VALID
Definition enums.h:5080
@ TRANSFORM_GROUP_FLAG_MATRIX_DIRTY
Definition enums.h:5084
@ TRANSFORM_GROUP_FLAG_IGNORE_MATRIX
Definition enums.h:5085
@ RENDER_MODE_IDX_1D
Definition enums.h:3223
@ RENDER_MODE_IDX_14
Definition enums.h:3214
@ RENDER_MODE_IDX_29
Definition enums.h:3236
@ RENDER_MODE_IDX_18
Definition enums.h:3218
@ RENDER_MODE_IDX_2B
Definition enums.h:3238
@ RENDER_MODE_IDX_0B
Definition enums.h:3204
@ RENDER_MODE_IDX_3A
Definition enums.h:3254
@ RENDER_MODE_IDX_1B
Definition enums.h:3221
@ RENDER_MODE_IDX_26
Definition enums.h:3233
@ RENDER_MODE_IDX_16
Definition enums.h:3216
@ RENDER_MODE_IDX_33
Definition enums.h:3246
@ RENDER_MODE_IDX_15
Definition enums.h:3215
@ RENDER_MODE_IDX_39
Definition enums.h:3253
@ RENDER_MODE_IDX_34
Definition enums.h:3247
@ RENDER_MODE_IDX_07
Definition enums.h:3200
@ RENDER_MODE_IDX_31
Definition enums.h:3244
@ RENDER_MODE_IDX_09
Definition enums.h:3202
@ RENDER_MODE_IDX_2A
Definition enums.h:3237
@ RENDER_MODE_IDX_02
Definition enums.h:3195
@ RENDER_MODE_IDX_27
Definition enums.h:3234
@ RENDER_MODE_IDX_3C
Definition enums.h:3256
@ RENDER_MODE_IDX_13
Definition enums.h:3213
@ RENDER_MODE_IDX_1F
Definition enums.h:3226
@ RENDER_MODE_IDX_2D
Definition enums.h:3240
@ RENDER_MODE_IDX_0C
Definition enums.h:3205
@ RENDER_MODE_IDX_12
Definition enums.h:3212
@ RENDER_MODE_IDX_11
Definition enums.h:3211
@ RENDER_MODE_IDX_1E
Definition enums.h:3224
@ RENDER_MODE_IDX_3B
Definition enums.h:3255
@ RENDER_MODE_IDX_38
Definition enums.h:3252
@ RENDER_MODE_IDX_22
Definition enums.h:3229
@ RENDER_MODE_IDX_25
Definition enums.h:3232
@ RENDER_MODE_IDX_23
Definition enums.h:3230
@ RENDER_MODE_IDX_19
Definition enums.h:3219
@ RENDER_MODE_IDX_32
Definition enums.h:3245
@ RENDER_MODE_IDX_30
Definition enums.h:3243
@ RENDER_MODE_IDX_0F
Definition enums.h:3208
@ RENDER_MODE_IDX_06
Definition enums.h:3199
@ RENDER_MODE_IDX_28
Definition enums.h:3235
@ RENDER_MODE_IDX_20
Definition enums.h:3227
@ RENDER_MODE_IDX_1C
Definition enums.h:3222
@ RENDER_MODE_IDX_10
Definition enums.h:3210
@ RENDER_MODE_IDX_2C
Definition enums.h:3239
@ RENDER_MODE_IDX_37
Definition enums.h:3251
@ RENDER_MODE_IDX_2F
Definition enums.h:3242
@ RENDER_MODE_IDX_01
Definition enums.h:3194
@ RENDER_MODE_IDX_1A
Definition enums.h:3220
@ RENDER_MODE_IDX_35
Definition enums.h:3248
@ RENDER_MODE_IDX_08
Definition enums.h:3201
@ RENDER_MODE_IDX_0D
Definition enums.h:3206
@ RENDER_MODE_IDX_36
Definition enums.h:3249
@ RENDER_MODE_IDX_2E
Definition enums.h:3241
@ RENDER_MODE_IDX_04
Definition enums.h:3197
@ RENDER_MODE_IDX_17
Definition enums.h:3217
@ RENDER_MODE_IDX_0A
Definition enums.h:3203
@ RENDER_MODE_IDX_0E
Definition enums.h:3207
@ RENDER_MODE_IDX_21
Definition enums.h:3228
@ RENDER_MODE_IDX_05
Definition enums.h:3198
@ RENDER_MODE_IDX_03
Definition enums.h:3196
@ RENDER_MODE_IDX_00
Definition enums.h:3193
@ RENDER_MODE_IDX_24
Definition enums.h:3231
@ MODEL_FLAG_DO_BOUNDS_CULLING
Definition enums.h:4366
@ MODEL_FLAG_IGNORE_MATRIX
Definition enums.h:4370
@ MODEL_FLAG_HAS_LOCAL_VERTEX_COPY
Definition enums.h:4364
@ MODEL_FLAG_INACTIVE
Definition enums.h:4359
@ MODEL_FLAG_HIDDEN
Definition enums.h:4358
@ MODEL_FLAG_VALID
Definition enums.h:4357
@ MODEL_FLAG_BILLBOARD
Definition enums.h:4365
@ MODEL_FLAG_20
Definition enums.h:4362
@ MODEL_FLAG_USES_CUSTOM_GFX
Definition enums.h:4361
@ MODEL_FLAG_TRANSFORM_GROUP_MEMBER
Definition enums.h:4360
@ MODEL_FLAG_MATRIX_DIRTY
Definition enums.h:4369
@ MODEL_FLAG_HAS_TEX_PANNER
Definition enums.h:4368
@ MODEL_FLAG_IGNORE_FOG
Definition enums.h:4363
@ RENDER_TASK_FLAG_20
Definition enums.h:3319
@ RENDER_TASK_FLAG_REFLECT_FLOOR
Definition enums.h:3318
@ RENDER_TASK_FLAG_ENABLED
Definition enums.h:3317
@ MODEL_GROUP_OTHERS_VISIBLE
Definition enums.h:4379
@ MODEL_GROUP_HIDDEN
Definition enums.h:4376
@ CONTEXT_WORLD
Definition enums.h:3529
@ RENDER_MODE_ALPHATEST_ONESIDED
Definition enums.h:3278
@ RENDER_MODE_SURFACE_OPA_NO_ZB
Definition enums.h:3267
@ RENDER_MODE_24_UNUSED
Definition enums.h:3301
@ RENDER_MODE_1D_UNUSED
Definition enums.h:3294
@ RENDER_MODE_1F_UNUSED
Definition enums.h:3296
@ RENDER_MODE_DECAL_OPA
Definition enums.h:3268
@ RENDER_MODE_0E_UNUSED
Definition enums.h:3277
@ RENDER_MODE_SURFACE_XLU_LAYER3
Definition enums.h:3299
@ RENDER_MODE_21_UNUSED
Definition enums.h:3298
@ RENDER_MODE_DECAL_XLU_NO_AA
Definition enums.h:3293
@ RENDER_MODE_SURFACE_XLU_LAYER2
Definition enums.h:3287
@ RENDER_MODE_SURFACE_XLU_NO_AA
Definition enums.h:3284
@ RENDER_MODE_SURF_SOLID_AA_ZB_LAYER0
Definition enums.h:3263
@ RENDER_MODE_INTERSECTING_XLU
Definition enums.h:3303
@ RENDER_MODE_PASS_THROUGH
Definition enums.h:3306
@ RENDER_MODE_DECAL_XLU
Definition enums.h:3291
@ RENDER_MODE_SHADOW
Definition enums.h:3297
@ RENDER_MODE_02_UNUSED
Definition enums.h:3265
@ RENDER_MODE_SURFACE_OPA_NO_AA
Definition enums.h:3266
@ RENDER_MODE_SURFACE_XLU_NO_ZB
Definition enums.h:3285
@ RENDER_MODE_1B_UNUSED
Definition enums.h:3292
@ RENDER_MODE_DECAL_OPA_NO_AA
Definition enums.h:3270
@ RENDER_MODE_0A_UNUSED
Definition enums.h:3273
@ RENDER_MODE_SURFACE_XLU_NO_ZB_BEHIND
Definition enums.h:3310
@ RENDER_MODE_SURFACE_OPA_NO_ZB_BEHIND
Definition enums.h:3308
@ RENDER_MODE_25_UNUSED
Definition enums.h:3302
@ RENDER_MODE_SURFACE_XLU_ZB_ZUPD
Definition enums.h:3286
@ RENDER_MODE_23_UNUSED
Definition enums.h:3300
@ RENDER_MODE_DECAL_XLU_AHEAD
Definition enums.h:3295
@ RENDER_MODE_18_UNUSED
Definition enums.h:3289
@ RENDER_MODE_0B_UNUSED
Definition enums.h:3274
@ RENDER_MODE_ALPHATEST_NO_ZB_BEHIND
Definition enums.h:3309
@ RENDER_MODE_INTERSECTING_OPA
Definition enums.h:3272
@ RENDER_MODE_ALPHATEST
Definition enums.h:3276
@ RENDER_MODE_12_UNUSED
Definition enums.h:3283
@ RENDER_MODE_08_UNUSED
Definition enums.h:3271
@ RENDER_MODE_SURFACE_OPA
Definition enums.h:3264
@ RENDER_MODE_CLOUD_NO_ZB
Definition enums.h:3313
@ RENDER_MODE_CLOUD
Definition enums.h:3312
@ RENDER_MODE_06_UNUSED
Definition enums.h:3269
@ RENDER_MODE_19_UNUSED
Definition enums.h:3290
@ RENDER_MODES_LAST_OPAQUE
Definition enums.h:3280
@ RENDER_MODE_ALPHATEST_NO_ZB
Definition enums.h:3279
@ RENDER_MODE_SURFACE_XLU_LAYER1
Definition enums.h:3282
@ RENDER_MODE_0C_UNUSED
Definition enums.h:3275
@ RENDER_MODE_27_UNUSED
Definition enums.h:3304
@ RENDER_MODE_SURFACE_XLU_AA_ZB_ZUPD
Definition enums.h:3307
@ RENDER_MODE_CLOUD_NO_ZCMP
Definition enums.h:3311
@ RENDER_MODE_17_UNUSED
Definition enums.h:3288
@ CUSTOM_GFX_0
Definition enums.h:4421
@ CUSTOM_GFX_NONE
Definition enums.h:4420
@ GLOBAL_OVERRIDES_ENABLE_FLOOR_REFLECTION
Definition enums.h:4326
u32 dma_copy(Addr romStart, Addr romEnd, void *vramDest)
Definition 43F0.c:444
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
void osSyncPrintf(const char *fmt,...)
Definition is_debug.c:32
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:4086
void func_8011B1D8(ModelNode *node)
Definition model.c:3458
Gfx Gfx_RM3_DECAL_XLU[]
Definition model.c:1117
void render_transform_group(void *group)
Definition model.c:3034
ModelCustomGfxList * gCurrentCustomModelGfxPtr
Definition model.c:1310
void clone_model(u16 srcModelID, u16 newModelID)
Definition model.c:3621
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:3906
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:4276
BSS s8 bBackgroundTintMode
Definition model.c:1335
void enable_transform_group(u16 modelID)
Definition model.c:3587
void mdl_local_gfx_copy_vertices(Vtx *src, s32 num, Vtx *dest)
Definition model.c:4032
s32 get_transform_group_index(s32 modelID)
Definition model.c:3418
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:3397
Gfx Gfx_RM2_INTERSECTING_XLU[]
Definition model.c:932
s32 endDistance
Definition model.c:115
@ 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
Gfx Gfx_RM2_INTERSECTING_OPA[]
Definition model.c:895
void render_transform_group_node(ModelNode *node)
Definition model.c:2985
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:2940
s32 startDistance
Definition model.c:114
void init_model_data(void)
Definition model.c:2431
BSS s32 texPannerAuxV[MAX_TEX_PANNERS]
Definition model.c:1343
void clear_render_tasks(void)
Definition model.c:4536
Gfx Gfx_RM3_INTERSECTING_OPA_NO_AA[]
Definition model.c:1157
void clear_model_data(void)
Definition model.c:2364
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:4099
void set_tex_panner(Model *model, s32 texPannerID)
Definition model.c:3812
void mdl_reset_transform_flags(void)
Definition model.c:3756
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:3789
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:3963
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:2455
Model * get_model_from_list_index(s32 listIndex)
Definition model.c:3315
#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
@ 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_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:3780
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:4521
u8 DepthTintColA
Definition model.c:580
void load_data_for_models(ModelNode *rootModel, s32 texturesOffset, s32 size)
Definition model.c:3319
void load_next_model_textures(ModelNode *model, s32 romOffset, s32 texSize)
Definition model.c:2299
void load_model_transforms(ModelNode *model, ModelNode *parent, Matrix4f mdlTxMtx, s32 treeDepth)
Definition model.c:3336
BSS FogSettings bFogSettings
Definition model.c:1338
s32 is_world_fog_enabled(void)
Definition model.c:3796
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:3849
BSS u16 mtg_MaxChild
Definition model.c:1349
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:3954
void disable_transform_group(u16 modelID)
Definition model.c:3604
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:3514
void load_texture_variants(u32 romOffset, s32 textureID, s32 baseOffset, s32 size)
Definition model.c:2173
BSS ModelList wModelList
Definition model.c:1314
void appendGfx_model_group(void *model)
Definition model.c:2925
u8 DepthTintColR
Definition model.c:577
void set_custom_gfx(s32 customGfxIndex, Gfx *pre, Gfx *post)
Definition model.c:3844
void * mdl_get_next_texture_address(s32 size)
Definition model.c:4509
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:2346
void build_custom_gfx(void)
Definition model.c:3854
BSS RenderTask * RenderTaskLists[3]
Definition model.c:1351
DepthFloatFactors DepthFloatLookupTable[]
Definition model.c:619
void load_texture_by_name(ModelNodeProperty *propertyName, s32 romOffset, s32 size)
Definition model.c:2047
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:3776
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:3695
void mdl_set_remap_tint_params(u8 maxR, u8 maxG, u8 maxB, u8 minR, u8 minG, u8 minB)
Definition model.c:3945
ModelTransformGroupList * gCurrentTransformGroups
Definition model.c:1309
@ 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
void set_mdl_custom_gfx_set(Model *model, s32 customGfxIndex, u32 tintType)
Definition model.c:3832
Gfx Gfx_RM2_SURFACE_XLU_AA_ZB_ZUPD[]
Definition model.c:1009
@ 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
s32 is_identity_fixed_mtx(Mtx *mtx)
Definition model.c:3886
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:3932
Gfx Gfx_RM3_SURFACE_XLU_NO_AA[]
Definition model.c:1174
Gfx Gfx_RM1_ALPHATEST[]
Definition model.c:676
void set_aux_pan_v(s32 texPannerID, s32 value)
Definition model.c:3828
s32 DepthTintStart
Definition model.c:581
void mdl_make_local_vertex_copy(s32 copyIndex, u16 modelID, s32 isMakingCopy)
Definition model.c:4041
void set_world_fog_dist(s32 start, s32 end)
Definition model.c:3784
Addr BattleEntityHeapBottom
void set_main_pan_u(s32 texPannerID, s32 value)
Definition model.c:3816
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:2472
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:2322
void set_aux_pan_u(s32 texPannerID, s32 value)
Definition model.c:3824
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:4016
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:4572
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:3805
BSS FogSettings wFogSettings
Definition model.c:1337
BSS ModelLocalVertexCopyList wModelLocalVtxBuffers
Definition model.c:1325
void render_models(void)
Definition model.c:2710
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:3053
@ 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 set_main_pan_v(s32 texPannerID, s32 value)
Definition model.c:3820
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
void load_texture_impl(u32 romOffset, TextureHandle *handle, TextureHeader *header, s32 mainSize, s32 mainPalSize, s32 auxSize, s32 auxPalSize)
Definition model.c:2009
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:2285
void mdl_get_copied_vertices(s32 copyIndex, Vtx **firstVertex, Vtx **copiedVertices, s32 *numCopied)
Definition model.c:4077
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:3800
void mdl_update_transform_matrices(void)
Definition model.c:2589
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
@ 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
Gfx Gfx_RM1_DECAL_XLU_NO_AA[]
Definition model.c:766
u8 DepthTintBaseB
Definition model.c:575
void mdl_group_set_visibility(u16 treeIndex, s32 flags, s32 mode)
Definition model.c:3637
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:3433
ModelTransformGroup * get_transform_group(s32 index)
Definition model.c:3453
#define TEST_POINT_VISIBILITY
Gfx Gfx_RM1_SURFACE_OPA_NO_AA[]
Definition model.c:718
#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:3920
ModelNodeProperty * propertyList
Definition model.h:55
ModelNode * baseModelNode
Definition model.h:83
u8 matrixFreshness
Definition model.h:73
Vtx * vtxCopy[2]
Definition model.h:106
Mtx * transformMatrix
Definition model.h:39
ModelLocalVertexCopy * ModelLocalVertexCopyList[16]
Definition model.h:110
ModelCustomGfxBuilderFunc ModelCustomGfxBuilderList[32]
Definition model.h:139
Mtx * finalMtx
Definition model.h:65
u16 * palette
Definition model.h:123
ModelNode * mdlNode
Definition model.h:131
Mtx * mtx
Definition model.h:133
void(* ModelCustomGfxBuilderFunc)(s32 index)
Definition model.h:136
struct ModelNode ** childList
Definition model.h:43
s8 renderMode
Definition model.h:72
ModelGroupData * groupData
Definition model.h:64
Vec3f center
Definition model.h:69
s8 textureVariation
Definition model.h:75
Gfx * gfxCopy[2]
Definition model.h:105
Gfx * displayList
Definition model.h:47
s32 numProperties
Definition model.h:54
ModelNode * modelNode
Definition model.h:63
u8 * raster
Definition model.h:122
s32 numLights
Definition model.h:41
u8 * auxRaster
Definition model.h:124
Lightsn * lightingGroup
Definition model.h:40
s32 type
Definition model.h:52
Model * ModelList[256]
Definition model.h:94
Mtx * bakedMtx
Definition model.h:62
u8 textureID
Definition model.h:74
u16 flags
Definition model.h:60
Gfx * gfx
Definition model.h:120
u8 texPannerID
Definition model.h:70
ModelTransformGroup * ModelTransformGroupList[4]
Definition model.h:95
s32 numChildren
Definition model.h:42
ModelNodePropertyData data
Definition model.h:35
u16 * auxPalette
Definition model.h:125
Matrix4f userTransformMtx
Definition model.h:86
u8 customGfxIndex
Definition model.h:71
Matrix4f userTransformMtx
Definition model.h:68
ModelDisplayData * displayData
Definition model.h:53
ModelGroupData * groupData
Definition model.h:132
u16 modelID
Definition model.h:61
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
Mtx savedMtx
Definition model.h:67
@ 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:233
#define PM_CC_TEX_COMBINE_3C
Definition macros.h:370
#define PM_CC_TEX_COMBINE_3B
Definition macros.h:369
#define PM_RM_SHROUD
Definition macros.h:274
#define PM_CC_ALT_INTERFERENCE
Definition macros.h:376
#define SCREEN_WIDTH
Definition macros.h:105
#define PM_CC_TINT_REMAP_SHADE_ALPHA
Definition macros.h:359
#define PM_CC_20
Definition macros.h:332
#define PM_CC1_24
Definition macros.h:365
#define BSS
Definition macros.h:7
#define PM_CC1_29
Definition macros.h:372
#define ARRAY_COUNT(arr)
Definition macros.h:40
#define OPTIMIZE_OFAST
Definition macros.h:579
#define PM_CC_TEX_COMBINE_3A
Definition macros.h:368
#define PM_CC_NOISE
Definition macros.h:310
#define PM_CC_22
Definition macros.h:363
#define INTEGER_LOG2(x)
#define PM_CC2_29
Definition macros.h:373
#define PM_CC2_MULTIPLY_SHADE
Definition macros.h:308
#define PM_CC_TINT_REMAP_NO_SHADE
Definition macros.h:351
#define ALIGNED(x)
Definition macros.h:10
#define PM_CC_TINT_DEPTH_NO_SHADE
Definition macros.h:326
#define PM_CC_23
Definition macros.h:364
#define PM_CC_TINT_DEPTH_MIPMAPS
Definition macros.h:336
#define PM_CC2_24
Definition macros.h:366
#define MAX_MODEL_TRANSFORM_GROUPS
Definition macros.h:89
#define PM_CC_TINT_REMAP_NOTEX
Definition macros.h:343
#define PM_CC_1A
Definition macros.h:312
#define MAX_TEX_PANNERS
Definition macros.h:96
#define PM_CC_TINT_DEPTH_NOTEX
Definition macros.h:318
#define MAX_MODELS
Definition macros.h:88
s16 viewportStartX
s16 viewportStartY
Matrix4f mtxPerspective
void * appendGfxArg
void(* appendGfx)(void *)
u8 Addr[]
Linker symbol address, as in ld_addrs.h.
Definition types.h:16
s32 gOverrideFlags
Definition main_loop.c:11
GameStatus * gGameStatusPtr
Definition main_loop.c:32
Camera gCameras[4]
Definition cam_main.c:17
Gfx * gMainGfxPos
Definition cam_main.c:15
u16 gMatrixListPos
Definition main_loop.c:45
s32 gCurrentCameraID
Definition cam_math.c:4
DisplayContext * gDisplayContext
Definition cam_main.c:16
s16 gCurrentCamID
Definition cam_main.c:13