forked from eden-emu/eden
Compare commits
9 commits
Author | SHA1 | Date | |
---|---|---|---|
853a6a7357 | |||
c412f51876 | |||
a508e0b0e0 | |||
c13f5dc69c | |||
59e7258624 | |||
c450de3c1f | |||
09113ecff8 | |||
64f5510372 | |||
3a795fcf8b |
18 changed files with 185 additions and 88 deletions
29
.ci/macos/build.sh
Executable file
29
.ci/macos/build.sh
Executable file
|
@ -0,0 +1,29 @@
|
||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
export LIBVULKAN_PATH="/opt/homebrew/lib/libvulkan.1.dylib"
|
||||||
|
|
||||||
|
if [ -z "$BUILD_TYPE" ]; then
|
||||||
|
export BUILD_TYPE="Release"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "$DEVEL" != "true" ]; then
|
||||||
|
export EXTRA_CMAKE_FLAGS=("${EXTRA_CMAKE_FLAGS[@]}" -DENABLE_QT_UPDATE_CHECKER=ON)
|
||||||
|
fi
|
||||||
|
|
||||||
|
mkdir -p build
|
||||||
|
cd build
|
||||||
|
|
||||||
|
cmake .. -GNinja \
|
||||||
|
-DYUZU_TESTS=OFF \
|
||||||
|
-DYUZU_USE_BUNDLED_QT=OFF \
|
||||||
|
-DENABLE_QT_TRANSLATION=ON \
|
||||||
|
-DYUZU_ENABLE_LTO=ON \
|
||||||
|
-DUSE_DISCORD_PRESENCE=ON \
|
||||||
|
-DYUZU_CMD=OFF \
|
||||||
|
-DYUZU_ROOM_STANDALONE=OFF \
|
||||||
|
-DCMAKE_CXX_FLAGS="-w" \
|
||||||
|
-DCMAKE_BUILD_TYPE="$BUILD_TYPE" \
|
||||||
|
-DYUZU_USE_PRECOMPILED_HEADERS=OFF \
|
||||||
|
"${EXTRA_CMAKE_FLAGS[@]}"
|
||||||
|
|
||||||
|
ninja
|
34
.ci/macos/package.sh
Executable file
34
.ci/macos/package.sh
Executable file
|
@ -0,0 +1,34 @@
|
||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
# credit: escary and hauntek
|
||||||
|
|
||||||
|
cd build
|
||||||
|
APP=./bin/eden.app
|
||||||
|
|
||||||
|
macdeployqt "$APP"
|
||||||
|
macdeployqt "$APP" -always-overwrite
|
||||||
|
|
||||||
|
# FixMachOLibraryPaths
|
||||||
|
find "$APP/Contents/Frameworks" ""$APP/Contents/MacOS"" -type f \( -name "*.dylib" -o -perm +111 \) | while read file; do
|
||||||
|
if file "$file" | grep -q "Mach-O"; then
|
||||||
|
otool -L "$file" | awk '/@rpath\// {print $1}' | while read lib; do
|
||||||
|
lib_name="${lib##*/}"
|
||||||
|
new_path="@executable_path/../Frameworks/$lib_name"
|
||||||
|
install_name_tool -change "$lib" "$new_path" "$file"
|
||||||
|
done
|
||||||
|
|
||||||
|
if [[ "$file" == *.dylib ]]; then
|
||||||
|
lib_name="${file##*/}"
|
||||||
|
new_id="@executable_path/../Frameworks/$lib_name"
|
||||||
|
install_name_tool -id "$new_id" "$file"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
codesign --deep --force --verify --verbose --sign - "$APP"
|
||||||
|
|
||||||
|
ZIP_NAME="eden-macos.zip"
|
||||||
|
mkdir -p artifacts
|
||||||
|
|
||||||
|
mv $APP .
|
||||||
|
7z a -tzip "$ZIP_NAME" eden.app
|
||||||
|
mv "$ZIP_NAME" artifacts/
|
3
.gitmodules
vendored
3
.gitmodules
vendored
|
@ -19,6 +19,9 @@
|
||||||
[submodule "cpp-httplib"]
|
[submodule "cpp-httplib"]
|
||||||
path = externals/cpp-httplib
|
path = externals/cpp-httplib
|
||||||
url = https://github.com/yhirose/cpp-httplib.git
|
url = https://github.com/yhirose/cpp-httplib.git
|
||||||
|
[submodule "ffmpeg"]
|
||||||
|
path = externals/ffmpeg/ffmpeg
|
||||||
|
url = https://github.com/FFmpeg/FFmpeg.git
|
||||||
[submodule "vcpkg"]
|
[submodule "vcpkg"]
|
||||||
path = externals/vcpkg
|
path = externals/vcpkg
|
||||||
url = https://github.com/microsoft/vcpkg.git
|
url = https://github.com/microsoft/vcpkg.git
|
||||||
|
|
|
@ -491,13 +491,15 @@ set(FFmpeg_COMPONENTS
|
||||||
avutil
|
avutil
|
||||||
swscale)
|
swscale)
|
||||||
|
|
||||||
set(CPM_SOURCE_CACHE ${CMAKE_SOURCE_DIR}/.cache/cpm)
|
|
||||||
|
|
||||||
add_subdirectory(externals)
|
add_subdirectory(externals)
|
||||||
|
|
||||||
if (ENABLE_QT)
|
if (ENABLE_QT)
|
||||||
if (YUZU_USE_BUNDLED_QT)
|
if (YUZU_USE_BUNDLED_QT)
|
||||||
|
if (APPLE)
|
||||||
|
download_qt(6.7.3)
|
||||||
|
else()
|
||||||
download_qt(6.8.3)
|
download_qt(6.8.3)
|
||||||
|
endif()
|
||||||
else()
|
else()
|
||||||
message(STATUS "Using system Qt")
|
message(STATUS "Using system Qt")
|
||||||
if (NOT Qt6_DIR)
|
if (NOT Qt6_DIR)
|
||||||
|
|
|
@ -221,7 +221,7 @@ set(MOLTENVK_DIR "${CMAKE_BINARY_DIR}/externals/MoltenVK")
|
||||||
set(MOLTENVK_TAR "${CMAKE_BINARY_DIR}/externals/MoltenVK.tar")
|
set(MOLTENVK_TAR "${CMAKE_BINARY_DIR}/externals/MoltenVK.tar")
|
||||||
if (NOT EXISTS ${MOLTENVK_DIR})
|
if (NOT EXISTS ${MOLTENVK_DIR})
|
||||||
if (NOT EXISTS ${MOLTENVK_TAR})
|
if (NOT EXISTS ${MOLTENVK_TAR})
|
||||||
file(DOWNLOAD https://github.com/KhronosGroup/MoltenVK/releases/download/v1.2.10-rc2/MoltenVK-all.tar
|
file(DOWNLOAD https://github.com/KhronosGroup/MoltenVK/releases/download/v1.2.11-artifacts/MoltenVK-all.tar
|
||||||
${MOLTENVK_TAR} SHOW_PROGRESS)
|
${MOLTENVK_TAR} SHOW_PROGRESS)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
|
9
externals/CMakeLists.txt
vendored
9
externals/CMakeLists.txt
vendored
|
@ -84,22 +84,17 @@ if (YUZU_USE_EXTERNAL_SDL2)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
include(CPM)
|
include(CPM)
|
||||||
|
set(CPM_SOURCE_CACHE ${CMAKE_SOURCE_DIR}/.cache/cpm)
|
||||||
set(CPM_USE_LOCAL_PACKAGES OFF)
|
set(CPM_USE_LOCAL_PACKAGES OFF)
|
||||||
|
|
||||||
if ("${YUZU_SYSTEM_PROFILE}" STREQUAL "steamdeck")
|
if ("${YUZU_SYSTEM_PROFILE}" STREQUAL "steamdeck")
|
||||||
set(SDL_HASH cc016b0046)
|
set(SDL_HASH cc016b0046)
|
||||||
set(SDL_PIPEWIRE OFF) # build errors out with this on
|
set(SDL_PIPEWIRE OFF) # build errors out with this on
|
||||||
set(SDL_SHA512SUM 34d5ef58da6a4f9efa6689c82f67badcbd741f5a4f562a9c2c30828fa839830fb07681c5dc6a7851520e261c8405a416ac0a2c2513b51984fb3b4fa4dcb3e20b)
|
|
||||||
else()
|
else()
|
||||||
set(SDL_HASH 2e4c12cd2c)
|
set(SDL_HASH 2e4c12cd2c)
|
||||||
set(SDL_SHA512SUM d95af47f469a312876f8ab361074a1e7b8083db19935a102d9c6e5887ace6008e64475a8c54b00164b40cad86492bb1b2366084efdd0b2555e5fea6d9c5da80e)
|
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
CPMAddPackage(
|
CPMAddPackage("gh:libsdl-org/SDL#${SDL_HASH}")
|
||||||
NAME SDL2
|
|
||||||
URL "https://github.com/libsdl-org/SDL/archive/${SDL_HASH}.zip"
|
|
||||||
URL_HASH SHA512=${SDL_SHA512SUM}
|
|
||||||
)
|
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
# ENet
|
# ENet
|
||||||
|
|
13
externals/ffmpeg/CMakeLists.txt
vendored
13
externals/ffmpeg/CMakeLists.txt
vendored
|
@ -19,17 +19,8 @@ if (NOT WIN32 AND NOT ANDROID)
|
||||||
message(FATAL_ERROR "Required program `autoconf` not found.")
|
message(FATAL_ERROR "Required program `autoconf` not found.")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
include(CPM)
|
set(FFmpeg_PREFIX ${PROJECT_SOURCE_DIR}/externals/ffmpeg/ffmpeg)
|
||||||
set(CPM_USE_LOCAL_PACKAGES OFF)
|
set(FFmpeg_BUILD_DIR ${PROJECT_BINARY_DIR}/externals/ffmpeg-build)
|
||||||
|
|
||||||
CPMAddPackage(
|
|
||||||
NAME ffmpeg
|
|
||||||
URL "https://github.com/ffmpeg/ffmpeg/archive/9c1294eadd.zip"
|
|
||||||
URL_HASH SHA512=2076e4cb843787c44718c70c4452517273dbc963ef98442f343762ade6c7b9f78555ae9b50a7c628844a15d8cb5e866c04e2f1acfb77093cea4fbc9edf3ad21a
|
|
||||||
)
|
|
||||||
|
|
||||||
set(FFmpeg_PREFIX ${ffmpeg_SOURCE_DIR})
|
|
||||||
set(FFmpeg_BUILD_DIR ${ffmpeg_BINARY_DIR})
|
|
||||||
set(FFmpeg_MAKEFILE ${FFmpeg_BUILD_DIR}/Makefile)
|
set(FFmpeg_MAKEFILE ${FFmpeg_BUILD_DIR}/Makefile)
|
||||||
make_directory(${FFmpeg_BUILD_DIR})
|
make_directory(${FFmpeg_BUILD_DIR})
|
||||||
|
|
||||||
|
|
1
externals/ffmpeg/ffmpeg
vendored
Submodule
1
externals/ffmpeg/ffmpeg
vendored
Submodule
|
@ -0,0 +1 @@
|
||||||
|
Subproject commit 9c1294eaddb88cb0e044c675ccae059a85fc9c6c
|
|
@ -728,26 +728,22 @@ Status BufferQueueProducer::Connect(const std::shared_ptr<IProducerListener>& li
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://android.googlesource.com/platform/frameworks/native/%2B/master/libs/gui/BufferQueueProducer.cpp#1457
|
|
||||||
Status BufferQueueProducer::Disconnect(NativeWindowApi api) {
|
Status BufferQueueProducer::Disconnect(NativeWindowApi api) {
|
||||||
LOG_DEBUG(Service_Nvnflinger, "disconnect api = {}", api);
|
LOG_DEBUG(Service_Nvnflinger, "api = {}", api);
|
||||||
|
|
||||||
std::shared_ptr<IConsumerListener> listener;
|
|
||||||
Status status = Status::NoError;
|
Status status = Status::NoError;
|
||||||
|
std::shared_ptr<IConsumerListener> listener;
|
||||||
|
|
||||||
{
|
{
|
||||||
std::scoped_lock lock{core->mutex};
|
std::scoped_lock lock{core->mutex};
|
||||||
|
|
||||||
core->WaitWhileAllocatingLocked();
|
core->WaitWhileAllocatingLocked();
|
||||||
|
|
||||||
if (core->is_abandoned) {
|
if (core->is_abandoned) {
|
||||||
|
// Disconnecting after the surface has been abandoned is a no-op.
|
||||||
return Status::NoError;
|
return Status::NoError;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (core->connected_api == NativeWindowApi::NoConnectedApi) {
|
|
||||||
LOG_DEBUG(Service_Nvnflinger, "disconnect: not connected (req = {})", api);
|
|
||||||
return Status::NoInit;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (api) {
|
switch (api) {
|
||||||
case NativeWindowApi::Egl:
|
case NativeWindowApi::Egl:
|
||||||
case NativeWindowApi::Cpu:
|
case NativeWindowApi::Cpu:
|
||||||
|
@ -762,20 +758,20 @@ Status BufferQueueProducer::Disconnect(NativeWindowApi api) {
|
||||||
buffer_wait_event->Signal();
|
buffer_wait_event->Signal();
|
||||||
listener = core->consumer_listener;
|
listener = core->consumer_listener;
|
||||||
} else {
|
} else {
|
||||||
LOG_ERROR(Service_Nvnflinger,
|
LOG_ERROR(Service_Nvnflinger, "still connected to another api (cur = {} req = {})",
|
||||||
"disconnect: still connected to another api (cur = {} req = {})",
|
|
||||||
core->connected_api, api);
|
core->connected_api, api);
|
||||||
status = Status::BadValue;
|
status = Status::BadValue;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
LOG_ERROR(Service_Nvnflinger, "disconnect: unknown api = {}", api);
|
LOG_ERROR(Service_Nvnflinger, "unknown api = {}", api);
|
||||||
status = Status::BadValue;
|
status = Status::BadValue;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (listener) {
|
// Call back without lock held
|
||||||
|
if (listener != nullptr) {
|
||||||
listener->OnBuffersReleased();
|
listener->OnBuffersReleased();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -40,22 +40,17 @@ Result IHOSBinderDriver::TransactParcel(s32 binder_id, u32 transaction_id,
|
||||||
}
|
}
|
||||||
|
|
||||||
Result IHOSBinderDriver::AdjustRefcount(s32 binder_id, s32 addval, s32 type) {
|
Result IHOSBinderDriver::AdjustRefcount(s32 binder_id, s32 addval, s32 type) {
|
||||||
LOG_DEBUG(Service_VI, "called id={}, addval={}, type={}", binder_id, addval, type);
|
LOG_WARNING(Service_VI, "(STUBBED) called id={}, addval={}, type={}", binder_id, addval, type);
|
||||||
R_UNLESS(type == 0 || type == 1, ResultUnknown);
|
|
||||||
m_server->AdjustRefcount(binder_id, addval, type == 1);
|
|
||||||
R_SUCCEED();
|
R_SUCCEED();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result IHOSBinderDriver::GetNativeHandle(s32 binder_id, u32 type_id,
|
Result IHOSBinderDriver::GetNativeHandle(s32 binder_id, u32 type_id,
|
||||||
OutCopyHandle<Kernel::KReadableEvent> out_handle) {
|
OutCopyHandle<Kernel::KReadableEvent> out_handle) {
|
||||||
LOG_DEBUG(Service_VI, "called id={}, type_id={}", binder_id, type_id);
|
LOG_WARNING(Service_VI, "(STUBBED) called id={}, type_id={}", binder_id, type_id);
|
||||||
|
|
||||||
const auto binder = m_server->TryGetBinder(binder_id);
|
const auto binder = m_server->TryGetBinder(binder_id);
|
||||||
R_UNLESS(binder != nullptr, ResultUnknown);
|
R_UNLESS(binder != nullptr, ResultUnknown);
|
||||||
|
|
||||||
auto native_handle = binder->GetNativeHandle(type_id);
|
|
||||||
R_UNLESS(native_handle != nullptr, ResultUnknown);
|
|
||||||
|
|
||||||
*out_handle = binder->GetNativeHandle(type_id);
|
*out_handle = binder->GetNativeHandle(type_id);
|
||||||
|
|
||||||
R_SUCCEED();
|
R_SUCCEED();
|
||||||
|
|
|
@ -17,7 +17,6 @@ s32 HosBinderDriverServer::RegisterBinder(std::shared_ptr<android::IBinder>&& bi
|
||||||
last_id++;
|
last_id++;
|
||||||
|
|
||||||
binders[last_id] = std::move(binder);
|
binders[last_id] = std::move(binder);
|
||||||
refcounts[last_id] = {}; // strong = 1, weak = 0
|
|
||||||
|
|
||||||
return last_id;
|
return last_id;
|
||||||
}
|
}
|
||||||
|
@ -26,29 +25,6 @@ void HosBinderDriverServer::UnregisterBinder(s32 binder_id) {
|
||||||
std::scoped_lock lk{lock};
|
std::scoped_lock lk{lock};
|
||||||
|
|
||||||
binders.erase(binder_id);
|
binders.erase(binder_id);
|
||||||
refcounts.erase(binder_id);
|
|
||||||
}
|
|
||||||
|
|
||||||
void HosBinderDriverServer::AdjustRefcount(s32 binder_id, s32 delta, bool is_weak) {
|
|
||||||
std::scoped_lock lk{lock};
|
|
||||||
|
|
||||||
auto search_rc = refcounts.find(binder_id);
|
|
||||||
if (search_rc == refcounts.end()) {
|
|
||||||
LOG_WARNING(Service_VI, "AdjustRefcount called for unknown binder id {}", binder_id);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto& rc = search_rc->second;
|
|
||||||
s32& counter = is_weak ? rc.weak : rc.strong;
|
|
||||||
counter += delta;
|
|
||||||
|
|
||||||
if (counter < 0)
|
|
||||||
counter = 0;
|
|
||||||
|
|
||||||
if (rc.strong == 0 && rc.weak == 0) {
|
|
||||||
binders.erase(binder_id);
|
|
||||||
refcounts.erase(search_rc);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<android::IBinder> HosBinderDriverServer::TryGetBinder(s32 id) const {
|
std::shared_ptr<android::IBinder> HosBinderDriverServer::TryGetBinder(s32 id) const {
|
||||||
|
|
|
@ -26,18 +26,10 @@ public:
|
||||||
|
|
||||||
std::shared_ptr<android::IBinder> TryGetBinder(s32 id) const;
|
std::shared_ptr<android::IBinder> TryGetBinder(s32 id) const;
|
||||||
|
|
||||||
void AdjustRefcount(s32 binder_id, s32 delta, bool is_weak);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
struct RefCounts {
|
|
||||||
s32 strong{1};
|
|
||||||
s32 weak{0};
|
|
||||||
};
|
|
||||||
|
|
||||||
mutable std::mutex lock;
|
|
||||||
s32 last_id = 0;
|
|
||||||
std::unordered_map<s32, std::shared_ptr<android::IBinder>> binders;
|
std::unordered_map<s32, std::shared_ptr<android::IBinder>> binders;
|
||||||
std::unordered_map<s32, RefCounts> refcounts;
|
mutable std::mutex lock;
|
||||||
|
s32 last_id{};
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace Service::Nvnflinger
|
} // namespace Service::Nvnflinger
|
||||||
|
|
|
@ -1373,8 +1373,8 @@ void TextureCacheRuntime::CopyImage(Image& dst, Image& src,
|
||||||
// these images that aren't size-compatible
|
// these images that aren't size-compatible
|
||||||
if (BytesPerBlock(src.info.format) != BytesPerBlock(dst.info.format)) {
|
if (BytesPerBlock(src.info.format) != BytesPerBlock(dst.info.format)) {
|
||||||
auto oneCopy = VideoCommon::ImageCopy{
|
auto oneCopy = VideoCommon::ImageCopy{
|
||||||
.src_offset = VideoCommon::Offset3D(0, 0, 0),
|
.src_offset = VideoCommon::Offset3D{0, 0, 0},
|
||||||
.dst_offset = VideoCommon::Offset3D(0, 0, 0),
|
.dst_offset = VideoCommon::Offset3D{0, 0, 0},
|
||||||
.extent = dst.info.size
|
.extent = dst.info.size
|
||||||
};
|
};
|
||||||
return ReinterpretImage(dst, src, std::span{&oneCopy, 1});
|
return ReinterpretImage(dst, src, std::span{&oneCopy, 1});
|
||||||
|
|
|
@ -15,7 +15,12 @@
|
||||||
#define VK_USE_PLATFORM_WAYLAND_KHR
|
#define VK_USE_PLATFORM_WAYLAND_KHR
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef __APPLE__
|
||||||
|
//#include <MoltenVK/mvk_vulkan.h>
|
||||||
#include <vulkan/vulkan.h>
|
#include <vulkan/vulkan.h>
|
||||||
|
#else
|
||||||
|
#include <vulkan/vulkan.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
// Sanitize macros
|
// Sanitize macros
|
||||||
#undef CreateEvent
|
#undef CreateEvent
|
||||||
|
|
|
@ -440,14 +440,13 @@ Instance Instance::Create(u32 version, Span<const char*> layers, Span<const char
|
||||||
#else
|
#else
|
||||||
constexpr VkFlags ci_flags{};
|
constexpr VkFlags ci_flags{};
|
||||||
#endif
|
#endif
|
||||||
// DO NOT TOUCH, breaks RNDA3!!
|
|
||||||
// Don't know why, but gloom + yellow line glitch appears
|
|
||||||
const VkApplicationInfo application_info{
|
const VkApplicationInfo application_info{
|
||||||
.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO,
|
.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO,
|
||||||
.pNext = nullptr,
|
.pNext = nullptr,
|
||||||
.pApplicationName = "yuzu Emulator",
|
.pApplicationName = "yuzu Emulator",
|
||||||
.applicationVersion = VK_MAKE_VERSION(1, 3, 0),
|
.applicationVersion = VK_MAKE_VERSION(1, 3, 0),
|
||||||
.pEngineName = "yuzu Emulator",
|
.pEngineName = "Eden Emulator",
|
||||||
.engineVersion = VK_MAKE_VERSION(1, 3, 0),
|
.engineVersion = VK_MAKE_VERSION(1, 3, 0),
|
||||||
.apiVersion = VK_API_VERSION_1_3,
|
.apiVersion = VK_API_VERSION_1_3,
|
||||||
};
|
};
|
||||||
|
|
|
@ -374,7 +374,7 @@ if (APPLE)
|
||||||
|
|
||||||
if (NOT USE_SYSTEM_MOLTENVK)
|
if (NOT USE_SYSTEM_MOLTENVK)
|
||||||
set(MOLTENVK_PLATFORM "macOS")
|
set(MOLTENVK_PLATFORM "macOS")
|
||||||
set(MOLTENVK_VERSION "v1.3.0")
|
set(MOLTENVK_VERSION "v1.2.11-artifacts")
|
||||||
download_moltenvk_external(${MOLTENVK_PLATFORM} ${MOLTENVK_VERSION})
|
download_moltenvk_external(${MOLTENVK_PLATFORM} ${MOLTENVK_VERSION})
|
||||||
endif()
|
endif()
|
||||||
find_library(MOLTENVK_LIBRARY MoltenVK REQUIRED)
|
find_library(MOLTENVK_LIBRARY MoltenVK REQUIRED)
|
||||||
|
|
|
@ -2,9 +2,23 @@
|
||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
#include <windows.h>
|
|
||||||
|
|
||||||
#include <wincon.h>
|
#include <wincon.h>
|
||||||
|
#include <windows.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __APPLE__
|
||||||
|
#include <cstdio>
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
#include <QProcess>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <signal.h>
|
||||||
|
#include <spawn.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#include "common/fs/path_util.h"
|
||||||
|
|
||||||
|
extern char** environ;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "common/logging/backend.h"
|
#include "common/logging/backend.h"
|
||||||
|
@ -12,18 +26,76 @@
|
||||||
#include "yuzu/uisettings.h"
|
#include "yuzu/uisettings.h"
|
||||||
|
|
||||||
namespace Debugger {
|
namespace Debugger {
|
||||||
|
#ifdef __APPLE__
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
pid_t g_terminal_pid = -1;
|
||||||
|
int g_saved_out = -1;
|
||||||
|
int g_saved_err = -1;
|
||||||
|
|
||||||
|
std::string GetLogFilePath() {
|
||||||
|
std::string dir = Common::FS::GetEdenPathString(Common::FS::EdenPath::LogDir);
|
||||||
|
if (!dir.empty() && dir.back() != '/')
|
||||||
|
dir.push_back('/');
|
||||||
|
return dir + "eden_log.txt";
|
||||||
|
}
|
||||||
|
|
||||||
|
void ShowMacConsole() {
|
||||||
|
const std::string logfile = GetLogFilePath();
|
||||||
|
if (logfile.empty())
|
||||||
|
return;
|
||||||
|
|
||||||
|
g_saved_out = dup(STDOUT_FILENO);
|
||||||
|
g_saved_err = dup(STDERR_FILENO);
|
||||||
|
|
||||||
|
int fd = ::open(logfile.c_str(), O_WRONLY | O_CREAT | O_APPEND, 0644);
|
||||||
|
if (fd == -1)
|
||||||
|
return;
|
||||||
|
dup2(fd, STDOUT_FILENO);
|
||||||
|
dup2(fd, STDERR_FILENO);
|
||||||
|
close(fd);
|
||||||
|
|
||||||
|
const std::string shell_cmd =
|
||||||
|
"osascript -e 'tell application \"Terminal\" "
|
||||||
|
"to do script \"printf \\\\e]1;Eden logs\\\\a\\\\e]2;Eden logs\\\\a; "
|
||||||
|
"tail -n +1 -F " + logfile + "\"'";
|
||||||
|
|
||||||
|
posix_spawnp(&g_terminal_pid, "/bin/sh", nullptr, nullptr,
|
||||||
|
(char* const[]){const_cast<char*>("/bin/sh"), const_cast<char*>("-c"),
|
||||||
|
const_cast<char*>(shell_cmd.c_str()), nullptr},
|
||||||
|
environ);
|
||||||
|
}
|
||||||
|
|
||||||
|
void HideMacConsole() {
|
||||||
|
if (g_terminal_pid > 0) {
|
||||||
|
kill(g_terminal_pid, SIGTERM);
|
||||||
|
g_terminal_pid = -1;
|
||||||
|
}
|
||||||
|
if (g_saved_out != -1) {
|
||||||
|
dup2(g_saved_out, STDOUT_FILENO);
|
||||||
|
close(g_saved_out);
|
||||||
|
g_saved_out = -1;
|
||||||
|
}
|
||||||
|
if (g_saved_err != -1) {
|
||||||
|
dup2(g_saved_err, STDERR_FILENO);
|
||||||
|
close(g_saved_err);
|
||||||
|
g_saved_err = -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} // namespace
|
||||||
|
#endif // __APPLE__
|
||||||
|
|
||||||
void ToggleConsole() {
|
void ToggleConsole() {
|
||||||
static bool console_shown = false;
|
static bool console_shown = false;
|
||||||
if (console_shown == UISettings::values.show_console.GetValue()) {
|
const bool want_console = UISettings::values.show_console.GetValue();
|
||||||
|
if (console_shown == want_console)
|
||||||
return;
|
return;
|
||||||
} else {
|
console_shown = want_console;
|
||||||
console_shown = UISettings::values.show_console.GetValue();
|
|
||||||
}
|
|
||||||
|
|
||||||
using namespace Common::Log;
|
using namespace Common::Log;
|
||||||
#if defined(_WIN32) && !defined(_DEBUG)
|
#if defined(_WIN32) && !defined(_DEBUG)
|
||||||
FILE* temp;
|
FILE* temp;
|
||||||
if (UISettings::values.show_console) {
|
if (want_console) {
|
||||||
if (AllocConsole()) {
|
if (AllocConsole()) {
|
||||||
// The first parameter for freopen_s is a out parameter, so we can just ignore it
|
// The first parameter for freopen_s is a out parameter, so we can just ignore it
|
||||||
freopen_s(&temp, "CONIN$", "r", stdin);
|
freopen_s(&temp, "CONIN$", "r", stdin);
|
||||||
|
@ -43,6 +115,12 @@ void ToggleConsole() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
|
#if defined(__APPLE__)
|
||||||
|
if (want_console)
|
||||||
|
ShowMacConsole();
|
||||||
|
else
|
||||||
|
HideMacConsole();
|
||||||
|
#endif
|
||||||
SetColorConsoleBackendEnabled(UISettings::values.show_console.GetValue());
|
SetColorConsoleBackendEnabled(UISettings::values.show_console.GetValue());
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
1
src/yuzu/externals/CMakeLists.txt
vendored
1
src/yuzu/externals/CMakeLists.txt
vendored
|
@ -6,6 +6,7 @@ set(BUILD_SHARED_LIBS OFF)
|
||||||
|
|
||||||
# QuaZip
|
# QuaZip
|
||||||
include(CPM)
|
include(CPM)
|
||||||
|
set(CPM_SOURCE_CACHE ${CMAKE_SOURCE_DIR}/.cache/cpm)
|
||||||
set(CPM_USE_LOCAL_PACKAGES ON)
|
set(CPM_USE_LOCAL_PACKAGES ON)
|
||||||
|
|
||||||
CPMAddPackage(
|
CPMAddPackage(
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue