aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Gilbert2018-10-25 21:45:23 -0700
committerPaul Gilbert2018-12-08 19:05:59 -0800
commit485e899312d1cf092e7cb52927593be21ef0f263 (patch)
tree0abb02f7c5fdb0adf290eb84627d8cc6df606b80
parentd1282498542b87ee0d807e5d4a2a09232a8dc677 (diff)
downloadscummvm-rg350-485e899312d1cf092e7cb52927593be21ef0f263.tar.gz
scummvm-rg350-485e899312d1cf092e7cb52927593be21ef0f263.tar.bz2
scummvm-rg350-485e899312d1cf092e7cb52927593be21ef0f263.zip
GLK: Adding glk stream methods
-rw-r--r--engines/gargoyle/glk.cpp54
-rw-r--r--engines/gargoyle/glk.h4
-rw-r--r--engines/gargoyle/glk_types.h5
-rw-r--r--engines/gargoyle/streams.cpp214
-rw-r--r--engines/gargoyle/streams.h36
5 files changed, 286 insertions, 27 deletions
diff --git a/engines/gargoyle/glk.cpp b/engines/gargoyle/glk.cpp
index d81ddf5b63..19933756f3 100644
--- a/engines/gargoyle/glk.cpp
+++ b/engines/gargoyle/glk.cpp
@@ -335,12 +335,11 @@ strid_t Glk::glk_stream_open_file(frefid_t fileref, FileMode fmode, glui32 rock)
}
strid_t Glk::glk_stream_open_memory(char *buf, glui32 buflen, FileMode fmode, glui32 rock) {
- // TODO
- return nullptr;
+ return _streams->addMemoryStream(buf, buflen, fmode, rock, false);
}
void Glk::glk_stream_close(strid_t str, stream_result_t *result) {
- // TODO
+ str->close(result);
}
strid_t Glk::glk_stream_iterate(strid_t str, glui32 *rockptr) const {
@@ -356,22 +355,29 @@ glui32 Glk::glk_stream_get_rock(strid_t str) const {
return str->getRock();
}
-void Glk::glk_stream_set_position(strid_t str, glsi32 pos, glui32 seekmode) {
- // TODO
+void Glk::glk_stream_set_position(strid_t str, glsi32 pos, glui32 seekMode) {
+ if (!str) {
+ warning("stream_set_position: invalid ref");
+ } else {
+ str->setPosition(pos, seekMode);
+ }
}
-glui32 Glk::glk_stream_get_position(strid_t str) {
- // TODO
- return 0;
+glui32 Glk::glk_stream_get_position(strid_t str) const {
+ if (!str) {
+ warning("stream_get_position: invalid ref");
+ return 0;
+ } else {
+ return str->getPosition();
+ }
}
void Glk::glk_stream_set_current(strid_t str) {
- // TODO
+ _streams->setCurrent(str);
}
strid_t Glk::glk_stream_get_current(void) {
- // TODO
- return nullptr;
+ return _streams->getCurrent();
}
void Glk::glk_put_char(unsigned char ch) {
@@ -387,32 +393,40 @@ void Glk::glk_put_char_stream(strid_t str, unsigned char ch) {
}
void Glk::glk_put_string(const char *s) {
- // TODO
+ _streams->getCurrent()->putBuffer(s, strlen(s));
}
void Glk::glk_put_string_stream(strid_t str, const char *s) {
- // TODO
+ str->putBuffer(s, strlen(s));
}
void Glk::glk_put_buffer(char *buf, glui32 len) {
- // TODO
+ _streams->getCurrent()->putBuffer(buf, len);
}
void Glk::glk_put_buffer_stream(strid_t str, const char *buf, glui32 len) {
- // TODO
+ str->putBuffer(buf, len);
}
void Glk::glk_set_style(glui32 styl) {
- // TODO
+ _streams->getCurrent()->setStyle(styl);
}
void Glk::glk_set_style_stream(strid_t str, glui32 styl) {
- // TODO
+ if (str) {
+ str->setStyle(styl);
+ } else {
+ warning("set_style_stream: invalid ref");
+ }
}
glsi32 Glk::glk_get_char_stream(strid_t str) {
- // TODO
- return 0;
+ if (str) {
+ warning("get_char_stream: invalid ref");
+ return -1;
+ } else {
+ return str->getChar();
+ }
}
glui32 Glk::glk_get_line_stream(strid_t str, char *buf, glui32 len) {
@@ -661,7 +675,7 @@ strid_t Glk::glk_stream_open_file_uni(frefid_t fileref, FileMode fmode, glui32 r
}
strid_t Glk::glk_stream_open_memory_uni(glui32 *buf, glui32 buflen, FileMode fmode, glui32 rock) {
- return _streams->addMemoryStream(buf, buflen, fmode, rock, false);
+ return _streams->addMemoryStream(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 e1923b7b02..3b49421d16 100644
--- a/engines/gargoyle/glk.h
+++ b/engines/gargoyle/glk.h
@@ -96,8 +96,8 @@ public:
void glk_stream_close(strid_t str, stream_result_t *result);
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_position(strid_t str, glsi32 pos, glui32 seekMode);
+ glui32 glk_stream_get_position(strid_t str) const;
void glk_stream_set_current(strid_t str);
strid_t glk_stream_get_current(void);
diff --git a/engines/gargoyle/glk_types.h b/engines/gargoyle/glk_types.h
index 81d05ac391..a521548047 100644
--- a/engines/gargoyle/glk_types.h
+++ b/engines/gargoyle/glk_types.h
@@ -46,11 +46,6 @@ class Window;
#define GLK_MODULE_DATETIME
#define GLK_MODULE_GARGLKTEXT
-/**
- * These types are opaque object identifiers. They're pointers to opaque
- * C structures, which are defined differently by each library.
- */
-typedef struct glk_fileref_struct *frefid_t;
typedef struct glk_schannel_struct *schanid_t;
/**
diff --git a/engines/gargoyle/streams.cpp b/engines/gargoyle/streams.cpp
index 749999153c..6a73c5b3e9 100644
--- a/engines/gargoyle/streams.cpp
+++ b/engines/gargoyle/streams.cpp
@@ -144,6 +144,18 @@ void WindowStream::putBufferUni(const uint32 *buf, size_t len) {
_window->_echoStream->putBufferUni(buf, len);
}
+void WindowStream::setStyle(glui32 val) {
+ if (!_writable)
+ return;
+
+ if (val >= style_NUMSTYLES)
+ val = 0;
+
+ _window->_attr.style = val;
+ if (_window->_echoStream)
+ _window->_echoStream->setStyle(val);
+}
+
/*--------------------------------------------------------------------------*/
MemoryStream::MemoryStream(Streams *streams, void *buf, size_t buflen, FileMode mode, uint32 rock, bool unicode) :
@@ -297,6 +309,66 @@ void MemoryStream::putBufferUni(const uint32 *buf, size_t len) {
}
}
+glui32 MemoryStream::getPosition() const {
+ if (_unicode)
+ return ((glui32 *)_bufPtr - (glui32 *)_buf);
+ else
+ return ((unsigned char *)_bufPtr - (unsigned char *)_buf);
+}
+
+void MemoryStream::setPosition(glui32 pos, glui32 seekMode) {
+ if (!_unicode)
+ {
+ if (seekMode == seekmode_Current)
+ pos = ((unsigned char *)_bufPtr - (unsigned char *)_buf) + pos;
+ else if (seekMode == seekmode_End)
+ pos = ((unsigned char *)_bufEof - (unsigned char *)_buf) + pos;
+ else
+ /* pos = pos */;
+ if (pos < 0)
+ pos = 0;
+ if (pos > (glui32)((unsigned char *)_bufEof - (unsigned char *)_buf))
+ pos = ((unsigned char *)_bufEof - (unsigned char *)_buf);
+ _bufPtr = (unsigned char *)_buf + pos;
+ } else {
+ if (seekMode == seekmode_Current)
+ pos = ((glui32 *)_bufPtr - (glui32 *)_buf) + pos;
+ else if (seekMode == seekmode_End)
+ pos = ((glui32 *)_bufEof - (glui32 *)_buf) + pos;
+
+ if (pos < 0)
+ pos = 0;
+ if (pos > (glui32)((glui32 *)_bufEof - (glui32 *)_buf))
+ pos = ((glui32 *)_bufEof - (glui32 *)_buf);
+ _bufPtr = (glui32 *)_buf + pos;
+ }
+}
+
+glsi32 MemoryStream::getChar() {
+ if (!_readable)
+ return -1;
+
+ if (_bufPtr < _bufEnd) {
+ if (!_unicode) {
+ unsigned char ch;
+ ch = *((unsigned char *)_bufPtr);
+ _bufPtr = ((unsigned char *)_bufPtr) + 1;
+ _readCount++;
+ return ch;
+ } else {
+ glui32 ch;
+ ch = *((glui32 *)_bufPtr);
+ _bufPtr = ((glui32 *)_bufPtr) + 1;
+ _readCount++;
+ if (ch > 0xff)
+ ch = '?';
+ return ch;
+ }
+ } else {
+ return -1;
+ }
+}
+
/*--------------------------------------------------------------------------*/
FileStream::FileStream(Streams *streams, uint32 rock, bool unicode) :
@@ -409,6 +481,148 @@ void FileStream::putCharUtf8(glui32 val) {
}
}
+glsi32 FileStream::getCharUtf8() {
+ glui32 res;
+ glui32 val0, val1, val2, val3;
+
+ if (_inFile->eos())
+ return -1;
+ val0 = _inFile->readByte();
+ if (val0 < 0x80) {
+ res = val0;
+ return res;
+ }
+
+ if ((val0 & 0xe0) == 0xc0) {
+ if (_inFile->eos()) {
+ warning("incomplete two-byte character");
+ return -1;
+ }
+
+ val1 = _inFile->readByte();
+ if ((val1 & 0xc0) != 0x80) {
+ warning("malformed two-byte character");
+ return '?';
+ }
+
+ res = (val0 & 0x1f) << 6;
+ res |= (val1 & 0x3f);
+ return res;
+ }
+
+ if ((val0 & 0xf0) == 0xe0) {
+ val1 = _inFile->readByte();
+ val2 = _inFile->readByte();
+ if (_inFile->eos()) {
+ warning("incomplete three-byte character");
+ return -1;
+ }
+ if ((val1 & 0xc0) != 0x80) {
+ warning("malformed three-byte character");
+ return '?';
+ }
+ if ((val2 & 0xc0) != 0x80) {
+ warning("malformed three-byte character");
+ return '?';
+ }
+
+ res = (((val0 & 0xf) << 12) & 0x0000f000);
+ res |= (((val1 & 0x3f) << 6) & 0x00000fc0);
+ res |= (((val2 & 0x3f)) & 0x0000003f);
+ return res;
+ }
+
+ if ((val0 & 0xf0) == 0xf0) {
+ if ((val0 & 0xf8) != 0xf0) {
+ warning("malformed four-byte character");
+ return '?';
+ }
+
+ val1 = _inFile->readByte();
+ val2 = _inFile->readByte();
+ val3 = _inFile->readByte();
+ if (_inFile->eos()) {
+ warning("incomplete four-byte character");
+ return -1;
+ }
+ if ((val1 & 0xc0) != 0x80) {
+ warning("malformed four-byte character");
+ return '?';
+ }
+ if ((val2 & 0xc0) != 0x80) {
+ warning("malformed four-byte character");
+ return '?';
+ }
+ if ((val3 & 0xc0) != 0x80) {
+ warning("malformed four-byte character");
+ return '?';
+ }
+
+ res = (((val0 & 0x7) << 18) & 0x1c0000);
+ res |= (((val1 & 0x3f) << 12) & 0x03f000);
+ res |= (((val2 & 0x3f) << 6) & 0x000fc0);
+ res |= (((val3 & 0x3f)) & 0x00003f);
+ return res;
+ }
+
+ warning("malformed character");
+ return '?';
+}
+
+glui32 FileStream::getPosition() const {
+ return _outFile->pos();
+}
+
+void FileStream::setPosition(glui32 pos, glui32 seekMode) {
+ _lastOp = 0;
+ if (_unicode)
+ pos *= 4;
+
+ error("FileStream::setPosition - seek not yet supported");
+// fseek(str->file, pos, ((seekmode == seekmode_Current) ? 1 :
+ // ((seekmode == seekmode_End) ? 2 : 0)));
+}
+
+glsi32 FileStream::getChar() {
+ if (!_readable)
+ return -1;
+
+ ensureOp(filemode_Read);
+ int res;
+ if (!_unicode) {
+ res = _inFile->readByte();
+ } else if (_textFile) {
+ res = getCharUtf8();
+ } else {
+ glui32 ch;
+ res = _inFile->readByte();
+ if (_inFile->eos())
+ return -1;
+ ch = (res & 0xFF);
+ res = _inFile->readByte();
+ if (_inFile->eos())
+ return -1;
+ ch = (ch << 8) | (res & 0xFF);
+ res = _inFile->readByte();
+ if (_inFile->eos())
+ return -1;
+ ch = (ch << 8) | (res & 0xFF);
+ res = _inFile->readByte();
+ if (_inFile->eos())
+ return -1;
+ ch = (ch << 8) | (res & 0xFF);
+ res = ch;
+ }
+ if (res != -1) {
+ _readCount++;
+ if (res >= 0x100)
+ return '?';
+ return (glsi32)res;
+ } else {
+ return -1;
+ }
+}
+
/*--------------------------------------------------------------------------*/
Streams::Streams() : _streamList(nullptr), _currentStream(nullptr) {
diff --git a/engines/gargoyle/streams.h b/engines/gargoyle/streams.h
index 51ab484eb7..8b7da6ff4c 100644
--- a/engines/gargoyle/streams.h
+++ b/engines/gargoyle/streams.h
@@ -32,6 +32,15 @@ namespace Gargoyle {
class Window;
class Streams;
+struct FileReference {
+ glui32 _rock;
+ Common::String _filename;
+ int _fileType;
+ int _textMode;
+ gidispatch_rock_t _dispRock;
+};
+typedef FileReference *frefid_t;
+
struct StreamResult {
uint32 _readCount;
uint32 _writeCount;
@@ -117,6 +126,14 @@ public:
putBufferUni(buf, len);
putCharUni('\n');
}
+
+ virtual glui32 getPosition() const { return 0; }
+
+ virtual void setPosition(glui32 pos, glui32 seekMode) {}
+
+ virtual void setStyle(glui32 val) {}
+
+ virtual glsi32 getChar() { return -1; }
};
typedef Stream *strid_t;
@@ -157,6 +174,8 @@ public:
* Write a unicode character
*/
virtual void putBufferUni(const uint32 *buf, size_t len) override;
+
+ virtual void setStyle(glui32 val) override;
};
/**
@@ -194,6 +213,12 @@ public:
* Write a unicode character
*/
virtual void putBufferUni(const uint32 *buf, size_t len) override;
+
+ virtual glui32 getPosition() const override;
+
+ virtual void setPosition(glui32 pos, glui32 seekMode) override;
+
+ virtual glsi32 getChar() override;
};
/**
@@ -215,6 +240,11 @@ private:
* Put a UTF8 character
*/
void putCharUtf8(glui32 val);
+
+ /**
+ * Get a UTF8 character
+ */
+ glsi32 getCharUtf8();
public:
/**
* Constructor
@@ -240,6 +270,12 @@ public:
* Write a unicode character
*/
virtual void putBufferUni(const uint32 *buf, size_t len) override;
+
+ virtual glui32 getPosition() const override;
+
+ virtual void setPosition(glui32 pos, glui32 seekMode) override;
+
+ virtual glsi32 getChar() override;
};
/**