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