From 53c447248136efb653bcb58b6b4905b83bd6a199 Mon Sep 17 00:00:00 2001 From: MoNTE48 Date: Wed, 5 Jun 2019 15:10:06 +0200 Subject: [PATCH] Mobile: Integrate libintl-lite (locale) --- build/android/Makefile | 16 +- build/android/jni/Android.mk | 4 +- .../MultiCraft.xcodeproj/project.pbxproj | 51 +-- build/iOS/Podfile | 24 +- build/iOS/deps/intl.sh | 23 -- build/iOS/deps/libraries.sh | 7 +- lib/intl/MessageCatalog.hpp | 93 +++++ lib/intl/README | 21 ++ lib/intl/Util.hpp | 221 ++++++++++++ lib/intl/libintl.cpp | 318 ++++++++++++++++++ lib/intl/libintl.h | 124 +++++++ src/defaultsettings.cpp | 44 ++- src/gettext.cpp | 16 - src/gettext.h | 6 +- src/touchscreengui.cpp | 5 +- 15 files changed, 861 insertions(+), 112 deletions(-) delete mode 100755 build/iOS/deps/intl.sh create mode 100644 lib/intl/MessageCatalog.hpp create mode 100644 lib/intl/README create mode 100644 lib/intl/Util.hpp create mode 100644 lib/intl/libintl.cpp create mode 100644 lib/intl/libintl.h diff --git a/build/android/Makefile b/build/android/Makefile index 991a3c5ba..fe268d02f 100644 --- a/build/android/Makefile +++ b/build/android/Makefile @@ -95,9 +95,6 @@ ICONV_VERSION = 1.16 ICONV_DIR = $(ANDR_ROOT)/deps/libiconv ICONV_URL_HTTP = https://ftp.gnu.org/pub/gnu/libiconv/libiconv-$(ICONV_VERSION).tar.gz -INTL_DIR = $(ANDR_ROOT)/deps/libintl -INTL_URL_GIT = https://github.com/j-jorge/libintl-lite.git - LUAJIT_GIT_BRANCH = v2.1 LUAJIT_DIR = $(ANDR_ROOT)/deps/luajit LUAJIT_LIB = $(LUAJIT_DIR)src/libluajit.a @@ -374,17 +371,6 @@ iconv_download : clean_iconv : $(RM) -rf ${ICONV_DIR} -intl_download : - @if [ ! -d ${INTL_DIR} ] ; then \ - echo "libintl sources missing, downloading..."; \ - mkdir -p ${ANDR_ROOT}/deps; \ - cd ${ANDR_ROOT}/deps; \ - git clone ${INTL_URL_GIT} libintl || exit 1; \ - fi - -clean_intl : - $(RM) -rf ${INTL_DIR} - #Note: Texturehack patch is required for gpu's not supporting color format # correctly. Known bad GPU: # -geforce on emulator @@ -644,7 +630,7 @@ clean_assets : apk: local.properties $(IRRLICHT_LIB) $(CURL_LIB) $(LEVELDB_LIB) $(LUAJIT_LIB) \ $(OPENAL_LIB) $(VORBIS_LIB) prep_srcdir $(ANDR_ROOT)/jni/src/android_version.h \ - $(ANDR_ROOT)/jni/src/android_version_githash.h intl_download iconv_download assets + $(ANDR_ROOT)/jni/src/android_version_githash.h iconv_download assets +@${ANDROID_NDK}/ndk-build \ TARGET_LIBDIR=${TARGET_LIBDIR} \ APP_PLATFORM=${APP_PLATFORM} TARGET_ABI=${TARGET_ABI} || exit 1; \ diff --git a/build/android/jni/Android.mk b/build/android/jni/Android.mk index edf7fce8a..667bc07ed 100644 --- a/build/android/jni/Android.mk +++ b/build/android/jni/Android.mk @@ -79,11 +79,11 @@ LOCAL_LDFLAGS := -Wl,--no-warn-mismatch,--gc-sections,--icf=safe LOCAL_C_INCLUDES := \ jni/src \ jni/src/script \ + jni/lib/intl \ jni/lib/jsoncpp \ jni/src/cguittfont \ jni/lib/gmp \ deps/irrlicht/include \ - deps/libintl \ deps/freetype/include \ deps/curl/include \ deps/openal-soft/include \ @@ -299,7 +299,7 @@ LOCAL_SRC_FILES += jni/src/cguittfont/xCGUITTFont.cpp LOCAL_SRC_FILES += jni/lib/gmp/mini-gmp.c # libIntl -LOCAL_SRC_FILES += deps/libintl/internal/libintl.cpp +LOCAL_SRC_FILES += jni/lib/intl/libintl.cpp # Threading LOCAL_SRC_FILES += \ diff --git a/build/iOS/MultiCraft/MultiCraft.xcodeproj/project.pbxproj b/build/iOS/MultiCraft/MultiCraft.xcodeproj/project.pbxproj index 221be9394..a400c6570 100755 --- a/build/iOS/MultiCraft/MultiCraft.xcodeproj/project.pbxproj +++ b/build/iOS/MultiCraft/MultiCraft.xcodeproj/project.pbxproj @@ -36,10 +36,10 @@ 4B35A9F41EEE017000274961 /* scripting_client.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B35A9F21EEE017000274961 /* scripting_client.cpp */; }; 4B35A9F71EEE018D00274961 /* scripting_server.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B35A9F51EEE018D00274961 /* scripting_server.cpp */; }; 844B495F228606B200EB60EF /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 844B495D228606B200EB60EF /* Main.storyboard */; }; + 8465A76522A7D4500095B7CA /* libintl.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8465A76422A7D4500095B7CA /* libintl.cpp */; }; 849C4F86209656D3005EB041 /* ru.lproj in Resources */ = {isa = PBXBuildFile; fileRef = 849C4F85209656D2005EB041 /* ru.lproj */; }; EB4367AE23CAD13A43ADF4B1 /* libPods-MultiCraft.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 8758CE009FCB7E91F4C84C28 /* libPods-MultiCraft.a */; }; F810D7052080E48100D109B8 /* en.lproj in Resources */ = {isa = PBXBuildFile; fileRef = F810D7042080E48000D109B8 /* en.lproj */; }; - F81F6BE51DDC7D99000B9E21 /* libintl.a in Frameworks */ = {isa = PBXBuildFile; fileRef = F81F6BE41DDC7D99000B9E21 /* libintl.a */; }; F84D3A951DE79AB400ADE1A0 /* ads.mm in Sources */ = {isa = PBXBuildFile; fileRef = F84D3A941DE79AB400ADE1A0 /* ads.mm */; }; F85119A71F4476FC00BFA9AF /* libcurl.a in Frameworks */ = {isa = PBXBuildFile; fileRef = F85119A61F4476FC00BFA9AF /* libcurl.a */; }; F856B5C31F55F7EE00FE9494 /* bg.png in Resources */ = {isa = PBXBuildFile; fileRef = F856B5C21F55F7EE00FE9494 /* bg.png */; }; @@ -229,7 +229,6 @@ F8E6C7D11DCA433E00F64426 /* libiconv.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = F8E6C7D01DCA433E00F64426 /* libiconv.tbd */; }; F8E6C7D51DCA476800F64426 /* libIrrlicht.a in Frameworks */ = {isa = PBXBuildFile; fileRef = F8E6C7D41DCA476800F64426 /* libIrrlicht.a */; }; F8E6C7D71DCA477600F64426 /* libfreetype.a in Frameworks */ = {isa = PBXBuildFile; fileRef = F8E6C7D61DCA477600F64426 /* libfreetype.a */; }; - F8E6C7D91DCA478500F64426 /* libleveldb.a in Frameworks */ = {isa = PBXBuildFile; fileRef = F8E6C7D81DCA478500F64426 /* libleveldb.a */; }; F8E6C7DB1DCA479200F64426 /* libogg.a in Frameworks */ = {isa = PBXBuildFile; fileRef = F8E6C7DA1DCA479200F64426 /* libogg.a */; }; F8E6C7DD1DCA47A300F64426 /* libvorbis.a in Frameworks */ = {isa = PBXBuildFile; fileRef = F8E6C7DC1DCA47A300F64426 /* libvorbis.a */; }; F8E6C7DF1DCA47AF00F64426 /* libvorbisfile.a in Frameworks */ = {isa = PBXBuildFile; fileRef = F8E6C7DE1DCA47AF00F64426 /* libvorbisfile.a */; }; @@ -291,10 +290,13 @@ 4B35A9F51EEE018D00274961 /* scripting_server.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = scripting_server.cpp; path = ../../../../src/script/scripting_server.cpp; sourceTree = ""; }; 4B35A9F61EEE018D00274961 /* scripting_server.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = scripting_server.h; path = ../../../../src/script/scripting_server.h; sourceTree = ""; }; 844B495E228606B200EB60EF /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; + 8465A76122A7D4500095B7CA /* MessageCatalog.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = MessageCatalog.hpp; sourceTree = ""; }; + 8465A76222A7D4500095B7CA /* libintl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = libintl.h; sourceTree = ""; }; + 8465A76322A7D4500095B7CA /* Util.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = Util.hpp; sourceTree = ""; }; + 8465A76422A7D4500095B7CA /* libintl.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = libintl.cpp; sourceTree = ""; }; 849C4F85209656D2005EB041 /* ru.lproj */ = {isa = PBXFileReference; lastKnownFileType = folder; path = ru.lproj; sourceTree = ""; }; 8758CE009FCB7E91F4C84C28 /* libPods-MultiCraft.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-MultiCraft.a"; sourceTree = BUILT_PRODUCTS_DIR; }; F810D7042080E48000D109B8 /* en.lproj */ = {isa = PBXFileReference; lastKnownFileType = folder; path = en.lproj; sourceTree = ""; }; - F81F6BE41DDC7D99000B9E21 /* libintl.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libintl.a; path = ../deps/intl/libintl.a; sourceTree = ""; }; F84D3A931DE79AB400ADE1A0 /* ads.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ads.h; path = ../../Ads/ads.h; sourceTree = ""; }; F84D3A941DE79AB400ADE1A0 /* ads.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = ads.mm; path = ../../Ads/ads.mm; sourceTree = ""; }; F85119A61F4476FC00BFA9AF /* libcurl.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libcurl.a; path = ../Pods/libCurlPod/lib/libcurl.a; sourceTree = ""; }; @@ -701,10 +703,9 @@ F8E6C7D01DCA433E00F64426 /* libiconv.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = libiconv.tbd; path = usr/lib/libiconv.tbd; sourceTree = SDKROOT; }; F8E6C7D41DCA476800F64426 /* libIrrlicht.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libIrrlicht.a; path = ../deps/irrlicht/libIrrlicht.a; sourceTree = ""; }; F8E6C7D61DCA477600F64426 /* libfreetype.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libfreetype.a; path = ../deps/freetype/lib/libfreetype.a; sourceTree = ""; }; - F8E6C7D81DCA478500F64426 /* libleveldb.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libleveldb.a; path = ../deps/leveldb/lib/libleveldb.a; sourceTree = ""; }; - F8E6C7DA1DCA479200F64426 /* libogg.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libogg.a; path = ../deps/libogg/lib/libogg.a; sourceTree = ""; }; - F8E6C7DC1DCA47A300F64426 /* libvorbis.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libvorbis.a; path = ../deps/libvorbis/lib/libvorbis.a; sourceTree = ""; }; - F8E6C7DE1DCA47AF00F64426 /* libvorbisfile.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libvorbisfile.a; path = ../deps/libvorbis/lib/libvorbisfile.a; sourceTree = ""; }; + F8E6C7DA1DCA479200F64426 /* libogg.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libogg.a; path = ../Pods/libOggVorbisPod/lib/libogg.a; sourceTree = ""; }; + F8E6C7DC1DCA47A300F64426 /* libvorbis.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libvorbis.a; path = ../Pods/libOggVorbisPod/lib/libvorbis.a; sourceTree = ""; }; + F8E6C7DE1DCA47AF00F64426 /* libvorbisfile.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libvorbisfile.a; path = ../Pods/libOggVorbisPod/lib/libvorbisfile.a; sourceTree = ""; }; F8E6C7E01DCA4EB300F64426 /* assets.zip */ = {isa = PBXFileReference; lastKnownFileType = archive.zip; name = assets.zip; path = ../../assets.zip; sourceTree = ""; }; F8E6C7E21DCA511700F64426 /* worlds.zip */ = {isa = PBXFileReference; lastKnownFileType = archive.zip; name = worlds.zip; path = ../../worlds.zip; sourceTree = ""; }; /* End PBXFileReference section */ @@ -723,12 +724,10 @@ F8E6C7D11DCA433E00F64426 /* libiconv.tbd in Frameworks */, F8E6C7D51DCA476800F64426 /* libIrrlicht.a in Frameworks */, F8E6C7D71DCA477600F64426 /* libfreetype.a in Frameworks */, - F8E6C7D91DCA478500F64426 /* libleveldb.a in Frameworks */, F8E6C7DB1DCA479200F64426 /* libogg.a in Frameworks */, F8E6C7DD1DCA47A300F64426 /* libvorbis.a in Frameworks */, F8E6C7DF1DCA47AF00F64426 /* libvorbisfile.a in Frameworks */, F85722891DDC74B700308383 /* libluajit.a in Frameworks */, - F81F6BE51DDC7D99000B9E21 /* libintl.a in Frameworks */, F85119A71F4476FC00BFA9AF /* libcurl.a in Frameworks */, EB4367AE23CAD13A43ADF4B1 /* libPods-MultiCraft.a in Frameworks */, ); @@ -746,6 +745,18 @@ name = gmp; sourceTree = ""; }; + 8465A76022A7D4500095B7CA /* intl */ = { + isa = PBXGroup; + children = ( + 8465A76122A7D4500095B7CA /* MessageCatalog.hpp */, + 8465A76222A7D4500095B7CA /* libintl.h */, + 8465A76322A7D4500095B7CA /* Util.hpp */, + 8465A76422A7D4500095B7CA /* libintl.cpp */, + ); + name = intl; + path = ../../../../lib/intl; + sourceTree = ""; + }; 87D06CD2CC310BE5E73639F4 /* Pods */ = { isa = PBXGroup; children = ( @@ -1095,6 +1106,7 @@ F8E6C5F01DCA3F9900F64426 /* voxelalgorithms.h */, F8E6C5F11DCA3F9900F64426 /* wieldmesh.cpp */, F8E6C5F21DCA3F9900F64426 /* wieldmesh.h */, + 8465A76022A7D4500095B7CA /* intl */, ); name = src; sourceTree = ""; @@ -1337,12 +1349,10 @@ isa = PBXGroup; children = ( F85119A61F4476FC00BFA9AF /* libcurl.a */, - F81F6BE41DDC7D99000B9E21 /* libintl.a */, F85722881DDC74B700308383 /* libluajit.a */, F8E6C7DE1DCA47AF00F64426 /* libvorbisfile.a */, F8E6C7DC1DCA47A300F64426 /* libvorbis.a */, F8E6C7DA1DCA479200F64426 /* libogg.a */, - F8E6C7D81DCA478500F64426 /* libleveldb.a */, F8E6C7D61DCA477600F64426 /* libfreetype.a */, F8E6C7D41DCA476800F64426 /* libIrrlicht.a */, F8E6C7D01DCA433E00F64426 /* libiconv.tbd */, @@ -1516,6 +1526,7 @@ F8E6C61E1DCA3F9900F64426 /* guiTable.cpp in Sources */, F8E6C6291DCA3F9900F64426 /* localplayer.cpp in Sources */, 4B35A9C81EEDD22500274961 /* tileanimation.cpp in Sources */, + 8465A76522A7D4500095B7CA /* libintl.cpp in Sources */, F8E6C6221DCA3F9900F64426 /* imagefilters.cpp in Sources */, F8E6C74D1DCA420A00F64426 /* l_mainmenu.cpp in Sources */, F8E6C5F71DCA3F9900F64426 /* client.cpp in Sources */, @@ -1732,6 +1743,7 @@ "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; COPY_PHASE_STRIP = NO; DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_BITCODE = NO; ENABLE_STRICT_OBJC_MSGSEND = YES; ENABLE_TESTABILITY = NO; GCC_C_LANGUAGE_STANDARD = gnu11; @@ -1782,6 +1794,7 @@ "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; COPY_PHASE_STRIP = NO; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_BITCODE = NO; ENABLE_NS_ASSERTIONS = NO; ENABLE_STRICT_OBJC_MSGSEND = YES; GCC_C_LANGUAGE_STANDARD = gnu11; @@ -1839,9 +1852,7 @@ "${SRCROOT}/../../../src/jsoncpp", "${SRCROOT}/../../../src/script", "${SRCROOT}/../deps/irrlicht/include", - "${SRCROOT}/../deps/libogg/include", - "${SRCROOT}/../deps/libvorbis/include", - "${SRCROOT}/../deps/leveldb/include", + "${SRCROOT}/../Pods/libOggVorbisPod/include", "${SRCROOT}/../deps/freetype/include/freetype2", "${SRCROOT}/../Pods/LuaJITPod/include", "${SRCROOT}/../deps/intl/include", @@ -1870,9 +1881,7 @@ OTHER_LDFLAGS = ( "$(inherited)", "-L${SRCROOT}/../deps/irrlicht", - "-L$(SRCROOT)/../deps/libogg/lib", - "-L$(SRCROOT)/../deps/libvorbis/lib", - "-L${SRCROOT}/../deps/leveldb/lib", + "-L$(SRCROOT)/../Pods/libOggVorbisPod/lib", "-L${SRCROOT}/../deps/freetype/lib", "-L${SRCROOT}/../Pods/LuaJITPod/lib", "-L${SRCROOT}/../deps/intl", @@ -1922,9 +1931,7 @@ "${SRCROOT}/../../../src/jsoncpp", "${SRCROOT}/../../../src/script", "${SRCROOT}/../deps/irrlicht/include", - "${SRCROOT}/../deps/libogg/include", - "${SRCROOT}/../deps/libvorbis/include", - "${SRCROOT}/../deps/leveldb/include", + "${SRCROOT}/../Pods/libOggVorbisPod/include", "${SRCROOT}/../deps/freetype/include/freetype2", "${SRCROOT}/../Pods/LuaJITPod/include", "${SRCROOT}/../deps/intl/include", @@ -1953,9 +1960,7 @@ OTHER_LDFLAGS = ( "$(inherited)", "-L${SRCROOT}/../deps/irrlicht", - "-L$(SRCROOT)/../deps/libogg/lib", - "-L$(SRCROOT)/../deps/libvorbis/lib", - "-L${SRCROOT}/../deps/leveldb/lib", + "-L$(SRCROOT)/../Pods/libOggVorbisPod/lib", "-L${SRCROOT}/../deps/freetype/lib", "-L${SRCROOT}/../Pods/LuaJITPod/lib", "-L${SRCROOT}/../deps/intl", diff --git a/build/iOS/Podfile b/build/iOS/Podfile index 252fc0efc..5a0575723 100755 --- a/build/iOS/Podfile +++ b/build/iOS/Podfile @@ -6,10 +6,28 @@ target 'MultiCraft' do source 'https://github.com/appodeal/CocoaPods.git' pod 'SSZipArchive' - pod 'SDVersion', :git => 'https://github.com/MoNTE48/SDVersion' - pod 'LuaJITPod', :git => 'https://github.com/MoNTE48/LuaJITPod' - pod 'libCurlPod', :git => 'https://github.com/MoNTE48/libCurlPod' + pod 'leveldb-library' + pod 'SDVersion', :git => 'https://github.com/MoNTE48/SDVersion' + pod 'LuaJITPod', :git => 'https://github.com/MoNTE48/LuaJITPod' + pod 'libCurlPod', :git => 'https://github.com/MoNTE48/libCurlPod' + pod 'libOggVorbisPod', :git => 'https://github.com/MoNTE48/libOggVorbisPod' pod 'Appodeal/Interstitial', '2.5.4-Beta' pod 'PersonalizedAdConsent', :git => 'https://github.com/MultiCraftProject/googleads-consent-sdk-ios' end + +post_install do |installer| + installer.pods_project.targets.each do |target| + target.build_configurations.each do |config| + config.build_settings['GCC_FAST_MATH'] = 'YES' + config.build_settings['GCC_OPTIMIZATION_LEVEL'] = 'fast' + config.build_settings['GCC_SYMBOL_PRIVATE_EXTERN'] = 'YES' + config.build_settings['GCC_UNROLL_LOOPS'] = 'YES' + config.build_settings['ENABLE_BITCODE'] = 'NO' + config.build_settings['IPHONEOS_DEPLOYMENT_TARGET'] = '9.0' + config.build_settings['OTHER_CFLAGS'] ||= ['-fvisibility=hidden', '-fdata-sections', '-ffunction-sections'] + config.build_settings['OTHER_CPLUSPLUSFLAGS'] ||= ['$(OTHER_CFLAGS)'] + config.build_settings['OTHER_LDFLAGS'] = ['-Wl,-dead_strip'] + end + end +end diff --git a/build/iOS/deps/intl.sh b/build/iOS/deps/intl.sh deleted file mode 100755 index 5c7424a54..000000000 --- a/build/iOS/deps/intl.sh +++ /dev/null @@ -1,23 +0,0 @@ -#!/bin/bash -e - -. sdk.sh - -if [ ! -d intl-src ]; then - wget https://github.com/j-jorge/libintl-lite/archive/master.tar.gz - tar -xzvf master.tar.gz - mv libintl-lite-master intl-src - rm master.tar.gz -fi - -cd intl-src - -cd internal -$IOS_CC $IOS_FLAGS -Wall -c libintl.cpp -o libintl.o -lipo libintl.o -create -output ../libintl.a -cd .. - -mkdir -p ../intl/include -cp -v libintl.a ../intl -cp -v libintl.h ../intl/include - -echo "intl build successful" diff --git a/build/iOS/deps/libraries.sh b/build/iOS/deps/libraries.sh index a6d3e3431..81c3dd818 100755 --- a/build/iOS/deps/libraries.sh +++ b/build/iOS/deps/libraries.sh @@ -1,12 +1,11 @@ #!/bin/bash -e ./irrlicht.sh -./libogg.sh -./libvorbis.sh -./leveldb.sh +#./libogg.sh +#./libvorbis.sh +#./leveldb.sh ./freetype.sh #./luajit.sh -./intl.sh #./libcurl.sh echo diff --git a/lib/intl/MessageCatalog.hpp b/lib/intl/MessageCatalog.hpp new file mode 100644 index 000000000..3faf5c1fb --- /dev/null +++ b/lib/intl/MessageCatalog.hpp @@ -0,0 +1,93 @@ +/* +Boost Software License - Version 1.0 - August 17th, 2003 + +Permission is hereby granted, free of charge, to any person or organization +obtaining a copy of the software and accompanying documentation covered by +this license (the "Software") to use, reproduce, display, distribute, +execute, and transmit the Software, and to prepare derivative works of the +Software, and to permit third-parties to whom the Software is furnished to +do so, all subject to the following: + +The copyright notices in the Software and this entire statement, including +the above license grant, this restriction and the following disclaimer, +must be included in all copies of the Software, in whole or in part, and +all derivative works of the Software, unless such copies or derivative +works are solely in the form of machine-executable object code generated by +a source language processor. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. +*/ + +#ifndef LIBINTL_INTERNAL_MESSAGECATALOG_HPP_ +#define LIBINTL_INTERNAL_MESSAGECATALOG_HPP_ + +#include +#include + +namespace libintllite +{ + +namespace internal +{ + +class MessageCatalog +{ +private: + MessageCatalog(const MessageCatalog&); + MessageCatalog& operator=(const MessageCatalog&); + + uint32_t numberOfStrings; + const std::string* sortedOrigStringsArray; + const std::string* translatedStringsArray; + +public: + // The ownership of these arrays is transfered to the created message + // catalog object! + // Does not throw exceptions! + MessageCatalog(uint32_t numberOfStrings, + const std::string* sortedOrigStringsArray, + const std::string* translatedStringsArray) : + numberOfStrings(numberOfStrings), + sortedOrigStringsArray(sortedOrigStringsArray), + translatedStringsArray(translatedStringsArray) + { + } + + ~MessageCatalog() + { + delete[] this->sortedOrigStringsArray; + delete[] this->translatedStringsArray; + } + + // Returns NULL, if the original string was not found. + // Does not throw exceptions! + const std::string* getTranslatedStrPtr(const std::string& orig) const + { + const std::string* lastSortedOrigStringEndIter + = this->sortedOrigStringsArray + this->numberOfStrings; + const std::string* origStrPtr = std::lower_bound(this->sortedOrigStringsArray, + lastSortedOrigStringEndIter, + orig); + + if (!origStrPtr || (origStrPtr == lastSortedOrigStringEndIter) || (*origStrPtr != orig) ) + { + return NULL; + } + else + { + return &this->translatedStringsArray[origStrPtr - this->sortedOrigStringsArray]; + } + } +}; + +} // namespace internal + +} // namespace libintllite + +#endif // LIBINTL_INTERNAL_MESSAGECATALOG_HPP_ diff --git a/lib/intl/README b/lib/intl/README new file mode 100644 index 000000000..8a1e8363f --- /dev/null +++ b/lib/intl/README @@ -0,0 +1,21 @@ +libintl lite fork +https://github.com/eidy/libintl-lite +=============== + +libintl-lite is a simple (but less powerful) GNU gettext libintl replacement originally written by felixhaedicke and released on SourceForge.net: http://sourceforge.net/projects/libintl-lite/ + +The library does not depends upon any library except the standard C++ library and the STL, thus making it well suited for platforms like Android. + +Where to get help? +=============== + +Issues should be reported on the project's page on GitHub: https://github.com/j-jorge/libintl-lite + +For general questions, send an email to julien.jorge@stuff-o-matic.com. + +Legal information +============== + +The software is licensed under the version 1 of the Boost Software License. + +See the LICENSE text in source files for details. diff --git a/lib/intl/Util.hpp b/lib/intl/Util.hpp new file mode 100644 index 000000000..7da04544b --- /dev/null +++ b/lib/intl/Util.hpp @@ -0,0 +1,221 @@ +/* +Boost Software License - Version 1.0 - August 17th, 2003 + +Permission is hereby granted, free of charge, to any person or organization +obtaining a copy of the software and accompanying documentation covered by +this license (the "Software") to use, reproduce, display, distribute, +execute, and transmit the Software, and to prepare derivative works of the +Software, and to permit third-parties to whom the Software is furnished to +do so, all subject to the following: + +The copyright notices in the Software and this entire statement, including +the above license grant, this restriction and the following disclaimer, +must be included in all copies of the Software, in whole or in part, and +all derivative works of the Software, unless such copies or derivative +works are solely in the form of machine-executable object code generated by +a source language processor. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. +*/ + +#ifndef LIBINTL_INTERNAL_UTIL_HPP_ +#define LIBINTL_INTERNAL_UTIL_HPP_ + +#if defined(WIN32) || defined(WINCE) +typedef unsigned int uint32_t; +#else +#include +#endif + +namespace libintllite +{ + +namespace internal +{ + +// Helper functions for handling numbers and char array conversions: + +static inline bool isBigEndian() +{ + uint32_t checkNumber = 0x1100; + return (*reinterpret_cast(&checkNumber) != 0); +} + +static inline uint32_t swapUInt32Bytes(uint32_t number) +{ + const char* numberAsCharArray = reinterpret_cast(&number); + + uint32_t swappedNumber; + char* swappedNumberAsCharArray = reinterpret_cast(&swappedNumber); + swappedNumberAsCharArray[0] = numberAsCharArray[3]; + swappedNumberAsCharArray[1] = numberAsCharArray[2]; + swappedNumberAsCharArray[2] = numberAsCharArray[1]; + swappedNumberAsCharArray[3] = numberAsCharArray[0]; + return swappedNumber; +} + +static inline uint32_t charArrayToUInt32(const char uint32CharArray[4]) +{ + return *reinterpret_cast(uint32CharArray); +} + +static inline bool readUIn32FromFile(FILE* fileHandle, bool needsBeToLeConversion, uint32_t& outReadUInt32) +{ + char uint32CharArray[4]; + if ((fread(uint32CharArray, 1, 4, fileHandle)) != 4) + { + return false; + } + + if (needsBeToLeConversion) + { + outReadUInt32 = swapUInt32Bytes(charArrayToUInt32(uint32CharArray)); + return true; + } + else + { + outReadUInt32 = charArrayToUInt32(uint32CharArray); + return true; + } +} + +// RAII classes: + +template +class ArrayGurard +{ +private: + ArrayGurard(const ArrayGurard&); + ArrayGurard& operator=(const ArrayGurard&); + + T*& arrayRef; + bool released; + +public: + explicit ArrayGurard(T*& arrayRef) : + arrayRef(arrayRef), + released(false) + { + } + + ~ArrayGurard() + { + if (!this->released) + { + delete[] this->arrayRef; + } + } + + const T* release() + { + this->released = true; + return this->arrayRef; + } +}; + +class CloseFileHandleGuard +{ +private: + CloseFileHandleGuard(const CloseFileHandleGuard&); + CloseFileHandleGuard& operator=(const CloseFileHandleGuard&); + + FILE*& fileHandleRef; + +public: + explicit CloseFileHandleGuard(FILE*& fileHandleRef) : + fileHandleRef(fileHandleRef) + { + } + + ~CloseFileHandleGuard() + { + if (this->fileHandleRef) + { + fclose(this->fileHandleRef); + } + } +}; + +// Helper function to load strings from a .mo file and stores them in a given array + +static bool loadMoFileStringsToArray(FILE* moFile, + uint32_t numberOfStrings, + uint32_t stringsTableOffsetFromFileBegin, + bool needsBeToLeConversion, + std::string* outStringsFromMoFileArray) +{ + if (fseek(moFile, stringsTableOffsetFromFileBegin, SEEK_SET) != 0) return false; + + uint32_t* stringsLengthsArray = NULL; + ArrayGurard stringsLengthsArrayGuard(stringsLengthsArray); + stringsLengthsArray = new uint32_t[numberOfStrings]; + if (!stringsLengthsArray) + { + return false; + } + + uint32_t firstStringOffset; + uint32_t lastStringOffset; + { + uint32_t currentStringLength; + uint32_t currentStringOffset; + for (uint32_t i = 0; i < numberOfStrings; i++) + { + if (!readUIn32FromFile(moFile, needsBeToLeConversion, currentStringLength)) return false; + if (!readUIn32FromFile(moFile, needsBeToLeConversion, currentStringOffset)) return false; + + stringsLengthsArray[i] = currentStringLength; + + if (i == 0) + { + firstStringOffset = currentStringOffset; + } + + if (i == (numberOfStrings - 1)) + { + lastStringOffset = currentStringOffset; + } + } + } + + { + char* stringCharsArray = NULL; + ArrayGurard stringCharsArrayGuard(stringCharsArray); + + uint32_t stringCharsArraySize = lastStringOffset + stringsLengthsArray[numberOfStrings - 1] + 1 - firstStringOffset; + if (stringCharsArraySize == 0) + { + return false; + } + + if (fseek(moFile, firstStringOffset, SEEK_SET) != 0) return false; + stringCharsArray = new char[stringCharsArraySize]; + if (!stringCharsArray) + { + return false; + } + if (fread(stringCharsArray, 1, stringCharsArraySize, moFile) != stringCharsArraySize) return false; + + const char* stringsCharsArrayIter = stringCharsArray; + for (uint32_t i = 0; i < numberOfStrings; i++) + { + const char* currentStrEndIter = stringsCharsArrayIter + stringsLengthsArray[i]; + outStringsFromMoFileArray[i] = std::string(stringsCharsArrayIter, currentStrEndIter); + stringsCharsArrayIter = currentStrEndIter + 1 /* skip the NULL char at the end of the string */ ; + } + } + + return true; +} + +} // namespace internal + +} // namespace libintllite + +#endif // LIBINTL_INTERNAL_UTIL_HPP_ diff --git a/lib/intl/libintl.cpp b/lib/intl/libintl.cpp new file mode 100644 index 000000000..14da2089f --- /dev/null +++ b/lib/intl/libintl.cpp @@ -0,0 +1,318 @@ +/* +Boost Software License - Version 1.0 - August 17th, 2003 + +Permission is hereby granted, free of charge, to any person or organization +obtaining a copy of the software and accompanying documentation covered by +this license (the "Software") to use, reproduce, display, distribute, +Software, and to permit third-parties to whom the Software is furnished to +do so, all subject to the following: + +The copyright notices in the Software and this entire statement, including +the above license grant, this restriction and the following disclaimer, +must be included in all copies of the Software, in whole or in part, and +all derivative works of the Software, unless such copies or derivative +works are solely in the form of machine-executable object code generated by +a source language processor. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. +*/ + +#include "libintl.h" + +#include +#include + +#include +#include +#include +#if defined(WIN32) || defined(WINCE) +typedef unsigned int uint32_t; +#define DIR_DELIM "\\" +#else +#define DIR_DELIM "/" +#include +#endif + +#include "MessageCatalog.hpp" +#include "Util.hpp" + +using namespace std; + +using namespace libintllite; +using namespace libintllite::internal; + +static char* currentDefaultDomain = NULL; +static map loadedMessageCatalogPtrsByDomain; + +libintl_lite_bool_t loadMessageCatalog(const char* domain, const char* moFilePath) +{ + if (!moFilePath || !domain) + { + return LIBINTL_LITE_BOOL_FALSE; + } + + FILE* moFile = NULL; + CloseFileHandleGuard closeFileHandleGuard(moFile); + + // Extend file path to include locale/LC_MESSAGES/domain.po + + std::string current_language; + const char *env_lang = getenv("LANGUAGE"); + if (env_lang) + current_language = env_lang; + else + return LIBINTL_LITE_BOOL_FALSE; + + std::string basePath(moFilePath); + std::string newPath = basePath + + DIR_DELIM + current_language + + DIR_DELIM + "LC_MESSAGES" + + DIR_DELIM + "MultiCraft" + ".mo"; // ToDo: fix bindtextdomain definition + + moFile = fopen(newPath.c_str(), "rb"); + + if (!moFile) + { + std::clog << "WARNING: Localisation file not found : " << newPath << std::endl; + return LIBINTL_LITE_BOOL_FALSE; + } + + libintl_lite_bool_t ret = loadMessageCatalogFile(domain, moFile); + if (ret == LIBINTL_LITE_BOOL_FALSE) + { + std::clog << "ERROR: Localisation file did not load : " << newPath << std::endl; + } + std::clog << "INFO: Localisation file loaded : " << newPath << std::endl; + return ret; +} + +libintl_lite_bool_t loadMessageCatalogFile(const char* domain, FILE* moFile) +{ + try + { + if (sizeof(uint32_t) != 4) + { + return LIBINTL_LITE_BOOL_FALSE; + } + + if (!moFile || !domain) + { + return LIBINTL_LITE_BOOL_FALSE; + } + + uint32_t magicNumber; + if (!readUIn32FromFile(moFile, false, magicNumber)) return LIBINTL_LITE_BOOL_FALSE; + if ((magicNumber != 0x950412de) && (magicNumber != 0xde120495)) return LIBINTL_LITE_BOOL_FALSE; + + uint32_t fileFormatRevision; + if (!readUIn32FromFile(moFile, false, fileFormatRevision)) return LIBINTL_LITE_BOOL_FALSE; + if (fileFormatRevision != 0) return LIBINTL_LITE_BOOL_FALSE; + + bool needsBeToLeConversion = isBigEndian(); + + uint32_t numberOfStrings; + if (!readUIn32FromFile(moFile, needsBeToLeConversion, numberOfStrings)) return false; + if (numberOfStrings == 0) + { + return LIBINTL_LITE_BOOL_TRUE; + } + std::clog << "INFO: " << numberOfStrings <<" localisation strings loaded for " << domain << std::endl; + + uint32_t offsetOrigTable; + if (!readUIn32FromFile(moFile, needsBeToLeConversion, offsetOrigTable)) return LIBINTL_LITE_BOOL_FALSE; + + uint32_t offsetTransTable; + if (!readUIn32FromFile(moFile, needsBeToLeConversion, offsetTransTable)) return LIBINTL_LITE_BOOL_FALSE; + + string* sortedOrigStringsArray = NULL; + ArrayGurard sortedOrigStringsArrayGuard(sortedOrigStringsArray); + sortedOrigStringsArray = new string[numberOfStrings]; + if (!sortedOrigStringsArray) + { + return LIBINTL_LITE_BOOL_FALSE; + } + + if (!loadMoFileStringsToArray(moFile, + numberOfStrings, + offsetOrigTable, + needsBeToLeConversion, + sortedOrigStringsArray)) return LIBINTL_LITE_BOOL_FALSE; + + string* translatedStringsArray = NULL; + ArrayGurard translatedStringsArrayGuard(translatedStringsArray); + translatedStringsArray = new string[numberOfStrings]; + if (!translatedStringsArray) + { + return LIBINTL_LITE_BOOL_FALSE; + } + + if (!loadMoFileStringsToArray(moFile, + numberOfStrings, + offsetTransTable, + needsBeToLeConversion, + translatedStringsArray)) return LIBINTL_LITE_BOOL_FALSE; + + MessageCatalog* newMessageCatalogPtr = new MessageCatalog(numberOfStrings, + sortedOrigStringsArray, + translatedStringsArray); + if (!newMessageCatalogPtr) return LIBINTL_LITE_BOOL_FALSE; + sortedOrigStringsArrayGuard.release(); + translatedStringsArrayGuard.release(); + + char* domainDup = strdup(domain); + if (!domainDup) return LIBINTL_LITE_BOOL_FALSE; + closeLoadedMessageCatalog(domain); + loadedMessageCatalogPtrsByDomain[domainDup] = newMessageCatalogPtr; + + return LIBINTL_LITE_BOOL_TRUE; + } + catch (...) + { + return LIBINTL_LITE_BOOL_FALSE; + } +} + +libintl_lite_bool_t bindtextdomain(const char* domain, const char* moFilePath) +{ + + return loadMessageCatalog( domain, moFilePath ); +} + +libintl_lite_bool_t bind_textdomain_codeset(const char* domain, const char* moFilePath) +{ + // not implemented yet + return LIBINTL_LITE_BOOL_FALSE; +} + +void closeLoadedMessageCatalog(const char* domain) +{ + if (domain) + { + for (map::iterator i = loadedMessageCatalogPtrsByDomain.begin(); + i != loadedMessageCatalogPtrsByDomain.end(); + i++) + { + if (strcmp(i->first, domain) == 0) + { + free(i->first); + delete i->second; + loadedMessageCatalogPtrsByDomain.erase(i); + return; + } + } + } +} + +void closeAllLoadedMessageCatalogs() +{ + for (map::iterator i = loadedMessageCatalogPtrsByDomain.begin(); + i != loadedMessageCatalogPtrsByDomain.end(); + i++) + { + free(i->first); + delete i->second; + } + loadedMessageCatalogPtrsByDomain.clear(); + free(currentDefaultDomain); + currentDefaultDomain = NULL; +} + +const char* textdomain(const char* domain) +{ + if (domain) + { + char* newDefaultDomain = strdup(domain); + if (!newDefaultDomain) + { + return NULL; + } + free(currentDefaultDomain); + currentDefaultDomain = newDefaultDomain; + return newDefaultDomain; + } + else + { + return NULL; + } +} + +const char* gettext(const char* origStr) +{ + return dgettext(NULL, origStr); +} + +const char* dgettext(const char* domain, const char* origStr) +{ + if (!origStr) + { + return NULL; + } + + if (!domain) + { + if (currentDefaultDomain) + { + domain = currentDefaultDomain; + } + else + { + return origStr; + } + } + + const MessageCatalog* msgCat = NULL; + for (map::iterator i = loadedMessageCatalogPtrsByDomain.begin(); + !msgCat && (i != loadedMessageCatalogPtrsByDomain.end()); + i++) + { + if (strcmp(i->first, domain) == 0) + { + msgCat = i->second; + } + } + + if (!msgCat) + { + return origStr; + } + + const string* translatedStrPtr = msgCat->getTranslatedStrPtr(origStr); + if (translatedStrPtr) + { + return translatedStrPtr->c_str(); + } + else + { + return origStr; + } +} + +const char* ngettext(const char* origStr, const char* origStrPlural, unsigned long n) +{ + if (n == 1) + { + return gettext(origStr); + } + else + { + return gettext(origStrPlural); + } +} + +const char* dngettext(const char* domain, const char* origStr, const char* origStrPlural, unsigned long n) +{ + if (n == 1) + { + return dgettext(domain, origStr); + } + else + { + return dgettext(domain, origStrPlural); + } +} diff --git a/lib/intl/libintl.h b/lib/intl/libintl.h new file mode 100644 index 000000000..9a0b610b4 --- /dev/null +++ b/lib/intl/libintl.h @@ -0,0 +1,124 @@ +/* +Boost Software License - Version 1.0 - August 17th, 2003 + +Permission is hereby granted, free of charge, to any person or organization +obtaining a copy of the software and accompanying documentation covered by +this license (the "Software") to use, reproduce, display, distribute, +execute, and transmit the Software, and to prepare derivative works of the +Software, and to permit third-parties to whom the Software is furnished to +do so, all subject to the following: + +The copyright notices in the Software and this entire statement, including +the above license grant, this restriction and the following disclaimer, +must be included in all copies of the Software, in whole or in part, and +all derivative works of the Software, unless such copies or derivative +works are solely in the form of machine-executable object code generated by +a source language processor. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. +*/ + +#ifndef LIBINTL_HPP_ +#define LIBINTL_HPP_ + +#include + +#define LIBINTL_LITE_API +#if (defined(WIN32) || defined(WINCE)) && defined(LIBINTL_LITE_WIN32_SHARED) + #undef LIBINTL_LITE_API + #ifdef LIBINTL_LITE_EXPORTS + #define LIBINTL_LITE_API __declspec(dllexport) + #else + #define LIBINTL_LITE_API __declspec(dllimport) + #endif +#endif + +#ifdef __cplusplus +extern "C" +{ +#endif + +typedef int libintl_lite_bool_t; +#define LIBINTL_LITE_BOOL_TRUE 1 +#define LIBINTL_LITE_BOOL_FALSE 0 + +/** + * Loads a message catalog from a given (GNU-compatible) .mo file. + * Returns true, if the message catalog was loaded successfully and + * false otherwise. + * This function is specific to libintl-lite and serves as a simple + * replacement for bindtextdomain() function of GNU gettext. + * The parameter "domain" must not be NULL! + * This function is NOT thread safe! + * Pay attention to the thread safety remarks of the gettext() function! + */ +LIBINTL_LITE_API libintl_lite_bool_t loadMessageCatalog(const char* domain, const char* moFilePath); +LIBINTL_LITE_API libintl_lite_bool_t loadMessageCatalogFile(const char* domain, FILE* moFile); + +LIBINTL_LITE_API libintl_lite_bool_t bindtextdomain(const char* domain, const char* dirname); + +LIBINTL_LITE_API libintl_lite_bool_t bind_textdomain_codeset(const char* domain, const char* codeset); + +/** + * Closes a message catalog for the specified domain and releases its obtained resources. + * This function is NOT thread safe! + * Pay attention to the thread safety remarks of the gettext() function! + */ +LIBINTL_LITE_API void closeLoadedMessageCatalog(const char* domain); + +/** + * Closes all loaded message catalogs releases their obtained resources. + * This function is NOT thread safe! + * Pay attention to the thread safety remarks of the gettext() function! + */ +LIBINTL_LITE_API void closeAllLoadedMessageCatalogs(); + +/** + * Sets the default text domain for gettext() / ngettext() calls. + * This function is NOT thread safe! + */ +LIBINTL_LITE_API const char* textdomain(const char* domain); + +/** + * Returns a pointer to the NULL-terminated string in the loaded for the default + * message catalog, or origString if origStr is NULL, textdomain() was not called, + * no message catalog for the specified domain is loaded or no translated message + * could be found. + * This function is thread-safe, but loadMessageCatalog(), textdomain(), + * closeLoadedMessageCatalog() or closeAllLoadedMessageCatalogs() + * must not be called at the same time! A returned string in the current + * loaded message catalog will be deleted, if loadMessageCatalog() or + * closeLoadedMessageCatalog() is called for the used domain afterwards! + * Does not perform any character set conversion! + */ +LIBINTL_LITE_API const char* gettext(const char* origStr); + +/** + * Works like the gettext() function, but uses the message catalog for a specified domain. + */ +LIBINTL_LITE_API const char* dgettext(const char* domain, const char* origStr); + +/** + * Works like the gettext() function, but distinguishes between singular + * and plural form of a message. + * Always returns the suitable singular string, if n == 1, and the plural string + * otherwise, regardless of the language. + */ +LIBINTL_LITE_API const char* ngettext(const char* origStr, const char* origStrPlural, unsigned long n); + +/** + * Works like the ngettext() function, but uses the message catalog for a specified domain. + */ +LIBINTL_LITE_API const char* dngettext(const char* domain, const char* origStr, const char* origStrPlural, unsigned long n); + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif // LIBINTL_HPP_ diff --git a/src/defaultsettings.cpp b/src/defaultsettings.cpp index 8dd67167f..f0887e886 100644 --- a/src/defaultsettings.cpp +++ b/src/defaultsettings.cpp @@ -393,6 +393,20 @@ void set_default_settings(Settings *settings) settings->setDefault("curl_verify_cert", "false"); settings->setDefault("gui_scaling_filter_txr2img", "false"); settings->setDefault("mapgens_available", "v7p, v6, flat"); + + // FIXME: this code should be in init_gettext() ideally + char lang[3] = {0}; + #ifdef __ANDROID__ + // Auto-detect language on Android + AConfiguration_getLanguage(porting::app_global->config, lang); + #elif __IOS__ + // Auto-detect language on iOS + NSString *syslang = [[NSLocale preferredLanguages] objectAtIndex:0]; + [syslang getBytes:lang maxLength:2 usedLength:nil encoding:NSASCIIStringEncoding options:0 range:NSMakeRange(0, 2) remainingRange:nil]; + #endif + if (!lang[0]) + errorstream << "Language auto-detection failed!" << std::endl; + settings->setDefault("language", lang); #endif // Android Settings @@ -431,14 +445,6 @@ void set_default_settings(Settings *settings) settings->setDefault("hud_scaling", "0.85"); settings->setDefault("gui_scaling", "1.2"); } - - // Auto-detect language on Android - // FIXME: this code should be in init_gettext() ideally - char lang[3] = {0}; - AConfiguration_getLanguage(porting::app_global->config, lang); - if (!lang[0]) - errorstream << "Language auto-detection failed!" << std::endl; - settings->setDefault("language", lang); #endif // iOS Settings @@ -452,26 +458,26 @@ void set_default_settings(Settings *settings) // set the size of the elements depending on the screen size if ([SDVersion deviceSize] == Screen3Dot5inch) { // 3.5" (old iPhone's) - settings->setDefault("hud_scaling", "0.5"); + settings->setDefault("hud_scaling", "0.55"); } else if ([SDVersion deviceSize] == Screen4inch) { // 4" (iPhone 5) - settings->setDefault("hud_scaling", "0.5"); - settings->setDefault("mouse_sensitivity", "0.25"); + settings->setDefault("hud_scaling", "0.55"); + settings->setDefault("mouse_sensitivity", "0.3"); } else if ([SDVersion deviceSize] == Screen4Dot7inch) { // 4.7" (iPhone) - settings->setDefault("hud_scaling", "0.6"); + settings->setDefault("hud_scaling", "0.65"); settings->setDefault("mouse_sensitivity", "0.25"); } else if ([SDVersion deviceSize] == Screen5Dot5inch) { // 5.5" (iPhone Plus) - settings->setDefault("hud_scaling", "0.7"); + settings->setDefault("hud_scaling", "0.75"); settings->setDefault("mouse_sensitivity", "0.3"); } else if (([SDVersion deviceSize] == Screen5Dot8inch) || ([SDVersion deviceSize] == Screen6Dot1inch) || ([SDVersion deviceSize] == Screen6Dot5inch)) { // 5.8+" (iPhone X-series) - settings->setDefault("hud_scaling", "0.8"); + settings->setDefault("hud_scaling", "0.85"); settings->setDefault("mouse_sensitivity", "0.35"); } else { // iPad - settings->setDefault("hud_scaling", "0.8"); + settings->setDefault("hud_scaling", "0.9"); } // Move the HUD up for the iPhone X-series and new iPad Pro @@ -507,14 +513,6 @@ void set_default_settings(Settings *settings) settings->setDefault("active_block_range", "2"); settings->setDefault("max_block_generate_distance", "5"); } - - // Auto-detect language on iOS - char lang[3] = {0}; - NSString *syslang = [[NSLocale preferredLanguages] objectAtIndex:0]; - [syslang getBytes:lang maxLength:2 usedLength:nil encoding:NSASCIIStringEncoding options:0 range:NSMakeRange(0, 2) remainingRange:nil]; - if (!lang[0]) - errorstream << "Language auto-detection failed!" << std::endl; - settings->setDefault("language", lang); #endif } diff --git a/src/gettext.cpp b/src/gettext.cpp index 3f73473b4..7908f83dc 100644 --- a/src/gettext.cpp +++ b/src/gettext.cpp @@ -234,22 +234,6 @@ void init_gettext(const char *path, const std::string &configured_language, //errorstream << "Gettext debug: domainname = " << tdomain << "; codeset = "<< codeset << std::endl; #endif // defined(_WIN32) -#if defined(__ANDROID__) || defined(__IOS__) - // On Android we use libintl-lite, we need to load .mo files manually - if (!configured_language.empty()) { - std::string mopath = path; - mopath += DIR_DELIM + configured_language - + DIR_DELIM + "LC_MESSAGES" - + DIR_DELIM + PROJECT_NAME - + ".mo"; - infostream << "Loading translations from file: " << mopath << std::endl; - int r = loadMessageCatalog(name.c_str(), mopath.c_str()); - infostream << " " << ( (r == 1)?"success":"failed" ) << std::endl; - } else { - infostream << "Language not configured, skipping load." << std::endl; - } -#endif // defined(__ANDROID__) - #else /* set current system default locale */ setlocale(LC_ALL, ""); diff --git a/src/gettext.h b/src/gettext.h index 775cdb331..aa0257c95 100644 --- a/src/gettext.h +++ b/src/gettext.h @@ -24,7 +24,11 @@ with this program; if not, write to the Free Software Foundation, Inc., #if USE_GETTEXT // #include - #include + #if defined(__ANDROID__) || defined(__IOS__) + #include "libintl.h" + #else + #include + #endif #else // In certain environments, some standard headers like // and include libintl.h. If libintl.h is included after diff --git a/src/touchscreengui.cpp b/src/touchscreengui.cpp index 2a9bc3f36..62b591632 100644 --- a/src/touchscreengui.cpp +++ b/src/touchscreengui.cpp @@ -206,7 +206,7 @@ void TouchScreenGUI::initButton(touch_gui_button_id id, rect button_rect, } static int getMaxControlPadSize(float density) { - return 280 * density * g_settings->getFloat("hud_scaling"); + return 260 * density * g_settings->getFloat("hud_scaling"); } int TouchScreenGUI::getGuiButtonSize() @@ -848,8 +848,9 @@ void TouchScreenGUI::step(float dtime) btn->repeatcounter += dtime; /* in case we're moving around digging does not happen */ + /* If the sneak button is required, it will not let you interact! if (m_move_id != -1) - m_move_has_really_moved = true; + m_move_has_really_moved = true;*/ if (btn->repeatcounter < btn->repeatdelay) continue;