NewFunctions
8.59 KB
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
-----------------------------------------------------------------------------
* New functions of F3DEX(.NoN), F3DLX(.NoN), F3DLX.Rej, F3DLP.Rej and L3DEX
ucode.
--- Release 1.21.
-----------------------------------------------------------------------------
+ gSPVertex (Gfx *pkt, Vtx *v, u32 n, u32 v0)
gsSPVertex( Vtx *v, u32 n, u32 v0)
Made the vertex cache larger, so changed the range of
parameters n and v0. (see below) g*SPVertex accepts less than
33 vertice per one load. (n accepts 1-32.) So, you may use it
twice or more to load more than 32 vertice(*).
Vertice
cache size Range of n Range of v0
F3DEX/F3DEX.NoN 32 1-32 0-31
F3DLX/F3DLX.NoN 32 1-32 0-31
F3DLX.Rej 64 1-32(*) 0-63
F3DLP.Rej 80 1-32(*) 0-79
L3DEX 32 1-32 0-31
+ gSP2Triangles (pkt, v00, v01, v02, flag0, v10, v11, v12, flag1)
gsSP2Triangles( v00, v01, v02, flag0, v10, v11, v12, flag1)
gSP2Triangles are "double triangle face command."
This command generates *two* triangles same as
gSP1Triangle(pkt++, v00, v01, v02, flag0);
gSP1Triangle(pkt++, v10, v11, v12, flag1);
You can replace two g*SP1Triangle to one g*SP2Triangles,
so this command can make DL size shorter.
F3DLX.Rej and F3DLP.Rej are very fast because they are
optimized for executing g*SP2Triangle. So you'd better use
g*SPTriangle to get more performance.
+ gSP1Quadrangle (pkt, v0, v1, v2, v3, flag)
gsSP1Quadrangle( v0, v1, v2, v3, flag)
g*SP1Quadrangle generates a quadrangle (v0,v1,v2,v3).
flag should be either 0,1,2 or 3 for flat shading.
We don't support dynamic divide selection for quadrangle in
this and later release. Because SP's overhead is larger than
DP's increase of performance we had expected.
In release 0.96 and later, g*SP1Quadrangle is emulated by
g*SP2Triangles, so apps for release 0.95 or before can work
with re-compiling.
+ gSPSetGeometryMode(Gfx *gdl, unsigned int mode)
gsSPSetGeometryMode(unsigned int mode)
G_CLIPPING would be available for mode identify.
If G_CLIPPING has cleared, F3DLX does not clip any triangle
(quadrangle) but faster.
If G_CLIPPING has cleared....
gSPVertex : Does not make pre-calculated vertex data for clipping.
gSP*Triangle: Does not work any clipping. (also gSP1Quadrangle)
So, following DL is *not* correct because gsSP1Triangle cannot get
pre-calculated vertex data of clipping from gsSPVertex.
In this DL, gsSP1Triangle cannot work.
gsSPClearGeometryMode(G_CLIPPING), // Clipping OFF
gsSPVertex(v, 3, 0), // Load 3 vertices
gsSPSetGeometryMode(G_CLIPPING), // Clipping ON
gsSP1Triangle(0,1,2,0), // Draw TRI
Also gSPCullDisplayList() cannot work with no pre-calculated vertex
data made by no G_CLIPPING.
G_CLIPPING is available in F3DLX only. It's ignored in other ucodes.
G_CLIPPING is set when initialized RSP.
+ gSPCullDisplaylist(Gfx *gdl, unsigned int v0, unsigned int vn)
gsSPCullDisplaylist(unsigned int v0, unsigned int vn)
Change ranges of v0 and vn by increase vertices cache size.
The ranges are same as v0 of gSPVertex parameter. But, must be
v0 <= vn. (man pages are incorrect.)
g*SPClipRatio of F3DEX(.NoN), F3DLX(.NoN) and L3DEX works same
as Fast3D's. But F3DLX.Rej's and F3DLP.Rej's are not same at all.
+ gSPClipRatio(Gfx *gdl, r)
gsSPClipRatio(r)
Also, g*SPClipRatio of F3DEX(.NoN), F3DLX(.NoN) and L3DEX works
same as Fast3D's. But F3DLX.Rej's and F3DLP.Rej's are not same
at all. In F3DL*.Rej, g*SPClipRatio defines a size of the rejecting
box. (default rejecting box size: FRUSTRATIO_2)
+ gSPModiftVertex(Gfx *gdl,
unsigned int vtx, unsigned int where, unsigned int val)
gsSPModifyVertex(unsigned int vtx, unsigned int where, unsigned int val)
Change ranges of vtx by increase vertices cache size. The
ranges are same as v0 of gSPVertex parameter.
+ gSPBranchLessZ(Gfx *gdl, Gfx *branchdl, unsigned int vtx,
float zval, float near, float far, int flag)
gsSPBranchLessZ(Gfx *branchdl, unsigned int vtx,
float zval, float near, float far, int flag)
Branch display list to pointer specified `branchdl' if screen
depth of `vtx' less than or equal `zval'. If greater, do nothing.
It makes supporting model LOD very easier.
Here is a sample model with 3 level LOD.
Gfx model_near[] = { // Model DL on 32<=depth<=200
.....
gsSPEndDisplayList(),
};
Gfx model_mid[] = { // Model DL on 201<=depth<=800
.....
gsSPEndDisplayList(),
};
Gfx model_far[] = { // Model DL on 801<=depth<=1600
.....
gsSPEndDisplayList(),
};
Gfx model[] = {
gsSPVertex(testvtx, 1, 0),
gsSPBranchLessZ(model_near, 0, 200, 32, 2000, G_BZ_PERSP),
gsSPBranchLessZ(model_mid, 0, 800, 32, 2000, G_BZ_PERSP),
gsSPBranchLessZ(model_far, 0, 1600, 32, 2000, G_BZ_PERSP),
gsSPEndDisplayList(), // Don't display if 1601<=depth.
};
This GBI needs some parameters about viewing frustum as following.
`near' Distance to the near clipping plane.
Same value specified in guPerspective()/guOrtho().
`far' Distance to the far clipping plane.
Same value specified in guPerspective()/guOrtho().
`flag' Set `G_BZ_PERSP' for perspective projection(guPerspective).
Set `G_BZ_ORTHO' for orthographic projection(guOrtho).
To use g*SPBranchLessZ(), the view port parameters
`vp.vscale[2]' and `vp.vtrans[2]' should be set `G_MAXZ/2'.
Normally, it is unnecessary to set other values for vp.vscale[2],
and vp.vtrans[2]. But, when you want other values, you may use
g*SPBranchLessZrg() instead of g*SPBranchLessZ().
This GBI's are supported in release 1.02 or later, and available
in F3DEX(.NoN), F3DLX(.NoN), F3DLX.Rej, F3DLP.Rej and L3DEX.
+ gSPBranchLessZrg(Gfx *gdl, Gfx *branchdl, unsigned int vtx,
float zval, float near, float far, int flag,
int zmin, int zmax)
gsSPBranchLessZrg(Gfx *branchdl, unsigned int vtx,
float zval, float near, float far, int flag,
int zmin, int zmax)
Normally, the range of screen depth value should be 0 to G_MAXZ
with g*SPBranchLessZ. However, if you want to use another range
`zmin' to `zmax', you should use g*SPBranchLessZrg instead of
g*SPBranchLessZ.
g*SPBranchLessZrg needs two more parameters than g*SPBranchLessZ.
`zmin' depth value minimum. (= vp.vtrans[2]-vp.vscale[2])
`zmax' depth value maximum. (= vp.vtrans[2]+vp.vscale[2])
Other paramters (gdl, branchdl, vtx, zval, near, far and flag)
are same as g*SPBranchLessZ's.
This GBI's are supported in release 1.02 or later, and available
in F3DEX(.NoN), F3DLX(.NoN), F3DLX.Rej, F3DLP.Rej and L3DEX.
+ gSPLoadUcode(Gfx *gdl, u64 *uc_start, u64 *uc_dstart)
gsSPLoadUcode(u64 *uc_start, u64 *uc_dstart)
uc_start : Physical address of the top of the ucode text section.
uc_dstart: Physical address of the top of the ucode data section.
Load ucode into IMEM/DMEM and initailize RSP.
Loadable ucodes are F3DEX(.NoN), F3DLX(.NoN), F3DLX_Rej, F3DLP_Rej
and L3DEX. Fast3D and Turbo3D are not loadable.
You should be careful to `Load ucode'. Because to load ucode would
often take some processing time. It's overhead. So, you should
avoid useless ucode loading.
The ucodes would be changed to get best performance in the situation,
such as...
o Loading F3DLX ucode to draw game field with clipping function.
(Clipping is necessary to draw game field.)
o Loading F3DLX.Rej (after draw game field) to draw game object as
a man, a car ... (F3DLX.Rej is faster than F3DLX.)
And you can load line ucode `L3DEX' to draw line without CPU
processing.
*** Caution ***
This GBI command g*SPLoadUcode makes RSP initailized.
So, you should set all parameters of RSP status again
(Segment address, Viewport, Geometry-mode, Matrix, Link info.
of display list ... and more). So, when you use g*SPLoadUcode in
Display list (DL1) linked from another Display List (DL2) by
g*SPDisplayList, the DL1 cannot return back to DL2. It's very
dangerous implemention I think, but we don't have enough code
space to fix it.
You should set `OS_TASK_LOADABLE' to member `flag' in `OSTask' to
use this GBI g*SPLoadUcode like as this.
OSTask *tp;
tp->t.flag = OS_TASK_LOADABLE | OS_TASK_DP_WAIT;
To make OS_TASK_LOADABLE available, you need U64 dev env
2.0h or later.
+ gSPLoadUcodeL(Gfx *gdl, ucode_name)
gsSPLoadUcodeL(ucode_name)
g*SPLoadUcodeL is same as g*SPLoadUcode expect an expression.
See following, (a) and (b) works equally.
(a) gsSPLoadUcode(OS_K0_TO_PHYSICAL(&gspF3DEX_fifoTextStart),
OS_K0_TO_PHYSICAL(&gspF3DEX_fifoDataStart))
(b) gsSPLoadUcodeL(gspF3DEX_fifo)