diff --git a/targets/app/common/DLC/DLCPack.cpp b/targets/app/common/DLC/DLCPack.cpp index 15b1a6c81..97c6ac41c 100644 --- a/targets/app/common/DLC/DLCPack.cpp +++ b/targets/app/common/DLC/DLCPack.cpp @@ -21,7 +21,6 @@ #include "app/common/DLC/DLCSkinFile.h" #include "minecraft/locale/StringTable.h" #include "app/linux/LinuxGame.h" -#include "app/linux/Stubs/winapi_stubs.h" #include "util/StringHelpers.h" DLCPack::DLCPack(const std::string& name, std::uint32_t dwLicenseMask) { diff --git a/targets/app/common/DLCController.cpp b/targets/app/common/DLCController.cpp index 13bfa6cf7..69aea9f52 100644 --- a/targets/app/common/DLCController.cpp +++ b/targets/app/common/DLCController.cpp @@ -6,7 +6,6 @@ #include "app/common/DLC/DLCSkinFile.h" #include "app/linux/LinuxGame.h" #include "app/linux/Linux_UIController.h" -#include "app/linux/Stubs/winapi_stubs.h" #include "minecraft/client/Minecraft.h" #include "minecraft/client/skins/TexturePack.h" #include "minecraft/client/skins/TexturePackRepository.h" @@ -105,7 +104,7 @@ void DLCController::mountNextDLC(int iPad) { [this](int pad, std::uint32_t dwErr, std::uint32_t dwLicenceMask) { return dlcMountedCallback(pad, dwErr, dwLicenceMask); - }) != ERROR_IO_PENDING) { + }) != 997 /* ERROR_IO_PENDING */) { app.DebugPrintf("Failed to mount DLC %d for pad %d\n", m_iTotalDLCInstalled, iPad); ++m_iTotalDLCInstalled; @@ -131,7 +130,7 @@ int DLCController::dlcMountedCallback(int iPad, std::uint32_t dwErr, #if defined(_WINDOWS64) app.DebugPrintf("--- DLCController::dlcMountedCallback\n"); - if (dwErr != ERROR_SUCCESS) { + if (dwErr != 0 /* ERROR_SUCCESS */) { app.DebugPrintf("Failed to mount DLC for pad %d: %u\n", iPad, dwErr); app.m_dlcManager.incrementUnnamedCorruptCount(); } else { diff --git a/targets/app/common/Game.cpp b/targets/app/common/Game.cpp index 28eaa47bb..9dbb035e5 100644 --- a/targets/app/common/Game.cpp +++ b/targets/app/common/Game.cpp @@ -20,7 +20,6 @@ #include "app/common/UI/Scenes/UIScene_FullscreenProgress.h" #include "app/linux/LinuxGame.h" #include "app/linux/Linux_UIController.h" -#include "app/linux/Stubs/winapi_stubs.h" #include "platform/NetTypes.h" #include "minecraft/client/model/SkinBox.h" #include "platform/XboxStubs.h" diff --git a/targets/app/common/GameRules/LevelGeneration/ConsoleSchematicFile.cpp b/targets/app/common/GameRules/LevelGeneration/ConsoleSchematicFile.cpp index aee9d428c..df109f509 100644 --- a/targets/app/common/GameRules/LevelGeneration/ConsoleSchematicFile.cpp +++ b/targets/app/common/GameRules/LevelGeneration/ConsoleSchematicFile.cpp @@ -9,7 +9,6 @@ #include #include "app/linux/LinuxGame.h" -#include "app/linux/Stubs/winapi_stubs.h" #include "minecraft/world/level/storage/ConsoleSaveFileIO/compression.h" #include "java/Class.h" #include "java/InputOutputStream/DataInputStream.h" diff --git a/targets/app/common/GameRules/LevelGeneration/ConsoleSchematicFile.h b/targets/app/common/GameRules/LevelGeneration/ConsoleSchematicFile.h index 6c788f700..bfc5c0cae 100644 --- a/targets/app/common/GameRules/LevelGeneration/ConsoleSchematicFile.h +++ b/targets/app/common/GameRules/LevelGeneration/ConsoleSchematicFile.h @@ -15,7 +15,6 @@ #include "minecraft/XuiActionPayload.h" -#include "app/linux/Stubs/winapi_stubs.h" #include "minecraft/world/level/storage/ConsoleSaveFileIO/compression.h" #include "minecraft/world/phys/Vec3.h" diff --git a/targets/app/common/GameRules/LevelGeneration/LevelGenerationOptions.cpp b/targets/app/common/GameRules/LevelGeneration/LevelGenerationOptions.cpp index a7ff792f0..a68e1de49 100644 --- a/targets/app/common/GameRules/LevelGeneration/LevelGenerationOptions.cpp +++ b/targets/app/common/GameRules/LevelGeneration/LevelGenerationOptions.cpp @@ -19,7 +19,6 @@ #include "minecraft/world/level/GameRules/GameRuleDefinition.h" #include "minecraft/locale/StringTable.h" #include "app/linux/LinuxGame.h" -#include "app/linux/Stubs/winapi_stubs.h" #include "java/File.h" #include "java/InputOutputStream/ByteArrayInputStream.h" #include "java/InputOutputStream/DataInputStream.h" @@ -556,7 +555,7 @@ void LevelGenerationOptions::loadBaseSaveData() { [this](int pad, std::uint32_t err, std::uint32_t lic) { return onPackMounted(pad, err, lic); }, - "WPACK") != ERROR_IO_PENDING) { + "WPACK") != 997 /* ERROR_IO_PENDING */) { // corrupt DLC setLoadedData(); app.DebugPrintf("Failed to mount LGO DLC %d for pad %d\n", @@ -577,7 +576,7 @@ int LevelGenerationOptions::onPackMounted(int iPad, uint32_t dwErr, uint32_t dwLicenceMask) { LevelGenerationOptions* lgo = this; lgo->m_bLoadingData = false; - if (dwErr != ERROR_SUCCESS) { + if (dwErr != 0 /* ERROR_SUCCESS */) { // corrupt DLC app.DebugPrintf("Failed to mount LGO DLC for pad %d: %d\n", iPad, dwErr); diff --git a/targets/app/common/GameRules/LevelRules/Rules/GameRule.cpp b/targets/app/common/GameRules/LevelRules/Rules/GameRule.cpp index 8e4a5f28b..fa035db9e 100644 --- a/targets/app/common/GameRules/LevelRules/Rules/GameRule.cpp +++ b/targets/app/common/GameRules/LevelRules/Rules/GameRule.cpp @@ -9,7 +9,6 @@ #include #include "minecraft/world/level/GameRules/GameRuleDefinition.h" -#include "app/linux/Stubs/winapi_stubs.h" #include "java/InputOutputStream/DataInputStream.h" #include "java/InputOutputStream/DataOutputStream.h" diff --git a/targets/app/common/Localisation/StringTable.cpp b/targets/app/common/Localisation/StringTable.cpp index beb418cbc..e0e1bcae7 100644 --- a/targets/app/common/Localisation/StringTable.cpp +++ b/targets/app/common/Localisation/StringTable.cpp @@ -4,7 +4,6 @@ #include #include "app/linux/LinuxGame.h" -#include "app/linux/Stubs/winapi_stubs.h" #include "java/InputOutputStream/ByteArrayInputStream.h" #include "java/InputOutputStream/DataInputStream.h" diff --git a/targets/app/common/MenuController.cpp b/targets/app/common/MenuController.cpp index f4cfed459..0aafa2219 100644 --- a/targets/app/common/MenuController.cpp +++ b/targets/app/common/MenuController.cpp @@ -6,7 +6,6 @@ #include "app/common/UI/Scenes/UIScene_FullscreenProgress.h" #include "app/linux/LinuxGame.h" #include "app/linux/Linux_UIController.h" -#include "app/linux/Stubs/winapi_stubs.h" #include "minecraft/client/Minecraft.h" #include "minecraft/client/ProgressRenderer.h" #include "minecraft/client/renderer/GameRenderer.h" @@ -498,7 +497,7 @@ int MenuController::remoteSaveThreadProc(void* lpParameter) { if (app.GetXuiAction(PlatformProfile.GetPrimaryPad()) != eAppAction_WaitRemoteServerSaveComplete) { - return ERROR_CANCELLED; + return 1223; // ERROR_CANCELLED } app.SetAction(PlatformProfile.GetPrimaryPad(), eAppAction_Idle); diff --git a/targets/app/common/Network/GameNetworkManager.cpp b/targets/app/common/Network/GameNetworkManager.cpp index ed88a05c7..a26907f0c 100644 --- a/targets/app/common/Network/GameNetworkManager.cpp +++ b/targets/app/common/Network/GameNetworkManager.cpp @@ -24,7 +24,6 @@ #include "app/common/UI/Scenes/In-Game Menu Screens/UIScene_PauseMenu.h" #include "app/linux/LinuxGame.h" #include "app/linux/Linux_UIController.h" -#include "app/linux/Stubs/winapi_stubs.h" #include "Socket.h" #include "platform/XboxStubs.h" #include "util/StringHelpers.h" diff --git a/targets/app/common/Network/PlatformNetworkManagerStub.cpp b/targets/app/common/Network/PlatformNetworkManagerStub.cpp index 3ae7bb298..15108e8b9 100644 --- a/targets/app/common/Network/PlatformNetworkManagerStub.cpp +++ b/targets/app/common/Network/PlatformNetworkManagerStub.cpp @@ -8,7 +8,6 @@ #include "app/common/Network/GameNetworkManager.h" #include "minecraft/network/platform/NetworkPlayerInterface.h" #include "app/linux/LinuxGame.h" -#include "app/linux/Stubs/winapi_stubs.h" #include "platform/NetTypes.h" #include "NetworkPlayerQNet.h" #include "Socket.h" diff --git a/targets/app/common/UI/All Platforms/ArchiveFile.cpp b/targets/app/common/UI/All Platforms/ArchiveFile.cpp index 445dcd085..af1034a2c 100644 --- a/targets/app/common/UI/All Platforms/ArchiveFile.cpp +++ b/targets/app/common/UI/All Platforms/ArchiveFile.cpp @@ -6,7 +6,6 @@ #include #include "app/linux/LinuxGame.h" -#include "app/linux/Stubs/winapi_stubs.h" #include "platform/fs/fs.h" #include "minecraft/world/level/storage/ConsoleSaveFileIO/compression.h" #include "java/InputOutputStream/ByteArrayInputStream.h" diff --git a/targets/app/common/UI/All Platforms/IUIScene_CraftingMenu.cpp b/targets/app/common/UI/All Platforms/IUIScene_CraftingMenu.cpp index 1b8bc6270..1affdedf7 100644 --- a/targets/app/common/UI/All Platforms/IUIScene_CraftingMenu.cpp +++ b/targets/app/common/UI/All Platforms/IUIScene_CraftingMenu.cpp @@ -12,7 +12,6 @@ #include "app/common/UI/All Platforms/UIEnums.h" #include "app/linux/LinuxGame.h" #include "app/linux/Linux_UIController.h" -#include "app/linux/Stubs/winapi_stubs.h" #include "minecraft/GameEnums.h" #include "minecraft/client/Minecraft.h" #include "minecraft/client/multiplayer/MultiPlayerGameMode.h" diff --git a/targets/app/common/UI/All Platforms/IUIScene_PauseMenu.cpp b/targets/app/common/UI/All Platforms/IUIScene_PauseMenu.cpp index b6dd3b624..ad1c9c2f6 100644 --- a/targets/app/common/UI/All Platforms/IUIScene_PauseMenu.cpp +++ b/targets/app/common/UI/All Platforms/IUIScene_PauseMenu.cpp @@ -18,7 +18,6 @@ #include "app/common/UI/UIScene.h" #include "app/linux/LinuxGame.h" #include "app/linux/Linux_UIController.h" -#include "app/linux/Stubs/winapi_stubs.h" #include "minecraft/world/level/storage/ConsoleSaveFileIO/compression.h" #include "minecraft/client/Minecraft.h" #include "minecraft/client/ProgressRenderer.h" @@ -243,7 +242,7 @@ int IUIScene_PauseMenu::SaveWorldThreadProc(void* lpParameter) { if (app.GetChangingSessionType()) { // 4J Stu - This causes the fullscreenprogress scene to ignore the // action it was given - hr = ERROR_CANCELLED; + hr = 1223; // ERROR_CANCELLED } return hr; } diff --git a/targets/app/common/UI/Scenes/Frontend Menu screens/UIScene_LeaderboardsMenu.cpp b/targets/app/common/UI/Scenes/Frontend Menu screens/UIScene_LeaderboardsMenu.cpp index 16f22f310..7fa6ef461 100644 --- a/targets/app/common/UI/Scenes/Frontend Menu screens/UIScene_LeaderboardsMenu.cpp +++ b/targets/app/common/UI/Scenes/Frontend Menu screens/UIScene_LeaderboardsMenu.cpp @@ -18,7 +18,6 @@ #include "app/common/UI/UIScene.h" #include "app/linux/LinuxGame.h" #include "app/linux/Linux_UIController.h" -#include "app/linux/Stubs/winapi_stubs.h" #include "minecraft/sounds/SoundTypes.h" #include "minecraft/world/item/Item.h" #include "minecraft/world/item/ItemInstance.h" diff --git a/targets/app/common/UI/Scenes/Frontend Menu screens/UIScene_MainMenu.cpp b/targets/app/common/UI/Scenes/Frontend Menu screens/UIScene_MainMenu.cpp index 4beac9a53..d7300605e 100644 --- a/targets/app/common/UI/Scenes/Frontend Menu screens/UIScene_MainMenu.cpp +++ b/targets/app/common/UI/Scenes/Frontend Menu screens/UIScene_MainMenu.cpp @@ -1,7 +1,9 @@ #include "UIScene_MainMenu.h" +#include #include +#include #include #include #include @@ -20,7 +22,6 @@ #include "app/common/UI/UIString.h" #include "app/linux/LinuxGame.h" #include "app/linux/Linux_UIController.h" -#include "app/linux/Stubs/winapi_stubs.h" #include "platform/NetTypes.h" #include "util/StringHelpers.h" @@ -176,18 +177,21 @@ void UIScene_MainMenu::handleGainFocus(bool navBack) { random->nextInt((int)m_splashes.size() - (eSplashRandomStart + 1)); // Override splash text on certain dates - SYSTEMTIME LocalSysTime; - GetLocalTime(&LocalSysTime); - if (LocalSysTime.wMonth == 11 && LocalSysTime.wDay == 9) { + const std::time_t now = std::chrono::system_clock::to_time_t( + std::chrono::system_clock::now()); + std::tm localTime; + localtime_r(&now, &localTime); + const int month = localTime.tm_mon + 1; // tm_mon is 0-based + const int day = localTime.tm_mday; + if (month == 11 && day == 9) { splashIndex = eSplashHappyBirthdayEx; - } else if (LocalSysTime.wMonth == 6 && LocalSysTime.wDay == 1) { + } else if (month == 6 && day == 1) { splashIndex = eSplashHappyBirthdayNotch; - } else if (LocalSysTime.wMonth == 12 && - LocalSysTime.wDay == 24) // the Java game shows this on - // Christmas Eve, so we will too + } else if (month == 12 && day == 24) // the Java game shows this on + // Christmas Eve, so we will too { splashIndex = eSplashMerryXmas; - } else if (LocalSysTime.wMonth == 1 && LocalSysTime.wDay == 1) { + } else if (month == 1 && day == 1) { splashIndex = eSplashHappyNewYear; } // splashIndex = 47; // Very short string diff --git a/targets/app/common/UI/Scenes/In-Game Menu Screens/UIScene_InGameInfoMenu.cpp b/targets/app/common/UI/Scenes/In-Game Menu Screens/UIScene_InGameInfoMenu.cpp index 482caabdf..05bbaa567 100644 --- a/targets/app/common/UI/Scenes/In-Game Menu Screens/UIScene_InGameInfoMenu.cpp +++ b/targets/app/common/UI/Scenes/In-Game Menu Screens/UIScene_InGameInfoMenu.cpp @@ -16,7 +16,6 @@ #include "app/common/UI/UIScene.h" #include "app/linux/LinuxGame.h" #include "app/linux/Linux_UIController.h" -#include "app/linux/Stubs/winapi_stubs.h" #include "minecraft/client/Minecraft.h" #include "minecraft/client/multiplayer/ClientConnection.h" #include "minecraft/client/multiplayer/MultiPlayerLocalPlayer.h" diff --git a/targets/app/common/UI/Scenes/UIScene_FullscreenProgress.cpp b/targets/app/common/UI/Scenes/UIScene_FullscreenProgress.cpp index 9c64047a4..803a001eb 100644 --- a/targets/app/common/UI/Scenes/UIScene_FullscreenProgress.cpp +++ b/targets/app/common/UI/Scenes/UIScene_FullscreenProgress.cpp @@ -16,7 +16,6 @@ #include "app/common/UI/UIScene.h" #include "app/linux/LinuxGame.h" #include "app/linux/Linux_UIController.h" -#include "app/linux/Stubs/winapi_stubs.h" #include "platform/C4JThread.h" #include "minecraft/client/Minecraft.h" #include "minecraft/client/ProgressRenderer.h" @@ -166,7 +165,7 @@ void UIScene_FullscreenProgress::tick() { // If we failed (currently used by network connection thread), navigate // back if (exitcode != 0) { - if (exitcode == ERROR_CANCELLED) { + if (exitcode == 1223 /* ERROR_CANCELLED */) { // Current thread cancelled for whatever reason // Currently used only for the // Game::RemoteSaveThreadProc thread Assume to diff --git a/targets/app/common/UI/UIScene.cpp b/targets/app/common/UI/UIScene.cpp index 148d8f930..00677e4b8 100644 --- a/targets/app/common/UI/UIScene.cpp +++ b/targets/app/common/UI/UIScene.cpp @@ -20,7 +20,6 @@ #include "app/linux/Iggy/include/rrCore.h" #include "app/linux/LinuxGame.h" #include "app/linux/Linux_UIController.h" -#include "app/linux/Stubs/winapi_stubs.h" #include "java/System.h" #include "minecraft/client/Lighting.h" #include "minecraft/client/Minecraft.h" diff --git a/targets/app/linux/Stubs/winapi_stubs.h b/targets/app/linux/Stubs/winapi_stubs.h deleted file mode 100644 index 52ef81a12..000000000 --- a/targets/app/linux/Stubs/winapi_stubs.h +++ /dev/null @@ -1,179 +0,0 @@ -#ifndef WINAPISTUBS_H -#define WINAPISTUBS_H - -#pragma once - -#include -#include -#include -#include -#include - -#include -#include - -typedef struct { - int32_t LowPart; - int32_t HighPart; - int64_t QuadPart; -} LARGE_INTEGER; - -typedef struct { - uint32_t LowPart; - uint32_t HighPart; - uint64_t QuadPart; -} ULARGE_INTEGER; - -#define ERROR_SUCCESS 0L -#define ERROR_IO_PENDING 997L // dderror -#define ERROR_CANCELLED 1223L - -#define MEM_COMMIT 0x1000 -#define MEM_RESERVE 0x2000 -#define MEM_DECOMMIT 0x4000 -#define PAGE_READWRITE 0x04 - -// https://learn.microsoft.com/en-us/windows/win32/api/minwinbase/ns-minwinbase-filetime -typedef struct _FILETIME { - int32_t dwLowDateTime; - int32_t dwHighDateTime; -} FILETIME, *PFILETIME, *LPFILETIME; - -// https://learn.microsoft.com/en-us/windows/win32/api/minwinbase/ns-minwinbase-systemtime -typedef struct _SYSTEMTIME { - int16_t wYear; - int16_t wMonth; - int16_t wDayOfWeek; - int16_t wDay; - int16_t wHour; - int16_t wMinute; - int16_t wSecond; - int16_t wMilliseconds; -} SYSTEMTIME, *PSYSTEMTIME, *LPSYSTEMTIME; - -#ifdef __LP64__ -static inline int64_t InterlockedCompareExchangeRelease64( - int64_t volatile* Destination, int64_t Exchange, int64_t Comperand) { - int64_t expected = Comperand; - __atomic_compare_exchange_n(Destination, &expected, Exchange, false, - __ATOMIC_RELEASE, __ATOMIC_RELAXED); - return expected; -} -#else -static inline int64_t InterlockedCompareExchangeRelease( - LONG volatile* Destination, LONG Exchange, LONG Comperand) { - LONG expected = Comperand; - __atomic_compare_exchange_n(Destination, &expected, Exchange, false, - __ATOMIC_RELEASE, __ATOMIC_RELAXED); - return expected; -} -#endif - -// internal helper: convert time_t to FILETIME (100ns intervals since -// 1601-01-01) -static inline FILETIME _TimeToFileTime(time_t t) { - const uint64_t EPOCH_DIFF = 11644473600ULL; - uint64_t val = ((uint64_t)t + EPOCH_DIFF) * 10000000ULL; - FILETIME ft; - ft.dwLowDateTime = (int32_t)(val & 0xFFFFFFFF); - ft.dwHighDateTime = (int32_t)(val >> 32); - return ft; -} - -// internal helper: convert FILETIME (100ns since 1601) to time_t (seconds since -// 1970) -static inline time_t _FileTimeToTimeT(const FILETIME& ft) { - uint64_t val = ((uint64_t)ft.dwHighDateTime << 32) | ft.dwLowDateTime; - const uint64_t EPOCH_DIFF = - 116444736000000000ULL; // 100ns intervals between 1601-01-01 and - // 1970-01-01 - return (time_t)((val - EPOCH_DIFF) / 10000000ULL); -} - -// internal helper: read the current wall clock into a timespec -static inline void _CurrentTimeSpec(struct timespec* ts) { -#ifdef CLOCK_REALTIME - clock_gettime(CLOCK_REALTIME, ts); -#else - struct timeval tv; - gettimeofday(&tv, nullptr); - ts->tv_sec = tv.tv_sec; - ts->tv_nsec = tv.tv_usec * 1000; -#endif -} - -// internal helper: fill SYSTEMTIME from a broken-down tm + nanosecond remainder -static inline void _FillSystemTime(const struct tm* tm, long tv_nsec, - LPSYSTEMTIME lpSystemTime) { - lpSystemTime->wYear = tm->tm_year + 1900; - lpSystemTime->wMonth = tm->tm_mon + 1; - lpSystemTime->wDayOfWeek = tm->tm_wday; // 0 = Sunday - lpSystemTime->wDay = tm->tm_mday; - lpSystemTime->wHour = tm->tm_hour; - lpSystemTime->wMinute = tm->tm_min; - lpSystemTime->wSecond = tm->tm_sec; - lpSystemTime->wMilliseconds = (int16_t)(tv_nsec / 1000000); // ns to ms -} - -// https://learn.microsoft.com/en-us/windows/win32/api/sysinfoapi/nf-sysinfoapi-getlocaltime -static inline void GetLocalTime(LPSYSTEMTIME lpSystemTime) { - struct timespec ts; - _CurrentTimeSpec(&ts); - struct tm tm; - localtime_r(&ts.tv_sec, &tm); // local time - _FillSystemTime(&tm, ts.tv_nsec, lpSystemTime); -} - -// https://learn.microsoft.com/en-us/windows/win32/api/timezoneapi/nf-timezoneapi-filetimetosystemtime -static inline bool FileTimeToSystemTime(const FILETIME* lpFileTime, - LPSYSTEMTIME lpSystemTime) { - uint64_t ft = ((uint64_t)lpFileTime->dwHighDateTime << 32) | - lpFileTime->dwLowDateTime; - time_t t = _FileTimeToTimeT(*lpFileTime); - long remainder_ns = (long)((ft % 10000000ULL) * 100); - - struct tm tm; - gmtime_r(&t, &tm); // UTC - _FillSystemTime(&tm, remainder_ns, lpSystemTime); - return true; -} - -static inline void* VirtualAlloc(void* lpAddress, size_t dwSize, - int32_t flAllocationType, int32_t flProtect) { - // MEM_COMMIT | MEM_RESERVE → mmap anonymous - int prot = 0; - if (flProtect == 0x04 /*PAGE_READWRITE*/) - prot = PROT_READ | PROT_WRITE; - else if (flProtect == 0x40 /*PAGE_EXECUTE_READWRITE*/) - prot = PROT_READ | PROT_WRITE | PROT_EXEC; - else if (flProtect == 0x02 /*PAGE_READONLY*/) - prot = PROT_READ; - else - prot = PROT_READ | PROT_WRITE; // default - - int flags = MAP_PRIVATE | MAP_ANONYMOUS; - if (lpAddress != nullptr) flags |= MAP_FIXED; - - void* p = mmap(lpAddress, dwSize, prot, flags, -1, 0); - if (p == MAP_FAILED) return nullptr; - return p; -} - -static inline bool VirtualFree(void* lpAddress, size_t dwSize, - int32_t dwFreeType) { - if (lpAddress == nullptr) return false; - // MEM_RELEASE (0x8000) frees the whole region - if (dwFreeType == 0x8000 /*MEM_RELEASE*/) { - // dwSize should be 0 for MEM_RELEASE per Win32 API, but we don't track - // allocation sizes Use dwSize if provided, otherwise this is a - // best-effort - if (dwSize == 0) dwSize = 4096; // minimum page - munmap(lpAddress, dwSize); - } else { - // MEM_DECOMMIT (0x4000) - just decommit (make inaccessible) - madvise(lpAddress, dwSize, MADV_DONTNEED); - } - return true; -} - -#endif // WINAPISTUBS_H diff --git a/targets/minecraft/client/BufferedImage.cpp b/targets/minecraft/client/BufferedImage.cpp index 3e2ab00c9..07a8d5b7b 100644 --- a/targets/minecraft/client/BufferedImage.cpp +++ b/targets/minecraft/client/BufferedImage.cpp @@ -11,7 +11,6 @@ #include "app/common/DLC/DLCManager.h" #include "app/common/DLC/DLCPack.h" #include "minecraft/IGameServices.h" -#include "app/linux/Stubs/winapi_stubs.h" #include "PlatformTypes.h" #include "util/StringHelpers.h" #include "platform/fs/fs.h" @@ -105,7 +104,7 @@ BufferedImage::BufferedImage(const std::string& File, } } - if (hr == ERROR_SUCCESS) { + if (hr == 0) { if (l == 0) { width = ImageInfo.Width; height = ImageInfo.Height; @@ -154,7 +153,7 @@ BufferedImage::BufferedImage(DLCPack* dlcPack, const std::string& File, D3DXIMAGE_INFO ImageInfo; hr = PlatformRenderer.LoadTextureData(pbData, dataBytes, &ImageInfo, &data[l]); - if (hr == ERROR_SUCCESS && l == 0) { + if (hr == 0 && l == 0) { width = ImageInfo.Width; height = ImageInfo.Height; } @@ -171,7 +170,7 @@ BufferedImage::BufferedImage(std::uint8_t* pbData, std::uint32_t dataBytes) { int32_t hr = PlatformRenderer.LoadTextureData(pbData, dataBytes, &ImageInfo, &data[0]); - if (hr == ERROR_SUCCESS) { + if (hr == 0) { width = ImageInfo.Width; height = ImageInfo.Height; } else { diff --git a/targets/minecraft/client/gui/SelectWorldScreen.cpp b/targets/minecraft/client/gui/SelectWorldScreen.cpp index 8f927fe86..813247347 100644 --- a/targets/minecraft/client/gui/SelectWorldScreen.cpp +++ b/targets/minecraft/client/gui/SelectWorldScreen.cpp @@ -2,14 +2,16 @@ #include "SelectWorldScreen.h" #include +#include #include +#include +#include #include #include "Button.h" #include "ConfirmScreen.h" #include "CreateWorldScreen.h" -#include "app/linux/Stubs/winapi_stubs.h" #include "RenameWorldScreen.h" #include "util/StringHelpers.h" #include "minecraft/client/Minecraft.h" @@ -258,21 +260,24 @@ void SelectWorldScreen::WorldSelectionList::renderItem(int i, int x, int y, std::string id = levelSummary->getLevelId(); - ULARGE_INTEGER rawtime; - rawtime.QuadPart = levelSummary->getLastPlayed() * - 10000; // Convert it from milliseconds back to FileTime - - FILETIME timeasfiletime; - timeasfiletime.dwHighDateTime = rawtime.HighPart; - timeasfiletime.dwLowDateTime = rawtime.LowPart; - - SYSTEMTIME time; - FileTimeToSystemTime(&timeasfiletime, &time); + // levelSummary->getLastPlayed() is milliseconds since the FILETIME + // epoch (1601-01-01 UTC). Convert to chrono::system_clock (1970 + // epoch) by subtracting the constant offset, then break down with + // gmtime_r for display. + constexpr int64_t kFileTimeEpochToUnixEpochMs = 11644473600000LL; + const int64_t lastPlayedUnixMs = + levelSummary->getLastPlayed() - kFileTimeEpochToUnixEpochMs; + const auto tp = std::chrono::system_clock::time_point{ + std::chrono::milliseconds{lastPlayedUnixMs}}; + time_t lastPlayedTime = std::chrono::system_clock::to_time_t(tp); + std::tm utc; + gmtime_r(&lastPlayedTime, &utc); char buffer[20]; // 4J Stu - Currently shows years as 4 digits, where java only showed 2 - snprintf(buffer, 20, "%d/%d/%d %d:%02d", time.wDay, time.wMonth, - time.wYear, time.wHour, time.wMinute); // 4J - TODO Localise this + snprintf(buffer, 20, "%d/%d/%d %d:%02d", utc.tm_mday, utc.tm_mon + 1, + utc.tm_year + 1900, utc.tm_hour, + utc.tm_min); // 4J - TODO Localise this id = id + " (" + buffer; int64_t size = levelSummary->getSizeOnDisk(); diff --git a/targets/minecraft/client/multiplayer/MultiPlayerChunkCache.cpp b/targets/minecraft/client/multiplayer/MultiPlayerChunkCache.cpp index 438d2e932..1d6baff82 100644 --- a/targets/minecraft/client/multiplayer/MultiPlayerChunkCache.cpp +++ b/targets/minecraft/client/multiplayer/MultiPlayerChunkCache.cpp @@ -1,10 +1,10 @@ #include "MultiPlayerChunkCache.h" +#include #include #include #include "minecraft/network/INetworkService.h" -#include "app/linux/Stubs/winapi_stubs.h" #include "util/StringHelpers.h" #include "minecraft/server/MinecraftServer.h" #include "minecraft/server/level/ServerChunkCache.h" @@ -210,16 +210,10 @@ LevelChunk* MultiPlayerChunkCache::create(int x, int z) { chunk->loaded = true; } -#if (defined _WIN64 || defined __LP64__) - if (InterlockedCompareExchangeRelease64( - (int64_t*)&cache[idx], (int64_t)chunk, (int64_t)lastChunk) == - (int64_t)lastChunk) -#else - if (InterlockedCompareExchangeRelease( - (int32_t*)&cache[idx], (int32_t)chunk, (int32_t)lastChunk) == - (int32_t)lastChunk) -#endif // 0 - { + LevelChunk* expected = lastChunk; + if (std::atomic_ref(cache[idx]) + .compare_exchange_strong(expected, chunk, + std::memory_order_release)) { // If we're sharing with the server, we'll need to calculate our // heightmap now, which isn't shared. If we aren't sharing with the // server, then this will be calculated when the chunk data arrives. diff --git a/targets/minecraft/client/skins/DLCTexturePack.cpp b/targets/minecraft/client/skins/DLCTexturePack.cpp index 369eb9668..594d0aa69 100644 --- a/targets/minecraft/client/skins/DLCTexturePack.cpp +++ b/targets/minecraft/client/skins/DLCTexturePack.cpp @@ -26,7 +26,6 @@ #include "minecraft/locale/StringTable.h" #include "app/common/UI/All Platforms/ArchiveFile.h" #include "app/linux/Linux_UIController.h" -#include "app/linux/Stubs/winapi_stubs.h" #include "minecraft/client/BufferedImage.h" #include "platform/fs/fs.h" #include "java/File.h" @@ -242,7 +241,7 @@ void DLCTexturePack::loadData() { [this](int pad, std::uint32_t err, std::uint32_t lic) { return onPackMounted(pad, err, lic); }, - "TPACK") != ERROR_IO_PENDING) { + "TPACK") != 997) { // corrupt DLC m_bHasLoadedData = true; if (gameServices().getLevelGenerationOptions()) @@ -273,7 +272,7 @@ int DLCTexturePack::onPackMounted(int iPad, std::uint32_t dwErr, std::uint32_t dwLicenceMask) { DLCTexturePack* texturePack = this; texturePack->m_bLoadingData = false; - if (dwErr != ERROR_SUCCESS) { + if (dwErr != 0) { // corrupt DLC Log::info("Failed to mount DLC for pad %d: %u\n", iPad, dwErr); } else { diff --git a/targets/minecraft/client/title/TitleScreen.cpp b/targets/minecraft/client/title/TitleScreen.cpp index f8b659b4c..a7d547b22 100644 --- a/targets/minecraft/client/title/TitleScreen.cpp +++ b/targets/minecraft/client/title/TitleScreen.cpp @@ -4,12 +4,14 @@ #include "TitleScreen.h" #include +#include +#include #include +#include #include #include "platform/renderer/renderer.h" -#include "app/linux/Stubs/winapi_stubs.h" #include "minecraft/client/BufferedImage.h" #include "util/StringHelpers.h" #include "java/InputOutputStream/BufferedReader.h" @@ -65,18 +67,20 @@ TitleScreen::TitleScreen() { random->nextInt((int)splashes.size() - (eSplashRandomStart + 1)); // Override splash text on certain dates - SYSTEMTIME LocalSysTime; - GetLocalTime(&LocalSysTime); - if (LocalSysTime.wMonth == 11 && LocalSysTime.wDay == 9) { + const auto now = std::chrono::system_clock::now(); + const auto t = std::chrono::system_clock::to_time_t(now); + std::tm localTime; + localtime_r(&t, &localTime); + const int month = localTime.tm_mon + 1; // tm_mon is 0-based + const int day = localTime.tm_mday; + if (month == 11 && day == 9) { splashIndex = eSplashHappyBirthdayEx; - } else if (LocalSysTime.wMonth == 6 && LocalSysTime.wDay == 1) { + } else if (month == 6 && day == 1) { splashIndex = eSplashHappyBirthdayNotch; - } else if (LocalSysTime.wMonth == 12 && - LocalSysTime.wDay == 24) // the Java game shows this on - // Christmas Eve, so we will too - { + } else if (month == 12 && day == 24) { + // the Java game shows this on Christmas Eve, so we will too splashIndex = eSplashMerryXmas; - } else if (LocalSysTime.wMonth == 1 && LocalSysTime.wDay == 1) { + } else if (month == 1 && day == 1) { splashIndex = eSplashHappyNewYear; } diff --git a/targets/minecraft/server/level/ServerChunkCache.cpp b/targets/minecraft/server/level/ServerChunkCache.cpp index 203c58d9b..6ba4cefbe 100644 --- a/targets/minecraft/server/level/ServerChunkCache.cpp +++ b/targets/minecraft/server/level/ServerChunkCache.cpp @@ -1,4 +1,5 @@ #include "minecraft/util/Log.h" +#include #include "ServerChunkCache.h" #include @@ -8,7 +9,6 @@ #include #include "minecraft/IGameServices.h" -#include "app/linux/Stubs/winapi_stubs.h" #include "ServerLevel.h" #include "minecraft/world/level/storage/ConsoleSaveFileIO/compression.h" #include "minecraft/server/MinecraftServer.h" @@ -165,16 +165,10 @@ LevelChunk* ServerChunkCache::create( } } -#if defined(_WIN64) || defined(__LP64__) - if (InterlockedCompareExchangeRelease64( - (int64_t*)&cache[idx], (int64_t)chunk, (int64_t)lastChunk) == - (int64_t)lastChunk) -#else - if (InterlockedCompareExchangeRelease( - (int32_t*)&cache[idx], (int32_t)chunk, (int32_t)lastChunk) == - (int32_t)lastChunk) -#endif - { + LevelChunk* expected = lastChunk; + if (std::atomic_ref(cache[idx]) + .compare_exchange_strong(expected, chunk, + std::memory_order_release)) { // Successfully updated the cache std::lock_guard lock(m_csLoadCreate); // 4J - added - this will run a recalcHeightmap if source is a diff --git a/targets/minecraft/world/level/chunk/SparseDataStorage.cpp b/targets/minecraft/world/level/chunk/SparseDataStorage.cpp index 5c7bf9c6c..e6dc4fd9a 100644 --- a/targets/minecraft/world/level/chunk/SparseDataStorage.cpp +++ b/targets/minecraft/world/level/chunk/SparseDataStorage.cpp @@ -1,4 +1,5 @@ #include "SparseDataStorage.h" +#include #include #include @@ -6,7 +7,6 @@ #include -#include "app/linux/Stubs/winapi_stubs.h" #include "platform/NetTypes.h" #include "java/InputOutputStream/DataInputStream.h" #include "java/InputOutputStream/DataOutputStream.h" @@ -426,8 +426,9 @@ void SparseDataStorage::addNewPlane(int y) { // succeed if the data stored at dataAndCount is equal to // lastDataAndCount, and will return the value present just before the // write took place - int64_t lastDataAndCount2 = InterlockedCompareExchangeRelease64( - (int64_t*)&dataAndCount, newDataAndCount, lastDataAndCount); + int64_t lastDataAndCount2 = lastDataAndCount; + std::atomic_ref(dataAndCount).compare_exchange_strong( + lastDataAndCount2, newDataAndCount, std::memory_order_release); if (lastDataAndCount2 == lastDataAndCount) { success = true; @@ -500,8 +501,9 @@ void SparseDataStorage::updateDataAndCount(int64_t newDataAndCount) { // succeed if the data stored at dataAndCount is equal to // lastDataAndCount, and will return the value present just before the // write took place - int64_t lastDataAndCount2 = InterlockedCompareExchangeRelease64( - (int64_t*)&dataAndCount, newDataAndCount, lastDataAndCount); + int64_t lastDataAndCount2 = lastDataAndCount; + std::atomic_ref(dataAndCount).compare_exchange_strong( + lastDataAndCount2, newDataAndCount, std::memory_order_release); if (lastDataAndCount2 == lastDataAndCount) { success = true; @@ -575,8 +577,9 @@ int SparseDataStorage::compress() { // succeed if the data stored at dataAndCount is equal to // lastDataAndCount, and will return the value present just before the // write took place - int64_t lastDataAndCount2 = InterlockedCompareExchangeRelease64( - (int64_t*)&dataAndCount, newDataAndCount, lastDataAndCount); + int64_t lastDataAndCount2 = lastDataAndCount; + std::atomic_ref(dataAndCount).compare_exchange_strong( + lastDataAndCount2, newDataAndCount, std::memory_order_release); if (lastDataAndCount2 != lastDataAndCount) { // Failed to write. Don't bother trying again... being very diff --git a/targets/minecraft/world/level/chunk/SparseLightStorage.cpp b/targets/minecraft/world/level/chunk/SparseLightStorage.cpp index 8d507bc7b..4e4929a6c 100644 --- a/targets/minecraft/world/level/chunk/SparseLightStorage.cpp +++ b/targets/minecraft/world/level/chunk/SparseLightStorage.cpp @@ -1,4 +1,5 @@ #include "SparseLightStorage.h" +#include #include #include @@ -6,7 +7,6 @@ #include -#include "app/linux/Stubs/winapi_stubs.h" #include "platform/NetTypes.h" #include "java/InputOutputStream/DataInputStream.h" #include "java/InputOutputStream/DataOutputStream.h" @@ -430,8 +430,9 @@ void SparseLightStorage::addNewPlane(int y) { // succeed if the data stored at dataAndCount is equal to // lastDataAndCount, and will return the value present just before the // write took place - int64_t lastDataAndCount2 = InterlockedCompareExchangeRelease64( - (int64_t*)&dataAndCount, newDataAndCount, lastDataAndCount); + int64_t lastDataAndCount2 = lastDataAndCount; + std::atomic_ref(dataAndCount).compare_exchange_strong( + lastDataAndCount2, newDataAndCount, std::memory_order_release); if (lastDataAndCount2 == lastDataAndCount) { success = true; @@ -504,8 +505,9 @@ void SparseLightStorage::updateDataAndCount(int64_t newDataAndCount) { // succeed if the data stored at dataAndCount is equal to // lastDataAndCount, and will return the value present just before the // write took place - int64_t lastDataAndCount2 = InterlockedCompareExchangeRelease64( - (int64_t*)&dataAndCount, newDataAndCount, lastDataAndCount); + int64_t lastDataAndCount2 = lastDataAndCount; + std::atomic_ref(dataAndCount).compare_exchange_strong( + lastDataAndCount2, newDataAndCount, std::memory_order_release); if (lastDataAndCount2 == lastDataAndCount) { success = true; @@ -586,8 +588,9 @@ int SparseLightStorage::compress() { // succeed if the data stored at dataAndCount is equal to // lastDataAndCount, and will return the value present just before the // write took place - int64_t lastDataAndCount2 = InterlockedCompareExchangeRelease64( - (int64_t*)&dataAndCount, newDataAndCount, lastDataAndCount); + int64_t lastDataAndCount2 = lastDataAndCount; + std::atomic_ref(dataAndCount).compare_exchange_strong( + lastDataAndCount2, newDataAndCount, std::memory_order_release); if (lastDataAndCount2 != lastDataAndCount) { // Failed to write. Don't bother trying again... being very diff --git a/targets/minecraft/world/level/storage/ConsoleSaveFileIO/ConsoleSaveFileOriginal.cpp b/targets/minecraft/world/level/storage/ConsoleSaveFileIO/ConsoleSaveFileOriginal.cpp index 693a08cde..b1e4f1370 100644 --- a/targets/minecraft/world/level/storage/ConsoleSaveFileIO/ConsoleSaveFileOriginal.cpp +++ b/targets/minecraft/world/level/storage/ConsoleSaveFileIO/ConsoleSaveFileOriginal.cpp @@ -18,7 +18,6 @@ #include "minecraft/GameEnums.h" #include "minecraft/BuildVer.h" #include "minecraft/world/level/GameRules/LevelGenerationOptions.h" -#include "app/linux/Stubs/winapi_stubs.h" #include "minecraft/world/level/storage/ConsoleSaveFileIO/compression.h" #include "java/File.h" #include "java/InputOutputStream/DataInputStream.h" @@ -35,32 +34,12 @@ #include "platform/storage/storage.h" #include "platform/fs/fs.h" -#define RESERVE_ALLOCATION MEM_RESERVE -#define COMMIT_ALLOCATION MEM_COMMIT - -unsigned int ConsoleSaveFileOriginal::pagesCommitted = 0; -void* ConsoleSaveFileOriginal::pvHeap = nullptr; ConsoleSaveFileOriginal::ConsoleSaveFileOriginal( const std::string& fileName, void* pvSaveData /*= nullptr*/, unsigned int initialFileSize /*= 0*/, bool forceCleanSave /*= false*/, - ESavePlatform plat /*= SAVE_FILE_PLATFORM_LOCAL*/) { - // One time initialise of static stuff required for our storage - if (pvHeap == nullptr) { - // Reserve a chunk of 64MB of virtual address space for our saves, using - // 64KB pages. We'll only be committing these as required to grow the - // storage we need, which will the storage to grow without having to use - // realloc. - - // AP - The Vita doesn't have virtual memory so a pretend system has - // been implemented in PSVitaStubs.cpp. All access to the memory must be - // done via the access function as the pointer returned from - // VirtualAlloc can't be used directly. - pvHeap = VirtualAlloc(nullptr, MAX_PAGE_COUNT * CSF_PAGE_SIZE, - RESERVE_ALLOCATION, PAGE_READWRITE); - } - - pvSaveMem = pvHeap; + ESavePlatform plat /*= SAVE_FILE_PLATFORM_LOCAL*/) + : saveBuffer(MAX_SAVE_SIZE) { m_fileName = fileName; unsigned int fileSize = initialFileSize; @@ -79,34 +58,6 @@ ConsoleSaveFileOriginal::ConsoleSaveFileOriginal( if (forceCleanSave) fileSize = 0; - unsigned int heapSize = std::max( - fileSize, - 1024u * 1024u * 2u); // 4J Stu - Our files are going to be bigger than - // 2MB so allocate high to start with - - // Initially committ enough room to store headSize bytes (using - // CSF_PAGE_SIZE pages, so rounding up here). We should only ever have one - // save file at a time, and the pages should be decommitted in the dtor, so - // pages committed should always be zero at this point. - if (pagesCommitted != 0) { -#ifndef _CONTENT_PACKAGE - assert(0); -#endif - } - - unsigned int pagesRequired = - (heapSize + (CSF_PAGE_SIZE - 1)) / CSF_PAGE_SIZE; - - void* pvRet = VirtualAlloc(pvHeap, pagesRequired * CSF_PAGE_SIZE, - COMMIT_ALLOCATION, PAGE_READWRITE); - if (pvRet == nullptr) { -#ifndef _CONTENT_PACKAGE - // Out of physical memory - assert(0); -#endif - } - pagesCommitted = pagesRequired; - if (fileSize > 0) { if (pvSaveData != nullptr) { memcpy(pvSaveMem, pvSaveData, fileSize); @@ -135,6 +86,7 @@ ConsoleSaveFileOriginal::ConsoleSaveFileOriginal( // Clear the first 8 bytes that reference the header header.WriteHeader(pvSourceData); } else { + assert(decompSize <= MAX_SAVE_SIZE); unsigned char* buf = new unsigned char[decompSize]; Compression::getCompression()->SetDecompressionType( plat); // if this save is from another platform, set the @@ -146,25 +98,6 @@ ConsoleSaveFileOriginal::ConsoleSaveFileOriginal( SAVE_FILE_PLATFORM_LOCAL); // and then set the // decompression back to the // local machine's standard type - - // Only ReAlloc if we need to (we might already have enough) - // and align to 512 byte boundaries - unsigned int currentHeapSize = pagesCommitted * CSF_PAGE_SIZE; - - unsigned int desiredSize = decompSize; - - if (desiredSize > currentHeapSize) { - unsigned int pagesRequired = - (desiredSize + (CSF_PAGE_SIZE - 1)) / CSF_PAGE_SIZE; - void* pvRet = - VirtualAlloc(pvHeap, pagesRequired * CSF_PAGE_SIZE, - COMMIT_ALLOCATION, PAGE_READWRITE); - if (pvRet == nullptr) { - // Out of physical memory - assert(0); - } - pagesCommitted = pagesRequired; - } memcpy(pvSaveMem, buf, decompSize); delete[] buf; } @@ -178,10 +111,7 @@ ConsoleSaveFileOriginal::ConsoleSaveFileOriginal( } } -ConsoleSaveFileOriginal::~ConsoleSaveFileOriginal() { - VirtualFree(pvHeap, MAX_PAGE_COUNT * CSF_PAGE_SIZE, MEM_DECOMMIT); - pagesCommitted = 0; -} +ConsoleSaveFileOriginal::~ConsoleSaveFileOriginal() = default; // Add the file to our table of internal files if not already there // Open our actual save file ready for reading/writing, and the set the file @@ -424,23 +354,7 @@ void ConsoleSaveFileOriginal::MoveDataBeyond( unsigned int buffer1Size = 0; unsigned int buffer2Size = 0; - // Only ReAlloc if we need to (we might already have enough) and align to - // 512 byte boundaries - unsigned int currentHeapSize = pagesCommitted * CSF_PAGE_SIZE; - - unsigned int desiredSize = header.GetFileSize() + nNumberOfBytesToWrite; - - if (desiredSize > currentHeapSize) { - unsigned int pagesRequired = - (desiredSize + (CSF_PAGE_SIZE - 1)) / CSF_PAGE_SIZE; - void* pvRet = VirtualAlloc(pvHeap, pagesRequired * CSF_PAGE_SIZE, - COMMIT_ALLOCATION, PAGE_READWRITE); - if (pvRet == nullptr) { - // Out of physical memory - assert(0); - } - pagesCommitted = pagesRequired; - } + assert(header.GetFileSize() + nNumberOfBytesToWrite <= MAX_SAVE_SIZE); // This is the start of where we want the space to be, and the start of the // data that we need to move diff --git a/targets/minecraft/world/level/storage/ConsoleSaveFileIO/ConsoleSaveFileOriginal.h b/targets/minecraft/world/level/storage/ConsoleSaveFileIO/ConsoleSaveFileOriginal.h index 2d8fcbd27..6e5be08ff 100644 --- a/targets/minecraft/world/level/storage/ConsoleSaveFileIO/ConsoleSaveFileOriginal.h +++ b/targets/minecraft/world/level/storage/ConsoleSaveFileIO/ConsoleSaveFileOriginal.h @@ -1,6 +1,8 @@ #pragma once +#include #include #include +#include #include "util/Definitions.h" #include "minecraft/world/level/storage/ConsoleSaveFileIO/ConsoleSaveFile.h" @@ -13,18 +15,19 @@ private: std::string m_fileName; - // void* hHeap; - static void* pvHeap; - static unsigned int pagesCommitted; + // Backing store for the in-memory save image. The buffer is sized to + // MAX_SAVE_SIZE up front; on Linux/macOS the kernel only physically backs + // pages that are actually touched, so this gives the same demand-paging + // behaviour the legacy VirtualAlloc reserve/commit pattern relied on, + // without any OS-specific calls. #if defined(_LARGE_WORLDS) - static const unsigned int CSF_PAGE_SIZE = 64 * 1024; - static const unsigned int MAX_PAGE_COUNT = - 32 * 1024; // 2GB virtual allocation + static constexpr std::size_t MAX_SAVE_SIZE = + 2u * 1024u * 1024u * 1024u; // 2GB #else - static const unsigned int CSF_PAGE_SIZE = 64 * 1024; - static const unsigned int MAX_PAGE_COUNT = 1024; + static constexpr std::size_t MAX_SAVE_SIZE = 64u * 1024u * 1024u; // 64MB #endif - void* pvSaveMem; + std::vector saveBuffer; + void* pvSaveMem = saveBuffer.data(); std::recursive_mutex m_lock; diff --git a/targets/minecraft/world/level/storage/ConsoleSaveFileIO/ConsoleSaveFileSplit.cpp b/targets/minecraft/world/level/storage/ConsoleSaveFileIO/ConsoleSaveFileSplit.cpp index 40c920a0d..b1bb7a155 100644 --- a/targets/minecraft/world/level/storage/ConsoleSaveFileIO/ConsoleSaveFileSplit.cpp +++ b/targets/minecraft/world/level/storage/ConsoleSaveFileIO/ConsoleSaveFileSplit.cpp @@ -20,7 +20,6 @@ #include "minecraft/GameEnums.h" #include "minecraft/BuildVer.h" #include "minecraft/world/level/GameRules/LevelGenerationOptions.h" -#include "app/linux/Stubs/winapi_stubs.h" #include "util/Timer.h" #include "util/StringHelpers.h" #include "minecraft/world/level/storage/ConsoleSaveFileIO/compression.h" @@ -41,11 +40,6 @@ class ProgressListener; -#define RESERVE_ALLOCATION MEM_RESERVE -#define COMMIT_ALLOCATION MEM_COMMIT - -unsigned int ConsoleSaveFileSplit::pagesCommitted = 0; -void* ConsoleSaveFileSplit::pvHeap = nullptr; ConsoleSaveFileSplit::RegionFileReference::RegionFileReference( int index, unsigned int regionIndex, unsigned int length /*=0*/, @@ -363,7 +357,8 @@ FileEntry* ConsoleSaveFileSplit::GetRegionFileEntry(unsigned int regionIndex) { ConsoleSaveFileSplit::ConsoleSaveFileSplit( const std::string& fileName, void* pvSaveData /*= nullptr*/, unsigned int initialFileSize /*= 0*/, bool forceCleanSave /*= false*/, - ESavePlatform plat /*= SAVE_FILE_PLATFORM_LOCAL*/) { + ESavePlatform plat /*= SAVE_FILE_PLATFORM_LOCAL*/) + : saveBuffer(MAX_SAVE_SIZE) { unsigned int fileSize = initialFileSize; // Load a save from the game rules @@ -389,7 +384,8 @@ ConsoleSaveFileSplit::ConsoleSaveFileSplit( ConsoleSaveFileSplit::ConsoleSaveFileSplit(ConsoleSaveFile* sourceSave, bool alreadySmallRegions, - ProgressListener* progress) { + ProgressListener* progress) + : saveBuffer(MAX_SAVE_SIZE) { _init(sourceSave->getFilename(), nullptr, 0, sourceSave->getSavePlatform()); header.setOriginalSaveVersion(sourceSave->getOriginalSaveVersion()); @@ -422,17 +418,6 @@ void ConsoleSaveFileSplit::_init(const std::string& fileName, void* pvSaveData, unsigned int fileSize, ESavePlatform plat) { m_lastTickTime = 0; - // One time initialise of static stuff required for our storage - if (pvHeap == nullptr) { - // Reserve a chunk of 64MB of virtual address space for our saves, using - // 64KB pages. We'll only be committing these as required to grow the - // storage we need, which will the storage to grow without having to use - // realloc. - pvHeap = VirtualAlloc(nullptr, MAX_PAGE_COUNT * CSF_PAGE_SIZE, - RESERVE_ALLOCATION, PAGE_READWRITE); - } - - pvSaveMem = pvHeap; m_fileName = fileName; // Get details of region files. From this point on we are responsible for @@ -458,34 +443,6 @@ void ConsoleSaveFileSplit::_init(const std::string& fileName, void* pvSaveData, regionFiles[regionIndex] = regionFileRef; } - unsigned int heapSize = std::max( - fileSize, - 1024u * 1024u * 2u); // 4J Stu - Our files are going to be bigger than - // 2MB so allocate high to start with - - // Initially committ enough room to store headSize bytes (using - // CSF_PAGE_SIZE pages, so rounding up here). We should only ever have one - // save file at a time, and the pages should be decommitted in the dtor, so - // pages committed should always be zero at this point. - if (pagesCommitted != 0) { -#if !defined(_CONTENT_PACKAGE) - assert(0); -#endif - } - - unsigned int pagesRequired = - (heapSize + (CSF_PAGE_SIZE - 1)) / CSF_PAGE_SIZE; - - void* pvRet = VirtualAlloc(pvHeap, pagesRequired * CSF_PAGE_SIZE, - COMMIT_ALLOCATION, PAGE_READWRITE); - if (pvRet == nullptr) { -#if !defined(_CONTENT_PACKAGE) - // Out of physical memory - assert(0); -#endif - } - pagesCommitted = pagesRequired; - if (fileSize > 0) { if (pvSaveData != nullptr) { memcpy(pvSaveMem, pvSaveData, fileSize); @@ -515,26 +472,7 @@ void ConsoleSaveFileSplit::_init(const std::string& fileName, void* pvSaveData, if (Compression::getCompression()->Decompress( buf, &decompSize, (unsigned char*)pvSaveMem + 8, fileSize - 8) == 0) { - // Only ReAlloc if we need to (we might already have enough) - // and align to 512 byte boundaries - unsigned int currentHeapSize = - pagesCommitted * CSF_PAGE_SIZE; - - unsigned int desiredSize = decompSize; - - if (desiredSize > currentHeapSize) { - unsigned int pagesRequired = - (desiredSize + (CSF_PAGE_SIZE - 1)) / CSF_PAGE_SIZE; - void* pvRet = - VirtualAlloc(pvHeap, pagesRequired * CSF_PAGE_SIZE, - COMMIT_ALLOCATION, PAGE_READWRITE); - if (pvRet == nullptr) { - // Out of physical memory - assert(0); - } - pagesCommitted = pagesRequired; - } - + assert(decompSize <= MAX_SAVE_SIZE); memcpy(pvSaveMem, buf, decompSize); } else { // Corrupt save, although most of the terrain should @@ -561,8 +499,6 @@ void ConsoleSaveFileSplit::_init(const std::string& fileName, void* pvSaveData, } ConsoleSaveFileSplit::~ConsoleSaveFileSplit() { - VirtualFree(pvHeap, MAX_PAGE_COUNT * CSF_PAGE_SIZE, MEM_DECOMMIT); - pagesCommitted = 0; // Make sure we don't have any thumbnail data still waiting round - we can't // need it now we've destroyed the save file anyway @@ -1023,23 +959,7 @@ void ConsoleSaveFileSplit::MoveDataBeyond(FileEntry* file, unsigned int buffer1Size = 0; unsigned int buffer2Size = 0; - // Only ReAlloc if we need to (we might already have enough) and align to - // 512 byte boundaries - unsigned int currentHeapSize = pagesCommitted * CSF_PAGE_SIZE; - - unsigned int desiredSize = header.GetFileSize() + nNumberOfBytesToWrite; - - if (desiredSize > currentHeapSize) { - unsigned int pagesRequired = - (desiredSize + (CSF_PAGE_SIZE - 1)) / CSF_PAGE_SIZE; - void* pvRet = VirtualAlloc(pvHeap, pagesRequired * CSF_PAGE_SIZE, - COMMIT_ALLOCATION, PAGE_READWRITE); - if (pvRet == nullptr) { - // Out of physical memory - assert(0); - } - pagesCommitted = pagesRequired; - } + assert(header.GetFileSize() + nNumberOfBytesToWrite <= MAX_SAVE_SIZE); // This is the start of where we want the space to be, and the start of the // data that we need to move diff --git a/targets/minecraft/world/level/storage/ConsoleSaveFileIO/ConsoleSaveFileSplit.h b/targets/minecraft/world/level/storage/ConsoleSaveFileIO/ConsoleSaveFileSplit.h index a1e93f573..bfc05165f 100644 --- a/targets/minecraft/world/level/storage/ConsoleSaveFileIO/ConsoleSaveFileSplit.h +++ b/targets/minecraft/world/level/storage/ConsoleSaveFileIO/ConsoleSaveFileSplit.h @@ -73,18 +73,19 @@ private: std::string m_fileName; bool m_autosave; - // void* hHeap; - static void* pvHeap; - static unsigned int pagesCommitted; + // Backing store for the in-memory save image. The buffer is sized to + // MAX_SAVE_SIZE up front; on Linux/macOS the kernel only physically backs + // pages that are actually touched, so this gives the same demand-paging + // behaviour the legacy VirtualAlloc reserve/commit pattern relied on, + // without any OS-specific calls. #if defined(_LARGE_WORLDS) - static const unsigned int CSF_PAGE_SIZE = 64 * 1024; - static const unsigned int MAX_PAGE_COUNT = - 32 * 1024; // 2GB virtual allocation + static constexpr std::size_t MAX_SAVE_SIZE = + 2u * 1024u * 1024u * 1024u; // 2GB #else - static const unsigned int CSF_PAGE_SIZE = 64 * 1024; - static const unsigned int MAX_PAGE_COUNT = 1024; + static constexpr std::size_t MAX_SAVE_SIZE = 64u * 1024u * 1024u; // 64MB #endif - void* pvSaveMem; + std::vector saveBuffer; + void* pvSaveMem = saveBuffer.data(); std::recursive_mutex m_lock; diff --git a/targets/minecraft/world/level/storage/ConsoleSaveFileIO/FileHeader.cpp b/targets/minecraft/world/level/storage/ConsoleSaveFileIO/FileHeader.cpp index a3ff514d5..991a8af5b 100644 --- a/targets/minecraft/world/level/storage/ConsoleSaveFileIO/FileHeader.cpp +++ b/targets/minecraft/world/level/storage/ConsoleSaveFileIO/FileHeader.cpp @@ -13,7 +13,6 @@ #include #include "app/linux/LinuxGame.h" -#include "app/linux/Stubs/winapi_stubs.h" #include "util/Definitions.h" #include "java/System.h" diff --git a/targets/minecraft/world/level/tile/entity/SignTileEntity.cpp b/targets/minecraft/world/level/tile/entity/SignTileEntity.cpp index d02363f13..2677f592a 100644 --- a/targets/minecraft/world/level/tile/entity/SignTileEntity.cpp +++ b/targets/minecraft/world/level/tile/entity/SignTileEntity.cpp @@ -2,7 +2,6 @@ #include -#include "app/linux/Stubs/winapi_stubs.h" #include "PlatformTypes.h" #include "minecraft/client/Minecraft.h" #include "minecraft/network/packet/SignUpdatePacket.h" @@ -153,7 +152,7 @@ int SignTileEntity::handleStringVerify(STRING_VERIFY_RESPONSE* pResults) { m_bVerified = true; m_bCensored = false; for (int i = 0; i < pResults->wNumStrings; i++) { - if (pResults->pStringResult[i] != ERROR_SUCCESS) { + if (pResults->pStringResult[i] != 0) { m_bCensored = true; } }