aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--engines/glk/frotz/config.cpp3
-rw-r--r--engines/glk/frotz/processor.cpp28
-rw-r--r--engines/glk/frotz/processor.h110
-rw-r--r--engines/glk/frotz/processor_screen.cpp4
-rw-r--r--engines/glk/frotz/processor_windows.cpp316
-rw-r--r--engines/glk/module.mk1
6 files changed, 445 insertions, 17 deletions
diff --git a/engines/glk/frotz/config.cpp b/engines/glk/frotz/config.cpp
index e53cd8c9ba..1d0264bc8e 100644
--- a/engines/glk/frotz/config.cpp
+++ b/engines/glk/frotz/config.cpp
@@ -96,9 +96,6 @@ void Header::loadHeader(Common::SeekableReadStream &f) {
if (h_version < V1 || h_version > V8)
error("Unknown Z-code version");
- if (h_version == V6)
- error("Cannot play Z-code version 6");
-
if (h_version == V3 && (h_config & CONFIG_BYTE_SWAPPED))
error("Byte swapped story file");
diff --git a/engines/glk/frotz/processor.cpp b/engines/glk/frotz/processor.cpp
index 09eb82b509..e9f0d87e3e 100644
--- a/engines/glk/frotz/processor.cpp
+++ b/engines/glk/frotz/processor.cpp
@@ -104,10 +104,10 @@ Opcode Processor::ext_opcodes[64] = {
&Processor::z_log_shift,
&Processor::z_art_shift,
&Processor::z_set_font,
- &Processor::__illegal__, // glkify - Processor::z_draw_picture,
- &Processor::__illegal__, // glkify - Processor::z_picture_data,
- &Processor::__illegal__, // glkify - Processor::z_erase_picture,
- &Processor::__illegal__, // glkify - Processor::z_set_margins,
+ &Processor::z_draw_picture,
+ &Processor::z_picture_data,
+ &Processor::z_erase_picture,
+ &Processor::z_set_margins,
&Processor::z_save_undo,
&Processor::z_restore_undo,
&Processor::z_print_unicode,
@@ -115,20 +115,20 @@ Opcode Processor::ext_opcodes[64] = {
&Processor::z_set_true_colour, // spec 1.1
&Processor::__illegal__,
&Processor::__illegal__,
- &Processor::__illegal__, // glkify - Processor::z_move_window,
- &Processor::__illegal__, // glkify - Processor::z_window_size,
- &Processor::__illegal__, // glkify - Processor::z_window_style,
- &Processor::__illegal__, // glkify - Processor::z_get_wind_prop,
- &Processor::__illegal__, // glkify - Processor::z_scroll_window,
+ &Processor::z_move_window,
+ &Processor::z_window_size,
+ &Processor::z_window_style,
+ &Processor::z_get_wind_prop,
+ &Processor::z_scroll_window,
&Processor::z_pop_stack,
- &Processor::__illegal__, // glkify - Processor::z_read_mouse,
- &Processor::__illegal__, // glkify - Processor::z_mouse_window,
+ &Processor::z_read_mouse,
+ &Processor::z_mouse_window,
&Processor::z_push_stack,
- &Processor::__illegal__, // glkify - Processor::z_put_wind_prop,
+ &Processor::z_put_wind_prop,
&Processor::z_print_form,
&Processor::z_make_menu,
- &Processor::__illegal__, // glkify - Processor::z_picture_table
- &Processor::z_buffer_screen, // spec 1.1
+ &Processor::z_picture_table,
+ &Processor::z_buffer_screen // spec 1.1
};
Processor::Processor(OSystem *syst, const GlkGameDescription &gameDesc) :
diff --git a/engines/glk/frotz/processor.h b/engines/glk/frotz/processor.h
index fb9c12f86f..dcf39869c1 100644
--- a/engines/glk/frotz/processor.h
+++ b/engines/glk/frotz/processor.h
@@ -1545,6 +1545,116 @@ protected:
void z_store();
/**@}*/
+
+ /**
+ * \defgroup Window/V6 Opcode methods
+ * @{
+ */
+
+ /**
+ * z_draw_picture, draw a picture.
+ *
+ * zargs[0] = number of picture to draw
+ * zargs[1] = y-coordinate of top left corner
+ * zargs[2] = x-coordinate of top left corner
+ */
+ void z_draw_picture();
+
+ /**
+ * Get information on a picture or the graphics file.
+ *
+ * zargs[0] = number of picture or 0 for the graphics file
+ * zargs[1] = address to write information to
+ */
+ void z_picture_data();
+
+ /**
+ * Erase a picture with background colour.
+ *
+ * zargs[0] = number of picture to erase
+ * zargs[1] = y-coordinate of top left corner (optional)
+ * zargs[2] = x-coordinate of top left corner (optional)
+ */
+ void z_erase_picture();
+
+ /**
+ * Set the left and right margins of a window.
+ *
+ * zargs[0] = left margin in pixels
+ * zargs[1] = right margin in pixels
+ * zargs[2] = window (-3 is the current one, optional)
+ */
+ void z_set_margins();
+
+
+ /**
+ * Place a window on the screen.
+ *
+ * zargs[0] = window (-3 is the current one)
+ * zargs[1] = y-coordinate
+ * zargs[2] = x-coordinate
+ *
+ */
+ void z_move_window();
+
+ /**
+ * Change the width and height of a window.
+ *
+ * zargs[0] = window (-3 is the current one)
+ * zargs[1] = new height in screen units
+ * zargs[2] = new width in screen units
+ */
+ void z_window_size();
+
+ /**
+ * Set / clear / toggle window attributes.
+ *
+ * zargs[0] = window (-3 is the current one)
+ * zargs[1] = window attribute flags
+ * zargs[2] = operation to perform (optional, defaults to 0)
+ */
+ void z_window_style();
+
+ /**
+ * Store the value of a window property.
+ *
+ * zargs[0] = window (-3 is the current one)
+ * zargs[1] = number of window property to be stored
+ */
+ void z_get_wind_prop();
+
+ /**
+ * Set the value of a window property.
+ *
+ * zargs[0] = window (-3 is the current one)
+ * zargs[1] = number of window property to set
+ * zargs[2] = value to set window property to
+ */
+ void z_put_wind_prop();
+
+ /**
+ * Scroll a window up or down.
+ *
+ * zargs[0] = window (-3 is the current one)
+ * zargs[1] = #screen units to scroll up (positive) or down (negative)
+ */
+ void z_scroll_window();
+
+ /**
+ * Select a window as mouse window.
+ *
+ * zargs[0] = window number (-3 is the current) or -1 for the screen
+ */
+ void z_mouse_window();
+
+ /**
+ * Prepare a group of pictures for faster display.
+ *
+ * zargs[0] = address of table holding the picture numbers
+ */
+ void z_picture_table();
+
+ /**@}*/
public:
/**
* Constructor
diff --git a/engines/glk/frotz/processor_screen.cpp b/engines/glk/frotz/processor_screen.cpp
index 2ec012854a..3adec6612d 100644
--- a/engines/glk/frotz/processor_screen.cpp
+++ b/engines/glk/frotz/processor_screen.cpp
@@ -127,7 +127,11 @@ void Processor::z_buffer_mode() {
}
void Processor::z_buffer_screen() {
+#ifdef TODO
+store((zword)os_buffer_screen((zargs[0] == (zword)-1) ? -1 : zargs[0]));
+#else
store(0);
+#endif
}
void Processor::z_erase_line() {
diff --git a/engines/glk/frotz/processor_windows.cpp b/engines/glk/frotz/processor_windows.cpp
new file mode 100644
index 0000000000..2f1956f6f1
--- /dev/null
+++ b/engines/glk/frotz/processor_windows.cpp
@@ -0,0 +1,316 @@
+/* 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 2
+ * 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, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "glk/frotz/processor.h"
+
+namespace Glk {
+namespace Frotz {
+
+static struct {
+ Story story_id;
+ int pic;
+ int pic1;
+ int pic2;
+} mapper[] = {
+ { ZORK_ZERO, 5, 497, 498 },
+ { ZORK_ZERO, 6, 501, 502 },
+ { ZORK_ZERO, 7, 499, 500 },
+ { ZORK_ZERO, 8, 503, 504 },
+ { ARTHUR, 54, 170, 171 },
+ { SHOGUN, 50, 61, 62 },
+ { UNKNOWN, 0, 0, 0 }
+};
+
+void Processor::z_draw_picture() {
+#ifdef TODO
+ zword pic = zargs[0];
+ zword y = zargs[1];
+ zword x = zargs[2];
+ int i;
+
+ flush_buffer ();
+
+ if (y == 0) // use cursor line if y-coordinate is 0
+ y = cwp->y_cursor;
+ if (x == 0) // use cursor column if x-coordinate is 0 */
+ x = cwp->x_cursor;
+
+ y += cwp->y_pos - 1;
+ x += cwp->x_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
+ Zork Zero were split into several MCGA pictures (left, right
+ and top borders). We pretend this has not happened. */
+
+ for (i = 0; mapper[i].story_id != UNKNOWN; i++) {
+ if (_storyId == mapper[i].story_id && pic == mapper[i].pic) {
+ int height1, width1;
+ int height2, width2;
+
+ int delta = 0;
+
+ os_picture_data (pic, &height1, &width1);
+ os_picture_data (mapper[i].pic2, &height2, &width2);
+
+ if (_storyId == ARTHUR && pic == 54)
+ delta = h_screen_width / 160;
+
+ os_draw_picture(mapper[i].pic1, gos_lower, Point(x + delta, y + height1));
+ os_draw_picture(mapper[i].pic2, gos_lower, Point(x + width1 - width2 - delta, y + height1));
+ }
+ }
+
+ os_draw_picture(pic, gos_lower, Point(x, y));
+
+ if (_storyId == SHOGUN && pic == 3) {
+ glui32 height, width;
+
+ os_picture_data(59, &height, &width);
+ os_draw_picture(59, gos_lower, Point(h_screen_width - width + 1, y));
+ }
+#endif
+}
+
+void Processor::z_picture_data() {
+#ifdef TODO
+ zword pic = zargs[0];
+ zword table = zargs[1];
+
+ int height, width;
+ int i;
+
+ bool avail = os_picture_data(pic, &height, &width);
+
+ for (i = 0; mapper[i].story_id != UNKNOWN; i++)
+
+ if (story_id == mapper[i].story_id) {
+
+ if (pic == mapper[i].pic) {
+
+ int height2, width2;
+
+ avail &= os_picture_data(mapper[i].pic1, &height2, &width2);
+ avail &= os_picture_data(mapper[i].pic2, &height2, &width2);
+
+ height += height2;
+
+ }
+ else if (pic == mapper[i].pic1 || pic == mapper[i].pic2)
+
+ avail = FALSE;
+ }
+
+ storew((zword)(table + 0), (zword)(height));
+ storew((zword)(table + 2), (zword)(width));
+
+ branch(avail);
+#endif
+}
+
+void Processor::z_erase_picture() {
+#ifdef TODO
+ int height, width;
+
+ zword y = zargs[1];
+ zword x = zargs[2];
+
+ flush_buffer();
+
+ /* Do nothing if the background is transparent */
+
+ if (hi(cwp->colour) == TRANSPARENT_COLOUR)
+ return;
+
+ if (y == 0) /* use cursor line if y-coordinate is 0 */
+ y = cwp->y_cursor;
+ if (x == 0) /* use cursor column if x-coordinate is 0 */
+ x = cwp->x_cursor;
+
+ os_picture_data(zargs[0], &height, &width);
+
+ y += cwp->y_pos - 1;
+ x += cwp->x_pos - 1;
+
+ os_erase_area(y, x, y + height - 1, x + width - 1, -1);
+#endif
+}
+
+void Processor::z_set_margins() {
+#ifdef TODO
+ zword win = winarg2();
+
+ flush_buffer();
+
+ wp[win].left = zargs[0];
+ wp[win].right = zargs[1];
+
+ /* Protect the margins */
+
+ if (wp[win].x_cursor <= zargs[0] || wp[win].x_cursor > wp[win].x_size - zargs[1]) {
+
+ wp[win].x_cursor = zargs[0] + 1;
+
+ if (win == cwin)
+ update_cursor();
+
+ }
+#endif
+}
+
+void Processor::z_move_window(void) {
+#ifdef TODO
+ zword win = winarg0();
+
+ flush_buffer();
+
+ wp[win].y_pos = zargs[1];
+ wp[win].x_pos = zargs[2];
+
+ if (win == cwin)
+ update_cursor();
+#endif
+}
+
+void Processor::z_window_size() {
+#ifdef TODO
+ zword win = winarg0();
+
+ flush_buffer();
+
+ wp[win].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])
+ reset_cursor(win);
+
+ os_window_height(win, wp[win].y_size);
+#endif
+}
+
+void Processor::z_window_style() {
+#ifdef TODO
+ zword win = winarg0();
+ zword flags = zargs[1];
+
+ flush_buffer();
+
+ /* Supply default arguments */
+
+ if (zargc < 3)
+ zargs[2] = 0;
+
+ /* Set window style */
+
+ switch (zargs[2]) {
+ case 0: wp[win].attribute = flags; break;
+ case 1: wp[win].attribute |= flags; break;
+ case 2: wp[win].attribute &= ~flags; break;
+ case 3: wp[win].attribute ^= flags; break;
+ }
+
+ if (cwin == win)
+ update_attributes();
+#endif
+}
+
+void Processor::z_get_wind_prop() {
+#ifdef TODO
+ flush_buffer();
+
+ if (zargs[1] < 16)
+ store(((zword *)(wp + winarg0()))[zargs[1]]);
+
+ else if (zargs[1] == 16)
+ store(os_to_true_colour(lo(wp[winarg0()].colour)));
+
+ else if (zargs[1] == 17) {
+
+ zword bg = hi(wp[winarg0()].colour);
+
+ if (bg == TRANSPARENT_COLOUR)
+ store((zword)-4);
+ else
+ store(os_to_true_colour(bg));
+
+ }
+ else
+ runtime_error(ERR_ILL_WIN_PROP);
+#endif
+}
+
+void Processor::z_put_wind_prop() {
+#ifdef TODO
+ flush_buffer();
+
+ if (zargs[1] >= 16)
+ runtime_error(ERR_ILL_WIN_PROP);
+
+ ((zword *)(wp + winarg0()))[zargs[1]] = zargs[2];
+#endif
+}
+
+void Processor::z_scroll_window() {
+#ifdef TODO
+ zword win = winarg0();
+ zword y, x;
+
+ flush_buffer();
+
+ /* Use the correct set of colours when scrolling the window */
+
+ if (win != cwin && !amiga_screen_model())
+ os_set_colour(lo(wp[win].colour), hi(wp[win].colour));
+
+ y = wp[win].y_pos;
+ x = wp[win].x_pos;
+
+ os_scroll_area(y,
+ x,
+ y + wp[win].y_size - 1,
+ x + wp[win].x_size - 1,
+ (short)zargs[1]);
+
+ if (win != cwin && !amiga_screen_model())
+ os_set_colour(lo(cwp->colour), hi(cwp->colour));
+#endif
+}
+
+void Processor::z_mouse_window() {
+#ifdef TODO
+ mwin = ((short)zargs[0] == -1) ? -1 : winarg0();
+#endif
+}
+
+void Processor::z_picture_table() {
+ /* This opcode is used by Shogun and Zork Zero when the player
+ * encounters built-in games such as Peggleboz. Nowadays it is
+ * not very helpful to hold the picture data in memory because
+ * even a small disk cache avoids re-loading of data.
+ */
+}
+
+} // End of namespace Scott
+} // End of namespace Glk
diff --git a/engines/glk/module.mk b/engines/glk/module.mk
index 003f8dcb6e..dd0c2a4b37 100644
--- a/engines/glk/module.mk
+++ b/engines/glk/module.mk
@@ -39,6 +39,7 @@ MODULE_OBJS := \
frotz/processor_table.o \
frotz/processor_text.o \
frotz/processor_variables.o \
+ frotz/processor_windows.o \
frotz/quetzal.o \
frotz/screen.o \
scott/detection.o \