1 /*---------------------------------------------------------------------------*
2   Project:      Sample demo program for NAND library
3   File:         banner.c
4   Programmer:   HIRATSU Daisuke
5 
6   Copyright (C) 2006 Nintendo.  All rights reserved.
7 
8   These coded instructions, statements, and computer programs contain
9   proprietary information of Nintendo of America Inc. and/or Nintendo
10   Company Ltd., and are protected by Federal copyright law.  They may
11   not be disclosed to third parties or copied or duplicated in any form,
12   in whole or in part, without the prior written consent of Nintendo.
13 
14   $Log: banner.c,v $
15   Revision 1.7  2006/11/22 14:02:53  hiratsu
16   Now banner sample demo creates not only "banner.bin" but also "savefile.dat".
17 
18   Revision 1.6  2006/10/24 09:47:29  hiratsu
19   USE_TPL switch is available.
20   Now messages are displayed to TV screen.
21 
22   Revision 1.5  2006/10/19 04:15:24  hiratsu
23   Banner/icon images are available.
24 
25   Revision 1.4  2006/09/19 12:43:12  hiratsu
26   Banner file size for NANDCheck() was wrong.  Fixed.
27 
28   Revision 1.3  2006/09/18 13:19:50  hiratsu
29   Added NANDCheck() judgement.
30 
31   Revision 1.2  2006/09/18 04:54:33  hiratsu
32   Used NANDMove() API for safe banner creation.
33 
34   Revision 1.1  2006/09/14 13:06:57  hiratsu
35   Initial check-in.
36 
37  *---------------------------------------------------------------------------*/
38 
39 #define USE_TPL
40 
41 #include <string.h>
42 #include <stdlib.h>
43 #include <revolution.h>
44 #include <revolution/nand.h>
45 #include <demo.h>
46 
47 #ifdef USE_TPL
48 #include <revolution/tpl.h>
49 #endif
50 
51 #include "util.h"
52 
53 #define PERM (NAND_PERM_OWNER_READ | NAND_PERM_OWNER_WRITE)    // Owner can read/write
54 #define ATTR 0x00                                              // No attributes.
55 #define ICONS 4
56 
57 #define SAVEFILE_SIZE (20*1024)       // 20KB  (requries 2 FS blocks)
58 
59 #define SCREEN_WIDTH  320
60 #define SCREEN_HEIGHT 240
61 
62 static BOOL verify(const char *name, u32 size);
63 static BOOL createSaveFile(void);
64 static BOOL createBannerFile(void);
65 static BOOL moveToHome(const char *srcPath);
66 static BOOL nandCheck(u32 fsBlocks, u32 inodes);
67 static BOOL getFileSize(const char *path, u32 *length);
68 static void displayMessage(char *msg);
69 
70 #ifdef USE_TPL
71 static TPLPalettePtr  tplIcons;
72 static TPLDescriptorPtr tdpIcons;
73 #else
74 static u8 s_bannerTexture[NAND_BANNER_TEXTURE_SIZE];
75 static u8 s_iconTexture[ICONS][NAND_BANNER_ICON_SIZE];
76 #endif
77 
78 static GXColor Blue  = { 0, 0, 64, 0 };
79 
80 
81 
main(void)82 int main(void)
83 {
84     char message[1024] = "";
85     DEMOInit(0);
86 
87     if(verify("savefile.dat", SAVEFILE_SIZE) && verify("banner.bin", NAND_BANNER_SIZE(ICONS)))  // Both files already exist
88     {
89         displayMessage
90           (
91               "Save file and banner file are ready.\n"
92               "You can delete the Banner file      \n"
93               "on Data Management Screen.            "
94               );
95     }
96     else if(verify("savefile.dat", SAVEFILE_SIZE))                   // Only save file exists
97     {
98         if(nandCheck(3, 1))  // 4-icons banner needs 3 FS blocks.
99         {
100             if(createBannerFile() && moveToHome("/tmp/banner.bin"))
101             {
102                 displayMessage
103                   (
104                       "Success.  Created banner file.      \n"
105                       "Please confirm it on Data Management\n"
106                       "Screen.                               "
107                       );
108             }
109             else
110             {
111                 displayMessage("Failed to create save file.");
112             }
113         }
114         else
115         {
116             displayMessage("NANDCheck() rejected your request.");
117         }
118     }
119     else                          // No files
120     {
121         if(nandCheck(3+2, 1+1))   // Total FS blocks and total i-nodes are required.
122         {
123             if(createSaveFile() && moveToHome("/tmp/savefile.dat") && createBannerFile() && moveToHome("/tmp/banner.bin"))
124             {
125                 displayMessage
126                   (
127                       "Success.                            \n"
128                       "Created save file and banner file.  \n"
129                       "Please confirm it on Data Management\n"
130                       "Screen.                               "
131                       );
132             }
133             else
134             {
135                 displayMessage("Failed to create files.");
136             }
137         }
138         else
139         {
140             displayMessage("NANDCheck() rejected your request.");
141         }
142     }
143 
144     OSShutdownSystem();
145 
146     return EXIT_SUCCESS;   // Never reach here.
147 }
148 
149 
verify(const char * name,u32 size)150 BOOL verify(const char *name, u32 size)
151 {
152     char path[NAND_MAX_PATH]="";
153     s32 ret = NAND_RESULT_FATAL_ERROR;
154     u32 length = 0;
155 
156     ret = NANDGetHomeDir(path);
157     if(ret!=NAND_RESULT_OK)
158     {
159         return FALSE;
160     }
161     strcat(path, "/");
162     strcat(path, name);
163 
164     if(getFileSize(path, &length))
165     {
166         if(length==size)
167         {
168             return TRUE;
169         }
170         else
171         {
172             return FALSE;
173         }
174     }
175     else
176     {
177         return FALSE;
178     }
179 }
180 
181 
nandCheck(const u32 fsBlocks,const u32 inodes)182 BOOL nandCheck(const u32 fsBlocks, const u32 inodes)
183 {
184     u32 answer = 0xffffffff;
185     s32 ret = NANDCheck(fsBlocks, inodes, &answer);
186     if(ret==NAND_RESULT_OK)
187     {
188         if(answer==0)
189         {
190             return TRUE;
191         }
192         else
193         {
194             return FALSE;
195         }
196     }
197     else
198     {
199         OSReport("NANDCheck() failed.  Result code: %d\n", ret);
200         return FALSE;
201     }
202 }
203 
204 
createSaveFile(void)205 BOOL createSaveFile(void)
206 {
207     s32 ret = NAND_RESULT_FATAL_ERROR;
208     NANDFileInfo info;
209     u8 buf[SAVEFILE_SIZE] ATTRIBUTE_ALIGN(32);
210     memset(buf, 0, SAVEFILE_SIZE);
211 
212     ret = NANDCreate("/tmp/savefile.dat", PERM, ATTR);
213     if(ret != NAND_RESULT_OK)
214     {
215         printErrMsg(ret);
216         OSReport("NANDCreate() failed.\n");
217         return FALSE;
218     }
219 
220     ret = NANDOpen("/tmp/savefile.dat", &info, NAND_ACCESS_WRITE);
221     if(ret != NAND_RESULT_OK)
222     {
223         printErrMsg(ret);
224         OSReport("NANDOpen() failed.  Result code: %d\n", ret);
225         return FALSE;
226     }
227 
228     ret = NANDWrite(&info, buf, SAVEFILE_SIZE);
229     if(ret != SAVEFILE_SIZE)
230     {
231         printErrMsg(ret);
232         OSReport("NANDWrite() failed.  Result code: %d\n", ret);
233         NANDClose(&info);
234         return FALSE;
235     }
236 
237     ret = NANDClose(&info);
238     if(ret != NAND_RESULT_OK)
239     {
240         printErrMsg(ret);
241         OSReport("NANDClose() failed.  Result code: %d\n", ret);
242         return FALSE;
243     }
244 
245     return TRUE;
246 }
247 
248 
createBannerFile(void)249 BOOL createBannerFile(void)
250 {
251     s32 ret = NAND_RESULT_FATAL_ERROR;
252     NANDFileInfo info;
253     static NANDBanner s_bnr ATTRIBUTE_ALIGN(32);
254 
255     ret = NANDCreate("/tmp/banner.bin", PERM, ATTR);
256     if(ret != NAND_RESULT_OK)
257     {
258         printErrMsg(ret);
259         OSReport("NANDCreate() failed.\n");
260         return FALSE;
261     }
262 
263     ret = NANDOpen("/tmp/banner.bin", &info, NAND_ACCESS_WRITE);
264     if(ret != NAND_RESULT_OK)
265     {
266         printErrMsg(ret);
267         OSReport("NANDOpen() failed.  Result code: %d\n", ret);
268         return FALSE;
269     }
270 
271     // Prepare banner data
272     {
273         int i = 0;
274         NANDInitBanner( &s_bnr, NAND_BANNER_FLAG_ANIM_BOUNCE, L"banner demo", L"(nanddemo)" );
275 #ifdef USE_TPL
276         // banner
277         TPLGetPalette(&tplIcons, "/nanddemo/wii.tpl");
278         tdpIcons = TPLGet(tplIcons, (u32) 0);
279         memcpy(s_bnr.bannerTexture, tdpIcons->textureHeader->data, NAND_BANNER_TEXTURE_SIZE);
280 
281         // icon
282         TPLReleasePalette(&tplIcons);
283         TPLGetPalette(&tplIcons,   "/nanddemo/yoshi.tpl");
284         for (i=0; i<ICONS; i++)
285         {
286           tdpIcons = TPLGet(tplIcons, (u32)i);
287           memcpy(s_bnr.iconTexture[i], tdpIcons->textureHeader->data, NAND_BANNER_ICON_SIZE);
288           NANDSetIconSpeed(&s_bnr, i, NAND_BANNER_ICON_ANIM_SPEED_SLOW);
289         }
290         NANDSetIconSpeed(&s_bnr, ICONS, NAND_BANNER_ICON_ANIM_SPEED_END);
291         s_bnr.flag |= NAND_BANNER_FLAG_ANIM_BOUNCE;
292 #else
293         // banner
294         memcpy(s_bnr.bannerTexture, s_bannerTexture, NAND_BANNER_TEXTURE_SIZE);
295 
296         // icon
297         for(i=0; i<ICONS; ++i)
298         {
299             memcpy(s_bnr.iconTexture[i], s_iconTexture[i], NAND_BANNER_ICON_SIZE);
300         }
301 #endif
302     }
303 
304     ret = NANDWrite(&info, &s_bnr, NAND_BANNER_SIZE(ICONS));
305     if(ret != NAND_BANNER_SIZE(ICONS))
306     {
307         printErrMsg(ret);
308         OSReport("NANDWrite() failed.  Result code: %d\n", ret);
309         NANDClose(&info);
310         return FALSE;
311     }
312 
313     ret = NANDClose(&info);
314     if(ret != NAND_RESULT_OK)
315     {
316         printErrMsg(ret);
317         OSReport("NANDClose() failed.  Result code: %d\n", ret);
318         return FALSE;
319     }
320 
321     return TRUE;
322 }
323 
324 
moveToHome(const char * srcPath)325 BOOL moveToHome(const char *srcPath)
326 {
327     char homePath[NAND_MAX_PATH]="";
328     NANDGetHomeDir(homePath);
329     if(NAND_RESULT_OK==NANDMove(srcPath, homePath))
330     {
331         return TRUE;
332     }
333     else
334     {
335         return FALSE;
336     }
337 }
338 
339 
getFileSize(const char * path,u32 * length)340 BOOL getFileSize(const char *path, u32 *length)
341 {
342     NANDFileInfo info;
343     s32 ret = NANDOpen(path, &info, NAND_ACCESS_READ);
344     if(ret!=NAND_RESULT_OK)
345     {
346         return FALSE;
347     }
348 
349     ret = NANDGetLength(&info, length);
350     if(ret!=NAND_RESULT_OK)
351     {
352         NANDClose(&info);
353         return FALSE;
354     }
355 
356     ret = NANDClose(&info);
357     if(ret!=NAND_RESULT_OK)
358     {
359         return FALSE;
360     }
361 
362     return TRUE;
363 }
364 
365 
displayMessage(char * msg)366 void displayMessage(char *msg)
367 {
368     DEMOInitCaption( DM_FT_XLU, SCREEN_WIDTH, SCREEN_HEIGHT );
369 
370     // Clear EFB
371     GXSetCopyClear(Blue, 0x00ffffff);
372     GXCopyDisp(DEMOGetCurrentBuffer(), GX_TRUE);
373 
374     while ( ! ( DEMOPadGetButton(0) & PAD_BUTTON_MENU ) )
375     {
376         // get pad status
377         DEMOPadRead( );
378 
379         // Draw scene
380         DEMOBeforeRender( );
381         DEMOPrintf(10, 12, 0, msg);
382         DEMODoneRender( );
383     }
384 }
385