From b201d669b5ea1470bb239036aa944342a0591a95 Mon Sep 17 00:00:00 2001 From: krzys-h Date: Fri, 28 Dec 2018 12:41:38 +0100 Subject: [PATCH 1/5] First iteration of UWP support Enough to kind of run Working drivers: xinput, d3d11 Still missing: input driver with keyboard support, audio driver --- AUTHORS.h | 1 + configuration.c | 19 +- dynamic.c | 2 + frontend/drivers/platform_win32.c | 102 +++- gfx/common/d3d10_common.c | 2 +- gfx/common/d3d11_common.c | 2 +- gfx/common/d3d11_common.h | 4 + gfx/common/d3d12_common.c | 4 +- gfx/common/d3d_common.c | 25 + gfx/common/d3d_common.h | 4 +- gfx/common/d3dcompiler_common.c | 2 +- gfx/common/dxgi_common.c | 29 +- gfx/common/dxgi_common.h | 3 +- gfx/drivers/d3d10.c | 27 +- gfx/drivers/d3d11.c | 101 +++- gfx/drivers/d3d12.c | 23 +- gfx/drivers/d3d8.c | 42 +- gfx/drivers/d3d9.c | 43 +- gfx/font_driver.c | 4 +- gfx/video_display_server.c | 2 +- gfx/video_driver.c | 4 +- griffin/griffin.c | 6 +- input/drivers_joypad/xinput_joypad.c | 52 +- input/input_driver.c | 4 +- input/input_keymaps.c | 7 +- libretro-common/dynamic/dylib.c | 45 +- libretro-common/file/file_path.c | 95 +++- libretro-common/file/nbio/nbio_intf.c | 2 +- libretro-common/include/file/file_path.h | 2 + menu/menu_displaylist.c | 6 +- menu/menu_driver.c | 2 +- pkg/msvc/RetroArch-msvc2017-UWP.sln | 51 ++ .../Assets/LockScreenLogo.scale-200.png | Bin 0 -> 1430 bytes .../Assets/SplashScreen.scale-200.png | Bin 0 -> 7700 bytes .../Assets/Square150x150Logo.scale-200.png | Bin 0 -> 2937 bytes .../Assets/Square44x44Logo.scale-200.png | Bin 0 -> 1647 bytes ...x44Logo.targetsize-24_altform-unplated.png | Bin 0 -> 1255 bytes pkg/msvc/msvc-2017-UWP/Assets/StoreLogo.png | Bin 0 -> 1451 bytes .../Assets/Wide310x150Logo.scale-200.png | Bin 0 -> 3204 bytes pkg/msvc/msvc-2017-UWP/Package.appxmanifest | 49 ++ .../RetroArch-msvc2017-UWP.vcxproj | 506 ++++++++++++++++++ .../RetroArch-msvc2017-UWP.vcxproj.filters | 280 ++++++++++ .../msvc-2017-UWP_TemporaryKey.pfx | Bin 0 -> 2504 bytes ui/ui_companion_driver.c | 2 +- uwp/uwp_func.h | 35 ++ uwp/uwp_main.cpp | 479 +++++++++++++++++ uwp/uwp_main.h | 82 +++ verbosity.c | 19 +- 48 files changed, 1986 insertions(+), 183 deletions(-) create mode 100644 pkg/msvc/RetroArch-msvc2017-UWP.sln create mode 100644 pkg/msvc/msvc-2017-UWP/Assets/LockScreenLogo.scale-200.png create mode 100644 pkg/msvc/msvc-2017-UWP/Assets/SplashScreen.scale-200.png create mode 100644 pkg/msvc/msvc-2017-UWP/Assets/Square150x150Logo.scale-200.png create mode 100644 pkg/msvc/msvc-2017-UWP/Assets/Square44x44Logo.scale-200.png create mode 100644 pkg/msvc/msvc-2017-UWP/Assets/Square44x44Logo.targetsize-24_altform-unplated.png create mode 100644 pkg/msvc/msvc-2017-UWP/Assets/StoreLogo.png create mode 100644 pkg/msvc/msvc-2017-UWP/Assets/Wide310x150Logo.scale-200.png create mode 100644 pkg/msvc/msvc-2017-UWP/Package.appxmanifest create mode 100644 pkg/msvc/msvc-2017-UWP/RetroArch-msvc2017-UWP.vcxproj create mode 100644 pkg/msvc/msvc-2017-UWP/RetroArch-msvc2017-UWP.vcxproj.filters create mode 100644 pkg/msvc/msvc-2017-UWP/msvc-2017-UWP_TemporaryKey.pfx create mode 100644 uwp/uwp_func.h create mode 100644 uwp/uwp_main.cpp create mode 100644 uwp/uwp_main.h diff --git a/AUTHORS.h b/AUTHORS.h index a94c292b12..4863d9b0fb 100644 --- a/AUTHORS.h +++ b/AUTHORS.h @@ -142,6 +142,7 @@ JuanVCS Justin Jacobs (dorkster) Justin Weiss (justinweiss) Ken Rossato (rossato) +Krzysztof Haładyn (krzys_h) kurumushi kwyxz l3iggs diff --git a/configuration.c b/configuration.c index 871a7cc7b6..7ab65f20d9 100644 --- a/configuration.c +++ b/configuration.c @@ -56,6 +56,10 @@ #include "record/record_driver.h" +#ifdef __WINRT__ +#include "uwp/uwp_func.h" +#endif + static const char* invalid_filename_chars[] = { /* https://support.microsoft.com/en-us/help/905231/information-about-the-characters-that-you-cannot-use-in-site-names--fo */ "~", "#", "%", "&", "*", "{", "}", "\\", ":", "[", "]", "?", "/", "|", "\'", "\"", @@ -319,6 +323,12 @@ static enum video_driver_enum VIDEO_DEFAULT_DRIVER = VIDEO_WII; static enum video_driver_enum VIDEO_DEFAULT_DRIVER = VIDEO_WIIU; #elif defined(XENON) static enum video_driver_enum VIDEO_DEFAULT_DRIVER = VIDEO_XENON360; +#elif defined(HAVE_D3D12) +static enum video_driver_enum VIDEO_DEFAULT_DRIVER = VIDEO_D3D12; +#elif defined(HAVE_D3D11) +static enum video_driver_enum VIDEO_DEFAULT_DRIVER = VIDEO_D3D11; +#elif defined(HAVE_D3D10) +static enum video_driver_enum VIDEO_DEFAULT_DRIVER = VIDEO_D3D10; #elif defined(HAVE_D3D9) static enum video_driver_enum VIDEO_DEFAULT_DRIVER = VIDEO_D3D9; #elif defined(HAVE_D3D8) @@ -2221,8 +2231,13 @@ static config_file_t *open_default_config_file(void) (void)path_size; -#if defined(_WIN32) && !defined(_XBOX) && !defined(__WINRT__) - fill_pathname_application_path(app_path, path_size); +#if defined(_WIN32) && !defined(_XBOX) +#ifdef __WINRT__ + /* On UWP, the app install directory is not writable so use the writable LocalState dir instead */ + fill_pathname_home_dir(app_path, path_size); +#else + fill_pathname_application_dir(app_path, path_size); +#endif fill_pathname_resolve_relative(conf_path, app_path, file_path_str(FILE_PATH_MAIN_CONFIG), path_size); diff --git a/dynamic.c b/dynamic.c index 049aad7883..89bcc8f1c7 100644 --- a/dynamic.c +++ b/dynamic.c @@ -306,6 +306,7 @@ static void libretro_get_environment_info(void (*func)(retro_environment_t), static bool load_dynamic_core(void) { +#ifndef __WINRT__ /* Can't lookup symbols in itself on UWP */ function_t sym = dylib_proc(NULL, "retro_init"); if (sym) @@ -319,6 +320,7 @@ static bool load_dynamic_core(void) RARCH_ERR("Proceeding could cause a crash. Aborting ...\n"); retroarch_fail(1, "init_libretro_sym()"); } +#endif if (string_is_empty(path_get(RARCH_PATH_CORE))) { diff --git a/frontend/drivers/platform_win32.c b/frontend/drivers/platform_win32.c index 59905c9884..c655a594c5 100644 --- a/frontend/drivers/platform_win32.c +++ b/frontend/drivers/platform_win32.c @@ -43,6 +43,11 @@ #include "../../verbosity.h" #include "../../ui/drivers/ui_win32.h" +#ifdef __WINRT__ +#include "../../uwp/uwp_func.h" +#endif + +#ifndef __WINRT__ /* We only load this library once, so we let it be * unloaded at application shutdown, since unloading * it early seems to cause issues on some systems. @@ -145,6 +150,7 @@ static void gfx_set_dwm(void) RARCH_ERR("Failed to set composition state ...\n"); dwm_composition_disabled = settings->bools.video_disable_composition; } +#endif static void frontend_win32_get_os(char *s, size_t len, int *major, int *minor) { @@ -165,7 +171,9 @@ static void frontend_win32_get_os(char *s, size_t len, int *major, int *minor) GetVersionEx((OSVERSIONINFO*)&vi); server = vi.wProductType != VER_NT_WORKSTATION; +#ifndef __WINRT__ serverR2 = GetSystemMetrics(SM_SERVERR2); +#endif switch (si.wProcessorArchitecture) { @@ -302,10 +310,19 @@ static void frontend_win32_get_os(char *s, size_t len, int *major, int *minor) strlcat(s, " ", len); strlcat(s, vi.szCSDVersion, len); } + +#ifdef __WINRT__ + if (!string_is_empty(uwp_device_family)) + { + strlcat(s, " ", len); + strlcat(s, uwp_device_family, len); + } +#endif } static void frontend_win32_init(void *data) { +#ifndef __WINRT__ typedef BOOL (WINAPI *isProcessDPIAwareProc)(); typedef BOOL (WINAPI *setProcessDPIAwareProc)(); #ifdef HAVE_DYNAMIC @@ -324,6 +341,7 @@ static void frontend_win32_init(void *data) if (!isDPIAwareProc()) if (setDPIAwareProc) setDPIAwareProc(); +#endif } enum frontend_powerstate frontend_win32_get_powerstate(int *seconds, int *percent) @@ -385,13 +403,14 @@ enum frontend_architecture frontend_win32_get_architecture(void) static int frontend_win32_parse_drive_list(void *data, bool load_content) { #ifdef HAVE_MENU + file_list_t *list = (file_list_t*)data; + enum msg_hash_enums enum_idx = load_content ? + MENU_ENUM_LABEL_FILE_DETECT_CORE_LIST_PUSH_DIR : + MSG_UNKNOWN; +#ifndef __WINRT__ size_t i = 0; unsigned drives = GetLogicalDrives(); char drive[] = " :\\"; - file_list_t *list = (file_list_t*)data; - enum msg_hash_enums enum_idx = load_content ? - MENU_ENUM_LABEL_FILE_DETECT_CORE_LIST_PUSH_DIR : - MSG_UNKNOWN; for (i = 0; i < 32; i++) { @@ -403,6 +422,22 @@ static int frontend_win32_parse_drive_list(void *data, bool load_content) enum_idx, FILE_TYPE_DIRECTORY, 0, 0); } +#else + /* TODO (krzys_h): UWP storage sandboxing */ + + char *home_dir = (char*)malloc(PATH_MAX_LENGTH * sizeof(char)); + + fill_pathname_home_dir(home_dir, + PATH_MAX_LENGTH * sizeof(char)); + + menu_entries_append_enum(list, + home_dir, + msg_hash_to_str(MENU_ENUM_LABEL_FILE_DETECT_CORE_LIST_PUSH_DIR), + enum_idx, + FILE_TYPE_DIRECTORY, 0, 0); + + free(home_dir); +#endif #endif return 0; @@ -411,6 +446,7 @@ static int frontend_win32_parse_drive_list(void *data, bool load_content) static void frontend_win32_environment_get(int *argc, char *argv[], void *args, void *params_data) { +#ifndef __WINRT__ gfx_set_dwm(); fill_pathname_expand_special(g_defaults.dirs[DEFAULT_DIR_ASSETS], @@ -459,6 +495,57 @@ static void frontend_win32_environment_get(int *argc, char *argv[], ":\\states", sizeof(g_defaults.dirs[DEFAULT_DIR_SAVESTATE])); fill_pathname_expand_special(g_defaults.dirs[DEFAULT_DIR_SYSTEM], ":\\system", sizeof(g_defaults.dirs[DEFAULT_DIR_SYSTEM])); +#else + /* On UWP, we have to use the writable directory instead of the install directory */ + fill_pathname_expand_special(g_defaults.dirs[DEFAULT_DIR_ASSETS], + "~\\assets", sizeof(g_defaults.dirs[DEFAULT_DIR_ASSETS])); + fill_pathname_expand_special(g_defaults.dirs[DEFAULT_DIR_AUDIO_FILTER], + "~\\filters\\audio", sizeof(g_defaults.dirs[DEFAULT_DIR_AUDIO_FILTER])); + fill_pathname_expand_special(g_defaults.dirs[DEFAULT_DIR_VIDEO_FILTER], + "~\\filters\\video", sizeof(g_defaults.dirs[DEFAULT_DIR_VIDEO_FILTER])); + fill_pathname_expand_special(g_defaults.dirs[DEFAULT_DIR_CHEATS], + "~\\cheats", sizeof(g_defaults.dirs[DEFAULT_DIR_CHEATS])); + fill_pathname_expand_special(g_defaults.dirs[DEFAULT_DIR_DATABASE], + "~\\database\\rdb", sizeof(g_defaults.dirs[DEFAULT_DIR_DATABASE])); + fill_pathname_expand_special(g_defaults.dirs[DEFAULT_DIR_CURSOR], + "~\\database\\cursors", sizeof(g_defaults.dirs[DEFAULT_DIR_CURSOR])); + fill_pathname_expand_special(g_defaults.dirs[DEFAULT_DIR_PLAYLIST], + "~\\playlists", sizeof(g_defaults.dirs[DEFAULT_DIR_ASSETS])); + fill_pathname_expand_special(g_defaults.dirs[DEFAULT_DIR_RECORD_CONFIG], + "~\\config\\record", sizeof(g_defaults.dirs[DEFAULT_DIR_RECORD_CONFIG])); + fill_pathname_expand_special(g_defaults.dirs[DEFAULT_DIR_RECORD_OUTPUT], + "~\\recordings", sizeof(g_defaults.dirs[DEFAULT_DIR_RECORD_OUTPUT])); + fill_pathname_expand_special(g_defaults.dirs[DEFAULT_DIR_MENU_CONFIG], + "~\\config", sizeof(g_defaults.dirs[DEFAULT_DIR_MENU_CONFIG])); + fill_pathname_expand_special(g_defaults.dirs[DEFAULT_DIR_REMAP], + "~\\config\\remaps", sizeof(g_defaults.dirs[DEFAULT_DIR_REMAP])); + fill_pathname_expand_special(g_defaults.dirs[DEFAULT_DIR_WALLPAPERS], + "~\\assets\\wallpapers", sizeof(g_defaults.dirs[DEFAULT_DIR_WALLPAPERS])); + fill_pathname_expand_special(g_defaults.dirs[DEFAULT_DIR_THUMBNAILS], + "~\\thumbnails", sizeof(g_defaults.dirs[DEFAULT_DIR_THUMBNAILS])); + fill_pathname_expand_special(g_defaults.dirs[DEFAULT_DIR_OVERLAY], + "~\\overlays", sizeof(g_defaults.dirs[DEFAULT_DIR_OVERLAY])); + /* This one is an exception: cores have to be loaded from the install directory, + * since this is the only place UWP apps can take .dlls from */ + fill_pathname_expand_special(g_defaults.dirs[DEFAULT_DIR_CORE], + ":\\cores", sizeof(g_defaults.dirs[DEFAULT_DIR_CORE])); + fill_pathname_expand_special(g_defaults.dirs[DEFAULT_DIR_CORE_INFO], + "~\\info", sizeof(g_defaults.dirs[DEFAULT_DIR_CORE_INFO])); + fill_pathname_expand_special(g_defaults.dirs[DEFAULT_DIR_AUTOCONFIG], + "~\\autoconfig", sizeof(g_defaults.dirs[DEFAULT_DIR_AUTOCONFIG])); + fill_pathname_expand_special(g_defaults.dirs[DEFAULT_DIR_SHADER], + "~\\shaders", sizeof(g_defaults.dirs[DEFAULT_DIR_SHADER])); + fill_pathname_expand_special(g_defaults.dirs[DEFAULT_DIR_CORE_ASSETS], + "~\\downloads", sizeof(g_defaults.dirs[DEFAULT_DIR_CORE_ASSETS])); + fill_pathname_expand_special(g_defaults.dirs[DEFAULT_DIR_SCREENSHOT], + "~\\screenshots", sizeof(g_defaults.dirs[DEFAULT_DIR_SCREENSHOT])); + fill_pathname_expand_special(g_defaults.dirs[DEFAULT_DIR_SRAM], + "~\\saves", sizeof(g_defaults.dirs[DEFAULT_DIR_SRAM])); + fill_pathname_expand_special(g_defaults.dirs[DEFAULT_DIR_SAVESTATE], + "~\\states", sizeof(g_defaults.dirs[DEFAULT_DIR_SAVESTATE])); + fill_pathname_expand_special(g_defaults.dirs[DEFAULT_DIR_SYSTEM], + "~\\system", sizeof(g_defaults.dirs[DEFAULT_DIR_SYSTEM])); +#endif #ifdef HAVE_MENU #if defined(HAVE_OPENGL) || defined(HAVE_OPENGLES) @@ -502,6 +589,7 @@ static uint64_t frontend_win32_get_mem_used(void) #endif } +#ifndef __WINRT__ static void frontend_win32_attach_console(void) { #ifdef _WIN32 @@ -560,6 +648,7 @@ static void frontend_win32_detach_console(void) #endif #endif } +#endif frontend_ctx_driver_t frontend_ctx_win32 = { frontend_win32_environment_get, @@ -583,8 +672,13 @@ frontend_ctx_driver_t frontend_ctx_win32 = { NULL, /* get_sighandler_state */ NULL, /* set_sighandler_state */ NULL, /* destroy_sighandler_state */ +#ifndef __WINRT__ frontend_win32_attach_console, /* attach_console */ frontend_win32_detach_console, /* detach_console */ +#else + NULL, + NULL, +#endif NULL, /* watch_path_for_changes */ NULL, /* check_for_path_changes */ NULL, /* set_sustained_performance_mode */ diff --git a/gfx/common/d3d10_common.c b/gfx/common/d3d10_common.c index 1b145015f7..16a35b9c57 100644 --- a/gfx/common/d3d10_common.c +++ b/gfx/common/d3d10_common.c @@ -20,7 +20,7 @@ #include "d3d10_common.h" #include "d3dcompiler_common.h" -#ifdef HAVE_DYNAMIC +#if defined(HAVE_DYNAMIC) && !defined(__WINRT__) #include typedef HRESULT(WINAPI* PFN_D3D10_CREATE_DEVICE_AND_SWAP_CHAIN)( diff --git a/gfx/common/d3d11_common.c b/gfx/common/d3d11_common.c index 16b32151e1..dbb3b53c42 100644 --- a/gfx/common/d3d11_common.c +++ b/gfx/common/d3d11_common.c @@ -20,7 +20,7 @@ #include "d3d11_common.h" #include "d3dcompiler_common.h" -#ifdef HAVE_DYNAMIC +#if defined(HAVE_DYNAMIC) && !defined(__WINRT__) #include HRESULT WINAPI D3D11CreateDeviceAndSwapChain( diff --git a/gfx/common/d3d11_common.h b/gfx/common/d3d11_common.h index 69128cd07a..db6254e8c1 100644 --- a/gfx/common/d3d11_common.h +++ b/gfx/common/d3d11_common.h @@ -2159,6 +2159,7 @@ static INLINE HRESULT D3D11ValidateContextForDispatch(D3D11Debug debug, D3D11Dev { return debug->lpVtbl->ValidateContextForDispatch(debug, context); } +#ifndef __WINRT__ static INLINE BOOL D3D11SetUseRef(D3D11SwitchToRef switch_to_ref, BOOL use_ref) { return switch_to_ref->lpVtbl->SetUseRef(switch_to_ref, use_ref); @@ -2167,6 +2168,7 @@ static INLINE BOOL D3D11GetUseRef(D3D11SwitchToRef switch_to_ref) { return switch_to_ref->lpVtbl->GetUseRef(switch_to_ref); } +#endif static INLINE HRESULT D3D11SetShaderTrackingOptionsByType( D3D11TracingDevice tracing_device, UINT resource_type_flags, UINT options) { @@ -2188,6 +2190,7 @@ static INLINE void D3D11ClearStoredMessages(D3D11InfoQueue info_queue) { info_queue->lpVtbl->ClearStoredMessages(info_queue); } +#ifndef __WINRT__ static INLINE HRESULT D3D11GetMessageA( D3D11InfoQueue info_queue, UINT64 message_index, @@ -2196,6 +2199,7 @@ static INLINE HRESULT D3D11GetMessageA( { return info_queue->lpVtbl->GetMessageA(info_queue, message_index, message, message_byte_length); } +#endif static INLINE UINT64 D3D11GetNumMessagesAllowedByStorageFilter(D3D11InfoQueue info_queue) { return info_queue->lpVtbl->GetNumMessagesAllowedByStorageFilter(info_queue); diff --git a/gfx/common/d3d12_common.c b/gfx/common/d3d12_common.c index 1b8d9478c5..a405dc5e46 100644 --- a/gfx/common/d3d12_common.c +++ b/gfx/common/d3d12_common.c @@ -1,4 +1,4 @@ -/* RetroArch - A frontend for libretro. +/* RetroArch - A frontend for libretro. * Copyright (C) 2014-2018 - Ali Bouhlel * * RetroArch is free software: you can redistribute it and/or modify it under the terms @@ -65,7 +65,7 @@ DEFINE_GUIDW(IID_ID3D12DebugCommandList, 0x09e0bf36, 0x54ac, 0x484f, 0x88, 0x47, /* clang-format on */ #endif -#ifdef HAVE_DYNAMIC +#if defined(HAVE_DYNAMIC) && !defined(__WINRT__) static dylib_t d3d12_dll; static const char* d3d12_dll_name = "d3d12.dll"; diff --git a/gfx/common/d3d_common.c b/gfx/common/d3d_common.c index c026c3c9f2..211e68939c 100644 --- a/gfx/common/d3d_common.c +++ b/gfx/common/d3d_common.c @@ -125,3 +125,28 @@ int32_t d3d_translate_filter(unsigned type) return (int32_t)D3D_TEXTURE_FILTER_POINT; } + +void d3d_input_driver(const char* input_name, const char* joypad_name, const input_driver_t** input, void** input_data) +{ +#if defined(_XBOX) || defined(__WINRT__) + void *xinput = input_xinput.init(joypad_name); + *input = xinput ? (const input_driver_t*)&input_xinput : NULL; + *input_data = xinput; +#else +#if _WIN32_WINNT >= 0x0501 + /* winraw only available since XP */ + if (string_is_equal(input_name, "raw")) + { + *input_data = input_winraw.init(joypad_name); + if (*input_data) + { + *input = &input_winraw; + return; + } + } +#endif + + *input_data = input_dinput.init(joypad_name); + *input = *input_data ? &input_dinput : NULL; +#endif +} diff --git a/gfx/common/d3d_common.h b/gfx/common/d3d_common.h index 69c9ae6526..14a724a3e7 100644 --- a/gfx/common/d3d_common.h +++ b/gfx/common/d3d_common.h @@ -20,7 +20,7 @@ #include "../../config.h" #endif -#ifndef _XBOX +#if !defined(_XBOX) && !defined(__WINRT__) #define HAVE_WINDOW #endif @@ -97,6 +97,8 @@ void *d3d_matrix_rotation_z(void *_pout, float angle); int32_t d3d_translate_filter(unsigned type); +void d3d_input_driver(const char* input_name, const char* joypad_name, const input_driver_t** input, void** input_data); + RETRO_END_DECLS #endif diff --git a/gfx/common/d3dcompiler_common.c b/gfx/common/d3dcompiler_common.c index 6da87c1ba4..22d17704a3 100644 --- a/gfx/common/d3dcompiler_common.c +++ b/gfx/common/d3dcompiler_common.c @@ -25,7 +25,7 @@ #include "d3dcompiler_common.h" #include "../../verbosity.h" -#ifdef HAVE_DYNAMIC +#if defined(HAVE_DYNAMIC) && !defined(__WINRT__) #include static dylib_t d3dcompiler_dll; diff --git a/gfx/common/dxgi_common.c b/gfx/common/dxgi_common.c index 3d935f41d2..86f4a7b987 100644 --- a/gfx/common/dxgi_common.c +++ b/gfx/common/dxgi_common.c @@ -30,7 +30,7 @@ #include "../video_driver.h" #include "win32_common.h" -#ifdef HAVE_DYNAMIC +#if defined(HAVE_DYNAMIC) && !defined(__WINRT__) #include HRESULT WINAPI CreateDXGIFactory1(REFIID riid, void** ppFactory) @@ -309,6 +309,7 @@ void dxgi_update_title(video_frame_info_t* video_info) if (settings->bools.video_memory_show) { +#ifndef __WINRT__ MEMORYSTATUS stat; char mem[128]; @@ -319,6 +320,7 @@ void dxgi_update_title(video_frame_info_t* video_info) mem, sizeof(mem), " || MEM: %.2f/%.2fMB", stat.dwAvailPhys / (1024.0f * 1024.0f), stat.dwTotalPhys / (1024.0f * 1024.0f)); strlcat(video_info->fps_text, mem, sizeof(video_info->fps_text)); +#endif } if (window) @@ -329,32 +331,11 @@ void dxgi_update_title(video_frame_info_t* video_info) video_driver_get_window_title(title, sizeof(title)); +#ifndef __WINRT__ if (title[0]) window->set_title(&main_window, title); - } -} - -void dxgi_input_driver(const char* name, const input_driver_t** input, void** input_data) -{ -#ifndef __WINRT__ - settings_t* settings = config_get_ptr(); - -#if _WIN32_WINNT >= 0x0501 - /* winraw only available since XP */ - if (string_is_equal(settings->arrays.input_driver, "raw")) - { - *input_data = input_winraw.init(name); - if (*input_data) - { - *input = &input_winraw; - return; - } - } -#endif - - *input_data = input_dinput.init(name); - *input = *input_data ? &input_dinput : NULL; #endif + } } DXGI_FORMAT glslang_format_to_dxgi(glslang_format fmt) diff --git a/gfx/common/dxgi_common.h b/gfx/common/dxgi_common.h index 0323b5d839..0e5e15e88f 100644 --- a/gfx/common/dxgi_common.h +++ b/gfx/common/dxgi_common.h @@ -444,6 +444,7 @@ static INLINE HRESULT DXGIGetAdapterDesc1(DXGIAdapter adapter, DXGI_ADAPTER_DESC { return adapter->lpVtbl->GetDesc1(adapter, desc); } +#ifndef __WINRT__ static INLINE ULONG DXGIReleaseDisplayControl(DXGIDisplayControl display_control) { return display_control->lpVtbl->Release(display_control); @@ -612,6 +613,7 @@ static INLINE HRESULT DXGICheckPresentDurationSupport( swap_chain_media, desired_present_duration, closest_smaller_present_duration, closest_larger_present_duration); } +#endif static INLINE ULONG DXGIReleaseSwapChain(DXGISwapChain swap_chain) { return swap_chain->lpVtbl->Release(swap_chain); @@ -793,7 +795,6 @@ void dxgi_copy( void* dst_data); void dxgi_update_title(video_frame_info_t* video_info); -void dxgi_input_driver(const char* name, const input_driver_t** input, void** input_data); DXGI_FORMAT glslang_format_to_dxgi(glslang_format fmt); diff --git a/gfx/drivers/d3d10.c b/gfx/drivers/d3d10.c index b123cda661..69a38a61a8 100644 --- a/gfx/drivers/d3d10.c +++ b/gfx/drivers/d3d10.c @@ -1,4 +1,4 @@ -/* RetroArch - A frontend for libretro. +/* RetroArch - A frontend for libretro. * Copyright (C) 2014-2018 - Ali Bouhlel * * RetroArch is free software: you can redistribute it and/or modify it under the terms @@ -35,6 +35,10 @@ #include "../../menu/menu_driver.h" #endif +#ifdef __WINRT__ +#error "UWP does not support D3D10" +#endif + #ifdef HAVE_OVERLAY static void d3d10_free_overlays(d3d10_video_t* d3d10) { @@ -556,8 +560,12 @@ static void d3d10_gfx_free(void* data) Release(d3d10->device); } +#ifdef HAVE_MONITOR win32_monitor_from_window(); +#endif +#ifdef HAVE_WINDOW win32_destroy_window(); +#endif free(d3d10); } @@ -566,31 +574,39 @@ d3d10_gfx_init(const video_info_t* video, const input_driver_t** input, void** input_data) { unsigned i; +#ifdef HAVE_MONITOR MONITORINFOEX current_mon; HMONITOR hm_to_use; WNDCLASSEX wndclass = { 0 }; +#endif settings_t* settings = config_get_ptr(); d3d10_video_t* d3d10 = (d3d10_video_t*)calloc(1, sizeof(*d3d10)); if (!d3d10) return NULL; +#ifdef HAVE_WINDOW win32_window_reset(); win32_monitor_init(); wndclass.lpfnWndProc = WndProcD3D; win32_window_init(&wndclass, true, NULL); +#endif +#ifdef HAVE_MONITOR win32_monitor_info(¤t_mon, &hm_to_use, &d3d10->cur_mon_id); +#endif d3d10->vp.full_width = video->width; d3d10->vp.full_height = video->height; +#ifdef HAVE_MONITOR if (!d3d10->vp.full_width) d3d10->vp.full_width = current_mon.rcMonitor.right - current_mon.rcMonitor.left; if (!d3d10->vp.full_height) d3d10->vp.full_height = current_mon.rcMonitor.bottom - current_mon.rcMonitor.top; +#endif if (!win32_set_video_mode(d3d10, d3d10->vp.full_width, d3d10->vp.full_height, video->fullscreen)) @@ -598,7 +614,7 @@ d3d10_gfx_init(const video_info_t* video, RARCH_ERR("[D3D10]: win32_set_video_mode failed.\n"); goto error; } - dxgi_input_driver(settings->arrays.input_joypad_driver, input, input_data); + d3d_input_driver(settings->arrays.input_driver, settings->arrays.input_joypad_driver, input, input_data); { UINT flags = 0; @@ -611,7 +627,9 @@ d3d10_gfx_init(const video_info_t* video, desc.BufferDesc.RefreshRate.Numerator = 60; desc.BufferDesc.RefreshRate.Denominator = 1; desc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; +#if HAVE_WINDOW desc.OutputWindow = main_window.hwnd; +#endif desc.SampleDesc.Count = 1; desc.SampleDesc.Quality = 0; desc.Windowed = TRUE; @@ -1598,7 +1616,12 @@ static const video_poke_interface_t d3d10_poke_interface = { d3d10_gfx_load_texture, d3d10_gfx_unload_texture, NULL, /* set_video_mode */ +#ifndef __WINRT__ win32_get_refresh_rate, +#else + /* UWP does not expose this information easily */ + NULL, +#endif d3d10_set_filtering, NULL, /* get_video_output_size */ NULL, /* get_video_output_prev */ diff --git a/gfx/drivers/d3d11.c b/gfx/drivers/d3d11.c index 137ad02525..8e0293be3e 100644 --- a/gfx/drivers/d3d11.c +++ b/gfx/drivers/d3d11.c @@ -1,4 +1,4 @@ -/* RetroArch - A frontend for libretro. +/* RetroArch - A frontend for libretro. * Copyright (C) 2014-2018 - Ali Bouhlel * * RetroArch is free software: you can redistribute it and/or modify it under the terms @@ -41,6 +41,10 @@ #include "../drivers_shader/slang_process.h" #endif +#ifdef __WINRT__ +#include "../../uwp/uwp_func.h" +#endif + static D3D11Device cached_device_d3d11; static D3D_FEATURE_LEVEL cached_supportedFeatureLevel; static D3D11DeviceContext cached_context; @@ -566,8 +570,12 @@ static void d3d11_gfx_free(void* data) Release(d3d11->device); } +#ifdef HAVE_MONITOR win32_monitor_from_window(); +#endif +#ifdef HAVE_WINDOW win32_destroy_window(); +#endif free(d3d11); } @@ -575,29 +583,37 @@ static void d3d11_gfx_free(void* data) d3d11_gfx_init(const video_info_t* video, const input_driver_t** input, void** input_data) { unsigned i; +#ifdef HAVE_MONITOR MONITORINFOEX current_mon; HMONITOR hm_to_use; WNDCLASSEX wndclass = { 0 }; +#endif settings_t* settings = config_get_ptr(); d3d11_video_t* d3d11 = (d3d11_video_t*)calloc(1, sizeof(*d3d11)); if (!d3d11) return NULL; +#ifdef HAVE_WINDOW win32_window_reset(); win32_monitor_init(); wndclass.lpfnWndProc = WndProcD3D; win32_window_init(&wndclass, true, NULL); +#endif +#ifdef HAVE_MONITOR win32_monitor_info(¤t_mon, &hm_to_use, &d3d11->cur_mon_id); +#endif d3d11->vp.full_width = video->width; d3d11->vp.full_height = video->height; +#ifdef HAVE_MONITOR if (!d3d11->vp.full_width) d3d11->vp.full_width = current_mon.rcMonitor.right - current_mon.rcMonitor.left; if (!d3d11->vp.full_height) d3d11->vp.full_height = current_mon.rcMonitor.bottom - current_mon.rcMonitor.top; +#endif if (!win32_set_video_mode(d3d11, d3d11->vp.full_width, d3d11->vp.full_height, video->fullscreen)) { @@ -605,7 +621,7 @@ d3d11_gfx_init(const video_info_t* video, const input_driver_t** input, void** i goto error; } - dxgi_input_driver(settings->arrays.input_joypad_driver, input, input_data); + d3d_input_driver(settings->arrays.input_driver, settings->arrays.input_joypad_driver, input, input_data); { UINT flags = 0; @@ -617,26 +633,45 @@ d3d11_gfx_init(const video_info_t* video, const input_driver_t** input, void** i D3D_FEATURE_LEVEL_10_0, D3D_FEATURE_LEVEL_9_3 }; +#ifdef __WINRT__ + /* UWP requires the use of newer version of the factory which requires newer version of this struct */ + DXGI_SWAP_CHAIN_DESC1 desc = { 0 }; +#else DXGI_SWAP_CHAIN_DESC desc = { 0 }; +#endif UINT number_feature_levels = ARRAY_SIZE(requested_feature_levels); - desc.BufferCount = 1; +#ifdef __WINRT__ + /* UWP forces us to do double-buffering */ + desc.BufferCount = 2; + desc.Width = d3d11->vp.full_width; + desc.Height = d3d11->vp.full_height; + desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; +#else + desc.BufferCount = 1; desc.BufferDesc.Width = d3d11->vp.full_width; desc.BufferDesc.Height = d3d11->vp.full_height; desc.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; desc.BufferDesc.RefreshRate.Numerator = 60; desc.BufferDesc.RefreshRate.Denominator = 1; +#endif desc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; +#if HAVE_WINDOW desc.OutputWindow = main_window.hwnd; +#endif desc.SampleDesc.Count = 1; desc.SampleDesc.Quality = 0; #if 0 desc.Scaling = DXGI_SCALING_STRETCH; #endif +#if HAVE_WINDOW desc.Windowed = TRUE; +#endif #if defined(WINAPI_FAMILY) && (WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP) /* On phone, no swap effects are supported. */ desc.SwapEffect = DXGI_SWAP_EFFECT_DISCARD; +#elif defined(__WINRT__) + desc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL; #else desc.SwapEffect = DXGI_SWAP_EFFECT_SEQUENTIAL; #endif @@ -646,37 +681,47 @@ d3d11_gfx_init(const video_info_t* video, const input_driver_t** input, void** i #endif if(cached_device_d3d11 && cached_context) { - IDXGIFactory* dxgiFactory = NULL; - IDXGIDevice* dxgiDevice = NULL; - IDXGIAdapter* adapter = NULL; - d3d11->device = cached_device_d3d11; d3d11->context = cached_context; d3d11->supportedFeatureLevel = cached_supportedFeatureLevel; - - d3d11->device->lpVtbl->QueryInterface( - d3d11->device, uuidof(IDXGIDevice), (void**)&dxgiDevice); - dxgiDevice->lpVtbl->GetAdapter(dxgiDevice, &adapter); - adapter->lpVtbl->GetParent( - adapter, uuidof(IDXGIFactory1), (void**)&dxgiFactory); - dxgiFactory->lpVtbl->CreateSwapChain( - dxgiFactory, (IUnknown*)d3d11->device, - &desc, (IDXGISwapChain**)&d3d11->swapChain); - - dxgiFactory->lpVtbl->Release(dxgiFactory); - adapter->lpVtbl->Release(adapter); - dxgiDevice->lpVtbl->Release(dxgiDevice); } else { - if (FAILED(D3D11CreateDeviceAndSwapChain( + if (FAILED(D3D11CreateDevice( NULL, D3D_DRIVER_TYPE_HARDWARE, NULL, flags, requested_feature_levels, number_feature_levels, - D3D11_SDK_VERSION, &desc, - (IDXGISwapChain**)&d3d11->swapChain, &d3d11->device, + D3D11_SDK_VERSION, &d3d11->device, &d3d11->supportedFeatureLevel, &d3d11->context))) goto error; } + + IDXGIDevice* dxgiDevice = NULL; + IDXGIAdapter* adapter = NULL; + + d3d11->device->lpVtbl->QueryInterface( + d3d11->device, uuidof(IDXGIDevice), (void**)&dxgiDevice); + dxgiDevice->lpVtbl->GetAdapter(dxgiDevice, &adapter); +#ifndef __WINRT__ + IDXGIFactory* dxgiFactory = NULL; + adapter->lpVtbl->GetParent( + adapter, uuidof(IDXGIFactory1), (void**)&dxgiFactory); + if (FAILED(dxgiFactory->lpVtbl->CreateSwapChain( + dxgiFactory, (IUnknown*)d3d11->device, + &desc, (IDXGISwapChain**)&d3d11->swapChain))) + goto error; +#else + IDXGIFactory2* dxgiFactory = NULL; + adapter->lpVtbl->GetParent( + adapter, uuidof(IDXGIFactory2), (void**)&dxgiFactory); + if (FAILED(dxgiFactory->lpVtbl->CreateSwapChainForCoreWindow( + dxgiFactory, (IUnknown*)d3d11->device, uwp_get_corewindow(), + &desc, NULL, (IDXGISwapChain1**)&d3d11->swapChain))) + goto error; +#endif + + dxgiFactory->lpVtbl->Release(dxgiFactory); + adapter->lpVtbl->Release(adapter); + dxgiDevice->lpVtbl->Release(dxgiDevice); } { @@ -1142,6 +1187,11 @@ static bool d3d11_gfx_frame( video_driver_set_size(&video_info->width, &video_info->height); } +#ifdef __WINRT__ + /* UWP requires double-buffering, so make sure we bind to the appropariate backbuffer */ + D3D11SetRenderTargets(context, 1, &d3d11->renderTargetView, NULL); +#endif + PERF_START(); #if 0 /* custom viewport doesn't call apply_state_changes, so we can't rely on this for now */ @@ -1622,7 +1672,12 @@ static const video_poke_interface_t d3d11_poke_interface = { d3d11_gfx_load_texture, d3d11_gfx_unload_texture, NULL, /* set_video_mode */ +#ifndef __WINRT__ win32_get_refresh_rate, +#else + /* UWP does not expose this information easily */ + NULL, +#endif d3d11_set_filtering, NULL, /* get_video_output_size */ NULL, /* get_video_output_prev */ diff --git a/gfx/drivers/d3d12.c b/gfx/drivers/d3d12.c index c4dab9fcc3..c89797c5db 100644 --- a/gfx/drivers/d3d12.c +++ b/gfx/drivers/d3d12.c @@ -1,4 +1,4 @@ -/* RetroArch - A frontend for libretro. +/* RetroArch - A frontend for libretro. * Copyright (C) 2014-2018 - Ali Bouhlel * * RetroArch is free software: you can redistribute it and/or modify it under the terms @@ -35,6 +35,10 @@ #include "wiiu/wiiu_dbg.h" +#ifdef __WINRT__ +#error "TODO (krzys_h): DX12 could be doable on UWP?" +#endif + static void d3d12_gfx_sync(d3d12_video_t* d3d12) { if (D3D12GetCompletedValue(d3d12->queue.fence) < d3d12->queue.fenceValue) @@ -864,8 +868,12 @@ static void d3d12_gfx_free(void* data) Release(d3d12->device); Release(d3d12->adapter); +#ifdef HAVE_MONITOR win32_monitor_from_window(); +#endif +#ifdef HAVE_WINDOW win32_destroy_window(); +#endif free(d3d12); } @@ -882,20 +890,26 @@ d3d12_gfx_init(const video_info_t* video, const input_driver_t** input, void** i if (!d3d12) return NULL; +#ifdef HAVE_WINDOW win32_window_reset(); win32_monitor_init(); wndclass.lpfnWndProc = WndProcD3D; win32_window_init(&wndclass, true, NULL); +#endif +#ifdef HAVE_MONITOR win32_monitor_info(¤t_mon, &hm_to_use, &d3d12->cur_mon_id); +#endif d3d12->vp.full_width = video->width; d3d12->vp.full_height = video->height; +#ifdef HAVE_MONITOR if (!d3d12->vp.full_width) d3d12->vp.full_width = current_mon.rcMonitor.right - current_mon.rcMonitor.left; if (!d3d12->vp.full_height) d3d12->vp.full_height = current_mon.rcMonitor.bottom - current_mon.rcMonitor.top; +#endif if (!win32_set_video_mode(d3d12, d3d12->vp.full_width, d3d12->vp.full_height, video->fullscreen)) { @@ -903,7 +917,7 @@ d3d12_gfx_init(const video_info_t* video, const input_driver_t** input, void** i goto error; } - dxgi_input_driver(settings->arrays.input_joypad_driver, input, input_data); + d3d_input_driver(settings->arrays.input_driver, settings->arrays.input_joypad_driver, input, input_data); if (!d3d12_init_base(d3d12)) goto error; @@ -1764,7 +1778,12 @@ static const video_poke_interface_t d3d12_poke_interface = { d3d12_gfx_load_texture, d3d12_gfx_unload_texture, NULL, /* set_video_mode */ +#ifndef __WINRT__ win32_get_refresh_rate, +#else + /* UWP does not expose this information easily */ + NULL, +#endif d3d12_set_filtering, NULL, /* get_video_output_size */ NULL, /* get_video_output_prev */ diff --git a/gfx/drivers/d3d8.c b/gfx/drivers/d3d8.c index a5dcf1b2a1..3c174fdd93 100644 --- a/gfx/drivers/d3d8.c +++ b/gfx/drivers/d3d8.c @@ -48,9 +48,11 @@ #ifdef _XBOX #define D3D8_PRESENTATIONINTERVAL D3DRS_PRESENTATIONINTERVAL #else +#ifndef __WINRT__ #define HAVE_MONITOR #define HAVE_WINDOW #endif +#endif #ifdef HAVE_MENU #include "../../menu/menu_driver.h" @@ -61,6 +63,10 @@ #include "../../core.h" #include "../../verbosity.h" +#ifdef __WINRT__ +#error "UWP does not support D3D8" +#endif + static LPDIRECT3D8 g_pD3D8; #ifdef _XBOX @@ -1137,37 +1143,6 @@ static void d3d8_set_osd_msg(void *data, d3d8_end_scene(d3d->dev); } -static void d3d8_input_driver( - const input_driver_t **input, void **input_data) -{ - settings_t *settings = config_get_ptr(); - const char *name = settings ? - settings->arrays.input_joypad_driver : NULL; -#ifdef _XBOX - void *xinput = input_xinput.init(name); - *input = xinput ? (const input_driver_t*)&input_xinput : NULL; - *input_data = xinput; -#else -#if _WIN32_WINNT >= 0x0501 - /* winraw only available since XP */ - if (string_is_equal(settings->arrays.input_driver, "raw")) - { - *input_data = input_winraw.init(name); - if (*input_data) - { - *input = &input_winraw; - dinput = NULL; - return; - } - } -#endif - - dinput = input_dinput.init(name); - *input = dinput ? &input_dinput : NULL; - *input_data = dinput; -#endif -} - static bool d3d8_init_internal(d3d8_video_t *d3d, const video_info_t *info, const input_driver_t **input, void **input_data) @@ -1255,7 +1230,7 @@ static bool d3d8_init_internal(d3d8_video_t *d3d, if (!d3d8_initialize(d3d, &d3d->video_info)) return false; - d3d8_input_driver(input, input_data); + d3d_input_driver(settings->arrays.input_driver, settings->arrays.input_joypad_driver, input, input_data); RARCH_LOG("[D3D8]: Init complete.\n"); return true; @@ -1888,9 +1863,10 @@ static const video_poke_interface_t d3d_poke_interface = { d3d8_load_texture, d3d8_unload_texture, d3d8_set_video_mode, -#ifdef _XBOX +#if defined(_XBOX) || defined(__WINRT__) NULL, #else + /* UWP does not expose this information easily */ win32_get_refresh_rate, #endif NULL, diff --git a/gfx/drivers/d3d9.c b/gfx/drivers/d3d9.c index a383190b48..00917d4bbe 100644 --- a/gfx/drivers/d3d9.c +++ b/gfx/drivers/d3d9.c @@ -1,4 +1,4 @@ -/* RetroArch - A frontend for libretro. +/* RetroArch - A frontend for libretro. * Copyright (C) 2010-2014 - Hans-Kristian Arntzen * Copyright (C) 2011-2017 - Daniel De Matteis * Copyright (C) 2012-2014 - OV2 @@ -65,6 +65,10 @@ #include "../../verbosity.h" #include "../../retroarch.h" +#ifdef __WINRT__ +#error "UWP does not support D3D9" +#endif + static LPDIRECT3D9 g_pD3D9; void *dinput; @@ -1182,38 +1186,6 @@ static void d3d9_set_osd_msg(void *data, d3d9_end_scene(dev); } -static void d3d9_input_driver( - const input_driver_t **input, void **input_data) -{ - settings_t *settings = config_get_ptr(); - const char *name = settings ? - settings->arrays.input_joypad_driver : NULL; -#ifdef _XBOX - void *xinput = input_xinput.init(name); - *input = xinput ? (const input_driver_t*)&input_xinput : NULL; - *input_data = xinput; -#else - -#if _WIN32_WINNT >= 0x0501 - /* winraw only available since XP */ - if (string_is_equal(settings->arrays.input_driver, "raw")) - { - *input_data = input_winraw.init(name); - if (*input_data) - { - *input = &input_winraw; - dinput = NULL; - return; - } - } -#endif - - dinput = input_dinput.init(name); - *input = dinput ? &input_dinput : NULL; - *input_data = dinput; -#endif -} - static bool d3d9_init_internal(d3d9_video_t *d3d, const video_info_t *info, const input_driver_t **input, void **input_data) @@ -1325,7 +1297,7 @@ static bool d3d9_init_internal(d3d9_video_t *d3d, if (!d3d9_initialize(d3d, &d3d->video_info)) return false; - d3d9_input_driver(input, input_data); + d3d_input_driver(settings->arrays.input_joypad_driver, input, input_data); RARCH_LOG("[D3D9]: Init complete.\n"); return true; @@ -2054,9 +2026,10 @@ static const video_poke_interface_t d3d9_poke_interface = { d3d9_load_texture, d3d9_unload_texture, d3d9_set_video_mode, -#ifdef _XBOX +#if defined(_XBOX) || defined(__WINRT__) NULL, #else + /* UWP does not expose this information easily */ win32_get_refresh_rate, #endif NULL, diff --git a/gfx/font_driver.c b/gfx/font_driver.c index 07ce2dd93c..8eaf1d2447 100644 --- a/gfx/font_driver.c +++ b/gfx/font_driver.c @@ -278,7 +278,7 @@ static bool vga_font_init_first( } #endif -#if defined(_WIN32) && !defined(_XBOX) +#if defined(_WIN32) && !defined(_XBOX) && !defined(__WINRT__) static const font_renderer_t *gdi_font_backends[] = { &gdi_font, NULL, @@ -666,7 +666,7 @@ static bool font_init_first( return switch_font_init_first(font_driver, font_handle, video_data, font_path, font_size, is_threaded); #endif -#if defined(_WIN32) && !defined(_XBOX) +#if defined(_WIN32) && !defined(_XBOX) && !defined(__WINRT__) case FONT_DRIVER_RENDER_GDI: return gdi_font_init_first(font_driver, font_handle, video_data, font_path, font_size, is_threaded); diff --git a/gfx/video_display_server.c b/gfx/video_display_server.c index e4824a0a46..73dd8c92ca 100644 --- a/gfx/video_display_server.c +++ b/gfx/video_display_server.c @@ -39,7 +39,7 @@ void* video_display_server_init(void) switch (type) { case RARCH_DISPLAY_WIN32: -#if defined(_WIN32) && !defined(_XBOX) +#if defined(_WIN32) && !defined(_XBOX) && !defined(__WINRT__) current_display_server = &dispserv_win32; #endif break; diff --git a/gfx/video_driver.c b/gfx/video_driver.c index 88ef1862ef..b00014fb0b 100644 --- a/gfx/video_driver.c +++ b/gfx/video_driver.c @@ -340,7 +340,7 @@ static const video_driver_t *video_drivers[] = { #ifdef HAVE_XSHM &video_xshm, #endif -#if defined(_WIN32) && !defined(_XBOX) +#if defined(_WIN32) && !defined(_XBOX) && !defined(__WINRT__) &video_gdi, #endif #ifdef DJGPP @@ -416,7 +416,7 @@ static const gfx_ctx_driver_t *gfx_ctx_drivers[] = { #if defined(HAVE_VULKAN) && defined(HAVE_VULKAN_DISPLAY) &gfx_ctx_khr_display, #endif -#if defined(_WIN32) && !defined(_XBOX) +#if defined(_WIN32) && !defined(_XBOX) && !defined(__WINRT__) &gfx_ctx_gdi, #endif #ifdef HAVE_SIXEL diff --git a/griffin/griffin.c b/griffin/griffin.c index 4589cafc12..cbe29ef9e7 100644 --- a/griffin/griffin.c +++ b/griffin/griffin.c @@ -601,6 +601,8 @@ INPUT #elif defined(DJGPP) #include "../input/drivers/dos_input.c" #include "../input/drivers_joypad/dos_joypad.c" +#elif defined(__WINRT__) +#include "../input/drivers/xdk_xinput_input.c" #endif #ifdef HAVE_WAYLAND @@ -947,7 +949,7 @@ FRONTEND #include "../frontend/frontend_driver.c" -#if defined(_WIN32) && !defined(_XBOX) && !defined(__WINRT__) +#if defined(_WIN32) && !defined(_XBOX) #include "../frontend/drivers/platform_win32.c" #endif @@ -1259,7 +1261,7 @@ MENU #include "../menu/drivers_display/menu_display_vga.c" #endif -#if defined(_WIN32) && !defined(_XBOX) +#if defined(_WIN32) && !defined(_XBOX) && !defined(__WINRT__) #include "../menu/drivers_display/menu_display_gdi.c" #endif diff --git a/input/drivers_joypad/xinput_joypad.c b/input/drivers_joypad/xinput_joypad.c index a7b5e639a8..1961b64262 100644 --- a/input/drivers_joypad/xinput_joypad.c +++ b/input/drivers_joypad/xinput_joypad.c @@ -42,12 +42,20 @@ #ifdef HAVE_DINPUT #include "dinput_joypad.h" +#else +int g_xinput_pad_indexes[MAX_USERS]; +bool g_xinput_block_pads; +#endif + +#if defined(__WINRT__) +#include #endif /* Check if the definitions do not already exist. * Official and mingw xinput headers have different include guards. + * Windows 10 API version doesn't have an include guard at all and just uses #pragma once instead */ -#if ((!_XINPUT_H_) && (!__WINE_XINPUT_H)) +#if ((!_XINPUT_H_) && (!__WINE_XINPUT_H)) && !defined(__WINRT__) #define XINPUT_GAMEPAD_DPAD_UP 0x0001 #define XINPUT_GAMEPAD_DPAD_DOWN 0x0002 @@ -173,7 +181,7 @@ const char *xinput_joypad_name(unsigned pad) return XBOX_CONTROLLER_NAMES[xuser]; } -#ifdef HAVE_DYNAMIC +#if defined(HAVE_DYNAMIC) && !defined(__WINRT__) static bool load_xinput_dll(void) { const char *version = "1.4"; @@ -210,7 +218,7 @@ static bool xinput_joypad_init(void *data) unsigned i, j; XINPUT_STATE dummy_state; -#ifdef HAVE_DYNAMIC +#if defined(HAVE_DYNAMIC) && !defined(__WINRT__) if (!g_xinput_dll) if (!load_xinput_dll()) return false; @@ -219,6 +227,9 @@ static bool xinput_joypad_init(void *data) * First try to load ordinal 100 (XInputGetStateEx). */ g_XInputGetStateEx = (XInputGetStateEx_t)dylib_proc(g_xinput_dll, (const char*)100); +#elif defined(__WINRT__) + /* XInputGetStateEx is not available on WinRT */ + g_XInputGetStateEx = NULL; #else g_XInputGetStateEx = (XInputGetStateEx_t)XInputGetStateEx; #endif @@ -230,7 +241,7 @@ static bool xinput_joypad_init(void *data) * XInputGetState, at the cost of losing guide button support. */ g_xinput_guide_button_supported = false; -#ifdef HAVE_DYNAMIC +#if defined(HAVE_DYNAMIC) && !defined(__WINRT__) g_XInputGetStateEx = (XInputGetStateEx_t)dylib_proc(g_xinput_dll, "XInputGetState"); #else g_XInputGetStateEx = (XInputGetStateEx_t)XInputGetState; @@ -239,7 +250,7 @@ static bool xinput_joypad_init(void *data) if (!g_XInputGetStateEx) { RARCH_ERR("[XInput]: Failed to init: DLL is invalid or corrupt.\n"); -#ifdef HAVE_DYNAMIC +#if defined(HAVE_DYNAMIC) && !defined(__WINRT__) dylib_close(g_xinput_dll); #endif return false; /* DLL was loaded but did not contain the correct function. */ @@ -247,7 +258,7 @@ static bool xinput_joypad_init(void *data) RARCH_WARN("[XInput]: No guide button support.\n"); } -#ifdef HAVE_DYNAMIC +#if defined(HAVE_DYNAMIC) && !defined(__WINRT__) g_XInputSetState = (XInputSetState_t)dylib_proc(g_xinput_dll, "XInputSetState"); #else g_XInputSetState = (XInputSetState_t)XInputSetState; @@ -255,7 +266,7 @@ static bool xinput_joypad_init(void *data) if (!g_XInputSetState) { RARCH_ERR("[XInput]: Failed to init: DLL is invalid or corrupt.\n"); -#ifdef HAVE_DYNAMIC +#if defined(HAVE_DYNAMIC) && !defined(__WINRT__) dylib_close(g_xinput_dll); #endif return false; /* DLL was loaded but did not contain the correct function. */ @@ -277,7 +288,7 @@ static bool xinput_joypad_init(void *data) (!g_xinput_states[1].connected) && (!g_xinput_states[2].connected) && (!g_xinput_states[3].connected)) - return false; + return true; RARCH_LOG("[XInput]: Pads connected: %d\n", g_xinput_states[0].connected + g_xinput_states[1].connected + g_xinput_states[2].connected + g_xinput_states[3].connected); @@ -347,7 +358,7 @@ static void xinput_joypad_destroy(void) for (i = 0; i < 4; ++i) memset(&g_xinput_states[i], 0, sizeof(xinput_joypad_state)); -#ifdef HAVE_DYNAMIC +#if defined(HAVE_DYNAMIC) && !defined(__WINRT__) dylib_close(g_xinput_dll); g_xinput_dll = NULL; @@ -499,6 +510,7 @@ static void xinput_joypad_poll(void) for (i = 0; i < 4; ++i) { +#ifdef HAVE_DINPUT if (g_xinput_states[i].connected) { if (g_XInputGetStateEx && g_XInputGetStateEx(i, @@ -506,6 +518,28 @@ static void xinput_joypad_poll(void) == ERROR_DEVICE_NOT_CONNECTED) g_xinput_states[i].connected = false; } +#else + /* Normally, dinput handles device insertion/removal for us, but + * since dinput is not available on UWP we have to do it ourselves */ + /* Also note that on UWP, the controllers are not available on startup + * and are instead 'plugged in' a moment later because Microsoft reasons */ + // TODO: This may be bad for performance? + bool new_connected = g_XInputGetStateEx && g_XInputGetStateEx(i, &(g_xinput_states[i].xstate)) != ERROR_DEVICE_NOT_CONNECTED; + if (new_connected != g_xinput_states[i].connected) + { + if (new_connected) + { + /* This is kinda ugly, but it's the same thing that dinput does */ + xinput_joypad_destroy(); + xinput_joypad_init(NULL); + return; + } + else + { + g_xinput_states[i].connected = new_connected; + } + } +#endif } #ifdef HAVE_DINPUT diff --git a/input/input_driver.c b/input/input_driver.c index 3d9d60f683..5134c23e76 100644 --- a/input/input_driver.c +++ b/input/input_driver.c @@ -107,7 +107,7 @@ static const input_driver_t *input_drivers[] = { #ifdef XENON &input_xenon360, #endif -#if defined(HAVE_XINPUT2) || defined(HAVE_XINPUT_XBOX1) +#if defined(HAVE_XINPUT2) || defined(HAVE_XINPUT_XBOX1) || defined(__WINRT__) &input_xinput, #endif #ifdef GEKKO @@ -137,7 +137,7 @@ static const input_driver_t *input_drivers[] = { #ifdef DJGPP &input_dos, #endif -#if defined(_WIN32) && !defined(_XBOX) && _WIN32_WINNT >= 0x0501 +#if defined(_WIN32) && !defined(_XBOX) && _WIN32_WINNT >= 0x0501 && !defined(__WINRT__) /* winraw only available since XP */ &input_winraw, #endif diff --git a/input/input_keymaps.c b/input/input_keymaps.c index ff3817ad92..9ec77c755a 100644 --- a/input/input_keymaps.c +++ b/input/input_keymaps.c @@ -1423,7 +1423,7 @@ const struct rarch_key_map rarch_key_map_dos[] = { }; #endif -#if defined(_WIN32) && _WIN32_WINNT >= 0x0501 +#if defined(_WIN32) && _WIN32_WINNT >= 0x0501 && !defined(__WINRT__) const struct rarch_key_map rarch_key_map_winraw[] = { { VK_BACK, RETROK_BACKSPACE }, { VK_TAB, RETROK_TAB }, @@ -1539,6 +1539,11 @@ const struct rarch_key_map rarch_key_map_winraw[] = { }; #endif +#ifdef __WINRT__ +/* Refer to uwp_main.cpp - on WinRT these constants are defined as C++ enum classes + * so they can't be placed in a C source file */ +#endif + enum retro_key rarch_keysym_lut[RETROK_LAST]; /** diff --git a/libretro-common/dynamic/dylib.c b/libretro-common/dynamic/dylib.c index bc6be9fc40..1db756c734 100644 --- a/libretro-common/dynamic/dylib.c +++ b/libretro-common/dynamic/dylib.c @@ -74,17 +74,42 @@ static void set_dl_error(void) dylib_t dylib_load(const char *path) { #ifdef _WIN32 +#ifndef __WINRT__ int prevmode = SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOOPENFILEERRORBOX); -#ifdef LEGACY_WIN32 +#endif +#ifdef __WINRT__ + /* On UWP, you can only load DLLs inside your install directory, using a special function that takes a relative path */ + + if (!path_is_absolute(path)) + RARCH_WARN("Relative path in dylib_load! This is likely an attempt to load a system library that will fail\n"); + + char *relative_path_abbrev = (char*)malloc(PATH_MAX_LENGTH * sizeof(char)); + fill_pathname_abbreviate_special(relative_path_abbrev, path, PATH_MAX_LENGTH * sizeof(char)); + + char *relative_path = relative_path_abbrev; + if (relative_path[0] != ':' || !path_char_is_slash(relative_path[1])) + RARCH_WARN("Path to dylib_load is not inside app install directory! Loading will probably fail\n"); + else + relative_path += 2; + + RARCH_LOG("Loading library using a relative path: '%s'\n", relative_path); + + wchar_t *pathW = utf8_to_utf16_string_alloc(relative_path); + dylib_t lib = LoadPackagedLibrary(pathW, 0); + free(pathW); + + free(relative_path_abbrev); +#elif defined(LEGACY_WIN32) dylib_t lib = LoadLibrary(path); #else wchar_t *pathW = utf8_to_utf16_string_alloc(path); dylib_t lib = LoadLibraryW(pathW); - free(pathW); #endif +#ifndef __WINRT__ SetErrorMode(prevmode); +#endif if (!lib) { @@ -114,8 +139,20 @@ function_t dylib_proc(dylib_t lib, const char *proc) function_t sym; #ifdef _WIN32 - sym = (function_t)GetProcAddress(lib ? - (HMODULE)lib : GetModuleHandle(NULL), proc); + HMODULE mod = (HMODULE)lib; +#ifndef __WINRT__ + if (!mod) + mod = GetModuleHandle(NULL); +#else + /* GetModuleHandle is not available on UWP */ + if (!mod) + { + RARCH_WARN("FIXME: It's not possible to look up symbols in current executable on UWP!\n"); + DebugBreak(); + return NULL; + } +#endif + sym = (function_t)GetProcAddress(mod, proc); if (!sym) { set_dl_error(); diff --git a/libretro-common/file/file_path.c b/libretro-common/file/file_path.c index 1e910f4ec1..2e27217457 100644 --- a/libretro-common/file/file_path.c +++ b/libretro-common/file/file_path.c @@ -96,6 +96,12 @@ #include /* stat() is defined here */ #endif +#if !defined(RARCH_CONSOLE) && defined(RARCH_INTERNAL) +#ifdef __WINRT__ +#include +#endif +#endif + /* Assume W-functions do not work below Win2K and Xbox platforms */ #if defined(_WIN32_WINNT) && _WIN32_WINNT < 0x0500 || defined(_XBOX) @@ -1005,17 +1011,36 @@ void fill_pathname_expand_special(char *out_path, const char *in_path, size_t size) { #if !defined(RARCH_CONSOLE) && defined(RARCH_INTERNAL) - if (*in_path == '~') + if (in_path[0] == '~') { - const char *home = getenv("HOME"); - if (home) + char *home_dir = (char*)malloc(PATH_MAX_LENGTH * sizeof(char)); + + home_dir[0] = '\0'; + + fill_pathname_home_dir(home_dir, + PATH_MAX_LENGTH * sizeof(char)); + + if (*home_dir) { - size_t src_size = strlcpy(out_path, home, size); + size_t src_size = strlcpy(out_path, home_dir, size); retro_assert(src_size < size); out_path += src_size; size -= src_size; - in_path++; + + if ( + (in_path[1] == '/') +#ifdef _WIN32 + || (in_path[1] == '\\') +#endif + ) + { + in_path += 2; + } + else + { + in_path++; + } } } else if ((in_path[0] == ':') && @@ -1027,23 +1052,24 @@ void fill_pathname_expand_special(char *out_path, ) ) { - size_t src_size; char *application_dir = (char*)malloc(PATH_MAX_LENGTH * sizeof(char)); application_dir[0] = '\0'; - fill_pathname_application_path(application_dir, + fill_pathname_application_dir(application_dir, PATH_MAX_LENGTH * sizeof(char)); - path_basedir_wrapper(application_dir); - src_size = strlcpy(out_path, application_dir, size); - retro_assert(src_size < size); + if (*application_dir) + { + size_t src_size = strlcpy(out_path, application_dir, size); + retro_assert(src_size < size); - free(application_dir); + free(application_dir); - out_path += src_size; - size -= src_size; - in_path += 2; + out_path += src_size; + size -= src_size; + in_path += 2; + } } #endif @@ -1058,7 +1084,7 @@ void fill_pathname_abbreviate_special(char *out_path, const char *candidates[3]; const char *notations[3]; char *application_dir = (char*)malloc(PATH_MAX_LENGTH * sizeof(char)); - const char *home = getenv("HOME"); + char *home_dir = (char*)malloc(PATH_MAX_LENGTH * sizeof(char)); application_dir[0] = '\0'; @@ -1070,16 +1096,17 @@ void fill_pathname_abbreviate_special(char *out_path, /* ugly hack - use application_dir pointer * before filling it in. C89 reasons */ candidates[0] = application_dir; - candidates[1] = home; + candidates[1] = home_dir; candidates[2] = NULL; notations [0] = ":"; notations [1] = "~"; notations [2] = NULL; - fill_pathname_application_path(application_dir, + fill_pathname_application_dir(application_dir, + PATH_MAX_LENGTH * sizeof(char)); + fill_pathname_home_dir(home_dir, PATH_MAX_LENGTH * sizeof(char)); - path_basedir_wrapper(application_dir); for (i = 0; candidates[i]; i++) { @@ -1107,6 +1134,7 @@ void fill_pathname_abbreviate_special(char *out_path, } free(application_dir); + free(home_dir); #endif retro_assert(strlcpy(out_path, in_path, size) < size); @@ -1148,7 +1176,7 @@ void fill_pathname_application_path(char *s, size_t len) CFBundleRef bundle = CFBundleGetMainBundle(); #endif #ifdef _WIN32 - DWORD ret; + DWORD ret = 0; wchar_t wstr[PATH_MAX_LENGTH] = {0}; #endif #ifdef __HAIKU__ @@ -1160,11 +1188,11 @@ void fill_pathname_application_path(char *s, size_t len) if (!len) return; -#ifdef _WIN32 +#if defined(_WIN32) #ifdef LEGACY_WIN32 - ret = GetModuleFileNameA(GetModuleHandle(NULL), s, len); + ret = GetModuleFileNameA(NULL, s, len); #else - ret = GetModuleFileNameW(GetModuleHandle(NULL), wstr, ARRAY_SIZE(wstr)); + ret = GetModuleFileNameW(NULL, wstr, ARRAY_SIZE(wstr)); if (*wstr) { @@ -1233,4 +1261,27 @@ void fill_pathname_application_path(char *s, size_t len) } #endif } + +void fill_pathname_application_dir(char *s, size_t len) +{ +#ifdef __WINRT__ + strlcpy(s, uwp_dir_install, len); +#else + fill_pathname_application_path(s, len); + path_basedir_wrapper(s); +#endif +} + +void fill_pathname_home_dir(char *s, size_t len) +{ +#ifdef __WINRT__ + strlcpy(s, uwp_dir_data, len); +#else + const char *home = getenv("HOME"); + if (home) + strlcpy(s, home, len); + else + *s = 0; +#endif +} #endif diff --git a/libretro-common/file/nbio/nbio_intf.c b/libretro-common/file/nbio/nbio_intf.c index d6254ef08e..1ce6322bc9 100644 --- a/libretro-common/file/nbio/nbio_intf.c +++ b/libretro-common/file/nbio/nbio_intf.c @@ -38,7 +38,7 @@ extern nbio_intf_t nbio_stdio; static nbio_intf_t *internal_nbio = &nbio_linux; #elif defined(HAVE_MMAP) && defined(BSD) static nbio_intf_t *internal_nbio = &nbio_mmap_unix; -#elif defined(_WIN32) && !defined(_XBOX) +#elif defined(_WIN32) && !defined(_XBOX) && !defined(__WINRT__) static nbio_intf_t *internal_nbio = &nbio_mmap_win32; #else static nbio_intf_t *internal_nbio = &nbio_stdio; diff --git a/libretro-common/include/file/file_path.h b/libretro-common/include/file/file_path.h index 026b4f7933..b6b533a6b9 100644 --- a/libretro-common/include/file/file_path.h +++ b/libretro-common/include/file/file_path.h @@ -462,6 +462,8 @@ void fill_pathname_slash(char *path, size_t size); #if !defined(RARCH_CONSOLE) && defined(RARCH_INTERNAL) void fill_pathname_application_path(char *buf, size_t size); +void fill_pathname_application_dir(char *buf, size_t size); +void fill_pathname_home_dir(char *buf, size_t size); #endif /** diff --git a/menu/menu_displaylist.c b/menu/menu_displaylist.c index 631cb9abe6..cc742f2ce6 100644 --- a/menu/menu_displaylist.c +++ b/menu/menu_displaylist.c @@ -359,12 +359,14 @@ static int menu_displaylist_parse_core_info(menu_displaylist_info_t *info) } } +#ifndef __WINRT__ if (settings->bools.menu_show_core_updater) menu_entries_append_enum(info->list, msg_hash_to_str(MENU_ENUM_LABEL_VALUE_CORE_DELETE), msg_hash_to_str(MENU_ENUM_LABEL_CORE_DELETE), MENU_ENUM_LABEL_CORE_DELETE, MENU_SETTING_ACTION_CORE_DELETE, 0, 0); +#endif return 0; } @@ -3102,6 +3104,7 @@ static unsigned menu_displaylist_parse_options( MENU_SETTING_ACTION, 0, 0); count++; #elif defined(HAVE_NETWORKING) +#ifndef __WINRT__ if (settings->bools.menu_show_core_updater) { menu_entries_append_enum(info->list, @@ -3111,6 +3114,7 @@ static unsigned menu_displaylist_parse_options( MENU_SETTING_ACTION, 0, 0); count++; } +#endif menu_entries_append_enum(info->list, msg_hash_to_str(MENU_ENUM_LABEL_VALUE_THUMBNAILS_UPDATER_LIST), @@ -4150,7 +4154,7 @@ bool menu_displaylist_process(menu_displaylist_info_t *info) if (info->need_sort) file_list_sort_on_alt(info->list); -#if defined(HAVE_NETWORKING) +#if defined(HAVE_NETWORKING) && !defined(__WINRT__) if (settings->bools.menu_show_core_updater && !settings->bools.kiosk_mode_enable) { if (info->download_core) diff --git a/menu/menu_driver.c b/menu/menu_driver.c index 5e193fca93..579e499ef9 100644 --- a/menu/menu_driver.c +++ b/menu/menu_driver.c @@ -148,7 +148,7 @@ static menu_display_ctx_driver_t *menu_display_ctx_drivers[] = { #ifdef WIIU &menu_display_ctx_wiiu, #endif -#if defined(_WIN32) && !defined(_XBOX) +#if defined(_WIN32) && !defined(_XBOX) && !defined(__WINRT__) &menu_display_ctx_gdi, #endif #ifdef DJGPP diff --git a/pkg/msvc/RetroArch-msvc2017-UWP.sln b/pkg/msvc/RetroArch-msvc2017-UWP.sln new file mode 100644 index 0000000000..30fad3eb7a --- /dev/null +++ b/pkg/msvc/RetroArch-msvc2017-UWP.sln @@ -0,0 +1,51 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 15 +VisualStudioVersion = 15.0.28307.168 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "RetroArch-msvc2017-UWP", "msvc-2017-UWP\RetroArch-msvc2017-UWP.vcxproj", "{F5E937B6-1BA0-4446-B94B-F3BBDEF908F4}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|ARM = Debug|ARM + Debug|ARM64 = Debug|ARM64 + Debug|x64 = Debug|x64 + Debug|x86 = Debug|x86 + Release|ARM = Release|ARM + Release|ARM64 = Release|ARM64 + Release|x64 = Release|x64 + Release|x86 = Release|x86 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {F5E937B6-1BA0-4446-B94B-F3BBDEF908F4}.Debug|ARM.ActiveCfg = Debug|ARM + {F5E937B6-1BA0-4446-B94B-F3BBDEF908F4}.Debug|ARM.Build.0 = Debug|ARM + {F5E937B6-1BA0-4446-B94B-F3BBDEF908F4}.Debug|ARM.Deploy.0 = Debug|ARM + {F5E937B6-1BA0-4446-B94B-F3BBDEF908F4}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {F5E937B6-1BA0-4446-B94B-F3BBDEF908F4}.Debug|ARM64.Build.0 = Debug|ARM64 + {F5E937B6-1BA0-4446-B94B-F3BBDEF908F4}.Debug|ARM64.Deploy.0 = Debug|ARM64 + {F5E937B6-1BA0-4446-B94B-F3BBDEF908F4}.Debug|x64.ActiveCfg = Debug|x64 + {F5E937B6-1BA0-4446-B94B-F3BBDEF908F4}.Debug|x64.Build.0 = Debug|x64 + {F5E937B6-1BA0-4446-B94B-F3BBDEF908F4}.Debug|x64.Deploy.0 = Debug|x64 + {F5E937B6-1BA0-4446-B94B-F3BBDEF908F4}.Debug|x86.ActiveCfg = Debug|Win32 + {F5E937B6-1BA0-4446-B94B-F3BBDEF908F4}.Debug|x86.Build.0 = Debug|Win32 + {F5E937B6-1BA0-4446-B94B-F3BBDEF908F4}.Debug|x86.Deploy.0 = Debug|Win32 + {F5E937B6-1BA0-4446-B94B-F3BBDEF908F4}.Release|ARM.ActiveCfg = Release|ARM + {F5E937B6-1BA0-4446-B94B-F3BBDEF908F4}.Release|ARM.Build.0 = Release|ARM + {F5E937B6-1BA0-4446-B94B-F3BBDEF908F4}.Release|ARM.Deploy.0 = Release|ARM + {F5E937B6-1BA0-4446-B94B-F3BBDEF908F4}.Release|ARM64.ActiveCfg = Release|ARM64 + {F5E937B6-1BA0-4446-B94B-F3BBDEF908F4}.Release|ARM64.Build.0 = Release|ARM64 + {F5E937B6-1BA0-4446-B94B-F3BBDEF908F4}.Release|ARM64.Deploy.0 = Release|ARM64 + {F5E937B6-1BA0-4446-B94B-F3BBDEF908F4}.Release|x64.ActiveCfg = Release|x64 + {F5E937B6-1BA0-4446-B94B-F3BBDEF908F4}.Release|x64.Build.0 = Release|x64 + {F5E937B6-1BA0-4446-B94B-F3BBDEF908F4}.Release|x64.Deploy.0 = Release|x64 + {F5E937B6-1BA0-4446-B94B-F3BBDEF908F4}.Release|x86.ActiveCfg = Release|Win32 + {F5E937B6-1BA0-4446-B94B-F3BBDEF908F4}.Release|x86.Build.0 = Release|Win32 + {F5E937B6-1BA0-4446-B94B-F3BBDEF908F4}.Release|x86.Deploy.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {2A811B94-2232-4C4E-A88E-33B0CDF139A2} + EndGlobalSection +EndGlobal diff --git a/pkg/msvc/msvc-2017-UWP/Assets/LockScreenLogo.scale-200.png b/pkg/msvc/msvc-2017-UWP/Assets/LockScreenLogo.scale-200.png new file mode 100644 index 0000000000000000000000000000000000000000..735f57adb5dfc01886d137b4e493d7e97cf13af3 GIT binary patch literal 1430 zcmaJ>TTC2P7~aKltDttVHYH6u8Io4i*}3fO&d$gd*bA_<3j~&e7%8(eXJLfhS!M@! zKrliY>>6yT4+Kr95$!DoD(Qn-5TP|{V_KS`k~E6(LGS@#`v$hQo&^^BKsw3HIsZBT z_y6C2n`lK@apunKojRQ^(_P}Mgewt$(^BBKCTZ;*xa?J3wQ7~@S0lUvbcLeq1Bg4o zH-bvQi|wt~L7q$~a-gDFP!{&TQfc3fX*6=uHv* zT&1&U(-)L%Xp^djI2?~eBF2cxC@YOP$+9d?P&h?lPy-9M2UT9fg5jKm1t$m#iWE{M zIf%q9@;fyT?0UP>tcw-bLkz;s2LlKl2qeP0w zECS7Ate+Awk|KQ+DOk;fl}Xsy4o^CY=pwq%QAAKKl628_yNPsK>?A>%D8fQG6IgdJ ztnxttBz#NI_a@fk7SU`WtrpsfZsNs9^0(2a z@C3#YO3>k~w7?2hipBf{#b6`}Xw1hlG$yi?;1dDs7k~xDAw@jiI*+tc;t2Lflg&bM)0!Y;0_@=w%`LW^8DsYpS#-bLOklX9r?Ei}TScw|4DbpW%+7 zFgAI)f51s}{y-eWb|vrU-Ya!GuYKP)J7z#*V_k^Xo>4!1Yqj*m)x&0L^tg3GJbVAJ zJ-Pl$R=NAabouV=^z_t;^K*0AvFs!vYU>_<|I^#c?>>CR<(T?=%{;U=aI*SbZADLH z&(f2wz_Y0??Tf|g;?|1Znw6}6U43Q#qNRwv1vp9uFn1)V#*4p&%$mP9x&15^OaBiDS(XppT|z^>;B{PLVEbS3IFYV yGvCsSX*m literal 0 HcmV?d00001 diff --git a/pkg/msvc/msvc-2017-UWP/Assets/SplashScreen.scale-200.png b/pkg/msvc/msvc-2017-UWP/Assets/SplashScreen.scale-200.png new file mode 100644 index 0000000000000000000000000000000000000000..023e7f1feda78d5100569825acedfd213a0d84e9 GIT binary patch literal 7700 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 literal 0 HcmV?d00001 diff --git a/pkg/msvc/msvc-2017-UWP/Assets/Square150x150Logo.scale-200.png b/pkg/msvc/msvc-2017-UWP/Assets/Square150x150Logo.scale-200.png new file mode 100644 index 0000000000000000000000000000000000000000..af49fec1a5484db1d52a7f9b5ec90a27c7030186 GIT binary patch literal 2937 zcma)84OCO-8BSud5)jwMLRVKgX(S?$n?Ld|vrsm<$CF7)&zTbyy1FE5bU`Q17MRv`9ue$;R(@8kR;#vJ*IM0>cJIAOte!d7oRgdH zd%ySjdB6L9=gX^A6)VzH7p2l@v~3zJAMw|DFy#^)F@@F*`mqUn=Il>l)8_+ab;nOW{%+iPx z+s{Eu|&pIs)Z7{La9~?xKfyl z#43?gjEL15d4WbOZo#SiP%>DB^+BcnJ=7dHEe;r#G=tuw|ka z%q@}##Uh7;tc%L_64m(kHtw74ty%BJMb)_1)#S0j`)F8_1jF7vScpsnH=0V19bO8y zR`0SjIdCUo&=>JwMQF8KHA<{ODHTiQh}0^@5QRmCA?gOH6_H3K^-_sNB^RrdNuK-R zOO*vOrKCVvDwgUck`kF(E7j{I#iiN;b*ZdCt4m@HPA`EuEqGGf4%!K<;(=I=&Vyrw z%TwcWtxa}8mCZ%Cyf&ActJ6_$ox5z6-D!0-dvnRx6t7y3d+h6QYpKWO;8OdnvERo7 zuEf>ih5`wqY)~o@OeVt-wM?Q!>QzdGRj!bz6fzYrfw$hZfAKzr2-M+D+R>}~oT574c;_3zquHcElqKIsryILt3g8n3jcMb+j?i?-L3FpZJ z2WRVBRdDPc+G5aaYg#5hpE+6nQ|(VSoxT3|biF;BUq#==-27Xi=gihDPYP$7?=9cP zYKE$jeQ|3~_L0VG-(F~2ZPyD0=k{J4Q~h(t__{-mz_w8{JDY9{`1ouzz!Vr5!ECdE z6U~O1k8c}24V7~zzXWTV-Pe4)y}wQJS&q%H5`Fo_f_JvIU489aCX$;P`u#!I-=^4ijC2{&9!O&h>mi?9oYD=GC#%)6{GzN6nQYw+Fal50!#x^asjBBR50i`+mho*ttoqV)ubM2KD9S~k7+FR4>{29?6 z{!l6kDdyTN0YJ9LgkPWeXm|gyi@zM3?0@{&pXT12w|78&W-q!RRF)&iLCEZVH<|fR zN0fr2^t8H(>L?>K#>^+jWROLral(Qy-xoBq1U7A&DV||wClb)Otd9?(gZ|8znMF}D zf<1haWz^s0qgecz;RFGt0C-B4g`jNGHsFU+;{<%t65v^sjk^h$lmWn#B0#_)9ij&d z-~lc`A)YYExi^7sBuPM^Y|wA2g*5?`K?#7tzELQYNxGo$UB$4J8RJp1k(8Jj+~hMT zlN~>M@KTTh^--8y3PK_NZ@AC!{PT=CziBzGd+wTJ^@icH!Bd}%)g8V)%K?|c&WTUk zy}qv1C%(fjRoZ4ozC3{O%@5?)XzH35zHns$pgU*Q?fj4v?fp1Qbm+j;3l;9jam9Da zXVcKjPlQ73x78QPu|Ffm6x?`~e3oD=gl=4kYK?={kD5j~QCXU)`HSdduNNENzA*2$ zOm3PzF!lN5e*06-f1Uot67wY#{o-S1!KZ7E=!~7ynnk9_iJR#kFoNbAOT#^2Gd17F zMmvU6>lndZQGd|ax9kUoXXO+$N?|j@6qpsF&_j7YXvwo_C{JpmLw5&#e6k>atv%es z5)7r*Wvv_JkUpT}M!_o!nVlEk1Zbl=a*2hQ*<|%*K1Glj^FcF`6kTzGQ3lz~2tCc@ z&x|tj;aH&1&9HwcJBcT`;{?a+pnej;M1HO(6Z{#J!cZA04hnFl;NXA+&`=7bjW_^o zfC40u3LMG?NdPtwGl>Tq6u}*QG)}-y;)lu-_>ee3kibW(69n0$0Zy!}9rQz%*v1iO zT9_H>99yIrSPYVy6^);rR}7Yo=J_T@hi+qhTZXnVWyf;JDYm5#eYLTxr*?kiNn!+Y zQ+LUkBafNJ#rH#C(?d5^;gw9o#%daEI{mA*LHPIHPU`#|H$hD zwm>0&+kahQ)E#%~k>&5@&#Vg82H?s%71=)(soi@174pi9--2{w{1$}Sz4zGn3Du&x bht0Iza^2ykEt4(epJ78uh5nDlX8(TxzDYwP literal 0 HcmV?d00001 diff --git a/pkg/msvc/msvc-2017-UWP/Assets/Square44x44Logo.scale-200.png b/pkg/msvc/msvc-2017-UWP/Assets/Square44x44Logo.scale-200.png new file mode 100644 index 0000000000000000000000000000000000000000..ce342a2ec8a61291ba76c54604aea7e9d20af11b GIT binary patch literal 1647 zcmaJ?eM}Q)7(e+G1Q(|`V9JhTI2>MkceK4;p;PR&$Pi?ejk3YQ_3o`S&|W_dsOZ8# zWPTt69g`t$ab`0cj-Y0yiBSOqmd)tG7G(}M5aP0_%&9TijB#&)I{zSE^4@#z^FF`l z`8{8`o%wlL(UI|y2!cdsuVamHH~H86F!*-15em4)NqUpCQM5?aoC_eCf@lV4wvF2a zjDQn1JBL69f&@2M3rvzJcfE!eZ8FZUBlFlC5RD)it33{mF9#B82AiyQE%w)`vlwa> zv{<1sm&kSKK$&%2jSFn7$t&P%%6Ue>R=EAnG8N7fqynWG8L3p!4801a;8{+nliO(qd(jNJ_?+9W3#hLIDLoT6~3fx9=`CC-D}-AMrpEO7HK zt3$GicGPc?GmDjy7K2P@La;eu4!$zWCZ`ym{Z$b zu-O6RM&K4JT|BIZB`E-gxqG%FzanI#+2FFmqHqXG7yxWB=w55RGOM)$xMb(>kSNR z2w=1AZi%z=AmG~yea~XaXJR!v7vLn(RUnELfiB1|6D84ICOS}^Zo2AdN}<&*h}G_u z{xZ!(%>tLT3J3<5XhWy-tg+6)0nmUUENLW8TWA{R6bgVd3X;anYFZ^IRis*_P-C-r z;i>%1^eL3UI2-{w8nuFFcs0e~7J{O2k^~Ce%+Ly4U?|=!0LH=t6()xi<^I-rs+9sF z*q{E-CxZbGPeu#a;XJwE;9S1?#R&uns>^0G3p`hEUF*v`M?@h%T%J%RChmD|EVydq zmHWh*_=S%emRC*mhxaVLzT@>Z2SX0u9v*DIJ@WC^kLVdlGV6LpK$KIrlJqc zpJ921)+3JJdTx|<`G&kXpKkjGJv=76R`yYIQ{#c-`%+`#V(7}Q;&@6U8!Td1`d;?N z_9mnI#?AA}4J!r)LN4!E-@H5eXauuB7TOawS>Y|{-P?NNx-lq+z1W-+y(;39P&&LP zL{N80?&=C*qKmdA^moMZRuPcD!B<*mq$ch=0Cnlitw#txRWhb3%TQvPqjkC`F69G4b! ze7z9MZ#+;_#l?H37UqUhDFb^l&s2{oM$3I0o^Q!yx;;V)QmCMo)Tb_ui|mit8MS?U zm##6$sZZ1$@|s%?l@>4Z<*Q}sRBSKMhb4I{e5LdEhsHIHTe8Bod5c>6QtT>$XgUBz z6MK`kO$=jmt@FqggOhJ5j~e@ygRbG;<{Vu)*+nn9aQeo0;$#j;|MS=S$&L?BeV25z xs3B`@=#`5TF{^6(A1rvdY@|-RtQ|iS5{tyX+wH?;n8E)G$kykv-D^wh{{!TZT%7;_ literal 0 HcmV?d00001 diff --git a/pkg/msvc/msvc-2017-UWP/Assets/Square44x44Logo.targetsize-24_altform-unplated.png b/pkg/msvc/msvc-2017-UWP/Assets/Square44x44Logo.targetsize-24_altform-unplated.png new file mode 100644 index 0000000000000000000000000000000000000000..f6c02ce97e0a802b85f6021e822c89f8bf57d5cd GIT binary patch literal 1255 zcmaJ>TWs4@7*5+{G#S+&C!qC#> zf>5N3P6jO*Cz>ug*(_DmW=)kea&m$gZ^+nyiF`;j%w@}y8)>p*SH}C`m?DXeieF2U zyQHecc_L%Gh!7GMt+hG06y;+|p4>m~}PjA}rKViGiEnn7G0ZO<>G|7q;2?NwGCM3s?eued6%hd$B+ z*kQJ{#~$S=DFE(%=E+UkmlEI*%3llUf~8Ja9YU1Vui0IbGBkW_gHB%Rd&!!ioX zs40O?i9I{};kle7GMvE7(rk`la=gTI)47=>%?q@^iL-nUo3}h4S}N-KHn8t5mVP8w z&bSErwp+37 zNJJ8?a|{r5Q3R0Z5s-LB1WHOwYC@7pCHWND#cL1cZ?{kJ368_*(UDWUDyb<}0y@o# zfMF016iMWPCb6obAxT$JlB6(2DrlXDTB&!0`!m??4F(qWMhjVZo?JXQmz`1*58Z=& zcDmB|S-E@j?BoFGix0flckqdS4jsPNzhfWyWIM98GxcLs89C(~dw%$_t;JjX-SD}E zfiGV;{8Q%8r}w9x>EEigW81>`kvnU@pK)4+xk9@+bNj9L!AAZ@SZ@q|)&BmY3+HZx zul~BeG4|}-;L%cHViQGQX?^zFfO0&#cHwel=d`lH9sJ-@Sl@n*(8J2>%Ac`IxyY?Q z{=GhWvC#gu-~Ia7*n{=+;qM?Ul_wy1+u7ho;=`>EwP^g~R@{unBds`!#@}tluZQpS zm)M~nYEifJWJGx?_6DcTy>#uh%>!H9=hb^(v`=m3F1{L>db=<5_tm+_&knAQ2EU$s Mu9UqpbNZeC0BbUo^Z)<= literal 0 HcmV?d00001 diff --git a/pkg/msvc/msvc-2017-UWP/Assets/StoreLogo.png b/pkg/msvc/msvc-2017-UWP/Assets/StoreLogo.png new file mode 100644 index 0000000000000000000000000000000000000000..7385b56c0e4d3c6b0efe3324aa1194157d837826 GIT binary patch literal 1451 zcmaJ>eN5D57_Z|bH;{0+1#mbl)eTU3{h)Wf7EZV?;HD@XL@{B`Ui%(2aMxQ~xdXSv z5nzWi(LW)U2=Vc-cY@s7nPt{i0hc6!7xN4NNHI#EQl>YNBy8l4%x9gr_W-j zEZMQmmTIy(>;lblRfh`dIyTgc9W5d!VP$L4(kKrN1c5G~(O_#xG zAJCNTstD^5SeXFB+&$h=ToJP2H>xr$iqPs-#O*;4(!Fjw25-!gEb*)mU}=)J;Iu>w zxK(5XoD0wrPSKQ~rbL^Cw6O_03*l*}i=ydbu7adJ6y;%@tjFeXIXT+ms30pmbOP%Q zX}S;+LBh8Tea~TSkHzvX6$rYb)+n&{kSbIqh|c7hmlxmwSiq5iVhU#iEQ<>a18|O^Sln-8t&+t`*{qBWo5M?wFM(JuimAOb5!K#D}XbslM@#1ZVz_;!9U zpfEpLAOz=0g@bd6Xj_ILi-x^!M}73h^o@}hM$1jflTs|Yuj9AL@A3<-?MV4!^4q`e z)fO@A;{9K^?W?DbnesnPr6kK>$zaKo&;FhFd(GYFCIU^T+OIMb%Tqo+P%oq(IdX7S zf6+HLO?7o0m+p>~Tp5UrXWh!UH!wZ5kv!E`_w)PTpI(#Iw{AS`gH4^b(bm^ZCq^FZ zY9DD7bH}rq9mg88+KgA$Zp!iWncuU2n1AuIa@=sWvUR-s`Qb{R*kk(SPU^`$6BXz8 zn#7yaFOIK%qGxyi`dYtm#&qqox0$h=pNi#u=M8zUG@bpiZ=3sT=1}Trr}39cC)H|v zbL?W)=&s4zrh)7>L(|cc%$1#!zfL?HjpeP%T+x_a+jZ16b^iKOHxFEX$7d|8${H-* zIrOJ5w&i$>*D>AKaIoYg`;{L@jM((Kt?$N$5OnuPqVvq**Nm}(f0wwOF%iX_Pba;V z;m@wxX&NcV3?<1+u?A{y_DIj7#m3Af1rCE)o`D&Y3}0%7E;iX1yMDiS)sh0wKi!36 zL!Wmq?P^Ku&rK~HJd97KkLTRl>ScGFYZNlYytWnhmuu|)L&ND8_PmkayQb{HOY640 bno1(wj@u8DCVuFR|31B*4ek@pZJqxCDDe1x literal 0 HcmV?d00001 diff --git a/pkg/msvc/msvc-2017-UWP/Assets/Wide310x150Logo.scale-200.png b/pkg/msvc/msvc-2017-UWP/Assets/Wide310x150Logo.scale-200.png new file mode 100644 index 0000000000000000000000000000000000000000..288995b397fdbef1fb7e85afd71445d5de1952c5 GIT binary patch literal 3204 zcmbVPeQXow8NYmBd90>}0NP?GhXW~VaeThm=a0tV#EwJMI!)6M3}|c4_Bl3=Kd>G0 z(GHx1wl<7(tP?FsOQkTilSo*iIvF%uArExJ73~P zSv1xEy!U(Wd4A9D`FQV@W3@F^qJ@PEF$@z`Z!*BbFsS(^?B zyiAzJ+q})bkgiQHWqEb*jJD-coHYr1^iocg)l!Qa{Xqs-l~6J}p-|##ZHYofskQ3$ zI0;xzXyhazBeXhIsg5A=%ufo@f)1yy&ScKS0;HF^!r_2UE^lpZEom(+@duma3awTv zCrCL-%D_SvYWIcdHkmI}#50(fkUi)Qgx!80ju>g1za^}ff>JI8Z@^-iCiaCgg@TgF z+vtE?Q9{VQUX&MW9SYYmGcxA14%N2@7FwBTD4N<(2{nWgV8$e3?-F=L^&FrtWn~(U_Q~~^uYiyeY6-KoTnfh9AWz@ zIKje0)u!_Lw)E}G!#kEfwKVdNt(UAf9*f>tEL_(=xco-T%jTi@7YlC3hs2ik%Le0H ztj}RTeCF(5mwvi3_56>-yB?l;J>-1%!9~=fs|QcNG3J~a@JCu`4SB460s0ZO+##4fFUSGLcj_ja^fL4&BKALfb#$6$O?>P@qx2Agl^x0i&ugt zsy5Pyu=()`7HRMG3IB7F1@`_ z+-!J%#i6e^U$e#+C%Q>_qVRzWRsG^W_n+@OcX@vzI&z;mzHNb!GQ?LWA(wtpqHqTM z1OFw_{Zn?fD)p)`c`kOgv{de=v@suGRqY{N^U7gI1VF3*F=obwaXI6ob5__Yn zVTguS!%(NI09J8x#AO_aW!9W7k*UvB;IWDFC3srwftr{kHj%g)fvnAm;&h_dnl~

MY- zf+K}sCe8qU6Ujs`3ua{U0Of$R_gVQBuUA za0v=mu#vIOqiiAZOr&h*$WyOw&k-xr$;G4Ixa!#TJNr>95(h>l%)PUy4p+^SgR(uR zta%k*?ny-+nAr8spEk1fo{J4i!b^Fia`N{_F6@zidA2ZTTrjl#^5Z-2KfB@Cu}l9s z(*|Z2jc?p~vn2f)3y9i*7zJV1L{$?|&q)4oaT;uXi6>1GkRXVTOzAz(RHEmr=eFIi z`}<>-Q?K0GN8!IYxeP1XKXO+jsJbp~o^);Bc;%b7Flpe7;1`Ny@3r7ZR;?R)aJt8C ziNlEC<@3f_lIV4TwV}&e;D!Ee5_|e#g0LUh=5vmYWYm7&2h*M>QPKvGh9-)wfMMW3 z8J9b%1k7dzPzO0_NGQy92BZ^FR6R~6;^6?lqO;-QUP4BY%cG%3vEhbm#>4vIhPBh3 z-+pZGjh$x%Hp{?=FHsMp0&wNPlj00us{&`1ZOZTqs8%4X&xH=UDr*xyBW(Zp&Em94 zf)ZSfn#yg0N)>!1kWdkqJ^S*z0FF5|fj&qcE#Na|%OY0$uO>!&hP+1ywfD_WXk@4J(?MBftK7>$Nvqh@tDuarN%PrTLQ2Uzysx>UV=V zk^RrDSvdQ?0;=hY67EgII-f4`t=+i*yS=Y~!XlqIy_4x&%+OdfbKOFPXS2X5%4R{N z$SQMX^AK6(fA + + + + + + + + + msvc-2017-UWP + krzys + Assets\StoreLogo.png + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/pkg/msvc/msvc-2017-UWP/RetroArch-msvc2017-UWP.vcxproj b/pkg/msvc/msvc-2017-UWP/RetroArch-msvc2017-UWP.vcxproj new file mode 100644 index 0000000000..0836dbbee9 --- /dev/null +++ b/pkg/msvc/msvc-2017-UWP/RetroArch-msvc2017-UWP.vcxproj @@ -0,0 +1,506 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + Debug + ARM + + + Release + ARM + + + Debug + ARM64 + + + Release + ARM64 + + + + {f5e937b6-1ba0-4446-b94b-f3bbdef908f4} + DirectXApp + RetroArchUWP + pl-PL + 14.0 + true + Windows Store + 10.0.17763.0 + 10.0.15063.0 + 10.0 + + + + Application + true + v141 + + + Application + true + v141 + + + Application + true + v141 + true + + + Application + true + v141 + + + Application + false + true + v141 + true + + + Application + false + true + v141 + true + + + Application + false + true + v141 + true + + + Application + false + true + v141 + true + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + msvc-2017-UWP_TemporaryKey.pfx + + + + d2d1.lib; d3d11.lib; dxgi.lib; windowscodecs.lib; dwrite.lib; dxguid.lib; %(AdditionalDependencies) + %(AdditionalLibraryDirectories); $(VCInstallDir)\lib\store\arm; $(VCInstallDir)\lib\arm + /nodefaultlib:vccorlibd /nodefaultlib:msvcrtd vccorlibd.lib msvcrtd.lib %(AdditionalOptions) + + + + + $(MSBuildProjectDirectory);$(MSBuildProjectDirectory)\..\..\..\;$(MSBuildProjectDirectory)\..\..\..\deps\rcheevos\include;$(MSBuildProjectDirectory)\..\..\..\deps\zlib;$(MSBuildProjectDirectory)\..\..\..\libretro-common\include;$(MSBuildProjectDirectory)\..\..\..\deps;$(MSBuildProjectDirectory)\..\..\..\deps\glslang;$(MSBuildProjectDirectory)\..\..\..\deps\SPIRV-Cross;$(MSBuildProjectDirectory)\..\..\..\deps\stb;$(MSBuildProjectDirectory)\..\..\..\gfx\include;%(AdditionalIncludeDirectories) + /bigobj %(AdditionalOptions) + 4453;28204 + WIN32;HAVE_MAIN;HAVE_DYNAMIC;HAVE_XAUDIO2;RARCH_INTERNAL;HAVE_CC_RESAMPLER;HAVE_SLANG;HAVE_SPIRV_CROSS;HAVE_UPDATE_ASSETS;HAVE_D3D;HAVE_D3D11;ENABLE_HLSL;RC_DISABLE_LUA;HAVE_CHEEVOS;HAVE_RUNAHEAD;HAVE_GRIFFIN;HAVE_LANGEXTRA;HAVE_FBO;HAVE_ZLIB;HAVE_RPNG;HAVE_RJPEG;HAVE_RBMP;HAVE_RTGA;HAVE_IMAGEVIEWER;HAVE_XMB;HAVE_SHADERPIPELINE;WANT_ZLIB;_DEBUG;_WINDOWS;%(PreprocessorDefinitions);HAVE_XINPUT;HAVE_XINPUT2;HAVE_XAUDIO;HAVE_DIRECTX;HAVE_NETWORKING;HAVE_NETWORK_CMD;HAVE_NETPLAYDISCOVERY;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;__SSE__;__i686__;HAVE_OVERLAY;HAVE_RGUI;HAVE_MENU;HAVE_MATERIALUI;HAVE_LIBRETRODB;HAVE_STB_FONT;HAVE_STATIC_DUMMY;HAVE_STATIC_VIDEO_FILTERS;HAVE_STATIC_AUDIO_FILTERS + + + + + d2d1.lib; d3d11.lib; dxgi.lib; windowscodecs.lib; dwrite.lib; dxguid.lib; %(AdditionalDependencies) + %(AdditionalLibraryDirectories); $(VCInstallDir)\lib\store\arm; $(VCInstallDir)\lib\arm + /nodefaultlib:vccorlib /nodefaultlib:msvcrt vccorlib.lib msvcrt.lib %(AdditionalOptions) + + + + + $(MSBuildProjectDirectory);$(MSBuildProjectDirectory)\..\..\..\;$(MSBuildProjectDirectory)\..\..\..\deps\rcheevos\include;$(MSBuildProjectDirectory)\..\..\..\deps\zlib;$(MSBuildProjectDirectory)\..\..\..\libretro-common\include;$(MSBuildProjectDirectory)\..\..\..\deps;$(MSBuildProjectDirectory)\..\..\..\deps\glslang;$(MSBuildProjectDirectory)\..\..\..\deps\SPIRV-Cross;$(MSBuildProjectDirectory)\..\..\..\deps\stb;$(MSBuildProjectDirectory)\..\..\..\gfx\include;%(AdditionalIncludeDirectories) + /bigobj %(AdditionalOptions) + 4453;28204 + WIN32;HAVE_MAIN;HAVE_DYNAMIC;HAVE_XAUDIO2;RARCH_INTERNAL;HAVE_CC_RESAMPLER;HAVE_SLANG;HAVE_SPIRV_CROSS;HAVE_UPDATE_ASSETS;HAVE_D3D;HAVE_D3D11;ENABLE_HLSL;RC_DISABLE_LUA;HAVE_CHEEVOS;HAVE_RUNAHEAD;HAVE_GRIFFIN;HAVE_LANGEXTRA;HAVE_FBO;HAVE_ZLIB;HAVE_XMB;HAVE_SHADERPIPELINE;WANT_ZLIB;HAVE_RPNG;HAVE_RJPEG;HAVE_RBMP;HAVE_RTGA;HAVE_IMAGEVIEWER;NDEBUG;_WINDOWS;%(PreprocessorDefinitions);HAVE_XINPUT;HAVE_XINPUT2;HAVE_XAUDIO;HAVE_DIRECTX;HAVE_NETWORKING;HAVE_NETWORK_CMD;HAVE_NETPLAYDISCOVERY;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;__SSE__;__i686__;HAVE_OVERLAY;HAVE_MENU;HAVE_RGUI;HAVE_MATERIALUI;HAVE_LIBRETRODB;HAVE_STB_FONT;HAVE_STATIC_DUMMY;HAVE_STATIC_VIDEO_FILTERS;HAVE_STATIC_AUDIO_FILTERS + + + + + d2d1.lib; d3d11.lib; dxgi.lib; windowscodecs.lib; dwrite.lib; dxguid.lib; %(AdditionalDependencies) + %(AdditionalLibraryDirectories); $(VCInstallDir)\lib\store\arm64; $(VCInstallDir)\lib\arm64 + /nodefaultlib:vccorlibd /nodefaultlib:msvcrtd vccorlibd.lib msvcrtd.lib %(AdditionalOptions) + + + + + $(MSBuildProjectDirectory);$(MSBuildProjectDirectory)\..\..\..\;$(MSBuildProjectDirectory)\..\..\..\deps\rcheevos\include;$(MSBuildProjectDirectory)\..\..\..\deps\zlib;$(MSBuildProjectDirectory)\..\..\..\libretro-common\include;$(MSBuildProjectDirectory)\..\..\..\deps;$(MSBuildProjectDirectory)\..\..\..\deps\glslang;$(MSBuildProjectDirectory)\..\..\..\deps\SPIRV-Cross;$(MSBuildProjectDirectory)\..\..\..\deps\stb;$(MSBuildProjectDirectory)\..\..\..\gfx\include;%(AdditionalIncludeDirectories) + /bigobj %(AdditionalOptions) + 4453;28204 + WIN32;HAVE_MAIN;HAVE_DYNAMIC;HAVE_XAUDIO2;RARCH_INTERNAL;HAVE_CC_RESAMPLER;HAVE_SLANG;HAVE_SPIRV_CROSS;HAVE_UPDATE_ASSETS;HAVE_D3D;HAVE_D3D11;ENABLE_HLSL;RC_DISABLE_LUA;HAVE_CHEEVOS;HAVE_RUNAHEAD;HAVE_GRIFFIN;HAVE_LANGEXTRA;HAVE_FBO;HAVE_ZLIB;HAVE_RPNG;HAVE_RJPEG;HAVE_RBMP;HAVE_RTGA;HAVE_IMAGEVIEWER;HAVE_XMB;HAVE_SHADERPIPELINE;WANT_ZLIB;_DEBUG;_WINDOWS;%(PreprocessorDefinitions);HAVE_XINPUT;HAVE_XINPUT2;HAVE_XAUDIO;HAVE_DIRECTX;HAVE_NETWORKING;HAVE_NETWORK_CMD;HAVE_NETPLAYDISCOVERY;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;__SSE__;__i686__;HAVE_OVERLAY;HAVE_RGUI;HAVE_MENU;HAVE_MATERIALUI;HAVE_LIBRETRODB;HAVE_STB_FONT;HAVE_STATIC_DUMMY;HAVE_STATIC_VIDEO_FILTERS;HAVE_STATIC_AUDIO_FILTERS + + + + + d2d1.lib; d3d11.lib; dxgi.lib; windowscodecs.lib; dwrite.lib; dxguid.lib; %(AdditionalDependencies) + %(AdditionalLibraryDirectories); $(VCInstallDir)\lib\store\arm64; $(VCInstallDir)\lib\arm64 + /nodefaultlib:vccorlib /nodefaultlib:msvcrt vccorlib.lib msvcrt.lib %(AdditionalOptions) + + + + + $(MSBuildProjectDirectory);$(MSBuildProjectDirectory)\..\..\..\;$(MSBuildProjectDirectory)\..\..\..\deps\rcheevos\include;$(MSBuildProjectDirectory)\..\..\..\deps\zlib;$(MSBuildProjectDirectory)\..\..\..\libretro-common\include;$(MSBuildProjectDirectory)\..\..\..\deps;$(MSBuildProjectDirectory)\..\..\..\deps\glslang;$(MSBuildProjectDirectory)\..\..\..\deps\SPIRV-Cross;$(MSBuildProjectDirectory)\..\..\..\deps\stb;$(MSBuildProjectDirectory)\..\..\..\gfx\include;%(AdditionalIncludeDirectories) + /bigobj %(AdditionalOptions) + 4453;28204 + WIN32;HAVE_MAIN;HAVE_DYNAMIC;HAVE_XAUDIO2;RARCH_INTERNAL;HAVE_CC_RESAMPLER;HAVE_SLANG;HAVE_SPIRV_CROSS;HAVE_UPDATE_ASSETS;HAVE_D3D;HAVE_D3D11;ENABLE_HLSL;RC_DISABLE_LUA;HAVE_CHEEVOS;HAVE_RUNAHEAD;HAVE_GRIFFIN;HAVE_LANGEXTRA;HAVE_FBO;HAVE_ZLIB;HAVE_XMB;HAVE_SHADERPIPELINE;WANT_ZLIB;HAVE_RPNG;HAVE_RJPEG;HAVE_RBMP;HAVE_RTGA;HAVE_IMAGEVIEWER;NDEBUG;_WINDOWS;%(PreprocessorDefinitions);HAVE_XINPUT;HAVE_XINPUT2;HAVE_XAUDIO;HAVE_DIRECTX;HAVE_NETWORKING;HAVE_NETWORK_CMD;HAVE_NETPLAYDISCOVERY;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;__SSE__;__i686__;HAVE_OVERLAY;HAVE_MENU;HAVE_RGUI;HAVE_MATERIALUI;HAVE_LIBRETRODB;HAVE_STB_FONT;HAVE_STATIC_DUMMY;HAVE_STATIC_VIDEO_FILTERS;HAVE_STATIC_AUDIO_FILTERS + + + + + d2d1.lib; d3d11.lib; dxgi.lib; windowscodecs.lib; dwrite.lib; dxguid.lib; %(AdditionalDependencies) + %(AdditionalLibraryDirectories); $(VCInstallDir)\lib\store; $(VCInstallDir)\lib + /nodefaultlib:vccorlibd /nodefaultlib:msvcrtd vccorlibd.lib msvcrtd.lib %(AdditionalOptions) + + + + + $(MSBuildProjectDirectory);$(MSBuildProjectDirectory)\..\..\..\;$(MSBuildProjectDirectory)\..\..\..\deps\rcheevos\include;$(MSBuildProjectDirectory)\..\..\..\deps\zlib;$(MSBuildProjectDirectory)\..\..\..\libretro-common\include;$(MSBuildProjectDirectory)\..\..\..\deps;$(MSBuildProjectDirectory)\..\..\..\deps\glslang;$(MSBuildProjectDirectory)\..\..\..\deps\SPIRV-Cross;$(MSBuildProjectDirectory)\..\..\..\deps\stb;$(MSBuildProjectDirectory)\..\..\..\gfx\include;%(AdditionalIncludeDirectories) + /bigobj %(AdditionalOptions) + 4453;28204 + WIN32;HAVE_MAIN;HAVE_DYNAMIC;HAVE_XAUDIO2;RARCH_INTERNAL;HAVE_CC_RESAMPLER;HAVE_SLANG;HAVE_SPIRV_CROSS;HAVE_UPDATE_ASSETS;HAVE_D3D;HAVE_D3D11;ENABLE_HLSL;RC_DISABLE_LUA;HAVE_CHEEVOS;HAVE_RUNAHEAD;HAVE_GRIFFIN;HAVE_LANGEXTRA;HAVE_FBO;HAVE_ZLIB;HAVE_RPNG;HAVE_RJPEG;HAVE_RBMP;HAVE_RTGA;HAVE_IMAGEVIEWER;HAVE_XMB;HAVE_SHADERPIPELINE;WANT_ZLIB;_DEBUG;_WINDOWS;%(PreprocessorDefinitions);HAVE_XINPUT;HAVE_XINPUT2;HAVE_XAUDIO;HAVE_DIRECTX;HAVE_NETWORKING;HAVE_NETWORK_CMD;HAVE_NETPLAYDISCOVERY;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;__SSE__;__i686__;HAVE_OVERLAY;HAVE_RGUI;HAVE_MENU;HAVE_MATERIALUI;HAVE_LIBRETRODB;HAVE_STB_FONT;HAVE_STATIC_DUMMY;HAVE_STATIC_VIDEO_FILTERS;HAVE_STATIC_AUDIO_FILTERS + ProgramDatabase + + + + + d2d1.lib; d3d11.lib; dxgi.lib; windowscodecs.lib; dwrite.lib; dxguid.lib; %(AdditionalDependencies) + %(AdditionalLibraryDirectories); $(VCInstallDir)\lib\store; $(VCInstallDir)\lib + /nodefaultlib:vccorlib /nodefaultlib:msvcrt vccorlib.lib msvcrt.lib %(AdditionalOptions) + + + + + $(MSBuildProjectDirectory);$(MSBuildProjectDirectory)\..\..\..\;$(MSBuildProjectDirectory)\..\..\..\deps\rcheevos\include;$(MSBuildProjectDirectory)\..\..\..\deps\zlib;$(MSBuildProjectDirectory)\..\..\..\libretro-common\include;$(MSBuildProjectDirectory)\..\..\..\deps;$(MSBuildProjectDirectory)\..\..\..\deps\glslang;$(MSBuildProjectDirectory)\..\..\..\deps\SPIRV-Cross;$(MSBuildProjectDirectory)\..\..\..\deps\stb;$(MSBuildProjectDirectory)\..\..\..\gfx\include;%(AdditionalIncludeDirectories) + /bigobj %(AdditionalOptions) + 4453;28204 + WIN32;HAVE_MAIN;HAVE_DYNAMIC;HAVE_XAUDIO2;RARCH_INTERNAL;HAVE_CC_RESAMPLER;HAVE_SLANG;HAVE_SPIRV_CROSS;HAVE_UPDATE_ASSETS;HAVE_D3D;HAVE_D3D11;ENABLE_HLSL;RC_DISABLE_LUA;HAVE_CHEEVOS;HAVE_RUNAHEAD;HAVE_GRIFFIN;HAVE_LANGEXTRA;HAVE_FBO;HAVE_ZLIB;HAVE_XMB;HAVE_SHADERPIPELINE;WANT_ZLIB;HAVE_RPNG;HAVE_RJPEG;HAVE_RBMP;HAVE_RTGA;HAVE_IMAGEVIEWER;NDEBUG;_WINDOWS;%(PreprocessorDefinitions);HAVE_XINPUT;HAVE_XINPUT2;HAVE_XAUDIO;HAVE_DIRECTX;HAVE_NETWORKING;HAVE_NETWORK_CMD;HAVE_NETPLAYDISCOVERY;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;__SSE__;__i686__;HAVE_OVERLAY;HAVE_MENU;HAVE_RGUI;HAVE_MATERIALUI;HAVE_LIBRETRODB;HAVE_STB_FONT;HAVE_STATIC_DUMMY;HAVE_STATIC_VIDEO_FILTERS;HAVE_STATIC_AUDIO_FILTERS + + + + + d2d1.lib; d3d11.lib; dxgi.lib; windowscodecs.lib; dwrite.lib; dxguid.lib; %(AdditionalDependencies) + %(AdditionalLibraryDirectories); $(VCInstallDir)\lib\store\amd64; $(VCInstallDir)\lib\amd64 + /nodefaultlib:vccorlibd /nodefaultlib:msvcrtd vccorlibd.lib msvcrtd.lib %(AdditionalOptions) + + + + + $(MSBuildProjectDirectory);$(MSBuildProjectDirectory)\..\..\..\;$(MSBuildProjectDirectory)\..\..\..\deps\rcheevos\include;$(MSBuildProjectDirectory)\..\..\..\deps\zlib;$(MSBuildProjectDirectory)\..\..\..\libretro-common\include;$(MSBuildProjectDirectory)\..\..\..\deps;$(MSBuildProjectDirectory)\..\..\..\deps\glslang;$(MSBuildProjectDirectory)\..\..\..\deps\SPIRV-Cross;$(MSBuildProjectDirectory)\..\..\..\deps\stb;$(MSBuildProjectDirectory)\..\..\..\gfx\include;%(AdditionalIncludeDirectories) + /bigobj %(AdditionalOptions) + 4453;28204 + WIN32;HAVE_MAIN;HAVE_DYNAMIC;HAVE_XAUDIO2;RARCH_INTERNAL;HAVE_CC_RESAMPLER;HAVE_SLANG;HAVE_SPIRV_CROSS;HAVE_UPDATE_ASSETS;HAVE_D3D;HAVE_D3D11;ENABLE_HLSL;RC_DISABLE_LUA;HAVE_CHEEVOS;HAVE_RUNAHEAD;HAVE_GRIFFIN;HAVE_LANGEXTRA;HAVE_FBO;HAVE_ZLIB;HAVE_RPNG;HAVE_RJPEG;HAVE_RBMP;HAVE_RTGA;HAVE_IMAGEVIEWER;HAVE_XMB;HAVE_SHADERPIPELINE;WANT_ZLIB;_DEBUG;_WINDOWS;%(PreprocessorDefinitions);HAVE_XINPUT;HAVE_XINPUT2;HAVE_XAUDIO;HAVE_DIRECTX;HAVE_NETWORKING;HAVE_NETWORK_CMD;HAVE_NETPLAYDISCOVERY;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;__SSE__;__i686__;HAVE_OVERLAY;HAVE_RGUI;HAVE_MENU;HAVE_MATERIALUI;HAVE_LIBRETRODB;HAVE_STB_FONT;HAVE_STATIC_DUMMY;HAVE_STATIC_VIDEO_FILTERS;HAVE_STATIC_AUDIO_FILTERS + ProgramDatabase + + + + + d2d1.lib; d3d11.lib; dxgi.lib; windowscodecs.lib; dwrite.lib; dxguid.lib; %(AdditionalDependencies) + %(AdditionalLibraryDirectories); $(VCInstallDir)\lib\store\amd64; $(VCInstallDir)\lib\amd64 + /nodefaultlib:vccorlib /nodefaultlib:msvcrt vccorlib.lib msvcrt.lib %(AdditionalOptions) + + + + + $(MSBuildProjectDirectory);$(MSBuildProjectDirectory)\..\..\..\;$(MSBuildProjectDirectory)\..\..\..\deps\rcheevos\include;$(MSBuildProjectDirectory)\..\..\..\deps\zlib;$(MSBuildProjectDirectory)\..\..\..\libretro-common\include;$(MSBuildProjectDirectory)\..\..\..\deps;$(MSBuildProjectDirectory)\..\..\..\deps\glslang;$(MSBuildProjectDirectory)\..\..\..\deps\SPIRV-Cross;$(MSBuildProjectDirectory)\..\..\..\deps\stb;$(MSBuildProjectDirectory)\..\..\..\gfx\include;%(AdditionalIncludeDirectories) + /bigobj %(AdditionalOptions) + 4453;28204 + WIN32;HAVE_MAIN;HAVE_DYNAMIC;HAVE_XAUDIO2;RARCH_INTERNAL;HAVE_CC_RESAMPLER;HAVE_SLANG;HAVE_SPIRV_CROSS;HAVE_UPDATE_ASSETS;HAVE_D3D;HAVE_D3D11;ENABLE_HLSL;RC_DISABLE_LUA;HAVE_CHEEVOS;HAVE_RUNAHEAD;HAVE_GRIFFIN;HAVE_LANGEXTRA;HAVE_FBO;HAVE_ZLIB;HAVE_XMB;HAVE_SHADERPIPELINE;WANT_ZLIB;HAVE_RPNG;HAVE_RJPEG;HAVE_RBMP;HAVE_RTGA;HAVE_IMAGEVIEWER;NDEBUG;_WINDOWS;%(PreprocessorDefinitions);HAVE_XINPUT;HAVE_XINPUT2;HAVE_XAUDIO;HAVE_DIRECTX;HAVE_NETWORKING;HAVE_NETWORK_CMD;HAVE_NETPLAYDISCOVERY;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;__SSE__;__i686__;HAVE_OVERLAY;HAVE_MENU;HAVE_RGUI;HAVE_MATERIALUI;HAVE_LIBRETRODB;HAVE_STB_FONT;HAVE_STATIC_DUMMY;HAVE_STATIC_VIDEO_FILTERS;HAVE_STATIC_AUDIO_FILTERS + + + + + + + + + + + + + + false + false + false + false + false + false + false + false + + + + + + + + + Designer + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + + true + + + true + + + true + + + true + + + true + + + + + + + + + + + + + \ No newline at end of file diff --git a/pkg/msvc/msvc-2017-UWP/RetroArch-msvc2017-UWP.vcxproj.filters b/pkg/msvc/msvc-2017-UWP/RetroArch-msvc2017-UWP.vcxproj.filters new file mode 100644 index 0000000000..a133f33c90 --- /dev/null +++ b/pkg/msvc/msvc-2017-UWP/RetroArch-msvc2017-UWP.vcxproj.filters @@ -0,0 +1,280 @@ + + + + + {1246fa09-e114-4a52-88c2-657b2f13d9fb} + + + {32de9679-6494-4933-afa2-430fd975e506} + + + {73676219-cf54-454f-b6fa-9b192c1454f8} + + + + + {bf1e643d-c518-4a77-a355-ae8a93efc18b} + + + {ba77ad30-f536-4bb8-ad9d-2870e8a9bd39} + + + + + assets + + + assets + + + assets + + + assets + + + assets + + + assets + + + assets + + + + + + + + + core_deps + + + cores + + + cores + + + core_deps + + + core_deps + + + core_deps + + + core_deps + + + core_deps + + + core_deps + + + core_deps + + + core_deps + + + core_deps + + + core_deps + + + core_deps + + + core_deps + + + core_deps + + + core_deps + + + core_deps + + + core_deps + + + core_deps + + + core_deps + + + core_deps + + + core_deps + + + core_deps + + + core_deps + + + core_deps + + + core_deps + + + core_deps + + + core_deps + + + core_deps + + + core_deps + + + core_deps + + + core_deps + + + core_deps + + + core_deps + + + core_deps + + + core_deps + + + core_deps + + + core_deps + + + core_deps + + + core_deps + + + core_deps + + + core_deps + + + core_deps + + + core_deps + + + core_deps + + + core_deps + + + core_deps + + + core_deps + + + core_deps + + + core_deps + + + core_deps + + + core_deps + + + core_deps + + + core_deps + + + core_deps + + + core_deps + + + core_deps + + + core_deps + + + core_deps + + + core_deps + + + core_deps + + + core_deps + + + core_deps + + + core_deps + + + core_deps + + + core_deps + + + core_deps + + + core_deps + + + core_deps + + + + + uwp + + + uwp + + + + + griffin + + + griffin + + + uwp + + + \ No newline at end of file diff --git a/pkg/msvc/msvc-2017-UWP/msvc-2017-UWP_TemporaryKey.pfx b/pkg/msvc/msvc-2017-UWP/msvc-2017-UWP_TemporaryKey.pfx new file mode 100644 index 0000000000000000000000000000000000000000..ff20a54c343d4c6e0aa5bdb5ed3b80e4c09bec18 GIT binary patch literal 2504 zcmZXUc{tQ<7sr1y#xSOwaYc&vU)k`^P!=_xm~L+}HijeUNxq7Z}8V#KYpDFqvedDt-u;4Ub<)YMn{C4$GNuP-}<_7ERP$*HW zu`zK@_Bxc#fq_J5g1R*f`f=CT;C+o!gi4etM*`XY_FB8A@-*CtMkQxVyDqDmCi(xeitv6A0$_#-B}O>9p# zj8}qu?Y^oXQwVMV>tY*YQXrRQO!e}sHZeWD2IKCi(!h)`!*8bLoq2DA{+^xw%uxm% z)aZbvB}WI5^;fB_>OSgM9($}CiWK$SRX>cfaHVS&fqQ z;*OE$Pk9fI$)(<&3G39VD2Ry8+J(Tn)+$9xN&W!%e`NGF$iINiDq+dylc6cKJg>3mWaf|7pk*5s}TGFio>;H5hxia_QIu+F)Xf(k`)3 zS7o`1d-_Y=0h>ja`cgV)_gMIachBx&dP-NUQ&Q0-EN7dPJNqYP_FHpEPA6L^L(GJ0 zt5aZj31|NN3lYY(7AAv-R$0*0YLeM7Bl zO!5-VHxWE6p^pR{unMQR({G}P1b2hPUmhpnWgl4Zn9%LmM|KXWI#<*UUhvkPhnmHg z)~$akw7-5S&Np>nV!mQ)Q)?>tmz4rg+5S4uG!)JpkU{Q&^4)dQ1943%ir=6Fm*Ry^ zeHpuv?82{+R7H%fTd>tJrF=D|fnN)B~3Y#`!tk*AKL}dRyHAlm`@JY)(Icw`> zYIh*aBX}b?OjV49FU|Qp>-}TVe}10TYtaf1B^tZX#Yb{NT<%HQAbWCoC#)n6u+9%lY0>(!)8LYIozys z^vO`qj^WExPpEKRRZMt~Gg|Gblt{)KLtZZg8t$Aproe{2xu;-5W+Mt43 zKnzE$W@FaQVRrp4na)-8Uc-oNqq?Uf!EcK0$EBa&8`=I9`@v~wL34w#jI%e#l z8mJ%AJUEda?_uiUg`g86JBBkO{TnLVi!VZ+&Zbo4Y`au&VdTP@Qyt@;6|DF)kzX3w zPmEED?KX}cF1Rirn?BIZZ ztZYCe$-e9m+&h2HSeSI(G^CHf+M;JGnB~QRxrMWp_y#f|NW40PRkzQoBJMg;1K1a2 zbujl#_yq9E?kMLj#Sl<#ZCoZIMvjT=14lr)uS}93Oixt>`F?A-r$Fqh?$@$E&7F8g zV{f9VBpsZXU`9cM&{W;*T+GB|D6<73uYjko+ymE$4g4i1E!aLM{2l%VQTg){#+syd z#5~Fu`{crnKjs>Ac@_j*6f}~(!MJa7xe7AyO)eSbnUT&v3MCJ99X~#H^io*enc68r z)oaQ=o`K_DdtASi9rfv9Nv(7VFfN^rt3sul*J;aoFSt>@;A3gy5@F99MFfQkJ%gH< z#l&;=lus9lsJ!ElYqvY4$=8HI+RKrHf;B>9u`ZkqP;b-ZckAy?#D2Q`%i9b&da-|c5N*VaI^{w4Q&%ke$ zRukdh+~NWc*yQ@Lbzl7s*J}k>(rGeD1{KTcPvJXP#_k-5sguiI%7G7n&}x0hfxjv&KY>T zmzUO<4P#_WrkKCd8B}s`mPa9;qM8@{H-kI3xtB{+_sugF|J<4. + */ + +#ifndef _UWP_FUNC_H +#define _UWP_FUNC_H + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +extern char uwp_dir_install[PATH_MAX_LENGTH]; +extern char uwp_dir_data[PATH_MAX_LENGTH]; +extern char uwp_device_family[128]; + +void* uwp_get_corewindow(void); + +#ifdef __cplusplus +} +#endif + +#endif _UWP_FUNC_H diff --git a/uwp/uwp_main.cpp b/uwp/uwp_main.cpp new file mode 100644 index 0000000000..7e3f132228 --- /dev/null +++ b/uwp/uwp_main.cpp @@ -0,0 +1,479 @@ +/* RetroArch - A frontend for libretro. + * Copyright (C) 2018 - Krzysztof Haładyn + * + * RetroArch is free software: you can redistribute it and/or modify it under the terms + * of the GNU General Public License as published by the Free Software Found- + * ation, either version 3 of the License, or (at your option) any later version. + * + * RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + * PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with RetroArch. + * If not, see . + */ + +#include "uwp_main.h" +#include +#include +#include +#include +#include +#include +#include +#include "uwp_func.h" + +#include + +using namespace RetroArchUWP; + +using namespace concurrency; +using namespace Windows::ApplicationModel; +using namespace Windows::ApplicationModel::Core; +using namespace Windows::ApplicationModel::Activation; +using namespace Windows::UI::Core; +using namespace Windows::UI::Input; +using namespace Windows::UI::ViewManagement; +using namespace Windows::System; +using namespace Windows::System::Profile; +using namespace Windows::Foundation; +using namespace Windows::Graphics::Display; + +char uwp_dir_install[PATH_MAX_LENGTH]; +char uwp_dir_data[PATH_MAX_LENGTH]; +char uwp_device_family[128]; + +// Some keys are unavailable in the VirtualKey enum (wtf) but the old-style constants work +const struct rarch_key_map rarch_key_map_uwp[] = { + { (unsigned int)VirtualKey::Back, RETROK_BACKSPACE }, + { (unsigned int)VirtualKey::Tab, RETROK_TAB }, + { (unsigned int)VirtualKey::Clear, RETROK_CLEAR }, + { (unsigned int)VirtualKey::Enter, RETROK_RETURN }, + { (unsigned int)VirtualKey::Pause, RETROK_PAUSE }, + { (unsigned int)VirtualKey::Escape, RETROK_ESCAPE }, + { (unsigned int)VirtualKey::ModeChange, RETROK_MODE }, + { (unsigned int)VirtualKey::Space, RETROK_SPACE }, + { (unsigned int)VirtualKey::PageUp, RETROK_PAGEUP }, + { (unsigned int)VirtualKey::PageDown, RETROK_PAGEDOWN }, + { (unsigned int)VirtualKey::End, RETROK_END }, + { (unsigned int)VirtualKey::Home, RETROK_HOME }, + { (unsigned int)VirtualKey::Left, RETROK_LEFT }, + { (unsigned int)VirtualKey::Up, RETROK_UP }, + { (unsigned int)VirtualKey::Right, RETROK_RIGHT }, + { (unsigned int)VirtualKey::Down, RETROK_DOWN }, + { (unsigned int)VirtualKey::Print, RETROK_PRINT }, + { (unsigned int)VirtualKey::Insert, RETROK_INSERT }, + { (unsigned int)VirtualKey::Delete, RETROK_DELETE }, + { (unsigned int)VirtualKey::Help, RETROK_HELP }, + { (unsigned int)VirtualKey::Number0, RETROK_0 }, + { (unsigned int)VirtualKey::Number1, RETROK_1 }, + { (unsigned int)VirtualKey::Number2, RETROK_2 }, + { (unsigned int)VirtualKey::Number3, RETROK_3 }, + { (unsigned int)VirtualKey::Number4, RETROK_4 }, + { (unsigned int)VirtualKey::Number5, RETROK_5 }, + { (unsigned int)VirtualKey::Number6, RETROK_6 }, + { (unsigned int)VirtualKey::Number7, RETROK_7 }, + { (unsigned int)VirtualKey::Number8, RETROK_8 }, + { (unsigned int)VirtualKey::Number9, RETROK_9 }, + { (unsigned int)VirtualKey::A, RETROK_a }, + { (unsigned int)VirtualKey::B, RETROK_b }, + { (unsigned int)VirtualKey::C, RETROK_c }, + { (unsigned int)VirtualKey::D, RETROK_d }, + { (unsigned int)VirtualKey::E, RETROK_e }, + { (unsigned int)VirtualKey::F, RETROK_f }, + { (unsigned int)VirtualKey::G, RETROK_g }, + { (unsigned int)VirtualKey::H, RETROK_h }, + { (unsigned int)VirtualKey::I, RETROK_i }, + { (unsigned int)VirtualKey::J, RETROK_j }, + { (unsigned int)VirtualKey::K, RETROK_k }, + { (unsigned int)VirtualKey::L, RETROK_l }, + { (unsigned int)VirtualKey::M, RETROK_m }, + { (unsigned int)VirtualKey::N, RETROK_n }, + { (unsigned int)VirtualKey::O, RETROK_o }, + { (unsigned int)VirtualKey::P, RETROK_p }, + { (unsigned int)VirtualKey::Q, RETROK_q }, + { (unsigned int)VirtualKey::R, RETROK_r }, + { (unsigned int)VirtualKey::S, RETROK_s }, + { (unsigned int)VirtualKey::T, RETROK_t }, + { (unsigned int)VirtualKey::U, RETROK_u }, + { (unsigned int)VirtualKey::V, RETROK_v }, + { (unsigned int)VirtualKey::W, RETROK_w }, + { (unsigned int)VirtualKey::X, RETROK_x }, + { (unsigned int)VirtualKey::Y, RETROK_y }, + { (unsigned int)VirtualKey::Z, RETROK_z }, + { (unsigned int)VirtualKey::LeftWindows, RETROK_LSUPER }, + { (unsigned int)VirtualKey::RightWindows, RETROK_RSUPER }, + { (unsigned int)VirtualKey::Application, RETROK_MENU }, + { (unsigned int)VirtualKey::NumberPad0, RETROK_KP0 }, + { (unsigned int)VirtualKey::NumberPad1, RETROK_KP1 }, + { (unsigned int)VirtualKey::NumberPad2, RETROK_KP2 }, + { (unsigned int)VirtualKey::NumberPad3, RETROK_KP3 }, + { (unsigned int)VirtualKey::NumberPad4, RETROK_KP4 }, + { (unsigned int)VirtualKey::NumberPad5, RETROK_KP5 }, + { (unsigned int)VirtualKey::NumberPad6, RETROK_KP6 }, + { (unsigned int)VirtualKey::NumberPad7, RETROK_KP7 }, + { (unsigned int)VirtualKey::NumberPad8, RETROK_KP8 }, + { (unsigned int)VirtualKey::NumberPad9, RETROK_KP9 }, + { (unsigned int)VirtualKey::Multiply, RETROK_KP_MULTIPLY }, + { (unsigned int)VirtualKey::Add, RETROK_KP_PLUS }, + { (unsigned int)VirtualKey::Subtract, RETROK_KP_MINUS }, + { (unsigned int)VirtualKey::Decimal, RETROK_KP_PERIOD }, + { (unsigned int)VirtualKey::Divide, RETROK_KP_DIVIDE }, + { (unsigned int)VirtualKey::F1, RETROK_F1 }, + { (unsigned int)VirtualKey::F2, RETROK_F2 }, + { (unsigned int)VirtualKey::F3, RETROK_F3 }, + { (unsigned int)VirtualKey::F4, RETROK_F4 }, + { (unsigned int)VirtualKey::F5, RETROK_F5 }, + { (unsigned int)VirtualKey::F6, RETROK_F6 }, + { (unsigned int)VirtualKey::F7, RETROK_F7 }, + { (unsigned int)VirtualKey::F8, RETROK_F8 }, + { (unsigned int)VirtualKey::F9, RETROK_F9 }, + { (unsigned int)VirtualKey::F10, RETROK_F10 }, + { (unsigned int)VirtualKey::F11, RETROK_F11 }, + { (unsigned int)VirtualKey::F12, RETROK_F12 }, + { (unsigned int)VirtualKey::F13, RETROK_F13 }, + { (unsigned int)VirtualKey::F14, RETROK_F14 }, + { (unsigned int)VirtualKey::F15, RETROK_F15 }, + { (unsigned int)VirtualKey::NumberKeyLock, RETROK_NUMLOCK }, + { (unsigned int)VirtualKey::Scroll, RETROK_SCROLLOCK }, + { (unsigned int)VirtualKey::LeftShift, RETROK_LSHIFT }, + { (unsigned int)VirtualKey::RightShift, RETROK_RSHIFT }, + { (unsigned int)VirtualKey::LeftControl, RETROK_LCTRL }, + { (unsigned int)VirtualKey::RightControl, RETROK_RCTRL }, + { (unsigned int)VirtualKey::LeftMenu, RETROK_LALT }, + { (unsigned int)VirtualKey::RightMenu, RETROK_RALT }, + { VK_RETURN, RETROK_KP_ENTER }, + { (unsigned int)VirtualKey::CapitalLock, RETROK_CAPSLOCK }, + { VK_OEM_1, RETROK_SEMICOLON }, + { VK_OEM_PLUS, RETROK_EQUALS }, + { VK_OEM_COMMA, RETROK_COMMA }, + { VK_OEM_MINUS, RETROK_MINUS }, + { VK_OEM_PERIOD, RETROK_PERIOD }, + { VK_OEM_2, RETROK_SLASH }, + { VK_OEM_3, RETROK_BACKQUOTE }, + { VK_OEM_4, RETROK_LEFTBRACKET }, + { VK_OEM_5, RETROK_BACKSLASH }, + { VK_OEM_6, RETROK_RIGHTBRACKET }, + { VK_OEM_7, RETROK_QUOTE }, + { 0, RETROK_UNKNOWN } +}; + +// The main function is only used to initialize our IFrameworkView class. +[Platform::MTAThread] +int main(Platform::Array^) +{ + Platform::String^ install_dir = Windows::ApplicationModel::Package::Current->InstalledLocation->Path + L"\\"; + wcstombs(uwp_dir_install, install_dir->Data(), PATH_MAX_LENGTH); + Platform::String^ data_dir = Windows::Storage::ApplicationData::Current->LocalFolder->Path + L"\\"; + wcstombs(uwp_dir_data, data_dir->Data(), PATH_MAX_LENGTH); + + wcstombs(uwp_device_family, AnalyticsInfo::VersionInfo->DeviceFamily->Data(), 128); + + RARCH_LOG("Data dir: %ls\n", data_dir->Data()); + RARCH_LOG("Install dir: %ls\n", install_dir->Data()); + + auto direct3DApplicationSource = ref new Direct3DApplicationSource(); + CoreApplication::Run(direct3DApplicationSource); + return 0; +} + +IFrameworkView^ Direct3DApplicationSource::CreateView() +{ + return ref new App(); +} + +App^ App::m_instance; + +App::App() : + m_initialized(false), + m_windowClosed(false), + m_windowVisible(true), + m_windowFocused(true), + m_windowResized(false) +{ + m_instance = this; +} + +// The first method called when the IFrameworkView is being created. +void App::Initialize(CoreApplicationView^ applicationView) +{ + // Register event handlers for app lifecycle. This example includes Activated, so that we + // can make the CoreWindow active and start rendering on the window. + applicationView->Activated += + ref new TypedEventHandler(this, &App::OnActivated); + + CoreApplication::Suspending += + ref new EventHandler(this, &App::OnSuspending); + + CoreApplication::Resuming += + ref new EventHandler(this, &App::OnResuming); +} + +// Called when the CoreWindow object is created (or re-created). +void App::SetWindow(CoreWindow^ window) +{ + window->SizeChanged += + ref new TypedEventHandler(this, &App::OnWindowSizeChanged); + + window->VisibilityChanged += + ref new TypedEventHandler(this, &App::OnVisibilityChanged); + + window->Activated += + ref new TypedEventHandler(this, &App::OnWindowActivated); + + window->Closed += + ref new TypedEventHandler(this, &App::OnWindowClosed); + + window->KeyDown += + ref new TypedEventHandler(this, &App::OnKeyDown); + + window->KeyUp += + ref new TypedEventHandler(this, &App::OnKeyUp); + + DisplayInformation^ currentDisplayInformation = DisplayInformation::GetForCurrentView(); + + currentDisplayInformation->DpiChanged += + ref new TypedEventHandler(this, &App::OnDpiChanged); + + currentDisplayInformation->OrientationChanged += + ref new TypedEventHandler(this, &App::OnOrientationChanged); + + DisplayInformation::DisplayContentsInvalidated += + ref new TypedEventHandler(this, &App::OnDisplayContentsInvalidated); + + Windows::UI::Core::SystemNavigationManager::GetForCurrentView()->BackRequested += + ref new EventHandler(this, &App::OnBackRequested); +} + +// Initializes scene resources, or loads a previously saved app state. +void App::Load(Platform::String^ entryPoint) +{ + int ret = rarch_main(NULL, NULL, NULL); + if (ret != 0) + { + RARCH_ERR("Init failed\n"); + CoreApplication::Exit(); + return; + } + input_keymaps_init_keyboard_lut(rarch_key_map_uwp); // TODO (krzys_h): move this to the input driver + m_initialized = true; +} + +// This method is called after the window becomes active. +void App::Run() +{ + if (!m_initialized) + { + RARCH_WARN("Initialization failed, so not running\n"); + return; + } + + bool x = false; + while (true) + { + CoreWindow::GetForCurrentThread()->Dispatcher->ProcessEvents(CoreProcessEventsOption::ProcessAllIfPresent); + + unsigned sleep_ms = 0; + int ret = runloop_iterate(&sleep_ms); + + if (ret == 1 && sleep_ms > 0) + retro_sleep(sleep_ms); + + task_queue_check(); + + if (!x) + { + /* HACK: I have no idea why is this necessary but it is required to get proper scaling on Xbox * + * Perhaps PreferredLaunchViewSize is broken and we need to wait until the app starts to call TryResizeView */ + m_windowResized = true; + x = true; + } + + if (ret == -1) + break; + } +} + +// Required for IFrameworkView. +// Terminate events do not cause Uninitialize to be called. It will be called if your IFrameworkView +// class is torn down while the app is in the foreground. +void App::Uninitialize() +{ + main_exit(NULL); +} + +// Application lifecycle event handlers. + +void App::OnActivated(CoreApplicationView^ applicationView, IActivatedEventArgs^ args) +{ + // Run() won't start until the CoreWindow is activated. + CoreWindow::GetForCurrentThread()->Activate(); +} + +void App::OnSuspending(Platform::Object^ sender, SuspendingEventArgs^ args) +{ + // Save app state asynchronously after requesting a deferral. Holding a deferral + // indicates that the application is busy performing suspending operations. Be + // aware that a deferral may not be held indefinitely. After about five seconds, + // the app will be forced to exit. + SuspendingDeferral^ deferral = args->SuspendingOperation->GetDeferral(); + + create_task([this, deferral]() + { + // TODO: Maybe creating a save state here would be a good idea? + + deferral->Complete(); + }); +} + +void App::OnResuming(Platform::Object^ sender, Platform::Object^ args) +{ + // Restore any data or state that was unloaded on suspend. By default, data + // and state are persisted when resuming from suspend. Note that this event + // does not occur if the app was previously terminated. +} + +void App::OnBackRequested(Platform::Object^ sender, Windows::UI::Core::BackRequestedEventArgs^ args) +{ + /* Prevent the B controller button on Xbox One from quitting the app */ + args->Handled = true; +} + +// Window event handlers. + +void App::OnWindowSizeChanged(CoreWindow^ sender, WindowSizeChangedEventArgs^ args) +{ + m_windowResized = true; +} + +void App::OnVisibilityChanged(CoreWindow^ sender, VisibilityChangedEventArgs^ args) +{ + m_windowVisible = args->Visible; +} + +void App::OnWindowActivated(CoreWindow^ sender, WindowActivatedEventArgs^ args) +{ + m_windowFocused = args->WindowActivationState != CoreWindowActivationState::Deactivated; +} + +void App::OnKeyDown(CoreWindow^ sender, KeyEventArgs^ args) +{ + OnKey(sender, args, true); +} + +void App::OnKeyUp(CoreWindow^ sender, KeyEventArgs^ args) +{ + OnKey(sender, args, false); +} + +void App::OnKey(CoreWindow^ sender, KeyEventArgs^ args, bool down) +{ + uint16_t mod = 0; + if ((sender->GetKeyState(VirtualKey::Shift) & CoreVirtualKeyStates::Locked) == CoreVirtualKeyStates::Locked) + mod |= RETROKMOD_SHIFT; + if ((sender->GetKeyState(VirtualKey::Control) & CoreVirtualKeyStates::Locked) == CoreVirtualKeyStates::Locked) + mod |= RETROKMOD_CTRL; + if ((sender->GetKeyState(VirtualKey::Menu) & CoreVirtualKeyStates::Locked) == CoreVirtualKeyStates::Locked) + mod |= RETROKMOD_ALT; + if ((sender->GetKeyState(VirtualKey::CapitalLock) & CoreVirtualKeyStates::Locked) == CoreVirtualKeyStates::Locked) + mod |= RETROKMOD_CAPSLOCK; + if ((sender->GetKeyState(VirtualKey::Scroll) & CoreVirtualKeyStates::Locked) == CoreVirtualKeyStates::Locked) + mod |= RETROKMOD_SCROLLOCK; + if ((sender->GetKeyState(VirtualKey::LeftWindows) & CoreVirtualKeyStates::Locked) == CoreVirtualKeyStates::Locked || + (sender->GetKeyState(VirtualKey::RightWindows) & CoreVirtualKeyStates::Locked) == CoreVirtualKeyStates::Locked) + mod |= RETROKMOD_META; + + unsigned keycode = input_keymaps_translate_keysym_to_rk((unsigned)args->VirtualKey); + + input_keyboard_event(down, keycode, 0, mod, RETRO_DEVICE_KEYBOARD); +} + +void App::OnWindowClosed(CoreWindow^ sender, CoreWindowEventArgs^ args) +{ + m_windowClosed = true; +} + +// DisplayInformation event handlers. + +void App::OnDpiChanged(DisplayInformation^ sender, Object^ args) +{ + m_windowResized = true; +} + +void App::OnOrientationChanged(DisplayInformation^ sender, Object^ args) +{ + m_windowResized = true; +} + +void App::OnDisplayContentsInvalidated(DisplayInformation^ sender, Object^ args) +{ + // Probably can be ignored? +} + +// Taken from DirectX UWP samples - on Xbox, everything is scaled 200% so getting the DPI calculation correct is crucial +static inline float ConvertDipsToPixels(float dips, float dpi) +{ + static const float dipsPerInch = 96.0f; + return floorf(dips * dpi / dipsPerInch + 0.5f); +} + +// Implement UWP equivalents of various win32_* functions +extern "C" { + + bool win32_has_focus(void) + { + return App::GetInstance()->IsWindowFocused(); + } + + bool win32_set_video_mode(void *data, unsigned width, unsigned height, bool fullscreen) + { + if (App::GetInstance()->IsInitialized()) + { + if (fullscreen != ApplicationView::GetForCurrentView()->IsFullScreenMode) + { + if (fullscreen) + ApplicationView::GetForCurrentView()->TryEnterFullScreenMode(); + else + ApplicationView::GetForCurrentView()->ExitFullScreenMode(); + } + ApplicationView::GetForCurrentView()->TryResizeView(Size(width, height)); + } + else + { + /* In case the window is not activated yet, TryResizeView will fail and we have to set the initial parameters instead */ + /* Note that these are preserved after restarting the app and used for the UWP splash screen size (!), so they should be set only during init and not changed afterwards */ + ApplicationView::PreferredLaunchViewSize = Size(width, height); + ApplicationView::PreferredLaunchWindowingMode = fullscreen ? ApplicationViewWindowingMode::FullScreen : ApplicationViewWindowingMode::PreferredLaunchViewSize; + } + + /* Setting the window size may sometimes fail "because UWP" + * (i.e. we are on device with no windows, or Windows sandbox decides the window can't be that small) + * so in case resizing fails we just send a resized event back to RetroArch with old size + * (and report success because otherwise it bails out hard about failing to set video mode) + */ + App::GetInstance()->SetWindowResized(); + return true; + } + + void win32_show_cursor(bool state) + { + CoreWindow::GetForCurrentThread()->PointerCursor = state ? ref new CoreCursor(CoreCursorType::Arrow, 0) : nullptr; + } + + void win32_check_window(bool *quit, bool *resize, unsigned *width, unsigned *height) + { + *quit = App::GetInstance()->IsWindowClosed(); + *resize = App::GetInstance()->CheckWindowResized(); + if (*resize) + { + float dpi = DisplayInformation::GetForCurrentView()->LogicalDpi; + *width = ConvertDipsToPixels(CoreWindow::GetForCurrentThread()->Bounds.Width, dpi); + *height = ConvertDipsToPixels(CoreWindow::GetForCurrentThread()->Bounds.Height, dpi); + } + } + + void* uwp_get_corewindow(void) + { + return (void*)CoreWindow::GetForCurrentThread(); + } +} diff --git a/uwp/uwp_main.h b/uwp/uwp_main.h new file mode 100644 index 0000000000..9d359e6e1a --- /dev/null +++ b/uwp/uwp_main.h @@ -0,0 +1,82 @@ +/* RetroArch - A frontend for libretro. + * Copyright (C) 2018 - Krzysztof Haładyn + * + * RetroArch is free software: you can redistribute it and/or modify it under the terms + * of the GNU General Public License as published by the Free Software Found- + * ation, either version 3 of the License, or (at your option) any later version. + * + * RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + * PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with RetroArch. + * If not, see . + */ + +#pragma once + +#include "uwp_main.h" + +namespace RetroArchUWP +{ + // Main entry point for our app. Connects the app with the Windows shell and handles application lifecycle events. + ref class App sealed : public Windows::ApplicationModel::Core::IFrameworkView + { + public: + App(); + + // IFrameworkView methods. + virtual void Initialize(Windows::ApplicationModel::Core::CoreApplicationView^ applicationView); + virtual void SetWindow(Windows::UI::Core::CoreWindow^ window); + virtual void Load(Platform::String^ entryPoint); + virtual void Run(); + virtual void Uninitialize(); + + protected: + // Application lifecycle event handlers. + void OnActivated(Windows::ApplicationModel::Core::CoreApplicationView^ applicationView, Windows::ApplicationModel::Activation::IActivatedEventArgs^ args); + void OnSuspending(Platform::Object^ sender, Windows::ApplicationModel::SuspendingEventArgs^ args); + void OnResuming(Platform::Object^ sender, Platform::Object^ args); + + void OnBackRequested(Platform::Object^ sender, Windows::UI::Core::BackRequestedEventArgs^ args); + + // Window event handlers. + void OnWindowSizeChanged(Windows::UI::Core::CoreWindow^ sender, Windows::UI::Core::WindowSizeChangedEventArgs^ args); + void OnVisibilityChanged(Windows::UI::Core::CoreWindow^ sender, Windows::UI::Core::VisibilityChangedEventArgs^ args); + void OnWindowClosed(Windows::UI::Core::CoreWindow^ sender, Windows::UI::Core::CoreWindowEventArgs^ args); + void OnWindowActivated(Windows::UI::Core::CoreWindow^ sender, Windows::UI::Core::WindowActivatedEventArgs^ args); + void OnKeyDown(Windows::UI::Core::CoreWindow^ sender, Windows::UI::Core::KeyEventArgs^ args); + void OnKeyUp(Windows::UI::Core::CoreWindow^ sender, Windows::UI::Core::KeyEventArgs^ args); + + // DisplayInformation event handlers. + void OnDpiChanged(Windows::Graphics::Display::DisplayInformation^ sender, Platform::Object^ args); + void OnOrientationChanged(Windows::Graphics::Display::DisplayInformation^ sender, Platform::Object^ args); + void OnDisplayContentsInvalidated(Windows::Graphics::Display::DisplayInformation^ sender, Platform::Object^ args); + + public: + bool IsInitialized() { return m_initialized; } + bool IsWindowClosed() { return m_windowClosed; } + bool IsWindowVisible() { return m_windowVisible; } + bool IsWindowFocused() { return m_windowFocused; } + bool CheckWindowResized() { bool resized = m_windowResized; m_windowResized = false; return resized; } + void SetWindowResized() { m_windowResized = true; } + static App^ GetInstance() { return m_instance; } + + private: + void OnKey(Windows::UI::Core::CoreWindow^ sender, Windows::UI::Core::KeyEventArgs^ args, bool down); + + private: + bool m_initialized; + bool m_windowClosed; + bool m_windowVisible; + bool m_windowFocused; + bool m_windowResized; + static App^ m_instance; + }; +} + +ref class Direct3DApplicationSource sealed : Windows::ApplicationModel::Core::IFrameworkViewSource +{ +public: + virtual Windows::ApplicationModel::Core::IFrameworkView^ CreateView(); +}; diff --git a/verbosity.c b/verbosity.c index 9db900e8e4..7a9cfccbd5 100644 --- a/verbosity.c +++ b/verbosity.c @@ -37,6 +37,11 @@ #include #endif +#if _WIN32 +#define WIN32_LEAN_AND_MEAN +#include +#endif + #include #include #include @@ -60,7 +65,11 @@ * will write to this file. */ static FILE *log_file_fp = NULL; static void* log_file_buf = NULL; +#if _DEBUG +static bool main_verbosity = true; +#else static bool main_verbosity = false; +#endif static bool log_file_initialized = false; #ifdef NXLINK @@ -193,7 +202,7 @@ void RARCH_LOG_V(const char *tag, const char *fmt, va_list ap) #else { -#ifdef HAVE_QT +#if defined(HAVE_QT) || defined(__WINRT__) char buffer[1024]; #endif #ifdef HAVE_FILE_LOGGER @@ -202,7 +211,7 @@ void RARCH_LOG_V(const char *tag, const char *fmt, va_list ap) FILE *fp = stderr; #endif -#ifdef HAVE_QT +#if defined(HAVE_QT) || defined(__WINRT__) buffer[0] = '\0'; vsnprintf(buffer, sizeof(buffer), fmt, ap); @@ -212,7 +221,13 @@ void RARCH_LOG_V(const char *tag, const char *fmt, va_list ap) fflush(fp); } +#if defined(HAVE_QT) ui_companion_driver_log_msg(buffer); +#endif + +#if defined(__WINRT__) + OutputDebugStringA(buffer); +#endif #else #if defined(NXLINK) && !defined(HAVE_FILE_LOGGER) if (nxlink_connected) From 6038060cd7e74df4cb36c50460ce9b9654c1281c Mon Sep 17 00:00:00 2001 From: krzys-h Date: Fri, 28 Dec 2018 19:22:13 +0100 Subject: [PATCH 2/5] Update appx manifest and icons These were generated using Visual Studio icon generation tools --- .../Assets/LargeTile.scale-100.png | Bin 0 -> 5183 bytes .../Assets/LargeTile.scale-200.png | Bin 0 -> 10373 bytes .../Assets/LargeTile.scale-400.png | Bin 0 -> 24747 bytes .../Assets/LockScreenLogo.scale-200.png | Bin 1430 -> 0 bytes .../Assets/SmallTile.scale-100.png | Bin 0 -> 1425 bytes .../Assets/SmallTile.scale-200.png | Bin 0 -> 2535 bytes .../Assets/SmallTile.scale-400.png | Bin 0 -> 4838 bytes .../Assets/SplashScreen.scale-100.png | Bin 0 -> 9276 bytes .../Assets/SplashScreen.scale-200.png | Bin 7700 -> 20707 bytes .../Assets/SplashScreen.scale-400.png | Bin 0 -> 49647 bytes .../Assets/Square150x150Logo.scale-100.png | Bin 0 -> 2631 bytes .../Assets/Square150x150Logo.scale-200.png | Bin 2937 -> 4927 bytes .../Assets/Square150x150Logo.scale-400.png | Bin 0 -> 10016 bytes ...x44Logo.altform-unplated_targetsize-16.png | Bin 0 -> 398 bytes ...44Logo.altform-unplated_targetsize-256.png | Bin 0 -> 4285 bytes ...x44Logo.altform-unplated_targetsize-48.png | Bin 0 -> 942 bytes .../Assets/Square44x44Logo.scale-100.png | Bin 0 -> 1199 bytes .../Assets/Square44x44Logo.scale-200.png | Bin 1647 -> 2350 bytes .../Assets/Square44x44Logo.scale-400.png | Bin 0 -> 4312 bytes .../Assets/Square44x44Logo.targetsize-16.png | Bin 0 -> 541 bytes ...x44Logo.targetsize-24_altform-unplated.png | Bin 1255 -> 0 bytes .../Assets/Square44x44Logo.targetsize-256.png | Bin 0 -> 6051 bytes .../Assets/Square44x44Logo.targetsize-48.png | Bin 0 -> 1320 bytes pkg/msvc/msvc-2017-UWP/Assets/StoreLogo.png | Bin 1451 -> 0 bytes .../Assets/StoreLogo.scale-100.png | Bin 0 -> 1058 bytes .../Assets/StoreLogo.scale-200.png | Bin 0 -> 1886 bytes .../Assets/StoreLogo.scale-400.png | Bin 0 -> 3394 bytes .../Assets/Wide310x150Logo.scale-100.png | Bin 0 -> 4734 bytes .../Assets/Wide310x150Logo.scale-200.png | Bin 3204 -> 9276 bytes .../Assets/Wide310x150Logo.scale-400.png | Bin 0 -> 20707 bytes pkg/msvc/msvc-2017-UWP/Package.appxmanifest | 42 ++----- .../RetroArch-msvc2017-UWP.vcxproj | 40 +++++-- .../RetroArch-msvc2017-UWP.vcxproj.filters | 110 ++++++++++++++---- 33 files changed, 126 insertions(+), 66 deletions(-) create mode 100644 pkg/msvc/msvc-2017-UWP/Assets/LargeTile.scale-100.png create mode 100644 pkg/msvc/msvc-2017-UWP/Assets/LargeTile.scale-200.png create mode 100644 pkg/msvc/msvc-2017-UWP/Assets/LargeTile.scale-400.png delete mode 100644 pkg/msvc/msvc-2017-UWP/Assets/LockScreenLogo.scale-200.png create mode 100644 pkg/msvc/msvc-2017-UWP/Assets/SmallTile.scale-100.png create mode 100644 pkg/msvc/msvc-2017-UWP/Assets/SmallTile.scale-200.png create mode 100644 pkg/msvc/msvc-2017-UWP/Assets/SmallTile.scale-400.png create mode 100644 pkg/msvc/msvc-2017-UWP/Assets/SplashScreen.scale-100.png create mode 100644 pkg/msvc/msvc-2017-UWP/Assets/SplashScreen.scale-400.png create mode 100644 pkg/msvc/msvc-2017-UWP/Assets/Square150x150Logo.scale-100.png create mode 100644 pkg/msvc/msvc-2017-UWP/Assets/Square150x150Logo.scale-400.png create mode 100644 pkg/msvc/msvc-2017-UWP/Assets/Square44x44Logo.altform-unplated_targetsize-16.png create mode 100644 pkg/msvc/msvc-2017-UWP/Assets/Square44x44Logo.altform-unplated_targetsize-256.png create mode 100644 pkg/msvc/msvc-2017-UWP/Assets/Square44x44Logo.altform-unplated_targetsize-48.png create mode 100644 pkg/msvc/msvc-2017-UWP/Assets/Square44x44Logo.scale-100.png create mode 100644 pkg/msvc/msvc-2017-UWP/Assets/Square44x44Logo.scale-400.png create mode 100644 pkg/msvc/msvc-2017-UWP/Assets/Square44x44Logo.targetsize-16.png delete mode 100644 pkg/msvc/msvc-2017-UWP/Assets/Square44x44Logo.targetsize-24_altform-unplated.png create mode 100644 pkg/msvc/msvc-2017-UWP/Assets/Square44x44Logo.targetsize-256.png create mode 100644 pkg/msvc/msvc-2017-UWP/Assets/Square44x44Logo.targetsize-48.png delete mode 100644 pkg/msvc/msvc-2017-UWP/Assets/StoreLogo.png create mode 100644 pkg/msvc/msvc-2017-UWP/Assets/StoreLogo.scale-100.png create mode 100644 pkg/msvc/msvc-2017-UWP/Assets/StoreLogo.scale-200.png create mode 100644 pkg/msvc/msvc-2017-UWP/Assets/StoreLogo.scale-400.png create mode 100644 pkg/msvc/msvc-2017-UWP/Assets/Wide310x150Logo.scale-100.png create mode 100644 pkg/msvc/msvc-2017-UWP/Assets/Wide310x150Logo.scale-400.png diff --git a/pkg/msvc/msvc-2017-UWP/Assets/LargeTile.scale-100.png b/pkg/msvc/msvc-2017-UWP/Assets/LargeTile.scale-100.png new file mode 100644 index 0000000000000000000000000000000000000000..f73146308640b5db3c360c1fc28195303821cd46 GIT binary patch literal 5183 zcmds5_g7Qfwhou8AV>)aDj2H5K@3t%Xadr~h%`YV2nLlXB*9P=LWxR1P!uaIbOjNF zL;@kws~qW40|Zc%(4-R}wA}4^|chTNcf-7Cn@DsKYY(MLGq~<(J4~7dd?b4uCV6sShcK? ze+y2=^b{P`by}!;jZ^qKQmYJA%=oo7IlgCcj zRp-6Q5gy^tN}aj7zt_9{_^1^-@2(>vKW2PQ7kS`DqP}*&`VTtHtA# zFx=Y!@kV<09LOQl2WODDis?@ZjtYT zW0(#zff`;lX%Q=5RiQf@z7&w?tngNBgQ_v;%#v{smrm9z3)uR%|ey)Fy67%UY-p1s1 zecM?3ULO^u1OI$?-W{%0k9sK+=^eK{TS(cDK2E7#chBu|W(Bzsel$cUx=Ig>-WyM^ zUTP42)8&&OZ<3L&AIQ!lTC;i@?b{v%PIcatkK9Dj0p)z=#?~AKZEvz0w9XmyDlaY3 zJXEGT7V z?55AQLxN{M(8|g*0}%qKz#F{1-6$Q=eZ?P@a55$DBfDo8bGS^S4VLrFYLIQsy~VNm za4ZyoKr}(Yqz*77StgOV_Rac@vAv=LFpSh$Q=|oUgpPeZR3_2*Ym}>Fu?$Q<;Fk^D&=5Hj7>nEyB%2S9=OKDhQc})mzSq2^ zQ%FyE7t}qgy%ndLk-rnVB{!3YfHXmIq>c}7trJ9jur6KRp5e>Q^^-#_^2D?zQzV*_ zdJEB#Pu}-dygUR9Z+UE(>+)#kk(j((ds-0t@Tw{D9wl|*zHc#n*2nZ{6Z9gfLkq$% zSQ-zVN^ce5eY)OKqM8{VK;_f>5=CF|ESvCoVA&_s1T`jg=#O6L){!h2yWpTXMwl!5 z{XjtO@5nvwRKDnNMOgn0Zg1`>a5+PqF4uix5^=hEZ6wg5?c~Jz-^vLG_wF4Oz>Ze? z=8*TPXKLJxV>CxmIi!rG8X%{&>Pj9GZ?;RymDtKEqFuHN+Hgi14qLG%&M^t^LVV2n zX^?q*Z#%Xt!zhXena%2#t2A)z%|#z}R2MH_5=3_W9;*(!v+fjZoSQXmyWU(wDHi)f zXqe&Vupcj6co@}d>WD_v0h2z~N>EW%^(R;k8kjE?WWMEj3XrE4T_?Y;?8EYZ2I7Mz zPu$T$mg7dh+aF%5E(pw18Kyf`&DxGKTz0D_dDXbFQcjP`(7GPzT5uR z>#@Kf9QRk6Q5b#2?v1zS40r#dIqHmdR_F5_8W5qQwY0~`{-i~#t;F$7>a(vbmd7Mj z>Zf@6eCSj192J&A5$QdHYaiUY9ct60tr9$iX`amI5WIgFVC<&+8qdVZu9oecWMlRf zCZ9>CxlvT5iyM8kykzrmtYivjkSgE?04cPxPZ>uTBIL<%Y_b9Vdd+}WAy$(fYul?& z25fzYV+K~sPz6m-x$d<^(h|32B%kP$C;tJk?SnCDvbt=)EBa_;vF(MAY>ew%+=CHn z84Pf8fd$90uFUy0COC@G?YzBVXqvnIEse&3b-A;TL3BK;FkEUJu z2W{t19)@2eGZu|G^ce95%v@{zdyXAncH8YS!WT8i8$&VK#iHwWVS;^H`IMKc7m zz@zkHwqN7HC*X{_eTtE%Hy_M1L zCKg_>l7;+Vf29h-S+Ery=SEOSs0nm9oBp-yFEzt=znfA zlw7KhE~I5VXGKGQg=3GbQ&71jf%M7Nrg!uD$bJs#mj)(#%1<3TUNib@E@;>1_$~X< zq?4y5U(u&9E`ySf3#rZ8UdZB3!gu88^S|?xgS60vB^eGL(a=0@s-{{ zedG{_G;tF1sbf$N+31@}vT%K3n-oZYGxx2dE+_=K3$e!sC^QO`xuXm z)gKAqy2+wwPE#fJtFe=dhj5>BAGSHfYwPH|0`mNq-*cltT5-ddyc?e^uwN?|LLOw1 ziaNvXOg68#JS(HhTssqONAyMohaTfUj4Cwr;=g15s_m!X7hhdGm|n381L>{?=+7!) z+G!wJ5>%;b?C7<|wlpZ0s^!K1`wGtdfZ9JQCX{i^&KT1^2ttye|B6VV6jib4gu{7E zTraXa>S}MtKw}LtB2=8CiAES;B2p7CO0jTSMruvWe$|!7|MhhR`jIA*$^(Ln_Lp&Z&TZJNY;Se&DF? zLT3)tz|Syr<;L{Qifl#dE5dB@@y!u>+zEC8EqgJUw;6I4OA4Cd%TSiyT z^c#$g>E~!*dXD3gPJ4BV9@AT@BvPyg@?0ZDiUP}cxT(%`6<(%+l_V)JVbQgJ( z$f`A>ALl$xz4lq;l!M*rMiooepXw$zH@7GAy?D@au~DI=-7`5OUkMoGoPd~IyAK*I zODsyB?nj&Kt~tM=AtW1KktD=a^h%)ZC^5HE{DD#o<+JQTG^KXK*Q^Bh`| zvD|ZmHYe68oXRvhn?eHu)YItPyBMm-Hy74`0a883hcmn(^KOG{7ZS|PPa$i}kbzoY z`fY;D$Aee}OyMmZ+)W?J$Ep2vQIV=(hmG`!;(1x=@j-8kI=ON^FdbG3F4uOXu?q7L z_BnUWwft#%l0FH@D!~!KM7+8rtgYI&Sw}c|-{=Lj8^Pyc^Y52NIJ^?(#FeI^3w@_H z3Zxw8es(-`1j-+2T}hG=Zdnm?qAbF^J^-kX_;H#3((yUu1CPlXC!o|8s0OL%VFi%Y z0L*4#UdnJdYiaHj0^KUTRoVh&cYHQuo-B|lcdP{sg!KnGaDL1TWdGyMC$2^j0_A|9c5YhQzFuRC6STlm`N%S8;gI)u&T z@}1k4rOz(l5o*3>OqnCnx^hqX8h|oGQecQMV;Yx zt&mye7woLs4_M47I)KtCb!C0rC|C~quzpBa^5dAemDBLg#DH!gQU{aDa9ebdr1&>U z2)F5yUR+vdgvO?d)1^-(0OnxJdse4DQNu-a<02BsN%;p*ezss;U?Fm{@U$$$M9L49 zPYd|fL%?J}hs*slZ}&YObbZ2g`l8%6ct_GcjOA^~bT2_Q#?;rq+jegnAeDVl(+ArE z$j_$LJhaX_H;oJdz7jn?2b>7w^k0suRXm89=4<|`4i1a|L!x;Fce(DoXOyb~2C9sU zeYycKm;>R>Pi=_m*dG){4UT6hl8n=V0Sn(}WUEIAyFZ}rGh=nr zYk#Uky|lT z%f}2p4wxPb*3FV@kk+4wImv8XS8qrJO~h!&4vUbW;3g42MPFUuAf<@A5|<@n&6F@_ zIVkuR0zFE&x?w?NPAsw(Pp88h5;Z3V>@Bco8WQy;22NWP9cy5N@T&<~F6PWM1zaS! zY*vu0+$6Fog$j&ea2tl)jYu7e6KsCR!UU?mC9B7(FI5rq3|xK&T*ek82R1<=|Lzb) z&GAi0o84$yhyre2$#+xAjg@t>U}{R>&3y%B&nx0=Y?r8$ z0_{X|3g4u-?rU(P7UV33Yr0~NuTzL@5_vnFEc(ykT7$Q!`f^dnUjl|5MkB>z1Huk2gfN?aJ9YFTW{9(0UV!GzA#rlh70r}BOd z)gesnBA&=PRx0v_OoI1zxH|vy%1f`88OpfZemXePabpALHX{49M^(tOSN33u$0d|x zGnPQuBCgJHoR8i+|LRf`ly`K$=YipODXAJJ*A1N2Ee^v|fP0rNlbx<#zkX$|CJ-m{ z%m{~c)5}7i$fBP{(Mkik8$TKWqQv&DE}}fasL|pm-E7Zh>F(Z-c{?(ESCM#Q6A}5G zl_;-yk3G(;G^2=2{t~FG*qNHl+dpP@_2mTTX@=u-o?aJQt5Td``qlzMe+XY@%kN1O rAfTS-7EDl=hp#G-}ZPs+fJAjsD8qD8UUwTJ%!-4G>d literal 0 HcmV?d00001 diff --git a/pkg/msvc/msvc-2017-UWP/Assets/LargeTile.scale-200.png b/pkg/msvc/msvc-2017-UWP/Assets/LargeTile.scale-200.png new file mode 100644 index 0000000000000000000000000000000000000000..80c1425605f951b417501dd89c5330028595dc5d GIT binary patch literal 10373 zcmeHtc|6qX`}a7Ui89$r7-b6;lkJ$2?1Pf6#X4d#XfiXQq9jYB?1L6gs1#{qm|(=#yqK+Rtjcj4|o2*%J)jLkvbz8eA|BSSY@tI5CQ(yQM zZE0XKB3-X0^X!J@o)TF^ndf)=F_hGEQOO6d^PQPqMtcYRfY{i3Id6%kw8M?hQ#0y%L^nJMAd`^g=F5xh(eAyQ$--VwYd<; zZ8>1e$Nx_I7ZBuV13Y9UWID1v%KXYyU)4fowO|Hf*}ql!;E$k{tAfd%1MT-sW+$2x zjXX&dZJD!)QYvpFmwKa~s;K0}pdOtzf-xS%TC9>vFNZ>?XA-yW%q0+s^&zp0nwr(| zxi|BDW1pYZ`Yl%`SW_u#>cpkrm)bw?c|GzsD_#cQ-D$1`c|N%`W-_xhR+gU&?VEo( zBTyM2Mw5uPpY`5nINR`N#&&$O_c0TVTLh#R9~ZAg;jVtYhN`64Q4#0lgFp9gHimfi z{rWsRJfE&?^7H1{bnV{0Yz?mbr89Q?$73NX(!mgFZl#g&>h~x#8hxN<<>x2AlIX(} zX~LEy&)4HGi{F~A@}C8(Y=KDDiQ1e|1eAu^;WIr-ShL3Bj12RHyk?h(aM3cc86auXg3$5V^cW5y+(f)rW7Z1qPkS zCCscX1XAVH-lcMX?WaF~@cB`yQ>{4R-WJFU^4dW2Xgo*{rvFV3{~ss9?LJX_M!oOE zeC>KPt-Bx{{IA}bubGav^_|d*UHmk}f7QSLr}sNs5^P`6oe87%!zYIr&JPcpn8d7H zxdj%q#|SF!yq>DY50=S27IfH1Ir(0jssDIgbQ5yz>c+B#dc7Ef$c1l-m(7v&oK4y?FL8_sx&@TTE+fK{i6cx9#RWx~;PIBk_)geY#`% zPE+PgclGkrYi*15#dhs>i}jTTztjuroVD+MYeh|X+Y+;xI=S_Qk<0zj9&{@!pzYN; zw!OBHgHY@(`&~IJf>*T<-Ykt5!($Q1X&aTLj-lE7^=r4fuMUzA>`!JWvZ3F_kw&fDgOc4EQl*Jhudfuf zWbVFib;)wJ@@jPw76pj&87WL8s-(WF6n(y`sA-~}xU}GzfQxUPafT(=sozL?A*=oU z3XIK3*Nd4+HAU0!QhU|oZIh5($?3l`9SIlE!7|n;^qa5UZv~78cXUna1v~RshO|@P zxVIGB)|JivA+OSc6j~8tpZ#=bz<3Q|}arX+Kii4TbgiKGuC3pp)D4|t@H&rw5 z%XatrSi`aQaYKjSVyUCxB`#E}3l&*~n!EhAU;jZ4xrQBa==ED)@?g7Lt?aB*&jiBj zDL-l+26XITLnnY}pZiC!qbp<2^7mh;*R)nEK$OydXS=r%${4a?y97~_r}_a`XR4K` zzl`-^iN~GlH@H*Sh^Rl3n1&8h40-jf*mlNkFvX5)r6HV>Jqp5X@6W3;M8CD4e`@pl5vScXVdWk%P97#cp=Mzq)l_t- zNM7yIJg)ca*RPBHsNM?>(+qj!FYb%C$w=-4OngJ@!yD4Qp?5pJ6gtrndO=M>&|Xmw zEN;xW=R##clr3W3jH=(5+C?lNhS8$!Ulc!98}6EVJ^l7ns-(Oc?{5bZ465qfL^H0F ziun=mU)Ce!#V?!Nh&f66>KJ*qQUL?8Eqn^U9Tyk@`oPlIV6mjwVZ;2}VnbG!1W!HN?@AcN^{S7=M zItvoibW3@bGGTg(t;O5Fucq5OsrUf`Vd!}SC(44x|A98~4xUK*G>?-bh6}t?G3O)C z6ZHznG&zF4W!U?4k@;u&G1c6z2f(^BEo^se8H2Oo2!kMC)IRV6-;s9MZ#_E2mTyoZ z7R`Hak-=9qCctuV*b*_gq^GX+mC?tES{a9b9-(zl3TMf0%%U}^&SIY}Y4H>^fSU6w zv+XWSCNsqj1^lI-jnfh8*&astW`G2`fGFqgn>{-n)xTW2(EoOoA2RK;xX%RA|D_Ni zX~qklWXQW1a`_TFid)JV$aTO}j)jz-k&AedlampYgbGCSw%?tfLer+@;`GLMr8}{}neR<8;zjL%>T*-URjX9v}&c69GyK-P> ze*XO1`I8c!xwJ9jUh9-L|T2Z~)7KM5%h&c8ih*Y_s>$N@x+XjXAj&+I%eX+sz$oGt2G;2!H0#q`Yg}%_HFwG0h(88PTQXb8b34v#f zhr5SADiephG2CHFW{8?Ya0{)K{$ugmiN&^3-6GBk@33NF>xz=3-{o|QPSoAbd)SHQ zH9(GRD=B$049GnNfShI{BwxJSnG47(fNawCvZO=+$T=J255CK~LFC)H7YV1mEG&Fp zt|?|^1?KqWX&Kd!&1K%v7jtB}H!cW4pTn`Pd0rVz@Z7LGla`XfAYITJKA+ zz_?)dvNHNloQ@0CIA{;BV@?M6JT4sQ;$VMt%LYqb7U!N?Yguc>c>ufU`$OQNX5o`8 z6Xt%ldpZW+(g8xnOB;w2d0eI{QB?4xXoHl1!8f@AO}vaZNEyI_6UYDhODL`PFpHC^ z1~9E4&;#%JnT8G24ONXiEWRpPywGsq?eWP(k?hO8#8;=oG@q2!mN~7OG^X$DU3^|t z2AIem|BJW51n8CdSjfat$RzbnaCZ9_!-2}*(Y`bD7bB^^!gTO=9LOP)mnCOxPURza zY9ato$;?(60!;A(fG^b!;Qk0N$C5`XYEu58NfXElpM^A(kXAemDMw}Co%Iv-c||DK$5d65r;l|+?6~hj2MbD)%e{C z?<;Uo6i5`0GxjKMK!_$|jbl}&4zh|QmB-1mlTWVQ)2hbwuS-m1;LZCJ~+n8m*{ z39&n-u5WU+k1d{)|qq)o{fWl1~~?Wz7})Pg{m1CLkt0L zfm=Wo;!wpAIvFGyd_)n9m7Og#JL;qeFB8FiAHzm6O_-l-=~c%2xF>+TTHqUoKn((G z{-cq@@S~H%(#gjpm^WI=_y~Uv;y7k|4{*33g-L6ph26p&YXUB*Q=+D)y|O(Uk;4GzAn3@0HT+@8hH91>Qj4(r6$kN^*ETsSIISdoky=>9bK zn+?8W!n`JiHq;DBY;Xw%?~9J$Dnt>b`vn{b7*ZO>7YU2v%m4={9MXcF+pWUNPV0?^ zbOxm(!0^b&MPuZLJh=Y0VeSPPLUQHK&6e{248@UWoNB}k+A;rqRv1kk_H)zaG#2f=*7rGE7me8P#-bzA1?Y5>|xa)&|I>nsjo^yb4rV8w?5zeI@&juSa zy3NJx+LY1JB#Qbh9zuVwj6My9KqK5u6K1s-8XOwq-0xwFk5SzMfPw!G!7drc0Z;9z zZUYf}AQXc}_Y6!iiYn5P3ktuepLKFBo#tuBWeMBsD6T@jT5W#A+;M5bc3{>cw||Cx zp&wujDG`V}&}=Kq{W`$M8*DFNcuzPC`rqN%bjsm>pZ;INOfWa$oiaL-L{SBjB!SxH zVrZ-3ZivF>i-bT4CJDeN^kK6s;U$VJ?S^7#HErkn&!ff9*|zL5yGjR1r6v65&{2;}!QUj5 zB8d_Q&Pgu5SI3Gz3Iq{+o1=UEov0#Sw$#PPc|5S#<8*jeTUi0$A?Gx zZI&g@ez`h90a#!>rXZQuF*=U))6JW`RbOApuLi!-s$Kpv9jvlhLyNmlnz$p`_|fm@ zQ%~dp!08V_^1xlk6e3yfw}eTQ&QgXmB$&+&!YW1REkMbB=UM1fB7z7*-^~?6%VLG4 zfaNhUxUmEi1qxCyFB{C$Vr92@3U}lVrHh2l-CS8E8#<6=3nYO!4;~e!VcacDp*$;_ zn@4kOj*vDtQBU4HG@Ai4`4^5*!mG}op<=U_SOFp^YCKNt=Oi82e1B}Li~Z;PgSS!`-|n?m1bW|)9%%OKtNwzYwjGrX zPL(0}fFmAr3T}V@u+jPcGq+g!^)1|tn7P7Bej%VIF}%B{-FLdmdg=s;T-BgJoOo*z z@C8ql$2&j#V1zcwCCXS+?cvKZ0iR?Dlfh|h=F5_eGk3Ro{I?Wz2GIY5wUz*f)$=Dt zlE`LcO&%w5wy7GN^tL~qVNq=}8z03o-98F%@oVBpf$)KOk z%oaAMJH`SS0}jv$l|4>A(XG|uEFknC%TCYG4(&(F4liR!$A5RfQJycpbno1!N*Ec) zG$4_`2Ba{}v53K=`|D!dzl6Z0NEaVQ$|^Iz?yJ7aw*ZRY!K1U6OvaQ)6WiZw8N|v#x=a`xJ@M#I(FHptH@Oykf_n z3O_Q+ex>O=;1{TwYn$D@CUk6Aa37!ejuJ3HBuvd+PBz ztwKu1f$J?%l-8j1zFq!u>Pi0JaSaBLC^{_B6P=GKyyt}a7n`0GS5YpZd2$meiJ3OZ z=9tqsQY^dU(Y9#65J(OHR$kH7TI@Iq-9iow$Y3HR7%>va6tp&P>6)m}iX>a;jEH8P z6f|tR&IB&bjK@>wENOF}`)A=MW?`z!zIedErY|OAnp~n&#Aj#cyY?!x?2JF5(D@<1 z^?*j!o#T=ubbuwS!YSOSRGDFqKJQPg5QDoRWQlo6j1muN;CEh7s`S8&n_^EPLYu|} z5i{;^zBDfqz|^}#q2wvE$L(uLMp?N%dcQwKl4ZB~wJqQ-CRCsH?j7g%02zyeb=?8i z`U3(okPUX!TMb%ebl^M$>bX~dB~r#FY>VN9+qo!u*T}fH35k5F8kD~^oPis1+IAQ5 z0o#nSymqLGMbQo9N#sjG>)~dt2au9O^G8Qu;HnJ9Rb=yl?u;Kz7 z`l08iqg3`2FZyY4pD>0+IB#>mVR$Mm&mySDu&kMB-#bv}?MosDosRz1H3l3mhmyph z1Kwq}4)>JD=5Q^;Eo(R?ew9wP&jkYMp5SS+XW+4st~ zo4iDt_A4vJVsSN{f?jnFPnC;n6W$PHsce=aJnXv1m&Wsf8t1YS-;0Lc^27r)yb55L zNNb7{iTpGf8CRdohyd)gc@TkCCr_KJAjXF3=X=7TtOiUHGVWM1H ziou4W;1C-PuEK6MG%cqX{{akj+0b{c;z+0yT?9Kg&eNAbLS4X6jgxSUYOuKgrf`Uc zB#_8#Y2rI+2}YPSAq}ugK$VaaG1yBec*mi~NOKbTxGd4KxQ=&F0%>=QE<%yP4{CB1 zjM-4SbqP5SgPj9%dnAzel8~wgJi4U`q1SQXK){0TEP%zOiNSsB=pvb9OuPx0mLrbj z-UQSwENGN85dv;FF)CmdPYkYWNf&XwgNgq=83_rNAy9#>mM{`5dp8fV$BD|?3>Irj zAU$v4L?3NqLGeK0r#laZJ`$*9#$n=(!6Kv+)k+Elr%IHT8fb7IX&1mo?|2p-qgrJE zJ2uf8zKg-<9O)v(vcZ#fR2DP|iBYsBuL6Cf*-%~U5}G&*3g69(t4T7J*W_Y8py2u$ zo>)Z^Y_l}c@=s5!7Z}M9Ateq}E2{!nXgJwT9J$Al&bpFp?5@du^cw)$Pz-)borm%9 zIgQ;3u7qTX`dj_U;S$K_U>Y^qcuAG3D#C_-(C8cmcJ4;OB@;ahLr5@L8DaX6N-Qw#223FwOp#b*tLOA&ZXs`p!(m;pY zE(zIG-(~C|OXvW`m?RlH$Pqde*wFA~<6vn*hbkB)83Rx|_6RSXjDrDHAJj6MolVwM zt3ec;kl?8y2im);yhnciWCG|1-@wJkBpHKCaedVSun}{b9H^{!Am+ZwfOc~MEPG^J zDF<}I0Y80Z&|d}y`um*L0GGR>;Fc-GpDZtqQ~^7 zEilmFDd;@5`y>WW%fw+FZz$P-PynW4RXGZq0U7j$4QUOTfQ<W_Sd~^W3#71K9 z4jneM16*;;Inzbv@N=vPP!?Nsn?n`U+0Z%M+(@wSNuKi_sv?Ng_*5Md@h8YEZz30d zd;|CD@tVB2@CRm5f-YX8Ywu`0pV95RTt=Z#gfyTL$7l)j`fr!d8TeooG07a9sQcW% zUjSHvb6VSS`&eUaS+unNr2?2IM<5Wm1gqFU!5#mI773ODULM1(yACh-@UcynRHxO| z>DYDJ%}uW9IPCFFTb03~@s#|?D6bKm@AB^ZUHNe<AbKRxf!9ZgC?tu zz;RM(w{UQIkM7DoU5;<$_blKs-5d#KG>ZP^${@L0<30lYW`qM)59v(cO{}7eVG1pQ^^`eVZ**}f2p*Ojp4!ml}%veL@|`i|#|tu}`h&$f;==J!XAJUF1I+gW&) zM2v3}ejYWZS6dpb46*DL`|qb`|F0j}t;Y6k&GoF_cjz7Xt`Kt6))`f5jUoLHlPEA} literal 0 HcmV?d00001 diff --git a/pkg/msvc/msvc-2017-UWP/Assets/LargeTile.scale-400.png b/pkg/msvc/msvc-2017-UWP/Assets/LargeTile.scale-400.png new file mode 100644 index 0000000000000000000000000000000000000000..85140caac238ad74f1a97fccb245d4b30c054e5f GIT binary patch literal 24747 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 literal 0 HcmV?d00001 diff --git a/pkg/msvc/msvc-2017-UWP/Assets/LockScreenLogo.scale-200.png b/pkg/msvc/msvc-2017-UWP/Assets/LockScreenLogo.scale-200.png deleted file mode 100644 index 735f57adb5dfc01886d137b4e493d7e97cf13af3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1430 zcmaJ>TTC2P7~aKltDttVHYH6u8Io4i*}3fO&d$gd*bA_<3j~&e7%8(eXJLfhS!M@! zKrliY>>6yT4+Kr95$!DoD(Qn-5TP|{V_KS`k~E6(LGS@#`v$hQo&^^BKsw3HIsZBT z_y6C2n`lK@apunKojRQ^(_P}Mgewt$(^BBKCTZ;*xa?J3wQ7~@S0lUvbcLeq1Bg4o zH-bvQi|wt~L7q$~a-gDFP!{&TQfc3fX*6=uHv* zT&1&U(-)L%Xp^djI2?~eBF2cxC@YOP$+9d?P&h?lPy-9M2UT9fg5jKm1t$m#iWE{M zIf%q9@;fyT?0UP>tcw-bLkz;s2LlKl2qeP0w zECS7Ate+Awk|KQ+DOk;fl}Xsy4o^CY=pwq%QAAKKl628_yNPsK>?A>%D8fQG6IgdJ ztnxttBz#NI_a@fk7SU`WtrpsfZsNs9^0(2a z@C3#YO3>k~w7?2hipBf{#b6`}Xw1hlG$yi?;1dDs7k~xDAw@jiI*+tc;t2Lflg&bM)0!Y;0_@=w%`LW^8DsYpS#-bLOklX9r?Ei}TScw|4DbpW%+7 zFgAI)f51s}{y-eWb|vrU-Ya!GuYKP)J7z#*V_k^Xo>4!1Yqj*m)x&0L^tg3GJbVAJ zJ-Pl$R=NAabouV=^z_t;^K*0AvFs!vYU>_<|I^#c?>>CR<(T?=%{;U=aI*SbZADLH z&(f2wz_Y0??Tf|g;?|1Znw6}6U43Q#qNRwv1vp9uFn1)V#*4p&%$mP9x&15^OaBiDS(XppT|z^>;B{PLVEbS3IFYV yGvCsSX*m diff --git a/pkg/msvc/msvc-2017-UWP/Assets/SmallTile.scale-100.png b/pkg/msvc/msvc-2017-UWP/Assets/SmallTile.scale-100.png new file mode 100644 index 0000000000000000000000000000000000000000..ef1f5dc6a891b07f208b81f37478cf884905a2b0 GIT binary patch literal 1425 zcmV;C1#bF@P)pKLrFwIRCt{2n>k1{Nf?Gpr!&!wHQ7kbTpW!(Qbl1S1A|>qJfa`Z z&@&X3%|wJvJTnnARl!Uh`Nc$yOcb+Sk8HHJ-&(6F+n%qhrZ1IxV3?YjKB}Is`s(N& zix~=HrJaG#jFCfNlkwXwDr>?H<7t6B#EGa4ZHHi!*fo3zlmG^INZ)c;UqpZBVoLydC zvhD3{_WJtDN=r-Q$}%UhW;Hf8#@5!>SXEUOo1UKLS3Z}^1@2c}UG0jwy}e~aLqqKG z@zMP~PC<#uL4ig_M%c#22LC)iKhOI5`q=gLb-{fgW_fv;i^2YLb8}pf0JR6iC8#Jl zO-)U1`t0oN-IW9=6bdAe)2Kb&-QD~<6dX+qD|3E8p4j)~klBTW1vi6jZEYX6L7_w;RF4$|j#ucI$OlAtYtYoxlq(l;>;C>; z>0APBIra7RZW_Vy;o*T_dCU6$P{@o3yh(v`mX($98YBza-`{7Qot-?5-fn$;onPA0sjaPb)5pih{N1)~me1$8plmk#t{Fj~7X)Q_n;;NpyiFJT<2VA;s-2x3o)&`S z?jHF@K3`s5lm%(a>FDTi({jOuAjBJ))zwuu(*net@$qrxb7KFcrKNY@LB`_ZqWc-O z72C-{dUJD=_4oI?+lzdv3eu7zUoBio5hMjTanemnAjcyi2zkT{`4)LcEmRexB}a}o zqD%EQkF?| zVh-gMl*W9j5V}E^LVNn)C+M??5s0ZoSc+QD@e0B;qNk_FcRO6knVFe)BWcW&yi*Sf z)C3$ufaX0hG4WwCDoCYS$;g8I=2@VkqT+)Xbfex$qzdR|FkuBa9>zUgU0uayzu*F! zOsHkjLNN%48Y7QNA+Q)R06h={i6)Hn%E}7s?d>fp-ztP&LoOr;UArvCZ*g1~><=Mg ztO8M3w!rss5Xl0&EC^{-f6)X$P>fIo`$NRu-k$p%E&#??Q3PNwk==a|g0NQWod=;w z=mcO2)Ic;P)F6Qf)+&Njn-qxj){N+#<*lq`Z20>xOfLQO9e+EHei2Xr=v;>8% zH6W3vERq%!g&2_7BPdA;ib@Pf^qIi81w|uo;T!Nw&15$aKG-^R{hykfRY8#cH zxWoWbj&0jN<2-p-K@sHbhWe3|lh5b3Ez3H?pGCvwq7Z3~gPaS0?v!tl+J=;Ket!P1 z^OnWGXoLPN8iu#Epb{suA07z_y4hbOHxP4iaq$neky6Z2`Gfj*#QgVxz{nvmatMqZ f0wagO$RYR-pL!m0+cb6#00000NkvXXu0mjfHSwLy literal 0 HcmV?d00001 diff --git a/pkg/msvc/msvc-2017-UWP/Assets/SmallTile.scale-200.png b/pkg/msvc/msvc-2017-UWP/Assets/SmallTile.scale-200.png new file mode 100644 index 0000000000000000000000000000000000000000..ca2057c7580188134ff05a155b82e37689e50715 GIT binary patch literal 2535 zcma)8c{JPEAEin#jipJoNF%7FmZ%CsGa3X*$ztnR+o3W=5vld7wpJ^WPVHezWmN4; zXOz}jZSADR*p6isA=IEqOBu{e`rq$&e&@{j{c+#tynEj}@7#CpAD2lX*@2~%q(wwT zzyv(bNjOu#LQ+DwE+3wg6b`9SynC34h)l;s`*;cV_>GCG@17_EF?TFdY`~u{&iMWzRFwf!n*ht*@r$xd_x0^omz9@PwQQHy z=Vl}ZznGQR*siZi+pDZ>Y2J@J!(D(!Z99?^wp}C0L|p_9TeWr?F?N?HCl6($6ryoQ zyHwS*W#ldCDUvK}90jI!=f9-t`$i@vI~~2fy)o1L<7QW1#mCLAM_!%O8)2cdva+tt zw#Du1$2J)pD1xs}Yv;HXjRlHBAdolx{ry+x2eZMhvK!Fc|EZ$C4kPRPoWRod{`Y89x7Gr__20>I4-40L_C4Y;#)$ zdfH)Ji!VPuGpMp_qX3Ox|7Zmym2w}d=Fj8VPg7E!vh;Sp8h{3{>9(FOOCp9 zq*r62tn^cl`1PshbAKJ~-&^aL?_eZ7u}gdE@z>g9-JB4+N2#j&^LZXjBU96pzqbNL z6OHt1vx3RV$+>s=rj}(R^yb5@t*yDy3gM`sN~j^I$JbYx;dF5Ei;8pw^&L?*4N1)yG5clV49`{mcM?A2}O+ ziPJ!v^_W>o1}oPOi{SDYvMM|JRY{oV5Ktk(Dl1}bqPC4+?xr!gJos}>&^Oe9w{NQh z;i5b9A7@&owkwfj{VvhoD9Xc@sEv=FsnisiluM;-iGa-Gg2VqpBPzJE%f@+yyn%uXWyBm++2)=Ui_A;b z4Y!1jrh=E)wvIM{G-SDx33++u{6LLo!_DpRUy(ZY4CL7dcMP+mM@4&YKN}}bagag} z`OzUI)>;Y!Hk{7W-=b&ST%9ZmeS z;>5A)B(N0HR4#tpzd(T3uVi`^v#=6g6!#1e?}GrwzU32nD_4L%2|B@n>dS>Jd{_*y zGAeo9+5)|`I<%H4r)U=~f)9&DCYV;}bcHbH10w9CWydEEa zW!lT8OBA_CN0Qzj*n(stxjFg|`e;y{L1s~wmhK?a*ArgGJC-;5;k6NxsGhfsV{)^! zgtW7e#tZV%7b4ewZL()0f<+8<$Wzgz)+VQk%$^GL@PXzfNH>k=cRI|4Q@sT{ovtBJ|TNVt0owOjIl1mTVw$X(FkLePQF`FG6OTJ9`Vl4TwH}>L(9$61cR1M`k1Y zs(ppaR4XUWwQsKT&hSl((ZhMV&X1VtFRdNc90_z*GjXUBrfuL3q)L&#UJ6QD4{zaZ zoOv#h3ef4bYcn4@sGJ2HY{~Sm#PTGv=R`LX{g!s{#?>1wueDNZ>x6kKfUWY%BiXyR zt1vyyU&Rg^&Nc5xc4=^NkSrXfvmnfA&Q2*Db}>G-a4?|D(A`vOm3Isb7B{%kDw&g$ zgIhJK9nbn=m|YZ_3A5&0uF}XXV@7q<;bSby93DM@+4BQP^zU|Aq7U1IHSfWo40``yJdi-!GOMCY@iSmWFvt%iPi*JR2VWNDtV| zcvwdMS;mEP1i()9*~BMaclKJ65>li%mFY-&N9{4`pWV(9IhLeA7bS;;%m^D^$IUGQ zEI6rjvHO8Cb3;9$W9U^Cql#6Wt=Qzy4UGONU4Q8Qo%!8xeQ+ZBCu(?1jQLi=rrs7p z#q$O6^Y0HSQ!XJ+KoKZaJBgq+664$0?D)_|l%N_m^%=u97kyp$gO!?$C}QqcSO zTJ>gLbZf+ogrr6^5yRy>yUZ<6U8cMRW3gz$@?eVnflM~>NDPonHX&We87)2bYlncf_=@f12cRt|* zeEX6y~#lp9KQdL;y<{B8-+1dtuw4X`^mb zO;EJuAx7`L8*AI-&ua2_ttK81f)i;MPo zg=2JIemLGkZ?ne*lCFV7n2P^b(-Ag-t&8>&5yKNu;()NHi4bf^xTjX%-+6LN`jm|L He=`37k9VlH literal 0 HcmV?d00001 diff --git a/pkg/msvc/msvc-2017-UWP/Assets/SmallTile.scale-400.png b/pkg/msvc/msvc-2017-UWP/Assets/SmallTile.scale-400.png new file mode 100644 index 0000000000000000000000000000000000000000..398721a4614d8cfb708b8b951b09af10501a95e0 GIT binary patch literal 4838 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 literal 0 HcmV?d00001 diff --git a/pkg/msvc/msvc-2017-UWP/Assets/SplashScreen.scale-100.png b/pkg/msvc/msvc-2017-UWP/Assets/SplashScreen.scale-100.png new file mode 100644 index 0000000000000000000000000000000000000000..23acbe613d6b15496736130401c88315cb993939 GIT binary patch literal 9276 zcmeHtXH=8h({Dlm5k-h}kfK;90wN?xN4g3K(m}dN2?04$Lq|Y5q6kV65T#d1s6qe* zJV-A|2u-hTJR+3+UgMaIQvY?>^TH-;oIpSw8OpN2?PSqzNdEA&^LoJZWhO~ z)zrLB^>pmn8U4+_4And|)%cwjXxZ>dLx${Ae3@ zR6qOl#oyoAnbjTML_HW&Pnb$LN0%S$<*tLl&_2oY&kLU33wV7&SLdP5mi#;S;|E5X zP>8Y%52Xnx94Mv>KgmdGH56`hQ+2R_{<7%nsZ+39iZ=4diL=69DsyBRVR)t-mqNx}Vv6Zv)$R zB~{o)68C#2FU(8+e+M-GXY^<_YdR7wd{Vkxzf{&H*04N4F%3S?jV#%nPE?AS3_fWb ztyI`1yAIFCI#+{AMl{zPw>b4C<&LL zf~j}*2@A3lBO_*C_h!=_encbxozL8|3G8Pd%+nF+Q93y+n-(!H5iF~nin(38&y4n% zm<&27jceK4m}9?@>G_DblXBDS(bvO2KihsJ30Q2)K+M%EpbKiIUY?#TK4Tu59zQO> zWHHFs6-|7YCRO-O+TF@yYuJQ6UD{o2a*$mD!zSR(sJLrWW9omjMU1s@Z^T`4i0yBL z3us_BHy~0EDxgB@^6JUszSHq-AJt=Hf)A(pX4W~p8a8_5em0XGvjSs&e|xz)w0Gru z(B4ey)P(=4Xx_uD39rMdUPY0zhL!rVNzPpF;N!h~C)gvntMYxgZsplu>F!NJWxx|t zf8WTunSb}&@<>%|IsUlb_gCndnEqT%Ah79RrQvqhl%t3QPS&v};(G) z#5`#8d>Z$pZPWgmM%nh*^Ij`rMq6c8(0<`1=;#L%>p)!XY#OSwu*)TW1V^;8D6z&j z`EK@W`qVZ^_VC$y165N!jH7u9JbFxP*tnUHZet{h3$txyd6S*n!p}0-C!k3cIleP*O*(fAP1O5K%&KAqa^=VUa z)9Xb|3AgsAV#Q-}6J(2)=2k)IOl7~gAdIhR?62SuihbTuUxV=|Gv)IcMc2H=*BrAJ zg~V0Fq7uuwb45RH0)s@`<2VPsmR~R`3KGA!iE913v7!b#*V1nb64n z@TvEXAIvg*Cj2ZrrU(L(jy*Ru$z#0KPOL4oSZ!?v-hj21Hrtmx1j_Ef=LbK1ogcHa zwRpFly>b4J(YEE|=^~?I47Ei-io?$ouXEL^j0#u|Id4~)qS{fn28Qj=RKW&e3{LOq zDrz~=B|^nY)tIft+g3%+?ZRX`HMh=WA#@#~>CQ~DK}`M!Op)fZcE=bv?j3E})J;YI zII*C^^^O_A(Vi7M8WQ|epRsAzKmYtap3n#~QQKTr@B}WXG^U!vBNpf2;f~X&JbPKC zT*7m?+^>=JOtznQp(OHichyX*-QO6C(Dd zT+XpsvAt|rl@cVoPol@yKQcJc0L#=$tYdK&%r|tGy#x0C%rv&&57*V^+1|#6aX@1a z^3*wo4~`F3e`cYK<0g)P*5i3kizm7J34#;sOC;m6$0J)>CBo#XErNwRYpNB-nRqbm z&V<^VsuqwCt1csBF5-_R)~<#M0XL=nR3L zVUE~Fo?^o#k}%wMopWlNXSM0Tt;Wk0?zOcpoB$7w9)Yj8kdrd>_ z0kzI&jFscjhI~~l&fBBg!)Gh>Lu-trR>46Ev z!%AvF*=iML9kkdm8(7*S1tqM<5!VTOq{NlonN;gEHkve0;_|-l;}(04J=p~kJ&F?@ zKlo_?w}4z`P^5`yTx&fST=$|XjVnVj5K|`@EEuC~S?}rWhkA`qn~lTyc>GMHjK{It zIPT%;`jUN_4jza%8pJ*}%b{?Q|^MAD)kjiiH>EY##PeqI)ZP6%UfL3Xdg> zATUsYM2VwXAnD5e4rh)z%X}TX-f1rIA(X2|!f!6qXE}j}Ho^u*tG1OK2I6H6Kp^_UKg?hKhK;>&ONZ8EBj+x=_*s@F4kf`q7lJE!C3u9duo%ipiB&0G)F z3(nkH=Ol6@*0=g-$lQ3b3b#w;e5 zUPkNR7?oHuGc%9s^P<|{rCDN~^b;3Gb~7svHcqRNMj~(Hw+*$SHpeeH5RUU<3>$3deznMYwIu z^{&EEaA)bUXR0y|oGrwz0^>v1xP-v{h5Q*AKL6!PH@tWmqU<-QEMmr`=0?j6t4$jH zA=S*T&Do?0QKc&cyYHxFQsvAK^W`R2&t8R{*14!Pi)vRh52B^d+j5LQ z1!v+X%5LRrTN!kOk#3?P1IYg(&qF{(8{U3B#Me%ldZ5;08gtk+_)y7G{?8AAHV{#h z1E^?7EF=zI?W=WgE%osLQ?HPI(6vca|2ExQ~ne8 zroGwQD`SG}PG^8B^)8;26bm;YVl)CAWCKpU${^Ql_M?uv>Dd}?q^qD$j^g@v<{7ts zOqFA=n6!FVx^(&1w;erkX`E&-^LrIgG+dwMA$`!8k@|z%- zr!t*(?D9|753XBGAg3aShwS6b9Y~>^M5czj&{JqL+U9AW;{yWtUhQ)O zFu%%N5Z7o!D?&EsL2({?|8KCZt{t=YBj=7n+Kl^|^P>O0=J_?%A?=xxzFiY|>CsBIUus1A?@t%akx_oH7*k*AP-rt|Gd z+HHr<5|FWuA38eDk7`6DZWM9bBWe-jMHOp{WM zj}8nvXs&od`-7wL#l^*CqB$2l`r@+pGRf9^W$Zm!=BZAO>g2r;!;+7_u@r|!EZxkg@ zWv@j;FGcu!&(>YYe~>En^m`QC8*iYKD6EZT>Ga$XB`!UHYWnNVItXj4Z_>N!l*0mp zXIizMEA+4s4CjV(RA0tqlryp%8+BBJYWg@hDC9nW1vKH075;i7X6rV7f4JN=D(cID zN^)9Fg`3a{@?O*4UT?6Qb=GXt>R-Qc3u07ay`|o#nlO%=S`8gx7k&(2L!N&oL50%xxR)uLkNG3d2|F4Yr!vDw(xCxBm?*D$tuHK7xKp1UCa+sRx?v6Sv~xnm?fd{L>V79-e|z$$0kQHv0|`ML6$zBY zI{aiCB@6t7BgdckZ!bGzc2+V+WU}kG76v=q7*9JE2SwJxJ`Fx3KbNAAvRYc}*_y%r zAIfal)Iyg9skhYMb6(~3j{wL8<1>t1?wz#v-+b7S*op!LI7cXDpr`kyN``f?i|jbWl)QX)Ohxu zjpk4TJil5xTW@=Uz->YXJ_V`|C&tSnn}ey5*Dcw8D!r=fH28cd=r>>#Bmj|sEmr?l{x(;M+2OmIfCwPZ(A)3!gXO%JZ%ytK zYFsDFK4E=k_)c~^wB}YN5$QYt91E96FLrEBxO6tu?L1iZOGat*4rdM5y*+roe^H7FD1m%SvC~g#2L~`tT2tUb zn*U1O4G+^dfK5%uAI^x^(F@R{gO8T1y8&r{a{Id8{=K6fa5vq6Y;XeIzB3GyLX3E5 zN(T)HYo>j2b*ax-xTNr@&Y-8yxL4{pUaAm~afHKJX}pkGu2DBjiIipOGye&{xofh< zJ1gVepYFZs0+`(nkU**j7*+)=qRHxyHw97#VleUxJ^Hg-kg&3eds#H|jl6;TPqvpw zp0cs=jCSd*{c4Z6=E!r#tCxPqMc5ZVB%<6|0{B5kg2 zFUymr+4)r>{Wrh`bq7pyPih_Rlvp+pbXkkobk!+-47?OFP7=gL)nqZ-WhaxEtGWtX zhLS;tzRv-PJhCH@c(>+KE7zKO+d(R1P45~q&L@YpK+b1H3iNJoW#%%TU*vNK_IM|? z020x8iSUPupf;IKwE#$|(JcLt!k=v&zI&Zlg=G8}vqx&eGry##g(r&V$PZ2K_3LDx-i9c9S;ZQ^0smO*^M; z0q(9sfsEybhD=?lfPT0qhsCj^8CvI|%U5crFIdQD4gD0yyXLQZ-W;A`jn5M^8qAA; zotC})tRT$C=>^14RHku!k!CuT?T7qSXfin6@+|pvZiUmy`}OoQi88Ys++qV9jb@d0 z5j^mL#r78$WD6=8ciuD~Tz9KqxDE*2RhFiO;wB$a**@WstfOVer=abM_9?mp+Q06jok@4Grd_)# z+i$cOER;qKD3kI8gB_YrGk#WtPu*d#6QL+S+@>A!4;NwT>H^xQ?D;w?|U|}-18}+pKwWL;43&+)n4}}Fjx-;=x0#f zh4sZwcXx2;y>a;Q+Dj!V`}VkdGXdb_KTV%@`SdcaXy6nW`R6&?mtLYw;)AE`UCa$B zioAiF`f?1JFSFmgT!j`~1zA)bI9JrC%D{ARK0$Up|1SDE;JGnXZsW4XqA5AVS-=ut zp-X9~vdUPddT&bFZmoSsLbrM%GK}lA&J^6%k&YAh`DS202EY-Sz(jxHUPP|?#%#BJ z(p|OR+eWeM;?=pY8RgfMrxd;DR~Gy8jB;%gt6fx0VIKu5phg8APN=`PDWhmgGN$yi zmueP(rh6M%CtX)waBT8+WylPcaRH(l#mx6`%L6dL`E~OjW0$S+;=HN$)NNozh7WQ? zmvMy857@a01M|4+X+eWUdhtUNvQuJ@!?PKtjC#FS>gKL1=3%hoK9hmfn(293#h;xe zh>X8L;Ww;&bUGdBF{LKy)R%2|ET$7Wfmtfe8t%W$+h|Q@xVx&eI?+h+^m+s|PeO_c z_WNhGBkkX+nZm}_%f<9&(jt+=?-q6zaY(!GQHI9}JCnhaY<2DvU*9{|usGrM(F}PJ z+@RH$RPf){4(J-xmFuQ;*>W-{X0%pC*fK(3jEdi; z18iDhsf9qvwS1zUL28lQAgWmCQGC>Ogv*d%6=ustj-kwkVsN?-ug-@u{D`h_qlBFk z(<&vV&Ciz8)(zLv_xsQ{i#P3l%}pt2mItrATAYxJBgHRIz3vZ**ee!g@KV z7qg#Jt!^(7%WE1$pF~v9eFB}vKOyv8J}YC+n#PLz^SOozh5B;i^9U8yadQVD7F1=_ z1pX6)mumg>&0{zrBmkgBnVjx%uPT$~fz>wy-NuZq<}(Wjf`5KewUqU$RN0GKI+Suf zC=&@z7#+s(f~v1(0v~Q&HK}q@3T`$5dcSN1&DPXNNY-U+&LvC*bOe~WdkIL`1u}n~qeDAg$VDl8gICkkon9~vK$JiOk*ww< zf^6mb1r`ZmgOefr{y>5QoE-DAAJHrh#z{=%m=_har!x3&t5^X4L6ksoxN{jh!*0v4 z#vaNLBB^50#54ps0gu0{IQ=}+`Y%d^*cmvD;)C&l5Qy;Ukte`Aiy+;;5>`pagPqs{-qhmB=~fCyWY>dL z45@Rv`M`MpbbLNX)IS`-&j;)hj_FI`Y2|vw2lQsubV6BDBlv^Cb90)UQZL};03gQ+ z5nkPSr389<^!tkF(2!pV&9vFWaPmOMJl89CF!R0Mf9cK72}A)L33*>wSXi0s8i#Gu zG=;?gWX^A(o!G9b2aAaSh!ZDp13MkMU!tCtg%OOUf#5#S+t8x`ygqN>8`T%d zw)S4#7EaQ8;$Ni*l}hZ3oCS3>viBx^Y;$BQ{qcHmmN|bgoZR-^dA4CTN4N-tu4%_@rpYJiYXh@xeAty zH~8SqEi4-H^73ZssM06t&?ovs&WFEVio{1Tlk`lfkt_soD-R9u% z>ZwRX9+)2bmk2!EPOVKSu+I=G3EQ|5gHK4Y8PlgPh=k}8y zXMtQ37dTZ;cQ8E~llAA=idCUxcxdPyNOAICZCb)ky7vP@N> z88qP8;bv7&(dUEwjt9>`Anz}Oe@21$g1Cf0PWu!HBxDXmF$D4fWRm~pKh&L^iSyg} NU74j=`hT-Y{|o$A5k3F_ literal 0 HcmV?d00001 diff --git a/pkg/msvc/msvc-2017-UWP/Assets/SplashScreen.scale-200.png b/pkg/msvc/msvc-2017-UWP/Assets/SplashScreen.scale-200.png index 023e7f1feda78d5100569825acedfd213a0d84e9..5fb2eb78fc37dd1b30e2413d4d9948a5e9591890 100644 GIT binary patch literal 20707 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 M=|j@_FHG|P0q81#+h5>eArRq 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 diff --git a/pkg/msvc/msvc-2017-UWP/Assets/SplashScreen.scale-400.png b/pkg/msvc/msvc-2017-UWP/Assets/SplashScreen.scale-400.png new file mode 100644 index 0000000000000000000000000000000000000000..62d2b0911b62fb7eb7e57f0a01afc5645fa85e9c GIT binary patch literal 49647 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 literal 0 HcmV?d00001 diff --git a/pkg/msvc/msvc-2017-UWP/Assets/Square150x150Logo.scale-200.png b/pkg/msvc/msvc-2017-UWP/Assets/Square150x150Logo.scale-200.png index af49fec1a5484db1d52a7f9b5ec90a27c7030186..22ebaab85605ef29271f142d9a8d8a21feabadb0 100644 GIT binary patch literal 4927 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 bht0Iza^2ykEt4(epJ78uh5nDlX8(TxzDYwP diff --git a/pkg/msvc/msvc-2017-UWP/Assets/Square150x150Logo.scale-400.png b/pkg/msvc/msvc-2017-UWP/Assets/Square150x150Logo.scale-400.png new file mode 100644 index 0000000000000000000000000000000000000000..efe1abaff79c26362573304a0fefcdfca29a692f GIT binary patch literal 10016 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 Xa`akhB4G}E@&>zTY=J2{M~M7C5;-IJ literal 0 HcmV?d00001 diff --git a/pkg/msvc/msvc-2017-UWP/Assets/Square44x44Logo.altform-unplated_targetsize-16.png b/pkg/msvc/msvc-2017-UWP/Assets/Square44x44Logo.altform-unplated_targetsize-16.png new file mode 100644 index 0000000000000000000000000000000000000000..d5b34622f9b3af1587b655a5b3dbc74498fba5e9 GIT binary patch literal 398 zcmV;90df9`P)pGKuJVFRCt`FlCg?|KoEwdo0T$FieEN zha+H6*L5N?41=z_u1n{q(`o()X_}Hu2*J#^o6*OkpdSPQG))7m)#|YVyrd*ah`_dO zA{sB%_kEH8*BFLb?!x(eCLI|1OxI9^oj|)4&jQ9ux~`i*=ERGDImn!t0`N_5x7*MA s;CNB@Hoz`z+a4zs3=imQshYp+7hz0^jHaH33;+NC07*qoM6N<$f)~fK-T(jq literal 0 HcmV?d00001 diff --git a/pkg/msvc/msvc-2017-UWP/Assets/Square44x44Logo.altform-unplated_targetsize-256.png b/pkg/msvc/msvc-2017-UWP/Assets/Square44x44Logo.altform-unplated_targetsize-256.png new file mode 100644 index 0000000000000000000000000000000000000000..22c0960e8ddfa8c9136bd4f6463edd84dfd7cd1c GIT binary patch literal 4285 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∨riwqg4xA*Z^HAELBRcN7O9%_;A+NEEd@<{UXh1GZECL}Q?649}IS-x9}(D08-DGHwWT52GHWr@4qKE8ccZ2<22P8C=%zWKgqH{KFD;fP@i_-ejE{xYgG-uDfK9?}luK4mN z85uH^j~J?bs40H6`)%56?1t!@L0|TcMu~TL^sro+0=`mn8tg;F_uh6_kaq&9ixyq% z9f+8VxX=}>8XLSZd-e%^OX5u&U2_bMC7zZxnUK(VQ)(B-c{_Qf*QW6+C+h}s>Vh$F zF@^UO^Up<{FWdI6Bgc}r&M$PHsLI)I%OBgcddGTh9#KZ(|ZGXQAK#s3K;9bdq{R} zC45i!#Zc$ZdnW24v$`$e`_V!;?Df;OEQ+J&b1$Bul(l|8yJXX{!Nxm%K8pf(58Fan zn6eAbNAXedl+3wNOQgy8_}|fwwr$u7+c&+USG=i7wO9GB=qRYl*g`FmoaTvy2OO%u z`UdBMdAB~-iws+AU!x(?=Qn4}vk?z+QOS&a{`(s!yCeas>Bw?CNZPMXwJ7E*g$}vr zWRw;C(1a^~u!NV%OK4@#CGWhT_2ws9!666nm=iY4b5jD;Z#eKYa;mUEul;1aO~Z8) zx1!qJpT;cVh3f0^z=1U@D3{iZq<34cHV1uiPQF=q?d-}BI_p)us99?dnzS8keoWn7fLE3tSscL&H!>sHXPrE&>XYr9m+-ezq@A21C2mD-oG)gQLejkZw?*Jix#z zZUYWy9C=7{(;pj)C8r0w^C~aG7Zy0jHz$8Kq98E8&aBBLr9 ztRSE@ruBhZeJM2_6}G6zolH@aRi(tJ&be5jBQ3-u$ti=CMISH|U%8!R$DozY>Bx6i zq|nUDOU#_h3l0DlwhxY1Uyc_BESB{4_R4OrRuLL=e-3ZW&CTS_jt;AB(Sv7+JK-8y z!hj!$Z(XdxE2CBv;oq-!$x{r7)0ceLw)Lt|4dk0lzggcGf3to_t|*&13#S)CqRC8B z1KEIV%;;^ga(Bgn5LPy!VEu~vitNi_nT*be;o+Ll@mmWE3%7oVV=R0_N<;22TUrtp zGJ);d>ZA)nH0h-|GHO`A{I$+hkk9v|mOMgFvs>T3eXGInp6y(@zwn?+@ce_xGnG$Y zM#Wa8@X@&d;O%F QpIU`a$lRCt{2nZ0WwK^Vrz#8&?RtGffER>u*0wH9q7S{;a{4QMN< zoffvDLbyV~bP=pYuJoh0PAslV`lR*a_8BtEx;L}mW=-&cMR#U)=Ka0%&eyJ&d~kW) zHo&gV0B-AZ0z{+H@4MaZ-sAE7cyEJvl5Ck=TwGKai^Wu(#|7AKw=L;`lQ15VY)MEz zU!?1sI*$wR_Q0v>D=+bLj)9M)Gl1JV1Gud-0F+E7Nh*~h(n?9X-L7WYOeRC(@i-X_ z24p&&5^1%!)wUx59qSu;P=;%S&4jj)hRUTqgZ~ zpH!<=^8EZvmdoWqelQr60q^ea$m{DXO}7i73xI|@oeuR{p-{j!gQho|O>FwO&!9Xr zP${3!N3Y>mfFlBd0Bvu*UfTn>zP_f70s!8E01*m>Xu3#d@)C&zsZ=U* zPhc#e{#YzV+htC(3;-c!AwXPRT~QA~@Ydtwqg?*s;X$*$d_FJtPA-=t>2#U`p+1Bc zAOMifW+{ZUm8NAy5V`;?OyCJ7gcZ}v%gaHYo=}znD4#FujWp|H^FD-WQ!Tw|(=-6YAW(6m z(U8;qe!n~@k%!e(4X76Kd%Yh0j{%B>&5jIj=G5VYd*$5SZnt%fhcGE1&ReY(4H^6z ziF?sz&(v;|L14ASHUJldP~e4wNB~8sA)Md@<;{fSZ|1B*IQ?4XFA;nZF(R`N zMvRy0`ol{X0sNG%d-9GDT9WGcEkXX`<#7Stz6SpHLG2WEemm{9&H!%fAEMHD^b5`o QUH||907*qoM6N<$f}z~7)Bpeg literal 0 HcmV?d00001 diff --git a/pkg/msvc/msvc-2017-UWP/Assets/Square44x44Logo.scale-100.png b/pkg/msvc/msvc-2017-UWP/Assets/Square44x44Logo.scale-100.png new file mode 100644 index 0000000000000000000000000000000000000000..8b7216b8d86dd82df8996b911bc32178a5fe3902 GIT binary patch literal 1199 zcmV;g1W@~lP)pIaY;l$RCt{2nL8{jQ5eTR>~`c{CG~nWlC`vgl7w3d#jQL_61G%m zMb_;Q%}o#`5;f6!B(__Mo7)hbOQP}EJHHcWGQ0EGnb}#c%Rkx7_~tx*=R4nb&Y2OD zcc$1|0|eD4aHZu4+}_^)B^HZ)duYB^@bIv@Zf$Luwt;~G1)_C)d@O^5gR-)+BAc6=1@(J+dejV1rnk4(v@@{7 z!$Z%00s}WRG|0@%jO21TSzljg+gA38i3tT!ENql_QfFtU`f1(W-AQ+Mx9MpH#`FFC zeYw8A4hKx^A-t2%=fyaTNLyQ*2}>w2#b{_~$Z-&e*xlXTHUB1zm?7hUBPS;(3i|x~ zTmb{lEV+e@Coq-K(b18*0-a1I&F6R>7}VO@>I%#ZEiW&tdq4q30OE|NrzZtY4q(F( z*s80mg8}O)?Ca~3uCA^ETNEPhbuQ?uZXf43$rYIR)gGf^Cy_+j!`37$7VYSSvzEg? zIyzcVmgm@YyS{;&o10w$w9@Hx$ug*=rA0ECjIXkY!4Vctas{rftu06t-7&u?MSSz~ zD_7vXy*=64*(r#nrKP3FftmWbxjEnEJ(G@gm!(WYM-7XDCUMD~4rrE`=jUgcnwm20 zY_GGkv#LWj0k&PPP9l+rVXiD=3kwUj=WcZa10%hN>sSMp?AG34N&)c_16o^KQ*~H% zilP0=_u)rF6CS|gUBrgKc3Mgdh=I+|&#U?jzBs9^!YO3|Yv@EGVeV9PsCO_wqP+Gn z;3S;W%(%e@21cBD`}_NYRx^c{!-fM249w^`fRl(}<&|Jw-bJAf@cIB=4zydlr4;&& zBWh?ru&At8q)K_(OJ%>)MFH*CyC{;^{IJkLK(%bZMk6OV1OzsE4j3dj*fCJII|gY3Ruc` z>>aRZ!1Ykf)@}`LF_D>>8D2o(0VN@z3b16BZz1n(En!k6L4u+^+B&=4{1C9DG}LmW z7~0yZ(@IUX{V+_4o1NXv%Y6xb-`}q$xmnJOsx4SNLzF;=r9u|4C^_eFy}i;SK}ZSp zURztR=p*9$#L+9h65w$$;FC}lc}y85tQ` zvD&HnsY<-LXvFF#`!j-~q!Zwu@qNOs{h!|@KGWR5t~NKYtL@7H{{}}2`J%xL?^yr< N002ovPDHLkV1oIFON0Ob literal 0 HcmV?d00001 diff --git a/pkg/msvc/msvc-2017-UWP/Assets/Square44x44Logo.scale-200.png b/pkg/msvc/msvc-2017-UWP/Assets/Square44x44Logo.scale-200.png index ce342a2ec8a61291ba76c54604aea7e9d20af11b..6fec1f0113eee30d077617b9e2b91a329ada95d1 100644 GIT binary patch literal 2350 zcma)8Yd8}O8=kjGBSLbRvyCk+IZv5HEG7$WMp90rG1ivIA&0G%L(2J3y^ax)Q%+k< zOF4x1qt|IpwJR$xolKZhUhl8($NS^^uIs*^`+0so*YiBr{Up0!&qzyxB>@0{w4;Na z+pc>2!+m>qBQ?j+bXP!E9XziA05V^m|@P*m;QVkG9Yu^}xVkM4<~sCSDN)u|Vaqf|S{@f;TgneI zpsb>V`2pPx%WrP4KuWZ$U;A6HZ}E}`&7)-89-Jk7DEkOJ_-{atwmpBooM&6|Bj(2< zg>|u(S&toatHN;v%j*;YEeg8|KFr57irbAe|RDkot`{-VqXyQ7zm-o zN3c+`UpIeUwt>cz!fVMXBK&i#<~=R%*xcjiFjuekocs&-38G^u!}0_gVGaK`(BeoW za$L4jB2?>#k?_{%u-QC^U{q*Vba^1StwVp}9oQ$+|)Y{rw)d*g^ zjIQky7dJb_>0CX zW@e@&Umy_J2?hoSqZkavsQ+~3t}HAqFF%*->lSB}l|d*JN}c|`A{Y!d`|B5HWTmUC zYj%GA%8D{c!dgcU>ZPr$<(H8v$Ni!_vn3L>eY?KBy*)cJf?H9JQX5u1GnU!h3Cehd z4%?@qqOv4h-+H*L2ZMDaCMNb8zs@LX;BYPtmQX)j_!T`zRa~c@tvw# zK8&8c$f3HzPG=ftEE?6P99P*>dqV?QW~HCm416vIDyFvkyo9#4wsx{2Vq;Ni>2^am z3GVLM3k>ej;MIgHhk~GI4L|6Xsf&D(OiEcw0Fmq0sw5ER2yb3q3F-AY0NsB{$mjc- zIsf!MkC@d z?+P}Sh-U^}z$H)%{T)4fwKsnz&|V&sB?g7}ZyH588LX12jxy|aN334ZdE!hnaGhIXPg zc~aR{@vsB!+`0R-^2XbZt)vd;)GYGi<{gW04Jf#zBR~NbMWq_8#wMWoM)*e=#nn$g zou0G@`;w=&c#H5oR>JXcc zgJW*tFS8eG>(iys;+mS8A;Ja_E-Vn-PbeUp+y(z6!=5#B2Ue*ZSRcutJ&pLq6(yyU7^08?5{_2cBV?ZaZt8ZQ&YbiD?!0?nOomC?`e8iri$Pe z+}HocmV{hB)4fFQUFoiS037YHcD1%Xbm@Re9rOt9Wu*3JOK{*4U|?~)Zt+5$+*ReD zZ*z`Z2O>{Ie98YZ)q0G~Yfe_7eHu`i;Z%8tf1SjSmm(>%H8&f@q83I@!}Uzy;`~s_>BJKEj$7)T zqzj?OfI+9pHZeEzik9_zuVTZ(YHMHOl>{O3oQET+A)aXk_z$J_sZ9^H%u;I)_F#-= zewuojdrZ&uWnFiCH~0IwLR7}@mXQmlb=oZWfm^6t^VRR~kIlS@9Iy4AVP9v{BR77M zwzd2^ax|B{iCg+FR7PYRK2IF!da(9|2gy5jIoCXN(zGq~qNJ`vaF?n%d8mjgO)iw5 z7S&cn9(^!U5fu6=WkRAWdhm~9uQqy3o5oBHMsAaqn__*|1sQxnOPJ7WE$t~!V{U|%WD?L~?lfeacq3 zq+Q7gy@?i!^JUvP5sQ1;g8y6&_Vna!v*W#6YXAla#1_)T!~~`wDR_Ec!G8)~-SU8f z?-(B|CaKmZV5bBNt%T8zF-0Y%&amE&QsU9xUAq(P8u(6Dc6N3}O)-=1yS<~y7cy;P zYa6E}i7eg7Z_`o4YVT@KJ6G3X%j<7jd4cB%7b{4eSty?#VS;-9o(RN&iH859sM!HP R*y|s}wLkCvI{#hazX2yUXd(ar literal 1647 zcmaJ?eM}Q)7(e+G1Q(|`V9JhTI2>MkceK4;p;PR&$Pi?ejk3YQ_3o`S&|W_dsOZ8# zWPTt69g`t$ab`0cj-Y0yiBSOqmd)tG7G(}M5aP0_%&9TijB#&)I{zSE^4@#z^FF`l z`8{8`o%wlL(UI|y2!cdsuVamHH~H86F!*-15em4)NqUpCQM5?aoC_eCf@lV4wvF2a zjDQn1JBL69f&@2M3rvzJcfE!eZ8FZUBlFlC5RD)it33{mF9#B82AiyQE%w)`vlwa> zv{<1sm&kSKK$&%2jSFn7$t&P%%6Ue>R=EAnG8N7fqynWG8L3p!4801a;8{+nliO(qd(jNJ_?+9W3#hLIDLoT6~3fx9=`CC-D}-AMrpEO7HK zt3$GicGPc?GmDjy7K2P@La;eu4!$zWCZ`ym{Z$b zu-O6RM&K4JT|BIZB`E-gxqG%FzanI#+2FFmqHqXG7yxWB=w55RGOM)$xMb(>kSNR z2w=1AZi%z=AmG~yea~XaXJR!v7vLn(RUnELfiB1|6D84ICOS}^Zo2AdN}<&*h}G_u z{xZ!(%>tLT3J3<5XhWy-tg+6)0nmUUENLW8TWA{R6bgVd3X;anYFZ^IRis*_P-C-r z;i>%1^eL3UI2-{w8nuFFcs0e~7J{O2k^~Ce%+Ly4U?|=!0LH=t6()xi<^I-rs+9sF z*q{E-CxZbGPeu#a;XJwE;9S1?#R&uns>^0G3p`hEUF*v`M?@h%T%J%RChmD|EVydq zmHWh*_=S%emRC*mhxaVLzT@>Z2SX0u9v*DIJ@WC^kLVdlGV6LpK$KIrlJqc zpJ921)+3JJdTx|<`G&kXpKkjGJv=76R`yYIQ{#c-`%+`#V(7}Q;&@6U8!Td1`d;?N z_9mnI#?AA}4J!r)LN4!E-@H5eXauuB7TOawS>Y|{-P?NNx-lq+z1W-+y(;39P&&LP zL{N80?&=C*qKmdA^moMZRuPcD!B<*mq$ch=0Cnlitw#txRWhb3%TQvPqjkC`F69G4b! ze7z9MZ#+;_#l?H37UqUhDFb^l&s2{oM$3I0o^Q!yx;;V)QmCMo)Tb_ui|mit8MS?U zm##6$sZZ1$@|s%?l@>4Z<*Q}sRBSKMhb4I{e5LdEhsHIHTe8Bod5c>6QtT>$XgUBz z6MK`kO$=jmt@FqggOhJ5j~e@ygRbG;<{Vu)*+nn9aQeo0;$#j;|MS=S$&L?BeV25z xs3B`@=#`5TF{^6(A1rvdY@|-RtQ|iS5{tyX+wH?;n8E)G$kykv-D^wh{{!TZT%7;_ diff --git a/pkg/msvc/msvc-2017-UWP/Assets/Square44x44Logo.scale-400.png b/pkg/msvc/msvc-2017-UWP/Assets/Square44x44Logo.scale-400.png new file mode 100644 index 0000000000000000000000000000000000000000..5e2a9c1e200184502e2b63287cdadd61f96066c3 GIT binary patch literal 4312 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 literal 0 HcmV?d00001 diff --git a/pkg/msvc/msvc-2017-UWP/Assets/Square44x44Logo.targetsize-16.png b/pkg/msvc/msvc-2017-UWP/Assets/Square44x44Logo.targetsize-16.png new file mode 100644 index 0000000000000000000000000000000000000000..979d24169f4e974fd71ec56ee3458e0232d638a1 GIT binary patch literal 541 zcmV+&0^pGKuJVFRCt`FlCg?|KoEwdo0T$FieEN zha+H6*L5N?41=z_u1n{q(`o()X_}Hu2*J#^o6*OkpdSPQG))7m)#|YVyrd*ah`_dO zA{sB%_kEH8*BFLb?!x(eCLI|1OxI9^oj|)4&jQ9ux~`i*=ERGDImn!t0`N_5x7*MA z;CNB@Hoz`z+a4zs3=imQshYp+7hz0^jHaH33;+NC07*qoM6N<$f_j_HCR(i)=JWYa zc^sOi!Dh4R+WYGuIa&YVaNu^qV0KA6Q>-7$Ahd1r- fgC76UgTIa+#x~A75G<*P00000NkvXXu0mjfVxRfx literal 0 HcmV?d00001 diff --git a/pkg/msvc/msvc-2017-UWP/Assets/Square44x44Logo.targetsize-24_altform-unplated.png b/pkg/msvc/msvc-2017-UWP/Assets/Square44x44Logo.targetsize-24_altform-unplated.png deleted file mode 100644 index f6c02ce97e0a802b85f6021e822c89f8bf57d5cd..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1255 zcmaJ>TWs4@7*5+{G#S+&C!qC#> zf>5N3P6jO*Cz>ug*(_DmW=)kea&m$gZ^+nyiF`;j%w@}y8)>p*SH}C`m?DXeieF2U zyQHecc_L%Gh!7GMt+hG06y;+|p4>m~}PjA}rKViGiEnn7G0ZO<>G|7q;2?NwGCM3s?eued6%hd$B+ z*kQJ{#~$S=DFE(%=E+UkmlEI*%3llUf~8Ja9YU1Vui0IbGBkW_gHB%Rd&!!ioX zs40O?i9I{};kle7GMvE7(rk`la=gTI)47=>%?q@^iL-nUo3}h4S}N-KHn8t5mVP8w z&bSErwp+37 zNJJ8?a|{r5Q3R0Z5s-LB1WHOwYC@7pCHWND#cL1cZ?{kJ368_*(UDWUDyb<}0y@o# zfMF016iMWPCb6obAxT$JlB6(2DrlXDTB&!0`!m??4F(qWMhjVZo?JXQmz`1*58Z=& zcDmB|S-E@j?BoFGix0flckqdS4jsPNzhfWyWIM98GxcLs89C(~dw%$_t;JjX-SD}E zfiGV;{8Q%8r}w9x>EEigW81>`kvnU@pK)4+xk9@+bNj9L!AAZ@SZ@q|)&BmY3+HZx zul~BeG4|}-;L%cHViQGQX?^zFfO0&#cHwel=d`lH9sJ-@Sl@n*(8J2>%Ac`IxyY?Q z{=GhWvC#gu-~Ia7*n{=+;qM?Ul_wy1+u7ho;=`>EwP^g~R@{unBds`!#@}tluZQpS zm)M~nYEifJWJGx?_6DcTy>#uh%>!H9=hb^(v`=m3F1{L>db=<5_tm+_&knAQ2EU$s Mu9UqpbNZeC0BbUo^Z)<= diff --git a/pkg/msvc/msvc-2017-UWP/Assets/Square44x44Logo.targetsize-256.png b/pkg/msvc/msvc-2017-UWP/Assets/Square44x44Logo.targetsize-256.png new file mode 100644 index 0000000000000000000000000000000000000000..1f953b2fc8a39c3d261addb866954062a592ddb0 GIT binary patch literal 6051 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 bno1(wj@u8DCVuFR|31B*4ek@pZJqxCDDe1x diff --git a/pkg/msvc/msvc-2017-UWP/Assets/StoreLogo.scale-100.png b/pkg/msvc/msvc-2017-UWP/Assets/StoreLogo.scale-100.png new file mode 100644 index 0000000000000000000000000000000000000000..a065bc4725591832a4d02e29978fe1fb56c14256 GIT binary patch literal 1058 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 OfTz1JvK8^K{Qm+Mb7ay0 literal 0 HcmV?d00001 diff --git a/pkg/msvc/msvc-2017-UWP/Assets/StoreLogo.scale-400.png b/pkg/msvc/msvc-2017-UWP/Assets/StoreLogo.scale-400.png new file mode 100644 index 0000000000000000000000000000000000000000..bc17a33e34062cb476eb1f46c135c52d492ff927 GIT binary patch literal 3394 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 literal 0 HcmV?d00001 diff --git a/pkg/msvc/msvc-2017-UWP/Assets/Wide310x150Logo.scale-200.png b/pkg/msvc/msvc-2017-UWP/Assets/Wide310x150Logo.scale-200.png index 288995b397fdbef1fb7e85afd71445d5de1952c5..7053ee0bbf3031f8f88d0bbc0e2c167a0fb36b0c 100644 GIT binary patch literal 9276 zcmeHt_g9lm6lMZ~hz3LfHB`ky5l~4&?_CMf1f(M>38DGXq!+0w&4vV|2qg5Ngx;}W zLrO@1&=i#(Kq2(9limGg|AXCgmUG}8CYd`kcV_PM+-Ke-GgCttH=G*+fxwK7^ei9{ zHctoydXbA0)I^+H8UT+&zD76wAP}B+tY2uCPw{OCL}JlcPuuE#He>8ingF$>>o2>4 z1RqDNHa{PS9>2h)O9vibz7hY-z%shjYT!!i`-CFnl9$s@>cu_IB&teo9eY}QQNHM2 zlC{Z~GdHB3KD&14Oj&dl7o3A%Zw;;Gw4YLYs;j|o+kgF)M&0&yNh3$fC}DcMb=Bwl zX6}9o5{zlt&Wm;dJfmLl4S|Q6p$j{x6pn^LAnkq!P@t;k|MCy6o>cO6A+qx*<+<+f z?Giasy*n~^ctr!e=;YyCW&@New_(B|R)lJL(Dm`h`qDw?kl>yib<#zLdS5@HfePHivLl!uYP~| zN7jShHDB8FfsL4U&al^L-v{+F8`yo~R%-b6+MRF>t)G}@=u~lX0I8y4*K0Xb`2O0k z`+iUCq2njV4Sw~d!FvLtK%FkQbQRPR6%rM$!O{JhuUqL}gL_e=Z$29rt;#kuS=a2x} zH2dwi_V~`ZLDED=hx~;5ZP@Y%5$QFtG|{%daqij+&u?2{Q5S&`TM^a39lPbPeFGKH z2#PzIK$xmpV~peq?o9jL%;invU=!k&*(li^Xlzv3Du?E5BdTTxNpMj6us!~a>c#ov zkfV;vx-`Cy0UN8;cDc-8$j#GL`JY;!F%Lm}Ei%Ag*8f#>GWOjv z+{|&~+v_SWa1tRo5>-$L$onyB2JztM(`mPEJaTHWX$hqov`GGWHg%OQndTHU7BE#@kn(U< zn4>9Gb8n~>C1X?hje%nqR|nzej#OH?UCoz^_O;&}{QLC3_q1(JWib+;7|j0DlfZF% zx^<->r(Xr-Q2fNgSIw)#HvikEvuP=BZVevS(#Pl-xz6W=E?#CbnRf?@&C_$YTb9Cm z%I)jEk4EnAPUSt|dD|h&i_jsYzq{=AQ7NG&Q^6hIwAeUb4JmW`^Ctjmb_$Fk9V2a( zI^x~bZJNphM@atjlW$tMQXR1yqTu%Nh~KBv30C3xEri%QuaUdoHTT2(J_y(-sR#AF z)}MM|@BOBY7q`tn6x++0#}B;nsdcqTKC{BU4u9|0$4o=f;P?LXG}(WCKFxm(s`b}lJ)0aMfI4Bn8LcFf%Ipm_^KeOCmrxl0Vt<$*-LFl`%AI)To zBOv#gq{!i_f9>qNLq|`<5%v*p$$<>Jm92TwNUwFW%vk|iJdcRS$5gQ;vaJ@=yYx@! zuVh6NqUkIA?l==!QGSjL#XM~1Y|mutn%G-Yw9g<=)6Jy{$3mA{rVKT=(t}sJ727U- z`K^Hd6UUiX!Ksf>}W$ZWrb*xc?&nF61XrlnR}RMlqt&5domiPb&=biLO?5k zNQj!w3HAOx&7A3bXM#t3ek`g^H%<3=|9!oeP(|S2bZiQ&sZe@dyTqlwy-+r^nXbXlD{PYQUY|cR82O~@V5MWA9d)pm5GAl? z*TkgRcN<@L^?P*(L}&V}W%A301D6cw5QG76RF+3Q7^CZn(-<TF=zuBS; z6-{T-hl%~Ybv;*EJq){+3ws)OTrDvtMbOrvvAdH1DwO+kSN{xA8aPT0H@XV?MgH&p#$k@v>SB_IWQF&OlQ&QW>Eq8eAbTdApL+5No#Fumv)q1gSL1-!E;-Q*x)5Dz?1uQqPDg|LY?qe zao#HE$jFkmx&c4`2i}YGu1{^z@^VhiLq~*A-)6I^u{KP%9<`OnFo}xGPYTUc|NCt; z?Sy;XaznsFzIj<^J7hk<+k{lnYAub(*lNtN^zP~7)!gY_3%%y|(5hwHpHXU)bIo?J zlh5(p;~nTMKr*SrxW`s{6C`I%;`Chn{!--rNJ+-cYn@Sq#?sTe@k3c8c`t=8=J)#x z;24Gb>UNeJP96%uj*3`sIO&xLId13yug1)3^K%&+yx(`_1lU3}w>Yp$>8|vdXkCk+ zo@CTbpsr=e)hITSW1bs$r>OliQtg(c9;2B#Z8(WW?)+V|qr@aAHAx{1W!wT}OJ_-f zE_&3K&>;J5;Snhm~@yO_Oa*e$t;xD+m5g2s!Afzn!Z z{gNOWmvRgM)?gm(h$}hzRUK%238zn z9p6~_Z@|dFwvA>r+DkwQlsaE4J1Vkg!N40>)Z9Xp+nB(g`L|#n$#KYMv=inl?uppL zr`e*~ISa2wU$xY!bP8qE^iWC2qF%zRoWRSbSQJ6`kwm!&uDMgm*sTBZ>W)%?C;oN# zWYPr-)f12dC~;)t=?^8&l$lKYSA&LheVCWZi3$s9^6?LO>vj@N=+L}#hpwumSj*$c z)&=*?vH6cY<`9$Fv<8SiI2RVjXe1F3OiX($lhZ;l`Yopo4tX`2mx{gke(*zHqcJrF zSx3Ij1?nQuBZnInI&9_0SUtS}J%qe0 z5494jieS3oDwmwH^9nV~!p#Mm9p;CuG)q)!r;gGgL15_TN(Ynd+XQRfe9fiFaRItN z7da()&|R9$0n2kiUwmO#e~K29+V&bZ*Xr6B{&IN18zS~nv8Z-fG|WibR$&VM#9v`R zy18Dx8gH)-r}e``)s$$L^(6ozSNPF4nuJBJRh%J*n~P#(-Y`b$Mh4r8*5wzHtmV=Y zA_?|&-loi3$t5Z1rIyNQi|NAs>3$+wlOMxBRFi`K`KCdomN0!L7L}*QCX~iTC1DTe zYJ_hosrxYJsI^m)i?GH9YJuxMGDE7IU|nH%Cjx}otXHZ*bT^`QSAT1U!rgDa9`EPM z-nez)Z&u$OmRkNVT6S*E$?;&@&L4Tkz+K@|SBk_!7p-4ee=N^&x)A=g2EZ`$gcYnv z)Q;TS@2{B;ON<9QL)?28?|qkEeRG^9d=M;n2{3)wWAB*~saq0}b`6B)y-N9x*5_qN-_5EBG_WjKO&pDV4 zPd-dC74)H{*rsHe26$ktqDKbD!6L-?C8ucF&!UAPl`(jO&VFuB*Wz!7TfT=Bz8MZN zA_YBJM-PN9%@T9vZg$aZpXC+0&9r1`Mz(H#4{H78FIPHiUsh!BEm^+=YuRgEaVJ})*7TK1jcpfg z)d8SR7#~<}$#Q4PJAK=>7yc^b%VQ@~l_t5SoqW+)y>rdMuNz}SgBu;}|9H?lBRrQ{ z)^jK|0U}x<+vKRqOCX2`z_E} zt+iewsA`uEHe$Qrnj58|UYrbd)&ouZyU&^K;zR7ET#AsL1ffcA-+MME&u9*?Gk7C6 zbPH8#KVC(r&YgrCTT6_lOBkxWdNem=HwTurfh!-jaR7{6i((|A;_qAOOexMLB=ukH z989*Rn8IMN5|QIn(b4q{Cc<{S`?&&d%ms{H6zOPJ5EaxHH;NvXmLhlc(&H@}9Do$96mEnSj=JGB&Fe#Gzy)kC#fk!99UygJk$0 zf8lV0$$>XW!qNk41<5OHLPwv@4U*xO1qbE)DV8pjZejz^#y#)K#y1{~Qs1XmK3(8I zp&M|n*G8QpUA4Hg4tyPL@MCzxJr@4&)9E#be*mjpXb@+ASU^ zFpJb+#G$m(mp?;qu{Hw{*%UB;mw?V%i%UoB)^*}j=2gBBre_HzyKtRSw=A{bw`07t zfaiCH&KUeG{foGLKUp+nCf~G+V&t41;R)G$(9Ze3P{<}*%7{ZPqc7>AnanfZ1d%{n z8gV(ZDn-^9En;>Xgt+*s2w9T;-cJArw&^eScDF6NIM22dITKHV4gJCj^2M@(sG)Fg z`wdjT3)E^yqmjzkHFNfVCdolh*WB12J_h~dsR%O$U)s1%$cm!}-a!8X24`66O!4^E zOd}=HlV{?;OtKdysi4F)G%iO;2>dSVx{)(K$bXgUb8UBQZfvE9cdH&Rc=o-i9I~>Pp6Te`geYs)igCgO>o1I(6PShd~@!EOuj`{7GR`;sWcp&dafU2pkdxvj40Fo6wJ_>xX}6 zF>&miM|{UM`P(m8b)o!c%;tcj4xrkjJ-jCu#JGQGl9#n83}BnJsS^Rl3xsuvMTXIc zY*t8FwPF%Uaiq@2-Htyo@jCa>^xA^{Ipev(sM}WWXn+=Ny@B#<6him_Bl1sf6cRrb zM~;u@REXRQ)3~ms2bMafigtc!cQA_f-{`%raGKgnmH&wyN2B3gr4fw6r>0-FtfCxx zul9X^rJ4njroJWKL;(DHd3(50=XuaG7{~8UK0{$w-0+KwH+5Xt&j8o)70Yb5N3)mI zK`matIup+;<~`M&)iuq{YWgf6E<~kcZj1n;?-iO_-eV}sN3ZkAoej=YDS7@e9wu~U zqS~s!gZ{b{^atk62PoYYe+hG?ke$C>-GFm$zZJ^2dD8jXn`}ui$&Z%56}-);>wbCJ z?aIVg%fUBSVME9REDX{kgLHO;F7cHQHFi66Z2=pyzW8cbIj@lkvKVh(khl5V(GV!< zH4sCI!!@L|^zfaB>L`7mv;@f+B_6Yg=Lg>BrxE&w1!Sy;RIWg%(e0c{{rn{c9B;Y2 z;A50p4XtC1@j3S=lgh8NN3ny@p?i|fpNE*F!8=<_W;qfH$(xNKdD!S@amW?@X z0qu+*i;F`g&y++YcTcB33p_Q`SCDYCHB31gR(veXBKm-x0vX$(3lv3$q)=L{pa`Zg z@bBb@OnEiPQ5JzHuF=U#i3DWPW?@58(D7QSTfsrNnFxrL+?~DFC2?HbIG}pnUI{KV z01VQrJl(!Fo^6N4nJhk23sk1e4Mpxe`Vfs+ogeI3{L|n$3?iNx2aD!P3((2CP-#A0Ys$Q&ptwTqAsASN-?(FeA%) zT)csArXa@-$or(vR!lVlysBA+^cRNfQ&W>wQ0&vc&_AGVM0IWWvsIim#ZdePB7SDN=Ui5B|4uH`e@A*=pn3exdp!vmppSa3z1)ga z4P3Z1u|=!%oTw}$2mKM--{>-$UQ$42i75YfTbh(K*R?wC@ujI@{n}FSGn_#WHJ94( zeA{nJTdQkeTU1V|cL}=j2#n?o$o#X4_Z9|9EE(NH`q^Mfx!dsph6gb`g$)Nx;WWSmGg!3xaKtt%pky`Eop-7nmgoB>lHYLil z%1Ecdp^k%MCNAtOP2BEgHnrgS_;O1_*3JuAdr#X?(AXqH&heOtbNoqJf zs5N{WAG+9Z;hyc&&rdI8u_#^xw*0Ag%3=JK=<}u5`e% zhrAe!yKc(`4Fh`e?X&Z}*3#uAchMAopr~bxwINE}bHiynQ;Ka;Hw$ib^OqwWD||!8 zgQw4_Sg$XRbr%{x{dO+H;g-hEvhH?>fI1o3>hv#=0jUIgF#avKSCMyww3dxeWzz8r zg#N3y*A|BFcE%nG>TQGP`*Gh5D*bIjsee=r?dTz ziTQx}1g3Xn`Ltr^Y5(9fy@@Qg+0q+j3uj_|w-l4i3k)(@sE@^>o8HD8heX4c^>DGZ zQwDPUO5{&J4r*>hH|+fTYPlI|rA3O_QIoxbNpjMa6~6!X!-;N?2YVZSdeToWw#zRz zFeOP8m}1*^DEy~m-t&}%UXkEReGg|b9Wcq?|yuIDk-Q`>E9=b z?%nkXAGy|zTh*@bI77%#4#0KQUfd2L56s}LeM{RiwhCavN|$D(=;rOtJCi4-s5Z_u zmVp~*$=Lk%oz0bQ*}BnN5AOAcv>rEA>M&Jw4jjG{x75eU57_#$Lv}CCf`nA(KhwI| z?L+u4B312QVlarchpW#F#5o;jtmc(WBdmW!FmTS*+V&Db!Hhm@a-6i5)#f&tUHSJh z`qi=J0UX*g!^Sy0VAAWEj>p*LJ74(i-9IF+JzB-j)b!yBpBK2l3b3AZOA%J?ZwBY8 zHsI=b2>BiiS_IHt+FXvcx|D%T>)5^J1Wkn7$H&Hh!obPDoAt}1FaclMμl1gu+y zFk_-Ea?;Ji&WfQS3PfmC*sFxRrwL2Y;I3J>231?yQf5+A{t~sl&R4eWg;aZw zsaVUt$RC^nnk^YRkH=NMd33Zfkb&Q*2a^X@B z3@%%|7|%i~iUM?V0X5xR$=&~U=E2ET(QnzxluCHZ8Xb3B>^k#a(0DMhVdnLt1t-Ge zK(iKp#f!5h}J(-a~>Z-DK$$TxU4cM=Mb9*o4nBzxY#g#UV{)q9t)ZX zuQkjf7?l-aFAwtm0Kjkc#)8!xb#GEn0n?jjwI_#;9uJwX$ffq37Hx5+!?c&sES1DR zzygds9VIK-7n=JK<@Q|9mVNXuNzUvKJ|0DVIlDergSz!T(P}SceIjx~u)$}%ITKsQ zk7+aaf)V0`SW2^c=$c8`H;SohH>U>^V_C-Qtc!GoC3f{(M?fyPVk{rQ&~Z)y)EgyC zJ4#~m8kb|Ee@TVCMEN=5pqXVxsVW6mCS{SFcpm97AXy#4^iYLWx-cwR>yUON8ulrv z%9{~$Sk9I<0tI)|mq)7xcwae> zPbfJSYvr}G@wY@|9V8$MmPFHAXi{p) z>|YYVi>aavrz`V=q`D^A+i_J~g&@=T9mV}EXmJ#4XbtXU3anB}%vHx`kUF|!c6X%s zac>gG+X`U;x{c>o_xNa0VSqI%=XZ|G#V!Kkv*yl zlrIttq3zBkjI>3zg+n0Htj6hhJY4n5McLkKJd;Q2)Aj{I$3RCC78gQMk4v$nz6{dM$n7Z zf&6YUP~KvdkL1gS#v;YVz`Ud%_P!A5gr|vtaSIq?aE=F%;*p@<J?{itik{xA-d{bErN%qif86I@<>mm4|xc|lnb814nS7&i{k>m!!;6MN$Y zmoxQU`G(AHhgNGq5vjfLQvgTfdoFT60yoUudw(Ny?ZhMb=)EsB$~tPQPS3AE-s-sM zriZ6759Qs7MIi)ZYis`Z?J&0t7rXr8NL|m~Z_~PP&}eyf1}`e_9xkV4&E+XsKGqb} zW@m5TL;%;&Tx?krTweR;1K6D(2{Orv$H8Uw0Te&2Gw!e=uc+F_e#|9b5$*QK*xJc> zWXrm?%l5k%j>D2}TCA~RYHDhD7si^_pZtjLE&8OLXUDHh7Emkq;%VJ)s@6CmehrwS zFAP`PC?XIJVxvbQbY<-WB<(OV9%jeGmvS|{vlV^DvsgFa=YTVOzGo}9i2!Bm5U^|G z!N->09m(w#lKXGZNkF}vIxz4OggCWkmyVeIZg8<)4q&SNCcrS}N{^=V@z`1!ezu2K zLM*%e754rAxX_3(&!p01s-()jM(h9nEAKhD42_0ynY_HDt&7w=rFMUL^2go3kHqT( zB#vyzXNz`k8`+!B><+kra6JE@XPj~Pgj{wuc&DHh9F*j5td|Gk7Xbw9I?!-nq z`L4_uOD@|h^}iTgCvs6J?0z=Gcg3y<6e_J^Mz7yrvM! zbLhQz{i|c6My9;plFW`l9`Hck%oW3D47R`U3;lLMHKqLUc-t_Tzx;vRHr{FtsdkWn y=fwg6)ayt@@E+wL1d<6}xcGnd9=~D#;N#%+pKo$CD!>~F5MzB)y-FRInEwG}-+;pa literal 3204 zcmbVPeQXow8NYmBd90>}0NP?GhXW~VaeThm=a0tV#EwJMI!)6M3}|c4_Bl3=Kd>G0 z(GHx1wl<7(tP?FsOQkTilSo*iIvF%uArExJ73~P zSv1xEy!U(Wd4A9D`FQV@W3@F^qJ@PEF$@z`Z!*BbFsS(^?B zyiAzJ+q})bkgiQHWqEb*jJD-coHYr1^iocg)l!Qa{Xqs-l~6J}p-|##ZHYofskQ3$ zI0;xzXyhazBeXhIsg5A=%ufo@f)1yy&ScKS0;HF^!r_2UE^lpZEom(+@duma3awTv zCrCL-%D_SvYWIcdHkmI}#50(fkUi)Qgx!80ju>g1za^}ff>JI8Z@^-iCiaCgg@TgF z+vtE?Q9{VQUX&MW9SYYmGcxA14%N2@7FwBTD4N<(2{nWgV8$e3?-F=L^&FrtWn~(U_Q~~^uYiyeY6-KoTnfh9AWz@ zIKje0)u!_Lw)E}G!#kEfwKVdNt(UAf9*f>tEL_(=xco-T%jTi@7YlC3hs2ik%Le0H ztj}RTeCF(5mwvi3_56>-yB?l;J>-1%!9~=fs|QcNG3J~a@JCu`4SB460s0ZO+##4fFUSGLcj_ja^fL4&BKALfb#$6$O?>P@qx2Agl^x0i&ugt zsy5Pyu=()`7HRMG3IB7F1@`_ z+-!J%#i6e^U$e#+C%Q>_qVRzWRsG^W_n+@OcX@vzI&z;mzHNb!GQ?LWA(wtpqHqTM z1OFw_{Zn?fD)p)`c`kOgv{de=v@suGRqY{N^U7gI1VF3*F=obwaXI6ob5__Yn zVTguS!%(NI09J8x#AO_aW!9W7k*UvB;IWDFC3srwftr{kHj%g)fvnAm;&h_dnl~

MY- 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

ODFl(mlLT>jXv8_y@8P_bZl?G%h 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 - - - - - - - + + + - msvc-2017-UWP - krzys + RetroArch + libretro Assets\StoreLogo.png - - - + - - - - + + + + - + \ No newline at end of file diff --git a/pkg/msvc/msvc-2017-UWP/RetroArch-msvc2017-UWP.vcxproj b/pkg/msvc/msvc-2017-UWP/RetroArch-msvc2017-UWP.vcxproj index 0836dbbee9..b6c0469a17 100644 --- a/pkg/msvc/msvc-2017-UWP/RetroArch-msvc2017-UWP.vcxproj +++ b/pkg/msvc/msvc-2017-UWP/RetroArch-msvc2017-UWP.vcxproj @@ -38,7 +38,7 @@ {f5e937b6-1ba0-4446-b94b-f3bbdef908f4} DirectXApp RetroArchUWP - pl-PL + en-US 14.0 true Windows Store @@ -252,15 +252,6 @@ WIN32;HAVE_MAIN;HAVE_DYNAMIC;HAVE_XAUDIO2;RARCH_INTERNAL;HAVE_CC_RESAMPLER;HAVE_SLANG;HAVE_SPIRV_CROSS;HAVE_UPDATE_ASSETS;HAVE_D3D;HAVE_D3D11;ENABLE_HLSL;RC_DISABLE_LUA;HAVE_CHEEVOS;HAVE_RUNAHEAD;HAVE_GRIFFIN;HAVE_LANGEXTRA;HAVE_FBO;HAVE_ZLIB;HAVE_XMB;HAVE_SHADERPIPELINE;WANT_ZLIB;HAVE_RPNG;HAVE_RJPEG;HAVE_RBMP;HAVE_RTGA;HAVE_IMAGEVIEWER;NDEBUG;_WINDOWS;%(PreprocessorDefinitions);HAVE_XINPUT;HAVE_XINPUT2;HAVE_XAUDIO;HAVE_DIRECTX;HAVE_NETWORKING;HAVE_NETWORK_CMD;HAVE_NETPLAYDISCOVERY;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;__SSE__;__i686__;HAVE_OVERLAY;HAVE_MENU;HAVE_RGUI;HAVE_MATERIALUI;HAVE_LIBRETRODB;HAVE_STB_FONT;HAVE_STATIC_DUMMY;HAVE_STATIC_VIDEO_FILTERS;HAVE_STATIC_AUDIO_FILTERS - - - - - - - - - false @@ -497,6 +488,35 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/pkg/msvc/msvc-2017-UWP/RetroArch-msvc2017-UWP.vcxproj.filters b/pkg/msvc/msvc-2017-UWP/RetroArch-msvc2017-UWP.vcxproj.filters index a133f33c90..e62f02f8a1 100644 --- a/pkg/msvc/msvc-2017-UWP/RetroArch-msvc2017-UWP.vcxproj.filters +++ b/pkg/msvc/msvc-2017-UWP/RetroArch-msvc2017-UWP.vcxproj.filters @@ -15,33 +15,10 @@ {bf1e643d-c518-4a77-a355-ae8a93efc18b} - - {ba77ad30-f536-4bb8-ad9d-2870e8a9bd39} + + {c3155604-6d38-494a-bfe0-861cef871cb2} - - - assets - - - assets - - - assets - - - assets - - - assets - - - assets - - - assets - - @@ -277,4 +254,87 @@ uwp + + + Assets + + + Assets + + + Assets + + + Assets + + + Assets + + + Assets + + + Assets + + + Assets + + + Assets + + + Assets + + + Assets + + + Assets + + + Assets + + + Assets + + + Assets + + + Assets + + + Assets + + + Assets + + + Assets + + + Assets + + + Assets + + + Assets + + + Assets + + + Assets + + + Assets + + + Assets + + + Assets + + \ No newline at end of file From cc686ba9bcdd8a0cb36165fdb7229282f682d3f0 Mon Sep 17 00:00:00 2001 From: krzys-h Date: Fri, 28 Dec 2018 11:42:24 +0100 Subject: [PATCH 3/5] Upgrade XAudio2 headers XAudio 2.7 was part of the old DirectX SDKs. XAudio 2.8+ is part of the Windows OS itself (starting from Windows 8). Since UWP lets you access only libraries that are built-in to the OS, the headers had to be upgraded to the newer version to get audio support working. --- audio/drivers/xaudio.c | 5 + audio/drivers/xaudio.h | 358 +---------- audio/drivers/xaudio27.h | 364 +++++++++++ audio/drivers/xaudio29.h | 1313 ++++++++++++++++++++++++++++++++++++++ 4 files changed, 1692 insertions(+), 348 deletions(-) create mode 100644 audio/drivers/xaudio27.h create mode 100644 audio/drivers/xaudio29.h diff --git a/audio/drivers/xaudio.c b/audio/drivers/xaudio.c index d344508b70..b8f2c73ad7 100644 --- a/audio/drivers/xaudio.c +++ b/audio/drivers/xaudio.c @@ -222,8 +222,13 @@ static xaudio2_t *xaudio2_new(unsigned samplerate, unsigned channels, if (FAILED(XAudio2Create(&handle->pXAudio2, 0, XAUDIO2_DEFAULT_PROCESSOR))) goto error; +#if (_WIN32_WINNT >= 0x0602 /*_WIN32_WINNT_WIN8*/) + if (FAILED(IXAudio2_CreateMasteringVoice(handle->pXAudio2, &handle->pMasterVoice, channels, samplerate, 0, device, NULL, AudioCategory_GameEffects))) + goto error; +#else if (FAILED(IXAudio2_CreateMasteringVoice(handle->pXAudio2, &handle->pMasterVoice, channels, samplerate, 0, device, NULL))) goto error; +#endif xaudio2_set_wavefmt(&wfx, channels, samplerate); diff --git a/audio/drivers/xaudio.h b/audio/drivers/xaudio.h index 788fe16789..a16581807f 100644 --- a/audio/drivers/xaudio.h +++ b/audio/drivers/xaudio.h @@ -1,7 +1,5 @@ /* RetroArch - A frontend for libretro. - * Copyright (C) 2010-2014 - Hans-Kristian Arntzen - * Copyright (C) 2011-2017 - Daniel De Matteis - * Copyright (C) 2010-2014 - OV2 + * Copyright (C) 2018 - Krzysztof Haładyn * * RetroArch is free software: you can redistribute it and/or modify it under the terms * of the GNU General Public License as published by the Free Software Found- @@ -15,350 +13,14 @@ * If not, see . */ -/* Kinda stripped down. Only contains the bare essentials used in RetroArch. */ - -#ifndef XAUDIO2_STRIPPED_H -#define XAUDIO2_STRIPPED_H - -#include -#include - -/* All structures defined in this file use tight field packing */ -#pragma pack(push, 1) - -#if defined(__cplusplus) && !defined(CINTERFACE) -#define X2DEFAULT(x) = (x) +#if (_WIN32_WINNT >= 0x0602 /*_WIN32_WINNT_WIN8*/) +/* XAudio 2.7 it part of the old DirectX SDKs. XAudio 2.8+ is part of the + * Windows OS itself (starting from Windows 8). Since UWP lets you access + * only libraries that are built-in to the OS, the headers had to be + * upgraded to the newer version to get audio support working. */ +#include "xaudio29.h" #else -#define X2DEFAULT(x) +/* The old version still has to be there since XAudio 2.8 is not available + * on Windows 7 and earlier */ +#include "xaudio27.h" #endif - -#ifdef _XBOX -#include - -#ifndef __cplusplus -#define OPAQUE interface -#endif -#define DEFINE_CLSID(className, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8) \ - DEFINE_GUID(CLSID_##className, 0x##l, 0x##w1, 0x##w2, 0x##b1, 0x##b2, 0x##b3, 0x##b4, 0x##b5, 0x##b6, 0x##b7, 0x##b8) -#define DEFINE_IID(interfaceName, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8) \ - DEFINE_GUID(IID_##interfaceName, 0x##l, 0x##w1, 0x##w2, 0x##b1, 0x##b2, 0x##b3, 0x##b4, 0x##b5, 0x##b6, 0x##b7, 0x##b8) - -DEFINE_CLSID(XAudio2, 3eda9b49, 2085, 498b, 9b, b2, 39, a6, 77, 84, 93, de); -DEFINE_CLSID(XAudio2_Debug, 47199894, 7cc2, 444d, 98, 73, ce, d2, 56, 2c, c6, 0e); -DEFINE_IID(IXAudio2, 8bcf1f58, 9fe7, 4583, 8a, c6, e2, ad, c4, 65, c8, bb); - -#include /* Basic audio data types and constants */ - -#else - -#define WIN32_LEAN_AND_MEAN -#include -#include -#include -#include - -#ifndef __cplusplus -#undef OPAQUE -#define OPAQUE struct -#endif - -#define DEFINE_GUID_X(n, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8) \ - static const GUID n = { l, w1, w2, { b1, b2, b3, b4, b5, b6, b7, b8 } } -#define DEFINE_CLSID_X(className, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8) \ - DEFINE_GUID_X(CLSID_##className, 0x##l, 0x##w1, 0x##w2, 0x##b1, 0x##b2, 0x##b3, 0x##b4, 0x##b5, 0x##b6, 0x##b7, 0x##b8) -#define DEFINE_IID_X(interfaceName, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8) \ - DEFINE_GUID_X(IID_##interfaceName, 0x##l, 0x##w1, 0x##w2, 0x##b1, 0x##b2, 0x##b3, 0x##b4, 0x##b5, 0x##b6, 0x##b7, 0x##b8) - -#ifndef __cplusplus -#ifndef INTERFACE -#define INTERFACE void -#endif -#endif - -DEFINE_CLSID_X(XAudio2, 5a508685, a254, 4fba, 9b, 82, 9a, 24, b0, 03, 06, af); /* 2.7 */ -DEFINE_IID_X(IXAudio2, 8bcf1f58, 9fe7, 4583, 8a, c6, e2, ad, c4, 65, c8, bb); - -#endif - -#ifdef _XBOX -#define XAUDIO2_DEFAULT_FREQ_RATIO 2.0f -#else -#define XAUDIO2_DEFAULT_FREQ_RATIO 4.0f -#endif - -#define XAUDIO2_COMMIT_NOW 0 -#define XAUDIO2_DEFAULT_CHANNELS 0 -#define XAUDIO2_DEFAULT_SAMPLERATE 0 - -#define XAUDIO2_DEBUG_ENGINE 0x0001 -#define XAUDIO2_VOICE_NOSRC 0x0004 - -typedef enum XAUDIO2_DEVICE_ROLE -{ - NotDefaultDevice = 0x0, - DefaultConsoleDevice = 0x1, - DefaultMultimediaDevice = 0x2, - DefaultCommunicationsDevice = 0x4, - DefaultGameDevice = 0x8, - GlobalDefaultDevice = 0xf, - InvalidDeviceRole = ~GlobalDefaultDevice -} XAUDIO2_DEVICE_ROLE; - -#ifdef _XBOX -typedef enum XAUDIO2_XBOX_HWTHREAD_SPECIFIER -{ - XboxThread0 = 0x01, - XboxThread1 = 0x02, - XboxThread2 = 0x04, - XboxThread3 = 0x08, - XboxThread4 = 0x10, - XboxThread5 = 0x20, - XAUDIO2_ANY_PROCESSOR = XboxThread4, - XAUDIO2_DEFAULT_PROCESSOR = XAUDIO2_ANY_PROCESSOR -} XAUDIO2_XBOX_HWTHREAD_SPECIFIER, XAUDIO2_PROCESSOR; -#else -typedef enum XAUDIO2_WINDOWS_PROCESSOR_SPECIFIER -{ -#if defined(__STDC_C89__) - XAUDIO2_ANY_PROCESSOR = 0xffff, -#else - XAUDIO2_ANY_PROCESSOR = 0xffffffff, -#endif - XAUDIO2_DEFAULT_PROCESSOR = XAUDIO2_ANY_PROCESSOR -} XAUDIO2_WINDOWS_PROCESSOR_SPECIFIER, XAUDIO2_PROCESSOR; -#endif - -typedef enum XAUDIO2_FILTER_TYPE { - LowPassFilter, - BandPassFilter, - HighPassFilter -} XAUDIO2_FILTER_TYPE; - -typedef struct XAUDIO2_DEVICE_DETAILS -{ - WCHAR DeviceID[256]; - WCHAR DisplayName[256]; - XAUDIO2_DEVICE_ROLE Role; - WAVEFORMATEXTENSIBLE OutputFormat; -} XAUDIO2_DEVICE_DETAILS; - -/* Forward declarations. */ -#ifdef __cplusplus -struct XAUDIO2_VOICE_DETAILS; -struct XAUDIO2_VOICE_SENDS; -struct XAUDIO2_EFFECT_DESCRIPTOR; -struct XAUDIO2_EFFECT_CHAIN; -struct XAUDIO2_FILTER_PARAMETERS; -struct XAUDIO2_BUFFER_WMA; -struct XAUDIO2_VOICE_STATE; -struct XAUDIO2_PERFORMANCE_DATA; -struct XAUDIO2_DEBUG_CONFIGURATION; -struct IXAudio2EngineCallback; -struct IXAudio2SubmixVoice; -#else -typedef OPAQUE XAUDIO2_VOICE_DETAILS XAUDIO2_VOICE_DETAILS; -typedef OPAQUE XAUDIO2_VOICE_SENDS XAUDIO2_VOICE_SENDS; -typedef OPAQUE XAUDIO2_EFFECT_DESCRIPTOR XAUDIO2_EFFECT_DESCRIPTOR; -typedef OPAQUE XAUDIO2_EFFECT_CHAIN XAUDIO2_EFFECT_CHAIN; -typedef OPAQUE XAUDIO2_FILTER_PARAMETERS XAUDIO2_FILTER_PARAMETERS; -typedef OPAQUE XAUDIO2_BUFFER_WMA XAUDIO2_BUFFER_WMA; -typedef OPAQUE XAUDIO2_VOICE_STATE XAUDIO2_VOICE_STATE; -typedef OPAQUE XAUDIO2_PERFORMANCE_DATA XAUDIO2_PERFORMANCE_DATA; -typedef OPAQUE XAUDIO2_DEBUG_CONFIGURATION XAUDIO2_DEBUG_CONFIGURATION; -typedef OPAQUE IXAudio2EngineCallback IXAudio2EngineCallback; -typedef OPAQUE IXAudio2SubmixVoice IXAudio2SubmixVoice; -#endif - - -typedef struct XAUDIO2_BUFFER -{ - UINT32 Flags; - UINT32 AudioBytes; - const BYTE* pAudioData; - UINT32 PlayBegin; - UINT32 PlayLength; - UINT32 LoopBegin; - UINT32 LoopLength; - UINT32 LoopCount; - void *pContext; -} XAUDIO2_BUFFER; - -#undef INTERFACE -#define INTERFACE IXAudio2VoiceCallback - -DECLARE_INTERFACE(IXAudio2VoiceCallback) -{ - STDMETHOD_(void, OnVoiceProcessingPassStart) (THIS_ UINT32 BytesRequired) PURE; - STDMETHOD_(void, OnVoiceProcessingPassEnd) (THIS) PURE; - STDMETHOD_(void, OnStreamEnd) (THIS) PURE; - STDMETHOD_(void, OnBufferStart) (THIS_ void *pBufferContext) PURE; - STDMETHOD_(void, OnBufferEnd) (THIS_ void *pBufferContext) PURE; - STDMETHOD_(void, OnLoopEnd) (THIS_ void *pBufferContext) PURE; - STDMETHOD_(void, OnVoiceError) (THIS_ void *pBufferContext, HRESULT Error) PURE; -}; - -#undef INTERFACE -#define INTERFACE IXAudio2Voice - -DECLARE_INTERFACE(IXAudio2Voice) -{ -#define Declare_IXAudio2Voice_Methods() \ - STDMETHOD_(void, GetVoiceDetails) (THIS_ XAUDIO2_VOICE_DETAILS* pVoiceDetails) PURE; \ - STDMETHOD(SetOutputVoices) (THIS_ const XAUDIO2_VOICE_SENDS* pSendList) PURE; \ - STDMETHOD(SetEffectChain) (THIS_ const XAUDIO2_EFFECT_CHAIN* pEffectChain) PURE; \ - STDMETHOD(EnableEffect) (THIS_ UINT32 EffectIndex, \ - UINT32 OperationSet X2DEFAULT(XAUDIO2_COMMIT_NOW)) PURE; \ - STDMETHOD(DisableEffect) (THIS_ UINT32 EffectIndex, \ - UINT32 OperationSet X2DEFAULT(XAUDIO2_COMMIT_NOW)) PURE; \ - STDMETHOD_(void, GetEffectState) (THIS_ UINT32 EffectIndex, BOOL* pEnabled) PURE; \ - STDMETHOD(SetEffectParameters) (THIS_ UINT32 EffectIndex, \ - const void *pParameters, \ - UINT32 ParametersByteSize, \ - UINT32 OperationSet X2DEFAULT(XAUDIO2_COMMIT_NOW)) PURE; \ - STDMETHOD(GetEffectParameters) (THIS_ UINT32 EffectIndex, void *pParameters, \ - UINT32 ParametersByteSize) PURE; \ - STDMETHOD(SetFilterParameters) (THIS_ const XAUDIO2_FILTER_PARAMETERS* pParameters, \ - UINT32 OperationSet X2DEFAULT(XAUDIO2_COMMIT_NOW)) PURE; \ - STDMETHOD_(void, GetFilterParameters) (THIS_ XAUDIO2_FILTER_PARAMETERS* pParameters) PURE; \ - STDMETHOD_(void, SetOutputFilterParameters) (THIS_ IXAudio2Voice *voice, const XAUDIO2_FILTER_PARAMETERS* param, \ - UINT32 op X2DEFAULT(XAUDIO2_COMMIT_NOW)) PURE; \ - STDMETHOD_(void, GetOutputFilterParameters) (THIS_ IXAudio2Voice *voice, XAUDIO2_FILTER_PARAMETERS* param) PURE; \ - STDMETHOD(SetVolume) (THIS_ float Volume, \ - UINT32 OperationSet X2DEFAULT(XAUDIO2_COMMIT_NOW)) PURE; \ - STDMETHOD_(void, GetVolume) (THIS_ float* pVolume) PURE; \ - STDMETHOD(SetChannelVolumes) (THIS_ UINT32 Channels, const float* pVolumes, \ - UINT32 OperationSet X2DEFAULT(XAUDIO2_COMMIT_NOW)) PURE; \ - STDMETHOD_(void, GetChannelVolumes) (THIS_ UINT32 Channels, float* pVolumes) PURE; \ - STDMETHOD(SetOutputMatrix) (THIS_ IXAudio2Voice* pDestinationVoice, \ - UINT32 SourceChannels, UINT32 DestinationChannels, \ - const float* pLevelMatrix, \ - UINT32 OperationSet X2DEFAULT(XAUDIO2_COMMIT_NOW)) PURE; \ - STDMETHOD_(void, GetOutputMatrix) (THIS_ IXAudio2Voice* pDestinationVoice, \ - UINT32 SourceChannels, UINT32 DestinationChannels, \ - float* pLevelMatrix) PURE; \ - STDMETHOD_(void, DestroyVoice) (THIS) PURE - - Declare_IXAudio2Voice_Methods(); -}; - -#undef INTERFACE -#define INTERFACE IXAudio2MasteringVoice - -DECLARE_INTERFACE_(IXAudio2MasteringVoice, IXAudio2Voice) -{ - Declare_IXAudio2Voice_Methods(); -}; - -#undef INTERFACE -#define INTERFACE IXAudio2SourceVoice - -DECLARE_INTERFACE_(IXAudio2SourceVoice, IXAudio2Voice) -{ - Declare_IXAudio2Voice_Methods(); - STDMETHOD(Start) (THIS_ UINT32 Flags, UINT32 OperationSet X2DEFAULT(XAUDIO2_COMMIT_NOW)) PURE; - STDMETHOD(Stop) (THIS_ UINT32 Flags, UINT32 OperationSet X2DEFAULT(XAUDIO2_COMMIT_NOW)) PURE; - STDMETHOD(SubmitSourceBuffer) (THIS_ const XAUDIO2_BUFFER* pBuffer, const XAUDIO2_BUFFER_WMA* pBufferWMA X2DEFAULT(NULL)) PURE; - STDMETHOD(FlushSourceBuffers) (THIS) PURE; - STDMETHOD(Discontinuity) (THIS) PURE; - STDMETHOD(ExitLoop) (THIS_ UINT32 OperationSet X2DEFAULT(XAUDIO2_COMMIT_NOW)) PURE; - STDMETHOD_(void, GetState) (THIS_ XAUDIO2_VOICE_STATE* pVoiceState) PURE; - STDMETHOD(SetFrequencyRatio) (THIS_ float Ratio, - UINT32 OperationSet X2DEFAULT(XAUDIO2_COMMIT_NOW)) PURE; - STDMETHOD_(void, GetFrequencyRatio) (THIS_ float* pRatio) PURE; -}; - -#undef INTERFACE -#define INTERFACE IXAudio2 - -DECLARE_INTERFACE_(IXAudio2, IUnknown) -{ - STDMETHOD(QueryInterface) (THIS_ REFIID riid, void** ppvInterface) PURE; - STDMETHOD_(ULONG, AddRef) (THIS) PURE; - STDMETHOD_(ULONG, Release) (THIS) PURE; - STDMETHOD(GetDeviceCount) (THIS_ UINT32* pCount) PURE; - STDMETHOD(GetDeviceDetails) (THIS_ UINT32 Index, XAUDIO2_DEVICE_DETAILS* pDeviceDetails) PURE; - STDMETHOD(Initialize) (THIS_ UINT32 Flags X2DEFAULT(0), - XAUDIO2_PROCESSOR XAudio2Processor X2DEFAULT(XAUDIO2_DEFAULT_PROCESSOR)) PURE; - STDMETHOD(RegisterForCallbacks) (IXAudio2EngineCallback* pCallback) PURE; - STDMETHOD_(void, UnregisterForCallbacks) (IXAudio2EngineCallback* pCallback) PURE; - STDMETHOD(CreateSourceVoice) (THIS_ IXAudio2SourceVoice** ppSourceVoice, - const WAVEFORMATEX* pSourceFormat, - UINT32 Flags X2DEFAULT(0), - float MaxFrequencyRatio X2DEFAULT(XAUDIO2_DEFAULT_FREQ_RATIO), - IXAudio2VoiceCallback* pCallback X2DEFAULT(NULL), - const XAUDIO2_VOICE_SENDS* pSendList X2DEFAULT(NULL), - const XAUDIO2_EFFECT_CHAIN* pEffectChain X2DEFAULT(NULL)) PURE; - STDMETHOD(CreateSubmixVoice) (THIS_ IXAudio2SubmixVoice** ppSubmixVoice, - UINT32 InputChannels, UINT32 InputSampleRate, - UINT32 Flags X2DEFAULT(0), UINT32 ProcessingStage X2DEFAULT(0), - const XAUDIO2_VOICE_SENDS* pSendList X2DEFAULT(NULL), - const XAUDIO2_EFFECT_CHAIN* pEffectChain X2DEFAULT(NULL)) PURE; - STDMETHOD(CreateMasteringVoice) (THIS_ IXAudio2MasteringVoice** ppMasteringVoice, - UINT32 InputChannels X2DEFAULT(XAUDIO2_DEFAULT_CHANNELS), - UINT32 InputSampleRate X2DEFAULT(XAUDIO2_DEFAULT_SAMPLERATE), - UINT32 Flags X2DEFAULT(0), UINT32 DeviceIndex X2DEFAULT(0), - const XAUDIO2_EFFECT_CHAIN* pEffectChain X2DEFAULT(NULL)) PURE; - STDMETHOD(StartEngine) (THIS) PURE; - STDMETHOD_(void, StopEngine) (THIS) PURE; - STDMETHOD(CommitChanges) (THIS_ UINT32 OperationSet) PURE; - STDMETHOD_(void, GetPerformanceData) (THIS_ XAUDIO2_PERFORMANCE_DATA* pPerfData) PURE; - STDMETHOD_(void, SetDebugConfiguration) (THIS_ const XAUDIO2_DEBUG_CONFIGURATION* pDebugConfiguration, - void *pReserved X2DEFAULT(NULL)) PURE; -}; - -#if defined(__cplusplus) && !defined(CINTERFACE) -/* C++ hooks */ -#define IXAudio2_Initialize(handle,a,b) handle->Initialize(a, b) -#define IXAudio2SourceVoice_SubmitSourceBuffer(handle, a, b) handle->SubmitSourceBuffer(a, b) -#define IXAudio2SourceVoice_Stop(handle, a, b) handle->Stop(a, b) -#define IXAudio2SourceVoice_DestroyVoice(handle) handle->DestroyVoice() -#define IXAudio2MasteringVoice_DestroyVoice(handle) handle->DestroyVoice() -#define IXAudio2_Release(handle) handle->Release() -#define IXAudio2_CreateSourceVoice(handle, a, b, c, d, e, f, g) handle->CreateSourceVoice(a, b, c, d, e, f, g) -#define IXAudio2_CreateMasteringVoice(handle, a, b, c, d, e, f) handle->CreateMasteringVoice(a, b, c, d, e, f) -#define IXAudio2SourceVoice_Start(handle, a, b) handle->Start(a, b) -#else -/* C hooks */ -#define IXAudio2_Initialize(handle,a,b) (handle)->lpVtbl->Initialize(handle, a, b) -#define IXAudio2_Release(handle) (handle)->lpVtbl->Release(handle) -#define IXAudio2_CreateSourceVoice(handle,ppSourceVoice,pSourceFormat,Flags,MaxFrequencyRatio,pCallback,pSendList,pEffectChain) (handle)->lpVtbl->CreateSourceVoice(handle, ppSourceVoice,pSourceFormat,Flags,MaxFrequencyRatio,pCallback,pSendList,pEffectChain) -#define IXAudio2_CreateMasteringVoice(handle,ppMasteringVoice,InputChannels,InputSampleRate,Flags,DeviceIndex,pEffectChain) (handle)->lpVtbl->CreateMasteringVoice(handle, ppMasteringVoice,InputChannels,InputSampleRate,Flags,DeviceIndex,pEffectChain) -#define IXAudio2_GetDeviceCount(handle, puCount) (handle)->lpVtbl->GetDeviceCount(handle, puCount) -#define IXAudio2_GetDeviceDetails(handle, Index,pDeviceDetails) (handle)->lpVtbl->GetDeviceDetails(handle, Index, pDeviceDetails) -#define IXAudio2SourceVoice_Start(handle, Flags, OperationSet) (handle)->lpVtbl->Start(handle, Flags, OperationSet) -#define IXAudio2SourceVoice_Stop(handle, Flags, OperationSet) (handle)->lpVtbl->Stop(handle, Flags, OperationSet) -#define IXAudio2SourceVoice_SubmitSourceBuffer(handle, pBuffer, pBufferWMA) (handle)->lpVtbl->SubmitSourceBuffer(handle, pBuffer, pBufferWMA) -#define IXAudio2SourceVoice_DestroyVoice(handle) (handle)->lpVtbl->DestroyVoice(handle) -#define IXAudio2MasteringVoice_DestroyVoice(handle) (handle)->lpVtbl->DestroyVoice(handle) -#endif - -#ifdef _XBOX -STDAPI XAudio2Create(__deref_out IXAudio2** ppXAudio2, UINT32 Flags X2DEFAULT(0), - XAUDIO2_PROCESSOR XAudio2Processor X2DEFAULT(XAUDIO2_DEFAULT_PROCESSOR)); -#else -static INLINE HRESULT XAudio2Create(IXAudio2 **ppXAudio2, UINT32 flags, XAUDIO2_PROCESSOR proc) -{ - IXAudio2 *pXAudio2 = NULL; -#ifdef __cplusplus - HRESULT hr = CoCreateInstance(CLSID_XAudio2, NULL, CLSCTX_INPROC_SERVER, IID_IXAudio2, (void**)&pXAudio2); -#else - HRESULT hr = CoCreateInstance(&CLSID_XAudio2, NULL, CLSCTX_INPROC_SERVER, &IID_IXAudio2, (void**)&pXAudio2); -#endif - - if (SUCCEEDED(hr)) - { - hr = IXAudio2_Initialize(pXAudio2, 0, XAUDIO2_DEFAULT_PROCESSOR); - if (SUCCEEDED(hr)) - *ppXAudio2 = pXAudio2; - else - IXAudio2_Release(pXAudio2); - } - return hr; -} -#endif - -/* Undo the #pragma pack(push, 1) directive at the top of this file */ -#pragma pack(pop) - -#endif - diff --git a/audio/drivers/xaudio27.h b/audio/drivers/xaudio27.h new file mode 100644 index 0000000000..788fe16789 --- /dev/null +++ b/audio/drivers/xaudio27.h @@ -0,0 +1,364 @@ +/* RetroArch - A frontend for libretro. + * Copyright (C) 2010-2014 - Hans-Kristian Arntzen + * Copyright (C) 2011-2017 - Daniel De Matteis + * Copyright (C) 2010-2014 - OV2 + * + * RetroArch is free software: you can redistribute it and/or modify it under the terms + * of the GNU General Public License as published by the Free Software Found- + * ation, either version 3 of the License, or (at your option) any later version. + * + * RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + * PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with RetroArch. + * If not, see . + */ + +/* Kinda stripped down. Only contains the bare essentials used in RetroArch. */ + +#ifndef XAUDIO2_STRIPPED_H +#define XAUDIO2_STRIPPED_H + +#include +#include + +/* All structures defined in this file use tight field packing */ +#pragma pack(push, 1) + +#if defined(__cplusplus) && !defined(CINTERFACE) +#define X2DEFAULT(x) = (x) +#else +#define X2DEFAULT(x) +#endif + +#ifdef _XBOX +#include + +#ifndef __cplusplus +#define OPAQUE interface +#endif +#define DEFINE_CLSID(className, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8) \ + DEFINE_GUID(CLSID_##className, 0x##l, 0x##w1, 0x##w2, 0x##b1, 0x##b2, 0x##b3, 0x##b4, 0x##b5, 0x##b6, 0x##b7, 0x##b8) +#define DEFINE_IID(interfaceName, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8) \ + DEFINE_GUID(IID_##interfaceName, 0x##l, 0x##w1, 0x##w2, 0x##b1, 0x##b2, 0x##b3, 0x##b4, 0x##b5, 0x##b6, 0x##b7, 0x##b8) + +DEFINE_CLSID(XAudio2, 3eda9b49, 2085, 498b, 9b, b2, 39, a6, 77, 84, 93, de); +DEFINE_CLSID(XAudio2_Debug, 47199894, 7cc2, 444d, 98, 73, ce, d2, 56, 2c, c6, 0e); +DEFINE_IID(IXAudio2, 8bcf1f58, 9fe7, 4583, 8a, c6, e2, ad, c4, 65, c8, bb); + +#include /* Basic audio data types and constants */ + +#else + +#define WIN32_LEAN_AND_MEAN +#include +#include +#include +#include + +#ifndef __cplusplus +#undef OPAQUE +#define OPAQUE struct +#endif + +#define DEFINE_GUID_X(n, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8) \ + static const GUID n = { l, w1, w2, { b1, b2, b3, b4, b5, b6, b7, b8 } } +#define DEFINE_CLSID_X(className, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8) \ + DEFINE_GUID_X(CLSID_##className, 0x##l, 0x##w1, 0x##w2, 0x##b1, 0x##b2, 0x##b3, 0x##b4, 0x##b5, 0x##b6, 0x##b7, 0x##b8) +#define DEFINE_IID_X(interfaceName, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8) \ + DEFINE_GUID_X(IID_##interfaceName, 0x##l, 0x##w1, 0x##w2, 0x##b1, 0x##b2, 0x##b3, 0x##b4, 0x##b5, 0x##b6, 0x##b7, 0x##b8) + +#ifndef __cplusplus +#ifndef INTERFACE +#define INTERFACE void +#endif +#endif + +DEFINE_CLSID_X(XAudio2, 5a508685, a254, 4fba, 9b, 82, 9a, 24, b0, 03, 06, af); /* 2.7 */ +DEFINE_IID_X(IXAudio2, 8bcf1f58, 9fe7, 4583, 8a, c6, e2, ad, c4, 65, c8, bb); + +#endif + +#ifdef _XBOX +#define XAUDIO2_DEFAULT_FREQ_RATIO 2.0f +#else +#define XAUDIO2_DEFAULT_FREQ_RATIO 4.0f +#endif + +#define XAUDIO2_COMMIT_NOW 0 +#define XAUDIO2_DEFAULT_CHANNELS 0 +#define XAUDIO2_DEFAULT_SAMPLERATE 0 + +#define XAUDIO2_DEBUG_ENGINE 0x0001 +#define XAUDIO2_VOICE_NOSRC 0x0004 + +typedef enum XAUDIO2_DEVICE_ROLE +{ + NotDefaultDevice = 0x0, + DefaultConsoleDevice = 0x1, + DefaultMultimediaDevice = 0x2, + DefaultCommunicationsDevice = 0x4, + DefaultGameDevice = 0x8, + GlobalDefaultDevice = 0xf, + InvalidDeviceRole = ~GlobalDefaultDevice +} XAUDIO2_DEVICE_ROLE; + +#ifdef _XBOX +typedef enum XAUDIO2_XBOX_HWTHREAD_SPECIFIER +{ + XboxThread0 = 0x01, + XboxThread1 = 0x02, + XboxThread2 = 0x04, + XboxThread3 = 0x08, + XboxThread4 = 0x10, + XboxThread5 = 0x20, + XAUDIO2_ANY_PROCESSOR = XboxThread4, + XAUDIO2_DEFAULT_PROCESSOR = XAUDIO2_ANY_PROCESSOR +} XAUDIO2_XBOX_HWTHREAD_SPECIFIER, XAUDIO2_PROCESSOR; +#else +typedef enum XAUDIO2_WINDOWS_PROCESSOR_SPECIFIER +{ +#if defined(__STDC_C89__) + XAUDIO2_ANY_PROCESSOR = 0xffff, +#else + XAUDIO2_ANY_PROCESSOR = 0xffffffff, +#endif + XAUDIO2_DEFAULT_PROCESSOR = XAUDIO2_ANY_PROCESSOR +} XAUDIO2_WINDOWS_PROCESSOR_SPECIFIER, XAUDIO2_PROCESSOR; +#endif + +typedef enum XAUDIO2_FILTER_TYPE { + LowPassFilter, + BandPassFilter, + HighPassFilter +} XAUDIO2_FILTER_TYPE; + +typedef struct XAUDIO2_DEVICE_DETAILS +{ + WCHAR DeviceID[256]; + WCHAR DisplayName[256]; + XAUDIO2_DEVICE_ROLE Role; + WAVEFORMATEXTENSIBLE OutputFormat; +} XAUDIO2_DEVICE_DETAILS; + +/* Forward declarations. */ +#ifdef __cplusplus +struct XAUDIO2_VOICE_DETAILS; +struct XAUDIO2_VOICE_SENDS; +struct XAUDIO2_EFFECT_DESCRIPTOR; +struct XAUDIO2_EFFECT_CHAIN; +struct XAUDIO2_FILTER_PARAMETERS; +struct XAUDIO2_BUFFER_WMA; +struct XAUDIO2_VOICE_STATE; +struct XAUDIO2_PERFORMANCE_DATA; +struct XAUDIO2_DEBUG_CONFIGURATION; +struct IXAudio2EngineCallback; +struct IXAudio2SubmixVoice; +#else +typedef OPAQUE XAUDIO2_VOICE_DETAILS XAUDIO2_VOICE_DETAILS; +typedef OPAQUE XAUDIO2_VOICE_SENDS XAUDIO2_VOICE_SENDS; +typedef OPAQUE XAUDIO2_EFFECT_DESCRIPTOR XAUDIO2_EFFECT_DESCRIPTOR; +typedef OPAQUE XAUDIO2_EFFECT_CHAIN XAUDIO2_EFFECT_CHAIN; +typedef OPAQUE XAUDIO2_FILTER_PARAMETERS XAUDIO2_FILTER_PARAMETERS; +typedef OPAQUE XAUDIO2_BUFFER_WMA XAUDIO2_BUFFER_WMA; +typedef OPAQUE XAUDIO2_VOICE_STATE XAUDIO2_VOICE_STATE; +typedef OPAQUE XAUDIO2_PERFORMANCE_DATA XAUDIO2_PERFORMANCE_DATA; +typedef OPAQUE XAUDIO2_DEBUG_CONFIGURATION XAUDIO2_DEBUG_CONFIGURATION; +typedef OPAQUE IXAudio2EngineCallback IXAudio2EngineCallback; +typedef OPAQUE IXAudio2SubmixVoice IXAudio2SubmixVoice; +#endif + + +typedef struct XAUDIO2_BUFFER +{ + UINT32 Flags; + UINT32 AudioBytes; + const BYTE* pAudioData; + UINT32 PlayBegin; + UINT32 PlayLength; + UINT32 LoopBegin; + UINT32 LoopLength; + UINT32 LoopCount; + void *pContext; +} XAUDIO2_BUFFER; + +#undef INTERFACE +#define INTERFACE IXAudio2VoiceCallback + +DECLARE_INTERFACE(IXAudio2VoiceCallback) +{ + STDMETHOD_(void, OnVoiceProcessingPassStart) (THIS_ UINT32 BytesRequired) PURE; + STDMETHOD_(void, OnVoiceProcessingPassEnd) (THIS) PURE; + STDMETHOD_(void, OnStreamEnd) (THIS) PURE; + STDMETHOD_(void, OnBufferStart) (THIS_ void *pBufferContext) PURE; + STDMETHOD_(void, OnBufferEnd) (THIS_ void *pBufferContext) PURE; + STDMETHOD_(void, OnLoopEnd) (THIS_ void *pBufferContext) PURE; + STDMETHOD_(void, OnVoiceError) (THIS_ void *pBufferContext, HRESULT Error) PURE; +}; + +#undef INTERFACE +#define INTERFACE IXAudio2Voice + +DECLARE_INTERFACE(IXAudio2Voice) +{ +#define Declare_IXAudio2Voice_Methods() \ + STDMETHOD_(void, GetVoiceDetails) (THIS_ XAUDIO2_VOICE_DETAILS* pVoiceDetails) PURE; \ + STDMETHOD(SetOutputVoices) (THIS_ const XAUDIO2_VOICE_SENDS* pSendList) PURE; \ + STDMETHOD(SetEffectChain) (THIS_ const XAUDIO2_EFFECT_CHAIN* pEffectChain) PURE; \ + STDMETHOD(EnableEffect) (THIS_ UINT32 EffectIndex, \ + UINT32 OperationSet X2DEFAULT(XAUDIO2_COMMIT_NOW)) PURE; \ + STDMETHOD(DisableEffect) (THIS_ UINT32 EffectIndex, \ + UINT32 OperationSet X2DEFAULT(XAUDIO2_COMMIT_NOW)) PURE; \ + STDMETHOD_(void, GetEffectState) (THIS_ UINT32 EffectIndex, BOOL* pEnabled) PURE; \ + STDMETHOD(SetEffectParameters) (THIS_ UINT32 EffectIndex, \ + const void *pParameters, \ + UINT32 ParametersByteSize, \ + UINT32 OperationSet X2DEFAULT(XAUDIO2_COMMIT_NOW)) PURE; \ + STDMETHOD(GetEffectParameters) (THIS_ UINT32 EffectIndex, void *pParameters, \ + UINT32 ParametersByteSize) PURE; \ + STDMETHOD(SetFilterParameters) (THIS_ const XAUDIO2_FILTER_PARAMETERS* pParameters, \ + UINT32 OperationSet X2DEFAULT(XAUDIO2_COMMIT_NOW)) PURE; \ + STDMETHOD_(void, GetFilterParameters) (THIS_ XAUDIO2_FILTER_PARAMETERS* pParameters) PURE; \ + STDMETHOD_(void, SetOutputFilterParameters) (THIS_ IXAudio2Voice *voice, const XAUDIO2_FILTER_PARAMETERS* param, \ + UINT32 op X2DEFAULT(XAUDIO2_COMMIT_NOW)) PURE; \ + STDMETHOD_(void, GetOutputFilterParameters) (THIS_ IXAudio2Voice *voice, XAUDIO2_FILTER_PARAMETERS* param) PURE; \ + STDMETHOD(SetVolume) (THIS_ float Volume, \ + UINT32 OperationSet X2DEFAULT(XAUDIO2_COMMIT_NOW)) PURE; \ + STDMETHOD_(void, GetVolume) (THIS_ float* pVolume) PURE; \ + STDMETHOD(SetChannelVolumes) (THIS_ UINT32 Channels, const float* pVolumes, \ + UINT32 OperationSet X2DEFAULT(XAUDIO2_COMMIT_NOW)) PURE; \ + STDMETHOD_(void, GetChannelVolumes) (THIS_ UINT32 Channels, float* pVolumes) PURE; \ + STDMETHOD(SetOutputMatrix) (THIS_ IXAudio2Voice* pDestinationVoice, \ + UINT32 SourceChannels, UINT32 DestinationChannels, \ + const float* pLevelMatrix, \ + UINT32 OperationSet X2DEFAULT(XAUDIO2_COMMIT_NOW)) PURE; \ + STDMETHOD_(void, GetOutputMatrix) (THIS_ IXAudio2Voice* pDestinationVoice, \ + UINT32 SourceChannels, UINT32 DestinationChannels, \ + float* pLevelMatrix) PURE; \ + STDMETHOD_(void, DestroyVoice) (THIS) PURE + + Declare_IXAudio2Voice_Methods(); +}; + +#undef INTERFACE +#define INTERFACE IXAudio2MasteringVoice + +DECLARE_INTERFACE_(IXAudio2MasteringVoice, IXAudio2Voice) +{ + Declare_IXAudio2Voice_Methods(); +}; + +#undef INTERFACE +#define INTERFACE IXAudio2SourceVoice + +DECLARE_INTERFACE_(IXAudio2SourceVoice, IXAudio2Voice) +{ + Declare_IXAudio2Voice_Methods(); + STDMETHOD(Start) (THIS_ UINT32 Flags, UINT32 OperationSet X2DEFAULT(XAUDIO2_COMMIT_NOW)) PURE; + STDMETHOD(Stop) (THIS_ UINT32 Flags, UINT32 OperationSet X2DEFAULT(XAUDIO2_COMMIT_NOW)) PURE; + STDMETHOD(SubmitSourceBuffer) (THIS_ const XAUDIO2_BUFFER* pBuffer, const XAUDIO2_BUFFER_WMA* pBufferWMA X2DEFAULT(NULL)) PURE; + STDMETHOD(FlushSourceBuffers) (THIS) PURE; + STDMETHOD(Discontinuity) (THIS) PURE; + STDMETHOD(ExitLoop) (THIS_ UINT32 OperationSet X2DEFAULT(XAUDIO2_COMMIT_NOW)) PURE; + STDMETHOD_(void, GetState) (THIS_ XAUDIO2_VOICE_STATE* pVoiceState) PURE; + STDMETHOD(SetFrequencyRatio) (THIS_ float Ratio, + UINT32 OperationSet X2DEFAULT(XAUDIO2_COMMIT_NOW)) PURE; + STDMETHOD_(void, GetFrequencyRatio) (THIS_ float* pRatio) PURE; +}; + +#undef INTERFACE +#define INTERFACE IXAudio2 + +DECLARE_INTERFACE_(IXAudio2, IUnknown) +{ + STDMETHOD(QueryInterface) (THIS_ REFIID riid, void** ppvInterface) PURE; + STDMETHOD_(ULONG, AddRef) (THIS) PURE; + STDMETHOD_(ULONG, Release) (THIS) PURE; + STDMETHOD(GetDeviceCount) (THIS_ UINT32* pCount) PURE; + STDMETHOD(GetDeviceDetails) (THIS_ UINT32 Index, XAUDIO2_DEVICE_DETAILS* pDeviceDetails) PURE; + STDMETHOD(Initialize) (THIS_ UINT32 Flags X2DEFAULT(0), + XAUDIO2_PROCESSOR XAudio2Processor X2DEFAULT(XAUDIO2_DEFAULT_PROCESSOR)) PURE; + STDMETHOD(RegisterForCallbacks) (IXAudio2EngineCallback* pCallback) PURE; + STDMETHOD_(void, UnregisterForCallbacks) (IXAudio2EngineCallback* pCallback) PURE; + STDMETHOD(CreateSourceVoice) (THIS_ IXAudio2SourceVoice** ppSourceVoice, + const WAVEFORMATEX* pSourceFormat, + UINT32 Flags X2DEFAULT(0), + float MaxFrequencyRatio X2DEFAULT(XAUDIO2_DEFAULT_FREQ_RATIO), + IXAudio2VoiceCallback* pCallback X2DEFAULT(NULL), + const XAUDIO2_VOICE_SENDS* pSendList X2DEFAULT(NULL), + const XAUDIO2_EFFECT_CHAIN* pEffectChain X2DEFAULT(NULL)) PURE; + STDMETHOD(CreateSubmixVoice) (THIS_ IXAudio2SubmixVoice** ppSubmixVoice, + UINT32 InputChannels, UINT32 InputSampleRate, + UINT32 Flags X2DEFAULT(0), UINT32 ProcessingStage X2DEFAULT(0), + const XAUDIO2_VOICE_SENDS* pSendList X2DEFAULT(NULL), + const XAUDIO2_EFFECT_CHAIN* pEffectChain X2DEFAULT(NULL)) PURE; + STDMETHOD(CreateMasteringVoice) (THIS_ IXAudio2MasteringVoice** ppMasteringVoice, + UINT32 InputChannels X2DEFAULT(XAUDIO2_DEFAULT_CHANNELS), + UINT32 InputSampleRate X2DEFAULT(XAUDIO2_DEFAULT_SAMPLERATE), + UINT32 Flags X2DEFAULT(0), UINT32 DeviceIndex X2DEFAULT(0), + const XAUDIO2_EFFECT_CHAIN* pEffectChain X2DEFAULT(NULL)) PURE; + STDMETHOD(StartEngine) (THIS) PURE; + STDMETHOD_(void, StopEngine) (THIS) PURE; + STDMETHOD(CommitChanges) (THIS_ UINT32 OperationSet) PURE; + STDMETHOD_(void, GetPerformanceData) (THIS_ XAUDIO2_PERFORMANCE_DATA* pPerfData) PURE; + STDMETHOD_(void, SetDebugConfiguration) (THIS_ const XAUDIO2_DEBUG_CONFIGURATION* pDebugConfiguration, + void *pReserved X2DEFAULT(NULL)) PURE; +}; + +#if defined(__cplusplus) && !defined(CINTERFACE) +/* C++ hooks */ +#define IXAudio2_Initialize(handle,a,b) handle->Initialize(a, b) +#define IXAudio2SourceVoice_SubmitSourceBuffer(handle, a, b) handle->SubmitSourceBuffer(a, b) +#define IXAudio2SourceVoice_Stop(handle, a, b) handle->Stop(a, b) +#define IXAudio2SourceVoice_DestroyVoice(handle) handle->DestroyVoice() +#define IXAudio2MasteringVoice_DestroyVoice(handle) handle->DestroyVoice() +#define IXAudio2_Release(handle) handle->Release() +#define IXAudio2_CreateSourceVoice(handle, a, b, c, d, e, f, g) handle->CreateSourceVoice(a, b, c, d, e, f, g) +#define IXAudio2_CreateMasteringVoice(handle, a, b, c, d, e, f) handle->CreateMasteringVoice(a, b, c, d, e, f) +#define IXAudio2SourceVoice_Start(handle, a, b) handle->Start(a, b) +#else +/* C hooks */ +#define IXAudio2_Initialize(handle,a,b) (handle)->lpVtbl->Initialize(handle, a, b) +#define IXAudio2_Release(handle) (handle)->lpVtbl->Release(handle) +#define IXAudio2_CreateSourceVoice(handle,ppSourceVoice,pSourceFormat,Flags,MaxFrequencyRatio,pCallback,pSendList,pEffectChain) (handle)->lpVtbl->CreateSourceVoice(handle, ppSourceVoice,pSourceFormat,Flags,MaxFrequencyRatio,pCallback,pSendList,pEffectChain) +#define IXAudio2_CreateMasteringVoice(handle,ppMasteringVoice,InputChannels,InputSampleRate,Flags,DeviceIndex,pEffectChain) (handle)->lpVtbl->CreateMasteringVoice(handle, ppMasteringVoice,InputChannels,InputSampleRate,Flags,DeviceIndex,pEffectChain) +#define IXAudio2_GetDeviceCount(handle, puCount) (handle)->lpVtbl->GetDeviceCount(handle, puCount) +#define IXAudio2_GetDeviceDetails(handle, Index,pDeviceDetails) (handle)->lpVtbl->GetDeviceDetails(handle, Index, pDeviceDetails) +#define IXAudio2SourceVoice_Start(handle, Flags, OperationSet) (handle)->lpVtbl->Start(handle, Flags, OperationSet) +#define IXAudio2SourceVoice_Stop(handle, Flags, OperationSet) (handle)->lpVtbl->Stop(handle, Flags, OperationSet) +#define IXAudio2SourceVoice_SubmitSourceBuffer(handle, pBuffer, pBufferWMA) (handle)->lpVtbl->SubmitSourceBuffer(handle, pBuffer, pBufferWMA) +#define IXAudio2SourceVoice_DestroyVoice(handle) (handle)->lpVtbl->DestroyVoice(handle) +#define IXAudio2MasteringVoice_DestroyVoice(handle) (handle)->lpVtbl->DestroyVoice(handle) +#endif + +#ifdef _XBOX +STDAPI XAudio2Create(__deref_out IXAudio2** ppXAudio2, UINT32 Flags X2DEFAULT(0), + XAUDIO2_PROCESSOR XAudio2Processor X2DEFAULT(XAUDIO2_DEFAULT_PROCESSOR)); +#else +static INLINE HRESULT XAudio2Create(IXAudio2 **ppXAudio2, UINT32 flags, XAUDIO2_PROCESSOR proc) +{ + IXAudio2 *pXAudio2 = NULL; +#ifdef __cplusplus + HRESULT hr = CoCreateInstance(CLSID_XAudio2, NULL, CLSCTX_INPROC_SERVER, IID_IXAudio2, (void**)&pXAudio2); +#else + HRESULT hr = CoCreateInstance(&CLSID_XAudio2, NULL, CLSCTX_INPROC_SERVER, &IID_IXAudio2, (void**)&pXAudio2); +#endif + + if (SUCCEEDED(hr)) + { + hr = IXAudio2_Initialize(pXAudio2, 0, XAUDIO2_DEFAULT_PROCESSOR); + if (SUCCEEDED(hr)) + *ppXAudio2 = pXAudio2; + else + IXAudio2_Release(pXAudio2); + } + return hr; +} +#endif + +/* Undo the #pragma pack(push, 1) directive at the top of this file */ +#pragma pack(pop) + +#endif + diff --git a/audio/drivers/xaudio29.h b/audio/drivers/xaudio29.h new file mode 100644 index 0000000000..9743738db0 --- /dev/null +++ b/audio/drivers/xaudio29.h @@ -0,0 +1,1313 @@ +/* RetroArch - A frontend for libretro. + * Copyright (C) 2018 - Krzysztof Haładyn + * + * RetroArch is free software: you can redistribute it and/or modify it under the terms + * of the GNU General Public License as published by the Free Software Found- + * ation, either version 3 of the License, or (at your option) any later version. + * + * RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + * PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with RetroArch. + * If not, see . + */ + +/************************************************************************** + * + * Copyright (c) Microsoft Corporation. All rights reserved. + * + * File: xaudio2.h + * Content: Declarations for the XAudio2 game audio API. + * + **************************************************************************/ + +/* Modified slightly to build without requiring the WinRT compiler since that is only available in C++ sources */ + +#ifdef _MSC_VER +#pragma once +#endif + +#ifndef __XAUDIO2_INCLUDED__ +#define __XAUDIO2_INCLUDED__ + +#include + +#if(_WIN32_WINNT < _WIN32_WINNT_WIN8) +#error "This version of XAudio2 is available only in Windows 8 or later. Use the XAudio2 headers and libraries from the DirectX SDK with applications that target Windows 7 and earlier versions." +#endif // (_WIN32_WINNT < _WIN32_WINNT_WIN8) + +#include + +#pragma region Application Family +#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP | WINAPI_PARTITION_TV_APP | WINAPI_PARTITION_TV_TITLE) + +// Current name of the DLL shipped in the same SDK as this header. +// The name reflects the current version +#if(_WIN32_WINNT >= _WIN32_WINNT_WIN10) + #define XAUDIO2_DLL_A "xaudio2_9.dll" + #define XAUDIO2_DLL_W L"xaudio2_9.dll" + #define XAUDIO2D_DLL_A "xaudio2_9d.dll" + #define XAUDIO2D_DLL_W L"xaudio2_9d.dll" +#else + #define XAUDIO2_DLL_A "xaudio2_8.dll" + #define XAUDIO2_DLL_W L"xaudio2_8.dll" + #define XAUDIO2D_DLL_A "xaudio2_8.dll" + #define XAUDIO2D_DLL_W L"xaudio2_8.dll" +#endif + +#ifdef UNICODE + #define XAUDIO2_DLL XAUDIO2_DLL_W + #define XAUDIO2D_DLL XAUDIO2D_DLL_W +#else + #define XAUDIO2_DLL XAUDIO2_DLL_A + #define XAUDIO2D_DLL XAUDIO2D_DLL_A +#endif + + +/************************************************************************** + * + * XAudio2 COM object class and interface IDs. + * + **************************************************************************/ + +#include + +#if defined(__cplusplus__) && defined(__WINRT__) + +#if(_WIN32_WINNT >= _WIN32_WINNT_WIN10) + // XAudio 2.9 + interface __declspec(uuid("2B02E3CF-2E0B-4ec3-BE45-1B2A3FE7210D")) IXAudio2; +#else + // XAudio 2.8 + interface __declspec(uuid("60d8dac8-5aa1-4e8e-b597-2f5e2883d484")) IXAudio2; +#endif + +#else + +/* Modified for C support */ +#define DEFINE_GUID_X(n, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8) \ + static const GUID n = { l, w1, w2, { b1, b2, b3, b4, b5, b6, b7, b8 } } +#define DEFINE_CLSID_X(className, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8) \ + DEFINE_GUID_X(CLSID_##className, 0x##l, 0x##w1, 0x##w2, 0x##b1, 0x##b2, 0x##b3, 0x##b4, 0x##b5, 0x##b6, 0x##b7, 0x##b8) +#define DEFINE_IID_X(interfaceName, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8) \ + DEFINE_GUID_X(IID_##interfaceName, 0x##l, 0x##w1, 0x##w2, 0x##b1, 0x##b2, 0x##b3, 0x##b4, 0x##b5, 0x##b6, 0x##b7, 0x##b8) + +#if(_WIN32_WINNT >= _WIN32_WINNT_WIN10) + DEFINE_IID_X(IXAudio2, 2B02E3CF, 2E0B, 4ec3, BE, 45, 1B, 2A, 3F, E7, 21, 0D); +#else + DEFINE_IID_X(IXAudio2, 60d8dac8, 5aa1, 4e8e, b5, 97, 2f, 5e, 28, 83, d4, 84); +#endif + +#endif + + +// Ignore the rest of this header if only the GUID definitions were requested +#ifndef GUID_DEFS_ONLY + +#include // Windows COM declarations +#include // Markers for documenting API semantics +#include // Basic data types and constants for audio work +#include // For AUDIO_STREAM_CATEGORY + +// All structures defined in this file use tight field packing +#pragma pack(push, 1) + + +/************************************************************************** + * + * XAudio2 constants, flags and error codes. + * + **************************************************************************/ + +// Numeric boundary values +#define XAUDIO2_MAX_BUFFER_BYTES 0x80000000 // Maximum bytes allowed in a source buffer +#define XAUDIO2_MAX_QUEUED_BUFFERS 64 // Maximum buffers allowed in a voice queue +#define XAUDIO2_MAX_BUFFERS_SYSTEM 2 // Maximum buffers allowed for system threads (Xbox 360 only) +#define XAUDIO2_MAX_AUDIO_CHANNELS 64 // Maximum channels in an audio stream +#define XAUDIO2_MIN_SAMPLE_RATE 1000 // Minimum audio sample rate supported +#define XAUDIO2_MAX_SAMPLE_RATE 200000 // Maximum audio sample rate supported +#define XAUDIO2_MAX_VOLUME_LEVEL 16777216.0f // Maximum acceptable volume level (2^24) +#define XAUDIO2_MIN_FREQ_RATIO (1/1024.0f) // Minimum SetFrequencyRatio argument +#define XAUDIO2_MAX_FREQ_RATIO 1024.0f // Maximum MaxFrequencyRatio argument +#define XAUDIO2_DEFAULT_FREQ_RATIO 2.0f // Default MaxFrequencyRatio argument +#define XAUDIO2_MAX_FILTER_ONEOVERQ 1.5f // Maximum XAUDIO2_FILTER_PARAMETERS.OneOverQ +#define XAUDIO2_MAX_FILTER_FREQUENCY 1.0f // Maximum XAUDIO2_FILTER_PARAMETERS.Frequency +#define XAUDIO2_MAX_LOOP_COUNT 254 // Maximum non-infinite XAUDIO2_BUFFER.LoopCount +#define XAUDIO2_MAX_INSTANCES 8 // Maximum simultaneous XAudio2 objects on Xbox 360 + +// For XMA voices on Xbox 360 there is an additional restriction on the MaxFrequencyRatio +// argument and the voice's sample rate: the product of these numbers cannot exceed 600000 +// for one-channel voices or 300000 for voices with more than one channel. +#define XAUDIO2_MAX_RATIO_TIMES_RATE_XMA_MONO 600000 +#define XAUDIO2_MAX_RATIO_TIMES_RATE_XMA_MULTICHANNEL 300000 + +// Numeric values with special meanings +#define XAUDIO2_COMMIT_NOW 0 // Used as an OperationSet argument +#define XAUDIO2_COMMIT_ALL 0 // Used in IXAudio2::CommitChanges +#define XAUDIO2_INVALID_OPSET (UINT32)(-1) // Not allowed for OperationSet arguments +#define XAUDIO2_NO_LOOP_REGION 0 // Used in XAUDIO2_BUFFER.LoopCount +#define XAUDIO2_LOOP_INFINITE 255 // Used in XAUDIO2_BUFFER.LoopCount +#define XAUDIO2_DEFAULT_CHANNELS 0 // Used in CreateMasteringVoice +#define XAUDIO2_DEFAULT_SAMPLERATE 0 // Used in CreateMasteringVoice + +// Flags +#define XAUDIO2_DEBUG_ENGINE 0x0001 // Used in XAudio2Create +#define XAUDIO2_VOICE_NOPITCH 0x0002 // Used in IXAudio2::CreateSourceVoice +#define XAUDIO2_VOICE_NOSRC 0x0004 // Used in IXAudio2::CreateSourceVoice +#define XAUDIO2_VOICE_USEFILTER 0x0008 // Used in IXAudio2::CreateSource/SubmixVoice +#define XAUDIO2_PLAY_TAILS 0x0020 // Used in IXAudio2SourceVoice::Stop +#define XAUDIO2_END_OF_STREAM 0x0040 // Used in XAUDIO2_BUFFER.Flags +#define XAUDIO2_SEND_USEFILTER 0x0080 // Used in XAUDIO2_SEND_DESCRIPTOR.Flags +#define XAUDIO2_VOICE_NOSAMPLESPLAYED 0x0100 // Used in IXAudio2SourceVoice::GetState +#define XAUDIO2_STOP_ENGINE_WHEN_IDLE 0x2000 // Used in XAudio2Create to force the engine to Stop when no source voices are Started, and Start when a voice is Started +#define XAUDIO2_1024_QUANTUM 0x8000 // Used in XAudio2Create to specify nondefault processing quantum of 21.33 ms (1024 samples at 48KHz) +#define XAUDIO2_NO_VIRTUAL_AUDIO_CLIENT 0x10000 // Used in CreateMasteringVoice to create a virtual audio client + +// Default parameters for the built-in filter +#define XAUDIO2_DEFAULT_FILTER_TYPE LowPassFilter +#define XAUDIO2_DEFAULT_FILTER_FREQUENCY XAUDIO2_MAX_FILTER_FREQUENCY +#define XAUDIO2_DEFAULT_FILTER_ONEOVERQ 1.0f + +// Internal XAudio2 constants +// The audio frame quantum can be calculated by reducing the fraction: +// SamplesPerAudioFrame / SamplesPerSecond +#define XAUDIO2_QUANTUM_NUMERATOR 1 // On Windows, XAudio2 processes audio +#define XAUDIO2_QUANTUM_DENOMINATOR 100 // in 10ms chunks (= 1/100 seconds) +#define XAUDIO2_QUANTUM_MS (1000.0f * XAUDIO2_QUANTUM_NUMERATOR / XAUDIO2_QUANTUM_DENOMINATOR) + +// XAudio2 error codes +#define FACILITY_XAUDIO2 0x896 +#define XAUDIO2_E_INVALID_CALL 0x88960001 // An API call or one of its arguments was illegal +#define XAUDIO2_E_XMA_DECODER_ERROR 0x88960002 // The XMA hardware suffered an unrecoverable error +#define XAUDIO2_E_XAPO_CREATION_FAILED 0x88960003 // XAudio2 failed to initialize an XAPO effect +#define XAUDIO2_E_DEVICE_INVALIDATED 0x88960004 // An audio device became unusable (unplugged, etc) + +/************************************************************************** + * + * Forward declarations for the XAudio2 interfaces. + * + **************************************************************************/ + +#ifdef __cplusplus + #define FWD_DECLARE(x) interface x +#else + #define FWD_DECLARE(x) typedef interface x x +#endif + +FWD_DECLARE(IXAudio2); +FWD_DECLARE(IXAudio2Voice); +FWD_DECLARE(IXAudio2SourceVoice); +FWD_DECLARE(IXAudio2SubmixVoice); +FWD_DECLARE(IXAudio2MasteringVoice); +FWD_DECLARE(IXAudio2EngineCallback); +FWD_DECLARE(IXAudio2VoiceCallback); + + +/************************************************************************** + * + * XAudio2 structures and enumerations. + * + **************************************************************************/ + +// Used in XAudio2Create, specifies which CPU(s) to use. +typedef UINT32 XAUDIO2_PROCESSOR; +#define Processor1 0x00000001 +#define Processor2 0x00000002 +#define Processor3 0x00000004 +#define Processor4 0x00000008 +#define Processor5 0x00000010 +#define Processor6 0x00000020 +#define Processor7 0x00000040 +#define Processor8 0x00000080 +#define Processor9 0x00000100 +#define Processor10 0x00000200 +#define Processor11 0x00000400 +#define Processor12 0x00000800 +#define Processor13 0x00001000 +#define Processor14 0x00002000 +#define Processor15 0x00004000 +#define Processor16 0x00008000 +#define Processor17 0x00010000 +#define Processor18 0x00020000 +#define Processor19 0x00040000 +#define Processor20 0x00080000 +#define Processor21 0x00100000 +#define Processor22 0x00200000 +#define Processor23 0x00400000 +#define Processor24 0x00800000 +#define Processor25 0x01000000 +#define Processor26 0x02000000 +#define Processor27 0x04000000 +#define Processor28 0x08000000 +#define Processor29 0x10000000 +#define Processor30 0x20000000 +#define Processor31 0x40000000 +#define Processor32 0x80000000 +#define XAUDIO2_ANY_PROCESSOR 0xffffffff +#define XAUDIO2_DEFAULT_PROCESSOR Processor1 + +// Returned by IXAudio2Voice::GetVoiceDetails +typedef struct XAUDIO2_VOICE_DETAILS +{ + UINT32 CreationFlags; // Flags the voice was created with. + UINT32 ActiveFlags; // Flags currently active. + UINT32 InputChannels; // Channels in the voice's input audio. + UINT32 InputSampleRate; // Sample rate of the voice's input audio. +} XAUDIO2_VOICE_DETAILS; + +// Used in XAUDIO2_VOICE_SENDS below +typedef struct XAUDIO2_SEND_DESCRIPTOR +{ + UINT32 Flags; // Either 0 or XAUDIO2_SEND_USEFILTER. + IXAudio2Voice* pOutputVoice; // This send's destination voice. +} XAUDIO2_SEND_DESCRIPTOR; + +// Used in the voice creation functions and in IXAudio2Voice::SetOutputVoices +typedef struct XAUDIO2_VOICE_SENDS +{ + UINT32 SendCount; // Number of sends from this voice. + XAUDIO2_SEND_DESCRIPTOR* pSends; // Array of SendCount send descriptors. +} XAUDIO2_VOICE_SENDS; + +// Used in XAUDIO2_EFFECT_CHAIN below +typedef struct XAUDIO2_EFFECT_DESCRIPTOR +{ + IUnknown* pEffect; // Pointer to the effect object's IUnknown interface. + BOOL InitialState; // TRUE if the effect should begin in the enabled state. + UINT32 OutputChannels; // How many output channels the effect should produce. +} XAUDIO2_EFFECT_DESCRIPTOR; + +// Used in the voice creation functions and in IXAudio2Voice::SetEffectChain +typedef struct XAUDIO2_EFFECT_CHAIN +{ + UINT32 EffectCount; // Number of effects in this voice's effect chain. + XAUDIO2_EFFECT_DESCRIPTOR* pEffectDescriptors; // Array of effect descriptors. +} XAUDIO2_EFFECT_CHAIN; + +// Used in XAUDIO2_FILTER_PARAMETERS below +typedef enum XAUDIO2_FILTER_TYPE +{ + LowPassFilter, // Attenuates frequencies above the cutoff frequency (state-variable filter). + BandPassFilter, // Attenuates frequencies outside a given range (state-variable filter). + HighPassFilter, // Attenuates frequencies below the cutoff frequency (state-variable filter). + NotchFilter, // Attenuates frequencies inside a given range (state-variable filter). + LowPassOnePoleFilter, // Attenuates frequencies above the cutoff frequency (one-pole filter, XAUDIO2_FILTER_PARAMETERS.OneOverQ has no effect) + HighPassOnePoleFilter // Attenuates frequencies below the cutoff frequency (one-pole filter, XAUDIO2_FILTER_PARAMETERS.OneOverQ has no effect) +} XAUDIO2_FILTER_TYPE; + +// Used in IXAudio2Voice::Set/GetFilterParameters and Set/GetOutputFilterParameters +typedef struct XAUDIO2_FILTER_PARAMETERS +{ + XAUDIO2_FILTER_TYPE Type; // Filter type. + float Frequency; // Filter coefficient. + // must be >= 0 and <= XAUDIO2_MAX_FILTER_FREQUENCY + // See XAudio2CutoffFrequencyToRadians() for state-variable filter types and + // XAudio2CutoffFrequencyToOnePoleCoefficient() for one-pole filter types. + float OneOverQ; // Reciprocal of the filter's quality factor Q; + // must be > 0 and <= XAUDIO2_MAX_FILTER_ONEOVERQ. + // Has no effect for one-pole filters. +} XAUDIO2_FILTER_PARAMETERS; + +// Used in IXAudio2SourceVoice::SubmitSourceBuffer +typedef struct XAUDIO2_BUFFER +{ + UINT32 Flags; // Either 0 or XAUDIO2_END_OF_STREAM. + UINT32 AudioBytes; // Size of the audio data buffer in bytes. + const BYTE* pAudioData; // Pointer to the audio data buffer. + UINT32 PlayBegin; // First sample in this buffer to be played. + UINT32 PlayLength; // Length of the region to be played in samples, + // or 0 to play the whole buffer. + UINT32 LoopBegin; // First sample of the region to be looped. + UINT32 LoopLength; // Length of the desired loop region in samples, + // or 0 to loop the entire buffer. + UINT32 LoopCount; // Number of times to repeat the loop region, + // or XAUDIO2_LOOP_INFINITE to loop forever. + void* pContext; // Context value to be passed back in callbacks. +} XAUDIO2_BUFFER; + +// Used in IXAudio2SourceVoice::SubmitSourceBuffer when submitting XWMA data. +// NOTE: If an XWMA sound is submitted in more than one buffer, each buffer's +// pDecodedPacketCumulativeBytes[PacketCount-1] value must be subtracted from +// all the entries in the next buffer's pDecodedPacketCumulativeBytes array. +// And whether a sound is submitted in more than one buffer or not, the final +// buffer of the sound should use the XAUDIO2_END_OF_STREAM flag, or else the +// client must call IXAudio2SourceVoice::Discontinuity after submitting it. +typedef struct XAUDIO2_BUFFER_WMA +{ + const UINT32* pDecodedPacketCumulativeBytes; // Decoded packet's cumulative size array. + // Each element is the number of bytes accumulated + // when the corresponding XWMA packet is decoded in + // order. The array must have PacketCount elements. + UINT32 PacketCount; // Number of XWMA packets submitted. Must be >= 1 and + // divide evenly into XAUDIO2_BUFFER.AudioBytes. +} XAUDIO2_BUFFER_WMA; + +// Returned by IXAudio2SourceVoice::GetState +typedef struct XAUDIO2_VOICE_STATE +{ + void* pCurrentBufferContext; // The pContext value provided in the XAUDIO2_BUFFER + // that is currently being processed, or NULL if + // there are no buffers in the queue. + UINT32 BuffersQueued; // Number of buffers currently queued on the voice + // (including the one that is being processed). + UINT64 SamplesPlayed; // Total number of samples produced by the voice since + // it began processing the current audio stream. + // If XAUDIO2_VOICE_NOSAMPLESPLAYED is specified + // in the call to IXAudio2SourceVoice::GetState, + // this member will not be calculated, saving CPU. +} XAUDIO2_VOICE_STATE; + +// Returned by IXAudio2::GetPerformanceData +typedef struct XAUDIO2_PERFORMANCE_DATA +{ + // CPU usage information + UINT64 AudioCyclesSinceLastQuery; // CPU cycles spent on audio processing since the + // last call to StartEngine or GetPerformanceData. + UINT64 TotalCyclesSinceLastQuery; // Total CPU cycles elapsed since the last call + // (only counts the CPU XAudio2 is running on). + UINT32 MinimumCyclesPerQuantum; // Fewest CPU cycles spent processing any one + // audio quantum since the last call. + UINT32 MaximumCyclesPerQuantum; // Most CPU cycles spent processing any one + // audio quantum since the last call. + + // Memory usage information + UINT32 MemoryUsageInBytes; // Total heap space currently in use. + + // Audio latency and glitching information + UINT32 CurrentLatencyInSamples; // Minimum delay from when a sample is read from a + // source buffer to when it reaches the speakers. + UINT32 GlitchesSinceEngineStarted; // Audio dropouts since the engine was started. + + // Data about XAudio2's current workload + UINT32 ActiveSourceVoiceCount; // Source voices currently playing. + UINT32 TotalSourceVoiceCount; // Source voices currently existing. + UINT32 ActiveSubmixVoiceCount; // Submix voices currently playing/existing. + + UINT32 ActiveResamplerCount; // Resample xAPOs currently active. + UINT32 ActiveMatrixMixCount; // MatrixMix xAPOs currently active. + + // Usage of the hardware XMA decoder (Xbox 360 only) + UINT32 ActiveXmaSourceVoices; // Number of source voices decoding XMA data. + UINT32 ActiveXmaStreams; // A voice can use more than one XMA stream. +} XAUDIO2_PERFORMANCE_DATA; + +// Used in IXAudio2::SetDebugConfiguration +typedef struct XAUDIO2_DEBUG_CONFIGURATION +{ + UINT32 TraceMask; // Bitmap of enabled debug message types. + UINT32 BreakMask; // Message types that will break into the debugger. + BOOL LogThreadID; // Whether to log the thread ID with each message. + BOOL LogFileline; // Whether to log the source file and line number. + BOOL LogFunctionName; // Whether to log the function name. + BOOL LogTiming; // Whether to log message timestamps. +} XAUDIO2_DEBUG_CONFIGURATION; + +// Values for the TraceMask and BreakMask bitmaps. Only ERRORS and WARNINGS +// are valid in BreakMask. WARNINGS implies ERRORS, DETAIL implies INFO, and +// FUNC_CALLS implies API_CALLS. By default, TraceMask is ERRORS and WARNINGS +// and all the other settings are zero. +#define XAUDIO2_LOG_ERRORS 0x0001 // For handled errors with serious effects. +#define XAUDIO2_LOG_WARNINGS 0x0002 // For handled errors that may be recoverable. +#define XAUDIO2_LOG_INFO 0x0004 // Informational chit-chat (e.g. state changes). +#define XAUDIO2_LOG_DETAIL 0x0008 // More detailed chit-chat. +#define XAUDIO2_LOG_API_CALLS 0x0010 // Public API function entries and exits. +#define XAUDIO2_LOG_FUNC_CALLS 0x0020 // Internal function entries and exits. +#define XAUDIO2_LOG_TIMING 0x0040 // Delays detected and other timing data. +#define XAUDIO2_LOG_LOCKS 0x0080 // Usage of critical sections and mutexes. +#define XAUDIO2_LOG_MEMORY 0x0100 // Memory heap usage information. +#define XAUDIO2_LOG_STREAMING 0x1000 // Audio streaming information. + + +/************************************************************************** + * + * IXAudio2: Top-level XAudio2 COM interface. + * + **************************************************************************/ + +// Use default arguments if compiling as C++ +#ifdef __cplusplus + #define X2DEFAULT(x) =x +#else + #define X2DEFAULT(x) +#endif + +#undef INTERFACE +#define INTERFACE IXAudio2 +DECLARE_INTERFACE_(IXAudio2, IUnknown) +{ + // NAME: IXAudio2::QueryInterface + // DESCRIPTION: Queries for a given COM interface on the XAudio2 object. + // Only IID_IUnknown and IID_IXAudio2 are supported. + // + // ARGUMENTS: + // riid - IID of the interface to be obtained. + // ppvInterface - Returns a pointer to the requested interface. + // + STDMETHOD(QueryInterface) (THIS_ REFIID riid, _Outptr_ void** ppvInterface) PURE; + + // NAME: IXAudio2::AddRef + // DESCRIPTION: Adds a reference to the XAudio2 object. + // + STDMETHOD_(ULONG, AddRef) (THIS) PURE; + + // NAME: IXAudio2::Release + // DESCRIPTION: Releases a reference to the XAudio2 object. + // + STDMETHOD_(ULONG, Release) (THIS) PURE; + + // NAME: IXAudio2::RegisterForCallbacks + // DESCRIPTION: Adds a new client to receive XAudio2's engine callbacks. + // + // ARGUMENTS: + // pCallback - Callback interface to be called during each processing pass. + // + STDMETHOD(RegisterForCallbacks) (_In_ IXAudio2EngineCallback* pCallback) PURE; + + // NAME: IXAudio2::UnregisterForCallbacks + // DESCRIPTION: Removes an existing receiver of XAudio2 engine callbacks. + // + // ARGUMENTS: + // pCallback - Previously registered callback interface to be removed. + // + STDMETHOD_(void, UnregisterForCallbacks) (_In_ IXAudio2EngineCallback* pCallback) PURE; + + // NAME: IXAudio2::CreateSourceVoice + // DESCRIPTION: Creates and configures a source voice. + // + // ARGUMENTS: + // ppSourceVoice - Returns the new object's IXAudio2SourceVoice interface. + // pSourceFormat - Format of the audio that will be fed to the voice. + // Flags - XAUDIO2_VOICE flags specifying the source voice's behavior. + // MaxFrequencyRatio - Maximum SetFrequencyRatio argument to be allowed. + // pCallback - Optional pointer to a client-provided callback interface. + // pSendList - Optional list of voices this voice should send audio to. + // pEffectChain - Optional list of effects to apply to the audio data. + // + STDMETHOD(CreateSourceVoice) (THIS_ _Outptr_ IXAudio2SourceVoice** ppSourceVoice, + _In_ const WAVEFORMATEX* pSourceFormat, + UINT32 Flags X2DEFAULT(0), + float MaxFrequencyRatio X2DEFAULT(XAUDIO2_DEFAULT_FREQ_RATIO), + _In_opt_ IXAudio2VoiceCallback* pCallback X2DEFAULT(NULL), + _In_opt_ const XAUDIO2_VOICE_SENDS* pSendList X2DEFAULT(NULL), + _In_opt_ const XAUDIO2_EFFECT_CHAIN* pEffectChain X2DEFAULT(NULL)) PURE; + + // NAME: IXAudio2::CreateSubmixVoice + // DESCRIPTION: Creates and configures a submix voice. + // + // ARGUMENTS: + // ppSubmixVoice - Returns the new object's IXAudio2SubmixVoice interface. + // InputChannels - Number of channels in this voice's input audio data. + // InputSampleRate - Sample rate of this voice's input audio data. + // Flags - XAUDIO2_VOICE flags specifying the submix voice's behavior. + // ProcessingStage - Arbitrary number that determines the processing order. + // pSendList - Optional list of voices this voice should send audio to. + // pEffectChain - Optional list of effects to apply to the audio data. + // + STDMETHOD(CreateSubmixVoice) (THIS_ _Outptr_ IXAudio2SubmixVoice** ppSubmixVoice, + UINT32 InputChannels, UINT32 InputSampleRate, + UINT32 Flags X2DEFAULT(0), UINT32 ProcessingStage X2DEFAULT(0), + _In_opt_ const XAUDIO2_VOICE_SENDS* pSendList X2DEFAULT(NULL), + _In_opt_ const XAUDIO2_EFFECT_CHAIN* pEffectChain X2DEFAULT(NULL)) PURE; + + + // NAME: IXAudio2::CreateMasteringVoice + // DESCRIPTION: Creates and configures a mastering voice. + // + // ARGUMENTS: + // ppMasteringVoice - Returns the new object's IXAudio2MasteringVoice interface. + // InputChannels - Number of channels in this voice's input audio data. + // InputSampleRate - Sample rate of this voice's input audio data. + // Flags - XAUDIO2_VOICE flags specifying the mastering voice's behavior. + // szDeviceId - Identifier of the device to receive the output audio. + // pEffectChain - Optional list of effects to apply to the audio data. + // StreamCategory - The audio stream category to use for this mastering voice + // + STDMETHOD(CreateMasteringVoice) (THIS_ _Outptr_ IXAudio2MasteringVoice** ppMasteringVoice, + UINT32 InputChannels X2DEFAULT(XAUDIO2_DEFAULT_CHANNELS), + UINT32 InputSampleRate X2DEFAULT(XAUDIO2_DEFAULT_SAMPLERATE), + UINT32 Flags X2DEFAULT(0), _In_opt_z_ LPCWSTR szDeviceId X2DEFAULT(NULL), + _In_opt_ const XAUDIO2_EFFECT_CHAIN* pEffectChain X2DEFAULT(NULL), + _In_ AUDIO_STREAM_CATEGORY StreamCategory X2DEFAULT(AudioCategory_GameEffects)) PURE; + + // NAME: IXAudio2::StartEngine + // DESCRIPTION: Creates and starts the audio processing thread. + // + STDMETHOD(StartEngine) (THIS) PURE; + + // NAME: IXAudio2::StopEngine + // DESCRIPTION: Stops and destroys the audio processing thread. + // + STDMETHOD_(void, StopEngine) (THIS) PURE; + + // NAME: IXAudio2::CommitChanges + // DESCRIPTION: Atomically applies a set of operations previously tagged + // with a given identifier. + // + // ARGUMENTS: + // OperationSet - Identifier of the set of operations to be applied. + // + STDMETHOD(CommitChanges) (THIS_ UINT32 OperationSet) PURE; + + // NAME: IXAudio2::GetPerformanceData + // DESCRIPTION: Returns current resource usage details: memory, CPU, etc. + // + // ARGUMENTS: + // pPerfData - Returns the performance data structure. + // + STDMETHOD_(void, GetPerformanceData) (THIS_ _Out_ XAUDIO2_PERFORMANCE_DATA* pPerfData) PURE; + + // NAME: IXAudio2::SetDebugConfiguration + // DESCRIPTION: Configures XAudio2's debug output (in debug builds only). + // + // ARGUMENTS: + // pDebugConfiguration - Structure describing the debug output behavior. + // pReserved - Optional parameter; must be NULL. + // + STDMETHOD_(void, SetDebugConfiguration) (THIS_ _In_opt_ const XAUDIO2_DEBUG_CONFIGURATION* pDebugConfiguration, + _Reserved_ void* pReserved X2DEFAULT(NULL)) PURE; +}; + + +/************************************************************************** + * + * IXAudio2Voice: Base voice management interface. + * + **************************************************************************/ + +#undef INTERFACE +#define INTERFACE IXAudio2Voice +DECLARE_INTERFACE(IXAudio2Voice) +{ + // These methods are declared in a macro so that the same declarations + // can be used in the derived voice types (IXAudio2SourceVoice, etc). + + #define Declare_IXAudio2Voice_Methods() \ + \ + /* NAME: IXAudio2Voice::GetVoiceDetails + // DESCRIPTION: Returns the basic characteristics of this voice. + // + // ARGUMENTS: + // pVoiceDetails - Returns the voice's details. + */\ + STDMETHOD_(void, GetVoiceDetails) (THIS_ _Out_ XAUDIO2_VOICE_DETAILS* pVoiceDetails) PURE; \ + \ + /* NAME: IXAudio2Voice::SetOutputVoices + // DESCRIPTION: Replaces the set of submix/mastering voices that receive + // this voice's output. + // + // ARGUMENTS: + // pSendList - Optional list of voices this voice should send audio to. + */\ + STDMETHOD(SetOutputVoices) (THIS_ _In_opt_ const XAUDIO2_VOICE_SENDS* pSendList) PURE; \ + \ + /* NAME: IXAudio2Voice::SetEffectChain + // DESCRIPTION: Replaces this voice's current effect chain with a new one. + // + // ARGUMENTS: + // pEffectChain - Structure describing the new effect chain to be used. + */\ + STDMETHOD(SetEffectChain) (THIS_ _In_opt_ const XAUDIO2_EFFECT_CHAIN* pEffectChain) PURE; \ + \ + /* NAME: IXAudio2Voice::EnableEffect + // DESCRIPTION: Enables an effect in this voice's effect chain. + // + // ARGUMENTS: + // EffectIndex - Index of an effect within this voice's effect chain. + // OperationSet - Used to identify this call as part of a deferred batch. + */\ + STDMETHOD(EnableEffect) (THIS_ UINT32 EffectIndex, \ + UINT32 OperationSet X2DEFAULT(XAUDIO2_COMMIT_NOW)) PURE; \ + \ + /* NAME: IXAudio2Voice::DisableEffect + // DESCRIPTION: Disables an effect in this voice's effect chain. + // + // ARGUMENTS: + // EffectIndex - Index of an effect within this voice's effect chain. + // OperationSet - Used to identify this call as part of a deferred batch. + */\ + STDMETHOD(DisableEffect) (THIS_ UINT32 EffectIndex, \ + UINT32 OperationSet X2DEFAULT(XAUDIO2_COMMIT_NOW)) PURE; \ + \ + /* NAME: IXAudio2Voice::GetEffectState + // DESCRIPTION: Returns the running state of an effect. + // + // ARGUMENTS: + // EffectIndex - Index of an effect within this voice's effect chain. + // pEnabled - Returns the enabled/disabled state of the given effect. + */\ + STDMETHOD_(void, GetEffectState) (THIS_ UINT32 EffectIndex, _Out_ BOOL* pEnabled) PURE; \ + \ + /* NAME: IXAudio2Voice::SetEffectParameters + // DESCRIPTION: Sets effect-specific parameters. + // + // REMARKS: Unlike IXAPOParameters::SetParameters, this method may + // be called from any thread. XAudio2 implements + // appropriate synchronization to copy the parameters to the + // realtime audio processing thread. + // + // ARGUMENTS: + // EffectIndex - Index of an effect within this voice's effect chain. + // pParameters - Pointer to an effect-specific parameters block. + // ParametersByteSize - Size of the pParameters array in bytes. + // OperationSet - Used to identify this call as part of a deferred batch. + */\ + STDMETHOD(SetEffectParameters) (THIS_ UINT32 EffectIndex, \ + _In_reads_bytes_(ParametersByteSize) const void* pParameters, \ + UINT32 ParametersByteSize, \ + UINT32 OperationSet X2DEFAULT(XAUDIO2_COMMIT_NOW)) PURE; \ + \ + /* NAME: IXAudio2Voice::GetEffectParameters + // DESCRIPTION: Obtains the current effect-specific parameters. + // + // ARGUMENTS: + // EffectIndex - Index of an effect within this voice's effect chain. + // pParameters - Returns the current values of the effect-specific parameters. + // ParametersByteSize - Size of the pParameters array in bytes. + */\ + STDMETHOD(GetEffectParameters) (THIS_ UINT32 EffectIndex, \ + _Out_writes_bytes_(ParametersByteSize) void* pParameters, \ + UINT32 ParametersByteSize) PURE; \ + \ + /* NAME: IXAudio2Voice::SetFilterParameters + // DESCRIPTION: Sets this voice's filter parameters. + // + // ARGUMENTS: + // pParameters - Pointer to the filter's parameter structure. + // OperationSet - Used to identify this call as part of a deferred batch. + */\ + STDMETHOD(SetFilterParameters) (THIS_ _In_ const XAUDIO2_FILTER_PARAMETERS* pParameters, \ + UINT32 OperationSet X2DEFAULT(XAUDIO2_COMMIT_NOW)) PURE; \ + \ + /* NAME: IXAudio2Voice::GetFilterParameters + // DESCRIPTION: Returns this voice's current filter parameters. + // + // ARGUMENTS: + // pParameters - Returns the filter parameters. + */\ + STDMETHOD_(void, GetFilterParameters) (THIS_ _Out_ XAUDIO2_FILTER_PARAMETERS* pParameters) PURE; \ + \ + /* NAME: IXAudio2Voice::SetOutputFilterParameters + // DESCRIPTION: Sets the filter parameters on one of this voice's sends. + // + // ARGUMENTS: + // pDestinationVoice - Destination voice of the send whose filter parameters will be set. + // pParameters - Pointer to the filter's parameter structure. + // OperationSet - Used to identify this call as part of a deferred batch. + */\ + STDMETHOD(SetOutputFilterParameters) (THIS_ _In_opt_ IXAudio2Voice* pDestinationVoice, \ + _In_ const XAUDIO2_FILTER_PARAMETERS* pParameters, \ + UINT32 OperationSet X2DEFAULT(XAUDIO2_COMMIT_NOW)) PURE; \ + \ + /* NAME: IXAudio2Voice::GetOutputFilterParameters + // DESCRIPTION: Returns the filter parameters from one of this voice's sends. + // + // ARGUMENTS: + // pDestinationVoice - Destination voice of the send whose filter parameters will be read. + // pParameters - Returns the filter parameters. + */\ + STDMETHOD_(void, GetOutputFilterParameters) (THIS_ _In_opt_ IXAudio2Voice* pDestinationVoice, \ + _Out_ XAUDIO2_FILTER_PARAMETERS* pParameters) PURE; \ + \ + /* NAME: IXAudio2Voice::SetVolume + // DESCRIPTION: Sets this voice's overall volume level. + // + // ARGUMENTS: + // Volume - New overall volume level to be used, as an amplitude factor. + // OperationSet - Used to identify this call as part of a deferred batch. + */\ + STDMETHOD(SetVolume) (THIS_ float Volume, \ + UINT32 OperationSet X2DEFAULT(XAUDIO2_COMMIT_NOW)) PURE; \ + \ + /* NAME: IXAudio2Voice::GetVolume + // DESCRIPTION: Obtains this voice's current overall volume level. + // + // ARGUMENTS: + // pVolume: Returns the voice's current overall volume level. + */\ + STDMETHOD_(void, GetVolume) (THIS_ _Out_ float* pVolume) PURE; \ + \ + /* NAME: IXAudio2Voice::SetChannelVolumes + // DESCRIPTION: Sets this voice's per-channel volume levels. + // + // ARGUMENTS: + // Channels - Used to confirm the voice's channel count. + // pVolumes - Array of per-channel volume levels to be used. + // OperationSet - Used to identify this call as part of a deferred batch. + */\ + STDMETHOD(SetChannelVolumes) (THIS_ UINT32 Channels, _In_reads_(Channels) const float* pVolumes, \ + UINT32 OperationSet X2DEFAULT(XAUDIO2_COMMIT_NOW)) PURE; \ + \ + /* NAME: IXAudio2Voice::GetChannelVolumes + // DESCRIPTION: Returns this voice's current per-channel volume levels. + // + // ARGUMENTS: + // Channels - Used to confirm the voice's channel count. + // pVolumes - Returns an array of the current per-channel volume levels. + */\ + STDMETHOD_(void, GetChannelVolumes) (THIS_ UINT32 Channels, _Out_writes_(Channels) float* pVolumes) PURE; \ + \ + /* NAME: IXAudio2Voice::SetOutputMatrix + // DESCRIPTION: Sets the volume levels used to mix from each channel of this + // voice's output audio to each channel of a given destination + // voice's input audio. + // + // ARGUMENTS: + // pDestinationVoice - The destination voice whose mix matrix to change. + // SourceChannels - Used to confirm this voice's output channel count + // (the number of channels produced by the last effect in the chain). + // DestinationChannels - Confirms the destination voice's input channels. + // pLevelMatrix - Array of [SourceChannels * DestinationChannels] send + // levels. The level used to send from source channel S to destination + // channel D should be in pLevelMatrix[S + SourceChannels * D]. + // OperationSet - Used to identify this call as part of a deferred batch. + */\ + STDMETHOD(SetOutputMatrix) (THIS_ _In_opt_ IXAudio2Voice* pDestinationVoice, \ + UINT32 SourceChannels, UINT32 DestinationChannels, \ + _In_reads_(SourceChannels * DestinationChannels) const float* pLevelMatrix, \ + UINT32 OperationSet X2DEFAULT(XAUDIO2_COMMIT_NOW)) PURE; \ + \ + /* NAME: IXAudio2Voice::GetOutputMatrix + // DESCRIPTION: Obtains the volume levels used to send each channel of this + // voice's output audio to each channel of a given destination + // voice's input audio. + // + // ARGUMENTS: + // pDestinationVoice - The destination voice whose mix matrix to obtain. + // SourceChannels - Used to confirm this voice's output channel count + // (the number of channels produced by the last effect in the chain). + // DestinationChannels - Confirms the destination voice's input channels. + // pLevelMatrix - Array of send levels, as above. + */\ + STDMETHOD_(void, GetOutputMatrix) (THIS_ _In_opt_ IXAudio2Voice* pDestinationVoice, \ + UINT32 SourceChannels, UINT32 DestinationChannels, \ + _Out_writes_(SourceChannels * DestinationChannels) float* pLevelMatrix) PURE; \ + \ + /* NAME: IXAudio2Voice::DestroyVoice + // DESCRIPTION: Destroys this voice, stopping it if necessary and removing + // it from the XAudio2 graph. + */\ + STDMETHOD_(void, DestroyVoice) (THIS) PURE + + Declare_IXAudio2Voice_Methods(); +}; + + +/************************************************************************** + * + * IXAudio2SourceVoice: Source voice management interface. + * + **************************************************************************/ + +#undef INTERFACE +#define INTERFACE IXAudio2SourceVoice +DECLARE_INTERFACE_(IXAudio2SourceVoice, IXAudio2Voice) +{ + // Methods from IXAudio2Voice base interface + Declare_IXAudio2Voice_Methods(); + + // NAME: IXAudio2SourceVoice::Start + // DESCRIPTION: Makes this voice start consuming and processing audio. + // + // ARGUMENTS: + // Flags - Flags controlling how the voice should be started. + // OperationSet - Used to identify this call as part of a deferred batch. + // + STDMETHOD(Start) (THIS_ UINT32 Flags X2DEFAULT(0), UINT32 OperationSet X2DEFAULT(XAUDIO2_COMMIT_NOW)) PURE; + + // NAME: IXAudio2SourceVoice::Stop + // DESCRIPTION: Makes this voice stop consuming audio. + // + // ARGUMENTS: + // Flags - Flags controlling how the voice should be stopped. + // OperationSet - Used to identify this call as part of a deferred batch. + // + STDMETHOD(Stop) (THIS_ UINT32 Flags X2DEFAULT(0), UINT32 OperationSet X2DEFAULT(XAUDIO2_COMMIT_NOW)) PURE; + + // NAME: IXAudio2SourceVoice::SubmitSourceBuffer + // DESCRIPTION: Adds a new audio buffer to this voice's input queue. + // + // ARGUMENTS: + // pBuffer - Pointer to the buffer structure to be queued. + // pBufferWMA - Additional structure used only when submitting XWMA data. + // + STDMETHOD(SubmitSourceBuffer) (THIS_ _In_ const XAUDIO2_BUFFER* pBuffer, _In_opt_ const XAUDIO2_BUFFER_WMA* pBufferWMA X2DEFAULT(NULL)) PURE; + + // NAME: IXAudio2SourceVoice::FlushSourceBuffers + // DESCRIPTION: Removes all pending audio buffers from this voice's queue. + // + STDMETHOD(FlushSourceBuffers) (THIS) PURE; + + // NAME: IXAudio2SourceVoice::Discontinuity + // DESCRIPTION: Notifies the voice of an intentional break in the stream of + // audio buffers (e.g. the end of a sound), to prevent XAudio2 + // from interpreting an empty buffer queue as a glitch. + // + STDMETHOD(Discontinuity) (THIS) PURE; + + // NAME: IXAudio2SourceVoice::ExitLoop + // DESCRIPTION: Breaks out of the current loop when its end is reached. + // + // ARGUMENTS: + // OperationSet - Used to identify this call as part of a deferred batch. + // + STDMETHOD(ExitLoop) (THIS_ UINT32 OperationSet X2DEFAULT(XAUDIO2_COMMIT_NOW)) PURE; + + // NAME: IXAudio2SourceVoice::GetState + // DESCRIPTION: Returns the number of buffers currently queued on this voice, + // the pContext value associated with the currently processing + // buffer (if any), and other voice state information. + // + // ARGUMENTS: + // pVoiceState - Returns the state information. + // Flags - Flags controlling what voice state is returned. + // + STDMETHOD_(void, GetState) (THIS_ _Out_ XAUDIO2_VOICE_STATE* pVoiceState, UINT32 Flags X2DEFAULT(0)) PURE; + + // NAME: IXAudio2SourceVoice::SetFrequencyRatio + // DESCRIPTION: Sets this voice's frequency adjustment, i.e. its pitch. + // + // ARGUMENTS: + // Ratio - Frequency change, expressed as source frequency / target frequency. + // OperationSet - Used to identify this call as part of a deferred batch. + // + STDMETHOD(SetFrequencyRatio) (THIS_ float Ratio, + UINT32 OperationSet X2DEFAULT(XAUDIO2_COMMIT_NOW)) PURE; + + // NAME: IXAudio2SourceVoice::GetFrequencyRatio + // DESCRIPTION: Returns this voice's current frequency adjustment ratio. + // + // ARGUMENTS: + // pRatio - Returns the frequency adjustment. + // + STDMETHOD_(void, GetFrequencyRatio) (THIS_ _Out_ float* pRatio) PURE; + + // NAME: IXAudio2SourceVoice::SetSourceSampleRate + // DESCRIPTION: Reconfigures this voice to treat its source data as being + // at a different sample rate than the original one specified + // in CreateSourceVoice's pSourceFormat argument. + // + // ARGUMENTS: + // UINT32 - The intended sample rate of further submitted source data. + // + STDMETHOD(SetSourceSampleRate) (THIS_ UINT32 NewSourceSampleRate) PURE; +}; + + +/************************************************************************** + * + * IXAudio2SubmixVoice: Submixing voice management interface. + * + **************************************************************************/ + +#undef INTERFACE +#define INTERFACE IXAudio2SubmixVoice +DECLARE_INTERFACE_(IXAudio2SubmixVoice, IXAudio2Voice) +{ + // Methods from IXAudio2Voice base interface + Declare_IXAudio2Voice_Methods(); + + // There are currently no methods specific to submix voices. +}; + + +/************************************************************************** + * + * IXAudio2MasteringVoice: Mastering voice management interface. + * + **************************************************************************/ + +#undef INTERFACE +#define INTERFACE IXAudio2MasteringVoice +DECLARE_INTERFACE_(IXAudio2MasteringVoice, IXAudio2Voice) +{ + // Methods from IXAudio2Voice base interface + Declare_IXAudio2Voice_Methods(); + + // NAME: IXAudio2MasteringVoice::GetChannelMask + // DESCRIPTION: Returns the channel mask for this voice + // + // ARGUMENTS: + // pChannelMask - returns the channel mask for this voice. This corresponds + // to the dwChannelMask member of WAVEFORMATEXTENSIBLE. + // + STDMETHOD(GetChannelMask) (THIS_ _Out_ DWORD* pChannelmask) PURE; +}; + + +/************************************************************************** + * + * IXAudio2EngineCallback: Client notification interface for engine events. + * + * REMARKS: Contains methods to notify the client when certain events happen + * in the XAudio2 engine. This interface should be implemented by + * the client. XAudio2 will call these methods via the interface + * pointer provided by the client when it calls + * IXAudio2::RegisterForCallbacks. + * + **************************************************************************/ + +#undef INTERFACE +#define INTERFACE IXAudio2EngineCallback +DECLARE_INTERFACE(IXAudio2EngineCallback) +{ + // Called by XAudio2 just before an audio processing pass begins. + STDMETHOD_(void, OnProcessingPassStart) (THIS) PURE; + + // Called just after an audio processing pass ends. + STDMETHOD_(void, OnProcessingPassEnd) (THIS) PURE; + + // Called in the event of a critical system error which requires XAudio2 + // to be closed down and restarted. The error code is given in Error. + STDMETHOD_(void, OnCriticalError) (THIS_ HRESULT Error) PURE; +}; + + +/************************************************************************** + * + * IXAudio2VoiceCallback: Client notification interface for voice events. + * + * REMARKS: Contains methods to notify the client when certain events happen + * in an XAudio2 voice. This interface should be implemented by the + * client. XAudio2 will call these methods via an interface pointer + * provided by the client in the IXAudio2::CreateSourceVoice call. + * + **************************************************************************/ + +#undef INTERFACE +#define INTERFACE IXAudio2VoiceCallback +DECLARE_INTERFACE(IXAudio2VoiceCallback) +{ + // Called just before this voice's processing pass begins. + STDMETHOD_(void, OnVoiceProcessingPassStart) (THIS_ UINT32 BytesRequired) PURE; + + // Called just after this voice's processing pass ends. + STDMETHOD_(void, OnVoiceProcessingPassEnd) (THIS) PURE; + + // Called when this voice has just finished playing a buffer stream + // (as marked with the XAUDIO2_END_OF_STREAM flag on the last buffer). + STDMETHOD_(void, OnStreamEnd) (THIS) PURE; + + // Called when this voice is about to start processing a new buffer. + STDMETHOD_(void, OnBufferStart) (THIS_ void* pBufferContext) PURE; + + // Called when this voice has just finished processing a buffer. + // The buffer can now be reused or destroyed. + STDMETHOD_(void, OnBufferEnd) (THIS_ void* pBufferContext) PURE; + + // Called when this voice has just reached the end position of a loop. + STDMETHOD_(void, OnLoopEnd) (THIS_ void* pBufferContext) PURE; + + // Called in the event of a critical error during voice processing, + // such as a failing xAPO or an error from the hardware XMA decoder. + // The voice may have to be destroyed and re-created to recover from + // the error. The callback arguments report which buffer was being + // processed when the error occurred, and its HRESULT code. + STDMETHOD_(void, OnVoiceError) (THIS_ void* pBufferContext, HRESULT Error) PURE; +}; + + +/************************************************************************** + * + * Macros to make it easier to use the XAudio2 COM interfaces in C code. + * + **************************************************************************/ + +#ifndef __cplusplus + +// IXAudio2 +#define IXAudio2_QueryInterface(This,riid,ppvInterface) ((This)->lpVtbl->QueryInterface(This,riid,ppvInterface)) +#define IXAudio2_AddRef(This) ((This)->lpVtbl->AddRef(This)) +#define IXAudio2_Release(This) ((This)->lpVtbl->Release(This)) +#define IXAudio2_CreateSourceVoice(This,ppSourceVoice,pSourceFormat,Flags,MaxFrequencyRatio,pCallback,pSendList,pEffectChain) ((This)->lpVtbl->CreateSourceVoice(This,ppSourceVoice,pSourceFormat,Flags,MaxFrequencyRatio,pCallback,pSendList,pEffectChain)) +#define IXAudio2_CreateSubmixVoice(This,ppSubmixVoice,InputChannels,InputSampleRate,Flags,ProcessingStage,pSendList,pEffectChain) ((This)->lpVtbl->CreateSubmixVoice(This,ppSubmixVoice,InputChannels,InputSampleRate,Flags,ProcessingStage,pSendList,pEffectChain)) +#define IXAudio2_CreateMasteringVoice(This,ppMasteringVoice,InputChannels,InputSampleRate,Flags,DeviceId,pEffectChain,StreamCategory) ((This)->lpVtbl->CreateMasteringVoice(This,ppMasteringVoice,InputChannels,InputSampleRate,Flags,DeviceId,pEffectChain,StreamCategory)) +#define IXAudio2_StartEngine(This) ((This)->lpVtbl->StartEngine(This)) +#define IXAudio2_StopEngine(This) ((This)->lpVtbl->StopEngine(This)) +#define IXAudio2_CommitChanges(This,OperationSet) ((This)->lpVtbl->CommitChanges(This,OperationSet)) +#define IXAudio2_GetPerformanceData(This,pPerfData) ((This)->lpVtbl->GetPerformanceData(This,pPerfData)) +#define IXAudio2_SetDebugConfiguration(This,pDebugConfiguration,pReserved) ((This)->lpVtbl->SetDebugConfiguration(This,pDebugConfiguration,pReserved)) + +// IXAudio2Voice +#define IXAudio2Voice_GetVoiceDetails(This,pVoiceDetails) ((This)->lpVtbl->GetVoiceDetails(This,pVoiceDetails)) +#define IXAudio2Voice_SetOutputVoices(This,pSendList) ((This)->lpVtbl->SetOutputVoices(This,pSendList)) +#define IXAudio2Voice_SetEffectChain(This,pEffectChain) ((This)->lpVtbl->SetEffectChain(This,pEffectChain)) +#define IXAudio2Voice_EnableEffect(This,EffectIndex,OperationSet) ((This)->lpVtbl->EnableEffect(This,EffectIndex,OperationSet)) +#define IXAudio2Voice_DisableEffect(This,EffectIndex,OperationSet) ((This)->lpVtbl->DisableEffect(This,EffectIndex,OperationSet)) +#define IXAudio2Voice_GetEffectState(This,EffectIndex,pEnabled) ((This)->lpVtbl->GetEffectState(This,EffectIndex,pEnabled)) +#define IXAudio2Voice_SetEffectParameters(This,EffectIndex,pParameters,ParametersByteSize, OperationSet) ((This)->lpVtbl->SetEffectParameters(This,EffectIndex,pParameters,ParametersByteSize,OperationSet)) +#define IXAudio2Voice_GetEffectParameters(This,EffectIndex,pParameters,ParametersByteSize) ((This)->lpVtbl->GetEffectParameters(This,EffectIndex,pParameters,ParametersByteSize)) +#define IXAudio2Voice_SetFilterParameters(This,pParameters,OperationSet) ((This)->lpVtbl->SetFilterParameters(This,pParameters,OperationSet)) +#define IXAudio2Voice_GetFilterParameters(This,pParameters) ((This)->lpVtbl->GetFilterParameters(This,pParameters)) +#define IXAudio2Voice_SetOutputFilterParameters(This,pDestinationVoice,pParameters,OperationSet) ((This)->lpVtbl->SetOutputFilterParameters(This,pDestinationVoice,pParameters,OperationSet)) +#define IXAudio2Voice_GetOutputFilterParameters(This,pDestinationVoice,pParameters) ((This)->lpVtbl->GetOutputFilterParameters(This,pDestinationVoice,pParameters)) +#define IXAudio2Voice_SetVolume(This,Volume,OperationSet) ((This)->lpVtbl->SetVolume(This,Volume,OperationSet)) +#define IXAudio2Voice_GetVolume(This,pVolume) ((This)->lpVtbl->GetVolume(This,pVolume)) +#define IXAudio2Voice_SetChannelVolumes(This,Channels,pVolumes,OperationSet) ((This)->lpVtbl->SetChannelVolumes(This,Channels,pVolumes,OperationSet)) +#define IXAudio2Voice_GetChannelVolumes(This,Channels,pVolumes) ((This)->lpVtbl->GetChannelVolumes(This,Channels,pVolumes)) +#define IXAudio2Voice_SetOutputMatrix(This,pDestinationVoice,SourceChannels,DestinationChannels,pLevelMatrix,OperationSet) ((This)->lpVtbl->SetOutputMatrix(This,pDestinationVoice,SourceChannels,DestinationChannels,pLevelMatrix,OperationSet)) +#define IXAudio2Voice_GetOutputMatrix(This,pDestinationVoice,SourceChannels,DestinationChannels,pLevelMatrix) ((This)->lpVtbl->GetOutputMatrix(This,pDestinationVoice,SourceChannels,DestinationChannels,pLevelMatrix)) +#define IXAudio2Voice_DestroyVoice(This) ((This)->lpVtbl->DestroyVoice(This)) + +// IXAudio2SourceVoice +#define IXAudio2SourceVoice_GetVoiceDetails IXAudio2Voice_GetVoiceDetails +#define IXAudio2SourceVoice_SetOutputVoices IXAudio2Voice_SetOutputVoices +#define IXAudio2SourceVoice_SetEffectChain IXAudio2Voice_SetEffectChain +#define IXAudio2SourceVoice_EnableEffect IXAudio2Voice_EnableEffect +#define IXAudio2SourceVoice_DisableEffect IXAudio2Voice_DisableEffect +#define IXAudio2SourceVoice_GetEffectState IXAudio2Voice_GetEffectState +#define IXAudio2SourceVoice_SetEffectParameters IXAudio2Voice_SetEffectParameters +#define IXAudio2SourceVoice_GetEffectParameters IXAudio2Voice_GetEffectParameters +#define IXAudio2SourceVoice_SetFilterParameters IXAudio2Voice_SetFilterParameters +#define IXAudio2SourceVoice_GetFilterParameters IXAudio2Voice_GetFilterParameters +#define IXAudio2SourceVoice_SetOutputFilterParameters IXAudio2Voice_SetOutputFilterParameters +#define IXAudio2SourceVoice_GetOutputFilterParameters IXAudio2Voice_GetOutputFilterParameters +#define IXAudio2SourceVoice_SetVolume IXAudio2Voice_SetVolume +#define IXAudio2SourceVoice_GetVolume IXAudio2Voice_GetVolume +#define IXAudio2SourceVoice_SetChannelVolumes IXAudio2Voice_SetChannelVolumes +#define IXAudio2SourceVoice_GetChannelVolumes IXAudio2Voice_GetChannelVolumes +#define IXAudio2SourceVoice_SetOutputMatrix IXAudio2Voice_SetOutputMatrix +#define IXAudio2SourceVoice_GetOutputMatrix IXAudio2Voice_GetOutputMatrix +#define IXAudio2SourceVoice_DestroyVoice IXAudio2Voice_DestroyVoice +#define IXAudio2SourceVoice_Start(This,Flags,OperationSet) ((This)->lpVtbl->Start(This,Flags,OperationSet)) +#define IXAudio2SourceVoice_Stop(This,Flags,OperationSet) ((This)->lpVtbl->Stop(This,Flags,OperationSet)) +#define IXAudio2SourceVoice_SubmitSourceBuffer(This,pBuffer,pBufferWMA) ((This)->lpVtbl->SubmitSourceBuffer(This,pBuffer,pBufferWMA)) +#define IXAudio2SourceVoice_FlushSourceBuffers(This) ((This)->lpVtbl->FlushSourceBuffers(This)) +#define IXAudio2SourceVoice_Discontinuity(This) ((This)->lpVtbl->Discontinuity(This)) +#define IXAudio2SourceVoice_ExitLoop(This,OperationSet) ((This)->lpVtbl->ExitLoop(This,OperationSet)) +#define IXAudio2SourceVoice_GetState(This,pVoiceState,Flags) ((This)->lpVtbl->GetState(This,pVoiceState,Flags)) +#define IXAudio2SourceVoice_SetFrequencyRatio(This,Ratio,OperationSet) ((This)->lpVtbl->SetFrequencyRatio(This,Ratio,OperationSet)) +#define IXAudio2SourceVoice_GetFrequencyRatio(This,pRatio) ((This)->lpVtbl->GetFrequencyRatio(This,pRatio)) +#define IXAudio2SourceVoice_SetSourceSampleRate(This,NewSourceSampleRate) ((This)->lpVtbl->SetSourceSampleRate(This,NewSourceSampleRate)) + +// IXAudio2SubmixVoice +#define IXAudio2SubmixVoice_GetVoiceDetails IXAudio2Voice_GetVoiceDetails +#define IXAudio2SubmixVoice_SetOutputVoices IXAudio2Voice_SetOutputVoices +#define IXAudio2SubmixVoice_SetEffectChain IXAudio2Voice_SetEffectChain +#define IXAudio2SubmixVoice_EnableEffect IXAudio2Voice_EnableEffect +#define IXAudio2SubmixVoice_DisableEffect IXAudio2Voice_DisableEffect +#define IXAudio2SubmixVoice_GetEffectState IXAudio2Voice_GetEffectState +#define IXAudio2SubmixVoice_SetEffectParameters IXAudio2Voice_SetEffectParameters +#define IXAudio2SubmixVoice_GetEffectParameters IXAudio2Voice_GetEffectParameters +#define IXAudio2SubmixVoice_SetFilterParameters IXAudio2Voice_SetFilterParameters +#define IXAudio2SubmixVoice_GetFilterParameters IXAudio2Voice_GetFilterParameters +#define IXAudio2SubmixVoice_SetOutputFilterParameters IXAudio2Voice_SetOutputFilterParameters +#define IXAudio2SubmixVoice_GetOutputFilterParameters IXAudio2Voice_GetOutputFilterParameters +#define IXAudio2SubmixVoice_SetVolume IXAudio2Voice_SetVolume +#define IXAudio2SubmixVoice_GetVolume IXAudio2Voice_GetVolume +#define IXAudio2SubmixVoice_SetChannelVolumes IXAudio2Voice_SetChannelVolumes +#define IXAudio2SubmixVoice_GetChannelVolumes IXAudio2Voice_GetChannelVolumes +#define IXAudio2SubmixVoice_SetOutputMatrix IXAudio2Voice_SetOutputMatrix +#define IXAudio2SubmixVoice_GetOutputMatrix IXAudio2Voice_GetOutputMatrix +#define IXAudio2SubmixVoice_DestroyVoice IXAudio2Voice_DestroyVoice + +// IXAudio2MasteringVoice +#define IXAudio2MasteringVoice_GetVoiceDetails IXAudio2Voice_GetVoiceDetails +#define IXAudio2MasteringVoice_SetOutputVoices IXAudio2Voice_SetOutputVoices +#define IXAudio2MasteringVoice_SetEffectChain IXAudio2Voice_SetEffectChain +#define IXAudio2MasteringVoice_EnableEffect IXAudio2Voice_EnableEffect +#define IXAudio2MasteringVoice_DisableEffect IXAudio2Voice_DisableEffect +#define IXAudio2MasteringVoice_GetEffectState IXAudio2Voice_GetEffectState +#define IXAudio2MasteringVoice_SetEffectParameters IXAudio2Voice_SetEffectParameters +#define IXAudio2MasteringVoice_GetEffectParameters IXAudio2Voice_GetEffectParameters +#define IXAudio2MasteringVoice_SetFilterParameters IXAudio2Voice_SetFilterParameters +#define IXAudio2MasteringVoice_GetFilterParameters IXAudio2Voice_GetFilterParameters +#define IXAudio2MasteringVoice_SetOutputFilterParameters IXAudio2Voice_SetOutputFilterParameters +#define IXAudio2MasteringVoice_GetOutputFilterParameters IXAudio2Voice_GetOutputFilterParameters +#define IXAudio2MasteringVoice_SetVolume IXAudio2Voice_SetVolume +#define IXAudio2MasteringVoice_GetVolume IXAudio2Voice_GetVolume +#define IXAudio2MasteringVoice_SetChannelVolumes IXAudio2Voice_SetChannelVolumes +#define IXAudio2MasteringVoice_GetChannelVolumes IXAudio2Voice_GetChannelVolumes +#define IXAudio2MasteringVoice_SetOutputMatrix IXAudio2Voice_SetOutputMatrix +#define IXAudio2MasteringVoice_GetOutputMatrix IXAudio2Voice_GetOutputMatrix +#define IXAudio2MasteringVoice_DestroyVoice IXAudio2Voice_DestroyVoice +#define IXAudio2MasteringVoice_GetChannelMask(This,pChannelMask) ((This)->lpVtbl->GetChannelMask(This,pChannelMask)) + +#endif // #ifndef __cplusplus + + +/************************************************************************** + * + * Utility functions used to convert from pitch in semitones and volume + * in decibels to the frequency and amplitude ratio units used by XAudio2. + * These are only defined if the client #defines XAUDIO2_HELPER_FUNCTIONS + * prior to #including xaudio2.h. + * + **************************************************************************/ + +#ifdef XAUDIO2_HELPER_FUNCTIONS + +#define _USE_MATH_DEFINES // Make math.h define M_PI +#include // For powf, log10f, sinf and asinf + +// Calculate the argument to SetVolume from a decibel value +__inline float XAudio2DecibelsToAmplitudeRatio(float Decibels) +{ + return powf(10.0f, Decibels / 20.0f); +} + +// Recover a volume in decibels from an amplitude factor +__inline float XAudio2AmplitudeRatioToDecibels(float Volume) +{ + if (Volume == 0) + { + return -3.402823466e+38f; // Smallest float value (-FLT_MAX) + } + return 20.0f * log10f(Volume); +} + +// Calculate the argument to SetFrequencyRatio from a semitone value +__inline float XAudio2SemitonesToFrequencyRatio(float Semitones) +{ + // FrequencyRatio = 2 ^ Octaves + // = 2 ^ (Semitones / 12) + return powf(2.0f, Semitones / 12.0f); +} + +// Recover a pitch in semitones from a frequency ratio +__inline float XAudio2FrequencyRatioToSemitones(float FrequencyRatio) +{ + // Semitones = 12 * log2(FrequencyRatio) + // = 12 * log2(10) * log10(FrequencyRatio) + return 39.86313713864835f * log10f(FrequencyRatio); +} + +// Convert from filter cutoff frequencies expressed in Hertz to the radian +// frequency values used in XAUDIO2_FILTER_PARAMETERS.Frequency, state-variable +// filter types only. Use XAudio2CutoffFrequencyToOnePoleCoefficient() for one-pole filter types. +// Note that the highest CutoffFrequency supported is SampleRate/6. +// Higher values of CutoffFrequency will return XAUDIO2_MAX_FILTER_FREQUENCY. +__inline float XAudio2CutoffFrequencyToRadians(float CutoffFrequency, UINT32 SampleRate) +{ + if ((UINT32)(CutoffFrequency * 6.0f) >= SampleRate) + { + return XAUDIO2_MAX_FILTER_FREQUENCY; + } + return 2.0f * sinf((float)M_PI * CutoffFrequency / SampleRate); +} + +// Convert from radian frequencies back to absolute frequencies in Hertz +__inline float XAudio2RadiansToCutoffFrequency(float Radians, float SampleRate) +{ + return SampleRate * asinf(Radians / 2.0f) / (float)M_PI; +} + +// Convert from filter cutoff frequencies expressed in Hertz to the filter +// coefficients used with XAUDIO2_FILTER_PARAMETERS.Frequency, +// LowPassOnePoleFilter and HighPassOnePoleFilter filter types only. +// Use XAudio2CutoffFrequencyToRadians() for state-variable filter types. +__inline float XAudio2CutoffFrequencyToOnePoleCoefficient(float CutoffFrequency, UINT32 SampleRate) +{ + if ((UINT32)CutoffFrequency >= SampleRate) + { + return XAUDIO2_MAX_FILTER_FREQUENCY; + } + return ( 1.0f - powf(1.0f - 2.0f * CutoffFrequency / SampleRate, 2.0f) ); +} + + +#endif // #ifdef XAUDIO2_HELPER_FUNCTIONS + + +/************************************************************************** + * + * XAudio2Create: Top-level function that creates an XAudio2 instance. + * + * ARGUMENTS: + * + * Flags - Flags specifying the XAudio2 object's behavior. + * + * XAudio2Processor - An XAUDIO2_PROCESSOR value that specifies the + * hardware threads (Xbox) or processors (Windows) that XAudio2 + * will use. Note that XAudio2 supports concurrent processing on + * multiple threads, using any combination of XAUDIO2_PROCESSOR + * flags. The values are platform-specific; platform-independent + * code can use XAUDIO2_DEFAULT_PROCESSOR to use the default on + * each platform. + * + **************************************************************************/ + +#ifdef __cplusplus__ + +#if (defined XAUDIO2_EXPORT) + // We're building xaudio2.dll + #define XAUDIO2_STDAPI extern "C" __declspec(dllexport) HRESULT __stdcall +#else + // We're an xaudio2 client + #define XAUDIO2_STDAPI extern "C" __declspec(dllimport) HRESULT __stdcall +#endif + +#else + +/* Modified for C support */ + +#if (defined XAUDIO2_EXPORT) + // We're building xaudio2.dll + #define XAUDIO2_STDAPI __declspec(dllexport) HRESULT __stdcall +#else + // We're an xaudio2 client + #define XAUDIO2_STDAPI __declspec(dllimport) HRESULT __stdcall +#endif + +#endif + +#if (NTDDI_VERSION >= NTDDI_WIN10_RS5) && WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) +XAUDIO2_STDAPI XAudio2CreateWithVersionInfo(_Outptr_ IXAudio2** ppXAudio2, + UINT32 Flags X2DEFAULT(0), + XAUDIO2_PROCESSOR XAudio2Processor X2DEFAULT(XAUDIO2_DEFAULT_PROCESSOR), + DWORD ntddiVersion X2DEFAULT(NTDDI_VERSION)); + +inline HRESULT XAudio2Create(_Outptr_ IXAudio2** ppXAudio2, + UINT32 Flags X2DEFAULT(0), + XAUDIO2_PROCESSOR XAudio2Processor X2DEFAULT(XAUDIO2_DEFAULT_PROCESSOR)) +{ + // When compiled for RS5 or later, try to invoke XAudio2CreateWithVersionInfo. + // Need to use LoadLibrary in case the app is running on an older OS. + typedef HRESULT(__stdcall *XAudio2CreateWithVersionInfoFunc)(_Outptr_ IXAudio2**, UINT32, XAUDIO2_PROCESSOR, DWORD); + typedef HRESULT(__stdcall *XAudio2CreateInfoFunc)(_Outptr_ IXAudio2**, UINT32, XAUDIO2_PROCESSOR); + + static HMODULE s_dllInstance = nullptr; + static XAudio2CreateWithVersionInfoFunc s_pfnAudio2CreateWithVersion = nullptr; + static XAudio2CreateInfoFunc s_pfnAudio2Create = nullptr; + + if (s_dllInstance == nullptr) + { + s_dllInstance = LoadLibraryEx(XAUDIO2_DLL, NULL, LOAD_LIBRARY_SEARCH_SYSTEM32); + if (s_dllInstance == nullptr) + { + return HRESULT_FROM_WIN32(GetLastError()); + } + + s_pfnAudio2CreateWithVersion = (XAudio2CreateWithVersionInfoFunc)(void*)GetProcAddress(s_dllInstance, "XAudio2CreateWithVersionInfo"); + if (s_pfnAudio2CreateWithVersion == nullptr) + { + s_pfnAudio2Create = (XAudio2CreateInfoFunc)(void*)GetProcAddress(s_dllInstance, "XAudio2Create"); + if (s_pfnAudio2Create == nullptr) + { + return HRESULT_FROM_WIN32(GetLastError()); + } + } + } + + if (s_pfnAudio2CreateWithVersion != nullptr) + { + return (*s_pfnAudio2CreateWithVersion)(ppXAudio2, Flags, XAudio2Processor, NTDDI_VERSION); + } + return (*s_pfnAudio2Create)(ppXAudio2, Flags, XAudio2Processor); +} +#else +// RS4 or older, or not a desktop app +XAUDIO2_STDAPI XAudio2Create(_Outptr_ IXAudio2** ppXAudio2, UINT32 Flags X2DEFAULT(0), + XAUDIO2_PROCESSOR XAudio2Processor X2DEFAULT(XAUDIO2_DEFAULT_PROCESSOR)); +#endif + +// Undo the #pragma pack(push, 1) directive at the top of this file +#pragma pack(pop) + +#endif // #ifndef GUID_DEFS_ONLY + +#endif /* WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP | WINAPI_PARTITION_TV_APP | WINAPI_PARTITION_TV_TITLE) */ +#pragma endregion + +#endif // #ifndef __XAUDIO2_INCLUDED__ + From f6c8a0c5c2eeb862a388a90f73851886b4d539c2 Mon Sep 17 00:00:00 2001 From: krzys-h Date: Fri, 28 Dec 2018 12:29:04 +0100 Subject: [PATCH 4/5] Add UWP input driver Keyboard, mouse and touch support: done --- configuration.c | 7 +- gfx/common/d3d_common.c | 16 +++- griffin/griffin.c | 1 + input/drivers/uwp_input.c | 174 ++++++++++++++++++++++++++++++++++++++ input/input_driver.c | 3 + input/input_driver.h | 1 + uwp/uwp_func.h | 7 ++ uwp/uwp_main.cpp | 146 ++++++++++++++++++++++++++++---- uwp/uwp_main.h | 7 +- 9 files changed, 340 insertions(+), 22 deletions(-) create mode 100644 input/drivers/uwp_input.c diff --git a/configuration.c b/configuration.c index 7ab65f20d9..880caedd27 100644 --- a/configuration.c +++ b/configuration.c @@ -227,6 +227,7 @@ enum input_driver_enum INPUT_WII, INPUT_WIIU, INPUT_XINPUT, + INPUT_UWP, INPUT_UDEV, INPUT_LINUXRAW, INPUT_COCOA, @@ -437,7 +438,9 @@ static enum midi_driver_enum MIDI_DEFAULT_DRIVER = MIDI_ALSA; static enum midi_driver_enum MIDI_DEFAULT_DRIVER = MIDI_NULL; #endif -#if defined(XENON) +#ifdef __WINRT__ +static enum input_driver_enum INPUT_DEFAULT_DRIVER = INPUT_UWP; +#elif defined(XENON) static enum input_driver_enum INPUT_DEFAULT_DRIVER = INPUT_XENON360; #elif defined(_XBOX360) || defined(_XBOX) || defined(HAVE_XINPUT2) || defined(HAVE_XINPUT_XBOX1) static enum input_driver_enum INPUT_DEFAULT_DRIVER = INPUT_XINPUT; @@ -867,6 +870,8 @@ const char *config_get_default_input(void) return "xenon360"; case INPUT_XINPUT: return "xinput"; + case INPUT_UWP: + return "uwp"; case INPUT_WII: return "gx"; case INPUT_WIIU: diff --git a/gfx/common/d3d_common.c b/gfx/common/d3d_common.c index 211e68939c..4019584e6c 100644 --- a/gfx/common/d3d_common.c +++ b/gfx/common/d3d_common.c @@ -128,7 +128,21 @@ int32_t d3d_translate_filter(unsigned type) void d3d_input_driver(const char* input_name, const char* joypad_name, const input_driver_t** input, void** input_data) { -#if defined(_XBOX) || defined(__WINRT__) +#if defined(__WINRT__) + /* Plain xinput is supported on UWP, but it supports joypad only (uwp driver was added later) */ + if (string_is_equal(input_name, "xinput")) + { + void *xinput = input_xinput.init(joypad_name); + *input = xinput ? (const input_driver_t*)&input_xinput : NULL; + *input_data = xinput; + } + else + { + void *uwp = input_uwp.init(joypad_name); + *input = uwp ? (const input_driver_t*)&input_uwp : NULL; + *input_data = uwp; + } +#elif defined(_XBOX) void *xinput = input_xinput.init(joypad_name); *input = xinput ? (const input_driver_t*)&input_xinput : NULL; *input_data = xinput; diff --git a/griffin/griffin.c b/griffin/griffin.c index cbe29ef9e7..e58883035a 100644 --- a/griffin/griffin.c +++ b/griffin/griffin.c @@ -603,6 +603,7 @@ INPUT #include "../input/drivers_joypad/dos_joypad.c" #elif defined(__WINRT__) #include "../input/drivers/xdk_xinput_input.c" +#include "../input/drivers/uwp_input.c" #endif #ifdef HAVE_WAYLAND diff --git a/input/drivers/uwp_input.c b/input/drivers/uwp_input.c new file mode 100644 index 0000000000..4c2f53af19 --- /dev/null +++ b/input/drivers/uwp_input.c @@ -0,0 +1,174 @@ +/* RetroArch - A frontend for libretro. + * Copyright (C) 2018 - Krzysztof Haładyn + * + * RetroArch is free software: you can redistribute it and/or modify it under the terms + * of the GNU General Public License as published by the Free Software Found- + * ation, either version 3 of the License, or (at your option) any later version. + * + * RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + * PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with RetroArch. + * If not, see . + */ + +#include +#include + +#ifdef HAVE_CONFIG_H +#include "../../config.h" +#endif + +#include +#include + +#include + +#include "../input_driver.h" + +// TODO: Add support for multiple mice and multiple touch + +typedef struct uwp_input +{ + bool blocked; + const input_device_driver_t *joypad; +} uwp_input_t; + +static void uwp_input_poll(void *data) +{ + uwp_input_t *uwp = (uwp_input_t*)data; + + if (uwp && uwp->joypad) + uwp->joypad->poll(); + + uwp_input_next_frame(); +} + +static int16_t uwp_input_state(void *data, + rarch_joypad_info_t joypad_info, + const struct retro_keybind **binds, + unsigned port, unsigned device, + unsigned index, unsigned id) +{ + uwp_input_t *uwp = (uwp_input_t*)data; + + switch (device) + { + case RETRO_DEVICE_JOYPAD: + return input_joypad_pressed(uwp->joypad, joypad_info, port, binds[port], id); + case RETRO_DEVICE_ANALOG: + if (binds[port]) + return input_joypad_analog(uwp->joypad, joypad_info, port, index, id, binds[port]); + break; + + case RETRO_DEVICE_KEYBOARD: + return (id < RETROK_LAST) && uwp_keyboard_pressed(id); + + case RETRO_DEVICE_MOUSE: + case RARCH_DEVICE_MOUSE_SCREEN: + return uwp_mouse_state(port, id, device == RARCH_DEVICE_MOUSE_SCREEN); + + case RETRO_DEVICE_POINTER: + case RARCH_DEVICE_POINTER_SCREEN: + return uwp_pointer_state(index, id, device == RARCH_DEVICE_POINTER_SCREEN); + } + + return 0; +} + +static void uwp_input_free_input(void *data) +{ + uwp_input_t *uwp = (uwp_input_t*)data; + + if (!uwp) + return; + + if (uwp->joypad) + uwp->joypad->destroy(); + + free(uwp); +} + +static void *uwp_input_init(const char *joypad_driver) +{ + uwp_input_t *uwp = (uwp_input_t*)calloc(1, sizeof(*uwp)); + if (!uwp) + return NULL; + + input_keymaps_init_keyboard_lut(rarch_key_map_uwp); + + uwp->joypad = input_joypad_init_driver(joypad_driver, uwp); + + return uwp; +} + +static uint64_t uwp_input_get_capabilities(void *data) +{ + uint64_t caps = 0; + + caps |= (1 << RETRO_DEVICE_JOYPAD); + caps |= (1 << RETRO_DEVICE_MOUSE); + caps |= (1 << RETRO_DEVICE_KEYBOARD); + caps |= (1 << RETRO_DEVICE_POINTER); + caps |= (1 << RETRO_DEVICE_ANALOG); + + return caps; +} + +static bool uwp_input_set_rumble(void *data, unsigned port, + enum retro_rumble_effect effect, uint16_t strength) +{ + struct uwp_input *uwp = (struct uwp_input*)data; + if (!uwp) + return false; + return input_joypad_set_rumble(uwp->joypad, port, effect, strength); +} + +static const input_device_driver_t *uwp_input_get_joypad_driver(void *data) +{ + uwp_input_t *uwp = (uwp_input_t*)data; + if (!uwp) + return NULL; + return uwp->joypad; +} + +static void uwp_input_grab_mouse(void *data, bool state) +{ + (void)data; + (void)state; +} + +static bool uwp_keyboard_mapping_is_blocked(void *data) +{ + uwp_input_t *uwp = (uwp_input_t*)data; + if (!uwp) + return false; + return uwp->blocked; +} + +static void uwp_keyboard_mapping_set_block(void *data, bool value) +{ + uwp_input_t *uwp = (uwp_input_t*)data; + if (!uwp) + return; + uwp->blocked = value; +} + +input_driver_t input_uwp = { + uwp_input_init, + uwp_input_poll, + uwp_input_state, + uwp_input_free_input, + NULL, + NULL, + uwp_input_get_capabilities, + "uwp", + uwp_input_grab_mouse, + NULL, + uwp_input_set_rumble, + uwp_input_get_joypad_driver, + NULL, + uwp_keyboard_mapping_is_blocked, + uwp_keyboard_mapping_set_block, +}; diff --git a/input/input_driver.c b/input/input_driver.c index 5134c23e76..709fac324b 100644 --- a/input/input_driver.c +++ b/input/input_driver.c @@ -104,6 +104,9 @@ static const input_driver_t *input_drivers[] = { #ifdef HAVE_X11 &input_x, #endif +#ifdef __WINRT__ + &input_uwp, +#endif #ifdef XENON &input_xenon360, #endif diff --git a/input/input_driver.h b/input/input_driver.h index 1ac166478b..11fcc415b8 100644 --- a/input/input_driver.h +++ b/input/input_driver.h @@ -834,6 +834,7 @@ extern input_driver_t input_xenon360; extern input_driver_t input_gx; extern input_driver_t input_wiiu; extern input_driver_t input_xinput; +extern input_driver_t input_uwp; extern input_driver_t input_linuxraw; extern input_driver_t input_udev; extern input_driver_t input_cocoa; diff --git a/uwp/uwp_func.h b/uwp/uwp_func.h index 7a3e98e60e..4b92bc489b 100644 --- a/uwp/uwp_func.h +++ b/uwp/uwp_func.h @@ -28,6 +28,13 @@ extern char uwp_device_family[128]; void* uwp_get_corewindow(void); +void uwp_input_next_frame(void); +bool uwp_keyboard_pressed(unsigned key); +int16_t uwp_mouse_state(unsigned port, unsigned id, bool screen); +int16_t uwp_pointer_state(unsigned idx, unsigned id, bool screen); + +extern const struct rarch_key_map rarch_key_map_uwp[]; + #ifdef __cplusplus } #endif diff --git a/uwp/uwp_main.cpp b/uwp/uwp_main.cpp index 7e3f132228..b79cbc65ef 100644 --- a/uwp/uwp_main.cpp +++ b/uwp/uwp_main.cpp @@ -34,6 +34,7 @@ using namespace Windows::ApplicationModel::Activation; using namespace Windows::UI::Core; using namespace Windows::UI::Input; using namespace Windows::UI::ViewManagement; +using namespace Windows::Devices::Input; using namespace Windows::System; using namespace Windows::System::Profile; using namespace Windows::Foundation; @@ -158,6 +159,20 @@ const struct rarch_key_map rarch_key_map_uwp[] = { { 0, RETROK_UNKNOWN } }; +struct uwp_input_state_t { + short mouse_screen_x = 0, mouse_screen_y = 0; + short mouse_rel_x = 0, mouse_rel_y = 0; + bool mouse_left = false, mouse_right = false, mouse_middle = false; + bool mouse_button4 = false, mouse_button5 = false; + short mouse_wheel_left = 0, mouse_wheel_up = 0; + + short touch_screen_x = 0, touch_screen_y = 0; + short touch_rel_x = 0, touch_rel_y = 0; + bool touch_touched = false; +}; + +struct uwp_input_state_t uwp_current_input, uwp_next_input; + // The main function is only used to initialize our IFrameworkView class. [Platform::MTAThread] int main(Platform::Array^) @@ -225,10 +240,22 @@ void App::SetWindow(CoreWindow^ window) ref new TypedEventHandler(this, &App::OnWindowClosed); window->KeyDown += - ref new TypedEventHandler(this, &App::OnKeyDown); + ref new TypedEventHandler(this, &App::OnKey); window->KeyUp += - ref new TypedEventHandler(this, &App::OnKeyUp); + ref new TypedEventHandler(this, &App::OnKey); + + window->PointerPressed += + ref new TypedEventHandler(this, &App::OnPointer); + + window->PointerReleased += + ref new TypedEventHandler(this, &App::OnPointer); + + window->PointerMoved += + ref new TypedEventHandler(this, &App::OnPointer); + + window->PointerWheelChanged += + ref new TypedEventHandler(this, &App::OnPointer); DisplayInformation^ currentDisplayInformation = DisplayInformation::GetForCurrentView(); @@ -255,7 +282,6 @@ void App::Load(Platform::String^ entryPoint) CoreApplication::Exit(); return; } - input_keymaps_init_keyboard_lut(rarch_key_map_uwp); // TODO (krzys_h): move this to the input driver m_initialized = true; } @@ -356,17 +382,7 @@ void App::OnWindowActivated(CoreWindow^ sender, WindowActivatedEventArgs^ args) m_windowFocused = args->WindowActivationState != CoreWindowActivationState::Deactivated; } -void App::OnKeyDown(CoreWindow^ sender, KeyEventArgs^ args) -{ - OnKey(sender, args, true); -} - -void App::OnKeyUp(CoreWindow^ sender, KeyEventArgs^ args) -{ - OnKey(sender, args, false); -} - -void App::OnKey(CoreWindow^ sender, KeyEventArgs^ args, bool down) +void App::OnKey(CoreWindow^ sender, KeyEventArgs^ args) { uint16_t mod = 0; if ((sender->GetKeyState(VirtualKey::Shift) & CoreVirtualKeyStates::Locked) == CoreVirtualKeyStates::Locked) @@ -385,7 +401,39 @@ void App::OnKey(CoreWindow^ sender, KeyEventArgs^ args, bool down) unsigned keycode = input_keymaps_translate_keysym_to_rk((unsigned)args->VirtualKey); - input_keyboard_event(down, keycode, 0, mod, RETRO_DEVICE_KEYBOARD); + input_keyboard_event(!args->KeyStatus.IsKeyReleased, keycode, 0, mod, RETRO_DEVICE_KEYBOARD); +} + +void App::OnPointer(CoreWindow^ sender, PointerEventArgs^ args) +{ + if (args->CurrentPoint->PointerDevice->PointerDeviceType == PointerDeviceType::Mouse) + { + uwp_next_input.mouse_left = args->CurrentPoint->Properties->IsLeftButtonPressed; + uwp_next_input.mouse_middle = args->CurrentPoint->Properties->IsMiddleButtonPressed; + uwp_next_input.mouse_right = args->CurrentPoint->Properties->IsRightButtonPressed; + uwp_next_input.mouse_button4 = args->CurrentPoint->Properties->IsXButton1Pressed; + uwp_next_input.mouse_button5 = args->CurrentPoint->Properties->IsXButton2Pressed; + uwp_next_input.mouse_screen_x = args->CurrentPoint->Position.X; + uwp_next_input.mouse_screen_y = args->CurrentPoint->Position.Y; + uwp_next_input.mouse_rel_x = uwp_next_input.mouse_screen_x - uwp_current_input.mouse_screen_x; + uwp_next_input.mouse_rel_y = uwp_next_input.mouse_screen_y - uwp_current_input.mouse_screen_y; + if (args->CurrentPoint->Properties->IsHorizontalMouseWheel) + { + uwp_next_input.mouse_wheel_left += args->CurrentPoint->Properties->MouseWheelDelta; + } + else + { + uwp_next_input.mouse_wheel_up += args->CurrentPoint->Properties->MouseWheelDelta; + } + } + else + { + uwp_next_input.touch_touched = args->CurrentPoint->IsInContact; + uwp_next_input.touch_screen_x = args->CurrentPoint->Position.X; + uwp_next_input.touch_screen_y = args->CurrentPoint->Position.Y; + uwp_next_input.touch_rel_x = uwp_next_input.touch_screen_x - uwp_current_input.touch_screen_x; + uwp_next_input.touch_rel_y = uwp_next_input.touch_screen_y - uwp_current_input.touch_screen_y; + } } void App::OnWindowClosed(CoreWindow^ sender, CoreWindowEventArgs^ args) @@ -476,4 +524,72 @@ extern "C" { { return (void*)CoreWindow::GetForCurrentThread(); } + + void uwp_input_next_frame(void) + { + uwp_current_input = uwp_next_input; + uwp_next_input.mouse_rel_x = 0; + uwp_next_input.mouse_rel_y = 0; + uwp_next_input.mouse_wheel_up %= WHEEL_DELTA; + uwp_next_input.mouse_wheel_left %= WHEEL_DELTA; + uwp_next_input.touch_rel_x = 0; + uwp_next_input.touch_rel_y = 0; + } + + bool uwp_keyboard_pressed(unsigned key) + { + unsigned sym = rarch_keysym_lut[(enum retro_key)key]; + return (CoreWindow::GetForCurrentThread()->GetKeyState((VirtualKey)sym) & CoreVirtualKeyStates::Down) == CoreVirtualKeyStates::Down; + } + + int16_t uwp_mouse_state(unsigned port, unsigned id, bool screen) + { + int16_t state = 0; + + switch (id) + { + case RETRO_DEVICE_ID_MOUSE_X: + return screen ? uwp_current_input.mouse_screen_x : uwp_current_input.mouse_rel_x; + case RETRO_DEVICE_ID_MOUSE_Y: + return screen ? uwp_current_input.mouse_screen_y : uwp_current_input.mouse_rel_y; + case RETRO_DEVICE_ID_MOUSE_LEFT: + return uwp_current_input.mouse_left; + case RETRO_DEVICE_ID_MOUSE_RIGHT: + return uwp_current_input.mouse_right; + case RETRO_DEVICE_ID_MOUSE_WHEELUP: + return uwp_current_input.mouse_wheel_up > WHEEL_DELTA; + case RETRO_DEVICE_ID_MOUSE_WHEELDOWN: + return uwp_current_input.mouse_wheel_up < -WHEEL_DELTA; + case RETRO_DEVICE_ID_MOUSE_HORIZ_WHEELUP: + return uwp_current_input.mouse_wheel_left > WHEEL_DELTA; + case RETRO_DEVICE_ID_MOUSE_HORIZ_WHEELDOWN: + return uwp_current_input.mouse_wheel_left < -WHEEL_DELTA; + case RETRO_DEVICE_ID_MOUSE_MIDDLE: + return uwp_current_input.mouse_middle; + case RETRO_DEVICE_ID_MOUSE_BUTTON_4: + return uwp_current_input.mouse_button4; + case RETRO_DEVICE_ID_MOUSE_BUTTON_5: + return uwp_current_input.mouse_button5; + } + + return 0; + } + + // TODO: I don't have any touch-enabled Windows devices to test if this actually works + int16_t uwp_pointer_state(unsigned idx, unsigned id, bool screen) + { + switch (id) + { + case RETRO_DEVICE_ID_POINTER_X: + return screen ? uwp_current_input.touch_screen_x : uwp_current_input.touch_rel_x; + case RETRO_DEVICE_ID_POINTER_Y: + return screen ? uwp_current_input.touch_screen_y : uwp_current_input.touch_rel_y; + case RETRO_DEVICE_ID_POINTER_PRESSED: + return uwp_current_input.touch_touched; + default: + break; + } + + return 0; + } } diff --git a/uwp/uwp_main.h b/uwp/uwp_main.h index 9d359e6e1a..623d922161 100644 --- a/uwp/uwp_main.h +++ b/uwp/uwp_main.h @@ -45,8 +45,8 @@ namespace RetroArchUWP void OnVisibilityChanged(Windows::UI::Core::CoreWindow^ sender, Windows::UI::Core::VisibilityChangedEventArgs^ args); void OnWindowClosed(Windows::UI::Core::CoreWindow^ sender, Windows::UI::Core::CoreWindowEventArgs^ args); void OnWindowActivated(Windows::UI::Core::CoreWindow^ sender, Windows::UI::Core::WindowActivatedEventArgs^ args); - void OnKeyDown(Windows::UI::Core::CoreWindow^ sender, Windows::UI::Core::KeyEventArgs^ args); - void OnKeyUp(Windows::UI::Core::CoreWindow^ sender, Windows::UI::Core::KeyEventArgs^ args); + void OnKey(Windows::UI::Core::CoreWindow^ sender, Windows::UI::Core::KeyEventArgs^ args); + void OnPointer(Windows::UI::Core::CoreWindow^ sender, Windows::UI::Core::PointerEventArgs^ args); // DisplayInformation event handlers. void OnDpiChanged(Windows::Graphics::Display::DisplayInformation^ sender, Platform::Object^ args); @@ -62,9 +62,6 @@ namespace RetroArchUWP void SetWindowResized() { m_windowResized = true; } static App^ GetInstance() { return m_instance; } - private: - void OnKey(Windows::UI::Core::CoreWindow^ sender, Windows::UI::Core::KeyEventArgs^ args, bool down); - private: bool m_initialized; bool m_windowClosed; From 4fb06703b3b14e633f932ae41fe3a3875572e618 Mon Sep 17 00:00:00 2001 From: krzys-h Date: Fri, 28 Dec 2018 14:24:31 +0100 Subject: [PATCH 5/5] Port d3d12 driver for UWP --- configuration.c | 3 +- gfx/common/d3d12_common.c | 37 ++++++++++++++++++- gfx/common/d3d12_common.h | 6 +++ gfx/common/dxgi_common.h | 23 ++++++++++++ gfx/drivers/d3d12.c | 11 ++++-- gfx/video_driver.c | 8 ++-- .../RetroArch-msvc2017-UWP.vcxproj | 16 ++++---- 7 files changed, 85 insertions(+), 19 deletions(-) diff --git a/configuration.c b/configuration.c index 880caedd27..aef1d7db2a 100644 --- a/configuration.c +++ b/configuration.c @@ -324,7 +324,8 @@ static enum video_driver_enum VIDEO_DEFAULT_DRIVER = VIDEO_WII; static enum video_driver_enum VIDEO_DEFAULT_DRIVER = VIDEO_WIIU; #elif defined(XENON) static enum video_driver_enum VIDEO_DEFAULT_DRIVER = VIDEO_XENON360; -#elif defined(HAVE_D3D12) +#elif defined(HAVE_D3D12) && false +/* FIXME: DX12 performance on Xbox is horrible for some reason, so use d3d11 as default */ static enum video_driver_enum VIDEO_DEFAULT_DRIVER = VIDEO_D3D12; #elif defined(HAVE_D3D11) static enum video_driver_enum VIDEO_DEFAULT_DRIVER = VIDEO_D3D11; diff --git a/gfx/common/d3d12_common.c b/gfx/common/d3d12_common.c index a405dc5e46..0f060231e0 100644 --- a/gfx/common/d3d12_common.c +++ b/gfx/common/d3d12_common.c @@ -159,15 +159,24 @@ bool d3d12_init_base(d3d12_video_t* d3d12) D3D12EnableDebugLayer(d3d12->debugController); #endif +#ifdef __WINRT__ + DXGICreateFactory2(&d3d12->factory); +#else DXGICreateFactory(&d3d12->factory); +#endif { int i = 0; while (true) { +#ifdef __WINRT__ + if (FAILED(DXGIEnumAdapters2(d3d12->factory, i++, &d3d12->adapter))) + return false; +#else if (FAILED(DXGIEnumAdapters(d3d12->factory, i++, &d3d12->adapter))) return false; +#endif if (SUCCEEDED(D3D12CreateDevice_(d3d12->adapter, D3D_FEATURE_LEVEL_11_0, &d3d12->device))) break; @@ -206,18 +215,33 @@ bool d3d12_init_queue(d3d12_video_t* d3d12) return true; } +#ifdef __WINRT__ +bool d3d12_init_swapchain(d3d12_video_t* d3d12, + int width, int height, void* corewindow) +#else bool d3d12_init_swapchain(d3d12_video_t* d3d12, int width, int height, HWND hwnd) +#endif { unsigned i; +#ifdef __WINRT__ + DXGI_SWAP_CHAIN_DESC1 desc; + memset(&desc, 0, sizeof(DXGI_SWAP_CHAIN_DESC1)); +#else DXGI_SWAP_CHAIN_DESC desc; - memset(&desc, 0, sizeof(DXGI_SWAP_CHAIN_DESC)); +#endif desc.BufferCount = countof(d3d12->chain.renderTargets); +#ifdef __WINRT__ + desc.Width = width; + desc.Height = height; + desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; +#else desc.BufferDesc.Width = width; desc.BufferDesc.Height = height; desc.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; +#endif desc.SampleDesc.Count = 1; #if 0 desc.BufferDesc.RefreshRate.Numerator = 60; @@ -225,16 +249,25 @@ bool d3d12_init_swapchain(d3d12_video_t* d3d12, desc.SampleDesc.Quality = 0; #endif desc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; +#ifdef HAVE_WINDOW desc.OutputWindow = hwnd; desc.Windowed = TRUE; +#endif #if 0 desc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL; #else desc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_DISCARD; #endif - DXGICreateSwapChain(d3d12->factory, d3d12->queue.handle, &desc, &d3d12->chain.handle); +#ifdef __WINRT__ + DXGICreateSwapChainForCoreWindow(d3d12->factory, d3d12->queue.handle, corewindow, &desc, NULL, &d3d12->chain.handle); +#else + DXGICreateSwapChain(d3d12->factory, d3d12->queue.handle, &desc, &d3d12->chain.handle); +#endif + +#ifdef HAVE_WINDOW DXGIMakeWindowAssociation(d3d12->factory, hwnd, DXGI_MWA_NO_ALT_ENTER); +#endif d3d12->chain.frame_index = DXGIGetCurrentBackBufferIndex(d3d12->chain.handle); diff --git a/gfx/common/d3d12_common.h b/gfx/common/d3d12_common.h index 8bb2bca7d6..08b13bf2d8 100644 --- a/gfx/common/d3d12_common.h +++ b/gfx/common/d3d12_common.h @@ -1001,6 +1001,7 @@ static INLINE void D3D12ClearStoredMessages(D3D12InfoQueue info_queue) { info_queue->lpVtbl->ClearStoredMessages(info_queue); } +#ifndef __WINRT__ static INLINE HRESULT D3D12GetMessageA( D3D12InfoQueue info_queue, UINT64 message_index, @@ -1009,6 +1010,7 @@ static INLINE HRESULT D3D12GetMessageA( { return info_queue->lpVtbl->GetMessageA(info_queue, message_index, message, message_byte_length); } +#endif static INLINE UINT64 D3D12GetNumMessagesAllowedByStorageFilter(D3D12InfoQueue info_queue) { return info_queue->lpVtbl->GetNumMessagesAllowedByStorageFilter(info_queue); @@ -1341,7 +1343,11 @@ static_assert( typedef struct { unsigned cur_mon_id; +#ifdef __WINRT__ + DXGIFactory2 factory; +#else DXGIFactory factory; +#endif DXGIAdapter adapter; D3D12Device device; diff --git a/gfx/common/dxgi_common.h b/gfx/common/dxgi_common.h index 0e5e15e88f..485142b099 100644 --- a/gfx/common/dxgi_common.h +++ b/gfx/common/dxgi_common.h @@ -270,6 +270,9 @@ typedef IDXGISurface1* DXGISurface; typedef IDXGIOutput* DXGIOutput; typedef IDXGIDevice* DXGIDevice; typedef IDXGIFactory1* DXGIFactory; +#ifdef __WINRT__ +typedef IDXGIFactory2* DXGIFactory2; +#endif typedef IDXGIAdapter1* DXGIAdapter; typedef IDXGIDisplayControl* DXGIDisplayControl; typedef IDXGIOutputDuplication* DXGIOutputDuplication; @@ -414,6 +417,14 @@ static INLINE HRESULT DXGICreateSwapChain( return factory->lpVtbl->CreateSwapChain( factory, (IUnknown*)device, desc, (IDXGISwapChain**)swap_chain); } +#ifdef __WINRT__ +static INLINE HRESULT DXGICreateSwapChainForCoreWindow( + DXGIFactory2 factory, void* device, void* corewindow, DXGI_SWAP_CHAIN_DESC1* desc, DXGIOutput restrict_to, DXGISwapChain* swap_chain) +{ + return factory->lpVtbl->CreateSwapChainForCoreWindow( + factory, (IUnknown*)device, (IUnknown*)corewindow, desc, restrict_to, (IDXGISwapChain1**)swap_chain); +} +#endif static INLINE HRESULT DXGICreateSoftwareAdapter(DXGIFactory factory, HMODULE module, DXGIAdapter* adapter) { @@ -423,6 +434,12 @@ static INLINE HRESULT DXGIEnumAdapters(DXGIFactory factory, UINT id, DXGIAdapter { return factory->lpVtbl->EnumAdapters1(factory, id, adapter); } +#ifdef __WINRT__ +static INLINE HRESULT DXGIEnumAdapters2(DXGIFactory2 factory, UINT id, DXGIAdapter* adapter) +{ + return factory->lpVtbl->EnumAdapters1(factory, id, adapter); +} +#endif static INLINE BOOL DXGIIsCurrent(DXGIFactory factory) { return factory->lpVtbl->IsCurrent(factory); @@ -760,6 +777,12 @@ static INLINE HRESULT DXGICreateFactory(DXGIFactory* factory) { return CreateDXGIFactory1(uuidof(IDXGIFactory1), (void**)factory); } +#ifdef __WINRT__ +static INLINE HRESULT DXGICreateFactory2(DXGIFactory2* factory) +{ + return CreateDXGIFactory1(uuidof(IDXGIFactory2), (void**)factory); +} +#endif /* internal */ diff --git a/gfx/drivers/d3d12.c b/gfx/drivers/d3d12.c index c89797c5db..6698d76897 100644 --- a/gfx/drivers/d3d12.c +++ b/gfx/drivers/d3d12.c @@ -35,10 +35,6 @@ #include "wiiu/wiiu_dbg.h" -#ifdef __WINRT__ -#error "TODO (krzys_h): DX12 could be doable on UWP?" -#endif - static void d3d12_gfx_sync(d3d12_video_t* d3d12) { if (D3D12GetCompletedValue(d3d12->queue.fence) < d3d12->queue.fenceValue) @@ -881,9 +877,11 @@ static void d3d12_gfx_free(void* data) static void* d3d12_gfx_init(const video_info_t* video, const input_driver_t** input, void** input_data) { +#ifdef HAVE_MONITOR MONITORINFOEX current_mon; HMONITOR hm_to_use; WNDCLASSEX wndclass = { 0 }; +#endif settings_t* settings = config_get_ptr(); d3d12_video_t* d3d12 = (d3d12_video_t*)calloc(1, sizeof(*d3d12)); @@ -931,8 +929,13 @@ d3d12_gfx_init(const video_info_t* video, const input_driver_t** input, void** i if (!d3d12_init_queue(d3d12)) goto error; +#ifdef __WINRT__ + if (!d3d12_init_swapchain(d3d12, d3d12->vp.full_width, d3d12->vp.full_height, uwp_get_corewindow())) + goto error; +#else if (!d3d12_init_swapchain(d3d12, d3d12->vp.full_width, d3d12->vp.full_height, main_window.hwnd)) goto error; +#endif d3d12_init_samplers(d3d12); d3d12_set_filtering(d3d12, 0, video->smooth); diff --git a/gfx/video_driver.c b/gfx/video_driver.c index b00014fb0b..14f87744d5 100644 --- a/gfx/video_driver.c +++ b/gfx/video_driver.c @@ -274,14 +274,14 @@ static const video_driver_t *video_drivers[] = { #ifdef XENON &video_xenon360, #endif -#if defined(HAVE_D3D10) - &video_d3d10, +#if defined(HAVE_D3D12) + &video_d3d12, #endif #if defined(HAVE_D3D11) &video_d3d11, #endif -#if defined(HAVE_D3D12) - &video_d3d12, +#if defined(HAVE_D3D10) + &video_d3d10, #endif #if defined(HAVE_D3D9) &video_d3d9, diff --git a/pkg/msvc/msvc-2017-UWP/RetroArch-msvc2017-UWP.vcxproj b/pkg/msvc/msvc-2017-UWP/RetroArch-msvc2017-UWP.vcxproj index b6c0469a17..cfb7f5a5d0 100644 --- a/pkg/msvc/msvc-2017-UWP/RetroArch-msvc2017-UWP.vcxproj +++ b/pkg/msvc/msvc-2017-UWP/RetroArch-msvc2017-UWP.vcxproj @@ -142,7 +142,7 @@ $(MSBuildProjectDirectory);$(MSBuildProjectDirectory)\..\..\..\;$(MSBuildProjectDirectory)\..\..\..\deps\rcheevos\include;$(MSBuildProjectDirectory)\..\..\..\deps\zlib;$(MSBuildProjectDirectory)\..\..\..\libretro-common\include;$(MSBuildProjectDirectory)\..\..\..\deps;$(MSBuildProjectDirectory)\..\..\..\deps\glslang;$(MSBuildProjectDirectory)\..\..\..\deps\SPIRV-Cross;$(MSBuildProjectDirectory)\..\..\..\deps\stb;$(MSBuildProjectDirectory)\..\..\..\gfx\include;%(AdditionalIncludeDirectories) /bigobj %(AdditionalOptions) 4453;28204 - WIN32;HAVE_MAIN;HAVE_DYNAMIC;HAVE_XAUDIO2;RARCH_INTERNAL;HAVE_CC_RESAMPLER;HAVE_SLANG;HAVE_SPIRV_CROSS;HAVE_UPDATE_ASSETS;HAVE_D3D;HAVE_D3D11;ENABLE_HLSL;RC_DISABLE_LUA;HAVE_CHEEVOS;HAVE_RUNAHEAD;HAVE_GRIFFIN;HAVE_LANGEXTRA;HAVE_FBO;HAVE_ZLIB;HAVE_RPNG;HAVE_RJPEG;HAVE_RBMP;HAVE_RTGA;HAVE_IMAGEVIEWER;HAVE_XMB;HAVE_SHADERPIPELINE;WANT_ZLIB;_DEBUG;_WINDOWS;%(PreprocessorDefinitions);HAVE_XINPUT;HAVE_XINPUT2;HAVE_XAUDIO;HAVE_DIRECTX;HAVE_NETWORKING;HAVE_NETWORK_CMD;HAVE_NETPLAYDISCOVERY;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;__SSE__;__i686__;HAVE_OVERLAY;HAVE_RGUI;HAVE_MENU;HAVE_MATERIALUI;HAVE_LIBRETRODB;HAVE_STB_FONT;HAVE_STATIC_DUMMY;HAVE_STATIC_VIDEO_FILTERS;HAVE_STATIC_AUDIO_FILTERS + WIN32;HAVE_MAIN;HAVE_DYNAMIC;HAVE_XAUDIO2;RARCH_INTERNAL;HAVE_CC_RESAMPLER;HAVE_SLANG;HAVE_SPIRV_CROSS;HAVE_UPDATE_ASSETS;HAVE_D3D;HAVE_D3D11;HAVE_D3D12;ENABLE_HLSL;RC_DISABLE_LUA;HAVE_CHEEVOS;HAVE_RUNAHEAD;HAVE_GRIFFIN;HAVE_LANGEXTRA;HAVE_FBO;HAVE_ZLIB;HAVE_RPNG;HAVE_RJPEG;HAVE_RBMP;HAVE_RTGA;HAVE_IMAGEVIEWER;HAVE_XMB;HAVE_SHADERPIPELINE;WANT_ZLIB;_DEBUG;_WINDOWS;%(PreprocessorDefinitions);HAVE_XINPUT;HAVE_XINPUT2;HAVE_XAUDIO;HAVE_DIRECTX;HAVE_NETWORKING;HAVE_NETWORK_CMD;HAVE_NETPLAYDISCOVERY;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;__SSE__;__i686__;HAVE_OVERLAY;HAVE_RGUI;HAVE_MENU;HAVE_MATERIALUI;HAVE_LIBRETRODB;HAVE_STB_FONT;HAVE_STATIC_DUMMY;HAVE_STATIC_VIDEO_FILTERS;HAVE_STATIC_AUDIO_FILTERS @@ -157,7 +157,7 @@ $(MSBuildProjectDirectory);$(MSBuildProjectDirectory)\..\..\..\;$(MSBuildProjectDirectory)\..\..\..\deps\rcheevos\include;$(MSBuildProjectDirectory)\..\..\..\deps\zlib;$(MSBuildProjectDirectory)\..\..\..\libretro-common\include;$(MSBuildProjectDirectory)\..\..\..\deps;$(MSBuildProjectDirectory)\..\..\..\deps\glslang;$(MSBuildProjectDirectory)\..\..\..\deps\SPIRV-Cross;$(MSBuildProjectDirectory)\..\..\..\deps\stb;$(MSBuildProjectDirectory)\..\..\..\gfx\include;%(AdditionalIncludeDirectories) /bigobj %(AdditionalOptions) 4453;28204 - WIN32;HAVE_MAIN;HAVE_DYNAMIC;HAVE_XAUDIO2;RARCH_INTERNAL;HAVE_CC_RESAMPLER;HAVE_SLANG;HAVE_SPIRV_CROSS;HAVE_UPDATE_ASSETS;HAVE_D3D;HAVE_D3D11;ENABLE_HLSL;RC_DISABLE_LUA;HAVE_CHEEVOS;HAVE_RUNAHEAD;HAVE_GRIFFIN;HAVE_LANGEXTRA;HAVE_FBO;HAVE_ZLIB;HAVE_XMB;HAVE_SHADERPIPELINE;WANT_ZLIB;HAVE_RPNG;HAVE_RJPEG;HAVE_RBMP;HAVE_RTGA;HAVE_IMAGEVIEWER;NDEBUG;_WINDOWS;%(PreprocessorDefinitions);HAVE_XINPUT;HAVE_XINPUT2;HAVE_XAUDIO;HAVE_DIRECTX;HAVE_NETWORKING;HAVE_NETWORK_CMD;HAVE_NETPLAYDISCOVERY;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;__SSE__;__i686__;HAVE_OVERLAY;HAVE_MENU;HAVE_RGUI;HAVE_MATERIALUI;HAVE_LIBRETRODB;HAVE_STB_FONT;HAVE_STATIC_DUMMY;HAVE_STATIC_VIDEO_FILTERS;HAVE_STATIC_AUDIO_FILTERS + WIN32;HAVE_MAIN;HAVE_DYNAMIC;HAVE_XAUDIO2;RARCH_INTERNAL;HAVE_CC_RESAMPLER;HAVE_SLANG;HAVE_SPIRV_CROSS;HAVE_UPDATE_ASSETS;HAVE_D3D;HAVE_D3D11;HAVE_D3D12;ENABLE_HLSL;RC_DISABLE_LUA;HAVE_CHEEVOS;HAVE_RUNAHEAD;HAVE_GRIFFIN;HAVE_LANGEXTRA;HAVE_FBO;HAVE_ZLIB;HAVE_XMB;HAVE_SHADERPIPELINE;WANT_ZLIB;HAVE_RPNG;HAVE_RJPEG;HAVE_RBMP;HAVE_RTGA;HAVE_IMAGEVIEWER;NDEBUG;_WINDOWS;%(PreprocessorDefinitions);HAVE_XINPUT;HAVE_XINPUT2;HAVE_XAUDIO;HAVE_DIRECTX;HAVE_NETWORKING;HAVE_NETWORK_CMD;HAVE_NETPLAYDISCOVERY;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;__SSE__;__i686__;HAVE_OVERLAY;HAVE_MENU;HAVE_RGUI;HAVE_MATERIALUI;HAVE_LIBRETRODB;HAVE_STB_FONT;HAVE_STATIC_DUMMY;HAVE_STATIC_VIDEO_FILTERS;HAVE_STATIC_AUDIO_FILTERS @@ -172,7 +172,7 @@ $(MSBuildProjectDirectory);$(MSBuildProjectDirectory)\..\..\..\;$(MSBuildProjectDirectory)\..\..\..\deps\rcheevos\include;$(MSBuildProjectDirectory)\..\..\..\deps\zlib;$(MSBuildProjectDirectory)\..\..\..\libretro-common\include;$(MSBuildProjectDirectory)\..\..\..\deps;$(MSBuildProjectDirectory)\..\..\..\deps\glslang;$(MSBuildProjectDirectory)\..\..\..\deps\SPIRV-Cross;$(MSBuildProjectDirectory)\..\..\..\deps\stb;$(MSBuildProjectDirectory)\..\..\..\gfx\include;%(AdditionalIncludeDirectories) /bigobj %(AdditionalOptions) 4453;28204 - WIN32;HAVE_MAIN;HAVE_DYNAMIC;HAVE_XAUDIO2;RARCH_INTERNAL;HAVE_CC_RESAMPLER;HAVE_SLANG;HAVE_SPIRV_CROSS;HAVE_UPDATE_ASSETS;HAVE_D3D;HAVE_D3D11;ENABLE_HLSL;RC_DISABLE_LUA;HAVE_CHEEVOS;HAVE_RUNAHEAD;HAVE_GRIFFIN;HAVE_LANGEXTRA;HAVE_FBO;HAVE_ZLIB;HAVE_RPNG;HAVE_RJPEG;HAVE_RBMP;HAVE_RTGA;HAVE_IMAGEVIEWER;HAVE_XMB;HAVE_SHADERPIPELINE;WANT_ZLIB;_DEBUG;_WINDOWS;%(PreprocessorDefinitions);HAVE_XINPUT;HAVE_XINPUT2;HAVE_XAUDIO;HAVE_DIRECTX;HAVE_NETWORKING;HAVE_NETWORK_CMD;HAVE_NETPLAYDISCOVERY;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;__SSE__;__i686__;HAVE_OVERLAY;HAVE_RGUI;HAVE_MENU;HAVE_MATERIALUI;HAVE_LIBRETRODB;HAVE_STB_FONT;HAVE_STATIC_DUMMY;HAVE_STATIC_VIDEO_FILTERS;HAVE_STATIC_AUDIO_FILTERS + WIN32;HAVE_MAIN;HAVE_DYNAMIC;HAVE_XAUDIO2;RARCH_INTERNAL;HAVE_CC_RESAMPLER;HAVE_SLANG;HAVE_SPIRV_CROSS;HAVE_UPDATE_ASSETS;HAVE_D3D;HAVE_D3D11;HAVE_D3D12;ENABLE_HLSL;RC_DISABLE_LUA;HAVE_CHEEVOS;HAVE_RUNAHEAD;HAVE_GRIFFIN;HAVE_LANGEXTRA;HAVE_FBO;HAVE_ZLIB;HAVE_RPNG;HAVE_RJPEG;HAVE_RBMP;HAVE_RTGA;HAVE_IMAGEVIEWER;HAVE_XMB;HAVE_SHADERPIPELINE;WANT_ZLIB;_DEBUG;_WINDOWS;%(PreprocessorDefinitions);HAVE_XINPUT;HAVE_XINPUT2;HAVE_XAUDIO;HAVE_DIRECTX;HAVE_NETWORKING;HAVE_NETWORK_CMD;HAVE_NETPLAYDISCOVERY;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;__SSE__;__i686__;HAVE_OVERLAY;HAVE_RGUI;HAVE_MENU;HAVE_MATERIALUI;HAVE_LIBRETRODB;HAVE_STB_FONT;HAVE_STATIC_DUMMY;HAVE_STATIC_VIDEO_FILTERS;HAVE_STATIC_AUDIO_FILTERS @@ -187,7 +187,7 @@ $(MSBuildProjectDirectory);$(MSBuildProjectDirectory)\..\..\..\;$(MSBuildProjectDirectory)\..\..\..\deps\rcheevos\include;$(MSBuildProjectDirectory)\..\..\..\deps\zlib;$(MSBuildProjectDirectory)\..\..\..\libretro-common\include;$(MSBuildProjectDirectory)\..\..\..\deps;$(MSBuildProjectDirectory)\..\..\..\deps\glslang;$(MSBuildProjectDirectory)\..\..\..\deps\SPIRV-Cross;$(MSBuildProjectDirectory)\..\..\..\deps\stb;$(MSBuildProjectDirectory)\..\..\..\gfx\include;%(AdditionalIncludeDirectories) /bigobj %(AdditionalOptions) 4453;28204 - WIN32;HAVE_MAIN;HAVE_DYNAMIC;HAVE_XAUDIO2;RARCH_INTERNAL;HAVE_CC_RESAMPLER;HAVE_SLANG;HAVE_SPIRV_CROSS;HAVE_UPDATE_ASSETS;HAVE_D3D;HAVE_D3D11;ENABLE_HLSL;RC_DISABLE_LUA;HAVE_CHEEVOS;HAVE_RUNAHEAD;HAVE_GRIFFIN;HAVE_LANGEXTRA;HAVE_FBO;HAVE_ZLIB;HAVE_XMB;HAVE_SHADERPIPELINE;WANT_ZLIB;HAVE_RPNG;HAVE_RJPEG;HAVE_RBMP;HAVE_RTGA;HAVE_IMAGEVIEWER;NDEBUG;_WINDOWS;%(PreprocessorDefinitions);HAVE_XINPUT;HAVE_XINPUT2;HAVE_XAUDIO;HAVE_DIRECTX;HAVE_NETWORKING;HAVE_NETWORK_CMD;HAVE_NETPLAYDISCOVERY;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;__SSE__;__i686__;HAVE_OVERLAY;HAVE_MENU;HAVE_RGUI;HAVE_MATERIALUI;HAVE_LIBRETRODB;HAVE_STB_FONT;HAVE_STATIC_DUMMY;HAVE_STATIC_VIDEO_FILTERS;HAVE_STATIC_AUDIO_FILTERS + WIN32;HAVE_MAIN;HAVE_DYNAMIC;HAVE_XAUDIO2;RARCH_INTERNAL;HAVE_CC_RESAMPLER;HAVE_SLANG;HAVE_SPIRV_CROSS;HAVE_UPDATE_ASSETS;HAVE_D3D;HAVE_D3D11;HAVE_D3D12;ENABLE_HLSL;RC_DISABLE_LUA;HAVE_CHEEVOS;HAVE_RUNAHEAD;HAVE_GRIFFIN;HAVE_LANGEXTRA;HAVE_FBO;HAVE_ZLIB;HAVE_XMB;HAVE_SHADERPIPELINE;WANT_ZLIB;HAVE_RPNG;HAVE_RJPEG;HAVE_RBMP;HAVE_RTGA;HAVE_IMAGEVIEWER;NDEBUG;_WINDOWS;%(PreprocessorDefinitions);HAVE_XINPUT;HAVE_XINPUT2;HAVE_XAUDIO;HAVE_DIRECTX;HAVE_NETWORKING;HAVE_NETWORK_CMD;HAVE_NETPLAYDISCOVERY;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;__SSE__;__i686__;HAVE_OVERLAY;HAVE_MENU;HAVE_RGUI;HAVE_MATERIALUI;HAVE_LIBRETRODB;HAVE_STB_FONT;HAVE_STATIC_DUMMY;HAVE_STATIC_VIDEO_FILTERS;HAVE_STATIC_AUDIO_FILTERS @@ -202,7 +202,7 @@ $(MSBuildProjectDirectory);$(MSBuildProjectDirectory)\..\..\..\;$(MSBuildProjectDirectory)\..\..\..\deps\rcheevos\include;$(MSBuildProjectDirectory)\..\..\..\deps\zlib;$(MSBuildProjectDirectory)\..\..\..\libretro-common\include;$(MSBuildProjectDirectory)\..\..\..\deps;$(MSBuildProjectDirectory)\..\..\..\deps\glslang;$(MSBuildProjectDirectory)\..\..\..\deps\SPIRV-Cross;$(MSBuildProjectDirectory)\..\..\..\deps\stb;$(MSBuildProjectDirectory)\..\..\..\gfx\include;%(AdditionalIncludeDirectories) /bigobj %(AdditionalOptions) 4453;28204 - WIN32;HAVE_MAIN;HAVE_DYNAMIC;HAVE_XAUDIO2;RARCH_INTERNAL;HAVE_CC_RESAMPLER;HAVE_SLANG;HAVE_SPIRV_CROSS;HAVE_UPDATE_ASSETS;HAVE_D3D;HAVE_D3D11;ENABLE_HLSL;RC_DISABLE_LUA;HAVE_CHEEVOS;HAVE_RUNAHEAD;HAVE_GRIFFIN;HAVE_LANGEXTRA;HAVE_FBO;HAVE_ZLIB;HAVE_RPNG;HAVE_RJPEG;HAVE_RBMP;HAVE_RTGA;HAVE_IMAGEVIEWER;HAVE_XMB;HAVE_SHADERPIPELINE;WANT_ZLIB;_DEBUG;_WINDOWS;%(PreprocessorDefinitions);HAVE_XINPUT;HAVE_XINPUT2;HAVE_XAUDIO;HAVE_DIRECTX;HAVE_NETWORKING;HAVE_NETWORK_CMD;HAVE_NETPLAYDISCOVERY;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;__SSE__;__i686__;HAVE_OVERLAY;HAVE_RGUI;HAVE_MENU;HAVE_MATERIALUI;HAVE_LIBRETRODB;HAVE_STB_FONT;HAVE_STATIC_DUMMY;HAVE_STATIC_VIDEO_FILTERS;HAVE_STATIC_AUDIO_FILTERS + WIN32;HAVE_MAIN;HAVE_DYNAMIC;HAVE_XAUDIO2;RARCH_INTERNAL;HAVE_CC_RESAMPLER;HAVE_SLANG;HAVE_SPIRV_CROSS;HAVE_UPDATE_ASSETS;HAVE_D3D;HAVE_D3D11;HAVE_D3D12;ENABLE_HLSL;RC_DISABLE_LUA;HAVE_CHEEVOS;HAVE_RUNAHEAD;HAVE_GRIFFIN;HAVE_LANGEXTRA;HAVE_FBO;HAVE_ZLIB;HAVE_RPNG;HAVE_RJPEG;HAVE_RBMP;HAVE_RTGA;HAVE_IMAGEVIEWER;HAVE_XMB;HAVE_SHADERPIPELINE;WANT_ZLIB;_DEBUG;_WINDOWS;%(PreprocessorDefinitions);HAVE_XINPUT;HAVE_XINPUT2;HAVE_XAUDIO;HAVE_DIRECTX;HAVE_NETWORKING;HAVE_NETWORK_CMD;HAVE_NETPLAYDISCOVERY;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;__SSE__;__i686__;HAVE_OVERLAY;HAVE_RGUI;HAVE_MENU;HAVE_MATERIALUI;HAVE_LIBRETRODB;HAVE_STB_FONT;HAVE_STATIC_DUMMY;HAVE_STATIC_VIDEO_FILTERS;HAVE_STATIC_AUDIO_FILTERS ProgramDatabase @@ -218,7 +218,7 @@ $(MSBuildProjectDirectory);$(MSBuildProjectDirectory)\..\..\..\;$(MSBuildProjectDirectory)\..\..\..\deps\rcheevos\include;$(MSBuildProjectDirectory)\..\..\..\deps\zlib;$(MSBuildProjectDirectory)\..\..\..\libretro-common\include;$(MSBuildProjectDirectory)\..\..\..\deps;$(MSBuildProjectDirectory)\..\..\..\deps\glslang;$(MSBuildProjectDirectory)\..\..\..\deps\SPIRV-Cross;$(MSBuildProjectDirectory)\..\..\..\deps\stb;$(MSBuildProjectDirectory)\..\..\..\gfx\include;%(AdditionalIncludeDirectories) /bigobj %(AdditionalOptions) 4453;28204 - WIN32;HAVE_MAIN;HAVE_DYNAMIC;HAVE_XAUDIO2;RARCH_INTERNAL;HAVE_CC_RESAMPLER;HAVE_SLANG;HAVE_SPIRV_CROSS;HAVE_UPDATE_ASSETS;HAVE_D3D;HAVE_D3D11;ENABLE_HLSL;RC_DISABLE_LUA;HAVE_CHEEVOS;HAVE_RUNAHEAD;HAVE_GRIFFIN;HAVE_LANGEXTRA;HAVE_FBO;HAVE_ZLIB;HAVE_XMB;HAVE_SHADERPIPELINE;WANT_ZLIB;HAVE_RPNG;HAVE_RJPEG;HAVE_RBMP;HAVE_RTGA;HAVE_IMAGEVIEWER;NDEBUG;_WINDOWS;%(PreprocessorDefinitions);HAVE_XINPUT;HAVE_XINPUT2;HAVE_XAUDIO;HAVE_DIRECTX;HAVE_NETWORKING;HAVE_NETWORK_CMD;HAVE_NETPLAYDISCOVERY;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;__SSE__;__i686__;HAVE_OVERLAY;HAVE_MENU;HAVE_RGUI;HAVE_MATERIALUI;HAVE_LIBRETRODB;HAVE_STB_FONT;HAVE_STATIC_DUMMY;HAVE_STATIC_VIDEO_FILTERS;HAVE_STATIC_AUDIO_FILTERS + WIN32;HAVE_MAIN;HAVE_DYNAMIC;HAVE_XAUDIO2;RARCH_INTERNAL;HAVE_CC_RESAMPLER;HAVE_SLANG;HAVE_SPIRV_CROSS;HAVE_UPDATE_ASSETS;HAVE_D3D;HAVE_D3D11;HAVE_D3D12;ENABLE_HLSL;RC_DISABLE_LUA;HAVE_CHEEVOS;HAVE_RUNAHEAD;HAVE_GRIFFIN;HAVE_LANGEXTRA;HAVE_FBO;HAVE_ZLIB;HAVE_XMB;HAVE_SHADERPIPELINE;WANT_ZLIB;HAVE_RPNG;HAVE_RJPEG;HAVE_RBMP;HAVE_RTGA;HAVE_IMAGEVIEWER;NDEBUG;_WINDOWS;%(PreprocessorDefinitions);HAVE_XINPUT;HAVE_XINPUT2;HAVE_XAUDIO;HAVE_DIRECTX;HAVE_NETWORKING;HAVE_NETWORK_CMD;HAVE_NETPLAYDISCOVERY;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;__SSE__;__i686__;HAVE_OVERLAY;HAVE_MENU;HAVE_RGUI;HAVE_MATERIALUI;HAVE_LIBRETRODB;HAVE_STB_FONT;HAVE_STATIC_DUMMY;HAVE_STATIC_VIDEO_FILTERS;HAVE_STATIC_AUDIO_FILTERS @@ -233,7 +233,7 @@ $(MSBuildProjectDirectory);$(MSBuildProjectDirectory)\..\..\..\;$(MSBuildProjectDirectory)\..\..\..\deps\rcheevos\include;$(MSBuildProjectDirectory)\..\..\..\deps\zlib;$(MSBuildProjectDirectory)\..\..\..\libretro-common\include;$(MSBuildProjectDirectory)\..\..\..\deps;$(MSBuildProjectDirectory)\..\..\..\deps\glslang;$(MSBuildProjectDirectory)\..\..\..\deps\SPIRV-Cross;$(MSBuildProjectDirectory)\..\..\..\deps\stb;$(MSBuildProjectDirectory)\..\..\..\gfx\include;%(AdditionalIncludeDirectories) /bigobj %(AdditionalOptions) 4453;28204 - WIN32;HAVE_MAIN;HAVE_DYNAMIC;HAVE_XAUDIO2;RARCH_INTERNAL;HAVE_CC_RESAMPLER;HAVE_SLANG;HAVE_SPIRV_CROSS;HAVE_UPDATE_ASSETS;HAVE_D3D;HAVE_D3D11;ENABLE_HLSL;RC_DISABLE_LUA;HAVE_CHEEVOS;HAVE_RUNAHEAD;HAVE_GRIFFIN;HAVE_LANGEXTRA;HAVE_FBO;HAVE_ZLIB;HAVE_RPNG;HAVE_RJPEG;HAVE_RBMP;HAVE_RTGA;HAVE_IMAGEVIEWER;HAVE_XMB;HAVE_SHADERPIPELINE;WANT_ZLIB;_DEBUG;_WINDOWS;%(PreprocessorDefinitions);HAVE_XINPUT;HAVE_XINPUT2;HAVE_XAUDIO;HAVE_DIRECTX;HAVE_NETWORKING;HAVE_NETWORK_CMD;HAVE_NETPLAYDISCOVERY;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;__SSE__;__i686__;HAVE_OVERLAY;HAVE_RGUI;HAVE_MENU;HAVE_MATERIALUI;HAVE_LIBRETRODB;HAVE_STB_FONT;HAVE_STATIC_DUMMY;HAVE_STATIC_VIDEO_FILTERS;HAVE_STATIC_AUDIO_FILTERS + WIN32;HAVE_MAIN;HAVE_DYNAMIC;HAVE_XAUDIO2;RARCH_INTERNAL;HAVE_CC_RESAMPLER;HAVE_SLANG;HAVE_SPIRV_CROSS;HAVE_UPDATE_ASSETS;HAVE_D3D;HAVE_D3D11;HAVE_D3D12;ENABLE_HLSL;RC_DISABLE_LUA;HAVE_CHEEVOS;HAVE_RUNAHEAD;HAVE_GRIFFIN;HAVE_LANGEXTRA;HAVE_FBO;HAVE_ZLIB;HAVE_RPNG;HAVE_RJPEG;HAVE_RBMP;HAVE_RTGA;HAVE_IMAGEVIEWER;HAVE_XMB;HAVE_SHADERPIPELINE;WANT_ZLIB;_DEBUG;_WINDOWS;%(PreprocessorDefinitions);HAVE_XINPUT;HAVE_XINPUT2;HAVE_XAUDIO;HAVE_DIRECTX;HAVE_NETWORKING;HAVE_NETWORK_CMD;HAVE_NETPLAYDISCOVERY;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;__SSE__;__i686__;HAVE_OVERLAY;HAVE_RGUI;HAVE_MENU;HAVE_MATERIALUI;HAVE_LIBRETRODB;HAVE_STB_FONT;HAVE_STATIC_DUMMY;HAVE_STATIC_VIDEO_FILTERS;HAVE_STATIC_AUDIO_FILTERS ProgramDatabase @@ -249,7 +249,7 @@ $(MSBuildProjectDirectory);$(MSBuildProjectDirectory)\..\..\..\;$(MSBuildProjectDirectory)\..\..\..\deps\rcheevos\include;$(MSBuildProjectDirectory)\..\..\..\deps\zlib;$(MSBuildProjectDirectory)\..\..\..\libretro-common\include;$(MSBuildProjectDirectory)\..\..\..\deps;$(MSBuildProjectDirectory)\..\..\..\deps\glslang;$(MSBuildProjectDirectory)\..\..\..\deps\SPIRV-Cross;$(MSBuildProjectDirectory)\..\..\..\deps\stb;$(MSBuildProjectDirectory)\..\..\..\gfx\include;%(AdditionalIncludeDirectories) /bigobj %(AdditionalOptions) 4453;28204 - WIN32;HAVE_MAIN;HAVE_DYNAMIC;HAVE_XAUDIO2;RARCH_INTERNAL;HAVE_CC_RESAMPLER;HAVE_SLANG;HAVE_SPIRV_CROSS;HAVE_UPDATE_ASSETS;HAVE_D3D;HAVE_D3D11;ENABLE_HLSL;RC_DISABLE_LUA;HAVE_CHEEVOS;HAVE_RUNAHEAD;HAVE_GRIFFIN;HAVE_LANGEXTRA;HAVE_FBO;HAVE_ZLIB;HAVE_XMB;HAVE_SHADERPIPELINE;WANT_ZLIB;HAVE_RPNG;HAVE_RJPEG;HAVE_RBMP;HAVE_RTGA;HAVE_IMAGEVIEWER;NDEBUG;_WINDOWS;%(PreprocessorDefinitions);HAVE_XINPUT;HAVE_XINPUT2;HAVE_XAUDIO;HAVE_DIRECTX;HAVE_NETWORKING;HAVE_NETWORK_CMD;HAVE_NETPLAYDISCOVERY;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;__SSE__;__i686__;HAVE_OVERLAY;HAVE_MENU;HAVE_RGUI;HAVE_MATERIALUI;HAVE_LIBRETRODB;HAVE_STB_FONT;HAVE_STATIC_DUMMY;HAVE_STATIC_VIDEO_FILTERS;HAVE_STATIC_AUDIO_FILTERS + WIN32;HAVE_MAIN;HAVE_DYNAMIC;HAVE_XAUDIO2;RARCH_INTERNAL;HAVE_CC_RESAMPLER;HAVE_SLANG;HAVE_SPIRV_CROSS;HAVE_UPDATE_ASSETS;HAVE_D3D;HAVE_D3D11;HAVE_D3D12;ENABLE_HLSL;RC_DISABLE_LUA;HAVE_CHEEVOS;HAVE_RUNAHEAD;HAVE_GRIFFIN;HAVE_LANGEXTRA;HAVE_FBO;HAVE_ZLIB;HAVE_XMB;HAVE_SHADERPIPELINE;WANT_ZLIB;HAVE_RPNG;HAVE_RJPEG;HAVE_RBMP;HAVE_RTGA;HAVE_IMAGEVIEWER;NDEBUG;_WINDOWS;%(PreprocessorDefinitions);HAVE_XINPUT;HAVE_XINPUT2;HAVE_XAUDIO;HAVE_DIRECTX;HAVE_NETWORKING;HAVE_NETWORK_CMD;HAVE_NETPLAYDISCOVERY;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;__SSE__;__i686__;HAVE_OVERLAY;HAVE_MENU;HAVE_RGUI;HAVE_MATERIALUI;HAVE_LIBRETRODB;HAVE_STB_FONT;HAVE_STATIC_DUMMY;HAVE_STATIC_VIDEO_FILTERS;HAVE_STATIC_AUDIO_FILTERS