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