1 /*---------------------------------------------------------------------------*
2 Project: single field frame buffer demo
3 File: moving.c
4
5 Copyright 2000 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: moving.c,v $
14 Revision 1.3 2008/06/26 02:51:26 urata
15 Removed MPAL defines
16
17 Revision 1.2 2006/02/20 04:13:13 mitu
18 Changed include path from dolphin/ to revolution/.
19
20 Revision 1.1 2005/12/16 08:34:25 urata
21 Initial check-in.
22
23
24 2 2000/03/01 5:41p Hashida
25 Moved NTSC definition from makefile to .c's
26
27 1 2000/02/18 10:39a Hashida
28 initial check-in
29
30 $NoKeywords: $
31 *---------------------------------------------------------------------------*/
32
33 #include <revolution.h>
34
35 #define NTSC // if you change here, you can see PAL
36 /* #define NON_INTERLACE */ // if you define this, you can see non-interlace
37
38 #define FLOOR(x, a) ( (x < a)? a : x )
39 #define CEIL(x, b) ( (x > b)? b : x )
40 #define CLAMP(x, a, b) (CEIL(FLOOR(x, a), b))
41
42 #if defined(NTSC)
43
44 GXRenderModeObj* rmode = &GXNtsc240Int;
45
46 #elif defined(PAL)
47
48 GXRenderModeObj* rmode = &GXPal264Int;
49
50 #endif
51
52 // for X frame buffer
53 static u8* xfbA;
54 static u8* xfbB;
55
56 typedef struct
57 {
58 u32 Y;
59 u32 Cb;
60 u32 Cr;
61
62 } Color_s;
63
64 Color_s color[] = {
65 { 180, 128, 128 },
66 { 162, 44, 142 },
67 { 131, 156, 44 },
68 { 112, 72, 58 },
69 { 84, 184, 198 },
70 { 65, 100, 212 },
71 { 35, 212, 114 },
72 { 16, 128, 128 },
73 };
74
75 void allocateFB(u32 fbSize);
76 void draw(u32 field, u32 code, u32 fbSize, u8* xfb);
77
78 /*---------------------------------------------------------------------------*
79 Name: allocateFB
80
81 Description: Allocates memory for two frame buffers
82
83 Arguments: fbSize each frame buffer size
84
85 Returns: None.
86 *---------------------------------------------------------------------------*/
allocateFB(u32 fbSize)87 void allocateFB(u32 fbSize)
88 {
89 void* arenaLo;
90
91 arenaLo = OSGetArenaLo();
92
93 // allocate memory for frame buffer here.
94 xfbA = (u8*)OSRoundUp32B(arenaLo);
95 xfbB = (u8*)OSRoundUp32B(xfbA + fbSize);
96
97 arenaLo = (void*)(xfbA + 2 * fbSize);
98 OSSetArenaLo(arenaLo);
99 }
100
101 /*---------------------------------------------------------------------------*
102 Name: Draw
103
104 Description: draw screen
105
106 Arguments: field above field(0) or below(1)
107 count frame count
108 fbSize size of the frame buffer
109 xfb frame buffer address
110
111 Returns: None.
112 *---------------------------------------------------------------------------*/
draw(u32 field,u32 count,u32 fbSize,u8 * xfb)113 void draw(u32 field, u32 count, u32 fbSize, u8* xfb)
114 {
115 u32 i, j;
116 u32 colorVal;
117 u32 cb, cr;
118 u32 y;
119 u8* ptr;
120
121 ptr = xfb;
122
123 // if field == above(0), we draw 0, 2, 4, ... 2n lines.
124 // if field == below(1), we draw 1, 3, 5, ... (2n-1) lines.
125 for (j = field; j < rmode->viHeight; j += 2)
126 {
127 for (i = 0; i < rmode->fbWidth; i += 2)
128 {
129 // clamping is needed because Cb and Cr should be
130 // in range [16, 240].
131 y = 128;
132 cb = CLAMP( (i + count*2) % 256, 16, 240);
133 cr = CLAMP( (j + count) % 256, 16, 240);
134
135 colorVal = (y << 24)
136 + (cb << 16)
137 + (y << 8)
138 + cr;
139
140 *(u32*)ptr = colorVal;
141
142 // We handle two pixels at a time.
143 ptr += VI_DISPLAY_PIX_SZ * 2;
144 }
145 }
146
147 DCStoreRange((void*)xfb, fbSize);
148 }
149
main(void)150 void main(void)
151 {
152 u32 frame;
153 u32 fbSize;
154 u8* xfb;
155 u32 first;
156
157 OSInit();
158 VIInit();
159
160 // Calculate frame buffer size.
161 // Note that each line width should be a multiple of 16.
162 fbSize = (u32)(VIPadFrameBufferWidth(rmode->fbWidth)
163 * rmode->xfbHeight * VI_DISPLAY_PIX_SZ);
164
165 allocateFB(fbSize);
166
167 VIConfigure(rmode);
168
169 // Need to "flush" so that the VI changes so far takes effect
170 // from the following field
171 VIFlush();
172 VIWaitForRetrace();
173
174 // Since the TV mode is interlace after VIInit,
175 // we need to wait for one more frame to make sure
176 // that the mode is switched from interlace to non-interlace
177 #ifdef NON_INTERLACE
178 VIWaitForRetrace();
179 #endif
180
181 first = 1;
182 frame = 0;
183
184 while(1)
185 {
186 xfb = (frame & 0x1)? xfbB : xfbA;
187
188 draw(VIGetNextField(), frame, fbSize, xfb);
189 VISetNextFrameBuffer( (void*)xfb );
190
191 if (first == 1)
192 {
193 VISetBlack(FALSE);
194 first = 0;
195 }
196
197 VIFlush();
198 VIWaitForRetrace();
199
200 frame++;
201 }
202 }
203