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