package org.inodes.gus.scummvm; import android.app.Activity; import android.app.AlertDialog; import android.content.DialogInterface; import android.media.AudioManager; import android.os.Bundle; import android.os.Environment; import android.util.DisplayMetrics; import android.util.Log; import android.view.SurfaceView; import android.view.SurfaceHolder; import android.view.MotionEvent; import android.view.inputmethod.InputMethodManager; import android.widget.Toast; public class ScummVMActivity extends Activity { private class MyScummVM extends ScummVM { private boolean usingSmallScreen() { // Multiple screen sizes came in with Android 1.6. Have // to use reflection in order to continue supporting 1.5 // devices :( DisplayMetrics metrics = new DisplayMetrics(); getWindowManager().getDefaultDisplay().getMetrics(metrics); try { // This 'density' term is very confusing. int DENSITY_LOW = metrics.getClass().getField("DENSITY_LOW").getInt(null); int densityDpi = metrics.getClass().getField("densityDpi").getInt(metrics); return densityDpi <= DENSITY_LOW; } catch (Exception e) { return false; } } public MyScummVM(SurfaceHolder holder) { super(ScummVMActivity.this.getAssets(), holder); // Enable ScummVM zoning on 'small' screens. // FIXME make this optional for the user // disabled for now since it crops too much //enableZoning(usingSmallScreen()); } @Override protected void getDPI(float[] values) { DisplayMetrics metrics = new DisplayMetrics(); getWindowManager().getDefaultDisplay().getMetrics(metrics); values[0] = metrics.xdpi; values[1] = metrics.ydpi; } @Override protected void displayMessageOnOSD(String msg) { Log.i(LOG_TAG, "OSD: " + msg); Toast.makeText(ScummVMActivity.this, msg, Toast.LENGTH_LONG).show(); } @Override protected void setWindowCaption(final String caption) { runOnUiThread(new Runnable() { public void run() { setTitle(caption); } }); } @Override protected String[] getPluginDirectories() { String[] dirs = new String[1]; dirs[0] = ScummVMApplication.getLastCacheDir().getPath(); return dirs; } @Override protected void showVirtualKeyboard(final boolean enable) { runOnUiThread(new Runnable() { public void run() { showKeyboard(enable); } }); } @Override protected String[] getSysArchives() { return new String[0]; } } private MyScummVM _scummvm; private ScummVMEvents _events; private Thread _scummvm_thread; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setVolumeControlStream(AudioManager.STREAM_MUSIC); setContentView(R.layout.main); takeKeyEvents(true); // This is a common enough error that we should warn about it // explicitly. if (!Environment.getExternalStorageDirectory().canRead()) { new AlertDialog.Builder(this) .setTitle(R.string.no_sdcard_title) .setIcon(android.R.drawable.ic_dialog_alert) .setMessage(R.string.no_sdcard) .setNegativeButton(R.string.quit, new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int which) { finish(); } }) .show(); return; } SurfaceView main_surface = (SurfaceView)findViewById(R.id.main_surface); main_surface.requestFocus(); getFilesDir().mkdirs(); // Start ScummVM _scummvm = new MyScummVM(main_surface.getHolder()); _scummvm.setArgs(new String[] { "ScummVM", "--config=" + getFileStreamPath("scummvmrc").getPath(), "--path=" + Environment.getExternalStorageDirectory().getPath(), "--gui-theme=scummmodern", "--savepath=" + getDir("saves", 0).getPath() }); _events = new ScummVMEvents(this, _scummvm); main_surface.setOnKeyListener(_events); main_surface.setOnTouchListener(_events); _scummvm_thread = new Thread(_scummvm, "ScummVM"); _scummvm_thread.start(); } @Override public void onStart() { Log.d(ScummVM.LOG_TAG, "onStart"); super.onStart(); } @Override public void onResume() { Log.d(ScummVM.LOG_TAG, "onResume"); super.onResume(); if (_scummvm != null) _scummvm.setPause(false); } @Override public void onPause() { Log.d(ScummVM.LOG_TAG, "onPause"); super.onPause(); if (_scummvm != null) _scummvm.setPause(true); } @Override public void onStop() { Log.d(ScummVM.LOG_TAG, "onStop"); super.onStop(); } @Override public void onDestroy() { Log.d(ScummVM.LOG_TAG, "onDestroy"); super.onDestroy(); if (_events != null) { _events.sendQuitEvent(); try { // 1s timeout _scummvm_thread.join(1000); } catch (InterruptedException e) { Log.i(ScummVM.LOG_TAG, "Error while joining ScummVM thread", e); } _scummvm = null; } } @Override public boolean onTrackballEvent(MotionEvent e) { if (_events != null) return _events.onTrackballEvent(e); return false; } private void showKeyboard(boolean show) { SurfaceView main_surface = (SurfaceView)findViewById(R.id.main_surface); InputMethodManager imm = (InputMethodManager) getSystemService(INPUT_METHOD_SERVICE); if (show) imm.showSoftInput(main_surface, InputMethodManager.SHOW_IMPLICIT); else imm.hideSoftInputFromWindow(main_surface.getWindowToken(), InputMethodManager.HIDE_IMPLICIT_ONLY); } }