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