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