diff --git a/3rd_Party/README.md b/3rd_Party/README.md new file mode 100644 index 0000000..979ddfc --- /dev/null +++ b/3rd_Party/README.md @@ -0,0 +1,5 @@ +# 3rd Party folder + +### !! Code from this folder is from Yuzu to make code from other folders compilable + +dir: /3rd_Party/ \ No newline at end of file diff --git a/3rd_Party/common/assert.h b/3rd_Party/common/assert.h new file mode 100644 index 0000000..67e7e93 --- /dev/null +++ b/3rd_Party/common/assert.h @@ -0,0 +1,84 @@ +// SPDX-FileCopyrightText: 2013 Dolphin Emulator Project +// SPDX-FileCopyrightText: 2014 Citra Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include "common/logging/log.h" + +// Sometimes we want to try to continue even after hitting an assert. +// However touching this file yields a global recompilation as this header is included almost +// everywhere. So let's just move the handling of the failed assert to a single cpp file. + +void assert_fail_impl(); +[[noreturn]] void unreachable_impl(); + +#ifdef _MSC_VER +#define YUZU_NO_INLINE __declspec(noinline) +#else +#define YUZU_NO_INLINE __attribute__((noinline)) +#endif + +#define ASSERT(_a_) \ + ([&]() YUZU_NO_INLINE { \ + if (!(_a_)) [[unlikely]] { \ + LOG_CRITICAL(Debug, "Assertion Failed!"); \ + assert_fail_impl(); \ + } \ + }()) + +#define ASSERT_MSG(_a_, ...) \ + ([&]() YUZU_NO_INLINE { \ + if (!(_a_)) [[unlikely]] { \ + LOG_CRITICAL(Debug, "Assertion Failed!\n" __VA_ARGS__); \ + assert_fail_impl(); \ + } \ + }()) + +#define UNREACHABLE() \ + do { \ + LOG_CRITICAL(Debug, "Unreachable code!"); \ + unreachable_impl(); \ + } while (0) + +#define UNREACHABLE_MSG(...) \ + do { \ + LOG_CRITICAL(Debug, "Unreachable code!\n" __VA_ARGS__); \ + unreachable_impl(); \ + } while (0) + +#ifdef _DEBUG +#define DEBUG_ASSERT(_a_) ASSERT(_a_) +#define DEBUG_ASSERT_MSG(_a_, ...) ASSERT_MSG(_a_, __VA_ARGS__) +#else // not debug +#define DEBUG_ASSERT(_a_) \ + do { \ + } while (0) +#define DEBUG_ASSERT_MSG(_a_, _desc_, ...) \ + do { \ + } while (0) +#endif + +#define UNIMPLEMENTED() ASSERT_MSG(false, "Unimplemented code!") +#define UNIMPLEMENTED_MSG(...) ASSERT_MSG(false, __VA_ARGS__) + +#define UNIMPLEMENTED_IF(cond) ASSERT_MSG(!(cond), "Unimplemented code!") +#define UNIMPLEMENTED_IF_MSG(cond, ...) ASSERT_MSG(!(cond), __VA_ARGS__) + +// If the assert is ignored, execute _b_ +#define ASSERT_OR_EXECUTE(_a_, _b_) \ + do { \ + ASSERT(_a_); \ + if (!(_a_)) [[unlikely]] { \ + _b_ \ + } \ + } while (0) + +// If the assert is ignored, execute _b_ +#define ASSERT_OR_EXECUTE_MSG(_a_, _b_, ...) \ + do { \ + ASSERT_MSG(_a_, __VA_ARGS__); \ + if (!(_a_)) [[unlikely]] { \ + _b_ \ + } \ + } while (0) diff --git a/3rd_Party/common/common_types.h b/3rd_Party/common/common_types.h new file mode 100644 index 0000000..ae04c4d --- /dev/null +++ b/3rd_Party/common/common_types.h @@ -0,0 +1,53 @@ +// SPDX-FileCopyrightText: 2012 Gekko Emulator +// SPDX-FileContributor: ShizZy +// SPDX-License-Identifier: GPL-2.0-or-later + +/** + * Copyright (C) 2005-2012 Gekko Emulator + * + * @file common_types.h + * @author ShizZy + * @date 2012-02-11 + * @brief Common types used throughout the project + * + * @section LICENSE + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details at + * http://www.gnu.org/copyleft/gpl.html + * + * Official project repository can be found at: + * http://code.google.com/p/gekko-gc-emu/ + */ + +#pragma once + +#include +#include + +using u8 = std::uint8_t; ///< 8-bit unsigned byte +using u16 = std::uint16_t; ///< 16-bit unsigned short +using u32 = std::uint32_t; ///< 32-bit unsigned word +using u64 = std::uint64_t; ///< 64-bit unsigned int + +using s8 = std::int8_t; ///< 8-bit signed byte +using s16 = std::int16_t; ///< 16-bit signed short +using s32 = std::int32_t; ///< 32-bit signed word +using s64 = std::int64_t; ///< 64-bit signed int + +using f32 = float; ///< 32-bit floating point +using f64 = double; ///< 64-bit floating point + +using VAddr = u64; ///< Represents a pointer in the userspace virtual address space. +using DAddr = u64; ///< Represents a pointer in the device specific virtual address space. +using PAddr = u64; ///< Represents a pointer in the ARM11 physical address space. +using GPUVAddr = u64; ///< Represents a pointer in the GPU virtual address space. + +using u128 = std::array; +static_assert(sizeof(u128) == 16, "u128 must be 128 bits wide"); diff --git a/3rd_Party/common/fs/path_util.h b/3rd_Party/common/fs/path_util.h new file mode 100644 index 0000000..59301e7 --- /dev/null +++ b/3rd_Party/common/fs/path_util.h @@ -0,0 +1,316 @@ +// SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include +#include + +#include "common/fs/fs_util.h" + +namespace Common::FS { + +enum class YuzuPath { + YuzuDir, // Where yuzu stores its data. + AmiiboDir, // Where Amiibo backups are stored. + CacheDir, // Where cached filesystem data is stored. + ConfigDir, // Where config files are stored. + CrashDumpsDir, // Where crash dumps are stored. + DumpDir, // Where dumped data is stored. + KeysDir, // Where key files are stored. + LoadDir, // Where cheat/mod files are stored. + LogDir, // Where log files are stored. + NANDDir, // Where the emulated NAND is stored. + PlayTimeDir, // Where play time data is stored. + ScreenshotsDir, // Where yuzu screenshots are stored. + SDMCDir, // Where the emulated SDMC is stored. + ShaderDir, // Where shaders are stored. + TASDir, // Where TAS scripts are stored. + IconsDir, // Where Icons for Windows shortcuts are stored. +}; + +/** + * Validates a given path. + * + * A given path is valid if it meets these conditions: + * - The path is not empty + * - The path is not too long + * + * @param path Filesystem path + * + * @returns True if the path is valid, false otherwise. + */ +[[nodiscard]] bool ValidatePath(const std::filesystem::path& path); + +#ifdef _WIN32 +template +[[nodiscard]] bool ValidatePath(const Path& path) { + if constexpr (IsChar) { + return ValidatePath(ToU8String(path)); + } else { + return ValidatePath(std::filesystem::path{path}); + } +} +#endif + +/** + * Concatenates two filesystem paths together. + * + * This is needed since the following occurs when using std::filesystem::path's operator/: + * first: "/first/path" + * second: "/second/path" (Note that the second path has a directory separator in the front) + * first / second yields "/second/path" when the desired result is first/path/second/path + * + * @param first First filesystem path + * @param second Second filesystem path + * + * @returns A concatenated filesystem path. + */ +[[nodiscard]] std::filesystem::path ConcatPath(const std::filesystem::path& first, + const std::filesystem::path& second); + +#ifdef _WIN32 +template +[[nodiscard]] std::filesystem::path ConcatPath(const Path1& first, const Path2& second) { + using ValueType1 = typename Path1::value_type; + using ValueType2 = typename Path2::value_type; + if constexpr (IsChar && IsChar) { + return ConcatPath(ToU8String(first), ToU8String(second)); + } else if constexpr (IsChar && !IsChar) { + return ConcatPath(ToU8String(first), second); + } else if constexpr (!IsChar && IsChar) { + return ConcatPath(first, ToU8String(second)); + } else { + return ConcatPath(std::filesystem::path{first}, std::filesystem::path{second}); + } +} +#endif + +/** + * Safe variant of ConcatPath that takes in a base path and an offset path from the given base path. + * + * If ConcatPath(base, offset) resolves to a path that is sandboxed within the base path, + * this will return the concatenated path. Otherwise this will return the base path. + * + * @param base Base filesystem path + * @param offset Offset filesystem path + * + * @returns A concatenated filesystem path if it is within the base path, + * returns the base path otherwise. + */ +[[nodiscard]] std::filesystem::path ConcatPathSafe(const std::filesystem::path& base, + const std::filesystem::path& offset); + +#ifdef _WIN32 +template +[[nodiscard]] std::filesystem::path ConcatPathSafe(const Path1& base, const Path2& offset) { + using ValueType1 = typename Path1::value_type; + using ValueType2 = typename Path2::value_type; + if constexpr (IsChar && IsChar) { + return ConcatPathSafe(ToU8String(base), ToU8String(offset)); + } else if constexpr (IsChar && !IsChar) { + return ConcatPathSafe(ToU8String(base), offset); + } else if constexpr (!IsChar && IsChar) { + return ConcatPathSafe(base, ToU8String(offset)); + } else { + return ConcatPathSafe(std::filesystem::path{base}, std::filesystem::path{offset}); + } +} +#endif + +/** + * Checks whether a given path is sandboxed within a given base path. + * + * @param base Base filesystem path + * @param path Filesystem path + * + * @returns True if the given path is sandboxed within the given base path, false otherwise. + */ +[[nodiscard]] bool IsPathSandboxed(const std::filesystem::path& base, + const std::filesystem::path& path); + +#ifdef _WIN32 +template +[[nodiscard]] bool IsPathSandboxed(const Path1& base, const Path2& path) { + using ValueType1 = typename Path1::value_type; + using ValueType2 = typename Path2::value_type; + if constexpr (IsChar && IsChar) { + return IsPathSandboxed(ToU8String(base), ToU8String(path)); + } else if constexpr (IsChar && !IsChar) { + return IsPathSandboxed(ToU8String(base), path); + } else if constexpr (!IsChar && IsChar) { + return IsPathSandboxed(base, ToU8String(path)); + } else { + return IsPathSandboxed(std::filesystem::path{base}, std::filesystem::path{path}); + } +} +#endif + +/** + * Checks if a character is a directory separator (either a forward slash or backslash). + * + * @param character Character + * + * @returns True if the character is a directory separator, false otherwise. + */ +[[nodiscard]] bool IsDirSeparator(char character); + +/** + * Checks if a character is a directory separator (either a forward slash or backslash). + * + * @param character Character + * + * @returns True if the character is a directory separator, false otherwise. + */ +[[nodiscard]] bool IsDirSeparator(char8_t character); + +/** + * Removes any trailing directory separators if they exist in the given path. + * + * @param path Filesystem path + * + * @returns The filesystem path without any trailing directory separators. + */ +[[nodiscard]] std::filesystem::path RemoveTrailingSeparators(const std::filesystem::path& path); + +#ifdef _WIN32 +template +[[nodiscard]] std::filesystem::path RemoveTrailingSeparators(const Path& path) { + if constexpr (IsChar) { + return RemoveTrailingSeparators(ToU8String(path)); + } else { + return RemoveTrailingSeparators(std::filesystem::path{path}); + } +} +#endif + +/** + * Sets the directory used for application storage. Used on Android where we do not know internal + * storage until informed by the frontend. + * + * @param app_directory Directory to use for application storage. + */ +void SetAppDirectory(const std::string& app_directory); + +/** + * Gets the filesystem path associated with the YuzuPath enum. + * + * @param yuzu_path YuzuPath enum + * + * @returns The filesystem path associated with the YuzuPath enum. + */ +[[nodiscard]] const std::filesystem::path& GetYuzuPath(YuzuPath yuzu_path); + +/** + * Gets the filesystem path associated with the YuzuPath enum as a UTF-8 encoded std::string. + * + * @param yuzu_path YuzuPath enum + * + * @returns The filesystem path associated with the YuzuPath enum as a UTF-8 encoded std::string. + */ +[[nodiscard]] std::string GetYuzuPathString(YuzuPath yuzu_path); + +/** + * Sets a new filesystem path associated with the YuzuPath enum. + * If the filesystem object at new_path is not a directory, this function will not do anything. + * + * @param yuzu_path YuzuPath enum + * @param new_path New filesystem path + */ +void SetYuzuPath(YuzuPath yuzu_path, const std::filesystem::path& new_path); + +#ifdef _WIN32 +template +void SetYuzuPath(YuzuPath yuzu_path, const Path& new_path) { + if constexpr (IsChar) { + SetYuzuPath(yuzu_path, ToU8String(new_path)); + } else { + SetYuzuPath(yuzu_path, std::filesystem::path{new_path}); + } +} +#endif + +#ifdef _WIN32 + +/** + * Gets the path of the directory containing the executable of the current process. + * + * @returns The path of the directory containing the executable of the current process. + */ +[[nodiscard]] std::filesystem::path GetExeDirectory(); + +/** + * Gets the path of the current user's %APPDATA% directory (%USERPROFILE%/AppData/Roaming). + * + * @returns The path of the current user's %APPDATA% directory. + */ +[[nodiscard]] std::filesystem::path GetAppDataRoamingDirectory(); + +#else + +/** + * Gets the path of the directory specified by the #HOME environment variable. + * If $HOME is not defined, it will attempt to query the user database in passwd instead. + * + * @returns The path of the current user's home directory. + */ +[[nodiscard]] std::filesystem::path GetHomeDirectory(); + +/** + * Gets the relevant paths for yuzu to store its data based on the given XDG environment variable. + * See https://specifications.freedesktop.org/basedir-spec/basedir-spec-latest.html + * Defaults to $HOME/.local/share for main application data, + * $HOME/.cache for cached data, and $HOME/.config for configuration files. + * + * @param env_name XDG environment variable name + * + * @returns The path where yuzu should store its data. + */ +[[nodiscard]] std::filesystem::path GetDataDirectory(const std::string& env_name); + +#endif + +#ifdef __APPLE__ + +[[nodiscard]] std::filesystem::path GetBundleDirectory(); + +#endif + +// vvvvvvvvvv Deprecated vvvvvvvvvv // + +// Removes the final '/' or '\' if one exists +[[nodiscard]] std::string_view RemoveTrailingSlash(std::string_view path); + +enum class DirectorySeparator { + ForwardSlash, + BackwardSlash, + PlatformDefault, +}; + +// Splits the path on '/' or '\' and put the components into a vector +// i.e. "C:\Users\Yuzu\Documents\save.bin" becomes {"C:", "Users", "Yuzu", "Documents", "save.bin" } +[[nodiscard]] std::vector SplitPathComponents(std::string_view filename); + +// Splits the path on '/' or '\' and put the components into a vector +// i.e. "C:\Users\Yuzu\Documents\save.bin" becomes {"C:", "Users", "Yuzu", "Documents", "save.bin" } +[[nodiscard]] std::vector SplitPathComponentsCopy(std::string_view filename); + +// Removes trailing slash, makes all '\\' into '/', and removes duplicate '/'. Makes '/' into '\\' +// depending if directory_separator is BackwardSlash or PlatformDefault and running on windows +[[nodiscard]] std::string SanitizePath( + std::string_view path, + DirectorySeparator directory_separator = DirectorySeparator::ForwardSlash); + +// Gets all of the text up to the last '/' or '\' in the path. +[[nodiscard]] std::string GetParentPath(std::string_view path); + +// Gets all of the text after the first '/' or '\' in the path. +[[nodiscard]] std::string_view GetPathWithoutTop(std::string_view path); + +// Gets the filename of the path +[[nodiscard]] std::string_view GetFilename(std::string_view path); + +// Gets the extension of the filename +[[nodiscard]] std::string_view GetExtensionFromFilename(std::string_view name); + +} // namespace Common::FS diff --git a/3rd_Party/common/logging/formatter.h b/3rd_Party/common/logging/formatter.h new file mode 100644 index 0000000..88e5550 --- /dev/null +++ b/3rd_Party/common/logging/formatter.h @@ -0,0 +1,22 @@ +// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include + +#include + +// adapted from https://github.com/fmtlib/fmt/issues/2704 +// a generic formatter for enum classes +#if FMT_VERSION >= 80100 +template +struct fmt::formatter, char>> + : formatter> { + template + auto format(const T& value, FormatContext& ctx) -> decltype(ctx.out()) { + return fmt::formatter>::format( + static_cast>(value), ctx); + } +}; +#endif diff --git a/3rd_Party/common/logging/log.h b/3rd_Party/common/logging/log.h new file mode 100644 index 0000000..498e8ff --- /dev/null +++ b/3rd_Party/common/logging/log.h @@ -0,0 +1,67 @@ +// SPDX-FileCopyrightText: 2014 Citra Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include +#include + +#include + +#include "import/common/logging/formatter.h" +#include "import/common/logging/types.h" + +namespace Common::Log { + +// trims up to and including the last of ../, ..\, src/, src\ in a string +constexpr const char* TrimSourcePath(std::string_view source) { + const auto rfind = [source](const std::string_view match) { + return source.rfind(match) == source.npos ? 0 : (source.rfind(match) + match.size()); + }; + auto idx = std::max({rfind("src/"), rfind("src\\"), rfind("../"), rfind("..\\")}); + return source.data() + idx; +} + +/// Logs a message to the global logger, using fmt +void FmtLogMessageImpl(Class log_class, Level log_level, const char* filename, + unsigned int line_num, const char* function, const char* format, + const fmt::format_args& args); + +template +void FmtLogMessage(Class log_class, Level log_level, const char* filename, unsigned int line_num, + const char* function, const char* format, const Args&... args) { + FmtLogMessageImpl(log_class, log_level, filename, line_num, function, format, + fmt::make_format_args(args...)); +} + +} // namespace Common::Log + +#ifdef _DEBUG +#define LOG_TRACE(log_class, ...) \ + Common::Log::FmtLogMessage(Common::Log::Class::log_class, Common::Log::Level::Trace, \ + Common::Log::TrimSourcePath(__FILE__), __LINE__, __func__, \ + __VA_ARGS__) +#else +#define LOG_TRACE(log_class, fmt, ...) (void(0)) +#endif + +#define LOG_DEBUG(log_class, ...) \ + Common::Log::FmtLogMessage(Common::Log::Class::log_class, Common::Log::Level::Debug, \ + Common::Log::TrimSourcePath(__FILE__), __LINE__, __func__, \ + __VA_ARGS__) +#define LOG_INFO(log_class, ...) \ + Common::Log::FmtLogMessage(Common::Log::Class::log_class, Common::Log::Level::Info, \ + Common::Log::TrimSourcePath(__FILE__), __LINE__, __func__, \ + __VA_ARGS__) +#define LOG_WARNING(log_class, ...) \ + Common::Log::FmtLogMessage(Common::Log::Class::log_class, Common::Log::Level::Warning, \ + Common::Log::TrimSourcePath(__FILE__), __LINE__, __func__, \ + __VA_ARGS__) +#define LOG_ERROR(log_class, ...) \ + Common::Log::FmtLogMessage(Common::Log::Class::log_class, Common::Log::Level::Error, \ + Common::Log::TrimSourcePath(__FILE__), __LINE__, __func__, \ + __VA_ARGS__) +#define LOG_CRITICAL(log_class, ...) \ + Common::Log::FmtLogMessage(Common::Log::Class::log_class, Common::Log::Level::Critical, \ + Common::Log::TrimSourcePath(__FILE__), __LINE__, __func__, \ + __VA_ARGS__) diff --git a/3rd_Party/common/logging/types.h b/3rd_Party/common/logging/types.h new file mode 100644 index 0000000..2b3a67b --- /dev/null +++ b/3rd_Party/common/logging/types.h @@ -0,0 +1,135 @@ +// SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include "import/common/common_types.h" + +namespace Common::Log { + +/// Specifies the severity or level of detail of the log message. +enum class Level : u8 { + Trace, ///< Extremely detailed and repetitive debugging information that is likely to + ///< pollute logs. + Debug, ///< Less detailed debugging information. + Info, ///< Status information from important points during execution. + Warning, ///< Minor or potential problems found during execution of a task. + Error, ///< Major problems found during execution of a task that prevent it from being + ///< completed. + Critical, ///< Major problems during execution that threaten the stability of the entire + ///< application. + + Count ///< Total number of logging levels +}; + +/** + * Specifies the sub-system that generated the log message. + * + * @note If you add a new entry here, also add a corresponding one to `ALL_LOG_CLASSES` in + * filter.cpp. + */ +enum class Class : u8 { + Log, ///< Messages about the log system itself + Common, ///< Library routines + Common_Filesystem, ///< Filesystem interface library + Common_Memory, ///< Memory mapping and management functions + Core, ///< LLE emulation core + Core_ARM, ///< ARM CPU core + Core_Timing, ///< CoreTiming functions + Config, ///< Emulator configuration (including commandline) + Debug, ///< Debugging tools + Debug_Emulated, ///< Debug messages from the emulated programs + Debug_GPU, ///< GPU debugging tools + Debug_Breakpoint, ///< Logging breakpoints and watchpoints + Debug_GDBStub, ///< GDB Stub + Kernel, ///< The HLE implementation of the CTR kernel + Kernel_SVC, ///< Kernel system calls + Service, ///< HLE implementation of system services. Each major service + ///< should have its own subclass. + Service_ACC, ///< The ACC (Accounts) service + Service_AM, ///< The AM (Applet manager) service + Service_AOC, ///< The AOC (AddOn Content) service + Service_APM, ///< The APM (Performance) service + Service_ARP, ///< The ARP service + Service_Audio, ///< The Audio (Audio control) service + Service_BCAT, ///< The BCAT service + Service_BGTC, ///< The BGTC (Background Task Controller) service + Service_BPC, ///< The BPC service + Service_BTDRV, ///< The Bluetooth driver service + Service_BTM, ///< The BTM service + Service_Capture, ///< The capture service + Service_ERPT, ///< The error reporting service + Service_ETicket, ///< The ETicket service + Service_EUPLD, ///< The error upload service + Service_Fatal, ///< The Fatal service + Service_FGM, ///< The FGM service + Service_Friend, ///< The friend service + Service_FS, ///< The FS (Filesystem) service + Service_GRC, ///< The game recording service + Service_HID, ///< The HID (Human interface device) service + Service_IRS, ///< The IRS service + Service_JIT, ///< The JIT service + Service_LBL, ///< The LBL (LCD backlight) service + Service_LDN, ///< The LDN (Local domain network) service + Service_LDR, ///< The loader service + Service_LM, ///< The LM (Logger) service + Service_Migration, ///< The migration service + Service_Mii, ///< The Mii service + Service_MM, ///< The MM (Multimedia) service + Service_MNPP, ///< The MNPP service + Service_NCM, ///< The NCM service + Service_NFC, ///< The NFC (Near-field communication) service + Service_NFP, ///< The NFP service + Service_NGC, ///< The NGC (No Good Content) service + Service_NIFM, ///< The NIFM (Network interface) service + Service_NIM, ///< The NIM service + Service_NOTIF, ///< The NOTIF (Notification) service + Service_NPNS, ///< The NPNS service + Service_NS, ///< The NS services + Service_NVDRV, ///< The NVDRV (Nvidia driver) service + Service_Nvnflinger, ///< The Nvnflinger service + Service_OLSC, ///< The OLSC service + Service_PCIE, ///< The PCIe service + Service_PCTL, ///< The PCTL (Parental control) service + Service_PCV, ///< The PCV service + Service_PM, ///< The PM service + Service_PREPO, ///< The PREPO (Play report) service + Service_PSC, ///< The PSC service + Service_PTM, ///< The PTM service + Service_SET, ///< The SET (Settings) service + Service_SM, ///< The SM (Service manager) service + Service_SPL, ///< The SPL service + Service_SSL, ///< The SSL service + Service_TCAP, ///< The TCAP service. + Service_Time, ///< The time service + Service_USB, ///< The USB (Universal Serial Bus) service + Service_VI, ///< The VI (Video interface) service + Service_WLAN, ///< The WLAN (Wireless local area network) service + HW, ///< Low-level hardware emulation + HW_Memory, ///< Memory-map and address translation + HW_LCD, ///< LCD register emulation + HW_GPU, ///< GPU control emulation + HW_AES, ///< AES engine emulation + IPC, ///< IPC interface + Frontend, ///< Emulator UI + Render, ///< Emulator video output and hardware acceleration + Render_Software, ///< Software renderer backend + Render_OpenGL, ///< OpenGL backend + Render_Vulkan, ///< Vulkan backend + Shader, ///< Shader recompiler + Shader_SPIRV, ///< Shader SPIR-V code generation + Shader_GLASM, ///< Shader GLASM code generation + Shader_GLSL, ///< Shader GLSL code generation + Audio, ///< Audio emulation + Audio_DSP, ///< The HLE implementation of the DSP + Audio_Sink, ///< Emulator audio output backend + Loader, ///< ROM loader + CheatEngine, ///< Memory manipulation and engine VM functions + Crypto, ///< Cryptographic engine/functions + Input, ///< Input emulation + Network, ///< Network emulation + WebService, ///< Interface to yuzu Web Services + Count ///< Total number of logging classes +}; + +} // namespace Common::Log diff --git a/3rd_Party/common/swap.h b/3rd_Party/common/swap.h new file mode 100644 index 0000000..6c51096 --- /dev/null +++ b/3rd_Party/common/swap.h @@ -0,0 +1,665 @@ +// SPDX-FileCopyrightText: 2012 PPSSPP Project +// SPDX-FileCopyrightText: 2012 Dolphin Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +// Official git repository and contact information can be found at +// https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. + +#pragma once + +#if defined(_MSC_VER) +#include +#endif +#include +#include +#include +#include "import/common/common_types.h" + +namespace Common { + +#ifdef _MSC_VER +[[nodiscard]] inline u16 swap16(u16 data) noexcept { + return _byteswap_ushort(data); +} +[[nodiscard]] inline u32 swap32(u32 data) noexcept { + return _byteswap_ulong(data); +} +[[nodiscard]] inline u64 swap64(u64 data) noexcept { + return _byteswap_uint64(data); +} +#elif defined(__clang__) || defined(__GNUC__) +#if defined(__Bitrig__) || defined(__OpenBSD__) +// redefine swap16, swap32, swap64 as inline functions +#undef swap16 +#undef swap32 +#undef swap64 +#endif +[[nodiscard]] inline u16 swap16(u16 data) noexcept { + return __builtin_bswap16(data); +} +[[nodiscard]] inline u32 swap32(u32 data) noexcept { + return __builtin_bswap32(data); +} +[[nodiscard]] inline u64 swap64(u64 data) noexcept { + return __builtin_bswap64(data); +} +#else +// Generic implementation. +[[nodiscard]] inline u16 swap16(u16 data) noexcept { + return (data >> 8) | (data << 8); +} +[[nodiscard]] inline u32 swap32(u32 data) noexcept { + return ((data & 0xFF000000U) >> 24) | ((data & 0x00FF0000U) >> 8) | + ((data & 0x0000FF00U) << 8) | ((data & 0x000000FFU) << 24); +} +[[nodiscard]] inline u64 swap64(u64 data) noexcept { + return ((data & 0xFF00000000000000ULL) >> 56) | ((data & 0x00FF000000000000ULL) >> 40) | + ((data & 0x0000FF0000000000ULL) >> 24) | ((data & 0x000000FF00000000ULL) >> 8) | + ((data & 0x00000000FF000000ULL) << 8) | ((data & 0x0000000000FF0000ULL) << 24) | + ((data & 0x000000000000FF00ULL) << 40) | ((data & 0x00000000000000FFULL) << 56); +} +#endif + +[[nodiscard]] inline float swapf(float f) noexcept { + static_assert(sizeof(u32) == sizeof(float), "float must be the same size as uint32_t."); + + u32 value; + std::memcpy(&value, &f, sizeof(u32)); + + value = swap32(value); + std::memcpy(&f, &value, sizeof(u32)); + + return f; +} + +[[nodiscard]] inline double swapd(double f) noexcept { + static_assert(sizeof(u64) == sizeof(double), "double must be the same size as uint64_t."); + + u64 value; + std::memcpy(&value, &f, sizeof(u64)); + + value = swap64(value); + std::memcpy(&f, &value, sizeof(u64)); + + return f; +} + +} // Namespace Common + +template +struct swap_struct_t { + using swapped_t = swap_struct_t; + +protected: + T value; + + static T swap(T v) { + return F::swap(v); + } + +public: + T swap() const { + return swap(value); + } + swap_struct_t() = default; + swap_struct_t(const T& v) : value(swap(v)) {} + + template + swapped_t& operator=(const S& source) { + value = swap(static_cast(source)); + return *this; + } + + operator s8() const { + return static_cast(swap()); + } + operator u8() const { + return static_cast(swap()); + } + operator s16() const { + return static_cast(swap()); + } + operator u16() const { + return static_cast(swap()); + } + operator s32() const { + return static_cast(swap()); + } + operator u32() const { + return static_cast(swap()); + } + operator s64() const { + return static_cast(swap()); + } + operator u64() const { + return static_cast(swap()); + } + operator float() const { + return static_cast(swap()); + } + operator double() const { + return static_cast(swap()); + } + + // +v + swapped_t operator+() const { + return +swap(); + } + // -v + swapped_t operator-() const { + return -swap(); + } + + // v / 5 + swapped_t operator/(const swapped_t& i) const { + return swap() / i.swap(); + } + template + swapped_t operator/(const S& i) const { + return swap() / i; + } + + // v * 5 + swapped_t operator*(const swapped_t& i) const { + return swap() * i.swap(); + } + template + swapped_t operator*(const S& i) const { + return swap() * i; + } + + // v + 5 + swapped_t operator+(const swapped_t& i) const { + return swap() + i.swap(); + } + template + swapped_t operator+(const S& i) const { + return swap() + static_cast(i); + } + // v - 5 + swapped_t operator-(const swapped_t& i) const { + return swap() - i.swap(); + } + template + swapped_t operator-(const S& i) const { + return swap() - static_cast(i); + } + + // v += 5 + swapped_t& operator+=(const swapped_t& i) { + value = swap(swap() + i.swap()); + return *this; + } + template + swapped_t& operator+=(const S& i) { + value = swap(swap() + static_cast(i)); + return *this; + } + // v -= 5 + swapped_t& operator-=(const swapped_t& i) { + value = swap(swap() - i.swap()); + return *this; + } + template + swapped_t& operator-=(const S& i) { + value = swap(swap() - static_cast(i)); + return *this; + } + + // ++v + swapped_t& operator++() { + value = swap(swap() + 1); + return *this; + } + // --v + swapped_t& operator--() { + value = swap(swap() - 1); + return *this; + } + + // v++ + swapped_t operator++(int) { + swapped_t old = *this; + value = swap(swap() + 1); + return old; + } + // v-- + swapped_t operator--(int) { + swapped_t old = *this; + value = swap(swap() - 1); + return old; + } + // Comparison + // v == i + bool operator==(const swapped_t& i) const { + return swap() == i.swap(); + } + template + bool operator==(const S& i) const { + return swap() == i; + } + + // v != i + bool operator!=(const swapped_t& i) const { + return swap() != i.swap(); + } + template + bool operator!=(const S& i) const { + return swap() != i; + } + + // v > i + bool operator>(const swapped_t& i) const { + return swap() > i.swap(); + } + template + bool operator>(const S& i) const { + return swap() > i; + } + + // v < i + bool operator<(const swapped_t& i) const { + return swap() < i.swap(); + } + template + bool operator<(const S& i) const { + return swap() < i; + } + + // v >= i + bool operator>=(const swapped_t& i) const { + return swap() >= i.swap(); + } + template + bool operator>=(const S& i) const { + return swap() >= i; + } + + // v <= i + bool operator<=(const swapped_t& i) const { + return swap() <= i.swap(); + } + template + bool operator<=(const S& i) const { + return swap() <= i; + } + + // logical + swapped_t operator!() const { + return !swap(); + } + + // bitmath + swapped_t operator~() const { + return ~swap(); + } + + swapped_t operator&(const swapped_t& b) const { + return swap() & b.swap(); + } + template + swapped_t operator&(const S& b) const { + return swap() & b; + } + swapped_t& operator&=(const swapped_t& b) { + value = swap(swap() & b.swap()); + return *this; + } + template + swapped_t& operator&=(const S b) { + value = swap(swap() & b); + return *this; + } + + swapped_t operator|(const swapped_t& b) const { + return swap() | b.swap(); + } + template + swapped_t operator|(const S& b) const { + return swap() | b; + } + swapped_t& operator|=(const swapped_t& b) { + value = swap(swap() | b.swap()); + return *this; + } + template + swapped_t& operator|=(const S& b) { + value = swap(swap() | b); + return *this; + } + + swapped_t operator^(const swapped_t& b) const { + return swap() ^ b.swap(); + } + template + swapped_t operator^(const S& b) const { + return swap() ^ b; + } + swapped_t& operator^=(const swapped_t& b) { + value = swap(swap() ^ b.swap()); + return *this; + } + template + swapped_t& operator^=(const S& b) { + value = swap(swap() ^ b); + return *this; + } + + template + swapped_t operator<<(const S& b) const { + return swap() << b; + } + template + swapped_t& operator<<=(const S& b) const { + value = swap(swap() << b); + return *this; + } + + template + swapped_t operator>>(const S& b) const { + return swap() >> b; + } + template + swapped_t& operator>>=(const S& b) const { + value = swap(swap() >> b); + return *this; + } + + // Member + /** todo **/ + + // Arithmetic + template + friend S operator+(const S& p, const swapped_t v); + + template + friend S operator-(const S& p, const swapped_t v); + + template + friend S operator/(const S& p, const swapped_t v); + + template + friend S operator*(const S& p, const swapped_t v); + + template + friend S operator%(const S& p, const swapped_t v); + + // Arithmetic + assignments + template + friend S operator+=(const S& p, const swapped_t v); + + template + friend S operator-=(const S& p, const swapped_t v); + + // Bitmath + template + friend S operator&(const S& p, const swapped_t v); + + // Comparison + template + friend bool operator<(const S& p, const swapped_t v); + + template + friend bool operator>(const S& p, const swapped_t v); + + template + friend bool operator<=(const S& p, const swapped_t v); + + template + friend bool operator>=(const S& p, const swapped_t v); + + template + friend bool operator!=(const S& p, const swapped_t v); + + template + friend bool operator==(const S& p, const swapped_t v); +}; + +// Arithmetic +template +S operator+(const S& i, const swap_struct_t v) { + return i + v.swap(); +} + +template +S operator-(const S& i, const swap_struct_t v) { + return i - v.swap(); +} + +template +S operator/(const S& i, const swap_struct_t v) { + return i / v.swap(); +} + +template +S operator*(const S& i, const swap_struct_t v) { + return i * v.swap(); +} + +template +S operator%(const S& i, const swap_struct_t v) { + return i % v.swap(); +} + +// Arithmetic + assignments +template +S& operator+=(S& i, const swap_struct_t v) { + i += v.swap(); + return i; +} + +template +S& operator-=(S& i, const swap_struct_t v) { + i -= v.swap(); + return i; +} + +// Logical +template +S operator&(const S& i, const swap_struct_t v) { + return i & v.swap(); +} + +// Comparison +template +bool operator<(const S& p, const swap_struct_t v) { + return p < v.swap(); +} +template +bool operator>(const S& p, const swap_struct_t v) { + return p > v.swap(); +} +template +bool operator<=(const S& p, const swap_struct_t v) { + return p <= v.swap(); +} +template +bool operator>=(const S& p, const swap_struct_t v) { + return p >= v.swap(); +} +template +bool operator!=(const S& p, const swap_struct_t v) { + return p != v.swap(); +} +template +bool operator==(const S& p, const swap_struct_t v) { + return p == v.swap(); +} + +template +struct swap_64_t { + static T swap(T x) { + return static_cast(Common::swap64(x)); + } +}; + +template +struct swap_32_t { + static T swap(T x) { + return static_cast(Common::swap32(x)); + } +}; + +template +struct swap_16_t { + static T swap(T x) { + return static_cast(Common::swap16(x)); + } +}; + +template +struct swap_float_t { + static T swap(T x) { + return static_cast(Common::swapf(x)); + } +}; + +template +struct swap_double_t { + static T swap(T x) { + return static_cast(Common::swapd(x)); + } +}; + +template +struct swap_enum_t { + static_assert(std::is_enum_v); + using base = std::underlying_type_t; + +public: + swap_enum_t() = default; + swap_enum_t(const T& v) : value(swap(v)) {} + + swap_enum_t& operator=(const T& v) { + value = swap(v); + return *this; + } + + operator T() const { + return swap(value); + } + + explicit operator base() const { + return static_cast(swap(value)); + } + +protected: + T value{}; + // clang-format off + using swap_t = std::conditional_t< + std::is_same_v, swap_16_t, std::conditional_t< + std::is_same_v, swap_16_t, std::conditional_t< + std::is_same_v, swap_32_t, std::conditional_t< + std::is_same_v, swap_32_t, std::conditional_t< + std::is_same_v, swap_64_t, std::conditional_t< + std::is_same_v, swap_64_t, void>>>>>>; + // clang-format on + static T swap(T x) { + return static_cast(swap_t::swap(static_cast(x))); + } +}; + +struct SwapTag {}; // Use the different endianness from the system +struct KeepTag {}; // Use the same endianness as the system + +template +struct AddEndian; + +// KeepTag specializations + +template +struct AddEndian { + using type = T; +}; + +// SwapTag specializations + +template <> +struct AddEndian { + using type = u8; +}; + +template <> +struct AddEndian { + using type = swap_struct_t>; +}; + +template <> +struct AddEndian { + using type = swap_struct_t>; +}; + +template <> +struct AddEndian { + using type = swap_struct_t>; +}; + +template <> +struct AddEndian { + using type = s8; +}; + +template <> +struct AddEndian { + using type = swap_struct_t>; +}; + +template <> +struct AddEndian { + using type = swap_struct_t>; +}; + +template <> +struct AddEndian { + using type = swap_struct_t>; +}; + +template <> +struct AddEndian { + using type = swap_struct_t>; +}; + +template <> +struct AddEndian { + using type = swap_struct_t>; +}; + +template +struct AddEndian { + static_assert(std::is_enum_v); + using type = swap_enum_t; +}; + +// Alias LETag/BETag as KeepTag/SwapTag depending on the system +using LETag = std::conditional_t; +using BETag = std::conditional_t; + +// Aliases for LE types +using u16_le = AddEndian::type; +using u32_le = AddEndian::type; +using u64_le = AddEndian::type; + +using s16_le = AddEndian::type; +using s32_le = AddEndian::type; +using s64_le = AddEndian::type; + +template +using enum_le = std::enable_if_t, typename AddEndian::type>; + +using float_le = AddEndian::type; +using double_le = AddEndian::type; + +// Aliases for BE types +using u16_be = AddEndian::type; +using u32_be = AddEndian::type; +using u64_be = AddEndian::type; + +using s16_be = AddEndian::type; +using s32_be = AddEndian::type; +using s64_be = AddEndian::type; + +template +using enum_be = std::enable_if_t, typename AddEndian::type>; + +using float_be = AddEndian::type; +using double_be = AddEndian::type; diff --git a/android/app/src/main/cpp/org/pound/poundemu/NativeLibrary.cpp b/android/app/src/main/cpp/org/pound/poundemu/NativeLibrary.cpp new file mode 100644 index 0000000..ef26612 --- /dev/null +++ b/android/app/src/main/cpp/org/pound/poundemu/NativeLibrary.cpp @@ -0,0 +1 @@ +// Android port (TODO) \ No newline at end of file