diff --git a/.gitignore b/.gitignore index 5b05d809..fbeee760 100644 --- a/.gitignore +++ b/.gitignore @@ -61,14 +61,14 @@ locale/ *.a ## Android build files -build/android/assets -build/android/bin -build/android/Debug +build/android/src/main/assets +build/android/build build/android/deps -build/android/gen +build/android/libs build/android/jni/src +build/android/src/main/jniLibs build/android/obj -build/android/path.cfg -build/android/and_env -build/android/AndroidManifest.xml -timestamp \ No newline at end of file +build/android/local.properties +build/android/.gradle +timestamp + diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 468ba051..986f6002 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -25,6 +25,7 @@ If you are planning to start some significant coding, you would benefit from ask - Have a title which begins with a capital letter - Be descriptive. (e.g. no `Update init.lua` or `Fix a problem`) - Have a first line with less than *80 characters* and have a second line that is *empty* + - Do **not** [sign your commits](https://git-scm.com/book/uz/v2/Git-Tools-Signing-Your-Work), as Minetest offers automatically built ppas over launchpad and it [would break](https://bugs.launchpad.net/bzr-git/+bug/1084403) if there were signed commits in master 4. Once you are happy with your changes, submit a pull request. - Open the [pull-request form](https://github.com/minetest/minetest/pull/new/master) diff --git a/build/android/AndroidManifest.xml.template b/build/android/AndroidManifest.xml.template deleted file mode 100644 index 3b882ffe..00000000 --- a/build/android/AndroidManifest.xml.template +++ /dev/null @@ -1,60 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/build/android/Makefile b/build/android/Makefile index 44753c44..5d0e45b8 100644 --- a/build/android/Makefile +++ b/build/android/Makefile @@ -6,12 +6,17 @@ # build for build platform APP_PLATFORM = android-19 -# paths used for timestaps, dependencys, tree config and libs -PATHCFGFILE = path.cfg +ANDR_ROOT = $(shell pwd) +PROJ_ROOT = $(shell realpath $(ANDR_ROOT)/../..) +APP_ROOT = $(ANDR_ROOT)/src/main -ANDROID_VERSION_CODE = 1 -COMPILER_VERSION = 4.9 +VERSION_MAJOR := $(shell cat $(PROJ_ROOT)/CMakeLists.txt | \ + grep ^set\(VERSION_MAJOR\ | sed 's/)/ /' | cut -f2 -d' ') +VERSION_MINOR := $(shell cat $(PROJ_ROOT)/CMakeLists.txt | \ + grep ^set\(VERSION_MINOR\ | sed 's/)/ /' | cut -f2 -d' ') +VERSION_PATCH := $(shell cat $(PROJ_ROOT)/CMakeLists.txt | \ + grep ^set\(VERSION_PATCH\ | sed 's/)/ /' | cut -f2 -d' ') ################################################################################ # toolchain config for ARMv7 @@ -27,6 +32,7 @@ TARGET_CXXFLAGS_ADDON = $(TARGET_CFLAGS_ADDON) TARGET_LDFLAGS_ADDON = -Wl,--no-warn-mismatch,--gc-sections -lm_hard TARGET_ARCH = armv7 CROSS_PREFIX = arm-linux-androideabi- +COMPILER_VERSION = 4.9 ################################################################################ # toolchain config for ARMv8 @@ -42,6 +48,7 @@ CROSS_PREFIX = arm-linux-androideabi- # TARGET_LDFLAGS_ADDON = -Wl,--no-warn-mismatch,--gc-sections # TARGET_ARCH = arm64 # CROSS_PREFIX = aarch64-linux-android- +# COMPILER_VERSION = 4.9 ################################################################################ # toolchain config for x86 @@ -57,93 +64,96 @@ CROSS_PREFIX = arm-linux-androideabi- # TARGET_LDFLAGS_ADDON = -Wl,--no-warn-mismatch,--gc-sections # TARGET_ARCH = x86 # CROSS_PREFIX = i686-linux-android- +# COMPILER_VERSION = 4.9 ################################################################################ ASSETS_TIMESTAMP = deps/assets_timestamp -OPENAL_FOLDER = $(ROOT)/deps/openal-soft -OPENAL_DIR = $(ROOT)/deps/openal-soft/android +OPENAL_FOLDER = $(ANDR_ROOT)/deps/openal-soft +OPENAL_DIR = $(ANDR_ROOT)/deps/openal-soft/android OPENAL_LIB = $(OPENAL_DIR)/libs/$(TARGET_ABI)/libopenal.so OPENAL_TIMESTAMP = $(OPENAL_DIR)/timestamp -OPENAL_TIMESTAMP_INT = $(ROOT)/deps/openal_timestamp +OPENAL_TIMESTAMP_INT = $(ANDR_ROOT)/deps/openal_timestamp OPENAL_URL_GIT = https://github.com/MoNTE48/openal-soft -VORBIS_DIR = $(ROOT)/deps/libvorbis-android +VORBIS_DIR = $(ANDR_ROOT)/deps/libvorbis-android VORBIS_LIB = $(VORBIS_DIR)/obj/local/$(TARGET_ABI)/libvorbis.a VORBIS_TIMESTAMP = $(VORBIS_DIR)/timestamp -VORBIS_TIMESTAMP_INT = $(ROOT)/deps/vorbis_timestamp +VORBIS_TIMESTAMP_INT = $(ANDR_ROOT)/deps/vorbis_timestamp VORBIS_URL_GIT = https://github.com/MoNTE48/libvorbis-android IRRLICHT_COMMIT = 58fa0cf3419c2733159fc3c6253634bedada3bfe -#IRRLICHT_COMMIT = 54b8cba398c3b845d0d1158822916c2f78be194b -IRRLICHT_DIR = $(ROOT)/deps/irrlicht +IRRLICHT_DIR = $(ANDR_ROOT)/deps/irrlicht IRRLICHT_LIB = $(IRRLICHT_DIR)/lib/Android/libIrrlicht.a IRRLICHT_TIMESTAMP = $(IRRLICHT_DIR)/timestamp -IRRLICHT_TIMESTAMP_INT = $(ROOT)/deps/irrlicht_timestamp +IRRLICHT_TIMESTAMP_INT = $(ANDR_ROOT)/deps/irrlicht_timestamp IRRLICHT_URL_HTTP = https://github.com/zaki/irrlicht/archive/$(IRRLICHT_COMMIT).zip # not used now OPENSSL_VERSION = 1.0.2g -OPENSSL_DIR = $(ROOT)/deps/openssl +OPENSSL_DIR = $(ANDR_ROOT)/deps/openssl OPENSSL_LIB = $(OPENSSL_DIR)/libssl.so.1.0.0 OPENSSL_TIMESTAMP = $(OPENSSL_DIR)/timestamp -OPENSSL_TIMESTAMP_INT = $(ROOT)/deps/openssl_timestamp +OPENSSL_TIMESTAMP_INT = $(ANDR_ROOT)/deps/openssl_timestamp OPENSSL_URL = ftp://ftp.openssl.org/source/openssl-$(OPENSSL_VERSION).tar.gz CURL_VERSION = 7.48.0 -CURL_DIR = $(ROOT)/deps/curl +CURL_DIR = $(ANDR_ROOT)/deps/curl CURL_LIB = $(CURL_DIR)/lib/.libs/libcurl.a CURL_TIMESTAMP = $(CURL_DIR)/timestamp -CURL_TIMESTAMP_INT = $(ROOT)/deps/curl_timestamp +CURL_TIMESTAMP_INT = $(ANDR_ROOT)/deps/curl_timestamp CURL_URL_HTTP = http://curl.haxx.se/download/curl-${CURL_VERSION}.tar.bz2 GMP_VERSION = 6.1.0 -GMP_DIR = $(ROOT)/deps/gmp +GMP_DIR = $(ANDR_ROOT)/deps/gmp GMP_LIB = $(GMP_DIR)/usr/lib/libgmp.so GMP_TIMESTAMP = $(GMP_DIR)/timestamp -GMP_TIMESTAMP_INT = $(ROOT)/deps/gmp_timestamp +GMP_TIMESTAMP_INT = $(ANDR_ROOT)/deps/gmp_timestamp GMP_URL_HTTP = https://gmplib.org/download/gmp/gmp-$(GMP_VERSION).tar.bz2 FREETYPE_VERSION = 2.6.3 -FREETYPE_DIR = $(ROOT)/deps/freetype +FREETYPE_DIR = $(ANDR_ROOT)/deps/freetype FREETYPE_LIB = $(FREETYPE_DIR)/objs/.libs/libfreetype.a FREETYPE_TIMESTAMP = $(FREETYPE_DIR)/timestamp -FREETYPE_TIMESTAMP_INT = $(ROOT)/deps/freetype_timestamp +FREETYPE_TIMESTAMP_INT = $(ANDR_ROOT)/deps/freetype_timestamp FREETYPE_URL_HTTP = http://download.savannah.gnu.org/releases/freetype/freetype-$(FREETYPE_VERSION).tar.bz2 ICONV_VERSION = 1.14 -ICONV_DIR = $(ROOT)/deps/libiconv +ICONV_DIR = $(ANDR_ROOT)/deps/libiconv ICONV_LIB = $(ICONV_DIR)/lib/.libs/libiconv.a ICONV_TIMESTAMP = $(ICONV_DIR)/timestamp -ICONV_TIMESTAMP_INT = $(ROOT)/deps/iconv_timestamp +ICONV_TIMESTAMP_INT = $(ANDR_ROOT)/deps/iconv_timestamp ICONV_URL_HTTP = http://ftp.gnu.org/pub/gnu/libiconv/libiconv-$(ICONV_VERSION).tar.gz SQLITE3_VERSION= 3120200 -SQLITE3_DIR = $(ROOT)/deps/sqlite +SQLITE3_DIR = $(ANDR_ROOT)/deps/sqlite SQLITE3_URL = http://www.sqlite.org/2016/sqlite-amalgamation-$(SQLITE3_VERSION).zip LUAJIT_GIT_BRANCH = v2.1 -LUAJIT_DIR = $(ROOT)/deps/luajit +LUAJIT_DIR = $(ANDR_ROOT)/deps/luajit LUAJIT_LIB = $(LUAJIT_DIR)src/libluajit.a LUAJIT_TIMESTAMP = $(LUAJIT_DIR)/timestamp -LUAJIT_TIMESTAMP_INT = $(ROOT)/deps/luajit_timestamp +LUAJIT_TIMESTAMP_INT = $(ANDR_ROOT)/deps/luajit_timestamp LUAJIT_URL_GIT = https://github.com/LuaJIT/LuaJIT.git ################################################################################ OS := $(shell uname) -ROOT = $(shell pwd) +ANDR_ROOT = $(shell pwd) -VERSION_MAJOR := $(shell cat $(ROOT)/../../CMakeLists.txt | \ +VERSION_MAJOR := $(shell cat $(ANDR_ROOT)/../../CMakeLists.txt | \ grep ^set\(VERSION_MAJOR\ | sed 's/)/ /' | cut -f2 -d' ') -VERSION_MINOR := $(shell cat $(ROOT)/../../CMakeLists.txt | \ +VERSION_MINOR := $(shell cat $(ANDR_ROOT)/../../CMakeLists.txt | \ grep ^set\(VERSION_MINOR\ | sed 's/)/ /' | cut -f2 -d' ') -VERSION_PATCH := $(shell cat $(ROOT)/../../CMakeLists.txt | \ +VERSION_PATCH := $(shell cat $(ANDR_ROOT)/../../CMakeLists.txt | \ grep ^set\(VERSION_PATCH\ | sed 's/)/ /' | cut -f2 -d' ') --include $(PATHCFGFILE) +ANDROID_SDK = $(shell grep '^sdk\.dir' local.properties | sed 's/^.*=[[:space:]]*//') +ANDROID_NDK = $(shell grep '^ndk\.dir' local.properties | sed 's/^.*=[[:space:]]*//') +NDK_MODULE_PATH = $(ANDROID_NDK)/toolchains + .PHONY : debug release reconfig delconfig \ irrlicht_download clean_irrlicht irrlicht \ @@ -152,52 +162,51 @@ VERSION_PATCH := $(shell cat $(ROOT)/../../CMakeLists.txt | \ luajit_download clean_luajit luajit \ apk clean_apk \ clean_all clean prep_srcdir \ - install_debug install envpaths all \ - manifest clean_manifest\ + install_debug install_release envpaths all \ $(ASSETS_TIMESTAMP) $(LUAJIT_TIMESTAMP) \ $(OPENAL_TIMESTAMP) $(VORBIS_TIMESTAMP) \ $(IRRLICHT_TIMESTAMP) $(CURL_TIMESTAMP) \ #$(OPENSSL_TIMESTAMP) $(VORBIS_TIMESTAMP) \ $(VORBIS_TIMESTAMP) \ - $(ROOT)/jni/src/android_version.h \ - $(ROOT)/jni/src/android_version_githash.h + $(ANDR_ROOT)/jni/src/android_version.h \ + $(ANDR_ROOT)/jni/src/android_version_githash.h -debug : $(PATHCFGFILE) +debug : local.properties export NDEBUG=; \ export BUILD_TYPE=debug; \ $(MAKE) apk all : debug release -release : $(PATHCFGFILE) +release : local.properties @export NDEBUG=1; \ export BUILD_TYPE=release; \ $(MAKE) apk reconfig: delconfig - @$(MAKE) $(PATHCFGFILE) + @$(MAKE) local.properties -delconfig : - $(RM) ${PATHCFGFILE} +delconfig: + $(RM) local.properties -$(PATHCFGFILE) : +local.properties: @echo "Please specify path of ANDROID NDK"; \ - echo "e.g. /home/user/android-ndk-r10e/"; \ + echo "e.g. $$HOME/Android/ndk-r11c/"; \ read ANDROID_NDK ; \ if [ ! -d $$ANDROID_NDK ] ; then \ echo "$$ANDROID_NDK is not a valid folder"; \ exit 1; \ fi; \ - echo "ANDROID_NDK = $$ANDROID_NDK" > ${PATHCFGFILE}; \ - echo "+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++";\ + echo "ndk.dir = $$ANDROID_NDK" > local.properties; \ echo "Please specify path of ANDROID SDK"; \ - echo "e.g. /home/user/adt-bundle-linux-x86_64-20131030/sdk/"; \ + echo "e.g. $$HOME/Android/sdk/"; \ read SDKFLDR ; \ if [ ! -d $$SDKFLDR ] ; then \ echo "$$SDKFLDR is not a valid folder"; \ exit 1; \ fi; \ - echo "SDKFOLDER = $$SDKFLDR" >> ${PATHCFGFILE}; + echo "sdk.dir = $$SDKFLDR" >> local.properties; + $(OPENAL_TIMESTAMP) : openal_download @LAST_MODIF=$$(find ${OPENAL_DIR} -type f -printf '%T@ %p\n' | sort -n | tail -1 | cut -f2- -d" "); \ @@ -208,8 +217,8 @@ $(OPENAL_TIMESTAMP) : openal_download openal_download : @if [ ! -d ${OPENAL_DIR} ] ; then \ echo "openal sources missing, downloading..."; \ - mkdir -p ${ROOT}/deps; \ - cd ${ROOT}/deps ; \ + mkdir -p ${ANDR_ROOT}/deps; \ + cd ${ANDR_ROOT}/deps ; \ git clone ${OPENAL_URL_GIT} || exit 1; \ fi @@ -224,12 +233,11 @@ $(OPENAL_LIB): $(OPENAL_TIMESTAMP) REFRESH=1; \ fi; \ if [ $$REFRESH -ne 0 ] ; then \ - export PATH=$$PATH:${ANDROID_NDK}; \ echo "changed timestamp for openal detected building..."; \ cd ${OPENAL_DIR}; \ - ndk-build NDEBUG=${NDEBUG} \ - APP_ABI=${TARGET_ABI} APP_PLATFORM=${APP_PLATFORM} \ - LOCAL_CXXFLAGS+="${TARGET_CXXFLAGS_ADDON}" || exit 1; \ + ${ANDROID_NDK}/ndk-build NDEBUG=${NDEBUG} \ + NDK_MODULE_PATH=${NDK_MODULE_PATH} APP_ABI=${TARGET_ABI} \ + TARGET_ARCH_ABI=${TARGET_ABI} APP_PLATFORM=${APP_PLATFORM} || exit 1; \ touch ${OPENAL_TIMESTAMP}; \ touch ${OPENAL_TIMESTAMP_INT}; \ else \ @@ -248,8 +256,8 @@ $(VORBIS_TIMESTAMP) : vorbis_download vorbis_download : @if [ ! -d ${VORBIS_DIR} ] ; then \ echo "vorbis sources missing, downloading..."; \ - mkdir -p ${ROOT}/deps; \ - cd ${ROOT}/deps ; \ + mkdir -p ${ANDR_ROOT}/deps; \ + cd ${ANDR_ROOT}/deps ; \ git clone ${VORBIS_URL_GIT}|| exit 1; \ fi @@ -265,14 +273,16 @@ $(VORBIS_LIB): $(VORBIS_TIMESTAMP) REFRESH=1; \ fi; \ if [ $$REFRESH -ne 0 ] ; then \ - export PATH=$$PATH:${ANDROID_NDK}; \ echo "changed timestamp for vorbis detected building..."; \ cd ${VORBIS_DIR}; \ - ndk-build NDEBUG=${NDEBUG} \ - APP_ABI=${TARGET_ABI} APP_PLATFORM=${APP_PLATFORM} \ - LOCAL_CXXFLAGS+="${TARGET_CXXFLAGS_ADDON}" || exit 1; \ - touch ${VORBIS_TIMESTAMP}; \ - touch ${VORBIS_TIMESTAMP_INT}; \ + ${ANDROID_NDK}/ndk-build NDEBUG=${NDEBUG} \ + NDK_MODULE_PATH=${NDK_MODULE_PATH} \ + APP_ABI=${TARGET_ABI} APP_PLATFORM=${APP_PLATFORM} \ + TARGET_CFLAGS+="${TARGET_CFLAGS_ADDON}" \ + TARGET_LDFLAGS+="${TARGET_LDFLAGS_ADDON}" \ + TARGET_CXXFLAGS+="${TARGET_CXXFLAGS_ADDON}" || exit 1; \ + touch ${OGG_TIMESTAMP}; \ + touch ${OGG_TIMESTAMP_INT}; \ else \ echo "nothing to be done for libvorbis"; \ fi @@ -289,11 +299,11 @@ $(OPENSSL_TIMESTAMP) : openssl_download openssl_download : @if [ ! -d ${OPENSSL_DIR} ] ; then \ echo "openssl sources missing, downloading..."; \ - mkdir -p ${ROOT}/deps; \ - cd ${ROOT}/deps; \ + mkdir -p ${ANDR_ROOT}/deps; \ + cd ${ANDR_ROOT}/deps; \ wget ${OPENSSL_URL} || exit 1; \ tar -xzf openssl-$(OPENSSL_VERSION).tar.gz; \ - $(RM) -rf $(ROOT)/deps/openssl-$(OPENSSL_VERSION).tar.gz; \ + $(RM) -rf $(ANDR_ROOT)/deps/openssl-$(OPENSSL_VERSION).tar.gz; \ mv openssl-$(OPENSSL_VERSION) openssl; \ fi @@ -313,8 +323,8 @@ $(OPENSSL_LIB): $(OPENSSL_TIMESTAMP) $(GMP_LIB) cd ${OPENSSL_DIR}; \ export TOOLCHAIN=/tmp/ndk-${TARGET_HOST}-openssl; \ ${ANDROID_NDK}/build/tools/make-standalone-toolchain.sh \ - --toolchain=${TARGET_TOOLCHAIN}-${COMPILER_VERSION} \ - --install-dir=$${TOOLCHAIN} --platform=${APP_PLATFORM}; \ + --toolchain=${TARGET_TOOLCHAIN}-${COMPILER_VERSION} \ + --install-dir=$${TOOLCHAIN} --platform=${APP_PLATFORM}; \ export PATH="$${TOOLCHAIN}/bin:$${PATH}"; \ CC=${CROSS_PREFIX}gcc ./Configure no-ssl2 no-ssl3 no-hw enable-gmp \ -DL_ENDIAN -I${GMP_DIR} -L${GMP_DIR}/usr/lib android-${TARGET_ARCH}; \ @@ -340,7 +350,7 @@ $(FREETYPE_TIMESTAMP) : freetype_download freetype_download : @if [ ! -d "${FREETYPE_DIR}" ] ; then \ echo "freetype sources missing, downloading..."; \ - mkdir -p ${ROOT}/deps; \ + mkdir -p ${ANDR_ROOT}/deps; \ cd deps; \ wget ${FREETYPE_URL_HTTP} || exit 1; \ tar -xjf freetype-${FREETYPE_VERSION}.tar.bz2 || exit 1; \ @@ -398,15 +408,15 @@ $(ICONV_TIMESTAMP) : iconv_download iconv_download : @if [ ! -d ${ICONV_DIR} ] ; then \ echo "iconv sources missing, downloading..."; \ - mkdir -p ${ROOT}/deps; \ - cd ${ROOT}/deps; \ + mkdir -p ${ANDR_ROOT}/deps; \ + cd ${ANDR_ROOT}/deps; \ wget ${ICONV_URL_HTTP} || exit 1; \ tar -xzf libiconv-${ICONV_VERSION}.tar.gz || exit 1; \ rm libiconv-${ICONV_VERSION}.tar.gz; \ mv libiconv-${ICONV_VERSION} libiconv; \ cd libiconv; \ - patch -p1 < ${ROOT}/libiconv_android.patch; \ - patch -p1 < ${ROOT}/libiconv_stdio.patch; \ + patch -p1 < ${ANDR_ROOT}/libiconv_android.patch; \ + patch -p1 < ${ANDR_ROOT}/libiconv_stdio.patch; \ fi iconv : $(ICONV_LIB) @@ -423,13 +433,13 @@ $(ICONV_LIB) : $(ICONV_TIMESTAMP) REFRESH=1; \ fi; \ if [ $$REFRESH -ne 0 ] ; then \ - export PATH=$$PATH:${ANDROID_NDK}; \ + mkdir -p ${ICONV_DIR}; \ echo "changed timestamp for iconv detected building..."; \ cd ${ICONV_DIR}; \ export TOOLCHAIN=/tmp/ndk-${TARGET_HOST}-iconv; \ ${ANDROID_NDK}/build/tools/make-standalone-toolchain.sh \ - --toolchain=${TARGET_TOOLCHAIN}-${COMPILER_VERSION} \ - --platform=${APP_PLATFORM} --install-dir=$${TOOLCHAIN}; \ + --toolchain=${TARGET_TOOLCHAIN}-${COMPILER_VERSION} \ + --platform=${APP_PLATFORM} --install-dir=$${TOOLCHAIN}; \ export PATH="$${TOOLCHAIN}/bin:$${PATH}"; \ export CC=${CROSS_PREFIX}gcc; \ export CXX=${CROSS_PREFIX}g++; \ @@ -459,7 +469,7 @@ clean_iconv : irrlicht_download : @if [ ! -d "deps/irrlicht" ] ; then \ echo "irrlicht sources missing, downloading..."; \ - mkdir -p ${ROOT}/deps; \ + mkdir -p ${ANDR_ROOT}/deps; \ cd deps; \ wget ${IRRLICHT_URL_HTTP} || exit 1; \ unzip ${IRRLICHT_COMMIT}.zip || exit 1; \ @@ -467,10 +477,10 @@ irrlicht_download : mv irrlicht-${IRRLICHT_COMMIT} irrlicht; \ cd irrlicht; \ mkdir -p lib/Android; \ - patch -p1 < ../../irrlicht-touchcount.patch || exit 1; \ - patch -p1 < ../../irrlicht-back_button.patch || exit 1; \ - patch -p1 < ../../irrlicht-texturehack.patch || exit 1; \ - patch -p1 < ../../irrlicht-optimization.patch || exit 1; \ + patch -p1 < ${ANDR_ROOT}/patches/irrlicht-touchcount.patch || exit 1; \ + patch -p1 < ${ANDR_ROOT}/patches/irrlicht-back_button.patch || exit 1; \ + patch -p1 < ${ANDR_ROOT}/patches/irrlicht-texturehack.patch || exit 1; \ + patch -p1 < ${ANDR_ROOT}/patches/irrlicht-optimization.patch || exit 1;\ fi $(IRRLICHT_TIMESTAMP) : irrlicht_download @@ -493,11 +503,12 @@ $(IRRLICHT_LIB): $(IRRLICHT_TIMESTAMP) $(FREETYPE_LIB) REFRESH=1; \ fi; \ if [ $$REFRESH -ne 0 ] ; then \ - export PATH=$$PATH:${ANDROID_NDK}; \ + mkdir -p ${IRRLICHT_DIR}; \ echo "changed timestamp for irrlicht detected building..."; \ cd deps/irrlicht/source/Irrlicht/Android; \ - ndk-build NDEBUG=${NDEBUG} \ - APP_ABI=${TARGET_ABI} APP_PLATFORM=${APP_PLATFORM} || exit 1; \ + ${ANDROID_NDK}/ndk-build NDEBUG=${NDEBUG} \ + NDK_MODULE_PATH=${NDK_MODULE_PATH} \ + APP_ABI=${TARGET_ABI} APP_PLATFORM=${APP_PLATFORM} || exit 1; \ touch ${IRRLICHT_TIMESTAMP}; \ touch ${IRRLICHT_TIMESTAMP_INT}; \ else \ @@ -517,7 +528,7 @@ $(CURL_TIMESTAMP) : curl_download curl_download : @if [ ! -d "deps/curl" ] ; then \ echo "curl sources missing, downloading..."; \ - mkdir -p ${ROOT}/deps; \ + mkdir -p ${ANDR_ROOT}/deps; \ cd deps; \ wget ${CURL_URL_HTTP} || exit 1; \ tar -xjf curl-${CURL_VERSION}.tar.bz2 || exit 1; \ @@ -540,14 +551,14 @@ $(CURL_LIB): $(CURL_TIMESTAMP) REFRESH=1; \ fi; \ if [ $$REFRESH -ne 0 ] ; then \ - export PATH=$$PATH:${ANDROID_NDK}; \ + mkdir -p ${CURL_DIR}; \ echo "changed timestamp for curl detected building..."; \ cd deps/curl; \ export CROSS_PREFIX=${CROSS_PREFIX}; \ export TOOLCHAIN=/tmp/ndk-${TARGET_HOST}-curl; \ ${ANDROID_NDK}/build/tools/make-standalone-toolchain.sh \ - --toolchain=${TARGET_TOOLCHAIN}-${COMPILER_VERSION} \ - --platform=${APP_PLATFORM} --install-dir=$${TOOLCHAIN}; \ + --toolchain=${TARGET_TOOLCHAIN}-${COMPILER_VERSION} \ + --platform=${APP_PLATFORM} --install-dir=$${TOOLCHAIN}; \ export PATH="$${TOOLCHAIN}/bin:$${PATH}"; \ export CC=${CROSS_PREFIX}gcc; \ export CXX=${CROSS_PREFIX}g++; \ @@ -579,7 +590,7 @@ $(GMP_TIMESTAMP) : gmp_download gmp_download : @if [ ! -d "${GMP_DIR}" ] ; then \ echo "gmp sources missing, downloading..."; \ - mkdir -p ${ROOT}/deps; \ + mkdir -p ${ANDR_ROOT}/deps; \ cd deps; \ wget ${GMP_URL_HTTP} || exit 1; \ tar -xjf gmp-${GMP_VERSION}.tar.bz2 || exit 1; \ @@ -601,14 +612,14 @@ $(GMP_LIB): $(GMP_TIMESTAMP) REFRESH=1; \ fi; \ if [ $$REFRESH -ne 0 ] ; then \ - export PATH=$$PATH:${ANDROID_NDK}; \ + mkdir -p ${GMP_DIR}; \ echo "changed timestamp for gmp detected building..."; \ cd deps/gmp; \ export CROSS_PREFIX=${CROSS_PREFIX}; \ export TOOLCHAIN=/tmp/ndk-${TARGET_HOST}-gmp; \ ${ANDROID_NDK}/build/tools/make-standalone-toolchain.sh \ - --toolchain=${TARGET_TOOLCHAIN}-${COMPILER_VERSION} \ - --platform=${APP_PLATFORM} --install-dir=$${TOOLCHAIN}; \ + --toolchain=${TARGET_TOOLCHAIN}-${COMPILER_VERSION} \ + --platform=${APP_PLATFORM} --install-dir=$${TOOLCHAIN}; \ export PATH="$${TOOLCHAIN}/bin:$${PATH}"; \ export CC=${CROSS_PREFIX}gcc; \ export CXX=${CROSS_PREFIX}g++; \ @@ -629,8 +640,8 @@ clean_gmp: sqlite3_download: deps/sqlite/sqlite3.c deps/sqlite/sqlite3.c : - mkdir -p ${ROOT}/deps; \ - cd ${ROOT}/deps; \ + mkdir -p ${ANDR_ROOT}/deps; \ + cd ${ANDR_ROOT}/deps; \ rm -R sqlite; \ wget ${SQLITE3_URL}; \ unzip sqlite-amalgamation-$(SQLITE3_VERSION).zip || exit 1; \ @@ -642,13 +653,13 @@ clean_sqlite3: $(RM) -R sqlite $(ASSETS_TIMESTAMP) : $(IRRLICHT_LIB) - @mkdir -p ${ROOT}/deps; \ + @mkdir -p ${ANDR_ROOT}/deps; \ for DIRNAME in {builtin,client,doc,fonts,games,mods,po,textures}; do \ - LAST_MODIF=$$(find ${ROOT}/../../${DIRNAME} -type f -printf '%T@ %p\n' | sort -n | tail -1 | cut -f2- -d" "); \ - if [ $$(basename $$LAST_MODIF) != "timestamp" ]; then \ - touch ${ROOT}/../../${DIRNAME}/timestamp; \ - touch ${ASSETS_TIMESTAMP}; \ - echo ${DIRNAME} changed $$LAST_MODIF; \ + LAST_MODIF=$$(find ${PROJ_ROOT}/${DIRNAME} -type f -printf '%T@ %p\n' | sort -n | tail -1 | cut -f2- -d" "); \ + if [ $$(basename $$LAST_MODIF) != "timestamp" ]; then \ + touch ${PROJ_ROOT}/${DIRNAME}/timestamp; \ + touch ${ASSETS_TIMESTAMP}; \ + echo ${DIRNAME} changed $$LAST_MODIF; \ fi; \ done; \ LAST_MODIF=$$(find ${IRRLICHT_DIR}/media -type f -printf '%T@ %p\n' | sort -n | tail -1 | cut -f2- -d" "); \ @@ -656,11 +667,11 @@ $(ASSETS_TIMESTAMP) : $(IRRLICHT_LIB) touch ${IRRLICHT_DIR}/media/timestamp; \ touch ${ASSETS_TIMESTAMP}; \ fi; \ - if [ ${ROOT}/../../multicraft.conf.example -nt ${ASSETS_TIMESTAMP} ] ; then \ + if [ ${PROJ_ROOT}/multicraft.conf.example -nt ${ASSETS_TIMESTAMP} ] ; then \ echo "conf changed"; \ touch ${ASSETS_TIMESTAMP}; \ fi; \ - if [ ${ROOT}/../../README.md -nt ${ASSETS_TIMESTAMP} ] ; then \ + if [ ${PROJ_ROOT}/README.txt -nt ${ASSETS_TIMESTAMP} ] ; then \ touch ${ASSETS_TIMESTAMP}; \ fi; \ if [ ! -e $(ASSETS_TIMESTAMP) ] ; then \ @@ -676,8 +687,8 @@ $(LUAJIT_TIMESTAMP) : luajit_download luajit_download : @if [ ! -d ${LUAJIT_DIR} ] ; then \ echo "luajit sources missing, downloading..."; \ - mkdir -p ${ROOT}/deps; \ - cd ${ROOT}/deps; \ + mkdir -p ${ANDR_ROOT}/deps; \ + cd ${ANDR_ROOT}/deps; \ git clone --branch ${LUAJIT_GIT_BRANCH} ${LUAJIT_URL_GIT} luajit || exit 1; \ fi @@ -716,25 +727,19 @@ clean_luajit: $(RM) -R deps/luajit assets : $(ASSETS_TIMESTAMP) - @REFRESH=0; \ - if [ ! -e ${ASSETS_TIMESTAMP} ] ; then \ - REFRESH=1; \ - fi; \ - if [ ${ASSETS_TIMESTAMP} -nt ${ASSETS_TIMESTAMP} ] ; then \ - REFRESH=1; \ + if [ ! -d ${APP_ROOT}/assets ] ; then \ + REFRESH=1; \ fi; \ if [ $$REFRESH -ne 0 ] ; then \ echo "assets changed, refreshing..."; \ $(MAKE) clean_assets; \ - mkdir -p ${ROOT}/assets/MultiCraft; \ - cp ${ROOT}/../../multicraft.conf.example ${ROOT}/assets/MultiCraft; \ - cp ${ROOT}/../../README.md ${ROOT}/assets/MultiCraft; \ - cp -r ${ROOT}/../../builtin ${ROOT}/assets/MultiCraft; \ - mkdir ${ROOT}/assets/MultiCraft/fonts; \ - cp -r ${ROOT}/../../fonts/basis33.ttf ${ROOT}/assets/MultiCraft/fonts/; \ - cp -r ${ROOT}/../../games ${ROOT}/assets/MultiCraft; \ - cp -r ${ROOT}/../../textures ${ROOT}/assets/MultiCraft; \ - cd ${ROOT}/assets || exit 1; \ + mkdir -p ${PROJ_ROOT}/assets/MultiCraft; \ + cp -r ${PROJ_ROOT}/builtin ${APP_ROOT}/assets/MultiCraft; \ + 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; \ + cp -r ${PROJ_ROOT}/textures ${APP_ROOT}/assets/MultiCraft; \ + cd ${APP_ROOT}/assets || exit 1; \ find . -name "timestamp" -exec rm {} \; ; \ find . -name "*.blend" -exec rm {} \; ; \ find . -name "*~" -exec rm {} \; ; \ @@ -742,13 +747,12 @@ assets : $(ASSETS_TIMESTAMP) find . -type d -path "*.svn" -exec rm -rf {} \; ; \ find . -type f -path "*.gitignore" -exec rm -rf {} \; ; \ ls -R | grep ":$$" | sed -e 's/:$$//' -e 's/\.//' -e 's/^\///' > "index.txt"; \ - find MultiCraft >"filelist.txt"; \ + find -L MultiCraft > filelist.txt; \ echo "Creating Files.zip"; \ zip -r Files.zip MultiCraft; \ - touch ${ASSETS_TIMESTAMP}; \ - touch ${ASSETS_TIMESTAMP_INT}; \ - else \ - echo "nothing to be done for assets"; \ + cp ${ANDR_ROOT}/${ASSETS_TIMESTAMP} ${ANDR_ROOT}/${ASSETS_TIMESTAMP}.old; \ + else \ + echo "nothing to be done for assets"; \ fi clean_assets : @@ -756,53 +760,50 @@ clean_assets : apk: $(PATHCFGFILE) assets $(ICONV_LIB) $(IRRLICHT_LIB) $(CURL_LIB) $(GMP_LIB) \ $(LUAJIT_LIB) \ - $(OPENAL_LIB) $(VORBIS_LIB) prep_srcdir $(ROOT)/jni/src/android_version.h \ - $(ROOT)/jni/src/android_version_githash.h sqlite3_download - @export NDEBUG=$$NDEBUG; $(MAKE) manifest; \ - export PATH=$$PATH:${SDKFOLDER}/platform-tools:${ANDROID_NDK}; \ - export ANDROID_HOME=${SDKFOLDER}; \ - mkdir -p ${ROOT}/src; \ - ndk-build NDEBUG=${NDEBUG} \ - GPROF=${GPROF} APP_ABI=${TARGET_ABI} \ - APP_PLATFORM=${APP_PLATFORM} \ - TARGET_LIBDIR=${TARGET_LIBDIR} && \ + $(OPENAL_LIB) $(VORBIS_LIB) prep_srcdir $(ANDR_ROOT)/jni/src/android_version.h \ + $(ANDR_ROOT)/jni/src/android_version_githash.h sqlite3_download + @${ANDROID_NDK}/ndk-build NDK_MODULE_PATH=${NDK_MODULE_PATH} \ + GPROF=${GPROF} APP_ABI=${TARGET_ABI} \ + APP_PLATFORM=${APP_PLATFORM} \ + TARGET_LIBDIR=${TARGET_LIBDIR} && \ + if [ ! -e ${APP_ROOT}/jniLibs ]; then \ + ln -s ${ANDR_ROOT}/libs ${APP_ROOT}/jniLibs || exit 1; \ + fi; \ + export VERSION_STR="${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH}" && \ + export BUILD_TYPE_C=$$(echo "$${BUILD_TYPE}" | sed 's/./\U&/') && \ + gradle assemble$$BUILD_TYPE_C && \ echo " Success! =)"; \ ant $$BUILD_TYPE && \ - echo "APK: bin/MultiCraft-$$BUILD_TYPE.apk" \ + echo "APK stored at: build/outputs/apk/MultiCraft-$$BUILD_TYPE.apk" && \ + echo "You can install it with \`make install_$$BUILD_TYPE\`" + +# These Intentionally doesn't depend on their respective build steps, +# because it takes a while to verify that everything's up-to-date. +install_debug: + ${ANDROID_SDK}/platform-tools/adb install -r build/outputs/apk/Minetest-debug.apk + +install_release: + ${ANDROID_SDK}/platform-tools/adb install -r build/outputs/apk/Minetest-release.apk prep_srcdir : - @if [ ! -e ${ROOT}/jni/src ]; then \ - ln -s ${ROOT}/../../src ${ROOT}/jni/src; \ + @if [ ! -e ${ANDR_ROOT}/jni/src ]; then \ + ln -s ${PROJ_ROOT}/src ${ANDR_ROOT}/jni/src; \ fi -clean_apk : manifest - @export PATH=$$PATH:${SDKFOLDER}platform-tools:${ANDROID_NDK}; \ - export ANDROID_HOME=${SDKFOLDER}; \ - ant clean - -install_debug : - @export PATH=$$PATH:${SDKFOLDER}platform-tools:${ANDROID_NDK}; \ - adb install -r ${ROOT}/bin/MultiCraft-debug.apk - -install : - @export PATH=$$PATH:${SDKFOLDER}platform-tools:${ANDROID_NDK}; \ - adb install -r ${ROOT}/bin/MultiCraft-release.apk - -envpaths : - @echo "export PATH=$$PATH:${SDKFOLDER}platform-tools:${ANDROID_NDK}" > and_env;\ - echo "export ANDROID_HOME=${SDKFOLDER}" >> and_env; +clean_apk : + gradle clean clean_all : - $(MAKE) clean_apk; \ - $(MAKE) clean_assets clean_manifest; \ + @$(MAKE) clean_apk; \ + $(MAKE) clean_assets; \ sleep 1; \ $(RM) -r gen libs obj deps bin Debug and_env jni/src clean_src : $(RM) -r gen libs obj bin Debug and_env jni/src -$(ROOT)/jni/src/android_version_githash.h : prep_srcdir - @export VERSION_FILE=${ROOT}/jni/src/android_version_githash.h; \ +$(ANDR_ROOT)/jni/src/android_version_githash.h : prep_srcdir + @export VERSION_FILE=${ANDR_ROOT}/jni/src/android_version_githash.h; \ export VERSION_FILE_NEW=$${VERSION_FILE}.new; \ { \ echo "#ifndef ANDROID_MT_VERSION_GITHASH_H"; \ @@ -820,8 +821,8 @@ $(ROOT)/jni/src/android_version_githash.h : prep_srcdir fi -$(ROOT)/jni/src/android_version.h : prep_srcdir - @export VERSION_FILE=${ROOT}/jni/src/android_version.h; \ +$(ANDR_ROOT)/jni/src/android_version.h : prep_srcdir + @export VERSION_FILE=${ANDR_ROOT}/jni/src/android_version.h; \ export VERSION_FILE_NEW=$${VERSION_FILE}.new; \ { \ echo "#ifndef ANDROID_MT_VERSION_H"; \ @@ -840,22 +841,5 @@ $(ROOT)/jni/src/android_version.h : prep_srcdir rm "$${VERSION_FILE_NEW}"; \ fi -manifest : - @BASE_VERSION="${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH}"; \ - if [ "${NDEBUG}x" != "x" ] ; then \ - DBG=''; \ - DBG_FLAG="android:debuggable=\"false\""; \ - else \ - DBG=""; \ - DBG_FLAG="android:debuggable=\"true\""; \ - fi; \ - cat ${ROOT}/AndroidManifest.xml.template | \ - sed "s/###ANDROID_VERSION###/${ANDROID_VERSION_CODE}/g" | \ - sed "s/###BASE_VERSION###/$$BASE_VERSION/g" | \ - sed -e "s@###DEBUG_BUILD###@$$DBG@g" | \ - sed -e "s@###DEBUG_FLAG###@$$DBG_FLAG@g" >${ROOT}/AndroidManifest.xml - -clean_manifest : - rm -rf ${ROOT}/AndroidManifest.xml - clean : clean_apk clean_assets + diff --git a/build/android/build.gradle b/build/android/build.gradle new file mode 100644 index 00000000..3ce11bec --- /dev/null +++ b/build/android/build.gradle @@ -0,0 +1,49 @@ +buildscript { + repositories { + mavenCentral() + } + dependencies { + classpath "com.android.tools.build:gradle:1.5.0" + } +} + +apply plugin: "com.android.application" + +android { + compileSdkVersion 23 + buildToolsVersion "23.0.3" + + defaultConfig { + versionCode 13 + versionName "${System.env.VERSION_STR}.${versionCode}" + minSdkVersion 9 + targetSdkVersion 9 + applicationId "net.minetest.minetest" + manifestPlaceholders = [ package: "net.minetest.minetest", project: project.name ] + } + + lintOptions { + disable "OldTargetApi", "GoogleAppIndexingWarning" + } + + Properties props = new Properties() + props.load(new FileInputStream(file("local.properties"))) + + if (props.getProperty("keystore") != null) { + signingConfigs { + release { + storeFile file(props["keystore"]) + storePassword props["keystore.password"] + keyAlias props["key"] + keyPassword props["key.password"] + } + } + + buildTypes { + release { + signingConfig signingConfigs.release + } + } + } +} + diff --git a/build/android/build.xml b/build/android/build.xml deleted file mode 100644 index bd9404a7..00000000 --- a/build/android/build.xml +++ /dev/null @@ -1,16 +0,0 @@ - - - - - - - - - - - - - diff --git a/build/android/jni/Android.mk b/build/android/jni/Android.mk index e72fb42b..89ef5769 100644 --- a/build/android/jni/Android.mk +++ b/build/android/jni/Android.mk @@ -50,12 +50,12 @@ GPROF_DEF=-DGPROF endif LOCAL_CFLAGS := -D_IRR_ANDROID_PLATFORM_ \ - -DHAVE_TOUCHSCREENGUI \ - -DUSE_CURL=1 \ - -DUSE_SOUND=1 \ - -DUSE_FREETYPE=1 \ - $(GPROF_DEF) \ - -pipe -fstrict-aliasing + -DHAVE_TOUCHSCREENGUI \ + -DUSE_CURL=1 \ + -DUSE_SOUND=1 \ + -DUSE_FREETYPE=1 \ + $(GPROF_DEF) \ + -pipe -fstrict-aliasing ifndef NDEBUG LOCAL_CFLAGS += -g -D_DEBUG -O0 -fno-omit-frame-pointer @@ -80,7 +80,7 @@ LOCAL_LDFLAGS = -Wl,--no-warn-mismatch,--gc-sections LOCAL_DISABLE_FATAL_LINKER_WARNINGS := true endif -LOCAL_C_INCLUDES := \ +LOCAL_C_INCLUDES := \ jni/src \ jni/src/script \ jni/src/json \ @@ -95,7 +95,7 @@ LOCAL_C_INCLUDES := \ deps/sqlite/ \ deps/luajit/src -LOCAL_SRC_FILES := \ +LOCAL_SRC_FILES := \ jni/src/ban.cpp \ jni/src/camera.cpp \ jni/src/cavegen.cpp \ @@ -223,7 +223,7 @@ LOCAL_SRC_FILES := \ # jni/src/content_cso.cpp # Network -LOCAL_SRC_FILES += \ +LOCAL_SRC_FILES += \ jni/src/network/connection.cpp \ jni/src/network/networkpacket.cpp \ jni/src/network/clientopcodes.cpp \ @@ -231,8 +231,8 @@ LOCAL_SRC_FILES += \ jni/src/network/serveropcodes.cpp \ jni/src/network/serverpackethandler.cpp -# Lua API -LOCAL_SRC_FILES += \ +# lua api +LOCAL_SRC_FILES += \ jni/src/script/common/c_content.cpp \ jni/src/script/common/c_converter.cpp \ jni/src/script/common/c_internal.cpp \ @@ -274,6 +274,40 @@ LOCAL_SRC_FILES += \ # Freetype2 LOCAL_SRC_FILES += jni/src/cguittfont/xCGUITTFont.cpp +# Lua +LOCAL_SRC_FILES += \ + jni/src/lua/src/lapi.c \ + jni/src/lua/src/lauxlib.c \ + jni/src/lua/src/lbaselib.c \ + jni/src/lua/src/lcode.c \ + jni/src/lua/src/ldblib.c \ + jni/src/lua/src/ldebug.c \ + jni/src/lua/src/ldo.c \ + jni/src/lua/src/ldump.c \ + jni/src/lua/src/lfunc.c \ + jni/src/lua/src/lgc.c \ + jni/src/lua/src/linit.c \ + jni/src/lua/src/liolib.c \ + jni/src/lua/src/llex.c \ + jni/src/lua/src/lmathlib.c \ + jni/src/lua/src/lmem.c \ + jni/src/lua/src/loadlib.c \ + jni/src/lua/src/lobject.c \ + jni/src/lua/src/lopcodes.c \ + jni/src/lua/src/loslib.c \ + jni/src/lua/src/lparser.c \ + jni/src/lua/src/lstate.c \ + jni/src/lua/src/lstring.c \ + jni/src/lua/src/lstrlib.c \ + jni/src/lua/src/ltable.c \ + jni/src/lua/src/ltablib.c \ + jni/src/lua/src/ltm.c \ + jni/src/lua/src/lundump.c \ + jni/src/lua/src/lvm.c \ + jni/src/lua/src/lzio.c \ + jni/src/lua/src/print.c +>>>>>>> upstream1/master + # SQLite3 LOCAL_SRC_FILES += deps/sqlite/sqlite3.c @@ -299,3 +333,4 @@ ifdef GPROF $(call import-module,android-ndk-profiler) endif $(call import-module,android/native_app_glue) + diff --git a/build/android/jni/Application.mk b/build/android/jni/Application.mk index 451681a4..43f99880 100644 --- a/build/android/jni/Application.mk +++ b/build/android/jni/Application.mk @@ -2,4 +2,4 @@ APP_MODULES := multicraft APP_STL := gnustl_static #APP_STL := c++_shared #LIBCXX_FORCE_REBUILD := true -APP_CPPFLAGS += -fexceptions -frtti \ No newline at end of file +APP_CPPFLAGS += -fexceptions -frtti diff --git a/build/android/lint.xml b/build/android/lint.xml deleted file mode 100644 index 7edd00cc..00000000 --- a/build/android/lint.xml +++ /dev/null @@ -1,4 +0,0 @@ - - - - \ No newline at end of file diff --git a/build/android/irrlicht-back_button.patch b/build/android/patches/irrlicht-back_button.patch similarity index 97% rename from build/android/irrlicht-back_button.patch rename to build/android/patches/irrlicht-back_button.patch index 227749ba..20faac48 100644 --- a/build/android/irrlicht-back_button.patch +++ b/build/android/patches/irrlicht-back_button.patch @@ -1,19 +1,19 @@ --- irrlicht/source/Irrlicht/Android/CIrrDeviceAndroid.cpp 2014-06-03 20:56:21.289559503 +0200 +++ irrlicht/source/Irrlicht/Android/CIrrDeviceAndroid.cpp.orig 2014-06-03 20:57:39.281556749 +0200 @@ -423,6 +423,7 @@ - } - - device->postEventFromUser(event); -+ status = 1; - } - break; - default: + } + + device->postEventFromUser(event); ++ status = 1; + } + break; + default: @@ -479,7 +480,7 @@ - KeyMap[1] = KEY_LBUTTON; // AKEYCODE_SOFT_LEFT - KeyMap[2] = KEY_RBUTTON; // AKEYCODE_SOFT_RIGHT - KeyMap[3] = KEY_HOME; // AKEYCODE_HOME -- KeyMap[4] = KEY_BACK; // AKEYCODE_BACK -+ KeyMap[4] = KEY_CANCEL; // AKEYCODE_BACK - KeyMap[5] = KEY_UNKNOWN; // AKEYCODE_CALL - KeyMap[6] = KEY_UNKNOWN; // AKEYCODE_ENDCALL - KeyMap[7] = KEY_KEY_0; // AKEYCODE_0 + KeyMap[1] = KEY_LBUTTON; // AKEYCODE_SOFT_LEFT + KeyMap[2] = KEY_RBUTTON; // AKEYCODE_SOFT_RIGHT + KeyMap[3] = KEY_HOME; // AKEYCODE_HOME +- KeyMap[4] = KEY_BACK; // AKEYCODE_BACK ++ KeyMap[4] = KEY_CANCEL; // AKEYCODE_BACK + KeyMap[5] = KEY_UNKNOWN; // AKEYCODE_CALL + KeyMap[6] = KEY_UNKNOWN; // AKEYCODE_ENDCALL + KeyMap[7] = KEY_KEY_0; // AKEYCODE_0 diff --git a/build/android/irrlicht-optimization.patch b/build/android/patches/irrlicht-optimization.patch similarity index 100% rename from build/android/irrlicht-optimization.patch rename to build/android/patches/irrlicht-optimization.patch diff --git a/build/android/irrlicht-texturehack.patch b/build/android/patches/irrlicht-texturehack.patch similarity index 97% rename from build/android/irrlicht-texturehack.patch rename to build/android/patches/irrlicht-texturehack.patch index a458ede7..30244191 100644 --- a/build/android/irrlicht-texturehack.patch +++ b/build/android/patches/irrlicht-texturehack.patch @@ -1,240 +1,240 @@ --- irrlicht/source/Irrlicht/COGLESTexture.cpp.orig 2014-06-22 17:01:13.266568869 +0200 +++ irrlicht/source/Irrlicht/COGLESTexture.cpp 2014-06-22 17:03:59.298572810 +0200 @@ -366,112 +366,140 @@ - void(*convert)(const void*, s32, void*) = 0; - getFormatParameters(ColorFormat, InternalFormat, filtering, PixelFormat, PixelType, convert); - -- // make sure we don't change the internal format of existing images -- if (!newTexture) -- InternalFormat = oldInternalFormat; -- -- Driver->setActiveTexture(0, this); -- -- if (Driver->testGLError()) -- os::Printer::log("Could not bind Texture", ELL_ERROR); -- -- // mipmap handling for main texture -- if (!level && newTexture) -- { -- // auto generate if possible and no mipmap data is given -- if (!IsCompressed && HasMipMaps && !mipmapData && Driver->queryFeature(EVDF_MIP_MAP_AUTO_UPDATE)) -- { -- if (Driver->getTextureCreationFlag(ETCF_OPTIMIZED_FOR_SPEED)) -- glHint(GL_GENERATE_MIPMAP_HINT, GL_FASTEST); -- else if (Driver->getTextureCreationFlag(ETCF_OPTIMIZED_FOR_QUALITY)) -- glHint(GL_GENERATE_MIPMAP_HINT, GL_NICEST); -- else -- glHint(GL_GENERATE_MIPMAP_HINT, GL_DONT_CARE); -+ bool retry = false; -+ -+ do { -+ if (retry) { -+ InternalFormat = GL_RGBA; -+ PixelFormat = GL_RGBA; -+ convert = CColorConverter::convert_A8R8G8B8toA8B8G8R8; -+ } -+ // make sure we don't change the internal format of existing images -+ if (!newTexture) -+ InternalFormat = oldInternalFormat; - -- glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, GL_TRUE); -- AutomaticMipmapUpdate=true; -- } -+ Driver->setActiveTexture(0, this); - -- // enable bilinear filter without mipmaps -- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, filtering); -- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, filtering); -- } -+ if (Driver->testGLError()) -+ os::Printer::log("Could not bind Texture", ELL_ERROR); - -- // now get image data and upload to GPU -+ // mipmap handling for main texture -+ if (!level && newTexture) -+ { -+ // auto generate if possible and no mipmap data is given -+ if (!IsCompressed && HasMipMaps && !mipmapData && Driver->queryFeature(EVDF_MIP_MAP_AUTO_UPDATE)) -+ { -+ if (Driver->getTextureCreationFlag(ETCF_OPTIMIZED_FOR_SPEED)) -+ glHint(GL_GENERATE_MIPMAP_HINT, GL_FASTEST); -+ else if (Driver->getTextureCreationFlag(ETCF_OPTIMIZED_FOR_QUALITY)) -+ glHint(GL_GENERATE_MIPMAP_HINT, GL_NICEST); -+ else -+ glHint(GL_GENERATE_MIPMAP_HINT, GL_DONT_CARE); -+ -+ glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, GL_TRUE); -+ AutomaticMipmapUpdate=true; -+ } -+ -+ // enable bilinear filter without mipmaps -+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, filtering); -+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, filtering); -+ } - -- u32 compressedImageSize = IImage::getCompressedImageSize(ColorFormat, image->getDimension().Width, image->getDimension().Height); -+ // now get image data and upload to GPU - -- void* source = image->lock(); -+ u32 compressedImageSize = IImage::getCompressedImageSize(ColorFormat, image->getDimension().Width, image->getDimension().Height); - -- IImage* tmpImage = 0; -+ void* source = image->lock(); - -- if (convert) -- { -- tmpImage = new CImage(image->getColorFormat(), image->getDimension()); -- void* dest = tmpImage->lock(); -- convert(source, image->getDimension().getArea(), dest); -- image->unlock(); -- source = dest; -- } -+ IImage* tmpImage = 0; - -- if (newTexture) -- { -- if (IsCompressed) -+ if (convert) - { -- glCompressedTexImage2D(GL_TEXTURE_2D, 0, InternalFormat, image->getDimension().Width, -- image->getDimension().Height, 0, compressedImageSize, source); -+ tmpImage = new CImage(image->getColorFormat(), image->getDimension()); -+ void* dest = tmpImage->lock(); -+ convert(source, image->getDimension().getArea(), dest); -+ image->unlock(); -+ source = dest; - } -- else -- glTexImage2D(GL_TEXTURE_2D, level, InternalFormat, image->getDimension().Width, -- image->getDimension().Height, 0, PixelFormat, PixelType, source); -- } -- else -- { -- if (IsCompressed) -+ -+ if (newTexture) - { -- glCompressedTexSubImage2D(GL_TEXTURE_2D, level, 0, 0, image->getDimension().Width, -- image->getDimension().Height, PixelFormat, compressedImageSize, source); -+ if (IsCompressed) -+ { -+ glCompressedTexImage2D(GL_TEXTURE_2D, 0, InternalFormat, image->getDimension().Width, -+ image->getDimension().Height, 0, compressedImageSize, source); -+ } -+ else -+ glTexImage2D(GL_TEXTURE_2D, level, InternalFormat, image->getDimension().Width, -+ image->getDimension().Height, 0, PixelFormat, PixelType, source); - } - else -- glTexSubImage2D(GL_TEXTURE_2D, level, 0, 0, image->getDimension().Width, -- image->getDimension().Height, PixelFormat, PixelType, source); -- } -- -- if (convert) -- { -- tmpImage->unlock(); -- tmpImage->drop(); -- } -- else -- image->unlock(); -- -- if (!level && newTexture) -- { -- if (IsCompressed && !mipmapData) - { -- if (image->hasMipMaps()) -- mipmapData = static_cast(image->lock())+compressedImageSize; -+ if (IsCompressed) -+ { -+ glCompressedTexSubImage2D(GL_TEXTURE_2D, level, 0, 0, image->getDimension().Width, -+ image->getDimension().Height, PixelFormat, compressedImageSize, source); -+ } - else -- HasMipMaps = false; -+ glTexSubImage2D(GL_TEXTURE_2D, level, 0, 0, image->getDimension().Width, -+ image->getDimension().Height, PixelFormat, PixelType, source); - } - -- regenerateMipMapLevels(mipmapData); -- -- if (HasMipMaps) // might have changed in regenerateMipMapLevels -+ if (convert) - { -- // enable bilinear mipmap filter -- GLint filteringMipMaps = GL_LINEAR_MIPMAP_NEAREST; -- -- if (filtering != GL_LINEAR) -- filteringMipMaps = GL_NEAREST_MIPMAP_NEAREST; -+ tmpImage->unlock(); -+ tmpImage->drop(); -+ } -+ else -+ image->unlock(); -+ -+ if (glGetError() != GL_NO_ERROR) { -+ static bool warned = false; -+ if ((!retry) && (ColorFormat == ECF_A8R8G8B8)) { -+ -+ if (!warned) { -+ os::Printer::log("Your driver claims to support GL_BGRA but fails on trying to upload a texture, converting to GL_RGBA and trying again", ELL_ERROR); -+ warned = true; -+ } -+ } -+ else if (retry) { -+ os::Printer::log("Neither uploading texture as GL_BGRA nor, converted one using GL_RGBA succeeded", ELL_ERROR); -+ } -+ retry = !retry; -+ continue; -+ } else { -+ retry = false; -+ } - -- glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, filteringMipMaps); -- glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, filtering); -+ if (!level && newTexture) -+ { -+ if (IsCompressed && !mipmapData) -+ { -+ if (image->hasMipMaps()) -+ mipmapData = static_cast(image->lock())+compressedImageSize; -+ else -+ HasMipMaps = false; -+ } -+ -+ regenerateMipMapLevels(mipmapData); -+ -+ if (HasMipMaps) // might have changed in regenerateMipMapLevels -+ { -+ // enable bilinear mipmap filter -+ GLint filteringMipMaps = GL_LINEAR_MIPMAP_NEAREST; -+ -+ if (filtering != GL_LINEAR) -+ filteringMipMaps = GL_NEAREST_MIPMAP_NEAREST; -+ -+ glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, filteringMipMaps); -+ glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, filtering); -+ } - } -- } - -- if (Driver->testGLError()) -- os::Printer::log("Could not glTexImage2D", ELL_ERROR); -+ if (Driver->testGLError()) -+ os::Printer::log("Could not glTexImage2D", ELL_ERROR); -+ } -+ while(retry); - } - - + void(*convert)(const void*, s32, void*) = 0; + getFormatParameters(ColorFormat, InternalFormat, filtering, PixelFormat, PixelType, convert); + +- // make sure we don't change the internal format of existing images +- if (!newTexture) +- InternalFormat = oldInternalFormat; +- +- Driver->setActiveTexture(0, this); +- +- if (Driver->testGLError()) +- os::Printer::log("Could not bind Texture", ELL_ERROR); +- +- // mipmap handling for main texture +- if (!level && newTexture) +- { +- // auto generate if possible and no mipmap data is given +- if (!IsCompressed && HasMipMaps && !mipmapData && Driver->queryFeature(EVDF_MIP_MAP_AUTO_UPDATE)) +- { +- if (Driver->getTextureCreationFlag(ETCF_OPTIMIZED_FOR_SPEED)) +- glHint(GL_GENERATE_MIPMAP_HINT, GL_FASTEST); +- else if (Driver->getTextureCreationFlag(ETCF_OPTIMIZED_FOR_QUALITY)) +- glHint(GL_GENERATE_MIPMAP_HINT, GL_NICEST); +- else +- glHint(GL_GENERATE_MIPMAP_HINT, GL_DONT_CARE); ++ bool retry = false; ++ ++ do { ++ if (retry) { ++ InternalFormat = GL_RGBA; ++ PixelFormat = GL_RGBA; ++ convert = CColorConverter::convert_A8R8G8B8toA8B8G8R8; ++ } ++ // make sure we don't change the internal format of existing images ++ if (!newTexture) ++ InternalFormat = oldInternalFormat; + +- glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, GL_TRUE); +- AutomaticMipmapUpdate=true; +- } ++ Driver->setActiveTexture(0, this); + +- // enable bilinear filter without mipmaps +- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, filtering); +- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, filtering); +- } ++ if (Driver->testGLError()) ++ os::Printer::log("Could not bind Texture", ELL_ERROR); + +- // now get image data and upload to GPU ++ // mipmap handling for main texture ++ if (!level && newTexture) ++ { ++ // auto generate if possible and no mipmap data is given ++ if (!IsCompressed && HasMipMaps && !mipmapData && Driver->queryFeature(EVDF_MIP_MAP_AUTO_UPDATE)) ++ { ++ if (Driver->getTextureCreationFlag(ETCF_OPTIMIZED_FOR_SPEED)) ++ glHint(GL_GENERATE_MIPMAP_HINT, GL_FASTEST); ++ else if (Driver->getTextureCreationFlag(ETCF_OPTIMIZED_FOR_QUALITY)) ++ glHint(GL_GENERATE_MIPMAP_HINT, GL_NICEST); ++ else ++ glHint(GL_GENERATE_MIPMAP_HINT, GL_DONT_CARE); ++ ++ glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, GL_TRUE); ++ AutomaticMipmapUpdate=true; ++ } ++ ++ // enable bilinear filter without mipmaps ++ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, filtering); ++ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, filtering); ++ } + +- u32 compressedImageSize = IImage::getCompressedImageSize(ColorFormat, image->getDimension().Width, image->getDimension().Height); ++ // now get image data and upload to GPU + +- void* source = image->lock(); ++ u32 compressedImageSize = IImage::getCompressedImageSize(ColorFormat, image->getDimension().Width, image->getDimension().Height); + +- IImage* tmpImage = 0; ++ void* source = image->lock(); + +- if (convert) +- { +- tmpImage = new CImage(image->getColorFormat(), image->getDimension()); +- void* dest = tmpImage->lock(); +- convert(source, image->getDimension().getArea(), dest); +- image->unlock(); +- source = dest; +- } ++ IImage* tmpImage = 0; + +- if (newTexture) +- { +- if (IsCompressed) ++ if (convert) + { +- glCompressedTexImage2D(GL_TEXTURE_2D, 0, InternalFormat, image->getDimension().Width, +- image->getDimension().Height, 0, compressedImageSize, source); ++ tmpImage = new CImage(image->getColorFormat(), image->getDimension()); ++ void* dest = tmpImage->lock(); ++ convert(source, image->getDimension().getArea(), dest); ++ image->unlock(); ++ source = dest; + } +- else +- glTexImage2D(GL_TEXTURE_2D, level, InternalFormat, image->getDimension().Width, +- image->getDimension().Height, 0, PixelFormat, PixelType, source); +- } +- else +- { +- if (IsCompressed) ++ ++ if (newTexture) + { +- glCompressedTexSubImage2D(GL_TEXTURE_2D, level, 0, 0, image->getDimension().Width, +- image->getDimension().Height, PixelFormat, compressedImageSize, source); ++ if (IsCompressed) ++ { ++ glCompressedTexImage2D(GL_TEXTURE_2D, 0, InternalFormat, image->getDimension().Width, ++ image->getDimension().Height, 0, compressedImageSize, source); ++ } ++ else ++ glTexImage2D(GL_TEXTURE_2D, level, InternalFormat, image->getDimension().Width, ++ image->getDimension().Height, 0, PixelFormat, PixelType, source); + } + else +- glTexSubImage2D(GL_TEXTURE_2D, level, 0, 0, image->getDimension().Width, +- image->getDimension().Height, PixelFormat, PixelType, source); +- } +- +- if (convert) +- { +- tmpImage->unlock(); +- tmpImage->drop(); +- } +- else +- image->unlock(); +- +- if (!level && newTexture) +- { +- if (IsCompressed && !mipmapData) + { +- if (image->hasMipMaps()) +- mipmapData = static_cast(image->lock())+compressedImageSize; ++ if (IsCompressed) ++ { ++ glCompressedTexSubImage2D(GL_TEXTURE_2D, level, 0, 0, image->getDimension().Width, ++ image->getDimension().Height, PixelFormat, compressedImageSize, source); ++ } + else +- HasMipMaps = false; ++ glTexSubImage2D(GL_TEXTURE_2D, level, 0, 0, image->getDimension().Width, ++ image->getDimension().Height, PixelFormat, PixelType, source); + } + +- regenerateMipMapLevels(mipmapData); +- +- if (HasMipMaps) // might have changed in regenerateMipMapLevels ++ if (convert) + { +- // enable bilinear mipmap filter +- GLint filteringMipMaps = GL_LINEAR_MIPMAP_NEAREST; +- +- if (filtering != GL_LINEAR) +- filteringMipMaps = GL_NEAREST_MIPMAP_NEAREST; ++ tmpImage->unlock(); ++ tmpImage->drop(); ++ } ++ else ++ image->unlock(); ++ ++ if (glGetError() != GL_NO_ERROR) { ++ static bool warned = false; ++ if ((!retry) && (ColorFormat == ECF_A8R8G8B8)) { ++ ++ if (!warned) { ++ os::Printer::log("Your driver claims to support GL_BGRA but fails on trying to upload a texture, converting to GL_RGBA and trying again", ELL_ERROR); ++ warned = true; ++ } ++ } ++ else if (retry) { ++ os::Printer::log("Neither uploading texture as GL_BGRA nor, converted one using GL_RGBA succeeded", ELL_ERROR); ++ } ++ retry = !retry; ++ continue; ++ } else { ++ retry = false; ++ } + +- glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, filteringMipMaps); +- glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, filtering); ++ if (!level && newTexture) ++ { ++ if (IsCompressed && !mipmapData) ++ { ++ if (image->hasMipMaps()) ++ mipmapData = static_cast(image->lock())+compressedImageSize; ++ else ++ HasMipMaps = false; ++ } ++ ++ regenerateMipMapLevels(mipmapData); ++ ++ if (HasMipMaps) // might have changed in regenerateMipMapLevels ++ { ++ // enable bilinear mipmap filter ++ GLint filteringMipMaps = GL_LINEAR_MIPMAP_NEAREST; ++ ++ if (filtering != GL_LINEAR) ++ filteringMipMaps = GL_NEAREST_MIPMAP_NEAREST; ++ ++ glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, filteringMipMaps); ++ glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, filtering); ++ } + } +- } + +- if (Driver->testGLError()) +- os::Printer::log("Could not glTexImage2D", ELL_ERROR); ++ if (Driver->testGLError()) ++ os::Printer::log("Could not glTexImage2D", ELL_ERROR); ++ } ++ while(retry); + } + + --- irrlicht/source/Irrlicht/COGLESTexture.cpp.orig 2014-06-25 00:28:50.820501856 +0200 +++ irrlicht/source/Irrlicht/COGLESTexture.cpp 2014-06-25 00:08:37.712544692 +0200 @@ -422,6 +422,9 @@ - source = dest; - } - -+ //clear old error -+ glGetError(); -+ - if (newTexture) - { - if (IsCompressed) + source = dest; + } + ++ //clear old error ++ glGetError(); ++ + if (newTexture) + { + if (IsCompressed) diff --git a/build/android/irrlicht-touchcount.patch b/build/android/patches/irrlicht-touchcount.patch similarity index 98% rename from build/android/irrlicht-touchcount.patch rename to build/android/patches/irrlicht-touchcount.patch index d4e4b9c3..f0c3db67 100644 --- a/build/android/irrlicht-touchcount.patch +++ b/build/android/patches/irrlicht-touchcount.patch @@ -1,30 +1,30 @@ --- irrlicht.orig/include/IEventReceiver.h 2014-06-03 19:43:50.433713133 +0200 +++ irrlicht/include/IEventReceiver.h 2014-06-03 19:44:36.993711489 +0200 @@ -375,6 +375,9 @@ - // Y position of simple touch. - s32 Y; - -+ // number of current touches -+ s32 touchedCount; -+ - //! Type of touch event. - ETOUCH_INPUT_EVENT Event; - }; + // Y position of simple touch. + s32 Y; + ++ // number of current touches ++ s32 touchedCount; ++ + //! Type of touch event. + ETOUCH_INPUT_EVENT Event; + }; --- irrlicht.orig/source/Irrlicht/Android/CIrrDeviceAndroid.cpp 2014-06-03 19:43:50.505713130 +0200 +++ irrlicht/source/Irrlicht/Android/CIrrDeviceAndroid.cpp 2014-06-03 19:45:37.265709359 +0200 @@ -315,6 +315,7 @@ - event.TouchInput.ID = AMotionEvent_getPointerId(androidEvent, i); - event.TouchInput.X = AMotionEvent_getX(androidEvent, i); - event.TouchInput.Y = AMotionEvent_getY(androidEvent, i); -+ event.TouchInput.touchedCount = AMotionEvent_getPointerCount(androidEvent); - - device->postEventFromUser(event); - } + event.TouchInput.ID = AMotionEvent_getPointerId(androidEvent, i); + event.TouchInput.X = AMotionEvent_getX(androidEvent, i); + event.TouchInput.Y = AMotionEvent_getY(androidEvent, i); ++ event.TouchInput.touchedCount = AMotionEvent_getPointerCount(androidEvent); + + device->postEventFromUser(event); + } @@ -326,6 +327,7 @@ - event.TouchInput.ID = AMotionEvent_getPointerId(androidEvent, pointerIndex); - event.TouchInput.X = AMotionEvent_getX(androidEvent, pointerIndex); - event.TouchInput.Y = AMotionEvent_getY(androidEvent, pointerIndex); -+ event.TouchInput.touchedCount = AMotionEvent_getPointerCount(androidEvent); - - device->postEventFromUser(event); - } + event.TouchInput.ID = AMotionEvent_getPointerId(androidEvent, pointerIndex); + event.TouchInput.X = AMotionEvent_getX(androidEvent, pointerIndex); + event.TouchInput.Y = AMotionEvent_getY(androidEvent, pointerIndex); ++ event.TouchInput.touchedCount = AMotionEvent_getPointerCount(androidEvent); + + device->postEventFromUser(event); + } diff --git a/build/android/libiconv_android.patch b/build/android/patches/libiconv_android.patch similarity index 100% rename from build/android/libiconv_android.patch rename to build/android/patches/libiconv_android.patch diff --git a/build/android/libiconv_stdio.patch b/build/android/patches/libiconv_stdio.patch similarity index 100% rename from build/android/libiconv_stdio.patch rename to build/android/patches/libiconv_stdio.patch diff --git a/build/android/proguard-project.txt b/build/android/proguard-project.txt deleted file mode 100644 index f2fe1559..00000000 --- a/build/android/proguard-project.txt +++ /dev/null @@ -1,20 +0,0 @@ -# To enable ProGuard in your project, edit project.properties -# to define the proguard.config property as described in that file. -# -# Add project specific ProGuard rules here. -# By default, the flags in this file are appended to flags specified -# in ${sdk.dir}/tools/proguard/proguard-android.txt -# You can edit the include path and order by changing the ProGuard -# include property in project.properties. -# -# For more details, see -# http://developer.android.com/guide/developing/tools/proguard.html - -# Add any project specific keep options here: - -# If your project uses WebView with JS, uncomment the following -# and specify the fully qualified class name to the JavaScript interface -# class: -#-keepclassmembers class fqcn.of.javascript.interface.for.webview { -# public *; -#} diff --git a/build/android/project.properties b/build/android/project.properties deleted file mode 100644 index c8a96193..00000000 --- a/build/android/project.properties +++ /dev/null @@ -1 +0,0 @@ -target=android-22 \ No newline at end of file diff --git a/build/android/res/drawable-xhdpi/ic_launcher.png b/build/android/res/drawable-xhdpi/ic_launcher.png deleted file mode 100644 index 45760d62..00000000 Binary files a/build/android/res/drawable-xhdpi/ic_launcher.png and /dev/null differ diff --git a/build/android/res/drawable-xhdpi/update.png b/build/android/res/drawable-xhdpi/update.png deleted file mode 100644 index 63fe67f2..00000000 Binary files a/build/android/res/drawable-xhdpi/update.png and /dev/null differ diff --git a/build/android/res/drawable/background.png b/build/android/res/drawable/background.png deleted file mode 100644 index 1ae046e1..00000000 Binary files a/build/android/res/drawable/background.png and /dev/null differ diff --git a/build/android/res/drawable/bg.xml b/build/android/res/drawable/bg.xml deleted file mode 100644 index 840f22ba..00000000 --- a/build/android/res/drawable/bg.xml +++ /dev/null @@ -1,4 +0,0 @@ - - \ No newline at end of file diff --git a/build/android/res/drawable/custom_progress_bar.xml b/build/android/res/drawable/custom_progress_bar.xml deleted file mode 100644 index ec233f27..00000000 --- a/build/android/res/drawable/custom_progress_bar.xml +++ /dev/null @@ -1,14 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/build/android/res/drawable/logo.png b/build/android/res/drawable/logo.png deleted file mode 100644 index 218ebd01..00000000 Binary files a/build/android/res/drawable/logo.png and /dev/null differ diff --git a/build/android/res/layout/activity_main.xml b/build/android/res/layout/activity_main.xml deleted file mode 100644 index a910225b..00000000 --- a/build/android/res/layout/activity_main.xml +++ /dev/null @@ -1,44 +0,0 @@ - - - - - - - - - - - \ No newline at end of file diff --git a/build/android/res/layout/dialog.xml b/build/android/res/layout/dialog.xml deleted file mode 100644 index 9d0bd333..00000000 --- a/build/android/res/layout/dialog.xml +++ /dev/null @@ -1,5 +0,0 @@ - - \ No newline at end of file diff --git a/build/android/res/values-ru/strings.xml b/build/android/res/values-ru/strings.xml deleted file mode 100644 index 4107373b..00000000 --- a/build/android/res/values-ru/strings.xml +++ /dev/null @@ -1,11 +0,0 @@ - - - - - Подготовка к обновлению… - Загрузка… - Загрузка MultiCraft - Осталось меньше минуты… - Недостаточно места для распаковки.\nОсвободите пространство в памяти устройства! - Для корректной работы, игре требуется разрешение записывать в память устройтсва. - \ No newline at end of file diff --git a/build/android/res/values-v21/styles.xml b/build/android/res/values-v21/styles.xml deleted file mode 100644 index 2417cf7b..00000000 --- a/build/android/res/values-v21/styles.xml +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/build/android/res/values/strings.xml b/build/android/res/values/strings.xml deleted file mode 100644 index bad627b6..00000000 --- a/build/android/res/values/strings.xml +++ /dev/null @@ -1,19 +0,0 @@ - - - - MultiCraft - 1.1.3 - 312077575425 - - - Preparing to update… - Loading… - Loading MultiCraft - Less than 1 minute… - - - Not enough space for unpack game data.\nPlease free some space on the storage memory! - - - Game need permission to write files to storage memory. - \ No newline at end of file diff --git a/build/android/res/values/styles.xml b/build/android/res/values/styles.xml deleted file mode 100644 index a127de09..00000000 --- a/build/android/res/values/styles.xml +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/build/android/settings.gradle b/build/android/settings.gradle new file mode 100644 index 00000000..a6e60c43 --- /dev/null +++ b/build/android/settings.gradle @@ -0,0 +1,2 @@ +rootProject.name = "Minetest" + diff --git a/build/android/src/mobi/MultiCraft/GameActivity.java b/build/android/src/mobi/MultiCraft/GameActivity.java deleted file mode 100644 index ddd4c7f9..00000000 --- a/build/android/src/mobi/MultiCraft/GameActivity.java +++ /dev/null @@ -1,113 +0,0 @@ -package mobi.MultiCraft; - -import android.app.NativeActivity; -import android.content.Intent; -import android.os.Build; -import android.os.Bundle; -import android.view.View; -import android.view.WindowManager; - -public class GameActivity extends NativeActivity { - static { - System.loadLibrary("gmp"); - System.loadLibrary("multicraft"); - } - - private int messageReturnCode; - private String messageReturnValue; - - public static native void putMessageBoxResult(String text); - - @Override - public void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); -// startAd(this, true); - messageReturnCode = -1; - messageReturnValue = ""; - makeFullScreen(); - } - - - public void makeFullScreen() { - if (Build.VERSION.SDK_INT >= 19) { - this.getWindow().getDecorView() - .setSystemUiVisibility(View.SYSTEM_UI_FLAG_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY); - } - } - - @Override - public void onWindowFocusChanged(boolean hasFocus) { - super.onWindowFocusChanged(hasFocus); - if (hasFocus) { - makeFullScreen(); - } - } - - @Override - protected void onRestart() { - super.onRestart(); -// startAd(this, false); - } - - @Override - protected void onResume() { - super.onResume(); - makeFullScreen(); - } - - @Override - protected void onStop() { - super.onStop(); -// stopAd(); - } - - protected void onActivityResult(int requestCode, int resultCode, Intent data) { - if (requestCode == 101) { - if (resultCode == RESULT_OK) { - String text = data.getStringExtra("text"); - messageReturnCode = 0; - messageReturnValue = text; - } else { - messageReturnCode = 1; - } - } - } - - public void copyAssets() { - } - - public void showDialog(String acceptButton, String hint, String current, int editType) { - Intent intent = new Intent(this, InputDialogActivity.class); - Bundle params = new Bundle(); - params.putString("acceptButton", acceptButton); - params.putString("hint", hint); - params.putString("current", current); - params.putInt("editType", editType); - intent.putExtras(params); - startActivityForResult(intent, 101); - messageReturnValue = ""; - messageReturnCode = -1; - } - - public int getDialogState() { - return messageReturnCode; - } - - public String getDialogValue() { - messageReturnCode = -1; - return messageReturnValue; - } - - public float getDensity() { - return getResources().getDisplayMetrics().density; - } - - public int getDisplayWidth() { - return getResources().getDisplayMetrics().widthPixels; - } - - public int getDisplayHeight() { - return getResources().getDisplayMetrics().heightPixels; - } -} \ No newline at end of file diff --git a/build/android/src/mobi/MultiCraft/InputDialogActivity.java b/build/android/src/mobi/MultiCraft/InputDialogActivity.java deleted file mode 100644 index 823dddd3..00000000 --- a/build/android/src/mobi/MultiCraft/InputDialogActivity.java +++ /dev/null @@ -1,75 +0,0 @@ -package mobi.MultiCraft; - -import android.annotation.SuppressLint; -import android.app.Activity; -import android.app.AlertDialog; -import android.content.Context; -import android.content.DialogInterface; -import android.content.Intent; -import android.os.Build; -import android.os.Bundle; -import android.text.InputType; -import android.view.KeyEvent; -import android.view.LayoutInflater; -import android.view.View; -import android.view.View.OnKeyListener; -import android.view.inputmethod.InputMethodManager; -import android.widget.EditText; - - -public class InputDialogActivity extends Activity { - private AlertDialog alertDialog; - - @SuppressLint("InflateParams") - @Override - public void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - Bundle b = getIntent().getExtras(); - int editType = b.getInt("editType"); - final AlertDialog.Builder builder = new AlertDialog.Builder(this); - LayoutInflater inflater = this.getLayoutInflater(); - View dialogView = inflater.inflate(R.layout.dialog, null); - builder.setView(dialogView); - final EditText editText = (EditText) dialogView.findViewById(R.id.editText); - final InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE); - imm.toggleSoftInput(InputMethodManager.SHOW_FORCED, InputMethodManager.HIDE_IMPLICIT_ONLY); - if (editType == 3) { - editText.setInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_PASSWORD); - } else { - editText.setInputType(InputType.TYPE_CLASS_TEXT); - } - editText.setOnKeyListener(new OnKeyListener() { - @Override - public boolean onKey(View view, int KeyCode, KeyEvent event) { - if (KeyCode == KeyEvent.KEYCODE_ENTER) { - imm.hideSoftInputFromWindow(editText.getWindowToken(), 0); - pushResult(editText.getText().toString()); - return true; - } - return false; - } - }); - alertDialog = builder.create(); - alertDialog.show(); - alertDialog.setOnCancelListener(new DialogInterface.OnCancelListener() { - @Override - public void onCancel(DialogInterface dialog) { - pushResult(editText.getText().toString()); - setResult(Activity.RESULT_CANCELED); - alertDialog.dismiss(); - finish(); - } - }); - } - - public void pushResult(String text) { - if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP && text.matches(".*[А-я].*")) { - text = Transliteration.toLatin(text); - } - Intent resultData = new Intent(); - resultData.putExtra("text", text); - setResult(Activity.RESULT_OK, resultData); - alertDialog.dismiss(); - finish(); - } -} \ No newline at end of file diff --git a/build/android/src/mobi/MultiCraft/MainActivity.java b/build/android/src/mobi/MultiCraft/MainActivity.java deleted file mode 100644 index 6dee623b..00000000 --- a/build/android/src/mobi/MultiCraft/MainActivity.java +++ /dev/null @@ -1,370 +0,0 @@ -package mobi.MultiCraft; - -import android.Manifest; -import android.annotation.SuppressLint; -import android.app.Activity; -import android.app.ProgressDialog; -import android.content.BroadcastReceiver; -import android.content.Context; -import android.content.Intent; -import android.content.IntentFilter; -import android.content.pm.PackageManager; -import android.graphics.drawable.Drawable; -import android.os.AsyncTask; -import android.os.Build; -import android.os.Bundle; -import android.os.Environment; -import android.os.StatFs; -import android.support.annotation.NonNull; -import android.support.v4.app.ActivityCompat; -import android.util.Log; -import android.view.View; -import android.view.WindowManager; -import android.widget.ProgressBar; -import android.widget.Toast; - -import java.io.File; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; - -import static mobi.MultiCraft.PreferencesHelper.TAG_BUILD_NUMBER; -import static mobi.MultiCraft.PreferencesHelper.TAG_SHORTCUT_CREATED; -import static mobi.MultiCraft.PreferencesHelper.getBuildNumber; -import static mobi.MultiCraft.PreferencesHelper.isCreateShortcut; -import static mobi.MultiCraft.PreferencesHelper.loadSettings; -import static mobi.MultiCraft.PreferencesHelper.saveSettings; - -public class MainActivity extends Activity { - public final static String TAG = "Error"; - public final static String CREATE_SHORTCUT = "com.android.launcher.action.INSTALL_SHORTCUT"; - public final static String FILES = Environment.getExternalStorageDirectory() + "/Files.zip"; - public final static String WORLDS = Environment.getExternalStorageDirectory() + "/worlds.zip"; - public final static String GAMES = Environment.getExternalStorageDirectory() + "/games.zip"; - public final static String NOMEDIA = ".nomedia"; - private final static int REQUEST_STORAGE = 0; - private ProgressDialog mProgressDialog; - private String dataFolder = "/Android/data/mobi.MultiCraft/files/"; - private String unzipLocation = Environment.getExternalStorageDirectory() + dataFolder; - private ProgressBar mProgressBar; - private Utilities util; - private BroadcastReceiver myReceiver = new BroadcastReceiver() { - @Override - public void onReceive(Context context, Intent intent) { - int progress = intent.getIntExtra(UnzipService.ACTION_PROGRESS, 0); - if (progress >= 0) { - mProgressBar.setVisibility(View.VISIBLE); - mProgressBar.setProgress(progress); - } else { - util.createNomedia(); - runGame(); - } - } - }; - - @Override - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); - loadSettings(this); - IntentFilter filter = new IntentFilter(UnzipService.ACTION_UPDATE); - registerReceiver(myReceiver, filter); - if (!isTaskRoot()) { - finish(); - return; - } - - - if (ActivityCompat.checkSelfPermission(this, - Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) { - requestStoragePermission(); - } else { - init(); - } - } - - public void makeFullScreen() { - if (Build.VERSION.SDK_INT >= 19) { - this.getWindow().getDecorView() - .setSystemUiVisibility(View.SYSTEM_UI_FLAG_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY); - } - } - - @Override - public void onWindowFocusChanged(boolean hasFocus) { - super.onWindowFocusChanged(hasFocus); - if (hasFocus) { - makeFullScreen(); - } - } - - @Override - protected void onDestroy() { - super.onDestroy(); - dismissProgressDialog(); - unregisterReceiver(myReceiver); - } - - @Override - protected void onResume() { - super.onResume(); - makeFullScreen(); - } - - private void addShortcut() { - saveSettings(TAG_SHORTCUT_CREATED, false); - Intent shortcutIntent = new Intent(getApplicationContext(), MainActivity.class); - shortcutIntent.setAction(Intent.ACTION_MAIN); - Intent addIntent = new Intent(); - addIntent.putExtra(Intent.EXTRA_SHORTCUT_INTENT, shortcutIntent); - addIntent.putExtra(Intent.EXTRA_SHORTCUT_NAME, getString(R.string.app_name)); - addIntent.putExtra(Intent.EXTRA_SHORTCUT_ICON_RESOURCE, - Intent.ShortcutIconResource.fromContext(getApplicationContext(), R.drawable.ic_launcher)); - addIntent.setAction(CREATE_SHORTCUT); - getApplicationContext().sendBroadcast(addIntent); - } - - @SuppressWarnings("deprecation") - public void init() { - setContentView(R.layout.activity_main); - if (isCreateShortcut()) - addShortcut(); - mProgressBar = (ProgressBar) findViewById(R.id.PB1); - Drawable draw; - draw = getResources().getDrawable(R.drawable.custom_progress_bar); - mProgressBar.setProgressDrawable(draw); - util = new Utilities(); - util.createDataFolder(); - util.checkVersion(); - } - - private void requestPermissionAfterExplain() { - Toast.makeText(this, R.string.explain, Toast.LENGTH_LONG).show(); - ActivityCompat.requestPermissions(MainActivity.this, - new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, REQUEST_STORAGE); - } - - private void requestStoragePermission() { - if (ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.WRITE_EXTERNAL_STORAGE)) { - requestPermissionAfterExplain(); - } else { - ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, - REQUEST_STORAGE); - } - } - - @Override - public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, - @NonNull int[] grantResults) { - - // Check if the only required permission has been granted - if (grantResults.length == 1 && grantResults[0] == PackageManager.PERMISSION_GRANTED) { - init(); - } else { - requestStoragePermission(); - } - } - - private void showSpinnerDialog(int message) { - if (mProgressDialog == null) { - mProgressDialog = new ProgressDialog(MainActivity.this); - mProgressDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER); - mProgressDialog.setCancelable(false); - } - mProgressDialog.setMessage(getString(message)); - mProgressDialog.show(); - } - - private void dismissProgressDialog() { - if (mProgressDialog != null && mProgressDialog.isShowing()) { - mProgressDialog.dismiss(); - } - } - - public void runGame() { - util.deleteZip(FILES); - util.deleteZip(WORLDS); - util.deleteZip(GAMES); - Intent intent = new Intent(MainActivity.this, GameActivity.class); - intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_CLEAR_TASK); - startActivity(intent); - } - - private void startUnzipService(String[] file) throws IOException { - // Start MyIntentService - Intent intentMyIntentService = new Intent(this, UnzipService.class); - intentMyIntentService.putExtra(UnzipService.EXTRA_KEY_IN_FILE, file); - intentMyIntentService.putExtra(UnzipService.EXTRA_KEY_IN_LOCATION, unzipLocation); - startService(intentMyIntentService); - - } - - private class DeleteTask extends AsyncTask { - String location; - - @Override - protected void onPreExecute() { - super.onPreExecute(); - showSpinnerDialog(R.string.rm_old); - } - - @Override - protected Void doInBackground(String... params) { - location = params[0]; - for (String p : params) { - util.deleteFiles(p); - } - return null; - } - - @Override - protected void onPostExecute(Void result) { - if (isFinishing()) - return; - dismissProgressDialog(); - if (unzipLocation.equals(location)) { - new CopyZip().execute(FILES, WORLDS, GAMES); - } else { - new CopyZip().execute(FILES, GAMES); - } - } - - - } - - private class CopyZip extends AsyncTask { - String[] zips; - - @Override - protected void onPreExecute() { - super.onPreExecute(); - } - - @Override - protected String doInBackground(String... params) { - zips = params; - for (String s : zips) { - copyAssets(s); - } - return "Done"; - - } - - @Override - protected void onPostExecute(String result) { - if (util.getAvailableSpaceInMB() > 15) { - try { - startUnzipService(zips); - } catch (IOException e) { - Log.e(TAG, "unzip failed: " + e.getMessage()); - } - } else - Toast.makeText(MainActivity.this, R.string.not_enough_space, Toast.LENGTH_LONG).show(); - } - - private void copyAssets(String zipName) { - String filename = zipName.substring(zipName.lastIndexOf("/") + 1); - InputStream in; - OutputStream out; - try { - in = getAssets().open(filename); - out = new FileOutputStream(zipName); - copyFile(in, out); - in.close(); - out.flush(); - out.close(); - } catch (IOException e) { - Log.e(TAG, "Failed to copy asset file: " + e.getMessage()); - } - } - - private void copyFile(InputStream in, OutputStream out) throws IOException { - byte[] buffer = new byte[1024]; - int read; - while ((read = in.read(buffer)) != -1) { - out.write(buffer, 0, read); - } - } - } - - private class Utilities { - - private void createDataFolder() { - File folder = new File(unzipLocation); - if (!(folder.exists())) - folder.mkdirs(); - } - - private void deleteZip(String fileName) { - File file = new File(fileName); - if (file.exists()) - file.delete(); - } - - private void startDeletion(boolean isAll) { - if (isAll) { - new DeleteTask().execute(unzipLocation); - } else { - new DeleteTask().execute(unzipLocation + "textures", unzipLocation + "games/MultiCraft", unzipLocation + "builtin", - unzipLocation + "fonts", unzipLocation + "debug.txt"); - } - } - - @SuppressWarnings("deprecation") - @SuppressLint("NewApi") - private long getAvailableSpaceInMB() { - final long SIZE_KB = 1024L; - final long SIZE_MB = SIZE_KB * SIZE_KB; - long availableSpace; - StatFs stat = new StatFs(Environment.getExternalStorageDirectory().getPath()); - if (Build.VERSION.SDK_INT > 17) { - availableSpace = stat.getAvailableBlocksLong() * stat.getBlockSizeLong(); - } else { - availableSpace = (long) stat.getAvailableBlocks() * (long) stat.getBlockSize(); - } - return availableSpace / SIZE_MB; - } - - private boolean isFolderEmpty(String folder) { - File location = new File(folder); - File[] contents = location.listFiles(); - return contents == null || contents.length == 0; - } - - public void checkVersion() { - if (isFolderEmpty(unzipLocation)) { - saveSettings(TAG_BUILD_NUMBER, getString(R.string.ver)); - startDeletion(true); - } else if (getBuildNumber().equals(getString(R.string.ver))) { - runGame(); - } else { - saveSettings(TAG_BUILD_NUMBER, getString(R.string.ver)); - startDeletion(false); - } - } - - private void deleteFiles(String path) { - File file = new File(path); - if (file.exists()) { - String deleteCmd = "rm -r " + path; - Runtime runtime = Runtime.getRuntime(); - try { - runtime.exec(deleteCmd); - } catch (IOException e) { - Log.e(TAG, "delete files failed: " + e.getLocalizedMessage()); - } - } - } - - public void createNomedia() { - File myFile = new File(unzipLocation, NOMEDIA); - if (!myFile.exists()) - try { - myFile.createNewFile(); - } catch (IOException e) { - Log.e(TAG, "nomedia has not been created: " + e.getMessage()); - } - } - } -} \ No newline at end of file diff --git a/build/android/src/mobi/MultiCraft/PreferencesHelper.java b/build/android/src/mobi/MultiCraft/PreferencesHelper.java deleted file mode 100644 index 4329e215..00000000 --- a/build/android/src/mobi/MultiCraft/PreferencesHelper.java +++ /dev/null @@ -1,40 +0,0 @@ -package mobi.MultiCraft; - -import android.content.Context; -import android.content.SharedPreferences; - -public class PreferencesHelper { - public static final String SETTINGS = "settings"; - public static final String TAG_SHORTCUT_CREATED = "createShortcut"; - public static final String TAG_BUILD_NUMBER = "buildNumber"; - private static boolean createShortcut; - private static String buildNumber; - private static SharedPreferences settings; - - public static boolean isCreateShortcut() { - return createShortcut; - } - - public static String getBuildNumber() { - return buildNumber; - } - - public static void loadSettings(final Context context) { - settings = context.getSharedPreferences(SETTINGS, Context.MODE_PRIVATE); - createShortcut = settings.getBoolean(TAG_SHORTCUT_CREATED, true); - buildNumber = settings.getString(TAG_BUILD_NUMBER, "0"); - } - - public static void saveSettings(String tag, boolean bool) { - SharedPreferences.Editor editor = settings.edit(); - editor.putBoolean(tag, bool); - editor.apply(); - } - - public static void saveSettings(String tag, String value) { - SharedPreferences.Editor editor = settings.edit(); - editor.putString(tag, value); - editor.apply(); - } - -} \ No newline at end of file diff --git a/build/android/src/mobi/MultiCraft/Transliteration.java b/build/android/src/mobi/MultiCraft/Transliteration.java deleted file mode 100644 index 27ceeb1b..00000000 --- a/build/android/src/mobi/MultiCraft/Transliteration.java +++ /dev/null @@ -1,72 +0,0 @@ -package mobi.MultiCraft; - -public class Transliteration { - - private static final String[] CHAR_TABLE = new String[81]; - private static final char START_CHAR = 'Ё'; - - - static { - CHAR_TABLE['А' - START_CHAR] = "A"; - CHAR_TABLE['Б' - START_CHAR] = "B"; - CHAR_TABLE['В' - START_CHAR] = "V"; - CHAR_TABLE['Г' - START_CHAR] = "G"; - CHAR_TABLE['Д' - START_CHAR] = "D"; - CHAR_TABLE['Е' - START_CHAR] = "E"; - CHAR_TABLE['Ё' - START_CHAR] = "E"; - CHAR_TABLE['Ж' - START_CHAR] = "ZH"; - CHAR_TABLE['З' - START_CHAR] = "Z"; - CHAR_TABLE['И' - START_CHAR] = "I"; - CHAR_TABLE['Й' - START_CHAR] = "J"; - CHAR_TABLE['К' - START_CHAR] = "K"; - CHAR_TABLE['Л' - START_CHAR] = "L"; - CHAR_TABLE['М' - START_CHAR] = "M"; - CHAR_TABLE['Н' - START_CHAR] = "N"; - CHAR_TABLE['О' - START_CHAR] = "O"; - CHAR_TABLE['П' - START_CHAR] = "P"; - CHAR_TABLE['Р' - START_CHAR] = "R"; - CHAR_TABLE['С' - START_CHAR] = "TS"; - CHAR_TABLE['Т' - START_CHAR] = "T"; - CHAR_TABLE['У' - START_CHAR] = "U"; - CHAR_TABLE['Ф' - START_CHAR] = "F"; - CHAR_TABLE['Х' - START_CHAR] = "H"; - CHAR_TABLE['Ц' - START_CHAR] = "C"; - CHAR_TABLE['Ч' - START_CHAR] = "CH"; - CHAR_TABLE['Ш' - START_CHAR] = "SH"; - CHAR_TABLE['Щ' - START_CHAR] = "SHCH"; - CHAR_TABLE['Ъ' - START_CHAR] = ""; - CHAR_TABLE['Ы' - START_CHAR] = "Y"; - CHAR_TABLE['Ь' - START_CHAR] = ""; - CHAR_TABLE['Э' - START_CHAR] = "E"; - CHAR_TABLE['Ю' - START_CHAR] = "U"; - CHAR_TABLE['Я' - START_CHAR] = "YA"; - - for (int i = 0; i < CHAR_TABLE.length; i++) { - char idx = (char) ((char) i + START_CHAR); - char lower = new String(new char[]{idx}).toLowerCase().charAt(0); - if (CHAR_TABLE[i] != null) { - CHAR_TABLE[lower - START_CHAR] = CHAR_TABLE[i].toLowerCase(); - } - } - } - - /** - * Переводит русский текст в транслит. В результирующей строке - * каждая русская буква будет заменена на соответствующую английскую. - * Не русские символы останутся прежними. - */ - public static String toLatin(String text) { - char charBuffer[] = text.toCharArray(); - StringBuilder sb = new StringBuilder(text.length()); - for (char symbol : charBuffer) { - int i = symbol - START_CHAR; - if (i >= 0 && i < CHAR_TABLE.length) { - String replace = CHAR_TABLE[i]; - sb.append(replace == null ? symbol : replace); - } else { - sb.append(symbol); - } - } - return sb.toString(); - } -} diff --git a/build/android/src/mobi/MultiCraft/UnzipService.java b/build/android/src/mobi/MultiCraft/UnzipService.java deleted file mode 100644 index d3add5ab..00000000 --- a/build/android/src/mobi/MultiCraft/UnzipService.java +++ /dev/null @@ -1,113 +0,0 @@ -package mobi.MultiCraft; - -import android.app.IntentService; -import android.app.Notification; -import android.app.NotificationManager; -import android.content.Context; -import android.content.Intent; -import android.util.Log; - -import java.io.File; -import java.io.FileInputStream; -import java.io.FileNotFoundException; -import java.io.FileOutputStream; -import java.io.IOException; -import java.util.zip.ZipEntry; -import java.util.zip.ZipFile; -import java.util.zip.ZipInputStream; - -public class UnzipService extends IntentService { - public static final String ACTION_UPDATE = "mobi.MultiCraft.UPDATE"; - public static final String EXTRA_KEY_IN_FILE = "file"; - public static final String EXTRA_KEY_IN_LOCATION = "location"; - public static final String ACTION_PROGRESS = "progress"; - public final String TAG = UnzipService.class.getSimpleName(); - private NotificationManager mNotifyManager; - private int id = 1; - - public UnzipService() { - super("mobi.MultiCraft.UnzipService"); - } - - private void isDir(String dir, String unzipLocation) { - File f = new File(unzipLocation + dir); - - if (!f.isDirectory()) { - f.mkdirs(); - } - } - - @Override - protected void onHandleIntent(Intent intent) { - mNotifyManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); - Notification.Builder mBuilder = new Notification.Builder(this); - mBuilder.setContentTitle(getString(R.string.notification_title)) - .setContentText(getString(R.string.notification_description)).setSmallIcon(R.drawable.update); - String[] file = intent.getStringArrayExtra(EXTRA_KEY_IN_FILE); - String location = intent.getStringExtra(EXTRA_KEY_IN_LOCATION); - - mNotifyManager.notify(id, mBuilder.build()); - int per = 0; - int size = getSummarySize(file); - for (String f : file) { - try { - try { - FileInputStream fin = new FileInputStream(f); - ZipInputStream zin = new ZipInputStream(fin); - ZipEntry ze; - while ((ze = zin.getNextEntry()) != null) { - if (ze.isDirectory()) { - per++; - isDir(ze.getName(), location); - } else { - per++; - int progress = 100 * per / size; - // send update - publishProgress(progress); - FileOutputStream f_out = new FileOutputStream(location + ze.getName()); - byte[] buffer = new byte[8192]; - int len; - while ((len = zin.read(buffer)) != -1) { - f_out.write(buffer, 0, len); - } - f_out.close(); - zin.closeEntry(); - f_out.close(); - } - } - zin.close(); - } catch (FileNotFoundException e) { - Log.e(TAG, e.getMessage()); - } - } catch (IOException e) { - Log.e(TAG, e.getLocalizedMessage()); - } - } - } - - private void publishProgress(int progress) { - Intent intentUpdate = new Intent(ACTION_UPDATE); - intentUpdate.putExtra(ACTION_PROGRESS, progress); - sendBroadcast(intentUpdate); - } - - private int getSummarySize(String[] zips) { - int size = 0; - for (String z : zips) { - try { - ZipFile zipSize = new ZipFile(z); - size += zipSize.size(); - } catch (IOException e) { - Log.e(TAG, e.getLocalizedMessage()); - } - } - return size; - } - - @Override - public void onDestroy() { - super.onDestroy(); - mNotifyManager.cancel(id); - publishProgress(-1); - } -} \ No newline at end of file diff --git a/builtin/game/chatcommands.lua b/builtin/game/chatcommands.lua index 4deff281..3350140e 100644 --- a/builtin/game/chatcommands.lua +++ b/builtin/game/chatcommands.lua @@ -181,8 +181,10 @@ core.register_chatcommand("grant", { end local privs = core.get_player_privs(grantname) local privs_unknown = "" + local basic_privs = + core.string_to_privs(core.setting_get("basic_privs") or "interact,shout") for priv, _ in pairs(grantprivs) do - if priv ~= "interact" and priv ~= "shout" and + if not basic_privs[priv] and not core.check_player_privs(name, {privs=true}) then return false, "Your privileges are insufficient." end @@ -223,8 +225,10 @@ core.register_chatcommand("revoke", { end local revoke_privs = core.string_to_privs(revoke_priv_str) local privs = core.get_player_privs(revoke_name) + local basic_privs = + core.string_to_privs(core.setting_get("basic_privs") or "interact,shout") for priv, _ in pairs(revoke_privs) do - if priv ~= "interact" and priv ~= "shout" and + if not basic_privs[priv] and not core.check_player_privs(name, {privs=true}) then return false, "Your privileges are insufficient." end @@ -348,10 +352,16 @@ core.register_chatcommand("teleport", { p.x = tonumber(p.x) p.y = tonumber(p.y) p.z = tonumber(p.z) - teleportee = core.get_player_by_name(name) - if teleportee and p.x and p.y and p.z then - teleportee:setpos(p) - return true, "Teleporting to "..core.pos_to_string(p) + if p.x and p.y and p.z then + local lm = tonumber(minetest.setting_get("map_generation_limit") or 31000) + if p.x < -lm or p.x > lm or p.y < -lm or p.y > lm or p.z < -lm or p.z > lm then + return false, "Cannot teleport out of map bounds!" + end + teleportee = core.get_player_by_name(name) + if teleportee then + teleportee:setpos(p) + return true, "Teleporting to "..core.pos_to_string(p) + end end local teleportee = nil diff --git a/builtin/mainmenu/common.lua b/builtin/mainmenu/common.lua index 071e3c2f..680ad163 100644 --- a/builtin/mainmenu/common.lua +++ b/builtin/mainmenu/common.lua @@ -177,7 +177,7 @@ end -------------------------------------------------------------------------------- function menu_handle_key_up_down(fields, textlist, settingname) - local oldidx, newidx = core.get_textlist_index(textlist) + local oldidx, newidx = core.get_textlist_index(textlist), 1 if fields.key_up or fields.key_down then if fields.key_up and oldidx and oldidx > 1 then newidx = oldidx - 1 @@ -202,12 +202,20 @@ function asyncOnlineFavourites() end menudata.favorites = menudata.public_known menudata.favorites_is_public = true + + if not menudata.public_downloading then + menudata.public_downloading = true + else + return + end + core.handle_async( function(param) return core.get_favorites("online") end, nil, function(result) + menudata.public_downloading = nil local favs = order_favorite_list(result) if favs[1] then menudata.public_known = favs diff --git a/builtin/mainmenu/dlg_config_world.lua b/builtin/mainmenu/dlg_config_world.lua index bb39eb16..f8844a43 100644 --- a/builtin/mainmenu/dlg_config_world.lua +++ b/builtin/mainmenu/dlg_config_world.lua @@ -25,20 +25,20 @@ local function get_formspec(data) local mod = data.list:get_list()[data.selected_mod] local retval = - "size[11,6.5,true]" .. - "label[0.5,-0.25;" .. fgettext("World:") .. "]" .. - "label[1.75,-0.25;" .. data.worldspec.name .. "]" + "size[11.5,7.5,true]" .. + "label[0.5,0;" .. fgettext("World:") .. "]" .. + "label[1.75,0;" .. data.worldspec.name .. "]" if data.hide_gamemods then - retval = retval .. "checkbox[0,5.75;cb_hide_gamemods;" .. fgettext("Hide Game") .. ";true]" + retval = retval .. "checkbox[1,6;cb_hide_gamemods;" .. fgettext("Hide Game") .. ";true]" else - retval = retval .. "checkbox[0,5.75;cb_hide_gamemods;" .. fgettext("Hide Game") .. ";false]" + retval = retval .. "checkbox[1,6;cb_hide_gamemods;" .. fgettext("Hide Game") .. ";false]" end if data.hide_modpackcontents then - retval = retval .. "checkbox[2,5.75;cb_hide_mpcontent;" .. fgettext("Hide mp content") .. ";true]" + retval = retval .. "checkbox[6,6;cb_hide_mpcontent;" .. fgettext("Hide mp content") .. ";true]" else - retval = retval .. "checkbox[2,5.75;cb_hide_mpcontent;" .. fgettext("Hide mp content") .. ";false]" + retval = retval .. "checkbox[6,6;cb_hide_mpcontent;" .. fgettext("Hide mp content") .. ";false]" end if mod == nil then @@ -46,13 +46,13 @@ local function get_formspec(data) end retval = retval .. - "label[0,0.45;" .. fgettext("Mod:") .. "]" .. - "label[0.75,0.45;" .. mod.name .. "]" .. - "label[0,1;" .. fgettext("Depends:") .. "]" .. - "textlist[0,1.5;5,4.25;world_config_depends;" .. + "label[0,0.7;" .. fgettext("Mod:") .. "]" .. + "label[0.75,0.7;" .. mod.name .. "]" .. + "label[0,1.25;" .. fgettext("Depends:") .. "]" .. + "textlist[0,1.75;5,4.25;world_config_depends;" .. modmgr.get_dependencies(mod.path) .. ";0]" .. - "button[9.25,6.35;2,0.5;btn_config_world_save;" .. fgettext("Save") .. "]" .. - "button[7.4,6.35;2,0.5;btn_config_world_cancel;" .. fgettext("Cancel") .. "]" + "button[3.25,7;2.5,0.5;btn_config_world_save;" .. fgettext("Save") .. "]" .. + "button[5.75,7;2.5,0.5;btn_config_world_cancel;" .. fgettext("Cancel") .. "]" if mod ~= nil and mod.name ~= "" and mod.typ ~= "game_mod" then if mod.is_modpack then @@ -68,22 +68,22 @@ local function get_formspec(data) end if all_enabled == false then - retval = retval .. "button[5.5,-0.125;2,0.5;btn_mp_enable;" .. fgettext("Enable MP") .. "]" + retval = retval .. "button[5.5,0.125;2.5,0.5;btn_mp_enable;" .. fgettext("Enable MP") .. "]" else - retval = retval .. "button[5.5,-0.125;2,0.5;btn_mp_disable;" .. fgettext("Disable MP") .. "]" + retval = retval .. "button[5.5,0.125;2.5,0.5;btn_mp_disable;" .. fgettext("Disable MP") .. "]" end else if mod.enabled then - retval = retval .. "checkbox[5.5,-0.375;cb_mod_enable;" .. fgettext("enabled") .. ";true]" + retval = retval .. "checkbox[5.5,-0.125;cb_mod_enable;" .. fgettext("enabled") .. ";true]" else - retval = retval .. "checkbox[5.5,-0.375;cb_mod_enable;" .. fgettext("enabled") .. ";false]" + retval = retval .. "checkbox[5.5,-0.125;cb_mod_enable;" .. fgettext("enabled") .. ";false]" end end end retval = retval .. - "button[8.5,-0.125;2.5,0.5;btn_all_mods;" .. fgettext("Enable all") .. "]" .. - "textlist[5.5,0.5;5.5,5.75;world_config_modlist;" + "button[8.75,0.125;2.5,0.5;btn_all_mods;" .. fgettext("Enable all") .. "]" .. + "textlist[5.5,0.75;5.75,5.25;world_config_modlist;" retval = retval .. modmgr.render_modlist(data.list) retval = retval .. ";" .. data.selected_mod .."]" diff --git a/builtin/mainmenu/dlg_create_world.lua b/builtin/mainmenu/dlg_create_world.lua index 861a5460..585f3684 100644 --- a/builtin/mainmenu/dlg_create_world.lua +++ b/builtin/mainmenu/dlg_create_world.lua @@ -46,7 +46,7 @@ local function create_world_formspec(dialogdata) current_seed = core.formspec_escape(current_seed) local retval = - "size[12,3]" .. + "size[12,3,true]" .. "label[2,0;" .. fgettext("World name") .. "]".. "field[4.5,0.4;6,0.5;te_world_name;;]" .. diff --git a/builtin/mainmenu/dlg_delete_mod.lua b/builtin/mainmenu/dlg_delete_mod.lua index f40f6b9e..ef428aa9 100644 --- a/builtin/mainmenu/dlg_delete_mod.lua +++ b/builtin/mainmenu/dlg_delete_mod.lua @@ -22,10 +22,11 @@ local function delete_mod_formspec(dialogdata) dialogdata.mod = modmgr.global_mods:get_list()[dialogdata.selected] local retval = - "size[12.4,5,true]" .. - "field[1.75,1;10,3;;" .. fgettext("Are you sure you want to delete \"$1\"?", dialogdata.mod.name) .. ";]".. - "button[4,4.2;1,0.5;dlg_delete_mod_confirm;" .. fgettext("Yes") .. "]" .. - "button[6.5,4.2;3,0.5;dlg_delete_mod_cancel;" .. fgettext("No of course not!") .. "]" + "size[11.5,4.5,true]" .. + "label[2,2;" .. + fgettext("Are you sure you want to delete \"$1\"?", dialogdata.mod.name) .. "]".. + "button[3.25,3.5;2.5,0.5;dlg_delete_mod_confirm;" .. fgettext("Delete") .. "]" .. + "button[5.75,3.5;2.5,0.5;dlg_delete_mod_cancel;" .. fgettext("Cancel") .. "]" return retval end diff --git a/builtin/mainmenu/dlg_rename_modpack.lua b/builtin/mainmenu/dlg_rename_modpack.lua index 9c48cf3f..1012f84d 100644 --- a/builtin/mainmenu/dlg_rename_modpack.lua +++ b/builtin/mainmenu/dlg_rename_modpack.lua @@ -22,14 +22,12 @@ local function rename_modpack_formspec(dialogdata) dialogdata.mod = modmgr.global_mods:get_list()[dialogdata.selected] local retval = - "size[12.4,5,true]" .. - "label[1.75,1;".. fgettext("Rename Modpack:") .. "]".. - "field[4.5,1.4;6,0.5;te_modpack_name;;" .. - dialogdata.mod.name .. - "]" .. - "button[5,4.2;2.6,0.5;dlg_rename_modpack_confirm;".. + "size[11.5,4.5,true]" .. + "field[2.5,2;7,0.5;te_modpack_name;".. fgettext("Rename Modpack:") .. ";" .. + dialogdata.mod.name .. "]" .. + "button[3.25,3.5;2.5,0.5;dlg_rename_modpack_confirm;".. fgettext("Accept") .. "]" .. - "button[7.5,4.2;2.8,0.5;dlg_rename_modpack_cancel;".. + "button[5.75,3.5;2.5,0.5;dlg_rename_modpack_cancel;".. fgettext("Cancel") .. "]" return retval diff --git a/builtin/settingtypes.txt b/builtin/settingtypes.txt index 065d1219..57498183 100644 --- a/builtin/settingtypes.txt +++ b/builtin/settingtypes.txt @@ -690,6 +690,9 @@ default_password (Default password) string # See /privs in game for a full list on your server and mod configuration. default_privs (Default privileges) string interact, shout +# Privileges that players with basic_privs can grant +basic_privs (Basic Privileges) string interact, shout + # Whether players are shown to clients without any range limit. # Deprecated, use the setting player_transfer_distance instead. unlimited_player_transfer_distance (Unlimited player transfer distance) bool true @@ -882,6 +885,9 @@ mg_biome_np_humidity_blend (Mapgen biome humidity blend noise parameters) noise_ [***Mapgen v5] +# Controls width of tunnels, a smaller value creates wider tunnels. +mgv5_cave_width (Mapgen v5 cave width) float 0.125 + mgv5_np_filler_depth (Mapgen v5 filler depth noise parameters) noise_params 0, 1, (150, 150, 150), 261, 4, 0.7, 2.0 mgv5_np_factor (Mapgen v5 factor noise parameters) noise_params 0, 1, (250, 250, 250), 920381, 3, 0.45, 2.0 mgv5_np_height (Mapgen v5 height noise parameters) noise_params 0, 10, (250, 250, 250), 84174, 4, 0.5, 2.0 @@ -936,6 +942,9 @@ mgv6_np_apple_trees (Mapgen v6 apple trees noise parameters) noise_params 0, 1, # Flags starting with 'no' are used to explicitly disable them. mgv7_spflags (Mapgen v7 flags) flags mountains,ridges mountains,ridges,nomountains,noridges +# Controls width of tunnels, a smaller value creates wider tunnels. +mgv7_cave_width (Mapgen v7 cave width) float 0.3 + mgv7_np_terrain_base (Mapgen v7 terrain base noise parameters) noise_params 4, 70, (600, 600, 600), 82341, 5, 0.6, 2.0 mgv7_np_terrain_alt (Mapgen v7 terrain altitude noise parameters) noise_params 4, 25, (600, 600, 600), 5934, 5, 0.6, 2.0 mgv7_np_terrain_persist (Mapgen v7 terrain persistation noise parameters) noise_params 0.6, 0.1, (2000, 2000, 2000), 539, 3, 0.6, 2.0 @@ -964,6 +973,9 @@ mgflat_ground_level (Mapgen flat ground level) int 8 # Y of upper limit of large pseudorandom caves. mgflat_large_cave_depth (Mapgen flat large cave depth) int -33 +# Controls width of tunnels, a smaller value creates wider tunnels. +mgflat_cave_width (Mapgen flat cave width) float 0.3 + # Terrain noise threshold for lakes. # Controls proportion of world area covered by lakes. # Adjust towards 0.0 for a larger proportion. @@ -991,6 +1003,9 @@ mgflat_np_cave2 (Mapgen flat cave2 noise parameters) noise_params 0, 12, (128, 1 [***Mapgen fractal] +# Controls width of tunnels, a smaller value creates wider tunnels. +mgfractal_cave_width (Mapgen fractal cave width) float 0.3 + # Choice of 18 fractals from 9 formulas. # 1 = 4D "Roundy" mandelbrot set. # 2 = 4D "Roundy" julia set. @@ -1070,60 +1085,63 @@ mgfractal_np_cave2 (Mapgen fractal cave2 noise parameters) noise_params 0, 12, ( mg_valleys_spflags (Valleys C Flags) flags altitude_chill,humid_rivers altitude_chill,noaltitude_chill,humid_rivers,nohumid_rivers # The altitude at which temperature drops by 20C -mg_valleys_altitude_chill (Altitude Chill) int 90 +mgvalleys_altitude_chill (Altitude Chill) int 90 # Depth below which you'll find large caves. -mg_valleys_large_cave_depth (Large cave depth) int -33 +mgvalleys_large_cave_depth (Large cave depth) int -33 # Creates unpredictable lava features in caves. # These can make mining difficult. Zero disables them. (0-10) -mg_valleys_lava_features (Lava Features) int 0 +mgvalleys_lava_features (Lava Features) int 0 # Depth below which you'll find massive caves. -mg_valleys_massive_cave_depth (Massive cave depth) int -256 +mgvalleys_massive_cave_depth (Massive cave depth) int -256 # How deep to make rivers -mg_valleys_river_depth (River Depth) int 4 +mgvalleys_river_depth (River Depth) int 4 # How wide to make rivers -mg_valleys_river_size (River Size) int 5 +mgvalleys_river_size (River Size) int 5 # Creates unpredictable water features in caves. # These can make mining difficult. Zero disables them. (0-10) -mg_valleys_water_features (Water Features) int 0 +mgvalleys_water_features (Water Features) int 0 + +# Controls width of tunnels, a smaller value creates wider tunnels. +mgvalleys_cave_width (Cave width) float 0.3 # Noise parameters [****Noises] # Caves and tunnels form at the intersection of the two noises -mg_valleys_np_cave1 (Cave noise #1) noise_params 0, 12, (100, 100, 100), 52534, 4, 0.5, 2.0 +mgvalleys_np_cave1 (Cave noise #1) noise_params 0, 12, (100, 100, 100), 52534, 4, 0.5, 2.0 # Caves and tunnels form at the intersection of the two noises -mg_valleys_np_cave2 (Cave noise #2) noise_params 0, 12, (100, 100, 100), 10325, 4, 0.5, 2.0 +mgvalleys_np_cave2 (Cave noise #2) noise_params 0, 12, (100, 100, 100), 10325, 4, 0.5, 2.0 # The depth of dirt or other filler -mg_valleys_np_filler_depth (Filler Depth) noise_params 0, 1.2, (256, 256, 256), 1605, 3, 0.5, 2.0 +mgvalleys_np_filler_depth (Filler Depth) noise_params 0, 1.2, (256, 256, 256), 1605, 3, 0.5, 2.0 # Massive caves form here. -mg_valleys_np_massive_caves (Massive cave noise) noise_params 0, 1, (768, 256, 768), 59033, 6, 0.63, 2.0 +mgvalleys_np_massive_caves (Massive cave noise) noise_params 0, 1, (768, 256, 768), 59033, 6, 0.63, 2.0 # River noise -- rivers occur close to zero -mg_valleys_np_rivers (River Noise) noise_params 0, 1, (256, 256, 256), -6050, 5, 0.6, 2.0 +mgvalleys_np_rivers (River Noise) noise_params 0, 1, (256, 256, 256), -6050, 5, 0.6, 2.0 # Base terrain height -mg_valleys_np_terrain_height (Terrain Height) noise_params -10, 50, (1024, 1024, 1024), 5202, 6, 0.4, 2.0 +mgvalleys_np_terrain_height (Terrain Height) noise_params -10, 50, (1024, 1024, 1024), 5202, 6, 0.4, 2.0 # Raises terrain to make valleys around the rivers -mg_valleys_np_valley_depth (Valley Depth) noise_params 5, 4, (512, 512, 512), -1914, 1, 1.0, 2.0 +mgvalleys_np_valley_depth (Valley Depth) noise_params 5, 4, (512, 512, 512), -1914, 1, 1.0, 2.0 # Slope and fill work together to modify the heights -mg_valleys_np_inter_valley_fill (Valley Fill) noise_params 0, 1, (256, 512, 256), 1993, 6, 0.8, 2.0 +mgvalleys_np_inter_valley_fill (Valley Fill) noise_params 0, 1, (256, 512, 256), 1993, 6, 0.8, 2.0 # Amplifies the valleys -mg_valleys_np_valley_profile (Valley Profile) noise_params 0.6, 0.5, (512, 512, 512), 777, 1, 1.0, 2.0 +mgvalleys_np_valley_profile (Valley Profile) noise_params 0.6, 0.5, (512, 512, 512), 777, 1, 1.0, 2.0 # Slope and fill work together to modify the heights -mg_valleys_np_inter_valley_slope (Valley Slope) noise_params 0.5, 0.5, (128, 128, 128), 746, 1, 1.0, 2.0 +mgvalleys_np_inter_valley_slope (Valley Slope) noise_params 0.5, 0.5, (128, 128, 128), 746, 1, 1.0, 2.0 [*Security] diff --git a/doc/lua_api.txt b/doc/lua_api.txt index 7abe1856..bbfe38ec 100644 --- a/doc/lua_api.txt +++ b/doc/lua_api.txt @@ -243,6 +243,7 @@ Example: default_dirt.png^default_grass_side.png `default_grass_side.png` is overlayed over `default_dirt.png`. +The texture with the lower resolution will be automatically upscaled to the higher resolution texture. ### Texture grouping Textures can be grouped together by enclosing them in `(` and `)`. @@ -1923,6 +1924,7 @@ Call these functions only at load time! * `minetest.register_privilege(name, definition)` * `definition`: `"description text"` * `definition`: `{ description = "description text", give_to_singleplayer = boolean, -- default: true }` + * To allow players with basic_privs to grant, see basic_privs minetest.conf setting. * `minetest.register_authentication_handler(handler)` * See `minetest.builtin_auth_handler` in `builtin.lua` for reference diff --git a/multicraft.conf.example b/multicraft.conf.example index 81a446ca..1fc8a413 100644 --- a/multicraft.conf.example +++ b/multicraft.conf.example @@ -825,6 +825,10 @@ # type: string # default_privs = interact, shout +# Privileges that players with basic_privs can grant +# type: string +# basic_privs = interact, shout + # Whether players are shown to clients without any range limit. # Deprecated, use the setting player_transfer_distance instead. # type: bool @@ -1093,6 +1097,10 @@ #### Mapgen v5 +# Controls width of tunnels, a smaller value creates wider tunnels. +# type: float +# mgv5_cave_width = 0.125 + # type: noise_params # mgv5_np_filler_depth = 0, 1, (150, 150, 150), 261, 4, 0.7, 2.0 @@ -1171,6 +1179,10 @@ # type: flags possible values: mountains, ridges, nomountains, noridges # mgv7_spflags = mountains,ridges +# Controls width of tunnels, a smaller value creates wider tunnels. +# type: float +# mgv7_cave_width = 0.3 + # type: noise_params # mgv7_np_terrain_base = 4, 70, (600, 600, 600), 82341, 5, 0.6, 2.0 @@ -1223,6 +1235,10 @@ # type: int # mgflat_large_cave_depth = -33 +# Controls width of tunnels, a smaller value creates wider tunnels. +# type: float +# mgflat_cave_width = 0.3 + # Terrain noise threshold for lakes. # Controls proportion of world area covered by lakes. # Adjust towards 0.0 for a larger proportion. @@ -1260,6 +1276,10 @@ #### Mapgen fractal +# Controls width of tunnels, a smaller value creates wider tunnels. +# type: float +# mgfractal_cave_width = 0.3 + # Choice of 18 fractals from 9 formulas. # 1 = 4D "Roundy" mandelbrot set. # 2 = 4D "Roundy" julia set. @@ -1351,79 +1371,83 @@ # Flags that are not specified in the flag string are not modified from the default. # Flags starting with 'no' are used to explicitly disable them. # type: flags possible values: altitude_chill, noaltitude_chill, humid_rivers, nohumid_rivers -# mg_valleys_spflags = altitude_chill,humid_rivers +# mgvalleys_spflags = altitude_chill,humid_rivers # The altitude at which temperature drops by 20C # type: int -# mg_valleys_altitude_chill = 90 +# mgvalleys_altitude_chill = 90 # Depth below which you'll find large caves. # type: int -# mg_valleys_large_cave_depth = -33 +# mgvalleys_large_cave_depth = -33 # Creates unpredictable lava features in caves. # These can make mining difficult. Zero disables them. (0-10) # type: int -# mg_valleys_lava_features = 0 +# mgvalleys_lava_features = 0 # Depth below which you'll find massive caves. # type: int -# mg_valleys_massive_cave_depth = -256 +# mgvalleys_massive_cave_depth = -256 # How deep to make rivers # type: int -# mg_valleys_river_depth = 4 +# mgvalleys_river_depth = 4 # How wide to make rivers # type: int -# mg_valleys_river_size = 5 +# mgvalleys_river_size = 5 # Creates unpredictable water features in caves. # These can make mining difficult. Zero disables them. (0-10) # type: int -# mg_valleys_water_features = 0 +# mgvalleys_water_features = 0 + +# Controls width of tunnels, a smaller value creates wider tunnels. +# type: float +# mgvalleys_cave_width = 0.3 ##### Noises # Caves and tunnels form at the intersection of the two noises # type: noise_params -# mg_valleys_np_cave1 = 0, 12, (100, 100, 100), 52534, 4, 0.5, 2.0 +# mgvalleys_np_cave1 = 0, 12, (100, 100, 100), 52534, 4, 0.5, 2.0 # Caves and tunnels form at the intersection of the two noises # type: noise_params -# mg_valleys_np_cave2 = 0, 12, (100, 100, 100), 10325, 4, 0.5, 2.0 +# mgvalleys_np_cave2 = 0, 12, (100, 100, 100), 10325, 4, 0.5, 2.0 # The depth of dirt or other filler # type: noise_params -# mg_valleys_np_filler_depth = 0, 1.2, (256, 256, 256), 1605, 3, 0.5, 2.0 +# mgvalleys_np_filler_depth = 0, 1.2, (256, 256, 256), 1605, 3, 0.5, 2.0 # Massive caves form here. # type: noise_params -# mg_valleys_np_massive_caves = 0, 1, (768, 256, 768), 59033, 6, 0.63, 2.0 +# mgvalleys_np_massive_caves = 0, 1, (768, 256, 768), 59033, 6, 0.63, 2.0 # River noise -- rivers occur close to zero # type: noise_params -# mg_valleys_np_rivers = 0, 1, (256, 256, 256), -6050, 5, 0.6, 2.0 +# mgvalleys_np_rivers = 0, 1, (256, 256, 256), -6050, 5, 0.6, 2.0 # Base terrain height # type: noise_params -# mg_valleys_np_terrain_height = -10, 50, (1024, 1024, 1024), 5202, 6, 0.4, 2.0 +# mgvalleys_np_terrain_height = -10, 50, (1024, 1024, 1024), 5202, 6, 0.4, 2.0 # Raises terrain to make valleys around the rivers # type: noise_params -# mg_valleys_np_valley_depth = 5, 4, (512, 512, 512), -1914, 1, 1.0, 2.0 +# mgvalleys_np_valley_depth = 5, 4, (512, 512, 512), -1914, 1, 1.0, 2.0 # Slope and fill work together to modify the heights # type: noise_params -# mg_valleys_np_inter_valley_fill = 0, 1, (256, 512, 256), 1993, 6, 0.8, 2.0 +# mgvalleys_np_inter_valley_fill = 0, 1, (256, 512, 256), 1993, 6, 0.8, 2.0 # Amplifies the valleys # type: noise_params -# mg_valleys_np_valley_profile = 0.6, 0.5, (512, 512, 512), 777, 1, 1.0, 2.0 +# mgvalleys_np_valley_profile = 0.6, 0.5, (512, 512, 512), 777, 1, 1.0, 2.0 # Slope and fill work together to modify the heights # type: noise_params -# mg_valleys_np_inter_valley_slope = 0.5, 0.5, (128, 128, 128), 746, 1, 1.0, 2.0 +# mgvalleys_np_inter_valley_slope = 0.5, 0.5, (128, 128, 128), 746, 1, 1.0, 2.0 ## Security diff --git a/src/chat.cpp b/src/chat.cpp index 454090b1..5c948d2b 100644 --- a/src/chat.cpp +++ b/src/chat.cpp @@ -679,8 +679,8 @@ ChatBackend::~ChatBackend() void ChatBackend::addMessage(std::wstring name, std::wstring text) { - name = removeChatEscapes(name); - text = removeChatEscapes(text); + name = unescape_enriched(name); + text = unescape_enriched(text); // Note: A message may consist of multiple lines, for example the MOTD. WStrfnd fnd(text); diff --git a/src/client/tile.cpp b/src/client/tile.cpp index 38e38a6e..3c347fc1 100644 --- a/src/client/tile.cpp +++ b/src/client/tile.cpp @@ -1178,7 +1178,28 @@ bool TextureSource::generateImagePart(std::string part_of_name, core::rect(pos_from, dim), video::SColor(255,255,255,255), NULL);*/ - blit_with_alpha(image, baseimg, pos_from, pos_to, dim); + + core::dimension2d dim_dst = baseimg->getDimension(); + if (dim == dim_dst) { + blit_with_alpha(image, baseimg, pos_from, pos_to, dim); + } else if (dim.Width * dim.Height < dim_dst.Width * dim_dst.Height) { + // Upscale overlying image + video::IImage* scaled_image = m_device->getVideoDriver()-> + createImage(video::ECF_A8R8G8B8, dim_dst); + image->copyToScaling(scaled_image); + + blit_with_alpha(scaled_image, baseimg, pos_from, pos_to, dim_dst); + scaled_image->drop(); + } else { + // Upscale base image + video::IImage* scaled_base = m_device->getVideoDriver()-> + createImage(video::ECF_A8R8G8B8, dim); + baseimg->copyToScaling(scaled_base); + baseimg->drop(); + baseimg = scaled_base; + + blit_with_alpha(image, baseimg, pos_from, pos_to, dim); + } } //cleanup image->drop(); diff --git a/src/environment.cpp b/src/environment.cpp index a6e6e29c..1724b3ab 100644 --- a/src/environment.cpp +++ b/src/environment.cpp @@ -50,6 +50,9 @@ with this program; if not, write to the Free Software Foundation, Inc., #define LBM_NAME_ALLOWED_CHARS "abcdefghijklmnopqrstuvwxyz0123456789_:" +// A number that is much smaller than the timeout for particle spawners should/could ever be +#define PARTICLE_SPAWNER_NO_EXPIRY -1024.f + Environment::Environment(): m_time_of_day_speed(0), m_time_of_day(9000), @@ -1544,6 +1547,49 @@ void ServerEnvironment::step(float dtime) */ removeRemovedObjects(); } + + /* + Manage particle spawner expiration + */ + if (m_particle_management_interval.step(dtime, 1.0)) { + for (std::map::iterator i = m_particle_spawners.begin(); + i != m_particle_spawners.end(); ) { + //non expiring spawners + if (i->second == PARTICLE_SPAWNER_NO_EXPIRY) { + ++i; + continue; + } + + i->second -= 1.0f; + if (i->second <= 0.f) + m_particle_spawners.erase(i++); + else + ++i; + } + } +} + +u32 ServerEnvironment::addParticleSpawner(float exptime) +{ + // Timers with lifetime 0 do not expire + float time = exptime > 0.f ? exptime : PARTICLE_SPAWNER_NO_EXPIRY; + + u32 id = 0; + for (;;) { // look for unused particlespawner id + id++; + std::map::iterator f; + f = m_particle_spawners.find(id); + if (f == m_particle_spawners.end()) { + m_particle_spawners[id] = time; + break; + } + } + return id; +} + +void ServerEnvironment::deleteParticleSpawner(u32 id) +{ + m_particle_spawners.erase(id); } ServerActiveObject* ServerEnvironment::getActiveObject(u16 id) diff --git a/src/environment.h b/src/environment.h index 17d8b727..d5091da2 100644 --- a/src/environment.h +++ b/src/environment.h @@ -337,6 +337,9 @@ public: // env_meta.txt doesn't exist (e.g. new world) void loadDefaultMeta(); + u32 addParticleSpawner(float exptime); + void deleteParticleSpawner(u32 id); + /* External ActiveObject interface ------------------------------------------- @@ -516,6 +519,10 @@ private: // Estimate for general maximum lag as determined by server. // Can raise to high values like 15s with eg. map generation mods. float m_max_lag_estimate; + + // Particles + IntervalLimiter m_particle_management_interval; + std::map m_particle_spawners; }; #ifndef SERVER diff --git a/src/game.cpp b/src/game.cpp index 47aea66e..148c88eb 100644 --- a/src/game.cpp +++ b/src/game.cpp @@ -3688,7 +3688,7 @@ void Game::handlePointingAtNode(GameRunData *runData, NodeMetadata *meta = map.getNodeMetadata(nodepos); if (meta) { - infotext = utf8_to_wide(meta->getString("infotext")); + infotext = unescape_enriched(utf8_to_wide(meta->getString("infotext"))); } else { MapNode n = map.getNodeNoEx(nodepos); @@ -3772,13 +3772,15 @@ void Game::handlePointingAtObject(GameRunData *runData, const v3f &player_position, bool show_debug) { - infotext = utf8_to_wide(runData->selected_object->infoText()); + infotext = unescape_enriched( + utf8_to_wide(runData->selected_object->infoText())); if (show_debug) { if (infotext != L"") { infotext += L"\n"; } - infotext += utf8_to_wide(runData->selected_object->debugInfoText()); + infotext += unescape_enriched(utf8_to_wide( + runData->selected_object->debugInfoText())); } if (input->getLeftState()) { diff --git a/src/guiEngine.cpp b/src/guiEngine.cpp index 0f3606dd..13923a5b 100644 --- a/src/guiEngine.cpp +++ b/src/guiEngine.cpp @@ -359,7 +359,7 @@ void GUIEngine::cloudPreProcess() /******************************************************************************/ void GUIEngine::cloudPostProcess() { - float fps_max = g_settings->getFloat("fps_max"); + float fps_max = g_settings->getFloat("pause_fps_max"); // Time of frame without fps limit u32 busytime_u32; diff --git a/src/guiFormSpecMenu.cpp b/src/guiFormSpecMenu.cpp index b69e2fc5..0fcc6f97 100644 --- a/src/guiFormSpecMenu.cpp +++ b/src/guiFormSpecMenu.cpp @@ -609,8 +609,6 @@ void GUIFormSpecMenu::parseButton(parserData* data,std::string element, if(!data->explicit_size) warningstream<<"invalid use of button without a size[] element"< rect = core::rect(pos.X, pos.Y, pos.X+geom.X, pos.Y+geom.Y); FieldSpec spec( @@ -746,7 +743,7 @@ void GUIFormSpecMenu::parseTable(parserData* data,std::string element) spec.ftype = f_Table; for (unsigned int i = 0; i < items.size(); ++i) { - items[i] = unescape_string(items[i]); + items[i] = unescape_string(unescape_enriched(items[i])); } //now really show table @@ -818,7 +815,7 @@ void GUIFormSpecMenu::parseTextList(parserData* data,std::string element) spec.ftype = f_Table; for (unsigned int i = 0; i < items.size(); ++i) { - items[i] = unescape_string(items[i]); + items[i] = unescape_string(unescape_enriched(items[i])); } //now really show list @@ -889,7 +886,8 @@ void GUIFormSpecMenu::parseDropDown(parserData* data,std::string element) } for (unsigned int i=0; i < items.size(); i++) { - e->addItem(utf8_to_wide(items[i]).c_str()); + e->addItem(unescape_string(unescape_enriched( + utf8_to_wide(items[i]))).c_str()); } if (str_initial_selection != "") @@ -930,8 +928,6 @@ void GUIFormSpecMenu::parsePwdField(parserData* data,std::string element) core::rect rect = core::rect(pos.X, pos.Y, pos.X+geom.X, pos.Y+geom.Y); - label = unescape_string(label); - std::wstring wlabel = utf8_to_wide(label); FieldSpec spec( @@ -995,8 +991,6 @@ void GUIFormSpecMenu::parseSimpleField(parserData* data, if(m_form_src) default_val = m_form_src->resolveText(default_val); - default_val = unescape_string(default_val); - label = unescape_string(label); std::wstring wlabel = utf8_to_wide(label); @@ -1094,9 +1088,6 @@ void GUIFormSpecMenu::parseTextArea(parserData* data, default_val = m_form_src->resolveText(default_val); - default_val = unescape_string(default_val); - label = unescape_string(label); - std::wstring wlabel = utf8_to_wide(label); FieldSpec spec( @@ -1197,7 +1188,6 @@ void GUIFormSpecMenu::parseLabel(parserData* data,std::string element) if(!data->explicit_size) warningstream<<"invalid use of label without a size[] element"< lines = split(text, '\n'); for (unsigned int i = 0; i != lines.size(); i++) { @@ -1243,7 +1233,8 @@ void GUIFormSpecMenu::parseVertLabel(parserData* data,std::string element) ((parts.size() > 2) && (m_formspec_version > FORMSPEC_API_VERSION))) { std::vector v_pos = split(parts[0],','); - std::wstring text = utf8_to_wide(unescape_string(parts[1])); + std::wstring text = unescape_string( + unescape_enriched(utf8_to_wide(parts[1]))); MY_CHECKPOS("vertlabel",1); @@ -1330,7 +1321,6 @@ void GUIFormSpecMenu::parseImageButton(parserData* data,std::string element, image_name = unescape_string(image_name); pressed_image_name = unescape_string(pressed_image_name); - label = unescape_string(label); std::wstring wlabel = utf8_to_wide(label); @@ -1430,7 +1420,8 @@ void GUIFormSpecMenu::parseTabHeader(parserData* data,std::string element) e->setNotClipped(true); for (unsigned int i = 0; i < buttons.size(); i++) { - e->addTab(utf8_to_wide(buttons[i]).c_str(), -1); + e->addTab(unescape_string(unescape_enriched( + utf8_to_wide(buttons[i]))).c_str(), -1); } if ((tab_index >= 0) && @@ -1489,7 +1480,6 @@ void GUIFormSpecMenu::parseItemImageButton(parserData* data,std::string element) m_default_tooltip_bgcolor, m_default_tooltip_color); - label = unescape_string(label); FieldSpec spec( name, utf8_to_wide(label), @@ -1604,14 +1594,14 @@ void GUIFormSpecMenu::parseTooltip(parserData* data, std::string element) std::vector parts = split(element,';'); if (parts.size() == 2) { std::string name = parts[0]; - m_tooltips[name] = TooltipSpec(unescape_string(parts[1]), + m_tooltips[name] = TooltipSpec(parts[1], m_default_tooltip_bgcolor, m_default_tooltip_color); return; } else if (parts.size() == 4) { std::string name = parts[0]; video::SColor tmp_color1, tmp_color2; if ( parseColorString(parts[2], tmp_color1, false) && parseColorString(parts[3], tmp_color2, false) ) { - m_tooltips[name] = TooltipSpec(unescape_string(parts[1]), + m_tooltips[name] = TooltipSpec(parts[1], tmp_color1, tmp_color2); return; } @@ -2242,18 +2232,20 @@ void GUIFormSpecMenu::drawList(const ListDrawSpec &s, int phase, } // Draw tooltip - std::string tooltip_text = ""; - if (hovering && !m_selected_item) - tooltip_text = item.getDefinition(m_gamedef->idef()).description; - if (tooltip_text != "") { - std::vector tt_rows = str_split(tooltip_text, '\n'); + std::wstring tooltip_text = L""; + if (hovering && !m_selected_item) { + tooltip_text = utf8_to_wide(item.getDefinition(m_gamedef->idef()).description); + tooltip_text = unescape_enriched(tooltip_text); + } + if (tooltip_text != L"") { + std::vector tt_rows = str_split(tooltip_text, L'\n'); m_tooltip_element->setBackgroundColor(m_default_tooltip_bgcolor); m_tooltip_element->setOverrideColor(m_default_tooltip_color); m_tooltip_element->setVisible(true); this->bringToFront(m_tooltip_element); - m_tooltip_element->setText(utf8_to_wide(tooltip_text).c_str()); + m_tooltip_element->setText(tooltip_text.c_str()); s32 tooltip_width = m_tooltip_element->getTextWidth() + m_btn_height; - s32 tooltip_height = m_tooltip_element->getTextHeight() * tt_rows.size() + 5; + s32 tooltip_height = m_tooltip_element->getTextHeight() + 5; v2u32 screenSize = driver->getScreenSize(); int tooltip_offset_x = m_btn_height; int tooltip_offset_y = m_btn_height; @@ -2504,7 +2496,7 @@ void GUIFormSpecMenu::drawMenu() u32 delta = 0; if (id == -1) { m_old_tooltip_id = id; - m_old_tooltip = ""; + m_old_tooltip = L""; } else { if (id == m_old_tooltip_id) { delta = porting::getDeltaMs(m_hovered_time, getTimeMs()); @@ -2517,11 +2509,11 @@ void GUIFormSpecMenu::drawMenu() if (id != -1 && delta >= m_tooltip_show_delay) { for(std::vector::iterator iter = m_fields.begin(); iter != m_fields.end(); ++iter) { - if ( (iter->fid == id) && (m_tooltips[iter->fname].tooltip != "") ){ + if (iter->fid == id && m_tooltips[iter->fname].tooltip != L"") { if (m_old_tooltip != m_tooltips[iter->fname].tooltip) { m_old_tooltip = m_tooltips[iter->fname].tooltip; - m_tooltip_element->setText(utf8_to_wide(m_tooltips[iter->fname].tooltip).c_str()); - std::vector tt_rows = str_split(m_tooltips[iter->fname].tooltip, '\n'); + m_tooltip_element->setText(m_tooltips[iter->fname].tooltip.c_str()); + std::vector tt_rows = str_split(m_tooltips[iter->fname].tooltip, L'\n'); s32 tooltip_width = m_tooltip_element->getTextWidth() + m_btn_height; s32 tooltip_height = m_tooltip_element->getTextHeight() * tt_rows.size() + 5; int tooltip_offset_x = m_btn_height; @@ -2875,7 +2867,7 @@ bool GUIFormSpecMenu::preprocessEvent(const SEvent& event) core::position2d(x, y)); if (event.MouseInput.Event == EMIE_LMOUSE_PRESSED_DOWN) { m_old_tooltip_id = -1; - m_old_tooltip = ""; + m_old_tooltip = L""; } if (!isChild(hovered,this)) { if (DoubleClickDetection(event)) { diff --git a/src/guiFormSpecMenu.h b/src/guiFormSpecMenu.h index 3b39d57c..93588ceb 100644 --- a/src/guiFormSpecMenu.h +++ b/src/guiFormSpecMenu.h @@ -29,6 +29,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "modalMenu.h" #include "guiTable.h" #include "network/networkprotocol.h" +#include "util/string.h" class IGameDef; class InventoryManager; @@ -191,18 +192,26 @@ class GUIFormSpecMenu : public GUIModalMenu bool scale; }; + /* The responsibility of unescaping the strings has been shifted + * from the formspec parsing methods to the draw methods. + * There still are a few exceptions: + * - Vertical label, because it modifies the string by inserting + * '\n' between each character, + * - Tab header, because it gives the string immediately to + * Irrlicht and we can't unescape it later. + */ struct FieldSpec { FieldSpec() { } FieldSpec(const std::string &name, const std::wstring &label, - const std::wstring &fdeflt, int id) : + const std::wstring &default_text, int id) : fname(name), - flabel(label), - fdefault(fdeflt), fid(id) { + flabel = unescape_string(unescape_enriched(label)); + fdefault = unescape_string(unescape_enriched(default_text)); send = false; ftype = f_Unknown; is_exit = false; @@ -235,12 +244,12 @@ class GUIFormSpecMenu : public GUIModalMenu } TooltipSpec(std::string a_tooltip, irr::video::SColor a_bgcolor, irr::video::SColor a_color): - tooltip(a_tooltip), bgcolor(a_bgcolor), color(a_color) { + tooltip = unescape_string(unescape_enriched(utf8_to_wide(a_tooltip))); } - std::string tooltip; + std::wstring tooltip; irr::video::SColor bgcolor; irr::video::SColor color; }; @@ -252,18 +261,18 @@ class GUIFormSpecMenu : public GUIModalMenu } StaticTextSpec(const std::wstring &a_text, const core::rect &a_rect): - text(a_text), rect(a_rect), parent_button(NULL) { + text = unescape_string(unescape_enriched(a_text)); } StaticTextSpec(const std::wstring &a_text, const core::rect &a_rect, gui::IGUIButton *a_parent_button): - text(a_text), rect(a_rect), parent_button(a_parent_button) { + text = unescape_string(unescape_enriched(a_text)); } std::wstring text; core::rect rect; @@ -406,7 +415,7 @@ protected: u32 m_tooltip_show_delay; s32 m_hovered_time; s32 m_old_tooltip_id; - std::string m_old_tooltip; + std::wstring m_old_tooltip; bool m_rmouse_auto_place; diff --git a/src/guiKeyChangeMenu.cpp b/src/guiKeyChangeMenu.cpp index e9b36b33..acb9ef89 100644 --- a/src/guiKeyChangeMenu.cpp +++ b/src/guiKeyChangeMenu.cpp @@ -187,7 +187,7 @@ void GUIKeyChangeMenu::regenerateGui(v2u32 screensize) { core::rect < s32 > rect(0, 0, 100, 30); - rect += topleft + v2s32(size.X - 100 - 20, size.Y - 40); + rect += topleft + v2s32(size.X / 2 - 105, size.Y - 40); const wchar_t *text = wgettext("Save"); Environment->addButton(rect, this, GUI_ID_BACK_BUTTON, text); @@ -195,7 +195,7 @@ void GUIKeyChangeMenu::regenerateGui(v2u32 screensize) } { core::rect < s32 > rect(0, 0, 100, 30); - rect += topleft + v2s32(size.X - 100 - 20 - 100 - 20, size.Y - 40); + rect += topleft + v2s32(size.X / 2 + 5, size.Y - 40); const wchar_t *text = wgettext("Cancel"); Environment->addButton(rect, this, GUI_ID_ABORT_BUTTON, text); diff --git a/src/hud.cpp b/src/hud.cpp index ab2f27c2..12c6b8e1 100644 --- a/src/hud.cpp +++ b/src/hud.cpp @@ -22,6 +22,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "hud.h" #include "settings.h" #include "util/numeric.h" +#include "util/string.h" #include "log.h" #include "gamedef.h" #include "itemdef.h" @@ -319,7 +320,7 @@ void Hud::drawLuaElements(const v3s16 &camera_offset) (e->number >> 8) & 0xFF, (e->number >> 0) & 0xFF); core::rect size(0, 0, e->scale.X, text_height * e->scale.Y); - std::wstring text = utf8_to_wide(e->text); + std::wstring text = unescape_enriched(utf8_to_wide(e->text)); core::dimension2d textsize = font->getDimension(text.c_str()); v2s32 offset((e->align.X - 1.0) * (textsize.Width / 2), (e->align.Y - 1.0) * (textsize.Height / 2)); @@ -355,11 +356,11 @@ void Hud::drawLuaElements(const v3s16 &camera_offset) (e->number >> 8) & 0xFF, (e->number >> 0) & 0xFF); core::rect size(0, 0, 200, 2 * text_height); - std::wstring text = utf8_to_wide(e->name); + std::wstring text = unescape_enriched(utf8_to_wide(e->name)); font->draw(text.c_str(), size + pos, color); std::ostringstream os; os << distance << e->text; - text = utf8_to_wide(os.str()); + text = unescape_enriched(utf8_to_wide(os.str())); pos.Y += text_height; font->draw(text.c_str(), size + pos, color); break; } diff --git a/src/inventory.cpp b/src/inventory.cpp index 3646b96d..1887e22a 100644 --- a/src/inventory.cpp +++ b/src/inventory.cpp @@ -335,8 +335,9 @@ ItemStack ItemStack::addItem(const ItemStack &newitem_, *this = newitem; newitem.clear(); } - // If item name differs, bail out - else if(name != newitem.name) + // If item name or metadata differs, bail out + else if (name != newitem.name + || metadata != newitem.metadata) { // cannot be added } @@ -374,8 +375,9 @@ bool ItemStack::itemFits(const ItemStack &newitem_, { newitem.clear(); } - // If item name differs, bail out - else if(name != newitem.name) + // If item name or metadata differs, bail out + else if (name != newitem.name + || metadata != newitem.metadata) { // cannot be added } diff --git a/src/mapgen_flat.cpp b/src/mapgen_flat.cpp index bf70ccd6..f53aadef 100644 --- a/src/mapgen_flat.cpp +++ b/src/mapgen_flat.cpp @@ -67,14 +67,15 @@ MapgenFlat::MapgenFlat(int mapgenid, MapgenParams *params, EmergeManager *emerge this->humidmap = NULL; MapgenFlatParams *sp = (MapgenFlatParams *)params->sparams; - this->spflags = sp->spflags; - this->ground_level = sp->ground_level; + this->spflags = sp->spflags; + this->ground_level = sp->ground_level; this->large_cave_depth = sp->large_cave_depth; - this->lake_threshold = sp->lake_threshold; - this->lake_steepness = sp->lake_steepness; - this->hill_threshold = sp->hill_threshold; - this->hill_steepness = sp->hill_steepness; + this->cave_width = sp->cave_width; + this->lake_threshold = sp->lake_threshold; + this->lake_steepness = sp->lake_steepness; + this->hill_threshold = sp->hill_threshold; + this->hill_steepness = sp->hill_steepness; //// 2D noise noise_terrain = new Noise(&sp->np_terrain, seed, csize.X, csize.Z); @@ -139,14 +140,14 @@ MapgenFlat::~MapgenFlat() MapgenFlatParams::MapgenFlatParams() { - spflags = 0; - - ground_level = 8; + spflags = 0; + ground_level = 8; large_cave_depth = -33; - lake_threshold = -0.45; - lake_steepness = 48.0; - hill_threshold = 0.45; - hill_steepness = 64.0; + cave_width = 0.3; + lake_threshold = -0.45; + lake_steepness = 48.0; + hill_threshold = 0.45; + hill_steepness = 64.0; np_terrain = NoiseParams(0, 1, v3f(600, 600, 600), 7244, 5, 0.6, 2.0); np_filler_depth = NoiseParams(0, 1.2, v3f(150, 150, 150), 261, 3, 0.7, 2.0); @@ -157,10 +158,10 @@ MapgenFlatParams::MapgenFlatParams() void MapgenFlatParams::readParams(const Settings *settings) { - settings->getFlagStrNoEx("mgflat_spflags", spflags, flagdesc_mapgen_flat); - + settings->getFlagStrNoEx("mgflat_spflags", spflags, flagdesc_mapgen_flat); settings->getS16NoEx("mgflat_ground_level", ground_level); settings->getS16NoEx("mgflat_large_cave_depth", large_cave_depth); + settings->getFloatNoEx("mgflat_cave_width", cave_width); settings->getFloatNoEx("mgflat_lake_threshold", lake_threshold); settings->getFloatNoEx("mgflat_lake_steepness", lake_steepness); settings->getFloatNoEx("mgflat_hill_threshold", hill_threshold); @@ -175,10 +176,10 @@ void MapgenFlatParams::readParams(const Settings *settings) void MapgenFlatParams::writeParams(Settings *settings) const { - settings->setFlagStr("mgflat_spflags", spflags, flagdesc_mapgen_flat, U32_MAX); - + settings->setFlagStr("mgflat_spflags", spflags, flagdesc_mapgen_flat, U32_MAX); settings->setS16("mgflat_ground_level", ground_level); settings->setS16("mgflat_large_cave_depth", large_cave_depth); + settings->setFloat("mgflat_cave_width", cave_width); settings->setFloat("mgflat_lake_threshold", lake_threshold); settings->setFloat("mgflat_lake_steepness", lake_steepness); settings->setFloat("mgflat_hill_threshold", hill_threshold); @@ -592,7 +593,7 @@ void MapgenFlat::generateCaves(s16 max_stone_y) float d1 = contour(noise_cave1->result[index3d]); float d2 = contour(noise_cave2->result[index3d]); - if (d1 * d2 > 0.3f && ndef->get(c).is_ground_content) { + if (d1 * d2 > cave_width && ndef->get(c).is_ground_content) { // In tunnel and ground content, excavate vm->m_data[vi] = MapNode(CONTENT_AIR); is_tunnel = true; diff --git a/src/mapgen_flat.h b/src/mapgen_flat.h index 748598df..fc3fddf9 100644 --- a/src/mapgen_flat.h +++ b/src/mapgen_flat.h @@ -34,14 +34,13 @@ extern FlagDesc flagdesc_mapgen_flat[]; struct MapgenFlatParams : public MapgenSpecificParams { u32 spflags; - s16 ground_level; s16 large_cave_depth; + float cave_width; float lake_threshold; float lake_steepness; float hill_threshold; float hill_steepness; - NoiseParams np_terrain; NoiseParams np_filler_depth; NoiseParams np_cave1; @@ -61,20 +60,20 @@ public: int ystride; int zstride_1d; - u32 spflags; v3s16 node_min; v3s16 node_max; v3s16 full_node_min; v3s16 full_node_max; + u32 spflags; s16 ground_level; s16 large_cave_depth; + float cave_width; float lake_threshold; float lake_steepness; float hill_threshold; float hill_steepness; - Noise *noise_terrain; Noise *noise_filler_depth; Noise *noise_cave1; diff --git a/src/mapgen_fractal.cpp b/src/mapgen_fractal.cpp index 754d657c..0b0cf7f9 100644 --- a/src/mapgen_fractal.cpp +++ b/src/mapgen_fractal.cpp @@ -65,21 +65,18 @@ MapgenFractal::MapgenFractal(int mapgenid, MapgenParams *params, EmergeManager * this->humidmap = NULL; MapgenFractalParams *sp = (MapgenFractalParams *)params->sparams; - this->spflags = sp->spflags; + this->spflags = sp->spflags; + this->cave_width = sp->cave_width; this->fractal = sp->fractal; this->iterations = sp->iterations; this->scale = sp->scale; this->offset = sp->offset; this->slice_w = sp->slice_w; - - this->julia_x = sp->julia_x; - this->julia_y = sp->julia_y; - this->julia_z = sp->julia_z; - this->julia_w = sp->julia_w; - - this->formula = fractal / 2 + fractal % 2; - this->julia = fractal % 2 == 0; + this->julia_x = sp->julia_x; + this->julia_y = sp->julia_y; + this->julia_z = sp->julia_z; + this->julia_w = sp->julia_w; //// 2D terrain noise noise_seabed = new Noise(&sp->np_seabed, seed, csize.X, csize.Z); @@ -96,6 +93,9 @@ MapgenFractal::MapgenFractal(int mapgenid, MapgenParams *params, EmergeManager * noise_heat_blend = new Noise(¶ms->np_biome_heat_blend, seed, csize.X, csize.Z); noise_humidity_blend = new Noise(¶ms->np_biome_humidity_blend, seed, csize.X, csize.Z); + this->formula = fractal / 2 + fractal % 2; + this->julia = fractal % 2 == 0; + //// Resolve nodes to be used INodeDefManager *ndef = emerge->ndef; @@ -144,18 +144,17 @@ MapgenFractal::~MapgenFractal() MapgenFractalParams::MapgenFractalParams() { - spflags = 0; - - fractal = 1; + spflags = 0; + cave_width = 0.3; + fractal = 1; iterations = 11; - scale = v3f(4096.0, 1024.0, 4096.0); - offset = v3f(1.79, 0.0, 0.0); - slice_w = 0.0; - - julia_x = 0.33; - julia_y = 0.33; - julia_z = 0.33; - julia_w = 0.33; + scale = v3f(4096.0, 1024.0, 4096.0); + offset = v3f(1.79, 0.0, 0.0); + slice_w = 0.0; + julia_x = 0.33; + julia_y = 0.33; + julia_z = 0.33; + julia_w = 0.33; np_seabed = NoiseParams(-14, 9, v3f(600, 600, 600), 41900, 5, 0.6, 2.0); np_filler_depth = NoiseParams(0, 1.2, v3f(150, 150, 150), 261, 3, 0.7, 2.0); @@ -166,45 +165,43 @@ MapgenFractalParams::MapgenFractalParams() void MapgenFractalParams::readParams(const Settings *settings) { - settings->getFlagStrNoEx("mgfractal_spflags", spflags, flagdesc_mapgen_fractal); + settings->getFlagStrNoEx("mgfractal_spflags", spflags, flagdesc_mapgen_fractal); + settings->getFloatNoEx("mgfractal_cave_width", cave_width); + settings->getU16NoEx("mgfractal_fractal", fractal); + settings->getU16NoEx("mgfractal_iterations", iterations); + settings->getV3FNoEx("mgfractal_scale", scale); + settings->getV3FNoEx("mgfractal_offset", offset); + settings->getFloatNoEx("mgfractal_slice_w", slice_w); + settings->getFloatNoEx("mgfractal_julia_x", julia_x); + settings->getFloatNoEx("mgfractal_julia_y", julia_y); + settings->getFloatNoEx("mgfractal_julia_z", julia_z); + settings->getFloatNoEx("mgfractal_julia_w", julia_w); - settings->getU16NoEx("mgfractal_fractal", fractal); - settings->getU16NoEx("mgfractal_iterations", iterations); - settings->getV3FNoEx("mgfractal_scale", scale); - settings->getV3FNoEx("mgfractal_offset", offset); - settings->getFloatNoEx("mgfractal_slice_w", slice_w); - - settings->getFloatNoEx("mgfractal_julia_x", julia_x); - settings->getFloatNoEx("mgfractal_julia_y", julia_y); - settings->getFloatNoEx("mgfractal_julia_z", julia_z); - settings->getFloatNoEx("mgfractal_julia_w", julia_w); - - settings->getNoiseParams("mgfractal_np_seabed", np_seabed); + settings->getNoiseParams("mgfractal_np_seabed", np_seabed); settings->getNoiseParams("mgfractal_np_filler_depth", np_filler_depth); - settings->getNoiseParams("mgfractal_np_cave1", np_cave1); - settings->getNoiseParams("mgfractal_np_cave2", np_cave2); + settings->getNoiseParams("mgfractal_np_cave1", np_cave1); + settings->getNoiseParams("mgfractal_np_cave2", np_cave2); } void MapgenFractalParams::writeParams(Settings *settings) const { - settings->setFlagStr("mgfractal_spflags", spflags, flagdesc_mapgen_fractal, U32_MAX); + settings->setFlagStr("mgfractal_spflags", spflags, flagdesc_mapgen_fractal, U32_MAX); + settings->setFloat("mgfractal_cave_width", cave_width); + settings->setU16("mgfractal_fractal", fractal); + settings->setU16("mgfractal_iterations", iterations); + settings->setV3F("mgfractal_scale", scale); + settings->setV3F("mgfractal_offset", offset); + settings->setFloat("mgfractal_slice_w", slice_w); + settings->setFloat("mgfractal_julia_x", julia_x); + settings->setFloat("mgfractal_julia_y", julia_y); + settings->setFloat("mgfractal_julia_z", julia_z); + settings->setFloat("mgfractal_julia_w", julia_w); - settings->setU16("mgfractal_fractal", fractal); - settings->setU16("mgfractal_iterations", iterations); - settings->setV3F("mgfractal_scale", scale); - settings->setV3F("mgfractal_offset", offset); - settings->setFloat("mgfractal_slice_w", slice_w); - - settings->setFloat("mgfractal_julia_x", julia_x); - settings->setFloat("mgfractal_julia_y", julia_y); - settings->setFloat("mgfractal_julia_z", julia_z); - settings->setFloat("mgfractal_julia_w", julia_w); - - settings->setNoiseParams("mgfractal_np_seabed", np_seabed); + settings->setNoiseParams("mgfractal_np_seabed", np_seabed); settings->setNoiseParams("mgfractal_np_filler_depth", np_filler_depth); - settings->setNoiseParams("mgfractal_np_cave1", np_cave1); - settings->setNoiseParams("mgfractal_np_cave2", np_cave2); + settings->setNoiseParams("mgfractal_np_cave1", np_cave1); + settings->setNoiseParams("mgfractal_np_cave2", np_cave2); } @@ -720,7 +717,7 @@ void MapgenFractal::generateCaves(s16 max_stone_y) float d1 = contour(noise_cave1->result[index3d]); float d2 = contour(noise_cave2->result[index3d]); - if (d1 * d2 > 0.3f && ndef->get(c).is_ground_content) { + if (d1 * d2 > cave_width && ndef->get(c).is_ground_content) { // In tunnel and ground content, excavate vm->m_data[vi] = MapNode(CONTENT_AIR); is_tunnel = true; diff --git a/src/mapgen_fractal.h b/src/mapgen_fractal.h index 93c29733..fd99032b 100644 --- a/src/mapgen_fractal.h +++ b/src/mapgen_fractal.h @@ -35,18 +35,16 @@ extern FlagDesc flagdesc_mapgen_fractal[]; struct MapgenFractalParams : public MapgenSpecificParams { u32 spflags; - + float cave_width; u16 fractal; u16 iterations; v3f scale; v3f offset; float slice_w; - float julia_x; float julia_y; float julia_z; float julia_w; - NoiseParams np_seabed; NoiseParams np_filler_depth; NoiseParams np_cave1; @@ -75,18 +73,16 @@ public: v3s16 full_node_max; u32 spflags; - + float cave_width; u16 fractal; u16 iterations; v3f scale; v3f offset; float slice_w; - float julia_x; float julia_y; float julia_z; float julia_w; - Noise *noise_seabed; Noise *noise_filler_depth; Noise *noise_cave1; diff --git a/src/mapgen_v5.cpp b/src/mapgen_v5.cpp index 657a0b86..01984825 100644 --- a/src/mapgen_v5.cpp +++ b/src/mapgen_v5.cpp @@ -63,7 +63,9 @@ MapgenV5::MapgenV5(int mapgenid, MapgenParams *params, EmergeManager *emerge) this->humidmap = NULL; MapgenV5Params *sp = (MapgenV5Params *)params->sparams; - this->spflags = sp->spflags; + + this->spflags = sp->spflags; + this->cave_width = sp->cave_width; // Terrain noise noise_filler_depth = new Noise(&sp->np_filler_depth, seed, csize.X, csize.Z); @@ -133,7 +135,8 @@ MapgenV5::~MapgenV5() MapgenV5Params::MapgenV5Params() { - spflags = 0; + spflags = 0; + cave_width = 0.125; np_filler_depth = NoiseParams(0, 1, v3f(150, 150, 150), 261, 4, 0.7, 2.0); np_factor = NoiseParams(0, 1, v3f(250, 250, 250), 920381, 3, 0.45, 2.0); @@ -150,7 +153,8 @@ MapgenV5Params::MapgenV5Params() void MapgenV5Params::readParams(const Settings *settings) { - settings->getFlagStrNoEx("mgv5_spflags", spflags, flagdesc_mapgen_v5); + settings->getFlagStrNoEx("mgv5_spflags", spflags, flagdesc_mapgen_v5); + settings->getFloatNoEx("mgv5_cave_width", cave_width); settings->getNoiseParams("mgv5_np_filler_depth", np_filler_depth); settings->getNoiseParams("mgv5_np_factor", np_factor); @@ -163,7 +167,8 @@ void MapgenV5Params::readParams(const Settings *settings) void MapgenV5Params::writeParams(Settings *settings) const { - settings->setFlagStr("mgv5_spflags", spflags, flagdesc_mapgen_v5, U32_MAX); + settings->setFlagStr("mgv5_spflags", spflags, flagdesc_mapgen_v5, U32_MAX); + settings->setFloat("mgv5_cave_width", cave_width); settings->setNoiseParams("mgv5_np_filler_depth", np_filler_depth); settings->setNoiseParams("mgv5_np_factor", np_factor); @@ -598,7 +603,7 @@ void MapgenV5::generateCaves(int max_stone_y) float d1 = contour(noise_cave1->result[index3d]); float d2 = contour(noise_cave2->result[index3d]); - if (d1 * d2 > 0.125f && ndef->get(c).is_ground_content) { + if (d1 * d2 > cave_width && ndef->get(c).is_ground_content) { // In tunnel and ground content, excavate vm->m_data[vi] = MapNode(CONTENT_AIR); is_tunnel = true; diff --git a/src/mapgen_v5.h b/src/mapgen_v5.h index 94fe6786..79cd4639 100644 --- a/src/mapgen_v5.h +++ b/src/mapgen_v5.h @@ -32,6 +32,7 @@ extern FlagDesc flagdesc_mapgen_v5[]; struct MapgenV5Params : public MapgenSpecificParams { u32 spflags; + float cave_width; NoiseParams np_filler_depth; NoiseParams np_factor; NoiseParams np_height; @@ -54,13 +55,14 @@ public: int ystride; int zstride_1d; - u32 spflags; v3s16 node_min; v3s16 node_max; v3s16 full_node_min; v3s16 full_node_max; + u32 spflags; + float cave_width; Noise *noise_filler_depth; Noise *noise_factor; Noise *noise_height; diff --git a/src/mapgen_v7.cpp b/src/mapgen_v7.cpp index bab95716..525199e8 100644 --- a/src/mapgen_v7.cpp +++ b/src/mapgen_v7.cpp @@ -71,7 +71,9 @@ MapgenV7::MapgenV7(int mapgenid, MapgenParams *params, EmergeManager *emerge) this->ridge_heightmap = new s16[csize.X * csize.Z]; MapgenV7Params *sp = (MapgenV7Params *)params->sparams; - this->spflags = sp->spflags; + + this->spflags = sp->spflags; + this->cave_width = sp->cave_width; //// Terrain noise noise_terrain_base = new Noise(&sp->np_terrain_base, seed, csize.X, csize.Z); @@ -152,7 +154,8 @@ MapgenV7::~MapgenV7() MapgenV7Params::MapgenV7Params() { - spflags = MGV7_MOUNTAINS | MGV7_RIDGES; + spflags = MGV7_MOUNTAINS | MGV7_RIDGES; + cave_width = 0.3; np_terrain_base = NoiseParams(4, 70, v3f(600, 600, 600), 82341, 5, 0.6, 2.0); np_terrain_alt = NoiseParams(4, 25, v3f(600, 600, 600), 5934, 5, 0.6, 2.0); @@ -170,7 +173,8 @@ MapgenV7Params::MapgenV7Params() void MapgenV7Params::readParams(const Settings *settings) { - settings->getFlagStrNoEx("mgv7_spflags", spflags, flagdesc_mapgen_v7); + settings->getFlagStrNoEx("mgv7_spflags", spflags, flagdesc_mapgen_v7); + settings->getFloatNoEx("mgv7_cave_width", cave_width); settings->getNoiseParams("mgv7_np_terrain_base", np_terrain_base); settings->getNoiseParams("mgv7_np_terrain_alt", np_terrain_alt); @@ -188,7 +192,8 @@ void MapgenV7Params::readParams(const Settings *settings) void MapgenV7Params::writeParams(Settings *settings) const { - settings->setFlagStr("mgv7_spflags", spflags, flagdesc_mapgen_v7, U32_MAX); + settings->setFlagStr("mgv7_spflags", spflags, flagdesc_mapgen_v7, U32_MAX); + settings->setFloat("mgv7_cave_width", cave_width); settings->setNoiseParams("mgv7_np_terrain_base", np_terrain_base); settings->setNoiseParams("mgv7_np_terrain_alt", np_terrain_alt); @@ -735,7 +740,7 @@ void MapgenV7::generateCaves(s16 max_stone_y) float d1 = contour(noise_cave1->result[index3d]); float d2 = contour(noise_cave2->result[index3d]); - if (d1 * d2 > 0.3f && ndef->get(c).is_ground_content) { + if (d1 * d2 > cave_width && ndef->get(c).is_ground_content) { // In tunnel and ground content, excavate vm->m_data[vi] = MapNode(CONTENT_AIR); is_tunnel = true; diff --git a/src/mapgen_v7.h b/src/mapgen_v7.h index 48f14d3c..d5441ded 100644 --- a/src/mapgen_v7.h +++ b/src/mapgen_v7.h @@ -34,6 +34,7 @@ extern FlagDesc flagdesc_mapgen_v7[]; struct MapgenV7Params : public MapgenSpecificParams { u32 spflags; + float cave_width; NoiseParams np_terrain_base; NoiseParams np_terrain_alt; NoiseParams np_terrain_persist; @@ -61,7 +62,6 @@ public: int ystride; int zstride_1u1d; int zstride_1d; - u32 spflags; v3s16 node_min; v3s16 node_max; @@ -70,6 +70,8 @@ public: s16 *ridge_heightmap; + u32 spflags; + float cave_width; Noise *noise_terrain_base; Noise *noise_terrain_alt; Noise *noise_terrain_persist; diff --git a/src/mapgen_valleys.cpp b/src/mapgen_valleys.cpp index af2e5f53..e4b1efb1 100644 --- a/src/mapgen_valleys.cpp +++ b/src/mapgen_valleys.cpp @@ -86,25 +86,16 @@ MapgenValleys::MapgenValleys(int mapgenid, MapgenParams *params, EmergeManager * g_settings->getU16("map_generation_limit")); MapgenValleysParams *sp = (MapgenValleysParams *)params->sparams; - this->spflags = sp->spflags; - - this->humid_rivers = (spflags & MGVALLEYS_HUMID_RIVERS); - this->use_altitude_chill = (spflags & MGVALLEYS_ALT_CHILL); + this->spflags = sp->spflags; this->altitude_chill = sp->altitude_chill; - this->humidity_adjust = params->np_biome_humidity.offset - 50.f; this->large_cave_depth = sp->large_cave_depth; this->lava_features_lim = rangelim(sp->lava_features, 0, 10); this->massive_cave_depth = sp->massive_cave_depth; this->river_depth_bed = sp->river_depth + 1.f; this->river_size_factor = sp->river_size / 100.f; this->water_features_lim = rangelim(sp->water_features, 0, 10); - - // a small chance of overflows if the settings are very high - this->cave_water_max_height = water_level + MYMAX(0, water_features_lim - 4) * 50; - this->lava_max_height = water_level + MYMAX(0, lava_features_lim - 4) * 50; - - tcave_cache = new float[csize.Y + 2]; + this->cave_width = sp->cave_width; //// 2D Terrain noise noise_filler_depth = new Noise(&sp->np_filler_depth, seed, csize.X, csize.Z); @@ -128,6 +119,16 @@ MapgenValleys::MapgenValleys(int mapgenid, MapgenParams *params, EmergeManager * noise_humidity_blend = new Noise(¶ms->np_biome_humidity_blend, seed, csize.X, csize.Z); noise_humidity = new Noise(¶ms->np_biome_humidity, seed, csize.X, csize.Z); + this->humid_rivers = (spflags & MGVALLEYS_HUMID_RIVERS); + this->use_altitude_chill = (spflags & MGVALLEYS_ALT_CHILL); + this->humidity_adjust = params->np_biome_humidity.offset - 50.f; + + // a small chance of overflows if the settings are very high + this->cave_water_max_height = water_level + MYMAX(0, water_features_lim - 4) * 50; + this->lava_max_height = water_level + MYMAX(0, lava_features_lim - 4) * 50; + + tcave_cache = new float[csize.Y + 2]; + //// Resolve nodes to be used INodeDefManager *ndef = emerge->ndef; @@ -165,10 +166,6 @@ MapgenValleys::~MapgenValleys() delete noise_cave1; delete noise_cave2; delete noise_filler_depth; - delete noise_heat; - delete noise_heat_blend; - delete noise_humidity; - delete noise_humidity_blend; delete noise_inter_valley_fill; delete noise_inter_valley_slope; delete noise_rivers; @@ -177,6 +174,11 @@ MapgenValleys::~MapgenValleys() delete noise_valley_depth; delete noise_valley_profile; + delete noise_heat; + delete noise_heat_blend; + delete noise_humidity; + delete noise_humidity_blend; + delete[] biomemap; delete[] heightmap; delete[] tcave_cache; @@ -185,8 +187,7 @@ MapgenValleys::~MapgenValleys() MapgenValleysParams::MapgenValleysParams() { - spflags = MGVALLEYS_HUMID_RIVERS | MGVALLEYS_ALT_CHILL; - + spflags = MGVALLEYS_HUMID_RIVERS | MGVALLEYS_ALT_CHILL; altitude_chill = 90; // The altitude at which temperature drops by 20C. large_cave_depth = -33; lava_features = 0; // How often water will occur in caves. @@ -194,6 +195,7 @@ MapgenValleysParams::MapgenValleysParams() river_depth = 4; // How deep to carve river channels. river_size = 5; // How wide to make rivers. water_features = 0; // How often water will occur in caves. + cave_width = 0.3; np_cave1 = NoiseParams(0, 12, v3f(96, 96, 96), 52534, 4, 0.5, 2.0); np_cave2 = NoiseParams(0, 12, v3f(96, 96, 96), 10325, 4, 0.5, 2.0); @@ -205,56 +207,56 @@ MapgenValleysParams::MapgenValleysParams() np_terrain_height = NoiseParams(-10.f, 50.f, v3f(1024, 1024, 1024), 5202, 6, 0.4f, 2.f); np_valley_depth = NoiseParams(5.f, 4.f, v3f(512, 512, 512), -1914, 1, 1.f, 2.f); np_valley_profile = NoiseParams(0.6f, 0.5f, v3f(512, 512, 512), 777, 1, 1.f, 2.f); - } +} void MapgenValleysParams::readParams(const Settings *settings) { - settings->getFlagStrNoEx("mg_valleys_spflags", spflags, flagdesc_mapgen_valleys); + settings->getFlagStrNoEx("mgvalleys_spflags", spflags, flagdesc_mapgen_valleys); + settings->getU16NoEx("mgvalleys_altitude_chill", altitude_chill); + settings->getS16NoEx("mgvalleys_large_cave_depth", large_cave_depth); + settings->getU16NoEx("mgvalleys_lava_features", lava_features); + settings->getS16NoEx("mgvalleys_massive_cave_depth", massive_cave_depth); + settings->getU16NoEx("mgvalleys_river_depth", river_depth); + settings->getU16NoEx("mgvalleys_river_size", river_size); + settings->getU16NoEx("mgvalleys_water_features", water_features); + settings->getFloatNoEx("mgvalleys_cave_width", cave_width); - settings->getU16NoEx("mg_valleys_altitude_chill", altitude_chill); - settings->getS16NoEx("mg_valleys_large_cave_depth", large_cave_depth); - settings->getU16NoEx("mg_valleys_lava_features", lava_features); - settings->getS16NoEx("mg_valleys_massive_cave_depth", massive_cave_depth); - settings->getU16NoEx("mg_valleys_river_depth", river_depth); - settings->getU16NoEx("mg_valleys_river_size", river_size); - settings->getU16NoEx("mg_valleys_water_features", water_features); - - settings->getNoiseParams("mg_valleys_np_cave1", np_cave1); - settings->getNoiseParams("mg_valleys_np_cave2", np_cave2); - settings->getNoiseParams("mg_valleys_np_filler_depth", np_filler_depth); - settings->getNoiseParams("mg_valleys_np_inter_valley_fill", np_inter_valley_fill); - settings->getNoiseParams("mg_valleys_np_inter_valley_slope", np_inter_valley_slope); - settings->getNoiseParams("mg_valleys_np_rivers", np_rivers); - settings->getNoiseParams("mg_valleys_np_massive_caves", np_massive_caves); - settings->getNoiseParams("mg_valleys_np_terrain_height", np_terrain_height); - settings->getNoiseParams("mg_valleys_np_valley_depth", np_valley_depth); - settings->getNoiseParams("mg_valleys_np_valley_profile", np_valley_profile); + settings->getNoiseParams("mgvalleys_np_cave1", np_cave1); + settings->getNoiseParams("mgvalleys_np_cave2", np_cave2); + settings->getNoiseParams("mgvalleys_np_filler_depth", np_filler_depth); + settings->getNoiseParams("mgvalleys_np_inter_valley_fill", np_inter_valley_fill); + settings->getNoiseParams("mgvalleys_np_inter_valley_slope", np_inter_valley_slope); + settings->getNoiseParams("mgvalleys_np_rivers", np_rivers); + settings->getNoiseParams("mgvalleys_np_massive_caves", np_massive_caves); + settings->getNoiseParams("mgvalleys_np_terrain_height", np_terrain_height); + settings->getNoiseParams("mgvalleys_np_valley_depth", np_valley_depth); + settings->getNoiseParams("mgvalleys_np_valley_profile", np_valley_profile); } void MapgenValleysParams::writeParams(Settings *settings) const { - settings->setFlagStr("mg_valleys_spflags", spflags, flagdesc_mapgen_valleys, U32_MAX); + settings->setFlagStr("mgvalleys_spflags", spflags, flagdesc_mapgen_valleys, U32_MAX); + settings->setU16("mgvalleys_altitude_chill", altitude_chill); + settings->setS16("mgvalleys_large_cave_depth", large_cave_depth); + settings->setU16("mgvalleys_lava_features", lava_features); + settings->setS16("mgvalleys_massive_cave_depth", massive_cave_depth); + settings->setU16("mgvalleys_river_depth", river_depth); + settings->setU16("mgvalleys_river_size", river_size); + settings->setU16("mgvalleys_water_features", water_features); + settings->setFloat("mgvalleys_cave_width", cave_width); - settings->setU16("mg_valleys_altitude_chill", altitude_chill); - settings->setS16("mg_valleys_large_cave_depth", large_cave_depth); - settings->setU16("mg_valleys_lava_features", lava_features); - settings->setS16("mg_valleys_massive_cave_depth", massive_cave_depth); - settings->setU16("mg_valleys_river_depth", river_depth); - settings->setU16("mg_valleys_river_size", river_size); - settings->setU16("mg_valleys_water_features", water_features); - - settings->setNoiseParams("mg_valleys_np_cave1", np_cave1); - settings->setNoiseParams("mg_valleys_np_cave2", np_cave2); - settings->setNoiseParams("mg_valleys_np_filler_depth", np_filler_depth); - settings->setNoiseParams("mg_valleys_np_inter_valley_fill", np_inter_valley_fill); - settings->setNoiseParams("mg_valleys_np_inter_valley_slope", np_inter_valley_slope); - settings->setNoiseParams("mg_valleys_np_rivers", np_rivers); - settings->setNoiseParams("mg_valleys_np_massive_caves", np_massive_caves); - settings->setNoiseParams("mg_valleys_np_terrain_height", np_terrain_height); - settings->setNoiseParams("mg_valleys_np_valley_depth", np_valley_depth); - settings->setNoiseParams("mg_valleys_np_valley_profile", np_valley_profile); + settings->setNoiseParams("mgvalleys_np_cave1", np_cave1); + settings->setNoiseParams("mgvalleys_np_cave2", np_cave2); + settings->setNoiseParams("mgvalleys_np_filler_depth", np_filler_depth); + settings->setNoiseParams("mgvalleys_np_inter_valley_fill", np_inter_valley_fill); + settings->setNoiseParams("mgvalleys_np_inter_valley_slope", np_inter_valley_slope); + settings->setNoiseParams("mgvalleys_np_rivers", np_rivers); + settings->setNoiseParams("mgvalleys_np_massive_caves", np_massive_caves); + settings->setNoiseParams("mgvalleys_np_terrain_height", np_terrain_height); + settings->setNoiseParams("mgvalleys_np_valley_depth", np_valley_depth); + settings->setNoiseParams("mgvalleys_np_valley_profile", np_valley_profile); } @@ -964,7 +966,7 @@ void MapgenValleys::generateCaves(s16 max_stone_y) // when a tunnel undercuts a river. However, that's not for // the mapgen to correct. Fix it in lua. - if (d1 * d2 > 0.3f && ndef->get(c).is_ground_content) { + if (d1 * d2 > cave_width && ndef->get(c).is_ground_content) { // in a tunnel vm->m_data[index_data] = n_air; tunnel_air_above = true; diff --git a/src/mapgen_valleys.h b/src/mapgen_valleys.h index 65b31e98..30ee4981 100644 --- a/src/mapgen_valleys.h +++ b/src/mapgen_valleys.h @@ -47,7 +47,6 @@ class BiomeManager; struct MapgenValleysParams : public MapgenSpecificParams { u32 spflags; - s16 large_cave_depth; s16 massive_cave_depth; u16 altitude_chill; @@ -55,11 +54,7 @@ struct MapgenValleysParams : public MapgenSpecificParams { u16 river_depth; u16 river_size; u16 water_features; - - NoiseParams np_biome_heat; - NoiseParams np_biome_heat_blend; - NoiseParams np_biome_humidity; - NoiseParams np_biome_humidity_blend; + float cave_width; NoiseParams np_cave1; NoiseParams np_cave2; NoiseParams np_filler_depth; @@ -110,23 +105,29 @@ private: float map_gen_limit; - u32 spflags; bool humid_rivers; bool use_altitude_chill; + float humidity_adjust; + s16 cave_water_max_height; + s16 lava_max_height; v3s16 node_min; v3s16 node_max; v3s16 full_node_min; v3s16 full_node_max; + u32 spflags; + float altitude_chill; + s16 lava_features_lim; + s16 massive_cave_depth; + float river_depth_bed; + float river_size_factor; + float *tcave_cache; + s16 water_features_lim; + float cave_width; Noise *noise_filler_depth; - Noise *noise_cave1; Noise *noise_cave2; - Noise *noise_heat; - Noise *noise_heat_blend; - Noise *noise_humidity; - Noise *noise_humidity_blend; Noise *noise_inter_valley_fill; Noise *noise_inter_valley_slope; Noise *noise_rivers; @@ -135,16 +136,10 @@ private: Noise *noise_valley_depth; Noise *noise_valley_profile; - float altitude_chill; - s16 cave_water_max_height; - float humidity_adjust; - s16 lava_features_lim; - s16 lava_max_height; - s16 massive_cave_depth; - float river_depth_bed; - float river_size_factor; - float *tcave_cache; - s16 water_features_lim; + Noise *noise_heat; + Noise *noise_heat_blend; + Noise *noise_humidity; + Noise *noise_humidity_blend; content_t c_cobble; content_t c_desert_stone; diff --git a/src/server.cpp b/src/server.cpp index 0bfeb045..a0d16f99 100644 --- a/src/server.cpp +++ b/src/server.cpp @@ -3187,19 +3187,7 @@ u32 Server::addParticleSpawner(u16 amount, float spawntime, peer_id = player->peer_id; } - u32 id = 0; - for(;;) // look for unused particlespawner id - { - id++; - if (std::find(m_particlespawner_ids.begin(), - m_particlespawner_ids.end(), id) - == m_particlespawner_ids.end()) - { - m_particlespawner_ids.push_back(id); - break; - } - } - + u32 id = m_env->addParticleSpawner(spawntime); SendAddParticleSpawner(peer_id, amount, spawntime, minpos, maxpos, minvel, maxvel, minacc, maxacc, minexptime, maxexptime, minsize, maxsize, @@ -3222,13 +3210,16 @@ void Server::deleteParticleSpawner(const std::string &playername, u32 id) peer_id = player->peer_id; } - m_particlespawner_ids.erase( - std::remove(m_particlespawner_ids.begin(), - m_particlespawner_ids.end(), id), - m_particlespawner_ids.end()); + m_env->deleteParticleSpawner(id); SendDeleteParticleSpawner(peer_id, id); } +void Server::deleteParticleSpawnerAll(u32 id) +{ + m_env->deleteParticleSpawner(id); + SendDeleteParticleSpawner(PEER_ID_INEXISTENT, id); +} + Inventory* Server::createDetachedInventory(const std::string &name) { if(m_detached_inventories.count(name) > 0){ diff --git a/src/server.h b/src/server.h index b5f6684c..0568a7bf 100644 --- a/src/server.h +++ b/src/server.h @@ -287,6 +287,7 @@ public: const std::string &playername); void deleteParticleSpawner(const std::string &playername, u32 id); + void deleteParticleSpawnerAll(u32 id); // Creates or resets inventory Inventory* createDetachedInventory(const std::string &name); @@ -662,11 +663,6 @@ private: // key = name std::map m_detached_inventories; - /* - Particles - */ - std::vector m_particlespawner_ids; - DISABLE_CLASS_COPY(Server); }; diff --git a/src/threading/thread.cpp b/src/threading/thread.cpp index 8688c4cb..ecf8563f 100644 --- a/src/threading/thread.cpp +++ b/src/threading/thread.cpp @@ -116,9 +116,7 @@ bool Thread::start() #if USE_CPP11_THREADS try { - m_thread_obj = new std::thread(threadProc, this); - m_thread_id = m_thread_obj->get_id(); - m_thread_handle = m_thread_obj->native_handle(); + m_thread_obj = new std::thread(threadProc, this); } catch (const std::system_error &e) { return false; } @@ -135,8 +133,6 @@ bool Thread::start() if (status) return false; - m_thread_id = m_thread_handle; - #endif while (!m_running) @@ -234,12 +230,6 @@ bool Thread::getReturnValue(void **ret) } -bool Thread::isCurrentThread() -{ - return thr_is_current_thread(m_thread_id); -} - - #if USE_CPP11_THREADS || USE_POSIX_THREADS void *Thread::threadProc(void *param) #elif defined(_WIN32_WCE) diff --git a/src/threading/thread.h b/src/threading/thread.h index 6a24afff..10732c44 100644 --- a/src/threading/thread.h +++ b/src/threading/thread.h @@ -90,12 +90,22 @@ public: /* * Returns true if the calling thread is this Thread object. */ - bool isCurrentThread(); + bool isCurrentThread() { return thr_is_current_thread(getThreadId()); } inline bool isRunning() { return m_running; } inline bool stopRequested() { return m_request_stop; } + +#if USE_CPP11_THREADS + inline threadid_t getThreadId() { return m_thread_obj->get_id(); } + inline threadhandle_t getThreadHandle() { return m_thread_obj->native_handle(); } +#else +# if USE_WIN_THREADS inline threadid_t getThreadId() { return m_thread_id; } +# else + inline threadid_t getThreadId() { return m_thread_handle; } +# endif inline threadhandle_t getThreadHandle() { return m_thread_handle; } +#endif /* * Gets the thread return value. @@ -147,8 +157,12 @@ private: Atomic m_running; Mutex m_mutex; - threadid_t m_thread_id; +#if !USE_CPP11_THREADS threadhandle_t m_thread_handle; +#if _WIN32 + threadid_t m_thread_id; +#endif +#endif static ThreadStartFunc threadProc; diff --git a/src/unittest/test_utilities.cpp b/src/unittest/test_utilities.cpp index e004a9c9..608c7a40 100644 --- a/src/unittest/test_utilities.cpp +++ b/src/unittest/test_utilities.cpp @@ -45,6 +45,7 @@ public: void testStringAllowed(); void testAsciiPrintableHelper(); void testUTF8(); + void testRemoveEscapes(); void testWrapRows(); void testIsNumber(); void testIsPowerOfTwo(); @@ -71,6 +72,7 @@ void TestUtilities::runTests(IGameDef *gamedef) TEST(testStringAllowed); TEST(testAsciiPrintableHelper); TEST(testUTF8); + TEST(testRemoveEscapes); TEST(testWrapRows); TEST(testIsNumber); TEST(testIsPowerOfTwo); @@ -253,6 +255,23 @@ void TestUtilities::testUTF8() == "the shovel dug a crumbly node!"); } +void TestUtilities::testRemoveEscapes() +{ + UASSERT(unescape_enriched( + L"abc\x1bXdef") == L"abcdef"); + UASSERT(unescape_enriched( + L"abc\x1b(escaped)def") == L"abcdef"); + UASSERT(unescape_enriched( + L"abc\x1b((escaped with parenthesis\\))def") == L"abcdef"); + UASSERT(unescape_enriched( + L"abc\x1b(incomplete") == L"abc"); + UASSERT(unescape_enriched( + L"escape at the end\x1b") == L"escape at the end"); + // Nested escapes not supported + UASSERT(unescape_enriched( + L"abc\x1b(outer \x1b(inner escape)escape)def") == L"abcescape)def"); +} + void TestUtilities::testWrapRows() { UASSERT(wrap_rows("12345678",4) == "1234\n5678"); diff --git a/src/util/string.cpp b/src/util/string.cpp index 6762f482..865020c4 100644 --- a/src/util/string.cpp +++ b/src/util/string.cpp @@ -729,33 +729,6 @@ static bool parseNamedColorString(const std::string &value, video::SColor &color return true; } -std::wstring removeChatEscapes(const std::wstring &s) { - std::wstring output; - size_t i = 0; - while (i < s.length()) { - if (s[i] == L'\v') { - ++i; - if (i == s.length()) continue; - if (s[i] == L'(') { - ++i; - while (i < s.length() && s[i] != L')') { - if (s[i] == L'\\') { - ++i; - } - ++i; - } - ++i; - } else { - ++i; - } - continue; - } - output += s[i]; - ++i; - } - return output; -} - void str_replace(std::string &str, char from, char to) { std::replace(str.begin(), str.end(), from, to); diff --git a/src/util/string.h b/src/util/string.h index d28a386c..0a2125bb 100644 --- a/src/util/string.h +++ b/src/util/string.h @@ -386,14 +386,6 @@ inline void str_replace(std::string &str, const std::string &pattern, } } -/** - * Remove all chat escape sequences in \p s. - * - * @param s The string in which to remove escape sequences. - * @return \p s, with escape sequences removed. - */ -std::wstring removeChatEscapes(const std::wstring &s); - /** * Replace all occurrences of the character \p from in \p str with \p to. * @@ -476,7 +468,7 @@ inline std::string wrap_rows(const std::string &from, * Removes backslashes from an escaped string (FormSpec strings) */ template -inline std::basic_string unescape_string(std::basic_string &s) +inline std::basic_string unescape_string(const std::basic_string &s) { std::basic_string res; @@ -492,6 +484,40 @@ inline std::basic_string unescape_string(std::basic_string &s) return res; } +/** + * Remove all escape sequences in \p s. + * + * @param s The string in which to remove escape sequences. + * @return \p s, with escape sequences removed. + */ +template +std::basic_string unescape_enriched(const std::basic_string &s) +{ + std::basic_string output; + size_t i = 0; + while (i < s.length()) { + if (s[i] == '\x1b') { + ++i; + if (i == s.length()) continue; + if (s[i] == '(') { + ++i; + while (i < s.length() && s[i] != ')') { + if (s[i] == '\\') { + ++i; + } + ++i; + } + ++i; + } else { + ++i; + } + continue; + } + output += s[i]; + ++i; + } + return output; +} /** * Checks that all characters in \p to_check are a decimal digits. diff --git a/util/bump_version.sh b/util/bump_version.sh index 51e76491..e19534a9 100755 --- a/util/bump_version.sh +++ b/util/bump_version.sh @@ -32,12 +32,12 @@ cd ${0%/*}/.. grep -q -E '^set\(VERSION_MAJOR [0-9]+\)$' CMakeLists.txt || die "error: Could not find CMakeLists.txt" grep -q -E '^set\(VERSION_MINOR [0-9]+\)$' CMakeLists.txt || die "error: Could not find CMakeLists.txt" grep -q -E '^set\(VERSION_PATCH [0-9]+\)$' CMakeLists.txt || die "error: Could not find CMakeLists.txt" -grep -q -E '^ANDROID_VERSION_CODE = [0-9]+$' build/android/Makefile || die "error: Could not find build/android/Makefile" +grep -q -E 'versionCode [0-9]+$' build/android/build.gradle || die "error: Could not find Android version code" VERSION_MAJOR=$(grep -E '^set\(VERSION_MAJOR [0-9]+\)$' CMakeLists.txt | tr -dC 0-9) VERSION_MINOR=$(grep -E '^set\(VERSION_MINOR [0-9]+\)$' CMakeLists.txt | tr -dC 0-9) VERSION_PATCH=$(grep -E '^set\(VERSION_PATCH [0-9]+\)$' CMakeLists.txt | tr -dC 0-9) -ANDROID_VERSION_CODE=$(grep -E '^ANDROID_VERSION_CODE = [0-9]+$' build/android/Makefile | tr -dC 0-9) +ANDROID_VERSION_CODE=$(grep -E 'versionCode [0-9]+$' build/android/build.gradle | tr -dC 0-9) echo "Current MultiCraft version: $VERSION_MAJOR.$VERSION_MINOR.$VERSION_PATCH" echo "Current Android version code: $ANDROID_VERSION_CODE" @@ -89,13 +89,13 @@ sed -i -re "s/^set\(VERSION_PATCH [0-9]+\)$/set(VERSION_PATCH $NEW_VERSION_PATCH sed -i -re "s/^set\(DEVELOPMENT_BUILD TRUE\)$/set(DEVELOPMENT_BUILD FALSE)/" CMakeLists.txt || die "Failed to unset DEVELOPMENT_BUILD" -sed -i -re "s/^ANDROID_VERSION_CODE = [0-9]+$/ANDROID_VERSION_CODE = $NEW_ANDROID_VERSION_CODE/" build/android/Makefile || die "Failed to update ANDROID_VERSION_CODE" +sed -i -re "s/versionCode [0-9]+$/versionCode $NEW_ANDROID_VERSION_CODE/" build/android/build.gradle || die "Failed to update Android version code" sed -i -re "1s/[0-9]+\.[0-9]+\.[0-9]+/$NEW_VERSION/g" doc/lua_api.txt || die "Failed to update doc/lua_api.txt" sed -i -re "1s/[0-9]+\.[0-9]+\.[0-9]+/$NEW_VERSION/g" doc/menu_lua_api.txt || die "Failed to update doc/menu_lua_api.txt" -git add -f CMakeLists.txt build/android/Makefile doc/lua_api.txt doc/menu_lua_api.txt || die "git add failed" +git add -f CMakeLists.txt build/android/build.gradle doc/lua_api.txt doc/menu_lua_api.txt || die "git add failed" git commit -m "Bump version to $NEW_VERSION" || die "git commit failed"