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