Touch Controls

This commit is contained in:
Waterdish
2024-11-23 18:45:19 -08:00
parent 5cadb5923d
commit cb1378429f
13 changed files with 737 additions and 5 deletions
@@ -20,15 +20,29 @@ import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
import android.util.Log;
//This class is the main SDLActivity and just sets up a bunch of default files
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.FrameLayout;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.widget.ImageView;
//This class is the main SDLActivity and just sets up a bunch of default files and the input overlay
public class MainActivity extends SDLActivity{
private static final int STORAGE_PERMISSION_REQUEST_CODE = 1;
SharedPreferences preferences;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
preferences = getSharedPreferences("com.dishii.mm.prefs",Context.MODE_PRIVATE);
setupControllerOverlay();
// Check if storage permissions are granted
if (hasStoragePermission()) {
doVersionCheck();
@@ -36,10 +50,10 @@ public class MainActivity extends SDLActivity{
} else {
requestStoragePermission();
}
attachController();
}
private void doVersionCheck(){
SharedPreferences preferences = getSharedPreferences("com.dishii.mm.prefs",Context.MODE_PRIVATE);
int currentVersion = BuildConfig.VERSION_CODE; // Use your app's version code
int storedVersion = preferences.getInt("appVersion", 1);
@@ -184,4 +198,258 @@ public class MainActivity extends SDLActivity{
return Environment.MEDIA_MOUNTED.equals(state);
}
public native void attachController();
// Native method for setting button state
public native void setButton(int button, boolean value);
public native void setCameraState(int axis, float value);
// Native method for setting joystick axis value
public native void setAxis(int axis, short value);
private Button button1, button2, button3, button4;
private Button buttonA, buttonB, buttonX, buttonY;
private Button buttonDpadUp, buttonDpadDown, buttonDpadLeft, buttonDpadRight;
private Button buttonLB, buttonRB, buttonZ, buttonStart, buttonBack;
private Button buttonToggle;
private FrameLayout leftJoystick;
private ImageView leftJoystickKnob;
private View overlayView;
// Function to set up the controller overlay (inflate layout and initialize buttons)
private void setupControllerOverlay() {
// Inflate the touchcontrol_overlay layout
LayoutInflater inflater = (LayoutInflater) getSystemService(LAYOUT_INFLATER_SERVICE);
overlayView = inflater.inflate(R.layout.touchcontrol_overlay, null);
// Set layout params for overlayView to control positioning and sizing
FrameLayout.LayoutParams layoutParams = new FrameLayout.LayoutParams(
FrameLayout.LayoutParams.MATCH_PARENT,
FrameLayout.LayoutParams.MATCH_PARENT
);
overlayView.setLayoutParams(layoutParams);
// Add overlay view to the main layout (you may need to add it to a container like FrameLayout)
ViewGroup view = (ViewGroup) getContentView();
view.addView(overlayView);
final ViewGroup buttonGroup = overlayView.findViewById(R.id.button_group);
buttonA = overlayView.findViewById(R.id.buttonA);
buttonB = overlayView.findViewById(R.id.buttonB);
buttonX = overlayView.findViewById(R.id.buttonX);
buttonY = overlayView.findViewById(R.id.buttonY);
buttonDpadUp = overlayView.findViewById(R.id.buttonDpadUp);
buttonDpadDown = overlayView.findViewById(R.id.buttonDpadDown);
buttonDpadLeft = overlayView.findViewById(R.id.buttonDpadLeft);
buttonDpadRight = overlayView.findViewById(R.id.buttonDpadRight);
buttonLB = overlayView.findViewById(R.id.buttonLB);
buttonRB = overlayView.findViewById(R.id.buttonRB);
buttonZ = overlayView.findViewById(R.id.buttonZ);
buttonStart = overlayView.findViewById(R.id.buttonStart);
buttonBack = overlayView.findViewById(R.id.buttonBack);
buttonToggle = overlayView.findViewById(R.id.buttonToggle);
// Initialize joysticks and joystick knobs from the inflated layout
leftJoystick = overlayView.findViewById(R.id.left_joystick);
leftJoystickKnob = overlayView.findViewById(R.id.left_joystick_knob);
FrameLayout rightScreenArea = overlayView.findViewById(R.id.right_screen_area);
// Set OnTouchListeners for the Xbox controller buttons
addTouchListener(buttonA, ControllerButtons.BUTTON_A); // SDL Button 0 (A)
addTouchListener(buttonB, ControllerButtons.BUTTON_B); // SDL Button 1 (B)
addTouchListener(buttonX, ControllerButtons.BUTTON_X); // SDL Button 2 (X)
addTouchListener(buttonY, ControllerButtons.BUTTON_Y); // SDL Button 3 (Y)
addTouchListener(buttonDpadUp, ControllerButtons.BUTTON_DPAD_UP); // SDL Button 10 (D-Pad Up)
addTouchListener(buttonDpadDown, ControllerButtons.BUTTON_DPAD_DOWN); // SDL Button 11 (D-Pad Down)
addTouchListener(buttonDpadLeft, ControllerButtons.BUTTON_DPAD_LEFT); // SDL Button 12 (D-Pad Left)
addTouchListener(buttonDpadRight, ControllerButtons.BUTTON_DPAD_RIGHT); // SDL Button 13 (D-Pad Right)
addTouchListener(buttonLB, ControllerButtons.BUTTON_LB); // SDL Button 4 (LB)
addTouchListener(buttonRB, ControllerButtons.BUTTON_RB); // SDL Button 5 (RB)
addTouchListener(buttonZ, ControllerButtons.AXIS_RT); // SDL Button 5 (Z)
addTouchListener(buttonStart, ControllerButtons.BUTTON_START); // SDL Button 7 (Start)
addTouchListener(buttonBack, ControllerButtons.BUTTON_BACK); // SDL Button 6 (Back)
// Setup joystick movement
setupJoystick(leftJoystick, leftJoystickKnob, true); // Left joystick
setupLookAround(rightScreenArea);
setupToggleButton(buttonToggle,buttonGroup);
}
private void setupToggleButton(Button button, ViewGroup uiGroup){
boolean isHidden = preferences.getBoolean("controlsVisible", false); // Default to 'false' (visible)
uiGroup.setVisibility(isHidden ? View.INVISIBLE : View.VISIBLE); // Set the initial visibility based on the saved state
button.setOnClickListener(new View.OnClickListener() {
boolean isHidden = false;
@Override
public void onClick(View v) {
if (isHidden) {
uiGroup.setVisibility(View.VISIBLE); // Show UI elements
} else {
uiGroup.setVisibility(View.INVISIBLE); // Hide UI elements
}
preferences.edit().putBoolean("controlsVisible", !isHidden).apply();
isHidden = !isHidden; // Toggle state
}
});
}
// Function to set a touch listener for each button
private void addTouchListener(Button button, int buttonNum) {
button.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
setButton(buttonNum, true);
button.setPressed(true);
return true;
case MotionEvent.ACTION_UP:
setButton(buttonNum, false);
button.setPressed(false);
return true;
case MotionEvent.ACTION_CANCEL:
setButton(buttonNum, false);
return true;
}
return false;
}
});
}
boolean TouchAreaEnabled = true;
void DisableTouchArea(){
TouchAreaEnabled = false;
}
void EnableTouchArea(){
TouchAreaEnabled = true;
}
private void setupLookAround(FrameLayout rightScreenArea) {
rightScreenArea.setOnTouchListener(new View.OnTouchListener() {
private float lastX = 0;
private float lastY = 0;
private boolean isTouching = false;
@Override
public boolean onTouch(View v, MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
// Start tracking the finger's position
lastX = event.getX();
lastY = event.getY();
isTouching = true;
break;
case MotionEvent.ACTION_MOVE:
if (isTouching) {
// Calculate the change in position (delta)
float deltaX = event.getX() - lastX;
float deltaY = event.getY() - lastY;
// Update the last position
lastX = event.getX();
lastY = event.getY();
// Increase sensitivity by using a larger multiplier
// Adjust these multipliers to suit your needs
float sensitivityMultiplier = 15; // Higher value for more sensitivity
float rx = (deltaX * sensitivityMultiplier);
float ry = (deltaY * sensitivityMultiplier);
// Send the mapped values to the joystick axes
setCameraState(0, rx); // Right stick X axis
setCameraState(1, ry); // Right stick Y axis
}
break;
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_CANCEL:
// Stop tracking the finger's position and reset joystick input
isTouching = false;
setCameraState(0, 0.0f); // Reset right stick X axis
setCameraState(1, 0.0f); // Reset right stick Y axis
break;
}
return TouchAreaEnabled; // Event full handled
}
});
}
// Function to set joystick movement with reset to center when not touched
private void setupJoystick(FrameLayout joystickLayout, ImageView joystickKnob, boolean isLeft) {
joystickLayout.post(() -> {
// Calculate the joystick center once, before any events
final float joystickCenterX = joystickLayout.getWidth() / 2f;
final float joystickCenterY = joystickLayout.getHeight() / 2f;
joystickLayout.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
case MotionEvent.ACTION_MOVE:
// Calculate the joystick movement and move the knob
float deltaX = event.getX() - joystickCenterX;
float deltaY = event.getY() - joystickCenterY;
// Clamp the joystick movement to prevent it from going outside the area
float maxRadius = joystickLayout.getWidth() / 2f - joystickKnob.getWidth() / 2f;
float distance = (float) Math.sqrt(deltaX * deltaX + deltaY * deltaY);
if (distance > maxRadius) {
float scale = maxRadius / distance;
deltaX *= scale;
deltaY *= scale;
}
joystickKnob.setX(joystickCenterX + deltaX - joystickKnob.getWidth() / 2f);
joystickKnob.setY(joystickCenterY + deltaY - joystickKnob.getHeight() / 2f);
// Send joystick values to native C code
short x = (short) (deltaX / maxRadius * Short.MAX_VALUE);
short y = (short) (deltaY / maxRadius * Short.MAX_VALUE);
// Send X-axis and Y-axis values
setAxis(isLeft ? ControllerButtons.AXIS_LX : ControllerButtons.AXIS_RX, x); // X-axis
setAxis(isLeft ? ControllerButtons.AXIS_LY : ControllerButtons.AXIS_RY, y); // Y-axis
break;
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_CANCEL:
// Reset joystick knob to the center position (ensure it's placed correctly)
joystickKnob.setX(joystickCenterX - joystickKnob.getWidth() / 2f);
joystickKnob.setY(joystickCenterY - joystickKnob.getHeight() / 2f);
// Reset joystick values to 0 when released or canceled
setAxis(isLeft ? ControllerButtons.AXIS_LX : ControllerButtons.AXIS_RX, (short) 0); // X-axis
setAxis(isLeft ? ControllerButtons.AXIS_LY : ControllerButtons.AXIS_RY, (short) 0); // Y-axis
break;
}
return true;
}
});
});
}
}