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