rework on resources system
This commit is contained in:
parent
e1af35f061
commit
ab6c52a3ee
|
@ -7,7 +7,7 @@ panel#background:
|
||||||
|
|
||||||
panel#icos4d:
|
panel#icos4d:
|
||||||
skin:
|
skin:
|
||||||
image: lightness/mouse.png
|
image: /skins/lightness/mouse.png
|
||||||
anchors.left: parent.left
|
anchors.left: parent.left
|
||||||
anchors.top: parent.top
|
anchors.top: parent.top
|
||||||
margin.left: -2
|
margin.left: -2
|
||||||
|
@ -15,7 +15,7 @@ panel#background:
|
||||||
|
|
||||||
panel#mouse:
|
panel#mouse:
|
||||||
skin:
|
skin:
|
||||||
image: lightness/icos4d.png
|
image: /skins/lightness/icos4d.png
|
||||||
anchors.right: parent.right
|
anchors.right: parent.right
|
||||||
anchors.bottom: parent.bottom
|
anchors.bottom: parent.bottom
|
||||||
margin.left: 60
|
margin.left: 60
|
||||||
|
@ -34,7 +34,7 @@ panel#background:
|
||||||
anchors.top: parent.top
|
anchors.top: parent.top
|
||||||
anchors.horizontalCenter: parent.horizontalCenter
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
margin.top: 16
|
margin.top: 16
|
||||||
onClick: UI.load("mainmenu/entergamewindow.yml")
|
onClick: UI.load("entergamewindow.yml")
|
||||||
|
|
||||||
button#accessAccountButton:
|
button#accessAccountButton:
|
||||||
text: Access Account
|
text: Access Account
|
||||||
|
@ -48,14 +48,14 @@ panel#background:
|
||||||
anchors.top: parent.top
|
anchors.top: parent.top
|
||||||
anchors.horizontalCenter: parent.horizontalCenter
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
margin.top: 76
|
margin.top: 76
|
||||||
onClick: UI.load("mainmenu/optionswindow.yml")
|
onClick: UI.load("optionswindow.yml")
|
||||||
|
|
||||||
button#infoButton:
|
button#infoButton:
|
||||||
text: Info
|
text: Info
|
||||||
anchors.top: parent.top
|
anchors.top: parent.top
|
||||||
anchors.horizontalCenter: parent.horizontalCenter
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
margin.top: 106
|
margin.top: 106
|
||||||
onClick: UI.load("mainmenu/infowindow.yml")
|
onClick: UI.load("infowindow.yml")
|
||||||
|
|
||||||
button#exitGameButton:
|
button#exitGameButton:
|
||||||
text: Exit
|
text: Exit
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
-- menu state
|
-- menu state
|
||||||
function onEnterMenuState()
|
function onEnterMenuState()
|
||||||
mainMenu = UI.load("mainmenu/mainmenu.yml")
|
mainMenu = UI.load("mainmenu.yml")
|
||||||
end
|
end
|
||||||
|
|
||||||
function onLeaveMenuState()
|
function onLeaveMenuState()
|
||||||
|
|
|
@ -3,9 +3,9 @@ function autoDestroyParent()
|
||||||
end
|
end
|
||||||
|
|
||||||
function messageBox(title, text)
|
function messageBox(title, text)
|
||||||
local msgBox = UI.load("modules/messagebox/messagebox.yml")
|
local msgBox = UI.load("messagebox.yml")
|
||||||
msgBox.locked = true
|
msgBox.locked = true
|
||||||
msgBox.title = title
|
msgBox.title = title
|
||||||
msgBox:child("textLabel").text = text
|
msgBox:child("textLabel").text = text
|
||||||
msgBox:child("okButton").onClick = autoDestroyParent
|
msgBox:child("okButton").onClick = autoDestroyParentz
|
||||||
end
|
end
|
||||||
|
|
|
@ -35,12 +35,10 @@ bool Configs::load(const std::string& fileName)
|
||||||
if(!g_resources.fileExists(fileName))
|
if(!g_resources.fileExists(fileName))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
std::string fileContents = g_resources.loadTextFile(fileName);
|
std::stringstream fin;
|
||||||
if(!fileContents.size())
|
if(!g_resources.loadFile(fileName, fin))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
std::istringstream fin(fileContents);
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
YAML::Parser parser(fin);
|
YAML::Parser parser(fin);
|
||||||
|
|
||||||
|
|
|
@ -24,6 +24,7 @@
|
||||||
|
|
||||||
#include <prerequisites.h>
|
#include <prerequisites.h>
|
||||||
#include <core/resources.h>
|
#include <core/resources.h>
|
||||||
|
#include <core/platform.h>
|
||||||
|
|
||||||
#include <physfs.h>
|
#include <physfs.h>
|
||||||
|
|
||||||
|
@ -32,6 +33,29 @@ Resources g_resources;
|
||||||
void Resources::init(const char *argv0)
|
void Resources::init(const char *argv0)
|
||||||
{
|
{
|
||||||
PHYSFS_init(argv0);
|
PHYSFS_init(argv0);
|
||||||
|
|
||||||
|
// try to find data directory
|
||||||
|
std::list<std::string> searchPaths;
|
||||||
|
std::string dir;
|
||||||
|
std::string baseDir = PHYSFS_getBaseDir();
|
||||||
|
|
||||||
|
std::list<std::string> possibleDirs;
|
||||||
|
possibleDirs.push_back("data");
|
||||||
|
possibleDirs.push_back(baseDir + "data");
|
||||||
|
possibleDirs.push_back(baseDir + "../data");
|
||||||
|
possibleDirs.push_back(baseDir + "../share/data");
|
||||||
|
possibleDirs.push_back("");
|
||||||
|
|
||||||
|
foreach(dir, possibleDirs)
|
||||||
|
if(g_resources.addToSearchPath(dir))
|
||||||
|
break;
|
||||||
|
|
||||||
|
// setup write directory
|
||||||
|
dir = Platform::getAppUserDir();
|
||||||
|
if(g_resources.setWriteDir(dir))
|
||||||
|
g_resources.addToSearchPath(dir);
|
||||||
|
else
|
||||||
|
logError("ERROR: could not setup write directory");
|
||||||
}
|
}
|
||||||
|
|
||||||
void Resources::terminate()
|
void Resources::terminate()
|
||||||
|
@ -41,59 +65,63 @@ void Resources::terminate()
|
||||||
|
|
||||||
bool Resources::setWriteDir(const std::string& path)
|
bool Resources::setWriteDir(const std::string& path)
|
||||||
{
|
{
|
||||||
bool ret = (bool)PHYSFS_setWriteDir(path.c_str());
|
if(!PHYSFS_setWriteDir(path.c_str()))
|
||||||
|
return false;
|
||||||
if(!ret)
|
return true;
|
||||||
flogError("ERROR: Could not set the path \"%s\" as write directory, file write will not work correctly.", path.c_str());
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Resources::addToSearchPath(const std::string& path, bool insertInFront /*= true*/)
|
bool Resources::addToSearchPath(const std::string& path, bool insertInFront /*= true*/)
|
||||||
{
|
{
|
||||||
if(!PHYSFS_addToSearchPath(path.c_str(), insertInFront ? 0 : 1)) {
|
if(!PHYSFS_addToSearchPath(path.c_str(), insertInFront ? 0 : 1))
|
||||||
flogError("ERROR: Error while adding \"%s\" to resources search path: %s", path.c_str() % PHYSFS_getLastError());
|
|
||||||
return false;
|
return false;
|
||||||
}
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Resources::fileExists(const std::string& filePath)
|
void Resources::addPackagesToSearchPath(const std::string &packagesDirectory, const std::string &packageExtension, bool append)
|
||||||
{
|
{
|
||||||
return PHYSFS_exists(filePath.c_str());
|
auto files = listDirectoryFiles(resolvePath(packagesDirectory));
|
||||||
|
foreach(const std::string& file, files) {
|
||||||
|
if(boost::ends_with(file, packageExtension))
|
||||||
|
addToSearchPath(packagesDirectory + "/" + file, !append);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
uchar *Resources::loadFile(const std::string& fileName, uint *fileSize)
|
bool Resources::fileExists(const std::string& fileName)
|
||||||
{
|
{
|
||||||
PHYSFS_file *file = PHYSFS_openRead(fileName.c_str());
|
return (PHYSFS_exists(resolvePath(fileName).c_str()) && !PHYSFS_isDirectory(resolvePath(fileName).c_str()));
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Resources::directoryExists(const std::string& directoryName)
|
||||||
|
{
|
||||||
|
return (PHYSFS_exists(resolvePath(directoryName).c_str()) && PHYSFS_isDirectory(resolvePath(directoryName).c_str()));
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Resources::loadFile(const std::string& fileName, std::iostream& out)
|
||||||
|
{
|
||||||
|
out.clear(std::ios::goodbit);
|
||||||
|
PHYSFS_file *file = PHYSFS_openRead(resolvePath(fileName).c_str());
|
||||||
if(!file) {
|
if(!file) {
|
||||||
flogError("ERROR: Failed to load file \"%s\": %s", fileName.c_str() % PHYSFS_getLastError());
|
flogError("ERROR: Failed to load file \"%s\": %s", fileName.c_str() % PHYSFS_getLastError());
|
||||||
*fileSize = 0;
|
out.clear(std::ios::failbit);
|
||||||
return NULL;
|
return false;
|
||||||
}
|
} else {
|
||||||
|
int fileSize = PHYSFS_fileLength(file);
|
||||||
*fileSize = PHYSFS_fileLength(file);
|
if(fileSize > 0) {
|
||||||
uchar *buffer = new uchar[*fileSize + 1];
|
char *buffer = new char[fileSize];
|
||||||
PHYSFS_read(file, (void*)buffer, 1, *fileSize);
|
PHYSFS_read(file, (void*)buffer, 1, fileSize);
|
||||||
buffer[*fileSize] = 0;
|
out.write(buffer, fileSize);
|
||||||
|
delete buffer;
|
||||||
|
} else
|
||||||
|
out.clear(std::ios::eofbit);
|
||||||
PHYSFS_close(file);
|
PHYSFS_close(file);
|
||||||
return buffer;
|
out.seekg(0, std::ios::beg);
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string Resources::loadTextFile(const std::string& fileName)
|
|
||||||
{
|
|
||||||
std::string text;
|
|
||||||
uint fileSize;
|
|
||||||
char *buffer = (char *)loadFile(fileName, &fileSize);
|
|
||||||
if(buffer) {
|
|
||||||
text.assign(buffer);
|
|
||||||
delete[] buffer;
|
|
||||||
}
|
|
||||||
return text;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Resources::saveFile(const std::string &fileName, const uchar *data, uint size)
|
bool Resources::saveFile(const std::string &fileName, const uchar *data, uint size)
|
||||||
{
|
{
|
||||||
PHYSFS_file *file = PHYSFS_openWrite(fileName.c_str());
|
PHYSFS_file *file = PHYSFS_openWrite(resolvePath(fileName).c_str());
|
||||||
if(!file) {
|
if(!file) {
|
||||||
flogError("ERROR: Failed to save file \"%s\": %s", fileName.c_str() % PHYSFS_getLastError());
|
flogError("ERROR: Failed to save file \"%s\": %s", fileName.c_str() % PHYSFS_getLastError());
|
||||||
return false;
|
return false;
|
||||||
|
@ -104,15 +132,29 @@ bool Resources::saveFile(const std::string &fileName, const uchar *data, uint si
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Resources::saveTextFile(const std::string &fileName, std::string text)
|
bool Resources::saveFile(const std::string &fileName, std::istream& in)
|
||||||
{
|
{
|
||||||
return saveFile(fileName, (const uchar*)text.c_str(), text.size());
|
std::streampos oldPos = in.tellg();
|
||||||
|
in.seekg(0, std::ios::end);
|
||||||
|
std::streampos size = in.tellg();
|
||||||
|
in.seekg(0, std::ios::beg);
|
||||||
|
char *buffer = new char[size];
|
||||||
|
in.read(buffer, size);
|
||||||
|
bool ret = saveFile(fileName, (const uchar*)buffer, size);
|
||||||
|
delete[] buffer;
|
||||||
|
in.seekg(oldPos, std::ios::beg);
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::list<std::string> Resources::getDirectoryFiles(const std::string& directory)
|
bool Resources::deleteFile(const std::string& fileName)
|
||||||
|
{
|
||||||
|
return PHYSFS_delete(resolvePath(fileName).c_str()) != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::list<std::string> Resources::listDirectoryFiles(const std::string& directoryPath)
|
||||||
{
|
{
|
||||||
std::list<std::string> files;
|
std::list<std::string> files;
|
||||||
char **rc = PHYSFS_enumerateFiles(directory.c_str());
|
char **rc = PHYSFS_enumerateFiles(resolvePath(directoryPath).c_str());
|
||||||
|
|
||||||
for(char **i = rc; *i != NULL; i++)
|
for(char **i = rc; *i != NULL; i++)
|
||||||
files.push_back(*i);
|
files.push_back(*i);
|
||||||
|
@ -120,3 +162,31 @@ std::list<std::string> Resources::getDirectoryFiles(const std::string& directory
|
||||||
PHYSFS_freeList(rc);
|
PHYSFS_freeList(rc);
|
||||||
return files;
|
return files;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Resources::pushCurrentPath(const std::string ¤tPath)
|
||||||
|
{
|
||||||
|
m_currentPaths.push(currentPath);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Resources::popCurrentPath()
|
||||||
|
{
|
||||||
|
m_currentPaths.pop();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string Resources::resolvePath(const std::string& path)
|
||||||
|
{
|
||||||
|
std::string fullPath;
|
||||||
|
if(boost::starts_with(path, "/"))
|
||||||
|
fullPath = path.substr(1);
|
||||||
|
else {
|
||||||
|
if(m_currentPaths.size() > 0) {
|
||||||
|
std::string currentPath = m_currentPaths.top();
|
||||||
|
if(currentPath.length() > 0)
|
||||||
|
fullPath += currentPath + "/";
|
||||||
|
}
|
||||||
|
fullPath += path;
|
||||||
|
}
|
||||||
|
return fullPath;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -35,36 +35,32 @@ public:
|
||||||
void init(const char *argv0);
|
void init(const char *argv0);
|
||||||
void terminate();
|
void terminate();
|
||||||
|
|
||||||
/// Sets the write directory
|
/// Set output files dir
|
||||||
bool setWriteDir(const std::string &path);
|
bool setWriteDir(const std::string &path);
|
||||||
|
|
||||||
/// Adds a directory or zip archive to the search path
|
/// Add an package or directory to the search path
|
||||||
bool addToSearchPath(const std::string& path, bool insertInFront = true);
|
bool addToSearchPath(const std::string& path, bool insertInFront = true);
|
||||||
|
/// Add all packages from a directory
|
||||||
|
void addPackagesToSearchPath(const std::string &packagesDirectory, const std::string &packageExtension, bool append);
|
||||||
|
|
||||||
/// Checks whether the given file exists in the search path
|
bool fileExists(const std::string& fileName);
|
||||||
bool fileExists(const std::string& filePath);
|
bool directoryExists(const std::string& directoryName);
|
||||||
|
|
||||||
/// Searches for zip files and adds them to the search path
|
bool loadFile(const std::string& fileName, std::iostream& out);
|
||||||
void searchAndAddArchives(const std::string &path,
|
|
||||||
const std::string &ext,
|
|
||||||
const bool append);
|
|
||||||
|
|
||||||
/** Load a file by allocating a buffer and filling it with the file contents
|
|
||||||
* where fileSize will be set to the file size.
|
|
||||||
* The returned buffer must be freed with delete[]. */
|
|
||||||
uchar *loadFile(const std::string &fileName, uint *fileSize);
|
|
||||||
|
|
||||||
/// Loads a text file into a std::string
|
|
||||||
std::string loadTextFile(const std::string &fileName);
|
|
||||||
|
|
||||||
/// Save a file into write directory
|
|
||||||
bool saveFile(const std::string& fileName, const uchar *data, uint size);
|
bool saveFile(const std::string& fileName, const uchar *data, uint size);
|
||||||
|
bool saveFile(const std::string& fileName, std::istream& in);
|
||||||
|
|
||||||
/// Save a text file into write directory
|
bool deleteFile(const std::string& fileName);
|
||||||
bool saveTextFile(const std::string &fileName, std::string text);
|
|
||||||
|
|
||||||
/// Get a list with all files in a directory
|
std::list<std::string> listDirectoryFiles(const std::string& directoryPath = "");
|
||||||
std::list<std::string> getDirectoryFiles(const std::string& directory);
|
|
||||||
|
void pushCurrentPath(const std::string ¤tPath);
|
||||||
|
void popCurrentPath();
|
||||||
|
std::string resolvePath(const std::string& path);
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::stack<std::string> m_currentPaths;
|
||||||
};
|
};
|
||||||
|
|
||||||
extern Resources g_resources;
|
extern Resources g_resources;
|
||||||
|
|
|
@ -68,13 +68,12 @@ void Font::calculateGlyphsWidthsAutomatically(const Size& glyphSize)
|
||||||
|
|
||||||
bool Font::load(const std::string& file)
|
bool Font::load(const std::string& file)
|
||||||
{
|
{
|
||||||
std::string fileContents = g_resources.loadTextFile(file);
|
std::stringstream fin;
|
||||||
if(!fileContents.size()) {
|
if(!g_resources.loadFile(file, fin)) {
|
||||||
flogError("ERROR: Coult not load font file \"%s", file.c_str());
|
flogError("ERROR: Coult not load font file \"%s", file.c_str());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::istringstream fin(fileContents);
|
|
||||||
std::string textureName;
|
std::string textureName;
|
||||||
Size glyphSize;
|
Size glyphSize;
|
||||||
|
|
||||||
|
@ -94,7 +93,7 @@ bool Font::load(const std::string& file)
|
||||||
m_glyphSpacing = yamlRead(doc, "glyph spacing", Size(0,0));
|
m_glyphSpacing = yamlRead(doc, "glyph spacing", Size(0,0));
|
||||||
|
|
||||||
// load texture
|
// load texture
|
||||||
m_texture = g_textures.get("fonts/" + textureName);
|
m_texture = g_textures.get(textureName);
|
||||||
if(!m_texture) {
|
if(!m_texture) {
|
||||||
flogError("ERROR: Failed to load image for font file \"%s\"", file.c_str());
|
flogError("ERROR: Failed to load image for font file \"%s\"", file.c_str());
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -30,17 +30,21 @@ Fonts g_fonts;
|
||||||
|
|
||||||
void Fonts::init()
|
void Fonts::init()
|
||||||
{
|
{
|
||||||
|
g_resources.pushCurrentPath("fonts");
|
||||||
|
|
||||||
// load all fonts
|
// load all fonts
|
||||||
std::list<std::string> files = g_resources.getDirectoryFiles("fonts");
|
std::list<std::string> files = g_resources.listDirectoryFiles();
|
||||||
foreach(const std::string& file, files) {
|
foreach(const std::string& file, files) {
|
||||||
if(boost::ends_with(file, ".yml")) {
|
if(boost::ends_with(file, ".yml")) {
|
||||||
std::string name = file;
|
std::string name = file;
|
||||||
boost::erase_first(name, ".yml");
|
boost::erase_first(name, ".yml");
|
||||||
FontPtr font(new Font(name));
|
FontPtr font(new Font(name));
|
||||||
if(font->load("fonts/" + file))
|
if(font->load(file))
|
||||||
m_fonts.push_back(font);
|
m_fonts.push_back(font);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
g_resources.popCurrentPath();
|
||||||
}
|
}
|
||||||
|
|
||||||
FontPtr Fonts::get(const std::string& fontName)
|
FontPtr Fonts::get(const std::string& fontName)
|
||||||
|
|
|
@ -28,12 +28,12 @@
|
||||||
#include <util/apngloader.h>
|
#include <util/apngloader.h>
|
||||||
#include "animatedtexture.h"
|
#include "animatedtexture.h"
|
||||||
|
|
||||||
TexturePtr TextureLoader::loadPNG(uchar *fileData, uint fileSize)
|
TexturePtr TextureLoader::loadPNG(std::stringstream& file)
|
||||||
{
|
{
|
||||||
TexturePtr texture;
|
TexturePtr texture;
|
||||||
|
|
||||||
apng_data apng;
|
apng_data apng;
|
||||||
if(load_apng(fileData, fileSize, &apng) == 0) {
|
if(load_apng(file, &apng) == 0) {
|
||||||
if(apng.num_frames > 1) { // animated texture
|
if(apng.num_frames > 1) { // animated texture
|
||||||
uchar *framesdata = apng.pdata + (apng.first_frame * apng.width * apng.height * apng.bpp);
|
uchar *framesdata = apng.pdata + (apng.first_frame * apng.width * apng.height * apng.bpp);
|
||||||
texture = TexturePtr(new AnimatedTexture(apng.width, apng.height, apng.bpp, apng.num_frames, framesdata, (int*)apng.frames_delay));
|
texture = TexturePtr(new AnimatedTexture(apng.width, apng.height, apng.bpp, apng.num_frames, framesdata, (int*)apng.frames_delay));
|
||||||
|
|
|
@ -32,7 +32,7 @@ class TextureLoader
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
/// Load a png textures
|
/// Load a png textures
|
||||||
static TexturePtr loadPNG(uchar *fileData, uint fileSize);
|
static TexturePtr loadPNG(std::stringstream& file);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // TEXTURELOADER_H
|
#endif // TEXTURELOADER_H
|
||||||
|
|
|
@ -52,19 +52,17 @@ TexturePtr Textures::get(const std::string& textureFile)
|
||||||
}
|
}
|
||||||
|
|
||||||
// load texture file data
|
// load texture file data
|
||||||
uint fileSize;
|
std::stringstream fin;
|
||||||
uchar *textureFileData = g_resources.loadFile(textureFile, &fileSize);
|
if(!g_resources.loadFile(textureFile, fin)) {
|
||||||
if(!textureFileData) {
|
|
||||||
flogError("ERROR: Unable to load texture %s, file could not be read.", textureFile.c_str());
|
flogError("ERROR: Unable to load texture %s, file could not be read.", textureFile.c_str());
|
||||||
return texture;
|
return texture;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// load the texture
|
// load the texture
|
||||||
texture = TexturePtr(TextureLoader::loadPNG(textureFileData, fileSize));
|
texture = TexturePtr(TextureLoader::loadPNG(fin));
|
||||||
if(!texture)
|
if(!texture)
|
||||||
flogError("ERROR: Unable to load texture %s", textureFile.c_str());
|
flogError("ERROR: Unable to load texture %s", textureFile.c_str());
|
||||||
delete[] textureFileData;
|
|
||||||
}
|
}
|
||||||
return texture;
|
return texture;
|
||||||
}
|
}
|
||||||
|
|
|
@ -834,7 +834,7 @@ bool Platform::isWindowMaximized()
|
||||||
std::string Platform::getAppUserDir()
|
std::string Platform::getAppUserDir()
|
||||||
{
|
{
|
||||||
std::stringstream sdir;
|
std::stringstream sdir;
|
||||||
sdir << PHYSFS_getUserDir() << "/." << x11.appName << "/";
|
sdir << PHYSFS_getUserDir() << "." << x11.appName;
|
||||||
if((mkdir(sdir.str().c_str(), S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH) != 0) && (errno != EEXIST))
|
if((mkdir(sdir.str().c_str(), S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH) != 0) && (errno != EEXIST))
|
||||||
flogError("ERROR: Couldn't create directory for saving configuration file. (%s)", sdir.str().c_str());
|
flogError("ERROR: Couldn't create directory for saving configuration file. (%s)", sdir.str().c_str());
|
||||||
return sdir.str();
|
return sdir.str();
|
||||||
|
|
|
@ -55,6 +55,7 @@ typedef int8_t int8;
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
#include <stack>
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <list>
|
#include <list>
|
||||||
|
|
|
@ -98,7 +98,7 @@ int lua_UI_load()
|
||||||
|
|
||||||
UIElementPtr element;
|
UIElementPtr element;
|
||||||
if(parent)
|
if(parent)
|
||||||
element = UILoader::loadFile(uiFile.c_str(), parent);
|
element = g_uiLoader.loadFromYAML(uiFile.c_str(), parent);
|
||||||
else
|
else
|
||||||
g_lua.reportErrorWithTraceback("invalid parent container");
|
g_lua.reportErrorWithTraceback("invalid parent container");
|
||||||
|
|
||||||
|
|
|
@ -54,9 +54,9 @@ void LuaScript::terminate()
|
||||||
|
|
||||||
void LuaScript::loadAllModules()
|
void LuaScript::loadAllModules()
|
||||||
{
|
{
|
||||||
std::list<std::string> modules = g_resources.getDirectoryFiles("modules");
|
std::list<std::string> modules = g_resources.listDirectoryFiles("modules");
|
||||||
foreach(const std::string& module, modules) {
|
foreach(const std::string& module, modules) {
|
||||||
std::list<std::string> moduleFiles = g_resources.getDirectoryFiles(std::string("modules/") + module);
|
std::list<std::string> moduleFiles = g_resources.listDirectoryFiles("modules/" + module);
|
||||||
foreach(const std::string& moduleFile, moduleFiles) {
|
foreach(const std::string& moduleFile, moduleFiles) {
|
||||||
if(boost::ends_with(moduleFile, ".lua"))
|
if(boost::ends_with(moduleFile, ".lua"))
|
||||||
loadFile(std::string("modules/") + module + "/" + moduleFile);
|
loadFile(std::string("modules/") + module + "/" + moduleFile);
|
||||||
|
@ -66,42 +66,24 @@ void LuaScript::loadAllModules()
|
||||||
|
|
||||||
bool LuaScript::loadFile(const std::string& fileName)
|
bool LuaScript::loadFile(const std::string& fileName)
|
||||||
{
|
{
|
||||||
if(!g_resources.fileExists(fileName)) {
|
std::stringstream fin;
|
||||||
|
if(g_resources.loadFile(fileName, fin))
|
||||||
|
return loadBuffer(fin.str(), fileName);
|
||||||
|
else
|
||||||
flogError("ERROR: script file '%s' doesn't exist", fileName.c_str());
|
flogError("ERROR: script file '%s' doesn't exist", fileName.c_str());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
std::string fileContents = g_resources.loadTextFile(fileName);
|
|
||||||
return loadBuffer(fileContents, fileName);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool LuaScript::loadBuffer(const std::string& text, const std::string& what)
|
bool LuaScript::loadBuffer(const std::string& text, const std::string& what)
|
||||||
{
|
{
|
||||||
// load buffer
|
if(loadBufferAsFunction(text, what) && callFunction())
|
||||||
int ret = luaL_loadbuffer(L, text.c_str(), text.length(), what.c_str());
|
|
||||||
if(ret != 0){
|
|
||||||
reportError(popString());
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// check if is loaded as a function
|
|
||||||
if(lua_isfunction(L, -1) == 0) {
|
|
||||||
pop();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// execute it
|
|
||||||
ret = lua_pcall(L, 0, 0, 0);
|
|
||||||
if(ret != 0){
|
|
||||||
reportError(popString());
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool LuaScript::loadBufferAsFunction(const std::string& text, const std::string& what)
|
bool LuaScript::loadBufferAsFunction(const std::string& text, const std::string& what)
|
||||||
{
|
{
|
||||||
int ret = luaL_loadbuffer(L, text.c_str(), text.length(), what.c_str());
|
int ret = luaL_loadbuffer(L, text.c_str(), text.length(), ("@" + what).c_str());
|
||||||
if(ret != 0){
|
if(ret != 0){
|
||||||
reportError(popString());
|
reportError(popString());
|
||||||
return false;
|
return false;
|
||||||
|
@ -111,7 +93,6 @@ bool LuaScript::loadBufferAsFunction(const std::string& text, const std::string&
|
||||||
pop();
|
pop();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -145,9 +126,17 @@ int LuaScript::getStackSize()
|
||||||
|
|
||||||
void LuaScript::insert(int index)
|
void LuaScript::insert(int index)
|
||||||
{
|
{
|
||||||
|
if(index != -1)
|
||||||
lua_insert(L, index);
|
lua_insert(L, index);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void LuaScript::swap(int index)
|
||||||
|
{
|
||||||
|
insert(index);
|
||||||
|
pushValue(index+1);
|
||||||
|
remove(index);
|
||||||
|
}
|
||||||
|
|
||||||
void LuaScript::remove(int index)
|
void LuaScript::remove(int index)
|
||||||
{
|
{
|
||||||
lua_remove(L, index);
|
lua_remove(L, index);
|
||||||
|
@ -390,23 +379,61 @@ void LuaScript::pushRef(int ref)
|
||||||
lua_rawgeti(L, LUA_REGISTRYINDEX, ref);
|
lua_rawgeti(L, LUA_REGISTRYINDEX, ref);
|
||||||
}
|
}
|
||||||
|
|
||||||
void LuaScript::callFunction(int numArgs)
|
std::string LuaScript::getFunctionSourcePath()
|
||||||
{
|
{
|
||||||
int size = lua_gettop(L);
|
std::string path;
|
||||||
int errorIndex = -(numArgs + 2);
|
|
||||||
lua_pushcfunction(L, &LuaScript::luaErrorHandler);
|
|
||||||
lua_insert(L, errorIndex);
|
|
||||||
|
|
||||||
int ret = lua_pcall(L, numArgs, 0, errorIndex);
|
lua_Debug ar;
|
||||||
if(ret != 0) {
|
memset(&ar, 0, sizeof(ar));
|
||||||
reportError(popString());
|
lua_getinfo(L, ">Sn", &ar);
|
||||||
|
|
||||||
|
// c function, we must get information of level above
|
||||||
|
if(strcmp("C", ar.what) == 0) {
|
||||||
|
memset(&ar, 0, sizeof(ar));
|
||||||
|
if(lua_getstack(L, 1, &ar) == 1) {
|
||||||
|
lua_getinfo(L, "f", &ar);
|
||||||
|
return getFunctionSourcePath();
|
||||||
}
|
}
|
||||||
|
|
||||||
// pop error func
|
} else {
|
||||||
lua_pop(L, 1);
|
if(ar.source) {
|
||||||
|
std::string source = ar.source;
|
||||||
|
std::size_t pos = source.find_last_of('/');
|
||||||
|
if(source[0] == '@' && pos != std::string::npos)
|
||||||
|
path = source.substr(1, pos - 1);
|
||||||
|
} else {
|
||||||
|
logError("no source");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return path;
|
||||||
|
}
|
||||||
|
|
||||||
if(lua_gettop(L) != size - numArgs - 1)
|
bool LuaScript::callFunction(int numArgs, int numRets)
|
||||||
|
{
|
||||||
|
pushValue(-numArgs - 1);
|
||||||
|
g_resources.pushCurrentPath(getFunctionSourcePath());
|
||||||
|
|
||||||
|
int size = getStackSize();
|
||||||
|
int errorIndex = -numArgs - 2;
|
||||||
|
lua_pushcfunction(L, &LuaScript::luaErrorHandler);
|
||||||
|
insert(errorIndex);
|
||||||
|
|
||||||
|
int ret = lua_pcall(L, numArgs, numRets, errorIndex);
|
||||||
|
if(ret != 0) {
|
||||||
|
reportError(popString());
|
||||||
|
pop(); // pop error func
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
remove(-numRets - 1); // pop error func
|
||||||
|
|
||||||
|
if(getStackSize() != size - numArgs - 1 + numRets) {
|
||||||
reportError("stack size changed!");
|
reportError("stack size changed!");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
g_resources.popCurrentPath();
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void LuaScript::callModuleField(const std::string& module, const std::string& field)
|
void LuaScript::callModuleField(const std::string& module, const std::string& field)
|
||||||
|
@ -581,8 +608,9 @@ int LuaScript::luaPackageLoader(lua_State* L)
|
||||||
std::string fileName = lua_tostring(L, -1);
|
std::string fileName = lua_tostring(L, -1);
|
||||||
fileName += ".lua";
|
fileName += ".lua";
|
||||||
if(g_resources.fileExists(fileName)) {
|
if(g_resources.fileExists(fileName)) {
|
||||||
std::string fileContents = g_resources.loadTextFile(fileName);
|
std::stringstream fin;
|
||||||
luaL_loadbuffer(L, fileContents.c_str(), fileContents.length(), fileName.c_str());
|
if(g_resources.loadFile(fileName, fin))
|
||||||
|
luaL_loadbuffer(L, fin.str().c_str(), fin.str().length(), fileName.c_str());
|
||||||
} else {
|
} else {
|
||||||
lua_pushfstring(L, "\n\tcould not load lua script " LUA_QS, fileName.c_str());
|
lua_pushfstring(L, "\n\tcould not load lua script " LUA_QS, fileName.c_str());
|
||||||
}
|
}
|
||||||
|
@ -601,16 +629,8 @@ int LuaScript::luaIndexMetaMethod(lua_State* L)
|
||||||
if(!lua_isnil(L, -1)) {
|
if(!lua_isnil(L, -1)) {
|
||||||
lua_remove(L, -2); // get_method, obj
|
lua_remove(L, -2); // get_method, obj
|
||||||
lua_insert(L, -2); // obj, get_method
|
lua_insert(L, -2); // obj, get_method
|
||||||
lua_pushcfunction(L, &LuaScript::luaErrorHandler); // errorfunc, obj,get_method
|
if(!g_lua.callFunction(1, 1))
|
||||||
lua_insert(L, -3); // obj, get_method, errorfunc
|
lua_pushnil(L);
|
||||||
int ret = lua_pcall(L, 1, 1, -3); // ret, errorfunc
|
|
||||||
if(ret != 0) {
|
|
||||||
g_lua.reportError(g_lua.popString()); // errofunc
|
|
||||||
lua_pop(L, 1); // (empty)
|
|
||||||
lua_pushnil(L); // nil
|
|
||||||
} else {
|
|
||||||
lua_remove(L, -2); // ret
|
|
||||||
}
|
|
||||||
return 1;
|
return 1;
|
||||||
} else {
|
} else {
|
||||||
lua_pop(L, 1); // mt, obj
|
lua_pop(L, 1); // mt, obj
|
||||||
|
@ -618,7 +638,7 @@ int LuaScript::luaIndexMetaMethod(lua_State* L)
|
||||||
lua_getfield(L, -1, key.c_str()); // method, methods, mt, obj
|
lua_getfield(L, -1, key.c_str()); // method, methods, mt, obj
|
||||||
lua_remove(L, -2); // method, mt, obj
|
lua_remove(L, -2); // method, mt, obj
|
||||||
if(!lua_isnil(L, -1)) {
|
if(!lua_isnil(L, -1)) {
|
||||||
lua_insert(L, -3); // obj, mt, method
|
lua_insert(L, -3); // mt, obj, method
|
||||||
lua_pop(L, 2); // method
|
lua_pop(L, 2); // method
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -654,12 +674,7 @@ int LuaScript::luaNewIndexMetaMethod(lua_State* L)
|
||||||
if(!lua_isnil(L, -1)) {
|
if(!lua_isnil(L, -1)) {
|
||||||
lua_remove(L, -2); // set_method, value, obj
|
lua_remove(L, -2); // set_method, value, obj
|
||||||
lua_insert(L, -3); // value, obj, set_method
|
lua_insert(L, -3); // value, obj, set_method
|
||||||
lua_pushcfunction(L, &LuaScript::luaErrorHandler); // errorfunc, value, obj, set_method
|
g_lua.callFunction(2);
|
||||||
lua_insert(L, -4); // value, obj, set_method, errorfunc
|
|
||||||
int ret = lua_pcall(L, 2, 0, -4); // errorfunc
|
|
||||||
if(ret != 0)
|
|
||||||
g_lua.reportError(g_lua.popString()); // errofunc
|
|
||||||
lua_pop(L, 1); // (empty)
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
lua_pop(L, 2); // mt, value, obj
|
lua_pop(L, 2); // mt, value, obj
|
||||||
|
|
|
@ -52,6 +52,7 @@ public:
|
||||||
|
|
||||||
int getStackSize();
|
int getStackSize();
|
||||||
void insert(int index);
|
void insert(int index);
|
||||||
|
void swap(int index);
|
||||||
void remove(int index);
|
void remove(int index);
|
||||||
bool next(int index = -2);
|
bool next(int index = -2);
|
||||||
void releaseRef(int ref);
|
void releaseRef(int ref);
|
||||||
|
@ -103,7 +104,9 @@ public:
|
||||||
void pushValue(int index = -1);
|
void pushValue(int index = -1);
|
||||||
void pushRef(int ref);
|
void pushRef(int ref);
|
||||||
|
|
||||||
void callFunction(int numArgs = 0);
|
std::string getFunctionSourcePath();
|
||||||
|
|
||||||
|
bool callFunction(int numArgs = 0, int numRets = 0);
|
||||||
void callModuleField(const std::string& module, const std::string& field);
|
void callModuleField(const std::string& module, const std::string& field);
|
||||||
|
|
||||||
typedef int (*LuaCFunction)();
|
typedef int (*LuaCFunction)();
|
||||||
|
|
|
@ -69,7 +69,7 @@ ImagePtr UIElementSkin::loadImage(const YAML::Node& node)
|
||||||
std::string textureName = yamlRead(cnode, "source", std::string());
|
std::string textureName = yamlRead(cnode, "source", std::string());
|
||||||
|
|
||||||
if(!textureName.empty())
|
if(!textureName.empty())
|
||||||
texture = g_textures.get("skins/" + textureName);
|
texture = g_textures.get(textureName);
|
||||||
else
|
else
|
||||||
texture = g_uiSkins.getDefaultTexture();
|
texture = g_uiSkins.getDefaultTexture();
|
||||||
|
|
||||||
|
@ -89,7 +89,7 @@ ImagePtr UIElementSkin::loadImage(const YAML::Node& node)
|
||||||
if(!image)
|
if(!image)
|
||||||
logError(yamlErrorDesc(cnode, "failed to load bordered image"));
|
logError(yamlErrorDesc(cnode, "failed to load bordered image"));
|
||||||
} else if(yamlHasValue(node, "image")) {
|
} else if(yamlHasValue(node, "image")) {
|
||||||
texture = g_textures.get("skins/" + yamlRead<std::string>(node, "image"));
|
texture = g_textures.get(yamlRead<std::string>(node, "image"));
|
||||||
if(texture)
|
if(texture)
|
||||||
image = ImagePtr(new Image(texture));
|
image = ImagePtr(new Image(texture));
|
||||||
if(!m_defaultSize.isValid())
|
if(!m_defaultSize.isValid())
|
||||||
|
|
|
@ -30,6 +30,8 @@
|
||||||
#include <script/luafunctions.h>
|
#include <script/luafunctions.h>
|
||||||
#include "uianchorlayout.h"
|
#include "uianchorlayout.h"
|
||||||
|
|
||||||
|
UILoader g_uiLoader;
|
||||||
|
|
||||||
UIElementPtr UILoader::createElementFromId(const std::string& id)
|
UIElementPtr UILoader::createElementFromId(const std::string& id)
|
||||||
{
|
{
|
||||||
UIElementPtr element;
|
UIElementPtr element;
|
||||||
|
@ -65,20 +67,15 @@ UIElementPtr UILoader::createElementFromId(const std::string& id)
|
||||||
return element;
|
return element;
|
||||||
}
|
}
|
||||||
|
|
||||||
UIElementPtr UILoader::loadFile(const std::string& file, const UIContainerPtr& parent)
|
UIElementPtr UILoader::loadFromYAML(std::string filePath, const UIContainerPtr& parent)
|
||||||
{
|
{
|
||||||
// try to find the file
|
std::stringstream fin;
|
||||||
std::string filePath = "modules/" + file;
|
if(!g_resources.loadFile(filePath, fin)) {
|
||||||
if(!g_resources.fileExists(filePath))
|
flogError("ERROR: Could not load ui file \"%s", filePath.c_str());
|
||||||
filePath = "addons/" + file;
|
|
||||||
if(!g_resources.fileExists(filePath))
|
|
||||||
filePath = file;
|
|
||||||
if(!g_resources.fileExists(filePath)) {
|
|
||||||
flogError("ERROR: Could not load ui file \"%s", file.c_str());
|
|
||||||
return UIElementPtr();
|
return UIElementPtr();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::istringstream fin(g_resources.loadTextFile(filePath));
|
m_currentFile = filePath;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
YAML::Parser parser(fin);
|
YAML::Parser parser(fin);
|
||||||
|
@ -110,7 +107,7 @@ UIElementPtr UILoader::loadFile(const std::string& file, const UIContainerPtr& p
|
||||||
element->onLoad();
|
element->onLoad();
|
||||||
return element;
|
return element;
|
||||||
} catch (YAML::Exception& e) {
|
} catch (YAML::Exception& e) {
|
||||||
flogError("ERROR: Failed to load ui file \"%s\":\n %s", file.c_str() % e.what());
|
flogError("ERROR: Failed to load ui file \"%s\":\n %s", filePath.c_str() % e.what());
|
||||||
}
|
}
|
||||||
|
|
||||||
return UIElementPtr();
|
return UIElementPtr();
|
||||||
|
@ -208,7 +205,7 @@ void UILoader::loadElement(const UIElementPtr& element, const YAML::Node& node)
|
||||||
// load events
|
// load events
|
||||||
if(yamlHasValue(node, "onLoad")) {
|
if(yamlHasValue(node, "onLoad")) {
|
||||||
const YAML::Node& cnode = node["onLoad"];
|
const YAML::Node& cnode = node["onLoad"];
|
||||||
if(g_lua.loadBufferAsFunction(yamlRead<std::string>(cnode), element->getId() + ":onLoad"))
|
if(g_lua.loadBufferAsFunction(yamlRead<std::string>(cnode), getElementSourceDesc(element, "onLoad")))
|
||||||
g_lua.setScriptableField(element, "onLoad");
|
g_lua.setScriptableField(element, "onLoad");
|
||||||
else
|
else
|
||||||
logError(yamlErrorDesc(cnode, "failed to parse inline lua script"));
|
logError(yamlErrorDesc(cnode, "failed to parse inline lua script"));
|
||||||
|
@ -216,7 +213,7 @@ void UILoader::loadElement(const UIElementPtr& element, const YAML::Node& node)
|
||||||
|
|
||||||
if(yamlHasValue(node, "onDestroy")) {
|
if(yamlHasValue(node, "onDestroy")) {
|
||||||
const YAML::Node& cnode = node["onDestroy"];
|
const YAML::Node& cnode = node["onDestroy"];
|
||||||
if(g_lua.loadBufferAsFunction(yamlRead<std::string>(cnode), element->getId() + ":onDestroy"))
|
if(g_lua.loadBufferAsFunction(yamlRead<std::string>(cnode), getElementSourceDesc(element, "onDestroy")))
|
||||||
g_lua.setScriptableField(element, "onDestroy");
|
g_lua.setScriptableField(element, "onDestroy");
|
||||||
else
|
else
|
||||||
logError(yamlErrorDesc(cnode, "failed to parse inline lua script"));
|
logError(yamlErrorDesc(cnode, "failed to parse inline lua script"));
|
||||||
|
@ -273,9 +270,19 @@ void UILoader::loadButton(const UIButtonPtr& button, const YAML::Node& node)
|
||||||
// set on click event
|
// set on click event
|
||||||
if(yamlHasValue(node, "onClick")) {
|
if(yamlHasValue(node, "onClick")) {
|
||||||
const YAML::Node& cnode = node["onClick"];
|
const YAML::Node& cnode = node["onClick"];
|
||||||
if(g_lua.loadBufferAsFunction(yamlRead<std::string>(cnode), button->getId() + ":onClick"))
|
if(g_lua.loadBufferAsFunction(yamlRead<std::string>(cnode), getElementSourceDesc(button, "onClick")))
|
||||||
g_lua.setScriptableField(button, "onClick");
|
g_lua.setScriptableField(button, "onClick");
|
||||||
else
|
else
|
||||||
logError(yamlErrorDesc(cnode, "failed to parse inline lua script"));
|
logError(yamlErrorDesc(cnode, "failed to parse inline lua script"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string UILoader::getElementSourceDesc(const UIElementPtr& element, const std::string& key)
|
||||||
|
{
|
||||||
|
std::string desc;
|
||||||
|
desc += g_resources.resolvePath(m_currentFile) + ":" + element->getId();
|
||||||
|
if(key.length() > 0)
|
||||||
|
desc += "[" + key + "]";
|
||||||
|
return desc;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -34,26 +34,32 @@ class UILoader
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
/// Loads an UIElement and it's children from a YAML file
|
/// Loads an UIElement and it's children from a YAML file
|
||||||
static UIElementPtr loadFile(const std::string& file, const UIContainerPtr& parent = UIContainer::getRoot());
|
UIElementPtr loadFromYAML(std::string filePath, const UIContainerPtr& parent = UIContainer::getRoot());
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/// Detect element type and create it
|
/// Detect element type and create it
|
||||||
static UIElementPtr createElementFromId(const std::string& id);
|
UIElementPtr createElementFromId(const std::string& id);
|
||||||
|
|
||||||
/// Populate container children from a YAML node
|
/// Populate container children from a YAML node
|
||||||
static void populateContainer(const UIContainerPtr& parent, const YAML::Node& node);
|
void populateContainer(const UIContainerPtr& parent, const YAML::Node& node);
|
||||||
|
|
||||||
/// Load element and its children from a YAML node
|
/// Load element and its children from a YAML node
|
||||||
static void loadElements(const UIElementPtr& parent, const YAML::Node& node);
|
void loadElements(const UIElementPtr& parent, const YAML::Node& node);
|
||||||
|
|
||||||
/// Load element proprieties from a YAML node
|
/// Load element proprieties from a YAML node
|
||||||
static void loadElement(const UIElementPtr& element, const YAML::Node& node);
|
void loadElement(const UIElementPtr& element, const YAML::Node& node);
|
||||||
|
|
||||||
/// Load anchor from a YAML node
|
/// Load anchor from a YAML node
|
||||||
static void loadElementAnchor(const UIElementPtr& anchoredElement, UI::AnchorPoint anchoredEdge, const YAML::Node& node);
|
void loadElementAnchor(const UIElementPtr& anchoredElement, UI::AnchorPoint anchoredEdge, const YAML::Node& node);
|
||||||
|
|
||||||
// specific elements loading
|
// specific elements loading
|
||||||
static void loadButton(const UIButtonPtr& button, const YAML::Node& node);
|
void loadButton(const UIButtonPtr& button, const YAML::Node& node);
|
||||||
|
|
||||||
|
std::string getElementSourceDesc(const UIElementPtr& element, const std::string& key = "");
|
||||||
|
|
||||||
|
std::string m_currentFile;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
extern UILoader g_uiLoader;
|
||||||
|
|
||||||
#endif // UILOADER_H
|
#endif // UILOADER_H
|
||||||
|
|
|
@ -35,13 +35,13 @@
|
||||||
|
|
||||||
UISkins g_uiSkins;
|
UISkins g_uiSkins;
|
||||||
|
|
||||||
void UISkins::load(const std::string& skinsFile)
|
void UISkins::load(const std::string& skinName)
|
||||||
{
|
{
|
||||||
std::string fileContents = g_resources.loadTextFile(skinsFile);
|
g_resources.pushCurrentPath("skins");
|
||||||
if(!fileContents.size())
|
|
||||||
flogFatal("FATAL ERROR: Could not load skin file \"%s", skinsFile.c_str());
|
|
||||||
|
|
||||||
std::istringstream fin(fileContents);
|
std::stringstream fin;
|
||||||
|
if(!g_resources.loadFile(skinName + ".yml", fin))
|
||||||
|
flogFatal("FATAL ERROR: Could not load skin \"%s", skinName.c_str());
|
||||||
|
|
||||||
try {
|
try {
|
||||||
YAML::Parser parser(fin);
|
YAML::Parser parser(fin);
|
||||||
|
@ -57,7 +57,7 @@ void UISkins::load(const std::string& skinsFile)
|
||||||
|
|
||||||
std::string defaultTextureName = yamlRead(doc, "default texture", std::string());
|
std::string defaultTextureName = yamlRead(doc, "default texture", std::string());
|
||||||
if(!defaultTextureName.empty())
|
if(!defaultTextureName.empty())
|
||||||
m_defaultTexture = g_textures.get("skins/" + defaultTextureName);
|
m_defaultTexture = g_textures.get(defaultTextureName);
|
||||||
|
|
||||||
{
|
{
|
||||||
const YAML::Node& node = doc["buttons"];
|
const YAML::Node& node = doc["buttons"];
|
||||||
|
@ -133,8 +133,10 @@ void UISkins::load(const std::string& skinsFile)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (YAML::Exception& e) {
|
} catch (YAML::Exception& e) {
|
||||||
flogFatal("FATAL ERROR: Malformed skin file \"%s\":\n %s", skinsFile.c_str() % e.what());
|
flogFatal("FATAL ERROR: Malformed skin file \"%s\":\n %s", skinName.c_str() % e.what());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
g_resources.popCurrentPath();
|
||||||
}
|
}
|
||||||
|
|
||||||
void UISkins::terminate()
|
void UISkins::terminate()
|
||||||
|
|
|
@ -35,7 +35,7 @@ class UISkins
|
||||||
public:
|
public:
|
||||||
UISkins() { }
|
UISkins() { }
|
||||||
|
|
||||||
void load(const std::string& skinsFile);
|
void load(const std::string& skinName);
|
||||||
void terminate();
|
void terminate();
|
||||||
|
|
||||||
UIElementSkinPtr getElementSkin(UI::ElementType elementType, const std::string& name = "default");
|
UIElementSkinPtr getElementSkin(UI::ElementType elementType, const std::string& name = "default");
|
||||||
|
|
|
@ -507,7 +507,7 @@ void compose6(unsigned char * dst, unsigned int dstbytes, unsigned char * src, u
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int load_apng(unsigned char *filedata, unsigned int filesize, struct apng_data *apng)
|
int load_apng(std::stringstream& file, struct apng_data *apng)
|
||||||
{
|
{
|
||||||
unsigned int i, j;
|
unsigned int i, j;
|
||||||
unsigned int rowbytes;
|
unsigned int rowbytes;
|
||||||
|
@ -522,8 +522,6 @@ int load_apng(unsigned char *filedata, unsigned int filesize, struct apng_data *
|
||||||
unsigned char coltype, compr, filter, interl;
|
unsigned char coltype, compr, filter, interl;
|
||||||
z_stream zstream;
|
z_stream zstream;
|
||||||
memset(apng, 0, sizeof(struct apng_data));
|
memset(apng, 0, sizeof(struct apng_data));
|
||||||
std::istringstream f1;
|
|
||||||
f1.rdbuf()->pubsetbuf((char*)filedata, filesize);
|
|
||||||
|
|
||||||
for (i=0; i<256; i++)
|
for (i=0; i<256; i++)
|
||||||
{
|
{
|
||||||
|
@ -560,21 +558,21 @@ int load_apng(unsigned char *filedata, unsigned int filesize, struct apng_data *
|
||||||
unsigned char * pDst2;
|
unsigned char * pDst2;
|
||||||
unsigned int * frames_delay;
|
unsigned int * frames_delay;
|
||||||
|
|
||||||
f1.read((char*)sig, 8);
|
file.read((char*)sig, 8);
|
||||||
if(f1.good() && memcmp(sig, png_sign, 8) == 0) {
|
if(!file.eof() && memcmp(sig, png_sign, 8) == 0) {
|
||||||
len = read32(f1);
|
len = read32(file);
|
||||||
chunk = read32(f1);
|
chunk = read32(file);
|
||||||
|
|
||||||
if ((len == 13) && (chunk == 0x49484452)) /* IHDR */
|
if ((len == 13) && (chunk == 0x49484452)) /* IHDR */
|
||||||
{
|
{
|
||||||
w = w0 = read32(f1);
|
w = w0 = read32(file);
|
||||||
h = h0 = read32(f1);
|
h = h0 = read32(file);
|
||||||
f1.read((char*)&depth, 1);
|
file.read((char*)&depth, 1);
|
||||||
f1.read((char*)&coltype, 1);
|
file.read((char*)&coltype, 1);
|
||||||
f1.read((char*)&compr, 1);
|
file.read((char*)&compr, 1);
|
||||||
f1.read((char*)&filter, 1);
|
file.read((char*)&filter, 1);
|
||||||
f1.read((char*)&interl, 1);
|
file.read((char*)&interl, 1);
|
||||||
crc = read32(f1);
|
crc = read32(file);
|
||||||
|
|
||||||
channels = 1;
|
channels = 1;
|
||||||
if (coltype == 2)
|
if (coltype == 2)
|
||||||
|
@ -616,17 +614,17 @@ int load_apng(unsigned char *filedata, unsigned int filesize, struct apng_data *
|
||||||
memset(pOut1, 0, outimg1);
|
memset(pOut1, 0, outimg1);
|
||||||
memset(pOut2, 0, outimg2);
|
memset(pOut2, 0, outimg2);
|
||||||
|
|
||||||
while (!f1.eof())
|
while (!file.eof())
|
||||||
{
|
{
|
||||||
len = read32(f1);
|
len = read32(file);
|
||||||
chunk = read32(f1);
|
chunk = read32(file);
|
||||||
|
|
||||||
if (chunk == 0x504C5445) /* PLTE */
|
if (chunk == 0x504C5445) /* PLTE */
|
||||||
{
|
{
|
||||||
unsigned int col;
|
unsigned int col;
|
||||||
for (i=0; i<len; i++)
|
for (i=0; i<len; i++)
|
||||||
{
|
{
|
||||||
f1.read((char*)&c, 1);
|
file.read((char*)&c, 1);
|
||||||
col = i/3;
|
col = i/3;
|
||||||
if (col<256)
|
if (col<256)
|
||||||
{
|
{
|
||||||
|
@ -634,14 +632,14 @@ int load_apng(unsigned char *filedata, unsigned int filesize, struct apng_data *
|
||||||
palsize = col+1;
|
palsize = col+1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
crc = read32(f1);
|
crc = read32(file);
|
||||||
}
|
}
|
||||||
else if (chunk == 0x74524E53) /* tRNS */
|
else if (chunk == 0x74524E53) /* tRNS */
|
||||||
{
|
{
|
||||||
hasTRNS = 1;
|
hasTRNS = 1;
|
||||||
for (i=0; i<len; i++)
|
for (i=0; i<len; i++)
|
||||||
{
|
{
|
||||||
f1.read((char*)&c, 1);
|
file.read((char*)&c, 1);
|
||||||
if (i<256)
|
if (i<256)
|
||||||
{
|
{
|
||||||
trns[i] = c;
|
trns[i] = c;
|
||||||
|
@ -671,16 +669,16 @@ int load_apng(unsigned char *filedata, unsigned int filesize, struct apng_data *
|
||||||
trns[5] = trns[4]; trns[4] = 0;
|
trns[5] = trns[4]; trns[4] = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
crc = read32(f1);
|
crc = read32(file);
|
||||||
}
|
}
|
||||||
else if (chunk == 0x6163544C) /* acTL */
|
else if (chunk == 0x6163544C) /* acTL */
|
||||||
{
|
{
|
||||||
frames = read32(f1);
|
frames = read32(file);
|
||||||
if(frames_delay)
|
if(frames_delay)
|
||||||
free(frames_delay);
|
free(frames_delay);
|
||||||
frames_delay = (unsigned int*)malloc(frames*sizeof(int));
|
frames_delay = (unsigned int*)malloc(frames*sizeof(int));
|
||||||
loops = read32(f1);
|
loops = read32(file);
|
||||||
crc = read32(f1);
|
crc = read32(file);
|
||||||
if (pOut1)
|
if (pOut1)
|
||||||
free(pOut1);
|
free(pOut1);
|
||||||
if (pOut2)
|
if (pOut2)
|
||||||
|
@ -748,16 +746,16 @@ int load_apng(unsigned char *filedata, unsigned int filesize, struct apng_data *
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
seq = read32(f1);
|
seq = read32(file);
|
||||||
w0 = read32(f1);
|
w0 = read32(file);
|
||||||
h0 = read32(f1);
|
h0 = read32(file);
|
||||||
x0 = read32(f1);
|
x0 = read32(file);
|
||||||
y0 = read32(f1);
|
y0 = read32(file);
|
||||||
d1 = read16(f1);
|
d1 = read16(file);
|
||||||
d2 = read16(f1);
|
d2 = read16(file);
|
||||||
f1.read((char*)&dop, 1);
|
file.read((char*)&dop, 1);
|
||||||
f1.read((char*)&bop, 1);
|
file.read((char*)&bop, 1);
|
||||||
crc = read32(f1);
|
crc = read32(file);
|
||||||
|
|
||||||
if(d2 == 0)
|
if(d2 == 0)
|
||||||
d2 = 100;
|
d2 = 100;
|
||||||
|
@ -780,17 +778,17 @@ int load_apng(unsigned char *filedata, unsigned int filesize, struct apng_data *
|
||||||
}
|
}
|
||||||
else if (chunk == 0x49444154) /* IDAT */
|
else if (chunk == 0x49444154) /* IDAT */
|
||||||
{
|
{
|
||||||
f1.read((char*)(pData + zsize), len);
|
file.read((char*)(pData + zsize), len);
|
||||||
zsize += len;
|
zsize += len;
|
||||||
crc = read32(f1);
|
crc = read32(file);
|
||||||
}
|
}
|
||||||
else if (chunk == 0x66644154) /* fdAT */
|
else if (chunk == 0x66644154) /* fdAT */
|
||||||
{
|
{
|
||||||
seq = read32(f1);
|
seq = read32(file);
|
||||||
len -= 4;
|
len -= 4;
|
||||||
f1.read((char*)(pData + zsize), len);
|
file.read((char*)(pData + zsize), len);
|
||||||
zsize += len;
|
zsize += len;
|
||||||
crc = read32(f1);
|
crc = read32(file);
|
||||||
}
|
}
|
||||||
else if (chunk == 0x49454E44) /* IEND */
|
else if (chunk == 0x49454E44) /* IEND */
|
||||||
{
|
{
|
||||||
|
@ -818,8 +816,8 @@ int load_apng(unsigned char *filedata, unsigned int filesize, struct apng_data *
|
||||||
c = (unsigned char)(chunk & 0xFF);
|
c = (unsigned char)(chunk & 0xFF);
|
||||||
if (notabc(c)) break;
|
if (notabc(c)) break;
|
||||||
|
|
||||||
f1.seekg(len, std::ios_base::cur);
|
file.seekg(len, std::ios_base::cur);
|
||||||
crc = read32(f1);
|
crc = read32(file);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* apng decoding - end */
|
/* apng decoding - end */
|
||||||
|
|
|
@ -25,6 +25,8 @@
|
||||||
#ifndef APNGLOADER_H
|
#ifndef APNGLOADER_H
|
||||||
#define APNGLOADER_H
|
#define APNGLOADER_H
|
||||||
|
|
||||||
|
#include <sstream>
|
||||||
|
|
||||||
struct apng_data {
|
struct apng_data {
|
||||||
unsigned char *pdata;
|
unsigned char *pdata;
|
||||||
unsigned int width;
|
unsigned int width;
|
||||||
|
@ -39,7 +41,7 @@ struct apng_data {
|
||||||
};
|
};
|
||||||
|
|
||||||
// returns -1 on error, 0 on success
|
// returns -1 on error, 0 on success
|
||||||
int load_apng(unsigned char *filedata, unsigned int filesize, struct apng_data *apng);
|
int load_apng(std::stringstream& file, struct apng_data *apng);
|
||||||
void free_apng(struct apng_data *apng);
|
void free_apng(struct apng_data *apng);
|
||||||
|
|
||||||
#endif // APNGLOADER_H
|
#endif // APNGLOADER_H
|
||||||
|
|
|
@ -101,9 +101,6 @@ int main(int argc, const char *argv[])
|
||||||
|
|
||||||
// init resources
|
// init resources
|
||||||
g_resources.init(args[0].c_str());
|
g_resources.init(args[0].c_str());
|
||||||
if(g_resources.setWriteDir(Platform::getAppUserDir()))
|
|
||||||
g_resources.addToSearchPath(Platform::getAppUserDir());
|
|
||||||
g_resources.addToSearchPath("data");
|
|
||||||
|
|
||||||
// before loading configurations set the default ones
|
// before loading configurations set the default ones
|
||||||
setDefaultConfigs();
|
setDefaultConfigs();
|
||||||
|
@ -127,7 +124,7 @@ int main(int argc, const char *argv[])
|
||||||
g_engine.enableFpsCounter();
|
g_engine.enableFpsCounter();
|
||||||
|
|
||||||
// load ui skins
|
// load ui skins
|
||||||
g_uiSkins.load("skins/lightness.yml");
|
g_uiSkins.load("lightness");
|
||||||
|
|
||||||
// load script modules
|
// load script modules
|
||||||
g_lua.loadAllModules();
|
g_lua.loadAllModules();
|
||||||
|
|
Loading…
Reference in New Issue