aboutsummaryrefslogtreecommitdiff
path: root/engines/glk/streams.h
diff options
context:
space:
mode:
Diffstat (limited to 'engines/glk/streams.h')
-rw-r--r--engines/glk/streams.h639
1 files changed, 639 insertions, 0 deletions
diff --git a/engines/glk/streams.h b/engines/glk/streams.h
new file mode 100644
index 0000000000..24ecc68eb5
--- /dev/null
+++ b/engines/glk/streams.h
@@ -0,0 +1,639 @@
+/* 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_STREAMS_H
+#define GLK_STREAMS_H
+
+#include "common/scummsys.h"
+#include "common/file.h"
+#include "common/savefile.h"
+#include "common/str.h"
+#include "glk/glk_types.h"
+
+namespace Gargoyle {
+
+#define SAVEGAME_VERSION 1
+
+class Window;
+class Streams;
+
+enum FileUsage {
+ fileusage_Data = 0x00,
+ fileusage_SavedGame = 0x01,
+ fileusage_Transcript = 0x02,
+ fileusage_InputRecord = 0x03,
+ fileusage_TypeMask = 0x0f,
+
+ fileusage_TextMode = 0x100,
+ fileusage_BinaryMode = 0x000
+};
+
+enum FileMode {
+ filemode_Write = 0x01,
+ filemode_Read = 0x02,
+ filemode_ReadWrite = 0x03,
+ filemode_WriteAppend = 0x05
+};
+
+enum SeekMode {
+ seekmode_Start = 0,
+ seekmode_Current = 1,
+ seekmode_End = 2
+};
+
+struct StreamResult {
+ uint32 _readCount;
+ uint32 _writeCount;
+};
+typedef StreamResult stream_result_t;
+
+struct SavegameHeader {
+ uint8 _version;
+ byte _interpType;
+ byte _language;
+ Common::String _md5;
+ Common::String _saveName;
+ int _year, _month, _day;
+ int _hour, _minute;
+ int _totalFrames;
+
+ /**
+ * Constructor
+ */
+ SavegameHeader() : _version(0), _interpType(0), _language(0), _year(0), _month(0), _day(0),
+ _hour(0), _minute(0), _totalFrames(0) {}
+};
+
+/**
+ * File details
+ */
+struct FileReference {
+ glui32 _rock;
+ int _slotNumber;
+ Common::String _description;
+ Common::String _filename;
+ FileUsage _fileType;
+ bool _textMode;
+ gidispatch_rock_t _dispRock;
+
+ /**
+ * Constructor
+ */
+ FileReference() : _rock(0), _slotNumber(-1), _fileType(fileusage_Data), _textMode(false) {}
+
+ /**
+ * Constructor
+ */
+ FileReference(int slot, const Common::String &desc, glui32 usage, glui32 rock = 0) :
+ _rock(rock), _slotNumber(slot), _description(desc),
+ _fileType((FileUsage)(usage & fileusage_TypeMask)), _textMode(usage & fileusage_TextMode) {}
+
+ /**
+ * Get savegame filename
+ */
+ const Common::String getSaveName() const;
+
+ /**
+ * Returns true if the given file exists
+ */
+ bool exists() const;
+
+ /**
+ * Delete the given file
+ */
+ void deleteFile();
+};
+
+typedef FileReference *frefid_t;
+typedef Common::Array< Common::SharedPtr<FileReference> > FileRefArray;
+
+
+/**
+ * Base class for streams
+ */
+class Stream {
+public:
+ Streams *_streams;
+ Stream *_prev;
+ Stream *_next;
+ uint32 _rock;
+ bool _unicode;
+ uint32 _readCount;
+ uint32 _writeCount;
+ bool _readable, _writable;
+public:
+ /**
+ * Constructor
+ */
+ Stream(Streams *streams, bool readable, bool writable, uint32 rock, bool unicode);
+
+ /**
+ * Destructor
+ */
+ virtual ~Stream();
+
+ /**
+ * Get the next stream
+ */
+ Stream *getNext(uint32 *rock) const;
+
+ /**
+ * Get the rock value for the stream
+ */
+ uint32 getRock() const {
+ return _rock;
+ }
+
+ /**
+ * Fill out the total amount read and/or written
+ */
+ void fillResult(StreamResult *result);
+
+ /**
+ * Close and delete the stream
+ */
+ void close(StreamResult *result = nullptr);
+
+ /**
+ * Write a character
+ */
+ virtual void putChar(unsigned char ch) = 0;
+
+ /**
+ * Write a unicode character
+ */
+ virtual void putCharUni(uint32 ch) = 0;
+
+ /**
+ * Write a buffer
+ */
+ virtual void putBuffer(const char *buf, size_t len) = 0;
+
+ /**
+ * Write a unicode character
+ */
+ virtual void putBufferUni(const uint32 *buf, size_t len) = 0;
+
+ /**
+ * Remove a string from the end of the stream, if indeed it is at the end
+ */
+ virtual void unputBuffer(const char *buf, size_t len) {}
+
+ /**
+ * Remove a string from the end of the stream, if indeed it is at the end
+ */
+ virtual void unputBufferUni(const glui32 *buf, size_t len) {}
+
+ /**
+ * Send a line to the stream with a trailing newline
+ */
+ void echoLine(char *buf, glui32 len) {
+ putBuffer(buf, len);
+ putChar('\n');
+ };
+
+ /**
+ * Send a line to the stream with a trailing newline
+ */
+ void echoLineUni(glui32 *buf, glui32 len) {
+ putBufferUni(buf, len);
+ putCharUni('\n');
+ }
+
+ virtual glui32 getPosition() const {
+ return 0;
+ }
+
+ virtual void setPosition(glsi32 pos, glui32 seekMode) {}
+
+ virtual void setStyle(glui32 val) {}
+
+ /**
+ * Get a character from the stream
+ */
+ virtual glsi32 getChar() {
+ return -1;
+ }
+
+ /**
+ * Get a unicode character from the stream
+ */
+ virtual glsi32 getCharUni() {
+ return -1;
+ }
+
+ /**
+ * Get a buffer
+ */
+ virtual glui32 getBuffer(char *buf, glui32 len) {
+ return 0;
+ }
+
+ /**
+ * Get a unicode buffer
+ */
+ virtual glui32 getBufferUni(glui32 *buf, glui32 len) {
+ return 0;
+ }
+
+ /**
+ * Get a line
+ */
+ virtual glui32 getLine(char *buf, glui32 len) {
+ return 0;
+ }
+
+ /**
+ * Get a unicode line
+ */
+ virtual glui32 getLineUni(glui32 *ubuf, glui32 len) {
+ return 0;
+ }
+
+ /**
+ * Set a hyperlink
+ */
+ virtual void setHyperlink(glui32 linkVal) {}
+
+ /**
+ * Set the style colors
+ */
+ virtual void setZColors(glui32 fg, glui32 bg);
+
+ /**
+ * Set the reverse video style
+ */
+ virtual void setReverseVideo(bool reverse);
+};
+typedef Stream *strid_t;
+
+/**
+ * Implements the stream for writing text to a window
+ */
+class WindowStream : public Stream {
+private:
+ Window *_window;
+public:
+ /**
+ * Constructor
+ */
+ WindowStream(Streams *streams, Window *window, uint32 rock = 0, bool unicode = true) :
+ Stream(streams, false, true, rock, unicode), _window(window) {}
+
+ /**
+ * Close the stream
+ */
+ virtual void close(StreamResult *result = nullptr);
+
+ /**
+ * Write a character
+ */
+ virtual void putChar(unsigned char ch) override;
+
+ /**
+ * Write a unicode character
+ */
+ virtual void putCharUni(uint32 ch) override;
+
+ /**
+ * Write a buffer
+ */
+ virtual void putBuffer(const char *buf, size_t len) override;
+
+ /**
+ * Write a unicode character
+ */
+ virtual void putBufferUni(const uint32 *buf, size_t len) override;
+
+ /**
+ * Remove a string from the end of the stream, if indeed it is at the end
+ */
+ virtual void unputBuffer(const char *buf, size_t len) override;
+
+ /**
+ * Remove a string from the end of the stream, if indeed it is at the end
+ */
+ virtual void unputBufferUni(const glui32 *buf, size_t len) override;
+
+ virtual void setStyle(glui32 val) override;
+
+ /**
+ * Set a hyperlink
+ */
+ virtual void setHyperlink(glui32 linkVal) override;
+
+ /**
+ * Set the style colors
+ */
+ virtual void setZColors(glui32 fg, glui32 bg) override;
+
+ /**
+ * Set the reverse video style
+ */
+ virtual void setReverseVideo(bool reverse) override;
+};
+
+/**
+ * Implements an in-memory stream
+ */
+class MemoryStream : public Stream {
+private:
+ void *_buf; ///< unsigned char* for latin1, glui32* for unicode
+ void *_bufPtr;
+ void *_bufEnd;
+ void *_bufEof;
+ size_t _bufLen; ///< # of bytes for latin1, # of 4-byte words for unicode
+public:
+ /**
+ * Constructor
+ */
+ MemoryStream(Streams *streams, void *buf, size_t buflen, FileMode mode, uint32 rock = 0, bool unicode = true);
+
+ /**
+ * Write a character
+ */
+ virtual void putChar(unsigned char ch) override;
+
+ /**
+ * Write a unicode character
+ */
+ virtual void putCharUni(uint32 ch) override;
+
+ /**
+ * Write a buffer
+ */
+ virtual void putBuffer(const char *buf, size_t len) override;
+
+ /**
+ * Write a unicode character
+ */
+ virtual void putBufferUni(const uint32 *buf, size_t len) override;
+
+ virtual glui32 getPosition() const override;
+
+ virtual void setPosition(glsi32 pos, glui32 seekMode) override;
+
+ /**
+ * Get a character from the stream
+ */
+ virtual glsi32 getChar() override;
+
+ /**
+ * Get a unicode character from the stream
+ */
+ virtual glsi32 getCharUni() override;
+
+ /**
+ * Get a buffer
+ */
+ virtual glui32 getBuffer(char *buf, glui32 len) override;
+
+ /**
+ * Get a unicode buffer
+ */
+ virtual glui32 getBufferUni(glui32 *buf, glui32 len) override;
+
+ /**
+ * Get a line
+ */
+ virtual glui32 getLine(char *buf, glui32 len) override;
+
+ /**
+ * Get a unicode line
+ */
+ virtual glui32 getLineUni(glui32 *ubuf, glui32 len) override;
+};
+
+/**
+ * Implements a file stream
+ */
+class FileStream : public Stream {
+private:
+ Common::File _file;
+ Common::OutSaveFile *_outFile;
+ Common::InSaveFile *_inFile;
+ Common::SeekableReadStream *_inStream;
+ uint32 _lastOp; ///< 0, filemode_Write, or filemode_Read
+ bool _textFile;
+private:
+ /**
+ * Ensure the stream is ready for the given operation
+ */
+ void ensureOp(FileMode mode);
+
+ /**
+ * Put a UTF8 character
+ */
+ void putCharUtf8(glui32 val);
+
+ /**
+ * Get a UTF8 character
+ */
+ glsi32 getCharUtf8();
+public:
+ /**
+ * Read a savegame header from a stream
+ */
+ static bool readSavegameHeader(Common::SeekableReadStream *stream, SavegameHeader &header);
+
+ /**
+ * Write out a savegame header
+ */
+ static void writeSavegameHeader(Common::WriteStream *stream, const Common::String &saveName);
+public:
+ /**
+ * Constructor
+ */
+ FileStream(Streams *streams, frefid_t fref, glui32 fmode, glui32 rock, bool unicode);
+
+ /**
+ * Destructor
+ */
+ virtual ~FileStream();
+
+ /**
+ * Write a character
+ */
+ virtual void putChar(unsigned char ch) override;
+
+ /**
+ * Write a unicode character
+ */
+ virtual void putCharUni(uint32 ch) override;
+
+ /**
+ * Write a buffer
+ */
+ virtual void putBuffer(const char *buf, size_t len) override;
+
+ /**
+ * Write a unicode character
+ */
+ virtual void putBufferUni(const uint32 *buf, size_t len) override;
+
+ virtual glui32 getPosition() const override;
+
+ virtual void setPosition(glsi32 pos, glui32 seekMode) override;
+
+ /**
+ * Get a character from the stream
+ */
+ virtual glsi32 getChar() override;
+
+ /**
+ * Get a unicode character from the stream
+ */
+ virtual glsi32 getCharUni() override;
+
+ /**
+ * Get a buffer
+ */
+ virtual glui32 getBuffer(char *buf, glui32 len) override;
+
+ /**
+ * Get a unicode buffer
+ */
+ virtual glui32 getBufferUni(glui32 *buf, glui32 len) override;
+
+ /**
+ * Get a line
+ */
+ virtual glui32 getLine(char *buf, glui32 len) override;
+
+ /**
+ * Get a unicode line
+ */
+ virtual glui32 getLineUni(glui32 *ubuf, glui32 len) override;
+};
+
+/**
+ * Streams manager
+ */
+class Streams {
+ friend class Stream;
+private:
+ Stream *_streamList;
+ Stream *_currentStream;
+ FileRefArray _fileReferences;
+private:
+ /**
+ * Adds a created stream to the list
+ */
+ void addStream(Stream *stream);
+
+ /**
+ * Remove a stream
+ */
+ void removeStream(Stream *stream);
+public:
+ /**
+ * Constructor
+ */
+ Streams();
+
+ /**
+ * Destructor
+ */
+ ~Streams();
+
+ /**
+ * Open a file stream
+ */
+ FileStream *openFileStream(frefid_t fref, glui32 fmode, glui32 rock, bool unicode);
+
+ /**
+ * Open a window stream
+ */
+ WindowStream *openWindowStream(Window *window);
+
+ /**
+ * Open a memory stream
+ */
+ MemoryStream *openMemoryStream(void *buf, size_t buflen, FileMode mode, uint32 rock = 0, bool unicode = true);
+
+ /**
+ * Delete a stream
+ */
+ void deleteStream(Stream *stream) {
+ delete stream;
+ }
+
+ /**
+ * Start an Iteration through streams
+ */
+ Stream *getFirst(uint32 *rock);
+
+ /**
+ * Set the current output stream
+ */
+ void setCurrent(Stream *stream) {
+ assert(stream->_writable);
+ _currentStream = stream;
+ }
+
+ /**
+ * Gets the current output stream
+ */
+ Stream *getCurrent() const {
+ return _currentStream;
+ }
+
+ /**
+ * Prompt for a savegame to load or save, and populate a file reference from the result
+ */
+ frefid_t createByPrompt(glui32 usage, FileMode fmode, glui32 rock);
+
+ /**
+ * Create a new file reference
+ */
+ frefid_t createRef(int slot, const Common::String &desc, glui32 usage, glui32 rock);
+
+ /**
+ * Create a new file reference
+ */
+ frefid_t createRef(const Common::String &filename, glui32 usage, glui32 rock);
+
+ /**
+ * Create a new temporary file reference
+ */
+ frefid_t createTemp(glui32 usage, glui32 rock);
+
+ /**
+ * Create a new file reference from an old one
+ */
+ frefid_t createFromRef(frefid_t fref, glui32 usage, glui32 rock);
+
+ /**
+ * Delete a file reference
+ */
+ void deleteRef(frefid_t fref);
+
+ /**
+ * Iterates to the next file reference following the specified one,
+ * or the first if null is passed
+ */
+ frefid_t iterate(frefid_t fref, glui32 *rock);
+};
+
+} // End of namespace Gargoyle
+
+#endif