1 /*---------------------------------------------------------------------------*
2 Project: TwlSDK - WM - demos - wep-1
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)memset(win, 0, 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)memset(win, 0, sizeof(Window));
52 win->next = n;
53 return;
54 }
55 }
56
57 (void)memset(win, 0, 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
79 l = (int)strlen(item);
80 if (win->flag & WIN_FLAG_SELECTABLE)
81 {
82 ++l;
83 }
84
85 w = l * 8 + win->leftmargin + win->rightmargin;
86 if (win->width < w)
87 {
88 win->width = w;
89 }
90
91 (void)strncpy(win->item[win->itemnum], item, ITEM_LENGTH_MAX);
92 win->item[win->itemnum][ITEM_LENGTH_MAX - 1] = 0;
93 win->height = win->itemnum * win->lineheight + 8;
94 ++win->itemnum;
95 }
96
openWindow(Window * win)97 void openWindow(Window * win)
98 {
99 if (win->state != WIN_STATE_CLOSED)
100 {
101 return;
102 }
103
104 win->count = 0;
105 win->state = WIN_STATE_OPENING;
106 }
107
closeWindow(Window * win)108 void closeWindow(Window * win)
109 {
110 if (win->state != WIN_STATE_OPENED)
111 {
112 return;
113 }
114
115 win->count = win->height;
116 win->state = WIN_STATE_CLOSING;
117 }
118
drawWindow(Window * win)119 void drawWindow(Window * win)
120 {
121 int y, h;
122 if (win->state == WIN_STATE_CLOSED)
123 {
124 return;
125 }
126
127 if (win->itemnum == 0)
128 {
129 return;
130 }
131
132 y = win->y + (win->height / 2) - (win->count / 2);
133 h = win->count;
134
135 setupPseudo2DCamera();
136
137 G3X_AlphaTest(FALSE, 0);
138 G3_PolygonAttr(GX_LIGHTMASK_NONE,
139 GX_POLYGONMODE_DECAL, GX_CULL_NONE, 0, 31, GX_POLYGON_ATTR_MISC_DISP_1DOT);
140 drawPseudo2DColorQuad(win->x - 7, y - 4, win->width + 4, h + 11, GX_RGB(0, 0, 20));
141 G3X_AlphaTest(TRUE, 0);
142 G3_PolygonAttr(GX_LIGHTMASK_NONE,
143 GX_POLYGONMODE_DECAL, GX_CULL_NONE, 0, 0, GX_POLYGON_ATTR_MISC_DISP_1DOT);
144 G3_TexImageParam(GX_TEXFMT_NONE,
145 GX_TEXGEN_NONE,
146 GX_TEXSIZE_S16,
147 GX_TEXSIZE_T16, GX_TEXREPEAT_NONE, GX_TEXFLIP_NONE, GX_TEXPLTTCOLOR0_USE, 0);
148 drawPseudo2DColorQuad(win->x - 8, y - 5, win->width + 6, h + 13, GX_RGB(20, 20, 31));
149
150 if (win->state == WIN_STATE_OPENED)
151 {
152 int i;
153 for (i = 0; i < win->itemnum; ++i)
154 {
155 PR_Locate(getInfoScreen(),
156 (win->x + win->leftmargin) / 8, (win->y + win->lineheight * i) / 8);
157 if (win->flag & WIN_FLAG_SELECTABLE)
158 {
159 PR_PrintString(getInfoScreen(), "%c", (win->selected == i) ? '>' : ' ');
160 PR_PutString(getInfoScreen(), win->item[i]);
161
162 }
163 else
164 {
165 PR_PutString(getInfoScreen(), win->item[i]);
166 }
167 }
168 }
169 }
170
updateWindow(Window * win)171 int updateWindow(Window * win)
172 {
173 switch (win->state)
174 {
175 case WIN_STATE_OPENING:
176 if (win->count >= win->height)
177 {
178 win->state = WIN_STATE_OPENED;
179 }
180 else
181 {
182 win->count += 6;
183 }
184 break;
185
186 case WIN_STATE_OPENED:
187 win->count = win->height;
188
189 if (!(win->flag & WIN_FLAG_NOCONTROL))
190 {
191 if (!(win->flag & WIN_FLAG_SELECTABLE))
192 {
193 if (getKeyInfo()->trg & PAD_BUTTON_A)
194 {
195 closeWindow(win);
196 }
197 else if (getKeyInfo()->trg & PAD_BUTTON_B)
198 {
199 win->selected = -1;
200 closeWindow(win);
201 }
202 }
203 else
204 {
205 KeyInfo *key;
206 key = getKeyInfo();
207 if (key->trg & PAD_BUTTON_A)
208 {
209 closeWindow(win);
210 }
211 if (key->trg & PAD_BUTTON_B)
212 {
213 win->selected = -1;
214 closeWindow(win);
215 }
216 if (key->trg & PAD_KEY_UP)
217 {
218 --win->selected;
219 if (win->selected < 0)
220 {
221 win->selected += win->itemnum;
222 }
223 }
224 if (key->trg & PAD_KEY_DOWN)
225 {
226 ++win->selected;
227 if (win->selected >= win->itemnum)
228 {
229 win->selected -= win->itemnum;
230 }
231 }
232 }
233 }
234
235 break;
236
237 case WIN_STATE_CLOSING:
238 if (win->count <= 0)
239 {
240 win->state = WIN_STATE_CLOSED;
241 }
242 else
243 {
244 win->count -= 6;
245 }
246 break;
247
248 case WIN_STATE_CLOSED:
249 win->count = 0;
250 break;
251 }
252
253 if (win->count > win->height)
254 {
255 win->count = win->height;
256 }
257 if (win->count < 0)
258 {
259 win->count = 0;
260 }
261
262 return win->state;
263 }
264
drawAllWindow(void)265 void drawAllWindow(void)
266 {
267 Window *w;
268 for (w = sWindowRoot; w != NULL; w = w->next)
269 {
270 drawWindow(w);
271 }
272 }
273
updateAllWindow(void)274 void updateAllWindow(void)
275 {
276 Window *w;
277 for (w = sWindowRoot; w != NULL; w = w->next)
278 {
279 (void)updateWindow(w);
280 }
281 }
282
closeAllWindow(void)283 void closeAllWindow(void)
284 {
285 Window *w;
286 for (w = sWindowRoot; w != NULL; w = w->next)
287 {
288 closeWindow(w);
289 }
290 }
291