From 7a21e236035876c8ae581d4f9d61584c6385b89a Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Fri, 28 Dec 2018 21:15:50 -0800 Subject: GLK: FROTZ: Implement PageUp/PageDn scrolling of desc area in Beyond Zork --- engines/glk/frotz/glk_interface.cpp | 17 +++++++++++++++++ engines/glk/glk_api.cpp | 2 +- engines/glk/window_text_buffer.cpp | 29 ++++++++++++++++++----------- engines/glk/window_text_grid.cpp | 2 +- engines/glk/windows.cpp | 20 ++++++++++++++++++-- engines/glk/windows.h | 4 +++- 6 files changed, 58 insertions(+), 16 deletions(-) diff --git a/engines/glk/frotz/glk_interface.cpp b/engines/glk/frotz/glk_interface.cpp index 74d6e457ee..88abbe3f68 100644 --- a/engines/glk/frotz/glk_interface.cpp +++ b/engines/glk/frotz/glk_interface.cpp @@ -194,6 +194,13 @@ void GlkInterface::initialize() { // Add any sound folder or zip addSound(); + + // For Beyond Zork the Page Up/Down keys are remapped to scroll the description area, + // since the arrow keys the original used are in use now for cycling prior commands + if (_storyId == BEYOND_ZORK) { + uint32 KEYCODES[2] = { keycode_PageUp, keycode_PageDown }; + glk_set_terminators_line_event(gos_lower, KEYCODES, 2); + } } void GlkInterface::addSound() { @@ -588,6 +595,16 @@ zchar GlkInterface::os_read_line(int max, zchar *buf, int timeout, int width, in reset_status_ht(); curr_status_ht = 0; + if (ev.val2) { + // Line terminator specified, so return it + if (_storyId == BEYOND_ZORK && ev.val2 == keycode_PageUp) + return ZC_ARROW_UP; + else if (_storyId == BEYOND_ZORK && ev.val2 == keycode_PageDown) + return ZC_ARROW_DOWN; + + return ev.val2; + } + return ZC_RETURN; } diff --git a/engines/glk/glk_api.cpp b/engines/glk/glk_api.cpp index 629dd0aa49..4b205001bd 100644 --- a/engines/glk/glk_api.cpp +++ b/engines/glk/glk_api.cpp @@ -138,7 +138,7 @@ uint GlkAPI::glk_gestalt_ext(uint id, uint val, uint *arr, uint arrlen) { return g_conf->_sound; case gestalt_LineTerminatorKey: - return Window::checkTerminator(val); + return Window::checkBasicTerminators(val); case gestalt_Timer: case gestalt_Unicode: diff --git a/engines/glk/window_text_buffer.cpp b/engines/glk/window_text_buffer.cpp index 6069ec8a82..6e48d1ddc4 100644 --- a/engines/glk/window_text_buffer.cpp +++ b/engines/glk/window_text_buffer.cpp @@ -762,9 +762,10 @@ void TextBufferWindow::cancelLineEvent(Event *ev) { _lineRequest = false; _lineRequestUni = false; if (_lineTerminators) { - free(_lineTerminators); + delete[] _lineTerminators; _lineTerminators = nullptr; } + _inBuf = nullptr; _inMax = 0; @@ -1246,15 +1247,10 @@ void TextBufferWindow::acceptReadLine(uint32 arg) { if (_height < 2) _scrollPos = 0; - if (_scrollPos || arg == keycode_PageUp || arg == keycode_MouseWheelUp) { - acceptScroll(arg); - return; - } - if (!_inBuf) return; - if (_lineTerminators && checkTerminator(arg)) { + if (_lineTerminators && checkTerminators(arg)) { for (cx = _lineTerminators; *cx; cx++) { if (*cx == arg) { acceptLine(arg); @@ -1263,6 +1259,11 @@ void TextBufferWindow::acceptReadLine(uint32 arg) { } } + if (_scrollPos || arg == keycode_PageUp || arg == keycode_MouseWheelUp) { + acceptScroll(arg); + return; + } + switch (arg) { // History keys (up and down) case keycode_Up: @@ -1442,10 +1443,16 @@ void TextBufferWindow::acceptLine(uint32 keycode) { _attr = _origAttr; if (_lineTerminators) { - uint val2 = keycode; - if (val2 == keycode_Return) - val2 = 0; - g_vm->_events->store(evtype_LineInput, this, len, val2); + if (keycode == keycode_Return) + keycode = 0; + else + // TODO: Currently particularly for Beyond Zork, we don't echo a newline + // for line terminators, allowing description area scrolling to not keep adding + // blank lines in the command area. In the future I may need to make it configurable + // when I see if any other line terminators need to have a newline + _echoLineInput = false; + + g_vm->_events->store(evtype_LineInput, this, len, keycode); free(_lineTerminators); _lineTerminators = nullptr; } else { diff --git a/engines/glk/window_text_grid.cpp b/engines/glk/window_text_grid.cpp index b621fec8e7..123481f639 100644 --- a/engines/glk/window_text_grid.cpp +++ b/engines/glk/window_text_grid.cpp @@ -465,7 +465,7 @@ void TextGridWindow::acceptReadLine(uint32 arg) { if (!_inBuf) return; - if (_lineTerminators && checkTerminator(arg)) { + if (_lineTerminators && checkTerminators(arg)) { const uint32 *cx; for (cx = _lineTerminators; *cx; cx++) { if (*cx == arg) { diff --git a/engines/glk/windows.cpp b/engines/glk/windows.cpp index 8562e347ee..946a373151 100644 --- a/engines/glk/windows.cpp +++ b/engines/glk/windows.cpp @@ -342,6 +342,10 @@ void Windows::inputScrollFocus() { void Windows::inputHandleKey(uint key) { if (_moreFocus) { inputMoreFocus(); + } else if (_focusWin && (_focusWin->_lineRequest || _focusWin->_lineRequestUni) && + _focusWin->checkTerminators(key)) { + // WORKAROUND: Do line terminators checking first. This was first needed for Beyond Zork, + // since it needs the Page Up/Down keys to scroll the description area rathern than the buffer area } else { switch (key) { case keycode_Tab: @@ -633,7 +637,7 @@ const WindowStyle *Window::getStyles() const { void Window::setTerminatorsLineEvent(const uint32 *keycodes, uint count) { if (dynamic_cast(this) || dynamic_cast(this)) { - delete _lineTerminatorsBase; + delete[] _lineTerminatorsBase; _lineTerminatorsBase = nullptr; if (!keycodes || count == 0) { @@ -651,7 +655,7 @@ void Window::setTerminatorsLineEvent(const uint32 *keycodes, uint count) { } } -bool Window::checkTerminator(uint32 ch) { +bool Window::checkBasicTerminators(uint32 ch) { if (ch == keycode_Escape) return true; else if (ch >= keycode_Func12 && ch <= keycode_Func1) @@ -660,6 +664,18 @@ bool Window::checkTerminator(uint32 ch) { return false; } +bool Window::checkTerminators(uint32 ch) { + if (checkBasicTerminators(ch)) + return true; + + for (uint idx = 0; idx < _termCt; ++idx) { + if (_lineTerminatorsBase[idx] == ch) + return true; + } + + return false; +} + bool Window::imageDraw(uint image, uint align, int val1, int val2) { if (!g_conf->_graphics) return false; diff --git a/engines/glk/windows.h b/engines/glk/windows.h index 337ad57be4..5529b314b6 100644 --- a/engines/glk/windows.h +++ b/engines/glk/windows.h @@ -396,7 +396,7 @@ public: gidispatch_rock_t _dispRock; public: - static bool checkTerminator(uint32 ch); + static bool checkBasicTerminators(uint32 ch); public: /** * Constructor @@ -498,6 +498,8 @@ public: int acceptScroll(uint arg); + bool checkTerminators(uint32 ch); + void setTerminatorsLineEvent(const uint32 *keycodes, uint count); virtual void acceptReadLine(uint32 arg); -- cgit v1.2.3