From 734366ce8919824336a1bbe543130e9d96b1e464 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Thu, 25 Oct 2018 22:09:35 -0700 Subject: GLK: Added more glk stream commands --- engines/gargoyle/glk.cpp | 16 +++- engines/gargoyle/streams.cpp | 172 +++++++++++++++++++++++++++++++++++++++++++ engines/gargoyle/streams.h | 39 ++++++++++ 3 files changed, 223 insertions(+), 4 deletions(-) (limited to 'engines') diff --git a/engines/gargoyle/glk.cpp b/engines/gargoyle/glk.cpp index 19933756f3..2f26aee5c4 100644 --- a/engines/gargoyle/glk.cpp +++ b/engines/gargoyle/glk.cpp @@ -655,13 +655,21 @@ void Glk::glk_put_buffer_stream_uni(strid_t str, const glui32 *buf, glui32 len) } glsi32 Glk::glk_get_char_stream_uni(strid_t str) { - // TODO - return 0; + if (str) { + return str->getCharUni(); + } else { + warning("get_char_stream_uni: invalid ref"); + return -1; + } } glui32 Glk::glk_get_buffer_stream_uni(strid_t str, glui32 *buf, glui32 len) { - // TODO - return 0; + if (str) { + return str->getBufferUni(buf, len); + } else { + warning("get_buffer_stream_uni: invalid ref"); + return 0; + } } glui32 Glk::glk_get_line_stream_uni(strid_t str, glui32 *buf, glui32 len) { diff --git a/engines/gargoyle/streams.cpp b/engines/gargoyle/streams.cpp index 6a73c5b3e9..42b89eb673 100644 --- a/engines/gargoyle/streams.cpp +++ b/engines/gargoyle/streams.cpp @@ -369,6 +369,81 @@ glsi32 MemoryStream::getChar() { } } +glsi32 MemoryStream::getCharUni() { + 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++; + return ch; + } + } else { + return -1; + } +} + +glui32 MemoryStream::getBufferUni(glui32 *buf, glui32 len) { + if (!_readable) + return 0; + + if (_bufPtr >= _bufEnd) { + len = 0; + } else { + if (!_unicode) { + unsigned char *bp = (unsigned char *)_bufPtr; + if (bp + len > (unsigned char *)_bufEnd) + { + glui32 lx; + lx = (bp + len) - (unsigned char *)_bufEnd; + if (lx < len) + len -= lx; + else + len = 0; + } + if (len) { + glui32 i; + for (i = 0; i < len; i++) + buf[i] = bp[i]; + bp += len; + if (bp >(unsigned char *)_bufEof) + _bufEof = bp; + } + _readCount += len; + _bufPtr = bp; + } else { + glui32 *bp = (glui32 *)_bufPtr; + if (bp + len > (glui32 *)_bufEnd) { + glui32 lx; + lx = (bp + len) - (glui32 *)_bufEnd; + if (lx < len) + len -= lx; + else + len = 0; + } + if (len) { + memcpy(buf, bp, len * 4); + bp += len; + if (bp >(glui32 *)_bufEof) + _bufEof = bp; + } + _readCount += len; + _bufPtr = bp; + } + } + + return len; +} + /*--------------------------------------------------------------------------*/ FileStream::FileStream(Streams *streams, uint32 rock, bool unicode) : @@ -623,6 +698,103 @@ glsi32 FileStream::getChar() { } } +glsi32 FileStream::getCharUni() { + 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 (res == -1) + return -1; + ch = (res & 0xFF); + res = _inFile->readByte(); + if (res == -1) + return -1; + ch = (ch << 8) | (res & 0xFF); + res = _inFile->readByte(); + if (res == -1) + return -1; + ch = (ch << 8) | (res & 0xFF); + res = _inFile->readByte(); + if (res == -1) + return -1; + ch = (ch << 8) | (res & 0xFF); + res = ch; + } + if (res != -1) { + _readCount++; + return (glsi32)res; + } else { + return -1; + } +} + + +glui32 FileStream::getBufferUni(glui32 *buf, glui32 len) { + if (!_readable) + return 0; + + ensureOp(filemode_Read); + if (!_unicode) { + glui32 lx; + for (lx = 0; lxreadByte(); + if (res == -1) + break; + ch = (res & 0xFF); + _readCount++; + buf[lx] = ch; + } + return lx; + } else if (_textFile) { + glui32 lx; + for (lx = 0; lxreadByte(); + if (res == -1) + break; + ch = (res & 0xFF); + res = _inFile->readByte(); + if (res == -1) + break; + ch = (ch << 8) | (res & 0xFF); + res = _inFile->readByte(); + if (res == -1) + break; + ch = (ch << 8) | (res & 0xFF); + res = _inFile->readByte(); + if (res == -1) + break; + ch = (ch << 8) | (res & 0xFF); + _readCount++; + buf[lx] = ch; + } + return lx; + } +} + /*--------------------------------------------------------------------------*/ Streams::Streams() : _streamList(nullptr), _currentStream(nullptr) { diff --git a/engines/gargoyle/streams.h b/engines/gargoyle/streams.h index 8b7da6ff4c..ff0f9be249 100644 --- a/engines/gargoyle/streams.h +++ b/engines/gargoyle/streams.h @@ -133,7 +133,20 @@ public: 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 unicode buffer + */ + virtual glui32 getBufferUni(glui32 *buf, glui32 len) { return 0; } }; typedef Stream *strid_t; @@ -218,7 +231,20 @@ public: virtual void setPosition(glui32 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 unicode buffer + */ + virtual glui32 getBufferUni(glui32 *buf, glui32 len) override; }; /** @@ -275,7 +301,20 @@ public: virtual void setPosition(glui32 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 unicode buffer + */ + virtual glui32 getBufferUni(glui32 *buf, glui32 len) override; }; /** -- cgit v1.2.3