Merge pull request #2501 from sigmabeta/android-kill-old-ui

Android: Remove the old UI, and remove support for pre-5.0 devices.
This commit is contained in:
Ryan Houdek 2015-06-09 03:57:47 -04:00
commit 0047ea8852
53 changed files with 396 additions and 3536 deletions

View File

@ -12,7 +12,7 @@ android {
defaultConfig {
applicationId "org.dolphinemu.dolphinemu"
minSdkVersion 18
minSdkVersion 21
targetSdkVersion 21
// TODO This should be set to the Buildbot build number for release builds, and be "1" for debug builds.

View File

@ -18,6 +18,7 @@
<uses-permission android:name="android.permission.INTERNET" />
<application
android:label="@string/app_name"
android:icon="@drawable/ic_launcher"
android:allowBackup="true"
android:supportsRtl="true"
@ -26,7 +27,6 @@
<activity
android:name=".activities.GameGridActivity"
android:label="@string/title_new_ui"
android:theme="@style/DolphinGamecube">
<!-- This intentfilter marks this Activity as the one that gets launched from Home screen. -->
@ -48,39 +48,10 @@
android:theme="@style/DolphinSettingsGamecube"
android:label="@string/grid_menu_settings"/>
<activity
android:name="org.dolphinemu.dolphinemu.gamelist.GameListActivity"
android:label="@string/app_name"
android:theme="@android:style/Theme.Holo.Light" >
<!-- Having a second activity with this intent-filter means we have two choices from the home screen. -->
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name=".activities.EmulationActivity"
android:theme="@style/DolphinEmulationGamecube"/>
<activity
android:name=".about.AboutActivity"
android:theme="@android:style/Theme.Holo.Light" />
<activity
android:name=".emulation.EmulationActivity"
android:screenOrientation="landscape" />
<activity
android:name=".settings.input.overlayconfig.OverlayConfigActivity"
android:screenOrientation="landscape"
android:theme="@android:style/Theme.NoTitleBar.Fullscreen"/>
<activity
android:name=".settings.PrefsActivity"
android:label="@string/settings"
android:theme="@android:style/Theme.Holo.Light" />
<service android:name=".services.AssetCopyService"/>

View File

@ -1,122 +0,0 @@
/**
* Copyright 2014 Dolphin Emulator Project
* Licensed under GPLv2+
* Refer to the license.txt file included.
*/
package org.dolphinemu.dolphinemu.about;
import org.dolphinemu.dolphinemu.R;
import org.dolphinemu.dolphinemu.utils.EGLHelper;
import android.app.Activity;
import android.app.Fragment;
import android.app.FragmentManager;
import android.os.Bundle;
import android.support.v13.app.FragmentPagerAdapter;
import android.support.v4.view.ViewPager;
/**
* Activity for the about menu, which displays info
* related to the CPU and GPU. Along with misc other info.
*/
public final class AboutActivity extends Activity
{
private final EGLHelper eglHelper = new EGLHelper(EGLHelper.EGL_OPENGL_ES2_BIT);
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
// Set the view pager
setContentView(R.layout.viewpager);
// Initialize the viewpager.
final ViewPager viewPager = (ViewPager) findViewById(R.id.pager);
viewPager.setAdapter(new ViewPagerAdapter(getFragmentManager()));
}
@Override
public void onDestroy()
{
super.onDestroy();
eglHelper.closeHelper();
}
/**
* {@link FragmentPagerAdapter} subclass responsible for handling
* the individual {@link Fragment}s within the {@link ViewPager}.
*/
private final class ViewPagerAdapter extends FragmentPagerAdapter
{
private final String[] pageTitles = {
getString(R.string.general),
getString(R.string.cpu),
getString(R.string.gles_two),
getString(R.string.gles_three),
getString(R.string.desktop_gl),
};
public ViewPagerAdapter(FragmentManager fm)
{
super(fm);
}
@Override
public Fragment getItem(int position)
{
if (position == 0)
{
return new DolphinInfoFragment();
}
else if (position == 1)
{
return new CPUInfoFragment(); // CPU
}
else if (position == 2) // GLES 2
{
return new GLES2InfoFragment();
}
else if (position == 3) // GLES 3 or OpenGL (depending on circumstances)
{
if (eglHelper.supportsGLES3())
return new GLES3InfoFragment();
else
return new GLInfoFragment(); // GLES3 not supported, but OpenGL is.
}
else if (position == 4) // OpenGL fragment
{
return new GLInfoFragment();
}
// This should never happen.
return null;
}
@Override
public int getCount()
{
if (eglHelper.supportsGLES3() && eglHelper.supportsOpenGL())
{
return 5;
}
else if (!eglHelper.supportsGLES3() && !eglHelper.supportsOpenGL())
{
return 3;
}
else // Either regular OpenGL or GLES3 isn't supported
{
return 4;
}
}
@Override
public CharSequence getPageTitle(int position)
{
return pageTitles[position];
}
}
}

View File

@ -1,48 +0,0 @@
/**
* Copyright 2014 Dolphin Emulator Project
* Licensed under GPLv2+
* Refer to the license.txt file included.
*/
package org.dolphinemu.dolphinemu.about;
/**
* Represents an item within an info fragment in the About menu.
*/
final class AboutFragmentItem
{
private final String title;
private final String subtitle;
/**
* Constructor
*
* @param title The title of this item.
* @param subtitle The subtitle for this item.
*/
public AboutFragmentItem(String title, String subtitle)
{
this.title = title;
this.subtitle = subtitle;
}
/**
* Gets the title of this item.
*
* @return the title of this item.
*/
public String getTitle()
{
return title;
}
/**
* Gets the subtitle of this item.
*
* @return the subtitle of this item.
*/
public String getSubTitle()
{
return subtitle;
}
}

View File

@ -1,67 +0,0 @@
/**
* Copyright 2014 Dolphin Emulator Project
* Licensed under GPLv2+
* Refer to the license.txt file included.
*/
package org.dolphinemu.dolphinemu.about;
import java.util.List;
import org.dolphinemu.dolphinemu.R;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.TextView;
/**
* {@link ArrayAdapter} subclass specifically for the
* information fragments within the about menu.
*/
final class AboutInfoFragmentAdapter extends ArrayAdapter<AboutFragmentItem>
{
private final int id;
private final List<AboutFragmentItem> items;
public AboutInfoFragmentAdapter(Context ctx, int id, List<AboutFragmentItem> items)
{
super(ctx, id, items);
this.id = id;
this.items = items;
}
@Override
public AboutFragmentItem getItem(int index)
{
return items.get(index);
}
@Override
public View getView(int position, View convertView, ViewGroup parent)
{
if (convertView == null)
{
LayoutInflater vi = LayoutInflater.from(getContext());
convertView = vi.inflate(id, parent, false);
}
final AboutFragmentItem item = items.get(position);
if (item != null)
{
TextView title = (TextView) convertView.findViewById(R.id.AboutItemTitle);
TextView subtitle = (TextView) convertView.findViewById(R.id.AboutItemSubTitle);
if (title != null)
title.setText(item.getTitle());
if (subtitle != null)
subtitle.setText(item.getSubTitle());
}
return convertView;
}
}

View File

@ -1,52 +0,0 @@
/**
* Copyright 2014 Dolphin Emulator Project
* Licensed under GPLv2+
* Refer to the license.txt file included.
*/
package org.dolphinemu.dolphinemu.about;
import java.util.ArrayList;
import java.util.List;
import org.dolphinemu.dolphinemu.R;
import org.dolphinemu.dolphinemu.utils.CPUHelper;
import android.app.ListFragment;
import android.os.Build;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ListView;
/**
* {@link ListFragment class that is responsible
* for displaying information related to the CPU.
*/
public final class CPUInfoFragment extends ListFragment
{
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
ListView rootView = (ListView) inflater.inflate(R.layout.gamelist_listview, container, false);
List<AboutFragmentItem> items = new ArrayList<AboutFragmentItem>();
CPUHelper cpuHelper = new CPUHelper(getActivity());
items.add(new AboutFragmentItem(getString(R.string.cpu_info), cpuHelper.getProcessorInfo()));
items.add(new AboutFragmentItem(getString(R.string.cpu_type), cpuHelper.getProcessorType()));
items.add(new AboutFragmentItem(getString(R.string.cpu_abi_one), Build.CPU_ABI));
items.add(new AboutFragmentItem(getString(R.string.cpu_abi_two), Build.CPU_ABI2));
items.add(new AboutFragmentItem(getString(R.string.num_cores), Integer.toString(cpuHelper.getNumCores())));
items.add(new AboutFragmentItem(getString(R.string.cpu_features), cpuHelper.getFeatures()));
items.add(new AboutFragmentItem(getString(R.string.cpu_hardware), Build.HARDWARE));
if (CPUHelper.isARM())
items.add(new AboutFragmentItem(getString(R.string.cpu_implementer), cpuHelper.getImplementer()));
AboutInfoFragmentAdapter adapter = new AboutInfoFragmentAdapter(getActivity(), R.layout.about_layout, items);
rootView.setAdapter(adapter);
return rootView;
}
}

View File

@ -1,48 +0,0 @@
/**
* Copyright 2014 Dolphin Emulator Project
* Licensed under GPLv2+
* Refer to the license.txt file included.
*/
package org.dolphinemu.dolphinemu.about;
import android.app.ListFragment;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ListView;
import java.util.ArrayList;
import java.util.List;
import org.dolphinemu.dolphinemu.NativeLibrary;
import org.dolphinemu.dolphinemu.R;
import org.dolphinemu.dolphinemu.utils.EGLHelper;
/**
* Represents the about screen.
*/
public final class DolphinInfoFragment extends ListFragment
{
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
ListView rootView = (ListView) inflater.inflate(R.layout.gamelist_listview, container, false);
EGLHelper eglHelper = new EGLHelper(EGLHelper.EGL_OPENGL_ES2_BIT);
final String yes = getString(R.string.yes);
final String no = getString(R.string.no);
List<AboutFragmentItem> Input = new ArrayList<AboutFragmentItem>();
Input.add(new AboutFragmentItem(getString(R.string.build_revision), NativeLibrary.GetVersionString()));
Input.add(new AboutFragmentItem(getString(R.string.supports_gles3), eglHelper.supportsGLES3() ? yes : no));
Input.add(new AboutFragmentItem(getString(R.string.supports_neon), NativeLibrary.SupportsNEON() ? yes : no));
AboutInfoFragmentAdapter adapter = new AboutInfoFragmentAdapter(getActivity(), R.layout.about_layout, Input);
rootView.setAdapter(adapter);
rootView.setEnabled(false); // Makes the list view non-clickable.
return rootView;
}
}

View File

@ -1,82 +0,0 @@
/**
* Copyright 2014 Dolphin Emulator Project
* Licensed under GPLv2+
* Refer to the license.txt file included.
*/
package org.dolphinemu.dolphinemu.about;
import android.app.ListFragment;
import android.opengl.GLES20;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ListView;
import org.dolphinemu.dolphinemu.R;
import org.dolphinemu.dolphinemu.about.Limit.Type;
import org.dolphinemu.dolphinemu.utils.EGLHelper;
import java.util.ArrayList;
import java.util.List;
/**
* {@link ListFragment} responsible for displaying
* information relating to OpenGL ES 2.
*/
public final class GLES2InfoFragment extends ListFragment
{
private final Limit[] Limits = {
new Limit("Vendor", GLES20.GL_VENDOR, Type.STRING),
new Limit("Version", GLES20.GL_VERSION, Type.STRING),
new Limit("Renderer", GLES20.GL_RENDERER, Type.STRING),
new Limit("GLSL version", GLES20.GL_SHADING_LANGUAGE_VERSION, Type.STRING),
// GLES 2.0 Limits
new Limit("Aliased Point Size", GLES20.GL_ALIASED_POINT_SIZE_RANGE, Type.INTEGER_RANGE),
new Limit("Aliased Line Width ", GLES20.GL_ALIASED_LINE_WIDTH_RANGE, Type.INTEGER_RANGE),
new Limit("Max Texture Size", GLES20.GL_MAX_TEXTURE_SIZE, Type.INTEGER),
new Limit("Viewport Dimensions", GLES20.GL_MAX_VIEWPORT_DIMS, Type.INTEGER_RANGE),
new Limit("Subpixel Bits", GLES20.GL_SUBPIXEL_BITS, Type.INTEGER),
new Limit("Max Vertex Attributes", GLES20.GL_MAX_VERTEX_ATTRIBS, Type.INTEGER),
new Limit("Max Vertex Uniform Vectors", GLES20.GL_MAX_VERTEX_UNIFORM_VECTORS, Type.INTEGER),
new Limit("Max Varying Vectors", GLES20.GL_MAX_VARYING_VECTORS, Type.INTEGER),
new Limit("Max Combined Texture Units", GLES20.GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, Type.INTEGER),
new Limit("Max Vertex Texture Units", GLES20.GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS, Type.INTEGER),
new Limit("Max Texture Units", GLES20.GL_MAX_TEXTURE_IMAGE_UNITS, Type.INTEGER),
new Limit("Max Fragment Uniform Vectors", GLES20.GL_MAX_FRAGMENT_UNIFORM_VECTORS, Type.INTEGER),
new Limit("Max Cubemap Texture Size", GLES20.GL_MAX_CUBE_MAP_TEXTURE_SIZE, Type.INTEGER),
new Limit("Shader Binary Formats", GLES20.GL_NUM_SHADER_BINARY_FORMATS, Type.INTEGER),
new Limit("Max Framebuffer Size", GLES20.GL_MAX_RENDERBUFFER_SIZE, Type.INTEGER),
};
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
final EGLHelper eglHelper = new EGLHelper(EGLHelper.EGL_OPENGL_ES2_BIT);
ListView rootView = (ListView) inflater.inflate(R.layout.gamelist_listview, container, false);
List<AboutFragmentItem> Input = new ArrayList<AboutFragmentItem>();
for (Limit limit : Limits)
{
Log.i("GLES2InfoFragment", "Getting enum " + limit.name);
Input.add(new AboutFragmentItem(limit.name, limit.GetValue(eglHelper)));
}
// Get extensions manually
String[] extensions = eglHelper.glGetString(GLES20.GL_EXTENSIONS).split(" ");
StringBuilder extensionsBuilder = new StringBuilder();
for (String extension : extensions)
{
extensionsBuilder.append(extension).append('\n');
}
Input.add(new AboutFragmentItem("OpenGL ES 2.0 Extensions", extensionsBuilder.toString()));
AboutInfoFragmentAdapter adapter = new AboutInfoFragmentAdapter(getActivity(), R.layout.about_layout, Input);
rootView.setAdapter(adapter);
return rootView;
}
}

View File

@ -1,114 +0,0 @@
/**
* Copyright 2014 Dolphin Emulator Project
* Licensed under GPLv2+
* Refer to the license.txt file included.
*/
package org.dolphinemu.dolphinemu.about;
import android.app.ListFragment;
import android.opengl.GLES30;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ListView;
import org.dolphinemu.dolphinemu.R;
import org.dolphinemu.dolphinemu.about.Limit.Type;
import org.dolphinemu.dolphinemu.utils.EGLHelper;
import java.util.ArrayList;
import java.util.List;
/**
* {@link ListFragment} responsible for displaying
* information relating to OpenGL ES 3.
*/
public final class GLES3InfoFragment extends ListFragment
{
private final Limit[] Limits = {
new Limit("Vendor", GLES30.GL_VENDOR, Type.STRING),
new Limit("Version", GLES30.GL_VERSION, Type.STRING),
new Limit("Renderer", GLES30.GL_RENDERER, Type.STRING),
new Limit("GLSL version", GLES30.GL_SHADING_LANGUAGE_VERSION, Type.STRING),
// GLES 2.0 Limits
new Limit("Aliased Point Size", GLES30.GL_ALIASED_POINT_SIZE_RANGE, Type.INTEGER_RANGE),
new Limit("Aliased Line Width ", GLES30.GL_ALIASED_LINE_WIDTH_RANGE, Type.INTEGER_RANGE),
new Limit("Max Texture Size", GLES30.GL_MAX_TEXTURE_SIZE, Type.INTEGER),
new Limit("Viewport Dimensions", GLES30.GL_MAX_VIEWPORT_DIMS, Type.INTEGER_RANGE),
new Limit("Subpixel Bits", GLES30.GL_SUBPIXEL_BITS, Type.INTEGER),
new Limit("Max Vertex Attributes", GLES30.GL_MAX_VERTEX_ATTRIBS, Type.INTEGER),
new Limit("Max Vertex Uniform Vectors", GLES30.GL_MAX_VERTEX_UNIFORM_VECTORS, Type.INTEGER),
new Limit("Max Varying Vectors", GLES30.GL_MAX_VARYING_VECTORS, Type.INTEGER),
new Limit("Max Combined Texture Units", GLES30.GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, Type.INTEGER),
new Limit("Max Vertex Texture Units", GLES30.GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS, Type.INTEGER),
new Limit("Max Texture Units", GLES30.GL_MAX_TEXTURE_IMAGE_UNITS, Type.INTEGER),
new Limit("Max Fragment Uniform Vectors", GLES30.GL_MAX_FRAGMENT_UNIFORM_VECTORS, Type.INTEGER),
new Limit("Max Cubemap Texture Size", GLES30.GL_MAX_CUBE_MAP_TEXTURE_SIZE, Type.INTEGER),
new Limit("Shader Binary Formats", GLES30.GL_NUM_SHADER_BINARY_FORMATS, Type.INTEGER),
new Limit("Max Framebuffer Size", GLES30.GL_MAX_RENDERBUFFER_SIZE, Type.INTEGER),
// GLES 3.0 limits
new Limit("Max 3D Texture size", GLES30.GL_MAX_3D_TEXTURE_SIZE, Type.INTEGER),
new Limit("Max Element Vertices", GLES30.GL_MAX_ELEMENTS_VERTICES, Type.INTEGER),
new Limit("Max Element Indices", GLES30.GL_MAX_ELEMENTS_INDICES, Type.INTEGER),
new Limit("Max Draw Buffers", GLES30.GL_MAX_DRAW_BUFFERS, Type.INTEGER),
new Limit("Max Fragment Uniform Components", GLES30.GL_MAX_FRAGMENT_UNIFORM_COMPONENTS, Type.INTEGER),
new Limit("Max Vertex Uniform Components", GLES30.GL_MAX_VERTEX_UNIFORM_COMPONENTS, Type.INTEGER),
new Limit("Number of Extensions", GLES30.GL_NUM_EXTENSIONS, Type.INTEGER),
new Limit("Max Array Texture Layers", GLES30.GL_MAX_ARRAY_TEXTURE_LAYERS, Type.INTEGER),
new Limit("Min Program Texel Offset", GLES30.GL_MIN_PROGRAM_TEXEL_OFFSET, Type.INTEGER),
new Limit("Max Program Texel Offset", GLES30.GL_MAX_PROGRAM_TEXEL_OFFSET, Type.INTEGER),
new Limit("Max Varying Components", GLES30.GL_MAX_VARYING_COMPONENTS, Type.INTEGER),
new Limit("Max TF Varying Length", GLES30.GL_TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH, Type.INTEGER),
new Limit("Max TF Separate Components", GLES30.GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS, Type.INTEGER),
new Limit("Max TF Interleaved Components", GLES30.GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS, Type.INTEGER),
new Limit("Max TF Separate Attributes", GLES30.GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS, Type.INTEGER),
new Limit("Max Color Attachments", GLES30.GL_MAX_COLOR_ATTACHMENTS, Type.INTEGER),
new Limit("Max Samples", GLES30.GL_MAX_SAMPLES, Type.INTEGER),
new Limit("Max Vertex UBOs", GLES30.GL_MAX_VERTEX_UNIFORM_BLOCKS, Type.INTEGER),
new Limit("Max Fragment UBOs", GLES30.GL_MAX_FRAGMENT_UNIFORM_BLOCKS, Type.INTEGER),
new Limit("Max Combined UBOs", GLES30.GL_MAX_COMBINED_UNIFORM_BLOCKS, Type.INTEGER),
new Limit("Max Uniform Buffer Bindings", GLES30.GL_MAX_UNIFORM_BUFFER_BINDINGS, Type.INTEGER),
new Limit("Max UBO Size", GLES30.GL_MAX_UNIFORM_BLOCK_SIZE, Type.INTEGER),
new Limit("Max Combined Vertex Uniform Components", GLES30.GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS, Type.INTEGER),
new Limit("Max Combined Fragment Uniform Components", GLES30.GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS, Type.INTEGER),
new Limit("UBO Alignment", GLES30.GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT, Type.INTEGER),
new Limit("Max Vertex Output Components", GLES30.GL_MAX_VERTEX_OUTPUT_COMPONENTS, Type.INTEGER),
new Limit("Max Fragment Input Components", GLES30.GL_MAX_FRAGMENT_INPUT_COMPONENTS, Type.INTEGER),
new Limit("Max Server Wait Timeout", GLES30.GL_MAX_SERVER_WAIT_TIMEOUT, Type.INTEGER),
new Limit("Program Binary Formats", GLES30.GL_NUM_PROGRAM_BINARY_FORMATS, Type.INTEGER),
new Limit("Max Element Index", GLES30.GL_MAX_ELEMENT_INDEX, Type.INTEGER),
new Limit("Sample Counts", GLES30.GL_NUM_SAMPLE_COUNTS, Type.INTEGER),
};
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
final EGLHelper eglHelper = new EGLHelper(EGLHelper.EGL_OPENGL_ES3_BIT_KHR);
ListView rootView = (ListView) inflater.inflate(R.layout.gamelist_listview, container, false);
List<AboutFragmentItem> Input = new ArrayList<AboutFragmentItem>();
for (Limit limit : Limits)
{
Log.i("GLES3InfoFragment", "Getting enum " + limit.name);
Input.add(new AboutFragmentItem(limit.name, limit.GetValue(eglHelper)));
}
// Get extensions manually
int numExtensions = eglHelper.glGetInteger(GLES30.GL_NUM_EXTENSIONS);
StringBuilder extensionsBuilder = new StringBuilder();
for (int i = 0; i < numExtensions; i++)
{
extensionsBuilder.append(eglHelper.glGetStringi(GLES30.GL_EXTENSIONS, i)).append('\n');
}
Input.add(new AboutFragmentItem("OpenGL ES 3.0 Extensions", extensionsBuilder.toString()));
AboutInfoFragmentAdapter adapter = new AboutInfoFragmentAdapter(getActivity(), R.layout.about_layout, Input);
rootView.setAdapter(adapter);
return rootView;
}
}

View File

@ -1,69 +0,0 @@
/**
* Copyright 2014 Dolphin Emulator Project
* Licensed under GPLv2+
* Refer to the license.txt file included.
*/
package org.dolphinemu.dolphinemu.about;
import android.app.ListFragment;
import android.opengl.GLES20;
import android.opengl.GLES30;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ListView;
import org.dolphinemu.dolphinemu.R;
import org.dolphinemu.dolphinemu.about.Limit.Type;
import org.dolphinemu.dolphinemu.utils.EGLHelper;
import java.util.ArrayList;
import java.util.List;
import javax.microedition.khronos.opengles.GL10;
/**
* {@link ListFragment} responsible for displaying
* information relating to OpenGL.
*/
public final class GLInfoFragment extends ListFragment
{
private final Limit[] Limits = {
new Limit("Vendor", GL10.GL_VENDOR, Type.STRING),
new Limit("Version", GL10.GL_VERSION, Type.STRING),
new Limit("Renderer", GL10.GL_RENDERER, Type.STRING),
new Limit("GLSL version", GLES20.GL_SHADING_LANGUAGE_VERSION, Type.STRING),
};
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
final EGLHelper eglHelper = new EGLHelper(EGLHelper.EGL_OPENGL_BIT);
ListView rootView = (ListView) inflater.inflate(R.layout.gamelist_listview, container, false);
List<AboutFragmentItem> Input = new ArrayList<AboutFragmentItem>();
for (Limit limit : Limits)
{
Log.i("GLInfoFragment", "Getting enum " + limit.name);
Input.add(new AboutFragmentItem(limit.name, limit.GetValue(eglHelper)));
}
// Get extensions manually
int numExtensions = eglHelper.glGetInteger(GLES30.GL_NUM_EXTENSIONS);
StringBuilder extensionsBuilder = new StringBuilder();
for (int i = 0; i < numExtensions; i++)
{
extensionsBuilder.append(eglHelper.glGetStringi(GL10.GL_EXTENSIONS, i)).append('\n');
}
Input.add(new AboutFragmentItem("OpenGL Extensions", extensionsBuilder.toString()));
AboutInfoFragmentAdapter adapter = new AboutInfoFragmentAdapter(getActivity(), R.layout.about_layout, Input);
rootView.setAdapter(adapter);
return rootView;
}
}

View File

@ -1,71 +0,0 @@
/**
* Copyright 2014 Dolphin Emulator Project
* Licensed under GPLv2+
* Refer to the license.txt file included.
*/
package org.dolphinemu.dolphinemu.about;
import org.dolphinemu.dolphinemu.utils.EGLHelper;
final class Limit
{
/**
* Possible types a Limit can be.
*/
enum Type
{
/** Generic string */
STRING,
/** Integer constant */
INTEGER,
/** Range of integers */
INTEGER_RANGE,
}
/** Name of this limit */
public final String name;
/** The GL constant that represents this limit.*/
public final int glEnum;
/** The {@link Type} of this limit. */
public final Type type;
/**
* Constructor
*
* @param name Name of the limit.
* @param glEnum The GL constant that represents this limit.
* @param type The {@link Type} of this limit.
*/
public Limit(String name, int glEnum, Type type)
{
this.name = name;
this.glEnum = glEnum;
this.type = type;
}
/**
* Retrieves the information represented by this limit.
*
* @param context {@link EGLHelper} context to retrieve the limit with.
*
* @return the information represented by this limit.
*/
public String GetValue(EGLHelper context)
{
if (type == Type.INTEGER)
{
return Integer.toString(context.glGetInteger(glEnum));
}
else if (type == Type.INTEGER_RANGE)
{
int[] data = new int[2];
context.getGL().glGetIntegerv(glEnum, data, 0);
return String.format("[%d, %d]", data[0], data[1]);
}
// If neither of the above type, assume it's a string.
return context.glGetString(glEnum);
}
}

View File

@ -18,7 +18,7 @@ import android.view.View;
import org.dolphinemu.dolphinemu.NativeLibrary;
import org.dolphinemu.dolphinemu.R;
import org.dolphinemu.dolphinemu.fragments.EmulationFragment;
import org.dolphinemu.dolphinemu.settings.input.InputConfigFragment;
import org.dolphinemu.dolphinemu.utils.InputConfigFragment;
import java.util.List;

View File

@ -1,9 +1,4 @@
package org.dolphinemu.dolphinemu.settings.input;
import java.util.ArrayList;
import java.util.List;
import org.dolphinemu.dolphinemu.NativeLibrary;
package org.dolphinemu.dolphinemu.dialogs;
import android.app.AlertDialog;
import android.content.Context;
@ -13,11 +8,17 @@ import android.view.InputDevice;
import android.view.KeyEvent;
import android.view.MotionEvent;
import org.dolphinemu.dolphinemu.NativeLibrary;
import org.dolphinemu.dolphinemu.utils.InputConfigFragment;
import java.util.ArrayList;
import java.util.List;
/**
* {@link AlertDialog} derivative that listens for
* motion events from controllers and joysticks.
*/
final class MotionAlertDialog extends AlertDialog
public final class MotionAlertDialog extends AlertDialog
{
// The selected input preference
private final Preference inputPref;
@ -27,7 +28,7 @@ final class MotionAlertDialog extends AlertDialog
/**
* Constructor
*
*
* @param ctx The current {@link Context}.
* @param inputPref The Preference to show this dialog for.
*/
@ -57,7 +58,7 @@ final class MotionAlertDialog extends AlertDialog
return false;
}
}
// Method that will be called within dispatchGenericMotionEvent
// that handles joystick/controller movements.
@ -115,7 +116,7 @@ final class MotionAlertDialog extends AlertDialog
return super.dispatchKeyEvent(event);
}
@Override
public boolean dispatchGenericMotionEvent(MotionEvent event)
{

View File

@ -1,316 +0,0 @@
/**
* Copyright 2013 Dolphin Emulator Project
* Licensed under GPLv2+
* Refer to the license.txt file included.
*/
package org.dolphinemu.dolphinemu.emulation;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.graphics.Color;
import android.graphics.drawable.ColorDrawable;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.view.InputDevice;
import android.view.KeyEvent;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.MotionEvent;
import android.view.View;
import android.view.Window;
import android.view.WindowManager.LayoutParams;
import org.dolphinemu.dolphinemu.NativeLibrary;
import org.dolphinemu.dolphinemu.R;
import org.dolphinemu.dolphinemu.settings.input.InputConfigFragment;
import java.util.List;
/**
* This is the activity where all of the emulation handling happens.
* This activity is responsible for displaying the SurfaceView that we render to.
*/
public final class EmulationActivity extends Activity
{
private boolean Running;
private boolean IsActionBarHidden = false;
private SharedPreferences sharedPrefs;
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
sharedPrefs = PreferenceManager.getDefaultSharedPreferences(this);
// Request window features for the emulation view.
getWindow().addFlags(LayoutParams.FLAG_KEEP_SCREEN_ON);
getWindow().addFlags(LayoutParams.FLAG_FULLSCREEN);
getWindow().requestFeature(Window.FEATURE_ACTION_BAR_OVERLAY);
// Set the transparency for the action bar.
ColorDrawable actionBarBackground = new ColorDrawable(Color.parseColor("#303030"));
actionBarBackground.setAlpha(175);
getActionBar().setBackgroundDrawable(actionBarBackground);
// Get the intent passed from the GameList when the game
// was selected. This is so the path of the game can be retrieved
// and set on the native side of the code so the emulator can actually
// load the game.
Intent gameToEmulate = getIntent();
NativeLibrary.SetFilename(gameToEmulate.getStringExtra("SelectedGame"));
Running = true;
// Set the emulation window.
setContentView(R.layout.emulation_view);
// If the input overlay was previously disabled, then don't show it.
if (!sharedPrefs.getBoolean("showInputOverlay", true))
{
findViewById(R.id.emulationControlOverlay).setVisibility(View.INVISIBLE);
}
// Hide the action bar by default so it doesn't get in the way.
getActionBar().hide();
IsActionBarHidden = true;
}
@Override
public void onStop()
{
super.onStop();
if (Running)
NativeLibrary.StopEmulation();
}
@Override
public void onPause()
{
super.onPause();
if (Running)
NativeLibrary.PauseEmulation();
}
@Override
public void onResume()
{
super.onResume();
if (Running)
NativeLibrary.UnPauseEmulation();
}
@Override
public void onDestroy()
{
super.onDestroy();
if (Running)
{
NativeLibrary.StopEmulation();
Running = false;
}
}
@Override
public void onBackPressed()
{
// The back button in the emulation
// window is the toggle for the action bar.
if (IsActionBarHidden)
{
IsActionBarHidden = false;
getActionBar().show();
}
else
{
IsActionBarHidden = true;
getActionBar().hide();
}
}
@Override
public boolean onCreateOptionsMenu(Menu menu)
{
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.emuwindow_overlay, menu);
return true;
}
@Override
public boolean onPrepareOptionsMenu(Menu menu)
{
// Determine which string the "Enable Input Overlay" menu item should have
// depending on its visibility at the time of preparing the options menu.
if (!sharedPrefs.getBoolean("showInputOverlay", true))
{
menu.findItem(R.id.enableInputOverlay).setTitle(R.string.enable_input_overlay);
}
else
{
menu.findItem(R.id.enableInputOverlay).setTitle(R.string.disable_input_overlay);
}
return true;
}
@Override
public boolean onMenuItemSelected(int itemId, MenuItem item)
{
switch(item.getItemId())
{
// Enable/Disable input overlay.
case R.id.enableInputOverlay:
{
View overlay = findViewById(R.id.emulationControlOverlay);
// Show the overlay
if (item.getTitle().equals(getString(R.string.enable_input_overlay)))
{
overlay.setVisibility(View.VISIBLE);
item.setTitle(R.string.disable_input_overlay);
sharedPrefs.edit().putBoolean("showInputOverlay", true).apply();
}
else // Hide the overlay
{
overlay.setVisibility(View.INVISIBLE);
item.setTitle(R.string.enable_input_overlay);
sharedPrefs.edit().putBoolean("showInputOverlay", false).apply();
}
return true;
}
// Screenshot capturing
case R.id.takeScreenshot:
NativeLibrary.SaveScreenShot();
return true;
// Save state slots
case R.id.saveSlot1:
NativeLibrary.SaveState(0);
return true;
case R.id.saveSlot2:
NativeLibrary.SaveState(1);
return true;
case R.id.saveSlot3:
NativeLibrary.SaveState(2);
return true;
case R.id.saveSlot4:
NativeLibrary.SaveState(3);
return true;
case R.id.saveSlot5:
NativeLibrary.SaveState(4);
return true;
// Load state slots
case R.id.loadSlot1:
NativeLibrary.LoadState(0);
return true;
case R.id.loadSlot2:
NativeLibrary.LoadState(1);
return true;
case R.id.loadSlot3:
NativeLibrary.LoadState(2);
return true;
case R.id.loadSlot4:
NativeLibrary.LoadState(3);
return true;
case R.id.loadSlot5:
NativeLibrary.LoadState(4);
return true;
case R.id.exitEmulation:
{
// Create a confirmation method for quitting the current emulation instance.
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle(R.string.overlay_exit_emulation);
builder.setMessage(R.string.overlay_exit_emulation_confirm);
builder.setNegativeButton(R.string.no, null);
builder.setPositiveButton(R.string.yes, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which)
{
onDestroy();
}
});
builder.show();
return true;
}
default:
return super.onMenuItemSelected(itemId, item);
}
}
// Gets button presses
@Override
public boolean dispatchKeyEvent(KeyEvent event)
{
int action = 0;
if (Running)
{
switch (event.getAction())
{
case KeyEvent.ACTION_DOWN:
// Handling the case where the back button is pressed.
if (event.getKeyCode() == KeyEvent.KEYCODE_BACK)
{
onBackPressed();
return true;
}
// Normal key events.
action = NativeLibrary.ButtonState.PRESSED;
break;
case KeyEvent.ACTION_UP:
action = NativeLibrary.ButtonState.RELEASED;
break;
default:
return false;
}
InputDevice input = event.getDevice();
boolean handled = NativeLibrary.onGamePadEvent(InputConfigFragment.getInputDesc(input), event.getKeyCode(), action);
return handled;
}
return false;
}
@Override
public boolean dispatchGenericMotionEvent(MotionEvent event)
{
if (((event.getSource() & InputDevice.SOURCE_CLASS_JOYSTICK) == 0) || !Running)
{
return super.dispatchGenericMotionEvent(event);
}
// Don't attempt to do anything if we are disconnecting a device.
if (event.getActionMasked() == MotionEvent.ACTION_CANCEL)
return true;
InputDevice input = event.getDevice();
List<InputDevice.MotionRange> motions = input.getMotionRanges();
for (InputDevice.MotionRange range : motions)
{
NativeLibrary.onGamePadMoveEvent(InputConfigFragment.getInputDesc(input), range.getAxis(), event.getAxisValue(range.getAxis()));
}
return true;
}
}

View File

@ -1,74 +0,0 @@
/**
* Copyright 2013 Dolphin Emulator Project
* Licensed under GPLv2+
* Refer to the license.txt file included.
*/
package org.dolphinemu.dolphinemu.emulation;
import org.dolphinemu.dolphinemu.NativeLibrary;
import android.content.Context;
import android.util.AttributeSet;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
/**
* The {@link SurfaceView} that rendering is performed on.
*/
public final class NativeGLSurfaceView extends SurfaceView
{
private static Thread myRun;
private static boolean Running = false;
private static boolean Created = false;
/**
* Constructor.
*
* @param context The current {@link Context}.
* @param attribs An AttributeSet for retrieving data from XML files.
*/
public NativeGLSurfaceView(Context context, AttributeSet attribs)
{
super(context, attribs);
if (!Created)
{
myRun = new Thread()
{
@Override
public void run() {
NativeLibrary.Run(getHolder().getSurface());
Created = false;
Running = false;
}
};
getHolder().addCallback(new SurfaceHolder.Callback()
{
public void surfaceCreated(SurfaceHolder holder)
{
// TODO Auto-generated method stub
if (!Running)
{
myRun.start();
Running = true;
}
}
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height)
{
// TODO Auto-generated method stub
}
public void surfaceDestroyed(SurfaceHolder holder)
{
// TODO Auto-generated method stub
}
});
Created = true;
}
}
}

View File

@ -1,159 +0,0 @@
/**
* Copyright 2013 Dolphin Emulator Project
* Licensed under GPLv2+
* Refer to the license.txt file included.
*/
package org.dolphinemu.dolphinemu.folderbrowser;
import android.app.ListFragment;
import android.os.Bundle;
import android.os.Environment;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ListView;
import java.io.File;
import java.util.*;
import org.dolphinemu.dolphinemu.NativeLibrary;
import org.dolphinemu.dolphinemu.R;
import org.dolphinemu.dolphinemu.gamelist.GameListActivity;
/**
* A basic folder browser {@link ListFragment} that allows
* the user to select ISOs/ROMs for playing within the
* emulator.
* <p>
* Any valid ISO/ROM selected in this will be added to
* the game list for easy browsing the next time the
* application is used.
* <p>
* Note that this file browser does not display files
* or directories that are hidden
*/
public final class FolderBrowser extends ListFragment
{
private FolderBrowserAdapter adapter;
private static File currentDir = null;
// Populates the FolderView with the given currDir's contents.
private void Fill(File currDir)
{
// Clear the adapter of previous items.
adapter.clear();
// Set the activity title to the current directory the FolderBrowser is in.
getActivity().setTitle(String.format(getString(R.string.current_dir), currDir.getName()));
File[] dirs = currDir.listFiles();
List<FolderBrowserItem> dir = new ArrayList<FolderBrowserItem>();
List<FolderBrowserItem> fls = new ArrayList<FolderBrowserItem>();
// Supported extensions to filter by
Set<String> validExts = new HashSet<String>(Arrays.asList(".dff", ".dol", ".elf", ".gcm", ".gcz", ".iso", ".wad", ".wbfs"));
// If dirs is null, then we don't have access permissions to the selected folder.
if (dirs != null)
{
// Search for any directories or files within the current dir.
for(File entry : dirs)
{
try
{
String entryName = entry.getName();
boolean hasExtension = (entryName.lastIndexOf(".") != -1);
// Skip hidden folders/files.
if (!entry.isHidden())
{
if(entry.isDirectory())
{
dir.add(new FolderBrowserItem(entryName, entry.getAbsolutePath()));
}
else if (entry.isFile() && hasExtension)
{
if (validExts.contains(entryName.toLowerCase().substring(entryName.lastIndexOf('.'))))
{
fls.add(new FolderBrowserItem(entryName, String.format(getString(R.string.file_size), entry.length()), entry.getAbsolutePath()));
}
}
}
}
catch (Exception ex)
{
Log.e("FolderBrowser", ex.toString());
}
}
}
Collections.sort(dir);
Collections.sort(fls);
dir.addAll(fls);
// Check for a parent directory to the one we're currently in.
if (!currDir.getPath().equalsIgnoreCase("/"))
dir.add(0, new FolderBrowserItem("..", getString(R.string.parent_directory), currDir.getParent()));
// Add the items to the adapter and notify the adapter users of its new contents.
adapter.addAll(dir);
adapter.notifyDataSetChanged();
}
@Override
public void onListItemClick(ListView lv, View v, int position, long id)
{
FolderBrowserItem item = adapter.getItem(position);
if(item.isDirectory())
{
currentDir = new File(item.getPath());
Fill(currentDir);
}
else
{
FolderSelected();
}
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
if(currentDir == null)
currentDir = new File(Environment.getExternalStorageDirectory().getPath());
ListView rootView = (ListView) inflater.inflate(R.layout.folderbrowser_listview, container, false);
adapter = new FolderBrowserAdapter(getActivity(), R.layout.folderbrowser_list_item);
rootView.setAdapter(adapter);
Fill(currentDir);
return rootView;
}
private void FolderSelected()
{
String Directories = NativeLibrary.GetConfig("Dolphin.ini", "General", "ISOPaths", "0");
int intDirectories = Integer.parseInt(Directories);
// Check to see if a path set in the Dolphin config
// matches the one the user is trying to add. If it's
// already set, then don't add it to the list again.
boolean pathNotPresent = true;
for (int i = 0; i < intDirectories; i++)
{
String isoPath = NativeLibrary.GetConfig("Dolphin.ini", "General", "ISOPath" + i, "");
pathNotPresent = !isoPath.equals(currentDir.getPath());
}
// User doesn't have this path in the config, so add it.
if (pathNotPresent)
{
NativeLibrary.SetConfig("Dolphin.ini", "General", "ISOPaths", Integer.toString(intDirectories+1));
NativeLibrary.SetConfig("Dolphin.ini", "General", "ISOPath" + Integer.toString(intDirectories), currentDir.getPath());
}
((GameListActivity)getActivity()).SwitchPage(0);
}
}

View File

@ -1,112 +0,0 @@
/**
* Copyright 2013 Dolphin Emulator Project
* Licensed under GPLv2+
* Refer to the license.txt file included.
*/
package org.dolphinemu.dolphinemu.folderbrowser;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ImageView;
import android.widget.TextView;
import org.dolphinemu.dolphinemu.R;
/**
* The {@link ArrayAdapter} that backs the file browser.
* <p>
* This is responsible for correctly handling the display
* of the items for the {@link FolderBrowser} UI.
*/
public final class FolderBrowserAdapter extends ArrayAdapter<FolderBrowserItem>
{
// ViewHolder which is used to hold onto
// items within a listview. This is done
// so that findViewById is not needed to
// be excessively called over and over.
private static final class ViewHolder
{
TextView title;
TextView subtitle;
ImageView icon;
}
private final Context context;
private final int id;
private ViewHolder viewHolder;
/**
* Constructor
*
* @param context The current {@link Context}.
* @param resourceId The resource ID for a layout file containing a layout to use when instantiating views.
*/
public FolderBrowserAdapter(Context context, int resourceId)
{
super(context, resourceId);
this.context = context;
this.id = resourceId;
}
@Override
public View getView(int position, View convertView, ViewGroup parent)
{
if (convertView == null)
{
LayoutInflater vi = LayoutInflater.from(context);
convertView = vi.inflate(id, parent, false);
// Initialize the ViewHolder and store it.
viewHolder = new ViewHolder();
viewHolder.title = (TextView) convertView.findViewById(R.id.BrowserItemTitle);
viewHolder.subtitle = (TextView) convertView.findViewById(R.id.BrowserItemSubTitle);
viewHolder.icon = (ImageView) convertView.findViewById(R.id.BrowserItemIcon);
convertView.setTag(viewHolder);
}
else // Can recover the holder.
{
viewHolder = (ViewHolder) convertView.getTag();
}
final FolderBrowserItem item = getItem(position);
if (item != null)
{
if (viewHolder.title != null)
{
viewHolder.title.setText(item.getName());
}
if (viewHolder.subtitle != null)
{
// Remove the subtitle for all folders, except for the parent directory folder.
if (item.isDirectory() && !item.getSubtitle().equals(context.getString(R.string.parent_directory)))
{
viewHolder.subtitle.setVisibility(View.GONE);
}
else
{
viewHolder.subtitle.setVisibility(View.VISIBLE);
viewHolder.subtitle.setText(item.getSubtitle());
}
}
if (viewHolder.icon != null)
{
if (item.isDirectory())
{
viewHolder.icon.setImageResource(R.drawable.ic_menu_folder);
}
else
{
viewHolder.icon.setImageResource(R.drawable.ic_menu_file);
}
}
}
return convertView;
}
}

View File

@ -1,110 +0,0 @@
/**
* Copyright 2013 Dolphin Emulator Project
* Licensed under GPLv2+
* Refer to the license.txt file included.
*/
package org.dolphinemu.dolphinemu.folderbrowser;
import java.io.File;
/**
* Represents an item in the {@link FolderBrowser} list.
*/
public final class FolderBrowserItem implements Comparable<FolderBrowserItem>
{
private final String name;
private final String subtitle;
private final String path;
private final File underlyingFile;
/**
* Constructor
*
* @param name The name of the file/folder represented by this item.
* @param subtitle The subtitle of this FolderBrowserItem.
* @param path The path of the file/folder represented by this item.
*/
public FolderBrowserItem(String name, String subtitle, String path)
{
this.name = name;
this.subtitle = subtitle;
this.path = path;
this.underlyingFile = new File(path);
}
/**
* Constructor. Initializes a FolderBrowserItem with an empty subtitle.
*
* @param name The name of the file/folder represented by this item.
* @param path The path of the file/folder represented by this item.
*/
public FolderBrowserItem(String name, String path)
{
this.name = name;
this.subtitle = "";
this.path = path;
this.underlyingFile = new File(path);
}
/**
* Gets the name of the file/folder represented by this FolderBrowserItem.
*
* @return the name of the file/folder represented by this FolderBrowserItem.
*/
public String getName()
{
return name;
}
/**
* Gets the subtitle text of this FolderBrowserItem.
*
* @return the subtitle text of this FolderBrowserItem.
*/
public String getSubtitle()
{
return subtitle;
}
/**
* Gets the path of the file/folder represented by this FolderBrowserItem.
*
* @return the path of the file/folder represented by this FolderBrowserItem.
*/
public String getPath()
{
return path;
}
/**
* Gets the {@link File} representation of the underlying file/folder
* represented by this FolderBrowserItem.
*
* @return the {@link File} representation of the underlying file/folder
* represented by this FolderBrowserItem.
*/
public File getUnderlyingFile()
{
return underlyingFile;
}
/**
* Gets whether or not this FolderBrowserItem represents a directory.
*
* @return true if this FolderBrowserItem represents a directory, false otherwise.
*/
public boolean isDirectory()
{
return underlyingFile.isDirectory();
}
@Override
public int compareTo(FolderBrowserItem other)
{
if(name != null)
return name.toLowerCase().compareTo(other.getName().toLowerCase());
else
throw new NullPointerException("The name of this FolderBrowserItem is null");
}
}

View File

@ -15,7 +15,7 @@ import android.view.ViewGroup;
import org.dolphinemu.dolphinemu.BuildConfig;
import org.dolphinemu.dolphinemu.NativeLibrary;
import org.dolphinemu.dolphinemu.R;
import org.dolphinemu.dolphinemu.emulation.overlay.InputOverlay;
import org.dolphinemu.dolphinemu.overlay.InputOverlay;
public final class EmulationFragment extends Fragment implements SurfaceHolder.Callback

View File

@ -1,373 +0,0 @@
/**
* Copyright 2013 Dolphin Emulator Project
* Licensed under GPLv2+
* Refer to the license.txt file included.
*/
package org.dolphinemu.dolphinemu.gamelist;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.Fragment;
import android.app.FragmentTransaction;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.res.Configuration;
import android.os.Build;
import android.os.Bundle;
import android.os.Environment;
import android.preference.PreferenceManager;
import android.support.v4.app.ActionBarDrawerToggle;
import android.support.v4.widget.DrawerLayout;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ListView;
import org.dolphinemu.dolphinemu.NativeLibrary;
import org.dolphinemu.dolphinemu.R;
import org.dolphinemu.dolphinemu.about.AboutActivity;
import org.dolphinemu.dolphinemu.emulation.EmulationActivity;
import org.dolphinemu.dolphinemu.folderbrowser.FolderBrowser;
import org.dolphinemu.dolphinemu.services.AssetCopyService;
import org.dolphinemu.dolphinemu.settings.PrefsActivity;
import org.dolphinemu.dolphinemu.sidemenu.SideMenuAdapter;
import org.dolphinemu.dolphinemu.sidemenu.SideMenuItem;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
/**
* The activity that implements all of the functions
* for the game list.
*/
public final class GameListActivity extends Activity
implements GameListFragment.OnGameListZeroListener
{
private int mCurFragmentNum = 0;
private ActionBarDrawerToggle mDrawerToggle;
private DrawerLayout mDrawerLayout;
private SideMenuAdapter mDrawerAdapter;
private ListView mDrawerList;
private boolean mAutoStart = false;
private String mAutoStartFile = "";
/**
* Called from the {@link GameListFragment}.
* <p>
* This is called when there are no games
* currently present within the game list.
*/
public void onZeroFiles()
{
mDrawerLayout.openDrawer(mDrawerList);
}
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.gamelist_activity);
mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
mDrawerList = (ListView) findViewById(R.id.left_drawer);
// Construct list of items to add to the side menu.
List<SideMenuItem> dir = new ArrayList<SideMenuItem>();
dir.add(new SideMenuItem(getString(R.string.game_list), 0));
dir.add(new SideMenuItem(getString(R.string.browse_folder), 1));
dir.add(new SideMenuItem(getString(R.string.settings), 2));
dir.add(new SideMenuItem(getString(R.string.about), 3));
mDrawerAdapter = new SideMenuAdapter(this, R.layout.sidemenu, dir);
mDrawerList.setAdapter(mDrawerAdapter);
mDrawerList.setOnItemClickListener(mMenuItemClickListener);
// Enable ActionBar app icon to behave as action to toggle nav drawer
getActionBar().setDisplayHomeAsUpEnabled(true);
getActionBar().setHomeButtonEnabled(true);
// ActionBarDrawerToggle ties together the the proper interactions
// between the sliding drawer and the action bar app icon
mDrawerToggle = new ActionBarDrawerToggle(
this, /* Host Activity */
mDrawerLayout, /* DrawerLayout object */
R.drawable.ic_drawer, /* Navigation drawer image to replace 'Up' caret */
R.string.drawer_open, /* "open drawer" description for accessibility */
R.string.drawer_close /* "close drawer" description for accessibility */
) {
public void onDrawerClosed(View view) {
invalidateOptionsMenu(); // creates call to onPrepareOptionsMenu()
}
public void onDrawerOpened(View drawerView) {
invalidateOptionsMenu(); // creates call to onPrepareOptionsMenu()
}
};
mDrawerLayout.setDrawerListener(mDrawerToggle);
CheckForIntent();
String BaseDir = NativeLibrary.GetUserDirectory();
final String DefaultDir = Environment.getExternalStorageDirectory() + File.separator + "dolphin-emu";
if (BaseDir.isEmpty())
BaseDir = DefaultDir;
NativeLibrary.SetUserDirectory(BaseDir);
// Stuff in this block only happens when this activity is newly created (i.e. not a rotation)
if (savedInstanceState == null)
{
// Copy assets into appropriate locations.
Intent copyAssets = new Intent(this, AssetCopyService.class);
startService(copyAssets);
// Display the game list fragment.
final GameListFragment gameList = new GameListFragment();
FragmentTransaction ft = getFragmentManager().beginTransaction();
ft.replace(R.id.content_frame, gameList);
ft.commit();
}
// Create an alert telling them that their phone sucks
if (Build.CPU_ABI.contains("arm") && !NativeLibrary.SupportsNEON())
{
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle(R.string.device_compat_warning);
builder.setMessage(R.string.device_compat_warning_msg);
builder.setPositiveButton(R.string.yes, null);
builder.setNegativeButton(R.string.no, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which)
{
finish();
}
});
builder.show();
}
if (mAutoStart)
{
// Start the emulation activity
Intent intent = new Intent(this, EmulationActivity.class);
intent.putExtra("SelectedGame", mAutoStartFile);
startActivity(intent);
}
}
private void CheckForIntent()
{
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
boolean handled = prefs.getBoolean("HandledIntent", false);
// Get an editor.
SharedPreferences.Editor editor = prefs.edit();
Bundle extras = getIntent().getExtras();
if (!handled && extras != null)
{
// Application got passed extra data
editor.putBoolean("HandledIntent", true);
editor.apply();
// Did we get passed a new user directory?
String user_dir = extras.getString("UserDir");
if (user_dir != null && user_dir.length() != 0)
NativeLibrary.SetUserDirectory(user_dir);
// Did we get passed a file?
String start_file = extras.getString("AutoStartFile");
if (start_file != null && start_file.length() != 0)
{
mAutoStart = true;
mAutoStartFile = start_file;
}
return;
}
editor.putBoolean("HandledIntent", false);
editor.apply();
}
/**
* Switches to the {@link Fragment} represented
* by the given ID number.
*
* @param toPage the number representing the {@link Fragment} to switch to.
*/
public void SwitchPage(int toPage)
{
if (mCurFragmentNum == toPage)
return;
switch(toPage)
{
case 0: // Game list
{
// We use the title section as the browser directory tracker in the folder browser.
// Make sure we flip the title back if we're coming from that fragment.
if (mCurFragmentNum == 1)
setTitle(R.string.app_name);
mCurFragmentNum = 0;
final GameListFragment gameList = new GameListFragment();
FragmentTransaction ft = getFragmentManager().beginTransaction();
ft.replace(R.id.content_frame, gameList);
ft.commit();
invalidateOptionsMenu();
}
break;
case 1: // Folder Browser
{
mCurFragmentNum = 1;
final FolderBrowser folderBrowser = new FolderBrowser();
FragmentTransaction ft = getFragmentManager().beginTransaction();
ft.replace(R.id.content_frame, folderBrowser);
ft.addToBackStack(null);
ft.commit();
invalidateOptionsMenu();
}
break;
case 2: // Settings
{
Intent intent = new Intent(this, PrefsActivity.class);
startActivity(intent);
}
break;
case 3: // About
{
Intent intent = new Intent(this, AboutActivity.class);
startActivity(intent);
}
break;
default:
break;
}
}
private final AdapterView.OnItemClickListener mMenuItemClickListener = new AdapterView.OnItemClickListener()
{
public void onItemClick(AdapterView<?> parent, View view, int position, long id)
{
SideMenuItem o = mDrawerAdapter.getItem(position);
mDrawerLayout.closeDrawer(mDrawerList);
SwitchPage(o.getID());
}
};
/**
* When using the ActionBarDrawerToggle, you must call it during
* onPostCreate() and onConfigurationChanged()...
*/
@Override
protected void onPostCreate(Bundle savedInstanceState)
{
super.onPostCreate(savedInstanceState);
// Sync the toggle state after onRestoreInstanceState has occurred.
mDrawerToggle.syncState();
}
@Override
public void onConfigurationChanged(Configuration newConfig)
{
super.onConfigurationChanged(newConfig);
// Pass any configuration change to the drawer toggle
mDrawerToggle.onConfigurationChanged(newConfig);
}
@Override
public boolean onCreateOptionsMenu(Menu menu)
{
// Only show this in the game list.
if (mCurFragmentNum == 0)
{
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.gamelist_menu, menu);
return true;
}
return false;
}
@Override
public boolean onOptionsItemSelected(MenuItem item)
{
// The action bar home/up action should open or close the drawer.
// ActionBarDrawerToggle will take care of this.
if (mDrawerToggle.onOptionsItemSelected(item))
{
return true;
}
// If clear game list is pressed.
if (item.getItemId() == R.id.clearGameList)
{
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle(R.string.clear_game_list);
builder.setMessage(getString(R.string.clear_game_list_confirm));
builder.setNegativeButton(R.string.no, null);
builder.setPositiveButton(R.string.yes, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which)
{
String directories = NativeLibrary.GetConfig("Dolphin.ini", "General", "ISOPaths", "0");
int intDirs = Integer.parseInt(directories);
for (int i = 0; i < intDirs; i++)
{
NativeLibrary.SetConfig("Dolphin.ini", "General", "ISOPath" + i, "");
}
// Since we flushed all paths, we signify this in the ini.
NativeLibrary.SetConfig("Dolphin.ini", "General", "ISOPaths", "0");
// Now finally, clear the game list.
((GameListFragment) getFragmentManager().findFragmentById(R.id.content_frame)).clearGameList();
}
});
builder.show();
}
return super.onOptionsItemSelected(item);
}
@Override
public void onSaveInstanceState(Bundle outState)
{
super.onSaveInstanceState(outState);
outState.putInt("currentFragmentNum", mCurFragmentNum);
}
@Override
public void onRestoreInstanceState(Bundle savedInstanceState)
{
super.onRestoreInstanceState(savedInstanceState);
mCurFragmentNum = savedInstanceState.getInt("currentFragmentNum");
}
@Override
public void onBackPressed()
{
if (mCurFragmentNum == 0)
{
finish();
}
else
{
SwitchPage(0);
}
}
}

View File

@ -1,124 +0,0 @@
/**
* Copyright 2013 Dolphin Emulator Project
* Licensed under GPLv2+
* Refer to the license.txt file included.
*/
package org.dolphinemu.dolphinemu.gamelist;
import android.content.Context;
import android.graphics.Bitmap;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ImageView;
import android.widget.TextView;
import org.dolphinemu.dolphinemu.R;
/**
* The adapter backing the game list.
* <p>
* Responsible for handling each game list item individually.
*/
public final class GameListAdapter extends ArrayAdapter<GameListItem>
{
private static final float BYTES_PER_GIB = 1024 * 1024 * 1024;
private static final float BYTES_PER_MIB = 1024 * 1024;
private final Context context;
private final int id;
/**
* Constructor
*
* @param context The current {@link Context}.
* @param resourceId The resource ID for a layout file containing a layout to use when instantiating views.
*/
public GameListAdapter(Context context, int resourceId)
{
super(context, resourceId);
this.context = context;
this.id = resourceId;
}
@Override
public View getView(int position, View gameView, ViewGroup parent)
{
ViewHolder holder;
// If getView() was called without passing in a recycled view,
if (gameView == null)
{
// Inflate a new view using the appropriate XML layout.
LayoutInflater inflater = LayoutInflater.from(context);
gameView = inflater.inflate(id, parent, false);
// Instantiate a holder to contain references to the game's views.
holder = new ViewHolder();
holder.title = (TextView) gameView.findViewById(R.id.GameListItemTitle);
holder.subtitle = (TextView) gameView.findViewById(R.id.GameListItemSubTitle);
holder.icon = (ImageView) gameView.findViewById(R.id.GameListItemIcon);
// Attach this list of references to the view.
gameView.setTag(holder);
}
// If we do have a recycled view, we can use the references it already contains.
else
{
holder = (ViewHolder) gameView.getTag();
}
// Get a reference to the game represented by this row.
final GameListItem item = getItem(position);
// Whether this row's view is newly created or not, set the children to contain the game's data.
if (item != null)
{
holder.title.setText(item.getName());
Bitmap icon = item.getImage();
if (icon != null)
{
holder.icon.setImageBitmap(icon);
}
else
{
holder.icon.setImageResource(R.drawable.no_banner);
}
float fileSize = item.getFilesize() / BYTES_PER_GIB;
String subtitle;
if (fileSize >= 1.0f)
{
subtitle = String.format(context.getString(R.string.file_size_gib), fileSize);
}
else
{
fileSize = item.getFilesize() / BYTES_PER_MIB;
subtitle = String.format(context.getString(R.string.file_size_mib), fileSize);
}
holder.subtitle.setText(subtitle);
}
// Make every other game in the list grey
if (position % 2 == 1)
gameView.setBackgroundColor(0xFFE3E3E3);
return gameView;
}
private final class ViewHolder
{
public TextView title;
public TextView subtitle;
public ImageView icon;
}
}

View File

@ -1,150 +0,0 @@
/**
* Copyright 2013 Dolphin Emulator Project
* Licensed under GPLv2+
* Refer to the license.txt file included.
*/
package org.dolphinemu.dolphinemu.gamelist;
import android.app.Activity;
import android.app.ListFragment;
import android.content.Intent;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ListView;
import android.widget.Toast;
import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import org.dolphinemu.dolphinemu.NativeLibrary;
import org.dolphinemu.dolphinemu.R;
import org.dolphinemu.dolphinemu.emulation.EmulationActivity;
/**
* The {@link ListFragment} responsible for displaying the game list.
*/
public final class GameListFragment extends ListFragment
{
private GameListAdapter mGameAdapter;
private OnGameListZeroListener mCallback;
/**
* Interface that defines how to handle the case
* when there are zero games in the game list.
*/
public interface OnGameListZeroListener
{
/**
* This is called when there are no games
* currently present within the game list.
*/
void onZeroFiles();
}
/**
* Clears all entries from the {@link GameListAdapter}
* backing this GameListFragment.
*/
public void clearGameList()
{
mGameAdapter.clear();
mGameAdapter.notifyDataSetChanged();
}
private void fill()
{
List<GameListItem> fls = new ArrayList<GameListItem>();
String Directories = NativeLibrary.GetConfig("Dolphin.ini", "General", "ISOPaths", "0");
int intDirectories = Integer.parseInt(Directories);
// Extensions to filter by.
Set<String> exts = new HashSet<String>(Arrays.asList(".dff", ".dol", ".elf", ".gcm", ".gcz", ".iso", ".wad", ".wbfs"));
for (int a = 0; a < intDirectories; ++a)
{
String BrowseDir = NativeLibrary.GetConfig("Dolphin.ini", "General", "ISOPath" + a, "");
File currentDir = new File(BrowseDir);
File[] dirs = currentDir.listFiles();
try
{
for (File entry : dirs)
{
String entryName = entry.getName();
if (!entry.isHidden() && !entry.isDirectory())
{
if (exts.contains(entryName.toLowerCase().substring(entryName.lastIndexOf('.'))))
fls.add(new GameListItem(getActivity(), entryName, entry.length(), entry.getAbsolutePath()));
}
}
}
catch (Exception ignored)
{
}
}
Collections.sort(fls);
// Add all the items to the adapter
mGameAdapter.addAll(fls);
mGameAdapter.notifyDataSetChanged();
if (fls.isEmpty())
{
mCallback.onZeroFiles();
}
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
ListView rootView = (ListView) inflater.inflate(R.layout.gamelist_listview, container, false);
mGameAdapter = new GameListAdapter(getActivity(), R.layout.gamelist_list_item);
rootView.setAdapter(mGameAdapter);
fill();
return rootView;
}
@Override
public void onListItemClick(ListView listView, View view, int position, long id)
{
GameListItem item = mGameAdapter.getItem(position);
// Show a toast indicating which game was clicked.
Toast.makeText(getActivity(), String.format(getString(R.string.file_clicked), item.getPath()), Toast.LENGTH_SHORT).show();
// Start the emulation activity and send the path of the clicked ROM to it.
Intent intent = new Intent(getActivity(), EmulationActivity.class);
intent.putExtra("SelectedGame", item.getPath());
startActivity(intent);
}
@Override
public void onAttach(Activity activity)
{
super.onAttach(activity);
// This makes sure that the container activity has implemented
// the callback interface. If not, it throws an exception
try
{
mCallback = (OnGameListZeroListener) activity;
}
catch (ClassCastException e)
{
throw new ClassCastException(activity.toString()
+ " must implement OnGameListZeroListener");
}
}
}

View File

@ -1,102 +0,0 @@
/**
* Copyright 2013 Dolphin Emulator Project
* Licensed under GPLv2+
* Refer to the license.txt file included.
*/
package org.dolphinemu.dolphinemu.gamelist;
import android.content.Context;
import android.graphics.Bitmap;
import java.io.File;
import org.dolphinemu.dolphinemu.NativeLibrary;
/**
* Represents an item in the game list.
*/
public final class GameListItem implements Comparable<GameListItem>
{
private String name;
private long filesize;
private final String path;
private Bitmap image;
/**
* Constructor.
*
* @param ctx The current {@link Context}
* @param name The name of this GameListItem.
* @param filesize The filesize for this GameListItem, in GiB
* @param path The file path for the game represented by this GameListItem.
*/
public GameListItem(Context ctx, String name, long filesize, String path)
{
this.name = name;
this.filesize = filesize;
this.path = path;
File file = new File(path);
if (!file.isDirectory() && !path.isEmpty())
{
int[] Banner = NativeLibrary.GetBanner(path);
if (Banner[0] != 0)
{
image = Bitmap.createBitmap(Banner, 96, 32, Bitmap.Config.ARGB_8888);
}
this.name = NativeLibrary.GetTitle(path);
}
}
/**
* Gets the name of this GameListItem.
*
* @return the name of this GameListItem.
*/
public String getName()
{
return name;
}
/**
* Gets the filesize of this GameListItem, in GiB.
*
* @return the filesize of this GameListItem.
*/
public long getFilesize()
{
return filesize;
}
/**
* Gets the file path of the game represented by this GameListItem.
*
* @return the file path of the game represented by this GameListItem.
*/
public String getPath()
{
return path;
}
/**
* Gets the image data for this game as a {@link Bitmap}.
*
* @return the image data for this game as a {@link Bitmap}.
*/
public Bitmap getImage()
{
return image;
}
@Override
public int compareTo(GameListItem o)
{
if (name != null)
return name.toLowerCase().compareTo(o.getName().toLowerCase());
else
throw new NullPointerException("The name of this GameListItem is null");
}
}

View File

@ -111,10 +111,35 @@ public final class GameDatabase extends SQLiteOpenHelper
public void scanLibrary(SQLiteDatabase database)
{
// TODO Before scanning known folders, go through the game table and remove any entries for which the file itself is missing.
// Before scanning known folders, go through the game table and remove any entries for which the file itself is missing.
Cursor fileCursor = database.query(TABLE_NAME_GAMES,
null, // Get all columns.
null, // Get all rows.
null,
null, // No grouping.
null,
null); // Order of games is irrelevant.
// Possibly overly defensive, but ensures that moveToNext() does not skip a row.
fileCursor.moveToPosition(-1);
while (fileCursor.moveToNext())
{
String gamePath = fileCursor.getString(GAME_COLUMN_PATH);
File game = new File(gamePath);
if (!game.exists())
{
Log.e("DolphinEmu", "Game file no longer exists. Removing from the library: " + gamePath);
database.delete(TABLE_NAME_GAMES,
KEY_DB_ID + " = ?",
new String[]{Long.toString(fileCursor.getLong(COLUMN_DB_ID))});
}
}
// Get a cursor listing all the folders the user has added to the library.
Cursor cursor = database.query(TABLE_NAME_FOLDERS,
Cursor folderCursor = database.query(TABLE_NAME_FOLDERS,
null, // Get all columns.
null, // Get all rows.
null,
@ -125,74 +150,91 @@ public final class GameDatabase extends SQLiteOpenHelper
Set<String> allowedExtensions = new HashSet<String>(Arrays.asList(".dff", ".dol", ".elf", ".gcm", ".gcz", ".iso", ".wad", ".wbfs"));
// Possibly overly defensive, but ensures that moveToNext() does not skip a row.
cursor.moveToPosition(-1);
folderCursor.moveToPosition(-1);
// Iterate through all results of the DB query (i.e. all folders in the library.)
while (cursor.moveToNext())
while (folderCursor.moveToNext())
{
String folderPath = cursor.getString(FOLDER_COLUMN_PATH);
String folderPath = folderCursor.getString(FOLDER_COLUMN_PATH);
File folder = new File(folderPath);
Log.i("DolphinEmu", "Reading files from library folder: " + folderPath);
// Iterate through every file in the folder.
File[] children = folder.listFiles();
for (File file : children)
if (children != null)
{
if (!file.isHidden() && !file.isDirectory())
for (File file : children)
{
String filePath = file.getPath();
int extensionStart = filePath.lastIndexOf('.');
if (extensionStart > 0)
if (!file.isHidden() && !file.isDirectory())
{
String fileExtension = filePath.substring(extensionStart);
String filePath = file.getPath();
// Check that the file has an extension we care about before trying to read out of it.
if (allowedExtensions.contains(fileExtension))
int extensionStart = filePath.lastIndexOf('.');
if (extensionStart > 0)
{
String name = NativeLibrary.GetTitle(filePath);
String fileExtension = filePath.substring(extensionStart);
// If the game's title field is empty, use the filename.
if (name.isEmpty())
// Check that the file has an extension we care about before trying to read out of it.
if (allowedExtensions.contains(fileExtension))
{
name = filePath.substring(filePath.lastIndexOf("/") + 1);
}
String name = NativeLibrary.GetTitle(filePath);
ContentValues game = Game.asContentValues(NativeLibrary.GetPlatform(filePath),
name,
NativeLibrary.GetDescription(filePath).replace("\n", " "),
NativeLibrary.GetCountry(filePath),
filePath,
NativeLibrary.GetGameId(filePath),
NativeLibrary.GetCompany(filePath));
// If the game's title field is empty, use the filename.
if (name.isEmpty())
{
name = filePath.substring(filePath.lastIndexOf("/") + 1);
}
// Try to update an existing game first.
int rowsMatched = database.update(TABLE_NAME_GAMES, // Which table to update.
game, // The values to fill the row with.
KEY_GAME_ID + " = ?", // The WHERE clause used to find the right row.
new String[]{game.getAsString(KEY_GAME_ID)}); // The ? in WHERE clause is replaced with this,
// which is provided as an array because there
// could potentially be more than one argument.
ContentValues game = Game.asContentValues(NativeLibrary.GetPlatform(filePath),
name,
NativeLibrary.GetDescription(filePath).replace("\n", " "),
NativeLibrary.GetCountry(filePath),
filePath,
NativeLibrary.GetGameId(filePath),
NativeLibrary.GetCompany(filePath));
// If update fails, insert a new game instead.
if (rowsMatched == 0)
{
Log.v("DolphinEmu", "Adding game: " + game.getAsString(KEY_GAME_TITLE));
database.insert(TABLE_NAME_GAMES, null, game);
}
else
{
Log.v("DolphinEmu", "Updated game: " + game.getAsString(KEY_GAME_TITLE));
// Try to update an existing game first.
int rowsMatched = database.update(TABLE_NAME_GAMES, // Which table to update.
game, // The values to fill the row with.
KEY_GAME_ID + " = ?", // The WHERE clause used to find the right row.
new String[]{game.getAsString(KEY_GAME_ID)}); // The ? in WHERE clause is replaced with this,
// which is provided as an array because there
// could potentially be more than one argument.
// If update fails, insert a new game instead.
if (rowsMatched == 0)
{
Log.v("DolphinEmu", "Adding game: " + game.getAsString(KEY_GAME_TITLE));
database.insert(TABLE_NAME_GAMES, null, game);
}
else
{
Log.v("DolphinEmu", "Updated game: " + game.getAsString(KEY_GAME_TITLE));
}
}
}
}
}
}
// If the folder is empty because it no longer exists, remove it from the library.
else if (!folder.exists())
{
Log.e("DolphinEmu", "Folder no longer exists. Removing from the library: " + folderPath);
database.delete(TABLE_NAME_FOLDERS,
KEY_DB_ID + " = ?",
new String[]{Long.toString(folderCursor.getLong(COLUMN_DB_ID))});
}
else
{
Log.e("DolphinEmu", "Folder contains no games: " + folderPath);
}
}
cursor.close();
folderCursor.close();
database.close();
}
}

View File

@ -98,6 +98,7 @@ public final class GameProvider extends ContentProvider
{
if (table.equals(REFRESH_LIBRARY))
{
Log.i("DolphinEmu", "URI specified table REFRESH_LIBRARY. No insertion necessary; refreshing library contents...");
mDbHelper.scanLibrary(database);
return uri;
}

View File

@ -4,7 +4,7 @@
* Refer to the license.txt file included.
*/
package org.dolphinemu.dolphinemu.emulation.overlay;
package org.dolphinemu.dolphinemu.overlay;
import android.content.Context;
import android.content.SharedPreferences;
@ -21,10 +21,12 @@ import android.view.MotionEvent;
import android.view.SurfaceView;
import android.view.View;
import android.view.View.OnTouchListener;
import org.dolphinemu.dolphinemu.NativeLibrary;
import org.dolphinemu.dolphinemu.NativeLibrary.ButtonState;
import org.dolphinemu.dolphinemu.NativeLibrary.ButtonType;
import org.dolphinemu.dolphinemu.R;
import java.util.HashSet;
import java.util.Set;

View File

@ -4,7 +4,7 @@
* Refer to the license.txt file included.
*/
package org.dolphinemu.dolphinemu.emulation.overlay;
package org.dolphinemu.dolphinemu.overlay;
import android.content.res.Resources;
import android.graphics.Bitmap;

View File

@ -4,7 +4,7 @@
* Refer to the license.txt file included.
*/
package org.dolphinemu.dolphinemu.emulation.overlay;
package org.dolphinemu.dolphinemu.overlay;
import android.content.res.Resources;
import android.graphics.Bitmap;

View File

@ -13,7 +13,7 @@ import android.preference.PreferenceManager;
import android.util.Log;
import org.dolphinemu.dolphinemu.NativeLibrary;
import org.dolphinemu.dolphinemu.settings.UserPreferences;
import org.dolphinemu.dolphinemu.utils.UserPreferences;
import java.io.File;
import java.io.FileOutputStream;

View File

@ -4,7 +4,7 @@ import android.app.IntentService;
import android.content.Intent;
import android.util.Log;
import org.dolphinemu.dolphinemu.settings.UserPreferences;
import org.dolphinemu.dolphinemu.utils.UserPreferences;
/**
* IntentServices, unlike regular services, inherently run on a background thread.

View File

@ -1,101 +0,0 @@
/**
* Copyright 2013 Dolphin Emulator Project
* Licensed under GPLv2+
* Refer to the license.txt file included.
*/
package org.dolphinemu.dolphinemu.settings;
import org.dolphinemu.dolphinemu.R;
import org.dolphinemu.dolphinemu.settings.cpu.CPUSettingsFragment;
import org.dolphinemu.dolphinemu.settings.input.InputConfigFragment;
import org.dolphinemu.dolphinemu.settings.video.VideoSettingsFragment;
import android.app.Activity;
import android.app.Fragment;
import android.app.FragmentManager;
import android.content.SharedPreferences;
import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.support.v13.app.FragmentPagerAdapter;
import android.support.v4.view.ViewPager;
/**
* Main activity that manages all of the preference fragments used to display
* the settings to the user.
*/
public final class PrefsActivity extends Activity implements OnSharedPreferenceChangeListener
{
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.viewpager);
// Set the ViewPager adapter.
final ViewPager viewPager = (ViewPager) findViewById(R.id.pager);
viewPager.setAdapter(new ViewPagerAdapter(getFragmentManager()));
// Register the preference change listener.
final SharedPreferences sPrefs = PreferenceManager.getDefaultSharedPreferences(this);
sPrefs.registerOnSharedPreferenceChangeListener(this);
}
@Override
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key)
{
// If any change is made to the preferences in the front-end, immediately save them.
UserPreferences.SavePrefsToIni(this);
}
/**
* A {@link FragmentPagerAdapter} that returns a fragment
* corresponding to one of the sections/tabs/pages.
*/
private final class ViewPagerAdapter extends FragmentPagerAdapter
{
private final String[] pageTitles = {
getString(R.string.cpu_settings),
getString(R.string.input_settings),
getString(R.string.video_settings)
};
public ViewPagerAdapter(FragmentManager fm)
{
super(fm);
}
@Override
public Fragment getItem(int position)
{
switch(position)
{
case 0:
return new CPUSettingsFragment();
case 1:
return new InputConfigFragment();
case 2:
return new VideoSettingsFragment();
default: // Should never happen.
return null;
}
}
@Override
public int getCount()
{
// Show total pages.
return 3;
}
@Override
public CharSequence getPageTitle(int position)
{
return pageTitles[position];
}
}
}

View File

@ -1,51 +0,0 @@
/**
* Copyright 2013 Dolphin Emulator Project
* Licensed under GPLv2+
* Refer to the license.txt file included.
*/
package org.dolphinemu.dolphinemu.settings.cpu;
import org.dolphinemu.dolphinemu.R;
import android.os.Build;
import android.os.Bundle;
import android.preference.ListPreference;
import android.preference.PreferenceFragment;
/**
* Responsible for the loading of the CPU preferences.
*/
public final class CPUSettingsFragment extends PreferenceFragment
{
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
// Load the preferences from an XML resource
addPreferencesFromResource(R.xml.cpu_prefs);
final ListPreference cpuCores = (ListPreference) findPreference("cpuCorePref");
//
// Set valid emulation cores depending on the CPU architecture
// that the Android device is running on.
//
if (Build.CPU_ABI.contains("x86-64"))
{
cpuCores.setEntries(R.array.emuCoreEntriesX86_64);
cpuCores.setEntryValues(R.array.emuCoreValuesX86_64);
}
else if (Build.CPU_ABI.contains("arm64"))
{
cpuCores.setEntries(R.array.emuCoreEntriesARM64);
cpuCores.setEntryValues(R.array.emuCoreValuesARM64);
}
else
{
cpuCores.setEntries(R.array.emuCoreEntriesOther);
cpuCores.setEntryValues(R.array.emuCoreValuesOther);
}
}
}

View File

@ -1,39 +0,0 @@
/**
* Copyright 2013 Dolphin Emulator Project
* Licensed under GPLv2+
* Refer to the license.txt file included.
*/
package org.dolphinemu.dolphinemu.settings.custom;
import android.content.Context;
import android.preference.ListPreference;
import android.util.AttributeSet;
/**
* A {@link ListPreference} that updates its summary upon it's selection being changed.
*/
public final class UpdatingListPreference extends ListPreference
{
/**
* Constructor
*
* @param context the current {@link Context}.
*/
public UpdatingListPreference(Context context, AttributeSet attribs)
{
super(context, attribs);
}
@Override
public void onDialogClosed(boolean positiveResult)
{
super.onDialogClosed(positiveResult);
// If an entry was selected
if (positiveResult)
{
setSummary(getEntry());
}
}
}

View File

@ -1,51 +0,0 @@
/**
* Copyright 2013 Dolphin Emulator Project
* Licensed under GPLv2+
* Refer to the license.txt file included.
*/
package org.dolphinemu.dolphinemu.settings.input.overlayconfig;
import org.dolphinemu.dolphinemu.R;
import android.app.Activity;
import android.os.Bundle;
import android.widget.RelativeLayout;
/**
* {@link Activity} used for configuring the input overlay.
*/
public final class OverlayConfigActivity extends Activity
{
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
// Initialize all of the buttons to add.
final OverlayConfigButton buttonA = new OverlayConfigButton(this, "gcpad_a", R.drawable.gcpad_a);
final OverlayConfigButton buttonB = new OverlayConfigButton(this, "gcpad_b", R.drawable.gcpad_b);
final OverlayConfigButton buttonX = new OverlayConfigButton(this, "gcpad_x", R.drawable.gcpad_x);
final OverlayConfigButton buttonY = new OverlayConfigButton(this, "gcpad_y", R.drawable.gcpad_y);
final OverlayConfigButton buttonZ = new OverlayConfigButton(this, "gcpad_z", R.drawable.gcpad_z);
final OverlayConfigButton buttonS = new OverlayConfigButton(this, "gcpad_start", R.drawable.gcpad_start);
final OverlayConfigButton buttonL = new OverlayConfigButton(this, "gcpad_l", R.drawable.gcpad_l);
final OverlayConfigButton buttonR = new OverlayConfigButton(this, "gcpad_r", R.drawable.gcpad_r);
final OverlayConfigButton joystick = new OverlayConfigButton(this, "gcpad_joystick_range", R.drawable.gcpad_joystick_range);
// Add the buttons to the layout
final RelativeLayout configLayout = new RelativeLayout(this);
configLayout.addView(buttonA);
configLayout.addView(buttonB);
configLayout.addView(buttonX);
configLayout.addView(buttonY);
configLayout.addView(buttonZ);
configLayout.addView(buttonS);
configLayout.addView(buttonL);
configLayout.addView(buttonR);
configLayout.addView(joystick);
// Now set the layout
setContentView(configLayout);
}
}

View File

@ -1,166 +0,0 @@
/**
* Copyright 2013 Dolphin Emulator Project
* Licensed under GPLv2+
* Refer to the license.txt file included.
*/
package org.dolphinemu.dolphinemu.settings.input.overlayconfig;
import android.content.Context;
import android.content.SharedPreferences;
import android.graphics.Bitmap;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.preference.PreferenceManager;
import android.util.DisplayMetrics;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnTouchListener;
import android.widget.Button;
import org.dolphinemu.dolphinemu.R;
/**
* A movable {@link Button} for use within the
* input overlay configuration screen.
*/
public final class OverlayConfigButton extends Button implements OnTouchListener
{
// SharedPreferences instance that the button positions are cached to.
private final SharedPreferences sharedPrefs;
// The String ID for this button.
//
// This ID is used upon releasing this button as the key for saving
// the X and Y coordinates of this button. This same key is also used
// for setting the coordinates of the button on the actual overlay during emulation.
//
// They can be accessed through SharedPreferences respectively as follows:
//
// SharedPreferences sPrefs = PreferenceManager.getDefaultSharedPreferences(this);
// float buttonX = sPrefs.getFloat(buttonId+"-X", -1f);
// float buttonY = sPrefs.getFloat(buttonId+"-Y", -1f);
//
private final String buttonId;
// The offset of the press while moving the button
private float moveOffsetX, moveOffsetY;
private Drawable resizeDrawable(Drawable image, float scale)
{
// Retrieve screen dimensions.
DisplayMetrics displayMetrics = getResources().getDisplayMetrics();
Bitmap b = ((BitmapDrawable)image).getBitmap();
Bitmap bitmapResized = Bitmap.createScaledBitmap(b,
(int)(displayMetrics.heightPixels * scale),
(int)(displayMetrics.heightPixels * scale),
true);
return new BitmapDrawable(getResources(), bitmapResized);
}
/**
* Constructor
*
* @param context the current {@link Context}.
* @param buttonId the String ID for this button.
* @param drawableId the Drawable ID for the image to represent this OverlayConfigButton.
*/
public OverlayConfigButton(Context context, String buttonId, int drawableId)
{
super(context);
// Set the button ID.
this.buttonId = buttonId;
// Set the button as its own OnTouchListener.
setOnTouchListener(this);
// Get the SharedPreferences instance.
sharedPrefs = PreferenceManager.getDefaultSharedPreferences(context);
// Decide scale based on button ID
// SeekBars are not able to set a minimum value, only a maximum value, which complicates
// things a bit. What happens here is after the SeekBar's value is retrieved, 25 is
// added so the value will never go below 25. It is then divided by 50 (25 + 25) so the
// default value will be 100%.
float scale;
float overlaySize = sharedPrefs.getInt("controls_size", 25);
overlaySize += 25;
overlaySize /= 50;
switch (drawableId)
{
case R.drawable.gcpad_b:
scale = 0.13f * overlaySize;
break;
case R.drawable.gcpad_x:
case R.drawable.gcpad_y:
scale = 0.18f * overlaySize;
break;
case R.drawable.gcpad_start:
scale = 0.12f * overlaySize;
break;
case R.drawable.gcpad_joystick_range:
scale = 0.30f * overlaySize;
break;
default:
scale = 0.20f * overlaySize;
break;
}
// Set the button's icon that represents it.
setBackground(resizeDrawable(getResources().getDrawable(drawableId), scale));
// Check if this button has previous values set that aren't the default.
final float x = sharedPrefs.getFloat(buttonId+"-X", -1f);
final float y = sharedPrefs.getFloat(buttonId+"-Y", -1f);
// If they are not -1, then they have a previous value set.
// Thus, we set those coordinate values.
if (x != -1f && y != -1f)
{
setX(x);
setY(y);
}
}
@Override
public boolean onTouch(View v, MotionEvent event)
{
switch(event.getAction())
{
// Get the offset of the press within the button
// The event X and Y locations are the offset within the button, not the screen
case MotionEvent.ACTION_DOWN:
{
moveOffsetX = event.getX();
moveOffsetY = event.getY();
return true;
}
// Only change the X/Y coordinates when we move the button.
case MotionEvent.ACTION_MOVE:
{
setX(getX() + event.getX() - moveOffsetX);
setY(getY() + event.getY() - moveOffsetY);
return true;
}
// Whenever the press event has ended
// is when we save all of the information.
case MotionEvent.ACTION_UP:
{
// Add the current X and Y positions of this button into SharedPreferences.
SharedPreferences.Editor editor = sharedPrefs.edit();
editor.putFloat(buttonId+"-X", getX());
editor.putFloat(buttonId+"-Y", getY());
editor.apply();
return true;
}
}
return false;
}
}

View File

@ -1,202 +0,0 @@
/**
* Copyright 2013 Dolphin Emulator Project
* Licensed under GPLv2+
* Refer to the license.txt file included.
*/
package org.dolphinemu.dolphinemu.settings.video;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.SharedPreferences;
import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
import android.os.Bundle;
import android.os.Environment;
import android.preference.ListPreference;
import android.preference.PreferenceFragment;
import android.preference.PreferenceManager;
import android.preference.PreferenceScreen;
import org.dolphinemu.dolphinemu.R;
import org.dolphinemu.dolphinemu.utils.EGLHelper;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import javax.microedition.khronos.opengles.GL10;
/**
* Responsible for handling the loading of the video preferences.
*/
public final class VideoSettingsFragment extends PreferenceFragment
{
private final EGLHelper eglHelper = new EGLHelper(EGLHelper.EGL_OPENGL_ES2_BIT);
private final String vendor = eglHelper.getGL().glGetString(GL10.GL_VENDOR);
private final String version = eglHelper.getGL().glGetString(GL10.GL_VERSION);
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
// Load the preferences from an XML resource
addPreferencesFromResource(R.xml.video_prefs);
//
// Setting valid video backends.
//
final ListPreference videoBackends = (ListPreference) findPreference("gpuPref");
final boolean deviceSupportsGL = eglHelper.supportsOpenGL();
final boolean deviceSupportsGLES3 = eglHelper.supportsGLES3();
if (deviceSupportsGL)
{
videoBackends.setEntries(R.array.videoBackendEntriesGL);
videoBackends.setEntryValues(R.array.videoBackendValuesGL);
}
else if (deviceSupportsGLES3)
{
videoBackends.setEntries(R.array.videoBackendEntriesGLES3);
videoBackends.setEntryValues(R.array.videoBackendValuesGLES3);
}
else
{
videoBackends.setEntries(R.array.videoBackendEntriesNoGLES3);
videoBackends.setEntryValues(R.array.videoBackendValuesNoGLES3);
}
//
// Set available post processing shaders
//
List<CharSequence> shader_names = new ArrayList<CharSequence>();
List<CharSequence> shader_values = new ArrayList<CharSequence>();
// Disabled option
shader_names.add("Disabled");
shader_values.add("");
File shaders_folder = new File(Environment.getExternalStorageDirectory()+ File.separator+"dolphin-emu"+ File.separator+"Shaders");
if (shaders_folder.exists())
{
File[] shaders = shaders_folder.listFiles();
for (File file : shaders)
{
if (file.isFile())
{
String filename = file.getName();
if (filename.contains(".glsl"))
{
// Strip the extension and put it in to the list
shader_names.add(filename.substring(0, filename.lastIndexOf('.')));
shader_values.add(filename.substring(0, filename.lastIndexOf('.')));
}
}
}
}
final ListPreference shader_preference = (ListPreference) findPreference("postProcessingShader");
shader_preference.setEntries(shader_names.toArray(new CharSequence[shader_names.size()]));
shader_preference.setEntryValues(shader_values.toArray(new CharSequence[shader_values.size()]));
//
// Disable all options if Software Rendering is used.
//
// Note that the numeric value in 'getPreference()'
// denotes the placement on the UI. So if more elements are
// added to the video settings, these may need to change.
//
final SharedPreferences sPrefs = PreferenceManager.getDefaultSharedPreferences(getActivity());
final PreferenceScreen mainScreen = getPreferenceScreen();
if (videoBackends.getValue().equals("Software Renderer"))
{
mainScreen.getPreference(0).setEnabled(false);
mainScreen.getPreference(1).setEnabled(false);
mainScreen.getPreference(3).setEnabled(false);
}
else if (videoBackends.getValue().equals("OGL"))
{
mainScreen.getPreference(0).setEnabled(true);
mainScreen.getPreference(1).setEnabled(true);
mainScreen.getPreference(3).setEnabled(true);
// Check if we support stereo
// If we support desktop GL then we must support at least OpenGL 3.2
// If we only support OpenGLES then we need both OpenGLES 3.1 and AEP
if ((eglHelper.supportsOpenGL() && eglHelper.GetVersion() >= 320) ||
(eglHelper.supportsGLES3() && eglHelper.GetVersion() >= 310 && eglHelper.SupportsExtension("GL_ANDROID_extension_pack_es31a")))
mainScreen.findPreference("StereoscopyScreen").setEnabled(true);
else
mainScreen.findPreference("StereoscopyScreen").setEnabled(false);
}
// Also set a listener, so that if someone changes the video backend, it will disable
// the video settings, upon the user choosing "Software Rendering".
sPrefs.registerOnSharedPreferenceChangeListener(new OnSharedPreferenceChangeListener()
{
@Override
public void onSharedPreferenceChanged(SharedPreferences preference, String key)
{
if (key.equals("gpuPref"))
{
if (preference.getString(key, "Software Renderer").equals("Software Renderer"))
{
mainScreen.getPreference(0).setEnabled(false);
mainScreen.getPreference(1).setEnabled(false);
mainScreen.getPreference(3).setEnabled(false);
}
else if (preference.getString(key, "Software Renderer").equals("OGL"))
{
mainScreen.getPreference(0).setEnabled(true);
mainScreen.getPreference(1).setEnabled(true);
mainScreen.getPreference(3).setEnabled(true);
// Create an alert telling them that their phone sucks
if (eglHelper.supportsGLES3()
&& vendor.equals("Qualcomm")
&& getQualcommVersion() == 14.0f)
{
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
builder.setTitle(R.string.device_compat_warning);
builder.setMessage(R.string.device_gles3compat_warning_msg);
builder.setPositiveButton(R.string.yes, null);
builder.setNegativeButton(R.string.no, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which)
{
// Get an editor.
SharedPreferences.Editor editor = sPrefs.edit();
editor.putString("gpuPref", "Software Renderer");
editor.apply();
videoBackends.setValue("Software Renderer");
videoBackends.setSummary("Software Renderer");
}
});
builder.show();
}
}
}
}
});
}
private float getQualcommVersion()
{
final int start = version.indexOf("V@") + 2;
final StringBuilder versionBuilder = new StringBuilder();
for (int i = start; i < version.length(); i++)
{
char c = version.charAt(i);
// End of numeric portion of version string.
if (c == ' ')
break;
versionBuilder.append(c);
}
return Float.parseFloat(versionBuilder.toString());
}
}

View File

@ -1,75 +0,0 @@
/**
* Copyright 2013 Dolphin Emulator Project
* Licensed under GPLv2+
* Refer to the license.txt file included.
*/
package org.dolphinemu.dolphinemu.sidemenu;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.TextView;
import java.util.List;
import org.dolphinemu.dolphinemu.R;
/**
* Adapter that backs the sidebar menu.
* <p>
* Responsible for handling the elements of each sidebar item.
*/
public final class SideMenuAdapter extends ArrayAdapter<SideMenuItem>
{
private final Context context;
private final int id;
private final List<SideMenuItem>items;
/**
* Constructor
*
* @param context The current {@link Context}.
* @param resourceId The resource ID for a layout file containing a layout to use when instantiating views.
* @param objects The objects to represent in the {@link ListView}.
*/
public SideMenuAdapter(Context context, int resourceId, List<SideMenuItem> objects)
{
super(context, resourceId, objects);
this.context = context;
this.id = resourceId;
this.items = objects;
}
@Override
public SideMenuItem getItem(int i)
{
return items.get(i);
}
@Override
public View getView(int position, View convertView, ViewGroup parent)
{
if (convertView == null)
{
LayoutInflater vi = LayoutInflater.from(context);
convertView = vi.inflate(id, null);
}
final SideMenuItem item = items.get(position);
if (item != null)
{
TextView title = (TextView) convertView.findViewById(R.id.SideMenuTitle);
if (title != null)
title.setText(item.getName());
}
return convertView;
}
}

View File

@ -1,50 +0,0 @@
/*
* Copyright 2013 Dolphin Emulator Project
* Licensed under GPLv2+
* Refer to the license.txt file included.
*/
package org.dolphinemu.dolphinemu.sidemenu;
/**
* Represents an item that goes in the sidemenu of the app.
*/
public final class SideMenuItem
{
private final String name;
private final int id;
/**
* Constructor
*
* @param name The name of the SideMenuItem.
* @param id ID number of this specific SideMenuItem.
*/
public SideMenuItem(String name, int id)
{
this.name = name;
this.id = id;
}
/**
* Gets the name of this SideMenuItem.
*
* @return the name of this SideMenuItem.
*/
public String getName()
{
return name;
}
/**
* Gets the ID of this SideMenuItem.
*
* @return the ID of this SideMenuItem.
*/
public int getID()
{
return id;
}
}

View File

@ -1,6 +1,4 @@
package org.dolphinemu.dolphinemu.settings.input;
import org.dolphinemu.dolphinemu.R;
package org.dolphinemu.dolphinemu.utils;
import android.app.AlertDialog;
import android.content.Context;
@ -8,6 +6,9 @@ import android.content.DialogInterface;
import android.preference.Preference;
import android.util.AttributeSet;
import org.dolphinemu.dolphinemu.R;
import org.dolphinemu.dolphinemu.dialogs.MotionAlertDialog;
/**
* {@link Preference} subclass that represents a preference
* used for assigning a key bind.
@ -16,7 +17,7 @@ public final class InputBindingPreference extends Preference
{
/**
* Constructor that is called when inflating an InputBindingPreference from XML.
*
*
* @param context The current {@link Context}.
* @param attrs The attributes of the XML tag that is inflating the preference.
*/
@ -34,11 +35,11 @@ public final class InputBindingPreference extends Preference
// Set the cancel button.
dialog.setButton(AlertDialog.BUTTON_NEGATIVE, getContext().getString(R.string.cancel), new AlertDialog.OnClickListener()
{
@Override
public void onClick(DialogInterface dialog, int which)
{
// Do nothing. Just makes the cancel button show up.
}
@Override
public void onClick(DialogInterface dialog, int which)
{
// Do nothing. Just makes the cancel button show up.
}
});
// Set the title and description message.

View File

@ -4,7 +4,7 @@
* Refer to the license.txt file included.
*/
package org.dolphinemu.dolphinemu.settings.input;
package org.dolphinemu.dolphinemu.utils;
import android.app.Fragment;
import android.os.Build;
@ -12,6 +12,7 @@ import android.os.Bundle;
import android.preference.Preference;
import android.preference.PreferenceFragment;
import android.view.InputDevice;
import org.dolphinemu.dolphinemu.NativeLibrary;
import org.dolphinemu.dolphinemu.R;

View File

@ -4,15 +4,15 @@
* Refer to the license.txt file included.
*/
package org.dolphinemu.dolphinemu.settings;
import org.dolphinemu.dolphinemu.NativeLibrary;
package org.dolphinemu.dolphinemu.utils;
import android.content.Context;
import android.content.SharedPreferences;
import android.os.Build;
import android.preference.PreferenceManager;
import org.dolphinemu.dolphinemu.NativeLibrary;
/**
* A class that retrieves all of the set user preferences in Android, in a safe way.
* <p>

View File

@ -1,24 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:minHeight="?android:attr/listPreferredItemHeight"
android:orientation="vertical">
<TextView
android:id="@+id/AboutItemTitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="15dip"
android:layout_marginTop="6dip"
android:singleLine="true"
android:textAppearance="?android:attr/textAppearanceMedium"/>
<TextView
android:id="@+id/AboutItemSubTitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="15dip"
android:textAppearance="?android:attr/textAppearanceSmall"/>
</LinearLayout>

View File

@ -1,22 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<merge xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="match_parent">
<!-- This is what everything is rendered to during emulation -->
<org.dolphinemu.dolphinemu.emulation.NativeGLSurfaceView
android:id="@+id/emulationView"
android:layout_height="match_parent"
android:layout_width="match_parent"
android:focusable="false"
android:focusableInTouchMode="false"/>
<!-- This is the onscreen input overlay -->
<org.dolphinemu.dolphinemu.emulation.overlay.InputOverlay
android:id="@+id/emulationControlOverlay"
android:layout_height="match_parent"
android:layout_width="match_parent"
android:focusable="true"
android:focusableInTouchMode="true"/>
</merge>

View File

@ -1,57 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="fill_parent"
android:layout_height="?android:attr/listPreferredItemHeight"
android:padding="3dp">
<ImageView
android:id="@+id/BrowserItemIcon"
android:layout_width="wrap_content"
android:layout_height="fill_parent"
tools:src="@drawable/ic_launcher"
android:layout_alignParentTop="true"
android:layout_alignParentBottom="true"
android:layout_marginEnd="6dip"/>
<!-- Properties in the 'tools' namespace are only visible in the UI editor, not at runtime. -->
<TextView tools:text="@string/file_size"
android:id="@+id/BrowserItemSubTitle"
android:layout_width="fill_parent"
android:layout_height="26dip"
android:textColor="#bbbbbb"
android:layout_toEndOf="@id/BrowserItemIcon"
android:layout_alignParentBottom="true"
android:layout_alignParentEnd="true"
android:singleLine="true"
android:ellipsize="marquee"
/>
<!-- Properties in the 'tools' namespace are only visible in the UI editor, not at runtime. -->
<TextView tools:text="Name of Game"
android:id="@+id/BrowserItemTitle"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:fontFamily="sans-serif-light"
android:textSize="22sp"
android:textColor="#555555"
android:singleLine="true"
android:ellipsize="end"
android:layout_toEndOf="@id/BrowserItemIcon"
android:layout_alignParentEnd="true"
android:layout_alignParentTop="true"
android:layout_above="@id/BrowserItemSubTitle"
android:layout_alignWithParentIfMissing="true"
android:gravity="center_vertical"
/>
</RelativeLayout>

View File

@ -1,8 +0,0 @@
<ListView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/gamelist"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:choiceMode="singleChoice"
android:dividerHeight="1dp"
tools:listitem="@layout/folderbrowser_list_item"/>

View File

@ -13,7 +13,7 @@
android:focusableInTouchMode="false"/>
<!-- This is the onscreen input overlay -->
<org.dolphinemu.dolphinemu.emulation.overlay.InputOverlay
<org.dolphinemu.dolphinemu.overlay.InputOverlay
android:id="@+id/surface_input_overlay"
android:layout_height="match_parent"
android:layout_width="match_parent"

View File

@ -1,20 +0,0 @@
<android.support.v4.widget.DrawerLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<FrameLayout
android:id="@+id/content_frame"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<ListView
android:id="@+id/left_drawer"
android:layout_width="240dp"
android:layout_height="match_parent"
android:layout_gravity="start"
android:choiceMode="singleChoice"
android:divider="@android:color/transparent"
android:dividerHeight="0dp"
android:background="#333"/>
</android.support.v4.widget.DrawerLayout>

View File

@ -1,57 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="fill_parent"
android:layout_height="?android:attr/listPreferredItemHeight"
android:padding="3dp">
<ImageView
android:id="@+id/GameListItemIcon"
android:layout_width="100dp"
android:layout_height="wrap_content"
tools:src="@drawable/ic_launcher"
android:layout_alignParentTop="true"
android:layout_alignParentBottom="true"
android:layout_marginEnd="6dip"/>
<!-- Properties in the 'tools' namespace are only visible in the UI editor, not at runtime. -->
<TextView tools:text="@string/file_size"
android:id="@+id/GameListItemSubTitle"
android:layout_width="fill_parent"
android:layout_height="26dip"
android:textColor="#bbbbbb"
android:layout_toEndOf="@id/GameListItemIcon"
android:layout_alignParentBottom="true"
android:layout_alignParentEnd="true"
android:singleLine="true"
android:ellipsize="marquee"
/>
<!-- Properties in the 'tools' namespace are only visible in the UI editor, not at runtime. -->
<TextView tools:text="Name of Game"
android:id="@+id/GameListItemTitle"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:fontFamily="sans-serif-light"
android:textSize="22sp"
android:textColor="#555555"
android:singleLine="true"
android:ellipsize="end"
android:layout_toEndOf="@id/GameListItemIcon"
android:layout_alignParentEnd="true"
android:layout_alignParentTop="true"
android:layout_above="@id/GameListItemSubTitle"
android:layout_alignWithParentIfMissing="true"
android:gravity="center_vertical"
/>
</RelativeLayout>

View File

@ -1,8 +0,0 @@
<ListView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/gamelist"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:choiceMode="singleChoice"
android:dividerHeight="1dp"
tools:listitem="@layout/gamelist_list_item"/>

View File

@ -1,20 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="wrap_content"
android:layout_height="48dp"
android:gravity="start"
android:orientation="vertical" >
<TextView
android:id="@+id/SideMenuTitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="4dp"
android:singleLine="true"
tools:text="Menu Option"
android:textAppearance="?android:attr/textAppearanceLarge"
android:fontFamily="sans-serif-light"
android:textColor="#FFFFFF" />
</LinearLayout>

View File

@ -1,15 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.view.ViewPager xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/pager"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v4.view.PagerTabStrip
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="top"
android:paddingBottom="10dp"
android:paddingTop="10dp" />
</android.support.v4.view.ViewPager>

File diff suppressed because it is too large Load Diff

View File

@ -68,102 +68,102 @@
android:key="enableController1"
android:title="@string/enable_controller"/>
<org.dolphinemu.dolphinemu.settings.input.InputBindingPreference
<org.dolphinemu.dolphinemu.utils.InputBindingPreference
android:dependency="enableController1"
android:key="InputA_0"
android:title="@string/button_a"/>
<org.dolphinemu.dolphinemu.settings.input.InputBindingPreference
<org.dolphinemu.dolphinemu.utils.InputBindingPreference
android:dependency="enableController1"
android:key="InputB_0"
android:title="@string/button_b"/>
<org.dolphinemu.dolphinemu.settings.input.InputBindingPreference
<org.dolphinemu.dolphinemu.utils.InputBindingPreference
android:dependency="enableController1"
android:key="InputX_0"
android:title="@string/button_x"/>
<org.dolphinemu.dolphinemu.settings.input.InputBindingPreference
<org.dolphinemu.dolphinemu.utils.InputBindingPreference
android:dependency="enableController1"
android:key="InputY_0"
android:title="@string/button_y"/>
<org.dolphinemu.dolphinemu.settings.input.InputBindingPreference
<org.dolphinemu.dolphinemu.utils.InputBindingPreference
android:dependency="enableController1"
android:key="InputZ_0"
android:title="@string/button_z"/>
<org.dolphinemu.dolphinemu.settings.input.InputBindingPreference
<org.dolphinemu.dolphinemu.utils.InputBindingPreference
android:dependency="enableController1"
android:key="InputStart_0"
android:title="@string/button_start"/>
<org.dolphinemu.dolphinemu.settings.input.InputBindingPreference
<org.dolphinemu.dolphinemu.utils.InputBindingPreference
android:dependency="enableController1"
android:key="DPadUp_0"
android:title="@string/dpad_up"/>
<org.dolphinemu.dolphinemu.settings.input.InputBindingPreference
<org.dolphinemu.dolphinemu.utils.InputBindingPreference
android:dependency="enableController1"
android:key="DPadDown_0"
android:title="@string/dpad_down"/>
<org.dolphinemu.dolphinemu.settings.input.InputBindingPreference
<org.dolphinemu.dolphinemu.utils.InputBindingPreference
android:dependency="enableController1"
android:key="DPadLeft_0"
android:title="@string/dpad_left"/>
<org.dolphinemu.dolphinemu.settings.input.InputBindingPreference
<org.dolphinemu.dolphinemu.utils.InputBindingPreference
android:dependency="enableController1"
android:key="DPadRight_0"
android:title="@string/dpad_right"/>
<org.dolphinemu.dolphinemu.settings.input.InputBindingPreference
<org.dolphinemu.dolphinemu.utils.InputBindingPreference
android:dependency="enableController1"
android:key="MainUp_0"
android:title="@string/main_stick_up"/>
<org.dolphinemu.dolphinemu.settings.input.InputBindingPreference
<org.dolphinemu.dolphinemu.utils.InputBindingPreference
android:dependency="enableController1"
android:key="MainDown_0"
android:title="@string/main_stick_down"/>
<org.dolphinemu.dolphinemu.settings.input.InputBindingPreference
<org.dolphinemu.dolphinemu.utils.InputBindingPreference
android:dependency="enableController1"
android:key="MainLeft_0"
android:title="@string/main_stick_left"/>
<org.dolphinemu.dolphinemu.settings.input.InputBindingPreference
<org.dolphinemu.dolphinemu.utils.InputBindingPreference
android:dependency="enableController1"
android:key="MainRight_0"
android:title="@string/main_stick_right"/>
<org.dolphinemu.dolphinemu.settings.input.InputBindingPreference
<org.dolphinemu.dolphinemu.utils.InputBindingPreference
android:dependency="enableController1"
android:key="CStickUp_0"
android:title="@string/c_stick_up"/>
<org.dolphinemu.dolphinemu.settings.input.InputBindingPreference
<org.dolphinemu.dolphinemu.utils.InputBindingPreference
android:dependency="enableController1"
android:key="CStickDown_0"
android:title="@string/c_stick_down"/>
<org.dolphinemu.dolphinemu.settings.input.InputBindingPreference
<org.dolphinemu.dolphinemu.utils.InputBindingPreference
android:dependency="enableController1"
android:key="CStickLeft_0"
android:title="@string/c_stick_left"/>
<org.dolphinemu.dolphinemu.settings.input.InputBindingPreference
<org.dolphinemu.dolphinemu.utils.InputBindingPreference
android:dependency="enableController1"
android:key="CStickRight_0"
android:title="@string/c_stick_right"/>
<org.dolphinemu.dolphinemu.settings.input.InputBindingPreference
<org.dolphinemu.dolphinemu.utils.InputBindingPreference
android:dependency="enableController1"
android:key="InputL_0"
android:title="@string/trigger_left"/>
<org.dolphinemu.dolphinemu.settings.input.InputBindingPreference
<org.dolphinemu.dolphinemu.utils.InputBindingPreference
android:dependency="enableController1"
android:key="InputR_0"
android:title="@string/trigger_right"/>
@ -178,102 +178,102 @@
android:key="enableController2"
android:title="@string/enable_controller"/>
<org.dolphinemu.dolphinemu.settings.input.InputBindingPreference
<org.dolphinemu.dolphinemu.utils.InputBindingPreference
android:dependency="enableController2"
android:key="InputA_1"
android:title="@string/button_a"/>
<org.dolphinemu.dolphinemu.settings.input.InputBindingPreference
<org.dolphinemu.dolphinemu.utils.InputBindingPreference
android:dependency="enableController2"
android:key="InputB_1"
android:title="@string/button_b"/>
<org.dolphinemu.dolphinemu.settings.input.InputBindingPreference
<org.dolphinemu.dolphinemu.utils.InputBindingPreference
android:dependency="enableController2"
android:key="InputX_1"
android:title="@string/button_x"/>
<org.dolphinemu.dolphinemu.settings.input.InputBindingPreference
<org.dolphinemu.dolphinemu.utils.InputBindingPreference
android:dependency="enableController2"
android:key="InputY_1"
android:title="@string/button_y"/>
<org.dolphinemu.dolphinemu.settings.input.InputBindingPreference
<org.dolphinemu.dolphinemu.utils.InputBindingPreference
android:dependency="enableController2"
android:key="InputZ_1"
android:title="@string/button_z"/>
<org.dolphinemu.dolphinemu.settings.input.InputBindingPreference
<org.dolphinemu.dolphinemu.utils.InputBindingPreference
android:dependency="enableController2"
android:key="InputStart_1"
android:title="@string/button_start"/>
<org.dolphinemu.dolphinemu.settings.input.InputBindingPreference
<org.dolphinemu.dolphinemu.utils.InputBindingPreference
android:dependency="enableController2"
android:key="DPadUp_1"
android:title="@string/dpad_up"/>
<org.dolphinemu.dolphinemu.settings.input.InputBindingPreference
<org.dolphinemu.dolphinemu.utils.InputBindingPreference
android:dependency="enableController2"
android:key="DPadDown_1"
android:title="@string/dpad_down"/>
<org.dolphinemu.dolphinemu.settings.input.InputBindingPreference
<org.dolphinemu.dolphinemu.utils.InputBindingPreference
android:dependency="enableController2"
android:key="DPadLeft_1"
android:title="@string/dpad_left"/>
<org.dolphinemu.dolphinemu.settings.input.InputBindingPreference
<org.dolphinemu.dolphinemu.utils.InputBindingPreference
android:dependency="enableController2"
android:key="DPadRight_1"
android:title="@string/dpad_right"/>
<org.dolphinemu.dolphinemu.settings.input.InputBindingPreference
<org.dolphinemu.dolphinemu.utils.InputBindingPreference
android:dependency="enableController2"
android:key="MainUp_1"
android:title="@string/main_stick_up"/>
<org.dolphinemu.dolphinemu.settings.input.InputBindingPreference
<org.dolphinemu.dolphinemu.utils.InputBindingPreference
android:dependency="enableController2"
android:key="MainDown_1"
android:title="@string/main_stick_down"/>
<org.dolphinemu.dolphinemu.settings.input.InputBindingPreference
<org.dolphinemu.dolphinemu.utils.InputBindingPreference
android:dependency="enableController2"
android:key="MainLeft_1"
android:title="@string/main_stick_left"/>
<org.dolphinemu.dolphinemu.settings.input.InputBindingPreference
<org.dolphinemu.dolphinemu.utils.InputBindingPreference
android:dependency="enableController2"
android:key="MainRight_1"
android:title="@string/main_stick_right"/>
<org.dolphinemu.dolphinemu.settings.input.InputBindingPreference
<org.dolphinemu.dolphinemu.utils.InputBindingPreference
android:dependency="enableController2"
android:key="CStickUp_1"
android:title="@string/c_stick_up"/>
<org.dolphinemu.dolphinemu.settings.input.InputBindingPreference
<org.dolphinemu.dolphinemu.utils.InputBindingPreference
android:dependency="enableController2"
android:key="CStickDown_1"
android:title="@string/c_stick_down"/>
<org.dolphinemu.dolphinemu.settings.input.InputBindingPreference
<org.dolphinemu.dolphinemu.utils.InputBindingPreference
android:dependency="enableController2"
android:key="CStickLeft_1"
android:title="@string/c_stick_left"/>
<org.dolphinemu.dolphinemu.settings.input.InputBindingPreference
<org.dolphinemu.dolphinemu.utils.InputBindingPreference
android:dependency="enableController2"
android:key="CStickRight_1"
android:title="@string/c_stick_right"/>
<org.dolphinemu.dolphinemu.settings.input.InputBindingPreference
<org.dolphinemu.dolphinemu.utils.InputBindingPreference
android:dependency="enableController2"
android:key="InputL_1"
android:title="@string/trigger_left"/>
<org.dolphinemu.dolphinemu.settings.input.InputBindingPreference
<org.dolphinemu.dolphinemu.utils.InputBindingPreference
android:dependency="enableController2"
android:key="InputR_1"
android:title="@string/trigger_right"/>
@ -287,102 +287,102 @@
android:key="enableController3"
android:title="@string/enable_controller"/>
<org.dolphinemu.dolphinemu.settings.input.InputBindingPreference
<org.dolphinemu.dolphinemu.utils.InputBindingPreference
android:dependency="enableController3"
android:key="InputA_2"
android:title="@string/button_a"/>
<org.dolphinemu.dolphinemu.settings.input.InputBindingPreference
<org.dolphinemu.dolphinemu.utils.InputBindingPreference
android:dependency="enableController3"
android:key="InputB_2"
android:title="@string/button_b"/>
<org.dolphinemu.dolphinemu.settings.input.InputBindingPreference
<org.dolphinemu.dolphinemu.utils.InputBindingPreference
android:dependency="enableController3"
android:key="InputX_2"
android:title="@string/button_x"/>
<org.dolphinemu.dolphinemu.settings.input.InputBindingPreference
<org.dolphinemu.dolphinemu.utils.InputBindingPreference
android:dependency="enableController3"
android:key="InputY_2"
android:title="@string/button_y"/>
<org.dolphinemu.dolphinemu.settings.input.InputBindingPreference
<org.dolphinemu.dolphinemu.utils.InputBindingPreference
android:dependency="enableController3"
android:key="InputZ_2"
android:title="@string/button_z"/>
<org.dolphinemu.dolphinemu.settings.input.InputBindingPreference
<org.dolphinemu.dolphinemu.utils.InputBindingPreference
android:dependency="enableController3"
android:key="InputStart_2"
android:title="@string/button_start"/>
<org.dolphinemu.dolphinemu.settings.input.InputBindingPreference
<org.dolphinemu.dolphinemu.utils.InputBindingPreference
android:dependency="enableController3"
android:key="DPadUp_2"
android:title="@string/dpad_up"/>
<org.dolphinemu.dolphinemu.settings.input.InputBindingPreference
<org.dolphinemu.dolphinemu.utils.InputBindingPreference
android:dependency="enableController3"
android:key="DPadDown_2"
android:title="@string/dpad_down"/>
<org.dolphinemu.dolphinemu.settings.input.InputBindingPreference
<org.dolphinemu.dolphinemu.utils.InputBindingPreference
android:dependency="enableController3"
android:key="DPadLeft_2"
android:title="@string/dpad_left"/>
<org.dolphinemu.dolphinemu.settings.input.InputBindingPreference
<org.dolphinemu.dolphinemu.utils.InputBindingPreference
android:dependency="enableController3"
android:key="DPadRight_2"
android:title="@string/dpad_right"/>
<org.dolphinemu.dolphinemu.settings.input.InputBindingPreference
<org.dolphinemu.dolphinemu.utils.InputBindingPreference
android:dependency="enableController3"
android:key="MainUp_2"
android:title="@string/main_stick_up"/>
<org.dolphinemu.dolphinemu.settings.input.InputBindingPreference
<org.dolphinemu.dolphinemu.utils.InputBindingPreference
android:dependency="enableController3"
android:key="MainDown_2"
android:title="@string/main_stick_down"/>
<org.dolphinemu.dolphinemu.settings.input.InputBindingPreference
<org.dolphinemu.dolphinemu.utils.InputBindingPreference
android:dependency="enableController3"
android:key="MainLeft_2"
android:title="@string/main_stick_left"/>
<org.dolphinemu.dolphinemu.settings.input.InputBindingPreference
<org.dolphinemu.dolphinemu.utils.InputBindingPreference
android:dependency="enableController3"
android:key="MainRight_2"
android:title="@string/main_stick_right"/>
<org.dolphinemu.dolphinemu.settings.input.InputBindingPreference
<org.dolphinemu.dolphinemu.utils.InputBindingPreference
android:dependency="enableController3"
android:key="CStickUp_2"
android:title="@string/c_stick_up"/>
<org.dolphinemu.dolphinemu.settings.input.InputBindingPreference
<org.dolphinemu.dolphinemu.utils.InputBindingPreference
android:dependency="enableController3"
android:key="CStickDown_2"
android:title="@string/c_stick_down"/>
<org.dolphinemu.dolphinemu.settings.input.InputBindingPreference
<org.dolphinemu.dolphinemu.utils.InputBindingPreference
android:dependency="enableController3"
android:key="CStickLeft_2"
android:title="@string/c_stick_left"/>
<org.dolphinemu.dolphinemu.settings.input.InputBindingPreference
<org.dolphinemu.dolphinemu.utils.InputBindingPreference
android:dependency="enableController3"
android:key="CStickRight_2"
android:title="@string/c_stick_right"/>
<org.dolphinemu.dolphinemu.settings.input.InputBindingPreference
<org.dolphinemu.dolphinemu.utils.InputBindingPreference
android:dependency="enableController3"
android:key="InputL_2"
android:title="@string/trigger_left"/>
<org.dolphinemu.dolphinemu.settings.input.InputBindingPreference
<org.dolphinemu.dolphinemu.utils.InputBindingPreference
android:dependency="enableController3"
android:key="InputR_2"
android:title="@string/trigger_right"/>
@ -397,102 +397,102 @@
android:key="enableController4"
android:title="@string/enable_controller"/>
<org.dolphinemu.dolphinemu.settings.input.InputBindingPreference
<org.dolphinemu.dolphinemu.utils.InputBindingPreference
android:dependency="enableController4"
android:key="InputA_3"
android:title="@string/button_a"/>
<org.dolphinemu.dolphinemu.settings.input.InputBindingPreference
<org.dolphinemu.dolphinemu.utils.InputBindingPreference
android:dependency="enableController4"
android:key="InputB_3"
android:title="@string/button_b"/>
<org.dolphinemu.dolphinemu.settings.input.InputBindingPreference
<org.dolphinemu.dolphinemu.utils.InputBindingPreference
android:dependency="enableController4"
android:key="InputX_3"
android:title="@string/button_x"/>
<org.dolphinemu.dolphinemu.settings.input.InputBindingPreference
<org.dolphinemu.dolphinemu.utils.InputBindingPreference
android:dependency="enableController4"
android:key="InputY_3"
android:title="@string/button_y"/>
<org.dolphinemu.dolphinemu.settings.input.InputBindingPreference
<org.dolphinemu.dolphinemu.utils.InputBindingPreference
android:dependency="enableController4"
android:key="InputZ_3"
android:title="@string/button_z"/>
<org.dolphinemu.dolphinemu.settings.input.InputBindingPreference
<org.dolphinemu.dolphinemu.utils.InputBindingPreference
android:dependency="enableController4"
android:key="InputStart_3"
android:title="@string/button_start"/>
<org.dolphinemu.dolphinemu.settings.input.InputBindingPreference
<org.dolphinemu.dolphinemu.utils.InputBindingPreference
android:dependency="enableController4"
android:key="DPadUp_3"
android:title="@string/dpad_up"/>
<org.dolphinemu.dolphinemu.settings.input.InputBindingPreference
<org.dolphinemu.dolphinemu.utils.InputBindingPreference
android:dependency="enableController4"
android:key="DPadDown_3"
android:title="@string/dpad_down"/>
<org.dolphinemu.dolphinemu.settings.input.InputBindingPreference
<org.dolphinemu.dolphinemu.utils.InputBindingPreference
android:dependency="enableController4"
android:key="DPadLeft_3"
android:title="@string/dpad_left"/>
<org.dolphinemu.dolphinemu.settings.input.InputBindingPreference
<org.dolphinemu.dolphinemu.utils.InputBindingPreference
android:dependency="enableController4"
android:key="DPadRight_3"
android:title="@string/dpad_right"/>
<org.dolphinemu.dolphinemu.settings.input.InputBindingPreference
<org.dolphinemu.dolphinemu.utils.InputBindingPreference
android:dependency="enableController4"
android:key="MainUp_3"
android:title="@string/main_stick_up"/>
<org.dolphinemu.dolphinemu.settings.input.InputBindingPreference
<org.dolphinemu.dolphinemu.utils.InputBindingPreference
android:dependency="enableController4"
android:key="MainDown_3"
android:title="@string/main_stick_down"/>
<org.dolphinemu.dolphinemu.settings.input.InputBindingPreference
<org.dolphinemu.dolphinemu.utils.InputBindingPreference
android:dependency="enableController4"
android:key="MainLeft_3"
android:title="@string/main_stick_left"/>
<org.dolphinemu.dolphinemu.settings.input.InputBindingPreference
<org.dolphinemu.dolphinemu.utils.InputBindingPreference
android:dependency="enableController4"
android:key="MainRight_3"
android:title="@string/main_stick_right"/>
<org.dolphinemu.dolphinemu.settings.input.InputBindingPreference
<org.dolphinemu.dolphinemu.utils.InputBindingPreference
android:dependency="enableController4"
android:key="CStickUp_3"
android:title="@string/c_stick_up"/>
<org.dolphinemu.dolphinemu.settings.input.InputBindingPreference
<org.dolphinemu.dolphinemu.utils.InputBindingPreference
android:dependency="enableController4"
android:key="CStickDown_3"
android:title="@string/c_stick_down"/>
<org.dolphinemu.dolphinemu.settings.input.InputBindingPreference
<org.dolphinemu.dolphinemu.utils.InputBindingPreference
android:dependency="enableController4"
android:key="CStickLeft_3"
android:title="@string/c_stick_left"/>
<org.dolphinemu.dolphinemu.settings.input.InputBindingPreference
<org.dolphinemu.dolphinemu.utils.InputBindingPreference
android:dependency="enableController4"
android:key="CStickRight_3"
android:title="@string/c_stick_right"/>
<org.dolphinemu.dolphinemu.settings.input.InputBindingPreference
<org.dolphinemu.dolphinemu.utils.InputBindingPreference
android:dependency="enableController4"
android:key="InputL_3"
android:title="@string/trigger_left"/>
<org.dolphinemu.dolphinemu.settings.input.InputBindingPreference
<org.dolphinemu.dolphinemu.utils.InputBindingPreference
android:dependency="enableController4"
android:key="InputR_3"
android:title="@string/trigger_right"/>