mirror of
https://git.eden-emu.dev/eden-emu/eden.git
synced 2026-08-15 13:16:43 +00:00
Compare commits
4 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| cbb74b3e70 | |||
| 7da774f766 | |||
| e875a3196b | |||
| 4eb082485d |
@@ -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`).
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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:
|
||||||
|
|||||||
@@ -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,
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user