font.c was created, and the Makefiles updated to reflect this. It contains reload_fon...
[xuni.git] / menu.c
blobaf93ddb8da445d9a202373b3156c09766c8d1d12
1 /*! \file menu.c
3 */
5 #include "SDL_image.h"
6 #include "SDL_rotozoom.h"
7 #include "font.h"
8 #include "graphics.h"
9 #include "gui.h"
10 #include "loop.h"
11 #include "menu.h"
12 #include "xuni.h"
14 static void resize_menu_images(struct menu_data_t *data,
15 struct smode_t *smode, struct font_t *font, struct gui_t *gui);
16 static int set_menu_widget_sel(int xp, int yp, int click,
17 struct menu_data_t *data, struct smode_t *smode, struct theme_t *theme,
18 struct gui_t *gui);
19 static void menu_perform_click(int id, enum loop_mode_t *mode);
20 static void free_resize_menu(struct menu_data_t *data, struct gui_t *gui);
22 void init_menu(struct menu_data_t *data, struct smode_t *smode,
23 struct font_t *font, struct gui_t *gui) {
25 size_t x;
26 /* gui/default/menuhover/X.png\0 */
27 char fn[GUI_PATH_LEN + /*7 + 1*/ + 9 + 1 + 1+1+3 + 1]
28 = GUI_PATH /*"default/"*/"menuhover/";
30 /*data->text.title = TTF_RenderText_Blended(font->sans, VERSION, white);*/
31 load_resize_image(&data->title, GUI_PATH "title.png");
33 data->frame_based = smode->main_menu_quality;
35 for(x = 0; x < sizeof(data->gui.hover)/sizeof(*data->gui.hover); x ++) {
36 sprintf(fn + GUI_PATH_LEN + /*7 + 1*/ + 9 + 1, "%i.png", (int)x);
37 load_resize_image(&data->gui.hover[x], fn);
40 load_resize_image(&data->gui.hoverback, GUI_PATH /*"default/"*/"menuhover/back.png");
42 data->back0.image = load_image(GUI_PATH "back0.png");
43 data->back1.image = load_image(GUI_PATH "back1.png");
45 data->quality.x0 = 300.0;
46 data->quality.y0 = 500.0;
47 data->quality.x1 = 600.0;
48 data->quality.y1 = 200.0;
50 data->loaded = 0;
51 resize_menu_images(data, smode, font, gui);
52 data->loaded = 1;
55 static void resize_menu_images(struct menu_data_t *data,
56 struct smode_t *smode, struct font_t *font, struct gui_t *gui) {
58 size_t x;
60 if(data->loaded) free_resize_menu(data, gui);
62 /*data->text.loadgame.text = TTF_RenderText_Blended(font->sans,
63 "Load existing game", white);*/
65 /*data->gui.lastid = (size_t)-1;*/
67 add_widget(gui->panel[PANEL_MAIN_MENU],
68 allocate_button(0, font->sans, "Create new game",
69 smode->width / 16, smode->height * .7,
70 smode->width / 3, smode->height / 15));
71 add_widget(gui->panel[PANEL_MAIN_MENU],
72 allocate_button(1, font->sans, "Join multi-player game",
73 smode->width / 16, smode->height * .7 + smode->height / 12,
74 smode->width / 3, smode->height / 15));
75 add_widget(gui->panel[PANEL_MAIN_MENU],
76 allocate_button(2, font->sans, "Load saved game",
77 smode->width / 16, smode->height * .7 + smode->height / 12 * 2,
78 smode->width / 3, smode->height / 15));
80 /*data->gui.widget[1].enabled = 0; !!! disable multiplayer button */
82 add_widget(gui->panel[PANEL_MAIN_MENU],
83 allocate_button(3, font->sans, "Options and preferences",
84 smode->width - smode->width / 3 - smode->width / 16,
85 smode->height * .7, smode->width / 3, smode->height / 15));
86 add_widget(gui->panel[PANEL_MAIN_MENU],
87 allocate_button(4, font->sans, "Help and information",
88 smode->width - smode->width / 3 - smode->width / 16,
89 smode->height * .7 + smode->height / 12, smode->width / 3,
90 smode->height / 15));
91 add_widget(gui->panel[PANEL_MAIN_MENU],
92 allocate_button(5, font->sans, "Quit",
93 smode->width - smode->width / 3 - smode->width / 16,
94 smode->height * .7 + smode->height / 12 * 2, smode->width / 3,
95 smode->height / 15));
97 if(data->title.original) {
98 data->title.image = zoomSurface(data->title.original,
99 smode->width / 1.5 / data->title.original->w,
100 smode->height / 1.5 / data->title.original->h, SMOOTHING_ON);
103 for(x = 0; x < sizeof(data->gui.hover)/sizeof(*data->gui.hover); x ++) {
104 if(data->gui.hover[x].original) {
105 data->gui.hover[x].image
106 = zoomSurface(data->gui.hover[x].original,
107 smode->width / 5.0 / data->gui.hover[x].original->w,
108 smode->height / 3.75 / data->gui.hover[x].original->h,
109 SMOOTHING_ON);
113 if(data->gui.hoverback.original) {
114 data->gui.hoverback.image
115 = zoomSurface(data->gui.hoverback.original,
116 smode->width / 5.0 / data->gui.hoverback.original->w,
117 smode->height / 3.75 / data->gui.hoverback.original->h,
118 SMOOTHING_ON);
122 void start_menu(struct menu_data_t *data) {
123 set_caption("Main menu");
126 int menu_event(enum loop_mode_t *mode, SDL_Event *event,
127 struct menu_data_t *data, struct smode_t *smode, struct font_t *font,
128 struct theme_t *theme, struct gui_t *gui) {
130 int repaint = 0;
131 /*struct widget_sel_t sel;*/
133 switch(event->type) {
134 case SDL_KEYDOWN:
135 break;
136 case SDL_KEYUP:
137 switch(event->key.keysym.sym) {
138 case SDLK_ESCAPE:
139 case SDLK_q:
140 *mode = MODE_QUIT;
141 break;
142 case SDLK_n:
143 *mode = MODE_GAME;
144 break;
145 case SDLK_o:
146 *mode = MODE_OPTIONS;
147 break;
148 case SDLK_F4:
149 if(event->key.keysym.mod & KMOD_ALT) *mode = MODE_QUIT;
150 break;
151 default: break;
153 break;
154 case SDL_MOUSEBUTTONDOWN:
155 if(event->button.button != 1) break;
157 repaint = set_menu_widget_sel(event->button.x, event->button.y, 1,
158 data, smode, theme, gui);
159 break;
160 case SDL_MOUSEBUTTONUP:
161 if(event->button.button != 1) break;
163 if(gui->sel.p.widget
164 && in_sdl_rect(event->button.x, event->button.y,
165 &gui->sel.p.widget->pos)) {
167 if(gui->sel.clickin) {
168 menu_perform_click(gui->sel.p.widget->id, mode);
169 gui->sel.clickin = 0;
172 gui->sel.wasin = 1;
173 repaint = 1;
175 else {
176 repaint = set_menu_widget_sel(event->button.x, event->button.y, 0,
177 data, smode, theme, gui);
180 break;
181 case SDL_MOUSEMOTION:
182 repaint = set_menu_widget_sel(event->button.x, event->button.y,
183 gui->sel.clickin, data, smode, theme, gui);
184 break;
185 case SDL_QUIT:
186 *mode = MODE_QUIT;
187 break;
188 case SDL_VIDEORESIZE:
189 resize_menu_images(data, smode, font, gui);
190 repaint = 1;
191 break;
192 default:
193 repaint = 1;
194 break;
197 return repaint;
200 static int set_menu_widget_sel(int xp, int yp, int click,
201 struct menu_data_t *data, struct smode_t *smode, struct theme_t *theme,
202 struct gui_t *gui) {
204 if(set_widget_sel_repaint(&gui->sel, xp, yp, click,
205 gui->panel[PANEL_MAIN_MENU]->widget,
206 gui->panel[PANEL_MAIN_MENU]->widgets)) {
208 return 1;
211 return 0;
214 static void menu_perform_click(int id, enum loop_mode_t *mode) {
215 switch(id) {
216 case 0:
217 *mode = MODE_GAME;
218 break;
219 case 3:
220 *mode = MODE_OPTIONS;
221 break;
222 case 5:
223 *mode = MODE_QUIT;
224 break;
225 default:
226 break;
230 void paint_menu(struct menu_data_t *data, struct smode_t *smode,
231 struct font_t *font, struct theme_t *theme, struct gui_t *gui) {
233 size_t x;
235 lock_screen(smode->screen);
236 SDL_FillRect(smode->screen, NULL,
237 SDL_MapRGB(smode->screen->format, 0, 0, 0));
238 unlock_screen(smode->screen);
240 if(data->back0.image) {
241 if(data->frame_based) {
242 blit_surface_fill_from(smode->screen, data->back0.image, 0, 0,
243 smode->width, smode->height, data->back0.x, data->back0.y);
245 data->back0.x += smode->width / data->quality.x0;
246 data->back0.y += smode->height / data->quality.y0;
248 if(data->back0.x >= data->back0.image->w) {
249 data->back0.x = 0;
251 if(data->back0.y >= data->back0.image->h) {
252 data->back0.y = 0;
255 else {
256 blit_surface_repeat(smode->screen, data->back0.image,
257 0, 0, smode->width, smode->height);
261 if(data->frame_based >= 2 && data->back1.image) {
262 blit_surface_fill_from(smode->screen, data->back1.image,
263 0, 0, smode->width, smode->height, data->back1.x, data->back1.y);
265 data->back1.x += smode->width / data->quality.x1;
266 data->back1.y += smode->height / data->quality.y1;
268 if(data->back1.x >= data->back1.image->w) {
269 data->back1.x = 0;
271 if(data->back1.y >= data->back1.image->h) {
272 data->back1.y = 0;
276 if(data->title.image) {
277 blit_surface(smode->screen, data->title.image,
278 (smode->width - data->title.image->w) / 2, 0);
281 if(data->gui.hoverback.image) {
282 blit_surface(smode->screen, data->gui.hoverback.image,
283 (smode->width - data->gui.hoverback.image->w) / 2,
284 smode->height * .69);
287 for(x = 0; x < gui->panel[PANEL_MAIN_MENU]->widgets; x ++) {
288 switch(paint_widget(smode, font, theme, gui,
289 gui->panel[PANEL_MAIN_MENU]->widget[x])) {
291 case BOX_OUT_HOVER:
292 case BOX_IN_ACTIVE:
293 if(data->gui.hover[x].image) {
294 blit_surface(smode->screen, data->gui.hover[x].image,
295 (smode->width - data->gui.hover[x].image->w) / 2,
296 smode->height * .69);
299 break;
300 default:
301 break;
305 paint_menu_fps(smode->screen, font);
307 /*SDL_GetMouseState(&xp, &yp);
308 pixelRGBA(screen, xp, yp, 255, 255, 255, 255);*/
310 SDL_UpdateRect(smode->screen, 0, 0, 0, 0);
313 void paint_menu_fps(SDL_Surface *screen, struct font_t *font) {
314 static unsigned long count = 0, total = 0, lastfps = 0;
315 static Uint32 lasttick = 0;
316 Uint32 tick = SDL_GetTicks();
317 char buffer[BUFSIZ];
318 SDL_Surface *text;
320 if(tick >= lasttick + 1000) {
321 lasttick = tick;
322 lastfps = count;
323 count = 0;
326 count ++;
327 total ++;
329 sprintf(buffer, "%3lu FPS | %lu (+%3lu) frames | %lu.%03lu seconds",
330 lastfps, total, count, (unsigned long)tick / 1000,
331 (unsigned long)tick % 1000);
332 text = render_white_text(font->mono, buffer);
334 blit_surface(screen, text, 10, 10);
336 SDL_FreeSurface(text);
339 static void free_resize_menu(struct menu_data_t *data, struct gui_t *gui) {
340 size_t x;
342 SDL_FreeSurface(data->title.image);
344 /*free_panel(gui->panel[PANEL_MAIN_MENU]);*/
346 for(x = 0; x < sizeof(data->gui.hover)/sizeof(*data->gui.hover); x ++) {
347 SDL_FreeSurface(data->gui.hover[x].image);
350 SDL_FreeSurface(data->gui.hoverback.image);
353 void free_menu(struct menu_data_t *data, struct gui_t *gui) {
354 size_t x;
356 free_resize_menu(data, gui);
358 SDL_FreeSurface(data->title.original);
360 SDL_FreeSurface(data->back0.image);
361 SDL_FreeSurface(data->back1.image);
363 for(x = 0; x < sizeof(data->gui.hover)/sizeof(*data->gui.hover); x ++) {
364 SDL_FreeSurface(data->gui.hover[x].original);
367 SDL_FreeSurface(data->gui.hoverback.original);