summaryrefslogtreecommitdiff
path: root/Source/Android
diff options
context:
space:
mode:
authorLinktothepast <kostamarino@gmail.com>2015-09-28 16:50:35 +0300
committerLinktothepast <kostamarino@gmail.com>2015-09-28 16:50:35 +0300
commit748be565b8df535ef558e74b38cd0f4d615f8a21 (patch)
treeb151efee0a87e99125f2401325a9bddecf84fc73 /Source/Android
parentcf17fccdd3093a1b8476b10183b1c4bde36da74d (diff)
parentce493b897d6d3735c930a8465cc0c26bbe5feb86 (diff)
Merge remote-tracking branch 'dolphin-emu/master' into gameinis
Diffstat (limited to 'Source/Android')
-rw-r--r--Source/Android/.gitignore1
-rw-r--r--Source/Android/app/build.gradle31
-rw-r--r--Source/Android/app/src/arm_64/res/values/arrays.xml2
-rw-r--r--Source/Android/app/src/main/AndroidManifest.xml13
-rw-r--r--Source/Android/app/src/main/assets/WiimoteNew.ini84
-rw-r--r--Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/NativeLibrary.java57
-rw-r--r--Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/activities/EmulationActivity.java459
-rw-r--r--Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/activities/MainActivity.java36
-rw-r--r--Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/activities/TvMainActivity.java290
-rw-r--r--Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/adapters/GameAdapter.java21
-rw-r--r--Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/adapters/GameRowPresenter.java118
-rw-r--r--Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/adapters/SettingsRowPresenter.java47
-rw-r--r--Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/fragments/EmulationFragment.java7
-rw-r--r--Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/fragments/LoadStateFragment.java55
-rw-r--r--Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/fragments/MenuFragment.java52
-rw-r--r--Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/fragments/PlatformGamesFragment.java16
-rw-r--r--Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/fragments/SaveStateFragment.java55
-rw-r--r--Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/model/Game.java34
-rw-r--r--Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/model/TvSettingsItem.java31
-rw-r--r--Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/services/AssetCopyService.java1
-rw-r--r--Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/utils/UserPreferences.java31
-rw-r--r--Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/viewholders/TvGameViewHolder.java39
-rw-r--r--Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/viewholders/TvSettingsViewHolder.java23
-rw-r--r--Source/Android/app/src/main/res/animator/menu_slide_in.xml17
-rw-r--r--Source/Android/app/src/main/res/animator/menu_slide_out.xml18
-rw-r--r--Source/Android/app/src/main/res/drawable/ic_add_tv.pngbin0 -> 1708 bytes
-rw-r--r--Source/Android/app/src/main/res/drawable/ic_refresh_tv.pngbin0 -> 1969 bytes
-rw-r--r--Source/Android/app/src/main/res/drawable/ic_settings_tv.pngbin0 -> 2248 bytes
-rw-r--r--Source/Android/app/src/main/res/layout-television/activity_emulation.xml44
-rw-r--r--Source/Android/app/src/main/res/layout-television/fragment_emulation.xml14
-rw-r--r--Source/Android/app/src/main/res/layout/activity_emulation.xml16
-rw-r--r--Source/Android/app/src/main/res/layout/activity_main.xml3
-rw-r--r--Source/Android/app/src/main/res/layout/activity_tv_main.xml13
-rw-r--r--Source/Android/app/src/main/res/layout/card_game.xml3
-rw-r--r--Source/Android/app/src/main/res/layout/fragment_ingame_menu.xml69
-rw-r--r--Source/Android/app/src/main/res/layout/fragment_state_load.xml65
-rw-r--r--Source/Android/app/src/main/res/layout/fragment_state_save.xml65
-rw-r--r--Source/Android/app/src/main/res/transition/change_image_transform.xml4
-rw-r--r--Source/Android/app/src/main/res/values-ja/strings.xml20
-rw-r--r--Source/Android/app/src/main/res/values/arrays.xml2
-rw-r--r--Source/Android/app/src/main/res/values/colors.xml2
-rw-r--r--Source/Android/app/src/main/res/values/strings.xml10
-rw-r--r--Source/Android/app/src/main/res/values/styles.xml69
-rw-r--r--Source/Android/app/src/main/res/xml/preferences.xml327
-rw-r--r--Source/Android/gradle/wrapper/gradle-wrapper.jarbin0 -> 49896 bytes
-rw-r--r--Source/Android/gradle/wrapper/gradle-wrapper.properties6
46 files changed, 2081 insertions, 189 deletions
diff --git a/Source/Android/.gitignore b/Source/Android/.gitignore
index a053548512..3fbf1ea2ff 100644
--- a/Source/Android/.gitignore
+++ b/Source/Android/.gitignore
@@ -36,7 +36,6 @@ workspace.xml
tasks.xml
.gradle/*
.idea
-gradle/
build/
*.so
*.iml
diff --git a/Source/Android/app/build.gradle b/Source/Android/app/build.gradle
index b936e0604d..62588307e0 100644
--- a/Source/Android/app/build.gradle
+++ b/Source/Android/app/build.gradle
@@ -1,7 +1,8 @@
apply plugin: 'com.android.application'
android {
- compileSdkVersion 21
+ // Leanback support requires >22
+ compileSdkVersion 22
buildToolsVersion "22.0.1"
lintOptions {
@@ -75,10 +76,13 @@ android {
}
dependencies {
- compile 'com.android.support:support-v13:22.2.0'
- compile 'com.android.support:cardview-v7:22.2.0'
- compile 'com.android.support:recyclerview-v7:22.2.0'
- compile 'com.android.support:design:22.2.0'
+ compile 'com.android.support:support-v13:22.2.1'
+ compile 'com.android.support:cardview-v7:22.2.1'
+ compile 'com.android.support:recyclerview-v7:22.2.1'
+ compile 'com.android.support:design:22.2.1'
+
+ // Android TV UI libraries.
+ compile 'com.android.support:leanback-v17:22.2.1'
// For showing the banner as a circle a-la Material Design Guidelines
compile 'de.hdodenhof:circleimageview:1.2.2'
@@ -134,7 +138,11 @@ task compileNative(type: Exec, dependsOn: 'setupCMake') {
executable 'make'
- args buildProperties.makeArgs
+ if (buildProperties.makeArgs == null || buildProperties.makeArgs.isEmpty()) {
+ // TODO
+ } else {
+ args buildProperties.makeArgs
+ }
} else {
executable 'echo'
args 'No build.properties found; skipping native build.'
@@ -144,13 +152,15 @@ task compileNative(type: Exec, dependsOn: 'setupCMake') {
String getExecutablePath(String command) {
def propsFile = rootProject.file("build.properties")
def path = null
+
if (propsFile.canRead()) {
def buildProperties = new Properties()
buildProperties.load(new FileInputStream(propsFile))
println buildProperties
path = buildProperties[command + "Path"]
}
- if (path == null) {
+
+ if (path == null || path.isEmpty()) {
try {
def stdout = new ByteArrayOutputStream()
@@ -164,21 +174,25 @@ String getExecutablePath(String command) {
project.logger.error("Gradle error: Couldn't find " + command + " executable.")
}
}
+
if (path != null) {
project.logger.quiet("Gradle: Found " + command + " executuable:" + path)
}
+
return path
}
String getNdkPath() {
def propsFile = rootProject.file("build.properties")
def ndkPath = null
+
if (propsFile.canRead()) {
def buildProperties = new Properties()
buildProperties.load(new FileInputStream(propsFile))
ndkPath = buildProperties.ndkPath
}
- if (ndkPath == null) {
+
+ if (ndkPath == null || ndkPath.isEmpty()) {
try {
def stdout = new ByteArrayOutputStream()
@@ -194,6 +208,7 @@ String getNdkPath() {
project.logger.error("Gradle error: Couldn't find NDK.")
}
}
+
if (ndkPath != null) {
project.logger.quiet("Gradle: Found Android NDK: " + ndkPath)
}
diff --git a/Source/Android/app/src/arm_64/res/values/arrays.xml b/Source/Android/app/src/arm_64/res/values/arrays.xml
index 12ed1695da..8f2ed0edff 100644
--- a/Source/Android/app/src/arm_64/res/values/arrays.xml
+++ b/Source/Android/app/src/arm_64/res/values/arrays.xml
@@ -6,10 +6,12 @@
<!-- New UI CPU Core selection - ARM64 -->
<string-array name="string_emu_cores" translatable="false">
<item>@string/interpreter</item>
+ <item>@string/cached_interpreter</item>
<item>@string/jit_arm64_recompiler</item>
</string-array>
<string-array name="int_emu_cores" translatable="false">
<item>0</item>
+ <item>5</item>
<item>4</item>
</string-array>
diff --git a/Source/Android/app/src/main/AndroidManifest.xml b/Source/Android/app/src/main/AndroidManifest.xml
index 30fffd11e9..e08b2dd0a8 100644
--- a/Source/Android/app/src/main/AndroidManifest.xml
+++ b/Source/Android/app/src/main/AndroidManifest.xml
@@ -33,12 +33,23 @@
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
- <category android:name="android.intent.category.LEANBACK_LAUNCHER"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
<activity
+ android:name=".activities.TvMainActivity"
+ android:theme="@style/DolphinTvGamecube">
+
+ <!-- This intentfilter marks this Activity as the one that gets launched from Home screen. -->
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN"/>
+
+ <category android:name="android.intent.category.LEANBACK_LAUNCHER"/>
+ </intent-filter>
+ </activity>
+
+ <activity
android:name=".activities.AddDirectoryActivity"
android:theme="@style/DolphinGamecube"
android:label="@string/add_directory_title"/>
diff --git a/Source/Android/app/src/main/assets/WiimoteNew.ini b/Source/Android/app/src/main/assets/WiimoteNew.ini
new file mode 100644
index 0000000000..41082fd8de
--- /dev/null
+++ b/Source/Android/app/src/main/assets/WiimoteNew.ini
@@ -0,0 +1,84 @@
+[Wiimote1]
+Device = Android/4/Touchscreen
+Buttons/A = `Button 22`
+Buttons/B = `Button 23`
+Buttons/1 = `Button 27`
+Buttons/2 = `Button 28`
+Buttons/- = `Button 24`
+Buttons/+ = `Button 25`
+Buttons/Home = `Button 26`
+IR/Up =
+IR/Down =
+IR/Left =
+IR/Right =
+Shake/X =
+Shake/Y =
+Shake/Z =
+D-Pad/Up = `Button 29`
+D-Pad/Down = `Button 30`
+D-Pad/Left = `Button 31`
+D-Pad/Right = `Button 32`
+Source = 1
+[Wiimote2]
+Device = Android/5/Touchscreen
+Buttons/A = `Button 22`
+Buttons/B = `Button 23`
+Buttons/1 = `Button 27`
+Buttons/2 = `Button 28`
+Buttons/- = `Button 24`
+Buttons/+ = `Button 25`
+Buttons/Home = `Button 26`
+IR/Up =
+IR/Down =
+IR/Left =
+IR/Right =
+Shake/X =
+Shake/Y =
+Shake/Z =
+D-Pad/Up = `Button 29`
+D-Pad/Down = `Button 30`
+D-Pad/Left = `Button 31`
+D-Pad/Right = `Button 32`
+Source = 1
+[Wiimote3]
+Device = Android/6/Touchscreen
+Buttons/A = `Button 22`
+Buttons/B = `Button 23`
+Buttons/1 = `Button 27`
+Buttons/2 = `Button 28`
+Buttons/- = `Button 24`
+Buttons/+ = `Button 25`
+Buttons/Home = `Button 26`
+IR/Up =
+IR/Down =
+IR/Left =
+IR/Right =
+Shake/X =
+Shake/Y =
+Shake/Z =
+D-Pad/Up = `Button 29`
+D-Pad/Down = `Button 30`
+D-Pad/Left = `Button 31`
+D-Pad/Right = `Button 32`
+Source = 1
+[Wiimote4]
+Device = Android/7/Touchscreen
+Buttons/A = `Button 22`
+Buttons/B = `Button 23`
+Buttons/1 = `Button 27`
+Buttons/2 = `Button 28`
+Buttons/- = `Button 24`
+Buttons/+ = `Button 25`
+Buttons/Home = `Button 26`
+IR/Up =
+IR/Down =
+IR/Left =
+IR/Right =
+Shake/X =
+Shake/Y =
+Shake/Z =
+D-Pad/Up = `Button 29`
+D-Pad/Down = `Button 30`
+D-Pad/Left = `Button 31`
+D-Pad/Right = `Button 32`
+Source = 1
diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/NativeLibrary.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/NativeLibrary.java
index c9efb0c790..db387344bd 100644
--- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/NativeLibrary.java
+++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/NativeLibrary.java
@@ -25,28 +25,39 @@ public final class NativeLibrary
*/
public static final class ButtonType
{
- public static final int BUTTON_A = 0;
- public static final int BUTTON_B = 1;
- public static final int BUTTON_START = 2;
- public static final int BUTTON_X = 3;
- public static final int BUTTON_Y = 4;
- public static final int BUTTON_Z = 5;
- public static final int BUTTON_UP = 6;
- public static final int BUTTON_DOWN = 7;
- public static final int BUTTON_LEFT = 8;
- public static final int BUTTON_RIGHT = 9;
- public static final int STICK_MAIN = 10;
- public static final int STICK_MAIN_UP = 11;
- public static final int STICK_MAIN_DOWN = 12;
- public static final int STICK_MAIN_LEFT = 13;
- public static final int STICK_MAIN_RIGHT = 14;
- public static final int STICK_C = 15;
- public static final int STICK_C_UP = 16;
- public static final int STICK_C_DOWN = 17;
- public static final int STICK_C_LEFT = 18;
- public static final int STICK_C_RIGHT = 19;
- public static final int TRIGGER_L = 20;
- public static final int TRIGGER_R = 21;
+ public static final int BUTTON_A = 0;
+ public static final int BUTTON_B = 1;
+ public static final int BUTTON_START = 2;
+ public static final int BUTTON_X = 3;
+ public static final int BUTTON_Y = 4;
+ public static final int BUTTON_Z = 5;
+ public static final int BUTTON_UP = 6;
+ public static final int BUTTON_DOWN = 7;
+ public static final int BUTTON_LEFT = 8;
+ public static final int BUTTON_RIGHT = 9;
+ public static final int STICK_MAIN = 10;
+ public static final int STICK_MAIN_UP = 11;
+ public static final int STICK_MAIN_DOWN = 12;
+ public static final int STICK_MAIN_LEFT = 13;
+ public static final int STICK_MAIN_RIGHT = 14;
+ public static final int STICK_C = 15;
+ public static final int STICK_C_UP = 16;
+ public static final int STICK_C_DOWN = 17;
+ public static final int STICK_C_LEFT = 18;
+ public static final int STICK_C_RIGHT = 19;
+ public static final int TRIGGER_L = 20;
+ public static final int TRIGGER_R = 21;
+ public static final int WIIMOTE_BUTTON_A = 22;
+ public static final int WIIMOTE_BUTTON_B = 23;
+ public static final int WIIMOTE_BUTTON_MINUS = 24;
+ public static final int WIIMOTE_BUTTON_PLUS = 25;
+ public static final int WIIMOTE_BUTTON_HOME = 26;
+ public static final int WIIMOTE_BUTTON_1 = 27;
+ public static final int WIIMOTE_BUTTON_2 = 28;
+ public static final int WIIMOTE_UP = 29;
+ public static final int WIIMOTE_DOWN = 30;
+ public static final int WIIMOTE_LEFT = 31;
+ public static final int WIIMOTE_RIGHT = 32;
}
/**
@@ -277,7 +288,7 @@ public final class NativeLibrary
public static void endEmulationActivity()
{
Log.v("DolphinEmu", "Ending EmulationActivity.");
- mEmulationActivity.finish();
+ mEmulationActivity.exitWithAnimation();
}
public static void setEmulationActivity(EmulationActivity emulationActivity)
diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/activities/EmulationActivity.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/activities/EmulationActivity.java
index d1e6f47273..04b5149a0e 100644
--- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/activities/EmulationActivity.java
+++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/activities/EmulationActivity.java
@@ -1,5 +1,6 @@
package org.dolphinemu.dolphinemu.activities;
+import android.app.Fragment;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
@@ -12,19 +13,45 @@ import android.view.Menu;
import android.view.MenuItem;
import android.view.MotionEvent;
import android.view.View;
+import android.view.ViewTreeObserver;
+import android.view.animation.AccelerateInterpolator;
+import android.view.animation.DecelerateInterpolator;
+import android.view.animation.Interpolator;
+import android.widget.FrameLayout;
+import android.widget.ImageView;
+import android.widget.LinearLayout;
+
+import com.squareup.picasso.Callback;
+import com.squareup.picasso.Picasso;
import org.dolphinemu.dolphinemu.NativeLibrary;
import org.dolphinemu.dolphinemu.R;
import org.dolphinemu.dolphinemu.fragments.EmulationFragment;
+import org.dolphinemu.dolphinemu.fragments.LoadStateFragment;
+import org.dolphinemu.dolphinemu.fragments.MenuFragment;
+import org.dolphinemu.dolphinemu.fragments.SaveStateFragment;
import java.util.List;
public final class EmulationActivity extends AppCompatActivity
{
private View mDecorView;
+ private ImageView mImageView;
+
+ private FrameLayout mFrameEmulation;
+ private LinearLayout mMenuLayout;
+
+ private String mSubmenuFragmentTag;
+
+ // So that MainActivity knows which view to invalidate before the return animation.
+ private int mPosition;
private boolean mDeviceHasTouchScreen;
private boolean mSystemUiVisible;
+ private boolean mMenuVisible;
+
+ private static final Interpolator sDecelerator = new DecelerateInterpolator();
+ private static final Interpolator sAccelerator = new AccelerateInterpolator();
/**
* Handlers are a way to pass a message to an Activity telling it to do something
@@ -39,59 +66,139 @@ public final class EmulationActivity extends AppCompatActivity
hideSystemUI();
}
};
+ private String mScreenPath;
+ private FrameLayout mFrameContent;
+ private String mSelectedTitle;
@Override
protected void onCreate(Bundle savedInstanceState)
{
- super.onCreate(savedInstanceState);
-
mDeviceHasTouchScreen = getPackageManager().hasSystemFeature("android.hardware.touchscreen");
- // Get a handle to the Window containing the UI.
- mDecorView = getWindow().getDecorView();
+ int themeId;
+ if (mDeviceHasTouchScreen)
+ {
+ themeId = R.style.DolphinEmulationGamecube;
- // Set these options now so that the SurfaceView the game renders into is the right size.
- mDecorView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE |
- View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION |
- View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN);
+ // Get a handle to the Window containing the UI.
+ mDecorView = getWindow().getDecorView();
- // Set the ActionBar to follow the navigation/status bar's visibility changes.
- mDecorView.setOnSystemUiVisibilityChangeListener(
- new View.OnSystemUiVisibilityChangeListener()
- {
- @Override
- public void onSystemUiVisibilityChange(int flags)
- {
- mSystemUiVisible = (flags & View.SYSTEM_UI_FLAG_HIDE_NAVIGATION) == 0;
+ // Set these options now so that the SurfaceView the game renders into is the right size.
+ mDecorView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE |
+ View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION |
+ View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN);
- if (mSystemUiVisible)
- {
- getSupportActionBar().show();
- hideSystemUiAfterDelay();
- }
- else
+ // Set the ActionBar to follow the navigation/status bar's visibility changes.
+ mDecorView.setOnSystemUiVisibilityChangeListener(
+ new View.OnSystemUiVisibilityChangeListener()
+ {
+ @Override
+ public void onSystemUiVisibilityChange(int flags)
{
- getSupportActionBar().hide();
+ mSystemUiVisible = (flags & View.SYSTEM_UI_FLAG_HIDE_NAVIGATION) == 0;
+
+ if (mSystemUiVisible)
+ {
+ getSupportActionBar().show();
+ hideSystemUiAfterDelay();
+ }
+ else
+ {
+ getSupportActionBar().hide();
+ }
}
}
- }
- );
+ );
+ }
+ else
+ {
+ themeId = R.style.DolphinEmulationTvGamecube;
+ }
+
+ setTheme(themeId);
+ super.onCreate(savedInstanceState);
+
+ // Picasso will take a while to load these big-ass screenshots. So don't run
+ // the animation until we say so.
+ postponeEnterTransition();
setContentView(R.layout.activity_emulation);
+ mImageView = (ImageView) findViewById(R.id.image_screenshot);
+ mFrameContent = (FrameLayout) findViewById(R.id.frame_content);
+ mFrameEmulation = (FrameLayout) findViewById(R.id.frame_emulation_fragment);
+ mMenuLayout = (LinearLayout) findViewById(R.id.layout_ingame_menu);
+
Intent gameToEmulate = getIntent();
String path = gameToEmulate.getStringExtra("SelectedGame");
- String title = gameToEmulate.getStringExtra("SelectedTitle");
+ mSelectedTitle = gameToEmulate.getStringExtra("SelectedTitle");
+ mScreenPath = gameToEmulate.getStringExtra("ScreenPath");
+ mPosition = gameToEmulate.getIntExtra("GridPosition", -1);
+
+ Picasso.with(this)
+ .load(mScreenPath)
+ .noFade()
+ .noPlaceholder()
+ .into(mImageView, new Callback()
+ {
+ @Override
+ public void onSuccess()
+ {
+ scheduleStartPostponedTransition(mImageView);
+ }
- setTitle(title);
+ @Override
+ public void onError()
+ {
+ // Still have to do this, or else the app will crash.
+ scheduleStartPostponedTransition(mImageView);
+ }
+ });
+
+ mImageView.animate()
+ .withLayer()
+ .setStartDelay(2000)
+ .setDuration(500)
+ .alpha(0.0f)
+ .withStartAction(new Runnable()
+ {
+ @Override
+ public void run()
+ {
+ mFrameEmulation.setVisibility(View.VISIBLE);
+ }
+ })
+ .withEndAction(new Runnable()
+ {
+ @Override
+ public void run()
+ {
+ mImageView.setVisibility(View.GONE);
+ }
+ });
// Instantiate an EmulationFragment.
EmulationFragment emulationFragment = EmulationFragment.newInstance(path);
// Add fragment to the activity - this triggers all its lifecycle callbacks.
getFragmentManager().beginTransaction()
- .add(R.id.frame_content, emulationFragment, EmulationFragment.FRAGMENT_TAG)
+ .add(R.id.frame_emulation_fragment, emulationFragment, EmulationFragment.FRAGMENT_TAG)
.commit();
+
+ if (mDeviceHasTouchScreen)
+ {
+ setTitle(mSelectedTitle);
+ }
+ else
+ {
+ MenuFragment menuFragment = (MenuFragment) getFragmentManager()
+ .findFragmentById(R.id.fragment_menu);
+
+ if (menuFragment != null)
+ {
+ menuFragment.setTitleText(mSelectedTitle);
+ }
+ }
}
@Override
@@ -116,8 +223,11 @@ public final class EmulationActivity extends AppCompatActivity
{
super.onPostCreate(savedInstanceState);
- // Give the user a few seconds to see what the controls look like, then hide them.
- hideSystemUiAfterDelay();
+ if (mDeviceHasTouchScreen)
+ {
+ // Give the user a few seconds to see what the controls look like, then hide them.
+ hideSystemUiAfterDelay();
+ }
}
@Override
@@ -125,36 +235,144 @@ public final class EmulationActivity extends AppCompatActivity
{
super.onWindowFocusChanged(hasFocus);
- if (hasFocus)
+ if (mDeviceHasTouchScreen)
{
- hideSystemUiAfterDelay();
- }
- else
- {
- // If the window loses focus (i.e. a dialog box, or a popup menu is on screen
- // stop hiding the UI.
- mSystemUiHider.removeMessages(0);
+ if (hasFocus)
+ {
+ hideSystemUiAfterDelay();
+ }
+ else
+ {
+ // If the window loses focus (i.e. a dialog box, or a popup menu is on screen
+ // stop hiding the UI.
+ mSystemUiHider.removeMessages(0);
+ }
}
}
@Override
public void onBackPressed()
{
- if (!mDeviceHasTouchScreen && !mSystemUiVisible)
+ if (!mDeviceHasTouchScreen)
{
- showSystemUI();
+ if (mSubmenuFragmentTag != null)
+ {
+ removeMenu();
+ }
+ else
+ {
+ toggleMenu();
+ }
}
else
{
- // Let the system handle it; i.e. quit the activity TODO or show "are you sure?" dialog.
- EmulationFragment fragment = (EmulationFragment) getFragmentManager()
- .findFragmentByTag(EmulationFragment.FRAGMENT_TAG);
- fragment.notifyEmulationStopped();
+ stopEmulation();
+ }
+ }
- NativeLibrary.StopEmulation();
+ private void toggleMenu()
+ {
+ if (mMenuVisible)
+ {
+ mMenuVisible = false;
+
+ mMenuLayout.animate()
+ .withLayer()
+ .setDuration(200)
+ .setInterpolator(sAccelerator)
+ .alpha(0.0f)
+ .translationX(-400.0f)
+ .withEndAction(new Runnable()
+ {
+ @Override
+ public void run()
+ {
+ if (mMenuVisible)
+ {
+ mMenuLayout.setVisibility(View.GONE);
+ }
+ }
+ });
}
+ else
+ {
+ mMenuVisible = true;
+ mMenuLayout.setVisibility(View.VISIBLE);
+
+// mMenuLayout.setTranslationX(-400.0f);
+ mMenuLayout.setAlpha(0.0f);
+
+ mMenuLayout.animate()
+ .withLayer()
+ .setDuration(300)
+ .setInterpolator(sDecelerator)
+ .alpha(1.0f)
+ .translationX(0.0f);
+ }
+ }
+
+ private void stopEmulation()
+ {
+ EmulationFragment fragment = (EmulationFragment) getFragmentManager()
+ .findFragmentByTag(EmulationFragment.FRAGMENT_TAG);
+ fragment.notifyEmulationStopped();
+
+ NativeLibrary.StopEmulation();
}
+ public void exitWithAnimation()
+ {
+ runOnUiThread(new Runnable()
+ {
+ @Override
+ public void run()
+ {
+ Picasso.with(EmulationActivity.this)
+ .invalidate(mScreenPath);
+
+ Picasso.with(EmulationActivity.this)
+ .load(mScreenPath)
+ .noFade()
+ .noPlaceholder()
+ .into(mImageView, new Callback()
+ {
+ @Override
+ public void onSuccess()
+ {
+ showScreenshot();
+ }
+
+ @Override
+ public void onError()
+ {
+ finish();
+ }
+ });
+ }
+ });
+ }
+
+ private void showScreenshot()
+ {
+ mImageView.setVisibility(View.VISIBLE);
+ mImageView.animate()
+ .withLayer()
+ .setDuration(100)
+ .alpha(1.0f)
+ .withEndAction(afterShowingScreenshot);
+ }
+
+ private Runnable afterShowingScreenshot = new Runnable()
+ {
+ @Override
+ public void run()
+ {
+ mFrameContent.removeView(mFrameEmulation);
+ setResult(mPosition);
+ finishAfterTransition();
+ }
+ };
+
@Override
public boolean onCreateOptionsMenu(Menu menu)
{
@@ -166,7 +384,13 @@ public final class EmulationActivity extends AppCompatActivity
@Override
public boolean onOptionsItemSelected(MenuItem item)
{
- switch (item.getItemId())
+ onMenuItemClicked(item.getItemId());
+ return true;
+ }
+
+ public void onMenuItemClicked(int id)
+ {
+ switch (id)
{
// Enable/Disable input overlay.
case R.id.menu_emulation_input_overlay:
@@ -176,67 +400,78 @@ public final class EmulationActivity extends AppCompatActivity
emulationFragment.toggleInputOverlayVisibility();
- return true;
+ return;
}
// Screenshot capturing
case R.id.menu_emulation_screenshot:
NativeLibrary.SaveScreenShot();
- return true;
+ return;
// Quicksave / Load
case R.id.menu_quicksave:
NativeLibrary.SaveState(9);
- return true;
+ return;
case R.id.menu_quickload:
NativeLibrary.LoadState(9);
- return true;
+ return;
+
+ // TV Menu only
+ case R.id.menu_emulation_save_root:
+ showMenu(SaveStateFragment.FRAGMENT_ID);
+ return;
+
+ case R.id.menu_emulation_load_root:
+ showMenu(LoadStateFragment.FRAGMENT_ID);
+ return;
// Save state slots
case R.id.menu_emulation_save_1:
NativeLibrary.SaveState(0);
- return true;
+ return;
case R.id.menu_emulation_save_2:
NativeLibrary.SaveState(1);
- return true;
+ return;
case R.id.menu_emulation_save_3:
NativeLibrary.SaveState(2);
- return true;
+ return;
case R.id.menu_emulation_save_4:
NativeLibrary.SaveState(3);
- return true;
+ return;
case R.id.menu_emulation_save_5:
NativeLibrary.SaveState(4);
- return true;
+ return;
// Load state slots
case R.id.menu_emulation_load_1:
NativeLibrary.LoadState(0);
- return true;
+ return;
case R.id.menu_emulation_load_2:
NativeLibrary.LoadState(1);
- return true;
+ return;
case R.id.menu_emulation_load_3:
NativeLibrary.LoadState(2);
- return true;
+ return;
case R.id.menu_emulation_load_4:
NativeLibrary.LoadState(3);
- return true;
+ return;
case R.id.menu_emulation_load_5:
NativeLibrary.LoadState(4);
- return true;
+ return;
- default:
- return super.onOptionsItemSelected(item);
+ case R.id.menu_exit:
+ toggleMenu();
+ stopEmulation();
+ return;
}
}
@@ -244,6 +479,11 @@ public final class EmulationActivity extends AppCompatActivity
@Override
public boolean dispatchKeyEvent(KeyEvent event)
{
+ if (mMenuVisible)
+ {
+ return super.dispatchKeyEvent(event);
+ }
+
int action = 0;
switch (event.getAction())
@@ -273,6 +513,11 @@ public final class EmulationActivity extends AppCompatActivity
@Override
public boolean dispatchGenericMotionEvent(MotionEvent event)
{
+ if (mMenuVisible)
+ {
+ return false;
+ }
+
if (((event.getSource() & InputDevice.SOURCE_CLASS_JOYSTICK) == 0))
{
return super.dispatchGenericMotionEvent(event);
@@ -324,4 +569,94 @@ public final class EmulationActivity extends AppCompatActivity
hideSystemUiAfterDelay();
}
+
+
+ private void scheduleStartPostponedTransition(final View sharedElement)
+ {
+ sharedElement.getViewTreeObserver().addOnPreDrawListener(
+ new ViewTreeObserver.OnPreDrawListener()
+ {
+ @Override
+ public boolean onPreDraw()
+ {
+ sharedElement.getViewTreeObserver().removeOnPreDrawListener(this);
+ startPostponedEnterTransition();
+ return true;
+ }
+ });
+ }
+
+ private void showMenu(int menuId)
+ {
+ Fragment fragment;
+
+ switch (menuId)
+ {
+ case SaveStateFragment.FRAGMENT_ID:
+ fragment = SaveStateFragment.newInstance();
+ mSubmenuFragmentTag = SaveStateFragment.FRAGMENT_TAG;
+ break;
+
+ case LoadStateFragment.FRAGMENT_ID:
+ fragment = LoadStateFragment.newInstance();
+ mSubmenuFragmentTag = LoadStateFragment.FRAGMENT_TAG;
+ break;
+
+ default:
+ return;
+ }
+
+ getFragmentManager().beginTransaction()
+ .setCustomAnimations(R.animator.menu_slide_in, R.animator.menu_slide_out)
+ .replace(R.id.frame_submenu, fragment, mSubmenuFragmentTag)
+ .commit();
+ }
+
+ private void removeMenu()
+ {
+ if (mSubmenuFragmentTag != null)
+ {
+ final Fragment fragment = getFragmentManager().findFragmentByTag(mSubmenuFragmentTag);
+
+ if (fragment != null)
+ {
+ // When removing a fragment without replacement, its aniimation must be done
+ // manually beforehand.
+ fragment.getView().animate()
+ .withLayer()
+ .setDuration(200)
+ .setInterpolator(sAccelerator)
+ .alpha(0.0f)
+ .translationX(600.0f)
+ .withEndAction(new Runnable()
+ {
+ @Override
+ public void run()
+ {
+ if (mMenuVisible)
+ {
+ getFragmentManager().beginTransaction()
+ .remove(fragment)
+ .commit();
+ }
+ }
+ });
+ }
+ else
+ {
+ Log.e("DolphinEmu", "[EmulationActivity] Fragment not found, can't remove.");
+ }
+
+ mSubmenuFragmentTag = null;
+ }
+ else
+ {
+ Log.e("DolphinEmu", "[EmulationActivity] Fragment Tag empty.");
+ }
+ }
+
+ public String getSelectedTitle()
+ {
+ return mSelectedTitle;
+ }
}
diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/activities/MainActivity.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/activities/MainActivity.java
index 7812e6ead5..9ffa651cc2 100644
--- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/activities/MainActivity.java
+++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/activities/MainActivity.java
@@ -35,7 +35,8 @@ import org.dolphinemu.dolphinemu.services.AssetCopyService;
*/
public final class MainActivity extends AppCompatActivity implements LoaderManager.LoaderCallbacks<Cursor>
{
- private static final int REQUEST_ADD_DIRECTORY = 1;
+ public static final int REQUEST_ADD_DIRECTORY = 1;
+ public static final int REQUEST_EMULATE_GAME = 2;
/**
* It is important to keep track of loader ID separately from platform ID (see Game.java)
@@ -115,15 +116,30 @@ public final class MainActivity extends AppCompatActivity implements LoaderManag
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent result)
{
- // If the user picked a file, as opposed to just backing out.
- if (resultCode == RESULT_OK)
+ switch (requestCode)
{
- // Sanity check to make sure the Activity that just returned was the AddDirectoryActivity;
- // other activities might use this callback in the future (don't forget to change Javadoc!)
- if (requestCode == REQUEST_ADD_DIRECTORY)
- {
- refreshFragment();
- }
+ case REQUEST_ADD_DIRECTORY:
+ // If the user picked a file, as opposed to just backing out.
+ if (resultCode == RESULT_OK)
+ {
+ // Sanity check to make sure the Activity that just returned was the AddDirectoryActivity;
+ // other activities might use this callback in the future (don't forget to change Javadoc!)
+ if (requestCode == REQUEST_ADD_DIRECTORY)
+ {
+ refreshFragment();
+ }
+ }
+ break;
+
+ case REQUEST_EMULATE_GAME:
+ // Invalidate Picasso image so that the new screenshot is animated in.
+ PlatformGamesFragment fragment = getPlatformFragment(mViewPager.getCurrentItem());
+
+ if (fragment != null)
+ {
+ fragment.refreshScreenshotAtPosition(resultCode);
+ }
+ break;
}
}
@@ -211,7 +227,7 @@ public final class MainActivity extends AppCompatActivity implements LoaderManag
GameProvider.URI_GAME, // URI of table to query
null, // Return all columns
GameDatabase.KEY_GAME_PLATFORM + " = ?", // Select by platform
- new String[]{Integer.toString(id)}, // Platform id is Loader id minus 1
+ new String[]{Integer.toString(id)}, // Platform id is Loader id
GameDatabase.KEY_GAME_TITLE + " asc" // Sort by game name, ascending order
);
diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/activities/TvMainActivity.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/activities/TvMainActivity.java
new file mode 100644
index 0000000000..3f3b8c168d
--- /dev/null
+++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/activities/TvMainActivity.java
@@ -0,0 +1,290 @@
+package org.dolphinemu.dolphinemu.activities;
+
+import android.app.Activity;
+import android.app.ActivityOptions;
+import android.app.FragmentManager;
+import android.content.Intent;
+import android.content.SharedPreferences;
+import android.database.Cursor;
+import android.os.Bundle;
+import android.preference.PreferenceManager;
+import android.support.v17.leanback.app.BrowseFragment;
+import android.support.v17.leanback.database.CursorMapper;
+import android.support.v17.leanback.widget.ArrayObjectAdapter;
+import android.support.v17.leanback.widget.CursorObjectAdapter;
+import android.support.v17.leanback.widget.HeaderItem;
+import android.support.v17.leanback.widget.ListRow;
+import android.support.v17.leanback.widget.ListRowPresenter;
+import android.support.v17.leanback.widget.OnItemViewClickedListener;
+import android.support.v17.leanback.widget.Presenter;
+import android.support.v17.leanback.widget.Row;
+import android.support.v17.leanback.widget.RowPresenter;
+import android.widget.Toast;
+
+import org.dolphinemu.dolphinemu.NativeLibrary;
+import org.dolphinemu.dolphinemu.R;
+import org.dolphinemu.dolphinemu.adapters.GameRowPresenter;
+import org.dolphinemu.dolphinemu.adapters.SettingsRowPresenter;
+import org.dolphinemu.dolphinemu.model.Game;
+import org.dolphinemu.dolphinemu.model.GameDatabase;
+import org.dolphinemu.dolphinemu.model.GameProvider;
+import org.dolphinemu.dolphinemu.model.TvSettingsItem;
+import org.dolphinemu.dolphinemu.services.AssetCopyService;
+import org.dolphinemu.dolphinemu.viewholders.TvGameViewHolder;
+
+public final class TvMainActivity extends Activity
+{
+ protected BrowseFragment mBrowseFragment;
+
+ private ArrayObjectAdapter mRowsAdapter;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState)
+ {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_tv_main);
+
+ final FragmentManager fragmentManager = getFragmentManager();
+ mBrowseFragment = (BrowseFragment) fragmentManager.findFragmentById(
+ R.id.fragment_game_list);
+
+ // Set display parameters for the BrowseFragment
+ mBrowseFragment.setHeadersState(BrowseFragment.HEADERS_ENABLED);
+ mBrowseFragment.setTitle(getString(R.string.app_name));
+ mBrowseFragment.setBadgeDrawable(getResources().getDrawable(
+ R.drawable.ic_launcher, null));
+ mBrowseFragment.setBrandColor(getResources().getColor(R.color.dolphin_blue_dark));
+
+ buildRowsAdapter();
+
+ mBrowseFragment.setOnItemViewClickedListener(
+ new OnItemViewClickedListener()
+ {
+ @Override
+ public void onItemClicked(Presenter.ViewHolder itemViewHolder, Object item, RowPresenter.ViewHolder rowViewHolder, Row row)
+ {
+ // Special case: user clicked on a settings row item.
+ if (item instanceof TvSettingsItem)
+ {
+ TvSettingsItem settingsItem = (TvSettingsItem) item;
+
+ switch (settingsItem.getItemId())
+ {
+ case R.id.menu_refresh:
+ getContentResolver().insert(GameProvider.URI_REFRESH, null);
+
+ // TODO Let the Activity know the data is refreshed in some other, better way.
+ recreate();
+ break;
+
+ case R.id.menu_settings:
+ // Launch the Settings Actvity.
+ Intent settings = new Intent(TvMainActivity.this, SettingsActivity.class);
+ startActivity(settings);
+ break;
+
+ case R.id.button_add_directory:
+ Intent fileChooser = new Intent(TvMainActivity.this, AddDirectoryActivity.class);
+
+ // The second argument to this method is read below in onActivityResult().
+ startActivityForResult(fileChooser, MainActivity.REQUEST_ADD_DIRECTORY);
+
+ break;
+
+ default:
+ Toast.makeText(TvMainActivity.this, "Unimplemented menu option.", Toast.LENGTH_SHORT).show();
+ break;
+ }
+ }
+ else
+ {
+ TvGameViewHolder holder = (TvGameViewHolder) itemViewHolder;
+ // Start the emulation activity and send the path of the clicked ISO to it.
+ Intent intent = new Intent(TvMainActivity.this, EmulationActivity.class);
+
+ intent.putExtra("SelectedGame", holder.path);
+ intent.putExtra("SelectedTitle", holder.title);
+ intent.putExtra("ScreenPath", holder.screenshotPath);
+
+ ActivityOptions options = ActivityOptions.makeSceneTransitionAnimation(
+ TvMainActivity.this,
+ holder.imageScreenshot,
+ "image_game_screenshot");
+
+ startActivity(intent, options.toBundle());
+ }
+ }
+ });
+
+ // Stuff in this block only happens when this activity is newly created (i.e. not a rotation)
+ if (savedInstanceState == null)
+ {
+ NativeLibrary.SetUserDirectory(""); // Auto-Detect
+
+ SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(this);
+ boolean assetsCopied = preferences.getBoolean("assetsCopied", false);
+
+ // Only perform these extensive copy operations once.
+ if (!assetsCopied)
+ {
+ // Copy assets into appropriate locations.
+ Intent copyAssets = new Intent(this, AssetCopyService.class);
+ startService(copyAssets);
+ }
+ }
+ }
+
+ /**
+ * Callback from AddDirectoryActivity. Applies any changes necessary to the GameGridActivity.
+ *
+ * @param requestCode An int describing whether the Activity that is returning did so successfully.
+ * @param resultCode An int describing what Activity is giving us this callback.
+ * @param result The information the returning Activity is providing us.
+ */
+ @Override
+ protected void onActivityResult(int requestCode, int resultCode, Intent result)
+ {
+ switch (requestCode)
+ {
+ case MainActivity.REQUEST_ADD_DIRECTORY:
+ // If the user picked a file, as opposed to just backing out.
+ if (resultCode == RESULT_OK)
+ {
+ // Sanity check to make sure the Activity that just returned was the AddDirectoryActivity;
+ // other activities might use this callback in the future (don't forget to change Javadoc!)
+ if (requestCode == MainActivity.REQUEST_ADD_DIRECTORY)
+ {
+ // TODO Let the Activity know the data is refreshed in some other, better way.
+ recreate();
+ }
+ }
+ break;
+ }
+ }
+
+ private void buildRowsAdapter()
+ {
+ mRowsAdapter = new ArrayObjectAdapter(new ListRowPresenter());
+
+ // For each platform
+ for (int platformIndex = 0; platformIndex <= Game.PLATFORM_ALL; ++platformIndex)
+ {
+ ListRow row = buildGamesRow(platformIndex);
+
+ // Add row to the adapter only if it is not empty.
+ if (row != null)
+ {
+ mRowsAdapter.add(row);
+ }
+ }
+
+ ListRow settingsRow = buildSettingsRow();
+ mRowsAdapter.add(settingsRow);
+
+ mBrowseFragment.setAdapter(mRowsAdapter);
+ }
+
+ private ListRow buildGamesRow(int platform)
+ {
+ // Create an adapter for this row.
+ CursorObjectAdapter row = new CursorObjectAdapter(new GameRowPresenter());
+
+ Cursor games;
+ if (platform == Game.PLATFORM_ALL)
+ {
+ // Get all games.
+ games = getContentResolver().query(
+ GameProvider.URI_GAME, // URI of table to query
+ null, // Return all columns
+ null, // Return all games
+ null, // Return all games
+ GameDatabase.KEY_GAME_TITLE + " asc" // Sort by game name, ascending order
+ );
+ }
+ else
+ {
+ // Get games for this particular platform.
+ games = getContentResolver().query(
+ GameProvider.URI_GAME, // URI of table to query
+ null, // Return all columns
+ GameDatabase.KEY_GAME_PLATFORM + " = ?", // Select by platform
+ new String[]{Integer.toString(platform)}, // Platform id
+ GameDatabase.KEY_GAME_TITLE + " asc" // Sort by game name, ascending order
+ );
+ }
+
+ // If cursor is empty, don't return a Row.
+ if (!games.moveToFirst())
+ {
+ return null;
+ }
+
+ row.changeCursor(games);
+ row.setMapper(new CursorMapper()
+ {
+ @Override
+ protected void bindColumns(Cursor cursor)
+ {
+ // No-op? Not sure what this does.
+ }
+
+ @Override
+ protected Object bind(Cursor cursor)
+ {
+ return Game.fromCursor(cursor);
+ }
+ });
+
+ String headerName;
+ switch (platform)
+ {
+ case Game.PLATFORM_GC:
+ headerName = "GameCube Games";
+ break;
+
+ case Game.PLATFORM_WII:
+ headerName = "Wii Games";
+ break;
+
+ case Game.PLATFORM_WII_WARE:
+ headerName = "WiiWare";
+ break;
+
+ case Game.PLATFORM_ALL:
+ headerName = "All Games";
+ break;
+
+ default:
+ headerName = "Error";
+ break;
+ }
+
+ // Create a header for this row.
+ HeaderItem header = new HeaderItem(platform, headerName);
+
+ // Create the row, passing it the filled adapter and the header, and give it to the master adapter.
+ return new ListRow(header, row);
+ }
+
+ private ListRow buildSettingsRow()
+ {
+ ArrayObjectAdapter rowItems = new ArrayObjectAdapter(new SettingsRowPresenter());
+
+ rowItems.add(new TvSettingsItem(R.id.menu_refresh,
+ R.drawable.ic_refresh_tv,
+ R.string.grid_menu_refresh));
+
+ rowItems.add(new TvSettingsItem(R.id.menu_settings,
+ R.drawable.ic_settings_tv,
+ R.string.grid_menu_settings));
+
+ rowItems.add(new TvSettingsItem(R.id.button_add_directory,
+ R.drawable.ic_add_tv,
+ R.string.add_directory_title));
+
+ // Create a header for this row.
+ HeaderItem header = new HeaderItem(R.string.settings, getString(R.string.settings));
+
+ return new ListRow(header, rowItems);
+ }
+}
diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/adapters/GameAdapter.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/adapters/GameAdapter.java
index a9a7be930e..e74bd6f96d 100644
--- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/adapters/GameAdapter.java
+++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/adapters/GameAdapter.java
@@ -1,9 +1,11 @@
package org.dolphinemu.dolphinemu.adapters;
import android.app.Activity;
+import android.app.ActivityOptions;
import android.content.Intent;
import android.database.Cursor;
import android.database.DataSetObserver;
+import android.graphics.Bitmap;
import android.graphics.Rect;
import android.support.v7.widget.RecyclerView;
import android.util.Log;
@@ -15,6 +17,7 @@ import com.squareup.picasso.Picasso;
import org.dolphinemu.dolphinemu.R;
import org.dolphinemu.dolphinemu.activities.EmulationActivity;
+import org.dolphinemu.dolphinemu.activities.MainActivity;
import org.dolphinemu.dolphinemu.dialogs.GameDetailsDialog;
import org.dolphinemu.dolphinemu.model.GameDatabase;
import org.dolphinemu.dolphinemu.viewholders.GameViewHolder;
@@ -80,14 +83,15 @@ public final class GameAdapter extends RecyclerView.Adapter<GameViewHolder> impl
if (mCursor.moveToPosition(position))
{
String screenPath = mCursor.getString(GameDatabase.GAME_COLUMN_SCREENSHOT_PATH);
- Picasso.with(holder.imageScreenshot.getContext())
- .invalidate(screenPath);
// Fill in the view contents.
Picasso.with(holder.imageScreenshot.getContext())
.load(screenPath)
.fit()
.centerCrop()
+ .noFade()
+ .noPlaceholder()
+ .config(Bitmap.Config.RGB_565)
.error(R.drawable.no_banner)
.into(holder.imageScreenshot);
@@ -112,8 +116,6 @@ public final class GameAdapter extends RecyclerView.Adapter<GameViewHolder> impl
{
Log.e("DolphinEmu", "Can't bind view; dataset is not valid.");
}
-
-
}
/**
@@ -220,8 +222,17 @@ public final class GameAdapter extends RecyclerView.Adapter<GameViewHolder> impl
intent.putExtra("SelectedGame", holder.path);
intent.putExtra("SelectedTitle", holder.title);
+ intent.putExtra("ScreenPath", holder.screenshotPath);
+ intent.putExtra("GridPosition", holder.getAdapterPosition());
+
+ ActivityOptions options = ActivityOptions.makeSceneTransitionAnimation(
+ (Activity) view.getContext(),
+ holder.imageScreenshot,
+ "image_game_screenshot");
- view.getContext().startActivity(intent);
+ ((Activity) view.getContext()).startActivityForResult(intent,
+ MainActivity.REQUEST_EMULATE_GAME,
+ options.toBundle());
}
/**
diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/adapters/GameRowPresenter.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/adapters/GameRowPresenter.java
new file mode 100644
index 0000000000..3b0b8095ce
--- /dev/null
+++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/adapters/GameRowPresenter.java
@@ -0,0 +1,118 @@
+package org.dolphinemu.dolphinemu.adapters;
+
+import android.graphics.Bitmap;
+import android.support.v17.leanback.widget.ImageCardView;
+import android.support.v17.leanback.widget.Presenter;
+import android.view.ViewGroup;
+import android.widget.ImageView;
+
+import com.squareup.picasso.Picasso;
+
+import org.dolphinemu.dolphinemu.R;
+import org.dolphinemu.dolphinemu.model.Game;
+import org.dolphinemu.dolphinemu.viewholders.TvGameViewHolder;
+
+/**
+ * The Leanback library / docs call this a Presenter, but it works very
+ * similarly to a RecyclerView.ViewHolder.
+ */
+public final class GameRowPresenter extends Presenter
+{
+ public ViewHolder onCreateViewHolder(ViewGroup parent)
+ {
+ // Create a new view.
+ ImageCardView gameCard = new ImageCardView(parent.getContext())
+ {
+ @Override
+ public void setSelected(boolean selected)
+ {
+ setCardBackground(this, selected);
+ super.setSelected(selected);
+ }
+ };
+
+ gameCard.setMainImageAdjustViewBounds(true);
+ gameCard.setMainImageDimensions(480, 320);
+ gameCard.setMainImageScaleType(ImageView.ScaleType.CENTER_CROP);
+
+ gameCard.setFocusable(true);
+ gameCard.setFocusableInTouchMode(true);
+
+ setCardBackground(gameCard, false);
+
+ // Use that view to create a ViewHolder.
+ return new TvGameViewHolder(gameCard);
+ }
+
+ public void onBindViewHolder(ViewHolder viewHolder, Object item)
+ {
+ TvGameViewHolder holder = (TvGameViewHolder) viewHolder;
+ Game game = (Game) item;
+
+ String screenPath = game.getScreenshotPath();
+
+ // Fill in the view contents.
+ Picasso.with(holder.imageScreenshot.getContext())
+ .load(screenPath)
+ .fit()
+ .centerCrop()
+ .noFade()
+ .noPlaceholder()
+ .config(Bitmap.Config.RGB_565)
+ .error(R.drawable.no_banner)
+ .into(holder.imageScreenshot);
+
+ holder.cardParent.setTitleText(game.getTitle());
+ holder.cardParent.setContentText(game.getCompany());
+
+ // TODO These shouldn't be necessary once the move to a DB-based model is complete.
+ holder.gameId = game.getGameId();
+ holder.path = game.getPath();
+ holder.title = game.getTitle();
+ holder.description = game.getDescription();
+ holder.country = game.getCountry();
+ holder.company = game.getCompany();
+ holder.screenshotPath = game.getScreenshotPath();
+
+ switch (game.getPlatform())
+ {
+ case Game.PLATFORM_GC:
+ holder.cardParent.setTag(R.color.dolphin_accent_gamecube);
+ break;
+
+ case Game.PLATFORM_WII:
+ holder.cardParent.setTag(R.color.dolphin_accent_wii);
+ break;
+
+ case Game.PLATFORM_WII_WARE:
+ holder.cardParent.setTag(R.color.dolphin_accent_wiiware);
+ break;
+
+ default:
+ holder.cardParent.setTag(android.R.color.holo_red_dark);
+ break;
+ }
+ }
+
+ public void onUnbindViewHolder(ViewHolder viewHolder)
+ {
+ // no op
+ }
+
+ public void setCardBackground(ImageCardView view, boolean selected)
+ {
+ int backgroundColor;
+
+ if (selected)
+ {
+ // TODO: 7/20/15 Try using view tag to set color
+ backgroundColor = (int) view.getTag();
+ }
+ else
+ {
+ backgroundColor = R.color.tv_card_unselected;
+ }
+
+ view.setInfoAreaBackgroundColor(view.getResources().getColor(backgroundColor));
+ }
+}
diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/adapters/SettingsRowPresenter.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/adapters/SettingsRowPresenter.java
new file mode 100644
index 0000000000..beef06a218
--- /dev/null
+++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/adapters/SettingsRowPresenter.java
@@ -0,0 +1,47 @@
+package org.dolphinemu.dolphinemu.adapters;
+
+
+import android.content.res.Resources;
+import android.support.v17.leanback.widget.ImageCardView;
+import android.support.v17.leanback.widget.Presenter;
+import android.view.ViewGroup;
+
+import org.dolphinemu.dolphinemu.model.TvSettingsItem;
+import org.dolphinemu.dolphinemu.viewholders.TvSettingsViewHolder;
+
+public final class SettingsRowPresenter extends Presenter
+{
+ public Presenter.ViewHolder onCreateViewHolder(ViewGroup parent)
+ {
+ // Create a new view.
+ ImageCardView settingsCard = new ImageCardView(parent.getContext());
+
+ settingsCard.setMainImageAdjustViewBounds(true);
+ settingsCard.setMainImageDimensions(192, 160);
+
+
+ settingsCard.setFocusable(true);
+ settingsCard.setFocusableInTouchMode(true);
+
+ // Use that view to create a ViewHolder.
+ return new TvSettingsViewHolder(settingsCard);
+ }
+
+ public void onBindViewHolder(Presenter.ViewHolder viewHolder, Object item)
+ {
+ TvSettingsViewHolder holder = (TvSettingsViewHolder) viewHolder;
+ TvSettingsItem settingsItem = (TvSettingsItem) item;
+
+ Resources resources = holder.cardParent.getResources();
+
+ holder.itemId = settingsItem.getItemId();
+
+ holder.cardParent.setTitleText(resources.getString(settingsItem.getLabelId()));
+ holder.cardParent.setMainImage(resources.getDrawable(settingsItem.getIconId(), null));
+ }
+
+ public void onUnbindViewHolder(Presenter.ViewHolder viewHolder)
+ {
+ // no op
+ }
+} \ No newline at end of file
diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/fragments/EmulationFragment.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/fragments/EmulationFragment.java
index 9d23736cb6..1eb1684531 100644
--- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/fragments/EmulationFragment.java
+++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/fragments/EmulationFragment.java
@@ -81,9 +81,12 @@ public final class EmulationFragment extends Fragment implements SurfaceHolder.C
mSurfaceView.getHolder().addCallback(this);
// If the input overlay was previously disabled, then don't show it.
- if (!mPreferences.getBoolean("showInputOverlay", true))
+ if (mInputOverlay != null)
{
- mInputOverlay.setVisibility(View.GONE);
+ if (!mPreferences.getBoolean("showInputOverlay", true))
+ {
+ mInputOverlay.setVisibility(View.GONE);
+ }
}
diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/fragments/LoadStateFragment.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/fragments/LoadStateFragment.java
new file mode 100644
index 0000000000..bbd9807b9b
--- /dev/null
+++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/fragments/LoadStateFragment.java
@@ -0,0 +1,55 @@
+package org.dolphinemu.dolphinemu.fragments;
+
+import android.app.Fragment;
+import android.os.Bundle;
+import android.support.annotation.Nullable;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.Button;
+import android.widget.GridLayout;
+
+import org.dolphinemu.dolphinemu.BuildConfig;
+import org.dolphinemu.dolphinemu.R;
+import org.dolphinemu.dolphinemu.activities.EmulationActivity;
+
+public final class LoadStateFragment extends Fragment implements View.OnClickListener
+{
+ public static final String FRAGMENT_TAG = BuildConfig.APPLICATION_ID + ".load_state";
+ public static final int FRAGMENT_ID = R.layout.fragment_state_load;
+
+ public static LoadStateFragment newInstance()
+ {
+ LoadStateFragment fragment = new LoadStateFragment();
+
+ // TODO Add any appropriate arguments to this fragment.
+
+ return fragment;
+ }
+
+ @Nullable
+ @Override
+ public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
+ {
+ View rootView = inflater.inflate(FRAGMENT_ID, container, false);
+
+ GridLayout grid = (GridLayout) rootView.findViewById(R.id.grid_state_slots);
+ for (int childIndex = 0; childIndex < grid.getChildCount(); childIndex++)
+ {
+ Button button = (Button) grid.getChildAt(childIndex);
+
+ button.setOnClickListener(this);
+ }
+
+ // So that item clicked to start this Fragment is no longer the focused item.
+ grid.requestFocus();
+
+ return rootView;
+ }
+
+ @Override
+ public void onClick(View button)
+ {
+ ((EmulationActivity) getActivity()).onMenuItemClicked(button.getId());
+ }
+}
diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/fragments/MenuFragment.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/fragments/MenuFragment.java
new file mode 100644
index 0000000000..d894f32373
--- /dev/null
+++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/fragments/MenuFragment.java
@@ -0,0 +1,52 @@
+package org.dolphinemu.dolphinemu.fragments;
+
+import android.app.Fragment;
+import android.os.Bundle;
+import android.support.annotation.Nullable;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.Button;
+import android.widget.LinearLayout;
+import android.widget.TextView;
+
+import org.dolphinemu.dolphinemu.BuildConfig;
+import org.dolphinemu.dolphinemu.R;
+import org.dolphinemu.dolphinemu.activities.EmulationActivity;
+
+public final class MenuFragment extends Fragment implements View.OnClickListener
+{
+ public static final String FRAGMENT_TAG = BuildConfig.APPLICATION_ID + ".ingame_menu";
+ public static final int FRAGMENT_ID = R.layout.fragment_ingame_menu;
+ private TextView mTitleText;
+
+ @Nullable
+ @Override
+ public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
+ {
+ View rootView = inflater.inflate(FRAGMENT_ID, container, false);
+
+ LinearLayout options = (LinearLayout) rootView.findViewById(R.id.layout_options);
+ for (int childIndex = 0; childIndex < options.getChildCount(); childIndex++)
+ {
+ Button button = (Button) options.getChildAt(childIndex);
+
+ button.setOnClickListener(this);
+ }
+
+ mTitleText = (TextView) rootView.findViewById(R.id.text_game_title);
+
+ return rootView;
+ }
+
+ @Override
+ public void onClick(View button)
+ {
+ ((EmulationActivity) getActivity()).onMenuItemClicked(button.getId());
+ }
+
+ public void setTitleText(String title)
+ {
+ mTitleText.setText(title);
+ }
+}
diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/fragments/PlatformGamesFragment.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/fragments/PlatformGamesFragment.java
index 4957090ed3..c1d1b1c8e7 100644
--- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/fragments/PlatformGamesFragment.java
+++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/fragments/PlatformGamesFragment.java
@@ -1,12 +1,12 @@
package org.dolphinemu.dolphinemu.fragments;
-import android.app.Activity;
import android.app.Fragment;
import android.app.LoaderManager;
import android.content.Loader;
import android.database.Cursor;
import android.os.Bundle;
import android.support.annotation.Nullable;
+import android.support.v7.widget.DefaultItemAnimator;
import android.support.v7.widget.GridLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.util.Log;
@@ -57,6 +57,15 @@ public class PlatformGamesFragment extends Fragment
RecyclerView.LayoutManager layoutManager = new GridLayoutManager(getActivity(),
getResources().getInteger(R.integer.game_grid_columns));
recyclerView.setLayoutManager(layoutManager);
+ recyclerView.setItemAnimator(new DefaultItemAnimator()
+ {
+ @Override
+ public boolean animateChange(RecyclerView.ViewHolder oldHolder, RecyclerView.ViewHolder newHolder, int fromX, int fromY, int toX, int toY)
+ {
+ dispatchChangeFinished(newHolder, false);
+ return true;
+ }
+ });
recyclerView.addItemDecoration(new GameAdapter.SpacesItemDecoration(8));
@@ -70,10 +79,9 @@ public class PlatformGamesFragment extends Fragment
return rootView;
}
- @Override
- public void onAttach(Activity activity)
+ public void refreshScreenshotAtPosition(int position)
{
- super.onAttach(activity);
+ mAdapter.notifyItemChanged(position);
}
public void refresh()
diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/fragments/SaveStateFragment.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/fragments/SaveStateFragment.java
new file mode 100644
index 0000000000..a5e9e6d441
--- /dev/null
+++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/fragments/SaveStateFragment.java
@@ -0,0 +1,55 @@
+package org.dolphinemu.dolphinemu.fragments;
+
+import android.app.Fragment;
+import android.os.Bundle;
+import android.support.annotation.Nullable;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.Button;
+import android.widget.GridLayout;
+
+import org.dolphinemu.dolphinemu.BuildConfig;
+import org.dolphinemu.dolphinemu.R;
+import org.dolphinemu.dolphinemu.activities.EmulationActivity;
+
+public final class SaveStateFragment extends Fragment implements View.OnClickListener
+{
+ public static final String FRAGMENT_TAG = BuildConfig.APPLICATION_ID + ".save_state";
+ public static final int FRAGMENT_ID = R.layout.fragment_state_save;
+
+ public static SaveStateFragment newInstance()
+ {
+ SaveStateFragment fragment = new SaveStateFragment();
+
+ // TODO Add any appropriate arguments to this fragment.
+
+ return fragment;
+ }
+
+ @Nullable
+ @Override
+ public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
+ {
+ View rootView = inflater.inflate(FRAGMENT_ID, container, false);
+
+ GridLayout grid = (GridLayout) rootView.findViewById(R.id.grid_state_slots);
+ for (int childIndex = 0; childIndex < grid.getChildCount(); childIndex++)
+ {
+ Button button = (Button) grid.getChildAt(childIndex);
+
+ button.setOnClickListener(this);
+ }
+
+ // So that item clicked to start this Fragment is no longer the focused item.
+ grid.requestFocus();
+
+ return rootView;
+ }
+
+ @Override
+ public void onClick(View button)
+ {
+ ((EmulationActivity) getActivity()).onMenuItemClicked(button.getId());
+ }
+}
diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/model/Game.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/model/Game.java
index f3ef6f7514..33a9f27c54 100644
--- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/model/Game.java
+++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/model/Game.java
@@ -3,13 +3,12 @@ package org.dolphinemu.dolphinemu.model;
import android.content.ContentValues;
import android.database.Cursor;
-import java.io.File;
-
public final class Game
{
public static final int PLATFORM_GC = 0;
public static final int PLATFORM_WII = 1;
public static final int PLATFORM_WII_WARE = 2;
+ public static final int PLATFORM_ALL = 3;
// Copied from IVolume::ECountry. Update these if that is ever modified.
public static final int COUNTRY_EUROPE = 0;
@@ -33,13 +32,13 @@ public final class Game
private String mDescription;
private String mPath;
private String mGameId;
- private String mScreenshotFolderPath;
+ private String mScreenshotPath;
private String mCompany;
private int mPlatform;
private int mCountry;
- public Game(int platform, String title, String description, int country, String path, String gameId, String company)
+ public Game(int platform, String title, String description, int country, String path, String gameId, String company, String screenshotPath)
{
mPlatform = platform;
mTitle = title;
@@ -48,7 +47,7 @@ public final class Game
mPath = path;
mGameId = gameId;
mCompany = company;
- mScreenshotFolderPath = PATH_SCREENSHOT_FOLDER + getGameId() + "/";
+ mScreenshotPath = screenshotPath;
}
public int getPlatform()
@@ -86,27 +85,9 @@ public final class Game
return mGameId;
}
- public String getScreenshotFolderPath()
- {
- return mScreenshotFolderPath;
- }
-
- public String getScreenPath()
+ public String getScreenshotPath()
{
- // Count how many screenshots are available, so we can use the most recent one.
- File screenshotFolder = new File(mScreenshotFolderPath.substring(mScreenshotFolderPath.indexOf('s') - 1));
- int screenCount = 0;
-
- if (screenshotFolder.isDirectory())
- {
- screenCount = screenshotFolder.list().length;
- }
-
- String screenPath = mScreenshotFolderPath
- + getGameId() + "-"
- + screenCount + ".png";
-
- return screenPath;
+ return mScreenshotPath;
}
public static ContentValues asContentValues(int platform, String title, String description, int country, String path, String gameId, String company)
@@ -135,6 +116,7 @@ public final class Game
cursor.getInt(GameDatabase.GAME_COLUMN_COUNTRY),
cursor.getString(GameDatabase.GAME_COLUMN_PATH),
cursor.getString(GameDatabase.GAME_COLUMN_GAME_ID),
- cursor.getString(GameDatabase.GAME_COLUMN_COMPANY));
+ cursor.getString(GameDatabase.GAME_COLUMN_COMPANY),
+ cursor.getString(GameDatabase.GAME_COLUMN_SCREENSHOT_PATH));
}
}
diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/model/TvSettingsItem.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/model/TvSettingsItem.java
new file mode 100644
index 0000000000..ccd87bfa4c
--- /dev/null
+++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/model/TvSettingsItem.java
@@ -0,0 +1,31 @@
+package org.dolphinemu.dolphinemu.model;
+
+
+public final class TvSettingsItem
+{
+ private final int mItemId;
+ private final int mIconId;
+ private final int mLabelId;
+
+ public TvSettingsItem(int itemId, int iconId, int labelId)
+ {
+ mItemId = itemId;
+ mIconId = iconId;
+ mLabelId = labelId;
+ }
+
+ public int getItemId()
+ {
+ return mItemId;
+ }
+
+ public int getIconId()
+ {
+ return mIconId;
+ }
+
+ public int getLabelId()
+ {
+ return mLabelId;
+ }
+}
diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/services/AssetCopyService.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/services/AssetCopyService.java
index 1f6f94bc8a..558a34be37 100644
--- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/services/AssetCopyService.java
+++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/services/AssetCopyService.java
@@ -61,6 +61,7 @@ public final class AssetCopyService extends IntentService
// Always copy over the GCPad config in case of change or corruption.
// Not a user configurable file.
copyAsset("GCPadNew.ini", ConfigDir + File.separator + "GCPadNew.ini");
+ copyAsset("WiimoteNew.ini", ConfigDir + File.separator + "WiimoteNew.ini");
// Load the configuration keys set in the Dolphin ini and gfx ini files
// into the application's shared preferences.
diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/utils/UserPreferences.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/utils/UserPreferences.java
index 168bd2dd93..dd8959129b 100644
--- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/utils/UserPreferences.java
+++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/utils/UserPreferences.java
@@ -45,14 +45,13 @@ public final class UserPreferences
else
editor.putString("cpuCorePref", getConfig("Dolphin.ini", "Core", "CPUCore", "3"));
- editor.putBoolean("dualCorePref", getConfig("Dolphin.ini", "Core", "CPUThread", "False").equals("True"));
- editor.putBoolean("fastmemPref", getConfig("Dolphin.ini", "Core", "Fastmem", "False").equals("True"));
+ editor.putBoolean("dualCorePref", getConfig("Dolphin.ini", "Core", "CPUThread", "True").equals("True"));
editor.putString("gpuPref", getConfig("Dolphin.ini", "Core", "GFXBackend", "OGL"));
editor.putBoolean("showFPS", getConfig("gfx_opengl.ini", "Settings", "ShowFPS", "False").equals("True"));
editor.putBoolean("drawOnscreenControls", getConfig("Dolphin.ini", "Android", "ScreenControls", "True").equals("True"));
- editor.putString("internalResolution", getConfig("gfx_opengl.ini", "Settings", "EFBScale", "2") );
+ editor.putString("internalResolution", getConfig("gfx_opengl.ini", "Settings", "EFBScale", "2"));
editor.putString("FSAA", getConfig("gfx_opengl.ini", "Settings", "MSAA", "0"));
editor.putString("anisotropicFiltering", getConfig("gfx_opengl.ini", "Enhancements", "MaxAnisotropy", "0"));
editor.putString("postProcessingShader", getConfig("gfx_opengl.ini", "Enhancements", "PostProcessingShader", ""));
@@ -62,10 +61,14 @@ public final class UserPreferences
editor.putBoolean("disableFog", getConfig("gfx_opengl.ini", "Settings", "DisableFog", "False").equals("True"));
editor.putBoolean("skipEFBAccess", getConfig("gfx_opengl.ini", "Hacks", "EFBAccessEnable", "False").equals("True"));
editor.putBoolean("ignoreFormatChanges", getConfig("gfx_opengl.ini", "Hacks", "EFBEmulateFormatChanges", "False").equals("True"));
- editor.putString("stereoscopyMode", getConfig("gfx_opengl.ini", "Enhancements", "StereoMode", "0"));
+ editor.putString("stereoscopyMode", getConfig("gfx_opengl.ini", "Enhancements", "StereoMode", "0"));
editor.putBoolean("stereoSwapEyes", getConfig("gfx_opengl.ini", "Enhancements", "StereoSwapEyes", "False").equals("True"));
editor.putString("stereoDepth", getConfig("gfx_opengl.ini", "Enhancements", "StereoDepth", "20"));
editor.putString("stereoConvergence", getConfig("gfx_opengl.ini", "Enhancements", "StereoConvergence", "20"));
+ editor.putBoolean("enableController1", getConfig("Dolphin.ini", "Settings", "SIDevice0", "6") == "6");
+ editor.putBoolean("enableController2", getConfig("Dolphin.ini", "Settings", "SIDevice1", "0") == "6");
+ editor.putBoolean("enableController3", getConfig("Dolphin.ini", "Settings", "SIDevice2", "0") == "6");
+ editor.putBoolean("enableController4", getConfig("Dolphin.ini", "Settings", "SIDevice3", "0") == "6");
String efbCopyOn = getConfig("gfx_opengl.ini", "Hacks", "EFBCopyEnable", "True");
String efbToTexture = getConfig("gfx_opengl.ini", "Hacks", "EFBToTextureEnable", "True");
@@ -106,7 +109,6 @@ public final class UserPreferences
editor.putString("externalFrameBuffer", "Real");
}
- editor.putBoolean("disableDestinationAlpha", getConfig("gfx_opengl.ini", "Settings", "DstAlphaPass", "False").equals("True"));
editor.putBoolean("fastDepthCalculation", getConfig("gfx_opengl.ini", "Settings", "FastDepthCalc", "True").equals("True"));
editor.putString("aspectRatio", getConfig("gfx_opengl.ini", "Settings", "AspectRatio", "0"));
@@ -135,9 +137,6 @@ public final class UserPreferences
// Current CPU core being used. Falls back to interpreter upon error.
String currentEmuCore = prefs.getString("cpuCorePref", "0");
- // Fastmem JIT core usage
- boolean isUsingFastmem = prefs.getBoolean("fastmemPref", false);
-
// Current video backend being used. Falls back to software rendering upon error.
String currentVideoBackend = prefs.getString("gpuPref", "Software Rendering");
@@ -162,9 +161,6 @@ public final class UserPreferences
// External frame buffer emulation. Falls back to disabled upon error.
String externalFrameBuffer = prefs.getString("externalFrameBuffer", "Disabled");
- // Whether or not to disable destination alpha.
- boolean disableDstAlphaPass = prefs.getBoolean("disableDestinationAlpha", false);
-
// Whether or not to use fast depth calculation.
boolean useFastDepthCalc = prefs.getBoolean("fastDepthCalculation", true);
@@ -207,10 +203,16 @@ public final class UserPreferences
// Stereoscopy convergence
String stereoscopyConvergence = prefs.getString("stereoConvergence", "20");
+ // Controllers
+ // Controller 1 never gets disconnected due to touch screen
+ //boolean enableController1 = prefs.getBoolean("enableController1", true);
+ boolean enableController2 = prefs.getBoolean("enableController2", false);
+ boolean enableController3 = prefs.getBoolean("enableController3", false);
+ boolean enableController4 = prefs.getBoolean("enableController4", false);
+
// CPU related Settings
NativeLibrary.SetConfig("Dolphin.ini", "Core", "CPUCore", currentEmuCore);
NativeLibrary.SetConfig("Dolphin.ini", "Core", "CPUThread", isUsingDualCore ? "True" : "False");
- NativeLibrary.SetConfig("Dolphin.ini", "Core", "Fastmem", isUsingFastmem ? "True" : "False");
// General Video Settings
NativeLibrary.SetConfig("Dolphin.ini", "Core", "GFXBackend", currentVideoBackend);
@@ -264,7 +266,6 @@ public final class UserPreferences
NativeLibrary.SetConfig("gfx_opengl.ini", "Settings", "UseRealXFB", "True");
}
- NativeLibrary.SetConfig("gfx_opengl.ini", "Settings", "DstAlphaPass", disableDstAlphaPass ? "True" : "False");
NativeLibrary.SetConfig("gfx_opengl.ini", "Settings", "FastDepthCalc", useFastDepthCalc ? "True" : "False");
//-- Enhancement Settings --//
@@ -280,5 +281,9 @@ public final class UserPreferences
NativeLibrary.SetConfig("gfx_opengl.ini", "Enhancements", "StereoSwapEyes", stereoscopyEyeSwap ? "True" : "False");
NativeLibrary.SetConfig("gfx_opengl.ini", "Enhancements", "StereoDepth", stereoscopySeparation);
NativeLibrary.SetConfig("gfx_opengl.ini", "Enhancements", "StereoConvergence", stereoscopyConvergence);
+ NativeLibrary.SetConfig("Dolphin.ini", "Settings", "SIDevice0", "6");
+ NativeLibrary.SetConfig("Dolphin.ini", "Settings", "SIDevice1", enableController2 ? "6" : "0");
+ NativeLibrary.SetConfig("Dolphin.ini", "Settings", "SIDevice2", enableController3 ? "6" : "0");
+ NativeLibrary.SetConfig("Dolphin.ini", "Settings", "SIDevice3", enableController4 ? "6" : "0");
}
}
diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/viewholders/TvGameViewHolder.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/viewholders/TvGameViewHolder.java
new file mode 100644
index 0000000000..d27a671c2f
--- /dev/null
+++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/viewholders/TvGameViewHolder.java
@@ -0,0 +1,39 @@
+package org.dolphinemu.dolphinemu.viewholders;
+
+import android.support.v17.leanback.widget.ImageCardView;
+import android.support.v17.leanback.widget.Presenter;
+import android.view.View;
+import android.widget.ImageView;
+
+/**
+ * A simple class that stores references to views so that the GameAdapter doesn't need to
+ * keep calling findViewById(), which is expensive.
+ */
+public final class TvGameViewHolder extends Presenter.ViewHolder
+{
+ public ImageCardView cardParent;
+
+ public ImageView imageScreenshot;
+
+ public String gameId;
+
+ // TODO Not need any of this stuff. Currently only the properties dialog needs it.
+ public String path;
+ public String title;
+ public String description;
+ public int country;
+ public String company;
+ public String screenshotPath;
+
+ public int backgroundColor;
+
+ public TvGameViewHolder(View itemView)
+ {
+ super(itemView);
+
+ itemView.setTag(this);
+
+ cardParent = (ImageCardView) itemView;
+ imageScreenshot = cardParent.getMainImageView();
+ }
+}
diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/viewholders/TvSettingsViewHolder.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/viewholders/TvSettingsViewHolder.java
new file mode 100644
index 0000000000..3264e93f5b
--- /dev/null
+++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/viewholders/TvSettingsViewHolder.java
@@ -0,0 +1,23 @@
+package org.dolphinemu.dolphinemu.viewholders;
+
+
+import android.support.v17.leanback.widget.ImageCardView;
+import android.support.v17.leanback.widget.Presenter;
+import android.view.View;
+
+public final class TvSettingsViewHolder extends Presenter.ViewHolder
+{
+ public ImageCardView cardParent;
+
+ // Determines what action to take when this item is clicked.
+ public int itemId;
+
+ public TvSettingsViewHolder(View itemView)
+ {
+ super(itemView);
+
+ itemView.setTag(this);
+
+ cardParent = (ImageCardView) itemView;
+ }
+}
diff --git a/Source/Android/app/src/main/res/animator/menu_slide_in.xml b/Source/Android/app/src/main/res/animator/menu_slide_in.xml
new file mode 100644
index 0000000000..e6f9ae6d8e
--- /dev/null
+++ b/Source/Android/app/src/main/res/animator/menu_slide_in.xml
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="utf-8"?>
+<set xmlns:android="http://schemas.android.com/apk/res/android">
+ <objectAnimator
+ android:propertyName="translationX"
+ android:valueType="floatType"
+ android:valueFrom="1280"
+ android:valueTo="0"
+ android:interpolator="@android:interpolator/decelerate_quad"
+ android:duration="300"/>
+ <objectAnimator
+ android:propertyName="alpha"
+ android:valueType="floatType"
+ android:valueFrom="0"
+ android:valueTo="1"
+ android:interpolator="@android:interpolator/accelerate_quad"
+ android:duration="300"/>
+</set> \ No newline at end of file
diff --git a/Source/Android/app/src/main/res/animator/menu_slide_out.xml b/Source/Android/app/src/main/res/animator/menu_slide_out.xml
new file mode 100644
index 0000000000..85c2556e48
--- /dev/null
+++ b/Source/Android/app/src/main/res/animator/menu_slide_out.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="utf-8"?>
+<set xmlns:android="http://schemas.android.com/apk/res/android">
+ <!-- This animation is used ONLY when a submenu is replaced. -->
+ <objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"
+ android:propertyName="translationX"
+ android:valueType="floatType"
+ android:valueFrom="0"
+ android:valueTo="1280"
+ android:interpolator="@android:interpolator/decelerate_quad"
+ android:duration="300"/>
+ <objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"
+ android:propertyName="alpha"
+ android:valueType="floatType"
+ android:valueFrom="1"
+ android:valueTo="0"
+ android:interpolator="@android:interpolator/decelerate_quad"
+ android:duration="300"/>
+</set> \ No newline at end of file
diff --git a/Source/Android/app/src/main/res/drawable/ic_add_tv.png b/Source/Android/app/src/main/res/drawable/ic_add_tv.png
new file mode 100644
index 0000000000..7332c75727
--- /dev/null
+++ b/Source/Android/app/src/main/res/drawable/ic_add_tv.png
Binary files differ
diff --git a/Source/Android/app/src/main/res/drawable/ic_refresh_tv.png b/Source/Android/app/src/main/res/drawable/ic_refresh_tv.png
new file mode 100644
index 0000000000..8bae5d34ab
--- /dev/null
+++ b/Source/Android/app/src/main/res/drawable/ic_refresh_tv.png
Binary files differ
diff --git a/Source/Android/app/src/main/res/drawable/ic_settings_tv.png b/Source/Android/app/src/main/res/drawable/ic_settings_tv.png
new file mode 100644
index 0000000000..9e242e7748
--- /dev/null
+++ b/Source/Android/app/src/main/res/drawable/ic_settings_tv.png
Binary files differ
diff --git a/Source/Android/app/src/main/res/layout-television/activity_emulation.xml b/Source/Android/app/src/main/res/layout-television/activity_emulation.xml
new file mode 100644
index 0000000000..06fe747c39
--- /dev/null
+++ b/Source/Android/app/src/main/res/layout-television/activity_emulation.xml
@@ -0,0 +1,44 @@
+<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ xmlns:tools="http://schemas.android.com/tools"
+ android:id="@+id/frame_content">
+
+ <FrameLayout
+ android:id="@+id/frame_emulation_fragment"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:visibility="invisible"/>
+
+ <ImageView
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:id="@+id/image_screenshot"
+ android:transitionName="image_game_screenshot"/>
+
+ <LinearLayout
+ android:id="@+id/layout_ingame_menu"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:orientation="horizontal"
+ android:visibility="gone"
+ tools:visibility="visible"
+ android:baselineAligned="false">
+
+ <fragment
+ android:id="@+id/fragment_menu"
+ android:layout_width="0dp"
+ android:layout_height="match_parent"
+ android:layout_weight="1"
+ android:name="org.dolphinemu.dolphinemu.fragments.MenuFragment"
+ tools:layout="@layout/fragment_ingame_menu"/>
+
+ <FrameLayout
+ android:id="@+id/frame_submenu"
+ android:layout_width="0dp"
+ android:layout_height="match_parent"
+ android:layout_weight="3"/>
+
+ </LinearLayout>
+
+</FrameLayout> \ No newline at end of file
diff --git a/Source/Android/app/src/main/res/layout-television/fragment_emulation.xml b/Source/Android/app/src/main/res/layout-television/fragment_emulation.xml
new file mode 100644
index 0000000000..787de65186
--- /dev/null
+++ b/Source/Android/app/src/main/res/layout-television/fragment_emulation.xml
@@ -0,0 +1,14 @@
+<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:tools="http://schemas.android.com/tools"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ tools:context="org.dolphinemu.dolphinemu.fragments.EmulationFragment">
+
+ <!-- This is what everything is rendered to during emulation -->
+ <SurfaceView
+ android:id="@+id/surface_emulation"
+ android:layout_height="match_parent"
+ android:layout_width="match_parent"
+ android:focusable="false"
+ android:focusableInTouchMode="false"/>
+</FrameLayout>
diff --git a/Source/Android/app/src/main/res/layout/activity_emulation.xml b/Source/Android/app/src/main/res/layout/activity_emulation.xml
index 63ea99ba83..9e4e84e151 100644
--- a/Source/Android/app/src/main/res/layout/activity_emulation.xml
+++ b/Source/Android/app/src/main/res/layout/activity_emulation.xml
@@ -1,5 +1,19 @@
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
- android:id="@+id/frame_content">
+ android:id="@+id/frame_content"
+ >
+
+ <FrameLayout
+ android:id="@+id/frame_emulation_fragment"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:visibility="invisible"/>
+
+ <ImageView
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:id="@+id/image_screenshot"
+ android:transitionName="image_game_screenshot"/>
+
</FrameLayout> \ No newline at end of file
diff --git a/Source/Android/app/src/main/res/layout/activity_main.xml b/Source/Android/app/src/main/res/layout/activity_main.xml
index 53d4de6e72..845ff24b45 100644
--- a/Source/Android/app/src/main/res/layout/activity_main.xml
+++ b/Source/Android/app/src/main/res/layout/activity_main.xml
@@ -3,8 +3,7 @@
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/coordinator_main"
android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:fitsSystemWindows="true">
+ android:layout_height="match_parent">
<android.support.design.widget.AppBarLayout
android:id="@+id/appbar"
diff --git a/Source/Android/app/src/main/res/layout/activity_tv_main.xml b/Source/Android/app/src/main/res/layout/activity_tv_main.xml
new file mode 100644
index 0000000000..922d874b02
--- /dev/null
+++ b/Source/Android/app/src/main/res/layout/activity_tv_main.xml
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="utf-8"?>
+<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent">
+
+ <fragment
+ android:name="android.support.v17.leanback.app.BrowseFragment"
+ android:id="@+id/fragment_game_list"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ />
+
+</FrameLayout> \ No newline at end of file
diff --git a/Source/Android/app/src/main/res/layout/card_game.xml b/Source/Android/app/src/main/res/layout/card_game.xml
index b18bc9e7ee..542969ebd6 100644
--- a/Source/Android/app/src/main/res/layout/card_game.xml
+++ b/Source/Android/app/src/main/res/layout/card_game.xml
@@ -20,7 +20,7 @@
android:id="@+id/image_game_screen"
android:layout_width="match_parent"
android:layout_height="0dp"
- android:transitionName="image_game_screen"
+ android:transitionName="image_game_screenshot"
android:layout_weight="1"
tools:src="@drawable/placeholder_screenshot"
tools:scaleType="centerCrop"/>
@@ -33,7 +33,6 @@
android:layout_marginLeft="16dp"
android:layout_marginRight="16dp"
android:layout_marginTop="16dp"
- android:layout_toStartOf="@+id/button_details"
android:ellipsize="end"
android:lines="1"
android:maxLines="1"
diff --git a/Source/Android/app/src/main/res/layout/fragment_ingame_menu.xml b/Source/Android/app/src/main/res/layout/fragment_ingame_menu.xml
new file mode 100644
index 0000000000..44093dc324
--- /dev/null
+++ b/Source/Android/app/src/main/res/layout/fragment_ingame_menu.xml
@@ -0,0 +1,69 @@
+<?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:orientation="vertical"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:background="@color/dolphin_blue_dark"
+ tools:layout_width="250dp"
+ >
+
+ <TextView
+ android:id="@+id/text_game_title"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ tools:text="The Legend of Zelda: The Wind Waker"
+ android:textColor="@android:color/white"
+ android:textSize="20sp"
+ android:layout_margin="32dp"/>
+
+ <ScrollView
+ android:layout_width="match_parent"
+ android:layout_height="0dp"
+ android:layout_weight="1"
+ >
+
+ <LinearLayout
+ android:id="@+id/layout_options"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="vertical">
+
+ <Button
+ android:id="@+id/menu_take_screenshot"
+ android:text="@string/overlay_screenshot"
+ style="@style/InGameMenuOption"/>
+
+ <Button
+ android:id="@+id/menu_quicksave"
+ android:text="@string/emulation_quicksave"
+ style="@style/InGameMenuOption"/>
+
+ <Button
+ android:id="@+id/menu_quickload"
+ android:text="@string/emulation_quickload"
+ style="@style/InGameMenuOption"/>
+
+ <Button
+ android:id="@+id/menu_emulation_save_root"
+ android:text="@string/overlay_savestate"
+ style="@style/InGameMenuOption"/>
+
+ <Button
+ android:id="@+id/menu_emulation_load_root"
+ android:text="@string/overlay_loadstate"
+ style="@style/InGameMenuOption"/>
+
+ <Button
+ android:id="@+id/menu_ingame_settings"
+ android:text="@string/settings"
+ style="@style/InGameMenuOption"/>
+
+ <Button
+ android:id="@+id/menu_exit"
+ android:text="@string/overlay_exit_emulation"
+ style="@style/InGameMenuOption"/>
+
+ </LinearLayout>
+ </ScrollView>
+</LinearLayout> \ No newline at end of file
diff --git a/Source/Android/app/src/main/res/layout/fragment_state_load.xml b/Source/Android/app/src/main/res/layout/fragment_state_load.xml
new file mode 100644
index 0000000000..1b04c6ce59
--- /dev/null
+++ b/Source/Android/app/src/main/res/layout/fragment_state_load.xml
@@ -0,0 +1,65 @@
+<?xml version="1.0" encoding="utf-8"?>
+<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:background="#af000000"
+ android:orientation="vertical"
+ >
+
+ <GridLayout
+ android:id="@+id/grid_state_slots"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:columnCount="3"
+ android:rowCount="2"
+ android:layout_gravity="center">
+
+ <Button
+ android:id="@+id/menu_emulation_load_1"
+ android:layout_width="128dp"
+ android:layout_height="128dp"
+ android:text="@string/overlay_slot1"
+ style="@style/InGameMenuOption"
+ />
+
+ <Button
+ android:id="@+id/menu_emulation_load_2"
+ android:layout_width="128dp"
+ android:layout_height="128dp"
+ android:text="@string/overlay_slot2"
+ style="@style/InGameMenuOption"
+ />
+
+ <Button
+ android:id="@+id/menu_emulation_load_3"
+ android:layout_width="128dp"
+ android:layout_height="128dp"
+ android:text="@string/overlay_slot3"
+ style="@style/InGameMenuOption"
+ />
+
+ <Button
+ android:id="@+id/menu_emulation_load_4"
+ android:layout_width="128dp"
+ android:layout_height="128dp"
+ android:text="@string/overlay_slot4"
+ style="@style/InGameMenuOption"
+ />
+
+ <Button
+ android:id="@+id/menu_emulation_load_5"
+ android:layout_width="128dp"
+ android:layout_height="128dp"
+ android:text="@string/overlay_slot5"
+ style="@style/InGameMenuOption"
+ />
+
+ <Button
+ android:id="@+id/menu_emulation_load_6"
+ android:layout_width="128dp"
+ android:layout_height="128dp"
+ android:text="@string/overlay_slot6"
+ style="@style/InGameMenuOption"
+ />
+ </GridLayout>
+</FrameLayout> \ No newline at end of file
diff --git a/Source/Android/app/src/main/res/layout/fragment_state_save.xml b/Source/Android/app/src/main/res/layout/fragment_state_save.xml
new file mode 100644
index 0000000000..b5ca1e1ed8
--- /dev/null
+++ b/Source/Android/app/src/main/res/layout/fragment_state_save.xml
@@ -0,0 +1,65 @@
+<?xml version="1.0" encoding="utf-8"?>
+<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:background="#af000000"
+ android:orientation="vertical"
+ >
+
+ <GridLayout
+ android:id="@+id/grid_state_slots"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:columnCount="3"
+ android:rowCount="2"
+ android:layout_gravity="center">
+
+ <Button
+ android:id="@+id/menu_emulation_save_1"
+ android:layout_width="128dp"
+ android:layout_height="128dp"
+ android:text="@string/overlay_slot1"
+ style="@style/InGameMenuOption"
+ />
+
+ <Button
+ android:id="@+id/menu_emulation_save_2"
+ android:layout_width="128dp"
+ android:layout_height="128dp"
+ android:text="@string/overlay_slot2"
+ style="@style/InGameMenuOption"
+ />
+
+ <Button
+ android:id="@+id/menu_emulation_save_3"
+ android:layout_width="128dp"
+ android:layout_height="128dp"
+ android:text="@string/overlay_slot3"
+ style="@style/InGameMenuOption"
+ />
+
+ <Button
+ android:id="@+id/menu_emulation_save_4"
+ android:layout_width="128dp"
+ android:layout_height="128dp"
+ android:text="@string/overlay_slot4"
+ style="@style/InGameMenuOption"
+ />
+
+ <Button
+ android:id="@+id/menu_emulation_save_5"
+ android:layout_width="128dp"
+ android:layout_height="128dp"
+ android:text="@string/overlay_slot5"
+ style="@style/InGameMenuOption"
+ />
+
+ <Button
+ android:id="@+id/menu_emulation_save_6"
+ android:layout_width="128dp"
+ android:layout_height="128dp"
+ android:text="@string/overlay_slot6"
+ style="@style/InGameMenuOption"
+ />
+ </GridLayout>
+</FrameLayout> \ No newline at end of file
diff --git a/Source/Android/app/src/main/res/transition/change_image_transform.xml b/Source/Android/app/src/main/res/transition/change_image_transform.xml
new file mode 100644
index 0000000000..3ee92bd7c4
--- /dev/null
+++ b/Source/Android/app/src/main/res/transition/change_image_transform.xml
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
+<transitionSet>
+ <changeImageTransform/>
+</transitionSet> \ No newline at end of file
diff --git a/Source/Android/app/src/main/res/values-ja/strings.xml b/Source/Android/app/src/main/res/values-ja/strings.xml
index 59e72d1819..10efaf6a2e 100644
--- a/Source/Android/app/src/main/res/values-ja/strings.xml
+++ b/Source/Android/app/src/main/res/values-ja/strings.xml
@@ -94,20 +94,20 @@
<string name="button_x">Xボタン</string>
<string name="button_y">Yボタン</string>
<string name="button_z">Zボタン</string>
- <string name="dpad_up">D-Pad: ↑</string>
- <string name="dpad_down">D-Pad: ↓</string>
- <string name="dpad_left">D-Pad: ←</string>
- <string name="dpad_right">D-Pad: →</string>
+ <string name="dpad_up">十字キー: ↑</string>
+ <string name="dpad_down">十字キー: ↓</string>
+ <string name="dpad_left">十字キー: ←</string>
+ <string name="dpad_right">十字キー: →</string>
<string name="main_stick_up">コントロールスティック: ↑</string>
<string name="main_stick_down">コントロールスティック: ↓</string>
<string name="main_stick_left">コントロールスティック: ←</string>
<string name="main_stick_right">コントロールスティック: →</string>
- <string name="c_stick_up">C-スティック: ↑</string>
- <string name="c_stick_down">C-スティック: ↓</string>
- <string name="c_stick_left">C-スティック: ←</string>
- <string name="c_stick_right">C-スティック: →</string>
- <string name="trigger_left">左のトリガー</string>
- <string name="trigger_right">右のトリガー</string>
+ <string name="c_stick_up">Cスティック: ↑</string>
+ <string name="c_stick_down">Cスティック: ↓</string>
+ <string name="c_stick_left">Cスティック: ←</string>
+ <string name="c_stick_right">Cスティック: →</string>
+ <string name="trigger_left">Lトリガー</string>
+ <string name="trigger_right">Rトリガー</string>
<!-- Wiimote (+ extension) only buttons -->
<string name="button_one">ボタン1</string>
<string name="button_two">ボタン2</string>
diff --git a/Source/Android/app/src/main/res/values/arrays.xml b/Source/Android/app/src/main/res/values/arrays.xml
index 9cdf07d876..85ebb4ebc1 100644
--- a/Source/Android/app/src/main/res/values/arrays.xml
+++ b/Source/Android/app/src/main/res/values/arrays.xml
@@ -46,9 +46,11 @@
<!-- New UI CPU Core selection - Default -->
<string-array name="string_emu_cores" translatable="false">
<item>@string/interpreter</item>
+ <item>@string/cached_interpreter</item>
</string-array>
<string-array name="int_emu_cores" translatable="false">
<item>0</item>
+ <item>5</item>
</string-array>
<!-- Video Backend Selection - Supports OpenGL ES 3 -->
diff --git a/Source/Android/app/src/main/res/values/colors.xml b/Source/Android/app/src/main/res/values/colors.xml
index d7b7847125..9052de99d5 100644
--- a/Source/Android/app/src/main/res/values/colors.xml
+++ b/Source/Android/app/src/main/res/values/colors.xml
@@ -8,4 +8,6 @@
<color name="dolphin_accent_gamecube">#651fff</color>
<color name="circle_grey">#bdbdbd</color>
+
+ <color name="tv_card_unselected">#444444</color>
</resources> \ No newline at end of file
diff --git a/Source/Android/app/src/main/res/values/strings.xml b/Source/Android/app/src/main/res/values/strings.xml
index 3843cfb9b1..a6f004d4d3 100644
--- a/Source/Android/app/src/main/res/values/strings.xml
+++ b/Source/Android/app/src/main/res/values/strings.xml
@@ -66,6 +66,7 @@
<string name="overlay_slot3">Slot 3</string>
<string name="overlay_slot4">Slot 4</string>
<string name="overlay_slot5">Slot 5</string>
+ <string name="overlay_slot6">Slot 6</string>
<!-- Input Config Fragment -->
<string name="input_settings">Input</string>
@@ -99,10 +100,10 @@
<string name="dpad_down">D-Pad Down</string>
<string name="dpad_left">D-Pad Left</string>
<string name="dpad_right">D-Pad Right</string>
- <string name="main_stick_up">Main Stick Up</string>
- <string name="main_stick_down">Main Stick Down</string>
- <string name="main_stick_left">Main Stick Left</string>
- <string name="main_stick_right">Main Stick Right</string>
+ <string name="main_stick_up">Control Stick Up</string>
+ <string name="main_stick_down">Control Stick Down</string>
+ <string name="main_stick_left">Control Stick Left</string>
+ <string name="main_stick_right">Control Stick Right</string>
<string name="c_stick_up">C Stick Up</string>
<string name="c_stick_down">C Stick Down</string>
<string name="c_stick_left">C Stick Left</string>
@@ -135,6 +136,7 @@
<!-- CPU Preference Fragment -->
<string name="interpreter">Interpreter</string>
+ <string name="cached_interpreter">Cached Interpreter</string>
<string name="jit64_recompiler">JIT64 Recompiler</string>
<string name="jitil_recompiler">JITIL Recompiler</string>
<string name="jit_arm_recompiler">JIT ARM Recompiler</string>
diff --git a/Source/Android/app/src/main/res/values/styles.xml b/Source/Android/app/src/main/res/values/styles.xml
index 98cf984807..dba853f492 100644
--- a/Source/Android/app/src/main/res/values/styles.xml
+++ b/Source/Android/app/src/main/res/values/styles.xml
@@ -7,6 +7,13 @@
<item name="colorPrimary">@color/dolphin_blue</item>
<!-- darker variant for the status bar and contextual app bars -->
<item name="colorPrimaryDark">@color/dolphin_blue_dark</item>
+
+ <!--enable window content transitions-->
+ <item name="android:windowContentTransitions">true</item>
+ <item name="android:windowAllowEnterTransitionOverlap">true</item>
+ <item name="android:windowAllowReturnTransitionOverlap">true</item>
+
+ <item name="android:colorControlHighlight">?attr/colorAccent</item>
</style>
<!-- Same as above, but use default action bar, and mandate margins. -->
@@ -62,10 +69,17 @@
<item name="colorAccent">@color/dolphin_accent_wiiware</item>
</style>
- <style name="DolphinEmulationBase" parent="Theme.AppCompat.Light.DarkActionBar">
+ <style name="DolphinEmulationBase" parent="Theme.AppCompat">
<item name="colorPrimary">@color/dolphin_blue</item>
<item name="colorPrimaryDark">@color/dolphin_blue_dark</item>
<item name="android:windowTranslucentNavigation">true</item>
+
+ <item name="android:windowBackground">@android:color/black</item>
+
+ <!--enable window content transitions-->
+ <item name="android:windowContentTransitions">true</item>
+ <item name="android:windowAllowEnterTransitionOverlap">true</item>
+ <item name="android:windowAllowReturnTransitionOverlap">true</item>
</style>
<!-- Inherit from the Base Dolphin Emulation Theme-->
@@ -81,10 +95,63 @@
<item name="colorAccent">@color/dolphin_accent_wiiware</item>
</style>
+ <style name="DolphinEmulationTvBase" parent="Theme.AppCompat.NoActionBar">
+ <item name="colorPrimary">@color/dolphin_blue</item>
+ <item name="colorPrimaryDark">@color/dolphin_blue_dark</item>
+ <item name="android:windowTranslucentNavigation">true</item>
+
+ <item name="android:windowBackground">@android:color/black</item>
+
+ <!--enable window content transitions-->
+ <item name="android:windowContentTransitions">true</item>
+ <item name="android:windowAllowEnterTransitionOverlap">true</item>
+ <item name="android:windowAllowReturnTransitionOverlap">true</item>
+ </style>
+
+ <!-- Inherit from the Base Dolphin Emulation Theme-->
+ <style name="DolphinEmulationTvWii" parent="DolphinEmulationTvBase">
+ <item name="colorAccent">@color/dolphin_accent_wii</item>
+ </style>
+
+ <style name="DolphinEmulationTvGamecube" parent="DolphinEmulationTvBase">
+ <item name="colorAccent">@color/dolphin_accent_gamecube</item>
+ </style>
+
+ <style name="DolphinEmulationTvWiiware" parent="DolphinEmulationTvBase">
+ <item name="colorAccent">@color/dolphin_accent_wiiware</item>
+ </style>
<!-- Hax to make Tablayout render icons -->
<style name="MyCustomTextAppearance" parent="TextAppearance.Design.Tab">
<item name="textAllCaps">false</item>
</style>
+ <!-- Android TV Themes -->
+ <style name="DolphinTvBase" parent="Theme.Leanback">
+ <item name="colorPrimary">@color/dolphin_blue</item>
+ <item name="colorPrimaryDark">@color/dolphin_blue_dark</item>
+
+ <!--enable window content transitions-->
+ <item name="android:windowContentTransitions">true</item>
+ <item name="android:windowAllowEnterTransitionOverlap">true</item>
+ <item name="android:windowAllowReturnTransitionOverlap">true</item>
+ </style>
+
+ <style name="DolphinTvGamecube" parent="DolphinTvBase">
+ <item name="colorAccent">@color/dolphin_accent_gamecube</item>
+ </style>
+
+ <style name="InGameMenuOption" parent="Widget.AppCompat.Button.Borderless">
+ <item name="android:textSize">16sp</item>
+ <item name="android:fontFamily">sans-serif-condensed</item>
+ <item name="android:textColor">@android:color/white</item>
+ <item name="android:textAllCaps">false</item>
+ <item name="android:layout_width">match_parent</item>
+ <item name="android:layout_height">48dp</item>
+ <item name="android:gravity">center_vertical|left</item>
+ <item name="android:paddingLeft">32dp</item>
+ <item name="android:paddingRight">32dp</item>
+ <item name="android:layout_margin">0dp</item>
+ </style>
+
</resources> \ No newline at end of file
diff --git a/Source/Android/app/src/main/res/xml/preferences.xml b/Source/Android/app/src/main/res/xml/preferences.xml
index c91f77ab96..5e98e54bfc 100644
--- a/Source/Android/app/src/main/res/xml/preferences.xml
+++ b/Source/Android/app/src/main/res/xml/preferences.xml
@@ -7,7 +7,7 @@
<!-- CPU Settings -->
<CheckBoxPreference
- android:defaultValue="false"
+ android:defaultValue="true"
android:key="dualCorePref"
android:summary="@string/dual_core_descrip"
android:title="@string/dual_core"/>
@@ -19,12 +19,6 @@
android:entries="@array/string_emu_cores"
android:entryValues="@array/int_emu_cores"/>
- <CheckBoxPreference
- android:defaultValue="false"
- android:key="fastmemPref"
- android:summary="@string/fastmem_desc"
- android:title="@string/fastmem"/>
-
</PreferenceCategory>
<PreferenceCategory
@@ -569,6 +563,317 @@
</PreferenceScreen>
</PreferenceScreen>
+ <!-- Wiimote Bindings -->
+ <PreferenceScreen
+ android:key="wiimote_bindings"
+ android:title="@string/wiimote_bindings">
+
+ <PreferenceScreen
+ android:key="wiimote_bindings_4"
+ android:title="@string/controller_0">
+
+ <CheckBoxPreference
+ android:key="enableWiimote1"
+ android:title="@string/enable_wiimote"/>
+
+ <org.dolphinemu.dolphinemu.utils.InputBindingPreference
+ android:dependency="enableWiimote1"
+ android:key="WiimoteA_4"
+ android:summary="%s"
+ android:title="@string/button_a"/>
+
+ <org.dolphinemu.dolphinemu.utils.InputBindingPreference
+ android:dependency="enableWiimote1"
+ android:key="WiimoteB_4"
+ android:summary="%s"
+ android:title="@string/button_b"/>
+
+ <org.dolphinemu.dolphinemu.utils.InputBindingPreference
+ android:dependency="enableWiimote1"
+ android:key="WiimoteMinus_4"
+ android:summary="%s"
+ android:title="@string/button_minus"/>
+
+ <org.dolphinemu.dolphinemu.utils.InputBindingPreference
+ android:dependency="enableWiimote1"
+ android:key="WiimotePlus_4"
+ android:summary="%s"
+ android:title="@string/button_plus"/>
+
+ <org.dolphinemu.dolphinemu.utils.InputBindingPreference
+ android:dependency="enableWiimote1"
+ android:key="WiimoteHome_4"
+ android:summary="%s"
+ android:title="@string/button_home"/>
+
+ <org.dolphinemu.dolphinemu.utils.InputBindingPreference
+ android:dependency="enableWiimote1"
+ android:key="Wiimote1_4"
+ android:summary="%s"
+ android:title="@string/button_one"/>
+
+ <org.dolphinemu.dolphinemu.utils.InputBindingPreference
+ android:dependency="enableWiimote1"
+ android:key="Wiimote2_4"
+ android:summary="%s"
+ android:title="@string/button_two"/>
+
+ <org.dolphinemu.dolphinemu.utils.InputBindingPreference
+ android:dependency="enableWiimote1"
+ android:key="WiimoteUp_4"
+ android:summary="%s"
+ android:title="@string/dpad_up"/>
+
+ <org.dolphinemu.dolphinemu.utils.InputBindingPreference
+ android:dependency="enableWiimote1"
+ android:key="WiimoteDown_4"
+ android:summary="%s"
+ android:title="@string/dpad_down"/>
+
+ <org.dolphinemu.dolphinemu.utils.InputBindingPreference
+ android:dependency="enableWiimote1"
+ android:key="WiimoteLeft_4"
+ android:summary="%s"
+ android:title="@string/dpad_left"/>
+
+ <org.dolphinemu.dolphinemu.utils.InputBindingPreference
+ android:dependency="enableWiimote1"
+ android:key="WiimoteRight_4"
+ android:summary="%s"
+ android:title="@string/dpad_right"/>
+
+ </PreferenceScreen>
+
+ <PreferenceScreen
+ android:key="wiimote_bindings_5"
+ android:title="@string/controller_1">
+
+ <CheckBoxPreference
+ android:key="enableWiimote2"
+ android:title="@string/enable_wiimote"/>
+
+ <org.dolphinemu.dolphinemu.utils.InputBindingPreference
+ android:dependency="enableWiimote2"
+ android:key="WiimoteA_5"
+ android:summary="%s"
+ android:title="@string/button_a"/>
+
+ <org.dolphinemu.dolphinemu.utils.InputBindingPreference
+ android:dependency="enableWiimote2"
+ android:key="WiimoteB_5"
+ android:summary="%s"
+ android:title="@string/button_b"/>
+
+ <org.dolphinemu.dolphinemu.utils.InputBindingPreference
+ android:dependency="enableWiimote2"
+ android:key="WiimoteMinus_5"
+ android:summary="%s"
+ android:title="@string/button_minus"/>
+
+ <org.dolphinemu.dolphinemu.utils.InputBindingPreference
+ android:dependency="enableWiimote2"
+ android:key="WiimotePlus_5"
+ android:summary="%s"
+ android:title="@string/button_plus"/>
+
+ <org.dolphinemu.dolphinemu.utils.InputBindingPreference
+ android:dependency="enableWiimote2"
+ android:key="WiimoteHome_5"
+ android:summary="%s"
+ android:title="@string/button_home"/>
+
+ <org.dolphinemu.dolphinemu.utils.InputBindingPreference
+ android:dependency="enableWiimote2"
+ android:key="Wiimote2_5"
+ android:summary="%s"
+ android:title="@string/button_one"/>
+
+ <org.dolphinemu.dolphinemu.utils.InputBindingPreference
+ android:dependency="enableWiimote2"
+ android:key="Wiimote2_5"
+ android:summary="%s"
+ android:title="@string/button_two"/>
+
+ <org.dolphinemu.dolphinemu.utils.InputBindingPreference
+ android:dependency="enableWiimote2"
+ android:key="WiimoteUp_5"
+ android:summary="%s"
+ android:title="@string/dpad_up"/>
+
+ <org.dolphinemu.dolphinemu.utils.InputBindingPreference
+ android:dependency="enableWiimote2"
+ android:key="WiimoteDown_5"
+ android:summary="%s"
+ android:title="@string/dpad_down"/>
+
+ <org.dolphinemu.dolphinemu.utils.InputBindingPreference
+ android:dependency="enableWiimote2"
+ android:key="WiimoteLeft_5"
+ android:summary="%s"
+ android:title="@string/dpad_left"/>
+
+ <org.dolphinemu.dolphinemu.utils.InputBindingPreference
+ android:dependency="enableWiimote2"
+ android:key="WiimoteRight_5"
+ android:summary="%s"
+ android:title="@string/dpad_right"/>
+
+ </PreferenceScreen>
+
+ <PreferenceScreen
+ android:key="wiimote_bindings_6"
+ android:title="@string/controller_2">
+
+ <CheckBoxPreference
+ android:key="enableWiimote3"
+ android:title="@string/enable_wiimote"/>
+
+ <org.dolphinemu.dolphinemu.utils.InputBindingPreference
+ android:dependency="enableWiimote3"
+ android:key="WiimoteA_6"
+ android:summary="%s"
+ android:title="@string/button_a"/>
+
+ <org.dolphinemu.dolphinemu.utils.InputBindingPreference
+ android:dependency="enableWiimote3"
+ android:key="WiimoteB_6"
+ android:summary="%s"
+ android:title="@string/button_b"/>
+
+ <org.dolphinemu.dolphinemu.utils.InputBindingPreference
+ android:dependency="enableWiimote3"
+ android:key="WiimoteMinus_6"
+ android:summary="%s"
+ android:title="@string/button_minus"/>
+
+ <org.dolphinemu.dolphinemu.utils.InputBindingPreference
+ android:dependency="enableWiimote3"
+ android:key="WiimotePlus_6"
+ android:summary="%s"
+ android:title="@string/button_plus"/>
+
+ <org.dolphinemu.dolphinemu.utils.InputBindingPreference
+ android:dependency="enableWiimote3"
+ android:key="WiimoteHome_6"
+ android:summary="%s"
+ android:title="@string/button_home"/>
+
+ <org.dolphinemu.dolphinemu.utils.InputBindingPreference
+ android:dependency="enableWiimote3"
+ android:key="Wiimote3_6"
+ android:summary="%s"
+ android:title="@string/button_one"/>
+
+ <org.dolphinemu.dolphinemu.utils.InputBindingPreference
+ android:dependency="enableWiimote3"
+ android:key="Wiimote2_6"
+ android:summary="%s"
+ android:title="@string/button_two"/>
+
+ <org.dolphinemu.dolphinemu.utils.InputBindingPreference
+ android:dependency="enableWiimote3"
+ android:key="WiimoteUp_6"
+ android:summary="%s"
+ android:title="@string/dpad_up"/>
+
+ <org.dolphinemu.dolphinemu.utils.InputBindingPreference
+ android:dependency="enableWiimote3"
+ android:key="WiimoteDown_6"
+ android:summary="%s"
+ android:title="@string/dpad_down"/>
+
+ <org.dolphinemu.dolphinemu.utils.InputBindingPreference
+ android:dependency="enableWiimote3"
+ android:key="WiimoteLeft_6"
+ android:summary="%s"
+ android:title="@string/dpad_left"/>
+
+ <org.dolphinemu.dolphinemu.utils.InputBindingPreference
+ android:dependency="enableWiimote3"
+ android:key="WiimoteRight_6"
+ android:summary="%s"
+ android:title="@string/dpad_right"/>
+
+ </PreferenceScreen>
+
+ <PreferenceScreen
+ android:key="wiimote_bindings_7"
+ android:title="@string/controller_3">
+
+ <CheckBoxPreference
+ android:key="enableWiimote4"
+ android:title="@string/enable_wiimote"/>
+
+ <org.dolphinemu.dolphinemu.utils.InputBindingPreference
+ android:dependency="enableWiimote4"
+ android:key="WiimoteA_7"
+ android:summary="%s"
+ android:title="@string/button_a"/>
+
+ <org.dolphinemu.dolphinemu.utils.InputBindingPreference
+ android:dependency="enableWiimote4"
+ android:key="WiimoteB_7"
+ android:summary="%s"
+ android:title="@string/button_b"/>
+
+ <org.dolphinemu.dolphinemu.utils.InputBindingPreference
+ android:dependency="enableWiimote4"
+ android:key="WiimoteMinus_7"
+ android:summary="%s"
+ android:title="@string/button_minus"/>
+
+ <org.dolphinemu.dolphinemu.utils.InputBindingPreference
+ android:dependency="enableWiimote4"
+ android:key="WiimotePlus_7"
+ android:summary="%s"
+ android:title="@string/button_plus"/>
+
+ <org.dolphinemu.dolphinemu.utils.InputBindingPreference
+ android:dependency="enableWiimote4"
+ android:key="WiimoteHome_7"
+ android:summary="%s"
+ android:title="@string/button_home"/>
+
+ <org.dolphinemu.dolphinemu.utils.InputBindingPreference
+ android:dependency="enableWiimote4"
+ android:key="Wiimote4_7"
+ android:summary="%s"
+ android:title="@string/button_one"/>
+
+ <org.dolphinemu.dolphinemu.utils.InputBindingPreference
+ android:dependency="enableWiimote4"
+ android:key="Wiimote2_7"
+ android:summary="%s"
+ android:title="@string/button_two"/>
+
+ <org.dolphinemu.dolphinemu.utils.InputBindingPreference
+ android:dependency="enableWiimote4"
+ android:key="WiimoteUp_7"
+ android:summary="%s"
+ android:title="@string/dpad_up"/>
+
+ <org.dolphinemu.dolphinemu.utils.InputBindingPreference
+ android:dependency="enableWiimote4"
+ android:key="WiimoteDown_7"
+ android:summary="%s"
+ android:title="@string/dpad_down"/>
+
+ <org.dolphinemu.dolphinemu.utils.InputBindingPreference
+ android:dependency="enableWiimote4"
+ android:key="WiimoteLeft_7"
+ android:summary="%s"
+ android:title="@string/dpad_left"/>
+
+ <org.dolphinemu.dolphinemu.utils.InputBindingPreference
+ android:dependency="enableWiimote4"
+ android:key="WiimoteRight_7"
+ android:summary="%s"
+ android:title="@string/dpad_right"/>
+
+ </PreferenceScreen>
+
+ </PreferenceScreen>
+
</PreferenceCategory>
<PreferenceCategory
@@ -720,12 +1025,6 @@
<PreferenceCategory android:title="@string/other">
<CheckBoxPreference
- android:defaultValue="false"
- android:key="disableDestinationAlpha"
- android:summary="@string/disable_destination_alpha_descrip"
- android:title="@string/disable_destination_alpha"/>
-
- <CheckBoxPreference
android:defaultValue="true"
android:key="fastDepthCalculation"
android:summary="@string/fast_depth_calculation_descrip"
@@ -755,4 +1054,4 @@
</PreferenceCategory>
<!-- TODO Add the About information here too. -->
-</PreferenceScreen> \ No newline at end of file
+</PreferenceScreen>
diff --git a/Source/Android/gradle/wrapper/gradle-wrapper.jar b/Source/Android/gradle/wrapper/gradle-wrapper.jar
new file mode 100644
index 0000000000..8c0fb64a86
--- /dev/null
+++ b/Source/Android/gradle/wrapper/gradle-wrapper.jar
Binary files differ
diff --git a/Source/Android/gradle/wrapper/gradle-wrapper.properties b/Source/Android/gradle/wrapper/gradle-wrapper.properties
new file mode 100644
index 0000000000..0c71e760dc
--- /dev/null
+++ b/Source/Android/gradle/wrapper/gradle-wrapper.properties
@@ -0,0 +1,6 @@
+#Wed Apr 10 15:27:10 PDT 2013
+distributionBase=GRADLE_USER_HOME
+distributionPath=wrapper/dists
+zipStoreBase=GRADLE_USER_HOME
+zipStorePath=wrapper/dists
+distributionUrl=https\://services.gradle.org/distributions/gradle-2.2.1-all.zip