summaryrefslogtreecommitdiff
path: root/libs/JSystem/J3DGraphBase/J3DGD.cpp
blob: 7f65db79a5556de33249424e5c38a5bb6529f87b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
//
// Generated By: dol2asm
// Translation Unit: J3DGD
//

#include "JSystem/J3DGraphBase/J3DGD.h"
#include "dol2asm.h"
#include "dolphin/gd.h"
#include "dolphin/os.h"

//
// Forward References:
//

extern "C" void J3DGDSetGenMode__FUcUcUcUc11_GXCullMode();
extern "C" void J3DGDSetGenMode_3Param__FUcUcUc();
extern "C" void J3DGDSetLightAttn__F10_GXLightIDffffff();
extern "C" void J3DGDSetLightColor__F10_GXLightID8_GXColor();
extern "C" void J3DGDSetLightPos__F10_GXLightIDfff();
extern "C" void J3DGDSetLightDir__F10_GXLightIDfff();
extern "C" void J3DGDSetVtxAttrFmtv__F9_GXVtxFmtPC17_GXVtxAttrFmtListb();
extern "C" void J3DGDSetTexCoordGen__F13_GXTexGenType12_GXTexGenSrc();
extern "C" void J3DGDSetTexCoordScale2__F13_GXTexCoordIDUsUcUcUsUcUc();
extern "C" void
J3DGDSetTexLookupMode__F11_GXTexMapID14_GXTexWrapMode14_GXTexWrapMode12_GXTexFilter12_GXTexFilterfffUcUc13_GXAnisotropy();
extern "C" void J3DGDSetTexImgAttr__F11_GXTexMapIDUsUs9_GXTexFmt();
extern "C" void J3DGDSetTexImgPtr__F11_GXTexMapIDPv();
extern "C" void J3DGDSetTexImgPtrRaw__F11_GXTexMapIDUl();
extern "C" void J3DGDSetTexTlut__F11_GXTexMapIDUl10_GXTlutFmt();
extern "C" void J3DGDLoadTlut__FPvUl11_GXTlutSize();
extern "C" void J3DGDSetIndTexMtx__F14_GXIndTexMtxIDPA3_fSc();
extern "C" void
J3DGDSetIndTexCoordScale__F16_GXIndTexStageID14_GXIndTexScale14_GXIndTexScale14_GXIndTexScale14_GXIndTexScale();
extern "C" void
J3DGDSetIndTexOrder__FUl13_GXTexCoordID11_GXTexMapID13_GXTexCoordID11_GXTexMapID13_GXTexCoordID11_GXTexMapID13_GXTexCoordID11_GXTexMapID();
extern "C" void
J3DGDSetTevOrder__F13_GXTevStageID13_GXTexCoordID11_GXTexMapID12_GXChannelID13_GXTexCoordID11_GXTexMapID12_GXChannelID();
extern "C" void J3DGDSetTevKColor__F14_GXTevKColorID8_GXColor();
extern "C" void J3DGDSetTevColorS10__F11_GXTevRegID11_GXColorS10();
extern "C" void J3DGDSetFog__F10_GXFogTypeffff8_GXColor();
extern "C" void J3DGDSetFogRangeAdj__FUcUsP14_GXFogAdjTable();
extern "C" void J3DFifoLoadPosMtxImm__FPA4_fUl();
extern "C" void J3DFifoLoadNrmMtxImm__FPA4_fUl();
extern "C" void J3DFifoLoadNrmMtxImm3x3__FPA3_fUl();
extern "C" void J3DFifoLoadNrmMtxToTexMtx__FPA4_fUl();
extern "C" void J3DFifoLoadNrmMtxToTexMtx3x3__FPA3_fUl();
extern "C" void J3DFifoLoadTexCached__F11_GXTexMapIDUl15_GXTexCacheSizeUl15_GXTexCacheSize();

//
// External References:
//

extern "C" void GDOverflowed();
extern "C" void __cvt_fp2unsigned();
extern "C" void _savegpr_14();
extern "C" void _savegpr_23();
extern "C" void _savegpr_24();
extern "C" void _savegpr_25();
extern "C" void _savegpr_27();
extern "C" void _savegpr_29();
extern "C" void _restgpr_14();
extern "C" void _restgpr_23();
extern "C" void _restgpr_24();
extern "C" void _restgpr_25();
extern "C" void _restgpr_27();
extern "C" void _restgpr_29();

//
// Declarations:
//

/* 8030D098-8030D210 3079D8 0178+00 0/0 1/1 0/0 .text J3DGDSetGenMode__FUcUcUcUc11_GXCullMode */
void J3DGDSetGenMode(u8 texGenNum, u8 colorChanNum, u8 tevStageNum, u8 indTexStageNum,
                     GXCullMode cullMode) {
    GDOverflowCheck(0xa);
    J3DGDWriteBPCmd(0xfe07fc3f);
    static u8 cm2hw[4] = {0, 2, 1, 3};
    J3DGDWriteBPCmd(texGenNum | colorChanNum << 4 | (tevStageNum - 1) << 0xa |
                    cm2hw[cullMode] << 0xe | indTexStageNum << 0x10);
}

/* 8030D210-8030D364 307B50 0154+00 0/0 1/1 0/0 .text            J3DGDSetGenMode_3Param__FUcUcUc */
void J3DGDSetGenMode_3Param(u8 texGenNum, u8 tevStageNum, u8 indTexStageNum) {
    GDOverflowCheck(0xa);
    J3DGDWriteBPCmd(0xfe073c0f);
    J3DGDWriteBPCmd(texGenNum | (tevStageNum - 1) << 0xa | indTexStageNum << 0x10);
}

/* 8030D364-8030D65C 307CA4 02F8+00 0/0 1/1 0/0 .text J3DGDSetLightAttn__F10_GXLightIDffffff */
void J3DGDSetLightAttn(GXLightID id, f32 a0, f32 a1, f32 a2, f32 k0, f32 k1, f32 k2) {
    J3DGDWriteXFCmdHdr(0x0604 + __GDLightID2Offset(id), 6);
    J3DGDWrite_f32(a0);
    J3DGDWrite_f32(a1);
    J3DGDWrite_f32(a2);
    J3DGDWrite_f32(k0);
    J3DGDWrite_f32(k1);
    J3DGDWrite_f32(k2);
}

/* 8030D65C-8030D76C 307F9C 0110+00 0/0 1/1 0/0 .text J3DGDSetLightColor__F10_GXLightID8_GXColor
 */
void J3DGDSetLightColor(GXLightID id, GXColor color) {
    J3DGDWriteXFCmd(0x0603 + __GDLightID2Offset(id),
                    (color.r << 24) | (color.g << 16) | (color.b << 8) | (color.a << 0));
}

/* 8030D76C-8030D938 3080AC 01CC+00 0/0 1/1 0/0 .text            J3DGDSetLightPos__F10_GXLightIDfff
 */
void J3DGDSetLightPos(GXLightID id, f32 x, f32 y, f32 z) {
    J3DGDWriteXFCmdHdr(0x060A + __GDLightID2Offset(id), 3);
    J3DGDWrite_f32(x);
    J3DGDWrite_f32(y);
    J3DGDWrite_f32(z);
}

/* 8030D938-8030DB04 308278 01CC+00 0/0 1/1 0/0 .text            J3DGDSetLightDir__F10_GXLightIDfff
 */
void J3DGDSetLightDir(GXLightID id, f32 x, f32 y, f32 z) {
    J3DGDWriteXFCmdHdr(0x060D + __GDLightID2Offset(id), 3);
    J3DGDWrite_f32(x);
    J3DGDWrite_f32(y);
    J3DGDWrite_f32(z);
}

/* 8030DB04-8030E064 308444 0560+00 1/0 1/1 0/0 .text
 * J3DGDSetVtxAttrFmtv__F9_GXVtxFmtPC17_GXVtxAttrFmtListb       */
void J3DGDSetVtxAttrFmtv(GXVtxFmt fmt, GXVtxAttrFmtList const* fmtList, bool param_2) {
    u32 pos_cnt = GX_POS_XYZ;
    u32 pos_type = GX_F32;
    u32 pos_shift = 0;
    u32 nrm_cnt = GX_NRM_XYZ;
    u32 nrm_type = GX_F32;
    u32 local_34 = 0;
    u32 clr0_cnt = GX_CLR_RGBA;
    u32 clr0_type = GX_RGBA8;
    u32 clr1_cnt = GX_CLR_RGBA;
    u32 clr1_type = GX_RGBA8;
    u32 tex0_cnt = GX_TEX_ST;
    u32 tex0_type = GX_F32;
    u32 tex0_shift = 0;
    u32 tex1_cnt = GX_TEX_ST;
    u32 tex1_type = GX_F32;
    u32 tex1_shift = 0;
    u32 tex2_cnt = GX_TEX_ST;
    u32 tex2_type = GX_F32;
    u32 tex2_shift = 0;
    u32 tex3_cnt = GX_TEX_ST;
    u32 tex3_type = GX_F32;
    u32 tex3_shift = 0;
    u32 tex4_cnt = GX_TEX_ST;
    u32 tex4_type = GX_F32;
    u32 tex4_shift = 0;
    u32 tex5_cnt = GX_TEX_ST;
    u32 tex5_type = GX_F32;
    u32 tex5_shift = 0;
    u32 tex6_cnt = GX_TEX_ST;
    u32 tex6_type = GX_F32;
    u32 tex6_shift = 0;
    u32 tex7_cnt = GX_TEX_ST;
    u32 tex7_type = GX_F32;
    u32 tex7_shift = 0;
    for (; fmtList->mAttrib != GX_VA_NULL; fmtList++) {
        switch (fmtList->mAttrib) {
        case GX_VA_POS:
            pos_cnt = fmtList->mCompCnt;
            pos_type = fmtList->mCompType;
            pos_shift = fmtList->mCompShift;
            break;
        case GX_VA_NRM:
        case GX_VA_NBT:
            nrm_type = fmtList->mCompType;
            if (fmtList->mCompCnt == GX_NRM_NBT3) {
                nrm_cnt = GX_NRM_NBT;
                local_34 = 1;
            } else {
                if (param_2) {
                    nrm_cnt = GX_NRM_NBT;
                } else {
                    nrm_cnt = fmtList->mCompCnt;
                }
                local_34 = 0;
            }
            break;
        case GX_VA_CLR0:
            clr0_cnt = fmtList->mCompCnt;
            clr0_type = fmtList->mCompType;
            break;
        case GX_VA_CLR1:
            clr1_cnt = fmtList->mCompCnt;
            clr1_type = fmtList->mCompType;
            break;
        case GX_VA_TEX0:
            tex0_cnt = fmtList->mCompCnt;
            tex0_type = fmtList->mCompType;
            tex0_shift = fmtList->mCompShift;
            break;
        case GX_VA_TEX1:
            tex1_cnt = fmtList->mCompCnt;
            tex1_type = fmtList->mCompType;
            tex1_shift = fmtList->mCompShift;
            break;
        case GX_VA_TEX2:
            tex2_cnt = fmtList->mCompCnt;
            tex2_type = fmtList->mCompType;
            tex2_shift = fmtList->mCompShift;
            break;
        case GX_VA_TEX3:
            tex3_cnt = fmtList->mCompCnt;
            tex3_type = fmtList->mCompType;
            tex3_shift = fmtList->mCompShift;
            break;
        case GX_VA_TEX4:
            tex4_cnt = fmtList->mCompCnt;
            tex4_type = fmtList->mCompType;
            tex4_shift = fmtList->mCompShift;
            break;
        case GX_VA_TEX5:
            tex5_cnt = fmtList->mCompCnt;
            tex5_type = fmtList->mCompType;
            tex5_shift = fmtList->mCompShift;
            break;
        case GX_VA_TEX6:
            tex6_cnt = fmtList->mCompCnt;
            tex6_type = fmtList->mCompType;
            tex6_shift = fmtList->mCompShift;
            break;
        case GX_VA_TEX7:
            tex7_cnt = fmtList->mCompCnt;
            tex7_type = fmtList->mCompType;
            tex7_shift = fmtList->mCompShift;
            break;
        }
    }
    GDOverflowCheck(0x12);
    J3DGDWriteCPCmd(GX_CP_REG_VAT_GRP0 + fmt,
                    pos_cnt | pos_type << 1 | pos_shift << 4 | nrm_cnt << 9 | nrm_type << 0xa |
                        clr0_cnt << 0xd | clr0_type << 0xe | clr1_cnt << 0x11 | clr1_type << 0x12 |
                        tex0_cnt << 0x15 | tex0_type << 0x16 | tex0_shift << 0x19 | 0x40000000 |
                        local_34 << 0x1f);
    J3DGDWriteCPCmd(GX_CP_REG_VAT_GRP1 + fmt,
                    tex1_cnt | tex1_type << 1 | tex1_shift << 4 | tex2_cnt << 9 | tex2_type << 0xa |
                        tex2_shift << 0xd | tex3_cnt << 0x12 | tex3_type << 0x13 |
                        tex3_shift << 0x16 | tex4_cnt << 0x1b | tex4_type << 0x1c | 0x80000000);
    J3DGDWriteCPCmd(GX_CP_REG_VAT_GRP2 + fmt,
                    tex4_shift | tex5_cnt << 5 | tex5_type << 6 | tex5_shift << 9 |
                        tex6_cnt << 0xe | tex6_type << 0xf | tex6_shift << 0x12 | tex7_cnt << 0x17 |
                        tex7_type << 0x18 | tex7_shift << 0x1b);
}

/* 8030E064-8030E234 3089A4 01D0+00 1/0 1/1 0/0 .text
 * J3DGDSetTexCoordGen__F13_GXTexGenType12_GXTexGenSrc          */
void J3DGDSetTexCoordGen(GXTexGenType texGenType, GXTexGenSrc texGenSrc) {
    u32 input_form = 0;
    u32 proj_type = 0;
    u32 src_row = 5;
    u32 bump_src_tex = 5;
    u32 bump_src_light = 0;
    u32 texgen_type;
    switch (texGenSrc) {
    case GX_TG_POS:
        src_row = 0;
        input_form = 1;
        break;
    case GX_TG_NRM:
        src_row = 1;
        input_form = 1;
        break;
    case GX_TG_BINRM:
        src_row = 3;
        input_form = 1;
        break;
    case GX_TG_TANGENT:
        src_row = 4;
        input_form = 1;
        break;
    case GX_TG_COLOR0:
        src_row = 2;
        break;
    case GX_TG_COLOR1:
        src_row = 2;
        break;
    case GX_TG_TEX0:
        src_row = 5;
        break;
    case GX_TG_TEX1:
        src_row = 6;
        break;
    case GX_TG_TEX2:
        src_row = 7;
        break;
    case GX_TG_TEX3:
        src_row = 8;
        break;
    case GX_TG_TEX4:
        src_row = 9;
        break;
    case GX_TG_TEX5:
        src_row = 10;
        break;
    case GX_TG_TEX6:
        src_row = 11;
        break;
    case GX_TG_TEX7:
        src_row = 12;
        break;
    case GX_TG_TEXCOORD0:
        bump_src_tex = 0;
        break;
    case GX_TG_TEXCOORD1:
        bump_src_tex = 1;
        break;
    case GX_TG_TEXCOORD2:
        bump_src_tex = 2;
        break;
    case GX_TG_TEXCOORD3:
        bump_src_tex = 3;
        break;
    case GX_TG_TEXCOORD4:
        bump_src_tex = 4;
        break;
    case GX_TG_TEXCOORD5:
        bump_src_tex = 5;
        break;
    case GX_TG_TEXCOORD6:
        bump_src_tex = 6;
        break;
    }
    switch (texGenType) {
    case GX_TG_MTX2x4:
        texgen_type = 0;
        break;
    case GX_TG_MTX3x4:
        texgen_type = 0;
        proj_type = 1;
        break;
    case GX_TG_BUMP0:
    case GX_TG_BUMP1:
    case GX_TG_BUMP2:
    case GX_TG_BUMP3:
    case GX_TG_BUMP4:
    case GX_TG_BUMP5:
    case GX_TG_BUMP6:
    case GX_TG_BUMP7:
        texgen_type = 1;
        bump_src_light = texGenType - 2;
        break;
    case GX_TG_SRTG:
        if (texGenSrc == GX_TG_COLOR0) {
            texgen_type = 2;
        } else {
            texgen_type = 3;
        }
        break;
    }
    J3DGDWrite_u32(
        proj_type << (31 - GX_XF_TEX_PROJTYPE_END) | input_form << (31 - GX_XF_TEX_INPUTFORM_END) |
        texgen_type << (31 - GX_XF_TEX_TEXGENTYPE_END) | src_row << (31 - GX_XF_TEX_SRCROW_END) |
        bump_src_tex << (31 - GX_XF_TEX_BUMPSRCTEX_END) |
        bump_src_light << (31 - GX_XF_TEX_BUMPSRCLIGHT_END));
}

/* 8030E234-8030E438 308B74 0204+00 0/0 16/16 0/0 .text
 * J3DGDSetTexCoordScale2__F13_GXTexCoordIDUsUcUcUsUcUc         */
void J3DGDSetTexCoordScale2(GXTexCoordID param_0, u16 param_1, u8 param_2, u8 param_3, u16 param_4,
                            u8 param_5, u8 param_6) {
    GDOverflowCheck(0xf);
    J3DGDWriteBPCmd(0xfe03ffff);
    J3DGDWriteBPCmd((param_1 - 1) | param_2 << 0x10 | param_3 << 0x11 |
                    (param_0 * 2 + 0x30) << 0x18);
    J3DGDWriteBPCmd((param_4 - 1) | param_5 << 0x10 | param_6 << 0x11 |
                    (param_0 * 2 + 0x31) << 0x18);
}

/* 8045090C-80450914 00038C 0008+00 1/1 0/0 0/0 .sdata           J3DGDTexMode0Ids */
static u8 J3DGDTexMode0Ids[8] = {
    0x80, 0x81, 0x82, 0x83, 0xA0, 0xA1, 0xA2, 0xA3,
};

/* 80450914-8045091C 000394 0008+00 1/1 0/0 0/0 .sdata           J3DGDTexMode1Ids */
static u8 J3DGDTexMode1Ids[8] = {
    0x84, 0x85, 0x86, 0x87, 0xA4, 0xA5, 0xA6, 0xA7,
};

/* 8045091C-80450924 00039C 0008+00 1/1 0/0 0/0 .sdata           J3DGDTexImage0Ids */
static u8 J3DGDTexImage0Ids[8] = {
    0x88, 0x89, 0x8A, 0x8B, 0xA8, 0xA9, 0xAA, 0xAB,
};

/* 80450924-8045092C 0003A4 0008+00 2/2 0/0 0/0 .sdata           J3DGDTexImage3Ids */
static u8 J3DGDTexImage3Ids[8] = {
    0x94, 0x95, 0x96, 0x97, 0xB4, 0xB5, 0xB6, 0xB7,
};

/* 8045092C-80450934 0003AC 0008+00 1/1 0/0 0/0 .sdata           J3DGDTexTlutIds */
static u8 J3DGDTexTlutIds[8] = {
    0x98, 0x99, 0x9A, 0x9B, 0xB8, 0xB9, 0xBA, 0xBB,
};

/* 80450934-8045093C 0003B4 0006+02 1/1 0/0 0/0 .sdata           GX2HWFiltConv */
static u8 GX2HWFiltConv[6] = {
    0x00, 0x04, 0x01, 0x05, 0x02, 0x06,
};

/* 8030E438-8030E5D4 308D78 019C+00 0/0 1/1 0/0 .text
 * J3DGDSetTexLookupMode__F11_GXTexMapID14_GXTexWrapMode14_GXTexWrapMode12_GXTexFilter12_GXTexFilterfffUcUc13_GXAnisotropy
 */
void J3DGDSetTexLookupMode(GXTexMapID param_0, GXTexWrapMode param_1, GXTexWrapMode param_2,
                           GXTexFilter param_3, GXTexFilter param_4, f32 param_5, f32 param_6,
                           f32 param_7, u8 param_8, u8 param_9, GXAnisotropy param_10) {
    J3DGDWriteBPCmd(param_1 | param_2 << 2 | (param_4 == GX_LINEAR) << 4 |
                    GX2HWFiltConv[param_3] << 5 | (param_9 == 0) << 8 |
                    ((int)(param_7 * 32.0f) & 0xff) << 9 | param_10 << 0x13 | param_8 << 0x15 |
                    J3DGDTexMode0Ids[param_0] << 0x18);
    J3DGDWriteBPCmd(((int)(param_5 * 16.0f) & 0xff) | ((int)(param_6 * 16.0f) & 0xff) << 8 |
                    J3DGDTexMode1Ids[param_0] << 0x18);
}

/* 8030E5D4-8030E67C 308F14 00A8+00 0/0 1/1 0/0 .text
 * J3DGDSetTexImgAttr__F11_GXTexMapIDUsUs9_GXTexFmt             */
void J3DGDSetTexImgAttr(GXTexMapID param_0, u16 param_1, u16 param_2, GXTexFmt param_3) {
    J3DGDWriteBPCmd((param_1 - 1) | (param_2 - 1) << 0xa | param_3 << 0x14 |
                    J3DGDTexImage0Ids[param_0] << 0x18);
}

/* 8030E67C-8030E70C 308FBC 0090+00 0/0 1/1 0/0 .text            J3DGDSetTexImgPtr__F11_GXTexMapIDPv
 */
void J3DGDSetTexImgPtr(GXTexMapID param_0, void* param_1) {
    J3DGDWriteBPCmd(OSCachedToPhysical(param_1) >> 5 | J3DGDTexImage3Ids[param_0] << 0x18);
}

/* 8030E70C-8030E7E0 30904C 00D4+00 0/0 1/1 0/0 .text J3DGDSetTexImgPtrRaw__F11_GXTexMapIDUl */
void J3DGDSetTexImgPtrRaw(GXTexMapID param_0, u32 param_1) {
    GDOverflowCheck(5);
    J3DGDWriteBPCmd(param_1 | J3DGDTexImage3Ids[param_0] << 0x18);
}

/* 8030E7E0-8030E878 309120 0098+00 0/0 1/1 0/0 .text
 * J3DGDSetTexTlut__F11_GXTexMapIDUl10_GXTlutFmt                */
void J3DGDSetTexTlut(GXTexMapID param_0, u32 param_1, GXTlutFmt param_2) {
    J3DGDWriteBPCmd((param_1 - 0x80000) >> 9 | param_2 << 0xa | J3DGDTexTlutIds[param_0] << 0x18);
}

/* 8030E878-8030EB30 3091B8 02B8+00 0/0 1/1 0/0 .text            J3DGDLoadTlut__FPvUl11_GXTlutSize
 */
void J3DGDLoadTlut(void* param_0, u32 param_1, GXTlutSize param_2) {
    J3DGDWriteBPCmd(0xfeffff00);
    J3DGDWriteBPCmd(0x0f000000);
    J3DGDWriteBPCmd(OSCachedToPhysical(param_0) >> 5 | 0x64000000);
    J3DGDWriteBPCmd((param_1 - 0x80000) >> 9 | param_2 << 0xa | 0x65000000);
    J3DGDWriteBPCmd(0xfeffff00);
    J3DGDWriteBPCmd(0x0f000000);
}

/* 8030EB30-8030EE10 309470 02E0+00 0/0 2/2 0/0 .text J3DGDSetIndTexMtx__F14_GXIndTexMtxIDPA3_fSc
 */
void J3DGDSetIndTexMtx(GXIndTexMtxID id, Mtx3P mtx, s8 exp) {
    s32 mtx32[6];
    u32 idx;

    switch (id) {
    case GX_ITM_0:
    case GX_ITM_1:
    case GX_ITM_2:
        idx = (u32)(id - GX_ITM_0);
        break;
    case GX_ITM_S0:
    case GX_ITM_S1:
    case GX_ITM_S2:
        idx = (u32)(id - GX_ITM_S0);
        break;
    case GX_ITM_T0:
    case GX_ITM_T1:
    case GX_ITM_T2:
        idx = (u32)(id - GX_ITM_T0);
        break;
    default:
        idx = 0;
        break;
    }

    exp += 17;

    mtx32[0] = (s32)(mtx[0][0] * 1024.0f) & 0x7FF;
    mtx32[1] = (s32)(mtx[1][0] * 1024.0f) & 0x7FF;

    mtx32[2] = (s32)(mtx[0][1] * 1024.0f) & 0x7FF;
    mtx32[3] = (s32)(mtx[1][1] * 1024.0f) & 0x7FF;

    mtx32[4] = (s32)(mtx[0][2] * 1024.0f) & 0x7FF;
    mtx32[5] = (s32)(mtx[1][2] * 1024.0f) & 0x7FF;

    GDOverflowCheck(15);

    J3DGDWriteBPCmd((mtx32[0] << 0) | (mtx32[1] << 11) | (((exp >> 0) & 0x03) << 22) |
                    (0x06 + idx * 3) << 24);
    J3DGDWriteBPCmd((mtx32[2] << 0) | (mtx32[3] << 11) | (((exp >> 2) & 0x03) << 22) |
                    (0x07 + idx * 3) << 24);
    J3DGDWriteBPCmd((mtx32[4] << 0) | (mtx32[5] << 11) | (((exp >> 4) & 0x03) << 22) |
                    (0x08 + idx * 3) << 24);
}

/* 8030EE10-8030EF08 309750 00F8+00 0/0 2/2 0/0 .text
 * J3DGDSetIndTexCoordScale__F16_GXIndTexStageID14_GXIndTexScale14_GXIndTexScale14_GXIndTexScale14_GXIndTexScale
 */
void J3DGDSetIndTexCoordScale(GXIndTexStageID stage, GXIndTexScale scale0, GXIndTexScale scale1,
                              GXIndTexScale scale2, GXIndTexScale scale3) {
    GDOverflowCheck(5);
    J3DGDWriteBPCmd(scale0 | scale1 << 4 | scale2 << 8 | scale3 << 0xc |
                    ((stage >> 1) + GX_BP_REG_RAS1_SS0) << 0x18);
}

/* 8030EF08-8030F108 309848 0200+00 0/0 2/2 0/0 .text
 * J3DGDSetIndTexOrder__FUl13_GXTexCoordID11_GXTexMapID13_GXTexCoordID11_GXTexMapID13_GXTexCoordID11_GXTexMapID13_GXTexCoordID11_GXTexMapID
 */
void J3DGDSetIndTexOrder(u32 count, GXTexCoordID coord0, GXTexMapID map0, GXTexCoordID coord1,
                         GXTexMapID map1, GXTexCoordID coord2, GXTexMapID map2, GXTexCoordID coord3,
                         GXTexMapID map3) {
    GDOverflowCheck(0xa);
    J3DGDWriteBPCmd(map0 & 7 | (coord0 & 7) << 3 | (map1 & 7) << 6 | (coord1 & 7) << 9 |
                    (map2 & 7) << 0xc | (coord2 & 7) << 0xf | (map3 & 7) << 0x12 |
                    (coord3 & 7) << 0x15 | GX_BP_REG_RAS1_IREF << 0x18);
    u32 imask = 0;
    for (u32 i = 0; i < count; i++) {
        switch (i) {
        case 0:
            imask |= 1 << (map0 & 7);
            break;
        case 1:
            imask |= 1 << (map1 & 7);
            break;
        case 2:
            imask |= 1 << (map2 & 7);
            break;
        case 3:
            imask |= 1 << (map3 & 7);
            break;
        }
    }
    J3DGDWriteBPCmd(imask | GX_BP_REG_INDIMASK << 0x18);
}

/* 8030F108-8030F294 309A48 018C+00 0/0 9/9 0/0 .text
 * J3DGDSetTevOrder__F13_GXTevStageID13_GXTexCoordID11_GXTexMapID12_GXChannelID13_GXTexCoordID11_GXTexMapID12_GXChannelID
 */
void J3DGDSetTevOrder(GXTevStageID stage, GXTexCoordID coord0, GXTexMapID map0,
                      GXChannelID channel0, GXTexCoordID coord1, GXTexMapID map1,
                      GXChannelID channel1) {
    coord0 = coord0 >= GX_MAXCOORD ? GX_TEXCOORD0 : coord0;
    coord1 = coord1 >= GX_MAXCOORD ? GX_TEXCOORD0 : coord1;
    GDOverflowCheck(5);
    static u8 c2r[32] = {0, 1, 0, 1, 0, 1, 7, 5, 6, 0, 0, 0, 0, 0, 0, 7,
                         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
    J3DGDWriteBPCmd((map0 & 7) | coord0 << 3 |
                    (map0 != GX_TEXMAP_NULL && !(map0 & GX_TEXMAP_DISABLE)) << 6 |
                    c2r[channel0 & 0xf] << 7 | (map1 & 7) << 0xc | coord1 << 0xf |
                    (map1 != GX_TEXMAP_NULL && !(map1 & GX_TEXMAP_DISABLE)) << 0x12 |
                    c2r[channel1 & 0xf] << 0x13 | (stage / 2 + GX_BP_REG_RAS1_TREF0) << 0x18);
}

/* 8030F294-8030F3FC 309BD4 0168+00 0/0 11/11 0/0 .text
 * J3DGDSetTevKColor__F14_GXTevKColorID8_GXColor                */
void J3DGDSetTevKColor(GXTevKColorID id, GXColor color) {
    u32 cmd0 = color.r | color.a << 0xc | 0x800000 | (id * 2 + GX_BP_REG_TEVREG0LO) << 0x18;
    u32 cmd1 = color.b | color.g << 0xc | 0x800000 | (id * 2 + GX_BP_REG_TEVREG0HI) << 0x18;
    GDOverflowCheck(0xa);
    J3DGDWriteBPCmd(cmd0);
    J3DGDWriteBPCmd(cmd1);
}

/* 8030F3FC-8030F630 309D3C 0234+00 0/0 11/11 0/0 .text
 * J3DGDSetTevColorS10__F11_GXTevRegID11_GXColorS10             */
void J3DGDSetTevColorS10(GXTevRegID id, GXColorS10 color) {
    u32 cmd0 =
        (color.r & 0x7ff) | (color.a & 0x7ff) << 0xc | (id * 2 + GX_BP_REG_TEVREG0LO) << 0x18;
    u32 cmd1 =
        (color.b & 0x7ff) | (color.g & 0x7ff) << 0xc | (id * 2 + GX_BP_REG_TEVREG0HI) << 0x18;
    GDOverflowCheck(0x14);
    J3DGDWriteBPCmd(cmd0);
    J3DGDWriteBPCmd(cmd1);
    J3DGDWriteBPCmd(cmd1);
    J3DGDWriteBPCmd(cmd1);
}

/* 8030F630-8030F994 309F70 0364+00 0/0 3/3 0/0 .text J3DGDSetFog__F10_GXFogTypeffff8_GXColor */
void J3DGDSetFog(GXFogType fogType, f32 param_1, f32 param_2, f32 nearZ, f32 farZ, GXColor color) {
    f32 fvar1, fvar2, fvar3;
    if (farZ == nearZ || param_2 == param_1) {
        fvar1 = 0.0f;
        fvar2 = 0.5f;
        fvar3 = 0.0f;
    } else {
        fvar1 = (farZ * nearZ) / ((farZ - nearZ) * (param_2 - param_1));
        fvar2 = farZ / (farZ - nearZ);
        fvar3 = param_1 / (param_2 - param_1);
    }
    u32 shift = 1;
    for (; fvar2 > 1.0; fvar2 *= 0.5f) {
        shift++;
    }
    for (; fvar2 > 0.0f && fvar2 < 0.5; fvar2 *= 2.0f) {
        shift--;
    }
    f32 fvar4 = (fvar1 / (1 << shift));
    u32 param1 = fvar2 * 8388638.0f;
    u32 param0 = *(u32*)&fvar4;
    u32 param3 = *(u32*)&fvar3;
    J3DGDWriteBPCmd(param0 >> 0xc | GX_BP_REG_FOGPARAM0 << 0x18);
    J3DGDWriteBPCmd(param1 | GX_BP_REG_FOGPARAM1 << 0x18);
    J3DGDWriteBPCmd(shift | GX_BP_REG_FOGPARAM2 << 0x18);
    J3DGDWriteBPCmd(param3 >> 0xc | fogType << 0x15 | GX_BP_REG_FOGPARAM3 << 0x18);
    J3DGDWriteBPCmd(color.b | color.g << 8 | color.r << 0x10 | GX_BP_REG_FOGCOLOR << 0x18);
}

/* 8030F994-8030FAE0 30A2D4 014C+00 0/0 3/3 0/0 .text J3DGDSetFogRangeAdj__FUcUsP14_GXFogAdjTable
 */
void J3DGDSetFogRangeAdj(u8 param_0, u16 param_1, GXFogAdjTable* table) {
    if (param_0 != 0) {
        for (int i = 0; i < 0xa; i += 2) {
            J3DGDWriteBPCmd((i / 2 + GX_BP_REG_FOGRANGEK0) << 0x18 | table->fogVals[i + 1] << 0xc |
                            table->fogVals[i]);
        }
    }
    u32 cmd = GX_BP_REG_FOGRANGE << 0x18 | (param_1 + 0x156) | param_0 << 0xa;
    J3DGDWriteBPCmd(cmd);
}

/* 8030FAE0-8030FB60 30A420 0080+00 0/0 10/10 0/0 .text            J3DFifoLoadPosMtxImm__FPA4_fUl */
void J3DFifoLoadPosMtxImm(MtxP mtx, u32 addr) {
    J3DFifoWriteXFCmdHdr((addr & 0x3fff) << 2, 0xc);
    J3DGXCmd1f32ptr(&mtx[0][0]);
    J3DGXCmd1f32ptr(&mtx[0][1]);
    J3DGXCmd1f32ptr(&mtx[0][2]);
    J3DGXCmd1f32ptr(&mtx[0][3]);
    J3DGXCmd1f32ptr(&mtx[1][0]);
    J3DGXCmd1f32ptr(&mtx[1][1]);
    J3DGXCmd1f32ptr(&mtx[1][2]);
    J3DGXCmd1f32ptr(&mtx[1][3]);
    J3DGXCmd1f32ptr(&mtx[2][0]);
    J3DGXCmd1f32ptr(&mtx[2][1]);
    J3DGXCmd1f32ptr(&mtx[2][2]);
    J3DGXCmd1f32ptr(&mtx[2][3]);
}

/* 8030FB60-8030FBCC 30A4A0 006C+00 0/0 9/9 0/0 .text            J3DFifoLoadNrmMtxImm__FPA4_fUl */
void J3DFifoLoadNrmMtxImm(MtxP mtx, u32 addr) {
    J3DFifoWriteXFCmdHdr(addr * 3 + 0x400, 9);
    J3DGXCmd1f32ptr(&mtx[0][0]);
    J3DGXCmd1f32ptr(&mtx[0][1]);
    J3DGXCmd1f32ptr(&mtx[0][2]);
    J3DGXCmd1f32ptr(&mtx[1][0]);
    J3DGXCmd1f32ptr(&mtx[1][1]);
    J3DGXCmd1f32ptr(&mtx[1][2]);
    J3DGXCmd1f32ptr(&mtx[2][0]);
    J3DGXCmd1f32ptr(&mtx[2][1]);
    J3DGXCmd1f32ptr(&mtx[2][2]);
}

/* 8030FBCC-8030FC38 30A50C 006C+00 0/0 3/3 0/0 .text            J3DFifoLoadNrmMtxImm3x3__FPA3_fUl
 */
void J3DFifoLoadNrmMtxImm3x3(Mtx3P mtx, u32 addr) {
    J3DFifoWriteXFCmdHdr(addr * 3 + 0x400, 9);
    J3DGXCmd1f32ptr(&mtx[0][0]);
    J3DGXCmd1f32ptr(&mtx[0][1]);
    J3DGXCmd1f32ptr(&mtx[0][2]);
    J3DGXCmd1f32ptr(&mtx[1][0]);
    J3DGXCmd1f32ptr(&mtx[1][1]);
    J3DGXCmd1f32ptr(&mtx[1][2]);
    J3DGXCmd1f32ptr(&mtx[2][0]);
    J3DGXCmd1f32ptr(&mtx[2][1]);
    J3DGXCmd1f32ptr(&mtx[2][2]);
}

/* 8030FC38-8030FCD0 30A578 0098+00 0/0 4/4 0/0 .text            J3DFifoLoadNrmMtxToTexMtx__FPA4_fUl
 */
void J3DFifoLoadNrmMtxToTexMtx(MtxP mtx, u32 addr) {
    J3DFifoWriteXFCmdHdr((addr & 0x3fff) << 2, 0xc);
    J3DGXCmd1f32ptr(&mtx[0][0]);
    J3DGXCmd1f32ptr(&mtx[0][1]);
    J3DGXCmd1f32ptr(&mtx[0][2]);
    J3DGXCmd1f32(0.0f);
    J3DGXCmd1f32ptr(&mtx[1][0]);
    J3DGXCmd1f32ptr(&mtx[1][1]);
    J3DGXCmd1f32ptr(&mtx[1][2]);
    J3DGXCmd1f32(0.0f);
    J3DGXCmd1f32ptr(&mtx[2][0]);
    J3DGXCmd1f32ptr(&mtx[2][1]);
    J3DGXCmd1f32ptr(&mtx[2][2]);
    J3DGXCmd1f32(0.0f);
}

/* 8030FCD0-8030FD68 30A610 0098+00 0/0 2/2 0/0 .text J3DFifoLoadNrmMtxToTexMtx3x3__FPA3_fUl */
void J3DFifoLoadNrmMtxToTexMtx3x3(Mtx3P mtx, u32 addr) {
    J3DFifoWriteXFCmdHdr((addr & 0x3fff) << 2, 0xc);
    J3DGXCmd1f32ptr(&mtx[0][0]);
    J3DGXCmd1f32ptr(&mtx[0][1]);
    J3DGXCmd1f32ptr(&mtx[0][2]);
    J3DGXCmd1f32(0.0f);
    J3DGXCmd1f32ptr(&mtx[1][0]);
    J3DGXCmd1f32ptr(&mtx[1][1]);
    J3DGXCmd1f32ptr(&mtx[1][2]);
    J3DGXCmd1f32(0.0f);
    J3DGXCmd1f32ptr(&mtx[2][0]);
    J3DGXCmd1f32ptr(&mtx[2][1]);
    J3DGXCmd1f32ptr(&mtx[2][2]);
    J3DGXCmd1f32(0.0f);
}

/* 8045093C-80450944 0003BC 0008+00 1/1 0/0 0/0 .sdata           J3DTexImage1Ids */
SECTION_SDATA static u8 J3DTexImage1Ids[8] = {
    0x8C, 0x8D, 0x8E, 0x8F, 0xAC, 0xAD, 0xAE, 0xAF,
};

/* 80450944-8045094C 0003C4 0008+00 1/1 0/0 0/0 .sdata           J3DTexImage2Ids */
SECTION_SDATA static u8 J3DTexImage2Ids[8] = {
    0x90, 0x91, 0x92, 0x93, 0xB0, 0xB1, 0xB2, 0xB3,
};

/* 8030FD68-8030FDE8 30A6A8 0080+00 0/0 1/1 0/0 .text
 * J3DFifoLoadTexCached__F11_GXTexMapIDUl15_GXTexCacheSizeUl15_GXTexCacheSize */
#ifdef NONMATCHING
void J3DFifoLoadTexCached(GXTexMapID id, u32 param_1, GXTexCacheSize param_2, u32 param_3,
                          GXTexCacheSize param_4) {
    J3DFifoLoadBPCmd(param_1 >> 5 | (param_2 + 3) << 0xf | (param_2 + 3) << 0x12 |
                     J3DTexImage1Ids[id] << 0x18);
    if (param_4 != GX_TEXCACHE_NONE && param_3 < 0x100000) {
        J3DFifoLoadBPCmd(param_3 >> 5 | (param_4 + 3) << 0xf | (param_4 + 3) << 0x12 |
                         J3DTexImage2Ids[id] << 0x18);
    }
}
#else
#pragma push
#pragma optimization_level 0
#pragma optimizewithasm off
asm void J3DFifoLoadTexCached(_GXTexMapID param_0, u32 param_1, _GXTexCacheSize param_2,
                              u32 param_3, _GXTexCacheSize param_4) {
    nofralloc
#include "asm/JSystem/J3DGraphBase/J3DGD/J3DFifoLoadTexCached__F11_GXTexMapIDUl15_GXTexCacheSizeUl15_GXTexCacheSize.s"
}
#pragma pop
#endif