Skip to content
Permalink
Browse files

Android: Normalize pointer touches based on rendered aspect ratio

This allows the defaults to be actual defaults across devices with different
screen sizes
  • Loading branch information...
zackhow committed Jan 20, 2019
1 parent ec557eb commit e8739156e4dc54b904af036d26609e624c997fcb
@@ -492,4 +492,19 @@ public static void clearEmulationActivity()

sEmulationActivity.clear();
}

public static void updateTouchPointer()
{
final EmulationActivity emulationActivity = sEmulationActivity.get();
if (emulationActivity == null)
{
Log.warning("[NativeLibrary] EmulationActivity is null.");
}
else
{
emulationActivity.runOnUiThread(emulationActivity::initInputPointer);
}
}

public static native float GetGameAspectRatio();
}
@@ -757,7 +757,7 @@ public void chooseDoubleTapButton()
builder.setPositiveButton(getString(R.string.ok), (dialogInterface, i) ->
{
editor.commit();
mEmulationFragment.refreshInputOverlay();
mEmulationFragment.initInputPointer();
});

AlertDialog alertDialog = builder.create();
@@ -1064,4 +1064,9 @@ public Settings getSettings()
{
return mSettings;
}

public void initInputPointer()
{
mEmulationFragment.initInputPointer();
}
}
@@ -201,6 +201,11 @@ public void toggleInputOverlayVisibility()
mInputOverlay.refreshControls();
}

public void initInputPointer()
{
mInputOverlay.initTouchPointer();
}

public void refreshInputOverlay()
{
mInputOverlay.refreshControls();
@@ -92,6 +92,7 @@ public InputOverlay(Context context, AttributeSet attrs)
mPreferences = PreferenceManager.getDefaultSharedPreferences(getContext());
if (!mPreferences.getBoolean("OverlayInitV2", false))
defaultOverlay();

// Load the controls.
refreshControls();

@@ -105,6 +106,27 @@ public InputOverlay(Context context, AttributeSet attrs)
requestFocus();
}

public void initTouchPointer()
{
// Refresh before starting the pointer
refreshControls();

if (!EmulationActivity.isGameCubeGame())
{
int doubleTapButton = mPreferences.getInt("doubleTapButton",
InputOverlayPointer.DOUBLE_TAP_OPTIONS.get(InputOverlayPointer.DOUBLE_TAP_A));

if (mPreferences.getInt("wiiController", OVERLAY_WIIMOTE_NUNCHUCK) !=
InputOverlay.OVERLAY_WIIMOTE_CLASSIC &&
doubleTapButton == InputOverlayPointer.DOUBLE_TAP_CLASSIC_A)
{
doubleTapButton = InputOverlayPointer.DOUBLE_TAP_A;
}

overlayPointer = new InputOverlayPointer(this.getContext(), doubleTapButton);
}
}

@Override
public void draw(Canvas canvas)
{
@@ -201,15 +223,22 @@ public boolean onTouch(View v, MotionEvent event)

// Release the buttons first, then press
for (int i = 0; i < dpadPressed.length; i++)
{
if (!dpadPressed[i])
{
NativeLibrary.onGamePadEvent(NativeLibrary.TouchScreenDevice, dpad.getId(i),
ButtonState.RELEASED);
}
}
// Press buttons
for (int i = 0; i < dpadPressed.length; i++)
{
if (dpadPressed[i])
{
NativeLibrary.onGamePadEvent(NativeLibrary.TouchScreenDevice, dpad.getId(i),
ButtonState.PRESSED);

}
}
setDpadState(dpad, dpadPressed[0], dpadPressed[1], dpadPressed[2], dpadPressed[3]);
}
break;
@@ -671,19 +700,6 @@ else if (mPreferences.getInt("wiiController", 3) == 4)
}
}

if (!EmulationActivity.isGameCubeGame())
{
int doubleTapButton = mPreferences.getInt("doubleTapButton",
InputOverlayPointer.DOUBLE_TAP_OPTIONS.get(InputOverlayPointer.DOUBLE_TAP_A));

if (mPreferences.getInt("wiiController", OVERLAY_WIIMOTE_NUNCHUCK) !=
InputOverlay.OVERLAY_WIIMOTE_CLASSIC &&
doubleTapButton == InputOverlayPointer.DOUBLE_TAP_CLASSIC_A)
doubleTapButton = InputOverlayPointer.DOUBLE_TAP_A;

overlayPointer = new InputOverlayPointer(this.getContext(), doubleTapButton);
}

invalidate();
}

@@ -19,8 +19,11 @@
public static final int DOUBLE_TAP_CLASSIC_A = 3;

private final float[] axes = {0f, 0f};

private float maxHeight;
private float maxWidth;
private float aspectAdjusted;
private boolean xAdjusted;
private boolean doubleTap = false;
private int doubleTapButton;
private int trackId = -1;
@@ -41,8 +44,33 @@ public InputOverlayPointer(Context context, int button)
DisplayMetrics outMetrics = new DisplayMetrics();
display.getMetrics(outMetrics);
doubleTapButton = button;
maxWidth = outMetrics.widthPixels / 2;
maxHeight = outMetrics.heightPixels / 2;

Integer y = outMetrics.heightPixels;
Integer x = outMetrics.widthPixels;

// Adjusting for device's black bars.
Float deviceAR = (float) x / y;
Float gameAR = NativeLibrary.GetGameAspectRatio();
aspectAdjusted = gameAR / deviceAR;

if (gameAR < deviceAR) // Black bars on left/right
{
xAdjusted = true;
Integer gameX = Math.round((float) y * gameAR);
Integer buffer = (x - gameX);

maxWidth = (float) (x - buffer) / 2;
maxHeight = (float) y / 2;
}
else // Bars on top/bottom
{
xAdjusted = false;
Integer gameY = Math.round((float) x * gameAR);
Integer buffer = (y - gameY);

maxWidth = (float) x / 2;
maxHeight = (float) (y - buffer) / 2;
}
}

public boolean onTouch(MotionEvent event)
@@ -68,9 +96,16 @@ public boolean onTouch(MotionEvent event)

int x = (int) event.getX(event.findPointerIndex(trackId));
int y = (int) event.getY(event.findPointerIndex(trackId));
axes[0] = (y - maxHeight) / maxHeight;
axes[1] = (x - maxWidth) / maxWidth;

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;
}
return false;
}

@@ -12,6 +12,7 @@ static JavaVM* s_java_vm;

static jclass s_native_library_class;
static jmethodID s_display_alert_msg;
static jmethodID s_get_update_touch_pointer;

static jclass s_game_file_class;
static jfieldID s_game_file_pointer;
@@ -41,6 +42,11 @@ jmethodID GetDisplayAlertMsg()
return s_display_alert_msg;
}

jmethodID GetUpdateTouchPointer()
{
return s_get_update_touch_pointer;
}

jclass GetAnalyticsClass()
{
return s_analytics_class;
@@ -98,6 +104,8 @@ jint JNI_OnLoad(JavaVM* vm, void* reserved)
s_native_library_class = reinterpret_cast<jclass>(env->NewGlobalRef(native_library_class));
s_display_alert_msg = env->GetStaticMethodID(s_native_library_class, "displayAlertMsg",
"(Ljava/lang/String;Ljava/lang/String;Z)Z");
s_get_update_touch_pointer =
env->GetStaticMethodID(IDCache::GetNativeLibraryClass(), "updateTouchPointer", "()V");

const jclass game_file_class = env->FindClass("org/dolphinemu/dolphinemu/model/GameFile");
s_game_file_class = reinterpret_cast<jclass>(env->NewGlobalRef(game_file_class));
@@ -14,6 +14,7 @@ JavaVM* GetJavaVM();

jclass GetNativeLibraryClass();
jmethodID GetDisplayAlertMsg();
jmethodID GetUpdateTouchPointer();

jclass GetAnalyticsClass();
jmethodID GetSendAnalyticsReport();
@@ -107,6 +107,11 @@ void Host_UpdateMainFrame()

void Host_RequestRenderWindowSize(int width, int height)
{
// Update touch pointer
JNIEnv* env;
IDCache::GetJavaVM()->AttachCurrentThread(&env, nullptr);
env->CallStaticVoidMethod(IDCache::GetNativeLibraryClass(), IDCache::GetUpdateTouchPointer());
IDCache::GetJavaVM()->DetachCurrentThread();
}

bool Host_UINeedsControllerState()
@@ -564,6 +569,13 @@ JNIEXPORT void JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_SurfaceDestr
s_surf = nullptr;
}
}

JNIEXPORT jfloat JNICALL
Java_org_dolphinemu_dolphinemu_NativeLibrary_GetGameAspectRatio(JNIEnv* env, jobject obj)
{
return g_renderer->CalculateDrawAspectRatio();
}

JNIEXPORT void JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_RefreshWiimotes(JNIEnv* env,
jobject obj)
{

0 comments on commit e873915

Please sign in to comment.
You can’t perform that action at this time.