1 /*---------------------------------------------------------------------------*
2   Project:  Revolution DVD error handling demo
3   File:     errorhandling.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: errorhandling.c,v $
14   Revision 1.8  2006/09/19 00:24:27  ooizumi
15   Removed the code to handle DVD_STATE_NO_INPUT status.
16 
17   Revision 1.7  2006/09/07 00:10:05  ooizumi
18   Modified to handle DVD_STATE_NO_INPUT state.
19 
20   Revision 1.6  2006/09/05 12:06:18  ooizumi
21   Enabled to handle reset switch.
22 
23   Revision 1.5  2006/07/28 02:01:17  ooizumi
24   Disabled handling reset switch code.
25 
26   Revision 1.4  2006/06/10 00:49:44  ooizumi
27   Disabled the default disc fatal screen.
28 
29   Revision 1.3  2006/02/28 21:17:19  ooizumi
30   Removed audio streaming functions.
31   Modified several comments.
32 
33   Revision 1.1  2006/01/17 02:43:50  hiratsu
34   Initial check in.
35 
36 
37     5     02/06/04 16:23 Hashida
38     Removed warnings.
39 
40     4     02/02/18 17:20 Hashida
41     Added DVDGetCurrentDiskID.
42     Fixed a bug that the demo crashes when executing DVDChangeDisk twice.
43 
44     3     1/03/02 5:48p Hashida
45     Added change disk.
46 
47     2     6/16/01 5:50a Hashida
48     Changed so that error status and play address are shown only when it's
49     succeeded.
50 
51     1     6/15/01 9:03p Hashida
52     Initial revision.
53 
54   $NoKeywords: $
55  *---------------------------------------------------------------------------*/
56 
57 /*---------------------------------------------------------------------------*
58  * This demo illustrates how to handle errors. See __refresh_status() for
59  * the actual error handling code!
60  *---------------------------------------------------------------------------*/
61 
62 #include <demo.h>
63 #include <revolution.h>
64 #include <demo/DEMOWin.h>
65 #include <string.h>
66 #include <stdio.h>
67 #include "selectfile.h"
68 
69 /*---------------------------------------------------------------------------*
70  * DVD definitions
71  *---------------------------------------------------------------------------*/
72 #define DVD_BUFFER_SIZE             0xf00000
73 static void*                        Buffer;
74 
75 static DVDFileInfo                  FileInfo;
76 static volatile BOOL                FileInfoIsInUse = FALSE;
77 
78 static DVDDiskID                    DiskID;
79 
80 /*---------------------------------------------------------------------------*
81  * Misc
82  *---------------------------------------------------------------------------*/
83 #define MIN(x, y)                   ((x) < (y)? (x):(y))
84 
85 
86 /*---------------------------------------------------------------------------*
87  * Data to pass from command issuing routines to status printing routine.
88  *---------------------------------------------------------------------------*/
89 enum{
90     COMMAND_READ,
91     COMMAND_SEEK,
92     COMMAND_GET_ERROR_STATUS,
93     COMMAND_CHANGE_DISK
94 };
95 
96 typedef struct
97 {
98     u32             command;
99     s32             readLength;
100 } CommandBlockData;
101 
102 static CommandBlockData         Data;
103 
104 
105 /*---------------------------------------------------------------------------*
106  * Messages for errors
107  *---------------------------------------------------------------------------*/
108 typedef struct
109 {
110     char*           line[6];
111 } Message;
112 
113 // Error messages. XXX Caution: Subject to change.
114 Message ErrorMessages[] = {
115     {"Please insert the disc for xxx.", "", "", "", "", ""},
116     {"This disc is not for xxx.", "Please insert the disc for xxx.", "", "", "", ""},
117     {"The disc could not be read.", "", "Please read the NINTENDO REVOLUTION",
118      "Instruction Booklet for more information", "", ""},
119     {"An error has occurred.", "", "Turn the power OFF and check", "the NINTENDO REVOLUTION",
120      "Instruction Booklet for", "further instructions."},
121     {"Please insert the next disc.", "", "", "", "", ""},
122 };
123 
124 enum{
125     MESSAGE_NO_DISK = 0,
126     MESSAGE_WRONG_DISK,
127     MESSAGE_RETRY_ERROR,
128     MESSAGE_FATAL_ERROR,
129     MESSAGE_CHANGE_DISK
130 };
131 
132 
133 /*---------------------------------------------------------------------------*
134  * Prototypes
135  *---------------------------------------------------------------------------*/
136 static void InitWindows(void);
137 
138 static void __status_refresh(DEMOWinInfo *handle);
139 
140 static void Run_Demo(void);
141 
142 static void MNU_read(DEMOWinMenuInfo *menu, u32 item, u32 *result);
143 static void MNU_seek(DEMOWinMenuInfo *menu, u32 item, u32 *result);
144 static void MNU_cancel(DEMOWinMenuInfo *menu, u32 item, u32 *result);
145 static void MNU_change_disk(DEMOWinMenuInfo *menu, u32 item, u32 *result);
146 static void MNU_get_disk_id(DEMOWinMenuInfo *menu, u32 item, u32 *result);
147 
148 static void MNU_pick_number(DEMOWinMenuInfo *menu, u32 item, u32 *result);
149 
150 /*---------------------------------------------------------------------------*
151  * Main Control Menu Stuff!
152  *---------------------------------------------------------------------------*/
153 DEMOWinMenuItem control_menu_items[] =
154 {
155     { "ISSUE COMMAND",              DEMOWIN_ITM_SEPARATOR,  NULL,                   NULL },
156     { "  DVDRead",                  DEMOWIN_ITM_NONE,       MNU_read,               NULL },
157     { "  DVDSeek",                  DEMOWIN_ITM_NONE,       MNU_seek,               NULL },
158     { "  DVDCancel",                DEMOWIN_ITM_NONE,       MNU_cancel,             NULL },
159     { "  DVDChangeDisk",            DEMOWIN_ITM_NONE,       MNU_change_disk,        NULL },
160     { "  DVDGetCurrentDiskID",      DEMOWIN_ITM_NONE,       MNU_get_disk_id,        NULL },
161     { "",                           DEMOWIN_ITM_TERMINATOR, NULL,                   NULL }
162 };
163 
164 DEMOWinMenuInfo control_menu =
165 {
166    "DVD Error Handling Demo",     // title
167     NULL,                   // window handle
168     control_menu_items,     // list of menu items
169     50,                     // max num of items to display at a time
170     DEMOWIN_MNU_NONE,       // attribute flags?
171 
172     // user callbacks for misc menu operations
173     NULL, NULL, NULL, NULL,
174     // private menu info members; do not touch
175     0, 0, 0, 0, 0
176 };
177 DEMOWinMenuInfo *control_menu_ptr;
178 
179 DEMOWinMenuItem number_menu_items[] =
180 {
181     { "255",                        DEMOWIN_ITM_EOF,        MNU_pick_number,        NULL },
182     { "0",                          DEMOWIN_ITM_EOF,        MNU_pick_number,        NULL },
183     { "1",                          DEMOWIN_ITM_EOF,        MNU_pick_number,        NULL },
184     { "2",                          DEMOWIN_ITM_EOF,        MNU_pick_number,        NULL },
185     { "3",                          DEMOWIN_ITM_EOF,        MNU_pick_number,        NULL },
186     { "4",                          DEMOWIN_ITM_EOF,        MNU_pick_number,        NULL },
187     { "5",                          DEMOWIN_ITM_EOF,        MNU_pick_number,        NULL },
188     { "6",                          DEMOWIN_ITM_EOF,        MNU_pick_number,        NULL },
189     { "7",                          DEMOWIN_ITM_EOF,        MNU_pick_number,        NULL },
190     { "8",                          DEMOWIN_ITM_EOF,        MNU_pick_number,        NULL },
191     { "",                           DEMOWIN_ITM_TERMINATOR, NULL,                   NULL }
192 };
193 DEMOWinMenuInfo number_menu =
194 {
195    "Pick next disk number", // title
196     NULL,                   // window handle
197     number_menu_items,     // list of menu items
198     10,                     // max num of items to display at a time
199     DEMOWIN_MNU_NONE,       // attribute flags?
200 
201     // user callbacks for misc menu operations
202     NULL, NULL, NULL, NULL,
203     // private menu info members; do not touch
204     0, 0, 0, 0, 0
205 };
206 
207 /*---------------------------------------------------------------------------*
208  * Debug and Status window stuff!
209  *---------------------------------------------------------------------------*/
210 DEMOWinInfo *debug_win;     // debug window
211 DEMOWinInfo *status_win;    // status window
212 DEMOWinInfo *errmsg_win;    // error message window
213 
214  /*---------------------------------------------------------------------------*
215     Name:               InitWindows
216 
217     Description:        Initialize windows
218 
219     Arguments:          none
220 
221     Returns:            none
222  *---------------------------------------------------------------------------*/
InitWindows(void)223 static void InitWindows(void)
224 {
225     DEMOWinInfo *p;
226 
227     control_menu_ptr = DEMOWinCreateMenuWindow(&control_menu, 20, 20);
228     p = control_menu_ptr->handle;
229 
230     // Intialize a window for showing status of DVD commands
231     // By passing "__status_refresh" as the last argument, the window system
232     // calls "__status_refresh" once every frame. We use this function to
233     // handle errors in this demo.
234     status_win = DEMOWinCreateWindow((u16)(p->x2+5), p->y1, 620, (u16)(p->y1+100),
235                                      "Status", 0, __status_refresh);
236 
237     // Initialize a window for debug output
238     debug_win  = DEMOWinCreateWindow((u16)(p->x2+5), (u16)(p->y1+105), 620, 434,
239                                      "Debug", 1024, NULL);
240 
241     // Initialize a window for showing error message
242     errmsg_win = DEMOWinCreateWindow(120, 150, 520, 250,
243                                      "Error message", 0, NULL);
244 
245     // Open status and debug windows. We don't open error message window until
246     // we hit an error.
247     DEMOWinOpenWindow(debug_win);
248     DEMOWinOpenWindow(status_win);
249 
250     // Tell the pointer to the debug window to the "file select" system
251     InitSelectFile(debug_win);
252 }
253 
254  /*---------------------------------------------------------------------------*
255     Name:               __status_refresh
256 
257     Description:        This is the error handling part. This function is called
258                         once every frame.
259 
260     Arguments:          handle              Window handle for the status window
261 
262     Returns:            none
263  *---------------------------------------------------------------------------*/
__status_refresh(DEMOWinInfo * handle)264 static void __status_refresh(DEMOWinInfo *handle)
265 {
266     static u32          counter;
267     s32                 message;
268     u32                 i;
269     CommandBlockData    *data;
270 
271 
272     // Clear status window (we only use the first two rows)
273     DEMOWinClearRow(handle, 0);
274     DEMOWinClearRow(handle, 1);
275 
276     // We use "user data" as the information of the command that was issued
277     // last.
278     data = DVDGetUserData((DVDCommandBlock*)&FileInfo);
279 
280     if (data)
281     {
282         // If it's a read command, show the progress
283         if (data->command == COMMAND_READ)
284         {
285             DEMOWinPrintfXY(handle, 0,  0, "Now loading....%3d%%(%d/%d)",
286                             100*DVDGetTransferredSize(&FileInfo)/data->readLength,
287                             DVDGetTransferredSize(&FileInfo), data->readLength);
288         }
289     }
290 
291     message = -1;
292 
293     // This part is for debugging purpose. Show the drive's status on status
294     // window.
295     switch(DVDGetDriveStatus())
296     {
297       case DVD_STATE_END:
298         FileInfoIsInUse = FALSE;
299         DEMOWinPrintfXY(handle, 0,  1, "Command finished");
300         break;
301       case DVD_STATE_FATAL_ERROR:
302         DEMOWinPrintfXY(handle, 0,  1, "Fatal error occurred");
303         message = MESSAGE_FATAL_ERROR;
304         break;
305       case DVD_STATE_BUSY:
306         break;
307       case DVD_STATE_NO_DISK:
308         DEMOWinPrintfXY(handle, 0,  1, "No disk");
309         message = MESSAGE_NO_DISK;
310         break;
311       case DVD_STATE_WRONG_DISK:
312         DEMOWinPrintfXY(handle, 0,  1, "Wrong disk");
313         message = MESSAGE_WRONG_DISK;
314         break;
315       case DVD_STATE_RETRY:
316         DEMOWinPrintfXY(handle, 0,  1, "Please retry");
317         message = MESSAGE_RETRY_ERROR;
318         break;
319       case DVD_STATE_MOTOR_STOPPED:
320         DEMOWinPrintfXY(handle, 0,  1, "Ready to replace");
321         message = MESSAGE_CHANGE_DISK;
322         break;
323     }
324 
325     // If necessary, launch error message window to show the error message to
326     // the user.
327     if (message >= 0)
328     {
329         DEMOWinOpenWindow(errmsg_win);
330         counter = (counter+1) % 60;
331         for (i = 0; i < 6; i++)
332         {
333             if (counter < 45)
334             {
335                 DEMOWinClearRow(errmsg_win, (u16)i);
336                 DEMOWinPrintfXY(errmsg_win, 0, (u16)i, ErrorMessages[message].line[i]);
337             }
338             else
339             {
340                 DEMOWinClearRow(errmsg_win, (u16)i);
341             }
342         }
343     }
344     else
345     {
346         DEMOWinCloseWindow(errmsg_win);
347     }
348 
349     if (OSGetResetSwitchState())
350     {
351         OSReport("reset is pressed\n");
352 
353         while (OSGetResetSwitchState())
354             ;
355 
356         OSReport("reset is released\n");
357 
358         // Black out screen
359         VISetBlack(TRUE);
360         VIFlush();
361         VIWaitForRetrace();
362 
363         OSRestart(3);
364     }
365 
366 } // end __status_refresh()
367 
368 
369  /*---------------------------------------------------------------------------*
370     Name:               MNU_cancel
371 
372     Description:        Issue DVDCancel. This function is called when DVDCancel
373                         is selected in the control window.
374 
375     Arguments:          menu, item, result      unused
376 
377     Returns:            none
378  *---------------------------------------------------------------------------*/
MNU_cancel(DEMOWinMenuInfo * menu,u32 item,u32 * result)379 static void MNU_cancel(DEMOWinMenuInfo *menu, u32 item, u32 *result)
380 {
381 #pragma unused(menu, item, result)
382     DVDCancelAsync((DVDCommandBlock*)&FileInfo, NULL);
383 }
384 
385 
readCallback(s32 result,DVDFileInfo * fileInfo)386 static void readCallback(s32 result, DVDFileInfo* fileInfo)
387 {
388 #pragma unused(fileInfo)
389 
390     if (result == DVD_RESULT_FATAL_ERROR)
391         return;
392 
393     if (result == DVD_RESULT_CANCELED)
394     {
395         OSReport("read canceled\n");
396         return;
397     }
398 
399     OSReport("read finished\n");
400 }
401 
402  /*---------------------------------------------------------------------------*
403     Name:               MNU_read
404 
405     Description:        Issue DVDRead, after letting the user to select a file
406                         to read.
407 
408     Arguments:          menu                Winmenuinfo for control window
409                         item, result        unused
410 
411     Returns:            none
412  *---------------------------------------------------------------------------*/
MNU_read(DEMOWinMenuInfo * menu,u32 item,u32 * result)413 static void MNU_read(DEMOWinMenuInfo *menu, u32 item, u32 *result)
414 {
415 #pragma unused(item)
416 #pragma unused(result)
417     s32             length;
418     char*           file;
419 
420     // Avoid using the same FileInfo/CommandBlock at the same time.
421     if (FileInfoIsInUse)
422     {
423         return;
424     }
425 
426     DEMOWinLogPrintf(debug_win, "\nIssuing a read...\n");
427     DEMOWinLogPrintf(debug_win, "Press A to choose a file to read or change directory.\nPress B to exit.\n");
428 
429     // Launch a window to let the user to select a file.
430     // The return value is the pointer to the selected file.
431     file = SelectFile(menu->handle);
432 
433     DVDOpen(file, &FileInfo);
434     // If the size of the file is larger than the buffer size, we only read
435     // the first DVD_BUFFER_SIZE bytes.
436     length = (s32)OSRoundUp32B(MIN(DVDGetLength(&FileInfo), DVD_BUFFER_SIZE));
437 
438     // Pass information to __status_refresh()
439     Data.command = COMMAND_READ;
440     Data.readLength = length;
441     DVDSetUserData((DVDCommandBlock*)&FileInfo, (void*)&Data);
442 
443     FileInfoIsInUse = TRUE;
444     DVDReadAsync(&FileInfo, Buffer, length, 0, readCallback);
445 
446 }
447 
448  /*---------------------------------------------------------------------------*
449     Name:               MNU_seek
450 
451     Description:        Issue DVDSeek, after letting the user to select a file
452                         to seek to.
453 
454     Arguments:          menu                Winmenuinfo for control window
455                         item, result        unused
456 
457     Returns:            none
458  *---------------------------------------------------------------------------*/
MNU_seek(DEMOWinMenuInfo * menu,u32 item,u32 * result)459 static void MNU_seek(DEMOWinMenuInfo *menu, u32 item, u32 *result)
460 {
461 #pragma unused(item)
462 #pragma unused(result)
463     char*           file;
464 
465     // Avoid using the same FileInfo/CommandBlock at the same time.
466     if (FileInfoIsInUse)
467     {
468         return;
469     }
470 
471     DEMOWinLogPrintf(debug_win, "\nIssuing a seek...\n");
472     DEMOWinLogPrintf(debug_win, "Press A to choose a file to seek to or change directory.\nPress B to exit.\n");
473 
474     // Launch a window to let the user to select a file.
475     // The return value is the pointer to the selected file.
476     file = SelectFile(menu->handle);
477 
478     DVDOpen(file, &FileInfo);
479 
480     // Pass information to __status_refresh()
481     Data.command = COMMAND_SEEK;
482     DVDSetUserData((DVDCommandBlock*)&FileInfo, (void*)&Data);
483 
484     FileInfoIsInUse = TRUE;
485     DVDSeekAsync(&FileInfo, 0, NULL);
486 
487 }
488 
489 
MNU_pick_number(DEMOWinMenuInfo * menu,u32 item,u32 * result)490 static void MNU_pick_number(DEMOWinMenuInfo *menu, u32 item, u32 *result)
491 {
492 #pragma unused (menu)
493     *result = (item == 0)? 0xff : item - 1;
494 
495 } // end __select_file
496 
497 
PickNumber(DEMOWinInfo * handle)498 static u32 PickNumber(DEMOWinInfo *handle)
499 {
500     u32             val = 0;
501 
502     DEMOWinSetWindowColor(handle, DEMOWIN_COLOR_CAPTION,
503                           50, 50, 50, 255);
504 
505     DEMOWinCreateMenuWindow(&number_menu, (u16)(handle->x2-10), (u16)(handle->y1+24));
506     val = DEMOWinMenu(&number_menu);
507     DEMOWinDestroyMenuWindow(&number_menu);
508 
509     DEMOWinSetWindowColor(handle, DEMOWIN_COLOR_RESET, 0, 0, 0, 0);
510 
511     return val;
512 }
513 
514  /*---------------------------------------------------------------------------*
515     Name:               MNU_change_disk
516 
517     Description:        Issue DVDChangeDisk
518 
519     Arguments:          menu                Winmenuinfo for control window
520                         item, result        unused
521 
522     Returns:            none
523  *---------------------------------------------------------------------------*/
MNU_change_disk(DEMOWinMenuInfo * menu,u32 item,u32 * result)524 static void MNU_change_disk(DEMOWinMenuInfo *menu, u32 item, u32 *result)
525 {
526 #pragma unused(menu, item, result)
527     u32                     n;
528 
529     // Avoid using the same FileInfo/CommandBlock at the same time.
530     if (FileInfoIsInUse)
531     {
532         return;
533     }
534 
535     // Pass information to __status_refresh()
536     Data.command = COMMAND_CHANGE_DISK;
537     DVDSetUserData((DVDCommandBlock*)&FileInfo, (void*)&Data);
538 
539     n = PickNumber(menu->handle);
540 
541     OSReport("number: %d\n", n);
542 
543     memcpy(&DiskID, DVDGetCurrentDiskID(), sizeof(DVDDiskID));
544     DiskID.diskNumber = (u8)n;      // BCD (0x00 ... 1st disk, 0x01 ... 2nd disk)
545 
546     FileInfoIsInUse = TRUE;
547     DVDChangeDiskAsync((DVDCommandBlock*)&FileInfo, &DiskID, NULL);
548 }
549 
changeDiskCallback(s32 result,DVDCommandBlock * commandBlock)550 static void changeDiskCallback(s32 result, DVDCommandBlock* commandBlock)
551 {
552 #pragma unused(result, commandBlock)
553 }
554 
555  /*---------------------------------------------------------------------------*
556     Name:               MNU_get_disk_id
557 
558     Description:        Show disk id
559 
560     Arguments:          menu                Winmenuinfo for control window
561                         item, result        unused
562 
563     Returns:            none
564  *---------------------------------------------------------------------------*/
MNU_get_disk_id(DEMOWinMenuInfo * menu,u32 item,u32 * result)565 static void MNU_get_disk_id(DEMOWinMenuInfo *menu, u32 item, u32 *result)
566 {
567 #pragma unused(menu, item, result)
568     DVDDiskID*              id;
569 
570     id = DVDGetCurrentDiskID();
571 
572     DEMOWinLogPrintf(debug_win, "====Current disk ID====\n");
573     DEMOWinLogPrintf(debug_win, "   Game Name ... %-4.4s\n", id->gameName);
574     DEMOWinLogPrintf(debug_win, "   Company ..... %-2.2s\n", id->company);
575     DEMOWinLogPrintf(debug_win, "   Disk # ...... %x\n",     id->diskNumber);
576     DEMOWinLogPrintf(debug_win, "   Game ver .... %x\n",     id->gameVersion);
577 }
578 
579  /*---------------------------------------------------------------------------*
580     Name:               Run_Demo
581 
582     Description:        Main loop of the demo.
583 
584     Arguments:          none
585 
586     Returns:            none
587  *---------------------------------------------------------------------------*/
Run_Demo(void)588 static void Run_Demo(void)
589 {
590     DEMOWinPadInfo pad;
591 
592     DEMOWinLogPrintf(debug_win, "-------------------------------\n");
593     DEMOWinLogPrintf(debug_win, "DVD error handling sample\n");
594     DEMOWinLogPrintf(debug_win, "-------------------------------\n");
595     DEMOWinLogPrintf(debug_win, "- Stick Up/Down to move cursor\n");
596     DEMOWinLogPrintf(debug_win, "- Button A to select an item\n");
597     DEMOWinLogPrintf(debug_win, "- Button B to exit a menu\n");
598     DEMOWinLogPrintf(debug_win, "While you are executing a command, open cover, make no disk,\n");
599     DEMOWinLogPrintf(debug_win, "put other disks to see how to handle errors\n");
600 
601     while(1)
602     {
603         // Launch control window. This funcion returns when B is pressed.
604         DEMOWinMenu(control_menu_ptr);
605 
606         DEMOWinLogPrintf(debug_win, "-------------------------------------------\n");
607         DEMOWinLogPrintf(debug_win, "\nUse Stick Up/Down to scroll debug buffer.\n");
608         DEMOWinLogPrintf(debug_win, "\nHit Start to resume the demo.\n");
609 
610         DEMOBeforeRender();
611         DEMOWinRefresh();
612         DEMODoneRender();
613         DEMOWinPadRead(&pad);
614 
615         // Let the user to scroll the debug window. Press start button to
616         // go to the top of the outer loop and open the control window again.
617         while(1)
618         {
619 
620             DEMOWinPadRead(&pad);
621 
622             if (pad.pads[0].stickY < -50)
623             {
624                 DEMOWinScrollWindow(debug_win, DEMOWIN_SCROLL_DOWN);
625                 if (pad.pads[0].triggerLeft > 150)
626                 {
627                     DEMOWinScrollWindow(debug_win, DEMOWIN_SCROLL_DOWN);
628                     DEMOWinScrollWindow(debug_win, DEMOWIN_SCROLL_DOWN);
629                 }
630             }
631             else if (pad.pads[0].stickY > 50)
632             {
633                 DEMOWinScrollWindow(debug_win, DEMOWIN_SCROLL_UP);
634                 if (pad.pads[0].triggerLeft > 150)
635                 {
636                     DEMOWinScrollWindow(debug_win, DEMOWIN_SCROLL_UP);
637                     DEMOWinScrollWindow(debug_win, DEMOWIN_SCROLL_UP);
638                 }
639 
640             }
641             else if (pad.changed_button[0] & PAD_BUTTON_START)
642             {
643                 DEMOWinScrollWindow(debug_win, DEMOWIN_SCROLL_HOME);
644                 // get out of the inner loop
645                 break;
646             }
647 
648             DEMOBeforeRender();
649             DEMOWinRefresh();
650             DEMODoneRender();
651 
652         } // debug buffer scroll loop
653 
654     } // forever loop
655 
656 
657 } // end Init_Player_Windows()
658 
659 
main(void)660 void main(void)
661 {
662     void*           arenaLo;
663 
664     arenaLo = OSGetArenaLo();
665     Buffer = arenaLo;
666     OSSetArenaLo((void*)((u32)arenaLo + DVD_BUFFER_SIZE));
667 
668     // disabled the default disc fatal screen
669     DVDSetAutoFatalMessaging(FALSE);
670 
671     // clear user data
672     DVDSetUserData((DVDCommandBlock*)&FileInfo, (void*)NULL);
673 
674     DEMOInit(NULL);
675 
676     OSReport("Disk number is %x\n", DVDGetCurrentDiskID()->diskNumber);
677 
678     AIInit(NULL);
679 
680     OSReport("AIInit done\n");
681 
682     DEMOWinInit();
683 
684     OSReport("DEMOWinInit done\n");
685 
686     InitWindows();
687 
688     OSReport("InitWindows done\n");
689 
690     Run_Demo();
691 
692 } // end main
693