1 /*
2 Copyright (C) 2009-2021 Parallel Realities
3
4 This program is free software; you can redistribute it and/or
5 modify it under the terms of the GNU General Public License
6 as published by the Free Software Foundation; either version 2
7 of the License, or (at your option) any later version.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12
13 See the GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA.
18 */
19
20 #include "../headers.h"
21
22 #include "../audio/audio.h"
23 #include "../game.h"
24 #include "../graphics/graphics.h"
25 #include "../hud.h"
26 #include "../init.h"
27 #include "../system/error.h"
28 #include "../system/load_save.h"
29 #include "io_menu.h"
30 #include "main_menu.h"
31 #include "ok_menu.h"
32 #include "widget.h"
33
34 extern Input input, menuInput;
35 extern Game game;
36 extern Entity *self;
37
38 static Menu menu;
39
40 static void loadMenuLayout(int);
41 static void showMainMenu(void);
42 static void doMenu(void);
43 static void saveGameInSlot(void);
44 static void loadGameInSlot(void);
45 static void showIOMenu(void);
46
drawIOMenu()47 void drawIOMenu()
48 {
49 int i;
50
51 drawImage(menu.background, menu.x, menu.y, FALSE, 196);
52
53 for (i=0;i<menu.widgetCount;i++)
54 {
55 drawWidget(menu.widgets[i], &menu, menu.index == i);
56 }
57 }
58
doMenu()59 static void doMenu()
60 {
61 Widget *w;
62 int up, down, attack, xAxisMoved, yAxisMoved;
63
64 up = FALSE;
65 down = FALSE;
66 attack = FALSE;
67
68 if (menuInput.up == TRUE)
69 {
70 up = TRUE;
71 }
72
73 else if (menuInput.down == TRUE)
74 {
75 down = TRUE;
76 }
77
78 else if (menuInput.attack == TRUE)
79 {
80 attack = TRUE;
81 }
82
83 else if (input.up == TRUE)
84 {
85 up = TRUE;
86 }
87
88 else if (input.down == TRUE)
89 {
90 down = TRUE;
91 }
92
93 else if (input.attack == TRUE)
94 {
95 attack = TRUE;
96 }
97
98 if (down == TRUE)
99 {
100 menu.index++;
101
102 if (menu.index == menu.widgetCount)
103 {
104 menu.index = 1;
105 }
106
107 playSound("sound/common/click");
108 }
109
110 else if (up == TRUE)
111 {
112 menu.index--;
113
114 if (menu.index < 1)
115 {
116 menu.index = menu.widgetCount - 1;
117 }
118
119 playSound("sound/common/click");
120 }
121
122 else if (attack == TRUE)
123 {
124 w = menu.widgets[menu.index];
125
126 if (w->clickAction != NULL)
127 {
128 playSound("sound/common/click");
129
130 w->clickAction();
131 }
132 }
133
134 xAxisMoved = input.xAxisMoved;
135 yAxisMoved = input.yAxisMoved;
136
137 memset(&menuInput, 0, sizeof(Input));
138 memset(&input, 0, sizeof(Input));
139
140 input.xAxisMoved = xAxisMoved;
141 input.yAxisMoved = yAxisMoved;
142 }
143
loadMenuLayout(int saving)144 static void loadMenuLayout(int saving)
145 {
146 char **saveFile;
147 int y, i, j, width , maxWidth, w;
148
149 w = i = 0;
150
151 y = BUTTON_PADDING / 2 + BORDER_PADDING;
152
153 menu.widgetCount = MAX_SAVE_SLOTS + 2;
154
155 menu.widgets = malloc(sizeof(Widget *) * menu.widgetCount);
156
157 if (menu.widgets == NULL)
158 {
159 showErrorAndExit("Ran out of memory when creating IO Menu");
160 }
161
162 saveFile = getSaveFileIndex();
163
164 if (saving == TRUE)
165 {
166 menu.widgets[0] = createWidget(_("Choose slot to save to"), NULL, NULL, NULL, NULL, -1, y, FALSE, 255, 255, 255);
167 }
168
169 else
170 {
171 menu.widgets[0] = createWidget(_("Choose slot to load from"), NULL, NULL, NULL, NULL, -1, y, FALSE, 255, 255, 255);
172 }
173
174 maxWidth = 0;
175
176 i = 1;
177
178 for (j=0;j<MAX_SAVE_SLOTS;j++)
179 {
180 if (saveFile == NULL || strlen(saveFile[j]) == 0)
181 {
182 menu.widgets[i] = createWidget(_("<Empty>"), NULL, NULL, NULL, saving == TRUE ? &saveGameInSlot : NULL, -1, y, FALSE, 255, 255, 255);
183 }
184
185 else
186 {
187 menu.widgets[i] = createWidget(saveFile[j], NULL, NULL, NULL, saving == TRUE ? &saveGameInSlot : &loadGameInSlot, -1, y, FALSE, 255, 255, 255);
188 }
189
190 if (saveFile[j] != NULL)
191 {
192 free(saveFile[j]);
193 }
194
195 if (menu.widgets[i]->selectedState->w > width)
196 {
197 width = menu.widgets[i]->selectedState->w;
198 }
199
200 i++;
201 }
202
203 menu.widgets[i] = createWidget(_("Back"), NULL, 0, 0, &showMainMenu, -1, y, TRUE, 255, 255, 255);
204
205 for (i=0;i<menu.widgetCount;i++)
206 {
207 menu.widgets[i]->y = y;
208
209 if (menu.widgets[i]->x != -1)
210 {
211 menu.widgets[i]->x = BUTTON_PADDING + BORDER_PADDING;
212 }
213
214 if (menu.widgets[i]->label != NULL)
215 {
216 menu.widgets[i]->label->y = y;
217
218 menu.widgets[i]->label->x = menu.widgets[i]->x + maxWidth + 10;
219
220 if (menu.widgets[i]->label->x + menu.widgets[i]->label->text->w > w)
221 {
222 w = menu.widgets[i]->label->x + menu.widgets[i]->label->text->w;
223 }
224 }
225
226 else
227 {
228 if (menu.widgets[i]->x + menu.widgets[i]->selectedState->w > w)
229 {
230 w = menu.widgets[i]->x + menu.widgets[i]->selectedState->w;
231 }
232 }
233
234 y += menu.widgets[i]->selectedState->h + BUTTON_PADDING / 2;
235 }
236
237 menu.w = w + BUTTON_PADDING;
238 menu.h = y - BORDER_PADDING;
239
240 menu.background = addBorder(createSurface(menu.w, menu.h, FALSE), 255, 255, 255, 0, 0, 0);
241
242 menu.x = (SCREEN_WIDTH - menu.background->w) / 2;
243 menu.y = (SCREEN_HEIGHT - menu.background->h) / 2;
244 }
245
initIOMenu(int saving)246 Menu *initIOMenu(int saving)
247 {
248 menu.action = &doMenu;
249
250 freeIOMenu();
251
252 loadMenuLayout(saving);
253
254 menu.returnAction = saving == TRUE ? NULL : &showMainMenu;
255
256 if (menu.index == 0)
257 {
258 menu.index = 1;
259 }
260
261 return &menu;
262 }
263
freeIOMenu()264 void freeIOMenu()
265 {
266 int i;
267
268 if (menu.widgets != NULL)
269 {
270 for (i=0;i<menu.widgetCount;i++)
271 {
272 freeWidget(menu.widgets[i]);
273 }
274
275 free(menu.widgets);
276
277 menu.widgets = NULL;
278 }
279
280 if (menu.background != NULL)
281 {
282 destroyTexture(menu.background);
283
284 menu.background = NULL;
285 }
286 }
287
showMainMenu()288 static void showMainMenu()
289 {
290 game.menu = initMainMenu();
291
292 game.drawMenu = &drawMainMenu;
293 }
294
loadGameInSlot()295 static void loadGameInSlot()
296 {
297 if (loadGame(menu.index - 1) == TRUE)
298 {
299 menu.returnAction = NULL;
300
301 freeMessageQueue();
302
303 setInfoBoxMessage(60, 255, 255, 255, _("Game Loaded"));
304
305 game.paused = FALSE;
306 }
307
308 else
309 {
310 game.menu = initOKMenu(_("Failed to load game"), &showIOMenu);
311
312 game.drawMenu = &drawOKMenu;
313 }
314 }
315
saveGameInSlot()316 static void saveGameInSlot()
317 {
318 saveGame(menu.index - 1);
319
320 freeMessageQueue();
321
322 setInfoBoxMessage(60, 255, 255, 255, _("Game Saved"));
323
324 pauseGame();
325 }
326
showIOMenu()327 static void showIOMenu()
328 {
329 game.menu = initIOMenu(FALSE);
330
331 game.drawMenu = &drawIOMenu;
332 }
333