Restore support for animated png files
* Rework resource manager * Add missing files * Improve some graphics classes
This commit is contained in:
parent
fdcad184f9
commit
0120b7554c
|
@ -165,7 +165,7 @@ void CreatureManager::clearSpawns()
|
||||||
void CreatureManager::loadMonsters(const std::string& file)
|
void CreatureManager::loadMonsters(const std::string& file)
|
||||||
{
|
{
|
||||||
TiXmlDocument doc;
|
TiXmlDocument doc;
|
||||||
doc.Parse(g_resources.loadFile(file).c_str());
|
doc.Parse(g_resources.readFileContents(file).c_str());
|
||||||
if(doc.Error())
|
if(doc.Error())
|
||||||
stdext::throw_exception(stdext::format("cannot open monsters file '%s': '%s'", file, doc.ErrorDesc()));
|
stdext::throw_exception(stdext::format("cannot open monsters file '%s': '%s'", file, doc.ErrorDesc()));
|
||||||
|
|
||||||
|
@ -187,7 +187,7 @@ void CreatureManager::loadMonsters(const std::string& file)
|
||||||
|
|
||||||
void CreatureManager::loadSingleCreature(const std::string& file)
|
void CreatureManager::loadSingleCreature(const std::string& file)
|
||||||
{
|
{
|
||||||
loadCreatureBuffer(g_resources.loadFile(file));
|
loadCreatureBuffer(g_resources.readFileContents(file));
|
||||||
}
|
}
|
||||||
|
|
||||||
void CreatureManager::loadNpcs(const std::string& folder)
|
void CreatureManager::loadNpcs(const std::string& folder)
|
||||||
|
@ -205,7 +205,7 @@ void CreatureManager::loadNpcs(const std::string& folder)
|
||||||
if(boost::filesystem::is_directory(it->status()))
|
if(boost::filesystem::is_directory(it->status()))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
loadCreatureBuffer(g_resources.loadFile(tmp + f));
|
loadCreatureBuffer(g_resources.readFileContents(tmp + f));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -222,7 +222,7 @@ void CreatureManager::loadSpawns(const std::string& fileName)
|
||||||
}
|
}
|
||||||
|
|
||||||
TiXmlDocument doc;
|
TiXmlDocument doc;
|
||||||
doc.Parse(g_resources.loadFile(fileName).c_str());
|
doc.Parse(g_resources.readFileContents(fileName).c_str());
|
||||||
if(doc.Error())
|
if(doc.Error())
|
||||||
stdext::throw_exception(stdext::format("cannot load spawns xml file '%s: '%s'", fileName, doc.ErrorDesc()));
|
stdext::throw_exception(stdext::format("cannot load spawns xml file '%s: '%s'", fileName, doc.ErrorDesc()));
|
||||||
|
|
||||||
|
|
|
@ -114,7 +114,7 @@ const HousePtr& HouseManager::getHouse(uint32 houseId)
|
||||||
void HouseManager::load(const std::string& fileName)
|
void HouseManager::load(const std::string& fileName)
|
||||||
{
|
{
|
||||||
TiXmlDocument doc;
|
TiXmlDocument doc;
|
||||||
doc.Parse(g_resources.loadFile(fileName).c_str());
|
doc.Parse(g_resources.readFileContents(fileName).c_str());
|
||||||
if(doc.Error())
|
if(doc.Error())
|
||||||
stdext::throw_exception(stdext::format("failed to load '%s': %s (House XML)", fileName, doc.ErrorDesc()));
|
stdext::throw_exception(stdext::format("failed to load '%s': %s (House XML)", fileName, doc.ErrorDesc()));
|
||||||
|
|
||||||
|
|
|
@ -125,7 +125,7 @@ ImagePtr SpriteManager::getSpriteImage(int id)
|
||||||
read += 4 + (3 * coloredPixels);
|
read += 4 + (3 * coloredPixels);
|
||||||
}
|
}
|
||||||
|
|
||||||
// fill remaining pixels with alpha
|
// fill reamaning pixels with alpha
|
||||||
while(writePos < SPRITE_DATA_SIZE) {
|
while(writePos < SPRITE_DATA_SIZE) {
|
||||||
pixels[writePos + 0] = 0x00;
|
pixels[writePos + 0] = 0x00;
|
||||||
pixels[writePos + 1] = 0x00;
|
pixels[writePos + 1] = 0x00;
|
||||||
|
|
|
@ -139,7 +139,7 @@ void ThingTypeManager::loadXml(const std::string& file)
|
||||||
stdext::throw_exception("OTB must be loaded before XML");
|
stdext::throw_exception("OTB must be loaded before XML");
|
||||||
|
|
||||||
TiXmlDocument doc;
|
TiXmlDocument doc;
|
||||||
doc.Parse(g_resources.loadFile(file).c_str());
|
doc.Parse(g_resources.readFileContents(file).c_str());
|
||||||
if(doc.Error())
|
if(doc.Error())
|
||||||
stdext::throw_exception(stdext::format("failed to parse '%s': '%s'", file, doc.ErrorDesc()));
|
stdext::throw_exception(stdext::format("failed to parse '%s': '%s'", file, doc.ErrorDesc()));
|
||||||
|
|
||||||
|
|
|
@ -109,10 +109,10 @@ void Application::deinit()
|
||||||
g_modules.unloadModules();
|
g_modules.unloadModules();
|
||||||
g_modules.clear();
|
g_modules.clear();
|
||||||
|
|
||||||
// release remaining lua object references
|
// release reamaning lua object references
|
||||||
g_lua.collectGarbage();
|
g_lua.collectGarbage();
|
||||||
|
|
||||||
// poll remaining events
|
// poll reamaning events
|
||||||
poll();
|
poll();
|
||||||
|
|
||||||
// disable dispatcher events
|
// disable dispatcher events
|
||||||
|
|
|
@ -45,7 +45,7 @@ void EventDispatcher::poll()
|
||||||
int loops = 0;
|
int loops = 0;
|
||||||
for(int count = 0, max = m_scheduledEventList.size(); count < max && !m_scheduledEventList.empty(); ++count) {
|
for(int count = 0, max = m_scheduledEventList.size(); count < max && !m_scheduledEventList.empty(); ++count) {
|
||||||
ScheduledEventPtr scheduledEvent = m_scheduledEventList.top();
|
ScheduledEventPtr scheduledEvent = m_scheduledEventList.top();
|
||||||
if(scheduledEvent->remainingTicks() > 0)
|
if(scheduledEvent->reamaningTicks() > 0)
|
||||||
break;
|
break;
|
||||||
m_scheduledEventList.pop();
|
m_scheduledEventList.pop();
|
||||||
scheduledEvent->execute();
|
scheduledEvent->execute();
|
||||||
|
|
|
@ -35,6 +35,17 @@ FileStream::FileStream(const std::string& name, PHYSFS_File *fileHandle, bool wr
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
FileStream::FileStream(const std::string& name, const std::string& buffer) :
|
||||||
|
m_name(name),
|
||||||
|
m_fileHandle(nullptr),
|
||||||
|
m_pos(0),
|
||||||
|
m_writeable(false),
|
||||||
|
m_caching(true)
|
||||||
|
{
|
||||||
|
m_data.resize(buffer.length());
|
||||||
|
memcpy(&m_data[0], &buffer[0], buffer.length());
|
||||||
|
}
|
||||||
|
|
||||||
FileStream::~FileStream()
|
FileStream::~FileStream()
|
||||||
{
|
{
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
|
@ -338,3 +349,4 @@ void FileStream::throwError(const std::string& message, bool physfsError)
|
||||||
completeMessage += std::string(": ") + PHYSFS_getLastError();
|
completeMessage += std::string(": ") + PHYSFS_getLastError();
|
||||||
stdext::throw_exception(completeMessage);
|
stdext::throw_exception(completeMessage);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -36,6 +36,7 @@ class FileStream : public LuaObject
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
FileStream(const std::string& name, PHYSFS_File *fileHandle, bool writeable);
|
FileStream(const std::string& name, PHYSFS_File *fileHandle, bool writeable);
|
||||||
|
FileStream(const std::string& name, const std::string& buffer);
|
||||||
~FileStream();
|
~FileStream();
|
||||||
|
|
||||||
void cache();
|
void cache();
|
||||||
|
|
|
@ -76,7 +76,7 @@ void GraphicalApplication::terminate()
|
||||||
// destroy particles
|
// destroy particles
|
||||||
g_particles.terminate();
|
g_particles.terminate();
|
||||||
|
|
||||||
// destroy any remaining widget
|
// destroy any reamaning widget
|
||||||
g_ui.terminate();
|
g_ui.terminate();
|
||||||
|
|
||||||
Application::terminate();
|
Application::terminate();
|
||||||
|
|
|
@ -48,10 +48,10 @@ bool Module::load()
|
||||||
for(const std::string& depName : m_dependencies) {
|
for(const std::string& depName : m_dependencies) {
|
||||||
ModulePtr dep = g_modules.getModule(depName);
|
ModulePtr dep = g_modules.getModule(depName);
|
||||||
if(!dep)
|
if(!dep)
|
||||||
stdext::throw_exception(stdext::format("dependency '%s' was not found", m_name, depName));
|
stdext::throw_exception(stdext::format("dependency '%s' was not found", depName));
|
||||||
|
|
||||||
if(!dep->isLoaded() && !dep->load())
|
if(!dep->isLoaded() && !dep->load())
|
||||||
stdext::throw_exception(stdext::format("dependency '%s' has failed to load", m_name, depName));
|
stdext::throw_exception(stdext::format("dependency '%s' has failed to load", depName));
|
||||||
}
|
}
|
||||||
|
|
||||||
if(m_sandboxed)
|
if(m_sandboxed)
|
||||||
|
@ -199,8 +199,8 @@ void Module::discover(const OTMLNodePtr& moduleNode)
|
||||||
}
|
}
|
||||||
|
|
||||||
if(OTMLNodePtr node = moduleNode->get("@onLoad"))
|
if(OTMLNodePtr node = moduleNode->get("@onLoad"))
|
||||||
m_onLoadFunc = std::make_tuple(node->value(), "@" + node->source() + "[" + node->tag() + "]");
|
m_onLoadFunc = std::make_tuple(node->value(), "@" + node->source() + ":[" + node->tag() + "]");
|
||||||
|
|
||||||
if(OTMLNodePtr node = moduleNode->get("@onUnload"))
|
if(OTMLNodePtr node = moduleNode->get("@onUnload"))
|
||||||
m_onUnloadFunc = std::make_tuple(node->value(), "@" + node->source() + "[" + node->tag() + "]");
|
m_onUnloadFunc = std::make_tuple(node->value(), "@" + node->source() + ":[" + node->tag() + "]");
|
||||||
}
|
}
|
||||||
|
|
|
@ -42,14 +42,12 @@ void ResourceManager::terminate()
|
||||||
PHYSFS_deinit();
|
PHYSFS_deinit();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ResourceManager::discoverWorkDir(const std::string& appName, const std::string& existentFile)
|
bool ResourceManager::discoverWorkDir(const std::string& existentFile)
|
||||||
{
|
{
|
||||||
// search for modules directory
|
// search for modules directory
|
||||||
std::string possiblePaths[] = { g_resources.getCurrentDir(),
|
std::string possiblePaths[] = { g_resources.getCurrentDir(),
|
||||||
g_resources.getBaseDir() + "../",
|
g_resources.getBaseDir(),
|
||||||
g_resources.getBaseDir() + "../share/" + appName + "/",
|
g_resources.getBaseDir() + "../" };
|
||||||
g_resources.getBaseDir() + appName + "/" };
|
|
||||||
|
|
||||||
bool found = false;
|
bool found = false;
|
||||||
for(const std::string& dir : possiblePaths) {
|
for(const std::string& dir : possiblePaths) {
|
||||||
if(!PHYSFS_addToSearchPath(dir.c_str(), 0))
|
if(!PHYSFS_addToSearchPath(dir.c_str(), 0))
|
||||||
|
@ -64,8 +62,7 @@ void ResourceManager::discoverWorkDir(const std::string& appName, const std::str
|
||||||
PHYSFS_removeFromSearchPath(dir.c_str());
|
PHYSFS_removeFromSearchPath(dir.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!found)
|
return found;
|
||||||
g_logger.fatal(stdext::format("Unable to find %s, the application cannot be initialized.", existentFile));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ResourceManager::setupUserWriteDir(const std::string& appWriteDirName)
|
bool ResourceManager::setupUserWriteDir(const std::string& appWriteDirName)
|
||||||
|
@ -165,35 +162,35 @@ bool ResourceManager::directoryExists(const std::string& directoryName)
|
||||||
return (PHYSFS_isDirectory(resolvePath(directoryName).c_str()));
|
return (PHYSFS_isDirectory(resolvePath(directoryName).c_str()));
|
||||||
}
|
}
|
||||||
|
|
||||||
void ResourceManager::loadFile(const std::string& fileName, std::iostream& out)
|
void ResourceManager::readFileStream(const std::string& fileName, std::iostream& out)
|
||||||
{
|
{
|
||||||
out.clear(std::ios::goodbit);
|
std::string buffer = readFileContents(fileName);
|
||||||
std::string fullPath = resolvePath(fileName);
|
if(buffer.length() == 0) {
|
||||||
PHYSFS_file* file = PHYSFS_openRead(fullPath.c_str());
|
|
||||||
if(!file) {
|
|
||||||
out.clear(std::ios::failbit);
|
|
||||||
stdext::throw_exception(stdext::format("unable to load file '%s': %s", fullPath.c_str(), PHYSFS_getLastError()));
|
|
||||||
} else {
|
|
||||||
int fileSize = PHYSFS_fileLength(file);
|
|
||||||
if(fileSize > 0) {
|
|
||||||
std::vector<char> buffer(fileSize);
|
|
||||||
PHYSFS_read(file, (void*)&buffer[0], 1, fileSize);
|
|
||||||
out.write(&buffer[0], fileSize);
|
|
||||||
} else
|
|
||||||
out.clear(std::ios::eofbit);
|
out.clear(std::ios::eofbit);
|
||||||
PHYSFS_close(file);
|
return;
|
||||||
out.seekg(0, std::ios::beg);
|
|
||||||
}
|
}
|
||||||
|
out.clear(std::ios::goodbit);
|
||||||
|
out.write(&buffer[0], buffer.length());
|
||||||
|
out.seekg(0, std::ios::beg);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string ResourceManager::loadFile(const std::string& fileName)
|
std::string ResourceManager::readFileContents(const std::string& fileName)
|
||||||
{
|
{
|
||||||
std::stringstream fin;
|
std::string fullPath = resolvePath(fileName);
|
||||||
loadFile(fileName, fin);
|
|
||||||
return fin.str();
|
PHYSFS_File* file = PHYSFS_openRead(fullPath.c_str());
|
||||||
|
if(!file)
|
||||||
|
stdext::throw_exception(stdext::format("unable to open file '%s': %s", fullPath, PHYSFS_getLastError()));
|
||||||
|
|
||||||
|
int fileSize = PHYSFS_fileLength(file);
|
||||||
|
std::string buffer(fileSize, 0);
|
||||||
|
PHYSFS_read(file, (void*)&buffer[0], 1, fileSize);
|
||||||
|
PHYSFS_close(file);
|
||||||
|
|
||||||
|
return buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ResourceManager::saveFile(const std::string& fileName, const uchar* data, uint size)
|
bool ResourceManager::writeFileBuffer(const std::string& fileName, const uchar* data, uint size)
|
||||||
{
|
{
|
||||||
PHYSFS_file* file = PHYSFS_openWrite(fileName.c_str());
|
PHYSFS_file* file = PHYSFS_openWrite(fileName.c_str());
|
||||||
if(!file) {
|
if(!file) {
|
||||||
|
@ -206,7 +203,7 @@ bool ResourceManager::saveFile(const std::string& fileName, const uchar* data, u
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ResourceManager::saveFile(const std::string& fileName, std::iostream& in)
|
bool ResourceManager::writeFileStream(const std::string& fileName, std::iostream& in)
|
||||||
{
|
{
|
||||||
std::streampos oldPos = in.tellg();
|
std::streampos oldPos = in.tellg();
|
||||||
in.seekg(0, std::ios::end);
|
in.seekg(0, std::ios::end);
|
||||||
|
@ -214,19 +211,20 @@ bool ResourceManager::saveFile(const std::string& fileName, std::iostream& in)
|
||||||
in.seekg(0, std::ios::beg);
|
in.seekg(0, std::ios::beg);
|
||||||
std::vector<char> buffer(size);
|
std::vector<char> buffer(size);
|
||||||
in.read(&buffer[0], size);
|
in.read(&buffer[0], size);
|
||||||
bool ret = saveFile(fileName, (const uchar*)&buffer[0], size);
|
bool ret = writeFileBuffer(fileName, (const uchar*)&buffer[0], size);
|
||||||
in.seekg(oldPos, std::ios::beg);
|
in.seekg(oldPos, std::ios::beg);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ResourceManager::saveFile(const std::string& fileName, const std::string& data)
|
bool ResourceManager::writeFileContents(const std::string& fileName, const std::string& data)
|
||||||
{
|
{
|
||||||
return saveFile(fileName, (const uchar*)data.c_str(), data.size());
|
return writeFileBuffer(fileName, (const uchar*)data.c_str(), data.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
FileStreamPtr ResourceManager::openFile(const std::string& fileName)
|
FileStreamPtr ResourceManager::openFile(const std::string& fileName)
|
||||||
{
|
{
|
||||||
std::string fullPath = resolvePath(fileName);
|
std::string fullPath = resolvePath(fileName);
|
||||||
|
|
||||||
PHYSFS_File* file = PHYSFS_openRead(fullPath.c_str());
|
PHYSFS_File* file = PHYSFS_openRead(fullPath.c_str());
|
||||||
if(!file)
|
if(!file)
|
||||||
stdext::throw_exception(stdext::format("unable to open file '%s': %s", fullPath, PHYSFS_getLastError()));
|
stdext::throw_exception(stdext::format("unable to open file '%s': %s", fullPath, PHYSFS_getLastError()));
|
||||||
|
@ -299,16 +297,12 @@ std::string ResourceManager::getRealDir(const std::string& path)
|
||||||
|
|
||||||
std::string ResourceManager::getCurrentDir()
|
std::string ResourceManager::getCurrentDir()
|
||||||
{
|
{
|
||||||
char buffer[2048];
|
return boost::filesystem::current_path().generic_string<std::string>() + "/";
|
||||||
PHYSFS_utf8FromLatin1((boost::filesystem::current_path().generic_string() + "/").c_str(), buffer, 2048);
|
|
||||||
return buffer;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string ResourceManager::getBaseDir()
|
std::string ResourceManager::getBaseDir()
|
||||||
{
|
{
|
||||||
char buffer[2048];
|
return PHYSFS_getBaseDir();
|
||||||
PHYSFS_utf8FromLatin1(PHYSFS_getBaseDir(), buffer, 2048);
|
|
||||||
return buffer;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string ResourceManager::guessFileType(const std::string& filename, const std::string& type)
|
std::string ResourceManager::guessFileType(const std::string& filename, const std::string& type)
|
||||||
|
|
|
@ -34,7 +34,7 @@ public:
|
||||||
// @dontbind
|
// @dontbind
|
||||||
void terminate();
|
void terminate();
|
||||||
|
|
||||||
void discoverWorkDir(const std::string& appName, const std::string& existentFile);
|
bool discoverWorkDir(const std::string& existentFile);
|
||||||
bool setupUserWriteDir(const std::string& appWriteDirName);
|
bool setupUserWriteDir(const std::string& appWriteDirName);
|
||||||
bool setWriteDir(const std::string& writeDir, bool create = false);
|
bool setWriteDir(const std::string& writeDir, bool create = false);
|
||||||
|
|
||||||
|
@ -46,13 +46,13 @@ public:
|
||||||
bool directoryExists(const std::string& directoryName);
|
bool directoryExists(const std::string& directoryName);
|
||||||
|
|
||||||
// @dontbind
|
// @dontbind
|
||||||
void loadFile(const std::string& fileName, std::iostream& out);
|
void readFileStream(const std::string& fileName, std::iostream& out);
|
||||||
std::string loadFile(const std::string& fileName);
|
std::string readFileContents(const std::string& fileName);
|
||||||
// @dontbind
|
// @dontbind
|
||||||
bool saveFile(const std::string& fileName, const uchar* data, uint size);
|
bool writeFileBuffer(const std::string& fileName, const uchar* data, uint size);
|
||||||
bool saveFile(const std::string& fileName, const std::string& data);
|
bool writeFileContents(const std::string& fileName, const std::string& data);
|
||||||
// @dontbind
|
// @dontbind
|
||||||
bool saveFile(const std::string& fileName, std::iostream& in);
|
bool writeFileStream(const std::string& fileName, std::iostream& in);
|
||||||
|
|
||||||
FileStreamPtr openFile(const std::string& fileName);
|
FileStreamPtr openFile(const std::string& fileName);
|
||||||
FileStreamPtr appendFile(const std::string& fileName);
|
FileStreamPtr appendFile(const std::string& fileName);
|
||||||
|
|
|
@ -35,7 +35,7 @@ public:
|
||||||
bool nextCycle();
|
bool nextCycle();
|
||||||
|
|
||||||
int ticks() { return m_ticks; }
|
int ticks() { return m_ticks; }
|
||||||
int remainingTicks() { return m_ticks - g_clock.millis(); }
|
int reamaningTicks() { return m_ticks - g_clock.millis(); }
|
||||||
int delay() { return m_delay; }
|
int delay() { return m_delay; }
|
||||||
int cyclesExecuted() { return m_cyclesExecuted; }
|
int cyclesExecuted() { return m_cyclesExecuted; }
|
||||||
int maxCycles() { return m_maxCycles; }
|
int maxCycles() { return m_maxCycles; }
|
||||||
|
|
|
@ -24,53 +24,60 @@
|
||||||
#include "graphics.h"
|
#include "graphics.h"
|
||||||
|
|
||||||
#include <framework/core/eventdispatcher.h>
|
#include <framework/core/eventdispatcher.h>
|
||||||
/*
|
|
||||||
AnimatedTexture::AnimatedTexture(int width, int height, int channels, int numFrames, uchar *framesPixels, int *framesDelay) :
|
AnimatedTexture::AnimatedTexture(const Size& size, std::vector<ImagePtr> frames, std::vector<int> framesDelay, bool buildMipmaps, bool compress)
|
||||||
Texture(),
|
|
||||||
m_numFrames(numFrames)
|
|
||||||
{
|
{
|
||||||
m_size.resize(width, height);
|
if(!setupSize(size, buildMipmaps))
|
||||||
|
return;
|
||||||
|
|
||||||
m_framesTextureId.resize(numFrames);
|
for(uint i=0;i<frames.size();++i) {
|
||||||
m_framesDelay.resize(numFrames);
|
m_frames.push_back(new Texture(frames[i], buildMipmaps, compress));
|
||||||
|
|
||||||
for(int i=0;i<numFrames;++i) {
|
|
||||||
uchar *framePixels = framesPixels + (i*height*width* channels);
|
|
||||||
uint id = internalLoadGLTexture(framePixels, channels, width, height);
|
|
||||||
|
|
||||||
m_framesTextureId[i] = id;
|
|
||||||
m_framesDelay[i] = framesDelay[i];
|
|
||||||
}
|
}
|
||||||
m_currentFrame = -1;
|
|
||||||
g_dispatcher.scheduleEvent(std::bind(&AnimatedTexture::processAnimation, this), 0);
|
m_framesDelay = framesDelay;
|
||||||
|
m_hasMipmaps = buildMipmaps;
|
||||||
|
m_id = m_frames[0]->getId();
|
||||||
|
m_currentFrame = 0;
|
||||||
|
m_animTimer.restart();
|
||||||
}
|
}
|
||||||
|
|
||||||
AnimatedTexture::~AnimatedTexture()
|
AnimatedTexture::~AnimatedTexture()
|
||||||
{
|
{
|
||||||
glDeleteTextures(m_numFrames, &m_framesTextureId[0]);
|
|
||||||
m_id = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void AnimatedTexture::enableBilinearFilter()
|
bool AnimatedTexture::buildHardwareMipmaps()
|
||||||
{
|
{
|
||||||
for(int i=0;i<m_numFrames;++i) {
|
if(!g_graphics.canUseHardwareMipmaps())
|
||||||
glBindTexture(GL_TEXTURE_2D, m_framesTextureId[i]);
|
return false;
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
for(const TexturePtr& frame : m_frames)
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
frame->buildHardwareMipmaps();
|
||||||
}
|
m_hasMipmaps = true;
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void AnimatedTexture::processAnimation()
|
void AnimatedTexture::setSmooth(bool smooth)
|
||||||
{
|
{
|
||||||
|
for(const TexturePtr& frame : m_frames)
|
||||||
|
frame->setSmooth(smooth);
|
||||||
|
m_smooth = smooth;
|
||||||
|
}
|
||||||
|
|
||||||
|
void AnimatedTexture::setRepeat(bool repeat)
|
||||||
|
{
|
||||||
|
for(const TexturePtr& frame : m_frames)
|
||||||
|
frame->setRepeat(repeat);
|
||||||
|
m_repeat = repeat;
|
||||||
|
}
|
||||||
|
|
||||||
|
void AnimatedTexture::updateAnimation()
|
||||||
|
{
|
||||||
|
if(m_animTimer.ticksElapsed() < m_framesDelay[m_currentFrame])
|
||||||
|
return;
|
||||||
|
|
||||||
|
m_animTimer.restart();
|
||||||
m_currentFrame++;
|
m_currentFrame++;
|
||||||
if(m_currentFrame >= m_numFrames)
|
if(m_currentFrame >= m_frames.size())
|
||||||
m_currentFrame = 0;
|
m_currentFrame = 0;
|
||||||
m_id = m_framesTextureId[m_currentFrame];
|
m_id = m_frames[m_currentFrame]->getId();
|
||||||
|
|
||||||
AnimatedTexturePtr self = asAnimatedTexture();
|
|
||||||
|
|
||||||
// continue to animate only if something still referencing this texture
|
|
||||||
if(self->ref_count() > 1)
|
|
||||||
g_dispatcher.scheduleEvent(std::bind(&AnimatedTexture::processAnimation, self), m_framesDelay[m_currentFrame]);
|
|
||||||
}
|
}
|
||||||
*/
|
|
|
@ -24,24 +24,28 @@
|
||||||
#define ANIMATEDTEXTURE_H
|
#define ANIMATEDTEXTURE_H
|
||||||
|
|
||||||
#include "texture.h"
|
#include "texture.h"
|
||||||
/*
|
#include <framework/core/timer.h>
|
||||||
|
|
||||||
class AnimatedTexture : public Texture
|
class AnimatedTexture : public Texture
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
AnimatedTexture(int width, int height, int channels, int numFrames, uchar *framesPixels, int *framesDelay);
|
AnimatedTexture(const Size& size, std::vector<ImagePtr> frames, std::vector<int> framesDelay, bool buildMipmaps = false, bool compress = false);
|
||||||
virtual ~AnimatedTexture();
|
virtual ~AnimatedTexture();
|
||||||
|
|
||||||
void enableBilinearFilter();
|
virtual bool buildHardwareMipmaps();
|
||||||
void processAnimation();
|
|
||||||
|
|
||||||
AnimatedTexturePtr asAnimatedTexture() { return static_self_cast<AnimatedTexture>(); }
|
virtual void setSmooth(bool smooth);
|
||||||
|
virtual void setRepeat(bool repeat);
|
||||||
|
|
||||||
|
void updateAnimation();
|
||||||
|
|
||||||
|
virtual bool isAnimatedTexture() { return true; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::vector<uint> m_framesTextureId;
|
std::vector<TexturePtr> m_frames;
|
||||||
std::vector<int> m_framesDelay;
|
std::vector<int> m_framesDelay;
|
||||||
int m_numFrames;
|
uint m_currentFrame;
|
||||||
int m_currentFrame;
|
Timer m_animTimer;
|
||||||
ticks_t m_lastAnimCheckTicks;
|
|
||||||
};
|
};
|
||||||
*/
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -52,9 +52,6 @@ void BitmapFont::load(const OTMLNodePtr& fontNode)
|
||||||
m_glyphsSize[32].setWidth(spaceWidth);
|
m_glyphsSize[32].setWidth(spaceWidth);
|
||||||
m_glyphsSize[160].setWidth(spaceWidth);
|
m_glyphsSize[160].setWidth(spaceWidth);
|
||||||
|
|
||||||
// use 127 as spacer [Width: 1]
|
|
||||||
m_glyphsSize[127].setWidth(1);
|
|
||||||
|
|
||||||
// new line actually has a size that will be useful in multiline algorithm
|
// new line actually has a size that will be useful in multiline algorithm
|
||||||
m_glyphsSize[(uchar)'\n'] = Size(1, m_glyphHeight);
|
m_glyphsSize[(uchar)'\n'] = Size(1, m_glyphHeight);
|
||||||
|
|
||||||
|
@ -262,6 +259,9 @@ Size BitmapFont::calculateTextRectSize(const std::string& text)
|
||||||
|
|
||||||
void BitmapFont::calculateGlyphsWidthsAutomatically(const ImagePtr& image, const Size& glyphSize)
|
void BitmapFont::calculateGlyphsWidthsAutomatically(const ImagePtr& image, const Size& glyphSize)
|
||||||
{
|
{
|
||||||
|
if(!image)
|
||||||
|
return;
|
||||||
|
|
||||||
int numHorizontalGlyphs = image->getSize().width() / glyphSize.width();
|
int numHorizontalGlyphs = image->getSize().width() / glyphSize.width();
|
||||||
auto texturePixels = image->getPixels();
|
auto texturePixels = image->getPixels();
|
||||||
|
|
||||||
|
|
|
@ -39,8 +39,8 @@ public:
|
||||||
void setAlign(Fw::AlignmentFlag align) { m_align = align; update(); }
|
void setAlign(Fw::AlignmentFlag align) { m_align = align; update(); }
|
||||||
|
|
||||||
Size getTextSize() { return m_textSize; }
|
Size getTextSize() { return m_textSize; }
|
||||||
std::string getText() { return m_text; }
|
std::string getText() const { return m_text; }
|
||||||
BitmapFontPtr getFont() { return m_font; }
|
BitmapFontPtr getFont() const { return m_font; }
|
||||||
Fw::AlignmentFlag getAlign() { return m_align; }
|
Fw::AlignmentFlag getAlign() { return m_align; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
|
@ -59,6 +59,11 @@ public:
|
||||||
m_textureCoordArray.addQuad(src);
|
m_textureCoordArray.addQuad(src);
|
||||||
m_hardwareCached = false;
|
m_hardwareCached = false;
|
||||||
}
|
}
|
||||||
|
void addUpsideDownQuad(const Rect& dest, const Rect& src) {
|
||||||
|
m_vertexArray.addUpsideDownQuad(dest);
|
||||||
|
m_textureCoordArray.addQuad(src);
|
||||||
|
m_hardwareCached = false;
|
||||||
|
}
|
||||||
|
|
||||||
void addBoudingRect(const Rect& dest, int innerLineWidth);
|
void addBoudingRect(const Rect& dest, int innerLineWidth);
|
||||||
void addRepeatedRects(const Rect& dest, const Rect& src);
|
void addRepeatedRects(const Rect& dest, const Rect& src);
|
||||||
|
|
|
@ -45,13 +45,12 @@ void FontManager::clearFonts()
|
||||||
m_defaultFont = BitmapFontPtr(new BitmapFont("emptyfont"));
|
m_defaultFont = BitmapFontPtr(new BitmapFont("emptyfont"));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool FontManager::importFont(std::string fontFile)
|
bool FontManager::importFont(std::string file)
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
if(!stdext::ends_with(fontFile, ".otfont"))
|
file = g_resources.guessFileType(file, "otfont");
|
||||||
fontFile += ".otfont";
|
|
||||||
|
|
||||||
OTMLDocumentPtr doc = OTMLDocument::parse(fontFile);
|
OTMLDocumentPtr doc = OTMLDocument::parse(file);
|
||||||
OTMLNodePtr fontNode = doc->at("Font");
|
OTMLNodePtr fontNode = doc->at("Font");
|
||||||
|
|
||||||
std::string name = fontNode->valueAt("name");
|
std::string name = fontNode->valueAt("name");
|
||||||
|
@ -69,12 +68,12 @@ bool FontManager::importFont(std::string fontFile)
|
||||||
m_fonts.push_back(font);
|
m_fonts.push_back(font);
|
||||||
|
|
||||||
// set as default if needed
|
// set as default if needed
|
||||||
if(!m_defaultFont)
|
if(!m_defaultFont || fontNode->valueAt<bool>("default", false))
|
||||||
m_defaultFont = font;
|
m_defaultFont = font;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
} catch(stdext::exception& e) {
|
} catch(stdext::exception& e) {
|
||||||
g_logger.error(stdext::format("Unable to load font from file '%s': %s", fontFile, e.what()));
|
g_logger.error(stdext::format("Unable to load font from file '%s': %s", file, e.what()));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -100,4 +99,3 @@ BitmapFontPtr FontManager::getFont(const std::string& fontName)
|
||||||
g_logger.error(stdext::format("font '%s' not found", fontName));
|
g_logger.error(stdext::format("font '%s' not found", fontName));
|
||||||
return getDefaultFont();
|
return getDefaultFont();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -34,7 +34,7 @@ public:
|
||||||
void terminate();
|
void terminate();
|
||||||
void clearFonts();
|
void clearFonts();
|
||||||
|
|
||||||
bool importFont(std::string fontFile);
|
bool importFont(std::string file);
|
||||||
|
|
||||||
bool fontExists(const std::string& fontName);
|
bool fontExists(const std::string& fontName);
|
||||||
BitmapFontPtr getFont(const std::string& fontName);
|
BitmapFontPtr getFont(const std::string& fontName);
|
||||||
|
|
|
@ -173,6 +173,8 @@ bool Graphics::selectPainterEngine(PainterEngine painterEngine)
|
||||||
{
|
{
|
||||||
Painter *painter = nullptr;
|
Painter *painter = nullptr;
|
||||||
Painter *fallbackPainter = nullptr;
|
Painter *fallbackPainter = nullptr;
|
||||||
|
PainterEngine fallbackPainterEngine = Painter_Any;
|
||||||
|
|
||||||
#ifdef PAINTER_OGL2
|
#ifdef PAINTER_OGL2
|
||||||
// always prefer OpenGL 2 over OpenGL 1
|
// always prefer OpenGL 2 over OpenGL 1
|
||||||
if(g_painterOGL2) {
|
if(g_painterOGL2) {
|
||||||
|
@ -181,6 +183,7 @@ bool Graphics::selectPainterEngine(PainterEngine painterEngine)
|
||||||
painter = g_painterOGL2;
|
painter = g_painterOGL2;
|
||||||
}
|
}
|
||||||
fallbackPainter = g_painterOGL2;
|
fallbackPainter = g_painterOGL2;
|
||||||
|
fallbackPainterEngine = Painter_OpenGL2;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -192,11 +195,14 @@ bool Graphics::selectPainterEngine(PainterEngine painterEngine)
|
||||||
painter = g_painterOGL1;
|
painter = g_painterOGL1;
|
||||||
}
|
}
|
||||||
fallbackPainter = g_painterOGL1;
|
fallbackPainter = g_painterOGL1;
|
||||||
|
fallbackPainterEngine = Painter_OpenGL1;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if(!painter)
|
if(!painter) {
|
||||||
painter = fallbackPainter;
|
painter = fallbackPainter;
|
||||||
|
m_selectedPainterEngine = fallbackPainterEngine;
|
||||||
|
}
|
||||||
|
|
||||||
// switch painters GL state
|
// switch painters GL state
|
||||||
if(painter) {
|
if(painter) {
|
||||||
|
|
|
@ -59,6 +59,8 @@ public:
|
||||||
std::string getVersion() { return (const char*)glGetString(GL_VERSION); }
|
std::string getVersion() { return (const char*)glGetString(GL_VERSION); }
|
||||||
std::string getExtensions() { return (const char*)glGetString(GL_EXTENSIONS); }
|
std::string getExtensions() { return (const char*)glGetString(GL_EXTENSIONS); }
|
||||||
|
|
||||||
|
void setShouldUseShaders(bool enable) { m_shouldUseShaders = enable; }
|
||||||
|
|
||||||
bool ok() { return m_ok; }
|
bool ok() { return m_ok; }
|
||||||
bool canUseDrawArrays();
|
bool canUseDrawArrays();
|
||||||
bool canUseShaders();
|
bool canUseShaders();
|
||||||
|
@ -71,6 +73,7 @@ public:
|
||||||
bool canUseClampToEdge();
|
bool canUseClampToEdge();
|
||||||
bool canUseBlendFuncSeparate();
|
bool canUseBlendFuncSeparate();
|
||||||
bool canCacheBackbuffer();
|
bool canCacheBackbuffer();
|
||||||
|
bool shouldUseShaders() { return m_shouldUseShaders; }
|
||||||
bool hasScissorBug();
|
bool hasScissorBug();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -87,6 +90,7 @@ private:
|
||||||
stdext::boolean<true> m_useMipmaps;
|
stdext::boolean<true> m_useMipmaps;
|
||||||
stdext::boolean<true> m_useHardwareMipmaps;
|
stdext::boolean<true> m_useHardwareMipmaps;
|
||||||
stdext::boolean<true> m_useClampToEdge;
|
stdext::boolean<true> m_useClampToEdge;
|
||||||
|
stdext::boolean<true> m_shouldUseShaders;
|
||||||
stdext::boolean<true> m_cacheBackbuffer;
|
stdext::boolean<true> m_cacheBackbuffer;
|
||||||
PainterEngine m_prefferedPainterEngine;
|
PainterEngine m_prefferedPainterEngine;
|
||||||
PainterEngine m_selectedPainterEngine;
|
PainterEngine m_selectedPainterEngine;
|
||||||
|
|
|
@ -35,13 +35,11 @@ Image::Image(const Size& size, int bpp, uint8 *pixels)
|
||||||
memcpy(&m_pixels[0], pixels, m_pixels.size());
|
memcpy(&m_pixels[0], pixels, m_pixels.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
ImagePtr Image::load(const std::string& file)
|
ImagePtr Image::load(std::string file)
|
||||||
{
|
{
|
||||||
ImagePtr image;
|
ImagePtr image;
|
||||||
try {
|
try {
|
||||||
// currently only png images are supported
|
file = g_resources.guessFileType(file, "png");
|
||||||
if(!stdext::ends_with(file, ".png"))
|
|
||||||
stdext::throw_exception("image file format no supported");
|
|
||||||
|
|
||||||
// load image file data
|
// load image file data
|
||||||
image = loadPNG(file);
|
image = loadPNG(file);
|
||||||
|
@ -54,7 +52,7 @@ ImagePtr Image::load(const std::string& file)
|
||||||
ImagePtr Image::loadPNG(const std::string& file)
|
ImagePtr Image::loadPNG(const std::string& file)
|
||||||
{
|
{
|
||||||
std::stringstream fin;
|
std::stringstream fin;
|
||||||
g_resources.loadFile(file, fin);
|
g_resources.readFileStream(file, fin);
|
||||||
ImagePtr image;
|
ImagePtr image;
|
||||||
apng_data apng;
|
apng_data apng;
|
||||||
if(load_apng(fin, &apng) == 0) {
|
if(load_apng(fin, &apng) == 0) {
|
||||||
|
|
|
@ -31,7 +31,7 @@ class Image : public stdext::shared_object
|
||||||
public:
|
public:
|
||||||
Image(const Size& size, int bpp = 4, uint8 *pixels = nullptr);
|
Image(const Size& size, int bpp = 4, uint8 *pixels = nullptr);
|
||||||
|
|
||||||
static ImagePtr load(const std::string& file);
|
static ImagePtr load(std::string file);
|
||||||
static ImagePtr loadPNG(const std::string& file);
|
static ImagePtr loadPNG(const std::string& file);
|
||||||
|
|
||||||
void overwriteMask(const Color& maskedColor, const Color& insideColor = Color::white, const Color& outsideColor = Color::alpha);
|
void overwriteMask(const Color& maskedColor, const Color& insideColor = Color::white, const Color& outsideColor = Color::alpha);
|
||||||
|
|
|
@ -75,6 +75,7 @@ public:
|
||||||
virtual void drawCoords(CoordsBuffer& coordsBuffer, DrawMode drawMode = Triangles) = 0;
|
virtual void drawCoords(CoordsBuffer& coordsBuffer, DrawMode drawMode = Triangles) = 0;
|
||||||
virtual void drawTextureCoords(CoordsBuffer& coordsBuffer, const TexturePtr& texture) = 0;
|
virtual void drawTextureCoords(CoordsBuffer& coordsBuffer, const TexturePtr& texture) = 0;
|
||||||
virtual void drawTexturedRect(const Rect& dest, const TexturePtr& texture, const Rect& src) = 0;
|
virtual void drawTexturedRect(const Rect& dest, const TexturePtr& texture, const Rect& src) = 0;
|
||||||
|
virtual void drawUpsideDownTexturedRect(const Rect& dest, const TexturePtr& texture, const Rect& src) = 0;
|
||||||
void drawTexturedRect(const Rect& dest, const TexturePtr& texture) { drawTexturedRect(dest, texture, Rect(Point(0,0), texture->getSize())); }
|
void drawTexturedRect(const Rect& dest, const TexturePtr& texture) { drawTexturedRect(dest, texture, Rect(Point(0,0), texture->getSize())); }
|
||||||
virtual void drawRepeatedTexturedRect(const Rect& dest, const TexturePtr& texture, const Rect& src) = 0;
|
virtual void drawRepeatedTexturedRect(const Rect& dest, const TexturePtr& texture, const Rect& src) = 0;
|
||||||
virtual void drawFilledRect(const Rect& dest) = 0;
|
virtual void drawFilledRect(const Rect& dest) = 0;
|
||||||
|
|
|
@ -149,6 +149,18 @@ void PainterOGL1::drawTexturedRect(const Rect& dest, const TexturePtr& texture,
|
||||||
drawCoords(m_coordsBuffer, TriangleStrip);
|
drawCoords(m_coordsBuffer, TriangleStrip);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void PainterOGL1::drawUpsideDownTexturedRect(const Rect& dest, const TexturePtr& texture, const Rect& src)
|
||||||
|
{
|
||||||
|
if(dest.isEmpty() || src.isEmpty() || texture->isEmpty())
|
||||||
|
return;
|
||||||
|
|
||||||
|
setTexture(texture.get());
|
||||||
|
|
||||||
|
m_coordsBuffer.clear();
|
||||||
|
m_coordsBuffer.addUpsideDownQuad(dest, src);
|
||||||
|
drawCoords(m_coordsBuffer, TriangleStrip);
|
||||||
|
}
|
||||||
|
|
||||||
void PainterOGL1::drawRepeatedTexturedRect(const Rect& dest, const TexturePtr& texture, const Rect& src)
|
void PainterOGL1::drawRepeatedTexturedRect(const Rect& dest, const TexturePtr& texture, const Rect& src)
|
||||||
{
|
{
|
||||||
if(dest.isEmpty() || src.isEmpty() || texture->isEmpty())
|
if(dest.isEmpty() || src.isEmpty() || texture->isEmpty())
|
||||||
|
|
|
@ -51,6 +51,7 @@ public:
|
||||||
void drawCoords(CoordsBuffer& coordsBuffer, DrawMode drawMode = Triangles);
|
void drawCoords(CoordsBuffer& coordsBuffer, DrawMode drawMode = Triangles);
|
||||||
void drawTextureCoords(CoordsBuffer& coordsBuffer, const TexturePtr& texture);
|
void drawTextureCoords(CoordsBuffer& coordsBuffer, const TexturePtr& texture);
|
||||||
void drawTexturedRect(const Rect& dest, const TexturePtr& texture, const Rect& src);
|
void drawTexturedRect(const Rect& dest, const TexturePtr& texture, const Rect& src);
|
||||||
|
void drawUpsideDownTexturedRect(const Rect& dest, const TexturePtr& texture, const Rect& src);
|
||||||
void drawRepeatedTexturedRect(const Rect& dest, const TexturePtr& texture, const Rect& src);
|
void drawRepeatedTexturedRect(const Rect& dest, const TexturePtr& texture, const Rect& src);
|
||||||
void drawFilledRect(const Rect& dest);
|
void drawFilledRect(const Rect& dest);
|
||||||
void drawFilledTriangle(const Point& a, const Point& b, const Point& c);
|
void drawFilledTriangle(const Point& a, const Point& b, const Point& c);
|
||||||
|
|
|
@ -141,6 +141,19 @@ void PainterOGL2::drawTexturedRect(const Rect& dest, const TexturePtr& texture,
|
||||||
drawCoords(m_coordsBuffer, TriangleStrip);
|
drawCoords(m_coordsBuffer, TriangleStrip);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void PainterOGL2::drawUpsideDownTexturedRect(const Rect& dest, const TexturePtr& texture, const Rect& src)
|
||||||
|
{
|
||||||
|
if(dest.isEmpty() || src.isEmpty() || texture->isEmpty())
|
||||||
|
return;
|
||||||
|
|
||||||
|
setDrawProgram(m_shaderProgram ? m_shaderProgram : m_drawTexturedProgram.get());
|
||||||
|
setTexture(texture);
|
||||||
|
|
||||||
|
m_coordsBuffer.clear();
|
||||||
|
m_coordsBuffer.addUpsideDownQuad(dest, src);
|
||||||
|
drawCoords(m_coordsBuffer, TriangleStrip);
|
||||||
|
}
|
||||||
|
|
||||||
void PainterOGL2::drawRepeatedTexturedRect(const Rect& dest, const TexturePtr& texture, const Rect& src)
|
void PainterOGL2::drawRepeatedTexturedRect(const Rect& dest, const TexturePtr& texture, const Rect& src)
|
||||||
{
|
{
|
||||||
if(dest.isEmpty() || src.isEmpty() || texture->isEmpty())
|
if(dest.isEmpty() || src.isEmpty() || texture->isEmpty())
|
||||||
|
|
|
@ -43,6 +43,7 @@ public:
|
||||||
void drawCoords(CoordsBuffer& coordsBuffer, DrawMode drawMode = Triangles);
|
void drawCoords(CoordsBuffer& coordsBuffer, DrawMode drawMode = Triangles);
|
||||||
void drawTextureCoords(CoordsBuffer& coordsBuffer, const TexturePtr& texture);
|
void drawTextureCoords(CoordsBuffer& coordsBuffer, const TexturePtr& texture);
|
||||||
void drawTexturedRect(const Rect& dest, const TexturePtr& texture, const Rect& src);
|
void drawTexturedRect(const Rect& dest, const TexturePtr& texture, const Rect& src);
|
||||||
|
void drawUpsideDownTexturedRect(const Rect& dest, const TexturePtr& texture, const Rect& src);
|
||||||
void drawRepeatedTexturedRect(const Rect& dest, const TexturePtr& texture, const Rect& src);
|
void drawRepeatedTexturedRect(const Rect& dest, const TexturePtr& texture, const Rect& src);
|
||||||
void drawFilledRect(const Rect& dest);
|
void drawFilledRect(const Rect& dest);
|
||||||
void drawFilledTriangle(const Point& a, const Point& b, const Point& c);
|
void drawFilledTriangle(const Point& a, const Point& b, const Point& c);
|
||||||
|
|
|
@ -45,6 +45,8 @@ void PainterShaderProgram::setupUniforms()
|
||||||
bindUniformLocation(TIME_UNIFORM, "u_Time");
|
bindUniformLocation(TIME_UNIFORM, "u_Time");
|
||||||
bindUniformLocation(TEX0_UNIFORM, "u_Tex0");
|
bindUniformLocation(TEX0_UNIFORM, "u_Tex0");
|
||||||
bindUniformLocation(TEX1_UNIFORM, "u_Tex1");
|
bindUniformLocation(TEX1_UNIFORM, "u_Tex1");
|
||||||
|
bindUniformLocation(TEX2_UNIFORM, "u_Tex2");
|
||||||
|
bindUniformLocation(TEX3_UNIFORM, "u_Tex3");
|
||||||
bindUniformLocation(RESOLUTION_UNIFORM, "u_Resolution");
|
bindUniformLocation(RESOLUTION_UNIFORM, "u_Resolution");
|
||||||
|
|
||||||
setUniformValue(PROJECTION_MATRIX_UNIFORM, m_projectionMatrix);
|
setUniformValue(PROJECTION_MATRIX_UNIFORM, m_projectionMatrix);
|
||||||
|
@ -54,6 +56,8 @@ void PainterShaderProgram::setupUniforms()
|
||||||
setUniformValue(TIME_UNIFORM, m_time);
|
setUniformValue(TIME_UNIFORM, m_time);
|
||||||
setUniformValue(TEX0_UNIFORM, 0);
|
setUniformValue(TEX0_UNIFORM, 0);
|
||||||
setUniformValue(TEX1_UNIFORM, 1);
|
setUniformValue(TEX1_UNIFORM, 1);
|
||||||
|
setUniformValue(TEX2_UNIFORM, 2);
|
||||||
|
setUniformValue(TEX3_UNIFORM, 3);
|
||||||
setUniformValue(RESOLUTION_UNIFORM, (float)m_resolution.width(), (float)m_resolution.height());
|
setUniformValue(RESOLUTION_UNIFORM, (float)m_resolution.width(), (float)m_resolution.height());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -154,7 +158,7 @@ void PainterShaderProgram::bindMultiTextures()
|
||||||
|
|
||||||
int i=1;
|
int i=1;
|
||||||
for(const TexturePtr& tex : m_multiTextures) {
|
for(const TexturePtr& tex : m_multiTextures) {
|
||||||
glActiveTexture(GL_TEXTURE0 + 1);
|
glActiveTexture(GL_TEXTURE0 + i++);
|
||||||
glBindTexture(GL_TEXTURE_2D, tex->getId());
|
glBindTexture(GL_TEXTURE_2D, tex->getId());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -20,8 +20,8 @@
|
||||||
* THE SOFTWARE.
|
* THE SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef PAINTERSHADER_H
|
#ifndef PAINTERSHADERPROGRAM_H
|
||||||
#define PAINTERSHADER_H
|
#define PAINTERSHADERPROGRAM_H
|
||||||
|
|
||||||
#include "shaderprogram.h"
|
#include "shaderprogram.h"
|
||||||
#include "coordsbuffer.h"
|
#include "coordsbuffer.h"
|
||||||
|
@ -40,7 +40,9 @@ protected:
|
||||||
TIME_UNIFORM = 4,
|
TIME_UNIFORM = 4,
|
||||||
TEX0_UNIFORM = 5,
|
TEX0_UNIFORM = 5,
|
||||||
TEX1_UNIFORM = 6,
|
TEX1_UNIFORM = 6,
|
||||||
RESOLUTION_UNIFORM = 7,
|
TEX2_UNIFORM = 7,
|
||||||
|
TEX3_UNIFORM = 8,
|
||||||
|
RESOLUTION_UNIFORM = 9,
|
||||||
};
|
};
|
||||||
|
|
||||||
friend class PainterOGL2;
|
friend class PainterOGL2;
|
||||||
|
|
|
@ -26,9 +26,11 @@
|
||||||
|
|
||||||
ParticleManager g_particles;
|
ParticleManager g_particles;
|
||||||
|
|
||||||
bool ParticleManager::importParticle(const std::string& file)
|
bool ParticleManager::importParticle(std::string file)
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
|
file = g_resources.guessFileType(file, "otps");
|
||||||
|
|
||||||
OTMLDocumentPtr doc = OTMLDocument::parse(file);
|
OTMLDocumentPtr doc = OTMLDocument::parse(file);
|
||||||
for(const OTMLNodePtr& node : doc->children()) {
|
for(const OTMLNodePtr& node : doc->children()) {
|
||||||
if(node->tag() == "Effect") {
|
if(node->tag() == "Effect") {
|
||||||
|
|
|
@ -29,7 +29,7 @@
|
||||||
class ParticleManager
|
class ParticleManager
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
bool importParticle(const std::string& file);
|
bool importParticle(std::string file);
|
||||||
ParticleEffectPtr createEffect(const std::string& name);
|
ParticleEffectPtr createEffect(const std::string& name);
|
||||||
void terminate();
|
void terminate();
|
||||||
|
|
||||||
|
|
|
@ -80,7 +80,7 @@ bool Shader::compileSourceCode(const std::string& sourceCode)
|
||||||
bool Shader::compileSourceFile(const std::string& sourceFile)
|
bool Shader::compileSourceFile(const std::string& sourceFile)
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
std::string sourceCode = g_resources.loadFile(sourceFile);
|
std::string sourceCode = g_resources.readFileContents(sourceFile);
|
||||||
return compileSourceCode(sourceCode);
|
return compileSourceCode(sourceCode);
|
||||||
} catch(stdext::exception& e) {
|
} catch(stdext::exception& e) {
|
||||||
g_logger.error(stdext::format("unable to load shader source form file: %s", sourceFile));
|
g_logger.error(stdext::format("unable to load shader source form file: %s", sourceFile));
|
||||||
|
|
|
@ -35,10 +35,10 @@ public:
|
||||||
|
|
||||||
void bind();
|
void bind();
|
||||||
void copyFromScreen(const Rect& screenRect);
|
void copyFromScreen(const Rect& screenRect);
|
||||||
bool buildHardwareMipmaps();
|
virtual bool buildHardwareMipmaps();
|
||||||
|
|
||||||
void setSmooth(bool smooth);
|
virtual void setSmooth(bool smooth);
|
||||||
void setRepeat(bool repeat);
|
virtual void setRepeat(bool repeat);
|
||||||
void setUpsideDown(bool upsideDown);
|
void setUpsideDown(bool upsideDown);
|
||||||
|
|
||||||
uint getId() { return m_id; }
|
uint getId() { return m_id; }
|
||||||
|
@ -50,6 +50,7 @@ public:
|
||||||
bool isEmpty() { return m_id == 0; }
|
bool isEmpty() { return m_id == 0; }
|
||||||
bool hasRepeat() { return m_repeat; }
|
bool hasRepeat() { return m_repeat; }
|
||||||
bool hasMipmaps() { return m_hasMipmaps; }
|
bool hasMipmaps() { return m_hasMipmaps; }
|
||||||
|
virtual bool isAnimatedTexture() { return false; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void createTexture();
|
void createTexture();
|
||||||
|
|
|
@ -26,6 +26,7 @@
|
||||||
#include "image.h"
|
#include "image.h"
|
||||||
|
|
||||||
#include <framework/core/resourcemanager.h>
|
#include <framework/core/resourcemanager.h>
|
||||||
|
#include <framework/core/clock.h>
|
||||||
#include <framework/graphics/apngloader.h>
|
#include <framework/graphics/apngloader.h>
|
||||||
|
|
||||||
TextureManager g_textures;
|
TextureManager g_textures;
|
||||||
|
@ -38,11 +39,26 @@ void TextureManager::init()
|
||||||
void TextureManager::terminate()
|
void TextureManager::terminate()
|
||||||
{
|
{
|
||||||
m_textures.clear();
|
m_textures.clear();
|
||||||
|
m_animatedTextures.clear();
|
||||||
m_emptyTexture = nullptr;
|
m_emptyTexture = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TextureManager::poll()
|
||||||
|
{
|
||||||
|
// update only every 16msec, this allows upto 60 fps for animated textures
|
||||||
|
static ticks_t lastUpdate = 0;
|
||||||
|
ticks_t now = g_clock.millis();
|
||||||
|
if(now - lastUpdate < 16)
|
||||||
|
return;
|
||||||
|
lastUpdate = now;
|
||||||
|
|
||||||
|
for(const AnimatedTexturePtr& animatedTexture : m_animatedTextures)
|
||||||
|
animatedTexture->updateAnimation();
|
||||||
|
}
|
||||||
|
|
||||||
void TextureManager::clearTexturesCache()
|
void TextureManager::clearTexturesCache()
|
||||||
{
|
{
|
||||||
|
m_animatedTextures.clear();
|
||||||
m_textures.clear();
|
m_textures.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -62,13 +78,11 @@ TexturePtr TextureManager::getTexture(const std::string& fileName)
|
||||||
// texture not found, load it
|
// texture not found, load it
|
||||||
if(!texture) {
|
if(!texture) {
|
||||||
try {
|
try {
|
||||||
// currently only png textures are supported
|
std::string filePathEx = g_resources.guessFileType(filePath, "png");
|
||||||
if(!stdext::ends_with(filePath, ".png"))
|
|
||||||
stdext::throw_exception("texture file format not supported");
|
|
||||||
|
|
||||||
// load texture file data
|
// load texture file data
|
||||||
std::stringstream fin;
|
std::stringstream fin;
|
||||||
g_resources.loadFile(filePath, fin);
|
g_resources.readFileStream(filePathEx, fin);
|
||||||
texture = loadPNG(fin);
|
texture = loadPNG(fin);
|
||||||
} catch(stdext::exception& e) {
|
} catch(stdext::exception& e) {
|
||||||
g_logger.error(stdext::format("Unable to load texture '%s': %s", fileName, e.what()));
|
g_logger.error(stdext::format("Unable to load texture '%s': %s", fileName, e.what()));
|
||||||
|
@ -88,12 +102,22 @@ TexturePtr TextureManager::loadPNG(std::stringstream& file)
|
||||||
|
|
||||||
apng_data apng;
|
apng_data apng;
|
||||||
if(load_apng(file, &apng) == 0) {
|
if(load_apng(file, &apng) == 0) {
|
||||||
|
Size imageSize(apng.width, apng.height);
|
||||||
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);
|
std::vector<ImagePtr> frames;
|
||||||
//texture = TexturePtr(new AnimatedTexture(apng.width, apng.height, apng.bpp, apng.num_frames, framesdata, (int*)apng.frames_delay));
|
std::vector<int> framesDelay;
|
||||||
g_logger.error("animated textures is disabled for a while");
|
for(uint i=0;i<apng.num_frames;++i) {
|
||||||
|
uchar *frameData = apng.pdata + ((apng.first_frame+i) * imageSize.area() * apng.bpp);
|
||||||
|
int frameDelay = apng.frames_delay[i];
|
||||||
|
|
||||||
|
framesDelay.push_back(frameDelay);
|
||||||
|
frames.push_back(ImagePtr(new Image(imageSize, apng.bpp, frameData)));
|
||||||
|
}
|
||||||
|
AnimatedTexturePtr animatedTexture = new AnimatedTexture(imageSize, frames, framesDelay);
|
||||||
|
m_animatedTextures.push_back(animatedTexture);
|
||||||
|
texture = animatedTexture;
|
||||||
} else {
|
} else {
|
||||||
ImagePtr image = ImagePtr(new Image(Size(apng.width, apng.height), apng.bpp, apng.pdata));
|
ImagePtr image = ImagePtr(new Image(imageSize, apng.bpp, apng.pdata));
|
||||||
texture = TexturePtr(new Texture(image));
|
texture = TexturePtr(new Texture(image));
|
||||||
}
|
}
|
||||||
free_apng(&apng);
|
free_apng(&apng);
|
||||||
|
|
|
@ -30,6 +30,7 @@ class TextureManager
|
||||||
public:
|
public:
|
||||||
void init();
|
void init();
|
||||||
void terminate();
|
void terminate();
|
||||||
|
void poll();
|
||||||
|
|
||||||
void clearTexturesCache();
|
void clearTexturesCache();
|
||||||
TexturePtr getTexture(const std::string& fileName);
|
TexturePtr getTexture(const std::string& fileName);
|
||||||
|
@ -39,6 +40,7 @@ private:
|
||||||
TexturePtr loadPNG(std::stringstream& file);
|
TexturePtr loadPNG(std::stringstream& file);
|
||||||
|
|
||||||
std::unordered_map<std::string, TexturePtr> m_textures;
|
std::unordered_map<std::string, TexturePtr> m_textures;
|
||||||
|
std::vector<AnimatedTexturePtr> m_animatedTextures;
|
||||||
TexturePtr m_emptyTexture;
|
TexturePtr m_emptyTexture;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -61,6 +61,18 @@ public:
|
||||||
addVertex(right, bottom);
|
addVertex(right, bottom);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline void addUpsideDownQuad(const Rect& rect) {
|
||||||
|
float top = rect.top();
|
||||||
|
float right = rect.right()+1;
|
||||||
|
float bottom = rect.bottom()+1;
|
||||||
|
float left = rect.left();
|
||||||
|
|
||||||
|
addVertex(left, bottom);
|
||||||
|
addVertex(right, bottom);
|
||||||
|
addVertex(left, top);
|
||||||
|
addVertex(right, top);
|
||||||
|
}
|
||||||
|
|
||||||
void clear() { m_buffer.reset(); }
|
void clear() { m_buffer.reset(); }
|
||||||
float *vertices() const { return m_buffer.data(); }
|
float *vertices() const { return m_buffer.data(); }
|
||||||
int vertexCount() const { return m_buffer.size() / 2; }
|
int vertexCount() const { return m_buffer.size() / 2; }
|
||||||
|
|
|
@ -328,7 +328,9 @@ void LuaInterface::loadScript(const std::string& fileName)
|
||||||
if(!stdext::starts_with(fileName, "/"))
|
if(!stdext::starts_with(fileName, "/"))
|
||||||
filePath = getCurrentSourcePath() + "/" + filePath;
|
filePath = getCurrentSourcePath() + "/" + filePath;
|
||||||
|
|
||||||
std::string buffer = g_resources.loadFile(fileName);
|
filePath = g_resources.guessFileType(filePath, "lua");
|
||||||
|
|
||||||
|
std::string buffer = g_resources.readFileContents(filePath);
|
||||||
std::string source = "@" + filePath;
|
std::string source = "@" + filePath;
|
||||||
loadBuffer(buffer, source);
|
loadBuffer(buffer, source);
|
||||||
}
|
}
|
||||||
|
@ -560,12 +562,10 @@ int LuaInterface::luaScriptLoader(lua_State* L)
|
||||||
|
|
||||||
int LuaInterface::lua_dofile(lua_State* L)
|
int LuaInterface::lua_dofile(lua_State* L)
|
||||||
{
|
{
|
||||||
std::string fileName = g_lua.popString();
|
std::string file = g_lua.popString();
|
||||||
if(!stdext::ends_with(fileName, ".lua"))
|
|
||||||
fileName += ".lua";
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
g_lua.loadScript(fileName);
|
g_lua.loadScript(file);
|
||||||
g_lua.call(0, LUA_MULTRET);
|
g_lua.call(0, LUA_MULTRET);
|
||||||
return g_lua.stackSize();
|
return g_lua.stackSize();
|
||||||
} catch(stdext::exception& e) {
|
} catch(stdext::exception& e) {
|
||||||
|
@ -580,7 +580,7 @@ int LuaInterface::lua_dofiles(lua_State* L)
|
||||||
std::string directory = g_lua.popString();
|
std::string directory = g_lua.popString();
|
||||||
|
|
||||||
for(const std::string& fileName : g_resources.listDirectoryFiles(directory)) {
|
for(const std::string& fileName : g_resources.listDirectoryFiles(directory)) {
|
||||||
if(!stdext::ends_with(fileName, ".lua"))
|
if(!stdext::ends_with(fileName, ".lua") && !stdext::ends_with(fileName, ".bc"))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
@ -1251,4 +1251,3 @@ int LuaInterface::getTop()
|
||||||
{
|
{
|
||||||
return lua_gettop(L);
|
return lua_gettop(L);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -191,7 +191,7 @@ void Application::registerLuaFunctions()
|
||||||
g_lua.registerClass<ScheduledEvent, Event>();
|
g_lua.registerClass<ScheduledEvent, Event>();
|
||||||
g_lua.bindClassMemberFunction<ScheduledEvent>("nextCycle", &ScheduledEvent::nextCycle);
|
g_lua.bindClassMemberFunction<ScheduledEvent>("nextCycle", &ScheduledEvent::nextCycle);
|
||||||
g_lua.bindClassMemberFunction<ScheduledEvent>("ticks", &ScheduledEvent::ticks);
|
g_lua.bindClassMemberFunction<ScheduledEvent>("ticks", &ScheduledEvent::ticks);
|
||||||
g_lua.bindClassMemberFunction<ScheduledEvent>("remainingTicks", &ScheduledEvent::remainingTicks);
|
g_lua.bindClassMemberFunction<ScheduledEvent>("reamaningTicks", &ScheduledEvent::reamaningTicks);
|
||||||
g_lua.bindClassMemberFunction<ScheduledEvent>("delay", &ScheduledEvent::delay);
|
g_lua.bindClassMemberFunction<ScheduledEvent>("delay", &ScheduledEvent::delay);
|
||||||
g_lua.bindClassMemberFunction<ScheduledEvent>("cyclesExecuted", &ScheduledEvent::cyclesExecuted);
|
g_lua.bindClassMemberFunction<ScheduledEvent>("cyclesExecuted", &ScheduledEvent::cyclesExecuted);
|
||||||
g_lua.bindClassMemberFunction<ScheduledEvent>("maxCycles", &ScheduledEvent::maxCycles);
|
g_lua.bindClassMemberFunction<ScheduledEvent>("maxCycles", &ScheduledEvent::maxCycles);
|
||||||
|
|
|
@ -110,11 +110,11 @@ void Protocol::internalRecvHeader(uint8* buffer, uint16 size)
|
||||||
{
|
{
|
||||||
// read message size
|
// read message size
|
||||||
m_inputMessage->fillBuffer(buffer, size);
|
m_inputMessage->fillBuffer(buffer, size);
|
||||||
uint16 remainingSize = m_inputMessage->readSize();
|
uint16 reamaningSize = m_inputMessage->readSize();
|
||||||
|
|
||||||
// read remaining message data
|
// read reamaning message data
|
||||||
if(m_connection)
|
if(m_connection)
|
||||||
m_connection->read(remainingSize, std::bind(&Protocol::internalRecvData, asProtocol(), std::placeholders::_1, std::placeholders::_2));
|
m_connection->read(reamaningSize, std::bind(&Protocol::internalRecvData, asProtocol(), std::placeholders::_1, std::placeholders::_2));
|
||||||
}
|
}
|
||||||
|
|
||||||
void Protocol::internalRecvData(uint8* buffer, uint16 size)
|
void Protocol::internalRecvData(uint8* buffer, uint16 size)
|
||||||
|
|
|
@ -37,7 +37,7 @@ OTMLDocumentPtr OTMLDocument::parse(const std::string& fileName)
|
||||||
{
|
{
|
||||||
std::stringstream fin;
|
std::stringstream fin;
|
||||||
std::string source = g_resources.resolvePath(fileName);
|
std::string source = g_resources.resolvePath(fileName);
|
||||||
g_resources.loadFile(source, fin);
|
g_resources.readFileStream(source, fin);
|
||||||
return parse(fin, source);
|
return parse(fin, source);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -58,6 +58,6 @@ std::string OTMLDocument::emit()
|
||||||
bool OTMLDocument::save(const std::string& fileName)
|
bool OTMLDocument::save(const std::string& fileName)
|
||||||
{
|
{
|
||||||
m_source = fileName;
|
m_source = fileName;
|
||||||
return g_resources.saveFile(fileName, emit());
|
return g_resources.writeFileContents(fileName, emit());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,26 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2010-2013 OTClient <https://github.com/edubart/otclient>
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
* THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "platform.h"
|
||||||
|
#include <boost/filesystem.hpp>
|
||||||
|
|
||||||
|
Platform g_platform;
|
|
@ -0,0 +1,45 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2010-2013 OTClient <https://github.com/edubart/otclient>
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
* THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef PLATFORM_H
|
||||||
|
#define PLATFORM_H
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
class Platform
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
void processArgs(std::vector<std::string>& args);
|
||||||
|
bool spawnProcess(const std::string& process, const std::vector<std::string>& args);
|
||||||
|
int getProcessId();
|
||||||
|
std::string getTempPath();
|
||||||
|
void copyFile(std::string from, std::string to);
|
||||||
|
void openUrl(std::string url);
|
||||||
|
std::string getCPUName();
|
||||||
|
double getTotalSystemMemory();
|
||||||
|
std::string getOSName();
|
||||||
|
};
|
||||||
|
|
||||||
|
extern Platform g_platform;
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,123 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2010-2013 OTClient <https://github.com/edubart/otclient>
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
* THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef __linux
|
||||||
|
|
||||||
|
#include "platform.h"
|
||||||
|
#include <fstream>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <framework/stdext/stdext.h>
|
||||||
|
|
||||||
|
void Platform::processArgs(std::vector<std::string>& args)
|
||||||
|
{
|
||||||
|
//nothing todo, linux args are already utf8 encoded
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Platform::spawnProcess(const std::string& process, const std::vector<std::string>& args)
|
||||||
|
{
|
||||||
|
pid_t pid = fork();
|
||||||
|
if(pid == -1)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if(pid == 0) {
|
||||||
|
char* cargs[args.size()+2];
|
||||||
|
cargs[0] = (char*)process.c_str();
|
||||||
|
for(uint i=1;i<=args.size();++i)
|
||||||
|
cargs[i] = (char*)args[i-1].c_str();
|
||||||
|
cargs[args.size()+1] = 0;
|
||||||
|
|
||||||
|
execv(process.c_str(), cargs);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
int Platform::getProcessId()
|
||||||
|
{
|
||||||
|
return getpid();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string Platform::getTempPath()
|
||||||
|
{
|
||||||
|
return "/tmp/";
|
||||||
|
}
|
||||||
|
|
||||||
|
void Platform::copyFile(std::string from, std::string to)
|
||||||
|
{
|
||||||
|
system(stdext::format("/bin/cp '%s' '%s'", from, to).c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
void Platform::openUrl(std::string url)
|
||||||
|
{
|
||||||
|
if(url.find("http://") == std::string::npos)
|
||||||
|
url.insert(0, "http://");
|
||||||
|
system(stdext::format("xdg-open %s", url).c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string Platform::getCPUName()
|
||||||
|
{
|
||||||
|
std::string line;
|
||||||
|
std::ifstream in("/proc/cpuinfo");
|
||||||
|
while(getline(in, line)) {
|
||||||
|
auto strs = stdext::split(line, ":");
|
||||||
|
std::string first = strs[0];
|
||||||
|
std::string second = strs[1];
|
||||||
|
stdext::trim(first);
|
||||||
|
stdext::trim(second);
|
||||||
|
if(strs.size() == 2 && first == "model name")
|
||||||
|
return second;
|
||||||
|
}
|
||||||
|
return std::string();
|
||||||
|
}
|
||||||
|
|
||||||
|
double Platform::getTotalSystemMemory()
|
||||||
|
{
|
||||||
|
std::string line;
|
||||||
|
std::ifstream in("/proc/meminfo");
|
||||||
|
while(getline(in, line)) {
|
||||||
|
auto strs = stdext::split(line, ":");
|
||||||
|
std::string first = strs[0];
|
||||||
|
std::string second = strs[1];
|
||||||
|
stdext::trim(first);
|
||||||
|
stdext::trim(second);
|
||||||
|
if(strs.size() == 2 && first == "MemTotal")
|
||||||
|
return stdext::unsafe_cast<double>(second.substr(0, second.length() - 3)) * 1000.0;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string Platform::getOSName()
|
||||||
|
{
|
||||||
|
std::string line;
|
||||||
|
std::ifstream in("/etc/issue");
|
||||||
|
if(getline(in, line)) {
|
||||||
|
std::size_t end = line.find('\\');
|
||||||
|
std::string res = line.substr(0, end);
|
||||||
|
stdext::trim(res);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
return std::string();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,347 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2010-2013 OTClient <https://github.com/edubart/otclient>
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
* THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef WIN32
|
||||||
|
|
||||||
|
#include "platform.h"
|
||||||
|
#include <windows.h>
|
||||||
|
#include <framework/stdext/stdext.h>
|
||||||
|
#include <boost/algorithm/string.hpp>
|
||||||
|
#include <tchar.h>
|
||||||
|
|
||||||
|
|
||||||
|
void Platform::processArgs(std::vector<std::string>& args)
|
||||||
|
{
|
||||||
|
int nargs;
|
||||||
|
wchar_t **wchar_argv = CommandLineToArgvW(GetCommandLineW(), &nargs);
|
||||||
|
if(!wchar_argv)
|
||||||
|
return;
|
||||||
|
|
||||||
|
args.clear();
|
||||||
|
if(wchar_argv) {
|
||||||
|
for(int i=0;i<nargs;++i)
|
||||||
|
args.push_back(stdext::utf16_to_utf8(wchar_argv[i]));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Platform::spawnProcess(const std::string& process, const std::vector<std::string>& args)
|
||||||
|
{
|
||||||
|
std::string commandLine;
|
||||||
|
for(uint i = 0; i < args.size(); ++i)
|
||||||
|
commandLine += stdext::format(" \"%s\"", args[i]);
|
||||||
|
std::wstring wfile = stdext::utf8_to_utf16(process);
|
||||||
|
std::wstring wcommandLine = stdext::utf8_to_utf16(commandLine);
|
||||||
|
|
||||||
|
if((int)ShellExecuteW(NULL, L"open", wfile.c_str(), wcommandLine.c_str(), NULL, SW_SHOWNORMAL) > 32)
|
||||||
|
return true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
int Platform::getProcessId()
|
||||||
|
{
|
||||||
|
return GetCurrentProcessId();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string Platform::getTempPath()
|
||||||
|
{
|
||||||
|
wchar_t path[MAX_PATH];
|
||||||
|
GetTempPathW(MAX_PATH, path);
|
||||||
|
return stdext::utf16_to_utf8(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Platform::copyFile(std::string from, std::string to)
|
||||||
|
{
|
||||||
|
boost::replace_all(from, "/", "\\");
|
||||||
|
boost::replace_all(to, "/", "\\");
|
||||||
|
CopyFileW(stdext::utf8_to_utf16(from).c_str(), stdext::utf8_to_utf16(to).c_str(), false);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Platform::openUrl(std::string url)
|
||||||
|
{
|
||||||
|
if(url.find("http://") == std::string::npos)
|
||||||
|
url.insert(0, "http://");
|
||||||
|
ShellExecuteW(NULL, L"open", stdext::utf8_to_utf16(url).c_str(), NULL, NULL, SW_SHOWNORMAL);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string Platform::getCPUName()
|
||||||
|
{
|
||||||
|
char buf[1024];
|
||||||
|
memset(buf, 0, sizeof(buf));
|
||||||
|
DWORD bufSize = sizeof(buf);
|
||||||
|
HKEY hKey;
|
||||||
|
if(RegOpenKeyExA(HKEY_LOCAL_MACHINE, "HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\0", 0, KEY_READ, &hKey) != ERROR_SUCCESS)
|
||||||
|
return "";
|
||||||
|
RegQueryValueExA(hKey, "ProcessorNameString", NULL, NULL, (LPBYTE)buf, (LPDWORD)&bufSize);
|
||||||
|
return buf;
|
||||||
|
}
|
||||||
|
|
||||||
|
double Platform::getTotalSystemMemory()
|
||||||
|
{
|
||||||
|
MEMORYSTATUSEX status;
|
||||||
|
status.dwLength = sizeof(status);
|
||||||
|
GlobalMemoryStatusEx(&status);
|
||||||
|
return status.ullTotalPhys;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define PRODUCT_PROFESSIONAL 0x00000030
|
||||||
|
#define VER_SUITE_WH_SERVER 0x00008000
|
||||||
|
#define VER_PLATFORM_WIN32s 0
|
||||||
|
#define VER_PLATFORM_WIN32_WINDOWS 1
|
||||||
|
#define VER_PLATFORM_WIN32_NT 2
|
||||||
|
#define PRODUCT_UNDEFINED 0x00000000
|
||||||
|
#define PRODUCT_ULTIMATE 0x00000001
|
||||||
|
#define PRODUCT_HOME_BASIC 0x00000002
|
||||||
|
#define PRODUCT_HOME_PREMIUM 0x00000003
|
||||||
|
#define PRODUCT_ENTERPRISE 0x00000004
|
||||||
|
#define PRODUCT_HOME_BASIC_N 0x00000005
|
||||||
|
#define PRODUCT_BUSINESS 0x00000006
|
||||||
|
#define PRODUCT_STANDARD_SERVER 0x00000007
|
||||||
|
#define PRODUCT_DATACENTER_SERVER 0x00000008
|
||||||
|
#define PRODUCT_SMALLBUSINESS_SERVER 0x00000009
|
||||||
|
#define PRODUCT_ENTERPRISE_SERVER 0x0000000A
|
||||||
|
#define PRODUCT_STARTER 0x0000000B
|
||||||
|
#define PRODUCT_DATACENTER_SERVER_CORE 0x0000000C
|
||||||
|
#define PRODUCT_STANDARD_SERVER_CORE 0x0000000D
|
||||||
|
#define PRODUCT_ENTERPRISE_SERVER_CORE 0x0000000E
|
||||||
|
#define PRODUCT_ENTERPRISE_SERVER_IA64 0x0000000F
|
||||||
|
#define PRODUCT_BUSINESS_N 0x00000010
|
||||||
|
#define PRODUCT_WEB_SERVER 0x00000011
|
||||||
|
#define PRODUCT_CLUSTER_SERVER 0x00000012
|
||||||
|
#define PRODUCT_HOME_SERVER 0x00000013
|
||||||
|
#define PRODUCT_STORAGE_EXPRESS_SERVER 0x00000014
|
||||||
|
#define PRODUCT_STORAGE_STANDARD_SERVER 0x00000015
|
||||||
|
#define PRODUCT_STORAGE_WORKGROUP_SERVER 0x00000016
|
||||||
|
#define PRODUCT_STORAGE_ENTERPRISE_SERVER 0x00000017
|
||||||
|
#define PRODUCT_SERVER_FOR_SMALLBUSINESS 0x00000018
|
||||||
|
#define PRODUCT_SMALLBUSINESS_SERVER_PREMIUM 0x00000019
|
||||||
|
#define PRODUCT_HOME_PREMIUM_N 0x0000001A
|
||||||
|
#define PRODUCT_ENTERPRISE_N 0x0000001B
|
||||||
|
#define PRODUCT_ULTIMATE_N 0x0000001C
|
||||||
|
#define PRODUCT_WEB_SERVER_CORE 0x0000001D
|
||||||
|
#define PRODUCT_MEDIUMBUSINESS_SERVER_MANAGEMENT 0x0000001E
|
||||||
|
#define PRODUCT_MEDIUMBUSINESS_SERVER_SECURITY 0x0000001F
|
||||||
|
#define PRODUCT_MEDIUMBUSINESS_SERVER_MESSAGING 0x00000020
|
||||||
|
#define PRODUCT_SERVER_FOUNDATION 0x00000021
|
||||||
|
#define PRODUCT_HOME_PREMIUM_SERVER 0x00000022
|
||||||
|
#define PRODUCT_SERVER_FOR_SMALLBUSINESS_V 0x00000023
|
||||||
|
#define PRODUCT_STANDARD_SERVER_V 0x00000024
|
||||||
|
#define PRODUCT_DATACENTER_SERVER_V 0x00000025
|
||||||
|
#define PRODUCT_ENTERPRISE_SERVER_V 0x00000026
|
||||||
|
#define PRODUCT_DATACENTER_SERVER_CORE_V 0x00000027
|
||||||
|
#define PRODUCT_STANDARD_SERVER_CORE_V 0x00000028
|
||||||
|
#define PRODUCT_ENTERPRISE_SERVER_CORE_V 0x00000029
|
||||||
|
#define PRODUCT_HYPERV 0x0000002A
|
||||||
|
#define PRODUCT_STORAGE_EXPRESS_SERVER_CORE 0x0000002B
|
||||||
|
#define PRODUCT_STORAGE_STANDARD_SERVER_CORE 0x0000002C
|
||||||
|
#define PRODUCT_STORAGE_WORKGROUP_SERVER_CORE 0x0000002D
|
||||||
|
#define PRODUCT_STORAGE_ENTERPRISE_SERVER_CORE 0x0000002E
|
||||||
|
#define PRODUCT_STARTER_N 0x0000002F
|
||||||
|
#define PRODUCT_PROFESSIONAL 0x00000030
|
||||||
|
#define PRODUCT_PROFESSIONAL_N 0x00000031
|
||||||
|
#define PRODUCT_SB_SOLUTION_SERVER 0x00000032
|
||||||
|
|
||||||
|
std::string Platform::getOSName()
|
||||||
|
{
|
||||||
|
typedef void (WINAPI *PGNSI)(LPSYSTEM_INFO);
|
||||||
|
typedef BOOL (WINAPI *PGPI)(DWORD, DWORD, DWORD, DWORD, PDWORD);
|
||||||
|
|
||||||
|
std::string ret;
|
||||||
|
OSVERSIONINFOEX osvi;
|
||||||
|
SYSTEM_INFO si;
|
||||||
|
PGNSI pGNSI;
|
||||||
|
PGPI pGPI;
|
||||||
|
BOOL bOsVersionInfoEx;
|
||||||
|
DWORD dwType;
|
||||||
|
|
||||||
|
ZeroMemory(&si, sizeof(SYSTEM_INFO));
|
||||||
|
ZeroMemory(&osvi, sizeof(OSVERSIONINFOEX));
|
||||||
|
|
||||||
|
osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
|
||||||
|
bOsVersionInfoEx = GetVersionEx((OSVERSIONINFO*) &osvi);
|
||||||
|
|
||||||
|
if(!bOsVersionInfoEx)
|
||||||
|
return std::string();
|
||||||
|
|
||||||
|
pGNSI = (PGNSI) GetProcAddress(GetModuleHandle(TEXT("kernel32.dll")), "GetNativeSystemInfo");
|
||||||
|
if(NULL != pGNSI)
|
||||||
|
pGNSI(&si);
|
||||||
|
else
|
||||||
|
GetSystemInfo(&si);
|
||||||
|
|
||||||
|
if(VER_PLATFORM_WIN32_NT==osvi.dwPlatformId && osvi.dwMajorVersion > 4) {
|
||||||
|
if(osvi.dwMajorVersion == 6) {
|
||||||
|
if(osvi.dwMinorVersion == 0) {
|
||||||
|
if(osvi.wProductType == VER_NT_WORKSTATION)
|
||||||
|
ret += "Windows Vista ";
|
||||||
|
else ret += "Windows Server 2008 ";
|
||||||
|
}
|
||||||
|
|
||||||
|
if(osvi.dwMinorVersion == 1 || osvi.dwMinorVersion == 2)
|
||||||
|
{
|
||||||
|
if(osvi.wProductType == VER_NT_WORKSTATION && osvi.dwMinorVersion == 1)
|
||||||
|
ret += "Windows 7 ";
|
||||||
|
else
|
||||||
|
if(osvi.wProductType == VER_NT_WORKSTATION && osvi.dwMinorVersion == 2)
|
||||||
|
ret += "Windows 8 ";
|
||||||
|
else
|
||||||
|
ret += "Windows Server 2008 R2 ";
|
||||||
|
}
|
||||||
|
|
||||||
|
pGPI = (PGPI) GetProcAddress(GetModuleHandle(TEXT("kernel32.dll")), "GetProductInfo");
|
||||||
|
|
||||||
|
pGPI( osvi.dwMajorVersion, osvi.dwMinorVersion, 0, 0, &dwType);
|
||||||
|
|
||||||
|
switch(dwType)
|
||||||
|
{
|
||||||
|
case PRODUCT_ULTIMATE:
|
||||||
|
ret += "Ultimate Edition";
|
||||||
|
break;
|
||||||
|
case PRODUCT_PROFESSIONAL:
|
||||||
|
ret += "Professional";
|
||||||
|
break;
|
||||||
|
case PRODUCT_HOME_PREMIUM:
|
||||||
|
ret += "Home Premium Edition";
|
||||||
|
break;
|
||||||
|
case PRODUCT_HOME_BASIC:
|
||||||
|
ret += "Home Basic Edition";
|
||||||
|
break;
|
||||||
|
case PRODUCT_ENTERPRISE:
|
||||||
|
ret += "Enterprise Edition";
|
||||||
|
break;
|
||||||
|
case PRODUCT_BUSINESS:
|
||||||
|
ret += "Business Edition";
|
||||||
|
break;
|
||||||
|
case PRODUCT_STARTER:
|
||||||
|
ret += "Starter Edition";
|
||||||
|
break;
|
||||||
|
case PRODUCT_CLUSTER_SERVER:
|
||||||
|
ret += "Cluster Server Edition";
|
||||||
|
break;
|
||||||
|
case PRODUCT_DATACENTER_SERVER:
|
||||||
|
ret += "Datacenter Edition";
|
||||||
|
break;
|
||||||
|
case PRODUCT_DATACENTER_SERVER_CORE:
|
||||||
|
ret += "Datacenter Edition (core installation)";
|
||||||
|
break;
|
||||||
|
case PRODUCT_ENTERPRISE_SERVER:
|
||||||
|
ret += "Enterprise Edition";
|
||||||
|
break;
|
||||||
|
case PRODUCT_ENTERPRISE_SERVER_CORE:
|
||||||
|
ret += "Enterprise Edition (core installation)";
|
||||||
|
break;
|
||||||
|
case PRODUCT_ENTERPRISE_SERVER_IA64:
|
||||||
|
ret += "Enterprise Edition for Itanium-based Systems";
|
||||||
|
break;
|
||||||
|
case PRODUCT_SMALLBUSINESS_SERVER:
|
||||||
|
ret += "Small Business Server";
|
||||||
|
break;
|
||||||
|
case PRODUCT_SMALLBUSINESS_SERVER_PREMIUM:
|
||||||
|
ret += "Small Business Server Premium Edition";
|
||||||
|
break;
|
||||||
|
case PRODUCT_STANDARD_SERVER:
|
||||||
|
ret += "Standard Edition";
|
||||||
|
break;
|
||||||
|
case PRODUCT_STANDARD_SERVER_CORE:
|
||||||
|
ret += "Standard Edition (core installation)";
|
||||||
|
break;
|
||||||
|
case PRODUCT_WEB_SERVER:
|
||||||
|
ret += "Web Server Edition";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 2) {
|
||||||
|
if(GetSystemMetrics(SM_SERVERR2))
|
||||||
|
ret += "Windows Server 2003 R2, ";
|
||||||
|
else if(osvi.wSuiteMask & VER_SUITE_STORAGE_SERVER)
|
||||||
|
ret += "Windows Storage Server 2003";
|
||||||
|
else if(osvi.wSuiteMask & VER_SUITE_WH_SERVER)
|
||||||
|
ret += "Windows Home Server";
|
||||||
|
else if(osvi.wProductType == VER_NT_WORKSTATION && si.wProcessorArchitecture==PROCESSOR_ARCHITECTURE_AMD64)
|
||||||
|
ret += "Windows XP Professional x64 Edition";
|
||||||
|
else
|
||||||
|
ret += "Windows Server 2003, ";
|
||||||
|
|
||||||
|
if(osvi.wProductType != VER_NT_WORKSTATION) {
|
||||||
|
if(si.wProcessorArchitecture==PROCESSOR_ARCHITECTURE_IA64) {
|
||||||
|
if(osvi.wSuiteMask & VER_SUITE_DATACENTER)
|
||||||
|
ret += "Datacenter Edition for Itanium-based Systems";
|
||||||
|
else if(osvi.wSuiteMask & VER_SUITE_ENTERPRISE)
|
||||||
|
ret += "Enterprise Edition for Itanium-based Systems";
|
||||||
|
}
|
||||||
|
|
||||||
|
else if(si.wProcessorArchitecture==PROCESSOR_ARCHITECTURE_AMD64) {
|
||||||
|
if(osvi.wSuiteMask & VER_SUITE_DATACENTER)
|
||||||
|
ret += "Datacenter x64 Edition";
|
||||||
|
else if(osvi.wSuiteMask & VER_SUITE_ENTERPRISE)
|
||||||
|
ret += "Enterprise x64 Edition";
|
||||||
|
else
|
||||||
|
ret += "Standard x64 Edition";
|
||||||
|
} else {
|
||||||
|
if(osvi.wSuiteMask & VER_SUITE_COMPUTE_SERVER)
|
||||||
|
ret += "Compute Cluster Edition";
|
||||||
|
else if(osvi.wSuiteMask & VER_SUITE_DATACENTER)
|
||||||
|
ret += "Datacenter Edition";
|
||||||
|
else if(osvi.wSuiteMask & VER_SUITE_ENTERPRISE)
|
||||||
|
ret += "Enterprise Edition";
|
||||||
|
else if(osvi.wSuiteMask & VER_SUITE_BLADE)
|
||||||
|
ret += "Web Edition";
|
||||||
|
else ret += "Standard Edition";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 1) {
|
||||||
|
ret += "Windows XP ";
|
||||||
|
if(osvi.wSuiteMask & VER_SUITE_PERSONAL)
|
||||||
|
ret += "Home Edition";
|
||||||
|
else ret += "Professional";
|
||||||
|
}
|
||||||
|
|
||||||
|
if(osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 0 ) {
|
||||||
|
ret += "Windows 2000 ";
|
||||||
|
if(osvi.wProductType == VER_NT_WORKSTATION) {
|
||||||
|
ret += "Professional";
|
||||||
|
} else {
|
||||||
|
if(osvi.wSuiteMask & VER_SUITE_DATACENTER)
|
||||||
|
ret += "Datacenter Server";
|
||||||
|
else if(osvi.wSuiteMask & VER_SUITE_ENTERPRISE)
|
||||||
|
ret += "Advanced Server";
|
||||||
|
else ret += "Server";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ret += stdext::format(" (build %d)", osvi.dwBuildNumber);
|
||||||
|
|
||||||
|
if(osvi.dwMajorVersion >= 6 ) {
|
||||||
|
if(si.wProcessorArchitecture==PROCESSOR_ARCHITECTURE_AMD64 )
|
||||||
|
ret += ", 64-bit";
|
||||||
|
else if (si.wProcessorArchitecture==PROCESSOR_ARCHITECTURE_INTEL )
|
||||||
|
ret += ", 32-bit";
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
ret = "Windows";
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
|
@ -39,7 +39,9 @@ int main(int argc, const char* argv[])
|
||||||
g_client.init(args);
|
g_client.init(args);
|
||||||
|
|
||||||
// find script init.lua and run it
|
// find script init.lua and run it
|
||||||
g_resources.discoverWorkDir(g_app.getCompactName(), "init.lua");
|
if(!g_resources.discoverWorkDir("init.lua"))
|
||||||
|
g_logger.fatal("Unable to find work directory, the application cannot be initialized.");
|
||||||
|
|
||||||
if(!g_lua.safeRunScript("init.lua"))
|
if(!g_lua.safeRunScript("init.lua"))
|
||||||
g_logger.fatal("Unable to run script init.lua!");
|
g_logger.fatal("Unable to run script init.lua!");
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue