package com.ferg.afergulator; import android.app.ActionBar; import android.app.Activity; import android.content.*; import android.graphics.Color; import android.net.Uri; import android.os.Bundle; import android.os.PowerManager; import android.view.*; import android.widget.*; import java.io.*; import java.util.Set; import butterknife.*; import timber.log.Timber; import com.ferg.afergulator.widget.ButtonNES; import com.ferg.afergulator.widget.ButtonNES.Key; import go.nesdroid.*; public class MainActivity extends Activity implements ActionBar.OnNavigationListener { private static final int FILE_SELECT_CODE = 0xc001; static { if (BuildConfig.DEBUG) Timber.plant(new Timber.DebugTree()); } @InjectView(R.id.gameView) GameView mGameView; private RomAdapter romAdapter; private SharedPreferences mRecentPrefs; protected PowerManager.WakeLock mWakeLock; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); requestWindowFeature(Window.FEATURE_ACTION_BAR_OVERLAY); setContentView(R.layout.main); ButterKnife.inject(this); mRecentPrefs = getSharedPreferences("recent", MODE_PRIVATE); getActionBar().setNavigationMode(ActionBar.NAVIGATION_MODE_LIST); getActionBar().setDisplayShowTitleEnabled(false); setSpinnerAdapter(); final PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE); mWakeLock = pm.newWakeLock(PowerManager.SCREEN_BRIGHT_WAKE_LOCK, "Fergulator"); mWakeLock.acquire(); } public void setSpinnerAdapter() { romAdapter = new RomAdapter(); getActionBar().setListNavigationCallbacks(romAdapter, this); } @Override protected void onResume() { super.onResume(); mGameView.onResume(); } @Override protected void onPause() { super.onPause(); mGameView.onPause(); } @Override public boolean onCreateOptionsMenu(Menu menu) { // TODO: Leave this out until save states work // getMenuInflater().inflate(R.menu.main_nes, menu); return true; } @Override public boolean onOptionsItemSelected(MenuItem item) { switch (item.getItemId()) { case R.id.menu_nes_load: Nesdroid.LoadState(); return true; case R.id.menu_nes_save: Nesdroid.SaveState(); return true; case R.id.menu_nes_shutdown: Toast.makeText(this, "power down not implemented yet", Toast.LENGTH_SHORT).show(); return true; } return super.onOptionsItemSelected(item); } @Override public boolean onKeyDown(int keyCode, KeyEvent event) { Key nesKey = ButtonNES.keyFromKeyCode(keyCode); if (nesKey != null) { Engine.buttonDown(nesKey); return true; } return false; } @Override public boolean onKeyUp(int keyCode, KeyEvent event) { Key nesKey = ButtonNES.keyFromKeyCode(keyCode); if (nesKey != null) { Engine.buttonUp(nesKey); return true; } return false; } @OnClick(R.id.frameLayout) public void toggleActionBar() { if (getActionBar().isShowing()) { getActionBar().hide(); mGameView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LOW_PROFILE); } else { mGameView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_VISIBLE); getActionBar().show(); } } private class RomAdapter extends ArrayAdapter<String> { int mHighlightColor; public RomAdapter() { super(MainActivity.this, R.layout.rom_spinner_item); mHighlightColor = getResources().getColor(android.R.color.holo_blue_light); add("Select ROM:"); add("Browse..."); Set<String> recent = (mRecentPrefs.getAll() == null) ? null : mRecentPrefs.getAll().keySet(); if (recent != null) { addAll(recent); } } @Override public View getDropDownView(int position, View convertView, ViewGroup parent) { TextView v = (TextView) super.getDropDownView(position, convertView, parent); int i = getActionBar().getSelectedNavigationIndex(); v.setTextColor(position == i ? Color.WHITE : mHighlightColor); return v; } } @Override public boolean onNavigationItemSelected(int itemPosition, long itemId) { if (itemPosition == 0) return false; if (itemPosition == 1) { Intent intent = new Intent(Intent.ACTION_GET_CONTENT); intent.setType("*/*"); intent.addCategory(Intent.CATEGORY_OPENABLE); try { startActivityForResult(Intent.createChooser(intent, "Select a NES rom:"), FILE_SELECT_CODE); } catch (ActivityNotFoundException ex) { Toast.makeText(this, "No file browser. =(", Toast.LENGTH_SHORT).show(); } getActionBar().setSelectedNavigationItem(0); return true; } Nesdroid.PauseEmulator(); String rom = romAdapter.getItem(itemPosition); String romUriString = mRecentPrefs.getString(rom, null); if (romUriString != null) { loadRom(Uri.parse(romUriString)); } return true; } private void loadRom(Uri uri) { Timber.d("Loading ROM: %s", uri); String name = uri.getLastPathSegment(); if (name != null && name.endsWith(".zip")) { Timber.d("ZIP File: TODO"); } InputStream is = null; try { is = getContentResolver().openInputStream(uri); mGameView.loadGame(is, name); toggleActionBar(); } catch (IOException e) { Toast.makeText(this, "Invalid NES rom!", Toast.LENGTH_SHORT).show(); Timber.w(e, "Invalid NES rom!"); mRecentPrefs.edit().remove(name).apply(); romAdapter.remove(name); getActionBar().setSelectedNavigationItem(0); } finally { closeSilently(is); } } @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); if (requestCode == FILE_SELECT_CODE && resultCode == RESULT_OK) { Uri uri = data.getData(); if (uri != null) { String name = uri.getLastPathSegment(); name = displayRomName(name); mRecentPrefs.edit().putString(name, uri.toString()).apply(); romAdapter.remove(name); romAdapter.insert(name, 2); getActionBar().setSelectedNavigationItem(2); } } } private String displayRomName(String rom) { if (rom.endsWith(".nes")) { return rom.substring(0, rom.length() - 4); } return rom; } static void closeSilently(Closeable aCloseable) { if (aCloseable != null) { try { aCloseable.close(); } catch (IOException ignored) { } } } }