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