Merge pull request #9215 from JosJuice/android-pointer-portrait

Android/InputOverlayPointer: Don't assume surface covers whole screen
This commit is contained in:
LC 2020-11-02 18:05:47 -05:00 committed by GitHub
commit d5c0a9a185
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 60 additions and 69 deletions

View File

@ -1,6 +1,7 @@
package org.dolphinemu.dolphinemu.fragments; package org.dolphinemu.dolphinemu.fragments;
import android.content.Context; import android.content.Context;
import android.graphics.Rect;
import android.os.Bundle; import android.os.Bundle;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.Surface; import android.view.Surface;
@ -93,6 +94,15 @@ public final class EmulationFragment extends Fragment implements SurfaceHolder.C
doneButton.setOnClickListener(v -> stopConfiguringControls()); doneButton.setOnClickListener(v -> stopConfiguringControls());
} }
contents.post(() ->
{
int overlayX = mInputOverlay.getLeft();
int overlayY = mInputOverlay.getTop();
mInputOverlay.setSurfacePosition(new Rect(
surfaceView.getLeft() - overlayX, surfaceView.getTop() - overlayY,
surfaceView.getRight() - overlayX, surfaceView.getBottom() - overlayY));
});
// The new Surface created here will get passed to the native code via onSurfaceChanged. // The new Surface created here will get passed to the native code via onSurfaceChanged.
return contents; return contents;

View File

@ -60,7 +60,9 @@ public final class InputOverlay extends SurfaceView implements OnTouchListener
private final Set<InputOverlayDrawableButton> overlayButtons = new HashSet<>(); private final Set<InputOverlayDrawableButton> overlayButtons = new HashSet<>();
private final Set<InputOverlayDrawableDpad> overlayDpads = new HashSet<>(); private final Set<InputOverlayDrawableDpad> overlayDpads = new HashSet<>();
private final Set<InputOverlayDrawableJoystick> overlayJoysticks = new HashSet<>(); private final Set<InputOverlayDrawableJoystick> overlayJoysticks = new HashSet<>();
private InputOverlayPointer overlayPointer; private InputOverlayPointer overlayPointer = null;
private Rect mSurfacePosition = null;
private boolean mIsFirstRun = true; private boolean mIsFirstRun = true;
private boolean mIsInEditMode = false; private boolean mIsInEditMode = false;
@ -125,19 +127,7 @@ public final class InputOverlay extends SurfaceView implements OnTouchListener
// Load the controls if we can. If not, EmulationActivity has to do it later. // Load the controls if we can. If not, EmulationActivity has to do it later.
if (NativeLibrary.IsGameMetadataValid()) if (NativeLibrary.IsGameMetadataValid())
{ refreshControls();
if (NativeLibrary.IsRunning())
{
// We would've needed a refreshControls call here in addition to the initTouchPointer call
// if it wasn't for initTouchPointer calling refreshControls.
initTouchPointer();
}
else
{
// We can't call initTouchPointer yet because it needs the aspect ratio of the running game.
refreshControls();
}
}
// Set the on touch listener. // Set the on touch listener.
setOnTouchListener(this); setOnTouchListener(this);
@ -149,24 +139,33 @@ public final class InputOverlay extends SurfaceView implements OnTouchListener
requestFocus(); requestFocus();
} }
public void setSurfacePosition(Rect rect)
{
mSurfacePosition = rect;
initTouchPointer();
}
public void initTouchPointer() public void initTouchPointer()
{ {
// Refresh before starting the pointer // Check if we have all the data we need yet
refreshControls(); boolean aspectRatioAvailable = NativeLibrary.IsRunning() && !NativeLibrary.IsBooting();
if (!aspectRatioAvailable || mSurfacePosition == null)
return;
if (NativeLibrary.IsEmulatingWii()) // Check if there's any point in running the pointer code
if (!NativeLibrary.IsEmulatingWii())
return;
int doubleTapButton = IntSetting.MAIN_DOUBLE_TAP_BUTTON.getIntGlobal();
if (mPreferences.getInt("wiiController", OVERLAY_WIIMOTE_NUNCHUK) !=
InputOverlay.OVERLAY_WIIMOTE_CLASSIC &&
doubleTapButton == InputOverlayPointer.DOUBLE_TAP_CLASSIC_A)
{ {
int doubleTapButton = IntSetting.MAIN_DOUBLE_TAP_BUTTON.getIntGlobal(); doubleTapButton = InputOverlayPointer.DOUBLE_TAP_A;
if (mPreferences.getInt("wiiController", OVERLAY_WIIMOTE_NUNCHUK) !=
InputOverlay.OVERLAY_WIIMOTE_CLASSIC &&
doubleTapButton == InputOverlayPointer.DOUBLE_TAP_CLASSIC_A)
{
doubleTapButton = InputOverlayPointer.DOUBLE_TAP_A;
}
overlayPointer = new InputOverlayPointer(this.getContext(), doubleTapButton);
} }
overlayPointer = new InputOverlayPointer(mSurfacePosition, doubleTapButton);
} }
@Override @Override

View File

@ -1,10 +1,7 @@
package org.dolphinemu.dolphinemu.overlay; package org.dolphinemu.dolphinemu.overlay;
import android.app.Activity; import android.graphics.Rect;
import android.content.Context;
import android.os.Handler; import android.os.Handler;
import android.util.DisplayMetrics;
import android.view.Display;
import android.view.MotionEvent; import android.view.MotionEvent;
import org.dolphinemu.dolphinemu.NativeLibrary; import org.dolphinemu.dolphinemu.NativeLibrary;
@ -20,10 +17,11 @@ public class InputOverlayPointer
private final float[] axes = {0f, 0f}; private final float[] axes = {0f, 0f};
private float maxHeight; private float mGameCenterX;
private float maxWidth; private float mGameCenterY;
private float aspectAdjusted; private float mGameWidthHalfInv;
private boolean xAdjusted; private float mGameHeightHalfInv;
private boolean doubleTap = false; private boolean doubleTap = false;
private int doubleTapButton; private int doubleTapButton;
private int trackId = -1; private int trackId = -1;
@ -38,39 +36,33 @@ public class InputOverlayPointer
DOUBLE_TAP_OPTIONS.add(NativeLibrary.ButtonType.CLASSIC_BUTTON_A); DOUBLE_TAP_OPTIONS.add(NativeLibrary.ButtonType.CLASSIC_BUTTON_A);
} }
public InputOverlayPointer(Context context, int button) public InputOverlayPointer(Rect surfacePosition, int button)
{ {
Display display = ((Activity) context).getWindowManager().getDefaultDisplay();
DisplayMetrics outMetrics = new DisplayMetrics();
display.getMetrics(outMetrics);
doubleTapButton = button; doubleTapButton = button;
Integer y = outMetrics.heightPixels; mGameCenterX = (surfacePosition.left + surfacePosition.right) / 2.0f;
Integer x = outMetrics.widthPixels; mGameCenterY = (surfacePosition.top + surfacePosition.bottom) / 2.0f;
float gameWidth = surfacePosition.right - surfacePosition.left;
float gameHeight = surfacePosition.bottom - surfacePosition.top;
// Adjusting for device's black bars. // Adjusting for device's black bars.
float deviceAR = (float) x / y; float surfaceAR = gameWidth / gameHeight;
float gameAR = NativeLibrary.GetGameAspectRatio(); float gameAR = NativeLibrary.GetGameAspectRatio();
aspectAdjusted = gameAR / deviceAR;
if (gameAR <= deviceAR) // Black bars on left/right if (gameAR <= surfaceAR)
{ {
xAdjusted = true; // Black bars on left/right
Integer gameX = Math.round((float) y * gameAR); gameWidth = gameHeight * gameAR;
Integer buffer = (x - gameX);
maxWidth = (float) (x - buffer) / 2;
maxHeight = (float) y / 2;
} }
else // Bars on top/bottom else
{ {
xAdjusted = false; // Black bars on top/bottom
Integer gameY = Math.round((float) x / gameAR); gameHeight = gameWidth / gameAR;
Integer buffer = (y - gameY);
maxWidth = (float) x / 2;
maxHeight = (float) (y - buffer) / 2;
} }
mGameWidthHalfInv = 1.0f / (gameWidth * 0.5f);
mGameHeightHalfInv = 1.0f / (gameHeight * 0.5f);
} }
public void onTouch(MotionEvent event) public void onTouch(MotionEvent event)
@ -94,18 +86,8 @@ public class InputOverlayPointer
if (trackId == -1) if (trackId == -1)
return; return;
int x = (int) event.getX(event.findPointerIndex(trackId)); axes[0] = (event.getY(event.findPointerIndex(trackId)) - mGameCenterY) * mGameHeightHalfInv;
int y = (int) event.getY(event.findPointerIndex(trackId)); axes[1] = (event.getX(event.findPointerIndex(trackId)) - mGameCenterX) * mGameWidthHalfInv;
if (xAdjusted)
{
axes[0] = (y - maxHeight) / maxHeight;
axes[1] = ((x * aspectAdjusted) - maxWidth) / maxWidth;
}
else
{
axes[0] = ((y * aspectAdjusted) - maxHeight) / maxHeight;
axes[1] = (x - maxWidth) / maxWidth;
}
} }
private void touchPress() private void touchPress()