1 /*---------------------------------------------------------------------------*
2 Project: WD demo
3 File: sample.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: sample.c,v $
14 Revision 1.8 2008/06/02 02:24:15 seiki_masashi
15 Added support for KPADRead specification changes.
16
17 Revision 1.7 2008/05/30 02:27:03 seiki_masashi
18 Reverted code consequent upon reverted SDK code.
19
20 Revision 1.5 2006/08/15 03:51:15 yasu
21 Support for PADDING warnings.
22
23 Revision 1.4 2006/07/18 09:25:25 terui
24 Fixed appearance
25
26 Revision 1.3 2006/07/13 13:55:09 terui
27 Adjusted the size of the heap for PAD.
28
29 Revision 1.2 2006/07/13 12:38:32 terui
30 Fixed appearance
31
32 Revision 1.1 2006/07/13 12:16:23 terui
33 Initial upload
34
35 $NoKeywords: $
36 *---------------------------------------------------------------------------*/
37
38 #include <revolution.h>
39 #include <revolution/kpad.h>
40 #include <revolution/mem.h>
41 #include "sample.h"
42 #include <string.h>
43 #include <stdarg.h>
44 #include <stdio.h>
45
46 /*---------------------------------------------------------------------------*
47 Constant Definitions
48 *---------------------------------------------------------------------------*/
49 #define SAMPLE_FIFO_SIZE ( 256 * 1024 )
50 #define SAMPLE_XFB_COUNT ( 2 )
51 #define SAMPLE_PADHEAP_SIZE ( 128 * 1024 )
52
53 #define SAMPLE_RAW_COUNT ( 33 + 1 )
54 #define SAMPLE_COL_COUNT ( 88 )
55
56 /*---------------------------------------------------------------------------*
57 Structure Definitions
58 *---------------------------------------------------------------------------*/
59 typedef struct SAMPLECamera
60 {
61 Vec pos;
62 Vec up;
63 Vec target;
64 f32 fovy;
65 f32 aspect;
66 f32 znear;
67 f32 zfar;
68
69 } SAMPLECamera;
70
71 /*---------------------------------------------------------------------------*
72 Internal Variable Definitions
73 *---------------------------------------------------------------------------*/
74 static s32 sampleFrameCount = 0;
75 static s32 sampleFrameCycle;
76 static GXRenderModeObj sampleRend;
77 static u8 sampleFifoBuf[ SAMPLE_FIFO_SIZE ] ATTRIBUTE_ALIGN( 32 );
78 static void* sampleXFB[ SAMPLE_XFB_COUNT ];
79 static MEMHeapHandle samplePadHeap;
80
81 static u8 sampleFontBuf[ OSRoundUp32B( OS_FONT_SIZE_ANSI + OS_FONT_SIZE_SJIS ) ] ATTRIBUTE_ALIGN( 32 );
82 static OSFontHeader* sampleFont = (OSFontHeader*)( &( sampleFontBuf[ 0 ] ) );
83 static char sampleString[ SAMPLE_RAW_COUNT ][ 256 ];
84 static s32 sampleRawIndex;
85 static s32 sampleNextRawIndex;
86 static s32 sampleNextColIndex;
87 static SAMPLECamera sampleCamera;
88 static GXLightObj sampleLight;
89
90 /*---------------------------------------------------------------------------*
91 Internal Function Prototype
92 *---------------------------------------------------------------------------*/
93 static void InitString( void );
94 static void RenderString( void );
95 static void* AllocFromPadHeap( u32 size );
96 static u8 FreeToPadHeap( void* ptr );
97
98 /*---------------------------------------------------------------------------*
99 Name : SampleInit
100 Description : Performs initialization required for on-screen display.
101 Arguments : None.
102 Returns : None.
103 *---------------------------------------------------------------------------*/
104 void
SampleInit(void)105 SampleInit( void )
106 {
107 /* Initialize VI */
108 {
109 const GXRenderModeObj* viConf = &GXNtsc480IntDf;
110
111 VIInit();
112 (void)memcpy( &sampleRend, viConf, sizeof( GXRenderModeObj ) );
113 GXAdjustForOverscan( &sampleRend, &sampleRend, 0, 16 );
114 sampleFrameCycle = ( ( ( sampleRend.viTVmode >> 2 ) == VI_PAL ) ? 50 : 60 );
115 VIConfigure( &sampleRend );
116 }
117
118 /* Allocate eXternal frame buffer */
119 {
120 void* arena_s;
121 u32 xfbSize;
122 s32 i;
123
124 arena_s = OSGetMEM1ArenaLo();
125 xfbSize = (u32)( VIPadFrameBufferWidth( sampleRend.fbWidth ) * sampleRend.xfbHeight * VI_DISPLAY_PIX_SZ );
126 for( i = 0; i < SAMPLE_XFB_COUNT; i ++ )
127 {
128 sampleXFB[ i ] = (void*)OSRoundUp32B( (u32)arena_s );
129 arena_s = (void*)OSRoundUp32B( (u32)( sampleXFB[ i ] ) + xfbSize );
130 }
131 OSSetMEM1ArenaLo( arena_s );
132 }
133
134 /* Initialize heap for WPAD sampling */
135 {
136 void* heapAddress;
137
138 heapAddress = OSGetMEM2ArenaLo();
139 OSSetMEM2ArenaLo( (void*)OSRoundUp32B( (u32)heapAddress + SAMPLE_PADHEAP_SIZE ) );
140 samplePadHeap = MEMCreateExpHeap( heapAddress, SAMPLE_PADHEAP_SIZE );
141 if( samplePadHeap == NULL )
142 {
143 OSHalt( "Could not create heap.\n" );
144 }
145 WPADRegisterAllocator( AllocFromPadHeap, FreeToPadHeap );
146 }
147
148 /* Initialize controllers */
149 {
150 KPADStatus status;
151
152 KPADInit();
153 while( KPADRead( WPAD_CHAN0, &status, 1 ) > 0 ) {}
154 while( KPADRead( WPAD_CHAN1, &status, 1 ) > 0 ) {}
155 while( KPADRead( WPAD_CHAN2, &status, 1 ) > 0 ) {}
156 while( KPADRead( WPAD_CHAN3, &status, 1 ) > 0 ) {}
157 }
158
159 /* Initialize GX */
160 {
161 GXFifoObj* gxFifo;
162 f32 yScale;
163 u16 xfbHeight;
164
165 gxFifo = GXInit( sampleFifoBuf, SAMPLE_FIFO_SIZE );
166 GXSetViewport( 0.0F, 0.0F, (f32)sampleRend.fbWidth, (f32)sampleRend.efbHeight, 0.0F, 1.0F );
167 GXSetScissor( 0, 0, (u32)sampleRend.fbWidth, (u32)sampleRend.efbHeight );
168 yScale = GXGetYScaleFactor( sampleRend.efbHeight, sampleRend.xfbHeight );
169 xfbHeight = (u16)GXSetDispCopyYScale( yScale );
170 GXSetDispCopySrc( 0, 0, sampleRend.fbWidth, sampleRend.efbHeight );
171 GXSetDispCopyDst( sampleRend.fbWidth, xfbHeight );
172 GXSetCopyFilter( sampleRend.aa, sampleRend.sample_pattern, GX_TRUE, sampleRend.vfilter );
173 GXSetDispCopyGamma( GX_GM_1_0 );
174 if( sampleRend.aa )
175 {
176 GXSetPixelFmt( GX_PF_RGB565_Z16, GX_ZC_LINEAR );
177 }
178 else
179 {
180 GXSetPixelFmt( GX_PF_RGB8_Z24, GX_ZC_LINEAR );
181 }
182 GXCopyDisp( sampleXFB[ 0 ], GX_TRUE );
183 }
184
185 InitString();
186
187 /* Wait for first frame */
188 {
189 VISetNextFrameBuffer( sampleXFB[ 0 ] );
190 VISetBlack( FALSE );
191 VIFlush();
192 VIWaitForRetrace();
193 if( (u32)( sampleRend.viTVmode ) & 0x1 )
194 {
195 VIWaitForRetrace();
196 }
197 }
198 }
199
200 /*---------------------------------------------------------------------------*
201 Name : SampleWaitRetrace
202 Description : Wait until V-Blank interrupt is generated.
203 Arguments : None.
204 Returns : None.
205 *---------------------------------------------------------------------------*/
206 void
SampleWaitRetrace(void)207 SampleWaitRetrace( void )
208 {
209 RenderString();
210 GXCopyDisp( sampleXFB[ sampleFrameCount % SAMPLE_XFB_COUNT ], GX_TRUE );
211 VISetNextFrameBuffer( sampleXFB[ sampleFrameCount % SAMPLE_XFB_COUNT ] );
212 VIFlush();
213 VIWaitForRetrace();
214 sampleFrameCount ++;
215 }
216
217 /*---------------------------------------------------------------------------*
218 Name : SampleReport
219 Description : Performs debug display of text.
220 Arguments : msg - The character string to be displayed
221 ... - Virtual argument.
222 Returns : None.
223 *---------------------------------------------------------------------------*/
224 void
SampleReport(const char * msg,...)225 SampleReport( const char* msg, ... )
226 {
227 va_list vl;
228 char temp[ 256 ];
229 s32 i;
230 char* p;
231
232 (void)memset( temp, 0, sizeof( temp ) );
233 va_start( vl, msg );
234 (void)vsprintf( temp, msg, vl );
235 va_end( vl );
236
237 OSReport( temp );
238 p = &temp[ 0 ];
239 for( i = 0; i < 256; i ++ )
240 {
241 if( *p == 0x00 )
242 {
243 sampleString[ sampleNextRawIndex % SAMPLE_RAW_COUNT ][ sampleNextColIndex ] = 0x00;
244 break;
245 }
246 if( *p == 0x0d )
247 {
248 p ++;
249 continue;
250 }
251 if( *p == 0x0a )
252 {
253 sampleString[ sampleNextRawIndex % SAMPLE_RAW_COUNT ][ sampleNextColIndex ] = 0x00;
254 sampleNextColIndex = 0;
255 sampleNextRawIndex ++;
256 if( sampleNextRawIndex >= SAMPLE_RAW_COUNT )
257 {
258 sampleRawIndex = ( sampleRawIndex + 1 ) % SAMPLE_RAW_COUNT;
259 }
260 p ++;
261 continue;
262 }
263 sampleString[ sampleNextRawIndex % SAMPLE_RAW_COUNT ][ sampleNextColIndex ] = *p;
264 if( ( ++ sampleNextColIndex ) > 255 )
265 {
266 sampleNextColIndex = 0;
267 sampleNextRawIndex ++;
268 if( sampleNextRawIndex >= SAMPLE_RAW_COUNT )
269 {
270 sampleRawIndex = ( sampleRawIndex + 1 ) % SAMPLE_RAW_COUNT;
271 }
272 }
273 p ++;
274 }
275 }
276
277 /*---------------------------------------------------------------------------*
278 Name : AllocFromPadHeap
279 Description : Dynamically allocates memory for the WPAD library.
280 Arguments : size - Specifies the size of memory to be allocated.
281 Returns : void* - Returns the starting address of the allocated memory.
282 *---------------------------------------------------------------------------*/
283 static void*
AllocFromPadHeap(u32 size)284 AllocFromPadHeap( u32 size )
285 {
286 return MEMAllocFromExpHeap( samplePadHeap, size );
287 }
288
289 /*---------------------------------------------------------------------------*
290 Name : FreeToPadHeap
291 Description : Deallocates memory dynamically allocated for the WPAD library.
292 Arguments : ptr - Specifies the start address of the memory to be deallocated.
293 Returns : u8 - Returns 0 if attempt to deallocate memory fails.
294 *---------------------------------------------------------------------------*/
295 static u8
FreeToPadHeap(void * ptr)296 FreeToPadHeap( void* ptr )
297 {
298 if( ptr == NULL )
299 {
300 return 0;
301 }
302 MEMFreeToExpHeap( samplePadHeap, ptr );
303 return 1;
304 }
305
306 /*---------------------------------------------------------------------------*
307 Name : InitString
308 Description : Performs initialization necessary to display strings for debugging.
309 Arguments : None.
310 Returns : None.
311 *---------------------------------------------------------------------------*/
312 static void
InitString(void)313 InitString( void )
314 {
315 /* Initialize the string buffer */
316 (void)memset( sampleString, 0, sizeof( sampleString ) );
317 sampleRawIndex = 0;
318 sampleNextRawIndex = 0;
319 sampleNextColIndex = 0;
320
321 /* Load font data */
322 (void)OSInitFont( sampleFont );
323
324 /* Initialize camera */
325 {
326 sampleCamera.fovy = 33.3f;
327 sampleCamera.aspect = (f32)( 10.0f / 7.0f );
328 sampleCamera.znear = 0.001f;
329 sampleCamera.zfar = 1023.999f;
330 sampleCamera.pos.x = 0.0f;
331 sampleCamera.pos.y = 0.0f;
332 sampleCamera.pos.z = -20.0f;
333 sampleCamera.up.x = 0.0f;
334 sampleCamera.up.y = 1.0f;
335 sampleCamera.up.z = 0.0f;
336 sampleCamera.target.x = 0.0f;
337 sampleCamera.target.y = 0.0f;
338 sampleCamera.target.z = 0.0f;
339 }
340
341 /* Initialize light */
342 {
343 const Vec lpos = { 0.0f, 0.0f, 0.0f };
344 const Vec ldir = { 0.0f, 0.0f, -1.0f };
345 const GXColor lcol = { 0xff, 0xff, 0xff, 0xff };
346
347 GXInitLightPosv( &sampleLight, &lpos );
348 GXInitLightDirv( &sampleLight, &ldir );
349 GXInitLightColor( &sampleLight, lcol );
350 GXInitLightSpot( &sampleLight, 0.03f, GX_SP_COS );
351 GXInitLightDistAttn( &sampleLight, 3.0f, 0.5f, GX_DA_GENTLE );
352 }
353 }
354
355 /*---------------------------------------------------------------------------*
356 Name : RenderString
357 Description : Performs the rendering required for each picture frame in order to perform debug display of text string.
358
359 Arguments : None.
360 Returns : None.
361 *---------------------------------------------------------------------------*/
362 static void
RenderString(void)363 RenderString( void )
364 {
365 f32 scrWidth = (f32)( sampleRend.fbWidth );
366 f32 scrHeight = (f32)( sampleRend.efbHeight );
367
368 const GXColor ambientCol = { 0xff, 0xff, 0xff, 0xff };
369 const GXColor strCol = { 0x00, 0x00, 0x00, 0xff };
370 const GXColor backCol = { 0xff, 0xff, 0xff, 0xff };
371
372 /* rendering preparation */
373 {
374 Mtx44 projMtx;
375 Mtx posMtx;
376
377 GXInvalidateTexAll();
378 /* Viewport settings */
379 if( (u32)( sampleRend.viTVmode ) & 0x1 )
380 {
381 GXSetViewportJitter( 0.0f, 0.0f, (f32)( sampleRend.fbWidth ), (f32)( sampleRend.efbHeight ), 0.0f, 1.0f, VIGetNextField() );
382 }
383 else
384 {
385 GXSetViewport( 0.0f, 0.0f, (f32)( sampleRend.fbWidth ), (f32)( sampleRend.efbHeight ), 0.0f, 1.0f );
386 }
387 GXSetScissor( 0, 0, (u32)( sampleRend.fbWidth ), (u32)( sampleRend.efbHeight ) );
388 /* camera settings */
389 MTXOrtho( projMtx, 0.0f, scrHeight, 0.0f, scrWidth, sampleCamera.znear, sampleCamera.zfar );
390 GXSetProjection( projMtx, GX_ORTHOGRAPHIC );
391 MTXIdentity( posMtx );
392 GXLoadPosMtxImm( posMtx, GX_PNMTX0 );
393 GXSetCurrentMtx( GX_PNMTX0 );
394 GXSetZMode( GX_TRUE, GX_LEQUAL, GX_TRUE );
395 GXSetBlendMode( GX_BM_BLEND, GX_BL_SRCALPHA, GX_BL_INVSRCALPHA, GX_LO_CLEAR );
396 /* light settings */
397 GXSetNumChans( 1 );
398 GXSetChanAmbColor( GX_COLOR0A0, ambientCol );
399 GXLoadLightObjImm( &sampleLight, GX_LIGHT0 );
400 GXSetChanCtrl( GX_COLOR0, GX_ENABLE, GX_SRC_REG, GX_SRC_REG, GX_LIGHT0, GX_DF_NONE, GX_AF_NONE );
401 GXSetChanCtrl( GX_ALPHA0, GX_DISABLE, GX_SRC_REG, GX_SRC_REG, GX_LIGHT0, GX_DF_NONE, GX_AF_NONE );
402 }
403
404 /* Render background */
405 {
406 s16 z = -1023;
407
408 /* Set vertex */
409 GXClearVtxDesc();
410 GXSetVtxDesc( GX_VA_POS, GX_DIRECT );
411 GXSetVtxAttrFmt( GX_VTXFMT1, GX_VA_POS, GX_POS_XYZ, GX_S16, 0 );
412 /* Texture settings */
413 GXSetNumTexGens( 0 );
414 GXSetNumTevStages( 1 );
415 GXSetTevOp( GX_TEVSTAGE0, GX_PASSCLR );
416 GXSetTevOrder( GX_TEVSTAGE0, GX_TEXCOORD0, GX_TEXMAP0, GX_COLOR0A0 );
417 /* Render square polygon */
418 GXSetChanMatColor( GX_COLOR0A0, backCol );
419 GXBegin( GX_QUADS, GX_VTXFMT1, 4 );
420 GXPosition3s16( 0, 0, z );
421 GXPosition3s16( (s16)scrWidth, 0, z );
422 GXPosition3s16( (s16)scrWidth, (s16)scrHeight, z );
423 GXPosition3s16( 0, (s16)scrHeight, z );
424 GXEnd();
425 }
426
427 /* Render character string */
428 {
429 s32 fx, fy, fw;
430 void* image;
431 char* ptr;
432 s32 i, j;
433 GXTexObj tobj;
434 s16 x, y, z, w, h;
435 Mtx scaleMtx;
436
437 /* Set vertex */
438 GXClearVtxDesc();
439 GXSetVtxDesc( GX_VA_POS, GX_DIRECT );
440 GXSetVtxDesc( GX_VA_TEX0, GX_DIRECT );
441 GXSetVtxAttrFmt( GX_VTXFMT0, GX_VA_POS, GX_POS_XYZ, GX_S16, 0 );
442 GXSetVtxAttrFmt( GX_VTXFMT0, GX_VA_TEX0, GX_TEX_ST, GX_S16, 0 );
443 /* Texture settings */
444 GXSetNumTexGens( 1 );
445 MTXScale( scaleMtx, ( 1.0f / sampleFont->sheetWidth ), ( 1.0f / sampleFont->sheetHeight ), 1.0f );
446 GXLoadTexMtxImm( scaleMtx, GX_TEXMTX0, GX_MTX2x4 );
447 GXSetTexCoordGen( GX_TEXCOORD0, GX_TG_MTX2x4, GX_TG_TEX0, GX_TEXMTX0 );
448 GXSetNumTevStages( 1 );
449 GXSetTevOp( GX_TEVSTAGE0, GX_MODULATE );
450 GXSetTevOrder( GX_TEVSTAGE0, GX_TEXCOORD0, GX_TEXMAP0, GX_COLOR0A0 );
451
452 /* Render the string buffer */
453 GXSetChanMatColor( GX_COLOR0A0, strCol );
454 for( i = 0; i < ( SAMPLE_RAW_COUNT - 1 ); i ++ )
455 {
456 x = 2;
457 y = (s16)( ( scrHeight * i ) / ( SAMPLE_RAW_COUNT - 1 ) );
458 z = -1;
459 h = (s16)( scrHeight / ( SAMPLE_RAW_COUNT - 1 ) );
460
461 ptr = &( sampleString[ ( sampleRawIndex + i ) % SAMPLE_RAW_COUNT ][ 0 ] );
462 for( j = 0; j < 256; j ++ )
463 {
464 if( ( *ptr == 0x00 ) || ( *ptr == 0x0d ) || ( *ptr == 0x0a ) )
465 {
466 break;
467 }
468 ptr = OSGetFontTexture( ptr, &image, &fx, &fy, &fw );
469 w = (s16)( ( fw * scrWidth ) / ( 12 * SAMPLE_COL_COUNT ) );
470 GXInitTexObj( &tobj, image, sampleFont->sheetWidth, sampleFont->sheetHeight, GX_TF_I4, GX_REPEAT, GX_REPEAT, GX_FALSE );
471 GXLoadTexObj( &tobj, GX_TEXMAP0 );
472 GXBegin( GX_QUADS, GX_VTXFMT0, 4 );
473 GXPosition3s16( (s16)( x + 0 ), (s16)( y + 0 ), z );
474 GXTexCoord2s16( (s16)( fx + 0 ), (s16)( fy + 0 ) );
475 GXPosition3s16( (s16)( x + w ), (s16)( y + 0 ), z );
476 GXTexCoord2s16( (s16)( fx + fw ), (s16)( fy + 0 ) );
477 GXPosition3s16( (s16)( x + w ), (s16)( y + h ), z );
478 GXTexCoord2s16( (s16)( fx + fw ), (s16)( fy + 24 ) );
479 GXPosition3s16( (s16)( x + 0 ), (s16)( y + h ), z );
480 GXTexCoord2s16( (s16)( fx + 0 ), (s16)( fy + 24 ) );
481 GXEnd();
482 x += w;
483 if( x >= scrWidth )
484 {
485 break;
486 }
487 }
488 }
489 }
490 }
491
492 /*---------------------------------------------------------------------------*
493 End of file
494 *---------------------------------------------------------------------------*/
495