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