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