From 4f3665edef694e743d369d2e02e7048dd68ee3bb Mon Sep 17 00:00:00 2001 From: pelya Date: Fri, 18 Feb 2011 16:09:20 +0000 Subject: [PATCH] app2sd support for shared libraries --- ChangeAppSettings.sh | 6 +- app2sd.sh | 35 +++++ project/java/Globals.java | 6 +- project/java/MainActivity.java | 134 +++++++++++++++--- project/java/Video.java | 24 +++- .../fheroes2/AndroidAppSettings.cfg | 9 +- .../AndroidData/{data8.zip => data9.zip} | Bin 850252 -> 869389 bytes project/jni/application/src | 2 +- project/jni/sdl_main/sdl_main.c | 1 + readme.txt | 10 ++ 10 files changed, 197 insertions(+), 30 deletions(-) create mode 100755 app2sd.sh rename project/jni/application/fheroes2/AndroidData/{data8.zip => data9.zip} (97%) diff --git a/ChangeAppSettings.sh b/ChangeAppSettings.sh index 037bf215a8..23815d8e90 100755 --- a/ChangeAppSettings.sh +++ b/ChangeAppSettings.sh @@ -488,7 +488,7 @@ if [ "$MultiABI" = "y" ] ; then else MultiABI="armeabi" fi -LibrariesToLoad="System.loadLibrary(\\\"sdl-$LibSdlVersion\\\");" +LibrariesToLoad="\\\"sdl-$LibSdlVersion\\\"" StaticLibraries=`grep 'APP_AVAILABLE_STATIC_LIBS' project/jni/SettingsTemplate.mk | sed 's/.*=\(.*\)/\1/'` for lib in $CompiledLibraries; do process=true @@ -496,7 +496,7 @@ for lib in $CompiledLibraries; do if [ "$lib" = "$lib1" ]; then process=false; fi done if $process; then - LibrariesToLoad="$LibrariesToLoad System.loadLibrary(\\\"$lib\\\");" + LibrariesToLoad="$LibrariesToLoad, \\\"$lib\\\"" fi done @@ -545,7 +545,7 @@ cat project/src/Globals.java | \ sed "s/public static int AppTouchscreenKeyboardKeysAmountAutoFire = .*;/public static int AppTouchscreenKeyboardKeysAmountAutoFire = $AppTouchscreenKeyboardKeysAmountAutoFire;/" | \ sed "s%public static String ReadmeText = .*%public static String ReadmeText = \"$ReadmeText\".replace(\"^\",\"\\\n\");%" | \ sed "s%public static String CommandLine = .*%public static String CommandLine = \"$AppCmdline\";%" | \ - sed "s/public LoadLibrary() .*/public LoadLibrary() { $LibrariesToLoad };/" > \ + sed "s/public static String AppLibraries.*/public static String AppLibraries[] = { $LibrariesToLoad };/" > \ project/src/Globals.java.1 mv -f project/src/Globals.java.1 project/src/Globals.java diff --git a/app2sd.sh b/app2sd.sh new file mode 100755 index 0000000000..a2d1496e1d --- /dev/null +++ b/app2sd.sh @@ -0,0 +1,35 @@ +#!/bin/sh + +APK=$1 +if [ -z "$APK" ] ; then + APK=project/bin/DemoActivity-debug.apk +fi + +echo Moving shared libraries on $APK to SD card +APK=`pwd`/$APK + +[ -e $APK ] || { echo File $APK does not exist; exit 1; } + +TMPDIR=app2sd-$$ + +mkdir -p $TMPDIR +cd $TMPDIR + +unzip $APK "lib/armeabi/*" || { echo "This apk file has already been app2sd-ed, or improperly compiled"; exit 1; } + +zip -j bindata.zip lib/armeabi/* +mkdir assets +split -b 1048576 -d -a 1 bindata.zip assets/bindata +rm bindata.zip + +zip -d $APK "lib/armeabi/*" "META-INF/*" + +zip -0 $APK assets/bindata* + +jarsigner -verbose -keystore ~/.android/debug.keystore -storepass "android" $APK androiddebugkey + +zipalign 4 $APK $APK-tmp +mv -f $APK-tmp $APK + +cd .. +rm -rf $TMPDIR diff --git a/project/java/Globals.java b/project/java/Globals.java index e9930a1a7f..c5a1879dc5 100644 --- a/project/java/Globals.java +++ b/project/java/Globals.java @@ -9,6 +9,8 @@ class Globals { public static String ApplicationName = "CommanderGenius"; + public static String AppLibraries[] = { "sdl-1.2", }; + public static final boolean Using_SDL_1_3 = false; // Should be zip file @@ -105,7 +107,3 @@ class Globals { public static boolean SmoothVideo = false; public static boolean MultiThreadedVideo = SwVideoMode; } - -class LoadLibrary { - public LoadLibrary() { System.loadLibrary("sdl-1.2"); }; -} diff --git a/project/java/MainActivity.java b/project/java/MainActivity.java index 48487ca040..ad26441bc4 100644 --- a/project/java/MainActivity.java +++ b/project/java/MainActivity.java @@ -24,6 +24,16 @@ import android.content.Intent; import android.view.View.OnKeyListener; import java.util.LinkedList; +import java.io.SequenceInputStream; +import java.io.BufferedInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.io.FileOutputStream; +import java.io.File; +import java.util.zip.ZipEntry; +import java.util.zip.ZipInputStream; + public class MainActivity extends Activity { @@ -81,7 +91,7 @@ public void onClick(View v) if(mAudioThread == null) // Starting from background (should not happen) { System.out.println("libSDL: Loading libraries"); - mLoadLibraryStub = new LoadLibrary(); + LoadLibraries(); mAudioThread = new AudioThread(this); System.out.println("libSDL: Loading settings"); Settings.Load(this); @@ -223,19 +233,13 @@ public void hideScreenKeyboard() { if(_screenKeyboard == null) return; - String text = _screenKeyboard.getText().toString(); - if( mGLView != null ) + + synchronized(textInput) { - synchronized(textInput) { - for(int i = 0; i < text.length(); i++) - { - DemoRenderer.nativeTextInput( (int)text.charAt(i), (int)text.codePointAt(i) ); - //textInput.addLast((int)text.charAt(i)); - //textInput.addLast((int)text.codePointAt(i)); - } - DemoRenderer.nativeTextInput( 13, 13 ); // send return - //textInput.addLast(13); - //textInput.addLast(13); + String text = _screenKeyboard.getText().toString(); + for(int i = 0; i < text.length(); i++) + { + DemoRenderer.nativeTextInput( (int)text.charAt(i), (int)text.codePointAt(i) ); } } _videoLayout.removeView(_screenKeyboard); @@ -255,12 +259,19 @@ class myKeyListener implements OnKeyListener myKeyListener(MainActivity parent) { _parent = parent; }; public boolean onKey(View v, int keyCode, KeyEvent event) { - if ((event.getAction() == KeyEvent.ACTION_DOWN) && (keyCode == KeyEvent.KEYCODE_ENTER)) + if ((event.getAction() == KeyEvent.ACTION_UP) && ((keyCode == KeyEvent.KEYCODE_ENTER) || (keyCode == KeyEvent.KEYCODE_BACK))) { _parent.hideScreenKeyboard(); + if(keyCode == KeyEvent.KEYCODE_ENTER) + { + synchronized(textInput) + { + DemoRenderer.nativeTextInput( 13, 13 ); // send return + } + } return true; } - if ((event.getAction() == KeyEvent.ACTION_DOWN) && (keyCode == KeyEvent.KEYCODE_DEL || keyCode == KeyEvent.KEYCODE_CLEAR)) + if ((event.getAction() == KeyEvent.ACTION_UP) && (keyCode == KeyEvent.KEYCODE_DEL || keyCode == KeyEvent.KEYCODE_CLEAR)) { synchronized(textInput) { DemoRenderer.nativeTextInput( 8, 8 ); @@ -376,13 +387,104 @@ public void hideTaskbarNotification() NotificationManager NotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); NotificationManager.cancel(NOTIFY_ID); } + + public void LoadLibraries() + { + try + { + for(String l : Globals.AppLibraries) + { + System.loadLibrary(l); + } + } + catch ( UnsatisfiedLinkError e ) + { + try { + System.out.println("libSDL: Extracting APP2SD-ed libs"); + + InputStream in = null; + try + { + for( int i = 0; ; i++ ) + { + InputStream in2 = getAssets().open("bindata" + String.valueOf(i)); + if( in == null ) + in = in2; + else + in = new SequenceInputStream( in, in2 ); + } + } + catch( IOException ee ) { } + + if( in == null ) + throw new RuntimeException("libSDL: Extracting APP2SD-ed libs failed, the .apk file packaged incorrectly"); + + ZipInputStream zip = new ZipInputStream(in); + + File cacheDir = getCacheDir(); + try { + cacheDir.mkdirs(); + } catch( SecurityException ee ) { }; + + byte[] buf = new byte[16384]; + while(true) + { + ZipEntry entry = null; + entry = zip.getNextEntry(); + /* + if( entry != null ) + System.out.println("Extracting lib " + entry.getName()); + */ + if( entry == null ) + { + System.out.println("Extracting libs finished"); + break; + } + if( entry.isDirectory() ) + { + System.out.println("Warning '" + entry.getName() + "' is a directory"); + continue; + } + + OutputStream out = null; + String path = cacheDir.getAbsolutePath() + "/" + entry.getName(); + + System.out.println("Saving to file '" + path + "'"); + + out = new FileOutputStream( path ); + int len = zip.read(buf); + while (len >= 0) + { + if(len > 0) + out.write(buf, 0, len); + len = zip.read(buf); + } + + out.flush(); + out.close(); + } + + for(String l : Globals.AppLibraries) + { + String libname = System.mapLibraryName(l); + File libpath = new File(cacheDir, libname); + System.out.println("libSDL: loading lib " + libpath.getPath()); + System.load(libpath.getPath()); + libpath.delete(); + } + } + catch ( Exception ee ) + { + System.out.println("libSDL: Error: " + e.toString()); + } + } + }; public FrameLayout getVideoLayout() { return _videoLayout; } static int NOTIFY_ID = 12367098; // Random ID private static DemoGLSurfaceView mGLView = null; - private static LoadLibrary mLoadLibraryStub = null; private static AudioThread mAudioThread = null; private static DataDownloader downloader = null; diff --git a/project/java/Video.java b/project/java/Video.java index 8f873437e7..72604b272d 100644 --- a/project/java/Video.java +++ b/project/java/Video.java @@ -18,6 +18,7 @@ import android.view.Window; import android.view.WindowManager; import android.os.Environment; +import java.io.File; import android.widget.TextView; import java.lang.Thread; @@ -205,8 +206,27 @@ public void onDrawFrame(GL10 gl) { // Thread.currentThread().setPriority((Thread.currentThread().getPriority() + Thread.MIN_PRIORITY)/2); mGlContextLost = false; - System.loadLibrary("application"); - System.loadLibrary("sdl_main"); + + String libs[] = { "application", "sdl_main" }; + try + { + for(String l : libs) + { + System.loadLibrary(l); + } + } + catch ( UnsatisfiedLinkError e ) + { + for(String l : libs) + { + String libname = System.mapLibraryName(l); + File libpath = new File(context.getCacheDir(), libname); + System.out.println("libSDL: loading lib " + libpath.getPath()); + System.load(libpath.getPath()); + libpath.delete(); + } + } + Settings.Apply(context); accelerometer = new AccelerometerReader(context); // Tweak video thread priority, if user selected big audio buffer diff --git a/project/jni/application/fheroes2/AndroidAppSettings.cfg b/project/jni/application/fheroes2/AndroidAppSettings.cfg index cc78f4b23f..aef6955123 100644 --- a/project/jni/application/fheroes2/AndroidAppSettings.cfg +++ b/project/jni/application/fheroes2/AndroidAppSettings.cfg @@ -1,14 +1,15 @@ # The application settings for Android libSDL port -AppSettingVersion=16 +AppSettingVersion=17 LibSdlVersion=1.2 AppName="Free Heroes 2" AppFullName=net.sourceforge.fheroes2 ScreenOrientation=h InhibitSuspend=n -AppDataDownloadUrl="Game data|data8.zip^Heroes 2 DEMO data files (45 Mb)|http://downloads.pcworld.com/pub/new/fun_and_games/adventure_strategy/h2demo.zip|http://sourceforge.net/projects/libsdl-android/files/FreeHeroes2/h2demo.zip/download^MIDI music support (18 Mb)|http://sourceforge.net/projects/libsdl-android/files/timidity.zip/download^Essential map pack (9 Mb)|http://sourceforge.net/projects/libsdl-android/files/FreeHeroes2/EssentialMapPack.zip/download^Additional map pack (95 Mb)|http://sourceforge.net/projects/libsdl-android/files/FreeHeroes2/AdditionalMapPack.zip/download^Mega map pack (280 Mb)|http://sourceforge.net/projects/libsdl-android/files/FreeHeroes2/MegaMapPack.zip/download^Russian translation|:fheroes2.cfg:http://sourceforge.net/projects/libsdl-android/files/FreeHeroes2/lang/fheroes2-ru.cfg/download^Czech translation|:fheroes2.cfg:http://sourceforge.net/projects/libsdl-android/files/FreeHeroes2/lang/fheroes2-cs.cfg/download^Spanish translation|:fheroes2.cfg:http://sourceforge.net/projects/libsdl-android/files/FreeHeroes2/lang/fheroes2-es.cfg/download^French translation|:fheroes2.cfg:http://sourceforge.net/projects/libsdl-android/files/FreeHeroes2/lang/fheroes2-fr.cfg/download^Hungarian translation|:fheroes2.cfg:http://sourceforge.net/projects/libsdl-android/files/FreeHeroes2/lang/fheroes2-hu.cfg/download^Polish translation|:fheroes2.cfg:http://sourceforge.net/projects/libsdl-android/files/FreeHeroes2/lang/fheroes2-pl.cfg/download^Portugese translation|:fheroes2.cfg:http://sourceforge.net/projects/libsdl-android/files/FreeHeroes2/lang/fheroes2-pt.cfg/download^Swedish translation|:fheroes2.cfg:http://sourceforge.net/projects/libsdl-android/files/FreeHeroes2/lang/fheroes2-sv.cfg/download" +AppDataDownloadUrl="Game data|data9.zip^Heroes 2 DEMO data files (45 Mb)|http://downloads.pcworld.com/pub/new/fun_and_games/adventure_strategy/h2demo.zip|http://sourceforge.net/projects/libsdl-android/files/FreeHeroes2/h2demo.zip/download^MIDI music support (18 Mb)|http://sourceforge.net/projects/libsdl-android/files/timidity.zip/download^Essential map pack (9 Mb)|http://sourceforge.net/projects/libsdl-android/files/FreeHeroes2/EssentialMapPack.zip/download^Additional map pack (95 Mb)|http://sourceforge.net/projects/libsdl-android/files/FreeHeroes2/AdditionalMapPack.zip/download^Mega map pack (280 Mb)|http://sourceforge.net/projects/libsdl-android/files/FreeHeroes2/MegaMapPack.zip/download^Russian translation|:fheroes2.cfg:http://sourceforge.net/projects/libsdl-android/files/FreeHeroes2/lang/fheroes2-ru.cfg/download^Czech translation|:fheroes2.cfg:http://sourceforge.net/projects/libsdl-android/files/FreeHeroes2/lang/fheroes2-cs.cfg/download^Spanish translation|:fheroes2.cfg:http://sourceforge.net/projects/libsdl-android/files/FreeHeroes2/lang/fheroes2-es.cfg/download^French translation|:fheroes2.cfg:http://sourceforge.net/projects/libsdl-android/files/FreeHeroes2/lang/fheroes2-fr.cfg/download^Hungarian translation|:fheroes2.cfg:http://sourceforge.net/projects/libsdl-android/files/FreeHeroes2/lang/fheroes2-hu.cfg/download^Polish translation|:fheroes2.cfg:http://sourceforge.net/projects/libsdl-android/files/FreeHeroes2/lang/fheroes2-pl.cfg/download^Portugese translation|:fheroes2.cfg:http://sourceforge.net/projects/libsdl-android/files/FreeHeroes2/lang/fheroes2-pt.cfg/download^Swedish translation|:fheroes2.cfg:http://sourceforge.net/projects/libsdl-android/files/FreeHeroes2/lang/fheroes2-sv.cfg/download" SdlVideoResize=y SdlVideoResizeKeepAspect=n NeedDepthBuffer=n +SwVideoMode=y AppUsesMouse=y AppNeedsTwoButtonMouse=y AppNeedsArrowKeys=n @@ -22,8 +23,8 @@ AppTouchscreenKeyboardKeysAmount=0 AppTouchscreenKeyboardKeysAmountAutoFire=0 RedefinedKeysScreenKb="LCTRL M T H E C SPACE C S L" MultiABI=n -AppVersionCode=225912 -AppVersionName="2259.12" +AppVersionCode=226512 +AppVersionName="2265.12" CompiledLibraries="sdl_net sdl_mixer sdl_image sdl_ttf png intl" CustomBuildScript=n AppCflags='-finline-functions -O2 -DWITH_ZLIB -DWITH_MIXER -DWITH_XML -DWITH_IMAGE -DWITH_TTF -DWITH_AI=simple' diff --git a/project/jni/application/fheroes2/AndroidData/data8.zip b/project/jni/application/fheroes2/AndroidData/data9.zip similarity index 97% rename from project/jni/application/fheroes2/AndroidData/data8.zip rename to project/jni/application/fheroes2/AndroidData/data9.zip index 2115ad3486ea43ad56bcf8a59ce2cbeb6a7f836b..14ad663c3d6739d4cbbb50fa229f56a0f4fb8a76 100644 GIT binary patch delta 19340 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 B4z>UQ delta 60 zcmeC}Fg^3hxS@ryg{g(Pg{6hHg{_6Xg`