Update oddball6x8 font.
[runemen.git] / src / ui.c
blobf174cbb97ae1296698f7cefe874b6d33776ccd12
1 #include <SDL.h>
2 #include "game.h"
3 #include "rune.h"
4 #include "runeconf.h"
5 #include "ui.h"
7 SDL_Rect ui_pane = { -PANE_WIDTH - 10, 0, PANE_WIDTH + 10, -0 };
8 SDL_Rect top_pane = { 0, 0, -0, 20 };
9 SDL_Rect game_map = { 0, 20, -PANE_WIDTH, -20 };
11 SDL_Rect minimap = { -PANE_WIDTH, 20, PANE_WIDTH, 128+4 };
12 SDL_Rect buildbox = { -PANE_WIDTH, 154, PANE_WIDTH, 48 };
13 SDL_Rect selbox = { -PANE_WIDTH, 154, PANE_WIDTH, 128 };
15 SDL_Rect unitpin = { -24, 154 + 4, 16, 16 };
16 SDL_Rect flagicon = { -24, 112, 16, 16 };
17 SDL_Rect tabicon = { -PANE_WIDTH + 8, 0, 40, 8 };
18 SDL_Rect pinbox = { -PANE_WIDTH, 190, PANE_WIDTH, 150 };
19 SDL_Rect hintbox = { -PANE_WIDTH, -128, PANE_WIDTH, 128 };
21 SDL_Rect plusbtn = { -42, 154 + 31, 16, 16 };
23 ui_t ui;
25 void adjust_boxes() {
27 SDL_Rect *boxes[] = {
28 &minimap, &buildbox, &selbox, &pinbox, &hintbox,
30 &unitpin, &plusbtn, &flagicon, &tabicon,
32 &ui_pane, &top_pane, &game_map,
34 int num = sizeof(boxes) / sizeof(SDL_Rect*);
36 int i;
38 for (i = 0; i < num; i++) {
40 SDL_Rect *box = boxes[i];
42 if (box->x < 0) box->x += ui.log_width;
43 if (box->y < 0) box->y += ui.log_height;
44 if (box->w < 0) box->w += ui.log_width;
45 if (box->h < 0) box->h += ui.log_height;
49 buildbox.y = minimap.y + minimap.h + 1;
51 ui_pane.h = ui.log_height;
52 top_pane.w = ui.log_width;
54 unitpin.y = selbox.y + 4;
55 plusbtn.y = selbox.y + 31;
56 flagicon.y += selbox.y;
57 tabicon.y += selbox.y;
58 tabicon.y += selbox.h;
61 /* Do horrible things... */
62 void adjust_ui() {
64 ui.draw_minimap = 0;
66 ui.draw_overlays = 1;
68 ui.no_mouse = 1;
72 void init_ui(SDL_Renderer *renderer, int w, int h) {
74 ui.log_width = w;
75 ui.log_height = h;
77 /* wood box */
78 ui.draw_uibg = 1;
80 if (w % 320 == 0 && h % 240 == 0) { /* 320 x 240 base, good old VGA */
81 ui.log_width = 640;
82 ui.log_height = 480;
85 if (w % 800 == 0 && h % 600 == 0) { /* 800 x 600 base, good old SVGA */
86 ui.log_width = 400;
87 ui.log_height = 300;
90 if (w % 320 == 0 && h % 188 == 0) { /* 320 x 188 base -- wicked, but acceptable */
91 ui.log_width = 640;
92 ui.log_height = 376;
95 if (w % 240 == 0 && h % 160 == 0) { /* 240 x 160 base -- very small screen */
96 ui.log_width = 480;
97 ui.log_height = 320;
99 #if 0
100 if (h < 400) { /* Very small screen, double the zoom */
102 ui.log_width /= 2;
103 ui.log_height /= 2;
106 #endif
107 if (ui.log_height < 400) { /* Very small base, adjust gui accordingly */
109 minimap.y = 0;
111 hintbox.y = minimap.y;
113 selbox.y = ui.log_height - selbox.h;
115 ui.draw_uibg = 0;
117 buildbox.w = TILE_W * 4;
118 buildbox.x = ui.log_width - buildbox.w - TILE_W/2;
120 buildbox.h = ui.log_height - buildbox.y;
123 SDL_RenderSetLogicalSize(renderer, ui.log_width, ui.log_height);
125 adjust_boxes();
126 #ifdef MOBILE_OS
127 ui.no_mouse = 1;
128 #else
129 ui.no_mouse = 0;
130 #endif
133 void reset_ui() {
134 ui.x = 0;
135 ui.y = 0;
137 ui.vx = 0;
138 ui.vy = 0;
140 ui.dragging = 0;
142 ui.unit = ui.house = ui.flag = -1;
143 ui.builder = ui.setflag = ui.stat = ui.btn = -1;
145 ui.hintType = -1;
147 ui.hover_top = overNothingMajor;
148 ui.hover = overNothingMinor;
150 /* layers */
151 ui.draw_fog = 0;
152 ui.draw_path = 0;
153 ui.draw_pools = 0;
154 ui.draw_overlays = 0;
155 ui.draw_scent = 0;
156 ui.draw_log = 1;
158 /* debug */
159 ui.game_speed = 25;
160 ui.fps = 0;
162 /* for touch/small-screen devices, use different ui */
163 #ifdef MOBILE_OS
164 adjust_ui();
165 #endif
168 void update_hintbox() {
170 switch (ui.hover) {
172 case overBuildButton:
174 ui.hintType = 0;
175 ui.hint = ui.hover_id;
176 break;
178 case overUnitStat:
180 ui.hintType = 1;
181 ui.hint = ui.hover_id;
182 break;
184 default:
185 ui.hintType = -1;
186 ui.hint = -1;
187 break;
190 /* Hacks */
191 if (ui.builder != -1) {
193 ui.hintType = 0;
194 ui.hint = ui.builder;
197 if (ui.stat != -1) {
199 ui.hintType = 1;
200 ui.hint = ui.stat;
206 void track_mouse() {
208 /* Given X and Y mouse position, determine various UI-related states... */
211 ui.hover = overNothingMinor;
212 ui.hover_id = 0;
214 if (SDL_InBounds(ui.x, ui.y, &ui_pane)) {
216 ui.hover_top = overPane;
218 track_mouse_ui();
220 } else if (SDL_InBounds(ui.x, ui.y, &top_pane)) {
222 ui.hover_top = overNothingMajor;
224 } else {
226 ui.hover_top = overMap;
228 track_mouse_map();
232 update_hintbox();
235 void track_mouse_map() {
237 Uint32 unit_i, house_i, flag_i;
239 ui.hover_xcollide = 0;
240 ui.hover = overNothingMinor;
242 if (ui.builder != -1) {
243 house_p *h = &bhouses[ui.builder];
245 int lx = ui.x + ui.vx - game_map.x;
246 int ly = ui.y + ui.vy - game_map.y;
248 int cx = -(TILE_W * h->w / 2) + (TILE_W/2);
249 int cy = -(TILE_H * h->h / 2) + (TILE_H/2);
251 lx += cx;
252 ly += cy;
254 ui.hover_tx = (lx / TILE_W);
255 ui.hover_ty = (ly / TILE_H);
257 ui.hover_xcollide = xcollide(ui.hover_tx, ui.hover_ty, h->w, h->h);
259 return;
262 ui.hover_tx = (ui.x + ui.vx - game_map.x) / TILE_W;
263 ui.hover_ty = (ui.y + ui.vy - game_map.y) / TILE_H;
265 if (ui.setflag != -1) {
267 ui.hover_xcollide = xcollide(ui.hover_tx, ui.hover_ty, 1, 1);
269 if (find_flagT(ui.hover_tx, ui.hover_ty) != -1) ui.hover_xcollide = 2;
272 unit_i = find_unit(ui.x, ui.y);
273 if (unit_i != -1) {
274 ui.hover = overUnit;
275 ui.hover_id = unit_i;
276 return;
278 house_i = find_house(ui.x, ui.y);
279 if (house_i != -1) {
280 ui.hover = overHouse;
281 ui.hover_id = house_i;
282 if (houses[house_i].flag_id[ui.faction] != -1
283 && ui.hover_tx == houses[house_i].x
284 && ui.hover_ty == houses[house_i].y) {
285 ui.hover = overHouseFlag;
286 ui.hover_id = ui.faction;
288 return;
290 flag_i = find_flagT(ui.hover_tx, ui.hover_ty);
291 if (flag_i != -1) {
292 ui.hover = overFlag;
293 ui.hover_id = flag_i;
294 return;
298 void track_mouse_ui() {
300 int i;
302 /* Minimap */
303 if (SDL_InBounds(ui.x, ui.y, &minimap)) {
305 ui.hover = overMinimap;
307 return;
310 /* Top-level menu (i.e. build buttons and unit-list) */
311 if (ui.house == -1 && ui.unit == -1 && ui.flag == -1) {
312 /* Name on the pinbox */
313 if (SDL_InBounds(ui.x, ui.y, &pinbox)) {
315 ui.hover = overPinBox;
316 ui.hover_id = -1;
318 SDL_Rect line = { 0, 0, 120, 16 };
319 SDL_Rect pinbtn = { 0, 0, 16, 16 };
321 line.x = pinbox.x;
322 line.y = pinbox.y;
323 pinbtn.x = pinbox.x + line.w;
324 pinbtn.y = pinbox.y;
326 for (i = 0; i < num_units; i++) {
327 unit_t *u = &units[i];
328 if (u->tile && u->pin) {
330 if (SDL_InBounds(ui.x, ui.y, &line)) {
331 ui.hover = overListName;
332 ui.hover_id = i;
333 return;
335 if (SDL_InBounds(ui.x, ui.y, &pinbtn)) {
336 ui.hover = overListPin;
337 ui.hover_id = i;
338 return;
340 line.y += line.h;
341 pinbtn.y += line.h;
345 return;
350 /* One of the build buttons */
351 if (ui.house == -1 && ui.unit == -1 && ui.flag == -1) {
352 SDL_Rect button = {
353 buildbox.x,
354 buildbox.y,
358 for (i = 0; i < 2; i++) {
359 if (SDL_InBounds(ui.x, ui.y, &button)) {
361 ui.hover = overFlagButton;
362 ui.hover_id = i;
364 return;
367 button.x += 17;
368 if (button.x >= buildbox.x + buildbox.w - TILE_W/2) {
369 button.x = buildbox.x;
370 button.y += 17;
373 for (i = 0; i < HMENU_ITEMS; i++) {
375 if (SDL_InBounds(ui.x, ui.y, &button)) {
377 ui.hover = overBuildButton;
378 ui.hover_id = i;
380 break;
383 button.x += 17;
384 if (button.x >= buildbox.x + buildbox.w - TILE_W/2) {
385 button.x = buildbox.x;
386 button.y += 17;
391 /* Something on the flagbox */
392 if (ui.flag != -1) {
394 /* Plus */
395 if (SDL_InBounds(ui.x, ui.y, &plusbtn)) {
397 ui.hover = overFlagPlus;
399 return;
404 /* Something on the housebox */
405 if (ui.house != -1) {
407 /* Flag icon */
408 if (SDL_InBounds(ui.x, ui.y, &flagicon)) {
410 ui.hover = overHouseFlag;
411 ui.hover_id = 0;
413 return;
417 /* One of the tab icons */
418 SDL_Rect button;
419 button.x = tabicon.x;
420 button.y = tabicon.y;
421 button.w = tabicon.w;
422 button.h = tabicon.h;
423 for (i = 0; i < MAX_HOUSETABS; i++) {
424 if (SDL_InBounds(ui.x, ui.y, &button)) {
425 ui.hover = overHouseTab;
426 ui.hover_id = i;
427 return;
429 button.x += tabicon.w;
430 if (button.x + tabicon.w >= ui.log_width) {
431 button.x = tabicon.x;
432 button.y += tabicon.h;
438 /* Something on the unitbox */
439 if (ui.unit != -1) {
441 /* Pin */
442 if (SDL_InBounds(ui.x, ui.y, &unitpin)) {
444 ui.hover = overUnitPin;
445 ui.hover_id = ui.unit;
447 return;
450 /* Flag icon */
451 if (SDL_InBounds(ui.x, ui.y, &flagicon)) {
453 ui.hover = overUnitFlag;
454 ui.hover_id = 0;
456 return;
461 /* One of the tab icons */
462 if (ui.unit != -1) {
463 SDL_Rect button;
464 button.x = tabicon.x;
465 button.y = tabicon.y;
466 button.w = tabicon.w;
467 button.h = tabicon.h;
468 for (i = 0; i < MAX_UNITTABS; i++) {
469 if (SDL_InBounds(ui.x, ui.y, &button)) {
470 ui.hover = overUnitTab;
471 ui.hover_id = i;
472 return;
474 button.x += tabicon.w;
475 if (button.x + tabicon.w >= ui.log_width) {
476 button.x = tabicon.x;
477 button.y += tabicon.h;
482 /* One of the stat/skill buttons */
483 if (ui.unit != -1) {
484 SDL_Rect button = {
485 selbox.x + BOX_PADDING + BOX_PADDING,
486 selbox.y + BOX_PADDING + BOX_PADDING + BOX_PADDING + 1,
491 for (i = 0; i < MAX_STAT; i++) {
492 button.y += 14;
493 if (SDL_InBounds(ui.x, ui.y, &button)) {
494 ui.hover = overUnitStat;
495 ui.hover_id = i;
499 button.y -= 14 * MAX_STAT;
500 button.x += 64;
502 for (i = 0; i < MAX_STAT; i++) {
503 button.y += 14;
504 if (SDL_InBounds(ui.x, ui.y, &button)) {
505 ui.hover = overUnitSkill;
506 ui.hover_id = i;