1 /*---------------------------------------------------------------------------*
2 Project: Revolution SDK DS-download test
3 File: mpdlsimple.c
4
5 Copyright 2006 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 $Log: mpdlntr2rvl.c,v $
14 Revision 1.13 2007/11/29 04:55:27 seiki_masashi
15 Added the const modifier.
16
17 Revision 1.12 2007/10/29 01:17:39 seiki_masashi
18 Added error handling
19
20 Revision 1.11 2007/10/27 15:27:06 seiki_masashi
21 Adjusted the display area
22
23 Revision 1.10 2007/10/27 14:51:22 seiki_masashi
24 Changed the refresh conditions for the count of the screen burn-in reduction feature
25 Fixed bugs.
26 Cleaned up the code
27
28 Revision 1.9 2007/10/27 11:22:14 seiki_masashi
29 Changed to use the MPDS library
30
31 Revision 1.8 2007/10/26 09:07:04 seiki_masashi
32 Added support for Shift_JIS and ISO-8859-1
33
34 Revision 1.7 2007/10/26 08:07:19 seiki_masashi
35 Added support for REXDEMOGetAnyMixedPadTrigger()
36
37 Revision 1.6 2007/10/04 09:41:35 seiki_masashi
38 Added support for MP_BEACON_PERIOD_AUTO
39
40 Revision 1.5 2007/07/30 10:40:19 kitase_hirotake
41 Eliminated warning(s).
42
43 Revision 1.4 2007/07/26 05:01:04 kitase_hirotake
44 Made changes so that DS input will cause the system to recover from the screen burn-in reduction state.
45
46 Revision 1.3 2007/02/16 06:30:15 yosizaki
47 Changed type of the playerbits (int->u32)
48
49 Revision 1.2 2006/12/01 09:42:35 kitase_hirotake
50 Revised to receive microphone input flag from DS.
51
52 Revision 1.1 2006/10/20 09:30:46 kitase_hirotake
53 Initial Upload
54
55 $NoKeywords: $
56 *---------------------------------------------------------------------------*/
57
58 //
59 // This is a demo of using MPDL to download a program to a DS and then reconnecting to that downloaded program.
60 //
61 //
62 // The demo also shows processing for screen burn-in reduction when using the DS as a controller.
63 //
64
65 #include <revolution.h>
66 #include <revolution/mpdl.h>
67 #include <revolution/mpds.h>
68 #include <revolution/mem.h>
69 #include <revolution/enc.h>
70
71 #include "rexdemo/demokpad.h"
72 #include "rexdemo/graphic.h"
73
74 #include <string.h>
75
76 /*===========================================================================*/
77 /* Settings */
78
79 #define USERHEAP_SIZE ( 1024 * 1024 )
80
81 #define DISP_OFFSET_X 16
82 #define DISP_OFFSET_Y 32
83
84 #define MY_GGID 0x003fff20
85
86 #define MY_MAX_NODES 15 // maximum number of child devices that can be connected (up to a maximum of 8 devices are guaranteed in Wii Sequential communications)
87 #define MY_DS_NODES 16 // The number of nodes, including the parent that is carrying out DataSharing
88 // for a normal application (MY_MAX_NODES+1)
89
90 #define MY_DS_LENGTH 8 // the shared data size per device for DataSharing
91 #define MY_DS_PORT 12
92
93 // When DataSharing is performed, the required transmission size is the shared size per device times the number of devices, plus 4 bytes.
94 #define MY_PARENT_MAX_SIZE ( (MY_DS_LENGTH * MY_DS_NODES) + MPDS_HEADER_SIZE )
95
96 static void* MyAlloc( u32 size );
97 static void MyFree( void* ptr );
98
99 /* Nintendo DS program image on memory */
100 static const u32 program_buffer_max = (u32)(3 * 1024 * 1024);
101 static u8 program_buffer[program_buffer_max] ATTRIBUTE_ALIGN(32);
102 static const char *program_path = "wmPadRead.srl";
103
104 /* MPDL work structure */
105 static MPDLConfig mpdlConfig ATTRIBUTE_ALIGN(32) =
106 {
107 MyAlloc,
108 MyFree,
109 2, // threadPriority
110 MY_GGID, // ggid
111 MP_TGID_AUTO, // tgid
112 MP_CHANNEL_AUTO, // channel
113
114 0, // serverColor
115 L"Wii", // serverName
116 L"wmPadRead Demo", // programTitle
117 L"Let's share PAD info!", // programComment
118 16, // programMaxEntry
119 program_buffer, // programImage
120
121 };
122
123 /* The MPConfig that will be used for sharing the pad data in the latter half [of the demo]*/
124 static MPConfig config =
125 {
126 MyAlloc,
127 MyFree,
128
129 8, // threadPriority
130
131 MP_MODE_PARENT, // mode
132
133 MY_GGID, // ggid
134 MP_TGID_AUTO, // tgid
135
136 MP_CHANNEL_AUTO, // channel; normally MP_CHANNEL_AUTO
137
138 MP_LIFETIME_DEFAULT,// lifeTime; usually equal to MP_LIFETIME_DEFAULT
139
140 MP_BEACON_PERIOD_AUTO, // beaconPeriod; normally MP_BEACON_PERIOD_AUTO
141 MY_MAX_NODES, // maxNodes
142 MY_PARENT_MAX_SIZE, // parentMaxSize
143 MY_DS_LENGTH, // childMaxSize
144 TRUE, // entryFlag
145 FALSE, // multiBootFlag; usually FALSE
146
147 1, // frequency
148
149 0, // userGameInfoLength
150 { 0, }, // userGameInfo
151
152 NULL, // indicationCallbackFunction
153
154 /// ... // port configuration (can be set up using MPSetPortConfig)
155 };
156
157 /* The DataSharing settings that will be used for sharing the pad data in the latter half [of the demo]*/
158 void DataSharingPortCallbackFunction( s32 type, MPPortCallbackInfo* info );
159 static MPDSConfig mpdsConfig =
160 {
161 MY_DS_LENGTH, // dataLength
162
163 MY_DS_PORT, // port (must use one of sequential communications ports 12-15)
164 MP_PRIORITY_HIGH, // priority
165
166 TRUE, // isParent; always TRUE
167 (1 << MY_DS_NODES)-1, // aidBits (a binary number that is a row of 1's. The number of 1's is equal to MY_DS_NODES)
168 TRUE, // isDoubleMode
169 TRUE, // isAutoStart; always TRUE
170 DataSharingPortCallbackFunction // mpdsCallback
171 };
172
173 /*===========================================================================*/
174 /* Definitions */
175
176 // Nintendo DS buttons and keys
177 #define DSPAD_BUTTON_A 0x0001 // A
178 #define DSPAD_BUTTON_B 0x0002 // B
179 #define DSPAD_BUTTON_SELECT 0x0004 // SELECT
180 #define DSPAD_BUTTON_START 0x0008 // START
181 #define DSPAD_KEY_RIGHT 0x0010 // +Control Pad, RIGHT
182 #define DSPAD_KEY_LEFT 0x0020 // +Control Pad, LEFT
183 #define DSPAD_KEY_UP 0x0040 // +Control Pad, UP
184 #define DSPAD_KEY_DOWN 0x0080 // +Control Pad, DOWN
185 #define DSPAD_BUTTON_R 0x0100 // R
186 #define DSPAD_BUTTON_L 0x0200 // L
187 #define DSPAD_BUTTON_X 0x0400 // X
188 #define DSPAD_BUTTON_Y 0x0800 // Y
189 #define DSPAD_BUTTON_DEBUG 0x2000 // Debug button
190 #define DSPAD_DETECT_FOLD_MASK 0x8000 // mask: folding
191
192 static const GXColor white = { 0xFF, 0xFF, 0xFF, };
193 static const GXColor yellow = { 0xFF, 0xFF, 0x00, };
194 static const GXColor gray = { 0x80, 0x80, 0x80, };
195 static const GXColor black = { 0x00, 0x00, 0x00, };
196 static const GXColor red = { 0xFF, 0x00, 0x18, };
197 static const GXColor green = { 0x00, 0xFF, 0x00, };
198
199 /*===========================================================================*/
200 /* Variables */
201
202 static MEMHeapHandle userHeap;
203
204 static ENCContext encContext;
205
206 static MPDSContext mpdsContext;
207
208 static u32 connectedAid;
209
210 static s32 viWidth;
211 static s32 viHeight;
212
213 typedef struct {
214 u16 keyData;
215 u8 touchPanel_x;
216 u8 touchPanel_y;
217 u8 mic;
218 u8 touch;
219 u8 padding[2];
220 } MyPadData;
221 static MyPadData recvData[MY_DS_NODES];
222 static MyPadData pre_recvData[MY_DS_NODES];
223
224 /*===========================================================================*/
225 /* Functions */
226
227 static void DoDownload( void );
228 static void DoPadSharing( void );
229 static u16 ConvKPadKeyToDSPad(u32 mixedKey);
230 static BOOL IsInputDifferent(const MyPadData* prevPadData, const MyPadData* padData);
231
232 /*===========================================================================*/
233
main(void)234 void main(void)
235 {
236 GXRenderModeObj* tvmode = NULL;
237 u32 tv_format;
238
239 /* Initialize OS and memory heap */
240 DVDInit();
241 OSReport( "startup mpdlsimple demo\n" );
242 REXDEMOKPadInit();
243 REXDEMOInitScreen( FALSE );
244 REXDEMOSetGroundColor( black );
245 REXDEMOSetFontSize( 10, 20 );
246 REXDEMOBeginRender();
247 REXDEMOWaitRetrace();
248
249 tv_format = VIGetTvFormat();
250 switch (tv_format)
251 {
252 case VI_NTSC:
253 tvmode = &GXNtsc480IntDf;
254 break;
255 case VI_MPAL:
256 tvmode = &GXMpal480IntDf;
257 break;
258 case VI_EURGB60:
259 tvmode = &GXEurgb60Hz480IntDf;
260 break;
261 case VI_PAL:
262 tvmode = &GXPal528IntDf;
263 break;
264 default:
265 OSHalt("Unknown TV format\n");
266 }
267 viWidth = tvmode->viWidth - DISP_OFFSET_X*2;
268 viHeight = tvmode->viHeight - DISP_OFFSET_Y*2;
269
270 /* Initialize heap for MP library */
271 {
272 void* heapAddress;
273
274 heapAddress = OSGetMEM2ArenaLo();
275 OSSetMEM2ArenaLo( (void*)OSRoundUp32B( (u32)heapAddress + USERHEAP_SIZE ) );
276 userHeap = MEMCreateExpHeapEx( heapAddress, USERHEAP_SIZE, MEM_HEAP_OPT_THREAD_SAFE );
277 if( userHeap == NULL )
278 {
279 OSHalt( "Could not create heap.\n" );
280 }
281 }
282
283 /* Initialize ENCContext for ROM Font*/
284 (void)ENCInitContext(&encContext);
285 (void)ENCSetExternalEncoding(&encContext,
286 ( OSGetFontEncode() == OS_FONT_ENCODE_SJIS )
287 ? (const u8*)"Shift_JIS" : (const u8*)"ISO-8859-1");
288 (void)ENCSetBreakType(&encContext, ENC_BR_KEEP);
289 (void)ENCSetAlternativeCharacter(&encContext, L'?', L'?');
290
291 /* Load Nintendo DS program from DVD */
292 {
293 DVDFileInfo file[1];
294 if ( !DVDOpen(program_path, file) )
295 {
296 OSHalt( "failed to read NintendoDS program file from DVD.\n" );
297 }
298 else
299 {
300 const u32 file_len = ( (DVDGetLength(file) + 31) & ~31 );
301 if ( file_len > program_buffer_max )
302 {
303 OSHalt( "specified program file is too large.\n" );
304 }
305 else if ( DVDRead(file, program_buffer, (int)file_len, 0) <= 0 )
306 {
307 OSHalt( "failed to read NintendoDS program file from DVD.\n" );
308 }
309 (void)DVDClose(file);
310 }
311 }
312
313 (void)NETMemSet(recvData, 0, sizeof(recvData));
314
315 for (; ;)
316 {
317 DoDownload();
318
319 OSReport("\n--- program has been completed ---\n");
320
321 OSReport("\n--- wait for downloaded DS demo connect to Wii ---\n");
322
323 DoPadSharing();
324 }
325 }
326
DoDownload(void)327 void DoDownload( void )
328 {
329 BOOL is_entry_closed;
330 u32 fixed_entry;
331
332 /* Initialize and startup MPDL */
333 if ( MPDLStartup( &mpdlConfig ) != MP_RESULT_OK )
334 {
335 OSHalt( "failed to startup MPDL!\n" );
336 }
337
338 is_entry_closed = FALSE;
339 fixed_entry = 0;
340 for (; ;)
341 {
342 int i;
343 u32 entry;
344 u32 booted;
345
346 REXDEMOKPadRead();
347
348 /* Update sequence */
349 entry = MPDLGetEntryBitmap();
350 booted = MPDLGetBootedBitmap();
351 if (!is_entry_closed)
352 {
353 const u32 full_entry = (u32)(((1 << mpdlConfig.programMaxEntry) - 1) & ~1);
354 if ((entry == full_entry) ||
355 ((REXDEMOGetAnyMixedPadTrigger() & (KPAD_BUTTON_A | (PAD_BUTTON_A << 16))) != 0))
356 {
357 is_entry_closed = TRUE;
358 fixed_entry = MPDLStartDownload();
359 }
360 }
361 else if (entry == 0)
362 {
363 break;
364 }
365
366 /* DrawFrame */
367 REXDEMOBeginRender();
368 {
369 /* *INDENT-OFF* */
370 static const GXColor ds_ipl_color_table[16] =
371 {
372 { 0x63, 0x84, 0x9C, }, /* GRAY */
373 { 0xBD, 0x4A, 0x00, }, /* BROWN */
374 { 0xFF, 0x00, 0x18, }, /* RED */
375 { 0xFF, 0x8C, 0xFF, }, /* PINK */
376 { 0xFF, 0x94, 0x00, }, /* ORANGE */
377 { 0xF7, 0xE7, 0x00, }, /* YELLOW */
378 { 0xAD, 0xFF, 0x00, }, /* LIME_GREEN */
379 { 0x00, 0xFF, 0x00, }, /* GREEN */
380 { 0x00, 0xA5, 0x39, }, /* DARK_GREEN */
381 { 0x4A, 0xDE, 0x8C, }, /* SEA_GREEN */
382 { 0x31, 0xBD, 0xF7, }, /* TURQUOISE */
383 { 0x00, 0x5A, 0xF7, }, /* BLUE */
384 { 0x00, 0x00, 0x94, }, /* DARK_BLUE */
385 { 0x8C, 0x00, 0xD6, }, /* PURPLE */
386 { 0xD6, 0x00, 0xEF, }, /* VIOLET */
387 { 0xFF, 0x00, 0x94, }, /* MAGENTA */
388 };
389 /* *INDENT-ON* */
390 const s16 ox = 4, oy = 48;
391
392 /* header */
393 REXDEMOSetTextColor(white);
394 REXDEMOPrintf(4, 8, 0, "MPDL simple sample");
395 REXDEMOSetTextColor(yellow);
396 if (!is_entry_closed)
397 {
398 REXDEMOPrintf(4, 24, 0, "entry is opened.");
399 REXDEMOPrintf(200, 24, 0, "(press A to start download)");
400 }
401 else if (entry > 0)
402 {
403 REXDEMOPrintf(4, 24, 0, "entry is closed, now downloading...");
404 }
405 else
406 {
407 REXDEMOPrintf(4, 24, 0, "download has been completed.");
408 REXDEMOPrintf(320, 24, 0, "(press A to restart new entry)");
409 // Download has been completed
410 }
411
412 /* entries */
413 REXDEMOSetTextColor(white);
414 REXDEMOPrintf(ox, oy, 0, "AID STATUS MAC-ADDR NAME");
415 for (i = 1; i < 16; ++i)
416 {
417 const s16 sy = (s16)(oy + i * 15);
418 MPDLPlayerInfo info[1];
419 BOOL valid_player = MPDLGetPlayerInfo(i, info);
420 REXDEMOSetTextColor(valid_player ? ds_ipl_color_table[info->color] : gray);
421
422 /* AID */
423 REXDEMOPrintf(ox + 5, sy, 0, "%2d", i);
424
425 /* STATUS */
426 if (!is_entry_closed)
427 {
428 if (valid_player)
429 {
430 REXDEMOPrintf(ox + 40, sy, 0, "ready");
431 }
432 else if (i < mpdlConfig.programMaxEntry)
433 {
434 REXDEMOPrintf(ox + 40, sy, 0, " none ");
435 }
436 }
437 else
438 {
439 if (valid_player)
440 {
441 if ((booted & (1 << i)) != 0)
442 {
443 REXDEMOPrintf(ox + 40, sy, 0, "booted");
444 }
445 else
446 {
447 REXDEMOPrintf(ox + 40, sy, 0, " %3d%% ", info->progress);
448 }
449 }
450 else if ((fixed_entry & (1 << i)) != 0)
451 {
452 REXDEMOPrintf(ox + 40, sy, 0, "failed");
453 }
454 }
455
456 /* MAC-ADDR & NAME */
457 if (valid_player)
458 {
459 char name[MPDL_PLAYER_NAME_MAX + 1];
460 {
461 ENCContext convCtx;
462 s32 dstlen, srclen;
463 u16 nameUTF16[MPDL_PLAYER_NAME_MAX + 1];
464
465 dstlen = MPDL_PLAYER_NAME_MAX;
466 srclen = (s32)(NETMinU32(info->name_length, MPDL_PLAYER_NAME_MAX)*sizeof(u16));
467 NETSwapAndCopyMemory16(nameUTF16, info->name, (u32)srclen);
468 (void)NETMemSet(name, 0, sizeof(name));
469 (void)ENCDuplicateContext(&convCtx, &encContext);
470 (void)ENCConvertFromInternalEncoding(&convCtx, (u8*)name, &dstlen, nameUTF16, &srclen);
471 }
472 REXDEMOPrintf(ox + 110, sy, 0,
473 "%02X%02X%02X:%02X%02X%02X %-10s",
474 info->mac[0], info->mac[1], info->mac[2],
475 info->mac[3], info->mac[4], info->mac[5], name);
476 }
477
478 }
479 }
480
481 REXDEMOWaitRetrace();
482 }
483 (void)MPDLCleanup();
484 }
485
DoPadSharing(void)486 void DoPadSharing( void )
487 {
488 s32 result;
489
490 connectedAid = 0;
491
492 result = MPDSInit( &mpdsContext, &mpdsConfig );
493 if ( result < 0 )
494 {
495 OSReport( "MPDSInit returns %08x\n", result );
496 OSHalt("** panic **");
497 }
498
499 result = MPDSSetupPortConfig( &mpdsContext, &config );
500 if ( result < 0 )
501 {
502 OSReport( "MPDSSetupPortConfig returns %08x\n", result );
503 OSHalt("** panic **");
504 }
505
506 result = MPStartup( &config );
507 if( result != MP_RESULT_OK )
508 {
509 OSReport( "MPStartup returns %08x\n", result );
510 OSHalt( "** panic **\n" );
511 }
512
513 {
514 static MyPadData sendData;
515 u32 count;
516
517 for ( count = 0; TRUE; count++ )
518 {
519 int i;
520 MPDSDataSet recvDataSet;
521 BOOL dimmingFlag; // Screen burn-in reduction feature refresh flag.
522 int pointX, pointY;
523 int dsPointX, dsPointY;
524 BOOL touch;
525
526 REXDEMOKPadRead();
527
528 (void)NETMemSet( &sendData, 0, sizeof(sendData) );
529 sendData.keyData = MPHToMP16(ConvKPadKeyToDSPad(REXDEMOKPadStatus[0].hold));
530 pointX = pointY = 0;
531 touch = FALSE;
532 if (REXDEMOKPadStatus[0].wpad_err == WPAD_ERR_NONE
533 && ((REXDEMOKPadStatus[0].dev_type == WPAD_DEV_CORE) || (REXDEMOKPadStatus[0].dev_type == WPAD_DEV_FREESTYLE)))
534 {
535 if (REXDEMOKPadStatus[0].dpd_valid_fg > 0)
536 {
537 pointX = (int)(REXDEMOKPadStatus[0].pos.x * 304 + 304);
538 pointY = (int)(REXDEMOKPadStatus[0].pos.y * 224 + 224);
539 touch = TRUE;
540 }
541 }
542 dsPointX = (pointX * 256 / viWidth);
543 dsPointY = (pointY * 192 / viHeight);
544 if ( dsPointX < 0 ) dsPointX = 0;
545 if ( 255 < dsPointX ) dsPointX = 255;
546 if ( dsPointY < 0 ) dsPointY = 0;
547 if ( 191 < dsPointY ) dsPointY = 191;
548 sendData.touch = (u8)touch;
549 sendData.touchPanel_x = (u8)dsPointX;
550 sendData.touchPanel_y = (u8)dsPointY;
551
552 // Share data using DataSharing
553 // Because the period of the vertical synchronization signal is different for the Wii and the DS, this will fail periodically even if the MPDSTryStep function is called to match with the period of the Wii's vertical synchronization signal.
554 //
555 // In order to maximize the efficiency of the communication, call the MPDSStep function synchronously in a separate thread, as shown in the mpdsmodel demo.
556 //
557 result = MPDSTryStep( &mpdsContext, &sendData, &recvDataSet );
558
559 dimmingFlag = FALSE;
560
561 if ( result == MP_RESULT_OK )
562 {
563 // Successfully received shared data
564 const u8* data;
565
566 // Parse the contents of the shared data
567 for ( i = 0; i < MY_MAX_NODES+1; i++ )
568 {
569 MyPadData prevPadData;
570 (void)NETMemCpy(&prevPadData, &recvData[i], sizeof(MyPadData));
571
572 data = MPDSGetData( &mpdsContext, &recvDataSet, (u32)i );
573 if ( data != NULL )
574 {
575 // Was able to share data from the i-th sharing partner
576 #if 0
577 OSReport( "received data from aid %d: 0x%04x %03d %03d\n",
578 i,
579 MPMPToH32(*(u32*)data), MPMPToH32(*((u32*)data+1)) >> 16, MPMPToH32(*((u32*)data+1)) & 0xffff );
580 #endif
581 (void)NETMemCpy(&recvData[i], data, sizeof(MyPadData));
582 }
583 else
584 {
585 (void)NETMemSet(&recvData[i], 0, sizeof(MyPadData));
586 }
587
588 // Were there any changes in input that will refresh the screen burn-in reduction feature?
589 dimmingFlag = dimmingFlag || IsInputDifferent(&prevPadData, &recvData[i]);
590 }
591 }
592 else if ( result == MP_RESULT_NO_DATA )
593 {
594 // Failed to receive the shared data
595 }
596 else
597 {
598 // Unexpected error
599 OSReport( "MPDSTryStep returns %d\n", result );
600 break;
601 }
602
603 // If there is any change in key input from the DS, refresh the countdown for the screen burn-in reduction
604 if ( dimmingFlag )
605 {
606 // Refresh the countdown for the screen burn-in reduction
607 if ( VIResetDimmingCount() == TRUE )
608 {
609 dimmingFlag = FALSE;
610 OSReport("== Reset dimming count! ==\n");
611 }
612 }
613
614 REXDEMOBeginRender();
615 {
616 for (i = 0; i <= 16; i++)
617 {
618 if (i == 0 || (connectedAid & (1 << (i - 1))))
619 {
620 u16 keyData = MPMPToH16(recvData[i].keyData);
621
622 if (i == 0)
623 {
624 // Draw the PAD information on the Wii side
625 REXDEMOSetTextColor(white);
626 REXDEMOPrintf(50+(i%4)*160, 5+(i/4)*120+DISP_OFFSET_Y, 0, "aid : %d", i);
627
628 REXDEMOSetTextColor( (keyData & DSPAD_BUTTON_A) ? red : green) ;
629 REXDEMOPrintf(60+(i%4)*160, 25+(i/4)*120+DISP_OFFSET_Y, 0, "A");
630 REXDEMOSetTextColor( (keyData & DSPAD_BUTTON_B) ? red : green) ;
631 REXDEMOPrintf(60+(i%4)*160, 55+(i/4)*120+DISP_OFFSET_Y, 0, "B");
632
633 REXDEMOSetTextColor( (keyData & DSPAD_BUTTON_L) ? red : green) ;
634 REXDEMOPrintf(85+(i%4)*160, 60+(i/4)*120+DISP_OFFSET_Y, 0, "M");
635 REXDEMOSetTextColor( (keyData & DSPAD_BUTTON_R) ? red : green) ;
636 REXDEMOPrintf(85+(i%4)*160, 20+(i/4)*120+DISP_OFFSET_Y, 0, "P");
637
638 REXDEMOSetTextColor( (keyData & DSPAD_KEY_UP) ? red : green) ;
639 REXDEMOPrintf(5+(i%4)*160, 40+(i/4)*120+DISP_OFFSET_Y, 0, "U");
640 REXDEMOSetTextColor( (keyData & DSPAD_KEY_DOWN) ? red : green) ;
641 REXDEMOPrintf(35+(i%4)*160, 40+(i/4)*120+DISP_OFFSET_Y, 0, "D");
642 REXDEMOSetTextColor( (keyData & DSPAD_KEY_LEFT) ? red : green) ;
643 REXDEMOPrintf(20+(i%4)*160, 55+(i/4)*120+DISP_OFFSET_Y, 0, "L");
644 REXDEMOSetTextColor( (keyData & DSPAD_KEY_RIGHT) ? red : green) ;
645 REXDEMOPrintf(20+(i%4)*160, 25+(i/4)*120+DISP_OFFSET_Y, 0, "R");
646
647 REXDEMOSetTextColor( (keyData & DSPAD_BUTTON_X) ? red : green) ;
648 REXDEMOPrintf(110+(i%4)*160, 40+(i/4)*120+DISP_OFFSET_Y, 0, "1");
649 REXDEMOSetTextColor( (keyData & DSPAD_BUTTON_Y) ? red : green) ;
650 REXDEMOPrintf(130+(i%4)*160, 40+(i/4)*120+DISP_OFFSET_Y, 0, "2");
651
652 REXDEMOSetTextColor( (keyData & DSPAD_BUTTON_START) ? red : green);
653 REXDEMOPrintf(85+(i%4)*160, 40+(i/4)*120+DISP_OFFSET_Y, 0, "H");
654 }
655 else
656 {
657 // Draw the PAD information on the DS side
658 REXDEMOSetTextColor(white);
659 REXDEMOPrintf(50+(i%4)*160, 5+(i/4)*120+DISP_OFFSET_Y, 0, "aid : %d", i);
660
661 REXDEMOSetTextColor( (keyData & DSPAD_BUTTON_A) ? red : green) ;
662 REXDEMOPrintf(130+(i%4)*160, 55+(i/4)*120+DISP_OFFSET_Y, 0, "A");
663 REXDEMOSetTextColor( (keyData & DSPAD_BUTTON_B) ? red : green) ;
664 REXDEMOPrintf(110+(i%4)*160, 63+(i/4)*120+DISP_OFFSET_Y, 0, "B");
665
666 REXDEMOSetTextColor( (keyData & DSPAD_BUTTON_L) ? red : green) ;
667 REXDEMOPrintf(20+(i%4)*160, 15+(i/4)*120+DISP_OFFSET_Y, 0, "L");
668 REXDEMOSetTextColor( (keyData & DSPAD_BUTTON_R) ? red : green) ;
669 REXDEMOPrintf(130+(i%4)*160, 15+(i/4)*120+DISP_OFFSET_Y, 0, "R");
670
671 REXDEMOSetTextColor( (keyData & DSPAD_KEY_UP) ? red : green) ;
672 REXDEMOPrintf(20+(i%4)*160, 40+(i/4)*120+DISP_OFFSET_Y, 0, "U");
673 REXDEMOSetTextColor( (keyData & DSPAD_KEY_DOWN) ? red : green) ;
674 REXDEMOPrintf(20+(i%4)*160, 70+(i/4)*120+DISP_OFFSET_Y, 0, "D");
675 REXDEMOSetTextColor( (keyData & DSPAD_KEY_LEFT) ? red : green) ;
676 REXDEMOPrintf(5+(i%4)*160, 55+(i/4)*120+DISP_OFFSET_Y, 0, "L");
677 REXDEMOSetTextColor( (keyData & DSPAD_KEY_RIGHT) ? red : green) ;
678 REXDEMOPrintf(35+(i%4)*160, 55+(i/4)*120+DISP_OFFSET_Y, 0, "R");
679
680 REXDEMOSetTextColor( (keyData & DSPAD_BUTTON_START) ? red : green) ;
681 REXDEMOPrintf(85+(i%4)*160, 55+(i/4)*120+DISP_OFFSET_Y, 0, "S");
682 REXDEMOSetTextColor( (keyData & DSPAD_BUTTON_SELECT) ? red : green) ;
683 REXDEMOPrintf(65+(i%4)*160, 55+(i/4)*120+DISP_OFFSET_Y, 0, "S");
684
685 REXDEMOSetTextColor( (keyData & DSPAD_BUTTON_X) ? red : green) ;
686 REXDEMOPrintf(130+(i%4)*160, 33+(i/4)*120+DISP_OFFSET_Y, 0, "X");
687 REXDEMOSetTextColor( (keyData & DSPAD_BUTTON_Y) ? red : green) ;
688 REXDEMOPrintf(110+(i%4)*160, 40+(i/4)*120+DISP_OFFSET_Y, 0, "Y");
689
690 //---- Display DS system closed detection state
691 REXDEMOSetTextColor( (keyData & DSPAD_DETECT_FOLD_MASK) ? red : green) ;
692 REXDEMOPrintf(75+(i%4)*160, 25+(i/4)*120+DISP_OFFSET_Y, 0, "F");
693
694 //---- Availability of microphone input
695 REXDEMOSetTextColor( (recvData[i].mic) ? red : green) ;
696 REXDEMOPrintf(75+(i%4)*160, 70+(i/4)*120+DISP_OFFSET_Y, 0, "M");
697
698 REXDEMOSetTextColor(white);
699 REXDEMOPrintf(20+(i%4)*160, 90+(i/4)*120+DISP_OFFSET_Y, 0, "(%03d : %03d)", recvData[i].touchPanel_x, recvData[i].touchPanel_y);
700 }
701
702 // Point to the touch panel information on the screen
703 if ( recvData[i].touch )
704 {
705 REXDEMOSetTextColor( red );
706 REXDEMOPrintf( (recvData[i].touchPanel_x * viWidth) / 256 + DISP_OFFSET_X,
707 (recvData[i].touchPanel_y * viHeight) / 192 + DISP_OFFSET_Y,
708 0, "%1x", i);
709 }
710 }
711 }
712 }
713
714 REXDEMOSetTextColor( white );
715 REXDEMOWaitRetrace();
716 }
717 }
718
719 (void)MPCleanup();
720 }
721
DataSharingPortCallbackFunction(s32 type,MPPortCallbackInfo * info)722 void DataSharingPortCallbackFunction( s32 type, MPPortCallbackInfo* info )
723 {
724 switch( type )
725 {
726 case MP_PORT_CB_TYPE_STARTUP:
727 OSReport( "PortCallback: startup notification\n" );
728 break;
729
730 case MP_PORT_CB_TYPE_CLEANUP:
731 OSReport( "PortCallback: cleanup notification\n" );
732 break;
733
734 case MP_PORT_CB_TYPE_CONNECTED:
735 OSReport( "PortCallback: connected(%d) " MP_MACADDRESS_PRINT_FORMAT "\n",
736 info->connected.fromAid,
737 MP_MACADDRESS_PRINT_LIST(info->connected.macAddress) );
738 OSReport("--> connectedAid = %x\n", info->connected.fromAid);
739 connectedAid |= ( 1 << (info->connected.fromAid - 1) );
740 OSReport("+++ connectedAid map = %x\n", connectedAid);
741 break;
742
743 case MP_PORT_CB_TYPE_DISCONNECTED:
744 OSReport( "PortCallback: disconnected(%d) " MP_MACADDRESS_PRINT_FORMAT "\n",
745 info->disconnected.fromAid,
746 MP_MACADDRESS_PRINT_LIST(info->disconnected.macAddress) );
747 OSReport("<-- disconnectedAid = %x\n", info->disconnected.fromAid);
748 connectedAid &= ~( 1 << (info->disconnected.fromAid - 1) );
749 OSReport("+++ connectedAid map = %x\n", connectedAid);
750 break;
751
752 case MPDS_PORT_CB_TYPE_DATASET_RECEIVED:
753 break;
754
755 default:
756 OSReport( "PortCallback: Unknown Type: %d\n", type );
757 break;
758 }
759 }
760
761 /*===========================================================================*/
762
MyAlloc(u32 size)763 void* MyAlloc( u32 size )
764 {
765 return MEMAllocFromExpHeapEx( userHeap, size, 32 );
766 }
767
MyFree(void * ptr)768 void MyFree( void* ptr )
769 {
770 MEMFreeToExpHeap( userHeap, ptr );
771 }
772
773 /*===========================================================================*/
774
ConvKPadKeyToDSPad(u32 mixedKey)775 u16 ConvKPadKeyToDSPad(u32 mixedKey)
776 {
777 u16 key = 0;
778
779 if ( mixedKey & (KPAD_BUTTON_LEFT | (PAD_BUTTON_LEFT << 16)) )
780 {
781 key |= DSPAD_KEY_LEFT;
782 }
783 if ( mixedKey & (KPAD_BUTTON_RIGHT | (PAD_BUTTON_RIGHT << 16)) )
784 {
785 key |= DSPAD_KEY_RIGHT;
786 }
787 if ( mixedKey & (KPAD_BUTTON_UP | (PAD_BUTTON_UP << 16)) )
788 {
789 key |= DSPAD_KEY_UP;
790 }
791 if ( mixedKey & (KPAD_BUTTON_DOWN | (PAD_BUTTON_DOWN << 16)) )
792 {
793 key |= DSPAD_KEY_DOWN;
794 }
795 if ( mixedKey & (KPAD_BUTTON_A | (PAD_BUTTON_A << 16)) )
796 {
797 key |= DSPAD_BUTTON_A;
798 }
799 if ( mixedKey & (KPAD_BUTTON_B | (PAD_BUTTON_B << 16)) )
800 {
801 key |= DSPAD_BUTTON_A;
802 }
803 if ( mixedKey & (KPAD_BUTTON_1 | (PAD_BUTTON_X << 16)) )
804 {
805 key |= DSPAD_BUTTON_X;
806 }
807 if ( mixedKey & (KPAD_BUTTON_2 | (PAD_BUTTON_Y << 16)) )
808 {
809 key |= DSPAD_BUTTON_Y;
810 }
811 if ( mixedKey & (KPAD_BUTTON_PLUS | (PAD_TRIGGER_R << 16)) )
812 {
813 key |= DSPAD_BUTTON_R;
814 }
815 if ( mixedKey & (KPAD_BUTTON_MINUS | (PAD_TRIGGER_L << 16)) )
816 {
817 key |= DSPAD_BUTTON_L;
818 }
819 if ( mixedKey & (KPAD_BUTTON_HOME | (PAD_BUTTON_START << 16)) )
820 {
821 key |= DSPAD_BUTTON_START;
822 }
823
824 return key;
825 }
826
IsInputDifferent(const MyPadData * prevPadData,const MyPadData * padData)827 BOOL IsInputDifferent(const MyPadData* prevPadData, const MyPadData* padData)
828 {
829 return ( prevPadData->keyData != padData->keyData
830 || prevPadData->touch != padData->touch
831 #if 0
832 // It is sufficient to make the normal ON/OFF of the touch into a trigger, so it is probably better not to refresh the count of the screen burn-in reduction feature during changes to the touch panel coordinates.
833 //
834 //
835 || prevPadData->touchPanel_x != padData->touchPanel_x
836 || prevPadData->touchPanel_y != padData->touchPanel_y
837 #endif
838 #if 0
839 // Normally, you should not refresh the count of the screen burn-in reduction feature based on mic input. However, there are exceptional situations in which using [mic input] as a trigger is conceivable for applications that do not have any input other than the DS microphone.
840 //
841 //
842 || prevPadData->mic != padData->mic
843 #endif
844 );
845 }
846
847 /*===========================================================================*/
848