From 43b9d829c8ef52fc8fddbdfc72a348b55f94c8f6 Mon Sep 17 00:00:00 2001 From: qloak Date: Tue, 14 Jul 2026 10:54:43 -0700 Subject: [PATCH 1/7] fixed Windows build for networking branch --- Minecraft.Client/Extrax64Stubs.cpp | 17 ++++++++++++----- Minecraft.World/AbstractContainerMenu.cpp | 4 ++-- Minecraft.World/ByteArrayTag.h | 2 +- Minecraft.World/OldChunkStorage.cpp | 2 +- Minecraft.World/RegionFileCache.cpp | 5 +---- Minecraft.World/RegionFileCache.h | 2 +- Minecraft.World/Tag.cpp | 2 +- 7 files changed, 19 insertions(+), 15 deletions(-) diff --git a/Minecraft.Client/Extrax64Stubs.cpp b/Minecraft.Client/Extrax64Stubs.cpp index 7fff9b09..e7d5fd6a 100644 --- a/Minecraft.Client/Extrax64Stubs.cpp +++ b/Minecraft.Client/Extrax64Stubs.cpp @@ -211,22 +211,29 @@ ULONG_PTR IQNetPlayer::GetCustomDataValue() { return m_customData; } -IQNetPlayer IQNet::m_player[4]; +static IQNetPlayer s_playerArray[4]; +IQNetPlayer *IQNet::m_player = s_playerArray; +DWORD IQNet::s_playerCapacity = 4; +DWORD IQNet::s_playerCount = 0; +bool IQNet::s_isHosting = false; bool _bQNetStubGameRunning = false; HRESULT IQNet::AddLocalPlayerByUserIndex(DWORD dwUserIndex){ return S_OK; } +void IQNet::SetPlayerCapacity(DWORD capacity) { s_playerCapacity = capacity; } +DWORD IQNet::GetPlayerCapacity() { return s_playerCapacity; } IQNetPlayer *IQNet::GetHostPlayer() { return &m_player[0]; } IQNetPlayer *IQNet::GetLocalPlayerByUserIndex(DWORD dwUserIndex) { return &m_player[dwUserIndex]; } IQNetPlayer *IQNet::GetPlayerByIndex(DWORD dwPlayerIndex) { return &m_player[0]; } IQNetPlayer *IQNet::GetPlayerBySmallId(BYTE SmallId){ return &m_player[0]; } IQNetPlayer *IQNet::GetPlayerByXuid(PlayerUID xuid){ return &m_player[0]; } -DWORD IQNet::GetPlayerCount() { return 1; } +DWORD IQNet::GetPlayerCount() { return s_playerCount; } QNET_STATE IQNet::GetState() { return _bQNetStubGameRunning ? QNET_STATE_GAME_PLAY : QNET_STATE_IDLE; } -bool IQNet::IsHost() { return true; } +bool IQNet::IsHost() { return s_isHosting; } HRESULT IQNet::JoinGameFromInviteInfo(DWORD dwUserIndex, DWORD dwUserMask, const INVITE_INFO *pInviteInfo) { return S_OK; } -void IQNet::HostGame() { _bQNetStubGameRunning = true; } -void IQNet::EndGame() { _bQNetStubGameRunning = false; } +void IQNet::HostGame() { _bQNetStubGameRunning = true; s_isHosting = true; } +void IQNet::ClientJoinGame() { _bQNetStubGameRunning = true; s_isHosting = false; } +void IQNet::EndGame() { _bQNetStubGameRunning = false; s_isHosting = false; } DWORD MinecraftDynamicConfigurations::GetTrialTime() { return DYNAMIC_CONFIG_DEFAULT_TRIAL_TIME; } diff --git a/Minecraft.World/AbstractContainerMenu.cpp b/Minecraft.World/AbstractContainerMenu.cpp index 6e00be6d..f775fb7a 100644 --- a/Minecraft.World/AbstractContainerMenu.cpp +++ b/Minecraft.World/AbstractContainerMenu.cpp @@ -552,13 +552,13 @@ bool AbstractContainerMenu::isPauseScreen() void AbstractContainerMenu::setItem(unsigned int slot, shared_ptr item) { - if (slot >= slots->size()) return; + if (slot >= slots.size()) return; getSlot(slot)->set(item); } void AbstractContainerMenu::setAll(ItemInstanceArray *items) { - for (unsigned int i = 0; i < items->length && i < slots->size(); i++) + for (unsigned int i = 0; i < items->length && i < slots.size(); i++) { getSlot(i)->set( (*items)[i] ); } diff --git a/Minecraft.World/ByteArrayTag.h b/Minecraft.World/ByteArrayTag.h index 6b797845..0e87607f 100644 --- a/Minecraft.World/ByteArrayTag.h +++ b/Minecraft.World/ByteArrayTag.h @@ -18,7 +18,7 @@ public: dos->write(data); } - void load(DataInput *dis) + void load(DataInput *dis, int tagDepth) { int length = dis->readInt(); if (length < 0 || length > 2 * 1024 * 1024) length = 0; diff --git a/Minecraft.World/OldChunkStorage.cpp b/Minecraft.World/OldChunkStorage.cpp index acfaecc3..54d510a4 100644 --- a/Minecraft.World/OldChunkStorage.cpp +++ b/Minecraft.World/OldChunkStorage.cpp @@ -490,7 +490,7 @@ LevelChunk *OldChunkStorage::load(Level *level, DataInputStream *dis) { CompoundTag *teTag = tileTicks->get(i); - level->forceAddTileTick(teTag->getInt(L"x"), teTag->getInt(L"y"), teTag->getInt(L"z"), teTag->getInt(L"i"), teTag->getInt(L"t")); + level->forceAddTileTick(teTag->getInt(L"x"), teTag->getInt(L"y"), teTag->getInt(L"z"), teTag->getInt(L"i"), teTag->getInt(L"t"), teTag->getInt(L"p")); } } } diff --git a/Minecraft.World/RegionFileCache.cpp b/Minecraft.World/RegionFileCache.cpp index 06bd498a..75485ceb 100644 --- a/Minecraft.World/RegionFileCache.cpp +++ b/Minecraft.World/RegionFileCache.cpp @@ -126,7 +126,4 @@ DataOutputStream *RegionFileCache::_getChunkDataOutputStream(ConsoleSaveFile *sa } -RegionFileCache::~RegionFileCache() -{ - _clear(); -} + diff --git a/Minecraft.World/RegionFileCache.h b/Minecraft.World/RegionFileCache.h index 9361ca4f..ae660baa 100644 --- a/Minecraft.World/RegionFileCache.h +++ b/Minecraft.World/RegionFileCache.h @@ -17,7 +17,7 @@ private: public: // Made public and non-static so we can have a cache for input and output files RegionFileCache() { InitializeCriticalSectionAndSpinCount(&m_cs, 4000); } - ~RegionFileCache() { DeleteCriticalSection(&m_cs); } + ~RegionFileCache() { _clear(); DeleteCriticalSection(&m_cs); } RegionFile *_getRegionFile(ConsoleSaveFile *saveFile, const wstring &prefix, int chunkX, int chunkZ); // 4J - TODO was synchronized void _clear(); // 4J - TODO was synchronized diff --git a/Minecraft.World/Tag.cpp b/Minecraft.World/Tag.cpp index 2cd9c229..f27130ae 100644 --- a/Minecraft.World/Tag.cpp +++ b/Minecraft.World/Tag.cpp @@ -115,7 +115,7 @@ Tag *Tag::readNamedTag(DataInput *dis) Tag *tag = newTag(type, name); if (tag == NULL) { depth--; return new EndTag(); } - tag->load(dis); + tag->load(dis, depth + 1); depth--; return tag; } -- 2.54.0 From 0eea592b868e4410fc63f45fd2d1a0e234fde4b5 Mon Sep 17 00:00:00 2001 From: qloak Date: Tue, 14 Jul 2026 12:16:55 -0700 Subject: [PATCH 2/7] fix: player list count, leaderboard stubs --- .../Leaderboards/LeaderboardManager.cpp | 2 ++ .../Network/PlatformNetworkManagerStub.h | 2 +- .../Common/UI/UIScene_InGameInfoMenu.cpp | 10 +++++++-- Minecraft.Client/Extrax64Stubs.cpp | 4 ++-- Minecraft.Client/Minecraft.Client.vcxproj | 2 +- Minecraft.Client/Minecraft.cpp | 2 +- Minecraft.Client/Options.cpp | 2 +- .../Leaderboards/WindowsLeaderboardManager.h | 22 ++++++++++++++----- .../Windows64/Windows64_Minecraft.cpp | 2 +- Minecraft.World/Minecraft.World.vcxproj | 2 +- 10 files changed, 34 insertions(+), 16 deletions(-) diff --git a/Minecraft.Client/Common/Leaderboards/LeaderboardManager.cpp b/Minecraft.Client/Common/Leaderboards/LeaderboardManager.cpp index 007afadc..d7bed46f 100644 --- a/Minecraft.Client/Common/Leaderboards/LeaderboardManager.cpp +++ b/Minecraft.Client/Common/Leaderboards/LeaderboardManager.cpp @@ -9,7 +9,9 @@ const wstring LeaderboardManager::filterNames[eNumFilterModes] = L"Friends", L"MyScore", L"TopRank" }; +#if !defined(_WINDOWS64) && !defined(_DURANGO) && !defined(__ORBIS__) && !defined(__PS3__) && !defined(__PSVITA__) && !defined(_XBOX) LeaderboardManager *LeaderboardManager::m_instance = NULL; +#endif void LeaderboardManager::DeleteInstance() { diff --git a/Minecraft.Client/Common/Network/PlatformNetworkManagerStub.h b/Minecraft.Client/Common/Network/PlatformNetworkManagerStub.h index a45a5e47..294980d5 100644 --- a/Minecraft.Client/Common/Network/PlatformNetworkManagerStub.h +++ b/Minecraft.Client/Common/Network/PlatformNetworkManagerStub.h @@ -165,6 +165,6 @@ private: void NotifyPlayerJoined( IQNetPlayer *pQNetPlayer ); #ifndef _XBOX - void FakeLocalPlayerJoined() { NotifyPlayerJoined(m_pIQNet->GetLocalPlayerByUserIndex(0)); } + void FakeLocalPlayerJoined() { AddLocalPlayerByUserIndex(0); } #endif }; diff --git a/Minecraft.Client/Common/UI/UIScene_InGameInfoMenu.cpp b/Minecraft.Client/Common/UI/UIScene_InGameInfoMenu.cpp index 092b7156..878e9249 100644 --- a/Minecraft.Client/Common/UI/UIScene_InGameInfoMenu.cpp +++ b/Minecraft.Client/Common/UI/UIScene_InGameInfoMenu.cpp @@ -93,7 +93,9 @@ void UIScene_InGameInfoMenu::updateTooltips() if(CGameNetworkManager::usingAdhocMode()) keyX = -1; #endif - INetworkPlayer *selectedPlayer = g_NetworkManager.GetPlayerBySmallId(m_players[m_playerList.getCurrentSelection()]->m_smallId); + INetworkPlayer *selectedPlayer = NULL; + if(m_playerList.getCurrentSelection() < m_players.size()) + selectedPlayer = g_NetworkManager.GetPlayerBySmallId(m_players[m_playerList.getCurrentSelection()]->m_smallId); int keyA = -1; Minecraft *pMinecraft = Minecraft::GetInstance(); @@ -335,7 +337,9 @@ void UIScene_InGameInfoMenu::handlePress(F64 controlId, F64 childId) break; case eControl_GamePlayers: int currentSelection = (int)childId; - INetworkPlayer *selectedPlayer = g_NetworkManager.GetPlayerBySmallId(m_players[currentSelection]->m_smallId); + INetworkPlayer *selectedPlayer = NULL; + if(currentSelection < m_players.size()) + selectedPlayer = g_NetworkManager.GetPlayerBySmallId(m_players[currentSelection]->m_smallId); Minecraft *pMinecraft = Minecraft::GetInstance(); shared_ptr localPlayer = pMinecraft->localplayers[m_iPad]; @@ -387,6 +391,8 @@ void UIScene_InGameInfoMenu::handleFocusChange(F64 controlId, F64 childId) void UIScene_InGameInfoMenu::OnPlayerChanged(void *callbackParam, INetworkPlayer *pPlayer, bool leaving) { + if(pPlayer == NULL) return; + app.DebugPrintf(" Player \"%ls\" %s (smallId: %d)\n", pPlayer->GetOnlineName(), leaving ? "leaving" : "joining", pPlayer->GetSmallId()); UIScene_InGameInfoMenu *scene = (UIScene_InGameInfoMenu *)callbackParam; diff --git a/Minecraft.Client/Extrax64Stubs.cpp b/Minecraft.Client/Extrax64Stubs.cpp index e7d5fd6a..19dcd797 100644 --- a/Minecraft.Client/Extrax64Stubs.cpp +++ b/Minecraft.Client/Extrax64Stubs.cpp @@ -231,8 +231,8 @@ DWORD IQNet::GetPlayerCount() { return s_playerCount; } QNET_STATE IQNet::GetState() { return _bQNetStubGameRunning ? QNET_STATE_GAME_PLAY : QNET_STATE_IDLE; } bool IQNet::IsHost() { return s_isHosting; } HRESULT IQNet::JoinGameFromInviteInfo(DWORD dwUserIndex, DWORD dwUserMask, const INVITE_INFO *pInviteInfo) { return S_OK; } -void IQNet::HostGame() { _bQNetStubGameRunning = true; s_isHosting = true; } -void IQNet::ClientJoinGame() { _bQNetStubGameRunning = true; s_isHosting = false; } +void IQNet::HostGame() { _bQNetStubGameRunning = true; s_isHosting = true; if(s_playerCount == 0) s_playerCount = 1; } +void IQNet::ClientJoinGame() { _bQNetStubGameRunning = true; s_isHosting = false; if(s_playerCount == 0) s_playerCount = 1; } void IQNet::EndGame() { _bQNetStubGameRunning = false; s_isHosting = false; } DWORD MinecraftDynamicConfigurations::GetTrialTime() { return DYNAMIC_CONFIG_DEFAULT_TRIAL_TIME; } diff --git a/Minecraft.Client/Minecraft.Client.vcxproj b/Minecraft.Client/Minecraft.Client.vcxproj index b7b62029..30552ddc 100644 --- a/Minecraft.Client/Minecraft.Client.vcxproj +++ b/Minecraft.Client/Minecraft.Client.vcxproj @@ -34044,7 +34044,7 @@ xcopy /q /y /i /s /e $(ProjectDir)Durango\CU $(LayoutDir)Image\Loose\CUfalse false false - true + false false false false diff --git a/Minecraft.Client/Minecraft.cpp b/Minecraft.Client/Minecraft.cpp index 07ab47d9..35261db8 100644 --- a/Minecraft.Client/Minecraft.cpp +++ b/Minecraft.Client/Minecraft.cpp @@ -1858,7 +1858,7 @@ void Minecraft::run_middle() achievementPopup->render(); PIXBeginNamedEvent(0,"Sleeping"); - Sleep(0); // 4J - was Thread.yield() + //Sleep(0); // 4J - was Thread.yield() PIXEndNamedEvent(); // if (Keyboard::isKeyDown(Keyboard::KEY_F7)) Display.update(); // 4J - removed condition diff --git a/Minecraft.Client/Options.cpp b/Minecraft.Client/Options.cpp index 33e94060..c0095d6e 100644 --- a/Minecraft.Client/Options.cpp +++ b/Minecraft.Client/Options.cpp @@ -116,7 +116,7 @@ void Options::init() bobView = true; anaglyph3d = false; advancedOpengl = false; - framerateLimit = 2; + framerateLimit = 0; fancyGraphics = true; ambientOcclusion = true; renderClouds = true; diff --git a/Minecraft.Client/Windows64/Leaderboards/WindowsLeaderboardManager.h b/Minecraft.Client/Windows64/Leaderboards/WindowsLeaderboardManager.h index a469ba04..ec7f2d60 100644 --- a/Minecraft.Client/Windows64/Leaderboards/WindowsLeaderboardManager.h +++ b/Minecraft.Client/Windows64/Leaderboards/WindowsLeaderboardManager.h @@ -17,13 +17,23 @@ public: virtual void DeleteSession() {} //Write the given stats - //This is called synchronously and will not free any memory allocated for views when it is done + virtual bool WriteStats(unsigned int viewCount, ViewIn views) { return true; } - virtual bool WriteStats(unsigned int viewCount, ViewIn views) { return false; } - - virtual bool ReadStats_Friends(LeaderboardReadListener *callback, int difficulty, EStatsType type, PlayerUID myUID) { return false; } - virtual bool ReadStats_MyScore(LeaderboardReadListener *callback, int difficulty, EStatsType type, PlayerUID myUID, unsigned int readCount) { return false; } - virtual bool ReadStats_TopRank(LeaderboardReadListener *callback, int difficulty, EStatsType type, unsigned int startIndex, unsigned int readCount) { return false; } + virtual bool ReadStats_Friends(LeaderboardReadListener *callback, int difficulty, EStatsType type, PlayerUID myUID, unsigned int startIndex, unsigned int readCount) { + ReadView view = { 0, NULL }; + callback->OnStatsReadComplete(eStatsReturn_Success, 0, view); + return true; + } + virtual bool ReadStats_MyScore(LeaderboardReadListener *callback, int difficulty, EStatsType type, PlayerUID myUID, unsigned int readCount) { + ReadView view = { 0, NULL }; + callback->OnStatsReadComplete(eStatsReturn_Success, 0, view); + return true; + } + virtual bool ReadStats_TopRank(LeaderboardReadListener *callback, int difficulty, EStatsType type, unsigned int startIndex, unsigned int readCount) { + ReadView view = { 0, NULL }; + callback->OnStatsReadComplete(eStatsReturn_Success, 0, view); + return true; + } //Perform a flush of the stats virtual void FlushStats() {} diff --git a/Minecraft.Client/Windows64/Windows64_Minecraft.cpp b/Minecraft.Client/Windows64/Windows64_Minecraft.cpp index baeeda99..0aae8055 100644 --- a/Minecraft.Client/Windows64/Windows64_Minecraft.cpp +++ b/Minecraft.Client/Windows64/Windows64_Minecraft.cpp @@ -498,7 +498,7 @@ app.DebugPrintf("width: %d, height: %d\n", width, height); DXGI_SWAP_CHAIN_DESC sd; ZeroMemory( &sd, sizeof( sd ) ); - sd.BufferCount = 1; + sd.BufferCount = 2; sd.BufferDesc.Width = width; sd.BufferDesc.Height = height; sd.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; diff --git a/Minecraft.World/Minecraft.World.vcxproj b/Minecraft.World/Minecraft.World.vcxproj index 5df0d959..4169c2d7 100644 --- a/Minecraft.World/Minecraft.World.vcxproj +++ b/Minecraft.World/Minecraft.World.vcxproj @@ -1124,7 +1124,7 @@ Sync false $(OutDir)$(ProjectName).pch - MultiThreadedDebugDLL + MultiThreadedDebug _LARGE_WORLDS;_DEBUG_MENUS_ENABLED;_DEBUG;_LIB;_CRT_NON_CONFORMING_SWPRINTFS;_CRT_SECURE_NO_WARNINGS;_WINDOWS64;%(PreprocessorDefinitions) Disabled true -- 2.54.0 From b4ed4a1a92177427ffe7fd8bd8d5d0387b6708f3 Mon Sep 17 00:00:00 2001 From: qloak Date: Tue, 14 Jul 2026 12:57:08 -0700 Subject: [PATCH 3/7] fix horse layered texture rendering for platforms without multitexture support --- Minecraft.Client/HorseRenderer.cpp | 32 +++++++++++++++++++++++++++--- Minecraft.Client/Textures.cpp | 6 +++++- 2 files changed, 34 insertions(+), 4 deletions(-) diff --git a/Minecraft.Client/HorseRenderer.cpp b/Minecraft.Client/HorseRenderer.cpp index 08ba49a2..97f75df1 100644 --- a/Minecraft.Client/HorseRenderer.cpp +++ b/Minecraft.Client/HorseRenderer.cpp @@ -46,9 +46,35 @@ void HorseRenderer::renderModel(shared_ptr mob, float wp, float ws } else { - EntityRenderer::bindTexture(mob); - model->render(mob, wp, ws, bob, headRotMinusBodyRot, headRotx, scale, true); - // Ensure that any extra layers of texturing are disabled after rendering this horse + shared_ptr horse = dynamic_pointer_cast(mob); + ResourceLocation *location = getTextureLocation(mob); + + // Pass 1: Bind only the coat texture (first valid layer) and render opaque + int coatTex = location->getTexture(0); + if( coatTex != -1 ) + { + RenderManager.TextureBind(entityRenderDispatcher->textures->loadTexture(coatTex)); + } + model->render(mob, wp, ws, bob, headRotMinusBodyRot, headRotx, scale, true); + + // Pass 2: If horse has armor, find the armor texture in the layers and render with blending + int armorType = horse->getArmorType(); + if( armorType > 0 ) + { + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + for( int i = 1; i < location->getTextureCount(); i++ ) + { + int texId = location->getTexture(i); + if( texId != -1 ) + { + RenderManager.TextureBind(entityRenderDispatcher->textures->loadTexture(texId)); + model->render(mob, wp, ws, bob, headRotMinusBodyRot, headRotx, scale, true); + } + } + glDisable(GL_BLEND); + } + RenderManager.TextureBind(-1); } } diff --git a/Minecraft.Client/Textures.cpp b/Minecraft.Client/Textures.cpp index 9a9b79fd..bce056be 100644 --- a/Minecraft.Client/Textures.cpp +++ b/Minecraft.Client/Textures.cpp @@ -434,7 +434,11 @@ void Textures::bindTextureLayers(ResourceLocation *resource) for( int i = 0; i < layers; i++ ) { - RenderManager.TextureBind(loadTexture(resource->getTexture(i))); + int texId = resource->getTexture(i); + if( texId != -1 ) + { + RenderManager.TextureBind(loadTexture(texId)); + } } } -- 2.54.0 From 3b4a7e3437f72c55b729f8a2c2b81c37eb9a5069 Mon Sep 17 00:00:00 2001 From: qloak Date: Tue, 14 Jul 2026 13:30:42 -0700 Subject: [PATCH 4/7] fix: fixed name tag Y-position for tall mobs (wither, iron golem, wither skeleton) --- Minecraft.Client/LivingEntityRenderer.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Minecraft.Client/LivingEntityRenderer.cpp b/Minecraft.Client/LivingEntityRenderer.cpp index 9e8682c7..7f4a3258 100644 --- a/Minecraft.Client/LivingEntityRenderer.cpp +++ b/Minecraft.Client/LivingEntityRenderer.cpp @@ -491,7 +491,7 @@ void LivingEntityRenderer::renderNameTag(shared_ptr mob, const wst float s = 1 / 60.0f * size; glPushMatrix(); - glTranslatef((float) x, (float) y + 2.3f, (float) z); + glTranslatef((float) x, (float) y + mob->bbHeight + 0.5f, (float) z); glNormal3f(0, 1, 0); glRotatef(-this->entityRenderDispatcher->playerRotY, 0, 1, 0); -- 2.54.0 From d666d4703571e28db76792b46f19c29bfbf116c5 Mon Sep 17 00:00:00 2001 From: qloak Date: Tue, 14 Jul 2026 13:59:06 -0700 Subject: [PATCH 5/7] fix: creeper hovering off the ground --- Minecraft.Client/CreeperModel.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Minecraft.Client/CreeperModel.cpp b/Minecraft.Client/CreeperModel.cpp index 066e0b55..14c7e55f 100644 --- a/Minecraft.Client/CreeperModel.cpp +++ b/Minecraft.Client/CreeperModel.cpp @@ -6,7 +6,7 @@ // 4J - added void CreeperModel::_init(float g) { - int yo = 4; + int yo = 6; head = new ModelPart(this, 0, 0); head->addBox(-4, - 8, -4, 8, 8, 8, g); // Head -- 2.54.0 From 4247c74ef3c1098bad51615eb01b3f680030d8bd Mon Sep 17 00:00:00 2001 From: qloak Date: Tue, 14 Jul 2026 14:12:41 -0700 Subject: [PATCH 6/7] fix: weakness potion effect description and damage value (0.5 -> 4 per level) --- Minecraft.World/AttackDamageMobEffect.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Minecraft.World/AttackDamageMobEffect.cpp b/Minecraft.World/AttackDamageMobEffect.cpp index 483c9a72..a2955db7 100644 --- a/Minecraft.World/AttackDamageMobEffect.cpp +++ b/Minecraft.World/AttackDamageMobEffect.cpp @@ -10,7 +10,7 @@ double AttackDamageMobEffect::getAttributeModifierValue(int amplifier, Attribute { if (id == MobEffect::weakness->id) { - return -0.5f * (amplifier + 1); + return -4.0f * (amplifier + 1); } else { -- 2.54.0 From 502d95bce2976bb766bfe4874e7809813d8d4d3e Mon Sep 17 00:00:00 2001 From: qloak Date: Tue, 14 Jul 2026 22:15:58 +0100 Subject: [PATCH 7/7] fix: Windows build for networking branch + player list + leaderboard + horse rendering (#2) title Reviewed-on: https://git.neolegacy.dev/pieeebot/mc_pieLCE/pulls/2 Co-authored-by: qloak Co-committed-by: qloak --- .../Leaderboards/LeaderboardManager.cpp | 2 ++ .../Network/PlatformNetworkManagerStub.h | 2 +- .../Common/UI/UIScene_InGameInfoMenu.cpp | 10 ++++-- Minecraft.Client/CreeperModel.cpp | 2 +- Minecraft.Client/Extrax64Stubs.cpp | 17 +++++++--- Minecraft.Client/HorseRenderer.cpp | 32 +++++++++++++++++-- Minecraft.Client/LivingEntityRenderer.cpp | 2 +- Minecraft.Client/Minecraft.Client.vcxproj | 2 +- Minecraft.Client/Minecraft.cpp | 2 +- Minecraft.Client/Options.cpp | 2 +- Minecraft.Client/Textures.cpp | 6 +++- .../Leaderboards/WindowsLeaderboardManager.h | 22 +++++++++---- .../Windows64/Windows64_Minecraft.cpp | 2 +- Minecraft.World/AbstractContainerMenu.cpp | 4 +-- Minecraft.World/AttackDamageMobEffect.cpp | 2 +- Minecraft.World/ByteArrayTag.h | 2 +- Minecraft.World/Minecraft.World.vcxproj | 2 +- Minecraft.World/OldChunkStorage.cpp | 2 +- Minecraft.World/RegionFileCache.cpp | 5 +-- Minecraft.World/RegionFileCache.h | 2 +- Minecraft.World/Tag.cpp | 2 +- 21 files changed, 88 insertions(+), 36 deletions(-) diff --git a/Minecraft.Client/Common/Leaderboards/LeaderboardManager.cpp b/Minecraft.Client/Common/Leaderboards/LeaderboardManager.cpp index 007afadc..d7bed46f 100644 --- a/Minecraft.Client/Common/Leaderboards/LeaderboardManager.cpp +++ b/Minecraft.Client/Common/Leaderboards/LeaderboardManager.cpp @@ -9,7 +9,9 @@ const wstring LeaderboardManager::filterNames[eNumFilterModes] = L"Friends", L"MyScore", L"TopRank" }; +#if !defined(_WINDOWS64) && !defined(_DURANGO) && !defined(__ORBIS__) && !defined(__PS3__) && !defined(__PSVITA__) && !defined(_XBOX) LeaderboardManager *LeaderboardManager::m_instance = NULL; +#endif void LeaderboardManager::DeleteInstance() { diff --git a/Minecraft.Client/Common/Network/PlatformNetworkManagerStub.h b/Minecraft.Client/Common/Network/PlatformNetworkManagerStub.h index a45a5e47..294980d5 100644 --- a/Minecraft.Client/Common/Network/PlatformNetworkManagerStub.h +++ b/Minecraft.Client/Common/Network/PlatformNetworkManagerStub.h @@ -165,6 +165,6 @@ private: void NotifyPlayerJoined( IQNetPlayer *pQNetPlayer ); #ifndef _XBOX - void FakeLocalPlayerJoined() { NotifyPlayerJoined(m_pIQNet->GetLocalPlayerByUserIndex(0)); } + void FakeLocalPlayerJoined() { AddLocalPlayerByUserIndex(0); } #endif }; diff --git a/Minecraft.Client/Common/UI/UIScene_InGameInfoMenu.cpp b/Minecraft.Client/Common/UI/UIScene_InGameInfoMenu.cpp index 092b7156..878e9249 100644 --- a/Minecraft.Client/Common/UI/UIScene_InGameInfoMenu.cpp +++ b/Minecraft.Client/Common/UI/UIScene_InGameInfoMenu.cpp @@ -93,7 +93,9 @@ void UIScene_InGameInfoMenu::updateTooltips() if(CGameNetworkManager::usingAdhocMode()) keyX = -1; #endif - INetworkPlayer *selectedPlayer = g_NetworkManager.GetPlayerBySmallId(m_players[m_playerList.getCurrentSelection()]->m_smallId); + INetworkPlayer *selectedPlayer = NULL; + if(m_playerList.getCurrentSelection() < m_players.size()) + selectedPlayer = g_NetworkManager.GetPlayerBySmallId(m_players[m_playerList.getCurrentSelection()]->m_smallId); int keyA = -1; Minecraft *pMinecraft = Minecraft::GetInstance(); @@ -335,7 +337,9 @@ void UIScene_InGameInfoMenu::handlePress(F64 controlId, F64 childId) break; case eControl_GamePlayers: int currentSelection = (int)childId; - INetworkPlayer *selectedPlayer = g_NetworkManager.GetPlayerBySmallId(m_players[currentSelection]->m_smallId); + INetworkPlayer *selectedPlayer = NULL; + if(currentSelection < m_players.size()) + selectedPlayer = g_NetworkManager.GetPlayerBySmallId(m_players[currentSelection]->m_smallId); Minecraft *pMinecraft = Minecraft::GetInstance(); shared_ptr localPlayer = pMinecraft->localplayers[m_iPad]; @@ -387,6 +391,8 @@ void UIScene_InGameInfoMenu::handleFocusChange(F64 controlId, F64 childId) void UIScene_InGameInfoMenu::OnPlayerChanged(void *callbackParam, INetworkPlayer *pPlayer, bool leaving) { + if(pPlayer == NULL) return; + app.DebugPrintf(" Player \"%ls\" %s (smallId: %d)\n", pPlayer->GetOnlineName(), leaving ? "leaving" : "joining", pPlayer->GetSmallId()); UIScene_InGameInfoMenu *scene = (UIScene_InGameInfoMenu *)callbackParam; diff --git a/Minecraft.Client/CreeperModel.cpp b/Minecraft.Client/CreeperModel.cpp index 066e0b55..14c7e55f 100644 --- a/Minecraft.Client/CreeperModel.cpp +++ b/Minecraft.Client/CreeperModel.cpp @@ -6,7 +6,7 @@ // 4J - added void CreeperModel::_init(float g) { - int yo = 4; + int yo = 6; head = new ModelPart(this, 0, 0); head->addBox(-4, - 8, -4, 8, 8, 8, g); // Head diff --git a/Minecraft.Client/Extrax64Stubs.cpp b/Minecraft.Client/Extrax64Stubs.cpp index 7fff9b09..19dcd797 100644 --- a/Minecraft.Client/Extrax64Stubs.cpp +++ b/Minecraft.Client/Extrax64Stubs.cpp @@ -211,22 +211,29 @@ ULONG_PTR IQNetPlayer::GetCustomDataValue() { return m_customData; } -IQNetPlayer IQNet::m_player[4]; +static IQNetPlayer s_playerArray[4]; +IQNetPlayer *IQNet::m_player = s_playerArray; +DWORD IQNet::s_playerCapacity = 4; +DWORD IQNet::s_playerCount = 0; +bool IQNet::s_isHosting = false; bool _bQNetStubGameRunning = false; HRESULT IQNet::AddLocalPlayerByUserIndex(DWORD dwUserIndex){ return S_OK; } +void IQNet::SetPlayerCapacity(DWORD capacity) { s_playerCapacity = capacity; } +DWORD IQNet::GetPlayerCapacity() { return s_playerCapacity; } IQNetPlayer *IQNet::GetHostPlayer() { return &m_player[0]; } IQNetPlayer *IQNet::GetLocalPlayerByUserIndex(DWORD dwUserIndex) { return &m_player[dwUserIndex]; } IQNetPlayer *IQNet::GetPlayerByIndex(DWORD dwPlayerIndex) { return &m_player[0]; } IQNetPlayer *IQNet::GetPlayerBySmallId(BYTE SmallId){ return &m_player[0]; } IQNetPlayer *IQNet::GetPlayerByXuid(PlayerUID xuid){ return &m_player[0]; } -DWORD IQNet::GetPlayerCount() { return 1; } +DWORD IQNet::GetPlayerCount() { return s_playerCount; } QNET_STATE IQNet::GetState() { return _bQNetStubGameRunning ? QNET_STATE_GAME_PLAY : QNET_STATE_IDLE; } -bool IQNet::IsHost() { return true; } +bool IQNet::IsHost() { return s_isHosting; } HRESULT IQNet::JoinGameFromInviteInfo(DWORD dwUserIndex, DWORD dwUserMask, const INVITE_INFO *pInviteInfo) { return S_OK; } -void IQNet::HostGame() { _bQNetStubGameRunning = true; } -void IQNet::EndGame() { _bQNetStubGameRunning = false; } +void IQNet::HostGame() { _bQNetStubGameRunning = true; s_isHosting = true; if(s_playerCount == 0) s_playerCount = 1; } +void IQNet::ClientJoinGame() { _bQNetStubGameRunning = true; s_isHosting = false; if(s_playerCount == 0) s_playerCount = 1; } +void IQNet::EndGame() { _bQNetStubGameRunning = false; s_isHosting = false; } DWORD MinecraftDynamicConfigurations::GetTrialTime() { return DYNAMIC_CONFIG_DEFAULT_TRIAL_TIME; } diff --git a/Minecraft.Client/HorseRenderer.cpp b/Minecraft.Client/HorseRenderer.cpp index 08ba49a2..97f75df1 100644 --- a/Minecraft.Client/HorseRenderer.cpp +++ b/Minecraft.Client/HorseRenderer.cpp @@ -46,9 +46,35 @@ void HorseRenderer::renderModel(shared_ptr mob, float wp, float ws } else { - EntityRenderer::bindTexture(mob); - model->render(mob, wp, ws, bob, headRotMinusBodyRot, headRotx, scale, true); - // Ensure that any extra layers of texturing are disabled after rendering this horse + shared_ptr horse = dynamic_pointer_cast(mob); + ResourceLocation *location = getTextureLocation(mob); + + // Pass 1: Bind only the coat texture (first valid layer) and render opaque + int coatTex = location->getTexture(0); + if( coatTex != -1 ) + { + RenderManager.TextureBind(entityRenderDispatcher->textures->loadTexture(coatTex)); + } + model->render(mob, wp, ws, bob, headRotMinusBodyRot, headRotx, scale, true); + + // Pass 2: If horse has armor, find the armor texture in the layers and render with blending + int armorType = horse->getArmorType(); + if( armorType > 0 ) + { + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + for( int i = 1; i < location->getTextureCount(); i++ ) + { + int texId = location->getTexture(i); + if( texId != -1 ) + { + RenderManager.TextureBind(entityRenderDispatcher->textures->loadTexture(texId)); + model->render(mob, wp, ws, bob, headRotMinusBodyRot, headRotx, scale, true); + } + } + glDisable(GL_BLEND); + } + RenderManager.TextureBind(-1); } } diff --git a/Minecraft.Client/LivingEntityRenderer.cpp b/Minecraft.Client/LivingEntityRenderer.cpp index 9e8682c7..7f4a3258 100644 --- a/Minecraft.Client/LivingEntityRenderer.cpp +++ b/Minecraft.Client/LivingEntityRenderer.cpp @@ -491,7 +491,7 @@ void LivingEntityRenderer::renderNameTag(shared_ptr mob, const wst float s = 1 / 60.0f * size; glPushMatrix(); - glTranslatef((float) x, (float) y + 2.3f, (float) z); + glTranslatef((float) x, (float) y + mob->bbHeight + 0.5f, (float) z); glNormal3f(0, 1, 0); glRotatef(-this->entityRenderDispatcher->playerRotY, 0, 1, 0); diff --git a/Minecraft.Client/Minecraft.Client.vcxproj b/Minecraft.Client/Minecraft.Client.vcxproj index b7b62029..30552ddc 100644 --- a/Minecraft.Client/Minecraft.Client.vcxproj +++ b/Minecraft.Client/Minecraft.Client.vcxproj @@ -34044,7 +34044,7 @@ xcopy /q /y /i /s /e $(ProjectDir)Durango\CU $(LayoutDir)Image\Loose\CUfalse false false - true + false false false false diff --git a/Minecraft.Client/Minecraft.cpp b/Minecraft.Client/Minecraft.cpp index 07ab47d9..35261db8 100644 --- a/Minecraft.Client/Minecraft.cpp +++ b/Minecraft.Client/Minecraft.cpp @@ -1858,7 +1858,7 @@ void Minecraft::run_middle() achievementPopup->render(); PIXBeginNamedEvent(0,"Sleeping"); - Sleep(0); // 4J - was Thread.yield() + //Sleep(0); // 4J - was Thread.yield() PIXEndNamedEvent(); // if (Keyboard::isKeyDown(Keyboard::KEY_F7)) Display.update(); // 4J - removed condition diff --git a/Minecraft.Client/Options.cpp b/Minecraft.Client/Options.cpp index 33e94060..c0095d6e 100644 --- a/Minecraft.Client/Options.cpp +++ b/Minecraft.Client/Options.cpp @@ -116,7 +116,7 @@ void Options::init() bobView = true; anaglyph3d = false; advancedOpengl = false; - framerateLimit = 2; + framerateLimit = 0; fancyGraphics = true; ambientOcclusion = true; renderClouds = true; diff --git a/Minecraft.Client/Textures.cpp b/Minecraft.Client/Textures.cpp index 9a9b79fd..bce056be 100644 --- a/Minecraft.Client/Textures.cpp +++ b/Minecraft.Client/Textures.cpp @@ -434,7 +434,11 @@ void Textures::bindTextureLayers(ResourceLocation *resource) for( int i = 0; i < layers; i++ ) { - RenderManager.TextureBind(loadTexture(resource->getTexture(i))); + int texId = resource->getTexture(i); + if( texId != -1 ) + { + RenderManager.TextureBind(loadTexture(texId)); + } } } diff --git a/Minecraft.Client/Windows64/Leaderboards/WindowsLeaderboardManager.h b/Minecraft.Client/Windows64/Leaderboards/WindowsLeaderboardManager.h index a469ba04..ec7f2d60 100644 --- a/Minecraft.Client/Windows64/Leaderboards/WindowsLeaderboardManager.h +++ b/Minecraft.Client/Windows64/Leaderboards/WindowsLeaderboardManager.h @@ -17,13 +17,23 @@ public: virtual void DeleteSession() {} //Write the given stats - //This is called synchronously and will not free any memory allocated for views when it is done + virtual bool WriteStats(unsigned int viewCount, ViewIn views) { return true; } - virtual bool WriteStats(unsigned int viewCount, ViewIn views) { return false; } - - virtual bool ReadStats_Friends(LeaderboardReadListener *callback, int difficulty, EStatsType type, PlayerUID myUID) { return false; } - virtual bool ReadStats_MyScore(LeaderboardReadListener *callback, int difficulty, EStatsType type, PlayerUID myUID, unsigned int readCount) { return false; } - virtual bool ReadStats_TopRank(LeaderboardReadListener *callback, int difficulty, EStatsType type, unsigned int startIndex, unsigned int readCount) { return false; } + virtual bool ReadStats_Friends(LeaderboardReadListener *callback, int difficulty, EStatsType type, PlayerUID myUID, unsigned int startIndex, unsigned int readCount) { + ReadView view = { 0, NULL }; + callback->OnStatsReadComplete(eStatsReturn_Success, 0, view); + return true; + } + virtual bool ReadStats_MyScore(LeaderboardReadListener *callback, int difficulty, EStatsType type, PlayerUID myUID, unsigned int readCount) { + ReadView view = { 0, NULL }; + callback->OnStatsReadComplete(eStatsReturn_Success, 0, view); + return true; + } + virtual bool ReadStats_TopRank(LeaderboardReadListener *callback, int difficulty, EStatsType type, unsigned int startIndex, unsigned int readCount) { + ReadView view = { 0, NULL }; + callback->OnStatsReadComplete(eStatsReturn_Success, 0, view); + return true; + } //Perform a flush of the stats virtual void FlushStats() {} diff --git a/Minecraft.Client/Windows64/Windows64_Minecraft.cpp b/Minecraft.Client/Windows64/Windows64_Minecraft.cpp index baeeda99..0aae8055 100644 --- a/Minecraft.Client/Windows64/Windows64_Minecraft.cpp +++ b/Minecraft.Client/Windows64/Windows64_Minecraft.cpp @@ -498,7 +498,7 @@ app.DebugPrintf("width: %d, height: %d\n", width, height); DXGI_SWAP_CHAIN_DESC sd; ZeroMemory( &sd, sizeof( sd ) ); - sd.BufferCount = 1; + sd.BufferCount = 2; sd.BufferDesc.Width = width; sd.BufferDesc.Height = height; sd.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; diff --git a/Minecraft.World/AbstractContainerMenu.cpp b/Minecraft.World/AbstractContainerMenu.cpp index 6e00be6d..f775fb7a 100644 --- a/Minecraft.World/AbstractContainerMenu.cpp +++ b/Minecraft.World/AbstractContainerMenu.cpp @@ -552,13 +552,13 @@ bool AbstractContainerMenu::isPauseScreen() void AbstractContainerMenu::setItem(unsigned int slot, shared_ptr item) { - if (slot >= slots->size()) return; + if (slot >= slots.size()) return; getSlot(slot)->set(item); } void AbstractContainerMenu::setAll(ItemInstanceArray *items) { - for (unsigned int i = 0; i < items->length && i < slots->size(); i++) + for (unsigned int i = 0; i < items->length && i < slots.size(); i++) { getSlot(i)->set( (*items)[i] ); } diff --git a/Minecraft.World/AttackDamageMobEffect.cpp b/Minecraft.World/AttackDamageMobEffect.cpp index 483c9a72..a2955db7 100644 --- a/Minecraft.World/AttackDamageMobEffect.cpp +++ b/Minecraft.World/AttackDamageMobEffect.cpp @@ -10,7 +10,7 @@ double AttackDamageMobEffect::getAttributeModifierValue(int amplifier, Attribute { if (id == MobEffect::weakness->id) { - return -0.5f * (amplifier + 1); + return -4.0f * (amplifier + 1); } else { diff --git a/Minecraft.World/ByteArrayTag.h b/Minecraft.World/ByteArrayTag.h index 6b797845..0e87607f 100644 --- a/Minecraft.World/ByteArrayTag.h +++ b/Minecraft.World/ByteArrayTag.h @@ -18,7 +18,7 @@ public: dos->write(data); } - void load(DataInput *dis) + void load(DataInput *dis, int tagDepth) { int length = dis->readInt(); if (length < 0 || length > 2 * 1024 * 1024) length = 0; diff --git a/Minecraft.World/Minecraft.World.vcxproj b/Minecraft.World/Minecraft.World.vcxproj index 5df0d959..4169c2d7 100644 --- a/Minecraft.World/Minecraft.World.vcxproj +++ b/Minecraft.World/Minecraft.World.vcxproj @@ -1124,7 +1124,7 @@ Sync false $(OutDir)$(ProjectName).pch - MultiThreadedDebugDLL + MultiThreadedDebug _LARGE_WORLDS;_DEBUG_MENUS_ENABLED;_DEBUG;_LIB;_CRT_NON_CONFORMING_SWPRINTFS;_CRT_SECURE_NO_WARNINGS;_WINDOWS64;%(PreprocessorDefinitions) Disabled true diff --git a/Minecraft.World/OldChunkStorage.cpp b/Minecraft.World/OldChunkStorage.cpp index acfaecc3..54d510a4 100644 --- a/Minecraft.World/OldChunkStorage.cpp +++ b/Minecraft.World/OldChunkStorage.cpp @@ -490,7 +490,7 @@ LevelChunk *OldChunkStorage::load(Level *level, DataInputStream *dis) { CompoundTag *teTag = tileTicks->get(i); - level->forceAddTileTick(teTag->getInt(L"x"), teTag->getInt(L"y"), teTag->getInt(L"z"), teTag->getInt(L"i"), teTag->getInt(L"t")); + level->forceAddTileTick(teTag->getInt(L"x"), teTag->getInt(L"y"), teTag->getInt(L"z"), teTag->getInt(L"i"), teTag->getInt(L"t"), teTag->getInt(L"p")); } } } diff --git a/Minecraft.World/RegionFileCache.cpp b/Minecraft.World/RegionFileCache.cpp index 06bd498a..75485ceb 100644 --- a/Minecraft.World/RegionFileCache.cpp +++ b/Minecraft.World/RegionFileCache.cpp @@ -126,7 +126,4 @@ DataOutputStream *RegionFileCache::_getChunkDataOutputStream(ConsoleSaveFile *sa } -RegionFileCache::~RegionFileCache() -{ - _clear(); -} + diff --git a/Minecraft.World/RegionFileCache.h b/Minecraft.World/RegionFileCache.h index 9361ca4f..ae660baa 100644 --- a/Minecraft.World/RegionFileCache.h +++ b/Minecraft.World/RegionFileCache.h @@ -17,7 +17,7 @@ private: public: // Made public and non-static so we can have a cache for input and output files RegionFileCache() { InitializeCriticalSectionAndSpinCount(&m_cs, 4000); } - ~RegionFileCache() { DeleteCriticalSection(&m_cs); } + ~RegionFileCache() { _clear(); DeleteCriticalSection(&m_cs); } RegionFile *_getRegionFile(ConsoleSaveFile *saveFile, const wstring &prefix, int chunkX, int chunkZ); // 4J - TODO was synchronized void _clear(); // 4J - TODO was synchronized diff --git a/Minecraft.World/Tag.cpp b/Minecraft.World/Tag.cpp index 2cd9c229..f27130ae 100644 --- a/Minecraft.World/Tag.cpp +++ b/Minecraft.World/Tag.cpp @@ -115,7 +115,7 @@ Tag *Tag::readNamedTag(DataInput *dis) Tag *tag = newTag(type, name); if (tag == NULL) { depth--; return new EndTag(); } - tag->load(dis); + tag->load(dis, depth + 1); depth--; return tag; } -- 2.54.0