Skip to content
Permalink
Browse files
Front: Implemented individual button scaling
  • Loading branch information
Gillou68310 committed Oct 21, 2015
1 parent 5786660 commit d15ad5c
Show file tree
Hide file tree
Showing 5 changed files with 144 additions and 42 deletions.
@@ -8,6 +8,19 @@
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="10dp" >

<CheckBox
android:id="@+id/checkBox_holdable"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/touchscreenProfileActivity_autoHoldable" />

<CheckBox
android:id="@+id/checkBox_feedback"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/touchscreenAnimation_summary" />

<RelativeLayout
android:id="@+id/rowX"
android:layout_width="match_parent"
@@ -59,7 +72,6 @@
</LinearLayout>
</RelativeLayout>


<RelativeLayout
android:id="@+id/rowY"
android:layout_width="match_parent"
@@ -93,7 +105,7 @@
android:paddingLeft="50dp"
android:paddingRight="50dp"
android:paddingTop="10dp" >

<TextView
android:id="@+id/textY"
android:layout_width="match_parent"
@@ -110,17 +122,56 @@
android:progress="50" />
</LinearLayout>
</RelativeLayout>

<RelativeLayout
android:id="@+id/rowScale"
android:layout_width="match_parent"
android:layout_height="wrap_content" >

<CheckBox
android:id="@+id/checkBox_holdable"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/touchscreenProfileActivity_autoHoldable" />

<CheckBox
android:id="@+id/checkBox_feedback"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/touchscreenAnimation_summary" />
<Button
android:id="@+id/buttonScaleDown"
android:layout_width="50dp"
android:layout_height="50dp"
android:layout_alignParentLeft="true"
android:layout_centerVertical="true"
android:text="-"
tools:ignore="HardcodedText,RtlHardcoded" />

<Button
android:id="@+id/buttonScaleUp"
android:layout_width="50dp"
android:layout_height="50dp"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
android:text="+"
tools:ignore="HardcodedText,RtlHardcoded" />

<LinearLayout
android:id="@+id/seekgroupScale"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:orientation="vertical"
android:paddingBottom="10dp"
android:paddingLeft="50dp"
android:paddingRight="50dp"
android:paddingTop="10dp" >

<TextView
android:id="@+id/textScale"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_horizontal"
android:text="@string/touchscreenProfileActivity_ScaleSlider"
android:textIsSelectable="false" />

<SeekBar
android:id="@+id/seekbarScale"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:max="200"
android:progress="50" />
</LinearLayout>
</RelativeLayout>
</LinearLayout>
</ScrollView>
@@ -532,6 +532,7 @@
<string name="touchscreenProfileActivity_remove">Remove</string>
<string name="touchscreenProfileActivity_horizontalSlider">Horizontal: %1$d %%</string>
<string name="touchscreenProfileActivity_verticalSlider">Vertical: %1$d %%</string>
<string name="touchscreenProfileActivity_ScaleSlider">Scaling: %1$d %%</string>
<string name="touchscreenProfileActivity_autoHoldable">Auto-holdable</string>

<!-- Controller button names -->
@@ -73,6 +73,9 @@
/** Scaling factor to apply to images. */
protected float scale = 1.0f;

/** Button scaling factor. */
protected ArrayList<Float> buttonScaling;

/** Button images. */
protected ArrayList<Image> buttonImages;

@@ -86,7 +89,10 @@
private final ArrayList<Integer> buttonY;

/** names of the buttons. */
private final ArrayList<String> buttonNames;
protected final ArrayList<String> buttonNames;

/** Analog background scaling. */
protected float analogBackScaling;

/** Analog background image (fixed). */
protected Image analogBackImage;
@@ -186,18 +192,21 @@ public TouchMap( Resources resources )
buttonX = new ArrayList<Integer>();
buttonY = new ArrayList<Integer>();
buttonNames = new ArrayList<String>();
buttonScaling = new ArrayList<Float>();
}

/**
* Clears the map data.
*/
public void clear()
{
buttonScaling.clear();
buttonImages.clear();
buttonMasks.clear();
buttonX.clear();
buttonY.clear();
buttonNames.clear();
analogBackScaling = 0;
analogBackImage = null;
analogForeImage = null;
analogBackX = analogBackY = 0;
@@ -219,16 +228,16 @@ public void resize( int w, int h )
// Recompute button locations
for( int i = 0; i < buttonImages.size(); i++ )
{
buttonImages.get( i ).setScale( scale );
buttonImages.get( i ).setScale( ( buttonScaling.get( i ) * scale ) );
buttonImages.get( i ).fitPercent( buttonX.get( i ), buttonY.get( i ), w, h );
buttonMasks.get( i ).setScale( scale );
buttonMasks.get( i ).setScale( ( buttonScaling.get( i ) * scale ) );
buttonMasks.get( i ).fitPercent( buttonX.get( i ), buttonY.get( i ), w, h );
}

// Recompute analog background location
if( analogBackImage != null )
{
analogBackImage.setScale( scale );
analogBackImage.setScale( ( analogBackScaling * scale ) );
analogBackImage.fitPercent( analogBackX, analogBackY, w, h );
}
}
@@ -246,21 +255,22 @@ public void resize( int w, int h )
public int getButtonPress( int xLocation, int yLocation )
{
// Search through every button mask to see if the corresponding button was touched
for( Image mask : buttonMasks )
for( int i = 0; i < buttonMasks.size(); i++ )
{
if( mask != null )
if( buttonMasks.get( i ) != null )
{
int left = mask.x;
int right = left + (int) ( mask.width * mask.scale );
int bottom = mask.y;
int top = bottom + (int) ( mask.height * mask.scale );
int left = buttonMasks.get( i ).x;
int right = left + (int) ( buttonMasks.get( i ).width * buttonMasks.get( i ).scale );
int bottom = buttonMasks.get( i ).y;
int top = bottom + (int) ( buttonMasks.get( i ).height * buttonMasks.get( i ).scale );

// See if the touch falls in the vicinity of the button (conservative test)
if( xLocation >= left && xLocation < right && yLocation >= bottom
&& yLocation < top )
{
// Get the mask color at this location
int c = mask.image.getPixel( (int) ( ( xLocation - mask.x ) / scale ), (int) ( ( yLocation - mask.y ) / scale ) );
int c = buttonMasks.get( i ).image.getPixel( (int) ( ( xLocation - buttonMasks.get( i ).x ) /
( buttonScaling.get( i ) * scale ) ), (int) ( ( yLocation - buttonMasks.get( i ).y ) / ( buttonScaling.get( i ) * scale ) ) );

// Ignore the alpha component if any
int rgb = c & 0x00ffffff;
@@ -345,10 +355,10 @@ public Point getAnalogDisplacement( int xLocation, int yLocation )
return new Point( 0, 0 );

// Distance from center along x-axis
int dX = xLocation - ( analogBackImage.x + (int) ( analogBackImage.hWidth * scale ) );
int dX = xLocation - ( analogBackImage.x + (int) ( analogBackImage.hWidth * ( analogBackScaling * scale ) ) );

// Distance from center along y-axis
int dY = yLocation - ( analogBackImage.y + (int) ( analogBackImage.hHeight * scale ) );
int dY = yLocation - ( analogBackImage.y + (int) ( analogBackImage.hHeight * ( analogBackScaling * scale ) ) );

return new Point( dX, dY );
}
@@ -375,7 +385,7 @@ public Rect getAnalogFrame()
*/
public Point getConstrainedDisplacement( int dX, int dY )
{
final float dC = (int) ( analogMaximum * scale );
final float dC = (int) ( analogMaximum * ( analogBackScaling * scale ) );
final float dA = dC * FloatMath.sqrt( 0.5f );
final float signX = (dX < 0) ? -1 : 1;
final float signY = (dY < 0) ? -1 : 1;
@@ -401,7 +411,7 @@ public Point getConstrainedDisplacement( int dX, int dY )
*/
public float getAnalogStrength( float displacement )
{
displacement /= scale;
displacement /= ( analogBackScaling * scale );
float p = ( displacement - analogDeadzone ) / ( analogMaximum - analogDeadzone );
return Utility.clamp( p, 0.0f, 1.0f );
}
@@ -415,7 +425,7 @@ public float getAnalogStrength( float displacement )
*/
public boolean isInCaptureRange( float displacement )
{
displacement /= scale;
displacement /= ( analogBackScaling * scale );
return ( displacement >= analogDeadzone ) && ( displacement < analogMaximum + analogPadding );
}

@@ -462,7 +472,7 @@ public void load( String skinDir, Profile profile, boolean animated )
* @param profile The name of the layout profile.
* @param name The name of the button.
*/
public void updateButton( Profile profile, String name )
public void updateButton( Profile profile, String name, int w, int h )
{
int x = profile.getInt( name + "-x", -1 );
int y = profile.getInt( name + "-y", -1 );
@@ -473,6 +483,15 @@ public void updateButton( Profile profile, String name )
{
analogBackX = x;
analogBackY = y;
analogBackImage.fitPercent( analogBackX, analogBackY, w, h );

if( analogForeImage != null )
{
int cX = analogBackImage.x + (int) ( analogBackImage.hWidth * ( analogBackScaling * scale ) );
int cY = analogBackImage.y + (int) ( analogBackImage.hHeight * ( analogBackScaling * scale ) );
analogForeImage.fitCenter( cX, cY, analogBackImage.x, analogBackImage.y,
(int) ( analogBackImage.width * ( analogBackScaling * scale ) ), (int) ( analogBackImage.height * ( analogBackScaling * scale ) ) );
}
}
else
{
@@ -482,6 +501,8 @@ public void updateButton( Profile profile, String name )
{
buttonX.set( i, x );
buttonY.set( i, y );
buttonImages.get( i ).fitPercent( buttonX.get( i ), buttonY.get( i ), w, h );
buttonMasks.get( i ).fitPercent( buttonX.get( i ), buttonY.get( i ), w, h );
}
}
}
@@ -557,6 +578,7 @@ protected void loadAnalog( Profile profile, boolean animated )
{
int x = profile.getInt( "analog-x", -1 );
int y = profile.getInt( "analog-y", -1 );
int scaling = profile.getInt("analog-scale", 100);

if( x >= 0 && y >= 0 )
{
@@ -579,6 +601,7 @@ protected void loadAnalog( Profile profile, boolean animated )
analogDeadzone = (int) ( analogBackImage.hWidth * ( profile.getFloat( "analog-min", 1 ) / 100.0f ) );
analogMaximum = (int) ( analogBackImage.hWidth * ( profile.getFloat( "analog-max", 55 ) / 100.0f ) );
analogPadding = (int) ( analogBackImage.hWidth * ( profile.getFloat( "analog-buff", 55 ) / 100.0f ) );
analogBackScaling = (float) scaling / 100.f;
}
}

@@ -592,6 +615,7 @@ protected void loadButton( Profile profile, String name )
{
int x = profile.getInt( name + "-x", -1 );
int y = profile.getInt( name + "-y", -1 );
int scaling = profile.getInt( name + "-scale", 100);

if( x >= 0 && y >= 0 )
{
@@ -603,6 +627,7 @@ protected void loadButton( Profile profile, String name )
// Load the displayed and mask images
buttonImages.add( new Image( mResources, skinFolder + "/" + name + ".png" ) );
buttonMasks.add( new Image( mResources, skinFolder + "/" + name + "-mask.png" ) );
buttonScaling.add( (float) scaling / 100.f );
}
}

@@ -23,6 +23,7 @@
import java.util.concurrent.CopyOnWriteArrayList;

import paulscode.android.mupen64plusae.game.GameOverlay;
import paulscode.android.mupen64plusae.input.AbstractController;
import paulscode.android.mupen64plusae.persistent.ConfigFile;
import paulscode.android.mupen64plusae.profile.Profile;
import paulscode.android.mupen64plusae.util.Image;
@@ -198,19 +199,28 @@ public void resize( int w, int h )
// Compute analog foreground location (centered)
if( analogBackImage != null && analogForeImage != null )
{
int cX = analogBackImage.x + (int) ( analogBackImage.hWidth * scale );
int cY = analogBackImage.y + (int) ( analogBackImage.hHeight * scale );
analogForeImage.setScale( scale );
int cX = analogBackImage.x + (int) ( analogBackImage.hWidth * ( analogBackScaling * scale ) );
int cY = analogBackImage.y + (int) ( analogBackImage.hHeight * ( analogBackScaling * scale ) );
analogForeImage.setScale( ( analogBackScaling * scale ) );
analogForeImage.fitCenter( cX, cY, analogBackImage.x, analogBackImage.y,
(int) ( analogBackImage.width * scale ), (int) ( analogBackImage.height * scale ) );
(int) ( analogBackImage.width * ( analogBackScaling * scale ) ), (int) ( analogBackImage.height * ( analogBackScaling * scale ) ) );
}

// Compute auto-hold overlay locations
for( int i = 0; i < autoHoldImages.length; i++ )
{
if( autoHoldImages[i] != null )
{
autoHoldImages[i].setScale( scale );
String name = ASSET_NAMES.get( i );
float scaling = 1.f;

for( int j = 0; j < buttonNames.size(); j++ )
{
if ( buttonNames.get( j ).equals( name ) )
scaling = buttonScaling.get( j );
}

autoHoldImages[i].setScale( ( scaling * scale ) );
autoHoldImages[i].fitPercent( autoHoldX[i], autoHoldY[i], w, h );
}
}
@@ -318,20 +328,20 @@ public boolean updateAnalog( float axisFractionX, float axisFractionY )
if( analogForeImage != null && analogBackImage != null )
{
// Get the location of stick center
int hX = (int) ( ( analogBackImage.hWidth + ( axisFractionX * analogMaximum ) ) * scale );
int hY = (int) ( ( analogBackImage.hHeight - ( axisFractionY * analogMaximum ) ) * scale );
int hX = (int) ( ( analogBackImage.hWidth + ( axisFractionX * analogMaximum ) ) * ( analogBackScaling * scale ) );
int hY = (int) ( ( analogBackImage.hHeight - ( axisFractionY * analogMaximum ) ) * ( analogBackScaling * scale ) );

// Use other values if invalid
if( hX < 0 )
hX = (int) ( analogBackImage.hWidth * scale );
hX = (int) ( analogBackImage.hWidth * ( analogBackScaling * scale ) );
if( hY < 0 )
hY = (int) ( analogBackImage.hHeight * scale );
hY = (int) ( analogBackImage.hHeight * ( analogBackScaling * scale ) );

// Update the position of the stick
int cX = analogBackImage.x + hX;
int cY = analogBackImage.y + hY;
analogForeImage.fitCenter( cX, cY, analogBackImage.x, analogBackImage.y,
(int) ( analogBackImage.width * scale ), (int) ( analogBackImage.height * scale ) );
(int) ( analogBackImage.width * ( analogBackScaling * scale ) ), (int) ( analogBackImage.height * ( analogBackScaling * scale ) ) );
return true;
}
return false;
@@ -473,8 +483,7 @@ public void load( String skinDir, Profile profile, boolean animated, boolean fps
*/
public void refreshButtonPosition( Profile profile, String name )
{
super.updateButton( profile, name );
resize( cacheWidth, cacheHeight, cacheMetrics );
super.updateButton( profile, name, cacheWidth, cacheHeight );
}

/*

0 comments on commit d15ad5c

Please sign in to comment.