Compare commits
6 commits
Author | SHA1 | Date | |
---|---|---|---|
50e5a0d752 | |||
b579338d2f | |||
7d0b6e781d | |||
eed403ea0c | |||
22b5180b82 | |||
767fed4c4c |
62 changed files with 2253 additions and 274 deletions
|
@ -7,8 +7,6 @@
|
|||
export NDK_CCACHE="$(which ccache)"
|
||||
ccache -s
|
||||
|
||||
git submodule update --init --recursive
|
||||
|
||||
BUILD_FLAVOR="mainline"
|
||||
|
||||
BUILD_TYPE="release"
|
||||
|
|
|
@ -7,9 +7,7 @@
|
|||
# Exit on error, rather than continuing with the rest of the script.
|
||||
set -e
|
||||
|
||||
ccache -s
|
||||
|
||||
git submodule update --init --recursive
|
||||
ccache -sv
|
||||
|
||||
mkdir build || true && cd build
|
||||
cmake .. \
|
||||
|
|
|
@ -6,9 +6,7 @@
|
|||
# Exit on error, rather than continuing with the rest of the script.
|
||||
set -e
|
||||
|
||||
ccache -s
|
||||
|
||||
git submodule update --init --recursive
|
||||
ccache -sv
|
||||
|
||||
mkdir build || true && cd build
|
||||
cmake .. \
|
||||
|
@ -54,9 +52,9 @@ DESTDIR="$PWD/AppDir" ninja install
|
|||
rm -vf AppDir/usr/bin/suyu-cmd AppDir/usr/bin/suyu-tester
|
||||
|
||||
# Download tools needed to build an AppImage
|
||||
wget -nc https://git.suyu.dev/suyu/ext-linux-bin/raw/branch/main/appimage/deploy-linux.sh
|
||||
wget -nc https://git.suyu.dev/suyu/ext-linux-bin/raw/branch/main/appimage/exec-x86_64.so
|
||||
wget -nc https://git.suyu.dev/suyu/AppImageKit-checkrt/raw/branch/gh-workflow/AppRun
|
||||
wget -nc https://gitlab.com/suyu-emu/ext-linux-bin/-/raw/main/appimage/deploy-linux.sh
|
||||
wget -nc https://gitlab.com/suyu-emu/ext-linux-bin/-/raw/main/appimage/exec-x86_64.so
|
||||
wget -nc https://gitlab.com/suyu-emu/AppImageKit-checkrt/-/raw/old/AppRun.sh
|
||||
|
||||
# Set executable bit
|
||||
chmod 755 \
|
||||
|
|
|
@ -8,9 +8,7 @@ set -e
|
|||
|
||||
#cd /suyu
|
||||
|
||||
ccache -s
|
||||
|
||||
git submodule update --init --recursive
|
||||
ccache -sv
|
||||
|
||||
rm -rf build
|
||||
mkdir -p build && cd build
|
||||
|
|
|
@ -8,7 +8,7 @@ name: 'suyu verify'
|
|||
|
||||
on:
|
||||
pull_request:
|
||||
# branches: [ "dev" ]
|
||||
branches: [ "dev" ]
|
||||
paths:
|
||||
- 'src/**'
|
||||
- 'CMakeModules/**'
|
||||
|
@ -19,7 +19,7 @@ on:
|
|||
# paths-ignore:
|
||||
# - 'src/android/**'
|
||||
push:
|
||||
# branches: [ "dev" ]
|
||||
branches: [ "dev" ]
|
||||
paths:
|
||||
- 'src/**'
|
||||
- 'CMakeModules/**'
|
||||
|
|
5
.gitmodules
vendored
5
.gitmodules
vendored
|
@ -1,4 +1,6 @@
|
|||
# SPDX-FileCopyrightText: 2014 Citra Emulator Project
|
||||
# SPDX-FileCopyrightText: 2024 suyu Emulator Project
|
||||
# SPDX-FileCopyrightText: 2024 Torzu Emulator Project
|
||||
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
[submodule "enet"]
|
||||
|
@ -67,3 +69,6 @@
|
|||
[submodule "Vulkan-Utility-Libraries"]
|
||||
path = externals/Vulkan-Utility-Libraries
|
||||
url = https://github.com/KhronosGroup/Vulkan-Utility-Libraries.git
|
||||
[submodule "externals/boost-headers"]
|
||||
path = externals/boost-headers
|
||||
url = https://github.com/boostorg/headers.git
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
# SPDX-FileCopyrightText: 2018 yuzu Emulator Project
|
||||
# SPDX-FileCopyrightText: 2024 suyu Emulator Project
|
||||
# SPDX-FileCopyrightText: 2024 Torzu Emulator Project
|
||||
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
cmake_minimum_required(VERSION 3.22)
|
||||
|
@ -276,18 +277,8 @@ if (ARCHITECTURE_arm64 AND (ANDROID OR ${CMAKE_SYSTEM_NAME} STREQUAL "Linux"))
|
|||
add_definitions(-DHAS_NCE=1)
|
||||
endif()
|
||||
|
||||
# Configure C++ standard
|
||||
# ===========================
|
||||
|
||||
if (MSVC)
|
||||
add_compile_options($<$<COMPILE_LANGUAGE:CXX>:/std:c++20>)
|
||||
|
||||
# boost still makes use of deprecated result_of.
|
||||
add_definitions(-D_HAS_DEPRECATED_RESULT_OF)
|
||||
else()
|
||||
set(CMAKE_CXX_STANDARD 20)
|
||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||
endif()
|
||||
set(CMAKE_CXX_STANDARD 20)
|
||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||
|
||||
# Output binaries to bin/
|
||||
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/bin)
|
||||
|
@ -296,7 +287,6 @@ set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/bin)
|
|||
# =======================================================================
|
||||
|
||||
# Enforce the search mode of non-required packages for better and shorter failure messages
|
||||
find_package(Boost 1.79.0 REQUIRED context)
|
||||
find_package(enet 1.3 MODULE)
|
||||
find_package(fmt 9 REQUIRED)
|
||||
find_package(LLVM 17.0.2 MODULE COMPONENTS Demangle)
|
||||
|
@ -354,11 +344,6 @@ if (SUYU_TESTS)
|
|||
find_package(Catch2 3.0.1 REQUIRED)
|
||||
endif()
|
||||
|
||||
# boost:asio has functions that require AcceptEx et al
|
||||
if (MINGW)
|
||||
find_library(MSWSOCK_LIBRARY mswsock REQUIRED)
|
||||
endif()
|
||||
|
||||
if(ENABLE_OPENSSL)
|
||||
find_package(OpenSSL 1.1.1 REQUIRED)
|
||||
endif()
|
||||
|
@ -685,8 +670,6 @@ function(create_target_directory_groups target_name)
|
|||
endforeach()
|
||||
endfunction()
|
||||
|
||||
# Prevent boost from linking against libs when building
|
||||
target_link_libraries(Boost::headers INTERFACE Boost::disable_autolinking)
|
||||
# Adjustments for MSVC + Ninja
|
||||
if (MSVC AND CMAKE_GENERATOR STREQUAL "Ninja")
|
||||
add_compile_options(
|
||||
|
|
20
README.md
20
README.md
|
@ -6,10 +6,9 @@ SPDX-License-Identifier: GPL-3.0-or-later
|
|||
|
||||
**Note**: We do not support or condone piracy in any form. In order to use suyu, you'll need keys from your real Switch system, and games which you have legally obtained and paid for. We do not intend to make money or profit from this project.
|
||||
|
||||
We're in need of developers. Please join our chat below or DM a dev if you want to contribute!
|
||||
This repo is currently based on Yuzu EA 4176 but the code will be rewritten for legal and performance reasons.
|
||||
We're in need of developers. Please join our chat below if you want to contribute!
|
||||
This repo was based on Yuzu EA 4176 but the code is being rewritten from the ground up for legal and performance reasons.
|
||||
|
||||
Our only website is suyu.dev so please be cautious when using other sites offering builds/downloads.
|
||||
|
||||
<hr />
|
||||
|
||||
|
@ -23,13 +22,12 @@ Our only website is suyu.dev so please be cautious when using other sites offeri
|
|||
|
||||
<h4 align="center"><b>suyu</b> was the continuation of the world's most popular, open-source Nintendo Switch emulator, yuzu, but is now something more.
|
||||
<br>
|
||||
It is written in C++ with portability in mind, and we actively provide builds for Windows, Linux and Android, iOS may come later.
|
||||
It is written in C++ with portability in mind, and we actively provide builds for Windows, Linux, Android and iOS potentially coming soon.
|
||||
|
||||
</h4>
|
||||
|
||||
<p align="center">
|
||||
<a href="https://chat.suyu.dev">Chat</a> |
|
||||
<a href="https://www.reddit.com/r/suyu/">Reddit</a> |
|
||||
<a href="#status">Status</a> |
|
||||
<a href="#development">Development</a> |
|
||||
<a href="#downloads">Downloads</a> |
|
||||
|
@ -56,7 +54,7 @@ We currently have builds over at the [Releases](https://git.suyu.dev/suyu/suyu/r
|
|||
|
||||
This project is completely free and open source, and anyone can contribute to help improve suyu.
|
||||
|
||||
Most of the development happens on Git. For development discussion, please join us in our [Chat](https://chat.suyu.dev) or [Subreddit](reddit.com/r/suyu/), you can also contact a developer.
|
||||
Most of the development happens on the Git. For development discussion, please join us in our [Chat](https://chat.suyu.dev) or contact a developer.
|
||||
|
||||
If you want to contribute, please take a look at the [Contributor's Guide](https://git.suyu.dev/suyu/suyu/wiki/Contributing) and [Developer Information](https://git.suyu.dev/suyu/suyu/wiki/Developer-Information).
|
||||
You can also contact any of the developers on the Chat to learn more about the current state of suyu.
|
||||
|
@ -67,27 +65,25 @@ You can also contact any of the developers on the Chat to learn more about the c
|
|||
* __Linux__: [Releases](https://git.suyu.dev/suyu/suyu/releases)
|
||||
* __macOS__: [Releases](https://git.suyu.dev/suyu/suyu/releases)
|
||||
* __Android__: [Releases](https://git.suyu.dev/suyu/suyu/releases)
|
||||
###### We currently do not provide builds for iOS, however if you would like, you could try the experimental [Sudachi Emulator](https://sudachi.emuplace.app/) and it's bigger project: [Folium](https://apps.apple.com/us/app/folium/id6498623389).
|
||||
###### We currently do not provide builds for iOS, however if you would like, you could try the experimental [Sudachi](https://github.com/emuPlace/Sudachi/releases)/[Folium](https://github.com/jarrodnorwell/Folium/releases).
|
||||
|
||||
If you want daily builds then [Click here](https://git.suyu.dev/suyu/suyu/actions).
|
||||
If you don't know how to download the daily builds then [Click here](https://git.suyu.dev/suyu/suyu/raw/branch/dev/img/daily-builds.png)
|
||||
|
||||
We have official builds [here.](https://git.suyu.dev/suyu/suyu/releases)<br>If any website or person is claiming to have a build for suyu, take that with a grain of salt and let us know.
|
||||
|
||||
For Multiplayer, we recommend using the "Yuzu Online" patch, install instructions can be found on Reddit and their Discord.
|
||||
We have official builds [here.](https://git.suyu.dev/suyu/suyu/releases)<br>If any website or person is claiming to have a build for suyu, take that with a grain of salt.
|
||||
|
||||
## Building
|
||||
|
||||
* __Windows__: [Windows Build](https://git.suyu.dev/suyu/suyu/wiki/Building-For-Windows)
|
||||
* __Linux__: [Linux Build](https://git.suyu.dev/suyu/suyu/wiki/Building-For-Linux)
|
||||
* __Android__: [Android Build](https://git.suyu.dev/suyu/suyu/wiki/Building-For-Android)
|
||||
* __MacOS__: [MacOS Build](https://git.suyu.dev/suyu/suyu/wiki/Building-for-macOS)
|
||||
* __macOS__: [macOS Build](https://git.suyu.dev/suyu/suyu/wiki/Building-for-macOS)
|
||||
|
||||
|
||||
|
||||
## Support
|
||||
|
||||
If you have any questions, don't hesitate to ask us in our [Chat](https://chat.suyu.dev) or [Subreddit](https://www.reddit.com/r/suyu/), make an issue or contact a developer. We don't bite!
|
||||
If you have any questions, don't hesitate to ask us in our [chat](https://chat.suyu.dev), make an issue or contact a developer. We don't bite!
|
||||
|
||||
|
||||
## License
|
||||
|
|
5
externals/CMakeLists.txt
vendored
5
externals/CMakeLists.txt
vendored
|
@ -1,4 +1,6 @@
|
|||
# SPDX-FileCopyrightText: 2016 Citra Emulator Project
|
||||
# SPDX-FileCopyrightText: 2024 suyu Emulator Project
|
||||
# SPDX-FileCopyrightText: 2024 Torzu Emulator Project
|
||||
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
# Dynarmic has cmake_minimum_required(3.12) and we may want to override
|
||||
|
@ -160,6 +162,9 @@ if (SUYU_USE_EXTERNAL_VULKAN_UTILITY_LIBRARIES)
|
|||
add_subdirectory(Vulkan-Utility-Libraries)
|
||||
endif()
|
||||
|
||||
# Boost headers
|
||||
add_subdirectory(boost-headers)
|
||||
|
||||
# TZDB (Time Zone Database)
|
||||
add_subdirectory(nx_tzdb)
|
||||
|
||||
|
|
1
externals/boost-headers
vendored
Submodule
1
externals/boost-headers
vendored
Submodule
|
@ -0,0 +1 @@
|
|||
Subproject commit 0456900fadde4b07c84760eadea4ccc9f948fe28
|
Binary file not shown.
Before Width: | Height: | Size: 249 KiB |
|
@ -13,7 +13,7 @@
|
|||
#include "common/polyfill_ranges.h"
|
||||
|
||||
namespace AudioCore {
|
||||
constexpr u32 CurrentRevision = 12;
|
||||
constexpr u32 CurrentRevision = 11;
|
||||
|
||||
enum class SupportTags {
|
||||
CommandProcessingTimeEstimatorVersion4,
|
||||
|
|
|
@ -54,8 +54,7 @@ public:
|
|||
const s32 to_register{std::min(std::min(appended_count, BufferAppendLimit),
|
||||
BufferAppendLimit - registered_count)};
|
||||
|
||||
out_buffers.reserve(to_register);
|
||||
for (s32 i = 0; i < to_register; ++i) {
|
||||
for (s32 i = 0; i < to_register; i++) {
|
||||
s32 index{appended_index - appended_count};
|
||||
if (index < 0) {
|
||||
index += N;
|
||||
|
@ -181,7 +180,6 @@ public:
|
|||
return 0;
|
||||
}
|
||||
|
||||
buffers_flushed.reserve(registered_count + appended_count);
|
||||
while (registered_count > 0) {
|
||||
auto index{registered_index - registered_count};
|
||||
if (index < 0) {
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
# SPDX-FileCopyrightText: 2018 yuzu Emulator Project
|
||||
# SPDX-FileCopyrightText: 2024 suyu Emulator Project
|
||||
# SPDX-FileCopyrightText: 2024 Torzu Emulator Project
|
||||
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
if (DEFINED ENV{AZURECIREPO})
|
||||
|
@ -262,7 +263,7 @@ if (CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
|
|||
)
|
||||
endif()
|
||||
|
||||
target_link_libraries(common PUBLIC Boost::context Boost::headers fmt::fmt microprofile stb::headers Threads::Threads)
|
||||
target_link_libraries(common PUBLIC Boost::headers fmt::fmt microprofile stb::headers Threads::Threads)
|
||||
target_link_libraries(common PRIVATE lz4::lz4 zstd::zstd LLVM::Demangle)
|
||||
|
||||
if (ANDROID)
|
||||
|
|
|
@ -1,91 +1,52 @@
|
|||
// SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project
|
||||
// SPDX-FileCopyrightText: Copyright 2024 suyu Emulator Project
|
||||
// SPDX-FileCopyrightText: Copyright 2024 Torzu Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#include <mutex>
|
||||
|
||||
#include "common/assert.h"
|
||||
#include "common/fiber.h"
|
||||
#include "common/virtual_buffer.h"
|
||||
|
||||
#include <boost/context/detail/fcontext.hpp>
|
||||
#define MINICORO_IMPL
|
||||
#include "common/minicoro.h"
|
||||
|
||||
namespace Common {
|
||||
|
||||
constexpr std::size_t default_stack_size = 512 * 1024;
|
||||
|
||||
struct Fiber::FiberImpl {
|
||||
FiberImpl() : stack{default_stack_size}, rewind_stack{default_stack_size} {}
|
||||
|
||||
VirtualBuffer<u8> stack;
|
||||
VirtualBuffer<u8> rewind_stack;
|
||||
FiberImpl() {}
|
||||
|
||||
std::mutex guard;
|
||||
std::function<void()> entry_point;
|
||||
std::function<void()> rewind_point;
|
||||
std::shared_ptr<Fiber> previous_fiber;
|
||||
bool is_thread_fiber{};
|
||||
bool released{};
|
||||
bool is_thread_fiber{};
|
||||
Fiber* next_fiber{};
|
||||
Fiber** next_fiber_ptr;
|
||||
std::function<void()> entry_point;
|
||||
|
||||
u8* stack_limit{};
|
||||
u8* rewind_stack_limit{};
|
||||
boost::context::detail::fcontext_t context{};
|
||||
boost::context::detail::fcontext_t rewind_context{};
|
||||
mco_coro* context;
|
||||
};
|
||||
|
||||
void Fiber::SetRewindPoint(std::function<void()>&& rewind_func) {
|
||||
impl->rewind_point = std::move(rewind_func);
|
||||
}
|
||||
|
||||
void Fiber::Start(boost::context::detail::transfer_t& transfer) {
|
||||
ASSERT(impl->previous_fiber != nullptr);
|
||||
impl->previous_fiber->impl->context = transfer.fctx;
|
||||
impl->previous_fiber->impl->guard.unlock();
|
||||
impl->previous_fiber.reset();
|
||||
impl->entry_point();
|
||||
UNREACHABLE();
|
||||
}
|
||||
|
||||
void Fiber::OnRewind([[maybe_unused]] boost::context::detail::transfer_t& transfer) {
|
||||
ASSERT(impl->context != nullptr);
|
||||
impl->context = impl->rewind_context;
|
||||
impl->rewind_context = nullptr;
|
||||
u8* tmp = impl->stack_limit;
|
||||
impl->stack_limit = impl->rewind_stack_limit;
|
||||
impl->rewind_stack_limit = tmp;
|
||||
impl->rewind_point();
|
||||
UNREACHABLE();
|
||||
}
|
||||
|
||||
void Fiber::FiberStartFunc(boost::context::detail::transfer_t transfer) {
|
||||
auto* fiber = static_cast<Fiber*>(transfer.data);
|
||||
fiber->Start(transfer);
|
||||
}
|
||||
|
||||
void Fiber::RewindStartFunc(boost::context::detail::transfer_t transfer) {
|
||||
auto* fiber = static_cast<Fiber*>(transfer.data);
|
||||
fiber->OnRewind(transfer);
|
||||
Fiber::Fiber() : impl{std::make_unique<FiberImpl>()} {
|
||||
impl->is_thread_fiber = true;
|
||||
}
|
||||
|
||||
Fiber::Fiber(std::function<void()>&& entry_point_func) : impl{std::make_unique<FiberImpl>()} {
|
||||
impl->entry_point = std::move(entry_point_func);
|
||||
impl->stack_limit = impl->stack.data();
|
||||
impl->rewind_stack_limit = impl->rewind_stack.data();
|
||||
u8* stack_base = impl->stack_limit + default_stack_size;
|
||||
impl->context =
|
||||
boost::context::detail::make_fcontext(stack_base, impl->stack.size(), FiberStartFunc);
|
||||
auto desc = mco_desc_init(
|
||||
[](mco_coro* coro) { reinterpret_cast<Fiber*>(coro->user_data)->impl->entry_point(); }, 0);
|
||||
desc.user_data = this;
|
||||
mco_result res = mco_create(&impl->context, &desc);
|
||||
ASSERT(res == MCO_SUCCESS);
|
||||
}
|
||||
|
||||
Fiber::Fiber() : impl{std::make_unique<FiberImpl>()} {}
|
||||
|
||||
Fiber::~Fiber() {
|
||||
if (impl->released) {
|
||||
return;
|
||||
}
|
||||
// Make sure the Fiber is not being used
|
||||
const bool locked = impl->guard.try_lock();
|
||||
ASSERT_MSG(locked, "Destroying a fiber that's still running");
|
||||
if (locked) {
|
||||
impl->guard.unlock();
|
||||
DestroyPre();
|
||||
if (impl->is_thread_fiber) {
|
||||
DestroyThreadFiber();
|
||||
} else {
|
||||
DestroyWorkFiber();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -94,42 +55,66 @@ void Fiber::Exit() {
|
|||
if (!impl->is_thread_fiber) {
|
||||
return;
|
||||
}
|
||||
impl->guard.unlock();
|
||||
DestroyPre();
|
||||
DestroyThreadFiber();
|
||||
}
|
||||
|
||||
void Fiber::DestroyPre() {
|
||||
// Make sure the Fiber is not being used
|
||||
const bool locked = impl->guard.try_lock();
|
||||
ASSERT_MSG(locked, "Destroying a fiber that's still running");
|
||||
if (locked) {
|
||||
impl->guard.unlock();
|
||||
}
|
||||
impl->released = true;
|
||||
}
|
||||
|
||||
void Fiber::Rewind() {
|
||||
ASSERT(impl->rewind_point);
|
||||
ASSERT(impl->rewind_context == nullptr);
|
||||
u8* stack_base = impl->rewind_stack_limit + default_stack_size;
|
||||
impl->rewind_context =
|
||||
boost::context::detail::make_fcontext(stack_base, impl->stack.size(), RewindStartFunc);
|
||||
boost::context::detail::jump_fcontext(impl->rewind_context, this);
|
||||
void Fiber::DestroyWorkFiber() {
|
||||
mco_result res = mco_destroy(impl->context);
|
||||
ASSERT(res == MCO_SUCCESS);
|
||||
}
|
||||
|
||||
void Fiber::DestroyThreadFiber() {
|
||||
if (*impl->next_fiber_ptr) {
|
||||
*impl->next_fiber_ptr = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void Fiber::YieldTo(std::weak_ptr<Fiber> weak_from, Fiber& to) {
|
||||
to.impl->guard.lock();
|
||||
to.impl->previous_fiber = weak_from.lock();
|
||||
|
||||
auto transfer = boost::context::detail::jump_fcontext(to.impl->context, &to);
|
||||
|
||||
// "from" might no longer be valid if the thread was killed
|
||||
if (auto from = weak_from.lock()) {
|
||||
if (from->impl->previous_fiber == nullptr) {
|
||||
ASSERT_MSG(false, "previous_fiber is nullptr!");
|
||||
return;
|
||||
if (!from->impl->is_thread_fiber) {
|
||||
// Set next fiber
|
||||
from->impl->next_fiber = &to;
|
||||
// Yield from thread
|
||||
if (!from->impl->released) {
|
||||
from->impl->guard.unlock();
|
||||
mco_yield(from->impl->context);
|
||||
}
|
||||
} else {
|
||||
from->impl->guard.lock();
|
||||
// Keep running next fiber until they've ran out
|
||||
auto& next_fiber_ptr = from->impl->next_fiber_ptr;
|
||||
next_fiber_ptr = &from->impl->next_fiber;
|
||||
*next_fiber_ptr = &to;
|
||||
for ([[maybe_unused]] unsigned round = 0; *next_fiber_ptr; round++) {
|
||||
auto next = *next_fiber_ptr;
|
||||
*next_fiber_ptr = nullptr;
|
||||
next_fiber_ptr = &next->impl->next_fiber;
|
||||
// Stop if new thread is thread fiber
|
||||
if (next->impl->is_thread_fiber)
|
||||
break;
|
||||
// Resume new thread
|
||||
next->impl->guard.lock();
|
||||
mco_result res = mco_resume(next->impl->context);
|
||||
ASSERT(res == MCO_SUCCESS);
|
||||
}
|
||||
from->impl->guard.unlock();
|
||||
}
|
||||
from->impl->previous_fiber->impl->context = transfer.fctx;
|
||||
from->impl->previous_fiber->impl->guard.unlock();
|
||||
from->impl->previous_fiber.reset();
|
||||
}
|
||||
}
|
||||
|
||||
std::shared_ptr<Fiber> Fiber::ThreadToFiber() {
|
||||
std::shared_ptr<Fiber> fiber = std::shared_ptr<Fiber>{new Fiber()};
|
||||
fiber->impl->guard.lock();
|
||||
fiber->impl->is_thread_fiber = true;
|
||||
return fiber;
|
||||
return std::shared_ptr<Fiber>{new Fiber()};
|
||||
}
|
||||
|
||||
} // namespace Common
|
||||
} // namespace Common
|
|
@ -1,4 +1,6 @@
|
|||
// SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project
|
||||
// SPDX-FileCopyrightText: Copyright 2024 suyu Emulator Project
|
||||
// SPDX-FileCopyrightText: Copyright 2024 Torzu Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#pragma once
|
||||
|
@ -6,9 +8,7 @@
|
|||
#include <functional>
|
||||
#include <memory>
|
||||
|
||||
namespace boost::context::detail {
|
||||
struct transfer_t;
|
||||
}
|
||||
#include "common/minicoro.h"
|
||||
|
||||
namespace Common {
|
||||
|
||||
|
@ -38,28 +38,21 @@ public:
|
|||
Fiber(Fiber&&) = default;
|
||||
Fiber& operator=(Fiber&&) = default;
|
||||
|
||||
/// Yields control from Fiber 'from' to Fiber 'to'
|
||||
/// Fiber 'from' must be the currently running fiber.
|
||||
static void YieldTo(std::weak_ptr<Fiber> weak_from, Fiber& to);
|
||||
[[nodiscard]] static std::shared_ptr<Fiber> ThreadToFiber();
|
||||
|
||||
void SetRewindPoint(std::function<void()>&& rewind_func);
|
||||
|
||||
void Rewind();
|
||||
|
||||
/// Only call from main thread's fiber
|
||||
void Exit();
|
||||
|
||||
private:
|
||||
Fiber();
|
||||
|
||||
void OnRewind(boost::context::detail::transfer_t& transfer);
|
||||
void Start(boost::context::detail::transfer_t& transfer);
|
||||
static void FiberStartFunc(boost::context::detail::transfer_t transfer);
|
||||
static void RewindStartFunc(boost::context::detail::transfer_t transfer);
|
||||
void DestroyPre();
|
||||
void DestroyWorkFiber();
|
||||
void DestroyThreadFiber();
|
||||
|
||||
struct FiberImpl;
|
||||
std::unique_ptr<FiberImpl> impl;
|
||||
};
|
||||
|
||||
} // namespace Common
|
||||
} // namespace Common
|
|
@ -14,7 +14,7 @@ template <typename T>
|
|||
struct fmt::formatter<T, std::enable_if_t<std::is_enum_v<T>, char>>
|
||||
: formatter<std::underlying_type_t<T>> {
|
||||
template <typename FormatContext>
|
||||
auto format(const T& value, FormatContext& ctx) const -> decltype(ctx.out()) {
|
||||
auto format(const T& value, FormatContext& ctx) -> decltype(ctx.out()) {
|
||||
return fmt::formatter<std::underlying_type_t<T>>::format(
|
||||
static_cast<std::underlying_type_t<T>>(value), ctx);
|
||||
}
|
||||
|
|
2077
src/common/minicoro.h
Normal file
2077
src/common/minicoro.h
Normal file
File diff suppressed because it is too large
Load diff
|
@ -262,7 +262,7 @@ struct fmt::formatter<Common::PhysicalAddress> {
|
|||
return ctx.begin();
|
||||
}
|
||||
template <typename FormatContext>
|
||||
auto format(const Common::PhysicalAddress& addr, FormatContext& ctx) const {
|
||||
auto format(const Common::PhysicalAddress& addr, FormatContext& ctx) {
|
||||
return fmt::format_to(ctx.out(), "{:#x}", static_cast<u64>(addr.GetValue()));
|
||||
}
|
||||
};
|
||||
|
@ -273,7 +273,7 @@ struct fmt::formatter<Common::ProcessAddress> {
|
|||
return ctx.begin();
|
||||
}
|
||||
template <typename FormatContext>
|
||||
auto format(const Common::ProcessAddress& addr, FormatContext& ctx) const {
|
||||
auto format(const Common::ProcessAddress& addr, FormatContext& ctx) {
|
||||
return fmt::format_to(ctx.out(), "{:#x}", static_cast<u64>(addr.GetValue()));
|
||||
}
|
||||
};
|
||||
|
@ -284,7 +284,7 @@ struct fmt::formatter<Common::VirtualAddress> {
|
|||
return ctx.begin();
|
||||
}
|
||||
template <typename FormatContext>
|
||||
auto format(const Common::VirtualAddress& addr, FormatContext& ctx) const {
|
||||
auto format(const Common::VirtualAddress& addr, FormatContext& ctx) {
|
||||
return fmt::format_to(ctx.out(), "{:#x}", static_cast<u64>(addr.GetValue()));
|
||||
}
|
||||
};
|
||||
|
|
|
@ -22,7 +22,7 @@ struct fmt::formatter<Dynarmic::A32::CoprocReg> {
|
|||
return ctx.begin();
|
||||
}
|
||||
template <typename FormatContext>
|
||||
auto format(const Dynarmic::A32::CoprocReg& reg, FormatContext& ctx) const {
|
||||
auto format(const Dynarmic::A32::CoprocReg& reg, FormatContext& ctx) {
|
||||
return fmt::format_to(ctx.out(), "cp{}", static_cast<size_t>(reg));
|
||||
}
|
||||
};
|
||||
|
|
|
@ -80,7 +80,6 @@ FileSys::VirtualFile GetGameFileFromPath(const FileSys::VirtualFilesystem& vfs,
|
|||
if (filename == "00") {
|
||||
const auto dir = vfs->OpenDirectory(dir_name, FileSys::OpenMode::Read);
|
||||
std::vector<FileSys::VirtualFile> concat;
|
||||
concat.reserve(0x10);
|
||||
|
||||
for (u32 i = 0; i < 0x10; ++i) {
|
||||
const auto file_name = fmt::format("{:02X}", i);
|
||||
|
|
|
@ -9,7 +9,6 @@
|
|||
#include <thread>
|
||||
|
||||
#include <boost/algorithm/string.hpp>
|
||||
#include <fmt/ranges.h>
|
||||
|
||||
#include "common/hex_util.h"
|
||||
#include "common/logging/log.h"
|
||||
|
@ -482,7 +481,6 @@ void GDBStub::HandleQuery(std::string_view command) {
|
|||
// beginning of list
|
||||
const auto& threads = GetProcess()->GetThreadList();
|
||||
std::vector<std::string> thread_ids;
|
||||
thread_ids.reserve(threads.size());
|
||||
for (const auto& thread : threads) {
|
||||
thread_ids.push_back(fmt::format("{:x}", thread.GetThreadId()));
|
||||
}
|
||||
|
|
|
@ -261,7 +261,7 @@ std::vector<NcaID> PlaceholderCache::List() const {
|
|||
std::vector<NcaID> out;
|
||||
for (const auto& sdir : dir->GetSubdirectories()) {
|
||||
for (const auto& file : sdir->GetFiles()) {
|
||||
const auto& name = file->GetName();
|
||||
const auto name = file->GetName();
|
||||
if (name.length() == 36 && name.ends_with(".nca")) {
|
||||
out.push_back(Common::HexStringToArray<0x10>(name.substr(0, 32)));
|
||||
}
|
||||
|
|
|
@ -117,9 +117,7 @@ std::vector<std::shared_ptr<NCA>> NSP::GetNCAsCollapsed() const {
|
|||
if (extracted)
|
||||
LOG_WARNING(Service_FS, "called on an NSP that is of type extracted.");
|
||||
std::vector<std::shared_ptr<NCA>> out;
|
||||
out.reserve(ncas.size());
|
||||
for (const auto& map : ncas) {
|
||||
out.reserve(map.second.size());
|
||||
for (const auto& inner_map : map.second)
|
||||
out.push_back(inner_map.second);
|
||||
}
|
||||
|
|
|
@ -10,7 +10,7 @@ namespace FileSys::SystemArchive {
|
|||
|
||||
namespace NgWord1Data {
|
||||
|
||||
[[maybe_unused]] constexpr std::size_t NUMBER_WORD_TXT_FILES = 0x10;
|
||||
constexpr std::size_t NUMBER_WORD_TXT_FILES = 0x10;
|
||||
|
||||
// Should this archive replacement mysteriously not work on a future game, consider updating.
|
||||
constexpr std::array<u8, 4> VERSION_DAT{0x0, 0x0, 0x0, 0x20}; // 11.0.1 System Version
|
||||
|
@ -24,7 +24,7 @@ constexpr std::array<u8, 30> WORD_TXT{
|
|||
|
||||
VirtualDir NgWord1() {
|
||||
std::vector<VirtualFile> files;
|
||||
files.reserve(files.size() + 2);
|
||||
files.reserve(NgWord1Data::NUMBER_WORD_TXT_FILES);
|
||||
|
||||
for (std::size_t i = 0; i < files.size(); ++i) {
|
||||
files.push_back(MakeArrayFile(NgWord1Data::WORD_TXT, fmt::format("{}.txt", i)));
|
||||
|
@ -54,7 +54,7 @@ constexpr std::array<u8, 0x2C> AC_NX_DATA{
|
|||
|
||||
VirtualDir NgWord2() {
|
||||
std::vector<VirtualFile> files;
|
||||
files.reserve(NgWord2Data::NUMBER_AC_NX_FILES + 4);
|
||||
files.reserve(NgWord2Data::NUMBER_AC_NX_FILES * 3);
|
||||
|
||||
for (std::size_t i = 0; i < NgWord2Data::NUMBER_AC_NX_FILES; ++i) {
|
||||
files.push_back(MakeArrayFile(NgWord2Data::AC_NX_DATA, fmt::format("ac_{}_b1_nx", i)));
|
||||
|
|
|
@ -37,7 +37,6 @@ const static std::map<std::string, const std::map<const char*, const std::vector
|
|||
|
||||
static void GenerateFiles(std::vector<VirtualFile>& directory,
|
||||
const std::map<const char*, const std::vector<u8>>& files) {
|
||||
directory.reserve(files.size());
|
||||
for (const auto& [filename, data] : files) {
|
||||
const auto data_copy{data};
|
||||
const std::string filename_copy{filename};
|
||||
|
@ -55,7 +54,6 @@ static std::vector<VirtualFile> GenerateZoneinfoFiles() {
|
|||
|
||||
VirtualDir TimeZoneBinary() {
|
||||
std::vector<VirtualDir> america_sub_dirs;
|
||||
america_sub_dirs.reserve(tzdb_america_dirs.size());
|
||||
for (const auto& [dir_name, files] : tzdb_america_dirs) {
|
||||
std::vector<VirtualFile> vfs_files;
|
||||
GenerateFiles(vfs_files, files);
|
||||
|
@ -64,7 +62,6 @@ VirtualDir TimeZoneBinary() {
|
|||
}
|
||||
|
||||
std::vector<VirtualDir> zoneinfo_sub_dirs;
|
||||
zoneinfo_sub_dirs.reserve(tzdb_zoneinfo_dirs.size());
|
||||
for (const auto& [dir_name, files] : tzdb_zoneinfo_dirs) {
|
||||
std::vector<VirtualFile> vfs_files;
|
||||
GenerateFiles(vfs_files, files);
|
||||
|
|
|
@ -38,8 +38,7 @@ VirtualDir CachedVfsDirectory::GetSubdirectory(std::string_view dir_name) const
|
|||
|
||||
std::vector<VirtualFile> CachedVfsDirectory::GetFiles() const {
|
||||
std::vector<VirtualFile> out;
|
||||
out.reserve(files.size());
|
||||
for (const auto& [_, file] : files) {
|
||||
for (auto& [file_name, file] : files) {
|
||||
out.push_back(file);
|
||||
}
|
||||
return out;
|
||||
|
@ -47,8 +46,7 @@ std::vector<VirtualFile> CachedVfsDirectory::GetFiles() const {
|
|||
|
||||
std::vector<VirtualDir> CachedVfsDirectory::GetSubdirectories() const {
|
||||
std::vector<VirtualDir> out;
|
||||
out.reserve(dirs.size());
|
||||
for (auto& [_, dir] : dirs) {
|
||||
for (auto& [dir_name, dir] : dirs) {
|
||||
out.push_back(dir);
|
||||
}
|
||||
return out;
|
||||
|
|
|
@ -121,7 +121,7 @@ void WindowSystem::RequestAppletVisibilityState(Applet& applet, bool visible) {
|
|||
void WindowSystem::OnOperationModeChanged() {
|
||||
std::scoped_lock lk{m_lock};
|
||||
|
||||
for (const auto& [_, applet] : m_applets) {
|
||||
for (const auto& [aruid, applet] : m_applets) {
|
||||
std::scoped_lock lk2{applet->lock};
|
||||
applet->lifecycle_manager.OnOperationAndPerformanceModeChanged();
|
||||
}
|
||||
|
@ -130,7 +130,7 @@ void WindowSystem::OnOperationModeChanged() {
|
|||
void WindowSystem::OnExitRequested() {
|
||||
std::scoped_lock lk{m_lock};
|
||||
|
||||
for (const auto& [_, applet] : m_applets) {
|
||||
for (const auto& [aruid, applet] : m_applets) {
|
||||
std::scoped_lock lk2{applet->lock};
|
||||
applet->lifecycle_manager.RequestExit();
|
||||
}
|
||||
|
@ -156,7 +156,7 @@ void WindowSystem::OnHomeButtonPressed(ButtonPressDuration type) {
|
|||
|
||||
void WindowSystem::PruneTerminatedAppletsLocked() {
|
||||
for (auto it = m_applets.begin(); it != m_applets.end(); /* ... */) {
|
||||
const auto& [_, applet] = *it;
|
||||
const auto& [aruid, applet] = *it;
|
||||
|
||||
std::scoped_lock lk{applet->lock};
|
||||
|
||||
|
|
|
@ -119,7 +119,7 @@ Result LANDiscovery::Scan(std::span<NetworkInfo> out_networks, s16& out_count,
|
|||
std::this_thread::sleep_for(std::chrono::seconds(1));
|
||||
|
||||
std::scoped_lock lock{packet_mutex};
|
||||
for (const auto& [_, info] : scan_results) {
|
||||
for (const auto& [key, info] : scan_results) {
|
||||
if (out_count >= static_cast<s16>(out_networks.size())) {
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -15,7 +15,6 @@
|
|||
#endif
|
||||
|
||||
#include <fmt/format.h>
|
||||
#include <fmt/ranges.h>
|
||||
|
||||
#include "common/fs/file.h"
|
||||
#include "common/fs/fs.h"
|
||||
|
|
|
@ -348,7 +348,7 @@ Result IApplicationManagerInterface::ListApplicationRecord(
|
|||
size_t i = 0;
|
||||
u8 ii = 24;
|
||||
|
||||
for (const auto& [_, game] : installed_games) {
|
||||
for (const auto& [slot, game] : installed_games) {
|
||||
if (i >= limit) {
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -167,7 +167,7 @@ constexpr inline Result GetSpanBetweenTimePoints(s64* out_seconds, const SteadyC
|
|||
template <>
|
||||
struct fmt::formatter<Service::PSC::Time::TimeType> : fmt::formatter<fmt::string_view> {
|
||||
template <typename FormatContext>
|
||||
auto format(Service::PSC::Time::TimeType type, FormatContext& ctx) const {
|
||||
auto format(Service::PSC::Time::TimeType type, FormatContext& ctx) {
|
||||
const string_view name = [type] {
|
||||
using Service::PSC::Time::TimeType;
|
||||
switch (type) {
|
||||
|
@ -270,4 +270,4 @@ struct fmt::formatter<Service::PSC::Time::ContinuousAdjustmentTimePoint>
|
|||
time_point.rtc_offset, time_point.diff_scale, time_point.shift_amount,
|
||||
time_point.lower, time_point.upper);
|
||||
}
|
||||
};
|
||||
};
|
|
@ -28,7 +28,7 @@ ServiceManager::ServiceManager(Kernel::KernelCore& kernel_) : kernel{kernel_} {
|
|||
}
|
||||
|
||||
ServiceManager::~ServiceManager() {
|
||||
for (auto& [_, port] : service_ports) {
|
||||
for (auto& [name, port] : service_ports) {
|
||||
port->Close();
|
||||
}
|
||||
|
||||
|
|
|
@ -571,7 +571,7 @@ SDLDriver::~SDLDriver() {
|
|||
std::vector<Common::ParamPackage> SDLDriver::GetInputDevices() const {
|
||||
std::vector<Common::ParamPackage> devices;
|
||||
std::unordered_map<int, std::shared_ptr<SDLJoystick>> joycon_pairs;
|
||||
for (const auto& [_, value] : joystick_map) {
|
||||
for (const auto& [key, value] : joystick_map) {
|
||||
for (const auto& joystick : value) {
|
||||
if (!joystick->GetSDLJoystick()) {
|
||||
continue;
|
||||
|
@ -591,7 +591,7 @@ std::vector<Common::ParamPackage> SDLDriver::GetInputDevices() const {
|
|||
}
|
||||
|
||||
// Add dual controllers
|
||||
for (const auto& [_, value] : joystick_map) {
|
||||
for (const auto& [key, value] : joystick_map) {
|
||||
for (const auto& joystick : value) {
|
||||
if (joystick->IsJoyconRight()) {
|
||||
if (!joycon_pairs.contains(joystick->GetPort())) {
|
||||
|
|
|
@ -184,7 +184,7 @@ struct fmt::formatter<Shader::Backend::GLASM::Id> {
|
|||
return ctx.begin();
|
||||
}
|
||||
template <typename FormatContext>
|
||||
auto format(Shader::Backend::GLASM::Id id, FormatContext& ctx) const {
|
||||
auto format(Shader::Backend::GLASM::Id id, FormatContext& ctx) {
|
||||
return Shader::Backend::GLASM::FormatTo<true>(ctx, id);
|
||||
}
|
||||
};
|
||||
|
@ -195,7 +195,7 @@ struct fmt::formatter<Shader::Backend::GLASM::Register> {
|
|||
return ctx.begin();
|
||||
}
|
||||
template <typename FormatContext>
|
||||
auto format(const Shader::Backend::GLASM::Register& value, FormatContext& ctx) const {
|
||||
auto format(const Shader::Backend::GLASM::Register& value, FormatContext& ctx) {
|
||||
if (value.type != Shader::Backend::GLASM::Type::Register) {
|
||||
throw Shader::InvalidArgument("Register value type is not register");
|
||||
}
|
||||
|
@ -209,7 +209,7 @@ struct fmt::formatter<Shader::Backend::GLASM::ScalarRegister> {
|
|||
return ctx.begin();
|
||||
}
|
||||
template <typename FormatContext>
|
||||
auto format(const Shader::Backend::GLASM::ScalarRegister& value, FormatContext& ctx) const {
|
||||
auto format(const Shader::Backend::GLASM::ScalarRegister& value, FormatContext& ctx) {
|
||||
if (value.type != Shader::Backend::GLASM::Type::Register) {
|
||||
throw Shader::InvalidArgument("Register value type is not register");
|
||||
}
|
||||
|
@ -223,7 +223,7 @@ struct fmt::formatter<Shader::Backend::GLASM::ScalarU32> {
|
|||
return ctx.begin();
|
||||
}
|
||||
template <typename FormatContext>
|
||||
auto format(const Shader::Backend::GLASM::ScalarU32& value, FormatContext& ctx) const {
|
||||
auto format(const Shader::Backend::GLASM::ScalarU32& value, FormatContext& ctx) {
|
||||
switch (value.type) {
|
||||
case Shader::Backend::GLASM::Type::Void:
|
||||
break;
|
||||
|
@ -244,7 +244,7 @@ struct fmt::formatter<Shader::Backend::GLASM::ScalarS32> {
|
|||
return ctx.begin();
|
||||
}
|
||||
template <typename FormatContext>
|
||||
auto format(const Shader::Backend::GLASM::ScalarS32& value, FormatContext& ctx) const {
|
||||
auto format(const Shader::Backend::GLASM::ScalarS32& value, FormatContext& ctx) {
|
||||
switch (value.type) {
|
||||
case Shader::Backend::GLASM::Type::Void:
|
||||
break;
|
||||
|
@ -265,7 +265,7 @@ struct fmt::formatter<Shader::Backend::GLASM::ScalarF32> {
|
|||
return ctx.begin();
|
||||
}
|
||||
template <typename FormatContext>
|
||||
auto format(const Shader::Backend::GLASM::ScalarF32& value, FormatContext& ctx) const {
|
||||
auto format(const Shader::Backend::GLASM::ScalarF32& value, FormatContext& ctx) {
|
||||
switch (value.type) {
|
||||
case Shader::Backend::GLASM::Type::Void:
|
||||
break;
|
||||
|
@ -286,7 +286,7 @@ struct fmt::formatter<Shader::Backend::GLASM::ScalarF64> {
|
|||
return ctx.begin();
|
||||
}
|
||||
template <typename FormatContext>
|
||||
auto format(const Shader::Backend::GLASM::ScalarF64& value, FormatContext& ctx) const {
|
||||
auto format(const Shader::Backend::GLASM::ScalarF64& value, FormatContext& ctx) {
|
||||
switch (value.type) {
|
||||
case Shader::Backend::GLASM::Type::Void:
|
||||
break;
|
||||
|
|
|
@ -196,11 +196,8 @@ Id Texture(EmitContext& ctx, IR::TextureInstInfo info, [[maybe_unused]] const IR
|
|||
}
|
||||
|
||||
Id TextureImage(EmitContext& ctx, IR::TextureInstInfo info, const IR::Value& index) {
|
||||
// if (!index.IsImmediate() || index.Type() != Shader::IR::Type::U32 || index.U32() != 0) {
|
||||
// throw NotImplementedException("Indirect image indexing");
|
||||
// }
|
||||
if (index.Type() != Shader::IR::Type::U32) {
|
||||
LOG_WARNING(Shader_SPIRV, "Non-U32 type provided as index: {}", index.Type());
|
||||
if (!index.IsImmediate() || index.U32() != 0) {
|
||||
throw NotImplementedException("Indirect image indexing");
|
||||
}
|
||||
if (info.type == TextureType::Buffer) {
|
||||
const TextureBufferDefinition& def{ctx.texture_buffers.at(info.descriptor_index)};
|
||||
|
@ -218,11 +215,8 @@ Id TextureImage(EmitContext& ctx, IR::TextureInstInfo info, const IR::Value& ind
|
|||
}
|
||||
|
||||
std::pair<Id, bool> Image(EmitContext& ctx, const IR::Value& index, IR::TextureInstInfo info) {
|
||||
// if (!index.IsImmediate() || index.Type() != Shader::IR::Type::U32 || index.U32() != 0) {
|
||||
// throw NotImplementedException("Indirect image indexing");
|
||||
// }
|
||||
if (index.Type() != Shader::IR::Type::U32) {
|
||||
LOG_WARNING(Shader_SPIRV, "Non-U32 type provided as index: {}", index.Type());
|
||||
if (!index.IsImmediate() || index.U32() != 0) {
|
||||
throw NotImplementedException("Indirect image indexing");
|
||||
}
|
||||
if (info.type == TextureType::Buffer) {
|
||||
const ImageBufferDefinition def{ctx.image_buffers.at(info.descriptor_index)};
|
||||
|
|
|
@ -250,7 +250,7 @@ struct fmt::formatter<Shader::IR::Attribute> {
|
|||
return ctx.begin();
|
||||
}
|
||||
template <typename FormatContext>
|
||||
auto format(const Shader::IR::Attribute& attribute, FormatContext& ctx) const {
|
||||
auto format(const Shader::IR::Attribute& attribute, FormatContext& ctx) {
|
||||
return fmt::format_to(ctx.out(), "{}", Shader::IR::NameOf(attribute));
|
||||
}
|
||||
};
|
||||
|
|
|
@ -52,7 +52,7 @@ struct fmt::formatter<Shader::IR::Condition> {
|
|||
return ctx.begin();
|
||||
}
|
||||
template <typename FormatContext>
|
||||
auto format(const Shader::IR::Condition& cond, FormatContext& ctx) const {
|
||||
auto format(const Shader::IR::Condition& cond, FormatContext& ctx) {
|
||||
return fmt::format_to(ctx.out(), "{}", Shader::IR::NameOf(cond));
|
||||
}
|
||||
};
|
||||
|
|
|
@ -55,7 +55,7 @@ struct fmt::formatter<Shader::IR::FlowTest> {
|
|||
return ctx.begin();
|
||||
}
|
||||
template <typename FormatContext>
|
||||
auto format(const Shader::IR::FlowTest& flow_test, FormatContext& ctx) const {
|
||||
auto format(const Shader::IR::FlowTest& flow_test, FormatContext& ctx) {
|
||||
return fmt::format_to(ctx.out(), "{}", Shader::IR::NameOf(flow_test));
|
||||
}
|
||||
};
|
||||
|
|
|
@ -54,7 +54,7 @@ constexpr Type F64x2{Type::F64x2};
|
|||
constexpr Type F64x3{Type::F64x3};
|
||||
constexpr Type F64x4{Type::F64x4};
|
||||
|
||||
constexpr OpcodeMeta META_TABLE[] {
|
||||
constexpr OpcodeMeta META_TABLE[]{
|
||||
#define OPCODE(name_token, type_token, ...) \
|
||||
{ \
|
||||
.name{#name_token}, \
|
||||
|
@ -103,7 +103,7 @@ struct fmt::formatter<Shader::IR::Opcode> {
|
|||
return ctx.begin();
|
||||
}
|
||||
template <typename FormatContext>
|
||||
auto format(const Shader::IR::Opcode& op, FormatContext& ctx) const {
|
||||
auto format(const Shader::IR::Opcode& op, FormatContext& ctx) {
|
||||
return fmt::format_to(ctx.out(), "{}", Shader::IR::NameOf(op));
|
||||
}
|
||||
};
|
||||
|
|
|
@ -33,7 +33,7 @@ struct fmt::formatter<Shader::IR::Pred> {
|
|||
return ctx.begin();
|
||||
}
|
||||
template <typename FormatContext>
|
||||
auto format(const Shader::IR::Pred& pred, FormatContext& ctx) const {
|
||||
auto format(const Shader::IR::Pred& pred, FormatContext& ctx) {
|
||||
if (pred == Shader::IR::Pred::PT) {
|
||||
return fmt::format_to(ctx.out(), "PT");
|
||||
} else {
|
||||
|
|
|
@ -319,7 +319,7 @@ struct fmt::formatter<Shader::IR::Reg> {
|
|||
return ctx.begin();
|
||||
}
|
||||
template <typename FormatContext>
|
||||
auto format(const Shader::IR::Reg& reg, FormatContext& ctx) const {
|
||||
auto format(const Shader::IR::Reg& reg, FormatContext& ctx) {
|
||||
if (reg == Shader::IR::Reg::RZ) {
|
||||
return fmt::format_to(ctx.out(), "RZ");
|
||||
} else if (static_cast<int>(reg) >= 0 && static_cast<int>(reg) < 255) {
|
||||
|
|
|
@ -54,7 +54,7 @@ struct fmt::formatter<Shader::IR::Type> {
|
|||
return ctx.begin();
|
||||
}
|
||||
template <typename FormatContext>
|
||||
auto format(const Shader::IR::Type& type, FormatContext& ctx) const {
|
||||
auto format(const Shader::IR::Type& type, FormatContext& ctx) {
|
||||
return fmt::format_to(ctx.out(), "{}", NameOf(type));
|
||||
}
|
||||
};
|
||||
|
|
|
@ -102,7 +102,7 @@ struct fmt::formatter<Shader::Maxwell::Location> {
|
|||
return ctx.begin();
|
||||
}
|
||||
template <typename FormatContext>
|
||||
auto format(const Shader::Maxwell::Location& location, FormatContext& ctx) const {
|
||||
auto format(const Shader::Maxwell::Location& location, FormatContext& ctx) {
|
||||
return fmt::format_to(ctx.out(), "{:04x}", location.Offset());
|
||||
}
|
||||
};
|
||||
|
|
|
@ -23,7 +23,7 @@ struct fmt::formatter<Shader::Maxwell::Opcode> {
|
|||
return ctx.begin();
|
||||
}
|
||||
template <typename FormatContext>
|
||||
auto format(const Shader::Maxwell::Opcode& opcode, FormatContext& ctx) const {
|
||||
auto format(const Shader::Maxwell::Opcode& opcode, FormatContext& ctx) {
|
||||
return fmt::format_to(ctx.out(), "{}", NameOf(opcode));
|
||||
}
|
||||
};
|
||||
|
|
|
@ -69,7 +69,7 @@ void ConfigureApplets::Setup(const ConfigurationShared::Builder& builder) {
|
|||
|
||||
applets_hold.emplace(setting->Id(), widget);
|
||||
}
|
||||
for (const auto& [_, widget] : applets_hold) {
|
||||
for (const auto& [label, widget] : applets_hold) {
|
||||
library_applets_layout.addWidget(widget);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -164,7 +164,7 @@ void ConfigureAudio::Setup(const ConfigurationShared::Builder& builder) {
|
|||
}
|
||||
}
|
||||
|
||||
for (const auto& [_, widget] : hold) {
|
||||
for (const auto& [id, widget] : hold) {
|
||||
layout.addWidget(widget);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -79,7 +79,7 @@ void ConfigureCpu::Setup(const ConfigurationShared::Builder& builder) {
|
|||
}
|
||||
}
|
||||
|
||||
for (const auto& [_, widget] : unsafe_hold) {
|
||||
for (const auto& [label, widget] : unsafe_hold) {
|
||||
unsafe_layout->addWidget(widget);
|
||||
}
|
||||
|
||||
|
|
|
@ -81,10 +81,10 @@ void ConfigureGeneral::Setup(const ConfigurationShared::Builder& builder) {
|
|||
}
|
||||
}
|
||||
|
||||
for (const auto& [_, widget] : general_hold) {
|
||||
for (const auto& [id, widget] : general_hold) {
|
||||
general_layout.addWidget(widget);
|
||||
}
|
||||
for (const auto& [_, widget] : linux_hold) {
|
||||
for (const auto& [id, widget] : linux_hold) {
|
||||
linux_layout.addWidget(widget);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -358,7 +358,7 @@ void ConfigureGraphics::Setup(const ConfigurationShared::Builder& builder) {
|
|||
}
|
||||
}
|
||||
|
||||
for (const auto& [_, widget] : hold_graphics) {
|
||||
for (const auto& [id, widget] : hold_graphics) {
|
||||
graphics_layout.addWidget(widget);
|
||||
}
|
||||
|
||||
|
|
|
@ -53,7 +53,7 @@ void ConfigureGraphicsAdvanced::Setup(const ConfigurationShared::Builder& builde
|
|||
checkbox_enable_compute_pipelines = widget;
|
||||
}
|
||||
}
|
||||
for (const auto& [_, widget] : hold) {
|
||||
for (const auto& [id, widget] : hold) {
|
||||
layout.addWidget(widget);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -50,7 +50,7 @@ void ConfigureLinuxTab::Setup(const ConfigurationShared::Builder& builder) {
|
|||
linux_hold.insert({setting->Id(), widget});
|
||||
}
|
||||
|
||||
for (const auto& [_, widget] : linux_hold) {
|
||||
for (const auto& [id, widget] : linux_hold) {
|
||||
linux_layout.addWidget(widget);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -174,10 +174,10 @@ void ConfigureSystem::Setup(const ConfigurationShared::Builder& builder) {
|
|||
widget->deleteLater();
|
||||
}
|
||||
}
|
||||
for (const auto& [_, widget] : core_hold) {
|
||||
for (const auto& [label, widget] : core_hold) {
|
||||
core_layout.addWidget(widget);
|
||||
}
|
||||
for (const auto& [_, widget] : system_hold) {
|
||||
for (const auto& [id, widget] : system_hold) {
|
||||
system_layout.addWidget(widget);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -83,7 +83,7 @@ static void PopulateResolutionComboBox(QComboBox* screenshot_height, QWidget* pa
|
|||
const auto& enumeration =
|
||||
Settings::EnumMetadata<Settings::ResolutionSetup>::Canonicalizations();
|
||||
std::set<u32> resolutions{};
|
||||
for (const auto& [_, value] : enumeration) {
|
||||
for (const auto& [name, value] : enumeration) {
|
||||
const float up_factor = GetUpFactor(value);
|
||||
u32 height_undocked = Layout::ScreenUndocked::Height * up_factor;
|
||||
u32 height_docked = Layout::ScreenDocked::Height * up_factor;
|
||||
|
|
|
@ -61,7 +61,7 @@ std::vector<std::string> InputProfiles::GetInputProfileNames() {
|
|||
|
||||
auto it = map_profiles.cbegin();
|
||||
while (it != map_profiles.cend()) {
|
||||
const auto& [profile_name, _] = *it;
|
||||
const auto& [profile_name, config] = *it;
|
||||
if (!ProfileExistsInFilesystem(profile_name)) {
|
||||
it = map_profiles.erase(it);
|
||||
continue;
|
||||
|
|
|
@ -135,7 +135,7 @@ QWidget* Widget::CreateCombobox(std::function<std::string()>& serializer,
|
|||
const ComboboxTranslations* enumeration{nullptr};
|
||||
if (combobox_enumerations.contains(type)) {
|
||||
enumeration = &combobox_enumerations.at(type);
|
||||
for (const auto& [_, name] : *enumeration) {
|
||||
for (const auto& [id, name] : *enumeration) {
|
||||
combobox->addItem(name);
|
||||
}
|
||||
} else {
|
||||
|
@ -223,7 +223,7 @@ QWidget* Widget::CreateRadioGroup(std::function<std::string()>& serializer,
|
|||
};
|
||||
|
||||
if (!Settings::IsConfiguringGlobal()) {
|
||||
for (const auto& [_, button] : radio_buttons) {
|
||||
for (const auto& [id, button] : radio_buttons) {
|
||||
QObject::connect(button, &QAbstractButton::clicked, [touch]() { touch(); });
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,8 +9,6 @@
|
|||
#include <memory>
|
||||
#include <thread>
|
||||
|
||||
#include <fmt/ranges.h>
|
||||
|
||||
#include "core/hle/service/am/applet_manager.h"
|
||||
#include "core/loader/nca.h"
|
||||
#include "core/loader/nro.h"
|
||||
|
|
|
@ -87,7 +87,7 @@ std::optional<std::filesystem::path> GetCurrentUserPlayTimePath(
|
|||
std::vector<PlayTimeElement> elements;
|
||||
elements.reserve(play_time_db.size());
|
||||
|
||||
for (const auto& [program_id, play_time] : play_time_db) {
|
||||
for (auto& [program_id, play_time] : play_time_db) {
|
||||
if (program_id != 0) {
|
||||
elements.push_back(PlayTimeElement{program_id, play_time});
|
||||
}
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
// SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project
|
||||
// SPDX-FileCopyrightText: Copyright 2024 Torzu Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#include <atomic>
|
||||
|
@ -271,43 +272,4 @@ TEST_CASE("Fibers::StartRace", "[common]") {
|
|||
REQUIRE(test_control.value3 == 1);
|
||||
}
|
||||
|
||||
class TestControl4;
|
||||
|
||||
class TestControl4 {
|
||||
public:
|
||||
TestControl4() {
|
||||
fiber1 = std::make_shared<Fiber>([this] { DoWork(); });
|
||||
goal_reached = false;
|
||||
rewinded = false;
|
||||
}
|
||||
|
||||
void Execute() {
|
||||
thread_fiber = Fiber::ThreadToFiber();
|
||||
Fiber::YieldTo(thread_fiber, *fiber1);
|
||||
thread_fiber->Exit();
|
||||
}
|
||||
|
||||
void DoWork() {
|
||||
fiber1->SetRewindPoint([this] { DoWork(); });
|
||||
if (rewinded) {
|
||||
goal_reached = true;
|
||||
Fiber::YieldTo(fiber1, *thread_fiber);
|
||||
}
|
||||
rewinded = true;
|
||||
fiber1->Rewind();
|
||||
}
|
||||
|
||||
std::shared_ptr<Common::Fiber> fiber1;
|
||||
std::shared_ptr<Common::Fiber> thread_fiber;
|
||||
bool goal_reached;
|
||||
bool rewinded;
|
||||
};
|
||||
|
||||
TEST_CASE("Fibers::Rewind", "[common]") {
|
||||
TestControl4 test_control{};
|
||||
test_control.Execute();
|
||||
REQUIRE(test_control.goal_reached);
|
||||
REQUIRE(test_control.rewinded);
|
||||
}
|
||||
|
||||
} // namespace Common
|
||||
|
|
|
@ -45,7 +45,7 @@ public:
|
|||
|
||||
[[nodiscard]] unsigned Count() const noexcept {
|
||||
unsigned count = 0;
|
||||
for (const auto& [_, value] : page_table) {
|
||||
for (const auto& [index, value] : page_table) {
|
||||
count += value;
|
||||
}
|
||||
return count;
|
||||
|
|
|
@ -45,7 +45,7 @@ public:
|
|||
// Vic does not know which nvdec is producing frames for it, so search all the fds here for
|
||||
// the given offset.
|
||||
for (auto& map : m_presentation_order) {
|
||||
for (auto& [offset, _] : map.second) {
|
||||
for (auto& [offset, frame] : map.second) {
|
||||
if (offset == search_offset) {
|
||||
return map.first;
|
||||
}
|
||||
|
@ -53,7 +53,7 @@ public:
|
|||
}
|
||||
|
||||
for (auto& map : m_decode_order) {
|
||||
for (auto& [offset, _] : map.second) {
|
||||
for (auto& [offset, frame] : map.second) {
|
||||
if (offset == search_offset) {
|
||||
return map.first;
|
||||
}
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
template <>
|
||||
struct fmt::formatter<VideoCore::Surface::PixelFormat> : fmt::formatter<fmt::string_view> {
|
||||
template <typename FormatContext>
|
||||
auto format(VideoCore::Surface::PixelFormat format, FormatContext& ctx) const {
|
||||
auto format(VideoCore::Surface::PixelFormat format, FormatContext& ctx) {
|
||||
using VideoCore::Surface::PixelFormat;
|
||||
const string_view name = [format] {
|
||||
switch (format) {
|
||||
|
@ -234,7 +234,7 @@ struct fmt::formatter<VideoCore::Surface::PixelFormat> : fmt::formatter<fmt::str
|
|||
template <>
|
||||
struct fmt::formatter<VideoCommon::ImageType> : fmt::formatter<fmt::string_view> {
|
||||
template <typename FormatContext>
|
||||
auto format(VideoCommon::ImageType type, FormatContext& ctx) const {
|
||||
auto format(VideoCommon::ImageType type, FormatContext& ctx) {
|
||||
const string_view name = [type] {
|
||||
using VideoCommon::ImageType;
|
||||
switch (type) {
|
||||
|
@ -262,7 +262,7 @@ struct fmt::formatter<VideoCommon::Extent3D> {
|
|||
}
|
||||
|
||||
template <typename FormatContext>
|
||||
auto format(const VideoCommon::Extent3D& extent, FormatContext& ctx) const {
|
||||
auto format(const VideoCommon::Extent3D& extent, FormatContext& ctx) {
|
||||
return fmt::format_to(ctx.out(), "{{{}, {}, {}}}", extent.width, extent.height,
|
||||
extent.depth);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue