mirror of
https://git.eden-emu.dev/eden-emu/eden.git
synced 2026-09-26 03:01:17 +00:00
Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 0eca53dc6b |
@@ -137,6 +137,11 @@ add_library(
|
||||
uuid.cpp
|
||||
uuid.h
|
||||
vector_math.h
|
||||
zbic_compression.cpp
|
||||
zbic_compression.h
|
||||
zstd.c
|
||||
zstd.h
|
||||
zstd_errors.h
|
||||
zstd_compression.cpp
|
||||
zstd_compression.h
|
||||
fs/ryujinx_compat.h fs/ryujinx_compat.cpp
|
||||
@@ -241,6 +246,7 @@ endif()
|
||||
|
||||
target_link_libraries(common PUBLIC fmt::fmt stb::headers Threads::Threads)
|
||||
target_link_libraries(common PRIVATE lz4::lz4 zstd::zstd)
|
||||
target_compile_definitions(common PRIVATE ZSTD_ZBIC_SUPPORT=1)
|
||||
|
||||
# Please refer to src/common/demangle.cpp
|
||||
if (WIN32)
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
#include <cstring>
|
||||
|
||||
#include "common/zbic_compression.h"
|
||||
#include "common/zstd.h"
|
||||
|
||||
namespace Common::Compression {
|
||||
|
||||
bool IsZBIC(const void* src, size_t src_size) {
|
||||
if (!src || src_size < 4) {
|
||||
return false;
|
||||
}
|
||||
u32 magic = 0;
|
||||
std::memcpy(&magic, src, sizeof(u32));
|
||||
return magic == ZSTD_MAGICNUMBER; // 0x4349425A ("ZBIC")
|
||||
}
|
||||
|
||||
int DecompressDataZBIC(void* dst, size_t dst_size, const void* src, size_t src_size) {
|
||||
if (!dst || !src || dst_size == 0 || src_size == 0) {
|
||||
return -1;
|
||||
}
|
||||
const size_t res = ZSTD_decompress(dst, dst_size, src, src_size);
|
||||
if (ZSTD_isError(res)) {
|
||||
return -1;
|
||||
}
|
||||
return static_cast<int>(res);
|
||||
}
|
||||
|
||||
std::vector<u8> DecompressDataZBIC(std::span<const u8> compressed, std::size_t uncompressed_size) {
|
||||
std::vector<u8> uncompressed(uncompressed_size);
|
||||
const int r = DecompressDataZBIC(uncompressed.data(), uncompressed_size, compressed.data(), compressed.size());
|
||||
if (r <= 0) {
|
||||
return {};
|
||||
}
|
||||
if (static_cast<size_t>(r) < uncompressed_size) {
|
||||
uncompressed.resize(static_cast<size_t>(r));
|
||||
}
|
||||
return uncompressed;
|
||||
}
|
||||
|
||||
} // namespace Common::Compression
|
||||
@@ -0,0 +1,18 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <span>
|
||||
#include <vector>
|
||||
#include "common/common_types.h"
|
||||
|
||||
namespace Common::Compression {
|
||||
|
||||
[[nodiscard]] bool IsZBIC(const void* src, size_t src_size);
|
||||
|
||||
[[nodiscard]] std::vector<u8> DecompressDataZBIC(std::span<const u8> compressed, std::size_t uncompressed_size);
|
||||
|
||||
[[nodiscard]] int DecompressDataZBIC(void* dst, size_t dst_size, const void* src, size_t src_size);
|
||||
|
||||
} // namespace Common::Compression
|
||||
+52650
File diff suppressed because it is too large
Load Diff
+3209
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,107 @@
|
||||
/*
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under both the BSD-style license (found in the
|
||||
* LICENSE file in the root directory of this source tree) and the GPLv2 (found
|
||||
* in the COPYING file in the root directory of this source tree).
|
||||
* You may select, at your option, one of the above-listed licenses.
|
||||
*/
|
||||
|
||||
#ifndef ZSTD_ERRORS_H_398273423
|
||||
#define ZSTD_ERRORS_H_398273423
|
||||
|
||||
#if defined (__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* ===== ZSTDERRORLIB_API : control library symbols visibility ===== */
|
||||
#ifndef ZSTDERRORLIB_VISIBLE
|
||||
/* Backwards compatibility with old macro name */
|
||||
# ifdef ZSTDERRORLIB_VISIBILITY
|
||||
# define ZSTDERRORLIB_VISIBLE ZSTDERRORLIB_VISIBILITY
|
||||
# elif defined(__GNUC__) && (__GNUC__ >= 4) && !defined(__MINGW32__)
|
||||
# define ZSTDERRORLIB_VISIBLE __attribute__ ((visibility ("default")))
|
||||
# else
|
||||
# define ZSTDERRORLIB_VISIBLE
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifndef ZSTDERRORLIB_HIDDEN
|
||||
# if defined(__GNUC__) && (__GNUC__ >= 4) && !defined(__MINGW32__)
|
||||
# define ZSTDERRORLIB_HIDDEN __attribute__ ((visibility ("hidden")))
|
||||
# else
|
||||
# define ZSTDERRORLIB_HIDDEN
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if defined(ZSTD_DLL_EXPORT) && (ZSTD_DLL_EXPORT==1)
|
||||
# define ZSTDERRORLIB_API __declspec(dllexport) ZSTDERRORLIB_VISIBLE
|
||||
#elif defined(ZSTD_DLL_IMPORT) && (ZSTD_DLL_IMPORT==1)
|
||||
# define ZSTDERRORLIB_API __declspec(dllimport) ZSTDERRORLIB_VISIBLE /* It isn't required but allows to generate better code, saving a function pointer load from the IAT and an indirect jump.*/
|
||||
#else
|
||||
# define ZSTDERRORLIB_API ZSTDERRORLIB_VISIBLE
|
||||
#endif
|
||||
|
||||
/*-*********************************************
|
||||
* Error codes list
|
||||
*-*********************************************
|
||||
* Error codes _values_ are pinned down since v1.3.1 only.
|
||||
* Therefore, don't rely on values if you may link to any version < v1.3.1.
|
||||
*
|
||||
* Only values < 100 are considered stable.
|
||||
*
|
||||
* note 1 : this API shall be used with static linking only.
|
||||
* dynamic linking is not yet officially supported.
|
||||
* note 2 : Prefer relying on the enum than on its value whenever possible
|
||||
* This is the only supported way to use the error list < v1.3.1
|
||||
* note 3 : ZSTD_isError() is always correct, whatever the library version.
|
||||
**********************************************/
|
||||
typedef enum {
|
||||
ZSTD_error_no_error = 0,
|
||||
ZSTD_error_GENERIC = 1,
|
||||
ZSTD_error_prefix_unknown = 10,
|
||||
ZSTD_error_version_unsupported = 12,
|
||||
ZSTD_error_frameParameter_unsupported = 14,
|
||||
ZSTD_error_frameParameter_windowTooLarge = 16,
|
||||
ZSTD_error_corruption_detected = 20,
|
||||
ZSTD_error_checksum_wrong = 22,
|
||||
ZSTD_error_literals_headerWrong = 24,
|
||||
ZSTD_error_dictionary_corrupted = 30,
|
||||
ZSTD_error_dictionary_wrong = 32,
|
||||
ZSTD_error_dictionaryCreation_failed = 34,
|
||||
ZSTD_error_parameter_unsupported = 40,
|
||||
ZSTD_error_parameter_combination_unsupported = 41,
|
||||
ZSTD_error_parameter_outOfBound = 42,
|
||||
ZSTD_error_tableLog_tooLarge = 44,
|
||||
ZSTD_error_maxSymbolValue_tooLarge = 46,
|
||||
ZSTD_error_maxSymbolValue_tooSmall = 48,
|
||||
ZSTD_error_cannotProduce_uncompressedBlock = 49,
|
||||
ZSTD_error_stabilityCondition_notRespected = 50,
|
||||
ZSTD_error_stage_wrong = 60,
|
||||
ZSTD_error_init_missing = 62,
|
||||
ZSTD_error_memory_allocation = 64,
|
||||
ZSTD_error_workSpace_tooSmall= 66,
|
||||
ZSTD_error_dstSize_tooSmall = 70,
|
||||
ZSTD_error_srcSize_wrong = 72,
|
||||
ZSTD_error_dstBuffer_null = 74,
|
||||
ZSTD_error_noForwardProgress_destFull = 80,
|
||||
ZSTD_error_noForwardProgress_inputEmpty = 82,
|
||||
/* following error codes are __NOT STABLE__, they can be removed or changed in future versions */
|
||||
ZSTD_error_frameIndex_tooLarge = 100,
|
||||
ZSTD_error_seekableIO = 102,
|
||||
ZSTD_error_dstBuffer_wrong = 104,
|
||||
ZSTD_error_srcBuffer_wrong = 105,
|
||||
ZSTD_error_sequenceProducer_failed = 106,
|
||||
ZSTD_error_externalSequences_invalid = 107,
|
||||
ZSTD_error_maxCode = 120 /* never EVER use this value directly, it can change in future versions! Use ZSTD_isError() instead */
|
||||
} ZSTD_ErrorCode;
|
||||
|
||||
ZSTDERRORLIB_API const char* ZSTD_getErrorString(ZSTD_ErrorCode code); /**< Same as ZSTD_getErrorName, but using a `ZSTD_ErrorCode` enum argument */
|
||||
|
||||
|
||||
#if defined (__cplusplus)
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* ZSTD_ERRORS_H_398273423 */
|
||||
@@ -94,7 +94,7 @@ LaunchParams ParseLaunchParams(Core::System& system, int argc, char *argv[], wch
|
||||
break;
|
||||
case 'u': {
|
||||
// Launch game with a specific user
|
||||
bool argument_ok = bool(isdigit(optarg[0]));
|
||||
bool argument_ok = isdigit(optarg[0]);
|
||||
p.selected_user = atoi(optarg);
|
||||
if (!argument_ok) {
|
||||
// try to look it up by username, only finds the first username that matches.
|
||||
|
||||
+32
-4
@@ -13,6 +13,7 @@
|
||||
#include "common/hex_util.h"
|
||||
#include "common/logging.h"
|
||||
#include "common/lz4_compression.h"
|
||||
#include "common/zbic_compression.h"
|
||||
#include "common/settings.h"
|
||||
#include "common/swap.h"
|
||||
#include "core/core.h"
|
||||
@@ -104,11 +105,38 @@ std::optional<VAddr> AppLoader_NSO::LoadModule(Kernel::KProcess& process, Core::
|
||||
for (std::size_t i = 0; i < nso_header.segments.size(); ++i) {
|
||||
nso_file.Read(compressed_data.data(), nso_header.segments_compressed_size[i], nso_header.segments[i].offset);
|
||||
if (nso_header.IsSegmentCompressed(i)) {
|
||||
int r = Common::Compression::DecompressDataLZ4(decompressed_size.data(), nso_header.segments[i].size, compressed_data.data(), nso_header.segments_compressed_size[i]);
|
||||
ASSERT(r == int(nso_header.segments[i].size));
|
||||
std::memcpy(codeset.memory.data() + module_start + nso_header.segments[i].location, decompressed_size.data(), nso_header.segments[i].size);
|
||||
if (nso_header.IsZBICCompressed()) {
|
||||
// ZBIC compression
|
||||
const int r = Common::Compression::DecompressDataZBIC(
|
||||
decompressed_size.data(),
|
||||
nso_header.segments[i].size,
|
||||
compressed_data.data(),
|
||||
nso_header.segments_compressed_size[i]
|
||||
);
|
||||
ASSERT(r > 0);
|
||||
} else {
|
||||
// LZ4 compression
|
||||
int r = Common::Compression::DecompressDataLZ4(
|
||||
decompressed_size.data(),
|
||||
nso_header.segments[i].size,
|
||||
compressed_data.data(),
|
||||
nso_header.segments_compressed_size[i]
|
||||
);
|
||||
ASSERT(r == int(nso_header.segments[i].size));
|
||||
}
|
||||
|
||||
std::memcpy(
|
||||
codeset.memory.data() + module_start + nso_header.segments[i].location,
|
||||
decompressed_size.data(),
|
||||
nso_header.segments[i].size
|
||||
);
|
||||
} else {
|
||||
std::memcpy(codeset.memory.data() + module_start + nso_header.segments[i].location, compressed_data.data(), nso_header.segments[i].size);
|
||||
// Not compressed
|
||||
std::memcpy(
|
||||
codeset.memory.data() + module_start + nso_header.segments[i].location,
|
||||
compressed_data.data(),
|
||||
nso_header.segments[i].size
|
||||
);
|
||||
}
|
||||
codeset.segments[i].addr = module_start + nso_header.segments[i].location;
|
||||
codeset.segments[i].offset = module_start + nso_header.segments[i].location;
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
@@ -58,6 +61,9 @@ struct NSOHeader {
|
||||
std::array<SHA256Hash, 3> segment_hashes;
|
||||
|
||||
bool IsSegmentCompressed(size_t segment_num) const;
|
||||
bool IsZBICCompressed() const {
|
||||
return ((flags >> 7) & 1) != 0;
|
||||
}
|
||||
};
|
||||
static_assert(sizeof(NSOHeader) == 0x100, "NSOHeader has incorrect size.");
|
||||
static_assert(std::is_trivially_copyable_v<NSOHeader>, "NSOHeader must be trivially copyable.");
|
||||
|
||||
@@ -406,8 +406,10 @@ int RegAlloc::RealizeReadWriteImpl(const IR::Value& read_value, const IR::Inst*
|
||||
} else if constexpr (kind == HostLoc::Kind::Fpr) {
|
||||
LoadCopyInto(read_value, oaknut::QReg{write_loc});
|
||||
return write_loc;
|
||||
} else if constexpr (kind == HostLoc::Kind::Flags) {
|
||||
ASSERT(false && "Incorrect function for ReadWrite of flags");
|
||||
} else {
|
||||
UNREACHABLE(); // kind == HostLoc::Kind::Flags
|
||||
UNREACHABLE();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -72,6 +72,40 @@ void Block::Reset(LocationDescriptor location_) noexcept {
|
||||
ASSERT(instructions.size() == 0);
|
||||
}
|
||||
|
||||
static std::string TerminalToString(const Term::Terminal& terminal_variant) noexcept {
|
||||
// struct : boost::static_visitor<std::string> {
|
||||
// std::string operator()(const std::monostate&) const {
|
||||
// return "<invalid>";
|
||||
// }
|
||||
// std::string operator()(const Term::ReturnToDispatch&) const {
|
||||
// return "ReturnToDispatch{}";
|
||||
// }
|
||||
// std::string operator()(const Term::LinkBlock& terminal) const {
|
||||
// return fmt::format("LinkBlock{{{}}}", terminal.next);
|
||||
// }
|
||||
// std::string operator()(const Term::LinkBlockFast& terminal) const {
|
||||
// return fmt::format("LinkBlockFast{{{}}}", terminal.next);
|
||||
// }
|
||||
// std::string operator()(const Term::PopRSBHint&) const {
|
||||
// return "PopRSBHint{}";
|
||||
// }
|
||||
// std::string operator()(const Term::FastDispatchHint&) const {
|
||||
// return "FastDispatchHint{}";
|
||||
// }
|
||||
// std::string operator()(const Term::If& terminal) const {
|
||||
// return fmt::format("If{{{}, {}, {}}}", A64::CondToString(terminal.if_), TerminalToString(terminal.then_), TerminalToString(terminal.else_));
|
||||
// }
|
||||
// std::string operator()(const Term::CheckBit& terminal) const {
|
||||
// return fmt::format("CheckBit{{{}, {}}}", TerminalToString(terminal.then_), TerminalToString(terminal.else_));
|
||||
// }
|
||||
// std::string operator()(const Term::CheckHalt& terminal) const {
|
||||
// return fmt::format("CheckHalt{{{}}}", TerminalToString(terminal.else_));
|
||||
// }
|
||||
// } visitor;
|
||||
// return boost::apply_visitor(visitor, terminal_variant);
|
||||
return "";
|
||||
}
|
||||
|
||||
std::string DumpBlock(const IR::Block& block) noexcept {
|
||||
std::string ret = fmt::format("Block: location={}-{}\n", block.Location(), block.EndLocation())
|
||||
+ fmt::format("cycles={}", block.CycleCount())
|
||||
@@ -140,9 +174,8 @@ std::string DumpBlock(const IR::Block& block) noexcept {
|
||||
|
||||
ret += fmt::format(" (uses: {})", inst.UseCount()) + '\n';
|
||||
}
|
||||
return ret + "terminal = " + [](const Term::Terminal&) -> std::string {
|
||||
return "";
|
||||
}(block.GetTerminal()) + '\n';
|
||||
ret += "terminal = " + TerminalToString(block.GetTerminal()) + '\n';
|
||||
return ret;
|
||||
}
|
||||
|
||||
} // namespace Dynarmic::IR
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
|
||||
@@ -6,8 +6,6 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <cstddef>
|
||||
#include <vector>
|
||||
#include "common/bit_field.h"
|
||||
#include "common/common_funcs.h"
|
||||
#include "common/common_types.h"
|
||||
|
||||
@@ -209,6 +209,8 @@ add_executable(yuzu
|
||||
util/overlay_dialog.ui
|
||||
util/sequence_dialog/sequence_dialog.cpp
|
||||
util/sequence_dialog/sequence_dialog.h
|
||||
util/url_request_interceptor.cpp
|
||||
util/url_request_interceptor.h
|
||||
util/util.cpp
|
||||
util/util.h
|
||||
|
||||
@@ -239,12 +241,6 @@ add_executable(yuzu
|
||||
|
||||
set_target_properties(yuzu PROPERTIES OUTPUT_NAME "eden")
|
||||
|
||||
if (YUZU_USE_QT_WEB_ENGINE)
|
||||
target_sources(yuzu PRIVATE
|
||||
util/url_request_interceptor.cpp
|
||||
util/url_request_interceptor.h)
|
||||
endif()
|
||||
|
||||
if (YUZU_CRASH_DUMPS)
|
||||
target_sources(yuzu PRIVATE
|
||||
breakpad.cpp
|
||||
|
||||
@@ -232,6 +232,7 @@
|
||||
<property name="title">
|
||||
<string>&Help</string>
|
||||
</property>
|
||||
<addaction name="action_Report_Compatibility"/>
|
||||
<addaction name="action_Open_Mods_Page"/>
|
||||
<addaction name="action_Open_UserHandbook"/>
|
||||
<addaction name="separator"/>
|
||||
|
||||
Reference in New Issue
Block a user