=== Overview ===
[xuni.git] / src / test / menu.c
blob8748eed73ba9b1ae0b53f93d5d8c1cd994922b4d
1 /*! \file menu.c
3 */
5 #include <string.h>
7 #include "SDL_image.h"
8 #include "SDL_rotozoom.h"
10 #include "menu.h"
12 #include "error.h"
13 #include "graphics.h"
14 #include "gui.h"
15 #include "loop.h"
16 #include "memory.h"
17 #include "xuni.h"
18 #include "resource/resource.h"
20 #include "widget/widgets.h"
21 #include "widget/button.h"
23 #include "main.h"
24 #include "version.h"
26 enum wid_t {
27 WID_ORION_BACKGROUND,
28 WID_MOON_BACKGROUND,
29 WID_PARALLAX_BACKGROUND_0,
30 WID_PARALLAX_BACKGROUND_1,
31 WID_PARALLAX_BACKGROUND_2,
32 WID_PARALLAX_BACKGROUND_3,
33 WID_VERSION_LABEL,
34 WID_NEWGAME,
35 WID_MULTIPLAYER,
36 WID_LOADGAME,
37 WID_OPTIONS,
38 WID_HELP,
39 WID_QUIT,
40 WID_NEWGAME_IMAGE,
41 WID_MULTIPLAYER_IMAGE,
42 WID_LOADGAME_IMAGE,
43 WID_OPTIONS_IMAGE,
44 WID_HELP_IMAGE,
45 WID_QUIT_IMAGE,
46 WIDS
49 struct string_index_t main_menu_background_names[MAIN_MENU_BACKGROUNDS] = {
50 {"Black", MAIN_MENU_BACKGROUND_BLACK},
51 {"Moon with parallax clouds",
52 MAIN_MENU_BACKGROUND_MOON_WITH_PARALLAX_CLOUDS},
53 {"Orion nebula", MAIN_MENU_BACKGROUND_ORION_NEBULA},
54 {"Orion nebula frame update", MAIN_MENU_BACKGROUND_ORION_NEBULA_FRAME},
55 {"Parallax clouds", MAIN_MENU_BACKGROUND_PARALLAX_CLOUDS}
58 static void set_hover_visible(struct gui_t *gui, struct widget_t *menu);
60 void switch_main_menu_background(struct widget_t *panel, const char *name) {
61 size_t index = string_to_index(main_menu_background_names,
62 sizeof(main_menu_background_names)
63 / sizeof(*main_menu_background_names), name);
64 static size_t wids[] = {
65 WID_ORION_BACKGROUND,
66 WID_MOON_BACKGROUND,
67 WID_PARALLAX_BACKGROUND_0,
68 WID_PARALLAX_BACKGROUND_1,
69 WID_PARALLAX_BACKGROUND_2,
70 WID_PARALLAX_BACKGROUND_3
72 static struct {
73 int frameupdate;
74 int enable[6];
75 } data[] = {
76 {1, {0, 1, 0, 1, 1, 1}},
77 {0, {1, 0, 0, 0, 0, 0}},
78 {1, {1, 0, 0, 0, 0, 0}},
79 {1, {0, 0, 1, 1, 0, 0}},
80 {0, {0, 0, 0, 0, 0, 0}}
82 size_t x;
84 if(index != (size_t)-1) {
85 panel->p.panel->frameupdate = data[index].frameupdate;
87 for(x = 0; x < sizeof(wids) / sizeof(*wids); x ++) {
88 if(data[index].enable[x]) {
89 widget_nameid_access(panel, wids[x])->visibility
90 |= WIDGET_VISIBILITY_VISIBLE;
92 else {
93 widget_nameid_access(panel, wids[x])->visibility
94 &= ~WIDGET_VISIBILITY_VISIBLE;
100 void init_menu(void *vdata, struct xuni_t *xuni,
101 struct widget_t *panel, struct resource_t *settings) {
103 init_wid(xuni->gui->widget, xuni->gui->widget,
104 PANEL_MAIN_MENU, "main menu");
106 init_wid(xuni->gui->widget, panel, WID_ORION_BACKGROUND,
107 "main menu/orion background");
108 init_wid(xuni->gui->widget, panel, WID_MOON_BACKGROUND,
109 "main menu/moon background");
110 init_wid(xuni->gui->widget, panel, WID_PARALLAX_BACKGROUND_0,
111 "main menu/parallax background 0");
112 init_wid(xuni->gui->widget, panel, WID_PARALLAX_BACKGROUND_1,
113 "main menu/parallax background 1");
114 init_wid(xuni->gui->widget, panel, WID_PARALLAX_BACKGROUND_2,
115 "main menu/parallax background 2");
116 init_wid(xuni->gui->widget, panel, WID_PARALLAX_BACKGROUND_3,
117 "main menu/parallax background 3");
118 init_wid(xuni->gui->widget, panel, WID_VERSION_LABEL,
119 "main menu/version label");
120 init_wid(xuni->gui->widget, panel, WID_NEWGAME, "main menu/newgame");
121 init_wid(xuni->gui->widget, panel, WID_MULTIPLAYER,
122 "main menu/multiplayer");
123 init_wid(xuni->gui->widget, panel, WID_LOADGAME, "main menu/loadgame");
124 init_wid(xuni->gui->widget, panel, WID_OPTIONS, "main menu/options");
125 init_wid(xuni->gui->widget, panel, WID_HELP, "main menu/help");
126 init_wid(xuni->gui->widget, panel, WID_QUIT, "main menu/quit");
127 init_wid(xuni->gui->widget, panel, WID_NEWGAME_IMAGE,
128 "main menu/newgame image");
129 init_wid(xuni->gui->widget, panel, WID_MULTIPLAYER_IMAGE,
130 "main menu/multiplayer image");
131 init_wid(xuni->gui->widget, panel, WID_LOADGAME_IMAGE,
132 "main menu/loadgame image");
133 init_wid(xuni->gui->widget, panel, WID_OPTIONS_IMAGE,
134 "main menu/options image");
135 init_wid(xuni->gui->widget, panel, WID_HELP_IMAGE,
136 "main menu/help image");
137 init_wid(xuni->gui->widget, panel, WID_QUIT_IMAGE,
138 "main menu/quit image");
140 add_widget_accelerator(xuni, panel,
141 widget_nameid_access(panel, WID_NEWGAME), SDLK_n, KMOD_NONE);
142 add_widget_accelerator(xuni, panel,
143 widget_nameid_access(panel, WID_OPTIONS), SDLK_o, KMOD_NONE);
144 add_widget_accelerator(xuni, panel,
145 widget_nameid_access(panel, WID_QUIT), SDLK_q, KMOD_NONE);
147 xuni_memory_free((void *)
148 widget_nameid_access(panel, WID_VERSION_LABEL)->p.label->text);
149 widget_nameid_access(panel, WID_VERSION_LABEL)->p.label->text
150 = xuni_memory_duplicate_string(get_xuni_version_string());
152 widget_event(xuni, widget_nameid_access(panel, WID_VERSION_LABEL),
153 WIDGET_EVENT_RESCALE);
155 /*data->quality.x0 = 300.0;
156 data->quality.y0 = 500.0;
157 data->quality.x1 = 600.0;
158 data->quality.y1 = 200.0;*/
161 void start_menu(void *vdata, struct xuni_t *xuni) {
162 struct widget_t *cursor;
163 struct widget_t *panel
164 = widget_nameid_access(xuni->gui->widget, PANEL_MAIN_MENU);
166 set_caption("Main menu");
168 cursor = widget_nameid_access(xuni->theme->current, THEME_DEFAULT_CURSOR);
170 if(cursor && cursor->p.image->image && panel->p.panel->frameupdate) {
171 show_cursor(0);
175 int menu_event(void *vdata, struct xuni_t *xuni, panel_type_t *mode,
176 SDL_Event *event) {
178 int repaint = 0;
180 switch(event->type) {
181 case SDL_KEYDOWN:
182 switch(event->key.keysym.sym) {
183 case SDLK_F4:
184 if(event->key.keysym.mod & KMOD_ALT) *mode = PANEL_NONE;
185 break;
186 default: break;
188 break;
189 case SDL_QUIT:
190 *mode = PANEL_NONE;
191 break;
192 case SDL_KEYUP:
193 case SDL_MOUSEMOTION:
194 break;
195 default:
196 repaint = 1;
197 break;
200 return repaint;
203 int menu_perform_click(struct widget_t *widget, panel_type_t *mode,
204 void *vdata, struct xuni_t *xuni) {
206 switch(widget->id) {
207 case WID_NEWGAME:
208 *mode = PANEL_GAME;
209 break;
210 case WID_OPTIONS:
211 *mode = PANEL_OPTIONS;
212 break;
213 case WID_QUIT:
214 *mode = PANEL_NONE;
215 break;
216 default:
217 break;
220 return 0; /* ignored */
223 static void set_hover_visible(struct gui_t *gui, struct widget_t *menu) {
224 size_t x;
226 for(x = WID_NEWGAME_IMAGE; x <= WID_QUIT_IMAGE; x ++) {
227 if(gui->sel.p.widget && gui->sel.p.widget == widget_nameid_follow(
228 menu, x + (WID_NEWGAME - WID_NEWGAME_IMAGE), (size_t)-1)) {
230 widget_nameid_access(menu, x)->visibility
231 |= WIDGET_VISIBILITY_VISIBLE;
233 else {
234 widget_nameid_access(menu, x)->visibility
235 &= ~WIDGET_VISIBILITY_VISIBLE;
240 void paint_menu(void *vdata, panel_type_t mode, struct xuni_t *xuni) {
241 struct widget_t *panel
242 = widget_nameid_access(xuni->gui->widget, PANEL_MAIN_MENU);
244 lock_screen(xuni->smode->screen);
245 clear_screen(xuni->smode->screen);
246 unlock_screen(xuni->smode->screen);
248 /*add_widget_clip(xuni,
249 widget_nameid_access(panel, WID_PARALLAX_BACKGROUND_0),
250 xuni->smode->width / data->quality.x0,
251 xuni->smode->height / data->quality.y0, 0, 0, 0, 0);
252 add_widget_clip(xuni,
253 widget_nameid_access(panel, WID_PARALLAX_BACKGROUND_1),
254 xuni->smode->width / data->quality.x1,
255 xuni->smode->height / data->quality.y1, 0, 0, 0, 0);*/
257 set_hover_visible(xuni->gui, panel);
259 widget_event(xuni, panel, WIDGET_EVENT_PAINT);
261 paint_menu_fps(xuni, THEME_FONT_MONO);
263 if(panel->p.panel->frameupdate) {
264 paint_cursor(xuni->smode,
265 widget_nameid_access(xuni->theme->current, THEME_DEFAULT_CURSOR));
268 update_screen(xuni);
271 void paint_menu_fps(struct xuni_t *xuni, size_t font) {
272 static unsigned long count = 0, total = 0, lastfps = 0;
273 static Uint32 lasttick = 0;
274 Uint32 tick = SDL_GetTicks();
275 char buffer[BUFSIZ];
276 SDL_Surface *text;
278 if(tick >= lasttick + 1000) {
279 lasttick = tick;
280 lastfps = count;
281 count = 0;
284 count ++;
285 total ++;
287 sprintf(buffer, "%3lu FPS | %lu (+%3lu) frames | %lu.%03lu seconds",
288 lastfps, total, count, (unsigned long)tick / 1000,
289 (unsigned long)tick % 1000);
290 text = render_text(get_theme_widget(xuni, font), buffer, 255, 255, 255);
292 blit_surface(xuni->smode->screen, text, 10, 10);
294 free_surface(text);
297 void free_main_menu(void *vdata, struct xuni_t *xuni) {