315 lines
12 KiB
C++
315 lines
12 KiB
C++
/* 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/>.
|
|
*
|
|
*/
|
|
|
|
#include "common/savefile.h"
|
|
#include "common/file.h"
|
|
#include "gui/filebrowser-dialog.h"
|
|
#include "gui/browser.h"
|
|
#include "director/director.h"
|
|
#include "director/picture.h"
|
|
#include "director/types.h"
|
|
#include "director/util.h"
|
|
#include "director/lingo/lingo.h"
|
|
#include "director/lingo/lingo-object.h"
|
|
#include "director/lingo/lingo-utils.h"
|
|
#include "director/lingo/xlibs/m/msfile.h"
|
|
|
|
/*************************************
|
|
*
|
|
* USED IN:
|
|
* The Simpsons Cartoon Studio
|
|
*
|
|
*************************************/
|
|
|
|
/*
|
|
"I mNew --Instantiates XObject" 1028:0023 string 56
|
|
"X mDispose --Removes XObject Instance" 1028:005b string 60
|
|
"S mName --Returns XObject Name" 1028:0097 string 56
|
|
"SS mGetFullDirList, dospath --Returns MS-DOS Full Directory List (use *.*)" 1028:00cf string 80
|
|
"SS mGetFileList, dospath --Returns MS-DOS File List (use *.*)" 1028:011f string 70
|
|
"SS mGetDirList, dospath --Returns MS-DOS Directory List (use *.*)" 1028:0165 string 75
|
|
"II mGetDiskFree, drive --Returns Free disk space, drive is 0 for current, 1 for A, ..." 1028:01b0 string 97
|
|
"SS mGetVolLabel, drive --Returns Drive Label (use d:\\*.*)" 1028:0211 string 68
|
|
"IS mCreateDir, dospath --Creates an MS-DOS Directory" 1028:0255 string 63
|
|
"IS mRemoveDir, dospath --Removes an MS-DOS Directory" 1028:0294 string 63
|
|
"S mGetCurrDir --Returns Current Working Directory" 1028:02d3 string 69
|
|
"IS mSetCurrDir, dospath --Sets Current Working Directory" 1028:0318 string 66
|
|
"IS mRemoveFile, dospath --Deletes File named by dospath" 1028:035a string 65
|
|
"ISS mRenameFile, oldpath ,newpath --Renames File named by oldpath" 1028:039b string 74
|
|
"ISS mCopyFile, srcpath, destpath --Copys srcpath to destpath, overwrites" 1028:03e5 string 82
|
|
"ISSI mCopyFiles, srcpath, destpath, incsubdir --Copys srcpath to destpath, overwrites" 1028:0437 string 90
|
|
"ISSSS mSetAppINI, app, key, string, file --Sets app.ini" 1028:0491 string 57
|
|
"SSSS mGetAppINI, app, key, file --Gets app.ini" 1028:04ca string 57
|
|
"S mGetWindowsDirectory --Gets Windows directory path" 1028:0503 string 72
|
|
"I mGetWinVer --Gets Windows major version number" 1028:054b string 78
|
|
"I mRestartWindows --Gets Windows major version number" 1028:0599 string 78
|
|
"SSSS mOpenFileDlg, title, defspec, file --Displays Director Open File Dialog Box" 1028:05e7 string 83
|
|
"SSSS mSaveFileDlg, title, defspec, file --Displays Director Save File Dialog Box" 1028:063a string 83
|
|
"SSSS mGetOFileName, deffile, filter, defext --Displays Open File Dialog Box" 1028:068d string 78
|
|
"SSSS mGetSFileName, deffile, filter, defext --Displays Save File Dialog Box" 1028:06db string 78
|
|
"SSSS mDisplayDlg, title, message, defspec --Displays Dialog Box" 1028:0729 string 66
|
|
"ISSSS mProgMgrAdd, group, command, title, icon --\r\r" 1028:076b string 57
|
|
*/
|
|
|
|
namespace Director {
|
|
|
|
const char *const MSFile::xlibName = "MSFile";
|
|
const XlibFileDesc MSFile::fileNames[] = {
|
|
{"MSFile", nullptr},
|
|
{"MSFILE16", nullptr},
|
|
{nullptr, nullptr},
|
|
};
|
|
|
|
static const MethodProto xlibMethods[] = {
|
|
// XObject
|
|
{"new", MSFile::m_new, 0, 0, 400},
|
|
{"dispose", MSFile::m_dispose, 0, 0, 400},
|
|
{"name", MSFile::m_name, 0, 1, 400},
|
|
{"getFullDirList", MSFile::m_getFullDirList, 1, 1, 400},
|
|
{"getFileList", MSFile::m_getFileList, 1, 1, 400},
|
|
{"getDirList", MSFile::m_getDirList, 1, 1, 400},
|
|
{"getDiskFree", MSFile::m_getDiskFree, 1, 1, 400},
|
|
{"getVolLabel", MSFile::m_getVolLabel, 1, 1, 400},
|
|
{"createDir", MSFile::m_createDir, 1, 1, 400},
|
|
{"removeDir", MSFile::m_removeDir, 1, 1, 400},
|
|
{"getCurrDir", MSFile::m_getCurrDir, 0, 1, 400},
|
|
{"setCurrDir", MSFile::m_setCurrDir, 1, 1, 400},
|
|
{"removeFile", MSFile::m_removeFile, 1, 1, 400},
|
|
{"renameFile", MSFile::m_renameFile, 2, 1, 400},
|
|
{"copyFile", MSFile::m_copyFile, 2, 1, 400},
|
|
{"copyFiles", MSFile::m_copyFiles, 3, 1, 400},
|
|
{"setAppINI", MSFile::m_setAppINI, 4, 1, 400},
|
|
{"getAppINI", MSFile::m_getAppINI, 3, 1, 400},
|
|
{"getWindowsDirectory", MSFile::m_getWindowsDirectory, 0, 1, 400},
|
|
{"getWinVer", MSFile::m_getWinVer, 0, 1, 400},
|
|
{"restartWindows", MSFile::m_restartWindows, 0 ,1, 400},
|
|
{"openFileDlg", MSFile::m_openFileDlg, 3, 1, 400},
|
|
{"saveFileDlg", MSFile::m_saveFileDlg, 3, 1, 400},
|
|
{"getOFileName", MSFile::m_getOFileName, 3, 1, 400},
|
|
{"getSFileName", MSFile::m_getSFileName, 3, 1, 400},
|
|
{"displayDlg", MSFile::m_displayDlg, 3, 1, 400},
|
|
{"progMgrAdd", MSFile::m_progMgrAdd, 4, 1, 400},
|
|
{nullptr, nullptr, 0, 0, 0}};
|
|
|
|
static const BuiltinProto xlibBuiltins[] = {
|
|
{nullptr, nullptr, 0, 0, 0, VOIDSYM}};
|
|
|
|
MSFileObject::MSFileObject(ObjectType objType) : Object<MSFileObject>("MSFile") {
|
|
_objType = objType;
|
|
_lastError = msErrorNone;
|
|
}
|
|
|
|
MSFileObject::MSFileObject(const MSFileObject &obj) : Object<MSFileObject>(obj) {
|
|
_objType = obj.getObjType();
|
|
_lastError = msErrorNone;
|
|
}
|
|
|
|
MSFileObject::~MSFileObject() {
|
|
}
|
|
|
|
void MSFileObject::dispose() {
|
|
_disposed = true;
|
|
}
|
|
|
|
bool MSFileObject::hasProp(const Common::String &propName) {
|
|
return (propName == "name");
|
|
}
|
|
|
|
Datum MSFileObject::getProp(const Common::String &propName) {
|
|
if (propName == "name")
|
|
return Datum(MSFile::xlibName);
|
|
warning("MSFile::getProp: unknown property '%s'", propName.c_str());
|
|
return Datum();
|
|
}
|
|
|
|
void MSFile::m_new(int nargs) {
|
|
Datum result = g_lingo->_state->me;
|
|
g_lingo->push(result);
|
|
}
|
|
|
|
XOBJSTUB(MSFile::m_dispose, 0)
|
|
XOBJSTUB(MSFile::m_name, "")
|
|
XOBJSTUB(MSFile::m_getFullDirList, "")
|
|
XOBJSTUB(MSFile::m_getFileList, "")
|
|
XOBJSTUB(MSFile::m_getDirList, "")
|
|
|
|
void MSFile::m_getDiskFree(int nargs) {
|
|
// We don't care about the drive letter. We will always just return 500 MB.
|
|
g_lingo->pop();
|
|
|
|
// 500 MB in KB
|
|
g_lingo->push(Datum(500 * 1024 * 1024));
|
|
}
|
|
|
|
void MSFile::m_getVolLabel(int nargs) {
|
|
Datum d = g_lingo->pop();
|
|
|
|
Common::String volLabel;
|
|
|
|
const char *gameId = g_director->getGameId();
|
|
if (strncmp(gameId, "simpsonsstudio", 14) == 0 || strncmp(gameId, "simpsonsplayer", 14) == 0) {
|
|
volLabel = "Simpsons";
|
|
} else {
|
|
warning("MSFile::m_getVolLabel(): Unsupported gameid '%s'", gameId);
|
|
}
|
|
|
|
g_lingo->push(volLabel);
|
|
}
|
|
|
|
XOBJSTUB(MSFile::m_createDir, 0)
|
|
XOBJSTUB(MSFile::m_removeDir, 0)
|
|
XOBJSTUB(MSFile::m_getCurrDir, "")
|
|
XOBJSTUB(MSFile::m_setCurrDir, 0)
|
|
XOBJSTUB(MSFile::m_removeFile, 0)
|
|
XOBJSTUB(MSFile::m_renameFile, 0)
|
|
|
|
Common::Path MSFile::resolveSourceFilePath(const Common::String& srcParam) {
|
|
return findPath(srcParam);
|
|
}
|
|
|
|
Common::SeekableReadStream *MSFile::openSourceStream(const Common::Path &srcFilePath, const Common::String &srcParam, char dirSeparator) {
|
|
Common::SaveFileManager *saves = g_system->getSavefileManager();
|
|
Common::String prefix = savePrefix();
|
|
|
|
// The source file may be a save file in the ScummVM save folder.
|
|
Common::String saveFileName = lastPathComponent(srcParam, dirSeparator);
|
|
|
|
// Modify the source file name to match the name of the potential save file
|
|
if (!saveFileName.hasSuffixIgnoreCase(".txt")) {
|
|
saveFileName += ".txt";
|
|
}
|
|
|
|
if (!saveFileName.hasPrefixIgnoreCase(prefix)) {
|
|
saveFileName = prefix + saveFileName;
|
|
}
|
|
|
|
// Try to open the save file
|
|
Common::SeekableReadStream *srcReadStream = saves->openForLoading(saveFileName);
|
|
|
|
// If the save file was not found then we will try opening the file directly
|
|
if (!srcReadStream) {
|
|
// We have a relative path so we can open it using Common::File
|
|
Common::File *srcFile = new Common::File();
|
|
if (srcFilePath.empty() || !srcFile->open(srcFilePath)) {
|
|
warning("MSFile::m_copyFile(): Error opening file %s", srcFilePath.toString(Common::Path::kNativeSeparator).c_str());
|
|
delete srcFile;
|
|
return nullptr;
|
|
}
|
|
srcReadStream = srcFile;
|
|
}
|
|
|
|
return srcReadStream;
|
|
}
|
|
|
|
Common::SeekableWriteStream *MSFile::openDestinationStream(Common::String &destFileName) {
|
|
Common::SaveFileManager *saves = g_system->getSavefileManager();
|
|
Common::String prefix = savePrefix();
|
|
|
|
Common::OutSaveFile *destFile = nullptr;
|
|
|
|
if (!destFileName.hasSuffixIgnoreCase(".txt")) {
|
|
destFileName += ".txt";
|
|
}
|
|
|
|
if (!destFileName.hasPrefixIgnoreCase(prefix)) {
|
|
destFileName = prefix + destFileName;
|
|
}
|
|
|
|
destFile = saves->openForSaving(destFileName, false);
|
|
|
|
return destFile;
|
|
}
|
|
|
|
bool MSFile::copyStream(Common::SeekableReadStream* srcStream, Common::SeekableWriteStream* destStream) {
|
|
if (srcStream && destStream) {
|
|
destStream->writeStream(srcStream);
|
|
destStream->finalize();
|
|
bool success = !destStream->err();
|
|
delete destStream;
|
|
return success;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
bool MSFile::copyGameFile(const Common::String& srcParam, const Common::String& destParam) {
|
|
char dirSeparator = g_director->_dirSeparator;
|
|
Common::Path srcFilePath = resolveSourceFilePath(srcParam);
|
|
Common::String destFileName = Common::lastPathComponent(destParam, dirSeparator);
|
|
|
|
Common::SeekableReadStream *srcStream = openSourceStream(srcFilePath, srcParam, dirSeparator);
|
|
Common::SeekableWriteStream *destStream = openDestinationStream(destFileName);
|
|
|
|
return copyStream(srcStream, destStream);
|
|
}
|
|
|
|
void MSFile::m_copyFile(int nargs) {
|
|
Datum d2 = g_lingo->pop();
|
|
Datum d1 = g_lingo->pop();
|
|
|
|
// The source and destination file parameters are absolute paths from the games perspective but do not match the paths for ScummVM
|
|
Common::String srcParam = d1.asString();
|
|
Common::String destParam = d2.asString();
|
|
|
|
bool success = copyGameFile(srcParam, destParam);
|
|
|
|
g_lingo->push(Datum(success ? 0 : 1)); // Push 0 for success, 1 for failure
|
|
}
|
|
|
|
XOBJSTUB(MSFile::m_copyFiles, 0)
|
|
XOBJSTUB(MSFile::m_setAppINI, 0)
|
|
XOBJSTUB(MSFile::m_getAppINI, "")
|
|
XOBJSTUB(MSFile::m_getWindowsDirectory, "")
|
|
XOBJSTUB(MSFile::m_getWinVer, 0)
|
|
XOBJSTUB(MSFile::m_restartWindows, 0)
|
|
XOBJSTUB(MSFile::m_openFileDlg, "")
|
|
XOBJSTUB(MSFile::m_saveFileDlg, "")
|
|
|
|
void MSFile::m_getOFileName(int nargs) {
|
|
Datum d3 = g_lingo->pop();
|
|
Datum d2 = g_lingo->pop();
|
|
Datum d1 = g_lingo->pop();
|
|
|
|
Common::String defFile = d1.asString();
|
|
Common::String filter = d2.asString();
|
|
Common::String defExt = d3.asString();
|
|
|
|
g_lingo->push(getFileNameFromModal(false, defFile, filter, defExt.c_str()));
|
|
}
|
|
|
|
XOBJSTUB(MSFile::m_getSFileName, "")
|
|
XOBJSTUB(MSFile::m_displayDlg, "")
|
|
XOBJSTUB(MSFile::m_progMgrAdd, 0)
|
|
|
|
void MSFile::open(ObjectType type, const Common::Path &path) {
|
|
MSFileObject::initMethods(xlibMethods);
|
|
MSFileObject *xobj = new MSFileObject(type);
|
|
if (g_director->getVersion() >= 500)
|
|
g_lingo->_openXtras.push_back(xlibName);
|
|
g_lingo->exposeXObject(xlibName, xobj);
|
|
g_lingo->initBuiltIns(xlibBuiltins);
|
|
}
|
|
|
|
void MSFile::close(ObjectType type) {
|
|
g_lingo->_globalvars[xlibName] = Datum();
|
|
}
|
|
} // End of namespace Director
|