From bb16c32bde58cba70e4877aa2d3ebd04332eb575 Mon Sep 17 00:00:00 2001 From: jacopograndi Date: Tue, 4 Jan 2022 13:35:02 +0100 Subject: linux compile and imgs --- graphics/cam.h | 26 +- graphics/graphics.cpp | 1586 ++++++++++++++++++++++++------------------------- graphics/graphics.h | 156 ++--- 3 files changed, 884 insertions(+), 884 deletions(-) (limited to 'graphics') diff --git a/graphics/cam.h b/graphics/cam.h index e3e158f..3f1496f 100644 --- a/graphics/cam.h +++ b/graphics/cam.h @@ -1,14 +1,14 @@ -#ifndef CAM_H -#define CAM_H - -#include - - -class Cam { - public: - Cam () { pos = vec2(); scale = 1; } - vec2 pos; - float scale; -}; - +#ifndef CAM_H +#define CAM_H + +#include + + +class Cam { + public: + Cam () { pos = vec2(); scale = 1; } + vec2 pos; + float scale; +}; + #endif \ No newline at end of file diff --git a/graphics/graphics.cpp b/graphics/graphics.cpp index fa0c9c8..823668a 100644 --- a/graphics/graphics.cpp +++ b/graphics/graphics.cpp @@ -1,794 +1,794 @@ -#include -#include -#include - -#include - -#include "graphics.h" -#include "../game/menu.h" -#include "../game/tile.h" -#include "../game/constants.h" - -Graphics::~Graphics () { -} - -void Graphics::present () { - backend.present(); -} - -void render_ent (Graphics *graphics, Gst &gst, Entity &ent, - vec2 pos, int dflag) -{ - Player &player = gst.players[ent.owner]; - float bound_y = ent.info->spritebounds.y; - if (ent.info->unit == 0) { bound_y = player.level*16+16; } - int done = 0; - if (dflag == 1) done = 512; - graphics->backend.render_sprite( - (int)ent.info->spritebounds.x, - (int)bound_y+done, 16, 16, - (int)pos.x, (int)pos.y, 32, 32 - ); - if (dflag == 0) { - graphics->backend.render_sprite( - (int)ent.info->spritebounds.x, - (int)bound_y+768, 16, 16, - (int)pos.x, (int)pos.y, 32, 32, - player.r, player.g, player.b - ); - } -} - -void render_ents (Graphics *graphics, Gst &gst, int unit) { - std::vector &entities = gst.entities; - for (int i=0; iunit != unit) continue; - Player &player = gst.players[entities[i].owner]; - int dflag = 0; - if (unit) dflag = entities[i].done; - vec2 pos { - graphics->cam.pos.x + entities[i].x*32, - graphics->cam.pos.y + entities[i].y*32 - }; - render_ent(graphics, gst, entities[i], pos, dflag); - } -} - -void render_menu (Graphics *graphics, Gst &gst, Menu &menu) { - vec2 res { (float)graphics->resx, (float)graphics->resy }; - if (menu.active) { - vec2 pos { res }; - float height = menu.options.size() * 20; - vec2 size { 120, height+10 }; - pos *= 0.5f; - pos -= size/2; - graphics->backend.render_rect( - 255,255,255,255, - menu.pos.x,menu.pos.y,menu.size.x,menu.size.y - ); - float acc = 0; - for (Option opt : menu.options) { - int r=0, g=0, b=0; - if (opt.id == menu.over) { - Player &player = gst.players[gst.turn]; - r = player.r; g = player.g; b = player.b; - } - graphics->backend.txt.render_text( - opt.name, menu.pos + vec2 {10, 10 + acc}, r, g, b); - float width = graphics->backend.txt.get_width(opt.name); - if (opt.cost.size() > 0) { - graphics->backend.txt.render_text( - std::to_string((int)roundf(opt.cost[0])) + "f", - menu.pos + vec2 { width + 20, 10 + acc }); - graphics->backend.txt.render_text( - std::to_string((int)roundf(opt.cost[1])) + "g", - menu.pos + vec2 { width + 50, 10 + acc }); - } - acc += 20; - } - } -} - -void render_menu_tech (Graphics *graphics, Gst &gst, View &view) { - vec2 res { (float)graphics->resx, (float)graphics->resy }; - if (view.menu_tech.active) { - vec2 pos { res }; - float height = view.menu_tech.options.size() * 20; - vec2 size { 120, height+10 }; - pos *= 0.5f; - pos -= size/2; - graphics->backend.render_rect( - 255,255,255,255, - view.menu_tech.pos.x,view.menu_tech.pos.y, - view.menu_tech.size.x,view.menu_tech.size.y - ); - - float x = 0, y = 0; - for (auto v : view.menu_tech.tech_opt_ordered) { - for (auto opt : v) { - int r=0, g=0, b=0; - Player &player = gst.players[gst.turn]; - if (opt.tech->id == view.menu_tech.over) { - r = player.r; g = player.g; b = player.b; - } - if (!gst.check_req_tech(opt.tech, player)) { - r = 100; g = 100; b = 100; - } - if (player.has_tech(opt.tech->id)) { - r = constants::col_gud_r; - g = constants::col_gud_g; - b = constants::col_gud_b; - } - graphics->backend.txt.render_text(opt.name, - view.menu_tech.pos + vec2 {10 + x, 10 + y}, r, g, b); - float width = graphics->backend.txt.get_width(opt.name); - /* - if (opt.tech->cost.size() > 0) { - graphics->backend.txt.render_text( - std::to_string (opt.tech->cost[0]) + "f", - view.menu_tech.pos + vec2 { width + 20 + x, 10 + y }); - graphics->backend.txt.render_text( - std::to_string (opt.tech->cost[1]) + "g", - view.menu_tech.pos + vec2 { width + 50 + x, 10 + y }); - }*/ - y += 10; - } - x += 150; y = 0; - } - } -} - - -int get_entity_info_height (Entity &ent) { - return 155+10*ent.info->abilities.size(); -} - -void render_entity_info (Graphics *graphics, Gst &gst, vec2 pos, int i) { - Entity &ent = gst.entities[i]; - Player &player = gst.players[ent.owner]; - auto &tech = player.tech_lookup; - int id = ent.info->id; - int w = 200, h = get_entity_info_height(ent); - - graphics->backend.render_rect (0,0,0,255, - (int)pos.x,(int)pos.y,w,h); - graphics->backend.render_rect (255,255,255,255, - (int)pos.x+1,(int)pos.y+1,w-2,h-2); - - graphics->backend.render_rect ( - 0,0,0,255, (int)pos.x+w-32-10-1, (int)pos.y+10-1,34,34); - graphics->backend.render_rect ( - 255,255,255,255, (int)pos.x+w-32-10, (int)pos.y+10,32,32); - - render_ent(graphics, gst, ent, vec2 { w-32-10.0f, 10 } + pos, 0); - - graphics->backend.txt.render_text(ent.info->name, pos + vec2 { 10, 10 }); - graphics->backend.txt.render_text("Attack", pos + vec2 { 10, 30 }); - float attack = ent.info->attack * (1+tech.id(id).attack); - graphics->backend.txt.render_text( - std::to_string((int)roundf(attack)), pos + vec2 { 90, 30 }); - graphics->backend.txt.render_text("Defence", pos + vec2 { 10, 45 }); - float defence = ent.info->defence * (1+tech.id(id).defence); - graphics->backend.txt.render_text( - std::to_string((int)roundf(defence)), pos + vec2 { 90, 45 }); - graphics->backend.txt.render_text("Move", pos + vec2 { 10, 60 }); - int move = ent.info->move + tech.id(id).move; - graphics->backend.txt.render_text( - std::to_string(move), pos + vec2 { 90, 60 }); - graphics->backend.txt.render_text("Range", pos + vec2 { 10, 75 }); - int range = ent.info->range + tech.id(id).range; - graphics->backend.txt.render_text( - std::to_string(range), pos + vec2 { 90, 75 }); - graphics->backend.txt.render_text("Sight", pos + vec2 { 10, 90 }); - int sight = ent.info->sight + tech.id(id).sight; - graphics->backend.txt.render_text( - std::to_string(sight), pos + vec2 { 90, 90 }); - graphics->backend.txt.render_text("Health", pos + vec2 { 10, 105 }); - graphics->backend.txt.render_text( - std::to_string((int)roundf(ent.hp)), pos + vec2 { 90, 105 }); - graphics->backend.txt.render_text("Class", pos + vec2 { 10, 120 }); - std::string ent_class = ""; - switch (ent.info->ent_class) { - case EntityInfo::Class::inf: ent_class = "Infantry"; break; - case EntityInfo::Class::cav: ent_class = "Cavalry"; break; - case EntityInfo::Class::ran: ent_class = "Ranged"; break; - case EntityInfo::Class::sie: ent_class = "Siege"; break; - case EntityInfo::Class::bld: ent_class = "Building"; break; - } - graphics->backend.txt.render_text(ent_class, pos + vec2 { 90, 120 }); - graphics->backend.txt.render_text("Abilities", pos + vec2 { 10, 135 }); - std::string abname; - for (int s=0; sabilities.size(); s++) { - abname = gst.inv->abilities[ent.info->abilities[s]].name; - graphics->backend.txt.render_text(abname, - pos + vec2 { 90, 135+s*10.0f }); - } -} - -void render_tile_info (Graphics *graphics, Gst &gst, vec2 pos, int i) { - int x = i % gst.inv->ground.sizex; - int y = i / gst.inv->ground.sizex; - Tile &tile = gst.inv->tiles[gst.inv->ground.tiles[gst.inv->ground.at(x,y)]]; - - int w = 200, h = 95; - graphics->backend.render_rect ( - 0,0,0,255, - (int)pos.x,(int)pos.y,w,h - ); - graphics->backend.render_rect ( - 255,255,255,255, - (int)pos.x+1,(int)pos.y+1,w-2,h-2 - ); - - graphics->backend.render_sprite ( - (int)tile.spritebounds.x, - (int)tile.spritebounds.y-16, 16, 32, - (int)pos.x + w-32-10, - (int)pos.y + 10-32, 32, 64 - ); - - graphics->backend.txt.render_text(tile.name, pos + vec2 { 10, 10 }); - graphics->backend.txt.render_text("Move", pos + vec2 { 10, 30 }); - graphics->backend.txt.render_text( - std::to_string(tile.move_cost), pos + vec2 { 90, 30 }); - graphics->backend.txt.render_text("Sight", pos + vec2 { 10, 45 }); - graphics->backend.txt.render_text( - std::to_string(tile.sight_cost), pos + vec2 { 90, 45 }); - graphics->backend.txt.render_text("Defence Bonus", pos + vec2 { 10, 60 }); - graphics->backend.txt.render_text( - std::to_string((int)roundf(tile.defence_bonus*100))+"%", pos + vec2 { 90, 60 }); - graphics->backend.txt.render_text("Range Bonus", pos + vec2 { 10, 75 }); - graphics->backend.txt.render_text( - std::to_string(tile.range_bonus), pos + vec2 { 90, 75 }); -} - -int render_attack_info_bonus (Graphics *graphics, Gst &gst, vec2 pos, - Entity &atk, Entity &def, bool attack, int rtl) -{ - float margin_amt = constants::menu_attack_margin_amt; - float margin_arrow = constants::menu_attack_margin_arrow; - float margin_mod = constants::menu_attack_margin_mod; - - std::vector bonuses; - if (attack) { bonuses = gst.get_bonuses(atk, def); } - else { bonuses = gst.get_bonuses(def, atk); } - - float value = attack ? atk.info->attack : atk.info->defence; - - { - std::string nlabel = attack ? "Attack" : "Defence"; - float labw = graphics->backend.txt.get_width(nlabel); - graphics->backend.txt.render_text(nlabel, - pos + vec2 { -labw*rtl, 0 }); - } { - std::string nlabel = std::to_string((int)roundf(value)); - float labw = graphics->backend.txt.get_width(nlabel); - graphics->backend.txt.render_text(nlabel, - pos + vec2 { margin_amt*(1-rtl*2)-labw*rtl, 0 }); - } - - int bonusnum = 0; float atk_mod = 1; - for (int s=0; sbackend.txt.get_width(b.id_string()); - graphics->backend.txt.render_text( - b.id_string(), pos + vec2 { -idw*rtl, 10.0f+bonusnum*10 }); - std::string amt; - if (b.amt > 0) amt += "+"; - amt += std::to_string((int)roundf(b.amt*100)) + "%"; - float labw = graphics->backend.txt.get_width(amt); - graphics->backend.txt.render_text( - amt, pos + vec2 { - margin_amt*(1-rtl*2)-labw*rtl, - 10.0f+bonusnum*10 }); - atk_mod += b.amt; - bonusnum ++; - } - } - - if (bonusnum > 0) { - { - std::string label = rtl ? "<-" : "->"; - float labw = graphics->backend.txt.get_width(label); - graphics->backend.txt.render_text(label, - pos + vec2 { margin_arrow*(1-rtl*2)-labw*rtl, 0 }); - } - { - std::string label = std::to_string((int)roundf(value * atk_mod)); - float labw = graphics->backend.txt.get_width(label); - graphics->backend.txt.render_text(label, - pos + vec2 { margin_mod*(1-rtl*2)-labw*rtl, 0 }); - } - } - - return bonusnum*10; -} - - -void render_attack_info (Graphics *graphics, Gst &gst, vec2 pos, int i, int j) { - float margin_amt = constants::menu_attack_margin_amt; - float margin_arrow = constants::menu_attack_margin_arrow; - float margin_mod = constants::menu_attack_margin_mod; - - Entity &atk = gst.entities[i]; - Entity &def = gst.entities[j]; - int w = 300, h = 250; - - graphics->backend.render_rect (0,0,0,255, - (int)pos.x,(int)pos.y,w,h); - graphics->backend.render_rect (255,255,255,255, - (int)pos.x+1,(int)pos.y+1,w-2,h-2); - - graphics->backend.render_rect ( - 0,0,0,255, (int)pos.x+10-1, (int)pos.y+35-1,34,34); - graphics->backend.render_rect ( - 255,255,255,255, (int)pos.x+10, (int)pos.y+35,32,32); - graphics->backend.render_sprite ( - (int)atk.info->spritebounds.x, - (int)atk.info->spritebounds.y, 16, 16, - (int)pos.x + 10, - (int)pos.y + 35, 32, 32 - ); - { - Tile &tile = gst.inv->tiles[gst.inv->ground.tiles[ - gst.inv->ground.at(atk.x,atk.y)]]; - graphics->backend.render_sprite ( - (int)tile.spritebounds.x, - (int)tile.spritebounds.y-16, 16, 32, - (int)pos.x + 52, - (int)pos.y + 35-32, 32, 64 - ); - } - - graphics->backend.render_rect ( - 0,0,0,255, (int)pos.x+w-42-1, (int)pos.y+35-1,34,34); - graphics->backend.render_rect ( - 255,255,255,255, (int)pos.x+w-42, (int)pos.y+35,32,32); - graphics->backend.render_sprite ( - (int)def.info->spritebounds.x, - (int)def.info->spritebounds.y, 16, 16, - (int)pos.x + w-42, - (int)pos.y + 35, 32, 32 - ); - { - Tile &tile = gst.inv->tiles[gst.inv->ground.tiles[ - gst.inv->ground.at(def.x,def.y)]]; - graphics->backend.render_sprite ( - (int)tile.spritebounds.x, - (int)tile.spritebounds.y-16, 16, 32, - (int)pos.x + w-84, - (int)pos.y + 35-32, 32, 64 - ); - } - - graphics->backend.txt.render_text(atk.info->name, pos + vec2 { 10, 10 }); - { - int txtwidth = graphics->backend.txt.get_width(def.info->name); - graphics->backend.txt.render_text(def.info->name, - pos + vec2 { w-10.0f-txtwidth, 10 }); - } - - BattleResult result = gst.battle_res(atk, def); - std::vector sres = { "++", "+", "=", "-", "--" }; - float atk_loss = atk.hp-result.atk_hp; - float def_loss = def.hp-result.def_hp; - float est_atk = def_loss - atk_loss; - float est_def = atk_loss - def_loss; - int atk_res = 2; - int def_res = 2; - if (est_atk > 40) { atk_res = 0; } - else if (est_atk > 5) { atk_res = 1; } - if (est_atk < -40) { atk_res = 4; } - else if (est_atk < -5) { atk_res = 3; } - if (est_def > 40) { def_res = 0; } - else if (est_def > 5) { def_res = 1; } - if (est_def < -40) { def_res = 4; } - else if (est_def < -5) { def_res = 3; } - - graphics->backend.txt.render_text("Health", pos + vec2 { 10, 80 }); - graphics->backend.txt.render_text( - std::to_string((int)roundf(atk.hp)), - pos + vec2 { 10+margin_amt, 80 }); - graphics->backend.txt.render_text("->", - pos + vec2 { 10+margin_arrow, 80 }); - graphics->backend.txt.render_text( - std::to_string((int)roundf(result.atk_hp)), - pos + vec2 { 10+margin_mod, 80 }); - graphics->backend.txt.render_text( - sres[atk_res], - pos + vec2 { 10+margin_mod+20, 80 }); - { - int txtwidth = graphics->backend.txt.get_width("Health"); - graphics->backend.txt.render_text("Health", - pos + vec2 { w-10.0f-txtwidth, 80 }); - std::string label = std::to_string((int)roundf(def.hp)); - int txtwidthlabel = graphics->backend.txt.get_width(label); - graphics->backend.txt.render_text(label, - pos + vec2 { w-10.0f-margin_amt-txtwidthlabel, 80 }); - } { - int txtwidth = graphics->backend.txt.get_width("<-"); - graphics->backend.txt.render_text("<-", - pos + vec2 { w-10.0f-margin_arrow-txtwidth, 80 }); - } { - std::string label = std::to_string((int)roundf(result.def_hp)); - int txtwidth = graphics->backend.txt.get_width(label); - graphics->backend.txt.render_text(label, - pos + vec2 { w-10.0f-margin_mod-txtwidth, 80 }); - } { - int txtwidth = graphics->backend.txt.get_width(sres[def_res]); - graphics->backend.txt.render_text(sres[def_res], - pos + vec2 { w-10.0f-margin_mod-20-txtwidth, 80 }); - } - - { - int batkh = render_attack_info_bonus(graphics, gst, - pos + vec2 { 10, 95 }, atk, def, true, 0); - int bdefh = render_attack_info_bonus(graphics, gst, - pos + vec2 { 10, 95 + batkh + 15.0f }, atk, def, false, 0); - } { - int batkh = render_attack_info_bonus(graphics, gst, - pos + vec2 { w-10.0f, 95 }, def, atk, true, 1); - int bdefh = render_attack_info_bonus(graphics, gst, - pos + vec2 { w-10.0f, 95 + batkh + 15.0f }, def, atk, false, 1); - } -} - -void Graphics::render (Gst &gst, View &view) -{ - Ground &gr = gst.inv->ground; - std::vector &entities = gst.entities; - vec2 res { (float)resx, (float)resy }; - - for (int y=0; ytiles[gr.tiles[gr.at(x,y)]]; - backend.render_sprite( - (int)tile.spritebounds.x, - (int)tile.spritebounds.y, 16, 16, - (int)cam.pos.x + x*32, (int)cam.pos.y + y*32, 32, 32 - ); - } - } - - for (Resource res : gr.resources) { - int x = res.pos % gr.sizex; - int y = res.pos / gr.sizex; - backend.render_sprite( - 16*res.kind, 16*2, 16, 16, - (int)cam.pos.x + x*32, (int)cam.pos.y + y*32, 32, 32 - ); - } - - render_ents(this, gst, 0); - render_ents(this, gst, 1); - - /* overlay */ - for (int y=0; ytiles[gr.tiles[gr.at(x,y)]]; - backend.render_sprite( - (int)tile.spritebounds.x, - (int)tile.spritebounds.y-16, 16, 16, - (int)cam.pos.x + x*32, (int)cam.pos.y + y*32-32, 32, 32 - ); - } - } - - if (view.selected_entity != -1) { - int i = view.selected_entity; - Entity &ent = entities[i]; - Player &player = gst.get_player(ent.owner); - float bound_y = ent.info->spritebounds.y; - if (ent.info->unit == 0) { bound_y = player.level*16+16; } - vec2 pos { (float)ent.x*32, (float)ent.y*32 }; - backend.render_sprite ( - (int)ent.info->spritebounds.x, - (int)bound_y+256, 16, 16, - (int)cam.pos.x + (int)pos.x, - (int)cam.pos.y + (int)pos.y, 32, 32 - ); - } - - if (view.selected_ground != -1) { - int x = view.selected_ground % gr.sizex; - int y = view.selected_ground / gr.sizex; - vec2 pos { (float)x*32, (float)y*32 }; - Tile &tile = gst.inv->tiles[gr.tiles[gr.at(x,y)]]; - backend.render_sprite( - (int)tile.spritebounds.x, - (int)tile.spritebounds.y+256-16, 16, 32, - (int)cam.pos.x + (int)pos.x, - (int)cam.pos.y + (int)pos.y-32, 32, 64 - ); - } - - for (int i=0; iunit == 1) { - backend.render_rect( - 0, 0, 0, 255, - (int)cam.pos.x + (int)ent.x*32+2, - (int)cam.pos.y + (int)ent.y*32+30, 28, 2 - ); - int amt = 28 * (entities[i].hp / 100); - Player &player = gst.get_player(ent.owner); - backend.render_rect( - player.r, player.g, player.b, 255, - (int)cam.pos.x + (int)ent.x*32+2, - (int)cam.pos.y + (int)ent.y*32+30, amt, 2 - ); - } - } - - render_menu(this, gst, view.menu_unit); - render_menu(this, gst, view.menu_day); - render_menu(this, gst, view.menu_build); - render_menu(this, gst, view.menu_train); - render_menu(this, gst, view.menu_trade); - render_menu(this, gst, view.menu_age_up); - render_menu_tech(this, gst, view); - - if (view.moves.size() > 0) { - for (int m : view.moves) { - int x = m % gr.sizex; int y = m / gr.sizex; - backend.render_rect( - 0, 120, 255, 100, - (int)cam.pos.x + x*32, (int)cam.pos.y + y*32, 32, 32 - ); - } - } - - if (view.attacks.size() > 0) { - for (int m : view.attacks) { - int x = m % gr.sizex; int y = m / gr.sizex; - backend.render_rect( - 255, 120, 0, 100, - (int)cam.pos.x + x*32, (int)cam.pos.y + y*32, 32, 32 - ); - } - } - - if (view.heals.size() > 0) { - for (int m : view.heals) { - int x = m % gr.sizex; int y = m / gr.sizex; - backend.render_rect( - 0, 200, 0, 100, - (int)cam.pos.x + x*32, (int)cam.pos.y + y*32, 32, 32 - ); - } - } - - if (view.converts.size() > 0) { - for (int m : view.converts) { - int x = m % gr.sizex; int y = m / gr.sizex; - backend.render_rect( - 200, 0, 200, 100, - (int)cam.pos.x + x*32, (int)cam.pos.y + y*32, 32, 32 - ); - } - } - - // top bar - vec2 pos { 0,0 }; - backend.render_rect ( - 255,255,255,255, - (int)pos.x,(int)pos.y,(int)res.x, 30 - ); - Player &player = gst.players[gst.turn]; - backend.render_rect ( - player.r, player.g, player.b, 255, - (int)pos.x+5,(int)pos.y+5, 20, 20 - ); - std::string txtfood = std::to_string((int)roundf(player.res[0])) + "f"; - std::string txtgold = std::to_string((int)roundf(player.res[1])) + "g"; - backend.txt.render_text( - txtfood, pos + vec2 { -backend.txt.get_width(txtfood) + res.x/2-10, 10 } - ); - backend.txt.render_text(txtgold, pos + vec2 { res.x/2+10, 10 }); - std::string txtres = "Researching: "; - if (player.researching != -1) { - txtres += gst.inv->get_tech(player.researching)->name; - } else { txtres += "None"; } - float reswidth = backend.txt.get_width(txtres); - backend.txt.render_text(txtres, pos + vec2 { res.x-reswidth-10, 10 }); - - // low bar - backend.render_rect ( - 255,255,255,255, - 0,(int)res.y-30,(int)res.x, 30 - ); - - // info stack box - int info_ground = -1; - if (view.hover_ground != -1) { info_ground = view.hover_ground; } - if (view.selected_entity != -1) { - int i = view.selected_entity; - info_ground = gr.at(entities[i].x, entities[i].y); - } - if (view.selected_ground != -1) { info_ground = view.selected_ground; } - - if (info_ground != -1) { - int unit = -1; - int bld = -1; - int x = info_ground % gr.sizex; - int y = info_ground / gr.sizex; - for (int i=0; i < gst.entities.size(); i++) { - Entity &ent = gst.entities[i]; - if (ent.x == x && ent.y == y) { - if (ent.info->unit) { unit = i; } - else { bld = i; } - } - } - - float hoff = -95; - if (bld != -1) hoff -= get_entity_info_height(gst.entities[bld]); - if (unit != -1) hoff -= get_entity_info_height(gst.entities[unit]); - - if (unit != -1) { - render_entity_info(this, gst, vec2 { 0, res.y-30+hoff }, unit); - hoff += get_entity_info_height(gst.entities[unit]); - } - if (bld != -1) { - render_entity_info(this, gst, vec2 { 0, res.y-30+hoff }, bld); - hoff += get_entity_info_height(gst.entities[bld]); - } - render_tile_info(this, gst, vec2 { 0, res.y-30+hoff }, info_ground); - } - - if (view.attacks.size() > 0 && view.hover_ground != -1) { - int def = -1; - int x = view.hover_ground % gr.sizex; - int y = view.hover_ground / gr.sizex; - for (int i=0; i < gst.entities.size(); i++) { - Entity &ent = gst.entities[i]; - if (ent.x == x && ent.y == y && ent.owner != gst.turn) { - def = i; break; - } - } - if (def != -1) { - render_attack_info(this, gst, vec2 { res.x/2-175, res.y/2-125 }, - view.selected_entity, def); - } - } -} - - -Graphics_sdl::Graphics_sdl (int resx, int resy) { - SDL_Init(SDL_INIT_VIDEO); - - SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "0"); - - window = SDL_CreateWindow("age", SDL_WINDOWPOS_UNDEFINED, - SDL_WINDOWPOS_UNDEFINED, resx, resy, SDL_WINDOW_SHOWN - | SDL_WINDOW_RESIZABLE); - screenSurface = SDL_GetWindowSurface(window); - - rend = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED); - SDL_SetRenderDrawBlendMode(rend, SDL_BLENDMODE_BLEND); - - load_sheet(); - - txt.gRenderer = rend; -} - -Graphics_sdl::~Graphics_sdl () { - SDL_DestroyWindow(window); - SDL_Quit(); -} - -SDL_Renderer* Graphics_sdl::get_renderer () { return rend; } - -void Graphics_sdl::present () { - SDL_RenderPresent(rend); - SDL_SetRenderDrawColor(rend, 0, 0, 0, 255); - SDL_RenderClear(rend); -} - -void Graphics_sdl::load_sheet () { - SDL_Surface* surf = SDL_LoadBMP("content/sprites.bmp"); - SDL_SetColorKey(surf, SDL_TRUE, SDL_MapRGB(surf ->format,255,0,255)); - if (!surf) { - std::cout << "Error loading image: " << SDL_GetError() << std::endl; - system("pause"); - return; - } - txsprites = SDL_CreateTextureFromSurface(rend, surf); - SDL_FreeSurface(surf); - - SDL_Surface* surftext = SDL_LoadBMP("content/gf.bmp"); - SDL_SetColorKey(surftext, SDL_TRUE, SDL_MapRGB(surftext ->format,255,0,255)); - if (!surftext) { - std::cout << "Error loading image: " << SDL_GetError() << std::endl; - system("pause"); - return; - } - txt.tex = SDL_CreateTextureFromSurface(rend, surftext); - SDL_FreeSurface(surftext); -} - -void Graphics_sdl::render_sprite ( - int x, int y, int w, int h, - int u, int v, int s, int t) -{ - SDL_Rect srcRect = { x, y, w, h }; - SDL_Rect dstRect = { u, v, s, t }; - SDL_RenderCopy(rend, txsprites, &srcRect, &dstRect); -} - -void Graphics_sdl::render_sprite ( - int x, int y, int w, int h, - int u, int v, int s, int t, - int r, int g, int b) -{ - SDL_SetTextureColorMod(txsprites, r, g, b); - render_sprite(x, y, w, h, u, v, s, t); - SDL_SetTextureColorMod(txsprites, 255, 255, 255); -} - -void Graphics_sdl::render_rect ( - int r, int g, int b, int a, - int x, int y, int w, int h) -{ - SDL_SetRenderDrawColor(rend, r, g, b, a); - SDL_Rect rect = { x, y, w, h }; - SDL_RenderFillRect(rend, &rect); -} - - - -Graphics_sdl_text::Graphics_sdl_text () { - for (int i=0; i<128; char_width[i++]=5); - char_width['('] = 2; char_width[')'] = 2; - char_width['['] = 2; char_width[']'] = 2; - char_width['{'] = 3; char_width['}'] = 3; - char_width[','] = 1; char_width['-'] = 5; char_width['.'] = 1; - char_width['/'] = 4; char_width['!'] = 1; - char_width[':'] = 1; char_width[';'] = 1; - char_width['%'] = 4; - char_width['<'] = 3; char_width['>'] = 3; char_width['='] = 4; - char_width['I'] = 1; - char_width['f'] = 4; char_width['i'] = 1; char_width['j'] = 3; - char_width['l'] = 1; char_width['k'] = 4; char_width['t'] = 4; -} - -int Graphics_sdl_text::get_width (std::string str) { - int width = 0; - for (int i=0; str[i]!='\0'; i++) { - width += char_width[str[i]]; - if (str[i+1]!='\0') width++; - } - return width; -} - -void Graphics_sdl_text::render_text (std::string str, vec2 off) { - render_text(str, off, 0, 0, 0); -} - -void Graphics_sdl_text::render_text (std::string str, vec2 off, - int r, int g, int b) -{ - SDL_SetTextureColorMod(tex, r, g, b); - int width = 0; - for (int i=0; str[i]!='\0'; i++) { - int char_i = str[i]; - SDL_Rect srcRect = { (char_i%32)*6+1, (char_i/32)*12+1, 5, 11 }; - SDL_Rect dstRect = { (int)off.x+width, (int)off.y, 5, 11 }; - SDL_RenderCopy(gRenderer, tex, &srcRect, &dstRect); - width += char_width[char_i]+1; - } -} - -/* -void render_text_scaled (SDL_Renderer* rend, char str[], - float off[], txtd *t, float scale) -{ - int width = 0; - for (int i=0; str[i]!='\0'; i++) { - int char_i = str[i]; - SDL_Rect srcRect = { (char_i%32)*6+1, (char_i/32)*12+1, 5, 11 }; - SDL_Rect dstRect = { off[0]+width, off[1], 5*scale, 11*scale }; - SDL_RenderCopy(rend, t->tex, &srcRect, &dstRect); - width += t->cw[char_i]*scale+1*scale; - } +#include +#include +#include + +#include + +#include "graphics.h" +#include "../game/menu.h" +#include "../game/tile.h" +#include "../game/constants.h" + +Graphics::~Graphics () { +} + +void Graphics::present () { + backend.present(); +} + +void render_ent (Graphics *graphics, Gst &gst, Entity &ent, + vec2 pos, int dflag) +{ + Player &player = gst.players[ent.owner]; + float bound_y = ent.info->spritebounds.y; + if (ent.info->unit == 0) { bound_y = player.level*16+16; } + int done = 0; + if (dflag == 1) done = 512; + graphics->backend.render_sprite( + (int)ent.info->spritebounds.x, + (int)bound_y+done, 16, 16, + (int)pos.x, (int)pos.y, 32, 32 + ); + if (dflag == 0) { + graphics->backend.render_sprite( + (int)ent.info->spritebounds.x, + (int)bound_y+768, 16, 16, + (int)pos.x, (int)pos.y, 32, 32, + player.r, player.g, player.b + ); + } +} + +void render_ents (Graphics *graphics, Gst &gst, int unit) { + std::vector &entities = gst.entities; + for (int i=0; iunit != unit) continue; + Player &player = gst.players[entities[i].owner]; + int dflag = 0; + if (unit) dflag = entities[i].done; + vec2 pos { + graphics->cam.pos.x + entities[i].x*32, + graphics->cam.pos.y + entities[i].y*32 + }; + render_ent(graphics, gst, entities[i], pos, dflag); + } +} + +void render_menu (Graphics *graphics, Gst &gst, Menu &menu) { + vec2 res { (float)graphics->resx, (float)graphics->resy }; + if (menu.active) { + vec2 pos { res }; + float height = menu.options.size() * 20; + vec2 size { 120, height+10 }; + pos *= 0.5f; + pos -= size/2; + graphics->backend.render_rect( + 255,255,255,255, + menu.pos.x,menu.pos.y,menu.size.x,menu.size.y + ); + float acc = 0; + for (Option opt : menu.options) { + int r=0, g=0, b=0; + if (opt.id == menu.over) { + Player &player = gst.players[gst.turn]; + r = player.r; g = player.g; b = player.b; + } + graphics->backend.txt.render_text( + opt.name, menu.pos + vec2 {10, 10 + acc}, r, g, b); + float width = graphics->backend.txt.get_width(opt.name); + if (opt.cost.size() > 0) { + graphics->backend.txt.render_text( + std::to_string((int)roundf(opt.cost[0])) + "f", + menu.pos + vec2 { width + 20, 10 + acc }); + graphics->backend.txt.render_text( + std::to_string((int)roundf(opt.cost[1])) + "g", + menu.pos + vec2 { width + 50, 10 + acc }); + } + acc += 20; + } + } +} + +void render_menu_tech (Graphics *graphics, Gst &gst, View &view) { + vec2 res { (float)graphics->resx, (float)graphics->resy }; + if (view.menu_tech.active) { + vec2 pos { res }; + float height = view.menu_tech.options.size() * 20; + vec2 size { 120, height+10 }; + pos *= 0.5f; + pos -= size/2; + graphics->backend.render_rect( + 255,255,255,255, + view.menu_tech.pos.x,view.menu_tech.pos.y, + view.menu_tech.size.x,view.menu_tech.size.y + ); + + float x = 0, y = 0; + for (auto v : view.menu_tech.tech_opt_ordered) { + for (auto opt : v) { + int r=0, g=0, b=0; + Player &player = gst.players[gst.turn]; + if (opt.tech->id == view.menu_tech.over) { + r = player.r; g = player.g; b = player.b; + } + if (!gst.check_req_tech(opt.tech, player)) { + r = 100; g = 100; b = 100; + } + if (player.has_tech(opt.tech->id)) { + r = constants::col_gud_r; + g = constants::col_gud_g; + b = constants::col_gud_b; + } + graphics->backend.txt.render_text(opt.name, + view.menu_tech.pos + vec2 {10 + x, 10 + y}, r, g, b); + float width = graphics->backend.txt.get_width(opt.name); + /* + if (opt.tech->cost.size() > 0) { + graphics->backend.txt.render_text( + std::to_string (opt.tech->cost[0]) + "f", + view.menu_tech.pos + vec2 { width + 20 + x, 10 + y }); + graphics->backend.txt.render_text( + std::to_string (opt.tech->cost[1]) + "g", + view.menu_tech.pos + vec2 { width + 50 + x, 10 + y }); + }*/ + y += 10; + } + x += 150; y = 0; + } + } +} + + +int get_entity_info_height (Entity &ent) { + return 155+10*ent.info->abilities.size(); +} + +void render_entity_info (Graphics *graphics, Gst &gst, vec2 pos, int i) { + Entity &ent = gst.entities[i]; + Player &player = gst.players[ent.owner]; + auto &tech = player.tech_lookup; + int id = ent.info->id; + int w = 200, h = get_entity_info_height(ent); + + graphics->backend.render_rect (0,0,0,255, + (int)pos.x,(int)pos.y,w,h); + graphics->backend.render_rect (255,255,255,255, + (int)pos.x+1,(int)pos.y+1,w-2,h-2); + + graphics->backend.render_rect ( + 0,0,0,255, (int)pos.x+w-32-10-1, (int)pos.y+10-1,34,34); + graphics->backend.render_rect ( + 255,255,255,255, (int)pos.x+w-32-10, (int)pos.y+10,32,32); + + render_ent(graphics, gst, ent, vec2 { w-32-10.0f, 10 } + pos, 0); + + graphics->backend.txt.render_text(ent.info->name, pos + vec2 { 10, 10 }); + graphics->backend.txt.render_text("Attack", pos + vec2 { 10, 30 }); + float attack = ent.info->attack * (1+tech.id(id).attack); + graphics->backend.txt.render_text( + std::to_string((int)roundf(attack)), pos + vec2 { 90, 30 }); + graphics->backend.txt.render_text("Defence", pos + vec2 { 10, 45 }); + float defence = ent.info->defence * (1+tech.id(id).defence); + graphics->backend.txt.render_text( + std::to_string((int)roundf(defence)), pos + vec2 { 90, 45 }); + graphics->backend.txt.render_text("Move", pos + vec2 { 10, 60 }); + int move = ent.info->move + tech.id(id).move; + graphics->backend.txt.render_text( + std::to_string(move), pos + vec2 { 90, 60 }); + graphics->backend.txt.render_text("Range", pos + vec2 { 10, 75 }); + int range = ent.info->range + tech.id(id).range; + graphics->backend.txt.render_text( + std::to_string(range), pos + vec2 { 90, 75 }); + graphics->backend.txt.render_text("Sight", pos + vec2 { 10, 90 }); + int sight = ent.info->sight + tech.id(id).sight; + graphics->backend.txt.render_text( + std::to_string(sight), pos + vec2 { 90, 90 }); + graphics->backend.txt.render_text("Health", pos + vec2 { 10, 105 }); + graphics->backend.txt.render_text( + std::to_string((int)roundf(ent.hp)), pos + vec2 { 90, 105 }); + graphics->backend.txt.render_text("Class", pos + vec2 { 10, 120 }); + std::string ent_class = ""; + switch (ent.info->ent_class) { + case EntityInfo::Class::inf: ent_class = "Infantry"; break; + case EntityInfo::Class::cav: ent_class = "Cavalry"; break; + case EntityInfo::Class::ran: ent_class = "Ranged"; break; + case EntityInfo::Class::sie: ent_class = "Siege"; break; + case EntityInfo::Class::bld: ent_class = "Building"; break; + } + graphics->backend.txt.render_text(ent_class, pos + vec2 { 90, 120 }); + graphics->backend.txt.render_text("Abilities", pos + vec2 { 10, 135 }); + std::string abname; + for (int s=0; sabilities.size(); s++) { + abname = gst.inv->abilities[ent.info->abilities[s]].name; + graphics->backend.txt.render_text(abname, + pos + vec2 { 90, 135+s*10.0f }); + } +} + +void render_tile_info (Graphics *graphics, Gst &gst, vec2 pos, int i) { + int x = i % gst.inv->ground.sizex; + int y = i / gst.inv->ground.sizex; + Tile &tile = gst.inv->tiles[gst.inv->ground.tiles[gst.inv->ground.at(x,y)]]; + + int w = 200, h = 95; + graphics->backend.render_rect ( + 0,0,0,255, + (int)pos.x,(int)pos.y,w,h + ); + graphics->backend.render_rect ( + 255,255,255,255, + (int)pos.x+1,(int)pos.y+1,w-2,h-2 + ); + + graphics->backend.render_sprite ( + (int)tile.spritebounds.x, + (int)tile.spritebounds.y-16, 16, 32, + (int)pos.x + w-32-10, + (int)pos.y + 10-32, 32, 64 + ); + + graphics->backend.txt.render_text(tile.name, pos + vec2 { 10, 10 }); + graphics->backend.txt.render_text("Move", pos + vec2 { 10, 30 }); + graphics->backend.txt.render_text( + std::to_string(tile.move_cost), pos + vec2 { 90, 30 }); + graphics->backend.txt.render_text("Sight", pos + vec2 { 10, 45 }); + graphics->backend.txt.render_text( + std::to_string(tile.sight_cost), pos + vec2 { 90, 45 }); + graphics->backend.txt.render_text("Defence Bonus", pos + vec2 { 10, 60 }); + graphics->backend.txt.render_text( + std::to_string((int)roundf(tile.defence_bonus*100))+"%", pos + vec2 { 90, 60 }); + graphics->backend.txt.render_text("Range Bonus", pos + vec2 { 10, 75 }); + graphics->backend.txt.render_text( + std::to_string(tile.range_bonus), pos + vec2 { 90, 75 }); +} + +int render_attack_info_bonus (Graphics *graphics, Gst &gst, vec2 pos, + Entity &atk, Entity &def, bool attack, int rtl) +{ + float margin_amt = constants::menu_attack_margin_amt; + float margin_arrow = constants::menu_attack_margin_arrow; + float margin_mod = constants::menu_attack_margin_mod; + + std::vector bonuses; + if (attack) { bonuses = gst.get_bonuses(atk, def); } + else { bonuses = gst.get_bonuses(def, atk); } + + float value = attack ? atk.info->attack : atk.info->defence; + + { + std::string nlabel = attack ? "Attack" : "Defence"; + float labw = graphics->backend.txt.get_width(nlabel); + graphics->backend.txt.render_text(nlabel, + pos + vec2 { -labw*rtl, 0 }); + } { + std::string nlabel = std::to_string((int)roundf(value)); + float labw = graphics->backend.txt.get_width(nlabel); + graphics->backend.txt.render_text(nlabel, + pos + vec2 { margin_amt*(1-rtl*2)-labw*rtl, 0 }); + } + + int bonusnum = 0; float atk_mod = 1; + for (int s=0; sbackend.txt.get_width(b.id_string()); + graphics->backend.txt.render_text( + b.id_string(), pos + vec2 { -idw*rtl, 10.0f+bonusnum*10 }); + std::string amt; + if (b.amt > 0) amt += "+"; + amt += std::to_string((int)roundf(b.amt*100)) + "%"; + float labw = graphics->backend.txt.get_width(amt); + graphics->backend.txt.render_text( + amt, pos + vec2 { + margin_amt*(1-rtl*2)-labw*rtl, + 10.0f+bonusnum*10 }); + atk_mod += b.amt; + bonusnum ++; + } + } + + if (bonusnum > 0) { + { + std::string label = rtl ? "<-" : "->"; + float labw = graphics->backend.txt.get_width(label); + graphics->backend.txt.render_text(label, + pos + vec2 { margin_arrow*(1-rtl*2)-labw*rtl, 0 }); + } + { + std::string label = std::to_string((int)roundf(value * atk_mod)); + float labw = graphics->backend.txt.get_width(label); + graphics->backend.txt.render_text(label, + pos + vec2 { margin_mod*(1-rtl*2)-labw*rtl, 0 }); + } + } + + return bonusnum*10; +} + + +void render_attack_info (Graphics *graphics, Gst &gst, vec2 pos, int i, int j) { + float margin_amt = constants::menu_attack_margin_amt; + float margin_arrow = constants::menu_attack_margin_arrow; + float margin_mod = constants::menu_attack_margin_mod; + + Entity &atk = gst.entities[i]; + Entity &def = gst.entities[j]; + int w = 300, h = 250; + + graphics->backend.render_rect (0,0,0,255, + (int)pos.x,(int)pos.y,w,h); + graphics->backend.render_rect (255,255,255,255, + (int)pos.x+1,(int)pos.y+1,w-2,h-2); + + graphics->backend.render_rect ( + 0,0,0,255, (int)pos.x+10-1, (int)pos.y+35-1,34,34); + graphics->backend.render_rect ( + 255,255,255,255, (int)pos.x+10, (int)pos.y+35,32,32); + graphics->backend.render_sprite ( + (int)atk.info->spritebounds.x, + (int)atk.info->spritebounds.y, 16, 16, + (int)pos.x + 10, + (int)pos.y + 35, 32, 32 + ); + { + Tile &tile = gst.inv->tiles[gst.inv->ground.tiles[ + gst.inv->ground.at(atk.x,atk.y)]]; + graphics->backend.render_sprite ( + (int)tile.spritebounds.x, + (int)tile.spritebounds.y-16, 16, 32, + (int)pos.x + 52, + (int)pos.y + 35-32, 32, 64 + ); + } + + graphics->backend.render_rect ( + 0,0,0,255, (int)pos.x+w-42-1, (int)pos.y+35-1,34,34); + graphics->backend.render_rect ( + 255,255,255,255, (int)pos.x+w-42, (int)pos.y+35,32,32); + graphics->backend.render_sprite ( + (int)def.info->spritebounds.x, + (int)def.info->spritebounds.y, 16, 16, + (int)pos.x + w-42, + (int)pos.y + 35, 32, 32 + ); + { + Tile &tile = gst.inv->tiles[gst.inv->ground.tiles[ + gst.inv->ground.at(def.x,def.y)]]; + graphics->backend.render_sprite ( + (int)tile.spritebounds.x, + (int)tile.spritebounds.y-16, 16, 32, + (int)pos.x + w-84, + (int)pos.y + 35-32, 32, 64 + ); + } + + graphics->backend.txt.render_text(atk.info->name, pos + vec2 { 10, 10 }); + { + int txtwidth = graphics->backend.txt.get_width(def.info->name); + graphics->backend.txt.render_text(def.info->name, + pos + vec2 { w-10.0f-txtwidth, 10 }); + } + + BattleResult result = gst.battle_res(atk, def); + std::vector sres = { "++", "+", "=", "-", "--" }; + float atk_loss = atk.hp-result.atk_hp; + float def_loss = def.hp-result.def_hp; + float est_atk = def_loss - atk_loss; + float est_def = atk_loss - def_loss; + int atk_res = 2; + int def_res = 2; + if (est_atk > 40) { atk_res = 0; } + else if (est_atk > 5) { atk_res = 1; } + if (est_atk < -40) { atk_res = 4; } + else if (est_atk < -5) { atk_res = 3; } + if (est_def > 40) { def_res = 0; } + else if (est_def > 5) { def_res = 1; } + if (est_def < -40) { def_res = 4; } + else if (est_def < -5) { def_res = 3; } + + graphics->backend.txt.render_text("Health", pos + vec2 { 10, 80 }); + graphics->backend.txt.render_text( + std::to_string((int)roundf(atk.hp)), + pos + vec2 { 10+margin_amt, 80 }); + graphics->backend.txt.render_text("->", + pos + vec2 { 10+margin_arrow, 80 }); + graphics->backend.txt.render_text( + std::to_string((int)roundf(result.atk_hp)), + pos + vec2 { 10+margin_mod, 80 }); + graphics->backend.txt.render_text( + sres[atk_res], + pos + vec2 { 10+margin_mod+20, 80 }); + { + int txtwidth = graphics->backend.txt.get_width("Health"); + graphics->backend.txt.render_text("Health", + pos + vec2 { w-10.0f-txtwidth, 80 }); + std::string label = std::to_string((int)roundf(def.hp)); + int txtwidthlabel = graphics->backend.txt.get_width(label); + graphics->backend.txt.render_text(label, + pos + vec2 { w-10.0f-margin_amt-txtwidthlabel, 80 }); + } { + int txtwidth = graphics->backend.txt.get_width("<-"); + graphics->backend.txt.render_text("<-", + pos + vec2 { w-10.0f-margin_arrow-txtwidth, 80 }); + } { + std::string label = std::to_string((int)roundf(result.def_hp)); + int txtwidth = graphics->backend.txt.get_width(label); + graphics->backend.txt.render_text(label, + pos + vec2 { w-10.0f-margin_mod-txtwidth, 80 }); + } { + int txtwidth = graphics->backend.txt.get_width(sres[def_res]); + graphics->backend.txt.render_text(sres[def_res], + pos + vec2 { w-10.0f-margin_mod-20-txtwidth, 80 }); + } + + { + int batkh = render_attack_info_bonus(graphics, gst, + pos + vec2 { 10, 95 }, atk, def, true, 0); + int bdefh = render_attack_info_bonus(graphics, gst, + pos + vec2 { 10, 95 + batkh + 15.0f }, atk, def, false, 0); + } { + int batkh = render_attack_info_bonus(graphics, gst, + pos + vec2 { w-10.0f, 95 }, def, atk, true, 1); + int bdefh = render_attack_info_bonus(graphics, gst, + pos + vec2 { w-10.0f, 95 + batkh + 15.0f }, def, atk, false, 1); + } +} + +void Graphics::render (Gst &gst, View &view) +{ + Ground &gr = gst.inv->ground; + std::vector &entities = gst.entities; + vec2 res { (float)resx, (float)resy }; + + for (int y=0; ytiles[gr.tiles[gr.at(x,y)]]; + backend.render_sprite( + (int)tile.spritebounds.x, + (int)tile.spritebounds.y, 16, 16, + (int)cam.pos.x + x*32, (int)cam.pos.y + y*32, 32, 32 + ); + } + } + + for (Resource res : gr.resources) { + int x = res.pos % gr.sizex; + int y = res.pos / gr.sizex; + backend.render_sprite( + 16*res.kind, 16*2, 16, 16, + (int)cam.pos.x + x*32, (int)cam.pos.y + y*32, 32, 32 + ); + } + + render_ents(this, gst, 0); + render_ents(this, gst, 1); + + /* overlay */ + for (int y=0; ytiles[gr.tiles[gr.at(x,y)]]; + backend.render_sprite( + (int)tile.spritebounds.x, + (int)tile.spritebounds.y-16, 16, 16, + (int)cam.pos.x + x*32, (int)cam.pos.y + y*32-32, 32, 32 + ); + } + } + + if (view.selected_entity != -1) { + int i = view.selected_entity; + Entity &ent = entities[i]; + Player &player = gst.get_player(ent.owner); + float bound_y = ent.info->spritebounds.y; + if (ent.info->unit == 0) { bound_y = player.level*16+16; } + vec2 pos { (float)ent.x*32, (float)ent.y*32 }; + backend.render_sprite ( + (int)ent.info->spritebounds.x, + (int)bound_y+256, 16, 16, + (int)cam.pos.x + (int)pos.x, + (int)cam.pos.y + (int)pos.y, 32, 32 + ); + } + + if (view.selected_ground != -1) { + int x = view.selected_ground % gr.sizex; + int y = view.selected_ground / gr.sizex; + vec2 pos { (float)x*32, (float)y*32 }; + Tile &tile = gst.inv->tiles[gr.tiles[gr.at(x,y)]]; + backend.render_sprite( + (int)tile.spritebounds.x, + (int)tile.spritebounds.y+256-16, 16, 32, + (int)cam.pos.x + (int)pos.x, + (int)cam.pos.y + (int)pos.y-32, 32, 64 + ); + } + + for (int i=0; iunit == 1) { + backend.render_rect( + 0, 0, 0, 255, + (int)cam.pos.x + (int)ent.x*32+2, + (int)cam.pos.y + (int)ent.y*32+30, 28, 2 + ); + int amt = 28 * (entities[i].hp / 100); + Player &player = gst.get_player(ent.owner); + backend.render_rect( + player.r, player.g, player.b, 255, + (int)cam.pos.x + (int)ent.x*32+2, + (int)cam.pos.y + (int)ent.y*32+30, amt, 2 + ); + } + } + + render_menu(this, gst, view.menu_unit); + render_menu(this, gst, view.menu_day); + render_menu(this, gst, view.menu_build); + render_menu(this, gst, view.menu_train); + render_menu(this, gst, view.menu_trade); + render_menu(this, gst, view.menu_age_up); + render_menu_tech(this, gst, view); + + if (view.moves.size() > 0) { + for (int m : view.moves) { + int x = m % gr.sizex; int y = m / gr.sizex; + backend.render_rect( + 0, 120, 255, 100, + (int)cam.pos.x + x*32, (int)cam.pos.y + y*32, 32, 32 + ); + } + } + + if (view.attacks.size() > 0) { + for (int m : view.attacks) { + int x = m % gr.sizex; int y = m / gr.sizex; + backend.render_rect( + 255, 120, 0, 100, + (int)cam.pos.x + x*32, (int)cam.pos.y + y*32, 32, 32 + ); + } + } + + if (view.heals.size() > 0) { + for (int m : view.heals) { + int x = m % gr.sizex; int y = m / gr.sizex; + backend.render_rect( + 0, 200, 0, 100, + (int)cam.pos.x + x*32, (int)cam.pos.y + y*32, 32, 32 + ); + } + } + + if (view.converts.size() > 0) { + for (int m : view.converts) { + int x = m % gr.sizex; int y = m / gr.sizex; + backend.render_rect( + 200, 0, 200, 100, + (int)cam.pos.x + x*32, (int)cam.pos.y + y*32, 32, 32 + ); + } + } + + // top bar + vec2 pos { 0,0 }; + backend.render_rect ( + 255,255,255,255, + (int)pos.x,(int)pos.y,(int)res.x, 30 + ); + Player &player = gst.players[gst.turn]; + backend.render_rect ( + player.r, player.g, player.b, 255, + (int)pos.x+5,(int)pos.y+5, 20, 20 + ); + std::string txtfood = std::to_string((int)roundf(player.res[0])) + "f"; + std::string txtgold = std::to_string((int)roundf(player.res[1])) + "g"; + backend.txt.render_text( + txtfood, pos + vec2 { -backend.txt.get_width(txtfood) + res.x/2-10, 10 } + ); + backend.txt.render_text(txtgold, pos + vec2 { res.x/2+10, 10 }); + std::string txtres = "Researching: "; + if (player.researching != -1) { + txtres += gst.inv->get_tech(player.researching)->name; + } else { txtres += "None"; } + float reswidth = backend.txt.get_width(txtres); + backend.txt.render_text(txtres, pos + vec2 { res.x-reswidth-10, 10 }); + + // low bar + backend.render_rect ( + 255,255,255,255, + 0,(int)res.y-30,(int)res.x, 30 + ); + + // info stack box + int info_ground = -1; + if (view.hover_ground != -1) { info_ground = view.hover_ground; } + if (view.selected_entity != -1) { + int i = view.selected_entity; + info_ground = gr.at(entities[i].x, entities[i].y); + } + if (view.selected_ground != -1) { info_ground = view.selected_ground; } + + if (info_ground != -1) { + int unit = -1; + int bld = -1; + int x = info_ground % gr.sizex; + int y = info_ground / gr.sizex; + for (int i=0; i < gst.entities.size(); i++) { + Entity &ent = gst.entities[i]; + if (ent.x == x && ent.y == y) { + if (ent.info->unit) { unit = i; } + else { bld = i; } + } + } + + float hoff = -95; + if (bld != -1) hoff -= get_entity_info_height(gst.entities[bld]); + if (unit != -1) hoff -= get_entity_info_height(gst.entities[unit]); + + if (unit != -1) { + render_entity_info(this, gst, vec2 { 0, res.y-30+hoff }, unit); + hoff += get_entity_info_height(gst.entities[unit]); + } + if (bld != -1) { + render_entity_info(this, gst, vec2 { 0, res.y-30+hoff }, bld); + hoff += get_entity_info_height(gst.entities[bld]); + } + render_tile_info(this, gst, vec2 { 0, res.y-30+hoff }, info_ground); + } + + if (view.attacks.size() > 0 && view.hover_ground != -1) { + int def = -1; + int x = view.hover_ground % gr.sizex; + int y = view.hover_ground / gr.sizex; + for (int i=0; i < gst.entities.size(); i++) { + Entity &ent = gst.entities[i]; + if (ent.x == x && ent.y == y && ent.owner != gst.turn) { + def = i; break; + } + } + if (def != -1) { + render_attack_info(this, gst, vec2 { res.x/2-175, res.y/2-125 }, + view.selected_entity, def); + } + } +} + + +Graphics_sdl::Graphics_sdl (int resx, int resy) { + SDL_Init(SDL_INIT_VIDEO); + + SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "0"); + + window = SDL_CreateWindow("age", SDL_WINDOWPOS_UNDEFINED, + SDL_WINDOWPOS_UNDEFINED, resx, resy, SDL_WINDOW_SHOWN + | SDL_WINDOW_RESIZABLE); + screenSurface = SDL_GetWindowSurface(window); + + rend = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED); + SDL_SetRenderDrawBlendMode(rend, SDL_BLENDMODE_BLEND); + + load_sheet(); + + txt.gRenderer = rend; +} + +Graphics_sdl::~Graphics_sdl () { + SDL_DestroyWindow(window); + SDL_Quit(); +} + +SDL_Renderer* Graphics_sdl::get_renderer () { return rend; } + +void Graphics_sdl::present () { + SDL_RenderPresent(rend); + SDL_SetRenderDrawColor(rend, 0, 0, 0, 255); + SDL_RenderClear(rend); +} + +void Graphics_sdl::load_sheet () { + SDL_Surface* surf = SDL_LoadBMP("content/sprites.bmp"); + SDL_SetColorKey(surf, SDL_TRUE, SDL_MapRGB(surf ->format,255,0,255)); + if (!surf) { + std::cout << "Error loading image: " << SDL_GetError() << std::endl; + system("pause"); + return; + } + txsprites = SDL_CreateTextureFromSurface(rend, surf); + SDL_FreeSurface(surf); + + SDL_Surface* surftext = SDL_LoadBMP("content/gf.bmp"); + SDL_SetColorKey(surftext, SDL_TRUE, SDL_MapRGB(surftext ->format,255,0,255)); + if (!surftext) { + std::cout << "Error loading image: " << SDL_GetError() << std::endl; + system("pause"); + return; + } + txt.tex = SDL_CreateTextureFromSurface(rend, surftext); + SDL_FreeSurface(surftext); +} + +void Graphics_sdl::render_sprite ( + int x, int y, int w, int h, + int u, int v, int s, int t) +{ + SDL_Rect srcRect = { x, y, w, h }; + SDL_Rect dstRect = { u, v, s, t }; + SDL_RenderCopy(rend, txsprites, &srcRect, &dstRect); +} + +void Graphics_sdl::render_sprite ( + int x, int y, int w, int h, + int u, int v, int s, int t, + int r, int g, int b) +{ + SDL_SetTextureColorMod(txsprites, r, g, b); + render_sprite(x, y, w, h, u, v, s, t); + SDL_SetTextureColorMod(txsprites, 255, 255, 255); +} + +void Graphics_sdl::render_rect ( + int r, int g, int b, int a, + int x, int y, int w, int h) +{ + SDL_SetRenderDrawColor(rend, r, g, b, a); + SDL_Rect rect = { x, y, w, h }; + SDL_RenderFillRect(rend, &rect); +} + + + +Graphics_sdl_text::Graphics_sdl_text () { + for (int i=0; i<128; char_width[i++]=5); + char_width['('] = 2; char_width[')'] = 2; + char_width['['] = 2; char_width[']'] = 2; + char_width['{'] = 3; char_width['}'] = 3; + char_width[','] = 1; char_width['-'] = 5; char_width['.'] = 1; + char_width['/'] = 4; char_width['!'] = 1; + char_width[':'] = 1; char_width[';'] = 1; + char_width['%'] = 4; + char_width['<'] = 3; char_width['>'] = 3; char_width['='] = 4; + char_width['I'] = 1; + char_width['f'] = 4; char_width['i'] = 1; char_width['j'] = 3; + char_width['l'] = 1; char_width['k'] = 4; char_width['t'] = 4; +} + +int Graphics_sdl_text::get_width (std::string str) { + int width = 0; + for (int i=0; str[i]!='\0'; i++) { + width += char_width[str[i]]; + if (str[i+1]!='\0') width++; + } + return width; +} + +void Graphics_sdl_text::render_text (std::string str, vec2 off) { + render_text(str, off, 0, 0, 0); +} + +void Graphics_sdl_text::render_text (std::string str, vec2 off, + int r, int g, int b) +{ + SDL_SetTextureColorMod(tex, r, g, b); + int width = 0; + for (int i=0; str[i]!='\0'; i++) { + int char_i = str[i]; + SDL_Rect srcRect = { (char_i%32)*6+1, (char_i/32)*12+1, 5, 11 }; + SDL_Rect dstRect = { (int)off.x+width, (int)off.y, 5, 11 }; + SDL_RenderCopy(gRenderer, tex, &srcRect, &dstRect); + width += char_width[char_i]+1; + } +} + +/* +void render_text_scaled (SDL_Renderer* rend, char str[], + float off[], txtd *t, float scale) +{ + int width = 0; + for (int i=0; str[i]!='\0'; i++) { + int char_i = str[i]; + SDL_Rect srcRect = { (char_i%32)*6+1, (char_i/32)*12+1, 5, 11 }; + SDL_Rect dstRect = { off[0]+width, off[1], 5*scale, 11*scale }; + SDL_RenderCopy(rend, t->tex, &srcRect, &dstRect); + width += t->cw[char_i]*scale+1*scale; + } }*/ \ No newline at end of file diff --git a/graphics/graphics.h b/graphics/graphics.h index af8630a..a5b5eee 100644 --- a/graphics/graphics.h +++ b/graphics/graphics.h @@ -1,79 +1,79 @@ -#ifndef GRAPHICS_H -#define GRAPHICS_H - -#include -#include - -#define SDL_MAIN_HANDLED -#include - -#include "../game/gst.h" -#include "../game/view.h" -#include "cam.h" - -#include - - -class Graphics_sdl_text { - public: - Graphics_sdl_text(); - int get_width (std::string str); - void render_text (std::string str, vec2 off); - void render_text (std::string str, vec2 off, int r, int g, int b); - SDL_Renderer* gRenderer; - SDL_Texture *tex; - int char_width[128]; -}; - - -class Graphics_sdl { - public: - Graphics_sdl (int resx, int resy); - ~Graphics_sdl (); - SDL_Renderer* get_renderer (); - void load_sheet (); - void present (); - void change_res (int resx, int resy) { - SDL_SetWindowSize(window, resx, resy); - } - void render_sprite ( - int x, int y, int w, int h, - int u, int v, int s, int t); - void render_rect ( - int r, int g, int b, int a, - int x, int y, int w, int h); - void render_sprite ( - int x, int y, int w, int h, - int u, int v, int s, int t, - int r, int g, int b); - - Graphics_sdl_text txt; - - private: - SDL_Window* window = NULL; - SDL_Surface* screenSurface = NULL; - SDL_Renderer* rend = NULL; - SDL_Texture* txsprites = NULL; -}; - - -class Graphics { - public: - Graphics (int resx, int resy) - : resx(resx), resy(resy), backend(resx, resy) {} - ~Graphics (); - - Graphics_sdl backend; - - int resx, resy; - Cam cam; - - void render (Gst &gst, View &view); - void present (); - void change_res (int x, int y) { - resx = x; resy = y; - backend.change_res(x, y); - } -}; - +#ifndef GRAPHICS_H +#define GRAPHICS_H + +#include +#include + +#define SDL_MAIN_HANDLED +#include + +#include "../game/gst.h" +#include "../game/view.h" +#include "cam.h" + +#include + + +class Graphics_sdl_text { + public: + Graphics_sdl_text(); + int get_width (std::string str); + void render_text (std::string str, vec2 off); + void render_text (std::string str, vec2 off, int r, int g, int b); + SDL_Renderer* gRenderer; + SDL_Texture *tex; + int char_width[128]; +}; + + +class Graphics_sdl { + public: + Graphics_sdl (int resx, int resy); + ~Graphics_sdl (); + SDL_Renderer* get_renderer (); + void load_sheet (); + void present (); + void change_res (int resx, int resy) { + SDL_SetWindowSize(window, resx, resy); + } + void render_sprite ( + int x, int y, int w, int h, + int u, int v, int s, int t); + void render_rect ( + int r, int g, int b, int a, + int x, int y, int w, int h); + void render_sprite ( + int x, int y, int w, int h, + int u, int v, int s, int t, + int r, int g, int b); + + Graphics_sdl_text txt; + + private: + SDL_Window* window = NULL; + SDL_Surface* screenSurface = NULL; + SDL_Renderer* rend = NULL; + SDL_Texture* txsprites = NULL; +}; + + +class Graphics { + public: + Graphics (int resx, int resy) + : resx(resx), resy(resy), backend(resx, resy) {} + ~Graphics (); + + Graphics_sdl backend; + + int resx, resy; + Cam cam; + + void render (Gst &gst, View &view); + void present (); + void change_res (int x, int y) { + resx = x; resy = y; + backend.change_res(x, y); + } +}; + #endif \ No newline at end of file -- cgit v1.2.3-54-g00ecf