mirror of
https://github.com/scummvm/scummvm.git
synced 2026-06-20 05:45:29 +00:00
GLK: Adding glk stream methods
This commit is contained in:
committed by
Paul Gilbert
parent
d128249854
commit
485e899312
+34
-20
@@ -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) {
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
/**
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user