mirror of
https://github.com/Almamu/linux-wallpaperengine.git
synced 2025-09-14 13:56:48 +08:00
~ Removed static variables in namespace WallpaperEngine::Irrlicht and moved to a context approach
This includes changes to old code to be compatible, the externs won't be used once the renderer is rewritten and the old code removed Signed-off-by: Alexis Maiquez <almamu@almamu.com>
This commit is contained in:
parent
1c50095ead
commit
b8b3c2899d
@ -48,14 +48,14 @@ add_executable(
|
|||||||
src/WallpaperEngine/video/material.h
|
src/WallpaperEngine/video/material.h
|
||||||
src/WallpaperEngine/texture.cpp
|
src/WallpaperEngine/texture.cpp
|
||||||
src/WallpaperEngine/texture.h
|
src/WallpaperEngine/texture.h
|
||||||
|
src/WallpaperEngine/Irrlicht/CContext.h
|
||||||
|
src/WallpaperEngine/Irrlicht/CContext.cpp
|
||||||
src/WallpaperEngine/Irrlicht/CImageLoaderTEX.h
|
src/WallpaperEngine/Irrlicht/CImageLoaderTEX.h
|
||||||
src/WallpaperEngine/Irrlicht/CImageLoaderTEX.cpp
|
src/WallpaperEngine/Irrlicht/CImageLoaderTEX.cpp
|
||||||
src/WallpaperEngine/Irrlicht/CPkgReader.h
|
src/WallpaperEngine/Irrlicht/CPkgReader.h
|
||||||
src/WallpaperEngine/Irrlicht/CPkgReader.cpp
|
src/WallpaperEngine/Irrlicht/CPkgReader.cpp
|
||||||
src/WallpaperEngine/Irrlicht/CFileList.h
|
src/WallpaperEngine/Irrlicht/CFileList.h
|
||||||
src/WallpaperEngine/Irrlicht/CFileList.cpp
|
src/WallpaperEngine/Irrlicht/CFileList.cpp
|
||||||
src/WallpaperEngine/Irrlicht/Irrlicht.cpp
|
|
||||||
src/WallpaperEngine/Irrlicht/Irrlicht.h
|
|
||||||
src/WallpaperEngine/sound.cpp
|
src/WallpaperEngine/sound.cpp
|
||||||
src/WallpaperEngine/sound.h
|
src/WallpaperEngine/sound.h
|
||||||
|
|
||||||
|
66
main.cpp
66
main.cpp
@ -8,20 +8,26 @@
|
|||||||
#include <SDL_mixer.h>
|
#include <SDL_mixer.h>
|
||||||
#include <SDL.h>
|
#include <SDL.h>
|
||||||
|
|
||||||
|
#include <X11/Xlib.h>
|
||||||
|
|
||||||
#include "WallpaperEngine/Render/Shaders/Compiler.h"
|
#include "WallpaperEngine/Render/Shaders/Compiler.h"
|
||||||
#include "WallpaperEngine/project.h"
|
#include "WallpaperEngine/project.h"
|
||||||
#include "WallpaperEngine/Irrlicht/Irrlicht.h"
|
|
||||||
#include "WallpaperEngine/Irrlicht/CImageLoaderTEX.h"
|
#include "WallpaperEngine/Irrlicht/CImageLoaderTEX.h"
|
||||||
|
|
||||||
#include "WallpaperEngine/Core/CProject.h"
|
#include "WallpaperEngine/Core/CProject.h"
|
||||||
|
#include "WallpaperEngine/Irrlicht/CContext.h"
|
||||||
|
|
||||||
int WinID = 0;
|
int WinID = 0;
|
||||||
irr::SIrrlichtCreationParameters _irr_params;
|
irr::SIrrlichtCreationParameters _irr_params;
|
||||||
|
|
||||||
irr::f32 g_Time = 0;
|
irr::f32 g_Time = 0;
|
||||||
|
|
||||||
|
WallpaperEngine::Irrlicht::CContext* IrrlichtContext;
|
||||||
|
|
||||||
int init_irrlicht()
|
int init_irrlicht()
|
||||||
{
|
{
|
||||||
|
IrrlichtContext = new WallpaperEngine::Irrlicht::CContext ();
|
||||||
|
|
||||||
// prepare basic configuration for irrlicht
|
// prepare basic configuration for irrlicht
|
||||||
_irr_params.AntiAlias = 8;
|
_irr_params.AntiAlias = 8;
|
||||||
_irr_params.Bits = 16;
|
_irr_params.Bits = 16;
|
||||||
@ -38,31 +44,34 @@ int init_irrlicht()
|
|||||||
_irr_params.WithAlphaChannel = false;
|
_irr_params.WithAlphaChannel = false;
|
||||||
_irr_params.ZBufferBits = 24;
|
_irr_params.ZBufferBits = 24;
|
||||||
_irr_params.LoggingLevel = irr::ELL_DEBUG;
|
_irr_params.LoggingLevel = irr::ELL_DEBUG;
|
||||||
_irr_params.WindowId = reinterpret_cast<void*> (WinID);
|
|
||||||
|
|
||||||
WallpaperEngine::Irrlicht::device = irr::createDeviceEx (_irr_params);
|
Display* display = XOpenDisplay (NULL);
|
||||||
|
int screen = XDefaultScreen (display);
|
||||||
|
|
||||||
if (WallpaperEngine::Irrlicht::device == nullptr)
|
_irr_params.WindowId = reinterpret_cast<void*> (XRootWindow (display, screen));
|
||||||
|
|
||||||
|
IrrlichtContext->setDevice (irr::createDeviceEx (_irr_params));
|
||||||
|
|
||||||
|
if (IrrlichtContext->getDevice () == nullptr)
|
||||||
{
|
{
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
WallpaperEngine::Irrlicht::device->setWindowCaption (L"Test game");
|
IrrlichtContext->getDevice ()->setWindowCaption (L"Test game");
|
||||||
WallpaperEngine::Irrlicht::driver = WallpaperEngine::Irrlicht::device->getVideoDriver();
|
|
||||||
|
|
||||||
// check for ps and vs support
|
// check for ps and vs support
|
||||||
if (
|
if (
|
||||||
WallpaperEngine::Irrlicht::driver->queryFeature (irr::video::EVDF_PIXEL_SHADER_1_1) == false &&
|
IrrlichtContext->getDevice ()->getVideoDriver()->queryFeature (irr::video::EVDF_PIXEL_SHADER_1_1) == false &&
|
||||||
WallpaperEngine::Irrlicht::driver->queryFeature (irr::video::EVDF_ARB_FRAGMENT_PROGRAM_1) == false)
|
IrrlichtContext->getDevice ()->getVideoDriver()->queryFeature (irr::video::EVDF_ARB_FRAGMENT_PROGRAM_1) == false)
|
||||||
{
|
{
|
||||||
WallpaperEngine::Irrlicht::device->getLogger ()->log ("WARNING: Pixel shaders disabled because of missing driver/hardware support");
|
IrrlichtContext->getDevice ()->getLogger ()->log ("WARNING: Pixel shaders disabled because of missing driver/hardware support");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (
|
if (
|
||||||
WallpaperEngine::Irrlicht::driver->queryFeature (irr::video::EVDF_VERTEX_SHADER_1_1) == false &&
|
IrrlichtContext->getDevice ()->getVideoDriver()->queryFeature (irr::video::EVDF_VERTEX_SHADER_1_1) == false &&
|
||||||
WallpaperEngine::Irrlicht::driver->queryFeature (irr::video::EVDF_ARB_VERTEX_PROGRAM_1) == false)
|
IrrlichtContext->getDevice ()->getVideoDriver()->queryFeature (irr::video::EVDF_ARB_VERTEX_PROGRAM_1) == false)
|
||||||
{
|
{
|
||||||
WallpaperEngine::Irrlicht::device->getLogger ()->log ("WARNING: Vertex shaders disabled because of missing driver/hardware support");
|
IrrlichtContext->getDevice ()->getLogger ()->log ("WARNING: Vertex shaders disabled because of missing driver/hardware support");
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@ -71,11 +80,15 @@ int init_irrlicht()
|
|||||||
void preconfigure_wallpaper_engine ()
|
void preconfigure_wallpaper_engine ()
|
||||||
{
|
{
|
||||||
// load the assets from wallpaper engine
|
// load the assets from wallpaper engine
|
||||||
WallpaperEngine::Irrlicht::device->getFileSystem ()->addFileArchive ("assets.zip", true, false);
|
IrrlichtContext->getDevice ()->getFileSystem ()->addFileArchive ("assets.zip", true, false);
|
||||||
|
|
||||||
// register custom loaders
|
// register custom loaders
|
||||||
WallpaperEngine::Irrlicht::driver->addExternalImageLoader (new WallpaperEngine::Irrlicht::CImageLoaderTex ());
|
IrrlichtContext->getDevice ()->getVideoDriver()->addExternalImageLoader (
|
||||||
WallpaperEngine::Irrlicht::device->getFileSystem ()->addArchiveLoader (new WallpaperEngine::Irrlicht::CArchiveLoaderPkg (WallpaperEngine::Irrlicht::device->getFileSystem ()));
|
new WallpaperEngine::Irrlicht::CImageLoaderTex (IrrlichtContext)
|
||||||
|
);
|
||||||
|
IrrlichtContext->getDevice ()->getFileSystem ()->addArchiveLoader (
|
||||||
|
new WallpaperEngine::Irrlicht::CArchiveLoaderPkg (IrrlichtContext)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
void print_help (const char* route)
|
void print_help (const char* route)
|
||||||
@ -158,7 +171,7 @@ int main (int argc, char* argv[])
|
|||||||
|
|
||||||
std::cout << "Initializing irrlicht to WindowID " << WinID << std::endl;
|
std::cout << "Initializing irrlicht to WindowID " << WinID << std::endl;
|
||||||
|
|
||||||
if (init_irrlicht())
|
if (init_irrlicht ())
|
||||||
{
|
{
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@ -178,21 +191,21 @@ int main (int argc, char* argv[])
|
|||||||
// pkg mode
|
// pkg mode
|
||||||
case 1:
|
case 1:
|
||||||
path = stringPathFixes(path);
|
path = stringPathFixes(path);
|
||||||
wallpaper_path = WallpaperEngine::Irrlicht::device->getFileSystem ()->getAbsolutePath (path.c_str ());
|
wallpaper_path = IrrlichtContext->getDevice ()->getFileSystem ()->getAbsolutePath (path.c_str ());
|
||||||
project_path = wallpaper_path + "project.json";
|
project_path = wallpaper_path + "project.json";
|
||||||
scene_path = wallpaper_path + "scene.pkg";
|
scene_path = wallpaper_path + "scene.pkg";
|
||||||
|
|
||||||
WallpaperEngine::Irrlicht::device->getFileSystem ()->addFileArchive (scene_path, true, false); // add the pkg file to the lookup list
|
IrrlichtContext->getDevice ()->getFileSystem ()->addFileArchive (scene_path, true, false); // add the pkg file to the lookup list
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// folder mode
|
// folder mode
|
||||||
case 2:
|
case 2:
|
||||||
path = stringPathFixes(path);
|
path = stringPathFixes(path);
|
||||||
wallpaper_path = WallpaperEngine::Irrlicht::device->getFileSystem ()->getAbsolutePath (path.c_str ());
|
wallpaper_path = IrrlichtContext->getDevice ()->getFileSystem ()->getAbsolutePath (path.c_str ());
|
||||||
project_path = wallpaper_path + "project.json";
|
project_path = wallpaper_path + "project.json";
|
||||||
|
|
||||||
// set our working directory
|
// set our working directory
|
||||||
WallpaperEngine::Irrlicht::device->getFileSystem ()->changeWorkingDirectoryTo (wallpaper_path);
|
IrrlichtContext->getDevice ()->getFileSystem ()->changeWorkingDirectoryTo (wallpaper_path);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@ -205,7 +218,7 @@ int main (int argc, char* argv[])
|
|||||||
|
|
||||||
if (SDL_Init (SDL_INIT_AUDIO) < 0 || mixer_flags != Mix_Init (mixer_flags))
|
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);
|
IrrlichtContext->getDevice ()->getLogger ()->log ("Cannot initialize SDL audio system", irr::ELL_ERROR);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -221,7 +234,10 @@ int main (int argc, char* argv[])
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
WallpaperEngine::Irrlicht::device->getLogger ()->log ("Non-orthogonal cameras not supported yet!!", irr::ELL_ERROR);
|
IrrlichtContext->getDevice ()->getLogger ()->log (
|
||||||
|
"Non-orthogonal cameras not supported yet!!", irr::ELL_ERROR
|
||||||
|
);
|
||||||
|
|
||||||
return -2;
|
return -2;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -232,11 +248,11 @@ int main (int argc, char* argv[])
|
|||||||
int32_t minimumTime = 1000 / 90;
|
int32_t minimumTime = 1000 / 90;
|
||||||
int32_t currentTime = 0;
|
int32_t currentTime = 0;
|
||||||
|
|
||||||
while (WallpaperEngine::Irrlicht::device->run () && WallpaperEngine::Irrlicht::driver)
|
while (IrrlichtContext->getDevice ()->run () && IrrlichtContext && IrrlichtContext->getDevice ())
|
||||||
{
|
{
|
||||||
// if (device->isWindowActive ())
|
// if (device->isWindowActive ())
|
||||||
{
|
{
|
||||||
currentTime = WallpaperEngine::Irrlicht::device->getTimer ()->getTime ();
|
currentTime = IrrlichtContext->getDevice ()->getTimer ()->getTime ();
|
||||||
g_Time = currentTime / 1000.0f;
|
g_Time = currentTime / 1000.0f;
|
||||||
|
|
||||||
if (currentTime - lastTime > minimumTime)
|
if (currentTime - lastTime > minimumTime)
|
||||||
@ -246,7 +262,7 @@ int main (int argc, char* argv[])
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
WallpaperEngine::Irrlicht::device->sleep (1, false);
|
IrrlichtContext->getDevice ()->sleep (1, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,13 +2,15 @@
|
|||||||
#include "FileSystem.h"
|
#include "FileSystem.h"
|
||||||
|
|
||||||
// engine includes
|
// engine includes
|
||||||
#include "WallpaperEngine/Irrlicht/Irrlicht.h"
|
#include "WallpaperEngine/Irrlicht/CContext.h"
|
||||||
|
|
||||||
|
extern WallpaperEngine::Irrlicht::CContext* IrrlichtContext;
|
||||||
|
|
||||||
namespace WallpaperEngine::FileSystem
|
namespace WallpaperEngine::FileSystem
|
||||||
{
|
{
|
||||||
std::string loadFullFile (irr::io::path file)
|
std::string loadFullFile (irr::io::path file)
|
||||||
{
|
{
|
||||||
irr::io::IReadFile* reader = WallpaperEngine::Irrlicht::device->getFileSystem ()->createAndOpenFile (file);
|
irr::io::IReadFile* reader = IrrlichtContext->getDevice ()->getFileSystem ()->createAndOpenFile (file);
|
||||||
|
|
||||||
if (reader == NULL)
|
if (reader == NULL)
|
||||||
throw std::runtime_error ("Cannot open file " + std::string (file.c_str ()) + " for reading");
|
throw std::runtime_error ("Cannot open file " + std::string (file.c_str ()) + " for reading");
|
||||||
|
14
src/WallpaperEngine/Irrlicht/CContext.cpp
Normal file
14
src/WallpaperEngine/Irrlicht/CContext.cpp
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
#include "CContext.h"
|
||||||
|
|
||||||
|
namespace WallpaperEngine::Irrlicht
|
||||||
|
{
|
||||||
|
void CContext::setDevice (irr::IrrlichtDevice* device)
|
||||||
|
{
|
||||||
|
this->m_device = device;
|
||||||
|
}
|
||||||
|
|
||||||
|
irr::IrrlichtDevice* CContext::getDevice ()
|
||||||
|
{
|
||||||
|
return this->m_device;
|
||||||
|
}
|
||||||
|
};
|
16
src/WallpaperEngine/Irrlicht/CContext.h
Normal file
16
src/WallpaperEngine/Irrlicht/CContext.h
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <irrlicht/irrlicht.h>
|
||||||
|
|
||||||
|
namespace WallpaperEngine::Irrlicht
|
||||||
|
{
|
||||||
|
class CContext
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
void setDevice (irr::IrrlichtDevice* device);
|
||||||
|
|
||||||
|
irr::IrrlichtDevice* getDevice ();
|
||||||
|
private:
|
||||||
|
irr::IrrlichtDevice* m_device;
|
||||||
|
};
|
||||||
|
};
|
@ -2,117 +2,106 @@
|
|||||||
|
|
||||||
#include "CFileList.h"
|
#include "CFileList.h"
|
||||||
|
|
||||||
using namespace WallpaperEngine::Irrlicht;
|
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('\\', '/');
|
static const irr::io::path emptyFileListEntry;
|
||||||
}
|
|
||||||
|
|
||||||
CFileList::~CFileList()
|
CFileList::CFileList (const irr::io::path& path, bool ignoreCase, bool ignorePaths) :
|
||||||
{
|
m_ignorePaths (ignorePaths),
|
||||||
Files.clear();
|
m_ignoreCase (ignoreCase),
|
||||||
}
|
m_path(path)
|
||||||
|
{
|
||||||
|
this->m_path.replace ('\\', '/');
|
||||||
|
}
|
||||||
|
|
||||||
u32 CFileList::getFileCount() const
|
CFileList::~CFileList ()
|
||||||
{
|
{
|
||||||
return Files.size();
|
this->m_files.clear ();
|
||||||
}
|
}
|
||||||
|
|
||||||
void CFileList::sort()
|
irr::u32 CFileList::getFileCount () const
|
||||||
{
|
{
|
||||||
Files.sort();
|
return this->m_files.size ();
|
||||||
}
|
}
|
||||||
|
|
||||||
const io::path& CFileList::getFileName(u32 index) const
|
void CFileList::sort ()
|
||||||
{
|
{
|
||||||
if (index >= Files.size())
|
this->m_files.sort ();
|
||||||
return emptyFileListEntry;
|
}
|
||||||
|
|
||||||
return Files[index].Name;
|
const irr::io::path& CFileList::getFileName (irr::u32 index) const
|
||||||
}
|
{
|
||||||
|
return (index < this->m_files.size ()) ? this->m_files [index].Name : emptyFileListEntry;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//! Gets the full name of a file in the list, path included, based on an index.
|
//! Gets the full name of a file in the list, path included, based on an index.
|
||||||
const io::path& CFileList::getFullFileName(u32 index) const
|
const irr::io::path& CFileList::getFullFileName (irr::u32 index) const
|
||||||
{
|
{
|
||||||
if (index >= Files.size())
|
return (index < this->m_files.size ()) ? this->m_files [index].FullName : emptyFileListEntry;
|
||||||
return emptyFileListEntry;
|
}
|
||||||
|
|
||||||
return Files[index].FullName;
|
|
||||||
}
|
|
||||||
|
|
||||||
//! adds a file or folder
|
//! adds a file or folder
|
||||||
u32 CFileList::addItem(const io::path& fullPath, u32 offset, u32 size, bool isDirectory, u32 id)
|
irr::u32 CFileList::addItem (const irr::io::path& fullPath, irr::u32 offset, irr::u32 size, bool isDirectory, irr::u32 id)
|
||||||
{
|
{
|
||||||
SFileListEntry entry;
|
SFileListEntry entry;
|
||||||
entry.ID = id ? id : Files.size();
|
entry.ID = id ? id : this->m_files.size ();
|
||||||
entry.Offset = offset;
|
entry.Offset = offset;
|
||||||
entry.Size = size;
|
entry.Size = size;
|
||||||
entry.Name = fullPath;
|
entry.Name = fullPath;
|
||||||
entry.Name.replace('\\', '/');
|
entry.Name.replace ('\\', '/');
|
||||||
entry.IsDirectory = isDirectory;
|
entry.IsDirectory = isDirectory;
|
||||||
|
|
||||||
// remove trailing slash
|
// remove trailing slash
|
||||||
if (entry.Name.lastChar() == '/')
|
if (entry.Name.lastChar () == '/')
|
||||||
{
|
{
|
||||||
entry.IsDirectory = true;
|
entry.IsDirectory = true;
|
||||||
entry.Name[entry.Name.size()-1] = 0;
|
entry.Name [entry.Name.size ()-1] = 0;
|
||||||
entry.Name.validate();
|
entry.Name.validate ();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (IgnoreCase)
|
if (this->m_ignoreCase)
|
||||||
entry.Name.make_lower();
|
entry.Name.make_lower ();
|
||||||
|
|
||||||
entry.FullName = entry.Name;
|
entry.FullName = entry.Name;
|
||||||
|
|
||||||
core::deletePathFromFilename(entry.Name);
|
irr::core::deletePathFromFilename (entry.Name);
|
||||||
|
|
||||||
if (IgnorePaths)
|
if (this->m_ignorePaths)
|
||||||
entry.FullName = entry.Name;
|
entry.FullName = entry.Name;
|
||||||
|
|
||||||
//os::Printer::log(Path.c_str(), entry.FullName);
|
this->m_files.push_back (entry);
|
||||||
|
|
||||||
Files.push_back(entry);
|
return this->m_files.size () - 1;
|
||||||
|
}
|
||||||
return Files.size() - 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
//! Returns the ID of a file in the file list, based on an index.
|
//! Returns the ID of a file in the file list, based on an index.
|
||||||
u32 CFileList::getID(u32 index) const
|
irr::u32 CFileList::getID (irr::u32 index) const
|
||||||
{
|
{
|
||||||
return index < Files.size() ? Files[index].ID : 0;
|
return (index < this->m_files.size ()) ? this->m_files [index].ID : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CFileList::isDirectory(u32 index) const
|
bool CFileList::isDirectory (irr::u32 index) const
|
||||||
{
|
{
|
||||||
bool ret = false;
|
return (index < this->m_files.size ()) ? this->m_files [index].IsDirectory : false;
|
||||||
if (index < Files.size())
|
}
|
||||||
ret = Files[index].IsDirectory;
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
//! Returns the size of a file
|
//! Returns the size of a file
|
||||||
u32 CFileList::getFileSize(u32 index) const
|
irr::u32 CFileList::getFileSize (irr::u32 index) const
|
||||||
{
|
{
|
||||||
return index < Files.size() ? Files[index].Size : 0;
|
return (index < this->m_files.size ()) ? this->m_files [index].Size : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
//! Returns the size of a file
|
//! Returns the size of a file
|
||||||
u32 CFileList::getFileOffset(u32 index) const
|
irr::u32 CFileList::getFileOffset (irr::u32 index) const
|
||||||
{
|
{
|
||||||
return index < Files.size() ? Files[index].Offset : 0;
|
return (index < this->m_files.size ()) ? this->m_files [index].Offset : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//! Searches for a file or folder within the list, returns the index
|
//! Searches for a file or folder within the list, returns the index
|
||||||
s32 CFileList::findFile(const io::path& filename, bool isDirectory = false) const
|
irr::s32 CFileList::findFile (const irr::io::path& filename, bool isDirectory = false) const
|
||||||
{
|
{
|
||||||
SFileListEntry entry;
|
SFileListEntry entry;
|
||||||
// we only need FullName to be set for the search
|
// we only need FullName to be set for the search
|
||||||
entry.FullName = filename;
|
entry.FullName = filename;
|
||||||
@ -122,25 +111,26 @@ s32 CFileList::findFile(const io::path& filename, bool isDirectory = false) cons
|
|||||||
entry.FullName.replace('\\', '/');
|
entry.FullName.replace('\\', '/');
|
||||||
|
|
||||||
// remove trailing slash
|
// remove trailing slash
|
||||||
if (entry.FullName.lastChar() == '/')
|
if (entry.FullName.lastChar () == '/')
|
||||||
{
|
{
|
||||||
entry.IsDirectory = true;
|
entry.IsDirectory = true;
|
||||||
entry.FullName[entry.FullName.size()-1] = 0;
|
entry.FullName [entry.FullName.size ()-1] = 0;
|
||||||
entry.FullName.validate();
|
entry.FullName.validate ();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (IgnoreCase)
|
if (this->m_ignoreCase)
|
||||||
entry.FullName.make_lower();
|
entry.FullName.make_lower ();
|
||||||
|
|
||||||
if (IgnorePaths)
|
if (this->m_ignorePaths)
|
||||||
core::deletePathFromFilename(entry.FullName);
|
irr::core::deletePathFromFilename (entry.FullName);
|
||||||
|
|
||||||
return Files.binary_search(entry);
|
return this->m_files.binary_search (entry);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//! Returns the base path of the file list
|
//! Returns the base path of the file list
|
||||||
const io::path& CFileList::getPath() const
|
const irr::io::path& CFileList::getPath () const
|
||||||
{
|
{
|
||||||
return Path;
|
return m_path;
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
@ -2,8 +2,6 @@
|
|||||||
|
|
||||||
#include <irrlicht/irrlicht.h>
|
#include <irrlicht/irrlicht.h>
|
||||||
|
|
||||||
using namespace irr;
|
|
||||||
|
|
||||||
namespace WallpaperEngine::Irrlicht
|
namespace WallpaperEngine::Irrlicht
|
||||||
{
|
{
|
||||||
//! An entry in a list of files, can be a folder or a file.
|
//! An entry in a list of files, can be a folder or a file.
|
||||||
@ -12,49 +10,49 @@ namespace WallpaperEngine::Irrlicht
|
|||||||
//! The name of the file
|
//! The name of the file
|
||||||
/** If this is a file or folder in the virtual filesystem and the archive
|
/** 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. */
|
was created with the ignoreCase flag then the file name will be lower case. */
|
||||||
io::path Name;
|
irr::io::path Name;
|
||||||
|
|
||||||
//! The name of the file including the path
|
//! The name of the file including the path
|
||||||
/** If this is a file or folder in the virtual filesystem and the archive was
|
/** 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. */
|
created with the ignoreDirs flag then it will be the same as Name. */
|
||||||
io::path FullName;
|
irr::io::path FullName;
|
||||||
|
|
||||||
//! The size of the file in bytes
|
//! The size of the file in bytes
|
||||||
u32 Size;
|
irr::u32 Size;
|
||||||
|
|
||||||
//! The ID of the file in an archive
|
//! The ID of the file in an archive
|
||||||
/** This is used to link the FileList entry to extra info held about this
|
/** 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. */
|
file in an archive, which can hold things like data offset and CRC. */
|
||||||
u32 ID;
|
irr::u32 ID;
|
||||||
|
|
||||||
//! FileOffset inside an archive
|
//! FileOffset inside an archive
|
||||||
u32 Offset;
|
irr::u32 Offset;
|
||||||
|
|
||||||
//! True if this is a folder, false if not.
|
//! True if this is a folder, false if not.
|
||||||
bool IsDirectory;
|
bool IsDirectory;
|
||||||
|
|
||||||
//! The == operator is provided so that CFileList can slowly search the list!
|
//! The == operator is provided so that CFileList can slowly search the list!
|
||||||
bool operator ==(const struct SFileListEntry& other) const
|
bool operator == (const struct SFileListEntry& other) const
|
||||||
{
|
{
|
||||||
if (IsDirectory != other.IsDirectory)
|
if (IsDirectory != other.IsDirectory)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
return FullName.equals_ignore_case(other.FullName);
|
return FullName.equals_ignore_case (other.FullName);
|
||||||
}
|
}
|
||||||
|
|
||||||
//! The < operator is provided so that CFileList can sort and quickly search the list.
|
//! The < operator is provided so that CFileList can sort and quickly search the list.
|
||||||
bool operator <(const struct SFileListEntry& other) const
|
bool operator < (const struct SFileListEntry& other) const
|
||||||
{
|
{
|
||||||
if (IsDirectory != other.IsDirectory)
|
if (IsDirectory != other.IsDirectory)
|
||||||
return IsDirectory;
|
return IsDirectory;
|
||||||
|
|
||||||
return FullName.lower_ignore_case(other.FullName);
|
return FullName.lower_ignore_case (other.FullName);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
//! Implementation of a file list
|
//! Implementation of a file list
|
||||||
class CFileList : public io::IFileList
|
class CFileList : public irr::io::IFileList
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
@ -62,10 +60,10 @@ namespace WallpaperEngine::Irrlicht
|
|||||||
|
|
||||||
//! Constructor
|
//! Constructor
|
||||||
/** \param path The path of this file archive */
|
/** \param path The path of this file archive */
|
||||||
CFileList(const io::path& path, bool ignoreCase, bool ignorePaths);
|
CFileList (const irr::io::path& path, bool ignoreCase, bool ignorePaths);
|
||||||
|
|
||||||
//! Destructor
|
//! Destructor
|
||||||
virtual ~CFileList();
|
virtual ~CFileList ();
|
||||||
|
|
||||||
//! Add as a file or folder to the list
|
//! 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 fullPath The file name including path, up to the root of the file list.
|
||||||
@ -73,51 +71,51 @@ namespace WallpaperEngine::Irrlicht
|
|||||||
\param offset The offset where the file is stored in an archive
|
\param offset The offset where the file is stored in an archive
|
||||||
\param size The size of the file in bytes.
|
\param size The size of the file in bytes.
|
||||||
\param id The ID of the file in the archive which owns it */
|
\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);
|
virtual irr::u32 addItem (const irr::io::path& fullPath, irr::u32 offset, irr::u32 size, bool isDirectory, irr::u32 id=0);
|
||||||
|
|
||||||
//! Sorts the file list. You should call this after adding any items to the file list
|
//! Sorts the file list. You should call this after adding any items to the file list
|
||||||
virtual void sort();
|
virtual void sort ();
|
||||||
|
|
||||||
//! Returns the amount of files in the filelist.
|
//! Returns the amount of files in the filelist.
|
||||||
virtual u32 getFileCount() const;
|
virtual irr::u32 getFileCount () const;
|
||||||
|
|
||||||
//! Gets the name of a file in the list, based on an index.
|
//! Gets the name of a file in the list, based on an index.
|
||||||
virtual const io::path& getFileName(u32 index) const;
|
virtual const irr::io::path& getFileName (irr::u32 index) const;
|
||||||
|
|
||||||
//! Gets the full name of a file in the list, path included, based on an index.
|
//! Gets the full name of a file in the list, path included, based on an index.
|
||||||
virtual const io::path& getFullFileName(u32 index) const;
|
virtual const irr::io::path& getFullFileName (irr::u32 index) const;
|
||||||
|
|
||||||
//! Returns the ID of a file in the file list, based on an index.
|
//! Returns the ID of a file in the file list, based on an index.
|
||||||
virtual u32 getID(u32 index) const;
|
virtual irr::u32 getID (irr::u32 index) const;
|
||||||
|
|
||||||
//! Returns true if the file is a directory
|
//! Returns true if the file is a directory
|
||||||
virtual bool isDirectory(u32 index) const;
|
virtual bool isDirectory (irr::u32 index) const;
|
||||||
|
|
||||||
//! Returns the size of a file
|
//! Returns the size of a file
|
||||||
virtual u32 getFileSize(u32 index) const;
|
virtual irr::u32 getFileSize (irr::u32 index) const;
|
||||||
|
|
||||||
//! Returns the offest of a file
|
//! Returns the offest of a file
|
||||||
virtual u32 getFileOffset(u32 index) const;
|
virtual irr::u32 getFileOffset (irr::u32 index) const;
|
||||||
|
|
||||||
//! Searches for a file or folder within the list, returns the index
|
//! Searches for a file or folder within the list, returns the index
|
||||||
virtual s32 findFile(const io::path& filename, bool isFolder) const;
|
virtual irr::s32 findFile (const irr::io::path& filename, bool isFolder) const;
|
||||||
|
|
||||||
//! Returns the base path of the file list
|
//! Returns the base path of the file list
|
||||||
virtual const io::path& getPath() const;
|
virtual const irr::io::path& getPath () const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
//! Ignore paths when adding or searching for files
|
//! Ignore paths when adding or searching for files
|
||||||
bool IgnorePaths;
|
bool m_ignorePaths;
|
||||||
|
|
||||||
//! Ignore case when adding or searching for files
|
//! Ignore case when adding or searching for files
|
||||||
bool IgnoreCase;
|
bool m_ignoreCase;
|
||||||
|
|
||||||
//! Path to the file list
|
//! Path to the file list
|
||||||
io::path Path;
|
irr::io::path m_path;
|
||||||
|
|
||||||
//! List of files
|
//! List of files
|
||||||
core::array<SFileListEntry> Files;
|
irr::core::array<SFileListEntry> m_files;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2,270 +2,340 @@
|
|||||||
|
|
||||||
#include <irrlicht/irrlicht.h>
|
#include <irrlicht/irrlicht.h>
|
||||||
#include <lz4.h>
|
#include <lz4.h>
|
||||||
#include <WallpaperEngine/Irrlicht/Irrlicht.h>
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <stdexcept>
|
||||||
|
|
||||||
using namespace irr::video;
|
|
||||||
using namespace WallpaperEngine::Irrlicht;
|
using namespace WallpaperEngine::Irrlicht;
|
||||||
|
|
||||||
//! returns true if the file maybe is able to be loaded by this class
|
namespace WallpaperEngine::Irrlicht
|
||||||
//! based on the file extension (e.g. ".tga")
|
|
||||||
bool CImageLoaderTex::isALoadableFileExtension (const io::path &filename) const
|
|
||||||
{
|
{
|
||||||
return core::hasFileExtension (filename, "tex");
|
CImageLoaderTex::TextureMipmap::TextureMipmap ()
|
||||||
}
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
CImageLoaderTex::TextureMipmap::~TextureMipmap ()
|
||||||
|
{
|
||||||
|
if (this->compression == 1)
|
||||||
|
delete this->compressedData;
|
||||||
|
|
||||||
|
delete this->uncompressedData;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CImageLoaderTex::TextureMipmap::decompressData ()
|
||||||
|
{
|
||||||
|
if (this->compression == 1)
|
||||||
|
{
|
||||||
|
this->uncompressedData = new char [this->uncompressedSize];
|
||||||
|
|
||||||
|
int result = LZ4_decompress_safe (
|
||||||
|
this->compressedData, this->uncompressedData,
|
||||||
|
this->compressedSize, this->uncompressedSize
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!result)
|
||||||
|
{
|
||||||
|
throw std::runtime_error ("Cannot decompress texture data");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
CImageLoaderTex::TextureContainer::TextureContainer () :
|
||||||
|
freeimageFormat (FREE_IMAGE_FORMAT::FIF_UNKNOWN)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
CImageLoaderTex::TextureContainer::~TextureContainer ()
|
||||||
|
{
|
||||||
|
std::vector <TextureMipmap*>::const_iterator cur = this->mipmaps.begin ();
|
||||||
|
std::vector <TextureMipmap*>::const_iterator end = this->mipmaps.end ();
|
||||||
|
|
||||||
|
for (; cur != end; cur ++)
|
||||||
|
{
|
||||||
|
delete *cur;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
CImageLoaderTex::CImageLoaderTex (CContext* context) :
|
||||||
|
m_context (context)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
//! 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 irr::io::path &filename) const
|
||||||
|
{
|
||||||
|
return irr::core::hasFileExtension (filename, "tex");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//! returns true if the file maybe is able to be loaded by this class
|
//! returns true if the file maybe is able to be loaded by this class
|
||||||
bool CImageLoaderTex::isALoadableFileFormat (io::IReadFile *file) const
|
bool CImageLoaderTex::isALoadableFileFormat (irr::io::IReadFile *file) const
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// load in the image data
|
|
||||||
IImage *CImageLoaderTex::loadImage (io::IReadFile *input) const
|
|
||||||
{
|
|
||||||
if (!input)
|
|
||||||
return nullptr;
|
|
||||||
|
|
||||||
video::IImage *image = nullptr;
|
|
||||||
|
|
||||||
|
CImageLoaderTex::TextureContainer* CImageLoaderTex::parseHeader (irr::io::IReadFile* input) const
|
||||||
|
{
|
||||||
char buffer [1024];
|
char buffer [1024];
|
||||||
|
|
||||||
if (input->read (buffer, 9) != 9)
|
if (input->read (buffer, 9) != 9 || memcmp (buffer, "TEXV0005", 9) != 0)
|
||||||
{
|
{
|
||||||
WallpaperEngine::Irrlicht::device->getLogger ()->log ("LOAD TEX: cannot read header\n", input->getFileName ().c_str (), irr::ELL_ERROR);
|
throw std::runtime_error ("unexpected container type");
|
||||||
return nullptr;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (memcmp (buffer, "TEXV0005", 9) != 0)
|
if (input->read (buffer, 9) != 9 || memcmp (buffer, "TEXI0001", 9) != 0)
|
||||||
{
|
{
|
||||||
WallpaperEngine::Irrlicht::device->getLogger ()->log ("LOAD TEX: not really a tex\n", input->getFileName ().c_str (), irr::ELL_ERROR);
|
throw std::runtime_error ("unexpected sub-container type");
|
||||||
return nullptr;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (input->read (buffer, 9) != 9)
|
TextureContainer* header = new TextureContainer;
|
||||||
{
|
|
||||||
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)
|
input->read (&header->format, 4);
|
||||||
{
|
|
||||||
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->seek (4, true); // ignore bytes
|
||||||
input->read (&texture_width, 4);
|
input->read (&header->textureWidth, 4);
|
||||||
input->read (&texture_height, 4);
|
input->read (&header->textureHeight, 4);
|
||||||
input->read (&width, 4);
|
input->read (&header->width, 4);
|
||||||
input->read (&height, 4);
|
input->read (&header->height, 4);
|
||||||
input->seek (4, true); // ignore bytes
|
input->seek (4, true); // ignore bytes
|
||||||
input->read (buffer, 9);
|
input->read (buffer, 9);
|
||||||
|
|
||||||
if (memcmp (buffer, "TEXB0003", 9) == 0)
|
if (memcmp (buffer, "TEXB0003", 9) == 0)
|
||||||
{
|
{
|
||||||
containerVersion = 3;
|
header->containerVersion = ContainerVersion::TEXB0003;
|
||||||
|
|
||||||
input->seek (4, true);
|
input->seek (4, true);
|
||||||
input->read (&imageFormat, 4);
|
input->read (&header->freeimageFormat, 4);
|
||||||
}
|
}
|
||||||
else if (memcmp (buffer, "TEXB0002", 9) == 0)
|
else if (memcmp (buffer, "TEXB0002", 9) == 0)
|
||||||
{
|
{
|
||||||
containerVersion = 2;
|
header->containerVersion = ContainerVersion::TEXB0002;
|
||||||
|
|
||||||
input->seek (4, true);
|
input->seek (4, true);
|
||||||
}
|
}
|
||||||
else if (memcmp (buffer, "TEXB0001", 9) == 0)
|
else if (memcmp (buffer, "TEXB0001", 9) == 0)
|
||||||
{
|
{
|
||||||
containerVersion = 1;
|
header->containerVersion = ContainerVersion::TEXB0001;
|
||||||
|
|
||||||
input->seek (4, true);
|
input->seek (4, true);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
WallpaperEngine::Irrlicht::device->getLogger ()->log ("LOAD TEX: Unknown container type\n", input->getFileName ().c_str (), irr::ELL_ERROR);
|
delete header;
|
||||||
return nullptr;
|
|
||||||
|
throw std::runtime_error ("Unknown container type");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (format == TextureFormat::A8)
|
if (header->format == TextureFormat::A8)
|
||||||
{
|
{
|
||||||
WallpaperEngine::Irrlicht::device->getLogger ()-> log ("LOAD TEX: A8 not supported\n", input->getFileName ().c_str (), irr::ELL_ERROR);
|
delete header;
|
||||||
return nullptr;
|
|
||||||
|
throw std::runtime_error ("A8 format not supported yet");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (format == TextureFormat::RA88)
|
if (header->format == TextureFormat::RA88)
|
||||||
{
|
{
|
||||||
WallpaperEngine::Irrlicht::device->getLogger ()->log ("LOAD TEX: RA88 not supported\n", input->getFileName ().c_str (), irr::ELL_ERROR);
|
delete header;
|
||||||
return nullptr;
|
|
||||||
|
throw std::runtime_error ("RA88 format not supported yet");
|
||||||
}
|
}
|
||||||
|
|
||||||
u32 mipmap_count = 0;
|
input->read (&header->mipmapCount, 4);
|
||||||
|
|
||||||
input->read (&mipmap_count, 4);
|
for (irr::u32 i = 0; i < header->mipmapCount; i ++)
|
||||||
|
|
||||||
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);
|
header->mipmaps.push_back (
|
||||||
input->read (&mipmap_uncompressed_size, 4);
|
this->parseMipmap (header, input)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
input->read (&mipmap_compressed_size, 4);
|
return header;
|
||||||
|
}
|
||||||
|
|
||||||
|
CImageLoaderTex::TextureMipmap* CImageLoaderTex::parseMipmap(TextureContainer* header, irr::io::IReadFile* input) const
|
||||||
|
{
|
||||||
|
TextureMipmap* mipmap = new TextureMipmap ();
|
||||||
|
|
||||||
|
input->read (&mipmap->width, 4);
|
||||||
|
input->read (&mipmap->height, 4);
|
||||||
|
|
||||||
|
if (header->containerVersion == ContainerVersion::TEXB0002 ||
|
||||||
|
header->containerVersion == ContainerVersion::TEXB0003)
|
||||||
|
{
|
||||||
|
input->read (&mipmap->compression, 4);
|
||||||
|
input->read (&mipmap->uncompressedSize, 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
input->read (&mipmap->compressedSize, 4);
|
||||||
|
|
||||||
// TODO: BETTER POSITION FOR THIS
|
// TODO: BETTER POSITION FOR THIS
|
||||||
if (mipmap_compression == 0)
|
if (mipmap->compression == 0)
|
||||||
{
|
{
|
||||||
// this might be better named as mipmap_bytes_size instead of compressed_size
|
// this might be better named as mipmap_bytes_size instead of compressed_size
|
||||||
// as in uncompressed files this variable actually holds the file length
|
// as in uncompressed files this variable actually holds the file length
|
||||||
mipmap_uncompressed_size = mipmap_compressed_size;
|
mipmap->uncompressedSize = mipmap->compressedSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
char *decompressedBuffer = new char [mipmap_uncompressed_size];
|
mipmap->uncompressedData = new char [mipmap->uncompressedSize];
|
||||||
|
|
||||||
if (mipmap_compression == 1)
|
if (mipmap->compression == 1)
|
||||||
{
|
{
|
||||||
char *compressedBuffer = new char [mipmap_compressed_size];
|
mipmap->compressedData = new char [mipmap->compressedSize];
|
||||||
|
|
||||||
input->read (compressedBuffer, mipmap_compressed_size);
|
input->read (mipmap->compressedData, mipmap->compressedSize);
|
||||||
|
|
||||||
int result = LZ4_decompress_safe (compressedBuffer, decompressedBuffer, mipmap_compressed_size, mipmap_uncompressed_size);
|
mipmap->decompressData ();
|
||||||
|
|
||||||
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
|
else
|
||||||
{
|
{
|
||||||
input->read (decompressedBuffer, mipmap_uncompressed_size);
|
input->read (mipmap->uncompressedData, mipmap->uncompressedSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (imageFormat == FREE_IMAGE_FORMAT::FIF_UNKNOWN)
|
return mipmap;
|
||||||
{
|
}
|
||||||
image = WallpaperEngine::Irrlicht::driver->createImage (ECF_A8R8G8B8, irr::core::dimension2d<u32> (width, height));
|
|
||||||
|
|
||||||
if (!image)
|
irr::video::IImage* CImageLoaderTex::parseFile (irr::io::IReadFile* input) const
|
||||||
{
|
{
|
||||||
delete [] decompressedBuffer;
|
irr::video::IImage *image = nullptr;
|
||||||
delete image;
|
TextureContainer* header = nullptr;
|
||||||
WallpaperEngine::Irrlicht::device->getLogger ()->log ("LOAD TEX: cannot create destination image\n", input->getFileName ().c_str (), irr::ELL_ERROR);
|
TextureMipmap* mipmap = nullptr;
|
||||||
|
|
||||||
|
if (input == nullptr)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
||||||
|
header = this->parseHeader (input);
|
||||||
|
mipmap = *header->mipmaps.begin ();
|
||||||
|
|
||||||
|
if (header->freeimageFormat == FREE_IMAGE_FORMAT::FIF_UNKNOWN)
|
||||||
|
{
|
||||||
|
image = this->m_context->getDevice ()->getVideoDriver ()->createImage (
|
||||||
|
irr::video::ECF_A8R8G8B8, irr::core::dimension2d<irr::u32> (header->width, header->height)
|
||||||
|
);
|
||||||
|
|
||||||
|
if (image == nullptr)
|
||||||
|
{
|
||||||
|
delete header;
|
||||||
|
|
||||||
|
throw std::runtime_error ("cannot create destination image");
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (format)
|
switch (header->format)
|
||||||
{
|
{
|
||||||
case TextureFormat::ARGB8888:
|
case TextureFormat::ARGB8888:
|
||||||
this->loadImageFromARGB8Data (image, decompressedBuffer, width, height, mipmap_width);
|
this->loadImageFromARGB8Data (
|
||||||
|
image, mipmap->uncompressedData, header->width, header->height, mipmap->width
|
||||||
|
);
|
||||||
break;
|
break;
|
||||||
case TextureFormat::DXT5:
|
case TextureFormat::DXT5:
|
||||||
this->loadImageFromDXT5 (image, decompressedBuffer, width, height, mipmap_width, mipmap_height);
|
this->loadImageFromDXT5 (
|
||||||
|
image, mipmap->uncompressedData, header->width, header->height, mipmap->width, mipmap->height
|
||||||
|
);
|
||||||
break;
|
break;
|
||||||
case TextureFormat::DXT1:
|
case TextureFormat::DXT1:
|
||||||
this->loadImageFromDXT1 (image, decompressedBuffer, width, height, mipmap_width, mipmap_height);
|
this->loadImageFromDXT1 (
|
||||||
|
image, mipmap->uncompressedData, header->width, header->height, mipmap->width, mipmap->height
|
||||||
|
);
|
||||||
break;
|
break;
|
||||||
case TextureFormat::DXT3:
|
case TextureFormat::DXT3:
|
||||||
WallpaperEngine::Irrlicht::device->getLogger ()->log ("LOAD TEX: DXT3 textures not supported yet\n", input->getFileName ().c_str (), irr::ELL_ERROR);
|
delete header;
|
||||||
delete [] decompressedBuffer;
|
|
||||||
delete image;
|
throw std::runtime_error ("DXT3 textures not supported yet");
|
||||||
return nullptr;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// copy the buffer to a new address
|
// generate a memory file for irrlicht to load the proper one as free image files
|
||||||
char* filebuffer = new char [mipmap_uncompressed_size];
|
// that are used by wallpaperengine are usually supported formats in irrlicht
|
||||||
|
// TODO: FIND A WAY TO CALL THE PROPER LOADER DIRECTLY INSTEAD OF GENERATING A FILE?
|
||||||
char tmpname [TMP_MAX];
|
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);
|
std::tmpnam (tmpname);
|
||||||
// store it in a std::string
|
|
||||||
std::string filename = tmpname;
|
std::string filename = tmpname;
|
||||||
irr::io::IReadFile* file;
|
irr::io::IReadFile* file = nullptr;
|
||||||
|
|
||||||
// free image format
|
switch (header->freeimageFormat)
|
||||||
switch (imageFormat)
|
|
||||||
{
|
{
|
||||||
case FREE_IMAGE_FORMAT::FIF_BMP:
|
case FREE_IMAGE_FORMAT::FIF_BMP:
|
||||||
// add extension to the file
|
|
||||||
filename += ".bmp";
|
filename += ".bmp";
|
||||||
file = WallpaperEngine::Irrlicht::device->getFileSystem ()->createMemoryReadFile (filebuffer, mipmap_uncompressed_size, filename.c_str (), true);
|
|
||||||
break;
|
break;
|
||||||
case FREE_IMAGE_FORMAT::FIF_PNG:
|
case FREE_IMAGE_FORMAT::FIF_PNG:
|
||||||
// add extension to the file
|
|
||||||
filename += ".png";
|
filename += ".png";
|
||||||
file = WallpaperEngine::Irrlicht::device->getFileSystem ()->createMemoryReadFile (filebuffer, mipmap_uncompressed_size, filename.c_str (), true);
|
|
||||||
break;
|
break;
|
||||||
case FREE_IMAGE_FORMAT::FIF_JPEG:
|
case FREE_IMAGE_FORMAT::FIF_JPEG:
|
||||||
// add extension to the file
|
|
||||||
filename += ".jpg";
|
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;
|
break;
|
||||||
case FREE_IMAGE_FORMAT::FIF_GIF:
|
case FREE_IMAGE_FORMAT::FIF_GIF:
|
||||||
filename += ".gif";
|
filename += ".gif";
|
||||||
file = WallpaperEngine::Irrlicht::device->getFileSystem ()->createMemoryReadFile (filebuffer, mipmap_uncompressed_size, filename.c_str (), true);
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
WallpaperEngine::Irrlicht::device->getLogger ()->log ("LOAD TEX: detected unsupported free-image format\n", input->getFileName ().c_str (), irr::ELL_ERROR);
|
throw std::runtime_error ("Unsupported free image extension");
|
||||||
delete [] decompressedBuffer;
|
|
||||||
delete [] filebuffer;
|
|
||||||
return nullptr;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
image = WallpaperEngine::Irrlicht::driver->createImageFromFile (file);
|
// create a copy of the file information for the filesystem module of irrlicht
|
||||||
|
// this will be freed automatically by irrlicht so we can freely delete the container
|
||||||
|
// data from memory without leaking memory
|
||||||
|
char* filebuffer = new char [mipmap->uncompressedSize];
|
||||||
|
|
||||||
if (!image)
|
memcpy (filebuffer, mipmap->uncompressedData, mipmap->uncompressedSize);
|
||||||
|
|
||||||
|
file = this->m_context->getDevice ()->getFileSystem ()->createMemoryReadFile (
|
||||||
|
filebuffer, mipmap->uncompressedSize, filename.c_str (), true
|
||||||
|
);
|
||||||
|
|
||||||
|
if (file == nullptr)
|
||||||
{
|
{
|
||||||
|
delete [] filebuffer;
|
||||||
|
delete header;
|
||||||
|
|
||||||
|
throw std::runtime_error ("cannot create temporal memory file");
|
||||||
|
}
|
||||||
|
|
||||||
|
image = this->m_context->getDevice ()->getVideoDriver ()->createImageFromFile (file);
|
||||||
|
|
||||||
|
if (image == nullptr)
|
||||||
|
{
|
||||||
|
// this takes care of freeing filebuffer
|
||||||
file->drop ();
|
file->drop ();
|
||||||
|
|
||||||
delete [] decompressedBuffer;
|
delete header;
|
||||||
delete image;
|
|
||||||
WallpaperEngine::Irrlicht::device->getLogger ()->log ("LOAD TEX: cannot create destination image\n", input->getFileName ().c_str (), irr::ELL_ERROR);
|
throw std::runtime_error ("cannot create destination image");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// delete container info as it's not needed anymore
|
||||||
|
delete header;
|
||||||
|
|
||||||
|
return image;
|
||||||
|
}
|
||||||
|
|
||||||
|
// load in the image data
|
||||||
|
irr::video::IImage *CImageLoaderTex::loadImage (irr::io::IReadFile *input) const
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
return this->parseFile (input);
|
||||||
|
}
|
||||||
|
catch (std::runtime_error ex)
|
||||||
|
{
|
||||||
|
this->m_context->getDevice ()->getLogger ()->log (
|
||||||
|
ex.what (), input->getFileName ().c_str (), irr::ELL_ERROR
|
||||||
|
);
|
||||||
|
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
delete [] decompressedBuffer;
|
void CImageLoaderTex::loadImageFromARGB8Data (irr::video::IImage* output, const char* input, irr::u32 width, irr::u32 height, irr::u32 mipmap_width) const
|
||||||
|
{
|
||||||
return image;
|
irr::u32 bytesPerPixel = output->getBytesPerPixel ();
|
||||||
}
|
|
||||||
|
|
||||||
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 ();
|
char *imagedata = (char *) output->lock ();
|
||||||
|
|
||||||
for (u32 y = 0; y < height; y ++)
|
for (irr::u32 y = 0; y < height; y ++)
|
||||||
{
|
{
|
||||||
u32 baseDestination = y * output->getPitch ();
|
irr::u32 baseDestination = y * output->getPitch ();
|
||||||
u32 baseOrigin = y * (mipmap_width * 4);
|
irr::u32 baseOrigin = y * (mipmap_width * 4);
|
||||||
|
|
||||||
for (u32 x = 0; x < width; x ++)
|
for (irr::u32 x = 0; x < width; x ++)
|
||||||
{
|
{
|
||||||
imagedata [baseDestination + (x * bytesPerPixel) + 2] = input [baseOrigin + ((width - x) * 4) + 0]; // r
|
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) + 1] = input [baseOrigin + ((width - x) * 4) + 1]; // g
|
||||||
@ -275,56 +345,56 @@ void CImageLoaderTex::loadImageFromARGB8Data (IImage* output, const char* input,
|
|||||||
}
|
}
|
||||||
|
|
||||||
output->unlock ();
|
output->unlock ();
|
||||||
}
|
}
|
||||||
|
|
||||||
void CImageLoaderTex::loadImageFromDXT1 (IImage* output, const char* input, u32 destination_width, u32 destination_height, u32 origin_width, u32 origin_height) const
|
void CImageLoaderTex::loadImageFromDXT1 (irr::video::IImage* output, const char* input, irr::u32 destination_width, irr::u32 destination_height, irr::u32 origin_width, irr::u32 origin_height) const
|
||||||
{
|
{
|
||||||
char* decompressedBuffer = new char [origin_width * origin_height * 4];
|
char* decompressedBuffer = new char [origin_width * origin_height * 4];
|
||||||
|
|
||||||
this->BlockDecompressImageDXT1 (origin_width, origin_height, (const unsigned char*) input, (unsigned long*) decompressedBuffer);
|
this->BlockDecompressImageDXT1 (origin_width, origin_height, (const unsigned char*) input, (unsigned long*) decompressedBuffer);
|
||||||
this->loadImageFromARGB8Data (output, decompressedBuffer, destination_width, destination_height, origin_width);
|
this->loadImageFromARGB8Data (output, decompressedBuffer, destination_width, destination_height, origin_width);
|
||||||
|
|
||||||
delete [] decompressedBuffer;
|
delete [] decompressedBuffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CImageLoaderTex::loadImageFromDXT5 (IImage* output, const char* input, u32 destination_width, u32 destination_height, u32 origin_width, u32 origin_height) const
|
void CImageLoaderTex::loadImageFromDXT5 (irr::video::IImage* output, const char* input, irr::u32 destination_width, irr::u32 destination_height, irr::u32 origin_width, irr::u32 origin_height) const
|
||||||
{
|
{
|
||||||
char* decompressedBuffer = new char [origin_width * origin_height * 4];
|
char* decompressedBuffer = new char [origin_width * origin_height * 4];
|
||||||
|
|
||||||
this->BlockDecompressImageDXT5 (origin_width, origin_height, (const unsigned char*) input, (unsigned long*) decompressedBuffer);
|
this->BlockDecompressImageDXT5 (origin_width, origin_height, (const unsigned char*) input, (unsigned long*) decompressedBuffer);
|
||||||
this->loadImageFromARGB8Data (output, decompressedBuffer, destination_width, destination_height, origin_width);
|
this->loadImageFromARGB8Data (output, decompressedBuffer, destination_width, destination_height, origin_width);
|
||||||
|
|
||||||
delete [] decompressedBuffer;
|
delete [] decompressedBuffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------
|
||||||
// The following code is a slightly modified version of this repository
|
// The following code is a slightly modified version of this repository
|
||||||
// https://github.com/Benjamin-Dobell/s3tc-dxt-decompression
|
// https://github.com/Benjamin-Dobell/s3tc-dxt-decompression
|
||||||
// ------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------
|
||||||
|
|
||||||
// unsigned long PackRGBA(): Helper method that packs RGBA channels into a single 4 byte pixel.
|
// unsigned long PackRGBA(): Helper method that packs RGBA channels into a single 4 byte pixel.
|
||||||
//
|
//
|
||||||
// unsigned char r: red channel.
|
// unsigned char r: red channel.
|
||||||
// unsigned char g: green channel.
|
// unsigned char g: green channel.
|
||||||
// unsigned char b: blue channel.
|
// unsigned char b: blue channel.
|
||||||
// unsigned char a: alpha channel.
|
// unsigned char a: alpha channel.
|
||||||
|
|
||||||
unsigned long CImageLoaderTex::PackRGBA(unsigned char r, unsigned char g, unsigned char b, unsigned char a) const
|
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);
|
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'.
|
// 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 x: x-coordinate of the first pixel in the block.
|
||||||
// unsigned long y: y-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 width: width of the texture being decompressed.
|
||||||
// unsigned long height: height of the texture being decompressed.
|
// unsigned long height: height of the texture being decompressed.
|
||||||
// const unsigned char *blockStorage: pointer to the block to decompress.
|
// const unsigned char *blockStorage: pointer to the block to decompress.
|
||||||
// unsigned long *image: pointer to image where the decompressed pixel data should be stored.
|
// 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
|
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 color0 = *reinterpret_cast<const unsigned short *>(blockStorage);
|
||||||
unsigned short color1 = *reinterpret_cast<const unsigned short *>(blockStorage + 2);
|
unsigned short color1 = *reinterpret_cast<const unsigned short *>(blockStorage + 2);
|
||||||
|
|
||||||
@ -394,17 +464,17 @@ void CImageLoaderTex::DecompressBlockDXT1(unsigned long x, unsigned long y, unsi
|
|||||||
image[(y + j)*width + (x + i)] = finalColor;
|
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'.
|
// 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 width: Texture width.
|
||||||
// unsigned long height: Texture height.
|
// unsigned long height: Texture height.
|
||||||
// const unsigned char *blockStorage: pointer to compressed DXT1 blocks.
|
// const unsigned char *blockStorage: pointer to compressed DXT1 blocks.
|
||||||
// unsigned long *image: pointer to the image where the decompressed pixels will be stored.
|
// 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
|
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 blockCountX = (width + 3) / 4;
|
||||||
unsigned long blockCountY = (height + 3) / 4;
|
unsigned long blockCountY = (height + 3) / 4;
|
||||||
unsigned long blockWidth = (width < 4) ? width : 4;
|
unsigned long blockWidth = (width < 4) ? width : 4;
|
||||||
@ -415,19 +485,19 @@ void CImageLoaderTex::BlockDecompressImageDXT1(unsigned long width, unsigned lon
|
|||||||
for (unsigned long i = 0; i < blockCountX; i++) DecompressBlockDXT1(i*4, j*4, width, blockStorage + i * 8, image);
|
for (unsigned long i = 0; i < blockCountX; i++) DecompressBlockDXT1(i*4, j*4, width, blockStorage + i * 8, image);
|
||||||
blockStorage += blockCountX * 8;
|
blockStorage += blockCountX * 8;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// void DecompressBlockDXT5(): Decompresses one block of a DXT5 texture and stores the resulting pixels at the appropriate offset in 'image'.
|
// 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 x: x-coordinate of the first pixel in the block.
|
||||||
// unsigned long y: y-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 width: width of the texture being decompressed.
|
||||||
// unsigned long height: height of the texture being decompressed.
|
// unsigned long height: height of the texture being decompressed.
|
||||||
// const unsigned char *blockStorage: pointer to the block to decompress.
|
// const unsigned char *blockStorage: pointer to the block to decompress.
|
||||||
// unsigned long *image: pointer to image where the decompressed pixel data should be stored.
|
// 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
|
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 alpha0 = *reinterpret_cast<const unsigned char *>(blockStorage);
|
||||||
unsigned char alpha1 = *reinterpret_cast<const unsigned char *>(blockStorage + 1);
|
unsigned char alpha1 = *reinterpret_cast<const unsigned char *>(blockStorage + 1);
|
||||||
|
|
||||||
@ -525,17 +595,17 @@ void CImageLoaderTex::DecompressBlockDXT5(unsigned long x, unsigned long y, unsi
|
|||||||
image[(y + j)*width + (x + i)] = finalColor;
|
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'.
|
// 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 width: Texture width.
|
||||||
// unsigned long height: Texture height.
|
// unsigned long height: Texture height.
|
||||||
// const unsigned char *blockStorage: pointer to compressed DXT5 blocks.
|
// const unsigned char *blockStorage: pointer to compressed DXT5 blocks.
|
||||||
// unsigned long *image: pointer to the image where the decompressed pixels will be stored.
|
// 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
|
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 blockCountX = (width + 3) / 4;
|
||||||
unsigned long blockCountY = (height + 3) / 4;
|
unsigned long blockCountY = (height + 3) / 4;
|
||||||
unsigned long blockWidth = (width < 4) ? width : 4;
|
unsigned long blockWidth = (width < 4) ? width : 4;
|
||||||
@ -546,4 +616,5 @@ void CImageLoaderTex::BlockDecompressImageDXT5(unsigned long width, unsigned lon
|
|||||||
for (unsigned long i = 0; i < blockCountX; i++) DecompressBlockDXT5(i*4, j*4, width, blockStorage + i * 16, image);
|
for (unsigned long i = 0; i < blockCountX; i++) DecompressBlockDXT5(i*4, j*4, width, blockStorage + i * 16, image);
|
||||||
blockStorage += blockCountX * 16;
|
blockStorage += blockCountX * 16;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
};
|
@ -1,33 +1,123 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <irrlicht/irrlicht.h>
|
#include <vector>
|
||||||
|
|
||||||
using namespace irr;
|
#include <irrlicht/irrlicht.h>
|
||||||
using namespace irr::video;
|
#include "CContext.h"
|
||||||
|
|
||||||
namespace WallpaperEngine::Irrlicht
|
namespace WallpaperEngine::Irrlicht
|
||||||
{
|
{
|
||||||
//! Surface Loader for PNG files
|
//! Surface Loader for PNG files
|
||||||
class CImageLoaderTex : public IImageLoader
|
class CImageLoaderTex : public irr::video::IImageLoader
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
CImageLoaderTex (CContext* context);
|
||||||
|
|
||||||
//! returns true if the file maybe is able to be loaded by this class
|
//! returns true if the file maybe is able to be loaded by this class
|
||||||
//! based on the file extension (e.g. ".png")
|
//! based on the file extension (e.g. ".png")
|
||||||
virtual bool isALoadableFileExtension(const io::path& filename) const;
|
virtual bool isALoadableFileExtension(const irr::io::path& filename) const;
|
||||||
|
|
||||||
//! returns true if the file maybe is able to be loaded by this class
|
//! returns true if the file maybe is able to be loaded by this class
|
||||||
virtual bool isALoadableFileFormat(io::IReadFile* file) const;
|
virtual bool isALoadableFileFormat(irr::io::IReadFile* file) const;
|
||||||
|
|
||||||
//! creates a surface from the file
|
//! creates a surface from the file
|
||||||
virtual IImage* loadImage(io::IReadFile* input) const;
|
virtual irr::video::IImage* loadImage(irr::io::IReadFile* input) const;
|
||||||
|
|
||||||
virtual void loadImageFromARGB8Data (IImage* output, const char* input, u32 width, u32 height, u32 mipmap_width) const;
|
virtual void loadImageFromARGB8Data (irr::video::IImage* output, const char* input, irr::u32 width, irr::u32 height, irr::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 loadImageFromDXT1 (irr::video::IImage* output, const char* input, irr::u32 destination_width, irr::u32 destination_height, irr::u32 origin_width, irr::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;
|
virtual void loadImageFromDXT5 (irr::video::IImage* output, const char* input, irr::u32 destination_width, irr::u32 destination_height, irr::u32 origin_width, irr::u32 origin_height) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
enum ContainerVersion
|
||||||
|
{
|
||||||
|
UNKNOWN = -1,
|
||||||
|
TEXB0003 = 3,
|
||||||
|
TEXB0002 = 2,
|
||||||
|
TEXB0001 = 1
|
||||||
|
};
|
||||||
|
|
||||||
|
class TextureMipmap
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
TextureMipmap ();
|
||||||
|
~TextureMipmap ();
|
||||||
|
|
||||||
|
/** Width of the mipmap */
|
||||||
|
irr::u32 width;
|
||||||
|
/** Height of the mipmap */
|
||||||
|
irr::u32 height;
|
||||||
|
/** If the mipmap data is compressed */
|
||||||
|
irr::u32 compression;
|
||||||
|
/** Uncompressed size of the mipmap */
|
||||||
|
irr::u32 uncompressedSize;
|
||||||
|
/** Compress size of the mipmap */
|
||||||
|
irr::u32 compressedSize;
|
||||||
|
/** Pointer to the compressed data */
|
||||||
|
char* compressedData = nullptr;
|
||||||
|
/** Pointer to the uncompressed data */
|
||||||
|
char* uncompressedData = nullptr;
|
||||||
|
/**
|
||||||
|
* Performs actual decompression of the compressed data
|
||||||
|
*/
|
||||||
|
void decompressData ();
|
||||||
|
};
|
||||||
|
|
||||||
|
class TextureContainer
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
TextureContainer ();
|
||||||
|
~TextureContainer ();
|
||||||
|
|
||||||
|
/** The version of the texture container */
|
||||||
|
ContainerVersion containerVersion = ContainerVersion::UNKNOWN;
|
||||||
|
/** Real width of the texture */
|
||||||
|
irr::u32 width;
|
||||||
|
/** Real height of the texture */
|
||||||
|
irr::u32 height;
|
||||||
|
/** Texture width in memory (power of 2) */
|
||||||
|
irr::u32 textureWidth;
|
||||||
|
/** Texture height in memory (power of 2) */
|
||||||
|
irr::u32 textureHeight;
|
||||||
|
/** Texture data format */
|
||||||
|
irr::u32 format;
|
||||||
|
/** Free Image format */
|
||||||
|
irr::u32 freeimageFormat;
|
||||||
|
/** Number of mipmap levels for the texture */
|
||||||
|
irr::u32 mipmapCount;
|
||||||
|
/** List of mipmaps */
|
||||||
|
std::vector <TextureMipmap*> mipmaps;
|
||||||
|
};
|
||||||
|
|
||||||
|
/** Irrlicht context */
|
||||||
|
CContext* m_context;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parses the container file and returns a texture ready to be used
|
||||||
|
*
|
||||||
|
* @param input The file to parse the data from
|
||||||
|
*
|
||||||
|
* @return The texture ready to be used
|
||||||
|
*/
|
||||||
|
irr::video::IImage* parseFile (irr::io::IReadFile* input) const;
|
||||||
|
/**
|
||||||
|
* Parses the container header and returns it's information
|
||||||
|
*
|
||||||
|
* @param input The file to parse the data from
|
||||||
|
*
|
||||||
|
* @return The container header data
|
||||||
|
*/
|
||||||
|
TextureContainer* parseHeader (irr::io::IReadFile* input) const;
|
||||||
|
/**
|
||||||
|
* Parses a mipmap level and returns it's information
|
||||||
|
*
|
||||||
|
* @param header The container header where this mipmap is contained
|
||||||
|
* @param input The file to parse the data from
|
||||||
|
*
|
||||||
|
* @return The mipmap info ready
|
||||||
|
*/
|
||||||
|
TextureMipmap* parseMipmap (TextureContainer* header, irr::io::IReadFile* input) const;
|
||||||
|
|
||||||
void BlockDecompressImageDXT1(unsigned long width, unsigned long height, const unsigned char *blockStorage, unsigned long *image) const;
|
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;
|
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;
|
unsigned long PackRGBA(unsigned char r, unsigned char g, unsigned char b, unsigned char a) const;
|
||||||
|
@ -1,45 +1,37 @@
|
|||||||
#include <WallpaperEngine/Irrlicht/Irrlicht.h>
|
|
||||||
#include "CPkgReader.h"
|
#include "CPkgReader.h"
|
||||||
|
|
||||||
using namespace WallpaperEngine::Irrlicht;
|
namespace WallpaperEngine::Irrlicht
|
||||||
|
|
||||||
CArchiveLoaderPkg::CArchiveLoaderPkg(irr::io::IFileSystem* fs)
|
|
||||||
: FileSystem(fs)
|
|
||||||
{
|
{
|
||||||
|
|
||||||
|
CArchiveLoaderPkg::CArchiveLoaderPkg (CContext* context) :
|
||||||
|
m_context (context)
|
||||||
|
{
|
||||||
#ifdef _DEBUG
|
#ifdef _DEBUG
|
||||||
setDebugName("CArchiveLoaderWAD");
|
setDebugName("CArchiveLoaderWAD");
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool CArchiveLoaderPkg::isALoadableFileFormat(const irr::io::path& filename) const
|
||||||
//! 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");
|
return irr::core::hasFileExtension (filename, "pkg");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
irr::io::IFileArchive* CArchiveLoaderPkg::createArchive(const irr::io::path& filename, bool ignoreCase, bool ignorePaths) const
|
||||||
//! 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::IFileArchive *archive = nullptr;
|
||||||
irr::io::IReadFile* file = FileSystem->createAndOpenFile(filename);
|
irr::io::IReadFile* file = this->m_context->getDevice ()->getFileSystem ()->createAndOpenFile(filename);
|
||||||
|
|
||||||
if (file)
|
if (file)
|
||||||
{
|
{
|
||||||
archive = createArchive (file, ignoreCase, ignorePaths);
|
archive = this->createArchive (file, ignoreCase, ignorePaths);
|
||||||
file->drop ();
|
file->drop ();
|
||||||
}
|
}
|
||||||
|
|
||||||
return archive;
|
return archive;
|
||||||
}
|
}
|
||||||
|
|
||||||
//! creates/loads an archive from the file.
|
irr::io::IFileArchive* CArchiveLoaderPkg::createArchive(irr::io::IReadFile* file, bool ignoreCase, bool ignorePaths) const
|
||||||
//! \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;
|
irr::io::IFileArchive *archive = nullptr;
|
||||||
|
|
||||||
if (file)
|
if (file)
|
||||||
@ -49,15 +41,10 @@ irr::io::IFileArchive* CArchiveLoaderPkg::createArchive(irr::io::IReadFile* file
|
|||||||
}
|
}
|
||||||
|
|
||||||
return archive;
|
return archive;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool CArchiveLoaderPkg::isALoadableFileFormat(irr::io::IReadFile* file) 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. */
|
|
||||||
bool CArchiveLoaderPkg::isALoadableFileFormat(irr::io::IReadFile* file) const
|
|
||||||
{
|
|
||||||
unsigned int size;
|
unsigned int size;
|
||||||
char* pointer;
|
char* pointer;
|
||||||
|
|
||||||
@ -79,68 +66,68 @@ bool CArchiveLoaderPkg::isALoadableFileFormat(irr::io::IReadFile* file) const
|
|||||||
|
|
||||||
delete [] pointer;
|
delete [] pointer;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
//! Check to see if the loader can create archives of this type.
|
//! Check to see if the loader can create archives of this type.
|
||||||
bool CArchiveLoaderPkg::isALoadableFileFormat(irr::io::E_FILE_ARCHIVE_TYPE fileType) const
|
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 ();
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
CPkgReader::CPkgReader (irr::io::IReadFile* file, bool ignoreCase, bool ignorePaths)
|
||||||
|
: CFileList((file ? file->getFileName() : irr::io::path("")), ignoreCase, ignorePaths), m_file(file)
|
||||||
|
{
|
||||||
|
if (this->m_file)
|
||||||
|
{
|
||||||
|
this->m_file->grab ();
|
||||||
this->scanPkgHeader ();
|
this->scanPkgHeader ();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
CPkgReader::~CPkgReader()
|
CPkgReader::~CPkgReader()
|
||||||
{
|
{
|
||||||
if (this->mFile)
|
if (this->m_file)
|
||||||
this->mFile->drop();
|
this->m_file->drop();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
irr::io::E_FILE_ARCHIVE_TYPE CPkgReader::getType() const
|
||||||
//! get the archive type
|
{
|
||||||
irr::io::E_FILE_ARCHIVE_TYPE CPkgReader::getType() const
|
|
||||||
{
|
|
||||||
return irr::io::E_FILE_ARCHIVE_TYPE::EFAT_ZIP;
|
return irr::io::E_FILE_ARCHIVE_TYPE::EFAT_ZIP;
|
||||||
}
|
}
|
||||||
|
|
||||||
const irr::io::IFileList* CPkgReader::getFileList() const
|
const irr::io::IFileList* CPkgReader::getFileList() const
|
||||||
{
|
{
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CPkgReader::scanPkgHeader ()
|
void CPkgReader::scanPkgHeader ()
|
||||||
{
|
{
|
||||||
char* headerVersion = this->readSizedString ();
|
char* headerVersion = this->readSizedString ();
|
||||||
|
|
||||||
if (strcmp ("PKGV0002", headerVersion) != 0 && strcmp ("PKGV0001", headerVersion) != 0)
|
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);
|
|
||||||
|
|
||||||
delete [] headerVersion;
|
delete [] headerVersion;
|
||||||
|
|
||||||
|
this->m_context->getDevice ()->getLogger ()->log (
|
||||||
|
"unexpected package header", this->m_file->getFileName ().c_str (), irr::ELL_ERROR
|
||||||
|
);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
delete [] headerVersion;
|
delete [] headerVersion;
|
||||||
|
irr::u32 entriesCount;
|
||||||
|
|
||||||
unsigned int entriesCount;
|
this->m_file->read (&entriesCount, 4);
|
||||||
|
|
||||||
this->mFile->read (&entriesCount, 4);
|
|
||||||
|
|
||||||
|
|
||||||
for (int i = 0; i < entriesCount; i ++)
|
for (irr::u32 i = 0; i < entriesCount; i ++)
|
||||||
{
|
{
|
||||||
char* filename = this->readSizedString ();
|
char* filename = this->readSizedString ();
|
||||||
unsigned int offset, length;
|
irr::u32 offset, length;
|
||||||
|
|
||||||
this->mFile->read (&offset, 4);
|
this->m_file->read (&offset, 4);
|
||||||
this->mFile->read (&length, 4);
|
this->m_file->read (&length, 4);
|
||||||
|
|
||||||
this->addItem (filename, offset, length, false);
|
this->addItem (filename, offset, length, false);
|
||||||
|
|
||||||
@ -148,18 +135,18 @@ void CPkgReader::scanPkgHeader ()
|
|||||||
}
|
}
|
||||||
|
|
||||||
// after the header is read we have to update the actual offsets
|
// after the header is read we have to update the actual offsets
|
||||||
for (int i = 0; i < this->Files.size (); i ++)
|
for (irr::u32 i = 0; i < this->m_files.size (); i ++)
|
||||||
{
|
{
|
||||||
this->Files [i].Offset += this->mFile->getPos ();
|
this->m_files [i].Offset += this->m_file->getPos ();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
char* CPkgReader::readSizedString ()
|
char* CPkgReader::readSizedString ()
|
||||||
{
|
{
|
||||||
unsigned int size;
|
unsigned int size;
|
||||||
char* pointer;
|
char* pointer;
|
||||||
|
|
||||||
this->mFile->read (&size, 4);
|
this->m_file->read (&size, 4);
|
||||||
|
|
||||||
// the string doesnt include the null terminator
|
// the string doesnt include the null terminator
|
||||||
size ++;
|
size ++;
|
||||||
@ -167,26 +154,27 @@ char* CPkgReader::readSizedString ()
|
|||||||
pointer = new char [size];
|
pointer = new char [size];
|
||||||
memset (pointer, 0, size);
|
memset (pointer, 0, size);
|
||||||
|
|
||||||
this->mFile->read (pointer, size - 1);
|
this->m_file->read (pointer, size - 1);
|
||||||
|
|
||||||
return pointer;
|
return pointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
irr::io::IReadFile* CPkgReader::createAndOpenFile (const irr::io::path& filename)
|
irr::io::IReadFile* CPkgReader::createAndOpenFile (const irr::io::path& filename)
|
||||||
{
|
{
|
||||||
irr::s32 index = this->findFile (filename, false);
|
irr::s32 index = this->findFile (filename, false);
|
||||||
|
|
||||||
if (index != -1)
|
if (index != -1)
|
||||||
return createAndOpenFile (index);
|
return createAndOpenFile (index);
|
||||||
|
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
irr::io::IReadFile* CPkgReader::createAndOpenFile (irr::u32 index)
|
irr::io::IReadFile* CPkgReader::createAndOpenFile (irr::u32 index)
|
||||||
{
|
{
|
||||||
if (index > this->Files.size ())
|
if (index > this->m_files.size ())
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
||||||
const SFileListEntry entry = Files [index];
|
const SFileListEntry entry = m_files [index];
|
||||||
return irr::io::createLimitReadFile (entry.FullName, mFile, entry.Offset, entry.Size);
|
return irr::io::createLimitReadFile (entry.FullName, m_file, entry.Offset, entry.Size);
|
||||||
|
}
|
||||||
}
|
}
|
@ -2,10 +2,9 @@
|
|||||||
#include <irrlicht/irrlicht.h>
|
#include <irrlicht/irrlicht.h>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
|
#include "CContext.h"
|
||||||
#include "CFileList.h"
|
#include "CFileList.h"
|
||||||
|
|
||||||
using namespace irr;
|
|
||||||
|
|
||||||
namespace WallpaperEngine::Irrlicht
|
namespace WallpaperEngine::Irrlicht
|
||||||
{
|
{
|
||||||
//! Archiveloader capable of loading WAD Archives
|
//! Archiveloader capable of loading WAD Archives
|
||||||
@ -14,36 +13,36 @@ namespace WallpaperEngine::Irrlicht
|
|||||||
public:
|
public:
|
||||||
|
|
||||||
//! Constructor
|
//! Constructor
|
||||||
CArchiveLoaderPkg(irr::io::IFileSystem *fs);
|
CArchiveLoaderPkg (CContext* context);
|
||||||
|
|
||||||
//! returns true if the file maybe is able to be loaded by this class
|
//! returns true if the file maybe is able to be loaded by this class
|
||||||
//! based on the file extension (e.g. ".zip")
|
//! based on the file extension (e.g. ".zip")
|
||||||
virtual bool isALoadableFileFormat(const irr::io::path &filename) const;
|
virtual bool isALoadableFileFormat (const irr::io::path &filename) const;
|
||||||
|
|
||||||
//! Check if the file might be loaded by this class
|
//! Check if the file might be loaded by this class
|
||||||
/** Check might look into the file.
|
/** Check might look into the file.
|
||||||
\param file File handle to check.
|
\param file File handle to check.
|
||||||
\return True if file seems to be loadable. */
|
\return True if file seems to be loadable. */
|
||||||
virtual bool isALoadableFileFormat(irr::io::IReadFile *file) const;
|
virtual bool isALoadableFileFormat (irr::io::IReadFile *file) const;
|
||||||
|
|
||||||
//! Check to see if the loader can create archives of this type.
|
//! Check to see if the loader can create archives of this type.
|
||||||
/** Check based on the archive type.
|
/** Check based on the archive type.
|
||||||
\param fileType The archive type to check.
|
\param fileType The archive type to check.
|
||||||
\return True if the archile loader supports this type, false if not */
|
\return True if the archile loader supports this type, false if not */
|
||||||
virtual bool isALoadableFileFormat(irr::io::E_FILE_ARCHIVE_TYPE fileType) const;
|
virtual bool isALoadableFileFormat (irr::io::E_FILE_ARCHIVE_TYPE fileType) const;
|
||||||
|
|
||||||
//! Creates an archive from the filename
|
//! Creates an archive from the filename
|
||||||
/** \param file File handle to check.
|
/** \param file File handle to check.
|
||||||
\return Pointer to newly created archive, or 0 upon error. */
|
\return Pointer to newly created archive, or 0 upon error. */
|
||||||
virtual irr::io::IFileArchive *
|
virtual irr::io::IFileArchive *
|
||||||
createArchive(const irr::io::path &filename, bool ignoreCase, bool ignorePaths) const;
|
createArchive (const irr::io::path &filename, bool ignoreCase, bool ignorePaths) const;
|
||||||
|
|
||||||
//! creates/loads an archive from the file.
|
//! creates/loads an archive from the file.
|
||||||
//! \return Pointer to the created archive. Returns 0 if loading failed.
|
//! \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;
|
virtual irr::io::IFileArchive *createArchive (irr::io::IReadFile *file, bool ignoreCase, bool ignorePaths) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
irr::io::IFileSystem *FileSystem;
|
CContext* m_context;
|
||||||
};
|
};
|
||||||
|
|
||||||
class CPkgReader : public virtual irr::io::IFileArchive, virtual CFileList
|
class CPkgReader : public virtual irr::io::IFileArchive, virtual CFileList
|
||||||
@ -51,29 +50,29 @@ namespace WallpaperEngine::Irrlicht
|
|||||||
public:
|
public:
|
||||||
|
|
||||||
//! constructor
|
//! constructor
|
||||||
CPkgReader(irr::io::IReadFile *file, bool ignoreCase, bool ignorePaths);
|
CPkgReader (irr::io::IReadFile *file, bool ignoreCase, bool ignorePaths);
|
||||||
|
|
||||||
//! destructor
|
//! destructor
|
||||||
virtual ~CPkgReader();
|
virtual ~CPkgReader ();
|
||||||
|
|
||||||
//! opens a file by file name
|
//! opens a file by file name
|
||||||
virtual irr::io::IReadFile *createAndOpenFile(const irr::io::path &filename);
|
virtual irr::io::IReadFile *createAndOpenFile (const irr::io::path &filename);
|
||||||
|
|
||||||
//! opens a file by index
|
//! opens a file by index
|
||||||
virtual irr::io::IReadFile *createAndOpenFile(unsigned int index);
|
virtual irr::io::IReadFile *createAndOpenFile (unsigned int index);
|
||||||
|
|
||||||
//! returns the list of files
|
//! returns the list of files
|
||||||
virtual const IFileList *getFileList() const;
|
virtual const IFileList *getFileList () const;
|
||||||
|
|
||||||
//! get the archive type
|
//! get the archive type
|
||||||
virtual irr::io::E_FILE_ARCHIVE_TYPE getType() const;
|
virtual irr::io::E_FILE_ARCHIVE_TYPE getType () const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void scanPkgHeader();
|
void scanPkgHeader ();
|
||||||
|
|
||||||
char *readSizedString();
|
char *readSizedString ();
|
||||||
|
|
||||||
irr::io::IFileSystem *mFileSystem;
|
CContext* m_context;
|
||||||
irr::io::IReadFile *mFile;
|
irr::io::IReadFile *m_file;
|
||||||
};
|
};
|
||||||
}
|
}
|
@ -1,8 +0,0 @@
|
|||||||
#include <WallpaperEngine/Irrlicht/Irrlicht.h>
|
|
||||||
|
|
||||||
namespace WallpaperEngine::Irrlicht
|
|
||||||
{
|
|
||||||
irr::video::IVideoDriver* driver = nullptr;
|
|
||||||
irr::IrrlichtDevice* device = nullptr;
|
|
||||||
irr::scene::ICameraSceneNode* camera = nullptr;
|
|
||||||
}
|
|
@ -1,10 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include <irrlicht/irrlicht.h>
|
|
||||||
|
|
||||||
namespace WallpaperEngine::Irrlicht
|
|
||||||
{
|
|
||||||
extern irr::video::IVideoDriver* driver;
|
|
||||||
extern irr::IrrlichtDevice* device;
|
|
||||||
extern irr::scene::ICameraSceneNode* camera;
|
|
||||||
};
|
|
@ -6,9 +6,6 @@
|
|||||||
// filesystem
|
// filesystem
|
||||||
#include <WallpaperEngine/FileSystem/FileSystem.h>
|
#include <WallpaperEngine/FileSystem/FileSystem.h>
|
||||||
|
|
||||||
// video engine
|
|
||||||
#include <WallpaperEngine/Irrlicht/Irrlicht.h>
|
|
||||||
|
|
||||||
// shader compiler
|
// shader compiler
|
||||||
#include <WallpaperEngine/Render/Shaders/Compiler.h>
|
#include <WallpaperEngine/Render/Shaders/Compiler.h>
|
||||||
#include <WallpaperEngine/Core/Core.h>
|
#include <WallpaperEngine/Core/Core.h>
|
||||||
@ -242,7 +239,7 @@ namespace WallpaperEngine::Render::Shaders
|
|||||||
|
|
||||||
std::string Compiler::precompile()
|
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) { throw std::runtime_error ("ERROR PRE-COMPILING SHADER" + this->m_errorInfo); }
|
||||||
// parse the shader and find #includes and such things and translate them to the correct name
|
// parse the shader and find #includes and such things and translate them to the correct name
|
||||||
// also remove any #version definition to prevent errors
|
// also remove any #version definition to prevent errors
|
||||||
std::string::const_iterator it = this->m_content.begin ();
|
std::string::const_iterator it = this->m_content.begin ();
|
||||||
@ -441,12 +438,6 @@ namespace WallpaperEngine::Render::Shaders
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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 ());
|
|
||||||
}
|
|
||||||
|
|
||||||
return this->m_compiledContent;
|
return this->m_compiledContent;
|
||||||
#undef BREAK_IF_ERROR
|
#undef BREAK_IF_ERROR
|
||||||
}
|
}
|
||||||
@ -462,8 +453,7 @@ namespace WallpaperEngine::Render::Shaders
|
|||||||
|
|
||||||
if (combo == data.end () || defvalue == data.end ())
|
if (combo == data.end () || defvalue == data.end ())
|
||||||
{
|
{
|
||||||
WallpaperEngine::Irrlicht::device->getLogger ()->log ("Cannot parse combo information", irr::ELL_ERROR);
|
throw std::runtime_error ("cannot parse combo information");
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// check the combos
|
// check the combos
|
||||||
@ -488,7 +478,7 @@ namespace WallpaperEngine::Render::Shaders
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
WallpaperEngine::Irrlicht::device->getLogger ()->log ("Cannot parse combo information, unknown type", irr::ELL_ERROR);
|
throw std::runtime_error ("cannot parse combo information, unknown type");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -504,7 +494,7 @@ namespace WallpaperEngine::Render::Shaders
|
|||||||
if (material == data.end () || defvalue == data.end ())
|
if (material == data.end () || defvalue == data.end ())
|
||||||
{
|
{
|
||||||
if (type != "sampler2D")
|
if (type != "sampler2D")
|
||||||
WallpaperEngine::Irrlicht::device->getLogger ()->log ("Cannot parse parameter info for ", name.c_str (), irr::ELL_ERROR);
|
throw std::runtime_error ("cannot parse parameter info for " + name);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -1,11 +1,12 @@
|
|||||||
#include <WallpaperEngine/FileSystem/FileSystem.h>
|
#include <WallpaperEngine/FileSystem/FileSystem.h>
|
||||||
|
|
||||||
|
#include "WallpaperEngine/Irrlicht/CContext.h"
|
||||||
#include "WallpaperEngine/Render/Shaders/Compiler.h"
|
#include "WallpaperEngine/Render/Shaders/Compiler.h"
|
||||||
#include "effect.h"
|
#include "effect.h"
|
||||||
#include "WallpaperEngine/Irrlicht/Irrlicht.h"
|
|
||||||
#include "WallpaperEngine/Core/Core.h"
|
#include "WallpaperEngine/Core/Core.h"
|
||||||
|
|
||||||
extern irr::f32 g_Time;
|
extern irr::f32 g_Time;
|
||||||
|
extern WallpaperEngine::Irrlicht::CContext* IrrlichtContext;
|
||||||
|
|
||||||
namespace WallpaperEngine
|
namespace WallpaperEngine
|
||||||
{
|
{
|
||||||
@ -97,7 +98,7 @@ namespace WallpaperEngine
|
|||||||
this->m_fragShader = new WallpaperEngine::Render::Shaders::Compiler (fragpath, WallpaperEngine::Render::Shaders::Compiler::Type::Type_Pixel, &this->m_combos, false);
|
this->m_fragShader = new WallpaperEngine::Render::Shaders::Compiler (fragpath, WallpaperEngine::Render::Shaders::Compiler::Type::Type_Pixel, &this->m_combos, false);
|
||||||
this->m_vertShader = new WallpaperEngine::Render::Shaders::Compiler (vertpath, WallpaperEngine::Render::Shaders::Compiler::Type::Type_Vertex, &this->m_combos, false);
|
this->m_vertShader = new WallpaperEngine::Render::Shaders::Compiler (vertpath, WallpaperEngine::Render::Shaders::Compiler::Type::Type_Vertex, &this->m_combos, false);
|
||||||
|
|
||||||
this->m_materialType = WallpaperEngine::Irrlicht::driver->getGPUProgrammingServices ()
|
this->m_materialType = IrrlichtContext->getDevice ()->getVideoDriver ()->getGPUProgrammingServices ()
|
||||||
->addHighLevelShaderMaterial (
|
->addHighLevelShaderMaterial (
|
||||||
this->m_vertShader->precompile ().c_str (), "main", irr::video::EVST_VS_2_0,
|
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,
|
this->m_fragShader->precompile ().c_str (), "main", irr::video::EPST_PS_2_0,
|
||||||
@ -336,7 +337,7 @@ namespace WallpaperEngine
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
WallpaperEngine::Irrlicht::device->getLogger ()->log ("Unknown type for combo value", name.c_str (), irr::ELL_ERROR);
|
IrrlichtContext->getDevice ()->getLogger ()->log ("Unknown type for combo value", name.c_str (), irr::ELL_ERROR);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5,9 +5,11 @@
|
|||||||
#include <WallpaperEngine/object3d.h>
|
#include <WallpaperEngine/object3d.h>
|
||||||
#include <WallpaperEngine/image.h>
|
#include <WallpaperEngine/image.h>
|
||||||
|
|
||||||
#include <WallpaperEngine/Irrlicht/Irrlicht.h>
|
#include <WallpaperEngine/Irrlicht/CContext.h>
|
||||||
#include <WallpaperEngine/Core/Core.h>
|
#include <WallpaperEngine/Core/Core.h>
|
||||||
|
|
||||||
|
extern WallpaperEngine::Irrlicht::CContext* IrrlichtContext;
|
||||||
|
|
||||||
namespace WallpaperEngine
|
namespace WallpaperEngine
|
||||||
{
|
{
|
||||||
image::image (json json_data, WallpaperEngine::object* parent) : object3d (object3d::Type::Type_Material, parent)
|
image::image (json json_data, WallpaperEngine::object* parent) : object3d (object3d::Type::Type_Material, parent)
|
||||||
@ -153,8 +155,8 @@ namespace WallpaperEngine
|
|||||||
0, 1, 2, 3
|
0, 1, 2, 3
|
||||||
};
|
};
|
||||||
|
|
||||||
WallpaperEngine::Irrlicht::driver->setMaterial (this->getMaterial ());
|
IrrlichtContext->getDevice ()->getVideoDriver ()->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);
|
IrrlichtContext->getDevice ()->getVideoDriver ()->drawVertexPrimitiveList (this->m_vertices, 4, indices, 1, irr::video::EVT_STANDARD, irr::scene::EPT_QUADS, irr::video::EIT_16BIT);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
@ -6,7 +6,6 @@
|
|||||||
#include "WallpaperEngine/FileSystem/FileSystem.h"
|
#include "WallpaperEngine/FileSystem/FileSystem.h"
|
||||||
|
|
||||||
#include "project.h"
|
#include "project.h"
|
||||||
#include "WallpaperEngine/Irrlicht/Irrlicht.h"
|
|
||||||
|
|
||||||
namespace WallpaperEngine
|
namespace WallpaperEngine
|
||||||
{
|
{
|
||||||
|
@ -1,11 +1,9 @@
|
|||||||
//
|
|
||||||
// Created by almamu on 17/05/19.
|
|
||||||
//
|
|
||||||
|
|
||||||
#include <SDL_rwops.h>
|
#include <SDL_rwops.h>
|
||||||
#include <SDL_mixer.h>
|
#include <SDL_mixer.h>
|
||||||
#include "sound.h"
|
#include "sound.h"
|
||||||
#include "WallpaperEngine/Irrlicht/Irrlicht.h"
|
#include "WallpaperEngine/Irrlicht/CContext.h"
|
||||||
|
|
||||||
|
extern WallpaperEngine::Irrlicht::CContext* IrrlichtContext;
|
||||||
|
|
||||||
namespace WallpaperEngine
|
namespace WallpaperEngine
|
||||||
{
|
{
|
||||||
@ -31,7 +29,7 @@ namespace WallpaperEngine
|
|||||||
{
|
{
|
||||||
SDL_RWops* sdlRwops = nullptr;
|
SDL_RWops* sdlRwops = nullptr;
|
||||||
Mix_Music* music = nullptr;
|
Mix_Music* music = nullptr;
|
||||||
irr::io::IReadFile* readfile = WallpaperEngine::Irrlicht::device->getFileSystem ()->createAndOpenFile ((*cur).c_str ());
|
irr::io::IReadFile* readfile = IrrlichtContext->getDevice ()->getFileSystem ()->createAndOpenFile ((*cur).c_str ());
|
||||||
int filesize = readfile->getSize ();
|
int filesize = readfile->getSize ();
|
||||||
char* filebuffer = new char [filesize];
|
char* filebuffer = new char [filesize];
|
||||||
|
|
||||||
@ -43,7 +41,7 @@ namespace WallpaperEngine
|
|||||||
|
|
||||||
if (music == nullptr)
|
if (music == nullptr)
|
||||||
{
|
{
|
||||||
WallpaperEngine::Irrlicht::device->getLogger ()->log ("Cannot load audio", Mix_GetError (), irr::ELL_ERROR);
|
IrrlichtContext->getDevice ()->getLogger ()->log ("Cannot load audio", Mix_GetError (), irr::ELL_ERROR);
|
||||||
}
|
}
|
||||||
|
|
||||||
this->m_bufferReader.push_back (sdlRwops);
|
this->m_bufferReader.push_back (sdlRwops);
|
||||||
@ -58,7 +56,7 @@ namespace WallpaperEngine
|
|||||||
{
|
{
|
||||||
if (Mix_PlayMusic ((*mixcur), -1) == -1)
|
if (Mix_PlayMusic ((*mixcur), -1) == -1)
|
||||||
{
|
{
|
||||||
WallpaperEngine::Irrlicht::device->getLogger ()->log ("Cannot play audio", Mix_GetError (), irr::ELL_ERROR);
|
IrrlichtContext->getDevice ()->getLogger ()->log ("Cannot play audio", Mix_GetError (), irr::ELL_ERROR);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,13 +2,15 @@
|
|||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
#include <lz4.h>
|
#include <lz4.h>
|
||||||
|
|
||||||
#include "WallpaperEngine/Irrlicht/Irrlicht.h"
|
#include <WallpaperEngine/Irrlicht/CContext.h>
|
||||||
|
|
||||||
|
extern WallpaperEngine::Irrlicht::CContext* IrrlichtContext;
|
||||||
|
|
||||||
namespace WallpaperEngine
|
namespace WallpaperEngine
|
||||||
{
|
{
|
||||||
texture::texture (irr::io::path& file)
|
texture::texture (irr::io::path& file)
|
||||||
{
|
{
|
||||||
this->m_texture = WallpaperEngine::Irrlicht::driver->getTexture (file);
|
this->m_texture = IrrlichtContext->getDevice ()->getVideoDriver ()->getTexture (file);
|
||||||
}
|
}
|
||||||
|
|
||||||
irr::video::ITexture* texture::getIrrTexture ()
|
irr::video::ITexture* texture::getIrrTexture ()
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
#include <WallpaperEngine/Irrlicht/Irrlicht.h>
|
|
||||||
#include <WallpaperEngine/video/material.h>
|
#include <WallpaperEngine/video/material.h>
|
||||||
|
#include <WallpaperEngine/Irrlicht/CContext.h>
|
||||||
|
|
||||||
|
extern WallpaperEngine::Irrlicht::CContext* IrrlichtContext;
|
||||||
|
|
||||||
namespace WallpaperEngine
|
namespace WallpaperEngine
|
||||||
{
|
{
|
||||||
@ -56,8 +58,10 @@ namespace WallpaperEngine
|
|||||||
0, 1, 2, 3
|
0, 1, 2, 3
|
||||||
};
|
};
|
||||||
|
|
||||||
WallpaperEngine::Irrlicht::driver->setMaterial (m_material);
|
IrrlichtContext->getDevice ()->getVideoDriver ()->setMaterial (m_material);
|
||||||
WallpaperEngine::Irrlicht::driver->drawVertexPrimitiveList (m_vertices, 4, indices, 1, irr::video::EVT_STANDARD, irr::scene::EPT_QUADS, irr::video::EIT_16BIT);
|
IrrlichtContext->getDevice ()->getVideoDriver ()->drawVertexPrimitiveList (
|
||||||
|
m_vertices, 4, indices, 1, irr::video::EVT_STANDARD, irr::scene::EPT_QUADS, irr::video::EIT_16BIT
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,5 +1,7 @@
|
|||||||
#include <WallpaperEngine/Irrlicht/Irrlicht.h>
|
|
||||||
#include <WallpaperEngine/video/renderer.h>
|
#include <WallpaperEngine/video/renderer.h>
|
||||||
|
#include <WallpaperEngine/Irrlicht/CContext.h>
|
||||||
|
|
||||||
|
extern WallpaperEngine::Irrlicht::CContext* IrrlichtContext;
|
||||||
|
|
||||||
namespace WallpaperEngine
|
namespace WallpaperEngine
|
||||||
{
|
{
|
||||||
@ -31,19 +33,19 @@ namespace WallpaperEngine
|
|||||||
znear,
|
znear,
|
||||||
zfar
|
zfar
|
||||||
);
|
);
|
||||||
WallpaperEngine::Irrlicht::camera = WallpaperEngine::Irrlicht::device->getSceneManager ()->addCameraSceneNode (0, position, lookat);
|
s_camera = IrrlichtContext->getDevice ()->getSceneManager ()->addCameraSceneNode (0, position, lookat);
|
||||||
WallpaperEngine::Irrlicht::camera->setProjectionMatrix (orthoProjection);
|
s_camera->setProjectionMatrix (orthoProjection);
|
||||||
|
|
||||||
WallpaperEngine::Irrlicht::driver->setTransform (irr::video::ETS_PROJECTION, orthoProjection);
|
IrrlichtContext->getDevice ()->getVideoDriver ()->setTransform (irr::video::ETS_PROJECTION, orthoProjection);
|
||||||
WallpaperEngine::Irrlicht::driver->setTransform (irr::video::ETS_VIEW, identity);
|
IrrlichtContext->getDevice ()->getVideoDriver ()->setTransform (irr::video::ETS_VIEW, identity);
|
||||||
WallpaperEngine::Irrlicht::driver->setTransform (irr::video::ETS_WORLD, identity);
|
IrrlichtContext->getDevice ()->getVideoDriver ()->setTransform (irr::video::ETS_WORLD, identity);
|
||||||
}
|
}
|
||||||
|
|
||||||
void renderer::render ()
|
void renderer::render ()
|
||||||
{
|
{
|
||||||
if (WallpaperEngine::Irrlicht::driver == nullptr) return;
|
if (IrrlichtContext->getDevice ()->getVideoDriver () == nullptr) return;
|
||||||
|
|
||||||
WallpaperEngine::Irrlicht::driver->beginScene(true, true, irr::video::SColor(0, 0, 0, 0));
|
IrrlichtContext->getDevice ()->getVideoDriver ()->beginScene(true, true, irr::video::SColor(0, 0, 0, 0));
|
||||||
|
|
||||||
std::vector<node*>::const_iterator cur = s_nodes.begin ();
|
std::vector<node*>::const_iterator cur = s_nodes.begin ();
|
||||||
std::vector<node*>::const_iterator end = s_nodes.end ();
|
std::vector<node*>::const_iterator end = s_nodes.end ();
|
||||||
@ -53,9 +55,10 @@ namespace WallpaperEngine
|
|||||||
(*cur)->render ();
|
(*cur)->render ();
|
||||||
}
|
}
|
||||||
|
|
||||||
WallpaperEngine::Irrlicht::driver->endScene ();
|
IrrlichtContext->getDevice ()->getVideoDriver ()->endScene ();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<node*> renderer::s_nodes;
|
std::vector<node*> renderer::s_nodes;
|
||||||
|
irr::scene::ICameraSceneNode* renderer::s_camera;
|
||||||
}
|
}
|
||||||
};
|
};
|
@ -20,6 +20,7 @@ namespace WallpaperEngine
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
static std::vector<node*> s_nodes;
|
static std::vector<node*> s_nodes;
|
||||||
|
static irr::scene::ICameraSceneNode* s_camera;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user