mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-04-28 21:08:04 +03:00
Merge 38c82771d3
into 8ee64a84c7
This commit is contained in:
commit
559c918f0a
86 changed files with 479 additions and 257 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -43,3 +43,4 @@ CMakeLists.txt.user
|
||||||
/.vscode/
|
/.vscode/
|
||||||
# Ignore flatpak-builder's cache dir
|
# Ignore flatpak-builder's cache dir
|
||||||
.flatpak-builder
|
.flatpak-builder
|
||||||
|
CMakeUserPresets.json
|
||||||
|
|
|
@ -191,7 +191,7 @@ endif()
|
||||||
# as defined above.
|
# as defined above.
|
||||||
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/Binaries)
|
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/Binaries)
|
||||||
|
|
||||||
if (WIN32)
|
if (MSVC)
|
||||||
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_SOURCE_DIR}/Binary)
|
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_SOURCE_DIR}/Binary)
|
||||||
|
|
||||||
if (CMAKE_SYSTEM_PROCESSOR MATCHES "x86_64|amd64|AMD64")
|
if (CMAKE_SYSTEM_PROCESSOR MATCHES "x86_64|amd64|AMD64")
|
||||||
|
@ -534,7 +534,7 @@ if(ENABLE_EGL)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(ENCODE_FRAMEDUMPS)
|
if(ENCODE_FRAMEDUMPS)
|
||||||
if(WIN32)
|
if(MSVC)
|
||||||
if(_M_X86_64)
|
if(_M_X86_64)
|
||||||
set(FFMPEG_DIR Externals/FFmpeg-bin/x64)
|
set(FFMPEG_DIR Externals/FFmpeg-bin/x64)
|
||||||
elseif(_M_ARM_64)
|
elseif(_M_ARM_64)
|
||||||
|
@ -767,8 +767,10 @@ else()
|
||||||
message(STATUS "libsystemd not found, disabling traversal server watchdog support")
|
message(STATUS "libsystemd not found, disabling traversal server watchdog support")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if (WIN32)
|
if (MSVC)
|
||||||
include_directories(Externals/WIL/include)
|
include_directories(Externals/WIL/include)
|
||||||
|
endif()
|
||||||
|
if (WIN32)
|
||||||
include_directories(Externals/OpenAL/include)
|
include_directories(Externals/OpenAL/include)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
|
23
CMakePresets.json
Normal file
23
CMakePresets.json
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
{
|
||||||
|
"version": 2,
|
||||||
|
"configurePresets": [
|
||||||
|
{
|
||||||
|
"name": "gcc-debug",
|
||||||
|
"binaryDir": "build-gcc-debug",
|
||||||
|
"generator": "Ninja",
|
||||||
|
"cacheVariables": {
|
||||||
|
"CMAKE_BUILD_TYPE": "Debug",
|
||||||
|
"CMAKE_EXPORT_COMPILE_COMMANDS": "ON"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "clang-debug",
|
||||||
|
"binaryDir": "build-clang-debug",
|
||||||
|
"generator": "Ninja",
|
||||||
|
"cacheVariables": {
|
||||||
|
"CMAKE_BUILD_TYPE": "Debug",
|
||||||
|
"CMAKE_EXPORT_COMPILE_COMMANDS": "ON"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
1
Externals/cubeb/CMakeLists.txt
vendored
1
Externals/cubeb/CMakeLists.txt
vendored
|
@ -10,6 +10,7 @@ option(BUILD_RUST_LIBS "Build rust backends" OFF)
|
||||||
option(BUNDLE_SPEEX "Bundle the speex library" OFF)
|
option(BUNDLE_SPEEX "Bundle the speex library" OFF)
|
||||||
option(LAZY_LOAD_LIBS "Lazily load shared libraries" ON)
|
option(LAZY_LOAD_LIBS "Lazily load shared libraries" ON)
|
||||||
option(USE_SANITIZERS "Use sanitizers" ON)
|
option(USE_SANITIZERS "Use sanitizers" ON)
|
||||||
|
option(BUILD_TOOLS "Build tools" OFF)
|
||||||
|
|
||||||
if(NOT CMAKE_BUILD_TYPE)
|
if(NOT CMAKE_BUILD_TYPE)
|
||||||
set(CMAKE_BUILD_TYPE "RelWithDebInfo" CACHE STRING
|
set(CMAKE_BUILD_TYPE "RelWithDebInfo" CACHE STRING
|
||||||
|
|
2
Externals/discord-rpc/CMakeLists.txt
vendored
2
Externals/discord-rpc/CMakeLists.txt
vendored
|
@ -1,4 +1,4 @@
|
||||||
cmake_minimum_required (VERSION 3.2.0)
|
cmake_minimum_required (VERSION 3.10.0)
|
||||||
project (DiscordRPC)
|
project (DiscordRPC)
|
||||||
|
|
||||||
include(GNUInstallDirs)
|
include(GNUInstallDirs)
|
||||||
|
|
2
Externals/enet/CMakeLists.txt
vendored
2
Externals/enet/CMakeLists.txt
vendored
|
@ -1,4 +1,4 @@
|
||||||
cmake_minimum_required(VERSION 2.8.12)
|
cmake_minimum_required(VERSION 3.10)
|
||||||
|
|
||||||
project(enet)
|
project(enet)
|
||||||
|
|
||||||
|
|
1
Externals/glslang/glslang/Include/Common.h
vendored
1
Externals/glslang/glslang/Include/Common.h
vendored
|
@ -44,6 +44,7 @@
|
||||||
#else
|
#else
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
#endif
|
#endif
|
||||||
|
#include <cstdint>
|
||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
#include <list>
|
#include <list>
|
||||||
|
|
3
Externals/hidapi/CMakeLists.txt
vendored
3
Externals/hidapi/CMakeLists.txt
vendored
|
@ -6,8 +6,9 @@ target_include_directories(hidapi PUBLIC hidapi-src/hidapi)
|
||||||
|
|
||||||
if(APPLE)
|
if(APPLE)
|
||||||
target_sources(hidapi PRIVATE hidapi-src/mac/hid.c)
|
target_sources(hidapi PRIVATE hidapi-src/mac/hid.c)
|
||||||
elseif(MSVC)
|
elseif(WIN32)
|
||||||
target_sources(hidapi PRIVATE hidapi-src/windows/hid.c)
|
target_sources(hidapi PRIVATE hidapi-src/windows/hid.c)
|
||||||
|
target_link_libraries(hidapi PUBLIC setupapi)
|
||||||
else()
|
else()
|
||||||
find_package(LIBUDEV)
|
find_package(LIBUDEV)
|
||||||
if(CMAKE_SYSTEM_NAME STREQUAL "Linux" AND LIBUDEV_FOUND)
|
if(CMAKE_SYSTEM_NAME STREQUAL "Linux" AND LIBUDEV_FOUND)
|
||||||
|
|
2
Externals/libspng/CMakeLists.txt
vendored
2
Externals/libspng/CMakeLists.txt
vendored
|
@ -1,4 +1,4 @@
|
||||||
cmake_minimum_required(VERSION 3.0)
|
cmake_minimum_required(VERSION 3.10)
|
||||||
|
|
||||||
project(spng C)
|
project(spng C)
|
||||||
|
|
||||||
|
|
7
Externals/libusb/CMakeLists.txt
vendored
7
Externals/libusb/CMakeLists.txt
vendored
|
@ -9,7 +9,7 @@ add_library(usb STATIC EXCLUDE_FROM_ALL
|
||||||
dolphin_disable_warnings(usb)
|
dolphin_disable_warnings(usb)
|
||||||
|
|
||||||
set_target_properties(usb PROPERTIES VERSION 1.0.26)
|
set_target_properties(usb PROPERTIES VERSION 1.0.26)
|
||||||
if(WIN32)
|
if(MSVC)
|
||||||
target_include_directories(usb BEFORE PUBLIC libusb/libusb PRIVATE libusb/msvc)
|
target_include_directories(usb BEFORE PUBLIC libusb/libusb PRIVATE libusb/msvc)
|
||||||
else()
|
else()
|
||||||
target_include_directories(usb
|
target_include_directories(usb
|
||||||
|
@ -31,6 +31,7 @@ if(WIN32 OR CYGWIN)
|
||||||
libusb/libusb/os/events_windows.c
|
libusb/libusb/os/events_windows.c
|
||||||
)
|
)
|
||||||
set(PLATFORM_WINDOWS TRUE)
|
set(PLATFORM_WINDOWS TRUE)
|
||||||
|
set(ENABLE_LOGGING TRUE)
|
||||||
elseif(APPLE)
|
elseif(APPLE)
|
||||||
target_sources(usb PRIVATE libusb/libusb/os/darwin_usb.c)
|
target_sources(usb PRIVATE libusb/libusb/os/darwin_usb.c)
|
||||||
find_library(COREFOUNDATION_LIBRARY CoreFoundation)
|
find_library(COREFOUNDATION_LIBRARY CoreFoundation)
|
||||||
|
@ -92,7 +93,9 @@ include(CheckTypeSize)
|
||||||
include(CheckSymbolExists)
|
include(CheckSymbolExists)
|
||||||
|
|
||||||
check_include_files(asm/types.h HAVE_ASM_TYPES_H)
|
check_include_files(asm/types.h HAVE_ASM_TYPES_H)
|
||||||
check_function_exists(clock_gettime HAVE_CLOCK_GETTIME)
|
if(NOT WIN32)
|
||||||
|
check_function_exists(clock_gettime HAVE_CLOCK_GETTIME)
|
||||||
|
endif()
|
||||||
check_symbol_exists(EFD_CLOEXEC "sys/eventfd.h" HAVE_DECL_EFD_CLOEXEC)
|
check_symbol_exists(EFD_CLOEXEC "sys/eventfd.h" HAVE_DECL_EFD_CLOEXEC)
|
||||||
check_symbol_exists(EFD_NONBLOCK "sys/eventfd.h" HAVE_DECL_EFD_NONBLOCK)
|
check_symbol_exists(EFD_NONBLOCK "sys/eventfd.h" HAVE_DECL_EFD_NONBLOCK)
|
||||||
check_symbol_exists(TFD_CLOEXEC "sys/timerfd.h" HAVE_DECL_TFD_CLOEXEC)
|
check_symbol_exists(TFD_CLOEXEC "sys/timerfd.h" HAVE_DECL_TFD_CLOEXEC)
|
||||||
|
|
2
Externals/libusb/config.h.in
vendored
2
Externals/libusb/config.h.in
vendored
|
@ -8,7 +8,7 @@
|
||||||
#undef ENABLE_DEBUG_LOGGING
|
#undef ENABLE_DEBUG_LOGGING
|
||||||
|
|
||||||
/* Define to 1 to enable message logging. */
|
/* Define to 1 to enable message logging. */
|
||||||
#undef ENABLE_LOGGING
|
#cmakedefine ENABLE_LOGGING 1
|
||||||
|
|
||||||
/* Define to 1 if you have the <asm/types.h> header file. */
|
/* Define to 1 if you have the <asm/types.h> header file. */
|
||||||
#cmakedefine HAVE_ASM_TYPES_H 1
|
#cmakedefine HAVE_ASM_TYPES_H 1
|
||||||
|
|
2
Externals/mbedtls/CMakeLists.txt
vendored
2
Externals/mbedtls/CMakeLists.txt
vendored
|
@ -20,7 +20,7 @@
|
||||||
# mbedtls, mbedx509, mbedcrypto and apidoc targets.
|
# mbedtls, mbedx509, mbedcrypto and apidoc targets.
|
||||||
#
|
#
|
||||||
|
|
||||||
cmake_minimum_required(VERSION 2.8.12)
|
cmake_minimum_required(VERSION 3.10)
|
||||||
|
|
||||||
# https://cmake.org/cmake/help/latest/policy/CMP0011.html
|
# https://cmake.org/cmake/help/latest/policy/CMP0011.html
|
||||||
# Setting this policy is required in CMake >= 3.18.0, otherwise a warning is generated. The OLD
|
# Setting this policy is required in CMake >= 3.18.0, otherwise a warning is generated. The OLD
|
||||||
|
|
28
Externals/miniupnpc/CMakeLists.txt
vendored
28
Externals/miniupnpc/CMakeLists.txt
vendored
|
@ -1,23 +1,9 @@
|
||||||
cmake_minimum_required(VERSION 2.8.12)
|
cmake_minimum_required(VERSION 3.10)
|
||||||
|
|
||||||
project(miniupnpc C)
|
project(miniupnpc C)
|
||||||
set(MINIUPNPC_VERSION 1.9)
|
set(MINIUPNPC_VERSION 1.9)
|
||||||
set(MINIUPNPC_API_VERSION 14)
|
set(MINIUPNPC_API_VERSION 14)
|
||||||
|
|
||||||
if(UNIX)
|
|
||||||
add_definitions(-DMINIUPNPC_SET_SOCKET_TIMEOUT)
|
|
||||||
add_definitions(-D_BSD_SOURCE -D_POSIX_C_SOURCE=1)
|
|
||||||
elseif(WIN32)
|
|
||||||
add_definitions(-D_WIN32_WINNT=0x0501)
|
|
||||||
find_library(WINSOCK2_LIBRARY NAMES ws2_32 WS2_32 Ws2_32)
|
|
||||||
find_library(IPHLPAPI_LIBRARY NAMES iphlpapi)
|
|
||||||
set(LDLIBS ${WINSOCK2_LIBRARY} ${IPHLPAPI_LIBRARY} ${LDLIBS})
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if(APPLE)
|
|
||||||
add_definitions(-DMACOSX -D_DARWIN_C_SOURCE)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
set(SRCS src/igd_desc_parse.c
|
set(SRCS src/igd_desc_parse.c
|
||||||
src/miniupnpc.c
|
src/miniupnpc.c
|
||||||
src/minixml.c
|
src/minixml.c
|
||||||
|
@ -36,4 +22,16 @@ add_library(miniupnpc STATIC ${SRCS})
|
||||||
dolphin_disable_warnings(miniupnpc)
|
dolphin_disable_warnings(miniupnpc)
|
||||||
target_include_directories(miniupnpc PUBLIC src)
|
target_include_directories(miniupnpc PUBLIC src)
|
||||||
|
|
||||||
|
if(UNIX)
|
||||||
|
target_compile_definitions(miniupnpc PRIVATE MINIUPNPC_SET_SOCKET_TIMEOUT)
|
||||||
|
target_compile_definitions(miniupnpc PRIVATE _BSD_SOURCE _POSIX_C_SOURCE=1)
|
||||||
|
elseif(WIN32)
|
||||||
|
target_compile_definitions(miniupnpc PRIVATE -D_WIN32_WINNT=0x0501)
|
||||||
|
target_link_libraries(miniupnpc PUBLIC ws2_32 iphlpapi)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if(APPLE)
|
||||||
|
target_compile_definitions(miniupnpc PRIVATE MACOSX _DARWIN_C_SOURCE)
|
||||||
|
endif()
|
||||||
|
|
||||||
add_library(Miniupnpc::miniupnpc ALIAS miniupnpc)
|
add_library(Miniupnpc::miniupnpc ALIAS miniupnpc)
|
||||||
|
|
18
Externals/rcheevos/CMakeLists.txt
vendored
18
Externals/rcheevos/CMakeLists.txt
vendored
|
@ -62,13 +62,15 @@ dolphin_disable_warnings(rcheevos)
|
||||||
|
|
||||||
target_include_directories(rcheevos PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/rcheevos/include")
|
target_include_directories(rcheevos PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/rcheevos/include")
|
||||||
target_include_directories(rcheevos INTERFACE "${CMAKE_CURRENT_SOURCE_DIR}")
|
target_include_directories(rcheevos INTERFACE "${CMAKE_CURRENT_SOURCE_DIR}")
|
||||||
target_compile_definitions(rcheevos PRIVATE "RC_DISABLE_LUA=1" "RCHEEVOS_URL_SSL")
|
target_compile_definitions(rcheevos PUBLIC "RC_DISABLE_LUA=1" "RCHEEVOS_URL_SSL")
|
||||||
target_compile_definitions(rcheevos PRIVATE "RC_CLIENT_SUPPORTS_HASH")
|
target_compile_definitions(rcheevos PUBLIC "RC_CLIENT_SUPPORTS_HASH")
|
||||||
target_compile_definitions(rcheevos PRIVATE "RC_CLIENT_SUPPORTS_EXTERNAL")
|
target_compile_definitions(rcheevos PUBLIC "RC_CLIENT_SUPPORTS_EXTERNAL")
|
||||||
target_compile_definitions(rcheevos PRIVATE "RC_HASH_NO_ENCRYPTED")
|
target_compile_definitions(rcheevos PUBLIC "RC_HASH_NO_ENCRYPTED")
|
||||||
target_compile_definitions(rcheevos PRIVATE "RC_HASH_NO_ROM")
|
target_compile_definitions(rcheevos PUBLIC "RC_HASH_NO_ROM")
|
||||||
target_compile_definitions(rcheevos PRIVATE "RC_HASH_NO_ZIP")
|
target_compile_definitions(rcheevos PUBLIC "RC_HASH_NO_ZIP")
|
||||||
if(CMAKE_SYSTEM_NAME MATCHES "Windows")
|
if(WIN32)
|
||||||
target_compile_definitions(rcheevos PRIVATE "RC_CLIENT_SUPPORTS_RAINTEGRATION")
|
if(RC_CLIENT_SUPPORTS_RAINTEGRATION)
|
||||||
|
target_compile_definitions(rcheevos PUBLIC RC_CLIENT_SUPPORTS_RAINTEGRATION)
|
||||||
|
endif()
|
||||||
target_compile_definitions(rcheevos PRIVATE "_CRT_SECURE_NO_WARNINGS")
|
target_compile_definitions(rcheevos PRIVATE "_CRT_SECURE_NO_WARNINGS")
|
||||||
endif()
|
endif()
|
||||||
|
|
|
@ -2,15 +2,18 @@
|
||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
#include "AudioCommon/WASAPIStream.h"
|
#include "AudioCommon/WASAPIStream.h"
|
||||||
|
#include "Common/ScopeGuard.h"
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
|
|
||||||
// clang-format off
|
// clang-format off
|
||||||
|
#include <initguid.h>
|
||||||
#include <Audioclient.h>
|
#include <Audioclient.h>
|
||||||
#include <mmdeviceapi.h>
|
#include <mmdeviceapi.h>
|
||||||
#include <devpkey.h>
|
#include <devpkey.h>
|
||||||
#include <functiondiscoverykeys_devpkey.h>
|
#include <functiondiscoverykeys_devpkey.h>
|
||||||
#include <wil/resource.h>
|
#include <propvarutil.h>
|
||||||
|
#include <wrl/client.h>
|
||||||
// clang-format on
|
// clang-format on
|
||||||
|
|
||||||
#include <thread>
|
#include <thread>
|
||||||
|
@ -28,8 +31,9 @@ using Microsoft::WRL::ComPtr;
|
||||||
WASAPIStream::WASAPIStream()
|
WASAPIStream::WASAPIStream()
|
||||||
{
|
{
|
||||||
if (SUCCEEDED(CoInitializeEx(nullptr, COINIT_MULTITHREADED)))
|
if (SUCCEEDED(CoInitializeEx(nullptr, COINIT_MULTITHREADED)))
|
||||||
m_coinitialize.activate();
|
m_coinitialize = true;
|
||||||
|
|
||||||
|
m_need_data_event = CreateEvent(NULL, FALSE, FALSE, NULL);
|
||||||
m_format.Format.wFormatTag = WAVE_FORMAT_EXTENSIBLE;
|
m_format.Format.wFormatTag = WAVE_FORMAT_EXTENSIBLE;
|
||||||
m_format.Format.nChannels = 2;
|
m_format.Format.nChannels = 2;
|
||||||
m_format.Format.nSamplesPerSec = GetMixer()->GetSampleRate();
|
m_format.Format.nSamplesPerSec = GetMixer()->GetSampleRate();
|
||||||
|
@ -47,6 +51,10 @@ WASAPIStream::~WASAPIStream()
|
||||||
m_running.store(false, std::memory_order_relaxed);
|
m_running.store(false, std::memory_order_relaxed);
|
||||||
if (m_thread.joinable())
|
if (m_thread.joinable())
|
||||||
m_thread.join();
|
m_thread.join();
|
||||||
|
if (m_need_data_event != NULL)
|
||||||
|
CloseHandle(m_need_data_event);
|
||||||
|
if (m_coinitialize)
|
||||||
|
CoUninitialize();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool WASAPIStream::IsValid()
|
bool WASAPIStream::IsValid()
|
||||||
|
@ -84,21 +92,22 @@ static void ForEachNamedDevice(const std::function<bool(ComPtr<IMMDevice>, std::
|
||||||
if (result != RPC_E_CHANGED_MODE && !HandleWinAPI("Failed to call CoInitialize", result))
|
if (result != RPC_E_CHANGED_MODE && !HandleWinAPI("Failed to call CoInitialize", result))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
wil::unique_couninitialize_call cleanup;
|
Common::ScopeGuard result_guard([result] {
|
||||||
if (FAILED(result))
|
if (SUCCEEDED(result))
|
||||||
cleanup.release(); // CoUninitialize must be matched with each successful CoInitialize call, so
|
CoUninitialize(); // CoUninitialize must be matched with each successful CoInitialize call,
|
||||||
// don't call it if initialize fails
|
// so don't call it if initialize fails
|
||||||
|
});
|
||||||
|
|
||||||
ComPtr<IMMDeviceEnumerator> enumerator;
|
ComPtr<IMMDeviceEnumerator> enumerator;
|
||||||
|
|
||||||
result = CoCreateInstance(__uuidof(MMDeviceEnumerator), nullptr, CLSCTX_INPROC_SERVER,
|
result = CoCreateInstance(__uuidof(MMDeviceEnumerator), nullptr, CLSCTX_INPROC_SERVER,
|
||||||
IID_PPV_ARGS(enumerator.GetAddressOf()));
|
IID_PPV_ARGS(&enumerator));
|
||||||
|
|
||||||
if (!HandleWinAPI("Failed to create MMDeviceEnumerator", result))
|
if (!HandleWinAPI("Failed to create MMDeviceEnumerator", result))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
ComPtr<IMMDeviceCollection> devices;
|
ComPtr<IMMDeviceCollection> devices;
|
||||||
result = enumerator->EnumAudioEndpoints(eRender, DEVICE_STATE_ACTIVE, devices.GetAddressOf());
|
result = enumerator->EnumAudioEndpoints(eRender, DEVICE_STATE_ACTIVE, &devices);
|
||||||
|
|
||||||
if (!HandleWinAPI("Failed to get available devices", result))
|
if (!HandleWinAPI("Failed to get available devices", result))
|
||||||
return;
|
return;
|
||||||
|
@ -109,19 +118,20 @@ static void ForEachNamedDevice(const std::function<bool(ComPtr<IMMDevice>, std::
|
||||||
for (u32 i = 0; i < count; i++)
|
for (u32 i = 0; i < count; i++)
|
||||||
{
|
{
|
||||||
ComPtr<IMMDevice> device;
|
ComPtr<IMMDevice> device;
|
||||||
devices->Item(i, device.GetAddressOf());
|
devices->Item(i, &device);
|
||||||
if (!HandleWinAPI("Failed to get device " + std::to_string(i), result))
|
if (!HandleWinAPI("Failed to get device " + std::to_string(i), result))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
ComPtr<IPropertyStore> device_properties;
|
ComPtr<IPropertyStore> device_properties;
|
||||||
|
|
||||||
result = device->OpenPropertyStore(STGM_READ, device_properties.GetAddressOf());
|
result = device->OpenPropertyStore(STGM_READ, &device_properties);
|
||||||
|
|
||||||
if (!HandleWinAPI("Failed to initialize IPropertyStore", result))
|
if (!HandleWinAPI("Failed to initialize IPropertyStore", result))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
wil::unique_prop_variant device_name;
|
PROPVARIANT device_name = {};
|
||||||
device_properties->GetValue(PKEY_Device_FriendlyName, device_name.addressof());
|
result = device_properties->GetValue(PKEY_Device_FriendlyName, &device_name);
|
||||||
|
Common::ScopeGuard device_name_guard([&] { PropVariantClear(&device_name); });
|
||||||
|
|
||||||
if (!callback(std::move(device), TStrToUTF8(device_name.pwszVal)))
|
if (!callback(std::move(device), TStrToUTF8(device_name.pwszVal)))
|
||||||
break;
|
break;
|
||||||
|
@ -160,7 +170,7 @@ bool WASAPIStream::Init()
|
||||||
{
|
{
|
||||||
ASSERT(m_enumerator == nullptr);
|
ASSERT(m_enumerator == nullptr);
|
||||||
HRESULT result = CoCreateInstance(__uuidof(MMDeviceEnumerator), nullptr, CLSCTX_INPROC_SERVER,
|
HRESULT result = CoCreateInstance(__uuidof(MMDeviceEnumerator), nullptr, CLSCTX_INPROC_SERVER,
|
||||||
IID_PPV_ARGS(m_enumerator.GetAddressOf()));
|
IID_PPV_ARGS(&m_enumerator));
|
||||||
|
|
||||||
if (!HandleWinAPI("Failed to create MMDeviceEnumerator", result))
|
if (!HandleWinAPI("Failed to create MMDeviceEnumerator", result))
|
||||||
return false;
|
return false;
|
||||||
|
@ -178,7 +188,7 @@ bool WASAPIStream::SetRunning(bool running)
|
||||||
|
|
||||||
if (Config::Get(Config::MAIN_WASAPI_DEVICE) == "default")
|
if (Config::Get(Config::MAIN_WASAPI_DEVICE) == "default")
|
||||||
{
|
{
|
||||||
result = m_enumerator->GetDefaultAudioEndpoint(eRender, eConsole, device.GetAddressOf());
|
result = m_enumerator->GetDefaultAudioEndpoint(eRender, eConsole, &device);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -189,7 +199,7 @@ bool WASAPIStream::SetRunning(bool running)
|
||||||
{
|
{
|
||||||
ERROR_LOG_FMT(AUDIO, "Can't find device '{}', falling back to default",
|
ERROR_LOG_FMT(AUDIO, "Can't find device '{}', falling back to default",
|
||||||
Config::Get(Config::MAIN_WASAPI_DEVICE));
|
Config::Get(Config::MAIN_WASAPI_DEVICE));
|
||||||
result = m_enumerator->GetDefaultAudioEndpoint(eRender, eConsole, device.GetAddressOf());
|
result = m_enumerator->GetDefaultAudioEndpoint(eRender, eConsole, &device);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -199,21 +209,21 @@ bool WASAPIStream::SetRunning(bool running)
|
||||||
// Show a friendly name in the log
|
// Show a friendly name in the log
|
||||||
ComPtr<IPropertyStore> device_properties;
|
ComPtr<IPropertyStore> device_properties;
|
||||||
|
|
||||||
result = device->OpenPropertyStore(STGM_READ, device_properties.GetAddressOf());
|
result = device->OpenPropertyStore(STGM_READ, &device_properties);
|
||||||
|
|
||||||
if (!HandleWinAPI("Failed to initialize IPropertyStore", result))
|
if (!HandleWinAPI("Failed to initialize IPropertyStore", result))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
wil::unique_prop_variant device_name;
|
PROPVARIANT device_name = {};
|
||||||
device_properties->GetValue(PKEY_Device_FriendlyName, device_name.addressof());
|
result = device_properties->GetValue(PKEY_Device_FriendlyName, &device_name);
|
||||||
|
Common::ScopeGuard device_name_guard([&] { PropVariantClear(&device_name); });
|
||||||
|
|
||||||
INFO_LOG_FMT(AUDIO, "Using audio endpoint '{}'", TStrToUTF8(device_name.pwszVal));
|
INFO_LOG_FMT(AUDIO, "Using audio endpoint '{}'", TStrToUTF8(device_name.pwszVal));
|
||||||
|
|
||||||
ComPtr<IAudioClient> audio_client;
|
ComPtr<IAudioClient> audio_client;
|
||||||
|
|
||||||
// Get IAudioDevice
|
// Get IAudioDevice
|
||||||
result = device->Activate(__uuidof(IAudioClient), CLSCTX_INPROC_SERVER, nullptr,
|
result = device->Activate(__uuidof(IAudioClient), CLSCTX_INPROC_SERVER, nullptr, &audio_client);
|
||||||
reinterpret_cast<LPVOID*>(audio_client.GetAddressOf()));
|
|
||||||
|
|
||||||
if (!HandleWinAPI("Failed to activate IAudioClient", result))
|
if (!HandleWinAPI("Failed to activate IAudioClient", result))
|
||||||
return false;
|
return false;
|
||||||
|
@ -276,15 +286,18 @@ bool WASAPIStream::SetRunning(bool running)
|
||||||
|
|
||||||
ComPtr<IAudioRenderClient> audio_renderer;
|
ComPtr<IAudioRenderClient> audio_renderer;
|
||||||
|
|
||||||
result = audio_client->GetService(IID_PPV_ARGS(audio_renderer.GetAddressOf()));
|
result = audio_client->GetService(IID_PPV_ARGS(&audio_renderer));
|
||||||
|
|
||||||
if (!HandleWinAPI("Failed to get IAudioRenderClient from IAudioClient", result))
|
if (!HandleWinAPI("Failed to get IAudioRenderClient from IAudioClient", result))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
wil::unique_event_nothrow need_data_event;
|
HANDLE need_data_event = CreateEvent(NULL, FALSE, FALSE, NULL);
|
||||||
need_data_event.create();
|
Common::ScopeGuard need_data_event_guard([&] {
|
||||||
|
if (need_data_event != NULL)
|
||||||
|
CloseHandle(need_data_event);
|
||||||
|
});
|
||||||
|
|
||||||
audio_client->SetEventHandle(need_data_event.get());
|
audio_client->SetEventHandle(need_data_event);
|
||||||
|
|
||||||
result = audio_client->Start();
|
result = audio_client->Start();
|
||||||
|
|
||||||
|
@ -297,6 +310,7 @@ bool WASAPIStream::SetRunning(bool running)
|
||||||
m_audio_client = std::move(audio_client);
|
m_audio_client = std::move(audio_client);
|
||||||
m_audio_renderer = std::move(audio_renderer);
|
m_audio_renderer = std::move(audio_renderer);
|
||||||
m_need_data_event = std::move(need_data_event);
|
m_need_data_event = std::move(need_data_event);
|
||||||
|
need_data_event = nullptr;
|
||||||
|
|
||||||
m_running.store(true, std::memory_order_relaxed);
|
m_running.store(true, std::memory_order_relaxed);
|
||||||
m_thread = std::thread(&WASAPIStream::SoundLoop, this);
|
m_thread = std::thread(&WASAPIStream::SoundLoop, this);
|
||||||
|
@ -308,7 +322,11 @@ bool WASAPIStream::SetRunning(bool running)
|
||||||
if (m_thread.joinable())
|
if (m_thread.joinable())
|
||||||
m_thread.join();
|
m_thread.join();
|
||||||
|
|
||||||
m_need_data_event.reset();
|
if (m_need_data_event)
|
||||||
|
{
|
||||||
|
CloseHandle(m_need_data_event);
|
||||||
|
m_need_data_event = NULL;
|
||||||
|
}
|
||||||
m_audio_renderer.Reset();
|
m_audio_renderer.Reset();
|
||||||
m_audio_client.Reset();
|
m_audio_client.Reset();
|
||||||
}
|
}
|
||||||
|
@ -326,7 +344,7 @@ void WASAPIStream::SoundLoop()
|
||||||
|
|
||||||
while (m_running.load(std::memory_order_relaxed))
|
while (m_running.load(std::memory_order_relaxed))
|
||||||
{
|
{
|
||||||
WaitForSingleObject(m_need_data_event.get(), 1000);
|
WaitForSingleObject(m_need_data_event, 1000);
|
||||||
|
|
||||||
m_audio_renderer->GetBuffer(m_frames_in_buffer, &data);
|
m_audio_renderer->GetBuffer(m_frames_in_buffer, &data);
|
||||||
|
|
||||||
|
@ -349,4 +367,4 @@ void WASAPIStream::SoundLoop()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // _WIN32
|
#endif // _MSC_VER
|
||||||
|
|
|
@ -9,7 +9,6 @@
|
||||||
#include <Windows.h>
|
#include <Windows.h>
|
||||||
#include <mmreg.h>
|
#include <mmreg.h>
|
||||||
#include <objbase.h>
|
#include <objbase.h>
|
||||||
#include <wil/resource.h>
|
|
||||||
// clang-format on
|
// clang-format on
|
||||||
|
|
||||||
#include <atomic>
|
#include <atomic>
|
||||||
|
@ -17,6 +16,7 @@
|
||||||
#include <thread>
|
#include <thread>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <wrl/client.h>
|
#include <wrl/client.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "AudioCommon/SoundStream.h"
|
#include "AudioCommon/SoundStream.h"
|
||||||
|
|
||||||
|
@ -25,8 +25,6 @@ struct IAudioRenderClient;
|
||||||
struct IMMDevice;
|
struct IMMDevice;
|
||||||
struct IMMDeviceEnumerator;
|
struct IMMDeviceEnumerator;
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
class WASAPIStream final : public SoundStream
|
class WASAPIStream final : public SoundStream
|
||||||
{
|
{
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
|
@ -49,12 +47,12 @@ private:
|
||||||
|
|
||||||
// CoUninitialize must be called after all WASAPI COM objects have been destroyed,
|
// CoUninitialize must be called after all WASAPI COM objects have been destroyed,
|
||||||
// therefore this member must be located before them, as first class fields are destructed last
|
// therefore this member must be located before them, as first class fields are destructed last
|
||||||
wil::unique_couninitialize_call m_coinitialize{false};
|
bool m_coinitialize{false};
|
||||||
|
|
||||||
Microsoft::WRL::ComPtr<IMMDeviceEnumerator> m_enumerator;
|
Microsoft::WRL::ComPtr<IMMDeviceEnumerator> m_enumerator;
|
||||||
Microsoft::WRL::ComPtr<IAudioClient> m_audio_client;
|
Microsoft::WRL::ComPtr<IAudioClient> m_audio_client;
|
||||||
Microsoft::WRL::ComPtr<IAudioRenderClient> m_audio_renderer;
|
Microsoft::WRL::ComPtr<IAudioRenderClient> m_audio_renderer;
|
||||||
wil::unique_event_nothrow m_need_data_event;
|
HANDLE m_need_data_event;
|
||||||
WAVEFORMATEXTENSIBLE m_format;
|
WAVEFORMATEXTENSIBLE m_format;
|
||||||
#endif // _WIN32
|
#endif // _MSC_VER
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,3 +1,7 @@
|
||||||
|
if(NOT MSVC)
|
||||||
|
add_compile_options(-Wno-missing-declarations)
|
||||||
|
endif()
|
||||||
|
|
||||||
add_subdirectory(AudioCommon)
|
add_subdirectory(AudioCommon)
|
||||||
add_subdirectory(Common)
|
add_subdirectory(Common)
|
||||||
add_subdirectory(Core)
|
add_subdirectory(Core)
|
||||||
|
|
|
@ -208,6 +208,8 @@ elseif(WIN32)
|
||||||
if (_M_X86_64)
|
if (_M_X86_64)
|
||||||
target_link_libraries(common PRIVATE opengl32.lib)
|
target_link_libraries(common PRIVATE opengl32.lib)
|
||||||
endif()
|
endif()
|
||||||
|
target_compile_definitions(common PRIVATE _WIN32_WINNT=0x0602)
|
||||||
|
target_compile_options(common PRIVATE -mxsave)
|
||||||
elseif (ANDROID)
|
elseif (ANDROID)
|
||||||
target_link_libraries(common
|
target_link_libraries(common
|
||||||
PRIVATE
|
PRIVATE
|
||||||
|
@ -336,6 +338,7 @@ endif()
|
||||||
|
|
||||||
if(WIN32)
|
if(WIN32)
|
||||||
target_sources(common PRIVATE HRWrap.h HRWrap.cpp)
|
target_sources(common PRIVATE HRWrap.h HRWrap.cpp)
|
||||||
|
target_link_libraries(common PUBLIC qwave)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(USE_UPNP)
|
if(USE_UPNP)
|
||||||
|
@ -375,7 +378,7 @@ if(UNIX)
|
||||||
if(SYSTEMD_FOUND)
|
if(SYSTEMD_FOUND)
|
||||||
target_link_libraries(traversal_server PRIVATE ${SYSTEMD_LIBRARIES})
|
target_link_libraries(traversal_server PRIVATE ${SYSTEMD_LIBRARIES})
|
||||||
endif()
|
endif()
|
||||||
elseif(WIN32)
|
elseif(MSVC)
|
||||||
find_package(PowerShell REQUIRED)
|
find_package(PowerShell REQUIRED)
|
||||||
execute_process(
|
execute_process(
|
||||||
COMMAND ${POWERSHELL_EXE} -Command "[System.Diagnostics.FileVersionInfo]::GetVersionInfo('$ENV{VCToolsRedistDir}vc_redist.x64.exe').ProductVersion"
|
COMMAND ${POWERSHELL_EXE} -Command "[System.Diagnostics.FileVersionInfo]::GetVersionInfo('$ENV{VCToolsRedistDir}vc_redist.x64.exe').ProductVersion"
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
#else // WIN32
|
#else // WIN32
|
||||||
|
#define NO_OLDNAMES
|
||||||
// Function Cross-Compatibility
|
// Function Cross-Compatibility
|
||||||
#define strcasecmp _stricmp
|
#define strcasecmp _stricmp
|
||||||
#define strncasecmp _strnicmp
|
#define strncasecmp _strnicmp
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
typedef NTSTATUS(NTAPI* PRTL_HEAP_COMMIT_ROUTINE)(IN PVOID Base, IN OUT PVOID* CommitAddress,
|
typedef NTSTATUS(NTAPI* PRTL_HEAP_COMMIT_ROUTINE)(IN PVOID Base, IN OUT PVOID* CommitAddress,
|
||||||
IN OUT PSIZE_T CommitSize);
|
IN OUT PSIZE_T CommitSize);
|
||||||
|
|
||||||
|
#ifndef __MINGW32__
|
||||||
typedef struct _RTL_HEAP_PARAMETERS
|
typedef struct _RTL_HEAP_PARAMETERS
|
||||||
{
|
{
|
||||||
ULONG Length;
|
ULONG Length;
|
||||||
|
@ -33,6 +34,7 @@ typedef struct _RTL_HEAP_PARAMETERS
|
||||||
PRTL_HEAP_COMMIT_ROUTINE CommitRoutine;
|
PRTL_HEAP_COMMIT_ROUTINE CommitRoutine;
|
||||||
SIZE_T Reserved[2];
|
SIZE_T Reserved[2];
|
||||||
} RTL_HEAP_PARAMETERS, *PRTL_HEAP_PARAMETERS;
|
} RTL_HEAP_PARAMETERS, *PRTL_HEAP_PARAMETERS;
|
||||||
|
#endif
|
||||||
|
|
||||||
typedef PVOID (*RtlCreateHeap_t)(_In_ ULONG Flags, _In_opt_ PVOID HeapBase,
|
typedef PVOID (*RtlCreateHeap_t)(_In_ ULONG Flags, _In_opt_ PVOID HeapBase,
|
||||||
_In_opt_ SIZE_T ReserveSize, _In_opt_ SIZE_T CommitSize,
|
_In_opt_ SIZE_T ReserveSize, _In_opt_ SIZE_T CommitSize,
|
||||||
|
@ -134,10 +136,11 @@ void CompatPatchesInstall(LdrWatcher* watcher)
|
||||||
// crash if applied before module initialization (i.e. called on the Ldr
|
// crash if applied before module initialization (i.e. called on the Ldr
|
||||||
// callout path).
|
// callout path).
|
||||||
auto patcher = ImportPatcher(event.base_address);
|
auto patcher = ImportPatcher(event.base_address);
|
||||||
patcher.PatchIAT("kernel32.dll", "HeapCreate", HeapCreateLow4GB);
|
patcher.PatchIAT("kernel32.dll", "HeapCreate", (void*)HeapCreateLow4GB);
|
||||||
}});
|
}});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef _MSC_VER
|
||||||
int __cdecl EnableCompatPatches()
|
int __cdecl EnableCompatPatches()
|
||||||
{
|
{
|
||||||
static LdrWatcher watcher;
|
static LdrWatcher watcher;
|
||||||
|
@ -157,4 +160,5 @@ int __cdecl EnableCompatPatches()
|
||||||
extern "C" {
|
extern "C" {
|
||||||
__declspec(allocate(".CRT$XCZ")) decltype(&EnableCompatPatches)
|
__declspec(allocate(".CRT$XCZ")) decltype(&EnableCompatPatches)
|
||||||
enableCompatPatches = EnableCompatPatches;
|
enableCompatPatches = EnableCompatPatches;
|
||||||
}
|
};
|
||||||
|
#endif
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
#include "Common/Logging/Log.h"
|
#include "Common/Logging/Log.h"
|
||||||
#include "Common/StringUtil.h"
|
#include "Common/StringUtil.h"
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
#ifdef _WIN32
|
||||||
#include <Windows.h>
|
#include <Windows.h>
|
||||||
#else
|
#else
|
||||||
#ifdef ANDROID
|
#ifdef ANDROID
|
||||||
|
|
|
@ -39,6 +39,7 @@
|
||||||
#include <direct.h> // getcwd
|
#include <direct.h> // getcwd
|
||||||
#include <io.h>
|
#include <io.h>
|
||||||
#include <objbase.h> // guid stuff
|
#include <objbase.h> // guid stuff
|
||||||
|
#include <share.h>
|
||||||
#include <shellapi.h>
|
#include <shellapi.h>
|
||||||
#else
|
#else
|
||||||
#include <dirent.h>
|
#include <dirent.h>
|
||||||
|
|
|
@ -223,7 +223,7 @@ void* GLContextWGL::GetFuncAddress(const std::string& name)
|
||||||
func = GetProcAddress(opengl_module, name.c_str());
|
func = GetProcAddress(opengl_module, name.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
return func;
|
return (void*)func;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create rendering window.
|
// Create rendering window.
|
||||||
|
|
|
@ -12,7 +12,7 @@ class GLContextWGL final : public GLContext
|
||||||
public:
|
public:
|
||||||
~GLContextWGL();
|
~GLContextWGL();
|
||||||
|
|
||||||
bool IsHeadless() const;
|
bool IsHeadless() const override;
|
||||||
|
|
||||||
std::unique_ptr<GLContext> CreateSharedContext() override;
|
std::unique_ptr<GLContext> CreateSharedContext() override;
|
||||||
|
|
||||||
|
|
|
@ -3,8 +3,14 @@
|
||||||
|
|
||||||
#include "HRWrap.h"
|
#include "HRWrap.h"
|
||||||
|
|
||||||
|
#ifndef _MSC_VER
|
||||||
|
#include <comdef.h>
|
||||||
|
#endif
|
||||||
|
#include "Common/StringUtil.h"
|
||||||
|
|
||||||
namespace Common
|
namespace Common
|
||||||
{
|
{
|
||||||
|
#ifdef _MSC_VER
|
||||||
std::string GetHResultMessage(HRESULT hr)
|
std::string GetHResultMessage(HRESULT hr)
|
||||||
{
|
{
|
||||||
auto err = winrt::hresult_error(hr);
|
auto err = winrt::hresult_error(hr);
|
||||||
|
@ -14,4 +20,11 @@ std::string GetHResultMessage(const winrt::hresult& hr)
|
||||||
{
|
{
|
||||||
return GetHResultMessage(hr.value);
|
return GetHResultMessage(hr.value);
|
||||||
}
|
}
|
||||||
|
#else
|
||||||
|
std::string GetHResultMessage(HRESULT hr)
|
||||||
|
{
|
||||||
|
_com_error err(hr);
|
||||||
|
return TStrToUTF8(err.ErrorMessage());
|
||||||
|
}
|
||||||
|
#endif
|
||||||
} // namespace Common
|
} // namespace Common
|
||||||
|
|
|
@ -3,10 +3,13 @@
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <windows.h>
|
||||||
#include <fmt/format.h>
|
#include <fmt/format.h>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <winerror.h>
|
#include <winerror.h>
|
||||||
|
#ifdef _MSC_VER
|
||||||
#include <winrt/base.h>
|
#include <winrt/base.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "Common/CommonTypes.h"
|
#include "Common/CommonTypes.h"
|
||||||
|
|
||||||
|
@ -35,6 +38,7 @@ struct fmt::formatter<Common::HRWrap>
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#ifdef _MSC_VER
|
||||||
template <>
|
template <>
|
||||||
struct fmt::formatter<winrt::hresult>
|
struct fmt::formatter<winrt::hresult>
|
||||||
{
|
{
|
||||||
|
@ -45,3 +49,4 @@ struct fmt::formatter<winrt::hresult>
|
||||||
return fmt::format_to(ctx.out(), "{} ({:#010x})", Common::GetHResultMessage(hr), hr.value);
|
return fmt::format_to(ctx.out(), "{} ({:#010x})", Common::GetHResultMessage(hr), hr.value);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
#endif
|
||||||
|
|
|
@ -9,6 +9,7 @@
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
#include <io.h>
|
#include <io.h>
|
||||||
|
#include <share.h>
|
||||||
|
|
||||||
#include "Common/CommonFuncs.h"
|
#include "Common/CommonFuncs.h"
|
||||||
#include "Common/StringUtil.h"
|
#include "Common/StringUtil.h"
|
||||||
|
|
|
@ -137,8 +137,10 @@ LdrWatcher::~LdrWatcher()
|
||||||
UninstallAll();
|
UninstallAll();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef _MSC_VER
|
||||||
// Needed for RtlInitUnicodeString
|
// Needed for RtlInitUnicodeString
|
||||||
#pragma comment(lib, "ntdll")
|
#pragma comment(lib, "ntdll")
|
||||||
|
#endif
|
||||||
|
|
||||||
bool LdrWatcher::InjectCurrentModules(const LdrObserver& observer)
|
bool LdrWatcher::InjectCurrentModules(const LdrObserver& observer)
|
||||||
{
|
{
|
||||||
|
|
|
@ -59,7 +59,8 @@ static bool InitWindowsMemoryFunctions(WindowsMemoryFunctions* functions)
|
||||||
void* const ptr_IsApiSetImplemented = kernelBase.GetSymbolAddress("IsApiSetImplemented");
|
void* const ptr_IsApiSetImplemented = kernelBase.GetSymbolAddress("IsApiSetImplemented");
|
||||||
if (!ptr_IsApiSetImplemented)
|
if (!ptr_IsApiSetImplemented)
|
||||||
return false;
|
return false;
|
||||||
if (!static_cast<PIsApiSetImplemented>(ptr_IsApiSetImplemented)("api-ms-win-core-memory-l1-1-6"))
|
if (!reinterpret_cast<PIsApiSetImplemented>(ptr_IsApiSetImplemented)(
|
||||||
|
"api-ms-win-core-memory-l1-1-6"))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
functions->m_api_ms_win_core_memory_l1_1_6_handle.Open("api-ms-win-core-memory-l1-1-6.dll");
|
functions->m_api_ms_win_core_memory_l1_1_6_handle.Open("api-ms-win-core-memory-l1-1-6.dll");
|
||||||
|
@ -156,9 +157,10 @@ u8* MemArena::ReserveMemoryRegion(size_t memory_size)
|
||||||
u8* base;
|
u8* base;
|
||||||
if (m_memory_functions.m_api_ms_win_core_memory_l1_1_6_handle.IsOpen())
|
if (m_memory_functions.m_api_ms_win_core_memory_l1_1_6_handle.IsOpen())
|
||||||
{
|
{
|
||||||
base = static_cast<u8*>(static_cast<PVirtualAlloc2>(m_memory_functions.m_address_VirtualAlloc2)(
|
base = static_cast<u8*>(reinterpret_cast<PVirtualAlloc2>(
|
||||||
nullptr, nullptr, memory_size, MEM_RESERVE | MEM_RESERVE_PLACEHOLDER, PAGE_NOACCESS,
|
m_memory_functions.m_address_VirtualAlloc2)(nullptr, nullptr, memory_size,
|
||||||
nullptr, 0));
|
MEM_RESERVE | MEM_RESERVE_PLACEHOLDER,
|
||||||
|
PAGE_NOACCESS, nullptr, 0));
|
||||||
if (base)
|
if (base)
|
||||||
{
|
{
|
||||||
m_reserved_region = base;
|
m_reserved_region = base;
|
||||||
|
@ -329,7 +331,7 @@ void* MemArena::MapInMemoryRegion(s64 offset, size_t size, void* base)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void* rv = static_cast<PMapViewOfFile3>(m_memory_functions.m_address_MapViewOfFile3)(
|
void* rv = reinterpret_cast<PMapViewOfFile3>(m_memory_functions.m_address_MapViewOfFile3)(
|
||||||
m_memory_handle, nullptr, base, offset, size, MEM_REPLACE_PLACEHOLDER, PAGE_READWRITE,
|
m_memory_handle, nullptr, base, offset, size, MEM_REPLACE_PLACEHOLDER, PAGE_READWRITE,
|
||||||
nullptr, 0);
|
nullptr, 0);
|
||||||
if (rv)
|
if (rv)
|
||||||
|
@ -422,7 +424,7 @@ void MemArena::UnmapFromMemoryRegion(void* view, size_t size)
|
||||||
{
|
{
|
||||||
if (m_memory_functions.m_api_ms_win_core_memory_l1_1_6_handle.IsOpen())
|
if (m_memory_functions.m_api_ms_win_core_memory_l1_1_6_handle.IsOpen())
|
||||||
{
|
{
|
||||||
if (static_cast<PUnmapViewOfFileEx>(m_memory_functions.m_address_UnmapViewOfFileEx)(
|
if (reinterpret_cast<PUnmapViewOfFileEx>(m_memory_functions.m_address_UnmapViewOfFileEx)(
|
||||||
view, MEM_PRESERVE_PLACEHOLDER))
|
view, MEM_PRESERVE_PLACEHOLDER))
|
||||||
{
|
{
|
||||||
if (!JoinRegionsAfterUnmap(view, size))
|
if (!JoinRegionsAfterUnmap(view, size))
|
||||||
|
@ -462,7 +464,7 @@ void* LazyMemoryRegion::Create(size_t size)
|
||||||
const size_t memory_size = Common::AlignUp(size, BLOCK_SIZE);
|
const size_t memory_size = Common::AlignUp(size, BLOCK_SIZE);
|
||||||
const size_t block_count = memory_size / BLOCK_SIZE;
|
const size_t block_count = memory_size / BLOCK_SIZE;
|
||||||
u8* memory =
|
u8* memory =
|
||||||
static_cast<u8*>(static_cast<PVirtualAlloc2>(m_memory_functions.m_address_VirtualAlloc2)(
|
static_cast<u8*>(reinterpret_cast<PVirtualAlloc2>(m_memory_functions.m_address_VirtualAlloc2)(
|
||||||
nullptr, nullptr, memory_size, MEM_RESERVE | MEM_RESERVE_PLACEHOLDER, PAGE_NOACCESS,
|
nullptr, nullptr, memory_size, MEM_RESERVE | MEM_RESERVE_PLACEHOLDER, PAGE_NOACCESS,
|
||||||
nullptr, 0));
|
nullptr, 0));
|
||||||
if (!memory)
|
if (!memory)
|
||||||
|
@ -504,7 +506,7 @@ void* LazyMemoryRegion::Create(size_t size)
|
||||||
// map the zero page into every block
|
// map the zero page into every block
|
||||||
for (size_t i = 0; i < block_count; ++i)
|
for (size_t i = 0; i < block_count; ++i)
|
||||||
{
|
{
|
||||||
void* result = static_cast<PMapViewOfFile3>(m_memory_functions.m_address_MapViewOfFile3)(
|
void* result = reinterpret_cast<PMapViewOfFile3>(m_memory_functions.m_address_MapViewOfFile3)(
|
||||||
zero_block, nullptr, memory + i * BLOCK_SIZE, 0, BLOCK_SIZE, MEM_REPLACE_PLACEHOLDER,
|
zero_block, nullptr, memory + i * BLOCK_SIZE, 0, BLOCK_SIZE, MEM_REPLACE_PLACEHOLDER,
|
||||||
PAGE_READONLY, nullptr, 0);
|
PAGE_READONLY, nullptr, 0);
|
||||||
if (!result)
|
if (!result)
|
||||||
|
@ -532,7 +534,7 @@ void LazyMemoryRegion::Clear()
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
// unmap the writable block
|
// unmap the writable block
|
||||||
if (!static_cast<PUnmapViewOfFileEx>(m_memory_functions.m_address_UnmapViewOfFileEx)(
|
if (!reinterpret_cast<PUnmapViewOfFileEx>(m_memory_functions.m_address_UnmapViewOfFileEx)(
|
||||||
memory + i * BLOCK_SIZE, MEM_PRESERVE_PLACEHOLDER))
|
memory + i * BLOCK_SIZE, MEM_PRESERVE_PLACEHOLDER))
|
||||||
{
|
{
|
||||||
PanicAlertFmt("Failed to unmap the writable block: {}", GetLastErrorString());
|
PanicAlertFmt("Failed to unmap the writable block: {}", GetLastErrorString());
|
||||||
|
@ -546,9 +548,10 @@ void LazyMemoryRegion::Clear()
|
||||||
m_writable_block_handles[i] = nullptr;
|
m_writable_block_handles[i] = nullptr;
|
||||||
|
|
||||||
// map the zero block
|
// map the zero block
|
||||||
void* map_result = static_cast<PMapViewOfFile3>(m_memory_functions.m_address_MapViewOfFile3)(
|
void* map_result =
|
||||||
m_zero_block, nullptr, memory + i * BLOCK_SIZE, 0, BLOCK_SIZE, MEM_REPLACE_PLACEHOLDER,
|
reinterpret_cast<PMapViewOfFile3>(m_memory_functions.m_address_MapViewOfFile3)(
|
||||||
PAGE_READONLY, nullptr, 0);
|
m_zero_block, nullptr, memory + i * BLOCK_SIZE, 0, BLOCK_SIZE, MEM_REPLACE_PLACEHOLDER,
|
||||||
|
PAGE_READONLY, nullptr, 0);
|
||||||
if (!map_result)
|
if (!map_result)
|
||||||
{
|
{
|
||||||
PanicAlertFmt("Failed to re-map the zero block: {}", GetLastErrorString());
|
PanicAlertFmt("Failed to re-map the zero block: {}", GetLastErrorString());
|
||||||
|
@ -564,7 +567,7 @@ void LazyMemoryRegion::Release()
|
||||||
u8* const memory = static_cast<u8*>(m_memory);
|
u8* const memory = static_cast<u8*>(m_memory);
|
||||||
for (size_t i = 0; i < m_writable_block_handles.size(); ++i)
|
for (size_t i = 0; i < m_writable_block_handles.size(); ++i)
|
||||||
{
|
{
|
||||||
static_cast<PUnmapViewOfFileEx>(m_memory_functions.m_address_UnmapViewOfFileEx)(
|
reinterpret_cast<PUnmapViewOfFileEx>(m_memory_functions.m_address_UnmapViewOfFileEx)(
|
||||||
memory + i * BLOCK_SIZE, MEM_PRESERVE_PLACEHOLDER);
|
memory + i * BLOCK_SIZE, MEM_PRESERVE_PLACEHOLDER);
|
||||||
if (m_writable_block_handles[i])
|
if (m_writable_block_handles[i])
|
||||||
{
|
{
|
||||||
|
@ -594,7 +597,7 @@ void LazyMemoryRegion::MakeMemoryBlockWritable(size_t block_index)
|
||||||
u8* const memory = static_cast<u8*>(m_memory);
|
u8* const memory = static_cast<u8*>(m_memory);
|
||||||
|
|
||||||
// unmap the zero block
|
// unmap the zero block
|
||||||
if (!static_cast<PUnmapViewOfFileEx>(m_memory_functions.m_address_UnmapViewOfFileEx)(
|
if (!reinterpret_cast<PUnmapViewOfFileEx>(m_memory_functions.m_address_UnmapViewOfFileEx)(
|
||||||
memory + block_index * BLOCK_SIZE, MEM_PRESERVE_PLACEHOLDER))
|
memory + block_index * BLOCK_SIZE, MEM_PRESERVE_PLACEHOLDER))
|
||||||
{
|
{
|
||||||
PanicAlertFmt("Failed to unmap the zero block: {}", GetLastErrorString());
|
PanicAlertFmt("Failed to unmap the zero block: {}", GetLastErrorString());
|
||||||
|
@ -611,7 +614,7 @@ void LazyMemoryRegion::MakeMemoryBlockWritable(size_t block_index)
|
||||||
}
|
}
|
||||||
|
|
||||||
// map the new block
|
// map the new block
|
||||||
void* map_result = static_cast<PMapViewOfFile3>(m_memory_functions.m_address_MapViewOfFile3)(
|
void* map_result = reinterpret_cast<PMapViewOfFile3>(m_memory_functions.m_address_MapViewOfFile3)(
|
||||||
block, nullptr, memory + block_index * BLOCK_SIZE, 0, BLOCK_SIZE, MEM_REPLACE_PLACEHOLDER,
|
block, nullptr, memory + block_index * BLOCK_SIZE, 0, BLOCK_SIZE, MEM_REPLACE_PLACEHOLDER,
|
||||||
PAGE_READWRITE, nullptr, 0);
|
PAGE_READWRITE, nullptr, 0);
|
||||||
if (!map_result)
|
if (!map_result)
|
||||||
|
|
|
@ -5,8 +5,10 @@
|
||||||
|
|
||||||
#if defined(_WIN32)
|
#if defined(_WIN32)
|
||||||
#include <Qos2.h>
|
#include <Qos2.h>
|
||||||
|
#ifdef _MSC_VER
|
||||||
#pragma comment(lib, "qwave")
|
#pragma comment(lib, "qwave")
|
||||||
#endif
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "Core/ConfigManager.h"
|
#include "Core/ConfigManager.h"
|
||||||
|
|
||||||
|
|
|
@ -581,6 +581,10 @@ std::string UTF16BEToUTF8(const char16_t* str, size_t max_size)
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifndef _MSC_VER
|
||||||
|
#pragma GCC diagnostic push
|
||||||
|
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
|
||||||
|
#endif
|
||||||
std::string UTF16ToUTF8(std::u16string_view input)
|
std::string UTF16ToUTF8(std::u16string_view input)
|
||||||
{
|
{
|
||||||
std::wstring_convert<std::codecvt_utf8_utf16<char16_t>, char16_t> converter;
|
std::wstring_convert<std::codecvt_utf8_utf16<char16_t>, char16_t> converter;
|
||||||
|
@ -592,6 +596,9 @@ std::u16string UTF8ToUTF16(std::string_view input)
|
||||||
std::wstring_convert<std::codecvt_utf8_utf16<char16_t>, char16_t> converter;
|
std::wstring_convert<std::codecvt_utf8_utf16<char16_t>, char16_t> converter;
|
||||||
return converter.from_bytes(input.data(), input.data() + input.size());
|
return converter.from_bytes(input.data(), input.data() + input.size());
|
||||||
}
|
}
|
||||||
|
#ifndef _MSC_VER
|
||||||
|
#pragma GCC diagnostic pop
|
||||||
|
#endif
|
||||||
|
|
||||||
// This is a replacement for path::u8path, which is deprecated starting with C++20.
|
// This is a replacement for path::u8path, which is deprecated starting with C++20.
|
||||||
std::filesystem::path StringToPath(std::string_view path)
|
std::filesystem::path StringToPath(std::string_view path)
|
||||||
|
@ -607,7 +614,7 @@ std::filesystem::path StringToPath(std::string_view path)
|
||||||
// path::u8string returns std::u8string starting with C++20, which is annoying to convert.
|
// path::u8string returns std::u8string starting with C++20, which is annoying to convert.
|
||||||
std::string PathToString(const std::filesystem::path& path)
|
std::string PathToString(const std::filesystem::path& path)
|
||||||
{
|
{
|
||||||
#ifdef _MSC_VER
|
#ifdef _WIN32
|
||||||
return WStringToUTF8(path.native());
|
return WStringToUTF8(path.native());
|
||||||
#else
|
#else
|
||||||
return path.native();
|
return path.native();
|
||||||
|
@ -625,7 +632,7 @@ std::vector<std::string> CommandLineToUtf8Argv(const wchar_t* command_line)
|
||||||
return {};
|
return {};
|
||||||
|
|
||||||
std::vector<std::string> argv(nargs);
|
std::vector<std::string> argv(nargs);
|
||||||
for (size_t i = 0; i < nargs; ++i)
|
for (int i = 0; i < nargs; ++i)
|
||||||
{
|
{
|
||||||
argv[i] = WStringToUTF8(tokenized[i]);
|
argv[i] = WStringToUTF8(tokenized[i]);
|
||||||
}
|
}
|
||||||
|
|
|
@ -47,7 +47,7 @@ int CurrentThreadId()
|
||||||
|
|
||||||
void SetThreadAffinity(std::thread::native_handle_type thread, u32 mask)
|
void SetThreadAffinity(std::thread::native_handle_type thread, u32 mask)
|
||||||
{
|
{
|
||||||
SetThreadAffinityMask(thread, mask);
|
SetThreadAffinityMask((HANDLE)thread, mask);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetCurrentThreadAffinity(u32 mask)
|
void SetCurrentThreadAffinity(u32 mask)
|
||||||
|
@ -66,6 +66,7 @@ void SwitchCurrentThread()
|
||||||
SwitchToThread();
|
SwitchToThread();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef _MSC_VER
|
||||||
// Sets the debugger-visible name of the current thread.
|
// Sets the debugger-visible name of the current thread.
|
||||||
// Uses trick documented in:
|
// Uses trick documented in:
|
||||||
// https://docs.microsoft.com/en-us/visualstudio/debugger/how-to-set-a-thread-name-in-native-code
|
// https://docs.microsoft.com/en-us/visualstudio/debugger/how-to-set-a-thread-name-in-native-code
|
||||||
|
@ -96,6 +97,7 @@ static void SetCurrentThreadNameViaException(const char* name)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
static void SetCurrentThreadNameViaApi(const char* name)
|
static void SetCurrentThreadNameViaApi(const char* name)
|
||||||
{
|
{
|
||||||
|
@ -112,7 +114,9 @@ static void SetCurrentThreadNameViaApi(const char* name)
|
||||||
|
|
||||||
void SetCurrentThreadName(const char* name)
|
void SetCurrentThreadName(const char* name)
|
||||||
{
|
{
|
||||||
|
#ifdef _MSC_VER
|
||||||
SetCurrentThreadNameViaException(name);
|
SetCurrentThreadNameViaException(name);
|
||||||
|
#endif
|
||||||
SetCurrentThreadNameViaApi(name);
|
SetCurrentThreadNameViaApi(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -11,7 +11,7 @@ namespace Common
|
||||||
std::optional<std::tm> Localtime(std::time_t time)
|
std::optional<std::tm> Localtime(std::time_t time)
|
||||||
{
|
{
|
||||||
std::tm local_time;
|
std::tm local_time;
|
||||||
#ifdef _MSC_VER
|
#ifdef _WIN32
|
||||||
if (localtime_s(&local_time, &time) != 0)
|
if (localtime_s(&local_time, &time) != 0)
|
||||||
return std::nullopt;
|
return std::nullopt;
|
||||||
#else
|
#else
|
||||||
|
|
|
@ -7,6 +7,9 @@
|
||||||
|
|
||||||
namespace WindowsRegistry
|
namespace WindowsRegistry
|
||||||
{
|
{
|
||||||
|
template bool ReadValue(u32* value, const std::string& subkey, const std::string& name);
|
||||||
|
template bool ReadValue(u64* value, const std::string& subkey, const std::string& name);
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
bool ReadValue(T* value, const std::string& subkey, const std::string& name)
|
bool ReadValue(T* value, const std::string& subkey, const std::string& name)
|
||||||
{
|
{
|
||||||
|
|
|
@ -9,8 +9,8 @@ namespace WindowsRegistry
|
||||||
{
|
{
|
||||||
template <typename T>
|
template <typename T>
|
||||||
bool ReadValue(T* value, const std::string& subkey, const std::string& name);
|
bool ReadValue(T* value, const std::string& subkey, const std::string& name);
|
||||||
template bool ReadValue(u32* value, const std::string& subkey, const std::string& name);
|
extern template bool ReadValue(u32* value, const std::string& subkey, const std::string& name);
|
||||||
template bool ReadValue(u64* value, const std::string& subkey, const std::string& name);
|
extern template bool ReadValue(u64* value, const std::string& subkey, const std::string& name);
|
||||||
template <>
|
template <>
|
||||||
bool ReadValue(std::string* value, const std::string& subkey, const std::string& name);
|
bool ReadValue(std::string* value, const std::string& subkey, const std::string& name);
|
||||||
|
|
||||||
|
|
|
@ -21,6 +21,10 @@
|
||||||
#include "Common/MsgHandler.h"
|
#include "Common/MsgHandler.h"
|
||||||
#include "Common/StringUtil.h"
|
#include "Common/StringUtil.h"
|
||||||
|
|
||||||
|
#ifndef _XCR_XFEATURE_ENABLED_MASK
|
||||||
|
#define _XCR_XFEATURE_ENABLED_MASK 0
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifndef _WIN32
|
#ifndef _WIN32
|
||||||
|
|
||||||
#ifdef __FreeBSD__
|
#ifdef __FreeBSD__
|
||||||
|
@ -55,6 +59,12 @@ static u64 xgetbv(u32 index)
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
|
#if defined(_MSC_VER) || defined(__clang__)
|
||||||
|
#include <intrin.h>
|
||||||
|
#else
|
||||||
|
#include <cpuid.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
constexpr u32 XCR_XFEATURE_ENABLED_MASK = _XCR_XFEATURE_ENABLED_MASK;
|
constexpr u32 XCR_XFEATURE_ENABLED_MASK = _XCR_XFEATURE_ENABLED_MASK;
|
||||||
|
|
||||||
static u64 xgetbv(u32 index)
|
static u64 xgetbv(u32 index)
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
add_library(core
|
add_library(core STATIC
|
||||||
AchievementManager.cpp
|
AchievementManager.cpp
|
||||||
AchievementManager.h
|
AchievementManager.h
|
||||||
ActionReplay.cpp
|
ActionReplay.cpp
|
||||||
|
@ -719,7 +719,6 @@ if(WIN32)
|
||||||
videod3d
|
videod3d
|
||||||
videod3d12
|
videod3d12
|
||||||
setupapi.lib
|
setupapi.lib
|
||||||
iphlpapi.lib
|
|
||||||
)
|
)
|
||||||
target_compile_definitions(core PRIVATE "-D_WINSOCK_DEPRECATED_NO_WARNINGS")
|
target_compile_definitions(core PRIVATE "-D_WINSOCK_DEPRECATED_NO_WARNINGS")
|
||||||
elseif(APPLE)
|
elseif(APPLE)
|
||||||
|
@ -787,11 +786,10 @@ if(MSVC)
|
||||||
target_link_libraries(core PRIVATE use_pch)
|
target_link_libraries(core PRIVATE use_pch)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(USE_RETRO_ACHIEVEMENTS)
|
if(NOT MSVC)
|
||||||
target_link_libraries(core PUBLIC rcheevos)
|
target_compile_options(core PRIVATE -Wno-invalid-offsetof)
|
||||||
target_compile_definitions(core PUBLIC -DUSE_RETRO_ACHIEVEMENTS)
|
endif()
|
||||||
target_compile_definitions(core PUBLIC -DRC_CLIENT_SUPPORTS_HASH)
|
|
||||||
if(RC_CLIENT_SUPPORTS_RAINTEGRATION)
|
if(USE_ASAN)
|
||||||
target_compile_definitions(core PUBLIC -DRC_CLIENT_SUPPORTS_RAINTEGRATION)
|
set_source_files_properties(MemTools.cpp PROPERTIES COMPILE_DEFINITIONS USE_ASAN)
|
||||||
endif()
|
|
||||||
endif()
|
endif()
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
#include "SFML/Network/Socket.hpp"
|
#include "SFML/Network/Socket.hpp"
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
#include <ws2ipdef.h>
|
#include <Ws2tcpip.h>
|
||||||
#else
|
#else
|
||||||
#include <sys/select.h>
|
#include <sys/select.h>
|
||||||
#include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
|
@ -803,7 +803,12 @@ sf::Socket::Status BbaTcpSocket::Connect(const sf::IpAddress& dest, u16 port, u3
|
||||||
addr.sin_addr.s_addr = net_ip;
|
addr.sin_addr.s_addr = net_ip;
|
||||||
addr.sin_family = AF_INET;
|
addr.sin_family = AF_INET;
|
||||||
addr.sin_port = 0;
|
addr.sin_port = 0;
|
||||||
(void)::bind(getNativeHandle(), reinterpret_cast<sockaddr*>(&addr), sizeof(addr));
|
if (::bind(getNativeHandle(), reinterpret_cast<sockaddr*>(&addr), sizeof(addr)) != 0)
|
||||||
|
{
|
||||||
|
ERROR_LOG_FMT(SP1, "bind failed: {}", Common::StrNetworkError());
|
||||||
|
m_connecting_state = ConnectingState::Error;
|
||||||
|
return sf::Socket::Status::Error;
|
||||||
|
}
|
||||||
m_connecting_state = ConnectingState::Connecting;
|
m_connecting_state = ConnectingState::Connecting;
|
||||||
return this->connect(dest, port);
|
return this->connect(dest, port);
|
||||||
}
|
}
|
||||||
|
@ -837,7 +842,7 @@ BbaTcpSocket::ConnectingState BbaTcpSocket::Connected(StackRef* ref)
|
||||||
{
|
{
|
||||||
case ConnectingState::Connecting:
|
case ConnectingState::Connecting:
|
||||||
{
|
{
|
||||||
const int fd = getNativeHandle();
|
const sf::SocketHandle fd = getNativeHandle();
|
||||||
const s32 nfds = fd + 1;
|
const s32 nfds = fd + 1;
|
||||||
fd_set read_fds;
|
fd_set read_fds;
|
||||||
fd_set write_fds;
|
fd_set write_fds;
|
||||||
|
|
|
@ -32,6 +32,7 @@ using ws_ssize_t = int;
|
||||||
#else
|
#else
|
||||||
#define closesocket close
|
#define closesocket close
|
||||||
using ws_ssize_t = ssize_t;
|
using ws_ssize_t = ssize_t;
|
||||||
|
#define SOCKET int
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef __linux__
|
#ifdef __linux__
|
||||||
|
@ -260,7 +261,7 @@ void TAPServerConnection::ReadThreadHandler()
|
||||||
{
|
{
|
||||||
fd_set rfds;
|
fd_set rfds;
|
||||||
FD_ZERO(&rfds);
|
FD_ZERO(&rfds);
|
||||||
FD_SET(m_fd, &rfds);
|
FD_SET((SOCKET)m_fd, &rfds);
|
||||||
|
|
||||||
timeval timeout;
|
timeval timeout;
|
||||||
timeout.tv_sec = 0;
|
timeout.tv_sec = 0;
|
||||||
|
|
|
@ -785,8 +785,8 @@ IPCReply NetIPTopDevice::HandleGetPeerNameRequest(const IOCtlRequest& request)
|
||||||
|
|
||||||
IPCReply NetIPTopDevice::HandleGetHostIDRequest(const IOCtlRequest& request)
|
IPCReply NetIPTopDevice::HandleGetHostIDRequest(const IOCtlRequest& request)
|
||||||
{
|
{
|
||||||
const DefaultInterface interface = GetSystemDefaultInterfaceOrFallback();
|
const DefaultInterface iface = GetSystemDefaultInterfaceOrFallback();
|
||||||
const u32 host_ip = ntohl(interface.inet.s_addr);
|
const u32 host_ip = ntohl(iface.inet.s_addr);
|
||||||
INFO_LOG_FMT(IOS_NET, "IOCTL_SO_GETHOSTID = {}.{}.{}.{}", host_ip >> 24, (host_ip >> 16) & 0xFF,
|
INFO_LOG_FMT(IOS_NET, "IOCTL_SO_GETHOSTID = {}.{}.{}.{}", host_ip >> 24, (host_ip >> 16) & 0xFF,
|
||||||
(host_ip >> 8) & 0xFF, host_ip & 0xFF);
|
(host_ip >> 8) & 0xFF, host_ip & 0xFF);
|
||||||
return IPCReply(host_ip);
|
return IPCReply(host_ip);
|
||||||
|
@ -1158,10 +1158,10 @@ IPCReply NetIPTopDevice::HandleGetInterfaceOptRequest(const IOCtlVRequest& reque
|
||||||
// XXX: this isn't exactly right; the buffer can be larger than 12 bytes,
|
// XXX: this isn't exactly right; the buffer can be larger than 12 bytes,
|
||||||
// in which case, depending on some interface settings, SO can write 12 more bytes
|
// in which case, depending on some interface settings, SO can write 12 more bytes
|
||||||
memory.Write_U32(0xC, request.io_vectors[1].address);
|
memory.Write_U32(0xC, request.io_vectors[1].address);
|
||||||
const DefaultInterface interface = GetSystemDefaultInterfaceOrFallback();
|
const DefaultInterface iface = GetSystemDefaultInterfaceOrFallback();
|
||||||
memory.Write_U32(ntohl(interface.inet.s_addr), request.io_vectors[0].address);
|
memory.Write_U32(ntohl(iface.inet.s_addr), request.io_vectors[0].address);
|
||||||
memory.Write_U32(ntohl(interface.netmask.s_addr), request.io_vectors[0].address + 4);
|
memory.Write_U32(ntohl(iface.netmask.s_addr), request.io_vectors[0].address + 4);
|
||||||
memory.Write_U32(ntohl(interface.broadcast.s_addr), request.io_vectors[0].address + 8);
|
memory.Write_U32(ntohl(iface.broadcast.s_addr), request.io_vectors[0].address + 8);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1173,8 +1173,8 @@ IPCReply NetIPTopDevice::HandleGetInterfaceOptRequest(const IOCtlVRequest& reque
|
||||||
|
|
||||||
case 0x4006: // get routing table
|
case 0x4006: // get routing table
|
||||||
{
|
{
|
||||||
const DefaultInterface interface = GetSystemDefaultInterfaceOrFallback();
|
const DefaultInterface iface = GetSystemDefaultInterfaceOrFallback();
|
||||||
for (InterfaceRouting route : interface.routing_table)
|
for (InterfaceRouting route : iface.routing_table)
|
||||||
{
|
{
|
||||||
memory.Write_U32(ntohl(route.destination.s_addr), request.io_vectors[0].address + param5);
|
memory.Write_U32(ntohl(route.destination.s_addr), request.io_vectors[0].address + param5);
|
||||||
memory.Write_U32(ntohl(route.netmask.s_addr), request.io_vectors[0].address + param5 + 4);
|
memory.Write_U32(ntohl(route.netmask.s_addr), request.io_vectors[0].address + param5 + 4);
|
||||||
|
|
|
@ -36,6 +36,7 @@
|
||||||
#define ERRORCODE(name) name
|
#define ERRORCODE(name) name
|
||||||
#define EITHER(win32, posix) posix
|
#define EITHER(win32, posix) posix
|
||||||
#define closesocket close
|
#define closesocket close
|
||||||
|
#define SOCKET int
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
namespace IOS::HLE
|
namespace IOS::HLE
|
||||||
|
@ -753,7 +754,7 @@ WiiSocket::ConnectingState WiiSocket::GetConnectingState() const
|
||||||
Common::ScopeGuard guard([&state] { Common::RestoreNetworkErrorState(state); });
|
Common::ScopeGuard guard([&state] { Common::RestoreNetworkErrorState(state); });
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
constexpr int (*get_errno)() = &WSAGetLastError;
|
int (*get_errno)() = &WSAGetLastError;
|
||||||
#else
|
#else
|
||||||
constexpr int (*get_errno)() = []() { return errno; };
|
constexpr int (*get_errno)() = []() { return errno; };
|
||||||
#endif
|
#endif
|
||||||
|
@ -774,8 +775,8 @@ WiiSocket::ConnectingState WiiSocket::GetConnectingState() const
|
||||||
FD_ZERO(&read_fds);
|
FD_ZERO(&read_fds);
|
||||||
FD_ZERO(&write_fds);
|
FD_ZERO(&write_fds);
|
||||||
FD_ZERO(&except_fds);
|
FD_ZERO(&except_fds);
|
||||||
FD_SET(fd, &write_fds);
|
FD_SET((SOCKET)fd, &write_fds);
|
||||||
FD_SET(fd, &except_fds);
|
FD_SET((SOCKET)fd, &except_fds);
|
||||||
|
|
||||||
if (select(nfds, &read_fds, &write_fds, &except_fds, &t) < 0)
|
if (select(nfds, &read_fds, &write_fds, &except_fds, &t) < 0)
|
||||||
{
|
{
|
||||||
|
@ -1011,9 +1012,9 @@ void WiiSockMan::Update()
|
||||||
const WiiSocket& sock = socket_iter->second;
|
const WiiSocket& sock = socket_iter->second;
|
||||||
if (sock.IsValid())
|
if (sock.IsValid())
|
||||||
{
|
{
|
||||||
FD_SET(sock.fd, &read_fds);
|
FD_SET((SOCKET)sock.fd, &read_fds);
|
||||||
FD_SET(sock.fd, &write_fds);
|
FD_SET((SOCKET)sock.fd, &write_fds);
|
||||||
FD_SET(sock.fd, &except_fds);
|
FD_SET((SOCKET)sock.fd, &except_fds);
|
||||||
nfds = std::max(nfds, sock.fd + 1);
|
nfds = std::max(nfds, sock.fd + 1);
|
||||||
++socket_iter;
|
++socket_iter;
|
||||||
}
|
}
|
||||||
|
@ -1176,7 +1177,8 @@ WiiSockAddrIn WiiSockMan::ToWiiAddrIn(const sockaddr_in& from, socklen_t addrlen
|
||||||
{
|
{
|
||||||
WiiSockAddrIn result;
|
WiiSockAddrIn result;
|
||||||
|
|
||||||
result.len = u8(addrlen > sizeof(WiiSockAddrIn) ? sizeof(WiiSockAddrIn) : addrlen);
|
result.len =
|
||||||
|
u8(static_cast<size_t>(addrlen) > sizeof(WiiSockAddrIn) ? sizeof(WiiSockAddrIn) : addrlen);
|
||||||
result.family = u8(from.sin_family & 0xFF);
|
result.family = u8(from.sin_family & 0xFF);
|
||||||
result.port = from.sin_port;
|
result.port = from.sin_port;
|
||||||
result.addr.addr = from.sin_addr.s_addr;
|
result.addr.addr = from.sin_addr.s_addr;
|
||||||
|
|
|
@ -12,6 +12,8 @@
|
||||||
#include "Common/CommonTypes.h"
|
#include "Common/CommonTypes.h"
|
||||||
#include "Core/IOS/Device.h"
|
#include "Core/IOS/Device.h"
|
||||||
|
|
||||||
|
#pragma push_macro("interface")
|
||||||
|
#undef interface
|
||||||
namespace IOS::HLE::USB
|
namespace IOS::HLE::USB
|
||||||
{
|
{
|
||||||
constexpr u8 DEFAULT_CONFIG_NUM = 0;
|
constexpr u8 DEFAULT_CONFIG_NUM = 0;
|
||||||
|
@ -189,3 +191,5 @@ protected:
|
||||||
u64 m_id = 0xFFFFFFFFFFFFFFFF;
|
u64 m_id = 0xFFFFFFFFFFFFFFFF;
|
||||||
};
|
};
|
||||||
} // namespace IOS::HLE::USB
|
} // namespace IOS::HLE::USB
|
||||||
|
|
||||||
|
#pragma pop_macro("interface")
|
||||||
|
|
|
@ -77,12 +77,12 @@ public:
|
||||||
DeviceDescriptor GetDeviceDescriptor() const override;
|
DeviceDescriptor GetDeviceDescriptor() const override;
|
||||||
std::vector<ConfigDescriptor> GetConfigurations() const override;
|
std::vector<ConfigDescriptor> GetConfigurations() const override;
|
||||||
std::vector<InterfaceDescriptor> GetInterfaces(u8 config) const override;
|
std::vector<InterfaceDescriptor> GetInterfaces(u8 config) const override;
|
||||||
std::vector<EndpointDescriptor> GetEndpoints(u8 config, u8 interface, u8 alt) const override;
|
std::vector<EndpointDescriptor> GetEndpoints(u8 config, u8 iface, u8 alt) const override;
|
||||||
bool Attach() override;
|
bool Attach() override;
|
||||||
bool AttachAndChangeInterface(u8 interface) override;
|
bool AttachAndChangeInterface(u8 iface) override;
|
||||||
int CancelTransfer(u8 endpoint) override;
|
int CancelTransfer(u8 endpoint) override;
|
||||||
int ChangeInterface(u8 interface) override;
|
int ChangeInterface(u8 iface) override;
|
||||||
int GetNumberOfAltSettings(u8 interface) override;
|
int GetNumberOfAltSettings(u8 iface) override;
|
||||||
int SetAltSetting(u8 alt_setting) override;
|
int SetAltSetting(u8 alt_setting) override;
|
||||||
int SubmitTransfer(std::unique_ptr<CtrlMessage> message) override;
|
int SubmitTransfer(std::unique_ptr<CtrlMessage> message) override;
|
||||||
int SubmitTransfer(std::unique_ptr<BulkMessage> message) override;
|
int SubmitTransfer(std::unique_ptr<BulkMessage> message) override;
|
||||||
|
|
|
@ -102,7 +102,11 @@ static LONG NTAPI Handler(PEXCEPTION_POINTERS pPtrs)
|
||||||
void InstallExceptionHandler()
|
void InstallExceptionHandler()
|
||||||
{
|
{
|
||||||
ASSERT(!s_veh_handle);
|
ASSERT(!s_veh_handle);
|
||||||
|
#ifdef USE_ASAN
|
||||||
|
s_veh_handle = AddVectoredExceptionHandler(FALSE, Handler);
|
||||||
|
#else
|
||||||
s_veh_handle = AddVectoredExceptionHandler(TRUE, Handler);
|
s_veh_handle = AddVectoredExceptionHandler(TRUE, Handler);
|
||||||
|
#endif
|
||||||
ASSERT(s_veh_handle);
|
ASSERT(s_veh_handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -23,6 +23,7 @@ typedef SSIZE_T ssize_t;
|
||||||
#include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
#include <sys/un.h>
|
#include <sys/un.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
#define SOCKET int
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "Common/Assert.h"
|
#include "Common/Assert.h"
|
||||||
|
@ -264,7 +265,7 @@ static bool IsDataAvailable()
|
||||||
fd_set _fds, *fds = &_fds;
|
fd_set _fds, *fds = &_fds;
|
||||||
|
|
||||||
FD_ZERO(fds);
|
FD_ZERO(fds);
|
||||||
FD_SET(s_sock, fds);
|
FD_SET((SOCKET)s_sock, fds);
|
||||||
|
|
||||||
t.tv_sec = 0;
|
t.tv_sec = 0;
|
||||||
t.tv_usec = 20;
|
t.tv_usec = 20;
|
||||||
|
|
|
@ -84,3 +84,8 @@ if(MSVC)
|
||||||
# Add precompiled header
|
# Add precompiled header
|
||||||
target_link_libraries(discio PRIVATE use_pch)
|
target_link_libraries(discio PRIVATE use_pch)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
if(USE_RETRO_ACHIEVEMENTS)
|
||||||
|
target_link_libraries(discio PUBLIC rcheevos)
|
||||||
|
target_compile_definitions(discio PUBLIC -DUSE_RETRO_ACHIEVEMENTS)
|
||||||
|
endif()
|
||||||
|
|
|
@ -12,6 +12,7 @@ endif()
|
||||||
|
|
||||||
if(WIN32)
|
if(WIN32)
|
||||||
target_sources(dolphin-nogui PRIVATE PlatformWin32.cpp)
|
target_sources(dolphin-nogui PRIVATE PlatformWin32.cpp)
|
||||||
|
target_link_libraries(dolphin-nogui PRIVATE Dwmapi.lib)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(APPLE)
|
if(APPLE)
|
||||||
|
@ -32,6 +33,11 @@ PRIVATE
|
||||||
cpp-optparse
|
cpp-optparse
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if(WIN32)
|
||||||
|
target_link_libraries(dolphin-nogui PRIVATE d3d11)
|
||||||
|
target_link_options(dolphin-nogui PRIVATE -municode)
|
||||||
|
endif()
|
||||||
|
|
||||||
if(APPLE)
|
if(APPLE)
|
||||||
target_link_libraries(dolphin-nogui
|
target_link_libraries(dolphin-nogui
|
||||||
PRIVATE
|
PRIVATE
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
// Microsoft Visual C++ generated resource script.
|
// Microsoft Visual C++ generated resource script.
|
||||||
//
|
//
|
||||||
#include "resource.h"
|
#include "resource.h"
|
||||||
IDI_ICON1 ICON "..\\..\\..\\Installer\\Dolphin.ico"
|
IDI_ICON1 ICON "..\\..\\..\\Installer\\Dolphin.ico"
|
||||||
"dolphin" ICON "..\\..\\..\\Installer\\Dolphin.ico"
|
"dolphin" ICON "..\\..\\..\\Installer\\Dolphin.ico"
|
||||||
|
|
||||||
|
|
|
@ -14,6 +14,7 @@
|
||||||
#include <climits>
|
#include <climits>
|
||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
#include <dwmapi.h>
|
#include <dwmapi.h>
|
||||||
|
#include <thread>
|
||||||
|
|
||||||
#include "VideoCommon/Present.h"
|
#include "VideoCommon/Present.h"
|
||||||
#include "resource.h"
|
#include "resource.h"
|
||||||
|
@ -29,7 +30,7 @@ public:
|
||||||
void SetTitle(const std::string& string) override;
|
void SetTitle(const std::string& string) override;
|
||||||
void MainLoop() override;
|
void MainLoop() override;
|
||||||
|
|
||||||
WindowSystemInfo GetWindowSystemInfo() const;
|
WindowSystemInfo GetWindowSystemInfo() const override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static constexpr TCHAR WINDOW_CLASS_NAME[] = _T("DolphinNoGUI");
|
static constexpr TCHAR WINDOW_CLASS_NAME[] = _T("DolphinNoGUI");
|
||||||
|
|
|
@ -19,7 +19,7 @@ message(STATUS "Found Qt version ${Qt6_VERSION}")
|
||||||
|
|
||||||
set_property(TARGET Qt6::Core PROPERTY INTERFACE_COMPILE_FEATURES "")
|
set_property(TARGET Qt6::Core PROPERTY INTERFACE_COMPILE_FEATURES "")
|
||||||
|
|
||||||
add_executable(dolphin-emu
|
add_executable(dolphin-emu WIN32
|
||||||
AboutDialog.cpp
|
AboutDialog.cpp
|
||||||
AboutDialog.h
|
AboutDialog.h
|
||||||
CheatSearchFactoryWidget.cpp
|
CheatSearchFactoryWidget.cpp
|
||||||
|
@ -439,6 +439,7 @@ if (WIN32)
|
||||||
shell32.lib
|
shell32.lib
|
||||||
dwmapi.lib # Needed to set window decorations for dark theme
|
dwmapi.lib # Needed to set window decorations for dark theme
|
||||||
)
|
)
|
||||||
|
target_link_options(dolphin-emu PRIVATE -municode)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if (MSVC)
|
if (MSVC)
|
||||||
|
@ -490,11 +491,6 @@ if(WIN32)
|
||||||
COMMAND ${CMAKE_COMMAND} -E copy_if_different "${CMAKE_CURRENT_SOURCE_DIR}/qt.conf.win" "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/qt.conf"
|
COMMAND ${CMAKE_COMMAND} -E copy_if_different "${CMAKE_CURRENT_SOURCE_DIR}/qt.conf.win" "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/qt.conf"
|
||||||
)
|
)
|
||||||
|
|
||||||
# Delegate to Qt's official deployment binary on Windows to copy over the necessary Qt-specific libraries, etc.
|
|
||||||
get_target_property(MOC_EXECUTABLE_LOCATION Qt6::moc IMPORTED_LOCATION)
|
|
||||||
get_filename_component(QT_BINARY_DIRECTORY "${MOC_EXECUTABLE_LOCATION}" DIRECTORY)
|
|
||||||
find_program(WINDEPLOYQT_EXE windeployqt HINTS "${QT_BINARY_DIRECTORY}")
|
|
||||||
|
|
||||||
# Note: We set the PATH for the duration of this command so that the
|
# Note: We set the PATH for the duration of this command so that the
|
||||||
# deployment application is able to locate the Qt libraries to copy.
|
# deployment application is able to locate the Qt libraries to copy.
|
||||||
# if the necessary paths aren't already set beforehand.
|
# if the necessary paths aren't already set beforehand.
|
||||||
|
@ -511,13 +507,13 @@ if(WIN32)
|
||||||
#
|
#
|
||||||
add_custom_command(TARGET dolphin-emu POST_BUILD
|
add_custom_command(TARGET dolphin-emu POST_BUILD
|
||||||
COMMAND "${CMAKE_COMMAND}" -E env PATH="${QT_BINARY_DIRECTORY}"
|
COMMAND "${CMAKE_COMMAND}" -E env PATH="${QT_BINARY_DIRECTORY}"
|
||||||
"${WINDEPLOYQT_EXE}" --libdir="${CMAKE_RUNTIME_OUTPUT_DIRECTORY}"
|
"${WINDEPLOYQT_EXECUTABLE}" --libdir="${CMAKE_RUNTIME_OUTPUT_DIRECTORY}"
|
||||||
--plugindir="${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/QtPlugins"
|
--plugindir="${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/QtPlugins"
|
||||||
$<IF:$<CONFIG:Debug>,--debug,--release>
|
|
||||||
--no-translations
|
--no-translations
|
||||||
--no-compiler-runtime
|
--no-compiler-runtime
|
||||||
--no-system-d3d-compiler
|
--no-system-d3d-compiler
|
||||||
--no-opengl-sw
|
--no-opengl-sw
|
||||||
|
--verbose 0
|
||||||
"$<TARGET_FILE:dolphin-emu>"
|
"$<TARGET_FILE:dolphin-emu>"
|
||||||
)
|
)
|
||||||
endif()
|
endif()
|
||||||
|
@ -677,7 +673,4 @@ endif()
|
||||||
if(USE_RETRO_ACHIEVEMENTS)
|
if(USE_RETRO_ACHIEVEMENTS)
|
||||||
target_link_libraries(dolphin-emu PRIVATE rcheevos)
|
target_link_libraries(dolphin-emu PRIVATE rcheevos)
|
||||||
target_compile_definitions(dolphin-emu PRIVATE -DUSE_RETRO_ACHIEVEMENTS)
|
target_compile_definitions(dolphin-emu PRIVATE -DUSE_RETRO_ACHIEVEMENTS)
|
||||||
if(RC_CLIENT_SUPPORTS_RAINTEGRATION)
|
|
||||||
target_compile_definitions(dolphin-emu PRIVATE -DRC_CLIENT_SUPPORTS_RAINTEGRATION)
|
|
||||||
endif()
|
|
||||||
endif()
|
endif()
|
||||||
|
|
|
@ -1,6 +1,4 @@
|
||||||
// Microsoft Visual C++ generated resource script.
|
// Microsoft Visual C++ generated resource script.
|
||||||
//
|
//
|
||||||
#include "resource.h"
|
#include "resource.h"
|
||||||
IDI_ICON1 ICON "..\\..\\..\\Installer\\Dolphin.ico"
|
IDI_ICON1 ICON "..\\..\\..\\Installer\\Dolphin.ico"
|
||||||
"dolphin" ICON "..\\..\\..\\Installer\\Dolphin.ico"
|
|
||||||
|
|
||||||
|
|
|
@ -1,10 +1,11 @@
|
||||||
// Copyright 2015 Dolphin Emulator Project
|
// Copyright 2015 Dolphin Emulator Project
|
||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
|
#include "Common/ScopeGuard.h"
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
#include <QCoreApplication>
|
#include <QCoreApplication>
|
||||||
#include <shlobj.h>
|
#include <shlobj.h>
|
||||||
#include <wil/com.h>
|
#include <wrl/client.h>
|
||||||
|
|
||||||
// This file uses some identifiers which are defined as macros in Windows headers.
|
// This file uses some identifiers which are defined as macros in Windows headers.
|
||||||
// Include and undefine the macros first thing we do to solve build errors.
|
// Include and undefine the macros first thing we do to solve build errors.
|
||||||
|
@ -785,9 +786,12 @@ void GameList::OpenGCSaveFolder()
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
bool GameList::AddShortcutToDesktop()
|
bool GameList::AddShortcutToDesktop()
|
||||||
{
|
{
|
||||||
auto init = wil::CoInitializeEx_failfast(COINIT_APARTMENTTHREADED);
|
if (FAILED(CoInitializeEx(NULL, COINIT_APARTMENTTHREADED)))
|
||||||
auto shell_link = wil::CoCreateInstanceNoThrow<ShellLink, IShellLink>();
|
return false;
|
||||||
if (!shell_link)
|
Common::ScopeGuard init_guard([] { CoUninitialize(); });
|
||||||
|
Microsoft::WRL::ComPtr<IShellLink> shell_link;
|
||||||
|
if (FAILED(
|
||||||
|
CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&shell_link))))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
std::wstring dolphin_path = QCoreApplication::applicationFilePath().toStdWString();
|
std::wstring dolphin_path = QCoreApplication::applicationFilePath().toStdWString();
|
||||||
|
@ -800,7 +804,8 @@ bool GameList::AddShortcutToDesktop()
|
||||||
if (FAILED(shell_link->SetArguments(args.c_str())))
|
if (FAILED(shell_link->SetArguments(args.c_str())))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
wil::unique_cotaskmem_string desktop;
|
PWSTR desktop;
|
||||||
|
Common::ScopeGuard desktop_guard([&] { CoTaskMemFree(desktop); });
|
||||||
if (FAILED(SHGetKnownFolderPath(FOLDERID_Desktop, KF_FLAG_NO_ALIAS, nullptr, &desktop)))
|
if (FAILED(SHGetKnownFolderPath(FOLDERID_Desktop, KF_FLAG_NO_ALIAS, nullptr, &desktop)))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
@ -811,8 +816,9 @@ bool GameList::AddShortcutToDesktop()
|
||||||
return Common::Contains(illegal_characters, ch);
|
return Common::Contains(illegal_characters, ch);
|
||||||
});
|
});
|
||||||
|
|
||||||
std::wstring desktop_path = std::wstring(desktop.get()) + UTF8ToTStr("\\" + game_name + ".lnk");
|
std::wstring desktop_path = std::wstring(desktop) + UTF8ToTStr("\\" + game_name + ".lnk");
|
||||||
auto persist_file = shell_link.try_query<IPersistFile>();
|
Microsoft::WRL::ComPtr<IPersistFile> persist_file;
|
||||||
|
shell_link.As(&persist_file);
|
||||||
if (!persist_file)
|
if (!persist_file)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
|
|
@ -21,6 +21,9 @@
|
||||||
#include "UICommon/GameFile.h"
|
#include "UICommon/GameFile.h"
|
||||||
#include "UICommon/UICommon.h"
|
#include "UICommon/UICommon.h"
|
||||||
|
|
||||||
|
#pragma push_macro("RemoveDirectory")
|
||||||
|
#undef RemoveDirectory
|
||||||
|
|
||||||
const QSize GAMECUBE_BANNER_SIZE(96, 32);
|
const QSize GAMECUBE_BANNER_SIZE(96, 32);
|
||||||
|
|
||||||
GameListModel::GameListModel(QObject* parent) : QAbstractTableModel(parent)
|
GameListModel::GameListModel(QObject* parent) : QAbstractTableModel(parent)
|
||||||
|
@ -515,3 +518,5 @@ void GameListModel::OnEmulationStateChanged(Core::State state)
|
||||||
m_timer.Reload();
|
m_timer.Reload();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#pragma pop_macro("RemoveDirectory")
|
||||||
|
|
|
@ -20,6 +20,9 @@
|
||||||
|
|
||||||
#include "UICommon/GameFile.h"
|
#include "UICommon/GameFile.h"
|
||||||
|
|
||||||
|
#pragma push_macro("RemoveDirectory")
|
||||||
|
#undef RemoveDirectory
|
||||||
|
|
||||||
// NOTE: Qt likes to be case-sensitive here even though it shouldn't be thus this ugly regex hack
|
// NOTE: Qt likes to be case-sensitive here even though it shouldn't be thus this ugly regex hack
|
||||||
static const QStringList game_filters{
|
static const QStringList game_filters{
|
||||||
QStringLiteral("*.[gG][cC][mM]"), QStringLiteral("*.[bB][iI][nN]"),
|
QStringLiteral("*.[gG][cC][mM]"), QStringLiteral("*.[bB][iI][nN]"),
|
||||||
|
@ -369,3 +372,5 @@ void GameTracker::PurgeCache()
|
||||||
m_needs_purge = true;
|
m_needs_purge = true;
|
||||||
Settings::Instance().RefreshGameList();
|
Settings::Instance().RefreshGameList();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#pragma pop_macro("RemoveDirectory")
|
||||||
|
|
|
@ -17,6 +17,9 @@
|
||||||
#include "Common/WorkQueueThread.h"
|
#include "Common/WorkQueueThread.h"
|
||||||
#include "UICommon/GameFileCache.h"
|
#include "UICommon/GameFileCache.h"
|
||||||
|
|
||||||
|
#pragma push_macro("RemoveDirectory")
|
||||||
|
#undef RemoveDirectory
|
||||||
|
|
||||||
namespace UICommon
|
namespace UICommon
|
||||||
{
|
{
|
||||||
class GameFile;
|
class GameFile;
|
||||||
|
@ -100,3 +103,5 @@ private:
|
||||||
|
|
||||||
Q_DECLARE_METATYPE(std::shared_ptr<const UICommon::GameFile>)
|
Q_DECLARE_METATYPE(std::shared_ptr<const UICommon::GameFile>)
|
||||||
Q_DECLARE_METATYPE(std::string)
|
Q_DECLARE_METATYPE(std::string)
|
||||||
|
|
||||||
|
#pragma pop_macro("RemoveDirectory")
|
||||||
|
|
|
@ -110,10 +110,6 @@ static bool QtMsgAlertHandler(const char* caption, const char* text, bool yes_no
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef _WIN32
|
|
||||||
#define main app_main
|
|
||||||
#endif
|
|
||||||
|
|
||||||
int main(int argc, char* argv[])
|
int main(int argc, char* argv[])
|
||||||
{
|
{
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
|
@ -320,5 +316,4 @@ int WINAPI wWinMain(_In_ HINSTANCE, _In_opt_ HINSTANCE, _In_ LPWSTR, _In_ int)
|
||||||
return main(argc, argv.data());
|
return main(argc, argv.data());
|
||||||
}
|
}
|
||||||
|
|
||||||
#undef main
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -1196,7 +1196,7 @@ void MainWindow::SetFullScreenResolution(bool fullscreen)
|
||||||
DEVMODE screen_settings;
|
DEVMODE screen_settings;
|
||||||
memset(&screen_settings, 0, sizeof(screen_settings));
|
memset(&screen_settings, 0, sizeof(screen_settings));
|
||||||
screen_settings.dmSize = sizeof(screen_settings);
|
screen_settings.dmSize = sizeof(screen_settings);
|
||||||
sscanf(Config::Get(Config::MAIN_FULLSCREEN_DISPLAY_RES).c_str(), "%dx%d",
|
sscanf(Config::Get(Config::MAIN_FULLSCREEN_DISPLAY_RES).c_str(), "%lux%lu",
|
||||||
&screen_settings.dmPelsWidth, &screen_settings.dmPelsHeight);
|
&screen_settings.dmPelsWidth, &screen_settings.dmPelsHeight);
|
||||||
screen_settings.dmBitsPerPel = 32;
|
screen_settings.dmBitsPerPel = 32;
|
||||||
screen_settings.dmFields = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT;
|
screen_settings.dmFields = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT;
|
||||||
|
|
|
@ -237,7 +237,7 @@ void AudioPane::OnBackendChanged()
|
||||||
m_latency_slider->setEnabled(AudioCommon::SupportsLatencyControl(backend));
|
m_latency_slider->setEnabled(AudioCommon::SupportsLatencyControl(backend));
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _MSC_VER
|
||||||
bool is_wasapi = backend == BACKEND_WASAPI;
|
bool is_wasapi = backend == BACKEND_WASAPI;
|
||||||
m_wasapi_device_label->setHidden(!is_wasapi);
|
m_wasapi_device_label->setHidden(!is_wasapi);
|
||||||
m_wasapi_device_combo->setHidden(!is_wasapi);
|
m_wasapi_device_combo->setHidden(!is_wasapi);
|
||||||
|
|
|
@ -21,6 +21,10 @@ PRIVATE
|
||||||
fmt::fmt
|
fmt::fmt
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if(WIN32)
|
||||||
|
target_link_options(dolphin-tool PRIVATE -municode)
|
||||||
|
endif()
|
||||||
|
|
||||||
if(MSVC)
|
if(MSVC)
|
||||||
# Add precompiled header
|
# Add precompiled header
|
||||||
target_link_libraries(dolphin-tool PRIVATE use_pch)
|
target_link_libraries(dolphin-tool PRIVATE use_pch)
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
// Microsoft Visual C++ generated resource script.
|
// Microsoft Visual C++ generated resource script.
|
||||||
//
|
//
|
||||||
#include "resource.h"
|
#include "resource.h"
|
||||||
IDI_ICON1 ICON "..\\..\\..\\Installer\\Dolphin.ico"
|
IDI_ICON1 ICON "..\\..\\..\\Installer\\Dolphin.ico"
|
||||||
"dolphin" ICON "..\\..\\..\\Installer\\Dolphin.ico"
|
"dolphin" ICON "..\\..\\..\\Installer\\Dolphin.ico"
|
||||||
|
|
||||||
|
|
|
@ -19,6 +19,10 @@
|
||||||
#include "DolphinTool/HeaderCommand.h"
|
#include "DolphinTool/HeaderCommand.h"
|
||||||
#include "DolphinTool/VerifyCommand.h"
|
#include "DolphinTool/VerifyCommand.h"
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
#include <windows.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
static void PrintUsage()
|
static void PrintUsage()
|
||||||
{
|
{
|
||||||
fmt::print(std::cerr, "usage: dolphin-tool COMMAND -h\n"
|
fmt::print(std::cerr, "usage: dolphin-tool COMMAND -h\n"
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
add_library(inputcommon
|
add_library(inputcommon STATIC
|
||||||
DynamicInputTextureManager.cpp
|
DynamicInputTextureManager.cpp
|
||||||
DynamicInputTextureManager.h
|
DynamicInputTextureManager.h
|
||||||
GCAdapter.cpp
|
GCAdapter.cpp
|
||||||
|
@ -101,13 +101,19 @@ if(WIN32)
|
||||||
ControllerInterface/DInput/XInputFilter.h
|
ControllerInterface/DInput/XInputFilter.h
|
||||||
ControllerInterface/Win32/Win32.cpp
|
ControllerInterface/Win32/Win32.cpp
|
||||||
ControllerInterface/Win32/Win32.h
|
ControllerInterface/Win32/Win32.h
|
||||||
ControllerInterface/WGInput/WGInput.cpp
|
|
||||||
ControllerInterface/WGInput/WGInput.h
|
|
||||||
ControllerInterface/XInput/XInput.cpp
|
ControllerInterface/XInput/XInput.cpp
|
||||||
ControllerInterface/XInput/XInput.h
|
ControllerInterface/XInput/XInput.h
|
||||||
ControllerInterface/ForceFeedback/ForceFeedbackDevice.cpp
|
ControllerInterface/ForceFeedback/ForceFeedbackDevice.cpp
|
||||||
ControllerInterface/ForceFeedback/ForceFeedbackDevice.h
|
ControllerInterface/ForceFeedback/ForceFeedbackDevice.h
|
||||||
)
|
)
|
||||||
|
target_compile_definitions(inputcommon PRIVATE WINVER=0x0602)
|
||||||
|
if(MSVC)
|
||||||
|
target_sources(inputcommon PRIVATE
|
||||||
|
ControllerInterface/WGInput/WGInput.cpp
|
||||||
|
ControllerInterface/WGInput/WGInput.h
|
||||||
|
)
|
||||||
|
endif()
|
||||||
|
target_link_libraries(inputcommon PUBLIC cfgmgr32 dinput8 dinput)
|
||||||
elseif(APPLE)
|
elseif(APPLE)
|
||||||
target_sources(inputcommon PRIVATE
|
target_sources(inputcommon PRIVATE
|
||||||
ControllerInterface/Quartz/Quartz.h
|
ControllerInterface/Quartz/Quartz.h
|
||||||
|
|
|
@ -11,8 +11,10 @@
|
||||||
#include "InputCommon/ControllerInterface/DInput/DInputJoystick.h"
|
#include "InputCommon/ControllerInterface/DInput/DInputJoystick.h"
|
||||||
#include "InputCommon/ControllerInterface/DInput/DInputKeyboardMouse.h"
|
#include "InputCommon/ControllerInterface/DInput/DInputKeyboardMouse.h"
|
||||||
|
|
||||||
|
#ifdef _MSC_VER
|
||||||
#pragma comment(lib, "Dinput8.lib")
|
#pragma comment(lib, "Dinput8.lib")
|
||||||
#pragma comment(lib, "dxguid.lib")
|
#pragma comment(lib, "dxguid.lib")
|
||||||
|
#endif
|
||||||
|
|
||||||
namespace ciface::DInput
|
namespace ciface::DInput
|
||||||
{
|
{
|
||||||
|
|
|
@ -45,7 +45,7 @@ private:
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Hat(u8 index, const DWORD& hat, u8 direction)
|
Hat(u8 index, const DWORD& hat, u8 direction)
|
||||||
: m_hat(hat), m_direction(direction), m_index(index)
|
: m_hat(hat), m_index(index), m_direction(direction)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
std::string GetName() const override;
|
std::string GetName() const override;
|
||||||
|
|
|
@ -18,7 +18,9 @@
|
||||||
#include "InputCommon/ControllerInterface/WGInput/WGInput.h"
|
#include "InputCommon/ControllerInterface/WGInput/WGInput.h"
|
||||||
#include "InputCommon/ControllerInterface/XInput/XInput.h"
|
#include "InputCommon/ControllerInterface/XInput/XInput.h"
|
||||||
|
|
||||||
|
#ifdef _MSC_VER
|
||||||
#pragma comment(lib, "OneCoreUAP.Lib")
|
#pragma comment(lib, "OneCoreUAP.Lib")
|
||||||
|
#endif
|
||||||
|
|
||||||
static std::mutex s_populate_mutex;
|
static std::mutex s_populate_mutex;
|
||||||
// TODO is this really needed?
|
// TODO is this really needed?
|
||||||
|
@ -81,7 +83,9 @@ InputBackend::InputBackend(ControllerInterface* controller_interface)
|
||||||
: ciface::InputBackend(controller_interface)
|
: ciface::InputBackend(controller_interface)
|
||||||
{
|
{
|
||||||
XInput::Init();
|
XInput::Init();
|
||||||
|
#ifdef _MSC_VER
|
||||||
WGInput::Init();
|
WGInput::Init();
|
||||||
|
#endif
|
||||||
|
|
||||||
CM_NOTIFY_FILTER notify_filter{.cbSize = sizeof(notify_filter),
|
CM_NOTIFY_FILTER notify_filter{.cbSize = sizeof(notify_filter),
|
||||||
.FilterType = CM_NOTIFY_FILTER_TYPE_DEVICEINTERFACE,
|
.FilterType = CM_NOTIFY_FILTER_TYPE_DEVICEINTERFACE,
|
||||||
|
@ -100,7 +104,9 @@ void InputBackend::PopulateDevices()
|
||||||
s_first_populate_devices_asked.Set();
|
s_first_populate_devices_asked.Set();
|
||||||
ciface::DInput::PopulateDevices(GetHWND());
|
ciface::DInput::PopulateDevices(GetHWND());
|
||||||
ciface::XInput::PopulateDevices();
|
ciface::XInput::PopulateDevices();
|
||||||
|
#ifdef _MSC_VER
|
||||||
ciface::WGInput::PopulateDevices();
|
ciface::WGInput::PopulateDevices();
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void InputBackend::HandleWindowChange()
|
void InputBackend::HandleWindowChange()
|
||||||
|
@ -125,7 +131,9 @@ InputBackend::~InputBackend()
|
||||||
}
|
}
|
||||||
|
|
||||||
XInput::DeInit();
|
XInput::DeInit();
|
||||||
|
#ifdef _MSC_VER
|
||||||
WGInput::DeInit();
|
WGInput::DeInit();
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace ciface::Win32
|
} // namespace ciface::Win32
|
||||||
|
|
|
@ -7,6 +7,10 @@
|
||||||
#define XINPUT_GAMEPAD_GUIDE 0x0400
|
#define XINPUT_GAMEPAD_GUIDE 0x0400
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifndef XINPUT_DLL
|
||||||
|
#define XINPUT_DLL L"xinput1_4.dll"
|
||||||
|
#endif
|
||||||
|
|
||||||
namespace ciface::XInput
|
namespace ciface::XInput
|
||||||
{
|
{
|
||||||
struct ButtonDef
|
struct ButtonDef
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
|
|
||||||
#include "InputCommon/ControllerInterface/ControllerInterface.h"
|
#include "InputCommon/ControllerInterface/ControllerInterface.h"
|
||||||
|
|
||||||
#ifndef XINPUT_DEVSUBTYPE_FLIGHT_STICK
|
#if !defined(XINPUT_DEVSUBTYPE_FLIGHT_STICK) && !defined(__MINGW32__)
|
||||||
#error You are building this module against the wrong version of DirectX. You probably need to remove DXSDK_DIR from your include path and/or _WIN32_WINNT is wrong.
|
#error You are building this module against the wrong version of DirectX. You probably need to remove DXSDK_DIR from your include path and/or _WIN32_WINNT is wrong.
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <cstdint>
|
||||||
#include <functional>
|
#include <functional>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
|
|
|
@ -10,10 +10,10 @@
|
||||||
#include <locale>
|
#include <locale>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
#include "Common/ScopeGuard.h"
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
#include <shlobj.h> // for SHGetFolderPath
|
#include <shlobj.h> // for SHGetFolderPath
|
||||||
|
|
||||||
#include <wil/resource.h>
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <fmt/format.h>
|
#include <fmt/format.h>
|
||||||
|
@ -204,13 +204,15 @@ void SetLocale(std::string locale_name)
|
||||||
const std::string& adjusted_locale = locale;
|
const std::string& adjusted_locale = locale;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// setlocale sets the C locale, and global sets the C and C++ locales, so the call to setlocale
|
// setlocale sets the C locale, and global sets the C and C++ locales, so the call to
|
||||||
// would be redundant if it wasn't for not having any other good way to check whether
|
// setlocale would be redundant if it wasn't for not having any other good way to check
|
||||||
// the locale name is valid. (Constructing a std::locale object for an unsupported
|
// whether the locale name is valid. (Constructing a std::locale object for an unsupported
|
||||||
// locale name throws std::runtime_error, and exception handling is disabled in Dolphin.)
|
// locale name throws std::runtime_error, and exception handling is disabled in Dolphin.)
|
||||||
|
#ifndef __MINGW32__
|
||||||
if (!std::setlocale(LC_ALL, adjusted_locale.c_str()))
|
if (!std::setlocale(LC_ALL, adjusted_locale.c_str()))
|
||||||
return false;
|
return false;
|
||||||
std::locale::global(std::locale(adjusted_locale));
|
std::locale::global(std::locale(adjusted_locale));
|
||||||
|
#endif
|
||||||
return true;
|
return true;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -315,29 +317,32 @@ void SetUserDirectory(std::string custom_path)
|
||||||
// -> Use GetExeDirectory()\User
|
// -> Use GetExeDirectory()\User
|
||||||
|
|
||||||
// Get AppData path in case we need it.
|
// Get AppData path in case we need it.
|
||||||
wil::unique_cotaskmem_string appdata;
|
PWSTR appdata;
|
||||||
bool appdata_found = SUCCEEDED(
|
Common::ScopeGuard appdata_guard([&] { CoTaskMemFree(appdata); });
|
||||||
SHGetKnownFolderPath(FOLDERID_RoamingAppData, KF_FLAG_DEFAULT, nullptr, appdata.put()));
|
bool appdata_found =
|
||||||
|
SUCCEEDED(SHGetKnownFolderPath(FOLDERID_RoamingAppData, KF_FLAG_DEFAULT, nullptr, &appdata));
|
||||||
|
|
||||||
// Check our registry keys
|
// Check our registry keys
|
||||||
wil::unique_hkey hkey;
|
HKEY hkey;
|
||||||
|
Common::ScopeGuard hkey_guard([&] { RegCloseKey(hkey); });
|
||||||
DWORD local = 0;
|
DWORD local = 0;
|
||||||
std::unique_ptr<TCHAR[]> configPath;
|
std::unique_ptr<TCHAR[]> configPath;
|
||||||
if (RegOpenKeyEx(HKEY_CURRENT_USER, TEXT("Software\\Dolphin Emulator"), 0, KEY_QUERY_VALUE,
|
if (SUCCEEDED(RegOpenKeyEx(HKEY_CURRENT_USER, TEXT("Software\\Dolphin Emulator"), 0,
|
||||||
hkey.put()) == ERROR_SUCCESS)
|
KEY_QUERY_VALUE, &hkey)))
|
||||||
{
|
{
|
||||||
|
Common::ScopeGuard local_user_config_hkey_guard([&] { RegCloseKey(hkey); });
|
||||||
DWORD size = sizeof(local);
|
DWORD size = sizeof(local);
|
||||||
if (RegQueryValueEx(hkey.get(), TEXT("LocalUserConfig"), nullptr, nullptr,
|
if (SUCCEEDED(RegQueryValueEx(hkey, TEXT("LocalUserConfig"), nullptr, nullptr,
|
||||||
reinterpret_cast<LPBYTE>(&local), &size) != ERROR_SUCCESS)
|
reinterpret_cast<LPBYTE>(&local), &size)))
|
||||||
{
|
{
|
||||||
local = 0;
|
local = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
size = 0;
|
size = 0;
|
||||||
RegQueryValueEx(hkey.get(), TEXT("UserConfigPath"), nullptr, nullptr, nullptr, &size);
|
RegQueryValueEx(hkey, TEXT("UserConfigPath"), nullptr, nullptr, nullptr, &size);
|
||||||
configPath = std::make_unique<TCHAR[]>(size / sizeof(TCHAR));
|
configPath = std::make_unique<TCHAR[]>(size / sizeof(TCHAR));
|
||||||
if (RegQueryValueEx(hkey.get(), TEXT("UserConfigPath"), nullptr, nullptr,
|
if (SUCCEEDED(RegQueryValueEx(hkey, TEXT("UserConfigPath"), nullptr, nullptr,
|
||||||
reinterpret_cast<LPBYTE>(configPath.get()), &size) != ERROR_SUCCESS)
|
reinterpret_cast<LPBYTE>(configPath.get()), &size)))
|
||||||
{
|
{
|
||||||
configPath.reset();
|
configPath.reset();
|
||||||
}
|
}
|
||||||
|
@ -346,14 +351,15 @@ void SetUserDirectory(std::string custom_path)
|
||||||
local = local != 0 || File::Exists(File::GetExeDirectory() + DIR_SEP "portable.txt");
|
local = local != 0 || File::Exists(File::GetExeDirectory() + DIR_SEP "portable.txt");
|
||||||
|
|
||||||
// Attempt to check if the old User directory exists in Documents.
|
// Attempt to check if the old User directory exists in Documents.
|
||||||
wil::unique_cotaskmem_string documents;
|
PWSTR documents;
|
||||||
bool documents_found = SUCCEEDED(
|
Common::ScopeGuard documents_guard([&] { CoTaskMemFree(documents); });
|
||||||
SHGetKnownFolderPath(FOLDERID_Documents, KF_FLAG_DEFAULT, nullptr, documents.put()));
|
bool documents_found =
|
||||||
|
SUCCEEDED(SHGetKnownFolderPath(FOLDERID_Documents, KF_FLAG_DEFAULT, nullptr, &documents));
|
||||||
|
|
||||||
std::optional<std::string> old_user_folder;
|
std::optional<std::string> old_user_folder;
|
||||||
if (documents_found)
|
if (documents_found)
|
||||||
{
|
{
|
||||||
old_user_folder = TStrToUTF8(documents.get()) + DIR_SEP NORMAL_USER_DIR DIR_SEP;
|
old_user_folder = TStrToUTF8(documents) + DIR_SEP NORMAL_USER_DIR DIR_SEP;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (local) // Case 1-2
|
if (local) // Case 1-2
|
||||||
|
@ -370,7 +376,7 @@ void SetUserDirectory(std::string custom_path)
|
||||||
}
|
}
|
||||||
else if (appdata_found) // Case 5
|
else if (appdata_found) // Case 5
|
||||||
{
|
{
|
||||||
user_path = TStrToUTF8(appdata.get()) + DIR_SEP NORMAL_USER_DIR DIR_SEP;
|
user_path = TStrToUTF8(appdata) + DIR_SEP NORMAL_USER_DIR DIR_SEP;
|
||||||
|
|
||||||
// Set the UserConfigPath value in the registry for backwards compatibility with older Dolphin
|
// Set the UserConfigPath value in the registry for backwards compatibility with older Dolphin
|
||||||
// builds, which will look for the default User directory in Documents. If we set this key,
|
// builds, which will look for the default User directory in Documents. If we set this key,
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
add_library(videod3d
|
add_library(videod3d STATIC
|
||||||
D3DBase.cpp
|
D3DBase.cpp
|
||||||
D3DBase.h
|
D3DBase.h
|
||||||
D3DBoundingBox.cpp
|
D3DBoundingBox.cpp
|
||||||
|
|
|
@ -153,7 +153,7 @@ void Destroy()
|
||||||
{
|
{
|
||||||
// print out alive objects, but only if we actually have pending references
|
// print out alive objects, but only if we actually have pending references
|
||||||
// note this will also print out internal live objects to the debug console
|
// note this will also print out internal live objects to the debug console
|
||||||
s_debug->ReportLiveDeviceObjects(D3D11_RLDO_SUMMARY | D3D11_RLDO_DETAIL);
|
s_debug->ReportLiveDeviceObjects(D3D11_RLDO_FLAGS(D3D11_RLDO_SUMMARY | D3D11_RLDO_DETAIL));
|
||||||
}
|
}
|
||||||
s_debug.Reset();
|
s_debug.Reset();
|
||||||
}
|
}
|
||||||
|
|
|
@ -90,7 +90,7 @@ std::vector<BBoxType> D3DBoundingBox::Read(u32 index, u32 length)
|
||||||
|
|
||||||
void D3DBoundingBox::Write(u32 index, std::span<const BBoxType> values)
|
void D3DBoundingBox::Write(u32 index, std::span<const BBoxType> values)
|
||||||
{
|
{
|
||||||
D3D11_BOX box{index * sizeof(BBoxType),
|
D3D11_BOX box{static_cast<u32>(index * sizeof(BBoxType)),
|
||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
static_cast<u32>((index + values.size()) * sizeof(BBoxType)),
|
static_cast<u32>((index + values.size()) * sizeof(BBoxType)),
|
||||||
|
|
|
@ -124,8 +124,11 @@ void Gfx::SetPipeline(const AbstractPipeline* pipeline)
|
||||||
void Gfx::SetScissorRect(const MathUtil::Rectangle<int>& rc)
|
void Gfx::SetScissorRect(const MathUtil::Rectangle<int>& rc)
|
||||||
{
|
{
|
||||||
// TODO: Move to stateman
|
// TODO: Move to stateman
|
||||||
const CD3D11_RECT rect(rc.left, rc.top, std::max(rc.right, rc.left + 1),
|
D3D11_RECT rect;
|
||||||
std::max(rc.bottom, rc.top + 1));
|
rect.left = rc.left;
|
||||||
|
rect.top = rc.top;
|
||||||
|
rect.left = std::max(rc.right, rc.left + 1);
|
||||||
|
rect.bottom = std::max(rc.bottom, rc.top + 1);
|
||||||
D3D::context->RSSetScissorRects(1, &rect);
|
D3D::context->RSSetScissorRects(1, &rect);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -133,7 +136,13 @@ void Gfx::SetViewport(float x, float y, float width, float height, float near_de
|
||||||
float far_depth)
|
float far_depth)
|
||||||
{
|
{
|
||||||
// TODO: Move to stateman
|
// TODO: Move to stateman
|
||||||
const CD3D11_VIEWPORT vp(x, y, width, height, near_depth, far_depth);
|
D3D11_VIEWPORT vp;
|
||||||
|
vp.TopLeftX = x;
|
||||||
|
vp.TopLeftY = y;
|
||||||
|
vp.Width = width;
|
||||||
|
vp.Height = height;
|
||||||
|
vp.MinDepth = near_depth;
|
||||||
|
vp.MaxDepth = far_depth;
|
||||||
D3D::context->RSSetViewports(1, &vp);
|
D3D::context->RSSetViewports(1, &vp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -15,8 +15,6 @@
|
||||||
|
|
||||||
namespace DX11
|
namespace DX11
|
||||||
{
|
{
|
||||||
std::mutex s_input_layout_lock;
|
|
||||||
|
|
||||||
std::unique_ptr<NativeVertexFormat>
|
std::unique_ptr<NativeVertexFormat>
|
||||||
Gfx::CreateNativeVertexFormat(const PortableVertexDeclaration& vtx_decl)
|
Gfx::CreateNativeVertexFormat(const PortableVertexDeclaration& vtx_decl)
|
||||||
{
|
{
|
||||||
|
|
|
@ -59,9 +59,14 @@ static ComPtr<ID3D11ShaderResourceView>
|
||||||
CreateTexelBufferView(ID3D11Buffer* buffer, TexelBufferFormat format, DXGI_FORMAT srv_format)
|
CreateTexelBufferView(ID3D11Buffer* buffer, TexelBufferFormat format, DXGI_FORMAT srv_format)
|
||||||
{
|
{
|
||||||
ComPtr<ID3D11ShaderResourceView> srv;
|
ComPtr<ID3D11ShaderResourceView> srv;
|
||||||
CD3D11_SHADER_RESOURCE_VIEW_DESC srv_desc(buffer, srv_format, 0,
|
D3D11_SHADER_RESOURCE_VIEW_DESC srv_desc;
|
||||||
VertexManager::TEXEL_STREAM_BUFFER_SIZE /
|
srv_desc.Format = srv_format;
|
||||||
VertexManager::GetTexelBufferElementSize(format));
|
srv_desc.ViewDimension = D3D11_SRV_DIMENSION_BUFFEREX;
|
||||||
|
srv_desc.BufferEx.FirstElement = 0;
|
||||||
|
srv_desc.BufferEx.NumElements =
|
||||||
|
VertexManager::TEXEL_STREAM_BUFFER_SIZE / VertexManager::GetTexelBufferElementSize(format);
|
||||||
|
srv_desc.BufferEx.Flags = 0;
|
||||||
|
|
||||||
HRESULT hr = D3D::device->CreateShaderResourceView(buffer, &srv_desc, &srv);
|
HRESULT hr = D3D::device->CreateShaderResourceView(buffer, &srv_desc, &srv);
|
||||||
ASSERT_MSG(VIDEO, SUCCEEDED(hr), "Failed to create SRV for texel buffer: {}", DX11HRWrap(hr));
|
ASSERT_MSG(VIDEO, SUCCEEDED(hr), "Failed to create SRV for texel buffer: {}", DX11HRWrap(hr));
|
||||||
return srv;
|
return srv;
|
||||||
|
@ -80,7 +85,7 @@ bool VertexManager::Initialize()
|
||||||
D3D11_BIND_INDEX_BUFFER | D3D11_BIND_VERTEX_BUFFER,
|
D3D11_BIND_INDEX_BUFFER | D3D11_BIND_VERTEX_BUFFER,
|
||||||
D3D11_USAGE_DYNAMIC, D3D11_CPU_ACCESS_WRITE);
|
D3D11_USAGE_DYNAMIC, D3D11_CPU_ACCESS_WRITE);
|
||||||
|
|
||||||
for (int i = 0; i < BUFFER_COUNT; i++)
|
for (u32 i = 0; i < BUFFER_COUNT; i++)
|
||||||
{
|
{
|
||||||
HRESULT hr = D3D::device->CreateBuffer(&bufdesc, nullptr, &m_buffers[i]);
|
HRESULT hr = D3D::device->CreateBuffer(&bufdesc, nullptr, &m_buffers[i]);
|
||||||
ASSERT_MSG(VIDEO, SUCCEEDED(hr), "Failed to create buffer: {}", DX11HRWrap(hr));
|
ASSERT_MSG(VIDEO, SUCCEEDED(hr), "Failed to create buffer: {}", DX11HRWrap(hr));
|
||||||
|
|
|
@ -38,7 +38,7 @@ public:
|
||||||
VertexManager();
|
VertexManager();
|
||||||
~VertexManager();
|
~VertexManager();
|
||||||
|
|
||||||
bool Initialize();
|
bool Initialize() override;
|
||||||
|
|
||||||
void UploadUtilityUniforms(const void* uniforms, u32 uniforms_size) override;
|
void UploadUtilityUniforms(const void* uniforms, u32 uniforms_size) override;
|
||||||
bool UploadTexelBuffer(const void* data, u32 data_size, TexelBufferFormat format,
|
bool UploadTexelBuffer(const void* data, u32 data_size, TexelBufferFormat format,
|
||||||
|
|
|
@ -116,8 +116,8 @@ bool DXTexture::CreateSRV()
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
const CD3D11_SHADER_RESOURCE_VIEW_DESC desc(
|
const CD3D11_SHADER_RESOURCE_VIEW_DESC desc(
|
||||||
m_texture.Get(), dimension, D3DCommon::GetSRVFormatForAbstractFormat(m_config.format), 0,
|
dimension, D3DCommon::GetSRVFormatForAbstractFormat(m_config.format), 0, m_config.levels, 0,
|
||||||
m_config.levels, 0, m_config.layers);
|
m_config.layers);
|
||||||
DEBUG_ASSERT(!m_srv);
|
DEBUG_ASSERT(!m_srv);
|
||||||
HRESULT hr = D3D::device->CreateShaderResourceView(m_texture.Get(), &desc, m_srv.GetAddressOf());
|
HRESULT hr = D3D::device->CreateShaderResourceView(m_texture.Get(), &desc, m_srv.GetAddressOf());
|
||||||
if (FAILED(hr))
|
if (FAILED(hr))
|
||||||
|
@ -132,9 +132,12 @@ bool DXTexture::CreateSRV()
|
||||||
|
|
||||||
bool DXTexture::CreateUAV()
|
bool DXTexture::CreateUAV()
|
||||||
{
|
{
|
||||||
const CD3D11_UNORDERED_ACCESS_VIEW_DESC desc(
|
D3D11_UNORDERED_ACCESS_VIEW_DESC desc;
|
||||||
m_texture.Get(), D3D11_UAV_DIMENSION_TEXTURE2DARRAY,
|
desc.ViewDimension = D3D11_UAV_DIMENSION_TEXTURE2DARRAY;
|
||||||
D3DCommon::GetSRVFormatForAbstractFormat(m_config.format), 0, 0, m_config.layers);
|
desc.Format = D3DCommon::GetSRVFormatForAbstractFormat(m_config.format);
|
||||||
|
desc.Texture2DArray.MipSlice = 0;
|
||||||
|
desc.Texture2DArray.FirstArraySlice = 0;
|
||||||
|
desc.Texture2DArray.ArraySize = m_config.layers;
|
||||||
DEBUG_ASSERT(!m_uav);
|
DEBUG_ASSERT(!m_uav);
|
||||||
HRESULT hr = D3D::device->CreateUnorderedAccessView(m_texture.Get(), &desc, m_uav.GetAddressOf());
|
HRESULT hr = D3D::device->CreateUnorderedAccessView(m_texture.Get(), &desc, m_uav.GetAddressOf());
|
||||||
if (FAILED(hr))
|
if (FAILED(hr))
|
||||||
|
@ -264,7 +267,13 @@ void DXStagingTexture::CopyFromTexture(const AbstractTexture* src,
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
CD3D11_BOX src_box(src_rect.left, src_rect.top, 0, src_rect.right, src_rect.bottom, 1);
|
D3D11_BOX src_box;
|
||||||
|
src_box.left = src_rect.left;
|
||||||
|
src_box.top = src_rect.top;
|
||||||
|
src_box.front = 0;
|
||||||
|
src_box.right = src_rect.right;
|
||||||
|
src_box.bottom = src_rect.bottom;
|
||||||
|
src_box.back = 1;
|
||||||
D3D::context->CopySubresourceRegion(
|
D3D::context->CopySubresourceRegion(
|
||||||
m_tex.Get(), 0, static_cast<u32>(dst_rect.left), static_cast<u32>(dst_rect.top), 0,
|
m_tex.Get(), 0, static_cast<u32>(dst_rect.left), static_cast<u32>(dst_rect.top), 0,
|
||||||
static_cast<const DXTexture*>(src)->GetD3DTexture(),
|
static_cast<const DXTexture*>(src)->GetD3DTexture(),
|
||||||
|
@ -299,7 +308,13 @@ void DXStagingTexture::CopyToTexture(const MathUtil::Rectangle<int>& src_rect, A
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
CD3D11_BOX src_box(src_rect.left, src_rect.top, 0, src_rect.right, src_rect.bottom, 1);
|
D3D11_BOX src_box;
|
||||||
|
src_box.left = src_rect.left;
|
||||||
|
src_box.top = src_rect.top;
|
||||||
|
src_box.front = 0;
|
||||||
|
src_box.right = src_rect.right;
|
||||||
|
src_box.bottom = src_rect.bottom;
|
||||||
|
src_box.back = 1;
|
||||||
D3D::context->CopySubresourceRegion(
|
D3D::context->CopySubresourceRegion(
|
||||||
static_cast<const DXTexture*>(dst)->GetD3DTexture(),
|
static_cast<const DXTexture*>(dst)->GetD3DTexture(),
|
||||||
D3D11CalcSubresource(dst_level, dst_layer, dst->GetLevels()),
|
D3D11CalcSubresource(dst_level, dst_layer, dst->GetLevels()),
|
||||||
|
@ -484,11 +499,15 @@ DXFramebuffer::Create(DXTexture* color_attachment, DXTexture* depth_attachment,
|
||||||
ComPtr<ID3D11DepthStencilView> dsv;
|
ComPtr<ID3D11DepthStencilView> dsv;
|
||||||
if (depth_attachment)
|
if (depth_attachment)
|
||||||
{
|
{
|
||||||
const CD3D11_DEPTH_STENCIL_VIEW_DESC desc(
|
D3D11_DEPTH_STENCIL_VIEW_DESC desc;
|
||||||
depth_attachment->GetConfig().IsMultisampled() ? D3D11_DSV_DIMENSION_TEXTURE2DMSARRAY :
|
desc.ViewDimension = depth_attachment->GetConfig().IsMultisampled() ?
|
||||||
D3D11_DSV_DIMENSION_TEXTURE2DARRAY,
|
D3D11_DSV_DIMENSION_TEXTURE2DMSARRAY :
|
||||||
D3DCommon::GetDSVFormatForAbstractFormat(depth_attachment->GetFormat()), 0, 0,
|
D3D11_DSV_DIMENSION_TEXTURE2DARRAY;
|
||||||
depth_attachment->GetLayers(), 0);
|
desc.Format = D3DCommon::GetDSVFormatForAbstractFormat(depth_attachment->GetFormat());
|
||||||
|
desc.Texture2DArray.MipSlice = 0;
|
||||||
|
desc.Texture2DMSArray.ArraySize = depth_attachment->GetLayers();
|
||||||
|
desc.Texture2DMSArray.FirstArraySlice = 0;
|
||||||
|
desc.Flags = 0;
|
||||||
HRESULT hr = D3D::device->CreateDepthStencilView(depth_attachment->GetD3DTexture(), &desc,
|
HRESULT hr = D3D::device->CreateDepthStencilView(depth_attachment->GetD3DTexture(), &desc,
|
||||||
dsv.GetAddressOf());
|
dsv.GetAddressOf());
|
||||||
ASSERT_MSG(VIDEO, SUCCEEDED(hr), "Failed to create depth stencil view for framebuffer: {}",
|
ASSERT_MSG(VIDEO, SUCCEEDED(hr), "Failed to create depth stencil view for framebuffer: {}",
|
||||||
|
|
|
@ -12,8 +12,8 @@ namespace DX12
|
||||||
{
|
{
|
||||||
using Microsoft::WRL::ComPtr;
|
using Microsoft::WRL::ComPtr;
|
||||||
|
|
||||||
static void ResourceBarrier(ID3D12GraphicsCommandList* cmdlist, ID3D12Resource* resource,
|
static inline void ResourceBarrier(ID3D12GraphicsCommandList* cmdlist, ID3D12Resource* resource,
|
||||||
D3D12_RESOURCE_STATES from_state, D3D12_RESOURCE_STATES to_state)
|
D3D12_RESOURCE_STATES from_state, D3D12_RESOURCE_STATES to_state)
|
||||||
{
|
{
|
||||||
const D3D12_RESOURCE_BARRIER barrier = {
|
const D3D12_RESOURCE_BARRIER barrier = {
|
||||||
D3D12_RESOURCE_BARRIER_TYPE_TRANSITION,
|
D3D12_RESOURCE_BARRIER_TYPE_TRANSITION,
|
||||||
|
|
|
@ -3,15 +3,12 @@
|
||||||
|
|
||||||
#include "VideoBackends/D3D12/DX12Context.h"
|
#include "VideoBackends/D3D12/DX12Context.h"
|
||||||
|
|
||||||
#include <algorithm>
|
|
||||||
#include <array>
|
#include <array>
|
||||||
#include <dxgi1_6.h>
|
#include <dxgi1_6.h>
|
||||||
#include <queue>
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include "Common/Assert.h"
|
#include "Common/Assert.h"
|
||||||
#include "Common/DynamicLibrary.h"
|
#include "Common/DynamicLibrary.h"
|
||||||
#include "Common/StringUtil.h"
|
|
||||||
|
|
||||||
#include "VideoBackends/D3D12/Common.h"
|
#include "VideoBackends/D3D12/Common.h"
|
||||||
#include "VideoBackends/D3D12/D3D12StreamBuffer.h"
|
#include "VideoBackends/D3D12/D3D12StreamBuffer.h"
|
||||||
|
@ -88,8 +85,8 @@ std::vector<u32> DXContext::GetAAModes(u32 adapter_index)
|
||||||
|
|
||||||
bool DXContext::SupportsTextureFormat(DXGI_FORMAT format)
|
bool DXContext::SupportsTextureFormat(DXGI_FORMAT format)
|
||||||
{
|
{
|
||||||
constexpr u32 required = D3D12_FORMAT_SUPPORT1_TEXTURE2D | D3D12_FORMAT_SUPPORT1_TEXTURECUBE |
|
const u32 required = D3D12_FORMAT_SUPPORT1_TEXTURE2D | D3D12_FORMAT_SUPPORT1_TEXTURECUBE |
|
||||||
D3D12_FORMAT_SUPPORT1_SHADER_SAMPLE;
|
D3D12_FORMAT_SUPPORT1_SHADER_SAMPLE;
|
||||||
|
|
||||||
D3D12_FEATURE_DATA_FORMAT_SUPPORT support = {format};
|
D3D12_FEATURE_DATA_FORMAT_SUPPORT support = {format};
|
||||||
return SUCCEEDED(m_device->CheckFeatureSupport(D3D12_FEATURE_FORMAT_SUPPORT, &support,
|
return SUCCEEDED(m_device->CheckFeatureSupport(D3D12_FEATURE_FORMAT_SUPPORT, &support,
|
||||||
|
@ -445,14 +442,14 @@ bool DXContext::CreateCommandLists()
|
||||||
for (u32 i = 0; i < NUM_COMMAND_LISTS; i++)
|
for (u32 i = 0; i < NUM_COMMAND_LISTS; i++)
|
||||||
{
|
{
|
||||||
CommandListResources& res = m_command_lists[i];
|
CommandListResources& res = m_command_lists[i];
|
||||||
HRESULT hr = m_device->CreateCommandAllocator(
|
HRESULT hr = m_device->CreateCommandAllocator(D3D12_COMMAND_LIST_TYPE_DIRECT,
|
||||||
D3D12_COMMAND_LIST_TYPE_DIRECT, IID_PPV_ARGS(res.command_allocator.GetAddressOf()));
|
IID_PPV_ARGS(&res.command_allocator));
|
||||||
ASSERT_MSG(VIDEO, SUCCEEDED(hr), "Failed to create command allocator: {}", DX12HRWrap(hr));
|
ASSERT_MSG(VIDEO, SUCCEEDED(hr), "Failed to create command allocator: {}", DX12HRWrap(hr));
|
||||||
if (FAILED(hr))
|
if (FAILED(hr))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
hr = m_device->CreateCommandList(1, D3D12_COMMAND_LIST_TYPE_DIRECT, res.command_allocator.Get(),
|
hr = m_device->CreateCommandList(1, D3D12_COMMAND_LIST_TYPE_DIRECT, res.command_allocator.Get(),
|
||||||
nullptr, IID_PPV_ARGS(res.command_list.GetAddressOf()));
|
nullptr, IID_PPV_ARGS(&res.command_list));
|
||||||
ASSERT_MSG(VIDEO, SUCCEEDED(hr), "Failed to create command list: {}", DX12HRWrap(hr));
|
ASSERT_MSG(VIDEO, SUCCEEDED(hr), "Failed to create command list: {}", DX12HRWrap(hr));
|
||||||
if (FAILED(hr))
|
if (FAILED(hr))
|
||||||
{
|
{
|
||||||
|
|
|
@ -45,7 +45,7 @@ static ComPtr<ID3D12Resource> CreateTextureUploadBuffer(u32 buffer_size)
|
||||||
|
|
||||||
DXTexture::DXTexture(const TextureConfig& config, ID3D12Resource* resource,
|
DXTexture::DXTexture(const TextureConfig& config, ID3D12Resource* resource,
|
||||||
D3D12_RESOURCE_STATES state, std::string_view name)
|
D3D12_RESOURCE_STATES state, std::string_view name)
|
||||||
: AbstractTexture(config), m_resource(resource), m_state(state), m_name(UTF8ToWString(name))
|
: AbstractTexture(config), m_resource(resource), m_name(UTF8ToWString(name)), m_state(state)
|
||||||
{
|
{
|
||||||
if (!m_name.empty())
|
if (!m_name.empty())
|
||||||
{
|
{
|
||||||
|
@ -331,14 +331,16 @@ void DXTexture::Load(u32 level, u32 width, u32 height, u32 row_length, const u8*
|
||||||
// Issue copy from buffer->texture.
|
// Issue copy from buffer->texture.
|
||||||
const u32 aligned_width = Common::AlignUp(width, block_size);
|
const u32 aligned_width = Common::AlignUp(width, block_size);
|
||||||
const u32 aligned_height = Common::AlignUp(height, block_size);
|
const u32 aligned_height = Common::AlignUp(height, block_size);
|
||||||
const D3D12_TEXTURE_COPY_LOCATION dst_loc = {m_resource.Get(),
|
const D3D12_TEXTURE_COPY_LOCATION dst_loc = {
|
||||||
D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX,
|
m_resource.Get(),
|
||||||
{static_cast<UINT>(CalcSubresource(level, layer))}};
|
D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX,
|
||||||
|
{{static_cast<UINT>(CalcSubresource(level, layer))}}};
|
||||||
const D3D12_TEXTURE_COPY_LOCATION src_loc = {
|
const D3D12_TEXTURE_COPY_LOCATION src_loc = {
|
||||||
upload_buffer_resource,
|
upload_buffer_resource,
|
||||||
D3D12_TEXTURE_COPY_TYPE_PLACED_FOOTPRINT,
|
D3D12_TEXTURE_COPY_TYPE_PLACED_FOOTPRINT,
|
||||||
{{upload_buffer_offset, D3DCommon::GetDXGIFormatForAbstractFormat(m_config.format, false),
|
{{upload_buffer_offset,
|
||||||
aligned_width, aligned_height, 1, upload_stride}}};
|
{D3DCommon::GetDXGIFormatForAbstractFormat(m_config.format, false), aligned_width,
|
||||||
|
aligned_height, 1, upload_stride}}}};
|
||||||
const D3D12_BOX src_box{0, 0, 0, aligned_width, aligned_height, 1};
|
const D3D12_BOX src_box{0, 0, 0, aligned_width, aligned_height, 1};
|
||||||
g_dx_context->GetCommandList()->CopyTextureRegion(&dst_loc, 0, 0, 0, &src_loc, &src_box);
|
g_dx_context->GetCommandList()->CopyTextureRegion(&dst_loc, 0, 0, 0, &src_loc, &src_box);
|
||||||
|
|
||||||
|
@ -363,11 +365,11 @@ void DXTexture::CopyRectangleFromTexture(const AbstractTexture* src,
|
||||||
const D3D12_TEXTURE_COPY_LOCATION dst_loc = {
|
const D3D12_TEXTURE_COPY_LOCATION dst_loc = {
|
||||||
m_resource.Get(),
|
m_resource.Get(),
|
||||||
D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX,
|
D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX,
|
||||||
{static_cast<UINT>(CalcSubresource(dst_level, dst_layer))}};
|
{{static_cast<UINT>(CalcSubresource(dst_level, dst_layer))}}};
|
||||||
const D3D12_TEXTURE_COPY_LOCATION src_loc = {
|
const D3D12_TEXTURE_COPY_LOCATION src_loc = {
|
||||||
src_dxtex->m_resource.Get(),
|
src_dxtex->m_resource.Get(),
|
||||||
D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX,
|
D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX,
|
||||||
{static_cast<UINT>(src_dxtex->CalcSubresource(src_level, src_layer))}};
|
{{static_cast<UINT>(src_dxtex->CalcSubresource(src_level, src_layer))}}};
|
||||||
const D3D12_BOX src_box = RectangleToBox(src_rect);
|
const D3D12_BOX src_box = RectangleToBox(src_rect);
|
||||||
const D3D12_RESOURCE_STATES old_src_state = src_dxtex->m_state;
|
const D3D12_RESOURCE_STATES old_src_state = src_dxtex->m_state;
|
||||||
src_dxtex->TransitionToState(D3D12_RESOURCE_STATE_COPY_SOURCE);
|
src_dxtex->TransitionToState(D3D12_RESOURCE_STATE_COPY_SOURCE);
|
||||||
|
@ -686,12 +688,13 @@ void DXStagingTexture::CopyFromTexture(const AbstractTexture* src,
|
||||||
const D3D12_TEXTURE_COPY_LOCATION dst_loc = {
|
const D3D12_TEXTURE_COPY_LOCATION dst_loc = {
|
||||||
m_resource.Get(),
|
m_resource.Get(),
|
||||||
D3D12_TEXTURE_COPY_TYPE_PLACED_FOOTPRINT,
|
D3D12_TEXTURE_COPY_TYPE_PLACED_FOOTPRINT,
|
||||||
{0,
|
{{0,
|
||||||
{D3DCommon::GetDXGIFormatForAbstractFormat(m_config.format, false), m_config.width,
|
{D3DCommon::GetDXGIFormatForAbstractFormat(m_config.format, false), m_config.width,
|
||||||
m_config.height, 1u, static_cast<UINT>(m_map_stride)}}};
|
m_config.height, 1u, static_cast<UINT>(m_map_stride)}}}};
|
||||||
const D3D12_TEXTURE_COPY_LOCATION src_loc = {
|
const D3D12_TEXTURE_COPY_LOCATION src_loc = {
|
||||||
src_tex->GetResource(), D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX,
|
src_tex->GetResource(),
|
||||||
static_cast<UINT>(src_tex->CalcSubresource(src_level, src_layer))};
|
D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX,
|
||||||
|
{{static_cast<UINT>(src_tex->CalcSubresource(src_level, src_layer))}}};
|
||||||
const D3D12_BOX src_box = RectangleToBox(src_rect);
|
const D3D12_BOX src_box = RectangleToBox(src_rect);
|
||||||
g_dx_context->GetCommandList()->CopyTextureRegion(&dst_loc, dst_rect.left, dst_rect.top, 0,
|
g_dx_context->GetCommandList()->CopyTextureRegion(&dst_loc, dst_rect.left, dst_rect.top, 0,
|
||||||
&src_loc, &src_box);
|
&src_loc, &src_box);
|
||||||
|
@ -725,14 +728,15 @@ void DXStagingTexture::CopyToTexture(const MathUtil::Rectangle<int>& src_rect, A
|
||||||
|
|
||||||
// Copy from VRAM -> host-visible memory.
|
// Copy from VRAM -> host-visible memory.
|
||||||
const D3D12_TEXTURE_COPY_LOCATION dst_loc = {
|
const D3D12_TEXTURE_COPY_LOCATION dst_loc = {
|
||||||
dst_tex->GetResource(), D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX,
|
dst_tex->GetResource(),
|
||||||
static_cast<UINT>(dst_tex->CalcSubresource(dst_level, dst_layer))};
|
D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX,
|
||||||
|
{{static_cast<UINT>(dst_tex->CalcSubresource(dst_level, dst_layer))}}};
|
||||||
const D3D12_TEXTURE_COPY_LOCATION src_loc = {
|
const D3D12_TEXTURE_COPY_LOCATION src_loc = {
|
||||||
m_resource.Get(),
|
m_resource.Get(),
|
||||||
D3D12_TEXTURE_COPY_TYPE_PLACED_FOOTPRINT,
|
D3D12_TEXTURE_COPY_TYPE_PLACED_FOOTPRINT,
|
||||||
{0,
|
{{0,
|
||||||
{D3DCommon::GetDXGIFormatForAbstractFormat(m_config.format, false), m_config.width,
|
{D3DCommon::GetDXGIFormatForAbstractFormat(m_config.format, false), m_config.width,
|
||||||
m_config.height, 1u, static_cast<UINT>(m_map_stride)}}};
|
m_config.height, 1u, static_cast<UINT>(m_map_stride)}}}};
|
||||||
const D3D12_BOX src_box = RectangleToBox(src_rect);
|
const D3D12_BOX src_box = RectangleToBox(src_rect);
|
||||||
g_dx_context->GetCommandList()->CopyTextureRegion(&dst_loc, dst_rect.left, dst_rect.top, 0,
|
g_dx_context->GetCommandList()->CopyTextureRegion(&dst_loc, dst_rect.left, dst_rect.top, 0,
|
||||||
&src_loc, &src_box);
|
&src_loc, &src_box);
|
||||||
|
|
|
@ -81,13 +81,13 @@ Microsoft::WRL::ComPtr<IDXGIFactory> CreateDXGIFactory(bool debug_device)
|
||||||
// Use Win8.1 version if available.
|
// Use Win8.1 version if available.
|
||||||
if (create_dxgi_factory2 &&
|
if (create_dxgi_factory2 &&
|
||||||
SUCCEEDED(create_dxgi_factory2(debug_device ? DXGI_CREATE_FACTORY_DEBUG : 0,
|
SUCCEEDED(create_dxgi_factory2(debug_device ? DXGI_CREATE_FACTORY_DEBUG : 0,
|
||||||
IID_PPV_ARGS(factory.GetAddressOf()))))
|
IID_PPV_ARGS(&factory))))
|
||||||
{
|
{
|
||||||
return factory;
|
return factory;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fallback to original version, without debug support.
|
// Fallback to original version, without debug support.
|
||||||
HRESULT hr = create_dxgi_factory(IID_PPV_ARGS(factory.ReleaseAndGetAddressOf()));
|
HRESULT hr = create_dxgi_factory(IID_PPV_ARGS(&factory));
|
||||||
if (FAILED(hr))
|
if (FAILED(hr))
|
||||||
{
|
{
|
||||||
PanicAlertFmt("CreateDXGIFactory() failed: {}", Common::HRWrap(hr));
|
PanicAlertFmt("CreateDXGIFactory() failed: {}", Common::HRWrap(hr));
|
||||||
|
@ -100,7 +100,7 @@ Microsoft::WRL::ComPtr<IDXGIFactory> CreateDXGIFactory(bool debug_device)
|
||||||
std::vector<std::string> GetAdapterNames()
|
std::vector<std::string> GetAdapterNames()
|
||||||
{
|
{
|
||||||
Microsoft::WRL::ComPtr<IDXGIFactory> factory;
|
Microsoft::WRL::ComPtr<IDXGIFactory> factory;
|
||||||
HRESULT hr = create_dxgi_factory(IID_PPV_ARGS(factory.GetAddressOf()));
|
HRESULT hr = create_dxgi_factory(IID_PPV_ARGS(&factory));
|
||||||
if (FAILED(hr))
|
if (FAILED(hr))
|
||||||
return {};
|
return {};
|
||||||
|
|
||||||
|
|
|
@ -155,7 +155,7 @@ bool SwapChain::CreateSwapChain(bool stereo, bool hdr)
|
||||||
// Only try to activate HDR here, to avoid failing when creating the swapchain
|
// Only try to activate HDR here, to avoid failing when creating the swapchain
|
||||||
// (we can't know if the format is supported upfront)
|
// (we can't know if the format is supported upfront)
|
||||||
Microsoft::WRL::ComPtr<IDXGISwapChain4> swap_chain4;
|
Microsoft::WRL::ComPtr<IDXGISwapChain4> swap_chain4;
|
||||||
hr = m_swap_chain->QueryInterface(IID_PPV_ARGS(&swap_chain4));
|
hr = m_swap_chain.As(&swap_chain4);
|
||||||
if (SUCCEEDED(hr))
|
if (SUCCEEDED(hr))
|
||||||
{
|
{
|
||||||
UINT color_space_support = 0;
|
UINT color_space_support = 0;
|
||||||
|
@ -214,7 +214,7 @@ bool SwapChain::ResizeSwapChain()
|
||||||
WARN_LOG_FMT(VIDEO, "ResizeBuffers() failed: {}", Common::HRWrap(hr));
|
WARN_LOG_FMT(VIDEO, "ResizeBuffers() failed: {}", Common::HRWrap(hr));
|
||||||
|
|
||||||
Microsoft::WRL::ComPtr<IDXGISwapChain4> swap_chain4;
|
Microsoft::WRL::ComPtr<IDXGISwapChain4> swap_chain4;
|
||||||
hr = m_swap_chain->QueryInterface(IID_PPV_ARGS(&swap_chain4));
|
hr = m_swap_chain.As(&swap_chain4);
|
||||||
if (SUCCEEDED(hr))
|
if (SUCCEEDED(hr))
|
||||||
hr = swap_chain4->SetColorSpace1(m_hdr ? DXGI_COLOR_SPACE_RGB_FULL_G10_NONE_P709 :
|
hr = swap_chain4->SetColorSpace1(m_hdr ? DXGI_COLOR_SPACE_RGB_FULL_G10_NONE_P709 :
|
||||||
DXGI_COLOR_SPACE_RGB_FULL_G22_NONE_P709);
|
DXGI_COLOR_SPACE_RGB_FULL_G22_NONE_P709);
|
||||||
|
|
|
@ -25,7 +25,7 @@ namespace
|
||||||
{
|
{
|
||||||
std::chrono::system_clock::time_point FileTimeToSysTime(std::filesystem::file_time_type file_time)
|
std::chrono::system_clock::time_point FileTimeToSysTime(std::filesystem::file_time_type file_time)
|
||||||
{
|
{
|
||||||
#ifdef _WIN32
|
#if defined(_WIN32) && !defined(__clang__)
|
||||||
return std::chrono::clock_cast<std::chrono::system_clock>(file_time);
|
return std::chrono::clock_cast<std::chrono::system_clock>(file_time);
|
||||||
#else
|
#else
|
||||||
// Note: all compilers should switch to chrono::clock_cast
|
// Note: all compilers should switch to chrono::clock_cast
|
||||||
|
|
|
@ -76,10 +76,17 @@ VideoBackendBase* g_video_backend = nullptr;
|
||||||
// performance graphics mode or using the IGP.
|
// performance graphics mode or using the IGP.
|
||||||
// AMD drivers >= 13.35 do the same, but for the variable
|
// AMD drivers >= 13.35 do the same, but for the variable
|
||||||
// named AmdPowerXpressRequestHighPerformance instead.
|
// named AmdPowerXpressRequestHighPerformance instead.
|
||||||
|
#ifdef __clang__
|
||||||
|
#pragma clang diagnostic push
|
||||||
|
#pragma clang diagnostic ignored "-Wmissing-variable-declarations"
|
||||||
|
#endif
|
||||||
extern "C" {
|
extern "C" {
|
||||||
__declspec(dllexport) DWORD NvOptimusEnablement = 1;
|
__declspec(dllexport) DWORD NvOptimusEnablement = 1;
|
||||||
__declspec(dllexport) int AmdPowerXpressRequestHighPerformance = 1;
|
__declspec(dllexport) int AmdPowerXpressRequestHighPerformance = 1;
|
||||||
}
|
}
|
||||||
|
#ifdef __clang__
|
||||||
|
#pragma clang diagnostic pop
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
std::string VideoBackendBase::BadShaderFilename(const char* shader_stage, int counter)
|
std::string VideoBackendBase::BadShaderFilename(const char* shader_stage, int counter)
|
||||||
|
|
|
@ -12,6 +12,9 @@ target_link_libraries(winupdater PRIVATE
|
||||||
Comctl32
|
Comctl32
|
||||||
)
|
)
|
||||||
|
|
||||||
|
target_compile_definitions(winupdater PRIVATE _UNICODE UNICODE)
|
||||||
|
target_link_options(winupdater PRIVATE -municode)
|
||||||
|
|
||||||
set_target_properties(winupdater PROPERTIES OUTPUT_NAME "Updater")
|
set_target_properties(winupdater PROPERTIES OUTPUT_NAME "Updater")
|
||||||
|
|
||||||
if(MSVC)
|
if(MSVC)
|
||||||
|
|
|
@ -78,7 +78,7 @@ bool InitWindow()
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (SUCCEEDED(CoCreateInstance(CLSID_TaskbarList, nullptr, CLSCTX_INPROC_SERVER,
|
if (SUCCEEDED(CoCreateInstance(CLSID_TaskbarList, nullptr, CLSCTX_INPROC_SERVER,
|
||||||
IID_PPV_ARGS(taskbar_list.GetAddressOf()))))
|
IID_PPV_ARGS(&taskbar_list))))
|
||||||
{
|
{
|
||||||
if (FAILED(taskbar_list->HrInit()))
|
if (FAILED(taskbar_list->HrInit()))
|
||||||
{
|
{
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue