aboutsummaryrefslogtreecommitdiff
path: root/engines/gargoyle
diff options
context:
space:
mode:
Diffstat (limited to 'engines/gargoyle')
-rw-r--r--engines/gargoyle/gargoyle.cpp3
-rw-r--r--engines/gargoyle/gargoyle.h2
-rw-r--r--engines/gargoyle/glk.cpp34
-rw-r--r--engines/gargoyle/glk.h18
-rw-r--r--engines/gargoyle/glk_types.h1
-rw-r--r--engines/gargoyle/stream.cpp114
-rw-r--r--engines/gargoyle/stream.h150
-rw-r--r--engines/gargoyle/windows.h16
8 files changed, 281 insertions, 57 deletions
diff --git a/engines/gargoyle/gargoyle.cpp b/engines/gargoyle/gargoyle.cpp
index 5401b2c513..986a40ab78 100644
--- a/engines/gargoyle/gargoyle.cpp
+++ b/engines/gargoyle/gargoyle.cpp
@@ -30,6 +30,7 @@
#include "graphics/thumbnail.h"
#include "gargoyle/gargoyle.h"
#include "gargoyle/events.h"
+#include "gargoyle/stream.h"
#include "gargoyle/windows.h"
namespace Gargoyle {
@@ -42,6 +43,7 @@ GargoyleEngine::GargoyleEngine(OSystem *syst, const GargoyleGameDescription *gam
GargoyleEngine::~GargoyleEngine() {
delete _events;
delete _screen;
+ delete _streams;
delete _windows;
}
@@ -55,6 +57,7 @@ void GargoyleEngine::initialize() {
initGraphics(640, 480, false);
_screen = new Graphics::Screen();
_events = new Events();
+ _streams = new Streams();
_windows = new Windows(_screen);
}
diff --git a/engines/gargoyle/gargoyle.h b/engines/gargoyle/gargoyle.h
index c7a7b86ecd..bd977137b4 100644
--- a/engines/gargoyle/gargoyle.h
+++ b/engines/gargoyle/gargoyle.h
@@ -35,6 +35,7 @@ namespace Gargoyle {
class Events;
class Windows;
+class Streams;
enum InterpreterType {
INTERPRETER_SCOTT
@@ -74,6 +75,7 @@ protected:
const GargoyleGameDescription *_gameDescription;
Events *_events;
Graphics::Screen *_screen;
+ Streams *_streams;
Windows *_windows;
Common::RandomSource _random;
int _loadSaveSlot;
diff --git a/engines/gargoyle/glk.cpp b/engines/gargoyle/glk.cpp
index 3e308d5506..22d02f5237 100644
--- a/engines/gargoyle/glk.cpp
+++ b/engines/gargoyle/glk.cpp
@@ -139,13 +139,13 @@ void Glk::glk_set_window(winid_t win) {
_windows->setCurrent(win ? win->_stream : nullptr);
}
-strid_t Glk::glk_stream_open_file(frefid_t fileref, glui32 fmode,
+strid_t Glk::glk_stream_open_file(frefid_t fileref, FileMode fmode,
glui32 rock) {
// TODO
return nullptr;
}
-strid_t Glk::glk_stream_open_memory(char *buf, glui32 buflen, glui32 fmode, glui32 rock) {
+strid_t Glk::glk_stream_open_memory(char *buf, glui32 buflen, FileMode fmode, glui32 rock) {
// TODO
return nullptr;
}
@@ -154,14 +154,17 @@ void Glk::glk_stream_close(strid_t str, stream_result_t *result) {
// TODO
}
-strid_t Glk::glk_stream_iterate(strid_t str, glui32 *rockptr) {
- // TODO
- return nullptr;
+strid_t Glk::glk_stream_iterate(strid_t str, glui32 *rockptr) const {
+ return str ? str->getNext(rockptr) : _streams->getFirst(rockptr);
}
-glui32 Glk::glk_stream_get_rock(strid_t str) {
- // TODO
- return 0;
+glui32 Glk::glk_stream_get_rock(strid_t str) const {
+ if (!str) {
+ warning("stream_get_rock: invalid ref");
+ return 0;
+ }
+
+ return str->getRock();
}
void Glk::glk_stream_set_position(strid_t str, glsi32 pos, glui32 seekmode) {
@@ -257,7 +260,7 @@ frefid_t Glk::glk_fileref_create_by_name(glui32 usage, char *name, glui32 rock)
return nullptr;
}
-frefid_t Glk::glk_fileref_create_by_prompt(glui32 usage, glui32 fmode, glui32 rock) {
+frefid_t Glk::glk_fileref_create_by_prompt(glui32 usage, FileMode fmode, glui32 rock) {
// TODO
return nullptr;
}
@@ -383,7 +386,7 @@ void Glk::glk_put_buffer_uni(glui32 *buf, glui32 len) {
}
void Glk::glk_put_char_stream_uni(strid_t str, glui32 ch) {
- str->writeUint32LE(ch);
+// str->writeUint32LE(ch);
}
void Glk::glk_put_string_stream_uni(strid_t str, const glui32 *s) {
@@ -391,8 +394,7 @@ void Glk::glk_put_string_stream_uni(strid_t str, const glui32 *s) {
}
void Glk::glk_put_buffer_stream_uni(strid_t str, const glui32 *buf, glui32 len) {
- while (len-- > 0)
- str->writeUint32LE(*buf++);
+// while (len-- > 0) str->writeUint32LE(*buf++);
}
glsi32 Glk::glk_get_char_stream_uni(strid_t str) {
@@ -410,15 +412,13 @@ glui32 Glk::glk_get_line_stream_uni(strid_t str, glui32 *buf, glui32 len) {
return 0;
}
-strid_t Glk::glk_stream_open_file_uni(frefid_t fileref, glui32 fmode, glui32 rock) {
+strid_t Glk::glk_stream_open_file_uni(frefid_t fileref, FileMode fmode, glui32 rock) {
// TODO
return nullptr;
}
-strid_t Glk::glk_stream_open_memory_uni(glui32 *buf, glui32 buflen,
- glui32 fmode, glui32 rock) {
- // TODO
- return nullptr;
+strid_t Glk::glk_stream_open_memory_uni(glui32 *buf, glui32 buflen, FileMode fmode, glui32 rock) {
+ return _streams->addMemoryStream(buf, buflen, fmode, rock, false);
}
void Glk::glk_request_char_event_uni(winid_t win) {
diff --git a/engines/gargoyle/glk.h b/engines/gargoyle/glk.h
index b0ef1714ac..0029ecf24f 100644
--- a/engines/gargoyle/glk.h
+++ b/engines/gargoyle/glk.h
@@ -90,13 +90,11 @@ public:
strid_t glk_window_get_echo_stream(winid_t win);
void glk_set_window(winid_t win);
- strid_t glk_stream_open_file(frefid_t fileref, glui32 fmode,
- glui32 rock);
- strid_t glk_stream_open_memory(char *buf, glui32 buflen, glui32 fmode,
- glui32 rock);
+ strid_t glk_stream_open_file(frefid_t fileref, FileMode fmode, glui32 rock);
+ strid_t glk_stream_open_memory(char *buf, glui32 buflen, FileMode fmode, glui32 rock);
void glk_stream_close(strid_t str, stream_result_t *result);
- strid_t glk_stream_iterate(strid_t str, glui32 *rockptr);
- glui32 glk_stream_get_rock(strid_t str);
+ strid_t glk_stream_iterate(strid_t str, glui32 *rockptr) const;
+ glui32 glk_stream_get_rock(strid_t str) const;
void glk_stream_set_position(strid_t str, glsi32 pos, glui32 seekmode);
glui32 glk_stream_get_position(strid_t str);
void glk_stream_set_current(strid_t str);
@@ -125,7 +123,7 @@ public:
frefid_t glk_fileref_create_temp(glui32 usage, glui32 rock);
frefid_t glk_fileref_create_by_name(glui32 usage, char *name,
glui32 rock);
- frefid_t glk_fileref_create_by_prompt(glui32 usage, glui32 fmode,
+ frefid_t glk_fileref_create_by_prompt(glui32 usage, FileMode fmode,
glui32 rock);
frefid_t glk_fileref_create_from_fileref(glui32 usage, frefid_t fref,
glui32 rock);
@@ -178,10 +176,8 @@ public:
glui32 glk_get_buffer_stream_uni(strid_t str, glui32 *buf, glui32 len);
glui32 glk_get_line_stream_uni(strid_t str, glui32 *buf, glui32 len);
- strid_t glk_stream_open_file_uni(frefid_t fileref, glui32 fmode,
- glui32 rock);
- strid_t glk_stream_open_memory_uni(glui32 *buf, glui32 buflen,
- glui32 fmode, glui32 rock);
+ strid_t glk_stream_open_file_uni(frefid_t fileref, FileMode fmode, glui32 rock);
+ strid_t glk_stream_open_memory_uni(glui32 *buf, glui32 buflen, FileMode fmode, glui32 rock);
void glk_request_char_event_uni(winid_t win);
void glk_request_line_event_uni(winid_t win, glui32 *buf,
diff --git a/engines/gargoyle/glk_types.h b/engines/gargoyle/glk_types.h
index 86b37fc5d7..c7b505e1d9 100644
--- a/engines/gargoyle/glk_types.h
+++ b/engines/gargoyle/glk_types.h
@@ -50,7 +50,6 @@ class Window;
* These types are opaque object identifiers. They're pointers to opaque
* C structures, which are defined differently by each library.
*/
-typedef Common::WriteStream *strid_t;
typedef struct glk_fileref_struct *frefid_t;
typedef struct glk_schannel_struct *schanid_t;
diff --git a/engines/gargoyle/stream.cpp b/engines/gargoyle/stream.cpp
index a08579a97d..c447646638 100644
--- a/engines/gargoyle/stream.cpp
+++ b/engines/gargoyle/stream.cpp
@@ -21,19 +21,121 @@
*/
#include "gargoyle/stream.h"
+#include "gargoyle/windows.h"
namespace Gargoyle {
-uint32 WindowStream::write(const void *dataPtr, uint32 dataSize) {
- // TODO
- return dataSize;
+Stream::Stream(bool readable, bool writable, uint32 rock, bool unicode) :
+ _readable(readable), _writable(writable), _readCount(0), _writeCount(0),
+ _prev(nullptr), _next(nullptr), _rock(0) {
}
-bool WindowStream::flush() {
- // TODO
- return true;
+Stream *Stream::getNext(uint32 *rock) const {
+ Stream *stream = _next;
+ if (rock)
+ *rock = stream ? stream->_rock : 0;
+ return stream;
}
+void Stream::fillResult(StreamResult *result) {
+ if (result) {
+ result->_readCount = _readCount;
+ result->_writeCount = _writeCount;
+ }
+}
+
+void Stream::close(StreamResult *result) {
+ fillResult(result);
+
+}
+
+/*--------------------------------------------------------------------------*/
+
+void WindowStream::writeChar(unsigned char ch) {
+
+}
+
+void WindowStream::writeCharUni(uint32 ch) {
+
+}
+
+/*--------------------------------------------------------------------------*/
+
+MemoryStream::MemoryStream(void *buf, size_t buflen, FileMode mode, uint32 rock, bool unicode) :
+ Stream(mode != filemode_Write, mode != filemode_Read, rock, unicode),
+ _buf(buf), _buflen(buflen), _bufptr(buf) {
+ assert(_buf && _buflen);
+ assert(mode == filemode_Read || mode == filemode_Write || mode == filemode_ReadWrite);
+
+ if (unicode)
+ _bufend = (uint32 *)buf + buflen;
+ else
+ _bufend = (byte *)buf + buflen;
+ _bufeof = mode == filemode_Write ? _buf : _bufend;
+}
+
+void MemoryStream::writeChar(unsigned char ch) {
+
+}
+
+void MemoryStream::writeCharUni(uint32 ch) {
+
+}
+
+/*--------------------------------------------------------------------------*/
+
+/*--------------------------------------------------------------------------*/
+
+/*--------------------------------------------------------------------------*/
+
+Streams::Streams() : _streamList(nullptr) {}
+
+Streams::~Streams() {
+ while (_streamList)
+ deleteStream(_streamList);
+}
+
+WindowStream *Streams::addWindowStream(Window *window) {
+ WindowStream *stream = new WindowStream(window);
+ addStream(stream);
+ return stream;
+}
+
+MemoryStream *Streams::addMemoryStream(void *buf, size_t buflen, FileMode mode, uint32 rock, bool unicode) {
+ MemoryStream *stream = new MemoryStream(buf, buflen, mode, rock, unicode);
+ addStream(stream);
+ return stream;
+}
+
+void Streams::addStream(Stream *stream) {
+ stream->_next = _streamList;
+ _streamList = stream;
+ if (stream->_next)
+ stream->_next->_prev = stream;
+}
+
+void Streams::deleteStream(Stream *stream) {
+ Stream *prev = stream->_prev;
+ Stream *next = stream->_next;
+
+ if (prev)
+ prev->_next = next;
+ else
+ _streamList = next;
+ if (next)
+ next->_prev = prev;
+
+ delete stream;
+}
+
+Stream *Streams::getFirst(uint32 *rock) {
+ if (rock)
+ *rock = _streamList ? _streamList->_rock : 0;
+ return _streamList;
+}
+
+/*--------------------------------------------------------------------------*/
+
size_t strlen_uni(const uint32 *s) {
size_t len = 0;
while (*s++)
diff --git a/engines/gargoyle/stream.h b/engines/gargoyle/stream.h
index 5a55fbc16a..4effee33ff 100644
--- a/engines/gargoyle/stream.h
+++ b/engines/gargoyle/stream.h
@@ -23,47 +23,169 @@
#ifndef GARGOYLE_STREAM_H
#define GARGOYLE_STREAM_H
-#include "common/stream.h"
+#include "common/scummsys.h"
+#include "gargoyle/glk_types.h"
namespace Gargoyle {
class Window;
+struct StreamResult {
+ uint32 _readCount;
+ uint32 _writeCount;
+};
+
+/**
+ * Base class for streams
+ */
+class Stream {
+public:
+ Stream *_prev;
+ Stream *_next;
+ uint32 _rock;
+ bool _unicode;
+ uint32 _readCount;
+ uint32 _writeCount;
+ bool _readable, _writable;
+public:
+ /**
+ * Constructor
+ */
+ Stream(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 the stream
+ */
+ virtual void close(StreamResult *result = nullptr);
+
+ /**
+ * Write a character
+ */
+ virtual void writeChar(unsigned char ch) = 0;
+
+ /**
+ * Write a unicode character
+ */
+ virtual void writeCharUni(uint32 ch) = 0;
+};
+typedef Stream *strid_t;
+
/**
* Implements the stream for writing text to a window
*/
-class WindowStream : public Common::WriteStream {
+class WindowStream : public Stream {
private:
- uint32 _rock;
Window *_window;
public:
/**
* Constructor
*/
- WindowStream(Window *window, uint32 rock = 0) : Common::WriteStream(),
- _window(window), _rock(rock) {}
+ WindowStream(Window *window, uint32 rock = 0, bool unicode = true) :
+ Stream(true, false, rock, unicode), _window(window) {}
/**
- * Write to the stream
+ * Write a character
*/
- virtual uint32 write(const void *dataPtr, uint32 dataSize);
-
+ virtual void writeChar(unsigned char ch) override;
+
/**
- * Flush the stream
+ * Write a unicode character
*/
- virtual bool flush();
+ virtual void writeCharUni(uint32 ch) 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(void *buf, size_t buflen, FileMode mode, uint32 rock = 0, bool unicode = true);
+
+ /**
+ * Write a character
+ */
+ virtual void writeChar(unsigned char ch);
+
+ /**
+ * Write a unicode character
+ */
+ virtual void writeCharUni(uint32 ch);
+};
+
+/**
+ * Streams manager
+ */
+class Streams {
+private:
+ Stream *_streamList;
+private:
/**
- * Finalize and close this stream
+ * Adds a created stream to the list
*/
- virtual void finalize() { flush(); }
+ void addStream(Stream *stream);
+public:
+ /**
+ * Constructor
+ */
+ Streams();
+
+ /**
+ * Destructor
+ */
+ ~Streams();
+
+ /**
+ * Add a window stream
+ */
+ WindowStream *addWindowStream(Window *window);
/**
- * Returns the stream position
+ * Add a memory stream
*/
- virtual int32 pos() const { return 0; }
+ MemoryStream *addMemoryStream(void *buf, size_t buflen, FileMode mode, uint32 rock = 0, bool unicode = true);
+
+ /**
+ * Delete a stream
+ */
+ void deleteStream(Stream *stream);
+
+ /**
+ * Start an Iteration through streams
+ */
+ Stream *getFirst(uint32 *rock);
};
+
+
/*
* Get the length of a unicode string
*/
diff --git a/engines/gargoyle/windows.h b/engines/gargoyle/windows.h
index 17e7d16aef..fdb29bb7b1 100644
--- a/engines/gargoyle/windows.h
+++ b/engines/gargoyle/windows.h
@@ -26,10 +26,10 @@
#include "common/array.h"
#include "common/list.h"
#include "common/rect.h"
-#include "common/stream.h"
#include "graphics/screen.h"
#include "gargoyle/glk_types.h"
#include "gargoyle/picture.h"
+#include "gargoyle/stream.h"
namespace Gargoyle {
@@ -54,7 +54,7 @@ private:
bool _moreFocus;
bool _claimSelect;
WindowMask *_mask;
- Common::WriteStream *_currentStr;
+ Stream *_currentStr;
private:
/**
* Create a new window
@@ -116,12 +116,12 @@ public:
/**
* Set the current output stream
*/
- void setCurrent(Common::WriteStream *stream) { _currentStr = stream; }
+ void setCurrent(Stream *stream) { _currentStr = stream; }
/**
* Gets the current output stream
*/
- Common::WriteStream *getCurrent() const { return _currentStr; }
+ Stream *getCurrent() const { return _currentStr; }
/**
* Repaint an area of the windows
@@ -184,12 +184,12 @@ public:
glui32 _rock;
glui32 _type;
- Window *parent; ///< pair window which contains this one
+ Window *parent; ///< pair window which contains this one
Common::Rect bbox;
int yadj;
- Common::WriteStream *_stream; ///< the window stream.
- Common::WriteStream *_echoStream; ///< the window's echo stream, if any.
+ Stream *_stream; ///< the window stream.
+ Stream *_echoStream; ///< the window's echo stream, if any.
int line_request;
int line_request_uni;
@@ -210,7 +210,7 @@ public:
byte fgcolor[3];
gidispatch_rock_t disprock;
- Window *next, *prev; ///< in the big linked list of windows
+ Window *next, *prev; ///< in the big linked list of windows
public:
/**
* Constructor