Compare commits

..

1 Commits

Author SHA1 Message Date
Bix
60995d649d Test Do not use D24 2025-11-22 13:21:04 +00:00
25 changed files with 95 additions and 397 deletions

View File

@@ -1,4 +1,8 @@
blank_issues_enabled: false
contact_links:
- name: Eden Discord
url: https://discord.gg/HstXbPch7X
- name: yuzu Discord
url: https://discord.com/invite/u77vRWY
about: If you are experiencing an issue with yuzu, and you need tech support, or if you have a general question, try asking in the official yuzu Discord linked here. Piracy is not allowed.
- name: Community forums
url: https://community.citra-emu.org
about: This is an alternative place for tech support, however helpers there are not as active.

View File

@@ -1,5 +1,6 @@
# Contributing
<!--
SPDX-FileCopyrightText: 2018 yuzu Emulator Project
SPDX-License-Identifier: GPL-2.0-or-later
-->
You want to contribute? Please consult [the development guide](./docs/Development.md).
Don't forget to [get a git account](./docs/SIGNUP.md) - not a requirement per se but it's highly recommended.
**The Contributor's Guide has moved to [the yuzu wiki](https://github.com/yuzu-emu/yuzu/wiki/Contributing).**

View File

@@ -21,7 +21,7 @@ It is written in C++ with portability in mind, and we actively maintain builds f
<p align="center">
</a>
<a href="https://discord.gg/HstXbPch7X">
<a href="https://discord.gg/kXAmGCXBGD">
<img src="https://img.shields.io/discord/1367654015269339267?color=5865F2&label=Eden&logo=discord&logoColor=white"
alt="Discord">
</a>
@@ -52,8 +52,8 @@ Check out our [website](https://eden-emu.dev) for the latest news on exciting fe
## Development
Most of the development happens on our Git server. It is also where [our central repository](https://git.eden-emu.dev/eden-emu/eden) is hosted. For development discussions, please join us on [Discord](https://discord.gg/HstXbPch7X) or [Revolt](https://rvlt.gg/qKgFEAbH).
You can also follow us on [X (Twitter)](https://nitter.poast.org/edenemuofficial) for updates and announcements.
Most of the development happens on our Git server. It is also where [our central repository](https://git.eden-emu.dev/eden-emu/eden) is hosted. For development discussions, please join us on [Discord](https://discord.gg/kXAmGCXBGD) or [Revolt](https://rvlt.gg/qKgFEAbH).
You can also follow us on [X (Twitter)](https://x.com/edenemuofficial) for updates and announcements.
If you would like to contribute, we are open to new developers and pull requests. Please ensure that your work is of a high standard and properly documented. You can also contact any of the developers on Discord or Revolt to learn more about the current state of the emulator.
@@ -82,7 +82,7 @@ Any donations received will go towards things such as:
* Additional hardware (e.g. GPUs as needed to improve rendering support, other peripherals to add support for, etc.)
* CI Infrastructure
If you would prefer to support us in a different way, please join our [Discord](https://discord.gg/HstXbPch7X) and talk to Camille or any of our other developers.
If you would prefer to support us in a different way, please join our [Discord](https://discord.gg/edenemu) and talk to Camille or any of our other developers.
## License

View File

@@ -58,7 +58,7 @@ android {
defaultConfig {
applicationId = "dev.eden.eden_emulator"
minSdk = 23
minSdk = 24
targetSdk = 36
versionName = getGitVersion()
versionCode = autoVersion

View File

@@ -29,7 +29,8 @@ SPDX-License-Identifier: GPL-3.0-or-later
<uses-permission android:name="android.permission.BLUETOOTH_SCAN" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_SPECIAL_USE" />
<uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES" />
<uses-permission android:name="android.permission.BLUETOOTH" android:maxSdkVersion="30" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" android:maxSdkVersion="30" />
<application
android:name="org.yuzu.yuzu_emu.YuzuApplication"
@@ -109,15 +110,5 @@ SPDX-License-Identifier: GPL-3.0-or-later
</intent-filter>
</provider>
<provider
android:name="androidx.core.content.FileProvider"
android:authorities="${applicationId}.provider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/file_paths" />
</provider>
</application>
</manifest>

View File

@@ -222,11 +222,6 @@ object NativeLibrary {
*/
external fun getUpdateUrl(version: String): String
/**
* Return the URL to download the APK for the given version
*/
external fun getUpdateApkUrl(version: String, packageId: String): String
/**
* Returns whether the update checker is enabled through CMAKE options.
*/

View File

@@ -235,13 +235,10 @@ class EmulationActivity : AppCompatActivity(), SensorEventListener {
}
override fun dispatchKeyEvent(event: KeyEvent): Boolean {
val isPhysicalKeyboard = event.source and InputDevice.SOURCE_KEYBOARD == InputDevice.SOURCE_KEYBOARD &&
event.device?.isVirtual == false
if (event.source and InputDevice.SOURCE_JOYSTICK != InputDevice.SOURCE_JOYSTICK &&
event.source and InputDevice.SOURCE_GAMEPAD != InputDevice.SOURCE_GAMEPAD &&
event.source and InputDevice.SOURCE_MOUSE != InputDevice.SOURCE_MOUSE &&
!isPhysicalKeyboard
event.source and InputDevice.SOURCE_KEYBOARD != InputDevice.SOURCE_KEYBOARD &&
event.source and InputDevice.SOURCE_MOUSE != InputDevice.SOURCE_MOUSE
) {
return super.dispatchKeyEvent(event)
}

View File

@@ -762,7 +762,6 @@ abstract class SettingsItem(
SwitchSetting(
BooleanSetting.ENABLE_UPDATE_CHECKS,
titleId = R.string.enable_update_checks,
descriptionId = R.string.enable_update_checks_description,
)
)
put(

View File

@@ -145,12 +145,13 @@ class GamePropertiesFragment : Fragment() {
val seconds = playTimeSeconds % 60
val readablePlayTime = when {
hours > 0 -> "$hours${getString(R.string.hours_abbr)} $minutes${getString(R.string.minutes_abbr)} $seconds${getString(R.string.seconds_abbr)}"
minutes > 0 -> "$minutes${getString(R.string.minutes_abbr)} $seconds${getString(R.string.seconds_abbr)}"
else -> "$seconds${getString(R.string.seconds_abbr)}"
}
hours > 0 -> "${hours}h ${minutes}m ${seconds}s"
minutes > 0 -> "${minutes}m ${seconds}s"
else -> "${seconds}s"
}
append(getString(R.string.playtime) + " " + readablePlayTime)
append(getString(R.string.playtime))
append(readablePlayTime)
}
binding.playtime.setOnClickListener {

View File

@@ -53,16 +53,8 @@ import androidx.core.content.edit
import org.yuzu.yuzu_emu.activities.EmulationActivity
import kotlin.text.compareTo
import androidx.core.net.toUri
import com.google.android.material.progressindicator.LinearProgressIndicator
import com.google.android.material.textview.MaterialTextView
import org.yuzu.yuzu_emu.features.settings.model.BooleanSetting
import org.yuzu.yuzu_emu.YuzuApplication
import org.yuzu.yuzu_emu.updater.APKDownloader
import org.yuzu.yuzu_emu.updater.APKInstaller
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
class MainActivity : AppCompatActivity(), ThemeProvider {
private lateinit var binding: ActivityMainBinding
@@ -194,7 +186,9 @@ class MainActivity : AppCompatActivity(), ThemeProvider {
.setTitle(R.string.update_available)
.setMessage(getString(R.string.update_available_description, version))
.setPositiveButton(android.R.string.ok) { _, _ ->
downloadAndInstallUpdate(version)
val url = NativeLibrary.getUpdateUrl(version)
val intent = Intent(Intent.ACTION_VIEW, url.toUri())
startActivity(intent)
}
.setNeutralButton(R.string.cancel) { dialog, _ ->
dialog.dismiss()
@@ -207,87 +201,6 @@ class MainActivity : AppCompatActivity(), ThemeProvider {
.show()
}
private fun downloadAndInstallUpdate(version: String) {
CoroutineScope(Dispatchers.IO).launch {
val packageId = applicationContext.packageName
val apkUrl = NativeLibrary.getUpdateApkUrl(version, packageId)
val apkFile = File(cacheDir, "update-$version.apk")
withContext(Dispatchers.Main) {
showDownloadProgressDialog()
}
val downloader = APKDownloader(apkUrl, apkFile)
downloader.download(
onProgress = { progress ->
runOnUiThread {
updateDownloadProgress(progress)
}
},
onComplete = { success ->
runOnUiThread {
dismissDownloadProgressDialog()
if (success) {
val installer = APKInstaller(this@MainActivity)
installer.install(
apkFile,
onComplete = {
Toast.makeText(
this@MainActivity,
R.string.update_installed_successfully,
Toast.LENGTH_LONG
).show()
},
onFailure = { exception ->
Toast.makeText(
this@MainActivity,
getString(R.string.update_install_failed, exception.message),
Toast.LENGTH_LONG
).show()
}
)
} else {
Toast.makeText(
this@MainActivity,
getString(R.string.update_download_failed) + "\n\nURL: $apkUrl",
Toast.LENGTH_LONG
).show()
}
}
}
)
}
}
private var progressDialog: androidx.appcompat.app.AlertDialog? = null
private var progressBar: LinearProgressIndicator? = null
private var progressMessage: MaterialTextView? = null
private fun showDownloadProgressDialog() {
val progressView = layoutInflater.inflate(R.layout.dialog_download_progress, null)
progressBar = progressView.findViewById(R.id.download_progress_bar)
progressMessage = progressView.findViewById(R.id.download_progress_message)
progressDialog = MaterialAlertDialogBuilder(this)
.setTitle(R.string.downloading_update)
.setView(progressView)
.setCancelable(false)
.create()
progressDialog?.show()
}
private fun updateDownloadProgress(progress: Int) {
progressBar?.progress = progress
progressMessage?.text = "$progress%"
}
private fun dismissDownloadProgressDialog() {
progressDialog?.dismiss()
progressDialog = null
progressBar = null
progressMessage = null
}
fun displayMultiplayerDialog() {
val dialog = NetPlayDialog(this)

View File

@@ -1,61 +0,0 @@
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
package org.yuzu.yuzu_emu.updater
import okhttp3.Call
import okhttp3.Callback
import okhttp3.OkHttpClient
import okhttp3.Request
import okhttp3.Response
import java.io.File
import java.io.FileOutputStream
import java.io.IOException
class APKDownloader(private val url: String, private val outputFile: File) {
fun download(onProgress: (Int) -> Unit, onComplete: (Boolean) -> Unit) {
val client = OkHttpClient()
val request = Request.Builder().url(url).build()
client.newCall(request).enqueue(object : Callback {
override fun onFailure(call: Call, e: IOException) {
e.printStackTrace()
onComplete(false)
}
override fun onResponse(call: Call, response: Response) {
if (response.isSuccessful) {
response.body?.let { body ->
val contentLength = body.contentLength()
try {
val inputStream = body.byteStream()
val outputStream = FileOutputStream(outputFile)
val buffer = ByteArray(4096)
var bytesRead: Int
var totalBytesRead: Long = 0
while (inputStream.read(buffer).also { bytesRead = it } != -1) {
outputStream.write(buffer, 0, bytesRead)
totalBytesRead += bytesRead
val progress = (totalBytesRead * 100 / contentLength).toInt()
onProgress(progress)
}
outputStream.flush()
outputStream.close()
inputStream.close()
onComplete(true)
} catch (e: IOException) {
e.printStackTrace()
onComplete(false)
}
} ?: run {
onComplete(false)
}
} else {
onComplete(false)
}
}
})
}
}

View File

@@ -1,41 +0,0 @@
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
package org.yuzu.yuzu_emu.updater
import android.content.Context
import android.content.Intent
import android.content.IntentFilter
import android.net.Uri
import androidx.core.content.FileProvider
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.launch
import java.io.File
class APKInstaller(private val context: Context) {
fun install(apkFile: File, onComplete: () -> Unit, onFailure: (Exception) -> Unit) {
try {
val apkUri: Uri = FileProvider.getUriForFile(
context,
context.applicationContext.packageName + ".provider",
apkFile
)
val intent = Intent(Intent.ACTION_VIEW)
intent.setDataAndType(apkUri, "application/vnd.android.package-archive")
intent.flags = Intent.FLAG_GRANT_READ_URI_PERMISSION or Intent.FLAG_ACTIVITY_NEW_TASK
context.startActivity(intent)
GlobalScope.launch {
val receiver = AppInstallReceiver(onComplete, onFailure)
context.registerReceiver(receiver, IntentFilter().apply {
addAction(Intent.ACTION_PACKAGE_ADDED)
addAction(Intent.ACTION_PACKAGE_REPLACED)
addDataScheme("package")
})
}
} catch (e: Exception) {
onFailure(e)
}
}
}

View File

@@ -1,30 +0,0 @@
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
package org.yuzu.yuzu_emu.updater
import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import android.util.Log
class AppInstallReceiver(
private val onComplete: () -> Unit,
private val onFailure: (Exception) -> Unit
) : BroadcastReceiver() {
override fun onReceive(context: Context, intent: Intent) {
val packageName = intent.data?.schemeSpecificPart
when (intent.action) {
Intent.ACTION_PACKAGE_ADDED, Intent.ACTION_PACKAGE_REPLACED -> {
Log.i("AppInstallReceiver", "Package installed or updated: $packageName")
onComplete()
context.unregisterReceiver(this)
}
else -> {
onFailure(Exception("Installation failed for package: $packageName"))
context.unregisterReceiver(this)
}
}
}
}

View File

@@ -1613,37 +1613,6 @@ JNIEXPORT jstring JNICALL Java_org_yuzu_yuzu_1emu_NativeLibrary_getUpdateUrl(
env->ReleaseStringUTFChars(version, version_str);
return env->NewStringUTF(url.c_str());
}
JNIEXPORT jstring JNICALL Java_org_yuzu_yuzu_1emu_NativeLibrary_getUpdateApkUrl(
JNIEnv* env,
jobject obj,
jstring version,
jstring packageId) {
const char* version_str = env->GetStringUTFChars(version, nullptr);
const char* package_id_str = env->GetStringUTFChars(packageId, nullptr);
std::string variant;
std::string package_id(package_id_str);
if (package_id.find("dev.legacy.eden_emulator") != std::string::npos) {
variant = "legacy";
} else if (package_id.find("com.miHoYo.Yuanshen") != std::string::npos) {
variant = "optimized";
} else {
variant = "standard";
}
const std::string apk_filename = fmt::format("Eden-Android-{}-{}.apk", version_str, variant);
const std::string url = fmt::format("{}/{}/releases/download/{}/{}",
std::string{Common::g_build_auto_update_website},
std::string{Common::g_build_auto_update_repo},
version_str,
apk_filename);
env->ReleaseStringUTFChars(version, version_str);
env->ReleaseStringUTFChars(packageId, package_id_str);
return env->NewStringUTF(url.c_str());
}
#endif
JNIEXPORT jstring JNICALL Java_org_yuzu_yuzu_1emu_NativeLibrary_getBuildVersion(

View File

@@ -1,31 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="24dp">
<com.google.android.material.textview.MaterialTextView
android:id="@+id/download_progress_message"
style="@style/TextAppearance.Material3.BodyMedium"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="16dp"
android:text="0%"
android:textAlignment="center"
android:textSize="18sp"
android:textStyle="bold" />
<com.google.android.material.progressindicator.LinearProgressIndicator
android:id="@+id/download_progress_bar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:max="100"
android:progress="0"
app:indicatorColor="?attr/colorPrimary"
app:trackColor="?attr/colorSurfaceVariant"
app:trackCornerRadius="4dp"
app:trackThickness="8dp" />
</LinearLayout>

View File

@@ -271,14 +271,9 @@
<string name="folder">Folder</string>
<string name="dont_show_again">Don\'t Show Again</string>
<string name="add_directory_success">New game directory added successfully </string>
<string name="enable_update_checks">Check for Updates</string>
<string name="enable_update_checks_description">Check for updates on launch, and optionally download and install the new update.</string>
<string name="enable_update_checks">Check for updates on app startup.</string>
<string name="update_available">Update Available</string>
<string name="update_available_description">A new version is available: %1$s\n\nWould you like to download it?</string>
<string name="downloading_update">Downloading Update</string>
<string name="update_download_failed">Failed to download update</string>
<string name="update_installed_successfully">Update installed successfully</string>
<string name="update_install_failed">Failed to install update: %1$s</string>
<string name="home_search">Search</string>
<string name="home_settings">Settings</string>
<string name="empty_gamelist">No files were found or no game directory has been selected yet.</string>
@@ -448,9 +443,9 @@
<string name="user_data_import_success">User data imported successfully</string>
<string name="user_data_export_cancelled">Export cancelled</string>
<string name="user_data_import_failed_description">Make sure the user data folders are at the root of the zip folder and contain a config file at config/config.ini and try again.</string>
<string name="discord_link" translatable="false">https://discord.gg/HstXbPch7X</string>
<string name="discord_link" translatable="false">https://discord.gg/kXAmGCXBGD</string>
<string name="revolt_link" translatable="false">https://rvlt.gg/qKgFEAbH</string>
<string name="x_link" translatable="false">https://nitter.poast.org/edenemuofficial</string>
<string name="x_link" translatable="false">https://x.com/edenemuofficial</string>
<string name="website_link" translatable="false">https://eden-emu.dev</string>
<string name="github_link" translatable="false">https://git.eden-emu.dev/eden-emu</string>
@@ -713,7 +708,7 @@
<string name="copy_details">Copy details</string>
<string name="add_ons">Add-ons</string>
<string name="add_ons_description">Toggle mods, updates and DLC</string>
<string name="playtime">Playtime:</string>
<string name="playtime">Playtime: </string>
<string name="reset_playtime">Clear Playtime</string>
<string name="reset_playtime_description">Reset the current game\'s playtime back to 0 seconds</string>
<string name="reset_playtime_warning_description">This will clear the current game\'s playtime data. Are you sure?</string>
@@ -721,9 +716,6 @@
<string name="edit_playtime">Edit Playtime</string>
<string name="hours">Hours</string>
<string name="minutes">Minutes</string>
<string name="hours_abbr">h</string>
<string name="minutes_abbr">m</string>
<string name="seconds_abbr">s</string>
<string name="hours_must_be_between_0_and_9999">Hours must be between 0 and 9999</string>
<string name="minutes_must_be_between_0_and_59">Minutes must be between 0 and 59</string>
<string name="seconds_must_be_between_0_and_59">Seconds must be between 0 and 59</string>

View File

@@ -1,8 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
<!-- this is required to share files in the app's internal storage -->
<cache-path name="apk_cache" path="." />
<external-cache-path name="external_apk_cache" path="." />
<files-path name="files" path="." />
<external-files-path name="external_files" path="." />
</paths>

View File

@@ -62,41 +62,29 @@ struct DrawParams {
VkViewport GetViewportState(const Device& device, const Maxwell& regs, size_t index, float scale) {
const auto& src = regs.viewport_transform[index];
const auto conv = [scale](float value) {
float new_value = value * scale;
if (scale < 1.0f) {
const bool sign = std::signbit(value);
new_value = std::round(std::abs(new_value));
new_value = sign ? -new_value : new_value;
}
return new_value;
float const new_value = value * scale;
return scale < 1.0f
? std::round(std::abs(new_value)) * (std::signbit(new_value) ? -1.f : 1.f)
: new_value;
};
const float x = conv(src.translate_x - src.scale_x);
const float width = conv(src.scale_x * 2.0f);
float y = conv(src.translate_y - src.scale_y);
float height = conv(src.scale_y * 2.0f);
const bool lower_left = regs.window_origin.mode != Maxwell::WindowOrigin::Mode::UpperLeft;
const bool y_negate = !device.IsNvViewportSwizzleSupported() &&
src.swizzle.y == Maxwell::ViewportSwizzle::NegativeY;
if (lower_left) {
// Flip by surface clip height
y += conv(static_cast<f32>(regs.surface_clip.height));
height = -height;
}
if (y_negate) {
// Flip by viewport height
y += height;
height = -height;
}
const float reduce_z = regs.depth_mode == Maxwell::DepthMode::MinusOneToOne ? 1.0f : 0.0f;
float const w = src.scale_x;
float h = src.scale_y;
if (regs.window_origin.mode == Maxwell::WindowOrigin::Mode::LowerLeft) // Flip by surface clip height
h = -h;
if (!device.IsNvViewportSwizzleSupported() && src.swizzle.y == Maxwell::ViewportSwizzle::NegativeY) // Flip by viewport height
h = -h;
// In theory, a raster flip is equivalent to a texture flip for a whole square viewport
// TODO: one day implement this properly and raster flip the triangles, not the whole viewport... guh
if(regs.viewport_transform[1].scale_y == 0 && regs.window_origin.flip_y != 0)
h = -h;
float const x = src.translate_x - w;
float const y = src.translate_y - h;
float const reduce_z = regs.depth_mode == Maxwell::DepthMode::MinusOneToOne ? 1.0f : 0.0f;
VkViewport viewport{
.x = x,
.y = y,
.width = width != 0.0f ? width : 1.0f,
.height = height != 0.0f ? height : 1.0f,
.x = conv(x),
.y = conv(y),
.width = w != 0.0f ? conv(w * 2.f) : 1.0f,
.height = h != 0.0f ? conv(h * 2.f) : 1.0f,
.minDepth = src.translate_z - src.scale_z * reduce_z,
.maxDepth = src.translate_z + src.scale_z,
};
@@ -1026,10 +1014,10 @@ void RasterizerVulkan::UpdateViewportsState(Tegra::Engines::Maxwell3D::Regs& reg
return;
}
if (!regs.viewport_scale_offset_enabled) {
float x = static_cast<float>(regs.surface_clip.x);
float y = static_cast<float>(regs.surface_clip.y);
float width = (std::max)(1.0f, static_cast<float>(regs.surface_clip.width));
float height = (std::max)(1.0f, static_cast<float>(regs.surface_clip.height));
float x = float(regs.surface_clip.x);
float y = float(regs.surface_clip.y);
float width = (std::max)(1.0f, float(regs.surface_clip.width));
float height = (std::max)(1.0f, float(regs.surface_clip.height));
if (regs.window_origin.mode != Maxwell::WindowOrigin::Mode::UpperLeft) {
y += height;
height = -height;

View File

@@ -287,10 +287,10 @@ void Scheduler::EndRenderPass()
for (size_t i = 0; i < num_images; ++i) {
const VkImageSubresourceRange& range = ranges[i];
const bool is_color = (range.aspectMask & VK_IMAGE_ASPECT_COLOR_BIT) != 0;
const bool is_depth_stencil = (range.aspectMask
const bool is_color = range.aspectMask & VK_IMAGE_ASPECT_COLOR_BIT;
const bool is_depth_stencil = range.aspectMask
& (VK_IMAGE_ASPECT_DEPTH_BIT
| VK_IMAGE_ASPECT_STENCIL_BIT)) !=0;
| VK_IMAGE_ASPECT_STENCIL_BIT);
VkAccessFlags src_access = 0;
VkPipelineStageFlags this_stage = 0;
@@ -326,19 +326,14 @@ void Scheduler::EndRenderPass()
};
}
// Graft: ensure explicit fragment tests + color output stages are always synchronized (AMD/Windows fix)
src_stages |= VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT |
VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT |
VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
cmdbuf.EndRenderPass();
cmdbuf.PipelineBarrier(src_stages,
VK_PIPELINE_STAGE_ALL_COMMANDS_BIT,
0,
nullptr,
nullptr,
vk::Span(barriers.data(), num_images) // Batched image barriers
{},
{},
{barriers.data(), num_images} // Batched image barriers
);
});

View File

@@ -712,6 +712,9 @@ Device::~Device() {
VkFormat Device::GetSupportedFormat(VkFormat wanted_format, VkFormatFeatureFlags wanted_usage,
FormatType format_type) const {
if (wanted_format == VK_FORMAT_D24_UNORM_S8_UINT) {
return VK_FORMAT_D32_SFLOAT_S8_UINT;
}
if (IsFormatSupported(wanted_format, wanted_usage, format_type)) {
return wanted_format;
}

View File

@@ -128,7 +128,7 @@ li.checked::marker { content: &quot;\2612&quot;; }
<item>
<widget class="QLabel" name="labelLinks">
<property name="text">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;a href=&quot;https://eden-emulator.github.io/&quot;&gt;&lt;span style=&quot; text-decoration: underline; color:#039be5;&quot;&gt;Website&lt;/span&gt;&lt;/a&gt; | &lt;a href=&quot;https://git.eden-emu.dev&quot;&gt;&lt;span style=&quot; text-decoration: underline; color:#039be5;&quot;&gt;Source Code&lt;/span&gt;&lt;/a&gt; | &lt;a href=&quot;https://git.eden-emu.dev/eden-emu/eden/activity/contributors&quot;&gt;&lt;span style=&quot; text-decoration: underline; color:#039be5;&quot;&gt;Contributors&lt;/span&gt;&lt;/a&gt; | &lt;a href=&quot;https://discord.gg/HstXbPch7X&quot;&gt;&lt;span style=&quot; text-decoration: underline; color:#039be5;&quot;&gt;Discord&lt;/span&gt;&lt;/a&gt; | &lt;a href=&quot;https://rvlt.gg/qKgFEAbH&quot;&gt;&lt;span style=&quot; text-decoration: underline; color:#039be5;&quot;&gt;Revolt&lt;/span&gt;&lt;/a&gt; | &lt;a href=&quot;https://nitter.poast.org/edenemuofficial&quot;&gt;&lt;span style=&quot; text-decoration: underline; color:#039be5;&quot;&gt;Twitter&lt;/span&gt;&lt;/a&gt; | &lt;a href=&quot;https://git.eden-emu.dev/eden-emu/eden/src/branch/master/LICENSE.txt&quot;&gt;&lt;span style=&quot; text-decoration: underline; color:#039be5;&quot;&gt;License&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;a href=&quot;https://eden-emulator.github.io/&quot;&gt;&lt;span style=&quot; text-decoration: underline; color:#039be5;&quot;&gt;Website&lt;/span&gt;&lt;/a&gt; | &lt;a href=&quot;https://git.eden-emu.dev&quot;&gt;&lt;span style=&quot; text-decoration: underline; color:#039be5;&quot;&gt;Source Code&lt;/span&gt;&lt;/a&gt; | &lt;a href=&quot;https://git.eden-emu.dev/eden-emu/eden/activity/contributors&quot;&gt;&lt;span style=&quot; text-decoration: underline; color:#039be5;&quot;&gt;Contributors&lt;/span&gt;&lt;/a&gt; | &lt;a href=&quot;https://discord.gg/kXAmGCXBGD&quot;&gt;&lt;span style=&quot; text-decoration: underline; color:#039be5;&quot;&gt;Discord&lt;/span&gt;&lt;/a&gt; | &lt;a href=&quot;https://rvlt.gg/qKgFEAbH&quot;&gt;&lt;span style=&quot; text-decoration: underline; color:#039be5;&quot;&gt;Revolt&lt;/span&gt;&lt;/a&gt; | &lt;a href=&quot;https://nitter.poast.org/edenemuofficial&quot;&gt;&lt;span style=&quot; text-decoration: underline; color:#039be5;&quot;&gt;Twitter&lt;/span&gt;&lt;/a&gt; | &lt;a href=&quot;https://git.eden-emu.dev/eden-emu/eden/src/branch/master/LICENSE.txt&quot;&gt;&lt;span style=&quot; text-decoration: underline; color:#039be5;&quot;&gt;License&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="openExternalLinks">
<bool>true</bool>

View File

@@ -83,6 +83,14 @@ ConfigureMotionTouch::ConfigureMotionTouch(QWidget* parent,
: QDialog(parent), input_subsystem{input_subsystem_},
ui(std::make_unique<Ui::ConfigureMotionTouch>()) {
ui->setupUi(this);
ui->udp_learn_more->setOpenExternalLinks(true);
ui->udp_learn_more->setText(
tr("<a "
"href='https://eden-emulator.github.io/wiki/"
"using-a-controller-or-android-phone-for-motion-or-touch-input'><span "
"style=\"text-decoration: underline; color:#039be5;\">Learn More</span></a>"));
SetConfiguration();
UpdateUiDisplay();
ConnectEvents();

View File

@@ -182,6 +182,13 @@
<property name="rightMargin">
<number>0</number>
</property>
<item>
<widget class="QLabel" name="udp_learn_more">
<property name="text">
<string>Learn More</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="udp_test">
<property name="sizePolicy">

View File

@@ -14,7 +14,7 @@
<item row="0" column="0" colspan="4">
<widget class="QLabel" name="label_1">
<property name="text">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Reads controller input from scripts in the same format as TAS-nx scripts.&lt;br/&gt;For a more detailed explanation, please consult the user handbook.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Reads controller input from scripts in the same format as TAS-nx scripts.&lt;br/&gt;For a more detailed explanation, please consult the &lt;a href=&quot;https://eden-emulator.github.io/help/feature/tas/&quot;&gt;&lt;span style=&quot; text-decoration: underline; color:#039be5;&quot;&gt;help page&lt;/span&gt;&lt;/a&gt; on the Eden website.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="openExternalLinks">
<bool>true</bool>

View File

@@ -577,7 +577,10 @@ MainWindow::MainWindow(bool has_broken_vulkan)
UISettings::values.has_broken_vulkan = true;
QMessageBox::warning(this, tr("Broken Vulkan Installation Detected"),
tr("Vulkan initialization failed during boot."));
tr("Vulkan initialization failed during boot.<br><br>Click <a "
"href='https://eden-emulator.github.io/wiki/faq/"
"#yuzu-starts-with-the-error-broken-vulkan-installation-detected'>"
"here for instructions to fix the issue</a>."));
#ifdef HAS_OPENGL
Settings::values.renderer_backend = Settings::RendererBackend::OpenGL;
@@ -1910,8 +1913,10 @@ bool MainWindow::LoadROM(const QString& filename, Service::AM::FrontendAppletPar
tr("You are using the deconstructed ROM directory format for this game, which is an "
"outdated format that has been superseded by others such as NCA, NAX, XCI, or "
"NSP. Deconstructed ROM directories lack icons, metadata, and update "
"support.<br>For an explanation of the various Switch formats Eden supports, "
"out our user handbook. This message will not be shown again."));
"support.<br><br>For an explanation of the various Switch formats Eden supports, <a "
"href='https://eden-emulator.github.io/wiki/overview-of-switch-game-formats'>check "
"out our "
"wiki</a>. This message will not be shown again."));
}
if (result != Core::SystemResultStatus::Success) {
@@ -2733,12 +2738,13 @@ void MainWindow::OnGameListNavigateToGamedbEntry(u64 program_id,
directory = it->second.second;
}
QDesktopServices::openUrl(QUrl(QStringLiteral("https://www.emuready.com/listings?emulatorIds=43bfc023-ec22-422d-8324-048a8ec9f28f") + directory));
QDesktopServices::openUrl(
QUrl(QStringLiteral("https://eden-emulator.github.io/game/") + directory));
}
void MainWindow::OnGameListCreateShortcut(u64 program_id, const std::string& game_path,
const QtCommon::Game::ShortcutTarget target) {
// Create shortcu
// Create shortcut
std::string arguments = fmt::format("-g \"{:s}\"", game_path);
QtCommon::Game::CreateShortcut(game_path, program_id, "", target, arguments, true);