diff --git a/Source/Android/app/src/main/assets/WiimoteNew.ini b/Source/Android/app/src/main/assets/WiimoteNew.ini index abead1e196..9fcbad5130 100644 --- a/Source/Android/app/src/main/assets/WiimoteNew.ini +++ b/Source/Android/app/src/main/assets/WiimoteNew.ini @@ -33,7 +33,7 @@ Tilt/Modifier/Range = 50,000000 Shake/X = `Button 132` Shake/Y = `Button 133` Shake/Z = `Button 134` -Extension = None +Extension = Nunchuk Nunchuk/Buttons/C = `Button 200` Nunchuk/Buttons/Z = `Button 201` Nunchuk/Stick/Up = `Axis 203` 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 822b41b11d..7aa2800ea4 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 @@ -2,13 +2,17 @@ package org.dolphinemu.dolphinemu.activities; import android.app.Activity; import android.app.ActivityOptions; +import android.app.AlertDialog; import android.app.Fragment; import android.content.Context; +import android.content.DialogInterface; import android.content.Intent; +import android.content.SharedPreferences; import android.hardware.usb.UsbManager; import android.os.Bundle; import android.os.Handler; import android.os.Message; +import android.preference.PreferenceManager; import android.support.v7.app.AppCompatActivity; import android.view.InputDevice; import android.view.KeyEvent; @@ -48,6 +52,8 @@ public final class EmulationActivity extends AppCompatActivity private String mSubmenuFragmentTag; + private SharedPreferences mPreferences; + // So that MainActivity knows which view to invalidate before the return animation. private int mPosition; @@ -55,6 +61,8 @@ public final class EmulationActivity extends AppCompatActivity private boolean mSystemUiVisible; private boolean mMenuVisible; + private static boolean mIsGameCubeGame; + /** * Handlers are a way to pass a message to an Activity telling it to do something * on the UI thread. This Handler responds to any message, even blank ones, by @@ -209,6 +217,10 @@ public final class EmulationActivity extends AppCompatActivity menuFragment.setTitleText(mSelectedTitle); } } + + mPreferences = PreferenceManager.getDefaultSharedPreferences(this); + + mIsGameCubeGame = (NativeLibrary.GetPlatform(path) == 0); } @Override @@ -383,13 +395,92 @@ public final class EmulationActivity extends AppCompatActivity { switch (id) { - // Enable/Disable input overlay. + // Enable/Disable specific buttons or the entire input overlay. case R.id.menu_emulation_input_overlay: { - EmulationFragment emulationFragment = (EmulationFragment) getFragmentManager() - .findFragmentByTag(EmulationFragment.FRAGMENT_TAG); + boolean[] enabledButtons = new boolean[11]; + AlertDialog.Builder builder = new AlertDialog.Builder(this); + builder.setTitle(R.string.emulation_toggle_input); + if (mIsGameCubeGame) + { + for (int i = 0; i < enabledButtons.length; i++) + { + enabledButtons[i] = mPreferences.getBoolean("buttonToggleGc" + i, true); + } + builder.setMultiChoiceItems(R.array.gcpadButtons, enabledButtons, + new DialogInterface.OnMultiChoiceClickListener() + { + @Override + public void onClick(DialogInterface dialog, int indexSelected, boolean isChecked) + { + SharedPreferences.Editor editor = mPreferences.edit(); - emulationFragment.toggleInputOverlayVisibility(); + if (mPreferences.getBoolean("buttonToggleGc" + indexSelected, true)) + { + // If the button is enabled, disable it. + editor.putBoolean("buttonToggleGc" + indexSelected, false); + } + else + { + // If the button is disabled, enable it. + editor.putBoolean("buttonToggleGc" + indexSelected, true); + } + editor.apply(); + } + }); + } + else + { + for (int i = 0; i < enabledButtons.length; i++) + { + enabledButtons[i] = mPreferences.getBoolean("buttonToggleWii" + i, true); + } + builder.setMultiChoiceItems(R.array.wiimoteButtons, enabledButtons, + new DialogInterface.OnMultiChoiceClickListener() + { + @Override + public void onClick(DialogInterface dialog, int indexSelected, boolean isChecked) + { + SharedPreferences.Editor editor = mPreferences.edit(); + + if (mPreferences.getBoolean("buttonToggleWii" + indexSelected, true)) + { + // If the button is enabled, disable it. + editor.putBoolean("buttonToggleWii" + indexSelected, false); + } + else + { + // If the button is disabled, enable it. + editor.putBoolean("buttonToggleWii" + indexSelected, true); + } + + editor.apply(); + } + }); + } + builder.setNeutralButton(getString(R.string.emulation_toggle_all), new DialogInterface.OnClickListener() + { + @Override + public void onClick(DialogInterface dialogInterface, int i) + { + EmulationFragment emulationFragment = (EmulationFragment) getFragmentManager() + .findFragmentByTag(EmulationFragment.FRAGMENT_TAG); + emulationFragment.toggleInputOverlayVisibility(); + } + }); + builder.setPositiveButton(getString(R.string.emulation_done), new DialogInterface.OnClickListener() + { + @Override + public void onClick(DialogInterface dialogInterface, int i) + { + EmulationFragment emulationFragment = (EmulationFragment) getFragmentManager() + .findFragmentByTag(EmulationFragment.FRAGMENT_TAG); + emulationFragment.refreshInputOverlay(); + } + }); + + AlertDialog alertDialog = builder.create(); + alertDialog.show(); return; } @@ -667,6 +758,11 @@ public final class EmulationActivity extends AppCompatActivity return mSelectedTitle; } + public static boolean isGameCubeGame() + { + return mIsGameCubeGame; + } + public static void launch(Activity activity, String path, String title, String screenshotPath, int position, View sharedView) { Intent launcher = new Intent(activity, EmulationActivity.class); 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 56a8b60c46..b70196a773 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 @@ -162,6 +162,11 @@ public final class EmulationFragment extends Fragment implements SurfaceHolder.C editor.apply(); } + public void refreshInputOverlay() + { + mInputOverlay.refreshControls(); + } + @Override public void surfaceCreated(SurfaceHolder holder) { diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/overlay/InputOverlay.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/overlay/InputOverlay.java index 8e296c4efb..5b90b43b6a 100644 --- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/overlay/InputOverlay.java +++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/overlay/InputOverlay.java @@ -26,6 +26,7 @@ import org.dolphinemu.dolphinemu.NativeLibrary; import org.dolphinemu.dolphinemu.NativeLibrary.ButtonState; import org.dolphinemu.dolphinemu.NativeLibrary.ButtonType; import org.dolphinemu.dolphinemu.R; +import org.dolphinemu.dolphinemu.activities.EmulationActivity; import java.util.HashSet; import java.util.Set; @@ -37,12 +38,16 @@ import java.util.Set; public final class InputOverlay extends SurfaceView implements OnTouchListener { private final Set overlayButtons = new HashSet<>(); + private final Set overlayDpads = new HashSet<>(); private final Set overlayJoysticks = new HashSet<>(); private boolean mIsInEditMode = false; private InputOverlayDrawableButton mButtonBeingConfigured; + private InputOverlayDrawableDpad mDpadBeingConfigured; private InputOverlayDrawableJoystick mJoystickBeingConfigured; + private SharedPreferences mPreferences; + /** * Resizes a {@link Bitmap} by a given scale factor * @@ -75,18 +80,10 @@ public final class InputOverlay extends SurfaceView implements OnTouchListener { super(context, attrs); - // Add all the overlay items to the HashSet. - overlayButtons.add(initializeOverlayButton(context, R.drawable.gcpad_a, ButtonType.BUTTON_A)); - overlayButtons.add(initializeOverlayButton(context, R.drawable.gcpad_b, ButtonType.BUTTON_B)); - overlayButtons.add(initializeOverlayButton(context, R.drawable.gcpad_x, ButtonType.BUTTON_X)); - overlayButtons.add(initializeOverlayButton(context, R.drawable.gcpad_y, ButtonType.BUTTON_Y)); - overlayButtons.add(initializeOverlayButton(context, R.drawable.gcpad_z, ButtonType.BUTTON_Z)); - overlayButtons.add(initializeOverlayButton(context, R.drawable.gcpad_start, ButtonType.BUTTON_START)); - overlayButtons.add(initializeOverlayButton(context, R.drawable.gcpad_l, ButtonType.TRIGGER_L)); - overlayButtons.add(initializeOverlayButton(context, R.drawable.gcpad_r, ButtonType.TRIGGER_R)); - overlayJoysticks.add(initializeOverlayJoystick(context, - R.drawable.gcpad_joystick_range, R.drawable.gcpad_joystick, - ButtonType.STICK_MAIN)); + mPreferences = PreferenceManager.getDefaultSharedPreferences(getContext()); + + // Load the controls. + refreshControls(); // Set the on touch listener. setOnTouchListener(this); @@ -108,6 +105,11 @@ public final class InputOverlay extends SurfaceView implements OnTouchListener button.draw(canvas); } + for (InputOverlayDrawableDpad dpad : overlayDpads) + { + dpad.draw(canvas); + } + for (InputOverlayDrawableJoystick joystick: overlayJoysticks) { joystick.draw(canvas); @@ -149,6 +151,48 @@ public final class InputOverlay extends SurfaceView implements OnTouchListener } } + for (InputOverlayDrawableDpad dpad : overlayDpads) + { + // Determine the button state to apply based on the MotionEvent action flag. + switch (event.getAction() & MotionEvent.ACTION_MASK) + { + case MotionEvent.ACTION_DOWN: + case MotionEvent.ACTION_POINTER_DOWN: + case MotionEvent.ACTION_MOVE: + // If a pointer enters the bounds of a button, press that button. + if (dpad.getBounds().contains((int)event.getX(pointerIndex), (int)event.getY(pointerIndex))) + { + if (dpad.getBounds().top + (dpad.getIntrinsicHeight() / 3) > (int)event.getY(pointerIndex)) + { + NativeLibrary.onGamePadEvent(NativeLibrary.TouchScreenDevice, dpad.getId(0), ButtonState.PRESSED); + } + if (dpad.getBounds().bottom - (dpad.getIntrinsicHeight() / 3) < (int)event.getY(pointerIndex)) + { + NativeLibrary.onGamePadEvent(NativeLibrary.TouchScreenDevice, dpad.getId(1), ButtonState.PRESSED); + } + if (dpad.getBounds().left + (dpad.getIntrinsicWidth() / 3) > (int)event.getX(pointerIndex)) + { + NativeLibrary.onGamePadEvent(NativeLibrary.TouchScreenDevice, dpad.getId(2), ButtonState.PRESSED); + } + if (dpad.getBounds().right - (dpad.getIntrinsicWidth() / 3) < (int)event.getX(pointerIndex)) + { + NativeLibrary.onGamePadEvent(NativeLibrary.TouchScreenDevice, dpad.getId(3), ButtonState.PRESSED); + } + } + break; + case MotionEvent.ACTION_UP: + case MotionEvent.ACTION_POINTER_UP: + // If a pointer ends, release the buttons. + if (dpad.getBounds().contains((int)event.getX(pointerIndex), (int)event.getY(pointerIndex))) + { + for(int i = 0; i < 4; i++) + { + NativeLibrary.onGamePadEvent(NativeLibrary.TouchScreenDevice, dpad.getId(i), ButtonState.RELEASED); + } + } + break; + } + } for (InputOverlayDrawableJoystick joystick : overlayJoysticks) { @@ -202,13 +246,47 @@ public final class InputOverlay extends SurfaceView implements OnTouchListener if (mButtonBeingConfigured == button) { //Persist button position by saving new place. - saveControlPosition(mButtonBeingConfigured.getSharedPrefsId(), mButtonBeingConfigured.getBounds().left, mButtonBeingConfigured.getBounds().top); + saveControlPosition(mButtonBeingConfigured.getId(), mButtonBeingConfigured.getBounds().left, mButtonBeingConfigured.getBounds().top); mButtonBeingConfigured = null; } break; } } + for (InputOverlayDrawableDpad dpad : overlayDpads) + { + // Determine the button state to apply based on the MotionEvent action flag. + switch (event.getAction() & MotionEvent.ACTION_MASK) + { + case MotionEvent.ACTION_DOWN: + case MotionEvent.ACTION_POINTER_DOWN: + // If no button is being moved now, remember the currently touched button to move. + if (mButtonBeingConfigured == null && dpad.getBounds().contains(fingerPositionX, fingerPositionY)) + { + mDpadBeingConfigured = dpad; + mDpadBeingConfigured.onConfigureTouch(v, event); + } + break; + case MotionEvent.ACTION_MOVE: + if (mDpadBeingConfigured != null) + { + mDpadBeingConfigured.onConfigureTouch(v, event); + invalidate(); + return true; + } + break; + + case MotionEvent.ACTION_UP: + case MotionEvent.ACTION_POINTER_UP: + if (mDpadBeingConfigured == dpad) + { + //Persist button position by saving new place. + saveControlPosition(mDpadBeingConfigured.getId(0), mDpadBeingConfigured.getBounds().left, mDpadBeingConfigured.getBounds().top); + mDpadBeingConfigured = null; + } + break; + } + } for (InputOverlayDrawableJoystick joystick : overlayJoysticks) { @@ -233,7 +311,7 @@ public final class InputOverlay extends SurfaceView implements OnTouchListener case MotionEvent.ACTION_POINTER_UP: if (mJoystickBeingConfigured != null) { - saveControlPosition(mJoystickBeingConfigured.getSharedPrefsId(), mJoystickBeingConfigured.getBounds().left, mJoystickBeingConfigured.getBounds().top); + saveControlPosition(mJoystickBeingConfigured.getId(), mJoystickBeingConfigured.getBounds().left, mJoystickBeingConfigured.getBounds().top); mJoystickBeingConfigured = null; } break; @@ -245,7 +323,125 @@ public final class InputOverlay extends SurfaceView implements OnTouchListener return true; } - private void saveControlPosition(String sharedPrefsId, int x, int y) + public void refreshControls() + { + // Remove all the overlay buttons from the HashSet. + overlayButtons.removeAll(overlayButtons); + overlayDpads.removeAll(overlayDpads); + overlayJoysticks.removeAll(overlayJoysticks); + + // Add all the enabled overlay items back to the HashSet. + if (EmulationActivity.isGameCubeGame()) + { + // GameCube + if (mPreferences.getBoolean("buttonToggleGc0", true)) + { + overlayButtons.add(initializeOverlayButton(getContext(), R.drawable.gcpad_a, ButtonType.BUTTON_A)); + } + if (mPreferences.getBoolean("buttonToggleGc1", true)) + { + overlayButtons.add(initializeOverlayButton(getContext(), R.drawable.gcpad_b, ButtonType.BUTTON_B)); + } + if (mPreferences.getBoolean("buttonToggleGc2", true)) + { + overlayButtons.add(initializeOverlayButton(getContext(), R.drawable.gcpad_x, ButtonType.BUTTON_X)); + } + if (mPreferences.getBoolean("buttonToggleGc3", true)) + { + overlayButtons.add(initializeOverlayButton(getContext(), R.drawable.gcpad_y, ButtonType.BUTTON_Y)); + } + if (mPreferences.getBoolean("buttonToggleGc4", true)) + { + overlayButtons.add(initializeOverlayButton(getContext(), R.drawable.gcpad_z, ButtonType.BUTTON_Z)); + } + if (mPreferences.getBoolean("buttonToggleGc5", true)) + { + overlayButtons.add(initializeOverlayButton(getContext(), R.drawable.gcpad_start, ButtonType.BUTTON_START)); + } + if (mPreferences.getBoolean("buttonToggleGc6", true)) + { + overlayButtons.add(initializeOverlayButton(getContext(), R.drawable.gcpad_l, ButtonType.TRIGGER_L)); + } + if (mPreferences.getBoolean("buttonToggleGc7", true)) + { + overlayButtons.add(initializeOverlayButton(getContext(), R.drawable.gcpad_r, ButtonType.TRIGGER_R)); + } + if (mPreferences.getBoolean("buttonToggleGc8", true)) + { + overlayDpads.add(initializeOverlayDpad(getContext(), R.drawable.gcwii_dpad, + ButtonType.BUTTON_UP, ButtonType.BUTTON_DOWN, + ButtonType.BUTTON_LEFT, ButtonType.BUTTON_RIGHT)); + } + if (mPreferences.getBoolean("buttonToggleGc9", true)) + { + overlayJoysticks.add(initializeOverlayJoystick(getContext(), + R.drawable.gcwii_joystick_range, R.drawable.gcwii_joystick, + ButtonType.STICK_MAIN)); + } + if (mPreferences.getBoolean("buttonToggleGc10", true)) + { + overlayJoysticks.add(initializeOverlayJoystick(getContext(), + R.drawable.gcwii_joystick_range, R.drawable.gcpad_c, + ButtonType.STICK_C)); + } + } + else + { + // Wiimote + Nunchuk + if (mPreferences.getBoolean("buttonToggleWii0", true)) + { + overlayButtons.add(initializeOverlayButton(getContext(), R.drawable.wiimote_a, ButtonType.WIIMOTE_BUTTON_A)); + } + if (mPreferences.getBoolean("buttonToggleWii1", true)) + { + overlayButtons.add(initializeOverlayButton(getContext(), R.drawable.wiimote_b, ButtonType.WIIMOTE_BUTTON_B)); + } + if (mPreferences.getBoolean("buttonToggleWii2", true)) + { + overlayButtons.add(initializeOverlayButton(getContext(), R.drawable.wiimote_one, ButtonType.WIIMOTE_BUTTON_1)); + } + if (mPreferences.getBoolean("buttonToggleWii3", true)) + { + overlayButtons.add(initializeOverlayButton(getContext(), R.drawable.wiimote_two, ButtonType.WIIMOTE_BUTTON_2)); + } + if (mPreferences.getBoolean("buttonToggleWii4", true)) + { + overlayButtons.add(initializeOverlayButton(getContext(), R.drawable.wiimote_plus, ButtonType.WIIMOTE_BUTTON_PLUS)); + } + if (mPreferences.getBoolean("buttonToggleWii5", true)) + { + overlayButtons.add(initializeOverlayButton(getContext(), R.drawable.wiimote_minus, ButtonType.WIIMOTE_BUTTON_MINUS)); + } + if (mPreferences.getBoolean("buttonToggleWii6", true)) + { + overlayButtons.add(initializeOverlayButton(getContext(), R.drawable.wiimote_home, ButtonType.WIIMOTE_BUTTON_HOME)); + } + if (mPreferences.getBoolean("buttonToggleWii7", true)) + { + overlayButtons.add(initializeOverlayButton(getContext(), R.drawable.nunchuk_c, ButtonType.NUNCHUK_BUTTON_C)); + } + if (mPreferences.getBoolean("buttonToggleWii8", true)) + { + overlayButtons.add(initializeOverlayButton(getContext(), R.drawable.nunchuk_z, ButtonType.NUNCHUK_BUTTON_Z)); + } + if (mPreferences.getBoolean("buttonToggleWii9", true)) + { + overlayDpads.add(initializeOverlayDpad(getContext(), R.drawable.gcwii_dpad, + ButtonType.WIIMOTE_UP, ButtonType.WIIMOTE_DOWN, + ButtonType.WIIMOTE_LEFT, ButtonType.WIIMOTE_RIGHT)); + } + if (mPreferences.getBoolean("buttonToggleWii10", true)) + { + overlayJoysticks.add(initializeOverlayJoystick(getContext(), + R.drawable.gcwii_joystick_range, R.drawable.gcwii_joystick, + ButtonType.NUNCHUK_STICK)); + } + } + + invalidate(); + } + + private void saveControlPosition(int sharedPrefsId, int x, int y) { final SharedPreferences sPrefs = PreferenceManager.getDefaultSharedPreferences(getContext()); SharedPreferences.Editor sPrefsEditor = sPrefs.edit(); @@ -295,38 +491,48 @@ public final class InputOverlay extends SurfaceView implements OnTouchListener // Decide scale based on button ID float scale; - float overlaySize = sPrefs.getInt("controls_size", 25); - overlaySize += 25; - overlaySize /= 50; - switch (resId) + switch (buttonId) { - case R.drawable.gcpad_b: - scale = 0.13f * overlaySize; + case ButtonType.BUTTON_A: + case ButtonType.WIIMOTE_BUTTON_B: + case ButtonType.NUNCHUK_BUTTON_Z: + scale = 0.2f; break; - case R.drawable.gcpad_x: - case R.drawable.gcpad_y: - scale = 0.18f * overlaySize; + case ButtonType.BUTTON_X: + case ButtonType.BUTTON_Y: + scale = 0.175f; break; - case R.drawable.gcpad_start: - scale = 0.12f * overlaySize; + case ButtonType.BUTTON_Z: + case ButtonType.TRIGGER_L: + case ButtonType.TRIGGER_R: + scale = 0.22f; + break; + case ButtonType.BUTTON_START: + scale = 0.075f; + break; + case ButtonType.WIIMOTE_BUTTON_1: + case ButtonType.WIIMOTE_BUTTON_2: + scale = 0.0875f; + break; + case ButtonType.WIIMOTE_BUTTON_PLUS: + case ButtonType.WIIMOTE_BUTTON_MINUS: + case ButtonType.WIIMOTE_BUTTON_HOME: + scale = 0.0625f; break; default: - scale = 0.20f * overlaySize; + scale = 0.125f; break; } // Initialize the InputOverlayDrawableButton. final Bitmap bitmap = resizeBitmap(context, BitmapFactory.decodeResource(res, resId), scale); - // String ID of the Drawable. This is what is passed into SharedPreferences - // to check whether or not a value has been set. Send to button so it can be referenced. - final String drawableId = res.getResourceEntryName(resId); - final InputOverlayDrawableButton overlayDrawable = new InputOverlayDrawableButton(res, bitmap, buttonId, drawableId); + final InputOverlayDrawableButton overlayDrawable = new InputOverlayDrawableButton(res, bitmap, buttonId); // The X and Y coordinates of the InputOverlayDrawableButton on the InputOverlay. // These were set in the input overlay configuration menu. - int drawableX = (int) sPrefs.getFloat(drawableId+"-X", 0f); - int drawableY = (int) sPrefs.getFloat(drawableId+"-Y", 0f); + int drawableX = (int) sPrefs.getFloat(buttonId+"-X", 0f); + int drawableY = (int) sPrefs.getFloat(buttonId+"-Y", 0f); // Intrinsic width and height of the InputOverlayDrawableButton. // For any who may not know, intrinsic width/height @@ -344,6 +550,70 @@ public final class InputOverlay extends SurfaceView implements OnTouchListener return overlayDrawable; } + /** + * Initializes an {@link InputOverlayDrawableDpad} + * + * @param context The current {@link Context}. + * @param resId The resource ID of the {@link Drawable} to get the {@link Bitmap} of. + * @param buttonUp Identifier for the up button. + * @param buttonDown Identifier for the down button. + * @param buttonLeft Identifier for the left button. + * @param buttonRight Identifier for the right button. + * + * @return the initialized {@link InputOverlayDrawableDpad} + */ + private static InputOverlayDrawableDpad initializeOverlayDpad(Context context, int resId, + int buttonUp, int buttonDown, + int buttonLeft, int buttonRight) + { + // Resources handle for fetching the initial Drawable resource. + final Resources res = context.getResources(); + + // SharedPreference to retrieve the X and Y coordinates for the InputOverlayDrawableDpad. + final SharedPreferences sPrefs = PreferenceManager.getDefaultSharedPreferences(context); + + // Decide scale based on button ID + float scale; + + switch (buttonUp) + { + case ButtonType.BUTTON_UP: + scale = 0.2375f; + break; + case ButtonType.WIIMOTE_UP: + scale = 0.2125f; + break; + default: + scale = 0.275f; + break; + } + + // Initialize the InputOverlayDrawableDpad. + final Bitmap bitmap = resizeBitmap(context, BitmapFactory.decodeResource(res, resId), scale); + final InputOverlayDrawableDpad overlayDrawable = new InputOverlayDrawableDpad(res, bitmap, + buttonUp, buttonDown, buttonLeft, buttonRight); + + // The X and Y coordinates of the InputOverlayDrawableDpad on the InputOverlay. + // These were set in the input overlay configuration menu. + int drawableX = (int) sPrefs.getFloat(buttonUp+"-X", 0f); + int drawableY = (int) sPrefs.getFloat(buttonUp+"-Y", 0f); + + // Intrinsic width and height of the InputOverlayDrawableDpad. + // For any who may not know, intrinsic width/height + // are the original unmodified width and height of the image. + int intrinWidth = overlayDrawable.getIntrinsicWidth(); + int intrinHeight = overlayDrawable.getIntrinsicHeight(); + + // Now set the bounds for the InputOverlayDrawableDpad. + // This will dictate where on the screen (and the what the size) the InputOverlayDrawableDpad will be. + overlayDrawable.setBounds(drawableX, drawableY, drawableX+intrinWidth, drawableY+intrinHeight); + + // Need to set the image's position + overlayDrawable.setPosition(drawableX, drawableY); + + return overlayDrawable; + } + /** * Initializes an {@link InputOverlayDrawableJoystick} * @@ -363,33 +633,39 @@ public final class InputOverlay extends SurfaceView implements OnTouchListener final SharedPreferences sPrefs = PreferenceManager.getDefaultSharedPreferences(context); // Initialize the InputOverlayDrawableJoystick. - float overlaySize = sPrefs.getInt("controls_size", 20); - overlaySize += 30; - overlaySize /= 50; - final Bitmap bitmapOuter = resizeBitmap(context, BitmapFactory.decodeResource(res, resOuter), 0.30f * overlaySize); + final Bitmap bitmapOuter = resizeBitmap(context, BitmapFactory.decodeResource(res, resOuter), 0.275f); final Bitmap bitmapInner = BitmapFactory.decodeResource(res, resInner); - // String ID of the Drawable. This is what is passed into SharedPreferences - // to check whether or not a value has been set. - final String drawableId = res.getResourceEntryName(resOuter); - // The X and Y coordinates of the InputOverlayDrawableButton on the InputOverlay. // These were set in the input overlay configuration menu. - int drawableX = (int) sPrefs.getFloat(drawableId+"-X", 0f); - int drawableY = (int) sPrefs.getFloat(drawableId+"-Y", 0f); + int drawableX = (int) sPrefs.getFloat(joystick+"-X", 0f); + int drawableY = (int) sPrefs.getFloat(joystick+"-Y", 0f); + + // Decide inner scale based on joystick ID + float scale; + + switch (joystick) + { + case ButtonType.STICK_C: + scale = 1.833f; + break; + default: + scale = 1.375f; + break; + } // Now set the bounds for the InputOverlayDrawableJoystick. // This will dictate where on the screen (and the what the size) the InputOverlayDrawableJoystick will be. int outerSize = bitmapOuter.getWidth(); Rect outerRect = new Rect(drawableX, drawableY, drawableX + outerSize, drawableY + outerSize); - Rect innerRect = new Rect(0, 0, outerSize / 4, outerSize / 4); + Rect innerRect = new Rect(0, 0, (int) (outerSize / scale), (int) (outerSize / scale)); // Send the drawableId to the joystick so it can be referenced when saving control position. final InputOverlayDrawableJoystick overlayDrawable = new InputOverlayDrawableJoystick(res, bitmapOuter, bitmapInner, outerRect, innerRect, - joystick, drawableId); + joystick); // Need to set the image's position overlayDrawable.setPosition(drawableX, drawableY); diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/overlay/InputOverlayDrawableButton.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/overlay/InputOverlayDrawableButton.java index add3cf4621..8601756faa 100644 --- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/overlay/InputOverlayDrawableButton.java +++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/overlay/InputOverlayDrawableButton.java @@ -23,7 +23,6 @@ public final class InputOverlayDrawableButton extends BitmapDrawable private int mButtonType; private int mPreviousTouchX, mPreviousTouchY; private int mControlPositionX, mControlPositionY; - private String mSharedPrefsId; /** * Constructor @@ -31,13 +30,11 @@ public final class InputOverlayDrawableButton extends BitmapDrawable * @param res {@link Resources} instance. * @param bitmap {@link Bitmap} to use with this Drawable. * @param buttonType Identifier for this type of button. - * @param sharedPrefsId Identifier for getting X and Y control positions from Shared Preferences. */ - public InputOverlayDrawableButton(Resources res, Bitmap bitmap, int buttonType, String sharedPrefsId) + public InputOverlayDrawableButton(Resources res, Bitmap bitmap, int buttonType) { super(res, bitmap); mButtonType = buttonType; - mSharedPrefsId = sharedPrefsId; } /** @@ -73,11 +70,6 @@ public final class InputOverlayDrawableButton extends BitmapDrawable return true; } - public String getSharedPrefsId() - { - return mSharedPrefsId; - } - public void setPosition(int x, int y) { mControlPositionX = x; diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/overlay/InputOverlayDrawableDpad.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/overlay/InputOverlayDrawableDpad.java new file mode 100644 index 0000000000..7c1584e529 --- /dev/null +++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/overlay/InputOverlayDrawableDpad.java @@ -0,0 +1,86 @@ +/** + * Copyright 2016 Dolphin Emulator Project + * Licensed under GPLv2+ + * Refer to the license.txt file included. + */ + +package org.dolphinemu.dolphinemu.overlay; + +import android.content.res.Resources; +import android.graphics.Bitmap; +import android.graphics.Rect; +import android.graphics.drawable.BitmapDrawable; +import android.view.MotionEvent; +import android.view.View; + +/** + * Custom {@link BitmapDrawable} that is capable + * of storing it's own ID. + */ +public final class InputOverlayDrawableDpad extends BitmapDrawable +{ + // The ID identifying what type of button this Drawable represents. + private int[] mButtonType = new int[4]; + private int mPreviousTouchX, mPreviousTouchY; + private int mControlPositionX, mControlPositionY; + + /** + * Constructor + * + * @param res {@link Resources} instance. + * @param bitmap {@link Bitmap} to use with this Drawable. + * @param buttonUp Identifier for the up button. + * @param buttonDown Identifier for the down button. + * @param buttonLeft Identifier for the left button. + * @param buttonRight Identifier for the right button. + */ + public InputOverlayDrawableDpad(Resources res, Bitmap bitmap, + int buttonUp, int buttonDown, + int buttonLeft, int buttonRight) + { + super(res, bitmap); + mButtonType[0] = buttonUp; + mButtonType[1] = buttonDown; + mButtonType[2] = buttonLeft; + mButtonType[3] = buttonRight; + } + + /** + * Gets one of the InputOverlayDrawableDpad's button IDs. + * + * @return the requested InputOverlayDrawableDpad's button ID. + */ + public int getId(int direction) + { + return mButtonType[direction]; + } + + public boolean onConfigureTouch(View v, MotionEvent event) + { + int pointerIndex = event.getActionIndex(); + int fingerPositionX = (int)event.getX(pointerIndex); + int fingerPositionY = (int)event.getY(pointerIndex); + switch (event.getAction()) + { + case MotionEvent.ACTION_DOWN: + mPreviousTouchX = fingerPositionX; + mPreviousTouchY = fingerPositionY; + break; + case MotionEvent.ACTION_MOVE: + mControlPositionX += fingerPositionX - mPreviousTouchX; + mControlPositionY += fingerPositionY - mPreviousTouchY; + setBounds(new Rect(mControlPositionX, mControlPositionY, getBitmap().getWidth() + mControlPositionX, getBitmap().getHeight() + mControlPositionY)); + mPreviousTouchX = fingerPositionX; + mPreviousTouchY = fingerPositionY; + break; + + } + return true; + } + + public void setPosition(int x, int y) + { + mControlPositionX = x; + mControlPositionY = y; + } +} diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/overlay/InputOverlayDrawableJoystick.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/overlay/InputOverlayDrawableJoystick.java index 56ac768a5a..885d84cb11 100644 --- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/overlay/InputOverlayDrawableJoystick.java +++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/overlay/InputOverlayDrawableJoystick.java @@ -24,7 +24,7 @@ public final class InputOverlayDrawableJoystick extends BitmapDrawable private final float[] axises = {0f, 0f}; private final BitmapDrawable ringInner; private int trackId = -1; - private String mSharedPrefsId; + private int mJoystickType; private int mControlPositionX, mControlPositionY; private int mPreviousTouchX, mPreviousTouchY; @@ -37,12 +37,11 @@ public final class InputOverlayDrawableJoystick extends BitmapDrawable * @param rectOuter {@link Rect} which represents the outer joystick bounds. * @param rectInner {@link Rect} which represents the inner joystick bounds. * @param joystick Identifier for which joystick this is. - * @param sharedPrefsId Identifier for getting X and Y control positions from Shared Preferences. */ public InputOverlayDrawableJoystick(Resources res, Bitmap bitmapOuter, Bitmap bitmapInner, Rect rectOuter, Rect rectInner, - int joystick, String sharedPrefsId) + int joystick) { super(res, bitmapOuter); this.setBounds(rectOuter); @@ -54,7 +53,17 @@ public final class InputOverlayDrawableJoystick extends BitmapDrawable this.axisIDs[1] = joystick + 2; this.axisIDs[2] = joystick + 3; this.axisIDs[3] = joystick + 4; - mSharedPrefsId = sharedPrefsId; + mJoystickType = joystick; + } + + /** + * Gets this InputOverlayDrawableJoystick's button ID. + * + * @return this InputOverlayDrawableJoystick's button ID. + */ + public int getId() + { + return mJoystickType; } @Override @@ -168,11 +177,6 @@ public final class InputOverlayDrawableJoystick extends BitmapDrawable ringInner.invalidateSelf(); } - public String getSharedPrefsId() - { - return mSharedPrefsId; - } - public void setPosition(int x, int y) { mControlPositionX = x; diff --git a/Source/Android/app/src/main/res/drawable-hdpi/gcpad_dpad.png b/Source/Android/app/src/main/res/drawable-hdpi/gcwii_dpad.png similarity index 100% rename from Source/Android/app/src/main/res/drawable-hdpi/gcpad_dpad.png rename to Source/Android/app/src/main/res/drawable-hdpi/gcwii_dpad.png diff --git a/Source/Android/app/src/main/res/drawable-hdpi/gcpad_joystick.png b/Source/Android/app/src/main/res/drawable-hdpi/gcwii_joystick.png similarity index 100% rename from Source/Android/app/src/main/res/drawable-hdpi/gcpad_joystick.png rename to Source/Android/app/src/main/res/drawable-hdpi/gcwii_joystick.png diff --git a/Source/Android/app/src/main/res/drawable-hdpi/gcpad_joystick_pressed.png b/Source/Android/app/src/main/res/drawable-hdpi/gcwii_joystick_pressed.png similarity index 100% rename from Source/Android/app/src/main/res/drawable-hdpi/gcpad_joystick_pressed.png rename to Source/Android/app/src/main/res/drawable-hdpi/gcwii_joystick_pressed.png diff --git a/Source/Android/app/src/main/res/drawable-hdpi/gcpad_joystick_range.png b/Source/Android/app/src/main/res/drawable-hdpi/gcwii_joystick_range.png similarity index 100% rename from Source/Android/app/src/main/res/drawable-hdpi/gcpad_joystick_range.png rename to Source/Android/app/src/main/res/drawable-hdpi/gcwii_joystick_range.png diff --git a/Source/Android/app/src/main/res/drawable-xhdpi/gcpad_dpad.png b/Source/Android/app/src/main/res/drawable-xhdpi/gcwii_dpad.png similarity index 100% rename from Source/Android/app/src/main/res/drawable-xhdpi/gcpad_dpad.png rename to Source/Android/app/src/main/res/drawable-xhdpi/gcwii_dpad.png diff --git a/Source/Android/app/src/main/res/drawable-xhdpi/gcpad_joystick.png b/Source/Android/app/src/main/res/drawable-xhdpi/gcwii_joystick.png similarity index 100% rename from Source/Android/app/src/main/res/drawable-xhdpi/gcpad_joystick.png rename to Source/Android/app/src/main/res/drawable-xhdpi/gcwii_joystick.png diff --git a/Source/Android/app/src/main/res/drawable-xhdpi/gcpad_joystick_pressed.png b/Source/Android/app/src/main/res/drawable-xhdpi/gcwii_joystick_pressed.png similarity index 100% rename from Source/Android/app/src/main/res/drawable-xhdpi/gcpad_joystick_pressed.png rename to Source/Android/app/src/main/res/drawable-xhdpi/gcwii_joystick_pressed.png diff --git a/Source/Android/app/src/main/res/drawable-xhdpi/gcpad_joystick_range.png b/Source/Android/app/src/main/res/drawable-xhdpi/gcwii_joystick_range.png similarity index 100% rename from Source/Android/app/src/main/res/drawable-xhdpi/gcpad_joystick_range.png rename to Source/Android/app/src/main/res/drawable-xhdpi/gcwii_joystick_range.png diff --git a/Source/Android/app/src/main/res/drawable-xxhdpi/gcpad_dpad.png b/Source/Android/app/src/main/res/drawable-xxhdpi/gcwii_dpad.png similarity index 100% rename from Source/Android/app/src/main/res/drawable-xxhdpi/gcpad_dpad.png rename to Source/Android/app/src/main/res/drawable-xxhdpi/gcwii_dpad.png diff --git a/Source/Android/app/src/main/res/drawable-xxhdpi/gcpad_joystick.png b/Source/Android/app/src/main/res/drawable-xxhdpi/gcwii_joystick.png similarity index 100% rename from Source/Android/app/src/main/res/drawable-xxhdpi/gcpad_joystick.png rename to Source/Android/app/src/main/res/drawable-xxhdpi/gcwii_joystick.png diff --git a/Source/Android/app/src/main/res/drawable-xxhdpi/gcpad_joystick_pressed.png b/Source/Android/app/src/main/res/drawable-xxhdpi/gcwii_joystick_pressed.png similarity index 100% rename from Source/Android/app/src/main/res/drawable-xxhdpi/gcpad_joystick_pressed.png rename to Source/Android/app/src/main/res/drawable-xxhdpi/gcwii_joystick_pressed.png diff --git a/Source/Android/app/src/main/res/drawable-xxhdpi/gcpad_joystick_range.png b/Source/Android/app/src/main/res/drawable-xxhdpi/gcwii_joystick_range.png similarity index 100% rename from Source/Android/app/src/main/res/drawable-xxhdpi/gcpad_joystick_range.png rename to Source/Android/app/src/main/res/drawable-xxhdpi/gcwii_joystick_range.png diff --git a/Source/Android/app/src/main/res/drawable-xxxhdpi/gcpad_dpad.png b/Source/Android/app/src/main/res/drawable-xxxhdpi/gcwii_dpad.png similarity index 100% rename from Source/Android/app/src/main/res/drawable-xxxhdpi/gcpad_dpad.png rename to Source/Android/app/src/main/res/drawable-xxxhdpi/gcwii_dpad.png diff --git a/Source/Android/app/src/main/res/drawable-xxxhdpi/gcpad_joystick.png b/Source/Android/app/src/main/res/drawable-xxxhdpi/gcwii_joystick.png similarity index 100% rename from Source/Android/app/src/main/res/drawable-xxxhdpi/gcpad_joystick.png rename to Source/Android/app/src/main/res/drawable-xxxhdpi/gcwii_joystick.png diff --git a/Source/Android/app/src/main/res/drawable-xxxhdpi/gcpad_joystick_pressed.png b/Source/Android/app/src/main/res/drawable-xxxhdpi/gcwii_joystick_pressed.png similarity index 100% rename from Source/Android/app/src/main/res/drawable-xxxhdpi/gcpad_joystick_pressed.png rename to Source/Android/app/src/main/res/drawable-xxxhdpi/gcwii_joystick_pressed.png diff --git a/Source/Android/app/src/main/res/drawable-xxxhdpi/gcpad_joystick_range.png b/Source/Android/app/src/main/res/drawable-xxxhdpi/gcwii_joystick_range.png similarity index 100% rename from Source/Android/app/src/main/res/drawable-xxxhdpi/gcpad_joystick_range.png rename to Source/Android/app/src/main/res/drawable-xxxhdpi/gcwii_joystick_range.png diff --git a/Source/Android/app/src/main/res/values/arrays.xml b/Source/Android/app/src/main/res/values/arrays.xml index 4335648861..62a15789d2 100644 --- a/Source/Android/app/src/main/res/values/arrays.xml +++ b/Source/Android/app/src/main/res/values/arrays.xml @@ -159,6 +159,20 @@ 12 + + A + B + X + Y + Z + Start + L + R + D-Pad + Main Stick + C Stick + + Disabled Emulated @@ -170,4 +184,18 @@ 2 + + A + B + 1 + 2 + + + - + Home + C + Z + D-Pad + Nunchuk Stick + + diff --git a/Source/Android/app/src/main/res/values/strings.xml b/Source/Android/app/src/main/res/values/strings.xml index 04db68eee8..5ad4e029b3 100644 --- a/Source/Android/app/src/main/res/values/strings.xml +++ b/Source/Android/app/src/main/res/values/strings.xml @@ -356,6 +356,7 @@ Toggle Touch Controls + Toggle All Quick Save Quick Load Refresh Wiimotes