graphics:

- use the UI scaling to define the size of the renderer textures,
- allow talk_gworld to be rescaled,
- allow to read rescaled graphics in the scenario in cboe, assuming
  that there are scaled similarly in X and Y. The scenario editor is
  also able to display them but its code will need to be modified to
  make it able to edit them...
This commit is contained in:
Laurent alonso
2020-10-22 21:47:23 +02:00
committed by Celtic Minstrel
parent 92eee35b66
commit 1daca1cf55
6 changed files with 44 additions and 36 deletions

View File

@@ -566,14 +566,9 @@ void cDialog::run(std::function<void(cDialog&)> onopen){
int wWidth=int(ui_scale*winRect.width()), wHeight=int(ui_scale*winRect.height());
win.create(sf::VideoMode(wWidth, wHeight), "Dialog", sf::Style::Titlebar);
sf::FloatRect viewport;
viewport.top = 0;
viewport.left = 0;
viewport.width = ui_scale;
viewport.height = ui_scale;
sf::View view;
view.reset(sf::FloatRect(0, 0, wWidth, wHeight));
view.setViewport(viewport);
view.setViewport(sf::FloatRect(0, 0, ui_scale, ui_scale));
win.setView(view);
// ASAN overflow

View File

@@ -17,9 +17,7 @@ class TextureLoader : public ResMgr::cLoader<Texture> {
if(img->loadFromFile(fpath.string())) {
Texture *texture=new Texture;
texture->texture=img;
texture->dimension=Texture::getApplicationDimension(fpath.filename().string());
if (texture->dimension.x==0 || texture->dimension.y==0)
texture->dimension=sf::Vector2u(img->getSize());
texture->dimension=Texture::getApplicationDimension(fpath.filename().string(),sf::Vector2u(img->getSize()));
return texture;
}
throw ResMgr::xError(ResMgr::ERR_LOAD, "Failed to load PNG image: " + fpath.string());

View File

@@ -113,8 +113,14 @@ void start_shop_mode(short which,short cost_adj,std::string store_name) {
active_shop.setName(store_name);
area_rect = talk_area_rect;
talk_gworld.create(area_rect.width(), area_rect.height());
float ui_scale= get_float_pref("UIScale", 1.0);
if (ui_scale < 1) ui_scale = 1.0;
talk_gworld.create(int(ui_scale*area_rect.width()), int(ui_scale*area_rect.height()));
sf::View view;
view.reset(sf::FloatRect(0,0, int(ui_scale*area_rect.width()), int(ui_scale*area_rect.height())));
view.setViewport(sf::FloatRect(0, 0, ui_scale, ui_scale));
talk_gworld.setView(view);
store_pre_shop_mode = overall_mode;
overall_mode = MODE_SHOPPING;
stat_screen_mode = MODE_SHOP;
@@ -561,7 +567,13 @@ void start_talk_mode(short m_num,short personality,mon_num_t monst_type,short st
store_m_num = m_num;
store_talk_face_pic = store_face_pic; ////
area_rect = talk_area_rect;
talk_gworld.create(area_rect.width(), area_rect.height());
float ui_scale= get_float_pref("UIScale", 1.0);
if (ui_scale < 1) ui_scale = 1.0;
talk_gworld.create(int(ui_scale*area_rect.width()), int(ui_scale*area_rect.height()));
sf::View view;
view.reset(sf::FloatRect(0,0, talk_gworld.getSize().x, talk_gworld.getSize().y));
view.setViewport(sf::FloatRect(0, 0, ui_scale, ui_scale));
talk_gworld.setView(view);
help_btn->show();
// This would be the place to show the text box, if I add it.

View File

@@ -481,23 +481,22 @@ void end_startup() {
item_sbar->show();
}
/* FIXME: actually the resolution of imgName sets the resolution of the final texture zone.
It may be better to add another Vector2u to define this resolution independly of imgName */
/* FIXME: normally, the renderTexture needed to be destroyed and recreated if the user
change the UI scaling. Let assume for now that he restarts the application */
static rectangle loadImageToRenderTexture(sf::RenderTexture& tex, std::string imgName) {
auto const& temp_gworld = *ResMgr::textures.get(imgName);
float ui_scale = get_float_pref("UIScale", 1.0);
if(ui_scale < 1) ui_scale = 1.0;
rectangle texrect(*temp_gworld);
tex.create(texrect.width(), texrect.height());
rect_draw_some_item(temp_gworld, rectangle(temp_gworld), tex, texrect, sf::BlendNone);
tex.create(int(ui_scale*temp_gworld.dimension.x), int(ui_scale*temp_gworld.dimension.y));
rect_draw_some_item(temp_gworld, rectangle(temp_gworld), tex, rectangle(tex), sf::BlendNone);
// now update the viewport so that a picture draw in 0,0,dim.y,dim.x fills the texture
sf::View view;
view.reset(sf::FloatRect(0, 0, texrect.width(), texrect.height()));
sf::FloatRect viewport;
viewport.left = 0;
viewport.top = 0;
viewport.width = float(texrect.width())/temp_gworld.dimension.x;
viewport.height = float(texrect.height())/temp_gworld.dimension.y;
view.setViewport(viewport);
view.reset(sf::FloatRect(0, 0, rectangle(tex).width(), rectangle(tex).height()));
view.setViewport(sf::FloatRect(0, 0, ui_scale, ui_scale));
tex.setView(view);
return rectangle(0,0,temp_gworld.dimension.y,temp_gworld.dimension.x);
}

View File

@@ -650,7 +650,7 @@ void draw_shop_graphics(bool pressed,rectangle clip_area_rect) {
clip_rect(talk_gworld, clip_area_rect);
}
area_rect = rectangle(talk_gworld);
area_rect = rectangle(0,0,talk_area_rect.height(),talk_area_rect.width());
frame_rect(talk_gworld, area_rect, Colours::BLACK);
area_rect.inset(1,1);
tileImage(talk_gworld, area_rect,bg[12]);
@@ -799,9 +799,7 @@ void draw_shop_graphics(bool pressed,rectangle clip_area_rect) {
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.getTexture(),from_rect,mainPtr,talk_area_rect);
}
static void place_talk_face() {
@@ -825,7 +823,7 @@ static void place_talk_face() {
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.getTexture(),rectangle(talk_gworld),mainPtr,talk_area_rect);
wordRect.offset(talk_area_rect.topLeft());
TextStyle style;
style.font = FONT_DUNGEON;
@@ -836,7 +834,7 @@ void click_talk_rect(word_rect_t word) {
place_talk_face();
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.getTexture(),rectangle(talk_gworld),mainPtr,talk_area_rect);
place_talk_face();
}
@@ -871,7 +869,7 @@ std::string get_item_interesting_string(cItem item) {
case eItemType::BOOTS: // coherent with damage_pc
sout << "Blocks "
<< (item.item_level>0 ? 1 : item.item_level) + (item.bonus>0 ? 1+item.bonus/2 : item.bonus) +
(item.protection > 0 ? 1 : item.protection)
(item.protection > 0 ? 1 : item.protection)
<< '-'
<< item.item_level + (item.bonus>=0 ? 3*item.bonus/2 : item.bonus) +
(item.protection>=0 ? item.protection : -1)
@@ -926,7 +924,7 @@ void place_talk_str(std::string str_to_place,std::string str_to_place2,short col
clip_rect(mainPtr, c_rect);
}
area_rect = rectangle(talk_gworld);
area_rect = rectangle(0,0,talk_area_rect.height(),talk_area_rect.width());
frame_rect(talk_gworld, area_rect, sf::Color::Black);
area_rect.inset(1,1);
tileImage(talk_gworld, area_rect,bg[12]);

View File

@@ -56,8 +56,8 @@ struct Texture {
operator rectangle() const {
return rectangle(0, 0, dimension.y, dimension.x);
}
static sf::Vector2u getApplicationDimension(std::string const &name) {
if (name.size()<5 || name.substr(name.size()-4)!=".png") return {0,0};
static sf::Vector2u getApplicationDimension(std::string const &name, sf::Vector2u imgSize) {
if (name.size()<5 || name.substr(name.size()-4)!=".png") return imgSize;
std::string const base=name.substr(0,name.size()-4);
static std::map<std::string, sf::Vector2u> nameToDimensions = {
{ "actionhelp", {275,100} },
@@ -114,12 +114,18 @@ struct Texture {
auto const &it=nameToDimensions.find(base);
if (it!=nameToDimensions.end())
return it->second;
// now check the special case terXXX.png and monstXXX.png
if (base.size()>=4 && base.substr(0,3)=="ter" && base.substr(3).find_first_not_of( "0123456789" ) == std::string::npos)
// now check the special case terXXX.png and monstXXX.png
if (base.size()>=4 && base.substr(0,3)=="ter" && base.substr(3).find_first_not_of( "0123456789" ) == std::string::npos)
return {280,180};
if (base.size()>=6 && base.substr(0,5)=="monst" && base.substr(5).find_first_not_of( "0123456789" ) == std::string::npos)
return {224,360};
return {0,0};
if (base.size()>=6 && base.substr(0,5)=="sheet" && base.substr(5).find_first_not_of( "0123456789" ) == std::string::npos) {
if (base.size()<=7 && (base.size()==6 || base[5]=='0' || base[5]=='1') && imgSize.x>280) {
// assume that this is a scaled terrain/object sheet in a scenario
return {280,unsigned(280/float(imgSize.x)*imgSize.y)};
}
}
return imgSize;
}
std::shared_ptr<const sf::Texture> texture;
sf::Vector2u dimension;