Add unit and house tabs, flag button.
[runemen.git] / src / draw.c
blob515d7d9f3ced8187ba7597f967af368a46124224
1 #include <SDL.h>
3 #include "libs/SDL_inprint/SDL2_inprint.h"
5 #include "game.h"
6 #include "ui.h"
7 #include "draw.h"
8 #include "rune.h"
10 SDL_Texture *tiles;
11 SDL_Texture *uibg;
12 SDL_Texture *small_font;
13 SDL_Texture *mid_font;
14 SDL_Texture *large_font;
16 SDL_Color white = { 0xFF, 0xFF, 0xFF, 255 };
17 SDL_Color black = { 0x00, 0x00, 0x00, 255 };
18 SDL_Color brown = { 0x6c, 0x44, 0x1c, 255 };
19 SDL_Color yellow = { 0xFF, 0xFF, 0x00, 255};
20 SDL_Color red = { 0xFF, 0x00, 0x00, 255};
21 SDL_Color darkred= { 0x66, 0x11, 0x11, 255};
23 SDL_Color reds[16];
25 Uint32 state_colors[4] = {
26 0xFFFFFF, 0xFF0000, 0x0000FF, 0x00FF00,
29 extern void SDL_ComputeGradient(SDL_Color *colors, int n, SDL_Color *start, SDL_Color *stop);
30 void prepare_colors() {
32 SDL_Color start = { 0xFF, 0x00, 0x00 };
33 SDL_Color end = { 0x66, 0x11, 0x11 };
35 SDL_ComputeGradient(reds, 16, &start, &end);
39 void MY_LineRect(SDL_Renderer *dst, SDL_Rect *dr, SDL_Color *color)
41 SDL_SetRenderDrawColor(dst, color->r, color->g, color->b, color->a);
42 SDL_RenderDrawRect(dst, dr);
45 void MY_PutPixel(SDL_Renderer *dest, Uint32 x, Sint32 y, SDL_Color *col)
47 SDL_SetRenderDrawColor(dest, col->r, col->g, col->b, col->a);
48 SDL_RenderDrawPoint(dest, x, y);
51 void MY_DrawVector(SDL_Renderer *surface, Sint32 x, Sint32 y, float a, int len, SDL_Color *color)
53 int i;
54 SDL_Rect *clip = NULL;//-&surface->clip_rect;
55 float c = cosf(a * M_PI / 180);
56 float s = sinf(a * M_PI / 180);
57 for (i = 0; i < len; i++)
59 int nx = (int)(x + i * c);
60 int ny = (int)(y + i * s);
62 if (!clip || SDL_InBounds(nx, ny, clip))
64 MY_PutPixel(surface, nx, ny, color);
69 void MY_DrawLine(SDL_Renderer *dst, Sint32 x1, Sint32 y1, Sint32 x2, Sint32 y2, SDL_Color *color)
71 Sint32 dx = x2 - x1;
72 Sint32 dy = y2 - y1;
73 double angle = atan2(dy, dx) * 180 / M_PI;
74 double distance = sqrt( (dx*dx) + (dy*dy) );
76 SDL_SetRenderDrawColor(dst, color->r, color->g, color->b, color->a);
77 //SDL_RenderDrawLine(dst, x1, y1, x2, y2);
78 MY_DrawVector(dst, x1, y1, (float)angle, (int)distance, color);
81 void SDL_AlphaFill(SDL_Renderer *dest, Uint32 x, Sint32 y, Uint32 w, Uint32 h, SDL_Color *color)
83 SDL_Rect dst = { x, y, w, h };
84 //SDL_SetRenderDrawBlendMode(dest, SDL_BLENDMODE_BLEND);
85 SDL_SetRenderDrawColor(dest, color->r, color->g, color->b, color->a);
86 SDL_RenderFillRect(dest, &dst);
88 #define PIXEL_BY_PIXEL
89 void MY_DrawSineWave(SDL_Renderer *surface, Sint32 x, Sint32 y, float a, int len, SDL_Color *col)
91 float i;
92 SDL_Rect *clip = NULL;//&surface->clip_rect;
93 float c = cosf(a * M_PI / 180);
94 float s = sinf(a * M_PI / 180);
95 float AMP = 2;
96 float WAV = 4;
98 #ifndef PIXEL_BY_PIXEL
99 int count = 0; SDL_Point points[1024];
100 #endif
101 int freq = ui.freq;
103 int colorquant = 16;//((len+1) / 16);
105 for (i = 0; i < len; i+= 0.5)//0.1)
107 int j = (int)(freq) % colorquant;
109 int nx = (int)(x + i * c);
110 int ny = (int)(y + i * s);
111 ny += ( cosf( (freq+i) / WAV) * AMP );
112 nx += ( sinf( (freq+i) / WAV) * AMP );
113 #ifndef PIXEL_BY_PIXEL
114 points[count].x = nx;
115 points[count].y = ny;
116 count++;
117 if (count >= sizeof(points) - 2) break;
118 continue;
119 #else
120 if (!clip || SDL_InBounds(nx, ny, clip))
122 MY_PutPixel(surface, nx, ny, &reds[j]);
123 //SDL_AlphaFill(surface, nx, ny, 2, 2, color);
125 #endif
127 #ifndef PIXEL_BY_PIXEL
128 SDL_SetRenderDrawColor(surface, col->r, col->g, col->b, col->a);
129 SDL_RenderDrawPoints(surface, points, count);
130 #endif
132 void MY_DrawSine(SDL_Renderer *dst, Sint32 x1, Sint32 y1, Sint32 x2, Sint32 y2, SDL_Color *color)
134 Sint32 dx = x2 - x1;
135 Sint32 dy = y2 - y1;
136 double angle = atan2(dy, dx) * 180 / M_PI;
137 double distance = sqrt( (dx*dx) + (dy*dy) );
139 MY_DrawSineWave(dst, x1, y1, (float)angle, (int)distance, color);
142 int unit_icon(unit_t *u) {
143 if (u->link == NULL) /* Either rune lord either free man */
144 if (u->ref_counts == 0) return 0; /* FREE MAN */
145 else return 3; /* RUNE LORD */
146 else /* Either a vector either a devotee */
147 if (u->ref_counts == 0) return 1; /* DEVOTEE */
148 else return 2; /* VECTOR */
151 /* RUNE printf */
152 int rprintf(SDL_Renderer *renderer, Uint32 x, Uint32 y, const char *fmt, ...) {
153 char buffer[1024];
155 va_list argptr;
156 va_start(argptr, fmt);
158 vsnprintf(buffer, sizeof(buffer), fmt, argptr);
160 va_end(argptr);
162 inprint(renderer, buffer, x, y);
164 return 0;
168 /* One tile */
169 void draw_tile(SDL_Renderer *screen, Uint8 id, Uint8 frame, Uint32 x, Uint32 y) {
170 SDL_Rect src = { frame * 16, id * 16 , 16, 16 };
171 SDL_Rect dst = { x, y, 16, 16 };
172 SDL_RenderCopy(screen, tiles, &src, &dst);
174 /* W & H tile */
175 void draw_ctile(SDL_Renderer *screen, Uint8 id, Uint8 frame, Uint32 x, Uint32 y, Uint8 w, Uint8 h) {
176 SDL_Rect src = { frame * 16, id * 16 , 16 * w, 16 * h };
177 SDL_Rect dst = { x, y, 16 * w, 16 * h };
178 SDL_RenderCopy(screen, tiles, &src, &dst);
180 /* Stretched tile */
181 void draw_stile(SDL_Renderer *screen, Uint8 id, Uint8 frame, Uint32 x, Uint32 y, Uint8 w, Uint8 h, Uint8 sw, Uint8 sh) {
182 SDL_Rect src = { frame * TILE_W, id * TILE_W , w * TILE_W, h * TILE_H };
183 SDL_Rect dst = { x, y, sw * TILE_W, sh * TILE_H };
184 SDL_RenderCopy(screen, tiles, &src, &dst);
187 /* W & H tile on sx/sy source */
188 void draw_btile(SDL_Renderer *screen, Uint32 sy, Uint32 sx, Uint32 x, Uint32 y, Uint8 w, Uint8 h) {
189 SDL_Rect src = { sx, sy, 16 * w, 16 * h };
190 SDL_Rect dst = { x, y, 16 * w, 16 * h };
191 SDL_RenderCopy(screen, tiles, &src, &dst);
194 void draw_visual(SDL_Renderer *renderer, Uint8 *refs[], animation_t *a, Uint32 x, Uint32 y) {
195 int i;
197 SDL_Rect dst = { x, y, a->plane.w, a->plane.h };
198 //start with base plane...
199 SDL_Rect src = { a->plane.x, a->plane.y, a->plane.w, a->plane.h };
201 //...offset by each modifier axis
202 for (i = 0; i < a->num_axises; i++) {
203 Uint8 ask = a->axis_modifier[i];
204 Uint8 ref = *(refs[ask]);
205 src.x += ref * a->axis_offset[i].w + a->axis_offset[i].x;
206 src.y += ref * a->axis_offset[i].h + a->axis_offset[i].y;
209 SDL_RenderCopy(renderer, a->image, &src, &dst);
214 void draw_blackbox(SDL_Renderer *screen, Uint32 x, Uint32 y, Uint32 w, Uint32 h) {
215 // Uint32 brown = SDL_MapRGB(screen->format, 0x6c, 0x44, 0x1c);
217 SDL_Rect box = { x, y, w, h };
219 SDL_SetRenderDrawColor(screen, 0, 0, 0, 255);
220 SDL_RenderFillRect(screen, &box);
222 /*box.x++;
223 box.y++;
224 box.w-=2;
225 box.h-=2;*/
227 SDL_SetRenderDrawColor(screen, brown.r, brown.g, brown.b, 255);
228 SDL_RenderDrawRect(screen, &box);
232 ///////////
234 void draw_pools(SDL_Renderer *screen) {
236 SDL_Color redish = { 0xff, 0, 0, 0x33 };
237 SDL_Color greenish = { 0, 0xff, 0, 0x33 };
238 SDL_Color black = { 0, 0, 0, 0xAA };
239 SDL_Color white = { 0xff, 0xff, 0xff, 0xEE };
241 int i;
242 for (i = 0 ; i < num_pools; i++) {
243 pool_t *pool = &pools[i];
244 unit_t *head = pool->head;
246 Uint32 x = head->x * TILE_W - TILE_W;
247 Uint32 y = head->y * TILE_H - TILE_H;
249 x -= (i % 4) * 8;
250 y -= (i % 4) * 16;
252 x = x - ui.vx + game_map.x;
253 y = y - ui.vy + game_map.y;
255 SDL_Rect mini = { x, y, 64, 10 };
257 SDL_AlphaFill(screen, x, y, mini.w, mini.h, &black);
258 MY_LineRect(screen, &mini, &redish);
260 // draw_tile(screen, TILE_STAT_Y, TILE_STAT_X + pool->stat, x , y);
262 int links = 0;
263 /* Draw kids overlays */
264 //unit_t *lim = (head->link == pool->tail ? NULL : pool->head);
265 unit_t *it = pool->tail;
266 while (it) {
267 Uint32 sx = it->x * TILE_W + it->ox - ui.vx + game_map.x;
268 Uint32 sy = it->y * TILE_H + it->oy - ui.vy + game_map.y;
270 MY_DrawLine(screen, sx + 8, sy + 4, x, y + mini.h/2, &redish);
272 it = it->link;
273 if (it == head) break;
274 links++;
277 infont(small_font);
278 incolor1(&white);
279 rprintf(screen, x + 3, y + 1, "%02d %s:%03d", links+1, stat_names[pool->stat], pool->pool);
281 Uint32 sx = head->x * TILE_W + it->ox - ui.vx + game_map.x;
282 Uint32 sy = head->y * TILE_H + it->oy - ui.vy + game_map.y;
284 MY_DrawLine(screen, sx + 8, sy + 4, x + mini.w/2, y + mini.h/2, &greenish);
288 //TODO: remove
289 infont(large_font);
291 void draw_paths(SDL_Renderer *screen, Sint8 sel, Uint16 x, Uint16 y) {
292 #ifndef DEBUG_PATHFIND
293 int i,j;
294 if (sel == -1) return;
295 unit_t *su = &units[sel];
296 for (i = 0; i < 16; i++) {
297 if (su->path[i] == -1) break;
298 int x, y;
300 y = su->path[i] / level_w;
301 x = su->path[i] % level_w;
303 Uint32 tx = x * TILE_W - ui.vx + game_map.x;
304 Uint32 ty = y * TILE_H - ui.vy + game_map.y;
306 SDL_Color color = { 255, 255, 255, 128 + i * 8 };
307 SDL_AlphaFill(screen, tx, ty, TILE_W, TILE_H, &color);
311 SDL_AlphaFill(screen,
312 su->tx * TILE_W - ui.vx + game_map.x,
313 su->ty * TILE_H - ui.vy + game_map.y, TILE_W, TILE_H, &yellow);
314 #else
315 int i,j;
316 if (sel == -1) return;
317 unit_t *su = &units[sel];
318 for (j = 0; j < LEVEL_H; j++) {
319 for (i = 0; i < LEVEL_W; i++) {
320 Uint32 pos = j * LEVEL_W + i;
321 Uint32 tx = i * TILE_W - ui.vx + game_map.x;
322 Uint32 ty = j * TILE_H - ui.vy + game_map.y;
323 char buf[16];
324 char vd = '>' - 1;
325 if (su->prev[pos] == -1) vd = '!';
326 else if (su->prev[pos] - pos == -1) vd = '<';
327 else if (su->prev[pos] - pos < -1) vd = '^';
328 else if (su->prev[pos] - pos > 1) vd = 'v';
330 infont(small_font);
331 incolor(0x00FFFFFF, 0);
332 //rprintf(screen, tx, ty, "%ld%c", (su->d[pos]/25 > 9 ? 9 : su->d[pos]/25), vd);
333 rprintf(screen, tx, ty, "%ld", su->d[pos]/10);
335 //Uint32 color = SDL_MapRGBA(screen->format,
336 SDL_Color color = { su->d[pos], su->d[pos], su->d[pos], su->d[pos] };
337 SDL_AlphaFill(screen, tx + x, ty + y, TILE_W, TILE_H, &color);
341 SDL_AlphaFill(screen,
342 su->tar_x * TILE_W - ui.vx + game_map.x,
343 su->tar_y * TILE_H - ui.vy + game_map.y, TILE_W, TILE_H, &red);
346 SDL_AlphaFill(screen,
347 su->tx * TILE_W - ui.vx + game_map.x,
348 su->ty * TILE_H - ui.vy + game_map.y, TILE_W, TILE_H, &yellow);
350 i = ui.hover_tx;
351 j = ui.hover_ty;
352 Uint32 pos = j * LEVEL_W + i;
353 Uint32 tx = i * TILE_W - ui.vx + game_map.x;
354 Uint32 ty = j * TILE_H - ui.vy + game_map.y;
356 infont(small_font);
357 incolor(0x00FF0000, 0);
358 //rprintf(screen, tx, ty, "%ld%c", (su->d[pos]/25 > 9 ? 9 : su->d[pos]/25), vd);
359 rprintf(screen, tx, ty, "%ld", su->d[pos]/10);
361 //TODO: remove
362 infont(large_font);
363 #endif
365 void draw_overlays(SDL_Renderer *screen, Sint8 sel, Uint8 flip, Uint8 block, unit_t *from) {
366 if (sel == -1) return;
367 int i;
368 if (block == 0) for (i = 0; i < num_units; i++) units[i].block = 0;
369 unit_t *su = &units[sel];
370 Uint32 sx = su->x * TILE_W + su->ox - ui.vx + game_map.x;
371 Uint32 sy = su->y * TILE_H + su->oy - ui.vy + game_map.y;
372 su->block = 1;
373 //Uint32 colors[16] = { 0x00FF0033, 0xFF000033 };
374 for (i = 0; i < num_units; i++) {
375 unit_t *u = &units[i];
376 Uint32 x = u->x * TILE_W + u->ox - ui.vx + game_map.x;
377 Uint32 y = u->y * TILE_H + u->oy - ui.vy + game_map.y;
379 if (u->tile == 0 || u == from) continue;
380 if (u->link == su ) {
381 MY_DrawSine(screen, sx + 8, sy + 4, x + 8, y + 4, reds);//colors[flip]);
382 //SDL_DrawLine(screen, sx + 8, sy + 4, x + 8, y + 4, colors[flip]);
383 if (!u->block) draw_overlays(screen, i, flip, 1, su);
385 if (su->link == u) {
386 MY_DrawSine(screen, x + 8, y + 4, sx + 8, sy + 4, reds);//colors[1 - flip]);
387 //SDL_DrawLine(screen, sx + 8, sy + 4, x + 8, y + 4, colors[flip]);
388 if (!u->block) draw_overlays(screen, i, flip, 1, su);
393 void draw_goldbox(SDL_Renderer *screen, Uint32 x, Uint32 y, Uint8 tile, int val) {
394 Uint32 w = 72;
395 Uint32 h = 14;
397 SDL_Rect border = { x, y, w, h };
398 SDL_Rect filler = { x+1, y+1, w-2, h-2 };
400 SDL_SetRenderDrawColor(screen, 0, 0, 0, 255); //black
401 SDL_RenderFillRect(screen, &filler);
403 SDL_SetRenderDrawColor(screen, brown.r, brown.g, brown.b, 255);
404 SDL_RenderDrawRect(screen, &border);
406 infont(large_font);
407 incolor(0x00FFFFFF, 0);
408 rprintf(screen, x+14, y+3, "% 7d", val);
410 draw_tile(screen, TILE_RES_Y, TILE_RES_X + tile, x+4, y+4);
413 void draw_buildset(SDL_Renderer *screen) {
415 int x = buildbox.x;
416 int y = buildbox.y;
418 int i;
419 for (i = 0; i < 2; i++) {
420 int hover = 0;
421 int pushin_x = 1;
422 int pushin_y = 1;
423 if (ui.setflag == i) {
424 hover = 2;
425 pushin_x = 0;
426 pushin_y = 0;
428 else {
429 if (ui.hover == overFlagButton && ui.hover_id == i) {
430 hover = 1;
434 draw_tile(screen, TILE_BTN_Y + 1, TILE_BTN_X + hover, x, y);
435 draw_tile(screen, TILE_FLAG_Y, TILE_FLAG_X + i, x - pushin_x, y - pushin_y);
437 x += 17;
438 if (x >= buildbox.x + buildbox.w - TILE_W/2) {
439 x = buildbox.x;
440 y += 17;
443 for (i = 0; i < HMENU_ITEMS; i++) {
445 house_p *m = &bhouses[i];
447 int hover = 0;
448 int pushin_x = 1;
449 int pushin_y = 1;
450 if (ui.builder == i) {
451 hover = 2;
452 pushin_x = 0;
453 pushin_y = 0;
455 else {
456 if (ui.hover == overBuildButton && ui.hover_id == i) {
457 hover = 1;
461 draw_tile(screen, TILE_BTN_Y + 1, TILE_BTN_X + hover, x, y);
462 draw_tile(screen, 0, m->icon + 1, x - pushin_x, y - pushin_y);
464 x += 17;
465 if (x >= buildbox.x + buildbox.w - TILE_W/2) {
466 x = buildbox.x;
467 y += 17;
472 void draw_minimap(SDL_Renderer *screen) {
473 Uint32 w = minimap.w;
474 Uint32 h = minimap.h;
476 Uint32 x = minimap.x;
477 Uint32 y = minimap.y;
479 // draw_blackbox(screen, x, y, w, h);
481 x += 1;
482 y += 1;
483 w -= 2;
484 h -= 2;
486 SDL_Rect dem = { x, y, w, h };
487 SDL_SetRenderDrawColor(screen, 0x11, 0x33, 0x11, 255);
488 SDL_RenderFillRect(screen, &dem);
490 int zY = h / level_h;
491 int zX = w / level_w;
493 int rw = level_w * zX;
494 int rh = level_h * zY;
496 int offX = w % level_w / 2;
497 int offY = h % level_h / 2;
499 x += offX;
500 y += offY;
502 int i;
503 for (i = 0; i < num_units; i++) {
504 unit_t *u = &units[i];
505 unit_p *proto = &bunits[u->tile];
507 SDL_Color *color;
509 color = &factions[u->faction].color;
511 if (ui.unit == i) {
512 color = &white;
514 SDL_Rect trg = { x + u->x * zX, y + (u->y-(proto->h-1)) * zY, proto->w * zX, proto->h * zY };
515 SDL_SetRenderDrawColor(screen, color->r, color->g, color->b, 255);
516 SDL_RenderFillRect(screen, &trg);
518 for (i = 0; i < num_houses; i++) {
519 house_t *h = &houses[i];
521 SDL_Color color;
522 color.a = 255;
523 color.r = 0; color.g = 0; color.b = 0xff;
524 if (ui.house == i) {
525 color.r = 0xff; color.g = 0xff; color.b = 0xff;
527 SDL_Rect trg = { x + h->x * zX, y + (h->y) * zY, h->w * zX, h->h * zY };
528 SDL_SetRenderDrawColor(screen, color.r, color.g, color.b, color.a);
529 SDL_RenderFillRect(screen, &trg);
531 int j;
532 for (j = 0; j < LEVEL_H; j++) {
533 for (i = 0; i < LEVEL_W; i++) {
534 if (fog[j][i]) {
535 SDL_Rect trg = { x + i * zX, y + j * zY, zX, zY };
536 SDL_SetRenderDrawColor(screen, 0,0,0, 255);
537 SDL_RenderFillRect(screen, &trg);
542 int vx = (x) + ui.vx / (TILE_W / zX);
543 int vy = (y) + ui.vy / (TILE_H / zY);
545 int vw = rw / ((float)level_w * TILE_W / (game_map.w - 1)) + 1;
546 int vh = rh / ((float)level_h * TILE_H / (game_map.h - 1)) + 1;
548 //SDL_Rect vport = { vx, vy, vw, vh }; // Most accurate
549 //SDL_Rect vport = { vx - offX, vy - offY, vw + offX * 2, vh + offY * 2 }; // Prettiest
550 SDL_Rect vport = { vx - 1, vy - 1, vw + 2, vh + 2 }; // Middle ground
552 MY_LineRect(screen, &vport, &white);
554 MY_LineRect(screen, &minimap, &brown);
558 void draw_unitname(SDL_Renderer *screen, unit_t *u, Uint32 y, Uint8 offset, Uint16 xoffset) {
559 unit_p *p = &bunits[u->tile];
560 Uint32 x = ui.log_width - PANE_WIDTH + xoffset;
562 //draw_blackbox(screen, x, y+2, w, h);
564 /* :( draw face in bad way */
565 if (!u->tile) draw_tile(screen, 0, 0, x, y);
566 else
567 draw_visual(screen, u->axis_refs, &p->face, x, y - (p->h-1)*TILE_H);
569 incolor1(&bunits[u->tile].color);
570 incolor(0x00ffffff, 0);
571 inprint(screen, u->name, x + 17, y + offset);
572 //inprint(screen, bunits[u->tile].title, x + 17, y+8+3);
575 void draw_progbar(SDL_Renderer *renderer, int val, int max, const char *buf, Uint32 x, Uint32 y, SDL_Color *colors[3]) {
577 SDL_Rect dest = { x, y, 96, 9 };
579 if (val < 0) val = 0;
581 int centerX = 0;
582 char buf2[80];
583 sprintf(buf2, buf, val, max);
584 centerX = (dest.w - strlen(buf2) * 6) / 2;
586 MY_LineRect(renderer, &dest, colors[0]);
588 dest.x += 1;
589 dest.y += 1;
590 dest.w -= 2;
591 dest.h -= 2;
593 int prop = val * 100 / max;
594 int pix_horz = dest.w * prop / 100;
596 SDL_AlphaFill(renderer, dest.x, dest.y, pix_horz, dest.h, colors[1]);
598 infont(small_font);
599 incolor1(colors[2]);
600 rprintf(renderer, x + centerX, y + 1, buf, val, max);
601 //rprintf(renderer, x, y + 1, buf, val, max);
605 void draw_pinbox(SDL_Renderer *screen) {
607 Uint32 x = pinbox.x;
608 Uint32 y = pinbox.y;
610 SDL_Rect pinbtn = { 0, 0, 16, 16 };
612 int i, highlight_pin;
613 for (i = 0; i < num_units; i++) {
614 unit_t *u = &units[i];
615 if (u->tile && u->pin) {
617 /* Draw name */
618 draw_unitname(screen, u, y, 6, 0);
620 /* Draw pin */
621 pinbtn.x = x + 120;
622 pinbtn.y = y + 4;
624 highlight_pin = 0;
625 if (ui.hover == overListPin && ui.hover_id == i) highlight_pin = 1;
627 draw_tile(screen, TILE_UICO_Y, TILE_UICO_X + 5 - highlight_pin, pinbtn.x, pinbtn.y);
629 y += 16;
635 void draw_flagbox(SDL_Renderer *renderer) {
637 const char flag_names[2][80] = {
638 "Explore Flag",
639 "Wanted Flag",
642 Uint32 w = selbox.w;
643 Uint32 h = selbox.h;
645 Uint32 x = selbox.x;
646 Uint32 y = selbox.y;
648 draw_blackbox(renderer, x, y, w, h);
650 x += BOX_PADDING;
651 y += BOX_PADDING;
652 w -= BOX_PADDING * 2;
653 h -= BOX_PADDING * 2;
655 flag_t *f = &your->flags[ui.flag];
657 draw_tile(renderer, TILE_FLAG_Y, TILE_FLAG_X + f->type, x, y); /* flag icon */
658 y += 3; /* small offset after icon */
660 incolor(0x00FFFFFF, 0);
661 infont(large_font);
662 inprint(renderer, flag_names[f->type], x + 17, y);
663 y += 8;
665 y += 16;
666 x += 16;
667 draw_goldbox(renderer, x, y, 1, f->reward);
669 int hl = 0;
671 if (ui.hover == overFlagPlus) hl = 1 + ui.pushing;
673 x = plusbtn.x;
674 y = plusbtn.y;
676 draw_tile(renderer, TILE_BTN_Y+1, TILE_BTN_X + hl, x, y);
678 draw_tile(renderer, TILE_FLAG_Y, TILE_FLAG_X+3, x, y);
682 void draw_housebox_visitors(SDL_Renderer *screen, house_t *h, Uint32 x, Uint32 y) {
683 /* visitors */
684 int i, j = 0;
685 for (i = 0; i < num_units; i++) {
686 unit_t *u = &units[i];
687 if (u->visiting != h) continue;
689 infont(mid_font);
690 draw_unitname(screen, u, y, 2, 0);
692 incolor(0x00999999, 0);
693 infont(small_font);
694 rprintf(screen, x + 17, y + 8 + 2, "PROG: %d (%d gold)", u->progress, u->carry_gold);
696 j++;
697 y += 16;
701 void draw_housetabs(SDL_Renderer *renderer) {
703 Uint32 x = tabicon.x;
704 Uint32 y = tabicon.y;
706 Uint32 color = 0xCCCCCC;
708 int i;
709 for (i = 0; i < MAX_HOUSETABS; i++) {
711 color = 0xCCCCCC;
712 if (i == ui.housetab) color = 0xFFFFFF;
713 else if (ui.hover == overUnitTab && i == ui.hover_id) color = 0xEEEEEE;
715 incolor(color, 0);
716 inprint(renderer, housetabs_names[i], x, y);
718 x += tabicon.w;
719 if (x + tabicon.w >= ui.log_width) {
720 x = tabicon.x;
721 y += tabicon.h;
726 void draw_housebox(SDL_Renderer *screen) {
728 Uint32 w = selbox.w;
729 Uint32 ph = selbox.h;
731 Uint32 x = selbox.x;
732 Uint32 y = selbox.y;
734 draw_blackbox(screen, x, y, w, ph);
736 x += BOX_PADDING;
737 y += BOX_PADDING;
738 //w -= BOX_PADDING * 2;
739 //h -= BOX_PADDING * 2;
741 house_t *h = &houses[ui.house];
742 house_p *p = &bhouses[h->tile];
744 draw_tile(screen, 0, h->tile+1, x, y); /* house icon */
745 y += 3; /* small offset after icon */
747 incolor(0x00FFFFFF, 0);
749 infont(large_font);
750 inprint(screen, "Something", x + 17, y);
751 y += 8;
753 infont(large_font);
754 inprint(screen, p->title, x + 17, y);
755 y += 8;
757 infont(small_font);
758 rprintf(screen, x + 17, y, "HP: %d/%d", h->hp, h->max_hp);
759 y += 8;
761 /* Draw flag */
762 if (h->flag_id[ui.faction] != -1)
763 draw_tile(screen, TILE_FLAG_Y, TILE_FLAG_X + 1, flagicon.x, flagicon.y); /* flag icon */
765 draw_housetabs(screen);
767 /* visitors */
768 draw_housebox_visitors(screen, h, x, y);
771 void draw_unitbox_tab1(SDL_Renderer *screen, unit_t *u, Uint32 x, Uint32 y) {
773 int icon;
775 unit_p *p = &bunits[u->tile];
777 Uint32 color;
779 infont(large_font);
781 icon = unit_icon(u);
783 /* Print state (and draw icon) */
784 draw_tile(screen, TILE_UICO_Y, TILE_UICO_X + icon, x + 26, y + 106);
785 incolor(state_colors[icon], 0);
786 inprint(screen, state_names[icon], x + 16 + 17, y+106);
787 incolor(0xFFFFFFFF, 0);
789 /* Draw stats */
790 int i;
791 int hover;
792 for (i = 0; i < MAX_STAT; i++) {
793 hover = 0;
794 y += 14;
795 if (ui.stat == i) hover = 2;
796 else {
797 if (ui.hover == overUnitStat && ui.hover_id == i) {
798 hover = 1;
801 if (u->link != NULL) hover = -1;
802 //if (u->link && u->link_stat == i) hover = 0;
803 draw_tile(screen, TILE_BTN_Y, TILE_BTN_X + hover, x , y);
805 draw_tile(screen, TILE_STAT_Y, TILE_STAT_X + i, x , y);
806 incolor(0xFFFFFF,0);
807 rprintf(screen, x + 17, y + 3, "%02d", u->base_stat[i]);
809 Uint32 col;
810 if (u->calc_stat[i] > u->base_stat[i]) col = 0x00FF00;
811 else if (u->calc_stat[i] < u->base_stat[i]) col = 0xFF0000;
812 else col = 0xFFFFFF;
814 incolor(col,0);
815 rprintf(screen, x + 17*2 + 7, y + 3, "%02d", u->calc_stat[i]);
818 /* Draw skills */
819 y -= 14 * MAX_STAT;
820 x += 64;
821 for (i = 0; i < MAX_STAT; i++) {
822 int tile = i;
823 hover = 0;
824 y += 14;
825 int hx = 0;
826 int hy = 0;
827 if (ui.btn == i) { hover = 2; hx = 1; hy = 1; }
828 else {
829 if (ui.hover == overUnitSkill && ui.hover_id == i) {
830 hover = 1;
834 /* Hack -- perception can take 2 different icons */
835 if (i == 4 && p->perc != Smell) tile += 1;
837 /* Hack -- offset "speech" icon by 1 */
838 if (i == 5) tile += 1;
840 //if (u->tile != U_PEASANT) hover = -1;
841 draw_tile(screen, TILE_BTN_Y, TILE_BTN_X + hover, x, y);
843 draw_tile(screen, TILE_STAT_Y + 3, TILE_STAT_X + tile, x+hx, y+hy);
845 incolor(0xFFFFFF, 0);
846 rprintf(screen, x + 17, y + 3, "%02d", u->base_skill[i]);
848 if (u->calc_skill[i] > u->base_skill[i]) color = 0x00FF00;
849 else if (u->calc_skill[i] < u->base_skill[i]) color = 0xFF0000;
850 else color = 0xFFFFFF;
852 incolor(color, 0);
853 rprintf(screen, x + 17*2 + 7, y + 3, "%02d", u->calc_skill[i]);
858 void draw_unitbox_tab2(SDL_Renderer *renderer, unit_t *u, Uint32 x, Uint32 y) {
859 unit_p *p = &bunits[u->tile];
861 /* Random info I */
862 infont(large_font);
863 incolor1(&white);
864 rprintf(renderer, x, y + 16, "Level: %02d", u->level);
865 /* exp */
866 SDL_Color *exp_colors[3] = { &darkviolet, &violet, &darkviolet };
867 draw_progbar(renderer, u->exp, 1000, "Exp: %d/%d", x + 17 - 4, y + 16 + 8, exp_colors);
869 /* Random info II */
870 infont(mid_font);
871 rprintf(renderer, x, y + 32, "Class: %s", p->title);
873 /* Random info III */
874 infont(small_font);
875 incolor1(&white);
876 rprintf(renderer, x, y + 64 + 8 * 0, "Fame: %d", u->fame);
877 rprintf(renderer, x, y + 64 + 8 * 1, "Happiness: %d%", u->happiness);
878 rprintf(renderer, x, y + 64 + 8 * 2, "Wealth: %d", u->gold);
879 SDL_Color *nrg_colors[3] = { &brown, &yellow, &brown };
880 draw_progbar(renderer, u->energy, (u->calc_stat[S_DEX]+1) * 10, "Energy: %d", x, y + 64 + 8 * 3, nrg_colors);
883 void draw_unitbox_tab_runes(SDL_Renderer *screen, unit_t *u, Uint32 x, Uint32 y) {
885 int icon;
886 unit_p *p = &bunits[u->tile];
888 icon = unit_icon(u);
890 infont(large_font);
892 /* Print state (and draw icon) */
893 draw_tile(screen, TILE_UICO_Y, TILE_UICO_X + icon, x + 26, y + 106);
894 incolor(state_colors[icon], 0);
895 inprint(screen, state_names[icon], x + 16 + 17, y+106);
896 incolor(0xFFFFFFFF, 0);
898 /* Draw stats */
899 int i;
900 int hover;
901 Uint32 col;
902 char *s;
903 int stat = 0;
904 for (i = 0; i < MAX_STAT; i++) {
905 hover = 0;
906 y += 14;
907 if (ui.stat == i) hover = 2;
908 else {
909 if (ui.hover == overUnitStat && ui.hover_id == i) {
910 hover = 1;
913 if (u->link != NULL) hover = -1;
914 //if (u->link && u->link_stat == i) hover = 0;
915 draw_tile(screen, TILE_BTN_Y, TILE_BTN_X + hover, x , y);
917 draw_tile(screen, TILE_STAT_Y, TILE_STAT_X + i, x , y);
919 if (u->link == NULL || u->link_stat != i) {
920 if (u->ref_count[i] == 0) icon = 0;
921 if (u->ref_count[i] > 0) icon = 3;
922 } else {
923 if (u->ref_count[i] == 0) icon = 1;
924 if (u->ref_count[i] > 0) icon = 2;
927 if (icon == 3) { col = 0x00FF00; s = "<"; stat = u->calc_stat[i]; }
928 else if (icon == 1) { col = 0xFF0000; s= ">"; stat = u->base_stat[i]; }
929 else if (icon == 2) { col = 0x0000FF; s= ">"; stat = u->rune_stat[i]; }
930 else { col = 0xFFFFFF; s = ""; stat = 0; }
932 infont(large_font);
933 incolor(col,0);
934 rprintf(screen, x + 17, y + 3, "%02d%s", stat, s);
936 /* Print relation */
937 infont(mid_font);
938 if (u->link && u->link_stat == i)
939 draw_unitname(screen, u->link, y - 4, 7, 48);
940 else if (u->ref_count[i]) {
941 incolor(col,0);
942 rprintf(screen, x + 48, y + 3, "%d dvt", u->ref_count[i]);
948 void draw_unitbox_tab_ai(SDL_Renderer *renderer, unit_t *u, Uint32 x, Uint32 y) {
949 unit_p *p = &bunits[u->tile];
951 infont(large_font);
952 incolor1(&white);
953 rprintf(renderer, x, y + 16 + 8 * 0, "Desire: %s", desire_names[u->top_desire]);
954 rprintf(renderer, x, y + 16 + 8 * 1, "Method: %s", desire_names[u->top_method]);
956 rprintf(renderer, x, y + 16 + 8 * 2, "Strategy: %s", start_names[u->strategy]);
957 rprintf(renderer, x, y + 16 + 8 * 3, "Tactic: %s", tact_names[u->tactic]);
959 infont(mid_font);
960 incolor1(&white);
963 rprintf(renderer, x, y + 16 + 8 * 5, "Target:");
965 switch (u->target_type) {
966 case TARGET_TILE:
967 rprintf(renderer, x, y + 16 + 8 * 6, "Some Tile");
968 break;
969 case TARGET_FLAG:
970 rprintf(renderer, x, y + 16 + 8 * 6, "Some Flag");
971 break;
972 case TARGET_HOUSE:
973 rprintf(renderer, x, y + 16 + 8 * 6, "%s: %s", bhouses[houses[u->target_id].tile].title, houses[u->target_id].title);
974 break;
975 case TARGET_UNIT:
976 rprintf(renderer, x, y + 16 + 8 * 5, "Target: Unit %d", u->target_id);
977 draw_unitname(renderer, &units[u->target_id], y + 16 + 8 * 6 - 4, 6, 16);
978 break;
979 case TARGET_NONE:
980 default:
981 rprintf(renderer, x, y + 16 + 8 * 5, "Target: None");
982 break;
985 int i, steps = 0;
986 for (i = 0; i < 16; i++) {
987 if (u->path[i] == -1) break;
988 steps++;
991 rprintf(renderer, x, y + 16 + 8 * 8, "Steps: %d", steps);
995 void draw_unittabs(SDL_Renderer *renderer) {
997 Uint32 x = tabicon.x;
998 Uint32 y = tabicon.y;
1000 Uint32 color = 0xCCCCCC;
1002 int i;
1003 for (i = 0; i < MAX_UNITTABS; i++) {
1005 color = 0xCCCCCC;
1006 if (i == ui.unittab) color = 0xFFFFFF;
1007 else if (ui.hover == overUnitTab && i == ui.hover_id) color = 0xEEEEEE;
1009 incolor(color, 0);
1010 inprint(renderer, unittabs_names[i], x, y);
1012 x += tabicon.w;
1013 if (x + tabicon.w >= ui.log_width) {
1014 x = tabicon.x;
1015 y += tabicon.h;
1020 void draw_unitbox(SDL_Renderer *screen) {
1022 Uint32 w = selbox.w;
1023 Uint32 h = selbox.h;
1025 Uint32 x = selbox.x;
1026 Uint32 y = selbox.y;
1028 draw_blackbox(screen, x, y, w, h);
1030 x += BOX_PADDING;
1031 y += BOX_PADDING;
1032 w -= BOX_PADDING * 2;
1033 h -= BOX_PADDING * 2;
1035 unit_t *u = &units[ui.unit];
1036 unit_p *p = &bunits[u->tile];
1038 /* :( draw face in bad way */
1039 if (!u->tile) draw_tile(screen, 0, 0, x, y);
1040 else
1041 draw_visual(screen, u->axis_refs, &p->face, x, y - (p->h-1)*TILE_H);
1043 /* Print name */
1044 infont(large_font);
1045 inprint(screen, u->name, x + 17, y + 3);
1046 incolor1(&bunits[u->tile].color);
1047 inprint(screen, bunits[u->tile].title, x + 17, y+8+3);
1049 /* Draw pin */
1050 draw_tile(screen, TILE_UICO_Y, TILE_UICO_X + 4 + u->pin, unitpin.x, unitpin.y);
1052 /* Draw flag */
1053 if (u->flag_id[ui.faction] != -1)
1054 draw_tile(screen, TILE_FLAG_Y, TILE_FLAG_X + 1, flagicon.x, flagicon.y); /* flag icon */
1056 /* Draw health */
1057 SDL_Color *hp_colors[3] = { &darkred, &red, &darkred };
1058 draw_progbar(screen, (u->max_hp - u->dmg), u->max_hp, "HP: %d/%d", x + 17, y + 8 + 3, hp_colors);
1060 x += BOX_PADDING;
1061 y += BOX_PADDING;
1062 w -= BOX_PADDING * 2;
1063 h -= BOX_PADDING * 2;
1065 y += BOX_PADDING;
1067 /* Draw tabs */
1068 draw_unittabs(screen);
1070 /* Draw contents */
1071 switch (ui.unittab) {
1072 case -1:
1073 case 0:
1074 draw_unitbox_tab1(screen, u, x, y);
1075 break;
1076 case 1:
1077 draw_unitbox_tab2(screen, u, x, y);
1078 break;
1079 case 4:
1080 draw_unitbox_tab_runes(screen, u, x, y);
1081 break;
1082 case 5:
1083 draw_unitbox_tab_ai(screen, u, x, y);
1084 break;
1085 default:
1086 break;
1091 void draw_hintbox(SDL_Renderer *screen) {
1093 Uint32 w = PANE_WIDTH;
1094 Uint32 h = 128;
1096 Uint32 x = ui.log_width - w;
1097 Uint32 y = hintbox.y;
1099 draw_blackbox(screen, x, y, w, h);
1101 x += BOX_PADDING;
1102 y += BOX_PADDING;
1103 w -= BOX_PADDING * 2;
1104 h -= BOX_PADDING * 2;
1106 /* Hack -- minus 1 pixel */
1107 x -= 1;
1109 if (ui.hintType == 0) { // Building
1111 house_p *h = &bhouses[ui.hint];
1113 infont(large_font);
1114 incolor(0xffffff, 0);
1115 inprint(screen, h->title, x, y);
1119 if (ui.hintType == 1) { // Stat
1121 infont(large_font);
1122 incolor(0xffffff, 0);
1123 inprint(screen, stat_long_names[ui.hint], x, y);
1125 y += 32;
1126 infont(small_font);
1127 incolor(0x999999, 0);
1128 inprint(screen, stat_descriptions[ui.hint], x, y);
1130 y += 32;
1131 infont(mid_font);
1132 incolor(0xffffff, 0);
1133 rprintf(screen, x, y, "1 forcible (100 blood ore)");
1136 /* TODO: remove this */
1137 infont(large_font);
1140 void draw_forcible(SDL_Renderer *screen) {
1141 draw_tile(screen, 22, 4, ui.x, ui.y);
1143 unit_t *u = &units[ui.unit];
1144 Uint32 x = u->x * TILE_W + u->ox - ui.vx + game_map.x;
1145 Uint32 y = u->y * TILE_H + u->oy - ui.vy + game_map.y;
1147 MY_DrawSine(screen, ui.x, ui.y, x + TILE_W/2, y + TILE_H/4, reds);
1149 if (ui.hover == overUnit) {
1150 unit_t *u2 = &units[ui.hover_id];
1151 Uint8 ok = 1;
1152 if (u2 == u) ok = 0;
1153 SDL_Color color = { 0, 0, 0, 0x33 };
1154 if (ok) color.g = 0xFF;
1155 else color.r = 0xFF;
1156 SDL_AlphaFill(screen,
1157 u2->x * TILE_W + u2->ox - ui.vx + game_map.x,
1158 u2->y * TILE_H + u2->oy - ui.vy + game_map.y, TILE_W, TILE_H, &color);
1162 void draw_builder(SDL_Renderer *screen) {
1164 SDL_Color color = { 0, 0, 0, 0x33 };
1165 house_p *h = &bhouses[ui.builder];
1167 /* For mouse-less devices, show the whole grid */
1168 if (ui.no_mouse) {
1169 //int i, j;
1171 return;
1174 if (ui.hover_xcollide) color.r = 0xFF; /* colliding, make it red */
1175 else color.g = 0xFF; /* not colliding, make it green */
1177 SDL_AlphaFill(screen,
1178 ui.hover_tx * TILE_W - ui.vx + game_map.x,
1179 ui.hover_ty * TILE_H - ui.vy + game_map.y,
1180 h->w * TILE_W, h->h * TILE_H, &color);
1183 void draw_setflag(SDL_Renderer *renderer) {
1185 SDL_Color color = { 0, 0, 0, 0x33 };
1187 if (ui.hover_xcollide != ui.setflag || ui.hover == overFlag)
1188 color.r = 0xFF; /* make it red */
1189 else
1190 color.g = 0xFF; /* make it green */
1192 SDL_AlphaFill(renderer,
1193 ui.hover_tx * TILE_W - ui.vx + game_map.x,
1194 ui.hover_ty * TILE_H - ui.vy + game_map.y,
1195 1 * TILE_W, 1 * TILE_H, &color);
1198 // draw_tile(renderer, TILE_FLAG_Y, TILE_FLAG_X + ui.setflag, ui.hover_tx, ui.hover_ty);
1199 draw_tile(renderer, TILE_FLAG_Y, TILE_FLAG_X + ui.setflag,
1200 ui.hover_tx * TILE_W - ui.vx + game_map.x,
1201 ui.hover_ty * TILE_H - ui.vy + game_map.y
1206 void draw_selector(SDL_Renderer *screen, Uint8 top, Uint32 x, Uint32 y, Uint8 w, Uint8 h) {
1207 if (w > 2) {
1208 if (top) draw_stile(screen, TILE_SEL_Y, TILE_SEL_X + 2, x, y + (h-1)*TILE_H - (h-1)*TILE_H, 2, 1, w, h);
1209 else draw_stile(screen, TILE_SEL_Y, TILE_SEL_X + 4, x, y + (h-1)*TILE_H - (h-1)*TILE_H, 2, 1, w, h);
1211 else if (w == 2) {
1212 if (top) draw_ctile(screen, TILE_SEL_Y, TILE_SEL_X + 2, x, y + (h-1)*TILE_H, 2, 1);
1213 else draw_ctile(screen, TILE_SEL_Y, TILE_SEL_X + 4, x, y + (h-1)*TILE_H, 2, 1);
1214 } else {
1215 if (top) draw_tile(screen, TILE_SEL_Y, TILE_SEL_X, x, y + (h-1)*TILE_H);
1216 else draw_tile(screen, TILE_SEL_Y, TILE_SEL_X + 1, x, y + (h-1)*TILE_H);
1220 void draw_unbuilt_house(SDL_Renderer *screen, house_t *h, int sel) {
1222 Uint32 x = h->x * TILE_W - ui.vx + game_map.x;
1223 Uint32 y = h->y * TILE_H - ui.vy + game_map.y;
1224 Uint32 pix_w = h->w * TILE_W;
1225 Uint32 pix_h = h->h * TILE_H;
1226 Uint8 tile = h->tile;
1228 house_p *bp = &bhouses[tile];
1230 if (sel) draw_selector(screen, 1, x, y, h->w, h->h);
1232 draw_btile(screen,
1233 bp->body.plane.y + bp->unbuilt.y,
1234 bp->body.plane.x + bp->unbuilt.x,
1235 x, y, h->w, h->h);
1237 SDL_Rect built;
1239 built.x = bp->body.plane.x + bp->body.axis_offset[0].x;
1240 built.y = bp->body.plane.y + bp->body.axis_offset[0].y;
1242 int prop = h->hp * 100 / h->max_hp;
1243 int pix_vert = pix_w * prop / 100;
1244 int pix_horz = pix_h * prop / 100;
1245 //printf("Percent built: %d (in pix: %d)\n", prop, pix);
1247 SDL_Rect src = { built.x + (pix_w - pix_vert), built.y, pix_vert, TILE_H * h->h };
1248 SDL_Rect dst = { x + (pix_w - pix_vert), y, pix_vert, TILE_H * h->h };
1249 SDL_RenderCopy(screen, tiles, &src, &dst);
1252 SDL_Rect src = { built.x, built.y + (pix_h - pix_horz), TILE_W * h->w, pix_horz };
1253 SDL_Rect dst = { x, y + (pix_h - pix_horz), TILE_W * h->w, pix_horz };
1254 SDL_RenderCopy(screen, tiles, &src, &dst);
1257 if (sel) draw_selector(screen, 0, x, y, h->w, h->h);
1260 inline void draw_house(SDL_Renderer *screen, house_t *h, Uint32 x, Uint32 y) {
1261 house_p *p = &bhouses[h->tile];
1262 draw_visual(screen, h->axis_refs, &p->body, x, y);
1265 void draw_houses(SDL_Renderer *screen) {
1266 int i;
1267 for (i = 0; i < num_houses; i++) {
1268 house_t *h = &houses[i];
1269 //if (h->tile == 0) continue;
1270 Uint32 x = h->x * TILE_W - ui.vx + game_map.x;
1271 Uint32 y = h->y * TILE_H - ui.vy + game_map.y;
1273 if (h->built == 0) { draw_unbuilt_house(screen, h, (ui.house==i)); continue; }
1275 house_p *bp = &bhouses[h->tile];
1277 if (ui.house == i) draw_selector(screen, 1, x, y, h->w, h->h);
1279 draw_visual(screen, h->axis_refs, &bp->body, x, y);
1281 if (ui.house == i) draw_selector(screen, 0, x, y, h->w, h->h);
1285 inline void draw_unit(SDL_Renderer *screen, unit_t *u, Uint32 x, Uint32 y) {
1286 unit_p *p = &bunits[u->tile];
1287 draw_visual(screen, u->axis_refs, &p->body, x, y);
1290 void draw_units(SDL_Renderer *screen) {
1291 int i;
1292 for (i = 0; i < num_units; i++) {
1293 unit_t *u = &units[i];
1294 unit_p *proto = &bunits[u->tile];
1296 Uint32 x = u->x * TILE_W + u->ox - ui.vx + game_map.x;
1297 Uint32 y = u->y * TILE_H + u->oy - ui.vy + game_map.y;
1299 if (proto->h <= 0) {
1300 fprintf(stderr, "Very bad unit (%p)'%s' -- [%d,%d -- %d,%d]!\n", proto, proto->id,
1301 proto->body.plane.x, proto->body.plane.y, proto->w, proto->h);
1302 exit(-1);
1305 y -= TILE_H * (proto->h - 1);
1307 if (u->visiting) continue;
1309 if (ui.unit == i) draw_selector(screen, 1, x, y, proto->w, proto->h);
1311 //draw_unit(screen, u, x, y);
1312 draw_visual(screen, u->axis_refs, &proto->body, x, y);
1314 if (ui.unit == i) draw_selector(screen, 0, x, y, proto->w, proto->h);
1316 draw_tile(screen, TILE_UICO_Y, TILE_UICO_X + unit_icon(u), x, y);
1318 if (u->baloon)
1319 draw_tile(screen, TILE_BALOON_Y, TILE_BALOON_X + u->baloon, x - 7, y - 7);
1324 void draw_flags(SDL_Renderer *renderer) {
1325 int i;
1326 for (i = 0; i < your->num_flags; i++) {
1327 flag_t *f = &your->flags[i];
1329 Uint32 x = f->x * TILE_W - ui.vx + game_map.x;
1330 Uint32 y = f->y * TILE_H - ui.vy + game_map.y;
1332 Uint8 small = 0;
1334 if (f->type == 1) {
1336 if (f->house) {
1338 house_t *h = f->house;
1339 x = h->x * TILE_W - ui.vx + game_map.x;
1340 y = h->y * TILE_H - ui.vy + game_map.y;
1342 f->x = h->x;
1343 f->y = h->y;
1345 if (f->unit) {
1347 unit_t *u = f->unit;
1348 unit_p *p = &bunits[u->tile];
1349 if (u->visiting) continue;
1350 x = u->x * TILE_W + u->ox - ui.vx + game_map.x;
1351 y = u->y * TILE_H + u->oy - ui.vy + game_map.y;
1353 f->x = u->x;
1354 f->y = u->y - (p->h-1);
1356 y -= (p->h-1) * TILE_H;
1358 small = 1;
1364 if (ui.flag == i) draw_selector(renderer, 1, x, y, 1, 1);
1366 draw_tile(renderer, TILE_FLAG_Y, TILE_FLAG_X + f->type + small, x, y);
1368 if (ui.flag == i) draw_selector(renderer, 0, x, y, 1, 1);
1375 int foglet(int x, int y) {
1376 int mask[3][3] = { { 1 } };
1377 if (y > 0) {
1378 if (x > 0) mask[0][0] = fog[y - 1][x - 1];
1379 mask[0][1] = fog[y - 1][x];
1380 if (x < LEVEL_W) mask[0][2] = fog[y - 1][x + 1];
1382 if (y < LEVEL_H) {
1383 if (x > 0) mask[2][0] = fog[y + 1][x - 1];
1384 mask[2][1] = fog[y + 1][x];
1385 if (x < LEVEL_W) mask[2][2] = fog[y + 1][x + 1];
1387 if (x > 0) {
1388 mask[1][0] = fog[y][x - 1];
1390 if (x < LEVEL_W) {
1391 mask[1][2] = fog[y][x + 1];
1393 if (fog[y][x] == 0) return 0;
1395 if (!fog[y-1][x] && !fog[y+1][x-1] && !fog[y+1][x+1]) return 0;
1396 if (!fog[y][x-1] && !fog[y-1][x+1] && !fog[y+1][x+1]) return 0;
1397 if (!fog[y][x+1] && !fog[y-1][x-1] && !fog[y+1][x-1]) return 0;
1398 if (!fog[y+1][x] && !fog[y-1][x-1] && !fog[y-1][x+1]) return 0;
1399 if (!fog[y-1][x] && !fog[y][x-1] && !fog[y+1][x+1]) return 0;
1400 if (!fog[y+1][x] && !fog[y][x+1] && !fog[y-1][x-1]) return 0;
1401 if (!fog[y+1][x] && !fog[y][x-1] && !fog[y-1][x+1]) return 0;
1402 if (!fog[y-1][x] && !fog[y][x+1] && !fog[y+1][x-1]) return 0;
1404 if (!fog[y+1][x-1] && !fog[y-1][x+1] && !fog[y+1][x+1] && fog[y][x-1] && fog[y-1][x] ) return 11;
1405 if (!fog[y+1][x-1] && !fog[y][x+1] && fog[y][x-1] && fog[y-1][x] ) return 11;
1406 if (!fog[y-1][x+1] && !fog[y+1][x] && fog[y][x-1] && fog[y-1][x] ) return 11;
1407 if (!fog[y+1][x] && !fog[y][x+1] && fog[y][x-1] && fog[y-1][x] ) return 11;
1409 if (!fog[y-1][x-1] && !fog[y+1][x-1] && !fog[y-1][x+1] && fog[y-1][x] && fog[y+1][x] ) return 19;
1410 if (!fog[y-1][x+1] && !fog[y][x-1] && fog[y][x+1] && fog[y+1][x] ) return 19;
1411 if (!fog[y+1][x-1] && !fog[y-1][x] && fog[y][x+1] && fog[y+1][x] ) return 19;
1412 if (!fog[y-1][x] && !fog[y][x-1] && fog[y][x+1] && fog[y+1][x] ) return 19;
1414 if (!fog[y-1][x-1] && !fog[y+1][x+1] && fog[y-1][x+1] && !fog[y+1][x] && fog[y][x+1] && fog[y-1][x] ) return 13;
1415 if (!fog[y-1][x-1] && !fog[y+1][x] && fog[y][x+1] && fog[y-1][x] ) return 13;
1416 if (!fog[y+1][x+1] && !fog[y][x-1] && fog[y][x+1] && fog[y-1][x] ) return 13;
1417 if (!fog[y][x-1] && !fog[y+1][x] && fog[y][x+1] && fog[y-1][x] ) return 13;
1419 if (!fog[y-1][x-1] && !fog[y+1][x+1] && !fog[y-1][x+1] && fog[y][x-1] && fog[y+1][x] ) return 17;
1420 if (!fog[y][x+1] && !fog[y-1][x] && fog[y][x-1] && fog[y+1][x] ) return 17;
1421 if (!fog[y-1][x-1] && !fog[y][x+1] && fog[y][x-1] && fog[y+1][x] ) return 17;
1422 if (!fog[y+1][x+1] && !fog[y-1][x] && fog[y][x-1] && fog[y+1][x] ) return 17;
1424 if (fog[y][x-1] == 0 && fog[y][x+1] == 0) return 0;
1425 if (fog[y-1][x] == 0 && fog[y+1][x] == 0) return 0;
1427 if (fog[y-1][x] && fog[y+1][x]) {
1428 if (!fog[y-1][x-1] && !fog[y+1][x+1] && fog[y-1][x+1]) return 14;
1429 if (!fog[y+1][x-1] && !fog[y-1][x+1] && fog[y+1][x+1]) return 16;
1432 if (fog[y - 1][x + 1] && fog[y][x - 1] && fog[y][x + 1] && !fog[y + 1][x - 1] && !fog[y + 1][x + 1]) return 2;
1433 if (fog[y + 1][x + 1] && fog[y][x - 1] && fog[y][x + 1] && !fog[y - 1][x - 1] && !fog[y - 1][x + 1]) return 8;
1434 if (fog[y - 1][x] && fog[y + 1][x] && !fog[y - 1][x + 1] && !fog[y + 1][x + 1]) return 4;
1435 if (fog[y - 1][x] && fog[y + 1][x] && !fog[y - 1][x - 1] && !fog[y + 1][x - 1]) return 6;
1437 if (fog[y][x + 1] && fog[y + 1][x] && !fog[y + 1][x + 1]) return 1;
1438 if (fog[y][x - 1] && fog[y + 1][x] && !fog[y + 1][x - 1]) return 3;
1439 if (fog[y][x + 1] && fog[y - 1][x] && !fog[y - 1][x + 1]) return 7;
1440 if (fog[y][x - 1] && fog[y - 1][x] && !fog[y - 1][x - 1]) return 9;
1442 if (!fog[y][x + 1]) return 4;
1443 if (!fog[y][x - 1]) return 6;
1444 if (!fog[y - 1][x]) return 8;
1445 if (!fog[y + 1][x]) return 2;
1447 return 5;
1449 void draw_scent(SDL_Renderer *screen) {
1451 int tx, ty;
1452 for (ty = 0; ty < LEVEL_H; ty++) {
1453 for (tx = 0; tx < LEVEL_W; tx++) {
1455 Uint32 x = tx * TILE_W - ui.vx + game_map.x;
1456 Uint32 y = ty * TILE_H - ui.vy + game_map.y;
1457 int n;
1458 SDL_Color color = { 0xff, 0xff, 0x00, 0x33 };
1459 color.b = scent_human[ty][tx]/10;
1461 for (n = 0; n < scent_human[ty][tx]/16; n++)
1463 SDL_AlphaFill(screen, x + rand()%TILE_W/4, y + rand()%TILE_H/4, TILE_W, TILE_H, &color);
1468 void draw_fog(SDL_Renderer *screen) {
1470 int tx, ty;
1471 Uint8 fols_x[20] = {-1, 0, 1, 2, 0, 1, 2, 0, 1, 2, 1, 0, 1, 2, 0, 1, 2, 0, 1, 2 };
1472 Uint8 fols_y[20] = { 0, 0, 0, 0, 1, 1, 1, 2, 2, 2, 1, 3, 3, 3, 4, 4, 4, 5, 5, 5 };
1474 for (ty = 0; ty < LEVEL_H; ty++) {
1475 for (tx = 0; tx < LEVEL_W; tx++) {
1477 Uint32 x = tx * TILE_W - ui.vx + game_map.x;
1478 Uint32 y = ty * TILE_H - ui.vy + game_map.y;
1480 Uint8 f = foglet(tx, ty);
1481 fog[ty][tx] = f;
1483 draw_tile(screen, TILE_FOG_Y + fols_y[f], TILE_FOG_X + fols_x[f], x, y);
1489 void draw_log(SDL_Renderer *renderer, log_t *log) {
1491 int i;
1493 Uint32 y = ui.log_height - 16;
1495 for (i = 0; i < 16; i++) {
1497 //incolor(log->color[i], 0);
1498 infont(mid_font);
1499 incolor(0xffffffff, 0);
1500 inprint(renderer, log->message[i], 0, y);
1502 y -= 16;
1505 infont(large_font);
1509 void draw_ui(SDL_Renderer *screen) {
1510 SDL_Rect src = { 0, 0, 640, 480 };
1511 SDL_Rect dst = { 0, 0, ui.log_width, ui.log_height };
1513 if (ui.draw_uibg)
1514 SDL_RenderCopy(screen, uibg, &src, &dst);
1516 draw_goldbox(screen, 2, 3, 0, your->ore);
1517 draw_goldbox(screen, 80, 3, 1, your->gold);
1519 draw_minimap(screen);
1521 if (ui.unit != -1) draw_unitbox(screen);
1522 else if (ui.house != -1) draw_housebox(screen);
1523 else if (ui.flag != -1) draw_flagbox(screen);
1524 else {
1525 draw_buildset(screen);
1526 draw_pinbox(screen);
1529 if (ui.hint != -1) draw_hintbox(screen);
1531 if (ui.draw_log) draw_log(screen, &gamelog);
1534 void draw_screen(SDL_Renderer *screen) {
1536 SDL_SetRenderDrawColor(screen, 0x11, 0x33, 0x11, 255);
1537 SDL_RenderClear(screen);
1539 draw_houses(screen);
1541 draw_units(screen);
1543 if (ui.draw_fog) draw_fog(screen);
1544 if (ui.draw_scent) draw_scent(screen);
1546 draw_flags(screen);
1548 draw_particles(screen, 100,100);
1550 if (ui.draw_overlays) draw_overlays(screen, ui.unit, 0, 0, NULL);
1552 if (ui.draw_path) draw_paths(screen, ui.unit, 0, 0);
1554 if (ui.draw_pools) draw_pools(screen);
1556 if (ui.setflag > -1) draw_setflag(screen);
1557 if (ui.builder > -1) draw_builder(screen);
1558 if (ui.stat > -1) draw_forcible(screen);
1560 draw_ui(screen);
1562 /* FPS: */
1563 infont(small_font);
1564 incolor(0xffffff, 0);
1565 rprintf(screen, ui.log_width - ui.log_width / 2, 4, "FPS: %d", ui.fps);