~ More class name changes and namespace modifictions (fs and irr)

Signed-off-by: Alexis Maiquez <almamu@almamu.com>
This commit is contained in:
Alexis Maiquez 2019-08-16 14:56:16 +02:00
parent 654918904a
commit 69724adfdc
37 changed files with 1146 additions and 1208 deletions

View File

@ -38,10 +38,8 @@ add_executable(
WallpaperEngine/object3d.h
WallpaperEngine/effect.cpp
WallpaperEngine/effect.h
WallpaperEngine/fs/utils.cpp
WallpaperEngine/fs/utils.h
WallpaperEngine/irrlicht.cpp
WallpaperEngine/irrlicht.h
WallpaperEngine/FileSystem/utils.cpp
WallpaperEngine/FileSystem/utils.h
WallpaperEngine/video/renderer.cpp
WallpaperEngine/video/renderer.h
WallpaperEngine/video/node.cpp
@ -50,12 +48,14 @@ add_executable(
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
WallpaperEngine/Irrlicht/CImageLoaderTEX.h
WallpaperEngine/Irrlicht/CImageLoaderTEX.cpp
WallpaperEngine/Irrlicht/CPkgReader.h
WallpaperEngine/Irrlicht/CPkgReader.cpp
WallpaperEngine/Irrlicht/CFileList.h
WallpaperEngine/Irrlicht/CFileList.cpp
WallpaperEngine/Irrlicht/Irrlicht.cpp
WallpaperEngine/Irrlicht/Irrlicht.h
WallpaperEngine/sound.cpp
WallpaperEngine/sound.h

View File

@ -16,7 +16,7 @@ CProject::CProject (std::string title, std::string type, CScene *scene) :
CProject* CProject::fromFile (const irr::io::path& filename)
{
json content = json::parse (WallpaperEngine::fs::utils::loadFullFile (filename));
json content = json::parse (WallpaperEngine::FileSystem::loadFullFile (filename));
json::const_iterator title = content.find ("title");
json::const_iterator type = content.find ("type");

View File

@ -48,7 +48,7 @@ CScene::CScene (
CScene* CScene::fromFile (const irr::io::path& filename)
{
json content = json::parse (WallpaperEngine::fs::utils::loadFullFile (filename));
json content = json::parse (WallpaperEngine::FileSystem::loadFullFile (filename));
json::const_iterator camera_it = content.find ("camera");
json::const_iterator general_it = content.find ("general");

View File

@ -27,7 +27,7 @@ CEffect* CEffect::fromJSON (json data)
throw std::runtime_error ("Object effect must have a file");
}
json content = json::parse (WallpaperEngine::fs::utils::loadFullFile ((*file_it).get <std::string> ().c_str ()));
json content = json::parse (WallpaperEngine::FileSystem::loadFullFile ((*file_it).get <std::string> ().c_str ()));
json::const_iterator name_it = content.find ("name");
json::const_iterator description_it = content.find ("description");

View File

@ -38,7 +38,7 @@ WallpaperEngine::Core::CObject* CImage::fromJSON (
throw std::runtime_error ("Images must have size");
}
json content = json::parse (WallpaperEngine::fs::utils::loadFullFile ((*image_it).get <std::string> ().c_str ()));
json content = json::parse (WallpaperEngine::FileSystem::loadFullFile ((*image_it).get <std::string> ().c_str ()));
json::const_iterator material_it = content.find ("material");

View File

@ -14,7 +14,7 @@ CMaterial::CMaterial ()
CMaterial* CMaterial::fromFile (irr::io::path filename)
{
return fromJSON (
json::parse (WallpaperEngine::fs::utils::loadFullFile (filename))
json::parse (WallpaperEngine::FileSystem::loadFullFile (filename))
);
}

View File

@ -12,7 +12,7 @@ CParticle* CParticle::fromFile (
const irr::core::vector3df& origin,
const irr::core::vector3df& scale)
{
json data = json::parse (WallpaperEngine::fs::utils::loadFullFile (filename));
json data = json::parse (WallpaperEngine::FileSystem::loadFullFile (filename));
json::const_iterator controlpoint_it = data.find ("controlpoint");
json::const_iterator starttime_it = data.find ("starttime");
json::const_iterator maxcount_it = data.find ("maxcount");

View File

@ -0,0 +1,27 @@
// filesystem includes
#include "utils.h"
// engine includes
#include "../Irrlicht/Irrlicht.h"
namespace WallpaperEngine::FileSystem
{
std::string loadFullFile (irr::io::path file)
{
irr::io::IReadFile* reader = WallpaperEngine::Irrlicht::device->getFileSystem ()->createAndOpenFile (file);
if (reader == NULL)
throw std::runtime_error ("Cannot open file " + std::string (file.c_str ()) + " for reading");
char* filedata = new char [reader->getSize () + 1];
memset (filedata, 0, reader->getSize () + 1);
reader->read (filedata, reader->getSize ());
reader->drop ();
std::string content = filedata;
delete [] filedata;
return content;
}
};

View File

@ -0,0 +1,24 @@
/**
* @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 WallpaperEngine::FileSystem
{
/**
* Loads a full file into an std::string
*
* @param file
* @return
*/
std::string loadFullFile (irr::io::path file);
}
#endif //WALLENGINE_RESOLVER_H

View File

@ -0,0 +1,146 @@
#include <irrlicht/irrlicht.h>
#include "CFileList.h"
using namespace WallpaperEngine::Irrlicht;
using namespace irr;
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;
}

View File

@ -0,0 +1,123 @@
#pragma once
#include <irrlicht/irrlicht.h>
using namespace irr;
namespace WallpaperEngine::Irrlicht
{
//! 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 io::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;
};
}

View File

@ -0,0 +1,549 @@
#include "CImageLoaderTEX.h"
#include <irrlicht/irrlicht.h>
#include <lz4.h>
#include <WallpaperEngine/Irrlicht/Irrlicht.h>
#include <string>
using namespace irr::video;
using namespace WallpaperEngine::Irrlicht;
//! returns true if the file maybe is able to be loaded by this class
//! based on the file extension (e.g. ".tga")
bool CImageLoaderTex::isALoadableFileExtension (const io::path &filename) const
{
return core::hasFileExtension (filename, "tex");
}
//! returns true if the file maybe is able to be loaded by this class
bool CImageLoaderTex::isALoadableFileFormat (io::IReadFile *file) const
{
return false;
}
// load in the image data
IImage *CImageLoaderTex::loadImage (io::IReadFile *input) const
{
if (!input)
return nullptr;
video::IImage *image = nullptr;
char buffer [1024];
if (input->read (buffer, 9) != 9)
{
WallpaperEngine::Irrlicht::device->getLogger ()->log ("LOAD TEX: cannot read header\n", input->getFileName ().c_str (), irr::ELL_ERROR);
return nullptr;
}
if (memcmp (buffer, "TEXV0005", 9) != 0)
{
WallpaperEngine::Irrlicht::device->getLogger ()->log ("LOAD TEX: not really a tex\n", input->getFileName ().c_str (), irr::ELL_ERROR);
return nullptr;
}
if (input->read (buffer, 9) != 9)
{
WallpaperEngine::Irrlicht::device->getLogger ()->log ("LOAD TEX: cannot read second header\n", input->getFileName ().c_str (), irr::ELL_ERROR);
return nullptr;
}
if (memcmp (buffer, "TEXI0001", 9) != 0)
{
WallpaperEngine::Irrlicht::device->getLogger ()->log ("LOAD TEX: not really a tex\n", input->getFileName ().c_str (), irr::ELL_ERROR);
return nullptr;
}
u32 width;
u32 height;
u32 texture_width;
u32 texture_height;
u32 format;
u32 imageFormat = FREE_IMAGE_FORMAT::FIF_UNKNOWN;
u8 containerVersion = 0;
input->read (&format, 4);
input->seek (4, true); // ignore bytes
input->read (&texture_width, 4);
input->read (&texture_height, 4);
input->read (&width, 4);
input->read (&height, 4);
input->seek (4, true); // ignore bytes
input->read (buffer, 9);
if (memcmp (buffer, "TEXB0003", 9) == 0)
{
containerVersion = 3;
input->seek (4, true);
input->read (&imageFormat, 4);
}
else if (memcmp (buffer, "TEXB0002", 9) == 0)
{
containerVersion = 2;
input->seek (4, true);
}
else if (memcmp (buffer, "TEXB0001", 9) == 0)
{
containerVersion = 1;
input->seek (4, true);
}
else
{
WallpaperEngine::Irrlicht::device->getLogger ()->log ("LOAD TEX: Unknown container type\n", input->getFileName ().c_str (), irr::ELL_ERROR);
return nullptr;
}
if (format == TextureFormat::A8)
{
WallpaperEngine::Irrlicht::device->getLogger ()-> log ("LOAD TEX: A8 not supported\n", input->getFileName ().c_str (), irr::ELL_ERROR);
return nullptr;
}
if (format == TextureFormat::RA88)
{
WallpaperEngine::Irrlicht::device->getLogger ()->log ("LOAD TEX: RA88 not supported\n", input->getFileName ().c_str (), irr::ELL_ERROR);
return nullptr;
}
u32 mipmap_count = 0;
input->read (&mipmap_count, 4);
u32 mipmap_width = 0;
u32 mipmap_height = 0;
u32 mipmap_compression = 0;
u32 mipmap_uncompressed_size = 0;
u32 mipmap_compressed_size = 0;
input->read (&mipmap_width, 4);
input->read (&mipmap_height, 4);
if (containerVersion > 1)
{
input->read (&mipmap_compression, 4);
input->read (&mipmap_uncompressed_size, 4);
}
input->read (&mipmap_compressed_size, 4);
// TODO: BETTER POSITION FOR THIS
if (mipmap_compression == 0)
{
// this might be better named as mipmap_bytes_size instead of compressed_size
// as in uncompressed files this variable actually holds the file length
mipmap_uncompressed_size = mipmap_compressed_size;
}
char *decompressedBuffer = new char [mipmap_uncompressed_size];
if (mipmap_compression == 1)
{
char *compressedBuffer = new char [mipmap_compressed_size];
input->read (compressedBuffer, mipmap_compressed_size);
int result = LZ4_decompress_safe (compressedBuffer, decompressedBuffer, mipmap_compressed_size, mipmap_uncompressed_size);
if (!result)
{
delete [] decompressedBuffer;
delete [] compressedBuffer;
WallpaperEngine::Irrlicht::device->getLogger ()->log ("LOAD TEX: cannot decompress texture data\n", input->getFileName ().c_str (), irr::ELL_ERROR);
return nullptr;
}
delete [] compressedBuffer;
}
else
{
input->read (decompressedBuffer, mipmap_uncompressed_size);
}
if (imageFormat == FREE_IMAGE_FORMAT::FIF_UNKNOWN)
{
image = WallpaperEngine::Irrlicht::driver->createImage (ECF_A8R8G8B8, irr::core::dimension2d<u32> (width, height));
if (!image)
{
delete [] decompressedBuffer;
delete image;
WallpaperEngine::Irrlicht::device->getLogger ()->log ("LOAD TEX: cannot create destination image\n", input->getFileName ().c_str (), irr::ELL_ERROR);
return nullptr;
}
switch (format)
{
case TextureFormat::ARGB8888:
this->loadImageFromARGB8Data (image, decompressedBuffer, width, height, mipmap_width);
break;
case TextureFormat::DXT5:
this->loadImageFromDXT5 (image, decompressedBuffer, width, height, mipmap_width, mipmap_height);
break;
case TextureFormat::DXT1:
this->loadImageFromDXT1 (image, decompressedBuffer, width, height, mipmap_width, mipmap_height);
break;
case TextureFormat::DXT3:
WallpaperEngine::Irrlicht::device->getLogger ()->log ("LOAD TEX: DXT3 textures not supported yet\n", input->getFileName ().c_str (), irr::ELL_ERROR);
delete [] decompressedBuffer;
delete image;
return nullptr;
}
}
else
{
// copy the buffer to a new address
char* filebuffer = new char [mipmap_uncompressed_size];
char tmpname [TMP_MAX];
// copy file data to the final file buffer to be used
memcpy (filebuffer, decompressedBuffer, mipmap_uncompressed_size);
// generate temporal name
std::tmpnam (tmpname);
// store it in a std::string
std::string filename = tmpname;
irr::io::IReadFile* file;
// free image format
switch (imageFormat)
{
case FREE_IMAGE_FORMAT::FIF_BMP:
// add extension to the file
filename += ".bmp";
file = WallpaperEngine::Irrlicht::device->getFileSystem ()->createMemoryReadFile (filebuffer, mipmap_uncompressed_size, filename.c_str (), true);
break;
case FREE_IMAGE_FORMAT::FIF_PNG:
// add extension to the file
filename += ".png";
file = WallpaperEngine::Irrlicht::device->getFileSystem ()->createMemoryReadFile (filebuffer, mipmap_uncompressed_size, filename.c_str (), true);
break;
case FREE_IMAGE_FORMAT::FIF_JPEG:
// add extension to the file
filename += ".jpg";
WallpaperEngine::Irrlicht::device->getFileSystem ()->createAndWriteFile ("/tmp/test.jpg", false)->write (filebuffer, mipmap_uncompressed_size);
file = WallpaperEngine::Irrlicht::device->getFileSystem ()->createMemoryReadFile (filebuffer, mipmap_uncompressed_size, filename.c_str (), true);
break;
case FREE_IMAGE_FORMAT::FIF_GIF:
filename += ".gif";
file = WallpaperEngine::Irrlicht::device->getFileSystem ()->createMemoryReadFile (filebuffer, mipmap_uncompressed_size, filename.c_str (), true);
break;
default:
WallpaperEngine::Irrlicht::device->getLogger ()->log ("LOAD TEX: detected unsupported free-image format\n", input->getFileName ().c_str (), irr::ELL_ERROR);
delete [] decompressedBuffer;
delete [] filebuffer;
return nullptr;
}
image = WallpaperEngine::Irrlicht::driver->createImageFromFile (file);
if (!image)
{
file->drop ();
delete [] decompressedBuffer;
delete image;
WallpaperEngine::Irrlicht::device->getLogger ()->log ("LOAD TEX: cannot create destination image\n", input->getFileName ().c_str (), irr::ELL_ERROR);
return nullptr;
}
}
delete [] decompressedBuffer;
return image;
}
void CImageLoaderTex::loadImageFromARGB8Data (IImage* output, const char* input, u32 width, u32 height, u32 mipmap_width) const
{
u32 bytesPerPixel = output->getBytesPerPixel ();
char *imagedata = (char *) output->lock ();
for (u32 y = 0; y < height; y ++)
{
u32 baseDestination = y * output->getPitch ();
u32 baseOrigin = y * (mipmap_width * 4);
for (u32 x = 0; x < width; x ++)
{
imagedata [baseDestination + (x * bytesPerPixel) + 2] = input [baseOrigin + ((width - x) * 4) + 0]; // r
imagedata [baseDestination + (x * bytesPerPixel) + 1] = input [baseOrigin + ((width - x) * 4) + 1]; // g
imagedata [baseDestination + (x * bytesPerPixel) + 0] = input [baseOrigin + ((width - x) * 4) + 2]; // b
imagedata [baseDestination + (x * bytesPerPixel) + 3] = input [baseOrigin + ((width - x) * 4) + 3]; // alpha
}
}
output->unlock ();
}
void CImageLoaderTex::loadImageFromDXT1 (IImage* output, const char* input, u32 destination_width, u32 destination_height, u32 origin_width, u32 origin_height) const
{
char* decompressedBuffer = new char [origin_width * origin_height * 4];
this->BlockDecompressImageDXT1 (origin_width, origin_height, (const unsigned char*) input, (unsigned long*) decompressedBuffer);
this->loadImageFromARGB8Data (output, decompressedBuffer, destination_width, destination_height, origin_width);
delete [] decompressedBuffer;
}
void CImageLoaderTex::loadImageFromDXT5 (IImage* output, const char* input, u32 destination_width, u32 destination_height, u32 origin_width, u32 origin_height) const
{
char* decompressedBuffer = new char [origin_width * origin_height * 4];
this->BlockDecompressImageDXT5 (origin_width, origin_height, (const unsigned char*) input, (unsigned long*) decompressedBuffer);
this->loadImageFromARGB8Data (output, decompressedBuffer, destination_width, destination_height, origin_width);
delete [] decompressedBuffer;
}
// ------------------------------------------------------------------------------------
// The following code is a slightly modified version of this repository
// https://github.com/Benjamin-Dobell/s3tc-dxt-decompression
// ------------------------------------------------------------------------------------
// unsigned long PackRGBA(): Helper method that packs RGBA channels into a single 4 byte pixel.
//
// unsigned char r: red channel.
// unsigned char g: green channel.
// unsigned char b: blue channel.
// unsigned char a: alpha channel.
unsigned long CImageLoaderTex::PackRGBA(unsigned char r, unsigned char g, unsigned char b, unsigned char a) const
{
return ((r << 24) | (g << 16) | (b << 8) | a);
}
// void DecompressBlockDXT1(): Decompresses one block of a DXT1 texture and stores the resulting pixels at the appropriate offset in 'image'.
//
// unsigned long x: x-coordinate of the first pixel in the block.
// unsigned long y: y-coordinate of the first pixel in the block.
// unsigned long width: width of the texture being decompressed.
// unsigned long height: height of the texture being decompressed.
// const unsigned char *blockStorage: pointer to the block to decompress.
// unsigned long *image: pointer to image where the decompressed pixel data should be stored.
void CImageLoaderTex::DecompressBlockDXT1(unsigned long x, unsigned long y, unsigned long width, const unsigned char *blockStorage, unsigned long *image) const
{
unsigned short color0 = *reinterpret_cast<const unsigned short *>(blockStorage);
unsigned short color1 = *reinterpret_cast<const unsigned short *>(blockStorage + 2);
unsigned long temp;
temp = (color0 >> 11) * 255 + 16;
unsigned char r0 = (unsigned char)((temp/32 + temp)/32);
temp = ((color0 & 0x07E0) >> 5) * 255 + 32;
unsigned char g0 = (unsigned char)((temp/64 + temp)/64);
temp = (color0 & 0x001F) * 255 + 16;
unsigned char b0 = (unsigned char)((temp/32 + temp)/32);
temp = (color1 >> 11) * 255 + 16;
unsigned char r1 = (unsigned char)((temp/32 + temp)/32);
temp = ((color1 & 0x07E0) >> 5) * 255 + 32;
unsigned char g1 = (unsigned char)((temp/64 + temp)/64);
temp = (color1 & 0x001F) * 255 + 16;
unsigned char b1 = (unsigned char)((temp/32 + temp)/32);
unsigned long code = *reinterpret_cast<const unsigned long *>(blockStorage + 4);
for (int j=0; j < 4; j++)
{
for (int i=0; i < 4; i++)
{
unsigned long finalColor = 0;
unsigned char positionCode = (code >> 2*(4*j+i)) & 0x03;
if (color0 > color1)
{
switch (positionCode)
{
case 0:
finalColor = PackRGBA(r0, g0, b0, 255);
break;
case 1:
finalColor = PackRGBA(r1, g1, b1, 255);
break;
case 2:
finalColor = PackRGBA((2*r0+r1)/3, (2*g0+g1)/3, (2*b0+b1)/3, 255);
break;
case 3:
finalColor = PackRGBA((r0+2*r1)/3, (g0+2*g1)/3, (b0+2*b1)/3, 255);
break;
}
}
else
{
switch (positionCode)
{
case 0:
finalColor = PackRGBA(r0, g0, b0, 255);
break;
case 1:
finalColor = PackRGBA(r1, g1, b1, 255);
break;
case 2:
finalColor = PackRGBA((r0+r1)/2, (g0+g1)/2, (b0+b1)/2, 255);
break;
case 3:
finalColor = PackRGBA(0, 0, 0, 255);
break;
}
}
if (x + i < width)
image[(y + j)*width + (x + i)] = finalColor;
}
}
}
// void BlockDecompressImageDXT1(): Decompresses all the blocks of a DXT1 compressed texture and stores the resulting pixels in 'image'.
//
// unsigned long width: Texture width.
// unsigned long height: Texture height.
// const unsigned char *blockStorage: pointer to compressed DXT1 blocks.
// unsigned long *image: pointer to the image where the decompressed pixels will be stored.
void CImageLoaderTex::BlockDecompressImageDXT1(unsigned long width, unsigned long height, const unsigned char *blockStorage, unsigned long *image) const
{
unsigned long blockCountX = (width + 3) / 4;
unsigned long blockCountY = (height + 3) / 4;
unsigned long blockWidth = (width < 4) ? width : 4;
unsigned long blockHeight = (height < 4) ? height : 4;
for (unsigned long j = 0; j < blockCountY; j++)
{
for (unsigned long i = 0; i < blockCountX; i++) DecompressBlockDXT1(i*4, j*4, width, blockStorage + i * 8, image);
blockStorage += blockCountX * 8;
}
}
// void DecompressBlockDXT5(): Decompresses one block of a DXT5 texture and stores the resulting pixels at the appropriate offset in 'image'.
//
// unsigned long x: x-coordinate of the first pixel in the block.
// unsigned long y: y-coordinate of the first pixel in the block.
// unsigned long width: width of the texture being decompressed.
// unsigned long height: height of the texture being decompressed.
// const unsigned char *blockStorage: pointer to the block to decompress.
// unsigned long *image: pointer to image where the decompressed pixel data should be stored.
void CImageLoaderTex::DecompressBlockDXT5(unsigned long x, unsigned long y, unsigned long width, const unsigned char *blockStorage, unsigned long *image) const
{
unsigned char alpha0 = *reinterpret_cast<const unsigned char *>(blockStorage);
unsigned char alpha1 = *reinterpret_cast<const unsigned char *>(blockStorage + 1);
const unsigned char *bits = blockStorage + 2;
unsigned long alphaCode1 = bits[2] | (bits[3] << 8) | (bits[4] << 16) | (bits[5] << 24);
unsigned short alphaCode2 = bits[0] | (bits[1] << 8);
unsigned short color0 = *reinterpret_cast<const unsigned short *>(blockStorage + 8);
unsigned short color1 = *reinterpret_cast<const unsigned short *>(blockStorage + 10);
unsigned long temp;
temp = (color0 >> 11) * 255 + 16;
unsigned char r0 = (unsigned char)((temp/32 + temp)/32);
temp = ((color0 & 0x07E0) >> 5) * 255 + 32;
unsigned char g0 = (unsigned char)((temp/64 + temp)/64);
temp = (color0 & 0x001F) * 255 + 16;
unsigned char b0 = (unsigned char)((temp/32 + temp)/32);
temp = (color1 >> 11) * 255 + 16;
unsigned char r1 = (unsigned char)((temp/32 + temp)/32);
temp = ((color1 & 0x07E0) >> 5) * 255 + 32;
unsigned char g1 = (unsigned char)((temp/64 + temp)/64);
temp = (color1 & 0x001F) * 255 + 16;
unsigned char b1 = (unsigned char)((temp/32 + temp)/32);
unsigned long code = *reinterpret_cast<const unsigned long *>(blockStorage + 12);
for (int j=0; j < 4; j++)
{
for (int i=0; i < 4; i++)
{
int alphaCodeIndex = 3*(4*j+i);
int alphaCode;
if (alphaCodeIndex <= 12)
{
alphaCode = (alphaCode2 >> alphaCodeIndex) & 0x07;
}
else if (alphaCodeIndex == 15)
{
alphaCode = (alphaCode2 >> 15) | ((alphaCode1 << 1) & 0x06);
}
else // alphaCodeIndex >= 18 && alphaCodeIndex <= 45
{
alphaCode = (alphaCode1 >> (alphaCodeIndex - 16)) & 0x07;
}
unsigned char finalAlpha;
if (alphaCode == 0)
{
finalAlpha = alpha0;
}
else if (alphaCode == 1)
{
finalAlpha = alpha1;
}
else
{
if (alpha0 > alpha1)
{
finalAlpha = ((8-alphaCode)*alpha0 + (alphaCode-1)*alpha1)/7;
}
else
{
if (alphaCode == 6)
finalAlpha = 0;
else if (alphaCode == 7)
finalAlpha = 255;
else
finalAlpha = ((6-alphaCode)*alpha0 + (alphaCode-1)*alpha1)/5;
}
}
unsigned char colorCode = (code >> 2*(4*j+i)) & 0x03;
unsigned long finalColor;
switch (colorCode)
{
case 0:
finalColor = PackRGBA(r0, g0, b0, finalAlpha);
break;
case 1:
finalColor = PackRGBA(r1, g1, b1, finalAlpha);
break;
case 2:
finalColor = PackRGBA((2*r0+r1)/3, (2*g0+g1)/3, (2*b0+b1)/3, finalAlpha);
break;
case 3:
finalColor = PackRGBA((r0+2*r1)/3, (g0+2*g1)/3, (b0+2*b1)/3, finalAlpha);
break;
}
if (x + i < width)
image[(y + j)*width + (x + i)] = finalColor;
}
}
}
// void BlockDecompressImageDXT5(): Decompresses all the blocks of a DXT5 compressed texture and stores the resulting pixels in 'image'.
//
// unsigned long width: Texture width.
// unsigned long height: Texture height.
// const unsigned char *blockStorage: pointer to compressed DXT5 blocks.
// unsigned long *image: pointer to the image where the decompressed pixels will be stored.
void CImageLoaderTex::BlockDecompressImageDXT5(unsigned long width, unsigned long height, const unsigned char *blockStorage, unsigned long *image) const
{
unsigned long blockCountX = (width + 3) / 4;
unsigned long blockCountY = (height + 3) / 4;
unsigned long blockWidth = (width < 4) ? width : 4;
unsigned long blockHeight = (height < 4) ? height : 4;
for (unsigned long j = 0; j < blockCountY; j++)
{
for (unsigned long i = 0; i < blockCountX; i++) DecompressBlockDXT5(i*4, j*4, width, blockStorage + i * 16, image);
blockStorage += blockCountX * 16;
}
}

View File

@ -0,0 +1,91 @@
#pragma once
#include <irrlicht/irrlicht.h>
using namespace irr;
using namespace irr::video;
namespace WallpaperEngine::Irrlicht
{
//! Surface Loader for PNG files
class CImageLoaderTex : public IImageLoader
{
public:
//! returns true if the file maybe is able to be loaded by this class
//! based on the file extension (e.g. ".png")
virtual bool isALoadableFileExtension(const io::path& filename) const;
//! returns true if the file maybe is able to be loaded by this class
virtual bool isALoadableFileFormat(io::IReadFile* file) const;
//! creates a surface from the file
virtual IImage* loadImage(io::IReadFile* input) const;
virtual void loadImageFromARGB8Data (IImage* output, const char* input, u32 width, u32 height, u32 mipmap_width) const;
virtual void loadImageFromDXT1 (IImage* output, const char* input, u32 destination_width, u32 destination_height, u32 origin_width, u32 origin_height) const;
virtual void loadImageFromDXT5 (IImage* output, const char* input, u32 destination_width, u32 destination_height, u32 origin_width, u32 origin_height) const;
private:
void BlockDecompressImageDXT1(unsigned long width, unsigned long height, const unsigned char *blockStorage, unsigned long *image) const;
void DecompressBlockDXT1(unsigned long x, unsigned long y, unsigned long width, const unsigned char *blockStorage, unsigned long *image) const;
unsigned long PackRGBA(unsigned char r, unsigned char g, unsigned char b, unsigned char a) const;
void BlockDecompressImageDXT5(unsigned long width, unsigned long height, const unsigned char *blockStorage, unsigned long *image) const;
void DecompressBlockDXT5(unsigned long x, unsigned long y, unsigned long width, const unsigned char *blockStorage, unsigned long *image) const;
enum TextureFormat
{
ARGB8888,
RA88,
A8,
DXT5,
DXT3,
DXT1
};
// extracted from the free image library
enum FREE_IMAGE_FORMAT
{
FIF_UNKNOWN = -1,
FIF_BMP = 0,
FIF_ICO = 1,
FIF_JPEG = 2,
FIF_JNG = 3,
FIF_KOALA = 4,
FIF_LBM = 5,
FIF_IFF = FIF_LBM,
FIF_MNG = 6,
FIF_PBM = 7,
FIF_PBMRAW = 8,
FIF_PCD = 9,
FIF_PCX = 10,
FIF_PGM = 11,
FIF_PGMRAW = 12,
FIF_PNG = 13,
FIF_PPM = 14,
FIF_PPMRAW = 15,
FIF_RAS = 16,
FIF_TARGA = 17,
FIF_TIFF = 18,
FIF_WBMP = 19,
FIF_PSD = 20,
FIF_CUT = 21,
FIF_XBM = 22,
FIF_XPM = 23,
FIF_DDS = 24,
FIF_GIF = 25,
FIF_HDR = 26,
FIF_FAXG3 = 27,
FIF_SGI = 28,
FIF_EXR = 29,
FIF_J2K = 30,
FIF_JP2 = 31,
FIF_PFM = 32,
FIF_PICT = 33,
FIF_RAW = 34,
FIF_WEBP = 35,
FIF_JXR = 36
};
};
}

View File

@ -1,10 +1,8 @@
//
// Created by almamu on 4/04/19.
//
#include <WallpaperEngine/irrlicht.h>
#include <WallpaperEngine/Irrlicht/Irrlicht.h>
#include "CPkgReader.h"
using namespace WallpaperEngine::Irrlicht;
CArchiveLoaderPkg::CArchiveLoaderPkg(irr::io::IFileSystem* fs)
: FileSystem(fs)
{
@ -123,7 +121,7 @@ void CPkgReader::scanPkgHeader ()
if (strcmp ("PKGV0002", headerVersion) != 0 && strcmp ("PKGV0001", headerVersion) != 0)
{
WallpaperEngine::irrlicht::device->getLogger ()->log ("Unexpected package header... Aborting load", this->mFile->getFileName ().c_str (), irr::ELL_ERROR);
WallpaperEngine::Irrlicht::device->getLogger ()->log ("Unexpected package header... Aborting load", this->mFile->getFileName ().c_str (), irr::ELL_ERROR);
delete [] headerVersion;
return;
@ -189,6 +187,6 @@ irr::io::IReadFile* CPkgReader::createAndOpenFile (irr::u32 index)
if (index > this->Files.size ())
return nullptr;
const irr::io::SFileListEntry entry = Files [index];
const SFileListEntry entry = Files [index];
return irr::io::createLimitReadFile (entry.FullName, mFile, entry.Offset, entry.Size);
}

View File

@ -0,0 +1,79 @@
#pragma once
#include <irrlicht/irrlicht.h>
#include <string>
#include "CFileList.h"
using namespace irr;
namespace WallpaperEngine::Irrlicht
{
//! 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 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;
};
}

View File

@ -0,0 +1,8 @@
#include <WallpaperEngine/Irrlicht/Irrlicht.h>
namespace WallpaperEngine::Irrlicht
{
irr::video::IVideoDriver* driver = nullptr;
irr::IrrlichtDevice* device = nullptr;
irr::scene::ICameraSceneNode* camera = nullptr;
}

View File

@ -0,0 +1,10 @@
#pragma once
#include <irrlicht/irrlicht.h>
namespace WallpaperEngine::Irrlicht
{
extern irr::video::IVideoDriver* driver;
extern irr::IrrlichtDevice* device;
extern irr::scene::ICameraSceneNode* camera;
};

View File

@ -2,7 +2,7 @@
#include "shaders/compiler.h"
#include "effect.h"
#include "irrlicht.h"
#include "WallpaperEngine/Irrlicht/Irrlicht.h"
#include "WallpaperEngine/Core/Core.h"
extern irr::f32 g_Time;
@ -57,7 +57,7 @@ namespace WallpaperEngine
}
}
this->m_content = WallpaperEngine::fs::utils::loadFullFile (this->m_file);
this->m_content = WallpaperEngine::FileSystem::loadFullFile (this->m_file);
this->m_json = json::parse (this->m_content);
json::const_iterator passes = this->m_json.find ("passes");
@ -76,7 +76,7 @@ namespace WallpaperEngine
continue;
irr::io::path material = (*material_it).get <std::string> ().c_str ();
std::string content = WallpaperEngine::fs::utils::loadFullFile (material);
std::string content = WallpaperEngine::FileSystem::loadFullFile (material);
json material_json = json::parse (content);
json::const_iterator shader_passes = material_json.find ("passes");
@ -97,7 +97,7 @@ namespace WallpaperEngine
this->m_fragShader = new WallpaperEngine::shaders::compiler (fragpath, WallpaperEngine::shaders::compiler::Type::Type_Pixel, &this->m_combos, false);
this->m_vertShader = new WallpaperEngine::shaders::compiler (vertpath, WallpaperEngine::shaders::compiler::Type::Type_Vertex, &this->m_combos, false);
this->m_materialType = WallpaperEngine::irrlicht::driver->getGPUProgrammingServices ()
this->m_materialType = WallpaperEngine::Irrlicht::driver->getGPUProgrammingServices ()
->addHighLevelShaderMaterial (
this->m_vertShader->precompile ().c_str (), "main", irr::video::EVST_VS_2_0,
this->m_fragShader->precompile ().c_str (), "main", irr::video::EPST_PS_2_0,
@ -336,7 +336,7 @@ namespace WallpaperEngine
}
else
{
WallpaperEngine::irrlicht::device->getLogger ()->log ("Unknown type for combo value", name.c_str (), irr::ELL_ERROR);
WallpaperEngine::Irrlicht::device->getLogger ()->log ("Unknown type for combo value", name.c_str (), irr::ELL_ERROR);
}
}
}

View File

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

View File

@ -1,36 +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 WallpaperEngine
{
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

@ -5,7 +5,7 @@
#include <WallpaperEngine/object3d.h>
#include <WallpaperEngine/image.h>
#include <WallpaperEngine/irrlicht.h>
#include <WallpaperEngine/Irrlicht/Irrlicht.h>
#include <WallpaperEngine/Core/Core.h>
namespace WallpaperEngine
@ -27,7 +27,7 @@ namespace WallpaperEngine
if (file_it != json_data.end () && (*file_it).is_string () == true)
{
this->m_file = (*file_it).get <std::string> ().c_str ();
this->m_content = WallpaperEngine::fs::utils::loadFullFile (this->m_file);
this->m_content = WallpaperEngine::FileSystem::loadFullFile (this->m_file);
json content = json::parse (this->m_content);
json::const_iterator it = content.find ("material");
@ -35,7 +35,7 @@ namespace WallpaperEngine
if (it != content.end () && (*it).is_string () == true)
{
irr::io::path materialfile = (*it).get <std::string> ().c_str ();
std::string texturejson_content = WallpaperEngine::fs::utils::loadFullFile (materialfile);
std::string texturejson_content = WallpaperEngine::FileSystem::loadFullFile (materialfile);
json materialcontent = json::parse (texturejson_content);
// now try to read the texture if any
@ -153,8 +153,8 @@ namespace WallpaperEngine
0, 1, 2, 3
};
WallpaperEngine::irrlicht::driver->setMaterial (this->getMaterial ());
WallpaperEngine::irrlicht::driver->drawVertexPrimitiveList (this->m_vertices, 4, indices, 1, irr::video::EVT_STANDARD, irr::scene::EPT_QUADS, irr::video::EIT_16BIT);
WallpaperEngine::Irrlicht::driver->setMaterial (this->getMaterial ());
WallpaperEngine::Irrlicht::driver->drawVertexPrimitiveList (this->m_vertices, 4, indices, 1, irr::video::EVT_STANDARD, irr::scene::EPT_QUADS, irr::video::EIT_16BIT);
}
}

View File

@ -1,157 +0,0 @@
// 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

@ -1,136 +0,0 @@
// 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

@ -1,553 +0,0 @@
#include "CImageLoaderTEX.h"
#include <irrlicht/irrlicht.h>
#include <lz4.h>
#include <WallpaperEngine/irrlicht.h>
#include <string>
namespace irr {
namespace video {
//! returns true if the file maybe is able to be loaded by this class
//! based on the file extension (e.g. ".tga")
bool CImageLoaderTex::isALoadableFileExtension (const io::path &filename) const
{
return core::hasFileExtension (filename, "tex");
}
//! returns true if the file maybe is able to be loaded by this class
bool CImageLoaderTex::isALoadableFileFormat (io::IReadFile *file) const
{
return false;
}
// load in the image data
IImage *CImageLoaderTex::loadImage (io::IReadFile *input) const
{
if (!input)
return nullptr;
video::IImage *image = nullptr;
char buffer [1024];
if (input->read (buffer, 9) != 9)
{
WallpaperEngine::irrlicht::device->getLogger ()->log ("LOAD TEX: cannot read header\n", input->getFileName ().c_str (), irr::ELL_ERROR);
return nullptr;
}
if (memcmp (buffer, "TEXV0005", 9) != 0)
{
WallpaperEngine::irrlicht::device->getLogger ()->log ("LOAD TEX: not really a tex\n", input->getFileName ().c_str (), irr::ELL_ERROR);
return nullptr;
}
if (input->read (buffer, 9) != 9)
{
WallpaperEngine::irrlicht::device->getLogger ()->log ("LOAD TEX: cannot read second header\n", input->getFileName ().c_str (), irr::ELL_ERROR);
return nullptr;
}
if (memcmp (buffer, "TEXI0001", 9) != 0)
{
WallpaperEngine::irrlicht::device->getLogger ()->log ("LOAD TEX: not really a tex\n", input->getFileName ().c_str (), irr::ELL_ERROR);
return nullptr;
}
u32 width;
u32 height;
u32 texture_width;
u32 texture_height;
u32 format;
u32 imageFormat = FREE_IMAGE_FORMAT::FIF_UNKNOWN;
u8 containerVersion = 0;
input->read (&format, 4);
input->seek (4, true); // ignore bytes
input->read (&texture_width, 4);
input->read (&texture_height, 4);
input->read (&width, 4);
input->read (&height, 4);
input->seek (4, true); // ignore bytes
input->read (buffer, 9);
if (memcmp (buffer, "TEXB0003", 9) == 0)
{
containerVersion = 3;
input->seek (4, true);
input->read (&imageFormat, 4);
}
else if (memcmp (buffer, "TEXB0002", 9) == 0)
{
containerVersion = 2;
input->seek (4, true);
}
else if (memcmp (buffer, "TEXB0001", 9) == 0)
{
containerVersion = 1;
input->seek (4, true);
}
else
{
WallpaperEngine::irrlicht::device->getLogger ()->log ("LOAD TEX: Unknown container type\n", input->getFileName ().c_str (), irr::ELL_ERROR);
return nullptr;
}
if (format == TextureFormat::A8)
{
WallpaperEngine::irrlicht::device->getLogger ()-> log ("LOAD TEX: A8 not supported\n", input->getFileName ().c_str (), irr::ELL_ERROR);
return nullptr;
}
if (format == TextureFormat::RA88)
{
WallpaperEngine::irrlicht::device->getLogger ()->log ("LOAD TEX: RA88 not supported\n", input->getFileName ().c_str (), irr::ELL_ERROR);
return nullptr;
}
u32 mipmap_count = 0;
input->read (&mipmap_count, 4);
u32 mipmap_width = 0;
u32 mipmap_height = 0;
u32 mipmap_compression = 0;
u32 mipmap_uncompressed_size = 0;
u32 mipmap_compressed_size = 0;
input->read (&mipmap_width, 4);
input->read (&mipmap_height, 4);
if (containerVersion > 1)
{
input->read (&mipmap_compression, 4);
input->read (&mipmap_uncompressed_size, 4);
}
input->read (&mipmap_compressed_size, 4);
// TODO: BETTER POSITION FOR THIS
if (mipmap_compression == 0)
{
// this might be better named as mipmap_bytes_size instead of compressed_size
// as in uncompressed files this variable actually holds the file length
mipmap_uncompressed_size = mipmap_compressed_size;
}
char *decompressedBuffer = new char [mipmap_uncompressed_size];
if (mipmap_compression == 1)
{
char *compressedBuffer = new char [mipmap_compressed_size];
input->read (compressedBuffer, mipmap_compressed_size);
int result = LZ4_decompress_safe (compressedBuffer, decompressedBuffer, mipmap_compressed_size, mipmap_uncompressed_size);
if (!result)
{
delete [] decompressedBuffer;
delete [] compressedBuffer;
WallpaperEngine::irrlicht::device->getLogger ()->log ("LOAD TEX: cannot decompress texture data\n", input->getFileName ().c_str (), irr::ELL_ERROR);
return nullptr;
}
delete [] compressedBuffer;
}
else
{
input->read (decompressedBuffer, mipmap_uncompressed_size);
}
if (imageFormat == FREE_IMAGE_FORMAT::FIF_UNKNOWN)
{
image = WallpaperEngine::irrlicht::driver->createImage (ECF_A8R8G8B8, irr::core::dimension2d<u32> (width, height));
if (!image)
{
delete [] decompressedBuffer;
delete image;
WallpaperEngine::irrlicht::device->getLogger ()->log ("LOAD TEX: cannot create destination image\n", input->getFileName ().c_str (), irr::ELL_ERROR);
return nullptr;
}
switch (format)
{
case TextureFormat::ARGB8888:
this->loadImageFromARGB8Data (image, decompressedBuffer, width, height, mipmap_width);
break;
case TextureFormat::DXT5:
this->loadImageFromDXT5 (image, decompressedBuffer, width, height, mipmap_width, mipmap_height);
break;
case TextureFormat::DXT1:
this->loadImageFromDXT1 (image, decompressedBuffer, width, height, mipmap_width, mipmap_height);
break;
case TextureFormat::DXT3:
WallpaperEngine::irrlicht::device->getLogger ()->log ("LOAD TEX: DXT3 textures not supported yet\n", input->getFileName ().c_str (), irr::ELL_ERROR);
delete [] decompressedBuffer;
delete image;
return nullptr;
}
}
else
{
// copy the buffer to a new address
char* filebuffer = new char [mipmap_uncompressed_size];
char tmpname [TMP_MAX];
// copy file data to the final file buffer to be used
memcpy (filebuffer, decompressedBuffer, mipmap_uncompressed_size);
// generate temporal name
std::tmpnam (tmpname);
// store it in a std::string
std::string filename = tmpname;
irr::io::IReadFile* file;
// free image format
switch (imageFormat)
{
case FREE_IMAGE_FORMAT::FIF_BMP:
// add extension to the file
filename += ".bmp";
file = WallpaperEngine::irrlicht::device->getFileSystem ()->createMemoryReadFile (filebuffer, mipmap_uncompressed_size, filename.c_str (), true);
break;
case FREE_IMAGE_FORMAT::FIF_PNG:
// add extension to the file
filename += ".png";
file = WallpaperEngine::irrlicht::device->getFileSystem ()->createMemoryReadFile (filebuffer, mipmap_uncompressed_size, filename.c_str (), true);
break;
case FREE_IMAGE_FORMAT::FIF_JPEG:
// add extension to the file
filename += ".jpg";
WallpaperEngine::irrlicht::device->getFileSystem ()->createAndWriteFile ("/tmp/test.jpg", false)->write (filebuffer, mipmap_uncompressed_size);
file = WallpaperEngine::irrlicht::device->getFileSystem ()->createMemoryReadFile (filebuffer, mipmap_uncompressed_size, filename.c_str (), true);
break;
case FREE_IMAGE_FORMAT::FIF_GIF:
filename += ".gif";
file = WallpaperEngine::irrlicht::device->getFileSystem ()->createMemoryReadFile (filebuffer, mipmap_uncompressed_size, filename.c_str (), true);
break;
default:
WallpaperEngine::irrlicht::device->getLogger ()->log ("LOAD TEX: detected unsupported free-image format\n", input->getFileName ().c_str (), irr::ELL_ERROR);
delete [] decompressedBuffer;
delete [] filebuffer;
return nullptr;
}
image = WallpaperEngine::irrlicht::driver->createImageFromFile (file);
if (!image)
{
file->drop ();
delete [] decompressedBuffer;
delete image;
WallpaperEngine::irrlicht::device->getLogger ()->log ("LOAD TEX: cannot create destination image\n", input->getFileName ().c_str (), irr::ELL_ERROR);
return nullptr;
}
}
delete [] decompressedBuffer;
return image;
}
void CImageLoaderTex::loadImageFromARGB8Data (IImage* output, const char* input, u32 width, u32 height, u32 mipmap_width) const
{
u32 bytesPerPixel = output->getBytesPerPixel ();
char *imagedata = (char *) output->lock ();
for (u32 y = 0; y < height; y ++)
{
u32 baseDestination = y * output->getPitch ();
u32 baseOrigin = y * (mipmap_width * 4);
for (u32 x = 0; x < width; x ++)
{
imagedata [baseDestination + (x * bytesPerPixel) + 2] = input [baseOrigin + ((width - x) * 4) + 0]; // r
imagedata [baseDestination + (x * bytesPerPixel) + 1] = input [baseOrigin + ((width - x) * 4) + 1]; // g
imagedata [baseDestination + (x * bytesPerPixel) + 0] = input [baseOrigin + ((width - x) * 4) + 2]; // b
imagedata [baseDestination + (x * bytesPerPixel) + 3] = input [baseOrigin + ((width - x) * 4) + 3]; // alpha
}
}
output->unlock ();
}
void CImageLoaderTex::loadImageFromDXT1 (IImage* output, const char* input, u32 destination_width, u32 destination_height, u32 origin_width, u32 origin_height) const
{
char* decompressedBuffer = new char [origin_width * origin_height * 4];
this->BlockDecompressImageDXT1 (origin_width, origin_height, (const unsigned char*) input, (unsigned long*) decompressedBuffer);
this->loadImageFromARGB8Data (output, decompressedBuffer, destination_width, destination_height, origin_width);
delete [] decompressedBuffer;
}
void CImageLoaderTex::loadImageFromDXT5 (IImage* output, const char* input, u32 destination_width, u32 destination_height, u32 origin_width, u32 origin_height) const
{
char* decompressedBuffer = new char [origin_width * origin_height * 4];
this->BlockDecompressImageDXT5 (origin_width, origin_height, (const unsigned char*) input, (unsigned long*) decompressedBuffer);
this->loadImageFromARGB8Data (output, decompressedBuffer, destination_width, destination_height, origin_width);
delete [] decompressedBuffer;
}
// ------------------------------------------------------------------------------------
// The following code is a slightly modified version of this repository
// https://github.com/Benjamin-Dobell/s3tc-dxt-decompression
// ------------------------------------------------------------------------------------
// unsigned long PackRGBA(): Helper method that packs RGBA channels into a single 4 byte pixel.
//
// unsigned char r: red channel.
// unsigned char g: green channel.
// unsigned char b: blue channel.
// unsigned char a: alpha channel.
unsigned long CImageLoaderTex::PackRGBA(unsigned char r, unsigned char g, unsigned char b, unsigned char a) const
{
return ((r << 24) | (g << 16) | (b << 8) | a);
}
// void DecompressBlockDXT1(): Decompresses one block of a DXT1 texture and stores the resulting pixels at the appropriate offset in 'image'.
//
// unsigned long x: x-coordinate of the first pixel in the block.
// unsigned long y: y-coordinate of the first pixel in the block.
// unsigned long width: width of the texture being decompressed.
// unsigned long height: height of the texture being decompressed.
// const unsigned char *blockStorage: pointer to the block to decompress.
// unsigned long *image: pointer to image where the decompressed pixel data should be stored.
void CImageLoaderTex::DecompressBlockDXT1(unsigned long x, unsigned long y, unsigned long width, const unsigned char *blockStorage, unsigned long *image) const
{
unsigned short color0 = *reinterpret_cast<const unsigned short *>(blockStorage);
unsigned short color1 = *reinterpret_cast<const unsigned short *>(blockStorage + 2);
unsigned long temp;
temp = (color0 >> 11) * 255 + 16;
unsigned char r0 = (unsigned char)((temp/32 + temp)/32);
temp = ((color0 & 0x07E0) >> 5) * 255 + 32;
unsigned char g0 = (unsigned char)((temp/64 + temp)/64);
temp = (color0 & 0x001F) * 255 + 16;
unsigned char b0 = (unsigned char)((temp/32 + temp)/32);
temp = (color1 >> 11) * 255 + 16;
unsigned char r1 = (unsigned char)((temp/32 + temp)/32);
temp = ((color1 & 0x07E0) >> 5) * 255 + 32;
unsigned char g1 = (unsigned char)((temp/64 + temp)/64);
temp = (color1 & 0x001F) * 255 + 16;
unsigned char b1 = (unsigned char)((temp/32 + temp)/32);
unsigned long code = *reinterpret_cast<const unsigned long *>(blockStorage + 4);
for (int j=0; j < 4; j++)
{
for (int i=0; i < 4; i++)
{
unsigned long finalColor = 0;
unsigned char positionCode = (code >> 2*(4*j+i)) & 0x03;
if (color0 > color1)
{
switch (positionCode)
{
case 0:
finalColor = PackRGBA(r0, g0, b0, 255);
break;
case 1:
finalColor = PackRGBA(r1, g1, b1, 255);
break;
case 2:
finalColor = PackRGBA((2*r0+r1)/3, (2*g0+g1)/3, (2*b0+b1)/3, 255);
break;
case 3:
finalColor = PackRGBA((r0+2*r1)/3, (g0+2*g1)/3, (b0+2*b1)/3, 255);
break;
}
}
else
{
switch (positionCode)
{
case 0:
finalColor = PackRGBA(r0, g0, b0, 255);
break;
case 1:
finalColor = PackRGBA(r1, g1, b1, 255);
break;
case 2:
finalColor = PackRGBA((r0+r1)/2, (g0+g1)/2, (b0+b1)/2, 255);
break;
case 3:
finalColor = PackRGBA(0, 0, 0, 255);
break;
}
}
if (x + i < width)
image[(y + j)*width + (x + i)] = finalColor;
}
}
}
// void BlockDecompressImageDXT1(): Decompresses all the blocks of a DXT1 compressed texture and stores the resulting pixels in 'image'.
//
// unsigned long width: Texture width.
// unsigned long height: Texture height.
// const unsigned char *blockStorage: pointer to compressed DXT1 blocks.
// unsigned long *image: pointer to the image where the decompressed pixels will be stored.
void CImageLoaderTex::BlockDecompressImageDXT1(unsigned long width, unsigned long height, const unsigned char *blockStorage, unsigned long *image) const
{
unsigned long blockCountX = (width + 3) / 4;
unsigned long blockCountY = (height + 3) / 4;
unsigned long blockWidth = (width < 4) ? width : 4;
unsigned long blockHeight = (height < 4) ? height : 4;
for (unsigned long j = 0; j < blockCountY; j++)
{
for (unsigned long i = 0; i < blockCountX; i++) DecompressBlockDXT1(i*4, j*4, width, blockStorage + i * 8, image);
blockStorage += blockCountX * 8;
}
}
// void DecompressBlockDXT5(): Decompresses one block of a DXT5 texture and stores the resulting pixels at the appropriate offset in 'image'.
//
// unsigned long x: x-coordinate of the first pixel in the block.
// unsigned long y: y-coordinate of the first pixel in the block.
// unsigned long width: width of the texture being decompressed.
// unsigned long height: height of the texture being decompressed.
// const unsigned char *blockStorage: pointer to the block to decompress.
// unsigned long *image: pointer to image where the decompressed pixel data should be stored.
void CImageLoaderTex::DecompressBlockDXT5(unsigned long x, unsigned long y, unsigned long width, const unsigned char *blockStorage, unsigned long *image) const
{
unsigned char alpha0 = *reinterpret_cast<const unsigned char *>(blockStorage);
unsigned char alpha1 = *reinterpret_cast<const unsigned char *>(blockStorage + 1);
const unsigned char *bits = blockStorage + 2;
unsigned long alphaCode1 = bits[2] | (bits[3] << 8) | (bits[4] << 16) | (bits[5] << 24);
unsigned short alphaCode2 = bits[0] | (bits[1] << 8);
unsigned short color0 = *reinterpret_cast<const unsigned short *>(blockStorage + 8);
unsigned short color1 = *reinterpret_cast<const unsigned short *>(blockStorage + 10);
unsigned long temp;
temp = (color0 >> 11) * 255 + 16;
unsigned char r0 = (unsigned char)((temp/32 + temp)/32);
temp = ((color0 & 0x07E0) >> 5) * 255 + 32;
unsigned char g0 = (unsigned char)((temp/64 + temp)/64);
temp = (color0 & 0x001F) * 255 + 16;
unsigned char b0 = (unsigned char)((temp/32 + temp)/32);
temp = (color1 >> 11) * 255 + 16;
unsigned char r1 = (unsigned char)((temp/32 + temp)/32);
temp = ((color1 & 0x07E0) >> 5) * 255 + 32;
unsigned char g1 = (unsigned char)((temp/64 + temp)/64);
temp = (color1 & 0x001F) * 255 + 16;
unsigned char b1 = (unsigned char)((temp/32 + temp)/32);
unsigned long code = *reinterpret_cast<const unsigned long *>(blockStorage + 12);
for (int j=0; j < 4; j++)
{
for (int i=0; i < 4; i++)
{
int alphaCodeIndex = 3*(4*j+i);
int alphaCode;
if (alphaCodeIndex <= 12)
{
alphaCode = (alphaCode2 >> alphaCodeIndex) & 0x07;
}
else if (alphaCodeIndex == 15)
{
alphaCode = (alphaCode2 >> 15) | ((alphaCode1 << 1) & 0x06);
}
else // alphaCodeIndex >= 18 && alphaCodeIndex <= 45
{
alphaCode = (alphaCode1 >> (alphaCodeIndex - 16)) & 0x07;
}
unsigned char finalAlpha;
if (alphaCode == 0)
{
finalAlpha = alpha0;
}
else if (alphaCode == 1)
{
finalAlpha = alpha1;
}
else
{
if (alpha0 > alpha1)
{
finalAlpha = ((8-alphaCode)*alpha0 + (alphaCode-1)*alpha1)/7;
}
else
{
if (alphaCode == 6)
finalAlpha = 0;
else if (alphaCode == 7)
finalAlpha = 255;
else
finalAlpha = ((6-alphaCode)*alpha0 + (alphaCode-1)*alpha1)/5;
}
}
unsigned char colorCode = (code >> 2*(4*j+i)) & 0x03;
unsigned long finalColor;
switch (colorCode)
{
case 0:
finalColor = PackRGBA(r0, g0, b0, finalAlpha);
break;
case 1:
finalColor = PackRGBA(r1, g1, b1, finalAlpha);
break;
case 2:
finalColor = PackRGBA((2*r0+r1)/3, (2*g0+g1)/3, (2*b0+b1)/3, finalAlpha);
break;
case 3:
finalColor = PackRGBA((r0+2*r1)/3, (g0+2*g1)/3, (b0+2*b1)/3, finalAlpha);
break;
}
if (x + i < width)
image[(y + j)*width + (x + i)] = finalColor;
}
}
}
// void BlockDecompressImageDXT5(): Decompresses all the blocks of a DXT5 compressed texture and stores the resulting pixels in 'image'.
//
// unsigned long width: Texture width.
// unsigned long height: Texture height.
// const unsigned char *blockStorage: pointer to compressed DXT5 blocks.
// unsigned long *image: pointer to the image where the decompressed pixels will be stored.
void CImageLoaderTex::BlockDecompressImageDXT5(unsigned long width, unsigned long height, const unsigned char *blockStorage, unsigned long *image) const
{
unsigned long blockCountX = (width + 3) / 4;
unsigned long blockCountY = (height + 3) / 4;
unsigned long blockWidth = (width < 4) ? width : 4;
unsigned long blockHeight = (height < 4) ? height : 4;
for (unsigned long j = 0; j < blockCountY; j++)
{
for (unsigned long i = 0; i < blockCountX; i++) DecompressBlockDXT5(i*4, j*4, width, blockStorage + i * 16, image);
blockStorage += blockCountX * 16;
}
}
}// end namespace irr
}//end namespace video

View File

@ -1,97 +0,0 @@
#ifndef __C_IMAGE_LOADER_TEX_H_INCLUDED__
#define __C_IMAGE_LOADER_TEX_H_INCLUDED__
#include <irrlicht/irrlicht.h>
namespace irr
{
namespace video
{
//! Surface Loader for PNG files
class CImageLoaderTex : public IImageLoader
{
public:
//! returns true if the file maybe is able to be loaded by this class
//! based on the file extension (e.g. ".png")
virtual bool isALoadableFileExtension(const io::path& filename) const;
//! returns true if the file maybe is able to be loaded by this class
virtual bool isALoadableFileFormat(io::IReadFile* file) const;
//! creates a surface from the file
virtual IImage* loadImage(io::IReadFile* input) const;
virtual void loadImageFromARGB8Data (IImage* output, const char* input, u32 width, u32 height, u32 mipmap_width) const;
virtual void loadImageFromDXT1 (IImage* output, const char* input, u32 destination_width, u32 destination_height, u32 origin_width, u32 origin_height) const;
virtual void loadImageFromDXT5 (IImage* output, const char* input, u32 destination_width, u32 destination_height, u32 origin_width, u32 origin_height) const;
private:
void BlockDecompressImageDXT1(unsigned long width, unsigned long height, const unsigned char *blockStorage, unsigned long *image) const;
void DecompressBlockDXT1(unsigned long x, unsigned long y, unsigned long width, const unsigned char *blockStorage, unsigned long *image) const;
unsigned long PackRGBA(unsigned char r, unsigned char g, unsigned char b, unsigned char a) const;
void BlockDecompressImageDXT5(unsigned long width, unsigned long height, const unsigned char *blockStorage, unsigned long *image) const;
void DecompressBlockDXT5(unsigned long x, unsigned long y, unsigned long width, const unsigned char *blockStorage, unsigned long *image) const;
enum TextureFormat
{
ARGB8888,
RA88,
A8,
DXT5,
DXT3,
DXT1
};
// extracted from the free image library
enum FREE_IMAGE_FORMAT
{
FIF_UNKNOWN = -1,
FIF_BMP = 0,
FIF_ICO = 1,
FIF_JPEG = 2,
FIF_JNG = 3,
FIF_KOALA = 4,
FIF_LBM = 5,
FIF_IFF = FIF_LBM,
FIF_MNG = 6,
FIF_PBM = 7,
FIF_PBMRAW = 8,
FIF_PCD = 9,
FIF_PCX = 10,
FIF_PGM = 11,
FIF_PGMRAW = 12,
FIF_PNG = 13,
FIF_PPM = 14,
FIF_PPMRAW = 15,
FIF_RAS = 16,
FIF_TARGA = 17,
FIF_TIFF = 18,
FIF_WBMP = 19,
FIF_PSD = 20,
FIF_CUT = 21,
FIF_XBM = 22,
FIF_XPM = 23,
FIF_DDS = 24,
FIF_GIF = 25,
FIF_HDR = 26,
FIF_FAXG3 = 27,
FIF_SGI = 28,
FIF_EXR = 29,
FIF_J2K = 30,
FIF_JP2 = 31,
FIF_PFM = 32,
FIF_PICT = 33,
FIF_RAW = 34,
FIF_WEBP = 35,
FIF_JXR = 36
};
};
} // end namespace video
} // end namespace irr
#endif /* !__C_IMAGE_LOADER_TEX_H_INCLUDED__ */

View File

@ -1,82 +0,0 @@
//
// 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

@ -1,8 +0,0 @@
#include <WallpaperEngine/irrlicht.h>
namespace WallpaperEngine
{
irr::video::IVideoDriver* irrlicht::driver = nullptr;
irr::IrrlichtDevice* irrlicht::device = nullptr;
irr::scene::ICameraSceneNode* irrlicht::camera = nullptr;
}

View File

@ -1,18 +0,0 @@
#ifndef WALLENGINE_IRRLICHT_H
#define WALLENGINE_IRRLICHT_H
#include <irrlicht/irrlicht.h>
namespace WallpaperEngine
{
class irrlicht
{
public:
static irr::video::IVideoDriver* driver;
static irr::IrrlichtDevice* device;
static irr::scene::ICameraSceneNode* camera;
};
}
#endif //WALLENGINE_IRRLICHT_H

View File

@ -6,13 +6,13 @@
#include "WallpaperEngine/fs/utils.h"
#include "project.h"
#include "irrlicht.h"
#include "WallpaperEngine/Irrlicht/Irrlicht.h"
namespace WallpaperEngine
{
project::project (irr::io::path& jsonfile_path)
{
this->m_content = WallpaperEngine::fs::utils::loadFullFile (jsonfile_path);
this->m_content = WallpaperEngine::FileSystem::loadFullFile (jsonfile_path);
this->m_projectFile = json::parse (this->m_content);
json::const_iterator file_it = this->m_projectFile.find ("file");

View File

@ -14,7 +14,7 @@ namespace WallpaperEngine
scene::scene (irr::io::path& file)
{
this->m_content = WallpaperEngine::fs::utils::loadFullFile (file);
this->m_content = WallpaperEngine::FileSystem::loadFullFile (file);
this->m_json = json::parse (this->m_content);
// check basic elements

View File

@ -7,7 +7,7 @@
#include <WallpaperEngine/fs/utils.h>
// video engine
#include <WallpaperEngine/irrlicht.h>
#include <WallpaperEngine/Irrlicht/Irrlicht.h>
// shader compiler
#include <WallpaperEngine/shaders/compiler.h>
@ -58,7 +58,7 @@ namespace WallpaperEngine
this->m_content = "";
}
this->m_content.append (WallpaperEngine::fs::utils::loadFullFile (file));
this->m_content.append (WallpaperEngine::FileSystem::loadFullFile (file));
// append file content
this->m_type = type;
@ -244,7 +244,7 @@ namespace WallpaperEngine
std::string compiler::precompile()
{
#define BREAK_IF_ERROR if (this->m_error == true) { WallpaperEngine::irrlicht::device->getLogger ()->log ("ERROR PRE-COMPILING SHADER", irr::ELL_ERROR); WallpaperEngine::irrlicht::device->getLogger ()->log (this->m_errorInfo.c_str (), irr::ELL_ERROR); return ""; }
#define BREAK_IF_ERROR if (this->m_error == true) { WallpaperEngine::Irrlicht::device->getLogger ()->log ("ERROR PRE-COMPILING SHADER", irr::ELL_ERROR); WallpaperEngine::Irrlicht::device->getLogger ()->log (this->m_errorInfo.c_str (), irr::ELL_ERROR); return ""; }
// parse the shader and find #includes and such things and translate them to the correct name
// also remove any #version definition to prevent errors
std::string::const_iterator it = this->m_content.begin ();
@ -445,8 +445,8 @@ namespace WallpaperEngine
if (this->m_recursive == false)
{
WallpaperEngine::irrlicht::device->getLogger ()->log ("Compiled shader output for", this->m_file.c_str ());
WallpaperEngine::irrlicht::device->getLogger ()->log (this->m_compiledContent.c_str ());
WallpaperEngine::Irrlicht::device->getLogger ()->log ("Compiled shader output for", this->m_file.c_str ());
WallpaperEngine::Irrlicht::device->getLogger ()->log (this->m_compiledContent.c_str ());
}
return this->m_compiledContent;
@ -464,7 +464,7 @@ namespace WallpaperEngine
if (combo == data.end () || defvalue == data.end ())
{
WallpaperEngine::irrlicht::device->getLogger ()->log ("Cannot parse combo information", irr::ELL_ERROR);
WallpaperEngine::Irrlicht::device->getLogger ()->log ("Cannot parse combo information", irr::ELL_ERROR);
return;
}
@ -490,7 +490,7 @@ namespace WallpaperEngine
}
else
{
WallpaperEngine::irrlicht::device->getLogger ()->log ("Cannot parse combo information, unknown type", irr::ELL_ERROR);
WallpaperEngine::Irrlicht::device->getLogger ()->log ("Cannot parse combo information, unknown type", irr::ELL_ERROR);
}
}
}
@ -506,7 +506,7 @@ namespace WallpaperEngine
if (material == data.end () || defvalue == data.end ())
{
if (type != "sampler2D")
WallpaperEngine::irrlicht::device->getLogger ()->log ("Cannot parse parameter info for ", name.c_str (), irr::ELL_ERROR);
WallpaperEngine::Irrlicht::device->getLogger ()->log ("Cannot parse parameter info for ", name.c_str (), irr::ELL_ERROR);
return;
}

View File

@ -5,6 +5,7 @@
#include <iostream>
#include <vector>
#include <map>
#include <nlohmann/json.hpp>
#include <WallpaperEngine/fs/utils.h>
@ -12,6 +13,8 @@ namespace WallpaperEngine
{
namespace shaders
{
using json = nlohmann::json;
/**
* A basic shader loader that adds basic function definitions to every loaded shader
*/

View File

@ -5,7 +5,7 @@
#include <SDL_rwops.h>
#include <SDL_mixer.h>
#include "sound.h"
#include "irrlicht.h"
#include "WallpaperEngine/Irrlicht/Irrlicht.h"
namespace WallpaperEngine
{
@ -31,7 +31,7 @@ namespace WallpaperEngine
{
SDL_RWops* sdlRwops = nullptr;
Mix_Music* music = nullptr;
irr::io::IReadFile* readfile = WallpaperEngine::irrlicht::device->getFileSystem ()->createAndOpenFile ((*cur).c_str ());
irr::io::IReadFile* readfile = WallpaperEngine::Irrlicht::device->getFileSystem ()->createAndOpenFile ((*cur).c_str ());
int filesize = readfile->getSize ();
char* filebuffer = new char [filesize];
@ -43,7 +43,7 @@ namespace WallpaperEngine
if (music == nullptr)
{
WallpaperEngine::irrlicht::device->getLogger ()->log ("Cannot load audio", Mix_GetError (), irr::ELL_ERROR);
WallpaperEngine::Irrlicht::device->getLogger ()->log ("Cannot load audio", Mix_GetError (), irr::ELL_ERROR);
}
this->m_bufferReader.push_back (sdlRwops);
@ -58,7 +58,7 @@ namespace WallpaperEngine
{
if (Mix_PlayMusic ((*mixcur), -1) == -1)
{
WallpaperEngine::irrlicht::device->getLogger ()->log ("Cannot play audio", Mix_GetError (), irr::ELL_ERROR);
WallpaperEngine::Irrlicht::device->getLogger ()->log ("Cannot play audio", Mix_GetError (), irr::ELL_ERROR);
}
}
}

View File

@ -2,13 +2,13 @@
#include <stdexcept>
#include <lz4.h>
#include "irrlicht.h"
#include "WallpaperEngine/Irrlicht/Irrlicht.h"
namespace WallpaperEngine
{
texture::texture (irr::io::path& file)
{
this->m_texture = WallpaperEngine::irrlicht::driver->getTexture (file);
this->m_texture = WallpaperEngine::Irrlicht::driver->getTexture (file);
}
irr::video::ITexture* texture::getIrrTexture ()

View File

@ -1,4 +1,4 @@
#include <WallpaperEngine/irrlicht.h>
#include <WallpaperEngine/Irrlicht/Irrlicht.h>
#include <WallpaperEngine/video/material.h>
namespace WallpaperEngine
@ -56,8 +56,8 @@ namespace WallpaperEngine
0, 1, 2, 3
};
WallpaperEngine::irrlicht::driver->setMaterial (m_material);
WallpaperEngine::irrlicht::driver->drawVertexPrimitiveList (m_vertices, 4, indices, 1, irr::video::EVT_STANDARD, irr::scene::EPT_QUADS, irr::video::EIT_16BIT);
WallpaperEngine::Irrlicht::driver->setMaterial (m_material);
WallpaperEngine::Irrlicht::driver->drawVertexPrimitiveList (m_vertices, 4, indices, 1, irr::video::EVT_STANDARD, irr::scene::EPT_QUADS, irr::video::EIT_16BIT);
}
}
}

View File

@ -1,4 +1,4 @@
#include <WallpaperEngine/irrlicht.h>
#include <WallpaperEngine/Irrlicht/Irrlicht.h>
#include <WallpaperEngine/video/renderer.h>
namespace WallpaperEngine
@ -31,19 +31,19 @@ namespace WallpaperEngine
znear,
zfar
);
WallpaperEngine::irrlicht::camera = WallpaperEngine::irrlicht::device->getSceneManager ()->addCameraSceneNode (0, position, lookat);
WallpaperEngine::irrlicht::camera->setProjectionMatrix (orthoProjection);
WallpaperEngine::Irrlicht::camera = WallpaperEngine::Irrlicht::device->getSceneManager ()->addCameraSceneNode (0, position, lookat);
WallpaperEngine::Irrlicht::camera->setProjectionMatrix (orthoProjection);
WallpaperEngine::irrlicht::driver->setTransform (irr::video::ETS_PROJECTION, orthoProjection);
WallpaperEngine::irrlicht::driver->setTransform (irr::video::ETS_VIEW, identity);
WallpaperEngine::irrlicht::driver->setTransform (irr::video::ETS_WORLD, identity);
WallpaperEngine::Irrlicht::driver->setTransform (irr::video::ETS_PROJECTION, orthoProjection);
WallpaperEngine::Irrlicht::driver->setTransform (irr::video::ETS_VIEW, identity);
WallpaperEngine::Irrlicht::driver->setTransform (irr::video::ETS_WORLD, identity);
}
void renderer::render ()
{
if (WallpaperEngine::irrlicht::driver == nullptr) return;
if (WallpaperEngine::Irrlicht::driver == nullptr) return;
WallpaperEngine::irrlicht::driver->beginScene(true, true, irr::video::SColor(0, 0, 0, 0));
WallpaperEngine::Irrlicht::driver->beginScene(true, true, irr::video::SColor(0, 0, 0, 0));
std::vector<node*>::const_iterator cur = s_nodes.begin ();
std::vector<node*>::const_iterator end = s_nodes.end ();
@ -53,7 +53,7 @@ namespace WallpaperEngine
(*cur)->render ();
}
WallpaperEngine::irrlicht::driver->endScene ();
WallpaperEngine::Irrlicht::driver->endScene ();
}
std::vector<node*> renderer::s_nodes;

View File

@ -3,15 +3,15 @@
#include <sstream>
#include <WallpaperEngine/video/renderer.h>
#include <WallpaperEngine/video/material.h>
#include <WallpaperEngine/irr/CPkgReader.h>
#include <WallpaperEngine/Irrlicht/CPkgReader.h>
#include <getopt.h>
#include <SDL_mixer.h>
#include <SDL.h>
#include "WallpaperEngine/shaders/compiler.h"
#include "WallpaperEngine/project.h"
#include "WallpaperEngine/irrlicht.h"
#include "WallpaperEngine/irr/CImageLoaderTEX.h"
#include "WallpaperEngine/Irrlicht/Irrlicht.h"
#include "WallpaperEngine/Irrlicht/CImageLoaderTEX.h"
#include "WallpaperEngine/Core/CProject.h"
@ -25,7 +25,7 @@ int init_irrlicht()
// prepare basic configuration for irrlicht
_irr_params.AntiAlias = 8;
_irr_params.Bits = 16;
// _irr_params.DeviceType = irr::EIDT_X11;
// _irr_params.DeviceType = Irrlicht::EIDT_X11;
_irr_params.DriverType = irr::video::EDT_OPENGL;
_irr_params.Doublebuffer = true;
_irr_params.EventReceiver = nullptr;
@ -40,29 +40,29 @@ int init_irrlicht()
_irr_params.LoggingLevel = irr::ELL_DEBUG;
_irr_params.WindowId = reinterpret_cast<void*> (WinID);
WallpaperEngine::irrlicht::device = irr::createDeviceEx (_irr_params);
WallpaperEngine::Irrlicht::device = irr::createDeviceEx (_irr_params);
if (WallpaperEngine::irrlicht::device == nullptr)
if (WallpaperEngine::Irrlicht::device == nullptr)
{
return 1;
}
WallpaperEngine::irrlicht::device->setWindowCaption (L"Test game");
WallpaperEngine::irrlicht::driver = WallpaperEngine::irrlicht::device->getVideoDriver();
WallpaperEngine::Irrlicht::device->setWindowCaption (L"Test game");
WallpaperEngine::Irrlicht::driver = WallpaperEngine::Irrlicht::device->getVideoDriver();
// check for ps and vs support
if (
WallpaperEngine::irrlicht::driver->queryFeature (irr::video::EVDF_PIXEL_SHADER_1_1) == false &&
WallpaperEngine::irrlicht::driver->queryFeature (irr::video::EVDF_ARB_FRAGMENT_PROGRAM_1) == false)
WallpaperEngine::Irrlicht::driver->queryFeature (irr::video::EVDF_PIXEL_SHADER_1_1) == false &&
WallpaperEngine::Irrlicht::driver->queryFeature (irr::video::EVDF_ARB_FRAGMENT_PROGRAM_1) == false)
{
WallpaperEngine::irrlicht::device->getLogger ()->log ("WARNING: Pixel shaders disabled because of missing driver/hardware support");
WallpaperEngine::Irrlicht::device->getLogger ()->log ("WARNING: Pixel shaders disabled because of missing driver/hardware support");
}
if (
WallpaperEngine::irrlicht::driver->queryFeature (irr::video::EVDF_VERTEX_SHADER_1_1) == false &&
WallpaperEngine::irrlicht::driver->queryFeature (irr::video::EVDF_ARB_VERTEX_PROGRAM_1) == false)
WallpaperEngine::Irrlicht::driver->queryFeature (irr::video::EVDF_VERTEX_SHADER_1_1) == false &&
WallpaperEngine::Irrlicht::driver->queryFeature (irr::video::EVDF_ARB_VERTEX_PROGRAM_1) == false)
{
WallpaperEngine::irrlicht::device->getLogger ()->log ("WARNING: Vertex shaders disabled because of missing driver/hardware support");
WallpaperEngine::Irrlicht::device->getLogger ()->log ("WARNING: Vertex shaders disabled because of missing driver/hardware support");
}
return 0;
@ -71,11 +71,11 @@ int init_irrlicht()
void preconfigure_wallpaper_engine ()
{
// load the assets from wallpaper engine
WallpaperEngine::irrlicht::device->getFileSystem ()->addFileArchive ("assets.zip", true, false);
WallpaperEngine::Irrlicht::device->getFileSystem ()->addFileArchive ("assets.zip", true, false);
// register custom loaders
WallpaperEngine::irrlicht::driver->addExternalImageLoader (new irr::video::CImageLoaderTex ());
WallpaperEngine::irrlicht::device->getFileSystem ()->addArchiveLoader (new CArchiveLoaderPkg (WallpaperEngine::irrlicht::device->getFileSystem ()));
WallpaperEngine::Irrlicht::driver->addExternalImageLoader (new WallpaperEngine::Irrlicht::CImageLoaderTex ());
WallpaperEngine::Irrlicht::device->getFileSystem ()->addArchiveLoader (new WallpaperEngine::Irrlicht::CArchiveLoaderPkg (WallpaperEngine::Irrlicht::device->getFileSystem ()));
}
void print_help (const char* route)
@ -164,20 +164,20 @@ int main (int argc, char* argv[])
// pkg mode
case 1:
wallpaper_path = WallpaperEngine::irrlicht::device->getFileSystem ()->getAbsolutePath (path.c_str ());
wallpaper_path = WallpaperEngine::Irrlicht::device->getFileSystem ()->getAbsolutePath (path.c_str ());
project_path = wallpaper_path + "project.json";
scene_path = wallpaper_path + "scene.pkg";
WallpaperEngine::irrlicht::device->getFileSystem ()->addFileArchive (scene_path, true, false); // add the pkg file to the lookup list
WallpaperEngine::Irrlicht::device->getFileSystem ()->addFileArchive (scene_path, true, false); // add the pkg file to the lookup list
break;
// folder mode
case 2:
wallpaper_path = WallpaperEngine::irrlicht::device->getFileSystem ()->getAbsolutePath (path.c_str ());
wallpaper_path = WallpaperEngine::Irrlicht::device->getFileSystem ()->getAbsolutePath (path.c_str ());
project_path = wallpaper_path + "project.json";
// set our working directory
WallpaperEngine::irrlicht::device->getFileSystem ()->changeWorkingDirectoryTo (wallpaper_path);
WallpaperEngine::Irrlicht::device->getFileSystem ()->changeWorkingDirectoryTo (wallpaper_path);
break;
default:
@ -190,7 +190,7 @@ int main (int argc, char* argv[])
if (SDL_Init (SDL_INIT_AUDIO) < 0 || mixer_flags != Mix_Init (mixer_flags))
{
WallpaperEngine::irrlicht::device->getLogger ()->log ("Cannot initialize SDL audio system", irr::ELL_ERROR);
WallpaperEngine::Irrlicht::device->getLogger ()->log ("Cannot initialize SDL audio system", irr::ELL_ERROR);
return -1;
}
@ -206,7 +206,7 @@ int main (int argc, char* argv[])
}
else
{
WallpaperEngine::irrlicht::device->getLogger ()->log ("Non-orthogonal cameras not supported yet!!", irr::ELL_ERROR);
WallpaperEngine::Irrlicht::device->getLogger ()->log ("Non-orthogonal cameras not supported yet!!", irr::ELL_ERROR);
return -2;
}
@ -217,11 +217,11 @@ int main (int argc, char* argv[])
int32_t minimumTime = 1000 / 90;
int32_t currentTime = 0;
while (WallpaperEngine::irrlicht::device->run () && WallpaperEngine::irrlicht::driver)
while (WallpaperEngine::Irrlicht::device->run () && WallpaperEngine::Irrlicht::driver)
{
// if (device->isWindowActive ())
{
currentTime = WallpaperEngine::irrlicht::device->getTimer ()->getTime ();
currentTime = WallpaperEngine::Irrlicht::device->getTimer ()->getTime ();
g_Time = currentTime / 1000.0f;
if (currentTime - lastTime > minimumTime)
@ -231,7 +231,7 @@ int main (int argc, char* argv[])
}
else
{
WallpaperEngine::irrlicht::device->sleep (1, false);
WallpaperEngine::Irrlicht::device->sleep (1, false);
}
}
}