diff --git a/src/game/boe.graphics.cpp b/src/game/boe.graphics.cpp index 8c14eb8a..b3a3cff9 100644 --- a/src/game/boe.graphics.cpp +++ b/src/game/boe.graphics.cpp @@ -481,6 +481,9 @@ void end_startup() { } static void loadImageToRenderTexture(sf::RenderTexture& tex, std::string imgName) { + // Clear scale-aware text stored for the previous texture instance: + clear_scale_aware_text(tex); + sf::Texture& temp_gworld = *ResMgr::graphics.get(imgName); rectangle texrect(temp_gworld); tex.create(texrect.width(), texrect.height()); @@ -661,6 +664,7 @@ void put_text_bar(std::string str, std::string right_str) { text_bar_gworld.setActive(false); auto& bar_gw = *ResMgr::graphics.get("textbar"); rect_draw_some_item(bar_gw, rectangle(bar_gw), text_bar_gworld, rectangle(bar_gw)); + clear_scale_aware_text(text_bar_gworld); TextStyle style; style.colour = sf::Color::White; style.font = FONT_BOLD; @@ -696,7 +700,7 @@ void put_text_bar(std::string str, std::string right_str) { void refresh_text_bar() { mainPtr.setActive(false); - rect_draw_some_item(text_bar_gworld.getTexture(), rectangle(text_bar_gworld), mainPtr, win_to_rects[WINRECT_STATUS]); + rect_draw_some_item(text_bar_gworld, rectangle(text_bar_gworld), mainPtr, win_to_rects[WINRECT_STATUS]); mainPtr.setActive(); } diff --git a/src/game/boe.newgraph.cpp b/src/game/boe.newgraph.cpp index 130c03c4..d9033b48 100644 --- a/src/game/boe.newgraph.cpp +++ b/src/game/boe.newgraph.cpp @@ -708,11 +708,13 @@ void draw_shop_graphics(bool item_pressed, bool item_help_pressed, rectangle cli area_rect = rectangle(talk_gworld); talk_gworld.setActive(false); + // Only re-render on top of the item that is clicked: if(item_pressed || item_help_pressed) { clip_area_rect.offset(-area_rect.left, -area_rect.top); clip_rect(talk_gworld, clip_area_rect); } else { + clear_scale_aware_text(talk_gworld); frame_rect(talk_gworld, area_rect, Colours::BLACK); area_rect.inset(1,1); tileImage(talk_gworld, area_rect,bg[12]); @@ -870,7 +872,7 @@ void refresh_shopping() { rectangle from_rect(talk_gworld); rectangle to_rect = from_rect; to_rect.offset(talk_gword_offset_x, talk_gword_offset_y); - rect_draw_some_item(talk_gworld.getTexture(),from_rect,mainPtr,to_rect); + rect_draw_some_item(talk_gworld,from_rect,mainPtr,to_rect); } static void place_talk_face() { @@ -898,7 +900,7 @@ void click_talk_rect(word_rect_t word) { rectangle talkRect(talk_gworld), wordRect(word.rect); mainPtr.setActive(); - rect_draw_some_item(talk_gworld.getTexture(),talkRect,mainPtr,talk_area_rect); + rect_draw_some_item(talk_gworld,talkRect,mainPtr,talk_area_rect); wordRect.offset(talk_area_rect.topLeft()); wordRect.width() += 10; // Arbitrary extra space fixes #481 and shouldn't cause any problems TextStyle style; @@ -911,7 +913,7 @@ void click_talk_rect(word_rect_t word) { help_btn->draw(); mainPtr.display(); play_sound(37, time_in_ticks(5)); - rect_draw_some_item(talk_gworld.getTexture(),talkRect,mainPtr,talk_area_rect); + rect_draw_some_item(talk_gworld,talkRect,mainPtr,talk_area_rect); place_talk_face(); } @@ -935,6 +937,7 @@ void place_talk_str(std::string str_to_place,std::string str_to_place2,short col } area_rect = rectangle(talk_gworld); + clear_scale_aware_text(talk_gworld); frame_rect(talk_gworld, area_rect, sf::Color::Black); area_rect.inset(1,1); tileImage(talk_gworld, area_rect,bg[12]); @@ -1002,14 +1005,14 @@ void place_talk_str(std::string str_to_place,std::string str_to_place2,short col // Finally place processed graphics mainPtr.setActive(); - rect_draw_some_item(talk_gworld.getTexture(),oldRect,mainPtr,talk_area_rect); + rect_draw_some_item(talk_gworld,oldRect,mainPtr,talk_area_rect); // I have no idea what this check is for; I'm jsut preserving it in case it was important if(c_rect.right == 0) place_talk_face(); } void refresh_talking() { rectangle tempRect(talk_gworld); - rect_draw_some_item(talk_gworld.getTexture(),tempRect,mainPtr,talk_area_rect); + rect_draw_some_item(talk_gworld,tempRect,mainPtr,talk_area_rect); place_talk_face(); } diff --git a/src/game/boe.text.cpp b/src/game/boe.text.cpp index b8cfb6ea..4ba3ee5b 100644 --- a/src/game/boe.text.cpp +++ b/src/game/boe.text.cpp @@ -97,6 +97,7 @@ void put_pc_screen() { rectangle info_from = {0,1,12,13}, switch_from = {0, 13, 12, 25}; pc_stats_gworld.setActive(false); + clear_scale_aware_text(pc_stats_gworld); // First clean up gworld with pretty patterns sf::Texture& orig = *ResMgr::graphics.get("statarea"); @@ -219,6 +220,7 @@ void put_item_screen(eItemWinMode screen_num) { rectangle upper_frame_rect = {3,3,15,268}; item_stats_gworld.setActive(false); + clear_scale_aware_text(item_stats_gworld); // First clean up gworld with pretty patterns sf::Texture& orig = *ResMgr::graphics.get("inventory"); @@ -588,9 +590,9 @@ void refresh_stat_areas(short mode) { if(mode == 1) x = sf::BlendAdd; else x = sf::BlendNone; - rect_draw_some_item(pc_stats_gworld.getTexture(), rectangle(pc_stats_gworld), mainPtr, win_to_rects[WINRECT_PCSTATS], x); - rect_draw_some_item(item_stats_gworld.getTexture(), rectangle(item_stats_gworld), mainPtr, win_to_rects[WINRECT_INVEN], x); - rect_draw_some_item(text_area_gworld.getTexture(), rectangle(text_area_gworld), mainPtr, win_to_rects[WINRECT_TRANSCRIPT], x); + rect_draw_some_item(pc_stats_gworld, rectangle(pc_stats_gworld), mainPtr, win_to_rects[WINRECT_PCSTATS], x); + rect_draw_some_item(item_stats_gworld, rectangle(item_stats_gworld), mainPtr, win_to_rects[WINRECT_INVEN], x); + rect_draw_some_item(text_area_gworld, rectangle(text_area_gworld), mainPtr, win_to_rects[WINRECT_TRANSCRIPT], x); } rectangle get_stat_effect_rect(int code) { @@ -1068,6 +1070,7 @@ void print_buf () { rectangle store_text_rect,dest_rect,erase_rect = {2,2,136,255}; text_area_gworld.setActive(false); + clear_scale_aware_text(text_area_gworld); // First clean up gworld with pretty patterns tileImage(text_area_gworld, erase_rect,bg[6]); @@ -1084,7 +1087,7 @@ void print_buf () { sf::Text text(text_buffer[line_to_print].line, *ResMgr::fonts.get("plain"), 12); text.setColor(Colours::BLACK); text.setPosition(moveTo); - text_area_gworld.draw(text); + draw_scale_aware_text(text_area_gworld, text); num_lines_printed++; line_to_print++; if(line_to_print== TEXT_BUF_LEN) { diff --git a/src/gfx/render_image.cpp b/src/gfx/render_image.cpp index 5dec6fe8..e1a2c17b 100644 --- a/src/gfx/render_image.cpp +++ b/src/gfx/render_image.cpp @@ -14,6 +14,7 @@ #include "fileio/fileio.hpp" #include "gfx/render_shapes.hpp" +#include "winutil.hpp" sf::Shader maskShader; extern fs::path progDir; @@ -121,6 +122,32 @@ void rect_draw_some_item(const sf::Texture& src_gworld,rectangle src_rect,const rect_draw_some_item(src.getTexture(), dest_rect, targ_gworld, targ_rect, &maskShader); } +std::map> store_scale_aware_text; + +static void draw_stored_scale_aware_text(sf::RenderTexture& texture, sf::RenderTarget& dest_window, rectangle targ_rect) { + // Temporarily switch target window to its unscaled view to draw scale-aware text + sf::View view = dest_window.getView(); + dest_window.setView(dest_window.getDefaultView()); + std::vector stored_text = store_scale_aware_text[&texture]; + for(sf::Text str_to_draw : stored_text){ + sf::Vector2f position = str_to_draw.getPosition(); + position = position + sf::Vector2f {0.0f+targ_rect.left, 0.0f+targ_rect.top}; + str_to_draw.setPosition(position * (float)get_ui_scale()); + dest_window.draw(str_to_draw); + } + dest_window.setView(view); +} + +void rect_draw_some_item(sf::RenderTexture& src_render_gworld,rectangle src_rect,sf::RenderTarget& targ_gworld,rectangle targ_rect,sf::BlendMode mode) { + rect_draw_some_item(src_render_gworld.getTexture(), src_rect, targ_gworld, targ_rect, mode); + draw_stored_scale_aware_text(src_render_gworld, targ_gworld, targ_rect); +} + +void rect_draw_some_item(sf::RenderTexture& src_render_gworld,rectangle src_rect,const sf::Texture& mask_gworld,sf::RenderTarget& targ_gworld,rectangle targ_rect) { + rect_draw_some_item(src_render_gworld.getTexture(), src_rect, mask_gworld, targ_gworld, targ_rect); + draw_stored_scale_aware_text(src_render_gworld, targ_gworld, targ_rect); +} + void setActiveRenderTarget(sf::RenderTarget& where) { const std::type_info& type = typeid(where); if(type == typeid(sf::RenderWindow&)) diff --git a/src/gfx/render_image.hpp b/src/gfx/render_image.hpp index 6dcf1510..ba64beab 100644 --- a/src/gfx/render_image.hpp +++ b/src/gfx/render_image.hpp @@ -22,7 +22,9 @@ void init_shaders(); void rect_draw_some_item(sf::RenderTarget& targ_gworld,rectangle targ_rect); void rect_draw_some_item(const sf::Texture& src_gworld,rectangle src_rect,sf::RenderTarget& targ_gworld,rectangle targ_rect,sf::BlendMode mode = sf::BlendNone); void rect_draw_some_item(const sf::Texture& src_gworld,rectangle src_rect,sf::RenderTarget& targ_gworld,rectangle targ_rect,rectangle in_frame,sf::BlendMode mode = sf::BlendNone); +void rect_draw_some_item(sf::RenderTexture& src_render_gworld,rectangle src_rect,sf::RenderTarget& targ_gworld,rectangle targ_rect,sf::BlendMode mode = sf::BlendNone); void rect_draw_some_item(const sf::Texture& src_gworld,rectangle src_rect,const sf::Texture& mask_gworld,sf::RenderTarget& targ_gworld,rectangle targ_rect); +void rect_draw_some_item(sf::RenderTexture& src_render_gworld,rectangle src_rect,const sf::Texture& mask_gworld,sf::RenderTarget& targ_gworld,rectangle targ_rect); void draw_splash(const sf::Texture& splash, sf::RenderWindow& targ, rectangle dest_rect); void setActiveRenderTarget(sf::RenderTarget& where); diff --git a/src/gfx/render_text.cpp b/src/gfx/render_text.cpp index c5dd750d..b62d5fb2 100644 --- a/src/gfx/render_text.cpp +++ b/src/gfx/render_text.cpp @@ -135,7 +135,14 @@ break_info_t calculate_line_wrapping(rectangle dest_rect, std::string str, TextS return break_info; } -void draw_scale_aware(sf::RenderTarget& dest_window, sf::Text str_to_draw) { +// I don't know of a better way to do this than using pointers as keys. +extern std::map> store_scale_aware_text; + +void clear_scale_aware_text(sf::RenderTexture& texture) { + store_scale_aware_text.erase(&texture); +} + +void draw_scale_aware_text(sf::RenderTarget& dest_window, sf::Text str_to_draw) { str_to_draw.setCharacterSize(str_to_draw.getCharacterSize() * get_ui_scale()); if(dynamic_cast(&dest_window) != nullptr){ @@ -145,8 +152,14 @@ void draw_scale_aware(sf::RenderTarget& dest_window, sf::Text str_to_draw) { dest_window.setView(dest_window.getDefaultView()); dest_window.draw(str_to_draw); dest_window.setView(view); - }else if(dynamic_cast(&dest_window) != nullptr){ - // TODO Onto a RenderTexture is trickier because the texture is locked at the smaller size. + }else if(sf::RenderTexture* p = dynamic_cast(&dest_window); p != nullptr){ + // Onto a RenderTexture is trickier because the texture is locked at the smaller size. + // What we can do is save the sf::Text with its relative position and render + // it onto the RenderWindow that eventually draws the RenderTexture. + if(store_scale_aware_text.find(p) == store_scale_aware_text.end()){ + store_scale_aware_text[p] = std::vector {}; + } + store_scale_aware_text[p].push_back(str_to_draw); } } @@ -243,7 +256,7 @@ static void win_draw_string(sf::RenderTarget& dest_window,rectangle dest_rect,st bounds.inset(0,-4); fill_rect(dest_window, bounds, options.hilite_bg); } else str_to_draw.setColor(options.style.colour); - draw_scale_aware(dest_window, str_to_draw); + draw_scale_aware_text(dest_window, str_to_draw); } } diff --git a/src/gfx/render_text.hpp b/src/gfx/render_text.hpp index 586d1f24..412f3211 100644 --- a/src/gfx/render_text.hpp +++ b/src/gfx/render_text.hpp @@ -57,7 +57,8 @@ enum class eTextMode { std::vector draw_string_hilite(sf::RenderTarget& dest_window,rectangle dest_rect,std::string str,TextStyle style,std::vector hilites,sf::Color hiliteClr); std::vector draw_string_sel(sf::RenderTarget& dest_window,rectangle dest_rect,std::string str,TextStyle style,std::vector hilites,sf::Color hiliteClr); -void draw_scale_aware(sf::RenderTarget& dest_window,sf::Text text); +void draw_scale_aware_text(sf::RenderTarget& dest_window, sf::Text str_to_draw); +void clear_scale_aware_text(sf::RenderTexture& texture); void win_draw_string(sf::RenderTarget& dest_window,rectangle dest_rect,std::string str,eTextMode mode,TextStyle style,bool right_align = false); void win_draw_string(sf::RenderTarget& dest_window,rectangle dest_rect,std::string str,eTextMode mode,TextStyle style, break_info_t break_info,bool right_align = false); break_info_t calculate_line_wrapping(rectangle dest_rect, std::string str, TextStyle style);