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
|
#ifndef GFX_H
#define GFX_H
#include "ultra64.h"
#include "ultra64/gbi.h"
#include "alignment.h"
#include "sched.h"
#include "thga.h"
#include "versions.h"
#define SCREEN_WIDTH 320
#define SCREEN_HEIGHT 240
// Texture memory size, 4 KiB
#define TMEM_SIZE 0x1000
typedef struct GfxPool {
/* 0x00000 */ u16 headMagic; // GFXPOOL_HEAD_MAGIC
/* 0x00008 */ Gfx polyOpaBuffer[0x17E0];
/* 0x0BF08 */ Gfx polyXluBuffer[0x800];
/* 0x0FF08 */ Gfx overlayBuffer[0x400];
/* 0x11F08 */ Gfx workBuffer[0x80];
/* 0x11308 */ Gfx unusedBuffer[0x20];
/* 0x12408 */ u16 tailMagic; // GFXPOOL_TAIL_MAGIC
} GfxPool; // size = 0x12410
typedef struct GraphicsContext {
/* 0x0000 */ Gfx* polyOpaBuffer; // Pointer to "Zelda 0"
/* 0x0004 */ Gfx* polyXluBuffer; // Pointer to "Zelda 1"
/* 0x0008 */ char unk_008[0x08]; // Unused, could this be pointers to "Zelda 2" / "Zelda 3"
/* 0x0010 */ Gfx* overlayBuffer; // Pointer to "Zelda 4"
/* 0x0014 */ u32 unk_014;
/* 0x0018 */ char unk_018[0x20];
/* 0x0038 */ OSMesg msgBuff[0x08];
/* 0x0058 */ OSMesgQueue* schedMsgQueue;
/* 0x005C */ OSMesgQueue queue;
/* 0x0078 */ OSScTask task;
/* 0x00E0 */ char unk_0E0[0xD0];
/* 0x01B0 */ Gfx* workBuffer;
/* 0x01B4 */ TwoHeadGfxArena work;
/* 0x01C4 */ char unk_01C4[0xC0];
/* 0x0284 */ OSViMode* viMode;
/* 0x0288 */ char unk_0288[0x20]; // Unused, could this be Zelda 2/3 ?
/* 0x02A8 */ TwoHeadGfxArena overlay; // "Zelda 4"
/* 0x02B8 */ TwoHeadGfxArena polyOpa; // "Zelda 0"
/* 0x02C8 */ TwoHeadGfxArena polyXlu; // "Zelda 1"
/* 0x02D8 */ u32 gfxPoolIdx;
/* 0x02DC */ u16* curFrameBuffer;
/* 0x02E0 */ char unk_2E0[0x04];
/* 0x02E4 */ u32 viFeatures;
/* 0x02E8 */ s32 fbIdx;
/* 0x02EC */ void (*callback)(struct GraphicsContext*, void*);
/* 0x02F0 */ void* callbackParam;
#if OOT_VERSION >= PAL_1_0
/* 0x02F4 */ f32 xScale;
/* 0x02F8 */ f32 yScale;
#endif
/* 0x02FC */ char unk_2FC[0x04];
} GraphicsContext; // size = 0x300
extern Gfx gEmptyDL[];
Gfx* Gfx_SetFog(Gfx* gfx, s32 r, s32 g, s32 b, s32 a, s32 near, s32 far);
Gfx* Gfx_SetFogWithSync(Gfx* gfx, s32 r, s32 g, s32 b, s32 a, s32 near, s32 far);
Gfx* Gfx_SetFog2(Gfx* gfx, s32 r, s32 g, s32 b, s32 a, s32 near, s32 far);
Gfx* Gfx_BranchTexScroll(Gfx** gfxP, u32 x, u32 y, s32 width, s32 height);
Gfx* func_80094E78(GraphicsContext* gfxCtx, u32 x, u32 y);
Gfx* Gfx_TexScroll(GraphicsContext* gfxCtx, u32 x, u32 y, s32 width, s32 height);
Gfx* Gfx_TwoTexScroll(GraphicsContext* gfxCtx, s32 tile1, u32 x1, u32 y1, s32 width1, s32 height1, s32 tile2, u32 x2,
u32 y2, s32 width2, s32 height2);
Gfx* Gfx_TwoTexScrollEnvColor(GraphicsContext* gfxCtx, s32 tile1, u32 x1, u32 y1, s32 width1, s32 height1, s32 tile2,
u32 x2, u32 y2, s32 width2, s32 height2, s32 r, s32 g, s32 b, s32 a);
Gfx* Gfx_EnvColor(GraphicsContext* gfxCtx, s32 r, s32 g, s32 b, s32 a);
void Gfx_SetupFrame(GraphicsContext* gfxCtx, u8 r, u8 g, u8 b);
void func_80095974(GraphicsContext* gfxCtx);
void* Graph_Alloc(GraphicsContext* gfxCtx, size_t size);
void* Graph_Alloc2(GraphicsContext* gfxCtx, size_t size);
#define WORK_DISP __gfxCtx->work.p
#define POLY_OPA_DISP __gfxCtx->polyOpa.p
#define POLY_XLU_DISP __gfxCtx->polyXlu.p
#define OVERLAY_DISP __gfxCtx->overlay.p
#if DEBUG_FEATURES
void Graph_OpenDisps(Gfx** dispRefs, GraphicsContext* gfxCtx, const char* file, int line);
void Graph_CloseDisps(Gfx** dispRefs, GraphicsContext* gfxCtx, const char* file, int line);
// __gfxCtx shouldn't be used directly.
// Use the DISP macros defined above when writing to display buffers.
#define OPEN_DISPS(gfxCtx, file, line) \
{ \
GraphicsContext* __gfxCtx; \
Gfx* dispRefs[4]; \
__gfxCtx = gfxCtx; \
(void)__gfxCtx; \
Graph_OpenDisps(dispRefs, gfxCtx, file, line)
#define CLOSE_DISPS(gfxCtx, file, line) \
do { \
Graph_CloseDisps(dispRefs, gfxCtx, file, line); \
} while (0); \
} \
(void)0
#define GRAPH_ALLOC(gfxCtx, size) Graph_Alloc(gfxCtx, size)
#else
#define OPEN_DISPS(gfxCtx, file, line) \
{ \
GraphicsContext* __gfxCtx = gfxCtx; \
s32 __dispPad
#define CLOSE_DISPS(gfxCtx, file, line) \
do {} while (0); \
} \
(void)0
#define GRAPH_ALLOC(gfxCtx, size) ((void*)((gfxCtx)->polyOpa.d = (Gfx*)((u8*)(gfxCtx)->polyOpa.d - ALIGN16(size))))
#endif
void Graph_ThreadEntry(void*);
extern u64 gMojiFontTLUTs[4][4]; // original name: "moji_tlut"
extern u64 gMojiFontTex[]; // original name: "font_ff"
/**
* `x` vertex x
* `y` vertex y
* `z` vertex z
* `s` texture s coordinate
* `t` texture t coordinate
* `crnx` red component of color vertex, or x component of normal vertex
* `cgny` green component of color vertex, or y component of normal vertex
* `cbnz` blue component of color vertex, or z component of normal vertex
* `a` alpha
*/
#define VTX(x,y,z,s,t,crnx,cgny,cbnz,a) { { { x, y, z }, 0, { s, t }, { crnx, cgny, cbnz, a } } }
#define VTX_T(x,y,z,s,t,cr,cg,cb,a) { { x, y, z }, 0, { s, t }, { cr, cg, cb, a } }
#define gDPSetTileCustom(pkt, fmt, siz, uls, ult, lrs, lrt, pal, \
cms, cmt, masks, maskt, shifts, shiftt) \
_DW({ \
gDPPipeSync(pkt); \
gDPTileSync(pkt); \
gDPSetTile(pkt, fmt, siz, \
(((((lrs) - (uls) + 1) * siz##_TILE_BYTES) + 7) >> 3), 0, \
G_TX_LOADTILE, 0, cmt, maskt, shiftt, cms, masks, \
shifts); \
gDPTileSync(pkt); \
gDPSetTile(pkt, fmt, siz, \
(((((lrs) - (uls) + 1) * siz##_LINE_BYTES) + 7) >> 3), 0, \
G_TX_RENDERTILE, pal, cmt, maskt, shiftt, cms, masks, shifts); \
gDPSetTileSize(pkt, G_TX_RENDERTILE, \
(uls) << G_TEXTURE_IMAGE_FRAC, \
(ult) << G_TEXTURE_IMAGE_FRAC, \
(lrs) << G_TEXTURE_IMAGE_FRAC, \
(lrt) << G_TEXTURE_IMAGE_FRAC); \
})
#endif
|