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