Transition from QtCore to stdc++ / STL / boost
This looks like a pretty major change, but in reality, 80% of it is just renames of types and corresponding methods. The config parsing code has been completely replaced with a boost::program_options based version. This means that the config file format slightly changed (checkout the updated README). I still expect there to be bugs / unforseen events. Those should be fixed in follow up commits. Also, finally reverted back to using pkg-config to locate and link libruby. Yay for less hacks!
This commit is contained in:
		
							parent
							
								
									01529c5741
								
							
						
					
					
						commit
						2adf8ab265
					
				
					 40 changed files with 722 additions and 456 deletions
				
			
		| 
						 | 
				
			
			@ -27,12 +27,12 @@
 | 
			
		|||
#include "filesystem.h"
 | 
			
		||||
#include "exception.h"
 | 
			
		||||
#include "al-util.h"
 | 
			
		||||
 | 
			
		||||
#include <QByteArray>
 | 
			
		||||
#include <QHash>
 | 
			
		||||
#include "boost-hash.h"
 | 
			
		||||
#include "debugwriter.h"
 | 
			
		||||
 | 
			
		||||
#include <vector>
 | 
			
		||||
#include <string>
 | 
			
		||||
#include <assert.h>
 | 
			
		||||
 | 
			
		||||
#include <SDL_audio.h>
 | 
			
		||||
#include <SDL_thread.h>
 | 
			
		||||
| 
						 | 
				
			
			@ -47,8 +47,6 @@
 | 
			
		|||
 | 
			
		||||
#include <alc.h>
 | 
			
		||||
 | 
			
		||||
#include <QDebug>
 | 
			
		||||
 | 
			
		||||
#define AUDIO_SLEEP 10
 | 
			
		||||
#define SE_SOURCES 6
 | 
			
		||||
#define SE_CACHE_MEM (10*1024*1024) // 10 MB
 | 
			
		||||
| 
						 | 
				
			
			@ -71,8 +69,8 @@ static uint8_t formatSampleSize(int sdlFormat)
 | 
			
		|||
		return 4;
 | 
			
		||||
 | 
			
		||||
	default:
 | 
			
		||||
		qDebug() << "Unhandled sample format";
 | 
			
		||||
		Q_ASSERT(0);
 | 
			
		||||
		Debug() << "Unhandled sample format";
 | 
			
		||||
		abort();
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return 0;
 | 
			
		||||
| 
						 | 
				
			
			@ -87,23 +85,23 @@ static ALenum chooseALFormat(int sampleSize, int channelCount)
 | 
			
		|||
		{
 | 
			
		||||
		case 1 : return AL_FORMAT_MONO8;
 | 
			
		||||
		case 2 : return AL_FORMAT_STEREO8;
 | 
			
		||||
		default: Q_ASSERT(0);
 | 
			
		||||
		default: abort();
 | 
			
		||||
		}
 | 
			
		||||
	case 2 :
 | 
			
		||||
		switch (channelCount)
 | 
			
		||||
		{
 | 
			
		||||
		case 1 : return AL_FORMAT_MONO16;
 | 
			
		||||
		case 2 : return AL_FORMAT_STEREO16;
 | 
			
		||||
		default : Q_ASSERT(0);
 | 
			
		||||
		default : abort();
 | 
			
		||||
		}
 | 
			
		||||
	case 4 :
 | 
			
		||||
		switch (channelCount)
 | 
			
		||||
		{
 | 
			
		||||
		case 1 : return AL_FORMAT_MONO_FLOAT32;
 | 
			
		||||
		case 2 : return AL_FORMAT_STEREO_FLOAT32;
 | 
			
		||||
		default : Q_ASSERT(0);
 | 
			
		||||
		default : abort();
 | 
			
		||||
		}
 | 
			
		||||
	default : Q_ASSERT(0);
 | 
			
		||||
	default : abort();
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return 0;
 | 
			
		||||
| 
						 | 
				
			
			@ -114,7 +112,7 @@ static const int streamBufSize = 32768;
 | 
			
		|||
struct SoundBuffer
 | 
			
		||||
{
 | 
			
		||||
	/* Uniquely identifies this or equal buffer */
 | 
			
		||||
	QByteArray key;
 | 
			
		||||
	std::string key;
 | 
			
		||||
 | 
			
		||||
	AL::Buffer::ID alBuffer;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -135,11 +133,6 @@ struct SoundBuffer
 | 
			
		|||
		alBuffer = AL::Buffer::gen();
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	~SoundBuffer()
 | 
			
		||||
	{
 | 
			
		||||
		AL::Buffer::del(alBuffer);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	static SoundBuffer *ref(SoundBuffer *buffer)
 | 
			
		||||
	{
 | 
			
		||||
		++buffer->refCount;
 | 
			
		||||
| 
						 | 
				
			
			@ -152,12 +145,20 @@ struct SoundBuffer
 | 
			
		|||
		if (--buffer->refCount == 0)
 | 
			
		||||
			delete buffer;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
	~SoundBuffer()
 | 
			
		||||
	{
 | 
			
		||||
		AL::Buffer::del(alBuffer);
 | 
			
		||||
	}
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct SoundEmitter
 | 
			
		||||
{
 | 
			
		||||
	typedef BoostHash<std::string, SoundBuffer*> BufferHash;
 | 
			
		||||
 | 
			
		||||
	IntruList<SoundBuffer> buffers;
 | 
			
		||||
	QHash<QByteArray, SoundBuffer*> bufferHash;
 | 
			
		||||
	BufferHash bufferHash;
 | 
			
		||||
 | 
			
		||||
	/* Byte count sum of all cached / playing buffers */
 | 
			
		||||
	uint32_t bufferBytes;
 | 
			
		||||
| 
						 | 
				
			
			@ -189,12 +190,12 @@ struct SoundEmitter
 | 
			
		|||
				SoundBuffer::deref(atchBufs[i]);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		QHash<QByteArray, SoundBuffer*>::iterator iter;
 | 
			
		||||
		for (iter = bufferHash.begin(); iter != bufferHash.end(); ++iter)
 | 
			
		||||
			delete iter.value();
 | 
			
		||||
		BufferHash::const_iterator iter;
 | 
			
		||||
		for (iter = bufferHash.cbegin(); iter != bufferHash.cend(); ++iter)
 | 
			
		||||
			SoundBuffer::deref(iter->second);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	void play(const QByteArray &filename,
 | 
			
		||||
	void play(const std::string &filename,
 | 
			
		||||
	          int volume,
 | 
			
		||||
	          int pitch)
 | 
			
		||||
	{
 | 
			
		||||
| 
						 | 
				
			
			@ -233,7 +234,7 @@ struct SoundEmitter
 | 
			
		|||
	}
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
	SoundBuffer *allocateBuffer(const QByteArray &filename)
 | 
			
		||||
	SoundBuffer *allocateBuffer(const std::string &filename)
 | 
			
		||||
	{
 | 
			
		||||
		SoundBuffer *buffer = bufferHash.value(filename, 0);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -252,7 +253,7 @@ private:
 | 
			
		|||
			SDL_RWops dataSource;
 | 
			
		||||
			const char *extension;
 | 
			
		||||
 | 
			
		||||
			shState->fileSystem().openRead(dataSource, filename.constData(),
 | 
			
		||||
			shState->fileSystem().openRead(dataSource, filename.c_str(),
 | 
			
		||||
			                               FileSystem::Audio, false, &extension);
 | 
			
		||||
 | 
			
		||||
			Sound_Sample *sampleHandle = Sound_NewSample(&dataSource, extension, 0, streamBufSize);
 | 
			
		||||
| 
						 | 
				
			
			@ -285,7 +286,7 @@ private:
 | 
			
		|||
			while (wouldBeBytes > SE_CACHE_MEM && !buffers.isEmpty())
 | 
			
		||||
			{
 | 
			
		||||
				SoundBuffer *last = buffers.tail();
 | 
			
		||||
				bufferHash.remove(last->key);
 | 
			
		||||
				bufferHash.erase(last->key);
 | 
			
		||||
				buffers.remove(last->link);
 | 
			
		||||
 | 
			
		||||
				wouldBeBytes -= last->bytes;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -28,9 +28,6 @@
 | 
			
		|||
 | 
			
		||||
#include <pixman.h>
 | 
			
		||||
 | 
			
		||||
#include <QString>
 | 
			
		||||
#include <QChar>
 | 
			
		||||
 | 
			
		||||
#include "gl-util.h"
 | 
			
		||||
#include "quad.h"
 | 
			
		||||
#include "quadarray.h"
 | 
			
		||||
| 
						 | 
				
			
			@ -944,6 +941,50 @@ void Bitmap::drawText(const IntRect &rect, const char *str, int align)
 | 
			
		|||
	modified();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* http://www.lemoda.net/c/utf8-to-ucs2/index.html */
 | 
			
		||||
static uint16_t utf8_to_ucs2(const char *_input,
 | 
			
		||||
                             const char **end_ptr)
 | 
			
		||||
{
 | 
			
		||||
	const unsigned char *input =
 | 
			
		||||
	        reinterpret_cast<const unsigned char*>(_input);
 | 
			
		||||
	*end_ptr = _input;
 | 
			
		||||
 | 
			
		||||
	if (input[0] == 0)
 | 
			
		||||
		return -1;
 | 
			
		||||
 | 
			
		||||
	if (input[0] < 0x80)
 | 
			
		||||
	{
 | 
			
		||||
		*end_ptr = _input + 1;
 | 
			
		||||
 | 
			
		||||
		return input[0];
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if ((input[0] & 0xE0) == 0xE0)
 | 
			
		||||
	{
 | 
			
		||||
		if (input[1] == 0 || input[2] == 0)
 | 
			
		||||
			return -1;
 | 
			
		||||
 | 
			
		||||
		*end_ptr = _input + 3;
 | 
			
		||||
 | 
			
		||||
		return (input[0] & 0x0F)<<12 |
 | 
			
		||||
		       (input[1] & 0x3F)<<6  |
 | 
			
		||||
		       (input[2] & 0x3F);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if ((input[0] & 0xC0) == 0xC0)
 | 
			
		||||
	{
 | 
			
		||||
		if (input[1] == 0)
 | 
			
		||||
			return -1;
 | 
			
		||||
 | 
			
		||||
		*end_ptr = _input + 2;
 | 
			
		||||
 | 
			
		||||
		return (input[0] & 0x1F)<<6  |
 | 
			
		||||
		       (input[1] & 0x3F);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return -1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
IntRect Bitmap::textSize(const char *str)
 | 
			
		||||
{
 | 
			
		||||
	GUARD_DISPOSED;
 | 
			
		||||
| 
						 | 
				
			
			@ -955,10 +996,14 @@ IntRect Bitmap::textSize(const char *str)
 | 
			
		|||
	int w, h;
 | 
			
		||||
	TTF_SizeUTF8(font, str, &w, &h);
 | 
			
		||||
 | 
			
		||||
	QString qstr = QString::fromUtf8(str);
 | 
			
		||||
	/* If str is one character long, *endPtr == 0 */
 | 
			
		||||
	const char *endPtr;
 | 
			
		||||
	uint16_t ucs2 = utf8_to_ucs2(str, &endPtr);
 | 
			
		||||
 | 
			
		||||
	if (p->font->getItalic() && qstr.length() == 1)
 | 
			
		||||
		TTF_GlyphMetrics(font, qstr.at(0).unicode(), 0, 0, 0, 0, &w);
 | 
			
		||||
	/* For cursive characters, returning the advance
 | 
			
		||||
	 * as width yields better results */
 | 
			
		||||
	if (p->font->getItalic() && *endPtr == '\0')
 | 
			
		||||
		TTF_GlyphMetrics(font, ucs2, 0, 0, 0, 0, &w);
 | 
			
		||||
 | 
			
		||||
	return IntRect(0, 0, w, h);
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										130
									
								
								src/boost-hash.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										130
									
								
								src/boost-hash.h
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,130 @@
 | 
			
		|||
/*
 | 
			
		||||
** boost-hash.h
 | 
			
		||||
**
 | 
			
		||||
** This file is part of mkxp.
 | 
			
		||||
**
 | 
			
		||||
** Copyright (C) 2013 Jonas Kulla <Nyocurio@gmail.com>
 | 
			
		||||
**
 | 
			
		||||
** mkxp is free software: you can redistribute it and/or modify
 | 
			
		||||
** it under the terms of the GNU General Public License as published by
 | 
			
		||||
** the Free Software Foundation, either version 2 of the License, or
 | 
			
		||||
** (at your option) any later version.
 | 
			
		||||
**
 | 
			
		||||
** mkxp is distributed in the hope that it will be useful,
 | 
			
		||||
** but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
** GNU General Public License for more details.
 | 
			
		||||
**
 | 
			
		||||
** You should have received a copy of the GNU General Public License
 | 
			
		||||
** along with mkxp.  If not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
#ifndef BOOSTHASH_H
 | 
			
		||||
#define BOOSTHASH_H
 | 
			
		||||
 | 
			
		||||
#include <boost/unordered/unordered_map.hpp>
 | 
			
		||||
#include <boost/unordered/unordered_set.hpp>
 | 
			
		||||
 | 
			
		||||
#include <utility>
 | 
			
		||||
 | 
			
		||||
/* Wrappers around the boost unordered template classes,
 | 
			
		||||
 * exposing an interface similar to Qt's QHash/QSet */
 | 
			
		||||
 | 
			
		||||
template<typename K, typename V>
 | 
			
		||||
class BoostHash
 | 
			
		||||
{
 | 
			
		||||
private:
 | 
			
		||||
	typedef boost::unordered_map<K, V> BoostType;
 | 
			
		||||
	typedef std::pair<K, V> PairType;
 | 
			
		||||
	BoostType p;
 | 
			
		||||
 | 
			
		||||
public:
 | 
			
		||||
	typedef typename BoostType::const_iterator const_iterator;
 | 
			
		||||
 | 
			
		||||
	inline bool contains(const K &key) const
 | 
			
		||||
	{
 | 
			
		||||
		const_iterator iter = p.find(key);
 | 
			
		||||
 | 
			
		||||
		return (iter != p.cend());
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	inline void insert(const K &key, const V &value)
 | 
			
		||||
	{
 | 
			
		||||
		p.insert(PairType(key, value));
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	inline void erase(const K &key)
 | 
			
		||||
	{
 | 
			
		||||
		p.erase(key);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	inline const V value(const K &key) const
 | 
			
		||||
	{
 | 
			
		||||
		const_iterator iter = p.find(key);
 | 
			
		||||
 | 
			
		||||
		if (iter == p.cend())
 | 
			
		||||
			return V();
 | 
			
		||||
 | 
			
		||||
		return iter->second;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	inline const V value(const K &key, const V &defaultValue) const
 | 
			
		||||
	{
 | 
			
		||||
		const_iterator iter = p.find(key);
 | 
			
		||||
 | 
			
		||||
		if (iter == p.cend())
 | 
			
		||||
			return defaultValue;
 | 
			
		||||
 | 
			
		||||
		return iter->second;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	inline V &operator[](const K &key)
 | 
			
		||||
	{
 | 
			
		||||
		return p[key];
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	inline const_iterator cbegin() const
 | 
			
		||||
	{
 | 
			
		||||
		return p.cbegin();
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	inline const_iterator cend() const
 | 
			
		||||
	{
 | 
			
		||||
		return p.cend();
 | 
			
		||||
	}
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template<typename K>
 | 
			
		||||
class BoostSet
 | 
			
		||||
{
 | 
			
		||||
private:
 | 
			
		||||
	typedef boost::unordered_set<K> BoostType;
 | 
			
		||||
	BoostType p;
 | 
			
		||||
 | 
			
		||||
public:
 | 
			
		||||
	typedef typename BoostType::const_iterator const_iterator;
 | 
			
		||||
 | 
			
		||||
	inline bool contains(const K &key)
 | 
			
		||||
	{
 | 
			
		||||
		const_iterator iter = p.find(key);
 | 
			
		||||
 | 
			
		||||
		return (iter != p.cend());
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	inline void insert(const K &key)
 | 
			
		||||
	{
 | 
			
		||||
		p.insert(key);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	inline const_iterator cbegin() const
 | 
			
		||||
	{
 | 
			
		||||
		return p.cbegin();
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	inline const_iterator cend() const
 | 
			
		||||
	{
 | 
			
		||||
		return p.cend();
 | 
			
		||||
	}
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#endif // BOOSTHASH_H
 | 
			
		||||
							
								
								
									
										126
									
								
								src/config.cpp
									
										
									
									
									
								
							
							
						
						
									
										126
									
								
								src/config.cpp
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -21,12 +21,16 @@
 | 
			
		|||
 | 
			
		||||
#include "config.h"
 | 
			
		||||
 | 
			
		||||
#include <QSettings>
 | 
			
		||||
#include <QFileInfo>
 | 
			
		||||
#include <QString>
 | 
			
		||||
#include <QStringList>
 | 
			
		||||
#include <QFile>
 | 
			
		||||
#include <QRegExp>
 | 
			
		||||
#include <boost/program_options/options_description.hpp>
 | 
			
		||||
#include <boost/program_options/parsers.hpp>
 | 
			
		||||
#include <boost/program_options/variables_map.hpp>
 | 
			
		||||
#include <fstream>
 | 
			
		||||
 | 
			
		||||
#include "debugwriter.h"
 | 
			
		||||
#include "util.h"
 | 
			
		||||
 | 
			
		||||
typedef std::vector<std::string> StringVec;
 | 
			
		||||
namespace po = boost::program_options;
 | 
			
		||||
 | 
			
		||||
Config::Config()
 | 
			
		||||
    : debugMode(false),
 | 
			
		||||
| 
						 | 
				
			
			@ -46,68 +50,84 @@ Config::Config()
 | 
			
		|||
 | 
			
		||||
void Config::read()
 | 
			
		||||
{
 | 
			
		||||
	QSettings confFile("mkxp.conf", QSettings::IniFormat);
 | 
			
		||||
#define PO_DESC_ALL \
 | 
			
		||||
	PO_DESC(debugMode, bool) \
 | 
			
		||||
    PO_DESC(winResizable, bool) \
 | 
			
		||||
    PO_DESC(fullscreen, bool) \
 | 
			
		||||
    PO_DESC(fixedAspectRatio, bool) \
 | 
			
		||||
    PO_DESC(smoothScaling, bool) \
 | 
			
		||||
    PO_DESC(vsync, bool) \
 | 
			
		||||
    PO_DESC(defScreenW, int) \
 | 
			
		||||
    PO_DESC(defScreenH, int) \
 | 
			
		||||
    PO_DESC(fixedFramerate, int) \
 | 
			
		||||
    PO_DESC(frameSkip, bool) \
 | 
			
		||||
    PO_DESC(solidFonts, bool) \
 | 
			
		||||
    PO_DESC(gameFolder, std::string) \
 | 
			
		||||
    PO_DESC(allowSymlinks, bool) \
 | 
			
		||||
    PO_DESC(customScript, std::string)
 | 
			
		||||
 | 
			
		||||
#define READ_VAL(key, Type) key = confFile.value(#key, key).to##Type()
 | 
			
		||||
#define PO_DESC(key, type) (#key, po::value< type >()->default_value(key))
 | 
			
		||||
 | 
			
		||||
	READ_VAL(debugMode, Bool);
 | 
			
		||||
	READ_VAL(winResizable, Bool);
 | 
			
		||||
	READ_VAL(fullscreen, Bool);
 | 
			
		||||
	READ_VAL(fixedAspectRatio, Bool);
 | 
			
		||||
	READ_VAL(smoothScaling, Bool);
 | 
			
		||||
	READ_VAL(vsync, Bool);
 | 
			
		||||
	READ_VAL(defScreenW, Int);
 | 
			
		||||
	READ_VAL(defScreenH, Int);
 | 
			
		||||
	READ_VAL(fixedFramerate, Int);
 | 
			
		||||
	READ_VAL(frameSkip, Bool);
 | 
			
		||||
	READ_VAL(solidFonts,  Bool);
 | 
			
		||||
	READ_VAL(gameFolder, ByteArray);
 | 
			
		||||
	READ_VAL(allowSymlinks, Bool);
 | 
			
		||||
	READ_VAL(customScript, ByteArray);
 | 
			
		||||
	po::options_description podesc;
 | 
			
		||||
	podesc.add_options()
 | 
			
		||||
	        PO_DESC_ALL
 | 
			
		||||
	        ("RTP", po::value<StringVec>())
 | 
			
		||||
	        ;
 | 
			
		||||
 | 
			
		||||
	QStringList _rtps = confFile.value("RTPs").toStringList();
 | 
			
		||||
	Q_FOREACH(const QString &s, _rtps)
 | 
			
		||||
		rtps.push_back(s.toUtf8());
 | 
			
		||||
	std::ifstream confFile;
 | 
			
		||||
	confFile.open("mkxp.conf");
 | 
			
		||||
 | 
			
		||||
	confFile.beginGroup("Binding");
 | 
			
		||||
	po::variables_map vm;
 | 
			
		||||
	po::store(po::parse_config_file(confFile, podesc, true), vm);
 | 
			
		||||
	po::notify(vm);
 | 
			
		||||
 | 
			
		||||
	QStringList bindingKeys = confFile.childKeys();
 | 
			
		||||
	Q_FOREACH (const QString &key, bindingKeys)
 | 
			
		||||
	{
 | 
			
		||||
		QVariant value = confFile.value(key);
 | 
			
		||||
	confFile.close();
 | 
			
		||||
 | 
			
		||||
		/* Convert QString to QByteArray */
 | 
			
		||||
		if (value.type() == QVariant::String)
 | 
			
		||||
			value = value.toString().toUtf8();
 | 
			
		||||
// Not gonna take your shit boost
 | 
			
		||||
#define GUARD_ALL( exp ) try { exp } catch(...) {}
 | 
			
		||||
 | 
			
		||||
		bindingConf.insert(key.toLatin1(), value);
 | 
			
		||||
	}
 | 
			
		||||
#undef PO_DESC
 | 
			
		||||
#define PO_DESC(key, type) GUARD_ALL( key = vm[#key].as< type >(); )
 | 
			
		||||
 | 
			
		||||
	confFile.endGroup();
 | 
			
		||||
	PO_DESC_ALL;
 | 
			
		||||
 | 
			
		||||
	GUARD_ALL( rtps = vm["RTP"].as<StringVec>(); );
 | 
			
		||||
 | 
			
		||||
#undef PO_DESC
 | 
			
		||||
#undef PO_DESC_ALL
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void Config::readGameINI()
 | 
			
		||||
{
 | 
			
		||||
	if (!customScript.isEmpty())
 | 
			
		||||
	if (!customScript.empty())
 | 
			
		||||
	{
 | 
			
		||||
		game.title = basename(customScript.constData());
 | 
			
		||||
		game.title = basename(customScript.c_str());
 | 
			
		||||
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	QSettings gameINI(gameFolder + "/Game.ini", QSettings::IniFormat);
 | 
			
		||||
	QFileInfo finfo(gameFolder.constData());
 | 
			
		||||
	game.title = gameINI.value("Game/Title", finfo.baseName()).toByteArray();
 | 
			
		||||
	po::options_description podesc;
 | 
			
		||||
	podesc.add_options()
 | 
			
		||||
	        ("Game.Title", po::value<std::string>())
 | 
			
		||||
	        ("Game.Scripts", po::value<std::string>())
 | 
			
		||||
	        ;
 | 
			
		||||
 | 
			
		||||
	/* Gotta read the "Scripts" entry manually because Qt can't handle '\' */
 | 
			
		||||
	QFile gameINIFile(gameFolder + "/Game.ini");
 | 
			
		||||
	if (gameINIFile.open(QFile::ReadOnly))
 | 
			
		||||
	{
 | 
			
		||||
		QString gameINIContents = gameINIFile.readAll();
 | 
			
		||||
		QRegExp scriptsRE(".*Scripts=(.*)\r\nTitle=.*");
 | 
			
		||||
		if (scriptsRE.exactMatch(gameINIContents))
 | 
			
		||||
		{
 | 
			
		||||
			game.scripts = scriptsRE.cap(1).toUtf8();
 | 
			
		||||
			game.scripts.replace('\\', '/');
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	std::string iniPath = gameFolder + "/Game.ini";
 | 
			
		||||
 | 
			
		||||
	std::ifstream iniFile;
 | 
			
		||||
	iniFile.open((iniPath).c_str());
 | 
			
		||||
 | 
			
		||||
	po::variables_map vm;
 | 
			
		||||
	po::store(po::parse_config_file(iniFile, podesc, true), vm);
 | 
			
		||||
	po::notify(vm);
 | 
			
		||||
 | 
			
		||||
	iniFile.close();
 | 
			
		||||
 | 
			
		||||
	GUARD_ALL( game.title = vm["Game.Title"].as<std::string>(); );
 | 
			
		||||
	GUARD_ALL( game.scripts = vm["Game.Scripts"].as<std::string>(); );
 | 
			
		||||
 | 
			
		||||
	strReplace(game.scripts, '\\', '/');
 | 
			
		||||
 | 
			
		||||
	if (game.title.empty())
 | 
			
		||||
		game.title = basename(gameFolder.c_str());
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										19
									
								
								src/config.h
									
										
									
									
									
								
							
							
						
						
									
										19
									
								
								src/config.h
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -22,10 +22,7 @@
 | 
			
		|||
#ifndef CONFIG_H
 | 
			
		||||
#define CONFIG_H
 | 
			
		||||
 | 
			
		||||
#include <QByteArray>
 | 
			
		||||
#include <QHash>
 | 
			
		||||
#include <QVariant>
 | 
			
		||||
 | 
			
		||||
#include <string>
 | 
			
		||||
#include <vector>
 | 
			
		||||
 | 
			
		||||
struct Config
 | 
			
		||||
| 
						 | 
				
			
			@ -46,20 +43,16 @@ struct Config
 | 
			
		|||
 | 
			
		||||
	bool solidFonts;
 | 
			
		||||
 | 
			
		||||
	QByteArray gameFolder;
 | 
			
		||||
	std::string gameFolder;
 | 
			
		||||
	bool allowSymlinks;
 | 
			
		||||
 | 
			
		||||
	QByteArray customScript;
 | 
			
		||||
	std::vector<QByteArray> rtps;
 | 
			
		||||
 | 
			
		||||
	/* Any values in the [Binding]
 | 
			
		||||
	 * group are collected here */
 | 
			
		||||
	QHash<QByteArray, QVariant> bindingConf;
 | 
			
		||||
	std::string customScript;
 | 
			
		||||
	std::vector<std::string> rtps;
 | 
			
		||||
 | 
			
		||||
	/* Game INI contents */
 | 
			
		||||
	struct {
 | 
			
		||||
		QByteArray scripts;
 | 
			
		||||
		QByteArray title;
 | 
			
		||||
		std::string scripts;
 | 
			
		||||
		std::string title;
 | 
			
		||||
	} game;
 | 
			
		||||
 | 
			
		||||
	Config();
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -20,42 +20,30 @@
 | 
			
		|||
*/
 | 
			
		||||
 | 
			
		||||
#include "debuglogger.h"
 | 
			
		||||
#include "debugwriter.h"
 | 
			
		||||
 | 
			
		||||
#include <glew.h>
 | 
			
		||||
 | 
			
		||||
#include <QFile>
 | 
			
		||||
#include <QTime>
 | 
			
		||||
#include <QTextStream>
 | 
			
		||||
#include <QDebug>
 | 
			
		||||
#include <iostream>
 | 
			
		||||
 | 
			
		||||
struct DebugLoggerPrivate
 | 
			
		||||
{
 | 
			
		||||
	QFile logFile;
 | 
			
		||||
	QTextStream *stream;
 | 
			
		||||
	std::ostream *stream;
 | 
			
		||||
 | 
			
		||||
	DebugLoggerPrivate(const char *logFilename)
 | 
			
		||||
	{
 | 
			
		||||
		if (logFilename)
 | 
			
		||||
		{
 | 
			
		||||
			logFile.setFileName(logFilename);
 | 
			
		||||
			logFile.open(QFile::WriteOnly);
 | 
			
		||||
			stream = new QTextStream(&logFile);
 | 
			
		||||
		}
 | 
			
		||||
		else
 | 
			
		||||
		{
 | 
			
		||||
			stream = new QTextStream(stderr, QIODevice::WriteOnly);
 | 
			
		||||
		}
 | 
			
		||||
		(void) logFilename;
 | 
			
		||||
 | 
			
		||||
		stream = &std::clog;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	~DebugLoggerPrivate()
 | 
			
		||||
	{
 | 
			
		||||
		delete stream;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	void writeTimestamp()
 | 
			
		||||
	{
 | 
			
		||||
		QTime time = QTime::currentTime();
 | 
			
		||||
		*stream << "[" << time.toString().toLatin1() << "] ";
 | 
			
		||||
		// FIXME reintroduce proper time stamps (is this even necessary??)
 | 
			
		||||
		*stream << "[GLDEBUG] ";
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	void writeLine(const char *line)
 | 
			
		||||
| 
						 | 
				
			
			@ -114,7 +102,7 @@ DebugLogger::DebugLogger(const char *filename)
 | 
			
		|||
	else if (GLEW_AMD_debug_output)
 | 
			
		||||
		glDebugMessageCallbackAMD(amdDebugFunc, p);
 | 
			
		||||
	else
 | 
			
		||||
		qDebug() << "DebugLogger: no debug extensions found";
 | 
			
		||||
		Debug() << "DebugLogger: no debug extensions found";
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
DebugLogger::~DebugLogger()
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										56
									
								
								src/debugwriter.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										56
									
								
								src/debugwriter.h
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,56 @@
 | 
			
		|||
/*
 | 
			
		||||
** debugwriter.h
 | 
			
		||||
**
 | 
			
		||||
** This file is part of mkxp.
 | 
			
		||||
**
 | 
			
		||||
** Copyright (C) 2013 Jonas Kulla <Nyocurio@gmail.com>
 | 
			
		||||
**
 | 
			
		||||
** mkxp is free software: you can redistribute it and/or modify
 | 
			
		||||
** it under the terms of the GNU General Public License as published by
 | 
			
		||||
** the Free Software Foundation, either version 2 of the License, or
 | 
			
		||||
** (at your option) any later version.
 | 
			
		||||
**
 | 
			
		||||
** mkxp is distributed in the hope that it will be useful,
 | 
			
		||||
** but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
** GNU General Public License for more details.
 | 
			
		||||
**
 | 
			
		||||
** You should have received a copy of the GNU General Public License
 | 
			
		||||
** along with mkxp.  If not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
#ifndef DEBUGWRITER_H
 | 
			
		||||
#define DEBUGWRITER_H
 | 
			
		||||
 | 
			
		||||
#include <iostream>
 | 
			
		||||
#include <sstream>
 | 
			
		||||
 | 
			
		||||
/* A cheap replacement for Debug() */
 | 
			
		||||
 | 
			
		||||
class Debug
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
	Debug()
 | 
			
		||||
	{
 | 
			
		||||
		buf << std::boolalpha;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	template<typename T>
 | 
			
		||||
	Debug &operator<<(const T &t)
 | 
			
		||||
	{
 | 
			
		||||
		buf << t;
 | 
			
		||||
		buf << " ";
 | 
			
		||||
 | 
			
		||||
		return *this;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	~Debug()
 | 
			
		||||
	{
 | 
			
		||||
		std::clog << buf.str() << "\n";
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
	std::stringstream buf;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#endif // DEBUGWRITER_H
 | 
			
		||||
| 
						 | 
				
			
			@ -29,11 +29,10 @@
 | 
			
		|||
 | 
			
		||||
#include "sharedstate.h"
 | 
			
		||||
#include "graphics.h"
 | 
			
		||||
#include "debugwriter.h"
 | 
			
		||||
 | 
			
		||||
#include <string.h>
 | 
			
		||||
 | 
			
		||||
#include <QDebug>
 | 
			
		||||
 | 
			
		||||
bool EventThread::keyStates[] = { false };
 | 
			
		||||
 | 
			
		||||
EventThread::JoyState EventThread::joyState =
 | 
			
		||||
| 
						 | 
				
			
			@ -97,7 +96,7 @@ void EventThread::process(RGSSThreadData &rtData)
 | 
			
		|||
	{
 | 
			
		||||
		if (!SDL_WaitEvent(&event))
 | 
			
		||||
		{
 | 
			
		||||
			qDebug() << "EventThread: Event error";
 | 
			
		||||
			Debug() << "EventThread: Event error";
 | 
			
		||||
			break;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -141,7 +140,7 @@ void EventThread::process(RGSSThreadData &rtData)
 | 
			
		|||
		case SDL_QUIT :
 | 
			
		||||
		case REQUEST_TERMINATION :
 | 
			
		||||
			terminate = true;
 | 
			
		||||
			qDebug() << "EventThread termination requested";
 | 
			
		||||
			Debug() << "EventThread termination requested";
 | 
			
		||||
			break;
 | 
			
		||||
 | 
			
		||||
		case SDL_KEYDOWN :
 | 
			
		||||
| 
						 | 
				
			
			@ -173,13 +172,13 @@ void EventThread::process(RGSSThreadData &rtData)
 | 
			
		|||
					if (fullscreen)
 | 
			
		||||
					{
 | 
			
		||||
						/* Prevent fullscreen flicker */
 | 
			
		||||
						strncpy(pendingTitle, rtData.config.game.title.constData(),
 | 
			
		||||
						strncpy(pendingTitle, rtData.config.game.title.c_str(),
 | 
			
		||||
						        sizeof(pendingTitle));
 | 
			
		||||
						havePendingTitle = true;
 | 
			
		||||
						break;
 | 
			
		||||
					}
 | 
			
		||||
 | 
			
		||||
					SDL_SetWindowTitle(win, rtData.config.game.title.constData());
 | 
			
		||||
					SDL_SetWindowTitle(win, rtData.config.game.title.c_str());
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
				break;
 | 
			
		||||
| 
						 | 
				
			
			@ -201,7 +200,7 @@ void EventThread::process(RGSSThreadData &rtData)
 | 
			
		|||
 | 
			
		||||
		case REQUEST_MESSAGEBOX :
 | 
			
		||||
			SDL_ShowSimpleMessageBox(event.user.code,
 | 
			
		||||
			                         rtData.config.game.title.constData(),
 | 
			
		||||
			                         rtData.config.game.title.c_str(),
 | 
			
		||||
			                         (const char*) event.user.data1, win);
 | 
			
		||||
			free(event.user.data1);
 | 
			
		||||
			msgBoxDone = true;
 | 
			
		||||
| 
						 | 
				
			
			@ -217,7 +216,7 @@ void EventThread::process(RGSSThreadData &rtData)
 | 
			
		|||
				break;
 | 
			
		||||
 | 
			
		||||
			snprintf(buffer, sizeof(buffer), "%s - %d FPS",
 | 
			
		||||
			         rtData.config.game.title.constData(), event.user.code);
 | 
			
		||||
			         rtData.config.game.title.c_str(), event.user.code);
 | 
			
		||||
 | 
			
		||||
			/* Updating the window title in fullscreen
 | 
			
		||||
			 * mode seems to cause flickering */
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -30,7 +30,7 @@
 | 
			
		|||
#include <SDL_mouse.h>
 | 
			
		||||
#include <SDL_mutex.h>
 | 
			
		||||
 | 
			
		||||
#include <QByteArray>
 | 
			
		||||
#include <string>
 | 
			
		||||
 | 
			
		||||
#include <stdint.h>
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -173,7 +173,7 @@ struct RGSSThreadData
 | 
			
		|||
 | 
			
		||||
	Config config;
 | 
			
		||||
 | 
			
		||||
	QByteArray rgssErrorMsg;
 | 
			
		||||
	std::string rgssErrorMsg;
 | 
			
		||||
 | 
			
		||||
	volatile bool rqScreenshot;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -22,7 +22,7 @@
 | 
			
		|||
#ifndef EXCEPTION_H
 | 
			
		||||
#define EXCEPTION_H
 | 
			
		||||
 | 
			
		||||
#include <QByteArray>
 | 
			
		||||
#include <string>
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
 | 
			
		||||
struct Exception
 | 
			
		||||
| 
						 | 
				
			
			@ -44,19 +44,19 @@ struct Exception
 | 
			
		|||
	};
 | 
			
		||||
 | 
			
		||||
	Type type;
 | 
			
		||||
	QByteArray fmt;
 | 
			
		||||
	QByteArray arg1;
 | 
			
		||||
	QByteArray arg2;
 | 
			
		||||
	std::string fmt;
 | 
			
		||||
	std::string arg1;
 | 
			
		||||
	std::string arg2;
 | 
			
		||||
 | 
			
		||||
	Exception(Type type, QByteArray fmt,
 | 
			
		||||
	          QByteArray arg1 = QByteArray(),
 | 
			
		||||
	          QByteArray arg2 = QByteArray())
 | 
			
		||||
	Exception(Type type, std::string fmt,
 | 
			
		||||
	          std::string arg1 = std::string(),
 | 
			
		||||
	          std::string arg2 = std::string())
 | 
			
		||||
	    : type(type), fmt(fmt), arg1(arg1), arg2(arg2)
 | 
			
		||||
	{}
 | 
			
		||||
 | 
			
		||||
	void snprintf(char *buffer, size_t bufSize) const
 | 
			
		||||
	{
 | 
			
		||||
		::snprintf(buffer, bufSize, fmt.constData(), arg1.constData(), arg2.constData());
 | 
			
		||||
		::snprintf(buffer, bufSize, fmt.c_str(), arg1.c_str(), arg2.c_str());
 | 
			
		||||
	}
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -23,22 +23,18 @@
 | 
			
		|||
 | 
			
		||||
#include "util.h"
 | 
			
		||||
#include "exception.h"
 | 
			
		||||
#include "boost-hash.h"
 | 
			
		||||
#include "debugwriter.h"
 | 
			
		||||
 | 
			
		||||
#include <physfs.h>
 | 
			
		||||
 | 
			
		||||
#include <SDL_sound.h>
 | 
			
		||||
 | 
			
		||||
#include <QHash>
 | 
			
		||||
#include <QSet>
 | 
			
		||||
#include <QByteArray>
 | 
			
		||||
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#include <algorithm>
 | 
			
		||||
#include <vector>
 | 
			
		||||
 | 
			
		||||
#include <QDebug>
 | 
			
		||||
 | 
			
		||||
struct RGSS_entryData
 | 
			
		||||
{
 | 
			
		||||
	int64_t offset;
 | 
			
		||||
| 
						 | 
				
			
			@ -73,11 +69,11 @@ struct RGSS_archiveData
 | 
			
		|||
 | 
			
		||||
	/* Maps: file path
 | 
			
		||||
	 * to:   entry data */
 | 
			
		||||
	QHash<QByteArray, RGSS_entryData> entryHash;
 | 
			
		||||
	BoostHash<std::string, RGSS_entryData> entryHash;
 | 
			
		||||
 | 
			
		||||
	/* Maps: directory path,
 | 
			
		||||
	 * to:   list of contained entries */
 | 
			
		||||
	QHash<QByteArray, QSet<QByteArray> > dirHash;
 | 
			
		||||
	BoostHash<std::string, BoostSet<std::string> > dirHash;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static bool
 | 
			
		||||
| 
						 | 
				
			
			@ -313,7 +309,7 @@ RGSS_openArchive(PHYSFS_Io *io, const char *, int forWrite)
 | 
			
		|||
	uint32_t magic = RGSS_MAGIC;
 | 
			
		||||
 | 
			
		||||
	/* Top level entry list */
 | 
			
		||||
	QSet<QByteArray> &topLevel = data->dirHash["."];
 | 
			
		||||
	BoostSet<std::string> &topLevel = data->dirHash["."];
 | 
			
		||||
 | 
			
		||||
	while (true)
 | 
			
		||||
	{
 | 
			
		||||
| 
						 | 
				
			
			@ -373,7 +369,7 @@ RGSS_openArchive(PHYSFS_Io *io, const char *, int forWrite)
 | 
			
		|||
				const char *dir = nameBuf;
 | 
			
		||||
				const char *entry = &nameBuf[i+1];
 | 
			
		||||
 | 
			
		||||
				QSet<QByteArray> &entryList = data->dirHash[dir];
 | 
			
		||||
				BoostSet<std::string> &entryList = data->dirHash[dir];
 | 
			
		||||
				entryList.insert(entry);
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -390,16 +386,16 @@ RGSS_enumerateFiles(void *opaque, const char *dirname,
 | 
			
		|||
{
 | 
			
		||||
	RGSS_archiveData *data = static_cast<RGSS_archiveData*>(opaque);
 | 
			
		||||
 | 
			
		||||
	QByteArray _dirname(dirname);
 | 
			
		||||
	std::string _dirname(dirname);
 | 
			
		||||
 | 
			
		||||
	if (!data->dirHash.contains(_dirname))
 | 
			
		||||
		return;
 | 
			
		||||
 | 
			
		||||
	const QSet<QByteArray> &entries = data->dirHash.value(_dirname);
 | 
			
		||||
	const BoostSet<std::string> &entries = data->dirHash[_dirname];
 | 
			
		||||
 | 
			
		||||
	QSet<QByteArray>::const_iterator iter;
 | 
			
		||||
	for (iter = entries.begin(); iter != entries.end(); ++iter)
 | 
			
		||||
		cb(callbackdata, origdir, iter->constData());
 | 
			
		||||
	BoostSet<std::string>::const_iterator iter;
 | 
			
		||||
	for (iter = entries.cbegin(); iter != entries.cend(); ++iter)
 | 
			
		||||
		cb(callbackdata, origdir, iter->c_str());
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static PHYSFS_Io*
 | 
			
		||||
| 
						 | 
				
			
			@ -500,9 +496,9 @@ static const PHYSFS_Archiver RGSS_Archiver =
 | 
			
		|||
struct FileSystemPrivate
 | 
			
		||||
{
 | 
			
		||||
	/* All keys are lower case */
 | 
			
		||||
	QHash<QByteArray, QByteArray> pathCache;
 | 
			
		||||
	BoostHash<std::string, std::string> pathCache;
 | 
			
		||||
 | 
			
		||||
	std::vector<QByteArray> extensions[FileSystem::Undefined];
 | 
			
		||||
	std::vector<std::string> extensions[FileSystem::Undefined];
 | 
			
		||||
 | 
			
		||||
	/* Attempt to locate an extension string in a filename.
 | 
			
		||||
	 * Either a pointer into the input string pointing at the
 | 
			
		||||
| 
						 | 
				
			
			@ -535,7 +531,7 @@ struct FileSystemPrivate
 | 
			
		|||
 | 
			
		||||
		buff[i] = '\0';
 | 
			
		||||
 | 
			
		||||
		QByteArray key(buff);
 | 
			
		||||
		std::string key(buff);
 | 
			
		||||
 | 
			
		||||
		if (pathCache.contains(key))
 | 
			
		||||
		{
 | 
			
		||||
| 
						 | 
				
			
			@ -544,17 +540,17 @@ struct FileSystemPrivate
 | 
			
		|||
			if (foundExt)
 | 
			
		||||
				*foundExt = findExt(filename);
 | 
			
		||||
 | 
			
		||||
			return pathCache[key].constData();
 | 
			
		||||
			return pathCache[key].c_str();
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		char buff2[512];
 | 
			
		||||
 | 
			
		||||
		if (type != FileSystem::Undefined)
 | 
			
		||||
		{
 | 
			
		||||
			std::vector<QByteArray> &extList = extensions[type];
 | 
			
		||||
			std::vector<std::string> &extList = extensions[type];
 | 
			
		||||
			for (size_t i = 0; i < extList.size(); ++i)
 | 
			
		||||
			{
 | 
			
		||||
				const char *ext = extList[i].constData();
 | 
			
		||||
				const char *ext = extList[i].c_str();
 | 
			
		||||
 | 
			
		||||
				snprintf(buff2, sizeof(buff2), "%s.%s", buff, ext);
 | 
			
		||||
				key = buff2;
 | 
			
		||||
| 
						 | 
				
			
			@ -564,7 +560,7 @@ struct FileSystemPrivate
 | 
			
		|||
					if (foundExt)
 | 
			
		||||
						*foundExt = ext;
 | 
			
		||||
 | 
			
		||||
					return pathCache[key].constData();
 | 
			
		||||
					return pathCache[key].c_str();
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
| 
						 | 
				
			
			@ -640,7 +636,7 @@ FileSystem::~FileSystem()
 | 
			
		|||
	delete p;
 | 
			
		||||
 | 
			
		||||
	if (PHYSFS_deinit() == 0)
 | 
			
		||||
		qDebug() << "PhyFS failed to deinit.";
 | 
			
		||||
		Debug() << "PhyFS failed to deinit.";
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void FileSystem::addPath(const char *path)
 | 
			
		||||
| 
						 | 
				
			
			@ -660,16 +656,16 @@ static void cacheEnumCB(void *d, const char *origdir,
 | 
			
		|||
	else
 | 
			
		||||
		strncpy(buf, fname, sizeof(buf));
 | 
			
		||||
 | 
			
		||||
	QByteArray mixedCase(buf);
 | 
			
		||||
	std::string mixedCase(buf);
 | 
			
		||||
 | 
			
		||||
	for (char *p = buf; *p; ++p)
 | 
			
		||||
		*p = tolower(*p);
 | 
			
		||||
 | 
			
		||||
	QByteArray lowerCase(buf);
 | 
			
		||||
	std::string lowerCase(buf);
 | 
			
		||||
 | 
			
		||||
	p->pathCache.insert(lowerCase, mixedCase);
 | 
			
		||||
 | 
			
		||||
	PHYSFS_enumerateFilesCallback(mixedCase.constData(), cacheEnumCB, p);
 | 
			
		||||
	PHYSFS_enumerateFilesCallback(mixedCase.c_str(), cacheEnumCB, p);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void FileSystem::createPathCache()
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -25,8 +25,6 @@
 | 
			
		|||
#include "etc.h"
 | 
			
		||||
#include "etc-internal.h"
 | 
			
		||||
 | 
			
		||||
#include <QDebug>
 | 
			
		||||
 | 
			
		||||
class Flashable
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										82
									
								
								src/font.cpp
									
										
									
									
									
								
							
							
						
						
									
										82
									
								
								src/font.cpp
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -24,17 +24,16 @@
 | 
			
		|||
#include "sharedstate.h"
 | 
			
		||||
#include "filesystem.h"
 | 
			
		||||
#include "exception.h"
 | 
			
		||||
#include "boost-hash.h"
 | 
			
		||||
#include "util.h"
 | 
			
		||||
 | 
			
		||||
#include <string>
 | 
			
		||||
#include <utility>
 | 
			
		||||
 | 
			
		||||
#include "../liberation.ttf.xxd"
 | 
			
		||||
 | 
			
		||||
#include <SDL_ttf.h>
 | 
			
		||||
 | 
			
		||||
#include <QHash>
 | 
			
		||||
#include <QByteArray>
 | 
			
		||||
#include <QPair>
 | 
			
		||||
 | 
			
		||||
#include <QDebug>
 | 
			
		||||
 | 
			
		||||
#define BUNDLED_FONT liberation
 | 
			
		||||
 | 
			
		||||
#define BUNDLED_FONT_D(f) assets_## f ##_ttf
 | 
			
		||||
| 
						 | 
				
			
			@ -44,11 +43,17 @@
 | 
			
		|||
#define BNDL_F_D(f) BUNDLED_FONT_D(f)
 | 
			
		||||
#define BNDL_F_L(f) BUNDLED_FONT_L(f)
 | 
			
		||||
 | 
			
		||||
typedef QPair<QByteArray, int> FontKey;
 | 
			
		||||
typedef std::pair<std::string, int> FontKey;
 | 
			
		||||
 | 
			
		||||
static void strToLower(std::string &str)
 | 
			
		||||
{
 | 
			
		||||
	for (size_t i = 0; i < str.size(); ++i)
 | 
			
		||||
		str[i] = tolower(str[i]);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
struct FontPoolPrivate
 | 
			
		||||
{
 | 
			
		||||
	QHash<FontKey, TTF_Font*> hash;
 | 
			
		||||
	BoostHash<FontKey, TTF_Font*> hash;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
FontPool::FontPool()
 | 
			
		||||
| 
						 | 
				
			
			@ -58,9 +63,9 @@ FontPool::FontPool()
 | 
			
		|||
 | 
			
		||||
FontPool::~FontPool()
 | 
			
		||||
{
 | 
			
		||||
	QHash<FontKey, TTF_Font*>::const_iterator iter;
 | 
			
		||||
	for (iter = p->hash.begin(); iter != p->hash.end(); ++iter)
 | 
			
		||||
		TTF_CloseFont(iter.value());
 | 
			
		||||
	BoostHash<FontKey, TTF_Font*>::const_iterator iter;
 | 
			
		||||
	for (iter = p->hash.cbegin(); iter != p->hash.cend(); ++iter)
 | 
			
		||||
		TTF_CloseFont(iter->second);
 | 
			
		||||
 | 
			
		||||
	delete p;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -71,16 +76,22 @@ static SDL_RWops *openBundledFont()
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
_TTF_Font *FontPool::request(const char *filename,
 | 
			
		||||
                            int size)
 | 
			
		||||
                             int size)
 | 
			
		||||
{
 | 
			
		||||
	// FIXME Find out how font path resolution is done in VX/Ace
 | 
			
		||||
	QByteArray nameKey = QByteArray(filename).toLower();
 | 
			
		||||
	nameKey.replace(' ', '_');
 | 
			
		||||
	std::string nameKey(filename);
 | 
			
		||||
	strToLower(nameKey);
 | 
			
		||||
	strReplace(nameKey, ' ', '_');
 | 
			
		||||
 | 
			
		||||
	bool useBundled = false;
 | 
			
		||||
	QByteArray path = QByteArray("Fonts/") + nameKey;
 | 
			
		||||
	if (!shState->fileSystem().exists(path.constData(), FileSystem::Font))
 | 
			
		||||
	std::string path = std::string("Fonts/") + nameKey;
 | 
			
		||||
	if (!shState->fileSystem().exists(path.c_str(), FileSystem::Font))
 | 
			
		||||
	{
 | 
			
		||||
		/* Use the same name key for the bundled font
 | 
			
		||||
		 * even when it resulted from multiple different
 | 
			
		||||
		 * font name requests. The space at the front is
 | 
			
		||||
		 * to prevent collisions (spaces are normally
 | 
			
		||||
		 * replaced with '_' */
 | 
			
		||||
		useBundled = true;
 | 
			
		||||
		nameKey = " bundled";
 | 
			
		||||
	}
 | 
			
		||||
| 
						 | 
				
			
			@ -90,14 +101,9 @@ _TTF_Font *FontPool::request(const char *filename,
 | 
			
		|||
	TTF_Font *font = p->hash.value(key, 0);
 | 
			
		||||
 | 
			
		||||
	if (font)
 | 
			
		||||
	{
 | 
			
		||||
//		static int i=0;qDebug() << "FontPool: <?+>" << i++;
 | 
			
		||||
		return font;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
//	qDebug() << "FontPool: <?->";
 | 
			
		||||
 | 
			
		||||
	/* Not in hash, create */
 | 
			
		||||
	/* Not in hash, open */
 | 
			
		||||
	SDL_RWops *ops;
 | 
			
		||||
 | 
			
		||||
	if (useBundled)
 | 
			
		||||
| 
						 | 
				
			
			@ -107,7 +113,7 @@ _TTF_Font *FontPool::request(const char *filename,
 | 
			
		|||
	else
 | 
			
		||||
	{
 | 
			
		||||
		ops = SDL_AllocRW();
 | 
			
		||||
		shState->fileSystem().openRead(*ops, path.constData(), FileSystem::Font, true);
 | 
			
		||||
		shState->fileSystem().openRead(*ops, path.c_str(), FileSystem::Font, true);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// FIXME 0.9 is guesswork at this point
 | 
			
		||||
| 
						 | 
				
			
			@ -124,7 +130,7 @@ _TTF_Font *FontPool::request(const char *filename,
 | 
			
		|||
 | 
			
		||||
struct FontPrivate
 | 
			
		||||
{
 | 
			
		||||
	QByteArray name;
 | 
			
		||||
	std::string name;
 | 
			
		||||
	int size;
 | 
			
		||||
	bool bold;
 | 
			
		||||
	bool italic;
 | 
			
		||||
| 
						 | 
				
			
			@ -132,7 +138,7 @@ struct FontPrivate
 | 
			
		|||
 | 
			
		||||
	Color colorTmp;
 | 
			
		||||
 | 
			
		||||
	static QByteArray defaultName;
 | 
			
		||||
	static std::string defaultName;
 | 
			
		||||
	static int defaultSize;
 | 
			
		||||
	static bool defaultBold;
 | 
			
		||||
	static bool defaultItalic;
 | 
			
		||||
| 
						 | 
				
			
			@ -144,15 +150,15 @@ struct FontPrivate
 | 
			
		|||
 | 
			
		||||
	FontPrivate(const char *name = 0,
 | 
			
		||||
	            int size = 0)
 | 
			
		||||
	    : name(name ? QByteArray(name) : defaultName),
 | 
			
		||||
	    : name(name ? std::string(name) : defaultName),
 | 
			
		||||
	      size(size ? size : defaultSize),
 | 
			
		||||
	      bold(defaultBold),
 | 
			
		||||
	      italic(defaultItalic),
 | 
			
		||||
	      color(&colorTmp),
 | 
			
		||||
	      colorTmp(*defaultColor)
 | 
			
		||||
	{
 | 
			
		||||
		sdlFont = shState->fontPool().request(this->name.constData(),
 | 
			
		||||
		                                     this->size);
 | 
			
		||||
		sdlFont = shState->fontPool().request(this->name.c_str(),
 | 
			
		||||
		                                      this->size);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	FontPrivate(const FontPrivate &other)
 | 
			
		||||
| 
						 | 
				
			
			@ -166,19 +172,19 @@ struct FontPrivate
 | 
			
		|||
	{}
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
QByteArray FontPrivate::defaultName   = "Arial";
 | 
			
		||||
int        FontPrivate::defaultSize   = 22;
 | 
			
		||||
bool       FontPrivate::defaultBold   = false;
 | 
			
		||||
bool       FontPrivate::defaultItalic = false;
 | 
			
		||||
Color     *FontPrivate::defaultColor  = &FontPrivate::defaultColorTmp;
 | 
			
		||||
std::string FontPrivate::defaultName   = "Arial";
 | 
			
		||||
int         FontPrivate::defaultSize   = 22;
 | 
			
		||||
bool        FontPrivate::defaultBold   = false;
 | 
			
		||||
bool        FontPrivate::defaultItalic = false;
 | 
			
		||||
Color      *FontPrivate::defaultColor  = &FontPrivate::defaultColorTmp;
 | 
			
		||||
 | 
			
		||||
Color FontPrivate::defaultColorTmp(255, 255, 255, 255);
 | 
			
		||||
 | 
			
		||||
bool Font::doesExist(const char *name)
 | 
			
		||||
{
 | 
			
		||||
	QByteArray path = QByteArray("fonts/") + QByteArray(name);
 | 
			
		||||
	std::string path = std::string("fonts/") + std::string(name);
 | 
			
		||||
 | 
			
		||||
	return shState->fileSystem().exists(path.constData(), FileSystem::Font);
 | 
			
		||||
	return shState->fileSystem().exists(path.c_str(), FileSystem::Font);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
Font::Font(const char *name,
 | 
			
		||||
| 
						 | 
				
			
			@ -199,7 +205,7 @@ Font::~Font()
 | 
			
		|||
 | 
			
		||||
const char *Font::getName() const
 | 
			
		||||
{
 | 
			
		||||
	return p->name.constData();
 | 
			
		||||
	return p->name.c_str();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void Font::setName(const char *value)
 | 
			
		||||
| 
						 | 
				
			
			@ -213,7 +219,7 @@ void Font::setSize(int value)
 | 
			
		|||
		return;
 | 
			
		||||
 | 
			
		||||
	p->size = value;
 | 
			
		||||
	p->sdlFont = shState->fontPool().request(p->name.constData(), value);
 | 
			
		||||
	p->sdlFont = shState->fontPool().request(p->name.c_str(), value);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#undef CHK_DISP
 | 
			
		||||
| 
						 | 
				
			
			@ -231,7 +237,7 @@ DEF_ATTR_SIMPLE_STATIC(Font, DefaultColor, Color*, FontPrivate::defaultColor)
 | 
			
		|||
 | 
			
		||||
const char *Font::getDefaultName()
 | 
			
		||||
{
 | 
			
		||||
	return FontPrivate::defaultName.constData();
 | 
			
		||||
	return FontPrivate::defaultName.c_str();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void Font::setDefaultName(const char *value)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										43
									
								
								src/main.cpp
									
										
									
									
									
								
							
							
						
						
									
										43
									
								
								src/main.cpp
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -27,14 +27,15 @@
 | 
			
		|||
#include <SDL_ttf.h>
 | 
			
		||||
#include <SDL_sound.h>
 | 
			
		||||
 | 
			
		||||
#include <string>
 | 
			
		||||
 | 
			
		||||
#include "sharedstate.h"
 | 
			
		||||
#include "eventthread.h"
 | 
			
		||||
#include "debuglogger.h"
 | 
			
		||||
#include "debugwriter.h"
 | 
			
		||||
 | 
			
		||||
#include "binding.h"
 | 
			
		||||
 | 
			
		||||
#include <QDebug>
 | 
			
		||||
 | 
			
		||||
static const char *reqExt[] =
 | 
			
		||||
{
 | 
			
		||||
	"GL_ARB_fragment_shader",
 | 
			
		||||
| 
						 | 
				
			
			@ -53,7 +54,7 @@ static const char *reqExt[] =
 | 
			
		|||
};
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
rgssThreadError(RGSSThreadData *rtData, const QByteArray &msg)
 | 
			
		||||
rgssThreadError(RGSSThreadData *rtData, const std::string &msg)
 | 
			
		||||
{
 | 
			
		||||
	rtData->rgssErrorMsg = msg;
 | 
			
		||||
	rtData->ethread->requestTerminate();
 | 
			
		||||
| 
						 | 
				
			
			@ -69,10 +70,10 @@ glGetStringInt(GLenum name)
 | 
			
		|||
static void
 | 
			
		||||
printGLInfo()
 | 
			
		||||
{
 | 
			
		||||
	qDebug() << "GL Vendor    :" << glGetStringInt(GL_VENDOR);
 | 
			
		||||
	qDebug() << "GL Renderer  :" << glGetStringInt(GL_RENDERER);
 | 
			
		||||
	qDebug() << "GL Version   :" << glGetStringInt(GL_VERSION);
 | 
			
		||||
	qDebug() << "GLSL Version :" << glGetStringInt(GL_SHADING_LANGUAGE_VERSION);
 | 
			
		||||
	Debug() << "GL Vendor    :" << glGetStringInt(GL_VENDOR);
 | 
			
		||||
	Debug() << "GL Renderer  :" << glGetStringInt(GL_RENDERER);
 | 
			
		||||
	Debug() << "GL Version   :" << glGetStringInt(GL_VERSION);
 | 
			
		||||
	Debug() << "GLSL Version :" << glGetStringInt(GL_SHADING_LANGUAGE_VERSION);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int rgssThreadFun(void *userdata)
 | 
			
		||||
| 
						 | 
				
			
			@ -91,7 +92,7 @@ int rgssThreadFun(void *userdata)
 | 
			
		|||
 | 
			
		||||
	if (!glCtx)
 | 
			
		||||
	{
 | 
			
		||||
		rgssThreadError(threadData, QByteArray("Error creating context: ") + SDL_GetError());
 | 
			
		||||
		rgssThreadError(threadData, std::string("Error creating context: ") + SDL_GetError());
 | 
			
		||||
		return 0;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -121,7 +122,7 @@ int rgssThreadFun(void *userdata)
 | 
			
		|||
	{
 | 
			
		||||
		if (!glewIsSupported(reqExt[i]))
 | 
			
		||||
		{
 | 
			
		||||
			rgssThreadError(threadData, QByteArray("Required GL extension \"")
 | 
			
		||||
			rgssThreadError(threadData, std::string("Required GL extension \"")
 | 
			
		||||
			                            + reqExt[i] + "\" not present");
 | 
			
		||||
			SDL_GL_DeleteContext(glCtx);
 | 
			
		||||
			return 0;
 | 
			
		||||
| 
						 | 
				
			
			@ -181,7 +182,7 @@ int main(int, char *argv[])
 | 
			
		|||
 | 
			
		||||
	if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_JOYSTICK) < 0)
 | 
			
		||||
	{
 | 
			
		||||
		qDebug() << "Error initializing SDL:" << SDL_GetError();
 | 
			
		||||
		Debug() << "Error initializing SDL:" << SDL_GetError();
 | 
			
		||||
 | 
			
		||||
		return 0;
 | 
			
		||||
	}
 | 
			
		||||
| 
						 | 
				
			
			@ -189,7 +190,7 @@ int main(int, char *argv[])
 | 
			
		|||
	int imgFlags = IMG_INIT_PNG | IMG_INIT_JPG;
 | 
			
		||||
	if (IMG_Init(imgFlags) != imgFlags)
 | 
			
		||||
	{
 | 
			
		||||
		qDebug() << "Error initializing SDL_image:" << SDL_GetError();
 | 
			
		||||
		Debug() << "Error initializing SDL_image:" << SDL_GetError();
 | 
			
		||||
		SDL_Quit();
 | 
			
		||||
 | 
			
		||||
		return 0;
 | 
			
		||||
| 
						 | 
				
			
			@ -197,7 +198,7 @@ int main(int, char *argv[])
 | 
			
		|||
 | 
			
		||||
	if (TTF_Init() < 0)
 | 
			
		||||
	{
 | 
			
		||||
		qDebug() << "Error initializing SDL_ttf:" << SDL_GetError();
 | 
			
		||||
		Debug() << "Error initializing SDL_ttf:" << SDL_GetError();
 | 
			
		||||
		IMG_Quit();
 | 
			
		||||
		SDL_Quit();
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -206,7 +207,7 @@ int main(int, char *argv[])
 | 
			
		|||
 | 
			
		||||
	if (Sound_Init() == 0)
 | 
			
		||||
	{
 | 
			
		||||
		qDebug() << "Error initializing SDL_sound:" << Sound_GetError();
 | 
			
		||||
		Debug() << "Error initializing SDL_sound:" << Sound_GetError();
 | 
			
		||||
		TTF_Quit();
 | 
			
		||||
		IMG_Quit();
 | 
			
		||||
		SDL_Quit();
 | 
			
		||||
| 
						 | 
				
			
			@ -224,13 +225,13 @@ int main(int, char *argv[])
 | 
			
		|||
	if (conf.fullscreen)
 | 
			
		||||
		winFlags |= SDL_WINDOW_FULLSCREEN_DESKTOP;
 | 
			
		||||
 | 
			
		||||
	win = SDL_CreateWindow(conf.game.title.constData(),
 | 
			
		||||
	win = SDL_CreateWindow(conf.game.title.c_str(),
 | 
			
		||||
	                       SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED,
 | 
			
		||||
	                       conf.defScreenW, conf.defScreenH, winFlags);
 | 
			
		||||
 | 
			
		||||
	if (!win)
 | 
			
		||||
	{
 | 
			
		||||
		qDebug() << "Error creating window";
 | 
			
		||||
		Debug() << "Error creating window";
 | 
			
		||||
		return 0;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -254,7 +255,7 @@ int main(int, char *argv[])
 | 
			
		|||
		/* We can stop waiting when the request was ack'd */
 | 
			
		||||
		if (rtData.rqTermAck)
 | 
			
		||||
		{
 | 
			
		||||
			qDebug() << "RGSS thread ack'd request after" << i*10 << "ms";
 | 
			
		||||
			Debug() << "RGSS thread ack'd request after" << i*10 << "ms";
 | 
			
		||||
			break;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -267,17 +268,17 @@ int main(int, char *argv[])
 | 
			
		|||
	if (rtData.rqTermAck)
 | 
			
		||||
		SDL_WaitThread(rgssThread, 0);
 | 
			
		||||
	else
 | 
			
		||||
		SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, conf.game.title.constData(),
 | 
			
		||||
		SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, conf.game.title.c_str(),
 | 
			
		||||
		                         "The RGSS script seems to be stuck and mkxp will now force quit", win);
 | 
			
		||||
 | 
			
		||||
	if (!rtData.rgssErrorMsg.isEmpty())
 | 
			
		||||
		SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, conf.game.title.constData(),
 | 
			
		||||
		                         rtData.rgssErrorMsg.constData(), win);
 | 
			
		||||
	if (!rtData.rgssErrorMsg.empty())
 | 
			
		||||
		SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, conf.game.title.c_str(),
 | 
			
		||||
		                         rtData.rgssErrorMsg.c_str(), win);
 | 
			
		||||
 | 
			
		||||
	/* Clean up any remainin events */
 | 
			
		||||
	eventThread.cleanup();
 | 
			
		||||
 | 
			
		||||
	qDebug() << "Shutting down.";
 | 
			
		||||
	Debug() << "Shutting down.";
 | 
			
		||||
 | 
			
		||||
	SDL_DestroyWindow(win);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -3,7 +3,7 @@
 | 
			
		|||
#include <SDL_timer.h>
 | 
			
		||||
#include <glew.h>
 | 
			
		||||
 | 
			
		||||
#include <QDebug>
 | 
			
		||||
#include "debugwriter.h"
 | 
			
		||||
 | 
			
		||||
struct TimerQuery
 | 
			
		||||
{
 | 
			
		||||
| 
						 | 
				
			
			@ -132,7 +132,7 @@ struct GPUTimerGLQuery : public PerfTimer
 | 
			
		|||
		if (++counter < iter)
 | 
			
		||||
			return;
 | 
			
		||||
 | 
			
		||||
		qDebug() << "                                  "
 | 
			
		||||
		Debug() << "                                  "
 | 
			
		||||
		            "Avg. GPU time:" << ((double) acc / (iter * 1000 * 1000)) << "ms";
 | 
			
		||||
 | 
			
		||||
		acc = counter = 0;
 | 
			
		||||
| 
						 | 
				
			
			@ -181,7 +181,7 @@ struct CPUTimer : public PerfTimer
 | 
			
		|||
		if (++counter < iter)
 | 
			
		||||
			return;
 | 
			
		||||
 | 
			
		||||
		qDebug() << "Avg. CPU time:" << ((double) acc / (iter * (perfFreq / 1000))) << "ms";
 | 
			
		||||
		Debug() << "Avg. CPU time:" << ((double) acc / (iter * (perfFreq / 1000))) << "ms";
 | 
			
		||||
		acc = counter = 0;
 | 
			
		||||
	}
 | 
			
		||||
};
 | 
			
		||||
| 
						 | 
				
			
			@ -199,7 +199,7 @@ PerfTimer *createGPUTimer(int iter)
 | 
			
		|||
	}
 | 
			
		||||
	else
 | 
			
		||||
	{
 | 
			
		||||
		qDebug() << "GL_EXT_timer_query not present: cannot measure GPU performance";
 | 
			
		||||
		Debug() << "GL_EXT_timer_query not present: cannot measure GPU performance";
 | 
			
		||||
		return new GPUTimerDummy();
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -22,8 +22,6 @@
 | 
			
		|||
#include "scene.h"
 | 
			
		||||
#include "sharedstate.h"
 | 
			
		||||
 | 
			
		||||
#include <QDebug>
 | 
			
		||||
 | 
			
		||||
Scene::Scene()
 | 
			
		||||
{
 | 
			
		||||
	geometry.xOrigin = geometry.yOrigin = 0;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -22,10 +22,11 @@
 | 
			
		|||
#include "shader.h"
 | 
			
		||||
#include "sharedstate.h"
 | 
			
		||||
#include "glstate.h"
 | 
			
		||||
#include "debugwriter.h"
 | 
			
		||||
 | 
			
		||||
#include <glew.h>
 | 
			
		||||
 | 
			
		||||
#include <QFile>
 | 
			
		||||
#include <assert.h>
 | 
			
		||||
 | 
			
		||||
#include "../sprite.frag.xxd"
 | 
			
		||||
#include "../hue.frag.xxd"
 | 
			
		||||
| 
						 | 
				
			
			@ -48,16 +49,14 @@
 | 
			
		|||
#include "../blurV.vert.xxd"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#include <QDebug>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#define INIT_SHADER(vert, frag) \
 | 
			
		||||
{ \
 | 
			
		||||
	Shader::init(shader_##vert##_vert, shader_##vert##_vert_len, shader_##frag##_frag, shader_##frag##_frag_len); \
 | 
			
		||||
	qDebug() << "    From:" << #vert ".vert" << #frag ".frag"; \
 | 
			
		||||
	Debug() << "    From:" << #vert ".vert" << #frag ".frag"; \
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#define COMP(shader) qDebug() << "--- Compiling " #shader
 | 
			
		||||
#define COMP(shader) Debug() << "--- Compiling " #shader
 | 
			
		||||
 | 
			
		||||
#define GET_U(name) u_##name = glGetUniformLocation(program, #name)
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -98,14 +97,14 @@ void Shader::init(const unsigned char *vert, int vertSize,
 | 
			
		|||
	glCompileShader(vertShader);
 | 
			
		||||
 | 
			
		||||
	glGetObjectParameterivARB(vertShader, GL_COMPILE_STATUS, &success);
 | 
			
		||||
	Q_ASSERT(success);
 | 
			
		||||
	assert(success); // FIXME should really throw here instead
 | 
			
		||||
 | 
			
		||||
	/* Compile fragment shader */
 | 
			
		||||
	glShaderSource(fragShader, 1, (const GLchar**) &frag, (const GLint*) &fragSize);
 | 
			
		||||
	glCompileShader(fragShader);
 | 
			
		||||
 | 
			
		||||
	glGetObjectParameterivARB(fragShader, GL_COMPILE_STATUS, &success);
 | 
			
		||||
	Q_ASSERT(success);
 | 
			
		||||
	assert(success);
 | 
			
		||||
 | 
			
		||||
	/* Link shader program */
 | 
			
		||||
	glAttachShader(program, vertShader);
 | 
			
		||||
| 
						 | 
				
			
			@ -118,23 +117,17 @@ void Shader::init(const unsigned char *vert, int vertSize,
 | 
			
		|||
	glLinkProgram(program);
 | 
			
		||||
 | 
			
		||||
	glGetObjectParameterivARB(program, GL_LINK_STATUS, &success);
 | 
			
		||||
	Q_ASSERT(success);
 | 
			
		||||
	assert(success);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void Shader::initFromFile(const char *_vertFile, const char *_fragFile)
 | 
			
		||||
{
 | 
			
		||||
	QFile vertFile(_vertFile);
 | 
			
		||||
	vertFile.open(QFile::ReadOnly);
 | 
			
		||||
	QByteArray vertContents = vertFile.readAll();
 | 
			
		||||
	vertFile.close();
 | 
			
		||||
	std::string vertContents, fragContents;
 | 
			
		||||
	readFile(_vertFile, vertContents);
 | 
			
		||||
	readFile(_fragFile, fragContents);
 | 
			
		||||
 | 
			
		||||
	QFile fragFile(_fragFile);
 | 
			
		||||
	fragFile.open(QFile::ReadOnly);
 | 
			
		||||
	QByteArray fragContents = fragFile.readAll();
 | 
			
		||||
	fragFile.close();
 | 
			
		||||
 | 
			
		||||
	init((const unsigned char*) vertContents.constData(), vertContents.size(),
 | 
			
		||||
	     (const unsigned char*) fragContents.constData(), fragContents.size());
 | 
			
		||||
	init((const unsigned char*) vertContents.c_str(), vertContents.size(),
 | 
			
		||||
	     (const unsigned char*) fragContents.c_str(), fragContents.size());
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void Shader::setVec4Uniform(GLint location, const Vec4 &vec)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -36,11 +36,9 @@
 | 
			
		|||
#include "quad.h"
 | 
			
		||||
#include "binding.h"
 | 
			
		||||
 | 
			
		||||
#include <QFile>
 | 
			
		||||
 | 
			
		||||
#include <unistd.h>
 | 
			
		||||
 | 
			
		||||
#include <QDebug>
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include <string>
 | 
			
		||||
 | 
			
		||||
SharedState *SharedState::instance = 0;
 | 
			
		||||
static GlobalIBO *globalIBO = 0;
 | 
			
		||||
| 
						 | 
				
			
			@ -93,21 +91,26 @@ struct SharedStatePrivate
 | 
			
		|||
	      graphics(threadData),
 | 
			
		||||
	      stampCounter(0)
 | 
			
		||||
	{
 | 
			
		||||
		if (!config.gameFolder.isEmpty())
 | 
			
		||||
		if (!config.gameFolder.empty())
 | 
			
		||||
		{
 | 
			
		||||
			int unused = chdir(config.gameFolder.constData());
 | 
			
		||||
			int unused = chdir(config.gameFolder.c_str());
 | 
			
		||||
			(void) unused;
 | 
			
		||||
			fileSystem.addPath(".");
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// FIXME find out correct archive filename
 | 
			
		||||
		QByteArray archPath = GAME_ARCHIVE;
 | 
			
		||||
		std::string archPath = GAME_ARCHIVE;
 | 
			
		||||
 | 
			
		||||
		if (QFile::exists(archPath.constData()))
 | 
			
		||||
			fileSystem.addPath(archPath.constData());
 | 
			
		||||
		/* Check if a game archive exists */
 | 
			
		||||
		FILE *tmp = fopen(archPath.c_str(), "r");
 | 
			
		||||
		if (tmp)
 | 
			
		||||
		{
 | 
			
		||||
			fileSystem.addPath(archPath.c_str());
 | 
			
		||||
			fclose(tmp);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		for (size_t i = 0; i < config.rtps.size(); ++i)
 | 
			
		||||
			fileSystem.addPath(config.rtps[i].constData());
 | 
			
		||||
			fileSystem.addPath(config.rtps[i].c_str());
 | 
			
		||||
 | 
			
		||||
		fileSystem.createPathCache();
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -37,8 +37,6 @@
 | 
			
		|||
 | 
			
		||||
#include <sigc++/connection.h>
 | 
			
		||||
 | 
			
		||||
#include <QDebug>
 | 
			
		||||
 | 
			
		||||
struct SpritePrivate
 | 
			
		||||
{
 | 
			
		||||
	Bitmap *bitmap;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -23,17 +23,15 @@
 | 
			
		|||
#include "exception.h"
 | 
			
		||||
#include "sharedstate.h"
 | 
			
		||||
#include "glstate.h"
 | 
			
		||||
#include "boost-hash.h"
 | 
			
		||||
#include "debugwriter.h"
 | 
			
		||||
 | 
			
		||||
#include <QHash>
 | 
			
		||||
#include <QQueue>
 | 
			
		||||
#include <QList>
 | 
			
		||||
#include <QLinkedList>
 | 
			
		||||
#include <QPair>
 | 
			
		||||
#include <list>
 | 
			
		||||
#include <utility>
 | 
			
		||||
#include <assert.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
 | 
			
		||||
#include <QDebug>
 | 
			
		||||
 | 
			
		||||
typedef QPair<uint16_t, uint16_t> Size;
 | 
			
		||||
typedef QQueue<TEXFBO> ObjList;
 | 
			
		||||
typedef std::pair<uint16_t, uint16_t> Size;
 | 
			
		||||
 | 
			
		||||
static uint32_t byteCount(Size &s)
 | 
			
		||||
{
 | 
			
		||||
| 
						 | 
				
			
			@ -43,23 +41,23 @@ static uint32_t byteCount(Size &s)
 | 
			
		|||
struct CacheNode
 | 
			
		||||
{
 | 
			
		||||
	TEXFBO obj;
 | 
			
		||||
	QLinkedList<TEXFBO>::iterator prioIter;
 | 
			
		||||
	std::list<TEXFBO>::iterator prioIter;
 | 
			
		||||
 | 
			
		||||
	bool operator==(const CacheNode &o)
 | 
			
		||||
	bool operator==(const CacheNode &o) const
 | 
			
		||||
	{
 | 
			
		||||
		return obj == o.obj;
 | 
			
		||||
	}
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
typedef QList<CacheNode> CNodeList;
 | 
			
		||||
typedef std::list<CacheNode> CNodeList;
 | 
			
		||||
 | 
			
		||||
struct TexPoolPrivate
 | 
			
		||||
{
 | 
			
		||||
	/* Contains all cached TexFBOs, grouped by size */
 | 
			
		||||
	QHash<Size, CNodeList> poolHash;
 | 
			
		||||
	BoostHash<Size, CNodeList> poolHash;
 | 
			
		||||
 | 
			
		||||
	/* Contains all cached TexFBOs, sorted by release time */
 | 
			
		||||
	QLinkedList<TEXFBO> priorityQueue;
 | 
			
		||||
	std::list<TEXFBO> priorityQueue;
 | 
			
		||||
 | 
			
		||||
	/* Maximal allowed cache memory */
 | 
			
		||||
	const uint32_t maxMemSize;
 | 
			
		||||
| 
						 | 
				
			
			@ -88,14 +86,18 @@ TexPool::TexPool(uint32_t maxMemSize)
 | 
			
		|||
 | 
			
		||||
TexPool::~TexPool()
 | 
			
		||||
{
 | 
			
		||||
	while (!p->priorityQueue.isEmpty())
 | 
			
		||||
	std::list<TEXFBO>::iterator iter;
 | 
			
		||||
 | 
			
		||||
	for (iter = p->priorityQueue.begin();
 | 
			
		||||
	     iter != p->priorityQueue.end();
 | 
			
		||||
	     ++iter)
 | 
			
		||||
	{
 | 
			
		||||
		TEXFBO obj = p->priorityQueue.takeFirst();
 | 
			
		||||
		TEXFBO obj = *iter;
 | 
			
		||||
		TEXFBO::fini(obj);
 | 
			
		||||
		--p->objCount;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	Q_ASSERT(p->objCount == 0);
 | 
			
		||||
	assert(p->objCount == 0);
 | 
			
		||||
 | 
			
		||||
	delete p;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -108,33 +110,39 @@ TEXFBO TexPool::request(int width, int height)
 | 
			
		|||
	/* See if we can statisfy request from cache */
 | 
			
		||||
	CNodeList &bucket = p->poolHash[size];
 | 
			
		||||
 | 
			
		||||
	if (!bucket.isEmpty())
 | 
			
		||||
	if (!bucket.empty())
 | 
			
		||||
	{
 | 
			
		||||
		/* Found one! */
 | 
			
		||||
		cnode = bucket.takeLast();
 | 
			
		||||
		cnode = bucket.back();
 | 
			
		||||
		bucket.pop_back();
 | 
			
		||||
 | 
			
		||||
		p->priorityQueue.erase(cnode.prioIter);
 | 
			
		||||
 | 
			
		||||
		p->memSize -= byteCount(size);
 | 
			
		||||
		--p->objCount;
 | 
			
		||||
 | 
			
		||||
//		qDebug() << "TexPool: <?+> (" << width << height << ")";
 | 
			
		||||
//		Debug() << "TexPool: <?+> (" << width << height << ")";
 | 
			
		||||
 | 
			
		||||
		return cnode.obj;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	int maxSize = glState.caps.maxTexSize;
 | 
			
		||||
	if (width > maxSize || height > maxSize)
 | 
			
		||||
		throw Exception(Exception::MKXPError,
 | 
			
		||||
		                "Texture dimensions [%s, %s] exceed hardware capabilities",
 | 
			
		||||
		                QByteArray::number(width), QByteArray::number(height));
 | 
			
		||||
	{
 | 
			
		||||
		char buffer[128];
 | 
			
		||||
		snprintf(buffer, sizeof(buffer),
 | 
			
		||||
		         "Texture dimensions [%d, %d] exceed hardware capabilities",
 | 
			
		||||
		         width, height);
 | 
			
		||||
 | 
			
		||||
		throw Exception(Exception::MKXPError, buffer);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* Nope, create it instead */
 | 
			
		||||
	TEXFBO::init(cnode.obj);
 | 
			
		||||
	TEXFBO::allocEmpty(cnode.obj, width, height);
 | 
			
		||||
	TEXFBO::linkFBO(cnode.obj);
 | 
			
		||||
 | 
			
		||||
//	qDebug() << "TexPool: <?-> (" << width << height << ")";
 | 
			
		||||
//	Debug() << "TexPool: <?-> (" << width << height << ")";
 | 
			
		||||
 | 
			
		||||
	return cnode.obj;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -150,7 +158,7 @@ void TexPool::release(TEXFBO &obj)
 | 
			
		|||
	if (p->disabled)
 | 
			
		||||
	{
 | 
			
		||||
		/* If we're disabled, delete without caching */
 | 
			
		||||
//		qDebug() << "TexPool: <!#> (" << obj.width << obj.height << ")";
 | 
			
		||||
//		Debug() << "TexPool: <!#> (" << obj.width << obj.height << ")";
 | 
			
		||||
		TEXFBO::fini(obj);
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
| 
						 | 
				
			
			@ -166,39 +174,43 @@ void TexPool::release(TEXFBO &obj)
 | 
			
		|||
		if (p->objCount == 0)
 | 
			
		||||
			break;
 | 
			
		||||
 | 
			
		||||
//		qDebug() << "TexPool: <!~> Size:" << p->memSize;
 | 
			
		||||
//		Debug() << "TexPool: <!~> Size:" << p->memSize;
 | 
			
		||||
 | 
			
		||||
		/* Retrieve object with lowest priority for deletion */
 | 
			
		||||
		CacheNode last;
 | 
			
		||||
		last.obj = p->priorityQueue.last();
 | 
			
		||||
		last.obj = p->priorityQueue.back();
 | 
			
		||||
		Size removedSize(last.obj.width, last.obj.height);
 | 
			
		||||
 | 
			
		||||
		CNodeList &bucket = p->poolHash[removedSize];
 | 
			
		||||
		Q_ASSERT(bucket.contains(last));
 | 
			
		||||
		bucket.removeOne(last);
 | 
			
		||||
		p->priorityQueue.removeLast();
 | 
			
		||||
 | 
			
		||||
		std::list<CacheNode>::iterator toRemove =
 | 
			
		||||
		        std::find(bucket.begin(), bucket.end(), last);
 | 
			
		||||
		assert(toRemove != bucket.end());
 | 
			
		||||
		bucket.erase(toRemove);
 | 
			
		||||
 | 
			
		||||
		p->priorityQueue.pop_back();
 | 
			
		||||
 | 
			
		||||
		TEXFBO::fini(last.obj);
 | 
			
		||||
 | 
			
		||||
		newMemSize -= byteCount(removedSize);;
 | 
			
		||||
		newMemSize -= byteCount(removedSize);
 | 
			
		||||
		--p->objCount;
 | 
			
		||||
 | 
			
		||||
//		qDebug() << "TexPool: <!-> (" << last.obj.tex << last.obj.fbo << ")";
 | 
			
		||||
//		Debug() << "TexPool: <!-> (" << last.obj.width << last.obj.height << ")";
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	p->memSize = newMemSize;
 | 
			
		||||
 | 
			
		||||
	/* Retain object */
 | 
			
		||||
	p->priorityQueue.prepend(obj);
 | 
			
		||||
	p->priorityQueue.push_front(obj);
 | 
			
		||||
	CacheNode cnode;
 | 
			
		||||
	cnode.obj = obj;
 | 
			
		||||
	cnode.prioIter = p->priorityQueue.begin();
 | 
			
		||||
	CNodeList &bucket = p->poolHash[size];
 | 
			
		||||
	bucket.append(cnode);
 | 
			
		||||
	bucket.push_back(cnode);
 | 
			
		||||
 | 
			
		||||
	++p->objCount;
 | 
			
		||||
 | 
			
		||||
//	qDebug() << "TexPool: <!+> (" << obj.width << obj.height << ") Current size:" << p->memSize;
 | 
			
		||||
//	Debug() << "TexPool: <!+> (" << obj.width << obj.height << ") Current size:" << p->memSize;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void TexPool::disable()
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										37
									
								
								src/util.h
									
										
									
									
									
								
							
							
						
						
									
										37
									
								
								src/util.h
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -22,6 +22,9 @@
 | 
			
		|||
#ifndef UTIL_H
 | 
			
		||||
#define UTIL_H
 | 
			
		||||
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include <string>
 | 
			
		||||
 | 
			
		||||
static inline int
 | 
			
		||||
wrapRange(int value, int min, int max)
 | 
			
		||||
{
 | 
			
		||||
| 
						 | 
				
			
			@ -56,6 +59,40 @@ findNextPow2(int start)
 | 
			
		|||
	return i;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Reads the contents of the file at 'path' and
 | 
			
		||||
 * appends them to 'out'. Returns false on failure */
 | 
			
		||||
inline bool readFile(const char *path,
 | 
			
		||||
                     std::string &out)
 | 
			
		||||
{
 | 
			
		||||
	FILE *f = fopen(path, "r");
 | 
			
		||||
 | 
			
		||||
	if (!f)
 | 
			
		||||
		return false;
 | 
			
		||||
 | 
			
		||||
	fseek(f, 0, SEEK_END);
 | 
			
		||||
	long size = ftell(f);
 | 
			
		||||
	fseek(f, 0, SEEK_SET);
 | 
			
		||||
 | 
			
		||||
	size_t back = out.size();
 | 
			
		||||
 | 
			
		||||
	out.resize(back+size);
 | 
			
		||||
	size_t read = fread(&out[back], 1, size, f);
 | 
			
		||||
	fclose(f);
 | 
			
		||||
 | 
			
		||||
	if (read != (size_t) size)
 | 
			
		||||
		out.resize(back+read);
 | 
			
		||||
 | 
			
		||||
	return true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
inline void strReplace(std::string &str,
 | 
			
		||||
                       char before, char after)
 | 
			
		||||
{
 | 
			
		||||
	for (size_t i = 0; i < str.size(); ++i)
 | 
			
		||||
		if (str[i] == before)
 | 
			
		||||
			str[i] = after;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#define ARRAY_SIZE(obj) (sizeof(obj) / sizeof((obj)[0]))
 | 
			
		||||
 | 
			
		||||
#define elementsN(obj) const int obj##N = ARRAY_SIZE(obj)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -31,8 +31,6 @@
 | 
			
		|||
 | 
			
		||||
#include <sigc++/connection.h>
 | 
			
		||||
 | 
			
		||||
#include <QDebug>
 | 
			
		||||
 | 
			
		||||
struct ViewportPrivate
 | 
			
		||||
{
 | 
			
		||||
	/* Needed for geometry changes */
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -36,8 +36,6 @@
 | 
			
		|||
 | 
			
		||||
#include <sigc++/connection.h>
 | 
			
		||||
 | 
			
		||||
#include <QDebug>
 | 
			
		||||
 | 
			
		||||
template<typename T>
 | 
			
		||||
struct Sides
 | 
			
		||||
{
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue