/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*
*/
#include "glk/hugo/hugo.h"
namespace Glk {
namespace Hugo {
void Hugo::hugo_init_screen() {
// Open the main window...
mainwin = currentwin = glk_window_open(nullptr, 0, 0, wintype_TextBuffer, 1);
assert(mainwin);
// ...and set it up for default output
glk_set_window(mainwin);
// By setting the width and height so high, we're basically forcing the Glk library
// to deal with text-wrapping and page ends
SCREENWIDTH = 0x7fff;
SCREENHEIGHT = 0x7fff;
FIXEDCHARWIDTH = 1;
FIXEDLINEHEIGHT = 1;
hugo_settextwindow(1, 1,
SCREENWIDTH/FIXEDCHARWIDTH, SCREENHEIGHT/FIXEDLINEHEIGHT);
}
void Hugo::hugo_getline(const char *prmpt) {
event_t ev;
char gotline = 0;
/* Just in case we try to get line input from a Glk-illegal
window that hasn't been created, switch as a failsafe
to mainwin
*/
if (currentwin == nullptr)
glk_set_window(currentwin = mainwin);
/* Print prompt */
glk_put_string(prmpt);
/* Request line input */
glk_request_line_event(currentwin, buffer, MAXBUFFER, 0);
while (!gotline) {
if (shouldQuit())
return;
/* Grab an event */
glk_select(&ev);
switch (ev.type)
{
case evtype_LineInput:
/* (Will always be currentwin, but anyway) */
if (ev.window == currentwin) {
gotline = true;
}
break;
default:
break;
}
}
/* The line we have received in commandbuf is not null-terminated */
buffer[ev.val1] = '\0'; /* i.e., the length */
/* Copy the input to the script file (if open) */
if (script) {
Common::String text = Common::String::format("%s%s\n", prmpt, buffer);
script->putBuffer(text.c_str(), text.size());
}
}
int Hugo::hugo_waitforkey() {
event_t ev;
char gotchar = 0;
/* Just in case we try to get key input from a Glk-illegal
window that hasn't been created, switch as a failsafe
to mainwin
*/
if (currentwin == nullptr)
glk_set_window(currentwin = mainwin);
#if defined (NO_KEYPRESS_CURSOR)
if (currentwin != mainwin)
{
glk_window_move_cursor(currentwin, currentpos / CHARWIDTH, currentline - 1);
hugo_print("*");
glk_window_move_cursor(currentwin, currentpos / CHARWIDTH, currentline - 1);
}
#endif
glk_request_char_event(currentwin);
while (!gotchar)
{
/* Grab an event */
glk_select(&ev);
switch (ev.type) {
case evtype_CharInput:
/* (Will always be mainwin, but anyway) */
if (ev.window == currentwin) {
gotchar = true;
}
break;
case evtype_Quit:
return 0;
default:
break;
}
}
/* Convert Glk special keycodes: */
switch (ev.val1)
{
case keycode_Left: ev.val1 = 8; break;
case keycode_Right: ev.val1 = 21; break;
case keycode_Up: ev.val1 = 11; break;
case keycode_Down: ev.val1 = 10; break;
case keycode_Return: ev.val1 = 13; break;
case keycode_Escape: ev.val1 = 27; break;
}
#if defined (NO_KEYPRESS_CURSOR)
if (currentwin != mainwin)
{
glk_window_move_cursor(currentwin, currentpos / CHARWIDTH, currentline - 1);
hugo_print(" ");
glk_window_move_cursor(currentwin, currentpos / CHARWIDTH, currentline - 1);
}
#endif
return ev.val1;
}
int Hugo::hugo_iskeywaiting() {
var[system_status] = STAT_UNAVAILABLE;
return 0;
}
int Hugo::hugo_timewait(int n) {
uint32 millisecs;
event_t ev;
if (!glk_gestalt(gestalt_Timer, 0))
return false;
if (n == 0) return true;
millisecs = 1000 / n;
if (millisecs == 0)
millisecs = 1;
// For the time being, we're going to disallow
// millisecond delays in Glk (1) because there's no
// point, and (2) so that we can tell we're running
// under Glk.
if (millisecs < 1000) return false;
glk_request_timer_events(millisecs);
while (1)
{
glk_select(&ev);
if (ev.type == evtype_Timer)
break;
}
glk_request_timer_events(0);
return true;
}
void Hugo::hugo_clearfullscreen() {
glk_window_clear(mainwin);
if (secondwin) glk_window_clear(secondwin);
if (auxwin) glk_window_clear(auxwin);
/* See hugo_print() for the need for this */
if (currentwin == mainwin) mainwin_bgcolor = glk_bgcolor;
/* Must be set: */
currentpos = 0;
currentline = 1;
if (!inwindow) just_cleared_screen = true;
}
void Hugo::hugo_clearwindow() {
/* Clears the currently defined window, moving the cursor to the top-left
corner of the window */
/* If the engine thinks we're in a window, but Glk was
unable to comply, don't clear the window, because it's
not really a window
*/
if (inwindow && currentwin == mainwin) return;
if (currentwin == nullptr) return;
glk_window_clear(currentwin);
/* See hugo_print() for the need for this */
if (currentwin == mainwin) mainwin_bgcolor = glk_bgcolor;
/* If we're in a fixed-font (i.e., textgrid) auxiliary
window when we call for a clear, close auxwin and reset
the current window to mainwin
*/
if (auxwin)
{
stream_result_t sr;
glk_window_close(auxwin, &sr);
auxwin = nullptr;
glk_set_window(currentwin = mainwin);
}
/* Must be set: */
currentpos = 0;
currentline = 1;
if (!inwindow) just_cleared_screen = true;
}
void Hugo::hugo_settextmode() {
charwidth = FIXEDCHARWIDTH;
lineheight = FIXEDLINEHEIGHT;
}
void Hugo::hugo_settextwindow(int left, int top, int right, int bottom) {
/* Hugo's arbitrarily positioned windows don't currently
mesh with what Glk has to offer, so we have to ignore any
non-Glk-ish Windows and just maintain the current
parameters
*/
if ((top != 1 || bottom >= physical_windowbottom / FIXEDLINEHEIGHT + 1)
/* Pre-v2.4 didn't support proper windowing */
&& (game_version >= 24 || !inwindow))
{
in_valid_window = false;
/* Glk-illegal floating window; setting currentwin
to nullptr will tell hugo_print() not to print in it:
*/
if (bottom= ' ') /* alphanumeric characters */
return CHARWIDTH; /* for non-proportional */
return 0;
}
int Hugo::hugo_textwidth(const char *a) const {
int i, slen, len = 0;
slen = (int)strlen(a);
for (i = 0; i