diff options
-rw-r--r-- | engines/glk/frotz/config.cpp | 3 | ||||
-rw-r--r-- | engines/glk/frotz/processor.cpp | 28 | ||||
-rw-r--r-- | engines/glk/frotz/processor.h | 110 | ||||
-rw-r--r-- | engines/glk/frotz/processor_screen.cpp | 4 | ||||
-rw-r--r-- | engines/glk/frotz/processor_windows.cpp | 316 | ||||
-rw-r--r-- | engines/glk/module.mk | 1 |
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 \ |