aboutsummaryrefslogtreecommitdiff
path: root/engines/gargoyle
diff options
context:
space:
mode:
authorPaul Gilbert2018-11-03 18:46:44 -0700
committerPaul Gilbert2018-12-08 19:05:59 -0800
commitdb112fc9f02e2a49b47a62d85f4920332b285728 (patch)
tree5ef02362dbfbc26d73dd93b728131d875e02734f /engines/gargoyle
parent60146c383d4b69920c6ba326611f9de66a513529 (diff)
downloadscummvm-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.h10
-rw-r--r--engines/gargoyle/glk.cpp10
-rw-r--r--engines/gargoyle/glk.h1
-rw-r--r--engines/gargoyle/streams.cpp106
-rw-r--r--engines/gargoyle/streams.h50
-rw-r--r--engines/gargoyle/windows.cpp2
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() {