1 /* 2 * Copyright (C) 2014 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.example.android.visualgamecontroller; 18 19 import android.content.Context; 20 import android.graphics.Bitmap; 21 import android.graphics.BitmapFactory; 22 import android.graphics.BlurMaskFilter; 23 import android.graphics.Canvas; 24 import android.graphics.Color; 25 import android.graphics.Paint; 26 import android.graphics.Point; 27 import android.util.AttributeSet; 28 import android.util.Log; 29 import android.view.Display; 30 import android.view.SurfaceHolder; 31 import android.view.SurfaceView; 32 import android.view.WindowManager; 33 34 import com.example.android.visualgamecontroller.FullscreenActivity.AxesMapping; 35 import com.example.android.visualgamecontroller.FullscreenActivity.ButtonMapping; 36 37 /** 38 * Custom view to display the game controller state visually. 39 */ 40 public class ControllerView extends SurfaceView implements 41 SurfaceHolder.Callback { 42 private static final String TAG = "ControllerView"; 43 private static final float IMAGE_RESOLUTION_HEIGHT = 1080.0F; 44 private static final int MAX_CONTROLLERS = 4; 45 46 private WindowManager mWindowManager; 47 private Bitmap mControllerBitmap; 48 private Bitmap mAxisBitmap; 49 private Bitmap mBlueLedBitmap; 50 private Bitmap mRightDirectionalBitmap; 51 private Bitmap mTopDirectionalBitmap; 52 private Bitmap mLeftDirectionalBitmap; 53 private Bitmap mBottomDirectionalBitmap; 54 private Bitmap mRightPaddleBitmap; 55 private Bitmap mLeftPaddleBitmap; 56 private Bitmap mGradientBitmap; 57 private Paint mBackgroundPaint; 58 private Paint mImagePaint; 59 private Paint mCirclePaint; 60 private Paint mLedPaint; 61 private Paint mDirectionalPaint; 62 private Paint mGradientPaint; 63 private Point mSize = new Point(); 64 private float mDisplayRatio = 1.0f; 65 private int[] mButtons; 66 private float[] mAxes; 67 private int mCurrentControllerNumber = -1; 68 // Image asset locations 69 private float[] mYButton = { 70 823 / IMAGE_RESOLUTION_HEIGHT, 276 / IMAGE_RESOLUTION_HEIGHT, 71 34 / IMAGE_RESOLUTION_HEIGHT 72 }; 73 private float[] mXButton = { 74 744 / IMAGE_RESOLUTION_HEIGHT, 355 / IMAGE_RESOLUTION_HEIGHT, 75 34 / IMAGE_RESOLUTION_HEIGHT 76 }; 77 private float[] mBButton = { 78 903 / IMAGE_RESOLUTION_HEIGHT, 355 / IMAGE_RESOLUTION_HEIGHT, 79 34 / IMAGE_RESOLUTION_HEIGHT 80 }; 81 private float[] mAButton = { 82 823 / IMAGE_RESOLUTION_HEIGHT, 434 / IMAGE_RESOLUTION_HEIGHT, 83 34 / IMAGE_RESOLUTION_HEIGHT 84 }; 85 private float[] mPowerButton = { 86 533 / IMAGE_RESOLUTION_HEIGHT, 353 / IMAGE_RESOLUTION_HEIGHT, 87 50 / IMAGE_RESOLUTION_HEIGHT 88 }; 89 private float[] mHomeButton = { 90 624 / IMAGE_RESOLUTION_HEIGHT, 353 / IMAGE_RESOLUTION_HEIGHT, 91 30 / IMAGE_RESOLUTION_HEIGHT 92 }; 93 private float[] mBackButton = { 94 443 / IMAGE_RESOLUTION_HEIGHT, 353 / IMAGE_RESOLUTION_HEIGHT, 95 30 / IMAGE_RESOLUTION_HEIGHT 96 }; 97 private float[] mLedButtons = { 98 463 / IMAGE_RESOLUTION_HEIGHT, 449 / IMAGE_RESOLUTION_HEIGHT, 99 502 / IMAGE_RESOLUTION_HEIGHT, 449 / IMAGE_RESOLUTION_HEIGHT, 100 539 / IMAGE_RESOLUTION_HEIGHT, 101 449 / IMAGE_RESOLUTION_HEIGHT, 574 / IMAGE_RESOLUTION_HEIGHT, 102 449 / IMAGE_RESOLUTION_HEIGHT 103 }; 104 private float[] mRightDirectionalButton = { 105 264 / IMAGE_RESOLUTION_HEIGHT, 336 / IMAGE_RESOLUTION_HEIGHT 106 }; 107 private float[] mTopDirectionalButton = { 108 218 / IMAGE_RESOLUTION_HEIGHT, 263 / IMAGE_RESOLUTION_HEIGHT 109 }; 110 private float[] mLeftDirectionalButton = { 111 144 / IMAGE_RESOLUTION_HEIGHT, 337 / IMAGE_RESOLUTION_HEIGHT 112 }; 113 private float[] mBottomDirectionalButton = { 114 217 / IMAGE_RESOLUTION_HEIGHT, 384 / IMAGE_RESOLUTION_HEIGHT 115 }; 116 private float[] mLeftAxis = { 117 305 / IMAGE_RESOLUTION_HEIGHT, 485 / IMAGE_RESOLUTION_HEIGHT, 118 63 / IMAGE_RESOLUTION_HEIGHT, 50 / IMAGE_RESOLUTION_HEIGHT 119 }; 120 private float[] mRightAxis = { 121 637 / IMAGE_RESOLUTION_HEIGHT, 485 / IMAGE_RESOLUTION_HEIGHT, 122 63 / IMAGE_RESOLUTION_HEIGHT, 50 / IMAGE_RESOLUTION_HEIGHT 123 }; 124 private float[] mRightPaddle = { 125 705 / IMAGE_RESOLUTION_HEIGHT, 166 / IMAGE_RESOLUTION_HEIGHT 126 }; 127 private float[] mRightPaddlePressed = { 128 705 / IMAGE_RESOLUTION_HEIGHT, 180 / IMAGE_RESOLUTION_HEIGHT 129 }; 130 private float[] mLeftPaddle = { 131 135 / IMAGE_RESOLUTION_HEIGHT, 166 / IMAGE_RESOLUTION_HEIGHT 132 }; 133 private float[] mLeftPaddlePressed = { 134 135 / IMAGE_RESOLUTION_HEIGHT, 180 / IMAGE_RESOLUTION_HEIGHT 135 }; 136 private float[] mLeftAxisButton = { 137 368 / IMAGE_RESOLUTION_HEIGHT, 548 / IMAGE_RESOLUTION_HEIGHT, 138 64 / IMAGE_RESOLUTION_HEIGHT 139 }; 140 private float[] mRightAxisButton = { 141 700 / IMAGE_RESOLUTION_HEIGHT, 548 / IMAGE_RESOLUTION_HEIGHT, 142 64 / IMAGE_RESOLUTION_HEIGHT 143 }; 144 private float[] mRightGradient = { 145 705 / IMAGE_RESOLUTION_HEIGHT, 125 / IMAGE_RESOLUTION_HEIGHT 146 }; 147 private float[] mLeftGradient = { 148 125 / IMAGE_RESOLUTION_HEIGHT, 125 / IMAGE_RESOLUTION_HEIGHT 149 }; 150 private float mAxisLeftX, mAxisLeftY; 151 private float mAxisRightX, mAxisRightY; 152 153 /** 154 * Class constructor taking only a context. Use this constructor to create 155 * {@link ControllerView} objects from your own code. 156 * 157 * @param context 158 */ ControllerView(Context context)159 public ControllerView(Context context) { 160 super(context); 161 init(); 162 } 163 164 /** 165 * Class constructor taking a context and an attribute set. This constructor 166 * is used by the layout engine to construct a {@link ControllerView} from a 167 * set of XML attributes. 168 * 169 * @param context 170 * @param attrs An attribute set which can contain attributes from 171 * {@link com.example.android.customviews.R.styleable.ControllerView} 172 * as well as attributes inherited from {@link android.view.View} 173 */ ControllerView(Context context, AttributeSet attrs)174 public ControllerView(Context context, AttributeSet attrs) { 175 super(context, attrs); 176 init(); 177 } 178 179 /** 180 * Initialize the custom control. 181 */ init()182 private void init() { 183 mWindowManager = (WindowManager) getContext().getSystemService(Context.WINDOW_SERVICE); 184 mBackgroundPaint = new Paint(); 185 mBackgroundPaint.setStyle(Paint.Style.FILL); 186 mBackgroundPaint.setDither(true); 187 mBackgroundPaint.setAntiAlias(true); 188 189 mImagePaint = new Paint(); 190 191 mCirclePaint = new Paint(); 192 mCirclePaint.setStyle(Paint.Style.FILL); 193 mCirclePaint.setDither(true); 194 mCirclePaint.setAntiAlias(true); 195 196 mLedPaint = new Paint(); 197 mLedPaint.setStyle(Paint.Style.FILL); 198 mLedPaint.setDither(true); 199 mLedPaint.setAntiAlias(true); 200 BlurMaskFilter blurMaskFilter = new BlurMaskFilter(20.0f, BlurMaskFilter.Blur.OUTER); 201 mLedPaint.setMaskFilter(blurMaskFilter); 202 203 mDirectionalPaint = new Paint(); 204 mDirectionalPaint.setDither(true); 205 mDirectionalPaint.setAntiAlias(true); 206 mDirectionalPaint.setAlpha(204); 207 208 mGradientPaint = new Paint(); 209 mGradientPaint.setDither(true); 210 mGradientPaint.setAntiAlias(true); 211 mGradientPaint.setAlpha(204); 212 } 213 loadBitmaps(int displayWidth, int displayHeight)214 private void loadBitmaps(int displayWidth, int displayHeight) { 215 // Load the image resources 216 mControllerBitmap = BitmapFactory.decodeResource(getResources(), 217 R.drawable.game_controller_paddles); 218 int controllerBitmapWidth = mControllerBitmap.getWidth(); 219 int controllerBitmapHeight = mControllerBitmap.getHeight(); 220 mAxisBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.axis); 221 mBlueLedBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.led_blue); 222 mRightDirectionalBitmap = BitmapFactory.decodeResource(getResources(), 223 R.drawable.directional_right); 224 mTopDirectionalBitmap = BitmapFactory.decodeResource(getResources(), 225 R.drawable.directional_top); 226 mLeftDirectionalBitmap = BitmapFactory.decodeResource(getResources(), 227 R.drawable.directional_left); 228 mBottomDirectionalBitmap = BitmapFactory.decodeResource(getResources(), 229 R.drawable.directional_bottom); 230 mRightPaddleBitmap = BitmapFactory.decodeResource(getResources(), 231 R.drawable.right_paddle); 232 mLeftPaddleBitmap = BitmapFactory.decodeResource(getResources(), 233 R.drawable.left_paddle); 234 mGradientBitmap = BitmapFactory.decodeResource(getResources(), 235 R.drawable.gradient); 236 237 mControllerBitmap = Bitmap.createScaledBitmap(mControllerBitmap, displayHeight, 238 displayHeight, true); 239 240 mDisplayRatio = displayHeight * 1.0f / controllerBitmapHeight; 241 // Scale the image bitmaps 242 mAxisBitmap = Bitmap.createScaledBitmap(mAxisBitmap, 243 (int) (mAxisBitmap.getWidth() * mDisplayRatio), 244 (int) (mAxisBitmap.getHeight() * mDisplayRatio), 245 true); 246 mBlueLedBitmap = Bitmap.createScaledBitmap(mBlueLedBitmap, 247 (int) (mBlueLedBitmap.getWidth() * mDisplayRatio), 248 (int) (mBlueLedBitmap.getHeight() * mDisplayRatio), 249 true); 250 mRightDirectionalBitmap = Bitmap.createScaledBitmap(mRightDirectionalBitmap, 251 (int) (mRightDirectionalBitmap.getWidth() * mDisplayRatio), 252 (int) (mRightDirectionalBitmap.getHeight() * mDisplayRatio), 253 true); 254 mTopDirectionalBitmap = Bitmap.createScaledBitmap(mTopDirectionalBitmap, 255 (int) (mTopDirectionalBitmap.getWidth() * mDisplayRatio), 256 (int) (mTopDirectionalBitmap.getHeight() * mDisplayRatio), 257 true); 258 mLeftDirectionalBitmap = Bitmap.createScaledBitmap(mLeftDirectionalBitmap, 259 (int) (mLeftDirectionalBitmap.getWidth() * mDisplayRatio), 260 (int) (mLeftDirectionalBitmap.getHeight() * mDisplayRatio), 261 true); 262 mBottomDirectionalBitmap = Bitmap.createScaledBitmap(mBottomDirectionalBitmap, 263 (int) (mBottomDirectionalBitmap.getWidth() * mDisplayRatio), 264 (int) (mBottomDirectionalBitmap.getHeight() * mDisplayRatio), 265 true); 266 mRightPaddleBitmap = Bitmap.createScaledBitmap(mRightPaddleBitmap, 267 (int) (mRightPaddleBitmap.getWidth() * mDisplayRatio), 268 (int) (mRightPaddleBitmap.getHeight() * mDisplayRatio), 269 true); 270 mLeftPaddleBitmap = Bitmap.createScaledBitmap(mLeftPaddleBitmap, 271 (int) (mLeftPaddleBitmap.getWidth() * mDisplayRatio), 272 (int) (mLeftPaddleBitmap.getHeight() * mDisplayRatio), 273 true); 274 mGradientBitmap = Bitmap.createScaledBitmap(mGradientBitmap, 275 (int) (mGradientBitmap.getWidth() * mDisplayRatio), 276 (int) (mGradientBitmap.getHeight() * mDisplayRatio), 277 true); 278 } 279 280 @Override surfaceChanged(SurfaceHolder holder, int format, int width, int height)281 public void surfaceChanged(SurfaceHolder holder, int format, int width, 282 int height) { 283 } 284 285 @Override surfaceCreated(SurfaceHolder holder)286 public void surfaceCreated(SurfaceHolder holder) { 287 } 288 289 @Override surfaceDestroyed(SurfaceHolder holder)290 public void surfaceDestroyed(SurfaceHolder holder) { 291 } 292 293 /* 294 * (non-Javadoc) 295 * @see android.view.SurfaceView#onMeasure(int, int) 296 */ onMeasure(int widthMeasureSpec, int heightMeasureSpec)297 protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { 298 int width = 0; 299 int height = 0; 300 301 Display display = mWindowManager.getDefaultDisplay(); 302 display.getSize(mSize); 303 int displayWidth = mSize.x; 304 int displayHeight = mSize.y; 305 displayWidth = getWidth(); 306 displayHeight = getHeight(); 307 308 int widthSpecMode = MeasureSpec.getMode(widthMeasureSpec); 309 int widthSpecSize = MeasureSpec.getSize(widthMeasureSpec); 310 int heightSpecMode = MeasureSpec.getMode(heightMeasureSpec); 311 int heightSpecSize = MeasureSpec.getSize(heightMeasureSpec); 312 Log.d(TAG, "widthSpecSize=" + widthSpecSize + ", heightSpecSize=" + heightSpecSize); 313 314 if (widthSpecMode == MeasureSpec.EXACTLY) { 315 width = widthSpecSize; 316 } else if (widthSpecMode == MeasureSpec.AT_MOST) { 317 width = Math.min(displayWidth, widthSpecSize); 318 } else { 319 width = displayWidth; 320 } 321 322 if (heightSpecMode == MeasureSpec.EXACTLY) { 323 height = heightSpecSize; 324 } else if (heightSpecMode == MeasureSpec.AT_MOST) { 325 height = Math.min(displayHeight, heightSpecSize); 326 } else { 327 height = displayHeight; 328 } 329 330 setMeasuredDimension(width, height); 331 332 if (width > 0 && height > 0) { 333 loadBitmaps(width, height); 334 } 335 } 336 337 /* 338 * (non-Javadoc) 339 * @see android.view.View#onDraw(android.graphics.Canvas) 340 */ 341 @Override onDraw(Canvas canvas)342 protected void onDraw(Canvas canvas) { 343 int offset = getWidth() / 2 - getHeight() / 2; 344 345 // Draw the background 346 canvas.drawColor(Color.BLACK); 347 canvas.drawRect(0, 0, getWidth(), getHeight(), mBackgroundPaint); 348 349 // Draw the brake/gas indicators 350 if (mAxes[AxesMapping.AXIS_BRAKE.ordinal()] > 0.0f) { 351 mGradientPaint.setAlpha((int) (mAxes[AxesMapping.AXIS_BRAKE.ordinal()] * 100) + 155); 352 canvas.drawBitmap(mGradientBitmap, offset + mLeftGradient[0] 353 * getHeight(), mLeftGradient[1] * getHeight(), mGradientPaint); 354 } 355 if (mAxes[AxesMapping.AXIS_GAS.ordinal()] > 0.0f) { 356 mGradientPaint.setAlpha((int) (mAxes[AxesMapping.AXIS_GAS.ordinal()] * 100) + 155); 357 canvas.drawBitmap(mGradientBitmap, offset + mRightGradient[0] 358 * getHeight(), mRightGradient[1] * getHeight(), mGradientPaint); 359 } 360 361 // Draw the paddles 362 canvas.drawColor(Color.TRANSPARENT); 363 if (mButtons[ButtonMapping.BUTTON_R1.ordinal()] == 0) { 364 canvas.drawBitmap(mRightPaddleBitmap, offset + mRightPaddle[0] 365 * getHeight(), mRightPaddle[1] * getHeight(), mImagePaint); 366 } else if (mButtons[ButtonMapping.BUTTON_R1.ordinal()] == 1) { 367 canvas.drawBitmap(mRightPaddleBitmap, offset + mRightPaddlePressed[0] 368 * getHeight(), mRightPaddlePressed[1] * getHeight(), mImagePaint); 369 } 370 if (mButtons[ButtonMapping.BUTTON_L1.ordinal()] == 0) { 371 canvas.drawBitmap(mLeftPaddleBitmap, offset + mLeftPaddle[0] 372 * getHeight(), mLeftPaddle[1] * getHeight(), mImagePaint); 373 } 374 else if (mButtons[ButtonMapping.BUTTON_L1.ordinal()] == 1) { 375 canvas.drawBitmap(mLeftPaddleBitmap, offset + mLeftPaddlePressed[0] 376 * getHeight(), mLeftPaddlePressed[1] * getHeight(), mImagePaint); 377 } 378 379 // Draw the controller body 380 canvas.drawBitmap(mControllerBitmap, offset, 0, mImagePaint); 381 382 // Draw the axes 383 mAxisLeftX = offset + mLeftAxis[0] * getHeight(); 384 mAxisLeftY = mLeftAxis[1] * getHeight(); 385 mAxisRightX = offset + mRightAxis[0] * getHeight(); 386 mAxisRightY = mRightAxis[1] * getHeight(); 387 if (mAxes[AxesMapping.AXIS_X.ordinal()] != 0.0f) { 388 mAxisLeftX = mAxisLeftX + mLeftAxis[3] * getHeight() 389 * mAxes[AxesMapping.AXIS_X.ordinal()]; 390 } 391 if (mAxes[AxesMapping.AXIS_Y.ordinal()] != 0.0f) { 392 mAxisLeftY = mAxisLeftY + mLeftAxis[3] 393 * getHeight() * mAxes[AxesMapping.AXIS_Y.ordinal()]; 394 } 395 canvas.drawBitmap(mAxisBitmap, mAxisLeftX, mAxisLeftY, mImagePaint); 396 if (mAxes[AxesMapping.AXIS_Z.ordinal()] != 0.0f) { 397 mAxisRightX = mAxisRightX + mRightAxis[3] * getHeight() 398 * mAxes[AxesMapping.AXIS_Z.ordinal()]; 399 } 400 if (mAxes[AxesMapping.AXIS_RZ.ordinal()] != 0.0f) { 401 mAxisRightY = mAxisRightY + mRightAxis[3] 402 * getHeight() * mAxes[AxesMapping.AXIS_RZ.ordinal()]; 403 } 404 canvas.drawBitmap(mAxisBitmap, mAxisRightX, mAxisRightY, mImagePaint); 405 406 // Draw the LED light 407 if (mCurrentControllerNumber > 0 && mCurrentControllerNumber <= MAX_CONTROLLERS) { 408 canvas.drawBitmap(mBlueLedBitmap, offset 409 + mLedButtons[2 * mCurrentControllerNumber - 2] * getHeight(), 410 mLedButtons[2 * mCurrentControllerNumber - 1] * getHeight(), mLedPaint); 411 } 412 413 // Draw the directional buttons 414 if (mAxes[AxesMapping.AXIS_HAT_X.ordinal()] == 1.0f) { 415 canvas.drawBitmap(mRightDirectionalBitmap, offset + mRightDirectionalButton[0] 416 * getHeight(), 417 mRightDirectionalButton[1] * getHeight(), mDirectionalPaint); 418 } 419 if (mAxes[AxesMapping.AXIS_HAT_Y.ordinal()] == -1.0f) { 420 canvas.drawBitmap(mTopDirectionalBitmap, offset + mTopDirectionalButton[0] 421 * getHeight(), 422 mTopDirectionalButton[1] * getHeight(), mDirectionalPaint); 423 } 424 if (mAxes[AxesMapping.AXIS_HAT_X.ordinal()] == -1.0f) { 425 canvas.drawBitmap(mLeftDirectionalBitmap, offset + mLeftDirectionalButton[0] 426 * getHeight(), 427 mLeftDirectionalButton[1] * getHeight(), mDirectionalPaint); 428 } 429 if (mAxes[AxesMapping.AXIS_HAT_Y.ordinal()] == 1.0f) { 430 canvas.drawBitmap(mBottomDirectionalBitmap, offset + mBottomDirectionalButton[0] 431 * getHeight(), mBottomDirectionalButton[1] * getHeight(), mDirectionalPaint); 432 } 433 434 // Draw the A/B/X/Y buttons 435 canvas.drawColor(Color.TRANSPARENT); 436 mCirclePaint.setColor(getResources().getColor(R.color.transparent_black)); 437 if (mButtons[ButtonMapping.BUTTON_Y.ordinal()] == 1) { 438 canvas.drawCircle(offset + mYButton[0] * getHeight(), mYButton[1] * getHeight(), 439 mYButton[2] * getHeight(), mCirclePaint); 440 } 441 if (mButtons[ButtonMapping.BUTTON_X.ordinal()] == 1) { 442 canvas.drawCircle(offset + mXButton[0] * getHeight(), mXButton[1] * getHeight(), 443 mXButton[2] * getHeight(), mCirclePaint); 444 } 445 if (mButtons[ButtonMapping.BUTTON_B.ordinal()] == 1) { 446 canvas.drawCircle(offset + mBButton[0] * getHeight(), mBButton[1] * getHeight(), 447 mBButton[2] * getHeight(), mCirclePaint); 448 } 449 if (mButtons[ButtonMapping.BUTTON_A.ordinal()] == 1) { 450 canvas.drawCircle(offset + mAButton[0] * getHeight(), mAButton[1] * getHeight(), 451 mAButton[2] * getHeight(), mCirclePaint); 452 } 453 454 // Draw the center buttons 455 if (mButtons[ButtonMapping.POWER.ordinal()] == 1) { 456 canvas.drawCircle(offset + mPowerButton[0] * getHeight(), 457 mPowerButton[1] * getHeight(), 458 mPowerButton[2] * getHeight(), mCirclePaint); 459 } 460 if (mButtons[ButtonMapping.BUTTON_START.ordinal()] == 1) { 461 canvas.drawCircle(offset + mHomeButton[0] * getHeight(), mHomeButton[1] * getHeight(), 462 mHomeButton[2] * getHeight(), mCirclePaint); 463 } 464 if (mButtons[ButtonMapping.BACK.ordinal()] == 1) { 465 canvas.drawCircle(offset + mBackButton[0] * getHeight(), mBackButton[1] * getHeight(), 466 mBackButton[2] * getHeight(), mCirclePaint); 467 } 468 469 // Draw the axes 470 if (mButtons[ButtonMapping.BUTTON_THUMBL.ordinal()] == 1) { 471 canvas.drawCircle(mLeftAxisButton[2] * getHeight() + mAxisLeftX, mLeftAxisButton[2] 472 * getHeight() + mAxisLeftY, 473 mLeftAxisButton[2] * getHeight(), mCirclePaint); 474 } 475 if (mButtons[ButtonMapping.BUTTON_THUMBR.ordinal()] == 1) { 476 canvas.drawCircle(mRightAxisButton[2] * getHeight() + mAxisRightX, mRightAxisButton[2] 477 * getHeight() + mAxisRightY, 478 mRightAxisButton[2] * getHeight(), mCirclePaint); 479 } 480 } 481 482 /** 483 * Set the button and axes mapping data structures. 484 * 485 * @param buttons 486 * @param axes 487 */ setButtonsAxes(int[] buttons, float[] axes)488 public void setButtonsAxes(int[] buttons, float[] axes) { 489 mButtons = buttons; 490 mAxes = axes; 491 } 492 setCurrentControllerNumber(int number)493 public void setCurrentControllerNumber(int number) { 494 Log.d(TAG, "setCurrentControllerNumber: " + number); 495 mCurrentControllerNumber = number; 496 } 497 } 498