1 /*---------------------------------------------------------------------------*
2 Project: Dolphin GD library
3 File: GDPixel.c
4
5 Copyright 2001 Nintendo. All rights reserved.
6
7 These coded instructions, statements, and computer programs contain
8 proprietary information of Nintendo of America Inc. and/or Nintendo
9 Company Ltd., and are protected by Federal copyright law. They may
10 not be disclosed to third parties or copied or duplicated in any form,
11 in whole or in part, without the prior written consent of Nintendo.
12
13 $Log: GDPixel.c,v $
14 Revision 1.2 2006/02/20 04:24:39 mitu
15 Changed include path from dolphin/ to revolution/.
16
17 Revision 1.1.1.1 2005/05/12 02:15:49 yasuh-to
18 Ported from dolphin source tree.
19
20
21 4 2003/07/17 11:42 Hirose
22 Fixed "PE_CMODE1_MASK_SETBLENDMODE" macro definition.
23
24 3 2002/10/28 11:08 Hirose
25 Supported fog functions for orthographic projection.
26
27 2 2001/10/13 2:27a Hirose
28 Added GDSetBlendMode().
29
30 1 2001/09/12 1:52p Carl
31 Initial revision of GD: Graphics Display List Library.
32 $NoKeywords: $
33 *---------------------------------------------------------------------------*/
34
35 #include <revolution/gd.h>
36 #include <revolution/os.h>
37
38 /*---------------------------------------------------------------------------*/
39
40
41 /*---------------------------------------------------------------------------*/
42 // Name: GDSetFog
43 //
44 // Description: Computes and sets fog parameters.
45 //
46 // Arguments: type: IN Fog type
47 // startz,
48 // endz: IN Z Range for linear fog.
49 // nearz,
50 // farz: IN Clipping planes Z values (projection matrix)
51 // color: IN Color of the fog.
52 //
53 // Returns:
54 //
55 /*---------------------------------------------------------------------------*/
56
GDSetFog(GXFogType type,f32 startz,f32 endz,f32 nearz,f32 farz,GXColor color)57 void GDSetFog( GXFogType type,
58 f32 startz,
59 f32 endz,
60 f32 nearz,
61 f32 farz,
62 GXColor color )
63 {
64 f32 A, B, B_mant, C, A_f;
65 u32 b_expn, b_m, a_hex, c_hex;
66 u32 fsel, proj;
67
68 ASSERTMSG(farz >= 0, "GDSetFog: The farz should be positive value");
69 ASSERTMSG(farz >= nearz, "GDSetFog: The farz should be larger than nearz");
70
71 fsel = (u32)(type & 0x07);
72 proj = (u32)((type >> 3) & 0x01);
73
74 if ( proj ) // ORTHOGRAPHIC
75 {
76 // Calculate constants a and c (TEV HW requirements).
77 if ((farz == nearz) || (endz == startz))
78 {
79 // take care of the odd-ball case.
80 A_f = 0.0f;
81 C = 0.0f;
82 }
83 else
84 {
85 A = 1.0F / (endz - startz);
86 A_f = (farz - nearz) * A;
87 C = (startz - nearz) * A;
88 }
89
90 b_expn = 0;
91 b_m = 0;
92 }
93 else // PERSPECTIVE
94 {
95 // Calculate constants a, b, and c (TEV HW requirements).
96 if ((farz == nearz) || (endz == startz))
97 {
98 // take care of the odd-ball case.
99 A = 0.0f;
100 B = 0.5f;
101 C = 0.0f;
102 }
103 else
104 {
105 A = (farz * nearz) / ((farz-nearz) * (endz-startz));
106 B = farz / (farz-nearz);
107 C = startz / (endz-startz);
108 }
109
110 B_mant = B;
111 b_expn = 1;
112 while (B_mant > 1.0)
113 {
114 B_mant /= 2;
115 b_expn++;
116 }
117 while ((B_mant > 0) && (B_mant < 0.5))
118 {
119 B_mant *= 2;
120 b_expn--;
121 }
122
123 A_f = A / (1 << (b_expn));
124 b_m = (u32)(B_mant * 8388638);
125 }
126
127 a_hex = (* (u32 *) &A_f);
128 c_hex = (* (u32 *) &C);
129
130 // Write out register values.
131 GDWriteBPCmd( TEV_FOG_PARAM_0_PS( (a_hex >> 12), TEV_FOG_PARAM_0_ID ));
132
133 GDWriteBPCmd( TEV_FOG_PARAM_1( b_m, TEV_FOG_PARAM_1_ID ));
134 GDWriteBPCmd( TEV_FOG_PARAM_2( b_expn, TEV_FOG_PARAM_2_ID ));
135
136 GDWriteBPCmd( TEV_FOG_PARAM_3_PS( (c_hex >> 12), proj, fsel,
137 TEV_FOG_PARAM_3_ID ));
138
139 GDWriteBPCmd( TEV_FOG_COLOR( color.b, color.g, color.r, TEV_FOG_COLOR_ID ));
140 }
141
142
143 /*---------------------------------------------------------------------------*/
144 // Name: GDSetBlendMode
145 //
146 // Description: Sets Blending and logic operation registers in PE.
147 // Register mask is used to prevent changing other status
148 // in the cmode0 register.
149 //
150 // Arguments: type: Blending or Logic op enable.
151 // src_factor: Blending source factor.
152 // dst_factor: Blending destination factor.
153 // logic_op: Logic operation.
154 //
155 // Returns: None.
156 //
157 /*---------------------------------------------------------------------------*/
158
159 #define PE_CMODE1_MASK_SETBLENDMODE \
160 (( 0x000001 << PE_CMODE0_BLEND_ENABLE_SHIFT ) | \
161 ( 0x000001 << PE_CMODE0_LOGICOP_ENABLE_SHIFT ) | \
162 ( 0x000007 << PE_CMODE0_DFACTOR_SHIFT ) | \
163 ( 0x000007 << PE_CMODE0_SFACTOR_SHIFT ) | \
164 ( 0x000001 << PE_CMODE0_BLENDOP_SHIFT ) | \
165 ( 0x00000F << PE_CMODE0_LOGICOP_SHIFT ))
166
167
GDSetBlendMode(GXBlendMode type,GXBlendFactor src_factor,GXBlendFactor dst_factor,GXLogicOp logic_op)168 void GDSetBlendMode( GXBlendMode type,
169 GXBlendFactor src_factor,
170 GXBlendFactor dst_factor,
171 GXLogicOp logic_op )
172 {
173 GDWriteBPCmd( SS_MASK( PE_CMODE1_MASK_SETBLENDMODE ));
174
175 GDWriteBPCmd( PE_CMODE0(
176 ((type == GX_BM_BLEND) || (type == GX_BM_SUBTRACT)),
177 (type == GX_BM_LOGIC),
178 0,
179 0,
180 0,
181 dst_factor,
182 src_factor,
183 (type == GX_BM_SUBTRACT),
184 logic_op,
185 PE_CMODE0_ID ));
186 }
187
188
189 /*---------------------------------------------------------------------------*/
190 // Name: GDSetBlendModeEtc
191 //
192 // Description: Sets Blending and logic operation registers in PE.
193 // Also sets color and alpha write masks and dither mode.
194 //
195 // Arguments: type: Blending or Logic op enable.
196 // src_factor: Blending source factor.
197 // dst_factor: Blending destination factor.
198 // logic_op: Logic operation.
199 // color_update_enable: as it says
200 // alpha_update_enable: as it says
201 // dither_enable: as it says
202 //
203 // Returns: None.
204 //
205 /*---------------------------------------------------------------------------*/
206
GDSetBlendModeEtc(GXBlendMode type,GXBlendFactor src_factor,GXBlendFactor dst_factor,GXLogicOp logic_op,GXBool color_update_enable,GXBool alpha_update_enable,GXBool dither_enable)207 void GDSetBlendModeEtc( GXBlendMode type,
208 GXBlendFactor src_factor,
209 GXBlendFactor dst_factor,
210 GXLogicOp logic_op,
211 GXBool color_update_enable,
212 GXBool alpha_update_enable,
213 GXBool dither_enable )
214 {
215 GDWriteBPCmd( PE_CMODE0(
216 ((type == GX_BM_BLEND) || (type == GX_BM_SUBTRACT)),
217 (type == GX_BM_LOGIC),
218 dither_enable,
219 color_update_enable,
220 alpha_update_enable,
221 dst_factor,
222 src_factor,
223 (type == GX_BM_SUBTRACT),
224 logic_op,
225 PE_CMODE0_ID ));
226 }
227
228 /*---------------------------------------------------------------------------*/
229 // Name: GDSetZMode
230 //
231 // Description: Sets zbuffer compare and update parameters.
232 //
233 // Arguments: compare_enable: enables z comparison and culling.
234 // func: function used in z comparision.
235 // update_enable: enables writing new z values to zbuffer.
236 //
237 // Returns: None.
238 //
239 /*---------------------------------------------------------------------------*/
240
GDSetZMode(GXBool compare_enable,GXCompare func,GXBool update_enable)241 void GDSetZMode( GXBool compare_enable,
242 GXCompare func,
243 GXBool update_enable )
244 {
245 GDWriteBPCmd( PE_ZMODE( compare_enable, func, update_enable, PE_ZMODE_ID ));
246 }
247
248 /*---------------------------------------------------------------------------*/
249 // Name: GDSetDstAlpha
250 //
251 // Description: Sets a constant alpha value for writing to framebuffer.
252 //
253 // Arguments: enable: Enable constant alpha writes.
254 // alpha: constant value.
255 //
256 // Returns: None.
257 //
258 /*---------------------------------------------------------------------------*/
259
GDSetDstAlpha(GXBool enable,u8 alpha)260 void GDSetDstAlpha( GXBool enable, u8 alpha )
261 {
262 GDWriteBPCmd( PE_CMODE1( alpha, enable, PE_CMODE1_ID ));
263 }
264
265 /*---------------------------------------------------------------------------*/
266 // Name: GDSetDrawSync
267 //
268 // Description: Writes a sync token to the PE's token register via GFX fifo.
269 //
270 // Arguments: token: token value to be written to the pipe.
271 //
272 // Returns:
273 //
274 /*---------------------------------------------------------------------------*/
275
GDSetDrawSync(u16 token)276 void GDSetDrawSync( u16 token )
277 {
278 // TOKEN_INT is the register that is compared against TOKEN
279 // to see whether or not to generate a CPU interrupt.
280 // TOKEN is the register that is readable using GXReadDrawSync().
281
282 GDWriteBPCmd( PE_TOKEN( token, PE_TOKEN_INT_ID ));
283 GDWriteBPCmd( PE_TOKEN( token, PE_TOKEN_ID ));
284 }
285
286