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