1 /*---------------------------------------------------------------------------*
2   Project:  TwlSDK - demos - FS - overlay
3   File:     main.c
4 
5   Copyright 2007-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   $Date:: 2008-09-17#$
14   $Rev: 8556 $
15   $Author: okubata_ryoma $
16  *---------------------------------------------------------------------------*/
17 
18 
19 #include <nitro.h>
20 
21 #include "DEMO.h"
22 #include "func.h"
23 
24 
25 /*---------------------------------------------------------------------------*/
26 /* Functions */
27 
28 /*---------------------------------------------------------------------------*
29   Name:         LoadOverlayHigh
30 
31   Description:  Uses the simplest procedure to load an overlay.
32                 This process is normally sufficient.
33 
34   Arguments:    id: Overlay ID
35 
36   Returns:      Whether the load succeeded or failed.
37  *---------------------------------------------------------------------------*/
LoadOverlayHigh(MIProcessor target,FSOverlayID id)38 static BOOL LoadOverlayHigh(MIProcessor target, FSOverlayID id)
39 {
40     return FS_LoadOverlay(target, id);
41 }
42 
43 /*---------------------------------------------------------------------------*
44   Name:         LoadOverlayMiddle
45 
46   Description:  Uses a somewhat lengthy procedure to load an overlay.
47                 This sequence is used when the process of obtaining overlay information must be separate from the process of loading the actual module.
48 
49 
50   Arguments:    id: Overlay ID
51 
52   Returns:      Whether the load succeeded or failed.
53  *---------------------------------------------------------------------------*/
LoadOverlayMiddle(MIProcessor target,FSOverlayID id)54 static BOOL LoadOverlayMiddle(MIProcessor target, FSOverlayID id)
55 {
56     BOOL            retval = FALSE;
57     FSOverlayInfo   info;
58     if (FS_LoadOverlayInfo(&info, target, id))
59     {
60         if (FS_LoadOverlayImage(&info))
61         {
62             FS_StartOverlay(&info);
63             retval = TRUE;
64         }
65     }
66     return retval;
67 }
68 
69 /*---------------------------------------------------------------------------*
70   Name:         LoadOverlayLow
71 
72   Description:  Uses a combination of only the lowest-level functions to load an overlay.
73                 Refer to this sequence if you want the application to manage overall progress in detail, such as when it uses the WFS library to get an overlay wirelessly.
74 
75 
76 
77   Arguments:    id: Overlay ID
78 
79   Returns:      Whether the load succeeded or failed.
80  *---------------------------------------------------------------------------*/
LoadOverlayLow(MIProcessor target,FSOverlayID id)81 static BOOL LoadOverlayLow(MIProcessor target, FSOverlayID id)
82 {
83     BOOL            retval = FALSE;
84     FSOverlayInfo   info;
85     if (FS_LoadOverlayInfo(&info, target, id))
86     {
87         FSFile  file;
88         FS_InitFile(&file);
89         (void)FS_LoadOverlayImageAsync(&info, &file);
90         (void)FS_WaitAsync(&file);
91         (void)FS_CloseFile(&file);
92         FS_StartOverlay(&info);
93         retval = TRUE;
94     }
95     return retval;
96 }
97 
98 // The High, Middle, and Low load processes are all equivalent.
99 // Choose the appropriate method after considering the scenario in which it will be used.
100 #define	LoadOverlay(id)	LoadOverlayLow(MI_PROCESSOR_ARM9, id)
101 
102 /*---------------------------------------------------------------------------*
103   Name:         NitroMain
104 
105   Description:  Application's main entry.
106 
107   Arguments:    None.
108 
109   Returns:      None.
110  *---------------------------------------------------------------------------*/
NitroMain(void)111 void NitroMain(void)
112 {
113     OS_Init();
114     (void)OS_EnableIrq();
115     (void)OS_EnableInterrupts();
116 
117     DEMOInitCommon();
118     DEMOInitVRAM();
119     DEMOInitDisplayBitmap();
120     DEMOHookConsole();
121 
122     DEMOSetBitmapTextColor(GX_RGBA(31, 31, 0, 1));
123     DEMOSetBitmapGroundColor(DEMO_RGB_CLEAR);
124     DEMOStartDisplay();
125 
126     FS_Init(FS_DMA_NOT_USE);
127 
128     OS_TPrintf("--------------------------------\n"
129                "overlay sample.\n");
130 
131     {
132         // An overlay ID written in the LSF file must be declared explicitly.
133         // (The actual symbol is automatically created by the LCF template file at link time)
134         FS_EXTERN_OVERLAY(main_overlay_1);
135         FS_EXTERN_OVERLAY(main_overlay_2);
136         FS_EXTERN_OVERLAY(main_overlay_3);
137 
138         /* *INDENT-OFF* */
139         static struct
140         {
141             FSOverlayID     id;
142             const char     *name;
143         }
144         list[] =
145         {
146             { FS_OVERLAY_ID(main_overlay_1), "main_overlay_1", },
147             { FS_OVERLAY_ID(main_overlay_2), "main_overlay_2", },
148             { FS_OVERLAY_ID(main_overlay_3), "main_overlay_3", },
149         };
150         static const int    overlay_max = sizeof(list) / sizeof(*list);
151         /* *INDENT-ON* */
152 
153         int     i;
154         int     loaded_overlay = -1;
155         int     current = 0;
156 
157         // Display the address of the function in each overlay.
158         // Note, in particular, that func_1 and func_2 have the same address.
159         OS_TPrintf("func_1() : addr = 0x%08X.\n", func_1);
160         OS_TPrintf("func_2() : addr = 0x%08X.\n", func_2);
161         OS_TPrintf("func_3() : addr = 0x%08X.\n", func_3);
162 
163         // Select and overlay and load it
164         for (;;)
165         {
166             DEMOReadKey();
167             // Load or unload the currently selected overlay with the A Button
168             if (DEMO_IS_TRIG(PAD_BUTTON_A))
169             {
170                 if (loaded_overlay == -1)
171                 {
172                     (void)LoadOverlay(list[current].id);
173                     loaded_overlay = current;
174                 }
175                 else
176                 {
177                     (void)FS_UnloadOverlay(MI_PROCESSOR_ARM9, list[loaded_overlay].id);
178                     loaded_overlay = -1;
179                 }
180             }
181             // Call the function in the current overlay once with the B Button
182             if (DEMO_IS_TRIG(PAD_BUTTON_B))
183             {
184                 // If multiple overlay regions conflict, the FS library guarantees behavior only for the last one to be loaded.
185                 // Take note of this when using a function in an overlay.
186                 //
187                 if (loaded_overlay == 0)
188                 {
189                     func_1();
190                 }
191                 else if (loaded_overlay == 1)
192                 {
193                     func_2();
194                 }
195                 else if (loaded_overlay == 2)
196                 {
197                     func_3();
198                 }
199             }
200             // Move the cursor by pressing Up and Down
201             if (DEMO_IS_TRIG(PAD_KEY_DOWN))
202             {
203                 if (++current >= overlay_max)
204                 {
205                     current -= overlay_max;
206                 }
207             }
208             else if (DEMO_IS_TRIG(PAD_KEY_UP))
209             {
210                 if (--current < 0)
211                 {
212                     current += overlay_max;
213                 }
214             }
215             // Displays screen
216             {
217                 int     ox = 10;
218                 int     oy = 60;
219                 DEMOFillRect(0, 0, GX_LCD_SIZE_X, GX_LCD_SIZE_Y, DEMO_RGB_CLEAR);
220                 DEMOSetBitmapTextColor(GX_RGBA(0, 31, 0, 1));
221                 DEMODrawText(10, 10, "UP&DOWN :select overlay");
222                 DEMODrawText(10, 20, "A button:load/unload overlay");
223                 DEMODrawText(10, 30, "B button:call function");
224                 DEMOSetBitmapTextColor(GX_RGBA(31, 31, 31, 1));
225                 DEMODrawFrame(ox, oy, 240, 10 + overlay_max * 10, GX_RGBA( 0, 31, 0, 1));
226                 for (i = 0; i < overlay_max; ++i)
227                 {
228                     BOOL    focus = (i == current);
229                     BOOL    loaded = (list[i].id == loaded_overlay);
230                     DEMOSetBitmapTextColor((GXRgb)(focus ? GX_RGBA(31, 31, 0, 1) : GX_RGBA(31, 31, 31, 1)));
231                     DEMODrawText(ox + 10, oy + 5 + i * 10, "%s%s %s",
232                                  focus ? ">" : " ", list[i].name, loaded ? "(loaded)" : "");
233                 }
234             }
235             DEMO_DrawFlip();
236             OS_WaitVBlankIntr();
237         }
238     }
239 
240     OS_Terminate();
241 }
242