From ef6242d2f7349e3383a9ee743bf21caa7f71a757 Mon Sep 17 00:00:00 2001 From: Ender's Games Date: Mon, 20 Aug 2018 16:50:21 -0400 Subject: [PATCH] Android: Create a per-game configuration view Android: Pass game configuration options to emu TODO: Fix inability to reload fragment w/ new settings Android: Limit preference scope, Avoid static crutch Android: Obligatory button to commit PGC settings Android pressures the use of async preferences, but does not properly block threads. This causes the settings from one view to bleed into the next when swapping back and forth. This can be overcome by explicitely writing to the specific pref object. Android: Add PGC documentation to window --- core/nullDC.cpp | 2 + .../java/com/reicast/emulator/Emulator.java | 20 ++ .../com/reicast/emulator/MainActivity.java | 30 ++- .../emulator/config/GameConfigFragment.java | 178 ------------- .../emulator/config/OptionsFragment.java | 105 +++----- .../emulator/config/PGConfigFragment.java | 235 ++++++++++++++++++ .../com/reicast/emulator/emu/GL2JNIView.java | 6 +- .../res/layout-v14/configure_fragment.xml | 2 +- ...fig_fragment.xml => pgconfig_fragment.xml} | 66 +++++ .../main/res/layout/configure_fragment.xml | 2 +- ...fig_fragment.xml => pgconfig_fragment.xml} | 66 +++++ .../src/main/res/menu-v23/activity_main.xml | 4 + .../src/main/res/menu/activity_main.xml | 3 + .../src/main/res/values/donottranslate.xml | 4 + .../reicast/src/main/res/values/strings.xml | 8 +- 15 files changed, 467 insertions(+), 264 deletions(-) delete mode 100644 shell/android-studio/reicast/src/main/java/com/reicast/emulator/config/GameConfigFragment.java create mode 100644 shell/android-studio/reicast/src/main/java/com/reicast/emulator/config/PGConfigFragment.java rename shell/android-studio/reicast/src/main/res/layout-v14/{game_config_fragment.xml => pgconfig_fragment.xml} (77%) rename shell/android-studio/reicast/src/main/res/layout/{game_config_fragment.xml => pgconfig_fragment.xml} (77%) diff --git a/core/nullDC.cpp b/core/nullDC.cpp index 24c610236..03c66bb76 100755 --- a/core/nullDC.cpp +++ b/core/nullDC.cpp @@ -208,7 +208,9 @@ int dc_init(int argc,wchar* argv[]) sh4_cpu.Reset(false); +#ifndef _ANDROID LoadCustom(); +#endif return rv; } diff --git a/shell/android-studio/reicast/src/main/java/com/reicast/emulator/Emulator.java b/shell/android-studio/reicast/src/main/java/com/reicast/emulator/Emulator.java index a37b7beaa..e9f1b54be 100644 --- a/shell/android-studio/reicast/src/main/java/com/reicast/emulator/Emulator.java +++ b/shell/android-studio/reicast/src/main/java/com/reicast/emulator/Emulator.java @@ -1,5 +1,6 @@ package com.reicast.emulator; +import android.app.Activity; import android.app.Application; import android.content.Context; import android.content.SharedPreferences; @@ -101,6 +102,25 @@ public class Emulator extends Application { JNIdc.dreamtime(DreamTime.getDreamtime()); } + public void getGameConfiguration(String gameId) { + SharedPreferences mPrefs = getSharedPreferences(gameId, Activity.MODE_PRIVATE); + Emulator.unstableopt = mPrefs.getBoolean(pref_unstable, unstableopt); + Emulator.dynsafemode = mPrefs.getBoolean(pref_dynsafemode, dynsafemode); + Emulator.frameskip = mPrefs.getInt(pref_frameskip, frameskip); + Emulator.pvrrender = mPrefs.getBoolean(pref_pvrrender, pvrrender); + Emulator.syncedrender = mPrefs.getBoolean(pref_syncedrender, syncedrender); + Emulator.modvols = mPrefs.getBoolean(pref_modvols, modvols); + } + + public void loadGameConfiguration() { + JNIdc.unstable(Emulator.unstableopt ? 1 : 0); + JNIdc.safemode(Emulator.dynsafemode ? 1 : 0); + JNIdc.frameskip(Emulator.frameskip); + JNIdc.pvrrender(Emulator.pvrrender ? 1 : 0); + JNIdc.syncedrender(Emulator.syncedrender ? 1 : 0); + JNIdc.modvols(Emulator.modvols ? 1 : 0); + } + static { AppCompatDelegate.setCompatVectorFromResourcesEnabled(true); } diff --git a/shell/android-studio/reicast/src/main/java/com/reicast/emulator/MainActivity.java b/shell/android-studio/reicast/src/main/java/com/reicast/emulator/MainActivity.java index 659d28b4c..5206a9211 100644 --- a/shell/android-studio/reicast/src/main/java/com/reicast/emulator/MainActivity.java +++ b/shell/android-studio/reicast/src/main/java/com/reicast/emulator/MainActivity.java @@ -18,8 +18,6 @@ import android.support.design.widget.NavigationView; import android.support.design.widget.Snackbar; import android.support.v4.app.ActivityCompat; import android.support.v4.app.Fragment; -import android.support.v4.app.FragmentManager; -import android.support.v4.app.FragmentTransaction; import android.support.v4.view.GravityCompat; import android.support.v4.widget.DrawerLayout; import android.support.v7.app.AppCompatActivity; @@ -35,6 +33,7 @@ import android.view.WindowManager; import android.widget.TextView; import com.reicast.emulator.config.Config; +import com.reicast.emulator.config.PGConfigFragment; import com.reicast.emulator.config.InputFragment; import com.reicast.emulator.config.OptionsFragment; import com.reicast.emulator.debug.GenerateLogs; @@ -364,15 +363,6 @@ public class MainActivity extends AppCompatActivity implements onMainBrowseSelected(true, null, false, null); } - public void onSettingsReload(Fragment options) { - getSupportFragmentManager().beginTransaction().remove(options).commit(); - OptionsFragment optionsFrag = new OptionsFragment(); - getSupportFragmentManager() - .beginTransaction() - .replace(R.id.fragment_container, optionsFrag, "OPTIONS_FRAG") - .addToBackStack(null).commit(); - } - @Override protected void onPause() { super.onPause(); @@ -449,6 +439,24 @@ public class MainActivity extends AppCompatActivity implements drawer.closeDrawer(GravityCompat.START); return true; + case R.id.pgconfig_menu: + PGConfigFragment pgconfigFrag = (PGConfigFragment) getSupportFragmentManager() + .findFragmentByTag("PGCONFIG_FRAG"); + if (pgconfigFrag != null) { + if (pgconfigFrag.isVisible()) { + drawer.closeDrawer(GravityCompat.START); + return true; + } + } + pgconfigFrag = new PGConfigFragment(); + getSupportFragmentManager() + .beginTransaction() + .replace(R.id.fragment_container, pgconfigFrag, "PGCONFIG_FRAG") + .addToBackStack(null).commit(); + setTitle(R.string.pgconfig); + drawer.closeDrawer(GravityCompat.START); + return true; + case R.id.input_menu: InputFragment inputFrag = (InputFragment) getSupportFragmentManager() .findFragmentByTag("INPUT_FRAG"); diff --git a/shell/android-studio/reicast/src/main/java/com/reicast/emulator/config/GameConfigFragment.java b/shell/android-studio/reicast/src/main/java/com/reicast/emulator/config/GameConfigFragment.java deleted file mode 100644 index 3f7dc2cde..000000000 --- a/shell/android-studio/reicast/src/main/java/com/reicast/emulator/config/GameConfigFragment.java +++ /dev/null @@ -1,178 +0,0 @@ -package com.reicast.emulator.config; - -import android.app.Activity; -import android.content.Context; -import android.content.SharedPreferences; -import android.os.Bundle; -import android.preference.PreferenceManager; -import android.support.v4.app.Fragment; -import android.text.Editable; -import android.text.TextWatcher; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; -import android.widget.CompoundButton; -import android.widget.CompoundButton.OnCheckedChangeListener; -import android.widget.EditText; -import android.widget.SeekBar; -import android.widget.SeekBar.OnSeekBarChangeListener; - -import com.reicast.emulator.Emulator; -import com.reicast.emulator.R; - -public class GameConfigFragment extends Fragment { - - private SharedPreferences mPrefs; - - // Container Activity must implement this interface - public interface OnClickListener { - void onMainBrowseSelected(boolean browse, String path_entry, boolean games, String query); - void onSettingsReload(Fragment options); - } - - @Override - public void onAttach(Activity activity) { - super.onAttach(activity); - } - - @Override - public void onAttach(Context context) { - super.onAttach(context); - } - - @Override - public View onCreateView(LayoutInflater inflater, ViewGroup container, - Bundle savedInstanceState) { - // Inflate the layout for this fragment - return inflater.inflate(R.layout.game_config_fragment, container, false); - } - - @Override - public void onViewCreated(View view, Bundle savedInstanceState) { - - mPrefs = PreferenceManager.getDefaultSharedPreferences(getActivity()); - - Emulator app = (Emulator) getActivity().getApplicationContext(); - app.getConfigurationPrefs(mPrefs); - - // Generate the menu options and fill in existing settings - - OnCheckedChangeListener dynarec_options = new OnCheckedChangeListener() { - - public void onCheckedChanged(CompoundButton buttonView, - boolean isChecked) { - mPrefs.edit().putBoolean(Emulator.pref_dynarecopt, isChecked).apply(); - Emulator.dynarecopt = isChecked; - } - }; - CompoundButton dynarec_opt = (CompoundButton) getView().findViewById( - R.id.dynarec_option); - dynarec_opt.setChecked(Emulator.dynarecopt); - dynarec_opt.setOnCheckedChangeListener(dynarec_options); - - OnCheckedChangeListener unstable_option = new OnCheckedChangeListener() { - - public void onCheckedChanged(CompoundButton buttonView, - boolean isChecked) { - mPrefs.edit().putBoolean(Emulator.pref_unstable, isChecked).apply(); - Emulator.unstableopt = isChecked; - } - }; - CompoundButton unstable_opt = (CompoundButton) getView().findViewById( - R.id.unstable_option); - if (Emulator.unstableopt) { - unstable_opt.setChecked(true); - } else { - unstable_opt.setChecked(false); - } - unstable_opt.setOnCheckedChangeListener(unstable_option); - - OnCheckedChangeListener safemode_option = new OnCheckedChangeListener() { - - public void onCheckedChanged(CompoundButton buttonView, - boolean isChecked) { - mPrefs.edit().putBoolean(Emulator.pref_dynsafemode, isChecked).apply(); - Emulator.dynsafemode = isChecked; - } - }; - CompoundButton safemode_opt = (CompoundButton) getView().findViewById( - R.id.dynarec_safemode); - if (Emulator.dynsafemode) { - safemode_opt.setChecked(true); - } else { - safemode_opt.setChecked(false); - } - safemode_opt.setOnCheckedChangeListener(safemode_option); - - final EditText mainFrames = (EditText) getView().findViewById(R.id.current_frames); - mainFrames.setText(String.valueOf(Emulator.frameskip)); - - final SeekBar frameSeek = (SeekBar) getView().findViewById(R.id.frame_seekbar); - frameSeek.setProgress(Emulator.frameskip); - frameSeek.setIndeterminate(false); - frameSeek.setOnSeekBarChangeListener(new OnSeekBarChangeListener() { - public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { - mainFrames.setText(String.valueOf(progress)); - } - - public void onStartTrackingTouch(SeekBar seekBar) { - // TODO Auto-generated method stub - } - - public void onStopTrackingTouch(SeekBar seekBar) { - int progress = seekBar.getProgress(); - mPrefs.edit().putInt(Emulator.pref_frameskip, progress).apply(); - Emulator.frameskip = progress; - } - }); - mainFrames.addTextChangedListener(new TextWatcher() { - public void afterTextChanged(Editable s) { - Editable frameText = mainFrames.getText(); - if (frameText != null) { - int frames = Integer.parseInt(frameText.toString()); - frameSeek.setProgress(frames); - mPrefs.edit().putInt(Emulator.pref_frameskip, frames).apply(); - Emulator.frameskip = frames; - } - } - - public void beforeTextChanged(CharSequence s, int start, int count, int after) { - } - - public void onTextChanged(CharSequence s, int start, int before, int count) { - } - }); - - OnCheckedChangeListener pvr_rendering = new OnCheckedChangeListener() { - - public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { - mPrefs.edit().putBoolean(Emulator.pref_pvrrender, isChecked).apply(); - Emulator.pvrrender = isChecked; - } - }; - CompoundButton pvr_render = (CompoundButton) getView().findViewById(R.id.render_option); - pvr_render.setChecked(Emulator.pvrrender); - pvr_render.setOnCheckedChangeListener(pvr_rendering); - - OnCheckedChangeListener synchronous = new OnCheckedChangeListener() { - public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { - mPrefs.edit().putBoolean(Emulator.pref_syncedrender, isChecked).apply(); - Emulator.syncedrender = isChecked; - } - }; - CompoundButton synced_render = (CompoundButton) getView().findViewById(R.id.syncrender_option); - synced_render.setChecked(Emulator.syncedrender); - synced_render.setOnCheckedChangeListener(synchronous); - - OnCheckedChangeListener mod_volumes = new OnCheckedChangeListener() { - - public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { - mPrefs.edit().putBoolean(Emulator.pref_modvols, isChecked).apply(); - Emulator.modvols = isChecked; - } - }; - CompoundButton modifier_volumes = (CompoundButton) getView().findViewById(R.id.modvols_option); - modifier_volumes.setChecked(Emulator.modvols); - modifier_volumes.setOnCheckedChangeListener(mod_volumes); - } -} diff --git a/shell/android-studio/reicast/src/main/java/com/reicast/emulator/config/OptionsFragment.java b/shell/android-studio/reicast/src/main/java/com/reicast/emulator/config/OptionsFragment.java index e2a5b9b71..2a4c4bec8 100644 --- a/shell/android-studio/reicast/src/main/java/com/reicast/emulator/config/OptionsFragment.java +++ b/shell/android-studio/reicast/src/main/java/com/reicast/emulator/config/OptionsFragment.java @@ -71,7 +71,6 @@ public class OptionsFragment extends Fragment { // Container Activity must implement this interface public interface OnClickListener { void onMainBrowseSelected(boolean browse, String path_entry, boolean games, String query); - void onSettingsReload(Fragment options); } @Override @@ -175,8 +174,7 @@ public class OptionsFragment extends Fragment { mPrefs.edit().putBoolean(Emulator.pref_usereios, isChecked).apply(); } }; - CompoundButton reios_opt = (CompoundButton) getView().findViewById( - R.id.reios_option); + CompoundButton reios_opt = (CompoundButton) getView().findViewById(R.id.reios_option); reios_opt.setChecked(mPrefs.getBoolean(Emulator.pref_usereios, false)); reios_opt.setOnCheckedChangeListener(reios_options); @@ -195,15 +193,13 @@ public class OptionsFragment extends Fragment { } } }; - CompoundButton details_opt = (CompoundButton) getView().findViewById( - R.id.details_option); + CompoundButton details_opt = (CompoundButton) getView().findViewById(R.id.details_option); details_opt.setChecked(mPrefs.getBoolean(Config.pref_gamedetails, false)); details_opt.setOnCheckedChangeListener(details_options); Button gameBrowse = (Button) getView().findViewById(R.id.browse_game_path); - final EditText editGames = (EditText) getView().findViewById( - R.id.game_path); + final EditText editGames = (EditText) getView().findViewById(R.id.game_path); game_directory = mPrefs.getString(Config.pref_games, game_directory); editGames.setText(game_directory); @@ -235,19 +231,16 @@ public class OptionsFragment extends Fragment { String[] bios = getResources().getStringArray(R.array.bios); codes = getResources().getStringArray(R.array.bioscode); - Spinner bios_spnr = (Spinner) getView().findViewById( - R.id.bios_spinner); + Spinner bios_spnr = (Spinner) getView().findViewById(R.id.bios_spinner); ArrayAdapter biosAdapter = new ArrayAdapter( getActivity(), android.R.layout.simple_spinner_item, bios); - biosAdapter - .setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); + biosAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); bios_spnr.setAdapter(biosAdapter); String region = mPrefs.getString("localized", codes[4]); bios_spnr.setSelection(biosAdapter.getPosition(region), true); bios_spnr.setOnItemSelectedListener(new OnItemSelectedListener() { - public void onItemSelected(AdapterView parent, View view, - int pos, long id) { + public void onItemSelected(AdapterView parent, View view, int pos, long id) { flashBios(codes[pos]); } @@ -262,12 +255,10 @@ public class OptionsFragment extends Fragment { public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { mPrefs.edit().putBoolean(Emulator.pref_nativeact, isChecked).apply(); - Emulator.nativeact = isChecked; } }; - CompoundButton native_opt = (CompoundButton) getView().findViewById( - R.id.native_option); - native_opt.setChecked(Emulator.nativeact); + CompoundButton native_opt = (CompoundButton) getView().findViewById(R.id.native_option); + native_opt.setChecked(mPrefs.getBoolean(Emulator.pref_nativeact, Emulator.nativeact)); native_opt.setOnCheckedChangeListener(native_options); OnCheckedChangeListener dynarec_options = new OnCheckedChangeListener() { @@ -275,11 +266,9 @@ public class OptionsFragment extends Fragment { public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { mPrefs.edit().putBoolean(Emulator.pref_dynarecopt, isChecked).apply(); - Emulator.dynarecopt = isChecked; } }; - CompoundButton dynarec_opt = (CompoundButton) getView().findViewById( - R.id.dynarec_option); + CompoundButton dynarec_opt = (CompoundButton) getView().findViewById(R.id.dynarec_option); dynarec_opt.setChecked(Emulator.dynarecopt); dynarec_opt.setOnCheckedChangeListener(dynarec_options); @@ -288,16 +277,10 @@ public class OptionsFragment extends Fragment { public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { mPrefs.edit().putBoolean(Emulator.pref_unstable, isChecked).apply(); - Emulator.unstableopt = isChecked; } }; - CompoundButton unstable_opt = (CompoundButton) getView().findViewById( - R.id.unstable_option); - if (Emulator.unstableopt) { - unstable_opt.setChecked(true); - } else { - unstable_opt.setChecked(false); - } + CompoundButton unstable_opt = (CompoundButton) getView().findViewById(R.id.unstable_option); + unstable_opt.setChecked(mPrefs.getBoolean(Emulator.pref_unstable, Emulator.unstableopt)); unstable_opt.setOnCheckedChangeListener(unstable_option); OnCheckedChangeListener safemode_option = new OnCheckedChangeListener() { @@ -305,36 +288,27 @@ public class OptionsFragment extends Fragment { public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { mPrefs.edit().putBoolean(Emulator.pref_dynsafemode, isChecked).apply(); - Emulator.dynsafemode = isChecked; } }; - CompoundButton safemode_opt = (CompoundButton) getView().findViewById( - R.id.dynarec_safemode); - if (Emulator.dynsafemode) { - safemode_opt.setChecked(true); - } else { - safemode_opt.setChecked(false); - } + CompoundButton safemode_opt = (CompoundButton) getView().findViewById(R.id.dynarec_safemode); + safemode_opt.setChecked(mPrefs.getBoolean(Emulator.pref_dynsafemode, Emulator.dynsafemode)); safemode_opt.setOnCheckedChangeListener(safemode_option); - String[] cables = getResources().getStringArray( - R.array.cable); - Spinner cable_spnr = (Spinner) getView().findViewById( - R.id.cable_spinner); + String[] cables = getResources().getStringArray(R.array.cable); + Spinner cable_spnr = (Spinner) getView().findViewById(R.id.cable_spinner); ArrayAdapter cableAdapter = new ArrayAdapter( getActivity(), R.layout.spinner_selected, cables); - cableAdapter - .setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); + cableAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); cable_spnr.setAdapter(cableAdapter); - cable_spnr.setSelection(Emulator.cable - 1, true); + cable_spnr.setSelection(mPrefs.getInt( + Emulator.pref_cable, Emulator.cable) - 1, true); cable_spnr.setOnItemSelectedListener(new OnItemSelectedListener() { public void onItemSelected(AdapterView parent, View view, int pos, long id) { mPrefs.edit().putInt(Emulator.pref_cable, pos + 1).apply(); - Emulator.cable = pos + 1; } public void onNothingSelected(AdapterView arg0) { @@ -351,11 +325,10 @@ public class OptionsFragment extends Fragment { getActivity(), R.layout.spinner_selected, regions); regionAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); region_spnr.setAdapter(regionAdapter); - region_spnr.setSelection(Emulator.dcregion, true); + region_spnr.setSelection(mPrefs.getInt(Emulator.pref_dcregion, Emulator.dcregion), true); region_spnr.setOnItemSelectedListener(new OnItemSelectedListener() { public void onItemSelected(AdapterView parent, View view, int pos, long id) { mPrefs.edit().putInt(Emulator.pref_dcregion, pos).apply(); - Emulator.dcregion = pos; } @@ -372,7 +345,7 @@ public class OptionsFragment extends Fragment { broadcast_spnr.setAdapter(broadcastAdapter); int select = 0; - String cast = String.valueOf(Emulator.broadcast); + String cast = String.valueOf(mPrefs.getInt(Emulator.pref_broadcast, Emulator.broadcast)); for (int i = 0; i < broadcasts.length; i++) { if (broadcasts[i].startsWith(cast + " - ")) select = i; @@ -385,7 +358,6 @@ public class OptionsFragment extends Fragment { String item = parent.getItemAtPosition(pos).toString(); String selection = item.substring(0, item.indexOf(" - ")); mPrefs.edit().putInt(Emulator.pref_broadcast, Integer.parseInt(selection)).apply(); - Emulator.broadcast = Integer.parseInt(selection); } @@ -398,40 +370,39 @@ public class OptionsFragment extends Fragment { public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { mPrefs.edit().putBoolean(Emulator.pref_limitfps, isChecked).apply(); - Emulator.limitfps = isChecked; } }; CompoundButton limit_fps = (CompoundButton) getView().findViewById(R.id.limitfps_option); - limit_fps.setChecked(Emulator.limitfps); + limit_fps.setChecked(mPrefs.getBoolean(Emulator.pref_limitfps, Emulator.limitfps)); limit_fps.setOnCheckedChangeListener(limitfps_option); OnCheckedChangeListener mipmaps_option = new OnCheckedChangeListener() { public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { mPrefs.edit().putBoolean(Emulator.pref_mipmaps, isChecked).apply(); - Emulator.mipmaps = isChecked; } }; CompoundButton mipmap_opt = (CompoundButton) getView().findViewById(R.id.mipmaps_option); - mipmap_opt.setChecked(Emulator.mipmaps); + mipmap_opt.setChecked(mPrefs.getBoolean(Emulator.pref_mipmaps, Emulator.mipmaps)); mipmap_opt.setOnCheckedChangeListener(mipmaps_option); OnCheckedChangeListener full_screen = new OnCheckedChangeListener() { public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { mPrefs.edit().putBoolean(Emulator.pref_widescreen, isChecked).apply(); - Emulator.widescreen = isChecked; } }; CompoundButton stretch_view = (CompoundButton) getView().findViewById(R.id.stretch_option); - stretch_view.setChecked(Emulator.widescreen); + stretch_view.setChecked(mPrefs.getBoolean(Emulator.pref_widescreen, Emulator.widescreen)); stretch_view.setOnCheckedChangeListener(full_screen); + int frameskip = mPrefs.getInt(Emulator.pref_frameskip, Emulator.frameskip); + final EditText mainFrames = (EditText) getView().findViewById(R.id.current_frames); - mainFrames.setText(String.valueOf(Emulator.frameskip)); + mainFrames.setText(String.valueOf(frameskip)); final SeekBar frameSeek = (SeekBar) getView().findViewById(R.id.frame_seekbar); - frameSeek.setProgress(Emulator.frameskip); + frameSeek.setProgress(frameskip); frameSeek.setIndeterminate(false); frameSeek.setOnSeekBarChangeListener(new OnSeekBarChangeListener() { public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { @@ -445,7 +416,6 @@ public class OptionsFragment extends Fragment { public void onStopTrackingTouch(SeekBar seekBar) { int progress = seekBar.getProgress(); mPrefs.edit().putInt(Emulator.pref_frameskip, progress).apply(); - Emulator.frameskip = progress; } }); mainFrames.addTextChangedListener(new TextWatcher() { @@ -455,7 +425,6 @@ public class OptionsFragment extends Fragment { int frames = Integer.parseInt(frameText.toString()); frameSeek.setProgress(frames); mPrefs.edit().putInt(Emulator.pref_frameskip, frames).apply(); - Emulator.frameskip = frames; } } @@ -470,32 +439,29 @@ public class OptionsFragment extends Fragment { public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { mPrefs.edit().putBoolean(Emulator.pref_pvrrender, isChecked).apply(); - Emulator.pvrrender = isChecked; } }; CompoundButton pvr_render = (CompoundButton) getView().findViewById(R.id.render_option); - pvr_render.setChecked(Emulator.pvrrender); + pvr_render.setChecked(mPrefs.getBoolean(Emulator.pref_pvrrender, Emulator.pvrrender)); pvr_render.setOnCheckedChangeListener(pvr_rendering); OnCheckedChangeListener synchronous = new OnCheckedChangeListener() { public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { mPrefs.edit().putBoolean(Emulator.pref_syncedrender, isChecked).apply(); - Emulator.syncedrender = isChecked; } }; CompoundButton synced_render = (CompoundButton) getView().findViewById(R.id.syncrender_option); - synced_render.setChecked(Emulator.syncedrender); + synced_render.setChecked(mPrefs.getBoolean(Emulator.pref_syncedrender, Emulator.syncedrender)); synced_render.setOnCheckedChangeListener(synchronous); OnCheckedChangeListener mod_volumes = new OnCheckedChangeListener() { public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { mPrefs.edit().putBoolean(Emulator.pref_modvols, isChecked).apply(); - Emulator.modvols = isChecked; } }; CompoundButton modifier_volumes = (CompoundButton) getView().findViewById(R.id.modvols_option); - modifier_volumes.setChecked(Emulator.modvols); + modifier_volumes.setChecked(mPrefs.getBoolean(Emulator.pref_modvols, Emulator.modvols)); modifier_volumes.setOnCheckedChangeListener(mod_volumes); // final EditText bootdiskEdit = (EditText) getView().findViewById(R.id.boot_disk); @@ -559,7 +525,6 @@ public class OptionsFragment extends Fragment { public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { mPrefs.edit().putBoolean(Emulator.pref_nosound, isChecked).apply(); - Emulator.nosound = isChecked; } }; boolean sound = mPrefs.getBoolean(Emulator.pref_nosound, false); @@ -589,7 +554,7 @@ public class OptionsFragment extends Fragment { } }); - Button resetEmu = (Button) getView().findViewById(R.id.reset_emu_settings); + Button resetEmu = (Button) getView().findViewById(R.id.reset_emu_btn); resetEmu.setOnClickListener(new View.OnClickListener() { public void onClick(View view) { AlertDialog.Builder b = new AlertDialog.Builder(getActivity()); @@ -623,12 +588,10 @@ public class OptionsFragment extends Fragment { for (final String type : mediaTypes) { filter[i] = new FilenameFilter() { public boolean accept(File dir, String name) { - if (dir.getName().startsWith(".") - || name.startsWith(".")) { + if (dir.getName().startsWith(".") || name.startsWith(".")) { return false; } else { - return StringUtils.endsWithIgnoreCase(name, "." - + type); + return StringUtils.endsWithIgnoreCase(name, "." + type); } } }; @@ -753,7 +716,7 @@ public class OptionsFragment extends Fragment { mPrefs.edit().remove(Config.pref_renderdepth).apply(); mPrefs.edit().remove(Config.pref_theme).apply(); - mCallback.onSettingsReload(this); + getActivity().finish(); } private void showToastMessage(String message, int duration) { diff --git a/shell/android-studio/reicast/src/main/java/com/reicast/emulator/config/PGConfigFragment.java b/shell/android-studio/reicast/src/main/java/com/reicast/emulator/config/PGConfigFragment.java new file mode 100644 index 000000000..88458c6d3 --- /dev/null +++ b/shell/android-studio/reicast/src/main/java/com/reicast/emulator/config/PGConfigFragment.java @@ -0,0 +1,235 @@ +package com.reicast.emulator.config; + +import android.app.Activity; +import android.app.AlertDialog; +import android.content.Context; +import android.content.DialogInterface; +import android.content.SharedPreferences; +import android.os.AsyncTask; +import android.os.Bundle; +import android.preference.PreferenceManager; +import android.support.v4.app.Fragment; +import android.text.Editable; +import android.text.TextWatcher; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.AdapterView; +import android.widget.ArrayAdapter; +import android.widget.Button; +import android.widget.CompoundButton; +import android.widget.CompoundButton.OnCheckedChangeListener; +import android.widget.EditText; +import android.widget.SeekBar; +import android.widget.SeekBar.OnSeekBarChangeListener; +import android.widget.Spinner; + +import com.android.util.FileUtils; +import com.reicast.emulator.Emulator; +import com.reicast.emulator.R; + +import org.apache.commons.lang3.StringUtils; + +import java.io.BufferedReader; +import java.io.File; +import java.io.FileNotFoundException; +import java.io.FilenameFilter; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.lang.ref.WeakReference; +import java.util.Collection; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public class PGConfigFragment extends Fragment { + + private Emulator app; + private Spinner mSpnrConfigs; + + private CompoundButton unstable_opt; + private CompoundButton safemode_opt; + private EditText mainFrames; + private SeekBar frameSeek; + private CompoundButton pvr_render; + private CompoundButton synced_render; + private CompoundButton modifier_volumes; + + @Override + public void onAttach(Activity activity) { + super.onAttach(activity); + } + + @Override + public void onAttach(Context context) { + super.onAttach(context); + } + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, + Bundle savedInstanceState) { + // Inflate the layout for this fragment + return inflater.inflate(R.layout.pgconfig_fragment, container, false); + } + + @Override + public void onViewCreated(View view, Bundle savedInstanceState) { + + app = (Emulator) getActivity().getApplicationContext(); + app.getConfigurationPrefs(PreferenceManager.getDefaultSharedPreferences(getActivity())); + + mSpnrConfigs = (Spinner) getView().findViewById(R.id.config_spinner); + new LocateConfigs(PGConfigFragment.this).execute( + getActivity().getFilesDir().getAbsolutePath()); + + unstable_opt = (CompoundButton) getView().findViewById(R.id.unstable_option); + safemode_opt = (CompoundButton) getView().findViewById(R.id.dynarec_safemode); + mainFrames = (EditText) getView().findViewById(R.id.current_frames); + frameSeek = (SeekBar) getView().findViewById(R.id.frame_seekbar); + pvr_render = (CompoundButton) getView().findViewById(R.id.render_option); + synced_render = (CompoundButton) getView().findViewById(R.id.syncrender_option); + modifier_volumes = (CompoundButton) getView().findViewById(R.id.modvols_option); + } + + private void saveSettings(SharedPreferences mPrefs) { + mPrefs.edit().putBoolean(Emulator.pref_unstable, unstable_opt.isChecked()) + .putBoolean(Emulator.pref_dynsafemode, safemode_opt.isChecked()) + .putInt(Emulator.pref_frameskip, frameSeek.getProgress()) + .putBoolean(Emulator.pref_pvrrender, pvr_render.isChecked()) + .putBoolean(Emulator.pref_syncedrender, synced_render.isChecked()) + .putBoolean(Emulator.pref_modvols, modifier_volumes.isChecked()).apply(); + } + + private void configureViewByGame(String gameId) { + final SharedPreferences mPrefs = getActivity() + .getSharedPreferences(gameId, Activity.MODE_PRIVATE); + unstable_opt.setChecked(mPrefs.getBoolean(Emulator.pref_unstable, Emulator.unstableopt)); + safemode_opt.setChecked(mPrefs.getBoolean(Emulator.pref_dynsafemode, Emulator.dynsafemode)); + + int frameskip = mPrefs.getInt(Emulator.pref_frameskip, Emulator.frameskip); + mainFrames.setText(String.valueOf(frameskip)); + + frameSeek.setProgress(frameskip); + frameSeek.setIndeterminate(false); + frameSeek.setOnSeekBarChangeListener(new OnSeekBarChangeListener() { + public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { + mainFrames.setText(String.valueOf(progress)); + } + + public void onStartTrackingTouch(SeekBar seekBar) { + // TODO Auto-generated method stub + } + + public void onStopTrackingTouch(SeekBar seekBar) { + + } + }); + mainFrames.addTextChangedListener(new TextWatcher() { + public void afterTextChanged(Editable s) { + Editable frameText = mainFrames.getText(); + if (frameText != null) { + int frames = Integer.parseInt(frameText.toString()); + frameSeek.setProgress(frames); + } + } + + public void beforeTextChanged(CharSequence s, int start, int count, int after) { + } + + public void onTextChanged(CharSequence s, int start, int before, int count) { + } + }); + + pvr_render.setChecked(mPrefs.getBoolean(Emulator.pref_pvrrender, Emulator.pvrrender)); + synced_render.setChecked(mPrefs.getBoolean(Emulator.pref_syncedrender, Emulator.syncedrender)); + modifier_volumes.setChecked(mPrefs.getBoolean(Emulator.pref_modvols, Emulator.modvols)); + + Button savePGC = (Button) getView().findViewById(R.id.save_pg_btn); + savePGC.setOnClickListener(new View.OnClickListener() { + public void onClick(View view) { + saveSettings(mPrefs); + } + }); + } + + private static class LocateConfigs extends AsyncTask> { + private WeakReference options; + + LocateConfigs(PGConfigFragment context) { + options = new WeakReference<>(context); + } + + @Override + protected List doInBackground(String... paths) { + File storage = new File(paths[0]); + String[] mediaTypes = options.get().getResources().getStringArray(R.array.configs); + FilenameFilter[] filter = new FilenameFilter[mediaTypes.length]; + int i = 0; + for (final String type : mediaTypes) { + filter[i] = new FilenameFilter() { + public boolean accept(File dir, String name) { + if (dir.getName().startsWith(".") || name.startsWith(".")) { + return false; + } else { + return StringUtils.endsWithIgnoreCase(name, "." + type); + } + } + }; + i++; + } + FileUtils fileUtils = new FileUtils(); + Collection files = fileUtils.listFiles(storage, filter, 0); + return (List) files; + } + + @Override + protected void onPostExecute(List items) { + if (items != null && !items.isEmpty()) { + final Map gameMap = new HashMap<>(); + String[] titles = new String[items.size()]; + for (int i = 0; i < items.size(); i ++) { + String filename = items.get(i).getName(); + try { + InputStream iS = options.get().getActivity().openFileInput(filename); + + if (iS != null) { + InputStreamReader iSR = new InputStreamReader(iS); + BufferedReader bR = new BufferedReader(iSR); + String readString = ""; + StringBuilder stringBuilder = new StringBuilder(); + + while ( (readString = bR.readLine()) != null ) { + stringBuilder.append(readString); + } + + iS.close(); + titles[i] = stringBuilder.toString(); + gameMap.put(titles[i], filename.substring(0, filename.length() - 4)); + } + } catch (IOException e) { + // TODO: Appropriate error message + } + } + ArrayAdapter configAdapter = new ArrayAdapter( + options.get().getActivity(), android.R.layout.simple_spinner_item, titles); + configAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); + options.get().mSpnrConfigs.setAdapter(configAdapter); + options.get().mSpnrConfigs.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() { + @Override + public void onItemSelected(AdapterView parent, View select, int pos, long id) { + options.get().configureViewByGame(gameMap.get( + String.valueOf(parent.getItemAtPosition(pos)) + )); + } + @Override + public void onNothingSelected(AdapterView parentView) { + + } + }); + } else { + options.get().mSpnrConfigs.setEnabled(false); + } + } + } +} diff --git a/shell/android-studio/reicast/src/main/java/com/reicast/emulator/emu/GL2JNIView.java b/shell/android-studio/reicast/src/main/java/com/reicast/emulator/emu/GL2JNIView.java index 2cd1b0de6..3c6c3cadf 100644 --- a/shell/android-studio/reicast/src/main/java/com/reicast/emulator/emu/GL2JNIView.java +++ b/shell/android-studio/reicast/src/main/java/com/reicast/emulator/emu/GL2JNIView.java @@ -675,15 +675,19 @@ public class GL2JNIView extends GLSurfaceView } void reiosInfo(String reiosId, String reiosSoftware) { + String gameId = reiosId.replaceAll("[^a-zA-Z0-9]+", "").toLowerCase(); try { OutputStreamWriter outputStreamWriter = new OutputStreamWriter( - context.openFileOutput(reiosId+".cfg", Context.MODE_PRIVATE)); + context.openFileOutput(gameId + ".pgc", Context.MODE_PRIVATE)); outputStreamWriter.write(reiosSoftware); outputStreamWriter.close(); } catch (IOException e) { Log.e("Exception", "File write failed: " + e.toString()); } + Emulator app = (Emulator) context.getApplicationContext(); + app.getGameConfiguration(gameId); + app.loadGameConfiguration(); } } diff --git a/shell/android-studio/reicast/src/main/res/layout-v14/configure_fragment.xml b/shell/android-studio/reicast/src/main/res/layout-v14/configure_fragment.xml index 3ddbcdee5..44395d05d 100644 --- a/shell/android-studio/reicast/src/main/res/layout-v14/configure_fragment.xml +++ b/shell/android-studio/reicast/src/main/res/layout-v14/configure_fragment.xml @@ -825,7 +825,7 @@ android:orientation="vertical" >