Don't create a new texture every time tiling is requested, though sadly this introduces a new issue

This commit is contained in:
2014-12-10 17:59:52 -05:00
parent 869ca7b2d7
commit eb2fb485ac
14 changed files with 204 additions and 378 deletions

View File

@@ -52,12 +52,12 @@ extern std::shared_ptr<cScrollbar> text_sbar,item_sbar,shop_sbar;
extern sf::Texture bg_gworld;
extern RECT sbar_rect,item_sbar_rect,shop_sbar_rect,startup_top;
extern RECT talk_area_rect, word_place_rect;
extern RECT map_pat[];
extern tessel_ref_t map_pat[];
extern location store_anim_ul;
extern long register_flag;
extern long ed_flag,ed_key;
extern bool fast_bang;
extern RECT bg[];
extern tessel_ref_t bg[];
extern cScenario scenario;
extern cUniverse univ;
extern cCustomGraphics spec_scen_g;
@@ -159,7 +159,7 @@ char spot_seen[9][9];
char anim_str[60];
location anim_str_loc;
extern RECT bw_pats[6];
extern tessel_ref_t bw_pats[6];
extern short combat_posing_monster , current_working_monster ; // 0-5 PC 100 + x - monster x
bool supressing_some_spaces = false;
@@ -621,7 +621,7 @@ void redraw_screen(int refresh) {
void put_background()
{
RECT bg_pict;
tessel_ref_t bg_pict;
if(overall_mode == MODE_STARTUP)
bg_pict = bg[4];
@@ -645,7 +645,7 @@ void put_background()
bg_pict = bg[8];
else bg_pict = bg[13];
}
tileImage(mainPtr, RECT(mainPtr), bg_gworld, bg_pict);
tileImage(mainPtr, RECT(mainPtr), bg_pict);
}
void draw_buttons(short mode)

View File

@@ -47,7 +47,7 @@ short monsters_faces[190] = {
extern location ul;
extern RECT windRect;
extern long anim_ticks;
extern RECT bg[];
extern tessel_ref_t bg[];
extern sf::RenderWindow mainPtr;
extern short town_type,which_combat_type;
extern eGameMode overall_mode;
@@ -72,7 +72,7 @@ extern location store_anim_ul;
extern char light_area[13][13];
extern short terrain_there[9][9];
extern char unexplored_area[13][13];
extern RECT bw_pats[6];
extern tessel_ref_t bw_pats[6];
extern short combat_posing_monster , current_working_monster ; // 0-5 PC 100 + x - monster x
extern short store_talk_face_pic;
extern cScenario scenario;
@@ -172,7 +172,7 @@ void apply_unseen_mask()
to_rect = base_rect;
to_rect.offset(-28 + i * 28,-36 + 36 * j);
to_rect |= big_to;
tileImage(mainPtr, to_rect, bg_gworld, bw_pats[3], sf::BlendAlpha);
tileImage(mainPtr, to_rect, bw_pats[3], sf::BlendAlpha);
//PaintRoundRect(&to_rect,4,4);
for (k = i - 2; k < i + 1; k++)
for (l = j - 2; l < j + 1; l++)
@@ -777,7 +777,7 @@ void draw_shop_graphics(bool pressed,RECT clip_area_rect)
area_rect = RECT(talk_gworld);
frame_rect(talk_gworld, area_rect, sf::Color::Black);
area_rect.inset(1,1);
tileImage(talk_gworld, area_rect,bg_gworld,bg[12]);
tileImage(talk_gworld, area_rect,bg[12]);
frame_rect(talk_gworld, shop_frame, sf::Color::Black);
@@ -1135,7 +1135,7 @@ void place_talk_str(std::string str_to_place,std::string str_to_place2,short col
area_rect = RECT(talk_gworld);
frame_rect(talk_gworld, area_rect, sf::Color::Black);
area_rect.inset(1,1);
tileImage(talk_gworld, area_rect,bg_gworld,bg[12]);
tileImage(talk_gworld, area_rect,bg[12]);
// Put help button
// TODO: Reimplement this with a cButton

View File

@@ -68,7 +68,7 @@ extern short which_item_page[6];
//extern CursHandle sword_curs;
extern std::shared_ptr<cScrollbar> text_sbar,item_sbar;
extern location store_anim_ul;
extern RECT bg[];
extern tessel_ref_t bg[];
extern short dest_personalities[40];
extern location source_locs[6];
extern location dest_locs[40] ;
@@ -138,9 +138,9 @@ void put_pc_screen()
pc_stats_gworld.setActive();
// First clean up gworld with pretty patterns
tileImage(pc_stats_gworld, erase_rect,bg_gworld,bg[6]);
tileImage(pc_stats_gworld, erase_rect,bg[6]);
for (i = 0; i < 3; i++)
tileImage(pc_stats_gworld, small_erase_rects[i],bg_gworld,bg[7]);
tileImage(pc_stats_gworld, small_erase_rects[i],bg[7]);
TextStyle style;
style.font = FONT_BOLD;
@@ -259,16 +259,16 @@ void put_item_screen(short screen_num,short suppress_buttons)
item_stats_gworld.setActive();
// First clean up gworld with pretty patterns
tileImage(item_stats_gworld, erase_rect,bg_gworld,bg[6]);
tileImage(item_stats_gworld, erase_rect,bg[6]);
if (suppress_buttons == 0)
for (i = 0; i < 6; i++)
tileImage(item_stats_gworld, item_screen_button_rects[i],bg_gworld,bg[7]);
tileImage(item_stats_gworld, upper_frame_rect,bg_gworld,bg[7]);
tileImage(item_stats_gworld, item_screen_button_rects[i],bg[7]);
tileImage(item_stats_gworld, upper_frame_rect,bg[7]);
// Draw buttons at bottom
if (suppress_buttons == 0) {
for (i = 0; i < 6; i++)
tileImage(item_stats_gworld, item_screen_button_rects[i],bg_gworld,bg[7]);
tileImage(item_stats_gworld, item_screen_button_rects[i],bg[7]);
}
item_offset = item_sbar->getPosition();
@@ -1355,7 +1355,7 @@ void print_buf ()
text_area_gworld.setActive();
// First clean up gworld with pretty patterns
tileImage(text_area_gworld, erase_rect,bg_gworld,bg[6]);
tileImage(text_area_gworld, erase_rect,bg[6]);
ctrl_val = 58 - text_sbar->getPosition();
start_print_point = buf_pointer - LINES_IN_TEXT_WIN - ctrl_val;
@@ -1432,71 +1432,6 @@ void Draw_Some_Item (sf::Texture& src_gworld, RECT src_rect, sf::RenderTarget& t
}
}
//void rect_draw_some_item (GWorldPtr src_gworld, RECT src_rect, GWorldPtr targ_gworld,
//RECT targ_rect, char masked, short main_win)
//// masked; // if 10 - make AddOver
//// main_win; // if 2, drawing onto dialog
//{
// PixMapHandle test1, test2;
// const BitMap * store_dest;
// GrafPtr cur_port;
// RGBColor store_color;
//
// GetPort(&cur_port);
// if (src_gworld == NULL) {
// if (main_win == 0) {
// SetPort ( targ_gworld);
// PaintRect(&targ_rect);
// SetPort (cur_port);
// }
// else PaintRect(&targ_rect);
// return;
// }
// if (main_win == 2) {
// GetBackColor(&store_color);
// BackColor(whiteColor);
// }
//
// store_dest = GetPortBitMapForCopyBits(cur_port);
//
// test1 = GetPortPixMap(src_gworld);
//
// if (main_win == 1)
// OffsetRect(&targ_rect,ul.h,ul.v);
//
// LockPixels(test1);
// if (main_win == 0) {
// test2 = GetPortPixMap(targ_gworld);
// LockPixels(test2);
// if (masked == 1)
// CopyBits ( (BitMap *) *test1 ,
// (BitMap *) *test2 ,
// &src_rect, &targ_rect,
// transparent , NULL);
// else CopyBits ( (BitMap *) *test1 ,
// (BitMap *) *test2 ,
// &src_rect, &targ_rect,
// (masked == 10) ? addOver : 0, NULL);
// UnlockPixels(test2);
// }
// else {
// if (masked == 1)
// CopyBits ( (BitMap *) *test1 ,
// store_dest ,
// &src_rect, &targ_rect,
// transparent , NULL);
// else CopyBits ( (BitMap *) *test1 ,
// store_dest ,
// &src_rect, &targ_rect,
// (masked == 10) ? addOver : 0, NULL);
// }
// UnlockPixels(test1);
// if (main_win == 2)
// RGBBackColor(&store_color);
// SetPort(cur_port);
//}
// TODO: This seems to duplicate logic found in graphtool to get a rect from a picture index
RECT coord_to_rect(short i,short j)
{
@@ -1516,159 +1451,6 @@ void make_cursor_sword()
set_cursor(sword_curs);
}
//short string_length(char *str)
//{
// short text_len[257];
// short total_width = 0,i,len;
// char p_str[256];
//
// for (i = 0; i < 257; i++)
// text_len[i]= 0;
//
// strcpy((char *) p_str,str);
// c2pstr(p_str);
// MeasureText(256,p_str,text_len);
// len = strlen((char *)str);
//
// for (i = 0; i < 257; i++)
// if ((text_len[i] > total_width) && (i <= len))
// total_width = text_len[i];
// return total_width;
//}
//void char_win_draw_string(WindowPtr dest_window,RECT dest_rect,char *str,short mode,short line_height)
//{
// char_port_draw_string(GetWindowPort(dest_window), dest_rect, str, mode, line_height);
//}
//
//
//void char_port_draw_string(GrafPtr dest_window,RECT dest_rect,char *str,short mode,short line_height)
//{
// char store_s[256];
//
// strcpy((char *) store_s,str);
// win_draw_string( dest_window, dest_rect,store_s, mode, line_height);
//
//}
// mode: 0 - align up and left, 1 - center on one line
// str is a c string, 256 characters
// uses current font
//void win_draw_string(GrafPtr dest_window,RECT dest_rect,Str255 str,short mode,short line_height)
//{
// GrafPtr old_port;
// const char* p_str,str_to_draw,str_to_draw2,c_str;
// char null_s[256] = " ";
// short str_len,i;
// short last_line_break = 0,last_word_break = 0,on_what_line = 0;
// short text_len[257];
// short total_width = 0;
// bool force_skip = false;
// RgnHandle current_clip;
// short adjust_x = 0,adjust_y = 0;
//
// if (dest_window == GetWindowPort(mainPtr)) {
// adjust_x = ul.h; adjust_y = ul.v;
// }
// strcpy((char *) p_str,(char *) str);
// strcpy((char *) c_str,(char *) str);
// c2pstr(p_str);
// for (i = 0; i < 257; i++)
// text_len[i]= 0;
// MeasureText(256,p_str,text_len);
// str_len = (short) strlen((char *)str);
// if (str_len == 0) {
// return;
// }
//
// GetPort(&old_port);
// SetPort(dest_window);
//
// //FrameRect(&dest_rect);
//
// current_clip = NewRgn();
// GetClip(current_clip);
//
// dest_rect.bottom += 5;
// //ClipRect(&dest_rect);
// dest_rect.bottom -= 5;
//
//
// for (i = 0; i < 257; i++)
// if ((text_len[i] > total_width) && (i <= str_len))
// total_width = text_len[i];
// if ((mode == 0) && (total_width < dest_rect.right - dest_rect.left))
// mode = 2;
// for (i = 0; i < 257; i++)
// if ((i <= str_len) && (c_str[i] == '|') && (mode == 2))
// mode = 0;
//
//
// switch (mode) {
// case 0:
// MoveTo(dest_rect.left + 1 + adjust_x, dest_rect.top + 1 + line_height * on_what_line + adjust_y + 9);
// for (i = 0;text_len[i] != text_len[i + 1], i < str_len;i++) {
// if (((text_len[i] - text_len[last_line_break] > (dest_rect.right - dest_rect.left - 6))
// && (last_word_break > last_line_break)) || (c_str[i] == '|')) {
// if (c_str[i] == '|') {
// c_str[i] = ' ';
// force_skip = true;
// last_word_break = i + 1;
// }
// sprintf((char *)str_to_draw,"%s",(char *)null_s);
// strncpy ((char *) str_to_draw,(char *) c_str + last_line_break,(size_t) (last_word_break - last_line_break - 1));
// sprintf((char *)str_to_draw2," %s",str_to_draw);
// str_to_draw2[0] = (char) strlen((char *)str_to_draw);
// DrawString(str_to_draw2);
// on_what_line++;
// MoveTo(dest_rect.left + 1 + adjust_x, dest_rect.top + 1 + line_height * on_what_line + adjust_y + 9);
// last_line_break = last_word_break;
// if (force_skip == true) {
// force_skip = false;
// i++;
// //last_line_break++;
// //last_word_break++;
// }
// }
// if (c_str[i] == ' ')
// last_word_break = i + 1;
// if (on_what_line == LINES_IN_TEXT_WIN - 1)
// i = 10000;
// }
//
// if (i - last_line_break > 1) {
// strcpy((char *)str_to_draw,(char *)null_s);
// strncpy ((char *) str_to_draw,(char *) c_str + last_line_break,(size_t) (i - last_line_break));
// sprintf((char *)str_to_draw2," %s",str_to_draw);
// if (strlen((char *) str_to_draw2) > 3) {
// str_to_draw2[0] = (char) strlen((char *)str_to_draw);
// DrawString(str_to_draw2);
// }
// }
// break;
// case 1:
// MoveTo((dest_rect.right + dest_rect.left) / 2 - (4 * total_width) / 9 + adjust_x,
// (dest_rect.bottom + dest_rect.top - line_height) / 2 + 9 + adjust_y);
// DrawText(p_str,1,p_str[0]);
// //DrawString(p_str);
// break;
// case 2:
// MoveTo(dest_rect.left + 1 + adjust_x,
// dest_rect.top + 1 + adjust_y + 9);
// DrawString(p_str);
// break;
// case 3:
// MoveTo(dest_rect.left + 1 + adjust_x,
// dest_rect.top + 1 + adjust_y + 9 + (dest_rect.bottom - dest_rect.top) / 6);
// DrawString(p_str);
// break;
// }
// SetClip(current_clip);
// DisposeRgn(current_clip);
// SetPort(old_port);
//}
short calc_day()
{
return (short) ((univ.party.age) / 3700) + 1;

View File

@@ -76,7 +76,7 @@ extern sf::RenderTexture map_gworld;
extern sf::Texture small_ter_gworld;
// In the 0..65535 range, this colour was {65535,65535,52428}
sf::Color parchment = {255,255,205};
extern RECT map_pat[];
extern tessel_ref_t map_pat[];
// TODO: Add blue cave graphics to these arrays?
unsigned char map_pats[256] = {
@@ -1516,7 +1516,7 @@ void draw_map(bool need_refresh) {
map_graphic_placed[kludge.x / 8][kludge.y] | (unsigned char)(s_pow(2,kludge.x % 8));
}
}
tileImage(mini_map, draw_rect,bg_gworld,map_pat[((pic >= 400) ? anim_map_pats[pic - 400] : map_pats[pic]) - 1]);
tileImage(mini_map, draw_rect,map_pat[((pic >= 400) ? anim_map_pats[pic - 400] : map_pats[pic]) - 1]);
break;
}
//OffsetRect(&ter_temp_from,
@@ -1540,7 +1540,7 @@ void draw_map(bool need_refresh) {
style.pointSize = 10;;
the_rect = RECT(mini_map);
tileImage(mini_map, the_rect,bg_gworld,bg[4]);
tileImage(mini_map, the_rect,bg[4]);
cPict theGraphic(mini_map);
theGraphic.setBounds(dlogpicrect);
theGraphic.setPict(21, PIC_DLOG);

View File

@@ -80,7 +80,7 @@ void cButton::draw(){
// TODO: How is it supposed to know it's a default button when this fact is stored in the dialog, not the button?
if(key.spec && key.k == key_enter) drawFrame(2,frameStyle); // frame default button, to provide a visual cue that it's the default
}else{
tileImage(*inWindow,frame,bg_gworld,bg[parent->getBg()]);
tileImage(*inWindow,frame,bg[parent->getBg()]);
}
}
@@ -251,7 +251,7 @@ void cLed::draw(){
to_rect.left = frame.left + 18; // Possibly could be 20
win_draw_string(*inWindow,to_rect,lbl,eTextMode::LEFT_TOP,style);
}else{
tileImage(*inWindow,frame,bg_gworld,bg[parent->getBg()]);
tileImage(*inWindow,frame,bg[parent->getBg()]);
}
}

View File

@@ -927,14 +927,24 @@ void cDialog::run(){
tabOrder[0].second->triggerFocusHandler(*this, tabOrder[0].first, false);
currentFocus = tabOrder[0].first;
}
// Sometimes it seems like the Cocoa menu handling clobbers the active rendering context.
// For whatever reason, delaying 100 milliseconds appears to fix this.
sf::sleep(sf::milliseconds(100));
win.create(sf::VideoMode(winRect.width(), winRect.height()), "Dialog", sf::Style::Titlebar);
win.setActive();
win.setVisible(true);
makeFrontWindow(win);
ModalSession dlog(win);
paintTimer.restart();
animTimer.restart();
while(dialogNotToast){
draw();
while(dialogNotToast){
// TODO: This is just a hack to prevent the constant flickering.
// All it actually does is slow the flickering to non-blinding frequency.
if(paintTimer.getElapsedTime().asMilliseconds() > 500) {
draw();
paintTimer.restart();
}
dlog.pumpEvents();
if(!win.pollEvent(currentEvent)) continue;
location where;
@@ -1375,7 +1385,7 @@ bool cDialog::doAnimations = false;
void cDialog::draw(){
win.setActive();
tileImage(win,winRect,bg_gworld,::bg[bg]);
tileImage(win,winRect,::bg[bg]);
if(doAnimations && animTimer.getElapsedTime().asMilliseconds() >= 500) {
cPict::advanceAnim();
animTimer.restart();

View File

@@ -170,7 +170,7 @@ private:
std::string defaultButton;
boost::any result;
std::string fname;
sf::Clock animTimer;
sf::Clock animTimer, paintTimer;
friend class cControl;
};

View File

@@ -539,7 +539,7 @@ void cPict::draw(){
if(!visible){ // Erase it
rect.inset(-3, -3);
tileImage(*inWindow,rect,bg_gworld,bg[parent->getBg()]);
tileImage(*inWindow,rect,bg[parent->getBg()]);
return;
}
if(picNum < 0) { // Just fill with black

View File

@@ -12,6 +12,7 @@
#include "mathutil.h"
sf::Texture cScrollbar::scroll_gw;
tessel_ref_t cScrollbar::bar_tessel[2];
cScrollbar::cScrollbar(cDialog& parent) : cControl(CTRL_SCROLL, parent) {}
@@ -19,6 +20,10 @@ cScrollbar::cScrollbar(sf::RenderWindow& parent) : cControl(CTRL_SCROLL, parent)
void cScrollbar::init() {
scroll_gw.loadFromImage(*ResMgr::get<ImageRsrc>("dlogscroll"));
RECT bar_rect = {0,48,16,64};
bar_tessel[0] = prepareForTiling(scroll_gw, bar_rect);
bar_rect.offset(0,16);
bar_tessel[1] = prepareForTiling(scroll_gw, bar_rect);
}
bool cScrollbar::isClickable(){
@@ -149,7 +154,7 @@ sf::Color cScrollbar::getColour() throw(xUnsupportedProp) {
void cScrollbar::draw() {
if(!isVisible()) return;
static const RECT up_rect = {0,0,16,16}, down_rect = {0,16,16,32}, thumb_rect = {0,32,16,48}, bar_rect = {0,48,16,64};
static const RECT up_rect = {0,0,16,16}, down_rect = {0,16,16,32}, thumb_rect = {0,32,16,48};
int bar_height = frame.height() - 32;
inWindow->setActive();
RECT draw_rect = frame, from_rect = up_rect;
@@ -160,10 +165,8 @@ void cScrollbar::draw() {
if(pos > 0) {
draw_rect.top = draw_rect.bottom;
draw_rect.height() = pos * (bar_height - 16) / max;
from_rect = bar_rect;
if(depressed && pressedPart == PART_PGUP)
from_rect.offset(0,16);
tileImage(*inWindow, draw_rect, scroll_gw, from_rect);
bool pressed = depressed && pressedPart == PART_PGUP;
tileImage(*inWindow, draw_rect, bar_tessel[pressed]);
}
draw_rect.top = draw_rect.bottom;
draw_rect.height() = 16;
@@ -174,10 +177,8 @@ void cScrollbar::draw() {
if(pos < max) {
draw_rect.top = draw_rect.bottom;
draw_rect.bottom = frame.bottom - 16;
from_rect = bar_rect;
if(depressed && pressedPart == PART_PGDN)
from_rect.offset(0,16);
tileImage(*inWindow, draw_rect, scroll_gw, from_rect);
bool pressed = depressed && pressedPart == PART_PGDN;
tileImage(*inWindow, draw_rect, bar_tessel[pressed]);
}
draw_rect = frame;
draw_rect.top = draw_rect.bottom - 16;

View File

@@ -13,6 +13,7 @@
/// Scrollbar-related classes and types.
#include "control.h"
#include "graphtool.h"
/// A simple vertical scrollbar.
/// This has no coupling with scrollable data; that must be handled externally by
@@ -28,6 +29,7 @@ class cScrollbar : public cControl {
} pressedPart;
click_callback_t onClick;
static sf::Texture scroll_gw;
static tessel_ref_t bar_tessel[2];
public:
/// @copydoc cDialog::init()
static void init();

View File

@@ -261,7 +261,7 @@ void draw_main_screen()
RECT source_rect, dest_rec,dest_rect;
RECT reg_rect;
tileImage(mainPtr,whole_win_rect,bg_gworld,bg[12]); // fill whole window with background texture
tileImage(mainPtr,whole_win_rect,bg[12]); // fill whole window with background texture
dest_rec = source_rect = title_from; // initializes, to draw title
// title_from is a RECT constant
dest_rec.offset(20,0);

View File

@@ -87,7 +87,7 @@ sf::Texture roads_gworld;
sf::Texture missiles_gworld;
sf::Texture status_gworld;
sf::Texture pc_gworld;
extern RECT map_pat[];
extern tessel_ref_t map_pat[];
// begin new stuff
RECT blue_button_from = {120,91,134,107};
@@ -388,7 +388,7 @@ void load_main_screen() {
void redraw_screen() {
RECT windRect(mainPtr);
tileImage(mainPtr,windRect,bg_gworld,bg[20]);
tileImage(mainPtr,windRect,bg[20]);
draw_main_screen();
if (overall_mode < MODE_MAIN_SCREEN);
draw_terrain();
@@ -414,7 +414,7 @@ void draw_main_screen() {
frame_rect(mainPtr, draw_rect, sf::Color::Black);
draw_rect.inset(1,1);
tileImage(mainPtr,draw_rect,bg_gworld,bg[17]);
tileImage(mainPtr,draw_rect,bg[17]);
draw_rb();
right_sbar->draw();
@@ -437,7 +437,7 @@ void draw_lb() {
short i;
temp_rect.right = RIGHT_AREA_UL_X - 2;
tileImage(mainPtr,temp_rect,bg_gworld,bg[20]);
tileImage(mainPtr,temp_rect,bg[20]);
for (i = 0; i < NLS; i++)
draw_lb_slot(i,0);
}
@@ -446,7 +446,7 @@ void draw_lb() {
void draw_lb_slot (short which,short mode) {
RECT text_rect,from_rect;
tileImage(mainPtr,left_buttons[which][0],bg_gworld,bg[20]);
tileImage(mainPtr,left_buttons[which][0],bg[20]);
if (left_button_status[which] == 0)
return;
text_rect = left_buttons[which][0];
@@ -487,7 +487,7 @@ void draw_rb_slot (short which,short mode) {
if ((which < pos) || (which >= pos + NRSONPAGE))
return;
tileImage(mainPtr,right_buttons[which - pos],bg_gworld,bg[17]);
tileImage(mainPtr,right_buttons[which - pos],bg[17]);
if (right_button_status[which] == 0)
return;
text_rect = right_buttons[which - pos];
@@ -506,7 +506,7 @@ void set_up_terrain_buttons() {
RECT palette_from,palette_to = palette_button_base;
tileImage(terrain_buttons_gworld,terrain_buttons_rect,bg_gworld,bg[17]);
tileImage(terrain_buttons_gworld,terrain_buttons_rect,bg[17]);
frame_rect(terrain_buttons_gworld, terrain_buttons_rect, sf::Color::Black);
// first make terrain buttons
@@ -611,7 +611,7 @@ void draw_terrain(){
return;
if (cur_viewing_mode == 0) {
tileImage(ter_draw_gworld,terrain_rect,bg_gworld,bg[17]);
tileImage(ter_draw_gworld,terrain_rect,bg[17]);
frame_rect(ter_draw_gworld, terrain_rect, sf::Color::Black);
for (q = 0; q < 9; q++)
for (r = 0; r < 9; r++)
@@ -817,7 +817,7 @@ void draw_terrain(){
if (cur_viewing_mode == 1) {
if (small_any_drawn == false) {
tileImage(ter_draw_gworld, terrain_rect,bg_gworld,bg[17]);
tileImage(ter_draw_gworld, terrain_rect,bg[17]);
frame_rect(ter_draw_gworld, terrain_rect, sf::Color::Black);
}
for (q = 0; q < (editing_town ? town->max_dim() : 48); q++)
@@ -926,7 +926,7 @@ void draw_items() {
dest_rect.left += 5;
dest_rect.right -= 5;
}
rect_draw_some_item((pic_num < 45) ? items_gworld : tiny_obj_gworld,
rect_draw_some_item((pic_num < 55) ? items_gworld : tiny_obj_gworld,
source_rect, ter_draw_gworld, dest_rect,sf::BlendAlpha);
}
}
@@ -997,15 +997,15 @@ void draw_one_tiny_terrain_spot (short i,short j,ter_num_t terrain_to_draw) {
switch (picture_wanted) {
case 0: case 1: case 73: case 72:
tileImage(ter_draw_gworld, dest_rect,bg_gworld,map_pat[0]);
tileImage(ter_draw_gworld, dest_rect,map_pat[0]);
break;
case 2: case 3: case 4:
tileImage(ter_draw_gworld, dest_rect,bg_gworld,map_pat[1]);
tileImage(ter_draw_gworld, dest_rect,map_pat[1]);
break;
default:
if ((picture_wanted < 170) && (map_pats[picture_wanted] > 0)) {
tileImage(ter_draw_gworld, dest_rect,bg_gworld,map_pat[map_pats[picture_wanted]]);
tileImage(ter_draw_gworld, dest_rect,map_pat[map_pats[picture_wanted]]);
}
else if (picture_wanted >= 1000) {
graf_pos_ref(source_gworld, from_rect) = spec_scen_g.find_graphic(picture_wanted % 1000);
@@ -1014,12 +1014,12 @@ void draw_one_tiny_terrain_spot (short i,short j,ter_num_t terrain_to_draw) {
else if (picture_wanted >= 400) {
source_gworld = &anim_gworld;
picture_wanted -= 400;
if (picture_wanted == 0) tileImage(ter_draw_gworld, dest_rect,bg_gworld,map_pat[13]);
else if (picture_wanted == 4) tileImage(ter_draw_gworld, dest_rect,bg_gworld,map_pat[21]);
else if (picture_wanted == 7) tileImage(ter_draw_gworld, dest_rect,bg_gworld,map_pat[20]);
else if (picture_wanted == 8) tileImage(ter_draw_gworld, dest_rect,bg_gworld,map_pat[19]);
else if (picture_wanted == 9) tileImage(ter_draw_gworld, dest_rect,bg_gworld,map_pat[20]);
else if (picture_wanted == 10) tileImage(ter_draw_gworld, dest_rect,bg_gworld,map_pat[19]);
if (picture_wanted == 0) tileImage(ter_draw_gworld, dest_rect,map_pat[13]);
else if (picture_wanted == 4) tileImage(ter_draw_gworld, dest_rect,map_pat[21]);
else if (picture_wanted == 7) tileImage(ter_draw_gworld, dest_rect,map_pat[20]);
else if (picture_wanted == 8) tileImage(ter_draw_gworld, dest_rect,map_pat[19]);
else if (picture_wanted == 9) tileImage(ter_draw_gworld, dest_rect,map_pat[20]);
else if (picture_wanted == 10) tileImage(ter_draw_gworld, dest_rect,map_pat[19]);
else {
//source_rect.left = 112 * (picture_wanted / 5);
//source_rect.right = source_rect.left + 28;
@@ -1131,7 +1131,7 @@ void place_location() {
erase_rect.right = RIGHT_AREA_WIDTH - 1;
erase_rect.top = terrain_rects[255].top + 26 - 9;//12 - 9;
erase_rect.bottom = erase_rect.top + 12;
tileImage(terrain_buttons_gworld, erase_rect,bg_gworld,bg[17]);
tileImage(terrain_buttons_gworld, erase_rect,bg[17]);
//MoveTo(terrain_rects[255].left + 20 ,terrain_rects[255].top + 12);
location moveTo(5 ,terrain_rects[255].top + 26);
@@ -1157,7 +1157,7 @@ void place_location() {
erase_rect.right = RIGHT_AREA_WIDTH - 1;
erase_rect.top = terrain_rects[255].bottom + 117;
erase_rect.bottom = RIGHT_AREA_HEIGHT + 6;
tileImage(terrain_buttons_gworld, erase_rect,bg_gworld,bg[17]);
tileImage(terrain_buttons_gworld, erase_rect,bg[17]);
if (overall_mode < MODE_MAIN_SCREEN) {
moveTo = location(5,terrain_rects[255].bottom + 129);
@@ -1221,7 +1221,7 @@ void place_just_location() {
erase_rect.right = RIGHT_AREA_WIDTH - 1;
erase_rect.top = terrain_rects[255].top + 12 - 9;
erase_rect.bottom = erase_rect.top + 12;
tileImage(terrain_buttons_gworld, erase_rect,bg_gworld,bg[17]);
tileImage(terrain_buttons_gworld, erase_rect,bg[17]);
//MoveTo(terrain_rects[255].left + 20 ,terrain_rects[255].top + 12);
location moveTo(5 ,terrain_rects[255].top + 26);

View File

@@ -16,16 +16,21 @@
#endif
#include <typeinfo>
#include <unordered_map>
#include <boost/filesystem.hpp>
#include <boost/math/constants/constants.hpp>
#include "restypes.hpp"
#include "mathutil.h"
using boost::math::constants::pi;
RECT bg[21];
RECT map_pat[30];
RECT bw_pats[6];
RECT bg_rects[21];
RECT map_pat_rects[30];
RECT bw_rects[6];
tessel_ref_t bg[21];
tessel_ref_t map_pat[30];
tessel_ref_t bw_pat[6];
sf::Texture bg_gworld;
bool use_win_graphics = false;
sf::Shader maskShader;
@@ -33,6 +38,8 @@ extern fs::path progDir;
// TODO: Shouldn't need this
extern sf::RenderWindow mainPtr;
static void register_main_patterns();
void init_graph_tool(){
fs::path shaderPath = progDir/"data"/"shaders";
fs::path fragPath = shaderPath/"mask.frag", vertPath = shaderPath/"mask.vert";
@@ -80,49 +87,48 @@ void init_graph_tool(){
18,19,20,21,22,24,25,27,
28,29
};
// for (i = 0; i < 21; i++)
// bg[i] = GetPixPat(128 + i);
for(i = 0; i < 17; i++){
bg[pat_i[i]] = {0,0,64,64};
bg[pat_i[i]].offset(64 * pat_offs[i].x,64 * pat_offs[i].y);
bg_rects[pat_i[i]] = {0,0,64,64};
bg_rects[pat_i[i]].offset(64 * pat_offs[i].x,64 * pat_offs[i].y);
}
RECT tmp_rect = bg[19];
RECT tmp_rect = bg_rects[19];
tmp_rect.offset(0, 64);
bg[0] = bg[1] = bg[18] = map_pat[7] = tmp_rect;
bg[0].right -= 32;
bg[0].bottom -= 32;
bg[1].left -= 32;
bg[1].bottom -= 32;
bg[18].right -= 32;
bg[18].top -= 32;
map_pat[7].left -= 32;
map_pat[7].top -= 32;
bg_rects[0] = bg_rects[1] = bg_rects[18] = map_pat_rects[7] = tmp_rect;
bg_rects[0].right -= 32;
bg_rects[0].bottom -= 32;
bg_rects[1].left -= 32;
bg_rects[1].bottom -= 32;
bg_rects[18].right -= 32;
bg_rects[18].top -= 32;
map_pat_rects[7].left -= 32;
map_pat_rects[7].top -= 32;
tmp_rect.offset(0, 64);
map_pat[8] = map_pat[23] = map_pat[26] = tmp_rect;
map_pat[8].right -= 32;
map_pat[8].bottom -= 32;
map_pat[23].left -= 32;
map_pat[23].right -= 16;
map_pat[23].bottom -= 32;
map_pat[26].left -= 32 + 16;
map_pat[26].bottom -= 32;
map_pat_rects[8] = map_pat_rects[23] = map_pat_rects[26] = tmp_rect;
map_pat_rects[8].right -= 32;
map_pat_rects[8].bottom -= 32;
map_pat_rects[23].left -= 32;
map_pat_rects[23].right -= 16;
map_pat_rects[23].bottom -= 32;
map_pat_rects[26].left -= 32 + 16;
map_pat_rects[26].bottom -= 32;
tmp_rect.offset(0, 64);
bg[7] = tmp_rect;
bg[7].bottom = bg[7].top + 16;
bg_rects[7] = tmp_rect;
bg_rects[7].bottom = bg_rects[7].top + 16;
tmp_rect.offset(0, -32);
tmp_rect.right = tmp_rect.left + 8;
tmp_rect.bottom = tmp_rect.top + 8;
for(i = 0; i < 26; i++){
map_pat[map_i[i]] = tmp_rect;
map_pat[map_i[i]].offset(8 * (i % 8),8 * (i / 8));
map_pat_rects[map_i[i]] = tmp_rect;
map_pat_rects[map_i[i]].offset(8 * (i % 8),8 * (i / 8));
// Note: 8 * (i / 8) != i, despite appearances, due to integer rounding
}
tmp_rect = map_pat[29];
tmp_rect = map_pat_rects[29];
for(i = 0; i < 6; i++) {
tmp_rect.offset(8, 0);
bw_pats[i] = tmp_rect;
bw_rects[i] = tmp_rect;
}
bg_gworld.loadFromImage(*ResMgr::get<ImageRsrc>("pixpats"));
register_main_patterns();
}
static void rect_draw_some_item(const sf::Texture& src_gworld,RECT src_rect,sf::RenderTarget& targ_gworld,RECT targ_rect,sf::RenderStates mode);
@@ -401,7 +407,7 @@ void draw_terrain(){
if (cur_viewing_mode == 0) {
SetPort( ter_draw_gworld);
FillCRect(&terrain_rect,bg[6]);
FillCRect(&terrain_rect,bg_rects[6]);
FrameRect(&terrain_rect);
SetPortWindowPort(mainPtr);
for (q = 0; q < 9; q++)
@@ -617,7 +623,7 @@ void draw_terrain(){
if (cur_viewing_mode == 1) {
SetPort( ter_draw_gworld);
if (small_any_drawn == false) {
FillCRect(&terrain_rect,bg[6]);
FillCRect(&terrain_rect,bg_rects[6]);
FrameRect(&terrain_rect);
}
for (q = 0; q < ((editing_town == true) ? max_dim[town_type] : 48); q++)
@@ -1068,6 +1074,19 @@ void Region::offset(location off) {
offset(off.x, off.y);
}
RECT Region::getEnclosingRect() {
if(shapes.empty()) return RECT();
RECT bounds = shapes[0]->getGlobalBounds();
for(size_t i = 0; i < shapes.size(); i++) {
RECT shapeRect = shapes[i]->getGlobalBounds();
if(shapeRect.top < bounds.top) bounds.top = shapeRect.top;
if(shapeRect.left < bounds.left) bounds.top = shapeRect.top;
if(shapeRect.bottom > bounds.bottom) bounds.top = shapeRect.top;
if(shapeRect.right > bounds.right) bounds.top = shapeRect.top;
}
return bounds;
}
// We can only use stencil buffer in the main window
// Could request it in dialogs, but currently don't
// SFML does not appear to allow requesting it for render textures
@@ -1130,80 +1149,83 @@ Region& Region::operator-=(Region& other) {
return *this;
}
void tileImage(sf::RenderTarget& target, RECT area, sf::Texture& img, sf::BlendMode mode){
bool saveRep = img.isRepeated();
img.setRepeated(true);
sf::Vector2u imgSz = img.getSize();
struct tessel_t {
sf::RenderTexture* tessel;
sf::Texture* img;
RECT srcRect;
};
bool operator==(const tessel_ref_t& a, const tessel_ref_t& b) {
return a.key == b.key;
}
template<> struct std::hash<tessel_ref_t> {
size_t operator()(tessel_ref_t key) const {
return key.key;
}
};
std::unordered_map<tessel_ref_t, tessel_t> tiling_reservoir;
static int tessel_index = 0;
tessel_ref_t prepareForTiling(sf::Texture& srcImg, RECT srcRect) {
tessel_ref_t ref = {tessel_index++};
tiling_reservoir[ref].img = &srcImg;
tiling_reservoir[ref].srcRect = srcRect;
tiling_reservoir[ref].tessel = new sf::RenderTexture;
tiling_reservoir[ref].tessel->create(srcRect.width(), srcRect.height());
RECT tesselRect(*tiling_reservoir[ref].tessel);
rect_draw_some_item(srcImg, srcRect, *tiling_reservoir[ref].tessel, tesselRect);
tiling_reservoir[ref].tessel->display();
tiling_reservoir[ref].tessel->setRepeated(true);
return ref;
}
void flushTessels(sf::Texture& alteredImg) {
erase_if(tiling_reservoir, [&alteredImg](std::pair<const tessel_ref_t,tessel_t>& kv) -> bool {
if(kv.second.img == &alteredImg) {
delete kv.second.tessel;
return true;
}
return false;
});
if(&alteredImg == &bg_gworld)
register_main_patterns();
}
static void register_main_patterns() {
for(int i = 0; i < 30; i++) {
if(i < 21) {
if(i < 6) {
bw_pat[i] = prepareForTiling(bg_gworld, bw_rects[i]);
}
bg[i] = prepareForTiling(bg_gworld, bg_rects[i]);
}
map_pat[i] = prepareForTiling(bg_gworld, map_pat_rects[i]);
}
}
void tileImage(sf::RenderTarget& target, RECT area, tessel_ref_t tessel, sf::BlendMode mode) {
// First, set up a dictionary of all textures ever tiled.
// The key type is a pair<Texture*,rectangle>.
// The value type is a Texture.
tessel_t& tesselInfo = tiling_reservoir[tessel];
RECT clipArea = area;
area.left -= area.left % imgSz.x;
area.top -= area.top % imgSz.y;
area.left -= area.left % tesselInfo.srcRect.width();
area.top -= area.top % tesselInfo.srcRect.height();
area |= RECT(target); // Make sure we don't draw out of bounds
unsigned int hrep = int((double(area.width())/imgSz.x)+0.5);
unsigned int vrep = int((double(area.height())/imgSz.y)+0.5);
sf::RectangleShape tessel(sf::Vector2f(hrep*imgSz.x,vrep*imgSz.y));
tessel.setTexture(&img);
tessel.setPosition(area.left, area.top);
sf::RectangleShape tesselShape(sf::Vector2f(area.width(),area.height()));
tesselShape.setTexture(&tesselInfo.tessel->getTexture());
tesselShape.setTextureRect(area);
tesselShape.setPosition(area.left, area.top);
sf::RenderStates renderMode(mode);
setActiveRenderTarget(target);
clip_rect(target, clipArea);
target.draw(tessel, renderMode);
undo_clip(target);
img.setRepeated(saveRep);
}
void tileImage(sf::RenderTarget& target, RECT area, sf::Texture& img, RECT srcRect, sf::BlendMode mode){
sf::RenderTexture temp;
temp.create(srcRect.width(), srcRect.height());
temp.setRepeated(true);
RECT tesselRect(temp);
temp.setActive();
rect_draw_some_item(img, srcRect, temp, tesselRect);
temp.display();
RECT clipArea = area;
area.left -= area.left % tesselRect.width();
area.top -= area.top % tesselRect.height();
area |= RECT(target); // Make sure we don't draw out of bounds
sf::RectangleShape tessel(sf::Vector2f(area.width(),area.height()));
tessel.setTexture(&temp.getTexture());
tessel.setTextureRect(area);
tessel.setPosition(area.left, area.top);
sf::RenderStates renderMode(mode);
setActiveRenderTarget(target);
clip_rect(target, clipArea);
target.draw(tessel, renderMode);
target.draw(tesselShape, renderMode);
undo_clip(target);
}
#if 0
void tileImage(RgnHandle area, GWorldPtr img, RECT srcRect, short mode){
GrafPtr cur_port;
GetPort(&cur_port);
const BitMap* drawDest = GetPortBitMapForCopyBits(cur_port);
PixMapHandle drawSource = GetPortPixMap(img);
int srcWidth=srcRect.right-srcRect.left;
int srcHeight=srcRect.bottom-srcRect.top;
int x,y;
RECT bounds;
GetRegionBounds(area, &bounds);
bounds.left -= bounds.left % srcWidth;
bounds.top -= bounds.top % srcHeight;
unsigned int hrep = (int)((double(bounds.right-bounds.left)/srcWidth)+0.5);
unsigned int vrep = (int)((double(bounds.bottom-bounds.top)/srcHeight)+0.5);
for(unsigned int i=0; i<=hrep; i++){
for(unsigned int j=0; j<=vrep; j++){
x=bounds.left+i*srcWidth;
y=bounds.top+j*srcHeight;
RECT targetRect={y,x,y+srcHeight,x+srcWidth};
CopyBits((BitMap*)*drawSource, drawDest,&srcRect,&targetRect,mode,area);
}
}
}
#endif
short can_see(location p1,location p2,std::function<short(short,short)> get_obscurity) {
short storage = 0;

View File

@@ -52,6 +52,7 @@ public:
void offset(int x, int y);
void offset(location off);
Region& operator-=(Region& other);
RECT getEnclosingRect();
};
typedef unsigned short pic_num_t;
@@ -85,6 +86,12 @@ struct snippet_t {
bool hilited;
};
struct tessel_ref_t {
int key;
};
bool operator==(const tessel_ref_t& a, const tessel_ref_t& b);
enum class eTextMode {
WRAP,
CENTRE,
@@ -106,8 +113,10 @@ short string_length(std::string str, TextStyle style);
//void draw_terrain();
RECT calc_rect(short i, short j);
void setActiveRenderTarget(sf::RenderTarget& where);
void tileImage(sf::RenderTarget& target, RECT area, sf::Texture& img, sf::BlendMode mode = sf::BlendNone);
void tileImage(sf::RenderTarget& target, RECT area, sf::Texture& img, RECT srcRect, sf::BlendMode mode = sf::BlendNone);
void flushTessels(sf::Texture& alteredImg);
tessel_ref_t prepareForTiling(sf::Texture& srcImg, RECT srcRect);
void tileImage(sf::RenderTarget& target, RECT area, tessel_ref_t tessel, sf::BlendMode mode = sf::BlendNone);
void tileImage(sf::RenderWindow& target, Region& rgn, tessel_ref_t tessel, sf::BlendMode mode = sf::BlendNone);
void fill_rect(sf::RenderTarget& target, RECT rect, sf::Color colour);
void frame_rect(sf::RenderTarget& target, RECT rect, sf::Color colour);
void fill_circle(sf::RenderTarget& target, RECT rect, sf::Color colour);
@@ -128,7 +137,7 @@ std::string get_str(std::string list, short j);
#ifndef GRAPHTOOL_CPP
extern m_pic_index_t m_pic_index[200];
extern RECT bg[];
extern tessel_ref_t bg[];
#endif
#endif