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