aboutsummaryrefslogtreecommitdiff
path: root/engines/gargoyle
diff options
context:
space:
mode:
authorPaul Gilbert2018-10-23 19:25:00 -0700
committerPaul Gilbert2018-12-08 19:05:59 -0800
commitba907c9aec333903acb013e9d3a25962c69b6ca6 (patch)
treefe2cb6f5dbf613505cb990b18065706dabd1469c /engines/gargoyle
parentcb2b7d439fb9cb89f2758d103ba2ea710e4f0a72 (diff)
downloadscummvm-rg350-ba907c9aec333903acb013e9d3a25962c69b6ca6.tar.gz
scummvm-rg350-ba907c9aec333903acb013e9d3a25962c69b6ca6.tar.bz2
scummvm-rg350-ba907c9aec333903acb013e9d3a25962c69b6ca6.zip
GLK: Implementing text buffer window methods
Diffstat (limited to 'engines/gargoyle')
-rw-r--r--engines/gargoyle/draw.cpp21
-rw-r--r--engines/gargoyle/draw.h12
-rw-r--r--engines/gargoyle/gargoyle.cpp9
-rw-r--r--engines/gargoyle/gargoyle.h5
-rw-r--r--engines/gargoyle/glk_types.h29
-rw-r--r--engines/gargoyle/picture.cpp25
-rw-r--r--engines/gargoyle/picture.h20
-rw-r--r--engines/gargoyle/speech.h49
-rw-r--r--engines/gargoyle/window_graphics.cpp5
-rw-r--r--engines/gargoyle/window_graphics.h3
-rw-r--r--engines/gargoyle/window_mask.cpp2
-rw-r--r--engines/gargoyle/window_mask.h7
-rw-r--r--engines/gargoyle/window_text_buffer.cpp1319
-rw-r--r--engines/gargoyle/window_text_buffer.h72
-rw-r--r--engines/gargoyle/window_text_grid.cpp9
-rw-r--r--engines/gargoyle/window_text_grid.h11
-rw-r--r--engines/gargoyle/windows.cpp27
-rw-r--r--engines/gargoyle/windows.h31
18 files changed, 1462 insertions, 194 deletions
diff --git a/engines/gargoyle/draw.cpp b/engines/gargoyle/draw.cpp
index 86d5fb0f92..f16d1a56ab 100644
--- a/engines/gargoyle/draw.cpp
+++ b/engines/gargoyle/draw.cpp
@@ -24,9 +24,28 @@
namespace Gargoyle {
-int Draw::drawStringUni(int x, int y, int fidx, byte *rgb, glui32 *s, int n, int spw) {
+int Draw::drawString(int x, int y, int fidx, const byte *rgb, const char *s, int n, int spw) {
// TODO
return 0;
}
+int Draw::drawStringUni(int x, int y, int fidx, const byte *rgb, const glui32 *s, int n, int spw) {
+ // TODO
+ return 0;
+}
+
+int Draw::stringWidth(int fidx, const char *s, int n, int spw) {
+ // TODO
+ return 0;
+}
+
+int Draw::stringWidthUni(int fidx, const glui32 *s, int n, int spw) {
+ // TODO
+ return 0;
+}
+
+void Draw::drawCaret(const Common::Point &pos) {
+ // TODO
+}
+
} // End of namespace Gargoyle
diff --git a/engines/gargoyle/draw.h b/engines/gargoyle/draw.h
index 61dfe1891a..e0ec133642 100644
--- a/engines/gargoyle/draw.h
+++ b/engines/gargoyle/draw.h
@@ -23,14 +23,22 @@
#ifndef GARGOYLE_DRAW_H
#define GARGOYLE_DRAW_H
-#include "common/events.h"
+#include "common/rect.h"
#include "gargoyle/glk_types.h"
namespace Gargoyle {
class Draw {
protected:
- int drawStringUni(int x, int y, int fidx, byte *rgb, glui32 *s, int n, int spw);
+ int drawString(int x, int y, int fidx, const byte *rgb, const char *s, int n, int spw);
+
+ int drawStringUni(int x, int y, int fidx, const byte *rgb, const glui32 *s, int n, int spw);
+
+ int stringWidth(int fidx, const char *s, int n, int spw);
+
+ int stringWidthUni(int fidx, const glui32 *s, int n, int spw);
+
+ void drawCaret(const Common::Point &pos);
};
} // End of namespace Gargoyle
diff --git a/engines/gargoyle/gargoyle.cpp b/engines/gargoyle/gargoyle.cpp
index 8620e886e0..37df6d1f3e 100644
--- a/engines/gargoyle/gargoyle.cpp
+++ b/engines/gargoyle/gargoyle.cpp
@@ -31,8 +31,10 @@
#include "gargoyle/gargoyle.h"
#include "gargoyle/conf.h"
#include "gargoyle/events.h"
+#include "gargoyle/picture.h"
#include "gargoyle/streams.h"
#include "gargoyle/windows.h"
+#include "gargoyle/window_mask.h"
namespace Gargoyle {
@@ -40,7 +42,8 @@ GargoyleEngine *g_vm;
GargoyleEngine::GargoyleEngine(OSystem *syst, const GargoyleGameDescription *gameDesc) :
_gameDescription(gameDesc), Engine(syst), _random("Gargoyle"), _conf(nullptr),
- _events(nullptr), _screen(nullptr), _windows(nullptr),
+ _events(nullptr), _picList(nullptr), _screen(nullptr), _windows(nullptr),
+ _windowMask(nullptr), _copySelect(false),
gli_unregister_obj(nullptr), gli_register_arr(nullptr), gli_unregister_arr(nullptr) {
g_vm = this;
}
@@ -48,9 +51,11 @@ GargoyleEngine::GargoyleEngine(OSystem *syst, const GargoyleGameDescription *gam
GargoyleEngine::~GargoyleEngine() {
delete _conf;
delete _events;
+ delete _picList;
delete _screen;
delete _streams;
delete _windows;
+ delete _windowMask;
}
void GargoyleEngine::initialize() {
@@ -64,8 +69,10 @@ void GargoyleEngine::initialize() {
_screen = new Graphics::Screen();
_conf = new Conf();
_events = new Events();
+ _picList = new PicList();
_streams = new Streams();
_windows = new Windows(_screen);
+ _windowMask = new WindowMask();
}
Common::Error GargoyleEngine::run() {
diff --git a/engines/gargoyle/gargoyle.h b/engines/gargoyle/gargoyle.h
index 1d81cb92e7..b99b7b44f6 100644
--- a/engines/gargoyle/gargoyle.h
+++ b/engines/gargoyle/gargoyle.h
@@ -36,7 +36,9 @@ namespace Gargoyle {
class Conf;
class Events;
+class PicList;
class Windows;
+class WindowMask;
class Streams;
enum InterpreterType {
@@ -94,8 +96,11 @@ protected:
public:
Conf *_conf;
Events *_events;
+ PicList *_picList;
Streams *_streams;
Windows *_windows;
+ WindowMask *_windowMask;
+ bool _copySelect;
void (*gli_unregister_obj)(void *obj, glui32 objclass, gidispatch_rock_t objrock);
gidispatch_rock_t (*gli_register_arr)(void *array, glui32 len, const char *typecode);
void (*gli_unregister_arr)(void *array, glui32 len, const char *typecode, gidispatch_rock_t objrock);
diff --git a/engines/gargoyle/glk_types.h b/engines/gargoyle/glk_types.h
index eaebb6f929..a25a413221 100644
--- a/engines/gargoyle/glk_types.h
+++ b/engines/gargoyle/glk_types.h
@@ -53,6 +53,35 @@ class Window;
typedef struct glk_fileref_struct *frefid_t;
typedef struct glk_schannel_struct *schanid_t;
+/**
+ * Usurp C1 space for ligatures and smart typography glyphs
+ */
+enum Enc {
+ ENC_LIG_FI = 128,
+ ENC_LIG_FL = 129,
+ ENC_LSQUO = 130,
+ ENC_RSQUO = 131,
+ ENC_LDQUO = 132,
+ ENC_RDQUO = 133,
+ ENC_NDASH = 134,
+ ENC_MDASH = 135,
+ ENC_FLOWBREAK = 136
+};
+
+/**
+ * These are the Unicode versions
+ */
+enum UniChars {
+ UNI_LIG_FI = 0xFB01,
+ UNI_LIG_FL = 0xFB02,
+ UNI_LSQUO = 0x2018,
+ UNI_RSQUO = 0x2019,
+ UNI_LDQUO = 0x201c,
+ UNI_RDQUO = 0x201d,
+ UNI_NDASH = 0x2013,
+ UNI_MDASH = 0x2014
+};
+
enum Gestalt {
gestalt_Version = 0,
gestalt_CharInput = 1,
diff --git a/engines/gargoyle/picture.cpp b/engines/gargoyle/picture.cpp
index 4b0b892322..fd33e718dd 100644
--- a/engines/gargoyle/picture.cpp
+++ b/engines/gargoyle/picture.cpp
@@ -24,6 +24,16 @@
namespace Gargoyle {
+void PicList::increment() {
+ // TODO
+}
+
+void PicList::decrement() {
+ // TODO
+}
+
+/*--------------------------------------------------------------------------*/
+
void Picture::increment() {
++_refCount;
}
@@ -35,4 +45,19 @@ void Picture::decrement() {
}
}
+Picture *Picture::load(uint32 id) {
+ // TODO: gli_picture_load
+ return nullptr;
+}
+
+Picture *Picture::scale(int sx, int sy) {
+ // TODO: gli_picture_scale
+ return nullptr;
+}
+
+void Picture::drawPicture(int x0, int y0, int dx0, int dy0, int dx1, int dy1) {
+ // TODO: drawPicture
+}
+
+
} // End of namespace Gargoyle
diff --git a/engines/gargoyle/picture.h b/engines/gargoyle/picture.h
index 38f776c6bc..c9527c5663 100644
--- a/engines/gargoyle/picture.h
+++ b/engines/gargoyle/picture.h
@@ -27,7 +27,17 @@
namespace Gargoyle {
+class PicList {
+public:
+ void increment();
+
+ void decrement();
+};
+
struct Picture : Graphics::Surface {
+public:
+ static Picture *load(uint32 id);
+public:
int _refCount;
uint32 _id;
bool _scaled;
@@ -46,6 +56,16 @@ struct Picture : Graphics::Surface {
* Decrement reference counter
*/
void decrement();
+
+ /**
+ * Rescale the picture to a new picture of a given size
+ */
+ Picture *scale(int sx, int sy);
+
+ /**
+ * Draw the picture
+ */
+ void drawPicture(int x0, int y0, int dx0, int dy0, int dx1, int dy1);
};
} // End of namespace Gargoyle
diff --git a/engines/gargoyle/speech.h b/engines/gargoyle/speech.h
new file mode 100644
index 0000000000..1ff2cb178d
--- /dev/null
+++ b/engines/gargoyle/speech.h
@@ -0,0 +1,49 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef GARGOYLE_SPEECH_H
+#define GARGOYLE_SPEECH_H
+
+#include "common/events.h"
+#include "gargoyle/glk_types.h"
+
+namespace Gargoyle {
+
+/**
+ * Currently not implemented
+ */
+class Speech {
+protected:
+ void gli_initialize_tts(void) {}
+
+ void gli_tts_flush(void) {}
+
+ void gli_tts_purge(void) {}
+
+ void gli_tts_speak(const glui32 *buf, size_t len) {}
+
+ void gli_free_tts(void) {}
+};
+
+} // End of namespace Gargoyle
+
+#endif
diff --git a/engines/gargoyle/window_graphics.cpp b/engines/gargoyle/window_graphics.cpp
index cc9a5dd19e..732686d2da 100644
--- a/engines/gargoyle/window_graphics.cpp
+++ b/engines/gargoyle/window_graphics.cpp
@@ -86,4 +86,9 @@ void GraphicsWindow::redraw() {
// TODO
}
+glui32 GraphicsWindow::imageDraw(glui32 image, glui32 align, bool scaled, glui32 width, glui32 height) {
+ // TODO: win_graphics_draw_picture
+ return 0;
+}
+
} // End of namespace Gargoyle
diff --git a/engines/gargoyle/window_graphics.h b/engines/gargoyle/window_graphics.h
index 77e49105b2..b0f53faf72 100644
--- a/engines/gargoyle/window_graphics.h
+++ b/engines/gargoyle/window_graphics.h
@@ -77,6 +77,9 @@ public:
*/
virtual void redraw() override;
+ virtual glui32 imageDraw(glui32 image, glui32 align, bool scaled, glui32 width = 0,
+ glui32 height = 0) override;
+
/**
* Get the window dimensions
*/
diff --git a/engines/gargoyle/window_mask.cpp b/engines/gargoyle/window_mask.cpp
index f0f6aa36bf..fe1d463eb7 100644
--- a/engines/gargoyle/window_mask.cpp
+++ b/engines/gargoyle/window_mask.cpp
@@ -202,7 +202,7 @@ int WindowMask::checkSelection(uint x0, uint y0, uint x1, uint y1) {
return false;
}
-int WindowMask::getSelection(uint x0, uint y0, uint x1, uint y1, uint *rx0, uint *rx1) {
+int WindowMask::getSelection(uint x0, uint y0, uint x1, uint y1, int *rx0, int *rx1) {
uint row, upper, lower, above, below;
int row_selected, found_left, found_right;
int from_right, from_below, is_above, is_below;
diff --git a/engines/gargoyle/window_mask.h b/engines/gargoyle/window_mask.h
index db0d7e655d..9dc5826916 100644
--- a/engines/gargoyle/window_mask.h
+++ b/engines/gargoyle/window_mask.h
@@ -30,13 +30,14 @@ namespace Gargoyle {
class Window;
-struct WindowMask {
+class WindowMask {
+public:
size_t _hor, _ver;
glui32 **_links;
Common::Rect _select;
static int _lastX, _lastY;
-
+public:
/**
* Constructor
*/
@@ -59,7 +60,7 @@ struct WindowMask {
int checkSelection(uint x0, uint y0, uint x1, uint y1);
- int getSelection(uint x0, uint y0, uint x1, uint y1, uint *rx0, uint *rx1);
+ int getSelection(uint x0, uint y0, uint x1, uint y1, int *rx0, int *rx1);
};
} // End of namespace Gargoyle
diff --git a/engines/gargoyle/window_text_buffer.cpp b/engines/gargoyle/window_text_buffer.cpp
index b916fc4b5c..3df2e5cd18 100644
--- a/engines/gargoyle/window_text_buffer.cpp
+++ b/engines/gargoyle/window_text_buffer.cpp
@@ -23,9 +23,17 @@
#include "gargoyle/window_text_buffer.h"
#include "gargoyle/conf.h"
#include "gargoyle/gargoyle.h"
+#include "gargoyle/string.h"
namespace Gargoyle {
+/**
+ *
+ * How many pixels we add to left/right margins
+ */
+#define SLOP (2 * GLI_SUBPIX)
+
+
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),
@@ -35,7 +43,7 @@ TextBufferWindow::TextBufferWindow(Windows *windows, uint32 rock) : Window(windo
_type = wintype_TextBuffer;
Common::fill(&_history[0], &_history[HISTORYLEN], nullptr);
- Common::copy(&g_conf->_tStyles[0], &g_conf->_tStyles[style_NUMSTYLES], styles);
+ Common::copy(&g_conf->_tStyles[0], &g_conf->_tStyles[style_NUMSTYLES], _styles);
}
TextBufferWindow::~TextBufferWindow() {
@@ -49,10 +57,10 @@ TextBufferWindow::~TextBufferWindow() {
delete[] _lineTerminators;
for (int i = 0; i < _scrollBack; i++) {
- if (_lines[i].lpic)
- _lines[i].lpic->decrement();
- if (_lines[i].rpic)
- _lines[i].rpic->decrement();
+ if (_lines[i]._lPic)
+ _lines[i]._lPic->decrement();
+ if (_lines[i]._rPic)
+ _lines[i]._rPic->decrement();
}
}
@@ -109,7 +117,7 @@ void TextBufferWindow::reflow() {
if (_height < 4 || _width < 20)
return;
- _lines[0].len = _numChars;
+ _lines[0]._len = _numChars;
/* allocate temp buffers */
Attributes *attrbuf = new Attributes[SCROLLBACK * TBLINELEN];
@@ -142,32 +150,32 @@ void TextBufferWindow::reflow() {
if (k == 0 && _lineRequest)
inputbyte = p + _inFence;
- if (_lines[k].lpic) {
+ if (_lines[k]._lPic) {
offsetbuf[x] = p;
alignbuf[x] = imagealign_MarginLeft;
- pictbuf[x] = _lines[k].lpic;
+ pictbuf[x] = _lines[k]._lPic;
if (pictbuf[x]) pictbuf[x]->increment();
- hyperbuf[x] = _lines[k].lhyper;
+ hyperbuf[x] = _lines[k]._lHyper;
x++;
}
- if (_lines[k].rpic) {
+ if (_lines[k]._rPic) {
offsetbuf[x] = p;
alignbuf[x] = imagealign_MarginRight;
- pictbuf[x] = _lines[k].rpic;
+ pictbuf[x] = _lines[k]._rPic;
if (pictbuf[x]) pictbuf[x]->increment();
- hyperbuf[x] = _lines[k].rhyper;
+ 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];
+ for (i = 0; i < _lines[k]._len; i++) {
+ attrbuf[p] = curattr = _lines[k]._attrs[i];
+ charbuf[p] = _lines[k]._chars[i];
p++;
}
- if (_lines[k].newline) {
+ if (_lines[k]._newLine) {
attrbuf[p] = curattr;
charbuf[p] = '\n';
p++;
@@ -224,32 +232,32 @@ void TextBufferWindow::touchScroll() {
_windows->repaint(_bbox);
for (int i = 0; i < _scrollMax; i++)
- _lines[i].dirty = true;
+ _lines[i]._dirty = true;
}
bool TextBufferWindow::putPicture(Picture *pic, glui32 align, glui32 linkval) {
if (align == imagealign_MarginRight)
{
- if (_lines[0].rpic || _numChars)
+ if (_lines[0]._rPic || _numChars)
return false;
_radjw = (pic->w + g_conf->_tMarginX) * GLI_SUBPIX;
_radjn = (pic->h + g_conf->_cellH - 1) / g_conf->_cellH;
- _lines[0].rpic = pic;
- _lines[0].rm = _radjw;
- _lines[0].rhyper = linkval;
+ _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)
+ if (_lines[0]._lPic || _numChars)
return false;
_ladjw = (pic->w + g_conf->_tMarginX) * GLI_SUBPIX;
_ladjn = (pic->h + g_conf->_cellH - 1) / g_conf->_cellH;
- _lines[0].lpic = pic;
- _lines[0].lm = _ladjw;
- _lines[0].lhyper = linkval;
+ _lines[0]._lPic = pic;
+ _lines[0]._lm = _ladjw;
+ _lines[0]._lHyper = linkval;
if (align != imagealign_MarginLeft)
flowBreak();
@@ -258,17 +266,110 @@ bool TextBufferWindow::putPicture(Picture *pic, glui32 align, glui32 linkval) {
return true;
}
-void TextBufferWindow::flowBreak() {
- // TODO
+glui32 TextBufferWindow::imageDraw(glui32 image, glui32 align, bool scaled, glui32 width, glui32 height) {
+ Picture *pic;
+ glui32 hyperlink;
+ int error;
+
+ pic = Picture::load(image);
+
+ if (!pic)
+ return false;
+
+ if (!_imageLoaded) {
+ g_vm->_picList->increment();
+ _imageLoaded = true;
+ }
+
+ if (scaled) {
+ Picture *tmp;
+ tmp = pic->scale(width, height);
+ pic = tmp;
+ }
+
+ hyperlink = _attr.hyper;
+
+ pic->increment();
+ error = putPicture(pic, align, hyperlink);
+
+ return error;
+}
+
+bool TextBufferWindow::flowBreak() {
+ while (_ladjn || _radjn)
+ putCharUni('\n');
+ return true;
+}
+
+void TextBufferWindow::putText(const char *buf, int len, int pos, int oldlen) {
+ int diff = len - oldlen;
+
+ if (_numChars + diff >= TBLINELEN)
+ return;
+
+ if (diff != 0 && pos + oldlen < _numChars)
+ {
+ memmove(_chars + pos + len,
+ _chars + pos + oldlen,
+ (_numChars - (pos + oldlen)) * 4);
+ memmove(_attrs + pos + len,
+ _attrs + pos + oldlen,
+ (_numChars - (pos + oldlen)) * sizeof(Attributes));
+ }
+ if (len > 0) {
+ int i;
+ for (i = 0; i < len; i++) {
+ _chars[pos + i] = buf[i];
+ _attrs[pos + i].set(style_Input);
+ }
+ }
+ _numChars += diff;
+
+ if (_inBuf) {
+ if (_inCurs >= pos + oldlen)
+ _inCurs += diff;
+ else if (_inCurs >= pos)
+ _inCurs = pos + len;
+ }
+
+ touch(0);
}
void TextBufferWindow::putTextUni(const glui32 *buf, int len, int pos, int oldlen) {
- // TODO
+ int diff = len - oldlen;
+
+ if (_numChars + diff >= TBLINELEN)
+ return;
+
+ if (diff != 0 && pos + oldlen < _numChars) {
+ memmove(_chars + pos + len,
+ _chars + pos + oldlen,
+ (_numChars - (pos + oldlen)) * 4);
+ memmove(_attrs + pos + len,
+ _attrs + pos + oldlen,
+ (_numChars - (pos + oldlen)) * sizeof(Attributes));
+ }
+ if (len > 0) {
+ int i;
+ memmove(_chars + pos, buf, len * 4);
+ for (i = 0; i < len; i++)
+ _attrs[pos + i].set(style_Input);
+ }
+ _numChars += diff;
+
+ if (_inBuf) {
+ if (_inCurs >= pos + oldlen)
+ _inCurs += diff;
+ else if (_inCurs >= pos)
+ _inCurs = pos + len;
+ }
+
+ touch(0);
}
void TextBufferWindow::touch(int line) {
int y = _bbox.top + g_conf->_tMarginY + (_height - line - 1) * g_conf->_leading;
- _lines[line].dirty = 1;
+ _lines[line]._dirty = 1;
_windows->clearSelection();
_windows->repaint(Common::Rect(_bbox.left, y - 2, _bbox.right, y + g_conf->_leading + 2));
}
@@ -278,7 +379,6 @@ glui32 TextBufferWindow::getSplit(glui32 size, bool vertical) const {
}
void TextBufferWindow::putCharUni(glui32 ch) {
- /*
glui32 bchars[TBLINELEN];
Attributes battrs[TBLINELEN];
int pw;
@@ -286,29 +386,28 @@ void TextBufferWindow::putCharUni(glui32 ch) {
int saved;
int i;
int linelen;
- unsigned char *color;
+ byte *color;
gli_tts_speak(&ch, 1);
- pw = (_bbox.right - _bbox.left - g_conf->_tMarginX * 2 - gli_scroll_width) * GLI_SUBPIX;
- pw = pw - 2 * SLOP - radjw - ladjw;
+ pw = (_bbox.right - _bbox.left - g_conf->_tMarginX * 2 - g_conf->_scrollWidth) * GLI_SUBPIX;
+ pw = pw - 2 * SLOP - _radjw - _ladjw;
- color = Windows::_overrideBgSet ? gli_window_color : bgcolor;
+ color = Windows::_overrideBgSet ? g_conf->_windowColor : _bgColor;
// oops ... overflow
- if (numchars + 1 >= TBLINELEN)
- scrolloneline(dwin, 0);
+ if (_numChars + 1 >= TBLINELEN)
+ scrollOneLine(0);
if (ch == '\n') {
- scrolloneline(dwin, 1);
+ scrollOneLine(1);
return;
}
- if (gli_conf_quotes) {
+ if (g_conf->_quotes) {
// fails for 'tis a wonderful day in the '80s
- if (gli_conf_quotes > 1 && ch == '\'')
- {
- if (numchars == 0 || leftquote(_chars[numchars - 1]))
+ if (g_conf->_quotes > 1 && ch == '\'') {
+ if (_numChars == 0 || leftquote(_chars[_numChars - 1]))
ch = UNI_LSQUO;
}
@@ -318,122 +417,112 @@ void TextBufferWindow::putCharUni(glui32 ch) {
if (ch == '\'')
ch = UNI_RSQUO;
- if (ch == '"')
- {
- if (numchars == 0 || leftquote(_chars[numchars - 1]))
+ if (ch == '"') {
+ if (_numChars == 0 || leftquote(_chars[_numChars - 1]))
ch = UNI_LDQUO;
else
ch = UNI_RDQUO;
}
}
- if (gli_conf_dashes && attr.style != style_Preformatted)
- {
- if (ch == '-')
- {
- dashed++;
- if (dashed == 2)
- {
- numchars--;
- if (gli_conf_dashes == 2)
+ if (g_conf->_dashes && _attr.style != style_Preformatted) {
+ if (ch == '-') {
+ _dashed++;
+ if (_dashed == 2) {
+ _numChars--;
+ if (g_conf->_dashes == 2)
ch = UNI_NDASH;
else
ch = UNI_MDASH;
}
- if (dashed == 3)
- {
- numchars--;
+ if (_dashed == 3) {
+ _numChars--;
ch = UNI_MDASH;
- dashed = 0;
+ _dashed = 0;
}
+ } else {
+ _dashed = 0;
}
- else
- dashed = 0;
}
- if (gli_conf_spaces && attr.style != style_Preformatted
- && styles[attr.style].bg == color
- && !styles[attr.style].reverse)
+ if (g_conf->_spaces && _attr.style != style_Preformatted
+ && _styles[_attr.style].bg == color
+ && !_styles[_attr.style].reverse)
{
// turn (period space space) into (period space)
- if (gli_conf_spaces == 1)
- {
+ if (g_conf->_spaces == 1) {
if (ch == '.')
- spaced = 1;
- else if (ch == ' ' && spaced == 1)
- spaced = 2;
- else if (ch == ' ' && spaced == 2)
- {
- spaced = 0;
+ _spaced = 1;
+ else if (ch == ' ' && _spaced == 1)
+ _spaced = 2;
+ else if (ch == ' ' && _spaced == 2) {
+ _spaced = 0;
return;
+ } else {
+ _spaced = 0;
}
- else
- spaced = 0;
}
// Turn (per sp x) into (per sp sp x)
- if (gli_conf_spaces == 2)
- {
+ if (g_conf->_spaces == 2) {
if (ch == '.')
- spaced = 1;
- else if (ch == ' ' && spaced == 1)
- spaced = 2;
- else if (ch != ' ' && spaced == 2)
+ _spaced = 1;
+ else if (ch == ' ' && _spaced == 1)
+ _spaced = 2;
+ else if (ch != ' ' && _spaced == 2)
{
- spaced = 0;
- win_textbuffer_putchar_uni(win, ' ');
+ _spaced = 0;
+ putCharUni(' ');
+ } else {
+ _spaced = 0;
}
- else
- spaced = 0;
}
}
- _chars[numchars] = ch;
- attrs[numchars] = attr;
- numchars++;
+ _chars[_numChars] = ch;
+ _attrs[_numChars] = _attr;
+ _numChars++;
// kill spaces at the end for line width calculation
- linelen = numchars;
+ linelen = _numChars;
while (linelen > 1 && _chars[linelen - 1] == ' '
- && styles[attrs[linelen - 1].style].bg == color
- && !styles[attrs[linelen - 1].style].reverse)
+ && _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;
+ if (calcWidth(_chars, _attrs, 0, linelen, -1) >= pw) {
+ bpoint = _numChars;
- for (i = numchars - 1; i > 0; i--)
- if (_chars[i] == ' ')
- {
+ for (i = _numChars - 1; i > 0; i--)
+ if (_chars[i] == ' ') {
bpoint = i + 1; // skip space
break;
}
- saved = numchars - bpoint;
+ saved = _numChars - bpoint;
memcpy(bchars, _chars + bpoint, saved * 4);
- memcpy(battrs, attrs + bpoint, saved * sizeof(attr_t));
- numchars = bpoint;
+ memcpy(battrs, _attrs + bpoint, saved * sizeof(Attributes));
+ _numChars = bpoint;
- scrolloneline(dwin, 0);
+ scrollOneLine(0);
memcpy(_chars, bchars, saved * 4);
- memcpy(attrs, battrs, saved * sizeof(attr_t));
- numchars = saved;
+ memcpy(_attrs, battrs, saved * sizeof(Attributes));
+ _numChars = saved;
}
touch(0);
- */
}
bool TextBufferWindow::unputCharUni(uint32 ch) {
- // TODO
- return false;
-}
+ if (_numChars > 0 && _chars[_numChars - 1] == ch) {
+ _numChars--;
+ touch(0);
+ return true;
+ }
-void TextBufferWindow::moveCursor(const Common::Point &newPos) {
- // TODO
+ return false;
}
void TextBufferWindow::clear() {
@@ -454,20 +543,20 @@ void TextBufferWindow::clear() {
_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 = true;
- _lines[i].repaint = false;
+ _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 = true;
+ _lines[i]._repaint = false;
}
_lastSeen = 0;
@@ -478,24 +567,146 @@ void TextBufferWindow::clear() {
touch(i);
}
+void TextBufferWindow::click(const Common::Point &newPos) {
+ int gh = false;
+ int gs = false;
+
+ if (_lineRequest || _charRequest
+ || _lineRequestUni || _charRequestUni
+ || _moreRequest || _scrollRequest)
+ _windows->setFocus(this);
+
+ if (_hyperRequest) {
+ glui32 linkval = g_vm->_windowMask->getHyperlink(newPos);
+ if (linkval) {
+ g_vm->_events->eventStore(evtype_Hyperlink, this, linkval, 0);
+ _hyperRequest = false;
+ if (g_conf->_safeClicks)
+ g_vm->_events->_forceClick = 1;
+ gh = true;
+ }
+ }
+
+ if (newPos.x > _bbox.right - g_conf->_scrollWidth) {
+ if (newPos.y < _bbox.top + g_conf->_tMarginY + g_conf->_scrollWidth)
+ acceptScroll(keycode_Up);
+ else if (newPos.y > _bbox.bottom - g_conf->_tMarginY - g_conf->_scrollWidth)
+ acceptScroll(keycode_Down);
+ else if (newPos.y < (_bbox.top + _bbox.bottom) / 2)
+ acceptScroll(keycode_PageUp);
+ else
+ acceptScroll(keycode_PageDown);
+ gs = true;
+ }
+
+ if (!gh && !gs) {
+ g_vm->_copySelect = true;
+ g_vm->_windowMask->startSelection(newPos);
+ }
+}
+
void TextBufferWindow::requestLineEvent(char *buf, glui32 maxlen, glui32 initlen) {
- if (_charRequest || _lineRequest || _charRequestUni || _lineRequestUni)
- {
+ if (_charRequest || _lineRequest || _charRequestUni || _lineRequestUni) {
warning("request_line_event: window already has keyboard request");
return;
}
- // TODO
+ int pw;
+
+ gli_tts_flush();
+
+ /* because '>' prompt is ugly without extra space */
+ if (_numChars && _chars[_numChars - 1] == '>')
+ putCharUni(' ');
+ if (_numChars && _chars[_numChars - 1] == '?')
+ putCharUni(' ');
+
+ /* make sure we have some space left for typing... */
+ pw = (_bbox.right - _bbox.left - g_conf->_tMarginX * 2) * GLI_SUBPIX;
+ pw = pw - 2 * SLOP - _radjw + _ladjw;
+ if (calcWidth(_chars, _attrs, 0, _numChars, -1) >= pw * 3 / 4)
+ putCharUni('\n');
+
+ _inBuf = buf;
+ _inMax = maxlen;
+ _inFence = _numChars;
+ _inCurs = _numChars;
+ _origAttr = _attr;
+ _attr.set(style_Input);
+
+ _historyPos = _historyPresent;
+
+ if (initlen) {
+ touch(0);
+ putText(buf, initlen, _inCurs, 0);
+ }
+
+ _echoLineInput = _echoLineInputBase;
+
+ if (_lineTerminatorsBase && _termCt) {
+ _lineTerminators = new glui32[_termCt + 1];
+
+ if (_lineTerminators) {
+ memcpy(_lineTerminators, _lineTerminatorsBase, _termCt * sizeof(glui32));
+ _lineTerminators[_termCt] = 0;
+ }
+ }
+
+ if (g_vm->gli_register_arr)
+ _inArrayRock = (*g_vm->gli_register_arr)(buf, maxlen, "&+#!Cn");
}
void TextBufferWindow::requestLineEventUni(glui32 *buf, glui32 maxlen, glui32 initlen) {
- if (_charRequest || _lineRequest || _charRequestUni || _lineRequestUni)
- {
+ if (_charRequest || _lineRequest || _charRequestUni || _lineRequestUni) {
warning("request_line_event_uni: window already has keyboard request");
return;
}
- // TODO
+ int pw;
+
+ gli_tts_flush();
+
+ /* because '>' prompt is ugly without extra space */
+ if (_numChars && _chars[_numChars - 1] == '>')
+ putCharUni(' ');
+ if (_numChars && _chars[_numChars - 1] == '?')
+ putCharUni(' ');
+
+ /* make sure we have some space left for typing... */
+ pw = (_bbox.right - _bbox.left - g_conf->_tMarginX * 2) * GLI_SUBPIX;
+ pw = pw - 2 * SLOP - _radjw + _ladjw;
+ if (calcWidth(_chars, _attrs, 0, _numChars, -1) >= pw * 3 / 4)
+ putCharUni('\n');
+
+ //_lastSeen = 0;
+
+ _inBuf = buf;
+ _inMax = maxlen;
+ _inFence = _numChars;
+ _inCurs = _numChars;
+ _origAttr = _attr;
+ _attr.set(style_Input);
+
+ _historyPos = _historyPresent;
+
+ if (initlen) {
+ touch(0);
+ putTextUni(buf, initlen, _inCurs, 0);
+ }
+
+ _echoLineInput = _echoLineInputBase;
+
+ if (_lineTerminatorsBase && _termCt) {
+ _lineTerminators = new glui32[_termCt + 1];
+
+ if (_lineTerminators) {
+ memcpy(_lineTerminators, _lineTerminatorsBase, _termCt * sizeof(glui32));
+ _lineTerminators[_termCt] = 0;
+ }
+ }
+
+ if (g_vm->gli_register_arr)
+ _inArrayRock = (*g_vm->gli_register_arr)(buf, maxlen, "&+#!Iu");
}
void TextBufferWindow::cancelLineEvent(Event *ev) {
@@ -571,21 +782,857 @@ void TextBufferWindow::cancelLineEvent(Event *ev) {
}
void TextBufferWindow::redraw() {
- // TODO
+ TextBufferRow *ln;
+ int linelen;
+ int nsp, spw, pw;
+ int x0, y0, x1, y1;
+ int x, y, w;
+ int a, b;
+ glui32 link;
+ int font;
+ unsigned char *color;
+ int i;
+ int hx0, hx1, hy0, hy1;
+ int selbuf, selrow, selchar, sx0, sx1, selleft, selright;
+ int tx, tsc, tsw, lsc, rsc;
+
+ _lines[0]._len = _numChars;
+
+ ln = new TextBufferRow();
+ if (!ln)
+ return;
+
+ x0 = (_bbox.left + g_conf->_tMarginX) * GLI_SUBPIX;
+ x1 = (_bbox.right - g_conf->_tMarginX - g_conf->_scrollWidth) * GLI_SUBPIX;
+ y0 = _bbox.top + g_conf->_tMarginY;
+ y1 = _bbox.bottom - g_conf->_tMarginY;
+
+ pw = x1 - x0 - 2 * GLI_SUBPIX;
+
+ /* check if any part of buffer is selected */
+ selbuf = g_vm->_windowMask->checkSelection(x0/GLI_SUBPIX,y0,x1/GLI_SUBPIX,y1);
+
+ for (i = _scrollPos + _height - 1; i >= _scrollPos; i--) {
+ /* top of line */
+ y = y0 + (_height - (i - _scrollPos) - 1) * g_conf->_leading;
+
+ /* check if part of line is selected */
+ if (selbuf) {
+ selrow = g_vm->_windowMask->getSelection(x0/GLI_SUBPIX, y,
+ x1/GLI_SUBPIX, y + g_conf->_leading,
+ &sx0, &sx1);
+ selleft = (sx0 == x0/GLI_SUBPIX);
+ selright = (sx1 == x1/GLI_SUBPIX);
+ } else {
+ selrow = false;
+ }
+
+ /* mark selected line dirty */
+ if (selrow)
+ _lines[i]._dirty = true;
+
+ memcpy(ln, &_lines[i], sizeof(TextBufferRow));
+
+ /* skip if we can */
+ if (!ln->_dirty && !ln->_repaint && !Windows::_forceRedraw && _scrollPos == 0)
+ continue;
+
+ /* repaint previously selected lines if needed */
+ if (ln->_repaint && !Windows::_forceRedraw)
+ _windows->redrawRect(Common::Rect(x0 / GLI_SUBPIX, y,
+ x1/GLI_SUBPIX, y + g_conf->_leading));
+
+ /* keep selected line dirty and flag for repaint */
+ if (!selrow) {
+ _lines[i]._dirty = false;
+ _lines[i]._repaint = false;
+ } else {
+ _lines[i]._repaint = true;
+ }
+
+ /* leave bottom line blank for [more] prompt */
+ if (i == _scrollPos && i > 0)
+ continue;
+
+ linelen = ln->_len;
+
+ /* kill spaces at the end unless they're a different color*/
+ color = Windows::_overrideBgSet ? g_conf->_windowColor : _bgColor;
+ while (i > 0 && linelen > 1 && ln->_chars[linelen-1] == ' '
+ && _styles[ln->_attrs[linelen-1].style].bg == color
+ && !_styles[ln->_attrs[linelen-1].style].reverse)
+ linelen --;
+
+ /* kill characters that would overwrite the scroll bar */
+ while (linelen > 1 && calcWidth(ln->_chars, ln->_attrs, 0, linelen, -1) >= pw)
+ linelen --;
+
+ /*
+ * count spaces and width for justification
+ */
+ if (g_conf->_justify && !ln->_newLine && i > 0) {
+ for (a = 0, nsp = 0; a < linelen; a++)
+ if (ln->_chars[a] == ' ')
+ nsp ++;
+ w = calcWidth(ln->_chars, ln->_attrs, 0, linelen, 0);
+ if (nsp)
+ spw = (x1 - x0 - ln->_lm - ln->_rm - 2 * SLOP - w) / nsp;
+ else
+ spw = 0;
+ } else {
+ spw = -1;
+ }
+
+ /* find and highlight selected characters */
+ if (selrow && !Windows::_claimSelect) {
+ lsc = 0;
+ rsc = 0;
+ selchar = false;
+ /* optimized case for all chars selected */
+ if (selleft && selright) {
+ rsc = linelen > 0 ? linelen - 1 : 0;
+ selchar = calcWidth(ln->_chars, ln->_attrs, lsc, rsc, spw)/GLI_SUBPIX;
+ } else {
+ /* optimized case for leftmost char selected */
+ if (selleft) {
+ tsc = linelen > 0 ? linelen - 1 : 0;
+ selchar = calcWidth(ln->_chars, ln->_attrs, lsc, tsc, spw)/GLI_SUBPIX;
+ } else {
+ /* find the substring contained by the selection */
+ tx = (x0 + SLOP + ln->_lm)/GLI_SUBPIX;
+ /* measure string widths until we find left char */
+ for (tsc = 0; tsc < linelen; tsc++) {
+ tsw = calcWidth(ln->_chars, ln->_attrs, 0, tsc, spw)/GLI_SUBPIX;
+ if (tsw + tx >= sx0 ||
+ tsw + tx + GLI_SUBPIX >= sx0 && ln->_chars[tsc] != ' ') {
+ lsc = tsc;
+ selchar = true;
+ break;
+ }
+ }
+ }
+ if (selchar) {
+ /* optimized case for rightmost char selected */
+ if (selright) {
+ rsc = linelen > 0 ? linelen - 1 : 0;
+ } else {
+ /* measure string widths until we find right char */
+ for (tsc = lsc; tsc < linelen; tsc++) {
+ tsw = calcWidth(ln->_chars, ln->_attrs, lsc, tsc, spw)/GLI_SUBPIX;
+ if (tsw + sx0 < sx1)
+ rsc = tsc;
+ }
+ if (lsc && !rsc)
+ rsc = lsc;
+ }
+ }
+ }
+ /* reverse colors for selected chars */
+ if (selchar) {
+ for (tsc = lsc; tsc <= rsc; tsc++) {
+ ln->_attrs[tsc].reverse = !ln->_attrs[tsc].reverse;
+ _copyBuf[_copyPos] = ln->_chars[tsc];
+ _copyPos++;
+ }
+ }
+ /* add newline if we reach the end of the line */
+ if (ln->_len == 0 || ln->_len == (rsc+1)) {
+ _copyBuf[_copyPos] = '\n';
+ _copyPos++;
+ }
+ }
+
+ /* clear any stored hyperlink coordinates */
+ g_vm->_windowMask->putHyperlink(0, x0/GLI_SUBPIX, y,
+ x1/GLI_SUBPIX, y + g_conf->_leading);
+
+ /*
+ * fill in background colors
+ */
+ color = Windows::_overrideBgSet ? g_conf->_windowColor : _bgColor;
+ _windows->drawRect(x0/GLI_SUBPIX, y,
+ (x1-x0) / GLI_SUBPIX, g_conf->_leading,
+ color);
+
+ x = x0 + SLOP + ln->_lm;
+ a = 0;
+ for (b = 0; b < linelen; b++)
+ {
+ if (ln->_attrs[a] == ln->_attrs[b]) {
+ link = ln->_attrs[a].hyper;
+ font = ln->_attrs[a].attrFont(_styles);
+ color = ln->_attrs[a].attrBg(_styles);
+ w = stringWidthUni(font, ln->_chars + a, b - a, spw);
+ _windows->drawRect(x/GLI_SUBPIX, y,
+ w/GLI_SUBPIX, g_conf->_leading,
+ color);
+ if (link) {
+ _windows->drawRect(x/GLI_SUBPIX + 1, y + g_conf->_baseLine + 1,
+ w/GLI_SUBPIX + 1, g_conf->_linkStyle,
+ g_conf->_linkColor);
+ g_vm->_windowMask->putHyperlink(link, x/GLI_SUBPIX, y,
+ x/GLI_SUBPIX + w/GLI_SUBPIX,
+ y + g_conf->_leading);
+ }
+ x += w;
+ a = b;
+ }
+ }
+ link = ln->_attrs[a].hyper;
+ font = ln->_attrs[a].attrFont(_styles);
+ color = ln->_attrs[a].attrBg(_styles);
+ w = stringWidthUni(font, ln->_chars + a, b - a, spw);
+ _windows->drawRect(x/GLI_SUBPIX, y, w/GLI_SUBPIX,
+ g_conf->_leading, color);
+ if (link) {
+ _windows->drawRect(x/GLI_SUBPIX + 1, y + g_conf->_baseLine + 1,
+ w/GLI_SUBPIX + 1, g_conf->_linkStyle,
+ g_conf->_linkColor);
+ g_vm->_windowMask->putHyperlink(link, x/GLI_SUBPIX, y,
+ x/GLI_SUBPIX + w/GLI_SUBPIX,
+ y + g_conf->_leading);
+ }
+ x += w;
+
+ color = Windows::_overrideBgSet ? g_conf->_windowColor : _bgColor;
+ _windows->drawRect(x/GLI_SUBPIX, y,
+ x1/GLI_SUBPIX - x/GLI_SUBPIX, g_conf->_leading,
+ color);
+
+ /*
+ * draw caret
+ */
+
+ if (_windows->getFocusWindow() == this && i == 0 && (_lineRequest || _lineRequestUni)) {
+ w = calcWidth(_chars, _attrs, 0, _inCurs, spw);
+ if (w < pw - g_conf->_caretShape * 2 * GLI_SUBPIX)
+ drawCaret(Common::Point(x0 + SLOP + ln->_lm + w, y + g_conf->_baseLine));
+ }
+
+ /*
+ * draw text
+ */
+
+ x = x0 + SLOP + ln->_lm;
+ a = 0;
+ for (b = 0; b < linelen; b++)
+ {
+ if (ln->_attrs[a] == ln->_attrs[b]) {
+ link = ln->_attrs[a].hyper;
+ font = ln->_attrs[a].attrFont(_styles);
+ color = link ? g_conf->_linkColor : ln->_attrs[a].attrFg(_styles);
+ x = drawStringUni(x, y + g_conf->_baseLine,
+ font, color, ln->_chars + a, b - a, spw);
+ a = b;
+ }
+ }
+ link = ln->_attrs[a].hyper;
+ font = ln->_attrs[a].attrFont(_styles);
+ color = link ? g_conf->_linkColor : ln->_attrs[a].attrFg(_styles);
+ drawStringUni(x, y + g_conf->_baseLine,
+ font, color, ln->_chars + a, linelen - a, spw);
+ }
+
+ /*
+ * draw more prompt
+ */
+ if (_scrollPos && _height > 1)
+ {
+ x = x0 + SLOP;
+ y = y0 + (_height - 1) * g_conf->_leading;
+
+ g_vm->_windowMask->putHyperlink(0, x0/GLI_SUBPIX, y,
+ x1/GLI_SUBPIX, y + g_conf->_leading);
+
+ color = Windows::_overrideBgSet ? g_conf->_windowColor : _bgColor;
+ _windows->drawRect(x/GLI_SUBPIX, y,
+ x1/GLI_SUBPIX - x/GLI_SUBPIX, g_conf->_leading,
+ color);
+
+ w = stringWidth(g_conf->_moreFont,
+ g_conf->_morePrompt.c_str(), g_conf->_morePrompt.size(), -1);
+
+ if (g_conf->_moreAlign == 1) /* center */
+ x = x0 + SLOP + (x1 - x0 - w - SLOP * 2) / 2;
+ if (g_conf->_moreAlign == 2) /* right */
+ x = x1 - SLOP - w;
+
+ color = Windows::_overrideFgSet ? g_conf->_moreColor : _fgColor;
+ drawString(x, y + g_conf->_baseLine,
+ g_conf->_moreFont, color,
+ g_conf->_morePrompt.c_str(), g_conf->_morePrompt.size(), -1);
+ y1 = y; /* don't want pictures overdrawing "[more]" */
+
+ /* try to claim the focus */
+ _moreRequest = true;
+ Windows::_moreFocus = true;
+ } else {
+ _moreRequest = false;
+ y1 = y0 + _height * g_conf->_leading;
+ }
+
+ /*
+ * draw the images
+ */
+ for (i = 0; i < _scrollBack; i++) {
+ memcpy(ln, &_lines[i], sizeof(TextBufferRow));
+
+ y = y0 + (_height - (i - _scrollPos) - 1) * g_conf->_leading;
+
+ if (ln->_lPic) {
+ if (y < y1 && y + ln->_lPic->h > y0) {
+ ln->_lPic->drawPicture(x0/GLI_SUBPIX, y, x0/GLI_SUBPIX, y0, x1/GLI_SUBPIX, y1);
+ link = ln->_lHyper;
+ hy0 = y > y0 ? y : y0;
+ hy1 = y + ln->_lPic->h < y1 ? y + ln->_lPic->h : y1;
+ hx0 = x0/GLI_SUBPIX;
+ hx1 = x0/GLI_SUBPIX + ln->_lPic->w < x1/GLI_SUBPIX
+ ? x0/GLI_SUBPIX + ln->_lPic->w
+ : x1/GLI_SUBPIX;
+ g_vm->_windowMask->putHyperlink(link, hx0, hy0, hx1, hy1);
+ }
+ }
+
+ if (ln->_rPic) {
+ if (y < y1 && y + ln->_rPic->h > y0) {
+ ln->_rPic->drawPicture(x1/GLI_SUBPIX - ln->_rPic->w, y,
+ x0/GLI_SUBPIX, y0, x1/GLI_SUBPIX, y1);
+ link = ln->_rHyper;
+ hy0 = y > y0 ? y : y0;
+ hy1 = y + ln->_rPic->h < y1 ? y + ln->_rPic->h : y1;
+ hx0 = x1/GLI_SUBPIX - ln->_rPic->w > x0/GLI_SUBPIX
+ ? x1/GLI_SUBPIX - ln->_rPic->w
+ : x0/GLI_SUBPIX;
+ hx1 = x1/GLI_SUBPIX;
+ g_vm->_windowMask->putHyperlink(link, hx0, hy0, hx1, hy1);
+ }
+ }
+ }
+
+ /*
+ * Draw the scrollbar
+ */
+
+ /* try to claim scroll keys */
+ _scrollRequest = _scrollMax > _height;
+
+ if (_scrollRequest && g_conf->_scrollWidth)
+ {
+ int t0, t1;
+ x0 = _bbox.right - g_conf->_scrollWidth;
+ x1 = _bbox.right;
+ y0 = _bbox.top + g_conf->_tMarginY;
+ y1 = _bbox.bottom - g_conf->_tMarginY;
+
+ g_vm->_windowMask->putHyperlink(0, x0, y0, x1, y1);
+
+ y0 += g_conf->_scrollWidth / 2;
+ y1 -= g_conf->_scrollWidth / 2;
+
+ // pos = thbot, pos - ht = thtop, max = wtop, 0 = wbot
+ t0 = (_scrollMax - _scrollPos) - (_height - 1);
+ t1 = (_scrollMax - _scrollPos);
+ if (_scrollMax > _height) {
+ t0 = t0 * (y1 - y0) / _scrollMax + y0;
+ t1 = t1 * (y1 - y0) / _scrollMax + y0;
+ } else {
+ t0 = t1 = y0;
+ }
+
+ _windows->drawRect(x0+1, y0, x1-x0-2, y1-y0, g_conf->_scrollBg);
+ _windows->drawRect(x0+1, t0, x1-x0-2, t1-t0, g_conf->_scrollFg);
+
+ for (i = 0; i < g_conf->_scrollWidth / 2 + 1; i++) {
+ _windows->drawRect(x0+g_conf->_scrollWidth/2-i,
+ y0 - g_conf->_scrollWidth/2 + i,
+ i*2, 1, g_conf->_scrollFg);
+ _windows->drawRect(x0+g_conf->_scrollWidth/2-i,
+ y1 + g_conf->_scrollWidth/2 - i,
+ i*2, 1, g_conf->_scrollFg);
+ }
+ }
+
+ /* send selected text to clipboard */
+ if (selbuf && _copyPos) {
+ Windows::_claimSelect = true;
+
+ copyTextToClipboard(_copyBuf, _copyPos);
+ for (i = 0; i < _copyPos; i++)
+ _copyBuf[i] = 0;
+ _copyPos = 0;
+ }
+
+ /* no more prompt means all text has been seen */
+ if (!_moreRequest)
+ _lastSeen = 0;
+
+ free(ln);
}
-/*--------------------------------------------------------------------------*/
+int TextBufferWindow::acceptScroll(glui32 arg) {
+ int pageht = _height - 2; /* 1 for prompt, 1 for overlap */
+ int startpos = _scrollPos;
+
+ switch (arg) {
+ case keycode_PageUp:
+ _scrollPos += pageht;
+ break;
+ case keycode_End:
+ _scrollPos = 0;
+ break;
+ case keycode_Up:
+ _scrollPos++;
+ break;
+ case keycode_Down:
+ case keycode_Return:
+ _scrollPos--;
+ break;
+ case keycode_MouseWheelUp:
+ _scrollPos += 3;
+ startpos = true;
+ break;
+ case keycode_MouseWheelDown:
+ _scrollPos -= 3;
+ startpos = true;
+ break;
+ case ' ':
+ case keycode_PageDown:
+ //default:
+ if (pageht)
+ _scrollPos -= pageht;
+ else
+ _scrollPos = 0;
+ break;
+ }
+
+ if (_scrollPos > _scrollMax - _height + 1)
+ _scrollPos = _scrollMax - _height + 1;
+ if (_scrollPos < 0)
+ _scrollPos = 0;
+ touchScroll();
+
+ return (startpos || _scrollPos);
+}
+
+void TextBufferWindow::acceptReadChar(glui32 arg) {
+ glui32 key;
+
+ if (_height < 2)
+ _scrollPos = 0;
+
+ if (_scrollPos
+ || arg == keycode_PageUp
+ || arg == keycode_MouseWheelUp) {
+ acceptScroll(arg);
+ return;
+ }
+
+ switch (arg) {
+ case keycode_Erase:
+ key = keycode_Delete;
+ break;
+ case keycode_MouseWheelUp:
+ case keycode_MouseWheelDown:
+ return;
+ default:
+ key = arg;
+ }
+
+ gli_tts_purge();
+
+ if (key > 0xff && key < (0xffffffff - keycode_MAXVAL + 1)) {
+ if (!(_charRequestUni) || key > 0x10ffff)
+ key = keycode_Unknown;
+ }
+
+ _charRequest = false;
+ _charRequestUni = false;
+ g_vm->_events->eventStore(evtype_CharInput, this, key, 0);
+}
+
+void TextBufferWindow::acceptReadLine(glui32 arg) {
+ glui32 *cx;
+ int len;
+
+ if (_height < 2)
+ _scrollPos = 0;
+
+ if (_scrollPos
+ || arg == keycode_PageUp
+ || arg == keycode_MouseWheelUp)
+ {
+ acceptScroll(arg);
+ return;
+ }
+
+ if (!_inBuf)
+ return;
+
+ if (_lineTerminators && checkTerminator(arg)) {
+ for (cx = _lineTerminators; *cx; cx++) {
+ if (*cx == arg) {
+ acceptLine(arg);
+ return;
+ }
+ }
+ }
+
+ switch (arg) {
+
+ /* History keys (up and down) */
+
+ case keycode_Up:
+ if (_historyPos == _historyFirst)
+ return;
+ if (_historyPos == _historyPresent) {
+ len = _numChars - _inFence;
+ if (len > 0) {
+ cx = new glui32[len + 1];
+ memcpy(cx, &(_chars[_inFence]), len * 4);
+ cx[len] = 0;
+ } else {
+ cx = nullptr;
+ }
+ if (_history[_historyPos])
+ free(_history[_historyPos]);
+ _history[_historyPos] = cx;
+ }
+ _historyPos--;
+ if (_historyPos < 0)
+ _historyPos += HISTORYLEN;
+ cx = _history[_historyPos];
+ putTextUni(cx, cx ? strlen_uni(cx) : 0, _inFence,
+ _numChars - _inFence);
+ break;
+
+ case keycode_Down:
+ if (_historyPos == _historyPresent)
+ return;
+ _historyPos++;
+ if (_historyPos >= HISTORYLEN)
+ _historyPos -= HISTORYLEN;
+ cx = _history[_historyPos];
+ putTextUni(cx, cx ? strlen_uni(cx) : 0, _inFence,
+ _numChars - _inFence);
+ break;
+
+ /* Cursor movement keys, during line input. */
+
+ case keycode_Left:
+ if (_inCurs <= _inFence)
+ return;
+ _inCurs--;
+ break;
+
+ case keycode_Right:
+ if (_inCurs >= _numChars)
+ return;
+ _inCurs++;
+ break;
+
+ case keycode_Home:
+ if (_inCurs <= _inFence)
+ return;
+ _inCurs = _inFence;
+ break;
+
+ case keycode_End:
+ if (_inCurs >= _numChars)
+ return;
+ _inCurs = _numChars;
+ break;
+
+ case keycode_SkipWordLeft:
+ while (_inCurs > _inFence && _chars[_inCurs - 1] == ' ')
+ _inCurs--;
+ while (_inCurs > _inFence && _chars[_inCurs - 1] != ' ')
+ _inCurs--;
+ break;
+
+ case keycode_SkipWordRight:
+ while (_inCurs < _numChars && _chars[_inCurs] != ' ')
+ _inCurs++;
+ while (_inCurs < _numChars && _chars[_inCurs] == ' ')
+ _inCurs++;
+ break;
+
+ /* Delete keys, during line input. */
+
+ case keycode_Delete:
+ if (_inCurs <= _inFence)
+ return;
+ putTextUni(nullptr, 0, _inCurs - 1, 1);
+ break;
+
+ case keycode_Erase:
+ if (_inCurs >= _numChars)
+ return;
+ putTextUni(nullptr, 0, _inCurs, 1);
+ break;
+
+ case keycode_Escape:
+ if (_inFence >= _numChars)
+ return;
+ putTextUni(nullptr, 0, _inFence, _numChars - _inFence);
+ break;
+
+ /* Regular keys */
+
+ case keycode_Return:
+ acceptLine(arg);
+ break;
+
+ default:
+ if (arg >= 32 && arg <= 0x10FFFF)
+ {
+ if (g_conf->_caps && (arg > 0x60 && arg < 0x7b))
+ arg -= 0x20;
+ putTextUni(&arg, 1, _inCurs, 0);
+ }
+ break;
+ }
-TextBufferWindow::TextBufferRow::TextBufferRow() : len(0), newline(0), dirty(false), repaint(false),
- lpic(nullptr), rpic(nullptr), lhyper(0), rhyper(0), lm(0), rm(0) {
+ touch(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, ' ');
+/* Return or enter, during line input. Ends line input. */
+void TextBufferWindow::acceptLine(glui32 keycode) {
+ int ix;
+ int len, olen;
+ void *inbuf;
+ glui32 *s, *o;
+ int inmax;
+ gidispatch_rock_t inarrayrock;
+ int unicode = _lineRequestUni;
+
+ if (!_inBuf)
+ return;
+
+ inbuf = _inBuf;
+ inmax = _inMax;
+ inarrayrock = _inArrayRock;
+
+ len = _numChars - _inFence;
+ if (_echoStream)
+ _echoStream->echoLineUni(_chars + _inFence, len);
+
+ gli_tts_purge();
+ if (g_conf->_speakInput) {
+ const uint32 NEWLINE = '\n';
+ gli_tts_speak(_chars + _inFence, len);
+ gli_tts_speak((const glui32 *)&NEWLINE, 1);
+ }
+
+ /*
+ * Store in history.
+ * The history is a ring buffer, with historypresent being the index of the most recent
+ * element and historyfirst the index of the oldest element.
+ * A history entry should not repeat the string from the entry before it.
+ */
+ if (len) {
+ s = new glui32[len + 1];
+ memcpy(s, _chars + _inFence, len * sizeof(glui32));
+ s[len] = 0;
+
+ free(_history[_historyPresent]);
+ _history[_historyPresent] = nullptr;
+
+ o = _history[(_historyPresent == 0 ? HISTORYLEN : _historyPresent) - 1];
+ olen = o ? strlen_uni(o) : 0;
+
+ if (len != olen || memcmp(s, o, olen * sizeof(glui32))) {
+ _history[_historyPresent] = s;
+
+ _historyPresent++;
+ if (_historyPresent == HISTORYLEN)
+ _historyPresent = 0;
+
+ if (_historyPresent == _historyFirst) {
+ _historyFirst++;
+ if (_historyFirst == HISTORYLEN)
+ _historyFirst = 0;
+ }
+ } else {
+ free(s);
+ }
+ }
+
+ /* Store in event buffer. */
+
+ if (len > inmax)
+ len = inmax;
+
+ if (!unicode) {
+ for (ix = 0; ix<len; ix++) {
+ glui32 ch = _chars[_inFence + ix];
+ if (ch > 0xff)
+ ch = '?';
+ ((char *)inbuf)[ix] = (char)ch;
+ }
+ } else {
+ for (ix = 0; ix<len; ix++)
+ ((glui32 *)inbuf)[ix] = _chars[_inFence + ix];
+ }
+
+ _attr = _origAttr;
+
+ if (_lineTerminators) {
+ glui32 val2 = keycode;
+ if (val2 == keycode_Return)
+ val2 = 0;
+ g_vm->_events->eventStore(evtype_LineInput, this, len, val2);
+ free(_lineTerminators);
+ _lineTerminators = nullptr;
+ } else {
+ g_vm->_events->eventStore(evtype_LineInput, this, len, 0);
+ }
+
+ _lineRequest = false;
+ _lineRequestUni = false;
+ _inBuf = nullptr;
+ _inMax = 0;
+
+ if (_echoLineInput) {
+ putCharUni('\n');
+ } else {
+ _numChars = _inFence;
+ touch(0);
+ }
+
+ if (g_vm->gli_unregister_arr)
+ (*g_vm->gli_unregister_arr)(inbuf, inmax, unicode ? "&+#!Iu" : "&+#!Cn", inarrayrock);
+}
+
+bool TextBufferWindow::leftquote(glui32 c) {
+ switch (c) {
+ case '(': case '[':
+
+ /* The following are Unicode characters in the "Separator, Space" category. */
+ case 0x0020: case 0x00a0: case 0x1680: case 0x2000:
+ case 0x2001: case 0x2002: case 0x2003: case 0x2004:
+ case 0x2005: case 0x2006: case 0x2007: case 0x2008:
+ case 0x2009: case 0x200a: case 0x202f: case 0x205f:
+ case 0x3000:
+ return true;
+ default:
+ return false;
+ }
+}
+
+void TextBufferWindow::scrollOneLine(bool forced) {
+ _lastSeen++;
+ _scrollMax++;
+
+ if (_scrollMax > _scrollBack - 1
+ || _lastSeen > _scrollBack - 1)
+ scrollResize();
+
+ if (_lastSeen >= _height)
+ _scrollPos++;
+
+ if (_scrollPos > _scrollMax - _height + 1)
+ _scrollPos = _scrollMax - _height + 1;
+ if (_scrollPos < 0)
+ _scrollPos = 0;
+
+ if (forced)
+ _dashed = 0;
+ _spaced = 0;
+
+ _lines[0]._len = _numChars;
+ _lines[0]._newLine = forced;
+
+ for (int i = _scrollBack - 1; i > 0; i--) {
+ memcpy(&_lines[i], &_lines[i - 1], sizeof(TextBufferRow));
+ if (i < _height)
+ touch(i);
+ }
+
+ if (_radjn)
+ _radjn--;
+ if (_radjn == 0)
+ _radjw = 0;
+ if (_ladjn)
+ _ladjn--;
+ if (_ladjn == 0)
+ _ladjw = 0;
+
+ touch(0);
+ _lines[0]._len = 0;
+ _lines[0]._newLine = 0;
+ _lines[0]._lm = _ladjw;
+ _lines[0]._rm = _radjw;
+ _lines[0]._lPic = nullptr;
+ _lines[0]._rPic = nullptr;
+ _lines[0]._lHyper = 0;
+ _lines[0]._rHyper = 0;
+ memset(_chars, ' ', TBLINELEN * 4);
+ memset(_attrs, 0, TBLINELEN * sizeof(Attributes));
+
+ _numChars = 0;
+
+ touchScroll();
+
+}
+
+void TextBufferWindow::scrollResize() {
+ int i;
+
+ _lines.clear();
+ _lines.resize(_scrollBack + SCROLLBACK);
+
+ _chars = _lines[0]._chars;
+ _attrs = _lines[0]._attrs;
+
+ for (i = _scrollBack; i < (_scrollBack + SCROLLBACK); i++)
+ {
+ _lines[i]._dirty = 0;
+ _lines[i]._repaint = 0;
+ _lines[i]._lm = 0;
+ _lines[i]._rm = 0;
+ _lines[i]._lPic = 0;
+ _lines[i]._rPic = 0;
+ _lines[i]._lHyper = 0;
+ _lines[i]._rHyper = 0;
+ _lines[i]._len = 0;
+ _lines[i]._newLine = 0;
+ memset(_lines[i]._chars, ' ', sizeof _lines[i]._chars);
+ memset(_lines[i]._attrs, 0, sizeof _lines[i]._attrs);
+ }
+
+ _scrollBack += SCROLLBACK;
+}
+
+int TextBufferWindow::calcWidth(glui32 *chars, Attributes *attrs, int startchar,
+ int numChars, int spw) {
+ int w = 0;
+ int a, b;
+
+ a = startchar;
+ for (b = startchar; b < numChars; b++) {
+ if (attrs[a] == attrs[b]) {
+ w += stringWidthUni(attrs[a].attrFont(_styles),
+ chars + a, b - a, spw);
+ a = b;
+ }
+ }
+
+ w += stringWidthUni(attrs[a].attrFont(_styles),
+ chars + a, b - a, spw);
+
+ return w;
+}
+
+void TextBufferWindow::copyTextToClipboard(const glui32 *text, size_t len) {
+ // TODO
+}
+
+/*--------------------------------------------------------------------------*/
+
+TextBufferWindow::TextBufferRow::TextBufferRow() : _len(0), _newLine(0), _dirty(false),
+ _repaint(false), _lPic(nullptr), _rPic(nullptr), _lHyper(0), _rHyper(0),
+ _lm(0), _rm(0) {
+ Common::fill(&_chars[0], &_chars[TBLINELEN], 0);
}
} // End of namespace Gargoyle
diff --git a/engines/gargoyle/window_text_buffer.h b/engines/gargoyle/window_text_buffer.h
index ebba2b4502..2a1c1f7748 100644
--- a/engines/gargoyle/window_text_buffer.h
+++ b/engines/gargoyle/window_text_buffer.h
@@ -25,47 +25,72 @@
#include "gargoyle/windows.h"
#include "gargoyle/picture.h"
+#include "gargoyle/speech.h"
namespace Gargoyle {
/**
* Text Buffer window
*/
-class TextBufferWindow : public Window {
+class TextBufferWindow : public Window, Speech {
/**
* 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;
+ glui32 _chars[TBLINELEN];
+ Attributes _attrs[TBLINELEN];
+ 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);
+
+ /**
+ * @remarks Only for input text
+ */
+ void putText(const char *buf, int len, int pos, int oldlen);
+
+ /**
+ * @remarks Only for input text
+ */
void putTextUni(const glui32 *buf, int len, int pos, int oldlen);
- void flowBreak();
+
+ bool flowBreak();
+
+ void acceptLine(glui32 keycode);
+
+ /**
+ * Return true if a following quotation mark should be an opening mark,
+ * false if it should be a closing mark. Opening quotation marks will
+ * appear following an open parenthesis, open square bracket, or
+ * whitespace.
+ */
+ bool leftquote(glui32 c);
/**
* Mark a given text row as modified
*/
void touch(int line);
+
+ void scrollOneLine(bool forced);
+ void scrollResize();
+ int calcWidth(glui32 *chars, Attributes *attrs, int startchar, int numchars, int spw);
+
+ /**
+ * Copy the passed text to the clipboard
+ */
+ void copyTextToClipboard(const glui32 *text, size_t len);
public:
int _width, _height;
int _spaced;
@@ -106,7 +131,7 @@ public:
glui32 *_lineTerminators;
/* style hints and settings */
- WindowStyle styles[style_NUMSTYLES];
+ WindowStyle _styles[style_NUMSTYLES];
/* for copy selection */
glui32 *_copyBuf;
@@ -143,14 +168,14 @@ public:
virtual bool unputCharUni(uint32 ch) override;
/**
- * Move the cursor
+ * Clear the window
*/
- virtual void moveCursor(const Common::Point &newPos) override;
+ virtual void clear() override;
/**
- * Clear the window
+ * Click the window
*/
- virtual void clear() override;
+ virtual void click(const Common::Point &newPos) override;
/**
* Prepare for inputing a line
@@ -176,6 +201,15 @@ public:
* Redraw the window
*/
virtual void redraw() override;
+
+ virtual glui32 imageDraw(glui32 image, glui32 align, bool scaled, glui32 width = 0,
+ glui32 height = 0) override;
+
+ virtual void acceptReadLine(glui32 arg) override;
+
+ virtual void acceptReadChar(glui32 arg) override;
+
+ int acceptScroll(glui32 arg);
};
} // End of namespace Gargoyle
diff --git a/engines/gargoyle/window_text_grid.cpp b/engines/gargoyle/window_text_grid.cpp
index 17bb2221c8..91331d7ff8 100644
--- a/engines/gargoyle/window_text_grid.cpp
+++ b/engines/gargoyle/window_text_grid.cpp
@@ -23,6 +23,7 @@
#include "gargoyle/window_text_grid.h"
#include "gargoyle/conf.h"
#include "gargoyle/gargoyle.h"
+#include "gargoyle/window_mask.h"
namespace Gargoyle {
@@ -203,7 +204,7 @@ void TextGridWindow::click(const Common::Point &newPos) {
}
if (_hyperRequest) {
- glui32 linkval = _windows->getHyperlink(newPos);
+ glui32 linkval = g_vm->_windowMask->getHyperlink(newPos);
if (linkval)
{
g_vm->_events->eventStore(evtype_Hyperlink, this, linkval, 0);
@@ -588,7 +589,7 @@ void TextGridWindow::redraw() {
y = y0 + i * g_conf->_leading;
/* clear any stored hyperlink coordinates */
- _windows->setHyperlink(0, x0, y, x0 + g_conf->_cellW * _width, y + g_conf->_leading);
+ g_vm->_windowMask->putHyperlink(0, x0, y, x0 + g_conf->_cellW * _width, y + g_conf->_leading);
a = 0;
for (b = 0; b < _width; b++) {
@@ -610,7 +611,7 @@ void TextGridWindow::redraw() {
if (link) {
_windows->drawRect(x, y + g_conf->_baseLine + 1, w,
g_conf->_linkStyle, g_conf->_linkColor);
- _windows->setHyperlink(link, x, y, x + w, y + g_conf->_leading);
+ g_vm->_windowMask->putHyperlink(link, x, y, x + w, y + g_conf->_leading);
}
x += w;
a = b;
@@ -634,7 +635,7 @@ void TextGridWindow::redraw() {
if (link) {
_windows->drawRect(x, y + g_conf->_baseLine + 1, w,
g_conf->_linkStyle, g_conf->_linkColor);
- _windows->setHyperlink(link, x, y, x + w, y + g_conf->_leading);
+ g_vm->_windowMask->putHyperlink(link, x, y, x + w, y + g_conf->_leading);
}
}
}
diff --git a/engines/gargoyle/window_text_grid.h b/engines/gargoyle/window_text_grid.h
index 0cf6d5e774..2c5a0a847c 100644
--- a/engines/gargoyle/window_text_grid.h
+++ b/engines/gargoyle/window_text_grid.h
@@ -56,17 +56,10 @@ private:
*/
void touch(int line);
- void acceptReadChar(glui32 arg);
-
/**
* Return or enter, during line input. Ends line input.
*/
void acceptLine(glui32 keycode);
-
- /**
- * Any regular key, during line input.
- */
- void acceptReadLine(glui32 arg);
public:
int _width, _height;
TextGridRows _lines;
@@ -158,6 +151,10 @@ public:
* Redraw the window
*/
virtual void redraw() override;
+
+ virtual void acceptReadLine(glui32 arg) override;
+
+ virtual void acceptReadChar(glui32 arg) override;
};
} // End of namespace Gargoyle
diff --git a/engines/gargoyle/windows.cpp b/engines/gargoyle/windows.cpp
index cf9b7de77d..c1c28e5123 100644
--- a/engines/gargoyle/windows.cpp
+++ b/engines/gargoyle/windows.cpp
@@ -37,6 +37,8 @@ bool Windows::_overrideReverse;
bool Windows::_overrideFgSet;
bool Windows::_overrideBgSet;
bool Windows::_forceRedraw;
+bool Windows::_claimSelect;
+bool Windows::_moreFocus;
int Windows::_overrideFgVal;
int Windows::_overrideBgVal;
int Windows::_zcolor_fg;
@@ -48,14 +50,15 @@ byte Windows::_zcolor_Bright[3];
/*--------------------------------------------------------------------------*/
-Windows::Windows(Graphics::Screen *screen) :
- _screen(screen), _moreFocus(false), _windowList(nullptr),
- _rootWin(nullptr), _focusWin(nullptr), _mask(nullptr), _claimSelect(0) {
+Windows::Windows(Graphics::Screen *screen) : _screen(screen), _windowList(nullptr),
+ _rootWin(nullptr), _focusWin(nullptr), _mask(nullptr) {
_mask = new WindowMask();
_overrideReverse = false;
_overrideFgSet = false;
_overrideBgSet = false;
_forceRedraw = true;
+ _claimSelect = false;
+ _moreFocus = false;
_overrideFgVal = 0;
_overrideBgVal = 0;
_zcolor_fg = _zcolor_bg = 0;
@@ -234,6 +237,10 @@ void Windows::redraw() {
// TODO: gli_windows_redraw
}
+void Windows::redrawRect(const Common::Rect &r) {
+ // TODO: gli_redraw_rect
+}
+
void Windows::repaint(const Common::Rect &box) {
// TODO
}
@@ -291,7 +298,7 @@ Window::Window(Windows *windows, glui32 rock) : _windows(windows), _rock(rock),
_type(0), _parent(nullptr), _next(nullptr), _prev(nullptr), _yAdj(0),
_lineRequest(0), _lineRequestUni(0), _charRequest(0), _charRequestUni(0),
_mouseRequest(0), _hyperRequest(0), _moreRequest(0), _scrollRequest(0), _imageLoaded(0),
- _echoLineInput(true), _lineTerminatorsBase(nullptr), _termCt(0), _echoStream(nullptr) {
+ _echoLineInputBase(true), _lineTerminatorsBase(nullptr), _termCt(0), _echoStream(nullptr) {
_attr.fgset = 0;
_attr.bgset = 0;
_attr.reverse = 0;
@@ -337,6 +344,10 @@ void Window::cancelLineEvent(Event *ev) {
g_vm->_events->clearEvent(ev);
}
+void Window::moveCursor(const Common::Point &newPos) {
+ warning("moveCursor: not a TextGrid window");
+}
+
void Window::requestLineEvent(char *buf, glui32 maxlen, glui32 initlen) {
warning("requestLineEvent: window does not support keyboard input");
}
@@ -353,6 +364,14 @@ void Window::redraw() {
}
}
+void Window::acceptReadLine(glui32 arg) {
+ warning("acceptReadLine:: window does not support keyboard input");
+}
+
+void Window::acceptReadChar(glui32 arg) {
+ warning("acceptReadChar:: window does not support keyboard input");
+}
+
bool Window::checkTerminator(glui32 ch) {
if (ch == keycode_Escape)
return true;
diff --git a/engines/gargoyle/windows.h b/engines/gargoyle/windows.h
index 5e6374c340..3f5c0bc274 100644
--- a/engines/gargoyle/windows.h
+++ b/engines/gargoyle/windows.h
@@ -85,8 +85,6 @@ private:
Window * _windowList; ///< List of all windows
Window *_rootWin; ///< The topmost window
Window *_focusWin; ///< The window selected by the player
- bool _moreFocus;
- bool _claimSelect;
WindowMask *_mask;
private:
/**
@@ -108,6 +106,8 @@ public:
static bool _overrideFgSet;
static bool _overrideBgSet;
static bool _forceRedraw;
+ static bool _claimSelect;
+ static bool _moreFocus;
static int _overrideFgVal;
static int _overrideBgVal;
static int _zcolor_fg, _zcolor_bg;
@@ -157,6 +157,8 @@ public:
void redraw();
+ void redrawRect(const Common::Rect &r);
+
/**
* Repaint an area of the windows
*/
@@ -176,18 +178,6 @@ public:
* Returns the end point of window iteration
*/
iterator end() { return iterator(nullptr); }
-
- /**
- * Gets a hyperlink
- */
- glui32 getHyperlink(const Common::Point &pos) { return _mask->getHyperlink(pos); }
-
- /**
- * Sets a hyperlink
- */
- void setHyperlink(glui32 linkval, uint x0, uint y0, uint x1, uint y1) {
- return _mask->putHyperlink(linkval, x0, y0, x1, y1);
- }
};
/**
@@ -278,7 +268,7 @@ public:
int _scrollRequest;
int _imageLoaded;
- glui32 _echoLineInput;
+ glui32 _echoLineInputBase;
glui32 *_lineTerminatorsBase;
glui32 _termCt;
@@ -323,7 +313,7 @@ public:
/**
* Move the cursor
*/
- virtual void moveCursor(const Common::Point &newPos) {}
+ virtual void moveCursor(const Common::Point &newPos);
/**
* Clear the window
@@ -364,6 +354,15 @@ public:
* Redraw the window
*/
virtual void redraw();
+
+ virtual glui32 imageDraw(glui32 image, glui32 align, bool scaled, glui32 width = 0,
+ glui32 height = 0) { return false; }
+
+ virtual void acceptReadLine(glui32 arg);
+
+ virtual void acceptReadChar(glui32 arg);
+
+ int acceptScroll(glui32 arg);
};
typedef Window *winid_t;