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/dialogs/graphic-sheets.xml b/rsrc/dialogs/graphic-sheets.xml
index 982a5d456..3fef7fe74 100644
--- a/rsrc/dialogs/graphic-sheets.xml
+++ b/rsrc/dialogs/graphic-sheets.xml
@@ -1,5 +1,4 @@
-
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/rsrc/graphics/startanim.png b/rsrc/graphics/startanim.png
index e4443d9a8..b10cb955f 100644
Binary files a/rsrc/graphics/startanim.png and b/rsrc/graphics/startanim.png differ
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
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.core.cpp b/src/scenedit/scen.core.cpp
index 641b9c662..56afa76ea 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"
@@ -3710,147 +3712,199 @@ void edit_custom_pics_types() {
pic_dlg.run();
}
-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;
-void edit_custom_sheets() {
+class cCustomGraphicsDialog {
+private:
+ cDialog dlg;
+ size_t cur = 0;
+ std::unordered_map sheets;
// Everything you do in this dialog can be undone when you hit cancel, leaving no trace in the main history.
std::vector deferred_actions;
int max_pic = -1;
std::vector all_pics;
- fs::path pic_dir = tempDir/scenario_temp_dir_name/"graphics";
- if(!scenario.scen_file.has_extension()) // It's an unpacked scenario
- pic_dir = scenario.scen_file/"graphics";
- if(!fs::exists(pic_dir)) fs::create_directories(pic_dir);
- for(fs::directory_iterator iter(pic_dir); iter != fs::directory_iterator(); iter++) {
- std::string fname = iter->path().filename().string().c_str();
- int dot = fname.find_last_of('.');
- if(fname.substr(0,5) == "sheet" && fname.substr(dot) == ".png" && std::all_of(fname.begin()+5, fname.begin()+dot, isdigit)) {
- int this_pic = boost::lexical_cast(fname.substr(5,dot-5));
- max_pic = max(max_pic, this_pic);
- all_pics.push_back(this_pic);
+ fs::path pic_dir;
+
+ // Icon selection info
+ int icon_start = 0;
+ int icon_end = 0;
+ int icon_min = 0;
+ int icon_max = 0;
+ // Buttons for working with icons
+ std::vector icon_buttons = {"icon-terr", "strip-terr", "add-terr"};
+
+ // Keep a single RenderTexture for splicing together custom graphics on a sheet
+ static sf::RenderTexture& canvas() {
+ static bool canvas_created = false;
+ static sf::RenderTexture instance;
+ if(!canvas_created){
+ instance.create(280, 360);
+ canvas_created = true;
}
+ return instance;
}
- // Iterating through the graphics folder is not deterministic
- std::sort(all_pics.begin(), all_pics.end());
-
- // First, make sure we even have custom graphics! Also make sure they're not legacy format.
- bool must_init_spec_g = false;
- if(spec_scen_g.is_old) {
- if(cChoiceDlog("convert-pics-now", {"cancel", "convert"}).show() == "cancel")
- return;
- spec_scen_g.convert_sheets();
- all_pics.resize(spec_scen_g.numSheets);
- std::iota(all_pics.begin(), all_pics.end(), 0);
- } else if(max_pic < 0) {
- if(cChoiceDlog("have-no-pics", {"cancel", "new"}).show() == "cancel")
- return;
- must_init_spec_g = true;
- } else if(max_pic >= 0 && spec_scen_g.numSheets < 1) {
- if(cChoiceDlog("have-only-full-pics", {"cancel", "new"}).show() == "new")
- must_init_spec_g = true;
+
+ // Keep a 1-tile RenderTexture for rendering new tiles
+ static sf::RenderTexture& scratch() {
+ static bool scratch_created = false;
+ static sf::RenderTexture instance;
+ if(!scratch_created){
+ instance.create(28, 36);
+ scratch_created = true;
+ }
+ return instance;
}
-
- if(must_init_spec_g) {
- spec_scen_g.clear();
- 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());
- all_pics.insert(all_pics.begin(), 0);
- ResMgr::graphics.pushPath(pic_dir);
-
- // We'll update the edit menu after this dialog closes
- deferred_actions.push_back(action_ptr(new aCreateGraphicsSheet(0)));
+
+ // Set up the canvas texture for modifying a given graphics sheet
+ void set_up_canvas(size_t sheet){
+ 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);
+ // For some reason, without this call, the canvas becomes black!
+ canvas().getTexture().copyToImage();
}
-
- set_cursor(watch_curs);
-
- // Get image data from the sheets in memory
- size_t cur = 0;
- std::unordered_map sheets;
- for(size_t i = 0; i < spec_scen_g.numSheets; i++) {
- sheets[i] = spec_scen_g.sheets[i]->copyToImage();
+
+ // Set which custom sheet is viewed
+ void set_dlg_custom_sheet(size_t sheet) {
+ dlg["num"].setTextToNum(sheet);
+ dynamic_cast(dlg["sheet"]).setPict(sheet, PIC_FULL);
}
-
- using namespace std::placeholders;
-
- cDialog pic_dlg(*ResMgr::dialogs.get("graphic-sheets"));
- 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 {
- if(cur >= spec_scen_g.numSheets) {
- fs::path fromPath = pic_dir/("sheet" + std::to_string(all_pics[cur]) + ".png");
- sf::Image img;
- img.loadFromFile(fromPath.string().c_str());
- set_clipboard_img(img);
- return true;
- }
- 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 {
- auto img = get_clipboard_img();
- if(img == nullptr) {
+
+ static int color_diff2(sf::Color c1, sf::Color c2) {
+ return pow(c1.r - c2.r, 2) + pow(c1.g - c2.g, 2) + pow(c1.b - c2.b, 2);
+ }
+
+ // Replace the current sheet with the image in a file
+ bool replace_from_file(std::string action_name, fs::path fpath) {
+ sf::Image img;
+ if(!img.loadFromFile(fpath.string().c_str())) {
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());
+ 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)));
+ sheets[all_pics[cur]] = img;
+ img.saveToFile(toPath.string().c_str());
ResMgr::graphics.free(resName);
- set_dlg_custom_sheet(me, all_pics[cur]);
+ set_dlg_custom_sheet(all_pics[cur]);
return true;
}
- deferred_actions.push_back(action_ptr(new aReplaceGraphicsSheet("Paste Graphics Sheet", cur, sheets[cur], new_image)));
+ 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]);
+ sheets[cur] = img;
+ spec_scen_g.replace_sheet(cur, img);
+ set_dlg_custom_sheet(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;
- sf::Image img;
- if(!img.loadFromFile(fpath.string().c_str())) {
- beep();
- return true;
- }
+ }
+
+ // Replace the current sheet with an sf::Image
+ bool replace_from_image(std::string action_name, sf::Image& image) {
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("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, image)));
+ sheets[all_pics[cur]] = image;
- img.saveToFile(toPath.string().c_str());
+ image.saveToFile(toPath.string().c_str());
ResMgr::graphics.free(resName);
- set_dlg_custom_sheet(me, all_pics[cur]);
+ set_dlg_custom_sheet(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, cur, sheets[cur], image)));
- sheets[cur] = img;
- spec_scen_g.replace_sheet(cur, img);
- set_dlg_custom_sheet(me, all_pics[cur]);
+ sheets[cur] = image;
+ spec_scen_g.replace_sheet(cur, image);
+ set_dlg_custom_sheet(all_pics[cur]);
return true;
- });
- pic_dlg["save"].attachClickHandler([&sheets,&cur,&all_pics,&pic_dir](cDialog&, std::string, eKeyMod) -> bool {
+ }
+
+ // Copy the current graphic sheet to system clipboard
+ bool copy_sheet() {
+ if(cur >= spec_scen_g.numSheets) {
+ fs::path fromPath = pic_dir/("sheet" + std::to_string(all_pics[cur]) + ".png");
+ sf::Image img;
+ img.loadFromFile(fromPath.string().c_str());
+ set_clipboard_img(img);
+ return true;
+ }
+ set_clipboard_img(sheets[cur]);
+ return true;
+ }
+
+ // Paste image from system clipboard over current sheet
+ bool paste_sheet() {
+ auto img = get_clipboard_img();
+ if(img == nullptr) {
+ beep();
+ return true;
+ }
+ return replace_from_image("Paste Graphics Sheet", *img);
+ }
+
+ bool edit_sheet_external() {
+ 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;
+ }
+ #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()};
+ 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;
+ }
+
+ // Reload external changes to current graphics sheet
+ bool reload_sheet() {
+ std::string resName = "sheet" + std::to_string(all_pics[cur]);
+ fs::path sheetPath = pic_dir/(resName + ".png");
+ return replace_from_file("Reload Graphics Sheet", sheetPath);
+ }
+
+ // Import image as graphics sheet
+ bool import_sheet() {
+ 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;
+ }
+
+ // Export current sheet to image file
+ bool export_sheet() {
fs::path fpath = nav_put_rsrc({"png", "bmp", "jpg", "jpeg"});
if(fpath.empty()) return true;
if(cur >= spec_scen_g.numSheets) {
@@ -3862,9 +3916,11 @@ void edit_custom_sheets() {
}
sheets[cur].saveToFile(fpath.string().c_str());
return true;
- });
- pic_dlg["new"].attachClickHandler([&sheets,&cur,&all_pics,&pic_dir,&deferred_actions](cDialog& me, std::string, eKeyMod) -> bool {
- cChoiceDlog pickNum("add-new-sheet", {"cancel", "new"}, &me);
+ }
+
+ // Create new sheet
+ bool new_sheet() {
+ cChoiceDlog pickNum("add-new-sheet", {"cancel", "new"}, &dlg);
pickNum->getControl("num").setTextToNum(spec_scen_g.numSheets);
if(pickNum.show() == "cancel") return true;
int newSheet = pickNum->getControl("num").getTextAsNum();
@@ -3879,24 +3935,26 @@ void edit_custom_sheets() {
} else {
auto iter = std::lower_bound(all_pics.begin(), all_pics.end(), newSheet);
if(*iter == newSheet) {
- showError("Sorry, but that sheet already exists! Try creating a sheet with a different number.", "Sheet number: " + std::to_string(newSheet), &me);
+ showError("Sorry, but that sheet already exists! Try creating a sheet with a different number.", "Sheet number: " + std::to_string(newSheet), &dlg);
return true;
}
iter = all_pics.insert(iter, newSheet);
cur = iter - all_pics.begin();
sf::Image img;
img.create(280, 360);
- img.saveToFile(sheetPath.string().c_str());
+ img.saveToFile(sheetPath.string());
}
- me["left"].show();
- me["right"].show();
- set_dlg_custom_sheet(me, all_pics[cur]);
+ dlg["left"].show();
+ dlg["right"].show();
+ set_dlg_custom_sheet(all_pics[cur]);
deferred_actions.push_back(action_ptr(new aCreateGraphicsSheet(newSheet)));
return true;
- });
- pic_dlg["del"].attachClickHandler([&sheets,&cur,&all_pics,&pic_dir,&deferred_actions](cDialog& me, std::string, eKeyMod) -> bool {
+ }
+
+ // Delete the current sheet
+ bool delete_sheet() {
int which_pic = all_pics[cur];
fs::path fpath = pic_dir/("sheet" + std::to_string(which_pic) + ".png");
@@ -3907,7 +3965,7 @@ void edit_custom_sheets() {
if(which_pic < spec_scen_g.numSheets) {
std::string choice = "del";
if(which_pic < spec_scen_g.numSheets - 1)
- choice = cChoiceDlog("must-delete-in-order", {"cancel", "del", "move"}, &me).show();
+ choice = cChoiceDlog("must-delete-in-order", {"cancel", "del", "move"}, &dlg).show();
if(choice == "cancel") return true;
if(choice == "move") {
moved = true;
@@ -3942,23 +4000,60 @@ void edit_custom_sheets() {
deferred_actions.push_back(action_ptr(new aDeleteGraphicsSheet(which_pic, moved, image_for_undo)));
if(all_pics.size() == 1) {
- me["left"].hide();
- me["right"].hide();
+ dlg["left"].hide();
+ dlg["right"].hide();
} else if(all_pics.empty()) {
cStrDlog("You've just deleted the last custom graphics sheet, so this dialog will now close. If you want to add more sheets, you can of course reopen the dialog.", "", "Last Sheet Deleted", 16, PIC_DLOG).show();
- me.toast(true);
+ dlg.toast(true);
return true;
}
if(cur > 0) cur--;
- set_dlg_custom_sheet(me, all_pics[cur]);
+ set_dlg_custom_sheet(all_pics[cur]);
return true;
- });
-
- if(all_pics.size() == 1) {
- pic_dlg["left"].hide();
- pic_dlg["right"].hide();
}
- pic_dlg.attachClickHandlers([&sheets,&cur,&all_pics](cDialog& me, std::string dir, eKeyMod) -> bool {
+
+ // Show which icons are selected
+ void show_icon_selection() {
+ dlg["icon-min"].setTextToNum(icon_min);
+ dlg["icon-max"].setTextToNum(icon_max);
+
+ // 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();
+ }
+ dlg["diff-threshold"].show();
+ }else{
+ for(auto name : icon_buttons){
+ dlg[name].hide();
+ }
+ dlg["diff-threshold"].hide();
+ }
+ };
+
+ bool arrow_button_filter(std::string dir) {
+ size_t old_cur = cur;
if(dir == "left") {
if(cur == 0)
cur = all_pics.size() - 1;
@@ -3968,41 +4063,259 @@ void edit_custom_sheets() {
if(cur >= all_pics.size())
cur = 0;
} else return true;
- set_dlg_custom_sheet(me, all_pics[cur]);
+ if(cur != old_cur){
+ icon_start = icon_end = icon_min = icon_max = 0;
+ show_icon_selection();
+ }
+
+ set_dlg_custom_sheet(all_pics[cur]);
return true;
- }, {"left", "right"});
-
- set_dlg_custom_sheet(pic_dlg, all_pics[cur]);
- shut_down_menus(5); // So that cmd+O, cmd+N, cmd+S can work
- pic_dlg.run();
-
- // Commit undo actions for everything that was done
- if(pic_dlg.accepted()){
- for(action_ptr action : deferred_actions){
- undo_list.add(action);
+ }
+
+ bool click_on_sheet() {
+ eKeyMod mod = current_key_mod();
+
+ location where_curs = sf::Mouse::getPosition(dlg.getWindow());
+ where_curs = dlg.getWindow().mapPixelToCoords(where_curs);
+ rectangle sheet_bounds = dlg["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);
+ show_icon_selection();
+
+ return true;
}
- // On cancel, UWIND the stack of deferred actions, reversing creations and deletions too.
- else{
- while(!deferred_actions.empty()){
- action_ptr previous = deferred_actions.back();
- deferred_actions.pop_back();
- previous->undo();
+
+ bool import_ter_icon() {
+ int sheet_start = 1000 + 100 * all_pics[cur];
+ set_up_canvas(all_pics[cur]);
+ pic_num_t icon = choose_graphic(0, PIC_TER, &dlg);
+ 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);
+ }
+
+ bool strip_ter_floor() {
+ int sheet_start = 1000 + 100 * all_pics[cur];
+ static sf::BlendMode blend_replace(sf::BlendMode::Factor::One, sf::BlendMode::Factor::Zero, sf::BlendMode::Equation::Add);
+ pic_num_t icon = choose_graphic(0, PIC_TER, &dlg);
+ scratch().clear(sf::Color(0,0,0,0));
+ scratch().display();
+ sf::Image without_floor = scratch().getTexture().copyToImage();
+ cPict::drawAt(mainPtr(),scratch(),{0,0,36,28},icon,PIC_TER,false);
+ scratch().display();
+ sf::Image floor_to_strip = scratch().getTexture().copyToImage();
+ set_up_canvas(all_pics[cur]);
+ sf::Image canvas_image = canvas().getTexture().copyToImage();
+ for(int i = 0; i < (icon_max - icon_min) + 1; ++i){
+ sf::Image copy = without_floor;
+ 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};
+ for(int y = 0; y < 36; ++y){
+ for(int x = 0; x < 28; ++x){
+ sf::Color source = canvas_image.getPixel(dest.left + x, dest.top + y);
+ sf::Color floor_source = floor_to_strip.getPixel(x, y);
+
+ float epsilon = dlg["diff-threshold"].getTextAsNum();
+ if(color_diff2(source, floor_source) > pow(epsilon, 2)){
+ copy.setPixel(x, y, source);
+ }
+ }
+ }
+ sf::Texture t;
+ t.loadFromImage(copy);
+ sf::Sprite s(t);
+ s.setPosition(dest.left, dest.top);
+
+ canvas().draw(s, blend_replace);
+ }
+ canvas().display();
+ sf::Image img = canvas().getTexture().copyToImage();
+ return replace_from_image("Strip Terrain Background", img);
+ }
+
+ bool add_ter_floor() {
+ int sheet_start = 1000 + 100 * all_pics[cur];
+ static sf::BlendMode blend_replace(sf::BlendMode::Factor::One, sf::BlendMode::Factor::Zero, sf::BlendMode::Equation::Add);
+ pic_num_t icon = choose_graphic(0, PIC_TER, &dlg);
+ set_up_canvas(all_pics[cur]);
+
+ scratch().clear(sf::Color(0,0,0,0));
+ cPict::drawAt(mainPtr(),scratch(),{0,0,36,28},icon,PIC_TER,false);
+ scratch().display();
+
+ sf::Image floor_to_add = scratch().getTexture().copyToImage();
+ sf::Texture floor_t;
+ floor_t.loadFromImage(floor_to_add);
+ sf::Sprite floor_s(floor_t);
+
+ sf::Texture sheet_t = canvas().getTexture();
+ 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};
+
+ scratch().clear(sf::Color(0,0,0,0));
+ scratch().draw(floor_s);
+ sf::Sprite ter_s(sheet_t, dest);
+ scratch().draw(ter_s, sf::BlendAlpha);
+ scratch().display();
+ sf::Sprite combined_s(scratch().getTexture());
+ combined_s.setPosition(dest.left, dest.top);
+ canvas().draw(combined_s, blend_replace);
+ }
+ canvas().display();
+ sf::Image img = canvas().getTexture().copyToImage();
+ return replace_from_image("Add Terrain Background", img);
+ }
+
+public:
+ cCustomGraphicsDialog() : dlg(*ResMgr::dialogs.get("graphic-sheets")) {
+ pic_dir = tempDir/scenario_temp_dir_name/"graphics";
+ if(!scenario.scen_file.has_extension()) // It's an unpacked scenario
+ pic_dir = scenario.scen_file/"graphics";
+ if(!fs::exists(pic_dir)) fs::create_directories(pic_dir);
+ }
+ void run() {
+ for(fs::directory_iterator iter(pic_dir); iter != fs::directory_iterator(); iter++) {
+ std::string fname = iter->path().filename().string().c_str();
+ int dot = fname.find_last_of('.');
+ if(fname.substr(0,5) == "sheet" && fname.substr(dot) == ".png" && std::all_of(fname.begin()+5, fname.begin()+dot, isdigit)) {
+ int this_pic = boost::lexical_cast(fname.substr(5,dot-5));
+ max_pic = max(max_pic, this_pic);
+ all_pics.push_back(this_pic);
+ }
+ }
+ // Iterating through the graphics folder is not deterministic
+ std::sort(all_pics.begin(), all_pics.end());
+
+ // First, make sure we even have custom graphics! Also make sure they're not legacy format.
+ bool must_init_spec_g = false;
+ if(spec_scen_g.is_old) {
+ if(cChoiceDlog("convert-pics-now", {"cancel", "convert"}).show() == "cancel")
+ return;
+ spec_scen_g.convert_sheets();
+ all_pics.resize(spec_scen_g.numSheets);
+ std::iota(all_pics.begin(), all_pics.end(), 0);
+ } else if(max_pic < 0) {
+ if(cChoiceDlog("have-no-pics", {"cancel", "new"}).show() == "cancel")
+ return;
+ must_init_spec_g = true;
+ } else if(max_pic >= 0 && spec_scen_g.numSheets < 1) {
+ if(cChoiceDlog("have-only-full-pics", {"cancel", "new"}).show() == "new")
+ must_init_spec_g = true;
+ }
+
+ if(must_init_spec_g) {
+ spec_scen_g.clear();
+ 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());
+ all_pics.insert(all_pics.begin(), 0);
+ ResMgr::graphics.pushPath(pic_dir);
+
+ // We'll update the edit menu after this dialog closes
+ deferred_actions.push_back(action_ptr(new aCreateGraphicsSheet(0)));
+ }
+
+ set_cursor(watch_curs);
+
+ 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{
+ sheets[idx].loadFromFile((pic_dir/("sheet" + std::to_string(idx) + ".png")).string());
+ }
+ }
+
+ using namespace std::placeholders;
+ dlg["cancel"].attachClickHandler(std::bind(&cDialog::toast, _1, false));
+ dlg["okay"].attachClickHandler(std::bind(&cDialog::toast, _1, true));
+ dlg["copy"].attachClickHandler(std::bind(&cCustomGraphicsDialog::copy_sheet,this));
+ dlg["paste"].attachClickHandler(std::bind(&cCustomGraphicsDialog::paste_sheet,this));
+ dlg["edit"].attachClickHandler(std::bind(&cCustomGraphicsDialog::edit_sheet_external,this));
+ dlg["reload"].attachClickHandler(std::bind(&cCustomGraphicsDialog::reload_sheet,this));
+ dlg["open"].attachClickHandler(std::bind(&cCustomGraphicsDialog::import_sheet,this));
+ dlg["save"].attachClickHandler(std::bind(&cCustomGraphicsDialog::export_sheet,this));
+ dlg["new"].attachClickHandler(std::bind(&cCustomGraphicsDialog::new_sheet,this));
+ dlg["del"].attachClickHandler(std::bind(&cCustomGraphicsDialog::delete_sheet,this));
+
+ if(all_pics.size() == 1) {
+ dlg["left"].hide();
+ dlg["right"].hide();
+ }
+
+ show_icon_selection();
+
+ dlg["left"].attachClickHandler(std::bind(&cCustomGraphicsDialog::arrow_button_filter, this, "left"));
+ dlg["right"].attachClickHandler(std::bind(&cCustomGraphicsDialog::arrow_button_filter, this, "right"));
+
+ set_dlg_custom_sheet(all_pics[cur]);
+
+ dlg["sheet"].attachClickHandler(std::bind(&cCustomGraphicsDialog::click_on_sheet, this));
+
+ dlg["icon-terr"].attachClickHandler(std::bind(&cCustomGraphicsDialog::import_ter_icon,this));
+ dlg["strip-terr"].attachClickHandler(std::bind(&cCustomGraphicsDialog::strip_ter_floor,this));
+ dlg["add-terr"].attachClickHandler(std::bind(&cCustomGraphicsDialog::add_ter_floor,this));
+
+ shut_down_menus(5); // So that cmd+O, cmd+N, cmd+S can work
+ dlg.run();
+
+ // Commit undo actions for everything that was done
+ if(dlg.accepted()){
+ for(action_ptr action : deferred_actions){
+ undo_list.add(action);
+ }
+ }
+ // On cancel, UWIND the stack of deferred actions, reversing creations and deletions too.
+ else{
+ while(!deferred_actions.empty()){
+ action_ptr previous = deferred_actions.back();
+ deferred_actions.pop_back();
+ previous->undo();
+ }
}
+
+ // Restore menus
+ shut_down_menus(4);
+ if(overall_mode <= MODE_MAIN_SCREEN)
+ shut_down_menus(editing_town ? 2 : 1);
+ else shut_down_menus(3);
+
+ update_edit_menu();
}
-
- // Restore menus
- shut_down_menus(4);
- if(overall_mode <= MODE_MAIN_SCREEN)
- shut_down_menus(editing_town ? 2 : 1);
- else shut_down_menus(3);
+};
- update_edit_menu();
+void edit_custom_sheets() {
+ cCustomGraphicsDialog().run();
}
fs::path get_snd_path(size_t index) {
- extern fs::path tempDir;
- extern std::string scenario_temp_dir_name;
fs::path sndpath = tempDir/scenario_temp_dir_name/"sounds";
std::string sndbasenm = "SND" + std::to_string(index);
fs::path sndfile = sndpath/(sndbasenm + ".wav");
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 82562ae97..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())
@@ -904,6 +907,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 +979,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 +1004,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();
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"