1 /*---------------------------------------------------------------------------*
2   Project:  Revolution Install Demo
3   File:     discnanddemo2.c
4 
5   Copyright (C) 2008 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: discnanddemo2.c,v $
14   Revision 1.2.2.2  2009/10/21 02:36:42  miyamoto_satoshi
15   Modified file name.
16 
17   Revision 1.2.2.1  2009/10/16 02:17:09  iwai_yuma
18   Removed <private/OS*.h> and added <revolution/discnand.h>.
19 
20   Revision 1.2  2009/10/05 05:52:47  iwai_yuma
21   Initial check-in to HEAD.
22 
23   Revision 1.1.2.2  2008/11/18 09:15:50  ooizumi
24   Fixed typo.
25 
26   Revision 1.1.2.1  2008/11/18 09:02:40  ooizumi
27   Initial check-in.
28 
29   $NoKeywords: $
30  *---------------------------------------------------------------------------*/
31 
32 /*---------------------------------------------------------------------------*
33  * This demo illustrates how to handle errors. See __refresh_status() for
34  * the actual error handling code!
35  *---------------------------------------------------------------------------*/
36 
37 #include <revolution/os/OSReset.h>
38 #include <revolution/discnand.h>
39 #include <demo.h>
40 #include <revolution.h>
41 #include <revolution/sc.h>
42 #include <demo/DEMOWin.h>
43 #include <string.h>
44 #include <stdio.h>
45 
46 /*---------------------------------------------------------------------------*
47  * Installer definitions
48  *---------------------------------------------------------------------------*/
49 typedef struct Channel
50 {
51     char*     fileName;  // channel application's file name to install
52     u16*      titleName; // channel application's title name to draw on screen
53     OSTitleId titleId;   // title id of channel application
54     u32       fsBlocks;  // FS block number
55     u32       inodes;    // inode number
56 } Channel;
57 
58 static u16*     TitleName;
59 static Channel* InstallChannelList;
60 
61 
62 static u16*    TitleNameJp = L"�f�B�X�N�h���`�����l���f��2";
63 static Channel InstallChannelListJp[] =
64 {
65     { "discnanddemo1.wad", L"�f�B�X�N�h���`�����l���f��1", 0x0001000452414241, 35, 10 },
66     { NULL,                NULL,                                            0,  0,  0 }
67 };
68 
69 static u16*    TitleNameEn = L"Disc Spinoff Channel Demo 2";
70 static Channel InstallChannelListEn[] =
71 {
72     { "discnanddemo1.wad", L"Disc Spinoff Channel Demo 1", 0x0001000452414241, 35, 10 },
73     { NULL,                NULL,                                            0,  0,  0 }
74 };
75 
76 static OSInstallInfo InstallChannelInfo[16];
77 
78 static u32 InstallChannelNum;
79 static u32 InstallFsBlocks;
80 static u32 InstallInodes;
81 
82 /*---------------------------------------------------------------------------*
83  * Prototypes
84  *---------------------------------------------------------------------------*/
85 static void InitWindows(void);
86 
87 static void __status_refresh(DEMOWinInfo *handle);
88 
89 static void Run_Demo(void);
90 
91 static void MNU_check_install(DEMOWinMenuInfo *menu, u32 item, u32 *result);
92 static void MNU_launch_installer(DEMOWinMenuInfo *menu, u32 item, u32 *result);
93 static void MNU_get_disk_id(DEMOWinMenuInfo *menu, u32 item, u32 *result);
94 
95 /*---------------------------------------------------------------------------*
96  * Main Control Menu Stuff!
97  *---------------------------------------------------------------------------*/
98 DEMOWinMenuItem control_menu_items_dvd[] =
99 {
100     { "ISSUE COMMAND",              DEMOWIN_ITM_SEPARATOR,  NULL,                   NULL },
101     { "  OSCheckInstall",           DEMOWIN_ITM_NONE,       MNU_check_install,      NULL },
102     { "  OSLaunchInstaller",        DEMOWIN_ITM_NONE,       MNU_launch_installer,   NULL },
103     { "  DVDGetCurrentDiskID",      DEMOWIN_ITM_NONE,       MNU_get_disk_id,        NULL },
104     { "",                           DEMOWIN_ITM_TERMINATOR, NULL,                   NULL }
105 };
106 
107 DEMOWinMenuInfo control_menu =
108 {
109    "Channel Install Demo",  // title
110     NULL,                          // window handle
111     control_menu_items_dvd,        // List of menu items
112     50,                            // max num of items to display at a time
113     DEMOWIN_MNU_NONE,              // attribute flags?
114 
115     // user callbacks for misc menu operations
116     NULL, NULL, NULL, NULL,
117     // private menu info members; do not touch
118     0, 0, 0, 0, 0
119 };
120 DEMOWinMenuInfo *control_menu_ptr;
121 
122 /*---------------------------------------------------------------------------*
123  * Debug and Status window stuff!
124  *---------------------------------------------------------------------------*/
125 DEMOWinInfo *debug_win;     // debug window
126 DEMOWinInfo *status_win;    // status window
127 
128  /*---------------------------------------------------------------------------*
129     Name:               InitWindows
130 
131     Description:        Initialize windows
132 
133     Arguments:          None.
134 
135     Returns:            None.
136  *---------------------------------------------------------------------------*/
InitWindows(void)137 static void InitWindows(void)
138 {
139     DEMOWinInfo *p;
140 
141     control_menu_ptr = DEMOWinCreateMenuWindow(&control_menu, 20, 20);
142     p = control_menu_ptr->handle;
143 
144     // Initialize a window for showing status of DVD commands
145     // By passing "__status_refresh" as the last argument, the window system
146     // calls "__status_refresh" once every frame. We use this function to
147     // handle errors in this demo.
148     status_win = DEMOWinCreateWindow((u16)(p->x2+5), p->y1, 620, (u16)(p->y1+100),
149                                      "Status", 0, __status_refresh);
150 
151     // Initialize a window for debug output
152     debug_win  = DEMOWinCreateWindow((u16)(p->x2+5), (u16)(p->y1+105), 620, 434,
153                                      "Debug", 1024, NULL);
154 
155     // Open status and debug windows. We don't open error message window until
156     // we hit an error.
157     DEMOWinOpenWindow(debug_win);
158     DEMOWinOpenWindow(status_win);
159 }
160 
161  /*---------------------------------------------------------------------------*
162     Name:               __status_refresh
163 
164     Description:        This is the error handling part. This function is called
165                         once every frame.
166 
167     Arguments:          handle:              Window handle for the status window
168 
169     Returns:            None.
170  *---------------------------------------------------------------------------*/
__status_refresh(DEMOWinInfo * handle)171 static void __status_refresh(DEMOWinInfo *handle)
172 {
173 #pragma unused(handle)
174     if (OSGetResetSwitchState())
175     {
176         OSReport("reset is pressed\n");
177 
178         while (OSGetResetSwitchState())
179             ;
180 
181         OSReport("reset is released\n");
182 
183         // Black out screen
184         VISetBlack(TRUE);
185         VIFlush();
186         VIWaitForRetrace();
187 
188         OSRestart(3);
189     }
190 
191 } // end __status_refresh()
192 
193 
194  /*---------------------------------------------------------------------------*
195     Name:               MNU_check_install
196 
197     Description:
198 
199     Arguments:          menu, item, result:      unused
200 
201     Returns:            None.
202  *---------------------------------------------------------------------------*/
MNU_check_install(DEMOWinMenuInfo * menu,u32 item,u32 * result)203 static void MNU_check_install(DEMOWinMenuInfo *menu, u32 item, u32 *result)
204 {
205 #pragma unused(menu, item, result)
206     u32 answer;
207 
208     if(!InstallChannelNum)
209     {
210         DEMOWinLogPrintf(debug_win, "Already installed.\n");
211     }
212     else
213     {
214         answer = 0xffffffff;
215         OSCheckInstall(InstallChannelNum, InstallFsBlocks, InstallInodes, &answer);
216 
217         DEMOWinLogPrintf(debug_win, "========Requirements========\n");
218         DEMOWinLogPrintf(debug_win, "   Channel space ... %4d %s\n", InstallChannelNum, (answer & OSINSTALL_CHECK_SYS_INSCHAN)  ? "NG" : "OK");
219         DEMOWinLogPrintf(debug_win, "   FS blocks ....... %4d %s\n", InstallFsBlocks,   (answer & OSINSTALL_CHECK_SYS_INSSPACE) ? "NG" : "OK");
220         DEMOWinLogPrintf(debug_win, "   Inodes .......... %4d %s\n", InstallInodes,     (answer & OSINSTALL_CHECK_SYS_INSINODE) ? "NG" : "OK");
221     }
222 }
223 
224  /*---------------------------------------------------------------------------*
225     Name:               MNU_launch_installer
226 
227     Description:
228 
229     Arguments:          menu, item, result:      unused
230 
231     Returns:            None.
232  *---------------------------------------------------------------------------*/
MNU_launch_installer(DEMOWinMenuInfo * menu,u32 item,u32 * result)233 static void MNU_launch_installer(DEMOWinMenuInfo *menu, u32 item, u32 *result)
234 {
235 #pragma unused(menu, item, result)
236     if(!InstallChannelNum)
237     {
238         DEMOWinLogPrintf(debug_win, "Already installed.\n");
239     }
240     else
241     {
242         // Black out screen
243         VISetBlack(TRUE);
244         VIFlush();
245         VIWaitForRetrace();
246 
247         OSLaunchInstaller(0xdeadbeef, TitleName, InstallChannelInfo);
248     }
249 }
250 
251 
252  /*---------------------------------------------------------------------------*
253     Name:               MNU_get_disk_id
254 
255     Description:        Show disk id
256 
257     Arguments:          menu:                Winmenuinfo for control window
258                         item, result:        unused
259 
260     Returns:            None.
261  *---------------------------------------------------------------------------*/
MNU_get_disk_id(DEMOWinMenuInfo * menu,u32 item,u32 * result)262 static void MNU_get_disk_id(DEMOWinMenuInfo *menu, u32 item, u32 *result)
263 {
264 #pragma unused(menu, item, result)
265     DVDDiskID*              id;
266 
267     id = DVDGetCurrentDiskID();
268 
269     DEMOWinLogPrintf(debug_win, "====Current disk ID====\n");
270     DEMOWinLogPrintf(debug_win, "   Game Name ... %-4.4s\n", id->gameName);
271     DEMOWinLogPrintf(debug_win, "   Company ..... %-2.2s\n", id->company);
272     DEMOWinLogPrintf(debug_win, "   Disk # ...... %x\n",     id->diskNumber);
273     DEMOWinLogPrintf(debug_win, "   Game ver .... %x\n",     id->gameVersion);
274 }
275 
276  /*---------------------------------------------------------------------------*
277     Name:               Run_Demo
278 
279     Description:        Main loop of the demo.
280 
281     Arguments:          None.
282 
283     Returns:            None.
284  *---------------------------------------------------------------------------*/
Run_Demo(void)285 static void Run_Demo(void)
286 {
287     DEMOWinPadInfo pad;
288 
289     DEMOWinLogPrintf(debug_win, "-------------------------------\n");
290     DEMOWinLogPrintf(debug_win, "DVD error handling sample\n");
291     DEMOWinLogPrintf(debug_win, "-------------------------------\n");
292     DEMOWinLogPrintf(debug_win, "- Stick Up/Down to move cursor\n");
293     DEMOWinLogPrintf(debug_win, "- Button A to select an item\n");
294     DEMOWinLogPrintf(debug_win, "- Button B to exit a menu\n");
295     DEMOWinLogPrintf(debug_win, "While you are executing a command, open cover, make no disk,\n");
296     DEMOWinLogPrintf(debug_win, "put other disks to see how to handle errors\n");
297 
298     while(1)
299     {
300         // Launch control window. This function returns when B is pressed.
301         DEMOWinMenu(control_menu_ptr);
302 
303         DEMOWinLogPrintf(debug_win, "-------------------------------------------\n");
304         DEMOWinLogPrintf(debug_win, "\nUse Stick Up/Down to scroll debug buffer.\n");
305         DEMOWinLogPrintf(debug_win, "\nHit Start to resume the demo.\n");
306 
307         DEMOBeforeRender();
308         DEMOWinRefresh();
309         DEMODoneRender();
310         DEMOWinPadRead(&pad);
311 
312         // Let the user scroll the debug window. Press start button to
313         // go to the top of the outer loop and open the control window again.
314         while(1)
315         {
316 
317             DEMOWinPadRead(&pad);
318 
319             if (pad.pads[0].stickY < -50)
320             {
321                 DEMOWinScrollWindow(debug_win, DEMOWIN_SCROLL_DOWN);
322                 if (pad.pads[0].triggerLeft > 150)
323                 {
324                     DEMOWinScrollWindow(debug_win, DEMOWIN_SCROLL_DOWN);
325                     DEMOWinScrollWindow(debug_win, DEMOWIN_SCROLL_DOWN);
326                 }
327             }
328             else if (pad.pads[0].stickY > 50)
329             {
330                 DEMOWinScrollWindow(debug_win, DEMOWIN_SCROLL_UP);
331                 if (pad.pads[0].triggerLeft > 150)
332                 {
333                     DEMOWinScrollWindow(debug_win, DEMOWIN_SCROLL_UP);
334                     DEMOWinScrollWindow(debug_win, DEMOWIN_SCROLL_UP);
335                 }
336 
337             }
338             else if (pad.changed_button[0] & PAD_BUTTON_START)
339             {
340                 DEMOWinScrollWindow(debug_win, DEMOWIN_SCROLL_HOME);
341                 // get out of the inner loop
342                 break;
343             }
344 
345             DEMOBeforeRender();
346             DEMOWinRefresh();
347             DEMODoneRender();
348 
349         } // debug buffer scroll loop
350 
351     } // forever loop
352 
353 
354 } // end Init_Player_Windows()
355 
main(s32 argc,char ** argv)356 void main (s32 argc, char** argv)
357 {
358     Channel*       channelPtr;
359     OSInstallInfo* channelInfoPtr;
360 
361     OSReport("to check installed titles:\n");
362     // select language
363     if(SCGetLanguage() == SC_LANG_JAPANESE)
364     {
365         TitleName          = TitleNameJp;
366         InstallChannelList = InstallChannelListJp;
367     }
368     else
369     {
370         TitleName          = TitleNameEn;
371         InstallChannelList = InstallChannelListEn;
372     }
373     channelPtr        = InstallChannelList;
374     channelInfoPtr    = InstallChannelInfo;
375     InstallChannelNum = 0;
376     InstallFsBlocks   = 0;
377     InstallInodes     = 0;
378     while(channelPtr->fileName)
379     {
380         if(OSIsTitleInstalled(channelPtr->titleId))
381         {
382             OSReport(" title %016llx is already installed.\n", channelPtr->titleId);
383         }
384         else
385         {
386             channelInfoPtr->fileName  = channelPtr->fileName;
387             channelInfoPtr->titleName = channelPtr->titleName;
388             InstallChannelNum++;
389             InstallFsBlocks += channelPtr->fsBlocks;
390             InstallInodes   += channelPtr->inodes;
391             OSReport(" added %016llx to install.\n", channelPtr->titleId);
392 
393             channelInfoPtr++;
394         }
395         channelPtr++;
396     }
397     channelInfoPtr->fileName = NULL; // set NULL to terminate
398 
399     // disabled the default disc fatal screen
400     DVDSetAutoFatalMessaging(FALSE);
401 
402     DEMOInit(NULL);
403 
404     OSReport("Disk number is %x\n", DVDGetCurrentDiskID()->diskNumber);
405 
406     AIInit(NULL);
407 
408     OSReport("AIInit done\n");
409 
410     DEMOWinInit();
411 
412     OSReport("DEMOWinInit done\n");
413 
414     InitWindows();
415 
416     OSReport("InitWindows done\n");
417 
418     OSReport("OSGetResetCode = %08X\n", OSGetResetCode());
419     // check reset code
420     switch(OSGetResetCode())
421     {
422         case 0: // boot from system menu
423         {
424             OSReport("boot from system menu\n");
425             break;
426         }
427 
428         case OS_RESETCODE_RESTART|3: // restart
429         {
430             OSReport("restart\n");
431             break;
432         }
433 
434         // boot from installer
435         case OS_RESETCODE_INSTALLER:
436         {
437             OSReport("return from installer.\n");
438 
439             OSReport("OSGetReturnCode = %08X %s\n",
440                      OSGetReturnCode(),
441                      OSGetReturnCode() ? "NG" : "OK");
442             OSReport("OSGetLaunchCode = %08X %s\n",
443                      OSGetLaunchCode(),
444                      (OSGetLaunchCode() == 0xdeadbeef) ? "OK" : "NG");
445             break;
446         }
447 
448         case OS_RESETCODE_LAUNCH: // launch
449         {
450             OSReport("launch from nand app\n");
451             break;
452         }
453 
454         default:
455         {
456             OSHalt("invalid state");
457             break;
458         }
459     }
460 
461     while(argc)
462     {
463         argc--;
464         OSReport("argv[%d] = %s\n", argc, argv[argc]);
465     }
466 
467     Run_Demo();
468 
469 } // end main
470