diff options
| author | Linktothepast <kostamarino@gmail.com> | 2015-09-28 16:50:35 +0300 |
|---|---|---|
| committer | Linktothepast <kostamarino@gmail.com> | 2015-09-28 16:50:35 +0300 |
| commit | 748be565b8df535ef558e74b38cd0f4d615f8a21 (patch) | |
| tree | b151efee0a87e99125f2401325a9bddecf84fc73 /Source/Android | |
| parent | cf17fccdd3093a1b8476b10183b1c4bde36da74d (diff) | |
| parent | ce493b897d6d3735c930a8465cc0c26bbe5feb86 (diff) | |
Merge remote-tracking branch 'dolphin-emu/master' into gameinis
Diffstat (limited to 'Source/Android')
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 Binary files differnew file mode 100644 index 0000000000..7332c75727 --- /dev/null +++ b/Source/Android/app/src/main/res/drawable/ic_add_tv.png 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 Binary files differnew file mode 100644 index 0000000000..8bae5d34ab --- /dev/null +++ b/Source/Android/app/src/main/res/drawable/ic_refresh_tv.png 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 Binary files differnew file mode 100644 index 0000000000..9e242e7748 --- /dev/null +++ b/Source/Android/app/src/main/res/drawable/ic_settings_tv.png 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 Binary files differnew file mode 100644 index 0000000000..8c0fb64a86 --- /dev/null +++ b/Source/Android/gradle/wrapper/gradle-wrapper.jar 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 |
