mirror of
https://git.eden-emu.dev/eden-emu/eden.git
synced 2025-07-20 08:15:46 +00:00
[frontend] Firmware setup & requirement (#222)
Currently Android only, will need to be added to desktop. Android incorrectly records firmware as 19.0.1 if on a higher version... TODO: - [x] desktop - [x] fix android Signed-off-by: crueter <swurl@swurl.xyz> Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/222 Co-authored-by: crueter <swurl@swurl.xyz> Co-committed-by: crueter <swurl@swurl.xyz>
This commit is contained in:
parent
20bf141faa
commit
f121df0aa3
22 changed files with 379 additions and 74 deletions
|
@ -7,16 +7,9 @@ license_header = <<~EOF
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
print 'Getting branch changes...'
|
print 'Getting branch changes...'
|
||||||
puts "\n"
|
|
||||||
branch_name = `git rev-parse --abbrev-ref HEAD`.chomp
|
branch_name = `git rev-parse --abbrev-ref HEAD`.chomp
|
||||||
print branch_name
|
|
||||||
puts "\n"
|
|
||||||
branch_commits = `git log #{branch_name} --not master --pretty=format:"%h"`.split("\n")
|
branch_commits = `git log #{branch_name} --not master --pretty=format:"%h"`.split("\n")
|
||||||
print branch_commits
|
|
||||||
puts "\n"
|
|
||||||
branch_commit_range = "#{branch_commits[-1]}^..#{branch_commits[0]}"
|
branch_commit_range = "#{branch_commits[-1]}^..#{branch_commits[0]}"
|
||||||
print branch_commit_range
|
|
||||||
puts "\n"
|
|
||||||
branch_changed_files = `git diff-tree --no-commit-id --name-only #{branch_commit_range} -r`.split("\n")
|
branch_changed_files = `git diff-tree --no-commit-id --name-only #{branch_commit_range} -r`.split("\n")
|
||||||
puts 'done'
|
puts 'done'
|
||||||
|
|
||||||
|
|
85
.ci/license-header.sh
Executable file
85
.ci/license-header.sh
Executable file
|
@ -0,0 +1,85 @@
|
||||||
|
#!/bin/sh -e
|
||||||
|
|
||||||
|
HEADER="$(cat "$PWD/.ci/license/header.txt")"
|
||||||
|
|
||||||
|
echo "Getting branch changes"
|
||||||
|
|
||||||
|
# I created this cursed POSIX abomination only to discover a better solution
|
||||||
|
#BRANCH=`git rev-parse --abbrev-ref HEAD`
|
||||||
|
#COMMITS=`git log ${BRANCH} --not master --pretty=format:"%h"`
|
||||||
|
#RANGE="${COMMITS[${#COMMITS[@]}-1]}^..${COMMITS[0]}"
|
||||||
|
#FILES=`git diff-tree --no-commit-id --name-only ${RANGE} -r`
|
||||||
|
|
||||||
|
FILES=$(git diff --name-only master)
|
||||||
|
|
||||||
|
echo "Done"
|
||||||
|
|
||||||
|
for file in $FILES; do
|
||||||
|
EXTENSION="${file##*.}"
|
||||||
|
case "$EXTENSION" in
|
||||||
|
kts|kt|cpp|h)
|
||||||
|
CONTENT="`cat $file`"
|
||||||
|
case "$CONTENT" in
|
||||||
|
"$HEADER"*) ;;
|
||||||
|
*) BAD_FILES="$BAD_FILES $file" ;;
|
||||||
|
esac
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
|
||||||
|
if [ "$BAD_FILES" = "" ]; then
|
||||||
|
echo
|
||||||
|
echo "All good."
|
||||||
|
|
||||||
|
exit
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "The following files have incorrect license headers:"
|
||||||
|
echo
|
||||||
|
|
||||||
|
for file in $BAD_FILES; do echo $file; done
|
||||||
|
|
||||||
|
cat << EOF
|
||||||
|
|
||||||
|
The following license header should be added to the start of all offending files:
|
||||||
|
|
||||||
|
=== BEGIN ===
|
||||||
|
$HEADER
|
||||||
|
=== END ===
|
||||||
|
|
||||||
|
If some of the code in this PR is not being contributed by the original author,
|
||||||
|
the files which have been exclusively changed by that code can be ignored.
|
||||||
|
If this happens, this PR requirement can be bypassed once all other files are addressed.
|
||||||
|
EOF
|
||||||
|
|
||||||
|
if [ "$FIX" = "true" ]; then
|
||||||
|
echo
|
||||||
|
echo "FIX set to true. Fixing headers."
|
||||||
|
echo
|
||||||
|
|
||||||
|
for file in $BAD_FILES; do
|
||||||
|
cat $file > $file.bak
|
||||||
|
|
||||||
|
cat .ci/license/header.txt > $file
|
||||||
|
echo >> $file
|
||||||
|
cat $file.bak >> $file
|
||||||
|
|
||||||
|
rm $file.bak
|
||||||
|
|
||||||
|
git add $file
|
||||||
|
done
|
||||||
|
|
||||||
|
echo "License headers fixed."
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "$COMMIT" = "true" ]; then
|
||||||
|
echo
|
||||||
|
echo "COMMIT set to true. Committing changes."
|
||||||
|
echo
|
||||||
|
|
||||||
|
git commit -m "Fix license headers"
|
||||||
|
|
||||||
|
echo "Changes committed. You may now push."
|
||||||
|
fi
|
||||||
|
|
||||||
|
exit
|
2
.ci/license/header.txt
Normal file
2
.ci/license/header.txt
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
|
||||||
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
4
.github/workflows/license-header.yml
vendored
4
.github/workflows/license-header.yml
vendored
|
@ -16,7 +16,7 @@ jobs:
|
||||||
run: git fetch origin master:master
|
run: git fetch origin master:master
|
||||||
|
|
||||||
- name: Make script executable
|
- name: Make script executable
|
||||||
run: chmod +x ./.ci/license-header.rb
|
run: chmod +x ./.ci/license-header.sh
|
||||||
|
|
||||||
- name: Check license headers
|
- name: Check license headers
|
||||||
run: ./.ci/license-header.rb
|
run: ./.ci/license-header.sh
|
||||||
|
|
|
@ -246,6 +246,7 @@ dependencies {
|
||||||
implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.6.3")
|
implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.6.3")
|
||||||
implementation("androidx.compose.ui:ui-graphics-android:1.7.8")
|
implementation("androidx.compose.ui:ui-graphics-android:1.7.8")
|
||||||
implementation("androidx.compose.ui:ui-text-android:1.7.8")
|
implementation("androidx.compose.ui:ui-text-android:1.7.8")
|
||||||
|
implementation("net.swiftzer.semver:semver:2.0.0")
|
||||||
}
|
}
|
||||||
|
|
||||||
fun runGitCommand(command: List<String>): String {
|
fun runGitCommand(command: List<String>): String {
|
||||||
|
|
|
@ -16,6 +16,7 @@ import android.view.View
|
||||||
import android.widget.TextView
|
import android.widget.TextView
|
||||||
import androidx.annotation.Keep
|
import androidx.annotation.Keep
|
||||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
||||||
|
import net.swiftzer.semver.SemVer
|
||||||
import java.lang.ref.WeakReference
|
import java.lang.ref.WeakReference
|
||||||
import org.yuzu.yuzu_emu.activities.EmulationActivity
|
import org.yuzu.yuzu_emu.activities.EmulationActivity
|
||||||
import org.yuzu.yuzu_emu.fragments.CoreErrorDialogFragment
|
import org.yuzu.yuzu_emu.fragments.CoreErrorDialogFragment
|
||||||
|
@ -407,6 +408,26 @@ object NativeLibrary {
|
||||||
*/
|
*/
|
||||||
external fun isFirmwareAvailable(): Boolean
|
external fun isFirmwareAvailable(): Boolean
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the firmware version.
|
||||||
|
*
|
||||||
|
* @return Reported firmware version
|
||||||
|
*/
|
||||||
|
external fun firmwareVersion(): String
|
||||||
|
|
||||||
|
fun isFirmwareSupported(): Boolean {
|
||||||
|
var version: SemVer
|
||||||
|
|
||||||
|
try {
|
||||||
|
version = SemVer.parse(firmwareVersion())
|
||||||
|
} catch (_: Exception) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
val max = SemVer(19, 0, 1)
|
||||||
|
|
||||||
|
return version <= max
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Checks the PatchManager for any addons that are available
|
* Checks the PatchManager for any addons that are available
|
||||||
*
|
*
|
||||||
|
|
|
@ -41,6 +41,7 @@ enum class BooleanSetting(override val key: String) : AbstractBooleanSetting {
|
||||||
SHOW_DEVICE_MODEL("show_device_model"),
|
SHOW_DEVICE_MODEL("show_device_model"),
|
||||||
SHOW_GPU_MODEL("show_gpu_model"),
|
SHOW_GPU_MODEL("show_gpu_model"),
|
||||||
SHOW_SOC_MODEL("show_soc_model"),
|
SHOW_SOC_MODEL("show_soc_model"),
|
||||||
|
SHOW_FW_VERSION("show_firmware_version"),
|
||||||
|
|
||||||
SOC_OVERLAY_BACKGROUND("soc_overlay_background"),
|
SOC_OVERLAY_BACKGROUND("soc_overlay_background"),
|
||||||
|
|
||||||
|
|
|
@ -460,6 +460,14 @@ abstract class SettingsItem(
|
||||||
descriptionId = R.string.show_soc_model_description
|
descriptionId = R.string.show_soc_model_description
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
put(
|
||||||
|
SwitchSetting(
|
||||||
|
BooleanSetting.SHOW_FW_VERSION,
|
||||||
|
titleId = R.string.show_fw_version,
|
||||||
|
descriptionId = R.string.show_fw_version_description
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
put(
|
put(
|
||||||
SingleChoiceSetting(
|
SingleChoiceSetting(
|
||||||
|
|
|
@ -271,6 +271,8 @@ class SettingsFragmentPresenter(
|
||||||
if (Build.VERSION.SDK_INT >= 31) {
|
if (Build.VERSION.SDK_INT >= 31) {
|
||||||
add(BooleanSetting.SHOW_SOC_MODEL.key)
|
add(BooleanSetting.SHOW_SOC_MODEL.key)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
add(BooleanSetting.SHOW_FW_VERSION.key)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,9 +1,8 @@
|
||||||
// SPDX-FileCopyrightText: 2023 yuzu Emulator Project
|
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
|
||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
|
||||||
|
|
||||||
// SPDX-FileCopyrightText: 2025 Eden Emulator Project
|
|
||||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
|
// SPDX-FileCopyrightText: 2023 yuzu Emulator Project
|
||||||
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
package org.yuzu.yuzu_emu.fragments
|
package org.yuzu.yuzu_emu.fragments
|
||||||
|
|
||||||
|
@ -754,6 +753,11 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (BooleanSetting.SHOW_FW_VERSION.getBoolean(NativeConfig.isPerGameConfigLoaded())) {
|
||||||
|
if (sb.isNotEmpty()) sb.append(" | ")
|
||||||
|
sb.append(NativeLibrary.firmwareVersion())
|
||||||
|
}
|
||||||
|
|
||||||
binding.showSocOverlayText.text = sb.toString()
|
binding.showSocOverlayText.text = sb.toString()
|
||||||
|
|
||||||
if (BooleanSetting.SOC_OVERLAY_BACKGROUND.getBoolean(NativeConfig.isPerGameConfigLoaded())) {
|
if (BooleanSetting.SOC_OVERLAY_BACKGROUND.getBoolean(NativeConfig.isPerGameConfigLoaded())) {
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
// SPDX-FileCopyrightText: 2025 Eden Emulator Project
|
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
|
||||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
package org.yuzu.yuzu_emu.fragments
|
package org.yuzu.yuzu_emu.fragments
|
||||||
|
@ -137,7 +137,7 @@ class HomeSettingsFragment : Fragment() {
|
||||||
binding.root.findNavController()
|
binding.root.findNavController()
|
||||||
.navigate(R.id.action_homeSettingsFragment_to_appletLauncherFragment)
|
.navigate(R.id.action_homeSettingsFragment_to_appletLauncherFragment)
|
||||||
},
|
},
|
||||||
{ NativeLibrary.isFirmwareAvailable() },
|
{ NativeLibrary.isFirmwareAvailable() && NativeLibrary.isFirmwareSupported() },
|
||||||
R.string.applets_error_firmware,
|
R.string.applets_error_firmware,
|
||||||
R.string.applets_error_description
|
R.string.applets_error_description
|
||||||
)
|
)
|
||||||
|
|
|
@ -1,9 +1,13 @@
|
||||||
|
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
|
||||||
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
// SPDX-FileCopyrightText: 2023 yuzu Emulator Project
|
// SPDX-FileCopyrightText: 2023 yuzu Emulator Project
|
||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
package org.yuzu.yuzu_emu.fragments
|
package org.yuzu.yuzu_emu.fragments
|
||||||
|
|
||||||
import android.app.Dialog
|
import android.app.Dialog
|
||||||
|
import android.content.DialogInterface
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
import android.view.View
|
import android.view.View
|
||||||
|
@ -28,6 +32,8 @@ class ProgressDialogFragment : DialogFragment() {
|
||||||
|
|
||||||
private val PROGRESS_BAR_RESOLUTION = 1000
|
private val PROGRESS_BAR_RESOLUTION = 1000
|
||||||
|
|
||||||
|
var onDialogComplete: (() -> Unit)? = null
|
||||||
|
|
||||||
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
|
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
|
||||||
val titleId = requireArguments().getInt(TITLE)
|
val titleId = requireArguments().getInt(TITLE)
|
||||||
val cancellable = requireArguments().getBoolean(CANCELLABLE)
|
val cancellable = requireArguments().getBoolean(CANCELLABLE)
|
||||||
|
@ -121,6 +127,11 @@ class ProgressDialogFragment : DialogFragment() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun onDismiss(dialog: DialogInterface) {
|
||||||
|
super.onDismiss(dialog)
|
||||||
|
onDialogComplete?.invoke()
|
||||||
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
const val TAG = "IndeterminateProgressDialogFragment"
|
const val TAG = "IndeterminateProgressDialogFragment"
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
// SPDX-FileCopyrightText: 2025 Eden Emulator Project
|
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
|
||||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
package org.yuzu.yuzu_emu.fragments
|
package org.yuzu.yuzu_emu.fragments
|
||||||
|
@ -166,6 +166,32 @@ class SetupFragment : Fragment() {
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
add(
|
||||||
|
SetupPage(
|
||||||
|
R.drawable.ic_firmware,
|
||||||
|
R.string.firmware,
|
||||||
|
R.string.firmware_description,
|
||||||
|
R.drawable.ic_add,
|
||||||
|
true,
|
||||||
|
R.string.select_firmware,
|
||||||
|
{
|
||||||
|
firmwareCallback = it
|
||||||
|
getFirmware.launch(arrayOf("application/zip"))
|
||||||
|
},
|
||||||
|
true,
|
||||||
|
R.string.install_firmware_warning,
|
||||||
|
R.string.install_firmware_warning_description,
|
||||||
|
R.string.install_firmware_warning_help,
|
||||||
|
{
|
||||||
|
if (NativeLibrary.isFirmwareAvailable()) {
|
||||||
|
StepState.COMPLETE
|
||||||
|
} else {
|
||||||
|
StepState.INCOMPLETE
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
add(
|
add(
|
||||||
SetupPage(
|
SetupPage(
|
||||||
R.drawable.ic_controller,
|
R.drawable.ic_controller,
|
||||||
|
@ -321,6 +347,7 @@ class SetupFragment : Fragment() {
|
||||||
}
|
}
|
||||||
|
|
||||||
private lateinit var keyCallback: SetupCallback
|
private lateinit var keyCallback: SetupCallback
|
||||||
|
private lateinit var firmwareCallback: SetupCallback
|
||||||
|
|
||||||
val getProdKey =
|
val getProdKey =
|
||||||
registerForActivityResult(ActivityResultContracts.OpenDocument()) { result ->
|
registerForActivityResult(ActivityResultContracts.OpenDocument()) { result ->
|
||||||
|
@ -332,6 +359,17 @@ class SetupFragment : Fragment() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val getFirmware =
|
||||||
|
registerForActivityResult(ActivityResultContracts.OpenDocument()) { result ->
|
||||||
|
if (result != null) {
|
||||||
|
mainActivity.processFirmware(result) {
|
||||||
|
if (NativeLibrary.isFirmwareAvailable()) {
|
||||||
|
firmwareCallback.onStepCompleted()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private lateinit var gamesDirCallback: SetupCallback
|
private lateinit var gamesDirCallback: SetupCallback
|
||||||
|
|
||||||
val getGamesDirectory =
|
val getGamesDirectory =
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
// SPDX-FileCopyrightText: 2025 Eden Emulator Project
|
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
|
||||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
package org.yuzu.yuzu_emu.model
|
package org.yuzu.yuzu_emu.model
|
||||||
|
@ -31,6 +31,9 @@ class HomeViewModel : ViewModel() {
|
||||||
private val _checkKeys = MutableStateFlow(false)
|
private val _checkKeys = MutableStateFlow(false)
|
||||||
val checkKeys = _checkKeys.asStateFlow()
|
val checkKeys = _checkKeys.asStateFlow()
|
||||||
|
|
||||||
|
private val _checkFirmware = MutableStateFlow(false)
|
||||||
|
val checkFirmware = _checkFirmware.asStateFlow()
|
||||||
|
|
||||||
var navigatedToSetup = false
|
var navigatedToSetup = false
|
||||||
|
|
||||||
fun setStatusBarShadeVisibility(visible: Boolean) {
|
fun setStatusBarShadeVisibility(visible: Boolean) {
|
||||||
|
@ -63,4 +66,8 @@ class HomeViewModel : ViewModel() {
|
||||||
fun setCheckKeys(value: Boolean) {
|
fun setCheckKeys(value: Boolean) {
|
||||||
_checkKeys.value = value
|
_checkKeys.value = value
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun setCheckFirmware(value: Boolean) {
|
||||||
|
_checkFirmware.value = value
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
// SPDX-FileCopyrightText: 2025 Eden Emulator Project
|
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
|
||||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
package org.yuzu.yuzu_emu.ui.main
|
package org.yuzu.yuzu_emu.ui.main
|
||||||
|
@ -62,6 +62,9 @@ class MainActivity : AppCompatActivity(), ThemeProvider {
|
||||||
private val CHECKED_DECRYPTION = "CheckedDecryption"
|
private val CHECKED_DECRYPTION = "CheckedDecryption"
|
||||||
private var checkedDecryption = false
|
private var checkedDecryption = false
|
||||||
|
|
||||||
|
private val CHECKED_FIRMWARE = "CheckedFirmware"
|
||||||
|
private var checkedFirmware = false
|
||||||
|
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
val splashScreen = installSplashScreen()
|
val splashScreen = installSplashScreen()
|
||||||
splashScreen.setKeepOnScreenCondition { !DirectoryInitialization.areDirectoriesReady }
|
splashScreen.setKeepOnScreenCondition { !DirectoryInitialization.areDirectoriesReady }
|
||||||
|
@ -76,17 +79,27 @@ class MainActivity : AppCompatActivity(), ThemeProvider {
|
||||||
|
|
||||||
if (savedInstanceState != null) {
|
if (savedInstanceState != null) {
|
||||||
checkedDecryption = savedInstanceState.getBoolean(CHECKED_DECRYPTION)
|
checkedDecryption = savedInstanceState.getBoolean(CHECKED_DECRYPTION)
|
||||||
|
checkedFirmware = savedInstanceState.getBoolean(CHECKED_FIRMWARE)
|
||||||
}
|
}
|
||||||
if (!checkedDecryption) {
|
if (!checkedDecryption) {
|
||||||
val firstTimeSetup = PreferenceManager.getDefaultSharedPreferences(applicationContext)
|
val firstTimeSetup = PreferenceManager.getDefaultSharedPreferences(applicationContext)
|
||||||
.getBoolean(Settings.PREF_FIRST_APP_LAUNCH, true)
|
.getBoolean(Settings.PREF_FIRST_APP_LAUNCH, true)
|
||||||
if (!firstTimeSetup) {
|
if (!firstTimeSetup) {
|
||||||
checkKeys()
|
checkKeys()
|
||||||
showPreAlphaWarningDialog()
|
|
||||||
}
|
}
|
||||||
checkedDecryption = true
|
checkedDecryption = true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!checkedFirmware) {
|
||||||
|
val firstTimeSetup = PreferenceManager.getDefaultSharedPreferences(applicationContext)
|
||||||
|
.getBoolean(Settings.PREF_FIRST_APP_LAUNCH, true)
|
||||||
|
if (!firstTimeSetup) {
|
||||||
|
checkFirmware()
|
||||||
|
showPreAlphaWarningDialog()
|
||||||
|
}
|
||||||
|
checkedFirmware = true
|
||||||
|
}
|
||||||
|
|
||||||
WindowCompat.setDecorFitsSystemWindows(window, false)
|
WindowCompat.setDecorFitsSystemWindows(window, false)
|
||||||
window.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_NOTHING)
|
window.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_NOTHING)
|
||||||
|
|
||||||
|
@ -135,6 +148,10 @@ class MainActivity : AppCompatActivity(), ThemeProvider {
|
||||||
if (it) checkKeys()
|
if (it) checkKeys()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
homeViewModel.checkFirmware.collect(this, resetState = { homeViewModel.setCheckFirmware(false) }) {
|
||||||
|
if (it) checkFirmware()
|
||||||
|
}
|
||||||
|
|
||||||
setInsets()
|
setInsets()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -175,9 +192,21 @@ class MainActivity : AppCompatActivity(), ThemeProvider {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun checkFirmware() {
|
||||||
|
if (!NativeLibrary.isFirmwareAvailable() || !NativeLibrary.isFirmwareSupported()) {
|
||||||
|
MessageDialogFragment.newInstance(
|
||||||
|
titleId = R.string.firmware_missing,
|
||||||
|
descriptionId = R.string.firmware_missing_description,
|
||||||
|
helpLinkId = R.string.firmware_missing_help
|
||||||
|
).show(supportFragmentManager, MessageDialogFragment.TAG)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
override fun onSaveInstanceState(outState: Bundle) {
|
override fun onSaveInstanceState(outState: Bundle) {
|
||||||
super.onSaveInstanceState(outState)
|
super.onSaveInstanceState(outState)
|
||||||
outState.putBoolean(CHECKED_DECRYPTION, checkedDecryption)
|
outState.putBoolean(CHECKED_DECRYPTION, checkedDecryption)
|
||||||
|
outState.putBoolean(CHECKED_FIRMWARE, checkedFirmware)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun finishSetup(navController: NavController) {
|
fun finishSetup(navController: NavController) {
|
||||||
|
@ -306,6 +335,7 @@ class MainActivity : AppCompatActivity(), ThemeProvider {
|
||||||
Toast.LENGTH_SHORT
|
Toast.LENGTH_SHORT
|
||||||
).show()
|
).show()
|
||||||
homeViewModel.setCheckKeys(true)
|
homeViewModel.setCheckKeys(true)
|
||||||
|
homeViewModel.setCheckFirmware(true)
|
||||||
gamesViewModel.reloadGames(true)
|
gamesViewModel.reloadGames(true)
|
||||||
return true
|
return true
|
||||||
} else {
|
} else {
|
||||||
|
@ -327,6 +357,10 @@ class MainActivity : AppCompatActivity(), ThemeProvider {
|
||||||
return@registerForActivityResult
|
return@registerForActivityResult
|
||||||
}
|
}
|
||||||
|
|
||||||
|
processFirmware(result)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun processFirmware(result: Uri, onComplete: (() -> Unit)? = null) {
|
||||||
val filterNCA = FilenameFilter { _, dirName -> dirName.endsWith(".nca") }
|
val filterNCA = FilenameFilter { _, dirName -> dirName.endsWith(".nca") }
|
||||||
|
|
||||||
val firmwarePath =
|
val firmwarePath =
|
||||||
|
@ -357,6 +391,7 @@ class MainActivity : AppCompatActivity(), ThemeProvider {
|
||||||
cacheFirmwareDir.copyRecursively(firmwarePath, true)
|
cacheFirmwareDir.copyRecursively(firmwarePath, true)
|
||||||
NativeLibrary.initializeSystem(true)
|
NativeLibrary.initializeSystem(true)
|
||||||
homeViewModel.setCheckKeys(true)
|
homeViewModel.setCheckKeys(true)
|
||||||
|
homeViewModel.setCheckFirmware(true)
|
||||||
getString(R.string.save_file_imported_success)
|
getString(R.string.save_file_imported_success)
|
||||||
}
|
}
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
|
@ -366,8 +401,11 @@ class MainActivity : AppCompatActivity(), ThemeProvider {
|
||||||
cacheFirmwareDir.deleteRecursively()
|
cacheFirmwareDir.deleteRecursively()
|
||||||
}
|
}
|
||||||
messageToShow
|
messageToShow
|
||||||
|
}.apply {
|
||||||
|
onDialogComplete = onComplete
|
||||||
}.show(supportFragmentManager, ProgressDialogFragment.TAG)
|
}.show(supportFragmentManager, ProgressDialogFragment.TAG)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun uninstallFirmware() {
|
fun uninstallFirmware() {
|
||||||
val firmwarePath = File(DirectoryInitialization.userDirectory + "/nand/system/Contents/registered/")
|
val firmwarePath = File(DirectoryInitialization.userDirectory + "/nand/system/Contents/registered/")
|
||||||
ProgressDialogFragment.newInstance(
|
ProgressDialogFragment.newInstance(
|
||||||
|
@ -382,6 +420,7 @@ class MainActivity : AppCompatActivity(), ThemeProvider {
|
||||||
// Optionally reinitialize the system or perform other necessary steps
|
// Optionally reinitialize the system or perform other necessary steps
|
||||||
NativeLibrary.initializeSystem(true)
|
NativeLibrary.initializeSystem(true)
|
||||||
homeViewModel.setCheckKeys(true)
|
homeViewModel.setCheckKeys(true)
|
||||||
|
homeViewModel.setCheckFirmware(true)
|
||||||
messageToShow = getString(R.string.firmware_uninstalled_success)
|
messageToShow = getString(R.string.firmware_uninstalled_success)
|
||||||
} else {
|
} else {
|
||||||
messageToShow = getString(R.string.firmware_uninstalled_failure)
|
messageToShow = getString(R.string.firmware_uninstalled_failure)
|
||||||
|
|
|
@ -1,3 +1,6 @@
|
||||||
|
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
|
||||||
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
// SPDX-FileCopyrightText: 2023 yuzu Emulator Project
|
// SPDX-FileCopyrightText: 2023 yuzu Emulator Project
|
||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
|
@ -136,6 +139,11 @@ namespace AndroidSettings {
|
||||||
Settings::Specialization::Default, true, true,
|
Settings::Specialization::Default, true, true,
|
||||||
&show_performance_overlay};
|
&show_performance_overlay};
|
||||||
|
|
||||||
|
Settings::Setting<bool> show_fw_version{linkage, true, "show_firmware_version",
|
||||||
|
Settings::Category::Overlay,
|
||||||
|
Settings::Specialization::Default, true, true,
|
||||||
|
&show_performance_overlay};
|
||||||
|
|
||||||
Settings::Setting<bool> soc_overlay_background{linkage, false, "soc_overlay_background",
|
Settings::Setting<bool> soc_overlay_background{linkage, false, "soc_overlay_background",
|
||||||
Settings::Category::Overlay,
|
Settings::Category::Overlay,
|
||||||
Settings::Specialization::Default, true, true,
|
Settings::Specialization::Default, true, true,
|
||||||
|
|
|
@ -57,6 +57,7 @@
|
||||||
#include "core/hle/service/am/applet_manager.h"
|
#include "core/hle/service/am/applet_manager.h"
|
||||||
#include "core/hle/service/am/frontend/applets.h"
|
#include "core/hle/service/am/frontend/applets.h"
|
||||||
#include "core/hle/service/filesystem/filesystem.h"
|
#include "core/hle/service/filesystem/filesystem.h"
|
||||||
|
#include "core/hle/service/set/system_settings_server.h"
|
||||||
#include "core/loader/loader.h"
|
#include "core/loader/loader.h"
|
||||||
#include "frontend_common/config.h"
|
#include "frontend_common/config.h"
|
||||||
#include "hid_core/frontend/emulated_controller.h"
|
#include "hid_core/frontend/emulated_controller.h"
|
||||||
|
@ -762,7 +763,7 @@ void Java_org_yuzu_yuzu_1emu_NativeLibrary_setCabinetMode(JNIEnv* env, jclass cl
|
||||||
static_cast<Service::NFP::CabinetMode>(jcabinetMode));
|
static_cast<Service::NFP::CabinetMode>(jcabinetMode));
|
||||||
}
|
}
|
||||||
|
|
||||||
jboolean Java_org_yuzu_yuzu_1emu_NativeLibrary_isFirmwareAvailable(JNIEnv* env, jclass clazz) {
|
bool isFirmwarePresent() {
|
||||||
auto bis_system =
|
auto bis_system =
|
||||||
EmulationSession::GetInstance().System().GetFileSystemController().GetSystemNANDContents();
|
EmulationSession::GetInstance().System().GetFileSystemController().GetSystemNANDContents();
|
||||||
if (!bis_system) {
|
if (!bis_system) {
|
||||||
|
@ -778,6 +779,31 @@ jboolean Java_org_yuzu_yuzu_1emu_NativeLibrary_isFirmwareAvailable(JNIEnv* env,
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
jboolean Java_org_yuzu_yuzu_1emu_NativeLibrary_isFirmwareAvailable(JNIEnv* env, jclass clazz) {
|
||||||
|
return isFirmwarePresent();
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO(crueter): This check is nonfunctional...
|
||||||
|
jstring Java_org_yuzu_yuzu_1emu_NativeLibrary_firmwareVersion(JNIEnv* env, jclass clazz) {
|
||||||
|
Service::Set::FirmwareVersionFormat firmware_data{};
|
||||||
|
const auto result = Service::Set::GetFirmwareVersionImpl(
|
||||||
|
firmware_data, EmulationSession::GetInstance().System(),
|
||||||
|
Service::Set::GetFirmwareVersionType::Version2);
|
||||||
|
|
||||||
|
if (result.IsError() || !isFirmwarePresent()) {
|
||||||
|
LOG_INFO(Frontend, "Installed firmware: No firmware available");
|
||||||
|
|
||||||
|
return Common::Android::ToJString(env, "N/A");
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::string display_version(firmware_data.display_version.data());
|
||||||
|
const std::string display_title(firmware_data.display_title.data());
|
||||||
|
|
||||||
|
LOG_INFO(Frontend, "Installed firmware: {}", display_title);
|
||||||
|
|
||||||
|
return Common::Android::ToJString(env, display_version);
|
||||||
|
}
|
||||||
|
|
||||||
jobjectArray Java_org_yuzu_yuzu_1emu_NativeLibrary_getPatchesForFile(JNIEnv* env, jobject jobj,
|
jobjectArray Java_org_yuzu_yuzu_1emu_NativeLibrary_getPatchesForFile(JNIEnv* env, jobject jobj,
|
||||||
jstring jpath,
|
jstring jpath,
|
||||||
jstring jprogramId) {
|
jstring jprogramId) {
|
||||||
|
|
|
@ -58,6 +58,8 @@
|
||||||
<string name="show_gpu_model_description">Display the host GPU model</string>
|
<string name="show_gpu_model_description">Display the host GPU model</string>
|
||||||
<string name="show_soc_model">Show SoC Model</string>
|
<string name="show_soc_model">Show SoC Model</string>
|
||||||
<string name="show_soc_model_description">Display the host SoC model</string>
|
<string name="show_soc_model_description">Display the host SoC model</string>
|
||||||
|
<string name="show_fw_version">Show Firmware Version</string>
|
||||||
|
<string name="show_fw_version_description">Display the installed firmware version</string>
|
||||||
|
|
||||||
<!-- Eden`s Veil -->
|
<!-- Eden`s Veil -->
|
||||||
<string name="eden_veil">Eden’s Veil</string>
|
<string name="eden_veil">Eden’s Veil</string>
|
||||||
|
@ -220,6 +222,9 @@
|
||||||
<string name="keys">Keys</string>
|
<string name="keys">Keys</string>
|
||||||
<string name="keys_description">Select your <b>prod.keys</b> file with the button below.</string>
|
<string name="keys_description">Select your <b>prod.keys</b> file with the button below.</string>
|
||||||
<string name="select_keys">Select Keys</string>
|
<string name="select_keys">Select Keys</string>
|
||||||
|
<string name="firmware">Firmware</string>
|
||||||
|
<string name="firmware_description">Select your <b>firmware.zip</b> file with the button below.\nEden currently requires version <b>19.0.1</b> or below.</string>
|
||||||
|
<string name="select_firmware">Select Firmware</string>
|
||||||
<string name="games">Games</string>
|
<string name="games">Games</string>
|
||||||
<string name="games_description">Select your <b>Games</b> folder with the button below.</string>
|
<string name="games_description">Select your <b>Games</b> folder with the button below.</string>
|
||||||
<string name="done">Done</string>
|
<string name="done">Done</string>
|
||||||
|
@ -232,6 +237,8 @@
|
||||||
<string name="step_complete">Complete!</string>
|
<string name="step_complete">Complete!</string>
|
||||||
|
|
||||||
<!-- Home strings -->
|
<!-- Home strings -->
|
||||||
|
<string name="firmware_version">Firmware:</string>
|
||||||
|
|
||||||
<string name="alphabetical">Alphabetical</string>
|
<string name="alphabetical">Alphabetical</string>
|
||||||
<string name="view_list">List</string>
|
<string name="view_list">List</string>
|
||||||
<string name="view_grid">Grid</string>
|
<string name="view_grid">Grid</string>
|
||||||
|
@ -262,6 +269,9 @@
|
||||||
<string name="install_prod_keys_warning">Skip adding keys?</string>
|
<string name="install_prod_keys_warning">Skip adding keys?</string>
|
||||||
<string name="install_prod_keys_warning_description">Valid keys are required to emulate retail games. Only homebrew apps will function if you continue.</string>
|
<string name="install_prod_keys_warning_description">Valid keys are required to emulate retail games. Only homebrew apps will function if you continue.</string>
|
||||||
<string name="install_prod_keys_warning_help">https://yuzu-mirror.github.io/help/quickstart/#guide-introduction</string>
|
<string name="install_prod_keys_warning_help">https://yuzu-mirror.github.io/help/quickstart/#guide-introduction</string>
|
||||||
|
<string name="install_firmware_warning">Skip adding firmware?</string>
|
||||||
|
<string name="install_firmware_warning_description">Many games require access to firmware to run properly.</string>
|
||||||
|
<string name="install_firmware_warning_help">https://yuzu-mirror.github.io/help/quickstart/#guide-introduction</string>
|
||||||
<string name="notifications">Notifications</string>
|
<string name="notifications">Notifications</string>
|
||||||
<string name="notifications_description">Grant the notification permission with the button below.</string>
|
<string name="notifications_description">Grant the notification permission with the button below.</string>
|
||||||
<string name="give_permission">Grant permission</string>
|
<string name="give_permission">Grant permission</string>
|
||||||
|
@ -357,18 +367,24 @@
|
||||||
<string name="no_save_data_found">No save data found</string>
|
<string name="no_save_data_found">No save data found</string>
|
||||||
<string name="verify_installed_content">Verify installed content</string>
|
<string name="verify_installed_content">Verify installed content</string>
|
||||||
<string name="verify_installed_content_description">Checks all installed content for corruption</string>
|
<string name="verify_installed_content_description">Checks all installed content for corruption</string>
|
||||||
|
|
||||||
<string name="keys_missing">Encryption keys are missing</string>
|
<string name="keys_missing">Encryption keys are missing</string>
|
||||||
<string name="keys_missing_description">Firmware and retail games cannot be decrypted</string>
|
<string name="keys_missing_description">Firmware and retail games cannot be decrypted</string>
|
||||||
<string name="keys_missing_help">https://yuzu-mirror.github.io/help/quickstart/#dumping-decryption-keys</string>
|
<string name="keys_missing_help">https://yuzu-mirror.github.io/help/quickstart/#dumping-decryption-keys</string>
|
||||||
|
|
||||||
|
<string name="firmware_missing">Firmware is missing or too new</string>
|
||||||
|
<string name="firmware_missing_description">Some games may not function properly. Eden requires firmware 19.0.1 or below.</string>
|
||||||
|
<string name="firmware_missing_help">https://yuzu-mirror.github.io/help/quickstart/#dumping-system-firmware</string>
|
||||||
|
|
||||||
<!-- Applet launcher strings -->
|
<!-- Applet launcher strings -->
|
||||||
<string name="qlaunch_applet">Qlaunch</string>
|
<string name="qlaunch_applet">Qlaunch</string>
|
||||||
<string name="qlaunch_description">Launch applications from the system home screen</string>
|
<string name="qlaunch_description">Launch applications from the system home screen</string>
|
||||||
<string name="applets">Applet launcher</string>
|
<string name="applets">Applet launcher</string>
|
||||||
<string name="applets_description">Launch system applets using installed firmware</string>
|
<string name="applets_description">Launch system applets using installed firmware</string>
|
||||||
<string name="applets_error_firmware">Firmware not installed</string>
|
<string name="applets_error_firmware">Firmware not installed or invalid version</string>
|
||||||
<string name="applets_error_applet">Applet not available</string>
|
<string name="applets_error_applet">Applet not available</string>
|
||||||
<string name="applets_error_description"><![CDATA[Please ensure your <a href="https://yuzu-mirror.github.io/help/quickstart/#dumping-prodkeys-and-titlekeys">prod.keys</a> file and <a href="https://yuzu-mirror.github.io/help/quickstart/#dumping-system-firmware">firmware</a> are installed and try again.]]></string>
|
<string name="applets_error_description"><![CDATA[Please ensure your <a href="https://yuzu-mirror.github.io/help/quickstart/#dumping-prodkeys-and-titlekeys">prod.keys</a> file and
|
||||||
|
<a href="https://yuzu-mirror.github.io/help/quickstart/#dumping-system-firmware">firmware</a> are installed and try again.<br>Additionally, ensure your firmware is of version 19.0.1 or older.]]></string>
|
||||||
<string name="album_applet">Album</string>
|
<string name="album_applet">Album</string>
|
||||||
<string name="album_applet_description">See images stored in the user screenshots folder with the system photo viewer</string>
|
<string name="album_applet_description">See images stored in the user screenshots folder with the system photo viewer</string>
|
||||||
<string name="mii_edit_applet">Mii edit</string>
|
<string name="mii_edit_applet">Mii edit</string>
|
||||||
|
|
|
@ -1,3 +1,6 @@
|
||||||
|
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
|
||||||
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
// SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project
|
// SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project
|
||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
|
@ -11,8 +14,8 @@ namespace HLE::ApiVersion {
|
||||||
|
|
||||||
// Horizon OS version constants.
|
// Horizon OS version constants.
|
||||||
|
|
||||||
constexpr u8 HOS_VERSION_MAJOR = 19;
|
constexpr u8 HOS_VERSION_MAJOR = 20;
|
||||||
constexpr u8 HOS_VERSION_MINOR = 0;
|
constexpr u8 HOS_VERSION_MINOR = 1;
|
||||||
constexpr u8 HOS_VERSION_MICRO = 1;
|
constexpr u8 HOS_VERSION_MICRO = 1;
|
||||||
|
|
||||||
// NintendoSDK version constants.
|
// NintendoSDK version constants.
|
||||||
|
@ -21,15 +24,15 @@ constexpr u8 SDK_REVISION_MAJOR = 1;
|
||||||
constexpr u8 SDK_REVISION_MINOR = 0;
|
constexpr u8 SDK_REVISION_MINOR = 0;
|
||||||
|
|
||||||
constexpr char PLATFORM_STRING[] = "NX";
|
constexpr char PLATFORM_STRING[] = "NX";
|
||||||
constexpr char VERSION_HASH[] = "835c78223df116284ef7e36e8441760edc81729c";
|
constexpr char VERSION_HASH[] = "9ffad64d79dd150490201461bdf66c8db963f57d";
|
||||||
constexpr char DISPLAY_VERSION[] = "19.0.1";
|
constexpr char DISPLAY_VERSION[] = "20.1.1";
|
||||||
constexpr char DISPLAY_TITLE[] = "NintendoSDK Firmware for NX 19.0.1-1.0";
|
constexpr char DISPLAY_TITLE[] = "NintendoSDK Firmware for NX 20.1.1-1.0";
|
||||||
|
|
||||||
// Atmosphere version constants.
|
// Atmosphere version constants.
|
||||||
|
|
||||||
constexpr u8 ATMOSPHERE_RELEASE_VERSION_MAJOR = 1;
|
constexpr u8 ATMOSPHERE_RELEASE_VERSION_MAJOR = 1;
|
||||||
constexpr u8 ATMOSPHERE_RELEASE_VERSION_MINOR = 0;
|
constexpr u8 ATMOSPHERE_RELEASE_VERSION_MINOR = 9;
|
||||||
constexpr u8 ATMOSPHERE_RELEASE_VERSION_MICRO = 0;
|
constexpr u8 ATMOSPHERE_RELEASE_VERSION_MICRO = 1;
|
||||||
|
|
||||||
constexpr u32 AtmosphereTargetFirmwareWithRevision(u8 major, u8 minor, u8 micro, u8 rev) {
|
constexpr u32 AtmosphereTargetFirmwareWithRevision(u8 major, u8 minor, u8 micro, u8 rev) {
|
||||||
return u32{major} << 24 | u32{minor} << 16 | u32{micro} << 8 | u32{rev};
|
return u32{major} << 24 | u32{minor} << 16 | u32{micro} << 8 | u32{rev};
|
||||||
|
|
|
@ -1,3 +1,6 @@
|
||||||
|
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
|
||||||
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
|
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
|
||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
|
@ -50,8 +53,8 @@ constexpr inline u32 RequiredKernelVersion =
|
||||||
|
|
||||||
// This is the highest SVC version supported, to be updated on new kernel releases.
|
// This is the highest SVC version supported, to be updated on new kernel releases.
|
||||||
// NOTE: Official kernel versions have SVC major = SDK major + 4, SVC minor = SDK minor.
|
// NOTE: Official kernel versions have SVC major = SDK major + 4, SVC minor = SDK minor.
|
||||||
constexpr inline u32 SupportedKernelMajorVersion = ConvertToSvcMajorVersion(15);
|
constexpr inline u32 SupportedKernelMajorVersion = ConvertToSvcMajorVersion(20);
|
||||||
constexpr inline u32 SupportedKernelMinorVersion = ConvertToSvcMinorVersion(3);
|
constexpr inline u32 SupportedKernelMinorVersion = ConvertToSvcMinorVersion(5);
|
||||||
constexpr inline u32 SupportedKernelVersion =
|
constexpr inline u32 SupportedKernelVersion =
|
||||||
EncodeKernelVersion(SupportedKernelMajorVersion, SupportedKernelMinorVersion);
|
EncodeKernelVersion(SupportedKernelMajorVersion, SupportedKernelMinorVersion);
|
||||||
|
|
||||||
|
|
|
@ -462,6 +462,9 @@ GMainWindow::GMainWindow(bool has_broken_vulkan)
|
||||||
// Gen keys if necessary
|
// Gen keys if necessary
|
||||||
OnCheckFirmwareDecryption();
|
OnCheckFirmwareDecryption();
|
||||||
|
|
||||||
|
// Check firmware
|
||||||
|
OnCheckFirmware();
|
||||||
|
|
||||||
game_list->LoadCompatibilityList();
|
game_list->LoadCompatibilityList();
|
||||||
// force reload on first load to ensure add-ons get updated
|
// force reload on first load to ensure add-ons get updated
|
||||||
game_list->PopulateAsync(UISettings::values.game_dirs, false);
|
game_list->PopulateAsync(UISettings::values.game_dirs, false);
|
||||||
|
@ -4326,6 +4329,7 @@ void GMainWindow::OnInstallFirmware() {
|
||||||
|
|
||||||
progress.close();
|
progress.close();
|
||||||
OnCheckFirmwareDecryption();
|
OnCheckFirmwareDecryption();
|
||||||
|
OnCheckFirmware();
|
||||||
}
|
}
|
||||||
|
|
||||||
void GMainWindow::OnInstallDecryptionKeys() {
|
void GMainWindow::OnInstallDecryptionKeys() {
|
||||||
|
@ -4404,6 +4408,7 @@ void GMainWindow::OnInstallDecryptionKeys() {
|
||||||
}
|
}
|
||||||
|
|
||||||
OnCheckFirmwareDecryption();
|
OnCheckFirmwareDecryption();
|
||||||
|
OnCheckFirmware();
|
||||||
}
|
}
|
||||||
|
|
||||||
void GMainWindow::OnAbout() {
|
void GMainWindow::OnAbout() {
|
||||||
|
@ -5067,6 +5072,34 @@ void GMainWindow::OnCheckFirmwareDecryption() {
|
||||||
UpdateMenuState();
|
UpdateMenuState();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void GMainWindow::OnCheckFirmware()
|
||||||
|
{
|
||||||
|
if (!CheckFirmwarePresence()) {
|
||||||
|
QMessageBox::warning(
|
||||||
|
this, tr("Firmware Missing"),
|
||||||
|
tr("Firmware missing. Firmware is required to run certain games and use the Home Menu.\n"
|
||||||
|
"Eden only works with firmware 19.0.1 and earlier."));
|
||||||
|
} else {
|
||||||
|
Service::Set::FirmwareVersionFormat firmware_data{};
|
||||||
|
const auto result = Service::Set::GetFirmwareVersionImpl(
|
||||||
|
firmware_data, *system, Service::Set::GetFirmwareVersionType::Version2);
|
||||||
|
|
||||||
|
if (result.IsError()) {
|
||||||
|
LOG_INFO(Frontend, "Unable to read firmware");
|
||||||
|
QMessageBox::warning(
|
||||||
|
this, tr("Firmware Corrupted"),
|
||||||
|
tr("Firmware reported as present, but was unable to be read. Check for decryption keys and redump firmware if necessary."));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (firmware_data.major > 19) {
|
||||||
|
QMessageBox::warning(
|
||||||
|
this, tr("Firmware Too New"),
|
||||||
|
tr("Firmware is too new. Eden only works with firmware 19.0.1 and earlier."));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool GMainWindow::CheckFirmwarePresence() {
|
bool GMainWindow::CheckFirmwarePresence() {
|
||||||
constexpr u64 MiiEditId = static_cast<u64>(Service::AM::AppletProgramId::MiiEdit);
|
constexpr u64 MiiEditId = static_cast<u64>(Service::AM::AppletProgramId::MiiEdit);
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,6 @@
|
||||||
|
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
|
||||||
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
// SPDX-FileCopyrightText: 2014 Citra Emulator Project
|
// SPDX-FileCopyrightText: 2014 Citra Emulator Project
|
||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
|
@ -414,6 +417,7 @@ private slots:
|
||||||
void OnCreateHomeMenuShortcut(GameListShortcutTarget target);
|
void OnCreateHomeMenuShortcut(GameListShortcutTarget target);
|
||||||
void OnCaptureScreenshot();
|
void OnCaptureScreenshot();
|
||||||
void OnCheckFirmwareDecryption();
|
void OnCheckFirmwareDecryption();
|
||||||
|
void OnCheckFirmware();
|
||||||
void OnLanguageChanged(const QString& locale);
|
void OnLanguageChanged(const QString& locale);
|
||||||
void OnMouseActivity();
|
void OnMouseActivity();
|
||||||
bool OnShutdownBegin();
|
bool OnShutdownBegin();
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue