1 /*---------------------------------------------------------------------------*
2 Project: KPAD Sample Program
3 File: graphic.c
4 Programmer: Keizo Ohta
5 Haruki Tojo
6
7 Copyright 2005-2008 Nintendo. All rights reserved.
8
9 These coded instructions, statements, and computer programs contain
10 proprietary information of Nintendo of America Inc. and/or Nintendo
11 Company Ltd., and are protected by Federal copyright law. They may
12 not be disclosed to third parties or copied or duplicated in any form,
13 in whole or in part, without the prior written consent of Nintendo.
14 *---------------------------------------------------------------------------*/
15
16 #include <revolution.h>
17 #include <math.h>
18
19 #include "graphic.h"
20
21 /***************************************************************
22 Variables
23 ***************************************************************/
24 GXColor black_clr = { 0, 0, 0, 255 } ;
25 GXColor smoke_clr = { 61, 61, 61, 255 } ;
26 GXColor gray_clr = { 129,129,129, 255 } ;
27 GXColor white_clr = { 255,255,255, 255 } ;
28 GXColor silver_clr = { 193,193,193, 255 } ;
29 GXColor red_clr = { 237, 58, 66, 255 } ;
30 GXColor green_clr = { 30,200,121, 255 } ;
31 GXColor blue_clr = { 0, 84,166, 255 } ;
32 GXColor yellow_clr = { 255,242, 0, 255 } ;
33 GXColor cyan_clr = { 0,184,239, 255 } ;
34 GXColor magenta_clr = { 236, 0,160, 255 } ;
35 GXColor orange_clr = { 255,155, 52, 255 } ;
36 GXColor violet_clr = { 188,122,205, 255 } ;
37 GXColor peagreen_clr = { 141,198, 63, 255 } ;
38
39 /*******************************************************************************
40 Initialize rendering of simple graphics
41 fb_width: Horizontal resolution of frame buffer
42 fb_height: Vertical resolution of frame buffer
43 *******************************************************************************/
init_draw_graphic(u16 fb_width,u16 fb_height)44 void init_draw_graphic( u16 fb_width, u16 fb_height )
45 {
46 Mtx44 proj_mtx ;
47 Mtx view_mtx ;
48 f32 canvas_wd, canvas_ht ;
49
50 //----- Virtual canvas size
51 canvas_wd = fb_width * 0.91346f ;
52 canvas_ht = (f32)(fb_height) ;
53
54 //----- MTX
55 MTXOrtho( proj_mtx, canvas_ht * -0.5f,canvas_ht * 0.5f, canvas_wd * -0.5f,canvas_wd * 0.5f, -10.0f,10.0f ) ;
56 GXSetProjection( proj_mtx, GX_ORTHOGRAPHIC ) ;
57
58 MTXIdentity( view_mtx ) ;
59 GXLoadPosMtxImm( view_mtx, GX_PNMTX0 ) ;
60 GXSetCurrentMtx( GX_PNMTX0 ) ;
61
62 //----- VERTEX
63 GXClearVtxDesc() ;
64 GXSetVtxDesc( GX_VA_POS, GX_DIRECT ) ;
65 GXSetVtxAttrFmt( GX_VTXFMT0, GX_VA_POS, GX_POS_XY, GX_F32, 0 ) ;
66
67 //----- CHANNEL
68 GXSetNumChans( 1 ) ;
69 GXSetChanCtrl( GX_COLOR0A0, GX_DISABLE, GX_SRC_REG, GX_SRC_REG, GX_LIGHT_NULL, GX_DF_NONE, GX_AF_NONE ) ;
70 GXSetChanCtrl( GX_COLOR1A1, GX_DISABLE, GX_SRC_REG, GX_SRC_REG, GX_LIGHT_NULL, GX_DF_NONE, GX_AF_NONE ) ;
71
72 //----- TEXTURE
73 GXSetNumTexGens( 0 ) ;
74
75 //----- TEV
76 GXSetNumTevStages( 1 ) ;
77 GXSetTevOrder( GX_TEVSTAGE0, GX_TEXCOORD_NULL, GX_TEXMAP_NULL, GX_COLOR_NULL ) ;
78 GXSetTevColorIn( GX_TEVSTAGE0, GX_CC_ZERO, GX_CC_ZERO, GX_CC_ZERO, GX_CC_C0 ) ;
79 GXSetTevColorOp( GX_TEVSTAGE0, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_ENABLE, GX_TEVPREV ) ;
80 GXSetTevAlphaIn( GX_TEVSTAGE0, GX_CA_ZERO, GX_CA_ZERO, GX_CA_ZERO, GX_CA_A0 ) ;
81 GXSetTevAlphaOp( GX_TEVSTAGE0, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_ENABLE, GX_TEVPREV ) ;
82 GXSetAlphaCompare( GX_ALWAYS,0, GX_AOP_OR, GX_ALWAYS,0 ) ;
83
84 //----- SCREEN
85 GXSetBlendMode( GX_BM_BLEND, GX_BL_SRCALPHA, GX_BL_INVSRCALPHA, GX_LO_NOOP ) ;
86 GXSetAlphaUpdate( GX_DISABLE ) ;
87
88 GXSetZMode( GX_DISABLE, GX_ALWAYS, GX_DISABLE ) ;
89 GXSetCullMode( GX_CULL_BACK ) ;
90 }
91
92 /*******************************************************************************
93 Initialize 3D graphics rendering
94 *******************************************************************************/
init_draw_graphic_3d(Mtx v,GXColor clr)95 void init_draw_graphic_3d( Mtx v, GXColor clr )
96 {
97 Mtx44 p ; // Projection matrix
98 Vec up = { 0.0F, 1.0F, 0.0F } ;
99 Vec camLoc = { 0.0F, 0.0F, -800.0F } ;
100 Vec objPt = { 0.0F, 0.0F, 100.0F } ;
101 f32 left = 240.0F ;
102 f32 top = 320.0F ;
103 f32 znear = 500.0F ;
104 f32 zfar = 2000.0F ;
105 GXLightObj MyLight ;
106
107 //----- MTX
108 MTXFrustum( p, left, -left, -top, top, znear, zfar ) ;
109 GXSetProjection( p, GX_PERSPECTIVE ) ;
110
111 //----- Camera
112 MTXLookAt( v, &camLoc, &up, &objPt ) ;
113
114 //----- VERTICES
115 GXClearVtxDesc() ;
116 GXSetVtxDesc( GX_VA_POS, GX_DIRECT ) ;
117 GXSetVtxDesc( GX_VA_NRM, GX_DIRECT ) ;
118 GXSetVtxAttrFmt( GX_VTXFMT3, GX_VA_POS, GX_POS_XYZ, GX_F32, 0 ) ;
119 GXSetVtxAttrFmt( GX_VTXFMT3, GX_VA_NRM, GX_NRM_XYZ, GX_F32, 0 ) ;
120
121 //----- CHANNEL
122 GXSetNumChans( 1 ) ;
123 GXSetChanCtrl( GX_COLOR0A0, GX_ENABLE, GX_SRC_REG, GX_SRC_REG, GX_LIGHT0, GX_DF_CLAMP, GX_AF_NONE ) ;
124
125 //----- TEXTURE
126 GXSetNumTexGens( 0 ) ;
127
128 //----- TEV
129 GXSetNumTevStages( 1 ) ;
130 GXSetTevOp( GX_TEVSTAGE0, GX_PASSCLR ) ;
131 GXSetTevOrder( GX_TEVSTAGE0, GX_TEXCOORD_NULL, GX_TEXMAP_NULL, GX_COLOR0A0 ) ;
132
133 //----- Z-comparison
134 GXSetZMode( GX_TRUE, GX_LEQUAL, GX_TRUE ) ;
135
136 //----- Lights
137 GXInitLightColor( &MyLight, white_clr ) ;
138 GXInitLightPos( &MyLight, 0.0F, 0.0F, 0.0F ) ;
139 GXLoadLightObjImm( &MyLight, GX_LIGHT0 ) ;
140
141 //----- Ambient colors
142 GXSetChanAmbColor( GX_COLOR0A0, gray_clr ) ;
143 //----- Material colors
144 GXSetChanMatColor( GX_COLOR0A0, clr ) ;
145
146 }
147
148
149 /*******************************************************************************
150 Render a point
151 *******************************************************************************/
draw_point(f32 px,f32 py,GXColor clr,f32 size)152 void draw_point( f32 px, f32 py, GXColor clr, f32 size )
153 {
154 GXSetTevColor( GX_TEVREG0, clr ) ;
155 GXSetPointSize( (u8)(s32)(size * 6.0f + 0.5f), GX_TO_ZERO ) ;
156
157 GXBegin( GX_POINTS, GX_VTXFMT0, 1 ) ;
158 GXPosition2f32( px, py ) ;
159 GXEnd() ;
160 }
161
162
163 /*******************************************************************************
164 Render a line segment
165 *******************************************************************************/
draw_line(f32 x1,f32 y1,f32 x2,f32 y2,GXColor clr,f32 width)166 void draw_line( f32 x1, f32 y1, f32 x2, f32 y2, GXColor clr, f32 width )
167 {
168 GXSetTevColor( GX_TEVREG0, clr ) ;
169 GXSetLineWidth( (u8)(s32)(width * 6.0f + 0.5f), GX_TO_ZERO ) ;
170
171 GXBegin( GX_LINES, GX_VTXFMT0, 2 ) ;
172 GXPosition2f32( x1, y1 ) ;
173 GXPosition2f32( x2, y2 ) ;
174 GXEnd() ;
175 }
176
177
178 /*******************************************************************************
179 Render a dashed line
180 *******************************************************************************/
draw_dashed_line(f32 x1,f32 y1,f32 x2,f32 y2,GXColor clr,f32 width)181 void draw_dashed_line( f32 x1, f32 y1, f32 x2, f32 y2, GXColor clr, f32 width )
182 {
183 const int DIV=5;
184 int i=0;
185 f32 dx = x2 - x1;
186 f32 dy = y2 - y1;
187 f32 length = (f32)sqrt(dx*dx + dy*dy);
188 GXSetTevColor( GX_TEVREG0, clr ) ;
189 GXSetLineWidth( (u8)(s32)(width * 6.0f + 0.5f), GX_TO_ZERO ) ;
190
191 for(i=0; i<DIV; ++i){
192 GXBegin( GX_LINES, GX_VTXFMT0, 2 ) ;
193 GXPosition2f32( x1+dx/(2*DIV)*(2*i+0), y1+dy/(2*DIV)*(2*i+0) ) ;
194 GXPosition2f32( x1+dx/(2*DIV)*(2*i+1), y1+dy/(2*DIV)*(2*i+1) ) ;
195 GXEnd() ;
196 }
197 }
198
199
200 /*******************************************************************************
201 Render an arrow
202 *******************************************************************************/
draw_arrow(f32 x1,f32 y1,f32 x2,f32 y2,GXColor clr,f32 width)203 void draw_arrow( f32 x1, f32 y1, f32 x2, f32 y2, GXColor clr, f32 width )
204 {
205 f32 vx,vy, f ;
206
207 vx = x2 - x1 ;
208 vy = y2 - y1 ;
209 f = sqrtf( vx*vx + vy*vy ) ;
210 if ( f == 0.0f ) {
211 vx = vy = 0.0f ;
212 } else {
213 f = width * 1.5f / f ;
214 vx *= f ;
215 vy *= f ;
216 }
217 draw_line( x1,y1, x2,y2, clr, width ) ;
218 draw_line( x2,y2, x2-vx-vx-vy,y2-vy-vy+vx, clr, width ) ;
219 draw_line( x2,y2, x2-vx-vx+vy,y2-vy-vy-vx, clr, width ) ;
220 }
221
222
223 /*******************************************************************************
224 Render an arrow (dashed line)
225 *******************************************************************************/
draw_dashed_arrow(f32 x1,f32 y1,f32 x2,f32 y2,GXColor clr,f32 width)226 void draw_dashed_arrow( f32 x1, f32 y1, f32 x2, f32 y2, GXColor clr, f32 width )
227 {
228 f32 vx,vy, f ;
229
230 vx = x2 - x1 ;
231 vy = y2 - y1 ;
232 f = sqrtf( vx*vx + vy*vy ) ;
233 if ( f == 0.0f ) {
234 vx = vy = 0.0f ;
235 } else {
236 f = width * 2.0f / f ;
237 vx *= f ;
238 vy *= f ;
239 }
240 draw_dashed_line( x1,y1, x2,y2, clr, width ) ;
241 draw_line( x2,y2, x2-vx-vx-vy,y2-vy-vy+vx, clr, width ) ;
242 draw_line( x2,y2, x2-vx-vx+vy,y2-vy-vy-vx, clr, width ) ;
243 }
244
245
246 /*******************************************************************************
247 Render a circle
248 *******************************************************************************/
draw_circle(f32 ox,f32 oy,f32 radius,GXColor clr,f32 width)249 void draw_circle( f32 ox, f32 oy, f32 radius, GXColor clr, f32 width )
250 {
251 s32 vtxs = 40 ; // Number of vertices
252 f32 k = 6.29f / (f32)vtxs ; // 2�� �� number of sections
253 s32 n ;
254 f32 f, vx,vy ;
255
256 if ( radius < width * 0.1f ) {
257 //----- Radii that are too small are processed as points
258 draw_point( ox,oy, clr, width ) ;
259 return ;
260 }
261
262 GXSetTevColor( GX_TEVREG0, clr ) ;
263 GXSetLineWidth( (u8)(s32)(width * 6.0f + 0.5f), GX_TO_ZERO ) ;
264
265 GXBegin( GX_LINESTRIP, GX_VTXFMT0, (u16)(vtxs + 1) ) ;
266
267 vx = radius ;
268 vy = 0.0f ;
269 n = vtxs ;
270 do {
271 GXPosition2f32( ox + vx, oy + vy ) ;
272
273 //----- Proceed in the direction of angular velocity
274 f = vx ;
275 vx -= vy * k ;
276 vy += f * k ;
277
278 //----- Correct the radius
279 f = radius / sqrtf( vx * vx + vy * vy ) ;
280 vx *= f ;
281 vy *= f ;
282 } while ( --n != 0 ) ;
283
284 GXPosition2f32( ox + radius, oy ) ; // The last point is the same as the start point
285 GXEnd() ;
286 }
287
288