diff --git a/changeAppSettings.sh b/changeAppSettings.sh index f4bee0b99..06e8b338d 100755 --- a/changeAppSettings.sh +++ b/changeAppSettings.sh @@ -891,6 +891,8 @@ rm -rf project/$OUT/local/*/objs*/sdl-*/src/*/android rm -rf project/$OUT/local/*/objs*/sdl-*/src/video/SDL_video.o rm -rf project/$OUT/local/*/objs*/sdl-*/SDL_renderer_gles.o rm -rf project/$OUT/local/*/objs*/sdl_* +rm -rf project/obj/local/*/objs*/lzma/src/XZInputStream.o +rm -rf project/obj/local/*/objs*/liblzma.so # Do not rebuild several huge libraries that do not depend on SDL version for LIB in freetype intl jpeg png lua mad tremor xerces xml2 curl lua mikmod \ boost boost_signals boost_thread boost_filesystem boost_date_time boost_system boost_regex boost_iostreams boost_program_options \ diff --git a/project/java/DataDownloader.java b/project/java/DataDownloader.java index 82b28dd78..c2e16e81a 100644 --- a/project/java/DataDownloader.java +++ b/project/java/DataDownloader.java @@ -55,13 +55,11 @@ import java.io.InputStream; import android.content.Context; import android.content.res.Resources; -import java.lang.String; +import java.util.Arrays; import android.text.SpannedString; import android.app.AlertDialog; import android.content.DialogInterface; -import org.tukaani.xz.XZInputStream; - class CountingInputStream extends BufferedInputStream { @@ -587,6 +585,8 @@ class DataDownloader extends Thread if (url.endsWith(".zip.xz") || url.endsWith(".zip.xz/download")) try { + if (!Arrays.asList(Globals.AppLibraries).contains("lzma")) + throw new IOException("LZMA support not compiled in - add lzma to CompiledLibraries inside AndroidAppSettings.cfg"); zip = new ZipInputStream(new XZInputStream(stream)); } catch (Exception eeeee) diff --git a/project/java/XZInputStream.java b/project/java/XZInputStream.java new file mode 100644 index 000000000..2563a190e --- /dev/null +++ b/project/java/XZInputStream.java @@ -0,0 +1,160 @@ +/* +Simple DirectMedia Layer +Java source code (C) 2009-2014 Sergii Pylypenko + +This software is provided 'as-is', without any express or implied +warranty. In no event will the authors be held liable for any damages +arising from the use of this software. + +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it +freely, subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +package net.sourceforge.clonekeenplus; + +import java.io.InputStream; +import java.io.DataInputStream; +import java.io.IOException; +import java.io.EOFException; +import android.util.Log; + +/** + * Decompresses a .xz file in streamed mode (no seeking). + * This is a copy of code from http://git.tukaani.org/xz-java.git + * but using liblzma and JNI instead of Java, because Java heap + * is very limited, and we're hitting memory limit on emulator. + */ +public class XZInputStream extends InputStream +{ + private long nativeData = 0; + private InputStream in = null; + private final byte[] inBuf = new byte[8192]; + private int inOffset = 0; + private int inAvailable = 0; + private boolean outBufEof = false; + private int offsets[] = new int[2]; + + private final byte[] tempBuf = new byte[1]; + + public XZInputStream(InputStream in) throws IOException + { + this.in = in; + if (in == null) + { + throw new NullPointerException("InputStream == null"); + } + nativeData = nativeInit(); + if (nativeData == 0) + { + throw new OutOfMemoryError("Cannot initialize JNI liblzma object"); + } + } + + @Override + public int available() throws IOException + { + return 0; // Don't care + } + + @Override + public void close() throws IOException + { + synchronized (this) + { + if (nativeData != 0) + nativeClose(nativeData); + nativeData = 0; + if (in != null) + { + try { + in.close(); + } finally { + in = null; + } + } + } + } + + @Override + protected void finalize() throws IOException + { + try { + close(); + } finally { + try { + super.finalize(); + } catch (Throwable t) { + throw new AssertionError(t); + } + } + } + + @Override + public int read() throws IOException + { + return read(tempBuf, 0, 1) == -1 ? -1 : (tempBuf[0] & 0xFF); + } + + @Override + public int read(byte[] outBuf, int outOffset, int outCount) throws IOException + { + //Log.i("SDL", "XZInputStream.read: outOffset " + outOffset + " outCount " + outCount + " outBufEof " + outBufEof + + // " inOffset " + inOffset + " inAvailable " + inAvailable); + if (outBufEof) + return -1; + if (outCount <= 0) + return 0; + + int oldOutOffset = outOffset; + + if (inOffset >= inAvailable && inAvailable != -1) + { + inAvailable = in.read(inBuf, 0, inBuf.length); + inOffset = 0; + //Log.i("SDL", "XZInputStream.read: in.read: inOffset " + inOffset + " inAvailable " + inAvailable); + } + + offsets[0] = inOffset; + offsets[1] = outOffset; + int ret = nativeRead(nativeData, inBuf, inAvailable, outBuf, outCount, offsets); + inOffset = offsets[0]; + outOffset = offsets[1]; + //Log.i("SDL", "XZInputStream.read: nativeRead: outOffset " + outOffset + " outCount " + outCount + " outBufEof " + outBufEof + + // " inOffset " + inOffset + " inAvailable " + inAvailable + " ret " + ret); + + if (ret != 0) + { + if (ret == 1) + { + if (inOffset < inAvailable) + throw new IOException("Garbage at the end of LZMA stream"); + if (inAvailable != -1) + inAvailable = in.read(inBuf, 0, inBuf.length); + if (inAvailable != -1) + throw new IOException("Garbage at the end of LZMA stream"); + outBufEof = true; + } + else + { + throw new IOException("LZMA error " + ret); + } + } + + //Log.i("SDL", "XZInputStream.read: returning " + (outOffset - oldOutOffset)); + return outOffset - oldOutOffset; + } + + private native long nativeInit(); + private native void nativeClose(long nativeData); + private native int nativeRead(long nativeData, byte[] inBuf, int inAvailable, byte[] outBuf, int outCount, int[] offsets); +} + diff --git a/project/jni/application/openttd/AndroidAppSettings.cfg b/project/jni/application/openttd/AndroidAppSettings.cfg index f3584966f..7fd35788e 100644 --- a/project/jni/application/openttd/AndroidAppSettings.cfg +++ b/project/jni/application/openttd/AndroidAppSettings.cfg @@ -213,7 +213,7 @@ FirstStartMenuOptions='' # Specify architectures to compile, 'all' or 'y' to compile for all architectures. # Available architectures: armeabi armeabi-v7a armeabi-v7a-hard x86 mips -MultiABI='armeabi-v7a x86' +MultiABI='x86' #armeabi-v7a x86 # Minimum amount of RAM application requires, in Mb, SDL will print warning to user if it's lower AppMinimumRAM=0 diff --git a/project/jni/application/openttd/src b/project/jni/application/openttd/src index 248b1a2c7..a7c276641 160000 --- a/project/jni/application/openttd/src +++ b/project/jni/application/openttd/src @@ -1 +1 @@ -Subproject commit 248b1a2c71cc084e78dcde86872de690f4886be8 +Subproject commit a7c2766411ed76b6385400ae42201c2b57055fc7 diff --git a/project/jni/lzma/Android.mk b/project/jni/lzma/Android.mk index 24ea1ff15..266a787ea 100644 --- a/project/jni/lzma/Android.mk +++ b/project/jni/lzma/Android.mk @@ -7,8 +7,7 @@ LOCAL_MODULE := lzma APP_SUBDIRS := $(patsubst $(LOCAL_PATH)/%, %, $(shell find $(LOCAL_PATH)/src -type d)) LOCAL_C_INCLUDES := $(foreach D, $(APP_SUBDIRS), $(LOCAL_PATH)/$(D)) $(LOCAL_PATH)/include -LOCAL_CFLAGS := -O3 -DHAVE_CONFIG_H -DTUKLIB_SYMBOL_PREFIX=lzma_ -std=c99 # Enable "restrict" keyword - +LOCAL_CFLAGS := -O3 -DHAVE_CONFIG_H -DTUKLIB_SYMBOL_PREFIX=lzma_ -std=c99 -DSDL_JAVA_PACKAGE_PATH=$(SDL_JAVA_PACKAGE_PATH) LOCAL_CPP_EXTENSION := .cpp diff --git a/project/jni/lzma/src/XZInputStream.c b/project/jni/lzma/src/XZInputStream.c new file mode 100644 index 000000000..dd36011e6 --- /dev/null +++ b/project/jni/lzma/src/XZInputStream.c @@ -0,0 +1,65 @@ +#include +#include +#include +#include +#include + +#include + +#include "lzma.h" + +#include "jniwrapperstuff.h" + +JNIEXPORT jlong JNICALL +JAVA_EXPORT_NAME(XZInputStream_nativeInit) (JNIEnv* env, jobject thiz) +{ + lzma_stream * stream = (lzma_stream *) malloc(sizeof(lzma_stream)); + lzma_stream tmp = LZMA_STREAM_INIT; + *stream = tmp; + int ret = lzma_stream_decoder(stream, UINT64_MAX, LZMA_CONCATENATED); + if (ret != LZMA_OK) + { + free(stream); + return 0; + } + return (jlong) (intptr_t) stream; +} + +JNIEXPORT void JNICALL +JAVA_EXPORT_NAME(XZInputStream_nativeClose) (JNIEnv* env, jobject thiz, jlong nativeData) +{ + lzma_stream * stream = (lzma_stream *) (intptr_t) nativeData; + lzma_end(stream); +} + +JNIEXPORT jint JNICALL +JAVA_EXPORT_NAME(XZInputStream_nativeRead) (JNIEnv* env, jobject thiz, jlong nativeData, + jobject inBuf, jint inAvailable, jobject outBuf, + jint outCount, jobject offsets) +{ + lzma_stream * stream = (lzma_stream *) (intptr_t) nativeData; + uint8_t *inBufNative = (uint8_t *) (*env)->GetPrimitiveArrayCritical(env, inBuf, NULL); + uint8_t *outBufNative = (uint8_t *) (*env)->GetPrimitiveArrayCritical(env, outBuf, NULL); + jint *offsetsNative = (jint *) (*env)->GetPrimitiveArrayCritical(env, offsets, NULL); + jint inOffset = offsetsNative[0]; + jint outOffset = offsetsNative[1]; + int ret; + + stream->avail_in = inAvailable - inOffset; + stream->next_in = inBufNative + inOffset; + stream->avail_out = outCount; + stream->next_out = outBufNative + outOffset; + ret = lzma_code(stream, inAvailable == -1 ? LZMA_FINISH : LZMA_RUN); + + (*env)->ReleasePrimitiveArrayCritical(env, offsets, offsetsNative, 0); + (*env)->ReleasePrimitiveArrayCritical(env, outBuf, outBufNative, 0); + (*env)->ReleasePrimitiveArrayCritical(env, inBuf, inBufNative, 0); + + inOffset = inAvailable - stream->avail_in; + outOffset += outCount - stream->avail_out; + + offsetsNative[0] = inOffset; + offsetsNative[1] = outOffset; + + return ret; +} diff --git a/project/libs/xz.jar b/project/libs/xz.jar deleted file mode 100644 index 39fa03d2d..000000000 Binary files a/project/libs/xz.jar and /dev/null differ diff --git a/todo.txt b/todo.txt index 8dbc9a977..139810e48 100644 --- a/todo.txt +++ b/todo.txt @@ -33,8 +33,6 @@ TODO, which will get actually done - OpenTTD: select from menu with two taps, not tap and hold. -- OpenTTD: two-finger continuous scrolling. - - OpenTTD: two-finger tap de-selects current tool and closes build station window. - OpenTTD: hide all windows when performing an action on the map, like laying tracks or creating station or selecting destination.