aboutsummaryrefslogtreecommitdiff
path: root/engines/glk/frotz
diff options
context:
space:
mode:
authorPaul Gilbert2019-02-15 19:23:53 -0800
committerPaul Gilbert2019-02-16 15:17:51 -0800
commit25b066520ed1247e2b3cd70433f9aa86c3587f7c (patch)
tree54902ed749cff2c208677f5a3568610a9e7a03cf /engines/glk/frotz
parentf4fa6efad1ff41b3ed50c43ceec6904cfd3efa08 (diff)
downloadscummvm-rg350-25b066520ed1247e2b3cd70433f9aa86c3587f7c.tar.gz
scummvm-rg350-25b066520ed1247e2b3cd70433f9aa86c3587f7c.tar.bz2
scummvm-rg350-25b066520ed1247e2b3cd70433f9aa86c3587f7c.zip
GLK: FROTZ: Improved setup and handling of fg/bg colors
Diffstat (limited to 'engines/glk/frotz')
-rw-r--r--engines/glk/frotz/config.cpp14
-rw-r--r--engines/glk/frotz/config.h10
-rw-r--r--engines/glk/frotz/glk_interface.cpp99
-rw-r--r--engines/glk/frotz/glk_interface.h21
-rw-r--r--engines/glk/frotz/processor.h10
-rw-r--r--engines/glk/frotz/processor_screen.cpp178
-rw-r--r--engines/glk/frotz/screen.cpp2
-rw-r--r--engines/glk/frotz/windows.cpp5
8 files changed, 229 insertions, 110 deletions
diff --git a/engines/glk/frotz/config.cpp b/engines/glk/frotz/config.cpp
index ad0764a9ab..6e7c260599 100644
--- a/engines/glk/frotz/config.cpp
+++ b/engines/glk/frotz/config.cpp
@@ -145,7 +145,12 @@ void Header::loadHeader(Common::SeekableReadStream &f) {
/*--------------------------------------------------------------------------*/
-UserOptions::UserOptions() : _undo_slots(MAX_UNDO_SLOTS), _sound(true), _quetzal(true) {
+UserOptions::UserOptions() : _undo_slots(MAX_UNDO_SLOTS), _sound(true), _quetzal(true), _color_enabled(false),
+ _err_report_mode(ERR_REPORT_ONCE), _ignore_errors(false), _expand_abbreviations(false), _tandyBit(false),
+ _piracy(false), _script_cols(0), _left_margin(0), _right_margin(0) {
+}
+
+void UserOptions::initialize(uint hVersion) {
_err_report_mode = getConfigInt("err_report_mode", ERR_REPORT_ONCE, ERR_REPORT_FATAL);
_ignore_errors = getConfigBool("ignore_errors");
_expand_abbreviations = getConfigBool("expand_abbreviations");
@@ -161,8 +166,11 @@ UserOptions::UserOptions() : _undo_slots(MAX_UNDO_SLOTS), _sound(true), _quetzal
_object_locating = getConfigBool("object_locating");
_object_movement = getConfigBool("object_movement");
- _defaultForeground = getConfigInt("foreground", 0xffffff, 0xffffff);
- _defaultBackground = getConfigInt("background", 0x000080, 0xffffff);
+ int defaultFg = hVersion == V6 ? 0 : 0xffffff;
+ int defaultBg = hVersion == V6 ? 0xffffff : 0;
+
+ _defaultForeground = getConfigInt("foreground", defaultFg, 0xffffff);
+ _defaultBackground = getConfigInt("background", defaultBg, 0xffffff);
}
bool UserOptions::isInfocom() const {
diff --git a/engines/glk/frotz/config.h b/engines/glk/frotz/config.h
index 1086d7e51f..7099996474 100644
--- a/engines/glk/frotz/config.h
+++ b/engines/glk/frotz/config.h
@@ -148,8 +148,9 @@ struct UserOptions {
int _undo_slots;
int _script_cols;
int _err_report_mode;
- uint _defaultForeground;
- uint _defaultBackground;
+ int _defaultForeground;
+ int _defaultBackground;
+ bool _color_enabled;
/**
* Constructor
@@ -157,6 +158,11 @@ struct UserOptions {
UserOptions();
/**
+ * Initializes the options
+ */
+ void initialize(uint hVersion);
+
+ /**
* Returns true if the game being played is one of the original Infocom releases
*/
bool isInfocom() const;
diff --git a/engines/glk/frotz/glk_interface.cpp b/engines/glk/frotz/glk_interface.cpp
index 42dcdac999..77f5d19d8a 100644
--- a/engines/glk/frotz/glk_interface.cpp
+++ b/engines/glk/frotz/glk_interface.cpp
@@ -33,13 +33,14 @@ namespace Frotz {
GlkInterface::GlkInterface(OSystem *syst, const GlkGameDescription &gameDesc) :
GlkAPI(syst, gameDesc),
- _pics(nullptr), oldstyle(0), curstyle(0), cury(1), curx(1), fixforced(0),
- curr_fg(zcolor_Current), curr_bg(zcolor_Current), curr_font(1), prev_font(1), temp_font(0),
+ _pics(nullptr), oldstyle(0), curstyle(0), cury(1), curx(1), curr_font(1), prev_font(1), temp_font(0),
curr_status_ht(0), mach_status_ht(0), gos_status(nullptr), gos_curwin(nullptr), gos_linepending(0),
gos_linebuf(nullptr), gos_linewin(nullptr), gos_channel(nullptr), cwin(0), mwin(0), mouse_x(0), mouse_y(0),
- menu_selected(0), enable_wrapping(false), enable_scripting(false), enable_scrolling(false),
- enable_buffering(false), next_sample(0), next_volume(0), _soundLocked(false), _soundPlaying(false) {
+ fixforced(0), menu_selected(0), enable_wrapping(false), enable_scripting(false), enable_scrolling(false),
+ enable_buffering(false), next_sample(0), next_volume(0), _soundLocked(false), _soundPlaying(false),
+ _reverseVideo(false) {
Common::fill(&statusline[0], &statusline[256], '\0');
+ Common::fill(&zcolors[0], &zcolors[zcolor_NUMCOLORS], 0);
}
GlkInterface::~GlkInterface() {
@@ -49,6 +50,29 @@ GlkInterface::~GlkInterface() {
void GlkInterface::initialize() {
uint width, height;
+ /* Setup options */
+ UserOptions::initialize(h_version);
+
+ /* Setup colors array */
+ const int COLOR_MAP[zcolor_NUMCOLORS - 2] = {
+ 0x0000, ///< 2 = black
+ 0x001D, ///< 3 = red
+ 0x0340, ///< 4 = green
+ 0x03BD, ///< 5 = yellow
+ 0x59A0, ///< 6 = blue
+ 0x7C1F, ///< 7 = magenta
+ 0x77A0, ///< 8 = cyan
+ 0x7FFF, ///< 9 = white
+ 0x5AD6, ///< 10 = light grey
+ 0x4631, ///< 11 = medium grey
+ 0x2D6B, ///< 12 = dark grey
+ };
+
+ zcolors[0] = -2; // Current
+ zcolors[1] = -1; // Default
+ for (int i = 2; i < zcolor_NUMCOLORS; ++i)
+ zcolors[i] = zRGB(COLOR_MAP[i - 2]);
+
/*
* Init glk stuff
*/
@@ -134,11 +158,27 @@ void GlkInterface::initialize() {
h_interpreter_number = h_version == 6 ? INTERP_MSDOS : INTERP_AMIGA;
h_interpreter_version = 'F';
- // Set these per spec 8.3.2.
- h_default_foreground = WHITE_COLOUR;
- h_default_background = BLACK_COLOUR;
- if (h_flags & COLOUR_FLAG)
- h_flags &= ~COLOUR_FLAG;
+ // Set up the foreground & background
+ _color_enabled = ((h_version >= 5) && (h_flags & COLOUR_FLAG))
+ || (_defaultForeground != -1) || (_defaultBackground != -1);
+
+ if (_color_enabled) {
+ h_config |= CONFIG_COLOUR;
+ h_flags |= COLOUR_FLAG; // FIXME: beyond zork handling?
+
+ assert(_defaultForeground != -1 && _defaultBackground != -1);
+ h_default_foreground = BLACK_COLOUR;
+ h_default_background = WHITE_COLOUR;
+ zcolors[h_default_foreground] = _defaultForeground;
+ zcolors[h_default_background] = _defaultBackground;
+ } else {
+ // Set these per spec 8.3.2.
+ h_default_foreground = WHITE_COLOUR;
+ h_default_background = BLACK_COLOUR;
+
+ if (h_flags & COLOUR_FLAG)
+ h_flags &= ~COLOUR_FLAG;
+ }
/*
* Open the windows
@@ -147,6 +187,11 @@ void GlkInterface::initialize() {
showBeyondZorkTitle();
_wp.setup(h_version == 6);
+ for (uint i = 0; i < _wp.size(); ++i) {
+ _wp[i][TRUE_FG_COLOR] = zcolors[h_default_foreground];
+ _wp[i][TRUE_BG_COLOR] = zcolors[h_default_background];
+ }
+
cwin = 0;
gos_curwin = _wp._lower;
@@ -366,9 +411,7 @@ void GlkInterface::erase_window(zword w) {
if (w == 0)
glk_window_clear(_wp._lower);
else if (_wp._upper) {
-#ifdef GARGLK
- garglk_set_reversevideo_stream(glk_window_get_stream(_wp._upper), true);
-#endif /* GARGLK */
+ //os_set_reverse_video(glk_window_get_stream(_wp._upper), true);
memset(statusline, ' ', sizeof statusline);
glk_window_clear(_wp._upper);
@@ -512,6 +555,31 @@ void GlkInterface::os_draw_picture(int picture, const Common::Rect &r) {
r.width() * cell.x, r.height() * cell.y);
}
+int GlkInterface::os_peek_color() {
+ if (_color_enabled) {
+ return _defaultBackground;
+ } else {
+ return (_reverseVideo) ? h_default_foreground : h_default_background;
+ }
+/*
+ if (u_setup.color_enabled) {
+#ifdef COLOR_SUPPORT
+ short fg, bg;
+ pair_content(PAIR_NUMBER(inch() & A_COLOR), &fg, &bg);
+ switch(bg) {
+ case COLOR_BLACK: return BLACK_COLOUR;
+ case COLOR_RED: return RED_COLOUR;
+ case COLOR_GREEN: return GREEN_COLOUR;
+ case COLOR_YELLOW: return YELLOW_COLOUR;
+ case COLOR_BLUE: return BLUE_COLOUR;
+ case COLOR_MAGENTA: return MAGENTA_COLOUR;
+ case COLOR_CYAN: return CYAN_COLOUR;
+ case COLOR_WHITE: return WHITE_COLOUR;
+ }
+ return 0;
+#endif /* COLOR_SUPPORT */
+}
+
zchar GlkInterface::os_read_key(int timeout, bool show_cursor) {
event_t ev;
winid_t win = gos_curwin ? gos_curwin : _wp._lower;
@@ -622,5 +690,12 @@ uint GlkInterface::roundDiv(uint x, uint y) {
return quotient;
}
+void GlkInterface::os_set_reverse_video(bool flag) {
+#ifdef GARGLK
+ _reverseVideo = flag;
+ garglk_set_reversevideo(flag);
+#endif
+}
+
} // End of namespace Frotz
} // End of namespace Glk
diff --git a/engines/glk/frotz/glk_interface.h b/engines/glk/frotz/glk_interface.h
index 93d0ecd4d2..ea7a104b8a 100644
--- a/engines/glk/frotz/glk_interface.h
+++ b/engines/glk/frotz/glk_interface.h
@@ -30,6 +30,12 @@
namespace Glk {
namespace Frotz {
+#define zB(i) ((((i >> 10) & 0x1F) << 3) | (((i >> 10) & 0x1F) >> 2))
+#define zG(i) ((((i >> 5) & 0x1F) << 3) | (((i >> 5) & 0x1F) >> 2))
+#define zR(i) ((((i ) & 0x1F) << 3) | (((i ) & 0x1F) >> 2))
+#define zRGB(i) _screen->format.RGBToColor(zR(i), zG(i), zB(i))
+#define zcolor_NUMCOLORS (13)
+
enum SoundEffect {
EFFECT_PREPARE = 1,
EFFECT_PLAY = 2,
@@ -50,16 +56,18 @@ class Pics;
* and sound effect handling
*/
class GlkInterface : public GlkAPI, public virtual UserOptions, public virtual Mem {
+private:
+ bool _reverseVideo;
public:
Pics *_pics;
zchar statusline[256];
+ int zcolors[zcolor_NUMCOLORS];
int oldstyle;
int curstyle;
int cury;
int curx;
int fixforced;
- uint curr_fg, curr_bg;
int curr_font;
int prev_font;
int temp_font;
@@ -183,6 +191,12 @@ protected:
void os_draw_picture(int picture, const Common::Rect &r);
/**
+ * Return the colour of the pixel below the cursor. This is used by V6 games to print
+ * text on top of pictures. The coulor need not be in the standard set of Z-machine colours.
+ */
+ int os_peek_color();
+
+ /**
* Call the IO interface to play a sample.
*/
void start_sample(int number, int volume, int repeats, zword eos);
@@ -238,6 +252,11 @@ protected:
* Waits for the user to type an input line
*/
zchar os_read_line(int max, zchar *buf, int timeout, int width, int continued);
+
+ /**
+ * Set whether reverse video mode is active
+ */
+ void os_set_reverse_video(bool flag);
public:
/**
* Constructor
diff --git a/engines/glk/frotz/processor.h b/engines/glk/frotz/processor.h
index e992a78100..dddcc7609a 100644
--- a/engines/glk/frotz/processor.h
+++ b/engines/glk/frotz/processor.h
@@ -346,6 +346,16 @@ protected:
*/
void screen_word(const zchar *s);
+ /**
+ * Erase the entire screen to background colour.
+ */
+ void erase_screen(zword win);
+
+ /**
+ * Erase a window to background colour.
+ */
+ void erase_window(zword win);
+
/**@}*/
/**
diff --git a/engines/glk/frotz/processor_screen.cpp b/engines/glk/frotz/processor_screen.cpp
index a440cfa013..29650451d6 100644
--- a/engines/glk/frotz/processor_screen.cpp
+++ b/engines/glk/frotz/processor_screen.cpp
@@ -189,6 +189,36 @@ void Processor::screen_word(const zchar *s) {
}
}
+void Processor::erase_screen(zword win) {
+ int curr_fg = _wp[1][TRUE_FG_COLOR];
+ int curr_bg = _wp[1][TRUE_BG_COLOR];
+
+ if (win == -1) {
+ if (_wp._upper) {
+ glk_set_window(_wp._upper);
+#ifdef GARGLK
+ garglk_set_zcolors(curr_fg, curr_bg);
+#endif /* GARGLK */
+ glk_window_clear(_wp._upper);
+ }
+
+ glk_window_clear(_wp._lower);
+ split_window(0);
+ glk_set_window(_wp._lower);
+ gos_curwin = _wp._lower;
+ }
+}
+
+void Processor::erase_window(zword win) {
+ if (h_version == V6 && win != cwin && h_interpreter_number != INTERP_AMIGA)
+ garglk_set_zcolors(_wp[win][TRUE_FG_COLOR], _wp[win][TRUE_BG_COLOR]);
+
+ glk_window_clear(_wp[win]);
+
+ if (h_version == V6 && win != cwin && h_interpreter_number != INTERP_AMIGA)
+ garglk_set_zcolors(_wp[cwin][TRUE_FG_COLOR], _wp[cwin][TRUE_BG_COLOR]);
+}
+
void Processor::z_buffer_mode() {
// No implementation
}
@@ -208,34 +238,14 @@ void Processor::z_erase_line() {
}
void Processor::z_erase_window() {
- short w = zargs[0];
- if (w == -2) {
- if (_wp._upper) {
- glk_set_window(_wp._upper);
-#ifdef GARGLK
- garglk_set_zcolors(curr_fg, curr_bg);
-#endif /* GARGLK */
- glk_window_clear(_wp._upper);
- glk_set_window(gos_curwin);
- }
- glk_window_clear(_wp._lower);
- }
- if (w == -1) {
- if (_wp._upper) {
- glk_set_window(_wp._upper);
-#ifdef GARGLK
- garglk_set_zcolors(curr_fg, curr_bg);
-#endif /* GARGLK */
- glk_window_clear(_wp._upper);
- }
- glk_window_clear(_wp._lower);
- split_window(0);
- glk_set_window(_wp._lower);
- gos_curwin = _wp._lower;
- }
+ short w = (short)zargs[0];
+
+ flush_buffer();
- if (w >= 0 && _wp[w])
- glk_window_clear(_wp[w]);
+ if (w == -1 || w == -2)
+ erase_screen(w);
+ else
+ erase_window(winarg0());
}
void Processor::z_get_cursor() {
@@ -270,12 +280,6 @@ void Processor::z_print_table() {
}
}
-#define zB(i) ((((i >> 10) & 0x1F) << 3) | (((i >> 10) & 0x1F) >> 2))
-#define zG(i) ((((i >> 5) & 0x1F) << 3) | (((i >> 5) & 0x1F) >> 2))
-#define zR(i) ((((i ) & 0x1F) << 3) | (((i ) & 0x1F) >> 2))
-
-#define zRGB(i) _screen->format.RGBToColor(zR(i), zG(i), zB(i))
-
void Processor::z_set_true_colour() {
int zfore = zargs[0];
int zback = zargs[1];
@@ -289,63 +293,61 @@ void Processor::z_set_true_colour() {
#ifdef GARGLK
garglk_set_zcolors(zfore, zback);
#endif /* GARGLK */
-
- curr_fg = (uint)zfore;
- curr_bg = (uint)zback;
}
-static const int zcolor_map[] = {
- -2, ///< 0 = current
- -1, ///< 1 = default
- 0x0000, ///< 2 = black
- 0x001D, ///< 3 = red
- 0x0340, ///< 4 = green
- 0x03BD, ///< 5 = yellow
- 0x59A0, ///< 6 = blue
- 0x7C1F, ///< 7 = magenta
- 0x77A0, ///< 8 = cyan
- 0x7FFF, ///< 9 = white
- 0x5AD6, ///< 10 = light grey
- 0x4631, ///< 11 = medium grey
- 0x2D6B, ///< 12 = dark grey
-};
-
-#define zcolor_NUMCOLORS (13)
-
void Processor::z_set_colour() {
- int zfore = zargs[0];
- int zback = zargs[1];
+ int fg = zargs[0];
+ int bg = zargs[1];
+ zword win = (h_version == V6) ? winarg2() : 0;
- switch (zfore) {
- case -1:
- case 0:
- case 1:
- zfore = zcolor_map[zfore];
- break;
-
- default:
- if (zfore < zcolor_NUMCOLORS)
- zfore = zRGB(zcolor_map[zfore]);
- break;
- }
-
- switch (zback) {
- case -1:
- case 0:
- case 1:
- zback = zcolor_map[zback];
- break;
+ flush_buffer();
- default:
- if (zback < zcolor_NUMCOLORS)
- zback = zRGB(zcolor_map[zback]);
- break;
+ if ((short)fg == -1)
+ // Get color at cursor
+ fg = os_peek_color();
+ if ((short)bg == -1)
+ // Get color at cursor
+ bg = os_peek_color();
+
+ if (fg == 0)
+ // keep current colour
+ fg = _wp[win][TRUE_FG_COLOR];
+ if (bg == 0)
+ bg = _wp[win][TRUE_BG_COLOR];
+
+ if (fg == 1)
+ fg = h_default_foreground;
+ if (bg == 1)
+ bg = h_default_background;
+
+ if (fg < zcolor_NUMCOLORS)
+ fg = zcolors[fg];
+ if (bg < zcolor_NUMCOLORS)
+ bg = zcolors[bg];
+
+ if (h_version == V6 && h_interpreter_number == INTERP_AMIGA) {
+ // Changing colours of window 0 affects the entire screen
+ if (win == 0) {
+ for (int i = 1; i < 8; ++i) {
+ int bg2 = _wp[i][TRUE_BG_COLOR];
+ int fg2 = _wp[i][TRUE_FG_COLOR];
+
+ if (bg2 < 16)
+ bg2 = (bg2 == _wp[0][TRUE_BG_COLOR]) ? fg : bg;
+ if (fg2 < 16)
+ fg2 = (fg2 == _wp[0][TRUE_FG_COLOR]) ? fg : bg;
+
+ _wp[i][TRUE_FG_COLOR] = fg2;
+ _wp[i][TRUE_BG_COLOR] = bg2;
+ }
+ }
}
- garglk_set_zcolors(zfore, zback);
+ _wp[win][TRUE_FG_COLOR] = fg;
+ _wp[win][TRUE_BG_COLOR] = bg;
- curr_fg = zfore;
- curr_bg = zback;
+ if (win == cwin || h_version != V6)
+ garglk_set_zcolors(fg, bg);
}
void Processor::z_set_font() {
@@ -432,9 +434,7 @@ void Processor::z_set_text_style() {
return;
if (style & REVERSE_STYLE) {
-#ifdef GARGLK
- garglk_set_reversevideo(true);
-#endif /* GARGLK */
+ os_set_reverse_video(true);
}
if (style & FIXED_WIDTH_STYLE) {
@@ -460,9 +460,7 @@ void Processor::z_set_text_style() {
}
if (curstyle == 0) {
-#ifdef GARGLK
- garglk_set_reversevideo(false);
-#endif /* GARGLK */
+ os_set_reverse_video(false);
}
}
@@ -524,9 +522,7 @@ void Processor::z_show_status() {
glk_set_window(_wp._upper);
gos_curwin = _wp._upper;
-#ifdef GARGLK
- garglk_set_reversevideo(true);
-#endif /* GARGLK */
+ os_set_reverse_video(true);
curx = cury = 1;
glk_window_move_cursor(_wp._upper, 0, 0);
diff --git a/engines/glk/frotz/screen.cpp b/engines/glk/frotz/screen.cpp
index d62c0dc68d..b1f28e498a 100644
--- a/engines/glk/frotz/screen.cpp
+++ b/engines/glk/frotz/screen.cpp
@@ -66,7 +66,7 @@ void FrotzScreen::loadVersion6Fonts(Common::Archive *archive) {
pi._lineSeparation = 0;
g_vm->_defaultForeground = 0;
- g_vm->_defaultBackground = zcolor_Transparent;
+ g_vm->_defaultBackground = (int)zcolor_Transparent;
g_conf->_tMarginX = 3;
for (uint idx = 0; idx < style_NUMSTYLES; ++idx) {
diff --git a/engines/glk/frotz/windows.cpp b/engines/glk/frotz/windows.cpp
index a9728e15a7..4f59666705 100644
--- a/engines/glk/frotz/windows.cpp
+++ b/engines/glk/frotz/windows.cpp
@@ -127,6 +127,11 @@ const zword &Window::getProperty(WindowProperty propType) {
void Window::setProperty(WindowProperty propType, zword value) {
switch (propType) {
+ case TRUE_FG_COLOR:
+ case TRUE_BG_COLOR:
+ _properties[propType] = value;
+ break;
+
default:
warning("Setting window property %d not yet supported", (int)propType);
}