- Removed the whole "fileResolver" class in favour of using the actual irrlicht file-handling functions

~ Added a small utils class to read full files to ram for the purpose of parsing json files
  Most of these files are really small, so there shouldn't really be any memory concerns
+ Added support for loading backgrounds directly from PKG files


Signed-off-by: Alexis Maiquez Murcia <almamu@almamu.com>
This commit is contained in:
Alexis Maiquez Murcia 2019-04-04 16:51:54 +02:00
parent e5affb470d
commit 9f9d44834b
21 changed files with 673 additions and 293 deletions

View File

@ -15,6 +15,6 @@ find_package(LZ4 REQUIRED)
include_directories(${X11_INCLUDE_DIR} ${IRRLICHT_INCLUDE_DIR} ${LZ4_INCLUDE_DIR} .)
add_executable(wallengine main.cpp wallpaperengine/shaders/compiler.h wallpaperengine/shaders/compiler.cpp wallpaperengine/project.cpp wallpaperengine/project.h wallpaperengine/scene.cpp wallpaperengine/scene.h wallpaperengine/object.cpp wallpaperengine/object.h wallpaperengine/camera.cpp wallpaperengine/camera.h wallpaperengine/core.cpp wallpaperengine/core.h wallpaperengine/image.cpp wallpaperengine/image.h wallpaperengine/object3d.cpp wallpaperengine/object3d.h wallpaperengine/effect.cpp wallpaperengine/effect.h wallpaperengine/fs/fileResolver.cpp wallpaperengine/fs/fileResolver.h wallpaperengine/irrlicht.cpp wallpaperengine/irrlicht.h wallpaperengine/config.cpp wallpaperengine/config.h wallpaperengine/video/renderer.cpp wallpaperengine/video/renderer.h wallpaperengine/video/node.cpp wallpaperengine/video/node.h wallpaperengine/video/material.cpp wallpaperengine/video/material.h wallpaperengine/texture.cpp wallpaperengine/texture.h wallpaperengine/irr/CImageLoaderTEX.h wallpaperengine/irr/CImageLoaderTEX.cpp)
add_executable(wallengine main.cpp wallpaperengine/shaders/compiler.h wallpaperengine/shaders/compiler.cpp wallpaperengine/project.cpp wallpaperengine/project.h wallpaperengine/scene.cpp wallpaperengine/scene.h wallpaperengine/object.cpp wallpaperengine/object.h wallpaperengine/camera.cpp wallpaperengine/camera.h wallpaperengine/core.cpp wallpaperengine/core.h wallpaperengine/image.cpp wallpaperengine/image.h wallpaperengine/object3d.cpp wallpaperengine/object3d.h wallpaperengine/effect.cpp wallpaperengine/effect.h wallpaperengine/fs/utils.cpp wallpaperengine/fs/utils.h wallpaperengine/irrlicht.cpp wallpaperengine/irrlicht.h wallpaperengine/config.cpp wallpaperengine/config.h wallpaperengine/video/renderer.cpp wallpaperengine/video/renderer.h wallpaperengine/video/node.cpp wallpaperengine/video/node.h wallpaperengine/video/material.cpp wallpaperengine/video/material.h wallpaperengine/texture.cpp wallpaperengine/texture.h wallpaperengine/irr/CImageLoaderTEX.h wallpaperengine/irr/CImageLoaderTEX.cpp wallpaperengine/irr/CPkgReader.h wallpaperengine/irr/CPkgReader.cpp wallpaperengine/irr/CFileList.h wallpaperengine/irr/CFileList.cpp)
target_link_libraries(wallengine ${X11_LIBRARIES} ${X11_Xxf86vm_LIB} ${OPENGL_LIBRARIES} ${GLUT_LIBRARIES} ${ZLIB_LIBRARIES} ${IRRLICHT_LIBRARY} ${LZ4_LIBRARY})

View File

@ -4,6 +4,7 @@
#include <wallpaperengine/config.h>
#include <wallpaperengine/video/renderer.h>
#include <wallpaperengine/video/material.h>
#include <wallpaperengine/irr/CPkgReader.h>
#include "wallpaperengine/shaders/compiler.h"
#include "wallpaperengine/project.h"
@ -97,8 +98,6 @@ void preconfigure_wallpaper_engine ()
wp::config::path::base = wp::irrlicht::device->getFileSystem ()->getAbsolutePath ("../");
wp::config::path::resources = wp::config::path::base + "/res";
wp::config::path::shaders = wp::config::path::resources + "/shaders";
wp::fs::resolver.changeWorkingDirectory (wp::config::path::base);
}
int main (int argc, char* argv[])
@ -123,14 +122,18 @@ int main (int argc, char* argv[])
// do_decompress ();
irr::io::path _wp_engine_folder = "/home/almamu/Development/tmp/nier__automata_-_become_as_gods_edition/";
irr::io::path _wp_project_file = _wp_engine_folder + "project.json";
// set our working directory
wp::fs::resolver.changeWorkingDirectory (_wp_engine_folder);
wp::irrlicht::device->getFileSystem ()->changeWorkingDirectoryTo (_wp_engine_folder);
// register custom loader
wp::irrlicht::driver->addExternalImageLoader (new irr::video::CImageLoaderTex ());
wp::irrlicht::device->getFileSystem ()->addArchiveLoader (new CArchiveLoaderPkg (wp::irrlicht::device->getFileSystem ()));
// wp::irrlicht::device->getFileSystem ()->addFileArchive ("./", true, false, irr::io::E_FILE_ARCHIVE_TYPE::EFAT_FOLDER);
// wp::irrlicht::device->getFileSystem ()->addFileArchive (_wp_engine_folder + "scene.pkg", true, false); // add the pkg file to the lookup list
wp::project* wp_project = new wp::project ();
wp::project* wp_project = new wp::project (_wp_project_file);
if (wp_project->getScene ()->isOrthogonal() == true)
{

View File

@ -1,4 +1,4 @@
#include <wallpaperengine/fs/fileResolver.h>
#include <wallpaperengine/fs/utils.h>
#include "effect.h"
namespace wp
@ -10,7 +10,7 @@ namespace wp
if (file != json_data.end () && (*file).is_string () == true)
{
this->m_file = wp::fs::resolver.resolve (*file);
this->m_file = ("effects/" + (*file).get <std::string> ()).c_str ();
}
}
};

View File

@ -1,136 +0,0 @@
#include <cstdint>
#include <sys/stat.h>
// filesystem includes
#include <wallpaperengine/fs/fileResolver.h>
// engine includes
#include <wallpaperengine/irrlicht.h>
namespace wp
{
namespace fs
{
fileResolver::fileResolver ()
{
this->m_environment.push_back (".");
}
fileResolver::fileResolver (std::vector<irr::io::path> environment)
{
this->m_environment.insert (this->m_environment.end (), environment.begin (), environment.end ());
}
void fileResolver::appendEnvironment (irr::io::path path)
{
this->m_environment.push_back (wp::irrlicht::device->getFileSystem ()->getAbsolutePath (path));
}
void fileResolver::removeEnvironment(irr::io::path path)
{
std::vector<irr::io::path>::const_iterator cur = this->m_environment.begin ();
std::vector<irr::io::path>::const_iterator end = this->m_environment.end ();
irr::io::path absolute = wp::irrlicht::device->getFileSystem ()->getAbsolutePath (path);
for (; cur != end; cur ++)
{
if (*cur == path)
{
this->m_environment.erase (cur);
return;
}
}
}
void fileResolver::prependEnvironment (irr::io::path path)
{
this->m_environment.insert (
this->m_environment.begin (),
wp::irrlicht::device->getFileSystem ()->getAbsolutePath (path)
);
}
void fileResolver::changeWorkingDirectory (irr::io::path newpath)
{
this->m_environment.erase (this->m_environment.begin ());
this->prependEnvironment (newpath);
}
irr::io::path fileResolver::getWorkingDirectory ()
{
return *this->m_environment.begin ();
}
fs::fileResolver fileResolver::clone ()
{
return fileResolver (this->m_environment);
}
irr::io::path fileResolver::resolve (irr::io::path name)
{
std::vector<irr::io::path>::const_iterator cur = this->m_environment.begin ();
std::vector<irr::io::path>::const_iterator end = this->m_environment.end ();
irr::io::path tmp = "";
// try to resolve the path
for (; cur != end; cur ++)
{
tmp = *cur;
tmp += "/";
tmp += name;
if (wp::irrlicht::device->getFileSystem ()->existFile (tmp) == true)
{
wp::irrlicht::device->getLogger ()->log ("Resolved file to", tmp.c_str ());
return tmp;
}
}
wp::irrlicht::device->getLogger ()->log ("Failed resolving file ", name.c_str (), irr::ELL_ERROR);
return "";
}
irr::io::path fileResolver::resolveOnWorkingDirectory (irr::io::path name)
{
irr::io::path file = *this->m_environment.begin () + "/" + name;
if (wp::irrlicht::device->getFileSystem ()->existFile (file) == true)
{
wp::irrlicht::device->getLogger ()->log ("Resolved file in working directory to", file.c_str ());
// perform stat over the file to check for directory
return file;
}
wp::irrlicht::device->getLogger ()->log ("Failed resolving file on working directory for ", name.c_str (), irr::ELL_ERROR);
return "";
}
irr::io::path fileResolver::resolve (json name)
{
std::string tmp = name;
return this->resolve (tmp.c_str ());
}
irr::io::path fileResolver::resolveOnWorkingDirectory (json name)
{
std::string tmp = name;
return this->resolveOnWorkingDirectory (tmp.c_str ());
}
irr::io::path fileResolver::resolve (const char* name)
{
return this->resolve (irr::io::path(name));
}
irr::io::path fileResolver::resolveOnWorkingDirectory (const char* name)
{
return this->resolveOnWorkingDirectory(irr::io::path (name));
}
fileResolver resolver;
}
}

View File

@ -1,104 +0,0 @@
/**
* @author Alexis Maiquez Murcia <almamu@almamu.com>
*/
#ifndef WALLENGINE_RESOLVER_H
#define WALLENGINE_RESOLVER_H
#include <string>
#include <vector>
#include <irrlicht/path.h>
#include <nlohmann/json.hpp>
namespace wp
{
using json = nlohmann::json;
namespace fs
{
/**
* Custom file resolver to limit our searches to specific folders
*/
class fileResolver
{
public:
/**
* Basic constructor, uses current path as base folder
*/
fileResolver ();
/**
* Creates a file resolver using a list as environment folders
*
* @param environment List of directories to use for finding files
*/
fileResolver (std::vector<irr::io::path> environment);
/**
* Adds a new folder to the environment list
*
* @param path
*/
void appendEnvironment (irr::io::path path);
/**
* Removes the given folder from the environment list
*
* @param path
*/
void removeEnvironment (irr::io::path path);
/**
* Updates the current working directory
*
* @param newpath
*/
void changeWorkingDirectory (irr::io::path newpath);
/**
* @return The current working directory
*/
irr::io::path getWorkingDirectory ();
/**
* @return A clone of this fileResolver
*/
fileResolver clone ();
/**
* Resolves the given filename or relative path
* on the current working directory or any of the registered
* environment folders
*
* @param name The filename/relative path to resolve
*
* @return The full path to the file
*/
irr::io::path resolve (irr::io::path name);
/**
* Resolves the given filename or relative path
* on the current working directory only
*
* @param name The filename/relative path to resolve
*
* @return The full path to the file
*/
irr::io::path resolveOnWorkingDirectory (irr::io::path name);
irr::io::path resolve (json name);
irr::io::path resolveOnWorkingDirectory (json name);
irr::io::path resolve (const char* name);
irr::io::path resolveOnWorkingDirectory (const char* name);
protected:
void prependEnvironment (irr::io::path path);
private:
/**
* List of environment paths in which the resolver will look for
* files in when trying to resolve them
*/
std::vector<irr::io::path> m_environment;
};
/**
* Static resolver used trough most of the application
*/
extern fileResolver resolver;
};
}
#endif //WALLENGINE_RESOLVER_H

View File

@ -0,0 +1,32 @@
#include <cstdint>
#include <sys/stat.h>
// filesystem includes
#include <wallpaperengine/fs/utils.h>
// engine includes
#include <wallpaperengine/irrlicht.h>
namespace wp
{
namespace fs
{
std::string utils::loadFullFile (irr::io::path file)
{
irr::io::IReadFile* reader = wp::irrlicht::device->getFileSystem ()->createAndOpenFile (file);
if (reader == NULL)
return "";
char* filedata = new char [reader->getSize () + 1];
memset (filedata, 0, reader->getSize () + 1);
reader->read (filedata, reader->getSize ());
std::string content = filedata;
delete [] filedata;
return content;
}
}
}

View File

@ -0,0 +1,36 @@
/**
* @author Alexis Maiquez Murcia <almamu@almamu.com>
*/
#ifndef WALLENGINE_RESOLVER_H
#define WALLENGINE_RESOLVER_H
#include <string>
#include <vector>
#include <irrlicht/path.h>
#include <nlohmann/json.hpp>
namespace wp
{
using json = nlohmann::json;
namespace fs
{
/**
* Custom file resolver to limit our searches to specific folders
*/
class utils
{
public:
/**
* Loads a full file into an std::string
*
* @param file
* @return
*/
static std::string loadFullFile (irr::io::path file);
};
};
}
#endif //WALLENGINE_RESOLVER_H

View File

@ -1,7 +1,7 @@
#include <irrlicht/irrlicht.h>
#include <fstream>
#include <wallpaperengine/fs/fileResolver.h>
#include <wallpaperengine/fs/utils.h>
#include <wallpaperengine/object3d.h>
#include <wallpaperengine/image.h>
@ -24,27 +24,18 @@ namespace wp
// basic texture, main thing to assign first
if (file_it != json_data.end () && (*file_it).is_string () == true)
{
this->m_file = wp::fs::resolver.resolve (*file_it);
this->m_file = (*file_it).get <std::string> ().c_str ();
this->m_content = wp::fs::utils::loadFullFile (this->m_file);
this->m_content = "";
std::ifstream _in (this->m_file.c_str ());
this->m_content.append (std::istreambuf_iterator<char> (_in), std::istreambuf_iterator<char> ());
json content = json::parse (this->m_content);
json::const_iterator it = content.find ("material");
if (it != content.end () && (*it).is_string () == true)
{
irr::io::path materialfile = wp::fs::resolver.resolveOnWorkingDirectory ((*it));
std::ifstream _in (materialfile.c_str ());
std::string texturejson_content = "";
texturejson_content.append (std::istreambuf_iterator<char> (_in), std::istreambuf_iterator<char> ());
irr::io::path materialfile = (*it).get <std::string> ().c_str ();
std::string texturejson_content = wp::fs::utils::loadFullFile (materialfile);
json materialcontent = json::parse (texturejson_content);
// change working directory for the resolver to the materials folder
this->m_resolver = wp::fs::resolver.clone ();
this->m_resolver.changeWorkingDirectory(this->m_resolver.resolveOnWorkingDirectory ("materials"));
// now try to read the texture if any
json::const_iterator it = materialcontent.find ("passes");
@ -64,13 +55,9 @@ namespace wp
for (; texturesCur != texturesEnd; texturesCur ++)
{
// TODO: SUPPORT PROPER WALLPAPERENGINE FORMATS
std::string name = (*texturesCur);
name += ".tex";
irr::io::path texturePath = this->m_resolver.resolveOnWorkingDirectory (name);
std::string basename = (*texturesCur);
irr::io::path texturepath = ("materials/" + (*texturesCur).get <std::string> () + ".tex").c_str ();
this->m_textures.push_back (new wp::texture (texturePath));
this->m_textures.push_back (new wp::texture (texturepath));
}
}
}

View File

@ -4,7 +4,7 @@
#include <nlohmann/json.hpp>
#include <irrlicht/irrlicht.h>
#include <wallpaperengine/fs/fileResolver.h>
#include <wallpaperengine/fs/utils.h>
#include <wallpaperengine/texture.h>
namespace wp
@ -26,7 +26,6 @@ namespace wp
irr::video::S3DVertex m_vertices [4];
irr::video::SMaterial m_material;
wp::fs::fileResolver m_resolver;
irr::core::vector3df m_origin;
irr::io::path m_file;
std::string m_content;

View File

@ -0,0 +1,157 @@
// Copyright (C) 2002-2012 Nikolaus Gebhardt
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in irrlicht.h
#include <irrlicht/irrlicht.h>
#include "CFileList.h"
namespace irr
{
namespace io
{
static const io::path emptyFileListEntry;
CFileList::CFileList(const io::path& path, bool ignoreCase, bool ignorePaths)
: IgnorePaths(ignorePaths), IgnoreCase(ignoreCase), Path(path)
{
Path.replace('\\', '/');
}
CFileList::~CFileList()
{
Files.clear();
}
u32 CFileList::getFileCount() const
{
return Files.size();
}
void CFileList::sort()
{
Files.sort();
}
const io::path& CFileList::getFileName(u32 index) const
{
if (index >= Files.size())
return emptyFileListEntry;
return Files[index].Name;
}
//! Gets the full name of a file in the list, path included, based on an index.
const io::path& CFileList::getFullFileName(u32 index) const
{
if (index >= Files.size())
return emptyFileListEntry;
return Files[index].FullName;
}
//! adds a file or folder
u32 CFileList::addItem(const io::path& fullPath, u32 offset, u32 size, bool isDirectory, u32 id)
{
SFileListEntry entry;
entry.ID = id ? id : Files.size();
entry.Offset = offset;
entry.Size = size;
entry.Name = fullPath;
entry.Name.replace('\\', '/');
entry.IsDirectory = isDirectory;
// remove trailing slash
if (entry.Name.lastChar() == '/')
{
entry.IsDirectory = true;
entry.Name[entry.Name.size()-1] = 0;
entry.Name.validate();
}
if (IgnoreCase)
entry.Name.make_lower();
entry.FullName = entry.Name;
core::deletePathFromFilename(entry.Name);
if (IgnorePaths)
entry.FullName = entry.Name;
//os::Printer::log(Path.c_str(), entry.FullName);
Files.push_back(entry);
return Files.size() - 1;
}
//! Returns the ID of a file in the file list, based on an index.
u32 CFileList::getID(u32 index) const
{
return index < Files.size() ? Files[index].ID : 0;
}
bool CFileList::isDirectory(u32 index) const
{
bool ret = false;
if (index < Files.size())
ret = Files[index].IsDirectory;
return ret;
}
//! Returns the size of a file
u32 CFileList::getFileSize(u32 index) const
{
return index < Files.size() ? Files[index].Size : 0;
}
//! Returns the size of a file
u32 CFileList::getFileOffset(u32 index) const
{
return index < Files.size() ? Files[index].Offset : 0;
}
//! Searches for a file or folder within the list, returns the index
s32 CFileList::findFile(const io::path& filename, bool isDirectory = false) const
{
SFileListEntry entry;
// we only need FullName to be set for the search
entry.FullName = filename;
entry.IsDirectory = isDirectory;
// exchange
entry.FullName.replace('\\', '/');
// remove trailing slash
if (entry.FullName.lastChar() == '/')
{
entry.IsDirectory = true;
entry.FullName[entry.FullName.size()-1] = 0;
entry.FullName.validate();
}
if (IgnoreCase)
entry.FullName.make_lower();
if (IgnorePaths)
core::deletePathFromFilename(entry.FullName);
return Files.binary_search(entry);
}
//! Returns the base path of the file list
const io::path& CFileList::getPath() const
{
return Path;
}
} // end namespace irr
} // end namespace io

View File

@ -0,0 +1,136 @@
// Copyright (C) 2002-2012 Nikolaus Gebhardt
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in irrlicht.h
#ifndef __C_FILE_LIST_H_INCLUDED__
#define __C_FILE_LIST_H_INCLUDED__
#include <irrlicht/irrlicht.h>
namespace irr
{
namespace io
{
//! An entry in a list of files, can be a folder or a file.
struct SFileListEntry
{
//! The name of the file
/** If this is a file or folder in the virtual filesystem and the archive
was created with the ignoreCase flag then the file name will be lower case. */
io::path Name;
//! The name of the file including the path
/** If this is a file or folder in the virtual filesystem and the archive was
created with the ignoreDirs flag then it will be the same as Name. */
io::path FullName;
//! The size of the file in bytes
u32 Size;
//! The ID of the file in an archive
/** This is used to link the FileList entry to extra info held about this
file in an archive, which can hold things like data offset and CRC. */
u32 ID;
//! FileOffset inside an archive
u32 Offset;
//! True if this is a folder, false if not.
bool IsDirectory;
//! The == operator is provided so that CFileList can slowly search the list!
bool operator ==(const struct SFileListEntry& other) const
{
if (IsDirectory != other.IsDirectory)
return false;
return FullName.equals_ignore_case(other.FullName);
}
//! The < operator is provided so that CFileList can sort and quickly search the list.
bool operator <(const struct SFileListEntry& other) const
{
if (IsDirectory != other.IsDirectory)
return IsDirectory;
return FullName.lower_ignore_case(other.FullName);
}
};
//! Implementation of a file list
class CFileList : public IFileList
{
public:
// CFileList methods
//! Constructor
/** \param path The path of this file archive */
CFileList(const io::path& path, bool ignoreCase, bool ignorePaths);
//! Destructor
virtual ~CFileList();
//! Add as a file or folder to the list
/** \param fullPath The file name including path, up to the root of the file list.
\param isDirectory True if this is a directory rather than a file.
\param offset The offset where the file is stored in an archive
\param size The size of the file in bytes.
\param id The ID of the file in the archive which owns it */
virtual u32 addItem(const io::path& fullPath, u32 offset, u32 size, bool isDirectory, u32 id=0);
//! Sorts the file list. You should call this after adding any items to the file list
virtual void sort();
//! Returns the amount of files in the filelist.
virtual u32 getFileCount() const;
//! Gets the name of a file in the list, based on an index.
virtual const io::path& getFileName(u32 index) const;
//! Gets the full name of a file in the list, path included, based on an index.
virtual const io::path& getFullFileName(u32 index) const;
//! Returns the ID of a file in the file list, based on an index.
virtual u32 getID(u32 index) const;
//! Returns true if the file is a directory
virtual bool isDirectory(u32 index) const;
//! Returns the size of a file
virtual u32 getFileSize(u32 index) const;
//! Returns the offest of a file
virtual u32 getFileOffset(u32 index) const;
//! Searches for a file or folder within the list, returns the index
virtual s32 findFile(const io::path& filename, bool isFolder) const;
//! Returns the base path of the file list
virtual const io::path& getPath() const;
protected:
//! Ignore paths when adding or searching for files
bool IgnorePaths;
//! Ignore case when adding or searching for files
bool IgnoreCase;
//! Path to the file list
io::path Path;
//! List of files
core::array<SFileListEntry> Files;
};
} // end namespace irr
} // end namespace io
#endif

View File

@ -0,0 +1,195 @@
//
// Created by almamu on 4/04/19.
//
#include <wallpaperengine/irrlicht.h>
#include "CPkgReader.h"
CArchiveLoaderPkg::CArchiveLoaderPkg(irr::io::IFileSystem* fs)
: FileSystem(fs)
{
#ifdef _DEBUG
setDebugName("CArchiveLoaderWAD");
#endif
}
//! returns true if the file maybe is able to be loaded by this class
bool CArchiveLoaderPkg::isALoadableFileFormat(const irr::io::path& filename) const
{
return irr::core::hasFileExtension (filename, "pkg");
}
//! Creates an archive from the filename
/** \param file File handle to check.
\return Pointer to newly created archive, or 0 upon error. */
irr::io::IFileArchive* CArchiveLoaderPkg::createArchive(const irr::io::path& filename, bool ignoreCase, bool ignorePaths) const
{
irr::io::IFileArchive *archive = nullptr;
irr::io::IReadFile* file = FileSystem->createAndOpenFile(filename);
if (file)
{
archive = createArchive (file, ignoreCase, ignorePaths);
file->drop ();
}
return archive;
}
//! creates/loads an archive from the file.
//! \return Pointer to the created archive. Returns 0 if loading failed.
irr::io::IFileArchive* CArchiveLoaderPkg::createArchive(irr::io::IReadFile* file, bool ignoreCase, bool ignorePaths) const
{
irr::io::IFileArchive *archive = nullptr;
if (file)
{
file->seek (0);
archive = new CPkgReader (file, ignoreCase, ignorePaths);
}
return archive;
}
//! Check if the file might be loaded by this class
/** Check might look into the file.
\param file File handle to check.
\return True if file seems to be loadable. */
bool CArchiveLoaderPkg::isALoadableFileFormat(irr::io::IReadFile* file) const
{
unsigned int size;
char* pointer;
file->read (&size, 4);
// the string doesnt include the null terminator
size ++;
pointer = new char [size];
memset (pointer, 0, size);
file->read (pointer, size - 1);
if (strcmp (pointer, "PKGV0002") != 0)
{
delete [] pointer;
return false;
}
delete [] pointer;
return true;
}
//! Check to see if the loader can create archives of this type.
bool CArchiveLoaderPkg::isALoadableFileFormat(irr::io::E_FILE_ARCHIVE_TYPE fileType) const
{
return false;
}
CPkgReader::CPkgReader (irr::io::IReadFile* file, bool ignoreCase, bool ignorePaths)
: CFileList((file ? file->getFileName() : irr::io::path("")), ignoreCase, ignorePaths), mFile(file)
{
if (this->mFile)
{
this->mFile->grab ();
this->scanPkgHeader ();
}
}
CPkgReader::~CPkgReader()
{
if (this->mFile)
this->mFile->drop();
}
//! get the archive type
irr::io::E_FILE_ARCHIVE_TYPE CPkgReader::getType() const
{
return irr::io::E_FILE_ARCHIVE_TYPE::EFAT_ZIP;
}
const irr::io::IFileList* CPkgReader::getFileList() const
{
return this;
}
void CPkgReader::scanPkgHeader ()
{
char* headerVersion = this->readSizedString ();
if (strcmp ("PKGV0002", headerVersion) != 0)
{
wp::irrlicht::device->getLogger ()->log ("Unexpected package header... Aborting load", this->mFile->getFileName ().c_str (), irr::ELL_ERROR);
delete [] headerVersion;
return;
}
delete [] headerVersion;
unsigned int entriesCount;
this->mFile->read (&entriesCount, 4);
for (int i = 0; i < entriesCount; i ++)
{
char* filename = this->readSizedString ();
unsigned int offset, length;
this->mFile->read (&offset, 4);
this->mFile->read (&length, 4);
this->addItem (filename, offset, length, false);
delete [] filename;
}
// after the header is read we have to update the actual offsets
for (int i = 0; i < this->Files.size (); i ++)
{
this->Files [i].Offset += this->mFile->getPos ();
}
}
char* CPkgReader::readSizedString ()
{
unsigned int size;
char* pointer;
this->mFile->read (&size, 4);
// the string doesnt include the null terminator
size ++;
pointer = new char [size];
memset (pointer, 0, size);
this->mFile->read (pointer, size - 1);
return pointer;
}
irr::io::IReadFile* CPkgReader::createAndOpenFile (const irr::io::path& filename)
{
irr::s32 index = this->findFile (filename, false);
if (index != -1)
return createAndOpenFile (index);
return nullptr;
}
irr::io::IReadFile* CPkgReader::createAndOpenFile (irr::u32 index)
{
if (index > this->Files.size ())
return nullptr;
const irr::io::SFileListEntry entry = Files [index];
return irr::io::createLimitReadFile (entry.FullName, mFile, entry.Offset, entry.Size);
}

View File

@ -0,0 +1,82 @@
//
// Created by almamu on 4/04/19.
//
#ifndef WALLENGINE_CPKGREADER_H
#define WALLENGINE_CPKGREADER_H
#include <irrlicht/irrlicht.h>
#include <string>
#include "CFileList.h"
//! Archiveloader capable of loading WAD Archives
class CArchiveLoaderPkg : public irr::io::IArchiveLoader
{
public:
//! Constructor
CArchiveLoaderPkg(irr::io::IFileSystem* fs);
//! returns true if the file maybe is able to be loaded by this class
//! based on the file extension (e.g. ".zip")
virtual bool isALoadableFileFormat(const irr::io::path& filename) const;
//! Check if the file might be loaded by this class
/** Check might look into the file.
\param file File handle to check.
\return True if file seems to be loadable. */
virtual bool isALoadableFileFormat(irr::io::IReadFile* file) const;
//! Check to see if the loader can create archives of this type.
/** Check based on the archive type.
\param fileType The archive type to check.
\return True if the archile loader supports this type, false if not */
virtual bool isALoadableFileFormat(irr::io::E_FILE_ARCHIVE_TYPE fileType) const;
//! Creates an archive from the filename
/** \param file File handle to check.
\return Pointer to newly created archive, or 0 upon error. */
virtual irr::io::IFileArchive* createArchive(const irr::io::path& filename, bool ignoreCase, bool ignorePaths) const;
//! creates/loads an archive from the file.
//! \return Pointer to the created archive. Returns 0 if loading failed.
virtual irr::io::IFileArchive* createArchive(irr::io::IReadFile* file, bool ignoreCase, bool ignorePaths) const;
private:
irr::io::IFileSystem* FileSystem;
};
class CPkgReader : public virtual irr::io::IFileArchive, virtual irr::io::CFileList
{
public:
//! constructor
CPkgReader (irr::io::IReadFile* file, bool ignoreCase, bool ignorePaths);
//! destructor
virtual ~CPkgReader ();
//! opens a file by file name
virtual irr::io::IReadFile* createAndOpenFile (const irr::io::path& filename);
//! opens a file by index
virtual irr::io::IReadFile* createAndOpenFile (unsigned int index);
//! returns the list of files
virtual const IFileList* getFileList () const;
//! get the archive type
virtual irr::io::E_FILE_ARCHIVE_TYPE getType () const;
protected:
void scanPkgHeader ();
char* readSizedString ();
irr::io::IFileSystem* mFileSystem;
irr::io::IReadFile* mFile;
};
#endif //WALLENGINE_CPKGREADER_H

View File

@ -3,20 +3,16 @@
#include <fstream>
#include <stdexcept>
#include "fs/fileResolver.h"
#include "wallpaperengine/fs/utils.h"
#include "project.h"
#include "irrlicht.h"
namespace wp
{
project::project ()
project::project (irr::io::path& jsonfile_path)
{
irr::io::path projectFile = wp::fs::resolver.resolveOnWorkingDirectory ("project.json");
std::ifstream _in (projectFile.c_str ());
this->m_content = "";
this->m_content.append (std::istreambuf_iterator<char> (_in), std::istreambuf_iterator<char> ());
this->m_content = wp::fs::utils::loadFullFile (jsonfile_path);
this->m_projectFile = json::parse (this->m_content);
json::const_iterator file_it = this->m_projectFile.find ("file");
@ -26,8 +22,8 @@ namespace wp
if (file_it != this->m_projectFile.end ())
{
// load scene file
this->m_file = wp::fs::resolver.resolveOnWorkingDirectory (*file_it);
this->m_scene = new scene (this->m_file.c_str ());
this->m_file = (*file_it).get <std::string> ().c_str ();
this->m_scene = new scene (this->m_file);
}
if (type_it != this->m_projectFile.end ())

View File

@ -12,7 +12,7 @@ namespace wp
class project
{
public:
project ();
project (irr::io::path& jsonfile_path);
scene* getScene ();

View File

@ -6,15 +6,15 @@
#include <wallpaperengine/scene.h>
#include <wallpaperengine/camera.h>
#include "wallpaperengine/fs/utils.h"
namespace wp
{
using json = nlohmann::json;
scene::scene (irr::io::path file)
scene::scene (irr::io::path& file)
{
std::ifstream _in (file.c_str ());
this->m_content = "";
this->m_content.append (std::istreambuf_iterator<char> (_in), std::istreambuf_iterator<char> ());
this->m_content = wp::fs::utils::loadFullFile (file);
this->m_json = json::parse (this->m_content);
// check basic elements

View File

@ -16,7 +16,7 @@ namespace wp
class scene : public wp::video::node
{
public:
scene (irr::io::path file);
scene (irr::io::path& file);
~scene ();
camera* getCamera ();

View File

@ -7,7 +7,7 @@
#include <wallpaperengine/config.h>
// filesystem
#include <wallpaperengine/fs/fileResolver.h>
#include <wallpaperengine/fs/utils.h>
// video engine
#include <wallpaperengine/irrlicht.h>
@ -54,9 +54,6 @@ namespace wp
// append file content
this->m_type = type;
this->m_resolver = wp::fs::resolver.clone ();
this->m_resolver.appendEnvironment (wp::config::path::shaders);
this->m_file = file;
}
@ -201,7 +198,7 @@ namespace wp
std::string compiler::lookupShaderFile (std::string filename)
{
// get file information
irr::io::path shader = this->m_resolver.resolve (filename.c_str ());
irr::io::path shader = ("shaders/" + filename).c_str ();
if (shader == "")
{

View File

@ -6,7 +6,7 @@
#include <vector>
#include <map>
#include <wallpaperengine/fs/fileResolver.h>
#include <wallpaperengine/fs/utils.h>
namespace wp
{
@ -193,7 +193,7 @@ namespace wp
/**
* The file resolver to be used by the compiler to load the files
*/
wp::fs::fileResolver m_resolver;
wp::fs::utils m_resolver;
};
}
}

View File

@ -6,7 +6,7 @@
namespace wp
{
texture::texture (irr::io::path file)
texture::texture (irr::io::path& file)
{
this->m_texture = wp::irrlicht::driver->getTexture (file);
}

View File

@ -8,7 +8,7 @@ namespace wp
class texture
{
public:
texture (irr::io::path file);
texture (irr::io::path& file);
irr::video::ITexture* getIrrTexture ();