From 1a5ae18f7ffdf50d127aa574442e66539e3df2d9 Mon Sep 17 00:00:00 2001 From: Nat Quayle Nelson Date: Mon, 23 Jun 2025 13:09:41 -0500 Subject: [PATCH 01/17] add image editor preference to scenedit --- rsrc/dialogs/pref-scenario.xml | 18 +++++++++++------- src/scenedit/scen.main.cpp | 27 +++++++++++++++++++++++++++ 2 files changed, 38 insertions(+), 7 deletions(-) diff --git a/rsrc/dialogs/pref-scenario.xml b/rsrc/dialogs/pref-scenario.xml index eb405f4ad..552eeff76 100644 --- a/rsrc/dialogs/pref-scenario.xml +++ b/rsrc/dialogs/pref-scenario.xml @@ -8,12 +8,12 @@ No UI Sounds Scale UI: - 1 - 1.5 - 2 - 3 - 4 - + 1 + 1.5 + 2 + 3 + 4 + Debug Party: @@ -21,6 +21,10 @@ Force default party (ignore above) - + Image Editor: + + + + diff --git a/src/scenedit/scen.main.cpp b/src/scenedit/scen.main.cpp index 82562ae97..5e898096a 100644 --- a/src/scenedit/scen.main.cpp +++ b/src/scenedit/scen.main.cpp @@ -904,6 +904,7 @@ static bool prefs_event_filter (cDialog& me, std::string id, eKeyMod) { set_pref("PlaySounds", dynamic_cast(me["nosound"]).getState() == led_off); set_pref("ForceDefaultParty", dynamic_cast(me["force-default-party"]).getState() == led_red); set_pref("DefaultPartyPath", dynamic_cast(me["party-path"]).getText()); + set_pref("ImageEditor", dynamic_cast(me["image-editor"]).getText()); } save_prefs(); return true; @@ -975,6 +976,23 @@ void pick_preferences() { return true; }); + cTextField& image_editor_field = dynamic_cast(prefsDlog["image-editor"]); + image_editor_field.setText(get_string_pref("ImageEditor")); + + image_editor_field.attachFocusHandler([](cDialog& me, std::string id, bool losing) -> bool { + if(!losing) return true; + std::string image_editor = me[id].getText(); + // Validate the debug party + if(!image_editor.empty()){ + if(!fs::exists(image_editor)){ + showError("Your chosen image editor cannot be found.", "", &me); + me[id].setText(get_string_pref("ImageEditor")); + return false; + } + } + return true; + }); + cButton& choose_button = dynamic_cast(prefsDlog["choose-party"]); choose_button.attachClickHandler([&default_party_field](cDialog&, std::string, eKeyMod) -> bool { fs::path new_path = nav_get_party(); @@ -983,6 +1001,15 @@ void pick_preferences() { } return true; }); + + cButton& choose_img_button = dynamic_cast(prefsDlog["choose-image-editor"]); + choose_img_button.attachClickHandler([&image_editor_field](cDialog&, std::string, eKeyMod) -> bool { + fs::path new_path = nav_get_rsrc({"exe", "app", ""}); + if(!new_path.empty()){ + image_editor_field.setText(new_path.string()); + } + return true; + }); prefsDlog.run(); From b4ea9166130cf18c7deaa6f270b772423f43c8ee Mon Sep 17 00:00:00 2001 From: Nat Quayle Nelson Date: Mon, 23 Jun 2025 13:25:41 -0500 Subject: [PATCH 02/17] edit/reload buttons in graphic editor --- rsrc/dialogs/graphic-sheets.xml | 11 ++++---- src/scenedit/scen.core.cpp | 48 ++++++++++++++++++++++++++++----- 2 files changed, 47 insertions(+), 12 deletions(-) diff --git a/rsrc/dialogs/graphic-sheets.xml b/rsrc/dialogs/graphic-sheets.xml index 982a5d456..5fb99e850 100644 --- a/rsrc/dialogs/graphic-sheets.xml +++ b/rsrc/dialogs/graphic-sheets.xml @@ -1,5 +1,4 @@ - @@ -8,10 +7,12 @@ - - - - + + + + + + diff --git a/src/scenedit/scen.core.cpp b/src/scenedit/scen.core.cpp index 641b9c662..3ca4fa67e 100644 --- a/src/scenedit/scen.core.cpp +++ b/src/scenedit/scen.core.cpp @@ -7,6 +7,8 @@ #include #include #include +#include +#include #include "scen.global.hpp" #include "scenario/scenario.hpp" #include "scenario/town.hpp" @@ -3822,9 +3824,23 @@ void edit_custom_sheets() { set_dlg_custom_sheet(me, all_pics[cur]); return true; }); - pic_dlg["open"].attachClickHandler([&sheets,&cur,&all_pics,&pic_dir,&deferred_actions](cDialog& me, std::string, eKeyMod) -> bool { - fs::path fpath = nav_get_rsrc({"png", "bmp", "jpg", "jpeg", "gif", "psd"}); - if(fpath.empty()) return true; + pic_dlg["edit"].attachClickHandler([&sheets,&cur,&all_pics,&pic_dir](cDialog&, std::string, eKeyMod) -> bool { + fs::path image_editor = get_string_pref("ImageEditor"); + if(image_editor.empty()){ + showWarning("Choose an external image editor in the preferences window first."); + return true; + } + + std::string resName = "sheet" + std::to_string(all_pics[cur]); + fs::path toPath = pic_dir/(resName + ".png"); + + std::vector args = {toPath.string()}; + bp::child ch(image_editor, args, bp::std_out > stdout); + ch.detach(); + return true; + }); + + auto replace_from_file = [&pic_dlg,&sheets,&cur,&all_pics,&pic_dir,&deferred_actions](std::string action_name, fs::path fpath) -> bool { sf::Image img; if(!img.loadFromFile(fpath.string().c_str())) { beep(); @@ -3835,19 +3851,37 @@ void edit_custom_sheets() { fs::path toPath = pic_dir/(resName + ".png"); sf::Image image_for_undo; + // TODO for reload, old image and new image will be the same! This could possibly be addressed by loading the image when edit is clicked? + // But there is no guarantee Edit is clicked first--the designer could externally edit the full-sheet image whenever they want. + + // Also comparing image blobs for equality is probably expensive, but we should have a check to prevent adding undo actions if the same file was imported + // or reload is clicked when the file isn't changed. image_for_undo.loadFromFile(toPath.string()); - deferred_actions.push_back(action_ptr(new aReplaceGraphicsSheet("Import Graphics Sheet", all_pics[cur], image_for_undo, img))); + deferred_actions.push_back(action_ptr(new aReplaceGraphicsSheet(action_name, all_pics[cur], image_for_undo, img))); img.saveToFile(toPath.string().c_str()); ResMgr::graphics.free(resName); - set_dlg_custom_sheet(me, all_pics[cur]); + set_dlg_custom_sheet(pic_dlg, all_pics[cur]); return true; } - deferred_actions.push_back(action_ptr(new aReplaceGraphicsSheet("Import Graphics Sheet", all_pics[cur], sheets[cur], img))); + deferred_actions.push_back(action_ptr(new aReplaceGraphicsSheet(action_name, all_pics[cur], sheets[cur], img))); sheets[cur] = img; spec_scen_g.replace_sheet(cur, img); - set_dlg_custom_sheet(me, all_pics[cur]); + set_dlg_custom_sheet(pic_dlg, all_pics[cur]); + return true; + }; + + pic_dlg["reload"].attachClickHandler([replace_from_file, &all_pics, &cur, &pic_dir](cDialog&, std::string, eKeyMod) -> bool { + std::string resName = "sheet" + std::to_string(all_pics[cur]); + fs::path sheetPath = pic_dir/(resName + ".png"); + replace_from_file("Reload Graphics Sheet", sheetPath); + return true; + }); + pic_dlg["open"].attachClickHandler([replace_from_file](cDialog& me, std::string, eKeyMod) -> bool { + fs::path fpath = nav_get_rsrc({"png", "bmp", "jpg", "jpeg", "gif", "psd"}); + if(fpath.empty()) return true; + replace_from_file("Import Graphics Sheet", fpath); return true; }); pic_dlg["save"].attachClickHandler([&sheets,&cur,&all_pics,&pic_dir](cDialog&, std::string, eKeyMod) -> bool { From a459332a2c962657d014ea5237a48c7c025b0e33 Mon Sep 17 00:00:00 2001 From: Nat Quayle Nelson Date: Mon, 23 Jun 2025 14:44:25 -0500 Subject: [PATCH 03/17] MacOS find inner binary of image editor app bundle --- src/scenedit/scen.core.cpp | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/src/scenedit/scen.core.cpp b/src/scenedit/scen.core.cpp index 3ca4fa67e..3344e7e45 100644 --- a/src/scenedit/scen.core.cpp +++ b/src/scenedit/scen.core.cpp @@ -3830,13 +3830,28 @@ void edit_custom_sheets() { showWarning("Choose an external image editor in the preferences window first."); return true; } + #ifdef SFML_SYSTEM_MACOS + // Find actual binary inside the .app bundle: + + image_editor = image_editor / "Contents" / "MacOS" / image_editor.stem(); + + #endif std::string resName = "sheet" + std::to_string(all_pics[cur]); fs::path toPath = pic_dir/(resName + ".png"); std::vector args = {toPath.string()}; - bp::child ch(image_editor, args, bp::std_out > stdout); - ch.detach(); + try{ + bp::child ch(image_editor, args, bp::std_out > stdout); + ch.detach(); + } + catch(std::exception& x) { + showError(std::string{"Error running your image editor: "} + x.what()); + } catch(std::string& x) { + showError("Error running your image editor: " + x); + } catch(...) { + showError("An unknown error occurred running your image editor!"); + } return true; }); From 9f7c775efa6570433567a159942b3942e7118a7d Mon Sep 17 00:00:00 2001 From: Nat Quayle Nelson Date: Mon, 23 Jun 2025 15:11:18 -0500 Subject: [PATCH 04/17] allow selecting range of icons in graphics sheet --- rsrc/dialogs/graphic-sheets.xml | 10 ++++++++++ src/scenedit/scen.core.cpp | 30 ++++++++++++++++++++++++++++++ 2 files changed, 40 insertions(+) diff --git a/rsrc/dialogs/graphic-sheets.xml b/rsrc/dialogs/graphic-sheets.xml index 5fb99e850..cc905a8f6 100644 --- a/rsrc/dialogs/graphic-sheets.xml +++ b/rsrc/dialogs/graphic-sheets.xml @@ -6,6 +6,8 @@ Sheet Number: + + @@ -13,9 +15,17 @@ + + + Selected icons: + 0 + - + 0 + + diff --git a/src/scenedit/scen.core.cpp b/src/scenedit/scen.core.cpp index 3344e7e45..681373e8f 100644 --- a/src/scenedit/scen.core.cpp +++ b/src/scenedit/scen.core.cpp @@ -4022,6 +4022,36 @@ void edit_custom_sheets() { }, {"left", "right"}); set_dlg_custom_sheet(pic_dlg, all_pics[cur]); + + int icon_start = 0; + int icon_end = 0; + int icon_min = 0; + int icon_max = 0; + pic_dlg["sheet"].attachClickHandler([&all_pics, &cur, &icon_start, &icon_end, &icon_min, &icon_max](cDialog& me, std::string, eKeyMod mod) -> bool { + location where_curs = sf::Mouse::getPosition(me.getWindow()); + where_curs = me.getWindow().mapPixelToCoords(where_curs); + rectangle sheet_bounds = me["sheet"].getBounds(); + where_curs.x -= sheet_bounds.left; + where_curs.y -= sheet_bounds.top; + where_curs.x /= 28; + where_curs.y /= 36; + + int icon_hit = 1000 + 100 * all_pics[cur] + 10 * where_curs.y + where_curs.x; + + if(mod_contains(mod, mod_shift)){ + icon_end = icon_hit; + }else{ + icon_start = icon_end = icon_hit; + } + icon_min = min(icon_start, icon_end); + icon_max = max(icon_start, icon_end); + me["icon-min"].setTextToNum(icon_min); + me["icon-max"].setTextToNum(icon_max); + // TODO highlight the selected icons visually + + return true; + }); + shut_down_menus(5); // So that cmd+O, cmd+N, cmd+S can work pic_dlg.run(); From 6e187a15e88d5235fb3bb0738c57ed70563bb581 Mon Sep 17 00:00:00 2001 From: Nat Quayle Nelson Date: Mon, 23 Jun 2025 15:18:33 -0500 Subject: [PATCH 05/17] clear icon selection when sheet changes --- src/scenedit/scen.core.cpp | 32 +++++++++++++++++++++++--------- 1 file changed, 23 insertions(+), 9 deletions(-) diff --git a/src/scenedit/scen.core.cpp b/src/scenedit/scen.core.cpp index 681373e8f..85ef359ea 100644 --- a/src/scenedit/scen.core.cpp +++ b/src/scenedit/scen.core.cpp @@ -4007,7 +4007,19 @@ void edit_custom_sheets() { pic_dlg["left"].hide(); pic_dlg["right"].hide(); } - pic_dlg.attachClickHandlers([&sheets,&cur,&all_pics](cDialog& me, std::string dir, eKeyMod) -> bool { + + int icon_start = 0; + int icon_end = 0; + int icon_min = 0; + int icon_max = 0; + auto show_icon_selection = [&icon_min, &icon_max, &pic_dlg]() { + pic_dlg["icon-min"].setTextToNum(icon_min); + pic_dlg["icon-max"].setTextToNum(icon_max); + // TODO highlight the selected icons visually + }; + + pic_dlg.attachClickHandlers([&sheets,&cur,&all_pics,show_icon_selection,&icon_start,&icon_end,&icon_min,&icon_max](cDialog& me, std::string dir, eKeyMod) -> bool { + size_t old_cur = cur; if(dir == "left") { if(cur == 0) cur = all_pics.size() - 1; @@ -4017,17 +4029,21 @@ void edit_custom_sheets() { if(cur >= all_pics.size()) cur = 0; } else return true; + if(cur != old_cur){ + icon_start = icon_end = icon_min = icon_max = 0; + show_icon_selection(); + } + set_dlg_custom_sheet(me, all_pics[cur]); return true; }, {"left", "right"}); set_dlg_custom_sheet(pic_dlg, all_pics[cur]); - int icon_start = 0; - int icon_end = 0; - int icon_min = 0; - int icon_max = 0; - pic_dlg["sheet"].attachClickHandler([&all_pics, &cur, &icon_start, &icon_end, &icon_min, &icon_max](cDialog& me, std::string, eKeyMod mod) -> bool { + + + + pic_dlg["sheet"].attachClickHandler([&all_pics, &cur, &icon_start, &icon_end, &icon_min, &icon_max, show_icon_selection](cDialog& me, std::string, eKeyMod mod) -> bool { location where_curs = sf::Mouse::getPosition(me.getWindow()); where_curs = me.getWindow().mapPixelToCoords(where_curs); rectangle sheet_bounds = me["sheet"].getBounds(); @@ -4045,9 +4061,7 @@ void edit_custom_sheets() { } icon_min = min(icon_start, icon_end); icon_max = max(icon_start, icon_end); - me["icon-min"].setTextToNum(icon_min); - me["icon-max"].setTextToNum(icon_max); - // TODO highlight the selected icons visually + show_icon_selection(); return true; }); From 0a4039c9ffca1aa9fd8b4c51a598c7c45f2dc354 Mon Sep 17 00:00:00 2001 From: Nat Quayle Nelson Date: Mon, 23 Jun 2025 15:40:23 -0500 Subject: [PATCH 06/17] non-mac targets scenario editor must save LastScenario pref --- src/scenedit/scen.actions.cpp | 3 +++ src/scenedit/scen.fileio.cpp | 2 ++ src/scenedit/scen.main.cpp | 3 +++ 3 files changed, 8 insertions(+) diff --git a/src/scenedit/scen.actions.cpp b/src/scenedit/scen.actions.cpp index c8540cbcd..a28e0f3bb 100644 --- a/src/scenedit/scen.actions.cpp +++ b/src/scenedit/scen.actions.cpp @@ -67,6 +67,8 @@ extern location cur_out; bool small_any_drawn = false; extern bool change_made; +extern void save_prefs(); + rectangle left_buttons[NLS][2]; // 0 - whole, 1 - blue button std::array left_button_status; std::vector right_button_status; @@ -257,6 +259,7 @@ static bool handle_lb_action(int i){ file_to_load = nav_get_scenario(); if(!file_to_load.empty() && load_scenario(file_to_load, scenario)) { set_pref("LastScenario", file_to_load.string()); + save_prefs(); restore_editor_state(); undo_list.clear(); update_edit_menu(); diff --git a/src/scenedit/scen.fileio.cpp b/src/scenedit/scen.fileio.cpp index a3bf1fe1c..ab6ee1feb 100644 --- a/src/scenedit/scen.fileio.cpp +++ b/src/scenedit/scen.fileio.cpp @@ -37,6 +37,7 @@ fs::path temp_file_to_load; std::string last_load_file = "Blades of Exile Scenario"; extern fs::path progDir, tempDir; extern bool cur_scen_is_mac; +extern void save_prefs(); void print_write_position (); void load_spec_graphics(); @@ -1110,6 +1111,7 @@ void save_scenario(bool rename) { } set_pref("LastScenario", toFile.string()); + save_prefs(); extern cUndoList undo_list; undo_list.save(); diff --git a/src/scenedit/scen.main.cpp b/src/scenedit/scen.main.cpp index 5e898096a..0d512934b 100644 --- a/src/scenedit/scen.main.cpp +++ b/src/scenedit/scen.main.cpp @@ -335,6 +335,8 @@ static void process_args(int argc, char* argv[]) { // On first launch, no need to clear the undo_list set_pref("LastScenario", file); + save_prefs(); + restore_editor_state(); change_made = false; ae_loading = true; @@ -521,6 +523,7 @@ void handle_menu_choice(eMenu item_hit) { undo_list.clear(); update_edit_menu(); set_pref("LastScenario", file_to_load.string()); + save_prefs(); restore_editor_state(); change_made = false; } else if(!file_to_load.empty()) From 6a8b6b0e5008146393ed49985a36c73f51f19612 Mon Sep 17 00:00:00 2001 From: Nat Quayle Nelson Date: Mon, 23 Jun 2025 17:39:50 -0500 Subject: [PATCH 07/17] allow cPict to draw on any RenderTarget --- src/dialogxml/widgets/pict.cpp | 286 +++++++++++++++++---------------- src/dialogxml/widgets/pict.hpp | 88 +++++----- 2 files changed, 194 insertions(+), 180 deletions(-) diff --git a/src/dialogxml/widgets/pict.cpp b/src/dialogxml/widgets/pict.cpp index f7b86e165..a27e6aa99 100644 --- a/src/dialogxml/widgets/pict.cpp +++ b/src/dialogxml/widgets/pict.cpp @@ -71,8 +71,8 @@ void cPict::init(){ drawPict()[PIC_BTN] = &cPict::drawInvenBtn; } -std::map& cPict::drawPict(){ - static std::map f; +std::map& cPict::drawPict(){ + static std::map f; return f; } @@ -728,22 +728,24 @@ std::shared_ptr cPict::getSheetInternal(eSheetType type, size } void cPict::draw(){ - sf::Color store_color; - rectangle rect = frame; getWindow().setActive(); + draw(getWindow()); + drawFrame(2, frameStyle); +} + +void cPict::draw(sf::RenderTarget& targ) { if(!visible) return; + rectangle rect = frame; if(picNum == BLANK || picType == PIC_NONE) // Just a solid fill - fill_rect(getWindow(), rect, fillClr); - else (this->*drawPict()[picType])(picNum,rect); - - drawFrame(2, frameStyle); + fill_rect(targ, rect, fillClr); + else (this->*drawPict()[picType])(picNum,rect,targ); } -void cPict::drawPresetTer(short num, rectangle to_rect){ +void cPict::drawPresetTer(short num, rectangle to_rect, sf::RenderTarget& targ){ if(num >= 960) { - drawPresetTerAnim(num - 960, to_rect); + drawPresetTerAnim(num - 960, to_rect, targ); return; } auto from_gw = getSheet(SHEET_TER, num / 50); @@ -752,10 +754,10 @@ void cPict::drawPresetTer(short num, rectangle to_rect){ rectangle from_rect = calc_rect(num % 10, num / 10); if(to_rect.right - to_rect.left > 28) to_rect.inset(4,0); - rect_draw_some_item(*from_gw, from_rect, getWindow(), to_rect); + rect_draw_some_item(*from_gw, from_rect, targ, to_rect); } -void cPict::drawPresetTerAnim(short num, rectangle to_rect){ +void cPict::drawPresetTerAnim(short num, rectangle to_rect, sf::RenderTarget& targ){ rectangle from_rect = calc_rect(4 * (num / 5) + (animLoops != 0 ? animFrame % 4 : 0), num % 5); auto from_gw = getSheet(SHEET_TER_ANIM); if(!from_gw) return; @@ -763,7 +765,7 @@ void cPict::drawPresetTerAnim(short num, rectangle to_rect){ to_rect.inset(4,0); to_rect.right = to_rect.left + 28; } - rect_draw_some_item(*from_gw, from_rect, getWindow(), to_rect); + rect_draw_some_item(*from_gw, from_rect, targ, to_rect); } static rectangle calcDefMonstRect(short i, short animFrame, short animLoops){ @@ -783,7 +785,7 @@ static rectangle calcDefMonstRect(short i, short animFrame, short animLoops){ return r; } -void cPict::drawPresetMonstSm(short num, rectangle to_rect){ +void cPict::drawPresetMonstSm(short num, rectangle to_rect, sf::RenderTarget& targ){ short m_start_pic = m_pic_index[num].i; auto from_gw = getSheet(SHEET_MONST, m_start_pic / 20); if(!from_gw) return; @@ -792,14 +794,14 @@ void cPict::drawPresetMonstSm(short num, rectangle to_rect){ rectangle from_rect = calcDefMonstRect(m_start_pic, animFrame, animLoops); to_rect.right = to_rect.left + 28; to_rect.bottom = to_rect.top + 36; - if(filled) fill_rect(getWindow(), to_rect, fillClr); - rect_draw_some_item(*from_gw, from_rect, getWindow(), to_rect, sf::BlendAlpha); + if(filled) fill_rect(targ, to_rect, fillClr); + rect_draw_some_item(*from_gw, from_rect, targ, to_rect, sf::BlendAlpha); } -void cPict::drawPresetMonstWide(short num, rectangle to_rect){ +void cPict::drawPresetMonstWide(short num, rectangle to_rect, sf::RenderTarget& targ){ rectangle small_monst_rect = {0,0,18,14}; to_rect.right = to_rect.left + 28; to_rect.bottom = to_rect.top + 36; - if(filled) fill_rect(getWindow(), to_rect, fillClr); + if(filled) fill_rect(targ, to_rect, fillClr); short m_start_pic = m_pic_index[num].i; auto from_gw = getSheet(SHEET_MONST, m_start_pic / 20); @@ -807,21 +809,21 @@ void cPict::drawPresetMonstWide(short num, rectangle to_rect){ updateAnim(4); rectangle from_rect = calcDefMonstRect(m_start_pic % 20, animFrame, animLoops); small_monst_rect.offset(to_rect.left,to_rect.top + 7); - rect_draw_some_item(*from_gw, from_rect, getWindow(), small_monst_rect, sf::BlendAlpha); + rect_draw_some_item(*from_gw, from_rect, targ, small_monst_rect, sf::BlendAlpha); m_start_pic = m_pic_index[num].i + 1; from_gw = getSheet(SHEET_MONST, m_start_pic / 20); if(!from_gw) return; from_rect = calcDefMonstRect(m_start_pic % 20, animFrame, animLoops); small_monst_rect.offset(14,0); - rect_draw_some_item(*from_gw, from_rect, getWindow(), small_monst_rect, sf::BlendAlpha); + rect_draw_some_item(*from_gw, from_rect, targ, small_monst_rect, sf::BlendAlpha); } -void cPict::drawPresetMonstTall(short num, rectangle to_rect){ +void cPict::drawPresetMonstTall(short num, rectangle to_rect, sf::RenderTarget& targ){ rectangle small_monst_rect = {0,0,18,14}; to_rect.right = to_rect.left + 28; to_rect.bottom = to_rect.top + 36; - if(filled) fill_rect(getWindow(), to_rect, fillClr); + if(filled) fill_rect(targ, to_rect, fillClr); short m_start_pic = m_pic_index[num].i; auto from_gw = getSheet(SHEET_MONST, m_start_pic / 20); @@ -829,21 +831,21 @@ void cPict::drawPresetMonstTall(short num, rectangle to_rect){ updateAnim(4); rectangle from_rect = calcDefMonstRect(m_start_pic % 20, animFrame, animLoops); small_monst_rect.offset(to_rect.left + 7,to_rect.top); - rect_draw_some_item(*from_gw, from_rect, getWindow(), small_monst_rect, sf::BlendAlpha); + rect_draw_some_item(*from_gw, from_rect, targ, small_monst_rect, sf::BlendAlpha); m_start_pic = m_pic_index[num].i + 1; from_gw = getSheet(SHEET_MONST, m_start_pic / 20); if(!from_gw) return; from_rect = calcDefMonstRect(m_start_pic % 20, animFrame, animLoops); small_monst_rect.offset(0,18); - rect_draw_some_item(*from_gw, from_rect, getWindow(), small_monst_rect, sf::BlendAlpha); + rect_draw_some_item(*from_gw, from_rect, targ, small_monst_rect, sf::BlendAlpha); } -void cPict::drawPresetMonstLg(short num, rectangle to_rect){ +void cPict::drawPresetMonstLg(short num, rectangle to_rect, sf::RenderTarget& targ){ rectangle small_monst_rect = {0,0,18,14}; to_rect.right = to_rect.left + 28; to_rect.bottom = to_rect.top + 36; - if(filled) fill_rect(getWindow(), to_rect, fillClr); + if(filled) fill_rect(targ, to_rect, fillClr); short m_start_pic = m_pic_index[num].i; auto from_gw = getSheet(SHEET_MONST, m_start_pic / 20); @@ -851,79 +853,79 @@ void cPict::drawPresetMonstLg(short num, rectangle to_rect){ updateAnim(4); rectangle from_rect = calcDefMonstRect(m_start_pic % 20, animFrame, animLoops); small_monst_rect.offset(to_rect.left,to_rect.top); - rect_draw_some_item(*from_gw, from_rect, getWindow(), small_monst_rect, sf::BlendAlpha); + rect_draw_some_item(*from_gw, from_rect, targ, small_monst_rect, sf::BlendAlpha); m_start_pic = m_pic_index[num].i + 1; from_gw = getSheet(SHEET_MONST, m_start_pic / 20); if(!from_gw) return; from_rect = calcDefMonstRect(m_start_pic % 20, animFrame, animLoops); small_monst_rect.offset(14,0); - rect_draw_some_item(*from_gw, from_rect, getWindow(), small_monst_rect, sf::BlendAlpha); + rect_draw_some_item(*from_gw, from_rect, targ, small_monst_rect, sf::BlendAlpha); m_start_pic = m_pic_index[num].i + 2; from_gw = getSheet(SHEET_MONST, m_start_pic / 20); if(!from_gw) return; from_rect = calcDefMonstRect(m_start_pic % 20, animFrame, animLoops); small_monst_rect.offset(-14,18); - rect_draw_some_item(*from_gw, from_rect, getWindow(), small_monst_rect, sf::BlendAlpha); + rect_draw_some_item(*from_gw, from_rect, targ, small_monst_rect, sf::BlendAlpha); m_start_pic = m_pic_index[num].i + 3; from_gw = getSheet(SHEET_MONST, m_start_pic / 20); if(!from_gw) return; from_rect = calcDefMonstRect(m_start_pic % 20, animFrame, animLoops); small_monst_rect.offset(14,0); - rect_draw_some_item(*from_gw, from_rect, getWindow(), small_monst_rect, sf::BlendAlpha); + rect_draw_some_item(*from_gw, from_rect, targ, small_monst_rect, sf::BlendAlpha); } -void cPict::drawPresetDlog(short num, rectangle to_rect){ +void cPict::drawPresetDlog(short num, rectangle to_rect, sf::RenderTarget& targ){ to_rect.right = to_rect.left + 36; to_rect.bottom = to_rect.top + 36; auto from_gw = getSheet(SHEET_DLOG); rectangle from_rect = {0,0,36,36}; from_rect.offset(36 * (num % 4),36 * (num / 4)); - rect_draw_some_item(*from_gw, from_rect, getWindow(), to_rect); + rect_draw_some_item(*from_gw, from_rect, targ, to_rect); } -void cPict::drawPresetDlogLg(short num, rectangle to_rect){ +void cPict::drawPresetDlogLg(short num, rectangle to_rect, sf::RenderTarget& targ){ to_rect.right = to_rect.left + (drawScaled ? getBounds().width() : 72); to_rect.bottom = to_rect.top + (drawScaled ? getBounds().height() : 72); auto from_gw = getSheet(SHEET_DLOG); rectangle from_rect = {0,0,72,72}; from_rect.offset(36 * (num % 4),36 * (num / 4)); - rect_draw_some_item(*from_gw, from_rect, getWindow(), to_rect); + rect_draw_some_item(*from_gw, from_rect, targ, to_rect); } -void cPict::drawPresetTalk(short num, rectangle to_rect){ +void cPict::drawPresetTalk(short num, rectangle to_rect, sf::RenderTarget& targ){ to_rect.right = to_rect.left + 32; to_rect.bottom = to_rect.top + 32; auto from_gw = getSheet(SHEET_TALK); rectangle from_rect = {0,0,32,32}; from_rect.offset(32 * (num % 10),32 * (num / 10)); - rect_draw_some_item(*from_gw, from_rect, getWindow(), to_rect); + rect_draw_some_item(*from_gw, from_rect, targ, to_rect); } -void cPict::drawPresetScen(short num, rectangle to_rect){ +void cPict::drawPresetScen(short num, rectangle to_rect, sf::RenderTarget& targ){ auto from_gw = getSheet(SHEET_SCEN); rectangle from_rect = {0,0,32,32}; from_rect.offset(32 * (num % 5),32 * (num / 5)); to_rect.right = to_rect.left + 32; to_rect.bottom = to_rect.top + 32; - rect_draw_some_item(*from_gw, from_rect, getWindow(), to_rect); + rect_draw_some_item(*from_gw, from_rect, targ, to_rect); } -void cPict::drawPresetScenLg(short num, rectangle to_rect){ +void cPict::drawPresetScenLg(short num, rectangle to_rect, sf::RenderTarget& targ){ auto from_gw = getSheet(SHEET_SCEN_LG); to_rect.right = to_rect.left + (drawScaled ? getBounds().width() : 64); to_rect.bottom = to_rect.top + (drawScaled ? getBounds().height() : 64); rectangle from_rect = {0,0,64,64}; from_rect.offset(num * 64, 0); - rect_draw_some_item(*from_gw, from_rect, getWindow(), to_rect); + rect_draw_some_item(*from_gw, from_rect, targ, to_rect); } -void cPict::drawPresetItem(short num, rectangle to_rect){ +void cPict::drawPresetItem(short num, rectangle to_rect, sf::RenderTarget& targ){ to_rect.right = to_rect.left + 28; to_rect.bottom = to_rect.top + 36; - if(filled) fill_rect(getWindow(), to_rect, fillClr); + if(filled) fill_rect(targ, to_rect, fillClr); std::shared_ptr from_gw; rectangle from_rect = {0,0,18,18}; if(num < 55) { @@ -934,35 +936,35 @@ void cPict::drawPresetItem(short num, rectangle to_rect){ to_rect.inset(5,9); from_rect.offset(18 * (num % 10), 18 * (num / 10)); } - rect_draw_some_item(*from_gw, from_rect, getWindow(), to_rect, sf::BlendAlpha); + rect_draw_some_item(*from_gw, from_rect, targ, to_rect, sf::BlendAlpha); } -void cPict::drawPresetTinyItem(short num, rectangle to_rect){ +void cPict::drawPresetTinyItem(short num, rectangle to_rect, sf::RenderTarget& targ){ to_rect.right = to_rect.left + 18; to_rect.bottom = to_rect.top + 18; - if(filled) fill_rect(getWindow(), to_rect, fillClr); + if(filled) fill_rect(targ, to_rect, fillClr); rectangle from_rect = {0,0,18,18}; auto from_gw = getSheet(SHEET_TINY_ITEM); from_rect.offset(18 * (num % 10), 18 * (num / 10)); - rect_draw_some_item(*from_gw, from_rect, getWindow(), to_rect, sf::BlendAlpha); + rect_draw_some_item(*from_gw, from_rect, targ, to_rect, sf::BlendAlpha); } -void cPict::drawPresetPc(short num, rectangle to_rect){ +void cPict::drawPresetPc(short num, rectangle to_rect, sf::RenderTarget& targ){ auto from_gw = getSheet(SHEET_PC); rectangle from_rect = calc_rect(2 * (num / 8), num % 8); to_rect.right = to_rect.left + 28; to_rect.bottom = to_rect.top + 36; - if(filled) fill_rect(getWindow(), to_rect, fillClr); - rect_draw_some_item(*from_gw, from_rect, getWindow(), to_rect, sf::BlendAlpha); + if(filled) fill_rect(targ, to_rect, fillClr); + rect_draw_some_item(*from_gw, from_rect, targ, to_rect, sf::BlendAlpha); } -void cPict::drawPresetField(short num, rectangle to_rect){ +void cPict::drawPresetField(short num, rectangle to_rect, sf::RenderTarget& targ){ auto from_gw = getSheet(SHEET_FIELD); rectangle from_rect = calc_rect(num % 8, num / 8); to_rect.right = to_rect.left + 28; to_rect.bottom = to_rect.top + 36; - if(filled) fill_rect(getWindow(), to_rect, fillClr); - rect_draw_some_item(*from_gw, from_rect, getWindow(), to_rect, sf::BlendAlpha); + if(filled) fill_rect(targ, to_rect, fillClr); + rect_draw_some_item(*from_gw, from_rect, targ, to_rect, sf::BlendAlpha); } void cPict::setAnimLoops(short value) { @@ -979,7 +981,7 @@ void cPict::updateAnim(short loop_frames) { } } -void cPict::drawPresetBoom(short num, rectangle to_rect){ +void cPict::drawPresetBoom(short num, rectangle to_rect, sf::RenderTarget& targ){ auto from_gw = getSheet(SHEET_BOOM); if(num >= 8){ num = 8 * (num - 7) + animFrame % 8; @@ -989,13 +991,13 @@ void cPict::drawPresetBoom(short num, rectangle to_rect){ // TODO: Be smarter about this - we know the first row is static booms and subsequent rows are animated booms. to_rect.right = to_rect.left + 28; to_rect.bottom = to_rect.top + 36; - if(filled) fill_rect(getWindow(), to_rect, fillClr); + if(filled) fill_rect(targ, to_rect, fillClr); // When missile loops are over, draw nothing if(animLoops != 0) - rect_draw_some_item(*from_gw, from_rect, getWindow(), to_rect, sf::BlendAlpha); + rect_draw_some_item(*from_gw, from_rect, targ, to_rect, sf::BlendAlpha); } -void cPict::drawFullSheet(short num, rectangle to_rect){ +void cPict::drawFullSheet(short num, rectangle to_rect, sf::RenderTarget& targ){ rectangle from_rect; auto from_gw = getSheet(SHEET_FULL, num); from_rect = rectangle(*from_gw); @@ -1003,25 +1005,25 @@ void cPict::drawFullSheet(short num, rectangle to_rect){ to_rect.right = to_rect.left + (from_rect.right - from_rect.left); to_rect.bottom = to_rect.top + (from_rect.bottom - from_rect.top); } - rect_draw_some_item(*from_gw, from_rect, getWindow(), to_rect); + rect_draw_some_item(*from_gw, from_rect, targ, to_rect); } -void cPict::drawPresetMissile(short num, rectangle to_rect){ +void cPict::drawPresetMissile(short num, rectangle to_rect, sf::RenderTarget& targ){ rectangle from_rect = {0,0,18,18}; auto from_gw = getSheet(SHEET_MISSILE); to_rect.right = to_rect.left + 18; to_rect.bottom = to_rect.top + 18; - if(filled) fill_rect(getWindow(), to_rect, fillClr); + if(filled) fill_rect(targ, to_rect, fillClr); updateAnim(8); // When missile loops are over, draw nothing if(animLoops != 0){ short i = animFrame % 8; from_rect.offset(18 * i, 18 * num); - rect_draw_some_item(*from_gw, from_rect, getWindow(), to_rect, sf::BlendAlpha); + rect_draw_some_item(*from_gw, from_rect, targ, to_rect, sf::BlendAlpha); } } -void cPict::drawPresetTerMap(short num, rectangle to_rect){ +void cPict::drawPresetTerMap(short num, rectangle to_rect, sf::RenderTarget& targ){ rectangle from_rect = {0,0,12,12}; auto from_gw = getSheet(SHEET_TER_MAP); // TODO: Should probably fill black somewhere in here...? @@ -1030,10 +1032,10 @@ void cPict::drawPresetTerMap(short num, rectangle to_rect){ if(num >= 960) from_rect.offset(12 * 20, 12 * (num - 960)); else from_rect.offset(12 * (num % 20), 12 * (num / 20)); - rect_draw_some_item(*from_gw, from_rect, getWindow(), to_rect); + rect_draw_some_item(*from_gw, from_rect, targ, to_rect); } -void cPict::drawStatusIcon(short num, rectangle to_rect){ +void cPict::drawStatusIcon(short num, rectangle to_rect, sf::RenderTarget& targ){ rectangle from_rect = {0,0,12,12}; auto from_gw = getSheet(SHEET_STATUS); to_rect.right = to_rect.left + 12; @@ -1042,21 +1044,21 @@ void cPict::drawStatusIcon(short num, rectangle to_rect){ if(getFormat(TXT_FRAME)) { rectangle pat_rect = to_rect; pat_rect.inset(-1,-1); - tileImage(getWindow(), pat_rect, bg[6]); + tileImage(targ, pat_rect, bg[6]); } - rect_draw_some_item(*from_gw, from_rect, getWindow(), to_rect, sf::BlendAlpha); + rect_draw_some_item(*from_gw, from_rect, targ, to_rect, sf::BlendAlpha); } -void cPict::drawCustomTer(short num, rectangle to_rect){ +void cPict::drawCustomTer(short num, rectangle to_rect, sf::RenderTarget& targ){ to_rect.right = to_rect.left + 28; to_rect.bottom = to_rect.top + 36; rectangle from_rect; std::shared_ptr from_gw; graf_pos_ref(from_gw, from_rect) = spec_scen_g.find_graphic(num); - rect_draw_some_item(*from_gw, from_rect, getWindow(), to_rect); + rect_draw_some_item(*from_gw, from_rect, targ, to_rect); } -void cPict::drawCustomTerAnim(short num, rectangle to_rect){ +void cPict::drawCustomTerAnim(short num, rectangle to_rect, sf::RenderTarget& targ){ to_rect.right = to_rect.left + 28; to_rect.bottom = to_rect.top + 36; updateAnim(4); @@ -1064,95 +1066,95 @@ void cPict::drawCustomTerAnim(short num, rectangle to_rect){ rectangle from_rect; std::shared_ptr from_gw; graf_pos_ref(from_gw, from_rect) = spec_scen_g.find_graphic(num); - rect_draw_some_item(*from_gw, from_rect, getWindow(), to_rect); + rect_draw_some_item(*from_gw, from_rect, targ, to_rect); } -void cPict::drawCustomMonstSm(short num, rectangle to_rect){ +void cPict::drawCustomMonstSm(short num, rectangle to_rect, sf::RenderTarget& targ){ static const short adj[4] = {0, 2, 1, 3}; updateAnim(4); num += adj[(animLoops != 0 ? animFrame % 4 : 0)]; to_rect.right = to_rect.left + 28; to_rect.bottom = to_rect.top + 36; - if(filled) fill_rect(getWindow(), to_rect, fillClr); + if(filled) fill_rect(targ, to_rect, fillClr); rectangle from_rect; std::shared_ptr from_gw; graf_pos_ref(from_gw, from_rect) = spec_scen_g.find_graphic(num); - rect_draw_some_item(*from_gw, from_rect, getWindow(), to_rect, sf::BlendAlpha); + rect_draw_some_item(*from_gw, from_rect, targ, to_rect, sf::BlendAlpha); } -void cPict::drawCustomMonstWide(short num, rectangle to_rect){ +void cPict::drawCustomMonstWide(short num, rectangle to_rect, sf::RenderTarget& targ){ static const short adj[4] = {0, 4, 2, 6}; updateAnim(4); num += adj[(animLoops != 0 ? animFrame % 4 : 0)]; rectangle small_monst_rect = {0,0,18,14}; to_rect.right = to_rect.left + 28; to_rect.bottom = to_rect.top + 36; - if(filled) fill_rect(getWindow(), to_rect, fillClr); + if(filled) fill_rect(targ, to_rect, fillClr); rectangle from_rect; std::shared_ptr from_gw; graf_pos_ref(from_gw, from_rect) = spec_scen_g.find_graphic(num); small_monst_rect.offset(to_rect.left,to_rect.top + 7); - rect_draw_some_item(*from_gw, from_rect, getWindow(), small_monst_rect, sf::BlendAlpha); + rect_draw_some_item(*from_gw, from_rect, targ, small_monst_rect, sf::BlendAlpha); graf_pos_ref(from_gw, from_rect) = spec_scen_g.find_graphic(num+1); small_monst_rect.offset(14,0); - rect_draw_some_item(*from_gw, from_rect, getWindow(), small_monst_rect, sf::BlendAlpha); + rect_draw_some_item(*from_gw, from_rect, targ, small_monst_rect, sf::BlendAlpha); } -void cPict::drawCustomMonstTall(short num, rectangle to_rect){ +void cPict::drawCustomMonstTall(short num, rectangle to_rect, sf::RenderTarget& targ){ static const short adj[4] = {0, 4, 2, 6}; updateAnim(4); num += adj[(animLoops != 0 ? animFrame % 4 : 0)]; rectangle small_monst_rect = {0,0,18,14}; to_rect.right = to_rect.left + 28; to_rect.bottom = to_rect.top + 36; - if(filled) fill_rect(getWindow(), to_rect, fillClr); + if(filled) fill_rect(targ, to_rect, fillClr); rectangle from_rect; std::shared_ptr from_gw; graf_pos_ref(from_gw, from_rect) = spec_scen_g.find_graphic(num); small_monst_rect.offset(to_rect.left + 7,to_rect.top); - rect_draw_some_item(*from_gw, from_rect, getWindow(), small_monst_rect, sf::BlendAlpha); + rect_draw_some_item(*from_gw, from_rect, targ, small_monst_rect, sf::BlendAlpha); graf_pos_ref(from_gw, from_rect) = spec_scen_g.find_graphic(num+1); small_monst_rect.offset(0,18); - rect_draw_some_item(*from_gw, from_rect, getWindow(), small_monst_rect, sf::BlendAlpha); + rect_draw_some_item(*from_gw, from_rect, targ, small_monst_rect, sf::BlendAlpha); } -void cPict::drawCustomMonstLg(short num, rectangle to_rect){ +void cPict::drawCustomMonstLg(short num, rectangle to_rect, sf::RenderTarget& targ){ static const short adj[4] = {0, 8, 4, 12}; updateAnim(4); num += adj[(animLoops != 0 ? animFrame % 4 : 0)]; rectangle small_monst_rect = {0,0,18,14}; to_rect.right = to_rect.left + 28; to_rect.bottom = to_rect.top + 36; - if(filled) fill_rect(getWindow(), to_rect, fillClr); + if(filled) fill_rect(targ, to_rect, fillClr); rectangle from_rect; std::shared_ptr from_gw; graf_pos_ref(from_gw, from_rect) = spec_scen_g.find_graphic(num); small_monst_rect.offset(to_rect.left,to_rect.top); - rect_draw_some_item(*from_gw, from_rect, getWindow(), small_monst_rect, sf::BlendAlpha); + rect_draw_some_item(*from_gw, from_rect, targ, small_monst_rect, sf::BlendAlpha); graf_pos_ref(from_gw, from_rect) = spec_scen_g.find_graphic(num+1); small_monst_rect.offset(14,0); - rect_draw_some_item(*from_gw, from_rect, getWindow(), small_monst_rect, sf::BlendAlpha); + rect_draw_some_item(*from_gw, from_rect, targ, small_monst_rect, sf::BlendAlpha); graf_pos_ref(from_gw, from_rect) = spec_scen_g.find_graphic(num+2); small_monst_rect.offset(-14,18); - rect_draw_some_item(*from_gw, from_rect, getWindow(), small_monst_rect, sf::BlendAlpha); + rect_draw_some_item(*from_gw, from_rect, targ, small_monst_rect, sf::BlendAlpha); graf_pos_ref(from_gw, from_rect) = spec_scen_g.find_graphic(num+3); small_monst_rect.offset(14,0); - rect_draw_some_item(*from_gw, from_rect, getWindow(), small_monst_rect, sf::BlendAlpha); + rect_draw_some_item(*from_gw, from_rect, targ, small_monst_rect, sf::BlendAlpha); } // This is a super-hacky way to wedge in scaled form, but at least it should work. static int dlog_to_w = 18, dlog_to_h = 36; -void cPict::drawCustomDlog(short num, rectangle to_rect){ +void cPict::drawCustomDlog(short num, rectangle to_rect, sf::RenderTarget& targ){ rectangle from_rect; std::shared_ptr from_gw; graf_pos_ref(from_gw, from_rect) = spec_scen_g.find_graphic(num); @@ -1160,34 +1162,34 @@ void cPict::drawCustomDlog(short num, rectangle to_rect){ to_rect.bottom = to_rect.top + dlog_to_h; from_rect.right = from_rect.left + 18; from_rect.bottom = from_rect.top + 36; - rect_draw_some_item(*from_gw, from_rect, getWindow(), to_rect); + rect_draw_some_item(*from_gw, from_rect, targ, to_rect); graf_pos_ref(from_gw, from_rect) = spec_scen_g.find_graphic(num+1); to_rect.offset(dlog_to_w,0); from_rect.right = from_rect.left + 18; from_rect.bottom = from_rect.top + 36; - rect_draw_some_item(*from_gw, from_rect, getWindow(), to_rect); + rect_draw_some_item(*from_gw, from_rect, targ, to_rect); } -void cPict::drawCustomDlogLg(short num, rectangle to_rect){ +void cPict::drawCustomDlogLg(short num, rectangle to_rect, sf::RenderTarget& targ){ if(drawScaled) { dlog_to_w = 9; dlog_to_h = 18; } - drawCustomDlog(num,to_rect); + drawCustomDlog(num,to_rect,targ); to_rect.offset(dlog_to_h,0); - drawCustomDlog(num + 2,to_rect); + drawCustomDlog(num + 2,to_rect,targ); to_rect.offset(-dlog_to_h,dlog_to_h); - drawCustomDlog(num + 4,to_rect); + drawCustomDlog(num + 4,to_rect,targ); to_rect.offset(dlog_to_h,0); - drawCustomDlog(num + 6,to_rect); + drawCustomDlog(num + 6,to_rect,targ); if(drawScaled) { dlog_to_w = 18; dlog_to_h = 26; } } -void cPict::drawCustomTalk(short num, rectangle to_rect){ +void cPict::drawCustomTalk(short num, rectangle to_rect, sf::RenderTarget& targ){ rectangle from_rect; std::shared_ptr from_gw; graf_pos_ref(from_gw, from_rect) = spec_scen_g.find_graphic(num); @@ -1195,49 +1197,49 @@ void cPict::drawCustomTalk(short num, rectangle to_rect){ to_rect.bottom = to_rect.top + 32; from_rect.right = from_rect.left + 16; from_rect.bottom = from_rect.top + 32; - rect_draw_some_item(*from_gw, from_rect, getWindow(), to_rect); + rect_draw_some_item(*from_gw, from_rect, targ, to_rect); graf_pos_ref(from_gw, from_rect) = spec_scen_g.find_graphic(num+1); to_rect.offset(16,0); from_rect.right = from_rect.left + 16; from_rect.bottom = from_rect.top + 32; - rect_draw_some_item(*from_gw, from_rect, getWindow(), to_rect); + rect_draw_some_item(*from_gw, from_rect, targ, to_rect); } -void cPict::drawCustomItem(short num, rectangle to_rect){ +void cPict::drawCustomItem(short num, rectangle to_rect, sf::RenderTarget& targ){ to_rect.right = to_rect.left + 28; to_rect.bottom = to_rect.top + 36; rectangle from_rect; std::shared_ptr from_gw; graf_pos_ref(from_gw, from_rect) = spec_scen_g.find_graphic(num); - if(filled) fill_rect(getWindow(), to_rect, fillClr); - rect_draw_some_item(*from_gw, from_rect, getWindow(), to_rect, sf::BlendAlpha); + if(filled) fill_rect(targ, to_rect, fillClr); + rect_draw_some_item(*from_gw, from_rect, targ, to_rect, sf::BlendAlpha); } -void cPict::drawCustomTinyItem(short num, rectangle to_rect){ +void cPict::drawCustomTinyItem(short num, rectangle to_rect, sf::RenderTarget& targ){ to_rect.right = to_rect.left + 18; to_rect.bottom = to_rect.top + 18; rectangle from_rect; std::shared_ptr from_gw; graf_pos_ref(from_gw, from_rect) = spec_scen_g.find_graphic(num); - if(filled) fill_rect(getWindow(), to_rect, fillClr); - rect_draw_some_item(*from_gw, from_rect, getWindow(), to_rect, sf::BlendAlpha); + if(filled) fill_rect(targ, to_rect, fillClr); + rect_draw_some_item(*from_gw, from_rect, targ, to_rect, sf::BlendAlpha); } -void cPict::drawCustomBoom(short num, rectangle to_rect){ +void cPict::drawCustomBoom(short num, rectangle to_rect, sf::RenderTarget& targ){ updateAnim(8); to_rect.right = to_rect.left + 28; to_rect.bottom = to_rect.top + 36; rectangle from_rect; std::shared_ptr from_gw; graf_pos_ref(from_gw, from_rect) = spec_scen_g.find_graphic(num + animFrame % 8); - if(filled) fill_rect(getWindow(), to_rect, fillClr); + if(filled) fill_rect(targ, to_rect, fillClr); // When boom loops are over, draw nothing if(animLoops != 0) - rect_draw_some_item(*from_gw, from_rect, getWindow(), to_rect, sf::BlendAlpha); + rect_draw_some_item(*from_gw, from_rect, targ, to_rect, sf::BlendAlpha); } -void cPict::drawCustomMissile(short num, rectangle to_rect){ +void cPict::drawCustomMissile(short num, rectangle to_rect, sf::RenderTarget& targ){ updateAnim(8); num += animFrame % 8; rectangle from_rect; @@ -1246,14 +1248,14 @@ void cPict::drawCustomMissile(short num, rectangle to_rect){ from_rect.right = from_rect.left + 18; from_rect.bottom = from_rect.top + 18; if(animFrame >= 4) from_rect.offset(0, 18); - if(filled) fill_rect(getWindow(), to_rect, fillClr); + if(filled) fill_rect(targ, to_rect, fillClr); to_rect.inset(5,9); // When missile loops are over, draw nothing if(animLoops != 0) - rect_draw_some_item(*from_gw, from_rect, getWindow(), to_rect, sf::BlendAlpha); + rect_draw_some_item(*from_gw, from_rect, targ, to_rect, sf::BlendAlpha); } -void cPict::drawCustomTerMap(short num, rectangle to_rect){ +void cPict::drawCustomTerMap(short num, rectangle to_rect, sf::RenderTarget& targ){ rectangle from_rect; std::shared_ptr from_gw; graf_pos_ref(from_gw, from_rect) = spec_scen_g.find_graphic(num % 1000); @@ -1263,111 +1265,111 @@ void cPict::drawCustomTerMap(short num, rectangle to_rect){ from_rect.offset((num / 3) * 12, (num % 3) * 12); to_rect.right = to_rect.left + 24; to_rect.bottom = to_rect.top + 24; - rect_draw_some_item(*from_gw, from_rect, getWindow(), to_rect); + rect_draw_some_item(*from_gw, from_rect, targ, to_rect); } -void cPict::drawPartyMonstSm(short num, rectangle to_rect){ +void cPict::drawPartyMonstSm(short num, rectangle to_rect, sf::RenderTarget& targ){ to_rect.right = to_rect.left + 28; to_rect.bottom = to_rect.top + 36; std::shared_ptr from_gw; rectangle from_rect; graf_pos_ref(from_gw, from_rect) = spec_scen_g.find_graphic(num, true); - if(filled) fill_rect(getWindow(), to_rect, fillClr); - rect_draw_some_item(*from_gw, from_rect, getWindow(), to_rect, sf::BlendAlpha); + if(filled) fill_rect(targ, to_rect, fillClr); + rect_draw_some_item(*from_gw, from_rect, targ, to_rect, sf::BlendAlpha); } -void cPict::drawPartyMonstWide(short num, rectangle to_rect){ +void cPict::drawPartyMonstWide(short num, rectangle to_rect, sf::RenderTarget& targ){ rectangle small_monst_rect = {0,0,18,14}; to_rect.right = to_rect.left + 28; to_rect.bottom = to_rect.top + 36; - if(filled) fill_rect(getWindow(), to_rect, fillClr); + if(filled) fill_rect(targ, to_rect, fillClr); std::shared_ptr from_gw; rectangle from_rect; graf_pos_ref(from_gw, from_rect) = spec_scen_g.find_graphic(num, true); small_monst_rect.offset(to_rect.left,to_rect.top + 7); - rect_draw_some_item(*from_gw, from_rect, getWindow(), small_monst_rect, sf::BlendAlpha); + rect_draw_some_item(*from_gw, from_rect, targ, small_monst_rect, sf::BlendAlpha); graf_pos_ref(from_gw, from_rect) = spec_scen_g.find_graphic(num+1, true); small_monst_rect.offset(14,0); - rect_draw_some_item(*from_gw, from_rect, getWindow(), small_monst_rect, sf::BlendAlpha); + rect_draw_some_item(*from_gw, from_rect, targ, small_monst_rect, sf::BlendAlpha); } -void cPict::drawPartyMonstTall(short num, rectangle to_rect){ +void cPict::drawPartyMonstTall(short num, rectangle to_rect, sf::RenderTarget& targ){ rectangle small_monst_rect = {0,0,18,14}; to_rect.right = to_rect.left + 28; to_rect.bottom = to_rect.top + 36; - if(filled) fill_rect(getWindow(), to_rect, fillClr); + if(filled) fill_rect(targ, to_rect, fillClr); std::shared_ptr from_gw; rectangle from_rect; graf_pos_ref(from_gw, from_rect) = spec_scen_g.find_graphic(num, true); small_monst_rect.offset(to_rect.left + 7,to_rect.top); - rect_draw_some_item(*from_gw, from_rect, getWindow(), small_monst_rect, sf::BlendAlpha); + rect_draw_some_item(*from_gw, from_rect, targ, small_monst_rect, sf::BlendAlpha); small_monst_rect.offset(0,18); graf_pos_ref(from_gw, from_rect) = spec_scen_g.find_graphic(num+1, true); - rect_draw_some_item(*from_gw, from_rect, getWindow(), small_monst_rect, sf::BlendAlpha); + rect_draw_some_item(*from_gw, from_rect, targ, small_monst_rect, sf::BlendAlpha); } -void cPict::drawPartyMonstLg(short num, rectangle to_rect){ +void cPict::drawPartyMonstLg(short num, rectangle to_rect, sf::RenderTarget& targ){ rectangle small_monst_rect = {0,0,18,14}; to_rect.right = to_rect.left + 28; to_rect.bottom = to_rect.top + 36; - if(filled) fill_rect(getWindow(), to_rect, fillClr); + if(filled) fill_rect(targ, to_rect, fillClr); std::shared_ptr from_gw; rectangle from_rect; graf_pos_ref(from_gw, from_rect) = spec_scen_g.find_graphic(num, true); small_monst_rect.offset(to_rect.left,to_rect.top); - rect_draw_some_item(*from_gw, from_rect, getWindow(), small_monst_rect, sf::BlendAlpha); + rect_draw_some_item(*from_gw, from_rect, targ, small_monst_rect, sf::BlendAlpha); small_monst_rect.offset(14,0); graf_pos_ref(from_gw, from_rect) = spec_scen_g.find_graphic(num+1, true); - rect_draw_some_item(*from_gw, from_rect, getWindow(), small_monst_rect, sf::BlendAlpha); + rect_draw_some_item(*from_gw, from_rect, targ, small_monst_rect, sf::BlendAlpha); small_monst_rect.offset(-14,18); graf_pos_ref(from_gw, from_rect) = spec_scen_g.find_graphic(num+2, true); - rect_draw_some_item(*from_gw, from_rect, getWindow(), small_monst_rect, sf::BlendAlpha); + rect_draw_some_item(*from_gw, from_rect, targ, small_monst_rect, sf::BlendAlpha); small_monst_rect.offset(14,0); graf_pos_ref(from_gw, from_rect) = spec_scen_g.find_graphic(num+3, true); - rect_draw_some_item(*from_gw, from_rect, getWindow(), small_monst_rect, sf::BlendAlpha); + rect_draw_some_item(*from_gw, from_rect, targ, small_monst_rect, sf::BlendAlpha); } -void cPict::drawPartyScen(short num, rectangle to_rect){ +void cPict::drawPartyScen(short num, rectangle to_rect, sf::RenderTarget& targ){ auto from_gw = getSheet(SHEET_HEADER); rectangle from_rect = {0,0,32,32}; from_rect.offset(32 * (num % 5),32 * (num / 5)); to_rect.right = to_rect.left + 32; to_rect.bottom = to_rect.top + 32; - rect_draw_some_item(*from_gw, from_rect, getWindow(), to_rect); + rect_draw_some_item(*from_gw, from_rect, targ, to_rect); } -void cPict::drawPartyItem(short num, rectangle to_rect){ +void cPict::drawPartyItem(short num, rectangle to_rect, sf::RenderTarget& targ){ to_rect.right = to_rect.left + 28; to_rect.bottom = to_rect.top + 36; std::shared_ptr from_gw; rectangle from_rect; graf_pos_ref(from_gw, from_rect) = spec_scen_g.find_graphic(num, true); - if(filled) fill_rect(getWindow(), to_rect, fillClr); - rect_draw_some_item(*from_gw, from_rect, getWindow(), to_rect, sf::BlendAlpha); + if(filled) fill_rect(targ, to_rect, fillClr); + rect_draw_some_item(*from_gw, from_rect, targ, to_rect, sf::BlendAlpha); } -void cPict::drawPartyPc(short num, rectangle to_rect){ +void cPict::drawPartyPc(short num, rectangle to_rect, sf::RenderTarget& targ){ to_rect.right = to_rect.left + 28; to_rect.bottom = to_rect.top + 36; std::shared_ptr from_gw; rectangle from_rect; graf_pos_ref(from_gw, from_rect) = spec_scen_g.find_graphic(num, true); - if(filled) fill_rect(getWindow(), to_rect, fillClr); - rect_draw_some_item(*from_gw, from_rect, getWindow(), to_rect, sf::BlendAlpha); + if(filled) fill_rect(targ, to_rect, fillClr); + rect_draw_some_item(*from_gw, from_rect, targ, to_rect, sf::BlendAlpha); } -void cPict::drawInvenBtn(short num, rectangle to_rect){ +void cPict::drawInvenBtn(short num, rectangle to_rect, sf::RenderTarget& targ){ static rectangle from_rect[]{ {0, 1, 12, 13}, // pc info {0, 13, 12, 25}, // pc switch @@ -1401,6 +1403,16 @@ void cPict::drawAt(sf::RenderWindow& win, rectangle dest, pic_num_t which_g, ePi pic.draw(); } +// TODO the win argument shouldn't be needed +void cPict::drawAt(sf::RenderWindow& win, sf::RenderTarget& targ, rectangle dest, pic_num_t which_g, ePicType type_g, bool framed) { + cParentless wrapper(win); + cPict pic(wrapper); + pic.frame = dest; + pic.setPict(which_g, type_g); + pic.setFormat(TXT_FRAME, framed ? FRM_SOLID : FRM_NONE); + pic.draw(targ); +} + cControl::storage_t cPict::store() const { storage_t storage = cControl::store(); storage["pic-num"] = picNum; diff --git a/src/dialogxml/widgets/pict.hpp b/src/dialogxml/widgets/pict.hpp index 15c16c588..4e8317aa0 100644 --- a/src/dialogxml/widgets/pict.hpp +++ b/src/dialogxml/widgets/pict.hpp @@ -66,6 +66,7 @@ class cPict : public cControl { static void advanceAnim(); virtual ~cPict(); void draw() override; + void draw(sf::RenderTarget& target); /// A utility function to draw an icon into an arbitrary window. /// @param win The window to draw in. /// @param dest The bounding rect to draw in (ignored for drawing the actual, but used for background fill and framing) @@ -73,6 +74,7 @@ class cPict : public cControl { /// @param type_g The type of icon to draw. /// @param framed Whether to draw a frame around the icon. static void drawAt(sf::RenderWindow& win, rectangle dest, pic_num_t which_g, ePicType type_g, bool framed); + static void drawAt(sf::RenderWindow& win, sf::RenderTarget& targ, rectangle dest, pic_num_t which_g, ePicType type_g, bool framed); /// A convenience constant that can be passed as the pic number to setPict(pic_num_t num). /// It sets the icon to nothing, showing as just black. static const pic_num_t BLANK; @@ -102,49 +104,49 @@ class cPict : public cControl { sf::Color fillClr = sf::Color::Black; // Transient parse flags bool wide = false, tall = false, tiny = false, custom = false, blank = false, filled = true; - void drawPresetTer(short num, rectangle to_rect); - void drawPresetTerAnim(short num, rectangle to_rect); - void drawPresetMonstSm(short num, rectangle to_rect); - void drawPresetMonstWide(short num, rectangle to_rect); - void drawPresetMonstTall(short num, rectangle to_rect); - void drawPresetMonstLg(short num, rectangle to_rect); - void drawPresetDlog(short num, rectangle to_rect); - void drawPresetDlogLg(short num, rectangle to_rect); - void drawPresetTalk(short num, rectangle to_rect); - void drawPresetScen(short num, rectangle to_rect); - void drawPresetScenLg(short num, rectangle to_rect); - void drawPresetItem(short num, rectangle to_rect); - void drawPresetTinyItem(short num, rectangle to_rect); - void drawPresetPc(short num, rectangle to_rect); - void drawPresetField(short num, rectangle to_rect); - void drawPresetBoom(short num, rectangle to_rect); - void drawPresetMissile(short num, rectangle to_rect); - void drawPresetTerMap(short num, rectangle to_rect); - void drawStatusIcon(short num, rectangle to_rect); - void drawFullSheet(short num, rectangle to_rect); - void drawCustomTer(short num, rectangle to_rect); - void drawCustomTerAnim(short num, rectangle to_rect); - void drawCustomMonstSm(short num, rectangle to_rect); - void drawCustomMonstWide(short num, rectangle to_rect); - void drawCustomMonstTall(short num, rectangle to_rect); - void drawCustomMonstLg(short num, rectangle to_rect); - void drawCustomDlog(short num, rectangle to_rect); - void drawCustomDlogLg(short num, rectangle to_rect); - void drawCustomTalk(short num, rectangle to_rect); - void drawCustomItem(short num, rectangle to_rect); - void drawCustomTinyItem(short num, rectangle to_rect); - void drawCustomBoom(short num, rectangle to_rect); - void drawCustomMissile(short num, rectangle to_rect); - void drawCustomTerMap(short num, rectangle to_rect); - void drawPartyMonstSm(short num, rectangle to_rect); - void drawPartyMonstWide(short num, rectangle to_rect); - void drawPartyMonstTall(short num, rectangle to_rect); - void drawPartyMonstLg(short num, rectangle to_rect); - void drawPartyScen(short num, rectangle to_rect); - void drawPartyItem(short num, rectangle to_rect); - void drawPartyPc(short num, rectangle to_rect); - void drawInvenBtn(short num, rectangle to_rect); - static std::map& drawPict(); + void drawPresetTer(short num, rectangle to_rect, sf::RenderTarget& targ); + void drawPresetTerAnim(short num, rectangle to_rect, sf::RenderTarget& targ); + void drawPresetMonstSm(short num, rectangle to_rect, sf::RenderTarget& targ); + void drawPresetMonstWide(short num, rectangle to_rect, sf::RenderTarget& targ); + void drawPresetMonstTall(short num, rectangle to_rect, sf::RenderTarget& targ); + void drawPresetMonstLg(short num, rectangle to_rect, sf::RenderTarget& targ); + void drawPresetDlog(short num, rectangle to_rect, sf::RenderTarget& targ); + void drawPresetDlogLg(short num, rectangle to_rect, sf::RenderTarget& targ); + void drawPresetTalk(short num, rectangle to_rect, sf::RenderTarget& targ); + void drawPresetScen(short num, rectangle to_rect, sf::RenderTarget& targ); + void drawPresetScenLg(short num, rectangle to_rect, sf::RenderTarget& targ); + void drawPresetItem(short num, rectangle to_rect, sf::RenderTarget& targ); + void drawPresetTinyItem(short num, rectangle to_rect, sf::RenderTarget& targ); + void drawPresetPc(short num, rectangle to_rect, sf::RenderTarget& targ); + void drawPresetField(short num, rectangle to_rect, sf::RenderTarget& targ); + void drawPresetBoom(short num, rectangle to_rect, sf::RenderTarget& targ); + void drawPresetMissile(short num, rectangle to_rect, sf::RenderTarget& targ); + void drawPresetTerMap(short num, rectangle to_rect, sf::RenderTarget& targ); + void drawStatusIcon(short num, rectangle to_rect, sf::RenderTarget& targ); + void drawFullSheet(short num, rectangle to_rect, sf::RenderTarget& targ); + void drawCustomTer(short num, rectangle to_rect, sf::RenderTarget& targ); + void drawCustomTerAnim(short num, rectangle to_rect, sf::RenderTarget& targ); + void drawCustomMonstSm(short num, rectangle to_rect, sf::RenderTarget& targ); + void drawCustomMonstWide(short num, rectangle to_rect, sf::RenderTarget& targ); + void drawCustomMonstTall(short num, rectangle to_rect, sf::RenderTarget& targ); + void drawCustomMonstLg(short num, rectangle to_rect, sf::RenderTarget& targ); + void drawCustomDlog(short num, rectangle to_rect, sf::RenderTarget& targ); + void drawCustomDlogLg(short num, rectangle to_rect, sf::RenderTarget& targ); + void drawCustomTalk(short num, rectangle to_rect, sf::RenderTarget& targ); + void drawCustomItem(short num, rectangle to_rect, sf::RenderTarget& targ); + void drawCustomTinyItem(short num, rectangle to_rect, sf::RenderTarget& targ); + void drawCustomBoom(short num, rectangle to_rect, sf::RenderTarget& targ); + void drawCustomMissile(short num, rectangle to_rect, sf::RenderTarget& targ); + void drawCustomTerMap(short num, rectangle to_rect, sf::RenderTarget& targ); + void drawPartyMonstSm(short num, rectangle to_rect, sf::RenderTarget& targ); + void drawPartyMonstWide(short num, rectangle to_rect, sf::RenderTarget& targ); + void drawPartyMonstTall(short num, rectangle to_rect, sf::RenderTarget& targ); + void drawPartyMonstLg(short num, rectangle to_rect, sf::RenderTarget& targ); + void drawPartyScen(short num, rectangle to_rect, sf::RenderTarget& targ); + void drawPartyItem(short num, rectangle to_rect, sf::RenderTarget& targ); + void drawPartyPc(short num, rectangle to_rect, sf::RenderTarget& targ); + void drawInvenBtn(short num, rectangle to_rect, sf::RenderTarget& targ); + static std::map& drawPict(); }; #endif From 70cc6828e2b641ee860ac8b67db0520913c60897 Mon Sep 17 00:00:00 2001 From: Nat Quayle Nelson Date: Mon, 23 Jun 2025 18:58:58 -0500 Subject: [PATCH 08/17] import terrain icons to custom sheets --- rsrc/dialogs/graphic-sheets.xml | 4 + src/scenedit/scen.core.cpp | 177 +++++++++++++++++++++----------- 2 files changed, 121 insertions(+), 60 deletions(-) diff --git a/rsrc/dialogs/graphic-sheets.xml b/rsrc/dialogs/graphic-sheets.xml index cc905a8f6..9b69a37a4 100644 --- a/rsrc/dialogs/graphic-sheets.xml +++ b/rsrc/dialogs/graphic-sheets.xml @@ -22,6 +22,10 @@ - 0 + + + + diff --git a/src/scenedit/scen.core.cpp b/src/scenedit/scen.core.cpp index 85ef359ea..ec9873231 100644 --- a/src/scenedit/scen.core.cpp +++ b/src/scenedit/scen.core.cpp @@ -3712,13 +3712,35 @@ void edit_custom_pics_types() { pic_dlg.run(); } +extern fs::path tempDir; +extern std::string scenario_temp_dir_name; + +// Keep a single RenderTexture for splicing together custom graphics +bool canvas_created = false; +static sf::RenderTexture& canvas() { + static sf::RenderTexture instance; + if(!canvas_created){ + instance.create(280, 360); + canvas_created = true; + } + return instance; +} + static void set_dlg_custom_sheet(cDialog& me, size_t sheet) { me["num"].setTextToNum(sheet); dynamic_cast(me["sheet"]).setPict(sheet, PIC_FULL); } -extern fs::path tempDir; -extern std::string scenario_temp_dir_name; +static void set_up_canvas(size_t sheet){ + fs::path pic_dir = tempDir/scenario_temp_dir_name/"graphics"; + fs::path fromPath = pic_dir/("sheet" + std::to_string(sheet) + ".png"); + + sf::Texture texture; + texture.loadFromFile(fromPath.string()); + sf::Sprite s(texture); + canvas().clear(sf::Color(0,0,0,0)); + canvas().draw(s); +} void edit_custom_sheets() { // Everything you do in this dialog can be undone when you hit cancel, leaving no trace in the main history. @@ -3781,9 +3803,63 @@ void edit_custom_sheets() { sheets[i] = spec_scen_g.sheets[i]->copyToImage(); } - using namespace std::placeholders; - cDialog pic_dlg(*ResMgr::dialogs.get("graphic-sheets")); + + auto replace_from_file = [&pic_dlg,&sheets,&cur,&all_pics,&pic_dir,&deferred_actions](std::string action_name, fs::path fpath) -> bool { + sf::Image img; + if(!img.loadFromFile(fpath.string().c_str())) { + beep(); + return true; + } + if(cur >= spec_scen_g.numSheets) { + std::string resName = "sheet" + std::to_string(all_pics[cur]); + fs::path toPath = pic_dir/(resName + ".png"); + + sf::Image image_for_undo; + // TODO for reload, old image and new image will be the same! This could possibly be addressed by loading the image when edit is clicked? + // But there is no guarantee Edit is clicked first--the designer could externally edit the full-sheet image whenever they want. + + // Also comparing image blobs for equality is probably expensive, but we should have a check to prevent adding undo actions if the same file was imported + // or reload is clicked when the file isn't changed. + image_for_undo.loadFromFile(toPath.string()); + deferred_actions.push_back(action_ptr(new aReplaceGraphicsSheet(action_name, all_pics[cur], image_for_undo, img))); + + img.saveToFile(toPath.string().c_str()); + ResMgr::graphics.free(resName); + set_dlg_custom_sheet(pic_dlg, all_pics[cur]); + return true; + } + deferred_actions.push_back(action_ptr(new aReplaceGraphicsSheet(action_name, all_pics[cur], sheets[cur], img))); + + sheets[cur] = img; + spec_scen_g.replace_sheet(cur, img); + set_dlg_custom_sheet(pic_dlg, all_pics[cur]); + return true; + }; + + auto replace_from_image = [&cur, &all_pics, pic_dir, &deferred_actions, &sheets, &pic_dlg](std::string action_name, sf::Image& image) -> bool { + if(cur >= spec_scen_g.numSheets) { + std::string resName = "sheet" + std::to_string(all_pics[cur]); + fs::path toPath = pic_dir/(resName + ".png"); + + sf::Image image_for_undo; + image_for_undo.loadFromFile(toPath.string()); + deferred_actions.push_back(action_ptr(new aReplaceGraphicsSheet(action_name, all_pics[cur], image_for_undo, image))); + + image.saveToFile(toPath.string().c_str()); + ResMgr::graphics.free(resName); + set_dlg_custom_sheet(pic_dlg, all_pics[cur]); + return true; + } + deferred_actions.push_back(action_ptr(new aReplaceGraphicsSheet(action_name, cur, sheets[cur], image))); + + sheets[cur] = image; + spec_scen_g.replace_sheet(cur, image); + set_dlg_custom_sheet(pic_dlg, all_pics[cur]); + return true; + }; + + using namespace std::placeholders; pic_dlg["cancel"].attachClickHandler(std::bind(&cDialog::toast, _1, false)); pic_dlg["okay"].attachClickHandler(std::bind(&cDialog::toast, _1, true)); pic_dlg["copy"].attachClickHandler([&sheets,&cur,&all_pics,&pic_dir](cDialog&, std::string, eKeyMod) -> bool { @@ -3797,32 +3873,13 @@ void edit_custom_sheets() { set_clipboard_img(sheets[cur]); return true; }); - pic_dlg["paste"].attachClickHandler([&sheets,&cur,&all_pics,&pic_dir,&deferred_actions](cDialog& me, std::string, eKeyMod) -> bool { + pic_dlg["paste"].attachClickHandler([&sheets,&cur,&all_pics,&pic_dir,&deferred_actions,replace_from_image](cDialog& me, std::string, eKeyMod) -> bool { auto img = get_clipboard_img(); if(img == nullptr) { beep(); return true; } - sf::Image new_image = *img; - if(cur >= spec_scen_g.numSheets) { - std::string resName = "sheet" + std::to_string(all_pics[cur]); - fs::path toPath = pic_dir/(resName + ".png"); - - sf::Image image_for_undo; - image_for_undo.loadFromFile(toPath.string()); - deferred_actions.push_back(action_ptr(new aReplaceGraphicsSheet("Paste Graphics Sheet", all_pics[cur], image_for_undo, new_image))); - - img->saveToFile(toPath.string().c_str()); - ResMgr::graphics.free(resName); - set_dlg_custom_sheet(me, all_pics[cur]); - return true; - } - deferred_actions.push_back(action_ptr(new aReplaceGraphicsSheet("Paste Graphics Sheet", cur, sheets[cur], new_image))); - - sheets[cur] = *img; - spec_scen_g.replace_sheet(cur, *img); - set_dlg_custom_sheet(me, all_pics[cur]); - return true; + return replace_from_image("Paste Graphics Sheet", *img); }); pic_dlg["edit"].attachClickHandler([&sheets,&cur,&all_pics,&pic_dir](cDialog&, std::string, eKeyMod) -> bool { fs::path image_editor = get_string_pref("ImageEditor"); @@ -3854,44 +3911,11 @@ void edit_custom_sheets() { } return true; }); - - auto replace_from_file = [&pic_dlg,&sheets,&cur,&all_pics,&pic_dir,&deferred_actions](std::string action_name, fs::path fpath) -> bool { - sf::Image img; - if(!img.loadFromFile(fpath.string().c_str())) { - beep(); - return true; - } - if(cur >= spec_scen_g.numSheets) { - std::string resName = "sheet" + std::to_string(all_pics[cur]); - fs::path toPath = pic_dir/(resName + ".png"); - - sf::Image image_for_undo; - // TODO for reload, old image and new image will be the same! This could possibly be addressed by loading the image when edit is clicked? - // But there is no guarantee Edit is clicked first--the designer could externally edit the full-sheet image whenever they want. - - // Also comparing image blobs for equality is probably expensive, but we should have a check to prevent adding undo actions if the same file was imported - // or reload is clicked when the file isn't changed. - image_for_undo.loadFromFile(toPath.string()); - deferred_actions.push_back(action_ptr(new aReplaceGraphicsSheet(action_name, all_pics[cur], image_for_undo, img))); - - img.saveToFile(toPath.string().c_str()); - ResMgr::graphics.free(resName); - set_dlg_custom_sheet(pic_dlg, all_pics[cur]); - return true; - } - deferred_actions.push_back(action_ptr(new aReplaceGraphicsSheet(action_name, all_pics[cur], sheets[cur], img))); - - sheets[cur] = img; - spec_scen_g.replace_sheet(cur, img); - set_dlg_custom_sheet(pic_dlg, all_pics[cur]); - return true; - }; pic_dlg["reload"].attachClickHandler([replace_from_file, &all_pics, &cur, &pic_dir](cDialog&, std::string, eKeyMod) -> bool { std::string resName = "sheet" + std::to_string(all_pics[cur]); fs::path sheetPath = pic_dir/(resName + ".png"); - replace_from_file("Reload Graphics Sheet", sheetPath); - return true; + return replace_from_file("Reload Graphics Sheet", sheetPath); }); pic_dlg["open"].attachClickHandler([replace_from_file](cDialog& me, std::string, eKeyMod) -> bool { fs::path fpath = nav_get_rsrc({"png", "bmp", "jpg", "jpeg", "gif", "psd"}); @@ -4012,12 +4036,22 @@ void edit_custom_sheets() { int icon_end = 0; int icon_min = 0; int icon_max = 0; - auto show_icon_selection = [&icon_min, &icon_max, &pic_dlg]() { + + std::vector icon_buttons = {"icon-terr", "strip-terr", "add-terr"}; + auto show_icon_selection = [&icon_min, &icon_max, &pic_dlg, icon_buttons]() { pic_dlg["icon-min"].setTextToNum(icon_min); pic_dlg["icon-max"].setTextToNum(icon_max); // TODO highlight the selected icons visually + for(auto name : icon_buttons){ + if(icon_min != 0){ + pic_dlg[name].show(); + }else{ + pic_dlg[name].hide(); + } + } }; + show_icon_selection(); pic_dlg.attachClickHandlers([&sheets,&cur,&all_pics,show_icon_selection,&icon_start,&icon_end,&icon_min,&icon_max](cDialog& me, std::string dir, eKeyMod) -> bool { size_t old_cur = cur; if(dir == "left") { @@ -4066,6 +4100,29 @@ void edit_custom_sheets() { return true; }); + pic_dlg.attachClickHandlers([&icon_max, &icon_min, &all_pics, &cur, replace_from_image](cDialog& me, std::string item_hit, eKeyMod) -> bool { + if(item_hit == "icon-terr"){ + pic_num_t icon = choose_graphic(0, PIC_TER, &me); + set_up_canvas(all_pics[cur]); + int sheet_start = 1000 + 100 * all_pics[cur]; + for(int i = 0; i < (icon_max - icon_min) + 1; ++i){ + int sheet_icon = icon_min + i - sheet_start; + int x = sheet_icon % 10; + int y = sheet_icon / 10; + rectangle dest {y * 36, x * 28, y * 36 + 36, x * 28 + 28}; + cPict::drawAt(mainPtr(),canvas(),dest,icon+i,PIC_TER,false); + } + canvas().display(); + sf::Image img = canvas().getTexture().copyToImage(); + return replace_from_image("Import Terrain Icon", img); + }else if(item_hit == "strip-terr"){ + + }else if(item_hit == "add-terr"){ + + } + return true; + },icon_buttons); + shut_down_menus(5); // So that cmd+O, cmd+N, cmd+S can work pic_dlg.run(); From 5d052d72e9885cd86de1dbb683f80e041a4f6430 Mon Sep 17 00:00:00 2001 From: Nat Quayle Nelson Date: Mon, 23 Jun 2025 20:34:42 -0500 Subject: [PATCH 09/17] strip and re-add terrain backgrounds --- rsrc/dialogs/graphic-sheets.xml | 1 + src/scenedit/scen.core.cpp | 112 ++++++++++++++++++++++++++++---- 2 files changed, 100 insertions(+), 13 deletions(-) diff --git a/rsrc/dialogs/graphic-sheets.xml b/rsrc/dialogs/graphic-sheets.xml index 9b69a37a4..9fbb8af27 100644 --- a/rsrc/dialogs/graphic-sheets.xml +++ b/rsrc/dialogs/graphic-sheets.xml @@ -24,6 +24,7 @@ + 0 diff --git a/src/scenedit/scen.core.cpp b/src/scenedit/scen.core.cpp index 69f116056..d950579e4 100644 --- a/src/scenedit/scen.core.cpp +++ b/src/scenedit/scen.core.cpp @@ -4016,7 +4016,29 @@ class cCustomGraphicsDialog { void show_icon_selection() { dlg["icon-min"].setTextToNum(icon_min); dlg["icon-max"].setTextToNum(icon_max); - // TODO highlight the selected icons visually + + // Clear selection lines + for(int y = 0; y < 11; ++y){ + for(int x = 0; x < 11; ++x){ + if(x < 10) + dlg["zrow-x" + std::to_string(x) + "y" + std::to_string(y)].hide(); + if(y < 10) + dlg["zcol-x" + std::to_string(x) + "y" + std::to_string(y)].hide(); + } + } + // highlight the selected icons visually + for(int y = 0; y < 10; ++y){ + for(int x = 0; x < 10; ++x){ + int icon = 1000 + 100 * all_pics[cur] + y * 10 + x; + if(icon >= icon_min && icon <= icon_max){ + dlg["zrow-x" + std::to_string(x) + "y" + std::to_string(y)].show(); + dlg["zrow-x" + std::to_string(x) + "y" + std::to_string(y+1)].show(); + dlg["zcol-x" + std::to_string(x) + "y" + std::to_string(y)].show(); + dlg["zcol-x" + std::to_string(x + 1) + "y" + std::to_string(y)].show(); + } + } + } + if(icon_min != 0){ for(auto name : icon_buttons){ dlg[name].show(); From 198c0a0f6bb02dbb60dd6a4aef6933670534be8a Mon Sep 17 00:00:00 2001 From: Nat Quayle Nelson Date: Thu, 31 Jul 2025 11:27:46 -0500 Subject: [PATCH 12/17] add function call that prevents black custom sheet canvas --- src/scenedit/scen.core.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/scenedit/scen.core.cpp b/src/scenedit/scen.core.cpp index d950579e4..e30e9b183 100644 --- a/src/scenedit/scen.core.cpp +++ b/src/scenedit/scen.core.cpp @@ -3766,6 +3766,8 @@ class cCustomGraphicsDialog { sf::Sprite s(texture); canvas().clear(sf::Color(0,0,0,0)); canvas().draw(s); + // For some reason, without this call, the canvas becomes black! + canvas().getTexture().copyToImage(); } // Set which custom sheet is viewed From 4710a2aac95c0f3d89a34f9bdfcadf904eee9b2a Mon Sep 17 00:00:00 2001 From: Nat Quayle Nelson Date: Thu, 31 Jul 2025 11:43:56 -0500 Subject: [PATCH 13/17] try fix test compilation --- test/catch.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/test/catch.cpp b/test/catch.cpp index a0d1033a8..3c444d992 100644 --- a/test/catch.cpp +++ b/test/catch.cpp @@ -19,6 +19,7 @@ std::vector extra_scen_dirs; std::string help_text_rsrc; bool check_for_interrupt(std::string) { return false; } +void save_prefs() {} // And these are referenced from the scenario code, though not used in test cases #include "scenario/scenario.hpp" From a2f0654a252811c7578c5179c3092d48a994fead Mon Sep 17 00:00:00 2001 From: Nat Quayle Nelson Date: Thu, 31 Jul 2025 11:59:58 -0500 Subject: [PATCH 14/17] Fix undo reload/import full-sheet graphic --- src/scenedit/scen.core.cpp | 29 +++++++++++++++++------------ 1 file changed, 17 insertions(+), 12 deletions(-) diff --git a/src/scenedit/scen.core.cpp b/src/scenedit/scen.core.cpp index e30e9b183..cb49f5e16 100644 --- a/src/scenedit/scen.core.cpp +++ b/src/scenedit/scen.core.cpp @@ -3791,13 +3791,10 @@ class cCustomGraphicsDialog { std::string resName = "sheet" + std::to_string(all_pics[cur]); fs::path toPath = pic_dir/(resName + ".png"); - sf::Image image_for_undo; - // TODO for reload, old image and new image will be the same! This could possibly be addressed by loading the image when edit is clicked? - // But there is no guarantee Edit is clicked first--the designer could externally edit the full-sheet image whenever they want. - - // Also comparing image blobs for equality is probably expensive, but we should have a check to prevent adding undo actions if the same file was imported - // or reload is clicked when the file isn't changed. - image_for_undo.loadFromFile(toPath.string()); + sf::Image image_for_undo = sheets[all_pics[cur]]; + // Comparing image blobs for equality is probably expensive, but maybe + // we should have a check to prevent adding undo actions if the same + // file was imported or reload is clicked when the file isn't changed. deferred_actions.push_back(action_ptr(new aReplaceGraphicsSheet(action_name, all_pics[cur], image_for_undo, img))); img.saveToFile(toPath.string().c_str()); @@ -3944,7 +3941,7 @@ class cCustomGraphicsDialog { cur = iter - all_pics.begin(); sf::Image img; img.create(280, 360); - img.saveToFile(sheetPath.string().c_str()); + img.saveToFile(sheetPath.string()); } dlg["left"].show(); dlg["right"].show(); @@ -4234,7 +4231,7 @@ class cCustomGraphicsDialog { spec_scen_g.sheets.resize(1); spec_scen_g.numSheets = 1; spec_scen_g.init_sheet(0); - spec_scen_g.sheets[0]->copyToImage().saveToFile((pic_dir/"sheet0.png").string().c_str()); + spec_scen_g.sheets[0]->copyToImage().saveToFile((pic_dir/"sheet0.png").string()); all_pics.insert(all_pics.begin(), 0); ResMgr::graphics.pushPath(pic_dir); @@ -4244,9 +4241,17 @@ class cCustomGraphicsDialog { set_cursor(watch_curs); - // Get image data from the sheets in memory - for(size_t i = 0; i < spec_scen_g.numSheets; i++) { - sheets[i] = spec_scen_g.sheets[i]->copyToImage(); + for(size_t idx : all_pics) { + // Get image data from the sheets in memory + if(idx < spec_scen_g.numSheets){ + sheets[idx] = spec_scen_g.sheets[idx]->copyToImage(); + } + // Get image data from sheets not in memory + else{ + sf::Texture texture; + texture.loadFromFile((pic_dir/("sheet" + std::to_string(idx) + ".png")).string()); + sheets[idx] = texture.copyToImage(); + } } using namespace std::placeholders; From 0878388c0892c11eef0ef1a204130cc3d7bc68df Mon Sep 17 00:00:00 2001 From: Nat Quayle Nelson Date: Thu, 31 Jul 2025 13:31:26 -0500 Subject: [PATCH 15/17] fix updating the in-memory image for full-sheets replaced --- src/scenedit/scen.core.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/scenedit/scen.core.cpp b/src/scenedit/scen.core.cpp index cb49f5e16..e07b999af 100644 --- a/src/scenedit/scen.core.cpp +++ b/src/scenedit/scen.core.cpp @@ -3796,7 +3796,7 @@ class cCustomGraphicsDialog { // we should have a check to prevent adding undo actions if the same // file was imported or reload is clicked when the file isn't changed. deferred_actions.push_back(action_ptr(new aReplaceGraphicsSheet(action_name, all_pics[cur], image_for_undo, img))); - + sheets[all_pics[cur]] = img; img.saveToFile(toPath.string().c_str()); ResMgr::graphics.free(resName); set_dlg_custom_sheet(all_pics[cur]); @@ -3819,6 +3819,7 @@ class cCustomGraphicsDialog { sf::Image image_for_undo; image_for_undo.loadFromFile(toPath.string()); deferred_actions.push_back(action_ptr(new aReplaceGraphicsSheet(action_name, all_pics[cur], image_for_undo, image))); + sheets[all_pics[cur]] = image; image.saveToFile(toPath.string().c_str()); ResMgr::graphics.free(resName); From ceac9f5d7270a7312c5088beb2ae97bd60d88958 Mon Sep 17 00:00:00 2001 From: Nat Quayle Nelson Date: Thu, 31 Jul 2025 14:37:20 -0500 Subject: [PATCH 16/17] add donor to credits --- pkg/credits/Funding.txt | 1 + rsrc/dialogs/about-boe.xml | 9 +++++---- rsrc/graphics/startanim.png | Bin 24905 -> 25086 bytes 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/pkg/credits/Funding.txt b/pkg/credits/Funding.txt index aca5479d8..905a2baf7 100644 --- a/pkg/credits/Funding.txt +++ b/pkg/credits/Funding.txt @@ -25,6 +25,7 @@ Confirmed: - K L - Laura Nelson - Mariann Krizsan +- Maryanne Wachter - Mike Lapinsky - Nathan Rickey - Nick Chaimov diff --git a/rsrc/dialogs/about-boe.xml b/rsrc/dialogs/about-boe.xml index f290fba02..ca7bc931a 100644 --- a/rsrc/dialogs/about-boe.xml +++ b/rsrc/dialogs/about-boe.xml @@ -18,11 +18,11 @@ ORIGINAL GAME:





- OPEN SOURCE CREDITS:











































































+ OPEN SOURCE CREDITS:












































































SCENARIO FIXES AND UPDATES:

- +
Concept, Design, Programming:
Graphics:
@@ -34,11 +34,11 @@ Graphics:






Consulting:



Testing and Troubleshooting:

- Funding:













































+ Funding:
















































Bandit Busywork:
- +
Jeff Vogel
Andrew Hunter
@@ -99,6 +99,7 @@ K L
Laura Nelson
Mariann Krizsan
+ Maryanne Wachter
Mike Lapinsky
Nathan Rickey
Nick Chaimov
diff --git a/rsrc/graphics/startanim.png b/rsrc/graphics/startanim.png index e4443d9a8181159680d516f2b316fcbfd71c81df..b10cb955fbc59aabd068fd33ea258189d1864f3f 100644 GIT binary patch delta 2874 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 delta 2681 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 From 304f8f20ee45e276d59186ed41d6513c0dfb7240 Mon Sep 17 00:00:00 2001 From: Nat Quayle Nelson Date: Thu, 31 Jul 2025 19:57:52 -0500 Subject: [PATCH 17/17] Load image directly Co-authored-by: Celtic Minstrel --- src/scenedit/scen.core.cpp | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/scenedit/scen.core.cpp b/src/scenedit/scen.core.cpp index e07b999af..56afa76ea 100644 --- a/src/scenedit/scen.core.cpp +++ b/src/scenedit/scen.core.cpp @@ -4249,9 +4249,7 @@ class cCustomGraphicsDialog { } // Get image data from sheets not in memory else{ - sf::Texture texture; - texture.loadFromFile((pic_dir/("sheet" + std::to_string(idx) + ".png")).string()); - sheets[idx] = texture.copyToImage(); + sheets[idx].loadFromFile((pic_dir/("sheet" + std::to_string(idx) + ".png")).string()); } }