diff options
-rw-r--r-- | engines/gargoyle/conf.cpp | 9 | ||||
-rw-r--r-- | engines/gargoyle/conf.h | 14 | ||||
-rw-r--r-- | engines/gargoyle/events.cpp | 4 | ||||
-rw-r--r-- | engines/gargoyle/events.h | 85 | ||||
-rw-r--r-- | engines/gargoyle/gargoyle.cpp | 7 | ||||
-rw-r--r-- | engines/gargoyle/gargoyle.h | 2 | ||||
-rw-r--r-- | engines/gargoyle/glk.cpp | 32 | ||||
-rw-r--r-- | engines/gargoyle/glk_types.h | 54 | ||||
-rw-r--r-- | engines/gargoyle/streams.cpp | 87 | ||||
-rw-r--r-- | engines/gargoyle/streams.h | 78 | ||||
-rw-r--r-- | engines/gargoyle/windows.cpp | 277 | ||||
-rw-r--r-- | engines/gargoyle/windows.h | 163 |
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(); |