1 /*---------------------------------------------------------------------------*
2 Project: hbm
3 File: homebutton.cpp
4
5 Copyright 2006-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 /* Definitions for changing the number of buttons */
18 /* #define BTN_NUM_3 */
19
20 /* Save confirmation on/off */
21 /* #define HBM_NO_SAVE */
22
23 #include <Revolution.h>
24 #include <revolution/kpad.h>
25 #include <revolution/sc.h>
26
27 #include <demo.h>
28
29 #include <string.h>
30 #include <math.h>
31
32 #include <revolution/hbm.h>
33
34 enum
35 {
36 OFF = 0,
37 ON
38 };
39
40 enum
41 {
42 eAlphaInIcon = 0,
43 ePauseIcon,
44 eAlphaOutIcon
45 };
46
47 static const f32 scStickMoveCoe = 2048.0f/72.0f; /* Amount-of-movement coefficient of the analog stick */
48 static KPADStatus sKpads[ WPAD_MAX_CONTROLLERS ][ KPAD_MAX_READ_BUFS ];
49
50 static TPLPalettePtr sIconTpl;
51
52 /* Allocate a buffer for sounds */
53 u8* sound_buf;
54 /* Read destination for the sound data from the optical disc */
55 u8* sound_data;
56
57 // Reset/Power Callback
58 static void ResetCallback();
59 static void PowerCallback();
60 static bool reset_called,power_called;
61
62 // NTSC / PAL
63 int sTvmode;
64
65 // Frame buffer size
66 u16 sFbWidth = 608;
67 u16 sFbHeight = 456;
68
69 // VI size
70 u16 viWidth = 670;
71 u16 viWidthWide = 686;
72 u16 viWidthWide_Pal = 682;
73
74 u16 viHeight = 456;
75 u16 viHeight_Pal = 542;
76
77 #ifdef ENABLE_BALANCE_BOARD
78 static u8 workarea[WPAD_BLCINT_WORK_LEN] ATTRIBUTE_ALIGN(32);
79 #endif // ENABLE_BALANCE_BOARD
80 /* RenderMode */
81 static GXRenderModeObj sRMObj[2] =
82 {
83 /* NTSC 4:3 */
84 {
85 VI_TVMODE_NTSC_INT,
86 sFbWidth,
87 sFbHeight,
88 viHeight,
89 (u16)((VI_MAX_WIDTH_NTSC - viWidth)/2),
90 (u16)((VI_MAX_HEIGHT_NTSC - viHeight)/2),
91 viWidth,
92 viHeight,
93 VI_XFBMODE_DF,
94 GX_FALSE,
95 GX_FALSE,
96 6, 6, 6, 6, 6, 6,
97 6, 6, 6, 6, 6, 6,
98 6, 6, 6, 6, 6, 6,
99 6, 6, 6, 6, 6, 6,
100 8, 8,
101 10, 12, 10,
102 8, 8,
103 },
104 /* PAL 4:3 */
105 {
106 VI_TVMODE_PAL_INT,
107 sFbWidth,
108 sFbHeight,
109 viHeight_Pal,
110 (u16)((VI_MAX_WIDTH_PAL - viWidth)/2),
111 (u16)((VI_MAX_HEIGHT_PAL - viHeight_Pal)/2),
112 viWidth,
113 viHeight_Pal,
114 VI_XFBMODE_DF,
115 GX_FALSE,
116 GX_FALSE,
117 6, 6, 6, 6, 6, 6,
118 6, 6, 6, 6, 6, 6,
119 6, 6, 6, 6, 6, 6,
120 6, 6, 6, 6, 6, 6,
121 8, 8,
122 10, 12, 10,
123 8, 8,
124 }
125 };
126
127 static GXRenderModeObj sRMObjWide[2] =
128 {
129 /* NTSC 16:9 */
130 {
131 VI_TVMODE_NTSC_INT,
132 sFbWidth,
133 sFbHeight,
134 viHeight,
135 (u16)((VI_MAX_WIDTH_NTSC - viWidth)/2),
136 (u16)((VI_MAX_HEIGHT_NTSC - viHeight)/2),
137 viWidth,
138 viHeight,
139 VI_XFBMODE_DF,
140 GX_FALSE,
141 GX_FALSE,
142 6, 6, 6, 6, 6, 6,
143 6, 6, 6, 6, 6, 6,
144 6, 6, 6, 6, 6, 6,
145 6, 6, 6, 6, 6, 6,
146 8, 8,
147 10, 12, 10,
148 8, 8,
149 },
150 /* PAL 16:9 */
151 {
152 VI_TVMODE_PAL_INT,
153 sFbWidth,
154 sFbHeight,
155 viHeight_Pal,
156 (u16)((VI_MAX_WIDTH_PAL - viWidthWide_Pal)/2),
157 (u16)((VI_MAX_HEIGHT_PAL - viHeight_Pal)/2),
158 viWidthWide_Pal,
159 viHeight_Pal,
160 VI_XFBMODE_DF,
161 GX_FALSE,
162 GX_FALSE,
163 6, 6, 6, 6, 6, 6,
164 6, 6, 6, 6, 6, 6,
165 6, 6, 6, 6, 6, 6,
166 6, 6, 6, 6, 6, 6,
167 8, 8,
168 10, 12, 10,
169 8, 8,
170 }
171 };
172
allocMem1(u32 size)173 static void* allocMem1( u32 size )
174 {
175 return MEMAllocFromAllocator( &DemoAllocator1, size );
176 }
177
freeMem1(void * ptr)178 static u8 freeMem1( void* ptr )
179 {
180 MEMFreeToAllocator( &DemoAllocator1, ptr );
181 return 1;
182 }
183
allocMem2(u32 size)184 static void* allocMem2( u32 size )
185 {
186 return MEMAllocFromAllocator( &DemoAllocator2, size );
187 }
188
freeMem2(void * ptr)189 static u8 freeMem2( void* ptr )
190 {
191 MEMFreeToAllocator( &DemoAllocator2, ptr );
192 return 1;
193 }
194
195 /* Event/sound callback function */
SoundCallback(int evt,int arg)196 static int SoundCallback( int evt, int arg )
197 {
198 OSReport( "SoundCallback: %d, %d\n", evt, arg );
199 return HBMSEV_RET_NONE;
200 }
201
ResetCallback()202 static void ResetCallback()
203 {
204 reset_called = true;
205 }
206
PowerCallback()207 static void PowerCallback()
208 {
209 power_called = true;
210 }
211
212 /* Load file */
ReadDvdFile(const char * fileName,MEMAllocator * mem,u32 * fileSize)213 static void* ReadDvdFile(
214 const char* fileName,
215 MEMAllocator* mem,
216 u32* fileSize
217 )
218 {
219 u32 fileLen, fileLenUp32;
220 void* readBuf;
221 s32 readBytes;
222
223 DVDFileInfo fileInfo;
224 if (! DVDOpen(fileName, &fileInfo))
225 {
226 return NULL;
227 }
228
229 fileLen = DVDGetLength(&fileInfo);
230 if( (fileLen % 32) != 0 )
231 {
232 fileLenUp32 = fileLen + (32 - (fileLen % 32));
233 }
234 else
235 {
236 fileLenUp32 = fileLen;
237 }
238 readBuf = MEMAllocFromAllocator(mem, fileLenUp32);
239 readBytes = DVDRead(&fileInfo, readBuf, (s32)(fileLenUp32), 0);
240 ASSERT(readBytes > 0);
241 if( fileSize )
242 *fileSize = fileLen;
243 DVDClose(&fileInfo);
244
245 return readBuf;
246 }
247
248
249 /* Initial settings */
Init()250 static void Init()
251 {
252 #ifdef BTN_NUM_3
253 char dirName[] = "hbm/HomeButton3";
254 #else
255 char dirName[] = "hbm/HomeButton2";
256 #endif
257 char nameBuf[32];
258
259 switch (VIGetTvFormat())
260 {
261 case VI_NTSC:
262 sTvmode = 0;
263 break;
264 case VI_PAL:
265 sTvmode = 1;
266 break;
267 default:
268 OSHalt("VIGetTvFormat()t: invalid TV format\n");
269 break;
270 }
271
272 DEMOInit(&sRMObj[sTvmode]);
273
274 SCInit();
275 while ( SC_STATUS_OK != SCCheckStatus() ) {} /* Wait for completion of SCInit() */
276 DVDInit();
277 OSInitFastCast();
278
279 #ifdef ENABLE_BALANCE_BOARD
280 WPADRegisterBLCWorkarea( workarea );
281 #endif // ENABLE_BALANCE_BOARD
282 WPADRegisterAllocator( allocMem2, freeMem2 );
283
284 PADInit();
285 KPADInit();
286
287 /* Load icon */
288 strcpy( nameBuf, dirName );
289 strcat( nameBuf, "/homeBtnIcon.tpl" );
290 sIconTpl = ( TPLPalettePtr )ReadDvdFile( nameBuf, &DemoAllocator1, NULL );
291 TPLBind( sIconTpl );
292
293 /* Power switch and reset switch callbacks */
294 OSSetResetCallback(ResetCallback);
295 OSSetPowerCallback(PowerCallback);
296
297 reset_called = false;
298 power_called = false;
299 }
300
301
302 /* Projection settings */
SetProjection(int wideflag)303 static void SetProjection( int wideflag )
304 {
305 Mtx44 projMtx;
306
307
308 if( !wideflag )
309 {
310 DEMOReInit(&sRMObj[sTvmode]);
311 f32 viRateX = sRMObj[sTvmode].viWidth / 670.f;
312 f32 viRateY = sRMObj[sTvmode].viHeight / 456.f;
313 MTXOrtho(projMtx, viRateY * 228.0f, -viRateY * 228.0f, -viRateX * 304.0f, viRateX * 304.0f, 0.0f, 500.0f);
314 }
315 else
316 {
317 DEMOReInit(&sRMObjWide[sTvmode]);
318 f32 viRateX = sRMObjWide[sTvmode].viWidth / 686.f;
319 f32 viRateY = sRMObjWide[sTvmode].viHeight / 456.f;
320 MTXOrtho(projMtx, viRateY * 228.0f, -viRateY * 228.0f, -viRateX * 437.0f, viRateX * 437.0f, 0.0f, 500.0f);
321 }
322
323 GXSetProjection(projMtx, GX_ORTHOGRAPHIC);
324 }
325
326 /* Initialize GX */
InitGX()327 static void InitGX()
328 {
329 GXClearVtxDesc();
330
331 GXSetVtxAttrFmt(GX_VTXFMT4, GX_VA_POS, GX_POS_XY, GX_F32, 0);
332 GXSetVtxAttrFmt(GX_VTXFMT4, GX_VA_CLR0, GX_CLR_RGB, GX_RGB8, 0);
333 GXSetVtxDesc(GX_VA_POS, GX_DIRECT);
334 GXSetVtxDesc(GX_VA_CLR0, GX_DIRECT);
335
336 GXSetNumChans(1);
337 GXSetNumTexGens(0);
338 GXSetNumTevStages(1);
339 GXSetTevOrder(GX_TEVSTAGE0, GX_TEXCOORD_NULL, GX_TEXMAP_NULL, GX_COLOR0A0);
340 GXSetTevOp(GX_TEVSTAGE0, GX_PASSCLR);
341
342 GXSetBlendMode(GX_BM_NONE, GX_BL_ZERO, GX_BL_ZERO, GX_LO_CLEAR);
343 GXSetZMode(GX_TRUE, GX_LEQUAL, GX_TRUE);
344 GXSetCurrentMtx( GX_PNMTX1 );
345 }
346
347 /* Render the "Prohibited" icon */
DrawBanIcon(u8 alpha)348 static void DrawBanIcon( u8 alpha )
349 {
350 GXTexObj texObj;
351 Mtx view_mtx ;
352 // mtx
353 MTXIdentity( view_mtx ) ;
354 GXLoadPosMtxImm( view_mtx, GX_PNMTX1 ) ;
355 GXSetCurrentMtx( GX_PNMTX1 ) ;
356
357 GXClearVtxDesc();
358
359 GXSetVtxAttrFmt(GX_VTXFMT5, GX_VA_POS, GX_POS_XY, GX_S16, 0);
360 GXSetVtxAttrFmt(GX_VTXFMT5, GX_VA_TEX0, GX_TEX_ST, GX_S16, 0);
361 GXSetVtxDesc(GX_VA_POS, GX_DIRECT);
362 GXSetVtxDesc(GX_VA_TEX0, GX_DIRECT);
363
364 GXSetNumChans(1);
365 GXSetChanCtrl(GX_COLOR0A0, GX_FALSE, GX_SRC_VTX, GX_SRC_VTX, GX_LIGHT_NULL, GX_DF_NONE, GX_AF_NONE);
366
367 GXSetNumTexGens(1);
368 GXSetTexCoordGen(GX_TEXCOORD0, GX_TG_MTX2x4, GX_TG_TEX0, GX_IDENTITY);
369
370 GXSetNumTevStages(1);
371 GXSetTevColor(GX_TEVREG0, (GXColor){255, 255, 255, alpha});
372 GXSetTevOrder(GX_TEVSTAGE0, GX_TEXCOORD0, GX_TEXMAP0, GX_COLOR_NULL);
373 GXSetTevColorIn(GX_TEVSTAGE0, GX_CC_ZERO, GX_CC_ZERO, GX_CC_ZERO, GX_CC_TEXC);
374 GXSetTevColorOp(GX_TEVSTAGE0, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_TRUE, GX_TEVPREV);
375 GXSetTevAlphaIn(GX_TEVSTAGE0, GX_CA_ZERO, GX_CA_A0, GX_CA_TEXA, GX_CA_ZERO);
376 GXSetTevAlphaOp(GX_TEVSTAGE0, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_TRUE, GX_TEVPREV);
377
378 GXSetBlendMode(GX_BM_BLEND, GX_BL_SRCALPHA, GX_BL_INVSRCALPHA, GX_LO_CLEAR);
379 GXSetZMode(GX_FALSE, GX_LEQUAL, GX_FALSE);
380
381 TPLGetGXTexObjFromPalette( sIconTpl, &texObj, 0 );
382 GXLoadTexObj( &texObj, GX_TEXMAP0 );
383
384 /* The rendering position may be anywhere inside the safe frame. */
385 GXBegin( GX_QUADS, GX_VTXFMT5, 4 );
386 GXPosition2s16( -256 + 0, 188 - 56 );
387 GXTexCoord2s16( 0, 1 );
388 GXPosition2s16( -256 + 0, 188 + 0 );
389 GXTexCoord2s16( 0, 0 );
390 GXPosition2s16( -256 + 56, 188 + 0 );
391 GXTexCoord2s16( 1, 0 );
392 GXPosition2s16( -256 + 56, 188 - 56 );
393 GXTexCoord2s16( 1, 1 );
394 GXEnd();
395 }
396
InitHomeButtonInfo(HBMDataInfo * pHbmInfo)397 static void InitHomeButtonInfo( HBMDataInfo* pHbmInfo )
398 {
399 #ifdef BTN_NUM_3
400 char dirName[] = "hbm/HomeButton3";
401 #else
402 char dirName[] = "hbm/HomeButton2";
403 #endif
404
405 char nameBuf[32];
406
407 /* Create file name */
408 strcpy( nameBuf, dirName );
409 /* Switching as necessary according to the language setting */
410 pHbmInfo->region=SCGetLanguage();
411 switch (pHbmInfo->region)
412 {
413 case SC_LANG_JAPANESE:
414 strcat( nameBuf, "/homeBtn.arc" );
415 break;
416 case SC_LANG_ENGLISH:
417 strcat( nameBuf, "/homeBtn_ENG.arc" );
418 break;
419 case SC_LANG_GERMAN:
420 strcat( nameBuf, "/homeBtn_GER.arc" );
421 break;
422 case SC_LANG_FRENCH:
423 strcat( nameBuf, "/homeBtn_FRA.arc" );
424 break;
425 case SC_LANG_SPANISH:
426 strcat( nameBuf, "/homeBtn_SPA.arc" );
427 break;
428 case SC_LANG_ITALIAN:
429 strcat( nameBuf, "/homeBtn_ITA.arc" );
430 break;
431 case SC_LANG_DUTCH:
432 strcat( nameBuf, "/homeBtn_NED.arc" );
433 break;
434 #ifdef SC_LANG_SIMP_CHINESE
435 case SC_LANG_SIMP_CHINESE:
436 strcat( nameBuf, "/homeBtn_CHN.arc" );
437 break;
438 #endif
439 #ifdef SC_LANG_KOREAN
440 case SC_LANG_KOREAN:
441 strcat( nameBuf, "/homeBtn_KOR.arc" );
442 break;
443 #endif
444 default:
445 pHbmInfo->region=SC_LANG_JAPANESE;
446 strcat( nameBuf, "/homeBtn.arc" );
447 break;
448 }
449 pHbmInfo->layoutBuf = ReadDvdFile( nameBuf, &DemoAllocator1, NULL );
450
451 strcpy( nameBuf, dirName );
452 strcat( nameBuf, "/SpeakerSe.arc" );
453 pHbmInfo->spkSeBuf = ReadDvdFile( nameBuf, &DemoAllocator1, NULL );
454
455 strcpy( nameBuf, dirName );
456 #ifdef HBM_NO_SAVE
457 strcat( nameBuf, "/home_nosave.csv" );
458 #else
459 strcat( nameBuf, "/home.csv" );
460 #endif
461 pHbmInfo->msgBuf = ReadDvdFile( nameBuf, &DemoAllocator1, NULL );
462
463 strcpy( nameBuf, dirName );
464 strcat( nameBuf, "/config.txt" );
465 pHbmInfo->configBuf = ReadDvdFile( nameBuf, &DemoAllocator1, &pHbmInfo->configBufSize );
466
467 pHbmInfo->sound_callback = SoundCallback;
468 pHbmInfo->backFlag = OFF;
469 pHbmInfo->cursor = 0;
470 pHbmInfo->adjust.x = 832.f / 608.f;
471 pHbmInfo->adjust.y = 1.0f;
472 pHbmInfo->frameDelta = 1.0f;
473
474 /* Memory allocation settings */
475 pHbmInfo->mem = allocMem1( HBM_MEM_SIZE );
476 pHbmInfo->memSize = HBM_MEM_SIZE;
477 pHbmInfo->pAllocator = NULL;
478
479 /* Change the exit message each time the HOME menu is started */
480 pHbmInfo->messageFlag++;
481 pHbmInfo->messageFlag &= 0x3;
482 }
483
484 /* Initialize sounds */
InitSound()485 static void InitSound()
486 {
487 #ifdef BTN_NUM_3
488 char dirName[] = "hbm/HomeButton3";
489 #else
490 char dirName[] = "hbm/HomeButton2";
491 #endif
492
493 char nameBuf[32];
494
495 /* Create file name */
496 strcpy( nameBuf, dirName );
497 strcat( nameBuf, "/HomeButtonSe.arc" );
498
499 /* Load sound data for AX use */
500 sound_data = (u8*)ReadDvdFile( nameBuf, &DemoAllocator1, NULL );
501 /* Allocate a buffer for sounds */
502 sound_buf = (u8*)allocMem1( HBM_MEM_SIZE_SOUND );
503 HBMCreateSound( sound_data, sound_buf, HBM_MEM_SIZE_SOUND );
504 }
505
506 /* Cursor position initialization */
InitControllerData(HBMControllerData * pConData)507 static void InitControllerData( HBMControllerData* pConData )
508 {
509 int i;
510 for( i = 0; i < WPAD_MAX_CONTROLLERS; i++ )
511 {
512 pConData->wiiCon[i].pos.x = 0.f;
513 pConData->wiiCon[i].pos.y = 0.f;
514 pConData->wiiCon[i].use_devtype = WPAD_DEV_CORE;
515 }
516 }
517
518 /* Absolute value clamp */
AbsClamp(f32 val,f32 max)519 static f32 AbsClamp( f32 val, f32 max )
520 {
521 return ( ( val > max ) ? max : ( val < -max ) ? -max : val );
522 }
523
524 /* Cursor movement processing for analog stick */
calcAnalogCursorPos(f32 stickX,f32 stickY,Vec2 * pos)525 static int calcAnalogCursorPos( f32 stickX, f32 stickY, Vec2* pos )
526 {
527 f32 x,y;
528 x = ( stickX / scStickMoveCoe );
529 y = ( stickY / scStickMoveCoe );
530 x = AbsClamp( x, 1.0f );
531 y = AbsClamp( y, 1.0f );
532 if( x == 0.0f && y == 0.0f ) return FALSE;
533 pos->x = AbsClamp( pos->x + x, 1.0f );
534 pos->y = AbsClamp( pos->y - y, 1.0f );
535 return TRUE;
536 }
537
538 /* Cursor movement processing when using +Control key */
calcDigitalCursorPos(u32 button,Vec2 * pos)539 static int calcDigitalCursorPos( u32 button, Vec2* pos )
540 {
541 const float spd =1.0f / scStickMoveCoe;
542 const float spd2= spd * 0.7071f;
543
544 button&=KPAD_CL_BUTTON_UP|KPAD_CL_BUTTON_LEFT|KPAD_CL_BUTTON_DOWN|KPAD_CL_BUTTON_RIGHT;
545 switch (button)
546 {
547 case KPAD_CL_BUTTON_UP: pos->y-=spd; break;
548 case KPAD_CL_BUTTON_LEFT: pos->x-=spd; break;
549 case KPAD_CL_BUTTON_DOWN: pos->y+=spd; break;
550 case KPAD_CL_BUTTON_RIGHT: pos->x+=spd; break;
551 case KPAD_CL_BUTTON_UP |KPAD_CL_BUTTON_LEFT: pos->y-=spd2; pos->x-=spd2; break;
552 case KPAD_CL_BUTTON_UP |KPAD_CL_BUTTON_RIGHT: pos->y-=spd2; pos->x+=spd2; break;
553 case KPAD_CL_BUTTON_DOWN|KPAD_CL_BUTTON_LEFT: pos->y+=spd2; pos->x-=spd2; break;
554 case KPAD_CL_BUTTON_DOWN|KPAD_CL_BUTTON_RIGHT: pos->y+=spd2; pos->x+=spd2; break;
555 default: return FALSE;
556 }
557 pos->x = AbsClamp( pos->x, 1.0f );
558 pos->y = AbsClamp( pos->y, 1.0f );
559 return TRUE;
560 }
561
562
563 /* Change the adjust value depending on the display mode */
SetAdjustValue(HBMDataInfo * pHbmInfo,int wideflag)564 static void SetAdjustValue( HBMDataInfo* pHbmInfo, int wideflag )
565 {
566 if( !wideflag )
567 {
568 /* 4:3 */
569 pHbmInfo->adjust.x = 1.0f;
570 pHbmInfo->adjust.y = 1.0f;
571 }
572 else
573 {
574 /* 16:9 */
575 pHbmInfo->adjust.x = 832.f / 608.f;
576 pHbmInfo->adjust.y = 1.0f;
577 }
578
579 if(sTvmode == 0)
580 {
581 /* NTSC: 60Hz */
582 pHbmInfo->frameDelta = 1.0f;
583 }
584 else
585 {
586 /* PAL: 50Hz */
587 pHbmInfo->frameDelta = 1.2f;
588 }
589 }
590
591 /* Main function */
main()592 void main()
593 {
594 Mtx mv;
595 HBMDataInfo hbmInfo;
596 HBMControllerData conData;
597 int homeBtnSwitch = OFF; /* HOME button switch */
598 int drawModeFlag = OFF; /* Flag for toggling between 4:3 and 16:9 displays */
599 int banIconSwitch = OFF; /* HOME button prohibition icon */
600 s8 banIconMode = 0; /* 0: AlphaIn, 1: Pause, 2: AlphaOut */
601 OSTick banIconTime = 0;
602 u8 banIconAlpha = 0;
603 s32 wpad_result[WPAD_MAX_CONTROLLERS];
604 u32 pad_type[WPAD_MAX_CONTROLLERS];
605 Vec2 pos[WPAD_MAX_CONTROLLERS];/* Position of the Pointer */
606 int input_classic;
607 int i;
608
609 s32 kpad_read[WPAD_MAX_CONTROLLERS];
610 GXRenderModeObj* pRm;
611
612 Init();
613
614 /* Viewport settings */
615 pRm = DEMOGetRenderModeObj();
616 MTXIdentity(mv);
617 GXLoadPosMtxImm(mv, GX_PNMTX1);
618 SetProjection( drawModeFlag );
619 /* No culling */
620 GXSetCullMode( GX_CULL_NONE );
621
622 /* Display the operation method on the console */
623 OSReport( "------------------------------\n" );
624 OSReport( "HOME Button Menu Sample\n\n" );
625 OSReport( "+ : Show Icon\n" );
626 OSReport( "2 : Switch Video Mode\n" );
627 OSReport( "------------------------------\n" );
628
629 OSReport("Mem1Free = %d\n", MEMGetTotalFreeSizeForExpHeap((MEMHeapHandle)DemoAllocator1.pHeap) );
630 OSReport("Mem2Free = %d\n", MEMGetTotalFreeSizeForExpHeap((MEMHeapHandle)DemoAllocator2.pHeap) );
631
632 while( 1 )
633 {
634 /* Wii controllers */
635 for( int i = 0; i < WPAD_MAX_CONTROLLERS; i++ )
636 {
637 wpad_result[i] = WPADProbe( i, &pad_type[i] );
638 conData.wiiCon[i].use_devtype = pad_type[i];
639 kpad_read[i] = KPADRead( i, &sKpads[i][0], KPAD_MAX_READ_BUFS );
640 if ( kpad_read[i] == 0 )
641 memset(&sKpads[i][0], 0, sizeof(KPADStatus));
642
643 switch( wpad_result[i] )
644 {
645 /* In the following error states, the value gotten by KPADRead is applied as-is. */
646 case WPAD_ERR_BUSY:
647 case WPAD_ERR_TRANSFER:
648 case WPAD_ERR_INVALID:
649 case WPAD_ERR_CORRUPTED:
650 case WPAD_ERR_NONE:
651 conData.wiiCon[i].kpad = &sKpads[i][0];
652
653 {
654 /*
655 According to guidelines, if there is input from a Classic Controller, that input is prioritized and inherits DPD coordinates.
656
657 Specify the DPD absolute coordinates when there is no Classic Controller input.
658 */
659
660 input_classic = calcDigitalCursorPos(
661 conData.wiiCon[i].kpad->ex_status.cl.hold,
662 &conData.wiiCon[i].pos );
663
664
665 input_classic = input_classic | calcAnalogCursorPos(
666 conData.wiiCon[i].kpad->ex_status.cl.lstick.x,
667 conData.wiiCon[i].kpad->ex_status.cl.lstick.y,
668 &conData.wiiCon[i].pos );
669
670 if( !input_classic && conData.wiiCon[i].kpad->dpd_valid_fg > 0)
671 {
672 conData.wiiCon[i].pos.x = conData.wiiCon[i].kpad->pos.x;
673 conData.wiiCon[i].pos.y = conData.wiiCon[i].kpad->pos.y;
674 }
675 }
676
677 /* Change the rendering mode */
678 if( !homeBtnSwitch && sKpads[i][0].trig == KPAD_BUTTON_2 )
679 {
680 drawModeFlag = !drawModeFlag;
681 SetProjection( drawModeFlag );
682 SetAdjustValue( &hbmInfo, drawModeFlag );
683 pRm = DEMOGetRenderModeObj();
684 }
685
686 if( sKpads[i][0].trig == KPAD_BUTTON_1 )
687 {
688 VISetBlack(FALSE);
689 VIFlush();
690 }
691
692 if ( !homeBtnSwitch && !banIconSwitch && sKpads[i][0].trig == KPAD_BUTTON_PLUS )
693 {
694 banIconMode = eAlphaInIcon;
695 banIconSwitch = ON;
696 banIconTime = OSGetTick();
697 banIconAlpha = 0;
698 }
699 break;
700 /* Apply NULL in the following error states. */
701 case WPAD_ERR_NO_CONTROLLER:
702 default:
703 conData.wiiCon[i].kpad = NULL;
704 break;
705 }
706 }
707 if( !homeBtnSwitch && !banIconSwitch )
708 {
709 BOOL press_home = FALSE;
710
711 for ( int i = 0; i < WPAD_MAX_CONTROLLERS; i++ )
712 {
713 if ( WPAD_ERR_NONE != wpad_result[i] ) continue;
714
715 /* When HOME is pressed on the Wii Remote or Classic Controller */
716 if ( sKpads[i][0].trig == KPAD_BUTTON_HOME ||
717 sKpads[i][0].ex_status.cl.trig==KPAD_CL_BUTTON_HOME )
718 {
719 press_home = TRUE;
720 homeBtnSwitch = ON;
721 break;
722 }
723 }
724 if ( press_home )
725 {
726 InitControllerData( &conData );
727 InitHomeButtonInfo( &hbmInfo );
728 /* Set the adjust value depending on the screen mode */
729 SetAdjustValue( &hbmInfo, drawModeFlag );
730
731 /* HBM initialization */
732 HBMCreate( &hbmInfo );
733 HBMInit();
734 /* Adjust ON */
735 HBMSetAdjustFlag( TRUE );
736
737 /* Load sound */
738 InitSound();
739
740 OSReport("Mem1Free = %d\n", MEMGetTotalFreeSizeForExpHeap((MEMHeapHandle)DemoAllocator1.pHeap) );
741 OSReport("Mem2Free = %d\n", MEMGetTotalFreeSizeForExpHeap((MEMHeapHandle)DemoAllocator2.pHeap) );
742 }
743 }
744
745 if( homeBtnSwitch )
746 {
747 /* Update SE (sound effect) */
748 HBMUpdateSound();
749
750 /* Update the HOME Menu */
751 if( HBMCalc( &conData ) >= HBM_SELECT_HOMEBTN )
752 {
753 /* The number of the decided-upon button is returned */
754 OSReport("Select Btn:%d\n", HBMGetSelectBtnNum());
755 OSReport("Reassigned:%d\n", HBMIsReassignedControllers());
756
757
758 /* Process executed when returning from the HOME Menu */
759 switch( HBMGetSelectBtnNum() )
760 {
761 case HBM_SELECT_HOMEBTN:
762 break;
763 /* Move to the Wii Menu */
764 case HBM_SELECT_BTN1:
765 OSReport( "Return to WiiMenu.\n" );
766 OSReturnToMenu();
767 break;
768 /* Reset */
769 case HBM_SELECT_BTN2:
770 OSReport( "Reset.\n" );
771 OSRestart( 0 );
772 break;
773 case 3:
774
775 break;
776 default:
777 break;
778 }
779 /* Release various and sundry items */
780 HBMDelete( );
781 HBMDeleteSound();
782
783 freeMem1( sound_buf );
784 freeMem1( sound_data );
785 freeMem1( hbmInfo.mem );
786 freeMem1( hbmInfo.layoutBuf );
787 freeMem1( hbmInfo.spkSeBuf );
788 freeMem1( hbmInfo.msgBuf );
789 freeMem1( hbmInfo.configBuf );
790
791 homeBtnSwitch = OFF;
792
793 OSReport("Mem1Free = %d\n", MEMGetTotalFreeSizeForExpHeap((MEMHeapHandle)DemoAllocator1.pHeap) );
794 OSReport("Mem2Free = %d\n", MEMGetTotalFreeSizeForExpHeap((MEMHeapHandle)DemoAllocator2.pHeap) );
795 }
796
797 }
798
799 /* Calculate the Pointer position */
800 for( i = 0; i < PAD_MAX_CONTROLLERS; i++ )
801 {
802 /* for Wii */
803 if ( WPAD_ERR_NONE == wpad_result[i] &&
804 0 < kpad_read[i] &&
805 conData.wiiCon[i].kpad )
806 {
807 if( !homeBtnSwitch )
808 {
809 if( sKpads[i]->dev_type == WPAD_DEV_CLASSIC )
810 {
811 pos[i].x = conData.wiiCon[i].pos.x;
812 pos[i].y = conData.wiiCon[i].pos.y;
813 }
814 else
815 {
816 pos[i].x = conData.wiiCon[i].kpad->pos.x;
817 pos[i].y = conData.wiiCon[i].kpad->pos.y;
818 }
819
820 pos[i].x *= pRm->fbWidth * 0.5f;
821 pos[i].y *= pRm->xfbHeight * 0.5f;
822
823 if( drawModeFlag )
824 {
825 pos[i].x *= hbmInfo.adjust.x;
826 pos[i].y *= hbmInfo.adjust.y;
827 }
828 }
829 }
830 }
831
832 DEMOBeforeRender();
833 {
834 InitGX();
835 if( homeBtnSwitch )
836 {
837 /* Render the HOME Menu */
838 HBMDraw();
839 }
840 /* Render the specified cursor inside the HOME Menu */
841 if( !homeBtnSwitch )
842 {
843 for( i = 0; i < PAD_MAX_CONTROLLERS; i++ )
844 {
845 if( conData.wiiCon[i].kpad )
846 {
847 /* Render the Wii Pointer */
848 GXBegin( GX_QUADS, GX_VTXFMT4, 4 );
849 GXPosition2f32( -10 + pos[i].x, -10 - pos[i].y );
850 GXColor3u8( 255, 255, 255 );
851 GXPosition2f32( -10 + pos[i].x, 10 - pos[i].y );
852 GXColor3u8( 255, 255, 255 );
853 GXPosition2f32( 10 + pos[i].x, 10 - pos[i].y );
854 GXColor3u8( 255, 255, 255 );
855 GXPosition2f32( 10 + pos[i].x, -10 - pos[i].y );
856 GXColor3u8( 255, 255, 255 );
857 GXEnd();
858 }
859 }
860
861 /* Render the HOME Menu prohibited icon */
862 if ( banIconSwitch )
863 {
864 f32 elapse = OSTicksToMilliseconds( OSDiffTick( OSGetTick(), banIconTime ) );
865
866 switch ( banIconMode )
867 {
868 case eAlphaInIcon: /* AlphaIn (250ms) */
869 banIconAlpha = ( u8 )( 255.9f * ( elapse / 250.f ) );
870 if ( elapse >= 250.f )
871 {
872 banIconTime = OSGetTick();
873 banIconMode = ePauseIcon;
874 banIconAlpha = 255;
875 }
876 break;
877 case ePauseIcon: /* Pause (1000ms) */
878 if ( elapse >= 1000.f )
879 {
880 banIconTime = OSGetTick();
881 banIconMode = eAlphaOutIcon;
882 }
883 break;
884 case eAlphaOutIcon: /* AlphaOut (250ms) */
885 banIconAlpha = ( u8 )( 255.9f * ( ( 250.f - elapse ) / 250.f ) );
886 if ( elapse >= 250.f )
887 {
888 banIconAlpha = 0;
889 banIconSwitch = OFF;
890 }
891 break;
892 }
893
894 DrawBanIcon( banIconAlpha );
895 }
896 }
897 }
898 DEMODoneRender();
899
900 /* Process executed when the RESET or Power Button is pressed */
901 if(reset_called)
902 {
903 /*When other than the HOME Menu, go straight on to reset */
904 if( homeBtnSwitch == OFF )
905 {
906 OSRestart(0);
907 }
908 /* If the HOME Menu is running, reset after black-out */
909 else
910 {
911 HBMStartBlackOut();
912 }
913 reset_called = false;
914 }
915
916 if(power_called)
917 {
918 OSReturnToMenu();
919 }
920 }
921 }
922
923