diff options
author | Paul Gilbert | 2018-11-03 18:46:44 -0700 |
---|---|---|
committer | Paul Gilbert | 2018-12-08 19:05:59 -0800 |
commit | db112fc9f02e2a49b47a62d85f4920332b285728 (patch) | |
tree | 5ef02362dbfbc26d73dd93b728131d875e02734f /engines/gargoyle | |
parent | 60146c383d4b69920c6ba326611f9de66a513529 (diff) | |
download | scummvm-rg350-db112fc9f02e2a49b47a62d85f4920332b285728.tar.gz scummvm-rg350-db112fc9f02e2a49b47a62d85f4920332b285728.tar.bz2 scummvm-rg350-db112fc9f02e2a49b47a62d85f4920332b285728.zip |
GLK: Adding file stream opening and closing
Diffstat (limited to 'engines/gargoyle')
-rw-r--r-- | engines/gargoyle/events.h | 10 | ||||
-rw-r--r-- | engines/gargoyle/glk.cpp | 10 | ||||
-rw-r--r-- | engines/gargoyle/glk.h | 1 | ||||
-rw-r--r-- | engines/gargoyle/streams.cpp | 106 | ||||
-rw-r--r-- | engines/gargoyle/streams.h | 50 | ||||
-rw-r--r-- | engines/gargoyle/windows.cpp | 2 |
6 files changed, 157 insertions, 22 deletions
diff --git a/engines/gargoyle/events.h b/engines/gargoyle/events.h index 3860dc25f4..70e7af4cdf 100644 --- a/engines/gargoyle/events.h +++ b/engines/gargoyle/events.h @@ -215,6 +215,16 @@ public: * Wait for a keyboard or mouse press */ void waitForPress(); + + /** + * Get the total number of frames played + */ + uint32 getTotalPlayTicks() const { return _frameCounter; } + + /** + * Set the total number of frames played + */ + void Events::setTotalPlayTicks(uint frames) { _frameCounter = frames; } }; } // End of namespace Gargoyle diff --git a/engines/gargoyle/glk.cpp b/engines/gargoyle/glk.cpp index f386f2280c..fb140a3390 100644 --- a/engines/gargoyle/glk.cpp +++ b/engines/gargoyle/glk.cpp @@ -331,12 +331,11 @@ void Glk::glk_set_window(winid_t win) { } strid_t Glk::glk_stream_open_file(frefid_t fileref, FileMode fmode, glui32 rock) { - // TODO - return nullptr; + return _streams->openFileStream(fileref, fmode, rock, false); } strid_t Glk::glk_stream_open_memory(char *buf, glui32 buflen, FileMode fmode, glui32 rock) { - return _streams->addMemoryStream(buf, buflen, fmode, rock, false); + return _streams->openMemoryStream(buf, buflen, fmode, rock, false); } void Glk::glk_stream_close(strid_t str, stream_result_t *result) { @@ -847,12 +846,11 @@ glui32 Glk::glk_get_line_stream_uni(strid_t str, glui32 *buf, glui32 len) { } strid_t Glk::glk_stream_open_file_uni(frefid_t fileref, FileMode fmode, glui32 rock) { - // TODO - return nullptr; + return _streams->openFileStream(fileref, fmode, rock, true); } strid_t Glk::glk_stream_open_memory_uni(glui32 *buf, glui32 buflen, FileMode fmode, glui32 rock) { - return _streams->addMemoryStream(buf, buflen, fmode, rock, true); + return _streams->openMemoryStream(buf, buflen, fmode, rock, true); } void Glk::glk_request_char_event_uni(winid_t win) { diff --git a/engines/gargoyle/glk.h b/engines/gargoyle/glk.h index bef6280971..7312a35d8e 100644 --- a/engines/gargoyle/glk.h +++ b/engines/gargoyle/glk.h @@ -24,7 +24,6 @@ #define GARGOYLE_GLK_H #include "gargoyle/gargoyle.h" -#include "gargoyle/files.h" #include "gargoyle/glk_types.h" #include "gargoyle/time.h" #include "gargoyle/windows.h" diff --git a/engines/gargoyle/streams.cpp b/engines/gargoyle/streams.cpp index 93335b9c0e..99ced12ce1 100644 --- a/engines/gargoyle/streams.cpp +++ b/engines/gargoyle/streams.cpp @@ -508,11 +508,47 @@ glui32 MemoryStream::getLineUni(glui32 *ubuf, glui32 len) { /*--------------------------------------------------------------------------*/ -FileStream::FileStream(Streams *streams, uint32 rock, bool unicode) : - Stream(streams, true, false, rock, unicode), _lastOp(0), _textFile(false) { - // TODO: Set up files - _outFile = nullptr; - _inFile = nullptr; +FileStream::FileStream(Streams *streams, frefid_t fref, glui32 fmode, glui32 rock, bool unicode) : + Stream(streams, true, false, rock, unicode), _lastOp(0), _textFile(false), + _inFile(nullptr), _outFile(nullptr), _inStream(nullptr) { + Common::String fname = fref->_slotNumber == -1 ? fref->_filename : fref->getSaveName(); + + if (fmode == filemode_Write || fmode == filemode_ReadWrite || fmode == filemode_WriteAppend) { + _outFile = g_system->getSavefileManager()->openForSaving(fname, fref->_slotNumber != -1); + if (!_outFile) + error("Could open file for writing - %s", fname.c_str()); + + if (fref->_slotNumber != -1) + writeSavegameHeader(_outFile, fref->_description); + } else if (fmode == filemode_Read) { + if (_file.open(fname)) { + _inStream = &_file; + } else { + _inFile = g_system->getSavefileManager()->openForLoading(fname); + _inStream = _inFile; + } + + if (!_inStream) + error("Could not open for reading - %s", fname.c_str()); + + if (_inFile) { + // It's a save file, so skip over the header + SavegameHeader header; + if (!readSavegameHeader(_inStream, header)) + error("Invalid savegame"); + + g_vm->_events->setTotalPlayTicks(header._totalFrames); + } + } +} + +FileStream::~FileStream() { + _file.close(); + delete _inFile; + if (_outFile) { + _outFile->finalize(); + delete _outFile; + } } void FileStream::ensureOp(FileMode mode) { @@ -798,7 +834,6 @@ glsi32 FileStream::getCharUni() { } } - glui32 FileStream::getBufferUni(glui32 *buf, glui32 len) { if (!_readable) return 0; @@ -926,6 +961,55 @@ glui32 FileStream::getLineUni(glui32 *ubuf, glui32 len) { } } +bool FileStream::readSavegameHeader(Common::SeekableReadStream *stream, SavegameHeader &header) { + header._totalFrames = 0; + + // Validate the header Id + if (stream->readUint32BE() != MKTAG('G', 'A', 'R', 'G')) + return false; + + // Check the savegame version + header._version = stream->readByte(); + if (header._version > SAVEGAME_VERSION) + error("Savegame is too recent"); + + // Read in name + char c; + while ((c = stream->readByte()) != '\0') + header._saveName += c; + + // Read in save date/time + header._year = stream->readUint16LE(); + header._month = stream->readUint16LE(); + header._day = stream->readUint16LE(); + header._hour = stream->readUint16LE(); + header._minute = stream->readUint16LE(); + header._totalFrames = stream->readUint32LE(); + + return true; +} + +void FileStream::writeSavegameHeader(Common::WriteStream *stream, const Common::String &saveName) { + // Write out a savegame header + stream->writeUint32BE(MKTAG('G', 'A', 'R', 'G')); + + stream->writeByte(SAVEGAME_VERSION); + + // Write savegame name + stream->write(saveName.c_str(), saveName.size()); + stream->writeByte('\0'); + + // Write out the save date/time + TimeDate td; + g_system->getTimeAndDate(td); + stream->writeUint16LE(td.tm_year + 1900); + stream->writeUint16LE(td.tm_mon + 1); + stream->writeUint16LE(td.tm_mday); + stream->writeUint16LE(td.tm_hour); + stream->writeUint16LE(td.tm_min); + stream->writeUint32LE(g_vm->_events->getTotalPlayTicks()); +} + /*--------------------------------------------------------------------------*/ Streams::Streams() : _streamList(nullptr), _currentStream(nullptr) { @@ -936,13 +1020,19 @@ Streams::~Streams() { delete _streamList; } -WindowStream *Streams::addWindowStream(Window *window) { +FileStream *Streams::openFileStream(frefid_t fref, glui32 fmode, glui32 rock, bool unicode) { + FileStream *stream = new FileStream(this, fref, fmode, rock, unicode); + addStream(stream); + return stream; +} + +WindowStream *Streams::openWindowStream(Window *window) { WindowStream *stream = new WindowStream(this, window); addStream(stream); return stream; } -MemoryStream *Streams::addMemoryStream(void *buf, size_t buflen, FileMode mode, uint32 rock, bool unicode) { +MemoryStream *Streams::openMemoryStream(void *buf, size_t buflen, FileMode mode, uint32 rock, bool unicode) { MemoryStream *stream = new MemoryStream(this, buf, buflen, mode, rock, unicode); addStream(stream); return stream; diff --git a/engines/gargoyle/streams.h b/engines/gargoyle/streams.h index 264190cc76..517192af3f 100644 --- a/engines/gargoyle/streams.h +++ b/engines/gargoyle/streams.h @@ -24,12 +24,15 @@ #define GARGOYLE_STREAMS_H #include "common/scummsys.h" +#include "common/file.h" #include "common/savefile.h" -#include "gargoyle/files.h" +#include "common/str.h" #include "gargoyle/glk_types.h" namespace Gargoyle { +#define SAVEGAME_VERSION 1 + class Window; class Streams; @@ -63,6 +66,19 @@ struct StreamResult { }; typedef StreamResult stream_result_t; +struct SavegameHeader { + uint8 _version; + Common::String _saveName; + int _year, _month, _day; + int _hour, _minute; + int _totalFrames; + + /** + * Constructor + */ + SavegameHeader() : _version(0), _year(0), _month(0), _day(0), _hour(0), + _minute(0), _totalFrames(0) {} +}; /** * File details @@ -326,8 +342,10 @@ public: */ 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: @@ -347,9 +365,24 @@ private: 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, uint32 rock = 0, bool unicode = true); + FileStream(Streams *streams, frefid_t fref, glui32 fmode, glui32 rock, bool unicode); + + /** + * Destructor + */ + virtual ~FileStream(); /** * Write a character @@ -427,14 +460,19 @@ public: ~Streams(); /** - * Add a window stream + * Open a file stream + */ + FileStream *openFileStream(frefid_t fref, glui32 fmode, glui32 rock, bool unicode); + + /** + * Open a window stream */ - WindowStream *addWindowStream(Window *window); + WindowStream *openWindowStream(Window *window); /** - * Add a memory stream + * Open a memory stream */ - MemoryStream *addMemoryStream(void *buf, size_t buflen, FileMode mode, uint32 rock = 0, bool unicode = true); + MemoryStream *openMemoryStream(void *buf, size_t buflen, FileMode mode, uint32 rock = 0, bool unicode = true); /** * Delete a stream diff --git a/engines/gargoyle/windows.cpp b/engines/gargoyle/windows.cpp index 89118819fa..b0f1cd7562 100644 --- a/engines/gargoyle/windows.cpp +++ b/engines/gargoyle/windows.cpp @@ -502,7 +502,7 @@ Window::Window(Windows *windows, glui32 rock) : _windows(windows), _rock(rock), _dispRock.num = 0; Streams &streams = *g_vm->_streams; - _stream = streams.addWindowStream(this); + _stream = streams.openWindowStream(this); } Window::~Window() { |