From d2d851b6efade86d0ef5226b198c6fa005a4e869 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jaakko=20Ker=C3=A4nen?= Date: Sat, 9 Jan 2016 11:02:18 +0200 Subject: [PATCH] libdoomsday: Added DataFile DataFile represents classic data files (WAD, LMP, etc.) in the file tree. Data files are accessible as byte arrays. --- .../include/doomsday/filesys/datafile.h | 72 ++++++++++++ doomsday/apps/libdoomsday/src/doomsdayapp.cpp | 6 +- .../apps/libdoomsday/src/filesys/datafile.cpp | 107 ++++++++++++++++++ .../sdk/libcore/include/de/filesys/file.h | 2 +- doomsday/sdk/libcore/src/filesys/file.cpp | 4 +- 5 files changed, 187 insertions(+), 4 deletions(-) create mode 100644 doomsday/apps/libdoomsday/include/doomsday/filesys/datafile.h create mode 100644 doomsday/apps/libdoomsday/src/filesys/datafile.cpp diff --git a/doomsday/apps/libdoomsday/include/doomsday/filesys/datafile.h b/doomsday/apps/libdoomsday/include/doomsday/filesys/datafile.h new file mode 100644 index 0000000000..1672d2b883 --- /dev/null +++ b/doomsday/apps/libdoomsday/include/doomsday/filesys/datafile.h @@ -0,0 +1,72 @@ +/** @file datafile.h FS2 File for classic data files: PK3, WAD, LMP, DED, DEH. + * + * @authors Copyright (c) 2016 Jaakko Keränen + * + * @par License + * GPL: http://www.gnu.org/licenses/gpl.html + * + * 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 2 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 + */ + +#ifndef LIBDOOMSDAY_DATAFILE_H +#define LIBDOOMSDAY_DATAFILE_H + +#include "../libdoomsday.h" +#include +#include + +/** + * Interpreter (for libcore FS) for classic data files: PK3, WAD, LMP, DED, DEH. + * + * Generates Doomsday 2 compatible metadata for data files, allowing them to + * be treated as packages at runtime. + * + * As packages, DataFile makes sure that the data gets loaded and unloaded + * when games are loaded (and in the right order). The data is actually loaded + * using the resource subsystem. To facilitate that, data file contents are + * available as plain byte arrays. + */ +class LIBDOOMSDAY_PUBLIC DataFile : public de::ByteArrayFile +{ +public: + enum Format { Pk3, Wad, Lump, Ded, Dehacked }; + +public: + ~DataFile(); + + de::String describe() const; + Format format() const; + + // Implements IByteArray. + Size size() const; + void get(Offset at, Byte *values, Size count) const; + void set(Offset at, Byte const *values, Size count); + +public: + struct LIBDOOMSDAY_PUBLIC Interpreter : public de::filesys::IInterpreter { + de::File *interpretFile(de::File *sourceData) const override; + }; + +protected: + /** + * Constructs a DataFile. The constructor is protected because DataFile is + * used as an interpreter so it gets created via IInterpreter. + * + * @param format Classic data file format. + * @param name Name of the file. + */ + DataFile(Format format, de::String const &name = ""); + +private: + DENG2_PRIVATE(d) +}; + +#endif // LIBDOOMSDAY_DATAFILE_H diff --git a/doomsday/apps/libdoomsday/src/doomsdayapp.cpp b/doomsday/apps/libdoomsday/src/doomsdayapp.cpp index 4b7a38b84c..2ee0f020de 100644 --- a/doomsday/apps/libdoomsday/src/doomsdayapp.cpp +++ b/doomsday/apps/libdoomsday/src/doomsdayapp.cpp @@ -13,12 +13,13 @@ * 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 + * http://www.gnu.org/licenses */ #include "doomsday/doomsdayapp.h" #include "doomsday/filesys/sys_direc.h" #include "doomsday/filesys/fs_util.h" +#include "doomsday/filesys/datafile.h" #include "doomsday/paths.h" #include @@ -173,6 +174,9 @@ DoomsdayApp::DoomsdayApp(Players::Constructor playerConstructor) { DENG2_ASSERT(!theDoomsdayApp); theDoomsdayApp = this; + + static DataFile::Interpreter intrpDataFile; + App::fileSystem().addInterpreter(intrpDataFile); } void DoomsdayApp::determineGlobalPaths() diff --git a/doomsday/apps/libdoomsday/src/filesys/datafile.cpp b/doomsday/apps/libdoomsday/src/filesys/datafile.cpp new file mode 100644 index 0000000000..dbf68bc9e7 --- /dev/null +++ b/doomsday/apps/libdoomsday/src/filesys/datafile.cpp @@ -0,0 +1,107 @@ +/** @file datafile.cpp FS2 File for classic data files: PK3, WAD, LMP, DED, DEH. + * + * @authors Copyright (c) 2016 Jaakko Keränen + * + * @par License + * GPL: http://www.gnu.org/licenses/gpl.html + * + * 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 2 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 "doomsday/filesys/datafile.h" + +using namespace de; + +namespace internal +{ + static char const *formatDescriptions[] = + { + "PK3 archive", + "WAD file", + "data lump", + "DED definitions", + "DeHackEd patch" + }; +} + +DENG2_PIMPL(DataFile) +{ + Format format; + + Instance(Public *i, Format fmt) : Base(i), format(fmt) + {} +}; + +DataFile::DataFile(Format format, String const &name) + : ByteArrayFile(name) + , d(new Instance(this, format)) +{} + +DataFile::~DataFile() +{ + DENG2_FOR_AUDIENCE2(Deletion, i) i->fileBeingDeleted(*this); + audienceForDeletion().clear(); + deindex(); +} + +String DataFile::describe() const +{ + return QString("%1 \"%2\"") + .arg(internal::formatDescriptions[d->format]) + .arg(name().fileNameWithoutExtension()); +} + +IByteArray::Size DataFile::size() const +{ + DENG2_ASSERT(source()); + return source()->size(); +} + +void DataFile::get(Offset at, Byte *values, Size count) const +{ + DENG2_ASSERT(source()); + source()->as().get(at, values, count); +} + +void DataFile::set(Offset at, Byte const *values, Size count) +{ + DENG2_ASSERT(source()); + source()->as().set(at, values, count); +} + +File *DataFile::Interpreter::interpretFile(File *sourceData) const +{ + // Naive check using the file extension. + static struct { String str; Format format; } formats[] = { + { ".pk3", Pk3 }, + { ".wad", Wad }, + { ".lmp", Lump }, + { ".ded", Ded }, + { ".deh", Dehacked } + }; + String const ext = sourceData->name().fileNameExtension(); + for(auto const &fmt : formats) + { + if(ext == fmt.str) + { + LOG_RES_VERBOSE("Interpreted ") << sourceData->description() + << " as " + << internal::formatDescriptions[fmt.format]; + + auto *data = new DataFile(fmt.format, sourceData->name()); + data->setSource(sourceData); + return data; + } + } + + // Was not interpreted. + return nullptr; +} diff --git a/doomsday/sdk/libcore/include/de/filesys/file.h b/doomsday/sdk/libcore/include/de/filesys/file.h index 62fd7b1323..de59d94809 100644 --- a/doomsday/sdk/libcore/include/de/filesys/file.h +++ b/doomsday/sdk/libcore/include/de/filesys/file.h @@ -64,7 +64,7 @@ class Feed; * * Subclasses have some special requirements for their destructors: * - deindex() must be called in all subclass destructors so that the instances indexed - * under the subclasses' type are removed from the file system's index also. + * under the subclasses' type are removed from the file system's index, too. * - The file must be automatically flushed before it gets destroyed (see flush()). * - The deletion audience must be notified and @c audienceForDeletion must be cleared * afterwards. diff --git a/doomsday/sdk/libcore/src/filesys/file.cpp b/doomsday/sdk/libcore/src/filesys/file.cpp index 1841cd94c4..d7fbb1b173 100644 --- a/doomsday/sdk/libcore/src/filesys/file.cpp +++ b/doomsday/sdk/libcore/src/filesys/file.cpp @@ -145,7 +145,7 @@ String File::description() const { if(parent()) { - desc += " [path \"" + path() + "\"]"; + desc += " (path \"" + path() + "\")"; } } @@ -161,7 +161,7 @@ String File::description() const { if(source() != this) { - desc += " (data sourced from " + source()->description() + ")"; + desc += "; data sourced from " + source()->description(); } }