1 /*---------------------------------------------------------------------------*
2 Project: networkmanual_jpeg
3 File: networkmanual_jpeg.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/tmcc/tmcc_jpeg.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
allocMem1(u32 size)184 static void* allocMem1( u32 size )
185 {
186 return MEMAllocFromAllocator( &DemoAllocator1, size );
187 }
188
freeMem1(void * ptr)189 static u8 freeMem1( void* ptr )
190 {
191 MEMFreeToAllocator( &DemoAllocator1, ptr );
192 return 1;
193 }
194
allocMem2(u32 size)195 static void* allocMem2( u32 size )
196 {
197 return MEMAllocFromAllocator( &DemoAllocator2, size );
198 }
199
freeMem2(void * ptr)200 static u8 freeMem2( void* ptr )
201 {
202 MEMFreeToAllocator( &DemoAllocator2, ptr );
203 return 1;
204 }
205
206 /* Event/sound callback function */
SoundCallback(int evt,int arg)207 static int SoundCallback( int evt, int arg )
208 {
209 OSReport( "SoundCallback: %d, %d\n", evt, arg );
210 return HBMSEV_RET_NONE;
211 }
212
ResetCallback()213 static void ResetCallback()
214 {
215 reset_called = true;
216 }
217
PowerCallback()218 static void PowerCallback()
219 {
220 power_called = true;
221 }
222
ReadNandFile(char * fileName,CNTHandle * cnt,u32 * fileSize=NULL)223 static void* ReadNandFile(
224 char *fileName,
225 CNTHandle* cnt,
226 u32* fileSize = NULL
227 )
228 {
229 CNTFileInfo fileInfo;
230 u32 l_fileSize;
231 void* buffer; // Pointer to the buffer
232 s32 rv; // for checking error
233
234 // Open the filename to fileInfo
235 rv = CNTOpen(cnt, fileName, &fileInfo);
236
237 if (rv != CNT_RESULT_OK)
238 {
239 OSReport("Cannot open file \"%s\"", fileName);
240 OSHalt("");
241 }
242
243 // Get the size of the files
244 l_fileSize = CNTGetLength(&fileInfo);
245 if( fileSize )
246 {
247 *fileSize = l_fileSize;
248 }
249
250 // Allocate buffers to read the files.
251 // Note that pointers returned by Allocator are all 32byte aligned.
252 buffer = (u8*)allocMem2( OSRoundUp32B( l_fileSize ) );
253
254 // Reads filenames all at one time
255 rv = CNTRead(&fileInfo, (void*)buffer, (u32)OSRoundUp32B( l_fileSize ));
256
257 // If CNTRead succeeds, it returns length (the number of bytes).
258 if (rv < 0)
259 {
260 OSReport("%d\n",rv);
261 OSHalt("Error occurred when issuing read for the first file");
262 }
263
264 CNTClose(&fileInfo);
265
266 return buffer;
267 }
268
269 // Open an LZ77-compressed file
ReadNandFileLZ(char * fileName,CNTHandle * cnt,u32 * fileSize=NULL)270 static void* ReadNandFileLZ(
271 char *fileName,
272 CNTHandle* cnt,
273 u32* fileSize = NULL
274 )
275 {
276 void* compbuffer; // Pointer to the buffer
277 void* buffer; // Pointer to the buffer
278 u32 l_fileSize = 0;
279
280 // Calculate the file size after decompression
281 compbuffer = ReadNandFile( fileName, cnt );
282 l_fileSize = CXGetUncompressedSize( compbuffer );
283 if( fileSize )
284 {
285 *fileSize = l_fileSize;
286 }
287
288 // Allocate the buffer for decompression
289 buffer = (u8*)allocMem2( OSRoundUp32B(l_fileSize) );
290
291 // Decompress the data
292 CXUncompressLZ( compbuffer, buffer );
293 DCFlushRange( buffer, l_fileSize );
294
295 // Deallocate the region used before the decompression
296 freeMem2( compbuffer );
297
298 return buffer;
299 }
300
301 // Open a Huffman-compressed file
ReadNandFileHuff(char * fileName,CNTHandle * cnt,u32 * fileSize=NULL)302 static void* ReadNandFileHuff(
303 char *fileName,
304 CNTHandle* cnt,
305 u32* fileSize = NULL
306 )
307 {
308 void* compbuffer; // Pointer to the buffer
309 void* buffer; // Pointer to the buffer
310 u32 l_fileSize = 0;
311
312 compbuffer = ReadNandFile( fileName, cnt );
313
314 // Calculate the file size after decompression
315 l_fileSize = CXGetUncompressedSize( compbuffer );
316 if( fileSize )
317 {
318 *fileSize = l_fileSize;
319 }
320
321 // Allocate the buffer for decompression
322 buffer = (u8*)allocMem2( OSRoundUp32B(l_fileSize) );
323
324 // Decompress the data
325 CXUncompressHuffman( compbuffer, buffer );
326 DCFlushRange( buffer, l_fileSize );
327
328 // Deallocate the region used before the decompression
329 freeMem2( compbuffer );
330
331 return buffer;
332 }
333
334 /* Initial settings */
Init()335 static void Init()
336 {
337 char dirName[] = "HomeButton3";
338 char nameBuf[64];
339
340 VIInit();
341 switch (VIGetTvFormat())
342 {
343 case VI_NTSC:
344 sTvmode = 0;
345 break;
346 case VI_PAL:
347 sTvmode = 1;
348 break;
349 default:
350 OSHalt("VIGetTvFormat()t: invalid TV format\n");
351 break;
352 }
353
354 DEMOInit(&sRMObj[sTvmode]);
355
356 SCInit();
357 while ( SC_STATUS_OK != SCCheckStatus() ) {} /* Wait for completion of SCInit() */
358 DVDInit();
359 OSInitFastCast();
360
361 #ifdef ENABLE_BALANCE_BOARD
362 WPADRegisterBLCWorkarea( workarea );
363 #endif // ENABLE_BALANCE_BOARD
364 WPADRegisterAllocator( allocMem2, freeMem2 );
365
366 PADInit();
367 KPADInit();
368
369 /* Load icon */
370 /* Initialization for NAND loading */
371 CNTInit();
372
373 // shared
374 if(CNTInitHandle(TARGET_SHARED, &CntHandle_Shared, &DemoAllocator2) != CNT_RESULT_OK)
375 {
376 OSHalt("Initializing SHARED handle was not finished:\n");
377 }
378
379 // hbm sound
380 if(CNTInitHandle(TARGET_SOUND, &CntHandle_SharedSound, &DemoAllocator2) != CNT_RESULT_OK)
381 {
382 OSHalt("Initializing SOUND handle was not finished:\n");
383 }
384
385 // hbm message
386 if(CNTInitHandle(TARGET_SAMPLE, &CntHandle_Sample, &DemoAllocator2) != CNT_RESULT_OK)
387 {
388 OSHalt("Initializing SAMPLE handle was not finished:\n");
389 }
390
391 // NWM message
392 if(CNTInitHandle(TARGET_NWM, &CntHandle_Nwm, &DemoAllocator2) != CNT_RESULT_OK)
393 {
394 OSHalt("Initializing NWM handle was not finished:\n");
395 }
396
397 strcpy( nameBuf, dirName );
398 strcat( nameBuf, "/homeBtnIcon.tpl" );
399 sIconTpl = ( TPLPalettePtr )ReadNandFile( nameBuf, &CntHandle_Shared );
400 TPLBind( sIconTpl );
401
402 /* Power switch and reset switch callbacks */
403 OSSetResetCallback(ResetCallback);
404 OSSetPowerCallback(PowerCallback);
405
406 reset_called = false;
407 power_called = false;
408 }
409
410
411 /* Projection settings */
SetProjection(int wideflag)412 static void SetProjection( int wideflag )
413 {
414 Mtx44 projMtx;
415
416 if( !wideflag )
417 {
418 DEMOReInit(&sRMObj[sTvmode]);
419 MTXOrtho(projMtx, 228.0f, -228.0f, -304.0f, 304.0f, 0.0f, 500.0f);
420 }
421 else
422 {
423 DEMOReInit(&sRMObjWide[sTvmode]);
424 MTXOrtho(projMtx, 228.0f, -228.0f, -416.0f, 416.0f, 0.0f, 500.0f);
425 }
426
427 GXSetProjection(projMtx, GX_ORTHOGRAPHIC);
428 }
429
430 /* Initialize GX */
InitGX()431 static void InitGX()
432 {
433 GXClearVtxDesc();
434
435 GXSetVtxAttrFmt(GX_VTXFMT4, GX_VA_POS, GX_POS_XY, GX_F32, 0);
436 GXSetVtxAttrFmt(GX_VTXFMT4, GX_VA_CLR0, GX_CLR_RGB, GX_RGB8, 0);
437 GXSetVtxDesc(GX_VA_POS, GX_DIRECT);
438 GXSetVtxDesc(GX_VA_CLR0, GX_DIRECT);
439
440 GXSetNumChans(1);
441 GXSetNumTexGens(0);
442 GXSetNumTevStages(1);
443 GXSetTevOrder(GX_TEVSTAGE0, GX_TEXCOORD_NULL, GX_TEXMAP_NULL, GX_COLOR0A0);
444 GXSetTevOp(GX_TEVSTAGE0, GX_PASSCLR);
445
446 GXSetBlendMode(GX_BM_NONE, GX_BL_ZERO, GX_BL_ZERO, GX_LO_CLEAR);
447 GXSetZMode(GX_TRUE, GX_LEQUAL, GX_TRUE);
448 GXSetCurrentMtx( GX_PNMTX1 );
449 }
450
451 /* Render the "Prohibited" icon */
DrawBanIcon(u8 alpha)452 static void DrawBanIcon( u8 alpha )
453 {
454 GXTexObj texObj;
455 Mtx view_mtx ;
456 // mtx
457 MTXIdentity( view_mtx ) ;
458 GXLoadPosMtxImm( view_mtx, GX_PNMTX1 ) ;
459 GXSetCurrentMtx( GX_PNMTX1 ) ;
460
461 GXClearVtxDesc();
462
463 GXSetVtxAttrFmt(GX_VTXFMT5, GX_VA_POS, GX_POS_XY, GX_S16, 0);
464 GXSetVtxAttrFmt(GX_VTXFMT5, GX_VA_TEX0, GX_TEX_ST, GX_S16, 0);
465 GXSetVtxDesc(GX_VA_POS, GX_DIRECT);
466 GXSetVtxDesc(GX_VA_TEX0, GX_DIRECT);
467
468 GXSetNumChans(1);
469 GXSetChanCtrl(GX_COLOR0A0, GX_FALSE, GX_SRC_VTX, GX_SRC_VTX, GX_LIGHT_NULL, GX_DF_NONE, GX_AF_NONE);
470
471 GXSetNumTexGens(1);
472 GXSetTexCoordGen(GX_TEXCOORD0, GX_TG_MTX2x4, GX_TG_TEX0, GX_IDENTITY);
473
474 GXSetNumTevStages(1);
475 GXSetTevColor(GX_TEVREG0, (GXColor){255, 255, 255, alpha});
476 GXSetTevOrder(GX_TEVSTAGE0, GX_TEXCOORD0, GX_TEXMAP0, GX_COLOR_NULL);
477 GXSetTevColorIn(GX_TEVSTAGE0, GX_CC_ZERO, GX_CC_ZERO, GX_CC_ZERO, GX_CC_TEXC);
478 GXSetTevColorOp(GX_TEVSTAGE0, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_TRUE, GX_TEVPREV);
479 GXSetTevAlphaIn(GX_TEVSTAGE0, GX_CA_ZERO, GX_CA_A0, GX_CA_TEXA, GX_CA_ZERO);
480 GXSetTevAlphaOp(GX_TEVSTAGE0, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_TRUE, GX_TEVPREV);
481
482 GXSetBlendMode(GX_BM_BLEND, GX_BL_SRCALPHA, GX_BL_INVSRCALPHA, GX_LO_CLEAR);
483 GXSetZMode(GX_FALSE, GX_LEQUAL, GX_FALSE);
484
485 TPLGetGXTexObjFromPalette( sIconTpl, &texObj, 0 );
486 GXLoadTexObj( &texObj, GX_TEXMAP0 );
487
488 /* The rendering position may be anywhere inside the safe frame. */
489 GXBegin( GX_QUADS, GX_VTXFMT5, 4 );
490 GXPosition2s16( -256 + 0, 188 - 56 );
491 GXTexCoord2s16( 0, 1 );
492 GXPosition2s16( -256 + 0, 188 + 0 );
493 GXTexCoord2s16( 0, 0 );
494 GXPosition2s16( -256 + 56, 188 + 0 );
495 GXTexCoord2s16( 1, 0 );
496 GXPosition2s16( -256 + 56, 188 - 56 );
497 GXTexCoord2s16( 1, 1 );
498 GXEnd();
499 }
500
InitHomeButtonInfo(HBMDataInfo * pHbmInfo,HBMNetworkManualInfo * pNetInfo)501 static void InitHomeButtonInfo( HBMDataInfo* pHbmInfo, HBMNetworkManualInfo* pNetInfo )
502 {
503 char dirName[] = "HomeButton3";
504
505 char nameBuf[64];
506 char nameNwmBuf[64];
507
508 /* Create filename */
509 strcpy( nameBuf, dirName );
510 strcpy( nameNwmBuf, dirName );
511 /* Switching as necessary according to the language setting */
512 pHbmInfo->region=SCGetLanguage();
513 switch (pHbmInfo->region)
514 {
515 case SC_LANG_JAPANESE:
516 strcat( nameBuf, "/LZ77_homeBtn.arc" );
517 strcat( nameNwmBuf, "/LZ77_homeBtn_nwm_jpn.arc" );
518 break;
519 case SC_LANG_ENGLISH:
520 strcat( nameBuf, "/LZ77_homeBtn_ENG.arc" );
521 strcat( nameNwmBuf, "/LZ77_homeBtn_nwm_eng.arc" );
522 break;
523 case SC_LANG_GERMAN:
524 strcat( nameBuf, "/LZ77_homeBtn_GER.arc" );
525 strcat( nameNwmBuf, "/LZ77_homeBtn_nwm_ger.arc" );
526 break;
527 case SC_LANG_FRENCH:
528 strcat( nameBuf, "/LZ77_homeBtn_FRA.arc" );
529 strcat( nameNwmBuf, "/LZ77_homeBtn_nwm_fra.arc" );
530 break;
531 case SC_LANG_SPANISH:
532 strcat( nameBuf, "/LZ77_homeBtn_SPA.arc" );
533 strcat( nameNwmBuf, "/LZ77_homeBtn_nwm_spa.arc" );
534 break;
535 case SC_LANG_ITALIAN:
536 strcat( nameBuf, "/LZ77_homeBtn_ITA.arc" );
537 strcat( nameNwmBuf, "/LZ77_homeBtn_nwm_ita.arc" );
538 break;
539 case SC_LANG_DUTCH:
540 strcat( nameBuf, "/LZ77_homeBtn_NED.arc" );
541 strcat( nameNwmBuf, "/LZ77_homeBtn_nwm_ned.arc" );
542 break;
543 default:
544 pHbmInfo->region=SC_LANG_JAPANESE;
545 strcat( nameBuf, "/LZ77_homeBtn.arc" );
546 strcat( nameNwmBuf, "/LZ77_homeBtn_nwm_jpn.arc" );
547 break;
548 }
549 pHbmInfo->layoutBuf = ReadNandFileLZ( nameBuf, &CntHandle_Shared );
550 pNetInfo->layoutBuf = ReadNandFileLZ( nameNwmBuf, &CntHandle_Nwm );
551
552 strcpy( nameBuf, dirName );
553 strcat( nameBuf, "/Huf8_SpeakerSe.arc" );
554 pHbmInfo->spkSeBuf = ReadNandFileHuff( nameBuf, &CntHandle_Shared );
555
556 strcpy( nameBuf, dirName );
557 #ifdef HBM_NO_SAVE
558 strcat( nameBuf, "/home_nosave.csv" );
559 #else
560 strcat( nameBuf, "/home.csv" );
561 #endif
562 // CSV files are not loaded because they are shared.
563 pHbmInfo->msgBuf = ReadNandFile( nameBuf, &CntHandle_Sample );
564 pNetInfo->msgBuf = ReadNandFile( "/HomeButton3/network.csv", &CntHandle_Sample, NULL );
565
566 strcpy( nameBuf, dirName );
567 strcat( nameBuf, "/config.txt" );
568 pHbmInfo->configBuf = ReadNandFile( nameBuf, &CntHandle_Shared, &pHbmInfo->configBufSize );
569
570 pHbmInfo->sound_callback = SoundCallback;
571 pHbmInfo->backFlag = OFF;
572 pHbmInfo->cursor = 0;
573 pHbmInfo->adjust.x = 832.f / 608.f;
574 pHbmInfo->adjust.y = 1.0f;
575 pHbmInfo->frameDelta = 1.0f;
576
577 /* Memory allocation settings */
578 pHbmInfo->mem = allocMem2( HBM_MEM_SIZE );
579 pHbmInfo->memSize = HBM_MEM_SIZE;
580 pHbmInfo->pAllocator = NULL;
581
582 /* Dialog message settings are applied to the WiiWare manual button messages as well. */
583 pHbmInfo->messageFlag = MESSAGE_FLAG;
584 }
585
586 /* Initialize sounds */
InitSound()587 static void InitSound()
588 {
589 char nameBuf[64];
590 strcpy( nameBuf, "HomeButtonSe/Huf8_HomeButtonSe.arc" );
591
592 /* Load sound data for AX use */
593 sound_data_ptr = (u8*)ReadNandFileHuff( nameBuf, &CntHandle_SharedSound );
594 /* Allocate a buffer for sounds */
595 sound_buf = (u8*)allocMem2( HBM_MEM_SIZE_SOUND );
596 HBMCreateSound( sound_data_ptr, sound_buf, HBM_MEM_SIZE_SOUND );
597 }
598
599 /* Cursor position initialization */
InitControllerData(HBMControllerData * pConData)600 static void InitControllerData( HBMControllerData* pConData )
601 {
602 int i;
603 for( i = 0; i < WPAD_MAX_CONTROLLERS; i++ )
604 {
605 pConData->wiiCon[i].pos.x = 0.f;
606 pConData->wiiCon[i].pos.y = 0.f;
607 pConData->wiiCon[i].use_devtype = WPAD_DEV_CORE;
608 }
609 }
610
611 /* Absolute value clamp */
AbsClamp(f32 val,f32 max)612 static f32 AbsClamp( f32 val, f32 max )
613 {
614 return ( ( val > max ) ? max : ( val < -max ) ? -max : val );
615 }
616
617 /* Cursor movement processing for analog stick */
calcAnalogCursorPos(f32 stickX,f32 stickY,Vec2 * pos)618 static int calcAnalogCursorPos( f32 stickX, f32 stickY, Vec2* pos )
619 {
620 f32 x,y;
621 x = ( stickX / scStickMoveCoe );
622 y = ( stickY / scStickMoveCoe );
623 x = AbsClamp( x, 1.0f );
624 y = AbsClamp( y, 1.0f );
625 if( x == 0.0f && y == 0.0f ) return FALSE;
626 pos->x = AbsClamp( pos->x + x, 1.0f );
627 pos->y = AbsClamp( pos->y - y, 1.0f );
628 return TRUE;
629 }
630
631 /* Cursor movement processing when using +Control key */
calcDigitalCursorPos(u32 button,Vec2 * pos)632 static int calcDigitalCursorPos( u32 button, Vec2* pos )
633 {
634 const float spd =1.0f / scStickMoveCoe;
635 const float spd2= spd * 0.7071f;
636
637 button&=KPAD_CL_BUTTON_UP|KPAD_CL_BUTTON_LEFT|KPAD_CL_BUTTON_DOWN|KPAD_CL_BUTTON_RIGHT;
638 switch (button)
639 {
640 case KPAD_CL_BUTTON_UP: pos->y-=spd; break;
641 case KPAD_CL_BUTTON_LEFT: pos->x-=spd; break;
642 case KPAD_CL_BUTTON_DOWN: pos->y+=spd; break;
643 case KPAD_CL_BUTTON_RIGHT: pos->x+=spd; break;
644 case KPAD_CL_BUTTON_UP |KPAD_CL_BUTTON_LEFT: pos->y-=spd2; pos->x-=spd2; break;
645 case KPAD_CL_BUTTON_UP |KPAD_CL_BUTTON_RIGHT: pos->y-=spd2; pos->x+=spd2; break;
646 case KPAD_CL_BUTTON_DOWN|KPAD_CL_BUTTON_LEFT: pos->y+=spd2; pos->x-=spd2; break;
647 case KPAD_CL_BUTTON_DOWN|KPAD_CL_BUTTON_RIGHT: pos->y+=spd2; pos->x+=spd2; break;
648 default: return FALSE;
649 }
650 pos->x = AbsClamp( pos->x, 1.0f );
651 pos->y = AbsClamp( pos->y, 1.0f );
652 return TRUE;
653 }
654
655
656 /* Change the adjust value depending on the display mode */
SetAdjustValue(HBMDataInfo * pHbmInfo,int wideflag)657 static void SetAdjustValue( HBMDataInfo* pHbmInfo, int wideflag )
658 {
659 if( !wideflag )
660 {
661 /* 4:3 */
662 pHbmInfo->adjust.x = 1.0f;
663 pHbmInfo->adjust.y = 1.0f;
664 }
665 else
666 {
667 /* 16:9 */
668 pHbmInfo->adjust.x = 832.f / 608.f;
669 pHbmInfo->adjust.y = 1.0f;
670 }
671
672 if(sTvmode == 0)
673 {
674 /* NTSC: 60Hz */
675 pHbmInfo->frameDelta = 1.0f;
676 }
677 else
678 {
679 /* PAL: 50Hz */
680 pHbmInfo->frameDelta = 1.2f;
681 }
682 }
683
684 /* Main function */
main()685 void main()
686 {
687 Mtx mv;
688 HBMDataInfo hbmInfo;
689 HBMNetworkManualInfo netInfo;
690 HBMControllerData conData;
691 int homeBtnSwitch = OFF; /* HOME button switch */
692 int drawModeFlag = OFF; /* Flag for toggling between 4:3 and 16:9 displays */
693 int banIconSwitch = OFF; /* HOME button prohibited icon */
694 s8 banIconMode = 0; /* 0: AlphaIn, 1: Pause, 2: AlphaOut */
695 OSTick banIconTime = 0;
696 u8 banIconAlpha = 0;
697 s32 wpad_result[WPAD_MAX_CONTROLLERS];
698 u32 pad_type[WPAD_MAX_CONTROLLERS];
699 Vec2 pos[WPAD_MAX_CONTROLLERS];/* Position of the Pointer */
700 int input_classic;
701 int i;
702
703 s32 kpad_read[WPAD_MAX_CONTROLLERS];
704 GXRenderModeObj* pRm;
705
706 Init();
707
708 /* Viewport settings */
709 pRm = DEMOGetRenderModeObj();
710 MTXIdentity(mv);
711 GXLoadPosMtxImm(mv, GX_PNMTX1);
712 SetProjection( drawModeFlag );
713 /* No culling */
714 GXSetCullMode( GX_CULL_NONE );
715
716 netInfo.graphicBuf = NULL;
717
718 /* Display the operation method on the console */
719 OSReport( "------------------------------\n" );
720 OSReport( "HOME Button Menu Sample\n\n" );
721 OSReport( "+ : Show Icon\n" );
722 OSReport( "2 : Switch Video Mode\n" );
723 OSReport( "------------------------------\n" );
724
725 OSReport("Mem1Free = %d\n", MEMGetTotalFreeSizeForExpHeap((MEMHeapHandle)DemoAllocator1.pHeap) );
726 OSReport("Mem2Free = %d\n", MEMGetTotalFreeSizeForExpHeap((MEMHeapHandle)DemoAllocator2.pHeap) );
727
728 while( 1 )
729 {
730 /* Wii controllers */
731 for( int i = 0; i < WPAD_MAX_CONTROLLERS; i++ )
732 {
733 wpad_result[i] = WPADProbe( i, &pad_type[i] );
734 conData.wiiCon[i].use_devtype = pad_type[i];
735 kpad_read[i] = KPADRead( i, &sKpads[i][0], KPAD_MAX_READ_BUFS );
736
737 switch( wpad_result[i] )
738 {
739 /* In the following error states, the value gotten by KPADRead is applied as-is. */
740 case WPAD_ERR_BUSY:
741 case WPAD_ERR_TRANSFER:
742 case WPAD_ERR_INVALID:
743 case WPAD_ERR_CORRUPTED:
744 case WPAD_ERR_NONE:
745 conData.wiiCon[i].kpad = &sKpads[i][0];
746
747 {
748 /*
749 According to guidelines, if there is input from a Classic Controller, that input is prioritized and inherits DPD coordinates.
750
751 Specify the DPD absolute coordinates when there is no Classic Controller input.
752 */
753
754 input_classic = calcDigitalCursorPos(
755 conData.wiiCon[i].kpad->ex_status.cl.hold,
756 &conData.wiiCon[i].pos );
757
758
759 input_classic = input_classic | calcAnalogCursorPos(
760 conData.wiiCon[i].kpad->ex_status.cl.lstick.x,
761 conData.wiiCon[i].kpad->ex_status.cl.lstick.y,
762 &conData.wiiCon[i].pos );
763
764 if( !input_classic && conData.wiiCon[i].kpad->dpd_valid_fg > 0)
765 {
766 conData.wiiCon[i].pos.x = conData.wiiCon[i].kpad->pos.x;
767 conData.wiiCon[i].pos.y = conData.wiiCon[i].kpad->pos.y;
768 }
769 }
770
771 /* Change the rendering mode */
772 if( !homeBtnSwitch && sKpads[i][0].trig == KPAD_BUTTON_2 )
773 {
774 drawModeFlag = !drawModeFlag;
775 SetProjection( drawModeFlag );
776 SetAdjustValue( &hbmInfo, drawModeFlag );
777 pRm = DEMOGetRenderModeObj();
778 }
779
780 if( sKpads[i][0].trig == KPAD_BUTTON_1 )
781 {
782 VISetBlack(FALSE);
783 VIFlush();
784 }
785
786 if ( !homeBtnSwitch && !banIconSwitch && sKpads[i][0].trig == KPAD_BUTTON_PLUS )
787 {
788 banIconMode = eAlphaInIcon;
789 banIconSwitch = ON;
790 banIconTime = OSGetTick();
791 banIconAlpha = 0;
792 }
793 break;
794 /* Apply NULL in the following error states. */
795 case WPAD_ERR_NO_CONTROLLER:
796 default:
797 conData.wiiCon[i].kpad = NULL;
798 break;
799 }
800 }
801 if( !homeBtnSwitch && !banIconSwitch )
802 {
803 BOOL press_home = FALSE;
804
805 for ( int i = 0; i < WPAD_MAX_CONTROLLERS; i++ )
806 {
807 if ( WPAD_ERR_NONE != wpad_result[i] ) continue;
808
809 /* When HOME is pressed on the Wii Remote or Classic Controller */
810 if ( sKpads[i][0].trig == KPAD_BUTTON_HOME ||
811 sKpads[i][0].ex_status.cl.trig==KPAD_CL_BUTTON_HOME )
812 {
813 OSReport("press_home = TRUE\n");
814 press_home = TRUE;
815 homeBtnSwitch = ON;
816 break;
817 }
818 }
819 if ( press_home )
820 {
821 InitControllerData( &conData );
822 InitHomeButtonInfo( &hbmInfo, &netInfo );
823
824 /* Set the adjust value depending on the screen mode */
825 SetAdjustValue( &hbmInfo, drawModeFlag );
826
827 /* Create the manual image */
828 {
829 u8 workmem[TMCC_JPEG_WORKAREA_SIZE];
830 u8 *jpgbuffer = NULL;
831 u32 jpgsize;
832 s32 buffersize;
833
834 netInfo.texFmt = GX_TF_RGB565;
835
836 if( hbmInfo.region == SC_LANG_JAPANESE )
837 jpgbuffer = (u8*)ReadNandFile( "sample.jpg", &CntHandle_Sample, &jpgsize );
838 else
839 jpgbuffer = (u8*)ReadNandFile( "s_sample.jpg", &CntHandle_Sample, &jpgsize );
840
841 HBMJPGGetTextureBufferSize ( (void *)workmem, &buffersize, &netInfo.width, &netInfo.height, (void *)jpgbuffer, jpgsize, GX_TF_RGB565 );
842 netInfo.graphicBuf = (u8*)allocMem2( (u32)buffersize );
843 HBMJPGMakeTextureBuffer ( (void *)workmem, (void *)netInfo.graphicBuf, (u32)buffersize, (void *)jpgbuffer, jpgsize, GX_TF_RGB565 );
844 freeMem2( jpgbuffer );
845 }
846 /* HBM initialization */
847 HBMCreate( &hbmInfo );
848 HBMCreateEx( &netInfo );
849
850 HBMInit();
851
852 /* Adjust ON */
853 HBMSetAdjustFlag( TRUE );
854
855 /* Load sounds */
856 InitSound();
857
858 OSReport("Mem1Free = %d\n", MEMGetTotalFreeSizeForExpHeap((MEMHeapHandle)DemoAllocator1.pHeap) );
859 OSReport("Mem2Free = %d\n", MEMGetTotalFreeSizeForExpHeap((MEMHeapHandle)DemoAllocator2.pHeap) );
860 }
861 }
862
863 if( homeBtnSwitch )
864 {
865 /* Update SE (sound effect) */
866 HBMUpdateSound();
867
868 /* Update the HOME Menu */
869 if( HBMCalc( &conData ) >= HBM_SELECT_HOMEBTN )
870 {
871 /* The number of the decided-upon button is returned */
872 OSReport("Select Btn:%d\n", HBMGetSelectBtnNum());
873 OSReport("Reassigned:%d\n", HBMIsReassignedControllers());
874
875
876 /* Process executed when returning from the HOME Menu */
877 switch( HBMGetSelectBtnNum() )
878 {
879 case HBM_SELECT_HOMEBTN:
880 break;
881 /* Move to the Wii Menu */
882 case HBM_SELECT_BTN1:
883 OSReport( "Return to WiiMenu.\n" );
884 OSReturnToMenu();
885 break;
886 /* Reset */
887 case HBM_SELECT_BTN2:
888 OSReport( "Reset.\n" );
889 OSRestart( 0 );
890 break;
891 case HBM_SELECT_BTN4:
892 OSReport( "Jump to NetworkManual.\n" );
893 OSLaunchManualViewer( 0 );
894 break;
895 default:
896 break;
897 }
898 /* Release various items */
899 HBMDelete( );
900 HBMDeleteSound();
901
902 freeMem2( sound_buf );
903 freeMem2( hbmInfo.mem );
904 freeMem2( hbmInfo.layoutBuf );
905 freeMem2( hbmInfo.spkSeBuf );
906 freeMem2( hbmInfo.msgBuf );
907 freeMem2( hbmInfo.configBuf );
908 freeMem2( sound_data_ptr );
909 freeMem2( netInfo.graphicBuf );
910 freeMem2( netInfo.layoutBuf );
911 freeMem2( netInfo.msgBuf );
912
913 homeBtnSwitch = OFF;
914
915 OSReport("Mem1Free = %d\n", MEMGetTotalFreeSizeForExpHeap((MEMHeapHandle)DemoAllocator1.pHeap) );
916 OSReport("Mem2Free = %d\n", MEMGetTotalFreeSizeForExpHeap((MEMHeapHandle)DemoAllocator2.pHeap) );
917 }
918
919 }
920
921 /* Calculate the Pointer position */
922 for( i = 0; i < PAD_MAX_CONTROLLERS; i++ )
923 {
924 /* For Wii */
925 if ( WPAD_ERR_NONE == wpad_result[i] &&
926 0 < kpad_read[i] &&
927 conData.wiiCon[i].kpad )
928 {
929 if( !homeBtnSwitch )
930 {
931 if( sKpads[i]->dev_type == WPAD_DEV_CLASSIC )
932 {
933 pos[i].x = conData.wiiCon[i].pos.x;
934 pos[i].y = conData.wiiCon[i].pos.y;
935 }
936 else
937 {
938 pos[i].x = conData.wiiCon[i].kpad->pos.x;
939 pos[i].y = conData.wiiCon[i].kpad->pos.y;
940 }
941
942 pos[i].x *= pRm->fbWidth * 0.5f;
943 pos[i].y *= pRm->xfbHeight * 0.5f;
944
945 if( drawModeFlag )
946 {
947 pos[i].x *= hbmInfo.adjust.x;
948 pos[i].y *= hbmInfo.adjust.y;
949 }
950 }
951 }
952 }
953
954 DEMOBeforeRender();
955 {
956 InitGX();
957 if( homeBtnSwitch )
958 {
959 /* Render the HOME Menu */
960 HBMDraw();
961 }
962 /* Render the specified cursor inside the HOME Menu */
963 if( !homeBtnSwitch )
964 {
965 for( i = 0; i < PAD_MAX_CONTROLLERS; i++ )
966 {
967 if( conData.wiiCon[i].kpad )
968 {
969 /* Render the Wii Pointer */
970 GXBegin( GX_QUADS, GX_VTXFMT4, 4 );
971 GXPosition2f32( -10 + pos[i].x, -10 - pos[i].y );
972 GXColor3u8( 255, 255, 255 );
973 GXPosition2f32( -10 + pos[i].x, 10 - pos[i].y );
974 GXColor3u8( 255, 255, 255 );
975 GXPosition2f32( 10 + pos[i].x, 10 - pos[i].y );
976 GXColor3u8( 255, 255, 255 );
977 GXPosition2f32( 10 + pos[i].x, -10 - pos[i].y );
978 GXColor3u8( 255, 255, 255 );
979 GXEnd();
980 }
981 }
982
983 /* Render the HOME Menu prohibited icon */
984 if ( banIconSwitch )
985 {
986 f32 elapse = OSTicksToMilliseconds( OSDiffTick( OSGetTick(), banIconTime ) );
987
988 switch ( banIconMode )
989 {
990 case eAlphaInIcon: /* AlphaIn (250ms) */
991 banIconAlpha = ( u8 )( 255.9f * ( elapse / 250.f ) );
992 if ( elapse >= 250.f )
993 {
994 banIconTime = OSGetTick();
995 banIconMode = ePauseIcon;
996 banIconAlpha = 255;
997 }
998 break;
999 case ePauseIcon: /* Pause (1000ms) */
1000 if ( elapse >= 1000.f )
1001 {
1002 banIconTime = OSGetTick();
1003 banIconMode = eAlphaOutIcon;
1004 }
1005 break;
1006 case eAlphaOutIcon: /* AlphaOut (250ms) */
1007 banIconAlpha = ( u8 )( 255.9f * ( ( 250.f - elapse ) / 250.f ) );
1008 if ( elapse >= 250.f )
1009 {
1010 banIconAlpha = 0;
1011 banIconSwitch = OFF;
1012 }
1013 break;
1014 }
1015
1016 DrawBanIcon( banIconAlpha );
1017 }
1018 }
1019 }
1020 DEMODoneRender();
1021
1022 /* Process executed when the RESET or Power Button is pressed */
1023 if(reset_called)
1024 {
1025 /*When other than the HOME Menu, go straight on to reset */
1026 if( homeBtnSwitch == OFF )
1027 {
1028 OSRestart(0);
1029 }
1030 /* If the HOME Menu is running, reset after black-out */
1031 else
1032 {
1033 HBMStartBlackOut();
1034 }
1035 reset_called = false;
1036 }
1037
1038 if(power_called)
1039 {
1040 OSReturnToMenu();
1041 }
1042 }
1043 }
1044
1045