early-access version 4046
This commit is contained in:
parent
dda8f0dfd5
commit
c3fa970dd5
14 changed files with 87 additions and 48 deletions
|
@ -1,7 +1,7 @@
|
||||||
yuzu emulator early access
|
yuzu emulator early access
|
||||||
=============
|
=============
|
||||||
|
|
||||||
This is the source code for early-access 4045.
|
This is the source code for early-access 4046.
|
||||||
|
|
||||||
## Legal Notice
|
## Legal Notice
|
||||||
|
|
||||||
|
|
|
@ -79,7 +79,18 @@ object Settings {
|
||||||
const val PREF_THEME_MODE = "ThemeMode"
|
const val PREF_THEME_MODE = "ThemeMode"
|
||||||
const val PREF_BLACK_BACKGROUNDS = "BlackBackgrounds"
|
const val PREF_BLACK_BACKGROUNDS = "BlackBackgrounds"
|
||||||
|
|
||||||
const val LayoutOption_Unspecified = 0
|
enum class EmulationOrientation(val int: Int) {
|
||||||
const val LayoutOption_MobilePortrait = 4
|
Unspecified(0),
|
||||||
const val LayoutOption_MobileLandscape = 5
|
SensorLandscape(5),
|
||||||
|
Landscape(1),
|
||||||
|
ReverseLandscape(2),
|
||||||
|
SensorPortrait(6),
|
||||||
|
Portrait(4),
|
||||||
|
ReversePortrait(3);
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
fun from(int: Int): EmulationOrientation =
|
||||||
|
entries.firstOrNull { it.int == int } ?: Unspecified
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -50,6 +50,7 @@ import org.yuzu.yuzu_emu.databinding.FragmentEmulationBinding
|
||||||
import org.yuzu.yuzu_emu.features.settings.model.BooleanSetting
|
import org.yuzu.yuzu_emu.features.settings.model.BooleanSetting
|
||||||
import org.yuzu.yuzu_emu.features.settings.model.IntSetting
|
import org.yuzu.yuzu_emu.features.settings.model.IntSetting
|
||||||
import org.yuzu.yuzu_emu.features.settings.model.Settings
|
import org.yuzu.yuzu_emu.features.settings.model.Settings
|
||||||
|
import org.yuzu.yuzu_emu.features.settings.model.Settings.EmulationOrientation
|
||||||
import org.yuzu.yuzu_emu.features.settings.utils.SettingsFile
|
import org.yuzu.yuzu_emu.features.settings.utils.SettingsFile
|
||||||
import org.yuzu.yuzu_emu.model.DriverViewModel
|
import org.yuzu.yuzu_emu.model.DriverViewModel
|
||||||
import org.yuzu.yuzu_emu.model.Game
|
import org.yuzu.yuzu_emu.model.Game
|
||||||
|
@ -99,6 +100,7 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback {
|
||||||
*/
|
*/
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
|
updateOrientation()
|
||||||
|
|
||||||
val intentUri: Uri? = requireActivity().intent.data
|
val intentUri: Uri? = requireActivity().intent.data
|
||||||
var intentGame: Game? = null
|
var intentGame: Game? = null
|
||||||
|
@ -458,13 +460,23 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback {
|
||||||
@SuppressLint("SourceLockedOrientationActivity")
|
@SuppressLint("SourceLockedOrientationActivity")
|
||||||
private fun updateOrientation() {
|
private fun updateOrientation() {
|
||||||
emulationActivity?.let {
|
emulationActivity?.let {
|
||||||
it.requestedOrientation = when (IntSetting.RENDERER_SCREEN_LAYOUT.getInt()) {
|
val orientationSetting =
|
||||||
Settings.LayoutOption_MobileLandscape ->
|
EmulationOrientation.from(IntSetting.RENDERER_SCREEN_LAYOUT.getInt())
|
||||||
|
it.requestedOrientation = when (orientationSetting) {
|
||||||
|
EmulationOrientation.Unspecified -> ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED
|
||||||
|
EmulationOrientation.SensorLandscape ->
|
||||||
ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE
|
ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE
|
||||||
Settings.LayoutOption_MobilePortrait ->
|
|
||||||
ActivityInfo.SCREEN_ORIENTATION_USER_PORTRAIT
|
EmulationOrientation.Landscape -> ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE
|
||||||
Settings.LayoutOption_Unspecified -> ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED
|
EmulationOrientation.ReverseLandscape ->
|
||||||
else -> ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE
|
ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE
|
||||||
|
|
||||||
|
EmulationOrientation.SensorPortrait ->
|
||||||
|
ActivityInfo.SCREEN_ORIENTATION_SENSOR_PORTRAIT
|
||||||
|
|
||||||
|
EmulationOrientation.Portrait -> ActivityInfo.SCREEN_ORIENTATION_PORTRAIT
|
||||||
|
EmulationOrientation.ReversePortrait ->
|
||||||
|
ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -651,7 +663,7 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback {
|
||||||
@SuppressLint("SourceLockedOrientationActivity")
|
@SuppressLint("SourceLockedOrientationActivity")
|
||||||
private fun startConfiguringControls() {
|
private fun startConfiguringControls() {
|
||||||
// Lock the current orientation to prevent editing inconsistencies
|
// Lock the current orientation to prevent editing inconsistencies
|
||||||
if (IntSetting.RENDERER_SCREEN_LAYOUT.getInt() == Settings.LayoutOption_Unspecified) {
|
if (IntSetting.RENDERER_SCREEN_LAYOUT.getInt() == EmulationOrientation.Unspecified.int) {
|
||||||
emulationActivity?.let {
|
emulationActivity?.let {
|
||||||
it.requestedOrientation =
|
it.requestedOrientation =
|
||||||
if (resources.configuration.orientation == Configuration.ORIENTATION_PORTRAIT) {
|
if (resources.configuration.orientation == Configuration.ORIENTATION_PORTRAIT) {
|
||||||
|
@ -669,7 +681,7 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback {
|
||||||
binding.doneControlConfig.visibility = View.GONE
|
binding.doneControlConfig.visibility = View.GONE
|
||||||
binding.surfaceInputOverlay.setIsInEditMode(false)
|
binding.surfaceInputOverlay.setIsInEditMode(false)
|
||||||
// Unlock the orientation if it was locked for editing
|
// Unlock the orientation if it was locked for editing
|
||||||
if (IntSetting.RENDERER_SCREEN_LAYOUT.getInt() == Settings.LayoutOption_Unspecified) {
|
if (IntSetting.RENDERER_SCREEN_LAYOUT.getInt() == EmulationOrientation.Unspecified.int) {
|
||||||
emulationActivity?.let {
|
emulationActivity?.let {
|
||||||
it.requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED
|
it.requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED
|
||||||
}
|
}
|
||||||
|
|
|
@ -445,7 +445,8 @@ class GamePropertiesFragment : Fragment() {
|
||||||
val zipResult = FileUtil.zipFromInternalStorage(
|
val zipResult = FileUtil.zipFromInternalStorage(
|
||||||
File(saveLocation),
|
File(saveLocation),
|
||||||
saveLocation.replaceAfterLast("/", ""),
|
saveLocation.replaceAfterLast("/", ""),
|
||||||
BufferedOutputStream(requireContext().contentResolver.openOutputStream(result))
|
BufferedOutputStream(requireContext().contentResolver.openOutputStream(result)),
|
||||||
|
compression = false
|
||||||
)
|
)
|
||||||
return@newInstance when (zipResult) {
|
return@newInstance when (zipResult) {
|
||||||
TaskState.Completed -> getString(R.string.export_success)
|
TaskState.Completed -> getString(R.string.export_success)
|
||||||
|
|
|
@ -167,13 +167,14 @@ class GamesViewModel : ViewModel() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun onCloseGameFoldersFragment() =
|
fun onCloseGameFoldersFragment() {
|
||||||
|
NativeConfig.saveGlobalConfig()
|
||||||
viewModelScope.launch {
|
viewModelScope.launch {
|
||||||
withContext(Dispatchers.IO) {
|
withContext(Dispatchers.IO) {
|
||||||
NativeConfig.saveGlobalConfig()
|
|
||||||
getGameDirs(true)
|
getGameDirs(true)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private fun getGameDirs(reloadList: Boolean = false) {
|
private fun getGameDirs(reloadList: Boolean = false) {
|
||||||
val gameDirs = NativeConfig.getGameDirs()
|
val gameDirs = NativeConfig.getGameDirs()
|
||||||
|
|
|
@ -625,7 +625,8 @@ class MainActivity : AppCompatActivity(), ThemeProvider {
|
||||||
File(DirectoryInitialization.userDirectory!!),
|
File(DirectoryInitialization.userDirectory!!),
|
||||||
DirectoryInitialization.userDirectory!!,
|
DirectoryInitialization.userDirectory!!,
|
||||||
BufferedOutputStream(contentResolver.openOutputStream(result)),
|
BufferedOutputStream(contentResolver.openOutputStream(result)),
|
||||||
taskViewModel.cancelled
|
taskViewModel.cancelled,
|
||||||
|
compression = false
|
||||||
)
|
)
|
||||||
return@newInstance when (zipResult) {
|
return@newInstance when (zipResult) {
|
||||||
TaskState.Completed -> getString(R.string.user_data_export_success)
|
TaskState.Completed -> getString(R.string.user_data_export_success)
|
||||||
|
|
|
@ -21,6 +21,7 @@ import org.yuzu.yuzu_emu.model.TaskState
|
||||||
import java.io.BufferedOutputStream
|
import java.io.BufferedOutputStream
|
||||||
import java.lang.NullPointerException
|
import java.lang.NullPointerException
|
||||||
import java.nio.charset.StandardCharsets
|
import java.nio.charset.StandardCharsets
|
||||||
|
import java.util.zip.Deflater
|
||||||
import java.util.zip.ZipOutputStream
|
import java.util.zip.ZipOutputStream
|
||||||
import kotlin.IllegalStateException
|
import kotlin.IllegalStateException
|
||||||
|
|
||||||
|
@ -312,15 +313,23 @@ object FileUtil {
|
||||||
* @param inputFile File representation of the item that will be zipped
|
* @param inputFile File representation of the item that will be zipped
|
||||||
* @param rootDir Directory containing the inputFile
|
* @param rootDir Directory containing the inputFile
|
||||||
* @param outputStream Stream where the zip file will be output
|
* @param outputStream Stream where the zip file will be output
|
||||||
|
* @param cancelled [StateFlow] that reports whether this process has been cancelled
|
||||||
|
* @param compression Disables compression if true
|
||||||
*/
|
*/
|
||||||
fun zipFromInternalStorage(
|
fun zipFromInternalStorage(
|
||||||
inputFile: File,
|
inputFile: File,
|
||||||
rootDir: String,
|
rootDir: String,
|
||||||
outputStream: BufferedOutputStream,
|
outputStream: BufferedOutputStream,
|
||||||
cancelled: StateFlow<Boolean>? = null
|
cancelled: StateFlow<Boolean>? = null,
|
||||||
|
compression: Boolean = true
|
||||||
): TaskState {
|
): TaskState {
|
||||||
try {
|
try {
|
||||||
ZipOutputStream(outputStream).use { zos ->
|
ZipOutputStream(outputStream).use { zos ->
|
||||||
|
if (!compression) {
|
||||||
|
zos.setMethod(ZipOutputStream.DEFLATED)
|
||||||
|
zos.setLevel(Deflater.NO_COMPRESSION)
|
||||||
|
}
|
||||||
|
|
||||||
inputFile.walkTopDown().forEach { file ->
|
inputFile.walkTopDown().forEach { file ->
|
||||||
if (cancelled?.value == true) {
|
if (cancelled?.value == true) {
|
||||||
return TaskState.Cancelled
|
return TaskState.Cancelled
|
||||||
|
@ -338,6 +347,7 @@ object FileUtil {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
|
Log.error("[FileUtil] Failed creating zip file - ${e.message}")
|
||||||
return TaskState.Failed
|
return TaskState.Failed
|
||||||
}
|
}
|
||||||
return TaskState.Completed
|
return TaskState.Completed
|
||||||
|
|
|
@ -14,12 +14,6 @@ AndroidConfig::AndroidConfig(const std::string& config_name, ConfigType config_t
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
AndroidConfig::~AndroidConfig() {
|
|
||||||
if (global) {
|
|
||||||
AndroidConfig::SaveAllValues();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void AndroidConfig::ReloadAllValues() {
|
void AndroidConfig::ReloadAllValues() {
|
||||||
Reload();
|
Reload();
|
||||||
ReadAndroidValues();
|
ReadAndroidValues();
|
||||||
|
|
|
@ -9,7 +9,6 @@ class AndroidConfig final : public Config {
|
||||||
public:
|
public:
|
||||||
explicit AndroidConfig(const std::string& config_name = "config",
|
explicit AndroidConfig(const std::string& config_name = "config",
|
||||||
ConfigType config_type = ConfigType::GlobalConfig);
|
ConfigType config_type = ConfigType::GlobalConfig);
|
||||||
~AndroidConfig() override;
|
|
||||||
|
|
||||||
void ReloadAllValues() override;
|
void ReloadAllValues() override;
|
||||||
void SaveAllValues() override;
|
void SaveAllValues() override;
|
||||||
|
|
|
@ -118,15 +118,23 @@
|
||||||
</integer-array>
|
</integer-array>
|
||||||
|
|
||||||
<string-array name="rendererScreenLayoutNames">
|
<string-array name="rendererScreenLayoutNames">
|
||||||
<item>@string/screen_layout_landscape</item>
|
|
||||||
<item>@string/screen_layout_portrait</item>
|
|
||||||
<item>@string/screen_layout_auto</item>
|
<item>@string/screen_layout_auto</item>
|
||||||
|
<item>@string/screen_layout_sensor_landscape</item>
|
||||||
|
<item>@string/screen_layout_landscape</item>
|
||||||
|
<item>@string/screen_layout_reverse_landscape</item>
|
||||||
|
<item>@string/screen_layout_sensor_portrait</item>
|
||||||
|
<item>@string/screen_layout_portrait</item>
|
||||||
|
<item>@string/screen_layout_reverse_portrait</item>
|
||||||
</string-array>
|
</string-array>
|
||||||
|
|
||||||
<integer-array name="rendererScreenLayoutValues">
|
<integer-array name="rendererScreenLayoutValues">
|
||||||
<item>5</item>
|
|
||||||
<item>4</item>
|
|
||||||
<item>0</item>
|
<item>0</item>
|
||||||
|
<item>5</item>
|
||||||
|
<item>1</item>
|
||||||
|
<item>2</item>
|
||||||
|
<item>6</item>
|
||||||
|
<item>4</item>
|
||||||
|
<item>3</item>
|
||||||
</integer-array>
|
</integer-array>
|
||||||
|
|
||||||
<string-array name="rendererAspectRatioNames">
|
<string-array name="rendererAspectRatioNames">
|
||||||
|
|
|
@ -463,9 +463,13 @@
|
||||||
<string name="anti_aliasing_smaa">SMAA</string>
|
<string name="anti_aliasing_smaa">SMAA</string>
|
||||||
|
|
||||||
<!-- Screen Layouts -->
|
<!-- Screen Layouts -->
|
||||||
<string name="screen_layout_landscape">Landscape</string>
|
|
||||||
<string name="screen_layout_portrait">Portrait</string>
|
|
||||||
<string name="screen_layout_auto">Auto</string>
|
<string name="screen_layout_auto">Auto</string>
|
||||||
|
<string name="screen_layout_sensor_landscape">Sensor landscape</string>
|
||||||
|
<string name="screen_layout_landscape">Landscape</string>
|
||||||
|
<string name="screen_layout_reverse_landscape">Reverse landscape</string>
|
||||||
|
<string name="screen_layout_sensor_portrait">Sensor portrait</string>
|
||||||
|
<string name="screen_layout_portrait">Portrait</string>
|
||||||
|
<string name="screen_layout_reverse_portrait">Reverse portrait</string>
|
||||||
|
|
||||||
<!-- Aspect Ratios -->
|
<!-- Aspect Ratios -->
|
||||||
<string name="ratio_default">Default (16:9)</string>
|
<string name="ratio_default">Default (16:9)</string>
|
||||||
|
|
|
@ -153,6 +153,8 @@ bool NPadData::IsNpadStyleIndexSupported(Core::HID::NpadStyleIndex style_index)
|
||||||
switch (style_index) {
|
switch (style_index) {
|
||||||
case Core::HID::NpadStyleIndex::ProController:
|
case Core::HID::NpadStyleIndex::ProController:
|
||||||
return style.fullkey.As<bool>();
|
return style.fullkey.As<bool>();
|
||||||
|
case Core::HID::NpadStyleIndex::Handheld:
|
||||||
|
return style.handheld.As<bool>();
|
||||||
case Core::HID::NpadStyleIndex::JoyconDual:
|
case Core::HID::NpadStyleIndex::JoyconDual:
|
||||||
return style.joycon_dual.As<bool>();
|
return style.joycon_dual.As<bool>();
|
||||||
case Core::HID::NpadStyleIndex::JoyconLeft:
|
case Core::HID::NpadStyleIndex::JoyconLeft:
|
||||||
|
|
|
@ -762,17 +762,6 @@ void Config::WriteBooleanSetting(const std::string& key, const bool& value,
|
||||||
WritePreparedSetting(key, AdjustOutputString(ToString(value)), string_default, use_global);
|
WritePreparedSetting(key, AdjustOutputString(ToString(value)), string_default, use_global);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
std::enable_if_t<std::is_integral_v<T>> Config::WriteIntegerSetting(
|
|
||||||
const std::string& key, const T& value, const std::optional<T>& default_value,
|
|
||||||
const std::optional<bool>& use_global) {
|
|
||||||
std::optional<std::string> string_default = std::nullopt;
|
|
||||||
if (default_value.has_value()) {
|
|
||||||
string_default = std::make_optional(ToString(default_value.value()));
|
|
||||||
}
|
|
||||||
WritePreparedSetting(key, AdjustOutputString(ToString(value)), string_default, use_global);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Config::WriteDoubleSetting(const std::string& key, const double& value,
|
void Config::WriteDoubleSetting(const std::string& key, const double& value,
|
||||||
const std::optional<double>& default_value,
|
const std::optional<double>& default_value,
|
||||||
const std::optional<bool>& use_global) {
|
const std::optional<bool>& use_global) {
|
||||||
|
@ -894,9 +883,10 @@ void Config::WriteSettingGeneric(const Settings::BasicSetting* const setting) {
|
||||||
WriteBooleanSetting(std::string(key).append("\\use_global"), setting->UsingGlobal());
|
WriteBooleanSetting(std::string(key).append("\\use_global"), setting->UsingGlobal());
|
||||||
}
|
}
|
||||||
if (global || !setting->UsingGlobal()) {
|
if (global || !setting->UsingGlobal()) {
|
||||||
|
auto value = global ? setting->ToStringGlobal() : setting->ToString();
|
||||||
WriteBooleanSetting(std::string(key).append("\\default"),
|
WriteBooleanSetting(std::string(key).append("\\default"),
|
||||||
setting->ToString() == setting->DefaultToString());
|
value == setting->DefaultToString());
|
||||||
WriteStringSetting(key, setting->ToString());
|
WriteStringSetting(key, value);
|
||||||
}
|
}
|
||||||
} else if (global) {
|
} else if (global) {
|
||||||
WriteBooleanSetting(std::string(key).append("\\default"),
|
WriteBooleanSetting(std::string(key).append("\\default"),
|
||||||
|
|
|
@ -157,17 +157,23 @@ protected:
|
||||||
void WriteBooleanSetting(const std::string& key, const bool& value,
|
void WriteBooleanSetting(const std::string& key, const bool& value,
|
||||||
const std::optional<bool>& default_value = std::nullopt,
|
const std::optional<bool>& default_value = std::nullopt,
|
||||||
const std::optional<bool>& use_global = std::nullopt);
|
const std::optional<bool>& use_global = std::nullopt);
|
||||||
template <typename T>
|
|
||||||
std::enable_if_t<std::is_integral_v<T>> WriteIntegerSetting(
|
|
||||||
const std::string& key, const T& value,
|
|
||||||
const std::optional<T>& default_value = std::nullopt,
|
|
||||||
const std::optional<bool>& use_global = std::nullopt);
|
|
||||||
void WriteDoubleSetting(const std::string& key, const double& value,
|
void WriteDoubleSetting(const std::string& key, const double& value,
|
||||||
const std::optional<double>& default_value = std::nullopt,
|
const std::optional<double>& default_value = std::nullopt,
|
||||||
const std::optional<bool>& use_global = std::nullopt);
|
const std::optional<bool>& use_global = std::nullopt);
|
||||||
void WriteStringSetting(const std::string& key, const std::string& value,
|
void WriteStringSetting(const std::string& key, const std::string& value,
|
||||||
const std::optional<std::string>& default_value = std::nullopt,
|
const std::optional<std::string>& default_value = std::nullopt,
|
||||||
const std::optional<bool>& use_global = std::nullopt);
|
const std::optional<bool>& use_global = std::nullopt);
|
||||||
|
template <typename T>
|
||||||
|
std::enable_if_t<std::is_integral_v<T>> WriteIntegerSetting(
|
||||||
|
const std::string& key, const T& value,
|
||||||
|
const std::optional<T>& default_value = std::nullopt,
|
||||||
|
const std::optional<bool>& use_global = std::nullopt) {
|
||||||
|
std::optional<std::string> string_default = std::nullopt;
|
||||||
|
if (default_value.has_value()) {
|
||||||
|
string_default = std::make_optional(ToString(default_value.value()));
|
||||||
|
}
|
||||||
|
WritePreparedSetting(key, AdjustOutputString(ToString(value)), string_default, use_global);
|
||||||
|
}
|
||||||
|
|
||||||
void ReadCategory(Settings::Category category);
|
void ReadCategory(Settings::Category category);
|
||||||
void WriteCategory(Settings::Category category);
|
void WriteCategory(Settings::Category category);
|
||||||
|
|
Loading…
Reference in a new issue