Add SDL2_mixer support.
[runemen.git] / src / mainmenu.c
blobeee5a761a1e20dd2d57c44481bd466ca586a2efd
1 #include <SDL.h>
3 #include "libs/lazyass/lazyass.h"
4 #include "libs/SDL_inprint/SDL2_inprint.h"
6 #include "draw.h"
7 #include "rune.h"
8 #include "ui.h"
10 SDL_Texture *bg;
11 SDL_Texture *sf;
13 #define BUTTON_PADDING 4
15 #ifndef SDL_InBounds
16 #define SDL_InBounds(X, Y, RECT) \
17 ((X) >= (RECT)->x && (X) <= (RECT)->x + (RECT)->w && \
18 (Y) >= (RECT)->y && (Y) <= (RECT)->y + (RECT)->h)
19 #endif
21 void draw_scale9x(SDL_Renderer *renderer, SDL_Rect *full, SDL_Rect *center, SDL_Rect *dst, SDL_bool stretch) {
23 SDL_Rect top_left = { full->x, full->y, center->x, center->y };
24 SDL_Rect bottom_left = { full->x, full->y + center->y + center->h, center->x, full->h - center->y - center->h };
25 SDL_Rect top_right = { full->x + center->x + center->w, full->y, full->w - center->x - center->w, center->y };
26 SDL_Rect bottom_right = { full->x + center->x + center->w, full->y + center->y + center->h, full->w - center->x - center->w, full->h - center->y - center->h };
28 SDL_Rect top_left_dst = { dst->x, dst->y, top_left.w, top_left.h };
29 SDL_Rect bottom_left_dst = { dst->x, dst->y + dst->h - bottom_left.h, bottom_left.w, bottom_left.h };
30 SDL_Rect top_right_dst = { dst->x + dst->w - top_right.w, dst->y, top_right.w, top_right.h };
31 SDL_Rect bottom_right_dst = { dst->x + dst->w - bottom_right.w, dst->y + dst->h - bottom_right.h, bottom_right.w, bottom_right.h };
33 SDL_Rect left = { full->x, full->y + center->y, center->x, center->h };
34 SDL_Rect left_dst = { dst->x, dst->y + center->y, left.w, left.h };
36 SDL_Rect right = { full->x + center->x + center->w, full->y + center->y, center->x, center->h };
37 SDL_Rect right_dst = { dst->x + dst->w - right.w, dst->y + center->y, right.w, right.h };
39 SDL_Rect top = { full->x + center->x, full->y, center->w, center->y };
40 SDL_Rect top_dst = { dst->x + center->x, dst->y, top.w, top.h };
42 SDL_Rect bottom = { full->x + center->x, full->y + center->y + center->h, center->w, center->y };
43 SDL_Rect bottom_dst = { dst->x + center->x, dst->y + dst->h - bottom.h, bottom.w, bottom.h };
45 SDL_Rect center_src = { full->x + center->x, full->y + center->y, center->w, center->h };
46 SDL_Rect center_dst = { dst->x + center->x, dst->y + center->y, center->w, center->h };
48 if (stretch == SDL_TRUE) {
50 top_dst.w = dst->w - center->w;
51 bottom_dst.w = dst->w - center->w;
53 center_dst.w = dst->w - center->w;
54 center_dst.h = dst->h - center->h;
56 left_dst.h = dst->h - center->h;
57 right_dst.h = dst->h - center->h;
59 SDL_RenderCopy(renderer, tiles, &center_src, &center_dst);
61 SDL_RenderCopy(renderer, tiles, &top, &top_dst);
62 SDL_RenderCopy(renderer, tiles, &left, &left_dst);
63 SDL_RenderCopy(renderer, tiles, &right, &right_dst);
64 SDL_RenderCopy(renderer, tiles, &bottom, &bottom_dst);
66 } else {
68 for (center_dst.y = dst->y + center->y ; center_dst.y < dst->y + dst->h - center_dst.h; center_dst.y += center_dst.h) {
69 for (center_dst.x = dst->x + center->x ; center_dst.x < dst->x + dst->w - center_dst.w; center_dst.x += center_dst.w) {
70 SDL_RenderCopy(renderer, tiles, &center_src, &center_dst);
71 } }
73 for (top_dst.x = dst->x + center->x ; top_dst.x < dst->x + dst->w - top_dst.w; top_dst.x += top_dst.w) {
74 SDL_RenderCopy(renderer, tiles, &top, &top_dst);
75 SDL_RenderCopy(renderer, tiles, &bottom, &bottom_dst);
76 bottom_dst.x += bottom_dst.w;
79 for (left_dst.y = dst->y + center->y ; left_dst.y < dst->y + dst->h - left_dst.h; left_dst.y += left_dst.h) {
80 SDL_RenderCopy(renderer, tiles, &left, &left_dst);
81 SDL_RenderCopy(renderer, tiles, &right, &right_dst);
82 right_dst.y += right_dst.h;
87 SDL_RenderCopy(renderer, tiles, &top_left, &top_left_dst);
88 SDL_RenderCopy(renderer, tiles, &bottom_left, &bottom_left_dst);
89 SDL_RenderCopy(renderer, tiles, &top_right, &top_right_dst);
90 SDL_RenderCopy(renderer, tiles, &bottom_right, &bottom_right_dst);
93 void draw_pushbutton(SDL_Renderer *renderer, Uint32 x, Uint32 y, Uint8 tw, Uint8 th, int state) {
95 SDL_Rect src = { TILE_BUTTON_X * TILE_W + state * TILE_W, TILE_BUTTON_Y * TILE_H, TILE_W, TILE_H };
97 SDL_Rect dst = { x, y, tw * TILE_W, th * TILE_H };
99 SDL_Rect center = { TILE_W/4, TILE_H/4, TILE_W/2, TILE_H/2 };
101 draw_scale9x(renderer, &src, &center, &dst, SDL_FALSE);
104 Uint32 mouse_x = 0;
105 Uint32 mouse_y = 0;
106 Uint8 mouse_push = 0;
107 Sint16 mouse_hover = -1;
109 SDL_Rect buttons[16] = {
110 { 240, 180 + (TILE_H+BUTTON_PADDING) * 0, 8, 1 },
111 { 240, 180 + (TILE_H+BUTTON_PADDING) * 1, 8, 1 },
112 { 240, 180 + (TILE_H+BUTTON_PADDING) * 2, 8, 1 },
113 { 240, 180 + (TILE_H+BUTTON_PADDING) * 3, 8, 1 },
114 { 240, 180 + (TILE_H+BUTTON_PADDING) * 4, 8, 1 },
116 const char *button_names[16] = {
117 "Debug Mode",
118 "Single Player",
119 "Multi Player",
120 "Options",
121 "Quit Game",
123 int button_ok[16] = {
130 int button_text_offx = 0;
131 int button_text_offy = 0;
133 int max_buttons = 5;
135 void adjust_buttons() {
136 int i;
138 Uint32 x = ui.log_width / 3;
139 Uint32 y = ui.log_height / 4;
141 int zoom = 1;
143 if (ui.no_mouse) zoom = 2;
146 if (zoom > 1) {
147 button_text_offx = 2 * zoom;
148 button_text_offy = 4 * zoom;
151 for (i = 0; i < max_buttons; i++) {
153 SDL_Rect *btn = &buttons[i];
155 btn->x = x;
156 btn->y = y + (TILE_H * zoom + BUTTON_PADDING) * i;
157 btn->h = zoom;
163 void draw_mainmenu(SDL_Renderer *renderer) {
165 //SDL_SetRenderDrawColor(renderer, 0xff, 0xff, 0xff, 255);
166 //SDL_RenderClear(renderer);
168 Uint8 push_offset_x[5] = { 0, 0, 0, 0, 2 };
169 Uint8 push_offset_y[5] = { 0, 0, 0, 0, 1 };
170 SDL_Color color_offset[5] = {
171 { 0x00, 0x00, 0x00, 0x00 },
172 { 0x33, 0x33, 0x33, 0x33 },
173 { 0xCC, 0xCC, 0xCC, 0xCC },
174 { 0x33, 0x33, 0x33, 0x33 },
175 { 0xEE, 0xEE, 0xEE, 0xEE },
178 SDL_RenderCopy(renderer, bg, NULL, NULL);
180 int i;
181 for (i = 0; i < max_buttons; i++) {
183 int hover = 0;
185 if (mouse_hover == i) hover = 1 + mouse_push;
187 if (button_ok[i]) hover += 2;
188 else hover = 1;
190 draw_pushbutton(renderer, buttons[i].x, buttons[i].y, buttons[i].w, buttons[i].h, hover);
191 incolor1(&color_offset[hover]);
192 inprint(renderer, button_names[i],
193 buttons[i].x + BUTTON_PADDING + push_offset_x[hover] + button_text_offx,
194 buttons[i].y + BUTTON_PADDING + push_offset_y[hover] + button_text_offy);
198 /* Draw cursor */
199 draw_tile(renderer, 22, 4 + (mouse_hover != -1 ? 1 : 0) + mouse_push, mouse_x - 4, mouse_y - 4);
202 void track_mouse_mainmenu() {
204 int i;
205 mouse_hover = -1;
206 for (i = 0; i < max_buttons; i++) {
208 SDL_Rect test = { buttons[i].x, buttons[i].y, buttons[i].w * TILE_W, buttons[i].h * TILE_H };
210 if (SDL_InBounds(mouse_x, mouse_y, &test)) {
212 mouse_hover = i;
213 break;
216 if (mouse_hover == -1) mouse_push = 0;
219 int do_mainmenu_event(SDL_Event *e) {
220 if (e->type == SDL_MOUSEMOTION && e->motion.which != SDL_TOUCH_MOUSEID) {
221 mouse_x = e->motion.x;
222 mouse_y = e->motion.y;
224 if ((e->type == SDL_MOUSEBUTTONDOWN || e->type == SDL_MOUSEBUTTONUP) && e->motion.which != SDL_TOUCH_MOUSEID) {
225 mouse_x = e->button.x;
226 mouse_y = e->button.y;
228 if (e->type == SDL_FINGERUP) {
229 mouse_x = (e->tfinger.x * ui.log_width);
230 mouse_y = (e->tfinger.y * ui.log_height);
231 track_mouse_mainmenu();
233 if (mouse_hover != -1) {
234 switch (mouse_hover) {
235 case 0:
236 return 1;
237 break;
238 case 4:
239 return -1;
240 break;
241 default: break;
246 if (e->type == SDL_MOUSEBUTTONDOWN && e->motion.which != SDL_TOUCH_MOUSEID) {
247 mouse_push = 1;
249 if (e->type == SDL_MOUSEBUTTONUP && e->motion.which != SDL_TOUCH_MOUSEID) {
250 mouse_push = 0;
252 if (mouse_hover != -1) {
253 switch (mouse_hover) {
254 case 0:
255 return 1;
256 break;
257 case 4:
258 return -1;
259 break;
260 default: break;
265 track_mouse_mainmenu();
266 return 0;
269 /* Returns -1 to quit game, 1 to continue somewhere... */
270 int mainmenu_loop(SDL_Renderer *renderer) {
272 int done = 0;
274 SDL_ShowCursor(SDL_FALSE);
276 SDL_Color white = { 0xff, 0xff, 0xff, 0xff };
278 bg = ASS_LoadTexture("data/endowment.bmp", NULL);
279 tiles = ASS_LoadTexture("data/gfx/runelord.bmp", &white);
281 adjust_buttons();
283 while (!done)
285 SDL_Event event = { 0 };
286 while (SDL_PollEvent(&event)) {
287 done = do_mainmenu_event(&event);
288 if (event.type == SDL_QUIT) done = -1;
289 if (event.type == SDL_KEYDOWN && event.key.keysym.sym == SDLK_ESCAPE) done = -1;
292 draw_mainmenu(renderer);
294 SDL_RenderPresent(renderer);
295 SDL_Delay(10);
298 ASS_FreeTexture(bg);
300 SDL_ShowCursor(SDL_TRUE);
302 SDL_SetRenderDrawColor(renderer, 0x00, 0x00, 0x00, 255);
303 SDL_RenderClear(renderer);
304 SDL_RenderPresent(renderer);
306 return done;