diff options
author | Paul Gilbert | 2018-11-23 17:07:33 -0800 |
---|---|---|
committer | Paul Gilbert | 2018-12-08 19:05:59 -0800 |
commit | a334cd704e21044e0660f918e1c9e3a5040c5837 (patch) | |
tree | a0859b95f06a7d5eae26e0a04f2f4370be84b320 | |
parent | 6f508124937df1b0cda5a2732039a82c4ec16b85 (diff) | |
download | scummvm-rg350-a334cd704e21044e0660f918e1c9e3a5040c5837.tar.gz scummvm-rg350-a334cd704e21044e0660f918e1c9e3a5040c5837.tar.bz2 scummvm-rg350-a334cd704e21044e0660f918e1c9e3a5040c5837.zip |
GLK: FROTZ: Further loading of Infocom pictures files
-rw-r--r-- | engines/glk/frotz/glk_interface.cpp | 31 | ||||
-rw-r--r-- | engines/glk/frotz/glk_interface.h | 7 | ||||
-rw-r--r-- | engines/glk/frotz/pics.cpp | 67 | ||||
-rw-r--r-- | engines/glk/frotz/pics.h | 14 | ||||
-rw-r--r-- | engines/glk/frotz/pics_decoder.cpp | 34 | ||||
-rw-r--r-- | engines/glk/frotz/pics_decoder.h | 47 | ||||
-rw-r--r-- | engines/glk/module.mk | 1 |
7 files changed, 172 insertions, 29 deletions
diff --git a/engines/glk/frotz/glk_interface.cpp b/engines/glk/frotz/glk_interface.cpp index 2790e3009d..4e7a503d82 100644 --- a/engines/glk/frotz/glk_interface.cpp +++ b/engines/glk/frotz/glk_interface.cpp @@ -96,11 +96,17 @@ void GlkInterface::initialize() { glk_stylehint_set(wintype_AllTypes, style_Note, stylehint_Weight, 1); glk_stylehint_set(wintype_AllTypes, style_Note, stylehint_Oblique, 1); + /* + * Open game windows + */ + if (_storyId == BEYOND_ZORK) + showBeyondZorkTitle(); + gos_lower = glk_window_open(0, 0, 0, wintype_TextGrid, 0); if (!gos_lower) gos_lower = glk_window_open(0, 0, 0, wintype_TextBuffer, 0); glk_window_get_size(gos_lower, &width, &height); - glk_window_close(gos_lower, NULL); + glk_window_close(gos_lower, nullptr); gos_lower = glk_window_open(0, 0, 0, wintype_TextBuffer, 0); gos_upper = glk_window_open(gos_lower, @@ -108,7 +114,7 @@ void GlkInterface::initialize() { 0, wintype_TextGrid, 0); - gos_channel = NULL; + gos_channel = nullptr; glk_set_window(gos_lower); gos_curwin = gos_lower; @@ -441,18 +447,17 @@ void GlkInterface::gos_cancel_pending_line() { gos_linepending = 0; } -void GlkInterface::os_restart_game(RestartAction stage) { - // Show Beyond Zork's title screen - if ((stage == RESTART_END) && (_storyId == BEYOND_ZORK)) { -/* - uint w, h; - if (os_picture_data(1, &h, &w)) { - _screen->clear(); - os_draw_picture(1, Common::Point(1, 1)); - _events->waitForPress(); - } - */ +void GlkInterface::showBeyondZorkTitle() { + uint winW, winH, imgW, imgH; + winid_t win = glk_window_open(0, 0, 0, wintype_TextGrid, 0); + glk_window_get_size(gos_lower, &winW, &winH); + + if (os_picture_data(1, &imgW, &imgH)) { + os_draw_picture(1, win, Common::Point(1, 1)); + _events->waitForPress(); } + + glk_window_close(win, nullptr); } void GlkInterface::os_draw_picture(int picture, winid_t win, const Common::Point &pos) { diff --git a/engines/glk/frotz/glk_interface.h b/engines/glk/frotz/glk_interface.h index 0dc88466f2..b279ec87a3 100644 --- a/engines/glk/frotz/glk_interface.h +++ b/engines/glk/frotz/glk_interface.h @@ -100,6 +100,11 @@ private: * Loads the pictures file for Infocom V6 games */ bool initPictures(); + + /** + * Displays the title screen for the game Beyond Zork + */ + void showBeyondZorkTitle(); protected: /** * Return the length of the character in screen units. @@ -192,7 +197,7 @@ protected: /** * Called during game restarts */ - void os_restart_game(RestartAction stage); + void os_restart_game(RestartAction stage) {} /** * Reads the mouse buttons diff --git a/engines/glk/frotz/pics.cpp b/engines/glk/frotz/pics.cpp index 29d2ec5e52..976c2b2cde 100644 --- a/engines/glk/frotz/pics.cpp +++ b/engines/glk/frotz/pics.cpp @@ -21,7 +21,9 @@ */ #include "glk/frotz/pics.h" +#include "glk/frotz/pics_decoder.h" #include "glk/glk.h" +#include "common/algorithm.h" namespace Glk { namespace Frotz { @@ -38,21 +40,53 @@ Pics::Pics() : Common::Archive(), _filename(getFilename()) { if (!f.open(_filename)) error("Error reading Pics file"); + Common::Array<uint> offsets; byte buffer[16]; f.read(buffer, 16); _index.resize(READ_LE_UINT16(&buffer[PIC_FILE_HEADER_NUM_IMAGES])); _entrySize = buffer[PIC_FILE_HEADER_ENTRY_SIZE]; _version = buffer[PIC_FILE_HEADER_FLAGS]; + assert(_entrySize >= 6 && _entrySize <= 14); // Iterate through loading the index for (uint idx = 0; idx < _index.size(); ++idx) { Entry &e = _index[idx]; - e._number = f.readUint16LE(); - e._offset = f.pos(); - e._size = _entrySize - 2; - f.skip(_entrySize - 2); + f.read(buffer, _entrySize); + + e._number = READ_LE_UINT16(buffer); + e._width = READ_LE_UINT16(buffer + 2); + e._height = READ_LE_UINT16(buffer + 4); + + if (_entrySize >= 11) { + e._dataOffset = READ_BE_UINT32(buffer + 7) & 0xffffff; + if (e._dataOffset) + offsets.push_back(e._dataOffset); + + if (_entrySize == 14) { + e._paletteOffset = READ_BE_UINT32(buffer + 10) & 0xffffff; + e._paletteSize = e._dataOffset - e._paletteOffset; + assert((e._paletteSize % 3) == 0); + } + } - e._filename = Common::String::format("PIC%u", e._number); + e._filename = Common::String::format("pic%u.raw", e._number); + } + + // Further processing of index to calculate data sizes + Common::sort(offsets.begin(), offsets.end()); + + for (uint idx = 0; idx < _index.size(); ++idx) { + Entry &e = _index[idx]; + if (!e._dataOffset) + continue; + + // Find the entry in the offsets array + uint oidx = 0; + while (oidx < offsets.size() && offsets[oidx] != e._dataOffset) + ++oidx; + + // Set the size + e._dataSize = (oidx == (offsets.size() - 1) ? f.size() : offsets[oidx + 1]) - e._dataOffset; } f.close(); @@ -96,16 +130,27 @@ const Common::ArchiveMemberPtr Pics::getMember(const Common::String &name) const Common::SeekableReadStream *Pics::createReadStreamForMember(const Common::String &name) const { for (uint idx = 0; idx < _index.size(); ++idx) { - if (_index[idx]._filename.equalsIgnoreCase(name)) { + const Entry &e = _index[idx]; + if (e._filename.equalsIgnoreCase(name)) { Common::File f; if (!f.open(_filename)) error("Reading failed"); - f.seek(_index[idx]._offset); - Common::SeekableReadStream *result = f.readStream(_index[idx]._size); - f.close(); - - return result; + // Read in the image's palette + assert(e._paletteSize); + Common::Array<byte> palette; + palette.resize(e._paletteSize); + f.seek(e._paletteOffset); + f.read(&palette[0], e._paletteSize); + + if (e._dataSize) { + Common::SeekableReadStream *src = f.readStream(e._dataSize); + f.close(); + return PictureDecoder::decode(*src, &palette[0]); + + } else { + error("TODO: Empty rect renderings"); + } } } diff --git a/engines/glk/frotz/pics.h b/engines/glk/frotz/pics.h index 55e3c0dd03..b05acc5e9f 100644 --- a/engines/glk/frotz/pics.h +++ b/engines/glk/frotz/pics.h @@ -20,8 +20,8 @@ * */ -#ifndef GLK_FROTZ_PICS -#define GLK_FROTZ_PICS +#ifndef GLK_FROTZ_PICS_H +#define GLK_FROTZ_PICS_H #include "common/archive.h" #include "common/array.h" @@ -38,9 +38,15 @@ class Pics : public Common::Archive { */ struct Entry { uint _number; - size_t _offset; - size_t _size; + size_t _width, _height; + size_t _dataOffset; + size_t _dataSize; + size_t _paletteOffset; + size_t _paletteSize; Common::String _filename; + + Entry() : _number(0), _width(0), _height(0), _dataOffset(0), _dataSize(0), + _paletteOffset(0), _paletteSize(0) {} }; private: Common::String _filename; diff --git a/engines/glk/frotz/pics_decoder.cpp b/engines/glk/frotz/pics_decoder.cpp new file mode 100644 index 0000000000..a67ed12f0c --- /dev/null +++ b/engines/glk/frotz/pics_decoder.cpp @@ -0,0 +1,34 @@ +/* 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/pics_decoder.h" + +namespace Glk { +namespace Frotz { + +Common::MemoryReadStream *PictureDecoder::decode(Common::ReadStream &src, const byte *palette) { + // TODO + return nullptr; +} + +} // End of namespace Frotz +} // End of namespace Glk diff --git a/engines/glk/frotz/pics_decoder.h b/engines/glk/frotz/pics_decoder.h new file mode 100644 index 0000000000..41484a1ffd --- /dev/null +++ b/engines/glk/frotz/pics_decoder.h @@ -0,0 +1,47 @@ +/* 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. + * + */ + +#ifndef GLK_FROTZ_PICS_DECODER_H +#define GLK_FROTZ_PICS_DECODER_H + +#include "common/memstream.h" +#include "common/stream.h" + +namespace Glk { +namespace Frotz { + +/** + * Decodes an Infocom encoded picture into a raw pixel stream that the outer + * Glk engine is capable of then loading into a picture object + */ +class PictureDecoder { +public: + /** + * Decode method + */ + static Common::MemoryReadStream *decode(Common::ReadStream &src, const byte *palette); +}; + +} // End of namespace Frotz +} // End of namespace Glk + +#endif diff --git a/engines/glk/module.mk b/engines/glk/module.mk index a4344dfa6c..0206643f9b 100644 --- a/engines/glk/module.mk +++ b/engines/glk/module.mk @@ -28,6 +28,7 @@ MODULE_OBJS := \ frotz/glk_interface.o \ frotz/mem.o \ frotz/pics.o \ + frotz/pics_decoder.o \ frotz/processor.o \ frotz/processor_buffer.o \ frotz/processor_input.o \ |