Initial commit
This commit is contained in:
826
engines/wintermute/base/scriptables/script_ext_file.cpp
Normal file
826
engines/wintermute/base/scriptables/script_ext_file.cpp
Normal file
@@ -0,0 +1,826 @@
|
||||
/* ScummVM - Graphic Adventure Engine
|
||||
*
|
||||
* ScummVM is the legal property of its developers, whose names
|
||||
* are too numerous to list here. Please refer to the COPYRIGHT
|
||||
* file distributed with this source distribution.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* This file is based on WME Lite.
|
||||
* http://dead-code.org/redir.php?target=wmelite
|
||||
* Copyright (c) 2011 Jan Nedoma
|
||||
*/
|
||||
|
||||
#include "engines/wintermute/system/sys_class_registry.h"
|
||||
#include "engines/wintermute/system/sys_class.h"
|
||||
#include "engines/wintermute/base/scriptables/script_stack.h"
|
||||
#include "engines/wintermute/base/scriptables/script_value.h"
|
||||
#include "engines/wintermute/base/scriptables/script.h"
|
||||
#include "engines/wintermute/utils/utils.h"
|
||||
#include "engines/wintermute/base/base_game.h"
|
||||
#include "engines/wintermute/base/base_engine.h"
|
||||
#include "engines/wintermute/base/base_file_manager.h"
|
||||
#include "engines/wintermute/base/file/base_savefile_manager_file.h"
|
||||
#include "engines/wintermute/platform_osystem.h"
|
||||
#include "engines/wintermute/base/scriptables/script_ext_file.h"
|
||||
#include "engines/wintermute/dcgf.h"
|
||||
|
||||
// Note: This code is completely untested, as I have yet to find a game that uses SXFile.
|
||||
|
||||
namespace Wintermute {
|
||||
|
||||
IMPLEMENT_PERSISTENT(SXFile, false)
|
||||
|
||||
BaseScriptable *makeSXFile(BaseGame *inGame, ScStack *stack) {
|
||||
return new SXFile(inGame, stack);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
SXFile::SXFile(BaseGame *inGame, ScStack *stack) : BaseScriptable(inGame) {
|
||||
stack->correctParams(1);
|
||||
ScValue *val = stack->pop();
|
||||
|
||||
_filename = nullptr;
|
||||
if (!val->isNULL()) {
|
||||
BaseUtils::setString(&_filename, val->getString());
|
||||
}
|
||||
|
||||
_readFile = nullptr;
|
||||
_writeFile = nullptr;
|
||||
|
||||
_mode = 0;
|
||||
_textMode = false;
|
||||
}
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
SXFile::~SXFile() {
|
||||
cleanup();
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void SXFile::cleanup() {
|
||||
SAFE_DELETE_ARRAY(_filename);
|
||||
close();
|
||||
}
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void SXFile::close() {
|
||||
if (_readFile) {
|
||||
_game->_fileManager->closeFile(_readFile);
|
||||
_readFile = nullptr;
|
||||
}
|
||||
if (_writeFile) {
|
||||
_writeFile->finalize();
|
||||
SAFE_DELETE(_writeFile);
|
||||
}
|
||||
_mode = 0;
|
||||
_textMode = false;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
const char *SXFile::scToString() {
|
||||
if (_filename && _filename[0]) {
|
||||
return _filename;
|
||||
} else {
|
||||
return "[file object]";
|
||||
}
|
||||
}
|
||||
|
||||
#define FILE_BUFFER_SIZE 32768
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
bool SXFile::scCallMethod(ScScript *script, ScStack *stack, ScStack *thisStack, const char *name) {
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// SetFilename
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
if (strcmp(name, "SetFilename") == 0) {
|
||||
stack->correctParams(1);
|
||||
const char *filename = stack->pop()->getString();
|
||||
cleanup();
|
||||
BaseUtils::setString(&_filename, filename);
|
||||
stack->pushNULL();
|
||||
return STATUS_OK;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// OpenAsText / OpenAsBinary
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
else if (strcmp(name, "OpenAsText") == 0 || strcmp(name, "OpenAsBinary") == 0) {
|
||||
stack->correctParams(1);
|
||||
close();
|
||||
_mode = stack->pop()->getInt(1);
|
||||
if (_mode < 1 || _mode > 3) {
|
||||
script->runtimeError("File.%s: invalid access mode. Setting read mode.", name);
|
||||
_mode = 1;
|
||||
}
|
||||
if (_mode == 1) {
|
||||
_readFile = _game->_fileManager->openFile(_filename);
|
||||
if (!_readFile) {
|
||||
//script->runtimeError("File.%s: Error opening file '%s' for reading.", name, _filename);
|
||||
close();
|
||||
} else {
|
||||
_textMode = strcmp(name, "OpenAsText") == 0;
|
||||
}
|
||||
} else {
|
||||
if (strcmp(name, "OpenAsText") == 0) {
|
||||
if (_mode == 2) {
|
||||
_writeFile = openForWrite(_filename, false);
|
||||
} else {
|
||||
_writeFile = openForAppend(_filename, false);
|
||||
}
|
||||
} else {
|
||||
if (_mode == 2) {
|
||||
_writeFile = openForWrite(_filename, true);
|
||||
} else {
|
||||
_writeFile = openForAppend(_filename, true);
|
||||
}
|
||||
}
|
||||
|
||||
if (!_writeFile) {
|
||||
//script->runtimeError("File.%s: Error opening file '%s' for writing.", name, _filename);
|
||||
close();
|
||||
} else {
|
||||
_textMode = strcmp(name, "OpenAsText") == 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (_readFile || _writeFile) {
|
||||
stack->pushBool(true);
|
||||
} else {
|
||||
stack->pushBool(false);
|
||||
}
|
||||
|
||||
return STATUS_OK;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Close
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
else if (strcmp(name, "Close") == 0) {
|
||||
stack->correctParams(0);
|
||||
close();
|
||||
stack->pushNULL();
|
||||
return STATUS_OK;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// SetPosition
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
else if (strcmp(name, "SetPosition") == 0) {
|
||||
stack->correctParams(1);
|
||||
if (_mode == 0) {
|
||||
script->runtimeError("File.%s: File is not open", name);
|
||||
stack->pushBool(false);
|
||||
} else {
|
||||
int pos = stack->pop()->getInt();
|
||||
stack->pushBool(setPos(pos));
|
||||
}
|
||||
return STATUS_OK;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Delete
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
else if (strcmp(name, "Delete") == 0) {
|
||||
stack->correctParams(0);
|
||||
close();
|
||||
stack->pushBool(sfmFileRemove(_filename));
|
||||
return STATUS_OK;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Copy
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
else if (strcmp(name, "Copy") == 0) {
|
||||
stack->correctParams(2);
|
||||
/* const char *dest = */ stack->pop()->getString();
|
||||
/* bool overwrite = */ stack->pop()->getBool(true);
|
||||
|
||||
// Known game that need this:
|
||||
// * Space Madness (to copy bonus wallpapers from data.dcp to /saves/ folder)
|
||||
// * games by Rootfix intertainment (to save temporary screenshot as savegame screenshot)
|
||||
warning("SXFile-Method: Copy not supported");
|
||||
|
||||
stack->pushBool(false);
|
||||
return STATUS_OK;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// ReadLine
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
else if (strcmp(name, "ReadLine") == 0) {
|
||||
stack->correctParams(0);
|
||||
if (!_textMode || !_readFile) {
|
||||
script->runtimeError("File.%s: File must be open in text mode.", name);
|
||||
stack->pushNULL();
|
||||
return STATUS_OK;
|
||||
}
|
||||
uint32 bufSize = FILE_BUFFER_SIZE;
|
||||
byte *buf = (byte *)malloc(bufSize);
|
||||
uint32 counter = 0;
|
||||
byte b;
|
||||
bool foundNewLine = false;
|
||||
bool ret = STATUS_FAILED;
|
||||
do {
|
||||
ret = _readFile->read(&b, 1);
|
||||
if (ret != 1) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (counter > bufSize) {
|
||||
buf = (byte *)realloc(buf, bufSize + FILE_BUFFER_SIZE);
|
||||
bufSize += FILE_BUFFER_SIZE;
|
||||
}
|
||||
if (b == '\n') {
|
||||
buf[counter] = '\0';
|
||||
foundNewLine = true;
|
||||
break;
|
||||
} else if (b == 0x0D) {
|
||||
continue;
|
||||
} else {
|
||||
buf[counter] = b;
|
||||
counter++;
|
||||
}
|
||||
} while (DID_SUCCEED(ret));
|
||||
|
||||
if (counter > bufSize) {
|
||||
buf = (byte *)realloc(buf, bufSize + FILE_BUFFER_SIZE);
|
||||
bufSize += FILE_BUFFER_SIZE;
|
||||
}
|
||||
buf[counter] = '\0';
|
||||
|
||||
if (!foundNewLine && counter == 0) {
|
||||
stack->pushNULL();
|
||||
} else {
|
||||
stack->pushString((char *)buf);
|
||||
}
|
||||
|
||||
free(buf);
|
||||
|
||||
return STATUS_OK;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// ReadText
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
else if (strcmp(name, "ReadText") == 0) {
|
||||
stack->correctParams(1);
|
||||
int textLen = stack->pop()->getInt();
|
||||
|
||||
if (!_textMode || !_readFile) {
|
||||
script->runtimeError("File.%s: File must be open in text mode.", name);
|
||||
stack->pushNULL();
|
||||
return STATUS_OK;
|
||||
}
|
||||
uint32 bufSize = FILE_BUFFER_SIZE;
|
||||
byte *buf = (byte *)malloc(bufSize);
|
||||
uint32 counter = 0;
|
||||
byte b;
|
||||
|
||||
bool ret = STATUS_FAILED;
|
||||
while (counter < (uint32)textLen) {
|
||||
ret = _readFile->read(&b, 1);
|
||||
if (ret != 1) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (counter > bufSize) {
|
||||
buf = (byte *)realloc(buf, bufSize + FILE_BUFFER_SIZE);
|
||||
bufSize += FILE_BUFFER_SIZE;
|
||||
}
|
||||
if (b == 0x0D) {
|
||||
continue;
|
||||
} else {
|
||||
buf[counter] = b;
|
||||
counter++;
|
||||
}
|
||||
}
|
||||
|
||||
if (counter > bufSize) {
|
||||
buf = (byte *)realloc(buf, bufSize + FILE_BUFFER_SIZE);
|
||||
bufSize += FILE_BUFFER_SIZE;
|
||||
}
|
||||
buf[counter] = '\0';
|
||||
|
||||
if (textLen > 0 && counter == 0) {
|
||||
stack->pushNULL();
|
||||
} else {
|
||||
stack->pushString((char *)buf);
|
||||
}
|
||||
|
||||
free(buf);
|
||||
|
||||
return STATUS_OK;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// WriteLine / WriteText
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
else if (strcmp(name, "WriteLine") == 0 || strcmp(name, "WriteText") == 0) {
|
||||
stack->correctParams(1);
|
||||
const char *line = stack->pop()->getString();
|
||||
if (!_textMode || !_writeFile) {
|
||||
script->runtimeError("File.%s: File must be open for writing in text mode.", name);
|
||||
stack->pushBool(false);
|
||||
return STATUS_OK;
|
||||
}
|
||||
Common::String writeLine;
|
||||
if (strcmp(name, "WriteLine") == 0) {
|
||||
writeLine = Common::String::format("%s\n", line);
|
||||
} else {
|
||||
writeLine = Common::String::format("%s", line);
|
||||
}
|
||||
_writeFile->writeString(writeLine);
|
||||
stack->pushBool(true);
|
||||
|
||||
return STATUS_OK;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// ReadBool
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
else if (strcmp(name, "ReadBool") == 0) {
|
||||
stack->correctParams(0);
|
||||
if (_textMode || !_readFile) {
|
||||
script->runtimeError("File.%s: File must be open for reading in binary mode.", name);
|
||||
stack->pushNULL();
|
||||
return STATUS_OK;
|
||||
}
|
||||
byte val;
|
||||
if (_readFile->read(&val, sizeof(byte))) {
|
||||
stack->pushBool(val != 0);
|
||||
} else {
|
||||
stack->pushNULL();
|
||||
}
|
||||
|
||||
return STATUS_OK;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// ReadByte
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
else if (strcmp(name, "ReadByte") == 0) {
|
||||
stack->correctParams(0);
|
||||
if (_textMode || !_readFile) {
|
||||
script->runtimeError("File.%s: File must be open for reading in binary mode.", name);
|
||||
stack->pushNULL();
|
||||
return STATUS_OK;
|
||||
}
|
||||
byte val = _readFile->readByte();
|
||||
if (!_readFile->err()) {
|
||||
stack->pushInt(val);
|
||||
} else {
|
||||
stack->pushNULL();
|
||||
}
|
||||
|
||||
return STATUS_OK;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// ReadShort
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
else if (strcmp(name, "ReadShort") == 0) {
|
||||
stack->correctParams(0);
|
||||
if (_textMode || !_readFile) {
|
||||
script->runtimeError("File.%s: File must be open for reading in binary mode.", name);
|
||||
stack->pushNULL();
|
||||
return STATUS_OK;
|
||||
}
|
||||
int16 val = _readFile->readSint16LE();
|
||||
if (!_readFile->err()) {
|
||||
stack->pushInt(65536 + val);
|
||||
} else {
|
||||
stack->pushNULL();
|
||||
}
|
||||
return STATUS_OK;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// ReadInt / ReadLong
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
else if (strcmp(name, "ReadInt") == 0 || strcmp(name, "ReadLong") == 0) {
|
||||
stack->correctParams(0);
|
||||
if (_textMode || !_readFile) {
|
||||
script->runtimeError("File.%s: File must be open for reading in binary mode.", name);
|
||||
stack->pushNULL();
|
||||
return STATUS_OK;
|
||||
}
|
||||
int32 val = _readFile->readSint32LE();
|
||||
if (!_readFile->err()) {
|
||||
stack->pushInt(val);
|
||||
} else {
|
||||
stack->pushNULL();
|
||||
}
|
||||
|
||||
return STATUS_OK;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// ReadFloat
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
else if (strcmp(name, "ReadFloat") == 0) {
|
||||
stack->correctParams(0);
|
||||
if (_textMode || !_readFile) {
|
||||
script->runtimeError("File.%s: File must be open for reading in binary mode.", name);
|
||||
stack->pushNULL();
|
||||
return STATUS_OK;
|
||||
}
|
||||
float val = _readFile->readFloatLE();
|
||||
if (!_readFile->err()) {
|
||||
stack->pushFloat(val);
|
||||
} else {
|
||||
stack->pushNULL();
|
||||
}
|
||||
|
||||
return STATUS_OK;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// ReadDouble
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
else if (strcmp(name, "ReadDouble") == 0) {
|
||||
stack->correctParams(0);
|
||||
if (_textMode || !_readFile) {
|
||||
script->runtimeError("File.%s: File must be open for reading in binary mode.", name);
|
||||
stack->pushNULL();
|
||||
return STATUS_OK;
|
||||
}
|
||||
double val = _readFile->readDoubleLE();
|
||||
if (!_readFile->err()) {
|
||||
stack->pushFloat(val);
|
||||
} else {
|
||||
stack->pushNULL();
|
||||
}
|
||||
|
||||
return STATUS_OK;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// ReadString
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
else if (strcmp(name, "ReadString") == 0) {
|
||||
stack->correctParams(0);
|
||||
if (_textMode || !_readFile) {
|
||||
script->runtimeError("File.%s: File must be open for reading in binary mode.", name);
|
||||
stack->pushNULL();
|
||||
return STATUS_OK;
|
||||
}
|
||||
uint32 size = _readFile->readUint32LE();
|
||||
if (!_readFile->err()) {
|
||||
byte *str = new byte[size + 1];
|
||||
if (str) {
|
||||
if (_readFile->read(str, size) == size) {
|
||||
str[size] = '\0';
|
||||
stack->pushString((char *)str);
|
||||
}
|
||||
delete[] str;
|
||||
} else {
|
||||
stack->pushNULL();
|
||||
}
|
||||
} else {
|
||||
stack->pushNULL();
|
||||
}
|
||||
|
||||
return STATUS_OK;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// WriteBool
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
else if (strcmp(name, "WriteBool") == 0) {
|
||||
stack->correctParams(1);
|
||||
bool val = stack->pop()->getBool();
|
||||
|
||||
if (_textMode || !_writeFile) {
|
||||
script->runtimeError("File.%s: File must be open for writing in binary mode.", name);
|
||||
stack->pushBool(false);
|
||||
return STATUS_OK;
|
||||
}
|
||||
_writeFile->writeByte(val);
|
||||
stack->pushBool(true);
|
||||
|
||||
return STATUS_OK;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// WriteByte
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
else if (strcmp(name, "WriteByte") == 0) {
|
||||
stack->correctParams(1);
|
||||
byte val = stack->pop()->getInt();
|
||||
|
||||
if (_textMode || !_writeFile) {
|
||||
script->runtimeError("File.%s: File must be open for writing in binary mode.", name);
|
||||
stack->pushBool(false);
|
||||
return STATUS_OK;
|
||||
}
|
||||
_writeFile->writeByte(val);
|
||||
stack->pushBool(true);
|
||||
|
||||
return STATUS_OK;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// WriteShort
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
else if (strcmp(name, "WriteShort") == 0) {
|
||||
stack->correctParams(1);
|
||||
int16 val = stack->pop()->getInt();
|
||||
|
||||
if (_textMode || !_writeFile) {
|
||||
script->runtimeError("File.%s: File must be open for writing in binary mode.", name);
|
||||
stack->pushBool(false);
|
||||
return STATUS_OK;
|
||||
}
|
||||
_writeFile->writeSint16LE(val);
|
||||
stack->pushBool(true);
|
||||
|
||||
return STATUS_OK;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// WriteInt / WriteLong
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
else if (strcmp(name, "WriteInt") == 0 || strcmp(name, "WriteLong") == 0) {
|
||||
stack->correctParams(1);
|
||||
int32 val = stack->pop()->getInt();
|
||||
|
||||
if (_textMode || !_writeFile) {
|
||||
script->runtimeError("File.%s: File must be open for writing in binary mode.", name);
|
||||
stack->pushBool(false);
|
||||
return STATUS_OK;
|
||||
}
|
||||
_writeFile->writeSint32LE(val);
|
||||
stack->pushBool(true);
|
||||
|
||||
return STATUS_OK;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// WriteFloat
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
else if (strcmp(name, "WriteFloat") == 0) {
|
||||
stack->correctParams(1);
|
||||
float val = stack->pop()->getFloat();
|
||||
|
||||
if (_textMode || !_writeFile) {
|
||||
script->runtimeError("File.%s: File must be open for writing in binary mode.", name);
|
||||
stack->pushBool(false);
|
||||
return STATUS_OK;
|
||||
}
|
||||
uint32 *ptr = (uint32 *)&val;
|
||||
_writeFile->writeUint32LE(*ptr);
|
||||
stack->pushBool(true);
|
||||
|
||||
return STATUS_OK;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// WriteDouble
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
else if (strcmp(name, "WriteDouble") == 0) {
|
||||
stack->correctParams(1);
|
||||
double val = stack->pop()->getFloat();
|
||||
|
||||
if (_textMode || !_writeFile) {
|
||||
script->runtimeError("File.%s: File must be open for writing in binary mode.", name);
|
||||
stack->pushBool(false);
|
||||
return STATUS_OK;
|
||||
}
|
||||
_writeFile->writeDoubleLE(val);
|
||||
stack->pushBool(true);
|
||||
|
||||
return STATUS_OK;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// WriteString
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
else if (strcmp(name, "WriteString") == 0) {
|
||||
stack->correctParams(1);
|
||||
const char *val = stack->pop()->getString();
|
||||
|
||||
if (_textMode || !_writeFile) {
|
||||
script->runtimeError("File.%s: File must be open for writing in binary mode.", name);
|
||||
stack->pushBool(false);
|
||||
return STATUS_OK;
|
||||
}
|
||||
|
||||
uint32 size = strlen(val);
|
||||
_writeFile->writeUint32LE(size);
|
||||
_writeFile->writeString(val);
|
||||
|
||||
stack->pushBool(true);
|
||||
|
||||
return STATUS_OK;
|
||||
} else {
|
||||
return BaseScriptable::scCallMethod(script, stack, thisStack, name);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
ScValue *SXFile::scGetProperty(const char *name) {
|
||||
_scValue->setNULL();
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Type (RO)
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
if (strcmp(name, "Type") == 0) {
|
||||
_scValue->setString("file");
|
||||
return _scValue;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Filename (RO)
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
if (strcmp(name, "Filename") == 0) {
|
||||
_scValue->setString(_filename);
|
||||
return _scValue;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Position (RO)
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
else if (strcmp(name, "Position") == 0) {
|
||||
_scValue->setInt(getPos());
|
||||
return _scValue;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Length (RO)
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
else if (strcmp(name, "Length") == 0) {
|
||||
_scValue->setInt(getLength());
|
||||
return _scValue;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// TextMode (RO)
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
else if (strcmp(name, "TextMode") == 0) {
|
||||
_scValue->setBool(_textMode);
|
||||
return _scValue;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// AccessMode (RO)
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
else if (strcmp(name, "AccessMode") == 0) {
|
||||
_scValue->setInt(_mode);
|
||||
return _scValue;
|
||||
} else {
|
||||
return BaseScriptable::scGetProperty(name);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
bool SXFile::scSetProperty(const char *name, ScValue *value) {
|
||||
/*
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Length
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
if (strcmp(name, "Length")==0) {
|
||||
int origLength = _length;
|
||||
_length = MAX(value->getInt(0), 0);
|
||||
|
||||
char propName[20];
|
||||
if (_length < OrigLength) {
|
||||
for(int i=_length; i<OrigLength; i++) {
|
||||
Common::sprintf_s(PropName, "%d", i);
|
||||
_values->DeleteProp(PropName);
|
||||
}
|
||||
}
|
||||
return STATUS_OK;
|
||||
}
|
||||
else*/ return BaseScriptable::scSetProperty(name, value);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
uint32 SXFile::getPos() {
|
||||
if (_mode == 1 && _readFile) {
|
||||
return _readFile->pos();
|
||||
} else if ((_mode == 2 || _mode == 3) && _writeFile) {
|
||||
error("SXFile - getPos for WriteFile not supported");
|
||||
return 0;
|
||||
// return ftell((FILE *)_writeFile);
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
bool SXFile::setPos(uint32 pos, int whence) {
|
||||
if (_mode == 1 && _readFile) {
|
||||
return _readFile->seek(pos, whence);
|
||||
} else if ((_mode == 2 || _mode == 3) && _writeFile) {
|
||||
if (BaseEngine::instance().getGameId() != "royalmahjong") {
|
||||
error("SXFile - seeking in WriteFile not supported");
|
||||
}
|
||||
return false;
|
||||
// return fseek((FILE *)_writeFile, pos, (int)origin) == 0;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
uint32 SXFile::getLength() {
|
||||
if (_mode == 1 && _readFile) {
|
||||
return _readFile->size();
|
||||
} else if ((_mode == 2 || _mode == 3) && _writeFile) {
|
||||
error("SXFile - reading length for WriteFile not supported");
|
||||
return 0;
|
||||
/*
|
||||
uint32 currentPos = ftell((FILE *)_writeFile);
|
||||
fseek((FILE *)_writeFile, 0, SEEK_END);
|
||||
int ret = ftell((FILE *)_writeFile);
|
||||
fseek((FILE *)_writeFile, CurrentPos, SEEK_SET);
|
||||
return Ret;*/
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
bool SXFile::persist(BasePersistenceManager *persistMgr) {
|
||||
|
||||
BaseScriptable::persist(persistMgr);
|
||||
|
||||
persistMgr->transferCharPtr(TMEMBER(_filename));
|
||||
persistMgr->transferSint32(TMEMBER(_mode));
|
||||
persistMgr->transferBool(TMEMBER(_textMode));
|
||||
|
||||
uint32 pos = 0;
|
||||
if (persistMgr->getIsSaving()) {
|
||||
pos = getPos();
|
||||
persistMgr->transferUint32(TMEMBER(pos));
|
||||
} else {
|
||||
persistMgr->transferUint32(TMEMBER(pos));
|
||||
|
||||
// try to re-open file if needed
|
||||
_writeFile = nullptr;
|
||||
_readFile = nullptr;
|
||||
|
||||
if (_mode != 0) {
|
||||
// open for reading
|
||||
if (_mode == 1) {
|
||||
_readFile = _game->_fileManager->openFile(_filename);
|
||||
if (!_readFile) {
|
||||
close();
|
||||
}
|
||||
}
|
||||
// open for writing / appending
|
||||
else {
|
||||
if (_textMode) {
|
||||
if (_mode == 2) {
|
||||
_writeFile = openForWrite(_filename, false);
|
||||
} else {
|
||||
_writeFile = openForAppend(_filename, false);
|
||||
}
|
||||
} else {
|
||||
if (_mode == 2) {
|
||||
_writeFile = openForWrite(_filename, true);
|
||||
} else {
|
||||
_writeFile = openForAppend(_filename, true);
|
||||
}
|
||||
}
|
||||
if (_writeFile) {
|
||||
close();
|
||||
}
|
||||
}
|
||||
setPos(pos);
|
||||
}
|
||||
}
|
||||
|
||||
return STATUS_OK;
|
||||
}
|
||||
|
||||
Common::WriteStream *SXFile::openForWrite(const Common::String &filename, bool binary) {
|
||||
return BaseFileManager::getEngineInstance()->openFileForWrite(_filename);
|
||||
}
|
||||
|
||||
// Should replace fopen(..., "ab+") and fopen(..., "a+")
|
||||
Common::WriteStream *SXFile::openForAppend(const Common::String &filename, bool binary) {
|
||||
warning("SXFile::openForAppend - WriteFiles with limited support as non-append mode");
|
||||
return BaseFileManager::getEngineInstance()->openFileForWrite(_filename);
|
||||
}
|
||||
|
||||
} // End of namespace Wintermute
|
||||
Reference in New Issue
Block a user