1 /*---------------------------------------------------------------------------*
2 Project: Launch Disk Demo
3 File: discnanddemo1.c
4
5 Copyright 2007 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: discnanddemo1.c,v $
14 Revision 1.2.2.1 2009/10/16 02:17:09 iwai_yuma
15 Removed <private/OS*.h> and added <revolution/discnand.h>.
16
17 Revision 1.2 2009/10/05 05:52:47 iwai_yuma
18 Initial check-in to HEAD.
19
20 Revision 1.1.2.1 2008/11/18 09:02:40 ooizumi
21 Initial check-in.
22
23 $NoKeywords: $
24 *---------------------------------------------------------------------------*/
25
26 /*---------------------------------------------------------------------------*
27 * This demo illustrates how to handle errors. See __refresh_status() for
28 * the actual error handling code!
29 *---------------------------------------------------------------------------*/
30
31 #include <revolution/os/OSReset.h>
32 #include <revolution/discnand.h>
33 #include <demo.h>
34 #include <revolution.h>
35 #include <demo/DEMOWin.h>
36 #include <string.h>
37 #include <stdio.h>
38
39 /*---------------------------------------------------------------------------*
40 * DVD definitions
41 *---------------------------------------------------------------------------*/
42 static DVDFileInfo FileInfo;
43 static volatile BOOL FileInfoIsInUse = FALSE;
44
45 static DVDDiskID DiskID;
46
47 #define GAMENAME "RABA"
48 #define COMPANYNAME "ZZ"
49
50 /*---------------------------------------------------------------------------*
51 * Misc
52 *---------------------------------------------------------------------------*/
53 #define MIN(x, y) ((x) < (y)? (x):(y))
54
55
56 /*---------------------------------------------------------------------------*
57 * Data to pass from command issuing routines to status printing routine.
58 *---------------------------------------------------------------------------*/
59 enum{
60 COMMAND_GET_ERROR_STATUS,
61 COMMAND_CHANGE_DISK,
62 COMMAND_PREPARE_DISK
63 };
64
65 typedef struct
66 {
67 u32 command;
68 s32 readLength;
69 } CommandBlockData;
70
71 static CommandBlockData Data;
72
73
74 /*---------------------------------------------------------------------------*
75 * Messages for errors
76 *---------------------------------------------------------------------------*/
77 typedef struct
78 {
79 char* line[6];
80 } Message;
81
82 // Error messages. XXX Caution: Subject to change.
83 Message ErrorMessages[] = {
84 {"Please insert the disc for xxx.", "", "", "", "", ""},
85 {"This disc is not for xxx.", "Please insert the disc for xxx.", "", "", "", ""},
86 {"The disc could not be read.", "", "Please read the NINTENDO REVOLUTION",
87 "Instruction Booklet for more information", "", ""},
88 {"An error has occurred.", "", "Turn the power OFF and check", "the NINTENDO REVOLUTION",
89 "Instruction Booklet for", "further instructions."},
90 {"Please insert the next disc.", "", "", "", "", ""},
91 };
92
93 enum{
94 MESSAGE_NO_DISK = 0,
95 MESSAGE_WRONG_DISK,
96 MESSAGE_RETRY_ERROR,
97 MESSAGE_FATAL_ERROR,
98 MESSAGE_CHANGE_DISK
99 };
100
101
102 /*---------------------------------------------------------------------------*
103 * Prototypes
104 *---------------------------------------------------------------------------*/
105 static void InitWindows(void);
106
107 static void __status_refresh(DEMOWinInfo *handle);
108
109 static void Run_Demo(void);
110
111 static void MNU_cancel(DEMOWinMenuInfo *menu, u32 item, u32 *result);
112 static void MNU_launch_diskl(DEMOWinMenuInfo *menu, u32 item, u32 *result);
113 static void MNU_launch_diskv(DEMOWinMenuInfo *menu, u32 item, u32 *result);
114 static void MNU_get_disk_id(DEMOWinMenuInfo *menu, u32 item, u32 *result);
115 static void MNU_prepare_disk(DEMOWinMenuInfo *menu, u32 item, u32 *result);
116
117 /*---------------------------------------------------------------------------*
118 * Main Control Menu Stuff!
119 *---------------------------------------------------------------------------*/
120 DEMOWinMenuItem control_menu_items_nand[] =
121 {
122 { "ISSUE COMMAND", DEMOWIN_ITM_SEPARATOR, NULL, NULL },
123 { " OSLaunchDiskl", DEMOWIN_ITM_NONE, MNU_launch_diskl, NULL },
124 { " OSLaunchDiskv", DEMOWIN_ITM_NONE, MNU_launch_diskv, NULL },
125 { " DVDCancel", DEMOWIN_ITM_NONE, MNU_cancel, NULL },
126 { " DVDPrepareDisk", DEMOWIN_ITM_NONE, MNU_prepare_disk, NULL },
127 { " DVDGetCurrentDiskID", DEMOWIN_ITM_NONE, MNU_get_disk_id, NULL },
128 { "", DEMOWIN_ITM_TERMINATOR, NULL, NULL }
129 };
130
131 DEMOWinMenuInfo control_menu =
132 {
133 "Launch Disk Demo", // title
134 NULL, // window handle
135 control_menu_items_nand, // list of menu items
136 50, // max num of items to display at a time
137 DEMOWIN_MNU_NONE, // attribute flags?
138
139 // user callbacks for misc menu operations
140 NULL, NULL, NULL, NULL,
141 // private menu info members; do not touch
142 0, 0, 0, 0, 0
143 };
144 DEMOWinMenuInfo *control_menu_ptr;
145
146 /*---------------------------------------------------------------------------*
147 * Debug and Status window stuff!
148 *---------------------------------------------------------------------------*/
149 DEMOWinInfo *debug_win; // debug window
150 DEMOWinInfo *status_win; // status window
151 DEMOWinInfo *errmsg_win; // error message window
152
153 /*---------------------------------------------------------------------------*
154 Name: InitWindows
155
156 Description: Initialize windows
157
158 Arguments: none
159
160 Returns: none
161 *---------------------------------------------------------------------------*/
InitWindows(void)162 static void InitWindows(void)
163 {
164 DEMOWinInfo *p;
165
166 control_menu_ptr = DEMOWinCreateMenuWindow(&control_menu, 20, 20);
167 p = control_menu_ptr->handle;
168
169 // Intialize a window for showing status of DVD commands
170 // By passing "__status_refresh" as the last argument, the window system
171 // calls "__status_refresh" once every frame. We use this function to
172 // handle errors in this demo.
173 status_win = DEMOWinCreateWindow((u16)(p->x2+5), p->y1, 620, (u16)(p->y1+100),
174 "Status", 0, __status_refresh);
175
176 // Initialize a window for debug output
177 debug_win = DEMOWinCreateWindow((u16)(p->x2+5), (u16)(p->y1+105), 620, 434,
178 "Debug", 1024, NULL);
179
180 // Initialize a window for showing error message
181 errmsg_win = DEMOWinCreateWindow(120, 150, 520, 250,
182 "Error message", 0, NULL);
183
184 // Open status and debug windows. We don't open error message window until
185 // we hit an error.
186 DEMOWinOpenWindow(debug_win);
187 DEMOWinOpenWindow(status_win);
188 }
189
190 /*---------------------------------------------------------------------------*
191 Name: __status_refresh
192
193 Description: This is the error handling part. This function is called
194 once every frame.
195
196 Arguments: handle Window handle for the status window
197
198 Returns: none
199 *---------------------------------------------------------------------------*/
__status_refresh(DEMOWinInfo * handle)200 static void __status_refresh(DEMOWinInfo *handle)
201 {
202 static u32 counter;
203 s32 message;
204 u32 i;
205 CommandBlockData *data;
206
207
208 // Clear status window (we only use the first two rows)
209 DEMOWinClearRow(handle, 0);
210 DEMOWinClearRow(handle, 1);
211
212 // We use "user data" as the information of the command that was issued
213 // last.
214 data = DVDGetUserData((DVDCommandBlock*)&FileInfo);
215
216 message = -1;
217
218 // This part is for debugging purpose. Show the drive's status on status
219 // window.
220 switch(DVDGetDriveStatus())
221 {
222 case DVD_STATE_END:
223 FileInfoIsInUse = FALSE;
224 DEMOWinPrintfXY(handle, 0, 1, "Command finished");
225 break;
226 case DVD_STATE_FATAL_ERROR:
227 DEMOWinPrintfXY(handle, 0, 1, "Fatal error occurred");
228 message = MESSAGE_FATAL_ERROR;
229 break;
230 case DVD_STATE_BUSY:
231 break;
232 case DVD_STATE_NO_DISK:
233 DEMOWinPrintfXY(handle, 0, 1, "No disk");
234 message = MESSAGE_NO_DISK;
235 break;
236 case DVD_STATE_WRONG_DISK:
237 DEMOWinPrintfXY(handle, 0, 1, "Wrong disk");
238 message = MESSAGE_WRONG_DISK;
239 break;
240 case DVD_STATE_RETRY:
241 DEMOWinPrintfXY(handle, 0, 1, "Please retry");
242 message = MESSAGE_RETRY_ERROR;
243 break;
244 case DVD_STATE_MOTOR_STOPPED:
245 DEMOWinPrintfXY(handle, 0, 1, "Ready to replace");
246 message = MESSAGE_CHANGE_DISK;
247 break;
248 }
249
250 // If necessary, launch error message window to show the error message to
251 // the user.
252 if (message >= 0)
253 {
254 DEMOWinOpenWindow(errmsg_win);
255 counter = (counter+1) % 60;
256 for (i = 0; i < 6; i++)
257 {
258 if (counter < 45)
259 {
260 DEMOWinClearRow(errmsg_win, (u16)i);
261 DEMOWinPrintfXY(errmsg_win, 0, (u16)i, ErrorMessages[message].line[i]);
262 }
263 else
264 {
265 DEMOWinClearRow(errmsg_win, (u16)i);
266 }
267 }
268 }
269 else
270 {
271 DEMOWinCloseWindow(errmsg_win);
272 }
273
274 if (OSGetResetSwitchState())
275 {
276 OSReport("reset is pressed\n");
277
278 while (OSGetResetSwitchState())
279 ;
280
281 OSReport("reset is released\n");
282
283 // Black out screen
284 VISetBlack(TRUE);
285 VIFlush();
286 VIWaitForRetrace();
287
288 OSRestart(3);
289 }
290
291 } // end __status_refresh()
292
293 char* launchArgv[] =
294 {
295 "launchArgv",
296 NULL
297 };
298
299 /*---------------------------------------------------------------------------*
300 Name: MNU_launch_diskl
301
302 Description:
303
304 Arguments: menu, item, result unused
305
306 Returns: none
307 *---------------------------------------------------------------------------*/
MNU_launch_diskl(DEMOWinMenuInfo * menu,u32 item,u32 * result)308 static void MNU_launch_diskl(DEMOWinMenuInfo *menu, u32 item, u32 *result)
309 {
310 #pragma unused(menu, item, result)
311 // Black out screen
312 VISetBlack(TRUE);
313 VIFlush();
314 VIWaitForRetrace();
315
316 OSLaunchDiskl(&DiskID, 0xdeadbeef, "launchArgl", NULL);
317 }
318
319 /*---------------------------------------------------------------------------*
320 Name: MNU_launch_diskv
321
322 Description:
323
324 Arguments: menu, item, result unused
325
326 Returns: none
327 *---------------------------------------------------------------------------*/
MNU_launch_diskv(DEMOWinMenuInfo * menu,u32 item,u32 * result)328 static void MNU_launch_diskv(DEMOWinMenuInfo *menu, u32 item, u32 *result)
329 {
330 #pragma unused(menu, item, result)
331 // Black out screen
332 VISetBlack(TRUE);
333 VIFlush();
334 VIWaitForRetrace();
335
336 OSLaunchDiskv(&DiskID, 0xabadcafe, launchArgv);
337 }
338
339 /*---------------------------------------------------------------------------*
340 Name: MNU_cancel
341
342 Description: Issue DVDCancel. This function is called when DVDCancel
343 is selected in the control window.
344
345 Arguments: menu, item, result unused
346
347 Returns: none
348 *---------------------------------------------------------------------------*/
MNU_cancel(DEMOWinMenuInfo * menu,u32 item,u32 * result)349 static void MNU_cancel(DEMOWinMenuInfo *menu, u32 item, u32 *result)
350 {
351 #pragma unused(menu, item, result)
352 DVDCancelAsync((DVDCommandBlock*)&FileInfo, NULL);
353 }
354
355 /*---------------------------------------------------------------------------*
356 Name: MNU_prepare_disk
357
358 Description: Issue DVDPrepareDisk
359
360 Arguments: menu Winmenuinfo for control window
361 item, result unused
362
363 Returns: none
364 *---------------------------------------------------------------------------*/
MNU_prepare_disk(DEMOWinMenuInfo * menu,u32 item,u32 * result)365 static void MNU_prepare_disk(DEMOWinMenuInfo *menu, u32 item, u32 *result)
366 {
367 #pragma unused(menu, item, result)
368 // Avoid using the same FileInfo/CommandBlock at the same time.
369 if (FileInfoIsInUse)
370 {
371 return;
372 }
373
374 // Pass information to __status_refresh()
375 Data.command = COMMAND_PREPARE_DISK;
376 DVDSetUserData((DVDCommandBlock*)&FileInfo, (void*)&Data);
377
378 FileInfoIsInUse = TRUE;
379 DVDPrepareDiskAsync((DVDCommandBlock*)&FileInfo, &DiskID, NULL);
380 }
381
382 /*---------------------------------------------------------------------------*
383 Name: MNU_get_disk_id
384
385 Description: Show disk id
386
387 Arguments: menu Winmenuinfo for control window
388 item, result unused
389
390 Returns: none
391 *---------------------------------------------------------------------------*/
MNU_get_disk_id(DEMOWinMenuInfo * menu,u32 item,u32 * result)392 static void MNU_get_disk_id(DEMOWinMenuInfo *menu, u32 item, u32 *result)
393 {
394 #pragma unused(menu, item, result)
395 DVDDiskID* id;
396
397 id = DVDGetCurrentDiskID();
398
399 DEMOWinLogPrintf(debug_win, "====Current disk ID====\n");
400 DEMOWinLogPrintf(debug_win, " Game Name ... %-4.4s\n", id->gameName);
401 DEMOWinLogPrintf(debug_win, " Company ..... %-2.2s\n", id->company);
402 DEMOWinLogPrintf(debug_win, " Disk # ...... %x\n", id->diskNumber);
403 DEMOWinLogPrintf(debug_win, " Game ver .... %x\n", id->gameVersion);
404 }
405
406 /*---------------------------------------------------------------------------*
407 Name: Run_Demo
408
409 Description: Main loop of the demo.
410
411 Arguments: none
412
413 Returns: none
414 *---------------------------------------------------------------------------*/
Run_Demo(void)415 static void Run_Demo(void)
416 {
417 DEMOWinPadInfo pad;
418
419 DEMOWinLogPrintf(debug_win, "-------------------------------\n");
420 DEMOWinLogPrintf(debug_win, "Launch disk sample\n");
421 DEMOWinLogPrintf(debug_win, "-------------------------------\n");
422 DEMOWinLogPrintf(debug_win, "- Stick Up/Down to move cursor\n");
423 DEMOWinLogPrintf(debug_win, "- Button A to select an item\n");
424 DEMOWinLogPrintf(debug_win, "- Button B to exit a menu\n");
425 DEMOWinLogPrintf(debug_win, "While you are executing a command, open cover, make no disk,\n");
426 DEMOWinLogPrintf(debug_win, "put other disks to see how to handle errors\n");
427
428 while(1)
429 {
430 // Launch control window. This funcion returns when B is pressed.
431 DEMOWinMenu(control_menu_ptr);
432
433 DEMOWinLogPrintf(debug_win, "-------------------------------------------\n");
434 DEMOWinLogPrintf(debug_win, "\nUse Stick Up/Down to scroll debug buffer.\n");
435 DEMOWinLogPrintf(debug_win, "\nHit Start to resume the demo.\n");
436
437 DEMOBeforeRender();
438 DEMOWinRefresh();
439 DEMODoneRender();
440 DEMOWinPadRead(&pad);
441
442 // Let the user to scroll the debug window. Press start button to
443 // go to the top of the outer loop and open the control window again.
444 while(1)
445 {
446
447 DEMOWinPadRead(&pad);
448
449 if (pad.pads[0].stickY < -50)
450 {
451 DEMOWinScrollWindow(debug_win, DEMOWIN_SCROLL_DOWN);
452 if (pad.pads[0].triggerLeft > 150)
453 {
454 DEMOWinScrollWindow(debug_win, DEMOWIN_SCROLL_DOWN);
455 DEMOWinScrollWindow(debug_win, DEMOWIN_SCROLL_DOWN);
456 }
457 }
458 else if (pad.pads[0].stickY > 50)
459 {
460 DEMOWinScrollWindow(debug_win, DEMOWIN_SCROLL_UP);
461 if (pad.pads[0].triggerLeft > 150)
462 {
463 DEMOWinScrollWindow(debug_win, DEMOWIN_SCROLL_UP);
464 DEMOWinScrollWindow(debug_win, DEMOWIN_SCROLL_UP);
465 }
466
467 }
468 else if (pad.changed_button[0] & PAD_BUTTON_START)
469 {
470 DEMOWinScrollWindow(debug_win, DEMOWIN_SCROLL_HOME);
471 // get out of the inner loop
472 break;
473 }
474
475 DEMOBeforeRender();
476 DEMOWinRefresh();
477 DEMODoneRender();
478
479 } // debug buffer scroll loop
480
481 } // forever loop
482
483
484 } // end Init_Player_Windows()
485
486 extern u32 OSGetLaunchCode(void);
487
main(s32 argc,char ** argv)488 void main (s32 argc, char** argv)
489 {
490 // generate disk id for disk launch
491 DVDGenerateDiskID(&DiskID, GAMENAME, COMPANYNAME, 0, 0);
492
493 // disabled the default disc fatal screen
494 DVDSetAutoFatalMessaging(FALSE);
495
496 // clear user data
497 DVDSetUserData((DVDCommandBlock*)&FileInfo, (void*)NULL);
498
499 DEMOInit(NULL);
500
501 OSReport("Disk number is %x\n", DVDGetCurrentDiskID()->diskNumber);
502
503 AIInit(NULL);
504
505 OSReport("AIInit done\n");
506
507 DEMOWinInit();
508
509 OSReport("DEMOWinInit done\n");
510
511 InitWindows();
512
513 OSReport("InitWindows done\n");
514
515 OSReport("OSGetAppType = %08X\n", OSGetAppType());
516 OSReport("OSGetResetCode = %08X\n", OSGetResetCode());
517 OSReport("OSGetLaunchCode = %08X\n", OSGetLaunchCode());
518 while(argc)
519 {
520 argc--;
521 OSReport("argv[%d] = %s\n", argc, argv[argc]);
522 }
523
524 Run_Demo();
525
526 } // end main
527