Android: Support Post Processing Shaders

This commit is contained in:
mahdihijazi 2018-01-28 01:51:42 +01:00
parent b4bb213ffd
commit b924445e48
7 changed files with 204 additions and 6 deletions

View File

@ -17,6 +17,7 @@ public abstract class SettingsItem
public static final int TYPE_SLIDER = 3; public static final int TYPE_SLIDER = 3;
public static final int TYPE_SUBMENU = 4; public static final int TYPE_SUBMENU = 4;
public static final int TYPE_INPUT_BINDING = 5; public static final int TYPE_INPUT_BINDING = 5;
public static final int TYPE_STRING_SINGLE_CHOICE = 6;
private String mKey; private String mKey;
private String mSection; private String mSection;

View File

@ -0,0 +1,97 @@
package org.dolphinemu.dolphinemu.model.settings.view;
import org.dolphinemu.dolphinemu.model.settings.Setting;
import org.dolphinemu.dolphinemu.model.settings.StringSetting;
public class StringSingleChoiceSetting extends SettingsItem
{
private String mDefaultValue;
private String[] mChoicesId;
private String[] mValuesId;
public StringSingleChoiceSetting(String key, String section, int file, int titleId, int descriptionId, String[] choicesId, String[] valuesId, String defaultValue, Setting setting)
{
super(key, section, file, setting, titleId, descriptionId);
mValuesId = valuesId;
mChoicesId = choicesId;
mDefaultValue = defaultValue;
}
public String[] getChoicesId()
{
return mChoicesId;
}
public String[] getValuesId()
{
return mValuesId;
}
public String getValueAt(int index)
{
if (mValuesId == null)
return null;
if (index >= 0 && index < mValuesId.length)
{
return mValuesId[index];
}
return "";
}
public String getSelectedValue()
{
if (getSetting() != null)
{
StringSetting setting = (StringSetting) getSetting();
return setting.getValue();
}
else
{
return mDefaultValue;
}
}
public int getSelectValueIndex() {
String selectedValue = getSelectedValue();
for(int i=0;i<mValuesId.length;i++) {
if(mValuesId[i].equals(selectedValue)) {
return i;
}
}
return -1;
}
/**
* Write a value to the backing int. If that int was previously null,
* initializes a new one and returns it, so it can be added to the Hashmap.
*
* @param selection New value of the int.
* @return null if overwritten successfully otherwise; a newly created IntSetting.
*/
public StringSetting setSelectedValue(String selection)
{
if (getSetting() == null)
{
StringSetting setting = new StringSetting(getKey(), getSection(), getFile(), selection);
setSetting(setting);
return setting;
}
else
{
StringSetting setting = (StringSetting) getSetting();
setting.setValue(selection);
return null;
}
}
@Override
public int getType()
{
return TYPE_STRING_SINGLE_CHOICE;
}
}

View File

@ -37,6 +37,7 @@ public final class DirectoryInitializationService extends IntentService
public static final String EXTRA_STATE = "directoryState"; public static final String EXTRA_STATE = "directoryState";
private static volatile DirectoryInitializationState directoryState = null; private static volatile DirectoryInitializationState directoryState = null;
private static String userPath; private static String userPath;
private static String internalPath;
private static AtomicBoolean isDolphinDirectoryInitializationRunning = new AtomicBoolean(false); private static AtomicBoolean isDolphinDirectoryInitializationRunning = new AtomicBoolean(false);
public enum DirectoryInitializationState public enum DirectoryInitializationState
@ -110,6 +111,7 @@ public final class DirectoryInitializationService extends IntentService
private void initializeInternalStorage() private void initializeInternalStorage()
{ {
File sysDirectory = new File(getFilesDir(), "Sys"); File sysDirectory = new File(getFilesDir(), "Sys");
internalPath = sysDirectory.getAbsolutePath();
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(this); SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(this);
String revision = NativeLibrary.GetGitRevision(); String revision = NativeLibrary.GetGitRevision();
@ -177,6 +179,20 @@ public final class DirectoryInitializationService extends IntentService
} }
public static String getDolphinInternalDirectory()
{
if (directoryState == null)
{
throw new IllegalStateException("DirectoryInitializationService has to run at least once!");
}
else if (isDolphinDirectoryInitializationRunning.get())
{
throw new IllegalStateException("DirectoryInitializationService has to finish running first!");
}
return internalPath;
}
private void sendBroadcastState(DirectoryInitializationState state) private void sendBroadcastState(DirectoryInitializationState state)
{ {
Intent localIntent = Intent localIntent =

View File

@ -23,6 +23,7 @@ import org.dolphinemu.dolphinemu.model.settings.view.InputBindingSetting;
import org.dolphinemu.dolphinemu.model.settings.view.SettingsItem; import org.dolphinemu.dolphinemu.model.settings.view.SettingsItem;
import org.dolphinemu.dolphinemu.model.settings.view.SingleChoiceSetting; import org.dolphinemu.dolphinemu.model.settings.view.SingleChoiceSetting;
import org.dolphinemu.dolphinemu.model.settings.view.SliderSetting; import org.dolphinemu.dolphinemu.model.settings.view.SliderSetting;
import org.dolphinemu.dolphinemu.model.settings.view.StringSingleChoiceSetting;
import org.dolphinemu.dolphinemu.model.settings.view.SubmenuSetting; import org.dolphinemu.dolphinemu.model.settings.view.SubmenuSetting;
import org.dolphinemu.dolphinemu.ui.settings.viewholder.CheckBoxSettingViewHolder; import org.dolphinemu.dolphinemu.ui.settings.viewholder.CheckBoxSettingViewHolder;
import org.dolphinemu.dolphinemu.ui.settings.viewholder.HeaderViewHolder; import org.dolphinemu.dolphinemu.ui.settings.viewholder.HeaderViewHolder;
@ -71,6 +72,7 @@ public final class SettingsAdapter extends RecyclerView.Adapter<SettingViewHolde
view = inflater.inflate(R.layout.list_item_setting_checkbox, parent, false); view = inflater.inflate(R.layout.list_item_setting_checkbox, parent, false);
return new CheckBoxSettingViewHolder(view, this); return new CheckBoxSettingViewHolder(view, this);
case SettingsItem.TYPE_STRING_SINGLE_CHOICE:
case SettingsItem.TYPE_SINGLE_CHOICE: case SettingsItem.TYPE_SINGLE_CHOICE:
view = inflater.inflate(R.layout.list_item_setting, parent, false); view = inflater.inflate(R.layout.list_item_setting, parent, false);
return new SingleChoiceViewHolder(view, this); return new SingleChoiceViewHolder(view, this);
@ -161,6 +163,18 @@ public final class SettingsAdapter extends RecyclerView.Adapter<SettingViewHolde
mDialog = builder.show(); mDialog = builder.show();
} }
public void onStringSingleChoiceClick(StringSingleChoiceSetting item)
{
mClickedItem = item;
AlertDialog.Builder builder = new AlertDialog.Builder(mView.getActivity());
builder.setTitle(item.getNameId());
builder.setSingleChoiceItems(item.getChoicesId(), item.getSelectValueIndex(), this);
mDialog = builder.show();
}
public void onSliderClick(SliderSetting item) public void onSliderClick(SliderSetting item)
{ {
mClickedItem = item; mClickedItem = item;
@ -274,6 +288,18 @@ public final class SettingsAdapter extends RecyclerView.Adapter<SettingViewHolde
closeDialog(); closeDialog();
} }
else if (mClickedItem instanceof StringSingleChoiceSetting)
{
StringSingleChoiceSetting scSetting = (StringSingleChoiceSetting) mClickedItem;
String value = scSetting.getValueAt(which);
StringSetting setting = scSetting.setSelectedValue(value);
if (setting != null)
{
mView.putSetting(setting);
}
closeDialog();
}
else if (mClickedItem instanceof SliderSetting) else if (mClickedItem instanceof SliderSetting)
{ {
SliderSetting sliderSetting = (SliderSetting) mClickedItem; SliderSetting sliderSetting = (SliderSetting) mClickedItem;

View File

@ -17,10 +17,14 @@ import org.dolphinemu.dolphinemu.model.settings.view.InputBindingSetting;
import org.dolphinemu.dolphinemu.model.settings.view.SettingsItem; import org.dolphinemu.dolphinemu.model.settings.view.SettingsItem;
import org.dolphinemu.dolphinemu.model.settings.view.SingleChoiceSetting; import org.dolphinemu.dolphinemu.model.settings.view.SingleChoiceSetting;
import org.dolphinemu.dolphinemu.model.settings.view.SliderSetting; import org.dolphinemu.dolphinemu.model.settings.view.SliderSetting;
import org.dolphinemu.dolphinemu.model.settings.view.StringSingleChoiceSetting;
import org.dolphinemu.dolphinemu.model.settings.view.SubmenuSetting; import org.dolphinemu.dolphinemu.model.settings.view.SubmenuSetting;
import org.dolphinemu.dolphinemu.services.DirectoryInitializationService;
import org.dolphinemu.dolphinemu.utils.EGLHelper; import org.dolphinemu.dolphinemu.utils.EGLHelper;
import org.dolphinemu.dolphinemu.utils.Log;
import org.dolphinemu.dolphinemu.utils.SettingsFile; import org.dolphinemu.dolphinemu.utils.SettingsFile;
import java.io.File;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
@ -330,6 +334,7 @@ public final class SettingsFragmentPresenter
Setting resolution = mSettings.get(SettingsFile.SETTINGS_GFX).get(SettingsFile.SECTION_GFX_SETTINGS).getSetting(SettingsFile.KEY_INTERNAL_RES); Setting resolution = mSettings.get(SettingsFile.SETTINGS_GFX).get(SettingsFile.SECTION_GFX_SETTINGS).getSetting(SettingsFile.KEY_INTERNAL_RES);
Setting fsaa = mSettings.get(SettingsFile.SETTINGS_GFX).get(SettingsFile.SECTION_GFX_SETTINGS).getSetting(SettingsFile.KEY_FSAA); Setting fsaa = mSettings.get(SettingsFile.SETTINGS_GFX).get(SettingsFile.SECTION_GFX_SETTINGS).getSetting(SettingsFile.KEY_FSAA);
Setting anisotropic = mSettings.get(SettingsFile.SETTINGS_GFX).get(SettingsFile.SECTION_GFX_ENHANCEMENTS).getSetting(SettingsFile.KEY_ANISOTROPY); Setting anisotropic = mSettings.get(SettingsFile.SETTINGS_GFX).get(SettingsFile.SECTION_GFX_ENHANCEMENTS).getSetting(SettingsFile.KEY_ANISOTROPY);
Setting shader = mSettings.get(SettingsFile.SETTINGS_GFX).get(SettingsFile.SECTION_GFX_ENHANCEMENTS).getSetting(SettingsFile.KEY_POST_SHADER);
Setting efbScaledCopy = mSettings.get(SettingsFile.SETTINGS_GFX).get(SettingsFile.SECTION_GFX_HACKS).getSetting(SettingsFile.KEY_SCALED_EFB); Setting efbScaledCopy = mSettings.get(SettingsFile.SETTINGS_GFX).get(SettingsFile.SECTION_GFX_HACKS).getSetting(SettingsFile.KEY_SCALED_EFB);
Setting perPixel = mSettings.get(SettingsFile.SETTINGS_GFX).get(SettingsFile.SECTION_GFX_SETTINGS).getSetting(SettingsFile.KEY_PER_PIXEL); Setting perPixel = mSettings.get(SettingsFile.SETTINGS_GFX).get(SettingsFile.SECTION_GFX_SETTINGS).getSetting(SettingsFile.KEY_PER_PIXEL);
Setting forceFilter = mSettings.get(SettingsFile.SETTINGS_GFX).get(SettingsFile.SECTION_GFX_ENHANCEMENTS).getSetting(SettingsFile.KEY_FORCE_FILTERING); Setting forceFilter = mSettings.get(SettingsFile.SETTINGS_GFX).get(SettingsFile.SECTION_GFX_ENHANCEMENTS).getSetting(SettingsFile.KEY_FORCE_FILTERING);
@ -341,9 +346,14 @@ public final class SettingsFragmentPresenter
sl.add(new SingleChoiceSetting(SettingsFile.KEY_FSAA, SettingsFile.SECTION_GFX_SETTINGS, SettingsFile.SETTINGS_GFX, R.string.FSAA, R.string.FSAA_description, R.array.FSAAEntries, R.array.FSAAValues, 0, fsaa)); sl.add(new SingleChoiceSetting(SettingsFile.KEY_FSAA, SettingsFile.SECTION_GFX_SETTINGS, SettingsFile.SETTINGS_GFX, R.string.FSAA, R.string.FSAA_description, R.array.FSAAEntries, R.array.FSAAValues, 0, fsaa));
sl.add(new SingleChoiceSetting(SettingsFile.KEY_ANISOTROPY, SettingsFile.SECTION_GFX_ENHANCEMENTS, SettingsFile.SETTINGS_GFX, R.string.anisotropic_filtering, R.string.anisotropic_filtering_description, R.array.anisotropicFilteringEntries, R.array.anisotropicFilteringValues, 0, anisotropic)); sl.add(new SingleChoiceSetting(SettingsFile.KEY_ANISOTROPY, SettingsFile.SECTION_GFX_ENHANCEMENTS, SettingsFile.SETTINGS_GFX, R.string.anisotropic_filtering, R.string.anisotropic_filtering_description, R.array.anisotropicFilteringEntries, R.array.anisotropicFilteringValues, 0, anisotropic));
// TODO IntSetting stereoModeValue = (IntSetting) mSettings.get(SettingsFile.SETTINGS_GFX).get(SettingsFile.SECTION_STEREOSCOPY).getSetting(SettingsFile.KEY_STEREO_MODE);
// Setting shader = mSettings.get(SettingsFile.SETTINGS_GFX).get(SettingsFile.SECTION_GFX_ENHANCEMENTS).getSetting(SettingsFile.KEY_POST_SHADER) int anaglyphMode = 3;
// sl.add(new SingleChoiceSetting(.getKey(), , R.string., R.string._description, R.array., R.array.)); String subDir = stereoModeValue != null && stereoModeValue.getValue() == anaglyphMode ? "Anaglyph" : null;
String[] shaderListEntries = getShaderList(subDir);
String[] shaderListValues = new String[shaderListEntries.length];
System.arraycopy(shaderListEntries, 0, shaderListValues, 0, shaderListEntries.length);
shaderListValues[0] = "";
sl.add(new StringSingleChoiceSetting(SettingsFile.KEY_POST_SHADER, SettingsFile.SECTION_GFX_ENHANCEMENTS, SettingsFile.SETTINGS_GFX, R.string.post_processing_shader, R.string.post_processing_shader_description, shaderListEntries, shaderListValues, "", shader));
sl.add(new CheckBoxSetting(SettingsFile.KEY_SCALED_EFB, SettingsFile.SECTION_GFX_HACKS, SettingsFile.SETTINGS_GFX, R.string.scaled_efb_copy, R.string.scaled_efb_copy_description, true, efbScaledCopy)); sl.add(new CheckBoxSetting(SettingsFile.KEY_SCALED_EFB, SettingsFile.SECTION_GFX_HACKS, SettingsFile.SETTINGS_GFX, R.string.scaled_efb_copy, R.string.scaled_efb_copy_description, true, efbScaledCopy));
sl.add(new CheckBoxSetting(SettingsFile.KEY_PER_PIXEL, SettingsFile.SECTION_GFX_SETTINGS, SettingsFile.SETTINGS_GFX, R.string.per_pixel_lighting, R.string.per_pixel_lighting_description, false, perPixel)); sl.add(new CheckBoxSetting(SettingsFile.KEY_PER_PIXEL, SettingsFile.SECTION_GFX_SETTINGS, SettingsFile.SETTINGS_GFX, R.string.per_pixel_lighting, R.string.per_pixel_lighting_description, false, perPixel));
@ -366,6 +376,44 @@ public final class SettingsFragmentPresenter
} }
} }
private String[] getShaderList(String subDir)
{
try
{
String shadersPath = DirectoryInitializationService.getDolphinInternalDirectory() + "/Shaders";
if(!TextUtils.isEmpty(subDir)) {
shadersPath += "/" + subDir;
}
File file = new File(shadersPath);
File[] shaderFiles = file.listFiles();
if (shaderFiles != null)
{
String[] result = new String[shaderFiles.length + 1];
result[0] = "Off";
for (int i = 0; i < shaderFiles.length; i++)
{
String name = shaderFiles[i].getName();
int extensionIndex = name.indexOf(".glsl");
if (extensionIndex > 0)
{
name = name.substring(0, extensionIndex);
}
result[i+1] = name;
}
return result;
}
}
catch (Exception ex)
{
Log.debug("[Settings] Unable to find shader files");
// return empty list
}
return new String[]{};
}
private void addHackSettings(ArrayList<SettingsItem> sl) private void addHackSettings(ArrayList<SettingsItem> sl)
{ {
boolean skipEFBValue = getInvertedBooleanValue(SettingsFile.SETTINGS_GFX, SettingsFile.SECTION_GFX_HACKS, SettingsFile.KEY_SKIP_EFB, false); boolean skipEFBValue = getInvertedBooleanValue(SettingsFile.SETTINGS_GFX, SettingsFile.SECTION_GFX_HACKS, SettingsFile.KEY_SKIP_EFB, false);

View File

@ -6,11 +6,12 @@ import android.widget.TextView;
import org.dolphinemu.dolphinemu.R; import org.dolphinemu.dolphinemu.R;
import org.dolphinemu.dolphinemu.model.settings.view.SettingsItem; import org.dolphinemu.dolphinemu.model.settings.view.SettingsItem;
import org.dolphinemu.dolphinemu.model.settings.view.SingleChoiceSetting; import org.dolphinemu.dolphinemu.model.settings.view.SingleChoiceSetting;
import org.dolphinemu.dolphinemu.model.settings.view.StringSingleChoiceSetting;
import org.dolphinemu.dolphinemu.ui.settings.SettingsAdapter; import org.dolphinemu.dolphinemu.ui.settings.SettingsAdapter;
public final class SingleChoiceViewHolder extends SettingViewHolder public final class SingleChoiceViewHolder extends SettingViewHolder
{ {
private SingleChoiceSetting mItem; private SettingsItem mItem;
private TextView mTextSettingName; private TextView mTextSettingName;
private TextView mTextSettingDescription; private TextView mTextSettingDescription;
@ -30,7 +31,7 @@ public final class SingleChoiceViewHolder extends SettingViewHolder
@Override @Override
public void bind(SettingsItem item) public void bind(SettingsItem item)
{ {
mItem = (SingleChoiceSetting) item; mItem = item;
mTextSettingName.setText(item.getNameId()); mTextSettingName.setText(item.getNameId());
@ -43,6 +44,13 @@ public final class SingleChoiceViewHolder extends SettingViewHolder
@Override @Override
public void onClick(View clicked) public void onClick(View clicked)
{ {
getAdapter().onSingleChoiceClick(mItem); if (mItem instanceof SingleChoiceSetting)
{
getAdapter().onSingleChoiceClick((SingleChoiceSetting) mItem);
}
else if (mItem instanceof StringSingleChoiceSetting)
{
getAdapter().onStringSingleChoiceClick((StringSingleChoiceSetting) mItem);
}
} }
} }

View File

@ -152,6 +152,8 @@
<string name="FSAA_description">Reduces the amount of aliasing caused by rasterizing 3D graphics. This makes the rendered picture look less blocky. Heavily decreases emulation speed and sometimes causes issues.</string> <string name="FSAA_description">Reduces the amount of aliasing caused by rasterizing 3D graphics. This makes the rendered picture look less blocky. Heavily decreases emulation speed and sometimes causes issues.</string>
<string name="anisotropic_filtering">Anisotropic Filtering</string> <string name="anisotropic_filtering">Anisotropic Filtering</string>
<string name="anisotropic_filtering_description">Enhances visual quality of textures that are at oblique viewing angles. Might cause issues in a small number of games.</string> <string name="anisotropic_filtering_description">Enhances visual quality of textures that are at oblique viewing angles. Might cause issues in a small number of games.</string>
<string name="post_processing_shader">Post-Processing Effect</string>
<string name="post_processing_shader_description">Apply a post-processing effect after finishing a frame</string>
<string name="postprocessing_shader">Post Processing Shader</string> <string name="postprocessing_shader">Post Processing Shader</string>
<string name="postprocessing_shader_description">Apply a post-processing effect after finishing a frame.</string> <string name="postprocessing_shader_description">Apply a post-processing effect after finishing a frame.</string>
<string name="scaled_efb_copy">Scaled EFB Copy</string> <string name="scaled_efb_copy">Scaled EFB Copy</string>