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