Merge pull request #81 from meancoot/android-newui

(Android) Add new frontend for easier install and use.
This commit is contained in:
Squarepusher 2012-12-08 02:12:38 -08:00
commit 344640d96c
60 changed files with 743 additions and 1040 deletions

View File

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

View File

@ -1,8 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="con" path="com.android.ide.eclipse.adt.ANDROID_FRAMEWORK"/>
<classpathentry kind="con" path="com.android.ide.eclipse.adt.LIBRARIES"/>
<classpathentry kind="src" path="src"/>
<classpathentry kind="src" path="gen"/>
<classpathentry kind="con" path="com.android.ide.eclipse.adt.ANDROID_FRAMEWORK"/>
<classpathentry kind="con" path="com.android.ide.eclipse.adt.LIBRARIES"/>
<classpathentry kind="output" path="bin/classes"/>
</classpath>

5
android/phoenix/.gitignore vendored Normal file
View File

@ -0,0 +1,5 @@
/gen
/bin
/libs/*/*
/obj
/jni/modules/*.so

View File

@ -1,16 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>RetroArch</name>
<name>Retroarch</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.cdt.managedbuilder.core.genmakebuilder</name>
<triggers>full,incremental,</triggers>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>com.android.ide.eclipse.adt.ResourceManagerBuilder</name>
<arguments>
@ -31,25 +25,9 @@
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder</name>
<triggers>full,incremental,</triggers>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>com.android.ide.eclipse.adt.AndroidNature</nature>
<nature>org.eclipse.jdt.core.javanature</nature>
<nature>org.eclipse.cdt.core.cnature</nature>
<nature>org.eclipse.cdt.managedbuilder.core.managedBuildNature</nature>
<nature>org.eclipse.cdt.managedbuilder.core.ScannerConfigNature</nature>
</natures>
<linkedResources>
<link>
<name>res/retroarch.cfg</name>
<type>1</type>
<locationURI>PARENT-2-PROJECT_LOC/retroarch.cfg</locationURI>
</link>
</linkedResources>
</projectDescription>

View File

@ -1,4 +1,11 @@
eclipse.preferences.version=1
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5
org.eclipse.jdt.core.compiler.compliance=1.5
org.eclipse.jdt.core.compiler.source=1.5
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

View File

@ -1,27 +1,31 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.retroarch"
package="org.retroarch"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk android:minSdkVersion="15" />
<uses-sdk
android:minSdkVersion="9"
android:targetSdkVersion="16" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<application
android:icon="@drawable/ic_launcher"
android:label="@string/app_name">
<activity android:name="phoenix" android:label="@string/app_name" >
android:label="@string/app_name" >
<activity android:name=".browser.ModuleActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:label="@string/app_name" android:name="com.retroarch.fileio.FileChooser" />
<activity android:label="@string/app_name" android:name="rombrowser" />
<activity android:name=".browser.DirectoryActivity"></activity>
<activity android:name="android.app.NativeActivity" android:configChanges="mcc|mnc|locale|touchscreen|keyboard|keyboardHidden|navigation|orientation|screenLayout|uiMode|screenSize|smallestScreenSize|fontScale">
<meta-data android:name="android.app.lib_name" android:value="retroarch-activity" />
<meta-data android:name="android.app.func_name" android:value="ANativeActivity_onCreate" />
</activity>
</application>
</manifest>

View File

@ -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.

92
android/phoenix/build.xml Normal file
View File

@ -0,0 +1,92 @@
<?xml version="1.0" encoding="UTF-8"?>
<project name="retroarch" default="help">
<!-- The local.properties file is created and updated by the 'android' tool.
It contains the path to the SDK. It should *NOT* be checked into
Version Control Systems. -->
<property file="local.properties" />
<!-- The ant.properties file can be created by you. It is only edited by the
'android' tool to add properties to it.
This is the place to change some Ant specific build properties.
Here are some properties you may want to change/update:
source.dir
The name of the source directory. Default is 'src'.
out.dir
The name of the output directory. Default is 'bin'.
For other overridable properties, look at the beginning of the rules
files in the SDK, at tools/ant/build.xml
Properties related to the SDK location or the project target should
be updated using the 'android' tool with the 'update' action.
This file is an integral part of the build system for your
application and should be checked into Version Control Systems.
-->
<property file="ant.properties" />
<!-- if sdk.dir was not set from one of the property file, then
get it from the ANDROID_HOME env var.
This must be done before we load project.properties since
the proguard config can use sdk.dir -->
<property environment="env" />
<condition property="sdk.dir" value="${env.ANDROID_HOME}">
<isset property="env.ANDROID_HOME" />
</condition>
<!-- The project.properties file is created and updated by the 'android'
tool, as well as ADT.
This contains project specific properties such as project target, and library
dependencies. Lower level build properties are stored in ant.properties
(or in .classpath for Eclipse projects).
This file is an integral part of the build system for your
application and should be checked into Version Control Systems. -->
<loadproperties srcFile="project.properties" />
<!-- quick check on sdk.dir -->
<fail
message="sdk.dir is missing. Make sure to generate local.properties using 'android update project' or to inject it through the ANDROID_HOME environment variable."
unless="sdk.dir"
/>
<!--
Import per project custom build rules if present at the root of the project.
This is the place to put custom intermediary targets such as:
-pre-build
-pre-compile
-post-compile (This is typically used for code obfuscation.
Compiled code location: ${out.classes.absolute.dir}
If this is not done in place, override ${out.dex.input.absolute.dir})
-post-package
-post-build
-pre-clean
-->
<import file="custom_rules.xml" optional="true" />
<!-- Import the actual build file.
To customize existing targets, there are two options:
- Customize only one target:
- copy/paste the target into this file, *before* the
<import> task.
- customize it to your needs.
- Customize the whole content of build.xml
- copy/paste the content of the rules files (minus the top node)
into this file, replacing the <import> task.
- customize to your needs.
***********************
****** IMPORTANT ******
***********************
In all cases you must update the value of version-tag below to read 'custom' instead of an integer,
in order to avoid having your file be overridden by tools such as "android update project"
-->
<!-- version-tag: 1 -->
<import file="${sdk.dir}/tools/ant/build.xml" />
</project>

View File

@ -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))))

View File

@ -0,0 +1,2 @@
APP_PLATFORM := android-9
APP_ABI := all

View File

@ -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)

View File

@ -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 *;
#}

View File

@ -11,4 +11,4 @@
#proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt
# Project target.
target=android-15
target=android-16

Binary file not shown.

Before

Width:  |  Height:  |  Size: 725 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 774 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 578 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 614 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 608 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 748 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 495 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 406 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 415 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 281 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 306 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 304 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 401 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 296 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 506 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 579 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 407 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 418 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 395 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 510 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 391 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 725 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 774 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 578 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 614 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 608 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 997 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 547 B

View File

@ -1,24 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_height="wrap_content" android:orientation="vertical" android:layout_width="wrap_content">
<Button android:id="@+id/fileChooserSubmit"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:text="Submit">
</Button>
<ListView android:id="@+id/fileChooserView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="2"
android:scrollbars="vertical"
android:fastScrollEnabled="true"
android:padding="2dp"
android:layout_above="@id/fileChooserSubmit">
</ListView>
</RelativeLayout>

View File

@ -1,20 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_height="wrap_content" android:orientation="vertical" android:layout_width="fill_parent">
<TextView android:text="@+id/TextView01"
android:id="@+id/TextView01"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:singleLine="true"
android:textStyle="bold"
android:layout_marginTop="5dip"
android:layout_marginLeft="5dip">
</TextView>
<TextView android:text="@+id/TextView02"
android:id="@+id/TextView02"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="10dip">
</TextView>
</LinearLayout>

View File

@ -0,0 +1,23 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="vertical" >
<ImageView
android:id="@+id/icon"
android:layout_width="192dp"
android:layout_height="192dp"
android:layout_gravity="center"
android:contentDescription="@string/file_type_icon"
android:padding="8dp" />
<TextView
android:id="@+id/name"
android:layout_width="wrap_content"
android:layout_height="0dp"
android:layout_gravity="center"
android:layout_weight="0.5"
android:textSize="18sp" />
</LinearLayout>

View File

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<GridView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/list"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:numColumns="2" >
</GridView>

View File

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<ListView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/list"
android:layout_width="match_parent"
android:layout_height="wrap_content" >
</ListView>

View File

@ -0,0 +1,23 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="48dp">
<ImageView
android:id="@+id/icon"
android:layout_width="48dp"
android:layout_height="48dp"
android:contentDescription="@string/file_type_icon"
android:padding="8dp" />
<TextView
android:id="@+id/name"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_weight="0.5"
android:textSize="18sp" />
</LinearLayout>

View File

@ -1,17 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<SurfaceView
android:id="@+id/surfaceview"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
/>
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/hello" />
</LinearLayout>

View File

@ -1,12 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Hello world from RomBrowser" />
</LinearLayout>

View File

@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android" >
<item android:id="@+id/input_method_select" android:title="@string/input_method" android:showAsAction="ifRoom"></item>
</menu>

View File

@ -1,9 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android" >
<item android:id="@+id/main" android:showAsAction="ifRoom|withText" android:title="Main" android:icon="@drawable/ic_action_main"></item>
<item android:id="@+id/open" android:showAsAction="collapseActionView" android:title="Select ROM" android:icon="@drawable/ic_action_open"></item>
<item android:id="@+id/libretro" android:showAsAction="collapseActionView" android:title="Select libretro core" android:icon="@drawable/ic_launcher"></item>
<item android:id="@+id/settings" android:showAsAction="collapseActionView" android:title="Settings" android:icon="@drawable/ic_action_settings"></item>
</menu>

View File

@ -1,404 +0,0 @@
## Skeleton config file for RetroArch
# Save all save files (*.srm) to this directory. This includes related files like .bsv, .rtc, .psrm, etc ...
# This will be overridden by explicit command line options.
# savefile_directory =
# Save all save states (*.state) to this directory.
# This will be overridden by explicit command line options.
# savestate_directory =
# Automatically saves a savestate at the end of RetroArch's lifetime.
# The path is $SRAM_PATH.auto.
# RetroArch will automatically load any savestate with this path on startup.
# savestate_auto_save = false
# Load libretro from a dynamic location for dynamically built RetroArch.
# This option is mandatory.
# libretro_path = "/path/to/libretro.so"
# Environment variables internally in RetroArch.
# Implementations can tap into this user-specificed information to enable functionality
# that is deemed too obscure to expose directly.
# Some variables might be "standardized" at a later time if needed.
# The string is formatted as key value pairs delimited by a semicolon ';'.
# Any white space between the delimiter ';' and the '=' is significant.
# I.e.: "key1=value1;key2=value2;..."
# environment_variables =
# Sets the "system" directory.
# Implementations can query for this directory to load BIOSes, system-specific configs, etc.
# system_directory =
#### Video
# Video driver to use. "gl", "xvideo", "sdl" or "ext" (external API driver)
# video_driver = "gl"
# Path to external video driver using the RetroArch driver API.
# video_external_driver =
# Windowed xscale and yscale
# (Real x res: base_size * xscale * aspect_ratio, real y res: base_size * yscale)
# video_xscale = 3.0
# video_yscale = 3.0
# Fullscreen resolution. Resolution of 0 uses the resolution of the desktop.
# video_fullscreen_x = 0
# video_fullscreen_y = 0
# Start in fullscreen. Can be changed at runtime.
# video_fullscreen = false
# If fullscreen, prefer using a windowed fullscreen mode.
# video_windowed_fullscreen = false
# Forcibly disable composition. Only works in Windows Vista/7 for now.
# video_disable_composition = false
# Video vsync.
# video_vsync = true
# Smoothens picture with bilinear filtering. Should be disabled if using pixel shaders.
# video_smooth = true
# Forces rendering area to stay equal to game aspect ratio or as defined in video_aspect_ratio.
# video_force_aspect = true
# A floating point value for video aspect ratio (width / height).
# If this is not set, aspect ratio is assumed to be automatic.
# Behavior then is defined by video_aspect_ratio_auto.
# video_aspect_ratio =
# If this is true and video_aspect_ratio is not set,
# aspect ratio is decided by libretro implementation.
# If this is false, 1:1 PAR will always be assumed if video_aspect_ratio is not set.
# video_aspect_ratio_auto = false
# Forces cropping of overscanned frames. Crops away top 7 scanlines and 8 bottom scanlines. (15/15 for interlaced frames).
# video_crop_overscan = false
# Path to Cg shader.
# video_cg_shader = "/path/to/cg/shader.cg"
# Path to bSNES XML shader (GLSL only). If both Cg shader path and XML shader path are defined,
# Cg shader will take priority unless overridden in video_shader_type.
# video_bsnes_shader = "/path/to/bsnes/xml/shader.shader"
# Which shader type to use. Valid values are "cg", "bsnes", "none" and "auto"
# video_shader_type = auto
# Defines a directory where XML shaders are kept.
# video_shader_dir =
# Render to texture first. Useful when doing multi-pass shaders or control the output of shaders better.
# video_render_to_texture = false
# Defines the video scale of render-to-texture.
# The output FBO size is scaled by these amounts against the input size (typically 256 * 224 for SNES).
# video_fbo_scale_x = 2.0
# video_fbo_scale_y = 2.0
# Define shader to use for second pass (needs render-to-texture).
# video_second_pass_shader = "/path/to/second/shader.{cg,shader}"
# Defines if bilinear filtering is used during second pass (needs render-to-texture).
# video_second_pass_smooth = true
# CPU-based filter. Path to a bSNES CPU filter (*.filter)
# video_filter =
# Path to a TTF font used for rendering messages. This path must be defined to enable fonts.
# Do note that the _full_ path of the font is necessary!
# video_font_path =
# Size of the TTF font rendered.
# video_font_size = 48
# Attempt to scale the font to fit better for multiple window sizes.
# video_font_scale = true
# Enable usage of OSD messages.
# video_font_enable = true
# Offset for where messages will be placed on screen. Values are in range 0.0 to 1.0 for both x and y values.
# [0.0, 0.0] maps to the lower left corner of the screen.
# video_message_pos_x = 0.05
# video_message_pos_y = 0.05
# Color for message. The value is treated as a hexadecimal value.
# It is a regular RGB hex number, i.e. red is "ff0000".
# video_message_color = ffffff
# Video refresh rate of your monitor.
# Used to calculate a suitable audio input rate.
# video_refresh_rate = 59.95
# Allows libretro cores to set rotation modes.
# Setting this to false will honor, but ignore this request.
# This is useful for vertically oriented games where one manually rotates the monitor.
# video_allow_rotate = true
#### Audio
# Enable audio.
# audio_enable = true
# Audio output samplerate.
# audio_out_rate = 48000
# When altering audio_in_rate on-the-fly, define by how much each time.
# audio_rate_step = 0.25
# Audio driver backend. Depending on configuration possible candidates are: alsa, pulse, oss, jack, rsound, roar, openal, sdl, xaudio and ext (external driver).
# audio_driver =
# Path to external audio driver using the RetroArch audio driver API.
# audio_external_driver =
# Override the default audio device the audio_driver uses. This is driver dependant. E.g. ALSA wants a PCM device, OSS wants a path (e.g. /dev/dsp), Jack wants portnames (e.g. system:playback1,system:playback_2), and so on ...
# audio_device =
# External DSP plugin that processes audio before it's sent to the driver.
# audio_dsp_plugin =
# Will sync (block) on audio. Recommended.
# audio_sync = true
# Desired audio latency in milliseconds. Might not be honored if driver can't provide given latency.
# audio_latency = 64
# Enable experimental audio rate control.
# audio_rate_control = false
# Controls audio rate control delta. Defines how much input rate can be adjusted dynamically.
# Input rate = in_rate * (1.0 +/- audio_rate_control_delta)
# audio_rate_control_delta = 0.005
#### Input
# Input driver. Depending on video driver, it might force a different input driver.
# input_driver = sdl
# Defines axis threshold. Possible values are [0.0, 1.0]
# input_axis_threshold = 0.5
# Keyboard input. Will recognize normal keypresses and special keys like "left", "right", and so on.
# Keyboard input, Joypad and Joyaxis will all obey the "nul" bind, which disables the bind completely,
# rather than relying on a default.
# input_player1_a = x
# input_player1_b = z
# input_player1_y = a
# input_player1_x = s
# input_player1_start = enter
# input_player1_select = rshift
# input_player1_l = q
# input_player1_r = w
# input_player1_left = left
# input_player1_right = right
# input_player1_up = up
# input_player1_down = down
# input_player1_l2 =
# input_player1_r2 =
# input_player1_l3 =
# input_player1_r3 =
# Two analog sticks (DualShock-esque).
# Bound as usual, however, if a real analog axis is bound,
# it can be read as a true analog.
# Positive X axis is right, Positive Y axis is down.
# input_player1_l_x_plus =
# input_player1_l_x_minus =
# input_player1_l_y_plus =
# input_player1_l_y_minus =
# input_player1_r_x_plus =
# input_player1_r_x_minus =
# input_player1_r_y_plus =
# input_player1_r_y_minus =
# If desired, it is possible to override which joypads are being used for player 1 through 5. First joypad available is 0.
# input_player1_joypad_index = 0
# input_player2_joypad_index = 1
# input_player3_joypad_index = 2
# input_player4_joypad_index = 3
# input_player5_joypad_index = 4
# Player 6-8 is not directly expected by libretro API, but we'll futureproof it.
# input_player6_joypad_index = 5
# input_player7_joypad_index = 6
# input_player8_joypad_index = 7
# Joypad buttons.
# Figure these out by using RetroArch-Phoenix or retroarch-joyconfig.
# You can use joypad hats with hnxx, where n is the hat, and xx is a string representing direction.
# E.g. "h0up"
# input_player1_a_btn =
# input_player1_b_btn =
# input_player1_y_btn =
# input_player1_x_btn =
# input_player1_start_btn =
# input_player1_select_btn =
# input_player1_l_btn =
# input_player1_r_btn =
# input_player1_left_btn =
# input_player1_right_btn =
# input_player1_up_btn =
# input_player1_down_btn =
# input_player1_l2_btn =
# input_player1_r2_btn =
# input_player1_l3_btn =
# input_player1_r3_btn =
# Axis for RetroArch D-Pad.
# Needs to be either '+' or '-' in the first character signaling either positive or negative direction of the axis, then the axis number.
# Do note that every other input option has the corresponding _btn and _axis binds as well; they are omitted here for clarity.
# input_player1_left_axis =
# input_player1_right_axis =
# input_player1_up_axis =
# input_player1_down_axis =
# Holding the turbo while pressing another button will let the button enter a turbo mode
# where the button state is modulated with a periodic signal.
# The modulation stops when the button itself (not turbo button) is released.
# input_player1_turbo =
# Describes the period and how long of that period a turbo-enabled button should behave.
# Numbers are described in frames.
# input_turbo_period = 6
# input_turbo_duty_cycle = 3
# This goes all the way to player 8 (*_player2_*, *_player3_*, etc), but omitted for clarity.
# All input binds have corresponding binds for keyboard (none), joykeys (_btn) and joyaxes (_axis) as well.
# Toggles fullscreen.
# input_toggle_fullscreen = f
# Saves state.
# input_save_state = f2
# Loads state.
# input_load_state = f4
# State slots. With slot set to 0, save state name is *.state (or whatever defined on commandline).
# When slot is != 0, path will be $path%d, where %d is slot number.
# input_state_slot_increase = f7
# input_state_slot_decrease = f6
# Toggles between fast-forwarding and normal speed.
# input_toggle_fast_forward = space
# Hold for fast-forward. Releasing button disables fast-forward.
# input_hold_fast_forward = l
# Key to exit emulator cleanly.
# Killing it in any hard way (SIGTERM, SIGKILL, etc, will terminate emulator without saving RAM, etc.)
# input_exit_emulator = escape
# Decrease/increase input sample rate on the fly. Amount to decrease/increase is defined by audio_rate_step.
# input_rate_step_up = kp_plus
# input_rate_step_down = kp_minus
# Applies next and previous XML/Cg shader in directory.
# input_shader_next = m
# input_shader_prev = n
# Hold button down to rewind. Rewinding must be enabled.
# input_rewind = r
# Toggle between recording and not.
# input_movie_record_toggle = o
# Toggle between paused and non-paused state
# input_pause_toggle = p
# Frame advance when game is paused
# input_frame_advance = k
# Reset the emulated SNES.
# input_reset = h
# Configures DSP plugin
# input_dsp_config = c
# Cheats.
# input_cheat_index_plus = y
# input_cheat_index_minus = t
# input_cheat_toggle = u
# Mute/unmute audio
# input_audio_mute = f9
# Take screenshot
# input_screenshot = f8
# Netplay flip players.
# input_netplay_flip_players = i
# Hold for slowmotion.
# input_slowmotion = e
#### Misc
# Enable rewinding. This will take a performance hit when playing, so it is disabled by default.
# Do note that rewinding will only work properly when using bSNES libretro core atm.
# rewind_enable = false
# Rewinding buffer size in megabytes. Bigger rewinding buffer means you can rewind longer.
# The buffer should be approx. 20MB per minute of buffer time.
# rewind_buffer_size = 20
# Rewind granularity. When rewinding defined number of frames, you can rewind several frames at a time, increasing the rewinding speed.
# rewind_granularity = 1
# Pause gameplay when window focus is lost.
# pause_nonactive = true
# Autosaves the non-volatile SRAM at a regular interval. This is disabled by default unless set otherwise.
# The interval is measured in seconds. A value of 0 disables autosave.
# autosave_interval =
# When being client over netplay, use keybinds for player 1.
# netplay_client_swap_input = false
# Path to XML cheat database (as used by bSNES).
# cheat_database_path =
# Path to XML cheat config, a file which keeps track of which
# cheat settings are used for individual games.
# If the file does not exist, it will be created.
# cheat_settings_path =
# Directory to dump screenshots to.
# screenshot_directory =
# Records video assuming video is hi-res.
# video_hires_record = false
# Enables lossless RGB H.264 recording if possible (if not, FFV1 is used).
# video_h264_record = true
# Records video after CPU video filter.
# video_post_filter_record = false
# Records output of GPU shaded material if available.
# video_gpu_record = false
# Screenshots output of GPU shaded material if available.
# video_gpu_screenshot = true
# Block SRAM from being overwritten when loading save states.
# Might potentially lead to buggy games.
# block_sram_overwrite = false
# When saving a savestate, save state index is automatically increased before
# it is saved.
# Also, when loading a ROM, the index will be set to the highest existing index.
# There is no upper bound on the index.
# savestate_auto_index = false
# Slowmotion ratio. When slowmotion, game will slow down by factor.
# slowmotion_ratio = 3.0
# Enable stdin/network command interface.
# network_cmd_enable = false
# network_cmd_port = 55355
# stdin_cmd_enable = false

View File

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="hello">Hello World, MainActivity!</string>
<string name="app_name">RetroArch</string>
<string name="input_method">Input Method</string>
<string name="file_type_icon">File type icon</string>
</resources>

View File

@ -1,117 +0,0 @@
package com.retroarch.fileio;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Set;
import com.retroarch.R;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.SectionIndexer;
import android.widget.TextView;
public class FileArrayAdapter extends ArrayAdapter<Option> implements SectionIndexer
{
HashMap<String, Integer> alphaIndexer;
String[] sections;
private Context c;
private int id;
private List<Option>items;
public FileArrayAdapter(Context context, int textViewResourceId,
List<Option> objects) {
super(context, textViewResourceId, objects);
c = context;
id = textViewResourceId;
items = objects;
initAlphaIndexer();
}
private void initAlphaIndexer()
{
alphaIndexer = new HashMap<String, Integer>();
int size = items.size();
for (int x = 0; x < size; x++) {
Option o = items.get(x);
String ch = o.name.substring(0, 1);
ch = ch.toUpperCase();
if (!alphaIndexer.containsKey(ch))
{
alphaIndexer.put(ch, x);
}
}
Set<String> sectionLetters = alphaIndexer.keySet();
ArrayList<String> sectionList = new ArrayList<String>(sectionLetters);
Collections.sort(sectionList);
sections = new String[sectionList.size()];
sectionList.toArray(sections);
}
public Option getItem(int i)
{
return items.get(i);
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
View v = convertView;
if (v == null) {
LayoutInflater vi = (LayoutInflater)c.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
v = vi.inflate(id, null);
}
final Option o = items.get(position);
if (o != null) {
TextView t1 = (TextView) v.findViewById(R.id.TextView01);
TextView t2 = (TextView) v.findViewById(R.id.TextView02);
if(t1!=null)
{
t1.setText(o.name);
}
if(t2!=null)
{
t2.setText(o.data);
}
}
return v;
}
public int getPositionForSection(int section)
{
// FIXME
if (section >= sections.length)
{
return 0;
}
return alphaIndexer.get(sections[section]);
}
public int getSectionForPosition(int position)
{
return 1;
}
public Object[] getSections()
{
return sections;
}
}

View File

@ -1,249 +0,0 @@
package com.retroarch.fileio;
import java.io.File;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Stack;
import com.retroarch.R;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.os.Environment;
import android.view.KeyEvent;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.Button;
import android.widget.ListView;
import android.widget.Toast;
public class FileChooser extends Activity
{
public static final String EXTRA_START_DIR = "StartDir";
public static final String EXTRA_EXTENSIONS = "Extensions";
public static final String EXTRA_TEMP_DIR = "TempDir";
public static final String EXTRA_SELECT_DIR = "SelectDir";
public static final String PAYLOAD_FILENAME = "Filename";
public static final String PAYLOAD_SELECTED_DIR = "DirSelected";
private File currentDir;
private FileArrayAdapter adapter;
private String _startDir;
private String _extensions;
private String _tempDir;
private String _selectDir;
private Stack<String> _dirStack;
private ListView _view;
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.file_choose);
_view = (ListView)findViewById(R.id.fileChooserView);
_startDir = getIntent().getStringExtra(EXTRA_START_DIR);
_extensions = getIntent().getStringExtra(EXTRA_EXTENSIONS);
_tempDir = getIntent().getStringExtra(EXTRA_TEMP_DIR);
_selectDir = getIntent().getStringExtra(EXTRA_SELECT_DIR);
// clamp start dir and remove the /
if (_startDir == null)
{
_startDir = Environment.getExternalStorageDirectory().getAbsolutePath();
}
else if (_startDir.endsWith("/"))
{
_startDir = _startDir.substring(0, _startDir.length() - 1);
}
// push the start dir onto the stack
_dirStack = new Stack<String>();
_dirStack.push(_startDir);
// clamp extentions to all or extra specified
if (_extensions == null)
{
_extensions = ".*";
}
// clamp temp dir
if (_tempDir == null)
{
_tempDir = Environment.getExternalStorageDirectory().getAbsolutePath();
}
// regular filesystem dir
currentDir = new File(_startDir);
fill(currentDir);
// are we dir selecting?, add button
if (_selectDir == null)
{
// hide button
Button b = (Button)findViewById(R.id.fileChooserSubmit);
b.setVisibility(Button.GONE);
}
else
{
// add on click submit
Button b = (Button)findViewById(R.id.fileChooserSubmit);
b.setOnClickListener(new OnClickListener()
{
public void onClick(View v)
{
String s = _dirStack.peek();
Toast.makeText(FileChooser.this, "Selected: " + s, Toast.LENGTH_SHORT).show();
Intent intent=new Intent();
intent.putExtra(FileChooser.PAYLOAD_SELECTED_DIR, s);
setResult(RESULT_OK, intent);
finish();
}
});
}
}
public boolean onCreateOptionsMenu(Menu menu)
{
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.main_menu, menu);
return true;
}
public boolean onOptionsItemSelected(MenuItem item)
{
switch (item.getItemId())
{
case R.id.main:
this.finish();
break;
case R.id.open:
//TODO: Return to root dir
break;
default:
Toast.makeText(this, "MenuItem " + item.getTitle() + " selected.", Toast.LENGTH_SHORT).show();
break;
}
return true;
}
private void fill(File f)
{
File[]dirs = f.listFiles();
this.setTitle("Path: "+f.getAbsolutePath());
List<Option>dir = new ArrayList<Option>();
List<Option>fls = new ArrayList<Option>();
try
{
for(File ff: dirs)
{
if(ff.isDirectory())
{
dir.add(new Option(ff.getName() + "/","Folder",ff.getAbsolutePath()));
}
else
{
int dotIndex = ff.getName().lastIndexOf('.');
if (dotIndex > 0)
{
String extension = ff.getName().substring(dotIndex+1).toLowerCase();
if (extension.matches(_extensions))
{
fls.add(new Option(ff.getName(),"File Size: "+ff.length(),ff.getAbsolutePath()));
}
}
}
}
}
catch(Exception e)
{
}
Collections.sort(dir);
Collections.sort(fls);
dir.addAll(fls);
dir.add(0,new Option("..", "Parent Directory", f.getParent()));
adapter = new FileArrayAdapter(FileChooser.this,R.layout.file_view,dir);
_view.setAdapter(adapter);
_view.setOnItemClickListener(new OnItemClickListener()
{
public void onItemClick(AdapterView<?> arg0, View arg1,
int arg2, long arg3)
{
int pos = arg0.getPositionForView(arg1);
Option o = adapter.getItem(pos);
if(o.data.equalsIgnoreCase("folder")|| o.data.equalsIgnoreCase("parent directory"))
{
if (o.path != null)
{
currentDir = new File(o.path);
fill(currentDir);
_dirStack.push(o.path);
}
}
else
{
onFileClick(o);
}
}
});
}
private void onFileClick(Option o)
{
Intent intent=new Intent();
intent.putExtra("PATH", o.path);
intent.putExtra("NAME", o.name);
setResult(RESULT_OK, intent);
finish();
}
@Override
public boolean onKeyDown(int keyCode, KeyEvent event)
{
if (keyCode == KeyEvent.KEYCODE_BACK)
{
if (_dirStack.size() > 1)
{
_dirStack.pop();
File file = new File(_dirStack.peek());
currentDir = file;
fill(currentDir);
}
else
{
Intent intent = new Intent();
setResult(RESULT_OK, intent);
finish();
}
return true;
}
return super.onKeyDown(keyCode, event);
}
}

View File

@ -1,23 +0,0 @@
package com.retroarch.fileio;
public class Option implements Comparable<Option>
{
public String name;
public String data;
public String path;
public Option(String n,String d,String p)
{
name = n;
data = d;
path = p;
}
public int compareTo(Option o)
{
if(this.name != null)
return this.name.toLowerCase().compareTo(o.name.toLowerCase());
else
throw new IllegalArgumentException();
}
}

View File

@ -1,121 +0,0 @@
/* RetroArch - A frontend for libretro.
* Copyright (C) 2010-2012 - Hans-Kristian Arntzen
* Copyright (C) 2011-2012 - Daniel De Matteis
*
* RetroArch is free software: you can redistribute it and/or modify it under the terms
* of the GNU General Public License as published by the Free Software Found-
* ation, either version 3 of the License, or (at your option) any later version.
*
* RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with RetroArch.
* If not, see <http://www.gnu.org/licenses/>.
*/
package com.retroarch;
import com.retroarch.R;
import com.retroarch.fileio.FileChooser;
import android.app.Activity;
import android.app.NativeActivity;
import android.content.Intent;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.widget.Toast;
import android.os.Bundle;
public class phoenix extends Activity
{
static private final int ACTIVITY_LOAD_ROM = 0;
static private final int ACTIVITY_LOAD_LIBRETRO_CORE = 1;
static private String libretro_path;
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
this.setTitle("RetroArch Phoenix");
}
public boolean onCreateOptionsMenu(Menu menu)
{
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.main_menu, menu);
return true;
}
public boolean onOptionsItemSelected(MenuItem item)
{
Intent myIntent;
switch (item.getItemId())
{
case R.id.main:
this.finish();
break;
case R.id.open:
Toast.makeText(this, "Select a ROM image from the Filebrowser.", Toast.LENGTH_SHORT).show();
myIntent = new Intent(this, FileChooser.class);
startActivityForResult(myIntent, ACTIVITY_LOAD_ROM);
break;
case R.id.libretro:
Toast.makeText(this, "Select a libretro core from the Filebrowser.", Toast.LENGTH_SHORT).show();
myIntent = new Intent(this, FileChooser.class);
startActivityForResult(myIntent, ACTIVITY_LOAD_LIBRETRO_CORE);
break;
default:
Toast.makeText(this, "MenuItem " + item.getTitle() + " selected.", Toast.LENGTH_SHORT).show();
break;
}
return true;
}
protected void onActivityResult(int requestCode, int resultCode, Intent data)
{
Intent myIntent;
switch(requestCode)
{
case ACTIVITY_LOAD_ROM:
if(data.getStringExtra("PATH") != null)
{
if(libretro_path != null)
{
Toast.makeText(this, "Loading: ["+ data.getStringExtra("PATH") + "]...", Toast.LENGTH_SHORT).show();
myIntent = new Intent(this, NativeActivity.class);
myIntent.putExtra("ROM", data.getStringExtra("PATH"));
myIntent.putExtra("LIBRETRO", libretro_path);
startActivity(myIntent);
}
else
Toast.makeText(this, "ERROR - No libretro core has been selected, cannot start RetroArch.", Toast.LENGTH_SHORT).show();
}
break;
case ACTIVITY_LOAD_LIBRETRO_CORE:
if(data.getStringExtra("PATH") != null)
{
Toast.makeText(this, "Libretro core path set to: ["+ data.getStringExtra("PATH") + "].", Toast.LENGTH_SHORT).show();
libretro_path = data.getStringExtra("PATH");
}
break;
}
}
@Override
protected void onPause()
{
super.onPause();
}
@Override
protected void onResume()
{
super.onResume();
}
}

View File

@ -0,0 +1,251 @@
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;
public final boolean parentItem;
protected final int typeIndex;
protected final boolean enabled;
public FileWrapper(File aFile, boolean aIsParentItem, boolean aIsEnabled)
{
file = aFile;
typeIndex = aIsParentItem ? 0 : (file.isDirectory() ? 1 : 0) + (file.isFile() ? 2 : 0);
parentItem = aIsParentItem;
enabled = aIsParentItem || aIsEnabled;
}
@Override public boolean isEnabled()
{
return enabled;
}
@Override public String getText()
{
return parentItem ? "[Parent Directory]" : file.getName();
}
@Override public int getIconResourceId()
{
if(!parentItem)
{
return file.isFile() ? R.drawable.ic_file : R.drawable.ic_dir;
}
else
{
return R.drawable.ic_dir;
}
}
@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<FileWrapper> adapter;
private File listedDirectory;
public static class BackStackItem implements Parcelable
{
public String path;
public boolean parentIsBack;
public BackStackItem(String aPath, boolean aParentIsBack)
{
path = aPath;
parentIsBack = aParentIsBack;
}
private BackStackItem(Parcel aIn)
{
path = aIn.readString();
parentIsBack = aIn.readInt() != 0;
}
public int describeContents()
{
return 0;
}
public void writeToParcel(Parcel out, int flags)
{
out.writeString(path);
out.writeInt(parentIsBack ? 1 : 0);
}
public static final Parcelable.Creator<BackStackItem> CREATOR = new Parcelable.Creator<BackStackItem>()
{
public BackStackItem createFromParcel(Parcel in) { return new BackStackItem(in); }
public BackStackItem[] newArray(int size) { return new BackStackItem[size]; }
};
}
private ArrayList<BackStackItem> backStack;
@Override public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.line_list);
// Setup the list
adapter = new IconAdapter<FileWrapper>(this, R.layout.line_list_item);
ListView list = (ListView)findViewById(R.id.list);
list.setAdapter(adapter);
list.setOnItemClickListener(this);
// Load Directory
if(savedInstanceState != null)
{
backStack = savedInstanceState.getParcelableArrayList("BACKSTACK");
}
if(backStack == null || backStack.size() == 0)
{
backStack = new ArrayList<BackStackItem>();
backStack.add(new BackStackItem(Environment.getExternalStorageDirectory().getPath(), false));
}
wrapFiles();
}
@Override protected void onSaveInstanceState(Bundle aState)
{
super.onSaveInstanceState(aState);
aState.putParcelableArrayList("BACKSTACK", backStack);
}
@Override public void onItemClick(AdapterView<?> aListView, View aView, int aPosition, long aID)
{
final FileWrapper item = adapter.getItem(aPosition);
if(item.parentItem && backStack.get(backStack.size() - 1).parentIsBack)
{
backStack.remove(backStack.size() - 1);
wrapFiles();
return;
}
final File selected = item.parentItem ? listedDirectory.getParentFile() : item.file;
if(selected.isDirectory())
{
backStack.add(new BackStackItem(selected.getAbsolutePath(), !item.parentItem));
wrapFiles();
}
else
{
final Intent intent = new Intent(this, selected.isFile() ? NativeActivity.class : DirectoryActivity.class)
.putExtra("ROM", selected.getAbsolutePath())
.putExtra("LIBRETRO", getIntent().getStringExtra("LIBRETRO"));
startActivity(intent);
}
}
@Override
public boolean onKeyDown(int keyCode, KeyEvent event)
{
if(keyCode == KeyEvent.KEYCODE_BACK && backStack.size() > 1)
{
backStack.remove(backStack.size() - 1);
wrapFiles();
return true;
}
return super.onKeyDown(keyCode, event);
}
@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()
{
listedDirectory = new File(backStack.get(backStack.size() - 1).path);
if(!listedDirectory.isDirectory())
{
throw new IllegalArgumentException("Directory is not valid.");
}
adapter.clear();
setTitle(listedDirectory.getAbsolutePath());
if(listedDirectory.getParentFile() != null)
{
adapter.add(new FileWrapper(null, true, true));
}
// Copy new items
final File[] files = listedDirectory.listFiles();
if(files != null)
{
for(File file: files)
{
adapter.add(new FileWrapper(file, false, file.isDirectory() || true));
}
}
// Sort items
adapter.sort(new Comparator<FileWrapper>()
{
@Override public int compare(FileWrapper aLeft, FileWrapper aRight)
{
return aLeft.compareTo(aRight);
};
});
// Update
adapter.notifyDataSetChanged();
}
}

View File

@ -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<T extends IconAdapterItem> extends ArrayAdapter<T>
{
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();
}
}

View File

@ -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
{
private IconAdapter<ModuleWrapper> adapter;
@Override public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.line_list);
// Setup the list
adapter = new IconAdapter<ModuleWrapper>(this, R.layout.line_list_item);
ListView list = (ListView)findViewById(R.id.list);
list.setAdapter(adapter);
list.setOnItemClickListener(this);
setTitle("Select Emulator");
// Populate the list
final String modulePath = getApplicationInfo().nativeLibraryDir;
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);
}
}