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