diff --git a/UnleashedRecomp/CMakeLists.txt b/UnleashedRecomp/CMakeLists.txt index 00aa2ad3..e7270cbf 100644 --- a/UnleashedRecomp/CMakeLists.txt +++ b/UnleashedRecomp/CMakeLists.txt @@ -82,7 +82,7 @@ set(SWA_APU_CXX_SOURCES if(SWA_XAUDIO2) list(APPEND SWA_APU_CXX_SOURCES "apu/driver/xaudio_driver.cpp") else() - list(APPEND SWA_APU_CXX_SOURCES "apu/driver/sdl2_driver.cpp") + list(APPEND SWA_APU_CXX_SOURCES "apu/driver/miniaudio_driver.cpp") endif() set(SWA_HID_CXX_SOURCES @@ -195,8 +195,8 @@ find_package(unofficial-concurrentqueue REQUIRED) find_package(imgui CONFIG REQUIRED) find_package(magic_enum CONFIG REQUIRED) find_package(unofficial-tiny-aes-c CONFIG REQUIRED) -find_path(READERWRITERQUEUE_INCLUDE_DIRS "readerwriterqueue/atomicops.h") find_package(nfd CONFIG REQUIRED) +find_path(MINIAUDIO_INCLUDE_DIRS "miniaudio.h") file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/D3D12) add_custom_command(TARGET UnleashedRecomp POST_BUILD @@ -245,7 +245,7 @@ target_include_directories(UnleashedRecomp PRIVATE ${LIBMSPACK_PATH} ${Stb_INCLUDE_DIR} ${SMOLV_SOURCE_DIR} - ${READERWRITERQUEUE_INCLUDE_DIRS} + ${MINIAUDIO_INCLUDE_DIRS} ) target_precompile_headers(UnleashedRecomp PUBLIC ${SWA_PRECOMPILED_HEADERS}) @@ -315,6 +315,7 @@ generate_aggregate_header( set(RESOURCES_SOURCE_PATH "${PROJECT_SOURCE_DIR}/../UnleashedRecompResources") set(RESOURCES_OUTPUT_PATH "${PROJECT_SOURCE_DIR}/res") + BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/achievements_menu/trophy.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/achievements_menu/trophy.dds" ARRAY_TYPE "unsigned char" ARRAY_NAME "g_trophy") BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/installer/arrow_circle.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/installer/arrow_circle.dds" ARRAY_TYPE "unsigned char" ARRAY_NAME "g_arrow_circle") BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/installer/install_001.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/installer/install_001.dds" ARRAY_TYPE "unsigned char" ARRAY_NAME "g_install_001") @@ -326,6 +327,8 @@ BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/in BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/installer/install_007.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/installer/install_007.dds" ARRAY_TYPE "unsigned char" ARRAY_NAME "g_install_007") BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/installer/install_008.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/installer/install_008.dds" ARRAY_TYPE "unsigned char" ARRAY_NAME "g_install_008") BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/installer/miles_electric_icon.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/installer/miles_electric_icon.dds" ARRAY_TYPE "unsigned char" ARRAY_NAME "g_miles_electric_icon") +BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/common/general_window.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/common/general_window.dds" ARRAY_TYPE "unsigned char" ARRAY_NAME "g_general_window") +BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/common/select_fade.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/common/select_fade.dds" ARRAY_TYPE "unsigned char" ARRAY_NAME "g_select_fade") +BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/common/select_fill.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/common/select_fill.dds" ARRAY_TYPE "unsigned char" ARRAY_NAME "g_select_fill") BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/game_icon.bmp" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/game_icon.bmp" ARRAY_TYPE "unsigned char" ARRAY_NAME "g_game_icon") BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/game_icon_night.bmp" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/game_icon_night.bmp" ARRAY_TYPE "unsigned char" ARRAY_NAME "g_game_icon_night") -BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/pause.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/pause.dds" ARRAY_TYPE "unsigned char" ARRAY_NAME "g_pause") diff --git a/UnleashedRecomp/apu/driver/miniaudio_driver.cpp b/UnleashedRecomp/apu/driver/miniaudio_driver.cpp new file mode 100644 index 00000000..a5b6dd2b --- /dev/null +++ b/UnleashedRecomp/apu/driver/miniaudio_driver.cpp @@ -0,0 +1,56 @@ +#include "miniaudio_driver.h" +#include +#include +#include +#include + +#define MINIAUDIO_IMPLEMENTATION +#include + +static PPCFunc* g_clientCallback{}; +static DWORD g_clientCallbackParam{}; // pointer in guest memory +static ma_device g_audioDevice{}; +static std::unique_ptr g_audioCtx; +static uint32_t* g_audioOutput; + +static void AudioCallback(ma_device* pDevice, void* pOutput, const void* pInput, ma_uint32 frameCount) +{ + if (g_audioCtx == nullptr) + g_audioCtx = std::make_unique(0); + + g_audioCtx->ppcContext.r3.u64 = g_clientCallbackParam; + g_audioOutput = reinterpret_cast(pOutput); + (*g_clientCallback)(g_audioCtx->ppcContext, reinterpret_cast(g_memory.base)); +} + +void XAudioInitializeSystem() +{ + ma_device_config deviceConfig = ma_device_config_init(ma_device_type_playback); + deviceConfig.sampleRate = XAUDIO_SAMPLES_HZ; + deviceConfig.periodSizeInFrames = XAUDIO_NUM_SAMPLES; + deviceConfig.noPreSilencedOutputBuffer = true; + deviceConfig.dataCallback = AudioCallback; + deviceConfig.playback.format = ma_format_f32; + deviceConfig.playback.channels = XAUDIO_NUM_CHANNELS; + ma_device_init(nullptr, &deviceConfig, &g_audioDevice); +} + +void XAudioRegisterClient(PPCFunc* callback, uint32_t param) +{ + auto* pClientParam = static_cast(g_userHeap.Alloc(sizeof(param))); + ByteSwap(param); + *pClientParam = param; + g_clientCallbackParam = g_memory.MapVirtual(pClientParam); + g_clientCallback = callback; + + ma_device_start(&g_audioDevice); +} + +void XAudioSubmitFrame(void* samples) +{ + for (size_t i = 0; i < XAUDIO_NUM_SAMPLES; i++) + { + for (size_t j = 0; j < XAUDIO_NUM_CHANNELS; j++) + g_audioOutput[i * XAUDIO_NUM_CHANNELS + j] = std::byteswap(((uint32_t*)samples)[j * XAUDIO_NUM_SAMPLES + i]); + } +} diff --git a/UnleashedRecomp/apu/driver/sdl2_driver.h b/UnleashedRecomp/apu/driver/miniaudio_driver.h similarity index 67% rename from UnleashedRecomp/apu/driver/sdl2_driver.h rename to UnleashedRecomp/apu/driver/miniaudio_driver.h index ab732be5..c8f99bf4 100644 --- a/UnleashedRecomp/apu/driver/sdl2_driver.h +++ b/UnleashedRecomp/apu/driver/miniaudio_driver.h @@ -1,3 +1,2 @@ #pragma once -#include #include diff --git a/UnleashedRecomp/apu/driver/sdl2_driver.cpp b/UnleashedRecomp/apu/driver/sdl2_driver.cpp deleted file mode 100644 index da4cba78..00000000 --- a/UnleashedRecomp/apu/driver/sdl2_driver.cpp +++ /dev/null @@ -1,81 +0,0 @@ -#include "sdl2_driver.h" -#include -#include -#include -#include - -#define SDLAUDIO_DRIVER_KEY (uint32_t)('SDLA') - -static constexpr uint32_t AUDIO_FRAME_SIZE = XAUDIO_NUM_SAMPLES * XAUDIO_NUM_CHANNELS; - -static std::atomic g_clientCallback{}; -static DWORD g_clientCallbackParam{}; // pointer in guest memory - -static SDL_AudioDeviceID g_audioDevice{}; -static moodycamel::BlockingReaderWriterCircularBuffer> g_audioQueue(16); - -static void SDLAudioCallback(void*, uint8_t* frames, int len) -{ - std::array audioFrame; - if (g_audioQueue.try_dequeue(audioFrame)) - memcpy(frames, &audioFrame, sizeof(audioFrame)); - else - memset(frames, 0, len); -} - -static PPC_FUNC(DriverLoop) -{ - GuestThread::SetThreadName(GetCurrentThreadId(), "Audio Driver"); - - while (true) - { - if (!g_clientCallback) - continue; - - ctx.r3.u64 = g_clientCallbackParam; - GuestCode::Run((void*)g_clientCallback, &ctx); - } -} - -void XAudioInitializeSystem() -{ - SDL_SetHint(SDL_HINT_AUDIO_CATEGORY, "playback"); - SDL_SetHint(SDL_HINT_AUDIO_DEVICE_APP_NAME, "SWA"); - - auto err = SDL_InitSubSystem(SDL_INIT_AUDIO); - SDL_AudioSpec spec{}; - spec.freq = XAUDIO_SAMPLES_HZ; - spec.format = AUDIO_F32SYS; - spec.channels = XAUDIO_NUM_CHANNELS; - spec.samples = XAUDIO_NUM_SAMPLES; - spec.callback = SDLAudioCallback; - g_audioDevice = SDL_OpenAudioDevice(nullptr, false, &spec, &spec, 0); - assert(g_audioDevice); - - SDL_PauseAudioDevice(g_audioDevice, 0); - KeInsertHostFunction(SDLAUDIO_DRIVER_KEY, DriverLoop); - GuestThread::Start(SDLAUDIO_DRIVER_KEY, 0, 0, nullptr); -} - -void XAudioRegisterClient(PPCFunc* callback, uint32_t param) -{ - auto* pClientParam = static_cast(g_userHeap.Alloc(sizeof(param))); - ByteSwap(param); - *pClientParam = param; - g_clientCallbackParam = g_memory.MapVirtual(pClientParam); - - g_clientCallback = callback; -} - -void XAudioSubmitFrame(void* samples) -{ - std::array audioFrame; - - for (size_t i = 0; i < XAUDIO_NUM_SAMPLES; i++) - { - for (size_t j = 0; j < XAUDIO_NUM_CHANNELS; j++) - audioFrame[i * XAUDIO_NUM_CHANNELS + j] = std::byteswap(((uint32_t*)samples)[j * XAUDIO_NUM_SAMPLES + i]); - } - - g_audioQueue.wait_enqueue(audioFrame); -} diff --git a/UnleashedRecomp/cpu/guest_code.h b/UnleashedRecomp/cpu/guest_code.h index 11a27080..4177b05e 100644 --- a/UnleashedRecomp/cpu/guest_code.h +++ b/UnleashedRecomp/cpu/guest_code.h @@ -4,7 +4,7 @@ struct GuestCode { - inline static void Run(void* hostAddress, PPCContext* ctx, void* baseAddress, void* callStack) + inline static void Run(void* hostAddress, PPCContext* ctx, void* baseAddress) { ctx->fpscr.loadFromHost(); reinterpret_cast(hostAddress)(*ctx, reinterpret_cast(baseAddress)); diff --git a/UnleashedRecomp/cpu/guest_thread.cpp b/UnleashedRecomp/cpu/guest_thread.cpp index c13f580f..21010ee1 100644 --- a/UnleashedRecomp/cpu/guest_thread.cpp +++ b/UnleashedRecomp/cpu/guest_thread.cpp @@ -11,24 +11,15 @@ constexpr size_t PCR_SIZE = 0xAB0; constexpr size_t TLS_SIZE = 0x100; constexpr size_t TEB_SIZE = 0x2E0; constexpr size_t STACK_SIZE = 0x40000; -constexpr size_t CALL_STACK_SIZE = 0x8000; -constexpr size_t TOTAL_SIZE = PCR_SIZE + TLS_SIZE + TEB_SIZE + STACK_SIZE + CALL_STACK_SIZE; +constexpr size_t TOTAL_SIZE = PCR_SIZE + TLS_SIZE + TEB_SIZE + STACK_SIZE; constexpr size_t TEB_OFFSET = PCR_SIZE + TLS_SIZE; -DWORD GuestThread::Start(uint32_t function) +GuestThreadContext::GuestThreadContext(uint32_t cpuNumber) { - const GuestThreadParameter parameter{ function }; - return Start(parameter); -} - -DWORD GuestThread::Start(const GuestThreadParameter& parameter) -{ - auto* thread = (uint8_t*)g_userHeap.Alloc(TOTAL_SIZE); - - const auto procMask = (uint8_t)(parameter.flags >> 24); - const auto cpuNumber = procMask == 0 ? 0 : 7 - std::countl_zero(procMask); + assert(thread == nullptr); + thread = (uint8_t*)g_userHeap.Alloc(TOTAL_SIZE); memset(thread, 0, TOTAL_SIZE); *(uint32_t*)thread = std::byteswap(g_memory.MapVirtual(thread + PCR_SIZE)); // tls pointer @@ -38,18 +29,36 @@ DWORD GuestThread::Start(const GuestThreadParameter& parameter) *(uint32_t*)(thread + PCR_SIZE + 0x10) = 0xFFFFFFFF; // that one TLS entry that felt quirky *(uint32_t*)(thread + PCR_SIZE + TLS_SIZE + 0x14C) = std::byteswap(GetCurrentThreadId()); // thread id - PPCContext ppcContext{}; ppcContext.fn = (uint8_t*)g_codeCache.bucket; ppcContext.r1.u64 = g_memory.MapVirtual(thread + PCR_SIZE + TLS_SIZE + TEB_SIZE + STACK_SIZE); // stack pointer - ppcContext.r3.u64 = parameter.value; ppcContext.r13.u64 = g_memory.MapVirtual(thread); + assert(GetPPCContext() == nullptr); SetPPCContext(ppcContext); +} - GuestCode::Run(g_codeCache.Find(parameter.function), &ppcContext, g_memory.Translate(0), g_memory.Translate(ppcContext.r1.u32)); +GuestThreadContext::~GuestThreadContext() +{ g_userHeap.Free(thread); +} - return (DWORD)ppcContext.r3.u64; +DWORD GuestThread::Start(uint32_t function) +{ + const GuestThreadParameter parameter{ function }; + return Start(parameter); +} + +DWORD GuestThread::Start(const GuestThreadParameter& parameter) +{ + const auto procMask = (uint8_t)(parameter.flags >> 24); + const auto cpuNumber = procMask == 0 ? 0 : 7 - std::countl_zero(procMask); + + GuestThreadContext ctx(cpuNumber); + ctx.ppcContext.r3.u64 = parameter.value; + + GuestCode::Run(g_codeCache.Find(parameter.function), &ctx.ppcContext, g_memory.Translate(0)); + + return (DWORD)ctx.ppcContext.r3.u64; } DWORD HostThreadStart(void* pParameter) diff --git a/UnleashedRecomp/cpu/guest_thread.h b/UnleashedRecomp/cpu/guest_thread.h index fd7f8ff7..7fb6e9b5 100644 --- a/UnleashedRecomp/cpu/guest_thread.h +++ b/UnleashedRecomp/cpu/guest_thread.h @@ -8,6 +8,15 @@ struct GuestThreadParameter uint32_t flags; }; +struct GuestThreadContext +{ + PPCContext ppcContext{}; + uint8_t* thread = nullptr; + + GuestThreadContext(uint32_t cpuNumber); + ~GuestThreadContext(); +}; + struct GuestThread { static DWORD Start(uint32_t function); diff --git a/UnleashedRecomp/gpu/video.cpp b/UnleashedRecomp/gpu/video.cpp index 489be1fe..b3fc8e3f 100644 --- a/UnleashedRecomp/gpu/video.cpp +++ b/UnleashedRecomp/gpu/video.cpp @@ -4638,7 +4638,7 @@ static void EnqueueGraphicsPipelineCompilation(const PipelineState& pipelineStat if (shouldCompile) { if (databaseDataHolderPair.counter == nullptr && databaseDataHolderPair.holder.databaseData.get() != nullptr) - databaseDataHolderPair.counter = std::make_unique(std::move(databaseDataHolderPair.holder)); + databaseDataHolderPair.counter = std::make_shared(std::move(databaseDataHolderPair.holder)); PipelineStateQueueItem queueItem; queueItem.pipelineHash = hash; diff --git a/UnleashedRecomp/misc_impl.cpp b/UnleashedRecomp/misc_impl.cpp index e9d391c3..451f001d 100644 --- a/UnleashedRecomp/misc_impl.cpp +++ b/UnleashedRecomp/misc_impl.cpp @@ -42,6 +42,7 @@ GUEST_FUNCTION_HOOK(sub_82BD4CA8, OutputDebugStringA); GUEST_FUNCTION_HOOK(sub_82BD4AC8, QueryPerformanceCounterImpl); GUEST_FUNCTION_HOOK(sub_831CD040, QueryPerformanceFrequencyImpl); +GUEST_FUNCTION_HOOK(sub_831CDAD0, GetTickCount); GUEST_FUNCTION_HOOK(sub_82BD4BC0, GlobalMemoryStatusImpl); diff --git a/UnleashedRecomp/patches/audio_patches.cpp b/UnleashedRecomp/patches/audio_patches.cpp index 47ee2dfd..e42d37ab 100644 --- a/UnleashedRecomp/patches/audio_patches.cpp +++ b/UnleashedRecomp/patches/audio_patches.cpp @@ -62,7 +62,7 @@ bool AudioPatches::CanAttenuate() auto version = GetPlatformVersion(); - m_isAttenuationSupported = version.Major == 10 && version.Build >= 17763; + m_isAttenuationSupported = version.Major >= 10 && version.Build >= 17763; return m_isAttenuationSupported; #else diff --git a/UnleashedRecomp/stdafx.h b/UnleashedRecomp/stdafx.h index 964e928a..d8769c36 100644 --- a/UnleashedRecomp/stdafx.h +++ b/UnleashedRecomp/stdafx.h @@ -33,7 +33,6 @@ #include #include #include -#include using Microsoft::WRL::ComPtr; diff --git a/UnleashedRecomp/ui/achievement_menu.cpp b/UnleashedRecomp/ui/achievement_menu.cpp index 23325211..152cfbde 100644 --- a/UnleashedRecomp/ui/achievement_menu.cpp +++ b/UnleashedRecomp/ui/achievement_menu.cpp @@ -8,6 +8,9 @@ #include #include #include +#include +#include +#include constexpr double HEADER_CONTAINER_INTRO_MOTION_START = 0; constexpr double HEADER_CONTAINER_INTRO_MOTION_END = 15; @@ -23,14 +26,12 @@ constexpr double CONTENT_CONTAINER_COMMON_MOTION_END = 12; constexpr double COUNTER_INTRO_FADE_START = 15; constexpr double COUNTER_INTRO_FADE_END = 16; -constexpr double COUNTER_SPRITE_FRAME_START = 0; -constexpr double COUNTER_SPRITE_FRAME_END = 30; constexpr double SELECTION_CONTAINER_BREATHE = 30; static bool g_isClosing = false; -static double g_appearTime = 0; +static double g_appearTime; static std::vector> g_achievements; @@ -39,6 +40,8 @@ static ImFont* g_fntNewRodinDB; static ImFont* g_fntNewRodinUB; static std::unique_ptr g_upTrophyIcon; +static std::unique_ptr g_upSelectionCursor; +static std::unique_ptr g_upWindow; static int g_firstVisibleRowIndex; static int g_selectedRowIndex; @@ -63,42 +66,8 @@ static void ResetSelection() static void DrawContainer(ImVec2 min, ImVec2 max, ImU32 gradientTop, ImU32 gradientBottom, float alpha = 1, float cornerRadius = 25) { auto drawList = ImGui::GetForegroundDrawList(); - auto vertices = GetPauseContainerVertices(min, max, cornerRadius); - // TODO: add a drop shadow. - - SetGradient(min, max, gradientTop, gradientBottom); - drawList->AddConvexPolyFilled(vertices.data(), vertices.size(), IM_COL32(255, 255, 255, 255 * alpha)); - ResetGradient(); - - drawList->AddPolyline(vertices.data(), vertices.size(), IM_COL32(247, 247, 247, 255 * alpha), true, Scale(2.5f)); - - for (int i = 0; i < vertices.size(); i++) - { - vertices[i].x -= Scale(0.4f); - vertices[i].y -= Scale(0.2f); - } - - auto colLineTop = IM_COL32(165, 170, 165, 230 * alpha); - auto colLineBottom = IM_COL32(190, 190, 190, 230 * alpha); - auto lineThickness = Scale(1); - - // Top left corner bottom to top left corner top. - drawList->AddLine(vertices[0], vertices[1], colLineTop, lineThickness * Scale(0.5f)); - - // Top left corner bottom to bottom left. - drawList->AddRectFilledMultiColor - ( - { /* X */ vertices[0].x - Scale(0.2f), /* Y */ vertices[0].y }, - { /* X */ vertices[6].x + lineThickness - Scale(0.2f), /* Y */ vertices[6].y }, - colLineTop, - colLineTop, - colLineBottom, - colLineBottom - ); - - // Top left corner top to top right. - drawList->AddLine(vertices[1], vertices[2], colLineTop, lineThickness); + DrawPauseContainer(g_upWindow, min, max, alpha); drawList->PushClipRect({ min.x, min.y + Scale(20) }, { max.x, max.y - Scale(5) }); } @@ -106,20 +75,39 @@ static void DrawContainer(ImVec2 min, ImVec2 max, ImU32 gradientTop, ImU32 gradi static void DrawSelectionContainer(ImVec2 min, ImVec2 max) { auto drawList = ImGui::GetForegroundDrawList(); - auto vertices = GetPauseContainerVertices(min, max, 10); static auto breatheStart = ImGui::GetTime(); auto alpha = Lerp(1.0f, 0.75f, (sin((ImGui::GetTime() - breatheStart) * (2.0f * M_PI / (55.0f / 60.0f))) + 1.0f) / 2.0f); + auto colour = IM_COL32(255, 255, 255, 255 * alpha); - SetGradient(min, max, IM_COL32(255, 246, 0, 129), IM_COL32(255, 194, 0, 118 * alpha)); - drawList->AddConvexPolyFilled(vertices.data(), vertices.size(), IM_COL32(255, 255, 255, 255 * alpha)); - ResetGradient(); + auto commonWidth = Scale(11); + auto commonHeight = Scale(24); + + auto tl = PIXELS_TO_UV_COORDS(64, 64, 0, 0, 11, 24); + auto tc = PIXELS_TO_UV_COORDS(64, 64, 11, 0, 8, 24); + auto tr = PIXELS_TO_UV_COORDS(64, 64, 19, 0, 11, 24); + auto cl = PIXELS_TO_UV_COORDS(64, 64, 0, 24, 11, 2); + auto cc = PIXELS_TO_UV_COORDS(64, 64, 11, 24, 8, 2); + auto cr = PIXELS_TO_UV_COORDS(64, 64, 19, 24, 11, 2); + auto bl = PIXELS_TO_UV_COORDS(64, 64, 0, 26, 11, 24); + auto bc = PIXELS_TO_UV_COORDS(64, 64, 11, 26, 8, 24); + auto br = PIXELS_TO_UV_COORDS(64, 64, 19, 26, 11, 24); + + drawList->AddImage(g_upSelectionCursor.get(), min, { min.x + commonWidth, min.y + commonHeight }, GET_UV_COORDS(tl), colour); + drawList->AddImage(g_upSelectionCursor.get(), { min.x + commonWidth, min.y }, { max.x - commonWidth, min.y + commonHeight }, GET_UV_COORDS(tc), colour); + drawList->AddImage(g_upSelectionCursor.get(), { max.x - commonWidth, min.y }, { max.x, min.y + commonHeight }, GET_UV_COORDS(tr), colour); + drawList->AddImage(g_upSelectionCursor.get(), { min.x, min.y + commonHeight }, { min.x + commonWidth, max.y - commonHeight }, GET_UV_COORDS(cl), colour); + drawList->AddImage(g_upSelectionCursor.get(), { min.x + commonWidth, min.y + commonHeight }, { max.x - commonWidth, max.y - commonHeight }, GET_UV_COORDS(cc), colour); + drawList->AddImage(g_upSelectionCursor.get(), { max.x - commonWidth, min.y + commonHeight }, { max.x, max.y - commonHeight }, GET_UV_COORDS(cr), colour); + drawList->AddImage(g_upSelectionCursor.get(), { min.x, max.y - commonHeight }, { min.x + commonWidth, max.y }, GET_UV_COORDS(bl), colour); + drawList->AddImage(g_upSelectionCursor.get(), { min.x + commonWidth, max.y - commonHeight }, { max.x - commonWidth, max.y }, GET_UV_COORDS(bc), colour); + drawList->AddImage(g_upSelectionCursor.get(), { max.x - commonWidth, max.y - commonHeight }, { max.x, max.y }, GET_UV_COORDS(br), colour); } static void DrawHeaderContainer(const char* text) { auto drawList = ImGui::GetForegroundDrawList(); - auto fontSize = Scale(26); + auto fontSize = Scale(24); auto textSize = g_fntNewRodinUB->CalcTextSizeA(fontSize, FLT_MAX, 0, text); auto cornerRadius = 23; auto textMarginX = Scale(16) + (Scale(cornerRadius) / 2); @@ -134,26 +122,25 @@ static void DrawHeaderContainer(const char* text) // Slide animation. auto containerMarginX = g_isClosing - ? Hermite(256, 156, containerMotion) - : Hermite(156, 256, containerMotion); + ? Hermite(251, 151, containerMotion) + : Hermite(151, 251, containerMotion); // Transparency fade animation. auto alpha = g_isClosing ? Lerp(1, 0, colourMotion) : Lerp(0, 1, colourMotion); - ImVec2 min = { Scale(containerMarginX), Scale(138) }; - ImVec2 max = { min.x + textMarginX * 2 + textSize.x, Scale(185) }; + ImVec2 min = { Scale(containerMarginX), Scale(136) }; + ImVec2 max = { min.x + textMarginX * 2 + textSize.x + Scale(5), Scale(196) }; - DrawContainer(min, max, IM_COL32(140, 142, 140, 201), IM_COL32(66, 65, 66, 234), alpha, cornerRadius); - drawList->PopClipRect(); + DrawPauseHeaderContainer(g_upWindow, min, max, alpha); // TODO: skew this text and apply bevel. DrawTextWithOutline ( g_fntNewRodinUB, fontSize, - { /* X */ min.x + textMarginX, /* Y */ min.y + ((max.y - min.y) - textSize.y) / 2 }, + { /* X */ min.x + textMarginX, /* Y */ min.y + ((max.y - min.y) - textSize.y) / 2 - Scale(5) }, IM_COL32(255, 255, 255, 255 * alpha), text, 3, @@ -168,9 +155,9 @@ static void DrawAchievement(int rowIndex, float yOffset, Achievement& achievemen auto clipRectMin = drawList->GetClipRectMin(); auto clipRectMax = drawList->GetClipRectMax(); - auto itemWidth = Scale(708); + auto itemWidth = Scale(700); auto itemHeight = Scale(94); - auto itemMarginX = Scale(13); + auto itemMarginX = Scale(18); auto imageMarginX = Scale(25); auto imageMarginY = Scale(18); auto imageSize = Scale(60); @@ -371,10 +358,16 @@ static void DrawAchievementTotal(ImVec2 min, ImVec2 max) ImVec2 imageMin = { max.x - imageSize - imageMarginX, min.y - imageSize - imageMarginY }; ImVec2 imageMax = { imageMin.x + imageSize, imageMin.y + imageSize }; - auto frm = int32_t(floor(ImGui::GetTime() * 30.0f)) % 30; - auto w = 256.0f / 7680.0f; - auto uv0 = ImVec2(frm * w, 0); - auto uv1 = ImVec2((frm + 1) * w, 1); + constexpr auto columns = 8; + constexpr auto rows = 4; + constexpr auto spriteSize = 256.0f; + constexpr auto textureWidth = 2048.0f; + constexpr auto textureHeight = 1024.0f; + auto frameIndex = int32_t(floor(ImGui::GetTime() * 30.0f)) % 30; + auto columnIndex = frameIndex % columns; + auto rowIndex = frameIndex / columns; + auto uv0 = ImVec2(columnIndex * spriteSize / textureWidth, rowIndex * spriteSize / textureHeight); + auto uv1 = ImVec2((columnIndex + 1) * spriteSize / textureWidth, (rowIndex + 1) * spriteSize / textureHeight); drawList->AddImage(g_upTrophyIcon.get(), imageMin, imageMax, uv0, uv1, IM_COL32(255, 255, 255, 255 * alpha)); @@ -404,20 +397,20 @@ static void DrawContentContainer() : ComputeMotion(g_appearTime, CONTENT_CONTAINER_COMMON_MOTION_START, CONTENT_CONTAINER_COMMON_MOTION_END); auto minX = g_isClosing - ? Hermite(256, 306, motion) - : Hermite(306, 256, motion); + ? Hermite(251, 301, motion) + : Hermite(301, 251, motion); auto minY = g_isClosing - ? Hermite(192, 209, motion) - : Hermite(209, 192, motion); + ? Hermite(189, 206, motion) + : Hermite(206, 189, motion); auto maxX = g_isClosing - ? Hermite(1026, 973, motion) - : Hermite(973, 1026, motion); + ? Hermite(1031, 978, motion) + : Hermite(978, 1031, motion); auto maxY = g_isClosing - ? Hermite(601, 569, motion) - : Hermite(569, 601, motion); + ? Hermite(604, 573, motion) + : Hermite(573, 604, motion); ImVec2 min = { Scale(minX), Scale(minY) }; ImVec2 max = { Scale(maxX), Scale(maxY) }; @@ -449,8 +442,8 @@ static void DrawContentContainer() // Draw separators. for (int i = 1; i <= 3; i++) { - auto lineMarginLeft = Scale(31); - auto lineMarginRight = Scale(46); + auto lineMarginLeft = Scale(35); + auto lineMarginRight = Scale(55); auto lineMarginY = Scale(2); ImVec2 lineMin = { clipRectMin.x + lineMarginLeft, clipRectMin.y + itemHeight * i + lineMarginY }; @@ -568,34 +561,35 @@ static void DrawContentContainer() // Draw scroll bar if (rowCount > visibleRowCount) { - float cornerRadius = Scale(25.0f); - float totalHeight = (clipRectMax.y - clipRectMin.y - cornerRadius) - Scale(3.0f); + float cornerRadius = Scale(25); + float totalHeight = (clipRectMax.y - clipRectMin.y - cornerRadius) - Scale(3); float heightRatio = float(visibleRowCount) / float(rowCount); float offsetRatio = float(g_firstVisibleRowIndex) / float(rowCount); - float offsetX = clipRectMax.x - Scale(31.0f); - float offsetY = offsetRatio * totalHeight + clipRectMin.y + Scale(4.0f); - float lineThickness = Scale(1.0f); - float innerMarginX = Scale(2.0f); - float outerMarginX = Scale(16.0f); + float offsetX = clipRectMax.x - Scale(39); + float offsetY = offsetRatio * totalHeight + clipRectMin.y + Scale(4); + float maxY = max.y - cornerRadius - Scale(3); + float lineThickness = Scale(1); + float innerMarginX = Scale(2); + float outerMarginX = Scale(24); // Outline drawList->AddRect ( { /* X */ offsetX - lineThickness, /* Y */ clipRectMin.y - lineThickness }, - { /* X */ clipRectMax.x - outerMarginX + lineThickness, /* Y */ max.y - cornerRadius + lineThickness }, + { /* X */ clipRectMax.x - outerMarginX + lineThickness, /* Y */ maxY + lineThickness }, IM_COL32(255, 255, 255, 155), - Scale(0.5f) + Scale(1) ); // Background drawList->AddRectFilledMultiColor ( { /* X */ offsetX, /* Y */ clipRectMin.y }, - { /* X */ clipRectMax.x - outerMarginX, /* Y */ max.y - cornerRadius }, - IM_COL32(82, 85, 82, 186), - IM_COL32(82, 85, 82, 186), - IM_COL32(74, 73, 74, 185), - IM_COL32(74, 73, 74, 185) + { /* X */ clipRectMax.x - outerMarginX, /* Y */ maxY }, + IM_COL32(123, 125, 123, 255), + IM_COL32(123, 125, 123, 255), + IM_COL32(97, 99, 97, 255), + IM_COL32(97, 99, 97, 255) ); // Scroll Bar Outline @@ -629,13 +623,9 @@ void AchievementMenu::Init() g_fntNewRodinDB = io.Fonts->AddFontFromFileTTF("FOT-NewRodinPro-DB.otf", 20.0f * FONT_SCALE); g_fntNewRodinUB = io.Fonts->AddFontFromFileTTF("FOT-NewRodinPro-UB.otf", 20.0f * FONT_SCALE); - size_t bufferSize = 0; - auto buffer = ReadAllBytes("achievements_trophy.png", bufferSize); - - if (!bufferSize) - return; - - g_upTrophyIcon = LoadTexture(buffer.get(), bufferSize); + g_upTrophyIcon = LoadTexture(g_trophy, sizeof(g_trophy)); + g_upSelectionCursor = LoadTexture(g_select_fill, sizeof(g_select_fill)); + g_upWindow = LoadTexture(g_general_window, sizeof(g_general_window)); } void AchievementMenu::Draw() diff --git a/UnleashedRecomp/ui/achievement_overlay.cpp b/UnleashedRecomp/ui/achievement_overlay.cpp index e6e4eee4..703fce46 100644 --- a/UnleashedRecomp/ui/achievement_overlay.cpp +++ b/UnleashedRecomp/ui/achievement_overlay.cpp @@ -8,6 +8,7 @@ #include #include #include +#include constexpr double OVERLAY_CONTAINER_COMMON_MOTION_START = 0; constexpr double OVERLAY_CONTAINER_COMMON_MOTION_END = 11; @@ -26,6 +27,8 @@ static Achievement g_achievement; static ImFont* g_fntSeurat; +static std::unique_ptr g_upWindow; + static bool DrawContainer(ImVec2 min, ImVec2 max, float cornerRadius = 25) { auto drawList = ImGui::GetForegroundDrawList(); @@ -51,8 +54,6 @@ static bool DrawContainer(ImVec2 min, ImVec2 max, float cornerRadius = 25) max.y = Hermite(centreY, max.y, containerMotion); } - auto vertices = GetPauseContainerVertices(min, max, cornerRadius); - // Transparency fade animation. auto colourMotion = g_isClosing ? ComputeMotion(g_appearTime, OVERLAY_CONTAINER_OUTRO_FADE_START, OVERLAY_CONTAINER_OUTRO_FADE_END) @@ -62,46 +63,7 @@ static bool DrawContainer(ImVec2 min, ImVec2 max, float cornerRadius = 25) ? Hermite(1, 0, colourMotion) : Hermite(0, 1, colourMotion); - auto colShadow = IM_COL32(0, 0, 0, 156 * alpha); - auto colGradientTop = IM_COL32(197, 194, 197, 200 * alpha); - auto colGradientBottom = IM_COL32(115, 113, 115, 236 * alpha); - - // TODO: add a drop shadow. - - // Draw vertices with gradient. - SetGradient(min, max, colGradientTop, colGradientBottom); - drawList->AddConvexPolyFilled(vertices.data(), vertices.size(), IM_COL32(255, 255, 255, 255 * alpha)); - ResetGradient(); - - // Draw outline. - drawList->AddPolyline - ( - vertices.data(), - vertices.size(), - IM_COL32(247, 247, 247, 255 * alpha), - true, - Scale(2.5f) - ); - - // Offset vertices to draw 3D effect lines. - for (int i = 0; i < vertices.size(); i++) - { - vertices[i].x -= Scale(0.4f); - vertices[i].y -= Scale(0.2f); - } - - auto colLineTop = IM_COL32(165, 170, 165, 230 * alpha); - auto colLineBottom = IM_COL32(190, 190, 190, 230 * alpha); - auto lineThickness = Scale(1.0f); - - // Top left corner bottom to top left corner top. - drawList->AddLine(vertices[0], vertices[1], colLineTop, lineThickness * 0.5f); - - // Top left corner bottom to bottom left. - drawList->AddRectFilledMultiColor({ vertices[0].x - 0.2f, vertices[0].y }, { vertices[6].x + lineThickness - 0.2f, vertices[6].y }, colLineTop, colLineTop, colLineBottom, colLineBottom); - - // Top left corner top to top right. - drawList->AddLine(vertices[1], vertices[2], colLineTop, lineThickness); + DrawPauseContainer(g_upWindow, min, max, alpha); drawList->PushClipRect(min, max); @@ -115,6 +77,8 @@ void AchievementOverlay::Init() constexpr float FONT_SCALE = 2.0f; g_fntSeurat = io.Fonts->AddFontFromFileTTF("FOT-SeuratPro-M.otf", 24.0f * FONT_SCALE); + + g_upWindow = LoadTexture(g_general_window, sizeof(g_general_window)); } void AchievementOverlay::Draw() @@ -138,18 +102,18 @@ void AchievementOverlay::Draw() auto maxSize = std::max(headerSize.x, bodySize.x); // Calculate image margins. - auto imageMarginX = Scale(20); - auto imageMarginY = Scale(20); + auto imageMarginX = Scale(25); + auto imageMarginY = Scale(22.5f); auto imageSize = Scale(60); // Calculate text margins. - auto textMarginX = imageMarginX * 2 + imageSize; + auto textMarginX = imageMarginX * 2 + imageSize - Scale(5); auto textMarginY = imageMarginY + Scale(2); auto containerWidth = imageMarginX + textMarginX + maxSize; - ImVec2 min = { (res.x / 2) - (containerWidth / 2), Scale(50) }; - ImVec2 max = { min.x + containerWidth, min.y + Scale(100) }; + ImVec2 min = { (res.x / 2) - (containerWidth / 2), Scale(55) }; + ImVec2 max = { min.x + containerWidth, min.y + Scale(105) }; if (DrawContainer(min, max)) { diff --git a/UnleashedRecomp/ui/imgui_utils.h b/UnleashedRecomp/ui/imgui_utils.h index 728e5c57..50bbfafe 100644 --- a/UnleashedRecomp/ui/imgui_utils.h +++ b/UnleashedRecomp/ui/imgui_utils.h @@ -1,6 +1,7 @@ #pragma once #include +#include #include #define PIXELS_TO_UV_COORDS(textureWidth, textureHeight, x, y, width, height) \ @@ -84,17 +85,65 @@ static std::vector GetPauseContainerVertices(ImVec2 min, ImVec2 max, flo return { - { min.x, min.y + cornerRadius }, - { min.x + cornerRadius, min.y }, - { max.x, min.y }, - { max.x, min.y + cornerRadius }, - { max.x, max.y - cornerRadius }, - { max.x - cornerRadius, max.y }, - { min.x, max.y }, - { min.x, max.y - cornerRadius } + { min.x, min.y + cornerRadius }, // 0 - TL Corner Bottom + { min.x + cornerRadius, min.y }, // 1 - TL Corner Top + { max.x, min.y }, // 2 - TR Corner Top + { max.x, min.y + cornerRadius }, // 3 - TR Corner Bottom + { max.x, max.y - cornerRadius }, // 4 - BR Corner Top + { max.x - cornerRadius, max.y }, // 5 - BR Corner Bottom + { min.x, max.y }, // 6 - BL Corner Bottom + { min.x, max.y - cornerRadius } // 7 - BL Corner Top }; } +static void DrawPauseContainer(std::unique_ptr& texture, ImVec2 min, ImVec2 max, float alpha = 1) +{ + auto drawList = ImGui::GetForegroundDrawList(); + + auto commonWidth = Scale(35); + auto commonHeight = Scale(35); + auto bottomHeight = Scale(5); + + auto tl = PIXELS_TO_UV_COORDS(512, 512, 0, 0, 35, 35); + auto tc = PIXELS_TO_UV_COORDS(512, 512, 51, 0, 5, 35); + auto tr = PIXELS_TO_UV_COORDS(512, 512, 70, 0, 35, 35); + auto cl = PIXELS_TO_UV_COORDS(512, 512, 0, 35, 35, 235); + auto cc = PIXELS_TO_UV_COORDS(512, 512, 51, 35, 5, 235); + auto cr = PIXELS_TO_UV_COORDS(512, 512, 70, 35, 35, 235); + auto bl = PIXELS_TO_UV_COORDS(512, 512, 0, 270, 35, 40); + auto bc = PIXELS_TO_UV_COORDS(512, 512, 51, 270, 5, 40); + auto br = PIXELS_TO_UV_COORDS(512, 512, 70, 270, 35, 40); + + auto colour = IM_COL32(255, 255, 255, 255 * alpha); + + drawList->AddImage(texture.get(), min, { min.x + commonWidth, min.y + commonHeight }, GET_UV_COORDS(tl), colour); + drawList->AddImage(texture.get(), { min.x + commonWidth, min.y }, { max.x - commonWidth, min.y + commonHeight }, GET_UV_COORDS(tc), colour); + drawList->AddImage(texture.get(), { max.x - commonWidth, min.y }, { max.x, min.y + commonHeight }, GET_UV_COORDS(tr), colour); + drawList->AddImage(texture.get(), { min.x, min.y + commonHeight }, { min.x + commonWidth, max.y - commonHeight }, GET_UV_COORDS(cl), colour); + drawList->AddImage(texture.get(), { min.x + commonWidth, min.y + commonHeight }, { max.x - commonWidth, max.y - commonHeight }, GET_UV_COORDS(cc), colour); + drawList->AddImage(texture.get(), { max.x - commonWidth, min.y + commonHeight }, { max.x, max.y - commonHeight }, GET_UV_COORDS(cr), colour); + drawList->AddImage(texture.get(), { min.x, max.y - commonHeight }, { min.x + commonWidth, max.y + bottomHeight }, GET_UV_COORDS(bl), colour); + drawList->AddImage(texture.get(), { min.x + commonWidth, max.y - commonHeight }, { max.x - commonWidth, max.y + bottomHeight }, GET_UV_COORDS(bc), colour); + drawList->AddImage(texture.get(), { max.x - commonWidth, max.y - commonHeight }, { max.x, max.y + bottomHeight }, GET_UV_COORDS(br), colour); +} + +static void DrawPauseHeaderContainer(std::unique_ptr& texture, ImVec2 min, ImVec2 max, float alpha = 1) +{ + auto drawList = ImGui::GetForegroundDrawList(); + + auto commonWidth = Scale(35); + + auto left = PIXELS_TO_UV_COORDS(512, 512, 0, 314, 35, 60); + auto centre = PIXELS_TO_UV_COORDS(512, 512, 51, 314, 5, 60); + auto right = PIXELS_TO_UV_COORDS(512, 512, 70, 314, 35, 60); + + auto colour = IM_COL32(255, 255, 255, 255 * alpha); + + drawList->AddImage(texture.get(), min, { min.x + commonWidth, max.y }, GET_UV_COORDS(left), colour); + drawList->AddImage(texture.get(), { min.x + commonWidth, min.y }, { max.x - commonWidth, max.y }, GET_UV_COORDS(centre), colour); + drawList->AddImage(texture.get(), { max.x - commonWidth, min.y }, max, GET_UV_COORDS(right), colour); +} + static void DrawTextWithMarquee(const ImFont* font, float fontSize, const ImVec2& pos, const ImVec2& min, const ImVec2& max, ImU32 color, const char* text, double time, double delay, double speed) { auto drawList = ImGui::GetForegroundDrawList(); diff --git a/UnleashedRecomp/ui/message_window.cpp b/UnleashedRecomp/ui/message_window.cpp index c82a044b..9e3639b5 100644 --- a/UnleashedRecomp/ui/message_window.cpp +++ b/UnleashedRecomp/ui/message_window.cpp @@ -3,7 +3,7 @@ #include #include #include -#include +#include constexpr double OVERLAY_CONTAINER_COMMON_MOTION_START = 0; constexpr double OVERLAY_CONTAINER_COMMON_MOTION_END = 11; @@ -139,9 +139,9 @@ void DrawButton(int rowIndex, float yOffset, float width, float height, std::str auto colour = IM_COL32(255, 255, 255, 255 * alpha); auto width = Scale(11); - auto left = PIXELS_TO_UV_COORDS(128, 128, 0, 0, 11, 50); - auto centre = PIXELS_TO_UV_COORDS(128, 128, 11, 0, 8, 50); - auto right = PIXELS_TO_UV_COORDS(128, 128, 19, 0, 11, 50); + auto left = PIXELS_TO_UV_COORDS(64, 64, 0, 0, 11, 50); + auto centre = PIXELS_TO_UV_COORDS(64, 64, 11, 0, 8, 50); + auto right = PIXELS_TO_UV_COORDS(64, 64, 19, 0, 11, 50); drawList->AddImage(g_upSelectionCursor.get(), min, { min.x + width, max.y }, GET_UV_COORDS(left), colour); drawList->AddImage(g_upSelectionCursor.get(), { min.x + width, min.y }, { max.x - width, max.y }, GET_UV_COORDS(centre), colour); @@ -176,7 +176,7 @@ void MessageWindow::Init() g_fntSeurat = io.Fonts->AddFontFromFileTTF("FOT-SeuratPro-M.otf", 28.0f * FONT_SCALE); - g_upSelectionCursor = LoadTexture(g_pause, sizeof(g_pause)); + g_upSelectionCursor = LoadTexture(g_select_fade, sizeof(g_select_fade)); } void MessageWindow::Draw() diff --git a/UnleashedRecomp/ui/window.cpp b/UnleashedRecomp/ui/window.cpp index 939e9922..f52f730f 100644 --- a/UnleashedRecomp/ui/window.cpp +++ b/UnleashedRecomp/ui/window.cpp @@ -179,6 +179,10 @@ void Window::Init() SDL_GetWindowWMInfo(s_pWindow, &info); s_handle = info.info.win.window; + + SetDarkTitleBar(true); + + SDL_ShowWindow(s_pWindow); } void Window::Update() diff --git a/UnleashedRecomp/ui/window.h b/UnleashedRecomp/ui/window.h index 9e48300b..f7d01d52 100644 --- a/UnleashedRecomp/ui/window.h +++ b/UnleashedRecomp/ui/window.h @@ -5,6 +5,12 @@ #include #include +#if _WIN32 +#include +#include +#pragma comment(lib, "dwmapi.lib") +#endif + #define DEFAULT_WIDTH 1280 #define DEFAULT_HEIGHT 720 @@ -67,6 +73,23 @@ public: SDL_SetWindowTitle(s_pWindow, title ? title : GetTitle()); } + static void SetDarkTitleBar(bool isEnabled) + { +#if _WIN32 + auto version = GetPlatformVersion(); + + if (version.Major < 10 || version.Build <= 17763) + return; + + auto flag = version.Build >= 18985 + ? DWMWA_USE_IMMERSIVE_DARK_MODE + : 19; // DWMWA_USE_IMMERSIVE_DARK_MODE_BEFORE_20H1 + + const DWORD useImmersiveDarkMode = isEnabled; + DwmSetWindowAttribute(s_handle, flag, &useImmersiveDarkMode, sizeof(useImmersiveDarkMode)); +#endif + } + static bool IsFullscreen() { return SDL_GetWindowFlags(s_pWindow) & SDL_WINDOW_FULLSCREEN_DESKTOP; @@ -144,7 +167,7 @@ public: static uint32_t GetWindowFlags() { - uint32_t flags = SDL_WINDOW_SHOWN | SDL_WINDOW_RESIZABLE; + uint32_t flags = SDL_WINDOW_HIDDEN | SDL_WINDOW_RESIZABLE; if (Config::WindowState == EWindowState::Maximised) flags |= SDL_WINDOW_MAXIMIZED; diff --git a/UnleashedRecompResources b/UnleashedRecompResources index b04e3bdc..5b5ad279 160000 --- a/UnleashedRecompResources +++ b/UnleashedRecompResources @@ -1 +1 @@ -Subproject commit b04e3bdcd9e76a0717cec69822f4eb01cd97d5c6 +Subproject commit 5b5ad2794a2c78d50dc6a85e71954fb6b9e80ae2 diff --git a/vcpkg.json b/vcpkg.json index 1ca62733..d778cb96 100644 --- a/vcpkg.json +++ b/vcpkg.json @@ -22,7 +22,7 @@ "features": [ "sdl2-binding" ] }, "magic-enum", - "readerwriterqueue", - "nativefiledialog-extended" + "nativefiledialog-extended", + "miniaudio" ] }