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