From 3ed48e3de223259dd58f0c613c2d68d69848e5a2 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Wed, 2 Jan 2019 14:21:49 -0800 Subject: GLK: FROTZ: Setting window positon & size, some property reading --- engines/glk/frotz/windows.cpp | 51 ++++++++++++++++++++++++++++++++++++------ engines/glk/frotz/windows.h | 30 +++++++++++++++++-------- engines/glk/glk_types.h | 1 + engines/glk/window_pair.cpp | 30 ++++++++++++++++++------- engines/glk/window_pair.h | 2 +- engines/glk/window_text_grid.h | 18 +++++++++++++++ engines/glk/windows.cpp | 4 ++-- engines/glk/windows.h | 15 +++++++++++++ 8 files changed, 124 insertions(+), 27 deletions(-) (limited to 'engines/glk') diff --git a/engines/glk/frotz/windows.cpp b/engines/glk/frotz/windows.cpp index fdcfcf16b1..1863e68032 100644 --- a/engines/glk/frotz/windows.cpp +++ b/engines/glk/frotz/windows.cpp @@ -42,10 +42,16 @@ Window &Windows::operator[](uint idx) { /*--------------------------------------------------------------------------*/ +Window::Window() : _windows(nullptr), _win(nullptr), _tempVal(0) {} + + winid_t Window::getWindow() { if (!_win) { // Window doesn't exist, so create it - // TODO + // TODO: For now I'm assuming all the extra created windows will be graphics, since Glk requires + // us to specify it at creation time. Not sure if it's true or not for all V6 games + winid_t parent = _windows->_lower; + _win = g_vm->glk_window_open(parent, winmethod_OnTop | winmethod_Fixed, 0, wintype_Graphics, 0); } return _win; @@ -54,9 +60,8 @@ winid_t Window::getWindow() { void Window::setSize(const Point &newSize) { winid_t win = getWindow(); + win->setSize(newSize); /* TODO - y_size = zargs[1]; - _wp[win].x_size = zargs[2]; // Keep the cursor within the window if (wp[win].y_cursor > zargs[1] || wp[win].x_cursor > zargs[2]) @@ -69,12 +74,44 @@ void Window::setSize(const Point &newSize) { void Window::setPosition(const Point &newPos) { winid_t win = getWindow(); - /* TODO - if (win == cwin) - update_cursor(); - */ + win->setPosition(newPos); +} + +const uint16 &Window::operator[](WindowProperty propType) { + _tempVal = getProperty(propType); + return _tempVal; } +uint16 Window::getProperty(WindowProperty propType) { + winid_t win = getWindow(); + Point pt; + + switch (propType) { + case Y_POS: + return win->_bbox.top; + case X_POS: + return win->_bbox.left; + case Y_SIZE: + return win->_bbox.height(); + case X_SIZE: + return win->_bbox.width(); + case Y_CURSOR: + return win->getCursor().y; + case X_CURSOR: + return win->getCursor().x; + default: + error("Read of an unimplemented property"); + /* + LEFT_MARGIN = 6, RIGHT_MARGIN = 7, NEWLINE_INTERRUPT = 8, INTERRUPT_COUNTDOWN = 9, + TEXT_STYLE = 10, COLOUR_DATA = 11, FONT_NUMBER = 12, FONT_SIZE = 13, ATTRIBUTES = 14, + LINE_COUNT = 15, TRUE_FG_COLOR = 16, TRUE_BG_COLOR = 17 + */ + } +} + +void Window::setProperty(WindowProperty propType, uint16 value) { + // TODO +} } // End of namespace Frotz } // End of namespace Glk diff --git a/engines/glk/frotz/windows.h b/engines/glk/frotz/windows.h index c94a1edce3..ba277d57dc 100644 --- a/engines/glk/frotz/windows.h +++ b/engines/glk/frotz/windows.h @@ -31,6 +31,13 @@ namespace Frotz { #include "glk/windows.h" #include "glk/utils.h" +enum WindowProperty { + Y_POS = 0, X_POS = 1, Y_SIZE = 2, X_SIZE = 3, Y_CURSOR = 4, X_CURSOR = 5, + LEFT_MARGIN = 6, RIGHT_MARGIN = 7, NEWLINE_INTERRUPT = 8, INTERRUPT_COUNTDOWN = 9, + TEXT_STYLE = 10, COLOUR_DATA = 11, FONT_NUMBER = 12, FONT_SIZE = 13, ATTRIBUTES = 14, + LINE_COUNT = 15, TRUE_FG_COLOR = 16, TRUE_BG_COLOR = 17 +}; + class Windows; /** @@ -41,16 +48,27 @@ class Window { private: Windows *_windows; winid_t _win; + uint16 _tempVal; ///< used in calls to square brackets operator private: /** * Gets a reference to the window, creating a new one if one doesn't already exist */ winid_t getWindow(); + + /** + * Get a property value + */ + uint16 getProperty(WindowProperty propType); + + /** + * Set a property value + */ + void setProperty(WindowProperty propType, uint16 value); public: /** * Constructor */ - Window() : _win(nullptr) {} + Window(); /** * Assignment operator @@ -71,15 +89,9 @@ public: operator bool() const { return _win != nullptr; } /** - * Property access. There are the following properties defined by the spec: - * 0 y coordinate 6 left margin size 12 font number - * 1 x coordinate 7 right margin size 13 font size - * 2 y size 8 newline interrupt routine 14 attributes - * 3 x size 9 interrupt countdown 15 line count - * 4 y cursor 10 text style 16 true foreground colour - * 5 x cursor 11 colour data 17 true background colour + * Property accessor */ - //zword &operator[](uint idx); + const uint16 &operator[](WindowProperty propType); /** * Set the window size diff --git a/engines/glk/glk_types.h b/engines/glk/glk_types.h index aa573e2e29..2e23aec018 100644 --- a/engines/glk/glk_types.h +++ b/engines/glk/glk_types.h @@ -154,6 +154,7 @@ enum WinMethod { winmethod_Right = 0x01, winmethod_Above = 0x02, winmethod_Below = 0x03, + winmethod_OnTop = 0x04, ///< Newly introduced for ScummGlk winmethod_DirMask = 0x0f, winmethod_Fixed = 0x10, diff --git a/engines/glk/window_pair.cpp b/engines/glk/window_pair.cpp index 6fdeb93635..c90f389eac 100644 --- a/engines/glk/window_pair.cpp +++ b/engines/glk/window_pair.cpp @@ -50,6 +50,28 @@ void PairWindow::rearrange(const Rect &box) { _bbox = box; + if (!_backward) { + ch1 = _child1; + ch2 = _child2; + } else { + ch1 = _child2; + ch2 = _child1; + } + + + if (_dir == winmethod_OnTop) { + // ch2 is on top of ch1 + ch1->rearrange(box1); + if (!ch2->_bbox.isEmpty() && !ch2->_bbox.contains(box)) { + // ch2 is outside new bounds, so clip it to the new dimensions + Rect subRect = ch2->_bbox; + subRect.clip(box); + ch2->rearrange(subRect); + } + + return; + } + if (_vertical) { min = _bbox.left; max = _bbox.right; @@ -113,14 +135,6 @@ void PairWindow::rearrange(const Rect &box) { box2.right = _bbox.right; } - if (!_backward) { - ch1 = _child1; - ch2 = _child2; - } else { - ch1 = _child2; - ch2 = _child1; - } - ch1->rearrange(box1); ch2->rearrange(box2); } diff --git a/engines/glk/window_pair.h b/engines/glk/window_pair.h index ebd2d01ac0..83cbcc884a 100644 --- a/engines/glk/window_pair.h +++ b/engines/glk/window_pair.h @@ -35,7 +35,7 @@ public: Window *_child1, *_child2; // split info... - uint _dir; ///< winmethod_Left, Right, Above, or Below + uint _dir; ///< winmethod_Left, Right, Above, Below, or OnTop bool _vertical, _backward; ///< flags uint _division; ///< winmethod_Fixed or winmethod_Proportional Window *_key; ///< nullptr or a leaf-descendant (not a Pair) diff --git a/engines/glk/window_text_grid.h b/engines/glk/window_text_grid.h index 1081df81b0..f5568cd24f 100644 --- a/engines/glk/window_text_grid.h +++ b/engines/glk/window_text_grid.h @@ -95,6 +95,24 @@ public: */ virtual FontInfo *getFontInfo() override { return &_font; } + /** + * Set the size of a window + */ + virtual void setSize(const Point &newSize) { + Window::setSize(newSize); + _curX = CLIP((int16)_curX, _bbox.left, _bbox.right); + _curY = CLIP((int16)_curY, _bbox.top, _bbox.bottom); + } + + /** + * Sets the position of a window + */ + virtual void setPosition(const Point &newPos) { + _bbox.moveTo(newPos); + _curX = CLIP((int16)_curX, _bbox.left, _bbox.right); + _curY = CLIP((int16)_curY, _bbox.top, _bbox.bottom); + } + /** * Rearranges the window */ diff --git a/engines/glk/windows.cpp b/engines/glk/windows.cpp index 0e59ebcf48..de8fa52385 100644 --- a/engines/glk/windows.cpp +++ b/engines/glk/windows.cpp @@ -103,8 +103,8 @@ Window *Windows::windowOpen(Window *splitwin, uint method, uint size, } val = (method & winmethod_DirMask); - if (val != winmethod_Above && val != winmethod_Below - && val != winmethod_Left && val != winmethod_Right) { + if (val != winmethod_Above && val != winmethod_Below && val != winmethod_Left + && val != winmethod_Right && val != winmethod_OnTop) { warning("window_open: invalid method (bad direction)"); return nullptr; } diff --git a/engines/glk/windows.h b/engines/glk/windows.h index 703fc5589a..dab521901e 100644 --- a/engines/glk/windows.h +++ b/engines/glk/windows.h @@ -426,6 +426,21 @@ public: _bbox = box; } + /** + * Set the size of a window + */ + virtual void setSize(const Point &newSize) { + _bbox.setWidth(newSize.x); + _bbox.setHeight(newSize.y); + } + + /** + * Sets the position of a window + */ + virtual void setPosition(const Point &newPos) { + _bbox.moveTo(newPos); + } + /** * Get window split size within parent pair window */ -- cgit v1.2.3