1 /*---------------------------------------------------------------------------*
2 Project: VI trap filter demo
3 File: cross-color.c
4
5 Copyright 2006 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: cross-color.c,v $
14 Revision 1.2 2008/06/26 02:52:51 urata
15 Removed MPAL defines
16
17 Revision 1.1 2006/07/22 04:56:27 urata
18 Initial check-in.
19
20 $NoKeywords: $
21 *---------------------------------------------------------------------------*/
22
23 #include <revolution.h>
24
25 #define NTSC // if you change here, you can see PAL
26
27
28 #if defined(NTSC)
29 GXRenderModeObj* rmode = &GXNtsc480Int;
30 #elif defined(PAL)
31 GXRenderModeObj* rmode = &GXPal528Int;
32 #elif defined(EURGB60)
33 GXRenderModeObj* rmode = &GXEurgb60Hz480Int;
34 #endif
35
36
37 // for X frame buffer
38 static u8* xfbA;
39 static u8* xfbB;
40
41 /*---------------------------------------------------------------------------*
42 Name: allocateFB
43
44 Description: Allocates memory for two frame buffers
45
46 Arguments: fbSize each frame buffer size
47
48 Returns: None.
49 *---------------------------------------------------------------------------*/
allocateFB(u32 fbSize)50 static void allocateFB(u32 fbSize)
51 {
52 void* arenaLo;
53
54 arenaLo = OSGetArenaLo();
55
56 // allocate memory for frame buffer here.
57 xfbA = (u8*)OSRoundUp32B(arenaLo);
58 xfbB = (u8*)OSRoundUp32B(xfbA + fbSize);
59
60 arenaLo = (void*)(xfbA + 2 * fbSize);
61 OSSetArenaLo(arenaLo);
62 }
63
64
65
66 /*---------------------------------------------------------------------------*
67 Name: YuvPset
68
69 Description: Draws a point.
70
71 Arguments: posX X coordinate
72 posY Y coordinate
73 width Stride of xfb
74 xfb Frame buffer address
75 luma Luma of point color
76 u,v Chroma of point color
77
78 Returns: None.
79 *---------------------------------------------------------------------------*/
YuvPset(s32 posX,s32 posY,s32 width,u32 * xfb,u8 luma,u8 u,u8 v)80 static void YuvPset(s32 posX, s32 posY, s32 width, u32 *xfb, u8 luma, u8 u, u8 v)
81 {
82 u32 *ptr;
83 u32 y1, y2;
84
85 ptr = xfb + (posX>>1) + (width/2) * posY;
86
87 if (posX & 1)
88 {
89 y1 = (((*ptr) >> 24) & 0xFF ) ;
90 y2 = luma;
91 }
92 else
93 {
94 y1 = luma;
95 y2 = (((*ptr) >> 8) & 0xFF ) ;
96 }
97 *ptr = ((y1<<24) | (u<<16) | (y2<<8) | v);
98 }
99
100 /*---------------------------------------------------------------------------*
101 Name: YuvCircle
102
103 Description: Draw circle
104
105 Arguments: posX Center of X coordinate
106 posY Center of Y coordinate
107 width Stride of xfb
108 r Radius
109 xfb Frame buffer address
110 luma Luma of point color
111 u,v Chroma of point color
112
113 Returns: None.
114 *---------------------------------------------------------------------------*/
YuvCircle(s32 posX,s32 posY,s32 width,s32 r,u32 * xfb,u8 luma,u8 u,u8 v)115 static void YuvCircle(s32 posX, s32 posY, s32 width, s32 r, u32 *xfb, u8 luma, u8 u, u8 v)
116 {
117 int x, y, f;
118
119 x = r;
120 y = 0;
121 f = -2 * r + 3;
122
123 while (x >= y) {
124 YuvPset(posX + x, posY + y, width, xfb, luma, u, v);
125 YuvPset(posX - x, posY + y, width, xfb, luma, u, v);
126 YuvPset(posX + x, posY - y, width, xfb, luma, u, v);
127 YuvPset(posX - x, posY - y, width, xfb, luma, u, v);
128 YuvPset(posX + y, posY + x, width, xfb, luma, u, v);
129 YuvPset(posX - y, posY + x, width, xfb, luma, u, v);
130 YuvPset(posX + y, posY - x, width, xfb, luma, u, v);
131 YuvPset(posX - y, posY - x, width, xfb, luma, u, v);
132 if (f >= 0) {
133 x --;
134 f -= x*4;
135 }
136 y++;
137 f += 4*y + 2;
138 }
139 }
140
141
142 /*---------------------------------------------------------------------------*
143 Name: DrawCircles
144
145 Description: Draw circles
146
147 Arguments: width Screen width
148 height Screen height
149 fbSize Size of the frame buffer
150 xfb Frame buffer address
151
152 Returns: None.
153 *---------------------------------------------------------------------------*/
DrawCircles(s32 width,s32 height,u32 fbSize,u8 * xfb)154 static void DrawCircles(s32 width, s32 height, u32 fbSize, u8* xfb)
155 {
156 s32 xoffset;
157 s32 yoffset;
158 s32 r;
159 u8 luma,u,v;
160
161 luma = 0xEB;
162 u = 0x80;
163 v = 0x80;
164 xoffset = width / 2;
165 yoffset = height / 2;
166
167
168 for(r=2; r<yoffset-3; r+=3)
169 {
170 YuvCircle(xoffset, yoffset, width, r, (u32 *)xfb, luma, u, v);
171 }
172 DCStoreRange((void*)xfb, fbSize);
173 }
174
175 /*---------------------------------------------------------------------------*
176 Name: DrawBlackScreen
177
178 Description: Draw black screen
179
180 Arguments: fbSize size of the frame buffer
181 xfb frame buffer address
182
183 Returns: None.
184 *---------------------------------------------------------------------------*/
DrawBlackScreen(u32 fbSize,u8 * xfb)185 static void DrawBlackScreen(u32 fbSize, u8 *xfb )
186 {
187 u16 *p = (u16 *)xfb;
188
189 while(fbSize--)
190 {
191 *p++ = 0x1080; // 2 byte
192 }
193 }
194
195 /*---------------------------------------------------------------------------*
196 Name: Main
197
198 Description: Main function
199
200 Arguments: None.
201
202 Returns: None.
203 *---------------------------------------------------------------------------*/
main(void)204 void main(void)
205 {
206 u32 frame;
207 u32 fbSize;
208 u8* xfb;
209 u32 first;
210 u32 mode;
211 PADStatus pstat[PAD_MAX_CONTROLLERS];
212 u32 plast=0;
213 VIBool trap_filter;
214
215 OSInit();
216 VIInit();
217 PADInit();
218
219 // Calculate frame buffer size.
220 // Note that each line width should be a multiple of 16.
221 fbSize = (u32)(VIPadFrameBufferWidth(rmode->fbWidth)
222 * rmode->xfbHeight * VI_DISPLAY_PIX_SZ);
223
224 allocateFB(fbSize);
225
226 VIConfigure(rmode);
227
228 // Need to "flush" so that the VI changes so far takes effect
229 // from the following field
230 VIFlush();
231 VIWaitForRetrace();
232
233
234 first = 1;
235 frame = 0;
236
237 mode=0; // flip mode; 0 = disable trap filter, 1 = enable trap filter
238 trap_filter=VI_DISABLE;
239 OSReport("Disable Trap filter.\n");
240
241 DrawBlackScreen(fbSize, xfbA);
242 DrawBlackScreen(fbSize, xfbB);
243
244 while(1)
245 {
246 PADRead(pstat);
247 if ((pstat[0].button & PAD_BUTTON_A) && !(plast & PAD_BUTTON_A))
248 {
249 mode = 1 - mode;
250 if (mode)
251 {
252 trap_filter = VI_ENABLE;
253 OSReport("Enable Trap filter.\n");
254 }
255 else
256 {
257 trap_filter = VI_DISABLE;
258 OSReport("Disable Trap filter.\n");
259 }
260 }
261
262 xfb = (frame & 0x1)? xfbB : xfbA;
263
264 DrawCircles( rmode->fbWidth, rmode->xfbHeight, fbSize, xfb);
265 VISetNextFrameBuffer((void*)xfb );
266
267 if (first == 1)
268 {
269 VISetBlack(FALSE);
270 first = 0;
271 }
272
273 VISetTrapFilter(trap_filter);
274
275 // Need to "flush" so that the VI changes so far takes effect
276 // from the following field
277 VIFlush();
278 VIWaitForRetrace();
279
280
281 plast = pstat[0].button;
282 frame++;
283 }
284 }
285