1 /*---------------------------------------------------------------------------*
2   Project:  networkmanual_tpl
3   File:     networkmanual_tpl.cpp
4 
5   Copyright 2008 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 
14 /* Use MEMHeap, which is inside DEMOInit */
15 #define DEMO_USE_MEMLIB
16 
17 /* Save confirmation on/off */
18 /* #define HBM_NO_SAVE */
19 /* Made to correspond to the WiiWare dialog messages */
20 #ifdef HBM_NO_SAVE
21 #define MESSAGE_FLAG	(HBMMSG_NOSAVE_WIIMENU | HBMMSG_NOSAVE_RESET)
22 #else
23 #define MESSAGE_FLAG	0
24 #endif
25 
26 #ifndef USE_FOR_NETWORKMANUAL
27 #define USE_FOR_NETWORKMANUAL
28 #endif
29 
30 #include <Revolution.h>
31 #include <revolution/kpad.h>
32 #include <revolution/sc.h>
33 #include <revolution/cnt.h>
34 #include <revolution/arc.h>
35 #include <revolution/cx.h>
36 #include <revolution/tpl.h>
37 
38 #include <demo.h>
39 
40 #include <string.h>
41 #include <math.h>
42 
43 #include <revolution/hbm.h>
44 
45 
46 
47 // This is the number of content index to be used in this program.
48 #define TARGET_SHARED   2
49 #define TARGET_SOUND    3
50 #define TARGET_NWM		4
51 #define TARGET_SAMPLE   5
52 enum
53 {
54     OFF = 0,
55     ON
56 };
57 
58 enum
59 {
60     eAlphaInIcon = 0,
61     ePauseIcon,
62     eAlphaOutIcon
63 };
64 
65 static const f32 scStickMoveCoe =  2048.0f/72.0f; /* Amount-of-movement coefficient of the analog stick */
66 static KPADStatus sKpads[ WPAD_MAX_CONTROLLERS ][ KPAD_MAX_READ_BUFS ];
67 
68 static TPLPalettePtr sIconTpl;
69 
70 /* Sound data */
71 u8* sound_data_ptr;
72 /* Allocate a buffer for sounds */
73 u8* sound_buf;
74 /* NAND handle */
75 CNTHandle   CntHandle_SharedSound;
76 CNTHandle   CntHandle_Shared;
77 CNTHandle   CntHandle_Nwm;
78 CNTHandle   CntHandle_Sample;
79 
80 // Reset/Power Callback
81 static void ResetCallback();
82 static void PowerCallback();
83 static bool reset_called,power_called;
84 
85 #ifdef  ENABLE_BALANCE_BOARD
86 static u8  workarea[WPAD_BLCINT_WORK_LEN] ATTRIBUTE_ALIGN(32);
87 #endif // ENABLE_BALANCE_BOARD
88 /* RenderMode */
89 static GXRenderModeObj sRMObj[2] =
90 {
91     /* NTSC 4:3 */
92     {
93         VI_TVMODE_NTSC_INT,
94         608,
95         456,
96         456,
97         (VI_MAX_WIDTH_NTSC - 670)/2,
98         (VI_MAX_HEIGHT_NTSC - 456)/2,
99         670,
100         456,
101         VI_XFBMODE_DF,
102         GX_FALSE,
103         GX_FALSE,
104         6, 6, 6, 6, 6, 6,
105         6, 6, 6, 6, 6, 6,
106         6, 6, 6, 6, 6, 6,
107         6, 6, 6, 6, 6, 6,
108         8, 8,
109         10, 12, 10,
110         8, 8,
111     },
112     /* PAL 4:3 */
113     {
114         VI_TVMODE_PAL_INT,
115         608,
116         456,
117         542,
118         (VI_MAX_WIDTH_PAL - 670)/2,
119         (VI_MAX_HEIGHT_PAL - 542)/2,
120         670,
121         542,
122         VI_XFBMODE_DF,
123         GX_FALSE,
124         GX_FALSE,
125         6, 6, 6, 6, 6, 6,
126         6, 6, 6, 6, 6, 6,
127         6, 6, 6, 6, 6, 6,
128         6, 6, 6, 6, 6, 6,
129         8, 8,
130         10, 12, 10,
131         8, 8,
132     }
133 };
134 
135 static GXRenderModeObj sRMObjWide[2] =
136 {
137     /* NTSC 16:9 */
138     {
139         VI_TVMODE_NTSC_INT,
140         608,
141         456,
142         456,
143         (VI_MAX_WIDTH_NTSC - 686)/2,
144         (VI_MAX_HEIGHT_NTSC - 456)/2,
145         686,
146         456,
147         VI_XFBMODE_DF,
148         GX_FALSE,
149         GX_FALSE,
150         6, 6, 6, 6, 6, 6,
151         6, 6, 6, 6, 6, 6,
152         6, 6, 6, 6, 6, 6,
153         6, 6, 6, 6, 6, 6,
154         8, 8,
155         10, 12, 10,
156         8, 8,
157     },
158     /* PAL 16:9 */
159     {
160         VI_TVMODE_PAL_INT,
161         608,
162         456,
163         542,
164         (VI_MAX_WIDTH_PAL - 682)/2,
165         (VI_MAX_HEIGHT_PAL - 542)/2,
166         682,
167         542,
168         VI_XFBMODE_DF,
169         GX_FALSE,
170         GX_FALSE,
171         6, 6, 6, 6, 6, 6,
172         6, 6, 6, 6, 6, 6,
173         6, 6, 6, 6, 6, 6,
174         6, 6, 6, 6, 6, 6,
175         8, 8,
176         10, 12, 10,
177         8, 8,
178     }
179 };
180 
181 // NTSC / PAL
182 int sTvmode;
183 
184 static void initgxfortex();
185 static void drawTexPlate( void* graphicBuf, u16 width, u16 height, GXTexFmt texFmt, f32  left, f32 top, f32 right, f32 bottom, f32 z, GXColor clr );
186 
187 /*---------------------------------------------------------------------------*
188   Name:         initgxfortex
189 
190   Description:  Sets up GX for rendering the texture mapping rectangle.
191 
192   Arguments:    None.
193 
194   Returns:      None.
195  *---------------------------------------------------------------------------*/
initgxfortex()196 static void initgxfortex()
197 {
198     GXClearVtxDesc();
199     GXSetVtxDesc(GX_VA_POS, GX_DIRECT);
200     GXSetVtxDesc(GX_VA_TEX0, GX_DIRECT);
201     GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_POS, GX_POS_XYZ, GX_F32, 0);
202     GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_TEX0, GX_TEX_ST, GX_F32, 0);
203 
204     GXSetChanCtrl(GX_COLOR0A0, GX_DISABLE, GX_SRC_REG, GX_SRC_REG,
205                     GX_LIGHT_NULL, GX_DF_NONE, GX_AF_NONE);
206     GXSetNumChans(1);
207 
208     GXSetTexCoordGen(GX_TEXCOORD0, GX_TG_MTX2x4, GX_TG_TEX0, GX_IDENTITY);
209     GXSetNumTexGens(1);
210 
211     GXSetTevColor(GX_TEVREG0, (GXColor){ 255, 255, 255, 255 });
212     GXSetTevColor(GX_TEVREG1, (GXColor){ 0, 0, 0, 0 });
213 
214     GXSetTevOrder(GX_TEVSTAGE0, GX_TEXCOORD0, GX_TEXMAP0, GX_COLOR_NULL);
215     GXSetTevColorIn(GX_TEVSTAGE0,GX_CC_ZERO, GX_CC_TEXC, GX_CC_C0, GX_CC_C1);
216     GXSetTevAlphaIn(GX_TEVSTAGE0,GX_CA_ZERO, GX_CA_TEXA, GX_CA_A0, GX_CA_A1);
217     GXSetTevColorOp(GX_TEVSTAGE0,GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_TRUE, GX_TEVPREV);
218     GXSetTevAlphaOp(GX_TEVSTAGE0,GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_TRUE, GX_TEVPREV);
219     GXSetTevSwapMode(GX_TEVSTAGE0, GX_TEV_SWAP0, GX_TEV_SWAP0);
220     GXSetTevDirect(GX_TEVSTAGE0);
221     GXSetNumTevStages(1);
222     GXSetNumIndStages(0);
223 
224     GXSetTevSwapModeTable(GX_TEV_SWAP0, GX_CH_RED, GX_CH_GREEN, GX_CH_BLUE, GX_CH_ALPHA);
225 
226     GXSetBlendMode(GX_BM_BLEND, GX_BL_SRCALPHA, GX_BL_INVSRCALPHA, GX_LO_SET);
227     GXSetZMode(GX_ENABLE, GX_ALWAYS, GX_DISABLE);
228     GXSetZCompLoc(GX_DISABLE);
229     GXSetAlphaCompare(GX_GREATER, 0, GX_AOP_AND, GX_ALWAYS, 0);
230     GXSetColorUpdate(GX_ENABLE);
231     GXSetAlphaUpdate(GX_DISABLE);
232 
233     GXSetNumIndStages(0);
234     GXSetTevSwapModeTable(GX_TEV_SWAP0, GX_CH_RED, GX_CH_GREEN, GX_CH_BLUE, GX_CH_ALPHA);
235     GXSetTevSwapMode(GX_TEVSTAGE0, GX_TEV_SWAP0, GX_TEV_SWAP0);
236 }
237 
238 /*---------------------------------------------------------------------------*
239   Name:         drawTexPlate
240 
241   Description:  Renders a texture-mapped rectangle.
242 
243   Arguments:    graphicBuf
244                 width
245                 height
246                 texFmt
247                 left
248                 top
249                 right
250                 bottom
251                 z
252                 clr
253 
254   Returns:      None.
255  *---------------------------------------------------------------------------*/
drawTexPlate(void * graphicBuf,u16 width,u16 height,GXTexFmt texFmt,f32 left,f32 top,f32 right,f32 bottom,f32 z,GXColor clr)256 static void drawTexPlate( void* graphicBuf, u16 width, u16 height, GXTexFmt texFmt, f32  left, f32 top,
257                              f32 right, f32 bottom, f32 z, GXColor clr )
258 {
259 #pragma unused( clr )
260     GXTexObj texObj;
261 
262     GXSetCullMode( GX_CULL_NONE );
263 
264     Mtx     view_mtx ;
265     // mtx
266     MTXIdentity( view_mtx ) ;
267     GXLoadPosMtxImm( view_mtx, GX_PNMTX0 ) ;
268     GXSetCurrentMtx( GX_PNMTX0 ) ;
269     GXClearVtxDesc();
270 
271     GXInitTexObj(   &texObj,
272                     (void *)graphicBuf,
273                     (u16)width,
274                     (u16)height,
275                     texFmt, GX_CLAMP, GX_CLAMP, GX_FALSE);
276 
277     GXSetVtxAttrFmt(GX_VTXFMT5, GX_VA_POS, GX_POS_XYZ, GX_F32, 0);
278     GXSetVtxAttrFmt(GX_VTXFMT5, GX_VA_TEX0, GX_TEX_ST, GX_S16, 0);
279     GXSetVtxDesc(GX_VA_POS,  GX_DIRECT);
280     GXSetVtxDesc(GX_VA_TEX0, GX_DIRECT);
281 
282     GXSetNumChans(1);
283     GXSetChanCtrl(GX_COLOR0A0, GX_FALSE, GX_SRC_VTX, GX_SRC_VTX, GX_LIGHT_NULL, GX_DF_NONE, GX_AF_NONE);
284 
285     GXSetNumTexGens(1);
286     GXSetTexCoordGen(GX_TEXCOORD0, GX_TG_MTX2x4, GX_TG_TEX0, GX_IDENTITY);
287 
288     GXSetNumTevStages(1);
289     GXSetTevColor(GX_TEVREG0, (GXColor){255, 255, 255, 255});
290     GXSetTevOrder(GX_TEVSTAGE0, GX_TEXCOORD0, GX_TEXMAP0, GX_COLOR_NULL);
291     GXSetTevColorIn(GX_TEVSTAGE0, GX_CC_ZERO, GX_CC_ZERO, GX_CC_ZERO, GX_CC_TEXC);
292     GXSetTevColorOp(GX_TEVSTAGE0, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_TRUE, GX_TEVPREV);
293     GXSetTevAlphaIn(GX_TEVSTAGE0, GX_CA_ZERO, GX_CA_A0, GX_CA_TEXA, GX_CA_ZERO);
294     GXSetTevAlphaOp(GX_TEVSTAGE0, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_TRUE, GX_TEVPREV);
295 
296     GXSetBlendMode(GX_BM_BLEND, GX_BL_SRCALPHA, GX_BL_INVSRCALPHA, GX_LO_CLEAR);
297     GXSetZMode(GX_FALSE, GX_LEQUAL, GX_FALSE);
298 
299     GXInitTexObjLOD( &texObj, GX_NEAR, GX_NEAR, 0, 0, 0, 0, 0, GX_ANISO_1);
300     GXInitTexObjFilter( &texObj,GX_LIN_MIP_LIN,GX_LINEAR );
301     GXLoadTexObj( &texObj, GX_TEXMAP0 );
302 
303     GXBegin( GX_QUADS, GX_VTXFMT5, 4 );
304         GXPosition3f32( left, top, z );
305         GXTexCoord2s16(0, 0);
306         GXPosition3f32( left, bottom, z );
307         GXTexCoord2s16(0, 1);
308         GXPosition3f32( right, bottom, z );
309         GXTexCoord2s16(1, 1);
310         GXPosition3f32( right, top, z );
311         GXTexCoord2s16(1, 0);
312     GXEnd();
313 }
314 
allocMem1(u32 size)315 static void* allocMem1( u32 size )
316 {
317     return MEMAllocFromAllocator( &DemoAllocator1, size );
318 }
319 
freeMem1(void * ptr)320 static u8 freeMem1( void* ptr )
321 {
322     MEMFreeToAllocator( &DemoAllocator1, ptr );
323     return 1;
324 }
325 
allocMem2(u32 size)326 static void* allocMem2( u32 size )
327 {
328     return MEMAllocFromAllocator( &DemoAllocator2, size );
329 }
330 
freeMem2(void * ptr)331 static u8 freeMem2( void* ptr )
332 {
333     MEMFreeToAllocator( &DemoAllocator2, ptr );
334     return 1;
335 }
336 
337 /* Event/sound callback function */
SoundCallback(int evt,int arg)338 static int SoundCallback( int evt, int arg )
339 {
340     OSReport( "SoundCallback: %d, %d\n", evt, arg );
341     return HBMSEV_RET_NONE;
342 }
343 
ResetCallback()344 static void ResetCallback()
345 {
346     reset_called = true;
347 }
348 
PowerCallback()349 static void PowerCallback()
350 {
351     power_called = true;
352 }
353 
ReadNandFile(char * fileName,CNTHandle * cnt,u32 * fileSize=NULL)354 static void* ReadNandFile(
355     char *fileName,
356     CNTHandle* cnt,
357     u32* fileSize = NULL
358 )
359 {
360     CNTFileInfo fileInfo;
361     u32         l_fileSize;
362     void*       buffer;     // Pointer to the buffer
363     s32         rv;         // for checking error
364 
365     // Open the filename to fileInfo
366     rv = CNTOpen(cnt, fileName, &fileInfo);
367 
368     if (rv != CNT_RESULT_OK)
369     {
370         OSReport("Cannot open file \"%s\"", fileName);
371         OSHalt("");
372     }
373 
374     // Get the size of the files
375     l_fileSize = CNTGetLength(&fileInfo);
376     if( fileSize )
377     {
378         *fileSize = l_fileSize;
379     }
380 
381     // Allocate buffers to read the files.
382     // Note that pointers returned by Allocator are all 32byte aligned.
383     buffer = (u8*)allocMem2( OSRoundUp32B( l_fileSize ) );
384 
385     // Reads filenames all at one time
386     rv = CNTRead(&fileInfo, (void*)buffer, (u32)OSRoundUp32B( l_fileSize ));
387 
388     // If CNTRead succeeds, it returns length (the number of bytes).
389     if (rv < 0)
390     {
391         OSReport("%d\n",rv);
392         OSHalt("Error occurred when issuing read for the first file");
393     }
394 
395     CNTClose(&fileInfo);
396 
397     return buffer;
398 }
399 
400 // Open an LZ77-compressed file
ReadNandFileLZ(char * fileName,CNTHandle * cnt,u32 * fileSize=NULL)401 static void* ReadNandFileLZ(
402     char *fileName,
403     CNTHandle* cnt,
404     u32* fileSize = NULL
405 )
406 {
407     void*         compbuffer;     // Pointer to the buffer
408     void*         buffer;         // Pointer to the buffer
409     u32           l_fileSize = 0;
410 
411     // Calculate the file size after decompression
412     compbuffer = ReadNandFile( fileName, cnt );
413     l_fileSize = CXGetUncompressedSize( compbuffer );
414     if( fileSize )
415     {
416         *fileSize = l_fileSize;
417     }
418 
419     // Allocate the buffer for decompression
420     buffer = (u8*)allocMem2( OSRoundUp32B(l_fileSize) );
421 
422     // Decompress the data
423     CXUncompressLZ( compbuffer, buffer );
424     DCFlushRange( buffer, l_fileSize );
425 
426     // Deallocate the region used before the decompression
427     freeMem2( compbuffer );
428 
429     return buffer;
430 }
431 
432 // Open a Huffman-compressed file
ReadNandFileHuff(char * fileName,CNTHandle * cnt,u32 * fileSize=NULL)433 static void* ReadNandFileHuff(
434     char *fileName,
435     CNTHandle* cnt,
436     u32* fileSize = NULL
437 )
438 {
439     void*         compbuffer;     // Pointer to the buffer
440     void*         buffer;         // Pointer to the buffer
441     u32           l_fileSize = 0;
442 
443     compbuffer = ReadNandFile( fileName, cnt );
444 
445     // Calculate the file size after decompression
446     l_fileSize = CXGetUncompressedSize( compbuffer );
447     if( fileSize )
448     {
449         *fileSize = l_fileSize;
450     }
451 
452     // Allocate the buffer for decompression
453     buffer = (u8*)allocMem2( OSRoundUp32B(l_fileSize) );
454 
455     // Decompress the data
456     CXUncompressHuffman( compbuffer, buffer );
457     DCFlushRange( buffer, l_fileSize );
458 
459     // Deallocate the region used before the decompression
460     freeMem2( compbuffer );
461 
462     return buffer;
463 }
464 
465 /* Initial settings */
Init()466 static void Init()
467 {
468     char dirName[] = "HomeButton3";
469     char nameBuf[64];
470 
471     VIInit();
472     switch (VIGetTvFormat())
473     {
474         case VI_NTSC:
475              sTvmode = 0;
476              break;
477         case VI_PAL:
478              sTvmode = 1;
479              break;
480         default:
481              OSHalt("VIGetTvFormat()t: invalid TV format\n");
482              break;
483     }
484 
485     DEMOInit(&sRMObj[sTvmode]);
486 
487     SCInit();
488     while ( SC_STATUS_OK != SCCheckStatus() ) {} /* Wait for completion of SCInit() */
489     DVDInit();
490     OSInitFastCast();
491 
492 #ifdef  ENABLE_BALANCE_BOARD
493     WPADRegisterBLCWorkarea( workarea );
494 #endif // ENABLE_BALANCE_BOARD
495     WPADRegisterAllocator( allocMem2, freeMem2 );
496 
497     PADInit();
498     KPADInit();
499 
500 	/* Initialization for NAND loading */
501     CNTInit();
502 
503     // shared
504     if(CNTInitHandle(TARGET_SHARED, &CntHandle_Shared, &DemoAllocator2) != CNT_RESULT_OK)
505     {
506         OSHalt("Initializing SHARED handle was not finished:\n");
507     }
508 
509     // hbm sound
510     if(CNTInitHandle(TARGET_SOUND, &CntHandle_SharedSound, &DemoAllocator2) != CNT_RESULT_OK)
511     {
512         OSHalt("Initializing SOUND handle was not finished:\n");
513     }
514 
515     // hbm message
516     if(CNTInitHandle(TARGET_SAMPLE, &CntHandle_Sample, &DemoAllocator2) != CNT_RESULT_OK)
517     {
518         OSHalt("Initializing SAMPLE handle was not finished:\n");
519     }
520 
521     // NWM message
522     if(CNTInitHandle(TARGET_NWM, &CntHandle_Nwm, &DemoAllocator2) != CNT_RESULT_OK)
523     {
524         OSHalt("Initializing NWM handle was not finished:\n");
525     }
526 
527 	/* Load icon */
528 	strcpy( nameBuf, dirName );
529     strcat( nameBuf, "/homeBtnIcon.tpl" );
530     sIconTpl = ( TPLPalettePtr )ReadNandFile( nameBuf, &CntHandle_Shared );
531     TPLBind( sIconTpl );
532 
533     /* Power switch and reset switch callbacks */
534     OSSetResetCallback(ResetCallback);
535     OSSetPowerCallback(PowerCallback);
536 
537     reset_called = false;
538     power_called = false;
539 }
540 
541 
542 /* Projection settings */
SetProjection(int wideflag)543 static void SetProjection( int wideflag )
544 {
545     Mtx44 projMtx;
546 
547     if( !wideflag )
548     {
549         DEMOReInit(&sRMObj[sTvmode]);
550         MTXOrtho(projMtx, 228.0f, -228.0f, -304.0f, 304.0f, 0.0f, 500.0f);
551     }
552     else
553     {
554         DEMOReInit(&sRMObjWide[sTvmode]);
555         MTXOrtho(projMtx, 228.0f, -228.0f, -416.0f, 416.0f, 0.0f, 500.0f);
556     }
557 
558     GXSetProjection(projMtx, GX_ORTHOGRAPHIC);
559 }
560 
561 /* Initialize GX */
InitGX()562 static void InitGX()
563 {
564     GXClearVtxDesc();
565 
566     GXSetVtxAttrFmt(GX_VTXFMT4, GX_VA_POS,  GX_POS_XY,  GX_F32, 0);
567     GXSetVtxAttrFmt(GX_VTXFMT4, GX_VA_CLR0, GX_CLR_RGB, GX_RGB8, 0);
568     GXSetVtxDesc(GX_VA_POS,  GX_DIRECT);
569     GXSetVtxDesc(GX_VA_CLR0, GX_DIRECT);
570 
571     GXSetNumChans(1);
572     GXSetNumTexGens(0);
573     GXSetNumTevStages(1);
574     GXSetTevOrder(GX_TEVSTAGE0, GX_TEXCOORD_NULL, GX_TEXMAP_NULL, GX_COLOR0A0);
575     GXSetTevOp(GX_TEVSTAGE0, GX_PASSCLR);
576 
577     GXSetBlendMode(GX_BM_NONE, GX_BL_ZERO, GX_BL_ZERO, GX_LO_CLEAR);
578     GXSetZMode(GX_TRUE, GX_LEQUAL, GX_TRUE);
579     GXSetCurrentMtx( GX_PNMTX1 );
580 }
581 
582 /* Render the "Prohibited" icon */
DrawBanIcon(u8 alpha)583 static void DrawBanIcon( u8 alpha )
584 {
585     GXTexObj texObj;
586     Mtx      view_mtx ;
587     // mtx
588     MTXIdentity( view_mtx ) ;
589     GXLoadPosMtxImm( view_mtx, GX_PNMTX1 ) ;
590     GXSetCurrentMtx( GX_PNMTX1 ) ;
591 
592     GXClearVtxDesc();
593 
594     GXSetVtxAttrFmt(GX_VTXFMT5, GX_VA_POS,  GX_POS_XY,  GX_S16, 0);
595     GXSetVtxAttrFmt(GX_VTXFMT5, GX_VA_TEX0, GX_TEX_ST, GX_S16, 0);
596     GXSetVtxDesc(GX_VA_POS,  GX_DIRECT);
597     GXSetVtxDesc(GX_VA_TEX0, GX_DIRECT);
598 
599     GXSetNumChans(1);
600     GXSetChanCtrl(GX_COLOR0A0, GX_FALSE, GX_SRC_VTX, GX_SRC_VTX, GX_LIGHT_NULL, GX_DF_NONE, GX_AF_NONE);
601 
602     GXSetNumTexGens(1);
603     GXSetTexCoordGen(GX_TEXCOORD0, GX_TG_MTX2x4, GX_TG_TEX0, GX_IDENTITY);
604 
605     GXSetNumTevStages(1);
606     GXSetTevColor(GX_TEVREG0, (GXColor){255, 255, 255, alpha});
607     GXSetTevOrder(GX_TEVSTAGE0, GX_TEXCOORD0, GX_TEXMAP0, GX_COLOR_NULL);
608     GXSetTevColorIn(GX_TEVSTAGE0, GX_CC_ZERO, GX_CC_ZERO, GX_CC_ZERO, GX_CC_TEXC);
609     GXSetTevColorOp(GX_TEVSTAGE0, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_TRUE, GX_TEVPREV);
610     GXSetTevAlphaIn(GX_TEVSTAGE0, GX_CA_ZERO, GX_CA_A0, GX_CA_TEXA, GX_CA_ZERO);
611     GXSetTevAlphaOp(GX_TEVSTAGE0, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_TRUE, GX_TEVPREV);
612 
613     GXSetBlendMode(GX_BM_BLEND, GX_BL_SRCALPHA, GX_BL_INVSRCALPHA, GX_LO_CLEAR);
614     GXSetZMode(GX_FALSE, GX_LEQUAL, GX_FALSE);
615 
616     TPLGetGXTexObjFromPalette( sIconTpl, &texObj, 0 );
617     GXLoadTexObj( &texObj, GX_TEXMAP0 );
618 
619     /* The rendering position may be anywhere inside the safe frame. */
620     GXBegin( GX_QUADS, GX_VTXFMT5, 4 );
621     GXPosition2s16( -256 + 0, 188 - 56 );
622     GXTexCoord2s16( 0, 1 );
623     GXPosition2s16( -256 + 0, 188 + 0 );
624     GXTexCoord2s16( 0, 0 );
625     GXPosition2s16( -256 + 56, 188 + 0 );
626     GXTexCoord2s16( 1, 0 );
627     GXPosition2s16( -256 + 56, 188 - 56 );
628     GXTexCoord2s16( 1, 1 );
629     GXEnd();
630 }
631 
InitHomeButtonInfo(HBMDataInfo * pHbmInfo,HBMNetworkManualInfo * pNetInfo)632 static void InitHomeButtonInfo( HBMDataInfo* pHbmInfo, HBMNetworkManualInfo* pNetInfo )
633 {
634     char dirName[] = "HomeButton3";
635 
636     char nameBuf[64];
637     char nameNwmBuf[64];
638 
639     /* Create filename */
640     strcpy( nameBuf, dirName );
641     strcpy( nameNwmBuf, dirName );
642     /* Switching as necessary according to the language setting */
643     pHbmInfo->region=SCGetLanguage();
644     switch (pHbmInfo->region)
645     {
646     case SC_LANG_JAPANESE:
647         strcat( nameBuf, "/LZ77_homeBtn.arc" );
648         strcat( nameNwmBuf, "/LZ77_homeBtn_nwm_jpn.arc" );
649         break;
650     case SC_LANG_ENGLISH:
651         strcat( nameBuf, "/LZ77_homeBtn_ENG.arc" );
652         strcat( nameNwmBuf, "/LZ77_homeBtn_nwm_eng.arc" );
653         break;
654     case SC_LANG_GERMAN:
655         strcat( nameBuf, "/LZ77_homeBtn_GER.arc" );
656         strcat( nameNwmBuf, "/LZ77_homeBtn_nwm_ger.arc" );
657         break;
658     case SC_LANG_FRENCH:
659         strcat( nameBuf, "/LZ77_homeBtn_FRA.arc" );
660         strcat( nameNwmBuf, "/LZ77_homeBtn_nwm_fra.arc" );
661         break;
662     case SC_LANG_SPANISH:
663         strcat( nameBuf, "/LZ77_homeBtn_SPA.arc" );
664         strcat( nameNwmBuf, "/LZ77_homeBtn_nwm_spa.arc" );
665         break;
666     case SC_LANG_ITALIAN:
667         strcat( nameBuf, "/LZ77_homeBtn_ITA.arc" );
668         strcat( nameNwmBuf, "/LZ77_homeBtn_nwm_ita.arc" );
669         break;
670     case SC_LANG_DUTCH:
671         strcat( nameBuf, "/LZ77_homeBtn_NED.arc" );
672         strcat( nameNwmBuf, "/LZ77_homeBtn_nwm_ned.arc" );
673         break;
674     default:
675         pHbmInfo->region=SC_LANG_JAPANESE;
676         strcat( nameBuf, "/LZ77_homeBtn.arc" );
677         strcat( nameNwmBuf, "/LZ77_homeBtn_nwm_jpn.arc" );
678         break;
679     }
680     pHbmInfo->layoutBuf = ReadNandFileLZ( nameBuf, &CntHandle_Shared );
681     pNetInfo->layoutBuf = ReadNandFileLZ( nameNwmBuf, &CntHandle_Nwm );
682 
683     strcpy( nameBuf, dirName );
684     strcat( nameBuf, "/Huf8_SpeakerSe.arc" );
685     pHbmInfo->spkSeBuf = ReadNandFileHuff( nameBuf, &CntHandle_Shared );
686 
687     strcpy( nameBuf, dirName );
688 #ifdef HBM_NO_SAVE
689     strcat( nameBuf, "/home_nosave.csv" );
690 #else
691     strcat( nameBuf, "/home.csv" );
692 #endif
693     // CSV files are not loaded because they are shared.
694     pHbmInfo->msgBuf = ReadNandFile( nameBuf, &CntHandle_Sample );
695     pNetInfo->msgBuf = ReadNandFile( "/HomeButton3/network.csv", &CntHandle_Sample, NULL );
696 
697     strcpy( nameBuf, dirName );
698     strcat( nameBuf, "/config.txt" );
699     pHbmInfo->configBuf = ReadNandFile( nameBuf, &CntHandle_Shared, &pHbmInfo->configBufSize );
700 
701     pHbmInfo->sound_callback = SoundCallback;
702     pHbmInfo->backFlag       = OFF;
703     pHbmInfo->cursor         = 0;
704     pHbmInfo->adjust.x       = 832.f / 608.f;
705     pHbmInfo->adjust.y       = 1.0f;
706     pHbmInfo->frameDelta     = 1.0f;
707 
708     /* Memory allocation settings */
709     pHbmInfo->mem = allocMem2( HBM_MEM_SIZE );
710     pHbmInfo->memSize	= HBM_MEM_SIZE;
711     pHbmInfo->pAllocator = NULL;
712 
713 	/* Dialog message settings are applied to the WiiWare manual button messages as well. */
714     pHbmInfo->messageFlag	= MESSAGE_FLAG;
715 }
716 
717 /* Initialize sounds */
InitSound()718 static void InitSound()
719 {
720     char nameBuf[64];
721     strcpy( nameBuf, "HomeButtonSe/Huf8_HomeButtonSe.arc" );
722 
723     /* Load sound data for AX use */
724     sound_data_ptr = (u8*)ReadNandFileHuff( nameBuf, &CntHandle_SharedSound );
725     /* Allocate a buffer for sounds */
726     sound_buf = (u8*)allocMem2( HBM_MEM_SIZE_SOUND );
727     HBMCreateSound( sound_data_ptr, sound_buf, HBM_MEM_SIZE_SOUND );
728 }
729 
730 /* Cursor position initialization */
InitControllerData(HBMControllerData * pConData)731 static void InitControllerData( HBMControllerData* pConData )
732 {
733     int i;
734     for( i = 0; i < WPAD_MAX_CONTROLLERS; i++ )
735     {
736         pConData->wiiCon[i].pos.x = 0.f;
737         pConData->wiiCon[i].pos.y = 0.f;
738         pConData->wiiCon[i].use_devtype = WPAD_DEV_CORE;
739     }
740 }
741 
742 /* Absolute value clamp */
AbsClamp(f32 val,f32 max)743 static f32 AbsClamp( f32 val, f32 max )
744 {
745     return ( ( val > max ) ? max : ( val < -max ) ? -max : val );
746 }
747 
748 /* Cursor movement processing for analog stick */
calcAnalogCursorPos(f32 stickX,f32 stickY,Vec2 * pos)749 static int calcAnalogCursorPos( f32 stickX, f32 stickY, Vec2* pos )
750 {
751     f32 x,y;
752     x = ( stickX / scStickMoveCoe );
753     y = ( stickY / scStickMoveCoe );
754     x = AbsClamp( x, 1.0f );
755     y = AbsClamp( y, 1.0f );
756     if( x == 0.0f && y == 0.0f ) return FALSE;
757     pos->x = AbsClamp( pos->x + x, 1.0f );
758     pos->y = AbsClamp( pos->y - y, 1.0f );
759     return TRUE;
760 }
761 
762 /* Cursor movement processing when using +Control key */
calcDigitalCursorPos(u32 button,Vec2 * pos)763 static int calcDigitalCursorPos( u32 button, Vec2* pos )
764 {
765     const float spd =1.0f / scStickMoveCoe;
766     const float spd2= spd * 0.7071f;
767 
768     button&=KPAD_CL_BUTTON_UP|KPAD_CL_BUTTON_LEFT|KPAD_CL_BUTTON_DOWN|KPAD_CL_BUTTON_RIGHT;
769     switch (button)
770     {
771     case KPAD_CL_BUTTON_UP:     pos->y-=spd; break;
772     case KPAD_CL_BUTTON_LEFT:   pos->x-=spd; break;
773     case KPAD_CL_BUTTON_DOWN:   pos->y+=spd; break;
774     case KPAD_CL_BUTTON_RIGHT:  pos->x+=spd; break;
775     case KPAD_CL_BUTTON_UP  |KPAD_CL_BUTTON_LEFT:   pos->y-=spd2; pos->x-=spd2; break;
776     case KPAD_CL_BUTTON_UP  |KPAD_CL_BUTTON_RIGHT:  pos->y-=spd2; pos->x+=spd2; break;
777     case KPAD_CL_BUTTON_DOWN|KPAD_CL_BUTTON_LEFT:   pos->y+=spd2; pos->x-=spd2; break;
778     case KPAD_CL_BUTTON_DOWN|KPAD_CL_BUTTON_RIGHT:  pos->y+=spd2; pos->x+=spd2; break;
779     default: return FALSE;
780     }
781     pos->x = AbsClamp( pos->x, 1.0f );
782     pos->y = AbsClamp( pos->y, 1.0f );
783     return TRUE;
784 }
785 
786 
787 /* Change the adjust value depending on the display mode */
SetAdjustValue(HBMDataInfo * pHbmInfo)788 static void SetAdjustValue( HBMDataInfo* pHbmInfo )
789 {
790     {
791         /* 16:9 */
792         pHbmInfo->adjust.x       = 832.f / 608.f;
793         pHbmInfo->adjust.y       = 1.0f;
794     }
795 
796     if(sTvmode == 0)
797     {
798         /* NTSC: 60Hz */
799         pHbmInfo->frameDelta     = 1.0f;
800     }
801     else
802     {
803         /* PAL: 50Hz */
804         pHbmInfo->frameDelta     = 1.2f;
805     }
806 }
807 
808 /* Main function */
main()809 void main()
810 {
811     Mtx mv;
812     HBMDataInfo hbmInfo;
813     HBMNetworkManualInfo    netInfo;
814     HBMControllerData conData;
815     int homeBtnSwitch  = OFF;   /* HOME button switch */
816     int drawModeFlag   = OFF;   /* Flag for toggling between 4:3 and 16:9 displays */
817     int banIconSwitch  = OFF;   /* HOME button prohibited icon */
818     s8  banIconMode    = 0;     /* 0: AlphaIn, 1: Pause, 2: AlphaOut */
819     OSTick banIconTime = 0;
820     u8  banIconAlpha   = 0;
821     s32 wpad_result[WPAD_MAX_CONTROLLERS];
822     u32 pad_type[WPAD_MAX_CONTROLLERS];
823     Vec2 pos[WPAD_MAX_CONTROLLERS];/* Position of the pointer */
824     int input_classic;
825     int i;
826 
827     // TPL
828     // Manual image
829     TPLPalettePtr  tplGraphic;
830     TPLDescriptorPtr tdpGraphic;
831     // Test image
832     TPLPalettePtr  tplGraphic_Test;
833     TPLDescriptorPtr tdpGraphic_Test;
834 
835     s32 kpad_read[WPAD_MAX_CONTROLLERS];
836     GXRenderModeObj* pRm;
837 
838     Init();
839 
840     /* Viewport settings */
841     pRm = DEMOGetRenderModeObj();
842     MTXIdentity(mv);
843     GXLoadPosMtxImm(mv, GX_PNMTX1);
844     SetProjection( drawModeFlag );
845     /* No culling */
846     GXSetCullMode( GX_CULL_NONE );
847 
848     /* Create the manual image */
849     {
850         // Load the manual image
851         tplGraphic = (TPLPalettePtr)ReadNandFile( "sample.tpl", &CntHandle_Sample );
852 
853         TPLBind( tplGraphic );
854         tdpGraphic = TPLGet(tplGraphic, (u32) 0);
855 
856         netInfo.width = tdpGraphic->textureHeader->width;
857         netInfo.height = tdpGraphic->textureHeader->height;
858         netInfo.texFmt  = (GXTexFmt)tdpGraphic->textureHeader->format;
859         netInfo.graphicBuf = (void*)tdpGraphic->textureHeader->data;
860 
861         // Load the test image
862         tplGraphic_Test = (TPLPalettePtr)ReadNandFile( "test.tpl", &CntHandle_Sample );
863         TPLBind( tplGraphic_Test );
864         tdpGraphic_Test = TPLGet(tplGraphic_Test, (u32) 0);
865     }
866 
867     /* Display the operation method on the console */
868     OSReport( "------------------------------\n" );
869     OSReport( "HOME Button Menu Sample\n\n" );
870     OSReport( "+ : Show Icon\n" );
871     OSReport( "2 : Switch Video Mode\n" );
872     OSReport( "------------------------------\n" );
873 
874     OSReport("Mem1Free = %d\n", MEMGetTotalFreeSizeForExpHeap((MEMHeapHandle)DemoAllocator1.pHeap) );
875     OSReport("Mem2Free = %d\n", MEMGetTotalFreeSizeForExpHeap((MEMHeapHandle)DemoAllocator2.pHeap) );
876 
877     InitControllerData( &conData );
878     InitHomeButtonInfo( &hbmInfo, &netInfo );
879 
880     /* Set the adjust value depending on the screen mode */
881     SetAdjustValue( &hbmInfo );
882 
883     /* HBM initialization */
884     HBMCreate( &hbmInfo );
885     HBMCreateEx( &netInfo );
886 
887     /* Load sounds */
888     InitSound();
889 
890     while( 1 )
891     {
892         /* Wii controllers */
893         for( int i = 0; i < WPAD_MAX_CONTROLLERS; i++ )
894         {
895             wpad_result[i] = WPADProbe( i, &pad_type[i] );
896             conData.wiiCon[i].use_devtype = pad_type[i];
897             kpad_read[i] = KPADRead( i, &sKpads[i][0], KPAD_MAX_READ_BUFS );
898 
899             switch( wpad_result[i] )
900             {
901             /* In the following error states, the value gotten by KPADRead is applied as is. */
902             case WPAD_ERR_BUSY:
903             case WPAD_ERR_TRANSFER:
904             case WPAD_ERR_INVALID:
905             case WPAD_ERR_CORRUPTED:
906             case WPAD_ERR_NONE:
907                 conData.wiiCon[i].kpad = &sKpads[i][0];
908 
909                 {
910                     /*
911                     According to guidelines, if there is input from a Classic Controller, that input is prioritized and inherits DPD coordinates.
912 
913                     Specify the DPD absolute coordinates when there is no Classic Controller input.
914                     */
915 
916                     input_classic = calcDigitalCursorPos(
917                         conData.wiiCon[i].kpad->ex_status.cl.hold,
918                         &conData.wiiCon[i].pos );
919 
920 
921                     input_classic = input_classic | calcAnalogCursorPos(
922                         conData.wiiCon[i].kpad->ex_status.cl.lstick.x,
923                         conData.wiiCon[i].kpad->ex_status.cl.lstick.y,
924                         &conData.wiiCon[i].pos );
925 
926                     if( !input_classic && conData.wiiCon[i].kpad->dpd_valid_fg > 0)
927                     {
928                         conData.wiiCon[i].pos.x = conData.wiiCon[i].kpad->pos.x;
929                         conData.wiiCon[i].pos.y = conData.wiiCon[i].kpad->pos.y;
930                     }
931                 }
932 
933                 /* Change the rendering mode */
934                 if( !homeBtnSwitch && sKpads[i][0].trig == KPAD_BUTTON_2 )
935                 {
936                     drawModeFlag = !drawModeFlag;
937                     SetProjection( drawModeFlag );
938                     pRm = DEMOGetRenderModeObj();
939                 }
940 
941                 if( sKpads[i][0].trig == KPAD_BUTTON_1 )
942                 {
943                     VISetBlack(FALSE);
944                     VIFlush();
945                 }
946 
947                 if ( !homeBtnSwitch && !banIconSwitch && sKpads[i][0].trig == KPAD_BUTTON_PLUS )
948                 {
949                     banIconMode   = eAlphaInIcon;
950                     banIconSwitch = ON;
951                     banIconTime   = OSGetTick();
952                     banIconAlpha  = 0;
953                 }
954                 break;
955             /* Apply NULL in the following error states. */
956             case WPAD_ERR_NO_CONTROLLER:
957             default:
958                 conData.wiiCon[i].kpad = NULL;
959                 break;
960             }
961         }
962         if( !homeBtnSwitch && !banIconSwitch )
963         {
964             BOOL press_home = FALSE;
965 
966             for ( int i = 0; i < WPAD_MAX_CONTROLLERS; i++ )
967             {
968                  if ( WPAD_ERR_NONE != wpad_result[i] ) continue;
969 
970                  /* When HOME is pressed on the Wii Remote or Classic Controller */
971                  if ( sKpads[i][0].trig == KPAD_BUTTON_HOME ||
972                       sKpads[i][0].ex_status.cl.trig==KPAD_CL_BUTTON_HOME )
973                  {
974 	                 OSReport("press_home = TRUE\n");
975                      press_home = TRUE;
976                      homeBtnSwitch = ON;
977                      break;
978                  }
979             }
980             if ( press_home )
981             {
982 				HBMInit();
983 
984                 /* Adjust */
985                 HBMSetAdjustFlag( drawModeFlag );
986 
987                 OSReport("Mem1Free = %d\n", MEMGetTotalFreeSizeForExpHeap((MEMHeapHandle)DemoAllocator1.pHeap) );
988                 OSReport("Mem2Free = %d\n", MEMGetTotalFreeSizeForExpHeap((MEMHeapHandle)DemoAllocator2.pHeap) );
989             }
990         }
991 
992         if( homeBtnSwitch )
993         {
994             /* Update SE (sound effect) */
995             HBMUpdateSound();
996 
997             /* Update the HOME Menu */
998             if( HBMCalc( &conData ) >= HBM_SELECT_HOMEBTN )
999             {
1000                 /* The number of the decided-upon button is returned */
1001                 OSReport("Select Btn:%d\n", HBMGetSelectBtnNum());
1002                 OSReport("Reassigned:%d\n", HBMIsReassignedControllers());
1003 
1004 
1005                 /* Process executed when returning from the HOME Menu */
1006                 switch( HBMGetSelectBtnNum() )
1007                 {
1008                 case HBM_SELECT_HOMEBTN:
1009                     break;
1010                 /* Move to the Wii Menu */
1011                 case HBM_SELECT_BTN1:
1012                     OSReport( "Return to WiiMenu.\n" );
1013                     OSReturnToMenu();
1014                     break;
1015                 /* Reset */
1016                 case HBM_SELECT_BTN2:
1017                     OSReport( "Reset.\n" );
1018                     OSRestart( 0 );
1019                     break;
1020                 case HBM_SELECT_BTN4:
1021                     OSReport( "Jump to NetworkManual.\n" );
1022                     OSLaunchManualViewer( 0 );
1023                     break;
1024                 default:
1025                     break;
1026                 }
1027 
1028                 homeBtnSwitch = OFF;
1029 
1030             }
1031 
1032         }
1033 
1034         /* Calculate the pointer position */
1035         for( i = 0; i < PAD_MAX_CONTROLLERS; i++ )
1036         {
1037             /* For Wii */
1038             if ( WPAD_ERR_NONE == wpad_result[i] &&
1039                  0 < kpad_read[i] &&
1040                  conData.wiiCon[i].kpad )
1041             {
1042                 if( !homeBtnSwitch )
1043                 {
1044                     if( sKpads[i]->dev_type == WPAD_DEV_CLASSIC )
1045                     {
1046                         pos[i].x = conData.wiiCon[i].pos.x;
1047                         pos[i].y = conData.wiiCon[i].pos.y;
1048                     }
1049                     else
1050                     {
1051                         pos[i].x = conData.wiiCon[i].kpad->pos.x;
1052                         pos[i].y = conData.wiiCon[i].kpad->pos.y;
1053                     }
1054 
1055                     pos[i].x *= pRm->fbWidth * 0.5f;
1056                     pos[i].y *= pRm->xfbHeight * 0.5f;
1057 
1058                     if( drawModeFlag )
1059                     {
1060                         pos[i].x *= hbmInfo.adjust.x;
1061                         pos[i].y *= hbmInfo.adjust.y;
1062                     }
1063                 }
1064             }
1065         }
1066 
1067         DEMOBeforeRender();
1068         {
1069             drawTexPlate(   (void*)tdpGraphic_Test->textureHeader->data,
1070                             tdpGraphic_Test->textureHeader->width,
1071                             tdpGraphic_Test->textureHeader->height,
1072                             (GXTexFmt)tdpGraphic_Test->textureHeader->format,
1073                             -304.f, 228.f, 304.f, -228.f, 0.f, (GXColor){ 255, 255, 255, 255 } );
1074 
1075             InitGX();
1076             if( homeBtnSwitch )
1077             {
1078                 /* Render the HOME Menu */
1079                 HBMDraw();
1080             }
1081             /* Render the specified cursor inside the HOME Menu */
1082             if( !homeBtnSwitch )
1083             {
1084                 for( i = 0; i < PAD_MAX_CONTROLLERS; i++ )
1085                 {
1086                     if( conData.wiiCon[i].kpad )
1087                     {
1088                         /* Render the Wii Pointer */
1089                         GXBegin( GX_QUADS, GX_VTXFMT4, 4 );
1090                         GXPosition2f32( -10 + pos[i].x, -10 - pos[i].y );
1091                         GXColor3u8( 255, 255, 255 );
1092                         GXPosition2f32( -10 + pos[i].x,  10 - pos[i].y );
1093                         GXColor3u8( 255, 255, 255 );
1094                         GXPosition2f32(  10 + pos[i].x,  10 - pos[i].y );
1095                         GXColor3u8( 255, 255, 255 );
1096                         GXPosition2f32(  10 + pos[i].x, -10 - pos[i].y );
1097                         GXColor3u8( 255, 255, 255 );
1098                         GXEnd();
1099                     }
1100                 }
1101 
1102                 /* Render the HOME Menu prohibited icon */
1103                 if ( banIconSwitch )
1104                 {
1105                     f32 elapse = OSTicksToMilliseconds( OSDiffTick( OSGetTick(), banIconTime ) );
1106 
1107                     switch ( banIconMode )
1108                     {
1109                     case eAlphaInIcon: /* AlphaIn (250ms) */
1110                         banIconAlpha = ( u8 )( 255.9f * ( elapse / 250.f ) );
1111                         if ( elapse >= 250.f )
1112                         {
1113                             banIconTime  = OSGetTick();
1114                             banIconMode  = ePauseIcon;
1115                             banIconAlpha = 255;
1116                         }
1117                         break;
1118                     case ePauseIcon: /* Pause (1000ms) */
1119                         if ( elapse >= 1000.f )
1120                         {
1121                             banIconTime = OSGetTick();
1122                             banIconMode = eAlphaOutIcon;
1123                         }
1124                         break;
1125                     case eAlphaOutIcon: /* AlphaOut (250ms) */
1126                         banIconAlpha = ( u8 )( 255.9f * ( ( 250.f - elapse ) / 250.f ) );
1127                         if ( elapse >= 250.f )
1128                         {
1129                             banIconAlpha  = 0;
1130                             banIconSwitch = OFF;
1131                         }
1132                         break;
1133                     }
1134 
1135                     DrawBanIcon( banIconAlpha );
1136                 }
1137             }
1138         }
1139         DEMODoneRender();
1140 
1141         /* Process executed when the RESET or Power Button is pressed */
1142         if(reset_called)
1143         {
1144             /*When other than the HOME Menu, go straight on to reset */
1145             if( homeBtnSwitch == OFF )
1146             {
1147                 OSRestart(0);
1148             }
1149             /* If the HOME Menu is running, reset after black-out */
1150             else
1151             {
1152                 HBMStartBlackOut();
1153             }
1154             reset_called = false;
1155         }
1156 
1157         if(power_called)
1158         {
1159             OSReturnToMenu();
1160         }
1161     }
1162 
1163     /* Release various items */
1164     HBMDelete( );
1165 
1166     HBMDeleteSound();
1167     freeMem2( sound_buf );
1168     freeMem2( hbmInfo.mem );
1169     freeMem2( hbmInfo.layoutBuf );
1170     freeMem2( hbmInfo.spkSeBuf );
1171     freeMem2( hbmInfo.msgBuf );
1172     freeMem2( hbmInfo.configBuf );
1173     freeMem2( netInfo.layoutBuf );
1174     freeMem2( netInfo.msgBuf );
1175     freeMem2( tplGraphic );
1176     freeMem2( tplGraphic_Test );
1177 
1178     OSReport("Mem1Free = %d\n", MEMGetTotalFreeSizeForExpHeap((MEMHeapHandle)DemoAllocator1.pHeap) );
1179     OSReport("Mem2Free = %d\n", MEMGetTotalFreeSizeForExpHeap((MEMHeapHandle)DemoAllocator2.pHeap) );
1180 }
1181 
1182