diff --git a/build/android/Makefile b/build/android/Makefile index 1c552636..e46507e1 100644 --- a/build/android/Makefile +++ b/build/android/Makefile @@ -117,6 +117,12 @@ ICONV_TIMESTAMP = $(ICONV_DIR)/timestamp ICONV_TIMESTAMP_INT = $(ANDR_ROOT)/deps/iconv_timestamp ICONV_URL_HTTP = https://ftp.gnu.org/pub/gnu/libiconv/libiconv-$(ICONV_VERSION).tar.gz +INTL_DIR = $(ANDR_ROOT)/deps/libintl/ +INTL_LIB = $(INTL_DIR)/libintl.a +INTL_TIMESTAMP = $(INTL_DIR)timestamp +INTL_TIMESTAMP_INT = $(ANDR_ROOT)/deps/intl_timestamp +INTL_URL_HTTP = https://github.com/j-jorge/libintl-lite/archive/master.tar.gz + SQLITE3_VERSION = 3150000 SQLITE3_DIR = $(ANDR_ROOT)/deps/sqlite SQLITE3_URL = https://www.sqlite.org/2016/sqlite-amalgamation-$(SQLITE3_VERSION).zip @@ -503,6 +509,60 @@ $(ICONV_LIB) : $(ICONV_TIMESTAMP) clean_iconv : $(RM) -rf ${ICONV_DIR} +$(INTL_TIMESTAMP) : intl_download + @LAST_MODIF=$$(find ${INTL_DIR} -type f -printf '%T@ %p\n' | sort -n | tail -1 | cut -f2- -d" "); \ + if [ $$(basename $$LAST_MODIF) != "timestamp" ] ; then \ + touch ${INTL_TIMESTAMP}; \ + fi + +intl_download : + @if [ ! -d ${INTL_DIR} ] ; then \ + echo "libintl sources missing, downloading..."; \ + mkdir -p ${ANDR_ROOT}/deps; \ + cd ${ANDR_ROOT}/deps; \ + wget ${INTL_URL_HTTP} -O libintl.tar.gz || exit 1; \ + tar -xzf libintl.tar.gz || exit 1; \ + rm libintl.tar.gz; \ + ln -s libintl-lite-master libintl; \ + fi + +intl : $(INTL_LIB) + +$(INTL_LIB) : $(INTL_TIMESTAMP) + @REFRESH=0; \ + if [ ! -e ${INTL_TIMESTAMP_INT} ] ; then \ + REFRESH=1; \ + fi; \ + if [ ! -e ${INTL_LIB} ] ; then \ + REFRESH=1; \ + fi; \ + if [ ${INTL_TIMESTAMP} -nt ${INTL_TIMESTAMP_INT} ] ; then \ + REFRESH=1; \ + fi; \ + if [ $$REFRESH -ne 0 ] ; then \ + mkdir -p ${INTL_DIR}; \ + echo "changed timestamp for intl detected building..."; \ + cd ${INTL_DIR}; \ + \ + export TOOLCHAIN=/tmp/ndk-${TARGET_HOST}-intl; \ + ${ANDROID_NDK}/build/tools/make-standalone-toolchain.sh \ + --toolchain=${TARGET_TOOLCHAIN}-${COMPILER_VERSION} \ + --platform=${APP_PLATFORM} --install-dir=$${TOOLCHAIN}; \ + export PATH="$${TOOLCHAIN}/bin:$${PATH}"; \ + cd internal; \ + ${CROSS_PREFIX}g++ -O3 -c libintl.cpp -o libintl.o || exit 1; \ + ${CROSS_PREFIX}ar rs ../libintl.a libintl.o || exit 1; \ + cd ..; \ + touch ${INTL_TIMESTAMP}; \ + touch ${INTL_TIMESTAMP_INT}; \ + rm -rf ${TOOLCHAIN}; \ + else \ + echo "nothing to be done for intl"; \ + 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 @@ -778,6 +838,20 @@ assets : $(ASSETS_TIMESTAMP) mkdir ${APP_ROOT}/assets/MultiCraft/fonts; \ cp -r ${PROJ_ROOT}/fonts/retrovillenc.ttf ${APP_ROOT}/assets/MultiCraft/fonts/; \ cp -r ${PROJ_ROOT}/games ${APP_ROOT}/assets/MultiCraft; \ + mkdir -p ${APP_ROOT}/assets/MultiCraft/locale; \ + pushd ${PROJ_ROOT}/po; \ + for lang in *; do \ + [ $${#lang} -ne 2 ] && continue; \ + MOPATH=${APP_ROOT}/assets/MultiCraft/locale/$$lang/LC_MESSAGES; \ + mkdir -p $$MOPATH; \ + pushd $$lang; \ + for fn in *.po; do \ + newfn=$${fn/.po/.mo}; \ + msgfmt -o $$MOPATH/$$newfn $$fn; \ + done; \ + popd; \ + done; \ + popd; \ cp -r ${PROJ_ROOT}/textures ${APP_ROOT}/assets/MultiCraft; \ cp -r ${PROJ_ROOT}/worlds ${APP_ROOT}/assets/MultiCraft; \ cd ${APP_ROOT}/assets || exit 1; \ @@ -802,7 +876,7 @@ clean_assets : # $(MPIR_LIB) apk: local.properties $(ICONV_LIB) $(IRRLICHT_LIB) $(CURL_LIB) $(LEVELDB_LIB) $(LUAJIT_LIB) \ - $(OPENAL_LIB) $(VORBIS_LIB) prep_srcdir $(ANDR_ROOT)/jni/src/android_version.h \ + $(OPENAL_LIB) $(VORBIS_LIB) $(INTL_LIB) prep_srcdir $(ANDR_ROOT)/jni/src/android_version.h \ $(ANDR_ROOT)/jni/src/android_version_githash.h sqlite3_download assets + @${ANDROID_NDK}/ndk-build NDK_MODULE_PATH=${NDK_MODULE_PATH} \ GPROF=${GPROF} APP_ABI=${TARGET_ABI} \ diff --git a/build/android/jni/Android.mk b/build/android/jni/Android.mk index 0d16a47d..31f70662 100644 --- a/build/android/jni/Android.mk +++ b/build/android/jni/Android.mk @@ -27,6 +27,11 @@ LOCAL_MODULE := iconv LOCAL_SRC_FILES := deps/libiconv/lib/.libs/libiconv.a include $(PREBUILT_STATIC_LIBRARY) +include $(CLEAR_VARS) +LOCAL_MODULE := intl +LOCAL_SRC_FILES := deps/libintl/libintl.a +include $(PREBUILT_STATIC_LIBRARY) + include $(CLEAR_VARS) LOCAL_MODULE := openal LOCAL_SRC_FILES := deps/openal-soft/android/obj/local/$(APP_ABI)/libopenal.a @@ -42,22 +47,6 @@ LOCAL_MODULE := LuaJIT LOCAL_SRC_FILES := deps/luajit/src/libluajit.a include $(PREBUILT_STATIC_LIBRARY) -#include $(CLEAR_VARS) -#LOCAL_MODULE := GNUIntl -#LOCAL_SRC_FILES := deps/gnuintl/obj/local/$(APP_ABI)/libgnuintl.so -#LOCAL_CFLAGS := -DHAVE_CONFIG_H -#LOCAL_CFLAGS += -DDEPENDS_ON_LIBICONV=1 -#LOCAL_CFLAGS += -Drelocate=libintl_relocate -#LOCAL_CFLAGS += -Dset_relocation_prefix=libintl_set_relocation_prefix -#LOCAL_CFLAGS += -DNO_XMALLOC -#LOCAL_CFLAGS += -DIN_LIBRARY -#LOCAL_CFLAGS += -DENABLE_RELOCATABLE=1 -#LOCAL_CFLAGS += -DIN_LIBINTL -#LOCAL_CFLAGS += -DBUILDING_DLL -#LOCAL_CFLAGS += -DBUILDING_LIBINTL -#LOCAL_CFLAGS += -DLOCALE_ALIAS_PATH=\"/sdcard/Android/data/mobi.MultiCraft/files\" -#include $(PREBUILT_SHARED_LIBRARY) - include $(CLEAR_VARS) LOCAL_MODULE := multicraft @@ -70,6 +59,7 @@ LOCAL_CFLAGS := -D_IRR_ANDROID_PLATFORM_ \ -DUSE_CURL=1 \ -DUSE_SOUND=1 \ -DUSE_FREETYPE=1 \ + -DUSE_GETTEXT=1 \ -DUSE_LEVELDB=1 \ $(GPROF_DEF) \ -pipe -fstrict-aliasing @@ -106,6 +96,7 @@ LOCAL_C_INCLUDES := \ jni/src/gmp \ deps/irrlicht/include \ deps/libiconv/include \ + deps/libintl \ deps/freetype/include \ deps/curl/include \ deps/openal-soft/include \ @@ -113,8 +104,6 @@ LOCAL_C_INCLUDES := \ deps/sqlite/ \ deps/leveldb/include \ deps/luajit/src \ -# deps/gnuintl/jni/include \ -# deps/gnuintl/jni/src LOCAL_SRC_FILES := \ jni/src/ban.cpp \ @@ -310,8 +299,7 @@ LOCAL_SRC_FILES += \ # JSONCPP LOCAL_SRC_FILES += jni/src/json/jsoncpp.cpp -LOCAL_STATIC_LIBRARIES := Irrlicht LevelDB freetype curl iconv LuaJIT openal vorbis android_native_app_glue $(PROFILER_LIBS) -#LOCAL_SHARED_LIBRARIES := GNUIntl +LOCAL_STATIC_LIBRARIES := Irrlicht LevelDB freetype curl iconv intl LuaJIT openal vorbis android_native_app_glue $(PROFILER_LIBS) LOCAL_LDLIBS := -lEGL -lGLESv1_CM -lGLESv2 -landroid -lOpenSLES diff --git a/src/defaultsettings.cpp b/src/defaultsettings.cpp index 7490aa56..9a643cf4 100644 --- a/src/defaultsettings.cpp +++ b/src/defaultsettings.cpp @@ -334,7 +334,18 @@ void set_default_settings(Settings *settings) settings->setDefault("high_precision_fpu", "true"); +#ifdef __ANDROID__ + // 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); +#else settings->setDefault("language", ""); +#endif + settings->setDefault("mainmenu_last_selected_world", "1"); #ifdef __ANDROID__ diff --git a/src/gettext.cpp b/src/gettext.cpp index f5485a89..306ee37c 100644 --- a/src/gettext.cpp +++ b/src/gettext.cpp @@ -24,12 +24,12 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "gettext.h" #include "util/string.h" #include "log.h" +#include "filesys.h" #if USE_GETTEXT && defined(_MSC_VER) #include #include #include -#include "filesys.h" #define setlocale(category, localename) \ setlocale(category, MSVC_LocaleLookup(localename)) @@ -234,6 +234,22 @@ 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__) + // 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/porting_android.cpp b/src/porting_android.cpp index 6abc2a54..e22c6c5e 100644 --- a/src/porting_android.cpp +++ b/src/porting_android.cpp @@ -208,6 +208,7 @@ void initializePathsAndroid() "getExternalStorageDirectory"); path_user = path_storage + DIR_DELIM + "Android/data/mobi.MultiCraft/Files"; path_share = path_user; + path_locale = path_user + DIR_DELIM + "locale"; } void showInputDialog(const std::string& acceptButton, const std::string& hint,