From 6f80c79e80e8a8d9351f8bc3fc7b4cae179df3e8 Mon Sep 17 00:00:00 2001 From: Tropical <42101043+tropicaaal@users.noreply.github.com> Date: Mon, 2 Mar 2026 17:47:01 -0600 Subject: [PATCH 01/26] remove duplicate includes of extraX64 Now that we support stdafx.h, these are unnecessary --- Minecraft.Client/PS3/Leaderboards/PS3LeaderboardManager.h | 1 - Minecraft.World/linux/wlinux.h | 2 -- 2 files changed, 3 deletions(-) diff --git a/Minecraft.Client/PS3/Leaderboards/PS3LeaderboardManager.h b/Minecraft.Client/PS3/Leaderboards/PS3LeaderboardManager.h index dbe6bd721..74fba9fc3 100644 --- a/Minecraft.Client/PS3/Leaderboards/PS3LeaderboardManager.h +++ b/Minecraft.Client/PS3/Leaderboards/PS3LeaderboardManager.h @@ -1,7 +1,6 @@ #pragma once #include "../../Common/Leaderboards/LeaderboardManager.h" -#include "../../../Minecraft.World/x64headers/extraX64.h" #include "PS3/Passphrase/ps3__np_conf.h" diff --git a/Minecraft.World/linux/wlinux.h b/Minecraft.World/linux/wlinux.h index 90c3d1d4c..28e42a0f9 100644 --- a/Minecraft.World/linux/wlinux.h +++ b/Minecraft.World/linux/wlinux.h @@ -61,6 +61,4 @@ typedef VOID* XMEMDECOMPRESSION_CONTEXT; typedef float FLOAT; -#include "../x64headers/extraX64.h" - #endif // WLINUX_H From 62551094c698bbc4c462ab3c56f8ed02e28a09da Mon Sep 17 00:00:00 2001 From: Tropical <42101043+tropicaaal@users.noreply.github.com> Date: Mon, 2 Mar 2026 17:47:19 -0600 Subject: [PATCH 02/26] fix: remove redefinitions of various xbox-related constants --- Minecraft.World/linux/xbox_valve.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Minecraft.World/linux/xbox_valve.h b/Minecraft.World/linux/xbox_valve.h index 2eff251a0..b242a4587 100644 --- a/Minecraft.World/linux/xbox_valve.h +++ b/Minecraft.World/linux/xbox_valve.h @@ -42,7 +42,7 @@ typedef long long int int64; #define XDEVICE_PORT1 1 #define XDEVICE_PORT2 2 #define XDEVICE_PORT3 3 -#define XUSER_MAX_COUNT 4 +// #define XUSER_MAX_COUNT 4 #define XUSER_INDEX_NONE 0x000000FE #define XBX_CLR_DEFAULT 0xFF000000 @@ -157,8 +157,8 @@ FORCEINLINE void XBX_SetStorageDeviceId( DWORD idx ) {} FORCEINLINE const char *XBX_GetLanguageString() { return ""; } FORCEINLINE bool XBX_IsLocalized() { return false; } -#define XCONTENT_MAX_DISPLAYNAME_LENGTH 128 -#define XCONTENT_MAX_FILENAME_LENGTH 42 +// #define XCONTENT_MAX_DISPLAYNAME_LENGTH 128 +// #define XCONTENT_MAX_FILENAME_LENGTH 42 #define XBX_INVALID_STORAGE_ID ((DWORD) -1) #define XBX_STORAGE_DECLINED ((DWORD) -2) From 81c9b9d021a8b0c2bc0101989d8bf9ea9606e38f Mon Sep 17 00:00:00 2001 From: Tropical <42101043+tropicaaal@users.noreply.github.com> Date: Mon, 2 Mar 2026 17:48:28 -0600 Subject: [PATCH 03/26] feat: stub `InitializeCriticalSection` in extraX64 --- Minecraft.World/x64headers/extraX64.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Minecraft.World/x64headers/extraX64.h b/Minecraft.World/x64headers/extraX64.h index c5bf0aeac..e351f4d48 100644 --- a/Minecraft.World/x64headers/extraX64.h +++ b/Minecraft.World/x64headers/extraX64.h @@ -47,6 +47,9 @@ typedef struct _RTL_CRITICAL_SECTION { typedef RTL_CRITICAL_SECTION CRITICAL_SECTION; +inline void InitializeCriticalSection(CRITICAL_SECTION* stubEnterCS) +{ +} inline void DeleteCriticalSection(CRITICAL_SECTION* stubEnterCS) { From 70c8a010e8faed1717eaa34e74baef15b20ed6b5 Mon Sep 17 00:00:00 2001 From: Tropical <42101043+tropicaaal@users.noreply.github.com> Date: Mon, 2 Mar 2026 17:57:20 -0600 Subject: [PATCH 04/26] refactor: move stubs out of `App_Defines.h` into wlinux/extraX64 --- Minecraft.Client/Common/App_Defines.h | 7 ------- Minecraft.World/linux/wlinux.h | 4 ++++ Minecraft.World/x64headers/extraX64.h | 5 ++++- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/Minecraft.Client/Common/App_Defines.h b/Minecraft.Client/Common/App_Defines.h index 88b37b88e..41c239f8d 100644 --- a/Minecraft.Client/Common/App_Defines.h +++ b/Minecraft.Client/Common/App_Defines.h @@ -104,13 +104,6 @@ #define MINECRAFT_LANGUAGE_LATINAMERICANSPANISH 0x13 #define MINECRAFT_LANGUAGE_GREEK 0x14 -#if defined(__linux__) -#define __debugbreak() -#define __int32 int -typedef unsigned long ULONG; -inline void InitializeCriticalSectionAndSpinCount(CRITICAL_SECTION CriticalSection, ULONG SpinCount) {} -#endif // __linux__ - /* Match these const int XC_LANGUAGE_ENGLISH =1; diff --git a/Minecraft.World/linux/wlinux.h b/Minecraft.World/linux/wlinux.h index 28e42a0f9..0148a1ce4 100644 --- a/Minecraft.World/linux/wlinux.h +++ b/Minecraft.World/linux/wlinux.h @@ -45,6 +45,10 @@ typedef long long LONGLONG; typedef size_t SIZE_T; typedef std::wstring LPWSTR; typedef unsigned char boolean; // java brainrot +#define __debugbreak() +#define __int32 int +typedef unsigned long ULONG; +typedef unsigned char byte; // https://learn.microsoft.com/en-us/windows/win32/api/minwinbase/ns-minwinbase-filetime typedef struct _FILETIME { diff --git a/Minecraft.World/x64headers/extraX64.h b/Minecraft.World/x64headers/extraX64.h index e351f4d48..b40171f02 100644 --- a/Minecraft.World/x64headers/extraX64.h +++ b/Minecraft.World/x64headers/extraX64.h @@ -11,7 +11,6 @@ #define MULTITHREAD_ENABLE -typedef unsigned char byte; const int XUSER_INDEX_ANY = 255; const int XUSER_INDEX_FOCUS = 254; @@ -51,6 +50,10 @@ inline void InitializeCriticalSection(CRITICAL_SECTION* stubEnterCS) { } +inline void InitializeCriticalSectionAndSpinCount(CRITICAL_SECTION* CriticalSection, ULONG SpinCount) +{ +} + inline void DeleteCriticalSection(CRITICAL_SECTION* stubEnterCS) { } From 006dba0602d87de0fd93ca2fb3039f0a651e2ca1 Mon Sep 17 00:00:00 2001 From: Tropical <42101043+tropicaaal@users.noreply.github.com> Date: Mon, 2 Mar 2026 18:28:06 -0600 Subject: [PATCH 05/26] feat: stub winapi TLS functions with pthread keys Not sure how sound implicit casting `pthread_key_t` to `DWORD` is, but we can get away with it for now. Otherwise, we're gonna need to keep a global list of registered keys and mutex that and blah blah blah --- Minecraft.World/linux/wlinux.h | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/Minecraft.World/linux/wlinux.h b/Minecraft.World/linux/wlinux.h index 0148a1ce4..d3842b934 100644 --- a/Minecraft.World/linux/wlinux.h +++ b/Minecraft.World/linux/wlinux.h @@ -6,6 +6,7 @@ #include #include #include +#include #define TRUE true #define FALSE false @@ -65,4 +66,31 @@ typedef VOID* XMEMDECOMPRESSION_CONTEXT; typedef float FLOAT; +#define TLS_OUT_OF_INDEXES ((DWORD)0xFFFFFFFF) + +DWORD TlsAlloc(VOID) { + pthread_key_t key; + + if (pthread_key_create(&key, NULL) == 0) { + return key; + } else { + return TLS_OUT_OF_INDEXES; + } +} + +BOOL TlsFree(DWORD dwTlsIndex) +{ + return pthread_key_delete(dwTlsIndex) == 0; +} + +LPVOID TlsGetValue(DWORD dwTlsIndex) +{ + return pthread_getspecific(dwTlsIndex); +} + +BOOL TlsSetValue(DWORD dwTlsIndex, LPVOID lpTlsValue) +{ + return pthread_setspecific(dwTlsIndex, lpTlsValue) == 0; +} + #endif // WLINUX_H From c4b25bc62214afde7550bd9b71e0b4768c35d10d Mon Sep 17 00:00:00 2001 From: Tropical <42101043+tropicaaal@users.noreply.github.com> Date: Mon, 2 Mar 2026 19:08:25 -0600 Subject: [PATCH 06/26] feat: add stubs for memory stats, atomics, errno --- Minecraft.World/linux/wlinux.h | 47 ++++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) diff --git a/Minecraft.World/linux/wlinux.h b/Minecraft.World/linux/wlinux.h index d3842b934..e1fc27f0a 100644 --- a/Minecraft.World/linux/wlinux.h +++ b/Minecraft.World/linux/wlinux.h @@ -6,6 +6,8 @@ #include #include #include +#include +#include #include #define TRUE true @@ -34,6 +36,7 @@ typedef char CHAR; typedef void* PVOID; typedef unsigned long* ULONG_PTR; typedef long LONG; +typedef long LONG64, *PLONG64; typedef void VOID; typedef ULONGLONG PlayerUID; typedef DWORD WORD; @@ -51,12 +54,27 @@ typedef unsigned char boolean; // java brainrot typedef unsigned long ULONG; typedef unsigned char byte; +#define PAGE_READWRITE 0x04 +#define MEM_LARGE_PAGES 0x20000000 +#define MAXULONG_PTR ((ULONG)0xFFFFFFFF) + // https://learn.microsoft.com/en-us/windows/win32/api/minwinbase/ns-minwinbase-filetime typedef struct _FILETIME { DWORD dwLowDateTime; DWORD dwHighDateTime; } FILETIME, *PFILETIME, *LPFILETIME; +typedef struct _MEMORYSTATUS { + DWORD dwLength; + DWORD dwMemoryLoad; + SIZE_T dwTotalPhys; + SIZE_T dwAvailPhys; + SIZE_T dwTotalPageFile; + SIZE_T dwAvailPageFile; + SIZE_T dwTotalVirtual; + SIZE_T dwAvailVirtual; +} MEMORYSTATUS, *LPMEMORYSTATUS; + #define FILE_BEGIN SEEK_SET typedef short SHORT; @@ -68,6 +86,7 @@ typedef float FLOAT; #define TLS_OUT_OF_INDEXES ((DWORD)0xFFFFFFFF) +// https://learn.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-tlsalloc DWORD TlsAlloc(VOID) { pthread_key_t key; @@ -78,19 +97,47 @@ DWORD TlsAlloc(VOID) { } } +// https://learn.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-tlsfree BOOL TlsFree(DWORD dwTlsIndex) { return pthread_key_delete(dwTlsIndex) == 0; } +// https://learn.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-tlsgetvalue LPVOID TlsGetValue(DWORD dwTlsIndex) { return pthread_getspecific(dwTlsIndex); } +// https://learn.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-tlssetvalue BOOL TlsSetValue(DWORD dwTlsIndex, LPVOID lpTlsValue) { return pthread_setspecific(dwTlsIndex, lpTlsValue) == 0; } + +// https://learn.microsoft.com/en-us/windows/win32/api/winbase/nf-winbase-globalmemorystatus +VOID GlobalMemoryStatus(LPMEMORYSTATUS lpBuffer) +{ + // TODO: Parse /proc/meminfo and set based on that. Probably will also need another different + // codepath for macOS too. +} + +DWORD GetLastError(VOID) +{ + return errno; +} + +LONG64 InterlockedCompareExchangeRelease64( + LONG64 volatile *Destination, + LONG64 Exchange, + LONG64 Comperand) +{ + LONG64 expected = Comperand; + __atomic_compare_exchange_n(Destination, &expected, Exchange, false, __ATOMIC_RELEASE, __ATOMIC_RELAXED); + return expected; +} + + + #endif // WLINUX_H From 065ffff0717283ae06774bc1a2b914f647bb31c2 Mon Sep 17 00:00:00 2001 From: Tropical <42101043+tropicaaal@users.noreply.github.com> Date: Mon, 2 Mar 2026 19:25:37 -0600 Subject: [PATCH 07/26] feat: stub critical sections on top of pthread recursive mutexes --- Minecraft.World/Dimension.cpp | 2 +- Minecraft.World/linux/wlinux.h | 42 +++++++++++++++++++++++-- Minecraft.World/x64headers/extraX64.h | 45 --------------------------- 3 files changed, 41 insertions(+), 48 deletions(-) diff --git a/Minecraft.World/Dimension.cpp b/Minecraft.World/Dimension.cpp index e3eba15df..a2a52aac3 100644 --- a/Minecraft.World/Dimension.cpp +++ b/Minecraft.World/Dimension.cpp @@ -2,7 +2,7 @@ #include "net.minecraft.world.level.levelgen.h" #include "net.minecraft.world.level.h" #include "net.minecraft.world.level.storage.h" -#include "dimension.h" +#include "Dimension.h" #include "BiomeSource.h" #include "FixedBiomeSource.h" #include "OldChunkStorage.h" diff --git a/Minecraft.World/linux/wlinux.h b/Minecraft.World/linux/wlinux.h index e1fc27f0a..09e3bea5f 100644 --- a/Minecraft.World/linux/wlinux.h +++ b/Minecraft.World/linux/wlinux.h @@ -86,6 +86,44 @@ typedef float FLOAT; #define TLS_OUT_OF_INDEXES ((DWORD)0xFFFFFFFF) +typedef pthread_mutex_t RTL_CRITICAL_SECTION; +typedef pthread_mutex_t* PRTL_CRITICAL_SECTION; + +typedef RTL_CRITICAL_SECTION CRITICAL_SECTION; +typedef PRTL_CRITICAL_SECTION PCRITICAL_SECTION; +typedef PRTL_CRITICAL_SECTION LPCRITICAL_SECTION; + +void InitializeCriticalSection(PRTL_CRITICAL_SECTION CriticalSection) { + pthread_mutexattr_t attr; + int ret; + + pthread_mutexattr_init(&attr); + pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE); + pthread_mutex_init(CriticalSection, &attr); + pthread_mutexattr_destroy(&attr); +} + +void InitializeCriticalSectionAndSpinCount(PRTL_CRITICAL_SECTION CriticalSection, ULONG SpinCount) { + // no spin count required because we use a recursive mutex + InitializeCriticalSection(CriticalSection); +} + +void DeleteCriticalSection(PRTL_CRITICAL_SECTION CriticalSection) { + pthread_mutex_destroy(CriticalSection); +} + +void EnterCriticalSection(PRTL_CRITICAL_SECTION CriticalSection) { + pthread_mutex_lock(CriticalSection); +} + +void LeaveCriticalSection(PRTL_CRITICAL_SECTION CriticalSection) { + pthread_mutex_unlock(CriticalSection); +} + +ULONG TryEnterCriticalSection(PRTL_CRITICAL_SECTION CriticalSection) { + return pthread_mutex_trylock(CriticalSection) == 0; +} + // https://learn.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-tlsalloc DWORD TlsAlloc(VOID) { pthread_key_t key; @@ -119,8 +157,8 @@ BOOL TlsSetValue(DWORD dwTlsIndex, LPVOID lpTlsValue) // https://learn.microsoft.com/en-us/windows/win32/api/winbase/nf-winbase-globalmemorystatus VOID GlobalMemoryStatus(LPMEMORYSTATUS lpBuffer) { - // TODO: Parse /proc/meminfo and set based on that. Probably will also need another different - // codepath for macOS too. + // TODO: Parse /proc/meminfo and set lpBuffer based on that. Probably will also need another + // different codepath for macOS too. } DWORD GetLastError(VOID) diff --git a/Minecraft.World/x64headers/extraX64.h b/Minecraft.World/x64headers/extraX64.h index b40171f02..17e1479df 100644 --- a/Minecraft.World/x64headers/extraX64.h +++ b/Minecraft.World/x64headers/extraX64.h @@ -22,51 +22,6 @@ const int XUSER_MAX_COUNT = 4; const int MINECRAFT_NET_MAX_PLAYERS = 8; #endif -#if defined(__linux__) - -typedef struct _RTL_CRITICAL_SECTION { - // // - // // The following field is used for blocking when there is contention for - // // the resource - // // - // - union { - ULONG_PTR RawEvent[4]; - } Synchronization; - // - // // - // // The following three fields control entering and exiting the critical - // // section for the resource - // // - // - LONG LockCount; - LONG RecursionCount; - HANDLE OwningThread; -} RTL_CRITICAL_SECTION, *PRTL_CRITICAL_SECTION; - -typedef RTL_CRITICAL_SECTION CRITICAL_SECTION; - -inline void InitializeCriticalSection(CRITICAL_SECTION* stubEnterCS) -{ -} - -inline void InitializeCriticalSectionAndSpinCount(CRITICAL_SECTION* CriticalSection, ULONG SpinCount) -{ -} - -inline void DeleteCriticalSection(CRITICAL_SECTION* stubEnterCS) -{ -} - -inline void EnterCriticalSection(CRITICAL_SECTION* stubEnterCS) -{ -} - -inline void LeaveCriticalSection( CRITICAL_SECTION* stubEnterCS) -{ -} -#endif // __linux__ - #ifdef __ORBIS__ #include #include From 22b97a4dc0ee5a64fbbcdecff9f7b314712de03d Mon Sep 17 00:00:00 2001 From: Tropical <42101043+tropicaaal@users.noreply.github.com> Date: Mon, 2 Mar 2026 19:33:37 -0600 Subject: [PATCH 08/26] feat: nanosleep-based `Sleep` stub --- Minecraft.World/linux/wlinux.h | 32 ++++++++++++++++++++++++-------- 1 file changed, 24 insertions(+), 8 deletions(-) diff --git a/Minecraft.World/linux/wlinux.h b/Minecraft.World/linux/wlinux.h index 09e3bea5f..07745d2ce 100644 --- a/Minecraft.World/linux/wlinux.h +++ b/Minecraft.World/linux/wlinux.h @@ -93,7 +93,8 @@ typedef RTL_CRITICAL_SECTION CRITICAL_SECTION; typedef PRTL_CRITICAL_SECTION PCRITICAL_SECTION; typedef PRTL_CRITICAL_SECTION LPCRITICAL_SECTION; -void InitializeCriticalSection(PRTL_CRITICAL_SECTION CriticalSection) { +void InitializeCriticalSection(PRTL_CRITICAL_SECTION CriticalSection) +{ pthread_mutexattr_t attr; int ret; @@ -103,24 +104,29 @@ void InitializeCriticalSection(PRTL_CRITICAL_SECTION CriticalSection) { pthread_mutexattr_destroy(&attr); } -void InitializeCriticalSectionAndSpinCount(PRTL_CRITICAL_SECTION CriticalSection, ULONG SpinCount) { +void InitializeCriticalSectionAndSpinCount(PRTL_CRITICAL_SECTION CriticalSection, ULONG SpinCount) +{ // no spin count required because we use a recursive mutex InitializeCriticalSection(CriticalSection); } -void DeleteCriticalSection(PRTL_CRITICAL_SECTION CriticalSection) { +void DeleteCriticalSection(PRTL_CRITICAL_SECTION CriticalSection) +{ pthread_mutex_destroy(CriticalSection); } -void EnterCriticalSection(PRTL_CRITICAL_SECTION CriticalSection) { +void EnterCriticalSection(PRTL_CRITICAL_SECTION CriticalSection) +{ pthread_mutex_lock(CriticalSection); } -void LeaveCriticalSection(PRTL_CRITICAL_SECTION CriticalSection) { +void LeaveCriticalSection(PRTL_CRITICAL_SECTION CriticalSection) +{ pthread_mutex_unlock(CriticalSection); } -ULONG TryEnterCriticalSection(PRTL_CRITICAL_SECTION CriticalSection) { +ULONG TryEnterCriticalSection(PRTL_CRITICAL_SECTION CriticalSection) +{ return pthread_mutex_trylock(CriticalSection) == 0; } @@ -166,6 +172,18 @@ DWORD GetLastError(VOID) return errno; } +VOID Sleep(DWORD dwMilliseconds) +{ + struct timespec ts; + ts.tv_nsec = (dwMilliseconds * 1000000) % 1000000000; + ts.tv_sec = dwMilliseconds / 1000; + + int ret; + do { + ret = nanosleep(&ts, &ts); + } while (ret == -1 && errno == EINTR); +} + LONG64 InterlockedCompareExchangeRelease64( LONG64 volatile *Destination, LONG64 Exchange, @@ -176,6 +194,4 @@ LONG64 InterlockedCompareExchangeRelease64( return expected; } - - #endif // WLINUX_H From d75e0570b0ab02d4c374e29fc227f484d02e98cb Mon Sep 17 00:00:00 2001 From: Tropical <42101043+tropicaaal@users.noreply.github.com> Date: Mon, 2 Mar 2026 19:40:11 -0600 Subject: [PATCH 09/26] fix: cast `InterlockedCompareExchangeRelease64` args in storage classes --- Minecraft.World/SparseDataStorage.cpp | 6 +++--- Minecraft.World/SparseLightStorage.cpp | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/Minecraft.World/SparseDataStorage.cpp b/Minecraft.World/SparseDataStorage.cpp index 6db131e78..4b761d787 100644 --- a/Minecraft.World/SparseDataStorage.cpp +++ b/Minecraft.World/SparseDataStorage.cpp @@ -407,7 +407,7 @@ void SparseDataStorage::addNewPlane(int y) // Attempt to update the data & count atomically. This command will Only succeed if the data stored at // dataAndCount is equal to lastDataAndCount, and will return the value present just before the write took place - __int64 lastDataAndCount2 = InterlockedCompareExchangeRelease64( &dataAndCount, newDataAndCount, lastDataAndCount ); + __int64 lastDataAndCount2 = InterlockedCompareExchangeRelease64( (LONG64 *)&dataAndCount, newDataAndCount, lastDataAndCount ); if( lastDataAndCount2 == lastDataAndCount ) { @@ -485,7 +485,7 @@ void SparseDataStorage::updateDataAndCount(__int64 newDataAndCount) // Attempt to update the data & count atomically. This command will Only succeed if the data stored at // dataAndCount is equal to lastDataAndCount, and will return the value present just before the write took place - __int64 lastDataAndCount2 = InterlockedCompareExchangeRelease64( &dataAndCount, newDataAndCount, lastDataAndCount ); + __int64 lastDataAndCount2 = InterlockedCompareExchangeRelease64( (LONG64 *)&dataAndCount, newDataAndCount, lastDataAndCount ); if( lastDataAndCount2 == lastDataAndCount ) { @@ -564,7 +564,7 @@ int SparseDataStorage::compress() // Attempt to update the data & count atomically. This command will Only succeed if the data stored at // dataAndCount is equal to lastDataAndCount, and will return the value present just before the write took place - __int64 lastDataAndCount2 = InterlockedCompareExchangeRelease64( &dataAndCount, newDataAndCount, lastDataAndCount ); + __int64 lastDataAndCount2 = InterlockedCompareExchangeRelease64( (LONG64 *)&dataAndCount, newDataAndCount, lastDataAndCount ); if( lastDataAndCount2 != lastDataAndCount ) { diff --git a/Minecraft.World/SparseLightStorage.cpp b/Minecraft.World/SparseLightStorage.cpp index f9a2f0cbd..8cc1dfeea 100644 --- a/Minecraft.World/SparseLightStorage.cpp +++ b/Minecraft.World/SparseLightStorage.cpp @@ -413,7 +413,7 @@ void SparseLightStorage::addNewPlane(int y) // Attempt to update the data & count atomically. This command will Only succeed if the data stored at // dataAndCount is equal to lastDataAndCount, and will return the value present just before the write took place - __int64 lastDataAndCount2 = InterlockedCompareExchangeRelease64( &dataAndCount, newDataAndCount, lastDataAndCount ); + __int64 lastDataAndCount2 = InterlockedCompareExchangeRelease64( (LONG64 *)&dataAndCount, newDataAndCount, lastDataAndCount ); if( lastDataAndCount2 == lastDataAndCount ) { @@ -491,7 +491,7 @@ void SparseLightStorage::updateDataAndCount(__int64 newDataAndCount) // Attempt to update the data & count atomically. This command will Only succeed if the data stored at // dataAndCount is equal to lastDataAndCount, and will return the value present just before the write took place - __int64 lastDataAndCount2 = InterlockedCompareExchangeRelease64( &dataAndCount, newDataAndCount, lastDataAndCount ); + __int64 lastDataAndCount2 = InterlockedCompareExchangeRelease64( (LONG64 *)&dataAndCount, newDataAndCount, lastDataAndCount ); if( lastDataAndCount2 == lastDataAndCount ) { @@ -581,7 +581,7 @@ int SparseLightStorage::compress() // Attempt to update the data & count atomically. This command will Only succeed if the data stored at // dataAndCount is equal to lastDataAndCount, and will return the value present just before the write took place - __int64 lastDataAndCount2 = InterlockedCompareExchangeRelease64( &dataAndCount, newDataAndCount, lastDataAndCount ); + __int64 lastDataAndCount2 = InterlockedCompareExchangeRelease64( (LONG64 *)&dataAndCount, newDataAndCount, lastDataAndCount ); if( lastDataAndCount2 != lastDataAndCount ) { From fd1dd31c6bc5b254ab91aeda72a1f6b0df4c017c Mon Sep 17 00:00:00 2001 From: Tropical <42101043+tropicaaal@users.noreply.github.com> Date: Mon, 2 Mar 2026 19:40:40 -0600 Subject: [PATCH 10/26] fix: follow the time-honored 4J tradition of being lazy and not stubbing `_itow` in ChunkStorage --- Minecraft.World/OldChunkStorage.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Minecraft.World/OldChunkStorage.cpp b/Minecraft.World/OldChunkStorage.cpp index 50c29a96d..98afdc677 100644 --- a/Minecraft.World/OldChunkStorage.cpp +++ b/Minecraft.World/OldChunkStorage.cpp @@ -65,7 +65,7 @@ File OldChunkStorage::getFile(int x, int z) wchar_t xRadix36[64]; wchar_t zRadix36[64]; -#if ( defined __PS3__ || defined __ORBIS__ || defined __PSVITA__ ) +#if ( defined __PS3__ || defined __ORBIS__ || defined __PSVITA__ || defined __linux__ ) assert(0); // need a gcc verison of _itow ? #else _itow(x,xRadix36,36); From dd81ec98b4282a1187ab9b0eb3633e79787910ee Mon Sep 17 00:00:00 2001 From: Tropical <42101043+tropicaaal@users.noreply.github.com> Date: Mon, 2 Mar 2026 19:45:10 -0600 Subject: [PATCH 11/26] refactor: make UIStructs and LevelGenerationOptions shut up --- Minecraft.Client/Common/GameRules/LevelGenerationOptions.h | 2 +- Minecraft.Client/Common/UI/UIStructs.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Minecraft.Client/Common/GameRules/LevelGenerationOptions.h b/Minecraft.Client/Common/GameRules/LevelGenerationOptions.h index cff00be23..9abed66fb 100644 --- a/Minecraft.Client/Common/GameRules/LevelGenerationOptions.h +++ b/Minecraft.Client/Common/GameRules/LevelGenerationOptions.h @@ -1,7 +1,7 @@ #pragma once using namespace std; -#pragma message("LevelGenerationOptions.h ") +// #pragma message("LevelGenerationOptions.h ") #include "GameRuleDefinition.h" #include "../../../Minecraft.World/StructureFeature.h" diff --git a/Minecraft.Client/Common/UI/UIStructs.h b/Minecraft.Client/Common/UI/UIStructs.h index 2dd03c8c5..ea57b3a1f 100644 --- a/Minecraft.Client/Common/UI/UIStructs.h +++ b/Minecraft.Client/Common/UI/UIStructs.h @@ -1,6 +1,6 @@ #pragma once -#pragma message("UIStructs.h") +// #pragma message("UIStructs.h") #include "UIEnums.h" From b7c6512445225981d851287ff2a574bb1f80b5df Mon Sep 17 00:00:00 2001 From: ella love Date: Mon, 2 Mar 2026 22:00:33 -0500 Subject: [PATCH 12/26] feat: implement win32 file I/O stubs over POSIX in wlinux.h --- .gitignore | 1 + Minecraft.World/linux/wlinux.h | 386 ++++++++++++++++++++++++++++++--- 2 files changed, 357 insertions(+), 30 deletions(-) diff --git a/.gitignore b/.gitignore index 6c81ca77e..830932518 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ # .gitignore build/ .cache/ +.idea/ diff --git a/Minecraft.World/linux/wlinux.h b/Minecraft.World/linux/wlinux.h index 07745d2ce..0550ca375 100644 --- a/Minecraft.World/linux/wlinux.h +++ b/Minecraft.World/linux/wlinux.h @@ -5,15 +5,24 @@ #include #include +#include #include #include #include #include +#include +#include +#include +#include +#include +#include +#include +#include #define TRUE true #define FALSE false #define RtlZeroMemory(Destination,Length) memset((Destination),0,(Length)) -#define ZeroMemory RtlZeroMemory +#define ZeroMemory RtlZeroMemory #define WINAPI typedef unsigned int DWORD; @@ -34,7 +43,7 @@ typedef unsigned int* LPDWORD; typedef const void* LPCVOID; typedef char CHAR; typedef void* PVOID; -typedef unsigned long* ULONG_PTR; +typedef uintptr_t ULONG_PTR; typedef long LONG; typedef long LONG64, *PLONG64; typedef void VOID; @@ -42,8 +51,8 @@ typedef ULONGLONG PlayerUID; typedef DWORD WORD; typedef struct { DWORD LowPart; - long long QuadPart; LONG HighPart; + long long QuadPart; } LARGE_INTEGER; typedef long long LONGLONG; typedef size_t SIZE_T; @@ -53,10 +62,45 @@ typedef unsigned char boolean; // java brainrot #define __int32 int typedef unsigned long ULONG; typedef unsigned char byte; +typedef short SHORT; +typedef float FLOAT; #define PAGE_READWRITE 0x04 #define MEM_LARGE_PAGES 0x20000000 -#define MAXULONG_PTR ((ULONG)0xFFFFFFFF) +#define MAXULONG_PTR ((ULONG_PTR)~0UL) +#define MAX_PATH 260 + +#define GENERIC_READ 0x80000000UL +#define GENERIC_WRITE 0x40000000UL +#define GENERIC_EXECUTE 0x20000000UL +#define GENERIC_ALL 0x10000000UL + +#define FILE_SHARE_READ 0x00000001 +#define FILE_SHARE_WRITE 0x00000002 +#define FILE_SHARE_DELETE 0x00000004 + +#define CREATE_NEW 1 +#define CREATE_ALWAYS 2 +#define OPEN_EXISTING 3 +#define OPEN_ALWAYS 4 +#define TRUNCATE_EXISTING 5 + +#define FILE_ATTRIBUTE_READONLY 0x00000001 +#define FILE_ATTRIBUTE_HIDDEN 0x00000002 +#define FILE_ATTRIBUTE_SYSTEM 0x00000004 +#define FILE_ATTRIBUTE_DIRECTORY 0x00000010 +#define FILE_ATTRIBUTE_ARCHIVE 0x00000020 +#define FILE_ATTRIBUTE_NORMAL 0x00000080 +#define FILE_ATTRIBUTE_TEMPORARY 0x00000100 +#define INVALID_FILE_ATTRIBUTES ((DWORD)-1) +#define INVALID_FILE_SIZE ((DWORD)-1) +#define INVALID_SET_FILE_POINTER ((DWORD)-1) + +#define FILE_BEGIN SEEK_SET +#define FILE_CURRENT SEEK_CUR +#define FILE_END SEEK_END + +#define INVALID_HANDLE_VALUE ((HANDLE)(ULONG_PTR)-1) // https://learn.microsoft.com/en-us/windows/win32/api/minwinbase/ns-minwinbase-filetime typedef struct _FILETIME { @@ -75,14 +119,46 @@ typedef struct _MEMORYSTATUS { SIZE_T dwAvailVirtual; } MEMORYSTATUS, *LPMEMORYSTATUS; -#define FILE_BEGIN SEEK_SET +typedef struct _WIN32_FIND_DATAA { + DWORD dwFileAttributes; + FILETIME ftCreationTime; + FILETIME ftLastAccessTime; + FILETIME ftLastWriteTime; + DWORD nFileSizeHigh; + DWORD nFileSizeLow; + DWORD dwReserved0; + DWORD dwReserved1; + char cFileName[MAX_PATH]; + char cAlternateFileName[14]; +} WIN32_FIND_DATAA, *PWIN32_FIND_DATAA, *LPWIN32_FIND_DATAA; -typedef short SHORT; +typedef WIN32_FIND_DATAA WIN32_FIND_DATA; +typedef PWIN32_FIND_DATAA PWIN32_FIND_DATA; +typedef LPWIN32_FIND_DATAA LPWIN32_FIND_DATA; + +typedef struct _WIN32_FILE_ATTRIBUTE_DATA { + DWORD dwFileAttributes; + FILETIME ftCreationTime; + FILETIME ftLastAccessTime; + FILETIME ftLastWriteTime; + DWORD nFileSizeHigh; + DWORD nFileSizeLow; +} WIN32_FILE_ATTRIBUTE_DATA, *LPWIN32_FILE_ATTRIBUTE_DATA; + +typedef enum _GET_FILEEX_INFO_LEVELS { + GetFileExInfoStandard, + GetFileExMaxInfoLevel +} GET_FILEEX_INFO_LEVELS; typedef VOID* XMEMCOMPRESSION_CONTEXT; typedef VOID* XMEMDECOMPRESSION_CONTEXT; -typedef float FLOAT; +// internal search state for FindFirstFile/FindNextFile +typedef struct _WLINUX_FIND_HANDLE { + DIR *dir; + char dirpath[MAX_PATH]; + char pattern[MAX_PATH]; +} _WLINUX_FIND_HANDLE; #define TLS_OUT_OF_INDEXES ((DWORD)0xFFFFFFFF) @@ -93,86 +169,81 @@ typedef RTL_CRITICAL_SECTION CRITICAL_SECTION; typedef PRTL_CRITICAL_SECTION PCRITICAL_SECTION; typedef PRTL_CRITICAL_SECTION LPCRITICAL_SECTION; -void InitializeCriticalSection(PRTL_CRITICAL_SECTION CriticalSection) +static inline void InitializeCriticalSection(PRTL_CRITICAL_SECTION CriticalSection) { pthread_mutexattr_t attr; - int ret; - pthread_mutexattr_init(&attr); pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE); pthread_mutex_init(CriticalSection, &attr); pthread_mutexattr_destroy(&attr); } -void InitializeCriticalSectionAndSpinCount(PRTL_CRITICAL_SECTION CriticalSection, ULONG SpinCount) +static inline void InitializeCriticalSectionAndSpinCount(PRTL_CRITICAL_SECTION CriticalSection, ULONG SpinCount) { // no spin count required because we use a recursive mutex InitializeCriticalSection(CriticalSection); } -void DeleteCriticalSection(PRTL_CRITICAL_SECTION CriticalSection) +static inline void DeleteCriticalSection(PRTL_CRITICAL_SECTION CriticalSection) { pthread_mutex_destroy(CriticalSection); } -void EnterCriticalSection(PRTL_CRITICAL_SECTION CriticalSection) +static inline void EnterCriticalSection(PRTL_CRITICAL_SECTION CriticalSection) { pthread_mutex_lock(CriticalSection); } -void LeaveCriticalSection(PRTL_CRITICAL_SECTION CriticalSection) +static inline void LeaveCriticalSection(PRTL_CRITICAL_SECTION CriticalSection) { pthread_mutex_unlock(CriticalSection); } -ULONG TryEnterCriticalSection(PRTL_CRITICAL_SECTION CriticalSection) +static inline ULONG TryEnterCriticalSection(PRTL_CRITICAL_SECTION CriticalSection) { return pthread_mutex_trylock(CriticalSection) == 0; } // https://learn.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-tlsalloc -DWORD TlsAlloc(VOID) { +static inline DWORD TlsAlloc(VOID) +{ pthread_key_t key; - - if (pthread_key_create(&key, NULL) == 0) { + if (pthread_key_create(&key, NULL) == 0) return key; - } else { - return TLS_OUT_OF_INDEXES; - } + return TLS_OUT_OF_INDEXES; } // https://learn.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-tlsfree -BOOL TlsFree(DWORD dwTlsIndex) +static inline BOOL TlsFree(DWORD dwTlsIndex) { return pthread_key_delete(dwTlsIndex) == 0; } // https://learn.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-tlsgetvalue -LPVOID TlsGetValue(DWORD dwTlsIndex) +static inline LPVOID TlsGetValue(DWORD dwTlsIndex) { return pthread_getspecific(dwTlsIndex); } // https://learn.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-tlssetvalue -BOOL TlsSetValue(DWORD dwTlsIndex, LPVOID lpTlsValue) +static inline BOOL TlsSetValue(DWORD dwTlsIndex, LPVOID lpTlsValue) { return pthread_setspecific(dwTlsIndex, lpTlsValue) == 0; } - // https://learn.microsoft.com/en-us/windows/win32/api/winbase/nf-winbase-globalmemorystatus -VOID GlobalMemoryStatus(LPMEMORYSTATUS lpBuffer) +static inline VOID GlobalMemoryStatus(LPMEMORYSTATUS lpBuffer) { // TODO: Parse /proc/meminfo and set lpBuffer based on that. Probably will also need another // different codepath for macOS too. } -DWORD GetLastError(VOID) +static inline DWORD GetLastError(VOID) { return errno; } -VOID Sleep(DWORD dwMilliseconds) +static inline VOID Sleep(DWORD dwMilliseconds) { struct timespec ts; ts.tv_nsec = (dwMilliseconds * 1000000) % 1000000000; @@ -184,7 +255,7 @@ VOID Sleep(DWORD dwMilliseconds) } while (ret == -1 && errno == EINTR); } -LONG64 InterlockedCompareExchangeRelease64( +static inline LONG64 InterlockedCompareExchangeRelease64( LONG64 volatile *Destination, LONG64 Exchange, LONG64 Comperand) @@ -194,4 +265,259 @@ LONG64 InterlockedCompareExchangeRelease64( return expected; } -#endif // WLINUX_H +// internal helper: convert time_t to FILETIME (100ns intervals since 1601-01-01) +static inline FILETIME _TimeToFileTime(time_t t) +{ + const ULONGLONG EPOCH_DIFF = 11644473600ULL; + ULONGLONG val = ((ULONGLONG)t + EPOCH_DIFF) * 10000000ULL; + FILETIME ft; + ft.dwLowDateTime = (DWORD)(val & 0xFFFFFFFF); + ft.dwHighDateTime = (DWORD)(val >> 32); + return ft; +} + +// internal helper: fill WIN32_FIND_DATAA from stat + name +static inline void _FillFindData(const char *name, const struct stat *st, WIN32_FIND_DATAA *out) +{ + memset(out, 0, sizeof(*out)); + out->dwFileAttributes = S_ISDIR(st->st_mode) ? FILE_ATTRIBUTE_DIRECTORY : FILE_ATTRIBUTE_NORMAL; + if (!(st->st_mode & S_IWUSR)) out->dwFileAttributes |= FILE_ATTRIBUTE_READONLY; + if (name[0] == '.') out->dwFileAttributes |= FILE_ATTRIBUTE_HIDDEN; + out->ftCreationTime = _TimeToFileTime(st->st_mtime); + out->ftLastAccessTime = _TimeToFileTime(st->st_atime); + out->ftLastWriteTime = _TimeToFileTime(st->st_mtime); + out->nFileSizeHigh = (DWORD)((st->st_size >> 32) & 0xFFFFFFFF); + out->nFileSizeLow = (DWORD)(st->st_size & 0xFFFFFFFF); + strncpy(out->cFileName, name, MAX_PATH - 1); +} + +static inline HANDLE CreateFileA(const char *lpFileName, DWORD dwDesiredAccess, DWORD dwShareMode, + void *lpSecurityAttributes, DWORD dwCreationDisposition, DWORD dwFlagsAndAttributes, HANDLE hTemplateFile) +{ + int flags = 0; + if ((dwDesiredAccess & GENERIC_READ) && (dwDesiredAccess & GENERIC_WRITE)) flags = O_RDWR; + else if (dwDesiredAccess & GENERIC_WRITE) flags = O_WRONLY; + else flags = O_RDONLY; + + switch (dwCreationDisposition) + { + case CREATE_NEW: flags |= O_CREAT | O_EXCL; break; + case CREATE_ALWAYS: flags |= O_CREAT | O_TRUNC; break; + case OPEN_EXISTING: break; + case OPEN_ALWAYS: flags |= O_CREAT; break; + case TRUNCATE_EXISTING: flags |= O_TRUNC; break; + } + + int fd = open(lpFileName, flags, 0644); + return fd == -1 ? INVALID_HANDLE_VALUE : (HANDLE)(intptr_t)fd; +} + +static inline HANDLE CreateFile(const char *lpFileName, DWORD dwDesiredAccess, DWORD dwShareMode, + void *lpSecurityAttributes, DWORD dwCreationDisposition, DWORD dwFlagsAndAttributes, HANDLE hTemplateFile) +{ + return CreateFileA(lpFileName, dwDesiredAccess, dwShareMode, lpSecurityAttributes, dwCreationDisposition, dwFlagsAndAttributes, hTemplateFile); +} + +static inline BOOL CloseHandle(HANDLE hObject) +{ + if (hObject == INVALID_HANDLE_VALUE) return FALSE; + return close((int)(intptr_t)hObject) == 0; +} + +static inline DWORD GetFileSize(HANDLE hFile, DWORD *lpFileSizeHigh) +{ + struct stat st{}; + if (fstat((int)(intptr_t)hFile, &st) != 0) { if (lpFileSizeHigh) *lpFileSizeHigh = 0; return INVALID_FILE_SIZE; } + if (lpFileSizeHigh) *lpFileSizeHigh = (DWORD)((st.st_size >> 32) & 0xFFFFFFFF); + return (DWORD)(st.st_size & 0xFFFFFFFF); +} + +static inline BOOL GetFileSizeEx(HANDLE hFile, LARGE_INTEGER *lpFileSize) +{ + struct stat st{}; + if (fstat((int)(intptr_t)hFile, &st) != 0) return FALSE; + if (lpFileSize) { lpFileSize->QuadPart = st.st_size; lpFileSize->LowPart = (DWORD)(st.st_size & 0xFFFFFFFF); lpFileSize->HighPart = (LONG)(st.st_size >> 32); } + return TRUE; +} + +static inline BOOL ReadFile(HANDLE hFile, void *lpBuffer, DWORD nNumberOfBytesToRead, DWORD *lpNumberOfBytesRead, void *lpOverlapped) +{ + ssize_t n = read((int)(intptr_t)hFile, lpBuffer, nNumberOfBytesToRead); + if (lpNumberOfBytesRead) *lpNumberOfBytesRead = n >= 0 ? (DWORD)n : 0; + return n >= 0; +} + +static inline BOOL WriteFile(HANDLE hFile, const void *lpBuffer, DWORD nNumberOfBytesToWrite, DWORD *lpNumberOfBytesWritten, void *lpOverlapped) +{ + ssize_t n = write((int)(intptr_t)hFile, lpBuffer, nNumberOfBytesToWrite); + if (lpNumberOfBytesWritten) *lpNumberOfBytesWritten = n >= 0 ? (DWORD)n : 0; + return n >= 0; +} + +static inline DWORD SetFilePointer(HANDLE hFile, LONG lDistanceToMove, LONG *lpDistanceToMoveHigh, DWORD dwMoveMethod) +{ + off_t offset = lDistanceToMove; + if (lpDistanceToMoveHigh) offset |= ((off_t)*lpDistanceToMoveHigh << 32); + off_t result = lseek((int)(intptr_t)hFile, offset, dwMoveMethod); + if (result == (off_t)-1) { if (lpDistanceToMoveHigh) *lpDistanceToMoveHigh = -1; return INVALID_SET_FILE_POINTER; } + if (lpDistanceToMoveHigh) *lpDistanceToMoveHigh = (LONG)(result >> 32); + return (DWORD)(result & 0xFFFFFFFF); +} + +static inline DWORD GetFileAttributesA(const char *lpFileName) +{ + struct stat st{}; + if (stat(lpFileName, &st) != 0) return INVALID_FILE_ATTRIBUTES; + DWORD attrs = S_ISDIR(st.st_mode) ? FILE_ATTRIBUTE_DIRECTORY : FILE_ATTRIBUTE_NORMAL; + if (!(st.st_mode & S_IWUSR)) attrs |= FILE_ATTRIBUTE_READONLY; + const char *base = strrchr(lpFileName, '/'); base = base ? base + 1 : lpFileName; + if (base[0] == '.') attrs |= FILE_ATTRIBUTE_HIDDEN; + return attrs; +} + +static inline DWORD GetFileAttributes(const char *lpFileName) +{ + return GetFileAttributesA(lpFileName); +} + +static inline BOOL GetFileAttributesExA(const char *lpFileName, GET_FILEEX_INFO_LEVELS fInfoLevelId, void *lpFileInformation) +{ + if (fInfoLevelId != GetFileExInfoStandard || !lpFileInformation) return FALSE; + struct stat st{}; + if (stat(lpFileName, &st) != 0) return FALSE; + WIN32_FILE_ATTRIBUTE_DATA *out = (WIN32_FILE_ATTRIBUTE_DATA *)lpFileInformation; + out->dwFileAttributes = GetFileAttributesA(lpFileName); + out->ftCreationTime = _TimeToFileTime(st.st_mtime); + out->ftLastAccessTime = _TimeToFileTime(st.st_atime); + out->ftLastWriteTime = _TimeToFileTime(st.st_mtime); + out->nFileSizeHigh = (DWORD)((st.st_size >> 32) & 0xFFFFFFFF); + out->nFileSizeLow = (DWORD)(st.st_size & 0xFFFFFFFF); + return TRUE; +} + +static inline BOOL GetFileAttributesEx(const char *lpFileName, GET_FILEEX_INFO_LEVELS fInfoLevelId, void *lpFileInformation) +{ + return GetFileAttributesExA(lpFileName, fInfoLevelId, lpFileInformation); +} + +static inline BOOL CreateDirectoryA(const char *lpPathName, void *lpSecurityAttributes) +{ + return mkdir(lpPathName, 0755) == 0; +} + +static inline BOOL CreateDirectory(const char *lpPathName, void *lpSecurityAttributes) +{ + return CreateDirectoryA(lpPathName, lpSecurityAttributes); +} + +static inline BOOL DeleteFileA(const char *lpFileName) +{ + return unlink(lpFileName) == 0; +} + +static inline BOOL DeleteFile(const char *lpFileName) +{ + return DeleteFileA(lpFileName); +} + +static inline BOOL MoveFileA(const char *lpExistingFileName, const char *lpNewFileName) +{ + return rename(lpExistingFileName, lpNewFileName) == 0; +} + +static inline BOOL MoveFile(const char *lpExistingFileName, const char *lpNewFileName) +{ + return MoveFileA(lpExistingFileName, lpNewFileName); +} + +// https://learn.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-findfirstfilea +static inline HANDLE FindFirstFileA(const char *lpFileName, WIN32_FIND_DATAA *lpFindFileData) +{ + if (!lpFileName || !lpFindFileData) return INVALID_HANDLE_VALUE; + + char dirpath[MAX_PATH], pattern[MAX_PATH]; + const char *sep = strrchr(lpFileName, '/'); + if (sep) + { + size_t len = sep - lpFileName; + if (len >= MAX_PATH) return INVALID_HANDLE_VALUE; + strncpy(dirpath, lpFileName, len); dirpath[len] = '\0'; + strncpy(pattern, sep + 1, MAX_PATH - 1); + } + else + { + strncpy(dirpath, ".", MAX_PATH - 1); + strncpy(pattern, lpFileName, MAX_PATH - 1); + } + + DIR *dir = opendir(dirpath); + if (!dir) return INVALID_HANDLE_VALUE; + + _WLINUX_FIND_HANDLE *fh = (_WLINUX_FIND_HANDLE *)malloc(sizeof(_WLINUX_FIND_HANDLE)); + if (!fh) { closedir(dir); return INVALID_HANDLE_VALUE; } + fh->dir = dir; + strncpy(fh->dirpath, dirpath, MAX_PATH - 1); + strncpy(fh->pattern, pattern, MAX_PATH - 1); + + struct dirent *ent; + while ((ent = readdir(fh->dir)) != NULL) + { + if (strcmp(ent->d_name, ".") == 0 || strcmp(ent->d_name, "..") == 0) continue; + if (fnmatch(fh->pattern, ent->d_name, 0) == 0) + { + char fullpath[MAX_PATH * 2]; + snprintf(fullpath, sizeof(fullpath), "%s/%s", fh->dirpath, ent->d_name); + struct stat st{}; + if (stat(fullpath, &st) == 0) _FillFindData(ent->d_name, &st, lpFindFileData); + else { memset(lpFindFileData, 0, sizeof(*lpFindFileData)); strncpy(lpFindFileData->cFileName, ent->d_name, MAX_PATH - 1); } + return (HANDLE)fh; + } + } + + closedir(fh->dir); free(fh); + return INVALID_HANDLE_VALUE; +} + +static inline HANDLE FindFirstFile(const char *lpFileName, WIN32_FIND_DATAA *lpFindFileData) +{ + return FindFirstFileA(lpFileName, lpFindFileData); +} + +// https://learn.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-findnextfilea +static inline BOOL FindNextFileA(HANDLE hFindFile, WIN32_FIND_DATAA *lpFindFileData) +{ + if (hFindFile == INVALID_HANDLE_VALUE || !lpFindFileData) return FALSE; + _WLINUX_FIND_HANDLE *fh = (_WLINUX_FIND_HANDLE *)hFindFile; + + struct dirent *ent; + while ((ent = readdir(fh->dir)) != NULL) + { + if (strcmp(ent->d_name, ".") == 0 || strcmp(ent->d_name, "..") == 0) continue; + if (fnmatch(fh->pattern, ent->d_name, 0) == 0) + { + char fullpath[MAX_PATH * 2]; + snprintf(fullpath, sizeof(fullpath), "%s/%s", fh->dirpath, ent->d_name); + struct stat st{}; + if (stat(fullpath, &st) == 0) _FillFindData(ent->d_name, &st, lpFindFileData); + else { memset(lpFindFileData, 0, sizeof(*lpFindFileData)); strncpy(lpFindFileData->cFileName, ent->d_name, MAX_PATH - 1); } + return TRUE; + } + } + return FALSE; +} + +static inline BOOL FindNextFile(HANDLE hFindFile, WIN32_FIND_DATAA *lpFindFileData) +{ + return FindNextFileA(hFindFile, lpFindFileData); +} + +// https://learn.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-findclose +static inline BOOL FindClose(HANDLE hFindFile) +{ + if (hFindFile == INVALID_HANDLE_VALUE) return FALSE; + _WLINUX_FIND_HANDLE *fh = (_WLINUX_FIND_HANDLE *)hFindFile; + closedir(fh->dir); free(fh); + return TRUE; +} + +#endif // WLINUX_H \ No newline at end of file From 42035b71d81c88439bd436c0918433163ebd5f13 Mon Sep 17 00:00:00 2001 From: Tropical <42101043+tropicaaal@users.noreply.github.com> Date: Mon, 2 Mar 2026 21:21:51 -0600 Subject: [PATCH 13/26] refactor: move linux stubs to `Minecraft.Client` Existing platform abstraction layers are all located in Minecraft.Client, making the `linux` folder the odd one out in `Minecraft.World`. This relocates `linux/wlinux.h` and its supporting helper files to `Minecraft.Client/Linux`. `wlinux.h` has been renamed to `LinuxStubs.h` for consistency. --- .../Linux/LinuxStubs.h | 16 ++++++++-------- .../Linux}/xbox_valve.h | 0 Minecraft.Client/stdafx.h | 8 +++++--- Minecraft.World/stdafx.h | 15 +++++---------- 4 files changed, 18 insertions(+), 21 deletions(-) rename Minecraft.World/linux/wlinux.h => Minecraft.Client/Linux/LinuxStubs.h (97%) rename {Minecraft.World/linux => Minecraft.Client/Linux}/xbox_valve.h (100%) diff --git a/Minecraft.World/linux/wlinux.h b/Minecraft.Client/Linux/LinuxStubs.h similarity index 97% rename from Minecraft.World/linux/wlinux.h rename to Minecraft.Client/Linux/LinuxStubs.h index 0550ca375..2e16db67d 100644 --- a/Minecraft.World/linux/wlinux.h +++ b/Minecraft.Client/Linux/LinuxStubs.h @@ -1,5 +1,5 @@ -#ifndef WLINUX_H -#define WLINUX_H +#ifndef LINUXSTUBS_H +#define LINUXSTUBS_H #pragma once @@ -154,11 +154,11 @@ typedef VOID* XMEMCOMPRESSION_CONTEXT; typedef VOID* XMEMDECOMPRESSION_CONTEXT; // internal search state for FindFirstFile/FindNextFile -typedef struct _WLINUX_FIND_HANDLE { +typedef struct _LINUXSTUBS_FIND_HANDLE { DIR *dir; char dirpath[MAX_PATH]; char pattern[MAX_PATH]; -} _WLINUX_FIND_HANDLE; +} _LINUXSTUBS_FIND_HANDLE; #define TLS_OUT_OF_INDEXES ((DWORD)0xFFFFFFFF) @@ -453,7 +453,7 @@ static inline HANDLE FindFirstFileA(const char *lpFileName, WIN32_FIND_DATAA *lp DIR *dir = opendir(dirpath); if (!dir) return INVALID_HANDLE_VALUE; - _WLINUX_FIND_HANDLE *fh = (_WLINUX_FIND_HANDLE *)malloc(sizeof(_WLINUX_FIND_HANDLE)); + _LINUXSTUBS_FIND_HANDLE *fh = (_LINUXSTUBS_FIND_HANDLE *)malloc(sizeof(_LINUXSTUBS_FIND_HANDLE)); if (!fh) { closedir(dir); return INVALID_HANDLE_VALUE; } fh->dir = dir; strncpy(fh->dirpath, dirpath, MAX_PATH - 1); @@ -487,7 +487,7 @@ static inline HANDLE FindFirstFile(const char *lpFileName, WIN32_FIND_DATAA *lpF static inline BOOL FindNextFileA(HANDLE hFindFile, WIN32_FIND_DATAA *lpFindFileData) { if (hFindFile == INVALID_HANDLE_VALUE || !lpFindFileData) return FALSE; - _WLINUX_FIND_HANDLE *fh = (_WLINUX_FIND_HANDLE *)hFindFile; + _LINUXSTUBS_FIND_HANDLE *fh = (_LINUXSTUBS_FIND_HANDLE *)hFindFile; struct dirent *ent; while ((ent = readdir(fh->dir)) != NULL) @@ -515,9 +515,9 @@ static inline BOOL FindNextFile(HANDLE hFindFile, WIN32_FIND_DATAA *lpFindFileDa static inline BOOL FindClose(HANDLE hFindFile) { if (hFindFile == INVALID_HANDLE_VALUE) return FALSE; - _WLINUX_FIND_HANDLE *fh = (_WLINUX_FIND_HANDLE *)hFindFile; + _LINUXSTUBS_FIND_HANDLE *fh = (_LINUXSTUBS_FIND_HANDLE *)hFindFile; closedir(fh->dir); free(fh); return TRUE; } -#endif // WLINUX_H \ No newline at end of file +#endif // LINUXSTUBS_H \ No newline at end of file diff --git a/Minecraft.World/linux/xbox_valve.h b/Minecraft.Client/Linux/xbox_valve.h similarity index 100% rename from Minecraft.World/linux/xbox_valve.h rename to Minecraft.Client/Linux/xbox_valve.h diff --git a/Minecraft.Client/stdafx.h b/Minecraft.Client/stdafx.h index fa7ef0367..d9302801a 100644 --- a/Minecraft.Client/stdafx.h +++ b/Minecraft.Client/stdafx.h @@ -149,7 +149,7 @@ typedef XUID GameSessionUID; #endif #include "../Minecraft.World/Definitions.h" -#include "../Minecraft.World/class.h" +#include "../Minecraft.World/Class.h" #include "../Minecraft.World/ArrayWithLength.h" #include "../Minecraft.World/SharedConstants.h" #include "../Minecraft.World/Random.h" @@ -211,7 +211,7 @@ typedef XUID GameSessionUID; #include "Common/UI/UIEnums.h" #include "Common/UI/UIStructs.h" // #ifdef _XBOX -#include "Common/App_defines.h" +#include "Common/App_Defines.h" #include "Common/App_enums.h" #include "Common/Tutorial/TutorialEnum.h" #include "Common/App_structs.h" @@ -280,8 +280,10 @@ typedef XUID GameSessionUID; #include "Windows64/Iggy/gdraw/gdraw_d3d11.h" #include "Windows64/Windows64_UIController.h" #elif defined __linux__ - // #include "Windows64/Sentient/MinecraftTelemetry.h" #include "Windows64Media/strings.h" + #include "Linux/LinuxStubs.h" + #include "Linux/xbox_valve.h" + // #include "Windows64/Sentient/MinecraftTelemetry.h" // #include "Windows64/Windows64_App.h" // #include "Windows64/Sentient/DynamicConfigurations.h" // #include "Windows64/Sentient/SentientTelemetryCommon.h" diff --git a/Minecraft.World/stdafx.h b/Minecraft.World/stdafx.h index 6b8b90ff2..a1394e1cc 100644 --- a/Minecraft.World/stdafx.h +++ b/Minecraft.World/stdafx.h @@ -12,11 +12,6 @@ typedef unsigned __int64; typedef unsigned __uint64; -#if defined( __linux__ ) -#include "linux/wlinux.h" -#include "linux/xbox_valve.h" -#endif - #ifdef _WINDOWS64 #define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers // Windows Header Files: @@ -98,6 +93,9 @@ typedef XUID GameSessionUID; #include #include #include + +#include "../Minecraft.Client/Linux/LinuxStubs.h" +#include "../Minecraft.Client/Linux/xbox_valve.h" #else #include #include @@ -126,11 +124,6 @@ typedef XUID GameSessionUID; #include #endif -#if defined(__linux__) -#else -#include "../Minecraft.Client/Xbox/Network/extra.h" -#endif - #include "Definitions.h" #include "Class.h" #include "Exceptions.h" @@ -183,6 +176,7 @@ void MemSect(int sect); #include "../Minecraft.Client/PSVita/4JLibs/inc/4J_Storage.h" #include "../Minecraft.Client/PSVita/4JLibs/inc/4J_Input.h" #elif defined __linux__ +// FIXME: Port 4JLibs to POSIX #include "../Minecraft.Client/Windows64/4JLibs/inc/4J_Profile.h" #include "../Minecraft.Client/Windows64/4JLibs/inc/4J_Render.h" #include "../Minecraft.Client/Windows64/4JLibs/inc/4J_Storage.h" @@ -246,6 +240,7 @@ void MemSect(int sect); #include "../Minecraft.Client/PSVita/Sentient/SentientManager.h" #include "../Minecraft.Client/PSVita/Sentient/MinecraftTelemetry.h" #elif defined(__linux__) +// FIXME: Move and port to ../Minecraft.Client/Linux #include "../Minecraft.Client/Windows64/Windows64_App.h" #include "../Minecraft.Client/Windows64Media/strings.h" #include "../Minecraft.Client/Windows64/Sentient/SentientTelemetryCommon.h" From 7c578c216167e22f2f80fd42f77ede8af40a4335 Mon Sep 17 00:00:00 2001 From: Tropical <42101043+tropicaaal@users.noreply.github.com> Date: Mon, 2 Mar 2026 21:49:26 -0600 Subject: [PATCH 14/26] feat: stub `QueryPerformance{Counter, Frequency}` --- Minecraft.Client/Linux/LinuxStubs.h | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/Minecraft.Client/Linux/LinuxStubs.h b/Minecraft.Client/Linux/LinuxStubs.h index 2e16db67d..31273cac8 100644 --- a/Minecraft.Client/Linux/LinuxStubs.h +++ b/Minecraft.Client/Linux/LinuxStubs.h @@ -520,4 +520,21 @@ static inline BOOL FindClose(HANDLE hFindFile) return TRUE; } +BOOL QueryPerformanceFrequency(LARGE_INTEGER *lpFrequency) +{ + // nanoseconds + lpFrequency->QuadPart = (1000000000); + return false; +} + +static inline BOOL QueryPerformanceCounter(LARGE_INTEGER *lpPerformanceCount) +{ + struct timespec ts; + clock_gettime(CLOCK_MONOTONIC, &ts); + + lpPerformanceCount->QuadPart = (ts.tv_sec * 1000000000LL) + ts.tv_nsec; + + return true; +} + #endif // LINUXSTUBS_H \ No newline at end of file From 5d5e4b44189ecc1a84706694e8f13d30cd6ebb6c Mon Sep 17 00:00:00 2001 From: Tropical <42101043+tropicaaal@users.noreply.github.com> Date: Mon, 2 Mar 2026 21:53:45 -0600 Subject: [PATCH 15/26] feat: implement `GetTickCount` --- Minecraft.Client/Linux/LinuxStubs.h | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/Minecraft.Client/Linux/LinuxStubs.h b/Minecraft.Client/Linux/LinuxStubs.h index 31273cac8..0987180b9 100644 --- a/Minecraft.Client/Linux/LinuxStubs.h +++ b/Minecraft.Client/Linux/LinuxStubs.h @@ -520,21 +520,34 @@ static inline BOOL FindClose(HANDLE hFindFile) return TRUE; } -BOOL QueryPerformanceFrequency(LARGE_INTEGER *lpFrequency) +static inline DWORD GetTickCount() +{ + struct timespec ts; + clock_gettime(CLOCK_MONOTONIC, &ts); + + // milliseconds + return (long long)ts.tv_sec * 1000 + (long long)ts.tv_nsec / 1000000; +} + +static inline BOOL QueryPerformanceFrequency(LARGE_INTEGER *lpFrequency) { // nanoseconds - lpFrequency->QuadPart = (1000000000); + lpFrequency->QuadPart = 1000000000; return false; } + static inline BOOL QueryPerformanceCounter(LARGE_INTEGER *lpPerformanceCount) { struct timespec ts; clock_gettime(CLOCK_MONOTONIC, &ts); - lpPerformanceCount->QuadPart = (ts.tv_sec * 1000000000LL) + ts.tv_nsec; + // nanoseconds + lpPerformanceCount->QuadPart = ((long long)ts.tv_sec * 1000000000) + (long long)ts.tv_nsec; return true; } + + #endif // LINUXSTUBS_H \ No newline at end of file From a2107c6ab5b201a5a71f636802731eb1736564c8 Mon Sep 17 00:00:00 2001 From: Tropical <42101043+tropicaaal@users.noreply.github.com> Date: Mon, 2 Mar 2026 21:58:40 -0600 Subject: [PATCH 16/26] fix: add missing `climits`/`cfloat` includes --- Minecraft.Client/Linux/LinuxStubs.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Minecraft.Client/Linux/LinuxStubs.h b/Minecraft.Client/Linux/LinuxStubs.h index 0987180b9..4af8de6d8 100644 --- a/Minecraft.Client/Linux/LinuxStubs.h +++ b/Minecraft.Client/Linux/LinuxStubs.h @@ -9,6 +9,8 @@ #include #include #include +#include +#include #include #include #include From 300b1ff8412a228e9b3742affdf95821560ad7e6 Mon Sep 17 00:00:00 2001 From: Tropical <42101043+tropicaaal@users.noreply.github.com> Date: Mon, 2 Mar 2026 22:01:56 -0600 Subject: [PATCH 17/26] fix: more miscapitalized includes --- Minecraft.World/Path.cpp | 2 +- Minecraft.World/WoodSlabTile.cpp | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Minecraft.World/Path.cpp b/Minecraft.World/Path.cpp index 538917f6f..ff8a641ad 100644 --- a/Minecraft.World/Path.cpp +++ b/Minecraft.World/Path.cpp @@ -1,7 +1,7 @@ #include "stdafx.h" #include "net.minecraft.world.entity.h" #include "net.minecraft.world.level.pathfinder.h" -#include "path.h" +#include "Path.h" Path::~Path() { diff --git a/Minecraft.World/WoodSlabTile.cpp b/Minecraft.World/WoodSlabTile.cpp index ba3a98e50..d7a0e9e10 100644 --- a/Minecraft.World/WoodSlabTile.cpp +++ b/Minecraft.World/WoodSlabTile.cpp @@ -1,7 +1,7 @@ #include "stdafx.h" #include "WoodSlabTile.h" -#include "woodtile.h" -#include "treetile.h" +#include "WoodTile.h" +#include "TreeTile.h" #include "net.minecraft.world.level.h" #include "net.minecraft.world.level.biome.h" #include "net.minecraft.world.item.h" From 55964caf95b5e8ea889a253e2187f6a2a81c0d5b Mon Sep 17 00:00:00 2001 From: Tropical <42101043+tropicaaal@users.noreply.github.com> Date: Mon, 2 Mar 2026 22:09:49 -0600 Subject: [PATCH 18/26] feat: direct `OutputDebugString` functions to stderr --- Minecraft.Client/Linux/LinuxStubs.h | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/Minecraft.Client/Linux/LinuxStubs.h b/Minecraft.Client/Linux/LinuxStubs.h index 4af8de6d8..e153d0de8 100644 --- a/Minecraft.Client/Linux/LinuxStubs.h +++ b/Minecraft.Client/Linux/LinuxStubs.h @@ -550,6 +550,21 @@ static inline BOOL QueryPerformanceCounter(LARGE_INTEGER *lpPerformanceCount) return true; } +#ifndef _FINAL_BUILD +VOID OutputDebugStringW(LPCWSTR lpOutputString) +{ + fwprintf(stderr, lpOutputString); +} +VOID OutputDebugString(LPCSTR lpOutputString) +{ + fprintf(stderr, lpOutputString); +} + +VOID OutputDebugStringA(LPCSTR lpOutputString) +{ + fprintf(stderr, lpOutputString); +} +#endif // _CONTENT_PACKAGE #endif // LINUXSTUBS_H \ No newline at end of file From e3b63aa6903a12fabe5bb8200ea14a7bebd45e01 Mon Sep 17 00:00:00 2001 From: Tropical <42101043+tropicaaal@users.noreply.github.com> Date: Mon, 2 Mar 2026 22:14:31 -0600 Subject: [PATCH 19/26] fix: add missing winerror macro definitions --- Minecraft.Client/Linux/LinuxStubs.h | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/Minecraft.Client/Linux/LinuxStubs.h b/Minecraft.Client/Linux/LinuxStubs.h index e153d0de8..ffc7be279 100644 --- a/Minecraft.Client/Linux/LinuxStubs.h +++ b/Minecraft.Client/Linux/LinuxStubs.h @@ -67,6 +67,12 @@ typedef unsigned char byte; typedef short SHORT; typedef float FLOAT; +#define ERROR_SUCCESS 0L +#define ERROR_IO_PENDING 997L // dderror +#define ERROR_CANCELLED 1223L +//#define S_OK ((HRESULT)0x00000000L) +#define S_FALSE ((HRESULT)0x00000001L) + #define PAGE_READWRITE 0x04 #define MEM_LARGE_PAGES 0x20000000 #define MAXULONG_PTR ((ULONG_PTR)~0UL) From 8d24ebdad8c3d73918dfeea477b9769bf10d6bd5 Mon Sep 17 00:00:00 2001 From: ella love Date: Mon, 2 Mar 2026 23:17:28 -0500 Subject: [PATCH 20/26] feat: add stubs for Windows system time functions --- Minecraft.Client/Linux/LinuxStubs.h | 129 ++++++++++++++++++++++++++++ 1 file changed, 129 insertions(+) diff --git a/Minecraft.Client/Linux/LinuxStubs.h b/Minecraft.Client/Linux/LinuxStubs.h index 2e16db67d..0b3d2445c 100644 --- a/Minecraft.Client/Linux/LinuxStubs.h +++ b/Minecraft.Client/Linux/LinuxStubs.h @@ -18,6 +18,7 @@ #include #include #include +#include #define TRUE true #define FALSE false @@ -160,6 +161,18 @@ typedef struct _LINUXSTUBS_FIND_HANDLE { char pattern[MAX_PATH]; } _LINUXSTUBS_FIND_HANDLE; +// https://learn.microsoft.com/en-us/windows/win32/api/minwinbase/ns-minwinbase-systemtime +typedef struct _SYSTEMTIME { + WORD wYear; + WORD wMonth; + WORD wDayOfWeek; + WORD wDay; + WORD wHour; + WORD wMinute; + WORD wSecond; + WORD wMilliseconds; +} SYSTEMTIME, *PSYSTEMTIME, *LPSYSTEMTIME; + #define TLS_OUT_OF_INDEXES ((DWORD)0xFFFFFFFF) typedef pthread_mutex_t RTL_CRITICAL_SECTION; @@ -520,4 +533,120 @@ static inline BOOL FindClose(HANDLE hFindFile) return TRUE; } +// internal helper: convert FILETIME (100ns since 1601) to time_t (seconds since 1970) +static inline time_t _FileTimeToTimeT(const FILETIME& ft) +{ + ULONGLONG val = ((ULONGLONG)ft.dwHighDateTime << 32) | ft.dwLowDateTime; + const ULONGLONG EPOCH_DIFF = 116444736000000000ULL; // 100ns intervals between 1601-01-01 and 1970-01-01 + return (time_t)((val - EPOCH_DIFF) / 10000000ULL); +} + +// https://learn.microsoft.com/en-us/windows/win32/api/sysinfoapi/nf-sysinfoapi-getsystemtime +static inline VOID GetSystemTime(LPSYSTEMTIME lpSystemTime) +{ + struct timespec ts; +#ifdef CLOCK_REALTIME + clock_gettime(CLOCK_REALTIME, &ts); +#else + struct timeval tv; + gettimeofday(&tv, NULL); + ts.tv_sec = tv.tv_sec; + ts.tv_nsec = tv.tv_usec * 1000; +#endif + struct tm tm; + gmtime_r(&ts.tv_sec, &tm); // UTC + + 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 = ts.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; +#ifdef CLOCK_REALTIME + clock_gettime(CLOCK_REALTIME, &ts); +#else + struct timeval tv; + gettimeofday(&tv, NULL); + ts.tv_sec = tv.tv_sec; + ts.tv_nsec = tv.tv_usec * 1000; +#endif + struct tm tm; + localtime_r(&ts.tv_sec, &tm); // local time + + lpSystemTime->wYear = tm.tm_year + 1900; + lpSystemTime->wMonth = tm.tm_mon + 1; + lpSystemTime->wDayOfWeek = tm.tm_wday; + lpSystemTime->wDay = tm.tm_mday; + lpSystemTime->wHour = tm.tm_hour; + lpSystemTime->wMinute = tm.tm_min; + lpSystemTime->wSecond = tm.tm_sec; + lpSystemTime->wMilliseconds = ts.tv_nsec / 1000000; +} + +// https://learn.microsoft.com/en-us/windows/win32/api/timezoneapi/nf-timezoneapi-systemtimetofiletime +static inline BOOL SystemTimeToFileTime(const SYSTEMTIME *lpSystemTime, LPFILETIME lpFileTime) +{ + struct tm tm = {0}; + tm.tm_year = lpSystemTime->wYear - 1900; + tm.tm_mon = lpSystemTime->wMonth - 1; + tm.tm_mday = lpSystemTime->wDay; + tm.tm_hour = lpSystemTime->wHour; + tm.tm_min = lpSystemTime->wMinute; + tm.tm_sec = lpSystemTime->wSecond; + tm.tm_isdst = -1; // unknown + + // Convert to time_t assuming UTC + time_t t; + // Portable UTC mktime: temporarily set TZ to UTC + char *tz_old = getenv("TZ"); + setenv("TZ", "UTC", 1); + tzset(); + t = mktime(&tm); + if (tz_old) + setenv("TZ", tz_old, 1); + else + unsetenv("TZ"); + tzset(); + + if (t == (time_t)-1) + return FALSE; + + // Add milliseconds + ULONGLONG ft = ((ULONGLONG)t + 11644473600ULL) * 10000000ULL; + ft += lpSystemTime->wMilliseconds * 10000ULL; // 1ms = 10000 * 100ns + + lpFileTime->dwLowDateTime = (DWORD)(ft & 0xFFFFFFFF); + lpFileTime->dwHighDateTime = (DWORD)(ft >> 32); + return TRUE; +} + +// https://learn.microsoft.com/en-us/windows/win32/api/timezoneapi/nf-timezoneapi-filetimetosystemtime +static inline BOOL FileTimeToSystemTime(const FILETIME *lpFileTime, LPSYSTEMTIME lpSystemTime) +{ + time_t t = _FileTimeToTimeT(*lpFileTime); + ULONGLONG ft = ((ULONGLONG)lpFileTime->dwHighDateTime << 32) | lpFileTime->dwLowDateTime; + ULONGLONG remainder100ns = ft % 10000000ULL; // 1 second = 10^7 * 100ns + + struct tm tm; + gmtime_r(&t, &tm); // UTC + + lpSystemTime->wYear = tm.tm_year + 1900; + lpSystemTime->wMonth = tm.tm_mon + 1; + lpSystemTime->wDayOfWeek = tm.tm_wday; + lpSystemTime->wDay = tm.tm_mday; + lpSystemTime->wHour = tm.tm_hour; + lpSystemTime->wMinute = tm.tm_min; + lpSystemTime->wSecond = tm.tm_sec; + lpSystemTime->wMilliseconds = (WORD)(remainder100ns / 10000); // 1ms = 10000 * 100ns + return TRUE; +} + #endif // LINUXSTUBS_H \ No newline at end of file From bb741c8bec6b5de5e3d12500a207f4591fab7be6 Mon Sep 17 00:00:00 2001 From: Tropical <42101043+tropicaaal@users.noreply.github.com> Date: Mon, 2 Mar 2026 22:34:37 -0600 Subject: [PATCH 21/26] fix: `extraX64.h` --- Minecraft.Client/PS3/Leaderboards/PS3LeaderboardManager.cpp | 1 + Minecraft.Client/stdafx.h | 2 +- Minecraft.World/x64headers/extraX64.h | 1 + 3 files changed, 3 insertions(+), 1 deletion(-) diff --git a/Minecraft.Client/PS3/Leaderboards/PS3LeaderboardManager.cpp b/Minecraft.Client/PS3/Leaderboards/PS3LeaderboardManager.cpp index 1f6ebd694..fd9229fe7 100644 --- a/Minecraft.Client/PS3/Leaderboards/PS3LeaderboardManager.cpp +++ b/Minecraft.Client/PS3/Leaderboards/PS3LeaderboardManager.cpp @@ -1,6 +1,7 @@ #include "stdafx.h" #include "PS3LeaderboardManager.h" +#include "../../../Minecraft.World/x64headers/extraX64.h" #include "base64.h" diff --git a/Minecraft.Client/stdafx.h b/Minecraft.Client/stdafx.h index d9302801a..84cd90805 100644 --- a/Minecraft.Client/stdafx.h +++ b/Minecraft.Client/stdafx.h @@ -109,7 +109,7 @@ typedef XUID GameSessionUID; #include "../Minecraft.Client/xbox/network/extra.h" #else -#include "extraX64.h" +#include "../Minecraft.World/x64headers/extraX64.h" #endif #ifdef __PS3__ diff --git a/Minecraft.World/x64headers/extraX64.h b/Minecraft.World/x64headers/extraX64.h index 17e1479df..c4051728c 100644 --- a/Minecraft.World/x64headers/extraX64.h +++ b/Minecraft.World/x64headers/extraX64.h @@ -11,6 +11,7 @@ #define MULTITHREAD_ENABLE +typedef unsigned char byte; const int XUSER_INDEX_ANY = 255; const int XUSER_INDEX_FOCUS = 254; From eea516a139189edae46b6d2e690b31065da27a5f Mon Sep 17 00:00:00 2001 From: Tropical <42101043+tropicaaal@users.noreply.github.com> Date: Tue, 3 Mar 2026 00:45:10 -0600 Subject: [PATCH 22/26] fix: stdafx linux platform, typedefs --- CMakeLists.txt | 1 + Minecraft.Client/LevelRenderer.h | 2 ++ Minecraft.Client/Linux/LinuxStubs.h | 9 +++++++-- Minecraft.Client/stdafx.h | 21 +++++++++++++++++---- Minecraft.World/stdafx.h | 5 +++-- 5 files changed, 30 insertions(+), 8 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index a0fcade4f..4832ae6be 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -6,6 +6,7 @@ project(MinecraftConsoles C CXX) # Set target arch type if empty. Visual studio solution generator provides it. ################################################################################ set(CMAKE_VS_PLATFORM_NAME "Linux") +set(CMAKE_CXX_STANDARD 11) ################################################################################ # Global configuration types diff --git a/Minecraft.Client/LevelRenderer.h b/Minecraft.Client/LevelRenderer.h index 3a6a8572f..e9849a021 100644 --- a/Minecraft.Client/LevelRenderer.h +++ b/Minecraft.Client/LevelRenderer.h @@ -4,7 +4,9 @@ #include "OffsettedRenderList.h" #include "../Minecraft.World/JavaIntHash.h" #include "../Minecraft.World/Level.h" +#ifndef __linux__ #include +#endif // __linux__ #ifdef __PS3__ #include "C4JSpursJob.h" #endif diff --git a/Minecraft.Client/Linux/LinuxStubs.h b/Minecraft.Client/Linux/LinuxStubs.h index ffc7be279..997d53914 100644 --- a/Minecraft.Client/Linux/LinuxStubs.h +++ b/Minecraft.Client/Linux/LinuxStubs.h @@ -30,8 +30,10 @@ typedef unsigned int DWORD; typedef const char *LPCSTR; typedef bool BOOL; +typedef BOOL *PBOOL; +typedef BOOL *LPBOOL; typedef void* LPVOID; -typedef char WCHAR; +typedef wchar_t WCHAR; typedef unsigned char BYTE; typedef BYTE* PBYTE; typedef const wchar_t* LPCWSTR; @@ -51,6 +53,7 @@ typedef long LONG64, *PLONG64; typedef void VOID; typedef ULONGLONG PlayerUID; typedef DWORD WORD; +typedef DWORD* PDWORD; typedef struct { DWORD LowPart; LONG HighPart; @@ -62,8 +65,10 @@ typedef std::wstring LPWSTR; typedef unsigned char boolean; // java brainrot #define __debugbreak() #define __int32 int +typedef int64_t __int64; +typedef uint64_t __uint64; typedef unsigned long ULONG; -typedef unsigned char byte; +// typedef unsigned char byte; typedef short SHORT; typedef float FLOAT; diff --git a/Minecraft.Client/stdafx.h b/Minecraft.Client/stdafx.h index 84cd90805..140d27f0b 100644 --- a/Minecraft.Client/stdafx.h +++ b/Minecraft.Client/stdafx.h @@ -54,6 +54,15 @@ #include "PSVitaTypes.h" #include "PSVitaStubs.h" #include "PSVitaMaths.h" +#elif defined __linux__ +#define AUTO_VAR(_var, _val) auto _var = _val +#include +#include +#include +#include +#include +#include "Linux/LinuxStubs.h" +#include "Linux/xbox_valve.h" #else #define AUTO_VAR(_var, _val) auto _var = _val #include @@ -178,6 +187,12 @@ typedef XUID GameSessionUID; #include "Windows64/4JLibs/inc/4J_Profile.h" #include "Windows64/4JLibs/inc/4J_Render.h" #include "Windows64/4JLibs/inc/4J_Storage.h" +#elif defined __linux__ + // draw the rest of the owl + #include "Windows64/4JLibs/inc/4J_Input.h" + #include "Windows64/4JLibs/inc/4J_Profile.h" + #include "Windows64/4JLibs/inc/4J_Render.h" + #include "Windows64/4JLibs/inc/4J_Storage.h" #elif defined __PSVITA__ #include "PSVita/4JLibs/inc/4J_Input.h" #include "PSVita/4JLibs/inc/4J_Profile.h" @@ -280,13 +295,11 @@ typedef XUID GameSessionUID; #include "Windows64/Iggy/gdraw/gdraw_d3d11.h" #include "Windows64/Windows64_UIController.h" #elif defined __linux__ - #include "Windows64Media/strings.h" - #include "Linux/LinuxStubs.h" - #include "Linux/xbox_valve.h" // #include "Windows64/Sentient/MinecraftTelemetry.h" + #include "Windows64Media/strings.h" // #include "Windows64/Windows64_App.h" // #include "Windows64/Sentient/DynamicConfigurations.h" - // #include "Windows64/Sentient/SentientTelemetryCommon.h" + #include "Windows64/Sentient/SentientTelemetryCommon.h" // not platform-specific so we can steal win64's homework here for now. // #include "Windows64/GameConfig/Minecraft.spa.h" // #include "Windows64/XML/ATGXmlParser.h" // #include "Windows64/Social/SocialManager.h" diff --git a/Minecraft.World/stdafx.h b/Minecraft.World/stdafx.h index a1394e1cc..87ad6832f 100644 --- a/Minecraft.World/stdafx.h +++ b/Minecraft.World/stdafx.h @@ -9,8 +9,9 @@ #define AUTO_VAR(_var, _val) auto _var = _val #endif -typedef unsigned __int64; -typedef unsigned __uint64; +#if ( defined _XBOX || defined _WINDOWS64 || defined _DURANGO ) +typedef unsigned __int64 __uint64; +#endif #ifdef _WINDOWS64 #define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers From 5dd67bd334cba344d16a6eb750196a64e69891b5 Mon Sep 17 00:00:00 2001 From: ella love Date: Tue, 3 Mar 2026 02:14:24 -0500 Subject: [PATCH 23/26] feat: Stubs for Debug Outputs --- Minecraft.Client/Linux/LinuxStubs.h | 134 +++++++++++++--------------- 1 file changed, 64 insertions(+), 70 deletions(-) diff --git a/Minecraft.Client/Linux/LinuxStubs.h b/Minecraft.Client/Linux/LinuxStubs.h index eb751d246..16abe7d60 100644 --- a/Minecraft.Client/Linux/LinuxStubs.h +++ b/Minecraft.Client/Linux/LinuxStubs.h @@ -549,89 +549,65 @@ static inline time_t _FileTimeToTimeT(const FILETIME& ft) return (time_t)((val - EPOCH_DIFF) / 10000000ULL); } -// https://learn.microsoft.com/en-us/windows/win32/api/sysinfoapi/nf-sysinfoapi-getsystemtime -static inline VOID GetSystemTime(LPSYSTEMTIME lpSystemTime) +// internal helper: read the current wall clock into a timespec +static inline void _CurrentTimeSpec(struct timespec *ts) { - struct timespec ts; #ifdef CLOCK_REALTIME - clock_gettime(CLOCK_REALTIME, &ts); + clock_gettime(CLOCK_REALTIME, ts); #else struct timeval tv; gettimeofday(&tv, NULL); - ts.tv_sec = tv.tv_sec; - ts.tv_nsec = tv.tv_usec * 1000; + ts->tv_sec = tv.tv_sec; + ts->tv_nsec = tv.tv_usec * 1000; #endif - struct tm tm; - gmtime_r(&ts.tv_sec, &tm); // UTC +} - 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 = ts.tv_nsec / 1000000; // ns to ms +// 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 = (WORD)(tv_nsec / 1000000); // ns to ms +} + +// https://learn.microsoft.com/en-us/windows/win32/api/sysinfoapi/nf-sysinfoapi-getsystemtime +static inline VOID GetSystemTime(LPSYSTEMTIME lpSystemTime) +{ + struct timespec ts; _CurrentTimeSpec(&ts); + struct tm tm; gmtime_r(&ts.tv_sec, &tm); // UTC + _FillSystemTime(&tm, ts.tv_nsec, lpSystemTime); } // https://learn.microsoft.com/en-us/windows/win32/api/sysinfoapi/nf-sysinfoapi-getlocaltime static inline VOID GetLocalTime(LPSYSTEMTIME lpSystemTime) { - struct timespec ts; -#ifdef CLOCK_REALTIME - clock_gettime(CLOCK_REALTIME, &ts); -#else - struct timeval tv; - gettimeofday(&tv, NULL); - ts.tv_sec = tv.tv_sec; - ts.tv_nsec = tv.tv_usec * 1000; -#endif - struct tm tm; - localtime_r(&ts.tv_sec, &tm); // local time - - lpSystemTime->wYear = tm.tm_year + 1900; - lpSystemTime->wMonth = tm.tm_mon + 1; - lpSystemTime->wDayOfWeek = tm.tm_wday; - lpSystemTime->wDay = tm.tm_mday; - lpSystemTime->wHour = tm.tm_hour; - lpSystemTime->wMinute = tm.tm_min; - lpSystemTime->wSecond = tm.tm_sec; - lpSystemTime->wMilliseconds = ts.tv_nsec / 1000000; + 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-systemtimetofiletime static inline BOOL SystemTimeToFileTime(const SYSTEMTIME *lpSystemTime, LPFILETIME lpFileTime) { - struct tm tm = {0}; + struct tm tm = {}; tm.tm_year = lpSystemTime->wYear - 1900; tm.tm_mon = lpSystemTime->wMonth - 1; tm.tm_mday = lpSystemTime->wDay; tm.tm_hour = lpSystemTime->wHour; tm.tm_min = lpSystemTime->wMinute; tm.tm_sec = lpSystemTime->wSecond; - tm.tm_isdst = -1; // unknown - // Convert to time_t assuming UTC - time_t t; - // Portable UTC mktime: temporarily set TZ to UTC - char *tz_old = getenv("TZ"); - setenv("TZ", "UTC", 1); - tzset(); - t = mktime(&tm); - if (tz_old) - setenv("TZ", tz_old, 1); - else - unsetenv("TZ"); - tzset(); + time_t t = timegm(&tm); + if (t == (time_t)-1) return FALSE; - if (t == (time_t)-1) - return FALSE; - - // Add milliseconds ULONGLONG ft = ((ULONGLONG)t + 11644473600ULL) * 10000000ULL; - ft += lpSystemTime->wMilliseconds * 10000ULL; // 1ms = 10000 * 100ns - - lpFileTime->dwLowDateTime = (DWORD)(ft & 0xFFFFFFFF); + ft += lpSystemTime->wMilliseconds * 10000ULL; + lpFileTime->dwLowDateTime = (DWORD)(ft & 0xFFFFFFFF); lpFileTime->dwHighDateTime = (DWORD)(ft >> 32); return TRUE; } @@ -639,21 +615,12 @@ static inline BOOL SystemTimeToFileTime(const SYSTEMTIME *lpSystemTime, LPFILETI // https://learn.microsoft.com/en-us/windows/win32/api/timezoneapi/nf-timezoneapi-filetimetosystemtime static inline BOOL FileTimeToSystemTime(const FILETIME *lpFileTime, LPSYSTEMTIME lpSystemTime) { - time_t t = _FileTimeToTimeT(*lpFileTime); ULONGLONG ft = ((ULONGLONG)lpFileTime->dwHighDateTime << 32) | lpFileTime->dwLowDateTime; - ULONGLONG remainder100ns = ft % 10000000ULL; // 1 second = 10^7 * 100ns + time_t t = _FileTimeToTimeT(*lpFileTime); + long remainder_ns = (long)((ft % 10000000ULL) * 100); - struct tm tm; - gmtime_r(&t, &tm); // UTC - - lpSystemTime->wYear = tm.tm_year + 1900; - lpSystemTime->wMonth = tm.tm_mon + 1; - lpSystemTime->wDayOfWeek = tm.tm_wday; - lpSystemTime->wDay = tm.tm_mday; - lpSystemTime->wHour = tm.tm_hour; - lpSystemTime->wMinute = tm.tm_min; - lpSystemTime->wSecond = tm.tm_sec; - lpSystemTime->wMilliseconds = (WORD)(remainder100ns / 10000); // 1ms = 10000 * 100ns + struct tm tm; gmtime_r(&t, &tm); // UTC + _FillSystemTime(&tm, remainder_ns, lpSystemTime); return TRUE; } static inline DWORD GetTickCount() @@ -701,4 +668,31 @@ VOID OutputDebugStringA(LPCSTR lpOutputString) } #endif // _CONTENT_PACKAGE +// https://learn.microsoft.com/en-us/windows/win32/api/debugapi/nf-debugapi-outputdebugstringa +static inline VOID OutputDebugStringA(LPCSTR lpOutputString) +{ + if (!lpOutputString) return; + fputs(lpOutputString, stderr); +} + +// https://learn.microsoft.com/en-us/windows/win32/api/debugapi/nf-debugapi-outputdebugstringw +static inline VOID OutputDebugStringW(LPCWSTR lpOutputString) +{ + if (!lpOutputString) return; + // wchar_t* -> char* via wcstombs, respecting the current locale. + // Passing NULL as dst to wcstombs queries the required buffer length. + size_t len = wcstombs(NULL, lpOutputString, 0); + if (len == (size_t)-1) return; // unconvertible sequence + char *buf = (char *)malloc(len + 1); + if (!buf) return; + wcstombs(buf, lpOutputString, len + 1); + fputs(buf, stderr); + free(buf); +} + +static inline VOID OutputDebugString(LPCSTR lpOutputString) +{ + return OutputDebugStringA(lpOutputString); +} + #endif // LINUXSTUBS_H \ No newline at end of file From 9dc8d0b2b1a6bb03d08628f1b38c9fb009519f27 Mon Sep 17 00:00:00 2001 From: Tropical <42101043+tropicaaal@users.noreply.github.com> Date: Tue, 3 Mar 2026 01:30:13 -0600 Subject: [PATCH 24/26] start adding back win64 4jlibs includes --- Minecraft.Client/Common/Audio/SoundEngine.h | 2 +- Minecraft.Client/Linux/LinuxStubs.h | 3 +++ .../PSVita/Social/SocialManager.h | 4 ++++ .../Windows64/Iggy/include/iggy.h | 2 +- .../Windows64/Social/SocialManager.h | 2 ++ Minecraft.Client/stdafx.h | 23 ++++++++++--------- Minecraft.World/GameEventPacket.cpp | 1 - Minecraft.World/SparseDataStorage.h | 2 ++ 8 files changed, 25 insertions(+), 14 deletions(-) diff --git a/Minecraft.Client/Common/Audio/SoundEngine.h b/Minecraft.Client/Common/Audio/SoundEngine.h index d5f7eeccf..3e9059dad 100644 --- a/Minecraft.Client/Common/Audio/SoundEngine.h +++ b/Minecraft.Client/Common/Audio/SoundEngine.h @@ -2,7 +2,7 @@ class Mob; class Options; using namespace std; -#include "../../Minecraft.World/SoundTypes.h" +#include "../../../Minecraft.World/SoundTypes.h" enum eMUSICFILES { diff --git a/Minecraft.Client/Linux/LinuxStubs.h b/Minecraft.Client/Linux/LinuxStubs.h index 997d53914..9e40945f1 100644 --- a/Minecraft.Client/Linux/LinuxStubs.h +++ b/Minecraft.Client/Linux/LinuxStubs.h @@ -27,6 +27,8 @@ #define ZeroMemory RtlZeroMemory #define WINAPI +#define _vsnprintf_s vsnprintf; + typedef unsigned int DWORD; typedef const char *LPCSTR; typedef bool BOOL; @@ -65,6 +67,7 @@ typedef std::wstring LPWSTR; typedef unsigned char boolean; // java brainrot #define __debugbreak() #define __int32 int +#define CONST const typedef int64_t __int64; typedef uint64_t __uint64; typedef unsigned long ULONG; diff --git a/Minecraft.Client/PSVita/Social/SocialManager.h b/Minecraft.Client/PSVita/Social/SocialManager.h index 0b6f2b2d9..3f111a442 100644 --- a/Minecraft.Client/PSVita/Social/SocialManager.h +++ b/Minecraft.Client/PSVita/Social/SocialManager.h @@ -7,7 +7,11 @@ #ifndef _SOCIAL_MANAGER_H #define _SOCIAL_MANAGER_H +#ifndef __linux__ #include +#endif // __linux__#ifndef __linux__ +#include +#endif // __linux__ #define MAX_SOCIALPOST_CAPTION 60 #define MAX_SOCIALPOST_DESC 100 diff --git a/Minecraft.Client/Windows64/Iggy/include/iggy.h b/Minecraft.Client/Windows64/Iggy/include/iggy.h index 56638a321..d38ccae67 100644 --- a/Minecraft.Client/Windows64/Iggy/include/iggy.h +++ b/Minecraft.Client/Windows64/Iggy/include/iggy.h @@ -8,7 +8,7 @@ #define IggyVersion "1.2.30" #define IggyFlashVersion "9,1,2,30" -#include "rrcore.h" // base data types, macros +#include "rrCore.h" // base data types, macros RADDEFSTART diff --git a/Minecraft.Client/Windows64/Social/SocialManager.h b/Minecraft.Client/Windows64/Social/SocialManager.h index 0b6f2b2d9..cad278fe3 100644 --- a/Minecraft.Client/Windows64/Social/SocialManager.h +++ b/Minecraft.Client/Windows64/Social/SocialManager.h @@ -7,7 +7,9 @@ #ifndef _SOCIAL_MANAGER_H #define _SOCIAL_MANAGER_H +#ifndef __linux__ #include +#endif // __linux__ #define MAX_SOCIALPOST_CAPTION 60 #define MAX_SOCIALPOST_DESC 100 diff --git a/Minecraft.Client/stdafx.h b/Minecraft.Client/stdafx.h index 140d27f0b..2de47ad20 100644 --- a/Minecraft.Client/stdafx.h +++ b/Minecraft.Client/stdafx.h @@ -295,18 +295,19 @@ typedef XUID GameSessionUID; #include "Windows64/Iggy/gdraw/gdraw_d3d11.h" #include "Windows64/Windows64_UIController.h" #elif defined __linux__ - // #include "Windows64/Sentient/MinecraftTelemetry.h" + // FIXME: Make Linux/ versions of all of these + // #include "Windows64/Sentient/MinecraftTelemetry.h" // conflicts with Common/Telemetry/TelemetryManager.h, no idea whats up with that #include "Windows64Media/strings.h" - // #include "Windows64/Windows64_App.h" - // #include "Windows64/Sentient/DynamicConfigurations.h" - #include "Windows64/Sentient/SentientTelemetryCommon.h" // not platform-specific so we can steal win64's homework here for now. - // #include "Windows64/GameConfig/Minecraft.spa.h" - // #include "Windows64/XML/ATGXmlParser.h" - // #include "Windows64/Social/SocialManager.h" - // #include "Common/Audio/SoundEngine.h" - // #include "Windows64/Iggy/include/iggy.h" - // #include "Windows64/Iggy/gdraw/gdraw_d3d11.h" - // #include "Windows64/Windows64_UIController.h" + #include "Windows64/Windows64_App.h" + #include "Windows64/Sentient/DynamicConfigurations.h" + #include "Windows64/Sentient/SentientTelemetryCommon.h" + #include "Windows64/GameConfig/Minecraft.spa.h" + #include "Windows64/XML/ATGXmlParser.h" + #include "Windows64/Social/SocialManager.h" + #include "Common/Audio/SoundEngine.h" + #include "Windows64/Iggy/include/iggy.h" + #include "Windows64/Iggy/gdraw/gdraw_d3d11.h" + #include "Windows64/Windows64_UIController.h" #elif defined __PSVITA__ #include "PSVita/PSVita_App.h" #include "PSVitaMedia/strings.h" // TODO - create PSVita-specific version of this diff --git a/Minecraft.World/GameEventPacket.cpp b/Minecraft.World/GameEventPacket.cpp index 64b36ff41..34e0b2bf1 100644 --- a/Minecraft.World/GameEventPacket.cpp +++ b/Minecraft.World/GameEventPacket.cpp @@ -3,7 +3,6 @@ #include "InputOutputStream.h" #include "PacketListener.h" #include "GameEventPacket.h" -#include "../Minecraft.Client/PS3Media/strings.h" const int GameEventPacket::NO_RESPAWN_BED_AVAILABLE = 0; diff --git a/Minecraft.World/SparseDataStorage.h b/Minecraft.World/SparseDataStorage.h index 93d5c4244..192316447 100644 --- a/Minecraft.World/SparseDataStorage.h +++ b/Minecraft.World/SparseDataStorage.h @@ -1,5 +1,7 @@ #pragma once +#ifndef __linux__ #include "xmcore.h" +#endif // __linux__ // 4J added - Storage for data (ie the extra per tile storage). Data is normally stored as 4-bits per tile, in a DataLayer class of 16384 bytes ( 128 x 16 x 16 x 0.5 ) // This class provides more economical storage for such data by taking into consideration that it is quite common for large parts of the data to be very compressible (ie zero). From 5d5cd69a5e0a4842886b2e587b25702f2fc75616 Mon Sep 17 00:00:00 2001 From: ella love Date: Tue, 3 Mar 2026 02:35:41 -0500 Subject: [PATCH 25/26] update: fwprintf for wchar_t handling. Cleaned up old debug impl --- Minecraft.Client/Linux/LinuxStubs.h | 27 +-------------------------- 1 file changed, 1 insertion(+), 26 deletions(-) diff --git a/Minecraft.Client/Linux/LinuxStubs.h b/Minecraft.Client/Linux/LinuxStubs.h index 16abe7d60..e64e3c0a7 100644 --- a/Minecraft.Client/Linux/LinuxStubs.h +++ b/Minecraft.Client/Linux/LinuxStubs.h @@ -651,23 +651,6 @@ static inline BOOL QueryPerformanceCounter(LARGE_INTEGER *lpPerformanceCount) return true; } -#ifndef _FINAL_BUILD -VOID OutputDebugStringW(LPCWSTR lpOutputString) -{ - fwprintf(stderr, lpOutputString); -} - -VOID OutputDebugString(LPCSTR lpOutputString) -{ - fprintf(stderr, lpOutputString); -} - -VOID OutputDebugStringA(LPCSTR lpOutputString) -{ - fprintf(stderr, lpOutputString); -} -#endif // _CONTENT_PACKAGE - // https://learn.microsoft.com/en-us/windows/win32/api/debugapi/nf-debugapi-outputdebugstringa static inline VOID OutputDebugStringA(LPCSTR lpOutputString) { @@ -679,15 +662,7 @@ static inline VOID OutputDebugStringA(LPCSTR lpOutputString) static inline VOID OutputDebugStringW(LPCWSTR lpOutputString) { if (!lpOutputString) return; - // wchar_t* -> char* via wcstombs, respecting the current locale. - // Passing NULL as dst to wcstombs queries the required buffer length. - size_t len = wcstombs(NULL, lpOutputString, 0); - if (len == (size_t)-1) return; // unconvertible sequence - char *buf = (char *)malloc(len + 1); - if (!buf) return; - wcstombs(buf, lpOutputString, len + 1); - fputs(buf, stderr); - free(buf); + fprintf(stderr, "%ls", lpOutputString); } static inline VOID OutputDebugString(LPCSTR lpOutputString) From b5ac1ac1904bbd9956938af6cf4011c45170ccb2 Mon Sep 17 00:00:00 2001 From: Tropical <42101043+tropicaaal@users.noreply.github.com> Date: Tue, 3 Mar 2026 01:42:26 -0600 Subject: [PATCH 26/26] feat: stub `CreateEvent` --- Minecraft.Client/Linux/LinuxStubs.h | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/Minecraft.Client/Linux/LinuxStubs.h b/Minecraft.Client/Linux/LinuxStubs.h index 7335c620f..3e5a0febe 100644 --- a/Minecraft.Client/Linux/LinuxStubs.h +++ b/Minecraft.Client/Linux/LinuxStubs.h @@ -678,4 +678,20 @@ static inline VOID OutputDebugString(LPCSTR lpOutputString) return OutputDebugStringA(lpOutputString); } +typedef struct { + pthread_mutex_t mutex; + pthread_cond_t cond; + int signaled; + int manual_reset; +} Event; + +HANDLE CreateEvent(int manual_reset, int initial_state) { + Event* ev = (Event*)malloc(sizeof(Event)); + pthread_mutex_init(&ev->mutex, NULL); + pthread_cond_init(&ev->cond, NULL); + ev->signaled = initial_state; + ev->manual_reset = manual_reset; + return (HANDLE)ev; +} + #endif // LINUXSTUBS_H \ No newline at end of file