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 VIInit();
260 switch (VIGetTvFormat())
261 {
262 case VI_NTSC:
263 sTvmode = 0;
264 break;
265 case VI_PAL:
266 sTvmode = 1;
267 break;
268 default:
269 OSHalt("VIGetTvFormat()t: invalid TV format\n");
270 break;
271 }
272
273 DEMOInit(&sRMObj[sTvmode]);
274
275 SCInit();
276 while ( SC_STATUS_OK != SCCheckStatus() ) {} /* Wait for completion of SCInit() */
277 DVDInit();
278 OSInitFastCast();
279
280 #ifdef ENABLE_BALANCE_BOARD
281 WPADRegisterBLCWorkarea( workarea );
282 #endif // ENABLE_BALANCE_BOARD
283 WPADRegisterAllocator( allocMem2, freeMem2 );
284
285 PADInit();
286 KPADInit();
287
288 /* Load icon */
289 strcpy( nameBuf, dirName );
290 strcat( nameBuf, "/homeBtnIcon.tpl" );
291 sIconTpl = ( TPLPalettePtr )ReadDvdFile( nameBuf, &DemoAllocator1, NULL );
292 TPLBind( sIconTpl );
293
294 /* Power switch and reset switch callbacks */
295 OSSetResetCallback(ResetCallback);
296 OSSetPowerCallback(PowerCallback);
297
298 reset_called = false;
299 power_called = false;
300 }
301
302
303 /* Projection settings */
SetProjection(int wideflag)304 static void SetProjection( int wideflag )
305 {
306 Mtx44 projMtx;
307
308
309 if( !wideflag )
310 {
311 DEMOReInit(&sRMObj[sTvmode]);
312 f32 viRateX = sRMObj[sTvmode].viWidth / 670.f;
313 f32 viRateY = sRMObj[sTvmode].viHeight / 456.f;
314 MTXOrtho(projMtx, viRateY * 228.0f, -viRateY * 228.0f, -viRateX * 304.0f, viRateX * 304.0f, 0.0f, 500.0f);
315 }
316 else
317 {
318 DEMOReInit(&sRMObjWide[sTvmode]);
319 f32 viRateX = sRMObjWide[sTvmode].viWidth / 686.f;
320 f32 viRateY = sRMObjWide[sTvmode].viHeight / 456.f;
321 MTXOrtho(projMtx, viRateY * 228.0f, -viRateY * 228.0f, -viRateX * 437.0f, viRateX * 437.0f, 0.0f, 500.0f);
322 }
323
324 GXSetProjection(projMtx, GX_ORTHOGRAPHIC);
325 }
326
327 /* Initialize GX */
InitGX()328 static void InitGX()
329 {
330 GXClearVtxDesc();
331
332 GXSetVtxAttrFmt(GX_VTXFMT4, GX_VA_POS, GX_POS_XY, GX_F32, 0);
333 GXSetVtxAttrFmt(GX_VTXFMT4, GX_VA_CLR0, GX_CLR_RGB, GX_RGB8, 0);
334 GXSetVtxDesc(GX_VA_POS, GX_DIRECT);
335 GXSetVtxDesc(GX_VA_CLR0, GX_DIRECT);
336
337 GXSetNumChans(1);
338 GXSetNumTexGens(0);
339 GXSetNumTevStages(1);
340 GXSetTevOrder(GX_TEVSTAGE0, GX_TEXCOORD_NULL, GX_TEXMAP_NULL, GX_COLOR0A0);
341 GXSetTevOp(GX_TEVSTAGE0, GX_PASSCLR);
342
343 GXSetBlendMode(GX_BM_NONE, GX_BL_ZERO, GX_BL_ZERO, GX_LO_CLEAR);
344 GXSetZMode(GX_TRUE, GX_LEQUAL, GX_TRUE);
345 GXSetCurrentMtx( GX_PNMTX1 );
346 }
347
348 /* Render the "Prohibited" icon */
DrawBanIcon(u8 alpha)349 static void DrawBanIcon( u8 alpha )
350 {
351 GXTexObj texObj;
352 Mtx view_mtx ;
353 // mtx
354 MTXIdentity( view_mtx ) ;
355 GXLoadPosMtxImm( view_mtx, GX_PNMTX1 ) ;
356 GXSetCurrentMtx( GX_PNMTX1 ) ;
357
358 GXClearVtxDesc();
359
360 GXSetVtxAttrFmt(GX_VTXFMT5, GX_VA_POS, GX_POS_XY, GX_S16, 0);
361 GXSetVtxAttrFmt(GX_VTXFMT5, GX_VA_TEX0, GX_TEX_ST, GX_S16, 0);
362 GXSetVtxDesc(GX_VA_POS, GX_DIRECT);
363 GXSetVtxDesc(GX_VA_TEX0, GX_DIRECT);
364
365 GXSetNumChans(1);
366 GXSetChanCtrl(GX_COLOR0A0, GX_FALSE, GX_SRC_VTX, GX_SRC_VTX, GX_LIGHT_NULL, GX_DF_NONE, GX_AF_NONE);
367
368 GXSetNumTexGens(1);
369 GXSetTexCoordGen(GX_TEXCOORD0, GX_TG_MTX2x4, GX_TG_TEX0, GX_IDENTITY);
370
371 GXSetNumTevStages(1);
372 GXSetTevColor(GX_TEVREG0, (GXColor){255, 255, 255, alpha});
373 GXSetTevOrder(GX_TEVSTAGE0, GX_TEXCOORD0, GX_TEXMAP0, GX_COLOR_NULL);
374 GXSetTevColorIn(GX_TEVSTAGE0, GX_CC_ZERO, GX_CC_ZERO, GX_CC_ZERO, GX_CC_TEXC);
375 GXSetTevColorOp(GX_TEVSTAGE0, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_TRUE, GX_TEVPREV);
376 GXSetTevAlphaIn(GX_TEVSTAGE0, GX_CA_ZERO, GX_CA_A0, GX_CA_TEXA, GX_CA_ZERO);
377 GXSetTevAlphaOp(GX_TEVSTAGE0, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_TRUE, GX_TEVPREV);
378
379 GXSetBlendMode(GX_BM_BLEND, GX_BL_SRCALPHA, GX_BL_INVSRCALPHA, GX_LO_CLEAR);
380 GXSetZMode(GX_FALSE, GX_LEQUAL, GX_FALSE);
381
382 TPLGetGXTexObjFromPalette( sIconTpl, &texObj, 0 );
383 GXLoadTexObj( &texObj, GX_TEXMAP0 );
384
385 /* The rendering position may be anywhere inside the safe frame. */
386 GXBegin( GX_QUADS, GX_VTXFMT5, 4 );
387 GXPosition2s16( -256 + 0, 188 - 56 );
388 GXTexCoord2s16( 0, 1 );
389 GXPosition2s16( -256 + 0, 188 + 0 );
390 GXTexCoord2s16( 0, 0 );
391 GXPosition2s16( -256 + 56, 188 + 0 );
392 GXTexCoord2s16( 1, 0 );
393 GXPosition2s16( -256 + 56, 188 - 56 );
394 GXTexCoord2s16( 1, 1 );
395 GXEnd();
396 }
397
InitHomeButtonInfo(HBMDataInfo * pHbmInfo)398 static void InitHomeButtonInfo( HBMDataInfo* pHbmInfo )
399 {
400 #ifdef BTN_NUM_3
401 char dirName[] = "hbm/HomeButton3";
402 #else
403 char dirName[] = "hbm/HomeButton2";
404 #endif
405
406 char nameBuf[32];
407
408 /* Create filename */
409 strcpy( nameBuf, dirName );
410 /* Switching as necessary according to the language setting */
411 pHbmInfo->region=SCGetLanguage();
412 switch (pHbmInfo->region)
413 {
414 case SC_LANG_JAPANESE:
415 strcat( nameBuf, "/homeBtn.arc" );
416 break;
417 case SC_LANG_ENGLISH:
418 strcat( nameBuf, "/homeBtn_ENG.arc" );
419 break;
420 case SC_LANG_GERMAN:
421 strcat( nameBuf, "/homeBtn_GER.arc" );
422 break;
423 case SC_LANG_FRENCH:
424 strcat( nameBuf, "/homeBtn_FRA.arc" );
425 break;
426 case SC_LANG_SPANISH:
427 strcat( nameBuf, "/homeBtn_SPA.arc" );
428 break;
429 case SC_LANG_ITALIAN:
430 strcat( nameBuf, "/homeBtn_ITA.arc" );
431 break;
432 case SC_LANG_DUTCH:
433 strcat( nameBuf, "/homeBtn_NED.arc" );
434 break;
435 #ifdef SC_LANG_SIMP_CHINESE
436 case SC_LANG_SIMP_CHINESE:
437 strcat( nameBuf, "/homeBtn_CHN.arc" );
438 break;
439 #endif
440 #ifdef SC_LANG_KOREAN
441 case SC_LANG_KOREAN:
442 strcat( nameBuf, "/homeBtn_KOR.arc" );
443 break;
444 #endif
445 default:
446 pHbmInfo->region=SC_LANG_JAPANESE;
447 strcat( nameBuf, "/homeBtn.arc" );
448 break;
449 }
450 pHbmInfo->layoutBuf = ReadDvdFile( nameBuf, &DemoAllocator1, NULL );
451
452 strcpy( nameBuf, dirName );
453 strcat( nameBuf, "/SpeakerSe.arc" );
454 pHbmInfo->spkSeBuf = ReadDvdFile( nameBuf, &DemoAllocator1, NULL );
455
456 strcpy( nameBuf, dirName );
457 #ifdef HBM_NO_SAVE
458 strcat( nameBuf, "/home_nosave.csv" );
459 #else
460 strcat( nameBuf, "/home.csv" );
461 #endif
462 pHbmInfo->msgBuf = ReadDvdFile( nameBuf, &DemoAllocator1, NULL );
463
464 strcpy( nameBuf, dirName );
465 strcat( nameBuf, "/config.txt" );
466 pHbmInfo->configBuf = ReadDvdFile( nameBuf, &DemoAllocator1, &pHbmInfo->configBufSize );
467
468 pHbmInfo->sound_callback = SoundCallback;
469 pHbmInfo->backFlag = OFF;
470 pHbmInfo->cursor = 0;
471 pHbmInfo->adjust.x = 832.f / 608.f;
472 pHbmInfo->adjust.y = 1.0f;
473 pHbmInfo->frameDelta = 1.0f;
474
475 /* Memory allocation settings */
476 pHbmInfo->mem = allocMem1( HBM_MEM_SIZE );
477 pHbmInfo->memSize = HBM_MEM_SIZE;
478 pHbmInfo->pAllocator = NULL;
479
480 /* Change the exit message each time the HOME menu is started */
481 pHbmInfo->messageFlag++;
482 pHbmInfo->messageFlag &= 0x3;
483 }
484
485 /* Initialize sounds */
InitSound()486 static void InitSound()
487 {
488 #ifdef BTN_NUM_3
489 char dirName[] = "hbm/HomeButton3";
490 #else
491 char dirName[] = "hbm/HomeButton2";
492 #endif
493
494 char nameBuf[32];
495
496 /* Create filename */
497 strcpy( nameBuf, dirName );
498 strcat( nameBuf, "/HomeButtonSe.arc" );
499
500 /* Load sound data for AX use */
501 sound_data = (u8*)ReadDvdFile( nameBuf, &DemoAllocator1, NULL );
502 /* Allocate a buffer for sounds */
503 sound_buf = (u8*)allocMem1( HBM_MEM_SIZE_SOUND );
504 HBMCreateSound( sound_data, sound_buf, HBM_MEM_SIZE_SOUND );
505 }
506
507 /* Cursor position initialization */
InitControllerData(HBMControllerData * pConData)508 static void InitControllerData( HBMControllerData* pConData )
509 {
510 int i;
511 for( i = 0; i < WPAD_MAX_CONTROLLERS; i++ )
512 {
513 pConData->wiiCon[i].pos.x = 0.f;
514 pConData->wiiCon[i].pos.y = 0.f;
515 pConData->wiiCon[i].use_devtype = WPAD_DEV_CORE;
516 }
517 }
518
519 /* Absolute value clamp */
AbsClamp(f32 val,f32 max)520 static f32 AbsClamp( f32 val, f32 max )
521 {
522 return ( ( val > max ) ? max : ( val < -max ) ? -max : val );
523 }
524
525 /* Cursor movement processing for analog stick */
calcAnalogCursorPos(f32 stickX,f32 stickY,Vec2 * pos)526 static int calcAnalogCursorPos( f32 stickX, f32 stickY, Vec2* pos )
527 {
528 f32 x,y;
529 x = ( stickX / scStickMoveCoe );
530 y = ( stickY / scStickMoveCoe );
531 x = AbsClamp( x, 1.0f );
532 y = AbsClamp( y, 1.0f );
533 if( x == 0.0f && y == 0.0f ) return FALSE;
534 pos->x = AbsClamp( pos->x + x, 1.0f );
535 pos->y = AbsClamp( pos->y - y, 1.0f );
536 return TRUE;
537 }
538
539 /* Cursor movement processing when using +Control key */
calcDigitalCursorPos(u32 button,Vec2 * pos)540 static int calcDigitalCursorPos( u32 button, Vec2* pos )
541 {
542 const float spd =1.0f / scStickMoveCoe;
543 const float spd2= spd * 0.7071f;
544
545 button&=KPAD_CL_BUTTON_UP|KPAD_CL_BUTTON_LEFT|KPAD_CL_BUTTON_DOWN|KPAD_CL_BUTTON_RIGHT;
546 switch (button)
547 {
548 case KPAD_CL_BUTTON_UP: pos->y-=spd; break;
549 case KPAD_CL_BUTTON_LEFT: pos->x-=spd; break;
550 case KPAD_CL_BUTTON_DOWN: pos->y+=spd; break;
551 case KPAD_CL_BUTTON_RIGHT: pos->x+=spd; break;
552 case KPAD_CL_BUTTON_UP |KPAD_CL_BUTTON_LEFT: pos->y-=spd2; pos->x-=spd2; break;
553 case KPAD_CL_BUTTON_UP |KPAD_CL_BUTTON_RIGHT: pos->y-=spd2; pos->x+=spd2; break;
554 case KPAD_CL_BUTTON_DOWN|KPAD_CL_BUTTON_LEFT: pos->y+=spd2; pos->x-=spd2; break;
555 case KPAD_CL_BUTTON_DOWN|KPAD_CL_BUTTON_RIGHT: pos->y+=spd2; pos->x+=spd2; break;
556 default: return FALSE;
557 }
558 pos->x = AbsClamp( pos->x, 1.0f );
559 pos->y = AbsClamp( pos->y, 1.0f );
560 return TRUE;
561 }
562
563
564 /* Change the adjust value depending on the display mode */
SetAdjustValue(HBMDataInfo * pHbmInfo,int wideflag)565 static void SetAdjustValue( HBMDataInfo* pHbmInfo, int wideflag )
566 {
567 if( !wideflag )
568 {
569 /* 4:3 */
570 pHbmInfo->adjust.x = 1.0f;
571 pHbmInfo->adjust.y = 1.0f;
572 }
573 else
574 {
575 /* 16:9 */
576 pHbmInfo->adjust.x = 832.f / 608.f;
577 pHbmInfo->adjust.y = 1.0f;
578 }
579
580 if(sTvmode == 0)
581 {
582 /* NTSC: 60Hz */
583 pHbmInfo->frameDelta = 1.0f;
584 }
585 else
586 {
587 /* PAL: 50Hz */
588 pHbmInfo->frameDelta = 1.2f;
589 }
590 }
591
592 /* Main function */
main()593 void main()
594 {
595 Mtx mv;
596 HBMDataInfo hbmInfo;
597 HBMControllerData conData;
598 int homeBtnSwitch = OFF; /* HOME button switch */
599 int drawModeFlag = OFF; /* Flag for toggling between 4:3 and 16:9 displays */
600 int banIconSwitch = OFF; /* HOME button prohibited icon */
601 s8 banIconMode = 0; /* 0: AlphaIn, 1: Pause, 2: AlphaOut */
602 OSTick banIconTime = 0;
603 u8 banIconAlpha = 0;
604 s32 wpad_result[WPAD_MAX_CONTROLLERS];
605 u32 pad_type[WPAD_MAX_CONTROLLERS];
606 Vec2 pos[WPAD_MAX_CONTROLLERS];/* Position of the Pointer */
607 int input_classic;
608 int i;
609
610 s32 kpad_read[WPAD_MAX_CONTROLLERS];
611 GXRenderModeObj* pRm;
612
613 Init();
614
615 /* Viewport settings */
616 pRm = DEMOGetRenderModeObj();
617 MTXIdentity(mv);
618 GXLoadPosMtxImm(mv, GX_PNMTX1);
619 SetProjection( drawModeFlag );
620 /* No culling */
621 GXSetCullMode( GX_CULL_NONE );
622
623 /* Display the operation method on the console */
624 OSReport( "------------------------------\n" );
625 OSReport( "HOME Button Menu Sample\n\n" );
626 OSReport( "+ : Show Icon\n" );
627 OSReport( "2 : Switch Video Mode\n" );
628 OSReport( "------------------------------\n" );
629
630 OSReport("Mem1Free = %d\n", MEMGetTotalFreeSizeForExpHeap((MEMHeapHandle)DemoAllocator1.pHeap) );
631 OSReport("Mem2Free = %d\n", MEMGetTotalFreeSizeForExpHeap((MEMHeapHandle)DemoAllocator2.pHeap) );
632
633 while( 1 )
634 {
635 /* Wii controllers */
636 for( int i = 0; i < WPAD_MAX_CONTROLLERS; i++ )
637 {
638 wpad_result[i] = WPADProbe( i, &pad_type[i] );
639 conData.wiiCon[i].use_devtype = pad_type[i];
640 kpad_read[i] = KPADRead( i, &sKpads[i][0], KPAD_MAX_READ_BUFS );
641
642 switch( wpad_result[i] )
643 {
644 /* In the following error states, the value gotten by KPADRead is applied as is. */
645 case WPAD_ERR_BUSY:
646 case WPAD_ERR_TRANSFER:
647 case WPAD_ERR_INVALID:
648 case WPAD_ERR_CORRUPTED:
649 case WPAD_ERR_NONE:
650 conData.wiiCon[i].kpad = &sKpads[i][0];
651
652 {
653 /*
654 According to guidelines, if there is input from a Classic Controller, that input is prioritized and inherits DPD coordinates.
655
656 Specify the DPD absolute coordinates when there is no Classic Controller input.
657 */
658
659 input_classic = calcDigitalCursorPos(
660 conData.wiiCon[i].kpad->ex_status.cl.hold,
661 &conData.wiiCon[i].pos );
662
663
664 input_classic = input_classic | calcAnalogCursorPos(
665 conData.wiiCon[i].kpad->ex_status.cl.lstick.x,
666 conData.wiiCon[i].kpad->ex_status.cl.lstick.y,
667 &conData.wiiCon[i].pos );
668
669 if( !input_classic && conData.wiiCon[i].kpad->dpd_valid_fg > 0)
670 {
671 conData.wiiCon[i].pos.x = conData.wiiCon[i].kpad->pos.x;
672 conData.wiiCon[i].pos.y = conData.wiiCon[i].kpad->pos.y;
673 }
674 }
675
676 /* Change the rendering mode */
677 if( !homeBtnSwitch && sKpads[i][0].trig == KPAD_BUTTON_2 )
678 {
679 drawModeFlag = !drawModeFlag;
680 SetProjection( drawModeFlag );
681 SetAdjustValue( &hbmInfo, drawModeFlag );
682 pRm = DEMOGetRenderModeObj();
683 }
684
685 if( sKpads[i][0].trig == KPAD_BUTTON_1 )
686 {
687 VISetBlack(FALSE);
688 VIFlush();
689 }
690
691 if ( !homeBtnSwitch && !banIconSwitch && sKpads[i][0].trig == KPAD_BUTTON_PLUS )
692 {
693 banIconMode = eAlphaInIcon;
694 banIconSwitch = ON;
695 banIconTime = OSGetTick();
696 banIconAlpha = 0;
697 }
698 break;
699 /* Apply NULL in the following error states. */
700 case WPAD_ERR_NO_CONTROLLER:
701 default:
702 conData.wiiCon[i].kpad = NULL;
703 break;
704 }
705 }
706 if( !homeBtnSwitch && !banIconSwitch )
707 {
708 BOOL press_home = FALSE;
709
710 for ( int i = 0; i < WPAD_MAX_CONTROLLERS; i++ )
711 {
712 if ( WPAD_ERR_NONE != wpad_result[i] ) continue;
713
714 /* When HOME is pressed on the Wii Remote or Classic Controller */
715 if ( sKpads[i][0].trig == KPAD_BUTTON_HOME ||
716 sKpads[i][0].ex_status.cl.trig==KPAD_CL_BUTTON_HOME )
717 {
718 press_home = TRUE;
719 homeBtnSwitch = ON;
720 break;
721 }
722 }
723 if ( press_home )
724 {
725 InitControllerData( &conData );
726 InitHomeButtonInfo( &hbmInfo );
727 /* Set the adjust value depending on the screen mode */
728 SetAdjustValue( &hbmInfo, drawModeFlag );
729
730 /* HBM initialization */
731 HBMCreate( &hbmInfo );
732 HBMInit();
733 /* Adjust ON */
734 HBMSetAdjustFlag( TRUE );
735
736 /* Load sounds */
737 InitSound();
738
739 OSReport("Mem1Free = %d\n", MEMGetTotalFreeSizeForExpHeap((MEMHeapHandle)DemoAllocator1.pHeap) );
740 OSReport("Mem2Free = %d\n", MEMGetTotalFreeSizeForExpHeap((MEMHeapHandle)DemoAllocator2.pHeap) );
741 }
742 }
743
744 if( homeBtnSwitch )
745 {
746 /* Update SE (sound effect) */
747 HBMUpdateSound();
748
749 /* Update the HOME Menu */
750 if( HBMCalc( &conData ) >= HBM_SELECT_HOMEBTN )
751 {
752 /* The number of the decided-upon button is returned */
753 OSReport("Select Btn:%d\n", HBMGetSelectBtnNum());
754 OSReport("Reassigned:%d\n", HBMIsReassignedControllers());
755
756
757 /* Process executed when returning from the HOME Menu */
758 switch( HBMGetSelectBtnNum() )
759 {
760 case HBM_SELECT_HOMEBTN:
761 break;
762 /* Move to the Wii Menu */
763 case HBM_SELECT_BTN1:
764 OSReport( "Return to WiiMenu.\n" );
765 OSReturnToMenu();
766 break;
767 /* Reset */
768 case HBM_SELECT_BTN2:
769 OSReport( "Reset.\n" );
770 OSRestart( 0 );
771 break;
772 case 3:
773
774 break;
775 default:
776 break;
777 }
778 /* Release various items */
779 HBMDelete( );
780 HBMDeleteSound();
781
782 freeMem1( sound_buf );
783 freeMem1( sound_data );
784 freeMem1( hbmInfo.mem );
785 freeMem1( hbmInfo.layoutBuf );
786 freeMem1( hbmInfo.spkSeBuf );
787 freeMem1( hbmInfo.msgBuf );
788 freeMem1( hbmInfo.configBuf );
789
790 homeBtnSwitch = OFF;
791
792 OSReport("Mem1Free = %d\n", MEMGetTotalFreeSizeForExpHeap((MEMHeapHandle)DemoAllocator1.pHeap) );
793 OSReport("Mem2Free = %d\n", MEMGetTotalFreeSizeForExpHeap((MEMHeapHandle)DemoAllocator2.pHeap) );
794 }
795
796 }
797
798 /* Calculate the Pointer position */
799 for( i = 0; i < PAD_MAX_CONTROLLERS; i++ )
800 {
801 /* For Wii */
802 if ( WPAD_ERR_NONE == wpad_result[i] &&
803 0 < kpad_read[i] &&
804 conData.wiiCon[i].kpad )
805 {
806 if( !homeBtnSwitch )
807 {
808 if( sKpads[i]->dev_type == WPAD_DEV_CLASSIC )
809 {
810 pos[i].x = conData.wiiCon[i].pos.x;
811 pos[i].y = conData.wiiCon[i].pos.y;
812 }
813 else
814 {
815 pos[i].x = conData.wiiCon[i].kpad->pos.x;
816 pos[i].y = conData.wiiCon[i].kpad->pos.y;
817 }
818
819 pos[i].x *= pRm->fbWidth * 0.5f;
820 pos[i].y *= pRm->xfbHeight * 0.5f;
821
822 if( drawModeFlag )
823 {
824 pos[i].x *= hbmInfo.adjust.x;
825 pos[i].y *= hbmInfo.adjust.y;
826 }
827 }
828 }
829 }
830
831 DEMOBeforeRender();
832 {
833 InitGX();
834 if( homeBtnSwitch )
835 {
836 /* Render the HOME Menu */
837 HBMDraw();
838 }
839 /* Render the specified cursor inside the HOME Menu */
840 if( !homeBtnSwitch )
841 {
842 for( i = 0; i < PAD_MAX_CONTROLLERS; i++ )
843 {
844 if( conData.wiiCon[i].kpad )
845 {
846 /* Render the Wii Pointer */
847 GXBegin( GX_QUADS, GX_VTXFMT4, 4 );
848 GXPosition2f32( -10 + pos[i].x, -10 - pos[i].y );
849 GXColor3u8( 255, 255, 255 );
850 GXPosition2f32( -10 + pos[i].x, 10 - pos[i].y );
851 GXColor3u8( 255, 255, 255 );
852 GXPosition2f32( 10 + pos[i].x, 10 - pos[i].y );
853 GXColor3u8( 255, 255, 255 );
854 GXPosition2f32( 10 + pos[i].x, -10 - pos[i].y );
855 GXColor3u8( 255, 255, 255 );
856 GXEnd();
857 }
858 }
859
860 /* Render the HOME Menu prohibited icon */
861 if ( banIconSwitch )
862 {
863 f32 elapse = OSTicksToMilliseconds( OSDiffTick( OSGetTick(), banIconTime ) );
864
865 switch ( banIconMode )
866 {
867 case eAlphaInIcon: /* AlphaIn (250ms) */
868 banIconAlpha = ( u8 )( 255.9f * ( elapse / 250.f ) );
869 if ( elapse >= 250.f )
870 {
871 banIconTime = OSGetTick();
872 banIconMode = ePauseIcon;
873 banIconAlpha = 255;
874 }
875 break;
876 case ePauseIcon: /* Pause (1000ms) */
877 if ( elapse >= 1000.f )
878 {
879 banIconTime = OSGetTick();
880 banIconMode = eAlphaOutIcon;
881 }
882 break;
883 case eAlphaOutIcon: /* AlphaOut (250ms) */
884 banIconAlpha = ( u8 )( 255.9f * ( ( 250.f - elapse ) / 250.f ) );
885 if ( elapse >= 250.f )
886 {
887 banIconAlpha = 0;
888 banIconSwitch = OFF;
889 }
890 break;
891 }
892
893 DrawBanIcon( banIconAlpha );
894 }
895 }
896 }
897 DEMODoneRender();
898
899 /* Process executed when the RESET or Power Button is pressed */
900 if(reset_called)
901 {
902 /*When other than the HOME Menu, go straight on to reset */
903 if( homeBtnSwitch == OFF )
904 {
905 OSRestart(0);
906 }
907 /* If the HOME Menu is running, reset after black-out */
908 else
909 {
910 HBMStartBlackOut();
911 }
912 reset_called = false;
913 }
914
915 if(power_called)
916 {
917 OSReturnToMenu();
918 }
919 }
920 }
921
922