1 /*---------------------------------------------------------------------------*
2 Project: TwlSDK - WM - demos - dataShare-Model
3 File: menu.c
4
5 Copyright 2006-2009 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:: 2009-06-04#$
14 $Rev: 10698 $
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)
226 {
227 closeWindow(win);
228 }
229 else if (getKeyInfo()->trg & PAD_BUTTON_B)
230 {
231 win->selected = -1;
232 closeWindow(win);
233 }
234 }
235 else
236 {
237 KeyInfo *key;
238 key = getKeyInfo();
239 if (key->trg & PAD_BUTTON_A)
240 {
241 closeWindow(win);
242 }
243 if (key->trg & PAD_BUTTON_B)
244 {
245 win->selected = -1;
246 closeWindow(win);
247 }
248 if (key->trg & PAD_KEY_UP)
249 {
250 --win->selected;
251 if (win->selected < 0)
252 {
253 win->selected += win->itemnum;
254 }
255 }
256 if (key->trg & PAD_KEY_DOWN)
257 {
258 ++win->selected;
259 if (win->selected >= win->itemnum)
260 {
261 win->selected -= win->itemnum;
262 }
263 }
264 }
265 }
266
267 break;
268
269 case WIN_STATE_CLOSING:
270 if (win->count <= 0)
271 {
272 win->state = WIN_STATE_CLOSED;
273 }
274 else
275 {
276 win->count -= 6;
277 }
278 break;
279
280 case WIN_STATE_CLOSED:
281 win->count = 0;
282 break;
283 }
284
285 if (win->count > win->height)
286 {
287 win->count = win->height;
288 }
289 if (win->count < 0)
290 {
291 win->count = 0;
292 }
293
294 return win->state;
295 }
296
drawAllWindow(void)297 void drawAllWindow(void)
298 {
299 Window *w;
300 for (w = sWindowRoot; w != NULL; w = w->next)
301 {
302 drawWindow(w);
303 }
304 }
305
updateAllWindow(void)306 void updateAllWindow(void)
307 {
308 Window *w;
309 for (w = sWindowRoot; w != NULL; w = w->next)
310 {
311 (void)updateWindow(w);
312 }
313 }
314
closeAllWindow(void)315 void closeAllWindow(void)
316 {
317 Window *w;
318 for (w = sWindowRoot; w != NULL; w = w->next)
319 {
320 closeWindow(w);
321 }
322 }
323