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