aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--engines/glk/frotz/glk_interface.cpp31
-rw-r--r--engines/glk/frotz/glk_interface.h7
-rw-r--r--engines/glk/frotz/pics.cpp67
-rw-r--r--engines/glk/frotz/pics.h14
-rw-r--r--engines/glk/frotz/pics_decoder.cpp34
-rw-r--r--engines/glk/frotz/pics_decoder.h47
-rw-r--r--engines/glk/module.mk1
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 \