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};