/* Copyright (C) 2013 Victor Olausson, Patrik Wållgren This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/ */ package bgsep.virtualgamepad; import java.util.ArrayList; import java.util.Observable; import java.util.Observer; import bgsep.communication.Communication; import bgsep.communication.CommunicationNotifier; import bgsep.model.Button; import bgsep.model.Gyro; import bgsep.model.JoystickHandler; import android.app.Activity; import android.content.Context; import android.content.Intent; import android.hardware.SensorManager; import android.os.Bundle; import android.os.Vibrator; import android.view.Menu; import android.view.MenuItem; import android.view.View; import android.view.ViewConfiguration; import android.view.WindowManager.LayoutParams; import android.widget.ImageView; /** * The activity for the GC controller * @author Victor Olausson * @author Patrik Wållgren * */ public class GcActivity extends Activity implements Observer { private boolean isInitialized; ImageView aImageView, bImageView, xImageView, yImageView, imageStart, imageBoundary, imageStick; private JoystickHandler gcJoystick; private Gyro gyro; private Button aButton, bButton, xButton, yButton, startButton; private ArrayList<Button> buttons; private Communication comm; private boolean hapticFeedback; private boolean useAccelerometer; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_gc); // Keep screen on getWindow().addFlags(LayoutParams.FLAG_KEEP_SCREEN_ON); //Dim soft menu keys if present if (!ViewConfiguration.get(this).hasPermanentMenuKey()) getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LOW_PROFILE); Intent i = getIntent(); hapticFeedback = i.getBooleanExtra("hapticFeedback", false); useAccelerometer = i.getBooleanExtra("useAccelerometer", false); isInitialized = false; comm = Communication.getInstance(); if(useAccelerometer) initGyro(); } @Override public void onWindowFocusChanged(boolean hasChanged) { // Initialization of the joystick must happen when all the views has been drawn. // Therefore initialize it when the window has focus and not in onCreate. if(!isInitialized) { initImages(); initButtons(); initJoystick(); isInitialized = true; } super.onWindowFocusChanged(hasChanged); } @Override public void update(Observable o, Object data) { // Joystick and Button movement handling if(o instanceof JoystickHandler && !(data instanceof CommunicationNotifier)) { JoystickHandler joystick = (JoystickHandler)o; ImageView stick = joystick.getStick(); ImageView boundary = joystick.getBoundary(); stick.setX((joystick.getX() * boundary.getWidth()/2) + boundary.getLeft() + boundary.getWidth()/2-stick.getWidth()/2); stick.setY((joystick.getY() * boundary.getHeight()/2 * -1) + boundary.getTop() + boundary.getHeight()/2-stick.getHeight()/2); } else if(o instanceof Button) { Button button = (Button)o; if(button.isPressed()) button.getButtonView().setImageResource(button.getPressedDrawableID()); else button.getButtonView().setImageResource(button.getUnPressedDrawableID()); } } @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.gc, menu); return true; } @Override public boolean onOptionsItemSelected(MenuItem item) { // Handle item selection Intent i; switch (item.getItemId()) { case R.id.action_nes: i = new Intent(this, NesActivity.class); i.putExtra("hapticFeedback", hapticFeedback); i.putExtra("useAccelerometer", useAccelerometer); startActivity(i); finish(); return true; case R.id.action_ps: i = new Intent(this, PsActivity.class); i.putExtra("hapticFeedback", hapticFeedback); i.putExtra("useAccelerometer", useAccelerometer); startActivity(i); finish(); return true; default: return super.onOptionsItemSelected(item); } } private void initImages() { aImageView = (ImageView)findViewById(R.id.gc_a_button); bImageView = (ImageView)findViewById(R.id.gc_b_button); xImageView = (ImageView)findViewById(R.id.gc_x_button); yImageView = (ImageView)findViewById(R.id.gc_y_button); imageStart = (ImageView)findViewById(R.id.gc_start_button); imageBoundary = (ImageView)findViewById(R.id.gc_joystickboundary); imageStick = (ImageView)findViewById(R.id.gc_joystick); } private void initButtons() { Vibrator vibrator = (Vibrator)getSystemService(Context.VIBRATOR_SERVICE); aButton = new Button(aImageView, R.drawable.gc_a_button, R.drawable.gc_a_button_pressed, 0, this, vibrator, hapticFeedback); bButton = new Button(bImageView, R.drawable.gc_b_button, R.drawable.gc_b_button_pressed, 1, this, vibrator, hapticFeedback); xButton = new Button(xImageView, R.drawable.gc_x_button, R.drawable.gc_x_button_pressed, 2, this, vibrator, hapticFeedback); yButton = new Button(yImageView, R.drawable.gc_y_button, R.drawable.gc_y_button_pressed, 3, this, vibrator, hapticFeedback); startButton = new Button(imageStart, R.drawable.gc_start_button, R.drawable.gc_start_button_pressed, 4, this, vibrator, hapticFeedback); buttons = new ArrayList<Button>(); buttons.add(aButton); buttons.add(bButton); buttons.add(startButton); buttons.add(xButton); buttons.add(yButton); for(Button b : buttons) b.addObserver(comm); } private void initJoystick() { gcJoystick = new JoystickHandler(imageBoundary, imageStick); gcJoystick.setLeftRightJoystickID(5, 6); gcJoystick.setUpDownJoystickID(7, 8); gcJoystick.addObserver(this); gcJoystick.addObserver(comm); } private void initGyro() { SensorManager sensorManager = (SensorManager)getSystemService(Context.SENSOR_SERVICE); gyro = new Gyro(sensorManager); gyro.setLeftRightGyroID(9, 10); gyro.setEnabled(useAccelerometer); gyro.registerListener(); gyro.addObserver(comm); } @Override public void onDestroy() { super.onDestroy(); releaseAliciaKeys(); } @Override public void onPause() { super.onPause(); releaseAliciaKeys(); } @Override public void onResume() { super.onResume(); if(useAccelerometer) gyro.registerListener(); } private void releaseAliciaKeys() { if(useAccelerometer) gyro.unregisterListener(); unPressAllButtons(); gcJoystick.releaseJoystick(); } private void unPressAllButtons() { for(Button b : buttons) b.setPressed(false); } }