Add SDL2_mixer support.
[runemen.git] / src / draw.c
blob2d8a02aa0ce5cecd33137f882bccfe4bc2df2416
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};
22 SDL_Color magenta = { 0xFF, 0x00, 0xFF, 255};
23 SDL_Color darkmagenta = { 0x80,0, 0x80, 255};
25 SDL_Color reds[16];
27 Uint32 state_colors[4] = {
28 0xFFFFFF, 0xFF0000, 0x0000FF, 0x00FF00,
31 extern void SDL_ComputeGradient(SDL_Color *colors, int n, SDL_Color *start, SDL_Color *stop);
32 void prepare_colors() {
34 SDL_Color start = { 0xFF, 0x00, 0x00 };
35 SDL_Color end = { 0x66, 0x11, 0x11 };
37 SDL_ComputeGradient(reds, 16, &start, &end);
41 void MY_LineRect(SDL_Renderer *dst, SDL_Rect *dr, SDL_Color *color)
43 SDL_SetRenderDrawColor(dst, color->r, color->g, color->b, color->a);
44 SDL_RenderDrawRect(dst, dr);
47 void MY_PutPixel(SDL_Renderer *dest, Uint32 x, Sint32 y, SDL_Color *col)
49 SDL_SetRenderDrawColor(dest, col->r, col->g, col->b, col->a);
50 SDL_RenderDrawPoint(dest, x, y);
53 void MY_DrawVector(SDL_Renderer *surface, Sint32 x, Sint32 y, float a, int len, SDL_Color *color)
55 int i;
56 SDL_Rect *clip = NULL;//-&surface->clip_rect;
57 float c = cosf(a * M_PI / 180);
58 float s = sinf(a * M_PI / 180);
59 for (i = 0; i < len; i++)
61 int nx = (int)(x + i * c);
62 int ny = (int)(y + i * s);
64 if (!clip || SDL_InBounds(nx, ny, clip))
66 MY_PutPixel(surface, nx, ny, color);
71 void MY_DrawLine(SDL_Renderer *dst, Sint32 x1, Sint32 y1, Sint32 x2, Sint32 y2, SDL_Color *color)
73 Sint32 dx = x2 - x1;
74 Sint32 dy = y2 - y1;
75 double angle = atan2(dy, dx) * 180 / M_PI;
76 double distance = sqrt( (dx*dx) + (dy*dy) );
78 SDL_SetRenderDrawColor(dst, color->r, color->g, color->b, color->a);
79 //SDL_RenderDrawLine(dst, x1, y1, x2, y2);
80 MY_DrawVector(dst, x1, y1, (float)angle, (int)distance, color);
83 void SDL_AlphaFill(SDL_Renderer *dest, Uint32 x, Sint32 y, Uint32 w, Uint32 h, SDL_Color *color)
85 SDL_Rect dst = { x, y, w, h };
86 //SDL_SetRenderDrawBlendMode(dest, SDL_BLENDMODE_BLEND);
87 SDL_SetRenderDrawColor(dest, color->r, color->g, color->b, color->a);
88 SDL_RenderFillRect(dest, &dst);
90 #define PIXEL_BY_PIXEL
91 void MY_DrawSineWave(SDL_Renderer *surface, Sint32 x, Sint32 y, float a, int len, SDL_Color *col)
93 float i;
94 SDL_Rect *clip = NULL;//&surface->clip_rect;
95 float c = cosf(a * M_PI / 180);
96 float s = sinf(a * M_PI / 180);
97 float AMP = 2;
98 float WAV = 4;
100 #ifndef PIXEL_BY_PIXEL
101 int count = 0; SDL_Point points[1024];
102 #endif
103 int freq = ui.freq;
105 int colorquant = 16;//((len+1) / 16);
107 for (i = 0; i < len; i+= 0.5)//0.1)
109 int j = (int)(freq) % colorquant;
111 int nx = (int)(x + i * c);
112 int ny = (int)(y + i * s);
113 ny += ( cosf( (freq+i) / WAV) * AMP );
114 nx += ( sinf( (freq+i) / WAV) * AMP );
115 #ifndef PIXEL_BY_PIXEL
116 points[count].x = nx;
117 points[count].y = ny;
118 count++;
119 if (count >= sizeof(points) - 2) break;
120 continue;
121 #else
122 if (!clip || SDL_InBounds(nx, ny, clip))
124 MY_PutPixel(surface, nx, ny, &reds[j]);
125 //SDL_AlphaFill(surface, nx, ny, 2, 2, color);
127 #endif
129 #ifndef PIXEL_BY_PIXEL
130 SDL_SetRenderDrawColor(surface, col->r, col->g, col->b, col->a);
131 SDL_RenderDrawPoints(surface, points, count);
132 #endif
134 void MY_DrawSine(SDL_Renderer *dst, Sint32 x1, Sint32 y1, Sint32 x2, Sint32 y2, SDL_Color *color)
136 Sint32 dx = x2 - x1;
137 Sint32 dy = y2 - y1;
138 double angle = atan2(dy, dx) * 180 / M_PI;
139 double distance = sqrt( (dx*dx) + (dy*dy) );
141 MY_DrawSineWave(dst, x1, y1, (float)angle, (int)distance, color);
144 int unit_icon(unit_t *u) {
145 if (u->link == NULL) /* Either rune lord either free man */
146 if (u->ref_counts == 0) return 0; /* FREE MAN */
147 else return 3; /* RUNE LORD */
148 else /* Either a vector either a devotee */
149 if (u->ref_counts == 0) return 1; /* DEVOTEE */
150 else return 2; /* VECTOR */
153 /* RUNE printf */
154 int rprintf(SDL_Renderer *renderer, Uint32 x, Uint32 y, const char *fmt, ...) {
155 char buffer[1024];
157 va_list argptr;
158 va_start(argptr, fmt);
160 vsnprintf(buffer, sizeof(buffer), fmt, argptr);
162 va_end(argptr);
164 inprint(renderer, buffer, x, y);
166 return 0;
170 /* One tile */
171 void draw_tile(SDL_Renderer *screen, Uint8 id, Uint8 frame, Uint32 x, Uint32 y) {
172 SDL_Rect src = { frame * 16, id * 16 , 16, 16 };
173 SDL_Rect dst = { x, y, 16, 16 };
174 SDL_RenderCopy(screen, tiles, &src, &dst);
176 /* W & H tile */
177 void draw_ctile(SDL_Renderer *screen, Uint8 id, Uint8 frame, Uint32 x, Uint32 y, Uint8 w, Uint8 h) {
178 SDL_Rect src = { frame * 16, id * 16 , 16 * w, 16 * h };
179 SDL_Rect dst = { x, y, 16 * w, 16 * h };
180 SDL_RenderCopy(screen, tiles, &src, &dst);
182 /* Stretched tile */
183 void draw_stile(SDL_Renderer *screen, Uint8 id, Uint8 frame, Uint32 x, Uint32 y, Uint8 w, Uint8 h, Uint8 sw, Uint8 sh) {
184 SDL_Rect src = { frame * TILE_W, id * TILE_W , w * TILE_W, h * TILE_H };
185 SDL_Rect dst = { x, y, sw * TILE_W, sh * TILE_H };
186 SDL_RenderCopy(screen, tiles, &src, &dst);
189 /* W & H tile on sx/sy source */
190 void draw_btile(SDL_Renderer *screen, Uint32 sy, Uint32 sx, Uint32 x, Uint32 y, Uint8 w, Uint8 h) {
191 SDL_Rect src = { sx, sy, 16 * w, 16 * h };
192 SDL_Rect dst = { x, y, 16 * w, 16 * h };
193 SDL_RenderCopy(screen, tiles, &src, &dst);
196 void draw_visual(SDL_Renderer *renderer, Uint8 *refs[], animation_t *a, Uint32 x, Uint32 y) {
197 int i;
199 SDL_Rect dst = { x, y, a->plane.w, a->plane.h };
200 //start with base plane...
201 SDL_Rect src = { a->plane.x, a->plane.y, a->plane.w, a->plane.h };
203 //...offset by each modifier axis
204 for (i = 0; i < a->num_axises; i++) {
205 Uint8 ask = a->axis_modifier[i];
206 Uint8 ref = *(refs[ask]);
207 src.x += ref * a->axis_offset[i].w + a->axis_offset[i].x;
208 src.y += ref * a->axis_offset[i].h + a->axis_offset[i].y;
211 SDL_RenderCopy(renderer, a->image, &src, &dst);
216 void draw_blackbox(SDL_Renderer *screen, Uint32 x, Uint32 y, Uint32 w, Uint32 h) {
217 // Uint32 brown = SDL_MapRGB(screen->format, 0x6c, 0x44, 0x1c);
219 SDL_Rect box = { x, y, w, h };
221 SDL_SetRenderDrawColor(screen, 0, 0, 0, 255);
222 SDL_RenderFillRect(screen, &box);
224 /*box.x++;
225 box.y++;
226 box.w-=2;
227 box.h-=2;*/
229 SDL_SetRenderDrawColor(screen, brown.r, brown.g, brown.b, 255);
230 SDL_RenderDrawRect(screen, &box);
234 ///////////
236 void draw_pools(SDL_Renderer *screen) {
238 SDL_Color redish = { 0xff, 0, 0, 0x33 };
239 SDL_Color greenish = { 0, 0xff, 0, 0x33 };
240 SDL_Color black = { 0, 0, 0, 0xAA };
241 SDL_Color white = { 0xff, 0xff, 0xff, 0xEE };
243 int i;
244 for (i = 0 ; i < num_pools; i++) {
245 pool_t *pool = &pools[i];
246 unit_t *head = pool->head;
248 Uint32 x = head->x * TILE_W - TILE_W;
249 Uint32 y = head->y * TILE_H - TILE_H;
251 x -= (i % 4) * 8;
252 y -= (i % 4) * 16;
254 x = x - ui.vx + game_map.x;
255 y = y - ui.vy + game_map.y;
257 SDL_Rect mini = { x, y, 64, 10 };
259 SDL_AlphaFill(screen, x, y, mini.w, mini.h, &black);
260 MY_LineRect(screen, &mini, &redish);
262 // draw_tile(screen, TILE_STAT_Y, TILE_STAT_X + pool->stat, x , y);
264 int links = 0;
265 /* Draw kids overlays */
266 //unit_t *lim = (head->link == pool->tail ? NULL : pool->head);
267 unit_t *it = pool->tail;
268 while (it) {
269 Uint32 sx = it->x * TILE_W + it->ox - ui.vx + game_map.x;
270 Uint32 sy = it->y * TILE_H + it->oy - ui.vy + game_map.y;
272 MY_DrawLine(screen, sx + 8, sy + 4, x, y + mini.h/2, &redish);
274 it = it->link;
275 if (it == head) break;
276 links++;
279 infont(small_font);
280 incolor1(&white);
281 rprintf(screen, x + 3, y + 1, "%02d %s:%03d", links+1, stat_names[pool->stat], pool->pool);
283 Uint32 sx = head->x * TILE_W + it->ox - ui.vx + game_map.x;
284 Uint32 sy = head->y * TILE_H + it->oy - ui.vy + game_map.y;
286 MY_DrawLine(screen, sx + 8, sy + 4, x + mini.w/2, y + mini.h/2, &greenish);
290 //TODO: remove
291 infont(large_font);
293 void draw_paths(SDL_Renderer *screen, Sint8 sel, Uint16 x, Uint16 y) {
294 #ifndef DEBUG_PATHFIND
295 int i,j;
296 if (sel == -1) return;
297 unit_t *su = &units[sel];
298 for (i = 0; i < 16; i++) {
299 if (su->path[i] == -1) break;
300 int x, y;
302 y = su->path[i] / level_w;
303 x = su->path[i] % level_w;
305 Uint32 tx = x * TILE_W - ui.vx + game_map.x;
306 Uint32 ty = y * TILE_H - ui.vy + game_map.y;
308 SDL_Color color = { 255, 255, 255, 128 + i * 8 };
309 SDL_AlphaFill(screen, tx, ty, TILE_W, TILE_H, &color);
313 SDL_AlphaFill(screen,
314 su->tx * TILE_W - ui.vx + game_map.x,
315 su->ty * TILE_H - ui.vy + game_map.y, TILE_W, TILE_H, &yellow);
316 #else
317 int i,j;
318 if (sel == -1) return;
319 unit_t *su = &units[sel];
320 for (j = 0; j < LEVEL_H; j++) {
321 for (i = 0; i < LEVEL_W; i++) {
322 Uint32 pos = j * LEVEL_W + i;
323 Uint32 tx = i * TILE_W - ui.vx + game_map.x;
324 Uint32 ty = j * TILE_H - ui.vy + game_map.y;
325 char buf[16];
326 char vd = '>' - 1;
327 if (su->prev[pos] == -1) vd = '!';
328 else if (su->prev[pos] - pos == -1) vd = '<';
329 else if (su->prev[pos] - pos < -1) vd = '^';
330 else if (su->prev[pos] - pos > 1) vd = 'v';
332 infont(small_font);
333 incolor(0x00FFFFFF, 0);
334 //rprintf(screen, tx, ty, "%ld%c", (su->d[pos]/25 > 9 ? 9 : su->d[pos]/25), vd);
335 rprintf(screen, tx, ty, "%ld", su->d[pos]/10);
337 //Uint32 color = SDL_MapRGBA(screen->format,
338 SDL_Color color = { su->d[pos], su->d[pos], su->d[pos], su->d[pos] };
339 SDL_AlphaFill(screen, tx + x, ty + y, TILE_W, TILE_H, &color);
343 SDL_AlphaFill(screen,
344 su->tar_x * TILE_W - ui.vx + game_map.x,
345 su->tar_y * TILE_H - ui.vy + game_map.y, TILE_W, TILE_H, &red);
348 SDL_AlphaFill(screen,
349 su->tx * TILE_W - ui.vx + game_map.x,
350 su->ty * TILE_H - ui.vy + game_map.y, TILE_W, TILE_H, &yellow);
352 i = ui.hover_tx;
353 j = ui.hover_ty;
354 Uint32 pos = j * LEVEL_W + i;
355 Uint32 tx = i * TILE_W - ui.vx + game_map.x;
356 Uint32 ty = j * TILE_H - ui.vy + game_map.y;
358 infont(small_font);
359 incolor(0x00FF0000, 0);
360 //rprintf(screen, tx, ty, "%ld%c", (su->d[pos]/25 > 9 ? 9 : su->d[pos]/25), vd);
361 rprintf(screen, tx, ty, "%ld", su->d[pos]/10);
363 //TODO: remove
364 infont(large_font);
365 #endif
367 void draw_overlays(SDL_Renderer *screen, Sint8 sel, Uint8 flip, Uint8 block, unit_t *from) {
368 if (sel == -1) return;
369 int i;
370 if (block == 0) for (i = 0; i < num_units; i++) units[i].block = 0;
371 unit_t *su = &units[sel];
372 Uint32 sx = su->x * TILE_W + su->ox - ui.vx + game_map.x;
373 Uint32 sy = su->y * TILE_H + su->oy - ui.vy + game_map.y;
374 su->block = 1;
375 //Uint32 colors[16] = { 0x00FF0033, 0xFF000033 };
376 for (i = 0; i < num_units; i++) {
377 unit_t *u = &units[i];
378 Uint32 x = u->x * TILE_W + u->ox - ui.vx + game_map.x;
379 Uint32 y = u->y * TILE_H + u->oy - ui.vy + game_map.y;
381 if (u->tile == 0 || u == from) continue;
382 if (u->link == su ) {
383 MY_DrawSine(screen, sx + 8, sy + 4, x + 8, y + 4, reds);//colors[flip]);
384 //SDL_DrawLine(screen, sx + 8, sy + 4, x + 8, y + 4, colors[flip]);
385 if (!u->block) draw_overlays(screen, i, flip, 1, su);
387 if (su->link == u) {
388 MY_DrawSine(screen, x + 8, y + 4, sx + 8, sy + 4, reds);//colors[1 - flip]);
389 //SDL_DrawLine(screen, sx + 8, sy + 4, x + 8, y + 4, colors[flip]);
390 if (!u->block) draw_overlays(screen, i, flip, 1, su);
395 void draw_goldbox(SDL_Renderer *screen, Uint32 x, Uint32 y, Uint8 tile, int val) {
396 Uint32 w = 72;
397 Uint32 h = 14;
399 SDL_Rect border = { x, y, w, h };
400 SDL_Rect filler = { x+1, y+1, w-2, h-2 };
402 SDL_SetRenderDrawColor(screen, 0, 0, 0, 255); //black
403 SDL_RenderFillRect(screen, &filler);
405 SDL_SetRenderDrawColor(screen, brown.r, brown.g, brown.b, 255);
406 SDL_RenderDrawRect(screen, &border);
408 infont(large_font);
409 incolor(0x00FFFFFF, 0);
410 rprintf(screen, x+14, y+3, "% 7d", val);
412 draw_tile(screen, TILE_RES_Y, TILE_RES_X + tile, x+4, y+4);
415 void draw_buildset(SDL_Renderer *screen) {
417 int x = buildbox.x;
418 int y = buildbox.y;
420 int i;
421 for (i = 0; i < 2; i++) {
422 int hover = 0;
423 int pushin_x = 1;
424 int pushin_y = 1;
425 if (ui.setflag == i) {
426 hover = 2;
427 pushin_x = 0;
428 pushin_y = 0;
430 else {
431 if (ui.hover == overFlagButton && ui.hover_id == i) {
432 hover = 1;
436 draw_tile(screen, TILE_BTN_Y + 1, TILE_BTN_X + hover, x, y);
437 draw_tile(screen, TILE_FLAG_Y, TILE_FLAG_X + i, x - pushin_x, y - pushin_y);
439 x += 17;
440 if (x >= buildbox.x + buildbox.w - TILE_W/2) {
441 x = buildbox.x;
442 y += 17;
445 for (i = 0; i < HMENU_ITEMS; i++) {
447 house_p *m = &bhouses[i];
449 int hover = 0;
450 int pushin_x = 1;
451 int pushin_y = 1;
452 if (ui.builder == i) {
453 hover = 2;
454 pushin_x = 0;
455 pushin_y = 0;
457 else {
458 if (ui.hover == overBuildButton && ui.hover_id == i) {
459 hover = 1;
463 draw_tile(screen, TILE_BTN_Y + 1, TILE_BTN_X + hover, x, y);
464 draw_tile(screen, 0, m->icon + 1, x - pushin_x, y - pushin_y);
466 x += 17;
467 if (x >= buildbox.x + buildbox.w - TILE_W/2) {
468 x = buildbox.x;
469 y += 17;
474 void draw_minimap(SDL_Renderer *screen) {
475 Uint32 w = minimap.w;
476 Uint32 h = minimap.h;
478 Uint32 x = minimap.x;
479 Uint32 y = minimap.y;
481 // draw_blackbox(screen, x, y, w, h);
483 x += 1;
484 y += 1;
485 w -= 2;
486 h -= 2;
488 SDL_Rect dem = { x, y, w, h };
489 SDL_SetRenderDrawColor(screen, 0x11, 0x33, 0x11, 255);
490 SDL_RenderFillRect(screen, &dem);
492 int zY = h / level_h;
493 int zX = w / level_w;
495 int rw = level_w * zX;
496 int rh = level_h * zY;
498 int offX = w % level_w / 2;
499 int offY = h % level_h / 2;
501 x += offX;
502 y += offY;
504 int i;
505 for (i = 0; i < num_units; i++) {
506 unit_t *u = &units[i];
507 unit_p *proto = &bunits[u->tile];
509 SDL_Color *color;
511 color = &factions[u->faction].color;
513 if (ui.unit == i) {
514 color = &white;
516 SDL_Rect trg = { x + u->x * zX, y + (u->y-(proto->h-1)) * zY, proto->w * zX, proto->h * zY };
517 SDL_SetRenderDrawColor(screen, color->r, color->g, color->b, 255);
518 SDL_RenderFillRect(screen, &trg);
520 for (i = 0; i < num_houses; i++) {
521 house_t *h = &houses[i];
523 SDL_Color color;
524 color.a = 255;
525 color.r = 0; color.g = 0; color.b = 0xff;
526 if (ui.house == i) {
527 color.r = 0xff; color.g = 0xff; color.b = 0xff;
529 SDL_Rect trg = { x + h->x * zX, y + (h->y) * zY, h->w * zX, h->h * zY };
530 SDL_SetRenderDrawColor(screen, color.r, color.g, color.b, color.a);
531 SDL_RenderFillRect(screen, &trg);
533 int j;
534 for (j = 0; j < LEVEL_H; j++) {
535 for (i = 0; i < LEVEL_W; i++) {
536 if (fog[j][i]) {
537 SDL_Rect trg = { x + i * zX, y + j * zY, zX, zY };
538 SDL_SetRenderDrawColor(screen, 0,0,0, 255);
539 SDL_RenderFillRect(screen, &trg);
544 int vx = (x) + ui.vx / (TILE_W / zX);
545 int vy = (y) + ui.vy / (TILE_H / zY);
547 int vw = rw / ((float)level_w * TILE_W / (game_map.w - 1)) + 1;
548 int vh = rh / ((float)level_h * TILE_H / (game_map.h - 1)) + 1;
550 //SDL_Rect vport = { vx, vy, vw, vh }; // Most accurate
551 //SDL_Rect vport = { vx - offX, vy - offY, vw + offX * 2, vh + offY * 2 }; // Prettiest
552 SDL_Rect vport = { vx - 1, vy - 1, vw + 2, vh + 2 }; // Middle ground
554 MY_LineRect(screen, &vport, &white);
556 MY_LineRect(screen, &minimap, &brown);
560 void draw_unitname(SDL_Renderer *screen, unit_t *u, Uint32 y, Uint8 offset, Uint16 xoffset) {
561 unit_p *p = &bunits[u->tile];
562 Uint32 x = ui.log_width - PANE_WIDTH + xoffset;
564 //draw_blackbox(screen, x, y+2, w, h);
566 /* :( draw face in bad way */
567 if (!u->tile) draw_tile(screen, 0, 0, x, y);
568 else
569 draw_visual(screen, u->axis_refs, &p->face, x, y - (p->h-1)*TILE_H);
571 incolor1(&bunits[u->tile].color);
572 incolor(0x00ffffff, 0);
573 inprint(screen, u->name, x + 17, y + offset);
574 //inprint(screen, bunits[u->tile].title, x + 17, y+8+3);
577 void draw_progbar(SDL_Renderer *renderer, int val, int max, const char *buf, Uint32 x, Uint32 y, SDL_Color *colors[3]) {
579 SDL_Rect dest = { x, y, 96, 9 };
581 if (val < 0) val = 0;
583 int centerX = 0;
584 char buf2[80];
585 sprintf(buf2, buf, val, max);
586 centerX = (dest.w - strlen(buf2) * 6) / 2;
588 MY_LineRect(renderer, &dest, colors[0]);
590 dest.x += 1;
591 dest.y += 1;
592 dest.w -= 2;
593 dest.h -= 2;
595 int prop = val * 100 / max;
596 int pix_horz = dest.w * prop / 100;
598 SDL_AlphaFill(renderer, dest.x, dest.y, pix_horz, dest.h, colors[1]);
600 infont(small_font);
601 incolor1(colors[2]);
602 rprintf(renderer, x + centerX, y + 1, buf, val, max);
603 //rprintf(renderer, x, y + 1, buf, val, max);
607 void draw_pinbox(SDL_Renderer *screen) {
609 Uint32 x = pinbox.x;
610 Uint32 y = pinbox.y;
612 SDL_Rect pinbtn = { 0, 0, 16, 16 };
614 int i, highlight_pin;
615 for (i = 0; i < num_units; i++) {
616 unit_t *u = &units[i];
617 if (u->tile && u->pin) {
619 /* Draw name */
620 draw_unitname(screen, u, y, 6, 0);
622 /* Draw pin */
623 pinbtn.x = x + 120;
624 pinbtn.y = y + 4;
626 highlight_pin = 0;
627 if (ui.hover == overListPin && ui.hover_id == i) highlight_pin = 1;
629 draw_tile(screen, TILE_UICO_Y, TILE_UICO_X + 5 - highlight_pin, pinbtn.x, pinbtn.y);
631 y += 16;
637 void draw_flagbox(SDL_Renderer *renderer) {
639 const char flag_names[2][80] = {
640 "Explore Flag",
641 "Wanted Flag",
644 Uint32 w = selbox.w;
645 Uint32 h = selbox.h;
647 Uint32 x = selbox.x;
648 Uint32 y = selbox.y;
650 draw_blackbox(renderer, x, y, w, h);
652 x += BOX_PADDING;
653 y += BOX_PADDING;
654 w -= BOX_PADDING * 2;
655 h -= BOX_PADDING * 2;
657 flag_t *f = &your->flags[ui.flag];
659 draw_tile(renderer, TILE_FLAG_Y, TILE_FLAG_X + f->type, x, y); /* flag icon */
660 y += 3; /* small offset after icon */
662 incolor(0x00FFFFFF, 0);
663 infont(large_font);
664 inprint(renderer, flag_names[f->type], x + 17, y);
665 y += 8;
667 y += 16;
668 x += 16;
669 draw_goldbox(renderer, x, y, 1, f->reward);
671 int hl = 0;
673 if (ui.hover == overFlagPlus) hl = 1 + ui.pushing;
675 x = plusbtn.x;
676 y = plusbtn.y;
678 draw_tile(renderer, TILE_BTN_Y+1, TILE_BTN_X + hl, x, y);
680 draw_tile(renderer, TILE_FLAG_Y, TILE_FLAG_X+3, x, y);
684 void draw_housebox_visitors(SDL_Renderer *screen, house_t *h, Uint32 x, Uint32 y) {
685 /* visitors */
686 int i, j = 0;
687 for (i = 0; i < num_units; i++) {
688 unit_t *u = &units[i];
689 if (u->visiting != h) continue;
691 infont(mid_font);
692 draw_unitname(screen, u, y, 2, 0);
694 incolor(0x00999999, 0);
695 infont(small_font);
696 rprintf(screen, x + 17, y + 8 + 2, "PROG: %d (%d gold)", u->progress, u->carry_gold);
698 j++;
699 y += 16;
703 void draw_housetabs(SDL_Renderer *renderer) {
705 Uint32 x = tabicon.x;
706 Uint32 y = tabicon.y;
708 Uint32 color = 0xCCCCCC;
710 int i;
711 for (i = 0; i < MAX_HOUSETABS; i++) {
713 color = 0xCCCCCC;
714 if (i == ui.housetab) color = 0xFFFFFF;
715 else if (ui.hover == overUnitTab && i == ui.hover_id) color = 0xEEEEEE;
717 incolor(color, 0);
718 inprint(renderer, housetabs_names[i], x, y);
720 x += tabicon.w;
721 if (x + tabicon.w >= ui.log_width) {
722 x = tabicon.x;
723 y += tabicon.h;
728 void draw_housebox(SDL_Renderer *screen) {
730 Uint32 w = selbox.w;
731 Uint32 ph = selbox.h;
733 Uint32 x = selbox.x;
734 Uint32 y = selbox.y;
736 draw_blackbox(screen, x, y, w, ph);
738 x += BOX_PADDING;
739 y += BOX_PADDING;
740 //w -= BOX_PADDING * 2;
741 //h -= BOX_PADDING * 2;
743 house_t *h = &houses[ui.house];
744 house_p *p = &bhouses[h->tile];
746 draw_tile(screen, 0, h->tile+1, x, y); /* house icon */
747 y += 3; /* small offset after icon */
749 incolor(0x00FFFFFF, 0);
751 infont(large_font);
752 inprint(screen, "Something", x + 17, y);
753 y += 8;
755 infont(large_font);
756 inprint(screen, p->title, x + 17, y);
757 y += 8;
759 infont(small_font);
760 rprintf(screen, x + 17, y, "HP: %d/%d", h->hp, h->max_hp);
761 y += 8;
763 /* Draw flag */
764 if (h->flag_id[ui.faction] != -1)
765 draw_tile(screen, TILE_FLAG_Y, TILE_FLAG_X + 1, flagicon.x, flagicon.y); /* flag icon */
767 draw_housetabs(screen);
769 /* visitors */
770 draw_housebox_visitors(screen, h, x, y);
773 void draw_unitbox_tab1(SDL_Renderer *screen, unit_t *u, Uint32 x, Uint32 y) {
775 int icon;
777 unit_p *p = &bunits[u->tile];
779 Uint32 color;
781 infont(large_font);
783 icon = unit_icon(u);
785 /* Print state (and draw icon) */
786 draw_tile(screen, TILE_UICO_Y, TILE_UICO_X + icon, x + 26, y + 106);
787 incolor(state_colors[icon], 0);
788 inprint(screen, state_names[icon], x + 16 + 17, y+106);
789 incolor(0xFFFFFFFF, 0);
791 /* Draw stats */
792 int i;
793 int hover;
794 for (i = 0; i < MAX_STAT; i++) {
795 hover = 0;
796 y += 14;
797 if (ui.stat == i) hover = 2;
798 else {
799 if (ui.hover == overUnitStat && ui.hover_id == i) {
800 hover = 1;
803 if (u->link != NULL) hover = -1;
804 //if (u->link && u->link_stat == i) hover = 0;
805 draw_tile(screen, TILE_BTN_Y, TILE_BTN_X + hover, x , y);
807 draw_tile(screen, TILE_STAT_Y, TILE_STAT_X + i, x , y);
808 incolor(0xFFFFFF,0);
809 rprintf(screen, x + 17, y + 3, "%02d", u->base_stat[i]);
811 Uint32 col;
812 if (u->calc_stat[i] > u->base_stat[i]) col = 0x00FF00;
813 else if (u->calc_stat[i] < u->base_stat[i]) col = 0xFF0000;
814 else col = 0xFFFFFF;
816 incolor(col,0);
817 rprintf(screen, x + 17*2 + 7, y + 3, "%02d", u->calc_stat[i]);
820 /* Draw skills */
821 y -= 14 * MAX_STAT;
822 x += 64;
823 for (i = 0; i < MAX_STAT; i++) {
824 int tile = i;
825 hover = 0;
826 y += 14;
827 int hx = 0;
828 int hy = 0;
829 if (ui.btn == i) { hover = 2; hx = 1; hy = 1; }
830 else {
831 if (ui.hover == overUnitSkill && ui.hover_id == i) {
832 hover = 1;
836 /* Hack -- perception can take 2 different icons */
837 if (i == 4 && p->perc != Smell) tile += 1;
839 /* Hack -- offset "speech" icon by 1 */
840 if (i == 5) tile += 1;
842 //if (u->tile != U_PEASANT) hover = -1;
843 draw_tile(screen, TILE_BTN_Y, TILE_BTN_X + hover, x, y);
845 draw_tile(screen, TILE_STAT_Y + 3, TILE_STAT_X + tile, x+hx, y+hy);
847 incolor(0xFFFFFF, 0);
848 rprintf(screen, x + 17, y + 3, "%02d", u->base_skill[i]);
850 if (u->calc_skill[i] > u->base_skill[i]) color = 0x00FF00;
851 else if (u->calc_skill[i] < u->base_skill[i]) color = 0xFF0000;
852 else color = 0xFFFFFF;
854 incolor(color, 0);
855 rprintf(screen, x + 17*2 + 7, y + 3, "%02d", u->calc_skill[i]);
860 void draw_unitbox_tab2(SDL_Renderer *renderer, unit_t *u, Uint32 x, Uint32 y) {
861 unit_p *p = &bunits[u->tile];
863 /* Random info I */
864 infont(large_font);
865 incolor1(&white);
866 rprintf(renderer, x, y + 16, "Level: %02d", u->level);
867 /* exp */
868 SDL_Color *exp_colors[3] = { &darkmagenta, &magenta, &darkmagenta };
869 draw_progbar(renderer, u->exp, 1000, "Exp: %d/%d", x + 17 - 4, y + 16 + 8, exp_colors);
871 /* Random info II */
872 infont(mid_font);
873 rprintf(renderer, x, y + 32, "Class: %s", p->title);
875 /* Random info III */
876 infont(small_font);
877 incolor1(&white);
878 rprintf(renderer, x, y + 64 + 8 * 0, "Fame: %d", u->fame);
879 rprintf(renderer, x, y + 64 + 8 * 1, "Happiness: %d%", u->happiness);
880 rprintf(renderer, x, y + 64 + 8 * 2, "Wealth: %d", u->gold);
881 SDL_Color *nrg_colors[3] = { &brown, &yellow, &brown };
882 draw_progbar(renderer, u->energy, (u->calc_stat[S_DEX]+1) * 10, "Energy: %d", x, y + 64 + 8 * 3, nrg_colors);
885 void draw_unitbox_tab_runes(SDL_Renderer *screen, unit_t *u, Uint32 x, Uint32 y) {
887 int icon;
888 unit_p *p = &bunits[u->tile];
890 icon = unit_icon(u);
892 infont(large_font);
894 /* Print state (and draw icon) */
895 draw_tile(screen, TILE_UICO_Y, TILE_UICO_X + icon, x + 26, y + 106);
896 incolor(state_colors[icon], 0);
897 inprint(screen, state_names[icon], x + 16 + 17, y+106);
898 incolor(0xFFFFFFFF, 0);
900 /* Draw stats */
901 int i;
902 int hover;
903 Uint32 col;
904 char *s;
905 int stat = 0;
906 for (i = 0; i < MAX_STAT; i++) {
907 hover = 0;
908 y += 14;
909 if (ui.stat == i) hover = 2;
910 else {
911 if (ui.hover == overUnitStat && ui.hover_id == i) {
912 hover = 1;
915 if (u->link != NULL) hover = -1;
916 //if (u->link && u->link_stat == i) hover = 0;
917 draw_tile(screen, TILE_BTN_Y, TILE_BTN_X + hover, x , y);
919 draw_tile(screen, TILE_STAT_Y, TILE_STAT_X + i, x , y);
921 if (u->link == NULL || u->link_stat != i) {
922 if (u->ref_count[i] == 0) icon = 0;
923 if (u->ref_count[i] > 0) icon = 3;
924 } else {
925 if (u->ref_count[i] == 0) icon = 1;
926 if (u->ref_count[i] > 0) icon = 2;
929 if (icon == 3) { col = 0x00FF00; s = "<"; stat = u->calc_stat[i]; }
930 else if (icon == 1) { col = 0xFF0000; s= ">"; stat = u->base_stat[i]; }
931 else if (icon == 2) { col = 0x0000FF; s= ">"; stat = u->rune_stat[i]; }
932 else { col = 0xFFFFFF; s = ""; stat = 0; }
934 infont(large_font);
935 incolor(col,0);
936 rprintf(screen, x + 17, y + 3, "%02d%s", stat, s);
938 /* Print relation */
939 infont(mid_font);
940 if (u->link && u->link_stat == i)
941 draw_unitname(screen, u->link, y - 4, 7, 48);
942 else if (u->ref_count[i]) {
943 incolor(col,0);
944 rprintf(screen, x + 48, y + 3, "%d dvt", u->ref_count[i]);
950 void draw_unitbox_tab_ai(SDL_Renderer *renderer, unit_t *u, Uint32 x, Uint32 y) {
951 unit_p *p = &bunits[u->tile];
953 infont(large_font);
954 incolor1(&white);
955 rprintf(renderer, x, y + 16 + 8 * 0, "Desire: %s", desire_names[u->top_desire]);
956 rprintf(renderer, x, y + 16 + 8 * 1, "Method: %s", desire_names[u->top_method]);
958 rprintf(renderer, x, y + 16 + 8 * 2, "Strategy: %s", start_names[u->strategy]);
959 rprintf(renderer, x, y + 16 + 8 * 3, "Tactic: %s", tact_names[u->tactic]);
961 infont(mid_font);
962 incolor1(&white);
965 rprintf(renderer, x, y + 16 + 8 * 5, "Target:");
967 switch (u->target_type) {
968 case TARGET_TILE:
969 rprintf(renderer, x, y + 16 + 8 * 6, "Some Tile");
970 break;
971 case TARGET_FLAG:
972 rprintf(renderer, x, y + 16 + 8 * 6, "Some Flag");
973 break;
974 case TARGET_HOUSE:
975 rprintf(renderer, x, y + 16 + 8 * 6, "%s: %s", bhouses[houses[u->target_id].tile].title, houses[u->target_id].title);
976 break;
977 case TARGET_UNIT:
978 rprintf(renderer, x, y + 16 + 8 * 5, "Target: Unit %d", u->target_id);
979 draw_unitname(renderer, &units[u->target_id], y + 16 + 8 * 6 - 4, 6, 16);
980 break;
981 case TARGET_NONE:
982 default:
983 rprintf(renderer, x, y + 16 + 8 * 5, "Target: None");
984 break;
987 int i, steps = 0;
988 for (i = 0; i < 16; i++) {
989 if (u->path[i] == -1) break;
990 steps++;
993 rprintf(renderer, x, y + 16 + 8 * 8, "Steps: %d", steps);
997 void draw_unittabs(SDL_Renderer *renderer) {
999 Uint32 x = tabicon.x;
1000 Uint32 y = tabicon.y;
1002 Uint32 color = 0xCCCCCC;
1004 int i;
1005 for (i = 0; i < MAX_UNITTABS; i++) {
1007 color = 0xCCCCCC;
1008 if (i == ui.unittab) color = 0xFFFFFF;
1009 else if (ui.hover == overUnitTab && i == ui.hover_id) color = 0xEEEEEE;
1011 incolor(color, 0);
1012 inprint(renderer, unittabs_names[i], x, y);
1014 x += tabicon.w;
1015 if (x + tabicon.w >= ui.log_width) {
1016 x = tabicon.x;
1017 y += tabicon.h;
1022 void draw_unitbox(SDL_Renderer *screen) {
1024 Uint32 w = selbox.w;
1025 Uint32 h = selbox.h;
1027 Uint32 x = selbox.x;
1028 Uint32 y = selbox.y;
1030 draw_blackbox(screen, x, y, w, h);
1032 x += BOX_PADDING;
1033 y += BOX_PADDING;
1034 w -= BOX_PADDING * 2;
1035 h -= BOX_PADDING * 2;
1037 unit_t *u = &units[ui.unit];
1038 unit_p *p = &bunits[u->tile];
1040 /* :( draw face in bad way */
1041 if (!u->tile) draw_tile(screen, 0, 0, x, y);
1042 else
1043 draw_visual(screen, u->axis_refs, &p->face, x, y - (p->h-1)*TILE_H);
1045 /* Print name */
1046 infont(large_font);
1047 inprint(screen, u->name, x + 17, y + 3);
1048 incolor1(&bunits[u->tile].color);
1049 inprint(screen, bunits[u->tile].title, x + 17, y+8+3);
1051 /* Draw pin */
1052 draw_tile(screen, TILE_UICO_Y, TILE_UICO_X + 4 + u->pin, unitpin.x, unitpin.y);
1054 /* Draw flag */
1055 if (u->flag_id[ui.faction] != -1)
1056 draw_tile(screen, TILE_FLAG_Y, TILE_FLAG_X + 1, flagicon.x, flagicon.y); /* flag icon */
1058 /* Draw health */
1059 SDL_Color *hp_colors[3] = { &darkred, &red, &darkred };
1060 draw_progbar(screen, (u->max_hp - u->dmg), u->max_hp, "HP: %d/%d", x + 17, y + 8 + 3, hp_colors);
1062 x += BOX_PADDING;
1063 y += BOX_PADDING;
1064 w -= BOX_PADDING * 2;
1065 h -= BOX_PADDING * 2;
1067 y += BOX_PADDING;
1069 /* Draw tabs */
1070 draw_unittabs(screen);
1072 /* Draw contents */
1073 switch (ui.unittab) {
1074 case -1:
1075 case 0:
1076 draw_unitbox_tab1(screen, u, x, y);
1077 break;
1078 case 1:
1079 draw_unitbox_tab2(screen, u, x, y);
1080 break;
1081 case 4:
1082 draw_unitbox_tab_runes(screen, u, x, y);
1083 break;
1084 case 5:
1085 draw_unitbox_tab_ai(screen, u, x, y);
1086 break;
1087 default:
1088 break;
1093 void draw_hintbox(SDL_Renderer *screen) {
1095 Uint32 w = PANE_WIDTH;
1096 Uint32 h = 128;
1098 Uint32 x = ui.log_width - w;
1099 Uint32 y = hintbox.y;
1101 draw_blackbox(screen, x, y, w, h);
1103 x += BOX_PADDING;
1104 y += BOX_PADDING;
1105 w -= BOX_PADDING * 2;
1106 h -= BOX_PADDING * 2;
1108 /* Hack -- minus 1 pixel */
1109 x -= 1;
1111 if (ui.hintType == 0) { // Building
1113 house_p *h = &bhouses[ui.hint];
1115 infont(large_font);
1116 incolor(0xffffff, 0);
1117 inprint(screen, h->title, x, y);
1121 if (ui.hintType == 1) { // Stat
1123 infont(large_font);
1124 incolor(0xffffff, 0);
1125 inprint(screen, stat_long_names[ui.hint], x, y);
1127 y += 32;
1128 infont(small_font);
1129 incolor(0x999999, 0);
1130 inprint(screen, stat_descriptions[ui.hint], x, y);
1132 y += 32;
1133 infont(mid_font);
1134 incolor(0xffffff, 0);
1135 rprintf(screen, x, y, "1 forcible (100 blood ore)");
1138 /* TODO: remove this */
1139 infont(large_font);
1142 void draw_forcible(SDL_Renderer *screen) {
1143 draw_tile(screen, 22, 4, ui.x, ui.y);
1145 unit_t *u = &units[ui.unit];
1146 Uint32 x = u->x * TILE_W + u->ox - ui.vx + game_map.x;
1147 Uint32 y = u->y * TILE_H + u->oy - ui.vy + game_map.y;
1149 MY_DrawSine(screen, ui.x, ui.y, x + TILE_W/2, y + TILE_H/4, reds);
1151 if (ui.hover == overUnit) {
1152 unit_t *u2 = &units[ui.hover_id];
1153 Uint8 ok = 1;
1154 if (u2 == u) ok = 0;
1155 SDL_Color color = { 0, 0, 0, 0x33 };
1156 if (ok) color.g = 0xFF;
1157 else color.r = 0xFF;
1158 SDL_AlphaFill(screen,
1159 u2->x * TILE_W + u2->ox - ui.vx + game_map.x,
1160 u2->y * TILE_H + u2->oy - ui.vy + game_map.y, TILE_W, TILE_H, &color);
1164 void draw_builder(SDL_Renderer *screen) {
1166 SDL_Color color = { 0, 0, 0, 0x33 };
1167 house_p *h = &bhouses[ui.builder];
1169 /* For mouse-less devices, show the whole grid */
1170 if (ui.no_mouse) {
1171 //int i, j;
1173 return;
1176 if (ui.hover_xcollide) color.r = 0xFF; /* colliding, make it red */
1177 else color.g = 0xFF; /* not colliding, make it green */
1179 SDL_AlphaFill(screen,
1180 ui.hover_tx * TILE_W - ui.vx + game_map.x,
1181 ui.hover_ty * TILE_H - ui.vy + game_map.y,
1182 h->w * TILE_W, h->h * TILE_H, &color);
1185 void draw_setflag(SDL_Renderer *renderer) {
1187 SDL_Color color = { 0, 0, 0, 0x33 };
1189 if (ui.hover_xcollide != ui.setflag || ui.hover == overFlag)
1190 color.r = 0xFF; /* make it red */
1191 else
1192 color.g = 0xFF; /* make it green */
1194 SDL_AlphaFill(renderer,
1195 ui.hover_tx * TILE_W - ui.vx + game_map.x,
1196 ui.hover_ty * TILE_H - ui.vy + game_map.y,
1197 1 * TILE_W, 1 * TILE_H, &color);
1200 // draw_tile(renderer, TILE_FLAG_Y, TILE_FLAG_X + ui.setflag, ui.hover_tx, ui.hover_ty);
1201 draw_tile(renderer, TILE_FLAG_Y, TILE_FLAG_X + ui.setflag,
1202 ui.hover_tx * TILE_W - ui.vx + game_map.x,
1203 ui.hover_ty * TILE_H - ui.vy + game_map.y
1208 void draw_selector(SDL_Renderer *screen, Uint8 top, Uint32 x, Uint32 y, Uint8 w, Uint8 h) {
1209 if (w > 2) {
1210 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);
1211 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);
1213 else if (w == 2) {
1214 if (top) draw_ctile(screen, TILE_SEL_Y, TILE_SEL_X + 2, x, y + (h-1)*TILE_H, 2, 1);
1215 else draw_ctile(screen, TILE_SEL_Y, TILE_SEL_X + 4, x, y + (h-1)*TILE_H, 2, 1);
1216 } else {
1217 if (top) draw_tile(screen, TILE_SEL_Y, TILE_SEL_X, x, y + (h-1)*TILE_H);
1218 else draw_tile(screen, TILE_SEL_Y, TILE_SEL_X + 1, x, y + (h-1)*TILE_H);
1222 void draw_unbuilt_house(SDL_Renderer *screen, house_t *h, int sel) {
1224 Uint32 x = h->x * TILE_W - ui.vx + game_map.x;
1225 Uint32 y = h->y * TILE_H - ui.vy + game_map.y;
1226 Uint32 pix_w = h->w * TILE_W;
1227 Uint32 pix_h = h->h * TILE_H;
1228 Uint8 tile = h->tile;
1230 house_p *bp = &bhouses[tile];
1232 if (sel) draw_selector(screen, 1, x, y, h->w, h->h);
1234 draw_btile(screen,
1235 bp->body.plane.y + bp->unbuilt.y,
1236 bp->body.plane.x + bp->unbuilt.x,
1237 x, y, h->w, h->h);
1239 SDL_Rect built;
1241 built.x = bp->body.plane.x + bp->body.axis_offset[0].x;
1242 built.y = bp->body.plane.y + bp->body.axis_offset[0].y;
1244 int prop = h->hp * 100 / h->max_hp;
1245 int pix_vert = pix_w * prop / 100;
1246 int pix_horz = pix_h * prop / 100;
1247 //printf("Percent built: %d (in pix: %d)\n", prop, pix);
1249 SDL_Rect src = { built.x + (pix_w - pix_vert), built.y, pix_vert, TILE_H * h->h };
1250 SDL_Rect dst = { x + (pix_w - pix_vert), y, pix_vert, TILE_H * h->h };
1251 SDL_RenderCopy(screen, tiles, &src, &dst);
1254 SDL_Rect src = { built.x, built.y + (pix_h - pix_horz), TILE_W * h->w, pix_horz };
1255 SDL_Rect dst = { x, y + (pix_h - pix_horz), TILE_W * h->w, pix_horz };
1256 SDL_RenderCopy(screen, tiles, &src, &dst);
1259 if (sel) draw_selector(screen, 0, x, y, h->w, h->h);
1262 inline void draw_house(SDL_Renderer *screen, house_t *h, Uint32 x, Uint32 y) {
1263 house_p *p = &bhouses[h->tile];
1264 draw_visual(screen, h->axis_refs, &p->body, x, y);
1267 void draw_houses(SDL_Renderer *screen) {
1268 int i;
1269 for (i = 0; i < num_houses; i++) {
1270 house_t *h = &houses[i];
1271 //if (h->tile == 0) continue;
1272 Uint32 x = h->x * TILE_W - ui.vx + game_map.x;
1273 Uint32 y = h->y * TILE_H - ui.vy + game_map.y;
1275 if (h->built == 0) { draw_unbuilt_house(screen, h, (ui.house==i)); continue; }
1277 house_p *bp = &bhouses[h->tile];
1279 if (ui.house == i) draw_selector(screen, 1, x, y, h->w, h->h);
1281 draw_visual(screen, h->axis_refs, &bp->body, x, y);
1283 if (ui.house == i) draw_selector(screen, 0, x, y, h->w, h->h);
1287 inline void draw_unit(SDL_Renderer *screen, unit_t *u, Uint32 x, Uint32 y) {
1288 unit_p *p = &bunits[u->tile];
1289 draw_visual(screen, u->axis_refs, &p->body, x, y);
1292 void draw_units(SDL_Renderer *screen) {
1293 int i;
1294 for (i = 0; i < num_units; i++) {
1295 unit_t *u = &units[i];
1296 unit_p *proto = &bunits[u->tile];
1298 Uint32 x = u->x * TILE_W + u->ox - ui.vx + game_map.x;
1299 Uint32 y = u->y * TILE_H + u->oy - ui.vy + game_map.y;
1301 if (proto->h <= 0) {
1302 fprintf(stderr, "Very bad unit (%p)'%s' -- [%d,%d -- %d,%d]!\n", proto, proto->id,
1303 proto->body.plane.x, proto->body.plane.y, proto->w, proto->h);
1304 exit(-1);
1307 y -= TILE_H * (proto->h - 1);
1309 if (u->visiting) continue;
1311 if (ui.unit == i) draw_selector(screen, 1, x, y, proto->w, proto->h);
1313 //draw_unit(screen, u, x, y);
1314 draw_visual(screen, u->axis_refs, &proto->body, x, y);
1316 if (ui.unit == i) draw_selector(screen, 0, x, y, proto->w, proto->h);
1318 draw_tile(screen, TILE_UICO_Y, TILE_UICO_X + unit_icon(u), x, y);
1320 if (u->baloon)
1321 draw_tile(screen, TILE_BALOON_Y, TILE_BALOON_X + u->baloon, x - 7, y - 7);
1326 void draw_flags(SDL_Renderer *renderer) {
1327 int i;
1328 for (i = 0; i < your->num_flags; i++) {
1329 flag_t *f = &your->flags[i];
1331 Uint32 x = f->x * TILE_W - ui.vx + game_map.x;
1332 Uint32 y = f->y * TILE_H - ui.vy + game_map.y;
1334 Uint8 small = 0;
1336 if (f->type == 1) {
1338 if (f->house) {
1340 house_t *h = f->house;
1341 x = h->x * TILE_W - ui.vx + game_map.x;
1342 y = h->y * TILE_H - ui.vy + game_map.y;
1344 f->x = h->x;
1345 f->y = h->y;
1347 if (f->unit) {
1349 unit_t *u = f->unit;
1350 unit_p *p = &bunits[u->tile];
1351 if (u->visiting) continue;
1352 x = u->x * TILE_W + u->ox - ui.vx + game_map.x;
1353 y = u->y * TILE_H + u->oy - ui.vy + game_map.y;
1355 f->x = u->x;
1356 f->y = u->y - (p->h-1);
1358 y -= (p->h-1) * TILE_H;
1360 small = 1;
1366 if (ui.flag == i) draw_selector(renderer, 1, x, y, 1, 1);
1368 draw_tile(renderer, TILE_FLAG_Y, TILE_FLAG_X + f->type + small, x, y);
1370 if (ui.flag == i) draw_selector(renderer, 0, x, y, 1, 1);
1377 int foglet(int x, int y) {
1378 int mask[3][3] = { { 1 } };
1379 if (y > 0) {
1380 if (x > 0) mask[0][0] = fog[y - 1][x - 1];
1381 mask[0][1] = fog[y - 1][x];
1382 if (x < LEVEL_W) mask[0][2] = fog[y - 1][x + 1];
1384 if (y < LEVEL_H) {
1385 if (x > 0) mask[2][0] = fog[y + 1][x - 1];
1386 mask[2][1] = fog[y + 1][x];
1387 if (x < LEVEL_W) mask[2][2] = fog[y + 1][x + 1];
1389 if (x > 0) {
1390 mask[1][0] = fog[y][x - 1];
1392 if (x < LEVEL_W) {
1393 mask[1][2] = fog[y][x + 1];
1395 if (fog[y][x] == 0) return 0;
1397 if (!fog[y-1][x] && !fog[y+1][x-1] && !fog[y+1][x+1]) return 0;
1398 if (!fog[y][x-1] && !fog[y-1][x+1] && !fog[y+1][x+1]) return 0;
1399 if (!fog[y][x+1] && !fog[y-1][x-1] && !fog[y+1][x-1]) return 0;
1400 if (!fog[y+1][x] && !fog[y-1][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;
1403 if (!fog[y+1][x] && !fog[y][x-1] && !fog[y-1][x+1]) return 0;
1404 if (!fog[y-1][x] && !fog[y][x+1] && !fog[y+1][x-1]) return 0;
1406 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;
1407 if (!fog[y+1][x-1] && !fog[y][x+1] && fog[y][x-1] && fog[y-1][x] ) return 11;
1408 if (!fog[y-1][x+1] && !fog[y+1][x] && fog[y][x-1] && fog[y-1][x] ) return 11;
1409 if (!fog[y+1][x] && !fog[y][x+1] && fog[y][x-1] && fog[y-1][x] ) return 11;
1411 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;
1412 if (!fog[y-1][x+1] && !fog[y][x-1] && fog[y][x+1] && fog[y+1][x] ) return 19;
1413 if (!fog[y+1][x-1] && !fog[y-1][x] && fog[y][x+1] && fog[y+1][x] ) return 19;
1414 if (!fog[y-1][x] && !fog[y][x-1] && fog[y][x+1] && fog[y+1][x] ) return 19;
1416 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;
1417 if (!fog[y-1][x-1] && !fog[y+1][x] && fog[y][x+1] && fog[y-1][x] ) return 13;
1418 if (!fog[y+1][x+1] && !fog[y][x-1] && fog[y][x+1] && fog[y-1][x] ) return 13;
1419 if (!fog[y][x-1] && !fog[y+1][x] && fog[y][x+1] && fog[y-1][x] ) return 13;
1421 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;
1422 if (!fog[y][x+1] && !fog[y-1][x] && fog[y][x-1] && fog[y+1][x] ) return 17;
1423 if (!fog[y-1][x-1] && !fog[y][x+1] && fog[y][x-1] && fog[y+1][x] ) return 17;
1424 if (!fog[y+1][x+1] && !fog[y-1][x] && fog[y][x-1] && fog[y+1][x] ) return 17;
1426 if (fog[y][x-1] == 0 && fog[y][x+1] == 0) return 0;
1427 if (fog[y-1][x] == 0 && fog[y+1][x] == 0) return 0;
1429 if (fog[y-1][x] && fog[y+1][x]) {
1430 if (!fog[y-1][x-1] && !fog[y+1][x+1] && fog[y-1][x+1]) return 14;
1431 if (!fog[y+1][x-1] && !fog[y-1][x+1] && fog[y+1][x+1]) return 16;
1434 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;
1435 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;
1436 if (fog[y - 1][x] && fog[y + 1][x] && !fog[y - 1][x + 1] && !fog[y + 1][x + 1]) return 4;
1437 if (fog[y - 1][x] && fog[y + 1][x] && !fog[y - 1][x - 1] && !fog[y + 1][x - 1]) return 6;
1439 if (fog[y][x + 1] && fog[y + 1][x] && !fog[y + 1][x + 1]) return 1;
1440 if (fog[y][x - 1] && fog[y + 1][x] && !fog[y + 1][x - 1]) return 3;
1441 if (fog[y][x + 1] && fog[y - 1][x] && !fog[y - 1][x + 1]) return 7;
1442 if (fog[y][x - 1] && fog[y - 1][x] && !fog[y - 1][x - 1]) return 9;
1444 if (!fog[y][x + 1]) return 4;
1445 if (!fog[y][x - 1]) return 6;
1446 if (!fog[y - 1][x]) return 8;
1447 if (!fog[y + 1][x]) return 2;
1449 return 5;
1451 void draw_scent(SDL_Renderer *screen) {
1453 int tx, ty;
1454 for (ty = 0; ty < LEVEL_H; ty++) {
1455 for (tx = 0; tx < LEVEL_W; tx++) {
1457 Uint32 x = tx * TILE_W - ui.vx + game_map.x;
1458 Uint32 y = ty * TILE_H - ui.vy + game_map.y;
1459 int n;
1460 SDL_Color color = { 0xff, 0xff, 0x00, 0x33 };
1461 color.b = scent_human[ty][tx]/10;
1463 for (n = 0; n < scent_human[ty][tx]/16; n++)
1465 SDL_AlphaFill(screen, x + rand()%TILE_W/4, y + rand()%TILE_H/4, TILE_W, TILE_H, &color);
1470 void draw_fog(SDL_Renderer *screen) {
1472 int tx, ty;
1473 Uint8 fols_x[20] = {-1, 0, 1, 2, 0, 1, 2, 0, 1, 2, 1, 0, 1, 2, 0, 1, 2, 0, 1, 2 };
1474 Uint8 fols_y[20] = { 0, 0, 0, 0, 1, 1, 1, 2, 2, 2, 1, 3, 3, 3, 4, 4, 4, 5, 5, 5 };
1476 for (ty = 0; ty < LEVEL_H; ty++) {
1477 for (tx = 0; tx < LEVEL_W; tx++) {
1479 Uint32 x = tx * TILE_W - ui.vx + game_map.x;
1480 Uint32 y = ty * TILE_H - ui.vy + game_map.y;
1482 Uint8 f = foglet(tx, ty);
1483 fog[ty][tx] = f;
1485 draw_tile(screen, TILE_FOG_Y + fols_y[f], TILE_FOG_X + fols_x[f], x, y);
1491 void draw_log(SDL_Renderer *renderer, log_t *log) {
1493 int i;
1495 Uint32 y = ui.log_height - 16;
1497 for (i = 0; i < 16; i++) {
1499 //incolor(log->color[i], 0);
1500 infont(mid_font);
1501 incolor(0xffffffff, 0);
1502 inprint(renderer, log->message[i], 0, y);
1504 y -= 16;
1507 infont(large_font);
1511 void draw_ui(SDL_Renderer *screen) {
1512 SDL_Rect src = { 0, 0, 640, 480 };
1513 SDL_Rect dst = { 0, 0, ui.log_width, ui.log_height };
1515 if (ui.draw_uibg)
1516 SDL_RenderCopy(screen, uibg, &src, &dst);
1518 draw_goldbox(screen, 2, 3, 0, your->ore);
1519 draw_goldbox(screen, 80, 3, 1, your->gold);
1521 draw_minimap(screen);
1523 if (ui.unit != -1) draw_unitbox(screen);
1524 else if (ui.house != -1) draw_housebox(screen);
1525 else if (ui.flag != -1) draw_flagbox(screen);
1526 else {
1527 draw_buildset(screen);
1528 draw_pinbox(screen);
1531 if (ui.hint != -1) draw_hintbox(screen);
1533 if (ui.draw_log) draw_log(screen, &gamelog);
1536 void draw_screen(SDL_Renderer *screen) {
1538 SDL_SetRenderDrawColor(screen, 0x11, 0x33, 0x11, 255);
1539 SDL_RenderClear(screen);
1541 draw_houses(screen);
1543 draw_units(screen);
1545 if (ui.draw_fog) draw_fog(screen);
1546 if (ui.draw_scent) draw_scent(screen);
1548 draw_flags(screen);
1550 draw_particles(screen, 100,100);
1552 if (ui.draw_overlays) draw_overlays(screen, ui.unit, 0, 0, NULL);
1554 if (ui.draw_path) draw_paths(screen, ui.unit, 0, 0);
1556 if (ui.draw_pools) draw_pools(screen);
1558 if (ui.setflag > -1) draw_setflag(screen);
1559 if (ui.builder > -1) draw_builder(screen);
1560 if (ui.stat > -1) draw_forcible(screen);
1562 draw_ui(screen);
1564 /* FPS: */
1565 infont(small_font);
1566 incolor(0xffffff, 0);
1567 rprintf(screen, ui.log_width - ui.log_width / 2, 4, "FPS: %d", ui.fps);