1 /*---------------------------------------------------------------------------*
2 Project: TwlSDK - WM - demos - dataShare-Model
3 File: menu.c
4
5 Copyright 2006-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-18#$
14 $Rev: 8573 $
15 $Author: okubata_ryoma $
16 *---------------------------------------------------------------------------*/
17
18 #ifdef SDK_TWL
19 #include <twl.h>
20 #else
21 #include <nitro.h>
22 #endif
23 #include <string.h>
24 #include "main.h"
25 #include "menu.h"
26 #include "graphics.h"
27 #include "print.h"
28 #include "key.h"
29
30 static Window *sWindowRoot = NULL;
31
initWindow(Window * win)32 void initWindow(Window * win)
33 {
34 Window *w;
35
36 if (sWindowRoot == NULL)
37 {
38 (void)MI_CpuClear8(win, sizeof(Window));
39 sWindowRoot = win;
40 return;
41 }
42
43 w = sWindowRoot;
44
45 for (; (w != NULL) && (w->next != NULL); w = w->next)
46 {
47 if (w == win)
48 {
49 Window *n;
50 n = win->next;
51 (void)MI_CpuClear8(win, sizeof(Window));
52 win->next = n;
53 return;
54 }
55 }
56
57 (void)MI_CpuClear8(win, sizeof(Window));
58 w->next = win;
59 }
60
setupWindow(Window * win,int x,int y,int flag,int lineheight,int leftmargin,int rightmargin)61 void setupWindow(Window * win,
62 int x, int y, int flag, int lineheight, int leftmargin, int rightmargin)
63 {
64 win->x = x;
65 win->y = y;
66 win->lineheight = lineheight;
67 win->leftmargin = leftmargin;
68 win->rightmargin = rightmargin;
69 win->selected = 0;
70 win->count = 0;
71 win->state = WIN_STATE_CLOSED;
72 win->flag = flag;
73 }
74
addItemToWindow(Window * win,const char * item)75 void addItemToWindow(Window * win, const char *item)
76 {
77 // int l, w;
78 SDK_MAX_ASSERT(win->itemnum, ITEM_NUM_MAX - 1);
79 /*
80 l = (int)strlen(item);
81 if (win->flag & WIN_FLAG_SELECTABLE)
82 {
83 ++l;
84 }
85
86 w = l * 8 + win->leftmargin + win->rightmargin;
87 if (win->width < w)
88 {
89 win->width = w;
90 }
91
92 (void)strncpy(win->item[win->itemnum], item, ITEM_LENGTH_MAX);
93 win->item[win->itemnum][ITEM_LENGTH_MAX - 1] = 0;
94 win->height = win->itemnum * win->lineheight + 8;
95 */
96 ++win->itemnum;
97 setItemToWindow(win, item, win->itemnum - 1);
98 win->height = (win->itemnum - 1) * win->lineheight + 8;
99 }
100
setItemToWindow(Window * win,const char * item,int index)101 void setItemToWindow(Window * win, const char *item, int index)
102 {
103 SDK_MINMAX_ASSERT(win->itemnum, 0, ITEM_NUM_MAX - 1);
104 if (index < win->itemnum)
105 {
106 int l, w;
107
108 l = PR_GetStringLengthA(item);
109 if (win->flag & WIN_FLAG_SELECTABLE)
110 {
111 ++l;
112 }
113
114 w = l * 8 + win->leftmargin + win->rightmargin;
115 if (win->width < w)
116 {
117 win->width = w;
118 }
119
120 (void)strncpy(win->item[index], item, ITEM_LENGTH_MAX);
121 win->item[index][ITEM_LENGTH_MAX - 1] = 0;
122 }
123 else
124 {
125 addItemToWindow(win, item);
126 }
127 }
128
openWindow(Window * win)129 void openWindow(Window * win)
130 {
131 if (win->state != WIN_STATE_CLOSED)
132 {
133 return;
134 }
135
136 win->count = 0;
137 win->state = WIN_STATE_OPENING;
138 }
139
closeWindow(Window * win)140 void closeWindow(Window * win)
141 {
142 if (win->state != WIN_STATE_OPENED)
143 {
144 return;
145 }
146
147 win->count = win->height;
148 win->state = WIN_STATE_CLOSING;
149 }
150
drawWindow(Window * win)151 void drawWindow(Window * win)
152 {
153 int y, h;
154 if (win->state == WIN_STATE_CLOSED)
155 {
156 return;
157 }
158
159 if (win->itemnum == 0)
160 {
161 return;
162 }
163
164 y = win->y + (win->height / 2) - (win->count / 2);
165 h = win->count;
166
167 setupPseudo2DCamera();
168
169 G3X_AlphaTest(FALSE, 0);
170 G3_PolygonAttr(GX_LIGHTMASK_NONE,
171 GX_POLYGONMODE_DECAL, GX_CULL_NONE, 0, 31, GX_POLYGON_ATTR_MISC_DISP_1DOT);
172 drawPseudo2DColorQuad(win->x - 7, y - 4, win->width + 4, h + 11, GX_RGB(0, 0, 20));
173 G3X_AlphaTest(TRUE, 0);
174 G3_PolygonAttr(GX_LIGHTMASK_NONE,
175 GX_POLYGONMODE_DECAL, GX_CULL_NONE, 0, 0, GX_POLYGON_ATTR_MISC_DISP_1DOT);
176 G3_TexImageParam(GX_TEXFMT_NONE,
177 GX_TEXGEN_NONE,
178 GX_TEXSIZE_S16,
179 GX_TEXSIZE_T16, GX_TEXREPEAT_NONE, GX_TEXFLIP_NONE, GX_TEXPLTTCOLOR0_USE, 0);
180 drawPseudo2DColorQuad(win->x - 8, y - 5, win->width + 6, h + 13, GX_RGB(20, 20, 31));
181
182 if (win->state == WIN_STATE_OPENED)
183 {
184 int i;
185 for (i = 0; i < win->itemnum; ++i)
186 {
187 PR_Locate(getInfoScreen(),
188 (win->x + win->leftmargin) / 8, (win->y + win->lineheight * i) / 8);
189 if (win->flag & WIN_FLAG_SELECTABLE)
190 {
191 PR_PrintString(getInfoScreen(), "%c", (win->selected == i) ? '>' : ' ');
192 PR_PutString(getInfoScreen(), win->item[i]);
193
194 }
195 else
196 {
197 PR_PutString(getInfoScreen(), win->item[i]);
198 }
199 }
200 }
201 }
202
updateWindow(Window * win)203 int updateWindow(Window * win)
204 {
205 switch (win->state)
206 {
207 case WIN_STATE_OPENING:
208 if (win->count >= win->height)
209 {
210 win->state = WIN_STATE_OPENED;
211 }
212 else
213 {
214 win->count += 6;
215 }
216 break;
217
218 case WIN_STATE_OPENED:
219 win->count = win->height;
220
221 if (!(win->flag & WIN_FLAG_NOCONTROL))
222 {
223 if (!(win->flag & WIN_FLAG_SELECTABLE))
224 {
225 if (getKeyInfo()->trg & (PAD_BUTTON_A | PAD_BUTTON_B))
226 {
227 closeWindow(win);
228 }
229 }
230 else
231 {
232 KeyInfo *key;
233 key = getKeyInfo();
234 if (key->trg & PAD_BUTTON_A)
235 {
236 closeWindow(win);
237 }
238 if (key->trg & PAD_BUTTON_B)
239 {
240 win->selected = -1;
241 closeWindow(win);
242 }
243 if (key->trg & PAD_KEY_UP)
244 {
245 --win->selected;
246 if (win->selected < 0)
247 {
248 win->selected += win->itemnum;
249 }
250 }
251 if (key->trg & PAD_KEY_DOWN)
252 {
253 ++win->selected;
254 if (win->selected >= win->itemnum)
255 {
256 win->selected -= win->itemnum;
257 }
258 }
259 }
260 }
261
262 break;
263
264 case WIN_STATE_CLOSING:
265 if (win->count <= 0)
266 {
267 win->state = WIN_STATE_CLOSED;
268 }
269 else
270 {
271 win->count -= 6;
272 }
273 break;
274
275 case WIN_STATE_CLOSED:
276 win->count = 0;
277 break;
278 }
279
280 if (win->count > win->height)
281 {
282 win->count = win->height;
283 }
284 if (win->count < 0)
285 {
286 win->count = 0;
287 }
288
289 return win->state;
290 }
291
drawAllWindow(void)292 void drawAllWindow(void)
293 {
294 Window *w;
295 for (w = sWindowRoot; w != NULL; w = w->next)
296 {
297 drawWindow(w);
298 }
299 }
300
updateAllWindow(void)301 void updateAllWindow(void)
302 {
303 Window *w;
304 for (w = sWindowRoot; w != NULL; w = w->next)
305 {
306 (void)updateWindow(w);
307 }
308 }
309
closeAllWindow(void)310 void closeAllWindow(void)
311 {
312 Window *w;
313 for (w = sWindowRoot; w != NULL; w = w->next)
314 {
315 closeWindow(w);
316 }
317 }
318