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