diff options
| author | Paul Gilbert | 2018-10-19 18:47:10 -0700 | 
|---|---|---|
| committer | Paul Gilbert | 2018-12-08 19:05:59 -0800 | 
| commit | 89102c42cac1bd2367a6322f07286452bab21e11 (patch) | |
| tree | e86aed0217ac49102d3fa6b9148d6550624c9702 | |
| parent | 47a7a1d4e2640b3b34e2091be606b26723990efb (diff) | |
| download | scummvm-rg350-89102c42cac1bd2367a6322f07286452bab21e11.tar.gz scummvm-rg350-89102c42cac1bd2367a6322f07286452bab21e11.tar.bz2 scummvm-rg350-89102c42cac1bd2367a6322f07286452bab21e11.zip | |
GLK: Window setup for text buffer windows
| -rw-r--r-- | engines/gargoyle/glk_types.h | 4 | ||||
| -rw-r--r-- | engines/gargoyle/module.mk | 1 | ||||
| -rw-r--r-- | engines/gargoyle/windows.cpp | 531 | ||||
| -rw-r--r-- | engines/gargoyle/windows.h | 133 | 
4 files changed, 640 insertions, 29 deletions
| diff --git a/engines/gargoyle/glk_types.h b/engines/gargoyle/glk_types.h index 040d666fbe..82f70e3618 100644 --- a/engines/gargoyle/glk_types.h +++ b/engines/gargoyle/glk_types.h @@ -219,6 +219,10 @@ enum StyleHint {  	stylehint_just_RightFlush = 3,  }; +enum FACES { MONOR, MONOB, MONOI, MONOZ, PROPR, PROPB, PROPI, PROPZ }; +enum TYPES { MONOF, PROPF }; +enum STYLES { FONTR, FONTB, FONTI, FONTZ }; +  #ifdef GLK_MODULE_IMAGE  enum ImageAlign { diff --git a/engines/gargoyle/module.mk b/engines/gargoyle/module.mk index 4a535af612..e5542a763c 100644 --- a/engines/gargoyle/module.mk +++ b/engines/gargoyle/module.mk @@ -5,6 +5,7 @@ MODULE_OBJS := \  	events.o \  	gargoyle.o \  	glk.o \ +	picture.o \  	windows.o \  	scott/detection.o \  	scott/scott.o diff --git a/engines/gargoyle/windows.cpp b/engines/gargoyle/windows.cpp index 25af90b277..194002b62b 100644 --- a/engines/gargoyle/windows.cpp +++ b/engines/gargoyle/windows.cpp @@ -27,6 +27,7 @@  namespace Gargoyle {  #define MAGIC_WINDOW_NUM (9876) +#define GLI_SUBPIX 8  bool Windows::_confLockCols;  bool Windows::_confLockRows; @@ -48,9 +49,47 @@ int Windows::_cellW;  int Windows::_cellH;  int Windows::_baseLine;  int Windows::_leading; +int Windows::_scrollWidth; +bool Windows::_overrideReverse; +bool Windows::_overrideFgSet; +bool Windows::_overrideBgSet; +int Windows::_overrideFgVal; +int Windows::_overrideBgVal; + + +WindowStyle T_STYLES[style_NUMSTYLES] = { +	{ PROPR,{ 0xff,0xff,0xff },{ 0x00,0x00,0x00 }, 0 }, ///< Normal +	{ PROPI,{ 0xff,0xff,0xff },{ 0x00,0x00,0x00 }, 0 }, ///< Emphasized +	{ MONOR,{ 0xff,0xff,0xff },{ 0x00,0x00,0x00 }, 0 }, ///< Preformatted +	{ PROPB,{ 0xff,0xff,0xff },{ 0x00,0x00,0x00 }, 0 }, ///< Header +	{ PROPB,{ 0xff,0xff,0xff },{ 0x00,0x00,0x00 }, 0 }, ///< Subheader +	{ PROPZ,{ 0xff,0xff,0xff },{ 0x00,0x00,0x00 }, 0 }, ///< Alert +	{ PROPR,{ 0xff,0xff,0xff },{ 0x00,0x00,0x00 }, 0 }, ///< Note +	{ PROPR,{ 0xff,0xff,0xff },{ 0x00,0x00,0x00 }, 0 }, ///< BlockQuote +	{ PROPB,{ 0xff,0xff,0xff },{ 0x00,0x00,0x00 }, 0 }, ///< Input +	{ MONOR,{ 0xff,0xff,0xff },{ 0x00,0x00,0x00 }, 0 }, ///< User1 +	{ MONOR,{ 0xff,0xff,0xff },{ 0x00,0x00,0x00 }, 0 }, ///< User2 +}; + +WindowStyle G_STYLES[style_NUMSTYLES] = { +	{ MONOR,{ 0xff,0xff,0xff },{ 0x00,0x00,0x00 }, 0 }, ///< Normal +	{ MONOI,{ 0xff,0xff,0xff },{ 0x00,0x00,0x00 }, 0 }, ///< Emphasized +	{ MONOR,{ 0xff,0xff,0xff },{ 0x00,0x00,0x00 }, 0 }, ///< Preformatted +	{ MONOB,{ 0xff,0xff,0xff },{ 0x00,0x00,0x00 }, 0 }, ///< Header +	{ MONOB,{ 0xff,0xff,0xff },{ 0x00,0x00,0x00 }, 0 }, ///< Subheader +	{ MONOR,{ 0xff,0xff,0xff },{ 0x00,0x00,0x00 }, 0 }, ///< Alert +	{ MONOR,{ 0xff,0xff,0xff },{ 0x00,0x00,0x00 }, 0 }, ///< Note +	{ MONOR,{ 0xff,0xff,0xff },{ 0x00,0x00,0x00 }, 0 }, ///< BlockQuote +	{ MONOR,{ 0xff,0xff,0xff },{ 0x00,0x00,0x00 }, 0 }, ///< Input +	{ MONOR,{ 0x60,0x60,0x60 },{ 0xff,0xff,0xff }, 0 }, ///< User1 +	{ MONOR,{ 0x60,0x60,0x60 },{ 0xff,0xff,0xff }, 0 }, ///< User2 +}; + +/*--------------------------------------------------------------------------*/  Windows::Windows(Graphics::Screen *screen) : _screen(screen), _forceRedraw(true), _moreFocus(false), -		_windowList(nullptr), _rootWin(nullptr), _focusWin(nullptr) { +		_windowList(nullptr), _rootWin(nullptr), _focusWin(nullptr), _mask(nullptr), +		_claimSelect(0) {  	_confLockCols = false;  	_confLockRows = false;  	_wMarginx = 15; @@ -69,6 +108,12 @@ Windows::Windows(Graphics::Screen *screen) : _screen(screen), _forceRedraw(true)  	_cellW = _cellH = 0;  	_baseLine = 15;  	_leading = 20; +	_scrollWidth = 0; +	_overrideReverse = false; +	_overrideFgSet = false; +	_overrideBgSet = false; +	_overrideFgVal = 0; +	_overrideBgVal = 0;  }  Window *Windows::windowOpen(Window *splitwin, glui32 method, glui32 size, @@ -127,7 +172,7 @@ Window *Windows::windowOpen(Window *splitwin, glui32 method, glui32 size,  		_rootWin = newwin;  	} else {  		// create pairwin, with newwin as the key -		pairwin = new PairWindow(method, newwin, size); +		pairwin = newPairWindow(method, newwin, size);  		pairwin->child1 = splitwin;  		pairwin->child2 = newwin; @@ -157,16 +202,16 @@ Window *Windows::newWindow(glui32 type, glui32 rock) {  	switch (type) {  	case wintype_Blank: -		win = new BlankWindow(rock); +		win = new BlankWindow(this, rock);  		break;  	case wintype_TextGrid: -		win = new TextGridWindow(rock); +		win = new TextGridWindow(this, rock);  		break;  	case wintype_TextBuffer: -		win = new TextBufferWindow(rock); +		win = new TextBufferWindow(this, rock);  		break;  	case wintype_Graphics: -		win = new GraphicsWindow(rock); +		win = new GraphicsWindow(this, rock);  		break;  	case wintype_Pair:  		error("Pair windows cannot be created directly"); @@ -183,7 +228,7 @@ Window *Windows::newWindow(glui32 type, glui32 rock) {  }  PairWindow *Windows::newPairWindow(glui32 method, Window *key, glui32 size) { -	PairWindow *pwin = new PairWindow(method, key, size); +	PairWindow *pwin = new PairWindow(this, method, key, size);  	pwin->next = _windowList;  	_windowList = pwin;  	if (pwin->next) @@ -221,10 +266,24 @@ void Windows::rearrange() {  	}  } +void Windows::clearSelection() { +	if (!_mask) { +		warning("clear_selection: mask not initialized"); +		return; +	} + +	if (_mask->select.left || _mask->select.right +		|| _mask->select.top || _mask->select.bottom) +		_forceRedraw = true; + +	_mask->select = Common::Rect(); +	_claimSelect = false; +} +  /*--------------------------------------------------------------------------*/ -Window::Window(glui32 rock) : _magicnum(MAGIC_WINDOW_NUM), _rock(rock), _type(0), -		parent(nullptr), next(nullptr), prev(nullptr), +Window::Window(Windows *windows, glui32 rock) : _magicnum(MAGIC_WINDOW_NUM), +		_windows(windows), _rock(rock), _type(0), parent(nullptr), next(nullptr), prev(nullptr),  		yadj(0), line_request(0), line_request_uni(0), char_request(0), char_request_uni(0),  		mouse_request(0), hyper_request(0), more_request(0), scroll_request(0), image_loaded(0),  		echo_line_input(true),  line_terminators(nullptr), termct(0), str(nullptr), echostr(nullptr) { @@ -243,13 +302,13 @@ Window::Window(glui32 rock) : _magicnum(MAGIC_WINDOW_NUM), _rock(rock), _type(0)  /*--------------------------------------------------------------------------*/ -BlankWindow::BlankWindow(uint32 rock) : Window(rock) { +BlankWindow::BlankWindow(Windows *windows, uint32 rock) : Window(windows, rock) {  	_type = wintype_Blank;  }  /*--------------------------------------------------------------------------*/ -TextGridWindow::TextGridWindow(uint32 rock) : Window(rock) { +TextGridWindow::TextGridWindow(Windows *windows, uint32 rock) : Window(windows, rock) {  	_type = wintype_TextGrid;  	width = height = 0;  	curx = cury = 0; @@ -259,6 +318,8 @@ TextGridWindow::TextGridWindow(uint32 rock) : Window(rock) {  	incurs = inlen = 0;  	inarrayrock.num = 0;  	line_terminators = nullptr; + +	Common::copy(&G_STYLES[0], &G_STYLES[style_NUMSTYLES], styles);  }  void TextGridWindow::rearrange(const Common::Rect &box) { @@ -289,6 +350,8 @@ void TextGridWindow::touch(int line) {  //	winrepaint(bbox.left, y, bbox.right, y + Windows::_leading);  } +/*--------------------------------------------------------------------------*/ +  void TextGridWindow::TextGridRow::resize(size_t newSize) {  	chars.clear();  	attr.clear(); @@ -299,19 +362,452 @@ void TextGridWindow::TextGridRow::resize(size_t newSize) {  /*--------------------------------------------------------------------------*/ -TextBufferWindow::TextBufferWindow(uint32 rock) : Window(rock) { +TextBufferWindow::TextBufferWindow(Windows *windows, uint32 rock) : Window(windows, rock), +		historypos(0), historyfirst(0), historypresent(0), lastseen(0), scrollpos(0), +		scrollmax(0), scrollback(SCROLLBACK), width(-1), height(-1), inbuf(nullptr), +		line_terminators(nullptr), echo_line_input(true), ladjw(0), radjw(0), ladjn(0), +		radjn(0), numchars(0), chars(nullptr), attrs(nullptr), +		spaced(0), dashed(0), copybuf(0), copypos(0) {  	_type = wintype_TextBuffer; +	Common::fill(&history[0], &history[HISTORYLEN], nullptr); + +	Common::copy(&T_STYLES[0], &T_STYLES[style_NUMSTYLES], styles); +} + +void TextBufferWindow::rearrange(const Common::Rect &box) { +	Window::rearrange(box); +	int newwid, newhgt; +	int rnd; + +	newwid = (box.width() - Windows::_tMarginx * 2 - Windows::_scrollWidth) / Windows::_cellW; +	newhgt = (box.height() - Windows::_tMarginy * 2) / Windows::_cellH; + +	/* align text with bottom */ +	rnd = newhgt * Windows::_cellH + Windows::_tMarginy * 2; +	yadj = (box.height() - rnd); +	bbox.top += (box.height() - rnd); + +	if (newwid != width) { +		width = newwid; +		reflow(); +	} + +	if (newhgt != height) { +		/* scroll up if we obscure new lines */ +		if (lastseen >= newhgt - 1) +			scrollpos += (height - newhgt); + +		height = newhgt; + +		/* keep window within 'valid' lines */ +		if (scrollpos > scrollmax - height + 1) +			scrollpos = scrollmax - height + 1; +		if (scrollpos < 0) +			scrollpos = 0; +		touchScroll(); + +		/* allocate copy buffer */ +		if (copybuf) +			delete[] copybuf; +		copybuf = new glui32[height * TBLINELEN]; + +		for (int i = 0; i < (height * TBLINELEN); i++) +			copybuf[i] = 0; + +		copypos = 0; +	} +} + +void TextBufferWindow::reflow() { +	int inputbyte = -1; +	Attributes curattr, oldattr; +	int i, k, p, s; +	int x; + +	if (height < 4 || width < 20) +		return; + +	lines[0].len = numchars; + +	/* allocate temp buffers */ +	Attributes *attrbuf = new Attributes[SCROLLBACK * TBLINELEN]; +	glui32 *charbuf = new glui32[SCROLLBACK * TBLINELEN]; +	int *alignbuf = new int[SCROLLBACK]; +	Picture **pictbuf = new Picture *[SCROLLBACK]; +	glui32 *hyperbuf = new glui32[SCROLLBACK]; +	int *offsetbuf = new int[SCROLLBACK]; + +	if (!attrbuf || !charbuf || !alignbuf || !pictbuf || !hyperbuf || !offsetbuf) { +		delete[] attrbuf; +		delete[] charbuf; +		delete[] alignbuf; +		delete[] pictbuf; +		delete[] hyperbuf; +		delete[] offsetbuf; +		return; +	} + +	/* copy text to temp buffers */ + +	oldattr = attr; +	curattr.clear(); + +	x = 0; +	p = 0; +	s = scrollmax < SCROLLBACK ? scrollmax : SCROLLBACK - 1; + +	for (k = s; k >= 0; k--) { +		if (k == 0 && line_request) +			inputbyte = p + infence; + +		if (lines[k].lpic) { +			offsetbuf[x] = p; +			alignbuf[x] = imagealign_MarginLeft; +			pictbuf[x] = lines[k].lpic; + +			if (pictbuf[x]) pictbuf[x]->increment(); +			hyperbuf[x] = lines[k].lhyper; +			x++; +		} + +		if (lines[k].rpic) { +			offsetbuf[x] = p; +			alignbuf[x] = imagealign_MarginRight; +			pictbuf[x] = lines[k].rpic; +			if (pictbuf[x]) pictbuf[x]->increment(); +			hyperbuf[x] = lines[k].rhyper; +			x++; +		} + +		for (i = 0; i < lines[k].len; i++) { +			attrbuf[p] = curattr = lines[k].attr[i]; +			charbuf[p] = lines[k].chars[i]; +			p++; +		} + +		if (lines[k].newline) { +			attrbuf[p] = curattr; +			charbuf[p] = '\n'; +			p++; +		} +	} + +	offsetbuf[x] = -1; + +	/* clear window */ + +	clear(); + +	/* and dump text back */ + +	x = 0; +	for (i = 0; i < p; i++) { +		if (i == inputbyte) +			break; +		attr = attrbuf[i]; + +		if (offsetbuf[x] == i) { +			putPicture(pictbuf[x], alignbuf[x], hyperbuf[x]); +			x++; +		} + +		putCharUni(charbuf[i]); +	} + +	/* terribly sorry about this... */ +	lastseen = 0; +	scrollpos = 0; + +	if (inputbyte != -1) { +		infence = numchars; +		putTextUnit(charbuf + inputbyte, p - inputbyte, numchars, 0); +		incurs = numchars; +	} + +	// free temp buffers +	delete[] attrbuf; +	delete[] charbuf; +	delete[] alignbuf; +	delete[] pictbuf; +	delete[] hyperbuf; +	delete[] offsetbuf; + +	attr = oldattr; + +	touchScroll(); +} + +void TextBufferWindow::touchScroll() { +	_windows->clearSelection(); + +	// TODO +	//winrepaint(win->bbox.left, win->bbox.top, win->bbox.right, win->bbox.bottom); +	for (int i = 0; i < scrollmax; i++) +		lines[i].dirty = true; +} + +void TextBufferWindow::clear() { +	int i; + +	attr.fgset = Windows::_overrideFgSet; +	attr.bgset = Windows::_overrideBgSet; +	attr.fgcolor = Windows::_overrideFgSet ? Windows::_overrideFgVal : 0; +	attr.bgcolor = Windows::_overrideBgSet ? Windows::_overrideBgVal : 0; +	attr.reverse = false; + +	ladjw = radjw = 0; +	ladjn = radjn = 0; + +	spaced = 0; +	dashed = 0; + +	numchars = 0; + +	for (i = 0; i < scrollback; i++) { +		lines[i].len = 0; + +		if (lines[i].lpic) lines[i].lpic->decrement(); +		lines[i].lpic = nullptr; +		if (lines[i].rpic) lines[i].rpic->decrement(); +		lines[i].rpic = nullptr; + +		lines[i].lhyper = 0; +		lines[i].rhyper = 0; +		lines[i].lm = 0; +		lines[i].rm = 0; +		lines[i].newline = 0; +		lines[i].dirty = 1; +		lines[i].repaint = 0; +	} + +	lastseen = 0; +	scrollpos = 0; +	scrollmax = 0; + +	for (i = 0; i < height; i++) +		touch(i); +} + +bool TextBufferWindow::putPicture(Picture *pic, glui32 align, glui32 linkval) { +	if (align == imagealign_MarginRight) +	{ +		if (lines[0].rpic || numchars) +			return false; + +		radjw = (pic->w + Windows::_tMarginx) * GLI_SUBPIX; +		radjn = (pic->h + Windows::_cellH - 1) / Windows::_cellH; +		lines[0].rpic = pic; +		lines[0].rm = radjw; +		lines[0].rhyper = linkval; +	} else { +		if (align != imagealign_MarginLeft && numchars) +			putCharUni('\n'); + +		if (lines[0].lpic || numchars) +			return false; + +		ladjw = (pic->w + Windows::_tMarginx) * GLI_SUBPIX; +		ladjn = (pic->h + Windows::_cellH - 1) / Windows::_cellH; +		lines[0].lpic = pic; +		lines[0].lm = ladjw; +		lines[0].lhyper = linkval; + +		if (align != imagealign_MarginLeft) +			flowBreak(); +	} + +	return true ; +} + +void TextBufferWindow::putCharUni(glui32 ch) { +	/* +	glui32 bchars[TBLINELEN]; +	Attributes battrs[TBLINELEN]; +	int pw; +	int bpoint; +	int saved; +	int i; +	int linelen; +	unsigned char *color; + +	gli_tts_speak(&ch, 1); + +	pw = (win->bbox.x1 - win->bbox.x0 - Windows::_tMarginx * 2 - gli_scroll_width) * GLI_SUBPIX; +	pw = pw - 2 * SLOP - radjw - ladjw; + +	color = gli_override_bg_set ? gli_window_color : win->bgcolor; + +	// oops ... overflow +	if (numchars + 1 >= TBLINELEN) +		scrolloneline(dwin, 0); + +	if (ch == '\n') { +		scrolloneline(dwin, 1); +		return; +	} + +	if (gli_conf_quotes) { +		// fails for 'tis a wonderful day in the '80s +		if (gli_conf_quotes > 1 && ch == '\'') +		{ +			if (numchars == 0 || leftquote(chars[numchars - 1])) +				ch = UNI_LSQUO; +		} + +		if (ch == '`') +			ch = UNI_LSQUO; + +		if (ch == '\'') +			ch = UNI_RSQUO; + +		if (ch == '"') +		{ +			if (numchars == 0 || leftquote(chars[numchars - 1])) +				ch = UNI_LDQUO; +			else +				ch = UNI_RDQUO; +		} +	} + +	if (gli_conf_dashes && win->attr.style != style_Preformatted) +	{ +		if (ch == '-') +		{ +			dashed++; +			if (dashed == 2) +			{ +				numchars--; +				if (gli_conf_dashes == 2) +					ch = UNI_NDASH; +				else +					ch = UNI_MDASH; +			} +			if (dashed == 3) +			{ +				numchars--; +				ch = UNI_MDASH; +				dashed = 0; +			} +		} +		else +			dashed = 0; +	} + +	if (gli_conf_spaces && win->attr.style != style_Preformatted +		&& styles[win->attr.style].bg == color +		&& !styles[win->attr.style].reverse) +	{ +		// turn (period space space) into (period space) +		if (gli_conf_spaces == 1) +		{ +			if (ch == '.') +				spaced = 1; +			else if (ch == ' ' && spaced == 1) +				spaced = 2; +			else if (ch == ' ' && spaced == 2) +			{ +				spaced = 0; +				return; +			} +			else +				spaced = 0; +		} + +		// Turn (per sp x) into (per sp sp x) +		if (gli_conf_spaces == 2) +		{ +			if (ch == '.') +				spaced = 1; +			else if (ch == ' ' && spaced == 1) +				spaced = 2; +			else if (ch != ' ' && spaced == 2) +			{ +				spaced = 0; +				win_textbuffer_putchar_uni(win, ' '); +			} +			else +				spaced = 0; +		} +	} + +	chars[numchars] = ch; +	attrs[numchars] = win->attr; +	numchars++; + +	// kill spaces at the end for line width calculation +	linelen = numchars; +	while (linelen > 1 && chars[linelen - 1] == ' ' +		&& styles[attrs[linelen - 1].style].bg == color +		&& !styles[attrs[linelen - 1].style].reverse) +		linelen--; + +	if (calcwidth(dwin, chars, attrs, 0, linelen, -1) >= pw) +	{ +		bpoint = numchars; + +		for (i = numchars - 1; i > 0; i--) +			if (chars[i] == ' ') +			{ +				bpoint = i + 1; // skip space +				break; +			} + +		saved = numchars - bpoint; + +		memcpy(bchars, chars + bpoint, saved * 4); +		memcpy(battrs, attrs + bpoint, saved * sizeof(attr_t)); +		numchars = bpoint; + +		scrolloneline(dwin, 0); + +		memcpy(chars, bchars, saved * 4); +		memcpy(attrs, battrs, saved * sizeof(attr_t)); +		numchars = saved; +	} + +	touch(0); +	*/ +} + +void TextBufferWindow::putTextUnit(const glui32 *buf, int len, int pos, int oldlen) { +	// TODO +} + +void TextBufferWindow::flowBreak() { +	// TODO +} + +void TextBufferWindow::touch(int line) { +//	int y = bbox.top + Windows::_tMarginy + (height - line - 1) * Windows::_leading; +	lines[line].dirty = 1; +	_windows->clearSelection(); +	//winrepaint(bbox.left, y - 2, bbox.right, y + Windows::_leading + 2);  }  /*--------------------------------------------------------------------------*/ -GraphicsWindow::GraphicsWindow(uint32 rock) : Window(rock) { +TextBufferWindow::TextBufferRow::TextBufferRow() : len(0), newline(0), dirty(false), repaint(false), +		lpic(nullptr), rpic(nullptr), lhyper(0), rhyper(0), lm(0), rm(0) { +} + +void TextBufferWindow::TextBufferRow::resize(size_t newSize) { +	chars.clear(); +	attr.clear(); +	chars.resize(newSize); +	attr.resize(newSize); +	Common::fill(&chars[0], &chars[0] + newSize, ' '); +} + +/*--------------------------------------------------------------------------*/ + +GraphicsWindow::GraphicsWindow(Windows *windows, uint32 rock) : Window(windows, rock) {  	_type = wintype_Graphics;  }  /*--------------------------------------------------------------------------*/ -PairWindow::PairWindow(glui32 method, Window *_key, glui32 _size) : Window(0), +PairWindow::PairWindow(Windows *windows, glui32 method, Window *_key, glui32 _size) : +		Window(windows, 0),  		dir(method & winmethod_DirMask),  		division(method & winmethod_DivisionMask),  		wborder((method & winmethod_BorderMask) == winmethod_Border), @@ -323,13 +819,6 @@ PairWindow::PairWindow(glui32 method, Window *_key, glui32 _size) : Window(0),  /*--------------------------------------------------------------------------*/ -WindowStyle::WindowStyle() : font(0), reverse(0) { -	Common::fill(&bg[0], &bg[3], 0); -	Common::fill(&fg[0], &fg[3], 0); -} - -/*--------------------------------------------------------------------------*/ -  void Attributes::clear() {  	fgset = 0;  	bgset = 0; diff --git a/engines/gargoyle/windows.h b/engines/gargoyle/windows.h index 45907a86e3..aad4969be2 100644 --- a/engines/gargoyle/windows.h +++ b/engines/gargoyle/windows.h @@ -29,12 +29,21 @@  #include "common/stream.h"  #include "graphics/screen.h"  #include "gargoyle/glk_types.h" +#include "gargoyle/picture.h"  namespace Gargoyle {  class Window;  class PairWindow; +struct WindowMask; +#define HISTORYLEN 100 +#define SCROLLBACK 512 +#define TBLINELEN 300 + +/** + * Main windows manager + */  class Windows {  private:  	Graphics::Screen *_screen; @@ -43,6 +52,8 @@ private:  	Window *_focusWin;         ///< The window selected by the player  	bool _forceRedraw;  	bool _moreFocus; +	bool _claimSelect; +	WindowMask *_mask;  private:  	/**  	 * Create a new window @@ -76,6 +87,12 @@ public:  	static int _cellW, _cellH;  	static int _baseLine;  	static int _leading; +	static int _scrollWidth; +	static bool _overrideReverse; +	static bool _overrideFgSet; +	static bool _overrideBgSet; +	static int _overrideFgVal; +	static int _overrideBgVal;  public:  	/**  	 * Constructor @@ -92,6 +109,8 @@ public:  	 * Return the root window  	 */  	Window *getRoot() const { return _rootWin; } + +	void clearSelection();  };  /** @@ -102,8 +121,6 @@ struct WindowStyle {  	byte bg[3];  	byte fg[3];  	int reverse; - -	WindowStyle();  };  /** @@ -132,11 +149,21 @@ struct Attributes {  	void clear();  }; +struct WindowMask { +	int hor; +	int ver; +	glui32 **links; +	Common::Rect select; + +	WindowMask() : hor(0), ver(0), links(nullptr) {} +}; +  /**   * Window definition   */  class Window {  public: +	Windows *_windows;  	glui32 _magicnum;  	glui32 _rock;  	glui32 _type; @@ -172,7 +199,7 @@ public:  	/**  	 * Constructor  	 */ -	Window(uint32 rock); +	Window(Windows *windows, uint32 rock);  	/**  	 * Destructor @@ -194,7 +221,7 @@ public:  	/**  	 * Constructor  	 */ -	BlankWindow(uint32 rock); +	BlankWindow(Windows *windows, uint32 rock);  };  /** @@ -245,7 +272,7 @@ public:  	/**  	 * Constructor  	 */ -	TextGridWindow(uint32 rock); +	TextGridWindow(Windows *windows, uint32 rock);  	/**  	 * Rearranges the window @@ -257,11 +284,101 @@ public:   * Text Buffer window   */  class TextBufferWindow : public Window { +	/** +	 * Structure for a row within the window +	 */ +	struct TextBufferRow { +		Common::Array<uint32> chars; +		Common::Array<Attributes> attr; +		int len, newline; +		bool dirty, repaint; +		Picture *lpic, *rpic; +		glui32 lhyper, rhyper; +		int lm, rm; + +		/** +		 * Constructor +		 */ +		TextBufferRow(); + +		/** +		 * Resize the row +		 */ +		void resize(size_t newSize); +	}; +	typedef Common::Array<TextBufferRow> TextBufferRows; +private: +	void reflow(); +	void touchScroll(); +	bool putPicture(Picture *pic, glui32 align, glui32 linkval); +	void putCharUni(glui32 ch); +	void putTextUnit(const glui32 *buf, int len, int pos, int oldlen); +	void flowBreak(); + +	/** +	 * Mark a given text row as modified +	 */ +	void touch(int line); +public: +	int width, height; +	int spaced; +	int dashed; + +	TextBufferRows lines; +	int scrollback; + +	int numchars;       ///< number of chars in last line: lines[0] +	glui32 *chars;      ///< alias to lines[0].chars +	Attributes *attrs;  ///< alias to lines[0].attrs + +						///< adjust margins temporarily for images +	int ladjw; +	int ladjn; +	int radjw; +	int radjn; + +	/* Command history. */ +	glui32 *history[HISTORYLEN]; +	int historypos; +	int historyfirst, historypresent; + +	/* for paging */ +	int lastseen; +	int scrollpos; +	int scrollmax; + +	/* for line input */ +	void *inbuf;        ///< unsigned char* for latin1, glui32* for unicode +	int inmax; +	long infence; +	long incurs; +	Attributes origattr; +	gidispatch_rock_t inarrayrock; + +	glui32 echo_line_input; +	glui32 *line_terminators; + +	/* style hints and settings */ +	WindowStyle styles[style_NUMSTYLES]; + +	/* for copy selection */ +	glui32 *copybuf; +	int copypos;  public:  	/**  	 * Constructor  	 */ -	TextBufferWindow(uint32 rock); +	TextBufferWindow(Windows *windows, uint32 rock); + +	/** +	 * Rearranges the window +	 */ +	virtual void rearrange(const Common::Rect &box); + +	/** +	 * Clear the window +	 */ +	void clear();  };  /** @@ -272,7 +389,7 @@ public:  	/**  	 * Constructor  	 */ -	GraphicsWindow(uint32 rock); +	GraphicsWindow(Windows *windows, uint32 rock);  };  /** @@ -294,7 +411,7 @@ public:  	/**  	 * Constructor  	 */ -	PairWindow(glui32 method, Window *_key, glui32 _size); +	PairWindow(Windows *windows, glui32 method, Window *_key, glui32 _size);  };  } // End of namespace Gargoyle | 
