aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Gilbert2018-10-21 10:53:32 -0700
committerPaul Gilbert2018-12-08 19:05:59 -0800
commitcc54beadce8852c29be883e957fbfe5f548f8946 (patch)
tree84374d2295d7f1bd8c344874a377156fa93d710b
parentd314cd39ee42c2b37fde0fa9d384fae67683cbea (diff)
downloadscummvm-rg350-cc54beadce8852c29be883e957fbfe5f548f8946.tar.gz
scummvm-rg350-cc54beadce8852c29be883e957fbfe5f548f8946.tar.bz2
scummvm-rg350-cc54beadce8852c29be883e957fbfe5f548f8946.zip
GLK: Start of window character output
-rw-r--r--engines/gargoyle/conf.cpp9
-rw-r--r--engines/gargoyle/conf.h14
-rw-r--r--engines/gargoyle/events.cpp4
-rw-r--r--engines/gargoyle/events.h85
-rw-r--r--engines/gargoyle/gargoyle.cpp7
-rw-r--r--engines/gargoyle/gargoyle.h2
-rw-r--r--engines/gargoyle/glk.cpp32
-rw-r--r--engines/gargoyle/glk_types.h54
-rw-r--r--engines/gargoyle/streams.cpp87
-rw-r--r--engines/gargoyle/streams.h78
-rw-r--r--engines/gargoyle/windows.cpp277
-rw-r--r--engines/gargoyle/windows.h163
12 files changed, 578 insertions, 234 deletions
diff --git a/engines/gargoyle/conf.cpp b/engines/gargoyle/conf.cpp
index 4e8b823dab..125e9f4c67 100644
--- a/engines/gargoyle/conf.cpp
+++ b/engines/gargoyle/conf.cpp
@@ -139,12 +139,13 @@ Conf::Conf() {
get("dashes", _dashes, 1);
get("spaces", _spaces);
get("caps", _caps);
- get("graphics", _graphics, 1);
- get("sound", _sound, 1);
+ get("graphics", _graphics, true);
+ get("sound", _sound, true);
get("speak", _speak);
get("speak_input", _speakInput);
get("speak_language", _speakLanguage);
get("stylehint", _styleHint, 1);
+ get("safeclicks", _safeClicks);
Common::copy(T_STYLES, T_STYLES + style_NUMSTYLES, _tStyles);
Common::copy(G_STYLES, G_STYLES + style_NUMSTYLES, _gStyles);
@@ -216,6 +217,10 @@ void Conf::get(const Common::String &key, int &field, int defaultVal) {
field = ConfMan.hasKey(key) ? strToInt(ConfMan.get(key).c_str()) : defaultVal;
}
+void Conf::get(const Common::String &key, bool &field, bool defaultVal) {
+ field = ConfMan.hasKey(key) ? strToInt(ConfMan.get(key).c_str()) != 0 : defaultVal;
+}
+
void Conf::get(const Common::String &key, FACES &field, FACES defaultFont) {
field = ConfMan.hasKey(key) ? Fonts::getId(ConfMan.get(key)) : defaultFont;
}
diff --git a/engines/gargoyle/conf.h b/engines/gargoyle/conf.h
index 5c4446a5a4..05dc6c9b46 100644
--- a/engines/gargoyle/conf.h
+++ b/engines/gargoyle/conf.h
@@ -52,6 +52,11 @@ private:
void get(const Common::String &key, int &field, int defaultVal = 0);
/**
+ * Get a numeric value
+ */
+ void get(const Common::String &key, bool &field, bool defaultVal = false);
+
+ /**
* Get a double
*/
void get(const Common::String &key, double &field, double defaultVal = 0.0);
@@ -103,12 +108,13 @@ public:
int _dashes;
int _spaces;
int _caps;
- int _graphics;
- int _sound;
- int _speak;
- int _speakInput;
+ bool _graphics;
+ bool _sound;
+ bool _speak;
+ bool _speakInput;
Common::String _speakLanguage;
int _styleHint;
+ bool _safeClicks;
WindowStyle _tStyles[style_NUMSTYLES];
WindowStyle _gStyles[style_NUMSTYLES];
WindowStyle _tStylesDefault[style_NUMSTYLES];
diff --git a/engines/gargoyle/events.cpp b/engines/gargoyle/events.cpp
index 93021efb4a..1f7cc6a236 100644
--- a/engines/gargoyle/events.cpp
+++ b/engines/gargoyle/events.cpp
@@ -28,4 +28,8 @@ void Events::pollEvents() {
// TODO
}
+void Events::clearEvent(Event *ev) {
+ // TODO
+}
+
} // End of namespace Gargoyle
diff --git a/engines/gargoyle/events.h b/engines/gargoyle/events.h
index ac66d0e3c9..476be40181 100644
--- a/engines/gargoyle/events.h
+++ b/engines/gargoyle/events.h
@@ -27,12 +27,97 @@
namespace Gargoyle {
+class Window;
+
+/**
+ * Event types
+ */
+enum EvType {
+ evtype_None = 0,
+ evtype_Timer = 1,
+ evtype_CharInput = 2,
+ evtype_LineInput = 3,
+ evtype_MouseInput = 4,
+ evtype_Arrange = 5,
+ evtype_Redraw = 6,
+ evtype_SoundNotify = 7,
+ evtype_Hyperlink = 8,
+ evtype_VolumeNotify = 9,
+
+ // ScummVM custom events
+ evtype_Quit = 99
+};
+
+/**
+ * Keycodes
+ */
+enum Keycode {
+ keycode_Unknown = 0xffffffffU,
+ keycode_Left = 0xfffffffeU,
+ keycode_Right = 0xfffffffdU,
+ keycode_Up = 0xfffffffcU,
+ keycode_Down = 0xfffffffbU,
+ keycode_Return = 0xfffffffaU,
+ keycode_Delete = 0xfffffff9U,
+ keycode_Escape = 0xfffffff8U,
+ keycode_Tab = 0xfffffff7U,
+ keycode_PageUp = 0xfffffff6U,
+ keycode_PageDown = 0xfffffff5U,
+ keycode_Home = 0xfffffff4U,
+ keycode_End = 0xfffffff3U,
+ keycode_Func1 = 0xffffffefU,
+ keycode_Func2 = 0xffffffeeU,
+ keycode_Func3 = 0xffffffedU,
+ keycode_Func4 = 0xffffffecU,
+ keycode_Func5 = 0xffffffebU,
+ keycode_Func6 = 0xffffffeaU,
+ keycode_Func7 = 0xffffffe9U,
+ keycode_Func8 = 0xffffffe8U,
+ keycode_Func9 = 0xffffffe7U,
+ keycode_Func10 = 0xffffffe6U,
+ keycode_Func11 = 0xffffffe5U,
+ keycode_Func12 = 0xffffffe4U,
+
+ // non standard keycodes
+ keycode_Erase = 0xffffef7fU,
+ keycode_MouseWheelUp = 0xffffeffeU,
+ keycode_MouseWheelDown = 0xffffefffU,
+ keycode_SkipWordLeft = 0xfffff000U,
+ keycode_SkipWordRight = 0xfffff001U,
+
+ // The last keycode is always = 0x100000000 - keycode_MAXVAL)
+ keycode_MAXVAL = 28U
+};
+
+/**
+ * Event structure
+ */
+struct Event {
+ EvType _type;
+ Window *_window;
+ uint32 _val1, _val2;
+
+ /**
+ * Constructor
+ */
+ Event() : _type(evtype_None), _window(nullptr), _val1(0), _val2(0) {}
+};
+
class Events {
public:
+ bool _forceClick;
+public:
+ /**
+ * Constructor
+ */
+ Events() : _forceClick(false) {}
+
/**
* Checks for new events
*/
void pollEvents();
+
+ void clearEvent(Event *ev);
};
} // End of namespace Gargoyle
diff --git a/engines/gargoyle/gargoyle.cpp b/engines/gargoyle/gargoyle.cpp
index a7b819c6b6..2ca14bf897 100644
--- a/engines/gargoyle/gargoyle.cpp
+++ b/engines/gargoyle/gargoyle.cpp
@@ -36,9 +36,12 @@
namespace Gargoyle {
+GargoyleEngine *g_vm;
+
GargoyleEngine::GargoyleEngine(OSystem *syst, const GargoyleGameDescription *gameDesc) :
_gameDescription(gameDesc), Engine(syst), _random("Gargoyle"), _conf(nullptr),
_events(nullptr), _screen(nullptr), _windows(nullptr) {
+ g_vm = this;
}
GargoyleEngine::~GargoyleEngine() {
@@ -60,8 +63,8 @@ void GargoyleEngine::initialize() {
_screen = new Graphics::Screen();
_conf = new Conf();
_events = new Events();
- _streams = new Streams(this);
- _windows = new Windows(this, _screen);
+ _streams = new Streams();
+ _windows = new Windows(_screen);
}
Common::Error GargoyleEngine::run() {
diff --git a/engines/gargoyle/gargoyle.h b/engines/gargoyle/gargoyle.h
index 39799d7b60..976221ab56 100644
--- a/engines/gargoyle/gargoyle.h
+++ b/engines/gargoyle/gargoyle.h
@@ -125,6 +125,8 @@ public:
const Common::String &GargoyleEngine::getFilename() const;
};
+extern GargoyleEngine *g_vm;
+
} // End of namespace Gargoyle
#endif
diff --git a/engines/gargoyle/glk.cpp b/engines/gargoyle/glk.cpp
index e81e806ac5..ba62de1573 100644
--- a/engines/gargoyle/glk.cpp
+++ b/engines/gargoyle/glk.cpp
@@ -187,11 +187,15 @@ strid_t Glk::glk_stream_get_current(void) {
}
void Glk::glk_put_char(unsigned char ch) {
- // TODO
+ _streams->getCurrent()->putChar(ch);
}
void Glk::glk_put_char_stream(strid_t str, unsigned char ch) {
- // TODO
+ if (str) {
+ str->putChar(ch);
+ } else {
+ warning("put_char_stream: invalid ref");
+ }
}
void Glk::glk_put_string(const char *s) {
@@ -375,27 +379,39 @@ glui32 Glk::glk_buffer_to_title_case_uni(glui32 *buf, glui32 len,
}
void Glk::glk_put_char_uni(glui32 ch) {
- glk_put_char_stream_uni(_streams->getCurrent(), ch);
+ _streams->getCurrent()->putCharUni(ch);
}
void Glk::glk_put_string_uni(glui32 *s) {
- glk_put_buffer_stream_uni(_streams->getCurrent(), s, strlen_uni(s));
+ _streams->getCurrent()->putBufferUni(s, strlen_uni(s));
}
void Glk::glk_put_buffer_uni(glui32 *buf, glui32 len) {
- glk_put_buffer_stream_uni(_streams->getCurrent(), buf, len);
+ _streams->getCurrent()->putBufferUni(buf, len);
}
void Glk::glk_put_char_stream_uni(strid_t str, glui32 ch) {
-// str->writeUint32LE(ch);
+ if (str) {
+ str->putCharUni(ch);
+ } else {
+ warning("put_char_stream_uni: invalid ref");
+ }
}
void Glk::glk_put_string_stream_uni(strid_t str, const glui32 *s) {
- glk_put_buffer_stream_uni(str, s, strlen_uni(s));
+ if (str) {
+ str->putBufferUni(s, strlen_uni(s));
+ } else {
+ warning("put_string_stream_uni: invalid ref");
+ }
}
void Glk::glk_put_buffer_stream_uni(strid_t str, const glui32 *buf, glui32 len) {
-// while (len-- > 0) str->writeUint32LE(*buf++);
+ if (str) {
+ str->putBufferUni(buf, len);
+ } else {
+ warning("put_buffer_stream_uni: invalid ref");
+ }
}
glsi32 Glk::glk_get_char_stream_uni(strid_t str) {
diff --git a/engines/gargoyle/glk_types.h b/engines/gargoyle/glk_types.h
index b6f0d290f1..8f84cbe6a6 100644
--- a/engines/gargoyle/glk_types.h
+++ b/engines/gargoyle/glk_types.h
@@ -82,60 +82,6 @@ enum Gestalt {
gestalt_GarglkText = 0x1100,
};
-enum EvType {
- evtype_None = 0,
- evtype_Timer = 1,
- evtype_CharInput = 2,
- evtype_LineInput = 3,
- evtype_MouseInput = 4,
- evtype_Arrange = 5,
- evtype_Redraw = 6,
- evtype_SoundNotify = 7,
- evtype_Hyperlink = 8,
- evtype_VolumeNotify = 9,
-
- // ScummVM custom events
- evtype_Quit = 99
-};
-
-enum Keycode {
- keycode_Unknown = 0xffffffffU,
- keycode_Left = 0xfffffffeU,
- keycode_Right = 0xfffffffdU,
- keycode_Up = 0xfffffffcU,
- keycode_Down = 0xfffffffbU,
- keycode_Return = 0xfffffffaU,
- keycode_Delete = 0xfffffff9U,
- keycode_Escape = 0xfffffff8U,
- keycode_Tab = 0xfffffff7U,
- keycode_PageUp = 0xfffffff6U,
- keycode_PageDown = 0xfffffff5U,
- keycode_Home = 0xfffffff4U,
- keycode_End = 0xfffffff3U,
- keycode_Func1 = 0xffffffefU,
- keycode_Func2 = 0xffffffeeU,
- keycode_Func3 = 0xffffffedU,
- keycode_Func4 = 0xffffffecU,
- keycode_Func5 = 0xffffffebU,
- keycode_Func6 = 0xffffffeaU,
- keycode_Func7 = 0xffffffe9U,
- keycode_Func8 = 0xffffffe8U,
- keycode_Func9 = 0xffffffe7U,
- keycode_Func10 = 0xffffffe6U,
- keycode_Func11 = 0xffffffe5U,
- keycode_Func12 = 0xffffffe4U,
-
- // non standard keycodes
- keycode_Erase = 0xffffef7fU,
- keycode_MouseWheelUp = 0xffffeffeU,
- keycode_MouseWheelDown = 0xffffefffU,
- keycode_SkipWordLeft = 0xfffff000U,
- keycode_SkipWordRight = 0xfffff001U,
-
- // The last keycode is always = 0x100000000 - keycode_MAXVAL)
- keycode_MAXVAL = 28U
-};
-
enum Style {
style_Normal = 0,
style_Emphasized = 1,
diff --git a/engines/gargoyle/streams.cpp b/engines/gargoyle/streams.cpp
index 382ce287cf..b505405997 100644
--- a/engines/gargoyle/streams.cpp
+++ b/engines/gargoyle/streams.cpp
@@ -21,6 +21,9 @@
*/
#include "gargoyle/streams.h"
+#include "gargoyle/conf.h"
+#include "gargoyle/events.h"
+#include "gargoyle/gargoyle.h"
#include "gargoyle/windows.h"
namespace Gargoyle {
@@ -62,12 +65,46 @@ void WindowStream::close(StreamResult *result) {
warning("cannot close window stream");
}
-void WindowStream::writeChar(unsigned char ch) {
+void WindowStream::putChar(unsigned char ch) {
+ if (!_writable)
+ return;
+ ++_writeCount;
+ if (_window->line_request || _window->line_request_uni) {
+ if (g_conf->_safeClicks && g_vm->_events->_forceClick) {
+ _window->cancelLineEvent(nullptr);
+ g_vm->_events->_forceClick = false;
+ } else {
+ warning("putChar: window has pending line request");
+ }
+ }
+
+ _window->putChar(ch);
+ if (_window->_echoStream)
+ _window->_echoStream->putChar(ch);
}
-void WindowStream::writeCharUni(uint32 ch) {
+void WindowStream::putCharUni(uint32 ch) {
+ if (!_writable)
+ return;
+ ++_writeCount;
+
+ //TODO
+}
+
+void WindowStream::putBuffer(const unsigned char *buf, size_t len) {
+ if (!_writable)
+ return;
+ ++_writeCount;
+ //TODO
+
+}
+void WindowStream::putBufferUni(const uint32 *buf, size_t len) {
+ if (!_writable)
+ return;
+ ++_writeCount;
+ //TODO
}
/*--------------------------------------------------------------------------*/
@@ -85,26 +122,56 @@ MemoryStream::MemoryStream(Streams *streams, void *buf, size_t buflen, FileMode
_bufeof = mode == filemode_Write ? _buf : _bufend;
}
-void MemoryStream::writeChar(unsigned char ch) {
+void MemoryStream::putChar(unsigned char ch) {
+ //TODO
}
-void MemoryStream::writeCharUni(uint32 ch) {
+void MemoryStream::putCharUni(uint32 ch) {
+ //TODO
}
-/*--------------------------------------------------------------------------*/
+void MemoryStream::putBuffer(const unsigned char *buf, size_t len) {
+ //TODO
+
+}
+
+void MemoryStream::putBufferUni(const uint32 *buf, size_t len) {
+ //TODO
+
+}
/*--------------------------------------------------------------------------*/
+FileStream::FileStream(Streams *streams, uint32 rock, bool unicode) :
+ Stream(streams, true, false, rock, unicode) {
+}
+
+void FileStream::putChar(unsigned char ch) {
+ //TODO
+}
+
+void FileStream::putCharUni(uint32 ch) {
+ //TODO
+}
+
+void FileStream::putBuffer(const unsigned char *buf, size_t len) {
+ //TODO
+}
+
+void FileStream::putBufferUni(const uint32 *buf, size_t len) {
+ //TODO
+}
+
/*--------------------------------------------------------------------------*/
-Streams::Streams(GargoyleEngine *engine) : _engine(engine), _streamList(nullptr), _currentStream(nullptr) {
+Streams::Streams() : _streamList(nullptr), _currentStream(nullptr) {
}
Streams::~Streams() {
while (_streamList)
- deleteStream(_streamList);
+ delete _streamList;
}
WindowStream *Streams::addWindowStream(Window *window) {
@@ -136,6 +203,12 @@ void Streams::removeStream(Stream *stream) {
_streamList = next;
if (next)
next->_prev = prev;
+
+ // Remove the stream as the echo stream of any window
+ for (Windows::iterator i = g_vm->_windows->begin(); i != g_vm->_windows->end(); ++i) {
+ if ((*i)->_echoStream == stream)
+ (*i)->_echoStream = nullptr;
+ }
}
Stream *Streams::getFirst(uint32 *rock) {
diff --git a/engines/gargoyle/streams.h b/engines/gargoyle/streams.h
index e45bcc491a..c43e2a089c 100644
--- a/engines/gargoyle/streams.h
+++ b/engines/gargoyle/streams.h
@@ -28,7 +28,6 @@
namespace Gargoyle {
-class GargoyleEngine;
class Window;
class Streams;
@@ -84,12 +83,22 @@ public:
/**
* Write a character
*/
- virtual void writeChar(unsigned char ch) = 0;
+ virtual void putChar(unsigned char ch) = 0;
/**
* Write a unicode character
*/
- virtual void writeCharUni(uint32 ch) = 0;
+ virtual void putCharUni(uint32 ch) = 0;
+
+ /**
+ * Write a buffer
+ */
+ virtual void putBuffer(const unsigned char *buf, size_t len) = 0;
+
+ /**
+ * Write a unicode character
+ */
+ virtual void putBufferUni(const uint32 *buf, size_t len) = 0;
};
typedef Stream *strid_t;
@@ -114,12 +123,22 @@ public:
/**
* Write a character
*/
- virtual void writeChar(unsigned char ch) override;
+ virtual void putChar(unsigned char ch) override;
/**
* Write a unicode character
*/
- virtual void writeCharUni(uint32 ch) override;
+ virtual void putCharUni(uint32 ch) override;
+
+ /**
+ * Write a buffer
+ */
+ virtual void putBuffer(const unsigned char *buf, size_t len) override;
+
+ /**
+ * Write a unicode character
+ */
+ virtual void putBufferUni(const uint32 *buf, size_t len) override;
};
/**
@@ -141,12 +160,54 @@ public:
/**
* Write a character
*/
- virtual void writeChar(unsigned char ch);
+ virtual void putChar(unsigned char ch) override;
+
+ /**
+ * Write a unicode character
+ */
+ virtual void putCharUni(uint32 ch) override;
+
+ /**
+ * Write a buffer
+ */
+ virtual void putBuffer(const unsigned char *buf, size_t len) override;
+
+ /**
+ * Write a unicode character
+ */
+ virtual void putBufferUni(const uint32 *buf, size_t len) override;
+};
+
+/**
+ * Implements a file stream
+ */
+class FileStream : public Stream {
+private:
+public:
+ /**
+ * Constructor
+ */
+ FileStream(Streams *streams, uint32 rock = 0, bool unicode = true);
+
+ /**
+ * Write a character
+ */
+ virtual void putChar(unsigned char ch) override;
+
+ /**
+ * Write a unicode character
+ */
+ virtual void putCharUni(uint32 ch) override;
+
+ /**
+ * Write a buffer
+ */
+ virtual void putBuffer(const unsigned char *buf, size_t len) override;
/**
* Write a unicode character
*/
- virtual void writeCharUni(uint32 ch);
+ virtual void putBufferUni(const uint32 *buf, size_t len) override;
};
/**
@@ -155,7 +216,6 @@ public:
class Streams {
friend class Stream;
private:
- GargoyleEngine *_engine;
Stream *_streamList;
Stream *_currentStream;
private:
@@ -172,7 +232,7 @@ public:
/**
* Constructor
*/
- Streams(GargoyleEngine *engine);
+ Streams();
/**
* Destructor
diff --git a/engines/gargoyle/windows.cpp b/engines/gargoyle/windows.cpp
index e39e5422ab..3212964715 100644
--- a/engines/gargoyle/windows.cpp
+++ b/engines/gargoyle/windows.cpp
@@ -38,13 +38,46 @@ bool Windows::_overrideBgSet;
int Windows::_overrideFgVal;
int Windows::_overrideBgVal;
+/*--------------------------------------------------------------------------*/
+
+Windows::iterator &Windows::iterator::operator++() {
+ if (!_current)
+ return *this;
+
+ PairWindow *pairWin = dynamic_cast<PairWindow *>(_current);
+
+ if (pairWin) {
+ _current = !pairWin->_backward ? pairWin->_child1 : pairWin->_child2;
+ } else {
+ while (_current->_parent) {
+ pairWin = dynamic_cast<PairWindow *>(_current->_parent);
+
+ if (!pairWin->_backward) {
+ if (_current == pairWin->_child1) {
+ _current = pairWin->_child2;
+ return *this;
+ }
+ } else {
+ if (_current == pairWin->_child2) {
+ _current = pairWin->_child1;
+ return *this;
+ }
+ }
+
+ _current = pairWin;
+ }
+
+ _current = nullptr;
+ }
+
+ return *this;
+}
/*--------------------------------------------------------------------------*/
-Windows::Windows(GargoyleEngine *engine, Graphics::Screen *screen) :
- _engine(engine), _screen(screen), _forceRedraw(true), _moreFocus(false),
- _windowList(nullptr), _rootWin(nullptr), _focusWin(nullptr), _mask(nullptr),
- _claimSelect(0) {
+Windows::Windows(Graphics::Screen *screen) :
+ _screen(screen), _forceRedraw(true), _moreFocus(false), _windowList(nullptr),
+ _rootWin(nullptr), _focusWin(nullptr), _mask(nullptr), _claimSelect(0) {
_overrideReverse = false;
_overrideFgSet = false;
_overrideBgSet = false;
@@ -89,7 +122,7 @@ Window *Windows::windowOpen(Window *splitwin, glui32 method, glui32 size,
return nullptr;
}
- oldparent = splitwin->parent;
+ oldparent = splitwin->_parent;
if (oldparent && oldparent->_type != wintype_Pair)
{
warning("window_open: parent window is not Pair");
@@ -112,9 +145,9 @@ Window *Windows::windowOpen(Window *splitwin, glui32 method, glui32 size,
pairwin->_child1 = splitwin;
pairwin->_child2 = newwin;
- splitwin->parent = pairwin;
- newwin->parent = pairwin;
- pairwin->parent = oldparent;
+ splitwin->_parent = pairwin;
+ newwin->_parent = pairwin;
+ pairwin->_parent = oldparent;
if (oldparent) {
PairWindow *parentWin = dynamic_cast<PairWindow *>(oldparent);
@@ -155,20 +188,20 @@ Window *Windows::newWindow(glui32 type, glui32 rock) {
error("Unknown window type");
}
- win->next = _windowList;
+ win->_next = _windowList;
_windowList = win;
- if (win->next)
- win->next->prev = win;
+ if (win->_next)
+ win->_next->_prev = win;
return win;
}
PairWindow *Windows::newPairWindow(glui32 method, Window *key, glui32 size) {
PairWindow *pwin = new PairWindow(this, method, key, size);
- pwin->next = _windowList;
+ pwin->_next = _windowList;
_windowList = pwin;
- if (pwin->next)
- pwin->next->prev = pwin;
+ if (pwin->_next)
+ pwin->_next->_prev = pwin;
return pwin;
}
@@ -223,7 +256,7 @@ void Windows::repaint(const Common::Rect &box) {
/*--------------------------------------------------------------------------*/
Window::Window(Windows *windows, glui32 rock) : _magicnum(MAGIC_WINDOW_NUM),
- _windows(windows), _rock(rock), _type(0), parent(nullptr), next(nullptr), prev(nullptr),
+ _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), _echoStream(nullptr) {
@@ -239,10 +272,18 @@ Window::Window(Windows *windows, glui32 rock) : _magicnum(MAGIC_WINDOW_NUM),
Common::fill(&fgcolor[0], &fgcolor[3], 3);
disprock.num = 0;
- Streams &streams = *windows->_engine->_streams;
+ Streams &streams = *g_vm->_streams;
_stream = streams.addWindowStream(this);
}
+void Window::cancelLineEvent(Event *ev) {
+ Event dummyEv;
+ if (!ev)
+ ev = &dummyEv;
+
+ g_vm->_events->clearEvent(ev);
+}
+
/*--------------------------------------------------------------------------*/
BlankWindow::BlankWindow(Windows *windows, uint32 rock) : Window(windows, rock) {
@@ -253,14 +294,14 @@ BlankWindow::BlankWindow(Windows *windows, uint32 rock) : Window(windows, rock)
TextGridWindow::TextGridWindow(Windows *windows, uint32 rock) : Window(windows, rock) {
_type = wintype_TextGrid;
- width = height = 0;
- curx = cury = 0;
- inbuf = nullptr;
- inorgx = inorgy = 0;
- inmax = 0;
- incurs = inlen = 0;
- inarrayrock.num = 0;
- line_terminators = nullptr;
+ _width = _height = 0;
+ _curX = _curY = 0;
+ _inBuf = nullptr;
+ _inorgX = _inorgY = 0;
+ _inMax = 0;
+ _inCurs = _inLen = 0;
+ _inArrayRock.num = 0;
+ _lineTerminators = nullptr;
Common::copy(&g_conf->_gStyles[0], &g_conf->_gStyles[style_NUMSTYLES], styles);
}
@@ -272,7 +313,7 @@ void TextGridWindow::rearrange(const Common::Rect &box) {
newwid = box.width() / g_conf->_cellW;
newhgt = box.height() / g_conf->_cellH;
- if (newwid == width && newhgt == height)
+ if (newwid == _width && newhgt == _height)
return;
lines.resize(newhgt);
@@ -282,8 +323,8 @@ void TextGridWindow::rearrange(const Common::Rect &box) {
}
attr.clear();
- width = newwid;
- height = newhgt;
+ _width = newwid;
+ _height = newhgt;
}
void TextGridWindow::touch(int line) {
@@ -297,6 +338,21 @@ glui32 TextGridWindow::getSplit(glui32 size, bool vertical) const {
size * g_conf->_cellH + g_conf->_tMarginY * 2;
}
+void TextGridWindow::cancelLineEvent(Event *ev) {
+ Event dummyEv;
+
+ if (!ev)
+ ev = &dummyEv;
+
+ g_vm->_events->clearEvent(ev);
+
+ if (!line_request && !line_request_uni)
+ return;
+
+
+ // TODO : textgrid_cancel_line
+}
+
/*--------------------------------------------------------------------------*/
void TextGridWindow::TextGridRow::resize(size_t newSize) {
@@ -310,13 +366,13 @@ void TextGridWindow::TextGridRow::resize(size_t newSize) {
/*--------------------------------------------------------------------------*/
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) {
+ _historyPos(0), _historyFirst(0), _historyPresent(0), _lastSeen(0), _scrollPos(0),
+ _scrollMax(0), _scrollBack(SCROLLBACK), _width(-1), _height(-1), _inBuf(nullptr),
+ _lineTerminators(nullptr), _echoLineInput(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::fill(&_history[0], &_history[HISTORYLEN], nullptr);
Common::copy(&g_conf->_tStyles[0], &g_conf->_tStyles[style_NUMSTYLES], styles);
}
@@ -334,31 +390,31 @@ void TextBufferWindow::rearrange(const Common::Rect &box) {
yadj = (box.height() - rnd);
bbox.top += (box.height() - rnd);
- if (newwid != width) {
- width = newwid;
+ if (newwid != _width) {
+ _width = newwid;
reflow();
}
- if (newhgt != height) {
+ if (newhgt != _height) {
/* scroll up if we obscure new lines */
- if (lastseen >= newhgt - 1)
- scrollpos += (height - newhgt);
+ if (_lastSeen >= newhgt - 1)
+ _scrollPos += (_height - newhgt);
- height = newhgt;
+ _height = newhgt;
/* keep window within 'valid' lines */
- if (scrollpos > scrollmax - height + 1)
- scrollpos = scrollmax - height + 1;
- if (scrollpos < 0)
- scrollpos = 0;
+ 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];
+ copybuf = new glui32[_height * TBLINELEN];
- for (int i = 0; i < (height * TBLINELEN); i++)
+ for (int i = 0; i < (_height * TBLINELEN); i++)
copybuf[i] = 0;
copypos = 0;
@@ -371,10 +427,10 @@ void TextBufferWindow::reflow() {
int i, k, p, s;
int x;
- if (height < 4 || width < 20)
+ if (_height < 4 || _width < 20)
return;
- lines[0].len = numchars;
+ _lines[0].len = _numChars;
/* allocate temp buffers */
Attributes *attrbuf = new Attributes[SCROLLBACK * TBLINELEN];
@@ -401,38 +457,38 @@ void TextBufferWindow::reflow() {
x = 0;
p = 0;
- s = scrollmax < SCROLLBACK ? scrollmax : SCROLLBACK - 1;
+ s = _scrollMax < SCROLLBACK ? _scrollMax : SCROLLBACK - 1;
for (k = s; k >= 0; k--) {
if (k == 0 && line_request)
- inputbyte = p + infence;
+ 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].attr[i];
+ charbuf[p] = _lines[k].chars[i];
p++;
}
- if (lines[k].newline) {
+ if (_lines[k].newline) {
attrbuf[p] = curattr;
charbuf[p] = '\n';
p++;
@@ -462,13 +518,13 @@ void TextBufferWindow::reflow() {
}
/* terribly sorry about this... */
- lastseen = 0;
- scrollpos = 0;
+ _lastSeen = 0;
+ _scrollPos = 0;
if (inputbyte != -1) {
- infence = numchars;
- putTextUnit(charbuf + inputbyte, p - inputbyte, numchars, 0);
- incurs = numchars;
+ _inFence = _numChars;
+ putTextUnit(charbuf + inputbyte, p - inputbyte, _numChars, 0);
+ _inCurs = _numChars;
}
// free temp buffers
@@ -488,8 +544,8 @@ void TextBufferWindow::touchScroll() {
_windows->clearSelection();
_windows->repaint(bbox);
- for (int i = 0; i < scrollmax; i++)
- lines[i].dirty = true;
+ for (int i = 0; i < _scrollMax; i++)
+ _lines[i].dirty = true;
}
void TextBufferWindow::clear() {
@@ -501,62 +557,62 @@ void TextBufferWindow::clear() {
attr.bgcolor = Windows::_overrideBgSet ? Windows::_overrideBgVal : 0;
attr.reverse = false;
- ladjw = radjw = 0;
- ladjn = radjn = 0;
+ _ladjw = _radjw = 0;
+ _ladjn = _radjn = 0;
- spaced = 0;
- dashed = 0;
+ _spaced = 0;
+ _dashed = 0;
- numchars = 0;
+ _numChars = 0;
- for (i = 0; i < scrollback; i++) {
- lines[i].len = 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;
+ 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].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;
- scrollpos = 0;
- scrollmax = 0;
+ _lastSeen = 0;
+ _scrollPos = 0;
+ _scrollMax = 0;
- for (i = 0; i < height; i++)
+ 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)
+ 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;
+ _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;
} else {
- if (align != imagealign_MarginLeft && numchars)
+ 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;
+ _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;
if (align != imagealign_MarginLeft)
flowBreak();
@@ -724,8 +780,8 @@ void TextBufferWindow::flowBreak() {
}
void TextBufferWindow::touch(int line) {
- int y = bbox.top + g_conf->_tMarginY + (height - line - 1) * g_conf->_leading;
- lines[line].dirty = 1;
+ int y = bbox.top + g_conf->_tMarginY + (_height - line - 1) * g_conf->_leading;
+ _lines[line].dirty = 1;
_windows->clearSelection();
_windows->repaint(Common::Rect(bbox.left, y - 2, bbox.right, y + g_conf->_leading + 2));
}
@@ -734,6 +790,21 @@ glui32 TextBufferWindow::getSplit(glui32 size, bool vertical) const {
return (vertical) ? size * g_conf->_cellW : size * g_conf->_cellH;
}
+void TextBufferWindow::cancelLineEvent(Event *ev) {
+ Event dummyEv;
+
+ if (!ev)
+ ev = &dummyEv;
+
+ g_vm->_events->clearEvent(ev);
+
+ if (!line_request && !line_request_uni)
+ return;
+
+
+ // TODO : textbuffer_cancel_line
+}
+
/*--------------------------------------------------------------------------*/
TextBufferWindow::TextBufferRow::TextBufferRow() : len(0), newline(0), dirty(false), repaint(false),
diff --git a/engines/gargoyle/windows.h b/engines/gargoyle/windows.h
index 6f7a016379..f09ebdbf41 100644
--- a/engines/gargoyle/windows.h
+++ b/engines/gargoyle/windows.h
@@ -27,6 +27,7 @@
#include "common/list.h"
#include "common/rect.h"
#include "graphics/screen.h"
+#include "gargoyle/events.h"
#include "gargoyle/glk_types.h"
#include "gargoyle/fonts.h"
#include "gargoyle/picture.h"
@@ -34,7 +35,6 @@
namespace Gargoyle {
-class GargoyleEngine;
class Window;
class PairWindow;
struct WindowMask;
@@ -47,9 +47,37 @@ struct WindowMask;
* Main windows manager
*/
class Windows {
- friend class Window;
+public:
+ class iterator {
+ private:
+ Window *_current;
+ public:
+ /**
+ * Constructor
+ */
+ iterator(Window *start) : _current(start) {}
+
+ /**
+ * Dereference
+ */
+ Window *operator*() const { return _current; }
+
+ /**
+ * Move to next
+ */
+ iterator &operator++();
+
+ /**
+ * Equality test
+ */
+ bool operator==(const iterator &i) { return _current == i._current; }
+
+ /**
+ * Inequality test
+ */
+ bool operator!=(const iterator &i) { return _current != i._current; }
+ };
private:
- GargoyleEngine *_engine;
Graphics::Screen *_screen;
Window * _windowList; ///< List of all windows
Window *_rootWin; ///< The topmost window
@@ -83,7 +111,7 @@ public:
/**
* Constructor
*/
- Windows(GargoyleEngine *engine, Graphics::Screen *screen);
+ Windows(Graphics::Screen *screen);
/**
* Open a new window
@@ -102,6 +130,16 @@ public:
* Repaint an area of the windows
*/
void repaint(const Common::Rect &box);
+
+ /**
+ * Get an iterator that will move over the tree
+ */
+ iterator begin() { return iterator(_windowList); }
+
+ /**
+ * Returns the end point of window iteration
+ */
+ iterator end() { return iterator(nullptr); }
};
/**
@@ -159,12 +197,13 @@ public:
glui32 _rock;
glui32 _type;
- Window *parent; ///< pair window which contains this one
+ Window *_parent; ///< pair window which contains this one
+ Window *_next, *_prev; ///< in the big linked list of windows
Common::Rect bbox;
int yadj;
- Stream *_stream; ///< the window stream.
- Stream *_echoStream; ///< the window's echo stream, if any.
+ Stream *_stream; ///< the window stream.
+ Stream *_echoStream; ///< the window's echo stream, if any.
int line_request;
int line_request_uni;
@@ -185,7 +224,6 @@ public:
byte fgcolor[3];
gidispatch_rock_t disprock;
- Window *next, *prev; ///< in the big linked list of windows
public:
/**
* Constructor
@@ -206,6 +244,31 @@ public:
* Get window split size within parent pair window
*/
virtual glui32 getSplit(glui32 size, bool vertical) const { return 0; }
+
+ /**
+ * Cancel a line event
+ */
+ virtual void cancelLineEvent(Event *ev);
+
+ /**
+ * Write a character
+ */
+ virtual void putChar(unsigned char ch) { /* TODO */ }
+
+ /**
+ * Write a unicode character
+ */
+ virtual void putCharUni(uint32 ch) { /* TODO */ }
+
+ /**
+ * Write a buffer
+ */
+ virtual void putBuffer(const unsigned char *buf, size_t len) { /* TODO */ }
+
+ /**
+ * Write a unicode character
+ */
+ virtual void putBufferUni(const uint32 *buf, size_t len) { /* TODO */ }
};
typedef Window *winid_t;
@@ -249,19 +312,19 @@ private:
*/
void touch(int line);
public:
- int width, height;
+ int _width, _height;
TextGridRows lines;
- int curx, cury; ///< the window cursor position
+ int _curX, _curY; ///< the window cursor position
- ///< for line input
- void *inbuf; ///< unsigned char* for latin1, glui32* for unicode
- int inorgx, inorgy;
- int inmax;
- int incurs, inlen;
- Attributes origattr;
- gidispatch_rock_t inarrayrock;
- glui32 *line_terminators;
+ ///< for line input
+ void *_inBuf; ///< unsigned char* for latin1, glui32* for unicode
+ int _inorgX, _inorgY;
+ int _inMax;
+ int _inCurs, _inLen;
+ Attributes _origAttr;
+ gidispatch_rock_t _inArrayRock;
+ glui32 *_lineTerminators;
WindowStyle styles[style_NUMSTYLES]; ///< style hints and settings
public:
@@ -279,6 +342,11 @@ public:
* Get window split size within parent pair window
*/
virtual glui32 getSplit(glui32 size, bool vertical) const override;
+
+ /**
+ * Cancel a line event
+ */
+ virtual void cancelLineEvent(Event *ev) override;
};
/**
@@ -321,43 +389,43 @@ private:
*/
void touch(int line);
public:
- int width, height;
- int spaced;
- int dashed;
+ int _width, _height;
+ int _spaced;
+ int _dashed;
- TextBufferRows lines;
- int scrollback;
+ 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
+ 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;
+ ///< adjust margins temporarily for images
+ int _ladjw;
+ int _ladjn;
+ int _radjw;
+ int _radjn;
/* Command history. */
- glui32 *history[HISTORYLEN];
- int historypos;
- int historyfirst, historypresent;
+ glui32 *_history[HISTORYLEN];
+ int _historyPos;
+ int _historyFirst, _historyPresent;
/* for paging */
- int lastseen;
- int scrollpos;
- int scrollmax;
+ 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;
+ 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;
+ glui32 _echoLineInput;
+ glui32 *_lineTerminators;
/* style hints and settings */
WindowStyle styles[style_NUMSTYLES];
@@ -382,6 +450,11 @@ public:
virtual glui32 getSplit(glui32 size, bool vertical) const override;
/**
+ * Cancel a line event
+ */
+ virtual void cancelLineEvent(Event *ev) override;
+
+ /**
* Clear the window
*/
void clear();