reg_t kFileIOSeek(EngineState *s, int argc, reg_t *argv) { uint16 handle = argv[0].toUint16(); uint16 offset = ABS<int16>(argv[1].toSint16()); // can be negative uint16 whence = argv[2].toUint16(); debugC(kDebugLevelFile, "kFileIO(seek): %d, %d, %d", handle, offset, whence); #ifdef ENABLE_SCI32 if (handle == VIRTUALFILE_HANDLE) return make_reg(0, s->_virtualIndexFile->seek(offset, whence)); #endif FileHandle *f = getFileFromHandle(s, handle); if (f && f->_in) { // Backward seeking isn't supported in zip file streams, thus adapt the // parameters accordingly if games ask for such a seek mode. A known // case where this is requested is the save file manager in Phantasmagoria if (whence == SEEK_END) { whence = SEEK_SET; offset = f->_in->size() - offset; } return make_reg(0, f->_in->seek(offset, whence)); } else if (f && f->_out) { error("kFileIOSeek: Unsupported seek operation on a writeable stream (offset: %d, whence: %d)", offset, whence); } return SIGNAL_REG; }
reg_t kFileIOReadByte(EngineState *s, int argc, reg_t *argv) { // Read the byte into the low byte of the accumulator FileHandle *f = getFileFromHandle(s, argv[0].toUint16()); if (!f) return NULL_REG; return make_reg(0, (s->r_acc.toUint16() & 0xff00) | f->_in->readByte()); }
reg_t kFileIOWriteRaw(EngineState *s, int argc, reg_t *argv) { uint16 handle = argv[0].toUint16(); uint16 size = argv[2].toUint16(); char *buf = new char[size]; bool success = false; s->_segMan->memcpy((byte *)buf, argv[1], size); debugC(kDebugLevelFile, "kFileIO(writeRaw): %d, %d", handle, size); #ifdef ENABLE_SCI32 if (handle == VIRTUALFILE_HANDLE) { s->_virtualIndexFile->write(buf, size); success = true; } else { #endif FileHandle *f = getFileFromHandle(s, handle); if (f) { f->_out->write(buf, size); success = true; } #ifdef ENABLE_SCI32 } #endif delete[] buf; if (success) return NULL_REG; return make_reg(0, 6); // DOS - invalid handle }
reg_t kFileIOWriteString(EngineState *s, int argc, reg_t *argv) { int handle = argv[0].toUint16(); Common::String str = s->_segMan->getString(argv[1]); debugC(kDebugLevelFile, "kFileIO(writeString): %d", handle); #ifdef ENABLE_SCI32 if (handle == VIRTUALFILE_HANDLE) { s->_virtualIndexFile->write(str.c_str(), str.size()); return NULL_REG; } #endif FileHandle *f = getFileFromHandle(s, handle); if (f) { f->_out->write(str.c_str(), str.size()); if (getSciVersion() <= SCI_VERSION_0_LATE) return s->r_acc; // SCI0 semantics: no value returned return NULL_REG; } if (getSciVersion() <= SCI_VERSION_0_LATE) return s->r_acc; // SCI0 semantics: no value returned return make_reg(0, 6); // DOS - invalid handle }
reg_t kFileIOClose(EngineState *s, int argc, reg_t *argv) { debugC(kDebugLevelFile, "kFileIO(close): %d", argv[0].toUint16()); if (argv[0] == SIGNAL_REG) return s->r_acc; uint16 handle = argv[0].toUint16(); #ifdef ENABLE_SCI32 if (handle == VIRTUALFILE_HANDLE) { s->_virtualIndexFile->close(); return SIGNAL_REG; } #endif FileHandle *f = getFileFromHandle(s, handle); if (f) { f->close(); if (getSciVersion() <= SCI_VERSION_0_LATE) return s->r_acc; // SCI0 semantics: no value returned return SIGNAL_REG; } if (getSciVersion() <= SCI_VERSION_0_LATE) return s->r_acc; // SCI0 semantics: no value returned return NULL_REG; }
reg_t kFileIOReadRaw(EngineState *s, int argc, reg_t *argv) { uint16 handle = argv[0].toUint16(); uint16 size = argv[2].toUint16(); int bytesRead = 0; char *buf = new char[size]; debugC(kDebugLevelFile, "kFileIO(readRaw): %d, %d", handle, size); #ifdef ENABLE_SCI32 if (handle == VIRTUALFILE_HANDLE) { bytesRead = s->_virtualIndexFile->read(buf, size); } else { #endif FileHandle *f = getFileFromHandle(s, handle); if (f) bytesRead = f->_in->read(buf, size); #ifdef ENABLE_SCI32 } #endif // TODO: What happens if less bytes are read than what has // been requested? (i.e. if bytesRead is non-zero, but still // less than size) if (bytesRead > 0) s->_segMan->memcpy(argv[1], (const byte*)buf, size); delete[] buf; return make_reg(0, bytesRead); }
void file_close(EngineState *s, int handle) { debugC(2, kDebugLevelFile, "Closing file %d\n", handle); FileHandle *f = getFileFromHandle(s, handle); if (f) f->close(); }
static void fseek_wrapper(EngineState *s, int handle, int offset, int whence) { FileHandle *f = getFileFromHandle(s, handle); if (!f) return; if (!f->_in) { error("fseek_wrapper: Trying to seek in file '%s' opened for writing", f->_name.c_str()); return; } s->r_acc = make_reg(0, f->_in->seek(offset, whence)); }
static void fread_wrapper(EngineState *s, char *dest, int bytes, int handle) { debugC(2, kDebugLevelFile, "fread()'ing %d bytes from handle %d\n", bytes, handle); FileHandle *f = getFileFromHandle(s, handle); if (!f) return; if (!f->_in) { error("fread_wrapper: Trying to read from file '%s' opened for writing", f->_name.c_str()); return; } s->r_acc = make_reg(0, f->_in->read(dest, bytes)); }
void fwrite_wrapper(EngineState *s, int handle, char *data, int length) { debugC(2, kDebugLevelFile, "fwrite()'ing \"%s\" to handle %d\n", data, handle); FileHandle *f = getFileFromHandle(s, handle); if (!f) return; if (!f->_out) { error("fgets_wrapper: Trying to write to file '%s' opened for reading", f->_name.c_str()); return; } f->_out->write(data, length); }
static void fgets_wrapper(EngineState *s, char *dest, int maxsize, int handle) { debugC(2, kDebugLevelFile, "FGets'ing %d bytes from handle %d\n", maxsize, handle); FileHandle *f = getFileFromHandle(s, handle); if (!f) return; if (!f->_in) { error("fgets_wrapper: Trying to read from file '%s' opened for writing", f->_name.c_str()); return; } f->_in->readLine_NEW(dest, maxsize); // The returned string must not have an ending LF int strSize = strlen(dest); if (strSize > 0) { if (dest[strSize - 1] == 0x0A) dest[strSize - 1] = 0; } debugC(2, kDebugLevelFile, "FGets'ed \"%s\"\n", dest); }
reg_t kFileIOWriteWord(EngineState *s, int argc, reg_t *argv) { FileHandle *f = getFileFromHandle(s, argv[0].toUint16()); if (f) f->_out->writeUint16LE(argv[1].toUint16()); return s->r_acc; // FIXME: does this really not return anything? }
reg_t kFileIOReadWord(EngineState *s, int argc, reg_t *argv) { FileHandle *f = getFileFromHandle(s, argv[0].toUint16()); if (!f) return NULL_REG; return make_reg(0, f->_in->readUint16LE()); }