1 /*---------------------------------------------------------------------------*
2 Project: TwlSDK - WM - demos - wep-1
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)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 | PAD_BUTTON_B))
194 {
195 closeWindow(win);
196 }
197 }
198 else
199 {
200 KeyInfo *key;
201 key = getKeyInfo();
202 if (key->trg & PAD_BUTTON_A)
203 {
204 closeWindow(win);
205 }
206 if (key->trg & PAD_BUTTON_B)
207 {
208 win->selected = -1;
209 closeWindow(win);
210 }
211 if (key->trg & PAD_KEY_UP)
212 {
213 --win->selected;
214 if (win->selected < 0)
215 {
216 win->selected += win->itemnum;
217 }
218 }
219 if (key->trg & PAD_KEY_DOWN)
220 {
221 ++win->selected;
222 if (win->selected >= win->itemnum)
223 {
224 win->selected -= win->itemnum;
225 }
226 }
227 }
228 }
229
230 break;
231
232 case WIN_STATE_CLOSING:
233 if (win->count <= 0)
234 {
235 win->state = WIN_STATE_CLOSED;
236 }
237 else
238 {
239 win->count -= 6;
240 }
241 break;
242
243 case WIN_STATE_CLOSED:
244 win->count = 0;
245 break;
246 }
247
248 if (win->count > win->height)
249 {
250 win->count = win->height;
251 }
252 if (win->count < 0)
253 {
254 win->count = 0;
255 }
256
257 return win->state;
258 }
259
drawAllWindow(void)260 void drawAllWindow(void)
261 {
262 Window *w;
263 for (w = sWindowRoot; w != NULL; w = w->next)
264 {
265 drawWindow(w);
266 }
267 }
268
updateAllWindow(void)269 void updateAllWindow(void)
270 {
271 Window *w;
272 for (w = sWindowRoot; w != NULL; w = w->next)
273 {
274 (void)updateWindow(w);
275 }
276 }
277
closeAllWindow(void)278 void closeAllWindow(void)
279 {
280 Window *w;
281 for (w = sWindowRoot; w != NULL; w = w->next)
282 {
283 closeWindow(w);
284 }
285 }
286