Created Makefiles for the dist/ subdirectory and put dist/ under subversion control.
[xuni.git] / src / menu.c
blob4b39e6cf35227d60b046aaab226de01ce644bab4
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 void free_resize_menu(struct menu_data_t *data, struct gui_t *gui);
18 void init_menu(struct menu_data_t *data, struct smode_t *smode,
19 struct font_t *font, struct gui_t *gui) {
21 size_t x;
22 /* gui/default/menuhover/X.png\0 */
23 char fn[GUI_PATH_LEN + /*7 + 1*/ + 9 + 1 + 1+1+3 + 1]
24 = GUI_PATH /*"default/"*/"menuhover/";
26 load_resize_image(&data->title, GUI_PATH "title.png");
28 data->frame_based = smode->main_menu_quality;
30 for(x = 0; x < sizeof(data->gui.hover)/sizeof(*data->gui.hover); x ++) {
31 sprintf(fn + GUI_PATH_LEN + /*7 + 1*/ + 9 + 1, "%i.png", (int)x);
32 load_resize_image(&data->gui.hover[x], fn);
35 /* !!! */
36 load_resize_image(&data->gui.hoverback, GUI_PATH "menuhover/back.png");
38 data->back0.image = load_image(GUI_PATH "back0.png");
39 data->back1.image = load_image(GUI_PATH "back1.png");
41 data->quality.x0 = 300.0;
42 data->quality.y0 = 500.0;
43 data->quality.x1 = 600.0;
44 data->quality.y1 = 200.0;
46 add_allocate_widget(gui->panel[PANEL_MAIN_MENU], 0, WIDGET_BUTTON);
47 add_allocate_widget(gui->panel[PANEL_MAIN_MENU], 1, WIDGET_BUTTON);
48 add_allocate_widget(gui->panel[PANEL_MAIN_MENU], 2, WIDGET_BUTTON);
50 add_allocate_widget(gui->panel[PANEL_MAIN_MENU], 3, WIDGET_BUTTON);
51 add_allocate_widget(gui->panel[PANEL_MAIN_MENU], 4, WIDGET_BUTTON);
52 add_allocate_widget(gui->panel[PANEL_MAIN_MENU], 5, WIDGET_BUTTON);
54 data->loaded = 0;
55 resize_menu_images(data, smode, font, gui);
56 data->loaded = 1;
59 static void resize_menu_images(struct menu_data_t *data,
60 struct smode_t *smode, struct font_t *font, struct gui_t *gui) {
62 size_t x;
64 if(data->loaded) free_resize_menu(data, gui);
66 /*data->text.loadgame.text = TTF_RenderText_Blended(font->sans,
67 "Load existing game", white);*/
69 /*data->gui.lastid = (size_t)-1;*/
71 set_button(gui->panel[PANEL_MAIN_MENU]->widget[0],
72 font->sans, "Create new game",
73 smode->width / 16, smode->height * .7,
74 smode->width / 3, smode->height / 15);
75 set_button(gui->panel[PANEL_MAIN_MENU]->widget[1],
76 font->sans, "Join multi-player game",
77 smode->width / 16, smode->height * .7 + smode->height / 12,
78 smode->width / 3, smode->height / 15);
79 set_button(gui->panel[PANEL_MAIN_MENU]->widget[2],
80 font->sans, "Load saved game",
81 smode->width / 16, smode->height * .7 + smode->height / 12 * 2,
82 smode->width / 3, smode->height / 15);
84 /*data->gui.widget[1].enabled = 0; !!! disable multiplayer button */
86 set_button(gui->panel[PANEL_MAIN_MENU]->widget[3],
87 font->sans, "Options and preferences",
88 smode->width - smode->width / 3 - smode->width / 16,
89 smode->height * .7, smode->width / 3, smode->height / 15);
90 set_button(gui->panel[PANEL_MAIN_MENU]->widget[4],
91 font->sans, "Help and information",
92 smode->width - smode->width / 3 - smode->width / 16,
93 smode->height * .7 + smode->height / 12,
94 smode->width / 3, smode->height / 15);
95 set_button(gui->panel[PANEL_MAIN_MENU]->widget[5],
96 font->sans, "Quit",
97 smode->width - smode->width / 3 - smode->width / 16,
98 smode->height * .7 + smode->height / 12 * 2,
99 smode->width / 3, smode->height / 15);
101 if(data->title.original) {
102 data->title.image = zoomSurface(data->title.original,
103 smode->width / 1.5 / data->title.original->w,
104 smode->height / 1.5 / data->title.original->h, SMOOTHING_ON);
107 for(x = 0; x < sizeof(data->gui.hover)/sizeof(*data->gui.hover); x ++) {
108 if(data->gui.hover[x].original) {
109 data->gui.hover[x].image
110 = zoomSurface(data->gui.hover[x].original,
111 smode->width / 5.0 / data->gui.hover[x].original->w,
112 smode->height / 3.75 / data->gui.hover[x].original->h,
113 SMOOTHING_ON);
117 if(data->gui.hoverback.original) {
118 data->gui.hoverback.image
119 = zoomSurface(data->gui.hoverback.original,
120 smode->width / 5.0 / data->gui.hoverback.original->w,
121 smode->height / 3.75 / data->gui.hoverback.original->h,
122 SMOOTHING_ON);
126 void start_menu(struct menu_data_t *data, struct theme_t *theme,
127 struct gui_t *gui) {
129 set_caption("Main menu");
131 if(theme->cursor.image && data->frame_based) SDL_ShowCursor(SDL_DISABLE);
132 clear_tab(&gui->tab, PANEL_MAIN_MENU);
135 int menu_event(enum loop_mode_t *mode, SDL_Event *event,
136 struct menu_data_t *data, struct smode_t *smode, struct font_t *font,
137 struct theme_t *theme, struct gui_t *gui) {
139 int repaint = 0;
140 /*struct widget_sel_t sel;*/
142 switch(event->type) {
143 case SDL_MOUSEBUTTONUP:
144 case SDL_MOUSEBUTTONDOWN:
145 case SDL_MOUSEMOTION:
146 break;
147 case SDL_KEYDOWN:
148 break;
149 case SDL_KEYUP:
150 switch(event->key.keysym.sym) {
151 case SDLK_ESCAPE:
152 case SDLK_q:
153 *mode = MODE_QUIT;
154 break;
155 case SDLK_n:
156 *mode = MODE_GAME;
157 break;
158 case SDLK_o:
159 *mode = MODE_OPTIONS;
160 break;
161 case SDLK_F4:
162 if(event->key.keysym.mod & KMOD_ALT) *mode = MODE_QUIT;
163 break;
164 default: break;
166 break;
167 case SDL_QUIT:
168 *mode = MODE_QUIT;
169 break;
170 case SDL_VIDEORESIZE:
171 resize_menu_images(data, smode, font, gui);
172 repaint = 1;
173 break;
174 default:
175 repaint = 1;
176 break;
179 return repaint;
182 int set_menu_widget_sel(int xp, int yp, int click, struct menu_data_t *data,
183 struct smode_t *smode, struct theme_t *theme, struct gui_t *gui) {
185 if(set_widget_sel_repaint(&gui->sel, xp, yp, click,
186 gui->panel[PANEL_MAIN_MENU])) {
188 return 1;
191 return 0;
194 void menu_perform_click(int id, enum loop_mode_t *mode) {
195 switch(id) {
196 case 0:
197 *mode = MODE_GAME;
198 break;
199 case 3:
200 *mode = MODE_OPTIONS;
201 break;
202 case 5:
203 *mode = MODE_QUIT;
204 break;
205 default:
206 break;
210 void paint_menu(struct menu_data_t *data, struct smode_t *smode,
211 struct font_t *font, struct theme_t *theme, struct gui_t *gui) {
213 size_t x;
214 int xp, yp;
216 lock_screen(smode->screen);
217 SDL_FillRect(smode->screen, NULL,
218 SDL_MapRGB(smode->screen->format, 0, 0, 0));
219 unlock_screen(smode->screen);
221 if(data->back0.image) {
222 if(data->frame_based) {
223 blit_surface_fill_from(smode->screen, data->back0.image, 0, 0,
224 smode->width, smode->height, data->back0.x, data->back0.y);
226 data->back0.x += smode->width / data->quality.x0;
227 data->back0.y += smode->height / data->quality.y0;
229 if(data->back0.x >= data->back0.image->w) {
230 data->back0.x = 0;
232 if(data->back0.y >= data->back0.image->h) {
233 data->back0.y = 0;
236 else {
237 blit_surface_repeat(smode->screen, data->back0.image,
238 0, 0, smode->width, smode->height);
242 if(data->frame_based >= 2 && data->back1.image) {
243 blit_surface_fill_from(smode->screen, data->back1.image,
244 0, 0, smode->width, smode->height, data->back1.x, data->back1.y);
246 data->back1.x += smode->width / data->quality.x1;
247 data->back1.y += smode->height / data->quality.y1;
249 if(data->back1.x >= data->back1.image->w) {
250 data->back1.x = 0;
252 if(data->back1.y >= data->back1.image->h) {
253 data->back1.y = 0;
257 if(data->title.image) {
258 blit_surface(smode->screen, data->title.image,
259 (smode->width - data->title.image->w) / 2, 0);
262 if(data->gui.hoverback.image) {
263 blit_surface(smode->screen, data->gui.hoverback.image,
264 (smode->width - data->gui.hoverback.image->w) / 2,
265 smode->height * .69);
268 for(x = 0; x < gui->panel[PANEL_MAIN_MENU]->widgets; x ++) {
269 switch(paint_widget(smode, font, theme, gui,
270 gui->panel[PANEL_MAIN_MENU]->widget[x])) {
272 case BOX_OUT_HOVER:
273 case BOX_IN_ACTIVE:
274 if(data->gui.hover[x].image) {
275 blit_surface(smode->screen, data->gui.hover[x].image,
276 (smode->width - data->gui.hover[x].image->w) / 2,
277 smode->height * .69);
280 break;
281 default:
282 break;
286 paint_menu_fps(smode->screen, font);
288 if(theme->cursor.image && data->frame_based) {
289 SDL_GetMouseState(&xp, &yp);
290 blit_surface(smode->screen, theme->cursor.image,
291 xp - theme->cursor.image->w / 2, yp - theme->cursor.image->h / 2);
294 /*SDL_GetMouseState(&xp, &yp);
295 pixelRGBA(screen, xp, yp, 255, 255, 255, 255);*/
297 SDL_UpdateRect(smode->screen, 0, 0, 0, 0);
300 void paint_menu_fps(SDL_Surface *screen, struct font_t *font) {
301 static unsigned long count = 0, total = 0, lastfps = 0;
302 static Uint32 lasttick = 0;
303 Uint32 tick = SDL_GetTicks();
304 char buffer[BUFSIZ];
305 SDL_Surface *text;
307 if(tick >= lasttick + 1000) {
308 lasttick = tick;
309 lastfps = count;
310 count = 0;
313 count ++;
314 total ++;
316 sprintf(buffer, "%3lu FPS | %lu (+%3lu) frames | %lu.%03lu seconds",
317 lastfps, total, count, (unsigned long)tick / 1000,
318 (unsigned long)tick % 1000);
319 text = render_white_text(font->mono, buffer);
321 blit_surface(screen, text, 10, 10);
323 SDL_FreeSurface(text);
326 static void free_resize_menu(struct menu_data_t *data, struct gui_t *gui) {
327 size_t x;
329 SDL_FreeSurface(data->title.image);
331 /*free_panel(gui->panel[PANEL_MAIN_MENU]);*/
333 for(x = 0; x < sizeof(data->gui.hover)/sizeof(*data->gui.hover); x ++) {
334 SDL_FreeSurface(data->gui.hover[x].image);
337 SDL_FreeSurface(data->gui.hoverback.image);
340 void free_menu(struct menu_data_t *data, struct gui_t *gui) {
341 size_t x;
343 free_resize_menu(data, gui);
345 SDL_FreeSurface(data->title.original);
347 SDL_FreeSurface(data->back0.image);
348 SDL_FreeSurface(data->back1.image);
350 for(x = 0; x < sizeof(data->gui.hover)/sizeof(*data->gui.hover); x ++) {
351 SDL_FreeSurface(data->gui.hover[x].original);
354 SDL_FreeSurface(data->gui.hoverback.original);