diff --git a/android/andretro/.classpath b/android/andretro/.classpath
new file mode 100644
index 0000000000..c5c5afd01d
--- /dev/null
+++ b/android/andretro/.classpath
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
+
diff --git a/android/andretro/.gitignore b/android/andretro/.gitignore
new file mode 100644
index 0000000000..c85d75bba4
--- /dev/null
+++ b/android/andretro/.gitignore
@@ -0,0 +1,5 @@
+/gen
+/bin
+/libs/*/*
+/obj
+/jni/modules/*.so
\ No newline at end of file
diff --git a/android/andretro/.project b/android/andretro/.project
new file mode 100644
index 0000000000..1a51a6a5da
--- /dev/null
+++ b/android/andretro/.project
@@ -0,0 +1,33 @@
+
+
+ Retroarch
+
+
+
+
+
+ com.android.ide.eclipse.adt.ResourceManagerBuilder
+
+
+
+
+ com.android.ide.eclipse.adt.PreCompilerBuilder
+
+
+
+
+ org.eclipse.jdt.core.javabuilder
+
+
+
+
+ com.android.ide.eclipse.adt.ApkBuilder
+
+
+
+
+
+ com.android.ide.eclipse.adt.AndroidNature
+ org.eclipse.jdt.core.javanature
+
+
diff --git a/android/andretro/.settings/org.eclipse.jdt.core.prefs b/android/andretro/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 0000000000..8000cd6ca6
--- /dev/null
+++ b/android/andretro/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,11 @@
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6
+org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
+org.eclipse.jdt.core.compiler.compliance=1.6
+org.eclipse.jdt.core.compiler.debug.lineNumber=generate
+org.eclipse.jdt.core.compiler.debug.localVariable=generate
+org.eclipse.jdt.core.compiler.debug.sourceFile=generate
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.source=1.6
diff --git a/android/andretro/AndroidManifest.xml b/android/andretro/AndroidManifest.xml
new file mode 100644
index 0000000000..f27845d9e1
--- /dev/null
+++ b/android/andretro/AndroidManifest.xml
@@ -0,0 +1,31 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/android/andretro/ant.properties b/android/andretro/ant.properties
new file mode 100644
index 0000000000..b0971e891e
--- /dev/null
+++ b/android/andretro/ant.properties
@@ -0,0 +1,17 @@
+# This file is used to override default values used by the Ant build system.
+#
+# This file must be checked into Version Control Systems, as it is
+# integral to the build system of your project.
+
+# This file is only used by the Ant script.
+
+# You can use this to override default values such as
+# 'source.dir' for the location of your java source folder and
+# 'out.dir' for the location of your output folder.
+
+# You can also use it define how the release builds are signed by declaring
+# the following properties:
+# 'key.store' for the location of your keystore and
+# 'key.alias' for the name of the key to use.
+# The password will be asked during the build when you use the 'release' target.
+
diff --git a/android/andretro/build.xml b/android/andretro/build.xml
new file mode 100644
index 0000000000..640264ba12
--- /dev/null
+++ b/android/andretro/build.xml
@@ -0,0 +1,92 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/android/andretro/jni/Android.mk b/android/andretro/jni/Android.mk
new file mode 100644
index 0000000000..021fee0ead
--- /dev/null
+++ b/android/andretro/jni/Android.mk
@@ -0,0 +1,71 @@
+RARCH_VERSION = "0.9.8-beta3"
+LOCAL_PATH := $(call my-dir)
+PERF_TEST := 1
+HAVE_OPENSL := 1
+HAVE_NEON := 1
+HAVE_SINC := 1
+
+include $(CLEAR_VARS)
+
+ifeq ($(TARGET_ARCH),arm)
+LOCAL_CFLAGS += -DANDROID_ARM -marm
+LOCAL_ARM_MODE := arm
+endif
+
+ifeq ($(TARGET_ARCH),x86)
+LOCAL_CFLAGS += -DANDROID_X86 -DHAVE_SSSE3
+endif
+
+ifeq ($(TARGET_ARCH_ABI),armeabi-v7a)
+
+ifeq ($(HAVE_NEON),1)
+LOCAL_CFLAGS += -DHAVE_NEON
+endif
+
+ifeq ($(HAVE_SINC),1)
+ifeq ($(HAVE_NEON),1)
+LOCAL_SRC_FILES += ../../../audio/sinc_neon.S.neon
+endif
+LOCAL_CFLAGS += -DHAVE_SINC
+endif
+
+LOCAL_CFLAGS += -DANDROID_ARM_V7
+endif
+
+
+ifeq ($(TARGET_ARCH),mips)
+LOCAL_CFLAGS += -DANDROID_MIPS -D__mips__ -D__MIPSEL__
+endif
+
+LOCAL_MODULE := retroarch-activity
+
+RARCH_PATH := ../../..
+LIBXML_PATH := ../../../deps/libxml2
+LOCAL_SRC_FILES += $(RARCH_PATH)/console/griffin/griffin.c
+
+
+ifeq ($(PERF_TEST), 1)
+LOCAL_CFLAGS += -DPERF_TEST
+endif
+
+LOCAL_CFLAGS += -O3 -fno-stack-protector -funroll-loops -DNDEBUG -DHAVE_GRIFFIN -DANDROID -DHAVE_DYNAMIC -DHAVE_OPENGL -DHAVE_OPENGLES -DHAVE_VID_CONTEXT -DHAVE_OPENGLES2 -DGLSL_DEBUG -DHAVE_GLSL -DHAVE_ZLIB -DWANT_RZLIB -DINLINE=inline -DLSB_FIRST -DHAVE_THREAD -D__LIBRETRO__ -DHAVE_CONFIGFILE=1 -DRARCH_PERFORMANCE_MODE -DRARCH_GPU_PERFORMANCE_MODE -DPACKAGE_VERSION=\"$(RARCH_VERSION)\" -std=gnu99
+
+LOCAL_LDLIBS := -L$(SYSROOT)/usr/lib -landroid -lEGL -lGLESv2 -llog -ldl
+LOCAL_C_INCLUDES += $(LIBXML_PATH)
+
+ifeq ($(HAVE_OPENSL), 1)
+LOCAL_CFLAGS += -DHAVE_SL
+LOCAL_LDLIBS += -lOpenSLES
+endif
+
+include $(BUILD_SHARED_LIBRARY)
+
+# Include all present sub-modules
+FOCAL_PATH := $(LOCAL_PATH)
+
+define function
+$(eval RETRO_MODULE_OBJECT := $(1))
+$(eval include $(FOCAL_PATH)/modules/Android.mk)
+endef
+
+$(foreach m,$(wildcard $(FOCAL_PATH)/modules/*.so),$(eval $(call function,$(m))))
diff --git a/android/andretro/jni/Application.mk b/android/andretro/jni/Application.mk
new file mode 100644
index 0000000000..492004a45f
--- /dev/null
+++ b/android/andretro/jni/Application.mk
@@ -0,0 +1,2 @@
+APP_PLATFORM := android-9
+APP_ABI := all
diff --git a/android/andretro/jni/modules/Android.mk b/android/andretro/jni/modules/Android.mk
new file mode 100644
index 0000000000..073cfc593f
--- /dev/null
+++ b/android/andretro/jni/modules/Android.mk
@@ -0,0 +1,6 @@
+LOCAL_PATH := $(call my-dir)
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := $(notdir $(RETRO_MODULE_OBJECT))
+LOCAL_SRC_FILES := $(notdir $(RETRO_MODULE_OBJECT))
+include $(PREBUILT_SHARED_LIBRARY)
diff --git a/android/andretro/libs/android-support-v4.jar b/android/andretro/libs/android-support-v4.jar
new file mode 100644
index 0000000000..feaf44f801
Binary files /dev/null and b/android/andretro/libs/android-support-v4.jar differ
diff --git a/android/andretro/proguard-project.txt b/android/andretro/proguard-project.txt
new file mode 100644
index 0000000000..f2fe1559a2
--- /dev/null
+++ b/android/andretro/proguard-project.txt
@@ -0,0 +1,20 @@
+# 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/android/andretro/project.properties b/android/andretro/project.properties
new file mode 100644
index 0000000000..9b84a6b4bf
--- /dev/null
+++ b/android/andretro/project.properties
@@ -0,0 +1,14 @@
+# This file is automatically generated by Android Tools.
+# Do not modify this file -- YOUR CHANGES WILL BE ERASED!
+#
+# This file must be checked in Version Control Systems.
+#
+# To customize properties used by the Ant build system edit
+# "ant.properties", and override values to adapt the script to your
+# project structure.
+#
+# To enable ProGuard to shrink and obfuscate your code, uncomment this (available properties: sdk.dir, user.home):
+#proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt
+
+# Project target.
+target=android-16
diff --git a/android/andretro/res/drawable-hdpi/ic_launcher.png b/android/andretro/res/drawable-hdpi/ic_launcher.png
new file mode 100644
index 0000000000..ea7613b8c4
Binary files /dev/null and b/android/andretro/res/drawable-hdpi/ic_launcher.png differ
diff --git a/android/andretro/res/drawable-ldpi/ic_launcher.png b/android/andretro/res/drawable-ldpi/ic_launcher.png
new file mode 100644
index 0000000000..f969b747a2
Binary files /dev/null and b/android/andretro/res/drawable-ldpi/ic_launcher.png differ
diff --git a/android/andretro/res/drawable-mdpi/ic_launcher.png b/android/andretro/res/drawable-mdpi/ic_launcher.png
new file mode 100644
index 0000000000..84f2bca830
Binary files /dev/null and b/android/andretro/res/drawable-mdpi/ic_launcher.png differ
diff --git a/android/andretro/res/drawable-nodpi/file.png b/android/andretro/res/drawable-nodpi/file.png
new file mode 100755
index 0000000000..7a2442eae4
Binary files /dev/null and b/android/andretro/res/drawable-nodpi/file.png differ
diff --git a/android/andretro/res/drawable-nodpi/folder.png b/android/andretro/res/drawable-nodpi/folder.png
new file mode 100755
index 0000000000..eb4bed47bf
Binary files /dev/null and b/android/andretro/res/drawable-nodpi/folder.png differ
diff --git a/android/andretro/res/drawable-xhdpi/ic_launcher.png b/android/andretro/res/drawable-xhdpi/ic_launcher.png
new file mode 100644
index 0000000000..a113106a99
Binary files /dev/null and b/android/andretro/res/drawable-xhdpi/ic_launcher.png differ
diff --git a/android/andretro/res/layout/icon_grid_item.xml b/android/andretro/res/layout/icon_grid_item.xml
new file mode 100644
index 0000000000..1109ae5f48
--- /dev/null
+++ b/android/andretro/res/layout/icon_grid_item.xml
@@ -0,0 +1,23 @@
+
+
+
+
+
+
+
+
diff --git a/android/andretro/res/layout/icon_grid_list.xml b/android/andretro/res/layout/icon_grid_list.xml
new file mode 100644
index 0000000000..272ecf43f8
--- /dev/null
+++ b/android/andretro/res/layout/icon_grid_list.xml
@@ -0,0 +1,8 @@
+
+
+
+
\ No newline at end of file
diff --git a/android/andretro/res/layout/line_list.xml b/android/andretro/res/layout/line_list.xml
new file mode 100644
index 0000000000..fda2c156b3
--- /dev/null
+++ b/android/andretro/res/layout/line_list.xml
@@ -0,0 +1,7 @@
+
+
+
+
diff --git a/android/andretro/res/layout/line_list_item.xml b/android/andretro/res/layout/line_list_item.xml
new file mode 100644
index 0000000000..46ebf2dec1
--- /dev/null
+++ b/android/andretro/res/layout/line_list_item.xml
@@ -0,0 +1,23 @@
+
+
+
+
+
+
+
+
diff --git a/android/andretro/res/menu/directory_list.xml b/android/andretro/res/menu/directory_list.xml
new file mode 100644
index 0000000000..bc390915c7
--- /dev/null
+++ b/android/andretro/res/menu/directory_list.xml
@@ -0,0 +1,4 @@
+
+
\ No newline at end of file
diff --git a/android/andretro/res/values/strings.xml b/android/andretro/res/values/strings.xml
new file mode 100644
index 0000000000..0402da9b84
--- /dev/null
+++ b/android/andretro/res/values/strings.xml
@@ -0,0 +1,7 @@
+
+
+ RetroArch
+ Input Method
+ File type icon
+
+
\ No newline at end of file
diff --git a/android/andretro/src/org/retroarch/browser/DirectoryActivity.java b/android/andretro/src/org/retroarch/browser/DirectoryActivity.java
new file mode 100644
index 0000000000..b3cdc14898
--- /dev/null
+++ b/android/andretro/src/org/retroarch/browser/DirectoryActivity.java
@@ -0,0 +1,153 @@
+package org.retroarch.browser;
+import org.retroarch.R;
+
+import java.util.*;
+import java.io.*;
+
+import android.content.*;
+import android.app.*;
+import android.os.*;
+import android.widget.*;
+import android.view.*;
+import android.view.inputmethod.*;
+import android.graphics.drawable.*;
+
+class FileWrapper implements IconAdapterItem
+{
+ public final File file;
+ protected final int typeIndex;
+ protected final boolean enabled;
+
+ public FileWrapper(File aFile, boolean aIsEnabled)
+ {
+ file = aFile;
+ typeIndex = (file.isDirectory() ? 1 : 0) + (file.isFile() ? 2 : 0);
+ enabled = aIsEnabled;
+ }
+
+ @Override public boolean isEnabled()
+ {
+ return enabled;
+ }
+
+ @Override public String getText()
+ {
+ return file.getName();
+ }
+
+ @Override public int getIconResourceId()
+ {
+ return file.isFile() ? R.drawable.file : R.drawable.folder;
+ }
+
+ @Override public Drawable getIconDrawable()
+ {
+ return null;
+ }
+
+ public int compareTo(FileWrapper aOther)
+ {
+ if(null != aOther)
+ {
+ // Who says ternary is hard to follow
+ if(isEnabled() == aOther.isEnabled())
+ {
+ return (typeIndex == aOther.typeIndex) ? file.compareTo(aOther.file) : ((typeIndex < aOther.typeIndex) ? -1 : 1);
+ }
+ else
+ {
+ return isEnabled() ? -1 : 1;
+ }
+ }
+
+ return -1;
+ }
+}
+
+public class DirectoryActivity extends Activity implements AdapterView.OnItemClickListener
+{
+ private IconAdapter adapter;
+ private String modulePath;
+
+ @Override public void onCreate(Bundle savedInstanceState)
+ {
+ super.onCreate(savedInstanceState);
+
+ setContentView(R.layout.line_list);
+
+ modulePath = getIntent().getStringExtra("LIBRETRO");
+
+ // Setup the list
+ adapter = new IconAdapter(this, R.layout.line_list_item);
+ ListView list = (ListView)findViewById(R.id.list);
+ list.setAdapter(adapter);
+ list.setOnItemClickListener(this);
+
+ // Load Directory
+ String path = getIntent().getStringExtra("ROM");
+ if(path == null)
+ {
+ path = Environment.getExternalStorageDirectory().getPath();
+ }
+
+ wrapFiles(new File(path));
+ setTitle(path);
+ }
+
+ @Override public void onItemClick(AdapterView> aListView, View aView, int aPosition, long aID)
+ {
+ final File selected = adapter.getItem(aPosition).file;
+
+ final Intent intent = new Intent(this, selected.isFile() ? NativeActivity.class : DirectoryActivity.class)
+ .putExtra("ROM", selected.getAbsolutePath())
+ .putExtra("LIBRETRO", modulePath);
+
+ startActivity(intent);
+ }
+
+ @Override public boolean onCreateOptionsMenu(Menu aMenu)
+ {
+ super.onCreateOptionsMenu(aMenu);
+ getMenuInflater().inflate(R.menu.directory_list, aMenu);
+
+ return true;
+ }
+
+ @Override public boolean onOptionsItemSelected(MenuItem aItem)
+ {
+ if(R.id.input_method_select == aItem.getItemId())
+ {
+ InputMethodManager imm = (InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE);
+ imm.showInputMethodPicker();
+ return true;
+ }
+
+ return super.onOptionsItemSelected(aItem);
+ }
+
+ private void wrapFiles(File aDirectory)
+ {
+ if(null == aDirectory || !aDirectory.isDirectory())
+ {
+ throw new IllegalArgumentException("Directory is not valid.");
+ }
+
+ // Copy new items
+ for(File file: aDirectory.listFiles())
+ {
+ adapter.add(new FileWrapper(file, file.isDirectory() || true));
+ }
+
+ // Sort items
+ adapter.sort(new Comparator()
+ {
+ @Override public int compare(FileWrapper aLeft, FileWrapper aRight)
+ {
+ return aLeft.compareTo(aRight);
+ };
+ });
+
+ // Update
+ adapter.notifyDataSetChanged();
+ }
+}
diff --git a/android/andretro/src/org/retroarch/browser/IconAdapter.java b/android/andretro/src/org/retroarch/browser/IconAdapter.java
new file mode 100644
index 0000000000..edea24c68c
--- /dev/null
+++ b/android/andretro/src/org/retroarch/browser/IconAdapter.java
@@ -0,0 +1,78 @@
+package org.retroarch.browser;
+import org.retroarch.R;
+
+import android.app.*;
+import android.content.*;
+import android.graphics.drawable.*;
+import android.view.*;
+import android.widget.*;
+
+interface IconAdapterItem
+{
+ public abstract boolean isEnabled();
+ public abstract String getText();
+ public abstract int getIconResourceId();
+ public abstract Drawable getIconDrawable();
+}
+
+class IconAdapter extends ArrayAdapter
+{
+ private final int layout;
+
+ public IconAdapter(Activity aContext, int aLayout)
+ {
+ super(aContext, aLayout);
+
+ layout = aLayout;
+ }
+
+ @Override public View getView(int aPosition, View aConvertView, ViewGroup aParent)
+ {
+ // Build the view
+ if(aConvertView == null)
+ {
+ LayoutInflater inflater = (LayoutInflater)aParent.getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
+ aConvertView = inflater.inflate(layout, aParent, false);
+ }
+
+ // Fill the view
+ IconAdapterItem item = getItem(aPosition);
+ final boolean enabled = item.isEnabled();
+
+ TextView textView = (TextView)aConvertView.findViewById(R.id.name);
+ if(null != textView)
+ {
+ textView.setText(item.getText());
+ textView.setEnabled(enabled);
+ }
+
+ ImageView imageView = (ImageView)aConvertView.findViewById(R.id.icon);
+ if(null != imageView)
+ {
+ if(enabled)
+ {
+ final int id = item.getIconResourceId();
+ if(0 != id)
+ {
+ imageView.setImageResource(id);
+ }
+ else
+ {
+ imageView.setImageDrawable(item.getIconDrawable());
+ }
+ }
+ else
+ {
+ imageView.setImageDrawable(null);
+ }
+ }
+
+ return aConvertView;
+ }
+
+ @Override public boolean isEnabled(int aPosition)
+ {
+ return getItem(aPosition).isEnabled();
+ }
+
+}
diff --git a/android/andretro/src/org/retroarch/browser/ModuleActivity.java b/android/andretro/src/org/retroarch/browser/ModuleActivity.java
new file mode 100644
index 0000000000..b0b5dba23f
--- /dev/null
+++ b/android/andretro/src/org/retroarch/browser/ModuleActivity.java
@@ -0,0 +1,106 @@
+package org.retroarch.browser;
+import org.retroarch.R;
+
+import java.io.*;
+
+import android.content.*;
+import android.app.*;
+import android.os.*;
+import android.widget.*;
+import android.view.*;
+import android.view.inputmethod.*;
+import android.graphics.drawable.*;
+
+class ModuleWrapper implements IconAdapterItem
+{
+ public final File file;
+
+ public ModuleWrapper(Context aContext, File aFile) throws IOException
+ {
+ file = aFile;
+ }
+
+ @Override public boolean isEnabled()
+ {
+ return true;
+ }
+
+ @Override public String getText()
+ {
+ return file.getName();
+ }
+
+ @Override public int getIconResourceId()
+ {
+ return 0;
+ }
+
+ @Override public Drawable getIconDrawable()
+ {
+ return null;
+ }
+}
+
+public class ModuleActivity extends Activity implements AdapterView.OnItemClickListener
+{
+ // HACK: Hard path
+ private static final String modulePath = "/data/data/org.retroarch/lib/";
+ private IconAdapter adapter;
+
+ @Override public void onCreate(Bundle savedInstanceState)
+ {
+ super.onCreate(savedInstanceState);
+
+ setContentView(R.layout.line_list);
+
+ // Setup the list
+ adapter = new IconAdapter(this, R.layout.line_list_item);
+ ListView list = (ListView)findViewById(R.id.list);
+ list.setAdapter(adapter);
+ list.setOnItemClickListener(this);
+
+ setTitle("Select Emulator");
+
+ for(final File lib: new File(modulePath).listFiles())
+ {
+ if(lib.getName().startsWith("libretro_"))
+ {
+ try
+ {
+ adapter.add(new ModuleWrapper(this, lib));;
+ }
+ catch(Exception e)
+ {
+ //Logger.d("Couldn't add module: " + lib.getPath());
+ }
+ }
+ }
+ }
+
+ @Override public void onItemClick(AdapterView> aListView, View aView, int aPosition, long aID)
+ {
+ final ModuleWrapper item = adapter.getItem(aPosition);
+
+ startActivity(new Intent(ModuleActivity.this, DirectoryActivity.class)
+ .putExtra("LIBRETRO", item.file.getAbsolutePath()));
+ }
+
+ @Override public boolean onCreateOptionsMenu(Menu aMenu)
+ {
+ super.onCreateOptionsMenu(aMenu);
+ getMenuInflater().inflate(R.menu.directory_list, aMenu);
+ return true;
+ }
+
+ @Override public boolean onOptionsItemSelected(MenuItem aItem)
+ {
+ if(R.id.input_method_select == aItem.getItemId())
+ {
+ InputMethodManager imm = (InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE);
+ imm.showInputMethodPicker();
+ return true;
+ }
+
+ return super.onOptionsItemSelected(aItem);
+ }
+}
diff --git a/android/native/jni/main.c b/android/native/jni/main.c
index 97d5c81559..0ee678e62e 100644
--- a/android/native/jni/main.c
+++ b/android/native/jni/main.c
@@ -339,9 +339,6 @@ static void* android_app_entry(void* param)
RARCH_LOG("ROM Filename: [%s].\n", rom_path);
RARCH_LOG("Libretro path: [%s].\n", libretro_path);
- /* ugly hack for now - hardcode libretro path to 'allowed' dir */
- snprintf(libretro_path, sizeof(libretro_path), "/data/data/com.retroarch/lib/libretro.so");
-
int argc = 0;
char *argv[MAX_ARGS] = {NULL};