OS X pathCache compatibility; added iniCodec configuration option for international compatibility

This commit is contained in:
Mathew 2014-08-18 23:32:19 -04:00
parent 7452331e04
commit 1783d5901e
6 changed files with 128 additions and 7 deletions

View File

@ -163,3 +163,6 @@
# Activate "reverb" effect for midi playback
#
# midi.reverb=false
# Specify character encoding of Game.ini
# iniCodec=UTF-8

View File

@ -8,12 +8,16 @@ INCLUDEPATH += . src
CONFIG(release, debug|release): DEFINES += NDEBUG
CONFIG += MIDI
CONFIG += MIDI INI_CODEC
DISABLE_MIDI {
CONFIG -= MIDI
}
DISABLE_INI_CODEC {
CONFIG -= INI_CODEC
}
isEmpty(BINDING) {
BINDING = MRI
}
@ -77,8 +81,9 @@ contains(RGSS_VER, 3) {
unix {
CONFIG += link_pkgconfig
PKGCONFIG += sigc++-2.0 pixman-1 zlib physfs \
sdl2 SDL2_image SDL2_ttf SDL_sound openal
PKGCONFIG += sigc++-2.0 pixman-1 physfs \
sdl2 SDL2_image SDL2_ttf SDL_sound
LIBS += -lz
RGSS2 {
PKGCONFIG += vorbisfile
@ -112,6 +117,17 @@ unix {
LIBS += -lboost_program_options$$BOOST_LIB_SUFFIX
}
unix:!macx {
PKGCONFIG += openal
}
macx {
CONFIG -= app_bundle
QMAKE_MACOSX_DEPLOYMENT_TARGET = 10.6
INCLUDEPATH += /System/Library/Frameworks/OpenAL.framework/Headers
LIBS += -liconv -framework OpenAL
}
# Input
HEADERS += \
src/quadarray.h \
@ -248,6 +264,13 @@ MIDI {
DEFINES += MIDI
}
INI_CODEC {
DEFINES += INI_CODEC
win32 {
LIBS += -liconv
}
}
defineReplace(xxdOutput) {
return($$basename(1).xxd)
}

View File

@ -27,6 +27,10 @@
#include <fstream>
#ifdef INI_CODEC
#include <iconv.h>
#endif
#include "debugwriter.h"
#include "util.h"
@ -78,7 +82,8 @@ void Config::read(int argc, char *argv[])
PO_DESC(midi.reverb, bool) \
PO_DESC(customScript, std::string) \
PO_DESC(pathCache, bool) \
PO_DESC(useScriptNames, bool)
PO_DESC(useScriptNames, bool) \
PO_DESC(iniCodec, std::string)
// Not gonna take your shit boost
#define GUARD_ALL( exp ) try { exp } catch(...) {}
@ -141,6 +146,44 @@ static std::string baseName(const std::string &path)
return path.substr(pos + 1);
}
static std::string iconvString(iconv_t cd, const std::string &srcStr)
{
size_t srcSize = srcStr.length();
/* iconv unnecessarily requires a char** instead of const char** */
char *src = const_cast<char*>(srcStr.c_str());
size_t dstBuffSize = srcSize;
char *dstBuff = static_cast<char*>(malloc(dstBuffSize));
/* These will be changed by iconv */
size_t dstSize = dstBuffSize;
char *dst = dstBuff;
/* Continue to convert/realloc until we've converted everything */
while (iconv(cd, &src, &srcSize, &dst, &dstSize) == (size_t) -1)
{
if (errno == E2BIG)
{
/* Grow buffer and retry */
size_t total = dstBuffSize - dstSize;
dstSize += dstBuffSize;
dstBuffSize *= 2;
dstBuff = static_cast<char*>(realloc(dstBuff, dstBuffSize));
dst = dstBuff + total;
}
else
{
free(dstBuff);
return std::string();
}
}
/* Create std::string and return */
std::string dstStr(dstBuff, dstBuff + (dstBuffSize - dstSize));
free(dstBuff);
return dstStr;
}
void Config::readGameINI()
{
if (!customScript.empty())
@ -171,6 +214,16 @@ void Config::readGameINI()
strReplace(game.scripts, '\\', '/');
#ifdef INI_CODEC
if (!iniCodec.empty())
{
iconv_t cd = iconv_open("utf-8", iniCodec.c_str());
game.title = iconvString(cd, game.title);
game.scripts = iconvString(cd, game.scripts);
iconv_close(cd);
}
#endif
if (game.title.empty())
game.title = baseName(gameFolder);
}

View File

@ -67,6 +67,8 @@ struct Config
bool useScriptNames;
std::string iniCodec;
std::string customScript;
std::vector<std::string> rtps;

View File

@ -37,6 +37,10 @@
#include <algorithm>
#include <vector>
#ifdef __APPLE__
#include <iconv.h>
#endif
static inline PHYSFS_File *sdlPHYS(SDL_RWops *ops)
{
return static_cast<PHYSFS_File*>(ops->hidden.unknown.data1);
@ -137,6 +141,35 @@ struct FileSystemPrivate
std::vector<std::string> extensions[FileSystem::Undefined+1];
#ifdef __APPLE__
/* Convert NFD UTF-8 filenames to NFC UTF-8 filenames */
iconv_t nfd2nfc;
FileSystemPrivate()
{
nfd2nfc = iconv_open("utf-8", "utf-8-mac");
}
~FileSystemPrivate()
{
iconv_close(nfd2nfc);
}
void nfcFromNfd(char *dst, const char *src, size_t dstSize)
{
size_t srcSize = strlen(src);
/* Reserve room for null terminator */
--dstSize;
/* iconv takes a char** instead of a const char**, even though
* the string data isn't written to. */
iconv(nfd2nfc,
const_cast<char**>(&src), &srcSize,
&dst, &dstSize);
/* Null-terminate */
*dst = 0;
}
#endif
/* Attempt to locate an extension string in a filename.
* Either a pointer into the input string pointing at the
* extension, or null is returned */
@ -376,7 +409,14 @@ static void cacheEnumCB(void *d, const char *origdir,
else
snprintf(buf, sizeof(buf), "%s/%s", origdir, fname);
char *ptr = buf;
#ifdef __APPLE__
char bufNfc[sizeof(buf)];
p->nfcFromNfd(bufNfc, buf, sizeof(bufNfc));
#else
char *const bufNfc = buf;
#endif
char *ptr = bufNfc;
/* Trim leading slash */
if (*ptr == '/')
@ -384,7 +424,7 @@ static void cacheEnumCB(void *d, const char *origdir,
std::string mixedCase(ptr);
for (char *p = buf; *p; ++p)
for (char *p = bufNfc; *p; ++p)
*p = tolower(*p);
std::string lowerCase(ptr);

View File

@ -59,7 +59,7 @@ typedef void (APIENTRYP PFNGLACTIVETEXTUREPROC) (GLenum texture);
typedef void (APIENTRY * _GLDEBUGPROC) (GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar* message, const void *userParam);
typedef void (APIENTRYP _PFNGLDEBUGMESSAGECALLBACKPROC) (_GLDEBUGPROC callback, const void *userParam);
#ifdef GLES2_HEADER
#if defined GLES2_HEADER || defined __APPLE__
#define GL_NUM_EXTENSIONS 0x821D
/* Buffer object */