1 /*---------------------------------------------------------------------------*
2   Project:  simple color test
3   File:     color.c
4 
5   Copyright 1998, 1999 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: color.c,v $
14   Revision 1.2  02/20/2006 04:13:13  mitu
15   changed include path from dolphin/ to revolution/.
16 
17   Revision 1.1  12/16/2005 08:34:26  urata
18   Initial check-in.
19 
20 
21     9     3/01/00 5:41p Hashida
22     Moved NTSC definition from makefile to .c's
23 
24     8     2/18/00 10:46a Hashida
25     Changed the code suitable for demos.
26 
27     7     1/28/00 10:37p Hashida
28     Added VIFlush.
29     Changed to wait for two frames when switching mode.
30 
31     6     1/26/00 3:56p Hashida
32     Changed to use VIConfigure.
33 
34     5     1/21/00 2:15a Hashida
35     Make it work for non-interlace mode
36 
37     4     1/12/00 6:56p Hashida
38     VI_DEBUG is not allowed as an argument for VIConfigureTVScreen
39     (the API decides whether or not debug mode should be used).
40 
41     3     1/11/00 11:06a Hashida
42     It doesn't work temporarily so fixed.
43 
44     2     12/24/99 11:12a Hashida
45     Fixed initial values.
46 
47     1     12/02/99 4:05p Hashida
48     Initial revision
49 
50     2     11/30/99 7:01p Hashida
51     Added a new test for single field frame buffer.
52 
53     2     11/17/99 3:31p Hashida
54     Removed DS mode test when Marlin since Marlin doesn't support DS mode
55     for now.
56 
57 
58     1     11/12/99 5:24p Hashida
59     Initial revision.
60 
61   $NoKeywords: $
62  *---------------------------------------------------------------------------*/
63 
64 #include <revolution.h>
65 
66 #define NTSC      // if you change here, you can see PAL or M/PAL
67 /* #define NON_INTERLACE */   // if you define this, you can see non-interlace
68 
69 #if defined(NTSC)
70 #ifndef NON_INTERLACE
71 GXRenderModeObj* rmode = &GXNtsc480Int;
72 #else
73 GXRenderModeObj* rmode = &GXNtsc240Ds;
74 #endif
75 
76 #elif defined(PAL)
77 
78 #ifndef NON_INTERLACE
79 GXRenderModeObj* rmode = &GXPal528Int;
80 #else
81 GXRenderModeObj* rmode = &GXPal264Ds;
82 #endif
83 
84 #else
85 
86 #ifndef NON_INTERLACE
87 GXRenderModeObj* rmode = &GXMpal480Int;
88 #else
89 GXRenderModeObj* rmode = &GXMpal240Ds;
90 #endif
91 
92 #endif
93 
94 // for X frame buffer
95 static u8*  xfb1;
96 static u8*  xfb2;
97 
98 typedef struct
99 {
100     u32         Y;
101     u32         Cb;
102     u32         Cr;
103 
104 } Color_s;
105 
106 Color_s color[] = {
107     { 180, 128, 128 },
108     { 162,  44, 142 },
109     { 131, 156,  44 },
110     { 112,  72,  58 },
111     {  84, 184, 198 },
112     {  65, 100, 212 },
113     {  35, 212, 114 },
114     {  16, 128, 128 },
115 };
116 
117 void allocateFB(u32 fbSize);
118 void fillColor(u32 code, u32 fbSize, u8* xfb);
119 
120 /*---------------------------------------------------------------------------*
121     Name:               allocateFB
122 
123     Description:        Allocates memory for two frame buffers
124 
125     Arguments:          fbSize      frame buffer size
126 
127     Returns:            none
128  *---------------------------------------------------------------------------*/
allocateFB(u32 fbSize)129 void allocateFB(u32 fbSize)
130 {
131     void*       arenaLo;
132 
133     arenaLo = OSGetArenaLo();
134 
135     // allocate memory for frame buffer here.
136     xfb1 = (u8*)OSRoundUp32B(arenaLo);
137     xfb2 = (u8*)OSRoundUp32B(xfb1 + fbSize);
138 
139     arenaLo = (void*)(xfb1 + 2 * fbSize);
140     OSSetArenaLo(arenaLo);
141 }
142 
143 /*---------------------------------------------------------------------------*
144     Name:               fillColor
145 
146     Description:        fill frame buffer by a single color
147 
148     Arguments:          code        color code
149                         fbSize      size of the frame buffer
150                         xfb         frame buffer address
151 
152     Returns:            none
153  *---------------------------------------------------------------------------*/
fillColor(u32 code,u32 fbSize,u8 * xfb)154 void fillColor(u32 code, u32 fbSize, u8* xfb)
155 {
156     u32         colorVal;
157     u8*         ptr;
158 
159     colorVal = (color[code].Y << 24)
160         + (color[code].Cb << 16)
161         + (color[code].Y << 8)
162         + color[code].Cr;
163 
164     for (ptr = xfb; ptr < xfb + fbSize; ptr += VI_DISPLAY_PIX_SZ * 2)
165         *(u32*)ptr = colorVal;
166 
167     DCStoreRange((void*)xfb, fbSize);
168 }
169 
main(void)170 void main(void)
171 {
172     u32         frame;
173     u32         code;
174     u32         fbSize;
175     u8*         xfb;
176     u32         first;
177 
178     OSInit();
179     VIInit();
180 
181     // Calculate frame buffer size.
182     // Note that each line width should be a multiple of 16.
183     fbSize = (u32)(VIPadFrameBufferWidth(rmode->fbWidth)
184         * rmode->xfbHeight * VI_DISPLAY_PIX_SZ);
185 
186     allocateFB(fbSize);
187 
188     VIConfigure(rmode);
189 
190     // Need to "flush" so that the VI changes so far takes effect
191     // from the following field
192     VIFlush();
193     VIWaitForRetrace();
194 
195     // Since the tv mode is interlace after VIInit,
196     // we need to wait for one more frame to make sure
197     // that the mode is switched from interlace to non-interlace
198 #ifdef NON_INTERLACE
199     VIWaitForRetrace();
200 #endif
201 
202     first = 1;
203     frame = 0;
204     code = 0;
205 
206     while(1)
207     {
208         xfb = (frame & 0x1)? xfb2 : xfb1;
209 
210         if (frame % 60 == 0)
211         {
212             code = (code + 1) % 8;
213         }
214 
215         fillColor(code, fbSize, xfb);
216 
217         VISetNextFrameBuffer((void*)xfb);
218 
219         if (first == 1)
220         {
221             VISetBlack(FALSE);
222             first = 0;
223         }
224 
225         VIFlush();
226         VIWaitForRetrace();
227 
228         frame++;
229     }
230 }
231