From 832418b83752c7cf6593824762ef819f92425b0a Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Thu, 8 Aug 2019 18:56:19 -0700 Subject: GLK: FROTZ: Ordering of text and graphics windows based on usage The ScummGlk backend already had a new 'arbitrary' mode allowing for windows to be placed at any position, and on top of each other. This expands on this by ensuring that the background window, which is used for drawing graphics on, appears behind text that gets written. Yet can still appear on top of the text (hiding it) when title screen graphics are being shown --- engines/glk/frotz/glk_interface.cpp | 10 +++---- engines/glk/frotz/processor_screen.cpp | 3 ++ engines/glk/frotz/processor_windows.cpp | 19 ++++++------ engines/glk/frotz/windows.cpp | 51 +++++++++++++++++++++------------ engines/glk/frotz/windows.h | 7 ++++- engines/glk/windows.cpp | 2 ++ 6 files changed, 57 insertions(+), 35 deletions(-) (limited to 'engines') diff --git a/engines/glk/frotz/glk_interface.cpp b/engines/glk/frotz/glk_interface.cpp index 6f5065421b..1e51933669 100644 --- a/engines/glk/frotz/glk_interface.cpp +++ b/engines/glk/frotz/glk_interface.cpp @@ -541,14 +541,14 @@ void GlkInterface::showBeyondZorkTitle() { } void GlkInterface::os_draw_picture(int picture, const Common::Point &pos) { - assert(pos.x != 0 && pos.y != 0); - if (_wp._cwin == 0 && _wp._lower) { - // Picture embedded within the lower text area - _wp._lower.imageDraw(picture, imagealign_MarginLeft, 0); - } else { + if (pos.x && pos.y) { + _wp._background->bringToFront(); glk_image_draw(_wp._background, picture, (pos.x - 1) * g_conf->_monoInfo._cellW, (pos.y - 1) * g_conf->_monoInfo._cellH); + } else { + // Picture embedded within the lower text area + _wp.currWin().imageDraw(picture, imagealign_MarginLeft, 0); } } diff --git a/engines/glk/frotz/processor_screen.cpp b/engines/glk/frotz/processor_screen.cpp index 78c884de3a..0d6023ef52 100644 --- a/engines/glk/frotz/processor_screen.cpp +++ b/engines/glk/frotz/processor_screen.cpp @@ -106,6 +106,9 @@ void Processor::screen_char(zchar c) { Window &w = _wp.currWin(); w.ensureTextWindow(); + if (h_version == V6) + _wp.showTextWindows(); + if (gos_linepending && (w == gos_linewin)) { gos_cancel_pending_line(); if (_wp.currWin() == _wp._upper) { diff --git a/engines/glk/frotz/processor_windows.cpp b/engines/glk/frotz/processor_windows.cpp index 2ebc960a5c..517296cdd2 100644 --- a/engines/glk/frotz/processor_windows.cpp +++ b/engines/glk/frotz/processor_windows.cpp @@ -49,19 +49,15 @@ void Processor::z_draw_picture() { flush_buffer(); Window &win = _wp[_wp._cwin]; - if (!x || !y) { - - // use cursor column if x-coordinate is 0 - if (!x) - x = win[X_CURSOR]; - // use cursor line if y-coordinate is 0 - if (!y) - y = win[Y_CURSOR]; + if (_wp._cwin == 0) { + // Embedded picture within the text area + x = y = 0; + } else { + assert(x && y); + x += win[X_POS] - 1; + y += win[Y_POS] - 1; } - x += win[X_POS] - 1; - y += win[Y_POS] - 1; - /* The following is necessary to make Amiga and Macintosh story * files work with MCGA graphics files. Some screen-filling * pictures of the original Amiga release like the borders of @@ -81,6 +77,7 @@ void Processor::z_draw_picture() { if (_storyId == ARTHUR && pic == 54) delta = h_screen_width / 160; + assert(x && y); os_draw_picture(mapper[i].pic1, Point(x + delta, y + height1)); os_draw_picture(mapper[i].pic2, Point(x + width1 - width2 - delta, y + height1)); } diff --git a/engines/glk/frotz/windows.cpp b/engines/glk/frotz/windows.cpp index 7e647ea06c..677b213246 100644 --- a/engines/glk/frotz/windows.cpp +++ b/engines/glk/frotz/windows.cpp @@ -23,8 +23,9 @@ #include "glk/frotz/windows.h" #include "glk/frotz/frotz.h" #include "glk/window_pair.h" -#include "glk/window_text_grid.h" +#include "glk/window_graphics.h" #include "glk/window_text_buffer.h" +#include "glk/window_text_grid.h" #include "glk/conf.h" namespace Glk { @@ -85,6 +86,21 @@ void Windows::setWindow(int win) { g_vm->glk_set_window(_windows[_cwin]._win); } +void Windows::showTextWindows() { + // For v6, drawing graphics brings them to the front (such for title screens). So check for it + const PairWindow *pairWin = dynamic_cast(g_vm->glk_window_get_root()); + if (g_vm->h_version == V6 && pairWin && dynamic_cast(pairWin->_children.back())) { + // Yep, it's at the forefront. So since we're now drawing text, ensure all text windows are in front of it + for (uint idx = 0; idx < size(); ++idx) { + if (_windows[idx]) { + winid_t win = _windows[idx]; + if (dynamic_cast(win)) + win->bringToFront(); + } + } + } +} + /*--------------------------------------------------------------------------*/ Window::Window() : _windows(nullptr), _win(nullptr), _quotes(0), _dashes(0), _spaces(0), _index(-1), @@ -126,15 +142,17 @@ Window &Window::operator=(winid_t win) { void Window::ensureTextWindow() { if (_win) { - // There's a window present, so make sure it's a text grid or text buffer window - if (dynamic_cast(_win) || dynamic_cast(_win)) - return; - - g_vm->glk_window_close(_win); - _win = nullptr; + // There's a window present, so make sure it's textual + if (!dynamic_cast(_win)) { + g_vm->glk_window_close(_win); + _win = nullptr; + createGlkWindow(); + } + } else { + createGlkWindow(); } - createGlkWindow(); + _windows->showTextWindows(); } void Window::setSize(const Point &newSize) { @@ -307,6 +325,9 @@ void Window::setReverseVideo(bool reverse) { } void Window::createGlkWindow() { + if (g_vm->h_version == V6) + _windows->showTextWindows(); + // Create a new window if (_index == 1) { // Text grid window @@ -356,19 +377,13 @@ void Window::checkRepositionLower() { } } -bool Window::imageDraw(uint image, int val1, int val2) { - if (!_win) - _win = g_vm->glk_window_open(g_vm->glk_window_get_root(), - winmethod_Arbitrary | winmethod_Fixed, 0, wintype_Graphics, 0); - - return g_vm->glk_image_draw(_win, image, val1, val2); +bool Window::imageDraw(uint image, ImageAlign align, int val) { + ensureTextWindow(); + return g_vm->glk_image_draw(_win, image, align, val); } bool Window::imageDrawScaled(uint image, int val1, int val2, uint width, uint height) { - if (!_win) - _win = g_vm->glk_window_open(g_vm->glk_window_get_root(), - winmethod_Arbitrary | winmethod_Fixed, 0, wintype_Graphics, 0); - + ensureTextWindow(); return g_vm->glk_image_draw_scaled(_win, image, val1, val2, width, height); } diff --git a/engines/glk/frotz/windows.h b/engines/glk/frotz/windows.h index 785fb10d8f..d55c928a30 100644 --- a/engines/glk/frotz/windows.h +++ b/engines/glk/frotz/windows.h @@ -206,7 +206,7 @@ public: /** * Draw an image */ - bool imageDraw(uint image, int val1, int val2); + bool imageDraw(uint image, ImageAlign align, int val); /** * Draw a scaled image @@ -265,6 +265,11 @@ public: assert(_windows[_cwin]._win); return _windows[_cwin]._win; } + + /** + * Places any text windows in front of the background in V6 games + */ + void showTextWindows(); }; } // End of namespace Frotz diff --git a/engines/glk/windows.cpp b/engines/glk/windows.cpp index 32f2868b7e..c1ed50ad17 100644 --- a/engines/glk/windows.cpp +++ b/engines/glk/windows.cpp @@ -741,6 +741,7 @@ void Window::bringToFront() { if (pairWin && pairWin->_dir == winmethod_Arbitrary && pairWin->_children.back() != this) { pairWin->_children.remove(this); pairWin->_children.push_back(this); + Windows::_forceRedraw = true; } } @@ -750,6 +751,7 @@ void Window::sendToBack() { if (pairWin && pairWin->_dir == winmethod_Arbitrary && pairWin->_children.front() != this) { pairWin->_children.remove(this); pairWin->_children.insert_at(0, this); + Windows::_forceRedraw = true; } } -- cgit v1.2.3