diff --git a/src/game/boe.graphics.cpp b/src/game/boe.graphics.cpp index 47f322483..2935e21b7 100644 --- a/src/game/boe.graphics.cpp +++ b/src/game/boe.graphics.cpp @@ -19,6 +19,7 @@ #include "gfx/render_shapes.hpp" #include "gfx/render_text.hpp" #include "gfx/tiling.hpp" +#include "gfx/graphics.hpp" #include "sounds.hpp" #include "mathutil.hpp" #include "dialogxml/widgets/button.hpp" @@ -102,6 +103,8 @@ short debug_nums[6] = {0,0,0,0,0,0}; char light_area[13][13]; char unexplored_area[13][13]; +size_t out_max_dim = 96; // 2x2 combined grid of outdoor sections + // Declare the graphics sf::RenderTexture& pc_stats_gworld() { static sf::RenderTexture instance; @@ -802,6 +805,10 @@ bool is_nature(short x, short y, unsigned short ground_t) { std::vector forcecage_locs; extern std::list posted_labels; +size_t cur_town_max_dim() { + return univ.town->max_dim; +} + //mode ... if 1, don't place on screen after redoing // if 2, only redraw over active monst void draw_terrain(short mode) { @@ -989,10 +996,10 @@ void draw_terrain(short mode) { if(is_town() || is_combat()) draw_items(where_draw); if(is_out() && univ.out.out_e[where_draw.x][where_draw.y] && univ.out.is_road(where_draw.x,where_draw.y)) - place_road(q,r,where_draw,true); + place_road(terrain_screen_gworld(),q,r,where_draw,true,true); else if(is_town() && univ.town.is_explored(where_draw.x,where_draw.y) && univ.town.is_road(where_draw.x, where_draw.y)) - place_road(q,r,where_draw,true); - else place_road(q,r,where_draw,false); + place_road(terrain_screen_gworld(),q,r,where_draw,true,false); + else place_road(terrain_screen_gworld(),q,r,where_draw,false,is_out()); draw_fields(where_draw); //draw_monsters(where_draw); //draw_vehicles(where_draw); @@ -1287,31 +1294,18 @@ void draw_trim(short q,short r,short which_trim,ter_num_t ground_ter) { rect_draw_some_item(*from_gworld, from_rect, *mask, terrain_screen_gworld(), to_rect); } - -static bool extend_road_terrain(int x, int y) { +bool is_road(int x, int y) { if(is_out() && univ.out.is_road(x,y)) return true; if(is_town() && univ.town.is_road(x,y)) return true; - ter_num_t ter = coord_to_ter(x,y); - eTrimType trim = univ.scenario.ter_types[ter].trim_type; - eTerSpec spec = univ.scenario.ter_types[ter].special; - ter_num_t flag = univ.scenario.ter_types[ter].flag1; - if(trim == eTrimType::CITY || trim == eTrimType::WALKWAY) - return true; - if(spec == eTerSpec::BRIDGE) - return true; - if(spec == eTerSpec::TOWN_ENTRANCE && trim != eTrimType::NONE) - return true; // cave entrance, most likely - if(spec == eTerSpec::UNLOCKABLE || spec == eTerSpec::CHANGE_WHEN_STEP_ON) - return true; // closed door, possibly locked; or closed portcullis - if(spec == eTerSpec::CHANGE_WHEN_USED && univ.scenario.ter_types[flag].special == eTerSpec::CHANGE_WHEN_STEP_ON && univ.scenario.ter_types[flag].flag1 == ter) - return true; // open door (I think) TODO: Verify this works - if(spec == eTerSpec::LOCKABLE) - return true; // open portcullis (most likely) return false; } +const cTerrain& get_ter_type(ter_num_t t) { + return univ.scenario.ter_types[t]; +} + static bool can_build_roads_on(ter_num_t ter) { if(impassable(ter)) return false; if(univ.scenario.ter_types[ter].special == eTerSpec::BRIDGE) return false; @@ -1329,60 +1323,6 @@ static bool connect_roads(ter_num_t ter){ return false; } -void place_road(short q,short r,location where,bool here) { - rectangle to_rect; - static const rectangle road_rects[5] = { - {76,28,80,41}, // horizontal partial - {72,60,90,64}, // vertical partial - {72,28,75,56}, // horizontal full - {72,56,108,60}, // vertical full - {80,28,84,32}, // central spot - }; - static const rectangle road_dest_rects[7] = { - {0,12,18,16}, // top - {16,15,20,28}, // right - {18,12,36,16}, // bottom - {16,0,20,13}, // left - {0,12,36,16}, // top + bottom - {16,0,20,28}, // right + left - {16,12,20,16}, // central spot - }; - - sf::Texture& roads_gworld = *ResMgr::graphics.get("fields"); - - if(here){ - to_rect = road_dest_rects[6]; - to_rect.offset(13 + q * 28,13 + r * 36); - rect_draw_some_item(roads_gworld, road_rects[4], terrain_screen_gworld(), to_rect); - - if((where.y == 0) || extend_road_terrain(where.x, where.y - 1)) { - to_rect = road_dest_rects[0]; - to_rect.offset(13 + q * 28,13 + r * 36); - rect_draw_some_item (roads_gworld, road_rects[1], terrain_screen_gworld(), to_rect); - } - - if(((is_out()) && (where.x == 96)) || (!(is_out()) && (where.x == univ.town->max_dim - 1)) - || extend_road_terrain(where.x + 1, where.y)) { - to_rect = road_dest_rects[1]; - to_rect.offset(13 + q * 28,13 + r * 36); - rect_draw_some_item (roads_gworld, road_rects[0], terrain_screen_gworld(), to_rect); - } - - if(((is_out()) && (where.y == 96)) || (!(is_out()) && (where.y == univ.town->max_dim - 1)) - || extend_road_terrain(where.x, where.y + 1)) { - to_rect = road_dest_rects[2]; - to_rect.offset(13 + q * 28,13 + r * 36); - rect_draw_some_item (roads_gworld, road_rects[1], terrain_screen_gworld(), to_rect); - } - - if((where.x == 0) || extend_road_terrain(where.x - 1, where.y)) { - to_rect = road_dest_rects[3]; - to_rect.offset(13 + q * 28,13 + r * 36); - rect_draw_some_item (roads_gworld, road_rects[0], terrain_screen_gworld(), to_rect); - } - } -} - void draw_rest_screen() { eGameMode store_mode; diff --git a/src/gfx/graphics.cpp b/src/gfx/graphics.cpp new file mode 100644 index 000000000..e1ab6da12 --- /dev/null +++ b/src/gfx/graphics.cpp @@ -0,0 +1,95 @@ +#include "graphics.hpp" + +#include "fileio/resmgr/res_image.hpp" +#include "render_image.hpp" +#include "scenario/terrain.hpp" + +extern bool is_road(int x, int y); +extern ter_num_t coord_to_ter(short x, short y); +extern const cTerrain& get_ter_type(ter_num_t t); +extern size_t cur_town_max_dim(); +extern size_t out_max_dim; + +bool extend_road_terrain(int x, int y) { + if(is_road(x, y)) return true; + ter_num_t ter = coord_to_ter(x,y); + const cTerrain& type = get_ter_type(ter); + eTrimType trim = type.trim_type; + eTerSpec spec = type.special; + ter_num_t flag = type.flag1; + if(trim == eTrimType::CITY || trim == eTrimType::WALKWAY) + return true; + if(spec == eTerSpec::BRIDGE) + return true; + if(spec == eTerSpec::TOWN_ENTRANCE && trim != eTrimType::NONE) + return true; // cave entrance, most likely + if(spec == eTerSpec::UNLOCKABLE || spec == eTerSpec::CHANGE_WHEN_STEP_ON) + return true; // closed door, possibly locked; or closed portcullis + if(spec == eTerSpec::CHANGE_WHEN_USED){ + const cTerrain& to_type = get_ter_type(flag); + if(to_type.special == eTerSpec::CHANGE_WHEN_STEP_ON && to_type.flag1 == ter) + return true; // open door (I think) TODO: Verify this works + } + if(spec == eTerSpec::LOCKABLE) + return true; // open portcullis (most likely) + return false; +} + +void place_road(sf::RenderTarget& targ, short q,short r,location where,bool here,bool is_out, location screen_offset) { + rectangle to_rect; + static const rectangle road_rects[5] = { + {76,28,80,41}, // horizontal partial + {72,60,90,64}, // vertical partial + {72,28,75,56}, // horizontal full + {72,56,108,60}, // vertical full + {80,28,84,32}, // central spot + }; + static const rectangle road_dest_rects[7] = { + {0,12,18,16}, // top + {16,15,20,28}, // right + {18,12,36,16}, // bottom + {16,0,20,13}, // left + {0,12,36,16}, // top + bottom + {16,0,20,28}, // right + left + {16,12,20,16}, // central spot + }; + + sf::Texture& roads_gworld = *ResMgr::graphics.get("fields"); + + if(here){ + to_rect = road_dest_rects[6]; + to_rect.offset(13 + q * 28,13 + r * 36); + to_rect.offset(screen_offset); + rect_draw_some_item(roads_gworld, road_rects[4], targ, to_rect); + + if((where.y == 0) || extend_road_terrain(where.x, where.y - 1)) { + to_rect = road_dest_rects[0]; + to_rect.offset(13 + q * 28,13 + r * 36); + to_rect.offset(screen_offset); + rect_draw_some_item (roads_gworld, road_rects[1], targ, to_rect); + } + + if((is_out && (where.x == out_max_dim)) || (!is_out && (where.x == cur_town_max_dim() - 1)) + || extend_road_terrain(where.x + 1, where.y)) { + to_rect = road_dest_rects[1]; + to_rect.offset(13 + q * 28,13 + r * 36); + to_rect.offset(screen_offset); + rect_draw_some_item (roads_gworld, road_rects[0], targ, to_rect); + } + + if((is_out && (where.y == out_max_dim)) || (!is_out && (where.y == cur_town_max_dim() - 1)) + || extend_road_terrain(where.x, where.y + 1)) { + to_rect = road_dest_rects[2]; + to_rect.offset(13 + q * 28,13 + r * 36); + to_rect.offset(screen_offset); + rect_draw_some_item (roads_gworld, road_rects[1], targ, to_rect); + } + + if((where.x == 0) || extend_road_terrain(where.x - 1, where.y)) { + to_rect = road_dest_rects[3]; + to_rect.offset(13 + q * 28,13 + r * 36); + to_rect.offset(screen_offset); + rect_draw_some_item (roads_gworld, road_rects[0], targ, to_rect); + } + } +} diff --git a/src/gfx/graphics.hpp b/src/gfx/graphics.hpp new file mode 100644 index 000000000..1a3d82c4e --- /dev/null +++ b/src/gfx/graphics.hpp @@ -0,0 +1,11 @@ +#ifndef BOE_SHARED_GRAPHICS_H +#define BOE_SHARED_GRAPHICS_H + +#include +#include "location.hpp" +#include "tools/framerate_limiter.hpp" + +bool extend_road_terrain(int x, int y); +void place_road(sf::RenderTarget& targ, short q,short r,location where,bool here, bool is_out, location screen_offset = {0,0}); + +#endif \ No newline at end of file diff --git a/src/scenedit/scen.graphics.cpp b/src/scenedit/scen.graphics.cpp index b7a4f50c6..41de10a11 100644 --- a/src/scenedit/scen.graphics.cpp +++ b/src/scenedit/scen.graphics.cpp @@ -9,6 +9,7 @@ #include "gfx/render_shapes.hpp" #include "gfx/render_text.hpp" #include "gfx/tiling.hpp" // for bg +#include "gfx/graphics.hpp" #include "scen.graphics.hpp" #include #include "scen.keydlgs.hpp" @@ -1014,6 +1015,16 @@ static ter_num_t ter_at(int q, int r) { return t_to_draw; } +const cTerrain& get_ter_type(ter_num_t t) { + return scenario.ter_types[t]; +} + +size_t cur_town_max_dim() { + return town->max_dim; +} + +size_t out_max_dim = 48; + void draw_terrain(){ location which_pt,where_draw; rectangle draw_rect,clipping_rect = {8,8,332,260}; @@ -1048,8 +1059,11 @@ void draw_terrain(){ sf::Texture& vehicle_gworld = *ResMgr::graphics.get("vehicle"); // TODO this doesn't work for the 1 row/column of adjacent outdoor sections drawn - if(is_road(cen_x + q - 4,cen_y + r - 4)) - rect_draw_some_item(fields_gworld, calc_rect(0, 2), mainPtr(), destrec, sf::BlendAlpha); + if(is_road(cen_x + q - 4,cen_y + r - 4)){ + // TODO subtracting from the TER_RECT_UL coords by 6, which I picked through trial and error and is still + // a bit off! + place_road(mainPtr(), q, r, loc(q + cen_x - 4, r + cen_y - 4), true, !editing_town, loc(TER_RECT_UL_X - 6, TER_RECT_UL_Y - 6)); + } if(is_spot(cen_x + q - 4,cen_y + r - 4)) rect_draw_some_item(fields_gworld, calc_rect(4, 0), mainPtr(), destrec, sf::BlendAlpha); @@ -1895,7 +1909,7 @@ bool is_spot(short i,short j){ return false; } -bool is_road(short i,short j){ +bool is_road(int i,int j){ if(editing_town) return is_field_type(i,j,SPECIAL_ROAD); else if(i >= 0 && i < 48 && j >= 0 && j < 48) diff --git a/src/scenedit/scen.graphics.hpp b/src/scenedit/scen.graphics.hpp index 8cd683e82..5441562e6 100644 --- a/src/scenedit/scen.graphics.hpp +++ b/src/scenedit/scen.graphics.hpp @@ -34,7 +34,7 @@ void make_field_type(short i,short j,eFieldType field_type,field_stroke_t& strok void take_field_type(short i,short j,eFieldType field_type,clear_field_stroke_t& stroke); bool container_there(location l); bool is_spot(short i,short j); -bool is_road(short i,short j); +bool is_road(int i,int j); short string_length(char *str); rectangle get_custom_rect (short which_rect); void init_dialogs();