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