mirror of
https://github.com/mkxp-z/mkxp-z.git
synced 2025-08-04 22:15:33 +02:00
Guess and convert the encoding of the game title (again)
This commit is contained in:
parent
af1924abd9
commit
b6ea039803
5 changed files with 370 additions and 26 deletions
|
@ -95,6 +95,22 @@ $(DOWNLOADS)/sigcxx/Makefile: $(DOWNLOADS)/sigcxx/autogen.sh
|
|||
|
||||
$(DOWNLOADS)/sigcxx/autogen.sh:
|
||||
$(CLONE) $(GITLAB)/mkxp-z/libsigcplusplus -b libsigc++-2-10 $(DOWNLOADS)/sigcxx
|
||||
|
||||
# uchardet
|
||||
uchardet: init_dirs $(LIBDIR)/libuchardet.a
|
||||
|
||||
$(LIBDIR)/libuchardet.a: $(DOWNLOADS)/uchardet/cmakebuild/Makefile
|
||||
cd $(DOWNLOADS)/uchardet/cmakebuild; \
|
||||
make -j$(NPROC); make install
|
||||
|
||||
$(DOWNLOADS)/uchardet/cmakebuild/Makefile: $(DOWNLOADS)/uchardet/CMakeLists.txt
|
||||
cd $(DOWNLOADS)/uchardet; \
|
||||
mkdir cmakebuild; cd cmakebuild; \
|
||||
$(CMAKE) -DBUILD_SHARED_LIBS=no
|
||||
|
||||
$(DOWNLOADS)/uchardet/CMakeLists.txt:
|
||||
$(CLONE) $(GITHUB)/freedesktop/uchardet $(DOWNLOADS)/uchardet
|
||||
|
||||
|
||||
# Pixman
|
||||
pixman: init_dirs libpng $(LIBDIR)/libpixman-1.a
|
||||
|
@ -310,5 +326,5 @@ clean-downloads:
|
|||
clean-compiled:
|
||||
-rm -rf build-$(SDK)-$(ARCH)
|
||||
|
||||
deps-core: libvorbis sigcxx pixman libpng libjpeg physfs sdl2 sdl2image sdlsound sdl2ttf openal openssl
|
||||
deps-core: libvorbis sigcxx pixman libpng libjpeg physfs uchardet sdl2 sdl2image sdlsound sdl2ttf openal openssl
|
||||
everything: deps-core ruby
|
||||
|
|
|
@ -101,6 +101,14 @@
|
|||
3B10EE092568E96A00372D13 /* binding-mri.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3B10EDF02568E96A00372D13 /* binding-mri.cpp */; };
|
||||
3B10EE0B2568E96A00372D13 /* module_rpg.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3B10EDF32568E96A00372D13 /* module_rpg.cpp */; };
|
||||
3B10EE0C2568E96A00372D13 /* viewport-binding.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3B10EDF42568E96A00372D13 /* viewport-binding.cpp */; };
|
||||
3B1BC0E1266F7C2600794D22 /* iniconfig.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3B1BC0E0266F7C0C00794D22 /* iniconfig.cpp */; };
|
||||
3B1BC0E2266F7C2700794D22 /* iniconfig.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3B1BC0E0266F7C0C00794D22 /* iniconfig.cpp */; };
|
||||
3B1BC0E3266F7C2700794D22 /* iniconfig.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3B1BC0E0266F7C0C00794D22 /* iniconfig.cpp */; };
|
||||
3B1BC0E4266F7C2800794D22 /* iniconfig.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3B1BC0E0266F7C0C00794D22 /* iniconfig.cpp */; };
|
||||
3B1BC0E8266F91E100794D22 /* libuchardet.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 3B1BC0E7266F91E100794D22 /* libuchardet.a */; };
|
||||
3B1BC0EA266F91FE00794D22 /* libuchardet.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 3B1BC0E9266F91FE00794D22 /* libuchardet.a */; };
|
||||
3B1BC0EC266F924B00794D22 /* libuchardet.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 3B1BC0EB266F924B00794D22 /* libuchardet.a */; };
|
||||
3B1BC0ED266F924B00794D22 /* libuchardet.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 3B1BC0EB266F924B00794D22 /* libuchardet.a */; };
|
||||
3B1C230725A142620075EF5D /* libruby.3.0.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 3B1C230625A142620075EF5D /* libruby.3.0.dylib */; };
|
||||
3B1C230825A1426C0075EF5D /* libruby.3.0.dylib in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 3B1C230625A142620075EF5D /* libruby.3.0.dylib */; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }; };
|
||||
3B1C230B25A144A10075EF5D /* libruby.3.0.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 3B1C230A25A144A10075EF5D /* libruby.3.0.dylib */; };
|
||||
|
@ -917,6 +925,12 @@
|
|||
3B10EDF32568E96A00372D13 /* module_rpg.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = module_rpg.cpp; sourceTree = "<group>"; };
|
||||
3B10EDF42568E96A00372D13 /* viewport-binding.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = "viewport-binding.cpp"; sourceTree = "<group>"; };
|
||||
3B10EE1F2569348E00372D13 /* json5pp.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = json5pp.hpp; sourceTree = "<group>"; };
|
||||
3B1BC0DF266F7C0C00794D22 /* iniconfig.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = iniconfig.h; sourceTree = "<group>"; };
|
||||
3B1BC0E0266F7C0C00794D22 /* iniconfig.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = iniconfig.cpp; sourceTree = "<group>"; };
|
||||
3B1BC0E6266F8E8700794D22 /* dependencies.make */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.make; name = dependencies.make; path = Dependencies/dependencies.make; sourceTree = "<group>"; };
|
||||
3B1BC0E7266F91E100794D22 /* libuchardet.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libuchardet.a; path = "Dependencies/build-macosx-arm64/lib/libuchardet.a"; sourceTree = "<group>"; };
|
||||
3B1BC0E9266F91FE00794D22 /* libuchardet.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libuchardet.a; path = "Dependencies/build-macosx-x86_64/lib/libuchardet.a"; sourceTree = "<group>"; };
|
||||
3B1BC0EB266F924B00794D22 /* libuchardet.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libuchardet.a; path = "Dependencies/build-macosx-x86_64/lib/libuchardet.a"; sourceTree = "<group>"; };
|
||||
3B1C230625A142620075EF5D /* libruby.3.0.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libruby.3.0.dylib; path = "Dependencies/build-macosx-arm64/lib/libruby.3.0.dylib"; sourceTree = "<group>"; };
|
||||
3B1C230A25A144A10075EF5D /* libruby.3.0.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libruby.3.0.dylib; path = "Dependencies/build-macosx-x86_64/lib/libruby.3.0.dylib"; sourceTree = "<group>"; };
|
||||
3B1C230D25A144BF0075EF5D /* libruby.3.0.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libruby.3.0.dylib; path = "Dependencies/build-macosx-universal/lib/libruby.3.0.dylib"; sourceTree = "<group>"; };
|
||||
|
@ -1072,6 +1086,7 @@
|
|||
3B1C23C725A19C600075EF5D /* libcrypto.a in Frameworks */,
|
||||
3B1C23C825A19C600075EF5D /* libopenal.a in Frameworks */,
|
||||
3B97F77725E6182100A569B5 /* libSDL2_sound.a in Frameworks */,
|
||||
3B1BC0ED266F924B00794D22 /* libuchardet.a in Frameworks */,
|
||||
3B1C23C925A19C600075EF5D /* libpixman-1.a in Frameworks */,
|
||||
3B5E1F1225A881FB0086FFDC /* libGLESv2.dylib in Frameworks */,
|
||||
3B1C23CA25A19C600075EF5D /* AppKit.framework in Frameworks */,
|
||||
|
@ -1118,6 +1133,7 @@
|
|||
files = (
|
||||
3BC65D622584EED10063AFF1 /* libSDL2_image.a in Frameworks */,
|
||||
3BC65D5A2584EED10063AFF1 /* libvorbis.a in Frameworks */,
|
||||
3B1BC0E8266F91E100794D22 /* libuchardet.a in Frameworks */,
|
||||
3B522DD2259BFF0B003301C4 /* libssl.a in Frameworks */,
|
||||
3B5E1F0D25A881FB0086FFDC /* libEGL.dylib in Frameworks */,
|
||||
3BC65D282584EDC60063AFF1 /* IOKit.framework in Frameworks */,
|
||||
|
@ -1161,6 +1177,7 @@
|
|||
files = (
|
||||
3BC65E2C2584F4290063AFF1 /* libvorbisenc.a in Frameworks */,
|
||||
3BC65E2D2584F4290063AFF1 /* libogg.a in Frameworks */,
|
||||
3B1BC0EA266F91FE00794D22 /* libuchardet.a in Frameworks */,
|
||||
3B522DCC259BFEE0003301C4 /* libssl.a in Frameworks */,
|
||||
3B5E1F0B25A881FB0086FFDC /* libEGL.dylib in Frameworks */,
|
||||
3BC65E222584F4290063AFF1 /* libSDL2_ttf.a in Frameworks */,
|
||||
|
@ -1209,6 +1226,7 @@
|
|||
3B522DD8259BFF2D003301C4 /* libcrypto.a in Frameworks */,
|
||||
3B5A8445256A0F6300BAF2E5 /* libopenal.a in Frameworks */,
|
||||
3B97F77625E6182100A569B5 /* libSDL2_sound.a in Frameworks */,
|
||||
3B1BC0EC266F924B00794D22 /* libuchardet.a in Frameworks */,
|
||||
3BE08107256879FE0006849F /* libpixman-1.a in Frameworks */,
|
||||
3B5E1F1025A881FB0086FFDC /* libGLESv2.dylib in Frameworks */,
|
||||
3B1C233025A16CB20075EF5D /* AppKit.framework in Frameworks */,
|
||||
|
@ -1338,6 +1356,8 @@
|
|||
3B10ED412568E95D00372D13 /* exception.h */,
|
||||
3B10ED422568E95D00372D13 /* debugwriter.h */,
|
||||
3B10EE1F2569348E00372D13 /* json5pp.hpp */,
|
||||
3B1BC0DF266F7C0C00794D22 /* iniconfig.h */,
|
||||
3B1BC0E0266F7C0C00794D22 /* iniconfig.cpp */,
|
||||
3B5A842B2569E8BA00BAF2E5 /* mINI.h */,
|
||||
);
|
||||
path = util;
|
||||
|
@ -1522,6 +1542,14 @@
|
|||
path = ../binding;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
3B1BC0E5266F8E2A00794D22 /* Makefiles */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
3B1BC0E6266F8E8700794D22 /* dependencies.make */,
|
||||
);
|
||||
name = Makefiles;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
3B1C231D25A15F8F0075EF5D /* mkxp */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
|
@ -1638,6 +1666,7 @@
|
|||
3BC65D492584EE690063AFF1 /* ARM64 */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
3B1BC0E7266F91E100794D22 /* libuchardet.a */,
|
||||
3BC65D4F2584EED10063AFF1 /* libfreetype.a */,
|
||||
3BC65D512584EED10063AFF1 /* libogg.a */,
|
||||
3BC65D562584EED10063AFF1 /* libopenal.a */,
|
||||
|
@ -1666,6 +1695,7 @@
|
|||
children = (
|
||||
3B5E1EF425A880D50086FFDC /* OpenGL ES */,
|
||||
3BC65D7D2584F3780063AFF1 /* libfreetype.a */,
|
||||
3B1BC0E9266F91FE00794D22 /* libuchardet.a */,
|
||||
3B522DA1259BAA13003301C4 /* libfluidsynth.dylib */,
|
||||
3B1C230D25A144BF0075EF5D /* libruby.3.0.dylib */,
|
||||
3BC65D822584F3780063AFF1 /* libogg.a */,
|
||||
|
@ -1728,6 +1758,7 @@
|
|||
3BDB22EB25644FBF00C4A63D = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
3B1BC0E5266F8E2A00794D22 /* Makefiles */,
|
||||
3BD2B7272565B343003DAD8A /* README.md */,
|
||||
3BDB23E22564546E00C4A63D /* icon.icns */,
|
||||
3BDB2409256470AE00C4A63D /* Player */,
|
||||
|
@ -1787,6 +1818,7 @@
|
|||
isa = PBXGroup;
|
||||
children = (
|
||||
3BE080FC256879FE0006849F /* libfreetype.a */,
|
||||
3B1BC0EB266F924B00794D22 /* libuchardet.a */,
|
||||
3B5A8444256A0F6300BAF2E5 /* libopenal.a */,
|
||||
3BE080FD256879FE0006849F /* libogg.a */,
|
||||
3BE081452568A5C60006849F /* libpng.a */,
|
||||
|
@ -2107,6 +2139,7 @@
|
|||
3B3F7D2D25B1A73A00EA5F1C /* SettingsMenuController.mm in Sources */,
|
||||
3B1C23BF25A19C600075EF5D /* filesystemImplApple.mm in Sources */,
|
||||
3B1C23C025A19C600075EF5D /* fake-api.cpp in Sources */,
|
||||
3B1BC0E4266F7C2800794D22 /* iniconfig.cpp in Sources */,
|
||||
3B1C23C125A19C600075EF5D /* sharedstate.cpp in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
|
@ -2190,6 +2223,7 @@
|
|||
3BC65D122584EDC60063AFF1 /* systemImplApple.mm in Sources */,
|
||||
3BC65D132584EDC60063AFF1 /* graphics.cpp in Sources */,
|
||||
3BC65D142584EDC60063AFF1 /* font.cpp in Sources */,
|
||||
3B1BC0E3266F7C2700794D22 /* iniconfig.cpp in Sources */,
|
||||
3BC65D172584EDC60063AFF1 /* filesystemImplApple.mm in Sources */,
|
||||
3BC65D182584EDC60063AFF1 /* fake-api.cpp in Sources */,
|
||||
3BC65D192584EDC60063AFF1 /* sharedstate.cpp in Sources */,
|
||||
|
@ -2268,6 +2302,7 @@
|
|||
3BC65DD32584F3AD0063AFF1 /* systemImplApple.mm in Sources */,
|
||||
3BC65DD42584F3AD0063AFF1 /* graphics.cpp in Sources */,
|
||||
3BC65DD52584F3AD0063AFF1 /* font.cpp in Sources */,
|
||||
3B1BC0E1266F7C2600794D22 /* iniconfig.cpp in Sources */,
|
||||
3BC65DD82584F3AD0063AFF1 /* filesystemImplApple.mm in Sources */,
|
||||
3BC65DD92584F3AD0063AFF1 /* fake-api.cpp in Sources */,
|
||||
3BC65DDA2584F3AD0063AFF1 /* sharedstate.cpp in Sources */,
|
||||
|
@ -2346,6 +2381,7 @@
|
|||
3B5A8464256A46B200BAF2E5 /* systemImplApple.mm in Sources */,
|
||||
3B10EDC12568E95E00372D13 /* graphics.cpp in Sources */,
|
||||
3B10EDC02568E95E00372D13 /* font.cpp in Sources */,
|
||||
3B1BC0E2266F7C2700794D22 /* iniconfig.cpp in Sources */,
|
||||
3B5A840D2569BE7C00BAF2E5 /* filesystemImplApple.mm in Sources */,
|
||||
3B10EDB12568E95E00372D13 /* fake-api.cpp in Sources */,
|
||||
3B10EDAC2568E95E00372D13 /* sharedstate.cpp in Sources */,
|
||||
|
@ -3025,6 +3061,7 @@
|
|||
"$(inherited)",
|
||||
"$(PROJECT_DIR)/Dependencies/Frameworks/ANGLE",
|
||||
"$(PROJECT_DIR)/Dependencies/build-macosx-universal/lib",
|
||||
"$(PROJECT_DIR)/Dependencies/build-macosx-x86_64/lib",
|
||||
);
|
||||
MARKETING_VERSION = 2.2.1;
|
||||
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
|
||||
|
@ -3107,6 +3144,7 @@
|
|||
"$(inherited)",
|
||||
"$(PROJECT_DIR)/Dependencies/Frameworks/ANGLE",
|
||||
"$(PROJECT_DIR)/Dependencies/build-macosx-universal/lib",
|
||||
"$(PROJECT_DIR)/Dependencies/build-macosx-x86_64/lib",
|
||||
);
|
||||
MARKETING_VERSION = 2.2.1;
|
||||
MTL_ENABLE_DEBUG_INFO = NO;
|
||||
|
@ -3310,6 +3348,7 @@
|
|||
"$(DEPENDENCY_SEARCH_PATH)/include/ruby-$(MRI_VERSION)/$(BUILD_ARCH)-darwin",
|
||||
"$(DEPENDENCY_SEARCH_PATH)/include/AL",
|
||||
"$(DEPENDENCY_SEARCH_PATH)/include/openssl",
|
||||
"$(DEPENDENCY_SEARCH_PATH)/include/uchardet",
|
||||
"$(PROJECT_DIR)/Dependencies/Frameworks/ANGLE",
|
||||
);
|
||||
LIBRARY_SEARCH_PATHS = (
|
||||
|
@ -3379,6 +3418,7 @@
|
|||
"$(DEPENDENCY_SEARCH_PATH)/include/ruby-$(MRI_VERSION)/$(BUILD_ARCH)-darwin",
|
||||
"$(DEPENDENCY_SEARCH_PATH)/include/AL",
|
||||
"$(DEPENDENCY_SEARCH_PATH)/include/openssl",
|
||||
"$(DEPENDENCY_SEARCH_PATH)/include/uchardet",
|
||||
"$(PROJECT_DIR)/Dependencies/Frameworks/ANGLE",
|
||||
);
|
||||
LIBRARY_SEARCH_PATHS = (
|
||||
|
|
178
src/config.cpp
178
src/config.cpp
|
@ -20,8 +20,94 @@
|
|||
#include "util/json5pp.hpp"
|
||||
#include "util/mINI.h"
|
||||
|
||||
#include "util/iniconfig.h"
|
||||
|
||||
#if defined(MKXPZ_BUILD_XCODE) || defined(MKXPZ_INI_ENCODING)
|
||||
#include <iconv.h>
|
||||
#include <uchardet.h>
|
||||
#include <errno.h>
|
||||
#endif
|
||||
|
||||
namespace json = json5pp;
|
||||
namespace ini = mINI;
|
||||
|
||||
/* http://stackoverflow.com/a/1031773 */
|
||||
static bool validUtf8(const char *string)
|
||||
{
|
||||
const uint8_t *bytes = (uint8_t*) string;
|
||||
|
||||
while(*bytes)
|
||||
{
|
||||
if( (/* ASCII
|
||||
* use bytes[0] <= 0x7F to allow ASCII control characters */
|
||||
bytes[0] == 0x09 ||
|
||||
bytes[0] == 0x0A ||
|
||||
bytes[0] == 0x0D ||
|
||||
(0x20 <= bytes[0] && bytes[0] <= 0x7E)
|
||||
)
|
||||
) {
|
||||
bytes += 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
if( (/* non-overlong 2-byte */
|
||||
(0xC2 <= bytes[0] && bytes[0] <= 0xDF) &&
|
||||
(0x80 <= bytes[1] && bytes[1] <= 0xBF)
|
||||
)
|
||||
) {
|
||||
bytes += 2;
|
||||
continue;
|
||||
}
|
||||
|
||||
if( (/* excluding overlongs */
|
||||
bytes[0] == 0xE0 &&
|
||||
(0xA0 <= bytes[1] && bytes[1] <= 0xBF) &&
|
||||
(0x80 <= bytes[2] && bytes[2] <= 0xBF)
|
||||
) ||
|
||||
(/* straight 3-byte */
|
||||
((0xE1 <= bytes[0] && bytes[0] <= 0xEC) ||
|
||||
bytes[0] == 0xEE ||
|
||||
bytes[0] == 0xEF) &&
|
||||
(0x80 <= bytes[1] && bytes[1] <= 0xBF) &&
|
||||
(0x80 <= bytes[2] && bytes[2] <= 0xBF)
|
||||
) ||
|
||||
(/* excluding surrogates */
|
||||
bytes[0] == 0xED &&
|
||||
(0x80 <= bytes[1] && bytes[1] <= 0x9F) &&
|
||||
(0x80 <= bytes[2] && bytes[2] <= 0xBF)
|
||||
)
|
||||
) {
|
||||
bytes += 3;
|
||||
continue;
|
||||
}
|
||||
|
||||
if( (/* planes 1-3 */
|
||||
bytes[0] == 0xF0 &&
|
||||
(0x90 <= bytes[1] && bytes[1] <= 0xBF) &&
|
||||
(0x80 <= bytes[2] && bytes[2] <= 0xBF) &&
|
||||
(0x80 <= bytes[3] && bytes[3] <= 0xBF)
|
||||
) ||
|
||||
(/* planes 4-15 */
|
||||
(0xF1 <= bytes[0] && bytes[0] <= 0xF3) &&
|
||||
(0x80 <= bytes[1] && bytes[1] <= 0xBF) &&
|
||||
(0x80 <= bytes[2] && bytes[2] <= 0xBF) &&
|
||||
(0x80 <= bytes[3] && bytes[3] <= 0xBF)
|
||||
) ||
|
||||
(/* plane 16 */
|
||||
bytes[0] == 0xF4 &&
|
||||
(0x80 <= bytes[1] && bytes[1] <= 0x8F) &&
|
||||
(0x80 <= bytes[2] && bytes[2] <= 0xBF) &&
|
||||
(0x80 <= bytes[3] && bytes[3] <= 0xBF)
|
||||
)
|
||||
) {
|
||||
bytes += 4;
|
||||
continue;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
std::string prefPath(const char *org, const char *app) {
|
||||
char *path = SDL_GetPrefPath(org, app);
|
||||
|
@ -255,40 +341,82 @@ void Config::readGameINI() {
|
|||
}
|
||||
|
||||
std::string iniFileName(execName + ".ini");
|
||||
SDLRWStream iniFile(iniFileName.c_str(), "r");
|
||||
|
||||
if (mkxp_fs::fileExists(iniFileName.c_str())) {
|
||||
ini::INIStructure iniStruct;
|
||||
|
||||
if (!ini::INIFile(iniFileName).read(iniStruct)) {
|
||||
Debug() << "Failed to read INI file" << iniFileName;
|
||||
if (iniFile)
|
||||
{
|
||||
INIConfiguration ic;
|
||||
if (ic.load(iniFile.stream()))
|
||||
{
|
||||
GUARD(game.title = ic.getStringProperty("Game", "Title"););
|
||||
GUARD(game.scripts = ic.getStringProperty("Game", "Scripts"););
|
||||
|
||||
strReplace(game.scripts, '\\', '/');
|
||||
|
||||
if (game.title.empty()) {
|
||||
Debug() << iniFileName + ": Could not find Game.Title";
|
||||
}
|
||||
|
||||
if (game.scripts.empty())
|
||||
Debug() << iniFileName + ": Could not find Game.Scripts";
|
||||
}
|
||||
else if (!iniStruct.has("Game")){
|
||||
Debug() << "INI is missing [Game] section";
|
||||
}
|
||||
|
||||
game.title = iniStruct["Game"]["Title"];
|
||||
game.scripts = iniStruct["Game"]["Scripts"];
|
||||
}
|
||||
else
|
||||
Debug() << "Could not read" << iniFileName;
|
||||
|
||||
if (game.title.empty()) {
|
||||
Debug() << "INI is missing Game.Title property";
|
||||
bool convSuccess = false;
|
||||
|
||||
// Attempt to convert from other encodings to UTF-8
|
||||
if (!validUtf8(game.title.c_str()))
|
||||
{
|
||||
#if defined(MKXPZ_BUILD_XCODE) || defined(MKXPZ_INI_ENCODING)
|
||||
uchardet_t ud = uchardet_new();
|
||||
uchardet_handle_data(ud, game.title.c_str(), game.title.length());
|
||||
uchardet_data_end(ud);
|
||||
const char *charset = uchardet_get_charset(ud);
|
||||
|
||||
Debug() << iniFileName << ": Assuming encoding is" << charset << "...";
|
||||
iconv_t cd = iconv_open("UTF-8", charset);
|
||||
|
||||
uchardet_delete(ud);
|
||||
|
||||
size_t inLen = game.title.size();
|
||||
size_t outLen = inLen * 4;
|
||||
std::string buf(outLen, '\0');
|
||||
char *inPtr = const_cast<char*>(game.title.c_str());
|
||||
char *outPtr = const_cast<char*>(buf.c_str());
|
||||
|
||||
errno = 0;
|
||||
size_t result = iconv(cd, &inPtr, &inLen, &outPtr, &outLen);
|
||||
|
||||
iconv_close(cd);
|
||||
|
||||
if (result != (size_t)-1 && errno == 0)
|
||||
{
|
||||
buf.resize(buf.size()-outLen);
|
||||
game.title = buf;
|
||||
convSuccess = true;
|
||||
}
|
||||
else {
|
||||
Debug() << iniFileName << ": failed to convert game title to UTF-8";
|
||||
}
|
||||
#else
|
||||
Debug() << iniFileName << ": Game title isn't valid UTF-8"
|
||||
#endif
|
||||
}
|
||||
else
|
||||
convSuccess = true;
|
||||
|
||||
if (game.title.empty() || !convSuccess)
|
||||
game.title = "mkxp-z";
|
||||
}
|
||||
|
||||
if (game.scripts.empty())
|
||||
Debug() << "INI is missing Game.Scripts property";
|
||||
|
||||
if (dataPathOrg.empty()) {
|
||||
if (dataPathOrg.empty())
|
||||
dataPathOrg = ".";
|
||||
}
|
||||
|
||||
if (dataPathApp.empty()) {
|
||||
if (dataPathApp.empty())
|
||||
dataPathApp = game.title;
|
||||
}
|
||||
|
||||
if (!dataPathApp.empty()) {
|
||||
customDataPath = prefPath(dataPathOrg.c_str(), dataPathApp.c_str());
|
||||
}
|
||||
customDataPath = prefPath(dataPathOrg.c_str(), dataPathApp.c_str());
|
||||
|
||||
commonDataPath = prefPath(".", "mkxp-z");
|
||||
|
||||
|
|
114
src/util/iniconfig.cpp
Normal file
114
src/util/iniconfig.cpp
Normal file
|
@ -0,0 +1,114 @@
|
|||
#include "iniconfig.h"
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
std::string toLowerCase(const std::string& str)
|
||||
{
|
||||
std::string lower = str;
|
||||
std::transform(lower.begin(), lower.end(), lower.begin(), ::tolower);
|
||||
return lower;
|
||||
}
|
||||
|
||||
std::string trim(const std::string& str, const std::string& chars = "\t\n\v\f\r ")
|
||||
{
|
||||
std::string trimmed = str;
|
||||
trimmed.erase(trimmed.find_last_not_of(chars) + 1);
|
||||
trimmed.erase(0, trimmed.find_first_not_of(chars));
|
||||
return trimmed;
|
||||
}
|
||||
|
||||
INIConfiguration::Section::Section (const std::string& sname) : m_Name (sname), m_PropertyMap()
|
||||
{
|
||||
}
|
||||
|
||||
bool INIConfiguration::Section::getStringProperty (const std::string& name, std::string& outPropStr) const
|
||||
{
|
||||
try
|
||||
{
|
||||
outPropStr = m_PropertyMap.at(toLowerCase(name)).m_Value;
|
||||
return true;
|
||||
}
|
||||
catch (std::out_of_range& oorexcept)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool INIConfiguration::load (std::istream& is)
|
||||
{
|
||||
if (!is.good())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
std::string currSectionName;
|
||||
|
||||
std::string line;
|
||||
std::getline (is, line);
|
||||
|
||||
while (!is.eof() && !is.bad())
|
||||
{
|
||||
if (line[0] == '[')
|
||||
{
|
||||
currSectionName = line.substr (1, line.find_last_of (']') - 1);
|
||||
}
|
||||
else if (line[0] != '#' && line.length() > 2)
|
||||
{
|
||||
int crloc = line.length() - 1;
|
||||
|
||||
if (crloc >= 0 && line[crloc] == '\r') //check for Windows-style newline
|
||||
line.resize (crloc); //and correct
|
||||
|
||||
size_t equalsPos = line.find_first_of ("=");
|
||||
|
||||
if (equalsPos != std::string::npos)
|
||||
{
|
||||
std::string key = line.substr (0, equalsPos);
|
||||
std::string val = line.substr (equalsPos + 1);
|
||||
|
||||
addProperty (currSectionName, key , val);
|
||||
}
|
||||
}
|
||||
|
||||
std::getline (is, line);
|
||||
}
|
||||
|
||||
if (is.bad())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
std::string INIConfiguration::getStringProperty(const std::string& sname, const std::string& name, const std::string& def) const
|
||||
{
|
||||
auto sectionIt = m_SectionMap.find(toLowerCase(sname));
|
||||
|
||||
if (sectionIt != m_SectionMap.end())
|
||||
{
|
||||
std::string prop;
|
||||
|
||||
if(sectionIt->second.getStringProperty(name, prop))
|
||||
{
|
||||
return prop;
|
||||
}
|
||||
}
|
||||
|
||||
return def;
|
||||
}
|
||||
|
||||
void INIConfiguration::addProperty (const std::string& sname, const std::string& name, const std::string& val)
|
||||
{
|
||||
if (m_SectionMap.find (toLowerCase(sname)) == m_SectionMap.end())
|
||||
{
|
||||
m_SectionMap.emplace (toLowerCase(sname), Section (sname));
|
||||
}
|
||||
|
||||
Section::Property p;
|
||||
p.m_Name = trim(name);
|
||||
p.m_Value = trim(val);
|
||||
|
||||
m_SectionMap.at (toLowerCase(sname)).m_PropertyMap[toLowerCase(p.m_Name)] = p;
|
||||
}
|
46
src/util/iniconfig.h
Normal file
46
src/util/iniconfig.h
Normal file
|
@ -0,0 +1,46 @@
|
|||
#ifndef INICONFIG_H
|
||||
#define INICONFIG_H
|
||||
|
||||
#include <iostream>
|
||||
#include <map>
|
||||
|
||||
class INIConfiguration
|
||||
{
|
||||
class Section
|
||||
{
|
||||
friend class INIConfiguration;
|
||||
|
||||
struct Property
|
||||
{
|
||||
std::string m_Name;
|
||||
std::string m_Value;
|
||||
};
|
||||
|
||||
typedef std::map<std::string, Property> property_map;
|
||||
public:
|
||||
Section (const Section& s) = default;
|
||||
Section (Section&& s) = default;
|
||||
|
||||
bool getStringProperty (const std::string& name, std::string& outPropStr) const;
|
||||
|
||||
private:
|
||||
explicit Section (const std::string& name);
|
||||
|
||||
std::string m_Name;
|
||||
property_map m_PropertyMap;
|
||||
};
|
||||
|
||||
typedef std::map<std::string, Section> section_map;
|
||||
public:
|
||||
bool load (std::istream& inStream);
|
||||
|
||||
std::string getStringProperty(const std::string& sname, const std::string& name, const std::string& def = "") const;
|
||||
|
||||
protected:
|
||||
void addProperty (const std::string& sname, const std::string& name, const std::string& val);
|
||||
|
||||
private:
|
||||
section_map m_SectionMap;
|
||||
};
|
||||
|
||||
#endif // INICONFIG_H
|
Loading…
Add table
Reference in a new issue