diff --git a/.github/workflows/nightly.yml b/.github/workflows/nightly.yml index 0affa845e..df01b57af 100644 --- a/.github/workflows/nightly.yml +++ b/.github/workflows/nightly.yml @@ -35,4 +35,5 @@ jobs: with: tag_name: nightly name: Nightly Release - files: LCEWindows64.zip \ No newline at end of file + body: Compiled with MSVC v14.44.35207 in Release mode with Whole Program Optimization, as well as `/O2 /Ot /Oi /Ob3 /GF`. (So far the floating point model is `/fp:strict` to avoid undefined behavior before we refactor for performance). Requires at least Windows 7 and DirectX 11 compatible GPU to run. + files: LCEWindows64.zip diff --git a/CMakeLists.txt b/CMakeLists.txt index c3ae11260..74851754d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,6 +1,6 @@ cmake_minimum_required(VERSION 3.24) -project(MinecraftConsoles LANGUAGES C CXX ASM_MASM) +project(MinecraftConsoles LANGUAGES C CXX RC ASM_MASM) if(NOT WIN32) message(FATAL_ERROR "This CMake build currently supports Windows only.") @@ -12,11 +12,24 @@ endif() set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$:Debug>") +function(configure_msvc_target target) + target_compile_options(${target} PRIVATE + $<$>,$>:/W3> + $<$,$>:/W0> + $<$:/MP> + $<$:/EHsc> + $<$,$>:/GL /O2 /Oi /GT /GF> + ) +endfunction() + include("${CMAKE_CURRENT_SOURCE_DIR}/cmake/WorldSources.cmake") include("${CMAKE_CURRENT_SOURCE_DIR}/cmake/ClientSources.cmake") list(TRANSFORM MINECRAFT_WORLD_SOURCES PREPEND "${CMAKE_CURRENT_SOURCE_DIR}/Minecraft.World/") list(TRANSFORM MINECRAFT_CLIENT_SOURCES PREPEND "${CMAKE_CURRENT_SOURCE_DIR}/Minecraft.Client/") +list(APPEND MINECRAFT_CLIENT_SOURCES + "${CMAKE_CURRENT_SOURCE_DIR}/Minecraft.Client/Xbox/MinecraftWindows.rc" +) add_library(MinecraftWorld STATIC ${MINECRAFT_WORLD_SOURCES}) target_include_directories(MinecraftWorld PRIVATE @@ -28,11 +41,7 @@ target_compile_definitions(MinecraftWorld PRIVATE $<$>:_LARGE_WORLDS;_DEBUG_MENUS_ENABLED;_LIB;_CRT_NON_CONFORMING_SWPRINTFS;_CRT_SECURE_NO_WARNINGS;_WINDOWS64> ) if(MSVC) - target_compile_options(MinecraftWorld PRIVATE - $<$:/W3> - $<$:/MP> - $<$:/EHsc> - ) + configure_msvc_target(MinecraftWorld) endif() add_executable(MinecraftClient WIN32 ${MINECRAFT_CLIENT_SOURCES}) @@ -47,10 +56,9 @@ target_compile_definitions(MinecraftClient PRIVATE $<$>:_LARGE_WORLDS;_DEBUG_MENUS_ENABLED;_CRT_NON_CONFORMING_SWPRINTFS;_CRT_SECURE_NO_WARNINGS;_WINDOWS64> ) if(MSVC) - target_compile_options(MinecraftClient PRIVATE - $<$:/W3> - $<$:/MP> - $<$:/EHsc> + configure_msvc_target(MinecraftClient) + target_link_options(MinecraftClient PRIVATE + $<$:/LTCG /INCREMENTAL:NO> ) endif() diff --git a/Minecraft.Client/Common/UI/IUIScene_CreativeMenu.cpp b/Minecraft.Client/Common/UI/IUIScene_CreativeMenu.cpp index c3348e584..973020db2 100644 --- a/Minecraft.Client/Common/UI/IUIScene_CreativeMenu.cpp +++ b/Minecraft.Client/Common/UI/IUIScene_CreativeMenu.cpp @@ -845,8 +845,9 @@ IUIScene_CreativeMenu::TabSpec::TabSpec(LPCWSTR icon, int descriptionId, int sta } } - m_staticPerPage = MAX_SIZE - dynamicItems; - m_pages = (int)ceil((float)m_staticItems / m_staticPerPage); + m_staticPerPage = columns; + const int totalRows = (m_staticItems + columns - 1) / columns; + m_pages = std::max(1, totalRows - 5 + 1); } IUIScene_CreativeMenu::TabSpec::~TabSpec() diff --git a/Minecraft.Client/Extrax64Stubs.cpp b/Minecraft.Client/Extrax64Stubs.cpp index 23b2c7f0e..3a86cbeaf 100644 --- a/Minecraft.Client/Extrax64Stubs.cpp +++ b/Minecraft.Client/Extrax64Stubs.cpp @@ -200,7 +200,7 @@ DWORD IQNetPlayer::GetCurrentRtt() { return 0; } bool IQNetPlayer::IsHost() { return m_isHostPlayer; } bool IQNetPlayer::IsGuest() { return false; } bool IQNetPlayer::IsLocal() { return true; } -PlayerUID IQNetPlayer::GetXuid() { return INVALID_XUID; } +PlayerUID IQNetPlayer::GetXuid() { return (PlayerUID)(0xe000d45248242f2e + m_smallId); } // todo: restore to INVALID_XUID once saves support this extern wstring g_playerName; LPCWSTR IQNetPlayer::GetGamertag() { return g_playerName.empty() ? L"Windows" : g_playerName.c_str(); } int IQNetPlayer::GetSessionIndex() { return 0; } diff --git a/Minecraft.Client/Input.cpp b/Minecraft.Client/Input.cpp index 6933a2d70..1639d09b8 100644 --- a/Minecraft.Client/Input.cpp +++ b/Minecraft.Client/Input.cpp @@ -145,7 +145,7 @@ void Input::tick(LocalPlayer *player) // Delta should normally be 0 since applyFrameMouseLook() already consumed it if (rawDx != 0.0f || rawDy != 0.0f) { - float mouseSensitivity = 0.5f; + float mouseSensitivity = ((float)app.GetGameSettings(iPad, eGameSetting_Sensitivity_InGame)) / 100.0f; float mdx = rawDx * mouseSensitivity; float mdy = -rawDy * mouseSensitivity; if (app.GetGameSettings(iPad, eGameSetting_ControlInvertLook)) diff --git a/Minecraft.Client/LevelRenderer.h b/Minecraft.Client/LevelRenderer.h index 46a4c31fe..88280b1e4 100644 --- a/Minecraft.Client/LevelRenderer.h +++ b/Minecraft.Client/LevelRenderer.h @@ -52,7 +52,7 @@ public: static const int CHUNK_SIZE = 16; #endif static const int CHUNK_Y_COUNT = Level::maxBuildHeight / CHUNK_SIZE; -#if defined _XBOX_ONE +#if (defined _XBOX_ONE || defined _WINDOWS64) static const int MAX_COMMANDBUFFER_ALLOCATIONS = 2047 * 1024 * 1024; // Changed to 2047. 4J had set to 512. #elif defined __ORBIS__ static const int MAX_COMMANDBUFFER_ALLOCATIONS = 448 * 1024 * 1024; // 4J - added - hard limit is 512 so giving a lot of headroom here for fragmentation (have seen 16MB lost to fragmentation in multiplayer crash dump before) diff --git a/Minecraft.Client/Minecraft.Client.vcxproj b/Minecraft.Client/Minecraft.Client.vcxproj index 97befd61f..549156369 100644 --- a/Minecraft.Client/Minecraft.Client.vcxproj +++ b/Minecraft.Client/Minecraft.Client.vcxproj @@ -310,6 +310,7 @@ Application MultiByte v143 + true Application @@ -774,7 +775,7 @@ - true + false $(OutDir)$(ProjectName)_D.xex $(ProjectDir)\..\Minecraft.World\x64headers;$(ProjectDir)\Xbox\Sentient\Include;$(IncludePath) @@ -1754,9 +1755,9 @@ xcopy /q /y /i /s /e $(ProjectDir)DurangoMedia\CU $(LayoutDir)Image\Loose\CU Use - Level3 + TurnOffAllWarnings ProgramDatabase - Full + MaxSpeed Sync false $(OutDir)$(ProjectName).pch @@ -1769,6 +1770,10 @@ xcopy /q /y /i /s /e $(ProjectDir)DurangoMedia\CU $(LayoutDir)Image\Loose\CUDefault false Speed + true + true + true + /Ob3 true @@ -1776,6 +1781,7 @@ xcopy /q /y /i /s /e $(ProjectDir)DurangoMedia\CU $(LayoutDir)Image\Loose\CUlegacy_stdio_definitions.lib;d3d11.lib;..\Minecraft.World\x64_Release\Minecraft.World.lib;XInput9_1_0.lib;Windows64\Iggy\lib\iggy_w64.lib;%(AdditionalDependencies) NotSet false + UseLinkTimeCodeGeneration Run postbuild script diff --git a/Minecraft.Client/Minecraft.Client.vcxproj.filters b/Minecraft.Client/Minecraft.Client.vcxproj.filters index fe61baa45..2be7710a9 100644 --- a/Minecraft.Client/Minecraft.Client.vcxproj.filters +++ b/Minecraft.Client/Minecraft.Client.vcxproj.filters @@ -729,7 +729,6 @@ {e5d7fb24-25b8-413c-84ec-974bf0d4a3d1} - @@ -3617,7 +3616,7 @@ Common\Source Files\UI\Scenes - + Common\Source Files\Leaderboards diff --git a/Minecraft.Client/Minecraft.cpp b/Minecraft.Client/Minecraft.cpp index 87f1b8bee..bc9aec3b9 100644 --- a/Minecraft.Client/Minecraft.cpp +++ b/Minecraft.Client/Minecraft.cpp @@ -1191,7 +1191,7 @@ void Minecraft::applyFrameMouseLook() KMInput.ConsumeMouseDelta(rawDx, rawDy); if (rawDx == 0.0f && rawDy == 0.0f) continue; - float mouseSensitivity = 0.5f; + float mouseSensitivity = ((float)app.GetGameSettings(iPad, eGameSetting_Sensitivity_InGame)) / 100.0f; float mdx = rawDx * mouseSensitivity; float mdy = -rawDy * mouseSensitivity; if (app.GetGameSettings(iPad, eGameSetting_ControlInvertLook)) diff --git a/Minecraft.Client/Windows64/Windows64_Minecraft.cpp b/Minecraft.Client/Windows64/Windows64_Minecraft.cpp index a1bdcd0f6..b49af8535 100644 --- a/Minecraft.Client/Windows64/Windows64_Minecraft.cpp +++ b/Minecraft.Client/Windows64/Windows64_Minecraft.cpp @@ -431,90 +431,6 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) return TRUE; } return DefWindowProc(hWnd, message, wParam, lParam); - case WM_SIZE: - { - if (wParam == SIZE_MINIMIZED) - return 0; - - UINT width = LOWORD(lParam); - UINT height = HIWORD(lParam); - - if (width == 0 || height == 0) - return 0; - - g_ScreenWidth = width; - g_ScreenHeight = height; - - if (g_pSwapChain) - { - g_pImmediateContext->OMSetRenderTargets(0, 0, 0); - g_pImmediateContext->ClearState(); - g_pImmediateContext->Flush(); - - if (g_pRenderTargetView) - { - g_pRenderTargetView->Release(); - g_pRenderTargetView = nullptr; - } - - if (g_pDepthStencilView) - { - g_pDepthStencilView->Release(); - g_pDepthStencilView = nullptr; - } - - if (g_pDepthStencilBuffer) - { - g_pDepthStencilBuffer->Release(); - g_pDepthStencilBuffer = nullptr; - } - - HRESULT hr = g_pSwapChain->ResizeBuffers( - 0, - width, - height, - DXGI_FORMAT_UNKNOWN, - 0 - ); - - if (FAILED(hr)) - { - app.DebugPrintf("ResizeBuffers Failed! HRESULT: 0x%X\n", hr); - return 0; - } - - ID3D11Texture2D* pBackBuffer = nullptr; - g_pSwapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), (void**)&pBackBuffer); - - g_pd3dDevice->CreateRenderTargetView(pBackBuffer, NULL, &g_pRenderTargetView); - pBackBuffer->Release(); - - D3D11_TEXTURE2D_DESC descDepth = {}; - descDepth.Width = width; - descDepth.Height = height; - descDepth.MipLevels = 1; - descDepth.ArraySize = 1; - descDepth.Format = DXGI_FORMAT_D24_UNORM_S8_UINT; - descDepth.SampleDesc.Count = 1; - descDepth.BindFlags = D3D11_BIND_DEPTH_STENCIL; - - g_pd3dDevice->CreateTexture2D(&descDepth, NULL, &g_pDepthStencilBuffer); - g_pd3dDevice->CreateDepthStencilView(g_pDepthStencilBuffer, NULL, &g_pDepthStencilView); - - g_pImmediateContext->OMSetRenderTargets(1, &g_pRenderTargetView, g_pDepthStencilView); - - D3D11_VIEWPORT vp = {}; - vp.Width = (FLOAT)width; - vp.Height = (FLOAT)height; - vp.MinDepth = 0.0f; - vp.MaxDepth = 1.0f; - vp.TopLeftX = 0; - vp.TopLeftY = 0; - - g_pImmediateContext->RSSetViewports(1, &vp); - } - } - break; default: return DefWindowProc(hWnd, message, wParam, lParam); } @@ -805,20 +721,6 @@ void CleanupDevice() if( g_pd3dDevice ) g_pd3dDevice->Release(); } -typedef HRESULT(__stdcall* SetProcessDpiAwareness_f)(PROCESS_DPI_AWARENESS); -static HRESULT dyn_SetProcessDpiAwareness(PROCESS_DPI_AWARENESS value) -{ - static const auto ptr = reinterpret_cast( - reinterpret_cast(::GetProcAddress(static_cast(LoadLibraryExW(L"Shcore.dll", nullptr, 0)), "SetProcessDpiAwareness"))); - if (ptr == nullptr) - { - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return E_NOTIMPL; - } - - return ptr(value); -} - int APIENTRY _tWinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _In_ LPTSTR lpCmdLine, @@ -1370,7 +1272,15 @@ int APIENTRY _tWinMain(_In_ HINSTANCE hInstance, } } - // F3 toggles the debug console overlay, F11 toggles fullscreen + // F1 toggles the HUD, F3 toggles the debug console overlay, F11 toggles fullscreen + if (KMInput.IsKeyPressed(VK_F1)) + { + int primaryPad = ProfileManager.GetPrimaryPad(); + unsigned char displayHud = app.GetGameSettings(primaryPad, eGameSetting_DisplayHUD); + app.SetGameSettings(primaryPad, eGameSetting_DisplayHUD, displayHud ? 0 : 1); + app.SetGameSettings(primaryPad, eGameSetting_DisplayHand, displayHud ? 0 : 1); + } + if (KMInput.IsKeyPressed(VK_F3)) { static bool s_debugConsole = false; @@ -1397,7 +1307,7 @@ int APIENTRY _tWinMain(_In_ HINSTANCE hInstance, { { ui.NavigateToScene(0, eUIScene_InGameInfoMenu); - + } } } @@ -1420,7 +1330,7 @@ int APIENTRY _tWinMain(_In_ HINSTANCE hInstance, { if (Minecraft* pMinecraft = Minecraft::GetInstance()) { - if (pMinecraft->options && app.DebugSettingsOn() && + if (pMinecraft->options && app.DebugSettingsOn() && app.GetGameStarted() && !ui.GetMenuDisplayed(0) && pMinecraft->screen == NULL) { ui.NavigateToScene(0, eUIScene_DebugOverlay, NULL, eUILayer_Debug); diff --git a/Minecraft.Client/Windows64Media/Media/Tutorial.pck b/Minecraft.Client/Windows64Media/Tutorial/Tutorial.pck similarity index 100% rename from Minecraft.Client/Windows64Media/Media/Tutorial.pck rename to Minecraft.Client/Windows64Media/Tutorial/Tutorial.pck diff --git a/Minecraft.Client/Xbox/Xbox_App.cpp b/Minecraft.Client/Xbox/Xbox_App.cpp index b252035e6..a342d8c2e 100644 --- a/Minecraft.Client/Xbox/Xbox_App.cpp +++ b/Minecraft.Client/Xbox/Xbox_App.cpp @@ -1658,7 +1658,8 @@ HRESULT CConsoleMinecraftApp::NavigateToScene(int iPad,EUIScene eScene, void *in // If you're navigating to the multigamejoinload, and the player hasn't seen the updates message yet, display it now // display this message the first 3 times - if((eScene==eUIScene_LoadOrJoinMenu) && (bSeenUpdateTextThisSession==false) && ( app.GetGameSettings(ProfileManager.GetPrimaryPad(),eGameSetting_DisplayUpdateMessage)!=0)) + // todo: re-enable if we fix this menu, for now its just blank! + if(false && (eScene==eUIScene_LoadOrJoinMenu) && (bSeenUpdateTextThisSession==false) && ( app.GetGameSettings(ProfileManager.GetPrimaryPad(),eGameSetting_DisplayUpdateMessage)!=0)) { eScene=eUIScene_NewUpdateMessage; bSeenUpdateTextThisSession=true; diff --git a/Minecraft.Client/glWrapper.cpp b/Minecraft.Client/glWrapper.cpp index 5e0fab2c6..540271b91 100644 --- a/Minecraft.Client/glWrapper.cpp +++ b/Minecraft.Client/glWrapper.cpp @@ -48,12 +48,12 @@ void glLoadIdentity() RenderManager.MatrixSetIdentity(); } -extern UINT g_ScreenWidth; -extern UINT g_ScreenHeight; +extern int g_iScreenWidth; +extern int g_iScreenHeight; void gluPerspective(float fovy, float aspect, float zNear, float zFar) { - float dynamicAspect = (float)g_ScreenWidth / (float)g_ScreenHeight; + float dynamicAspect = (float)g_iScreenWidth / (float)g_iScreenHeight; RenderManager.MatrixPerspective(fovy, dynamicAspect, zNear, zFar); } diff --git a/Minecraft.World/MapItemSavedData.cpp b/Minecraft.World/MapItemSavedData.cpp index 6304aa624..981bab3e2 100644 --- a/Minecraft.World/MapItemSavedData.cpp +++ b/Minecraft.World/MapItemSavedData.cpp @@ -596,7 +596,14 @@ void MapItemSavedData::mergeInMapData(shared_ptr dataToAdd) void MapItemSavedData::removeItemFrameDecoration(shared_ptr item) { - AUTO_VAR(frameDecoration, nonPlayerDecorations.find( item->getFrame()->entityId ) ); + if ( !item ) + return; + + std::shared_ptr frame = item->getFrame(); + if ( !frame ) + return; + + auto frameDecoration = nonPlayerDecorations.find(frame->entityId); if ( frameDecoration != nonPlayerDecorations.end() ) { delete frameDecoration->second; diff --git a/Minecraft.World/Minecraft.World.vcxproj b/Minecraft.World/Minecraft.World.vcxproj index c9516552c..58880529c 100644 --- a/Minecraft.World/Minecraft.World.vcxproj +++ b/Minecraft.World/Minecraft.World.vcxproj @@ -307,6 +307,7 @@ StaticLibrary MultiByte v143 + true StaticLibrary @@ -1336,9 +1337,9 @@ Use - Level3 + TurnOffAllWarnings ProgramDatabase - Full + MaxSpeed Sync false $(OutDir)$(ProjectName).pch @@ -1351,6 +1352,10 @@ true Default Speed + true + true + true + /Ob3 true diff --git a/README.md b/README.md index 84d0186d8..999626e9a 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # MinecraftConsoles -[![Discord](https://img.shields.io/badge/Discord-Join%20Server-5865F2?logo=discord&logoColor=white)](https://discord.gg/5CSzhc9t) +[![Discord](https://img.shields.io/badge/Discord-Join%20Server-5865F2?logo=discord&logoColor=white)](https://discord.gg/jrum7HhegA) ![Tutorial World](.github/TutorialWorld.png) @@ -61,6 +61,7 @@ This feature is based on [LCEMP](https://github.com/LCEMP/LCEMP/) - **Select Item**: `Mouse Wheel` or keys `1` to `9` - **Accept or Decline Tutorial hints**: `Enter` to accept and `B` to decline - **Game Info (Player list and Host Options)**: `TAB` +- **Toggle HUD**: `F1` - **Toggle Debug Info**: `F3` - **Open Debug Overlay**: `F4` diff --git a/cmake/ClientSources.cmake b/cmake/ClientSources.cmake index f56b7ef08..c75b3bf34 100644 --- a/cmake/ClientSources.cmake +++ b/cmake/ClientSources.cmake @@ -476,6 +476,7 @@ set(MINECRAFT_CLIENT_SOURCES "Windows64/Windows64_App.cpp" "Windows64/Windows64_Minecraft.cpp" "Windows64/Windows64_UIController.cpp" + "Windows64/Network/WinsockNetLayer.cpp" "WitchModel.cpp" "WitchRenderer.cpp" "WitherBossModel.cpp" diff --git a/cmake/CopyAssets.cmake b/cmake/CopyAssets.cmake index 47b19ca79..a0252f730 100644 --- a/cmake/CopyAssets.cmake +++ b/cmake/CopyAssets.cmake @@ -12,9 +12,28 @@ set(_project_dir "${PROJECT_SOURCE_DIR}/Minecraft.Client") function(copy_tree_if_exists src_rel dst_rel) set(_src "${_project_dir}/${src_rel}") set(_dst "${OUTPUT_DIR}/${dst_rel}") + if(EXISTS "${_src}") file(MAKE_DIRECTORY "${_dst}") - execute_process(COMMAND "${CMAKE_COMMAND}" -E copy_directory "${_src}" "${_dst}") + file(GLOB_RECURSE _files RELATIVE "${_src}" "${_src}/*") + + foreach(_file IN LISTS _files) # if not a source file + if(NOT _file MATCHES "\\.(cpp|c|h|hpp|xml|lang)$") + set(_full_src "${_src}/${_file}") + set(_full_dst "${_dst}/${_file}") + + if(IS_DIRECTORY "${_full_src}") + file(MAKE_DIRECTORY "${_full_dst}") + else() + get_filename_component(_dst_dir "${_full_dst}" DIRECTORY) + file(MAKE_DIRECTORY "${_dst_dir}") + execute_process( + COMMAND "${CMAKE_COMMAND}" -E copy_if_different + "${_full_src}" "${_full_dst}" + ) + endif() + endif() + endforeach() endif() endfunction() @@ -25,10 +44,15 @@ endfunction() function(copy_file_if_exists src_rel dst_rel) set(_src "${PROJECT_SOURCE_DIR}/${src_rel}") set(_dst "${OUTPUT_DIR}/${dst_rel}") + + get_filename_component(_dst_dir "${_dst}" DIRECTORY) + file(MAKE_DIRECTORY "${_dst_dir}") + if(EXISTS "${_src}") - get_filename_component(_dst_dir "${_dst}" DIRECTORY) - file(MAKE_DIRECTORY "${_dst_dir}") - execute_process(COMMAND "${CMAKE_COMMAND}" -E copy_if_different "${_src}" "${_dst}") + execute_process( + COMMAND "${CMAKE_COMMAND}" -E copy_if_different + "${_src}" "${_dst}" + ) endif() endfunction() @@ -46,24 +70,24 @@ function(copy_first_existing dst_rel) endif() endfunction() -if(CONFIGURATION STREQUAL "Debug") - copy_tree_if_exists("Durango/Sound" "Durango/Sound") - copy_tree_if_exists("music" "music") - copy_tree_if_exists("Windows64/GameHDD" "Windows64/GameHDD") - copy_tree_if_exists("Common/Media" "Common/Media") - copy_tree_if_exists("Common/res" "Common/res") - copy_tree_if_exists("Common/Trial" "Common/Trial") - copy_tree_if_exists("Common/Tutorial" "Common/Tutorial") -else() - copy_tree_if_exists("music" "music") - copy_tree_if_exists("Windows64/GameHDD" "Windows64/GameHDD") - copy_tree_if_exists("Common/Media" "Common/Media") - copy_tree_if_exists("Common/res" "Common/res") - copy_tree_if_exists("Common/Trial" "Common/Trial") - copy_tree_if_exists("Common/Tutorial" "Common/Tutorial") - copy_tree_if_exists("DurangoMedia" "Windows64Media") - copy_tree_if_exists("Windows64Media" "Windows64Media") -endif() +function(remove_directory_if_exists rel_path) + set(_dir "${OUTPUT_DIR}/${rel_path}") + if(EXISTS "${_dir}") + file(REMOVE_RECURSE "${_dir}") + endif() +endfunction() + +copy_tree_if_exists("Durango/Sound" "Windows64/Sound") +copy_tree_if_exists("music" "music") +copy_tree_if_exists("Windows64/GameHDD" "Windows64/GameHDD") +copy_file_if_exists("Minecraft.Client/Common/Media/MediaWindows64.arc" "Common/Media/MediaWindows64.arc") +copy_tree_if_exists("Common/res" "Common/res") +copy_tree_if_exists("Common/Trial" "Common/Trial") +copy_tree_if_exists("Common/Tutorial" "Common/Tutorial") +copy_tree_if_exists("DurangoMedia" "Windows64Media") +copy_tree_if_exists("Windows64Media" "Windows64Media") + +remove_directory_if_exists("Windows64Media/Layout") # Some runtime code asserts if this directory tree is missing. ensure_dir("Windows64/GameHDD")