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