From 00996c8d388cf0164416df3d24775863fd272dbe Mon Sep 17 00:00:00 2001 From: Lioncash Date: Tue, 20 Aug 2013 19:39:00 -0400 Subject: [Android] Implement a ViewPager for the settings. Also, move classes into appropriate packages to make things cleaner. --- .../org/dolphinemu/dolphinemu/AboutFragment.java | 6 +- .../org/dolphinemu/dolphinemu/DolphinEmulator.java | 4 + .../org/dolphinemu/dolphinemu/FolderBrowser.java | 141 ----------- .../dolphinemu/FolderBrowserAdapter.java | 87 ------- .../dolphinemu/dolphinemu/FolderBrowserItem.java | 123 --------- .../dolphinemu/dolphinemu/GameListActivity.java | 265 -------------------- .../org/dolphinemu/dolphinemu/GameListAdapter.java | 66 ----- .../dolphinemu/dolphinemu/GameListFragment.java | 153 ------------ .../org/dolphinemu/dolphinemu/GameListItem.java | 92 ------- .../dolphinemu/dolphinemu/InputConfigAdapter.java | 61 ----- .../dolphinemu/dolphinemu/InputConfigFragment.java | 218 ---------------- .../org/dolphinemu/dolphinemu/InputConfigItem.java | 99 -------- .../org/dolphinemu/dolphinemu/PrefsFragment.java | 226 ----------------- .../org/dolphinemu/dolphinemu/SideMenuAdapter.java | 53 ---- .../org/dolphinemu/dolphinemu/SideMenuItem.java | 58 ----- .../org/dolphinemu/dolphinemu/UserPreferences.java | 221 ----------------- .../dolphinemu/folderbrowser/FolderBrowser.java | 145 +++++++++++ .../folderbrowser/FolderBrowserAdapter.java | 89 +++++++ .../folderbrowser/FolderBrowserItem.java | 123 +++++++++ .../dolphinemu/gamelist/GameListActivity.java | 275 +++++++++++++++++++++ .../dolphinemu/gamelist/GameListAdapter.java | 68 +++++ .../dolphinemu/gamelist/GameListFragment.java | 156 ++++++++++++ .../dolphinemu/gamelist/GameListItem.java | 94 +++++++ .../dolphinemu/inputconfig/InputConfigAdapter.java | 63 +++++ .../inputconfig/InputConfigFragment.java | 221 +++++++++++++++++ .../dolphinemu/inputconfig/InputConfigItem.java | 101 ++++++++ .../dolphinemu/settings/CPUSettingsFragment.java | 81 ++++++ .../dolphinemu/settings/PrefsActivity.java | 146 +++++++++++ .../dolphinemu/settings/UserPreferences.java | 229 +++++++++++++++++ .../dolphinemu/settings/VideoSettingsFragment.java | 202 +++++++++++++++ .../dolphinemu/sidemenu/SideMenuAdapter.java | 55 +++++ .../dolphinemu/sidemenu/SideMenuItem.java | 58 +++++ 32 files changed, 2115 insertions(+), 1864 deletions(-) delete mode 100644 Source/Android/src/org/dolphinemu/dolphinemu/FolderBrowser.java delete mode 100644 Source/Android/src/org/dolphinemu/dolphinemu/FolderBrowserAdapter.java delete mode 100644 Source/Android/src/org/dolphinemu/dolphinemu/FolderBrowserItem.java delete mode 100644 Source/Android/src/org/dolphinemu/dolphinemu/GameListActivity.java delete mode 100644 Source/Android/src/org/dolphinemu/dolphinemu/GameListAdapter.java delete mode 100644 Source/Android/src/org/dolphinemu/dolphinemu/GameListFragment.java delete mode 100644 Source/Android/src/org/dolphinemu/dolphinemu/GameListItem.java delete mode 100644 Source/Android/src/org/dolphinemu/dolphinemu/InputConfigAdapter.java delete mode 100644 Source/Android/src/org/dolphinemu/dolphinemu/InputConfigFragment.java delete mode 100644 Source/Android/src/org/dolphinemu/dolphinemu/InputConfigItem.java delete mode 100644 Source/Android/src/org/dolphinemu/dolphinemu/PrefsFragment.java delete mode 100644 Source/Android/src/org/dolphinemu/dolphinemu/SideMenuAdapter.java delete mode 100644 Source/Android/src/org/dolphinemu/dolphinemu/SideMenuItem.java delete mode 100644 Source/Android/src/org/dolphinemu/dolphinemu/UserPreferences.java create mode 100644 Source/Android/src/org/dolphinemu/dolphinemu/folderbrowser/FolderBrowser.java create mode 100644 Source/Android/src/org/dolphinemu/dolphinemu/folderbrowser/FolderBrowserAdapter.java create mode 100644 Source/Android/src/org/dolphinemu/dolphinemu/folderbrowser/FolderBrowserItem.java create mode 100644 Source/Android/src/org/dolphinemu/dolphinemu/gamelist/GameListActivity.java create mode 100644 Source/Android/src/org/dolphinemu/dolphinemu/gamelist/GameListAdapter.java create mode 100644 Source/Android/src/org/dolphinemu/dolphinemu/gamelist/GameListFragment.java create mode 100644 Source/Android/src/org/dolphinemu/dolphinemu/gamelist/GameListItem.java create mode 100644 Source/Android/src/org/dolphinemu/dolphinemu/inputconfig/InputConfigAdapter.java create mode 100644 Source/Android/src/org/dolphinemu/dolphinemu/inputconfig/InputConfigFragment.java create mode 100644 Source/Android/src/org/dolphinemu/dolphinemu/inputconfig/InputConfigItem.java create mode 100644 Source/Android/src/org/dolphinemu/dolphinemu/settings/CPUSettingsFragment.java create mode 100644 Source/Android/src/org/dolphinemu/dolphinemu/settings/PrefsActivity.java create mode 100644 Source/Android/src/org/dolphinemu/dolphinemu/settings/UserPreferences.java create mode 100644 Source/Android/src/org/dolphinemu/dolphinemu/settings/VideoSettingsFragment.java create mode 100644 Source/Android/src/org/dolphinemu/dolphinemu/sidemenu/SideMenuAdapter.java create mode 100644 Source/Android/src/org/dolphinemu/dolphinemu/sidemenu/SideMenuItem.java (limited to 'Source/Android/src') diff --git a/Source/Android/src/org/dolphinemu/dolphinemu/AboutFragment.java b/Source/Android/src/org/dolphinemu/dolphinemu/AboutFragment.java index 07e36fa459..40e78fc4bf 100644 --- a/Source/Android/src/org/dolphinemu/dolphinemu/AboutFragment.java +++ b/Source/Android/src/org/dolphinemu/dolphinemu/AboutFragment.java @@ -11,6 +11,10 @@ import android.widget.ListView; import java.util.ArrayList; import java.util.List; +import org.dolphinemu.dolphinemu.folderbrowser.FolderBrowserAdapter; +import org.dolphinemu.dolphinemu.folderbrowser.FolderBrowserItem; +import org.dolphinemu.dolphinemu.settings.VideoSettingsFragment; + /** * Copyright 2013 Dolphin Emulator Project * Licensed under GPLv2 @@ -42,7 +46,7 @@ public final class AboutFragment extends Fragment List Input = new ArrayList(); Input.add(new FolderBrowserItem(getString(R.string.build_revision), NativeLibrary.GetVersionString(), "", true)); - Input.add(new FolderBrowserItem(getString(R.string.supports_gles3), PrefsFragment.SupportsGLES3() ? yes : no, "", true)); + Input.add(new FolderBrowserItem(getString(R.string.supports_gles3), VideoSettingsFragment.SupportsGLES3() ? yes : no, "", true)); adapter = new FolderBrowserAdapter(m_activity, R.layout.about_layout, Input); mMainList.setAdapter(adapter); diff --git a/Source/Android/src/org/dolphinemu/dolphinemu/DolphinEmulator.java b/Source/Android/src/org/dolphinemu/dolphinemu/DolphinEmulator.java index f1abc215d1..3dca1f5fbe 100644 --- a/Source/Android/src/org/dolphinemu/dolphinemu/DolphinEmulator.java +++ b/Source/Android/src/org/dolphinemu/dolphinemu/DolphinEmulator.java @@ -15,6 +15,10 @@ import android.view.WindowManager; import java.io.*; import java.util.List; +import org.dolphinemu.dolphinemu.gamelist.GameListActivity; +import org.dolphinemu.dolphinemu.inputconfig.InputConfigFragment; +import org.dolphinemu.dolphinemu.settings.UserPreferences; + public final class DolphinEmulator extends Activity { static private NativeGLSurfaceView GLview = null; diff --git a/Source/Android/src/org/dolphinemu/dolphinemu/FolderBrowser.java b/Source/Android/src/org/dolphinemu/dolphinemu/FolderBrowser.java deleted file mode 100644 index bd41c75093..0000000000 --- a/Source/Android/src/org/dolphinemu/dolphinemu/FolderBrowser.java +++ /dev/null @@ -1,141 +0,0 @@ -package org.dolphinemu.dolphinemu; - -import android.app.Activity; -import android.app.Fragment; -import android.os.Bundle; -import android.os.Environment; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; -import android.widget.AdapterView; -import android.widget.ListView; -import android.widget.Toast; - -import java.io.File; -import java.util.*; - -public final class FolderBrowser extends Fragment -{ - private Activity m_activity; - private FolderBrowserAdapter adapter; - private ListView mDrawerList; - private View rootView; - private static File currentDir = null; - - // Populates the FolderView with the given currDir's contents. - private void Fill(File currDir) - { - m_activity.setTitle(getString(R.string.current_dir) + currDir.getName()); - File[] dirs = currDir.listFiles(); - Listdir = new ArrayList(); - Listfls = new ArrayList(); - - // Supported extensions to filter by - Set validExts = new HashSet(Arrays.asList(".gcm", ".iso", ".wbfs", ".gcz", ".dol", ".elf", ".dff")); - Set invalidExts = new HashSet(Arrays.asList(".zip", ".rar", ".7z")); - - // Search for any directories or supported files within the current dir. - try - { - for(File entry : dirs) - { - String entryName = entry.getName(); - - if (entryName.charAt(0) != '.') - { - if(entry.isDirectory()) - { - dir.add(new FolderBrowserItem(entryName, entry.getAbsolutePath(), true)); - } - else - { - if (validExts.contains(entryName.toLowerCase().substring(entryName.lastIndexOf('.')))) - { - fls.add(new FolderBrowserItem(entryName, getString(R.string.file_size)+entry.length(), entry.getAbsolutePath(), true)); - } - else if (invalidExts.contains(entryName.toLowerCase().substring(entryName.lastIndexOf('.')))) - { - fls.add(new FolderBrowserItem(entryName, getString(R.string.file_size)+entry.length(), entry.getAbsolutePath(), false)); - } - } - } - } - } - catch(Exception ignored) - { - } - - Collections.sort(dir); - Collections.sort(fls); - dir.addAll(fls); - - // Check for a parent directory to the one we're currently in. - if (!currDir.getPath().equalsIgnoreCase("/")) - dir.add(0, new FolderBrowserItem("..", getString(R.string.parent_directory), currDir.getParent(), true)); - - adapter = new FolderBrowserAdapter(m_activity, R.layout.folderbrowser, dir); - mDrawerList = (ListView) rootView.findViewById(R.id.gamelist); - mDrawerList.setAdapter(adapter); - mDrawerList.setOnItemClickListener(mMenuItemClickListener); - } - - @Override - public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) - { - if(currentDir == null) - currentDir = new File(Environment.getExternalStorageDirectory().getPath()); - - rootView = inflater.inflate(R.layout.gamelist_listview, container, false); - - Fill(currentDir); - return mDrawerList; - } - - private AdapterView.OnItemClickListener mMenuItemClickListener = new AdapterView.OnItemClickListener() - { - public void onItemClick(AdapterView parent, View view, int position, long id) - { - FolderBrowserItem item = adapter.getItem(position); - if(item.isDirectory()) - { - currentDir = new File(item.getPath()); - Fill(currentDir); - } - else - { - if (item.isValid()) - FolderSelected(); - else - Toast.makeText(m_activity, getString(R.string.cant_use_compressed_filetypes), Toast.LENGTH_LONG).show(); - } - } - }; - - @Override - public void onAttach(Activity activity) - { - super.onAttach(activity); - - // This makes sure that the container activity has implemented - // the callback interface. If not, it throws an exception - try - { - m_activity = activity; - } - catch (ClassCastException e) - { - throw new ClassCastException(activity.toString() - + " must implement OnGameListZeroListener"); - } - } - private void FolderSelected() - { - String Directories = NativeLibrary.GetConfig("Dolphin.ini", "General", "GCMPathes", "0"); - int intDirectories = Integer.parseInt(Directories); - Directories = Integer.toString(intDirectories + 1); - NativeLibrary.SetConfig("Dolphin.ini", "General", "GCMPathes", Directories); - NativeLibrary.SetConfig("Dolphin.ini", "General", "GCMPath" + Integer.toString(intDirectories), currentDir.getPath()); - - ((GameListActivity)m_activity).SwitchPage(0); - } -} diff --git a/Source/Android/src/org/dolphinemu/dolphinemu/FolderBrowserAdapter.java b/Source/Android/src/org/dolphinemu/dolphinemu/FolderBrowserAdapter.java deleted file mode 100644 index f7596600b7..0000000000 --- a/Source/Android/src/org/dolphinemu/dolphinemu/FolderBrowserAdapter.java +++ /dev/null @@ -1,87 +0,0 @@ -package org.dolphinemu.dolphinemu; - -import android.content.Context; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; -import android.widget.ArrayAdapter; -import android.widget.ImageView; -import android.widget.TextView; - -import java.util.List; - -public final class FolderBrowserAdapter extends ArrayAdapter -{ - private final Context c; - private final int id; - private final List items; - - public FolderBrowserAdapter(Context context, int textViewResourceId, List objects) - { - super(context, textViewResourceId, objects); - c = context; - id = textViewResourceId; - items = objects; - } - - public FolderBrowserItem getItem(int i) - { - return items.get(i); - } - - @Override - public View getView(int position, View convertView, ViewGroup parent) - { - View v = convertView; - if (v == null) - { - LayoutInflater vi = (LayoutInflater) c.getSystemService(Context.LAYOUT_INFLATER_SERVICE); - v = vi.inflate(id, parent, false); - } - - final FolderBrowserItem item = items.get(position); - if (item != null) - { - ImageView iconView = (ImageView) v.findViewById(R.id.ImageIcon); - TextView mainText = (TextView) v.findViewById(R.id.FolderTitle); - TextView subtitleText = (TextView) v.findViewById(R.id.FolderSubTitle); - - if(mainText != null) - { - mainText.setText(item.getName()); - - if (!item.isValid()) - { - mainText.setTextColor(0xFFFF0000); - } - } - - if(subtitleText != null) - { - // Remove the subtitle for all folders, except for the parent directory folder. - if (item.isDirectory() && !item.getSubtitle().equals(c.getResources().getString(R.string.parent_directory))) - { - subtitleText.setVisibility(View.GONE); - } - else - { - subtitleText.setText(item.getSubtitle()); - } - } - - if (iconView != null) - { - if (item.isDirectory()) - { - iconView.setImageResource(R.drawable.ic_menu_folder); - } - else - { - iconView.setImageResource(R.drawable.ic_menu_file); - } - } - - } - return v; - } -} diff --git a/Source/Android/src/org/dolphinemu/dolphinemu/FolderBrowserItem.java b/Source/Android/src/org/dolphinemu/dolphinemu/FolderBrowserItem.java deleted file mode 100644 index 5fd9bd5ad1..0000000000 --- a/Source/Android/src/org/dolphinemu/dolphinemu/FolderBrowserItem.java +++ /dev/null @@ -1,123 +0,0 @@ -package org.dolphinemu.dolphinemu; - -import java.io.File; - -/** - * Represents an item in the folder browser list. - */ -public final class FolderBrowserItem implements Comparable -{ - private final String name; - private final String subtitle; - private final String path; - private final boolean isValid; - private final File underlyingFile; - - /** - * Constructor - * - * @param name The name of the file/folder represented by this item. - * @param subtitle The subtitle of this FolderBrowserItem to display. - * @param path The path of the file/folder represented by this item. - * @param isValid Whether or not this item represents a file type that can be handled. - */ - public FolderBrowserItem(String name, String subtitle, String path, boolean isValid) - { - this.name = name; - this.subtitle = subtitle; - this.path = path; - this.isValid = isValid; - this.underlyingFile = new File(path); - } - - /** - * Constructor. Initializes a FolderBrowserItem with an empty subtitle. - * - * @param ctx Context this FolderBrowserItem is being used in. - * @param name The name of the file/folder represented by this item. - * @param path The path of the file/folder represented by this item. - * @param isValid Whether or not this item represents a file type that can be handled. - */ - public FolderBrowserItem(String name, String path, boolean isValid) - { - this.name = name; - this.subtitle = ""; - this.path = path; - this.isValid = isValid; - this.underlyingFile = new File(path); - } - - /** - * Gets the name of the file/folder represented by this FolderBrowserItem. - * - * @return the name of the file/folder represented by this FolderBrowserItem. - */ - public String getName() - { - return name; - } - - /** - * Gets the subtitle text of this FolderBrowserItem. - * - * @return the subtitle text of this FolderBrowserItem. - */ - public String getSubtitle() - { - return subtitle; - } - - /** - * Gets the path of the file/folder represented by this FolderBrowserItem. - * - * @return the path of the file/folder represented by this FolderBrowserItem. - */ - public String getPath() - { - return path; - } - - /** - * Gets whether or not the file represented - * by this FolderBrowserItem is supported - * and can be handled correctly. - * - * @return whether or not the file represented - * by this FolderBrowserItem is supported - * and can be handled correctly. - */ - public boolean isValid() - { - return isValid; - } - - /** - * Gets the {@link File} representation of the underlying file/folder - * represented by this FolderBrowserItem. - * - * @return the {@link File} representation of the underlying file/folder - * represented by this FolderBrowserItem. - */ - public File getUnderlyingFile() - { - return underlyingFile; - } - - /** - * Gets whether or not this FolderBrowserItem represents a directory. - * - * @return true if this FolderBrowserItem represents a directory, false otherwise. - */ - public boolean isDirectory() - { - return underlyingFile.isDirectory(); - } - - public int compareTo(FolderBrowserItem other) - { - if(this.name != null) - return this.name.toLowerCase().compareTo(other.getName().toLowerCase()); - else - throw new IllegalArgumentException(); - } -} diff --git a/Source/Android/src/org/dolphinemu/dolphinemu/GameListActivity.java b/Source/Android/src/org/dolphinemu/dolphinemu/GameListActivity.java deleted file mode 100644 index 08736b7360..0000000000 --- a/Source/Android/src/org/dolphinemu/dolphinemu/GameListActivity.java +++ /dev/null @@ -1,265 +0,0 @@ -package org.dolphinemu.dolphinemu; - -import android.app.Activity; -import android.app.Fragment; -import android.app.FragmentManager; -import android.content.res.Configuration; -import android.os.Bundle; -import android.support.v4.app.ActionBarDrawerToggle; -import android.support.v4.widget.DrawerLayout; -import android.view.*; -import android.widget.AdapterView; -import android.widget.ListView; -import java.util.ArrayList; -import java.util.List; - -/** - * Copyright 2013 Dolphin Emulator Project - * Licensed under GPLv2 - * Refer to the license.txt file included. - */ -public final class GameListActivity extends Activity - implements GameListFragment.OnGameListZeroListener -{ - private int mCurFragmentNum = 0; - private Fragment mCurFragment; - - private ActionBarDrawerToggle mDrawerToggle; - private DrawerLayout mDrawerLayout; - private SideMenuAdapter mDrawerAdapter; - private ListView mDrawerList; - - // Called from the game list fragment - public void onZeroFiles() - { - mDrawerLayout.openDrawer(mDrawerList); - } - - @Override - protected void onCreate(Bundle savedInstanceState) - { - super.onCreate(savedInstanceState); - setContentView(R.layout.gamelist_activity); - - mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout); - mDrawerList = (ListView) findViewById(R.id.left_drawer); - - List dir = new ArrayList(); - dir.add(new SideMenuItem(getString(R.string.game_list), 0)); - dir.add(new SideMenuItem(getString(R.string.browse_folder), 1)); - dir.add(new SideMenuItem(getString(R.string.settings), 2)); - dir.add(new SideMenuItem(getString(R.string.gamepad_config), 3)); - dir.add(new SideMenuItem(getString(R.string.about), 4)); - - mDrawerAdapter = new SideMenuAdapter(this, R.layout.sidemenu, dir); - mDrawerList.setAdapter(mDrawerAdapter); - mDrawerList.setOnItemClickListener(mMenuItemClickListener); - - // enable ActionBar app icon to behave as action to toggle nav drawer - getActionBar().setDisplayHomeAsUpEnabled(true); - getActionBar().setHomeButtonEnabled(true); - - // ActionBarDrawerToggle ties together the the proper interactions - // between the sliding drawer and the action bar app icon - mDrawerToggle = new ActionBarDrawerToggle( - this, /* host Activity */ - mDrawerLayout, /* DrawerLayout object */ - R.drawable.ic_drawer, /* nav drawer image to replace 'Up' caret */ - R.string.drawer_open, /* "open drawer" description for accessibility */ - R.string.drawer_close /* "close drawer" description for accessibility */ - ) { - public void onDrawerClosed(View view) { - invalidateOptionsMenu(); // creates call to onPrepareOptionsMenu() - } - - public void onDrawerOpened(View drawerView) { - invalidateOptionsMenu(); // creates call to onPrepareOptionsMenu() - } - }; - mDrawerLayout.setDrawerListener(mDrawerToggle); - - recreateFragment(); - } - - private void recreateFragment() - { - mCurFragment = new GameListFragment(); - FragmentManager fragmentManager = getFragmentManager(); - fragmentManager.beginTransaction().replace(R.id.content_frame, mCurFragment).commit(); - } - - public void SwitchPage(int toPage) - { - if (mCurFragmentNum == toPage) - return; - - switch (mCurFragmentNum) - { - // Folder browser - case 1: - recreateFragment(); - break; - - case 3: // Gamepad settings - { - InputConfigAdapter adapter = ((InputConfigFragment)mCurFragment).getAdapter(); - for (int a = 0; a < adapter.getCount(); ++a) - { - InputConfigItem o = adapter.getItem(a); - String config = o.getConfig(); - String bind = o.getBind(); - String ConfigValues[] = config.split("-"); - String Key = ConfigValues[0]; - String Value = ConfigValues[1]; - NativeLibrary.SetConfig("Dolphin.ini", Key, Value, bind); - } - } - break; - - case 0: // Game List - case 2: // Settings - case 4: // About - /* Do Nothing */ - break; - } - - switch(toPage) - { - case 0: - { - mCurFragmentNum = 0; - mCurFragment = new GameListFragment(); - FragmentManager fragmentManager = getFragmentManager(); - fragmentManager.beginTransaction().replace(R.id.content_frame, mCurFragment).commit(); - } - break; - - case 1: - { - mCurFragmentNum = 1; - mCurFragment = new FolderBrowser(); - FragmentManager fragmentManager = getFragmentManager(); - fragmentManager.beginTransaction().replace(R.id.content_frame, mCurFragment).commit(); - } - break; - - case 2: - { - mCurFragmentNum = 2; - mCurFragment = new PrefsFragment(); - FragmentManager fragmentManager = getFragmentManager(); - fragmentManager.beginTransaction().replace(R.id.content_frame, mCurFragment).commit(); - } - break; - - case 3: - { - mCurFragmentNum = 3; - mCurFragment = new InputConfigFragment(); - FragmentManager fragmentManager = getFragmentManager(); - fragmentManager.beginTransaction().replace(R.id.content_frame, mCurFragment).commit(); - } - break; - - case 4: - { - mCurFragmentNum = 4; - mCurFragment = new AboutFragment(); - FragmentManager fragmentManager = getFragmentManager(); - fragmentManager.beginTransaction().replace(R.id.content_frame, mCurFragment).commit(); - } - break; - - default: - break; - } - } - - private AdapterView.OnItemClickListener mMenuItemClickListener = new AdapterView.OnItemClickListener() - { - public void onItemClick(AdapterView parent, View view, int position, long id) - { - SideMenuItem o = mDrawerAdapter.getItem(position); - mDrawerLayout.closeDrawer(mDrawerList); - SwitchPage(o.getID()); - } - }; - /** - * When using the ActionBarDrawerToggle, you must call it during - * onPostCreate() and onConfigurationChanged()... - */ - - @Override - protected void onPostCreate(Bundle savedInstanceState) - { - super.onPostCreate(savedInstanceState); - // Sync the toggle state after onRestoreInstanceState has occurred. - mDrawerToggle.syncState(); - } - - @Override - public void onConfigurationChanged(Configuration newConfig) - { - super.onConfigurationChanged(newConfig); - // Pass any configuration change to the drawer toggle - mDrawerToggle.onConfigurationChanged(newConfig); - } - - /* Called whenever we call invalidateOptionsMenu() */ - @Override - public boolean onPrepareOptionsMenu(Menu menu) - { - return super.onPrepareOptionsMenu(menu); - } - - @Override - public boolean onOptionsItemSelected(MenuItem item) - { - // The action bar home/up action should open or close the drawer. - // ActionBarDrawerToggle will take care of this. - if (mDrawerToggle.onOptionsItemSelected(item)) - { - return true; - } - - return super.onOptionsItemSelected(item); - } - - public void onBackPressed() - { - SwitchPage(0); - } - - public interface OnGameConfigListener - { - public boolean onMotionEvent(MotionEvent event); - public boolean onKeyEvent(KeyEvent event); - } - - // Gets move(triggers, joystick) events - @Override - public boolean dispatchGenericMotionEvent(MotionEvent event) - { - if (mCurFragmentNum == 3) - { - if (((OnGameConfigListener)mCurFragment).onMotionEvent(event)) - return true; - } - - return super.dispatchGenericMotionEvent(event); - } - - // Gets button presses - @Override - public boolean dispatchKeyEvent(KeyEvent event) - { - if (mCurFragmentNum == 3) - { - if (((OnGameConfigListener)mCurFragment).onKeyEvent(event)) - return true; - } - - return super.dispatchKeyEvent(event); - } - -} diff --git a/Source/Android/src/org/dolphinemu/dolphinemu/GameListAdapter.java b/Source/Android/src/org/dolphinemu/dolphinemu/GameListAdapter.java deleted file mode 100644 index d683741c79..0000000000 --- a/Source/Android/src/org/dolphinemu/dolphinemu/GameListAdapter.java +++ /dev/null @@ -1,66 +0,0 @@ -package org.dolphinemu.dolphinemu; - -import android.content.Context; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; -import android.widget.ArrayAdapter; -import android.widget.ImageView; -import android.widget.TextView; - -import java.util.List; - -public final class GameListAdapter extends ArrayAdapter -{ - private final Context c; - private final int id; - private final Listitems; - - public GameListAdapter(Context context, int textViewResourceId, List objects) - { - super(context, textViewResourceId, objects); - c = context; - id = textViewResourceId; - items = objects; - } - - public GameListItem getItem(int i) - { - return items.get(i); - } - - @Override - public View getView(int position, View convertView, ViewGroup parent) - { - View v = convertView; - if (v == null) - { - LayoutInflater vi = (LayoutInflater)c.getSystemService(Context.LAYOUT_INFLATER_SERVICE); - v = vi.inflate(id, parent, false); - } - - final GameListItem item = items.get(position); - if (item != null) - { - TextView title = (TextView) v.findViewById(R.id.GameItemTitle); - TextView subtitle = (TextView) v.findViewById(R.id.GameItemSubText); - ImageView icon = (ImageView) v.findViewById(R.id.GameItemIcon); - - if(title != null) - title.setText(item.getName()); - - if(subtitle != null) - subtitle.setText(item.getData()); - - if(icon != null) - { - icon.setImageBitmap(item.getImage()); - icon.getLayoutParams().width = (int) ((860 / c.getResources().getDisplayMetrics().density) + 0.5); - icon.getLayoutParams().height = (int)((340 / c.getResources().getDisplayMetrics().density) + 0.5); - } - } - - return v; - } -} - diff --git a/Source/Android/src/org/dolphinemu/dolphinemu/GameListFragment.java b/Source/Android/src/org/dolphinemu/dolphinemu/GameListFragment.java deleted file mode 100644 index 8464eaea9c..0000000000 --- a/Source/Android/src/org/dolphinemu/dolphinemu/GameListFragment.java +++ /dev/null @@ -1,153 +0,0 @@ -package org.dolphinemu.dolphinemu; - -import android.app.Activity; -import android.app.Fragment; -import android.content.Intent; -import android.os.Bundle; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; -import android.widget.AdapterView; -import android.widget.ListView; -import android.widget.Toast; - -import java.io.File; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.HashSet; -import java.util.List; -import java.util.Set; - -/** - * Copyright 2013 Dolphin Emulator Project - * Licensed under GPLv2 - * Refer to the license.txt file included. - */ -public final class GameListFragment extends Fragment -{ - private ListView mMainList; - private GameListAdapter mGameAdapter; - private static GameListActivity mMe; - OnGameListZeroListener mCallback; - - public interface OnGameListZeroListener - { - public void onZeroFiles(); - } - - public GameListFragment() - { - // Empty constructor required for fragment subclasses - } - - private void Fill() - { - List fls = new ArrayList(); - String Directories = NativeLibrary.GetConfig("Dolphin.ini", "General", "GCMPathes", "0"); - int intDirectories = Integer.parseInt(Directories); - - // Extensions to filter by. - Set exts = new HashSet(Arrays.asList(".gcm", ".iso", ".wbfs", ".gcz", ".dol", ".elf", ".dff")); - - for (int a = 0; a < intDirectories; ++a) - { - String BrowseDir = NativeLibrary.GetConfig("Dolphin.ini", "General", "GCMPath" + a, ""); - File currentDir = new File(BrowseDir); - File[] dirs = currentDir.listFiles(); - try - { - for(File entry : dirs) - { - String entryName = entry.getName(); - - if (entryName.charAt(0) != '.') - { - if(!entry.isDirectory()) - { - if (exts.contains(entryName.toLowerCase().substring(entryName.lastIndexOf('.')))) - fls.add(new GameListItem(mMe.getApplicationContext(), entryName, getString(R.string.file_size)+entry.length(),entry.getAbsolutePath(), true)); - } - } - } - } - catch(Exception ignored) - { - } - } - Collections.sort(fls); - - // Remove any duplicate items from the list. - // We don't need to index these in the game list more than once. - // - // This works by comparing the paths of items in the file list for equality, - // so there should be no worries about accidentally removing a valid game. - for (int i = 0; i < fls.size(); i++) - { - int indexNext = i+1; - - if (indexNext < fls.size() && fls.get(indexNext).getPath().contains(fls.get(i).getPath())) - { - fls.remove(indexNext); - } - } - - mGameAdapter = new GameListAdapter(mMe, R.layout.gamelist_layout, fls); - mMainList.setAdapter(mGameAdapter); - if (fls.size() == 0) - mCallback.onZeroFiles(); - } - - @Override - public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) - { - View rootView = inflater.inflate(R.layout.gamelist_listview, container, false); - mMainList = (ListView) rootView.findViewById(R.id.gamelist); - mMainList.setOnItemClickListener(mGameItemClickListener); - - Fill(); - - return mMainList; - } - - private AdapterView.OnItemClickListener mGameItemClickListener = new AdapterView.OnItemClickListener() - { - public void onItemClick(AdapterView parent, View view, int position, long id) - { - GameListItem o = mGameAdapter.getItem(position); - if(!(o.getData().equalsIgnoreCase(getString(R.string.folder))||o.getData().equalsIgnoreCase(getString(R.string.parent_directory)))) - { - onFileClick(o.getPath()); - } - } - }; - - private void onFileClick(String o) - { - Toast.makeText(mMe, getString(R.string.file_clicked) + o, Toast.LENGTH_SHORT).show(); - - Intent intent = new Intent(); - intent.putExtra("Select", o); - mMe.setResult(Activity.RESULT_OK, intent); - mMe.finish(); - } - - @Override - public void onAttach(Activity activity) - { - super.onAttach(activity); - - // This makes sure that the container activity has implemented - // the callback interface. If not, it throws an exception - try - { - mCallback = (OnGameListZeroListener) activity; - mMe = (GameListActivity) activity; - } - catch (ClassCastException e) - { - throw new ClassCastException(activity.toString() - + " must implement OnGameListZeroListener"); - } - } -} \ No newline at end of file diff --git a/Source/Android/src/org/dolphinemu/dolphinemu/GameListItem.java b/Source/Android/src/org/dolphinemu/dolphinemu/GameListItem.java deleted file mode 100644 index 10f44f69e4..0000000000 --- a/Source/Android/src/org/dolphinemu/dolphinemu/GameListItem.java +++ /dev/null @@ -1,92 +0,0 @@ -package org.dolphinemu.dolphinemu; - -import android.content.Context; -import android.graphics.Bitmap; -import android.graphics.BitmapFactory; - -import java.io.File; -import java.io.IOException; -import java.io.InputStream; - -public final class GameListItem implements Comparable -{ - private String name; - private final String data; - private final String path; - private final boolean isValid; - private Bitmap image; - - public GameListItem(Context ctx, String name, String data, String path, boolean isValid) - { - this.name = name; - this.data = data; - this.path = path; - this.isValid = isValid; - - File file = new File(path); - if (!file.isDirectory() && !path.equals("")) - { - int[] Banner = NativeLibrary.GetBanner(path); - if (Banner[0] == 0) - { - try - { - // Open the no banner icon. - InputStream noBannerPath = ctx.getAssets().open("NoBanner.png"); - - // Decode the bitmap. - image = BitmapFactory.decodeStream(noBannerPath); - - // Scale the bitmap to match other banners. - image = Bitmap.createScaledBitmap(image, 96, 32, false); - } - catch (IOException e) - { - // TODO Auto-generated catch block - e.printStackTrace(); - } - - } - else - { - image = Bitmap.createBitmap(Banner, 96, 32, Bitmap.Config.ARGB_8888); - } - - this.name = NativeLibrary.GetTitle(path); - } - } - - public String getName() - { - return name; - } - - public String getData() - { - return data; - } - - public String getPath() - { - return path; - } - - public Bitmap getImage() - { - return image; - } - - public boolean isValid() - { - return isValid; - } - - public int compareTo(GameListItem o) - { - if(this.name != null) - return this.name.toLowerCase().compareTo(o.getName().toLowerCase()); - else - throw new IllegalArgumentException(); - } -} - diff --git a/Source/Android/src/org/dolphinemu/dolphinemu/InputConfigAdapter.java b/Source/Android/src/org/dolphinemu/dolphinemu/InputConfigAdapter.java deleted file mode 100644 index 12541b8b37..0000000000 --- a/Source/Android/src/org/dolphinemu/dolphinemu/InputConfigAdapter.java +++ /dev/null @@ -1,61 +0,0 @@ -package org.dolphinemu.dolphinemu; - -import android.content.Context; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; -import android.widget.ArrayAdapter; -import android.widget.TextView; - -import java.util.List; - -/** - * Copyright 2013 Dolphin Emulator Project - * Licensed under GPLv2 - * Refer to the license.txt file included. - */ -public final class InputConfigAdapter extends ArrayAdapter -{ - private final Context c; - private final int id; - private final List items; - - public InputConfigAdapter(Context context, int textViewResourceId, List objects) - { - super(context, textViewResourceId, objects); - c = context; - id = textViewResourceId; - items = objects; - } - - public InputConfigItem getItem(int i) - { - return items.get(i); - } - - @Override - public View getView(int position, View convertView, ViewGroup parent) - { - View v = convertView; - if (v == null) - { - LayoutInflater vi = (LayoutInflater)c.getSystemService(Context.LAYOUT_INFLATER_SERVICE); - v = vi.inflate(id, parent, false); - } - - final InputConfigItem item = items.get(position); - if (item != null) - { - TextView title = (TextView) v.findViewById(R.id.FolderTitle); - TextView subtitle = (TextView) v.findViewById(R.id.FolderSubTitle); - - if(title != null) - title.setText(item.getName()); - - if(subtitle != null) - subtitle.setText(item.getBind()); - } - - return v; - } -} diff --git a/Source/Android/src/org/dolphinemu/dolphinemu/InputConfigFragment.java b/Source/Android/src/org/dolphinemu/dolphinemu/InputConfigFragment.java deleted file mode 100644 index 530f8b1d3b..0000000000 --- a/Source/Android/src/org/dolphinemu/dolphinemu/InputConfigFragment.java +++ /dev/null @@ -1,218 +0,0 @@ -package org.dolphinemu.dolphinemu; - -import android.app.Activity; -import android.app.Fragment; -import android.os.Build; -import android.os.Bundle; -import android.util.Log; -import android.view.*; -import android.widget.AdapterView; -import android.widget.ListView; -import android.widget.Toast; - -import java.util.ArrayList; -import java.util.List; - -/** - * Copyright 2013 Dolphin Emulator Project - * Licensed under GPLv2 - * Refer to the license.txt file included. - */ -public final class InputConfigFragment extends Fragment - implements GameListActivity.OnGameConfigListener -{ - private Activity m_activity; - private ListView mDrawerList; - private InputConfigAdapter adapter; - private int configPosition = 0; - boolean Configuring = false; - boolean firstEvent = true; - - static public String getInputDesc(InputDevice input) - { - if (input == null) - return "null"; // Happens when the inputdevice is from an unknown source - - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) - { - return input.getDescriptor(); - } - else - { - List motions = input.getMotionRanges(); - String fakeid = ""; - - for (InputDevice.MotionRange range : motions) - fakeid += range.getAxis(); - - return fakeid; - } - } - @Override - public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) - { - List Input = new ArrayList(); - Input.add(new InputConfigItem(getString(R.string.draw_onscreen_controls), "Android-ScreenControls", "True")); - Input.add(new InputConfigItem(getString(R.string.button_a), "Android-InputA")); - Input.add(new InputConfigItem(getString(R.string.button_b), "Android-InputB")); - Input.add(new InputConfigItem(getString(R.string.button_start), "Android-InputStart")); - Input.add(new InputConfigItem(getString(R.string.button_x), "Android-InputX")); - Input.add(new InputConfigItem(getString(R.string.button_y), "Android-InputY")); - Input.add(new InputConfigItem(getString(R.string.button_z), "Android-InputZ")); - Input.add(new InputConfigItem(getString(R.string.dpad_up), "Android-DPadUp")); - Input.add(new InputConfigItem(getString(R.string.dpad_down), "Android-DPadDown")); - Input.add(new InputConfigItem(getString(R.string.dpad_left), "Android-DPadLeft")); - Input.add(new InputConfigItem(getString(R.string.dpad_right), "Android-DPadRight")); - Input.add(new InputConfigItem(getString(R.string.main_stick_up), "Android-MainUp")); - Input.add(new InputConfigItem(getString(R.string.main_stick_down), "Android-MainDown")); - Input.add(new InputConfigItem(getString(R.string.main_stick_left), "Android-MainLeft")); - Input.add(new InputConfigItem(getString(R.string.main_stick_right), "Android-MainRight")); - Input.add(new InputConfigItem(getString(R.string.c_stick_up), "Android-CStickUp")); - Input.add(new InputConfigItem(getString(R.string.c_stick_down), "Android-CStickDown")); - Input.add(new InputConfigItem(getString(R.string.c_stick_left), "Android-CStickLeft")); - Input.add(new InputConfigItem(getString(R.string.c_stick_right), "Android-CStickRight")); - Input.add(new InputConfigItem(getString(R.string.trigger_left), "Android-InputL")); - Input.add(new InputConfigItem(getString(R.string.trigger_right), "Android-InputR")); - - adapter = new InputConfigAdapter(m_activity, R.layout.folderbrowser, Input); - View rootView = inflater.inflate(R.layout.gamelist_listview, container, false); - mDrawerList = (ListView) rootView.findViewById(R.id.gamelist); - - mDrawerList.setAdapter(adapter); - mDrawerList.setOnItemClickListener(mMenuItemClickListener); - return mDrawerList; - } - - private AdapterView.OnItemClickListener mMenuItemClickListener = new AdapterView.OnItemClickListener() - { - public void onItemClick(AdapterView parent, View view, int position, long id) - { - InputConfigItem o = adapter.getItem(position); - switch(position) - { - case 0: // On screen controls - String newBind; - if (o.getBind().equals("True")) - { - Toast.makeText(m_activity, getString(R.string.not_drawing_onscreen_controls), Toast.LENGTH_SHORT).show(); - newBind = "False"; - } - else - { - Toast.makeText(m_activity, getString(R.string.drawing_onscreen_controls), Toast.LENGTH_SHORT).show(); - newBind = "True"; - } - adapter.remove(o); - o.setBind(newBind); - adapter.insert(o, position); - break; - - default: // gamepad controls - - Toast.makeText(m_activity, getString(R.string.press_button_to_config, o.getName()), Toast.LENGTH_SHORT).show(); - configPosition = position; - Configuring = true; - firstEvent = true; - break; - } - } - }; - - private static ArrayList m_values = new ArrayList(); - - private void AssignBind(String bind) - { - InputConfigItem o = adapter.getItem(configPosition); - adapter.remove(o); - o.setBind(bind); - adapter.insert(o, configPosition); - } - - public InputConfigAdapter getAdapter() - { - return adapter; - } - - // Called from GameListActivity - public boolean onMotionEvent(MotionEvent event) - { - if (((event.getSource() & InputDevice.SOURCE_CLASS_JOYSTICK) == 0)) - return false; - - InputDevice input = event.getDevice(); - List motions = input.getMotionRanges(); - if (Configuring) - { - if (firstEvent) - { - m_values.clear(); - - for (InputDevice.MotionRange range : motions) - { - m_values.add(event.getAxisValue(range.getAxis())); - } - - firstEvent = false; - } - else - { - for (int a = 0; a < motions.size(); ++a) - { - InputDevice.MotionRange range = motions.get(a); - - if (m_values.get(a) > (event.getAxisValue(range.getAxis()) + 0.5f)) - { - AssignBind("Device '" + InputConfigFragment.getInputDesc(input) + "'-Axis " + range.getAxis() + "-"); - Configuring = false; - } - else if (m_values.get(a) < (event.getAxisValue(range.getAxis()) - 0.5f)) - { - AssignBind("Device '" + InputConfigFragment.getInputDesc(input) + "'-Axis " + range.getAxis() + "+"); - Configuring = false; - } - } - } - } - return true; - } - - public boolean onKeyEvent(KeyEvent event) - { - Log.w("InputConfigFragment", "Got Event " + event.getAction()); - switch (event.getAction()) - { - case KeyEvent.ACTION_DOWN: - case KeyEvent.ACTION_UP: - if (Configuring) - { - InputDevice input = event.getDevice(); - AssignBind("Device '" + InputConfigFragment.getInputDesc(input) + "'-Button " + event.getKeyCode()); - Configuring = false; - return true; - } - - default: - break; - } - - return false; - } - - @Override - public void onAttach(Activity activity) - { - super.onAttach(activity); - - // This makes sure that the container activity has implemented - // the callback interface. If not, it throws an exception - try - { - m_activity = activity; - } - catch (ClassCastException e) - { - throw new ClassCastException(activity.toString() - + " must implement OnGameListZeroListener"); - } - } -} diff --git a/Source/Android/src/org/dolphinemu/dolphinemu/InputConfigItem.java b/Source/Android/src/org/dolphinemu/dolphinemu/InputConfigItem.java deleted file mode 100644 index 70e68261ec..0000000000 --- a/Source/Android/src/org/dolphinemu/dolphinemu/InputConfigItem.java +++ /dev/null @@ -1,99 +0,0 @@ -/* - * Copyright 2013 Dolphin Emulator Project - * Licensed under GPLv2 - * Refer to the license.txt file included. - */ - -package org.dolphinemu.dolphinemu; - -/** - * Represents a controller input item (button, stick, etc). - */ -public final class InputConfigItem implements Comparable -{ - private String m_name; - private String m_Config; - private String m_bind; - - private void Init(String name, String config, String defaultBind) - { - m_name = name; - m_Config = config; - String ConfigValues[] = m_Config.split("-"); - String Key = ConfigValues[0]; - String Value = ConfigValues[1]; - m_bind = NativeLibrary.GetConfig("Dolphin.ini", Key, Value, defaultBind); - } - - /** - * Constructor - * - * @param name Name of the input config item. - * @param config Name of the key in the configuration file that this control modifies. - * @param defaultBind Default binding to fall back upon if binding fails. - */ - public InputConfigItem(String name, String config, String defaultBind) - { - Init(name, config, defaultBind); - } - - /** - * Constructor that creates an InputConfigItem - * that has a default binding of "None" - * - * @param name Name of the input config item. - * @param config Name of the key in the configuration file that this control modifies. - */ - public InputConfigItem(String name, String config) - { - Init(name, config, "None"); - } - - /** - * Gets the name of this InputConfigItem. - * - * @return the name of this InputConfigItem - */ - public String getName() - { - return m_name; - } - - /** - * Gets the config key this InputConfigItem modifies. - * - * @return the config key this InputConfigItem modifies. - */ - public String getConfig() - { - return m_Config; - } - - /** - * Gets the currently set binding of this InputConfigItem - * - * @return the currently set binding of this InputConfigItem - */ - public String getBind() - { - return m_bind; - } - - /** - * Sets a new binding for this InputConfigItem. - * - * @param bind The new binding. - */ - public void setBind(String bind) - { - m_bind = bind; - } - - public int compareTo(InputConfigItem o) - { - if(this.m_name != null) - return this.m_name.toLowerCase().compareTo(o.getName().toLowerCase()); - else - throw new IllegalArgumentException(); - } -} diff --git a/Source/Android/src/org/dolphinemu/dolphinemu/PrefsFragment.java b/Source/Android/src/org/dolphinemu/dolphinemu/PrefsFragment.java deleted file mode 100644 index f6196c7236..0000000000 --- a/Source/Android/src/org/dolphinemu/dolphinemu/PrefsFragment.java +++ /dev/null @@ -1,226 +0,0 @@ -package org.dolphinemu.dolphinemu; - -import android.app.Activity; -import android.os.Build; -import android.os.Bundle; -import android.preference.ListPreference; -import android.preference.PreferenceFragment; -import javax.microedition.khronos.egl.*; -import javax.microedition.khronos.opengles.GL10; - -// -// TODO: It would be nice to situate the preferences in a ViewPager. -// In such a way that the video settings are divided into sections like -// [General | Enhancements | Hacks] -// -// However I do not know how to correctly get ViewPagers to work with PreferenceFragments -// (at the time of writing), so if anyone else can implement this (AND document it nicely) -// that would be awesome -// -// - Lioncash -// - -/** - * Copyright 2013 Dolphin Emulator Project - * Licensed under GPLv2 - * Refer to the license.txt file included. - */ -public final class PrefsFragment extends PreferenceFragment -{ - private Activity m_activity; - - static public class VersionCheck - { - EGL10 mEGL; - EGLDisplay mEGLDisplay; - EGLConfig[] mEGLConfigs; - EGLConfig mEGLConfig; - EGLContext mEGLContext; - EGLSurface mEGLSurface; - GL10 mGL; - - String mThreadOwner; - - public VersionCheck() - { - int[] version = new int[2]; - int[] attribList = new int[] { - EGL10.EGL_WIDTH, 1, - EGL10.EGL_HEIGHT, 1, - EGL10.EGL_RENDERABLE_TYPE, 4, - EGL10.EGL_NONE - }; - int EGL_CONTEXT_CLIENT_VERSION = 0x3098; - int[] ctx_attribs = new int[] { - EGL_CONTEXT_CLIENT_VERSION, 2, - EGL10.EGL_NONE - }; - - // No error checking performed, minimum required code to elucidate logic - mEGL = (EGL10) EGLContext.getEGL(); - mEGLDisplay = mEGL.eglGetDisplay(EGL10.EGL_DEFAULT_DISPLAY); - mEGL.eglInitialize(mEGLDisplay, version); - mEGLConfig = chooseConfig(); // Choosing a config is a little more complicated - mEGLContext = mEGL.eglCreateContext(mEGLDisplay, mEGLConfig, EGL10.EGL_NO_CONTEXT, ctx_attribs); - mEGLSurface = mEGL.eglCreatePbufferSurface(mEGLDisplay, mEGLConfig, attribList); - mEGL.eglMakeCurrent(mEGLDisplay, mEGLSurface, mEGLSurface, mEGLContext); - mGL = (GL10) mEGLContext.getGL(); - - // Record thread owner of OpenGL context - mThreadOwner = Thread.currentThread().getName(); - } - - public String getVersion() - { - return mGL.glGetString(GL10.GL_VERSION); - } - - public String getVendor() - { - return mGL.glGetString(GL10.GL_VENDOR); - } - - public String getRenderer() - { - return mGL.glGetString(GL10.GL_RENDERER); - } - - private EGLConfig chooseConfig() - { - int[] attribList = new int[] { - EGL10.EGL_DEPTH_SIZE, 0, - EGL10.EGL_STENCIL_SIZE, 0, - EGL10.EGL_RED_SIZE, 8, - EGL10.EGL_GREEN_SIZE, 8, - EGL10.EGL_BLUE_SIZE, 8, - EGL10.EGL_ALPHA_SIZE, 8, - EGL10.EGL_NONE - }; - - // No error checking performed, minimum required code to elucidate logic - // Expand on this logic to be more selective in choosing a configuration - int[] numConfig = new int[1]; - mEGL.eglChooseConfig(mEGLDisplay, attribList, null, 0, numConfig); - int configSize = numConfig[0]; - mEGLConfigs = new EGLConfig[configSize]; - mEGL.eglChooseConfig(mEGLDisplay, attribList, mEGLConfigs, configSize, numConfig); - - return mEGLConfigs[0]; // Best match is probably the first configuration - } - } - - static public boolean SupportsGLES3() - { - VersionCheck mbuffer = new VersionCheck(); - String m_GLVersion = mbuffer.getVersion(); - String m_GLVendor = mbuffer.getVendor(); - String m_GLRenderer = mbuffer.getRenderer(); - - boolean mSupportsGLES3 = false; - - // Check for OpenGL ES 3 support (General case). - if (m_GLVersion != null && (m_GLVersion.contains("OpenGL ES 3.0") || m_GLVersion.equals("OpenGL ES 3.0"))) - mSupportsGLES3 = true; - - // Checking for OpenGL ES 3 support for certain Qualcomm devices. - if (!mSupportsGLES3 && m_GLVendor != null && m_GLVendor.equals("Qualcomm")) - { - if (m_GLRenderer.contains("Adreno (TM) 3")) - { - int mVStart = m_GLVersion.indexOf("V@") + 2; - int mVEnd = 0; - float mVersion; - - for (int a = mVStart; a < m_GLVersion.length(); ++a) - { - if (m_GLVersion.charAt(a) == ' ') - { - mVEnd = a; - break; - } - } - - mVersion = Float.parseFloat(m_GLVersion.substring(mVStart, mVEnd)); - - if (mVersion >= 14.0f) - mSupportsGLES3 = true; - } - } - return mSupportsGLES3; - } - - @Override - public void onCreate(Bundle savedInstanceState) - { - super.onCreate(savedInstanceState); - - // Load the preferences from an XML resource - addPreferencesFromResource(R.xml.prefs); - - final ListPreference cpuCores = (ListPreference) findPreference("cpuCorePref"); - - // - // Set valid emulation cores depending on the CPU architecture - // that the Android device is running on. - // - if (Build.CPU_ABI.contains("x86")) - { - cpuCores.setEntries(R.array.emuCoreEntriesX86); - cpuCores.setEntryValues(R.array.emuCoreValuesX86); - } - else if (Build.CPU_ABI.contains("arm")) - { - cpuCores.setEntries(R.array.emuCoreEntriesARM); - cpuCores.setEntryValues(R.array.emuCoreValuesARM); - } - else - { - cpuCores.setEntries(R.array.emuCoreEntriesOther); - cpuCores.setEntryValues(R.array.emuCoreValuesOther); - } - - // - // Setting valid video backends. - // - final ListPreference videoBackends = (ListPreference) findPreference("gpuPref"); - final boolean deviceSupportsGLES3 = SupportsGLES3(); - - if (deviceSupportsGLES3) - { - videoBackends.setEntries(R.array.videoBackendEntriesGLES3); - videoBackends.setEntryValues(R.array.videoBackendValuesGLES3); - } - else - { - videoBackends.setEntries(R.array.videoBackendEntriesNoGLES3); - videoBackends.setEntryValues(R.array.videoBackendValuesNoGLES3); - } - } - - @Override - public void onAttach(Activity activity) - { - super.onAttach(activity); - - // This makes sure that the container activity has implemented - // the callback interface. If not, it throws an exception - try - { - m_activity = activity; - } - catch (ClassCastException e) - { - throw new ClassCastException(activity.toString() - + " must implement OnGameListZeroListener"); - } - } - - @Override - public void onDestroy() - { - super.onDestroy(); - - // When the fragment is done being used, save the settings to the Dolphin ini file. - UserPreferences.SaveConfigToDolphinIni(m_activity); - } -} diff --git a/Source/Android/src/org/dolphinemu/dolphinemu/SideMenuAdapter.java b/Source/Android/src/org/dolphinemu/dolphinemu/SideMenuAdapter.java deleted file mode 100644 index 11c071b026..0000000000 --- a/Source/Android/src/org/dolphinemu/dolphinemu/SideMenuAdapter.java +++ /dev/null @@ -1,53 +0,0 @@ -package org.dolphinemu.dolphinemu; - -import android.content.Context; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; -import android.widget.ArrayAdapter; -import android.widget.TextView; - -import java.util.List; - -public final class SideMenuAdapter extends ArrayAdapter -{ - private final Context c; - private final int id; - private final Listitems; - - public SideMenuAdapter(Context context, int textViewResourceId, List objects) - { - super(context, textViewResourceId, objects); - c = context; - id = textViewResourceId; - items = objects; - } - - public SideMenuItem getItem(int i) - { - return items.get(i); - } - - @Override - public View getView(int position, View convertView, ViewGroup parent) - { - View v = convertView; - if (v == null) - { - LayoutInflater vi = (LayoutInflater)c.getSystemService(Context.LAYOUT_INFLATER_SERVICE); - v = vi.inflate(id, null); - } - - final SideMenuItem item = items.get(position); - if (item != null) - { - TextView title = (TextView) v.findViewById(R.id.SideMenuTitle); - - if(title != null) - title.setText(item.getName()); - } - - return v; - } -} - diff --git a/Source/Android/src/org/dolphinemu/dolphinemu/SideMenuItem.java b/Source/Android/src/org/dolphinemu/dolphinemu/SideMenuItem.java deleted file mode 100644 index 51ebc93c19..0000000000 --- a/Source/Android/src/org/dolphinemu/dolphinemu/SideMenuItem.java +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Copyright 2013 Dolphin Emulator Project - * Licensed under GPLv2 - * Refer to the license.txt file included. - */ - -package org.dolphinemu.dolphinemu; - - -/** - * Represents an item that goes in the sidemenu of the app. - */ -public final class SideMenuItem implements Comparable -{ - private final String m_name; - private final int m_id; - - /** - * Constructor - * - * @param name The name of the SideMenuItem. - * @param id ID number of this specific SideMenuItem. - */ - public SideMenuItem(String name, int id) - { - m_name = name; - m_id = id; - } - - /** - * Gets the name of this SideMenuItem. - * - * @return the name of this SideMenuItem. - */ - public String getName() - { - return m_name; - } - - /** - * Gets the ID of this SideMenuItem. - * - * @return the ID of this SideMenuItem. - */ - public int getID() - { - return m_id; - } - - public int compareTo(SideMenuItem o) - { - if(this.m_name != null) - return this.m_name.toLowerCase().compareTo(o.getName().toLowerCase()); - else - throw new IllegalArgumentException(); - } -} - diff --git a/Source/Android/src/org/dolphinemu/dolphinemu/UserPreferences.java b/Source/Android/src/org/dolphinemu/dolphinemu/UserPreferences.java deleted file mode 100644 index 80e8b9dfdc..0000000000 --- a/Source/Android/src/org/dolphinemu/dolphinemu/UserPreferences.java +++ /dev/null @@ -1,221 +0,0 @@ -package org.dolphinemu.dolphinemu; - -import android.content.Context; -import android.content.SharedPreferences; -import android.preference.PreferenceManager; - -/** - * A class that retrieves all of the set user preferences in Android, in a safe way. - *

- * If any preferences are added to this emulator, an accessor for that preference - * should be added here. This way lengthy calls to getters from SharedPreferences - * aren't made necessary. - */ -public final class UserPreferences -{ - /** - * Loads the set config items from the Dolphin config files to the shared preferences of this front-end - * - * @param ctx The context used to retrieve the SharedPreferences instance. - */ - public static void LoadDolphinConfigToPrefs(Context ctx) - { - SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(ctx); - - // Get an editor. - SharedPreferences.Editor editor = prefs.edit(); - - // Add the settings. - editor.putString("cpuCorePref", getConfig("Dolphin.ini", "Core", "CPUCore", "3")); - editor.putBoolean("dualCorePref", getConfig("Dolphin.ini", "Core", "CPUThread", "False").equals("True")); - editor.putString("gpuPref", getConfig("Dolphin.ini", "Core", "GFXBackend ", "Software Renderer")); - - editor.putString("internalResolution", getConfig("gfx_opengl.ini", "Settings", "EFBScale", "2") ); - editor.putString("anisotropicFiltering", getConfig("gfx_opengl.ini", "Enhancements", "MaxAnisotropy", "0")); - editor.putBoolean("scaledEFBCopy", getConfig("gfx_opengl.ini", "Hacks", "EFBScaleCopy", "True").equals("True")); - editor.putBoolean("perPixelLighting", getConfig("gfx_opengl.ini", "Settings", "EnablePixelLighting", "False").equals("True")); - editor.putBoolean("forceTextureFiltering", getConfig("gfx_opengl.ini", "Enhancements", "ForceFiltering", "False").equals("True")); - editor.putBoolean("disableFog", getConfig("gfx_opengl.ini", "Settings", "DisableFog", "False").equals("True")); - editor.putBoolean("skipEFBAccess", getConfig("gfx_opengl.ini", "Hacks", "EFBAccessEnable", "False").equals("True")); - editor.putBoolean("ignoreFormatChanges", getConfig("gfx_opengl.ini", "Hacks", "EFBEmulateFormatChanges", "False").equals("False")); - - String efbCopyOn = getConfig("gfx_opengl.ini", "Hacks", "EFBCopyEnable", "False"); - String efbToTexture = getConfig("gfx_opengl.ini", "Hacks", "EFBToTextureEnable", "False"); - String efbCopyCache = getConfig("gfx_opengl.ini", "Hacks", "EFBCopyCacheEnable", "False"); - - if (efbCopyOn.equals("False")) - { - editor.putString("efbCopyMethod", "Off"); - } - else if (efbCopyOn.equals("True") && efbToTexture.equals("True")) - { - editor.putString("efbCopyMethod", "Texture"); - } - else if(efbCopyOn.equals("True") && efbToTexture.equals("False") && efbCopyCache.equals("False")) - { - editor.putString("efbCopyMethod", "RAM (uncached)"); - } - else if(efbCopyOn.equals("True") && efbToTexture.equals("False") && efbCopyCache.equals("True")) - { - editor.putString("efbCopyMethod", "RAM (cached)"); - } - - editor.putString("textureCacheAccuracy", getConfig("gfx_opengl.ini", "Settings", "SafeTextureCacheColorSamples", "128")); - - String usingXFB = getConfig("gfx_opengl.ini", "Settings", "UseXFB", "False"); - String usingRealXFB = getConfig("gfx_opengl.ini", "Settings", "UseRealXFB", "False"); - - if (usingXFB.equals("False")) - { - editor.putString("externalFrameBuffer", "Disabled"); - } - else if (usingXFB.equals("True") && usingRealXFB.equals("False")) - { - editor.putString("externalFrameBuffer", "Virtual"); - } - else if (usingXFB.equals("True") && usingRealXFB.equals("True")) - { - editor.putString("externalFrameBuffer", "Real"); - } - - editor.putBoolean("cacheDisplayLists", getConfig("gfx_opengl.ini", "Hacks", "DlistCachingEnable", "False").equals("True")); - editor.putBoolean("disableDestinationAlpha", getConfig("gfx_opengl.ini", "Settings", "DstAlphaPass", "False").equals("True")); - editor.putBoolean("fastDepthCalculation", getConfig("gfx_opengl.ini", "Settings", "FastDepthCalc", "True").equals("True")); - - // Apply the changes. - editor.commit(); - } - - // Small utility method that shortens calls to NativeLibrary.GetConfig. - private static String getConfig(String ini, String section, String key, String defaultValue) - { - return NativeLibrary.GetConfig(ini, section, key, defaultValue); - } - - /** - * Writes the config to the Dolphin ini file. - * - * @param ctx The context used to retrieve the user settings. - * */ - public static void SaveConfigToDolphinIni(Context ctx) - { - SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(ctx); - - // Whether or not the user is using dual core. - boolean isUsingDualCore = prefs.getBoolean("dualCorePref", true); - - // Current CPU core being used. Falls back to interpreter upon error. - String currentEmuCore = prefs.getString("cpuCorePref", "0"); - - // Current video backend being used. Falls back to software rendering upon error. - String currentVideoBackend = prefs.getString("gpuPref", "Software Rendering"); - - // Whether or not to ignore all EFB access requests from the CPU. - boolean skipEFBAccess = prefs.getBoolean("skipEFBAccess", false); - - // Whether or not to ignore changes to the EFB format. - boolean ignoreFormatChanges = prefs.getBoolean("ignoreFormatChanges", false); - - // EFB copy method to use. - String efbCopyMethod = prefs.getString("efbCopyMethod", "Off"); - - // Texture cache accuracy. Falls back to "Fast" up error. - String textureCacheAccuracy = prefs.getString("textureCacheAccuracy", "128"); - - // External frame buffer emulation. Falls back to disabled upon error. - String externalFrameBuffer = prefs.getString("externalFrameBuffer", "Disabled"); - - // Whether or not display list caching is enabled. - boolean dlistCachingEnabled = prefs.getBoolean("cacheDisplayLists", false); - - // Whether or not to disable destination alpha. - boolean disableDstAlphaPass = prefs.getBoolean("disableDestinationAlpha", false); - - // Whether or not to use fast depth calculation. - boolean useFastDepthCalc = prefs.getBoolean("fastDepthCalculation", true); - - // Internal resolution. Falls back to 1x Native upon error. - String internalResolution = prefs.getString("internalResolution", "2"); - - // Anisotropic Filtering Level. Falls back to 1x upon error. - String anisotropicFiltLevel = prefs.getString("anisotropicFiltering", "0"); - - // Whether or not Scaled EFB copies are used. - boolean usingScaledEFBCopy = prefs.getBoolean("scaledEFBCopy", true); - - // Whether or not per-pixel lighting is used. - boolean usingPerPixelLighting = prefs.getBoolean("perPixelLighting", false); - - // Whether or not texture filtering is being forced. - boolean isForcingTextureFiltering = prefs.getBoolean("forceTextureFiltering", false); - - // Whether or not fog is disabled. - boolean fogIsDisabled = prefs.getBoolean("disableFog", false); - - - // CPU related Settings - NativeLibrary.SetConfig("Dolphin.ini", "Core", "CPUCore", currentEmuCore); - NativeLibrary.SetConfig("Dolphin.ini", "Core", "CPUThread", isUsingDualCore ? "True" : "False"); - - // General Video Settings - NativeLibrary.SetConfig("Dolphin.ini", "Core", "GFXBackend", currentVideoBackend); - - // Video Hack Settings - NativeLibrary.SetConfig("gfx_opengl.ini", "Hacks", "EFBAccessEnable", skipEFBAccess ? "False" : "True"); - NativeLibrary.SetConfig("gfx_opengl.ini", "Hacks", "EFBEmulateFormatChanges", ignoreFormatChanges ? "True" : "False"); - - // Set EFB Copy Method - if (efbCopyMethod.equals("Off")) - { - NativeLibrary.SetConfig("gfx_opengl.ini", "Hacks", "EFBCopyEnable", "False"); - } - else if (efbCopyMethod.equals("Texture")) - { - NativeLibrary.SetConfig("gfx_opengl.ini", "Hacks", "EFBCopyEnable", "True"); - NativeLibrary.SetConfig("gfx_opengl.ini", "Hacks", "EFBToTextureEnable", "True"); - } - else if (efbCopyMethod.equals("RAM (uncached)")) - { - NativeLibrary.SetConfig("gfx_opengl.ini", "Hacks", "EFBCopyEnable", "True"); - NativeLibrary.SetConfig("gfx_opengl.ini", "Hacks", "EFBToTextureEnable", "False"); - NativeLibrary.SetConfig("gfx_opengl.ini", "Hacks", "EFBCopyCacheEnable", "False"); - } - else if (efbCopyMethod.equals("RAM (cached)")) - { - NativeLibrary.SetConfig("gfx_opengl.ini", "Hacks", "EFBCopyEnable", "True"); - NativeLibrary.SetConfig("gfx_opengl.ini", "Hacks", "EFBToTextureEnable", "False"); - NativeLibrary.SetConfig("gfx_opengl.ini", "Hacks", "EFBCopyCacheEnable", "True"); - } - - // Set texture cache accuracy - NativeLibrary.SetConfig("gfx_opengl.ini", "Settings", "SafeTextureCacheColorSamples", textureCacheAccuracy); - - // Set external frame buffer. - if (externalFrameBuffer.equals("Disabled")) - { - NativeLibrary.SetConfig("gfx_opengl.ini", "Settings", "UseXFB", "False"); - } - else if (externalFrameBuffer.equals("Virtual")) - { - NativeLibrary.SetConfig("gfx_opengl.ini", "Settings", "UseXFB", "True"); - NativeLibrary.SetConfig("gfx_opengl.ini", "Settings", "UseRealXFB", "False"); - } - else if (externalFrameBuffer.equals("Real")) - { - NativeLibrary.SetConfig("gfx_opengl.ini", "Settings", "UseXFB", "True"); - NativeLibrary.SetConfig("gfx_opengl.ini", "Settings", "UseRealXFB", "True"); - } - - NativeLibrary.SetConfig("gfx_opengl.ini", "Hacks", "DlistCachingEnable", dlistCachingEnabled ? "True" : "False"); - NativeLibrary.SetConfig("gfx_opengl.ini", "Settings", "DstAlphaPass", disableDstAlphaPass ? "True" : "False"); - NativeLibrary.SetConfig("gfx_opengl.ini", "Settings", "FastDepthCalc", useFastDepthCalc ? "True" : "False"); - - //-- Enhancement Settings --// - NativeLibrary.SetConfig("gfx_opengl.ini", "Settings", "EFBScale", internalResolution); - NativeLibrary.SetConfig("gfx_opengl.ini", "Enhancements", "MaxAnisotropy", anisotropicFiltLevel); - NativeLibrary.SetConfig("gfx_opengl.ini", "Hacks", "EFBScaledCopy", usingScaledEFBCopy ? "True" : "False"); - NativeLibrary.SetConfig("gfx_opengl.ini", "Settings", "EnablePixelLighting", usingPerPixelLighting ? "True" : "False"); - NativeLibrary.SetConfig("gfx_opengl.ini", "Enhancements", "ForceFiltering", isForcingTextureFiltering ? "True" : "False"); - NativeLibrary.SetConfig("gfx_opengl.ini", "Settings", "DisableFog", fogIsDisabled ? "True" : "False"); - } -} diff --git a/Source/Android/src/org/dolphinemu/dolphinemu/folderbrowser/FolderBrowser.java b/Source/Android/src/org/dolphinemu/dolphinemu/folderbrowser/FolderBrowser.java new file mode 100644 index 0000000000..3dc0b4fbb4 --- /dev/null +++ b/Source/Android/src/org/dolphinemu/dolphinemu/folderbrowser/FolderBrowser.java @@ -0,0 +1,145 @@ +package org.dolphinemu.dolphinemu.folderbrowser; + +import android.app.Activity; +import android.app.Fragment; +import android.os.Bundle; +import android.os.Environment; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.AdapterView; +import android.widget.ListView; +import android.widget.Toast; + +import java.io.File; +import java.util.*; + +import org.dolphinemu.dolphinemu.NativeLibrary; +import org.dolphinemu.dolphinemu.R; +import org.dolphinemu.dolphinemu.gamelist.GameListActivity; + +public final class FolderBrowser extends Fragment +{ + private Activity m_activity; + private FolderBrowserAdapter adapter; + private ListView mDrawerList; + private View rootView; + private static File currentDir = null; + + // Populates the FolderView with the given currDir's contents. + private void Fill(File currDir) + { + m_activity.setTitle(getString(R.string.current_dir) + currDir.getName()); + File[] dirs = currDir.listFiles(); + Listdir = new ArrayList(); + Listfls = new ArrayList(); + + // Supported extensions to filter by + Set validExts = new HashSet(Arrays.asList(".gcm", ".iso", ".wbfs", ".gcz", ".dol", ".elf", ".dff")); + Set invalidExts = new HashSet(Arrays.asList(".zip", ".rar", ".7z")); + + // Search for any directories or supported files within the current dir. + try + { + for(File entry : dirs) + { + String entryName = entry.getName(); + + if (entryName.charAt(0) != '.') + { + if(entry.isDirectory()) + { + dir.add(new FolderBrowserItem(entryName, entry.getAbsolutePath(), true)); + } + else + { + if (validExts.contains(entryName.toLowerCase().substring(entryName.lastIndexOf('.')))) + { + fls.add(new FolderBrowserItem(entryName, getString(R.string.file_size)+entry.length(), entry.getAbsolutePath(), true)); + } + else if (invalidExts.contains(entryName.toLowerCase().substring(entryName.lastIndexOf('.')))) + { + fls.add(new FolderBrowserItem(entryName, getString(R.string.file_size)+entry.length(), entry.getAbsolutePath(), false)); + } + } + } + } + } + catch(Exception ignored) + { + } + + Collections.sort(dir); + Collections.sort(fls); + dir.addAll(fls); + + // Check for a parent directory to the one we're currently in. + if (!currDir.getPath().equalsIgnoreCase("/")) + dir.add(0, new FolderBrowserItem("..", getString(R.string.parent_directory), currDir.getParent(), true)); + + adapter = new FolderBrowserAdapter(m_activity, R.layout.folderbrowser, dir); + mDrawerList = (ListView) rootView.findViewById(R.id.gamelist); + mDrawerList.setAdapter(adapter); + mDrawerList.setOnItemClickListener(mMenuItemClickListener); + } + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) + { + if(currentDir == null) + currentDir = new File(Environment.getExternalStorageDirectory().getPath()); + + rootView = inflater.inflate(R.layout.gamelist_listview, container, false); + + Fill(currentDir); + return mDrawerList; + } + + private AdapterView.OnItemClickListener mMenuItemClickListener = new AdapterView.OnItemClickListener() + { + public void onItemClick(AdapterView parent, View view, int position, long id) + { + FolderBrowserItem item = adapter.getItem(position); + if(item.isDirectory()) + { + currentDir = new File(item.getPath()); + Fill(currentDir); + } + else + { + if (item.isValid()) + FolderSelected(); + else + Toast.makeText(m_activity, getString(R.string.cant_use_compressed_filetypes), Toast.LENGTH_LONG).show(); + } + } + }; + + @Override + public void onAttach(Activity activity) + { + super.onAttach(activity); + + // This makes sure that the container activity has implemented + // the callback interface. If not, it throws an exception + try + { + m_activity = activity; + } + catch (ClassCastException e) + { + throw new ClassCastException(activity.toString() + + " must implement OnGameListZeroListener"); + } + } + private void FolderSelected() + { + String Directories = NativeLibrary.GetConfig("Dolphin.ini", "General", "GCMPathes", "0"); + int intDirectories = Integer.parseInt(Directories); + Directories = Integer.toString(intDirectories + 1); + NativeLibrary.SetConfig("Dolphin.ini", "General", "GCMPathes", Directories); + NativeLibrary.SetConfig("Dolphin.ini", "General", "GCMPath" + Integer.toString(intDirectories), currentDir.getPath()); + + ((GameListActivity)m_activity).SwitchPage(0); + } +} diff --git a/Source/Android/src/org/dolphinemu/dolphinemu/folderbrowser/FolderBrowserAdapter.java b/Source/Android/src/org/dolphinemu/dolphinemu/folderbrowser/FolderBrowserAdapter.java new file mode 100644 index 0000000000..3d8ce2d4b3 --- /dev/null +++ b/Source/Android/src/org/dolphinemu/dolphinemu/folderbrowser/FolderBrowserAdapter.java @@ -0,0 +1,89 @@ +package org.dolphinemu.dolphinemu.folderbrowser; + +import java.util.List; + +import android.content.Context; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ArrayAdapter; +import android.widget.ImageView; +import android.widget.TextView; + +import org.dolphinemu.dolphinemu.R; + +public final class FolderBrowserAdapter extends ArrayAdapter +{ + private final Context c; + private final int id; + private final List items; + + public FolderBrowserAdapter(Context context, int textViewResourceId, List objects) + { + super(context, textViewResourceId, objects); + c = context; + id = textViewResourceId; + items = objects; + } + + public FolderBrowserItem getItem(int i) + { + return items.get(i); + } + + @Override + public View getView(int position, View convertView, ViewGroup parent) + { + View v = convertView; + if (v == null) + { + LayoutInflater vi = (LayoutInflater) c.getSystemService(Context.LAYOUT_INFLATER_SERVICE); + v = vi.inflate(id, parent, false); + } + + final FolderBrowserItem item = items.get(position); + if (item != null) + { + ImageView iconView = (ImageView) v.findViewById(R.id.ImageIcon); + TextView mainText = (TextView) v.findViewById(R.id.FolderTitle); + TextView subtitleText = (TextView) v.findViewById(R.id.FolderSubTitle); + + if(mainText != null) + { + mainText.setText(item.getName()); + + if (!item.isValid()) + { + mainText.setTextColor(0xFFFF0000); + } + } + + if(subtitleText != null) + { + // Remove the subtitle for all folders, except for the parent directory folder. + if (item.isDirectory() && !item.getSubtitle().equals(c.getResources().getString(R.string.parent_directory))) + { + subtitleText.setVisibility(View.GONE); + } + else + { + subtitleText.setText(item.getSubtitle()); + } + } + + if (iconView != null) + { + if (item.isDirectory()) + { + iconView.setImageResource(R.drawable.ic_menu_folder); + } + else + { + iconView.setImageResource(R.drawable.ic_menu_file); + } + } + + } + return v; + } +} diff --git a/Source/Android/src/org/dolphinemu/dolphinemu/folderbrowser/FolderBrowserItem.java b/Source/Android/src/org/dolphinemu/dolphinemu/folderbrowser/FolderBrowserItem.java new file mode 100644 index 0000000000..1184b4889c --- /dev/null +++ b/Source/Android/src/org/dolphinemu/dolphinemu/folderbrowser/FolderBrowserItem.java @@ -0,0 +1,123 @@ +package org.dolphinemu.dolphinemu.folderbrowser; + +import java.io.File; + +/** + * Represents an item in the folder browser list. + */ +public final class FolderBrowserItem implements Comparable +{ + private final String name; + private final String subtitle; + private final String path; + private final boolean isValid; + private final File underlyingFile; + + /** + * Constructor + * + * @param name The name of the file/folder represented by this item. + * @param subtitle The subtitle of this FolderBrowserItem to display. + * @param path The path of the file/folder represented by this item. + * @param isValid Whether or not this item represents a file type that can be handled. + */ + public FolderBrowserItem(String name, String subtitle, String path, boolean isValid) + { + this.name = name; + this.subtitle = subtitle; + this.path = path; + this.isValid = isValid; + this.underlyingFile = new File(path); + } + + /** + * Constructor. Initializes a FolderBrowserItem with an empty subtitle. + * + * @param ctx Context this FolderBrowserItem is being used in. + * @param name The name of the file/folder represented by this item. + * @param path The path of the file/folder represented by this item. + * @param isValid Whether or not this item represents a file type that can be handled. + */ + public FolderBrowserItem(String name, String path, boolean isValid) + { + this.name = name; + this.subtitle = ""; + this.path = path; + this.isValid = isValid; + this.underlyingFile = new File(path); + } + + /** + * Gets the name of the file/folder represented by this FolderBrowserItem. + * + * @return the name of the file/folder represented by this FolderBrowserItem. + */ + public String getName() + { + return name; + } + + /** + * Gets the subtitle text of this FolderBrowserItem. + * + * @return the subtitle text of this FolderBrowserItem. + */ + public String getSubtitle() + { + return subtitle; + } + + /** + * Gets the path of the file/folder represented by this FolderBrowserItem. + * + * @return the path of the file/folder represented by this FolderBrowserItem. + */ + public String getPath() + { + return path; + } + + /** + * Gets whether or not the file represented + * by this FolderBrowserItem is supported + * and can be handled correctly. + * + * @return whether or not the file represented + * by this FolderBrowserItem is supported + * and can be handled correctly. + */ + public boolean isValid() + { + return isValid; + } + + /** + * Gets the {@link File} representation of the underlying file/folder + * represented by this FolderBrowserItem. + * + * @return the {@link File} representation of the underlying file/folder + * represented by this FolderBrowserItem. + */ + public File getUnderlyingFile() + { + return underlyingFile; + } + + /** + * Gets whether or not this FolderBrowserItem represents a directory. + * + * @return true if this FolderBrowserItem represents a directory, false otherwise. + */ + public boolean isDirectory() + { + return underlyingFile.isDirectory(); + } + + public int compareTo(FolderBrowserItem other) + { + if(this.name != null) + return this.name.toLowerCase().compareTo(other.getName().toLowerCase()); + else + throw new IllegalArgumentException(); + } +} diff --git a/Source/Android/src/org/dolphinemu/dolphinemu/gamelist/GameListActivity.java b/Source/Android/src/org/dolphinemu/dolphinemu/gamelist/GameListActivity.java new file mode 100644 index 0000000000..8e460527ff --- /dev/null +++ b/Source/Android/src/org/dolphinemu/dolphinemu/gamelist/GameListActivity.java @@ -0,0 +1,275 @@ +package org.dolphinemu.dolphinemu.gamelist; + +import android.app.Activity; +import android.app.Fragment; +import android.app.FragmentManager; +import android.content.Intent; +import android.content.res.Configuration; +import android.os.Bundle; +import android.support.v4.app.ActionBarDrawerToggle; +import android.support.v4.widget.DrawerLayout; +import android.view.*; +import android.widget.AdapterView; +import android.widget.ListView; +import java.util.ArrayList; +import java.util.List; + +import org.dolphinemu.dolphinemu.AboutFragment; +import org.dolphinemu.dolphinemu.NativeLibrary; +import org.dolphinemu.dolphinemu.R; +import org.dolphinemu.dolphinemu.folderbrowser.FolderBrowser; +import org.dolphinemu.dolphinemu.inputconfig.InputConfigAdapter; +import org.dolphinemu.dolphinemu.inputconfig.InputConfigFragment; +import org.dolphinemu.dolphinemu.inputconfig.InputConfigItem; +import org.dolphinemu.dolphinemu.settings.PrefsActivity; +import org.dolphinemu.dolphinemu.sidemenu.SideMenuAdapter; +import org.dolphinemu.dolphinemu.sidemenu.SideMenuItem; + +/** + * Copyright 2013 Dolphin Emulator Project + * Licensed under GPLv2 + * Refer to the license.txt file included. + */ +public final class GameListActivity extends Activity + implements GameListFragment.OnGameListZeroListener +{ + private int mCurFragmentNum = 0; + private Fragment mCurFragment; + + private ActionBarDrawerToggle mDrawerToggle; + private DrawerLayout mDrawerLayout; + private SideMenuAdapter mDrawerAdapter; + private ListView mDrawerList; + + // Called from the game list fragment + public void onZeroFiles() + { + mDrawerLayout.openDrawer(mDrawerList); + } + + @Override + protected void onCreate(Bundle savedInstanceState) + { + super.onCreate(savedInstanceState); + setContentView(R.layout.gamelist_activity); + + mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout); + mDrawerList = (ListView) findViewById(R.id.left_drawer); + + List dir = new ArrayList(); + dir.add(new SideMenuItem(getString(R.string.game_list), 0)); + dir.add(new SideMenuItem(getString(R.string.browse_folder), 1)); + dir.add(new SideMenuItem(getString(R.string.settings), 2)); + dir.add(new SideMenuItem(getString(R.string.gamepad_config), 3)); + dir.add(new SideMenuItem(getString(R.string.about), 4)); + + mDrawerAdapter = new SideMenuAdapter(this, R.layout.sidemenu, dir); + mDrawerList.setAdapter(mDrawerAdapter); + mDrawerList.setOnItemClickListener(mMenuItemClickListener); + + // enable ActionBar app icon to behave as action to toggle nav drawer + getActionBar().setDisplayHomeAsUpEnabled(true); + getActionBar().setHomeButtonEnabled(true); + + // ActionBarDrawerToggle ties together the the proper interactions + // between the sliding drawer and the action bar app icon + mDrawerToggle = new ActionBarDrawerToggle( + this, /* host Activity */ + mDrawerLayout, /* DrawerLayout object */ + R.drawable.ic_drawer, /* nav drawer image to replace 'Up' caret */ + R.string.drawer_open, /* "open drawer" description for accessibility */ + R.string.drawer_close /* "close drawer" description for accessibility */ + ) { + public void onDrawerClosed(View view) { + invalidateOptionsMenu(); // creates call to onPrepareOptionsMenu() + } + + public void onDrawerOpened(View drawerView) { + invalidateOptionsMenu(); // creates call to onPrepareOptionsMenu() + } + }; + mDrawerLayout.setDrawerListener(mDrawerToggle); + + recreateFragment(); + } + + private void recreateFragment() + { + mCurFragment = new GameListFragment(); + FragmentManager fragmentManager = getFragmentManager(); + fragmentManager.beginTransaction().replace(R.id.content_frame, mCurFragment).commit(); + } + + public void SwitchPage(int toPage) + { + if (mCurFragmentNum == toPage) + return; + + switch (mCurFragmentNum) + { + // Folder browser + case 1: + recreateFragment(); + break; + + case 3: // Gamepad settings + { + InputConfigAdapter adapter = ((InputConfigFragment)mCurFragment).getAdapter(); + for (int a = 0; a < adapter.getCount(); ++a) + { + InputConfigItem o = adapter.getItem(a); + String config = o.getConfig(); + String bind = o.getBind(); + String ConfigValues[] = config.split("-"); + String Key = ConfigValues[0]; + String Value = ConfigValues[1]; + NativeLibrary.SetConfig("Dolphin.ini", Key, Value, bind); + } + } + break; + + case 0: // Game List + case 2: // Settings + case 4: // About + /* Do Nothing */ + break; + } + + switch(toPage) + { + case 0: + { + mCurFragmentNum = 0; + mCurFragment = new GameListFragment(); + FragmentManager fragmentManager = getFragmentManager(); + fragmentManager.beginTransaction().replace(R.id.content_frame, mCurFragment).commit(); + } + break; + + case 1: + { + mCurFragmentNum = 1; + mCurFragment = new FolderBrowser(); + FragmentManager fragmentManager = getFragmentManager(); + fragmentManager.beginTransaction().replace(R.id.content_frame, mCurFragment).commit(); + } + break; + + case 2: + { + Intent intent = new Intent(this, PrefsActivity.class); + startActivity(intent); + } + break; + + case 3: + { + mCurFragmentNum = 3; + mCurFragment = new InputConfigFragment(); + FragmentManager fragmentManager = getFragmentManager(); + fragmentManager.beginTransaction().replace(R.id.content_frame, mCurFragment).commit(); + } + break; + + case 4: + { + mCurFragmentNum = 4; + mCurFragment = new AboutFragment(); + FragmentManager fragmentManager = getFragmentManager(); + fragmentManager.beginTransaction().replace(R.id.content_frame, mCurFragment).commit(); + } + break; + + default: + break; + } + } + + private AdapterView.OnItemClickListener mMenuItemClickListener = new AdapterView.OnItemClickListener() + { + public void onItemClick(AdapterView parent, View view, int position, long id) + { + SideMenuItem o = mDrawerAdapter.getItem(position); + mDrawerLayout.closeDrawer(mDrawerList); + SwitchPage(o.getID()); + } + }; + /** + * When using the ActionBarDrawerToggle, you must call it during + * onPostCreate() and onConfigurationChanged()... + */ + + @Override + protected void onPostCreate(Bundle savedInstanceState) + { + super.onPostCreate(savedInstanceState); + // Sync the toggle state after onRestoreInstanceState has occurred. + mDrawerToggle.syncState(); + } + + @Override + public void onConfigurationChanged(Configuration newConfig) + { + super.onConfigurationChanged(newConfig); + // Pass any configuration change to the drawer toggle + mDrawerToggle.onConfigurationChanged(newConfig); + } + + /* Called whenever we call invalidateOptionsMenu() */ + @Override + public boolean onPrepareOptionsMenu(Menu menu) + { + return super.onPrepareOptionsMenu(menu); + } + + @Override + public boolean onOptionsItemSelected(MenuItem item) + { + // The action bar home/up action should open or close the drawer. + // ActionBarDrawerToggle will take care of this. + if (mDrawerToggle.onOptionsItemSelected(item)) + { + return true; + } + + return super.onOptionsItemSelected(item); + } + + public void onBackPressed() + { + SwitchPage(0); + } + + public interface OnGameConfigListener + { + public boolean onMotionEvent(MotionEvent event); + public boolean onKeyEvent(KeyEvent event); + } + + // Gets move(triggers, joystick) events + @Override + public boolean dispatchGenericMotionEvent(MotionEvent event) + { + if (mCurFragmentNum == 3) + { + if (((OnGameConfigListener)mCurFragment).onMotionEvent(event)) + return true; + } + + return super.dispatchGenericMotionEvent(event); + } + + // Gets button presses + @Override + public boolean dispatchKeyEvent(KeyEvent event) + { + if (mCurFragmentNum == 3) + { + if (((OnGameConfigListener)mCurFragment).onKeyEvent(event)) + return true; + } + + return super.dispatchKeyEvent(event); + } + +} diff --git a/Source/Android/src/org/dolphinemu/dolphinemu/gamelist/GameListAdapter.java b/Source/Android/src/org/dolphinemu/dolphinemu/gamelist/GameListAdapter.java new file mode 100644 index 0000000000..1944733723 --- /dev/null +++ b/Source/Android/src/org/dolphinemu/dolphinemu/gamelist/GameListAdapter.java @@ -0,0 +1,68 @@ +package org.dolphinemu.dolphinemu.gamelist; + +import android.content.Context; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ArrayAdapter; +import android.widget.ImageView; +import android.widget.TextView; + +import java.util.List; + +import org.dolphinemu.dolphinemu.R; + +public final class GameListAdapter extends ArrayAdapter +{ + private final Context c; + private final int id; + private final Listitems; + + public GameListAdapter(Context context, int textViewResourceId, List objects) + { + super(context, textViewResourceId, objects); + c = context; + id = textViewResourceId; + items = objects; + } + + public GameListItem getItem(int i) + { + return items.get(i); + } + + @Override + public View getView(int position, View convertView, ViewGroup parent) + { + View v = convertView; + if (v == null) + { + LayoutInflater vi = (LayoutInflater)c.getSystemService(Context.LAYOUT_INFLATER_SERVICE); + v = vi.inflate(id, parent, false); + } + + final GameListItem item = items.get(position); + if (item != null) + { + TextView title = (TextView) v.findViewById(R.id.GameItemTitle); + TextView subtitle = (TextView) v.findViewById(R.id.GameItemSubText); + ImageView icon = (ImageView) v.findViewById(R.id.GameItemIcon); + + if(title != null) + title.setText(item.getName()); + + if(subtitle != null) + subtitle.setText(item.getData()); + + if(icon != null) + { + icon.setImageBitmap(item.getImage()); + icon.getLayoutParams().width = (int) ((860 / c.getResources().getDisplayMetrics().density) + 0.5); + icon.getLayoutParams().height = (int)((340 / c.getResources().getDisplayMetrics().density) + 0.5); + } + } + + return v; + } +} + diff --git a/Source/Android/src/org/dolphinemu/dolphinemu/gamelist/GameListFragment.java b/Source/Android/src/org/dolphinemu/dolphinemu/gamelist/GameListFragment.java new file mode 100644 index 0000000000..945fb64acb --- /dev/null +++ b/Source/Android/src/org/dolphinemu/dolphinemu/gamelist/GameListFragment.java @@ -0,0 +1,156 @@ +package org.dolphinemu.dolphinemu.gamelist; + +import android.app.Activity; +import android.app.Fragment; +import android.content.Intent; +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.AdapterView; +import android.widget.ListView; +import android.widget.Toast; + +import java.io.File; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +import org.dolphinemu.dolphinemu.NativeLibrary; +import org.dolphinemu.dolphinemu.R; + +/** + * Copyright 2013 Dolphin Emulator Project + * Licensed under GPLv2 + * Refer to the license.txt file included. + */ +public final class GameListFragment extends Fragment +{ + private ListView mMainList; + private GameListAdapter mGameAdapter; + private static GameListActivity mMe; + OnGameListZeroListener mCallback; + + public interface OnGameListZeroListener + { + public void onZeroFiles(); + } + + public GameListFragment() + { + // Empty constructor required for fragment subclasses + } + + private void Fill() + { + List fls = new ArrayList(); + String Directories = NativeLibrary.GetConfig("Dolphin.ini", "General", "GCMPathes", "0"); + int intDirectories = Integer.parseInt(Directories); + + // Extensions to filter by. + Set exts = new HashSet(Arrays.asList(".gcm", ".iso", ".wbfs", ".gcz", ".dol", ".elf", ".dff")); + + for (int a = 0; a < intDirectories; ++a) + { + String BrowseDir = NativeLibrary.GetConfig("Dolphin.ini", "General", "GCMPath" + a, ""); + File currentDir = new File(BrowseDir); + File[] dirs = currentDir.listFiles(); + try + { + for(File entry : dirs) + { + String entryName = entry.getName(); + + if (entryName.charAt(0) != '.') + { + if(!entry.isDirectory()) + { + if (exts.contains(entryName.toLowerCase().substring(entryName.lastIndexOf('.')))) + fls.add(new GameListItem(mMe.getApplicationContext(), entryName, getString(R.string.file_size)+entry.length(),entry.getAbsolutePath(), true)); + } + } + } + } + catch(Exception ignored) + { + } + } + Collections.sort(fls); + + // Remove any duplicate items from the list. + // We don't need to index these in the game list more than once. + // + // This works by comparing the paths of items in the file list for equality, + // so there should be no worries about accidentally removing a valid game. + for (int i = 0; i < fls.size(); i++) + { + int indexNext = i+1; + + if (indexNext < fls.size() && fls.get(indexNext).getPath().contains(fls.get(i).getPath())) + { + fls.remove(indexNext); + } + } + + mGameAdapter = new GameListAdapter(mMe, R.layout.gamelist_layout, fls); + mMainList.setAdapter(mGameAdapter); + if (fls.size() == 0) + mCallback.onZeroFiles(); + } + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) + { + View rootView = inflater.inflate(R.layout.gamelist_listview, container, false); + mMainList = (ListView) rootView.findViewById(R.id.gamelist); + mMainList.setOnItemClickListener(mGameItemClickListener); + + Fill(); + + return mMainList; + } + + private AdapterView.OnItemClickListener mGameItemClickListener = new AdapterView.OnItemClickListener() + { + public void onItemClick(AdapterView parent, View view, int position, long id) + { + GameListItem o = mGameAdapter.getItem(position); + if(!(o.getData().equalsIgnoreCase(getString(R.string.folder))||o.getData().equalsIgnoreCase(getString(R.string.parent_directory)))) + { + onFileClick(o.getPath()); + } + } + }; + + private void onFileClick(String o) + { + Toast.makeText(mMe, getString(R.string.file_clicked) + o, Toast.LENGTH_SHORT).show(); + + Intent intent = new Intent(); + intent.putExtra("Select", o); + mMe.setResult(Activity.RESULT_OK, intent); + mMe.finish(); + } + + @Override + public void onAttach(Activity activity) + { + super.onAttach(activity); + + // This makes sure that the container activity has implemented + // the callback interface. If not, it throws an exception + try + { + mCallback = (OnGameListZeroListener) activity; + mMe = (GameListActivity) activity; + } + catch (ClassCastException e) + { + throw new ClassCastException(activity.toString() + + " must implement OnGameListZeroListener"); + } + } +} \ No newline at end of file diff --git a/Source/Android/src/org/dolphinemu/dolphinemu/gamelist/GameListItem.java b/Source/Android/src/org/dolphinemu/dolphinemu/gamelist/GameListItem.java new file mode 100644 index 0000000000..9634eb5fa1 --- /dev/null +++ b/Source/Android/src/org/dolphinemu/dolphinemu/gamelist/GameListItem.java @@ -0,0 +1,94 @@ +package org.dolphinemu.dolphinemu.gamelist; + +import android.content.Context; +import android.graphics.Bitmap; +import android.graphics.BitmapFactory; + +import java.io.File; +import java.io.IOException; +import java.io.InputStream; + +import org.dolphinemu.dolphinemu.NativeLibrary; + +public final class GameListItem implements Comparable +{ + private String name; + private final String data; + private final String path; + private final boolean isValid; + private Bitmap image; + + public GameListItem(Context ctx, String name, String data, String path, boolean isValid) + { + this.name = name; + this.data = data; + this.path = path; + this.isValid = isValid; + + File file = new File(path); + if (!file.isDirectory() && !path.equals("")) + { + int[] Banner = NativeLibrary.GetBanner(path); + if (Banner[0] == 0) + { + try + { + // Open the no banner icon. + InputStream noBannerPath = ctx.getAssets().open("NoBanner.png"); + + // Decode the bitmap. + image = BitmapFactory.decodeStream(noBannerPath); + + // Scale the bitmap to match other banners. + image = Bitmap.createScaledBitmap(image, 96, 32, false); + } + catch (IOException e) + { + // TODO Auto-generated catch block + e.printStackTrace(); + } + + } + else + { + image = Bitmap.createBitmap(Banner, 96, 32, Bitmap.Config.ARGB_8888); + } + + this.name = NativeLibrary.GetTitle(path); + } + } + + public String getName() + { + return name; + } + + public String getData() + { + return data; + } + + public String getPath() + { + return path; + } + + public Bitmap getImage() + { + return image; + } + + public boolean isValid() + { + return isValid; + } + + public int compareTo(GameListItem o) + { + if(this.name != null) + return this.name.toLowerCase().compareTo(o.getName().toLowerCase()); + else + throw new IllegalArgumentException(); + } +} + diff --git a/Source/Android/src/org/dolphinemu/dolphinemu/inputconfig/InputConfigAdapter.java b/Source/Android/src/org/dolphinemu/dolphinemu/inputconfig/InputConfigAdapter.java new file mode 100644 index 0000000000..a02c97c343 --- /dev/null +++ b/Source/Android/src/org/dolphinemu/dolphinemu/inputconfig/InputConfigAdapter.java @@ -0,0 +1,63 @@ +package org.dolphinemu.dolphinemu.inputconfig; + +import android.content.Context; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ArrayAdapter; +import android.widget.TextView; + +import java.util.List; + +import org.dolphinemu.dolphinemu.R; + +/** + * Copyright 2013 Dolphin Emulator Project + * Licensed under GPLv2 + * Refer to the license.txt file included. + */ +public final class InputConfigAdapter extends ArrayAdapter +{ + private final Context c; + private final int id; + private final List items; + + public InputConfigAdapter(Context context, int textViewResourceId, List objects) + { + super(context, textViewResourceId, objects); + c = context; + id = textViewResourceId; + items = objects; + } + + public InputConfigItem getItem(int i) + { + return items.get(i); + } + + @Override + public View getView(int position, View convertView, ViewGroup parent) + { + View v = convertView; + if (v == null) + { + LayoutInflater vi = (LayoutInflater)c.getSystemService(Context.LAYOUT_INFLATER_SERVICE); + v = vi.inflate(id, parent, false); + } + + final InputConfigItem item = items.get(position); + if (item != null) + { + TextView title = (TextView) v.findViewById(R.id.FolderTitle); + TextView subtitle = (TextView) v.findViewById(R.id.FolderSubTitle); + + if(title != null) + title.setText(item.getName()); + + if(subtitle != null) + subtitle.setText(item.getBind()); + } + + return v; + } +} diff --git a/Source/Android/src/org/dolphinemu/dolphinemu/inputconfig/InputConfigFragment.java b/Source/Android/src/org/dolphinemu/dolphinemu/inputconfig/InputConfigFragment.java new file mode 100644 index 0000000000..00794f3ea0 --- /dev/null +++ b/Source/Android/src/org/dolphinemu/dolphinemu/inputconfig/InputConfigFragment.java @@ -0,0 +1,221 @@ +package org.dolphinemu.dolphinemu.inputconfig; + +import android.app.Activity; +import android.app.Fragment; +import android.os.Build; +import android.os.Bundle; +import android.util.Log; +import android.view.*; +import android.widget.AdapterView; +import android.widget.ListView; +import android.widget.Toast; + +import java.util.ArrayList; +import java.util.List; + +import org.dolphinemu.dolphinemu.R; +import org.dolphinemu.dolphinemu.gamelist.GameListActivity; + +/** + * Copyright 2013 Dolphin Emulator Project + * Licensed under GPLv2 + * Refer to the license.txt file included. + */ +public final class InputConfigFragment extends Fragment + implements GameListActivity.OnGameConfigListener +{ + private Activity m_activity; + private ListView mDrawerList; + private InputConfigAdapter adapter; + private int configPosition = 0; + boolean Configuring = false; + boolean firstEvent = true; + + static public String getInputDesc(InputDevice input) + { + if (input == null) + return "null"; // Happens when the inputdevice is from an unknown source + + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) + { + return input.getDescriptor(); + } + else + { + List motions = input.getMotionRanges(); + String fakeid = ""; + + for (InputDevice.MotionRange range : motions) + fakeid += range.getAxis(); + + return fakeid; + } + } + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) + { + List Input = new ArrayList(); + Input.add(new InputConfigItem(getString(R.string.draw_onscreen_controls), "Android-ScreenControls", "True")); + Input.add(new InputConfigItem(getString(R.string.button_a), "Android-InputA")); + Input.add(new InputConfigItem(getString(R.string.button_b), "Android-InputB")); + Input.add(new InputConfigItem(getString(R.string.button_start), "Android-InputStart")); + Input.add(new InputConfigItem(getString(R.string.button_x), "Android-InputX")); + Input.add(new InputConfigItem(getString(R.string.button_y), "Android-InputY")); + Input.add(new InputConfigItem(getString(R.string.button_z), "Android-InputZ")); + Input.add(new InputConfigItem(getString(R.string.dpad_up), "Android-DPadUp")); + Input.add(new InputConfigItem(getString(R.string.dpad_down), "Android-DPadDown")); + Input.add(new InputConfigItem(getString(R.string.dpad_left), "Android-DPadLeft")); + Input.add(new InputConfigItem(getString(R.string.dpad_right), "Android-DPadRight")); + Input.add(new InputConfigItem(getString(R.string.main_stick_up), "Android-MainUp")); + Input.add(new InputConfigItem(getString(R.string.main_stick_down), "Android-MainDown")); + Input.add(new InputConfigItem(getString(R.string.main_stick_left), "Android-MainLeft")); + Input.add(new InputConfigItem(getString(R.string.main_stick_right), "Android-MainRight")); + Input.add(new InputConfigItem(getString(R.string.c_stick_up), "Android-CStickUp")); + Input.add(new InputConfigItem(getString(R.string.c_stick_down), "Android-CStickDown")); + Input.add(new InputConfigItem(getString(R.string.c_stick_left), "Android-CStickLeft")); + Input.add(new InputConfigItem(getString(R.string.c_stick_right), "Android-CStickRight")); + Input.add(new InputConfigItem(getString(R.string.trigger_left), "Android-InputL")); + Input.add(new InputConfigItem(getString(R.string.trigger_right), "Android-InputR")); + + adapter = new InputConfigAdapter(m_activity, R.layout.folderbrowser, Input); + View rootView = inflater.inflate(R.layout.gamelist_listview, container, false); + mDrawerList = (ListView) rootView.findViewById(R.id.gamelist); + + mDrawerList.setAdapter(adapter); + mDrawerList.setOnItemClickListener(mMenuItemClickListener); + return mDrawerList; + } + + private AdapterView.OnItemClickListener mMenuItemClickListener = new AdapterView.OnItemClickListener() + { + public void onItemClick(AdapterView parent, View view, int position, long id) + { + InputConfigItem o = adapter.getItem(position); + switch(position) + { + case 0: // On screen controls + String newBind; + if (o.getBind().equals("True")) + { + Toast.makeText(m_activity, getString(R.string.not_drawing_onscreen_controls), Toast.LENGTH_SHORT).show(); + newBind = "False"; + } + else + { + Toast.makeText(m_activity, getString(R.string.drawing_onscreen_controls), Toast.LENGTH_SHORT).show(); + newBind = "True"; + } + adapter.remove(o); + o.setBind(newBind); + adapter.insert(o, position); + break; + + default: // gamepad controls + + Toast.makeText(m_activity, getString(R.string.press_button_to_config, o.getName()), Toast.LENGTH_SHORT).show(); + configPosition = position; + Configuring = true; + firstEvent = true; + break; + } + } + }; + + private static ArrayList m_values = new ArrayList(); + + private void AssignBind(String bind) + { + InputConfigItem o = adapter.getItem(configPosition); + adapter.remove(o); + o.setBind(bind); + adapter.insert(o, configPosition); + } + + public InputConfigAdapter getAdapter() + { + return adapter; + } + + // Called from GameListActivity + public boolean onMotionEvent(MotionEvent event) + { + if (((event.getSource() & InputDevice.SOURCE_CLASS_JOYSTICK) == 0)) + return false; + + InputDevice input = event.getDevice(); + List motions = input.getMotionRanges(); + if (Configuring) + { + if (firstEvent) + { + m_values.clear(); + + for (InputDevice.MotionRange range : motions) + { + m_values.add(event.getAxisValue(range.getAxis())); + } + + firstEvent = false; + } + else + { + for (int a = 0; a < motions.size(); ++a) + { + InputDevice.MotionRange range = motions.get(a); + + if (m_values.get(a) > (event.getAxisValue(range.getAxis()) + 0.5f)) + { + AssignBind("Device '" + InputConfigFragment.getInputDesc(input) + "'-Axis " + range.getAxis() + "-"); + Configuring = false; + } + else if (m_values.get(a) < (event.getAxisValue(range.getAxis()) - 0.5f)) + { + AssignBind("Device '" + InputConfigFragment.getInputDesc(input) + "'-Axis " + range.getAxis() + "+"); + Configuring = false; + } + } + } + } + return true; + } + + public boolean onKeyEvent(KeyEvent event) + { + Log.w("InputConfigFragment", "Got Event " + event.getAction()); + switch (event.getAction()) + { + case KeyEvent.ACTION_DOWN: + case KeyEvent.ACTION_UP: + if (Configuring) + { + InputDevice input = event.getDevice(); + AssignBind("Device '" + InputConfigFragment.getInputDesc(input) + "'-Button " + event.getKeyCode()); + Configuring = false; + return true; + } + + default: + break; + } + + return false; + } + + @Override + public void onAttach(Activity activity) + { + super.onAttach(activity); + + // This makes sure that the container activity has implemented + // the callback interface. If not, it throws an exception + try + { + m_activity = activity; + } + catch (ClassCastException e) + { + throw new ClassCastException(activity.toString() + + " must implement OnGameListZeroListener"); + } + } +} diff --git a/Source/Android/src/org/dolphinemu/dolphinemu/inputconfig/InputConfigItem.java b/Source/Android/src/org/dolphinemu/dolphinemu/inputconfig/InputConfigItem.java new file mode 100644 index 0000000000..71b557dcc3 --- /dev/null +++ b/Source/Android/src/org/dolphinemu/dolphinemu/inputconfig/InputConfigItem.java @@ -0,0 +1,101 @@ +/* + * Copyright 2013 Dolphin Emulator Project + * Licensed under GPLv2 + * Refer to the license.txt file included. + */ + +package org.dolphinemu.dolphinemu.inputconfig; + +import org.dolphinemu.dolphinemu.NativeLibrary; + +/** + * Represents a controller input item (button, stick, etc). + */ +public final class InputConfigItem implements Comparable +{ + private String m_name; + private String m_Config; + private String m_bind; + + private void Init(String name, String config, String defaultBind) + { + m_name = name; + m_Config = config; + String ConfigValues[] = m_Config.split("-"); + String Key = ConfigValues[0]; + String Value = ConfigValues[1]; + m_bind = NativeLibrary.GetConfig("Dolphin.ini", Key, Value, defaultBind); + } + + /** + * Constructor + * + * @param name Name of the input config item. + * @param config Name of the key in the configuration file that this control modifies. + * @param defaultBind Default binding to fall back upon if binding fails. + */ + public InputConfigItem(String name, String config, String defaultBind) + { + Init(name, config, defaultBind); + } + + /** + * Constructor that creates an InputConfigItem + * that has a default binding of "None" + * + * @param name Name of the input config item. + * @param config Name of the key in the configuration file that this control modifies. + */ + public InputConfigItem(String name, String config) + { + Init(name, config, "None"); + } + + /** + * Gets the name of this InputConfigItem. + * + * @return the name of this InputConfigItem + */ + public String getName() + { + return m_name; + } + + /** + * Gets the config key this InputConfigItem modifies. + * + * @return the config key this InputConfigItem modifies. + */ + public String getConfig() + { + return m_Config; + } + + /** + * Gets the currently set binding of this InputConfigItem + * + * @return the currently set binding of this InputConfigItem + */ + public String getBind() + { + return m_bind; + } + + /** + * Sets a new binding for this InputConfigItem. + * + * @param bind The new binding. + */ + public void setBind(String bind) + { + m_bind = bind; + } + + public int compareTo(InputConfigItem o) + { + if(this.m_name != null) + return this.m_name.toLowerCase().compareTo(o.getName().toLowerCase()); + else + throw new IllegalArgumentException(); + } +} diff --git a/Source/Android/src/org/dolphinemu/dolphinemu/settings/CPUSettingsFragment.java b/Source/Android/src/org/dolphinemu/dolphinemu/settings/CPUSettingsFragment.java new file mode 100644 index 0000000000..a50b094338 --- /dev/null +++ b/Source/Android/src/org/dolphinemu/dolphinemu/settings/CPUSettingsFragment.java @@ -0,0 +1,81 @@ +/** + * Copyright 2013 Dolphin Emulator Project + * Licensed under GPLv2 + * Refer to the license.txt file included. + */ + +package org.dolphinemu.dolphinemu.settings; + +import org.dolphinemu.dolphinemu.R; + +import android.app.Activity; +import android.os.Build; +import android.os.Bundle; +import android.preference.ListPreference; +import android.preference.PreferenceFragment; + +/** + * Responsible for the loading of the CPU preferences. + */ +public final class CPUSettingsFragment extends PreferenceFragment +{ + private Activity m_activity; + + @Override + public void onCreate(Bundle savedInstanceState) + { + super.onCreate(savedInstanceState); + + // Load the preferences from an XML resource + addPreferencesFromResource(R.xml.cpu_prefs); + + final ListPreference cpuCores = (ListPreference) findPreference("cpuCorePref"); + + // + // Set valid emulation cores depending on the CPU architecture + // that the Android device is running on. + // + if (Build.CPU_ABI.contains("x86")) + { + cpuCores.setEntries(R.array.emuCoreEntriesX86); + cpuCores.setEntryValues(R.array.emuCoreValuesX86); + } + else if (Build.CPU_ABI.contains("arm")) + { + cpuCores.setEntries(R.array.emuCoreEntriesARM); + cpuCores.setEntryValues(R.array.emuCoreValuesARM); + } + else + { + cpuCores.setEntries(R.array.emuCoreEntriesOther); + cpuCores.setEntryValues(R.array.emuCoreValuesOther); + } + } + + @Override + public void onAttach(Activity activity) + { + super.onAttach(activity); + + // This makes sure that the container activity has implemented + // the callback interface. If not, it throws an exception + try + { + m_activity = activity; + } + catch (ClassCastException e) + { + throw new ClassCastException(activity.toString() + + " must implement OnGameListZeroListener"); + } + } + + @Override + public void onDestroy() + { + super.onDestroy(); + + // When this fragment is destroyed, force the settings to be saved to the ini file. + UserPreferences.SaveConfigToDolphinIni(m_activity); + } +} diff --git a/Source/Android/src/org/dolphinemu/dolphinemu/settings/PrefsActivity.java b/Source/Android/src/org/dolphinemu/dolphinemu/settings/PrefsActivity.java new file mode 100644 index 0000000000..8186ffc05e --- /dev/null +++ b/Source/Android/src/org/dolphinemu/dolphinemu/settings/PrefsActivity.java @@ -0,0 +1,146 @@ +/** + * Copyright 2013 Dolphin Emulator Project + * Licensed under GPLv2 + * Refer to the license.txt file included. + */ + +package org.dolphinemu.dolphinemu.settings; + +import org.dolphinemu.dolphinemu.R; + +import android.app.ActionBar; +import android.app.ActionBar.Tab; +import android.app.Activity; +import android.app.Fragment; +import android.app.FragmentManager; +import android.app.FragmentTransaction; +import android.os.Bundle; +import android.support.v13.app.FragmentPagerAdapter; +import android.support.v4.view.ViewPager; + +/** + * Main activity that manages all of the preference fragments used to display + * the settings to the user. + */ +public final class PrefsActivity extends Activity implements ActionBar.TabListener +{ + /** + * The {@link android.support.v4.view.PagerAdapter} that will provide org.dolphinemu.dolphinemu.settings for each of the + * sections. We use a {@link android.support.v4.app.FragmentPagerAdapter} derivative, which will + * keep every loaded fragment in memory. If this becomes too memory intensive, it may be best to + * switch to a {@link android.support.v4.app.FragmentStatePagerAdapter}. + */ + SectionsPagerAdapter mSectionsPagerAdapter; + + /** + * The {@link ViewPager} that will host the section contents. + */ + ViewPager mViewPager; + + @Override + protected void onCreate(Bundle savedInstanceState) + { + super.onCreate(savedInstanceState); + setContentView(R.layout.prefs_viewpager); + + // Set up the action bar. + final ActionBar actionBar = getActionBar(); + actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS); + + // Create the adapter that will return a fragment for each of the three + // primary sections of the app. + mSectionsPagerAdapter = new SectionsPagerAdapter(getFragmentManager()); + + // Set up the ViewPager with the sections adapter. + mViewPager = (ViewPager) findViewById(R.id.pager); + mViewPager.setAdapter(mSectionsPagerAdapter); + + // When swiping between different sections, select the corresponding + // tab. We can also use ActionBar.Tab#select() to do this if we have + // a reference to the Tab. + mViewPager.setOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener() + { + @Override + public void onPageSelected(int position) + { + actionBar.setSelectedNavigationItem(position); + } + } ); + + // Create a tab with text corresponding to the page title defined by + // the adapter. Also specify this Activity object, which implements + // the TabListener interface, as the callback (listener) for when + // this tab is selected. + actionBar.addTab(actionBar.newTab().setText(R.string.cpu_settings).setTabListener(this)); + actionBar.addTab(actionBar.newTab().setText(R.string.video_settings).setTabListener(this)); + + } + + public void onTabReselected(Tab arg0, FragmentTransaction arg1) + { + // Do nothing. + } + + public void onTabSelected(Tab tab, FragmentTransaction ft) + { + // When the given tab is selected, switch to the corresponding page in the ViewPager. + mViewPager.setCurrentItem(tab.getPosition()); + } + + public void onTabUnselected(Tab tab, FragmentTransaction ft) + { + // Do nothing. + } + + /** + * A {@link FragmentPagerAdapter} that returns a fragment corresponding to one of the + * sections/tabs/pages. + */ + public class SectionsPagerAdapter extends FragmentPagerAdapter + { + + public SectionsPagerAdapter(FragmentManager fm) + { + super(fm); + } + + @Override + public Fragment getItem(int position) + { + switch(position) + { + case 0: + return new CPUSettingsFragment(); + + case 1: + return new VideoSettingsFragment(); + + default: // Should never happen. + return null; + } + } + + @Override + public int getCount() + { + // Show total pages. + return 2; + } + + @Override + public CharSequence getPageTitle(int position) + { + switch(position) + { + case 0: + return getString(R.string.cpu_settings).toUpperCase(); + + case 1: + return getString(R.string.video_settings).toUpperCase(); + + default: // Should never happen. + return null; + } + } + } +} diff --git a/Source/Android/src/org/dolphinemu/dolphinemu/settings/UserPreferences.java b/Source/Android/src/org/dolphinemu/dolphinemu/settings/UserPreferences.java new file mode 100644 index 0000000000..0bf8535492 --- /dev/null +++ b/Source/Android/src/org/dolphinemu/dolphinemu/settings/UserPreferences.java @@ -0,0 +1,229 @@ +/** + * Copyright 2013 Dolphin Emulator Project + * Licensed under GPLv2 + * Refer to the license.txt file included. + */ + +package org.dolphinemu.dolphinemu.settings; + +import org.dolphinemu.dolphinemu.NativeLibrary; + +import android.content.Context; +import android.content.SharedPreferences; +import android.preference.PreferenceManager; + +/** + * A class that retrieves all of the set user preferences in Android, in a safe way. + *

+ * If any preferences are added to this emulator, an accessor for that preference + * should be added here. This way lengthy calls to getters from SharedPreferences + * aren't made necessary. + */ +public final class UserPreferences +{ + /** + * Loads the set config items from the Dolphin config files to the shared preferences of this front-end + * + * @param ctx The context used to retrieve the SharedPreferences instance. + */ + public static void LoadDolphinConfigToPrefs(Context ctx) + { + SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(ctx); + + // Get an editor. + SharedPreferences.Editor editor = prefs.edit(); + + // Add the settings. + editor.putString("cpuCorePref", getConfig("Dolphin.ini", "Core", "CPUCore", "3")); + editor.putBoolean("dualCorePref", getConfig("Dolphin.ini", "Core", "CPUThread", "False").equals("True")); + editor.putString("gpuPref", getConfig("Dolphin.ini", "Core", "GFXBackend ", "Software Renderer")); + + editor.putString("internalResolution", getConfig("gfx_opengl.ini", "Settings", "EFBScale", "2") ); + editor.putString("anisotropicFiltering", getConfig("gfx_opengl.ini", "Enhancements", "MaxAnisotropy", "0")); + editor.putBoolean("scaledEFBCopy", getConfig("gfx_opengl.ini", "Hacks", "EFBScaleCopy", "True").equals("True")); + editor.putBoolean("perPixelLighting", getConfig("gfx_opengl.ini", "Settings", "EnablePixelLighting", "False").equals("True")); + editor.putBoolean("forceTextureFiltering", getConfig("gfx_opengl.ini", "Enhancements", "ForceFiltering", "False").equals("True")); + editor.putBoolean("disableFog", getConfig("gfx_opengl.ini", "Settings", "DisableFog", "False").equals("True")); + editor.putBoolean("skipEFBAccess", getConfig("gfx_opengl.ini", "Hacks", "EFBAccessEnable", "False").equals("True")); + editor.putBoolean("ignoreFormatChanges", getConfig("gfx_opengl.ini", "Hacks", "EFBEmulateFormatChanges", "False").equals("False")); + + String efbCopyOn = getConfig("gfx_opengl.ini", "Hacks", "EFBCopyEnable", "False"); + String efbToTexture = getConfig("gfx_opengl.ini", "Hacks", "EFBToTextureEnable", "False"); + String efbCopyCache = getConfig("gfx_opengl.ini", "Hacks", "EFBCopyCacheEnable", "False"); + + if (efbCopyOn.equals("False")) + { + editor.putString("efbCopyMethod", "Off"); + } + else if (efbCopyOn.equals("True") && efbToTexture.equals("True")) + { + editor.putString("efbCopyMethod", "Texture"); + } + else if(efbCopyOn.equals("True") && efbToTexture.equals("False") && efbCopyCache.equals("False")) + { + editor.putString("efbCopyMethod", "RAM (uncached)"); + } + else if(efbCopyOn.equals("True") && efbToTexture.equals("False") && efbCopyCache.equals("True")) + { + editor.putString("efbCopyMethod", "RAM (cached)"); + } + + editor.putString("textureCacheAccuracy", getConfig("gfx_opengl.ini", "Settings", "SafeTextureCacheColorSamples", "128")); + + String usingXFB = getConfig("gfx_opengl.ini", "Settings", "UseXFB", "False"); + String usingRealXFB = getConfig("gfx_opengl.ini", "Settings", "UseRealXFB", "False"); + + if (usingXFB.equals("False")) + { + editor.putString("externalFrameBuffer", "Disabled"); + } + else if (usingXFB.equals("True") && usingRealXFB.equals("False")) + { + editor.putString("externalFrameBuffer", "Virtual"); + } + else if (usingXFB.equals("True") && usingRealXFB.equals("True")) + { + editor.putString("externalFrameBuffer", "Real"); + } + + editor.putBoolean("cacheDisplayLists", getConfig("gfx_opengl.ini", "Hacks", "DlistCachingEnable", "False").equals("True")); + editor.putBoolean("disableDestinationAlpha", getConfig("gfx_opengl.ini", "Settings", "DstAlphaPass", "False").equals("True")); + editor.putBoolean("fastDepthCalculation", getConfig("gfx_opengl.ini", "Settings", "FastDepthCalc", "True").equals("True")); + + // Apply the changes. + editor.commit(); + } + + // Small utility method that shortens calls to NativeLibrary.GetConfig. + private static String getConfig(String ini, String section, String key, String defaultValue) + { + return NativeLibrary.GetConfig(ini, section, key, defaultValue); + } + + /** + * Writes the config to the Dolphin ini file. + * + * @param ctx The context used to retrieve the user settings. + * */ + public static void SaveConfigToDolphinIni(Context ctx) + { + SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(ctx); + + // Whether or not the user is using dual core. + boolean isUsingDualCore = prefs.getBoolean("dualCorePref", true); + + // Current CPU core being used. Falls back to interpreter upon error. + String currentEmuCore = prefs.getString("cpuCorePref", "0"); + + // Current video backend being used. Falls back to software rendering upon error. + String currentVideoBackend = prefs.getString("gpuPref", "Software Rendering"); + + // Whether or not to ignore all EFB access requests from the CPU. + boolean skipEFBAccess = prefs.getBoolean("skipEFBAccess", false); + + // Whether or not to ignore changes to the EFB format. + boolean ignoreFormatChanges = prefs.getBoolean("ignoreFormatChanges", false); + + // EFB copy method to use. + String efbCopyMethod = prefs.getString("efbCopyMethod", "Off"); + + // Texture cache accuracy. Falls back to "Fast" up error. + String textureCacheAccuracy = prefs.getString("textureCacheAccuracy", "128"); + + // External frame buffer emulation. Falls back to disabled upon error. + String externalFrameBuffer = prefs.getString("externalFrameBuffer", "Disabled"); + + // Whether or not display list caching is enabled. + boolean dlistCachingEnabled = prefs.getBoolean("cacheDisplayLists", false); + + // Whether or not to disable destination alpha. + boolean disableDstAlphaPass = prefs.getBoolean("disableDestinationAlpha", false); + + // Whether or not to use fast depth calculation. + boolean useFastDepthCalc = prefs.getBoolean("fastDepthCalculation", true); + + // Internal resolution. Falls back to 1x Native upon error. + String internalResolution = prefs.getString("internalResolution", "2"); + + // Anisotropic Filtering Level. Falls back to 1x upon error. + String anisotropicFiltLevel = prefs.getString("anisotropicFiltering", "0"); + + // Whether or not Scaled EFB copies are used. + boolean usingScaledEFBCopy = prefs.getBoolean("scaledEFBCopy", true); + + // Whether or not per-pixel lighting is used. + boolean usingPerPixelLighting = prefs.getBoolean("perPixelLighting", false); + + // Whether or not texture filtering is being forced. + boolean isForcingTextureFiltering = prefs.getBoolean("forceTextureFiltering", false); + + // Whether or not fog is disabled. + boolean fogIsDisabled = prefs.getBoolean("disableFog", false); + + + // CPU related Settings + NativeLibrary.SetConfig("Dolphin.ini", "Core", "CPUCore", currentEmuCore); + NativeLibrary.SetConfig("Dolphin.ini", "Core", "CPUThread", isUsingDualCore ? "True" : "False"); + + // General Video Settings + NativeLibrary.SetConfig("Dolphin.ini", "Core", "GFXBackend", currentVideoBackend); + + // Video Hack Settings + NativeLibrary.SetConfig("gfx_opengl.ini", "Hacks", "EFBAccessEnable", skipEFBAccess ? "False" : "True"); + NativeLibrary.SetConfig("gfx_opengl.ini", "Hacks", "EFBEmulateFormatChanges", ignoreFormatChanges ? "True" : "False"); + + // Set EFB Copy Method + if (efbCopyMethod.equals("Off")) + { + NativeLibrary.SetConfig("gfx_opengl.ini", "Hacks", "EFBCopyEnable", "False"); + } + else if (efbCopyMethod.equals("Texture")) + { + NativeLibrary.SetConfig("gfx_opengl.ini", "Hacks", "EFBCopyEnable", "True"); + NativeLibrary.SetConfig("gfx_opengl.ini", "Hacks", "EFBToTextureEnable", "True"); + } + else if (efbCopyMethod.equals("RAM (uncached)")) + { + NativeLibrary.SetConfig("gfx_opengl.ini", "Hacks", "EFBCopyEnable", "True"); + NativeLibrary.SetConfig("gfx_opengl.ini", "Hacks", "EFBToTextureEnable", "False"); + NativeLibrary.SetConfig("gfx_opengl.ini", "Hacks", "EFBCopyCacheEnable", "False"); + } + else if (efbCopyMethod.equals("RAM (cached)")) + { + NativeLibrary.SetConfig("gfx_opengl.ini", "Hacks", "EFBCopyEnable", "True"); + NativeLibrary.SetConfig("gfx_opengl.ini", "Hacks", "EFBToTextureEnable", "False"); + NativeLibrary.SetConfig("gfx_opengl.ini", "Hacks", "EFBCopyCacheEnable", "True"); + } + + // Set texture cache accuracy + NativeLibrary.SetConfig("gfx_opengl.ini", "Settings", "SafeTextureCacheColorSamples", textureCacheAccuracy); + + // Set external frame buffer. + if (externalFrameBuffer.equals("Disabled")) + { + NativeLibrary.SetConfig("gfx_opengl.ini", "Settings", "UseXFB", "False"); + } + else if (externalFrameBuffer.equals("Virtual")) + { + NativeLibrary.SetConfig("gfx_opengl.ini", "Settings", "UseXFB", "True"); + NativeLibrary.SetConfig("gfx_opengl.ini", "Settings", "UseRealXFB", "False"); + } + else if (externalFrameBuffer.equals("Real")) + { + NativeLibrary.SetConfig("gfx_opengl.ini", "Settings", "UseXFB", "True"); + NativeLibrary.SetConfig("gfx_opengl.ini", "Settings", "UseRealXFB", "True"); + } + + NativeLibrary.SetConfig("gfx_opengl.ini", "Hacks", "DlistCachingEnable", dlistCachingEnabled ? "True" : "False"); + NativeLibrary.SetConfig("gfx_opengl.ini", "Settings", "DstAlphaPass", disableDstAlphaPass ? "True" : "False"); + NativeLibrary.SetConfig("gfx_opengl.ini", "Settings", "FastDepthCalc", useFastDepthCalc ? "True" : "False"); + + //-- Enhancement Settings --// + NativeLibrary.SetConfig("gfx_opengl.ini", "Settings", "EFBScale", internalResolution); + NativeLibrary.SetConfig("gfx_opengl.ini", "Enhancements", "MaxAnisotropy", anisotropicFiltLevel); + NativeLibrary.SetConfig("gfx_opengl.ini", "Hacks", "EFBScaledCopy", usingScaledEFBCopy ? "True" : "False"); + NativeLibrary.SetConfig("gfx_opengl.ini", "Settings", "EnablePixelLighting", usingPerPixelLighting ? "True" : "False"); + NativeLibrary.SetConfig("gfx_opengl.ini", "Enhancements", "ForceFiltering", isForcingTextureFiltering ? "True" : "False"); + NativeLibrary.SetConfig("gfx_opengl.ini", "Settings", "DisableFog", fogIsDisabled ? "True" : "False"); + } +} diff --git a/Source/Android/src/org/dolphinemu/dolphinemu/settings/VideoSettingsFragment.java b/Source/Android/src/org/dolphinemu/dolphinemu/settings/VideoSettingsFragment.java new file mode 100644 index 0000000000..fcb04134ad --- /dev/null +++ b/Source/Android/src/org/dolphinemu/dolphinemu/settings/VideoSettingsFragment.java @@ -0,0 +1,202 @@ +/** + * Copyright 2013 Dolphin Emulator Project + * Licensed under GPLv2 + * Refer to the license.txt file included. + */ + +package org.dolphinemu.dolphinemu.settings; + +import javax.microedition.khronos.egl.EGL10; +import javax.microedition.khronos.egl.EGLConfig; +import javax.microedition.khronos.egl.EGLContext; +import javax.microedition.khronos.egl.EGLDisplay; +import javax.microedition.khronos.egl.EGLSurface; +import javax.microedition.khronos.opengles.GL10; + +import org.dolphinemu.dolphinemu.R; + +import android.app.Activity; +import android.os.Bundle; +import android.preference.ListPreference; +import android.preference.PreferenceFragment; + +/** + * Responsible for handling the loading of the video preferences. + */ +public final class VideoSettingsFragment extends PreferenceFragment +{ + private Activity m_activity; + + static public class VersionCheck + { + EGL10 mEGL; + EGLDisplay mEGLDisplay; + EGLConfig[] mEGLConfigs; + EGLConfig mEGLConfig; + EGLContext mEGLContext; + EGLSurface mEGLSurface; + GL10 mGL; + + String mThreadOwner; + + public VersionCheck() + { + int[] version = new int[2]; + int[] attribList = new int[] { + EGL10.EGL_WIDTH, 1, + EGL10.EGL_HEIGHT, 1, + EGL10.EGL_RENDERABLE_TYPE, 4, + EGL10.EGL_NONE + }; + int EGL_CONTEXT_CLIENT_VERSION = 0x3098; + int[] ctx_attribs = new int[] { + EGL_CONTEXT_CLIENT_VERSION, 2, + EGL10.EGL_NONE + }; + + // No error checking performed, minimum required code to elucidate logic + mEGL = (EGL10) EGLContext.getEGL(); + mEGLDisplay = mEGL.eglGetDisplay(EGL10.EGL_DEFAULT_DISPLAY); + mEGL.eglInitialize(mEGLDisplay, version); + mEGLConfig = chooseConfig(); // Choosing a config is a little more complicated + mEGLContext = mEGL.eglCreateContext(mEGLDisplay, mEGLConfig, EGL10.EGL_NO_CONTEXT, ctx_attribs); + mEGLSurface = mEGL.eglCreatePbufferSurface(mEGLDisplay, mEGLConfig, attribList); + mEGL.eglMakeCurrent(mEGLDisplay, mEGLSurface, mEGLSurface, mEGLContext); + mGL = (GL10) mEGLContext.getGL(); + + // Record thread owner of OpenGL context + mThreadOwner = Thread.currentThread().getName(); + } + + public String getVersion() + { + return mGL.glGetString(GL10.GL_VERSION); + } + + public String getVendor() + { + return mGL.glGetString(GL10.GL_VENDOR); + } + + public String getRenderer() + { + return mGL.glGetString(GL10.GL_RENDERER); + } + + private EGLConfig chooseConfig() + { + int[] attribList = new int[] { + EGL10.EGL_DEPTH_SIZE, 0, + EGL10.EGL_STENCIL_SIZE, 0, + EGL10.EGL_RED_SIZE, 8, + EGL10.EGL_GREEN_SIZE, 8, + EGL10.EGL_BLUE_SIZE, 8, + EGL10.EGL_ALPHA_SIZE, 8, + EGL10.EGL_NONE + }; + + // No error checking performed, minimum required code to elucidate logic + // Expand on this logic to be more selective in choosing a configuration + int[] numConfig = new int[1]; + mEGL.eglChooseConfig(mEGLDisplay, attribList, null, 0, numConfig); + int configSize = numConfig[0]; + mEGLConfigs = new EGLConfig[configSize]; + mEGL.eglChooseConfig(mEGLDisplay, attribList, mEGLConfigs, configSize, numConfig); + + return mEGLConfigs[0]; // Best match is probably the first configuration + } + } + + static public boolean SupportsGLES3() + { + VersionCheck mbuffer = new VersionCheck(); + String m_GLVersion = mbuffer.getVersion(); + String m_GLVendor = mbuffer.getVendor(); + String m_GLRenderer = mbuffer.getRenderer(); + + boolean mSupportsGLES3 = false; + + // Check for OpenGL ES 3 support (General case). + if (m_GLVersion != null && (m_GLVersion.contains("OpenGL ES 3.0") || m_GLVersion.equals("OpenGL ES 3.0"))) + mSupportsGLES3 = true; + + // Checking for OpenGL ES 3 support for certain Qualcomm devices. + if (!mSupportsGLES3 && m_GLVendor != null && m_GLVendor.equals("Qualcomm")) + { + if (m_GLRenderer.contains("Adreno (TM) 3")) + { + int mVStart = m_GLVersion.indexOf("V@") + 2; + int mVEnd = 0; + float mVersion; + + for (int a = mVStart; a < m_GLVersion.length(); ++a) + { + if (m_GLVersion.charAt(a) == ' ') + { + mVEnd = a; + break; + } + } + + mVersion = Float.parseFloat(m_GLVersion.substring(mVStart, mVEnd)); + + if (mVersion >= 14.0f) + mSupportsGLES3 = true; + } + } + return mSupportsGLES3; + } + + @Override + public void onCreate(Bundle savedInstanceState) + { + super.onCreate(savedInstanceState); + + // Load the preferences from an XML resource + addPreferencesFromResource(R.xml.video_prefs); + + // + // Setting valid video backends. + // + final ListPreference videoBackends = (ListPreference) findPreference("gpuPref"); + final boolean deviceSupportsGLES3 = SupportsGLES3(); + + if (deviceSupportsGLES3) + { + videoBackends.setEntries(R.array.videoBackendEntriesGLES3); + videoBackends.setEntryValues(R.array.videoBackendValuesGLES3); + } + else + { + videoBackends.setEntries(R.array.videoBackendEntriesNoGLES3); + videoBackends.setEntryValues(R.array.videoBackendValuesNoGLES3); + } + } + + @Override + public void onAttach(Activity activity) + { + super.onAttach(activity); + + // This makes sure that the container activity has implemented + // the callback interface. If not, it throws an exception + try + { + m_activity = activity; + } + catch (ClassCastException e) + { + throw new ClassCastException(activity.toString() + + " must implement OnGameListZeroListener"); + } + } + + @Override + public void onDestroy() + { + super.onDestroy(); + + // When the fragment is done being used, save the settings to the Dolphin ini file. + UserPreferences.SaveConfigToDolphinIni(m_activity); + } +} diff --git a/Source/Android/src/org/dolphinemu/dolphinemu/sidemenu/SideMenuAdapter.java b/Source/Android/src/org/dolphinemu/dolphinemu/sidemenu/SideMenuAdapter.java new file mode 100644 index 0000000000..4d4816e355 --- /dev/null +++ b/Source/Android/src/org/dolphinemu/dolphinemu/sidemenu/SideMenuAdapter.java @@ -0,0 +1,55 @@ +package org.dolphinemu.dolphinemu.sidemenu; + +import android.content.Context; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ArrayAdapter; +import android.widget.TextView; + +import java.util.List; + +import org.dolphinemu.dolphinemu.R; + +public final class SideMenuAdapter extends ArrayAdapter +{ + private final Context c; + private final int id; + private final Listitems; + + public SideMenuAdapter(Context context, int textViewResourceId, List objects) + { + super(context, textViewResourceId, objects); + c = context; + id = textViewResourceId; + items = objects; + } + + public SideMenuItem getItem(int i) + { + return items.get(i); + } + + @Override + public View getView(int position, View convertView, ViewGroup parent) + { + View v = convertView; + if (v == null) + { + LayoutInflater vi = (LayoutInflater)c.getSystemService(Context.LAYOUT_INFLATER_SERVICE); + v = vi.inflate(id, null); + } + + final SideMenuItem item = items.get(position); + if (item != null) + { + TextView title = (TextView) v.findViewById(R.id.SideMenuTitle); + + if(title != null) + title.setText(item.getName()); + } + + return v; + } +} + diff --git a/Source/Android/src/org/dolphinemu/dolphinemu/sidemenu/SideMenuItem.java b/Source/Android/src/org/dolphinemu/dolphinemu/sidemenu/SideMenuItem.java new file mode 100644 index 0000000000..2b780dcbb2 --- /dev/null +++ b/Source/Android/src/org/dolphinemu/dolphinemu/sidemenu/SideMenuItem.java @@ -0,0 +1,58 @@ +/* + * Copyright 2013 Dolphin Emulator Project + * Licensed under GPLv2 + * Refer to the license.txt file included. + */ + +package org.dolphinemu.dolphinemu.sidemenu; + + +/** + * Represents an item that goes in the sidemenu of the app. + */ +public final class SideMenuItem implements Comparable +{ + private final String m_name; + private final int m_id; + + /** + * Constructor + * + * @param name The name of the SideMenuItem. + * @param id ID number of this specific SideMenuItem. + */ + public SideMenuItem(String name, int id) + { + m_name = name; + m_id = id; + } + + /** + * Gets the name of this SideMenuItem. + * + * @return the name of this SideMenuItem. + */ + public String getName() + { + return m_name; + } + + /** + * Gets the ID of this SideMenuItem. + * + * @return the ID of this SideMenuItem. + */ + public int getID() + { + return m_id; + } + + public int compareTo(SideMenuItem o) + { + if(this.m_name != null) + return this.m_name.toLowerCase().compareTo(o.getName().toLowerCase()); + else + throw new IllegalArgumentException(); + } +} + -- cgit v1.2.3