console: Format tabs semi-intelligently
[attac-man.git] / menu.c
blobadf63ab86d8c9f92951cb56960fe2191fe61831b
1 /*
2 Pacman Arena
3 Copyright (C) 2003 Nuno Subtil
5 This program is free software; you can redistribute it and/or
6 modify it under the terms of the GNU General Public License
7 as published by the Free Software Foundation; either version 2
8 of the License, or (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
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, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20 static const char cvsid[] =
21 "$Id: menu.c,v 1.26 2003/11/30 17:43:55 nsubtil Exp $";
23 #ifdef _WIN32
24 #include <windows.h>
25 #endif
27 #include <GL/gl.h>
28 #include <SDL.h>
29 #include <SDL_net.h>
30 #include <stdlib.h>
31 #include <math.h>
33 #include "object.h"
34 #include "game.h"
35 #include "map.h"
36 #include "player.h"
37 #include "screen.h"
38 #include "render.h"
39 #include "gfx.h"
40 #include "audio.h"
41 #include "net.h"
42 #include "input.h"
43 #include "render_map.h"
45 #include "menu.h"
47 #include "level-demo.h"
48 #include "level-classic.h"
49 #include "level-1.h"
51 /* Exported so the console can access it */
52 struct game *current_game = NULL;
54 void menu_setup_map(struct map *map)
56 int x, y;
58 for(y = 0; y < map->height; y++)
59 for(x = 0; x < map->width; x++)
61 if(MAP(map, x, y).content == MAP_CONTENT_FOOD)
63 MAP_FOOD(map, x, y).type = FOOD_TYPE_INTERMITTENT;
64 MAP_FOOD(map, x, y).status = FOOD_STATUS_EATEN;
65 MAP_FOOD(map, x, y).time = sqrt(pow(x, 2) + pow(y, 2)) / 5.0;
66 MAP_FOOD(map, x, y).active_time = 10.0;
67 MAP_FOOD(map, x, y).fade_out = 1.0;
68 MAP_FOOD(map, x, y).inactive_time = 3.0;
69 MAP_FOOD(map, x, y).fade_in = 1.0;
74 void menu_run(void)
76 struct game *game;
77 struct menu_entry main_menu[] =
79 { "gfx/start-game-high.tga", "gfx/start-game-low.tga", NULL, NULL },
80 { "gfx/resolution-high.tga", "gfx/resolution-low.tga", NULL, NULL },
81 { "gfx/high_scores-high.tga", "gfx/high_scores-low.tga", NULL, NULL },
82 { "gfx/exit-high.tga", "gfx/exit-low.tga", NULL, NULL }
84 int main_menu_num = 4;
85 int c, current_selection = 0;
87 for(c = 0; c < main_menu_num; c++)
89 main_menu[c].image_high = gfx_get(main_menu[c].image_name_high);
90 if(main_menu[c].image_high->id == (GLuint)-1)
92 gfx_alpha_from_key(main_menu[c].image_name_high, 0, 0, 0);
93 gfx_upload_texture(main_menu[c].image_name_high);
96 main_menu[c].image_low = gfx_get(main_menu[c].image_name_low);
97 if(main_menu[c].image_low->id == (GLuint)-1)
99 gfx_alpha_from_key(main_menu[c].image_name_low, 0, 0, 0);
100 gfx_upload_texture(main_menu[c].image_name_low);
104 /* preload */
105 game = game_new(GAME_TYPE_DEMO);
106 game->map = map_load_from_ascii((char **)level_demo, NULL,
107 LEVEL_DEMO_WIDTH, LEVEL_DEMO_HEIGHT);
108 menu_setup_map(game->map);
110 game_reset(game);
111 // game_load_level(LEVEL_DEMO);
112 game->demo_camera = (struct camera *)malloc(sizeof(struct camera));
113 game->demo_camera->type = CAMERA_TYPE_DEMO;
114 game_reset_camera(game, -1);
115 game_start(game);
117 audio_play_music("sfx/hummingbird.ogg");
118 screen_set_fadein(0.5);
120 for(;;)
122 struct game *gm;
123 float delta;
124 int last_update, ticks;
126 switch((current_selection = menu(game, main_menu,
127 main_menu_num, current_selection))) {
128 case 0:
130 last_update = SDL_GetTicks();
131 delta = 0.0;
133 audio_fade_music(500);
134 screen_set_fadeout(0.5);
136 for(;;)
138 int diff;
140 ticks = SDL_GetTicks();
141 diff = ticks - last_update;
142 last_update = ticks;
143 delta += (float)diff / 1000;
145 if(delta >= 0.5)
146 break;
148 // screen_update_gamma((float)diff / 1000);
149 render_start_frame();
150 render_setup(game, -1);
151 map_render_opaque_objects(game);
152 game_draw_opaque_objects(game, -1);
153 game_draw_translucent_objects(game, -1);
154 map_render_translucent_objects(game, -1);
157 /* classic single-player */
158 gm = game_new(GAME_TYPE_CLASSIC);
159 /* for scores, etc. */
160 current_game = gm;
161 gm->map = map_load_from_ascii((char **)level_classic,
162 (char **)level_classic_ghost_map,
163 LEVEL_CLASSIC_WIDTH, LEVEL_CLASSIC_HEIGHT);
164 player_add_new(gm);
165 // player_add_new(gm);
166 // screen_set_num_viewports(2);
167 // screen_reset_gamma();
168 game_run(gm);
170 screen_set_num_viewports(1);
171 audio_play_music("sfx/hummingbird.ogg");
172 break;
174 case 1:
175 menu_resolution(game);
176 break;
178 case 2:
179 menu_high_scores();
180 break;
182 case 3:
183 SDL_Quit();
184 exit(0);
185 break;
187 case -1:
188 SDL_Quit();
189 exit(0);
194 void menu_resolution(struct game *game)
196 struct menu_entry menu_resolution[] =
198 { "gfx/640-480-high.tga", "gfx/640-480-low.tga", NULL, NULL },
199 { "gfx/800-600-high.tga", "gfx/800-600-low.tga", NULL, NULL },
200 { "gfx/1024-768-high.tga", "gfx/1024-768-low.tga", NULL, NULL },
201 { "gfx/1400-1050-high.tga", "gfx/1400-1050-low.tga", NULL, NULL }
203 int menu_resolution_num = 4;
204 int ret, c, width, new_w = 0, height, new_h = 0;
205 int current_selection = 0;
207 for(c = 0; c < menu_resolution_num; c++)
209 menu_resolution[c].image_high = gfx_get(menu_resolution[c].image_name_high);
210 if(menu_resolution[c].image_high->id == (GLuint)-1)
212 gfx_alpha_from_key(menu_resolution[c].image_name_high, 0, 0, 0);
213 gfx_upload_texture(menu_resolution[c].image_name_high);
216 menu_resolution[c].image_low = gfx_get(menu_resolution[c].image_name_low);
217 if(menu_resolution[c].image_low->id == (GLuint)-1)
219 gfx_alpha_from_key(menu_resolution[c].image_name_low, 0, 0, 0);
220 gfx_upload_texture(menu_resolution[c].image_name_low);
224 screen_get_resolution(&width, &height);
225 switch (width) {
226 case 640:
227 current_selection = 0;
228 break;
229 case 800:
230 current_selection = 1;
231 break;
232 case 1024:
233 current_selection = 2;
234 break;
235 case 1400:
236 current_selection = 3;
237 break;
238 default:
239 current_selection = 0;
240 break;
243 while ((ret = menu(game, menu_resolution,
244 menu_resolution_num, current_selection)) != -1) {
245 switch(ret) {
246 case 0:
247 new_w = 640;
248 new_h = 480;
249 break;
251 case 1:
252 new_w = 800;
253 new_h = 600;
254 break;
256 case 2:
257 new_w = 1024;
258 new_h = 768;
259 break;
261 case 3:
262 new_w = 1400;
263 new_h = 1050;
264 break;
266 default:
267 return;
270 current_selection = ret;
271 screen_set_resolution(new_w, new_h);
272 screen_switch_resolution();
276 void menu_high_scores(void)
278 return;
281 int menu(struct game *game, struct menu_entry *m, int n, int cur)
283 int last_update, c;
284 int selected = cur;
285 struct image_rgba32 *banner;
286 struct map *map;
287 struct viewport *vp;
289 map = game->map;
291 banner = gfx_get("gfx/pacman-arena-banner.tga");
292 if(banner->id == (GLuint)-1)
294 gfx_alpha_from_key("gfx/pacman-arena-banner.tga", 0, 0, 0);
295 gfx_upload_texture("gfx/pacman-arena-banner.tga");
299 game_reset();
300 game_load_level(LEVEL_DEMO);
301 camera_type = CAMERA_TYPE_DEMO;
302 game_reset_camera();
303 game_start();
306 vp = screen_get_viewport(0);
308 last_update = SDL_GetTicks();
310 for(;;)
312 float v_scale, h_scale;
313 int diff, top, left, menu_width, menu_height, scaled_width, scaled_height, image_width;
315 input_update();
317 if(input_kstate(SDLK_ESCAPE))
319 input_kclear(SDLK_ESCAPE);
320 return -1;
323 if(input_kstate(SDLK_RETURN))
325 input_kclear(SDLK_RETURN);
326 return selected;
330 if(input_kstate(SDLK_DOWN))
332 input_kclear(SDLK_DOWN);
333 selected = (selected + 1) % n;
337 if(input_kstate(SDLK_UP))
339 input_kclear(SDLK_UP);
340 selected = (selected + n - 1) % n;
343 diff = SDL_GetTicks() - last_update;
344 if(server_running)
345 net_server_update();
347 game_update(game, (float)diff / 1000);
348 last_update = SDL_GetTicks();
350 // screen_update_gamma((float)diff / 1000);
351 render_start_frame();
352 render_setup(game, -1);
353 map_render_opaque_objects(game);
354 game_draw_opaque_objects(game, -1);
355 game_draw_translucent_objects(game, -1);
356 map_render_translucent_objects(game, -1);
358 render_setup_2d(vp);
360 top = vp->height / 2 - vp->height / 5;
361 h_scale = (float)vp->width / 800.0;
362 v_scale = (float)vp->height / 600.0;
364 menu_width = 0;
365 menu_height = 0;
367 for(c = 0; c < n; c++)
369 if(c == selected)
371 if(m[c].image_high->width > menu_width)
372 menu_width = m[c].image_high->width;
374 menu_height += m[c].image_high->height + 20;
376 } else {
377 if(m[c].image_low->width > menu_width)
378 menu_width = m[c].image_low->width;
380 menu_height += m[c].image_low->height + 20;
384 menu_width += 40;
386 scaled_width = (int)
387 ((float)menu_width * h_scale);
388 scaled_height = (int)
389 ((float)menu_height * v_scale);
391 left = vp->width / 2 - scaled_width / 2;
393 glDisable(GL_TEXTURE_2D);
394 glEnable(GL_BLEND);
395 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
396 glColor4f(0.0, 0.0, 0.0, 0.5);
398 glBegin(GL_QUADS);
399 glVertex2i(left, top);
400 glVertex2i(left + scaled_width, top);
401 glVertex2i(left + scaled_width, top + scaled_height);
402 glVertex2i(left, top + scaled_height);
403 glEnd();
405 for(c = 0; c < n; c++)
407 if(c == selected)
409 image_width = (int)((float)m[c].image_high->width * h_scale);
410 render_draw_scaled_image(
411 m[c].image_name_high,
412 vp->width / 2 - image_width / 2,
413 top,
414 vp->width / 2 + image_width / 2,
415 top + ((float)m[c].image_low->height * v_scale));
418 top += (int)
419 (((float)(m[c].image_high->height + 20)) * v_scale);
420 } else {
421 image_width = (int)((float)m[c].image_low->width * h_scale);
422 render_draw_scaled_image(
423 m[c].image_name_low,
424 vp->width / 2 - image_width / 2,
425 top,
426 vp->width / 2 + image_width / 2,
427 top + ((float)m[c].image_low->height * v_scale));
429 top += (int)
430 (((float)(m[c].image_high->height + 20)) * v_scale);
435 render_draw_scaled_image("gfx/pacman-arena-banner.tga", 0, 0,
436 vp->width, vp->width * banner->height / banner->width);
438 render_finish_frame();