aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--engines/gargoyle/files.cpp79
-rw-r--r--engines/gargoyle/files.h45
-rw-r--r--engines/gargoyle/gargoyle.h5
-rw-r--r--engines/gargoyle/glk.cpp42
-rw-r--r--engines/gargoyle/glk.h12
5 files changed, 148 insertions, 35 deletions
diff --git a/engines/gargoyle/files.cpp b/engines/gargoyle/files.cpp
index c3f1367c66..e14a315f09 100644
--- a/engines/gargoyle/files.cpp
+++ b/engines/gargoyle/files.cpp
@@ -21,12 +21,15 @@
*/
#include "gargoyle/files.h"
+#include "gargoyle/gargoyle.h"
#include "gui/saveload.h"
+#include "common/file.h"
+#include "common/savefile.h"
#include "common/translation.h"
namespace Gargoyle {
-frefid_t Files::prompt(glui32 usage, FileMode fmode, glui32 rock) {
+frefid_t Files::createByPrompt(glui32 usage, FileMode fmode, glui32 rock) {
switch (usage & fileusage_TypeMask) {
case fileusage_SavedGame: {
if (fmode == filemode_Write) {
@@ -64,34 +67,94 @@ frefid_t Files::prompt(glui32 usage, FileMode fmode, glui32 rock) {
}
frefid_t Files::createRef(int slot, const Common::String &desc, glui32 usage, glui32 rock) {
- _fileReferences.push_back(FileReference());
- frefid_t fref = &_fileReferences.back();
-
+ frefid_t fref = new FileReference();
fref->_slotNumber = slot;
fref->_description = desc;
fref->_textMode = ((usage & fileusage_TextMode) != 0);
fref->_fileType = (FileUsage)(usage & fileusage_TypeMask);
+
+ _fileReferences.push_back(FileRefArray::value_type(fref));
return fref;
}
frefid_t Files::createRef(const Common::String &filename, glui32 usage, glui32 rock) {
- _fileReferences.push_back(FileReference());
- frefid_t fref = &_fileReferences.back();
-
+ frefid_t fref = new FileReference();
fref->_filename = filename;
fref->_textMode = ((usage & fileusage_TextMode) != 0);
fref->_fileType = (FileUsage)(usage & fileusage_TypeMask);
+
+ _fileReferences.push_back(FileRefArray::value_type(fref));
return fref;
}
+frefid_t Files::createTemp(glui32 usage, glui32 rock) {
+ return createRef(Common::String::format("%s.tmp", g_vm->getTargetName().c_str()),
+ usage, rock);
+}
+
+frefid_t Files::createFromRef(frefid_t fref, glui32 usage, glui32 rock) {
+ return createRef(fref->_filename, usage, rock);
+}
+
void Files::deleteRef(frefid_t fref) {
for (uint idx = 0; idx < _fileReferences.size(); ++idx) {
- if (&_fileReferences[idx] == fref) {
+ if (_fileReferences[idx].get() == fref) {
_fileReferences.remove_at(idx);
return;
}
}
}
+frefid_t Files::iterate(frefid_t fref, glui32 *rock) {
+ // Find reference following the specified one
+ int index = -1;
+ for (uint idx = 0; idx < _fileReferences.size(); ++idx) {
+ if (fref == nullptr || _fileReferences[idx].get() == fref) {
+ if (idx < (_fileReferences.size() - 1))
+ index = idx + 1;
+ break;
+ }
+ }
+
+ if (index != -1) {
+ if (rock)
+ *rock = _fileReferences[index].get()->_rock;
+ return _fileReferences[index].get();
+ }
+
+ if (rock)
+ *rock = 0;
+ return nullptr;
+}
+
+/*--------------------------------------------------------------------------*/
+
+const Common::String FileReference::getSaveName() const {
+ assert(_slotNumber != -1);
+ return Common::String::format("%s.%.3d", g_vm->getTargetName().c_str(), _slotNumber);
+}
+
+bool FileReference::exists() const {
+ Common::String filename;
+
+ if (_slotNumber == -1) {
+ if (Common::File::exists(_filename))
+ return true;
+ filename = _filename;
+ } else {
+ filename = getSaveName();
+ }
+
+ // Check for a savegame (or other file in the save folder) with that name
+ Common::InSaveFile *inSave = g_system->getSavefileManager()->openForLoading(filename);
+ bool result = inSave != nullptr;
+ delete inSave;
+ return result;
+}
+
+void FileReference::deleteFile() {
+ Common::String filename = (_slotNumber == -1) ? _filename : getSaveName();
+ g_system->getSavefileManager()->removeSavefile(filename);
+}
} // End of namespace Gargoyle
diff --git a/engines/gargoyle/files.h b/engines/gargoyle/files.h
index cfd757b053..7e7ebfb726 100644
--- a/engines/gargoyle/files.h
+++ b/engines/gargoyle/files.h
@@ -25,6 +25,7 @@
#include "gargoyle/glk_types.h"
#include "common/array.h"
+#include "common/ptr.h"
#include "common/str.h"
namespace Gargoyle {
@@ -65,17 +66,39 @@ struct FileReference {
FileUsage _fileType;
bool _textMode;
gidispatch_rock_t _dispRock;
+
+ /**
+ * Constructor
+ */
+ FileReference() : _rock(0), _slotNumber(-1), _fileType(fileusage_Data), _textMode(false) {}
+
+ /**
+ * Get savegame filename
+ */
+ const Common::String getSaveName() const;
+
+ /**
+ * Returns true if the given file exists
+ */
+ bool exists() const;
+
+ /**
+ * Delete the given file
+ */
+ void deleteFile();
};
+
typedef FileReference *frefid_t;
+typedef Common::Array< Common::SharedPtr<FileReference> > FileRefArray;
class Files {
private:
- Common::Array<FileReference> _fileReferences;
+ FileRefArray _fileReferences;
public:
/**
- * Prompt for a file
+ * Prompt for a savegame to load or save, and populate a file reference from the result
*/
- frefid_t prompt(glui32 usage, FileMode fmode, glui32 rock);
+ frefid_t createByPrompt(glui32 usage, FileMode fmode, glui32 rock);
/**
* Create a new file reference
@@ -88,9 +111,25 @@ public:
frefid_t createRef(const Common::String &filename, glui32 usage, glui32 rock);
/**
+ * Create a new temporary file reference
+ */
+ frefid_t createTemp(glui32 usage, glui32 rock);
+
+ /**
+ * Create a new file reference from an old one
+ */
+ frefid_t createFromRef(frefid_t fref, glui32 usage, glui32 rock);
+
+ /**
* Delete a file reference
*/
void deleteRef(frefid_t fref);
+
+ /**
+ * Iterates to the next file reference following the specified one,
+ * or the first if null is passed
+ */
+ frefid_t iterate(frefid_t fref, glui32 *rock);
};
} // End of namespace Gargoyle
diff --git a/engines/gargoyle/gargoyle.h b/engines/gargoyle/gargoyle.h
index 3538b4c825..651499e4e8 100644
--- a/engines/gargoyle/gargoyle.h
+++ b/engines/gargoyle/gargoyle.h
@@ -138,6 +138,11 @@ public:
* Returns the primary filename for the game
*/
const Common::String &GargoyleEngine::getFilename() const;
+
+ /**
+ * Return the game engine's target name
+ */
+ const Common::String &getTargetName() const { return _targetName; }
};
extern GargoyleEngine *g_vm;
diff --git a/engines/gargoyle/glk.cpp b/engines/gargoyle/glk.cpp
index 2f9f57ed84..7805207eb0 100644
--- a/engines/gargoyle/glk.cpp
+++ b/engines/gargoyle/glk.cpp
@@ -459,23 +459,31 @@ glui32 Glk::glk_style_measure(winid_t win, glui32 styl, glui32 hint, glui32 *res
}
frefid_t Glk::glk_fileref_create_temp(glui32 usage, glui32 rock) {
- // TODO
- return nullptr;
+ return _files->createTemp(usage, rock);
}
-frefid_t Glk::glk_fileref_create_by_name(glui32 usage, char *name, glui32 rock) {
- // TODO
- return nullptr;
+frefid_t Glk::glk_fileref_create_by_name(glui32 usage, const char *name, glui32 rock) {
+ // Take out all dangerous characters
+ Common::String tempName(name);
+ for (uint idx = 0; idx < tempName.size(); ++idx) {
+ if (tempName[idx] == '/' || tempName[idx] == '\\' || tempName[idx] == ':')
+ tempName.setChar(idx, '-');
+ }
+
+ return _files->createRef(tempName, usage, rock);
}
frefid_t Glk::glk_fileref_create_by_prompt(glui32 usage, FileMode fmode, glui32 rock) {
- // TODO
- return nullptr;
+ return _files->createByPrompt(usage, fmode, rock);
}
frefid_t Glk::glk_fileref_create_from_fileref(glui32 usage, frefid_t fref, glui32 rock) {
- // TODO
- return nullptr;
+ if (!fref) {
+ warning("fileref_create_from_fileref: invalid ref");
+ return nullptr;
+ } else {
+ return _files->createFromRef(fref, usage, rock);
+ }
}
void Glk::glk_fileref_destroy(frefid_t fref) {
@@ -483,22 +491,24 @@ void Glk::glk_fileref_destroy(frefid_t fref) {
}
frefid_t Glk::glk_fileref_iterate(frefid_t fref, glui32 *rockptr) {
- // TODO
- return nullptr;
+ return _files->iterate(fref, rockptr);
}
glui32 Glk::glk_fileref_get_rock(frefid_t fref) {
- // TODO
- return 0;
+ if (!fref) {
+ warning("fileref_get_rock: invalid ref.");
+ return 0;
+ } else {
+ return fref->_rock;
+ }
}
void Glk::glk_fileref_delete_file(frefid_t fref) {
- // TODO
+ fref->deleteFile();
}
glui32 Glk::glk_fileref_does_file_exist(frefid_t fref) {
- // TODO
- return 0;
+ return fref->exists();
}
void Glk::glk_select(event_t *event) {
diff --git a/engines/gargoyle/glk.h b/engines/gargoyle/glk.h
index 0124cb1b40..ccd2e5b20d 100644
--- a/engines/gargoyle/glk.h
+++ b/engines/gargoyle/glk.h
@@ -112,16 +112,12 @@ public:
glsi32 val);
void glk_stylehint_clear(glui32 wintype, glui32 styl, glui32 hint);
glui32 glk_style_distinguish(winid_t win, glui32 styl1, glui32 styl2);
- glui32 glk_style_measure(winid_t win, glui32 styl, glui32 hint,
- glui32 *result);
+ glui32 glk_style_measure(winid_t win, glui32 styl, glui32 hint, glui32 *result);
frefid_t glk_fileref_create_temp(glui32 usage, glui32 rock);
- frefid_t glk_fileref_create_by_name(glui32 usage, char *name,
- glui32 rock);
- frefid_t glk_fileref_create_by_prompt(glui32 usage, FileMode fmode,
- glui32 rock);
- frefid_t glk_fileref_create_from_fileref(glui32 usage, frefid_t fref,
- glui32 rock);
+ frefid_t glk_fileref_create_by_name(glui32 usage, const char *name, glui32 rock);
+ frefid_t glk_fileref_create_by_prompt(glui32 usage, FileMode fmode, glui32 rock);
+ frefid_t glk_fileref_create_from_fileref(glui32 usage, frefid_t fref, glui32 rock);
void glk_fileref_destroy(frefid_t fref);
frefid_t glk_fileref_iterate(frefid_t fref, glui32 *rockptr);
glui32 glk_fileref_get_rock(frefid_t fref);