Compare commits

...

4 Commits

Author SHA1 Message Date
lizzie cbb74b3e70 fix
Signed-off-by: lizzie <lizzie@eden-emu.dev>
2026-05-19 04:28:22 +00:00
lizzie 7da774f766 [hle] make HBLoader work
Signed-off-by: lizzie <lizzie@eden-emu.dev>
2026-05-19 04:16:52 +00:00
lizzie e875a3196b [core/hle/services/sockets] allow 'valid' range from [16,255] for IPv4 (#3491)
Signed-off-by: lizzie <lizzie@eden-emu.dev>
Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/3491
Reviewed-by: Maufeat <sahyno1996@gmail.com>
Reviewed-by: CamilleLaVey <camillelavey99@gmail.com>
2026-05-18 23:54:47 +02:00
lizzie 4eb082485d [video_core] fix odr violation in formatter for pixelFormat (#3504)
Signed-off-by: lizzie <lizzie@eden-emu.dev>
Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/3504
Reviewed-by: crueter <crueter@eden-emu.dev>
Reviewed-by: CamilleLaVey <camillelavey99@gmail.com>
2026-05-18 23:54:07 +02:00
9 changed files with 46 additions and 19 deletions
+8
View File
@@ -9,3 +9,11 @@ At the moment of writing, we do not support CFW such as Atmosphere, due to:
We do however, maintain HLE compatibility with the former mentioned CFW, applications that require Atmosphere to run will run fine in the emulator without any adjustments. We do however, maintain HLE compatibility with the former mentioned CFW, applications that require Atmosphere to run will run fine in the emulator without any adjustments.
If they don't run - then that's a bug! If they don't run - then that's a bug!
## Atmosphere
Fusee Galee, the bootloader and other low-level mechanisms are not emulated at the moment.
Having OFW is recommended, but may not be required (untested).
Extract the contents of Atmosphere into `sdmc`. Then to launch simply use `-hlaunch` instead (orthogonal to `-qlaunch`).
+3
View File
@@ -10,6 +10,9 @@ There are two main applications, an SDL-based app (`eden-cli`) and a Qt based ap
- `-u <number>`: Select the index of the user to load as. - `-u <number>`: Select the index of the user to load as.
- `-input-profile <name>`: Specifies input profile name to use (for player #0 only). - `-input-profile <name>`: Specifies input profile name to use (for player #0 only).
- `-qlaunch`: Launch QLaunch. - `-qlaunch`: Launch QLaunch.
- `-hlaunch`: Launch homebrew launcher `nx-hbloader`.
- Requires a copy of Atmosphere to be extracted onto `sdmc`.
- This is a shorthand for `<eden folder>/sdmc/atmosphere/hbl.nsp`.
- `-setup`: Launch setup applet. - `-setup`: Launch setup applet.
## eden-cli ## eden-cli
+5 -1
View File
@@ -1,3 +1,6 @@
// SPDX-FileCopyrightText: Copyright 2026 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
@@ -268,7 +271,8 @@ Result KCapabilities::SetHandleTableCapability(const u32 cap) {
Result KCapabilities::SetDebugFlagsCapability(const u32 cap) { Result KCapabilities::SetDebugFlagsCapability(const u32 cap) {
// Validate. // Validate.
const DebugFlags pack{cap}; const DebugFlags pack{cap};
R_UNLESS(pack.reserved == 0, ResultReservedUsed); // TODO: Enabling this breaks compatibility with HBloader and such
//R_UNLESS(pack.reserved == 0, ResultReservedUsed);
DebugFlags debug_capabilities{m_debug_capabilities}; DebugFlags debug_capabilities{m_debug_capabilities};
debug_capabilities.allow_debug.Assign(pack.allow_debug); debug_capabilities.allow_debug.Assign(pack.allow_debug);
+4 -4
View File
@@ -629,7 +629,7 @@ Errno BSD::BindImpl(s32 fd, std::span<const u8> addr) {
if (!IsFileDescriptorValid(fd)) { if (!IsFileDescriptorValid(fd)) {
return Errno::BADF; return Errno::BADF;
} }
ASSERT(addr.size() == sizeof(SockAddrIn)); ASSERT(addr.size() >= 16);
auto addr_in = GetValue<SockAddrIn>(addr); auto addr_in = GetValue<SockAddrIn>(addr);
return Translate(file_descriptors[fd]->socket->Bind(Translate(addr_in))); return Translate(file_descriptors[fd]->socket->Bind(Translate(addr_in)));
@@ -640,7 +640,7 @@ Errno BSD::ConnectImpl(s32 fd, std::span<const u8> addr) {
return Errno::BADF; return Errno::BADF;
} }
UNIMPLEMENTED_IF(addr.size() != sizeof(SockAddrIn)); ASSERT(addr.size() >= 16);
auto addr_in = GetValue<SockAddrIn>(addr); auto addr_in = GetValue<SockAddrIn>(addr);
const Errno result = Translate(file_descriptors[fd]->socket->Connect(Translate(addr_in))); const Errno result = Translate(file_descriptors[fd]->socket->Connect(Translate(addr_in)));
@@ -874,7 +874,7 @@ std::pair<s32, Errno> BSD::RecvFromImpl(s32 fd, u32 flags, std::vector<u8>& mess
if (ret < 0) { if (ret < 0) {
addr.clear(); addr.clear();
} else { } else {
ASSERT(addr.size() == sizeof(SockAddrIn)); ASSERT(addr.size() >= 16);
const SockAddrIn result = Translate(addr_in); const SockAddrIn result = Translate(addr_in);
PutValue(addr, result); PutValue(addr, result);
} }
@@ -899,7 +899,7 @@ std::pair<s32, Errno> BSD::SendToImpl(s32 fd, u32 flags, std::span<const u8> mes
Network::SockAddrIn addr_in; Network::SockAddrIn addr_in;
Network::SockAddrIn* p_addr_in = nullptr; Network::SockAddrIn* p_addr_in = nullptr;
if (!addr.empty()) { if (!addr.empty()) {
ASSERT(addr.size() == sizeof(SockAddrIn)); ASSERT(addr.size() >= 16);
auto guest_addr_in = GetValue<SockAddrIn>(addr); auto guest_addr_in = GetValue<SockAddrIn>(addr);
addr_in = Translate(guest_addr_in); addr_in = Translate(guest_addr_in);
p_addr_in = &addr_in; p_addr_in = &addr_in;
+1 -1
View File
@@ -238,7 +238,7 @@ static std::vector<u8> SerializeAddrInfo(const std::vector<Network::AddrInfo>& v
Append<u32_be>(data, static_cast<u32>(Translate(addrinfo.family))); // ai_family Append<u32_be>(data, static_cast<u32>(Translate(addrinfo.family))); // ai_family
Append<u32_be>(data, static_cast<u32>(Translate(addrinfo.socket_type))); // ai_socktype Append<u32_be>(data, static_cast<u32>(Translate(addrinfo.socket_type))); // ai_socktype
Append<u32_be>(data, static_cast<u32>(Translate(addrinfo.protocol))); // ai_protocol Append<u32_be>(data, static_cast<u32>(Translate(addrinfo.protocol))); // ai_protocol
Append<u32_be>(data, sizeof(SockAddrIn)); // ai_addrlen Append<u32_be>(data, 16); // ai_addrlen
// ^ *not* sizeof(SerializedSockAddrIn), not that it matters since they're the same size // ^ *not* sizeof(SerializedSockAddrIn), not that it matters since they're the same size
// ai_addr: // ai_addr:
+2 -1
View File
@@ -110,8 +110,9 @@ struct SockAddrIn {
u8 family; u8 family;
u16 portno; u16 portno;
std::array<u8, 4> ip; std::array<u8, 4> ip;
std::array<u8, 8> zeroes; std::array<u8, 248> zeroes;
}; };
static_assert(sizeof(SockAddrIn) == 0x100);
enum class PollEvents : u16 { enum class PollEvents : u16 {
// Using Pascal case because IN is a macro on Windows. // Using Pascal case because IN is a macro on Windows.
@@ -265,13 +265,9 @@ PollEvents Translate(Network::PollEvents flags) {
} }
Network::SockAddrIn Translate(SockAddrIn value) { Network::SockAddrIn Translate(SockAddrIn value) {
if (value.len != 0 && value.len != sizeof(value) && value.len != 6) { // All lengths are valid, from [0 upto 256]
LOG_WARNING(Service, "Unexpected SockAddrIn len={}, expected 0, {}, or 6",
value.len, sizeof(value));
}
return { return {
.family = Translate(static_cast<Domain>(value.family)), .family = Translate(Domain(value.family)),
.ip = value.ip, .ip = value.ip,
.portno = static_cast<u16>(value.portno >> 8 | value.portno << 8), .portno = static_cast<u16>(value.portno >> 8 | value.portno << 8),
}; };
@@ -279,7 +275,7 @@ Network::SockAddrIn Translate(SockAddrIn value) {
SockAddrIn Translate(Network::SockAddrIn value) { SockAddrIn Translate(Network::SockAddrIn value) {
return { return {
.len = sizeof(SockAddrIn), .len = 16,
.family = static_cast<u8>(Translate(value.family)), .family = static_cast<u8>(Translate(value.family)),
.portno = static_cast<u16>(value.portno >> 8 | value.portno << 8), .portno = static_cast<u16>(value.portno >> 8 | value.portno << 8),
.ip = value.ip, .ip = value.ip,
+10 -1
View File
@@ -5,6 +5,8 @@
#pragma once #pragma once
#undef PIXEL_FORMAT_LIST
#include <climits> #include <climits>
#include <utility> #include <utility>
#include "common/assert.h" #include "common/assert.h"
@@ -128,7 +130,7 @@ namespace VideoCore::Surface {
PIXEL_FORMAT_ELEM(S8_UINT_D24_UNORM, 1, 1, 32) \ PIXEL_FORMAT_ELEM(S8_UINT_D24_UNORM, 1, 1, 32) \
PIXEL_FORMAT_ELEM(D32_FLOAT_S8_UINT, 1, 1, 64) PIXEL_FORMAT_ELEM(D32_FLOAT_S8_UINT, 1, 1, 64)
enum class PixelFormat { enum class PixelFormat : u32 {
#define PIXEL_FORMAT_ELEM(name, ...) name, #define PIXEL_FORMAT_ELEM(name, ...) name,
PIXEL_FORMAT_LIST PIXEL_FORMAT_LIST
#undef PIXEL_FORMAT_ELEM #undef PIXEL_FORMAT_ELEM
@@ -192,6 +194,13 @@ constexpr u32 BytesPerBlock(PixelFormat pixel_format) {
return BitsPerBlock(pixel_format) / CHAR_BIT; return BitsPerBlock(pixel_format) / CHAR_BIT;
} }
}
#include "video_core/gpu.h"
#include "video_core/textures/texture.h"
namespace VideoCore::Surface {
SurfaceTarget SurfaceTargetFromTextureType(Tegra::Texture::TextureType texture_type); SurfaceTarget SurfaceTargetFromTextureType(Tegra::Texture::TextureType texture_type);
bool SurfaceTargetIsLayered(SurfaceTarget target); bool SurfaceTargetIsLayered(SurfaceTarget target);
bool SurfaceTargetIsArray(SurfaceTarget target); bool SurfaceTargetIsArray(SurfaceTarget target);
+10 -4
View File
@@ -3,6 +3,7 @@
// Qt on macOS doesn't define VMA shit // Qt on macOS doesn't define VMA shit
#include <boost/algorithm/string/split.hpp> #include <boost/algorithm/string/split.hpp>
#include "common/fs/path_util.h"
#include "common/settings.h" #include "common/settings.h"
#include "common/settings_enums.h" #include "common/settings_enums.h"
#include "frontend_common/settings_generator.h" #include "frontend_common/settings_generator.h"
@@ -635,6 +636,7 @@ MainWindow::MainWindow(bool has_broken_vulkan)
QString game_path; QString game_path;
bool should_launch_qlaunch = false; bool should_launch_qlaunch = false;
bool should_launch_hlaunch = false;
bool should_launch_setup = false; bool should_launch_setup = false;
bool has_gamepath = false; bool has_gamepath = false;
bool is_fullscreen = false; bool is_fullscreen = false;
@@ -676,6 +678,8 @@ MainWindow::MainWindow(bool has_broken_vulkan)
players[0].profile_name = args[++i].toStdString(); players[0].profile_name = args[++i].toStdString();
} else if (args[i] == QStringLiteral("-qlaunch")) { } else if (args[i] == QStringLiteral("-qlaunch")) {
should_launch_qlaunch = true; should_launch_qlaunch = true;
} else if (args[i] == QStringLiteral("-hlaunch")) {
should_launch_hlaunch = true;
} else if (args[i] == QStringLiteral("-setup")) { } else if (args[i] == QStringLiteral("-setup")) {
should_launch_setup = true; should_launch_setup = true;
} else { } else {
@@ -694,10 +698,12 @@ MainWindow::MainWindow(bool has_broken_vulkan)
} else { } else {
if (!game_path.isEmpty()) { if (!game_path.isEmpty()) {
BootGame(game_path, ApplicationAppletParameters()); BootGame(game_path, ApplicationAppletParameters());
} else { } else if (should_launch_qlaunch) {
if (should_launch_qlaunch) { LaunchFirmwareApplet(u64(Service::AM::AppletProgramId::QLaunch), std::nullopt);
LaunchFirmwareApplet(u64(Service::AM::AppletProgramId::QLaunch), std::nullopt); } else if (should_launch_hlaunch) {
} std::filesystem::path const sd_dir = Common::FS::GetEdenPathString(Common::FS::EdenPath::SDMCDir);
auto const hbl_path = (sd_dir / "atmosphere" / "hbl.nsp").string();
BootGame(QString::fromStdString(hbl_path), ApplicationAppletParameters());
} }
} }
} }